@rubytech/create-maxy-code 0.1.187 → 0.1.188
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/lib/graph-mcp/dist/index.js +4 -3
- package/payload/platform/lib/graph-mcp/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-mcp/src/index.ts +4 -3
- package/payload/platform/package.json +1 -0
- package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
- package/payload/platform/plugins/admin/PLUGIN.md +1 -0
- package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +16 -0
- package/payload/platform/plugins/admin/hooks/mcp-tool-missing.sh +94 -0
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +7 -0
- package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +3 -3
- package/payload/platform/plugins/admin/skills/stream-log-review/references/analysis-patterns.md +11 -7
- package/payload/platform/plugins/docs/references/admin-ui.md +3 -4
- package/payload/platform/plugins/docs/references/deployment.md +1 -1
- package/payload/platform/plugins/docs/references/internals.md +6 -4
- package/payload/platform/plugins/docs/references/plugins-guide.md +2 -2
- package/payload/platform/plugins/graph/.claude-plugin/plugin.json +8 -0
- package/payload/platform/plugins/graph/PLUGIN.md +37 -0
- package/payload/platform/plugins/memory/PLUGIN.md +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +1 -1
- package/payload/platform/plugins/memory/references/graph-primitives.md +36 -27
- package/payload/platform/plugins/obsidian-import/PLUGIN.md +1 -1
- package/payload/platform/scripts/check-canonical-tool-names.mjs +110 -0
- package/payload/platform/scripts/generate-canonical-tool-names.mjs +63 -0
- package/payload/platform/scripts/lib/canonical-tool-names.mjs +88 -0
- package/payload/platform/scripts/setup-account.sh +6 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.d.ts +7 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts +5 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +204 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.js +23 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/index.js +30 -6
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/mcp-tools-probe.d.ts +6 -4
- package/payload/platform/services/claude-session-manager/dist/mcp-tools-probe.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/mcp-tools-probe.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +1 -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 +50 -26
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +40 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +200 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -0
- 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 +50 -34
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js +23 -13
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
- package/payload/platform/templates/specialists/agents/content-producer.md +3 -3
- package/payload/platform/templates/specialists/agents/librarian.md +2 -2
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/platform/templates/specialists/agents/project-manager.md +1 -1
- package/payload/platform/templates/specialists/agents/research-assistant.md +1 -1
- package/payload/server/{chunk-EFJ2EXZK.js → chunk-WWD4TCJJ.js} +0 -16
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/assets/Checkbox-ChWmQ7if.js +1 -0
- package/payload/server/public/assets/admin-BLi_fAKQ.js +216 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DZoOzmjE.js → architectureDiagram-Q4EWVU46-DSqzB21V.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DG3yufCR.js → blockDiagram-DXYQGD6D--otTO_UB.js} +1 -1
- package/payload/server/public/assets/brand-Djtb-tLQ.js +9 -0
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-BBx5wXuZ.js → c4Diagram-AHTNJAMY-CBszqa9W.js} +1 -1
- package/payload/server/public/assets/channel-C-SJYogg.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-DwP7g5ns.js → chunk-336JU56O-ClAJP2KY.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-DXzGdc22.js → chunk-426QAEUC-CgLucS4H.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-1LDRjk0E.js → chunk-4TB4RGXK-BvOX6mSk.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-BHjWhwhn.js → chunk-5FUZZQ4R-uyN4XtrW.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CwPHRVN8.js → chunk-5PVQY5BW-B6xHEzh2.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-7443hrYZ.js → chunk-EDXVE4YY-9objw8tW.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-BTnmmnmX.js → chunk-ENJZ2VHE-pQpbHIJL.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-CPnMJplL.js → chunk-ICPOFSXX-qS23jC3x.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-DCQ5Q4RS.js → chunk-OYMX7WX6-C9YUwGqp.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-BmfZG8e4.js → chunk-U2HBQHQK-D_pYedRJ.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-Da2yJL2u.js → chunk-X2U36JSP-nxf6GHD-.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BdUmMUJ6.js → chunk-YZCP3GAM-DqKT124V.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-abkGirrZ.js → chunk-ZZ45TVLE-CLwvpbvu.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-OBkxl5to.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CkTyus-1.js +1 -0
- package/payload/server/public/assets/clone-VufdPzJ-.js +1 -0
- package/payload/server/public/assets/{dagre-BVVuAEsU.js → dagre-COCXt23n.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-VG2kNj19.js → dagre-KV5264BT-DmuVMrt4.js} +1 -1
- package/payload/server/public/assets/data-TlJbMIfa.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-DRiVy69K.js → diagram-5BDNPKRD-DOiLSgj_.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-DtpiRTYX.js → diagram-G4DWMVQ6-quY6PSZQ.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-Da3t99fY.js → diagram-MMDJMWI5-tN2yiz0C.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-BzQmLTJQ.js → diagram-TYMM5635-CjrRQNQ0.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-D3Ll-GDw.js → erDiagram-SMLLAGMA-CrNNMxkA.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-D17bje6d.js → flowDiagram-DWJPFMVM-CCUsJph7.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BjeQ-Bun.js → ganttDiagram-T4ZO3ILL-18276bri.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-LtX4pvZS.js → gitGraphDiagram-UUTBAWPF-CsLsKMjN.js} +1 -1
- package/payload/server/public/assets/graph-D2Yvni5R.js +1 -0
- package/payload/server/public/assets/graph-labels-uksnCgSC.js +1 -0
- package/payload/server/public/assets/{graphlib-CzwsfZOw.js → graphlib-CmtUzIni.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-DOgH4i52.js → infoDiagram-42DDH7IO-Dny_ZNz3.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-DYqy5BFj.js → ishikawaDiagram-UXIWVN3A-kUhIUQE-.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CsFpIULJ.js → journeyDiagram-VCZTEJTY-DekMvAKB.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-5uZuArw7.js → kanban-definition-6JOO6SKY-st0HNZZo.js} +1 -1
- package/payload/server/public/assets/lib-Ca7uCvl9.js +33 -0
- package/payload/server/public/assets/{line-BY8PmCSW.js → line-BaNk-I7J.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-CJ_9xqwK.js → mermaid-parser.core-CRCHYQ_F.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-CXznBkX7.js → mermaid.core-BaIYEciF.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DZbHBud5.js → mindmap-definition-QFDTVHPH-D4u4KU2v.js} +1 -1
- package/payload/server/public/assets/{page-CfN7nw1J.js → page-DayPduMN.js} +2 -2
- package/payload/server/public/assets/page-QQmuB04w.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-QmOi4DRG.js → pieDiagram-DEJITSTG-BItWEilY.js} +1 -1
- package/payload/server/public/assets/public-Dze4yArS.js +7 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-Cpidq6Xj.js → quadrantDiagram-34T5L4WZ-CeWDBvmH.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-CBqtfbzR.js → requirementDiagram-MS252O5E-CcosjedW.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-4BiY4dV9.js → sankeyDiagram-XADWPNL6-DNGeFpUj.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-DVlL-l2u.js → sequenceDiagram-FGHM5R23-Cqy_deB6.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CAm9dW68.js → stateDiagram-FHFEXIEX-2yoAqEsA.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Dc5siYvu.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-CD-tZc4y.js → timeline-definition-GMOUNBTQ-Dmeghpw1.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-Davcm0TF.js → vennDiagram-DHZGUBPP-TX5D-Zzp.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-40LBYw_Y.js → wardleyDiagram-NUSXRM2D-B7mcpl5E.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DEPT-__v.js → xychartDiagram-5P7HB3ND-DH77CxKf.js} +1 -1
- package/payload/server/public/brand/Archive/favicon.ico +0 -0
- package/payload/server/public/brand/Archive/maxy-black.png +0 -0
- package/payload/server/public/brand/Archive/maxy-horizontal.png +0 -0
- package/payload/server/public/brand/Archive/maxy-monochrome.png +0 -0
- package/payload/server/public/brand/Archive/maxy-square.png +0 -0
- package/payload/server/public/brand/Archive/maxy.png +0 -0
- package/payload/server/public/brand/Archive/star.png +0 -0
- package/payload/server/public/brand/Archive.zip +0 -0
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +312 -793
- package/payload/server/public/assets/ChatInput-CvRaT05l.js +0 -13
- package/payload/server/public/assets/Checkbox-BJKNkUYu.js +0 -1
- package/payload/server/public/assets/admin-BNy4N2d6.js +0 -217
- package/payload/server/public/assets/channel-DdtUtt5g.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CKk2DFZe.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E--YvfDQCh.js +0 -1
- package/payload/server/public/assets/clone-Cw6UfPGM.js +0 -1
- package/payload/server/public/assets/data-uBpwaldK.js +0 -1
- package/payload/server/public/assets/graph-labels-Cn9jAE6I.js +0 -1
- package/payload/server/public/assets/graph-tvTPvBaz.js +0 -1
- package/payload/server/public/assets/lib-p4ylk2XS.js +0 -29
- package/payload/server/public/assets/page-B3VYaBcf.js +0 -1
- package/payload/server/public/assets/public-Bbew78md.js +0 -7
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-B2EzXi50.js +0 -1
- /package/payload/server/public/assets/{ChatInput-DzacFNMk.css → brand-DzacFNMk.css} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: graph
|
|
3
|
+
tools:
|
|
4
|
+
- name: maxy-graph-read_neo4j_cypher
|
|
5
|
+
publicAllowlist: false
|
|
6
|
+
adminAllowlist: true
|
|
7
|
+
- name: maxy-graph-get_neo4j_schema
|
|
8
|
+
publicAllowlist: false
|
|
9
|
+
adminAllowlist: true
|
|
10
|
+
- name: maxy-graph-write_neo4j_cypher
|
|
11
|
+
publicAllowlist: false
|
|
12
|
+
adminAllowlist: false
|
|
13
|
+
mcp:
|
|
14
|
+
command: node
|
|
15
|
+
args:
|
|
16
|
+
- ${PLATFORM_ROOT}/lib/graph-mcp/dist/index.js
|
|
17
|
+
env:
|
|
18
|
+
LOG_DIR: ${LOG_DIR}
|
|
19
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
20
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
21
|
+
SESSION_ID: ${SESSION_ID}
|
|
22
|
+
NEO4J_URI: ${NEO4J_URI}
|
|
23
|
+
NEO4J_PASSWORD: ${NEO4J_PASSWORD}
|
|
24
|
+
description: "Raw Neo4j Cypher proxy. Wraps the upstream `mcp-neo4j-cypher` server (spawned under uvx by `platform/lib/graph-mcp`) under the stable `maxy-graph` namespace, so its tools register as `maxy-graph-read_neo4j_cypher`, `maxy-graph-get_neo4j_schema`, and `maxy-graph-write_neo4j_cypher`. The read and schema tools are admin-allowlisted for schema checks and read-only queries; the write tool is specialist-only (database-operator / librarian execute operator-confirmed `mergeCypher` templates through it, never hand-authored Cypher). The shim validates write Cypher against the live schema, stamps provenance, and rejects unknown labels/edges. Account isolation is per-brand Neo4j; the shim adds no query-layer tenant filter."
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# graph
|
|
28
|
+
|
|
29
|
+
Cypher proxy plugin. The server is `platform/lib/graph-mcp`, which adopts the upstream
|
|
30
|
+
Python `mcp-neo4j-cypher` server per brand and proxies its JSON-RPC stdio under the
|
|
31
|
+
`maxy-graph` namespace. It is registered through the installed-plugin channel like every
|
|
32
|
+
other platform MCP, so its tools surface as `mcp__plugin_graph_graph__maxy-graph-*`.
|
|
33
|
+
|
|
34
|
+
Write Cypher is intercepted (not forwarded) so the shim can validate tokens against the
|
|
35
|
+
live schema cache, stamp `createdBy` provenance, and roll back orphan-producing writes.
|
|
36
|
+
Read Cypher and schema introspection forward to upstream with an envelope-warning probe
|
|
37
|
+
that stitches Neo4j `gql_status` codes back into the response.
|
package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* Per-row dispatch (the skill executes; this tool emits the cypher):
|
|
15
15
|
* mention → (:Section)-[:MENTIONS {contentHash}]->(:Person|:Organization)
|
|
16
16
|
* task → (:Task)-[:REFERENCES {contentHash}]->(:Section)
|
|
17
|
-
* (the skill calls
|
|
17
|
+
* (the skill calls mcp__plugin_work_work__work-create first,
|
|
18
18
|
* then this REFERENCES edge via raw cypher.)
|
|
19
19
|
* preference → MERGE (p:Preference {accountId, contentHash})
|
|
20
20
|
* then (p)-[:OBSERVED_IN]->(chunk)
|
package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* Per-row dispatch (the skill executes; this tool emits the cypher):
|
|
15
15
|
* mention → (:Section)-[:MENTIONS {contentHash}]->(:Person|:Organization)
|
|
16
16
|
* task → (:Task)-[:REFERENCES {contentHash}]->(:Section)
|
|
17
|
-
* (the skill calls
|
|
17
|
+
* (the skill calls mcp__plugin_work_work__work-create first,
|
|
18
18
|
* then this REFERENCES edge via raw cypher.)
|
|
19
19
|
* preference → MERGE (p:Preference {accountId, contentHash})
|
|
20
20
|
* then (p)-[:OBSERVED_IN]->(chunk)
|
|
@@ -40,31 +40,40 @@ token-limit discipline the upstream server enforces.
|
|
|
40
40
|
|
|
41
41
|
## When the memory tools are absent
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
`
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
The maxy MCP tool names are bound to the live registry (Task 502): the
|
|
44
|
+
canonical long name `mcp__plugin_memory_memory__<tool>` is generated from the
|
|
45
|
+
memory plugin's manifest, a build gate fails when any instruction names a tool
|
|
46
|
+
the registry does not serve, and a PostToolUse hook turns a missing-tool call
|
|
47
|
+
into a fixed envelope. So a missing memory tool is one of two distinct states,
|
|
48
|
+
not the single "failed to start" the old contract assumed:
|
|
49
|
+
|
|
50
|
+
- **Server dead.** None of the `mcp__plugin_memory_memory__*` tools appear in
|
|
51
|
+
your tool list at all. The per-account memory server did not start; the
|
|
52
|
+
platform's `[mcp-init-error] server=memory` line in the per-conversation
|
|
53
|
+
stream log names it.
|
|
54
|
+
- **Name not registered.** The server is up and other
|
|
55
|
+
`mcp__plugin_memory_memory__*` tools are present, but a specific call returns
|
|
56
|
+
`No such tool available`. The `mcp-tool-missing` hook has already logged
|
|
57
|
+
`[mcp-tool-missing] server=memory tool=<tool>` and returned the deterministic
|
|
58
|
+
envelope you are reading.
|
|
59
|
+
|
|
60
|
+
In either state, reply once with exactly:
|
|
61
|
+
|
|
62
|
+
> The memory MCP server is unavailable on this device. Run the admin
|
|
51
63
|
> system-status check to diagnose — do not retry by other routes.
|
|
52
64
|
|
|
53
|
-
Then stop. Do not search for a similarly-named tool via `ToolSearch`, do
|
|
54
|
-
|
|
55
|
-
write goes through the schema-aware memory tools), do not
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
exists so the operator knows the session cannot proceed without an
|
|
60
|
-
operator-side fix (the loud-fail contract applies equally
|
|
61
|
-
to graph and memory tool initialisation).
|
|
65
|
+
Then stop. Do not search for a similarly-named tool via `ToolSearch`, do not
|
|
66
|
+
improvise via `mcp__plugin_graph_graph__maxy-graph-read_neo4j_cypher` (it is
|
|
67
|
+
read-only — every write goes through the schema-aware memory tools), do not
|
|
68
|
+
paraphrase, do not describe the server as "warming up". The reply exists so the
|
|
69
|
+
operator knows the session cannot proceed without an operator-side fix (the
|
|
70
|
+
loud-fail contract applies equally to graph and memory tool initialisation).
|
|
62
71
|
|
|
63
72
|
## Mutation intents
|
|
64
73
|
|
|
65
74
|
The graph tools above are read-only. Every write intent has a schema-aware
|
|
66
75
|
tool that already exists — match the user's prose to a tool in this table
|
|
67
|
-
rather than improvising. `
|
|
76
|
+
rather than improvising. `mcp__plugin_admin_admin__admin-remove` is in your initial
|
|
68
77
|
tool list; the other tools below are deferred (they do not appear until
|
|
69
78
|
you invoke `ToolSearch` by the exact name you pick from the table).
|
|
70
79
|
Do not use `ToolSearch` to *discover* the tool by keyword — identify it
|
|
@@ -78,14 +87,14 @@ graph as a single action.
|
|
|
78
87
|
|
|
79
88
|
| User intent | Tool | When to pick this, not the next row |
|
|
80
89
|
|---|---|---|
|
|
81
|
-
| "remove admin X", "take away their admin access", "revoke admin" | `
|
|
82
|
-
| "delete this specific node", "remove this entry by its id", "get rid of node X", "remove orphans", "prune", "clean up" | `
|
|
83
|
-
| "undo that delete", "I deleted X by mistake, bring it back", "restore the contact I just trashed" | `
|
|
84
|
-
| "empty the trash", "purge old soft-deletes", "what's been sitting in trash and ready to clear" | `
|
|
85
|
-
| "scrub this conversation's memory", "remove this claim the bot picked up", "forget what we said in that thread" | `
|
|
86
|
-
| "update a property", "fix a typo in a node", "change the role field on X", "null this poisonous string" | `
|
|
87
|
-
| "update X by name, search didn't return it", "wire this Org but search came back empty", "I know it exists but I don't have the elementId" | `
|
|
88
|
-
| "don't surface these substrings in future memory results", "watch for this string" | `
|
|
90
|
+
| "remove admin X", "take away their admin access", "revoke admin" | `mcp__plugin_admin_admin__admin-remove` | Device-level admin offboarding — detaches the `(AdminUser)-[:ADMIN_OF]->(LocalBusiness)` edge and updates `platform/config/users.json`. Not for scrubbing personal data — use the GDPR contact-erase tools for that. |
|
|
91
|
+
| "delete this specific node", "remove this entry by its id", "get rid of node X", "remove orphans", "prune", "clean up" | `mcp__plugin_memory_memory__memory-delete` | Soft-deletes a single node by `elementId` (adds `:Trashed`, preserves relationships, snapshots unique keys, invisible to `memory-search` and any `notTrashed`-filtered read). For KnowledgeDocument, cascades to Sections and Chunks. Enumerate candidates first with a Cypher read, confirm with the user, then delete each by `elementId`. There is no bulk "delete everything without relationships" tool. Per the write doctrine (`.docs/neo4j.md` § Write doctrine), **new** orphans should be impossible — every writer now rejects zero-edge calls at the MCP tool-surface. Existing orphans from legacy data are legitimate backfill candidates but are not produced by any live writer; if you see a freshly-created orphan, it is a bug in a writer that bypassed `writeNodeWithEdges`, not expected state. |
|
|
92
|
+
| "undo that delete", "I deleted X by mistake, bring it back", "restore the contact I just trashed" | `mcp__plugin_memory_memory__memory-restore` | Removes `:Trashed`, restores snapshotted unique-key properties. Fails loudly when an active node already holds the unique slot (e.g. a fresh `LocalBusiness` was created while the old one was in trash) — the error names the conflicting `elementId` so you can ask the user how to resolve. |
|
|
93
|
+
| "empty the trash", "purge old soft-deletes", "what's been sitting in trash and ready to clear" | `mcp__plugin_memory_memory__memory-empty-trash` | Hard-deletes trashed nodes whose `trashedAt` is older than `graceDays` (default 30); `dryRun=true` lists candidates without mutating. Use `dryRun` first, show the list to the user, then run for real. For KnowledgeDocument candidates, the on-disk attachment directory is removed too. |
|
|
94
|
+
| "scrub this conversation's memory", "remove this claim the bot picked up", "forget what we said in that thread" | `mcp__plugin_memory_memory__conversation-memory-expunge` | Removes deny-listable content from `:Memory` nodes scoped to one conversation. Requires an explicit pattern and sessionId. Not for deleting individual nodes — use `memory-delete`. |
|
|
95
|
+
| "update a property", "fix a typo in a node", "change the role field on X", "null this poisonous string" | `mcp__plugin_memory_memory__memory-update` | Targeted property edit on an existing node, schema-validated. Use to null individual string properties matching a deny-list entry once you've identified the offender via a Cypher read. Not for creating new nodes — use `memory-write`. |
|
|
96
|
+
| "update X by name, search didn't return it", "wire this Org but search came back empty", "I know it exists but I don't have the elementId" | `mcp__plugin_memory_memory__memory-update-by-name` | Repair surface for the case where `memory-search` cannot return a row you know exists by name. Resolves the unique `(label, name, accountId)` tuple, then delegates to `memory-update`. Rejects loudly on zero or ambiguous matches (the rejection lists candidate elementIds so you can pick one). Trashed nodes excluded. Use this only after `memory-search` failed — for normal updates, get the elementId from search and call `memory-update` directly. |
|
|
97
|
+
| "don't surface these substrings in future memory results", "watch for this string" | `mcp__plugin_memory_memory__graph-prune-denylist-add` | Records a substring as operator-curated signal. Nothing auto-applies it — when a subsequent memory-search or cypher read surfaces a match, use `memory-update` or `memory-delete` with discretion to scrub it. |
|
|
89
98
|
|
|
90
99
|
**Never run `cypher-shell` via `Bash` to work around the read-only tool.**
|
|
91
100
|
The admin session's `Bash` surface has no path to the per-brand Neo4j
|
|
@@ -107,7 +116,7 @@ MATCH (a:AdminUser) WHERE NOT (a)--() RETURN elementId(a), a.userId, a.createdAt
|
|
|
107
116
|
```
|
|
108
117
|
|
|
109
118
|
Show the list to the user. For each confirmed entry, call
|
|
110
|
-
`
|
|
119
|
+
`mcp__plugin_memory_memory__memory-delete` with the `elementId`. Do not batch-delete
|
|
111
120
|
by pattern — on 2026-04-20 an autonomous orphan-delete rule wiped 19
|
|
112
121
|
nodes in one call, with no property recovery possible. Structural mass-
|
|
113
122
|
deletion by shape is banned; discretion per node is the only sanctioned
|
|
@@ -18,7 +18,7 @@ The admin agent delegates to `specialists:database-operator` when the operator d
|
|
|
18
18
|
|
|
19
19
|
## How parsing happens
|
|
20
20
|
|
|
21
|
-
The skill does not parse markdown. Vault traversal, frontmatter YAML, wikilink regex, tag scanning, daily-notes detection, and attachment resolution all happen server-side inside `
|
|
21
|
+
The skill does not parse markdown. Vault traversal, frontmatter YAML, wikilink regex, tag scanning, daily-notes detection, and attachment resolution all happen server-side inside `mcp__plugin_memory_memory__obsidian-vault-import` (memory plugin). The skill is the operator-facing conversation surface only: confirm owner → select filters → invoke the tool with `mode='dry-run'` → present ambiguities → invoke with `mode='commit'` and the operator's resolutions.
|
|
22
22
|
|
|
23
23
|
## Intra-plugin growth
|
|
24
24
|
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Strong build gate for canonical maxy MCP tool names (Task 502).
|
|
3
|
+
//
|
|
4
|
+
// Two checks, both must pass:
|
|
5
|
+
// 1. Regenerate-and-diff: the committed generated artifact
|
|
6
|
+
// (canonical-tool-names.generated.ts) must byte-match a fresh generation
|
|
7
|
+
// from platform/plugins/*/PLUGIN.md. A stale artifact fails the build —
|
|
8
|
+
// this is what stops a PLUGIN.md tool add/remove from drifting away from
|
|
9
|
+
// the names instructions are bound to.
|
|
10
|
+
// 2. Instruction-name validation: every `mcp__...` tool name in an
|
|
11
|
+
// instruction file (specialist templates, agent prompts, plugin
|
|
12
|
+
// references/skills, PLUGIN.md prose) that targets a MAXY plugin must be
|
|
13
|
+
// the canonical long prefix AND must exist in the live set. A short-prefix
|
|
14
|
+
// maxy name (mcp__<plugin>__<tool>) fails — it must be long. An unknown
|
|
15
|
+
// long-prefix maxy name fails — typo or stale. Non-maxy bridge namespaces
|
|
16
|
+
// (playwright, etc.) are ignored: their tool names are upstream-owned.
|
|
17
|
+
|
|
18
|
+
import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs'
|
|
19
|
+
import { join } from 'node:path'
|
|
20
|
+
import { computeCanonicalToolNames, MAXY_CODE_ROOT } from './lib/canonical-tool-names.mjs'
|
|
21
|
+
import { renderArtifact, renderPluginsList } from './generate-canonical-tool-names.mjs'
|
|
22
|
+
|
|
23
|
+
const GENERATED = join(
|
|
24
|
+
MAXY_CODE_ROOT, 'platform', 'services', 'claude-session-manager', 'src',
|
|
25
|
+
'canonical-tool-names.generated.ts',
|
|
26
|
+
)
|
|
27
|
+
const PLUGINS_TXT = join(
|
|
28
|
+
MAXY_CODE_ROOT, 'platform', 'plugins', 'admin', 'hooks', 'lib',
|
|
29
|
+
'maxy-mcp-plugins.txt',
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const SCAN_DIRS = [
|
|
33
|
+
join(MAXY_CODE_ROOT, 'platform', 'templates', 'specialists', 'agents'),
|
|
34
|
+
join(MAXY_CODE_ROOT, 'platform', 'plugins'),
|
|
35
|
+
]
|
|
36
|
+
const SCAN_EXT = new Set(['.md'])
|
|
37
|
+
const SKIP_DIRS = new Set(['node_modules', 'dist', 'build', 'payload', '__tests__'])
|
|
38
|
+
// mcp__<seg>__<tool> — seg may itself contain `_` (long prefix plugin_a_b).
|
|
39
|
+
const TOOL_RE = /mcp__([A-Za-z0-9-]+(?:_[A-Za-z0-9-]+)*)__([A-Za-z0-9_-]+)/g
|
|
40
|
+
|
|
41
|
+
function* walk(dir) {
|
|
42
|
+
let entries
|
|
43
|
+
try { entries = readdirSync(dir) } catch { return }
|
|
44
|
+
for (const e of entries.sort()) {
|
|
45
|
+
if (e.startsWith('.') || SKIP_DIRS.has(e)) continue
|
|
46
|
+
const p = join(dir, e)
|
|
47
|
+
let st
|
|
48
|
+
try { st = statSync(p) } catch { continue }
|
|
49
|
+
if (st.isDirectory()) { yield* walk(p); continue }
|
|
50
|
+
const ext = e.includes('.') ? '.' + e.split('.').pop() : ''
|
|
51
|
+
if (SCAN_EXT.has(ext)) yield p
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function main() {
|
|
56
|
+
const { plugins, names } = computeCanonicalToolNames()
|
|
57
|
+
const maxyPlugins = new Set(plugins)
|
|
58
|
+
const canonical = new Set(names)
|
|
59
|
+
|
|
60
|
+
// Check 1 — regenerate-and-diff both generated outputs.
|
|
61
|
+
let driftError = null
|
|
62
|
+
const staleOutputs = []
|
|
63
|
+
if ((existsSync(GENERATED) ? readFileSync(GENERATED, 'utf8') : '') !== renderArtifact()) staleOutputs.push(GENERATED)
|
|
64
|
+
if ((existsSync(PLUGINS_TXT) ? readFileSync(PLUGINS_TXT, 'utf8') : '') !== renderPluginsList()) staleOutputs.push(PLUGINS_TXT)
|
|
65
|
+
if (staleOutputs.length > 0) {
|
|
66
|
+
driftError =
|
|
67
|
+
`[gate] canonical-tool-names: GENERATED ARTIFACT STALE.\n` +
|
|
68
|
+
staleOutputs.map((p) => ` ${p}`).join('\n') + '\n' +
|
|
69
|
+
` Regenerate: cd platform && npm run gen:canonical-tools`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check 2 — instruction-name validation.
|
|
73
|
+
const violations = []
|
|
74
|
+
for (const root of SCAN_DIRS) {
|
|
75
|
+
for (const file of walk(root)) {
|
|
76
|
+
const text = readFileSync(file, 'utf8')
|
|
77
|
+
for (const m of text.matchAll(TOOL_RE)) {
|
|
78
|
+
const seg = m[1]
|
|
79
|
+
const full = m[0]
|
|
80
|
+
// Skip glob patterns in prose (`mcp__plugin_x_x__*`): the `*` is not a
|
|
81
|
+
// tool char so the match captured a partial name, not a real reference.
|
|
82
|
+
if (text[m.index + full.length] === '*') continue
|
|
83
|
+
if (seg.startsWith('plugin_')) {
|
|
84
|
+
// Long prefix mcp__plugin_<plugin>_<server>__<tool>.
|
|
85
|
+
const inner = seg.slice('plugin_'.length)
|
|
86
|
+
// plugin === server for maxy; the long prefix is `<plugin>_<plugin>`.
|
|
87
|
+
const plugin = [...maxyPlugins].find((p) => inner === `${p}_${p}`)
|
|
88
|
+
if (!plugin) continue // non-maxy bridge (playwright) — upstream-owned.
|
|
89
|
+
if (!canonical.has(full)) {
|
|
90
|
+
violations.push({ file, name: full, why: 'unknown maxy tool (typo or stale)' })
|
|
91
|
+
}
|
|
92
|
+
} else if (maxyPlugins.has(seg)) {
|
|
93
|
+
// Short prefix mcp__<maxyplugin>__<tool> — must be long now.
|
|
94
|
+
violations.push({ file, name: full, why: `short prefix for maxy plugin '${seg}' — use canonical long name` })
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const failed = driftError || violations.length > 0
|
|
101
|
+
if (driftError) console.error(driftError)
|
|
102
|
+
if (violations.length > 0) {
|
|
103
|
+
console.error('[gate] canonical-tool-names: instruction files name tools outside the live set:')
|
|
104
|
+
for (const v of violations) console.error(` ${v.file.replace(MAXY_CODE_ROOT + '/', '')}: ${v.name} — ${v.why}`)
|
|
105
|
+
}
|
|
106
|
+
if (failed) process.exit(1)
|
|
107
|
+
console.log(`[gate] check-canonical-tool-names: PASS (${names.length} canonical names, scanned instruction files)`)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
main()
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Generator: writes the committed canonical maxy MCP tool-name artifact from
|
|
3
|
+
// every platform/plugins/<dir>/PLUGIN.md. Run via `npm run gen:canonical-tools`
|
|
4
|
+
// (platform). The strong build gate (check-canonical-tool-names.mjs) regenerates
|
|
5
|
+
// in-memory and fails the build if the committed artifact has drifted.
|
|
6
|
+
import { writeFileSync } from 'node:fs'
|
|
7
|
+
import { join } from 'node:path'
|
|
8
|
+
import { computeCanonicalToolNames, MAXY_CODE_ROOT } from './lib/canonical-tool-names.mjs'
|
|
9
|
+
|
|
10
|
+
const OUT = join(
|
|
11
|
+
MAXY_CODE_ROOT, 'platform', 'services', 'claude-session-manager', 'src',
|
|
12
|
+
'canonical-tool-names.generated.ts',
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
// Plain newline-delimited maxy plugin list the deterministic missing-tool hook
|
|
16
|
+
// (bash) reads to tell a maxy server (mcp__plugin_<p>_<p>__) from a third-party
|
|
17
|
+
// bridge that shares the same long-prefix shape (Playwright etc.).
|
|
18
|
+
const PLUGINS_TXT = join(
|
|
19
|
+
MAXY_CODE_ROOT, 'platform', 'plugins', 'admin', 'hooks', 'lib',
|
|
20
|
+
'maxy-mcp-plugins.txt',
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
export function renderPluginsList() {
|
|
24
|
+
const { plugins } = computeCanonicalToolNames()
|
|
25
|
+
return plugins.join('\n') + '\n'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function renderArtifact() {
|
|
29
|
+
const { plugins, names } = computeCanonicalToolNames()
|
|
30
|
+
const body = [
|
|
31
|
+
'// GENERATED — do not edit by hand.',
|
|
32
|
+
'// Source: platform/plugins/*/PLUGIN.md (tools: + hidden: blocks).',
|
|
33
|
+
'// Regenerate: cd platform && npm run gen:canonical-tools',
|
|
34
|
+
'// Gate: platform/scripts/check-canonical-tool-names.mjs fails the build on drift.',
|
|
35
|
+
'//',
|
|
36
|
+
'// Canonical long-prefix names every maxy MCP tool is served under by the',
|
|
37
|
+
'// installed-plugin channel: mcp__plugin_<dir>_<dir>__<tool>.',
|
|
38
|
+
'',
|
|
39
|
+
'/** Directory basenames of maxy platform plugins that expose a tool surface. */',
|
|
40
|
+
'export const MAXY_MCP_PLUGINS: readonly string[] = [',
|
|
41
|
+
...plugins.map((p) => ` ${JSON.stringify(p)},`),
|
|
42
|
+
']',
|
|
43
|
+
'',
|
|
44
|
+
'/** Every canonical maxy MCP tool name (long prefix), sorted. */',
|
|
45
|
+
'export const CANONICAL_MAXY_TOOL_NAMES: readonly string[] = [',
|
|
46
|
+
...names.map((n) => ` ${JSON.stringify(n)},`),
|
|
47
|
+
']',
|
|
48
|
+
'',
|
|
49
|
+
].join('\n')
|
|
50
|
+
return body
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function main() {
|
|
54
|
+
writeFileSync(OUT, renderArtifact(), 'utf8')
|
|
55
|
+
writeFileSync(PLUGINS_TXT, renderPluginsList(), 'utf8')
|
|
56
|
+
const { plugins, names } = computeCanonicalToolNames()
|
|
57
|
+
console.log(`[gen] canonical-tool-names: ${plugins.length} plugins, ${names.length} tools -> ${OUT}`)
|
|
58
|
+
console.log(`[gen] maxy-mcp-plugins.txt -> ${PLUGINS_TXT}`)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { OUT, PLUGINS_TXT }
|
|
62
|
+
|
|
63
|
+
if (import.meta.url === `file://${process.argv[1]}`) main()
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Shared source of truth for canonical (long-prefix) maxy MCP tool names.
|
|
2
|
+
//
|
|
3
|
+
// Claude Code's installed-plugin channel serves every plugin MCP tool under
|
|
4
|
+
// the long prefix `mcp__plugin_<plugin>_<server>__<tool>`. For every platform
|
|
5
|
+
// plugin the marketplace name, the MCP server key, and the directory basename
|
|
6
|
+
// are identical, so the canonical name is deterministically
|
|
7
|
+
// `mcp__plugin_<dir>_<dir>__<tool>`. This module is the single place that
|
|
8
|
+
// derives those names from each `platform/plugins/<dir>/PLUGIN.md`; the
|
|
9
|
+
// generator writes the committed artifact from it, the build gate diffs
|
|
10
|
+
// against it, and the session-manager cross-checks its tool surface against it.
|
|
11
|
+
//
|
|
12
|
+
// Scope: platform plugins only. Third-party bridge servers (playwright, etc.)
|
|
13
|
+
// also render under `mcp__plugin_*` but their tool names are upstream-owned and
|
|
14
|
+
// are NOT part of the maxy canonical set — the drift check treats a
|
|
15
|
+
// `mcp__plugin_*` name whose plugin segment is not a maxy plugin as a bridge
|
|
16
|
+
// pass, never validating it against this set.
|
|
17
|
+
|
|
18
|
+
import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs'
|
|
19
|
+
import { dirname, join, resolve } from 'node:path'
|
|
20
|
+
import { fileURLToPath } from 'node:url'
|
|
21
|
+
|
|
22
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
23
|
+
export const MAXY_CODE_ROOT = resolve(__dirname, '..', '..', '..')
|
|
24
|
+
const PLATFORM_PLUGINS_ROOT = join(MAXY_CODE_ROOT, 'platform', 'plugins')
|
|
25
|
+
|
|
26
|
+
/** Long-prefix canonical name for a platform plugin tool. plugin === server
|
|
27
|
+
* === directory basename for every platform MCP plugin. */
|
|
28
|
+
export function canonicalToolName(plugin, tool) {
|
|
29
|
+
return `mcp__plugin_${plugin}_${plugin}__${tool}`
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function extractFrontmatter(md) {
|
|
33
|
+
if (!md.startsWith('---')) return null
|
|
34
|
+
const end = md.indexOf('\n---', 3)
|
|
35
|
+
if (end < 0) return null
|
|
36
|
+
return md.slice(3, end)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Collect `- name: <x>` entries under a bare `tools:` block and `- <x>` entries
|
|
40
|
+
// under a bare `hidden:` block. Both contribute names a specialist may list in
|
|
41
|
+
// its `tools:` frontmatter, so both belong to the live set.
|
|
42
|
+
function parseToolNames(frontmatter) {
|
|
43
|
+
const lines = frontmatter.split('\n')
|
|
44
|
+
const names = []
|
|
45
|
+
let mode = null // 'tools' | 'hidden' | null
|
|
46
|
+
for (const line of lines) {
|
|
47
|
+
if (/^tools\s*:/.test(line)) {
|
|
48
|
+
mode = /^tools\s*:\s*$/.test(line) ? 'tools' : null
|
|
49
|
+
continue
|
|
50
|
+
}
|
|
51
|
+
if (/^hidden\s*:/.test(line)) {
|
|
52
|
+
mode = /^hidden\s*:\s*$/.test(line) ? 'hidden' : null
|
|
53
|
+
continue
|
|
54
|
+
}
|
|
55
|
+
if (/^\S/.test(line) && line.trim() !== '') { mode = null; continue }
|
|
56
|
+
if (mode === 'tools') {
|
|
57
|
+
const m = line.match(/^\s+-\s+name:\s*(.+?)\s*$/)
|
|
58
|
+
if (m) names.push(m[1])
|
|
59
|
+
} else if (mode === 'hidden') {
|
|
60
|
+
const m = line.match(/^\s+-\s+(.+?)\s*$/)
|
|
61
|
+
if (m) names.push(m[1])
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return names
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Returns { plugins, names } — `plugins` is the sorted list of maxy plugin
|
|
68
|
+
* directory basenames that declare a tool surface; `names` is the sorted list
|
|
69
|
+
* of canonical long-prefix tool names across all of them. */
|
|
70
|
+
export function computeCanonicalToolNames(pluginsRoot = PLATFORM_PLUGINS_ROOT) {
|
|
71
|
+
const plugins = []
|
|
72
|
+
const names = new Set()
|
|
73
|
+
if (!existsSync(pluginsRoot)) return { plugins, names: [] }
|
|
74
|
+
for (const entry of readdirSync(pluginsRoot).sort()) {
|
|
75
|
+
if (entry.startsWith('.')) continue
|
|
76
|
+
const dir = join(pluginsRoot, entry)
|
|
77
|
+
try { if (!statSync(dir).isDirectory()) continue } catch { continue }
|
|
78
|
+
const manifest = join(dir, 'PLUGIN.md')
|
|
79
|
+
if (!existsSync(manifest)) continue
|
|
80
|
+
const fm = extractFrontmatter(readFileSync(manifest, 'utf-8'))
|
|
81
|
+
if (fm === null) continue
|
|
82
|
+
const toolNames = parseToolNames(fm)
|
|
83
|
+
if (toolNames.length === 0) continue
|
|
84
|
+
plugins.push(entry)
|
|
85
|
+
for (const t of toolNames) names.add(canonicalToolName(entry, t))
|
|
86
|
+
}
|
|
87
|
+
return { plugins: plugins.sort(), names: Array.from(names).sort() }
|
|
88
|
+
}
|
|
@@ -127,6 +127,12 @@ cat > "$ACCOUNT_SETTINGS" << SETTINGS_EOF
|
|
|
127
127
|
{ "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
|
|
128
128
|
]
|
|
129
129
|
},
|
|
130
|
+
{
|
|
131
|
+
"matcher": "mcp__.*",
|
|
132
|
+
"hooks": [
|
|
133
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/mcp-tool-missing.sh" }
|
|
134
|
+
]
|
|
135
|
+
},
|
|
130
136
|
{
|
|
131
137
|
"matcher": "Write",
|
|
132
138
|
"hooks": [
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Long-prefix name served by the installed-plugin channel (admin + specialist
|
|
2
|
+
* spawns). plugin === server === plugin directory basename. */
|
|
3
|
+
export declare function canonicalToolName(plugin: string, tool: string): string;
|
|
4
|
+
/** Short-prefix name served by the per-spawn `--mcp-config` channel, retained
|
|
5
|
+
* only for public-agent spawns. */
|
|
6
|
+
export declare function qualifyShortToolName(plugin: string, tool: string): string;
|
|
7
|
+
//# sourceMappingURL=canonical-tool-names.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-tool-names.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.ts"],"names":[],"mappings":"AAaA;gEACgE;AAChE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;oCACoC;AACpC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzE"}
|
package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Directory basenames of maxy platform plugins that expose a tool surface. */
|
|
2
|
+
export declare const MAXY_MCP_PLUGINS: readonly string[];
|
|
3
|
+
/** Every canonical maxy MCP tool name (long prefix), sorted. */
|
|
4
|
+
export declare const CANONICAL_MAXY_TOOL_NAMES: readonly string[];
|
|
5
|
+
//# sourceMappingURL=canonical-tool-names.generated.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAiB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EA+KtD,CAAA"}
|