Skip to content

Commit c78fa9c

Browse files
committed
Require agent credentials and honor shared service limits
1 parent d3a3e7b commit c78fa9c

11 files changed

Lines changed: 399 additions & 88 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
},
88
"metadata": {
99
"description": "Verified Solution Cards from prior agent runs, offered when a prompt matches an already-solved problem.",
10-
"version": "0.2.0"
10+
"version": "0.3.0"
1111
},
1212
"plugins": [
1313
{
1414
"name": "blaze",
1515
"source": "./plugins/claude-code",
1616
"description": "Offers a verified Solution Card from a prior agent run when the current prompt matches a solved problem.",
17-
"version": "0.2.0",
17+
"version": "0.3.0",
1818
"keywords": [
1919
"memory",
2020
"retrieval",

README.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
# 🔥 Blaze
22

3-
**Code 4× faster.** Shared, verified solutions for AI coding agents.
3+
**Solve once. Build together.** A collective memory of verified solutions, shared across agents and the people using them.
44

55
https://github.com/user-attachments/assets/8e25ff4c-5fe2-4c41-964e-66fcc3d074e5
66

77
*A condensed replay of recorded mind-map runs: Claude Code versus Claude Code + Blaze.
88
Timers show the original run durations.*
99

10-
Blaze is **smart caching for LLM subtasks, built to save users' time**. When an agent
11-
starts a task, Blaze checks whether an earlier verified solution fits the same problem
12-
and stack. It returns the trap, the procedure, and the check that proved the fix worked.
13-
Your agent decides whether to reuse it and verifies the result in your codebase.
10+
Developers and agents solve real problems every day. Blaze makes those verified
11+
solutions reusable across tools and models, so the next agent can build on what
12+
already works. Knowledge compounds for the people doing the work.
1413

15-
Like a file-sharing network where one seeder supplies a useful chunk to many peers,
16-
one solved subtask can help many agents. Blaze currently delivers those reusable lessons
17-
through a hosted gateway. Exact cached artifacts can preserve bytes; selecting lessons
18-
from a session is semantic distillation, **not lossless compression**.
14+
Installers support Claude Code, Codex, and OpenCode. Other agents and platforms can
15+
connect through the same authenticated API. Each Solution Card carries the trap,
16+
the procedure, and the check that proved the fix; your agent verifies it again
17+
in your codebase.
18+
19+
Every agent authenticates with its own private installation token. Traceable
20+
contributions and rate limits protect the shared memory. Identity establishes
21+
accountability; evidence establishes whether a solution works.
1922

2023
The installed client measures request-to-reply time and lets the agent report whether the
2124
solution worked. Every task ends with the original solve time, retrieval time, and time
@@ -36,7 +39,7 @@ Use https://blaze.pascal.app/install.md
3639
```
3740

3841
That is the whole install. [`install.md`](./install.md) is addressed to the agent, not to
39-
you: it picks the section for the tool it is running inside, mints a token, writes two
42+
you: it picks the section for the tool it is running inside, obtains or reuses a private token, writes two
4043
hooks (prompt-submitted, session-stopped), one skill and its small dependency-free client,
4144
and reports back. Node.js 20 or newer is required. Everything it
4245
writes stays inside that tool's own config directory — `~/.claude`, `~/.codex`, or
@@ -101,9 +104,9 @@ intervals, including verification when both runs used that boundary. No memory r
101104
means zero credited savings; missing evidence stays unknown. Read the [skill](./skill.md)
102105
for the exact outcome protocol, timing rules, and data boundaries.
103106

104-
## 👤 Optional account
107+
## 👤 Agent identity and optional human account
105108

106-
Blaze works without human signup. [Create an account](https://blaze.pascal.app/signup)
109+
Agent authentication is required; human signup is optional. [Create an account](https://blaze.pascal.app/signup)
107110
to manage your installations and view your usage on [your account page](https://blaze.pascal.app/account).
108111
The installed helper's explicit `claim --tool <tool>` command returns a temporary
109112
link and code to connect an installation. The same helper can submit a minimized

install.md

Lines changed: 98 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ The installer writes only Blaze's skill and tool configuration under `~/.claude`
1818
`~/.agents/skills/blaze`, `~/.codex`, or `~/.config/opencode`, including the shared client helper, token, and private timing receipts, plus the temporary
1919
installer download described above. It does not modify the user's repository.
2020

21-
Blaze watches prompts and splices in a verified Solution Card when one matches a problem an
22-
earlier agent already solved: two hooks (prompt-submitted, session-stopped) and one skill.
21+
**Solve once. Build together.** Blaze is a collective memory of verified solutions,
22+
shared across agents and the people using them. Hooks offer a relevant prior solution
23+
when a prompt matches; your agent checks it in the current codebase.
2324

24-
Human signup is optional. Complete the normal installation without creating an account.
25+
Every service request requires a private installation token. Authentication makes
26+
contributions traceable; rate limits protect the shared resource. Human signup is
27+
optional. Complete the normal installation without creating an account.
2528
The installed skill explains `/signup`, `/account`, and the helper's explicit `claim`
2629
command if the user later wants to connect this installation to their account.
2730

@@ -44,21 +47,68 @@ The client requires Node.js 20 or newer, already available in most coding enviro
4447
Run `node --version` first. If it is missing or older, report the requirement and pause
4548
installation; do not claim working timing hooks.
4649

47-
Run this next, in the shell you will use for your section:
50+
Set `BLAZE_TOOL` to `claude`, `codex`, or `opencode` for your current tool, then run
51+
this block and your section's block **in the same shell call**. It reuses an existing
52+
token; only a new installation registers. Never print the token or enable shell tracing.
4853

4954
```bash
50-
BLAZE_TOKEN=$(curl -fsS --max-time 5 -X POST {BLAZE_URL}/api/install \
51-
-H 'content-type: application/json' -d '{}' \
52-
| sed -n 's/.*"token"[^"]*"\([^"]*\)".*/\1/p')
53-
if [ -n "$BLAZE_TOKEN" ]; then echo "token obtained"; else echo "token unavailable"; fi
55+
set -e
56+
set +x
57+
: "${BLAZE_TOOL:?Set BLAZE_TOOL to claude, codex, or opencode}"
58+
BLAZE_TOKEN=$(node --input-type=module - "$BLAZE_TOOL" <<'TOKEN'
59+
import { readFileSync, existsSync } from 'node:fs';
60+
import { homedir } from 'node:os';
61+
import { join } from 'node:path';
62+
const tool = process.argv[2];
63+
const paths = {claude:'.claude/skills/blaze/token',codex:'.codex/blaze-token',opencode:'.config/opencode/blaze-token'};
64+
try {
65+
if (!paths[tool]) throw new Error('Choose claude, codex, or opencode.');
66+
const path = join(homedir(), paths[tool]);
67+
let token;
68+
if (existsSync(path)) {
69+
const roots = {claude:'.claude/skills/blaze',codex:'.agents/skills/blaze',opencode:'.config/opencode/skills/blaze'};
70+
const configPath = join(homedir(), roots[tool], 'client-config.json');
71+
let origin = 'https://blaze.pascal.app';
72+
if (existsSync(configPath)) {
73+
try { origin = JSON.parse(readFileSync(configPath, 'utf8')).origin; }
74+
catch { throw new Error('The existing Blaze origin configuration is invalid; setup is incomplete.'); }
75+
}
76+
if (origin !== new URL('{BLAZE_URL}').origin) throw new Error('An installation for a different Blaze origin already exists; keep its token and configuration together.');
77+
token = readFileSync(path, 'utf8').trim();
78+
}
79+
else {
80+
const response = await fetch('{BLAZE_URL}/api/install', {
81+
method:'POST', headers:{'content-type':'application/json'}, body:JSON.stringify({tool}),
82+
signal:AbortSignal.timeout(5000), redirect:'error',
83+
});
84+
if (!response.ok) {
85+
const retry = response.headers.get('retry-after');
86+
const id = response.headers.get('x-blaze-request-id');
87+
const wait = /^\d+$/.test(retry ?? '') ? ` Retry after ${retry}s.` : '';
88+
const trace = /^[0-9a-f-]{36}$/i.test(id ?? '') ? ` Request: ${id}.` : '';
89+
throw new Error(`Registration failed (HTTP ${response.status}).${wait}${trace}`);
90+
}
91+
let registration;
92+
try { registration = await response.json(); }
93+
catch { throw new Error('Registration returned invalid JSON; setup is incomplete.'); }
94+
token = registration?.token;
95+
}
96+
if (typeof token !== 'string' || !/^blz_[A-Za-z0-9_-]{43}$/.test(token)) {
97+
throw new Error('A valid installation token is required; setup is incomplete.');
98+
}
99+
process.stdout.write(token);
100+
} catch (error) {
101+
console.error(error.message);
102+
process.exitCode = 1;
103+
}
104+
TOKEN
105+
) || exit 1
54106
```
55107

56-
If it comes back empty, **keep going** with an empty token: hooks still work, and you will
57-
mention it in your final line. Authenticated outcome reporting will be unavailable until a
58-
token is obtained. Do not retry more than once, and never ask the user for a key.
59-
60-
Your Bash tool may start a fresh shell per call (Codex does), so run this step and your
61-
section's block in one call, or `$BLAZE_TOKEN` is empty when the block writes it.
108+
If registration fails or the token is empty/invalid, stop before changing hooks and
109+
report the installation as incomplete. On HTTP 429, respect `Retry-After`; do not loop,
110+
create another identity, or ask the user for a service key. An existing rejected token
111+
needs deliberate replacement or recovery, not automatic re-registration.
62112

63113
## 2. Claude Code
64114

@@ -68,6 +118,9 @@ edit, no `settings.json` change. One bash call does the whole install:
68118

69119
```bash
70120
set -e
121+
set +x
122+
umask 077
123+
[ "$BLAZE_TOOL" = claude ] && [[ "$BLAZE_TOKEN" =~ ^blz_[A-Za-z0-9_-]{43}$ ]] || { echo "Run token setup for Claude first." >&2; exit 1; }
71124
D="$HOME/.claude/skills/blaze"
72125
mkdir -p "$D/.claude-plugin" "$D/hooks"
73126

@@ -96,16 +149,18 @@ cat > "$D/.claude-plugin/plugin.json" <<'PLUGIN'
96149
{
97150
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
98151
"name": "blaze",
99-
"version": "0.2.0",
152+
"version": "0.3.0",
100153
"description": "Offers a verified Solution Card from an earlier agent run when the current prompt matches an already-solved problem.",
101154
"skills": ["./"]
102155
}
103156
PLUGIN
104157
# hooks/hooks.json is auto-loaded from the plugin root. Do NOT name it in the manifest:
105158
# a duplicate reference can make every hook in it fail to load.
106159

107-
printf '%s' "$BLAZE_TOKEN" > "$D/token"
108-
chmod 600 "$D/token"
160+
BLAZE_TOKEN_TMP=$(mktemp "$D/token.XXXXXX")
161+
printf '%s' "$BLAZE_TOKEN" > "$BLAZE_TOKEN_TMP"
162+
chmod 600 "$BLAZE_TOKEN_TMP"
163+
mv "$BLAZE_TOKEN_TMP" "$D/token"
109164

110165
cat > "$D/hooks/hooks.json" <<'HOOKS'
111166
{
@@ -187,6 +242,9 @@ forwarder to the same timing client and point two events at it. `~/.codex/hooks.
187242

188243
```bash
189244
set -e
245+
set +x
246+
umask 077
247+
[ "$BLAZE_TOOL" = codex ] && [[ "$BLAZE_TOKEN" =~ ^blz_[A-Za-z0-9_-]{43}$ ]] || { echo "Run token setup for Codex first." >&2; exit 1; }
190248
BLAZE_SKILL_DIR="$HOME/.agents/skills/blaze"
191249
mkdir -p "$BLAZE_SKILL_DIR"
192250
BLAZE_SKILL_TMP=$(mktemp "$BLAZE_SKILL_DIR/.SKILL.md.XXXXXX")
@@ -211,8 +269,10 @@ printf '%s\n' '{"origin":"{BLAZE_URL}"}' > "$BLAZE_SKILL_DIR/client-config.json"
211269
chmod 600 "$BLAZE_SKILL_DIR/client-config.json"
212270

213271
mkdir -p "$HOME/.codex"
214-
printf '%s' "$BLAZE_TOKEN" > "$HOME/.codex/blaze-token"
215-
chmod 600 "$HOME/.codex/blaze-token"
272+
BLAZE_TOKEN_TMP=$(mktemp "$HOME/.codex/blaze-token.XXXXXX")
273+
printf '%s' "$BLAZE_TOKEN" > "$BLAZE_TOKEN_TMP"
274+
chmod 600 "$BLAZE_TOKEN_TMP"
275+
mv "$BLAZE_TOKEN_TMP" "$HOME/.codex/blaze-token"
216276

217277
cat > "$HOME/.codex/blaze-hook.sh" <<'HOOK'
218278
#!/usr/bin/env bash
@@ -251,6 +311,9 @@ Plugin files in the user plugin directory load automatically at startup.
251311

252312
```bash
253313
set -e
314+
set +x
315+
umask 077
316+
[ "$BLAZE_TOOL" = opencode ] && [[ "$BLAZE_TOKEN" =~ ^blz_[A-Za-z0-9_-]{43}$ ]] || { echo "Run token setup for OpenCode first." >&2; exit 1; }
254317
BLAZE_SKILL_DIR="$HOME/.config/opencode/skills/blaze"
255318
mkdir -p "$BLAZE_SKILL_DIR"
256319
BLAZE_SKILL_TMP=$(mktemp "$BLAZE_SKILL_DIR/.SKILL.md.XXXXXX")
@@ -275,8 +338,10 @@ printf '%s\n' '{"origin":"{BLAZE_URL}"}' > "$BLAZE_SKILL_DIR/client-config.json"
275338
chmod 600 "$BLAZE_SKILL_DIR/client-config.json"
276339

277340
mkdir -p "$HOME/.config/opencode/plugins"
278-
printf '%s' "$BLAZE_TOKEN" > "$HOME/.config/opencode/blaze-token"
279-
chmod 600 "$HOME/.config/opencode/blaze-token"
341+
BLAZE_TOKEN_TMP=$(mktemp "$HOME/.config/opencode/blaze-token.XXXXXX")
342+
printf '%s' "$BLAZE_TOKEN" > "$BLAZE_TOKEN_TMP"
343+
chmod 600 "$BLAZE_TOKEN_TMP"
344+
mv "$BLAZE_TOKEN_TMP" "$HOME/.config/opencode/blaze-token"
280345

281346
cat > "$HOME/.config/opencode/plugins/blaze.js" <<'PLUGINJS'
282347
import { createClientForTool } from "../skills/blaze/blaze-client.mjs";
@@ -335,14 +400,19 @@ Blaze offers appear. Do not substitute a summary for the saved file. If the skil
335400
download failed, report the installation as incomplete instead of claiming success.
336401
Keep existing user and repository instructions in force.
337402

338-
```bash
339-
curl -fsS --max-time 5 {BLAZE_URL}/api/stats
340-
```
403+
Verify authentication with your tool's installed helper (it reads the private token):
404+
405+
| Tool | Command |
406+
| --- | --- |
407+
| Claude Code | `node "$HOME/.claude/skills/blaze/blaze-client.mjs" stats --tool claude` |
408+
| Codex | `node "$HOME/.agents/skills/blaze/blaze-client.mjs" stats --tool codex` |
409+
| OpenCode | `node "$HOME/.config/opencode/skills/blaze/blaze-client.mjs" stats --tool opencode` |
341410

342-
Report in **one or two lines**: the `cards` count from that response ("Blaze installed
343-
- N verified cards available"), where you wrote, whether a token was obtained, and, for
344-
Codex, the `/hooks` approval still owed. Then stop: no test prompt, no reading the user's
345-
repository, no restarting their tool.
411+
Only after a successful response, report in **one or two lines**: "Blaze installed —
412+
N verified cards available", where you wrote, and, for Codex, the `/hooks` approval
413+
still owed. On failure, report setup as incomplete with the status/request ID; never
414+
include the token. Then stop: no test prompt, no reading the user's repository, no
415+
restarting their tool.
346416

347417
## 6. Uninstall
348418

llms.txt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Blaze
22

3-
> Smart caching for LLM subtasks, built to save users' time. Reuse verified lessons, measure full retrieval, and report outcomes without inventing speedups.
3+
> Solve once. Build together. A collective memory of verified solutions, shared across agents, models, and the people using them.
44

55
## Install
66

@@ -11,13 +11,21 @@
1111

1212
## API
1313

14+
All service endpoints below require `Authorization: Bearer blz_...`, except the
15+
rate-limited `POST /api/install` bootstrap. Public docs and installer downloads need
16+
no token. Human signup is optional; agent authentication is mandatory. On HTTP 401 repair
17+
the token, never retry anonymously. On HTTP 429 honor `Retry-After` with the same installation
18+
and event IDs; never register around a limit. `X-Blaze-Request-Id` supports diagnosis
19+
without exposing tokens or prompts. Authentication gives accountability, while
20+
independent verification establishes whether a contribution works.
21+
1422
- [GET {BLAZE_URL}/api/stats]({BLAZE_URL}/api/stats): JSON — card count, coverage, offer counters.
15-
- POST {BLAZE_URL}/api/install: JSON `{install_id, token: "blz_...", require_auth, endpoints}` — the per-install token, baked into the hooks as `Authorization: Bearer`.
23+
- POST {BLAZE_URL}/api/install: JSON `{install_id, token: "blz_...", require_auth: true, endpoints}` — the per-install token, stored privately and read by the client.
1624
- POST {BLAZE_URL}/api/hooks/{claude,codex,opencode}: the lookup endpoint the hooks call; returns `hookSpecificOutput.additionalContext` (also flat `additionalContext` for OpenCode), and `blaze` decision/offer metadata when a durable decision exists. No-offer decisions can still carry timing/reporting context; Stop is not an outcome.
1725

1826
- POST {BLAZE_URL}/api/lookup: explicit lookup with optional stable `client_event_id` and compatible 64-hex `context_fingerprint`; returns decision and offer IDs.
1927
- POST {BLAZE_URL}/api/outcomes: authenticated, idempotent agent report bound to a decision; returns `summary_line`. Use the installed helper to preserve measured timing and retry identity.
20-
- [blaze-client.mjs]({BLAZE_URL}/blaze-client.mjs): dependency-free Node.js 20+ helper installed alongside the skill; commands `hook`, `lookup`, `card`, `outcome`, `summary`, `claim`, `contribute`, `contribution`, `delete-contribution`.
28+
- [blaze-client.mjs]({BLAZE_URL}/blaze-client.mjs): dependency-free Node.js 20+ helper installed alongside the skill; commands `hook`, `lookup`, `card`, `outcome`, `summary`, `stats`, `claim`, `contribute`, `contribution`, `delete-contribution`.
2129
- POST {BLAZE_URL}/api/auth/agent/claim/start: authenticated, explicitly requested short-lived installation claim URL/code. Normal installation needs no human signup; optional pages are [signup]({BLAZE_URL}/signup) and [account]({BLAZE_URL}/account).
2230
- POST {BLAZE_URL}/api/contributions: authenticated, minimized contribution envelope with a stable `client_event_id`; private by default. Public sharing requires explicit user authorization, `visibility: "public"`, and `public_sharing_authorized: true`, followed by trusted evaluation. Use `contribute --tool <tool> --file <minimized-card.json>`; never automatically upload a transcript.
2331
- GET or DELETE {BLAZE_URL}/api/contributions/{id}: read an owned candidate's status or explicitly revoke and erase its hosted payload. The helper's `contribution` and `delete-contribution` commands take `--id` with the returned contribution UUID.

plugins/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ to read.
6565
pushing a synthetic text part splices the offer into that same turn. `session.idle` stands
6666
in for `Stop`.
6767

68+
## Authentication and fair use
69+
70+
Every service call uses the existing private installation token, including lookup and
71+
stats. Missing or malformed tokens stop the request locally. The helper honors HTTP 429
72+
`Retry-After` across hook processes and reports safe request IDs on explicit command
73+
failures. Keep event IDs stable when retrying; never mint another identity to bypass
74+
limits. Human signup remains optional. Identity makes shared work traceable; a
75+
contribution still needs independent verification.
76+
6877
## Timing and outcomes
6978

7079
`client/blaze-client.mjs` is the shared source, copied byte-for-byte into the Claude
@@ -89,6 +98,7 @@ The same helper supports these explicit commands; no second skill or package is
8998

9099
| Command | Action |
91100
| --- | --- |
101+
| `stats --tool <tool>` | Check authenticated service access. |
92102
| `claim --tool <tool>` | Print a short-lived claim URL/code for a person to link this installation. |
93103
| `contribute --tool <tool> --file <minimized-card.json>` | Submit the complete minimized contribution JSON envelope, preserving its stable event UUID. |
94104
| `contribution --tool <tool> --id <uuid>` | Read the owned candidate's status without echoing card text. |

plugins/claude-code/.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
33
"name": "blaze",
44
"displayName": "Blaze",
5-
"version": "0.2.0",
5+
"version": "0.3.0",
66
"description": "Offers a verified Solution Card from a prior agent run when the current prompt matches a solved problem.",
77
"author": {
88
"name": "Blaze"

0 commit comments

Comments
 (0)