@geminilight/mindos 0.6.67 → 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 +26 -25
- 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.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 +17 -17
- 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 +26 -25
- 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 +39 -39
- 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-9bb19a959ffb87ac.js → layout-8aa53b34ef34a246.js} +28 -28
- 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 +101 -3
- package/_standalone/__tests__/acp/registry.test.ts +34 -5
- 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 +10 -10
- 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/panels/AgentsPanel.tsx +8 -1
- 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 +4 -6
- 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/acp/detect/route.ts +9 -15
- 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 +10 -10
- 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/panels/AgentsPanel.tsx +8 -1
- 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 +69 -29
- package/app/lib/acp/index.ts +4 -6
- package/app/lib/acp/registry.ts +43 -47
- package/app/lib/acp/session.ts +253 -517
- package/app/lib/acp/subprocess.ts +249 -414
- 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 +5 -3
- 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/8947.js +0 -52
- package/_standalone/.next/static/0JtsgqDZLSJ6MrIZIV6gC/_buildManifest.js +0 -1
- package/_standalone/.next/static/chunks/1814.a79b84d37df75c43.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/476.463546c195b89cce.js +0 -48
- 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/5998.7bd28de9747440b5.js +0 -1
- 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/loading-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/trash/page-bebb28bf472cf691.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-dd5698f3df138835.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-043f40ef7816d8c4.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/{0JtsgqDZLSJ6MrIZIV6gC → ixCTELNH6V05Z00pC6ZMO}/_ssgManifest.js +0 -0
|
@@ -1,32 +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';
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
import { Readable, Writable } from 'node:stream';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import os from 'os';
|
|
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';
|
|
13
37
|
import { readSettings } from '../settings';
|
|
14
38
|
|
|
15
|
-
/** Incoming JSON-RPC request from agent (bidirectional — agent asks US for permission). */
|
|
16
|
-
export interface AcpIncomingRequest {
|
|
17
|
-
jsonrpc: '2.0';
|
|
18
|
-
id: string | number;
|
|
19
|
-
method: string;
|
|
20
|
-
params?: Record<string, unknown>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** JSON-RPC 2.0 notification from agent (no id → no response expected). */
|
|
24
|
-
export interface AcpNotification {
|
|
25
|
-
jsonrpc: '2.0';
|
|
26
|
-
method: string;
|
|
27
|
-
params?: Record<string, unknown>;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
39
|
/* ── Types ─────────────────────────────────────────────────────────────── */
|
|
31
40
|
|
|
32
41
|
export interface AcpProcess {
|
|
@@ -34,35 +43,68 @@ export interface AcpProcess {
|
|
|
34
43
|
agentId: string;
|
|
35
44
|
proc: ChildProcess;
|
|
36
45
|
alive: boolean;
|
|
37
|
-
/** Set when the process fails to spawn or exits with an error. */
|
|
38
46
|
spawnError?: string;
|
|
39
|
-
/** Exit code when the process has terminated. */
|
|
40
47
|
exitCode?: number | null;
|
|
41
48
|
}
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
+
}
|
|
46
63
|
|
|
47
64
|
/* ── State ─────────────────────────────────────────────────────────────── */
|
|
48
65
|
|
|
49
66
|
const processes = new Map<string, AcpProcess>();
|
|
50
|
-
const messageListeners = new Map<string, Set<MessageCallback>>();
|
|
51
|
-
const requestListeners = new Map<string, Set<RequestCallback>>();
|
|
52
|
-
const notificationListeners = new Map<string, Set<NotificationCallback>>();
|
|
53
|
-
let rpcIdCounter = 1;
|
|
54
67
|
|
|
55
|
-
/* ── Public API
|
|
68
|
+
/* ── Public API — Process Lifecycle ───────────────────────────────────── */
|
|
69
|
+
|
|
70
|
+
/**
|
|
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
|
+
}
|
|
56
98
|
|
|
57
99
|
/**
|
|
58
|
-
* Spawn an ACP agent subprocess.
|
|
100
|
+
* Spawn an ACP agent subprocess (low-level — prefer spawnAndConnect).
|
|
59
101
|
*/
|
|
60
102
|
export function spawnAcpAgent(
|
|
61
103
|
entry: AcpRegistryEntry,
|
|
62
104
|
options?: { env?: Record<string, string>; cwd?: string },
|
|
63
105
|
): AcpProcess {
|
|
64
106
|
const settings = readSettings();
|
|
65
|
-
const userOverride = settings.acpAgents
|
|
107
|
+
const userOverride = findUserOverride(entry.id, settings.acpAgents);
|
|
66
108
|
const resolved = resolveAgentCommand(entry.id, entry, userOverride);
|
|
67
109
|
const { cmd, args } = { cmd: resolved.cmd, args: resolved.args };
|
|
68
110
|
|
|
@@ -85,50 +127,10 @@ export function spawnAcpAgent(
|
|
|
85
127
|
const acpProc: AcpProcess = { id, agentId: entry.id, proc, alive: true };
|
|
86
128
|
|
|
87
129
|
processes.set(id, acpProc);
|
|
88
|
-
messageListeners.set(id, new Set());
|
|
89
|
-
requestListeners.set(id, new Set());
|
|
90
|
-
notificationListeners.set(id, new Set());
|
|
91
|
-
|
|
92
|
-
// Parse newline-delimited JSON-RPC 2.0 from stdout.
|
|
93
|
-
// Three message types per spec:
|
|
94
|
-
// 1. Request (has method + id) → agent asking client for something
|
|
95
|
-
// 2. Notification (has method, NO id) → agent streaming updates
|
|
96
|
-
// 3. Response (has id, NO method) → reply to our request
|
|
97
|
-
let buffer = '';
|
|
98
|
-
proc.stdout?.on('data', (chunk: Buffer) => {
|
|
99
|
-
buffer += chunk.toString();
|
|
100
|
-
const lines = buffer.split('\n');
|
|
101
|
-
buffer = lines.pop() ?? '';
|
|
102
|
-
|
|
103
|
-
for (const line of lines) {
|
|
104
|
-
const trimmed = line.trim();
|
|
105
|
-
if (!trimmed) continue;
|
|
106
|
-
try {
|
|
107
|
-
const msg = JSON.parse(trimmed);
|
|
108
|
-
|
|
109
|
-
if (msg.method !== undefined) {
|
|
110
|
-
if (msg.id !== undefined) {
|
|
111
|
-
const reqCbs = requestListeners.get(id);
|
|
112
|
-
if (reqCbs) for (const cb of reqCbs) cb(msg as AcpIncomingRequest);
|
|
113
|
-
} else {
|
|
114
|
-
const notifCbs = notificationListeners.get(id);
|
|
115
|
-
if (notifCbs) for (const cb of notifCbs) cb(msg as AcpNotification);
|
|
116
|
-
}
|
|
117
|
-
} else {
|
|
118
|
-
const msgCbs = messageListeners.get(id);
|
|
119
|
-
if (msgCbs) for (const cb of msgCbs) cb(msg as AcpJsonRpcResponse);
|
|
120
|
-
}
|
|
121
|
-
} catch {
|
|
122
|
-
// Not valid JSON — skip (could be agent debug output)
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
130
|
|
|
127
|
-
// Capture stderr for debugging (agents may log startup errors there)
|
|
128
131
|
let stderrBuf = '';
|
|
129
132
|
proc.stderr?.on('data', (chunk: Buffer) => {
|
|
130
133
|
stderrBuf += chunk.toString();
|
|
131
|
-
// Keep only last 4KB to avoid unbounded memory
|
|
132
134
|
if (stderrBuf.length > 4096) stderrBuf = stderrBuf.slice(-4096);
|
|
133
135
|
});
|
|
134
136
|
|
|
@@ -139,8 +141,6 @@ export function spawnAcpAgent(
|
|
|
139
141
|
acpProc.spawnError = stderrBuf.trim().slice(0, 500) || `Process exited with code ${code}`;
|
|
140
142
|
console.error(`[ACP] ${entry.id} exited with code ${code}: ${acpProc.spawnError}`);
|
|
141
143
|
}
|
|
142
|
-
// Do NOT delete listeners here — sendAndWait still needs them to reject.
|
|
143
|
-
// Listeners are cleaned up in killAgent() and by individual unsub calls.
|
|
144
144
|
});
|
|
145
145
|
|
|
146
146
|
proc.on('error', (err) => {
|
|
@@ -152,131 +152,22 @@ export function spawnAcpAgent(
|
|
|
152
152
|
return acpProc;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
/**
|
|
156
|
-
* Send a JSON-RPC message to an ACP agent's stdin.
|
|
157
|
-
*/
|
|
158
|
-
export function sendMessage(acpProc: AcpProcess, method: string, params?: Record<string, unknown>): string {
|
|
159
|
-
if (!acpProc.alive || !acpProc.proc.stdin?.writable) {
|
|
160
|
-
throw new Error(`ACP process ${acpProc.id} is not alive`);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const id = `rpc-${rpcIdCounter++}`;
|
|
164
|
-
const request: AcpJsonRpcRequest = {
|
|
165
|
-
jsonrpc: '2.0',
|
|
166
|
-
id,
|
|
167
|
-
method,
|
|
168
|
-
...(params ? { params } : {}),
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
acpProc.proc.stdin.write(JSON.stringify(request) + '\n');
|
|
172
|
-
return id;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Register a callback for messages from an ACP agent.
|
|
177
|
-
* Returns an unsubscribe function.
|
|
178
|
-
*/
|
|
179
|
-
export function onMessage(acpProc: AcpProcess, callback: MessageCallback): () => void {
|
|
180
|
-
const listeners = messageListeners.get(acpProc.id);
|
|
181
|
-
if (!listeners) throw new Error(`ACP process ${acpProc.id} not found`);
|
|
182
|
-
|
|
183
|
-
listeners.add(callback);
|
|
184
|
-
return () => { listeners.delete(callback); };
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Send a JSON-RPC request and wait for a response with the matching ID.
|
|
189
|
-
*/
|
|
190
|
-
export function sendAndWait(
|
|
191
|
-
acpProc: AcpProcess,
|
|
192
|
-
method: string,
|
|
193
|
-
params?: Record<string, unknown>,
|
|
194
|
-
timeoutMs = 30_000,
|
|
195
|
-
): Promise<AcpJsonRpcResponse> {
|
|
196
|
-
return new Promise((resolve, reject) => {
|
|
197
|
-
// Fail fast if process is already dead (e.g. binary not found).
|
|
198
|
-
if (!acpProc.alive) {
|
|
199
|
-
const reason = acpProc.spawnError || 'Process is not alive';
|
|
200
|
-
reject(new Error(
|
|
201
|
-
`Agent "${acpProc.agentId}" is not running: ${reason}. ` +
|
|
202
|
-
`Please check that the agent is installed and available on your PATH.`,
|
|
203
|
-
));
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
let rpcId: string;
|
|
208
|
-
try {
|
|
209
|
-
rpcId = sendMessage(acpProc, method, params);
|
|
210
|
-
} catch (err) {
|
|
211
|
-
reject(err);
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const cleanup = () => {
|
|
216
|
-
clearTimeout(timer);
|
|
217
|
-
unsub();
|
|
218
|
-
acpProc.proc.removeListener('close', onClose);
|
|
219
|
-
acpProc.proc.removeListener('error', onError);
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
const timer = setTimeout(() => {
|
|
223
|
-
cleanup();
|
|
224
|
-
reject(new Error(`ACP RPC timeout after ${timeoutMs}ms for method: ${method}`));
|
|
225
|
-
}, timeoutMs);
|
|
226
|
-
|
|
227
|
-
const unsub = onMessage(acpProc, (msg) => {
|
|
228
|
-
if (String(msg.id) === rpcId) {
|
|
229
|
-
cleanup();
|
|
230
|
-
resolve(msg);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
// Reject immediately if the process dies while we're waiting.
|
|
235
|
-
const onClose = (code: number | null) => {
|
|
236
|
-
cleanup();
|
|
237
|
-
const reason = acpProc.spawnError || `Process exited with code ${code}`;
|
|
238
|
-
reject(new Error(
|
|
239
|
-
`Agent "${acpProc.agentId}" exited unexpectedly: ${reason}. ` +
|
|
240
|
-
`Please check that the agent is installed and available on your PATH.`,
|
|
241
|
-
));
|
|
242
|
-
};
|
|
243
|
-
const onError = (err: Error) => {
|
|
244
|
-
cleanup();
|
|
245
|
-
reject(new Error(
|
|
246
|
-
`Agent "${acpProc.agentId}" failed to start: ${err.message}. ` +
|
|
247
|
-
`Please check that the agent is installed and available on your PATH.`,
|
|
248
|
-
));
|
|
249
|
-
};
|
|
250
|
-
acpProc.proc.once('close', onClose);
|
|
251
|
-
acpProc.proc.once('error', onError);
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
|
|
255
155
|
/**
|
|
256
156
|
* Kill an ACP agent process and its entire process tree.
|
|
257
|
-
* Uses negative PID to send signal to the process group (requires detached spawn).
|
|
258
157
|
*/
|
|
259
158
|
export function killAgent(acpProc: AcpProcess): void {
|
|
260
159
|
const pid = acpProc.proc.pid;
|
|
261
160
|
if (pid) {
|
|
262
|
-
// Kill the entire process group via negative PID
|
|
263
161
|
try { process.kill(-pid, 'SIGTERM'); } catch { /* already dead */ }
|
|
264
|
-
|
|
265
|
-
// Force SIGKILL after 3s — use signal 0 probe instead of `alive` flag
|
|
266
|
-
// because `alive` is set to false below before the timeout fires.
|
|
267
162
|
setTimeout(() => {
|
|
268
163
|
try {
|
|
269
|
-
process.kill(-pid, 0);
|
|
164
|
+
process.kill(-pid, 0);
|
|
270
165
|
process.kill(-pid, 'SIGKILL');
|
|
271
|
-
} catch { /* already dead
|
|
166
|
+
} catch { /* already dead */ }
|
|
272
167
|
}, 3000);
|
|
273
168
|
}
|
|
274
169
|
acpProc.alive = false;
|
|
275
170
|
processes.delete(acpProc.id);
|
|
276
|
-
messageListeners.delete(acpProc.id);
|
|
277
|
-
requestListeners.delete(acpProc.id);
|
|
278
|
-
notificationListeners.delete(acpProc.id);
|
|
279
|
-
// Clean up any terminals spawned by this process
|
|
280
171
|
const terms = terminalMaps.get(acpProc.id);
|
|
281
172
|
if (terms) {
|
|
282
173
|
for (const entry of terms.values()) {
|
|
@@ -286,269 +177,215 @@ export function killAgent(acpProc: AcpProcess): void {
|
|
|
286
177
|
}
|
|
287
178
|
}
|
|
288
179
|
|
|
289
|
-
/**
|
|
290
|
-
* Get a process by its ID.
|
|
291
|
-
*/
|
|
292
180
|
export function getProcess(id: string): AcpProcess | undefined {
|
|
293
181
|
return processes.get(id);
|
|
294
182
|
}
|
|
295
183
|
|
|
296
|
-
/**
|
|
297
|
-
* Get all active processes.
|
|
298
|
-
*/
|
|
299
184
|
export function getActiveProcesses(): AcpProcess[] {
|
|
300
185
|
return [...processes.values()].filter(p => p.alive);
|
|
301
186
|
}
|
|
302
187
|
|
|
303
|
-
/**
|
|
304
|
-
* Kill all active ACP processes. Used for cleanup.
|
|
305
|
-
*/
|
|
306
188
|
export function killAllAgents(): void {
|
|
307
189
|
for (const proc of processes.values()) {
|
|
308
190
|
killAgent(proc);
|
|
309
191
|
}
|
|
310
192
|
}
|
|
311
193
|
|
|
312
|
-
|
|
313
|
-
|
|
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
|
-
): void {
|
|
347
|
-
if (!acpProc.alive || !acpProc.proc.stdin?.writable) {
|
|
348
|
-
throw new Error(`ACP process ${acpProc.id} is not alive`);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
const response: AcpJsonRpcResponse = {
|
|
352
|
-
jsonrpc: '2.0',
|
|
353
|
-
id,
|
|
354
|
-
result,
|
|
355
|
-
};
|
|
356
|
-
acpProc.proc.stdin.write(JSON.stringify(response) + '\n');
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Install auto-approval for all incoming permission/capability requests.
|
|
361
|
-
* Agents in ACP mode send requests like fs/read, fs/write, terminal/execute etc.
|
|
362
|
-
* Without approval, the agent hangs waiting for TTY input that never comes.
|
|
363
|
-
* Returns an unsubscribe function.
|
|
364
|
-
*/
|
|
365
|
-
export function installAutoApproval(acpProc: AcpProcess): () => void {
|
|
366
|
-
return onRequest(acpProc, (req) => {
|
|
367
|
-
const method = req.method;
|
|
368
|
-
const params = (req.params ?? {}) as Record<string, unknown>;
|
|
369
|
-
|
|
370
|
-
switch (method) {
|
|
371
|
-
// ── File system: read ──
|
|
372
|
-
case 'fs/read_text_file': {
|
|
373
|
-
const filePath = String(params.path ?? '');
|
|
374
|
-
if (!filePath) {
|
|
375
|
-
sendResponse(acpProc, req.id, { error: { code: -32602, message: 'path is required' } });
|
|
376
|
-
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');
|
|
377
228
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
if (line !== undefined || limit !== undefined) {
|
|
384
|
-
const lines = content.split('\n');
|
|
385
|
-
const start = (line ?? 1) - 1; // 1-based to 0-based
|
|
386
|
-
const end = limit !== undefined ? start + limit : lines.length;
|
|
387
|
-
content = lines.slice(Math.max(0, start), end).join('\n');
|
|
388
|
-
}
|
|
389
|
-
sendResponse(acpProc, req.id, { content });
|
|
390
|
-
} catch (err) {
|
|
391
|
-
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}`);
|
|
392
234
|
}
|
|
393
|
-
|
|
235
|
+
throw new RequestError(-32603, `Failed to read ${params.path}: ${err?.message ?? err}`);
|
|
394
236
|
}
|
|
237
|
+
},
|
|
395
238
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
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}`);
|
|
403
252
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const path = require('path');
|
|
407
|
-
const dir = path.dirname(filePath);
|
|
408
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
409
|
-
fs.writeFileSync(filePath, content, 'utf-8');
|
|
410
|
-
sendResponse(acpProc, req.id, {});
|
|
411
|
-
} catch (err) {
|
|
412
|
-
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}`);
|
|
413
255
|
}
|
|
414
|
-
|
|
256
|
+
throw RequestError.internalError(undefined, err?.message ?? String(err));
|
|
415
257
|
}
|
|
258
|
+
},
|
|
416
259
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
const command = String(params.command ?? '');
|
|
420
|
-
const args = Array.isArray(params.args) ? params.args.map(String) : [];
|
|
421
|
-
const cwd = typeof params.cwd === 'string' ? params.cwd : undefined;
|
|
422
|
-
const env = (params.env && typeof params.env === 'object') ? params.env as Record<string, string> : undefined;
|
|
423
|
-
const outputByteLimit = typeof params.outputByteLimit === 'number' ? params.outputByteLimit : 1_000_000;
|
|
424
|
-
|
|
425
|
-
if (!command) {
|
|
426
|
-
sendResponse(acpProc, req.id, { error: { code: -32602, message: 'command is required' } });
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
260
|
+
async createTerminal(params: CreateTerminalRequest): Promise<CreateTerminalResponse> {
|
|
261
|
+
if (!params.command) throw RequestError.invalidParams(undefined, 'command is required');
|
|
429
262
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
cwd,
|
|
435
|
-
env: { ...process.env, ...(env ?? {}) },
|
|
436
|
-
shell: true,
|
|
437
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
let output = '';
|
|
441
|
-
let truncated = false;
|
|
442
|
-
|
|
443
|
-
child.stdout?.on('data', (chunk: Buffer) => {
|
|
444
|
-
if (output.length < outputByteLimit) {
|
|
445
|
-
output += chunk.toString();
|
|
446
|
-
if (output.length > outputByteLimit) {
|
|
447
|
-
output = output.slice(0, outputByteLimit);
|
|
448
|
-
truncated = true;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
});
|
|
452
|
-
child.stderr?.on('data', (chunk: Buffer) => {
|
|
453
|
-
if (output.length < outputByteLimit) {
|
|
454
|
-
output += chunk.toString();
|
|
455
|
-
if (output.length > outputByteLimit) {
|
|
456
|
-
output = output.slice(0, outputByteLimit);
|
|
457
|
-
truncated = true;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
// Store terminal in process-scoped map
|
|
463
|
-
const terminalMap = getOrCreateTerminalMap(acpProc.id);
|
|
464
|
-
terminalMap.set(terminalId, { child, output: () => output, truncated: () => truncated });
|
|
465
|
-
|
|
466
|
-
sendResponse(acpProc, req.id, { terminalId });
|
|
467
|
-
} catch (err) {
|
|
468
|
-
sendResponse(acpProc, req.id, { error: { code: -32603, message: (err as Error).message } });
|
|
469
|
-
}
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
263
|
+
const requestedCwd = params.cwd ?? undefined;
|
|
264
|
+
const terminalCwd = requestedCwd && isWithinAllowedWritePaths(requestedCwd, cwd)
|
|
265
|
+
? requestedCwd
|
|
266
|
+
: cwd;
|
|
472
267
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const
|
|
476
|
-
const terminal = getTerminal(acpProc.id, terminalId);
|
|
477
|
-
if (!terminal) {
|
|
478
|
-
sendResponse(acpProc, req.id, { error: { code: -32002, message: `Terminal not found: ${terminalId}` } });
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
const exitStatus = terminal.child.exitCode !== null ? { exitCode: terminal.child.exitCode } : undefined;
|
|
482
|
-
sendResponse(acpProc, req.id, { output: terminal.output(), truncated: terminal.truncated(), exitStatus });
|
|
483
|
-
return;
|
|
268
|
+
const envObj: Record<string, string> = {};
|
|
269
|
+
if (params.env) {
|
|
270
|
+
for (const v of params.env) envObj[v.name] = v.value;
|
|
484
271
|
}
|
|
485
272
|
|
|
486
|
-
|
|
487
|
-
case 'terminal/kill': {
|
|
488
|
-
const terminalId = String(params.terminalId ?? '');
|
|
489
|
-
const terminal = getTerminal(acpProc.id, terminalId);
|
|
490
|
-
if (!terminal) {
|
|
491
|
-
sendResponse(acpProc, req.id, { error: { code: -32002, message: `Terminal not found: ${terminalId}` } });
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
|
-
terminal.child.kill('SIGTERM');
|
|
495
|
-
sendResponse(acpProc, req.id, {});
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
273
|
+
console.log(`[ACP] terminal/create: agent=${proc.agentId} cmd="${params.command} ${(params.args ?? []).join(' ')}" cwd=${terminalCwd}`);
|
|
498
274
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
sendResponse(acpProc, req.id, { exitCode: terminal.child.exitCode, signal: terminal.child.signalCode });
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
terminal.child.on('exit', (code: number | null, signal: string | null) => {
|
|
512
|
-
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'],
|
|
513
284
|
});
|
|
514
|
-
return;
|
|
515
|
-
}
|
|
516
285
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
if (
|
|
522
|
-
|
|
523
|
-
|
|
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;
|
|
524
294
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
295
|
+
};
|
|
296
|
+
child.stdout?.on('data', collect);
|
|
297
|
+
child.stderr?.on('data', collect);
|
|
530
298
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
// Auto-approve in production; log in dev for debugging
|
|
534
|
-
if (process.env.NODE_ENV === 'development') console.log(`[ACP] Auto-approving permission: ${JSON.stringify(params.toolCall ?? {}).slice(0, 200)}`);
|
|
535
|
-
sendResponse(acpProc, req.id, { outcome: { selected: { optionId: 'allow_once' } } });
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
299
|
+
const terminalMap = getOrCreateTerminalMap(proc.id);
|
|
300
|
+
terminalMap.set(terminalId, { child, output: () => output, truncated: () => truncated });
|
|
538
301
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
sendResponse(acpProc, req.id, {});
|
|
302
|
+
return { terminalId };
|
|
303
|
+
} catch (err) {
|
|
304
|
+
throw RequestError.internalError(undefined, (err as Error).message);
|
|
543
305
|
}
|
|
544
|
-
}
|
|
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
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/* ── Path safety ───────────────────────────────────────────────────────── */
|
|
362
|
+
|
|
363
|
+
const SENSITIVE_PATH_PATTERNS = [
|
|
364
|
+
/[/\\]\.ssh[/\\](id_|config$|authorized_keys|known_hosts)/i,
|
|
365
|
+
/[/\\]\.env(\.[^/\\]*)?$/i,
|
|
366
|
+
/[/\\]credentials\.json$/i,
|
|
367
|
+
/[/\\]\.aws[/\\]credentials$/i,
|
|
368
|
+
/[/\\]\.gnupg[/\\]/i,
|
|
369
|
+
];
|
|
370
|
+
|
|
371
|
+
function isSensitivePath(filePath: string): boolean {
|
|
372
|
+
const normalized = path.resolve(filePath);
|
|
373
|
+
return SENSITIVE_PATH_PATTERNS.some(p => p.test(normalized));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function isWithinAllowedWritePaths(filePath: string, cwd: string): boolean {
|
|
377
|
+
const normalized = path.resolve(filePath);
|
|
378
|
+
const allowedRoots = [cwd, os.tmpdir()];
|
|
379
|
+
return allowedRoots.some(root => {
|
|
380
|
+
const normalizedRoot = path.resolve(root);
|
|
381
|
+
return normalized === normalizedRoot || normalized.startsWith(normalizedRoot + path.sep);
|
|
545
382
|
});
|
|
546
383
|
}
|
|
547
384
|
|
|
548
385
|
/* ── Terminal management (per ACP process) ─────────────────────────────── */
|
|
549
386
|
|
|
550
387
|
interface TerminalEntry {
|
|
551
|
-
child:
|
|
388
|
+
child: ChildProcess;
|
|
552
389
|
output: () => string;
|
|
553
390
|
truncated: () => boolean;
|
|
554
391
|
}
|
|
@@ -571,5 +408,3 @@ function getTerminal(procId: string, terminalId: string): TerminalEntry | undefi
|
|
|
571
408
|
function removeTerminal(procId: string, terminalId: string): void {
|
|
572
409
|
terminalMaps.get(procId)?.delete(terminalId);
|
|
573
410
|
}
|
|
574
|
-
|
|
575
|
-
/* ── Internal — agent command resolution moved to agent-descriptors.ts ─ */
|