@geminilight/mindos 0.6.69 → 0.6.70
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/_standalone/.mindos-build-version +1 -1
- package/_standalone/.next/BUILD_ID +1 -1
- package/_standalone/.next/app-path-routes-manifest.json +22 -21
- package/_standalone/.next/build-manifest.json +3 -3
- package/_standalone/.next/cache/.previewinfo +1 -1
- package/_standalone/.next/cache/.rscinfo +1 -1
- package/_standalone/.next/cache/config.json +3 -3
- package/_standalone/.next/prerender-manifest.json +3 -3
- package/_standalone/.next/react-loadable-manifest.json +7 -7
- package/_standalone/.next/routes-manifest.json +6 -0
- package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +1 -1
- package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/page.js +1 -1
- package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/copy-skill/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js +13 -13
- package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/channels/verify/route.js +1 -0
- package/_standalone/.next/server/app/api/channels/verify/route.js.nft.json +1 -0
- package/_standalone/.next/server/app/api/channels/verify/route_client-reference-manifest.js +1 -0
- package/_standalone/.next/server/app/api/connect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/extract-pdf/route.js +2 -2
- package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/raw/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/test/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/clip/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/inbox/clip/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/lint/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/lint/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/direct-tools/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/tools/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/space-overview/route.js +2 -2
- package/_standalone/.next/server/app/api/space-overview/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/space-overview/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changelog/page.js +1 -1
- package/_standalone/.next/server/app/changelog/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changes/page.js +1 -1
- package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/page.js +1 -1
- package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/explore/page.js +1 -1
- package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/help/page.js +1 -1
- package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/login/page.js +1 -1
- package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/page.js +1 -1
- package/_standalone/.next/server/app/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/setup/page.js +1 -1
- package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/trash/page.js +3 -3
- package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
- package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/wiki/page.js +1 -1
- package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +22 -21
- package/_standalone/.next/server/chunks/3437.js +2 -2
- package/_standalone/.next/server/chunks/5299.js +1 -0
- package/_standalone/.next/server/chunks/6022.js +42 -42
- package/_standalone/.next/server/chunks/6133.js +54 -0
- package/_standalone/.next/server/chunks/6539.js +1 -1
- package/_standalone/.next/server/chunks/8326.js +1 -0
- package/_standalone/.next/server/chunks/8388.js +5 -3
- package/_standalone/.next/server/chunks/953.js +6 -4
- package/_standalone/.next/server/chunks/9938.js +24 -0
- package/_standalone/.next/server/middleware-build-manifest.js +1 -1
- package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/_standalone/.next/server/pages/500.html +2 -2
- package/_standalone/.next/server/server-reference-manifest.js +1 -1
- package/_standalone/.next/server/server-reference-manifest.json +1 -1
- package/_standalone/.next/static/chunks/1814.8a1fef15856dce84.js +1 -0
- package/_standalone/.next/static/chunks/2654-e07c692d6c99f25b.js +1 -0
- package/_standalone/.next/static/chunks/{2935.7d75923daaf448d3.js → 2935.9b08eeade3644806.js} +1 -1
- package/_standalone/.next/static/chunks/3269.a7343771e3f0ff58.js +48 -0
- package/_standalone/.next/static/chunks/3637.2b2697198968d83f.js +1 -0
- package/_standalone/.next/static/chunks/{5550-b7c97fc13628db15.js → 4327-d70a8d457e2d03fe.js} +1 -1
- package/_standalone/.next/static/chunks/48-c88ea6a2a45f15b4.js +28 -0
- package/_standalone/.next/static/chunks/5581-6d403608b5dfb20b.js +29 -0
- package/_standalone/.next/static/chunks/6902-edc5c487c696bd0b.js +3 -0
- package/_standalone/.next/static/chunks/808.72eb7bdd399e9a24.js +1 -0
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/{route-e0c1e2c67572781c.js → route-930dfa67e2789df5.js} +1 -1
- package/_standalone/.next/static/chunks/app/_global-error/{page-e0c1e2c67572781c.js → page-930dfa67e2789df5.js} +1 -1
- package/_standalone/.next/static/chunks/app/agents/page-3dc2bf2f6bc7334c.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/agents/{route-e0c1e2c67572781c.js → route-930dfa67e2789df5.js} +1 -1
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/{route-e0c1e2c67572781c.js → route-930dfa67e2789df5.js} +1 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/config/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/install/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/session/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/copy-skill/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/custom/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/auth/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/backlinks/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/changes/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/channels/verify/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/connect/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/export/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/import/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/raw/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/files/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/git/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/graph/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/health/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/im/config/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/im/status/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/im/test/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/clip/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/init/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/lint/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/direct-tools/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/tools/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/monitoring/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/recent-files/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/restart/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/search/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/skills/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/space-overview/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/sync/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/tree-version/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/uninstall/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-check/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-status/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/workflows/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/changes/page-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-75a6330292613587.js +157 -0
- package/_standalone/.next/static/chunks/app/echo/page-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/layout-8aa53b34ef34a246.js +133 -0
- package/_standalone/.next/static/chunks/app/loading-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/{page-c3be6477dbcf182d.js → page-318332501426ef5b.js} +1 -1
- package/_standalone/.next/static/chunks/app/trash/page-17bd5aedcfea9b65.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-d5c37c41c556013d.js +12 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/webpack-1c2d44f6d86f3986.js +1 -0
- package/_standalone/.next/static/css/a8cadde78aea8585.css +1 -0
- package/_standalone/.next/static/ixCTELNH6V05Z00pC6ZMO/_buildManifest.js +1 -0
- package/_standalone/.next/trace +72 -71
- package/_standalone/.next/types/routes.d.ts +2 -1
- package/_standalone/.next/types/validator.ts +9 -0
- package/_standalone/MINDOS_ARCHITECTURE_DIAGRAM.md +488 -0
- package/_standalone/MINDOS_EXPLORATION_SUMMARY.md +229 -0
- package/_standalone/MINDOS_INFRASTRUCTURE_ANALYSIS.md +732 -0
- package/_standalone/__tests__/acp/agent-descriptors.test.ts +36 -0
- package/_standalone/__tests__/acp/session.test.ts +346 -167
- package/_standalone/__tests__/agent/provider-endpoints.test.ts +70 -0
- package/_standalone/__tests__/api/channels-verify.test.ts +75 -0
- package/_standalone/__tests__/api/extract-pdf.test.ts +265 -0
- package/_standalone/__tests__/api/test-key.test.ts +15 -3
- package/_standalone/__tests__/channel-mgmt.test.js +11 -0
- package/_standalone/__tests__/components/breadcrumb-header-ux.test.ts +14 -0
- package/_standalone/__tests__/components/header-toc-vertical-alignment.test.ts +23 -0
- package/_standalone/__tests__/components/table-of-contents-header-layout.test.ts +15 -0
- package/_standalone/__tests__/components/view-page-header-layout.test.ts +13 -0
- package/_standalone/__tests__/components/view-page-header-scroll-stability.test.ts +34 -0
- package/_standalone/__tests__/core/hybrid-search.test.ts +109 -0
- package/_standalone/components/Breadcrumb.tsx +11 -11
- package/_standalone/components/FindInPage.tsx +1 -1
- package/_standalone/components/MarkdownView.tsx +4 -0
- package/_standalone/components/Panel.tsx +17 -10
- package/_standalone/components/TableOfContents.tsx +9 -9
- package/_standalone/components/agents/AgentsContentChannelDetail.tsx +168 -54
- package/_standalone/components/agents/AgentsContentChannels.tsx +22 -22
- package/_standalone/components/ask/AskContent.tsx +68 -28
- package/_standalone/components/ask/AskHeader.tsx +6 -2
- package/_standalone/components/ask/ProviderModelCapsule.tsx +11 -9
- package/_standalone/components/ask/SessionHistoryPanel.tsx +398 -0
- package/_standalone/components/settings/AiTab.tsx +5 -1
- package/_standalone/components/settings/KnowledgeTab.tsx +92 -1
- package/_standalone/components/settings/McpConnectGuides.tsx +4 -0
- package/_standalone/components/settings/McpPortSection.tsx +207 -0
- package/_standalone/components/settings/McpTab.tsx +1 -5
- package/_standalone/components/settings/TestButton.tsx +1 -0
- package/_standalone/components/settings/{ServerPortsCard.tsx → WebPortSection.tsx} +66 -151
- package/_standalone/components/settings/types.ts +12 -0
- package/_standalone/components/settings/useCustomProviderForm.ts +2 -2
- package/_standalone/data/skills/mindos/SKILL.md +45 -1
- package/_standalone/hooks/useAcpDetection.ts +1 -1
- package/_standalone/hooks/useAcpRegistry.ts +1 -1
- package/_standalone/hooks/useFileImport.ts +7 -2
- package/_standalone/hooks/useFileUpload.ts +17 -10
- package/_standalone/lib/acp/index.ts +3 -7
- package/_standalone/lib/acp/types.ts +0 -29
- package/_standalone/lib/im/platforms.ts +6 -2
- package/_standalone/lib/pdf-extract.ts +6 -2
- package/_standalone/package-lock.json +12 -2
- package/_standalone/package.json +2 -1
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/MINDOS_ARCHITECTURE_DIAGRAM.md +488 -0
- package/app/MINDOS_EXPLORATION_SUMMARY.md +229 -0
- package/app/MINDOS_INFRASTRUCTURE_ANALYSIS.md +732 -0
- package/app/app/api/channels/verify/route.ts +54 -0
- package/app/app/api/extract-pdf/route.ts +17 -3
- package/app/app/api/settings/list-models/route.ts +40 -44
- package/app/app/api/settings/route.ts +16 -0
- package/app/app/api/settings/test-key/route.ts +5 -2
- package/app/app/view/[...path]/ViewPageClient.tsx +1 -1
- package/app/components/Breadcrumb.tsx +11 -11
- package/app/components/DirView.tsx +1 -1
- package/app/components/FindInPage.tsx +1 -1
- package/app/components/InboxView.tsx +2 -2
- package/app/components/MarkdownView.tsx +4 -0
- package/app/components/Panel.tsx +17 -10
- package/app/components/TableOfContents.tsx +9 -9
- package/app/components/agents/AgentsContentChannelDetail.tsx +168 -54
- package/app/components/agents/AgentsContentChannels.tsx +22 -22
- package/app/components/ask/AskContent.tsx +68 -28
- package/app/components/ask/AskHeader.tsx +6 -2
- package/app/components/ask/ProviderModelCapsule.tsx +11 -9
- package/app/components/ask/SessionHistoryPanel.tsx +398 -0
- package/app/components/settings/AiTab.tsx +5 -1
- package/app/components/settings/KnowledgeTab.tsx +92 -1
- package/app/components/settings/McpConnectGuides.tsx +4 -0
- package/app/components/settings/McpPortSection.tsx +207 -0
- package/app/components/settings/McpTab.tsx +1 -5
- package/app/components/settings/TestButton.tsx +1 -0
- package/app/components/settings/{ServerPortsCard.tsx → WebPortSection.tsx} +66 -151
- package/app/components/settings/types.ts +12 -0
- package/app/components/settings/useCustomProviderForm.ts +2 -2
- package/app/data/skills/mindos/SKILL.md +45 -1
- package/app/hooks/useAcpDetection.ts +1 -1
- package/app/hooks/useAcpRegistry.ts +1 -1
- package/app/hooks/useFileImport.ts +7 -2
- package/app/hooks/useFileUpload.ts +17 -10
- package/app/lib/acp/agent-descriptors.ts +18 -0
- package/app/lib/acp/index.ts +3 -7
- package/app/lib/acp/registry.ts +1 -1
- package/app/lib/acp/session.ts +237 -530
- package/app/lib/acp/subprocess.ts +224 -427
- package/app/lib/acp/types.ts +0 -29
- package/app/lib/agent/model.ts +20 -4
- package/app/lib/agent/non-streaming.ts +37 -20
- package/app/lib/agent/providers.ts +31 -0
- package/app/lib/agent/tools.ts +2 -1
- package/app/lib/core/embedding-index.ts +285 -0
- package/app/lib/core/embedding-provider.ts +164 -0
- package/app/lib/core/hybrid-search.ts +160 -0
- package/app/lib/core/search.ts +11 -21
- package/app/lib/i18n/modules/ai-chat.ts +26 -0
- package/app/lib/i18n/modules/panels.ts +14 -0
- package/app/lib/i18n/modules/settings.ts +2 -0
- package/app/lib/im/platforms.ts +6 -2
- package/app/lib/im/verify.ts +94 -0
- package/app/lib/pdf-extract.ts +6 -2
- package/app/lib/settings.ts +23 -0
- package/app/package.json +2 -1
- package/bin/cli.js +3 -1
- package/bin/commands/channel.js +342 -0
- package/bin/commands/update.js +11 -4
- package/bin/lib/build.js +34 -16
- package/bin/lib/channel-config.js +168 -0
- package/bin/lib/channel-constants.js +88 -0
- package/bin/lib/channel-mgmt.js +244 -0
- package/bin/lib/channel-prompts.js +72 -0
- package/bin/lib/channel-validate.js +57 -0
- package/bin/lib/safe-rm.js +165 -0
- package/package.json +1 -1
- package/skills/mindos/SKILL.md +45 -1
- package/_standalone/.next/server/chunks/1750.js +0 -1
- package/_standalone/.next/server/chunks/7200.js +0 -52
- package/_standalone/.next/static/HL8b6d3NCfyoAXNuY2kcn/_buildManifest.js +0 -1
- package/_standalone/.next/static/chunks/1814.a79b84d37df75c43.js +0 -1
- package/_standalone/.next/static/chunks/3466.bc6ab3172ad66091.js +0 -1
- package/_standalone/.next/static/chunks/3637.38c4f28d8f698e0e.js +0 -1
- package/_standalone/.next/static/chunks/4351-9ab695985bb808ad.js +0 -1
- package/_standalone/.next/static/chunks/5133-3779d65f4fdfb041.js +0 -30
- package/_standalone/.next/static/chunks/5581-4dd3d32f6e8606ec.js +0 -29
- package/_standalone/.next/static/chunks/8735.66a049abcf0971fb.js +0 -48
- package/_standalone/.next/static/chunks/app/agents/page-4c0637183e46c8d3.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/config/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/install/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/session/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agents/copy-skill/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agents/custom/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/auth/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/backlinks/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/changes/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/connect/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/export/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/import/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/raw/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/files/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/git/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/graph/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/health/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/im/config/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/im/status/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/im/test/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/inbox/clip/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/inbox/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/init/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/lint/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/direct-tools/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/tools/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/monitoring/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/recent-files/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/restart/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/search/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/skills/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/space-overview/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/sync/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/tree-version/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/uninstall/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-check/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-status/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/workflows/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/changes/page-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-5333ab47257fab7f.js +0 -159
- package/_standalone/.next/static/chunks/app/echo/page-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/layout-bd0652768781e726.js +0 -133
- package/_standalone/.next/static/chunks/app/loading-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/trash/page-8280ba2f5c20861e.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-b942374e2f88c53e.js +0 -12
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/webpack-9e42857d6c44fe70.js +0 -1
- package/_standalone/.next/static/css/8b1f248d6540e52f.css +0 -1
- package/_standalone/lib/core/__tests__/synonym-dict.test.ts +0 -82
- package/app/lib/core/__tests__/synonym-dict.test.ts +0 -82
- package/app/lib/core/synonym-dict.ts +0 -139
- /package/_standalone/.next/static/{HL8b6d3NCfyoAXNuY2kcn → ixCTELNH6V05Z00pC6ZMO}/_ssgManifest.js +0 -0
|
@@ -1,34 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ACP Subprocess Manager — Spawn
|
|
3
|
-
*
|
|
2
|
+
* ACP Subprocess Manager — Spawn ACP agent processes and create SDK connections.
|
|
3
|
+
* Process lifecycle (spawn, kill, cleanup) remains here.
|
|
4
|
+
* All JSON-RPC protocol handling is delegated to @agentclientprotocol/sdk.
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
import { spawn, type ChildProcess } from 'child_process';
|
|
8
|
+
import { Readable, Writable } from 'node:stream';
|
|
7
9
|
import path from 'path';
|
|
8
10
|
import os from 'os';
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import {
|
|
13
|
+
ClientSideConnection,
|
|
14
|
+
ndJsonStream,
|
|
15
|
+
RequestError,
|
|
16
|
+
type Client,
|
|
17
|
+
type SessionNotification,
|
|
18
|
+
type ReadTextFileRequest,
|
|
19
|
+
type ReadTextFileResponse,
|
|
20
|
+
type WriteTextFileRequest,
|
|
21
|
+
type WriteTextFileResponse,
|
|
22
|
+
type CreateTerminalRequest,
|
|
23
|
+
type CreateTerminalResponse,
|
|
24
|
+
type TerminalOutputRequest,
|
|
25
|
+
type TerminalOutputResponse,
|
|
26
|
+
type KillTerminalRequest,
|
|
27
|
+
type KillTerminalResponse,
|
|
28
|
+
type WaitForTerminalExitRequest,
|
|
29
|
+
type WaitForTerminalExitResponse,
|
|
30
|
+
type ReleaseTerminalRequest,
|
|
31
|
+
type ReleaseTerminalResponse,
|
|
32
|
+
type RequestPermissionRequest,
|
|
33
|
+
type RequestPermissionResponse,
|
|
34
|
+
} from '@agentclientprotocol/sdk';
|
|
35
|
+
import type { AcpRegistryEntry } from './types';
|
|
36
|
+
import { resolveAgentCommand, findUserOverride } from './agent-descriptors';
|
|
15
37
|
import { readSettings } from '../settings';
|
|
16
38
|
|
|
17
|
-
/** Incoming JSON-RPC request from agent (bidirectional — agent asks US for permission). */
|
|
18
|
-
export interface AcpIncomingRequest {
|
|
19
|
-
jsonrpc: '2.0';
|
|
20
|
-
id: string | number;
|
|
21
|
-
method: string;
|
|
22
|
-
params?: Record<string, unknown>;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** JSON-RPC 2.0 notification from agent (no id → no response expected). */
|
|
26
|
-
export interface AcpNotification {
|
|
27
|
-
jsonrpc: '2.0';
|
|
28
|
-
method: string;
|
|
29
|
-
params?: Record<string, unknown>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
39
|
/* ── Types ─────────────────────────────────────────────────────────────── */
|
|
33
40
|
|
|
34
41
|
export interface AcpProcess {
|
|
@@ -36,35 +43,68 @@ export interface AcpProcess {
|
|
|
36
43
|
agentId: string;
|
|
37
44
|
proc: ChildProcess;
|
|
38
45
|
alive: boolean;
|
|
39
|
-
/** Set when the process fails to spawn or exits with an error. */
|
|
40
46
|
spawnError?: string;
|
|
41
|
-
/** Exit code when the process has terminated. */
|
|
42
47
|
exitCode?: number | null;
|
|
43
48
|
}
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Mutable callbacks container — session layer swaps handlers
|
|
52
|
+
* for each prompt/promptStream call.
|
|
53
|
+
*/
|
|
54
|
+
export interface AcpClientCallbacks {
|
|
55
|
+
onSessionUpdate?: (params: SessionNotification) => void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface AcpConnection {
|
|
59
|
+
connection: ClientSideConnection;
|
|
60
|
+
callbacks: AcpClientCallbacks;
|
|
61
|
+
process: AcpProcess;
|
|
62
|
+
}
|
|
48
63
|
|
|
49
64
|
/* ── State ─────────────────────────────────────────────────────────────── */
|
|
50
65
|
|
|
51
66
|
const processes = new Map<string, AcpProcess>();
|
|
52
|
-
const messageListeners = new Map<string, Set<MessageCallback>>();
|
|
53
|
-
const requestListeners = new Map<string, Set<RequestCallback>>();
|
|
54
|
-
const notificationListeners = new Map<string, Set<NotificationCallback>>();
|
|
55
|
-
let rpcIdCounter = 1;
|
|
56
67
|
|
|
57
|
-
/* ── Public API
|
|
68
|
+
/* ── Public API — Process Lifecycle ───────────────────────────────────── */
|
|
58
69
|
|
|
59
70
|
/**
|
|
60
|
-
* Spawn an ACP agent subprocess.
|
|
71
|
+
* Spawn an ACP agent subprocess and create an SDK connection.
|
|
72
|
+
* Returns both the process handle and the SDK ClientSideConnection.
|
|
73
|
+
*/
|
|
74
|
+
export function spawnAndConnect(
|
|
75
|
+
entry: AcpRegistryEntry,
|
|
76
|
+
options?: { env?: Record<string, string>; cwd?: string },
|
|
77
|
+
): AcpConnection {
|
|
78
|
+
const proc = spawnAcpAgent(entry, options);
|
|
79
|
+
const cwd = options?.cwd ?? process.cwd();
|
|
80
|
+
const callbacks: AcpClientCallbacks = {};
|
|
81
|
+
|
|
82
|
+
const client = createMindosClient(proc, cwd, callbacks);
|
|
83
|
+
|
|
84
|
+
const output = Writable.toWeb(proc.proc.stdin!) as WritableStream<Uint8Array>;
|
|
85
|
+
const input = Readable.toWeb(proc.proc.stdout!) as ReadableStream<Uint8Array>;
|
|
86
|
+
const stream = ndJsonStream(output, input);
|
|
87
|
+
|
|
88
|
+
const connection = new ClientSideConnection(() => client, stream);
|
|
89
|
+
|
|
90
|
+
connection.signal.addEventListener('abort', () => {
|
|
91
|
+
if (proc.alive) {
|
|
92
|
+
proc.alive = false;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return { connection, callbacks, process: proc };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Spawn an ACP agent subprocess (low-level — prefer spawnAndConnect).
|
|
61
101
|
*/
|
|
62
102
|
export function spawnAcpAgent(
|
|
63
103
|
entry: AcpRegistryEntry,
|
|
64
104
|
options?: { env?: Record<string, string>; cwd?: string },
|
|
65
105
|
): AcpProcess {
|
|
66
106
|
const settings = readSettings();
|
|
67
|
-
const userOverride = settings.acpAgents
|
|
107
|
+
const userOverride = findUserOverride(entry.id, settings.acpAgents);
|
|
68
108
|
const resolved = resolveAgentCommand(entry.id, entry, userOverride);
|
|
69
109
|
const { cmd, args } = { cmd: resolved.cmd, args: resolved.args };
|
|
70
110
|
|
|
@@ -87,50 +127,10 @@ export function spawnAcpAgent(
|
|
|
87
127
|
const acpProc: AcpProcess = { id, agentId: entry.id, proc, alive: true };
|
|
88
128
|
|
|
89
129
|
processes.set(id, acpProc);
|
|
90
|
-
messageListeners.set(id, new Set());
|
|
91
|
-
requestListeners.set(id, new Set());
|
|
92
|
-
notificationListeners.set(id, new Set());
|
|
93
|
-
|
|
94
|
-
// Parse newline-delimited JSON-RPC 2.0 from stdout.
|
|
95
|
-
// Three message types per spec:
|
|
96
|
-
// 1. Request (has method + id) → agent asking client for something
|
|
97
|
-
// 2. Notification (has method, NO id) → agent streaming updates
|
|
98
|
-
// 3. Response (has id, NO method) → reply to our request
|
|
99
|
-
let buffer = '';
|
|
100
|
-
proc.stdout?.on('data', (chunk: Buffer) => {
|
|
101
|
-
buffer += chunk.toString();
|
|
102
|
-
const lines = buffer.split('\n');
|
|
103
|
-
buffer = lines.pop() ?? '';
|
|
104
|
-
|
|
105
|
-
for (const line of lines) {
|
|
106
|
-
const trimmed = line.trim();
|
|
107
|
-
if (!trimmed) continue;
|
|
108
|
-
try {
|
|
109
|
-
const msg = JSON.parse(trimmed);
|
|
110
|
-
|
|
111
|
-
if (msg.method !== undefined) {
|
|
112
|
-
if (msg.id !== undefined) {
|
|
113
|
-
const reqCbs = requestListeners.get(id);
|
|
114
|
-
if (reqCbs) for (const cb of reqCbs) cb(msg as AcpIncomingRequest);
|
|
115
|
-
} else {
|
|
116
|
-
const notifCbs = notificationListeners.get(id);
|
|
117
|
-
if (notifCbs) for (const cb of notifCbs) cb(msg as AcpNotification);
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
const msgCbs = messageListeners.get(id);
|
|
121
|
-
if (msgCbs) for (const cb of msgCbs) cb(msg as AcpJsonRpcResponse);
|
|
122
|
-
}
|
|
123
|
-
} catch {
|
|
124
|
-
// Not valid JSON — skip (could be agent debug output)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
130
|
|
|
129
|
-
// Capture stderr for debugging (agents may log startup errors there)
|
|
130
131
|
let stderrBuf = '';
|
|
131
132
|
proc.stderr?.on('data', (chunk: Buffer) => {
|
|
132
133
|
stderrBuf += chunk.toString();
|
|
133
|
-
// Keep only last 4KB to avoid unbounded memory
|
|
134
134
|
if (stderrBuf.length > 4096) stderrBuf = stderrBuf.slice(-4096);
|
|
135
135
|
});
|
|
136
136
|
|
|
@@ -141,8 +141,6 @@ export function spawnAcpAgent(
|
|
|
141
141
|
acpProc.spawnError = stderrBuf.trim().slice(0, 500) || `Process exited with code ${code}`;
|
|
142
142
|
console.error(`[ACP] ${entry.id} exited with code ${code}: ${acpProc.spawnError}`);
|
|
143
143
|
}
|
|
144
|
-
// Do NOT delete listeners here — sendAndWait still needs them to reject.
|
|
145
|
-
// Listeners are cleaned up in killAgent() and by individual unsub calls.
|
|
146
144
|
});
|
|
147
145
|
|
|
148
146
|
proc.on('error', (err) => {
|
|
@@ -154,131 +152,22 @@ export function spawnAcpAgent(
|
|
|
154
152
|
return acpProc;
|
|
155
153
|
}
|
|
156
154
|
|
|
157
|
-
/**
|
|
158
|
-
* Send a JSON-RPC message to an ACP agent's stdin.
|
|
159
|
-
*/
|
|
160
|
-
export function sendMessage(acpProc: AcpProcess, method: string, params?: Record<string, unknown>): string {
|
|
161
|
-
if (!acpProc.alive || !acpProc.proc.stdin?.writable) {
|
|
162
|
-
throw new Error(`ACP process ${acpProc.id} is not alive`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const id = `rpc-${rpcIdCounter++}`;
|
|
166
|
-
const request: AcpJsonRpcRequest = {
|
|
167
|
-
jsonrpc: '2.0',
|
|
168
|
-
id,
|
|
169
|
-
method,
|
|
170
|
-
...(params ? { params } : {}),
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
acpProc.proc.stdin.write(JSON.stringify(request) + '\n');
|
|
174
|
-
return id;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Register a callback for messages from an ACP agent.
|
|
179
|
-
* Returns an unsubscribe function.
|
|
180
|
-
*/
|
|
181
|
-
export function onMessage(acpProc: AcpProcess, callback: MessageCallback): () => void {
|
|
182
|
-
const listeners = messageListeners.get(acpProc.id);
|
|
183
|
-
if (!listeners) throw new Error(`ACP process ${acpProc.id} not found`);
|
|
184
|
-
|
|
185
|
-
listeners.add(callback);
|
|
186
|
-
return () => { listeners.delete(callback); };
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Send a JSON-RPC request and wait for a response with the matching ID.
|
|
191
|
-
*/
|
|
192
|
-
export function sendAndWait(
|
|
193
|
-
acpProc: AcpProcess,
|
|
194
|
-
method: string,
|
|
195
|
-
params?: Record<string, unknown>,
|
|
196
|
-
timeoutMs = 30_000,
|
|
197
|
-
): Promise<AcpJsonRpcResponse> {
|
|
198
|
-
return new Promise((resolve, reject) => {
|
|
199
|
-
// Fail fast if process is already dead (e.g. binary not found).
|
|
200
|
-
if (!acpProc.alive) {
|
|
201
|
-
const reason = acpProc.spawnError || 'Process is not alive';
|
|
202
|
-
reject(new Error(
|
|
203
|
-
`Agent "${acpProc.agentId}" is not running: ${reason}. ` +
|
|
204
|
-
`Please check that the agent is installed and available on your PATH.`,
|
|
205
|
-
));
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
let rpcId: string;
|
|
210
|
-
try {
|
|
211
|
-
rpcId = sendMessage(acpProc, method, params);
|
|
212
|
-
} catch (err) {
|
|
213
|
-
reject(err);
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const cleanup = () => {
|
|
218
|
-
clearTimeout(timer);
|
|
219
|
-
unsub();
|
|
220
|
-
acpProc.proc.removeListener('close', onClose);
|
|
221
|
-
acpProc.proc.removeListener('error', onError);
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
const timer = setTimeout(() => {
|
|
225
|
-
cleanup();
|
|
226
|
-
reject(new Error(`ACP RPC timeout after ${timeoutMs}ms for method: ${method}`));
|
|
227
|
-
}, timeoutMs);
|
|
228
|
-
|
|
229
|
-
const unsub = onMessage(acpProc, (msg) => {
|
|
230
|
-
if (String(msg.id) === rpcId) {
|
|
231
|
-
cleanup();
|
|
232
|
-
resolve(msg);
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
// Reject immediately if the process dies while we're waiting.
|
|
237
|
-
const onClose = (code: number | null) => {
|
|
238
|
-
cleanup();
|
|
239
|
-
const reason = acpProc.spawnError || `Process exited with code ${code}`;
|
|
240
|
-
reject(new Error(
|
|
241
|
-
`Agent "${acpProc.agentId}" exited unexpectedly: ${reason}. ` +
|
|
242
|
-
`Please check that the agent is installed and available on your PATH.`,
|
|
243
|
-
));
|
|
244
|
-
};
|
|
245
|
-
const onError = (err: Error) => {
|
|
246
|
-
cleanup();
|
|
247
|
-
reject(new Error(
|
|
248
|
-
`Agent "${acpProc.agentId}" failed to start: ${err.message}. ` +
|
|
249
|
-
`Please check that the agent is installed and available on your PATH.`,
|
|
250
|
-
));
|
|
251
|
-
};
|
|
252
|
-
acpProc.proc.once('close', onClose);
|
|
253
|
-
acpProc.proc.once('error', onError);
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
|
|
257
155
|
/**
|
|
258
156
|
* Kill an ACP agent process and its entire process tree.
|
|
259
|
-
* Uses negative PID to send signal to the process group (requires detached spawn).
|
|
260
157
|
*/
|
|
261
158
|
export function killAgent(acpProc: AcpProcess): void {
|
|
262
159
|
const pid = acpProc.proc.pid;
|
|
263
160
|
if (pid) {
|
|
264
|
-
// Kill the entire process group via negative PID
|
|
265
161
|
try { process.kill(-pid, 'SIGTERM'); } catch { /* already dead */ }
|
|
266
|
-
|
|
267
|
-
// Force SIGKILL after 3s — use signal 0 probe instead of `alive` flag
|
|
268
|
-
// because `alive` is set to false below before the timeout fires.
|
|
269
162
|
setTimeout(() => {
|
|
270
163
|
try {
|
|
271
|
-
process.kill(-pid, 0);
|
|
164
|
+
process.kill(-pid, 0);
|
|
272
165
|
process.kill(-pid, 'SIGKILL');
|
|
273
|
-
} catch { /* already dead
|
|
166
|
+
} catch { /* already dead */ }
|
|
274
167
|
}, 3000);
|
|
275
168
|
}
|
|
276
169
|
acpProc.alive = false;
|
|
277
170
|
processes.delete(acpProc.id);
|
|
278
|
-
messageListeners.delete(acpProc.id);
|
|
279
|
-
requestListeners.delete(acpProc.id);
|
|
280
|
-
notificationListeners.delete(acpProc.id);
|
|
281
|
-
// Clean up any terminals spawned by this process
|
|
282
171
|
const terms = terminalMaps.get(acpProc.id);
|
|
283
172
|
if (terms) {
|
|
284
173
|
for (const entry of terms.values()) {
|
|
@@ -288,275 +177,185 @@ export function killAgent(acpProc: AcpProcess): void {
|
|
|
288
177
|
}
|
|
289
178
|
}
|
|
290
179
|
|
|
291
|
-
/**
|
|
292
|
-
* Get a process by its ID.
|
|
293
|
-
*/
|
|
294
180
|
export function getProcess(id: string): AcpProcess | undefined {
|
|
295
181
|
return processes.get(id);
|
|
296
182
|
}
|
|
297
183
|
|
|
298
|
-
/**
|
|
299
|
-
* Get all active processes.
|
|
300
|
-
*/
|
|
301
184
|
export function getActiveProcesses(): AcpProcess[] {
|
|
302
185
|
return [...processes.values()].filter(p => p.alive);
|
|
303
186
|
}
|
|
304
187
|
|
|
305
|
-
/**
|
|
306
|
-
* Kill all active ACP processes. Used for cleanup.
|
|
307
|
-
*/
|
|
308
188
|
export function killAllAgents(): void {
|
|
309
189
|
for (const proc of processes.values()) {
|
|
310
190
|
killAgent(proc);
|
|
311
191
|
}
|
|
312
192
|
}
|
|
313
193
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
): void {
|
|
349
|
-
if (!acpProc.alive || !acpProc.proc.stdin?.writable) {
|
|
350
|
-
throw new Error(`ACP process ${acpProc.id} is not alive`);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const response: AcpJsonRpcResponse = {
|
|
354
|
-
jsonrpc: '2.0',
|
|
355
|
-
id,
|
|
356
|
-
result,
|
|
357
|
-
};
|
|
358
|
-
acpProc.proc.stdin.write(JSON.stringify(response) + '\n');
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Install auto-approval for all incoming permission/capability requests.
|
|
363
|
-
* Agents in ACP mode send requests like fs/read, fs/write, terminal/execute etc.
|
|
364
|
-
* Without approval, the agent hangs waiting for TTY input that never comes.
|
|
365
|
-
* Returns an unsubscribe function.
|
|
366
|
-
*/
|
|
367
|
-
export function installAutoApproval(
|
|
368
|
-
acpProc: AcpProcess,
|
|
369
|
-
options?: { cwd?: string },
|
|
370
|
-
): () => void {
|
|
371
|
-
const cwd = options?.cwd;
|
|
372
|
-
|
|
373
|
-
return onRequest(acpProc, (req) => {
|
|
374
|
-
const method = req.method;
|
|
375
|
-
const params = (req.params ?? {}) as Record<string, unknown>;
|
|
376
|
-
|
|
377
|
-
switch (method) {
|
|
378
|
-
// ── File system: read ──
|
|
379
|
-
case 'fs/read_text_file': {
|
|
380
|
-
const filePath = String(params.path ?? '');
|
|
381
|
-
if (!filePath) {
|
|
382
|
-
sendResponse(acpProc, req.id, { error: { code: -32602, message: 'path is required' } });
|
|
383
|
-
return;
|
|
384
|
-
}
|
|
385
|
-
if (isSensitivePath(filePath)) {
|
|
386
|
-
sendResponse(acpProc, req.id, { error: { code: -32001, message: `Access denied: ${filePath} is a sensitive file` } });
|
|
387
|
-
return;
|
|
194
|
+
/* ── Client Implementation ─────────────────────────────────────────────── */
|
|
195
|
+
|
|
196
|
+
function createMindosClient(
|
|
197
|
+
proc: AcpProcess,
|
|
198
|
+
cwd: string,
|
|
199
|
+
callbacks: AcpClientCallbacks,
|
|
200
|
+
): Client {
|
|
201
|
+
return {
|
|
202
|
+
async requestPermission(params: RequestPermissionRequest): Promise<RequestPermissionResponse> {
|
|
203
|
+
console.log(`[ACP] Auto-approve permission: agent=${proc.agentId} ${JSON.stringify(params.toolCall ?? params).slice(0, 200)}`);
|
|
204
|
+
const options = params.options ?? [];
|
|
205
|
+
const selected =
|
|
206
|
+
options.find(o => o.kind === 'allow_once') ??
|
|
207
|
+
options.find(o => o.kind === 'allow_always') ??
|
|
208
|
+
options[0];
|
|
209
|
+
return { outcome: { outcome: 'selected', optionId: selected?.optionId ?? 'allow_once' } };
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
async sessionUpdate(params: SessionNotification): Promise<void> {
|
|
213
|
+
callbacks.onSessionUpdate?.(params);
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
async readTextFile(params: ReadTextFileRequest): Promise<ReadTextFileResponse> {
|
|
217
|
+
if (!params.path) throw RequestError.invalidParams(undefined, 'path is required');
|
|
218
|
+
if (isSensitivePath(params.path)) {
|
|
219
|
+
throw new RequestError(-32001, `Access denied: ${params.path} is a sensitive file`);
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
let content = fs.readFileSync(params.path, 'utf-8');
|
|
223
|
+
if (params.line != null || params.limit != null) {
|
|
224
|
+
const lines = content.split('\n');
|
|
225
|
+
const start = ((params.line ?? 1) - 1);
|
|
226
|
+
const end = params.limit != null ? start + params.limit : lines.length;
|
|
227
|
+
content = lines.slice(Math.max(0, start), end).join('\n');
|
|
388
228
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
if (line !== undefined || limit !== undefined) {
|
|
395
|
-
const lines = content.split('\n');
|
|
396
|
-
const start = (line ?? 1) - 1; // 1-based to 0-based
|
|
397
|
-
const end = limit !== undefined ? start + limit : lines.length;
|
|
398
|
-
content = lines.slice(Math.max(0, start), end).join('\n');
|
|
399
|
-
}
|
|
400
|
-
sendResponse(acpProc, req.id, { content });
|
|
401
|
-
} catch (err) {
|
|
402
|
-
sendResponse(acpProc, req.id, { error: { code: -32002, message: (err as Error).message } });
|
|
229
|
+
return { content };
|
|
230
|
+
} catch (err: any) {
|
|
231
|
+
if (err?.code === 'ENOENT') throw RequestError.resourceNotFound(params.path);
|
|
232
|
+
if (err?.code === 'EACCES' || err?.code === 'EPERM') {
|
|
233
|
+
throw new RequestError(-32001, `Permission denied: ${params.path}`);
|
|
403
234
|
}
|
|
404
|
-
|
|
235
|
+
throw new RequestError(-32603, `Failed to read ${params.path}: ${err?.message ?? err}`);
|
|
405
236
|
}
|
|
237
|
+
},
|
|
406
238
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
239
|
+
async writeTextFile(params: WriteTextFileRequest): Promise<WriteTextFileResponse> {
|
|
240
|
+
if (!params.path) throw RequestError.invalidParams(undefined, 'path is required');
|
|
241
|
+
if (!isWithinAllowedWritePaths(params.path, cwd)) {
|
|
242
|
+
throw new RequestError(-32001, `Write denied: ${params.path} is outside the working directory`);
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
const dir = path.dirname(params.path);
|
|
246
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
247
|
+
fs.writeFileSync(params.path, params.content, 'utf-8');
|
|
248
|
+
return {};
|
|
249
|
+
} catch (err: any) {
|
|
250
|
+
if (err?.code === 'EACCES' || err?.code === 'EPERM') {
|
|
251
|
+
throw new RequestError(-32001, `Write permission denied: ${params.path}`);
|
|
418
252
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const dir = path.dirname(filePath);
|
|
422
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
423
|
-
fs.writeFileSync(filePath, content, 'utf-8');
|
|
424
|
-
sendResponse(acpProc, req.id, {});
|
|
425
|
-
} catch (err) {
|
|
426
|
-
sendResponse(acpProc, req.id, { error: { code: -32603, message: (err as Error).message } });
|
|
253
|
+
if (err?.code === 'ENOSPC') {
|
|
254
|
+
throw new RequestError(-32603, `Disk full: cannot write ${params.path}`);
|
|
427
255
|
}
|
|
428
|
-
|
|
256
|
+
throw RequestError.internalError(undefined, err?.message ?? String(err));
|
|
429
257
|
}
|
|
258
|
+
},
|
|
430
259
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
const command = String(params.command ?? '');
|
|
434
|
-
const args = Array.isArray(params.args) ? params.args.map(String) : [];
|
|
435
|
-
const cwd = typeof params.cwd === 'string' ? params.cwd : undefined;
|
|
436
|
-
const env = (params.env && typeof params.env === 'object') ? params.env as Record<string, string> : undefined;
|
|
437
|
-
const outputByteLimit = typeof params.outputByteLimit === 'number' ? params.outputByteLimit : 1_000_000;
|
|
438
|
-
|
|
439
|
-
if (!command) {
|
|
440
|
-
sendResponse(acpProc, req.id, { error: { code: -32602, message: 'command is required' } });
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
260
|
+
async createTerminal(params: CreateTerminalRequest): Promise<CreateTerminalResponse> {
|
|
261
|
+
if (!params.command) throw RequestError.invalidParams(undefined, 'command is required');
|
|
443
262
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
cwd,
|
|
449
|
-
env: { ...process.env, ...(env ?? {}) },
|
|
450
|
-
shell: true,
|
|
451
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
let output = '';
|
|
455
|
-
let truncated = false;
|
|
456
|
-
|
|
457
|
-
child.stdout?.on('data', (chunk: Buffer) => {
|
|
458
|
-
if (output.length < outputByteLimit) {
|
|
459
|
-
output += chunk.toString();
|
|
460
|
-
if (output.length > outputByteLimit) {
|
|
461
|
-
output = output.slice(0, outputByteLimit);
|
|
462
|
-
truncated = true;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
});
|
|
466
|
-
child.stderr?.on('data', (chunk: Buffer) => {
|
|
467
|
-
if (output.length < outputByteLimit) {
|
|
468
|
-
output += chunk.toString();
|
|
469
|
-
if (output.length > outputByteLimit) {
|
|
470
|
-
output = output.slice(0, outputByteLimit);
|
|
471
|
-
truncated = true;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
});
|
|
475
|
-
|
|
476
|
-
// Store terminal in process-scoped map
|
|
477
|
-
const terminalMap = getOrCreateTerminalMap(acpProc.id);
|
|
478
|
-
terminalMap.set(terminalId, { child, output: () => output, truncated: () => truncated });
|
|
479
|
-
|
|
480
|
-
sendResponse(acpProc, req.id, { terminalId });
|
|
481
|
-
} catch (err) {
|
|
482
|
-
sendResponse(acpProc, req.id, { error: { code: -32603, message: (err as Error).message } });
|
|
483
|
-
}
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
263
|
+
const requestedCwd = params.cwd ?? undefined;
|
|
264
|
+
const terminalCwd = requestedCwd && isWithinAllowedWritePaths(requestedCwd, cwd)
|
|
265
|
+
? requestedCwd
|
|
266
|
+
: cwd;
|
|
486
267
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const
|
|
490
|
-
const terminal = getTerminal(acpProc.id, terminalId);
|
|
491
|
-
if (!terminal) {
|
|
492
|
-
sendResponse(acpProc, req.id, { error: { code: -32002, message: `Terminal not found: ${terminalId}` } });
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
const exitStatus = terminal.child.exitCode !== null ? { exitCode: terminal.child.exitCode } : undefined;
|
|
496
|
-
sendResponse(acpProc, req.id, { output: terminal.output(), truncated: terminal.truncated(), exitStatus });
|
|
497
|
-
return;
|
|
268
|
+
const envObj: Record<string, string> = {};
|
|
269
|
+
if (params.env) {
|
|
270
|
+
for (const v of params.env) envObj[v.name] = v.value;
|
|
498
271
|
}
|
|
499
272
|
|
|
500
|
-
|
|
501
|
-
case 'terminal/kill': {
|
|
502
|
-
const terminalId = String(params.terminalId ?? '');
|
|
503
|
-
const terminal = getTerminal(acpProc.id, terminalId);
|
|
504
|
-
if (!terminal) {
|
|
505
|
-
sendResponse(acpProc, req.id, { error: { code: -32002, message: `Terminal not found: ${terminalId}` } });
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
terminal.child.kill('SIGTERM');
|
|
509
|
-
sendResponse(acpProc, req.id, {});
|
|
510
|
-
return;
|
|
511
|
-
}
|
|
273
|
+
console.log(`[ACP] terminal/create: agent=${proc.agentId} cmd="${params.command} ${(params.args ?? []).join(' ')}" cwd=${terminalCwd}`);
|
|
512
274
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
sendResponse(acpProc, req.id, { exitCode: terminal.child.exitCode, signal: terminal.child.signalCode });
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
terminal.child.on('exit', (code: number | null, signal: string | null) => {
|
|
526
|
-
sendResponse(acpProc, req.id, { exitCode: code, signal });
|
|
275
|
+
const terminalId = `term-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
276
|
+
const outputByteLimit = params.outputByteLimit ?? 1_000_000;
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
const child = spawn(params.command, params.args ?? [], {
|
|
280
|
+
cwd: terminalCwd,
|
|
281
|
+
env: { ...process.env, ...envObj },
|
|
282
|
+
shell: true,
|
|
283
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
527
284
|
});
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
285
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
if (
|
|
536
|
-
|
|
537
|
-
|
|
286
|
+
let output = '';
|
|
287
|
+
let truncated = false;
|
|
288
|
+
const collect = (chunk: Buffer) => {
|
|
289
|
+
output += chunk.toString();
|
|
290
|
+
if (output.length > outputByteLimit) {
|
|
291
|
+
// ACP spec: truncate from the beginning, keeping most recent output
|
|
292
|
+
output = output.slice(-outputByteLimit);
|
|
293
|
+
truncated = true;
|
|
538
294
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
return;
|
|
543
|
-
}
|
|
295
|
+
};
|
|
296
|
+
child.stdout?.on('data', collect);
|
|
297
|
+
child.stderr?.on('data', collect);
|
|
544
298
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
// Auto-approve in production; log in dev for debugging
|
|
548
|
-
if (process.env.NODE_ENV === 'development') console.log(`[ACP] Auto-approving permission: ${JSON.stringify(params.toolCall ?? {}).slice(0, 200)}`);
|
|
549
|
-
sendResponse(acpProc, req.id, { outcome: { selected: { optionId: 'allow_once' } } });
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
299
|
+
const terminalMap = getOrCreateTerminalMap(proc.id);
|
|
300
|
+
terminalMap.set(terminalId, { child, output: () => output, truncated: () => truncated });
|
|
552
301
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
sendResponse(acpProc, req.id, {});
|
|
302
|
+
return { terminalId };
|
|
303
|
+
} catch (err) {
|
|
304
|
+
throw RequestError.internalError(undefined, (err as Error).message);
|
|
557
305
|
}
|
|
558
|
-
}
|
|
559
|
-
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
async terminalOutput(params: TerminalOutputRequest): Promise<TerminalOutputResponse> {
|
|
309
|
+
const terminal = getTerminal(proc.id, params.terminalId);
|
|
310
|
+
if (!terminal) throw new RequestError(-32002, `Terminal not found: ${params.terminalId}`);
|
|
311
|
+
const exitStatus = terminal.child.exitCode !== null
|
|
312
|
+
? { exitCode: terminal.child.exitCode, signal: terminal.child.signalCode }
|
|
313
|
+
: undefined;
|
|
314
|
+
return { output: terminal.output(), truncated: terminal.truncated(), exitStatus };
|
|
315
|
+
},
|
|
316
|
+
|
|
317
|
+
async killTerminal(params: KillTerminalRequest): Promise<KillTerminalResponse> {
|
|
318
|
+
const terminal = getTerminal(proc.id, params.terminalId);
|
|
319
|
+
if (!terminal) throw new RequestError(-32002, `Terminal not found: ${params.terminalId}`);
|
|
320
|
+
terminal.child.kill('SIGTERM');
|
|
321
|
+
return {};
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
async waitForTerminalExit(params: WaitForTerminalExitRequest): Promise<WaitForTerminalExitResponse> {
|
|
325
|
+
const terminal = getTerminal(proc.id, params.terminalId);
|
|
326
|
+
if (!terminal) throw new RequestError(-32002, `Terminal not found: ${params.terminalId}`);
|
|
327
|
+
if (terminal.child.exitCode !== null) {
|
|
328
|
+
return { exitCode: terminal.child.exitCode, signal: terminal.child.signalCode };
|
|
329
|
+
}
|
|
330
|
+
return new Promise((resolve) => {
|
|
331
|
+
terminal.child.on('exit', (code: number | null, signal: string | null) => {
|
|
332
|
+
resolve({ exitCode: code, signal });
|
|
333
|
+
});
|
|
334
|
+
// Re-check after attaching listener to avoid race condition:
|
|
335
|
+
// if child exited between the check above and .on('exit'), the event already fired.
|
|
336
|
+
if (terminal.child.exitCode !== null) {
|
|
337
|
+
resolve({ exitCode: terminal.child.exitCode, signal: terminal.child.signalCode });
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
},
|
|
341
|
+
|
|
342
|
+
async releaseTerminal(params: ReleaseTerminalRequest): Promise<ReleaseTerminalResponse> {
|
|
343
|
+
const terminal = getTerminal(proc.id, params.terminalId);
|
|
344
|
+
if (!terminal) throw new RequestError(-32002, `Terminal not found: ${params.terminalId}`);
|
|
345
|
+
if (terminal.child.exitCode === null) terminal.child.kill('SIGTERM');
|
|
346
|
+
removeTerminal(proc.id, params.terminalId);
|
|
347
|
+
return {};
|
|
348
|
+
},
|
|
349
|
+
|
|
350
|
+
async extMethod(_method: string, _params: Record<string, unknown>): Promise<Record<string, unknown>> {
|
|
351
|
+
console.log(`[ACP] Auto-approve ext method: agent=${proc.agentId} method=${_method}`);
|
|
352
|
+
return {};
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
async extNotification(_method: string, _params: Record<string, unknown>): Promise<void> {
|
|
356
|
+
// Silently accept extension notifications
|
|
357
|
+
},
|
|
358
|
+
};
|
|
560
359
|
}
|
|
561
360
|
|
|
562
361
|
/* ── Path safety ───────────────────────────────────────────────────────── */
|
|
@@ -586,7 +385,7 @@ function isWithinAllowedWritePaths(filePath: string, cwd: string): boolean {
|
|
|
586
385
|
/* ── Terminal management (per ACP process) ─────────────────────────────── */
|
|
587
386
|
|
|
588
387
|
interface TerminalEntry {
|
|
589
|
-
child:
|
|
388
|
+
child: ChildProcess;
|
|
590
389
|
output: () => string;
|
|
591
390
|
truncated: () => boolean;
|
|
592
391
|
}
|
|
@@ -609,5 +408,3 @@ function getTerminal(procId: string, terminalId: string): TerminalEntry | undefi
|
|
|
609
408
|
function removeTerminal(procId: string, terminalId: string): void {
|
|
610
409
|
terminalMaps.get(procId)?.delete(terminalId);
|
|
611
410
|
}
|
|
612
|
-
|
|
613
|
-
/* ── Internal — agent command resolution moved to agent-descriptors.ts ─ */
|