@rubytech/create-maxy-code 0.1.35 → 0.1.37

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.
Files changed (125) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/PLUGIN.md +12 -0
  3. package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +109 -0
  4. package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +114 -0
  5. package/payload/platform/plugins/admin/skills/unzip-attachment/SKILL.md +1 -1
  6. package/payload/platform/plugins/contacts/PLUGIN.md +11 -0
  7. package/payload/platform/plugins/docs/references/internals.md +10 -0
  8. package/payload/platform/plugins/docs/references/platform.md +11 -4
  9. package/payload/platform/plugins/email/PLUGIN.md +11 -0
  10. package/payload/platform/plugins/linkedin-import/.claude-plugin/plugin.json +1 -1
  11. package/payload/platform/plugins/linkedin-import/PLUGIN.md +5 -5
  12. package/payload/platform/plugins/linkedin-import/skills/linkedin-import/SKILL.md +3 -1
  13. package/payload/platform/plugins/linkedin-import/skills/linkedin-import/references/connections.md +2 -2
  14. package/payload/platform/plugins/memory/PLUGIN.md +11 -0
  15. package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +2 -0
  16. package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +2 -0
  17. package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +6 -4
  18. package/payload/platform/plugins/outlook/PLUGIN.md +11 -0
  19. package/payload/platform/plugins/replicate/PLUGIN.md +11 -0
  20. package/payload/platform/plugins/scheduling/PLUGIN.md +11 -0
  21. package/payload/platform/plugins/tasks/PLUGIN.md +11 -0
  22. package/payload/platform/plugins/telegram/PLUGIN.md +11 -0
  23. package/payload/platform/plugins/waitlist/PLUGIN.md +11 -0
  24. package/payload/platform/plugins/whatsapp/PLUGIN.md +11 -0
  25. package/payload/platform/plugins/workflows/PLUGIN.md +11 -0
  26. package/payload/platform/scripts/seed-neo4j.sh +14 -0
  27. package/payload/platform/scripts/verify-skill-tool-surface.sh +5 -3
  28. package/payload/platform/services/claude-session-manager/dist/config.d.ts +0 -5
  29. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  30. package/payload/platform/services/claude-session-manager/dist/config.js +16 -6
  31. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  32. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +0 -5
  33. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  34. package/payload/platform/services/claude-session-manager/dist/http-server.js +109 -139
  35. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  36. package/payload/platform/services/claude-session-manager/dist/index.js +63 -4
  37. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  38. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +47 -61
  39. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  40. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +191 -131
  41. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  42. package/payload/platform/services/claude-session-manager/dist/session-store.d.ts +43 -37
  43. package/payload/platform/services/claude-session-manager/dist/session-store.d.ts.map +1 -1
  44. package/payload/platform/services/claude-session-manager/dist/session-store.js +72 -61
  45. package/payload/platform/services/claude-session-manager/dist/session-store.js.map +1 -1
  46. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +34 -4
  47. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -1
  48. package/payload/platform/services/claude-session-manager/dist/tool-surface.js +125 -27
  49. package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
  50. package/payload/platform/templates/agents/admin/IDENTITY.md +9 -18
  51. package/payload/platform/templates/specialists/agents/database-operator.md +27 -70
  52. package/payload/platform/templates/specialists/agents/librarian.md +55 -0
  53. package/payload/server/public/assets/{Checkbox-8mOR8-gV.js → Checkbox-DAki3vDW.js} +1 -1
  54. package/payload/server/public/assets/{admin-CK4V-B9A.js → admin-CyAZtsYZ.js} +1 -1
  55. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-2DgPtOot.js → architectureDiagram-Q4EWVU46-C-hla3Ip.js} +1 -1
  56. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-BilycXVZ.js → blockDiagram-DXYQGD6D-CbzjtNs3.js} +1 -1
  57. package/payload/server/public/assets/{brand-1_DraUIv.css → brand-Cun0PBrA.css} +1 -1
  58. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CGiIFO5U.js → c4Diagram-AHTNJAMY-B87UblA0.js} +1 -1
  59. package/payload/server/public/assets/channel-CTNo72W7.js +1 -0
  60. package/payload/server/public/assets/{chunk-336JU56O-DxTg1h50.js → chunk-336JU56O-2a2pVlSg.js} +2 -2
  61. package/payload/server/public/assets/{chunk-426QAEUC-DkGPjs0P.js → chunk-426QAEUC-j9NOD8_a.js} +1 -1
  62. package/payload/server/public/assets/{chunk-4TB4RGXK-D2JaxD6r.js → chunk-4TB4RGXK-Cs872xAq.js} +1 -1
  63. package/payload/server/public/assets/{chunk-5FUZZQ4R-Do3pbAGo.js → chunk-5FUZZQ4R-BnDFbZ_I.js} +1 -1
  64. package/payload/server/public/assets/{chunk-5PVQY5BW-np5moZSl.js → chunk-5PVQY5BW-Bu5B3Hyf.js} +1 -1
  65. package/payload/server/public/assets/{chunk-EDXVE4YY-BUFLWwRP.js → chunk-EDXVE4YY-B96Fw4FF.js} +1 -1
  66. package/payload/server/public/assets/{chunk-ENJZ2VHE-BE7Gt41s.js → chunk-ENJZ2VHE-CcGrGQim.js} +1 -1
  67. package/payload/server/public/assets/{chunk-ICPOFSXX-gOBkROMP.js → chunk-ICPOFSXX-ZRvcI4Ai.js} +1 -1
  68. package/payload/server/public/assets/{chunk-OYMX7WX6-DR-BkNZa.js → chunk-OYMX7WX6-B6RI9Fbf.js} +1 -1
  69. package/payload/server/public/assets/{chunk-U2HBQHQK-qLp-uSVE.js → chunk-U2HBQHQK-BYGHVYyo.js} +1 -1
  70. package/payload/server/public/assets/{chunk-X2U36JSP-DQiKti0J.js → chunk-X2U36JSP-rwNs-gTO.js} +1 -1
  71. package/payload/server/public/assets/{chunk-YZCP3GAM-Cd0JhpTo.js → chunk-YZCP3GAM-jPttJRap.js} +1 -1
  72. package/payload/server/public/assets/{chunk-ZZ45TVLE-8u01H3Hy.js → chunk-ZZ45TVLE-DLykWOT5.js} +1 -1
  73. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BaV5nDmT.js +1 -0
  74. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DOKlCKjY.js +1 -0
  75. package/payload/server/public/assets/clone-sQSwlSln.js +1 -0
  76. package/payload/server/public/assets/{dagre-KV5264BT-BBF_zxbi.js → dagre-KV5264BT-C6wSzHX2.js} +1 -1
  77. package/payload/server/public/assets/{dagre-BfVsOYOv.js → dagre-jnQDnF-5.js} +1 -1
  78. package/payload/server/public/assets/data-DbkuXcPb.js +1 -0
  79. package/payload/server/public/assets/{device-url-actions-CJBD3ecO.js → device-url-actions-y1tXNDZx.js} +1 -1
  80. package/payload/server/public/assets/{diagram-5BDNPKRD-BFHk2a7t.js → diagram-5BDNPKRD-N3X-n90h.js} +1 -1
  81. package/payload/server/public/assets/{diagram-G4DWMVQ6-Be3_qYl2.js → diagram-G4DWMVQ6-vfmbzdPd.js} +1 -1
  82. package/payload/server/public/assets/{diagram-MMDJMWI5-B3r4XVcu.js → diagram-MMDJMWI5-BETmPx_w.js} +1 -1
  83. package/payload/server/public/assets/{diagram-TYMM5635-BW5EIT4D.js → diagram-TYMM5635-BSUGM4wG.js} +1 -1
  84. package/payload/server/public/assets/{erDiagram-SMLLAGMA-DTu4_1Kb.js → erDiagram-SMLLAGMA-CWZ9OwMb.js} +1 -1
  85. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CadrjLcA.js → flowDiagram-DWJPFMVM-BpQOQS1a.js} +1 -1
  86. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-Cn0npD0L.js → ganttDiagram-T4ZO3ILL-Dc59igCS.js} +1 -1
  87. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CK3gG5Qm.js → gitGraphDiagram-UUTBAWPF-D6lXg3zl.js} +1 -1
  88. package/payload/server/public/assets/graph-CC5_6-dg.js +1 -0
  89. package/payload/server/public/assets/{graph-labels-CPzF6Gbk.js → graph-labels-DFyNH0jb.js} +1 -1
  90. package/payload/server/public/assets/{graphlib-DFIOO59N.js → graphlib-yG7kH8Fr.js} +1 -1
  91. package/payload/server/public/assets/{infoDiagram-42DDH7IO-BohUsXnN.js → infoDiagram-42DDH7IO-TS9Pv8Os.js} +1 -1
  92. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-tjmA4BU8.js → ishikawaDiagram-UXIWVN3A-BJiJJTq6.js} +1 -1
  93. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-DzBlFESM.js → journeyDiagram-VCZTEJTY-C7PW4fmw.js} +1 -1
  94. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BTw9BxK8.js → kanban-definition-6JOO6SKY-BEk21ciD.js} +1 -1
  95. package/payload/server/public/assets/{line-BYPL6wAj.js → line-DusyVWDE.js} +1 -1
  96. package/payload/server/public/assets/{mermaid-parser.core-Dmu4fWCS.js → mermaid-parser.core-DeeojQSb.js} +1 -1
  97. package/payload/server/public/assets/{mermaid.core-Z9vvieC2.js → mermaid.core-p65Lo7Sj.js} +3 -3
  98. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-BccAnfJ4.js → mindmap-definition-QFDTVHPH-B0jxFxdS.js} +1 -1
  99. package/payload/server/public/assets/{page-CBTlFm3b.js → page-BeYGnDzI.js} +1 -1
  100. package/payload/server/public/assets/{page-CDrsNrDO.js → page-x5khmfRx.js} +1 -1
  101. package/payload/server/public/assets/{pieDiagram-DEJITSTG-CZwxH1nJ.js → pieDiagram-DEJITSTG-DJ5GKYt6.js} +1 -1
  102. package/payload/server/public/assets/{public-MKWxjwiF.js → public-cnoUs7vq.js} +3 -3
  103. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BWT4DItX.js → quadrantDiagram-34T5L4WZ-BV7R-kwV.js} +1 -1
  104. package/payload/server/public/assets/{requirementDiagram-MS252O5E-CHYkWUEy.js → requirementDiagram-MS252O5E-DRiLzlGN.js} +1 -1
  105. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-km7p45Ng.js → sankeyDiagram-XADWPNL6-C5-6_cCI.js} +1 -1
  106. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BT1C0Dw-.js → sequenceDiagram-FGHM5R23-5FXm_VYM.js} +1 -1
  107. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-hibC19DY.js → stateDiagram-FHFEXIEX-FCQTaGqV.js} +1 -1
  108. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BdpPhdqg.js +1 -0
  109. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Cnm86NfE.js → timeline-definition-GMOUNBTQ-tvtq62ef.js} +1 -1
  110. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-ByjQPLzS.js → vennDiagram-DHZGUBPP-Dk-k7CE4.js} +1 -1
  111. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-CMVrWw7l.js → wardleyDiagram-NUSXRM2D-CZSrqniY.js} +1 -1
  112. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-Mpc1u3FV.js → xychartDiagram-5P7HB3ND-CpGLpk7Q.js} +1 -1
  113. package/payload/server/public/data.html +5 -5
  114. package/payload/server/public/graph.html +6 -6
  115. package/payload/server/public/index.html +8 -8
  116. package/payload/server/public/public.html +5 -5
  117. package/payload/server/server.js +128 -106
  118. package/payload/server/public/assets/channel-DYpIZW3Q.js +0 -1
  119. package/payload/server/public/assets/classDiagram-6PBFFD2Q-nkfy9gg7.js +0 -1
  120. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-B-pMmeCC.js +0 -1
  121. package/payload/server/public/assets/clone-jiTzIER6.js +0 -1
  122. package/payload/server/public/assets/data-BIOaDoqe.js +0 -1
  123. package/payload/server/public/assets/graph-ClfU7t1k.js +0 -1
  124. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-MuJZxjmU.js +0 -1
  125. /package/payload/server/public/assets/{brand-CENN2zdq.js → brand-lj7EhWRg.js} +0 -0
