@svenroth-ai/shipwright 0.28.0 → 0.29.1
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/client/dist/apple-touch-icon.png +0 -0
- package/client/dist/assets/{EmbeddedTerminal-4xgNUBUu.js → EmbeddedTerminal-BXosRYLy.js} +30 -30
- package/client/dist/assets/{abnfDiagram-VRR7QNED-BdCNbaqc.js → abnfDiagram-VCTEODGH-BGxuVEiU.js} +1 -1
- package/client/dist/assets/arc-o82bcJs8.js +1 -0
- package/client/dist/assets/architectureDiagram-5GKGNRK7-CaeUIM7e.js +36 -0
- package/client/dist/assets/blockDiagram-I7D4REHJ-DtWpTjgT.js +129 -0
- package/client/dist/assets/c4Diagram-7LVT6UL2-sJULbaUv.js +38 -0
- package/client/dist/assets/channel-CLBQbfQb.js +1 -0
- package/client/dist/assets/{chunk-2Q5K7J3B-4N6AnmBJ.js → chunk-2Q5K7J3B-CPeH4xHb.js} +1 -1
- package/client/dist/assets/{chunk-5VM5RSS4-Bwd7rtD3.js → chunk-5VM5RSS4-DxiKB3qZ.js} +1 -1
- package/client/dist/assets/{chunk-32BRIVSS-Cs67LiCy.js → chunk-F27PBJKO-B8V1zhCX.js} +1 -1
- package/client/dist/assets/{chunk-EX3LRPZG-CQqGfptD.js → chunk-IMKFNOWR-BtXet829.js} +5 -5
- package/client/dist/assets/{chunk-JWPE2WC7-ClvKd4PN.js → chunk-JWPE2WC7-BaQYKssR.js} +1 -1
- package/client/dist/assets/chunk-POPQ4Y6H-I1x_vfH3.js +1 -0
- package/client/dist/assets/{chunk-MOJQB5TN-Cwvj8GE1.js → chunk-SVP7TREG-Bvt8jrSp.js} +1 -1
- package/client/dist/assets/{chunk-V7JOEXUC-CYFfa4PY.js → chunk-TICWLB2K--9ywNq1F.js} +1 -1
- package/client/dist/assets/{chunk-XXDRQBXY-BQAZ6Our.js → chunk-XXDRQBXY-DrIyrBs1.js} +1 -1
- package/client/dist/assets/classDiagram-ZZMXUADV-D8z-o3xu.js +1 -0
- package/client/dist/assets/classDiagram-v2-VYDZK3BY-D8z-o3xu.js +1 -0
- package/client/dist/assets/{cose-bilkent-JH36ORCC-C76Yia6h.js → cose-bilkent-JH36ORCC-DISm8_p0.js} +1 -1
- package/client/dist/assets/{cynefin-VYW2F7L2-pJe7rdTi.js → cynefin-OW5HDTMX-wyDjqucU.js} +3 -3
- package/client/dist/assets/{cynefinDiagram-TSTJHNR4-EeHQ7dYV.js → cynefinDiagram-5FMLGOSQ-CN-IKDQ6.js} +1 -1
- package/client/dist/assets/dagre-GXQ25YYZ-QY0m5eSL.js +4 -0
- package/client/dist/assets/diagram-S7CK7UJ4-DhjaAe2g.js +30 -0
- package/client/dist/assets/diagram-UQ7AKVKN-D-3R3axg.js +41 -0
- package/client/dist/assets/{diagram-FQU43EPY-DW_-leqw.js → diagram-VSXAHHWV-BxXEtjRu.js} +2 -2
- package/client/dist/assets/{diagram-G47NLZAW-C_hsLD4u.js → diagram-VX7I27RA-DkbXkJpd.js} +1 -1
- package/client/dist/assets/{diagram-NH7WQ7WH-CbeQuO_f.js → diagram-Z3DM3KII-DQGRD9gQ.js} +1 -1
- package/client/dist/assets/{ebnfDiagram-CCIWWBDH-B8Z8WHF6.js → ebnfDiagram-PWID7BFC-C_XxskCm.js} +1 -1
- package/client/dist/assets/erDiagram-RLTQ6QDP-BhBsYQ7c.js +99 -0
- package/client/dist/assets/flowDiagram-HODETNUW-D7fXEPrM.js +168 -0
- package/client/dist/assets/{ganttDiagram-NO4QXBWP-K3X0DYBa.js → ganttDiagram-EL5Y4UJY-Bwf8EtWr.js} +4 -4
- package/client/dist/assets/{gitGraphDiagram-IHSO6WYX-B2SEx0xa.js → gitGraphDiagram-WWUBYQGX-C3_ixsOl.js} +1 -1
- package/client/dist/assets/index-DWrPE3aq.css +1 -0
- package/client/dist/assets/index-DwRlIUrK.js +924 -0
- package/client/dist/assets/infoDiagram-27XIBGKW-BpcHmgOL.js +2 -0
- package/client/dist/assets/{ishikawaDiagram-FXEZZL3T-CrN7QJzt.js → ishikawaDiagram-5VMMS53U-DzSGmhT5.js} +4 -4
- package/client/dist/assets/{journeyDiagram-5HDEW3XC-XHIsl7rM.js → journeyDiagram-3NMN7TZE-CT1CrVQO.js} +2 -2
- package/client/dist/assets/{kanban-definition-HUTT4EX6-A6HJqHw7.js → kanban-definition-UXKFOSKX-N1CNMAOm.js} +8 -8
- package/client/dist/assets/katex-C5jXJg4s.js +257 -0
- package/client/dist/assets/layout-CR8gdfo4.js +1 -0
- package/client/dist/assets/{linear-D1vF9IQB.js → linear-CfLRjQgX.js} +1 -1
- package/client/dist/assets/mermaid.core-Bnqt31Q7.js +312 -0
- package/client/dist/assets/{mindmap-definition-LN4V7U3C-CxRkUj6Z.js → mindmap-definition-YA3MSWOX-Brc-v1M4.js} +2 -2
- package/client/dist/assets/{pegDiagram-2B236MQR-Bs9dp-8a.js → pegDiagram-XKGWAZYB-D8jUV01U.js} +1 -1
- package/client/dist/assets/{pieDiagram-ENE6RG2P-DBWILzB8.js → pieDiagram-E7YTZNPT-BiSkIsrz.js} +3 -3
- package/client/dist/assets/{quadrantDiagram-ABIIQ3AL-DrCVJJx6.js → quadrantDiagram-AXDQQJYC-CJetqQxd.js} +1 -1
- package/client/dist/assets/{railroadDiagram-RFXS5EU6-BdPW2dNf.js → railroadDiagram-O6MQD6OU-DTTtZpGO.js} +1 -1
- package/client/dist/assets/{requirementDiagram-TGXJPOKE-Bj_g3tC5.js → requirementDiagram-BXWQKSXE-meFCoLtR.js} +5 -5
- package/client/dist/assets/{sankeyDiagram-HTMAVEWB-BGL9NnsS.js → sankeyDiagram-P5KCCOFB-BR9eN4Do.js} +4 -4
- package/client/dist/assets/{sequenceDiagram-DBY2YBRQ-DEirxTZY.js → sequenceDiagram-WJ2MYXX4-BdVzFsCC.js} +1 -1
- package/client/dist/assets/{sizeCapture-X5ZJPWSS-BtLrvrea.js → sizeCapture-INFHLROL-CZoZ7r-1.js} +1 -1
- package/client/dist/assets/stateDiagram-D77RDMKH-Cmc-iYtm.js +1 -0
- package/client/dist/assets/stateDiagram-v2-MP3YSRHH-Cj-hQ4qB.js +1 -0
- package/client/dist/assets/swimlanes-42K2YHIH-DN4MssUX.js +1 -0
- package/client/dist/assets/swimlanesDiagram-VR7AAH4N-DFxrYFKF.js +8 -0
- package/client/dist/assets/{timeline-definition-FHXFAJF6-CnBKJtD_.js → timeline-definition-24CTP7MA-pxxqlxwt.js} +3 -3
- package/client/dist/assets/{vennDiagram-L72KCM5P-BYmiJYoh.js → vennDiagram-4TSXK5OY-DiItNcze.js} +5 -5
- package/client/dist/assets/{wardleyDiagram-EHGQE667-DU7vW8q3.js → wardleyDiagram-VM6X3IG4-Dfvub75z.js} +1 -1
- package/client/dist/assets/xychartDiagram-S5SC5T6Z-Bx83X515.js +7 -0
- package/client/dist/favicon-16.png +0 -0
- package/client/dist/favicon-32.png +0 -0
- package/client/dist/icon-192.png +0 -0
- package/client/dist/icon-512.png +0 -0
- package/client/dist/icon-maskable-512.png +0 -0
- package/client/dist/index.html +11 -2
- package/client/dist/manifest.json +13 -0
- package/package.json +2 -2
- package/server/dist/config.d.ts.map +1 -1
- package/server/dist/config.js +7 -2
- package/server/dist/config.js.map +1 -1
- package/server/dist/core/adopt-scan-findings.d.ts +12 -0
- package/server/dist/core/adopt-scan-findings.d.ts.map +1 -0
- package/server/dist/core/adopt-scan-findings.js +96 -0
- package/server/dist/core/adopt-scan-findings.js.map +1 -0
- package/server/dist/core/adopt-scan.d.ts +49 -0
- package/server/dist/core/adopt-scan.d.ts.map +1 -0
- package/server/dist/core/adopt-scan.js +201 -0
- package/server/dist/core/adopt-scan.js.map +1 -0
- package/server/dist/core/custom-profile-command-policy.d.ts +6 -0
- package/server/dist/core/custom-profile-command-policy.d.ts.map +1 -0
- package/server/dist/core/custom-profile-command-policy.js +110 -0
- package/server/dist/core/custom-profile-command-policy.js.map +1 -0
- package/server/dist/core/custom-profile-loader.d.ts +34 -0
- package/server/dist/core/custom-profile-loader.d.ts.map +1 -0
- package/server/dist/core/custom-profile-loader.js +225 -0
- package/server/dist/core/custom-profile-loader.js.map +1 -0
- package/server/dist/core/preview-child-lifecycle.d.ts +7 -2
- package/server/dist/core/preview-child-lifecycle.d.ts.map +1 -1
- package/server/dist/core/preview-child-lifecycle.js +17 -5
- package/server/dist/core/preview-child-lifecycle.js.map +1 -1
- package/server/dist/core/preview-session-manager.d.ts +1 -0
- package/server/dist/core/preview-session-manager.d.ts.map +1 -1
- package/server/dist/core/preview-session-manager.js +2 -2
- package/server/dist/core/preview-session-manager.js.map +1 -1
- package/server/dist/core/project-actions-loader.d.ts +13 -0
- package/server/dist/core/project-actions-loader.d.ts.map +1 -1
- package/server/dist/core/project-actions-loader.js +28 -6
- package/server/dist/core/project-actions-loader.js.map +1 -1
- package/server/dist/core/project-data-dir.d.ts +41 -0
- package/server/dist/core/project-data-dir.d.ts.map +1 -0
- package/server/dist/core/project-data-dir.js +64 -0
- package/server/dist/core/project-data-dir.js.map +1 -0
- package/server/dist/core/project-data-migrate.d.ts +14 -0
- package/server/dist/core/project-data-migrate.d.ts.map +1 -0
- package/server/dist/core/project-data-migrate.js +94 -0
- package/server/dist/core/project-data-migrate.js.map +1 -0
- package/server/dist/core/project-manager.d.ts.map +1 -1
- package/server/dist/core/project-manager.js +9 -10
- package/server/dist/core/project-manager.js.map +1 -1
- package/server/dist/core/session-file/access.d.ts +26 -0
- package/server/dist/core/session-file/access.d.ts.map +1 -0
- package/server/dist/core/session-file/access.js +143 -0
- package/server/dist/core/session-file/access.js.map +1 -0
- package/server/dist/core/session-file/asset-access.d.ts +15 -0
- package/server/dist/core/session-file/asset-access.d.ts.map +1 -0
- package/server/dist/core/session-file/asset-access.js +141 -0
- package/server/dist/core/session-file/asset-access.js.map +1 -0
- package/server/dist/core/session-file/evidence.d.ts +25 -0
- package/server/dist/core/session-file/evidence.d.ts.map +1 -0
- package/server/dist/core/session-file/evidence.js +201 -0
- package/server/dist/core/session-file/evidence.js.map +1 -0
- package/server/dist/core/session-file/probe.d.ts +16 -0
- package/server/dist/core/session-file/probe.d.ts.map +1 -0
- package/server/dist/core/session-file/probe.js +63 -0
- package/server/dist/core/session-file/probe.js.map +1 -0
- package/server/dist/core/session-file/safe-read.d.ts +33 -0
- package/server/dist/core/session-file/safe-read.d.ts.map +1 -0
- package/server/dist/core/session-file/safe-read.js +103 -0
- package/server/dist/core/session-file/safe-read.js.map +1 -0
- package/server/dist/core/session-file/sensitive.d.ts +5 -0
- package/server/dist/core/session-file/sensitive.d.ts.map +1 -0
- package/server/dist/core/session-file/sensitive.js +52 -0
- package/server/dist/core/session-file/sensitive.js.map +1 -0
- package/server/dist/core/session-info/collect.d.ts +70 -0
- package/server/dist/core/session-info/collect.d.ts.map +1 -0
- package/server/dist/core/session-info/collect.js +248 -0
- package/server/dist/core/session-info/collect.js.map +1 -0
- package/server/dist/core/session-info/line-scan.d.ts +20 -0
- package/server/dist/core/session-info/line-scan.d.ts.map +1 -0
- package/server/dist/core/session-info/line-scan.js +109 -0
- package/server/dist/core/session-info/line-scan.js.map +1 -0
- package/server/dist/core/session-info/remote-control.d.ts +9 -0
- package/server/dist/core/session-info/remote-control.d.ts.map +1 -0
- package/server/dist/core/session-info/remote-control.js +64 -0
- package/server/dist/core/session-info/remote-control.js.map +1 -0
- package/server/dist/core/session-info/session-info.d.ts +18 -0
- package/server/dist/core/session-info/session-info.d.ts.map +1 -0
- package/server/dist/core/session-info/session-info.js +170 -0
- package/server/dist/core/session-info/session-info.js.map +1 -0
- package/server/dist/core/session-info/small-file.d.ts +2 -0
- package/server/dist/core/session-info/small-file.d.ts.map +1 -0
- package/server/dist/core/session-info/small-file.js +42 -0
- package/server/dist/core/session-info/small-file.js.map +1 -0
- package/server/dist/core/session-info/subagent-transcript.d.ts +12 -0
- package/server/dist/core/session-info/subagent-transcript.d.ts.map +1 -0
- package/server/dist/core/session-info/subagent-transcript.js +78 -0
- package/server/dist/core/session-info/subagent-transcript.js.map +1 -0
- package/server/dist/core/session-info/subagents.d.ts +14 -0
- package/server/dist/core/session-info/subagents.d.ts.map +1 -0
- package/server/dist/core/session-info/subagents.js +92 -0
- package/server/dist/core/session-info/subagents.js.map +1 -0
- package/server/dist/core/session-info/test-fixtures.d.ts +50 -0
- package/server/dist/core/session-info/test-fixtures.d.ts.map +1 -0
- package/server/dist/core/session-info/test-fixtures.js +43 -0
- package/server/dist/core/session-info/test-fixtures.js.map +1 -0
- package/server/dist/core/session-info/types.d.ts +77 -0
- package/server/dist/core/session-info/types.d.ts.map +1 -0
- package/server/dist/core/session-info/types.js +14 -0
- package/server/dist/core/session-info/types.js.map +1 -0
- package/server/dist/core/stack-profiles-create.d.ts +31 -0
- package/server/dist/core/stack-profiles-create.d.ts.map +1 -0
- package/server/dist/core/stack-profiles-create.js +128 -0
- package/server/dist/core/stack-profiles-create.js.map +1 -0
- package/server/dist/core/stack-profiles.d.ts +49 -0
- package/server/dist/core/stack-profiles.d.ts.map +1 -0
- package/server/dist/core/stack-profiles.js +142 -0
- package/server/dist/core/stack-profiles.js.map +1 -0
- package/server/dist/external/_shared/helpers.d.ts +2 -0
- package/server/dist/external/_shared/helpers.d.ts.map +1 -1
- package/server/dist/external/_shared/helpers.js.map +1 -1
- package/server/dist/external/actions/get.d.ts +3 -1
- package/server/dist/external/actions/get.d.ts.map +1 -1
- package/server/dist/external/actions/get.js +15 -4
- package/server/dist/external/actions/get.js.map +1 -1
- package/server/dist/external/actions/routes.d.ts +3 -1
- package/server/dist/external/actions/routes.d.ts.map +1 -1
- package/server/dist/external/actions/routes.js.map +1 -1
- package/server/dist/external/actions/stub.d.ts.map +1 -1
- package/server/dist/external/actions/stub.js +15 -4
- package/server/dist/external/actions/stub.js.map +1 -1
- package/server/dist/external/actions/upload-delete.d.ts.map +1 -1
- package/server/dist/external/actions/upload-delete.js +30 -20
- package/server/dist/external/actions/upload-delete.js.map +1 -1
- package/server/dist/external/actions/upload.d.ts.map +1 -1
- package/server/dist/external/actions/upload.js +5 -4
- package/server/dist/external/actions/upload.js.map +1 -1
- package/server/dist/external/create-external-routes-args.d.ts +3 -1
- package/server/dist/external/create-external-routes-args.d.ts.map +1 -1
- package/server/dist/external/inbox/_phase-gate.d.ts +9 -0
- package/server/dist/external/inbox/_phase-gate.d.ts.map +1 -0
- package/server/dist/external/inbox/_phase-gate.js +87 -0
- package/server/dist/external/inbox/_phase-gate.js.map +1 -0
- package/server/dist/external/inbox/_types.d.ts +7 -0
- package/server/dist/external/inbox/_types.d.ts.map +1 -1
- package/server/dist/external/inbox/routes.d.ts.map +1 -1
- package/server/dist/external/inbox/routes.js +2 -0
- package/server/dist/external/inbox/routes.js.map +1 -1
- package/server/dist/external/launch/action-substitution-branch.js +2 -2
- package/server/dist/external/launch/action-substitution-branch.js.map +1 -1
- package/server/dist/external/mission-context/facts.js +2 -2
- package/server/dist/external/mission-context/facts.js.map +1 -1
- package/server/dist/external/preview/routes.d.ts +3 -1
- package/server/dist/external/preview/routes.d.ts.map +1 -1
- package/server/dist/external/preview/routes.js +8 -1
- package/server/dist/external/preview/routes.js.map +1 -1
- package/server/dist/external/routes.d.ts.map +1 -1
- package/server/dist/external/routes.js +2 -2
- package/server/dist/external/routes.js.map +1 -1
- package/server/dist/external/session-file/probe-route.d.ts +4 -0
- package/server/dist/external/session-file/probe-route.d.ts.map +1 -0
- package/server/dist/external/session-file/probe-route.js +66 -0
- package/server/dist/external/session-file/probe-route.js.map +1 -0
- package/server/dist/external/session-file/routes.d.ts +12 -0
- package/server/dist/external/session-file/routes.d.ts.map +1 -0
- package/server/dist/external/session-file/routes.js +90 -0
- package/server/dist/external/session-file/routes.js.map +1 -0
- package/server/dist/external/session-file/session-file.fixture.d.ts +45 -0
- package/server/dist/external/session-file/session-file.fixture.d.ts.map +1 -0
- package/server/dist/external/session-file/session-file.fixture.js +41 -0
- package/server/dist/external/session-file/session-file.fixture.js.map +1 -0
- package/server/dist/external/session-info/routes.d.ts +15 -0
- package/server/dist/external/session-info/routes.d.ts.map +1 -0
- package/server/dist/external/session-info/routes.js +57 -0
- package/server/dist/external/session-info/routes.js.map +1 -0
- package/server/dist/external/tasks/_phase-helpers.js +2 -2
- package/server/dist/external/tasks/_phase-helpers.js.map +1 -1
- package/server/dist/external/tasks/create.js +2 -2
- package/server/dist/external/tasks/create.js.map +1 -1
- package/server/dist/external-routes-wiring.d.ts.map +1 -1
- package/server/dist/external-routes-wiring.js +10 -1
- package/server/dist/external-routes-wiring.js.map +1 -1
- package/server/dist/index.d.ts.map +1 -1
- package/server/dist/index.js +6 -8
- package/server/dist/index.js.map +1 -1
- package/server/dist/routes/adopt-scan.d.ts +4 -0
- package/server/dist/routes/adopt-scan.d.ts.map +1 -0
- package/server/dist/routes/adopt-scan.js +27 -0
- package/server/dist/routes/adopt-scan.js.map +1 -0
- package/server/dist/routes/profiles.d.ts +7 -0
- package/server/dist/routes/profiles.d.ts.map +1 -1
- package/server/dist/routes/profiles.js +13 -0
- package/server/dist/routes/profiles.js.map +1 -1
- package/server/dist/routes/projects.d.ts.map +1 -1
- package/server/dist/routes/projects.js +58 -16
- package/server/dist/routes/projects.js.map +1 -1
- package/server/dist/routes/stack-profiles.d.ts +10 -0
- package/server/dist/routes/stack-profiles.d.ts.map +1 -0
- package/server/dist/routes/stack-profiles.js +65 -0
- package/server/dist/routes/stack-profiles.js.map +1 -0
- package/server/dist/terminal/data-target.d.ts +17 -0
- package/server/dist/terminal/data-target.d.ts.map +1 -0
- package/server/dist/terminal/data-target.js +56 -0
- package/server/dist/terminal/data-target.js.map +1 -0
- package/server/dist/terminal/image-paste.d.ts +2 -0
- package/server/dist/terminal/image-paste.d.ts.map +1 -1
- package/server/dist/terminal/image-paste.js +11 -12
- package/server/dist/terminal/image-paste.js.map +1 -1
- package/server/dist/terminal/routes.d.ts +5 -0
- package/server/dist/terminal/routes.d.ts.map +1 -1
- package/server/dist/terminal/routes.js +11 -13
- package/server/dist/terminal/routes.js.map +1 -1
- package/server/dist/types/project.d.ts +9 -0
- package/server/dist/types/project.d.ts.map +1 -1
- package/server/dist/types/stack-profile-contract.d.ts +33 -0
- package/server/dist/types/stack-profile-contract.d.ts.map +1 -0
- package/server/dist/types/stack-profile-contract.js +11 -0
- package/server/dist/types/stack-profile-contract.js.map +1 -0
- package/server/package.json +3 -3
- package/client/dist/assets/arc-DoZTTE1N.js +0 -1
- package/client/dist/assets/architectureDiagram-ZJ3FMSHR-DFTG4KtO.js +0 -36
- package/client/dist/assets/blockDiagram-677ZJIJ3-C34UBjOB.js +0 -132
- package/client/dist/assets/c4Diagram-LMCZKHZV-CbqAB1Ou.js +0 -10
- package/client/dist/assets/channel-DBcZw7Kn.js +0 -1
- package/client/dist/assets/chunk-RYQCIY6F-DrWMx37d.js +0 -1
- package/client/dist/assets/chunk-VR4S4FIN-B5eWtesm.js +0 -1
- package/client/dist/assets/classDiagram-OUVF2IWQ-C3Q1V9DU.js +0 -1
- package/client/dist/assets/classDiagram-v2-EOCWNBFH-C3Q1V9DU.js +0 -1
- package/client/dist/assets/dagre-VKFMJZFB-VXOY6IHR.js +0 -4
- package/client/dist/assets/diagram-OA4YK3LP-DRHY5d_c.js +0 -30
- package/client/dist/assets/diagram-WEI45ONY-B87OYR_S.js +0 -41
- package/client/dist/assets/erDiagram-Q63AITRT-DaD7oa9H.js +0 -85
- package/client/dist/assets/flowDiagram-23GEKE2U-GrMVpsea.js +0 -156
- package/client/dist/assets/graph-C9eacEi8.js +0 -1
- package/client/dist/assets/index-CIpLt0ie.js +0 -863
- package/client/dist/assets/index-DGtnTeFd.css +0 -1
- package/client/dist/assets/infoDiagram-FWYZ7A6U-Fi8fQ95G.js +0 -2
- package/client/dist/assets/katex-DkKDou_j.js +0 -257
- package/client/dist/assets/layout-DEXfKzaS.js +0 -1
- package/client/dist/assets/map-Czzmt4hB.js +0 -1
- package/client/dist/assets/mermaid.core-D6w9zlA0.js +0 -314
- package/client/dist/assets/stateDiagram-2N3HPSRC-D3GXIouX.js +0 -1
- package/client/dist/assets/stateDiagram-v2-6OUMAXLB-D3lXe_mJ.js +0 -1
- package/client/dist/assets/swimlanes-5IMT3BWC-PMRQzNhU.js +0 -2
- package/client/dist/assets/swimlanesDiagram-G3AALYLV-DMLbRFiO.js +0 -8
- package/client/dist/assets/xychartDiagram-FW5EYKEG-BEtPvBSU.js +0 -7
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type OpenForRead } from "../session-jsonl-io.js";
|
|
2
|
+
export declare const SCAN_CHUNK_BYTES: number;
|
|
3
|
+
export declare const MAX_LINE_BYTES: number;
|
|
4
|
+
export interface ScanOptions {
|
|
5
|
+
chunkBytes?: number;
|
|
6
|
+
maxLineBytes?: number;
|
|
7
|
+
openForRead?: OpenForRead;
|
|
8
|
+
/** Called at the start of every attempt (readWithRetry re-runs the whole scan): reset consumer state here. */
|
|
9
|
+
onAttempt?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface LineScanResult {
|
|
12
|
+
/** Window began after byte 0 — older history was not seen. */
|
|
13
|
+
truncated: boolean;
|
|
14
|
+
scannedBytes: number;
|
|
15
|
+
sizeBytes: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function scanLines(filePath: string, maxBytes: number, onLine: (line: string) => void, opts?: ScanOptions): Promise<LineScanResult>;
|
|
18
|
+
/** First line of the file (≤ `headBytes`), for the start timestamp when the scan window skipped it. */
|
|
19
|
+
export declare function readFirstLine(filePath: string, headBytes?: number, openForRead?: OpenForRead): Promise<string | null>;
|
|
20
|
+
//# sourceMappingURL=line-scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-scan.d.ts","sourceRoot":"","sources":["../../../src/core/session-info/line-scan.ts"],"names":[],"mappings":"AAcA,OAAO,EAA+B,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEvF,eAAO,MAAM,gBAAgB,QAAkB,CAAC;AAChD,eAAO,MAAM,cAAc,QAAkB,CAAC;AAE9C,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,8GAA8G;IAC9G,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAC9B,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,cAAc,CAAC,CA0DzB;AAED,uGAAuG;AACvG,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,SAAa,EACtB,WAAW,GAAE,WAA0B,GACtC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmBxB"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Bounded, read-only, line-oriented scan of a (possibly 100 MB+) session JSONL.
|
|
3
|
+
*
|
|
4
|
+
* Reads the NEWEST `maxBytes` of the file in fixed-size POSITIONAL chunks via
|
|
5
|
+
* the same open/stat/read shape as `session-jsonl-io.ts` (never a whole-file
|
|
6
|
+
* read — CLAUDE.md rule 6) wrapped in its `readWithRetry` torn-read envelope.
|
|
7
|
+
* Lines are cut on 0x0A only and decoded per line, so a multi-byte character
|
|
8
|
+
* can never be split across a chunk (rule 5). When the window starts mid-line
|
|
9
|
+
* the first (partial) line is dropped; a record above MAX_LINE_BYTES is skipped
|
|
10
|
+
* undecoded (huge tool results hold none of the facts we collect).
|
|
11
|
+
*/
|
|
12
|
+
import { open } from "node:fs/promises";
|
|
13
|
+
import { ENOENT_FATAL, readWithRetry } from "../session-jsonl-io.js";
|
|
14
|
+
export const SCAN_CHUNK_BYTES = 4 * 1024 * 1024;
|
|
15
|
+
export const MAX_LINE_BYTES = 8 * 1024 * 1024;
|
|
16
|
+
const openReadOnly = (p) => open(p, "r");
|
|
17
|
+
export async function scanLines(filePath, maxBytes, onLine, opts = {}) {
|
|
18
|
+
const chunkBytes = opts.chunkBytes ?? SCAN_CHUNK_BYTES;
|
|
19
|
+
const maxLine = opts.maxLineBytes ?? MAX_LINE_BYTES;
|
|
20
|
+
const openForRead = opts.openForRead ?? openReadOnly;
|
|
21
|
+
// The file was just located, so ENOENT means "gone": fail fast instead of burning the ~3 s retry budget.
|
|
22
|
+
return readWithRetry(async () => {
|
|
23
|
+
opts.onAttempt?.();
|
|
24
|
+
const fh = await openForRead(filePath);
|
|
25
|
+
try {
|
|
26
|
+
const { size } = await fh.stat();
|
|
27
|
+
const start = Math.max(0, size - maxBytes);
|
|
28
|
+
let pos = start;
|
|
29
|
+
let carry = Buffer.alloc(0);
|
|
30
|
+
// Drop the first line only when the window really begins mid-line.
|
|
31
|
+
let dropFirst = false;
|
|
32
|
+
if (start > 0) {
|
|
33
|
+
const prev = Buffer.alloc(1);
|
|
34
|
+
const { bytesRead } = await fh.read(prev, 0, 1, start - 1);
|
|
35
|
+
dropFirst = bytesRead === 1 && prev[0] !== 0x0a;
|
|
36
|
+
}
|
|
37
|
+
let skipping = false; // inside an over-long line
|
|
38
|
+
while (pos < size) {
|
|
39
|
+
const len = Math.min(chunkBytes, size - pos);
|
|
40
|
+
const buf = Buffer.allocUnsafe(len);
|
|
41
|
+
let off = 0;
|
|
42
|
+
while (off < len) {
|
|
43
|
+
const { bytesRead } = await fh.read(buf, off, len - off, pos + off);
|
|
44
|
+
if (bytesRead === 0)
|
|
45
|
+
break;
|
|
46
|
+
off += bytesRead;
|
|
47
|
+
}
|
|
48
|
+
if (off === 0)
|
|
49
|
+
break; // file shrank under us
|
|
50
|
+
pos += off;
|
|
51
|
+
const data = carry.length ? Buffer.concat([carry, buf.subarray(0, off)]) : buf.subarray(0, off);
|
|
52
|
+
let lineStart = 0;
|
|
53
|
+
for (let i = data.indexOf(0x0a); i !== -1; i = data.indexOf(0x0a, lineStart)) {
|
|
54
|
+
if (dropFirst)
|
|
55
|
+
dropFirst = false;
|
|
56
|
+
else if (skipping)
|
|
57
|
+
skipping = false;
|
|
58
|
+
else if (i > lineStart && i - lineStart <= maxLine)
|
|
59
|
+
onLine(data.toString("utf8", lineStart, i));
|
|
60
|
+
lineStart = i + 1;
|
|
61
|
+
}
|
|
62
|
+
carry = Buffer.from(data.subarray(lineStart));
|
|
63
|
+
if (carry.length > maxLine) {
|
|
64
|
+
carry = Buffer.alloc(0);
|
|
65
|
+
if (!dropFirst)
|
|
66
|
+
skipping = true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Final line without a trailing newline (a live session mid-write may
|
|
70
|
+
// leave a torn one — JSON.parse failure is the consumer's concern).
|
|
71
|
+
if (!dropFirst && !skipping && carry.length)
|
|
72
|
+
onLine(carry.toString("utf8"));
|
|
73
|
+
return { truncated: start > 0, scannedBytes: Math.min(size, maxBytes), sizeBytes: size };
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
try {
|
|
77
|
+
await fh.close();
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
/* a close failure must not mask the real I/O error (see session-jsonl-io.ts) */
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, ENOENT_FATAL);
|
|
84
|
+
}
|
|
85
|
+
/** First line of the file (≤ `headBytes`), for the start timestamp when the scan window skipped it. */
|
|
86
|
+
export async function readFirstLine(filePath, headBytes = 256 * 1024, openForRead = openReadOnly) {
|
|
87
|
+
return readWithRetry(async () => {
|
|
88
|
+
const fh = await openForRead(filePath);
|
|
89
|
+
try {
|
|
90
|
+
const { size } = await fh.stat();
|
|
91
|
+
const len = Math.min(size, headBytes);
|
|
92
|
+
if (len <= 0)
|
|
93
|
+
return null;
|
|
94
|
+
const buf = Buffer.allocUnsafe(len);
|
|
95
|
+
const { bytesRead } = await fh.read(buf, 0, len, 0);
|
|
96
|
+
const nl = buf.subarray(0, bytesRead).indexOf(0x0a);
|
|
97
|
+
return buf.toString("utf8", 0, nl === -1 ? bytesRead : nl);
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
try {
|
|
101
|
+
await fh.close();
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
/* see above */
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}, ENOENT_FATAL);
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=line-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-scan.js","sourceRoot":"","sources":["../../../src/core/session-info/line-scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SessionRemoteControl } from "./types.js";
|
|
2
|
+
export declare const CLAUDE_SESSIONS_DIR: string;
|
|
3
|
+
export interface RemoteControlDeps {
|
|
4
|
+
sessionsDir?: string;
|
|
5
|
+
isPidAlive?: (pid: number) => boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function defaultIsPidAlive(pid: number): boolean;
|
|
8
|
+
export declare function detectRemoteControl(sessionUuid: string, bridgeSeenInJsonl: boolean, deps?: RemoteControlDeps): Promise<SessionRemoteControl>;
|
|
9
|
+
//# sourceMappingURL=remote-control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-control.d.ts","sourceRoot":"","sources":["../../../src/core/session-info/remote-control.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,mBAAmB,QAA8C,CAAC;AAE/E,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACvC;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQtD;AAED,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,OAAO,EAC1B,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,oBAAoB,CAAC,CAiC/B"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Remote Control detection. Truth source is `~/.claude/sessions/<pid>.json`
|
|
3
|
+
* (one file per RUNNING claude process, carrying `sessionId` and — while Remote
|
|
4
|
+
* Control is on — `bridgeSessionId`). A `bridge-session` record in the session
|
|
5
|
+
* JSONL only proves it was enabled ONCE, so it feeds `onceEnabled`, never
|
|
6
|
+
* `active`. Liveness is a signal-0 probe: a stale file from a killed process
|
|
7
|
+
* must not read as "on". Read-only (CLAUDE.md DO-NOT #1).
|
|
8
|
+
*/
|
|
9
|
+
import { readdir } from "node:fs/promises";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { readSmallRegularFile } from "./small-file.js";
|
|
13
|
+
export const CLAUDE_SESSIONS_DIR = path.join(homedir(), ".claude", "sessions");
|
|
14
|
+
export function defaultIsPidAlive(pid) {
|
|
15
|
+
try {
|
|
16
|
+
process.kill(pid, 0);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
// EPERM = exists but not ours (alive); ESRCH = gone.
|
|
21
|
+
return err.code === "EPERM";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export async function detectRemoteControl(sessionUuid, bridgeSeenInJsonl, deps = {}) {
|
|
25
|
+
const dir = deps.sessionsDir ?? CLAUDE_SESSIONS_DIR;
|
|
26
|
+
const alive = deps.isPidAlive ?? defaultIsPidAlive;
|
|
27
|
+
const wanted = sessionUuid.toLowerCase();
|
|
28
|
+
let onceEnabled = bridgeSeenInJsonl;
|
|
29
|
+
let files = [];
|
|
30
|
+
try {
|
|
31
|
+
files = (await readdir(dir)).filter((f) => /^\d+\.json$/.test(f));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return { active: false, onceEnabled, pid: null };
|
|
35
|
+
}
|
|
36
|
+
for (const f of files) {
|
|
37
|
+
let rec;
|
|
38
|
+
try {
|
|
39
|
+
const text = await readSmallRegularFile(path.join(dir, f), 64 * 1024);
|
|
40
|
+
if (text === null)
|
|
41
|
+
continue;
|
|
42
|
+
const parsed = JSON.parse(text);
|
|
43
|
+
// Valid JSON is not necessarily an object (`null`, an array, a number):
|
|
44
|
+
// these files belong to another program, so one odd file must be
|
|
45
|
+
// skipped, never allowed to throw out of the whole session-info read.
|
|
46
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
|
|
47
|
+
continue;
|
|
48
|
+
rec = parsed;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
continue; // being rewritten / not JSON
|
|
52
|
+
}
|
|
53
|
+
if (typeof rec.sessionId !== "string" || rec.sessionId.toLowerCase() !== wanted)
|
|
54
|
+
continue;
|
|
55
|
+
const pid = typeof rec.pid === "number" ? rec.pid : Number(f.replace(/\.json$/, ""));
|
|
56
|
+
if (typeof rec.bridgeSessionId === "string" && rec.bridgeSessionId) {
|
|
57
|
+
onceEnabled = true;
|
|
58
|
+
if (Number.isInteger(pid) && pid > 0 && alive(pid))
|
|
59
|
+
return { active: true, onceEnabled, pid };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { active: false, onceEnabled, pid: null };
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=remote-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-control.js","sourceRoot":"","sources":["../../../src/core/session-info/remote-control.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { JsonlLocation } from "../session-watcher.js";
|
|
2
|
+
import { type RemoteControlDeps } from "./remote-control.js";
|
|
3
|
+
import type { SessionInfo } from "./types.js";
|
|
4
|
+
export declare const SESSION_SCAN_BYTES: number;
|
|
5
|
+
export declare const SUBAGENT_SCAN_BYTES: number;
|
|
6
|
+
export declare const MAX_SUBAGENTS = 60;
|
|
7
|
+
export declare const MAX_OUTPUTS = 300;
|
|
8
|
+
export interface SessionInfoDeps extends RemoteControlDeps {
|
|
9
|
+
now?: () => number;
|
|
10
|
+
/** Test seam: bypass the per-file memo. */
|
|
11
|
+
noMemo?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Test hook: number of real scans performed (memo misses). */
|
|
14
|
+
export declare const scanStats: {
|
|
15
|
+
scans: number;
|
|
16
|
+
};
|
|
17
|
+
export declare function readSessionInfo(sessionUuid: string, loc: JsonlLocation, deps?: SessionInfoDeps): Promise<SessionInfo>;
|
|
18
|
+
//# sourceMappingURL=session-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-info.d.ts","sourceRoot":"","sources":["../../../src/core/session-info/session-info.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAElF,OAAO,KAAK,EAAE,WAAW,EAAqB,MAAM,YAAY,CAAC;AAEjE,eAAO,MAAM,kBAAkB,QAAmB,CAAC;AACnD,eAAO,MAAM,mBAAmB,QAAmB,CAAC;AACpD,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,WAAW,MAAM,CAAC;AAI/B,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAOD,+DAA+D;AAC/D,eAAO,MAAM,SAAS;;CAAe,CAAC;AAoEtC,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,aAAa,EAClB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,WAAW,CAAC,CAoEtB"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Orchestrator for GET /tasks/:id/session-info: scans the session JSONL and its
|
|
3
|
+
* `<uuid>/subagents/agent-*.jsonl` siblings (bounded, positional, read-only)
|
|
4
|
+
* and assembles the SessionInfo view.
|
|
5
|
+
*
|
|
6
|
+
* Memo: PER FILE, keyed by (path,size,mtime), with in-flight de-duplication so
|
|
7
|
+
* parallel polls share one scan. A live session therefore rescans only the
|
|
8
|
+
* files that actually changed — finished agent files are free. It is a pure
|
|
9
|
+
* function cache (no byte cursors, same answer on hit and miss), so the
|
|
10
|
+
* transcript route's statelessness (CLAUDE.md rule 4) is untouched; bounded by
|
|
11
|
+
* MEMO_MAX with oldest-first eviction.
|
|
12
|
+
*/
|
|
13
|
+
import { readdir, realpath, stat } from "node:fs/promises";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { ENOENT_FATAL, readWithRetry } from "../session-jsonl-io.js";
|
|
16
|
+
import { ingestLine, newFacts, outputKey, quickTimestamp } from "./collect.js";
|
|
17
|
+
import { readFirstLine, scanLines } from "./line-scan.js";
|
|
18
|
+
import { detectRemoteControl } from "./remote-control.js";
|
|
19
|
+
import { buildSubagents } from "./subagents.js";
|
|
20
|
+
export const SESSION_SCAN_BYTES = 48 * 1024 * 1024;
|
|
21
|
+
export const SUBAGENT_SCAN_BYTES = 12 * 1024 * 1024;
|
|
22
|
+
export const MAX_SUBAGENTS = 60;
|
|
23
|
+
export const MAX_OUTPUTS = 300;
|
|
24
|
+
const MEMO_MAX = 512;
|
|
25
|
+
const SCAN_CONCURRENCY = 6;
|
|
26
|
+
const memo = new Map();
|
|
27
|
+
/** Test hook: number of real scans performed (memo misses). */
|
|
28
|
+
export const scanStats = { scans: 0 };
|
|
29
|
+
async function scanFile(file, maxBytes, agentId) {
|
|
30
|
+
scanStats.scans++;
|
|
31
|
+
// readWithRetry re-runs the whole scan on a transient fs error: every attempt starts from fresh facts.
|
|
32
|
+
let facts = newFacts();
|
|
33
|
+
const scan = await scanLines(file, maxBytes, (l) => ingestLine(facts, l, agentId), {
|
|
34
|
+
onAttempt: () => {
|
|
35
|
+
facts = newFacts();
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
if (scan.truncated) {
|
|
39
|
+
// Window skipped the start; recover the true start timestamp from the head.
|
|
40
|
+
const head = await readFirstLine(file).catch(() => null);
|
|
41
|
+
const ts = head ? quickTimestamp(head) : null;
|
|
42
|
+
if (ts)
|
|
43
|
+
facts.firstTs = ts;
|
|
44
|
+
}
|
|
45
|
+
return { facts, scan };
|
|
46
|
+
}
|
|
47
|
+
function scanCached(file, sig, maxBytes, agentId, noMemo) {
|
|
48
|
+
if (noMemo)
|
|
49
|
+
return scanFile(file, maxBytes, agentId);
|
|
50
|
+
const hit = memo.get(file);
|
|
51
|
+
if (hit && hit.sig === sig) {
|
|
52
|
+
memo.delete(file); // LRU: refresh recency on a hit
|
|
53
|
+
memo.set(file, hit);
|
|
54
|
+
return hit.p;
|
|
55
|
+
}
|
|
56
|
+
const p = scanFile(file, maxBytes, agentId);
|
|
57
|
+
memo.delete(file);
|
|
58
|
+
if (memo.size >= MEMO_MAX)
|
|
59
|
+
memo.delete(memo.keys().next().value);
|
|
60
|
+
memo.set(file, { sig, p });
|
|
61
|
+
p.catch(() => {
|
|
62
|
+
if (memo.get(file)?.p === p)
|
|
63
|
+
memo.delete(file); // never cache a failure
|
|
64
|
+
});
|
|
65
|
+
return p;
|
|
66
|
+
}
|
|
67
|
+
async function listSubagentFiles(sessionPath) {
|
|
68
|
+
const dir = path.join(path.dirname(sessionPath), path.basename(sessionPath, ".jsonl"), "subagents");
|
|
69
|
+
let entries;
|
|
70
|
+
try {
|
|
71
|
+
// Containment (CLAUDE.md DO-NOT #10 style: realpath + path.relative, not startsWith):
|
|
72
|
+
// a junction/symlinked subagents dir must not lead outside the session folder.
|
|
73
|
+
const [realDir, realRoot] = await Promise.all([realpath(dir), realpath(path.dirname(sessionPath))]);
|
|
74
|
+
const rel = path.relative(realRoot, realDir);
|
|
75
|
+
if (rel.startsWith("..") || path.isAbsolute(rel))
|
|
76
|
+
return { files: [], dropped: 0 };
|
|
77
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return { files: [], dropped: 0 };
|
|
81
|
+
}
|
|
82
|
+
const out = [];
|
|
83
|
+
for (const e of entries) {
|
|
84
|
+
// Dirent.isFile() is false for symlinks: a link planted in the dir is never followed.
|
|
85
|
+
const m = e.isFile() ? /^agent-([A-Za-z0-9]+)\.jsonl$/.exec(e.name) : null;
|
|
86
|
+
if (!m)
|
|
87
|
+
continue;
|
|
88
|
+
const jsonlPath = path.join(dir, e.name);
|
|
89
|
+
try {
|
|
90
|
+
const s = await stat(jsonlPath);
|
|
91
|
+
out.push({ agentId: m[1], jsonlPath, metaPath: path.join(dir, `agent-${m[1]}.meta.json`), mtimeMs: s.mtimeMs, size: s.size });
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
/* vanished between readdir and stat */
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
out.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
98
|
+
return { files: out.slice(0, MAX_SUBAGENTS), dropped: Math.max(0, out.length - MAX_SUBAGENTS) };
|
|
99
|
+
}
|
|
100
|
+
export async function readSessionInfo(sessionUuid, loc, deps = {}) {
|
|
101
|
+
const now = (deps.now ?? Date.now)();
|
|
102
|
+
const { files: subFiles, dropped } = await listSubagentFiles(loc.path);
|
|
103
|
+
const st = await readWithRetry(() => stat(loc.path), ENOENT_FATAL);
|
|
104
|
+
const main = await scanCached(loc.path, `${st.size}:${st.mtimeMs}`, SESSION_SCAN_BYTES, null, deps.noMemo);
|
|
105
|
+
const subFacts = new Map();
|
|
106
|
+
let next = 0;
|
|
107
|
+
const worker = async () => {
|
|
108
|
+
for (let k = next++; k < subFiles.length; k = next++) {
|
|
109
|
+
const f = subFiles[k];
|
|
110
|
+
try {
|
|
111
|
+
subFacts.set(f.agentId, (await scanCached(f.jsonlPath, `${f.size}:${f.mtimeMs}`, SUBAGENT_SCAN_BYTES, f.agentId, deps.noMemo)).facts);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
/* an unreadable agent file drops that agent's detail, not the whole view */
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
// Bounded pool: a cold memo must not open 60 files / hold 60 chunk buffers at once.
|
|
119
|
+
await Promise.all(Array.from({ length: Math.min(SCAN_CONCURRENCY, subFiles.length) }, worker));
|
|
120
|
+
const facts = main.facts;
|
|
121
|
+
const lastCompaction = facts.compactions.length ? facts.compactions[facts.compactions.length - 1] : null;
|
|
122
|
+
// A compaction newer than the newest usage makes that usage stale: still reported
|
|
123
|
+
// (the spec's definition), flagged, and paired with the compactor's own estimate.
|
|
124
|
+
const compactedSince = !!lastCompaction && lastCompaction.seq > facts.usageSeq;
|
|
125
|
+
const merged = new Map();
|
|
126
|
+
const all = [...facts.outputs.values(), ...[...subFacts.values()].flatMap((sf) => [...sf.outputs.values()])];
|
|
127
|
+
for (const o of all) {
|
|
128
|
+
const key = outputKey(o.path);
|
|
129
|
+
const prev = merged.get(key);
|
|
130
|
+
if (!prev)
|
|
131
|
+
merged.set(key, { ...o });
|
|
132
|
+
else {
|
|
133
|
+
if (o.firstAt && (!prev.firstAt || o.firstAt < prev.firstAt))
|
|
134
|
+
prev.firstAt = o.firstAt;
|
|
135
|
+
if (o.lastAt && (!prev.lastAt || o.lastAt > prev.lastAt)) {
|
|
136
|
+
prev.lastAt = o.lastAt;
|
|
137
|
+
prev.tool = o.tool;
|
|
138
|
+
prev.agentId = o.agentId;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const sortedAll = [...merged.values()].sort((a, b) => (b.lastAt ?? "").localeCompare(a.lastAt ?? ""));
|
|
143
|
+
const remoteControl = await detectRemoteControl(sessionUuid, facts.bridgeSeen, deps);
|
|
144
|
+
const subagents = await buildSubagents(subFiles, subFacts, facts, now);
|
|
145
|
+
return {
|
|
146
|
+
sessionUuid,
|
|
147
|
+
context: {
|
|
148
|
+
tokens: facts.usage?.tokens ?? null,
|
|
149
|
+
model: facts.usage?.model ?? facts.model,
|
|
150
|
+
at: facts.usage?.at ?? null,
|
|
151
|
+
compactedSince,
|
|
152
|
+
tokensAfterCompaction: compactedSince ? (lastCompaction.postTokens ?? null) : null,
|
|
153
|
+
},
|
|
154
|
+
compaction: {
|
|
155
|
+
count: facts.compactions.length,
|
|
156
|
+
last: lastCompaction
|
|
157
|
+
? { at: lastCompaction.at, preTokens: lastCompaction.preTokens, postTokens: lastCompaction.postTokens }
|
|
158
|
+
: null,
|
|
159
|
+
},
|
|
160
|
+
outputs: sortedAll.slice(0, MAX_OUTPUTS),
|
|
161
|
+
remoteControl,
|
|
162
|
+
subagents,
|
|
163
|
+
scan: {
|
|
164
|
+
...main.scan,
|
|
165
|
+
outputsTruncated: Math.max(0, sortedAll.length - MAX_OUTPUTS),
|
|
166
|
+
subagentsTruncated: dropped,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=session-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-info.js","sourceRoot":"","sources":["../../../src/core/session-info/session-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"small-file.d.ts","sourceRoot":"","sources":["../../../src/core/session-info/small-file.ts"],"names":[],"mappings":"AAkBA,wBAAsB,oBAAoB,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoB9F"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Read a small regular file with ONE open and no path-based check before it
|
|
3
|
+
* (CodeQL js/file-system-race: an `lstat(p)` followed by `readFile(p)` lets the
|
|
4
|
+
* file change between the check and the read). The checks run on the open
|
|
5
|
+
* handle instead:
|
|
6
|
+
* - `O_NOFOLLOW` (POSIX) refuses a symlink at open time; `O_NONBLOCK` keeps a
|
|
7
|
+
* FIFO planted under the name from blocking the open.
|
|
8
|
+
* - `fh.stat()` must be a regular file within `maxBytes`.
|
|
9
|
+
* - Windows has no `O_NOFOLLOW`, so a post-open `lstat` must agree: not a
|
|
10
|
+
* symlink, and the same file (dev + ino) as the one actually opened.
|
|
11
|
+
* Read-only (CLAUDE.md DO-NOT #1). Returns null on anything unexpected.
|
|
12
|
+
*/
|
|
13
|
+
import { constants } from "node:fs";
|
|
14
|
+
import { lstat, open } from "node:fs/promises";
|
|
15
|
+
const FLAGS = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0);
|
|
16
|
+
export async function readSmallRegularFile(p, maxBytes) {
|
|
17
|
+
let fh;
|
|
18
|
+
try {
|
|
19
|
+
fh = await open(p, FLAGS);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null; // missing, symlink (ELOOP), directory, permission
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const st = await fh.stat({ bigint: true });
|
|
26
|
+
if (!st.isFile() || st.size > BigInt(maxBytes))
|
|
27
|
+
return null;
|
|
28
|
+
const link = await lstat(p, { bigint: true });
|
|
29
|
+
if (link.isSymbolicLink() || link.dev !== st.dev || link.ino !== st.ino)
|
|
30
|
+
return null;
|
|
31
|
+
const buf = Buffer.alloc(Number(st.size));
|
|
32
|
+
const { bytesRead } = await fh.read(buf, 0, buf.length, 0);
|
|
33
|
+
return buf.subarray(0, bytesRead).toString("utf8");
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
await fh.close().catch(() => { });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=small-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"small-file.js","sourceRoot":"","sources":["../../../src/core/session-info/small-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,GAAG,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC;AAE7F,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,CAAS,EAAE,QAAgB;IACpE,IAAI,EAAE,CAAC;IACP,IAAI,CAAC;QACH,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,kDAAkD;IACjE,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5D,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACrF,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC3D,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACnC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const SUBAGENT_TRANSCRIPT_MAX_BYTES: number;
|
|
2
|
+
export declare const AGENT_ID_RE: RegExp;
|
|
3
|
+
export type SubagentTranscript = {
|
|
4
|
+
status: "ok";
|
|
5
|
+
content: string;
|
|
6
|
+
truncated: boolean;
|
|
7
|
+
sizeBytes: number;
|
|
8
|
+
} | {
|
|
9
|
+
status: "missing";
|
|
10
|
+
};
|
|
11
|
+
export declare function readSubagentTranscript(sessionPath: string, agentId: string, maxBytes?: number): Promise<SubagentTranscript>;
|
|
12
|
+
//# sourceMappingURL=subagent-transcript.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-transcript.d.ts","sourceRoot":"","sources":["../../../src/core/session-info/subagent-transcript.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,6BAA6B,QAAc,CAAC;AACzD,eAAO,MAAM,WAAW,QAAwB,CAAC;AAEjD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAwB1B,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAsC,GAC/C,OAAO,CAAC,kBAAkB,CAAC,CA2B7B"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Read-only tail of ONE subagent's JSONL (`<session>/subagents/agent-<id>.jsonl`)
|
|
3
|
+
* for the Mission Agents window (campaign mission-desktop-style, M4).
|
|
4
|
+
*
|
|
5
|
+
* Safety, in order: the id is validated against the filename grammar; the file
|
|
6
|
+
* path is realpath'd and must equal EXACTLY `<uuid>/subagents/agent-<id>.jsonl`
|
|
7
|
+
* under the session's project dir (realpath + path.relative, never startsWith
|
|
8
|
+
* — CLAUDE.md DO-NOT #10) so a symlink cannot point at another session or
|
|
9
|
+
* outside the tree; the file is opened ONCE and the HANDLE is checked to be a
|
|
10
|
+
* regular file (no stat-then-open race). ONE open serves both the size and the
|
|
11
|
+
* positional read of `[size - MAX, size)` inside the retry envelope of
|
|
12
|
+
* `session-jsonl-io.ts`; the window is cut on `\n` boundaries only (rule 5), so
|
|
13
|
+
* a 100 MB agent file costs a flat ~1 MB read. Stateless: no cursor, no cache
|
|
14
|
+
* (rule 4).
|
|
15
|
+
*/
|
|
16
|
+
import { open, realpath } from "node:fs/promises";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
import { ENOENT_FATAL, readWithRetry } from "../session-jsonl-io.js";
|
|
19
|
+
export const SUBAGENT_TRANSCRIPT_MAX_BYTES = 1024 * 1024;
|
|
20
|
+
export const AGENT_ID_RE = /^[A-Za-z0-9]{1,64}$/;
|
|
21
|
+
async function readWindow(real, maxBytes) {
|
|
22
|
+
const fh = await open(real, "r");
|
|
23
|
+
try {
|
|
24
|
+
const st = await fh.stat();
|
|
25
|
+
if (!st.isFile())
|
|
26
|
+
throw Object.assign(new Error("not a regular file"), { code: "ENOTREG" });
|
|
27
|
+
const size = st.size;
|
|
28
|
+
const start = Math.max(0, size - maxBytes);
|
|
29
|
+
const buf = Buffer.allocUnsafe(size - start);
|
|
30
|
+
let off = 0;
|
|
31
|
+
while (off < buf.length) {
|
|
32
|
+
const { bytesRead } = await fh.read(buf, off, buf.length - off, start + off);
|
|
33
|
+
if (bytesRead === 0)
|
|
34
|
+
break; // the file shrank under us
|
|
35
|
+
off += bytesRead;
|
|
36
|
+
}
|
|
37
|
+
return { bytes: buf.subarray(0, off), start, size };
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
await fh.close().catch(() => undefined);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const fold = (p) => (process.platform === "win32" ? p.toLowerCase() : p);
|
|
44
|
+
export async function readSubagentTranscript(sessionPath, agentId, maxBytes = SUBAGENT_TRANSCRIPT_MAX_BYTES) {
|
|
45
|
+
if (!AGENT_ID_RE.test(agentId))
|
|
46
|
+
return { status: "missing" };
|
|
47
|
+
const name = `agent-${agentId}.jsonl`;
|
|
48
|
+
const expected = path.join(path.basename(sessionPath, ".jsonl"), "subagents", name);
|
|
49
|
+
let real;
|
|
50
|
+
try {
|
|
51
|
+
const [realRoot, realFile] = await Promise.all([
|
|
52
|
+
realpath(path.dirname(sessionPath)),
|
|
53
|
+
realpath(path.join(path.dirname(sessionPath), expected)),
|
|
54
|
+
]);
|
|
55
|
+
if (fold(path.relative(realRoot, realFile)) !== fold(expected))
|
|
56
|
+
return { status: "missing" };
|
|
57
|
+
real = realFile;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return { status: "missing" };
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const w = await readWithRetry(() => readWindow(real, maxBytes), ENOENT_FATAL);
|
|
64
|
+
let bytes = w.bytes;
|
|
65
|
+
// Mid-file start: drop the partial first line. A line still being appended is dropped too.
|
|
66
|
+
if (w.start > 0)
|
|
67
|
+
bytes = bytes.subarray(bytes.indexOf(10) + 1);
|
|
68
|
+
bytes = bytes.subarray(0, bytes.lastIndexOf(10) + 1);
|
|
69
|
+
return { status: "ok", content: bytes.toString("utf8"), truncated: w.start > 0, sizeBytes: w.size };
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
const code = err?.code;
|
|
73
|
+
if (code === "ENOENT" || code === "ENOTREG" || code === "EISDIR" || code === "EPERM" || code === "EACCES")
|
|
74
|
+
return { status: "missing" };
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=subagent-transcript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-transcript.js","sourceRoot":"","sources":["../../../src/core/session-info/subagent-transcript.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Facts } from "./collect.js";
|
|
2
|
+
import type { SessionSubagent } from "./types.js";
|
|
3
|
+
export declare const SUBAGENT_STALE_MS: number;
|
|
4
|
+
/** An agent blocked inside an unanswered tool call (long test run, permission prompt) gets far longer. */
|
|
5
|
+
export declare const SUBAGENT_PENDING_STALE_MS: number;
|
|
6
|
+
export interface SubagentFile {
|
|
7
|
+
agentId: string;
|
|
8
|
+
jsonlPath: string;
|
|
9
|
+
metaPath: string;
|
|
10
|
+
mtimeMs: number;
|
|
11
|
+
size: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function buildSubagents(files: SubagentFile[], subFacts: Map<string, Facts>, parent: Facts, now: number): Promise<SessionSubagent[]>;
|
|
14
|
+
//# sourceMappingURL=subagents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagents.d.ts","sourceRoot":"","sources":["../../../src/core/session-info/subagents.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAgB,KAAK,EAA4B,MAAM,cAAc,CAAC;AAElF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAChD,0GAA0G;AAC1G,eAAO,MAAM,yBAAyB,QAAiB,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAgBD,wBAAsB,cAAc,CAClC,KAAK,EAAE,YAAY,EAAE,EACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,EAC5B,MAAM,EAAE,KAAK,EACb,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,eAAe,EAAE,CAAC,CAyD5B"}
|