@misterhuydo/cairn-mcp 1.30.0 → 1.32.0
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 +57 -13
- package/dist/cairn-cli.js +63 -63
- package/dist/index.js +67 -67
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -225,6 +225,32 @@ invisible:
|
|
|
225
225
|
instead of "go and find it". A link that cannot be resolved is dropped rather than
|
|
226
226
|
emitted dead.
|
|
227
227
|
|
|
228
|
+
The two halves answer different questions and deliberately disagree. The reader half
|
|
229
|
+
hides shipped and abandoned work so what is *next* leads. The JSON half publishes the
|
|
230
|
+
plan **complete** — `done` and `stale` phases stay in `phases` with their real status,
|
|
231
|
+
because a consumer that cannot see finished work will confidently render an incomplete
|
|
232
|
+
plan. A shipped phase also carries `shipped` (the date) and `commit` (short HEAD when it
|
|
233
|
+
was marked done), which is what turns "this was done" into something you can point an
|
|
234
|
+
agent at when you are tracing a bug back to where it came from. Phases from *superseded*
|
|
235
|
+
plans, whose numbers a later plan reclaimed, move to a separate `shipped_phases` array —
|
|
236
|
+
identity and provenance only, no `detail`, so a long-lived repo's history cannot bloat
|
|
237
|
+
the file. That key is always present; its absence means the file predates this.
|
|
238
|
+
|
|
239
|
+
Three rules the format leaves implicit, each of which has cost a consumer real time:
|
|
240
|
+
|
|
241
|
+
- **The `roadmap-json` block is terminated by a fence at the start of a line.** Match it
|
|
242
|
+
that way, not with a naive non-greedy `` ``` ``. This is safe by construction: a
|
|
243
|
+
newline inside a JSON string is escaped, so an embedded fence can never begin a line
|
|
244
|
+
and only the real terminator can.
|
|
245
|
+
- **`detail` may itself contain fenced code**, which is exactly why the rule above
|
|
246
|
+
matters. A consumer that ends the block at the first `` ``` `` it meets can end it
|
|
247
|
+
*inside* a JSON string and spill ~125KB of machine data onto the page as prose.
|
|
248
|
+
- **`cursor` may name a slice, not a top-level phase.** It is the exact focus. To mark
|
|
249
|
+
one phase current, use `cursor_phase`, which is always the top-level ancestor and
|
|
250
|
+
always resolves in `phases`; `cursor_path` is the root-to-focus chain for breadcrumbs.
|
|
251
|
+
All three are `null` when nothing is active, so "nothing is in progress" is never
|
|
252
|
+
ambiguous with a broken pointer.
|
|
253
|
+
|
|
228
254
|
The first line is the marker that says who generated the file and when
|
|
229
255
|
(`<!-- slot:roadmap format=roadmap/1 provider=cairn generated=… -->`). cairn declares
|
|
230
256
|
the slot in its MCP entry in `~/.claude.json`, so a cockpit does not have to guess.
|
|
@@ -348,19 +374,37 @@ is least reason to speak. Bytes survive now only as a fallback for when no usage
|
|
|
348
374
|
record is reachable, and when that happens the line says so instead of dressing a
|
|
349
375
|
file size up as a token count.
|
|
350
376
|
|
|
351
|
-
**It only speaks at 90% of the window and above
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
377
|
+
**It only speaks at 90% of the window and above** — and the window is a setting, not
|
|
378
|
+
a measurement. Nothing cairn can read carries it: no hook input has it, the
|
|
379
|
+
transcript records usage but never a limit, and the model id is no help either
|
|
380
|
+
because a `claude-opus-5[1m]` session writes the base `claude-opus-5` into both the
|
|
381
|
+
transcript's `message.model` and `lastModelUsage` in `~/.claude.json`.
|
|
382
|
+
|
|
383
|
+
Through v1.31.0 cairn guessed the *smallest* window that could hold what it had
|
|
384
|
+
measured, which meant an unmeasured session was assumed to be 200k. That produced a
|
|
385
|
+
guaranteed false-alarm band: on a 1M session, every reading between 180k and 196k
|
|
386
|
+
looked like a nearly-full 200k one. It was measured live at 192,634 tokens, where
|
|
387
|
+
cairn reported **96%** and `/context` said **19%**. The band is structural rather
|
|
388
|
+
than a tuning error — any firing point for a 200k window is a point a 1M session
|
|
389
|
+
also passes through — so no threshold can serve both, and the tie-break has to come
|
|
390
|
+
from outside.
|
|
391
|
+
|
|
392
|
+
Since v1.32.0 cairn never guesses downward. Unset, it assumes the widest window it
|
|
393
|
+
knows about and stays quiet; the cost of that being wrong is one missed nudge on a
|
|
394
|
+
genuinely full small window, against an interruption at a fifth of capacity that
|
|
395
|
+
teaches you to ignore the line for good. Measurement still raises the floor — having
|
|
396
|
+
*seen* 482k tokens proves the window is bigger than that — it simply can never lower
|
|
397
|
+
it.
|
|
398
|
+
|
|
399
|
+
If your window really is 200k, say so and both the threshold and the reported
|
|
400
|
+
percentage become exact:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
export CAIRN_CONTEXT_WINDOW=200000
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
`CAIRN_CONTEXT_HINT_TOKENS` still overrides the trigger point outright if you want a
|
|
407
|
+
different bar rather than a different window.
|
|
364
408
|
|
|
365
409
|
Deliberately not built: no full transcript walk (the tail only; a full walk in this
|
|
366
410
|
hot path once froze every terminal in the cockpit for 4.3 seconds), no counting
|