@rubytech/create-maxy-code 0.1.39 → 0.1.41
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/dist/index.js +35 -101
- package/dist/uninstall.js +11 -102
- package/package.json +1 -1
- package/payload/platform/lib/mcp-stderr-tee/package.json +7 -0
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +142 -52
- package/payload/platform/plugins/docs/references/deployment.md +7 -3
- package/payload/platform/plugins/docs/references/platform.md +18 -4
- package/payload/platform/plugins/docs/references/plugins-guide.md +2 -0
- package/payload/platform/services/claude-session-manager/dist/config.d.ts +17 -0
- package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/config.js +37 -1
- package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts +54 -0
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +516 -0
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/hooks-discovery.d.ts +7 -0
- package/payload/platform/services/claude-session-manager/dist/hooks-discovery.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/hooks-discovery.js +90 -0
- package/payload/platform/services/claude-session-manager/dist/hooks-discovery.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +3 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +426 -204
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +60 -13
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts +2 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.js +11 -6
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +40 -45
- 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 +146 -162
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/reaper.d.ts +24 -0
- package/payload/platform/services/claude-session-manager/dist/reaper.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/reaper.js +114 -0
- package/payload/platform/services/claude-session-manager/dist/reaper.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts +16 -41
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.js +29 -68
- package/payload/platform/services/claude-session-manager/dist/session-store.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +54 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js +111 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +4 -2
- package/payload/platform/templates/agents/admin/SOUL.md +8 -14
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.d.ts +51 -0
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.js +196 -0
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.js.map +1 -0
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/package.json +7 -0
- package/payload/server/{chunk-NNHHGQJL.js → chunk-4P2MPERV.js} +6 -163
- package/payload/server/{chunk-3G6JMV7N.js → chunk-MEGIQYUD.js} +1 -1
- package/payload/server/{chunk-QC5LHYPH.js → chunk-XJVJ2B2Q.js} +1 -1
- package/payload/server/{cloudflare-task-tracker-NEB3X6O2.js → cloudflare-task-tracker-R6MMORFU.js} +2 -2
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/public/assets/{Checkbox-CmCjmfJy.js → Checkbox-blxv2XPY.js} +1 -1
- package/payload/server/public/assets/{admin-CtodW6As.js → admin-C3EvHpLN.js} +1 -1
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-CfOjbx0H.js → architectureDiagram-Q4EWVU46-bETsVzGS.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-D0kA2C9i.js → blockDiagram-DXYQGD6D-5y0GBnfQ.js} +1 -1
- package/payload/server/public/assets/{brand-6hKfBgOI.css → brand-DQlLKLDH.css} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CDgXiXgj.js → c4Diagram-AHTNJAMY-C1znpVGu.js} +1 -1
- package/payload/server/public/assets/channel-BWqTaXzb.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-BfBTcT5X.js → chunk-336JU56O-DlCVUGzQ.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-BdSSZ1Kw.js → chunk-426QAEUC-bGYkmA4z.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-UvE1im9g.js → chunk-4TB4RGXK-6Sb0Undm.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-Dx4DslXz.js → chunk-5FUZZQ4R-CAT_Pq2T.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CNHawhLJ.js → chunk-5PVQY5BW-j231ESse.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-Rmjv-1et.js → chunk-EDXVE4YY-BAlS4QL7.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-CL-LeH3r.js → chunk-ENJZ2VHE-D3Ku_BMP.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-B2MFOJDt.js → chunk-ICPOFSXX-AR86A5WB.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-BxcIcCt5.js → chunk-OYMX7WX6-DxGhapkW.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-COzwOBrY.js → chunk-U2HBQHQK-DAlqsDo_.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-B0rjT5hL.js → chunk-X2U36JSP-lZdkkdyB.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-pwrIw0XH.js → chunk-YZCP3GAM-CCjtXOFD.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-BXpeAm0k.js → chunk-ZZ45TVLE-ComtdKny.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-B9hC6fOR.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-afl_ydIG.js +1 -0
- package/payload/server/public/assets/clone-Lj83OaZ3.js +1 -0
- package/payload/server/public/assets/{dagre-DjOJn05k.js → dagre-DX8QJeVt.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-PczvQiEh.js → dagre-KV5264BT-BcRbiZ1q.js} +1 -1
- package/payload/server/public/assets/data-CS_R5VWQ.js +1 -0
- package/payload/server/public/assets/{device-url-actions-C55ZS_Zg.js → device-url-actions-Cag9IJ7n.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-D477xo5F.js → diagram-5BDNPKRD-Bw47VwHO.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-C-HAtbtT.js → diagram-G4DWMVQ6-B-aVfhiD.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-B9wus4H0.js → diagram-MMDJMWI5-DERz2dKo.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-UMZLloFr.js → diagram-TYMM5635-B7eEX9Ta.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-B8E52Mp4.js → erDiagram-SMLLAGMA-G_JJq3zB.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CUel34tq.js → flowDiagram-DWJPFMVM-BeY9QaO0.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BfwE-Xav.js → ganttDiagram-T4ZO3ILL-IXviGYnx.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-2d6tXRIM.js → gitGraphDiagram-UUTBAWPF-GlY6pZQ1.js} +1 -1
- package/payload/server/public/assets/graph-DtGkQBFr.js +1 -0
- package/payload/server/public/assets/graph-labels-Dwu1ON5v.js +1 -0
- package/payload/server/public/assets/{graphlib-CCo9-wNJ.js → graphlib-BWgAjZSb.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-DB1SVWL6.js → infoDiagram-42DDH7IO-D4YZM0gD.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-CdeMUTYS.js → ishikawaDiagram-UXIWVN3A-fR71GDOp.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-D8x8TUoc.js → journeyDiagram-VCZTEJTY-C1TcY_6m.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-Cmkhd1mO.js → kanban-definition-6JOO6SKY-IPZKpnnG.js} +1 -1
- package/payload/server/public/assets/{line-CoHkpBv3.js → line-B2JtEL1B.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-C7R2PfZC.js → mermaid-parser.core-BKCLXqUh.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-lQaq-kll.js → mermaid.core-CmNpCLB-.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CsPq3pX1.js → mindmap-definition-QFDTVHPH-BS0E2FPD.js} +1 -1
- package/payload/server/public/assets/{page-DwEaAdVp.js → page-BdI3GCun.js} +1 -1
- package/payload/server/public/assets/{page-CBKzjUHO.js → page-zIjAkU2y.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-FZH9sTnP.js → pieDiagram-DEJITSTG-J61JDyk8.js} +1 -1
- package/payload/server/public/assets/{public-hGLzxhE_.js → public-C5vaQnC_.js} +4 -4
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-9poxfoqh.js → quadrantDiagram-34T5L4WZ-CLI03OtR.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-Ce7iOdT_.js → requirementDiagram-MS252O5E-C8MCt5NO.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DINuXatI.js → sankeyDiagram-XADWPNL6-DQuugruj.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CSMec3EK.js → sequenceDiagram-FGHM5R23-CoYitwhO.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-15DKzypj.js → stateDiagram-FHFEXIEX-G68cHHoI.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Dtgpgr_D.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-BxIRc9Pu.js → timeline-definition-GMOUNBTQ-CelLeJVS.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-DdgRyU55.js → vennDiagram-DHZGUBPP-BVgFPkJq.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-CKvhU1Uj.js → wardleyDiagram-NUSXRM2D-CzD_8hl2.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-d0V1V4PD.js → xychartDiagram-5P7HB3ND-BuTxWdX5.js} +1 -1
- 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 +1058 -846
- package/payload/server/public/assets/channel-DA7MGMzQ.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DqfmcWSr.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BVOMSbZ_.js +0 -1
- package/payload/server/public/assets/clone-Byp7hagU.js +0 -1
- package/payload/server/public/assets/data-A7azIkZU.js +0 -1
- package/payload/server/public/assets/graph-Dx83EhtP.js +0 -1
- package/payload/server/public/assets/graph-labels-Bg2Bzelb.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-AcaK_QfD.js +0 -1
- /package/payload/server/public/assets/{brand-DXOx08r0.js → brand-D6mXeyxV.js} +0 -0
|
@@ -56,7 +56,7 @@ Cloudflare, WhatsApp, Telegram, and any other dormant capability surfaces on own
|
|
|
56
56
|
|
|
57
57
|
### Per-spawn system-prompt sentinels
|
|
58
58
|
|
|
59
|
-
Every PTY spawn injects an `--append-system-prompt` block composed of
|
|
59
|
+
Every PTY spawn injects an `--append-system-prompt` block composed of these sentinel sections in fixed order:
|
|
60
60
|
|
|
61
61
|
| Sentinel | Source | Behaviour on resolve failure |
|
|
62
62
|
|---|---|---|
|
|
@@ -65,15 +65,19 @@ Every PTY spawn injects an `--append-system-prompt` block composed of six sentin
|
|
|
65
65
|
| `<identity>` | `<accountDir>/agents/<role>/IDENTITY.md` | spawn refuses with `identity-unresolved` |
|
|
66
66
|
| `<soul>` | `<accountDir>/agents/<role>/SOUL.md` | spawn refuses with `identity-unresolved` |
|
|
67
67
|
| `<about-owner>` | upstream `loadUserProfile` + `formatProfileSummary` (UI process) | sentinel carries `coverage-unresolved: <reason>`; spawn proceeds |
|
|
68
|
+
| `<specialist-domains>` | `<accountDir>/specialists/agents/*.md` frontmatter (UI process) | sentinel omitted when set is empty |
|
|
69
|
+
| `<plugin-manifest>` | enabled plugins' PLUGIN.md frontmatter + skill SKILL.md frontmatter (UI process) | sentinel omitted when set is empty |
|
|
68
70
|
| `<dormant-plugins>` | installed-minus-enabled set from `platform/plugins/` and `account.json` | sentinel omitted when set is empty |
|
|
69
71
|
|
|
70
72
|
Diagnostic line per spawn (`~/.<brand>/logs/server.log`):
|
|
71
73
|
|
|
72
74
|
```
|
|
73
|
-
[pty-spawn] sessionId=<id> appendSystemPromptBytes=<n> identityBytes=<n> soulBytes=<n> aboutOwnerBytes=<n> dormantPluginsBytes=<n> accountDir=<path> role=<admin|public> hostname=<h> lanIPv4=<ip> adminUrl=<url> tunnelUrl=<url|none>
|
|
75
|
+
[pty-spawn] sessionId=<id> appendSystemPromptBytes=<n> identityBytes=<n> soulBytes=<n> aboutOwnerBytes=<n> dormantPluginsBytes=<n> pluginManifestBytes=<n> specialistDomainsBytes=<n> accountDir=<path> role=<admin|public> hostname=<h> lanIPv4=<ip> adminUrl=<url> tunnelUrl=<url|none>
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
The `pty-spawn-start` line additionally carries `hooksResolved=<event1,event2,…>` — the hook event names Claude Code would actually load for that PTY (resolved by walking the same `$CLAUDE_CONFIG_DIR/settings.json` plus the cwd-to-.git path Claude Code itself uses). A Stop hook registered in a settings file outside the loader's scope shows up as a missing event in this list.
|
|
79
|
+
|
|
80
|
+
Zero `aboutOwnerBytes` on a fresh-account spawn (sparse profile) is a regression: the upstream resolver returned ok:false with a reason, and the operator should see `coverage-unresolved: <reason>` in the agent's first turn. Zero `dormantPluginsBytes` on a Maxy install with `cloudflare` not enabled is likewise a regression. Zero `pluginManifestBytes` on any account with enabled plugins means the upstream walker failed silently.
|
|
77
81
|
|
|
78
82
|
The manager also runs a boot-time self-test that renders a fixture compose call against synthetic inputs and refuses to start if any sentinel is missing:
|
|
79
83
|
|
|
@@ -70,15 +70,17 @@ There is no dashboard, no settings panel, no menus. Everything is done through c
|
|
|
70
70
|
|
|
71
71
|
The chat input auto-grows as you type — it expands to fit your message and shrinks back when you delete text. You can also drag the resize handle above the input to set a custom height.
|
|
72
72
|
|
|
73
|
-
The admin interface is a three-pane layout: a sidebar on the left with navigation (Sessions, People, Agents, Projects, Tasks, Artefacts) and your recent conversations; the chat in the middle; and an artefact pane on the right that opens when you select a document, click a project, or open Browser, Data, or Graph from the menu, holding the surface side-by-side with the conversation so the chat stays live while you work in it. At the very top of the sidebar — above the nav rows — a borderless row holds two controls: a "+ New session" button on the left that spawns a fresh Claude Code session, and a Mode trigger on the right showing the current permission mode (Ask, Accept edits, Plan, or Auto). The sidebar's vertical order is: new-session strip first, then the nav (Sessions, People, Agents, Projects, Tasks, Artefacts), then the sessions list, then the footer. Both controls render as plain text-plus-icon affordances with no surrounding rectangle
|
|
73
|
+
The admin interface is a three-pane layout: a sidebar on the left with navigation (Sessions, People, Agents, Projects, Tasks, Artefacts) and your recent conversations; the chat in the middle; and an artefact pane on the right that opens when you select a document, click a project, or open Browser, Data, or Graph from the menu, holding the surface side-by-side with the conversation so the chat stays live while you work in it. At the very top of the sidebar — above the nav rows — a borderless row holds two controls: a "+ New session" button on the left that spawns a fresh Claude Code session, and a Mode trigger on the right showing the current permission mode (Ask, Accept edits, Plan, or Auto). The sidebar's vertical order is: new-session strip first, then the nav (Sessions, People, Agents, Projects, Tasks, Artefacts), then the sessions list, then the footer. Both controls render as plain text-plus-icon affordances with no surrounding rectangle. The "+ New session" button is a text-width hit target — its clickable area is exactly the icon plus label, not the whole row — and shows no hover fill; the only hover feedback is the pointer cursor. The Mode trigger is pushed flush to the right edge of the row. Clicking the Mode trigger opens a popover downward from the row whose header reads "Mode" and lists the four permission modes with the current selection check-marked. The sidebar's nav rows swap the list view in place: Sessions shows recent conversations, Projects shows your active work projects, and Artefacts lists every KnowledgeDocument plus this account's agent templates (your admin agent's IDENTITY, SOUL, and KNOWLEDGE files plus one entry per enabled specialist). Each recent session row carries a three-state indicator: three pulsing dots when the session is busy (currently processing a turn), a solid sage dot when it is idle (live PTY waiting for input), and a hollow ring when it is archived (PTY exited, JSONL on disk for audit). The list itself splits into three views via a segmented control above the rows: **Active** shows every live session, **Archived** shows every JSONL on disk whose PTY has exited, and **All** shows both. The view choice persists across reloads. An "Include background" toggle inside the Active view surfaces specialist spawns (the database-operator recorder, premium-plugin agents, anything spawned with a `--agent` flag) which are hidden by default so the list reflects what you started directly. Each row also carries a small uppercase badge — `admin` for operator-driven sessions, the specialist name (for example `db-op`) for background work — so the source of any row is unambiguous at a glance. The People, Agents, and Tasks rows are graph shortcuts: clicking each opens the artefact-pane Graph filtered to every Person, every public Agent, or every Task in your account respectively, with no side-list, because the graph itself is the result. Public agents become first-class graph entities the moment you create them, with edges to their IDENTITY/SOUL/KNOWLEDGE files, edges to every knowledge document they have access to, and edges from every conversation they have handled, so a single Agents click reveals the whole shape of who knows what and who has been talking to whom. Click an artefact row to open the document. KnowledgeDocuments and your admin agent's templates are editable: type in the document and changes save automatically; specialist agent templates are read-only because they ship with Maxy and your edits would be overwritten on the next install. PDF artefacts render inline so you can read them without leaving the pane. If your browser doesn't have a built-in PDF viewer, a Download button appears instead. Artefacts that have no readable file backing them (orphan rows, files removed from disk, unsupported content types) show a one-line banner explaining the skip instead of opening to a blank pane. Click a project row to open the Graph view focused on that project's neighbourhood; clicking a second project swaps the focus rather than stacking on top. The chat and artefact divider is drag-resizable: drag the line between the columns to make either side wider; double-click it to reset to half of the available width (viewport minus sidebar), clamped to the chat and artefact min-width floors. Your chosen width is remembered across reloads. On wider screens (>1280px) all three panes are visible. The sidebar narrows at 1280px, the artefact pane hides at 1080px (Browser, Data, and Graph then open as full-window pages instead), and the sidebar collapses to a 56px icon rail at 820px. On every viewport the chat header reads left to right as a triptych: a dedicated sidebar toggle (the panel-right icon, which swaps to panel-right-open when the sidebar is showing), the brand mark next to the title in the centre, and the menu burger on the right. This header toggle is the sole sidebar-toggle button; the sidebar itself no longer carries a duplicate. Tap the sidebar toggle to show or hide the sidebar: on phones (<720px) it slides the drawer in or out, on wider screens it collapses or expands the sidebar column. The brand mark in the centre is decorative; clicks go through the dedicated toggle so the affordance is unambiguous. The drawer animation only fires on tap (220ms slide in or out); resizing your window across the 720px boundary snaps the layout without animation, so you never see a half-open flash. At ≤640px the session metadata pane stacks each label above its value instead of the desktop two-column grid, and the row of action buttons (Open in new tab / Open JSONL / Rename / Pin / Archive / End or Purge) collapses behind a single Actions trigger that opens a popover upward from the foot of the pane. Breakpoint summary: >1280px = full sidebar + chat + artefact pane (drag-resizable divider); 1280px→1080px = sidebar narrows; 1080px→820px = artefact pane hides (Browser/Data/Graph open as full-window pages instead); 820px→720px = sidebar collapses to 56px icon rail; ≤720px = sidebar becomes off-canvas drawer (vertical stack of nav, recents list, foot, the same shape as the desktop sidebar, just on top of the chat instead of beside it).
|
|
74
74
|
|
|
75
75
|
Page titles are brand-aware: the browser tab shows your product name (e.g. `Real Agent` instead of `Maxy`) on every shell — chat, graph, and data — so a non-default brand never leaks the default name in tab strips or browser history.
|
|
76
76
|
|
|
77
|
-
**Session lifecycle and reconcile model.** The sidebar Sessions list
|
|
77
|
+
**Session lifecycle and reconcile model.** The sidebar Sessions list is driven by a single Server-Sent Events feed at `/api/admin/claude-sessions/events`. The session manager watches the two directories Claude Code writes (`${CLAUDE_CONFIG_DIR}/sessions/<pid>.json` for live state, `${CLAUDE_CONFIG_DIR}/projects/<slug>/<sid>.jsonl` for transcripts) and emits `row-created`, `row-updated`, `row-archived`, or `row-removed` deltas to every connected browser tab. On connect the manager replays the current row index so a freshly-opened tab catches up without polling, then streams deltas as files change on disk. Two open tabs see the same list within ~300ms of any spawn, status flip, or exit; no refresh button required for state to be current. The legacy `/list` fetch and `useAdminSessions` hook stay mounted to serve the ConversationsModal and the post-action reconcile path in `session-actions`, but the sidebar's visible rows come from the row store, not from `/list`. Each EventSource open emits `[admin-events] client-connected ip=<…> seeded-rows=<n>` server-side and `[admin-ui] session-row-store connected events-received=<n>` in the browser console; transport drops log `[admin-ui] session-row-store reconnect attempt=<n>` until the EventSource reattaches.
|
|
78
78
|
|
|
79
|
-
The trade-off is
|
|
79
|
+
The trade-off is a longer-lived connection per tab: the manager's per-process subscriber count rises with open tabs, and the SSE channel must survive proxy idle timeouts. The manager emits a 25-second keep-alive comment line on every connection (ignored by EventSource consumers, refreshes the proxy clock) and the browser-side store force-closes-and-reconnects on transport errors with exponential backoff capped at 30s.
|
|
80
80
|
|
|
81
|
-
**Spawn lifecycle:
|
|
81
|
+
**Spawn lifecycle: PID-file driven.** Clicking "+ New session" spawns the PTY and waits for Claude Code's PID file to appear at `${CLAUDE_CONFIG_DIR}/sessions/<pid>.json`. The PID file lands at process init (for `entrypoint: cli` spawns) and carries the intrinsic `sessionId`, `bridgeSessionId`, `agent`, and `status` directly. The manager's filesystem watcher reports the create event; the spawn response includes the canonical `sessionId` from that file. URL capture still runs in parallel to populate the operator-facing iframe URL, but it no longer gates readiness. The JSONL transcript is written on the first operator turn (true on 2.1.143 and 2.1.128); the watcher fires a separate event for that, and `/list`, `/meta`, `/log` resolve any of four ids — `sessionId`, `bridgeSessionId`, `bridgeSuffix`, or numeric `pid` — to the same row.
|
|
82
|
+
|
|
83
|
+
**Stop vs. delete.** `POST /<id>/stop` sends SIGTERM, leaves the JSONL on disk for audit, and is idempotent against an already-dead row. `DELETE /<id>` removes the JSONL + sidecar + per-session subdir and returns 409 if the PTY is still alive (stop first). Any unknown id returns 404; nothing returns a silent 204 against an id the manager does not know.
|
|
82
84
|
|
|
83
85
|
The metadata pane subscribes to the same /list projection. When an operator clicks End on an alive row, the DELETE returns 200 and the post-mutation refetch decides what happens next: a session that wrote a JSONL surfaces as a dehydrated `status: 'ended'` row (the pane swaps `End session` for `Purge JSONL` plus `Resume`), and a session that never wrote a JSONL (`Turns: 0`) leaves the list entirely (the pane shows a `Session ended without a transcript. Close this pane.` banner with a Close button and no destructive action). The manager's `/list` and `/meta` are the only authorities on post-End state; the client does not pre-empt either response with an optimistic mutation.
|
|
84
86
|
|
|
@@ -122,3 +124,15 @@ When your public agent sends a message to someone — via email, WhatsApp, Teleg
|
|
|
122
124
|
- **SMS:** a brief suffix is appended when the message is AI-composed
|
|
123
125
|
|
|
124
126
|
Messages you write yourself (e.g. typing directly in WhatsApp) are not marked — the disclosure applies only to content composed by the AI agent.
|
|
127
|
+
|
|
128
|
+
## Session Slot Safeguards
|
|
129
|
+
|
|
130
|
+
{{productName}} runs each chat — yours and every visitor's — as a separate `claude` process on your Pi. Three safeguards keep these processes from piling up:
|
|
131
|
+
|
|
132
|
+
- **Specialist cap.** Background specialists (`database-operator`, `content-producer`, etc.) are limited to three running at once. If you ask for a fourth while three are still working, the oldest idle one is shut down first. If all three are actively running, the request is rejected with `specialist-cap-reached`.
|
|
133
|
+
- **Operator reserve.** Two slots are always held back for *you* — your own chats and one-off tasks. Specialist work that would consume the last reserved slot is rejected with `operator-slots-reserved`. Your interactive chats are never blocked.
|
|
134
|
+
- **Idle reaper.** Every 30 seconds the platform looks for specialist processes that started, then went silent without producing any output. After two minutes of silence the platform shuts them down.
|
|
135
|
+
|
|
136
|
+
All three are tunable via env vars (`CLAUDE_SESSION_MANAGER_SPECIALIST_CAP`, `CLAUDE_SESSION_MANAGER_OPERATOR_RESERVE`, `CLAUDE_SESSION_MANAGER_TOTAL_PTY_CAP`, `CLAUDE_SESSION_MANAGER_RECORDER_IDLE_TTL_MS`); developer details in `.docs/platform.md` § "Claude Session Manager — PTY Slot Safeguards".
|
|
137
|
+
|
|
138
|
+
If you suspect background processes are piling up, run `grep '\[reaper\]' ~/.{brand}/logs/server.log | tail -50` — each tick logs how many rows it scanned and reaped.
|
|
@@ -141,6 +141,8 @@ initStderrTee("your-plugin-name");
|
|
|
141
141
|
|
|
142
142
|
After this, every `console.error("[your-tool]...")` from any tool in the plugin appears as `[<iso-ts>] [mcp:your-plugin-name] [your-tool]...` in the per-conversation stream log `claude-agent-stream-{conversationId}.log`, alongside the usual agent events. The raw per-server file `mcp-your-plugin-name-stderr-{date}.log` is still produced for deep-dive grep.
|
|
143
143
|
|
|
144
|
+
**Premium plugins.** Source lives at `premium-plugins/<bundle>/plugins/<name>/mcp/src/` — deeper than platform plugins, so the source-relative import to `platform/lib/mcp-stderr-tee/dist/index.js` uses more `../` segments. The bundler rewrites the compiled output to the canonical `../../../../lib/mcp-stderr-tee/dist/index.js` at staging time and ships `platform/lib/mcp-stderr-tee/{dist,package.json}` into `premium-plugins/<bundle>/lib/mcp-stderr-tee/` so the import resolves at deployed depth. The bundler fails loudly if `platform/lib/mcp-stderr-tee/package.json` is missing (it must pin `type` so install-location parent walks cannot mis-classify the dist file) or if any lib referenced by a rewritten import has no source dist.
|
|
145
|
+
|
|
144
146
|
**How the tee decides which file to write to:** the platform sets `STREAM_LOG_PATH` as an environment variable on every MCP server spawn, pointing to the conversation-scoped stream log. The MCP server does not know about conversations — it just trusts `STREAM_LOG_PATH`. Multiple concurrent conversations produce multiple concurrent MCP server processes, each teeing to its own file; no cross-conversation leakage.
|
|
145
147
|
|
|
146
148
|
**`STREAM_LOG_PATH` reaches every Claude Code child.** The platform now sets `STREAM_LOG_PATH` on the parent `claude` spawn env itself (not only on MCP server envs), so the bundled Bun runtime inherits it and every Bash-tool subprocess the CLI spawns sees it too. Opt-in shell scripts — currently `setup-tunnel.sh`, `reset-tunnel.sh`, and `list-cf-domains.sh` under `platform/plugins/cloudflare/scripts/` — read the variable, guard against a missing value with a loud exit, and tee subprocess output line-by-line into the same per-conversation file. Each spawn writes one `[spawn-env] STREAM_LOG_PATH=set pid=… conversationId=… site=…` line so the env-propagation is auditable per session. The chat UI tails the same file for lines matching `^\[([^\]]+)\] \[([a-z][a-z0-9-]*)((?::[a-z0-9:_-]+)?)\] ` — any lowercase scope shape participates on first write (earlier platform fixes generalised from the pre-592 enum `setup-tunnel|reset-tunnel`) — and emits them as `script_stream` SSE events; see `.docs/web-chat.md` for the contract. Inner-layer helpers that a.sh wrapper spawns (e.g. `list-cf-domains.ts` via `node --experimental-strip-types`) must write phase lines directly to `STREAM_LOG_PATH` rather than relying on stderr propagation; the build-gate `platform/ui/scripts/check-stream-log-contract.mjs` enforces this and is the definitive reference for the three allowed patterns (tee-wrapped, direct-write, or explicit stderr-only marker).
|
|
@@ -14,6 +14,23 @@ export interface ManagerConfig {
|
|
|
14
14
|
urlCaptureTimeoutMs: number;
|
|
15
15
|
killGraceMs: number;
|
|
16
16
|
jsonlReadMaxBytes: number;
|
|
17
|
+
/** Per-account concurrent specialist (`--agent`) PTYs. (N+1)th attempt
|
|
18
|
+
* evicts the oldest idle specialist; rejects 503 if none are idle.
|
|
19
|
+
* Env override: `CLAUDE_SESSION_MANAGER_SPECIALIST_CAP`. Default 3. */
|
|
20
|
+
specialistCap: number;
|
|
21
|
+
/** Slots reserved for operator (non-specialist) spawns. Specialist
|
|
22
|
+
* spawns are rejected with 503 `operator-slots-reserved` once
|
|
23
|
+
* `currentTotalLive >= totalPtyCap - operatorReserve`. Env:
|
|
24
|
+
* `CLAUDE_SESSION_MANAGER_OPERATOR_RESERVE`. Default 2. */
|
|
25
|
+
operatorReserve: number;
|
|
26
|
+
/** Hard ceiling on concurrent PTYs the manager will hold open. Taken
|
|
27
|
+
* as the min of `/proc/sys/kernel/pty/max` (Linux only; absent on
|
|
28
|
+
* Darwin) and `CLAUDE_SESSION_MANAGER_TOTAL_PTY_CAP` (default 64). */
|
|
29
|
+
totalPtyCap: number;
|
|
30
|
+
/** Reaper TTL: a specialist row with `status: idle` and no JSONL whose
|
|
31
|
+
* `updatedAt` is older than this is SIGTERMed. Env:
|
|
32
|
+
* `CLAUDE_SESSION_MANAGER_RECORDER_IDLE_TTL_MS`. Default 120 000. */
|
|
33
|
+
recorderIdleTtlMs: number;
|
|
17
34
|
host: HostResolution;
|
|
18
35
|
/** per-account directory resolved at boot. Mirrors the
|
|
19
36
|
* installer's `resolveInstallAccountId` walk: the first sub-directory of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAA;AAGhC,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD;;4DAEwD;IACxD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;IACzB,IAAI,EAAE,cAAc,CAAA;IACpB;;;;;;;8BAO0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB;;;qDAGiD;IACjD,iBAAiB,EAAE,iBAAiB,CAAA;CACrC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAA;AAGhC,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD;;4DAEwD;IACxD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;IACzB;;4EAEwE;IACxE,aAAa,EAAE,MAAM,CAAA;IACrB;;;gEAG4D;IAC5D,eAAe,EAAE,MAAM,CAAA;IACvB;;2EAEuE;IACvE,WAAW,EAAE,MAAM,CAAA;IACnB;;0EAEsE;IACtE,iBAAiB,EAAE,MAAM,CAAA;IACzB,IAAI,EAAE,cAAc,CAAA;IACpB;;;;;;;8BAO0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB;;;qDAGiD;IACjD,iBAAiB,EAAE,iBAAiB,CAAA;CACrC;AA4KD,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,aAAa,CA4E9E"}
|
|
@@ -7,6 +7,28 @@ const DEFAULT_URL_TIMEOUT_MS = 30_000;
|
|
|
7
7
|
const DEFAULT_KILL_GRACE_MS = 5_000;
|
|
8
8
|
const DEFAULT_JSONL_READ_MAX_BYTES = 1 * 1024 * 1024;
|
|
9
9
|
const DEFAULT_BRAND_PORT = 19200;
|
|
10
|
+
const DEFAULT_SPECIALIST_CAP = 3;
|
|
11
|
+
const DEFAULT_OPERATOR_RESERVE = 2;
|
|
12
|
+
const DEFAULT_TOTAL_PTY_CAP = 64;
|
|
13
|
+
const DEFAULT_RECORDER_IDLE_TTL_MS = 120_000;
|
|
14
|
+
const PTY_MAX_PATH = '/proc/sys/kernel/pty/max';
|
|
15
|
+
function parsePositiveInt(raw, fallback) {
|
|
16
|
+
if (raw === undefined)
|
|
17
|
+
return fallback;
|
|
18
|
+
const n = Number(raw);
|
|
19
|
+
return Number.isInteger(n) && n > 0 ? n : fallback;
|
|
20
|
+
}
|
|
21
|
+
function readKernelPtyMax() {
|
|
22
|
+
try {
|
|
23
|
+
const raw = readFileSync(PTY_MAX_PATH, 'utf-8').trim();
|
|
24
|
+
const n = Number(raw);
|
|
25
|
+
return Number.isInteger(n) && n > 0 ? n : Number.POSITIVE_INFINITY;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Darwin (dev) / sysctl absent → no kernel-derived ceiling. Env cap holds.
|
|
29
|
+
return Number.POSITIVE_INFINITY;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
10
32
|
const CHANNELS_FOR_LIMITS = [
|
|
11
33
|
'browser',
|
|
12
34
|
'whatsapp',
|
|
@@ -146,7 +168,6 @@ export function loadConfig(env = process.env) {
|
|
|
146
168
|
}
|
|
147
169
|
const persistDir = env.CLAUDE_SESSION_MANAGER_PERSIST_DIR ?? join(homedir(), '.maxy');
|
|
148
170
|
const claudeBin = env.CLAUDE_BIN ?? 'claude';
|
|
149
|
-
const spawnCwd = env.CLAUDE_SESSION_MANAGER_SPAWN_CWD ?? process.cwd();
|
|
150
171
|
const brand = loadBrand(env);
|
|
151
172
|
const platformRoot = env.PLATFORM_ROOT ?? env.MAXY_PLATFORM_ROOT;
|
|
152
173
|
if (!platformRoot) {
|
|
@@ -159,6 +180,12 @@ export function loadConfig(env = process.env) {
|
|
|
159
180
|
throw new Error(`[claude-session-manager] account-dir-unresolved: no <installDir>/data/accounts/<uuid>/account.json under ${dirname(platformRoot)}/data/accounts. ` +
|
|
160
181
|
'The installer (seed-neo4j.sh / writeInstallDefaults) must run before manager start.');
|
|
161
182
|
}
|
|
183
|
+
// Claude Code walks `.claude/settings.json` from cwd to .git root. Defaulting
|
|
184
|
+
// spawnCwd to process.cwd() — i.e. the manager service directory — strands
|
|
185
|
+
// the account-scoped settings.json (and its Stop hook) outside that walk.
|
|
186
|
+
// Default to accountDir so seed-neo4j.sh's `<accountDir>/.claude/settings.json`
|
|
187
|
+
// is on the discovery path. Env-var override is preserved for tests.
|
|
188
|
+
const spawnCwd = env.CLAUDE_SESSION_MANAGER_SPAWN_CWD ?? accountDir;
|
|
162
189
|
const lan = resolveLanIPv4();
|
|
163
190
|
const brandPort = resolveBrandPort(env);
|
|
164
191
|
const osHost = hostname();
|
|
@@ -178,6 +205,11 @@ export function loadConfig(env = process.env) {
|
|
|
178
205
|
// the manager renders `tunnel-url: none` rather than fabricating an FQDN
|
|
179
206
|
// for a tunnel that may not exist.
|
|
180
207
|
const tunnelUrl = null;
|
|
208
|
+
const specialistCap = parsePositiveInt(env.CLAUDE_SESSION_MANAGER_SPECIALIST_CAP, DEFAULT_SPECIALIST_CAP);
|
|
209
|
+
const operatorReserve = parsePositiveInt(env.CLAUDE_SESSION_MANAGER_OPERATOR_RESERVE, DEFAULT_OPERATOR_RESERVE);
|
|
210
|
+
const envTotalCap = parsePositiveInt(env.CLAUDE_SESSION_MANAGER_TOTAL_PTY_CAP, DEFAULT_TOTAL_PTY_CAP);
|
|
211
|
+
const totalPtyCap = Math.min(readKernelPtyMax(), envTotalCap);
|
|
212
|
+
const recorderIdleTtlMs = parsePositiveInt(env.CLAUDE_SESSION_MANAGER_RECORDER_IDLE_TTL_MS, DEFAULT_RECORDER_IDLE_TTL_MS);
|
|
181
213
|
return {
|
|
182
214
|
port,
|
|
183
215
|
persistDir,
|
|
@@ -186,6 +218,10 @@ export function loadConfig(env = process.env) {
|
|
|
186
218
|
urlCaptureTimeoutMs: DEFAULT_URL_TIMEOUT_MS,
|
|
187
219
|
killGraceMs: DEFAULT_KILL_GRACE_MS,
|
|
188
220
|
jsonlReadMaxBytes: DEFAULT_JSONL_READ_MAX_BYTES,
|
|
221
|
+
specialistCap,
|
|
222
|
+
operatorReserve,
|
|
223
|
+
totalPtyCap,
|
|
224
|
+
recorderIdleTtlMs,
|
|
189
225
|
host: {
|
|
190
226
|
hostname: osHost,
|
|
191
227
|
lanIPv4: lan.ip,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC,OAAO,EACL,2BAA2B,GAG5B,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Logger } from './types.js';
|
|
2
|
+
export type RowState = 'live' | 'archived';
|
|
3
|
+
export type RowStatus = 'idle' | 'busy' | 'gone';
|
|
4
|
+
export interface SessionRow {
|
|
5
|
+
/** Intrinsic Claude session id (UUID). Canonical key. */
|
|
6
|
+
sessionId: string;
|
|
7
|
+
/** Full bridge session id ("session_<suffix>") from PID file, or null. */
|
|
8
|
+
bridgeSessionId: string | null;
|
|
9
|
+
/** Suffix only (no "session_" prefix). Derived from bridgeSessionId. */
|
|
10
|
+
bridgeSuffix: string | null;
|
|
11
|
+
/** Specialist agent name from PID file (`--agent <name>`), or null.
|
|
12
|
+
* Always null on archived rows — PID file is gone by then. */
|
|
13
|
+
agent: string | null;
|
|
14
|
+
/** Specialist agent name cached from the first JSONL `agent-setting`
|
|
15
|
+
* record (read once at row-archive transition or boot-seed of an
|
|
16
|
+
* archived row). Null when the JSONL has no `agent-setting` record
|
|
17
|
+
* (operator-driven session). UI's resolveAgentLabel falls back to
|
|
18
|
+
* this when `agent` is null. */
|
|
19
|
+
cachedAgentSetting: string | null;
|
|
20
|
+
cwd: string | null;
|
|
21
|
+
pid: number | null;
|
|
22
|
+
jsonlPath: string | null;
|
|
23
|
+
pidFilePath: string | null;
|
|
24
|
+
state: RowState;
|
|
25
|
+
status: RowStatus;
|
|
26
|
+
/** ms epoch from PID file `updatedAt`/`startedAt`, or 0 if unknown. */
|
|
27
|
+
updatedAt: number;
|
|
28
|
+
}
|
|
29
|
+
export interface WatcherEvent {
|
|
30
|
+
kind: 'create' | 'modify' | 'delete';
|
|
31
|
+
source: 'pid' | 'jsonl';
|
|
32
|
+
row: SessionRow | null;
|
|
33
|
+
sessionId: string;
|
|
34
|
+
}
|
|
35
|
+
export type Subscriber = (event: WatcherEvent) => void;
|
|
36
|
+
export interface FsWatcher {
|
|
37
|
+
bootSeed(): void;
|
|
38
|
+
arm(): void;
|
|
39
|
+
subscribe(sub: Subscriber): () => void;
|
|
40
|
+
getBySessionId(id: string): SessionRow | undefined;
|
|
41
|
+
getByBridgeSessionId(id: string): SessionRow | undefined;
|
|
42
|
+
getByBridgeSuffix(suffix: string): SessionRow | undefined;
|
|
43
|
+
getByPid(pid: number): SessionRow | undefined;
|
|
44
|
+
all(): SessionRow[];
|
|
45
|
+
/** Resolve once a PID-file event lands for `pid`. Rejects on `timeoutMs`. */
|
|
46
|
+
waitForPid(pid: number, timeoutMs: number): Promise<SessionRow>;
|
|
47
|
+
close(): void;
|
|
48
|
+
}
|
|
49
|
+
export declare function createFsWatcher(opts: {
|
|
50
|
+
sessionsDir: string;
|
|
51
|
+
projectsDir: string;
|
|
52
|
+
logger: Logger;
|
|
53
|
+
}): FsWatcher;
|
|
54
|
+
//# sourceMappingURL=fs-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-watcher.d.ts","sourceRoot":"","sources":["../src/fs-watcher.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAsCxC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAA;AAC1C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAEhD,MAAM,WAAW,UAAU;IACzB,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAA;IACjB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,wEAAwE;IACxE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B;mEAC+D;IAC/D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB;;;;qCAIiC;IACjC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,SAAS,CAAA;IACjB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACpC,MAAM,EAAE,KAAK,GAAG,OAAO,CAAA;IACvB,GAAG,EAAE,UAAU,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;AAEtD,MAAM,WAAW,SAAS;IACxB,QAAQ,IAAI,IAAI,CAAA;IAChB,GAAG,IAAI,IAAI,CAAA;IACX,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,IAAI,CAAA;IACtC,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;IAClD,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;IACxD,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;IACzD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;IAC7C,GAAG,IAAI,UAAU,EAAE,CAAA;IACnB,6EAA6E;IAC7E,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IAC/D,KAAK,IAAI,IAAI,CAAA;CACd;AA0DD,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf,GAAG,SAAS,CAyVZ"}
|