@rubytech/create-maxy-code 0.1.64 → 0.1.66
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/package.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +1 -1
- package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +140 -61
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +135 -49
- package/payload/platform/plugins/docs/references/admin-session.md +19 -4
- package/payload/platform/plugins/docs/references/internals.md +7 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/_helpers/emit-capture.d.ts +22 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/_helpers/emit-capture.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/_helpers/emit-capture.js +44 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/_helpers/emit-capture.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights-emit.test.js +68 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection-emit.test.js +48 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-memory-expunge-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-memory-expunge-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-memory-expunge-emit.test.js +53 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-memory-expunge-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/graph-prune-denylist-add-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/graph-prune-denylist-add-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/graph-prune-denylist-add-emit.test.js +40 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/graph-prune-denylist-add-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/graph-prune-denylist-remove-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/graph-prune-denylist-remove-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/graph-prune-denylist-remove-emit.test.js +39 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/graph-prune-denylist-remove-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write-emit.test.js +88 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-classify-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-classify-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-classify-emit.test.js +58 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-classify-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-emit.test.js +58 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-edit-attachment-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-edit-attachment-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-edit-attachment-emit.test.js +70 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-edit-attachment-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-emit.test.js +48 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-emit.test.js +74 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-extract-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-extract-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-extract-emit.test.js +47 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-extract-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-web-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-web-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-web-emit.test.js +65 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-web-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex-emit.test.js +43 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-rename-attachment-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-rename-attachment-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-rename-attachment-emit.test.js +65 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-rename-attachment-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-restore-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-restore-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-restore-emit.test.js +49 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-restore-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-emit.test.js +74 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-emit.test.js +74 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-delete-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-delete-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-delete-emit.test.js +62 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-delete-emit.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-emit.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-emit.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-emit.test.js +76 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-emit.test.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/index.js +75 -2
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +8 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +14 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts +24 -4
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js +39 -9
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -1
- package/payload/server/server-init.cjs +40 -0
|
@@ -492,7 +492,13 @@ For subagents, the same spawn pushes `--add-dir` for every bundled plugin agents
|
|
|
492
492
|
|
|
493
493
|
A boot gate refuses to start the manager when any admin-allowlisted tool `mcp__<plugin>__*` lacks a registered server. The signal is `boot-failed reason=mcp-allowlist-without-server plugin=<p> tool=<t>` followed by `process.exit(1)`. The remediation is a one-line edit to the named `PLUGIN.md`: add the `mcp:` block. The complementary observability emit `mcp-config-allowlist-coverage admin-tools=A admin-registered=R` (where `A === R`) confirms the invariant per boot.
|
|
494
494
|
|
|
495
|
-
|
|
495
|
+
A second boot gate walks every specialist `.md` under `platform/templates/specialists/agents/`, every bundled `<plugin>/agents/` directory, and the per-account `<accountDir>/specialists/agents/` directory, parses each file's `tools:` frontmatter line, and classifies every tool name as one of: CC-native (Read, Bash, …), bridge-namespace (`mcp__plugin_playwright_*`, `mcp__graph__*`), a tool the loaded `PLUGIN.md` set actually serves, `unknown-tool-in-plugin` (namespace served but tool name absent), `unknown-plugin-namespace` (namespace served by nothing), `brand-excluded-plugin` (namespace served by nothing on this brand, **but** the brand's `brand.json#plugins.excluded` list names it), or `malformed-name` (not CC-native and not `mcp__<plugin>__<tool>`-shaped). The first three pass. The next two refuse boot with one `boot-failed reason=specialist-tool-drift specialist=<name> tool=<t> drift=<class> path=<…>` line per defect, then `process.exit(1)`. `brand-excluded-plugin` is a structural pass: it lands in a per-specialist strip-list, the manager continues to boot, and at spawn time `pty-spawner` removes those tool names from the `--agent <name>` spawn's `--allowed-tools` argv. The complementary observability emit `specialist-tool-strip specialist=<name> plugin=<p> tools=<csv> reason=brand-excluded` fires one line per stripped (specialist, plugin) pair so an operator who reads `server.log` sees the brand filter doing work without cross-referencing `brand.json` against the template. The startup-self-test line `startup-self-test specialist-tool-drift=ok inspected=<N> stripped-specialists=<M>` confirms the gate ran and how many specialists carry strip-lists.
|
|
496
|
+
|
|
497
|
+
This gate was Task 173. The `brand-excluded` branch closes the recurring crash-restart loop on brands that ship without a plugin the shared `personal-assistant.md` template references (e.g. `realagent-code` excludes `telegram` while the template hard-codes `mcp__telegram__*`). The brand-agnostic template stays a single file; the brand-aware filter expresses what the specialist *may* do on this install while the template expresses what it *can* do across brands. Tool typos and renamed plugins still refuse to boot — only namespaces explicitly named in `plugins.excluded` are demoted to strip-and-warn.
|
|
498
|
+
|
|
499
|
+
**Per-spawn signals (server.log).** Every spawn emits `pty-spawn-mcp-config servers=<N> tools=<M> bytes=<B> path=<…>` once, plus one `pty-spawn-agents-dir role=<admin|public> path=<…>` per added directory. Specialist spawns additionally emit `pty-spawn-allowlist specialist=<name> count=<N> stripped=<S> sourced-from=agent-frontmatter` where `stripped` is the count of brand-excluded tool names removed before argv emission. The diagnostic one-liner is `grep -E 'pty-spawn-mcp-config|pty-spawn-agents-dir|pty-spawn-allowlist|mcp-config-allowlist-coverage|specialist-tool-strip|boot-failed reason=' ~/.<brand>/logs/server.log | tail -50`.
|
|
500
|
+
|
|
501
|
+
**Brand-process start counter (Task 173).** `platform/ui/server-init.cjs` increments a persistent counter at `/tmp/server-init-<accountId>-restart.count` on every fresh start and emits `[server-init] start count=<N> account=<accountId> counter-path=<…>` to `server.log`. /tmp clears on reboot, so a clean reboot starts the count fresh; any value `>1` between operator-observed reboots means the brand process (driven by its `Requires=<brand>-claude-session-manager.service` clause) is restarting. The diagnostic one-liner is `grep '\[server-init\] start' ~/.<brand>/logs/server.log | tail -5` — the trailing `count=` value is the loop depth without counting SIGTERMs.
|
|
496
502
|
|
|
497
503
|
**Programmatic spawn entry point.** Every admin PTY spawn that needs a first user prompt — UI click, turn-recorder hook, future automation — routes through the single wrapper at [`platform/ui/server/routes/admin/claude-sessions.ts`](../../../ui/server/routes/admin/claude-sessions.ts). The wrapper owns the per-spawn enrichment (owner profile, dormant/active plugins, specialist domains, tunnel URL) and the `senderId` resolution; it forwards a single `POST /spawn` to the session manager on `127.0.0.1`, with `initialMessage` inlined on that body. The manager appends `initialMessage` as the trailing positional argv to `claude`, so the CLI processes it as the session's first user turn at PTY startup — no separate `POST /<sessionId>/input` call, no bracketed-paste. (Task 153.) See `admin-session.md` "Spawn-with-initialMessage wrapper" for the body schema and caller list.
|
|
498
504
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
export interface CapturedEmit {
|
|
3
|
+
tag: string;
|
|
4
|
+
level: "info" | "error" | "warn" | "debug";
|
|
5
|
+
line: string;
|
|
6
|
+
}
|
|
7
|
+
export interface EmitCapture {
|
|
8
|
+
fetchSpy: ReturnType<typeof vi.fn>;
|
|
9
|
+
captures: () => CapturedEmit[];
|
|
10
|
+
restore: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function setupEmitCapture(port?: string): EmitCapture;
|
|
13
|
+
/**
|
|
14
|
+
* Build a Neo4j Session stub whose `.run()` returns records constructed from
|
|
15
|
+
* row objects. Each call to `.run()` consumes the next entry from rowSequence.
|
|
16
|
+
* A row is a plain object — its keys are accessed by `record.get(key)`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function makeMockSession(rowSequence?: Array<Array<Record<string, unknown>>>): {
|
|
19
|
+
run: import("vitest").Mock<import("@vitest/spy").Procedure>;
|
|
20
|
+
close: import("vitest").Mock<import("@vitest/spy").Procedure>;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=emit-capture.d.ts.map
|
package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/_helpers/emit-capture.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-capture.d.ts","sourceRoot":"","sources":["../../../../src/tools/__tests__/_helpers/emit-capture.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,YAAY,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,SAAU,GAAG,WAAW,CAmB5D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,GAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAM;;;EAatF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Task 168 — shared test helper for per-tool emit assertions.
|
|
2
|
+
//
|
|
3
|
+
// Spies global fetch, sets PLATFORM_PORT so withWriteEvent reaches the
|
|
4
|
+
// loopback URL (instead of stderr-fallback), and exposes the captured
|
|
5
|
+
// POST bodies. Each test pairs this with whatever per-tool deps it must
|
|
6
|
+
// mock so the wrapped body either resolves or throws.
|
|
7
|
+
import { vi } from "vitest";
|
|
8
|
+
export function setupEmitCapture(port = "12345") {
|
|
9
|
+
process.env.PLATFORM_PORT = port;
|
|
10
|
+
const originalFetch = globalThis.fetch;
|
|
11
|
+
const fetchSpy = vi.fn().mockResolvedValue(new Response('{"ok":true}', { status: 200 }));
|
|
12
|
+
globalThis.fetch = fetchSpy;
|
|
13
|
+
return {
|
|
14
|
+
fetchSpy,
|
|
15
|
+
captures: () => fetchSpy.mock.calls.map((call) => {
|
|
16
|
+
const init = call[1];
|
|
17
|
+
return JSON.parse(init.body);
|
|
18
|
+
}),
|
|
19
|
+
restore: () => {
|
|
20
|
+
globalThis.fetch = originalFetch;
|
|
21
|
+
delete process.env.PLATFORM_PORT;
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build a Neo4j Session stub whose `.run()` returns records constructed from
|
|
27
|
+
* row objects. Each call to `.run()` consumes the next entry from rowSequence.
|
|
28
|
+
* A row is a plain object — its keys are accessed by `record.get(key)`.
|
|
29
|
+
*/
|
|
30
|
+
export function makeMockSession(rowSequence = []) {
|
|
31
|
+
let i = 0;
|
|
32
|
+
return {
|
|
33
|
+
run: vi.fn().mockImplementation(async () => {
|
|
34
|
+
const rows = rowSequence[i++] ?? [];
|
|
35
|
+
return {
|
|
36
|
+
records: rows.map((row) => ({
|
|
37
|
+
get: (key) => row[key],
|
|
38
|
+
})),
|
|
39
|
+
};
|
|
40
|
+
}),
|
|
41
|
+
close: vi.fn().mockResolvedValue(undefined),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=emit-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-capture.js","sourceRoot":"","sources":["../../../../src/tools/__tests__/_helpers/emit-capture.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,wEAAwE;AACxE,sDAAsD;AAEtD,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAc5B,MAAM,UAAU,gBAAgB,CAAC,IAAI,GAAG,OAAO;IAC7C,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC;IACjC,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC;IACvC,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CACxC,IAAI,QAAQ,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAC7C,CAAC;IACF,UAAU,CAAC,KAAK,GAAG,QAAmC,CAAC;IACvD,OAAO;QACL,QAAQ;QACR,QAAQ,EAAE,GAAG,EAAE,CACb,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAgB,CAAC;YACpC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAc,CAAiB,CAAC;QACzD,CAAC,CAAC;QACJ,OAAO,EAAE,GAAG,EAAE;YACZ,UAAU,CAAC,KAAK,GAAG,aAAa,CAAC;YACjC,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,cAAqD,EAAE;IACrF,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO;QACL,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE;YACzC,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBAC1B,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;iBAC/B,CAAC,CAAC;aACJ,CAAC;QACJ,CAAC,CAAC;QACF,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;KAC5C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-archive-derive-insights-emit.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/conversation-archive-derive-insights-emit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Task 168 — per-tool emit assertion for conversation-archive-derive-insights.
|
|
2
|
+
//
|
|
3
|
+
// Read-only inside the wrapper but routed through it because Task 166 wired
|
|
4
|
+
// every write-path tool — here it pins observability for the dispatch path,
|
|
5
|
+
// not data writes. Happy path requires real chunks + Haiku; error path is
|
|
6
|
+
// the natural archive-not-found gate.
|
|
7
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
8
|
+
import { setupEmitCapture, makeMockSession } from "./_helpers/emit-capture.js";
|
|
9
|
+
const mockSession = makeMockSession();
|
|
10
|
+
vi.mock("../../lib/neo4j.js", () => ({
|
|
11
|
+
getSession: () => mockSession,
|
|
12
|
+
}));
|
|
13
|
+
vi.mock("../../../../../../lib/oauth-llm/dist/index.js", () => ({
|
|
14
|
+
callOauthLlm: vi.fn(),
|
|
15
|
+
}));
|
|
16
|
+
import { conversationArchiveDeriveInsights } from "../conversation-archive-derive-insights.js";
|
|
17
|
+
describe("conversation-archive-derive-insights — emit wrapper wired", () => {
|
|
18
|
+
let emit;
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
emit = setupEmitCapture();
|
|
21
|
+
mockSession.run.mockReset();
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => emit.restore());
|
|
24
|
+
it("emits result=error line when archive not found", async () => {
|
|
25
|
+
// loadArchive's MATCH returns no rows → tool throws archive-not-found.
|
|
26
|
+
mockSession.run.mockResolvedValue({ records: [] });
|
|
27
|
+
await expect(conversationArchiveDeriveInsights({
|
|
28
|
+
accountId: "acct-1",
|
|
29
|
+
archiveElementId: "4:missing:1",
|
|
30
|
+
})).rejects.toThrow(/archive-not-found/);
|
|
31
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
32
|
+
const body = emit.captures()[0];
|
|
33
|
+
expect(body.tag).toBe("mcp:memory");
|
|
34
|
+
expect(body.level).toBe("error");
|
|
35
|
+
expect(body.line).toContain("conversation-archive-derive-insights");
|
|
36
|
+
expect(body.line).toContain("result=error");
|
|
37
|
+
});
|
|
38
|
+
it("emits result=ok line on happy path (archive with no chunks to walk)", async () => {
|
|
39
|
+
// loadArchive: one row with archive metadata + totalChunks=1 (totalChunks=0
|
|
40
|
+
// is treated as archive-not-found per loadArchive guard).
|
|
41
|
+
mockSession.run.mockResolvedValueOnce({
|
|
42
|
+
records: [
|
|
43
|
+
{
|
|
44
|
+
get: (k) => {
|
|
45
|
+
if (k === "title")
|
|
46
|
+
return "Stub Archive";
|
|
47
|
+
if (k === "totalChunks")
|
|
48
|
+
return 1;
|
|
49
|
+
return null;
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
});
|
|
54
|
+
// loadChunks: empty — for-loop never iterates so no LLM/related-cypher fires.
|
|
55
|
+
mockSession.run.mockResolvedValueOnce({ records: [] });
|
|
56
|
+
await conversationArchiveDeriveInsights({
|
|
57
|
+
accountId: "acct-1",
|
|
58
|
+
archiveElementId: "4:archive:1",
|
|
59
|
+
});
|
|
60
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
61
|
+
const body = emit.captures()[0];
|
|
62
|
+
expect(body.tag).toBe("mcp:memory");
|
|
63
|
+
expect(body.level).toBe("info");
|
|
64
|
+
expect(body.line).toContain("conversation-archive-derive-insights");
|
|
65
|
+
expect(body.line).toContain("result=ok");
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=conversation-archive-derive-insights-emit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-archive-derive-insights-emit.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/conversation-archive-derive-insights-emit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-archive-enrich-rejection-emit.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/conversation-archive-enrich-rejection-emit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Task 168 — per-tool emit assertion for conversation-archive-enrich-rejection.
|
|
2
|
+
//
|
|
3
|
+
// Existing memory MCP test (conversation-archive-enrich-rejection.test.ts)
|
|
4
|
+
// runs the impl against a scratch directory; this companion file isolates
|
|
5
|
+
// the emit-wrapper contract. We mock the underlying derive-insights module's
|
|
6
|
+
// path constants + key helper so the impl runs without needing PLATFORM_ROOT.
|
|
7
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
8
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { setupEmitCapture } from "./_helpers/emit-capture.js";
|
|
12
|
+
import { conversationArchiveEnrichRejection } from "../conversation-archive-enrich-rejection.js";
|
|
13
|
+
describe("conversation-archive-enrich-rejection — emit wrapper wired", () => {
|
|
14
|
+
let emit;
|
|
15
|
+
let scratch;
|
|
16
|
+
let origRoot;
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
emit = setupEmitCapture();
|
|
19
|
+
scratch = mkdtempSync(resolve(tmpdir(), "task-168-"));
|
|
20
|
+
origRoot = process.env.PLATFORM_ROOT;
|
|
21
|
+
process.env.PLATFORM_ROOT = resolve(scratch, "platform");
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
emit.restore();
|
|
25
|
+
if (origRoot === undefined)
|
|
26
|
+
delete process.env.PLATFORM_ROOT;
|
|
27
|
+
else
|
|
28
|
+
process.env.PLATFORM_ROOT = origRoot;
|
|
29
|
+
rmSync(scratch, { recursive: true, force: true });
|
|
30
|
+
});
|
|
31
|
+
it("emits result=ok line on happy path (record mode)", async () => {
|
|
32
|
+
await conversationArchiveEnrichRejection({
|
|
33
|
+
accountId: "acct-1",
|
|
34
|
+
archiveElementId: "4:archive:1",
|
|
35
|
+
chunkElementId: "4:chunk:1",
|
|
36
|
+
kind: "mention",
|
|
37
|
+
contentHash: "abcd",
|
|
38
|
+
mode: "record",
|
|
39
|
+
});
|
|
40
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
41
|
+
const body = emit.captures()[0];
|
|
42
|
+
expect(body.tag).toBe("mcp:memory");
|
|
43
|
+
expect(body.level).toBe("info");
|
|
44
|
+
expect(body.line).toContain("conversation-archive-enrich-rejection");
|
|
45
|
+
expect(body.line).toContain("result=ok");
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=conversation-archive-enrich-rejection-emit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-archive-enrich-rejection-emit.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/conversation-archive-enrich-rejection-emit.test.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,2EAA2E;AAC3E,0EAA0E;AAC1E,6EAA6E;AAC7E,8EAA8E;AAE9E,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAM,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,EAAE,kCAAkC,EAAE,MAAM,6CAA6C,CAAC;AAEjG,QAAQ,CAAC,4DAA4D,EAAE,GAAG,EAAE;IAC1E,IAAI,IAAyC,CAAC;IAC9C,IAAI,OAAe,CAAC;IACpB,IAAI,QAA4B,CAAC;IAEjC,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAC1B,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;QACtD,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IACH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;;YACxD,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC1C,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,kCAAkC,CAAC;YACvC,SAAS,EAAE,QAAQ;YACnB,gBAAgB,EAAE,aAAa;YAC/B,cAAc,EAAE,WAAW;YAC3B,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,MAAM;YACnB,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAC;QACrE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-memory-expunge-emit.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/conversation-memory-expunge-emit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Task 168 — per-tool emit assertion for conversation-memory-expunge.
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
3
|
+
import { setupEmitCapture } from "./_helpers/emit-capture.js";
|
|
4
|
+
vi.mock("../../lib/neo4j.js", () => ({
|
|
5
|
+
getDriver: () => ({}),
|
|
6
|
+
}));
|
|
7
|
+
vi.mock("../../lib/graph-prune.js", () => ({
|
|
8
|
+
expungeConversationMemory: vi.fn(),
|
|
9
|
+
}));
|
|
10
|
+
import { conversationMemoryExpunge } from "../conversation-memory-expunge.js";
|
|
11
|
+
import { expungeConversationMemory } from "../../lib/graph-prune.js";
|
|
12
|
+
describe("conversation-memory-expunge — emit wrapper wired", () => {
|
|
13
|
+
let emit;
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
emit = setupEmitCapture();
|
|
16
|
+
vi.mocked(expungeConversationMemory).mockReset();
|
|
17
|
+
});
|
|
18
|
+
afterEach(() => emit.restore());
|
|
19
|
+
it("emits result=ok line on happy path", async () => {
|
|
20
|
+
vi.mocked(expungeConversationMemory).mockResolvedValue({
|
|
21
|
+
conversationId: "conv-1",
|
|
22
|
+
pattern: ".*",
|
|
23
|
+
nodesScanned: 0,
|
|
24
|
+
propertiesNulled: 0,
|
|
25
|
+
affectedNodeIds: [],
|
|
26
|
+
});
|
|
27
|
+
await conversationMemoryExpunge({
|
|
28
|
+
accountId: "acct-1",
|
|
29
|
+
conversationId: "conv-1",
|
|
30
|
+
pattern: ".*",
|
|
31
|
+
});
|
|
32
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
33
|
+
const body = emit.captures()[0];
|
|
34
|
+
expect(body.tag).toBe("mcp:memory");
|
|
35
|
+
expect(body.level).toBe("info");
|
|
36
|
+
expect(body.line).toContain("conversation-memory-expunge");
|
|
37
|
+
expect(body.line).toContain("result=ok");
|
|
38
|
+
});
|
|
39
|
+
it("emits result=error line when expungeConversationMemory throws", async () => {
|
|
40
|
+
vi.mocked(expungeConversationMemory).mockRejectedValue(new Error("driver error"));
|
|
41
|
+
await expect(conversationMemoryExpunge({
|
|
42
|
+
accountId: "acct-1",
|
|
43
|
+
conversationId: "conv-1",
|
|
44
|
+
pattern: ".*",
|
|
45
|
+
})).rejects.toThrow(/driver error/);
|
|
46
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
47
|
+
const body = emit.captures()[0];
|
|
48
|
+
expect(body.level).toBe("error");
|
|
49
|
+
expect(body.line).toContain("conversation-memory-expunge");
|
|
50
|
+
expect(body.line).toContain("result=error");
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=conversation-memory-expunge-emit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-memory-expunge-emit.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/conversation-memory-expunge-emit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-prune-denylist-add-emit.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/graph-prune-denylist-add-emit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Task 168 — per-tool emit assertion for graph-prune-denylist-add.
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
3
|
+
import { setupEmitCapture } from "./_helpers/emit-capture.js";
|
|
4
|
+
vi.mock("../../lib/graph-prune.js", () => ({
|
|
5
|
+
resolveConfigDir: () => "/tmp/task-168-stub",
|
|
6
|
+
loadDenylist: () => ({ values: [] }),
|
|
7
|
+
saveDenylist: vi.fn(),
|
|
8
|
+
}));
|
|
9
|
+
import { graphPruneDenylistAdd } from "../graph-prune-denylist-add.js";
|
|
10
|
+
import * as graphPrune from "../../lib/graph-prune.js";
|
|
11
|
+
describe("graph-prune-denylist-add — emit wrapper wired", () => {
|
|
12
|
+
let emit;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
emit = setupEmitCapture();
|
|
15
|
+
vi.mocked(graphPrune.saveDenylist).mockReset();
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => emit.restore());
|
|
18
|
+
it("emits result=ok line on happy path", async () => {
|
|
19
|
+
await graphPruneDenylistAdd(["NewLabel"]);
|
|
20
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
21
|
+
const body = emit.captures()[0];
|
|
22
|
+
expect(body.tag).toBe("mcp:memory");
|
|
23
|
+
expect(body.level).toBe("info");
|
|
24
|
+
expect(body.line).toContain("graph-prune-denylist-add");
|
|
25
|
+
expect(body.line).toContain("result=ok");
|
|
26
|
+
});
|
|
27
|
+
it("emits result=error line when saveDenylist throws", async () => {
|
|
28
|
+
vi.mocked(graphPrune.saveDenylist).mockImplementation(() => {
|
|
29
|
+
throw new Error("disk full");
|
|
30
|
+
});
|
|
31
|
+
await expect(graphPruneDenylistAdd(["NewLabel"])).rejects.toThrow(/disk full/);
|
|
32
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
33
|
+
const body = emit.captures()[0];
|
|
34
|
+
expect(body.level).toBe("error");
|
|
35
|
+
expect(body.line).toContain("graph-prune-denylist-add");
|
|
36
|
+
expect(body.line).toContain("result=error");
|
|
37
|
+
expect(body.line).toContain("reason=neo4j-driver-error");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=graph-prune-denylist-add-emit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-prune-denylist-add-emit.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/graph-prune-denylist-add-emit.test.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,EAAE,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,CAAC;IACzC,gBAAgB,EAAE,GAAG,EAAE,CAAC,oBAAoB;IAC5C,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACpC,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;CACtB,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,UAAU,MAAM,0BAA0B,CAAC;AAEvD,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;IAC7D,IAAI,IAAyC,CAAC;IAC9C,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAC1B,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IACH,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAEhC,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,qBAAqB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACzD,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC/E,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-prune-denylist-remove-emit.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/graph-prune-denylist-remove-emit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Task 168 — per-tool emit assertion for graph-prune-denylist-remove.
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
3
|
+
import { setupEmitCapture } from "./_helpers/emit-capture.js";
|
|
4
|
+
vi.mock("../../lib/graph-prune.js", () => ({
|
|
5
|
+
resolveConfigDir: () => "/tmp/task-168-stub",
|
|
6
|
+
loadDenylist: () => ({ values: ["ExistingLabel"] }),
|
|
7
|
+
saveDenylist: vi.fn(),
|
|
8
|
+
}));
|
|
9
|
+
import { graphPruneDenylistRemove } from "../graph-prune-denylist-remove.js";
|
|
10
|
+
import * as graphPrune from "../../lib/graph-prune.js";
|
|
11
|
+
describe("graph-prune-denylist-remove — emit wrapper wired", () => {
|
|
12
|
+
let emit;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
emit = setupEmitCapture();
|
|
15
|
+
vi.mocked(graphPrune.saveDenylist).mockReset();
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => emit.restore());
|
|
18
|
+
it("emits result=ok line on happy path", async () => {
|
|
19
|
+
await graphPruneDenylistRemove(["ExistingLabel"]);
|
|
20
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
21
|
+
const body = emit.captures()[0];
|
|
22
|
+
expect(body.tag).toBe("mcp:memory");
|
|
23
|
+
expect(body.level).toBe("info");
|
|
24
|
+
expect(body.line).toContain("graph-prune-denylist-remove");
|
|
25
|
+
expect(body.line).toContain("result=ok");
|
|
26
|
+
});
|
|
27
|
+
it("emits result=error line when saveDenylist throws", async () => {
|
|
28
|
+
vi.mocked(graphPrune.saveDenylist).mockImplementation(() => {
|
|
29
|
+
throw new Error("permission denied");
|
|
30
|
+
});
|
|
31
|
+
await expect(graphPruneDenylistRemove(["ExistingLabel"])).rejects.toThrow(/permission denied/);
|
|
32
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
33
|
+
const body = emit.captures()[0];
|
|
34
|
+
expect(body.level).toBe("error");
|
|
35
|
+
expect(body.line).toContain("graph-prune-denylist-remove");
|
|
36
|
+
expect(body.line).toContain("result=error");
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=graph-prune-denylist-remove-emit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-prune-denylist-remove-emit.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/graph-prune-denylist-remove-emit.test.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,EAAE,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,CAAC;IACzC,gBAAgB,EAAE,GAAG,EAAE,CAAC,oBAAoB;IAC5C,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC;IACnD,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;CACtB,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,KAAK,UAAU,MAAM,0BAA0B,CAAC;AAEvD,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,IAAI,IAAyC,CAAC;IAC9C,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAC1B,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IACH,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAEhC,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,wBAAwB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACzD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC/F,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-archive-write-emit.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-archive-write-emit.test.ts"],"names":[],"mappings":""}
|
package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write-emit.test.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Task 168 — per-tool emit assertion for memory-archive-write.
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
3
|
+
import { setupEmitCapture } from "./_helpers/emit-capture.js";
|
|
4
|
+
const mockSession = {
|
|
5
|
+
run: vi.fn(),
|
|
6
|
+
executeWrite: vi.fn(),
|
|
7
|
+
close: vi.fn().mockResolvedValue(undefined),
|
|
8
|
+
};
|
|
9
|
+
vi.mock("../../lib/neo4j.js", () => ({
|
|
10
|
+
getSession: () => mockSession,
|
|
11
|
+
}));
|
|
12
|
+
import { memoryArchiveWrite } from "../memory-archive-write.js";
|
|
13
|
+
describe("memory-archive-write — emit wrapper wired", () => {
|
|
14
|
+
let emit;
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
emit = setupEmitCapture();
|
|
17
|
+
mockSession.run.mockReset();
|
|
18
|
+
mockSession.executeWrite.mockReset();
|
|
19
|
+
});
|
|
20
|
+
afterEach(() => emit.restore());
|
|
21
|
+
it("emits result=ok line on happy path", async () => {
|
|
22
|
+
// verifyArchive's MATCH: owner found with :Person label and matching account.
|
|
23
|
+
mockSession.run.mockResolvedValue({
|
|
24
|
+
records: [
|
|
25
|
+
{
|
|
26
|
+
get: (k) => {
|
|
27
|
+
if (k === "labels")
|
|
28
|
+
return ["Person"];
|
|
29
|
+
if (k === "accountId")
|
|
30
|
+
return "acct-1";
|
|
31
|
+
return null;
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
const noopCounters = {
|
|
37
|
+
nodesCreated: 0,
|
|
38
|
+
relationshipsCreated: 0,
|
|
39
|
+
propertiesSet: 0,
|
|
40
|
+
};
|
|
41
|
+
// writeBatch wraps personRes / orgRes inside executeWrite. Return the
|
|
42
|
+
// counter shapes the handler reads.
|
|
43
|
+
mockSession.executeWrite.mockImplementation(async (fn) => {
|
|
44
|
+
return fn({
|
|
45
|
+
run: vi.fn().mockResolvedValue({
|
|
46
|
+
summary: { counters: { updates: () => noopCounters } },
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
await memoryArchiveWrite({
|
|
51
|
+
archiveType: "linkedin-connections",
|
|
52
|
+
ownerNodeId: "4:owner:1",
|
|
53
|
+
accountId: "acct-1",
|
|
54
|
+
rows: [
|
|
55
|
+
{
|
|
56
|
+
firstName: "Alice",
|
|
57
|
+
lastName: "Carter",
|
|
58
|
+
email: "alice@example.com",
|
|
59
|
+
company: "ExampleCo",
|
|
60
|
+
position: "Director",
|
|
61
|
+
connectedOn: "2024-01-01",
|
|
62
|
+
url: "https://www.linkedin.com/in/alice",
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
});
|
|
66
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
67
|
+
const body = emit.captures()[0];
|
|
68
|
+
expect(body.tag).toBe("mcp:memory");
|
|
69
|
+
expect(body.level).toBe("info");
|
|
70
|
+
expect(body.line).toContain("memory-archive-write");
|
|
71
|
+
expect(body.line).toContain("result=ok");
|
|
72
|
+
});
|
|
73
|
+
it("emits result=error line on missing accountId (invalid-input)", async () => {
|
|
74
|
+
await expect(memoryArchiveWrite({
|
|
75
|
+
archiveType: "linkedin-connections",
|
|
76
|
+
ownerNodeId: "4:owner:1",
|
|
77
|
+
accountId: "",
|
|
78
|
+
rows: [{}],
|
|
79
|
+
})).rejects.toThrow(/accountId is required/);
|
|
80
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
81
|
+
const body = emit.captures()[0];
|
|
82
|
+
expect(body.level).toBe("error");
|
|
83
|
+
expect(body.line).toContain("memory-archive-write");
|
|
84
|
+
expect(body.line).toContain("result=error");
|
|
85
|
+
expect(body.line).toContain("reason=invalid-input");
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=memory-archive-write-emit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-archive-write-emit.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-archive-write-emit.test.ts"],"names":[],"mappings":"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"}
|
package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-classify-emit.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-classify-emit.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-classify-emit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Task 168 — per-tool emit assertion for memory-classify.
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
3
|
+
import { setupEmitCapture } from "./_helpers/emit-capture.js";
|
|
4
|
+
vi.mock("../memory-ingest-extract.js", () => ({
|
|
5
|
+
extractCache: new Map(),
|
|
6
|
+
memoryIngestExtract: vi.fn(),
|
|
7
|
+
}));
|
|
8
|
+
vi.mock("../../lib/llm-classifier.js", () => ({
|
|
9
|
+
classifyDocument: vi.fn(),
|
|
10
|
+
}));
|
|
11
|
+
import { memoryClassify } from "../memory-classify.js";
|
|
12
|
+
import { extractCache } from "../memory-ingest-extract.js";
|
|
13
|
+
import { classifyDocument } from "../../lib/llm-classifier.js";
|
|
14
|
+
const liveSchemaSource = {
|
|
15
|
+
recognisedLabels: () => new Set(["UserProfile", "Position", "Education"]),
|
|
16
|
+
};
|
|
17
|
+
describe("memory-classify — emit wrapper wired", () => {
|
|
18
|
+
let emit;
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
emit = setupEmitCapture();
|
|
21
|
+
vi.mocked(classifyDocument).mockReset();
|
|
22
|
+
extractCache.clear();
|
|
23
|
+
});
|
|
24
|
+
afterEach(() => emit.restore());
|
|
25
|
+
it("emits result=ok line on happy path", async () => {
|
|
26
|
+
extractCache.set("att-1", { text: "doc body" });
|
|
27
|
+
vi.mocked(classifyDocument).mockResolvedValue({
|
|
28
|
+
sections: [],
|
|
29
|
+
documentEdges: [],
|
|
30
|
+
});
|
|
31
|
+
await memoryClassify({
|
|
32
|
+
accountId: "acct-1",
|
|
33
|
+
attachmentId: "att-1",
|
|
34
|
+
anchorDescription: "subject = UserProfile",
|
|
35
|
+
liveSchemaSource,
|
|
36
|
+
});
|
|
37
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
38
|
+
const body = emit.captures()[0];
|
|
39
|
+
expect(body.tag).toBe("mcp:memory");
|
|
40
|
+
expect(body.level).toBe("info");
|
|
41
|
+
expect(body.line).toContain("memory-classify");
|
|
42
|
+
expect(body.line).toContain("result=ok");
|
|
43
|
+
});
|
|
44
|
+
it("emits result=error line when cached extract is missing", async () => {
|
|
45
|
+
await expect(memoryClassify({
|
|
46
|
+
accountId: "acct-1",
|
|
47
|
+
attachmentId: "missing",
|
|
48
|
+
anchorDescription: "subject = UserProfile",
|
|
49
|
+
liveSchemaSource,
|
|
50
|
+
})).rejects.toThrow(/No cached extract/);
|
|
51
|
+
expect(emit.fetchSpy).toHaveBeenCalledTimes(1);
|
|
52
|
+
const body = emit.captures()[0];
|
|
53
|
+
expect(body.level).toBe("error");
|
|
54
|
+
expect(body.line).toContain("memory-classify");
|
|
55
|
+
expect(body.line).toContain("result=error");
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=memory-classify-emit.test.js.map
|
package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-classify-emit.test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-classify-emit.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-classify-emit.test.ts"],"names":[],"mappings":"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"}
|
package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-emit.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-delete-emit.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-delete-emit.test.ts"],"names":[],"mappings":""}
|