@tequila99/githuman 0.11.2 → 0.12.0
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/README.md +62 -2
- package/dist/cli/commands/mcp.js +112 -0
- package/dist/cli/commands/pi-acp.js +21 -0
- package/dist/cli/config.js +7 -1
- package/dist/cli/index.js +19 -8
- package/dist/cli/server-runtime.js +1 -0
- package/dist/server/adapters/agents/artifact-permission.js +88 -0
- package/dist/server/adapters/pi-acp/agent.js +98 -0
- package/dist/server/adapters/pi-acp/compatibility.js +57 -0
- package/dist/server/adapters/pi-acp/control.js +76 -0
- package/dist/server/adapters/pi-acp/errors.js +17 -0
- package/dist/server/adapters/pi-acp/extension.js +255 -0
- package/dist/server/adapters/pi-acp/launch.js +16 -0
- package/dist/server/adapters/pi-acp/mcp.js +153 -0
- package/dist/server/adapters/pi-acp/process.js +199 -0
- package/dist/server/adapters/pi-acp/session.js +409 -0
- package/dist/server/adapters/pi-acp/vendor/LICENSE +21 -0
- package/dist/server/adapters/pi-acp/vendor/README.md +29 -0
- package/dist/server/adapters/pi-acp/vendor/prompt.js +56 -0
- package/dist/server/app.js +92 -5
- package/dist/server/config/agents.js +4 -6
- package/dist/server/db/artifact-graph-migrations.js +56 -0
- package/dist/server/db/artifact-migrations.js +70 -0
- package/dist/server/db/artifact-review-migrations.js +24 -0
- package/dist/server/db/artifact-search-migrations.js +31 -0
- package/dist/server/db/artifact-validation-migrations.js +70 -0
- package/dist/server/db/index.js +3 -0
- package/dist/server/db/migrations.js +10 -0
- package/dist/server/db/sqlite-error.js +15 -0
- package/dist/server/db/transaction.js +40 -0
- package/dist/server/errors/artifacts.js +28 -0
- package/dist/server/errors/database.js +2 -0
- package/dist/server/hooks/access/require-access.js +8 -0
- package/dist/server/repositories/artifact-catalog.repo.js +283 -0
- package/dist/server/repositories/artifact-files.repo.js +181 -0
- package/dist/server/repositories/artifact-graph.repo.js +50 -0
- package/dist/server/repositories/artifact-search.repo.js +192 -0
- package/dist/server/repositories/artifact-transition.repo.js +85 -0
- package/dist/server/repositories/artifact-validation.repo.js +146 -0
- package/dist/server/repositories/notes-catalog.repo.js +2 -10
- package/dist/server/repositories/task.repo.js +114 -0
- package/dist/server/routes/agent.js +8 -1
- package/dist/server/routes/artifact-actions.js +129 -0
- package/dist/server/routes/artifact-agent.js +183 -0
- package/dist/server/routes/artifact-definitions.js +163 -0
- package/dist/server/routes/artifact-transitions.js +80 -0
- package/dist/server/routes/artifacts.js +111 -0
- package/dist/server/routes/events.js +5 -1
- package/dist/server/services/agent/agent-session.js +180 -10
- package/dist/server/services/agent/context-builder.js +30 -2
- package/dist/server/services/agent/session-registry.js +106 -2
- package/dist/server/services/agent/turn-task-context.js +1 -0
- package/dist/server/services/artifact-authorization.service.js +174 -0
- package/dist/server/services/artifact-definition.service.js +96 -0
- package/dist/server/services/artifact-export.service.js +44 -0
- package/dist/server/services/artifact-graph-validation.js +497 -0
- package/dist/server/services/artifact-graph.service.js +81 -0
- package/dist/server/services/artifact-lifecycle.service.js +343 -0
- package/dist/server/services/artifact-maintenance.service.js +55 -0
- package/dist/server/services/artifact-search.service.js +331 -0
- package/dist/server/services/artifact-storage.service.js +646 -0
- package/dist/server/services/artifact-transition.service.js +607 -0
- package/dist/server/services/artifact-type.service.js +74 -0
- package/dist/server/services/artifact-validation-jobs.service.js +518 -0
- package/dist/server/services/device-connections.js +9 -1
- package/dist/server/services/review.service.js +6 -5
- package/dist/server/services/task.service.js +225 -0
- package/dist/server/utils/artifact-actor.js +13 -0
- package/dist/server/utils/artifact-page.js +42 -0
- package/dist/server/utils/take-within-bytes.js +16 -0
- package/dist/server/utils/text.js +7 -0
- package/dist/shared/agents/schemas.js +27 -0
- package/dist/shared/app/storage-constants.js +2 -0
- package/dist/shared/artifact-tools/descriptions.js +11 -0
- package/dist/shared/artifact-tools/instructions.js +14 -0
- package/dist/shared/artifact-tools/schemas.js +119 -0
- package/dist/shared/artifact-transitions/constants.js +21 -0
- package/dist/shared/artifact-transitions/schemas.js +111 -0
- package/dist/shared/artifact-transitions/transitions.js +61 -0
- package/dist/shared/artifact-transitions/types.js +1 -0
- package/dist/shared/artifacts/constants.js +34 -0
- package/dist/shared/artifacts/mcp-constants.js +24 -0
- package/dist/shared/artifacts/normalize.js +9 -0
- package/dist/shared/artifacts/schemas.js +820 -0
- package/dist/shared/artifacts/search.js +101 -0
- package/dist/shared/artifacts/types.js +1 -0
- package/dist/shared/events/schemas.js +1 -1
- package/dist/shared/events/types.js +1 -0
- package/dist/shared/tasks/schemas.js +261 -0
- package/dist/shared/tasks/types.js +1 -0
- package/dist/shared/utils/artifact-body.js +10 -0
- package/dist/shared/utils/canonical-json.js +22 -0
- package/dist/shared/utils/is-safe-prefixed-filename.js +10 -0
- package/dist/shared/utils/is-uuid.js +4 -2
- package/dist/shared/utils/is-valid-artifact-type-id.js +9 -0
- package/dist/shared/utils/is-valid-filename-prefix.js +13 -0
- package/dist/web/assets/AccessPage-Dvj0aCkm.js +1 -0
- package/dist/web/assets/AddButton-CMC9qf51.js +4 -0
- package/dist/web/assets/AddToAgentButton-BitTdCEg.js +1 -0
- package/dist/web/assets/AppPage-Cozv2vqG.js +1 -0
- package/dist/web/assets/ArtifactDefinitionPicker-BQOoU60k.js +3 -0
- package/dist/web/assets/ArtifactDefinitionPicker-D3qdrxlC.css +1 -0
- package/dist/web/assets/ArtifactsPage-BJR-XYYs.js +2 -0
- package/dist/web/assets/ArtifactsPage-Cu1xdYNf.css +1 -0
- package/dist/web/assets/CancelButton-mkxRHwoZ.js +1 -0
- package/dist/web/assets/ClosePopup-BtDeDZsk.js +1 -0
- package/dist/web/assets/CreateButton-zCmb7snC.js +1 -0
- package/dist/web/assets/CreateReviewFabButton-BCg1TvFh.js +1 -0
- package/dist/web/assets/DialogHeader-CPL9OtDV.css +1 -0
- package/dist/web/assets/DialogHeader-CQvAZVx7.js +1 -0
- package/dist/web/assets/{ErrorNotFound-DucDzOUJ.js → ErrorNotFound-fXS367lZ.js} +1 -1
- package/dist/web/assets/{IndexPage-D5PvyGrX.css → IndexPage-5V5GLtgi.css} +1 -1
- package/dist/web/assets/IndexPage-DMTZyWQA.js +1 -0
- package/dist/web/assets/MainLayout-DWJ_-EMV.js +7 -0
- package/dist/web/assets/MainLayout-Dy74m_q1.css +1 -0
- package/dist/web/assets/NoteVisualEditor-5rHBQ3j0.js +1054 -0
- package/dist/web/assets/{NoteVisualEditor-CawpxEFB.css → NoteVisualEditor-DE4ACTRJ.css} +1 -1
- package/dist/web/assets/NotesPage-C_eoCUl7.css +1 -0
- package/dist/web/assets/NotesPage-CjaxjLBW.js +4 -0
- package/dist/web/assets/{PdfPreview-rlkcqoMF.js → PdfPreview-2NQ5gkjh.js} +2 -2
- package/dist/web/assets/ProjectFilePage-B-WUUxnq.js +1 -0
- package/dist/web/assets/QBtn-V3VXtJXi.js +1 -0
- package/dist/web/assets/QFab-CxpedhPI.js +1 -0
- package/dist/web/assets/{QForm-Be8-ucuJ.js → QForm-ClpSneeD.js} +1 -1
- package/dist/web/assets/QInput-BnqLJGXl.js +1 -0
- package/dist/web/assets/QScrollArea-js5dkUz1.js +1 -0
- package/dist/web/assets/QSpace-C7iAnGlU.js +1 -0
- package/dist/web/assets/QTabs-DIy5gWMb.js +1 -0
- package/dist/web/assets/QVirtualScroll-DkD0TczV.js +1 -0
- package/dist/web/assets/ReviewDetailPage-BgxcsTqY.css +1 -0
- package/dist/web/assets/ReviewDetailPage-Bmc8DmSu.js +1 -0
- package/dist/web/assets/ReviewsPage-DR1IWCmu.js +1 -0
- package/dist/web/assets/SearchInput-BRyN93Z1.js +1 -0
- package/dist/web/assets/StatusSwitcher-CpkH8BuC.js +1 -0
- package/dist/web/assets/{StatusSwitcher-D6i8_OfR.css → StatusSwitcher-DaE1ufAA.css} +1 -1
- package/dist/web/assets/TagFilterField-Bl3FBkB5.js +1 -0
- package/dist/web/assets/TagFilterField-DjUH0m3_.css +1 -0
- package/dist/web/assets/{TerminalView-617DZuPt.css → TerminalView-BCeke4xd.css} +1 -1
- package/dist/web/assets/{TerminalView-D4elkzN4.js → TerminalView-tEyLM5qZ.js} +12 -12
- package/dist/web/assets/{abnfDiagram-O67JEVCF-Cugru96L.js → abnfDiagram-O67JEVCF-DN9xiV9p.js} +1 -1
- package/dist/web/assets/{access-store-Cdg8oRAM.js → access-store-CwkOl71l.js} +1 -1
- package/dist/web/assets/{agent-store-D_W7iD_B.js → agent-store-Grbx4jkz.js} +5 -5
- package/dist/web/assets/architecture-7GRP2DOG-DmaYCP8T.js +1 -0
- package/dist/web/assets/{architectureDiagram-NJMV4G6O-7rMsE4Wt.js → architectureDiagram-NJMV4G6O-BVAJOucG.js} +1 -1
- package/dist/web/assets/{blockDiagram-BEXU5L5S-BvSnwUrI.js → blockDiagram-BEXU5L5S-TJAfSX44.js} +1 -1
- package/dist/web/assets/{c4Diagram-YGBWAQC7-CgmQlCVx.js → c4Diagram-YGBWAQC7-5UHyT_tW.js} +1 -1
- package/dist/web/assets/channel-B4_5H-fb.js +1 -0
- package/dist/web/assets/{chunk-3FUC2YCW-_i8udThz.js → chunk-3FUC2YCW-CelgLyJi.js} +1 -1
- package/dist/web/assets/{chunk-5DYCD2WN-Mhk2LlLk.js → chunk-5DYCD2WN-bhEAVIbQ.js} +1 -1
- package/dist/web/assets/{chunk-742MDFTN-CDVcwgEp.js → chunk-742MDFTN-ByLz4EcD.js} +1 -1
- package/dist/web/assets/{chunk-7INBJB4K-C2c1fi9s.js → chunk-7INBJB4K-CK2i0csa.js} +1 -1
- package/dist/web/assets/{chunk-7M6MHVWA-BeGkoIBL.js → chunk-7M6MHVWA-CoCiujjC.js} +1 -1
- package/dist/web/assets/{chunk-7PRAP22T-BVWTh9sT.js → chunk-7PRAP22T-CY4NCrCY.js} +1 -1
- package/dist/web/assets/{chunk-GTNCS2PH-gVhX7NZP.js → chunk-GTNCS2PH-DMB7bQGB.js} +1 -1
- package/dist/web/assets/{chunk-GWA4HPMP-BPdnIcQH.js → chunk-GWA4HPMP-F6qclPTR.js} +1 -1
- package/dist/web/assets/{chunk-MBY4JIJT-B2VfO_06.js → chunk-MBY4JIJT-CSiiBtlX.js} +1 -1
- package/dist/web/assets/{chunk-NETBCI7D-DZF_gITO.js → chunk-NETBCI7D-CBh7GChL.js} +1 -1
- package/dist/web/assets/{chunk-O7XYJQB3-CDpBWiLq.js → chunk-O7XYJQB3-B2aqz0sN.js} +1 -1
- package/dist/web/assets/{chunk-UA2S7LBM-Iv7TSRE_.js → chunk-UA2S7LBM-B_-P_eR0.js} +1 -1
- package/dist/web/assets/{chunk-WEXAMYUT-Ce6goZ2Y.js → chunk-WEXAMYUT-19nMFxzK.js} +1 -1
- package/dist/web/assets/{chunk-Z7XXMR3K-CY6E6_Ux.js → chunk-Z7XXMR3K-Co7gzRY1.js} +1 -1
- package/dist/web/assets/{chunk-ZIGJFQKS-BLzsXZBc.js → chunk-ZIGJFQKS-Eoi4K5bK.js} +1 -1
- package/dist/web/assets/{classDiagram-v2-NBCMYWYE-Dz0kD9P6.js → classDiagram-v2-NBCMYWYE-CfFGzL-A.js} +1 -1
- package/dist/web/assets/copy-code-DaqEfdXL.js +1 -0
- package/dist/web/assets/create-DedXY-KP.js +1 -0
- package/dist/web/assets/{cynefin-OW5HDTMX-DWIx3wRm.js → cynefin-OW5HDTMX-DdZXl3KU.js} +1 -1
- package/dist/web/assets/{cynefinDiagram-VND7K2PF-2D80uocv.js → cynefinDiagram-VND7K2PF-WU21nYH-.js} +1 -1
- package/dist/web/assets/{dagre-6A5THRUB-BLBhukn-.js → dagre-6A5THRUB-48z3F8Pl.js} +1 -1
- package/dist/web/assets/date-DZIuZp-w.js +1 -0
- package/dist/web/assets/{devices-store-BfZKPOhg.js → devices-store-Bfk2wdrQ.js} +1 -1
- package/dist/web/assets/{diagram-22UHCM2B-DY8dMLZ3.js → diagram-22UHCM2B-B0AZgJW9.js} +1 -1
- package/dist/web/assets/{diagram-3UASUU5V-Bf6Od1NH.js → diagram-3UASUU5V-CzEzrxuO.js} +1 -1
- package/dist/web/assets/{diagram-ATOU4E4O-CjLGcYD5.js → diagram-ATOU4E4O-w6h1bD3w.js} +1 -1
- package/dist/web/assets/{diagram-CDSNMT55-gIvaVNvs.js → diagram-CDSNMT55-BdTHQd_o.js} +1 -1
- package/dist/web/assets/{diagram-MLGK6HIB-VR5kiCi5.js → diagram-MLGK6HIB-pB4cj6c2.js} +1 -1
- package/dist/web/assets/{diagram-MPIPVDR6-CdAdj25I.js → diagram-MPIPVDR6-C7C06qyV.js} +1 -1
- package/dist/web/assets/diff-store-DBDL5Hw5.js +93 -0
- package/dist/web/assets/{dist-lgw4kcVA.js → dist-B7Cu0FBW.js} +1 -1
- package/dist/web/assets/{dist-yzAhvE-V.js → dist-B8i8y3GY.js} +1 -1
- package/dist/web/assets/{dist-C85t5q3z.js → dist-BNgPhnKo.js} +1 -1
- package/dist/web/assets/{dist-CEl-Ko94.js → dist-BWoPV5P3.js} +1 -1
- package/dist/web/assets/{dist-DLuI1PxH.js → dist-CJ7isxli.js} +1 -1
- package/dist/web/assets/{dist-joQDFmfy.js → dist-CTJJYvYG.js} +1 -1
- package/dist/web/assets/{dist-CBGyhCYv.js → dist-CZz0KXAA.js} +1 -1
- package/dist/web/assets/{dist-CIMEaJAX.js → dist-DNpwgDba.js} +1 -1
- package/dist/web/assets/{dist-CTd7Kuqx.js → dist-DWCdhk-O.js} +1 -1
- package/dist/web/assets/{dist-BU8erXQF.js → dist-DqSUdjG9.js} +1 -1
- package/dist/web/assets/{dist-C54FrSb8.js → dist-Dy9K9LOR.js} +1 -1
- package/dist/web/assets/{ebnfDiagram-ZINNZB2B-irTAlMFO.js → ebnfDiagram-ZINNZB2B-75vt7539.js} +1 -1
- package/dist/web/assets/{elk-276RUBZZ-Dj5ligvC.js → elk-276RUBZZ-DXDjJVTy.js} +1 -1
- package/dist/web/assets/{erDiagram-OPXOYQCR-Bvn6rbL1.js → erDiagram-OPXOYQCR-tNNInTmk.js} +1 -1
- package/dist/web/assets/eventmodeling-NTZA5JFV-QMRehQtM.js +1 -0
- package/dist/web/assets/flowDiagram-KWPJA3E3-DJAgsbXC.js +1 -0
- package/dist/web/assets/{ganttDiagram-FUAMR5RP-BNGAUF5H.js → ganttDiagram-FUAMR5RP-h3E8lnCd.js} +1 -1
- package/dist/web/assets/{gitGraph-4MIJSDKK-DYSHOl72.js → gitGraph-4MIJSDKK-BUwY-iv2.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-X574FWY7-BGwRHrPq.js → gitGraphDiagram-X574FWY7-C0AgQH5k.js} +1 -1
- package/dist/web/assets/i18n-CfTd46OX.js +1 -0
- package/dist/web/assets/icons-BoaZfGBj.js +1 -0
- package/dist/web/assets/index-BQU3KK1E.css +1 -0
- package/dist/web/assets/index-BTpokWxr.js +2 -0
- package/dist/web/assets/{info-A6RAGUB7-DNWR20pW.js → info-A6RAGUB7-DVMZ4hdK.js} +1 -1
- package/dist/web/assets/{infoDiagram-VRGFBTTK-BhNwJLY5.js → infoDiagram-VRGFBTTK-kLaGXGQ2.js} +1 -1
- package/dist/web/assets/{init-app-cg-B_TFN.js → init-app-Bxc_l2yT.js} +1 -1
- package/dist/web/assets/{is-D0waCELe.js → is-B1kBQ5Va.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-OU5B5YK6-CSkDpn64.js → ishikawaDiagram-OU5B5YK6-Oj7bZlyo.js} +1 -1
- package/dist/web/assets/{journeyDiagram-ZHPQQLJL-D2CEecC3.js → journeyDiagram-ZHPQQLJL-BG7V2Srs.js} +1 -1
- package/dist/web/assets/{kanban-definition-PNTS6WVX-CQHlo4Hh.js → kanban-definition-PNTS6WVX-CIJiDE6d.js} +1 -1
- package/dist/web/assets/{line-C-izH1ks.js → line-D2vEKYRZ.js} +1 -1
- package/dist/web/assets/markdown-Bm2wfvok.js +16 -0
- package/dist/web/assets/mdi-Byw1NZrZ.js +1 -0
- package/dist/web/assets/{mermaid-parser.core-CAGwq6D-.js → mermaid-parser.core-BcBEWjW6.js} +3 -3
- package/dist/web/assets/{mermaid.core--xlI_0tK.js → mermaid.core-DobO0deo.js} +4 -4
- package/dist/web/assets/{mindmap-definition-NLK3R4M7-BuCxhlwy.js → mindmap-definition-NLK3R4M7-y7Qz5gBF.js} +1 -1
- package/dist/web/assets/{packet-AYTQ26CC-Bi7x5lJK.js → packet-AYTQ26CC-oRQgKr9d.js} +1 -1
- package/dist/web/assets/{pegDiagram-GJSIUBJH-qWzBPkCQ.js → pegDiagram-GJSIUBJH-RIU8XOHq.js} +1 -1
- package/dist/web/assets/{pie-WAS4IAKB-Di0wC4XB.js → pie-WAS4IAKB-qmOlsLkx.js} +1 -1
- package/dist/web/assets/{pieDiagram-5QR66LMP-BCDVY9q2.js → pieDiagram-5QR66LMP-BM932TDA.js} +1 -1
- package/dist/web/assets/pinia-BfqEuvsi.js +1 -0
- package/dist/web/assets/pinia-Cmp1GI8k.js +1 -0
- package/dist/web/assets/preview-store-D7qF6SgX.js +2 -0
- package/dist/web/assets/{project-files-store-byqyG2ts.js → project-files-store-OhGs_H7U.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-O4NWA36T-CpFObUjT.js → quadrantDiagram-O4NWA36T-qQZYwTy7.js} +1 -1
- package/dist/web/assets/{radar-RG4KPBEZ-Br8yH8rq.js → radar-RG4KPBEZ-Kdglk6eY.js} +1 -1
- package/dist/web/assets/{railroad-74A4TZTK-CACSqhA-.js → railroad-74A4TZTK-kVhMYx4I.js} +1 -1
- package/dist/web/assets/railroad-abnf-HS5TGJTU-MiKgjOXr.js +1 -0
- package/dist/web/assets/railroad-ebnf-LZEXJU2U-BFL9h7Zx.js +1 -0
- package/dist/web/assets/railroad-peg-WCYAUIDC-ChGGfIn7.js +1 -0
- package/dist/web/assets/{railroadDiagram-XR7U4H2S-sYXRKGK1.js → railroadDiagram-XR7U4H2S-K9SrOGcT.js} +1 -1
- package/dist/web/assets/{render-C7fu7uYY.js → render-Brao9Nj2.js} +1 -1
- package/dist/web/assets/repository-store-DZgQ5H7J.js +1 -0
- package/dist/web/assets/{requirementDiagram-PLB6GJNP-C9I1JbQc.js → requirementDiagram-PLB6GJNP-CtA9ZKEx.js} +1 -1
- package/dist/web/assets/runtime-core.esm-bundler-DDnHUoIy.js +1 -0
- package/dist/web/assets/{safe-storage-C76bPypO.js → safe-storage-CvVvrm4v.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-IPEJSGJF-CuvFQhPh.js → sankeyDiagram-IPEJSGJF-BH_t4exx.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-PO4LG4MO-CaVb9Y6e.js → sequenceDiagram-PO4LG4MO-hPNPqpDa.js} +1 -1
- package/dist/web/assets/single-flight-CyDZB3rb.js +1 -0
- package/dist/web/assets/{stateDiagram-v2-GCMORJYK-Dp_APryr.js → stateDiagram-v2-GCMORJYK-BVmjZDRD.js} +1 -1
- package/dist/web/assets/{swimlanes-2SLR337P-FclUI-k0.js → swimlanes-2SLR337P-Tgk8-6jj.js} +1 -1
- package/dist/web/assets/swimlanesDiagram-TC7HE7FX-W1zDrK61.js +8 -0
- package/dist/web/assets/{terminal-store-BnEkXuBj.js → terminal-store-CKgJjtC6.js} +1 -1
- package/dist/web/assets/theme-slSxLNv6.js +1 -0
- package/dist/web/assets/{timeline-definition-EJHVYXUP-BAqwqj3c.js → timeline-definition-EJHVYXUP-lAIHEGe8.js} +1 -1
- package/dist/web/assets/{treeView-Q6P3EWNA-D87jJbUQ.js → treeView-Q6P3EWNA-CdvzKtWf.js} +1 -1
- package/dist/web/assets/{treemap-WGGIJYW6-B6nhGhRc.js → treemap-WGGIJYW6-BxDSJfrJ.js} +1 -1
- package/dist/web/assets/use-add-agent-context-BSHGL5iV.js +1 -0
- package/dist/web/assets/use-app-theme-fmVV2QM8.js +1 -0
- package/dist/web/assets/use-countdown-D6_qSOZJ.js +1 -0
- package/dist/web/assets/use-notify-error-Dx2D9IEP.js +1 -0
- package/dist/web/assets/{use-panel-width-CjSWCFr4.js → use-panel-width-BYOPuHat.js} +1 -1
- package/dist/web/assets/use-router-link-D7geCGQI.js +1 -0
- package/dist/web/assets/use-row-height-BK8kNihW.js +1 -0
- package/dist/web/assets/use-server-events-CvcbsbIf.js +1 -0
- package/dist/web/assets/use-virtual-scroll-DixIsJk4.js +1 -0
- package/dist/web/assets/{use-workspace-navigation-CnebLvBV.js → use-workspace-navigation-AaRMWmjQ.js} +1 -1
- package/dist/web/assets/{usecaseDiagram-POWQR4AR-7YcIKxAb.js → usecaseDiagram-POWQR4AR-BH3KvMpz.js} +1 -1
- package/dist/web/assets/{vennDiagram-UO4OBE2U-BZq5cFC4.js → vennDiagram-UO4OBE2U-Dfi-raKp.js} +1 -1
- package/dist/web/assets/viewport-store-NqQS7itT.js +1 -0
- package/dist/web/assets/{vue-i18n.runtime-CEtihHHL.js → vue-i18n.runtime-JOo8b7-t.js} +2 -2
- package/dist/web/assets/{wardley-WFR3VGLG-BT8YO9H4.js → wardley-WFR3VGLG-DmbtSM24.js} +1 -1
- package/dist/web/assets/{wardleyDiagram-VNRHLVJA-rDpXFf6D.js → wardleyDiagram-VNRHLVJA-DIzhGvI7.js} +1 -1
- package/dist/web/assets/weighted-lru-BFtZKA_y.js +1 -0
- package/dist/web/assets/workspace-navigation-xfxULfM7.js +1 -0
- package/dist/web/assets/{xychartDiagram-PMCCYNJV-ClniUuZc.js → xychartDiagram-PMCCYNJV-XgqSHH_N.js} +1 -1
- package/dist/web/index.html +9 -9
- package/package.json +5 -3
- package/dist/web/assets/AccessPage-CX3w30zw.js +0 -1
- package/dist/web/assets/AppPage-PFJG281y.js +0 -1
- package/dist/web/assets/CreateButton-Ch0b7juj.js +0 -1
- package/dist/web/assets/CreateReviewFabButton-DTuJzw3q.js +0 -1
- package/dist/web/assets/IndexPage-tgW07Qvs.js +0 -1
- package/dist/web/assets/MainLayout-C6yBhQnf.css +0 -1
- package/dist/web/assets/MainLayout-Cw4jpB1x.js +0 -8
- package/dist/web/assets/NoteVisualEditor-DiGhLhQg.js +0 -1054
- package/dist/web/assets/NotesPage-CVyVr9tl.js +0 -4
- package/dist/web/assets/NotesPage-CxGnZuVQ.css +0 -1
- package/dist/web/assets/PanelResize-B6FP9ZVB.js +0 -1
- package/dist/web/assets/ProjectFilePage-CkxfX9b1.js +0 -1
- package/dist/web/assets/QBtn-CyyV1Bx_.js +0 -1
- package/dist/web/assets/QExpansionItem-Dp9lbdVb.js +0 -4
- package/dist/web/assets/QFab-LOmZ9rev.js +0 -1
- package/dist/web/assets/QInput-Dq6131uz.js +0 -1
- package/dist/web/assets/QSelect-B34OqtIH.js +0 -1
- package/dist/web/assets/QSpace-BhOVGpQh.js +0 -1
- package/dist/web/assets/QVirtualScroll-BYgJ1Kh2.js +0 -1
- package/dist/web/assets/ReviewDetailPage-CkCilMNW.css +0 -1
- package/dist/web/assets/ReviewDetailPage-GNjBa4X0.js +0 -1
- package/dist/web/assets/ReviewsPage-An5fRS92.js +0 -1
- package/dist/web/assets/StatusSwitcher-DrFHHwGm.js +0 -1
- package/dist/web/assets/architecture-7GRP2DOG-BPCNj4lR.js +0 -1
- package/dist/web/assets/channel-CzRYxuLe.js +0 -1
- package/dist/web/assets/create-B9Tn5Xvi.js +0 -1
- package/dist/web/assets/diff-store-B4adGxC2.js +0 -93
- package/dist/web/assets/eventmodeling-NTZA5JFV-BJsTZ_nG.js +0 -1
- package/dist/web/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNa-Dr0goTwe.woff +0 -0
- package/dist/web/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ-D-x-0Q06.woff2 +0 -0
- package/dist/web/assets/flowDiagram-KWPJA3E3-CvXh1Df7.js +0 -1
- package/dist/web/assets/i18n-DnlAcIbT.js +0 -1
- package/dist/web/assets/index-Cw7GJi3K.js +0 -2
- package/dist/web/assets/index-wsOPzloa.css +0 -1
- package/dist/web/assets/markdown-CvtLTiBZ.js +0 -16
- package/dist/web/assets/pinia-DO0AdKGg.js +0 -1
- package/dist/web/assets/pinia-uOZCmBi-.js +0 -1
- package/dist/web/assets/preview-store-DyO8G-ox.js +0 -1
- package/dist/web/assets/railroad-abnf-HS5TGJTU-DTBsRB1c.js +0 -1
- package/dist/web/assets/railroad-ebnf-LZEXJU2U-D3mrY4ar.js +0 -1
- package/dist/web/assets/railroad-peg-WCYAUIDC-33ZjWX0u.js +0 -1
- package/dist/web/assets/repository-store-DtRDth1L.js +0 -1
- package/dist/web/assets/runtime-core.esm-bundler-CAvPiMpd.js +0 -1
- package/dist/web/assets/single-flight-fPyIy7h5.js +0 -1
- package/dist/web/assets/swimlanesDiagram-TC7HE7FX-CuUvsn0e.js +0 -8
- package/dist/web/assets/theme-CnbaLamF.js +0 -1
- package/dist/web/assets/use-add-agent-context-xHAjjOf1.js +0 -1
- package/dist/web/assets/use-app-theme-DEowpWRR.js +0 -1
- package/dist/web/assets/use-countdown-DlcwwJrs.js +0 -1
- package/dist/web/assets/use-router-link-CUoYaYUw.js +0 -1
- package/dist/web/assets/use-row-height-BsE9-rO2.js +0 -1
- package/dist/web/assets/use-server-events-C2X4Xz00.js +0 -1
- package/dist/web/assets/use-virtual-scroll-BAZGswHv.js +0 -1
- package/dist/web/assets/viewport-store-CCHiY2QG.js +0 -1
- package/dist/web/assets/weighted-lru-BGovtJ2a.js +0 -1
- package/dist/web/assets/workspace-navigation-DdW0rSGz.js +0 -1
- /package/dist/web/assets/{PanelResize-XjrbOj2S.css → AddToAgentButton-XjrbOj2S.css} +0 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import { piFailureReason } from "./errors.js";
|
|
2
|
+
import { promptToPiMessage } from "./vendor/prompt.js";
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { McpRegistry } from "./mcp.js";
|
|
5
|
+
import { PiProcess } from "./process.js";
|
|
6
|
+
import { BRIDGE_TIMEOUT_MS, MAX_PENDING_CALLS } from "./control.js";
|
|
7
|
+
import { ARTIFACT_TASK_INSTRUCTIONS } from "../../../shared/artifact-tools/instructions.js";
|
|
8
|
+
import { isRecord } from "../../../shared/utils/guards.js";
|
|
9
|
+
export class PiSession {
|
|
10
|
+
id = randomUUID();
|
|
11
|
+
registry = new McpRegistry();
|
|
12
|
+
process = new PiProcess();
|
|
13
|
+
#generation = 0;
|
|
14
|
+
#turn;
|
|
15
|
+
#seen = new Set();
|
|
16
|
+
#pending = 0;
|
|
17
|
+
#ready = false;
|
|
18
|
+
#closed = false;
|
|
19
|
+
#cancelled = false;
|
|
20
|
+
#stopReason = 'end_turn';
|
|
21
|
+
#agentStarted = false;
|
|
22
|
+
#thinking = [];
|
|
23
|
+
#completion;
|
|
24
|
+
#begun;
|
|
25
|
+
#models = [];
|
|
26
|
+
#state = {};
|
|
27
|
+
profile;
|
|
28
|
+
callbacks;
|
|
29
|
+
constructor(profile, callbacks) {
|
|
30
|
+
this.profile = profile;
|
|
31
|
+
this.callbacks = callbacks;
|
|
32
|
+
const failure = () => {
|
|
33
|
+
const wasReady = this.#ready;
|
|
34
|
+
this.close();
|
|
35
|
+
if (wasReady)
|
|
36
|
+
callbacks.failure();
|
|
37
|
+
};
|
|
38
|
+
this.process.onFailure = failure;
|
|
39
|
+
this.registry.onFailure = failure;
|
|
40
|
+
this.process.onControl = frame => {
|
|
41
|
+
if (frame.type === 'begun' &&
|
|
42
|
+
frame.generation === this.#generation &&
|
|
43
|
+
this.#begun) {
|
|
44
|
+
this.#begun();
|
|
45
|
+
this.#begun = undefined;
|
|
46
|
+
}
|
|
47
|
+
else if (frame.type === 'call') {
|
|
48
|
+
void this.call(frame).catch(failure);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
failure();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
this.process.onEvent = event => {
|
|
55
|
+
void this.event(event).catch(failure);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async start(cwd, servers) {
|
|
59
|
+
try {
|
|
60
|
+
await this.registry.connect(servers);
|
|
61
|
+
if (this.#closed)
|
|
62
|
+
throw new Error('Pi bridge closed during discovery');
|
|
63
|
+
await this.process.start(cwd, this.profile, {
|
|
64
|
+
tools: this.registry.tools,
|
|
65
|
+
instructions: `${this.registry.instructions}\n\n${ARTIFACT_TASK_INSTRUCTIONS}`
|
|
66
|
+
});
|
|
67
|
+
this.#state = await this.process.request('get_state');
|
|
68
|
+
if (!isRecord(this.#state.model)) {
|
|
69
|
+
throw new Error('Pi bridge requires a configured model and authorization in the installed pi');
|
|
70
|
+
}
|
|
71
|
+
const available = await this.process.request('get_available_models');
|
|
72
|
+
if (!Array.isArray(available.models)) {
|
|
73
|
+
throw new Error('Pi runtime did not return its model catalog');
|
|
74
|
+
}
|
|
75
|
+
this.#models = available.models.filter(isRecord).flatMap(model => typeof model.id === 'string' && typeof model.provider === 'string'
|
|
76
|
+
? [
|
|
77
|
+
{
|
|
78
|
+
id: model.id,
|
|
79
|
+
provider: model.provider,
|
|
80
|
+
name: typeof model.name === 'string' ? model.name : model.id
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
: []);
|
|
84
|
+
await this.refreshThinking();
|
|
85
|
+
this.#ready = true;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
this.close();
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
assertSession(id) {
|
|
93
|
+
if (!this.#ready || this.#closed || id !== this.id) {
|
|
94
|
+
throw new Error('Unknown or unavailable pi session');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
get config() {
|
|
98
|
+
const model = this.#state.model;
|
|
99
|
+
const options = [
|
|
100
|
+
{
|
|
101
|
+
type: 'select',
|
|
102
|
+
id: 'thought_level',
|
|
103
|
+
category: 'thought_level',
|
|
104
|
+
name: 'Thinking',
|
|
105
|
+
currentValue: String(this.#state.thinkingLevel),
|
|
106
|
+
options: this.#thinking.map(value => ({ value, name: value }))
|
|
107
|
+
}
|
|
108
|
+
];
|
|
109
|
+
if (!isRecord(model) || !this.#models.length)
|
|
110
|
+
return options;
|
|
111
|
+
return [
|
|
112
|
+
...options,
|
|
113
|
+
{
|
|
114
|
+
type: 'select',
|
|
115
|
+
id: 'model',
|
|
116
|
+
category: 'model',
|
|
117
|
+
name: 'Model',
|
|
118
|
+
currentValue: `${String(model.provider)}/${String(model.id)}`,
|
|
119
|
+
options: this.#models.map(value => ({
|
|
120
|
+
value: `${value.provider}/${value.id}`,
|
|
121
|
+
name: value.name
|
|
122
|
+
}))
|
|
123
|
+
}
|
|
124
|
+
];
|
|
125
|
+
}
|
|
126
|
+
async setConfig(id, value) {
|
|
127
|
+
if (this.#turn) {
|
|
128
|
+
throw new Error('Pi setting is unavailable');
|
|
129
|
+
}
|
|
130
|
+
if (id === 'thought_level' && this.#thinking.includes(value)) {
|
|
131
|
+
await this.process.request('set_thinking_level', { level: value });
|
|
132
|
+
this.#state = await this.process.request('get_state');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (id !== 'model')
|
|
136
|
+
throw new Error('Unknown pi setting');
|
|
137
|
+
const model = this.#models.find(candidate => `${candidate.provider}/${candidate.id}` === value);
|
|
138
|
+
if (!model)
|
|
139
|
+
throw new Error('Unknown pi model');
|
|
140
|
+
await this.process.request('set_model', {
|
|
141
|
+
provider: model.provider,
|
|
142
|
+
modelId: model.id
|
|
143
|
+
});
|
|
144
|
+
this.#state = await this.process.request('get_state');
|
|
145
|
+
await this.refreshThinking();
|
|
146
|
+
}
|
|
147
|
+
async refreshThinking() {
|
|
148
|
+
const thinking = await this.process.request('get_available_thinking_levels');
|
|
149
|
+
if (!Array.isArray(thinking.levels) ||
|
|
150
|
+
!thinking.levels.every(value => typeof value === 'string')) {
|
|
151
|
+
throw new Error('Pi thinking levels unavailable');
|
|
152
|
+
}
|
|
153
|
+
this.#thinking = thinking.levels;
|
|
154
|
+
}
|
|
155
|
+
async prompt(blocks) {
|
|
156
|
+
if (this.#turn || !this.#ready || this.#closed) {
|
|
157
|
+
throw new Error('Pi session is not ready for a prompt');
|
|
158
|
+
}
|
|
159
|
+
const { message, images } = promptToPiMessage(blocks);
|
|
160
|
+
if (this.profile === 'validator' && message.trimStart().startsWith('/')) {
|
|
161
|
+
throw new Error('Validator slash commands are unavailable');
|
|
162
|
+
}
|
|
163
|
+
if (/^\s*\/reload(?:\s|$)/.test(message)) {
|
|
164
|
+
throw new Error('Pi bridge reload requires a new chat');
|
|
165
|
+
}
|
|
166
|
+
const turn = new AbortController();
|
|
167
|
+
this.#turn = turn;
|
|
168
|
+
this.#generation++;
|
|
169
|
+
this.#cancelled = false;
|
|
170
|
+
this.#agentStarted = false;
|
|
171
|
+
this.#stopReason = 'end_turn';
|
|
172
|
+
this.#seen.clear();
|
|
173
|
+
try {
|
|
174
|
+
await new Promise((resolve, reject) => {
|
|
175
|
+
const timer = setTimeout(() => {
|
|
176
|
+
this.#begun = undefined;
|
|
177
|
+
reject(new Error('Pi turn control acknowledgement timed out'));
|
|
178
|
+
}, BRIDGE_TIMEOUT_MS);
|
|
179
|
+
this.#begun = () => {
|
|
180
|
+
clearTimeout(timer);
|
|
181
|
+
resolve();
|
|
182
|
+
};
|
|
183
|
+
this.process.send('begin', { generation: this.#generation });
|
|
184
|
+
});
|
|
185
|
+
if (turn.signal.aborted)
|
|
186
|
+
return { stopReason: 'cancelled' };
|
|
187
|
+
const completion = new Promise((resolve, reject) => {
|
|
188
|
+
this.#completion = { resolve, reject };
|
|
189
|
+
});
|
|
190
|
+
completion.catch(() => { });
|
|
191
|
+
const deadline = setTimeout(() => {
|
|
192
|
+
this.#completion?.reject(new Error('Pi turn deadline exceeded'));
|
|
193
|
+
this.close();
|
|
194
|
+
}, 300000);
|
|
195
|
+
try {
|
|
196
|
+
await this.process.request('prompt', { message, images });
|
|
197
|
+
if (message.trimStart().startsWith('/') && !this.#agentStarted) {
|
|
198
|
+
this.#completion?.resolve();
|
|
199
|
+
}
|
|
200
|
+
await completion;
|
|
201
|
+
}
|
|
202
|
+
finally {
|
|
203
|
+
clearTimeout(deadline);
|
|
204
|
+
this.#completion = undefined;
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
stopReason: this.#cancelled ? 'cancelled' : this.#stopReason
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
if (this.#cancelled)
|
|
212
|
+
return { stopReason: 'cancelled' };
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
turn.abort();
|
|
217
|
+
this.#turn = undefined;
|
|
218
|
+
this.#seen.clear();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async cancel() {
|
|
222
|
+
if (!this.#turn)
|
|
223
|
+
return;
|
|
224
|
+
this.#cancelled = true;
|
|
225
|
+
this.#turn.abort();
|
|
226
|
+
this.process.send('cancel', { generation: this.#generation });
|
|
227
|
+
await this.process.request('abort');
|
|
228
|
+
}
|
|
229
|
+
async call(frame) {
|
|
230
|
+
const turn = this.#turn;
|
|
231
|
+
if (!turn ||
|
|
232
|
+
turn.signal.aborted ||
|
|
233
|
+
frame.generation !== this.#generation ||
|
|
234
|
+
typeof frame.id !== 'string' ||
|
|
235
|
+
typeof frame.name !== 'string' ||
|
|
236
|
+
this.#seen.has(frame.id) ||
|
|
237
|
+
this.#seen.size >= 10000 ||
|
|
238
|
+
this.#pending >= MAX_PENDING_CALLS) {
|
|
239
|
+
throw new Error('Invalid, repeated or stale pi call');
|
|
240
|
+
}
|
|
241
|
+
this.#seen.add(frame.id);
|
|
242
|
+
this.#pending++;
|
|
243
|
+
const generation = this.#generation;
|
|
244
|
+
const id = frame.id;
|
|
245
|
+
let result;
|
|
246
|
+
try {
|
|
247
|
+
const snapshot = this.registry.snapshot(frame.name, frame.arguments);
|
|
248
|
+
const signal = AbortSignal.any([
|
|
249
|
+
turn.signal,
|
|
250
|
+
AbortSignal.timeout(BRIDGE_TIMEOUT_MS)
|
|
251
|
+
]);
|
|
252
|
+
const permissionRequest = this.callbacks.permission({
|
|
253
|
+
sessionId: this.id,
|
|
254
|
+
toolCall: {
|
|
255
|
+
toolCallId: id,
|
|
256
|
+
title: snapshot.descriptor.name,
|
|
257
|
+
name: snapshot.descriptor.name,
|
|
258
|
+
kind: 'execute',
|
|
259
|
+
rawInput: structuredClone(snapshot.arguments),
|
|
260
|
+
_meta: {
|
|
261
|
+
githumanPi: {
|
|
262
|
+
server: snapshot.descriptor.server,
|
|
263
|
+
tool: snapshot.descriptor.originalName,
|
|
264
|
+
registryGeneration: 1
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
options: [
|
|
269
|
+
{ optionId: 'allow_once', name: 'Allow once', kind: 'allow_once' },
|
|
270
|
+
{
|
|
271
|
+
optionId: 'reject_once',
|
|
272
|
+
name: 'Reject once',
|
|
273
|
+
kind: 'reject_once'
|
|
274
|
+
}
|
|
275
|
+
]
|
|
276
|
+
}, signal);
|
|
277
|
+
let abortPermission;
|
|
278
|
+
let permission;
|
|
279
|
+
try {
|
|
280
|
+
permission = await Promise.race([
|
|
281
|
+
permissionRequest,
|
|
282
|
+
new Promise((_resolve, reject) => {
|
|
283
|
+
abortPermission = () => reject(new Error('Pi permission deadline exceeded or call cancelled'));
|
|
284
|
+
if (signal.aborted) {
|
|
285
|
+
abortPermission();
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
signal.addEventListener('abort', abortPermission, { once: true });
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
]);
|
|
292
|
+
}
|
|
293
|
+
finally {
|
|
294
|
+
if (abortPermission) {
|
|
295
|
+
signal.removeEventListener('abort', abortPermission);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (signal.aborted ||
|
|
299
|
+
turn !== this.#turn ||
|
|
300
|
+
generation !== this.#generation ||
|
|
301
|
+
permission.outcome.outcome !== 'selected' ||
|
|
302
|
+
permission.outcome.optionId !== 'allow_once') {
|
|
303
|
+
throw new Error('Pi MCP permission denied or cancelled');
|
|
304
|
+
}
|
|
305
|
+
result = await this.registry.call(frame.name, snapshot.arguments, signal);
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
result = {
|
|
309
|
+
isError: true,
|
|
310
|
+
content: [
|
|
311
|
+
{
|
|
312
|
+
type: 'text',
|
|
313
|
+
text: 'Pi MCP call failed, was denied, or was cancelled.'
|
|
314
|
+
}
|
|
315
|
+
]
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
finally {
|
|
319
|
+
this.#pending--;
|
|
320
|
+
}
|
|
321
|
+
if (!this.#closed &&
|
|
322
|
+
turn === this.#turn &&
|
|
323
|
+
!turn.signal.aborted &&
|
|
324
|
+
generation === this.#generation) {
|
|
325
|
+
this.process.send('result', { id, generation, result });
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
async event(event) {
|
|
329
|
+
if (!this.#turn)
|
|
330
|
+
return;
|
|
331
|
+
if (event.type === 'agent_start')
|
|
332
|
+
this.#agentStarted = true;
|
|
333
|
+
if (event.type === 'message_end' && isRecord(event.message)) {
|
|
334
|
+
if (event.message.stopReason === 'length')
|
|
335
|
+
this.#stopReason = 'max_tokens';
|
|
336
|
+
if (event.message.stopReason === 'refusal')
|
|
337
|
+
this.#stopReason = 'refusal';
|
|
338
|
+
}
|
|
339
|
+
if (event.type === 'agent_end') {
|
|
340
|
+
this.#completion?.resolve();
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
if (event.type === 'message_end' &&
|
|
344
|
+
isRecord(event.message) &&
|
|
345
|
+
event.message.stopReason === 'error') {
|
|
346
|
+
this.#completion?.reject(new Error(piFailureReason(event.message.errorMessage)));
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (this.#turn.signal.aborted)
|
|
350
|
+
return;
|
|
351
|
+
let update;
|
|
352
|
+
if (event.type === 'message_update' &&
|
|
353
|
+
isRecord(event.assistantMessageEvent)) {
|
|
354
|
+
const delta = event.assistantMessageEvent;
|
|
355
|
+
if ((delta.type === 'text_delta' || delta.type === 'thinking_delta') &&
|
|
356
|
+
typeof delta.delta === 'string') {
|
|
357
|
+
update = {
|
|
358
|
+
sessionUpdate: delta.type === 'text_delta'
|
|
359
|
+
? 'agent_message_chunk'
|
|
360
|
+
: 'agent_thought_chunk',
|
|
361
|
+
content: { type: 'text', text: delta.delta }
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
else if (event.type === 'tool_execution_start' &&
|
|
366
|
+
typeof event.toolCallId === 'string') {
|
|
367
|
+
update = {
|
|
368
|
+
sessionUpdate: 'tool_call',
|
|
369
|
+
toolCallId: event.toolCallId,
|
|
370
|
+
title: String(event.toolName),
|
|
371
|
+
name: String(event.toolName),
|
|
372
|
+
rawInput: event.args,
|
|
373
|
+
status: 'in_progress',
|
|
374
|
+
kind: 'execute'
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
else if (event.type === 'tool_execution_end' &&
|
|
378
|
+
typeof event.toolCallId === 'string') {
|
|
379
|
+
const result = event.result;
|
|
380
|
+
const content = isRecord(result) && Array.isArray(result.content)
|
|
381
|
+
? result.content.filter(isRecord).flatMap(block => block.type === 'text' && typeof block.text === 'string'
|
|
382
|
+
? [
|
|
383
|
+
{
|
|
384
|
+
type: 'content',
|
|
385
|
+
content: { type: 'text', text: block.text }
|
|
386
|
+
}
|
|
387
|
+
]
|
|
388
|
+
: [])
|
|
389
|
+
: [];
|
|
390
|
+
update = {
|
|
391
|
+
sessionUpdate: 'tool_call_update',
|
|
392
|
+
toolCallId: event.toolCallId,
|
|
393
|
+
status: event.isError ? 'failed' : 'completed',
|
|
394
|
+
content
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
if (update)
|
|
398
|
+
await this.callbacks.update(this.id, update);
|
|
399
|
+
}
|
|
400
|
+
close() {
|
|
401
|
+
if (this.#closed)
|
|
402
|
+
return;
|
|
403
|
+
this.#closed = true;
|
|
404
|
+
this.#turn?.abort();
|
|
405
|
+
this.#completion?.reject(new Error('Pi session closed'));
|
|
406
|
+
this.process.close();
|
|
407
|
+
void this.registry.close();
|
|
408
|
+
}
|
|
409
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Sergii Kozak
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# pi-acp provenance
|
|
2
|
+
|
|
3
|
+
Baseline: published MIT pi-acp@0.0.34 tarball, compared to upstream commit
|
|
4
|
+
04d0a15d6bb42bb65cce5c9caedcdcb2cdcb6905 before reuse.
|
|
5
|
+
|
|
6
|
+
Tarball: https://registry.npmjs.org/pi-acp/-/pi-acp-0.0.34.tgz
|
|
7
|
+
SHA-256: 4b3bf6bc71bed2b7f43dd7fcfa1906e464828e471740da593107e4f1608f2650
|
|
8
|
+
SHA-512 (npm integrity): MrCp37UbpUzkTkzTIMJQf1RYrT+kr4fgGDGFoLmBN26UupuCZp0XxVIY+7XYsMo3yDnzDeZUJ0jPyM3Si6Bkkg==
|
|
9
|
+
Published bundle SHA-256: 324aeb8bba1228937e16b1326fb3e014e2a625b2dea549dbcd49b006cd5df6a2
|
|
10
|
+
|
|
11
|
+
The tarball source map has 17 sources. Four differ from the git commit:
|
|
12
|
+
acp/agent.ts, acp/session.ts, acp/pi-sessions.ts, acp/translate/prompt.ts.
|
|
13
|
+
The published tarball is the selected baseline, including prompt.ts.
|
|
14
|
+
|
|
15
|
+
| Layer | Local difference |
|
|
16
|
+
| ----------------------------------------------- | ---------------------------------------------------------------------- |
|
|
17
|
+
| prompt.ts | Formatting and comment conventions; imported from published source map |
|
|
18
|
+
| ACP agent/session | New SDK 1.5 builder API; one session; no restore/history handlers |
|
|
19
|
+
| RPC process | New bounded transport; no session files; no Windows launchers |
|
|
20
|
+
| MCP/control/permissions | New GitHuman-owned registry, extension and ACP gate |
|
|
21
|
+
| Upstream history, session store, slash commands | Excluded |
|
|
22
|
+
|
|
23
|
+
Keep LICENSE with the redistributed prompt conversion code. Runtime npx and
|
|
24
|
+
pi SDK dependencies are not required. Maintainers compare upstream changes
|
|
25
|
+
when supported pi versions or upstream security fixes change. Reconsider the
|
|
26
|
+
SDK-runtime ADR if the fork can no longer be reviewed as a bounded change.
|
|
27
|
+
|
|
28
|
+
macOS verification was explicitly skipped by the user because no host was
|
|
29
|
+
available. Linux tests do not establish macOS support.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export function promptToPiMessage(blocks) {
|
|
2
|
+
let message = '';
|
|
3
|
+
const images = [];
|
|
4
|
+
for (const b of blocks) {
|
|
5
|
+
switch (b.type) {
|
|
6
|
+
case 'text':
|
|
7
|
+
message += b.text;
|
|
8
|
+
break;
|
|
9
|
+
case 'resource_link':
|
|
10
|
+
// A lightweight, human-readable hint for the LLM.
|
|
11
|
+
message += `\n[Context] ${b.uri}`;
|
|
12
|
+
break;
|
|
13
|
+
case 'image': {
|
|
14
|
+
// pi expects base64 image bytes in `data` without a data-url prefix.
|
|
15
|
+
images.push({
|
|
16
|
+
type: 'image',
|
|
17
|
+
mimeType: b.mimeType,
|
|
18
|
+
data: b.data
|
|
19
|
+
});
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
case 'resource': {
|
|
23
|
+
// Clients should not send this if embeddedContext=false, but be resilient.
|
|
24
|
+
const r = b.resource;
|
|
25
|
+
const uri = typeof r?.uri === 'string' ? r.uri : '(unknown)';
|
|
26
|
+
if ('text' in r && typeof r.text === 'string') {
|
|
27
|
+
// TextResourceContents
|
|
28
|
+
const mime = typeof r?.mimeType === 'string' ? r.mimeType : 'text/plain';
|
|
29
|
+
message += `\n[Embedded Context] ${uri} (${mime})\n${r.text}`;
|
|
30
|
+
}
|
|
31
|
+
else if ('blob' in r && typeof r.blob === 'string') {
|
|
32
|
+
// BlobResourceContents
|
|
33
|
+
const mime = typeof r?.mimeType === 'string'
|
|
34
|
+
? r.mimeType
|
|
35
|
+
: 'application/octet-stream';
|
|
36
|
+
const bytes = Buffer.byteLength(r.blob, 'base64');
|
|
37
|
+
message += `\n[Embedded Context] ${uri} (${mime}, ${bytes} bytes)`;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
message += `\n[Embedded Context] ${uri}`;
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
case 'audio': {
|
|
45
|
+
// Not supported by pi. Provide a marker so we don't silently drop context.
|
|
46
|
+
const bytes = Buffer.byteLength(b.data, 'base64');
|
|
47
|
+
message += `\n[Audio] (${b.mimeType}, ${bytes} bytes) not supported by pi-acp`;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
default:
|
|
51
|
+
// Ignore unknown block types for now.
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { message, images };
|
|
56
|
+
}
|
package/dist/server/app.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
import { artifactActionRoutes } from "./routes/artifact-actions.js";
|
|
2
|
+
import { artifactTransitionRoutes } from "./routes/artifact-transitions.js";
|
|
3
|
+
import { addressUrl } from "../shared/network/address-url.js";
|
|
4
|
+
import { artifactAgentRoutes } from "./routes/artifact-agent.js";
|
|
5
|
+
import { ForbiddenError } from "./errors/http.js";
|
|
6
|
+
import { artifactDefinitionRoutes } from "./routes/artifact-definitions.js";
|
|
7
|
+
import { DEFAULT_DB_PREFIX } from "../shared/app/storage-constants.js";
|
|
8
|
+
import { artifactRoutes } from "./routes/artifacts.js";
|
|
9
|
+
import { ArtifactStorageService } from "./services/artifact-storage.service.js";
|
|
10
|
+
import { ArtifactMaintenanceService } from "./services/artifact-maintenance.service.js";
|
|
1
11
|
import { watchNotes } from "./services/notes-watcher.service.js";
|
|
2
12
|
import { notesRoutes } from "./routes/notes.js";
|
|
3
13
|
import { NotesService } from "./services/notes.service.js";
|
|
@@ -49,8 +59,15 @@ const DEVICE_SWEEP_MS = 60 * 60 * 1000;
|
|
|
49
59
|
// also when another server process on the same database revoked it.
|
|
50
60
|
// One indexed SELECT per connected device.
|
|
51
61
|
const DEVICE_RECHECK_MS = 2000;
|
|
62
|
+
// A wildcard bind accepts loopback connections; the MCP process connects there.
|
|
63
|
+
const WILDCARD_LOOPBACK = {
|
|
64
|
+
'::': '::1',
|
|
65
|
+
'0.0.0.0': '127.0.0.1'
|
|
66
|
+
};
|
|
52
67
|
export function buildApp(options = {}) {
|
|
53
68
|
const app = Fastify({
|
|
69
|
+
// Logging is off. Redact the Authorization header before you turn it on:
|
|
70
|
+
// it carries the agent session key (ADR 0096).
|
|
54
71
|
logger: false,
|
|
55
72
|
forceCloseConnections: true,
|
|
56
73
|
ajv: {
|
|
@@ -62,6 +79,7 @@ export function buildApp(options = {}) {
|
|
|
62
79
|
]
|
|
63
80
|
}
|
|
64
81
|
});
|
|
82
|
+
const allowedHosts = new AllowedHosts(options.allowedHosts);
|
|
65
83
|
const repositoryPath = options.repositoryPath ?? process.cwd();
|
|
66
84
|
const db = options.db ?? createTestDatabase();
|
|
67
85
|
const eventBus = options.eventBus ?? createEventBus();
|
|
@@ -70,6 +88,8 @@ export function buildApp(options = {}) {
|
|
|
70
88
|
onChange: () => eventBus.publish({ type: 'devices:changed' })
|
|
71
89
|
});
|
|
72
90
|
const deviceConnections = new DeviceConnections(devices);
|
|
91
|
+
// Set after the access hook exists, because the registry needs the listening server address.
|
|
92
|
+
let agentRegistry;
|
|
73
93
|
devices.removeExpired();
|
|
74
94
|
const sweep = setInterval(() => devices.removeExpired(), DEVICE_SWEEP_MS);
|
|
75
95
|
sweep.unref();
|
|
@@ -92,7 +112,16 @@ export function buildApp(options = {}) {
|
|
|
92
112
|
app.register(fastifyPlugin(async (root) => {
|
|
93
113
|
root.addHook('onRequest', createAccessHook({
|
|
94
114
|
devices,
|
|
95
|
-
allowedHosts
|
|
115
|
+
allowedHosts,
|
|
116
|
+
authorizeArtifactAgent(request, reply) {
|
|
117
|
+
const id = agentRegistry?.authenticateArtifactKey(request.headers.authorization);
|
|
118
|
+
if (!id || !agentRegistry) {
|
|
119
|
+
throw new ForbiddenError('Artifact session access denied.');
|
|
120
|
+
}
|
|
121
|
+
const release = agentRegistry.trackArtifactRequest(id, () => reply.raw.destroy());
|
|
122
|
+
reply.raw.once('finish', release);
|
|
123
|
+
reply.raw.once('close', release);
|
|
124
|
+
}
|
|
96
125
|
}));
|
|
97
126
|
}));
|
|
98
127
|
// The spec collects routes as they are added, so it comes before them.
|
|
@@ -120,6 +149,45 @@ export function buildApp(options = {}) {
|
|
|
120
149
|
watcher.close();
|
|
121
150
|
});
|
|
122
151
|
}
|
|
152
|
+
const artifacts = options.artifacts ??
|
|
153
|
+
new ArtifactStorageService({
|
|
154
|
+
db,
|
|
155
|
+
repositoryPath,
|
|
156
|
+
prefix: options.artifactPrefix ?? DEFAULT_DB_PREFIX,
|
|
157
|
+
eventBus
|
|
158
|
+
});
|
|
159
|
+
app.register(artifactRoutes, { service: artifacts });
|
|
160
|
+
app.register(artifactActionRoutes, {
|
|
161
|
+
service: artifacts.lifecycle,
|
|
162
|
+
recheckAccess: createAccessHook({ devices, allowedHosts })
|
|
163
|
+
});
|
|
164
|
+
artifacts.lifecycle.transitions.setActorGuard(actor => actor.id === 'local' || devices.isTrusted(actor.id));
|
|
165
|
+
artifacts.lifecycle.transitions.setErrorHandler(error => app.log.error({ err: error }, 'Artifact transition work failed'));
|
|
166
|
+
app.register(artifactTransitionRoutes, {
|
|
167
|
+
service: artifacts.lifecycle.transitions,
|
|
168
|
+
recheckAccess: createAccessHook({ devices, allowedHosts })
|
|
169
|
+
});
|
|
170
|
+
app.addHook('onReady', async () => {
|
|
171
|
+
artifacts.lifecycle.jobs.recover();
|
|
172
|
+
artifacts.lifecycle.transitions.start();
|
|
173
|
+
});
|
|
174
|
+
app.addHook('onClose', async () => {
|
|
175
|
+
artifacts.lifecycle.transitions.stop();
|
|
176
|
+
artifacts.lifecycle.jobs.close();
|
|
177
|
+
});
|
|
178
|
+
app.register(artifactDefinitionRoutes, { storage: artifacts });
|
|
179
|
+
const artifactMaintenance = new ArtifactMaintenanceService({
|
|
180
|
+
storage: artifacts,
|
|
181
|
+
onError: (error, phase) => {
|
|
182
|
+
app.log.error({ err: error, phase }, 'Artifact maintenance failed');
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
app.addHook('onReady', async () => {
|
|
186
|
+
artifactMaintenance.start();
|
|
187
|
+
});
|
|
188
|
+
app.addHook('onClose', async () => {
|
|
189
|
+
artifactMaintenance.stop();
|
|
190
|
+
});
|
|
123
191
|
app.register(diffRoutes, { repositoryPath });
|
|
124
192
|
app.register(gitRoutes, { repositoryPath });
|
|
125
193
|
app.register(projectFileRoutes, { repositoryPath });
|
|
@@ -148,12 +216,31 @@ export function buildApp(options = {}) {
|
|
|
148
216
|
});
|
|
149
217
|
}
|
|
150
218
|
if (options.agentPresets) {
|
|
219
|
+
const registry = createSessionRegistry({
|
|
220
|
+
presets: options.agentPresets,
|
|
221
|
+
connections: deviceConnections,
|
|
222
|
+
artifactUrl: () => {
|
|
223
|
+
const address = app.server.address();
|
|
224
|
+
// Before listen there is no address; only tests that skip listen get here.
|
|
225
|
+
if (!address)
|
|
226
|
+
return undefined;
|
|
227
|
+
if (typeof address === 'string') {
|
|
228
|
+
throw new Error(`Artifact tools need a TCP address, but the server listens on "${address}".`);
|
|
229
|
+
}
|
|
230
|
+
return `${addressUrl(WILDCARD_LOOPBACK[address.address] ?? address.address, address.port)}/`;
|
|
231
|
+
},
|
|
232
|
+
repositoryPath,
|
|
233
|
+
taskIds: sessionId => artifacts.definitions.assignment(sessionId).taskIds,
|
|
234
|
+
taskAssignment: sessionId => artifacts.definitions.assignment(sessionId)
|
|
235
|
+
});
|
|
236
|
+
agentRegistry = registry;
|
|
237
|
+
app.register(artifactAgentRoutes, { storage: artifacts, registry });
|
|
238
|
+
artifacts.tasks.attachSessions(registry);
|
|
239
|
+
artifacts.lifecycle.attachSessions(registry);
|
|
151
240
|
app.register(agentRoutes, {
|
|
241
|
+
artifacts,
|
|
152
242
|
notes,
|
|
153
|
-
registry
|
|
154
|
-
presets: options.agentPresets,
|
|
155
|
-
repositoryPath
|
|
156
|
-
}),
|
|
243
|
+
registry,
|
|
157
244
|
db,
|
|
158
245
|
repositoryPath,
|
|
159
246
|
eventBus,
|