@coopcli/specsketch 5.3.0 → 5.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -162
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,18 +32,33 @@ contains artifacts — scaffolded by `openspec new change` or hand-written — t
|
|
|
32
32
|
baseline: generation makes the **smallest revision** that fulfills the drawing, leaving
|
|
33
33
|
unimplicated files byte-identical.
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
## Use cases
|
|
36
|
+
|
|
37
|
+
- **Spec-first feature kickoff.** Sketch the shape of a change, generate the OpenSpec
|
|
38
|
+
proposal/design/tasks/capability specs, review, and hand the change directory to an
|
|
39
|
+
implementing agent. `npx openspec validate` works on the output.
|
|
40
|
+
- **Revising an existing change.** Point specsketch at a change directory that already has
|
|
41
|
+
artifacts; update the drawing and regenerate — only what the diagram implicates changes.
|
|
42
|
+
- **Design review, captured.** Chat about the generated spec (answers are grounded in the
|
|
43
|
+
artifacts on disk), then **Regenerate** — your corrections in the conversation become
|
|
44
|
+
requirements for the next pass, so review decisions land in the spec instead of a
|
|
45
|
+
meeting doc.
|
|
46
|
+
- **Whiteboarding with the team.** `--share` hosts the canvas live; teammates draw with you
|
|
47
|
+
from a plain browser link, no account or install, and everything lands in the change
|
|
48
|
+
directory on your machine.
|
|
49
|
+
- **Grounded in real code.** `@` references pull actual files into the model's context, so
|
|
50
|
+
the spec describes your system rather than a guess at it.
|
|
51
|
+
|
|
52
|
+
## File references: `@<path | filename>`
|
|
36
53
|
|
|
37
54
|
Anywhere you type — the architecture title, text on the canvas (labels and loose notes),
|
|
38
|
-
or the review chat — an `@` reference pulls a real file into the model's context
|
|
39
|
-
generated OpenSpec is grounded in your actual code instead of guesses:
|
|
55
|
+
or the review chat — an `@` reference pulls a real file into the model's context:
|
|
40
56
|
|
|
41
57
|
- `@server/app.ts` — a path relative to the directory you launched `specsketch` from.
|
|
42
58
|
- `@schema.ts` — a bare filename; the tree is searched (skipping `.git`, `node_modules`,
|
|
43
59
|
`dist`) and the shallowest match wins. Multiple matches are noted in the context.
|
|
44
60
|
- `@src/ui` or `@src/ui/` — a **directory**; its files (recursively, up to 50 files and
|
|
45
|
-
the size budgets) are all pulled into context, each reported individually.
|
|
46
|
-
directories include what fits and note what was omitted.
|
|
61
|
+
the size budgets) are all pulled into context, each reported individually.
|
|
47
62
|
|
|
48
63
|
Typing `@` in the chat composer or the system prompt editor opens an **inline search**
|
|
49
64
|
over that same scope — files and directories, filtered as you type; arrows + Enter/Tab
|
|
@@ -57,27 +72,25 @@ unresolvable reference never fails generation or chat — it degrades to a "coul
|
|
|
57
72
|
resolved" note in the context, and the chat pane lists which files resolved and which
|
|
58
73
|
didn't under each answer.
|
|
59
74
|
|
|
60
|
-
|
|
75
|
+
## The spec review pane: Spec / System Prompt / Chat
|
|
61
76
|
|
|
62
77
|
The right-hand panel has a menu with three options:
|
|
63
78
|
|
|
64
|
-
- **Spec** — the generated artifacts (summary, proposal, design, tasks, capability specs)
|
|
65
|
-
exactly what the panel showed before.
|
|
79
|
+
- **Spec** — the generated artifacts (summary, proposal, design, tasks, capability specs).
|
|
66
80
|
- **System Prompt** — view *and edit* the prompt that drives generation. Saved edits apply
|
|
67
81
|
to every subsequent generation and persist with the change directory (`specsketch.json`);
|
|
68
82
|
**Reset** restores the built-in default. `@` references inside the prompt resolve like
|
|
69
83
|
any other input, so you can pin conventions with `@docs/style.md`.
|
|
70
|
-
- **Chat** — available once a spec exists. Ask questions about the generated OpenSpec
|
|
71
|
-
|
|
72
|
-
iterate:
|
|
84
|
+
- **Chat** — available once a spec exists. Ask questions about the generated OpenSpec,
|
|
85
|
+
pull files in with `@` references, and iterate:
|
|
73
86
|
- **Regenerate** (header, next to Generate Spec) re-runs generation with the conversation
|
|
74
|
-
as extra context
|
|
87
|
+
as extra context.
|
|
75
88
|
- **Clear** (in the pane) discards the conversation and starts over.
|
|
76
89
|
- Every generation resets the chat and seeds it with an AI-written summary of the prior
|
|
77
|
-
conversation and what changed on disk
|
|
78
|
-
|
|
90
|
+
conversation and what changed on disk — context stays bounded, the thread of decisions
|
|
91
|
+
survives. The chat persists in `specsketch.json` across restarts.
|
|
79
92
|
|
|
80
|
-
|
|
93
|
+
## Requirements & auth
|
|
81
94
|
|
|
82
95
|
- **Node ≥ 22** (the CLI checks at startup).
|
|
83
96
|
- **Anthropic credentials** — only needed for Generate Spec; drawing works without them, and
|
|
@@ -89,10 +102,11 @@ The right-hand panel has a menu with three options:
|
|
|
89
102
|
brew install anthropics/tap/ant && ant auth login
|
|
90
103
|
```
|
|
91
104
|
|
|
92
|
-
|
|
105
|
+
## CLI reference
|
|
93
106
|
|
|
94
107
|
```
|
|
95
108
|
specsketch <path-to-openspec-change-dir> [--port <n>] [--share]
|
|
109
|
+
specsketch login [--profile <name>] [--web-url <url>]
|
|
96
110
|
```
|
|
97
111
|
|
|
98
112
|
- The directory is created if it doesn't exist; its basename becomes the change name.
|
|
@@ -106,7 +120,7 @@ specsketch <path-to-openspec-change-dir> [--port <n>] [--share]
|
|
|
106
120
|
server-side refusal fallbacks to Opus and requires your org to allow 30-day data
|
|
107
121
|
retention.
|
|
108
122
|
|
|
109
|
-
|
|
123
|
+
## Shared sessions (`--share`)
|
|
110
124
|
|
|
111
125
|
```bash
|
|
112
126
|
specsketch login # once per machine
|
|
@@ -119,164 +133,36 @@ browser — **no account, no install** — see the live canvas, and can draw on
|
|
|
119
133
|
edits stream back and land in `diagram.excalidraw` like your own. The top bar shows a
|
|
120
134
|
live pill with the participant count and a copy-link button.
|
|
121
135
|
|
|
122
|
-
|
|
136
|
+
Worth knowing:
|
|
123
137
|
|
|
124
138
|
- The host needs a CoopCLI account (`specsketch login` — opens a browser, saves
|
|
125
|
-
credentials to `~/.coopcli/config.json`, the same file `coop login` writes); guests
|
|
126
|
-
itself is the capability: anyone holding it can view **and edit**
|
|
127
|
-
ends. The server stores only a hash of the link token.
|
|
139
|
+
credentials to `~/.coopcli/config.json`, the same file `coop login` writes); guests
|
|
140
|
+
never do. The link itself is the capability: anyone holding it can view **and edit**
|
|
141
|
+
until the session ends. The server stores only a hash of the link token.
|
|
128
142
|
- The local server still binds to 127.0.0.1 only — sharing runs over a single outbound
|
|
129
|
-
connection from the CLI
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
own collab server uses. The change directory on the host remains the durable copy.
|
|
143
|
+
connection from the CLI. Your CoopCLI API key never reaches any browser.
|
|
144
|
+
- Concurrent edits resolve per element, last-write-wins. The change directory on the
|
|
145
|
+
host remains the durable copy.
|
|
133
146
|
- Connections heal themselves (heartbeat + reconnect with backoff); a brief
|
|
134
|
-
"reconnecting…" pill is normal
|
|
147
|
+
"reconnecting…" pill is normal.
|
|
135
148
|
- **Ctrl-C ends the session and invalidates the link.** Idle sessions expire server-side
|
|
136
149
|
after 24 h.
|
|
137
150
|
|
|
138
|
-
|
|
151
|
+
## Troubleshooting
|
|
139
152
|
|
|
140
153
|
| Symptom | Fix |
|
|
141
154
|
|---|---|
|
|
142
|
-
| `sh: specsketch: command not found` from `npx` **inside this repo** | This repo *is* `@coopcli/specsketch`, so npx resolves to the local checkout (which has no bin link) instead of the registry. Use `npm run cli -- ./openspec/changes/<name>`, or run npx from any other directory |
|
|
143
155
|
| `npm error 404 @coopcli/specsketch not found` right after a release | Registry propagation lag — retry in a minute or two |
|
|
144
156
|
| Startup warning "No Anthropic credentials detected" | Set `ANTHROPIC_API_KEY` or run `ant auth login`, then restart |
|
|
145
157
|
| Generate fails with a 401 / "anthropic-auth" | Same as above — the server found no credentials, or the login profile expired (`ant auth status`) |
|
|
146
158
|
| "Node NN detected — specsketch needs Node >= 22" | Upgrade Node (https://nodejs.org) |
|
|
147
159
|
| Port already in use | Handled automatically — the server moves to the next free port and prints it; `--port <n>` sets the preferred starting port |
|
|
148
160
|
| Regeneration changed a file you hand-edited | Expected when the drawing implicates it — the diagram is the source of truth; use `git diff`/`git checkout` to recover, and keep change dirs in version control |
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
Diagram a system with your team in real time, talk it through, and turn the result into an
|
|
158
|
-
**OpenSpec** change proposal. Boxes and arrows + conversation in → a reviewable, spec-shaped
|
|
159
|
-
proposal out.
|
|
160
|
-
|
|
161
|
-
This repo is **spec-first**: `openspec/` is the source of truth for what SpecSketch does. The
|
|
162
|
-
code in `src/` is the Phase 1 reference implementation of those specs.
|
|
163
|
-
|
|
164
|
-
## Product shape (phased)
|
|
165
|
-
|
|
166
|
-
- **Phase 1 — diagram → spec (built).** A single browser session: draw an architecture on an
|
|
167
|
-
Excalidraw canvas, press **Generate Spec**, and an agentic workflow (Flue) returns an OpenSpec
|
|
168
|
-
change proposal (proposal / design / tasks / capability specs).
|
|
169
|
-
- **Phase 2 — real-time collaboration.** Multiple engineers on one server-authoritative canvas
|
|
170
|
-
(Durable Object over WebSocket), with presence and shareable session links.
|
|
171
|
-
- **Phase 3 — voice & specs-from-conversation.** Live audio/video over Cloudflare Realtime
|
|
172
|
-
(WebRTC), transcription, and feeding the transcript into spec generation.
|
|
173
|
-
|
|
174
|
-
## Architecture (Phase 1)
|
|
175
|
-
|
|
176
|
-
```
|
|
177
|
-
Browser (Workers Assets) Cloudflare Worker
|
|
178
|
-
┌───────────────────────────┐ ┌──────────────────────────────┐
|
|
179
|
-
│ React + @excalidraw │ POST │ src/app.ts (Hono @ /api) │
|
|
180
|
-
│ architecture canvas │ ───────► │ /api/workflows/spec-builder│
|
|
181
|
-
│ [Generate Spec] │ graph │ │ │
|
|
182
|
-
│ │ (JSON) │ ▼ │
|
|
183
|
-
│ ◄── OpenSpec artifacts ────┼──────────┤ Flue workflow (Durable │
|
|
184
|
-
└───────────────────────────┘ bundle │ Object) → Anthropic Claude │
|
|
185
|
-
│ │ structured output │
|
|
186
|
-
│ ▼ (SpecBundle) │
|
|
187
|
-
└──────────────────────────────┘
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
The client distills the raw Excalidraw scene into a compact `{nodes, edges, notes}` graph
|
|
191
|
-
(`src/ui/scene.ts`); the `spec-builder` workflow (`src/workflows/spec-builder.ts`) turns it into
|
|
192
|
-
a validated `SpecBundle` (`src/lib/schema.ts`), rendered as browsable artifacts.
|
|
193
|
-
|
|
194
|
-
## Stack
|
|
195
|
-
|
|
196
|
-
- **Cloudflare Workers + Workers Assets** — one Worker serves the SPA and the API.
|
|
197
|
-
- **Flue** (`@flue/runtime`, `@flue/cli`) — AI agent orchestration; each workflow is a Durable
|
|
198
|
-
Object. Provider: Anthropic (Claude); the Workers `AI` binding is also available.
|
|
199
|
-
- **Excalidraw** (`@excalidraw/excalidraw`) — the drawing surface.
|
|
200
|
-
- **valibot** — shared request/response schemas (UI + workflow).
|
|
201
|
-
- **Cloudflare Realtime** (Phase 3) — WebRTC SFU for audio/video.
|
|
202
|
-
|
|
203
|
-
## Getting started (local MVP)
|
|
204
|
-
|
|
205
|
-
Contributor flow for this repo (the published CLI above is built from the same code —
|
|
206
|
-
`npm run cli -- <change-dir>` builds and runs it from source; don't use
|
|
207
|
-
`npx @coopcli/specsketch` inside this repo, since npx resolves the name to the local
|
|
208
|
-
checkout instead of the registry).
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
npm install
|
|
212
|
-
npm run dev # web (Vite, http://localhost:5173) + api (Hono/Node, :8787)
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
Open <http://localhost:5173> — a unique canvas URL is minted automatically. Draw labeled boxes
|
|
216
|
-
and arrows, click **Generate Spec**, then use the top-bar **Canvas | Spec** toggle to read the
|
|
217
|
-
generated OpenSpec proposal.
|
|
218
|
-
|
|
219
|
-
**Auth:** the backend calls Anthropic via `new Anthropic()` with no key configured — the SDK
|
|
220
|
-
resolves the local authed session (`ANTHROPIC_API_KEY` → `ANTHROPIC_AUTH_TOKEN` → the active
|
|
221
|
-
`ant auth login` / Claude Code profile). As a dev convenience the local server also reads
|
|
222
|
-
`ANTHROPIC_API_KEY` from `.dev.vars` (the same file the Cloudflare dev flow uses) when the
|
|
223
|
-
environment has no credentials. If a generate call 401s, run `ant auth status`; never paste a
|
|
224
|
-
key into the code.
|
|
225
|
-
|
|
226
|
-
Other scripts:
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
npm run check # tsc --noEmit
|
|
230
|
-
npm test # vitest — unit + integration tests, no credentials needed
|
|
231
|
-
npm run server # api only (tsx watch server/index.ts)
|
|
232
|
-
npm run web # web only (vite)
|
|
233
|
-
npm run smoke # live end-to-end check against a running server (needs auth)
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
See [TESTING.md](TESTING.md) for the manual QA checklist mapped to the OpenSpec scenarios.
|
|
237
|
-
|
|
238
|
-
### Cloudflare/Flue production path
|
|
239
|
-
|
|
240
|
-
The Cloudflare deployment (single Worker + Flue Durable Objects) is kept intact under the
|
|
241
|
-
`*:cf` scripts and is not used by the local MVP:
|
|
242
|
-
|
|
243
|
-
```bash
|
|
244
|
-
cp .dev.vars.example .dev.vars # add your ANTHROPIC_API_KEY
|
|
245
|
-
npm run dev:cf # build the UI, then flue dev --target cloudflare (http://localhost:3583)
|
|
246
|
-
npm run build:cf # vite build → flue build --target cloudflare → patch asset binding
|
|
247
|
-
npx wrangler secret put ANTHROPIC_API_KEY
|
|
248
|
-
npm run deploy:cf # build, then wrangler deploy the generated config
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
## OpenSpec roadmap
|
|
252
|
-
|
|
253
|
-
All outcomes are defined as validated OpenSpec change proposals under `openspec/changes/`.
|
|
254
|
-
Each change is a thin, independently implementable/testable slice; its spec scenarios are the QA
|
|
255
|
-
acceptance criteria. Run `npx openspec list` / `npx openspec validate --all`.
|
|
256
|
-
|
|
257
|
-
| Phase | Change | Capability(ies) | Status |
|
|
258
|
-
|-------|--------|-----------------|--------|
|
|
259
|
-
| 1 | `phase-1-diagram-to-spec` | architecture-canvas, diagram-interpretation, spec-generation, openspec-artifacts, worker-platform | scaffold built |
|
|
260
|
-
| 2 | `canvas-room-durable-object` | canvas-room | proposed |
|
|
261
|
-
| 2 | `realtime-canvas-sync` | realtime-canvas-sync | proposed |
|
|
262
|
-
| 2 | `collaboration-presence` | collaboration-presence | proposed |
|
|
263
|
-
| 2 | `shareable-session-links` | shareable-session-links | proposed |
|
|
264
|
-
| 3 | `realtime-voice-signaling` | realtime-voice-session | proposed |
|
|
265
|
-
| 3 | `voice-audio` | voice-audio | proposed |
|
|
266
|
-
| 3 | `participant-video` | participant-video | proposed |
|
|
267
|
-
| 3 | `conversation-transcription` | conversation-transcription | proposed |
|
|
268
|
-
| 3 | `transcript-informed-specs` | transcript-informed-specs | proposed |
|
|
269
|
-
| — | `spec-persistence-and-export` | spec-persistence-and-export | proposed |
|
|
270
|
-
| — | `coopcli-specsketch-distribution` | npm-distribution, local-persistence, product-microsite | shipped (v0.1.0 on npm; microsite live) |
|
|
271
|
-
|
|
272
|
-
Suggested implementation order follows the table (each Phase 2/3 change builds on the one above
|
|
273
|
-
it). The `spec-builder` workflow already dogfoods this format — its output is exactly these
|
|
274
|
-
artifacts.
|
|
275
|
-
|
|
276
|
-
## Notes
|
|
277
|
-
|
|
278
|
-
- **Model**: pinned to a verified Flue specifier in one constant in `src/workflows/spec-builder.ts`;
|
|
279
|
-
bump it there as newer Claude specifiers are confirmed in Flue's provider mapping.
|
|
280
|
-
- **Flue beta asset binding**: `flue build` (beta) regenerates the Cloudflare config and currently
|
|
281
|
-
drops the user `assets` block, so `scripts/patch-assets.mjs` re-injects it after the build. Once
|
|
282
|
-
Flue propagates user asset config, delete that script and its `build` step.
|
|
161
|
+
| `--share` says it needs login | Run `specsketch login` once on the hosting machine; `--profile` selects a non-default CoopCLI config profile |
|
|
162
|
+
| Share link says it no longer works | The host ended the session (Ctrl-C) or it idled out — ask for a fresh link |
|
|
163
|
+
|
|
164
|
+
More: [product page](https://coopcli.com/products/specsketch) ·
|
|
165
|
+
[docs](https://coopcli.com/products/specsketch/docs/). Sibling product:
|
|
166
|
+
[specplan](https://coopcli.com/products/specplan/) — plan the roadmap those changes live
|
|
167
|
+
on. Source, contributor setup, and the QA checklist live in the
|
|
168
|
+
[coopcli repo](https://github.com/jtaylorcpp/coopcli) (`packages/specsketch`).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coopcli/specsketch",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.1",
|
|
4
4
|
"description": "coopcli specsketch \u2014 draw an architecture diagram, generate an OpenSpec change proposal into your openspec/ change directory. Local-only.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|