@@ -1,81 +1,92 @@
1
- // In-memory session store. keyed on Claude Code's intrinsic
2
- // `claudeSessionId` (the JSONL basename), not on a manager-minted id. The
3
- // manager mints zero ids of its own; the intrinsic id is the one
4
- // identifier per Claude process, stable from observation onward across
5
- // alive→ended and across manager restarts.
1
+ // In-memory session store. One identifier per Claude process, but the
2
+ // spawn-time window between PTY creation and Claude Code writing its first
3
+ // JSONL line is now unbounded: claude does not write the JSONL until the
4
+ // operator types the first turn (verified Pi 2.1.143 and Mac 2.1.128).
6
5
  //
7
- // During the spawn-time gap between PTY creation and Claude Code writing
8
- // its first JSONL line, the intrinsic id is not yet known. The store
9
- // holds a small `pendingByBridge` map keyed on the URL bridge suffix for
10
- // that window only. The pending entry is promoted into the main store
11
- // the instant `jsonl-observer` matches the JSONL on disk; on observation
12
- // failure or PTY exit before observation, the pending entry is removed.
6
+ // Lifecycle spans the full PTY lifetime:
7
+ //
8
+ // pending — created when /spawn captures the /remote-control URL.
9
+ // The row is keyed by the URL `bridgeSuffix` (the substring
10
+ // after `session_` in the URL). `claudeSessionId` is null;
11
+ // `jsonlPath` is null. The /spawn response returns at this
12
+ // point, so the operator sees a usable row inside ~2 s even
13
+ // when they never type.
14
+ //
15
+ // promoted — fires later (seconds or minutes, gated on operator typing)
16
+ // when `jsonl-observer` matches a JSONL on disk whose head
17
+ // bytes carry the bridge suffix. `claudeSessionId` is filled
18
+ // with the intrinsic JSONL basename, `jsonlPath` is set, and
19
+ // the same StoredSession is also registered under the
20
+ // intrinsic id so GET routes resolve either id to the same
21
+ // row.
22
+ //
23
+ // ended — operator deletes the row, the PTY exits, or the manager
24
+ // restarts. Promoted rows stay enumerable from disk via the
25
+ // JSONL transcript. Pending rows that never promoted have no
26
+ // JSONL and disappear cleanly on delete.
27
+ //
28
+ // The store mints zero ids of its own. The bridge suffix is claude's, the
29
+ // intrinsic id is claude's. The manager only observes them.
13
30
  export class SessionStore {
14
- sessions = new Map();
15
- pendingByBridge = new Map();
16
- add(s) {
17
- this.sessions.set(s.claudeSessionId, s);
31
+ /** Keyed by the row's stable surface id (bridge suffix). Lookup-by-bridge
32
+ * is the alive-row contract. */
33
+ byBridge = new Map();
34
+ /** Filled at promotion time so /list, /meta, /log routes resolve the
35
+ * intrinsic id to the same StoredSession the bridge id resolves to. */
36
+ byClaude = new Map();
37
+ /** Register a freshly-spawned session (claudeSessionId null, jsonlPath
38
+ * null). The row becomes visible to /list immediately. */
39
+ addPending(s) {
40
+ this.byBridge.set(s.bridgeSuffix, s);
18
41
  }
42
+ /** Resolve by either the bridge suffix or the intrinsic claudeSessionId.
43
+ * Returns the same StoredSession in either case once promotion has
44
+ * fired. */
19
45
  get(id) {
20
- return this.sessions.get(id);
46
+ return this.byBridge.get(id) ?? this.byClaude.get(id);
21
47
  }
48
+ /** Remove by either id. Drops both index entries. */
22
49
  remove(id) {
23
- const s = this.sessions.get(id);
24
- if (s)
25
- this.sessions.delete(id);
50
+ const s = this.get(id);
51
+ if (!s)
52
+ return undefined;
53
+ this.byBridge.delete(s.bridgeSuffix);
54
+ if (s.claudeSessionId !== null)
55
+ this.byClaude.delete(s.claudeSessionId);
26
56
  return s;
27
57
  }
28
- listBySender(senderId) {
58
+ listBySender(senderId, opts = {}) {
59
+ const includeHidden = opts.includeHidden === true;
29
60
  const out = [];
30
- for (const s of this.sessions.values()) {
31
- if (s.senderId === senderId)
32
- out.push(s);
61
+ for (const s of this.byBridge.values()) {
62
+ if (s.senderId !== senderId)
63
+ continue;
64
+ if (!includeHidden && s.hidden)
65
+ continue;
66
+ out.push(s);
33
67
  }
34
68
  return out;
35
69
  }
36
70
  all() {
37
- return [...this.sessions.values()];
71
+ return [...this.byBridge.values()];
38
72
  }
39
73
  size() {
40
- return this.sessions.size;
41
- }
42
- // --- pending lifecycle ----------------------------------
43
- addPending(p) {
44
- this.pendingByBridge.set(p.bridgeSuffix, p);
45
- }
46
- getPending(bridgeSuffix) {
47
- return this.pendingByBridge.get(bridgeSuffix);
48
- }
49
- removePending(bridgeSuffix) {
50
- const p = this.pendingByBridge.get(bridgeSuffix);
51
- if (p)
52
- this.pendingByBridge.delete(bridgeSuffix);
53
- return p;
74
+ return this.byBridge.size;
54
75
  }
55
- /** Move a pending entry into the main store under its newly-observed
56
- * `claudeSessionId`. Idempotent: a second call for the same bridge
57
- * suffix is a no-op once the pending entry has been removed.
58
- * Returns the promoted StoredSession, or null when no pending entry
59
- * exists for this bridge suffix (already promoted, cancelled, or
60
- * the PTY exited before observation fired). */
61
- promotePending(bridgeSuffix, claudeSessionId, jsonlPath) {
62
- const p = this.pendingByBridge.get(bridgeSuffix);
63
- if (!p)
76
+ /** Bind a pending row to its newly-observed `claudeSessionId` + JSONL
77
+ * path. Idempotent: a second call on an already-promoted row updates
78
+ * nothing. Returns the StoredSession on success, null when no row
79
+ * exists for the bridge suffix (operator already deleted it, or the
80
+ * PTY exited before observation fired). */
81
+ promote(bridgeSuffix, claudeSessionId, jsonlPath) {
82
+ const s = this.byBridge.get(bridgeSuffix);
83
+ if (!s)
64
84
  return null;
65
- this.pendingByBridge.delete(bridgeSuffix);
66
- const s = {
67
- claudeSessionId,
68
- pid: p.pid,
69
- url: p.url,
70
- startedAt: p.startedAt,
71
- senderId: p.senderId,
72
- role: p.role,
73
- channel: p.channel,
74
- jsonlPath,
75
- pty: p.pty,
76
- exited: p.exited,
77
- };
78
- this.sessions.set(claudeSessionId, s);
85
+ if (s.claudeSessionId !== null)
86
+ return s;
87
+ s.claudeSessionId = claudeSessionId;
88
+ s.jsonlPath = jsonlPath;
89
+ this.byClaude.set(claudeSessionId, s);
79
90
  return s;
80
91
  }
81
92
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,0EAA0E;AAC1E,iEAAiE;AACjE,uEAAuE;AACvE,2CAA2C;AAC3C,EAAE;AACF,yEAAyE;AACzE,qEAAqE;AACrE,yEAAyE;AACzE,sEAAsE;AACtE,yEAAyE;AACzE,wEAAwE;AAyCxE,MAAM,OAAO,YAAY;IACN,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAA;IAC3C,eAAe,GAAG,IAAI,GAAG,EAA0B,CAAA;IAEpE,GAAG,CAAC,CAAgB;QAClB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAA;IACzC,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,CAAC,EAAU;QACf,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC/B,IAAI,CAAC;YAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC/B,OAAO,CAAC,CAAA;IACV,CAAC;IAED,YAAY,CAAC,QAAgB;QAC3B,MAAM,GAAG,GAAoB,EAAE,CAAA;QAC/B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1C,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IACpC,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAA;IAC3B,CAAC;IAED,2DAA2D;IAE3D,UAAU,CAAC,CAAiB;QAC1B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;IAC7C,CAAC;IAED,UAAU,CAAC,YAAoB;QAC7B,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IAC/C,CAAC;IAED,aAAa,CAAC,YAAoB;QAChC,MAAM,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAChD,IAAI,CAAC;YAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;QAChD,OAAO,CAAC,CAAA;IACV,CAAC;IAED;;;;;oDAKgD;IAChD,cAAc,CACZ,YAAoB,EACpB,eAAuB,EACvB,SAAiB;QAEjB,MAAM,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAChD,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACnB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;QACzC,MAAM,CAAC,GAAkB;YACvB,eAAe;YACf,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,SAAS;YACT,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,MAAM,EAAE,CAAC,CAAC,MAAM;SACjB,CAAA;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAA;QACrC,OAAO,CAAC,CAAA;IACV,CAAC;CACF"}
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,2EAA2E;AAC3E,yEAAyE;AACzE,uEAAuE;AACvE,EAAE;AACF,yCAAyC;AACzC,EAAE;AACF,sEAAsE;AACtE,0EAA0E;AAC1E,yEAAyE;AACzE,yEAAyE;AACzE,0EAA0E;AAC1E,sCAAsC;AACtC,EAAE;AACF,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,2EAA2E;AAC3E,oEAAoE;AACpE,yEAAyE;AACzE,qBAAqB;AACrB,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,uDAAuD;AACvD,EAAE;AACF,0EAA0E;AAC1E,4DAA4D;AAsC5D,MAAM,OAAO,YAAY;IACvB;qCACiC;IAChB,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAA;IAC5D;4EACwE;IACvD,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAA;IAE5D;+DAC2D;IAC3D,UAAU,CAAC,CAAgB;QACzB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;IACtC,CAAC;IAED;;iBAEa;IACb,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACvD,CAAC;IAED,qDAAqD;IACrD,MAAM,CAAC,EAAU;QACf,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACtB,IAAI,CAAC,CAAC;YAAE,OAAO,SAAS,CAAA;QACxB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;QACpC,IAAI,CAAC,CAAC,eAAe,KAAK,IAAI;YAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAA;QACvE,OAAO,CAAC,CAAA;IACV,CAAC;IAED,YAAY,CAAC,QAAgB,EAAE,OAAoC,EAAE;QACnE,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,KAAK,IAAI,CAAA;QACjD,MAAM,GAAG,GAAoB,EAAE,CAAA;QAC/B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ;gBAAE,SAAQ;YACrC,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,MAAM;gBAAE,SAAQ;YACxC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACb,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IACpC,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAA;IAC3B,CAAC;IAED;;;;gDAI4C;IAC5C,OAAO,CACL,YAAoB,EACpB,eAAuB,EACvB,SAAiB;QAEjB,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACzC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACnB,IAAI,CAAC,CAAC,eAAe,KAAK,IAAI;YAAE,OAAO,CAAC,CAAA;QACxC,CAAC,CAAC,eAAe,GAAG,eAAe,CAAA;QACnC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAA;QACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAA;QACrC,OAAO,CAAC,CAAA;IACV,CAAC;CACF"}
@@ -1,6 +1,16 @@
1
1
  export interface ToolSurface {
2
2
  admin: ReadonlySet<string>;
3
3
  public: ReadonlySet<string>;
4
+ /** Per-plugin MCP server descriptors. Key is the plugin directory name
5
+ * (matches the `mcp__<plugin>__*` namespace). Spawned by Claude Code at
6
+ * session start via `--mcp-config`. Plugins with `tools: []` contribute
7
+ * no servers. */
8
+ mcpServers: ReadonlyMap<string, McpServerDescriptor>;
9
+ }
10
+ export interface McpServerDescriptor {
11
+ command: string;
12
+ args: readonly string[];
13
+ env?: Readonly<Record<string, string>>;
4
14
  }
5
15
  export declare class ToolSurfaceError extends Error {
6
16
  readonly reason: string;
@@ -16,10 +26,30 @@ interface ToolEntry {
16
26
  * Throws ToolSurfaceError on any malformed entry (missing name, missing or
17
27
  * non-boolean publicAllowlist). */
18
28
  export declare function parseToolsBlock(frontmatter: string, pluginDir: string): ToolEntry[];
29
+ /** Parse the optional `mcp:` block out of a PLUGIN.md frontmatter body.
30
+ * Returns null when the frontmatter has no `mcp:` key. Throws on a malformed
31
+ * shape (missing command, args not a list, env not key:value pairs). The
32
+ * schema mirrors Claude Code's `.mcp.json`:
33
+ * mcp:
34
+ * command: node
35
+ * args:
36
+ * - ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
37
+ * - ${PLATFORM_ROOT}/plugins/memory/mcp/dist/index.js
38
+ * env:
39
+ * MCP_SPAWN_TEE_NAME: memory
40
+ * ACCOUNT_ID: ${ACCOUNT_ID}
41
+ */
42
+ export declare function parseMcpBlock(frontmatter: string, pluginDir: string): McpServerDescriptor | null;
19
43
  /** Walk a plugins root directory, parse every <name>/PLUGIN.md, and return
20
- * the {admin, public} sets of fully qualified tool names. Throws on the
21
- * first malformed manifest — the caller (the manager boot) must exit
22
- * non-zero so the operator sees the gap. */
23
- export declare function loadToolSurface(pluginsRoot: string): ToolSurface;
44
+ * the {admin, public, mcpServers} sets. Throws on the first malformed
45
+ * manifest — the caller (the manager boot) must exit non-zero so the
46
+ * operator sees the gap.
47
+ *
48
+ * Invariant: a plugin that declares `tools:` with at least one entry MUST
49
+ * also declare an `mcp:` block. Without it the spawn would push
50
+ * `--allowed-tools mcp__<plugin>__*` for a server that was never registered
51
+ * with Claude Code; the tools would be unreachable and the operator would
52
+ * see "tool not found" rather than a boot-time gap. */
53
+ export declare function loadToolSurface(pluginsRoots: string | readonly string[]): ToolSurface;
24
54
  export {};
25
55
  //# sourceMappingURL=tool-surface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-surface.d.ts","sourceRoot":"","sources":["../src/tool-surface.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC1B,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAC5B;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aACb,MAAM,EAAE,MAAM;aAAkB,MAAM,EAAE,MAAM;gBAA9C,MAAM,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM;CAI3E;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,OAAO,CAAA;CACzB;AAYD;;;oCAGoC;AACpC,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,CAsEnF;AAED;;;6CAG6C;AAC7C,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CA0BhE"}
1
+ {"version":3,"file":"tool-surface.d.ts","sourceRoot":"","sources":["../src/tool-surface.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC1B,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC3B;;;sBAGkB;IAClB,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;CACrD;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACvC;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aACb,MAAM,EAAE,MAAM;aAAkB,MAAM,EAAE,MAAM;gBAA9C,MAAM,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM;CAI3E;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,OAAO,CAAA;CACzB;AAYD;;;oCAGoC;AACpC,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,CAsEnF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CA6ChG;AAED;;;;;;;;;wDASwD;AACxD,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,WAAW,CA8CrF"}
@@ -111,39 +111,137 @@ export function parseToolsBlock(frontmatter, pluginDir) {
111
111
  flush();
112
112
  return out;
113
113
  }
114
- /** Walk a plugins root directory, parse every <name>/PLUGIN.md, and return
115
- * the {admin, public} sets of fully qualified tool names. Throws on the
116
- * first malformed manifest the caller (the manager boot) must exit
117
- * non-zero so the operator sees the gap. */
118
- export function loadToolSurface(pluginsRoot) {
119
- if (!existsSync(pluginsRoot)) {
120
- throw new ToolSurfaceError('plugins-root-missing', pluginsRoot);
114
+ /** Parse the optional `mcp:` block out of a PLUGIN.md frontmatter body.
115
+ * Returns null when the frontmatter has no `mcp:` key. Throws on a malformed
116
+ * shape (missing command, args not a list, env not key:value pairs). The
117
+ * schema mirrors Claude Code's `.mcp.json`:
118
+ * mcp:
119
+ * command: node
120
+ * args:
121
+ * - ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
122
+ * - ${PLATFORM_ROOT}/plugins/memory/mcp/dist/index.js
123
+ * env:
124
+ * MCP_SPAWN_TEE_NAME: memory
125
+ * ACCOUNT_ID: ${ACCOUNT_ID}
126
+ */
127
+ export function parseMcpBlock(frontmatter, pluginDir) {
128
+ const lines = frontmatter.split(/\r?\n/);
129
+ let i = 0;
130
+ while (i < lines.length) {
131
+ if (/^mcp:\s*$/.test(lines[i])) {
132
+ i++;
133
+ break;
134
+ }
135
+ i++;
121
136
  }
122
- const admin = new Set();
123
- const pub = new Set();
124
- const entries = readdirSync(pluginsRoot).sort();
125
- for (const plugin of entries) {
126
- const pluginDir = join(pluginsRoot, plugin);
127
- try {
128
- if (!statSync(pluginDir).isDirectory())
129
- continue;
137
+ if (i >= lines.length)
138
+ return null;
139
+ let command = null;
140
+ const args = [];
141
+ const env = {};
142
+ let envHasEntry = false;
143
+ let mode = 'top';
144
+ for (; i < lines.length; i++) {
145
+ const line = lines[i];
146
+ if (line.length === 0)
147
+ continue;
148
+ // top-level key (no leading space) ends the mcp block
149
+ if (/^[A-Za-z_]/.test(line))
150
+ break;
151
+ const topCommand = line.match(/^\s\s(command):\s*(.+?)\s*$/);
152
+ const topArgsHeader = line.match(/^\s\s(args):\s*$/);
153
+ const topEnvHeader = line.match(/^\s\s(env):\s*$/);
154
+ if (topCommand) {
155
+ command = topCommand[2];
156
+ mode = 'top';
157
+ continue;
130
158
  }
131
- catch {
159
+ if (topArgsHeader) {
160
+ mode = 'args';
132
161
  continue;
133
162
  }
134
- const manifestPath = join(pluginDir, 'PLUGIN.md');
135
- if (!existsSync(manifestPath))
163
+ if (topEnvHeader) {
164
+ mode = 'env';
136
165
  continue;
137
- const raw = readFileSync(manifestPath, 'utf-8');
138
- const frontmatter = extractFrontmatter(raw, plugin);
139
- const tools = parseToolsBlock(frontmatter, plugin);
140
- for (const t of tools) {
141
- const qualified = `mcp__${plugin}__${t.name}`;
142
- admin.add(qualified);
143
- if (t.publicAllowlist)
144
- pub.add(qualified);
166
+ }
167
+ if (mode === 'args') {
168
+ const item = line.match(/^\s+-\s+(.+?)\s*$/);
169
+ if (item) {
170
+ args.push(item[1]);
171
+ continue;
172
+ }
173
+ }
174
+ if (mode === 'env') {
175
+ const kv = line.match(/^\s+([A-Za-z_][A-Za-z0-9_]*):\s*(.+?)\s*$/);
176
+ if (kv) {
177
+ env[kv[1]] = kv[2];
178
+ envHasEntry = true;
179
+ continue;
180
+ }
181
+ }
182
+ }
183
+ if (command === null) {
184
+ throw new ToolSurfaceError('mcp-command-missing', `${pluginDir}/PLUGIN.md mcp: block has no command`);
185
+ }
186
+ const desc = { command, args };
187
+ if (envHasEntry)
188
+ desc.env = env;
189
+ return desc;
190
+ }
191
+ /** Walk a plugins root directory, parse every <name>/PLUGIN.md, and return
192
+ * the {admin, public, mcpServers} sets. Throws on the first malformed
193
+ * manifest — the caller (the manager boot) must exit non-zero so the
194
+ * operator sees the gap.
195
+ *
196
+ * Invariant: a plugin that declares `tools:` with at least one entry MUST
197
+ * also declare an `mcp:` block. Without it the spawn would push
198
+ * `--allowed-tools mcp__<plugin>__*` for a server that was never registered
199
+ * with Claude Code; the tools would be unreachable and the operator would
200
+ * see "tool not found" rather than a boot-time gap. */
201
+ export function loadToolSurface(pluginsRoots) {
202
+ const roots = Array.isArray(pluginsRoots) ? pluginsRoots : [pluginsRoots];
203
+ for (const r of roots) {
204
+ if (!existsSync(r))
205
+ throw new ToolSurfaceError('plugins-root-missing', r);
206
+ }
207
+ const admin = new Set();
208
+ const pub = new Set();
209
+ const mcpServers = new Map();
210
+ for (const root of roots) {
211
+ const entries = readdirSync(root).sort();
212
+ for (const plugin of entries) {
213
+ const pluginDir = join(root, plugin);
214
+ try {
215
+ if (!statSync(pluginDir).isDirectory())
216
+ continue;
217
+ }
218
+ catch {
219
+ continue;
220
+ }
221
+ const manifestPath = join(pluginDir, 'PLUGIN.md');
222
+ if (!existsSync(manifestPath))
223
+ continue;
224
+ const raw = readFileSync(manifestPath, 'utf-8');
225
+ const frontmatter = extractFrontmatter(raw, plugin);
226
+ const tools = parseToolsBlock(frontmatter, plugin);
227
+ if (tools.length === 0)
228
+ continue;
229
+ const mcp = parseMcpBlock(frontmatter, plugin);
230
+ if (!mcp) {
231
+ throw new ToolSurfaceError('mcp-block-missing', `${plugin}/PLUGIN.md declares tools but no mcp: block; spawns would --allowed-tools mcp__${plugin}__* with no registered server`);
232
+ }
233
+ if (mcpServers.has(plugin)) {
234
+ throw new ToolSurfaceError('mcp-plugin-duplicate', `${plugin} declared by more than one plugins root`);
235
+ }
236
+ mcpServers.set(plugin, mcp);
237
+ for (const t of tools) {
238
+ const qualified = `mcp__${plugin}__${t.name}`;
239
+ admin.add(qualified);
240
+ if (t.publicAllowlist)
241
+ pub.add(qualified);
242
+ }
145
243
  }
146
244
  }
147
- return { admin, public: pub };
245
+ return { admin, public: pub, mcpServers };
148
246
  }
149
247
  //# sourceMappingURL=tool-surface.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-surface.js","sourceRoot":"","sources":["../src/tool-surface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-surface.js","sourceRoot":"","sources":["../src/tool-surface.ts"],"names":[],"mappings":"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"}
@@ -8,19 +8,15 @@ These three rules win when anything else in this prompt conflicts with them.
8
8
  2. **Be concise.** Three sentences or fewer. If you cannot answer in three, ask in five words.
9
9
  3. **Show your evidence.** Gather evidence before forming a hypothesis. One measurement beats three guesses.
10
10
 
11
- ## The graph
12
-
13
- The Neo4j graph is where this account stores everything it knows. Before you write, reduce the input to the smallest set of nodes, edges, and properties that keeps the meaning. When you read, you get candidates back, not answers; pick the few that answer the current question. When the graph is wrong, fix it. When the graph is empty and you have to fall back to training knowledge, say so out loud.
14
-
15
- Every node has a parent. The canonical hierarchy is LocalBusiness, then Project, then Task or Person or Organisation or KnowledgeDocument. A node with no upward edge to its hierarchy parent is a write defect, not a graph state. The wrapped writers refuse it; the graph-write shim rolls back any raw cypher that produces one. Cross-hierarchy edges (one Person linked to several Projects, one KnowledgeDocument about several Organisations) are normal; the rule governs containment, not exclusivity.
16
-
17
11
  ## The owner
18
12
 
19
- Your brain is the Neo4j graph. It holds everything you know about the owner. The more you know about them (basic facts, preferences, working style, personality, relationships, goals) the more you can do for them. You decide which attributes are worth collecting; the canonical fields on the graph schema are only a starting point. Aim for the full picture of who the owner is as a person: biographical facts, personality, working preferences, relationships, interests, goals, anything a long-trusted private secretary would know about the person they serve. Add whatever fields you need to `Person.preferences`, to `Person` itself, or to `LocalBusiness` as new properties. Populate and maintain both nodes as comprehensively as possible, and query them at session start. On every new session, open with what matters now (changes since last session, things needing attention, promises) when there is something to report; otherwise open with one grounded question that expands what you do not yet know about the owner, in the category where the gap is widest. Until you know whether the owner is personal or business-owner, the graph-write gate blocks every user-domain write and you are inoperative; ask once on first contact, then write the persona property and the corresponding node.
13
+ The more you know about the owner, the better the work you can do. Never stop seeking information about them, prioritising what is pertinent to their current activities and objectives. The owner's activities and objectives are themselves first-class subjects to ask about.
14
+
15
+ Everything you learn in conversation is recorded for you by a background agent that watches every completed turn. You do not write to the graph yourself. Ask, listen, and act on what you have already been told; the recording is taken care of.
20
16
 
21
17
  Remote access and public-facing channels are optional. Cloudflare Tunnel exposes the platform on a custom domain; WhatsApp, Telegram, and email reach the owner without one. If none is set up, explain each briefly when the conversation surfaces a need, and offer to assist. The execution paths are `setup-tunnel` (Cloudflare), the WhatsApp pairing flow, and the Telegram channel plugin.
22
18
 
23
- When the owner declines an offer, record the decline as a property on `Person` (e.g. `preferences.declinedRemoteAccess: true`) so you do not re-ask. The `## About the Owner` Coverage signal will keep surfacing missing fields; honour `notApplicable: true` on any field the owner has explicitly opted out of.
19
+ When the owner declines an offer, record the decline as a property on `Person` (e.g. `preferences.declinedRemoteAccess: true`) so you do not re-ask.
24
20
 
25
21
  ## Before you act
26
22
 
@@ -28,7 +24,7 @@ You may not act on a request until you know three things: what is being asked, w
28
24
 
29
25
  ## Your role
30
26
 
31
- You are the head of operations, chief of staff, and private secretary. Two jobs in every session. First, turn every conversation into one precise action: cut the vagueness, find the signal, name it. Second, keep the graph organised: projects hold the top-level entities, tasks live under projects, people and organisations carry the relationships.
27
+ You are the head of operations, chief of staff, and private secretary. Turn every conversation into one precise action: cut the vagueness, find the signal, name it.
32
28
 
33
29
  ## How you sound
34
30
 
@@ -38,19 +34,14 @@ You are an AI. Say so if asked. Never pretend to be a human. Speak British Engli
38
34
 
39
35
  Address the owner directly. Open with what matters now: what changed since last session, what needs attention, what was promised. Skip greetings that don't earn their place. The first message of every session is a status, not a salutation.
40
36
 
41
- When there is no status to report (fresh account, post-onboarding first turn, no open tasks, no overnight changes), open with a single grounded question that names one specific field from the `### Coverage` `Missing:` list inside `<about-owner>`. Ask one thing about how the owner works in that category. Never a list, never a form, never "tell me about yourself". One question, the kind a sharp new colleague would ask on their second day.
37
+ When there is no status to report (fresh account, post-onboarding first turn, no open tasks, no overnight changes), open with one grounded question that expands what you do not yet know about the owner, in the category where the gap is widest. Ask the kind of question a sharp new colleague would ask on their second day. Never a list, never a form, never "tell me about yourself". One question, the final sentence.
42
38
 
43
- When the operator describes work that a dormant plugin would do for them, mention the relevant plugin from `<dormant-plugins>` in one helpful sentence. Maximum one nudge per plugin per session.
39
+ If the operator describes work a dormant plugin would do automatically, offer to enable it in one helpful sentence. Maximum one nudge per plugin per session.
44
40
 
45
- ## Three files to read at session start
41
+ ## Two files to read at session start
46
42
 
47
43
  - `SOUL.md`: how you sound. Tone and personality only, no rules.
48
44
  - `AGENTS.md`: the list of installed specialists and when to send work to each.
49
- - `LEARNINGS.md`: corrections from past sessions, which you own. Read before repeating an approach that previously failed.
50
-
51
- ## You own LEARNINGS.md
52
-
53
- `LEARNINGS.md` is yours to keep current. Read it at session start; add to it during the session. Add a new entry whenever a tool call reveals a reusable correction (parameter format, schema requirement, auth quirk, data-shape issue) or the owner states a working principle that should shape every future interaction. One entry per distinct pattern: before writing, check whether a matching entry already exists, and update rather than duplicate. Keep entries short, state the rule first, then one sentence of why. Do not store business knowledge, personality, or domain knowledge there; those belong in the graph, in SOUL.md, and in the relevant skill respectively.
54
45
 
55
46
  ## How to choose where work goes
56
47
 
@@ -81,4 +72,4 @@ One-sided framing only: "Proceed?" or "Stop?", never "Proceed, or stop?" because
81
72
 
82
73
  - **Skill inputs.** When a skill needs an input you do not have, call `AskUserQuestion` next. Never call `memory-search` or `conversation-search` to guess.
83
74
  - **Resuming the thread.** After a self-contained sub-flow (identity repair, schema audit, attachment unzip), the conversation history still holds the owner's earlier request. Name what they were asking and pick it back up yourself. Never ask the owner to restate.
84
- - **Dormant capabilities.** The `<dormant-plugins>` block lists plugins the owner has not turned on. When the owner describes a task that a dormant plugin would do automatically, mention the plugin in one helpful sentence. Maximum one nudge per plugin per session.
75
+ - **Dormant capabilities.** If the operator describes work a dormant plugin would do automatically, offer to enable it. Maximum one nudge per plugin per session.