@pi-harness/pi-harness 0.1.21 → 0.1.23
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 +1 -1
- package/apps/web/dist/assets/index-Bo9CNI_U.js +22 -0
- package/apps/web/dist/index.html +1 -1
- package/apps/web/package.json +6 -6
- package/apps/web/server-dist/bin.js +18 -5
- package/apps/web/server-dist/bin.js.map +1 -1
- package/apps/web/src/server/bin.ts +18 -5
- package/apps/web/test/bin.test.ts +90 -0
- package/node_modules/@pi-harness/api-gateway/dist/index.d.ts.map +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/index.js +204 -66
- package/node_modules/@pi-harness/api-gateway/dist/index.js.map +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/agent-teams.json +3 -12
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/anchored-standard.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/annotation.json +3 -8
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/archify.json +3 -12
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/at-file.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/auto-mode.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/better-sidebar.json +3 -13
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-fetch.json +2 -5
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-session.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/canvas-draw.json +3 -9
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/change-verifier.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cleaner.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cli-notifier.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/code2skill.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/colleague-skill.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context-doctor.json +2 -8
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context.json +2 -7
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cost-meter.json +3 -12
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/dependency-checker.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/fail-logger.json +2 -7
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/genui.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/graph-memory.json +3 -12
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/history-compressor.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/hol-guard.json +4 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/i18n-pair.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/image-compressor.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/llm-verifier.json +3 -13
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-client.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-panel.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/memory.json +3 -9
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mock-server.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/modlens.json +3 -9
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/module-search.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/openpets.json +2 -7
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plan-execute.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-check.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-dev.json +3 -12
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-finder.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-radar.json +3 -9
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-stars.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-guard.json +3 -9
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-library.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/readme-gen.json +2 -7
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/recall-unread.json +2 -7
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reverse-skill.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +3 -13
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/secure-audit.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bridge.json +2 -7
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-compare.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-export.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-insights.json +2 -7
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-search.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-catalog.json +3 -12
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-guard.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/sql-lens.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/synapse.json +3 -9
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/tab-manager.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/taskboard.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/test-harness.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/theme-studio.json +3 -11
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/token-guard.json +2 -7
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/turn-rewind.json +2 -7
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +3 -9
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +2 -6
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/web-research.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +3 -13
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-search.json +3 -10
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/yaml-validator.json +2 -6
- package/node_modules/@pi-harness/api-gateway/package.json +1 -1
- package/node_modules/@pi-harness/cli/dist/node-stdio.d.ts.map +1 -1
- package/node_modules/@pi-harness/cli/dist/node-stdio.js +3 -1
- package/node_modules/@pi-harness/cli/dist/node-stdio.js.map +1 -1
- package/node_modules/@pi-harness/cli/dist/relaunch.d.ts.map +1 -1
- package/node_modules/@pi-harness/cli/dist/relaunch.js +6 -1
- package/node_modules/@pi-harness/cli/dist/relaunch.js.map +1 -1
- package/node_modules/@pi-harness/cli/package.json +1 -1
- package/node_modules/@pi-harness/host-webserver/dist/index.d.ts.map +1 -1
- package/node_modules/@pi-harness/host-webserver/dist/index.js +52 -3
- package/node_modules/@pi-harness/host-webserver/dist/index.js.map +1 -1
- package/node_modules/@pi-harness/host-webserver/package.json +1 -1
- package/node_modules/@pi-harness/web-app/dist/index.d.ts +3 -0
- package/node_modules/@pi-harness/web-app/dist/index.d.ts.map +1 -1
- package/node_modules/@pi-harness/web-app/dist/index.js +9 -5
- package/node_modules/@pi-harness/web-app/dist/index.js.map +1 -1
- package/node_modules/@pi-harness/web-app/package.json +1 -1
- package/package.json +7 -7
- package/packages/api-gateway/dist/index.d.ts.map +1 -1
- package/packages/api-gateway/dist/index.js +204 -66
- package/packages/api-gateway/dist/index.js.map +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/agent-teams.json +3 -12
- package/packages/api-gateway/dist/marketplace-entries/official/anchored-standard.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/annotation.json +3 -8
- package/packages/api-gateway/dist/marketplace-entries/official/archify.json +3 -12
- package/packages/api-gateway/dist/marketplace-entries/official/at-file.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/auto-mode.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/better-sidebar.json +3 -13
- package/packages/api-gateway/dist/marketplace-entries/official/browser-fetch.json +2 -5
- package/packages/api-gateway/dist/marketplace-entries/official/browser-session.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/canvas-draw.json +3 -9
- package/packages/api-gateway/dist/marketplace-entries/official/change-verifier.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/cleaner.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/cli-notifier.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/code2skill.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/colleague-skill.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/context-doctor.json +2 -8
- package/packages/api-gateway/dist/marketplace-entries/official/context.json +2 -7
- package/packages/api-gateway/dist/marketplace-entries/official/cost-meter.json +3 -12
- package/packages/api-gateway/dist/marketplace-entries/official/dependency-checker.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/fail-logger.json +2 -7
- package/packages/api-gateway/dist/marketplace-entries/official/genui.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/graph-memory.json +3 -12
- package/packages/api-gateway/dist/marketplace-entries/official/history-compressor.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/hol-guard.json +4 -11
- package/packages/api-gateway/dist/marketplace-entries/official/i18n-pair.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/image-compressor.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/llm-verifier.json +3 -13
- package/packages/api-gateway/dist/marketplace-entries/official/mcp-client.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/mcp-panel.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/memory.json +3 -9
- package/packages/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/mock-server.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/modlens.json +3 -9
- package/packages/api-gateway/dist/marketplace-entries/official/module-search.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/openpets.json +2 -7
- package/packages/api-gateway/dist/marketplace-entries/official/plan-execute.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-check.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-dev.json +3 -12
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-finder.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-radar.json +3 -9
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-stars.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/prompt-guard.json +3 -9
- package/packages/api-gateway/dist/marketplace-entries/official/prompt-library.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/readme-gen.json +2 -7
- package/packages/api-gateway/dist/marketplace-entries/official/recall-unread.json +2 -7
- package/packages/api-gateway/dist/marketplace-entries/official/reverse-skill.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +3 -13
- package/packages/api-gateway/dist/marketplace-entries/official/secure-audit.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/session-bridge.json +2 -7
- package/packages/api-gateway/dist/marketplace-entries/official/session-compare.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/session-export.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/session-insights.json +2 -7
- package/packages/api-gateway/dist/marketplace-entries/official/session-search.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/skill-catalog.json +3 -12
- package/packages/api-gateway/dist/marketplace-entries/official/skill-guard.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/sql-lens.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/synapse.json +3 -9
- package/packages/api-gateway/dist/marketplace-entries/official/tab-manager.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/taskboard.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/test-harness.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/theme-studio.json +3 -11
- package/packages/api-gateway/dist/marketplace-entries/official/token-guard.json +2 -7
- package/packages/api-gateway/dist/marketplace-entries/official/turn-rewind.json +2 -7
- package/packages/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +3 -9
- package/packages/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +2 -6
- package/packages/api-gateway/dist/marketplace-entries/official/web-research.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +3 -13
- package/packages/api-gateway/dist/marketplace-entries/official/workspace-search.json +3 -10
- package/packages/api-gateway/dist/marketplace-entries/official/yaml-validator.json +2 -6
- package/packages/api-gateway/package.json +1 -1
- package/packages/api-gateway/src/index.ts +227 -68
- package/packages/api-gateway/src/marketplace-entries/official/agent-teams.json +3 -12
- package/packages/api-gateway/src/marketplace-entries/official/anchored-standard.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/annotation.json +3 -8
- package/packages/api-gateway/src/marketplace-entries/official/archify.json +3 -12
- package/packages/api-gateway/src/marketplace-entries/official/at-file.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/auto-mode.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/better-sidebar.json +3 -13
- package/packages/api-gateway/src/marketplace-entries/official/browser-fetch.json +2 -5
- package/packages/api-gateway/src/marketplace-entries/official/browser-session.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/canvas-draw.json +3 -9
- package/packages/api-gateway/src/marketplace-entries/official/change-verifier.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/cleaner.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/cli-notifier.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/code2skill.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/colleague-skill.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/context-doctor.json +2 -8
- package/packages/api-gateway/src/marketplace-entries/official/context.json +2 -7
- package/packages/api-gateway/src/marketplace-entries/official/cost-meter.json +3 -12
- package/packages/api-gateway/src/marketplace-entries/official/dependency-checker.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/docker-sandbox.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/fail-logger.json +2 -7
- package/packages/api-gateway/src/marketplace-entries/official/genui.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/git-time-capsule.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/graph-memory.json +3 -12
- package/packages/api-gateway/src/marketplace-entries/official/history-compressor.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/hol-guard.json +4 -11
- package/packages/api-gateway/src/marketplace-entries/official/i18n-pair.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/image-compressor.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/llm-verifier.json +3 -13
- package/packages/api-gateway/src/marketplace-entries/official/mcp-client.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/mcp-panel.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/memory.json +3 -9
- package/packages/api-gateway/src/marketplace-entries/official/mirage-bridge.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/mock-server.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/modlens.json +3 -9
- package/packages/api-gateway/src/marketplace-entries/official/module-search.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/obsidian-sync.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/openpets.json +2 -7
- package/packages/api-gateway/src/marketplace-entries/official/plan-execute.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/plugin-check.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/plugin-dev.json +3 -12
- package/packages/api-gateway/src/marketplace-entries/official/plugin-finder.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/plugin-radar.json +3 -9
- package/packages/api-gateway/src/marketplace-entries/official/plugin-stars.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/prompt-guard.json +3 -9
- package/packages/api-gateway/src/marketplace-entries/official/prompt-library.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/readme-gen.json +2 -7
- package/packages/api-gateway/src/marketplace-entries/official/recall-unread.json +2 -7
- package/packages/api-gateway/src/marketplace-entries/official/reverse-skill.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/reviewer-bot.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/runtime-doctor.json +3 -13
- package/packages/api-gateway/src/marketplace-entries/official/secure-audit.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/session-bookmarks.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/session-bridge.json +2 -7
- package/packages/api-gateway/src/marketplace-entries/official/session-compare.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/session-export.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/session-insights.json +2 -7
- package/packages/api-gateway/src/marketplace-entries/official/session-search.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/skill-catalog.json +3 -12
- package/packages/api-gateway/src/marketplace-entries/official/skill-guard.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/sql-lens.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/synapse.json +3 -9
- package/packages/api-gateway/src/marketplace-entries/official/tab-manager.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/taskboard.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/telemetry-blocker.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/test-harness.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/theme-studio.json +3 -11
- package/packages/api-gateway/src/marketplace-entries/official/token-guard.json +2 -7
- package/packages/api-gateway/src/marketplace-entries/official/turn-rewind.json +2 -7
- package/packages/api-gateway/src/marketplace-entries/official/undo-savepoint.json +3 -9
- package/packages/api-gateway/src/marketplace-entries/official/vision-toolkit.json +2 -6
- package/packages/api-gateway/src/marketplace-entries/official/web-research.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/workspace-navigator.json +3 -13
- package/packages/api-gateway/src/marketplace-entries/official/workspace-search.json +3 -10
- package/packages/api-gateway/src/marketplace-entries/official/yaml-validator.json +2 -6
- package/packages/api-gateway/test/index.test.ts +363 -1
- package/packages/api-gateway/test/marketplace-schema.test.ts +139 -0
- package/packages/api-gateway/test/release-contract.test.ts +77 -0
- package/packages/api-gateway/test/release-package.test.ts +1 -1
- package/packages/api-gateway/test/release-version.test.ts +6 -4
- package/packages/bundle-web-app/dist/index.d.ts +3 -0
- package/packages/bundle-web-app/dist/index.d.ts.map +1 -1
- package/packages/bundle-web-app/dist/index.js +9 -5
- package/packages/bundle-web-app/dist/index.js.map +1 -1
- package/packages/bundle-web-app/package.json +1 -1
- package/packages/bundle-web-app/src/index.ts +12 -5
- package/packages/bundle-web-app/test/index.test.ts +33 -2
- package/packages/cli/dist/node-stdio.d.ts.map +1 -1
- package/packages/cli/dist/node-stdio.js +3 -1
- package/packages/cli/dist/node-stdio.js.map +1 -1
- package/packages/cli/dist/relaunch.d.ts.map +1 -1
- package/packages/cli/dist/relaunch.js +6 -1
- package/packages/cli/dist/relaunch.js.map +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/cli/src/node-stdio.ts +6 -3
- package/packages/cli/src/relaunch.ts +5 -1
- package/packages/cli/test/node-stdio.test.ts +43 -0
- package/packages/cli/test/relaunch.test.ts +35 -0
- package/packages/host-webserver/dist/index.d.ts.map +1 -1
- package/packages/host-webserver/dist/index.js +52 -3
- package/packages/host-webserver/dist/index.js.map +1 -1
- package/packages/host-webserver/package.json +1 -1
- package/packages/host-webserver/src/index.ts +57 -3
- package/packages/host-webserver/test/index.test.ts +129 -1
- package/apps/web/dist/assets/index-e92yZuUr.js +0 -22
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
|
-
import { mkdir, mkdtemp, readFile, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
1
|
+
import { execFile, type ExecFileException } from "node:child_process";
|
|
2
|
+
import { mkdir, mkdtemp, readFile, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
3
3
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
4
|
-
import { basename, isAbsolute, join, relative, resolve } from "node:path";
|
|
4
|
+
import { basename, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import type { Context } from "@deepseek-ai/cordis";
|
|
7
7
|
import { SessionManager, type AgentSessionEvent, type ExtensionUIContext } from "@earendil-works/pi-coding-agent";
|
|
8
8
|
import type Loader from "@deepseek-ai/cordis-plugin-loader";
|
|
9
|
+
import { atomicWriteFile } from "@pi-harness/core";
|
|
9
10
|
import type { PiPluginUiRegistry, PiRuntimeService, PiModelsService, PiHarnessLaunch } from "@pi-harness/core";
|
|
10
11
|
import type { WebServer } from "@pi-harness/host-webserver";
|
|
11
12
|
import {
|
|
@@ -33,20 +34,35 @@ interface ApiServices {
|
|
|
33
34
|
|
|
34
35
|
const loadMarketplaceStatistics = createMarketplaceStatisticsLoader();
|
|
35
36
|
|
|
37
|
+
const DEFAULT_BODY_LIMIT_BYTES = 64 * 1024;
|
|
38
|
+
const IMPORT_CONTENT_LIMIT_BYTES = 10 * 1024 * 1024;
|
|
39
|
+
// The import body carries the JSONL content as a JSON string, so quotes and newlines are escaped; leave headroom above the content limit for that overhead.
|
|
40
|
+
const IMPORT_BODY_LIMIT_BYTES = 16 * 1024 * 1024;
|
|
41
|
+
// Retained trajectory events are replayed to every SSE client and returned by /api/session, so the array must stay bounded.
|
|
42
|
+
const MAX_RETAINED_EVENTS = 2000;
|
|
43
|
+
const GIT_TIMEOUT_MS = 15_000;
|
|
44
|
+
|
|
45
|
+
class PayloadTooLargeError extends Error {
|
|
46
|
+
constructor() {
|
|
47
|
+
super("Request body is too large");
|
|
48
|
+
this.name = "PayloadTooLargeError";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
36
52
|
function sendJson(response: ServerResponse, status: number, payload: unknown): void {
|
|
37
53
|
const body = JSON.stringify(payload);
|
|
38
54
|
response.writeHead(status, { "content-type": "application/json; charset=utf-8", "cache-control": "no-store", "content-length": Buffer.byteLength(body) });
|
|
39
55
|
response.end(body);
|
|
40
56
|
}
|
|
41
57
|
|
|
42
|
-
async function bodyText(request: IncomingMessage): Promise<string> {
|
|
58
|
+
async function bodyText(request: IncomingMessage, maxBytes = DEFAULT_BODY_LIMIT_BYTES): Promise<string> {
|
|
43
59
|
const chunks: string[] = [];
|
|
44
60
|
let length = 0;
|
|
45
61
|
for await (const chunk of request) {
|
|
46
62
|
const input: string | Uint8Array = chunk as string | Uint8Array;
|
|
47
63
|
const value = typeof input === "string" ? input : Buffer.from(input).toString("utf8");
|
|
48
64
|
length += Buffer.byteLength(value);
|
|
49
|
-
if (length >
|
|
65
|
+
if (length > maxBytes) throw new PayloadTooLargeError();
|
|
50
66
|
chunks.push(value);
|
|
51
67
|
}
|
|
52
68
|
return chunks.join("");
|
|
@@ -139,26 +155,67 @@ function sessionMetadataFile(manager: SessionManager): string {
|
|
|
139
155
|
return resolve(manager.getSessionDir(), ".pi-harness-session-meta.json");
|
|
140
156
|
}
|
|
141
157
|
|
|
142
|
-
|
|
158
|
+
interface MetadataLogger {
|
|
159
|
+
warn(message: string): void;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// A missing file is the normal first-run state. Any other read or parse failure means the file exists but is unusable; it is renamed aside so the wreckage survives for recovery and the next write cannot silently replace the only copy.
|
|
163
|
+
async function readSessionMetadata(manager: SessionManager, logger: MetadataLogger): Promise<SessionMetadataMap> {
|
|
164
|
+
const file = sessionMetadataFile(manager);
|
|
165
|
+
let raw: string;
|
|
166
|
+
try {
|
|
167
|
+
raw = await readFile(file, "utf8");
|
|
168
|
+
} catch (error) {
|
|
169
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") return {};
|
|
170
|
+
await quarantineSessionMetadata(file, logger, error);
|
|
171
|
+
return {};
|
|
172
|
+
}
|
|
143
173
|
try {
|
|
144
|
-
const parsed: unknown = JSON.parse(
|
|
145
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
|
|
174
|
+
const parsed: unknown = JSON.parse(raw);
|
|
175
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("session metadata must be a JSON object");
|
|
146
176
|
return parsed as SessionMetadataMap;
|
|
147
|
-
} catch {
|
|
177
|
+
} catch (error) {
|
|
178
|
+
await quarantineSessionMetadata(file, logger, error);
|
|
148
179
|
return {};
|
|
149
180
|
}
|
|
150
181
|
}
|
|
151
182
|
|
|
183
|
+
async function quarantineSessionMetadata(file: string, logger: MetadataLogger, error: unknown): Promise<void> {
|
|
184
|
+
const quarantined = `${file}.corrupt-${Date.now()}`;
|
|
185
|
+
try {
|
|
186
|
+
await rename(file, quarantined);
|
|
187
|
+
logger.warn(`Session metadata at ${file} is unreadable (${errorText(error)}); moved it to ${quarantined} and starting from an empty map`);
|
|
188
|
+
} catch (renameError) {
|
|
189
|
+
logger.warn(`Session metadata at ${file} is unreadable (${errorText(error)}) and could not be quarantined: ${errorText(renameError)}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
152
193
|
async function writeSessionMetadata(manager: SessionManager, metadata: SessionMetadataMap): Promise<void> {
|
|
153
194
|
await mkdir(manager.getSessionDir(), { recursive: true });
|
|
154
|
-
await
|
|
195
|
+
await atomicWriteFile(sessionMetadataFile(manager), JSON.stringify(metadata, null, 2) + "\n", { encoding: "utf8" });
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Every read-modify-write of the metadata file runs through this chain so concurrent requests cannot interleave and drop each other's updates.
|
|
199
|
+
let sessionMetadataQueue: Promise<unknown> = Promise.resolve();
|
|
200
|
+
|
|
201
|
+
function mutateSessionMetadata<T>(manager: SessionManager, logger: MetadataLogger, mutate: (metadata: SessionMetadataMap) => Promise<T> | T): Promise<T> {
|
|
202
|
+
const operation = sessionMetadataQueue
|
|
203
|
+
.catch(() => undefined)
|
|
204
|
+
.then(async () => {
|
|
205
|
+
const metadata = await readSessionMetadata(manager, logger);
|
|
206
|
+
const result = await mutate(metadata);
|
|
207
|
+
await writeSessionMetadata(manager, metadata);
|
|
208
|
+
return result;
|
|
209
|
+
});
|
|
210
|
+
sessionMetadataQueue = operation;
|
|
211
|
+
return operation;
|
|
155
212
|
}
|
|
156
213
|
|
|
157
214
|
function sessionPathInDirectory(path: string, manager: SessionManager): boolean {
|
|
158
215
|
const root = resolve(manager.getSessionDir());
|
|
159
216
|
const target = resolve(path);
|
|
160
217
|
const relativePath = relative(root, target);
|
|
161
|
-
return relativePath !== "" && !isAbsolute(relativePath) && relativePath !== ".." && !relativePath.startsWith(".." +
|
|
218
|
+
return relativePath !== "" && !isAbsolute(relativePath) && relativePath !== ".." && !relativePath.startsWith(".." + sep) && target.endsWith(".jsonl");
|
|
162
219
|
}
|
|
163
220
|
|
|
164
221
|
const webSessionUi = {
|
|
@@ -452,25 +509,69 @@ function writeSse(response: ServerResponse, payload: unknown): void {
|
|
|
452
509
|
response.write(`data: ${JSON.stringify(jsonSafe(payload))}\n\n`);
|
|
453
510
|
}
|
|
454
511
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
512
|
+
type GitTermination = "timeout" | "output-limit";
|
|
513
|
+
|
|
514
|
+
// Node reports a maxBuffer overflow through a string error code and a timeout through `killed`; neither is a git exit status, so they must not be folded into an ordinary non-zero exit.
|
|
515
|
+
function gitTermination(error: ExecFileException | null): GitTermination | undefined {
|
|
516
|
+
if (error === null) return undefined;
|
|
517
|
+
if (error.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") return "output-limit";
|
|
518
|
+
if (error.killed === true) return "timeout";
|
|
519
|
+
return undefined;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function gitTerminationMessage(command: string, termination: GitTermination): string {
|
|
523
|
+
return termination === "timeout"
|
|
524
|
+
? `git ${command} timed out after ${GIT_TIMEOUT_MS / 1000} seconds`
|
|
525
|
+
: `git ${command} produced more output than the buffer limit allows`;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
interface GitStatusResult {
|
|
529
|
+
readonly output: string;
|
|
530
|
+
readonly truncated: boolean;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
function gitStatus(cwd: string): Promise<GitStatusResult> {
|
|
534
|
+
return new Promise((resolveStatus, rejectStatus) => {
|
|
535
|
+
execFile("git", ["status", "--short", "--untracked-files=all"], { cwd, timeout: GIT_TIMEOUT_MS, maxBuffer: 512 * 1024 }, (error, stdout, stderr) => {
|
|
536
|
+
if (error === null) {
|
|
537
|
+
resolveStatus({ output: stdout, truncated: false });
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
const termination = gitTermination(error);
|
|
541
|
+
if (termination === "output-limit") {
|
|
542
|
+
// Keep the complete lines that arrived before the kill; the final line may have been cut mid-path.
|
|
543
|
+
resolveStatus({ output: stdout.slice(0, stdout.lastIndexOf("\n") + 1), truncated: true });
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (termination === undefined && error.code === 128 && /not a git repository/i.test(stderr)) {
|
|
547
|
+
resolveStatus({ output: "", truncated: false });
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
rejectStatus(new Error(termination ? gitTerminationMessage("status", termination) : stderr.trim() || error.message, { cause: error }));
|
|
551
|
+
});
|
|
458
552
|
});
|
|
459
553
|
}
|
|
460
554
|
|
|
461
555
|
function gitDiff(cwd: string, path: string): Promise<string> {
|
|
462
556
|
return new Promise((resolveOutput) => {
|
|
463
|
-
execFile("git", ["diff", "--no-ext-diff", "--", path], { cwd, maxBuffer: 1024 * 1024 }, (error, stdout) =>
|
|
557
|
+
execFile("git", ["diff", "--no-ext-diff", "--", path], { cwd, timeout: GIT_TIMEOUT_MS, maxBuffer: 1024 * 1024 }, (error, stdout) =>
|
|
464
558
|
resolveOutput(error && stdout.length === 0 ? "" : stdout),
|
|
465
559
|
);
|
|
466
560
|
});
|
|
467
561
|
}
|
|
468
562
|
|
|
469
|
-
|
|
563
|
+
interface GitCommandResult {
|
|
564
|
+
readonly stdout: string;
|
|
565
|
+
readonly stderr: string;
|
|
566
|
+
readonly code: number;
|
|
567
|
+
readonly terminated: GitTermination | undefined;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
function gitCommand(cwd: string, args: readonly string[]): Promise<GitCommandResult> {
|
|
470
571
|
return new Promise((resolveResult) => {
|
|
471
|
-
execFile("git", [...args], { cwd, maxBuffer: 2 * 1024 * 1024 }, (error, stdout, stderr) => {
|
|
572
|
+
execFile("git", [...args], { cwd, timeout: GIT_TIMEOUT_MS, maxBuffer: 2 * 1024 * 1024 }, (error, stdout, stderr) => {
|
|
472
573
|
const code = error && typeof error.code === "number" ? error.code : error ? 1 : 0;
|
|
473
|
-
resolveResult({ stdout, stderr, code });
|
|
574
|
+
resolveResult({ stdout, stderr, code, terminated: gitTermination(error) });
|
|
474
575
|
});
|
|
475
576
|
});
|
|
476
577
|
}
|
|
@@ -559,7 +660,11 @@ export default {
|
|
|
559
660
|
const events: AgentSessionEvent[] = [];
|
|
560
661
|
const eventClients = new Set<ServerResponse>();
|
|
561
662
|
const handleEvent = (event: AgentSessionEvent) => {
|
|
562
|
-
events.
|
|
663
|
+
// Streaming deltas reach clients live over SSE and each one carries the whole partial message, so only durable events are retained for snapshots.
|
|
664
|
+
if (event.type !== "message_update") {
|
|
665
|
+
events.push(event);
|
|
666
|
+
if (events.length > MAX_RETAINED_EVENTS) events.splice(0, events.length - MAX_RETAINED_EVENTS);
|
|
667
|
+
}
|
|
563
668
|
for (const response of eventClients) {
|
|
564
669
|
if (response.writableEnded || response.destroyed) {
|
|
565
670
|
eventClients.delete(response);
|
|
@@ -686,7 +791,12 @@ export default {
|
|
|
686
791
|
return;
|
|
687
792
|
}
|
|
688
793
|
const path = join(services.launch.agentDir, "settings.json");
|
|
689
|
-
|
|
794
|
+
// Replace the file atomically so an interrupted write never leaves a truncated settings.json behind; keep the existing permission bits.
|
|
795
|
+
const mode = await stat(path).then(
|
|
796
|
+
(info) => info.mode & 0o777,
|
|
797
|
+
() => 0o644,
|
|
798
|
+
);
|
|
799
|
+
await atomicWriteFile(path, JSON.stringify(parsed, null, 2) + "\n", { encoding: "utf8", mode });
|
|
690
800
|
await services.runtime.session.settingsManager.reload();
|
|
691
801
|
sendJson(response, 200, piConfig(services));
|
|
692
802
|
} catch (error) {
|
|
@@ -1192,8 +1302,14 @@ export default {
|
|
|
1192
1302
|
const disposeFiles = services.webServer.register({
|
|
1193
1303
|
path: "/api/files",
|
|
1194
1304
|
async handler(_request, response) {
|
|
1195
|
-
|
|
1196
|
-
|
|
1305
|
+
let status: GitStatusResult;
|
|
1306
|
+
try {
|
|
1307
|
+
status = await gitStatus(activeCwd(services));
|
|
1308
|
+
} catch (error) {
|
|
1309
|
+
sendJson(response, 500, { error: errorText(error) });
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
const items = status.output
|
|
1197
1313
|
.split("\n")
|
|
1198
1314
|
.map((line) => line.trimEnd())
|
|
1199
1315
|
.filter((line) => line.length > 0)
|
|
@@ -1205,7 +1321,7 @@ export default {
|
|
|
1205
1321
|
label: status === "??" ? "untracked" : status.includes("D") ? "deleted" : status.includes("A") ? "added" : "modified",
|
|
1206
1322
|
};
|
|
1207
1323
|
});
|
|
1208
|
-
sendJson(response, 200, { items });
|
|
1324
|
+
sendJson(response, 200, { items, ...(status.truncated ? { truncated: true } : {}) });
|
|
1209
1325
|
},
|
|
1210
1326
|
});
|
|
1211
1327
|
const disposeFileDiff = services.webServer.register({
|
|
@@ -1224,7 +1340,7 @@ export default {
|
|
|
1224
1340
|
const root = resolve(activeCwd(services));
|
|
1225
1341
|
const absolute = resolve(root, requested);
|
|
1226
1342
|
const relativePath = relative(root, absolute);
|
|
1227
|
-
if (isAbsolute(relativePath) || relativePath === ".." || relativePath.startsWith(".." +
|
|
1343
|
+
if (isAbsolute(relativePath) || relativePath === ".." || relativePath.startsWith(".." + sep)) {
|
|
1228
1344
|
sendJson(response, 400, { error: "path must stay inside the workspace" });
|
|
1229
1345
|
return;
|
|
1230
1346
|
}
|
|
@@ -1251,11 +1367,19 @@ export default {
|
|
|
1251
1367
|
}
|
|
1252
1368
|
const root = resolve(activeCwd(services));
|
|
1253
1369
|
const add = await gitCommand(root, ["add", "-A", "--", ...paths]);
|
|
1370
|
+
if (add.terminated) {
|
|
1371
|
+
sendJson(response, 500, { error: gitTerminationMessage("add", add.terminated) });
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1254
1374
|
if (add.code !== 0) {
|
|
1255
1375
|
sendJson(response, 409, { error: add.stderr.trim() || "Unable to stage workspace files" });
|
|
1256
1376
|
return;
|
|
1257
1377
|
}
|
|
1258
1378
|
const commit = await gitCommand(root, ["commit", "-m", payload.message.trim(), "--", ...paths]);
|
|
1379
|
+
if (commit.terminated) {
|
|
1380
|
+
sendJson(response, 500, { error: gitTerminationMessage("commit", commit.terminated) });
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1259
1383
|
if (commit.code !== 0) {
|
|
1260
1384
|
sendJson(response, 409, { error: commit.stdout.trim() || commit.stderr.trim() || "Nothing to commit" });
|
|
1261
1385
|
return;
|
|
@@ -1286,16 +1410,36 @@ export default {
|
|
|
1286
1410
|
sendJson(response, 400, { error: paths.message });
|
|
1287
1411
|
return;
|
|
1288
1412
|
}
|
|
1289
|
-
const untracked = await gitCommand(root, ["ls-files", "--others", "--exclude-standard", "--", ...paths]);
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1413
|
+
const untracked = await gitCommand(root, ["ls-files", "-z", "--others", "--exclude-standard", "--", ...paths]);
|
|
1414
|
+
// `git restore` refuses the whole request when any pathspec is unknown to it, so restore only the paths git tracks. `--with-tree=HEAD` keeps staged deletions in the list; it fails on an unborn HEAD, where the plain index listing is all there is.
|
|
1415
|
+
let tracked = await gitCommand(root, ["ls-files", "-z", "--with-tree=HEAD", "--", ...paths]);
|
|
1416
|
+
if (tracked.code !== 0 && tracked.terminated === undefined) tracked = await gitCommand(root, ["ls-files", "-z", "--", ...paths]);
|
|
1417
|
+
const listing = [untracked, tracked].find((result) => result.terminated !== undefined || result.code !== 0);
|
|
1418
|
+
if (listing) {
|
|
1419
|
+
if (listing.terminated) sendJson(response, 500, { error: gitTerminationMessage("ls-files", listing.terminated) });
|
|
1420
|
+
else sendJson(response, 409, { error: listing.stderr.trim() || "Unable to inspect workspace files" });
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
const untrackedPaths = untracked.stdout.split("\0").filter(Boolean);
|
|
1424
|
+
const trackedPaths = tracked.stdout.split("\0").filter(Boolean);
|
|
1425
|
+
const known = [...untrackedPaths, ...trackedPaths];
|
|
1426
|
+
const unknown = paths.filter((path) => !known.some((candidate) => candidate === path || candidate.startsWith(path + "/")));
|
|
1427
|
+
if (unknown.length > 0) {
|
|
1428
|
+
sendJson(response, 409, { error: `Paths did not match any file known to git: ${unknown.join(", ")}` });
|
|
1293
1429
|
return;
|
|
1294
1430
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
.
|
|
1298
|
-
|
|
1431
|
+
if (trackedPaths.length > 0) {
|
|
1432
|
+
const restore = await gitCommand(root, ["restore", "--worktree", "--staged", "--", ...trackedPaths]);
|
|
1433
|
+
if (restore.terminated) {
|
|
1434
|
+
sendJson(response, 500, { error: gitTerminationMessage("restore", restore.terminated) });
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
if (restore.code !== 0) {
|
|
1438
|
+
sendJson(response, 409, { error: restore.stderr.trim() || "Unable to restore workspace files" });
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
for (const path of untrackedPaths) {
|
|
1299
1443
|
await rm(resolve(root, path), { recursive: true, force: true });
|
|
1300
1444
|
}
|
|
1301
1445
|
sendJson(response, 200, { reverted: true, paths });
|
|
@@ -1332,6 +1476,10 @@ export default {
|
|
|
1332
1476
|
const disposePrompt = services.webServer.register({
|
|
1333
1477
|
path: "/api/prompt",
|
|
1334
1478
|
async handler(request, response) {
|
|
1479
|
+
if (request.method !== "POST") {
|
|
1480
|
+
sendJson(response, 405, { error: "Method not allowed" });
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1335
1483
|
if (busy) {
|
|
1336
1484
|
sendJson(response, 409, { error: "Another prompt is already running" });
|
|
1337
1485
|
return;
|
|
@@ -1583,9 +1731,9 @@ export default {
|
|
|
1583
1731
|
events.length = 0;
|
|
1584
1732
|
}
|
|
1585
1733
|
await unlink(path);
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1734
|
+
await mutateSessionMetadata(manager, context.logger, (metadata) => {
|
|
1735
|
+
delete metadata[path];
|
|
1736
|
+
});
|
|
1589
1737
|
sendJson(response, 200, { deleted: true, path, sessionFile: services.runtime.session.sessionFile });
|
|
1590
1738
|
} catch (error) {
|
|
1591
1739
|
sendJson(response, 400, { error: errorText(error) });
|
|
@@ -1607,16 +1755,17 @@ export default {
|
|
|
1607
1755
|
sendJson(response, 400, { error: "Invalid session path" });
|
|
1608
1756
|
return;
|
|
1609
1757
|
}
|
|
1610
|
-
const
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1758
|
+
const nextMetadata = await mutateSessionMetadata(manager, context.logger, (metadata) => {
|
|
1759
|
+
const currentMetadata = metadata[path] ?? {};
|
|
1760
|
+
const updated: SessionMetadata = {
|
|
1761
|
+
...currentMetadata,
|
|
1762
|
+
...(payload.archived === undefined ? {} : { archived: payload.archived === true }),
|
|
1763
|
+
...(payload.pinned === undefined ? {} : { pinned: payload.pinned === true }),
|
|
1764
|
+
};
|
|
1765
|
+
metadata[path] = updated;
|
|
1766
|
+
return updated;
|
|
1767
|
+
});
|
|
1768
|
+
sendJson(response, 200, { path, metadata: nextMetadata });
|
|
1620
1769
|
} catch (error) {
|
|
1621
1770
|
sendJson(response, 400, { error: errorText(error) });
|
|
1622
1771
|
}
|
|
@@ -1654,21 +1803,21 @@ export default {
|
|
|
1654
1803
|
sendJson(response, 409, { error: "Cannot batch-delete the active session" });
|
|
1655
1804
|
return;
|
|
1656
1805
|
}
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1806
|
+
await mutateSessionMetadata(manager, context.logger, async (metadata) => {
|
|
1807
|
+
for (const path of paths) {
|
|
1808
|
+
if (action === "delete") {
|
|
1809
|
+
await unlink(path);
|
|
1810
|
+
delete metadata[path];
|
|
1811
|
+
} else {
|
|
1812
|
+
const current = metadata[path] ?? {};
|
|
1813
|
+
metadata[path] = {
|
|
1814
|
+
...current,
|
|
1815
|
+
...(action === "archive" || action === "unarchive" ? { archived: action === "archive" } : {}),
|
|
1816
|
+
...(action === "pin" || action === "unpin" ? { pinned: action === "pin" } : {}),
|
|
1817
|
+
};
|
|
1818
|
+
}
|
|
1669
1819
|
}
|
|
1670
|
-
}
|
|
1671
|
-
await writeSessionMetadata(manager, metadata);
|
|
1820
|
+
});
|
|
1672
1821
|
sendJson(response, 200, { action, count: paths.length });
|
|
1673
1822
|
} catch (error) {
|
|
1674
1823
|
sendJson(response, 400, { error: errorText(error) });
|
|
@@ -1716,11 +1865,21 @@ export default {
|
|
|
1716
1865
|
return;
|
|
1717
1866
|
}
|
|
1718
1867
|
try {
|
|
1719
|
-
const payload = JSON.parse(await bodyText(request)) as {
|
|
1868
|
+
const payload = JSON.parse(await bodyText(request, IMPORT_BODY_LIMIT_BYTES)) as {
|
|
1869
|
+
path?: unknown;
|
|
1870
|
+
content?: unknown;
|
|
1871
|
+
filename?: unknown;
|
|
1872
|
+
cwd?: unknown;
|
|
1873
|
+
};
|
|
1720
1874
|
const suppliedPath = typeof payload.path === "string" ? payload.path : "";
|
|
1721
1875
|
const content = typeof payload.content === "string" ? payload.content : undefined;
|
|
1722
|
-
|
|
1723
|
-
|
|
1876
|
+
// `path` reads an existing file and `content` is written to a private temporary file; accepting both would let the request choose where the content lands.
|
|
1877
|
+
if (suppliedPath && content !== undefined) {
|
|
1878
|
+
sendJson(response, 400, { error: "Provide either a JSONL file path or file content, not both" });
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
if (content === undefined && (!suppliedPath || !isAbsolute(suppliedPath) || !suppliedPath.endsWith(".jsonl"))) {
|
|
1882
|
+
sendJson(response, 400, { error: "An absolute .jsonl file path or file content is required" });
|
|
1724
1883
|
return;
|
|
1725
1884
|
}
|
|
1726
1885
|
const manager = services.runtime.session.sessionManager;
|
|
@@ -1730,12 +1889,12 @@ export default {
|
|
|
1730
1889
|
}
|
|
1731
1890
|
const targetCwd = typeof payload.cwd === "string" && payload.cwd.trim() ? resolve(payload.cwd) : activeCwd(services);
|
|
1732
1891
|
const temporaryDirectory = content === undefined ? undefined : await mkdtemp(join(tmpdir(), "pi-harness-import-"));
|
|
1733
|
-
const
|
|
1734
|
-
|
|
1735
|
-
|
|
1892
|
+
const requestedName = basename(typeof payload.filename === "string" && payload.filename.trim() ? payload.filename : "import.jsonl");
|
|
1893
|
+
const importName = requestedName === "" || requestedName === "." || requestedName === ".." ? "import.jsonl" : requestedName;
|
|
1894
|
+
const importPath = temporaryDirectory === undefined ? suppliedPath : join(temporaryDirectory, importName);
|
|
1736
1895
|
try {
|
|
1737
1896
|
if (content !== undefined) {
|
|
1738
|
-
if (Buffer.byteLength(content, "utf8") >
|
|
1897
|
+
if (Buffer.byteLength(content, "utf8") > IMPORT_CONTENT_LIMIT_BYTES) {
|
|
1739
1898
|
sendJson(response, 413, { error: "Imported session must be at most 10 MiB" });
|
|
1740
1899
|
return;
|
|
1741
1900
|
}
|
|
@@ -1759,7 +1918,7 @@ export default {
|
|
|
1759
1918
|
if (temporaryDirectory) await rm(temporaryDirectory, { recursive: true, force: true });
|
|
1760
1919
|
}
|
|
1761
1920
|
} catch (error) {
|
|
1762
|
-
sendJson(response, 400, { error: errorText(error) });
|
|
1921
|
+
sendJson(response, error instanceof PayloadTooLargeError ? 413 : 400, { error: errorText(error) });
|
|
1763
1922
|
}
|
|
1764
1923
|
},
|
|
1765
1924
|
});
|
|
@@ -1796,7 +1955,7 @@ export default {
|
|
|
1796
1955
|
const page = Math.max(0, Number.parseInt(url.searchParams.get("page") ?? "0", 10) || 0);
|
|
1797
1956
|
const pageSize = Math.min(100, Math.max(1, Number.parseInt(url.searchParams.get("pageSize") ?? "50", 10) || 50));
|
|
1798
1957
|
const includeArchived = url.searchParams.get("includeArchived") === "true";
|
|
1799
|
-
const metadata = await readSessionMetadata(manager);
|
|
1958
|
+
const metadata = await readSessionMetadata(manager, context.logger);
|
|
1800
1959
|
const items =
|
|
1801
1960
|
typeof manager.isPersisted === "function" && manager.isPersisted() ? await SessionManager.list(services.launch.cwd, manager.getSessionDir()) : [];
|
|
1802
1961
|
const filtered = items.filter((item) => includeArchived || metadata[item.path]?.archived !== true);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "agent-teams",
|
|
3
3
|
"packageName": "@pi-harness/core/plugins/agent-teams",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.23",
|
|
5
5
|
"name": "Agent Team Board",
|
|
6
6
|
"description": "Maintain a bounded, session-local collaboration ledger of named roles, dependency-aware tasks, and mailbox notes without spawning agents or sending external messages.",
|
|
7
7
|
"author": "Pi Harness",
|
|
@@ -13,17 +13,8 @@
|
|
|
13
13
|
"id": "collaboration",
|
|
14
14
|
"label": "会话协作"
|
|
15
15
|
},
|
|
16
|
-
"capabilities": [
|
|
17
|
-
|
|
18
|
-
"tasks",
|
|
19
|
-
"mailbox notes",
|
|
20
|
-
"dependency graph",
|
|
21
|
-
"cycle detection"
|
|
22
|
-
],
|
|
23
|
-
"hooks": [
|
|
24
|
-
"session lifecycle",
|
|
25
|
-
"plugin UI"
|
|
26
|
-
],
|
|
16
|
+
"capabilities": ["collaboration ledger", "tasks", "mailbox notes", "dependency graph", "cycle detection"],
|
|
17
|
+
"hooks": ["session lifecycle", "plugin UI"],
|
|
27
18
|
"profile": {
|
|
28
19
|
"name": "@pi-harness/core/plugins/agent-teams",
|
|
29
20
|
"config": {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "anchored-standard",
|
|
3
3
|
"packageName": "@pi-harness/core/plugins/anchored-standard",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.23",
|
|
5
5
|
"name": "Anchored Standard",
|
|
6
6
|
"description": "Audit agent trajectories against an explicit tool-call allowlist and flag activity outside the anchored run.",
|
|
7
7
|
"author": "Pi Harness",
|
|
@@ -13,15 +13,8 @@
|
|
|
13
13
|
"id": "security",
|
|
14
14
|
"label": "安全"
|
|
15
15
|
},
|
|
16
|
-
"capabilities": [
|
|
17
|
-
|
|
18
|
-
"tool allowlist",
|
|
19
|
-
"run anchoring"
|
|
20
|
-
],
|
|
21
|
-
"hooks": [
|
|
22
|
-
"session events",
|
|
23
|
-
"plugin UI"
|
|
24
|
-
],
|
|
16
|
+
"capabilities": ["trajectory audit", "tool allowlist", "run anchoring"],
|
|
17
|
+
"hooks": ["session events", "plugin UI"],
|
|
25
18
|
"profile": {
|
|
26
19
|
"name": "@pi-harness/core/plugins/anchored-standard",
|
|
27
20
|
"config": {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "annotation",
|
|
3
3
|
"packageName": "@pi-harness/core/plugins/annotation",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.23",
|
|
5
5
|
"name": "Annotations",
|
|
6
6
|
"description": "Capture bounded selections and notes from the conversation for later agent context.",
|
|
7
7
|
"author": "Pi Harness",
|
|
@@ -13,13 +13,8 @@
|
|
|
13
13
|
"id": "context",
|
|
14
14
|
"label": "上下文管理"
|
|
15
15
|
},
|
|
16
|
-
"capabilities": [
|
|
17
|
-
|
|
18
|
-
"context"
|
|
19
|
-
],
|
|
20
|
-
"hooks": [
|
|
21
|
-
"plugin UI"
|
|
22
|
-
],
|
|
16
|
+
"capabilities": ["annotations", "context"],
|
|
17
|
+
"hooks": ["plugin UI"],
|
|
23
18
|
"profile": {
|
|
24
19
|
"name": "@pi-harness/core/plugins/annotation",
|
|
25
20
|
"config": {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "archify",
|
|
3
3
|
"packageName": "@pi-harness/core/plugins/archify",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.23",
|
|
5
5
|
"name": "Architecture Map",
|
|
6
6
|
"description": "Build a bounded, read-only architecture map from workspace components and package dependencies.",
|
|
7
7
|
"author": "Pi Harness",
|
|
@@ -13,17 +13,8 @@
|
|
|
13
13
|
"id": "developer",
|
|
14
14
|
"label": "开发工具"
|
|
15
15
|
},
|
|
16
|
-
"capabilities": [
|
|
17
|
-
|
|
18
|
-
"workspace scan",
|
|
19
|
-
"dependency map",
|
|
20
|
-
"Mermaid"
|
|
21
|
-
],
|
|
22
|
-
"hooks": [
|
|
23
|
-
"workspace files",
|
|
24
|
-
"package manifest",
|
|
25
|
-
"plugin UI"
|
|
26
|
-
],
|
|
16
|
+
"capabilities": ["architecture map", "workspace scan", "dependency map", "Mermaid"],
|
|
17
|
+
"hooks": ["workspace files", "package manifest", "plugin UI"],
|
|
27
18
|
"profile": {
|
|
28
19
|
"name": "@pi-harness/core/plugins/archify",
|
|
29
20
|
"config": {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "at-file",
|
|
3
3
|
"packageName": "@pi-harness/core/plugins/at-file",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.23",
|
|
5
5
|
"name": "@file Context",
|
|
6
6
|
"description": "Attach a bounded 256 KiB strict UTF-8 workspace file using canonical workspace path confinement and no-follow regular-file reads, framing it as offline, read-only, untrusted model context with closing-tag neutralization and cancellable sequential execution.",
|
|
7
7
|
"author": "Pi Harness",
|
|
@@ -22,11 +22,7 @@
|
|
|
22
22
|
"cancellable sequential execution",
|
|
23
23
|
"descriptor-safe normalized panel"
|
|
24
24
|
],
|
|
25
|
-
"hooks": [
|
|
26
|
-
"file context tool",
|
|
27
|
-
"workspace file read",
|
|
28
|
-
"plugin UI"
|
|
29
|
-
],
|
|
25
|
+
"hooks": ["file context tool", "workspace file read", "plugin UI"],
|
|
30
26
|
"profile": {
|
|
31
27
|
"name": "@pi-harness/core/plugins/at-file",
|
|
32
28
|
"config": {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "auto-mode",
|
|
3
3
|
"packageName": "@pi-harness/core/plugins/auto-mode",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.23",
|
|
5
5
|
"name": "Auto Mode",
|
|
6
6
|
"description": "Execute argv commands under a safe policy that blocks shell wrappers and requires confirmation for risky operations.",
|
|
7
7
|
"author": "Pi Harness",
|
|
@@ -13,15 +13,8 @@
|
|
|
13
13
|
"id": "security",
|
|
14
14
|
"label": "安全"
|
|
15
15
|
},
|
|
16
|
-
"capabilities": [
|
|
17
|
-
|
|
18
|
-
"confirmation gate",
|
|
19
|
-
"safe execution"
|
|
20
|
-
],
|
|
21
|
-
"hooks": [
|
|
22
|
-
"argv execution",
|
|
23
|
-
"plugin UI"
|
|
24
|
-
],
|
|
16
|
+
"capabilities": ["command policy", "confirmation gate", "safe execution"],
|
|
17
|
+
"hooks": ["argv execution", "plugin UI"],
|
|
25
18
|
"profile": {
|
|
26
19
|
"name": "@pi-harness/core/plugins/auto-mode",
|
|
27
20
|
"config": {
|