klypix-mcp 1.64.0 → 1.66.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 +49 -20
- package/bin/klypix-brain-deleted.mjs +6 -1
- package/bin/klypix-conformance.mjs +67 -31
- package/bin/klypix-git-tools.mjs +4 -4
- package/bin/klypix-install.mjs +2 -2
- package/bin/klypix-worker.mjs +31 -6
- package/package.json +3 -2
- package/src/agent-presence.mjs +377 -79
- package/src/brain-doctor.mjs +44 -9
- package/src/brain-graveyard.mjs +52 -3
- package/src/brain-note.mjs +3 -1
- package/src/codex-brain-hook.mjs +38 -8
- package/src/finding-routing.mjs +61 -22
- package/src/global-brain-hook.mjs +275 -121
- package/src/klypix-core.mjs +72 -84
- package/src/klypix-format.mjs +215 -8
- package/src/mcp-presence.mjs +355 -38
- package/src/mcp-supervisor.mjs +127 -15
- package/src/merge-brains.mjs +39 -6
- package/src/presence-relay.mjs +184 -32
- package/src/result-reconcile.mjs +618 -0
- package/src/semantic-memory.mjs +48 -0
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ npx klypix-mcp conformance
|
|
|
79
79
|
|
|
80
80
|
It runs in a temporary fixture and touches nothing else. It checks tool discovery, task memory,
|
|
81
81
|
truthful peer reporting, overlap surfacing, proactive logging, and in-band delivery of a peer note.
|
|
82
|
-
It verifies
|
|
82
|
+
It verifies 15 required coordination behaviours — not the 21 tools, and not the retrieval engine.
|
|
83
83
|
|
|
84
84
|
---
|
|
85
85
|
|
|
@@ -150,7 +150,9 @@ not a filing convention.
|
|
|
150
150
|
|
|
151
151
|
- **Decisions have a lifecycle.** A new decision that contradicts an old one supersedes it. The
|
|
152
152
|
stale card is archived with an arrow and a date, never deleted, and later answers surface the
|
|
153
|
-
correction rather than the corpse.
|
|
153
|
+
correction rather than the corpse. If a later decision returns to an earlier superseded stance,
|
|
154
|
+
high-confidence lineage leaves a dated `re-adopts` stamp on the new card plus an earlier→current
|
|
155
|
+
edge; the original A→B→C history remains intact.
|
|
154
156
|
- **Corrections are explicit, not guessed.** Supersession fires on an UPPERCASE correction cue or
|
|
155
157
|
an explicit edge. `brain_reconcile` only *proposes* stale-vs-correction pairs for a human to
|
|
156
158
|
confirm.
|
|
@@ -274,7 +276,9 @@ the full brief written to disk for when broad history or status work needs it.
|
|
|
274
276
|
|
|
275
277
|
Every other host gets a bounded ~2.8KB task capsule from one `brain_sync` call, plus a compact
|
|
276
278
|
always-loaded `AGENTS.md` block that tells the agent to make that call at task start, when scope
|
|
277
|
-
changes, and on completion. The gateway capsule is lexical-fast by design.
|
|
279
|
+
changes, and on completion. The gateway capsule is lexical-fast by design. A newly captured open
|
|
280
|
+
gap can claim a labeled `RECENT OPEN` slot only after clearing the normal lexical-relevance floor,
|
|
281
|
+
so fresh relevant findings are not crowded out by older area vocabulary.
|
|
278
282
|
|
|
279
283
|
Briefs are **not** injected automatically on Cursor, Cline, Copilot, Gemini CLI or Antigravity —
|
|
280
284
|
there are no lifecycle hooks on those hosts.
|
|
@@ -285,9 +289,12 @@ On Claude Code, decisions are captured automatically at turn end from inline `
|
|
|
285
289
|
markers in the transcript, deduped, under a capture lock.
|
|
286
290
|
|
|
287
291
|
On every other host, capture is explicit: `brain_note` runs the same capture engine as the hooks —
|
|
288
|
-
dedup, supersession, `✓` resolve, `~` update in place, `+` skill,
|
|
289
|
-
|
|
290
|
-
|
|
292
|
+
dedup, supersession, round-trip re-adoption receipts, `✓` resolve, `~` update in place, `+` skill,
|
|
293
|
+
`closes:` — and stamps which agent wrote the card. A `✓` question preference ranks only candidates
|
|
294
|
+
that already clear raw lexical overlap and two subject-identity anchors; generic lifecycle wording
|
|
295
|
+
cannot turn weak overlap into a closure.
|
|
296
|
+
(If you install the git commit hook from the KLYPIX app, commit messages also capture automatically,
|
|
297
|
+
for any agent. That hook has no CLI installer.)
|
|
291
298
|
|
|
292
299
|
`brain_challenge` is the other direction: propose a decision and the brain answers with receipts —
|
|
293
300
|
prior decisions that deterministically contradict it, standing rules that dispute it, and
|
|
@@ -323,14 +330,30 @@ have to have declared their files for the overlap to be visible at all.
|
|
|
323
330
|
|
|
324
331
|
## Handoffs and messages
|
|
325
332
|
|
|
326
|
-
`brain_message` leaves one-time coordination notes for other sessions.
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
333
|
+
`brain_message` leaves one-time coordination notes for other sessions. A supported KLYPIX action
|
|
334
|
+
offers the note in model-visible context; the next independent supported action replays it and
|
|
335
|
+
records an acknowledgement. That acknowledgement proves only that a later action followed the
|
|
336
|
+
offer — never that a person read it or that an agent acted on it. Pending and offered notes survive
|
|
337
|
+
reconnects. Expiry or bounded-capacity eviction records a failed per-recipient receipt instead of
|
|
338
|
+
silently looking delivered. The core lane is machine-local, notes expire after 24 hours, and they
|
|
339
|
+
are never written into the brain.
|
|
330
340
|
|
|
331
341
|
Durable handoffs go in the brain itself — decisions, findings, open questions and skills captured
|
|
332
342
|
as cards, each stamped with the agent that wrote it.
|
|
333
343
|
|
|
344
|
+
## Evidence-gated completion
|
|
345
|
+
|
|
346
|
+
When a task publishes a quantified or otherwise machine-checkable claim, it can attach one or more
|
|
347
|
+
versioned result manifests to `brain_sync { phase: "complete" }`. Each manifest binds the claim to a
|
|
348
|
+
report hash, producer/run provenance, the exact input and configuration fingerprints, and named
|
|
349
|
+
metrics with counts and tolerances. Matching peer evidence is recorded as corroboration; conflicting
|
|
350
|
+
or incomparable evidence returns `needs-reconciliation` and keeps the task scope active.
|
|
351
|
+
|
|
352
|
+
The gate fails closed. Once a task submits result evidence, it cannot bypass an invalid or
|
|
353
|
+
conflicting result by retrying completion without the manifest, and that obligation survives worker
|
|
354
|
+
restart, hibernation, and transparent hot-swap. A fresh `phase: "start"` is the explicit boundary for
|
|
355
|
+
a new task. The strict schema and reusable validator are exported as `klypix-mcp/result-reconcile`.
|
|
356
|
+
|
|
334
357
|
## Human control in Klypix
|
|
335
358
|
|
|
336
359
|
> **Not a second brain. A shared one.**
|
|
@@ -471,14 +494,14 @@ The MCP verbs below are what agents call. These are what **you** call:
|
|
|
471
494
|
|---|---|
|
|
472
495
|
| `brain_ask` | Whole-brain question answering — correction-aware, `as_of` time travel |
|
|
473
496
|
| `brain_challenge` | The brain argues back: contradictions with receipts, tried-and-reversed chains, standing rules, other-agent provenance flags |
|
|
474
|
-
| `brain_note` | Capture with the full lifecycle — supersede / ✓ resolve / ~ update / 🛠 skill / `closes:` |
|
|
497
|
+
| `brain_note` | Capture with the full lifecycle — supersede / re-adopt / ✓ resolve / ~ update / 🛠 skill / `closes:` |
|
|
475
498
|
| `brain_reconcile` | Proposes stale-vs-correction pairs and unrecorded migrations for a human to confirm |
|
|
476
499
|
| `brain_insights` | Hubs, orphaned decisions, stale questions, area sizes |
|
|
477
500
|
| `brain_lens` | Machine-readable freshness, provenance, activity, timeline, orrery and unresolved views |
|
|
478
501
|
| `brain_garden` | Maintenance pass — proposes first, and cannot apply without an approval code the human generates |
|
|
479
502
|
| `brain_doctor` | Self-diagnosis: version, core/enhanced host adapters, active sessions, tool count, projection drift |
|
|
480
|
-
| `brain_message` | Session-to-session coordination notes (24h TTL, never written into the brain) |
|
|
481
|
-
| `brain_sync` | Context Gateway: task capsule, active-task peers, exact-file overlap, one-time alerts, timing |
|
|
503
|
+
| `brain_message` | Session-to-session coordination notes with per-recipient offer / later-action acknowledgement / failure receipts (24h TTL, never written into the brain) |
|
|
504
|
+
| `brain_sync` | Context Gateway: task capsule, active-task peers, exact-file overlap, one-time alerts, timing, and optional result-manifest reconciliation |
|
|
482
505
|
| `brain_connect` | Find and draw related-but-unlinked cards |
|
|
483
506
|
| `project_map_context` | Read-only, bounded code-graph evidence beside correction-aware brain context, with exact-path review proposals; external artifacts (e.g. Graphify) are supported but never installed or run locally |
|
|
484
507
|
| `project_map_scan` | KLYPIX's own zero-install scanner: gitignore-aware file inventory + file-level import edges (relative, tsconfig-alias, and monorepo-workspace imports resolved) written to `klypix-map/graph.json` — which then serves `project_map_context` automatically |
|
|
@@ -491,7 +514,7 @@ The MCP verbs below are what agents call. These are what **you** call:
|
|
|
491
514
|
| `add_to_canvas` | Append cards/connections (positions preserved) |
|
|
492
515
|
| `list_canvases` | List every `.klypix` in the vault |
|
|
493
516
|
|
|
494
|
-
Exactly
|
|
517
|
+
Exactly 21, machine-verifiable with `npx klypix-mcp doctor`.
|
|
495
518
|
|
|
496
519
|
> **`canvas_view`:** no MCP Apps host has been observed rendering the UI resource yet — there is no
|
|
497
520
|
> screenshot and no host-level test. Hosts without the extension get clean text, which is the path
|
|
@@ -570,7 +593,8 @@ replaceable worker runs the brain core. A staged update is hash-verified, initia
|
|
|
570
593
|
checked for backward-compatible tool schemas, and handed the current `brain_sync` task scope before
|
|
571
594
|
the supervisor switches between requests. Added tools use the standard
|
|
572
595
|
`notifications/tools/list_changed` signal. A failed or breaking candidate is rejected while the old
|
|
573
|
-
worker keeps serving.
|
|
596
|
+
worker keeps serving. A blocked result claim is kept in a durable per-project/session marker, so a
|
|
597
|
+
worker replacement cannot turn a failed evidence check into a result-less completion.
|
|
574
598
|
|
|
575
599
|
Compatible engine updates therefore activate behind the same live connection — no reconnect, no
|
|
576
600
|
host restart. Three cases still require a deliberate reconnect or manual install: the one-time
|
|
@@ -601,7 +625,11 @@ keep lazy first-use indexing instead.
|
|
|
601
625
|
- **Coordination state is local files.** The brain is a file in your repo; the presence lane is a
|
|
602
626
|
file under your home directory. Nothing is uploaded — with one explicit, default-OFF exception:
|
|
603
627
|
the cross-PC presence relay, which (only after per-brain consent in the KLYPIX desktop app)
|
|
604
|
-
shares
|
|
628
|
+
shares whitelisted presence fields and the text of one-time coordination notes over that
|
|
629
|
+
brain's cloud channel. KLYPIX does not automatically attach file/card contents, diffs, or screen
|
|
630
|
+
data, but a note relays whatever its sender typed (and automatic overlap alerts name the declared
|
|
631
|
+
file paths involved). The scope is versioned: an older metadata-only grant does not authorize note
|
|
632
|
+
text and must be granted again. No current consent, no frames.
|
|
605
633
|
- **`install` writes to your home directory:** `~/.claude/project-brain` (engine + runtime),
|
|
606
634
|
`~/.claude/settings.json` (four hooks — written even if Claude Code is not installed),
|
|
607
635
|
`~/.codex/AGENTS.md` (guidance block), and with `--codex-hooks`, `~/.codex/hooks.json`. It also
|
|
@@ -617,9 +645,10 @@ Read this section before you build on any of it.
|
|
|
617
645
|
- **Coordination is machine-local and OS-user-local.** The presence lane is a file in your home
|
|
618
646
|
directory. Two developers on two machines do not see each other's sessions, peers, overlaps or
|
|
619
647
|
messages. This package ships the cross-machine presence *core* (`./presence-relay` — versioned
|
|
620
|
-
metadata-
|
|
621
|
-
|
|
622
|
-
|
|
648
|
+
whitelisted presence metadata plus coordination-note text, a symmetric default-off consent gate,
|
|
649
|
+
loop prevention, stable message IDs and per-recipient-machine acknowledgement primitives), but no
|
|
650
|
+
transport: carrying frames between machines is the desktop app's job. With `klypix-mcp` alone,
|
|
651
|
+
coordination is machine-local.
|
|
623
652
|
- **Overlap matching is exact-path, and both sides must declare.** A session that never declares
|
|
624
653
|
its expected files is invisible to overlap detection, and `src/auth/token.ts` does not match a
|
|
625
654
|
rename or a parent directory.
|
|
@@ -685,7 +714,7 @@ Your `brain.klypix` is yours — it is a plain ZIP and stays readable with or wi
|
|
|
685
714
|
Issues and pull requests: [github.com/dahshanlabs/klypix-mcp](https://github.com/dahshanlabs/klypix-mcp).
|
|
686
715
|
Questions or feedback: [hello@klypix.com](mailto:hello@klypix.com).
|
|
687
716
|
|
|
688
|
-
The repository carries
|
|
717
|
+
The repository carries 59 test files, 54 of them in the `npm test` chain, covering the presence
|
|
689
718
|
lane and its cross-machine relay, the Context Gateway, supervisor hot-swap, auto-update, retrieval
|
|
690
719
|
quality, decay, challenge, lenses, the format guard, the git tools (including a real `git merge`
|
|
691
720
|
through the merge driver), uninstall, and conformance. Run them with `npm test` from a clone — they
|
|
@@ -37,8 +37,13 @@ if (action === 'list') {
|
|
|
37
37
|
console.log(`${entries.length} deleted card(s) in ${path.basename(brainPath)} — newest first\n`);
|
|
38
38
|
for (const e of entries) {
|
|
39
39
|
const full = ids.includes(e.id) ? await readGraveyardCard(buf, e.id) : null;
|
|
40
|
-
|
|
40
|
+
const label = e.summary?.label || e.preview || `(${e.summary?.type || 'unknown'} item)`;
|
|
41
|
+
const audit = e.deletion?.confidence === 'legacy'
|
|
42
|
+
? 'legacy source unverified'
|
|
43
|
+
: `${e.deletion?.initiator || 'unknown'} via ${e.deletion?.cause || 'unclassified'}`;
|
|
44
|
+
console.log(` ${e.id} ${ago(e.deletedAt).padEnd(9)} ${e.area ? `[${e.area}] ` : ''}${label} <${audit}>`);
|
|
41
45
|
if (full?.content) console.log(`\n${String(full.content).split('\n').map((l) => ` ${l}`).join('\n')}\n`);
|
|
46
|
+
else if (full) console.log(`\n ${JSON.stringify(e.summary || { type: full.type || 'unknown' })}\n`);
|
|
42
47
|
}
|
|
43
48
|
console.log(`\nFull text: npx klypix-mcp brain-deleted list <id> --brain "${brainPath}"`);
|
|
44
49
|
console.log(`Restore: npx klypix-mcp brain-deleted restore <id>`);
|
|
@@ -106,22 +106,32 @@ try {
|
|
|
106
106
|
const tools = await a.client.listTools();
|
|
107
107
|
checks.brainSyncDiscoverable = tools.tools?.some((tool) => tool.name === 'brain_sync') === true;
|
|
108
108
|
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
109
|
+
const syncStart = async (client, intent, expectedTasks) => {
|
|
110
|
+
let response;
|
|
111
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
112
|
+
response = await client.callTool({
|
|
113
|
+
name: 'brain_sync',
|
|
114
|
+
arguments: {
|
|
115
|
+
phase: 'start',
|
|
116
|
+
intent,
|
|
117
|
+
files: ['src/conformance-overlap.ts'],
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
const structured = response.structuredContent || {};
|
|
121
|
+
if (Number.isFinite(structured.timingMs?.total)
|
|
122
|
+
&& structured.counts?.activeTasks === expectedTasks) return { response, attempt };
|
|
123
|
+
await wait(75);
|
|
124
|
+
}
|
|
125
|
+
return { response, attempt: 3 };
|
|
126
|
+
};
|
|
127
|
+
// The lane is deliberately lock-protected and the two real clients heartbeat
|
|
128
|
+
// concurrently. A bounded retry proves convergence without turning one
|
|
129
|
+
// transient lock collision into a false product failure.
|
|
130
|
+
const aStarted = await syncStart(a.client, 'Validate automatic Codex Context Gateway coordination', 1);
|
|
131
|
+
const bStarted = await syncStart(b.client, 'Validate proactive overlap delivery from a second session', 2);
|
|
132
|
+
const aStart = aStarted.response;
|
|
133
|
+
const bStart = bStarted.response;
|
|
134
|
+
metrics.startAttempts = { first: aStarted.attempt, second: bStarted.attempt };
|
|
125
135
|
const aStructured = aStart.structuredContent || {};
|
|
126
136
|
const bStructured = bStart.structuredContent || {};
|
|
127
137
|
checks.taskMemory = Array.isArray(aStructured.context?.hits) && aStructured.context.hits.length > 0;
|
|
@@ -144,16 +154,25 @@ try {
|
|
|
144
154
|
metrics.firstClientLogCount = a.logs.length;
|
|
145
155
|
if (!checks.proactiveLogging && a.logs.length) metrics.firstClientLogs = a.logs.slice(-4);
|
|
146
156
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
+
let checkpointStructured = {};
|
|
158
|
+
let inBandAttempts = 0;
|
|
159
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
160
|
+
inBandAttempts = attempt;
|
|
161
|
+
const aCheckpoint = await a.client.callTool({
|
|
162
|
+
name: 'brain_sync',
|
|
163
|
+
arguments: {
|
|
164
|
+
phase: 'checkpoint',
|
|
165
|
+
intent: 'Validate automatic Codex Context Gateway coordination',
|
|
166
|
+
files: ['src/conformance-overlap.ts'],
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
checkpointStructured = aCheckpoint.structuredContent || {};
|
|
170
|
+
if (checkpointStructured.messages?.some((message) =>
|
|
171
|
+
String(message.text).includes('Automatic KLYPIX overlap alert'))) break;
|
|
172
|
+
await wait(75);
|
|
173
|
+
}
|
|
174
|
+
metrics.inBandAttempts = inBandAttempts;
|
|
175
|
+
checks.durableInBandOffer = checkpointStructured.messages?.some((message) =>
|
|
157
176
|
String(message.text).includes('Automatic KLYPIX overlap alert')) === true;
|
|
158
177
|
|
|
159
178
|
await Promise.all([
|
|
@@ -188,10 +207,26 @@ try {
|
|
|
188
207
|
&& /no live session declared docs\/unowned\.md/.test(nobody.reason);
|
|
189
208
|
|
|
190
209
|
const receipt = summarizeReceipts({
|
|
191
|
-
messages: [{
|
|
210
|
+
messages: [{
|
|
211
|
+
id: 'finding-note',
|
|
212
|
+
from: 'finding-sender',
|
|
213
|
+
to: 'all',
|
|
214
|
+
text: 'verified note',
|
|
215
|
+
ts: now - 1_000,
|
|
216
|
+
candidateIds: ['finding-owner'],
|
|
217
|
+
deliveryVersion: 2,
|
|
218
|
+
deliveries: [{
|
|
219
|
+
recipientId: 'finding-owner',
|
|
220
|
+
state: 'acknowledged',
|
|
221
|
+
attempts: 1,
|
|
222
|
+
offeredAt: now - 900,
|
|
223
|
+
acknowledgedAt: now - 500,
|
|
224
|
+
}],
|
|
225
|
+
seen: ['finding-owner'],
|
|
226
|
+
}],
|
|
192
227
|
sessions: lane, selfId: 'finding-sender', now,
|
|
193
228
|
});
|
|
194
|
-
checks.findingReceiptRendered = /
|
|
229
|
+
checks.findingReceiptRendered = /model-context delivery acknowledged by all 1 target peer\(s\) on a later action \(not human-read\)/.test(renderReceiptSummary(receipt));
|
|
195
230
|
}
|
|
196
231
|
|
|
197
232
|
// ── Cross-PC presence: simulated two-machine scenario ─────────────────────
|
|
@@ -305,7 +340,7 @@ const required = [
|
|
|
305
340
|
'exactBlockingOverlap',
|
|
306
341
|
'alertQueued',
|
|
307
342
|
'proactiveLogging',
|
|
308
|
-
'
|
|
343
|
+
'durableInBandOffer',
|
|
309
344
|
'findingRouteOwnerReason',
|
|
310
345
|
'findingRouteNobodyReason',
|
|
311
346
|
'findingReceiptRendered',
|
|
@@ -323,7 +358,8 @@ const result = {
|
|
|
323
358
|
metrics,
|
|
324
359
|
contract: {
|
|
325
360
|
proactive: 'best-effort MCP logging notification',
|
|
326
|
-
|
|
361
|
+
inBand: 'a retained machine-local note is offered on a supported model-context KLYPIX action, then acknowledged only by a later independent action; expiry/overflow are failed receipts',
|
|
362
|
+
crossMachine: 'relay primitives require caller-confirmed durable insertion and a per-recipient-machine acknowledgement; app bridge wiring is a separate conformance boundary',
|
|
327
363
|
},
|
|
328
364
|
};
|
|
329
365
|
|
|
@@ -336,6 +372,6 @@ if (jsonMode) {
|
|
|
336
372
|
}
|
|
337
373
|
if (checks.error) console.log(` error: ${checks.error}`);
|
|
338
374
|
console.log(` memory/coordination: ${metrics.firstClientMs ?? '?'}ms / ${metrics.secondClientMs ?? '?'}ms`);
|
|
339
|
-
console.log(' proactive notifications are best-effort;
|
|
375
|
+
console.log(' proactive notifications are best-effort; retained notes use offer → later-action acknowledgement, with explicit failure receipts.');
|
|
340
376
|
}
|
|
341
377
|
process.exit(ok ? 0 : 1);
|
package/bin/klypix-git-tools.mjs
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// • ONE merge engine — the driver rides src/merge-brains.mjs verbatim.
|
|
13
13
|
// • The registered driver path is the INSTALLED runtime
|
|
14
14
|
// (~/.claude/project-brain) — stable across npx cache evictions; this
|
|
15
|
-
// module self-provisions the
|
|
15
|
+
// module self-provisions the four engine files + their two deps there
|
|
16
16
|
// when missing, without running the full hook installer.
|
|
17
17
|
// • A truncated list must NEVER render as complete: every capped section
|
|
18
18
|
// emits its "…and N more" through an unguarded push.
|
|
@@ -85,11 +85,11 @@ async function loadEngine() {
|
|
|
85
85
|
|
|
86
86
|
// ── git-driver ──────────────────────────────────────────────────────────────
|
|
87
87
|
|
|
88
|
-
const ENGINE_FILES = ['klypix-merge-driver.mjs', 'merge-brains.mjs', 'klypix-format.mjs'];
|
|
88
|
+
const ENGINE_FILES = ['klypix-merge-driver.mjs', 'merge-brains.mjs', 'klypix-format.mjs', 'brain-graveyard.mjs'];
|
|
89
89
|
const ENGINE_DEPS = ['jszip', 'fractional-indexing'];
|
|
90
90
|
|
|
91
|
-
// Make sure the INSTALLED runtime can actually run the driver: the
|
|
92
|
-
// engine files plus their two
|
|
91
|
+
// Make sure the INSTALLED runtime can actually run the driver: the four
|
|
92
|
+
// engine files plus their two runtime deps. This is deliberately a
|
|
93
93
|
// light provision — it never touches hooks or servers; the full installer
|
|
94
94
|
// remains `npx klypix-mcp install`.
|
|
95
95
|
function ensureDriverRuntime() {
|
package/bin/klypix-install.mjs
CHANGED
|
@@ -226,7 +226,7 @@ const flatten = (code) => code
|
|
|
226
226
|
.replace(/\.\.\/src\/klypix-(core|format)\.mjs/g, './klypix-$1.mjs')
|
|
227
227
|
// brain-doctor + agent-rules (the server's lazy `import('../src/brain-doctor.mjs')`
|
|
228
228
|
// for the brain_doctor tool) → flat sibling refs in the runtime layout.
|
|
229
|
-
.replace(/\.\.\/src\/(brain-doctor|agent-rules|mcp-presence|mcp-supervisor|mcp-auto-update|semantic-memory|runtime-inspector|project-graph|git-capture-install)\.mjs/g, './$1.mjs')
|
|
229
|
+
.replace(/\.\.\/src\/(bench|brain-doctor|agent-presence|agent-rules|finding-routing|mcp-presence|mcp-supervisor|mcp-auto-update|presence-relay|semantic-memory|runtime-inspector|project-graph|git-capture-install)\.mjs/g, './$1.mjs')
|
|
230
230
|
.replace(/klypix-worker\.mjs/g, 'klypix-mcp-worker.mjs')
|
|
231
231
|
.replace(/const PKG_VERSION = \(\(\) => \{[\s\S]*?\}\)\(\);/, `const PKG_VERSION = '${VERSION}'; // baked at install (flat layout has no package.json)`);
|
|
232
232
|
|
|
@@ -293,7 +293,7 @@ try {
|
|
|
293
293
|
// canvas-view-app.html is the canvas_view MCP App UI — staged raw (an HTML
|
|
294
294
|
// file must never get a JS-comment banner) beside the flat server, which
|
|
295
295
|
// resolves it via its ./canvas-view-app.html candidate path.
|
|
296
|
-
for (const f of ['global-brain-hook.mjs', 'brain-semantic.mjs', 'semantic-memory.mjs', 'brain-note.mjs', 'brain-git-hook.mjs', 'git-capture-install.mjs', 'brain-history.mjs', 'brain-graveyard.mjs', 'klypix-format.mjs', 'klypix-core.mjs', 'brain-write-lock.mjs', 'agent-rules.mjs', 'brain-doctor.mjs', 'agent-presence.mjs', 'mcp-presence.mjs', 'finding-routing.mjs', 'mcp-supervisor.mjs', 'mcp-auto-update.mjs', 'runtime-inspector.mjs', 'project-graph.mjs', 'bench.mjs', 'codex-brain-hook.mjs', 'codex-hooks.mjs', 'canvas-view-app.html']) {
|
|
296
|
+
for (const f of ['global-brain-hook.mjs', 'brain-semantic.mjs', 'semantic-memory.mjs', 'brain-note.mjs', 'brain-git-hook.mjs', 'git-capture-install.mjs', 'brain-history.mjs', 'brain-graveyard.mjs', 'klypix-format.mjs', 'klypix-core.mjs', 'brain-write-lock.mjs', 'agent-rules.mjs', 'brain-doctor.mjs', 'agent-presence.mjs', 'mcp-presence.mjs', 'result-reconcile.mjs', 'finding-routing.mjs', 'presence-relay.mjs', 'mcp-supervisor.mjs', 'mcp-auto-update.mjs', 'runtime-inspector.mjs', 'project-graph.mjs', 'bench.mjs', 'codex-brain-hook.mjs', 'codex-hooks.mjs', 'canvas-view-app.html']) {
|
|
297
297
|
const s = path.join(SRC, f); if (exists(s)) staged.push({ dst: f, content: fs.readFileSync(s, 'utf8') });
|
|
298
298
|
}
|
|
299
299
|
for (const [src, dst] of [
|
package/bin/klypix-worker.mjs
CHANGED
|
@@ -509,7 +509,7 @@ server.registerTool('brain_note', {
|
|
|
509
509
|
|
|
510
510
|
server.registerTool('brain_message', {
|
|
511
511
|
title: 'Message the other live agent sessions on this project (one-time note, not a brain card)',
|
|
512
|
-
description: 'Leave a DELIBERATE, targeted note for the OTHER active agent sessions working on this project right now ("merged the hook refactor — rebase before you commit", "don\'t touch canvasStore, mid-refactor"). Any MCP client can send and receive through the shared presence lane.
|
|
512
|
+
description: 'Leave a DELIBERATE, targeted note for the OTHER active agent sessions working on this project right now ("merged the hook refactor — rebase before you commit", "don\'t touch canvasStore, mid-refactor"). Any MCP client can send and receive through the shared machine-local presence lane. A supported lifecycle event or KLYPIX tool result offers the note into model-visible context; a later independent supported action acknowledges that offer. Pending/offered notes replay after reconnect, while expiry or capacity loss leaves a failed per-recipient receipt instead of silently disappearing. Acknowledged means a later action followed the offer — it is NOT proof a human read it. Delivery remains OS-user-local, machine-local, bounded by a 24h TTL, and unavailable to a peer that never takes a supported action. Ephemeral and NOT persisted to the brain — for a durable decision use brain_note instead.',
|
|
513
513
|
inputSchema: {
|
|
514
514
|
text: z.string().describe('The note to deliver (kept to 400 chars).'),
|
|
515
515
|
to: z.string().optional().describe('Target hint — a peer session id-prefix or branch name; omit or "all" for every live session.'),
|
|
@@ -518,12 +518,23 @@ server.registerTool('brain_message', {
|
|
|
518
518
|
}, async ({ text, to, canvas }) => {
|
|
519
519
|
let via; try { via = server.server.getClientVersion()?.name; } catch { /* optional */ }
|
|
520
520
|
mcpPresence.noteSent(text);
|
|
521
|
-
return toContent(await opBrainMessage({
|
|
521
|
+
return toContent(await opBrainMessage({
|
|
522
|
+
vault: mcpPresence.vault,
|
|
523
|
+
// Bind the default message lane to the brain this worker actually joined.
|
|
524
|
+
// The worker process can be launched from an IDE/install directory that has
|
|
525
|
+
// a different ancestor brain; falling back to process.cwd() would split the
|
|
526
|
+
// sender presence and its message across two unrelated project lanes.
|
|
527
|
+
canvas: canvas || mcpPresence.brainPath,
|
|
528
|
+
text,
|
|
529
|
+
to,
|
|
530
|
+
via,
|
|
531
|
+
from: mcpPresence.refreshIdentity(),
|
|
532
|
+
}));
|
|
522
533
|
});
|
|
523
534
|
|
|
524
535
|
server.registerTool('brain_sync', {
|
|
525
536
|
title: 'KLYPIX Context Gateway — synchronize task, peers, conflicts, and relevant memory',
|
|
526
|
-
description: 'APPROVAL-FREE task gateway over the authorized MCP connection. Call FIRST with a concise intent and expected files, again when scope changes, and with phase:"complete" before the final response. One bounded response returns compact task-relevant brain context, active TASK peers (idle connections hidden), one-time messages, structured exact-file conflicts, and late-arrival overlap alerts. Works on any MCP host — it needs only the authorized MCP connection, so native lifecycle hooks are optional. LIMITS: conflict matching is EXACT-PATH and both sessions must have declared their files, coordination is machine-local and OS-user-local (a teammate on another machine is invisible), and overlap
|
|
537
|
+
description: 'APPROVAL-FREE task gateway over the authorized MCP connection. Call FIRST with a concise intent and expected files, again when scope changes, and with phase:"complete" before the final response. One bounded response returns compact task-relevant brain context, active TASK peers (idle connections hidden), one-time messages, structured exact-file conflicts, and late-arrival overlap alerts. A completion that supplies machine-checkable result manifests is fail-closed: invalid, conflicting, or incomparable evidence returns needs-reconciliation and retains task scope. Works on any MCP host — it needs only the authorized MCP connection, so native lifecycle hooks are optional. LIMITS: conflict matching is EXACT-PATH and both sessions must have declared their files, coordination/result reconciliation is machine-local and OS-user-local (a teammate on another machine is invisible), and file overlap remains ADVISORY.',
|
|
527
538
|
annotations: {
|
|
528
539
|
destructiveHint: false,
|
|
529
540
|
idempotentHint: true,
|
|
@@ -534,11 +545,24 @@ server.registerTool('brain_sync', {
|
|
|
534
545
|
intent: z.string().max(160).optional().describe('One sentence describing the current task. Supply for start/checkpoint; completion clears it.'),
|
|
535
546
|
files: z.array(z.string()).max(20).optional().describe('Project-relative files you expect to touch or have touched. Exact overlaps with peers are flagged.'),
|
|
536
547
|
phase: z.enum(['start', 'checkpoint', 'complete']).optional().describe('start replaces prior task scope; checkpoint merges changed scope; complete clears task intent/files. Default: checkpoint.'),
|
|
537
|
-
include_context: z.boolean().optional().describe('Include fast task-relevant brain cards in the same response. Defaults true;
|
|
548
|
+
include_context: z.boolean().optional().describe('Include fast task-relevant brain cards and offer queued coordination notes in the same response. Defaults true; false also defers note delivery so internal supervisor probes cannot consume model-visible messages.'),
|
|
549
|
+
// Deliberately permissive at the MCP/Zod boundary. The authoritative,
|
|
550
|
+
// versioned fail-closed validator lives in result-reconcile.mjs and must see
|
|
551
|
+
// malformed/unknown nested fields so it can persist the evidence-required
|
|
552
|
+
// marker before rejecting them. A strict transport schema rejected first,
|
|
553
|
+
// allowing a later result-less completion to bypass that state entirely.
|
|
554
|
+
results: z.unknown().optional().describe('On phase complete, 1-8 result manifests for stable claim keys. The in-handler versioned validator rejects malformed, empty, unknown-field, or incomparable evidence and retains task scope.'),
|
|
538
555
|
},
|
|
539
|
-
}, async ({ project, intent, files, phase, include_context }) => {
|
|
556
|
+
}, async ({ project, intent, files, phase, include_context, results }) => {
|
|
540
557
|
const totalStartedAt = Date.now();
|
|
541
|
-
const report = mcpPresence.sync({
|
|
558
|
+
const report = mcpPresence.sync({
|
|
559
|
+
project,
|
|
560
|
+
intent,
|
|
561
|
+
files,
|
|
562
|
+
phase,
|
|
563
|
+
results,
|
|
564
|
+
deliverMessages: include_context !== false,
|
|
565
|
+
});
|
|
542
566
|
// Zero-manual harness convergence: brain_sync is the one project-aware
|
|
543
567
|
// gateway every MCP host can call. Register MCP-only projects here (Claude's
|
|
544
568
|
// lifecycle hook is no longer the sole registry writer), then reconcile only
|
|
@@ -624,6 +648,7 @@ server.registerTool('brain_sync', {
|
|
|
624
648
|
text: [report.text, harnessText, shipNotice, contextText, timingText].filter(Boolean).join('\n\n'),
|
|
625
649
|
}],
|
|
626
650
|
structuredContent,
|
|
651
|
+
...(report.isError ? { isError: true } : {}),
|
|
627
652
|
};
|
|
628
653
|
});
|
|
629
654
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "klypix-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.66.0",
|
|
4
4
|
"description": "Shared project brain and MCP coordination server for multi-agent coding.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"./core": "./src/klypix-core.mjs",
|
|
54
54
|
"./presence": "./src/agent-presence.mjs",
|
|
55
55
|
"./mcp-presence": "./src/mcp-presence.mjs",
|
|
56
|
+
"./result-reconcile": "./src/result-reconcile.mjs",
|
|
56
57
|
"./presence-relay": "./src/presence-relay.mjs",
|
|
57
58
|
"./supervisor": "./src/mcp-supervisor.mjs",
|
|
58
59
|
"./runtime-inspector": "./src/runtime-inspector.mjs",
|
|
@@ -79,7 +80,7 @@
|
|
|
79
80
|
"test:project-graph": "node test/project-graph.mjs",
|
|
80
81
|
"bench": "node bin/klypix-mcp.mjs bench",
|
|
81
82
|
"test:bench": "node test/bench.mjs",
|
|
82
|
-
"test": "node test/publish-verdict.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/agent-presence.mjs && node test/intent-guard.mjs && node test/git-capture-install.mjs && node test/brain-history.mjs && node test/brain-graveyard.mjs && node test/finding-routing.mjs && node test/finding-routing-hook.mjs && node test/presence-relay.mjs && node test/context-gateway.mjs && node test/conformance.mjs && node test/brain-doctor.mjs && node test/version-currency.mjs && node test/ship-capture.mjs && node test/lane-message.mjs && node test/brain-quality.mjs && node test/brain-connect-orphans.mjs && node test/brief-and-recall.mjs && node test/layout-cluster.mjs && node test/brain-ask.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/skill-staleness.mjs && node test/canvas-view.mjs && node test/status-completeness.mjs && node test/semantic-gate.mjs && node test/memory-runtime.mjs && node test/semantic-cache.mjs && node test/decay-status.mjs && node test/decay-hook.mjs && node test/evidence-anchors.mjs && node test/presence-visibility.mjs && node test/merge-brains.mjs && node test/concurrent-writes.mjs && node test/lock-interop.mjs && node test/a2a-smoke.mjs && node test/cli-args.mjs && node test/format-guard.mjs && node test/git-tools.mjs && node test/uninstall.mjs",
|
|
83
|
+
"test": "node test/publish-verdict.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/agent-presence.mjs && node test/result-reconcile.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/context-gateway.mjs && node test/conformance.mjs && node test/brain-doctor.mjs && node test/version-currency.mjs && node test/ship-capture.mjs && node test/lane-message.mjs && node test/brain-quality.mjs && node test/brain-connect-orphans.mjs && node test/brief-and-recall.mjs && node test/layout-cluster.mjs && node test/brain-ask.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/skill-staleness.mjs && node test/canvas-view.mjs && node test/status-completeness.mjs && node test/semantic-gate.mjs && node test/memory-runtime.mjs && node test/semantic-cache.mjs && node test/decay-status.mjs && node test/decay-hook.mjs && node test/evidence-anchors.mjs && node test/presence-visibility.mjs && node test/merge-brains.mjs && node test/concurrent-writes.mjs && node test/lock-interop.mjs && node test/a2a-smoke.mjs && node test/cli-args.mjs && node test/format-guard.mjs && node test/git-tools.mjs && node test/uninstall.mjs",
|
|
83
84
|
"test:memory": "node test/memory-runtime.mjs",
|
|
84
85
|
"test:memory:soak": "node --expose-gc test/memory-soak.mjs",
|
|
85
86
|
"runtime": "node bin/klypix-runtime.mjs"
|