klypix-mcp 1.106.2 → 1.107.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/A2A.md +1 -1
- package/README.md +58 -11
- package/bin/klypix-a2a.mjs +1 -1
- package/bin/klypix-conformance.mjs +2 -1
- package/bin/klypix-install.mjs +7 -3
- package/bin/klypix-mcp.mjs +9 -1
- package/bin/klypix-worker.mjs +71 -2
- package/package.json +3 -3
- package/src/brain-rules.mjs +1673 -0
- package/src/codex-brain-hook.mjs +16 -0
- package/src/global-brain-hook.mjs +152 -29
- package/src/klypix-core.mjs +96 -11
- package/src/klypix-format.mjs +283 -17
- package/src/mcp-presence.mjs +18 -0
- package/src/project-graph.mjs +5 -1
package/A2A.md
CHANGED
|
@@ -55,7 +55,7 @@ the skills below.
|
|
|
55
55
|
|---|---|---|
|
|
56
56
|
| `make_board` | Create a new `.klypix` from cards + connections | a `.klypix` **FilePart** + summary |
|
|
57
57
|
| `remember` | Append cards/decisions to an existing canvas (positions preserved) | result summary; flat card appends also return a `.klypix` FilePart |
|
|
58
|
-
| `learn_skill` | Capture a reusable how-to / gotcha as a 🛠 skill card —
|
|
58
|
+
| `learn_skill` | Capture a reusable how-to / gotcha as a 🛠 skill card — kept until corrected; shown first to sessions that touch the files it names | result summary |
|
|
59
59
|
| `recall` | Search card text/titles/`#tags` across the vault | matching cards (text) |
|
|
60
60
|
| `read_canvas` | Read one canvas (cards, graph, `[[links]]`) + its images | markdown + image FileParts |
|
|
61
61
|
| `list_canvases` | List canvases with counts | text |
|
package/README.md
CHANGED
|
@@ -56,8 +56,8 @@ You need **Node.js 20 or newer** (`node -v`).
|
|
|
56
56
|
`brain_sync` in other hosts. A correction replaces the old decision, and the old card stays as
|
|
57
57
|
history.
|
|
58
58
|
- **A heads-up when work overlaps.** Each session says what it is doing and which files it expects
|
|
59
|
-
to touch. When two sessions name the same file, both are warned.
|
|
60
|
-
edit. This works on one computer. With [KLYPIX network](https://klypix.com/network)
|
|
59
|
+
to touch. When two sessions name the same file, both are warned. For overlapping work KLYPIX
|
|
60
|
+
warns; it never blocks an edit. This works on one computer. With [KLYPIX network](https://klypix.com/network)
|
|
61
61
|
installed on both computers (klypix-mcp 1.106.0 or later), it also lists sessions in the same
|
|
62
62
|
project on a teammate's computer.
|
|
63
63
|
- **Notes and handoffs between sessions.** An agent can leave a note for another session, even one
|
|
@@ -69,6 +69,11 @@ You need **Node.js 20 or newer** (`node -v`).
|
|
|
69
69
|
git command that would sweep another live session's uncommitted work into your commit is stopped.
|
|
70
70
|
A command that would throw work away saves a rescue copy first, then asks you. It covers git
|
|
71
71
|
commands run through Claude Code's tools, on one computer.
|
|
72
|
+
- **Lessons that catch the repeat mistake.** A lesson the brain recorded can become a project rule
|
|
73
|
+
that a person approves: a check of the diff, with no AI at check time. A rule warns when a session
|
|
74
|
+
plans its files, while it edits and at commit. Only a rule the person approves as blocking stops
|
|
75
|
+
the work: Claude Code before it writes the forbidden line (Codex is warned), and an opt-in git
|
|
76
|
+
hook at commit, for any tool or person. Rules check the diff; they do not run your tests.
|
|
72
77
|
- **A file you own.** The brain is one `.klypix` file in your repo: a plain ZIP, versioned with
|
|
73
78
|
Git. The engine is Apache-2.0, runs on your machine, and works without the KLYPIX app or an
|
|
74
79
|
account. Brain data stays in your files; your agent's model provider still receives what the
|
|
@@ -88,7 +93,7 @@ has the details.
|
|
|
88
93
|
| **Claude Desktop** | A one-time config entry | The KLYPIX app's Settings, or by hand |
|
|
89
94
|
| **Claude, as a plugin** | One pinned version, keyword search, no hooks | [klypix-plugin](https://github.com/dahshanlabs/klypix-plugin) |
|
|
90
95
|
|
|
91
|
-
klypix-mcp
|
|
96
|
+
klypix-mcp has 27 MCP tools on Linux and macOS and 28 on Windows, where `show_in_klypix` is
|
|
92
97
|
added. `npx klypix-mcp doctor` shows the count for your install.
|
|
93
98
|
|
|
94
99
|
> **One project. Many agents. One current understanding.**
|
|
@@ -118,14 +123,15 @@ tool's official documentation and says that KLYPIX wrote it) · [klypix.com/klyp
|
|
|
118
123
|
- **[Reference](#reference):** [How the brain works](#how-the-brain-works) ·
|
|
119
124
|
[Supported hosts](#supported-hosts-and-their-integration-level) ·
|
|
120
125
|
[Running as a Claude plugin](#running-as-a-claude-plugin) · [Task briefing](#task-briefing) ·
|
|
121
|
-
[Capture and corrections](#capture-and-corrections) · [
|
|
126
|
+
[Capture and corrections](#capture-and-corrections) · [Project rules](#project-rules-lessons-that-stop-the-repeat) ·
|
|
127
|
+
[Presence and task intent](#presence-and-task-intent) ·
|
|
122
128
|
[Overlap warnings](#overlap-warnings) ·
|
|
123
129
|
[Teammates on other computers](#teammates-on-other-computers-klypix-network) ·
|
|
124
130
|
[Handoffs and messages](#handoffs-and-messages) · [Evidence-gated completion](#evidence-gated-completion) ·
|
|
125
131
|
[Human control in KLYPIX](#human-control-in-klypix) · [Measure it yourself](#measure-it-yourself) ·
|
|
126
132
|
[Git and concurrency](#git-and-concurrency) ·
|
|
127
133
|
[The git guard for a shared checkout](#whose-is-this-the-git-guard-for-a-shared-checkout) ·
|
|
128
|
-
[The command line](#the-command-line) · [The verbs](#the-verbs-
|
|
134
|
+
[The command line](#the-command-line) · [The verbs](#the-verbs-27-and-28-on-windows) ·
|
|
129
135
|
[One file you can hold](#one-file-you-can-hold) · [Use it as a library](#use-it-as-a-library) ·
|
|
130
136
|
[A2A](#also-speaks-a2a-protocol-v030--experimental) ·
|
|
131
137
|
[Updates](#updates--the-propagation-contract) · [Security and permissions](#security-and-permissions) ·
|
|
@@ -561,9 +567,9 @@ on cards, and, on a call that needs the running app, the app's bridge token (abo
|
|
|
561
567
|
|
|
562
568
|
| Where | What | Why |
|
|
563
569
|
|---|---|---|
|
|
564
|
-
| Your project | Only what a tool call asks for: `brain.klypix` (`brain_note` and the other brain tools), canvases (`create_canvas`, `add_to_canvas`), `klypix-map/graph.json` when `project_map_scan` is called,
|
|
570
|
+
| Your project | Only what a tool call asks for: `brain.klypix` (`brain_note` and the other brain tools), canvases (`create_canvas`, `add_to_canvas`), `klypix-map/graph.json` when `project_map_scan` is called, `.klypix/claims/<owner>.json` when `brain_sync` is asked to publish a release claim, and `.klypix/rules.json` when `brain_rules` adds, approves or retires a rule. Only when you run `npx klypix-mcp check --install-hook`: a marked block in `.git/hooks/pre-commit`, `pre-push` and `post-commit`; `npx klypix-mcp rules allow` keeps its one-hour exception in `.git/klypix-rules-allow.json`. During a brain write it holds `.claude/brain-capture.lock`, creating the `.claude/` folder if the project has none. The lock file is deleted after the write; the folder stays. Creating a canvas briefly holds `.klypix-create.lock` in the folder. | The KLYPIX app and every other session that writes the brain use the same locks, so two writers never overwrite each other. |
|
|
565
571
|
| The plugin's data folder (`KLYPIX_PLUGIN_DATA`) | Connection receipts (`.supervisors/`), the running-server heartbeat (`.running-servers.json`), the list of projects whose brains you used (`registry.json`, which `search_all_brains` reads), and the last version and git tag seen in each project (`ship-observations/`). Also `extracted/`: copies of the PDFs, Office and other files `read_card_contents` hands to your AI tool as a local path, taken from the canvas you asked about. | Only this server uses these files. If `KLYPIX_PLUGIN_DATA` is not set, or still contains a `${...}` that was never filled in, it uses `CLAUDE_PLUGIN_DATA`. If neither is usable, the files go in `~/.claude/project-brain`, except `extracted/`, which then goes in `<system temp>/klypix-mcp/extracted` (where it always goes outside plugin mode). |
|
|
566
|
-
| `~/.claude/project-brain` (shared) | Presence lanes (`sessions/`), write locks (`locks/`), restore points (`history/`), and small records built from your brain: `.capture-gap.json`, and `enrichment/`, `provenance/`, `.brief-cache-*` and `.guards-*` when the tools that use them run. | Your other KLYPIX sessions on this computer (Claude Code, Codex, Cursor, the app) use the same files on purpose. Through them, a plugin session and a terminal session on the same project see each other, get warnings when they plan to edit the same files, and pass notes. Restore points are kept here so that `npx klypix-mcp brain-history` can still undo a brain write after you remove the plugin. |
|
|
572
|
+
| `~/.claude/project-brain` (shared) | Presence lanes (`sessions/`), write locks (`locks/`), restore points (`history/`), and small records built from your brain: `.capture-gap.json`, and `enrichment/`, `provenance/`, `.brief-cache-*` and `.guards-*` when the tools that use them run. `rules/` counts how often each project rule fired, blocked or was overridden on this computer. | Your other KLYPIX sessions on this computer (Claude Code, Codex, Cursor, the app) use the same files on purpose. Through them, a plugin session and a terminal session on the same project see each other, get warnings when they plan to edit the same files, and pass notes. Restore points are kept here so that `npx klypix-mcp brain-history` can still undo a brain write after you remove the plugin. |
|
|
567
573
|
|
|
568
574
|
**`brain_reopen`.** Sometimes a session leaves a note for another session that has already closed.
|
|
569
575
|
An agent can then call `brain_reopen`, and KLYPIX asks you first: in chat with *Reopen* and *Not
|
|
@@ -586,7 +592,10 @@ Every other host gets a bounded ~2.8KB task capsule from one `brain_sync` call,
|
|
|
586
592
|
always-loaded `AGENTS.md` block that tells the agent to make that call at task start, when scope
|
|
587
593
|
changes, and on completion. The gateway capsule is lexical-fast by design. A newly captured open
|
|
588
594
|
gap can claim a labeled `RECENT OPEN` slot only after clearing the normal lexical-relevance floor,
|
|
589
|
-
so fresh relevant findings are not crowded out by older area vocabulary.
|
|
595
|
+
so fresh relevant findings are not crowded out by older area vocabulary. When the call declares
|
|
596
|
+
`files`, the lessons that name those files come first, under "Lessons for your files": at most
|
|
597
|
+
four, ranked exact path, then file name, glob and folder. The Claude Code brief does the same for
|
|
598
|
+
the files the checkout is changing (uncommitted, and the last three commits), then lists the newest.
|
|
590
599
|
|
|
591
600
|
Briefs are **not** injected automatically on Cursor, Cline, Copilot, Gemini CLI or Antigravity —
|
|
592
601
|
there are no lifecycle hooks on those hosts.
|
|
@@ -648,7 +657,9 @@ On Claude Code, decisions are captured automatically at turn end from inline `
|
|
|
648
657
|
markers in the transcript, deduped, under a capture lock.
|
|
649
658
|
|
|
650
659
|
A marker can end with optional suffixes, in any order: `closes: <card title or [[wikilink]]>`,
|
|
651
|
-
`ev: <file[:line]>, PR#<n>`, `verify: <command
|
|
660
|
+
`ev: <file[:line]>, PR#<n>`, `verify: <command>`, `q: <the question this answers?>` and
|
|
661
|
+
`rule: <glob>[,<glob>] never "<text>"` (or `never /<regex>/`, `must "<text>"`,
|
|
662
|
+
`listed-in <file>[,<file>]`, `keep-eol`, `costly`). They count
|
|
652
663
|
only as one run at the end of the line, written lowercase as `key: value`, and each value must
|
|
653
664
|
have its key's shape: references for `ev:`, a command for `verify:`, a question (question word
|
|
654
665
|
first, `?` last) for `q:`. Anything else is kept as card text, so "a Q: and A: layout", "the ev:
|
|
@@ -663,6 +674,13 @@ content words and under half the card's) is appended to that card as a dated `(~
|
|
|
663
674
|
instead. The card keeps its date, colour and probe, and previews show the newest amendment first.
|
|
664
675
|
The correction lands and nothing is lost.
|
|
665
676
|
|
|
677
|
+
A `rule:` suffix makes a new lesson (a decision, `+` or `!`) rule-ready. Its globs must name files
|
|
678
|
+
tracked in the repository and a `/regex/` must compile; the rule lands as a visible
|
|
679
|
+
`⚙ rule candidate:` line on a 🛠️ card, and `brain_rules` propose reads it before any prose. It
|
|
680
|
+
checks nothing until a person approves the rule. A rule that fails those checks is not recorded,
|
|
681
|
+
the lesson is, and the hook says why on the next prompt. `brain_note` takes the same suffix at the
|
|
682
|
+
end of its text.
|
|
683
|
+
|
|
666
684
|
The Stop hook reads the whole transcript every time, so a `~` or `✓` line applies once. A marker
|
|
667
685
|
that an older hook (1.85 or 1.86.0) already captured is not captured again after an upgrade. If
|
|
668
686
|
1.86.0 cut the note short, the stub is restored to the full text in place. When a marker does not
|
|
@@ -684,6 +702,27 @@ only (explicit correction cues, opposite-polarity pairs), never mere topical sim
|
|
|
684
702
|
means no contradiction signal was found — not verified consistency. A memory that cannot disagree
|
|
685
703
|
with you is flattery.
|
|
686
704
|
|
|
705
|
+
### Project rules: lessons that stop the repeat
|
|
706
|
+
|
|
707
|
+
Some lessons can be checked in a diff: *every new route must also be in the route list*, *tests
|
|
708
|
+
in this folder must import shared code relatively*, *this file's line endings must not change*. `brain_rules` turns those
|
|
709
|
+
lessons into rules in `.klypix/rules.json`, each citing the card it came from. A person approves
|
|
710
|
+
each rule with a code only they can print (`npx klypix-mcp rules code promote <ids>`). Until then
|
|
711
|
+
the rule is a candidate and checks nothing.
|
|
712
|
+
|
|
713
|
+
An active rule runs in three places: `brain_sync` names the rules for a session's files, the edit
|
|
714
|
+
hook reports findings to Claude Code and Codex as they edit, and the opt-in git hooks
|
|
715
|
+
(`npx klypix-mcp check --install-hook`) print them at commit and push. Rules warn by default. A
|
|
716
|
+
rule the person approves with `--block` stops the commit or push for any tool or person, and stops
|
|
717
|
+
Claude Code before it writes a forbidden line; Codex is only warned, because its hooks cannot
|
|
718
|
+
deny. A check is glob, regex and line-ending work over the diff: it takes
|
|
719
|
+
milliseconds, runs offline and uses no model. Overrides, bypasses and false alarms are recorded in
|
|
720
|
+
the brain, and `npx klypix-mcp rules` shows each rule's blocks, overrides and false alarms.
|
|
721
|
+
|
|
722
|
+
How to write, approve and retire rules: [docs/brain-rules.md](docs/brain-rules.md). To see what a
|
|
723
|
+
set of rules would have flagged on a repository's own history, `scripts/brain-rules-proof.mjs`
|
|
724
|
+
replays them over its pull requests and failed Actions logs, with what those runs cost.
|
|
725
|
+
|
|
687
726
|
### Presence and task intent
|
|
688
727
|
|
|
689
728
|
An active session means an authorized MCP connection or host lifecycle adapter that heartbeated
|
|
@@ -1164,10 +1203,12 @@ The MCP verbs below are what agents call. These are what **you** call:
|
|
|
1164
1203
|
| `npx klypix-mcp diff [ref]` | Card-level brain diff against a git ref, as markdown |
|
|
1165
1204
|
| `npx klypix-mcp pr-brief [ref]` | Brain cards referencing the files changed since a ref, as markdown |
|
|
1166
1205
|
| `npx klypix-mcp garden-code` | Print the human approval code `brain_garden` requires |
|
|
1206
|
+
| `npx klypix-mcp check` | Run this project's rules (`.klypix/rules.json`) on the working tree, `--staged`, or `--base <ref>`; `--install-hook` wires the opt-in pre-commit, pre-push and post-commit hooks |
|
|
1207
|
+
| `npx klypix-mcp rules` | The person's side of project rules: per-rule counts and suggestions, `code promote\|retire <ids>` (the approval code), `allow <id> --reason` (one hour), `false-alarm <id> --reason` |
|
|
1167
1208
|
| `npx klypix-mcp rescue` | Rescue copies the git guard saved before a discard: `list`, `show <id>`, `restore <id> [paths…]`, `prune` |
|
|
1168
1209
|
| `npx klypix-mcp sessions` | This project's closed sessions and the notes waiting for them; `sessions reopen <id>` reopens one |
|
|
1169
1210
|
|
|
1170
|
-
### The verbs:
|
|
1211
|
+
### The verbs: 27, and 28 on Windows
|
|
1171
1212
|
|
|
1172
1213
|
| Tool | What it does |
|
|
1173
1214
|
|---|---|
|
|
@@ -1178,6 +1219,7 @@ The MCP verbs below are what agents call. These are what **you** call:
|
|
|
1178
1219
|
| `brain_insights` | Hubs, orphaned decisions, stale questions, area sizes |
|
|
1179
1220
|
| `brain_lens` | Machine-readable freshness, provenance, activity, timeline, orrery and unresolved views; on a canvas open in KLYPIX (Windows), the first five come from KLYPIX's own lens code |
|
|
1180
1221
|
| `brain_garden` | Maintenance pass — proposes first; consolidation cannot apply without an approval code the human generates. The separate `repair:"duplicate-partials"` pass is dry-run first and needs no code (it removes only exact repeats and archives nothing) |
|
|
1222
|
+
| `brain_rules` | Project rules made from the brain's lessons: `propose` routes each lesson to rule, instruction or note; `add` writes candidates to `.klypix/rules.json`; `promote` and `retire` need the person's approval code, and a rule warns unless the person approved it with `--block`; `check` runs the rules on a diff; `status` shows blocks, overrides, false alarms and retirement suggestions. No AI at check time ([docs/brain-rules.md](docs/brain-rules.md)) |
|
|
1181
1223
|
| `brain_doctor` | Self-diagnosis: version, core/enhanced host adapters, active sessions, tool count, projection drift |
|
|
1182
1224
|
| `brain_message` | Session-to-session coordination notes — to a live session, or queued for one that is not running until it next starts — with a fixed send-time audience and per-recipient pending / offer / acknowledgement / consumption / failure receipts (a directed note is kept 7 days, a broadcast 24h; never written into the brain) |
|
|
1183
1225
|
| `brain_message_receipt` | Explicitly record model-side consumption using the exact message id and per-recipient offer token; acknowledgement alone never consumes a note |
|
|
@@ -1199,7 +1241,7 @@ The MCP verbs below are what agents call. These are what **you** call:
|
|
|
1199
1241
|
| `add_to_canvas` | Append cards/connections (positions preserved), bordered and readable on KLYPIX's dark and Paper themes; a card's `group` puts it in that titled box. On a canvas open in KLYPIX (Windows) the cards go to KLYPIX itself: live, attributed, one undo. When KLYPIX cannot take them it refuses (`OPEN_IN_APP`, `ACCESS_OFF`, `BLOCKED`), a box locked from AI tools (`SCOPE_LOCKED`) or a frozen box (`FROZEN`), and writes nothing; project brains are the exception to the first. Returns the new card ids |
|
|
1200
1242
|
| `list_canvases` | List every `.klypix` in the vault |
|
|
1201
1243
|
|
|
1202
|
-
Exactly
|
|
1244
|
+
Exactly 27 on Linux and macOS and 28 on Windows, where `show_in_klypix` is registered; machine-verifiable with `npx klypix-mcp doctor`, whose TOOLS line applies the same rule and whose App bridge line says whether KLYPIX is running, with access on or off.
|
|
1203
1245
|
|
|
1204
1246
|
> **`canvas_view`:** no MCP Apps host has been observed rendering the UI resource yet — there is no
|
|
1205
1247
|
> screenshot and no host-level test. Hosts without the extension get clean text, which is the path
|
|
@@ -1413,6 +1455,11 @@ Read this section before you build on any of it.
|
|
|
1413
1455
|
`src/auth/token.ts` does not match a rename. Folder overlap is advisory. The merge test sees
|
|
1414
1456
|
committed work only, needs git 2.38 or newer, and runs only for sessions on different local
|
|
1415
1457
|
branches of the same repository.
|
|
1458
|
+
- **Project rules check the diff, not behaviour.** They see file names, added lines, line endings
|
|
1459
|
+
and paths; they do not run code or tests. They warn unless the person approved them with
|
|
1460
|
+
`--block`; Codex is warned, not stopped, while it edits, and the commit hooks are opt-in per
|
|
1461
|
+
clone. The approval code and the refusal inside agent shells prevent accidents; they do not stop
|
|
1462
|
+
a deliberate workaround.
|
|
1416
1463
|
- **Overlap warnings are advisory.** Nothing is blocked. One severity string in the payload reads
|
|
1417
1464
|
`blocking`; the mechanism is not.
|
|
1418
1465
|
- **Codex has no automatic capture**, with or without `--codex-hooks`. The Codex hook never writes
|
package/bin/klypix-a2a.mjs
CHANGED
|
@@ -132,7 +132,7 @@ function agentCard(publicUrl) {
|
|
|
132
132
|
{
|
|
133
133
|
id: 'learn_skill',
|
|
134
134
|
name: 'Learn a reusable skill (how-to / gotcha)',
|
|
135
|
-
description: 'Record a 🛠️ SKILL — a reusable how-to, gotcha, or convention ("always dedup zKeys before REORDER") that
|
|
135
|
+
description: 'Record a 🛠️ SKILL — a reusable how-to, gotcha, or convention ("always dedup zKeys before REORDER") that is kept until corrected and shown first to sessions that touch the files it names, distinct from a one-time decision. Routes through the capture engine with the "+" marker. A delegating agent uses this to teach the shared brain how work is done here, so every future agent inherits it. Plain "remember" auto-promotes to a skill when the text reads as a general rule.',
|
|
136
136
|
tags: ['memory', 'skill', 'how-to', 'procedure', 'brain', 'learn'],
|
|
137
137
|
examples: ['Learn this gotcha: never set backgroundThrottling false — it breaks visibility detection', 'Remember the convention: Electron main imports must stay at top'],
|
|
138
138
|
inputModes: ['text/plain', 'application/json'],
|
|
@@ -134,7 +134,8 @@ try {
|
|
|
134
134
|
metrics.startAttempts = { first: aStarted.attempt, second: bStarted.attempt };
|
|
135
135
|
const aStructured = aStart.structuredContent || {};
|
|
136
136
|
const bStructured = bStart.structuredContent || {};
|
|
137
|
-
checks.taskMemory = Array.isArray(aStructured.context?.hits) && aStructured.context.hits.length > 0
|
|
137
|
+
checks.taskMemory = (Array.isArray(aStructured.context?.hits) && aStructured.context.hits.length > 0)
|
|
138
|
+
|| (Array.isArray(aStructured.context?.fileLessons) && aStructured.context.fileLessons.length > 0);
|
|
138
139
|
checks.truthfulTaskCount = bStructured.counts?.activeTasks === 2
|
|
139
140
|
&& bStructured.peers?.length === 1;
|
|
140
141
|
checks.exactBlockingOverlap = bStructured.conflicts?.length === 1
|
package/bin/klypix-install.mjs
CHANGED
|
@@ -349,7 +349,9 @@ const flatten = (code) => code
|
|
|
349
349
|
// app bridge, which imports the protocol.
|
|
350
350
|
// session-handoff (1.99.1): the worker's brain_sync imports CONTINUE_RE and
|
|
351
351
|
// formatHandoffCards from it directly (1.99.0 only reached it via core).
|
|
352
|
-
|
|
352
|
+
// brain-rules (project rules): the worker's brain_rules tool and the
|
|
353
|
+
// dispatcher's `check` / `rules` verbs import it lazily.
|
|
354
|
+
.replace(/\.\.\/src\/(bench|brain-doctor|agent-presence|agent-rules|capture-gap|enrichment|finding-routing|mcp-presence|mcp-supervisor|mcp-auto-update|presence-relay|repo-state|semantic-memory|runtime-inspector|project-graph|git-capture-install|app-lease|app-tools|app-bridge-protocol|app-bridge-client|session-handoff|brain-rules)\.mjs/g, './$1.mjs')
|
|
353
355
|
.replace(/klypix-worker\.mjs/g, 'klypix-mcp-worker.mjs')
|
|
354
356
|
.replace(/const PKG_VERSION = \(\(\) => \{[\s\S]*?\}\)\(\);/, `const PKG_VERSION = '${VERSION}'; // baked at install (flat layout has no package.json)`);
|
|
355
357
|
|
|
@@ -495,7 +497,7 @@ try {
|
|
|
495
497
|
// a newer klypix-format cannot. merge-brains and the driver ship here so
|
|
496
498
|
// brain-history's restore merge, the KLYPIX core and the git driver all
|
|
497
499
|
// find one engine in this directory.
|
|
498
|
-
for (const f of ['global-brain-hook.mjs', 'klypix-format.mjs', 'brain-graveyard.mjs', 'merge-brains.mjs', 'klypix-merge-driver.mjs', 'capture-gap.mjs', 'brain-semantic.mjs', 'semantic-memory.mjs', 'enrichment.mjs', 'provenance.mjs', 'brain-note.mjs', 'brain-evidence.mjs', 'brain-git-hook.mjs', 'git-capture-install.mjs', 'brain-history.mjs', 'app-lease.mjs', 'klypix-core.mjs', 'app-bridge-protocol.mjs', 'app-bridge-client.mjs', 'app-tools.mjs', 'card-files.mjs', 'brain-write-lock.mjs', 'agent-rules.mjs', 'brain-doctor.mjs', 'editor-detect.mjs', 'agent-presence.mjs', 'mcp-presence.mjs', 'repo-state.mjs', 'result-reconcile.mjs', 'finding-routing.mjs', 'presence-relay.mjs', 'network-bridge.mjs', 'mcp-supervisor.mjs', 'mcp-auto-update.mjs', 'runtime-inspector.mjs', 'project-graph.mjs', 'bench.mjs', 'codex-brain-hook.mjs', 'codex-hooks.mjs', 'session-handoff.mjs', 'live-projection.mjs', 'whose.mjs', 'whose-classify.mjs', 'whose-ledger.mjs', 'whose-rescue.mjs', 'canvas-view-app.html']) {
|
|
500
|
+
for (const f of ['global-brain-hook.mjs', 'klypix-format.mjs', 'brain-graveyard.mjs', 'merge-brains.mjs', 'klypix-merge-driver.mjs', 'capture-gap.mjs', 'brain-semantic.mjs', 'semantic-memory.mjs', 'enrichment.mjs', 'provenance.mjs', 'brain-note.mjs', 'brain-evidence.mjs', 'brain-git-hook.mjs', 'git-capture-install.mjs', 'brain-history.mjs', 'app-lease.mjs', 'klypix-core.mjs', 'app-bridge-protocol.mjs', 'app-bridge-client.mjs', 'app-tools.mjs', 'card-files.mjs', 'brain-write-lock.mjs', 'brain-rules.mjs', 'agent-rules.mjs', 'brain-doctor.mjs', 'editor-detect.mjs', 'agent-presence.mjs', 'mcp-presence.mjs', 'repo-state.mjs', 'result-reconcile.mjs', 'finding-routing.mjs', 'presence-relay.mjs', 'network-bridge.mjs', 'mcp-supervisor.mjs', 'mcp-auto-update.mjs', 'runtime-inspector.mjs', 'project-graph.mjs', 'bench.mjs', 'codex-brain-hook.mjs', 'codex-hooks.mjs', 'session-handoff.mjs', 'live-projection.mjs', 'whose.mjs', 'whose-classify.mjs', 'whose-ledger.mjs', 'whose-rescue.mjs', 'canvas-view-app.html']) {
|
|
499
501
|
const s = path.join(SRC, f); if (exists(s)) staged.push({ dst: f, content: fs.readFileSync(s, 'utf8') });
|
|
500
502
|
}
|
|
501
503
|
for (const [src, dst] of [
|
|
@@ -572,7 +574,9 @@ try {
|
|
|
572
574
|
// Guard cards (2026-08-24): pre-action lane. Fast path — reads only the
|
|
573
575
|
// compiled guard sidecar; 'warn' injects context, 'block' denies with
|
|
574
576
|
// the card's message. Absent guards = stat + one tiny read, then no-op.
|
|
575
|
-
|
|
577
|
+
// Project rules (.klypix/rules.json) ride the same lane for edits: a
|
|
578
|
+
// forbidden line is denied before it is written (MultiEdit included).
|
|
579
|
+
['PreToolUse', { matcher: 'Bash|PowerShell|Edit|Write|MultiEdit', hooks: [{ type: 'command', command: brainCmd('--guard'), timeout: 10 }] }],
|
|
576
580
|
// Session end (1.105.0): a closed or cut-off Claude Code session leaves
|
|
577
581
|
// the lane at once. Before this, only the 10-minute TTL removed it, so the
|
|
578
582
|
// next session read a dead peer as "live" and refused to continue its
|
package/bin/klypix-mcp.mjs
CHANGED
|
@@ -19,7 +19,7 @@ const PKG_VERSION = (() => {
|
|
|
19
19
|
}
|
|
20
20
|
})();
|
|
21
21
|
|
|
22
|
-
const DIRECT = new Set(['install', 'link', 'doctor', 'runtime', 'conformance', 'garden-code', 'init', 'git-driver', 'git-hook', 'brain-history', 'brain-deleted', 'orphans', 'diff', 'pr-brief', 'uninstall', 'bench', 'sessions', 'rescue']);
|
|
22
|
+
const DIRECT = new Set(['install', 'link', 'doctor', 'runtime', 'conformance', 'garden-code', 'init', 'git-driver', 'git-hook', 'brain-history', 'brain-deleted', 'orphans', 'diff', 'pr-brief', 'uninstall', 'bench', 'sessions', 'rescue', 'check', 'rules']);
|
|
23
23
|
|
|
24
24
|
const USAGE = [
|
|
25
25
|
`klypix-mcp ${PKG_VERSION} — shared project brain + MCP coordination server.`,
|
|
@@ -36,6 +36,11 @@ const USAGE = [
|
|
|
36
36
|
' bench [--quick] [--json] [--out F] reproducible benchmark: concurrent-write safety, latency, soak, crash',
|
|
37
37
|
' init seed a starter ./brain.klypix + print an MCP config',
|
|
38
38
|
' garden-code [brain] print the human approval code for brain_garden',
|
|
39
|
+
' check [--staged|--base B|--range A..B] [--strict] [--json]',
|
|
40
|
+
' run this project\'s rules (.klypix/rules.json) on a diff — milliseconds, no install/tests',
|
|
41
|
+
' check --install-hook|--remove-hook opt-in git pre-commit/pre-push/post-commit hooks for those rules',
|
|
42
|
+
' rules [list|code promote|retire <ids>|promote|retire <ids> --code C|allow <id> --reason R|false-alarm <id> --reason R]',
|
|
43
|
+
' the human side of rules: approval codes, one-hour overrides, false alarms',
|
|
39
44
|
' uninstall [--check|--yes|unlink] remove this install from the machine (--check inventories first; never deletes a .klypix)',
|
|
40
45
|
' git-driver [install|status] [repo] register the card-level .klypix merge driver for a repo (zero-command teams)',
|
|
41
46
|
' git-hook [install|remove|status] wire the agent-neutral commit-capture hook (any agent/branch/worktree → brain cards)',
|
|
@@ -78,6 +83,9 @@ if (verb === 'bench') {
|
|
|
78
83
|
console.log(process.argv.includes('--json') ? JSON.stringify(report, null, 2) : markdown);
|
|
79
84
|
const c = report.scenarios?.concurrentWriters;
|
|
80
85
|
process.exit(c?.verdict === 'no-loss' ? 0 : 1);
|
|
86
|
+
} else if (verb === 'check' || verb === 'rules') {
|
|
87
|
+
const { runRulesCli } = await import('../src/brain-rules.mjs');
|
|
88
|
+
process.exit(await runRulesCli(verb === 'rules' ? process.argv.slice(2) : process.argv.slice(3)));
|
|
81
89
|
} else if (verb === 'runtime') {
|
|
82
90
|
process.argv.splice(2, 1);
|
|
83
91
|
await import('./klypix-runtime.mjs');
|
package/bin/klypix-worker.mjs
CHANGED
|
@@ -228,7 +228,7 @@ if (process.argv[2] === 'init') {
|
|
|
228
228
|
{ title: 'Goal', cards: [{ text: '❓ What is this project for, and for whom?\nAgent: survey the repo on your first session and replace this with the real goal.' }] },
|
|
229
229
|
{ title: 'Architecture', cards: [{ text: '❓ Key components and how they fit.\nAgent: record the actual shape from the repo — only what a new session must know.' }] },
|
|
230
230
|
{ title: 'Decisions', cards: [{ text: 'Decisions land here automatically: agents emit `🧠 BRAIN [Area]: …` markers; a new decision that replaces an old one archives it (superseded). Resolve finished items with `✓`, correct in place with `~`. Drag any card into 📌 Focus to make it lead every session brief.' }] },
|
|
231
|
-
{ title: '🛠️ Skills', cards: [{ text: '🛠️ Reusable how-tos, gotchas & conventions land here — emit `🧠 BRAIN [Area] +: <skill>` (or just state a rule like "always X / never Y" and it auto-promotes). Skills
|
|
231
|
+
{ title: '🛠️ Skills', cards: [{ text: '🛠️ Reusable how-tos, gotchas & conventions land here — emit `🧠 BRAIN [Area] +: <skill>` (or just state a rule like "always X / never Y" and it auto-promotes). Skills are kept until corrected and shown first to sessions that touch the files they name, unlike one-time decisions. This is "how we work here", inherited by every future agent.' }] },
|
|
232
232
|
{ title: 'Pending / next', cards: [{ text: 'What is in flight and what comes next. Close finished items with the ✓ marker.' }] },
|
|
233
233
|
{ title: 'Open questions', cards: [{ text: 'Unresolved questions (the ❓ marker) live here — the session brief surfaces them first.' }] },
|
|
234
234
|
{ title: '📌 Focus', cards: [{ text: 'Drag any card into this area to make it lead every session brief — steer your agent by moving cards.' }] },
|
|
@@ -812,7 +812,7 @@ try {
|
|
|
812
812
|
|
|
813
813
|
server.registerTool('brain_note', {
|
|
814
814
|
title: 'Write a deliberate note to the project brain (decision / question / milestone / skill / resolve / update)',
|
|
815
|
-
description: 'Record something in the project brain ON DEMAND — the agent-neutral twin of the Claude-Code capture hook, so any client (Cursor / Cline / Desktop) can write the brain, not just read it. Unlike add_to_canvas (a flat append), this routes through the brain\'s capture engine, so a new decision SUPERSEDES a heavily-overlapping older one, ✓ RESOLVES/archives a matching card, closes: resolves the strategy/question a milestone fulfils, and ~ UPDATES a card in place — the full decision lifecycle, with dedup. Use marker "+" to record a 🛠️ SKILL — a reusable how-to/gotcha/convention ("always dedup zKeys before REORDER")
|
|
815
|
+
description: 'Record something in the project brain ON DEMAND — the agent-neutral twin of the Claude-Code capture hook, so any client (Cursor / Cline / Desktop) can write the brain, not just read it. Unlike add_to_canvas (a flat append), this routes through the brain\'s capture engine, so a new decision SUPERSEDES a heavily-overlapping older one, ✓ RESOLVES/archives a matching card, closes: resolves the strategy/question a milestone fulfils, and ~ UPDATES a card in place — the full decision lifecycle, with dedup. Use marker "+" to record a 🛠️ SKILL — a reusable how-to/gotcha/convention ("always dedup zKeys before REORDER") kept until corrected and shown first to sessions that touch the files it names, distinct from a one-time decision. When the mistake is mechanical, end the text with a `rule:` suffix to make the lesson RULE-READY: repo globs, then `never "<text>"`, `never /<regex>/`, `must "<text>"`, `listed-in <file>[,<file>]`, `keep-eol` or `costly` — e.g. `rule: web/tests/**/*.test.ts never "from \'@/"`. The globs must name tracked files; it lands as a visible "⚙ rule candidate" line that nothing checks until brain_rules adds it and a person approves it. Use it to remember a decision, ask an open question, mark a milestone, log a skill, resolve a finished item, or correct a card. Defaults to the project brain ("brain").',
|
|
816
816
|
inputSchema: {
|
|
817
817
|
text: z.string().describe('The note — one concise idea; the first line becomes the card title.'),
|
|
818
818
|
marker: z.enum(['', '?', '!', '+', '✓', '~']).optional().describe('(none)=decision · ?=open question · !=milestone · +=🛠️ skill (reusable how-to/gotcha; always resurfaces, never ages out) · ✓=resolve+archive the best-matching card · ~=update the matching card in place. Default: decision.'),
|
|
@@ -1540,6 +1540,38 @@ server.registerTool('brain_sync', {
|
|
|
1540
1540
|
};
|
|
1541
1541
|
});
|
|
1542
1542
|
|
|
1543
|
+
server.registerTool('brain_rules', {
|
|
1544
|
+
title: 'Project rules from the brain\'s lessons — enforced before CI, with no AI at check time',
|
|
1545
|
+
description: 'Turns lessons this brain recorded ("every new route must also be in PRIVATE_ROUTES", "a new *.test.ts must be listed in package.json", "this file is mixed CRLF/LF") into DETERMINISTIC diff checks, versioned in the repo as .klypix/rules.json, each citing the card it came from. Checked before the code reaches CI: brain_sync shows the rules for the files you declare; the edit hook (Claude Code; Codex gets the same) and an opt-in git pre-commit/pre-push hook report findings. Rules WARN by default; only a rule the human approved with --block stops an edit (Claude Code) or a commit, and a commit that skips a blocking rule (--no-verify) is recorded. Actions: "propose" routes each lesson to rule / instruction / note and drafts the checkable ones; "add" writes completed drafts as CANDIDATES (inert); "promote" and "retire" need the human\'s 8-character approval code (`npx klypix-mcp rules code promote|retire <ids>` — never shown to you, never guess it; a rule that blocks you is lifted only by the human); "check" runs the rules on the working tree, the staged change, or a range (include_candidates:true tests candidates before approval); "status" lists rules with fires / blocks / overrides / false alarms and retirement suggestions; "false_alarm" records that a finding was wrong (it does not lift the rule). Kinds: listed-in, forbid-pattern, preserve-eol, cloud-required. Checks are string/glob/regex work over the diff — milliseconds, offline; the project\'s own tests stay with its CI.',
|
|
1546
|
+
inputSchema: {
|
|
1547
|
+
action: z.enum(['propose', 'add', 'check', 'status', 'promote', 'retire', 'false_alarm']).describe('What to do. Default flow: propose → add → (human) promote; check any time; status for counts and suggestions.'),
|
|
1548
|
+
project: z.string().optional().describe('Absolute project root (the folder holding brain.klypix and .klypix/). Defaults to this session\'s project brain.'),
|
|
1549
|
+
query: z.string().optional().describe('propose: only lessons containing this text.'),
|
|
1550
|
+
limit: z.number().int().min(1).max(100).optional().describe('propose: at most this many lessons (default 30).'),
|
|
1551
|
+
rules: z.array(z.record(z.string(), z.any())).max(32).optional().describe('add: complete rules — {id, kind, severity, why, fix, source:{card}, files:[globs], …kind fields}. listed-in: when "added-files"|"added-lines", registry:[files], needle (template: {file} {basename} {name} {relpath} {1}), pattern for added-lines (capture group 1 = the value to find). forbid-pattern: pattern. preserve-eol: files only. cloud-required: files, severity "advise".'),
|
|
1552
|
+
ids: z.array(z.string()).max(32).optional().describe('promote / retire / false_alarm: rule ids.'),
|
|
1553
|
+
approve: z.string().optional().describe('promote / retire: the human\'s 8-character code. Never guess or fabricate it.'),
|
|
1554
|
+
reason: z.string().max(300).optional().describe('retire / false_alarm: why, in one line.'),
|
|
1555
|
+
mode: z.enum(['worktree', 'staged', 'range']).optional().describe('check: the working tree vs HEAD (default), the staged change, or a commit range (with base).'),
|
|
1556
|
+
base: z.string().optional().describe('check: base ref for a range (merge-base with head is used).'),
|
|
1557
|
+
head: z.string().optional().describe('check: head ref for a range (default HEAD).'),
|
|
1558
|
+
files: z.array(z.string()).max(50).optional().describe('check: just list the rules these files fall under (no diff).'),
|
|
1559
|
+
include_candidates: z.boolean().optional().describe('check: also run candidate rules — to see what a rule would catch before the human approves it.'),
|
|
1560
|
+
block: z.boolean().optional().describe('promote: true only when the human printed the code with --block, making these rules stop an edit or a commit instead of warning. Rules warn by default.'),
|
|
1561
|
+
},
|
|
1562
|
+
}, async ({ action, project, query, limit, rules, ids, approve, reason, mode, base, head, files, include_candidates, block }, extra) => {
|
|
1563
|
+
try {
|
|
1564
|
+
const { brainRulesTool } = await import('../src/brain-rules.mjs');
|
|
1565
|
+
const brainPath = project ? path.join(path.resolve(project), 'brain.klypix') : (mcpPresence.brainPath || path.join(mcpPresence.vault, 'brain.klypix'));
|
|
1566
|
+
return toContent(await brainRulesTool({
|
|
1567
|
+
projectRoot: path.dirname(brainPath), brainPath, action, query, limit, rules, ids, approve, reason, mode, base, head, files,
|
|
1568
|
+
includeCandidates: include_candidates === true, block: block === true, pluginMode: PLUGIN_MODE, proposedBy: extra?.klypixClientName || '',
|
|
1569
|
+
}));
|
|
1570
|
+
} catch (error) {
|
|
1571
|
+
return toContent({ blocks: [{ kind: 'text', text: `brain_rules failed: ${error?.message || error}` }], isError: true });
|
|
1572
|
+
}
|
|
1573
|
+
});
|
|
1574
|
+
|
|
1543
1575
|
server.registerTool('brain_doctor', {
|
|
1544
1576
|
title: 'Brain doctor — is this brain current, wired, and in sync?',
|
|
1545
1577
|
description: 'Read-only self-check of the installed klypix brain, as ONE verdict: VERSION (deployed brain-core + optional npm currency), CLAUDE (existing 5-hook capture readiness), CODEX (automatic MCP presence plus optional enhanced-hook status), TOOLS (discoverable MCP verbs), SESSIONS (all active presence-adapter sessions across hosts, never recent-chat history), and HARNESS (projection drift). Use to answer "is my brain current, correctly installed, in sync, and who is actually live?" without file-spelunking. Never writes: the only side effects are read-only subprocess queries (git rev-parse / tag --list / log / merge-base with fixed argument arrays, and `npm view` only when check_npm is true) — it creates, edits, and deletes nothing. SCOPE: only CLAUDE and CODEX get behavioural verdicts. HARNESS classifies the projected config/rules FILES on disk — a project can read fully ok while no other host has ever actually loaded them, so do not report a clean HARNESS as "Cursor/Cline/Windsurf/Copilot is working". The MCP-callable twin of `npx klypix-mcp doctor`. Besides the text, the result carries structuredContent {verdict, layers, version, autoUpdate, supervisors, readinessWarnings, actions}: the same verdict as data, including when the next automatic update check runs and what it will do.',
|
|
@@ -1808,6 +1840,43 @@ server.server.oninitialized = () => {
|
|
|
1808
1840
|
};
|
|
1809
1841
|
server.server.onclose = stopRuntimePresence;
|
|
1810
1842
|
process.once('exit', stopRuntimePresence);
|
|
1843
|
+
// Published tool schemas are a compatibility contract: a running supervisor
|
|
1844
|
+
// compares them byte for byte before it hot-swaps a worker, and the frozen
|
|
1845
|
+
// snapshots in test/fixtures pin them. zod 4.6 writes a union of plain types as
|
|
1846
|
+
// `type: ["number","string"]` where every snapshot and every supervisor already
|
|
1847
|
+
// running knows `anyOf: [{type:"number"},{type:"string"}]` — the same meaning in
|
|
1848
|
+
// other bytes. Rewrite each type list back into anyOf, FIRST in its object as
|
|
1849
|
+
// zod 4.4 wrote it (before description), so a zod bump never drifts a frozen
|
|
1850
|
+
// schema.
|
|
1851
|
+
const isTypeList = (value) => Array.isArray(value) && value.length > 1 && value.every((t) => typeof t === 'string');
|
|
1852
|
+
function frozenSchemaShape(node) {
|
|
1853
|
+
if (Array.isArray(node)) return node.map(frozenSchemaShape);
|
|
1854
|
+
if (!node || typeof node !== 'object') return node;
|
|
1855
|
+
const out = {};
|
|
1856
|
+
if (isTypeList(node.type)) out.anyOf = node.type.map((type) => ({ type }));
|
|
1857
|
+
for (const [key, value] of Object.entries(node)) {
|
|
1858
|
+
if (key === 'type' && isTypeList(value)) continue;
|
|
1859
|
+
out[key] = frozenSchemaShape(value);
|
|
1860
|
+
}
|
|
1861
|
+
return out;
|
|
1862
|
+
}
|
|
1863
|
+
const sdkListTools = server.server._requestHandlers?.get?.('tools/list');
|
|
1864
|
+
if (typeof sdkListTools === 'function') {
|
|
1865
|
+
server.server._requestHandlers.set('tools/list', async (request, extra) => {
|
|
1866
|
+
const result = await sdkListTools(request, extra);
|
|
1867
|
+
if (!result || !Array.isArray(result.tools)) return result;
|
|
1868
|
+
return {
|
|
1869
|
+
...result,
|
|
1870
|
+
tools: result.tools.map((tool) => ({
|
|
1871
|
+
...tool,
|
|
1872
|
+
...(tool.inputSchema ? { inputSchema: frozenSchemaShape(tool.inputSchema) } : {}),
|
|
1873
|
+
...(tool.outputSchema ? { outputSchema: frozenSchemaShape(tool.outputSchema) } : {}),
|
|
1874
|
+
})),
|
|
1875
|
+
};
|
|
1876
|
+
});
|
|
1877
|
+
} else {
|
|
1878
|
+
log('tools/list schema shaping unavailable in this SDK; published schemas follow zod as-is');
|
|
1879
|
+
}
|
|
1811
1880
|
await server.connect(transport);
|
|
1812
1881
|
// Most sessions use brain_sync/presence and should not pay for a private model
|
|
1813
1882
|
// they never query. Legacy mode restores the old eager lifecycle immediately.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "klypix-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.107.1",
|
|
4
4
|
"mcpName": "io.github.dahshanlabs/klypix-mcp",
|
|
5
5
|
"description": "Shared project memory for Claude Code, Codex and Cursor: decisions, corrections, overlap warnings.",
|
|
6
6
|
"type": "module",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"bench": "node bin/klypix-mcp.mjs bench",
|
|
98
98
|
"test:bench": "node test/bench.mjs",
|
|
99
99
|
"pretest": "node test/publish-workflow.mjs",
|
|
100
|
-
"test": "node test/publish-verdict.mjs && node test/npx-owned-names.mjs && node test/project-graph.mjs && node test/project-map-cli.mjs && node test/mcp-auto-update.mjs && node test/mcp-supervisor.mjs && node test/runtime-inspector.mjs && node test/codex-hooks.mjs && node test/request-identity.mjs && node test/session-identity-core.mjs && node test/agent-presence.mjs && node test/message-delivery-v3.mjs && node test/claude-message-delivery-v3.mjs && node test/session-mailbox.mjs && node test/session-reopen.mjs && node test/session-handoff.mjs && node test/lock-notes.mjs && node test/whose-classify.mjs && node test/whose-ledger.mjs && node test/whose-rescue.mjs && node test/whose-hook.mjs && node test/live-projection.mjs && node test/lane-write-retry.mjs && node test/result-reconcile.mjs && node test/evidence-publication-gate.mjs && node test/release-evidence-cli.mjs && node test/intent-guard.mjs && node test/git-capture-install.mjs && node test/brain-history.mjs && node test/brain-graveyard.mjs && node test/archived-visibility.mjs && node test/finding-routing.mjs && node test/finding-routing-hook.mjs && node test/presence-relay.mjs && node test/network-bridge.mjs && node test/install-version.mjs && node test/install-rename-backoff.mjs && node test/project-binding-rebind.mjs && node test/context-gateway.mjs && node test/repo-state.mjs && node test/released-tag-guard.mjs && node test/conformance.mjs && node test/brain-doctor.mjs && node test/version-currency.mjs && node test/ship-capture.mjs && node test/capture-gap.mjs && node test/lane-message.mjs && node test/brain-quality.mjs && node test/brain-connect-orphans.mjs && node test/orphan-gardener.mjs && node test/brief-and-recall.mjs && node test/guard-cards.mjs && node test/layout-cluster.mjs && node test/brain-ask.mjs && node test/brain-ask-words.mjs && node test/retrieval-fusion.mjs && node test/eval-retrieval.mjs && node test/field-report-2026-07-04.mjs && node test/autoprop.mjs && node test/overlay-recency-2026-07-12.mjs && node test/brain-challenge.mjs && node test/brain-lens.mjs && node test/brain-kind.mjs && node test/rule-drafts.mjs && node test/claim-engine.mjs && node test/partial-notes.mjs && node test/lifecycle-prefix.mjs && node test/close-link-safety.mjs && node test/resolve-ledger.mjs && node test/plan-fulfillment.mjs && node test/arrange-receipts.mjs && node test/skill-staleness.mjs && node test/canvas-view.mjs && node test/status-completeness.mjs && node test/semantic-security.mjs && node test/semantic-gate.mjs && node test/memory-runtime.mjs && node test/semantic-cache.mjs && node test/semantic-preparation.mjs && node test/semantic-hash-parity.mjs && node test/enrichment.mjs && node test/provenance.mjs && node test/confirm-trail.mjs && node test/hook-fallback.mjs && node test/eval-hook-lane.mjs && node test/hook-unified-lane.mjs && node test/decay-status.mjs && node test/decay-hook.mjs && node test/marker-suffix-grammar.mjs && node test/marker-after-colon.mjs && node test/evidence-anchors.mjs && node test/brain-evidence.mjs && node test/presence-visibility.mjs && node test/undeclared-active.mjs && node test/presence-liveness.mjs && node test/observed-scope.mjs && node test/overlap-tiers.mjs && node test/coordination-bench.mjs && node test/release-lease.mjs && node test/release-reconcile.mjs && node test/release-ancestry.mjs && node test/release-claim-join.mjs && node test/release-claims.mjs && node test/release-handshake.mjs && node test/completion-guard.mjs && node test/results-not-manifests.mjs && node test/merge-brains.mjs && node test/merge-readings.mjs && node test/revival-map.mjs && node test/merge-scale.mjs && node test/concurrent-writes.mjs && node test/lock-interop.mjs && node test/capture-write-failure.mjs && node test/a2a-smoke.mjs && node test/one-command-setup.mjs && node test/cli-args.mjs && node test/format-guard.mjs && node test/canvas-groups.mjs && node test/git-tools.mjs && node test/link-compat.mjs && node test/uninstall.mjs && node test/current-guidance.mjs && node test/current-first.mjs && node test/status-shape.mjs && node test/status-hook.mjs && node test/read-canvas-saved-readings.mjs && node test/document-readings.mjs && node test/open-lease.mjs && node test/agent-card-style.mjs && node test/tool-schema-freeze.mjs && node test/app-lease-vectors.mjs && node test/app-tools-stdio.mjs && node test/card-contents-files.mjs && node test/codex-app-table.mjs && node test/plugin-mode.mjs && node test/app-bridge-vectors.mjs && node test/app-bridge-client.mjs && node test/app-tools-static.mjs && node test/app-tools-stdio-live.mjs",
|
|
100
|
+
"test": "node test/publish-verdict.mjs && node test/npx-owned-names.mjs && node test/project-graph.mjs && node test/project-map-cli.mjs && node test/mcp-auto-update.mjs && node test/mcp-supervisor.mjs && node test/runtime-inspector.mjs && node test/codex-hooks.mjs && node test/request-identity.mjs && node test/session-identity-core.mjs && node test/agent-presence.mjs && node test/message-delivery-v3.mjs && node test/claude-message-delivery-v3.mjs && node test/session-mailbox.mjs && node test/session-reopen.mjs && node test/session-handoff.mjs && node test/lock-notes.mjs && node test/whose-classify.mjs && node test/whose-ledger.mjs && node test/whose-rescue.mjs && node test/whose-hook.mjs && node test/live-projection.mjs && node test/lane-write-retry.mjs && node test/result-reconcile.mjs && node test/evidence-publication-gate.mjs && node test/release-evidence-cli.mjs && node test/intent-guard.mjs && node test/git-capture-install.mjs && node test/brain-history.mjs && node test/brain-graveyard.mjs && node test/archived-visibility.mjs && node test/finding-routing.mjs && node test/finding-routing-hook.mjs && node test/presence-relay.mjs && node test/network-bridge.mjs && node test/brain-rules.mjs && node test/brain-recall.mjs && node test/install-version.mjs && node test/install-rename-backoff.mjs && node test/project-binding-rebind.mjs && node test/context-gateway.mjs && node test/repo-state.mjs && node test/released-tag-guard.mjs && node test/conformance.mjs && node test/brain-doctor.mjs && node test/version-currency.mjs && node test/ship-capture.mjs && node test/capture-gap.mjs && node test/lane-message.mjs && node test/brain-quality.mjs && node test/brain-connect-orphans.mjs && node test/orphan-gardener.mjs && node test/brief-and-recall.mjs && node test/guard-cards.mjs && node test/layout-cluster.mjs && node test/brain-ask.mjs && node test/brain-ask-words.mjs && node test/retrieval-fusion.mjs && node test/eval-retrieval.mjs && node test/field-report-2026-07-04.mjs && node test/autoprop.mjs && node test/overlay-recency-2026-07-12.mjs && node test/brain-challenge.mjs && node test/brain-lens.mjs && node test/brain-kind.mjs && node test/rule-drafts.mjs && node test/claim-engine.mjs && node test/partial-notes.mjs && node test/lifecycle-prefix.mjs && node test/close-link-safety.mjs && node test/resolve-ledger.mjs && node test/plan-fulfillment.mjs && node test/arrange-receipts.mjs && node test/skill-staleness.mjs && node test/canvas-view.mjs && node test/status-completeness.mjs && node test/semantic-security.mjs && node test/semantic-gate.mjs && node test/memory-runtime.mjs && node test/semantic-cache.mjs && node test/semantic-preparation.mjs && node test/semantic-hash-parity.mjs && node test/enrichment.mjs && node test/provenance.mjs && node test/confirm-trail.mjs && node test/hook-fallback.mjs && node test/eval-hook-lane.mjs && node test/hook-unified-lane.mjs && node test/decay-status.mjs && node test/decay-hook.mjs && node test/marker-suffix-grammar.mjs && node test/marker-after-colon.mjs && node test/evidence-anchors.mjs && node test/brain-evidence.mjs && node test/presence-visibility.mjs && node test/undeclared-active.mjs && node test/presence-liveness.mjs && node test/observed-scope.mjs && node test/overlap-tiers.mjs && node test/coordination-bench.mjs && node test/release-lease.mjs && node test/release-reconcile.mjs && node test/release-ancestry.mjs && node test/release-claim-join.mjs && node test/release-claims.mjs && node test/release-handshake.mjs && node test/completion-guard.mjs && node test/results-not-manifests.mjs && node test/merge-brains.mjs && node test/merge-readings.mjs && node test/revival-map.mjs && node test/merge-scale.mjs && node test/concurrent-writes.mjs && node test/lock-interop.mjs && node test/capture-write-failure.mjs && node test/a2a-smoke.mjs && node test/one-command-setup.mjs && node test/cli-args.mjs && node test/format-guard.mjs && node test/canvas-groups.mjs && node test/git-tools.mjs && node test/link-compat.mjs && node test/uninstall.mjs && node test/current-guidance.mjs && node test/current-first.mjs && node test/status-shape.mjs && node test/status-hook.mjs && node test/read-canvas-saved-readings.mjs && node test/document-readings.mjs && node test/open-lease.mjs && node test/agent-card-style.mjs && node test/tool-schema-freeze.mjs && node test/app-lease-vectors.mjs && node test/app-tools-stdio.mjs && node test/card-contents-files.mjs && node test/codex-app-table.mjs && node test/plugin-mode.mjs && node test/app-bridge-vectors.mjs && node test/app-bridge-client.mjs && node test/app-tools-static.mjs && node test/app-tools-stdio-live.mjs",
|
|
101
101
|
"test:memory": "node test/memory-runtime.mjs",
|
|
102
102
|
"test:memory:soak": "node --expose-gc test/memory-soak.mjs",
|
|
103
103
|
"runtime": "node bin/klypix-runtime.mjs",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
"fractional-indexing": "^3.2.0",
|
|
112
112
|
"jpeg-js": "^0.4.4",
|
|
113
113
|
"jszip": "^3.10.1",
|
|
114
|
-
"zod": "^4.
|
|
114
|
+
"zod": "^4.6.7"
|
|
115
115
|
},
|
|
116
116
|
"devDependencies": {
|
|
117
117
|
"@huggingface/transformers": "^4.2.0"
|