@surething/cockpit 1.0.261 → 1.0.263
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/.next-prod/BUILD_ID +1 -1
- package/.next-prod/app-path-routes-manifest.json +6 -3
- package/.next-prod/build-manifest.json +3 -3
- package/.next-prod/cockpit-build.json +2 -2
- package/.next-prod/prerender-manifest.json +4 -4
- package/.next-prod/react-loadable-manifest.json +1 -1
- package/.next-prod/routes-manifest.json +18 -0
- package/.next-prod/server/app/_global-error/page.js +2 -2
- package/.next-prod/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/_global-error.html +1 -1
- package/.next-prod/server/app/_global-error.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next-prod/server/app/_not-found/page.js +1 -1
- package/.next-prod/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/_not-found.html +2 -2
- package/.next-prod/server/app/_not-found.rsc +4 -4
- package/.next-prod/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/.next-prod/server/app/_not-found.segments/_index.segment.rsc +12 -11
- package/.next-prod/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next-prod/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next-prod/server/app/api/agent/test/route.js +1 -1
- package/.next-prod/server/app/api/bash/route.js +1 -1
- package/.next-prod/server/app/api/chat/codex/route.js +1 -1
- package/.next-prod/server/app/api/chat/deepseek/route.js +1 -1
- package/.next-prod/server/app/api/chat/glm/route.js +1 -1
- package/.next-prod/server/app/api/chat/kimi/route.js +1 -1
- package/.next-prod/server/app/api/chat/ollama/route.js +1 -1
- package/.next-prod/server/app/api/chat/route.js +1 -1
- package/.next-prod/server/app/api/chat/stop/route.js +1 -1
- package/.next-prod/server/app/api/claude-stats/route.js +1 -1
- package/.next-prod/server/app/api/commands/route.js +1 -1
- package/.next-prod/server/app/api/comments/route.js +1 -1
- package/.next-prod/server/app/api/db/columns/route.js +1 -1
- package/.next-prod/server/app/api/db/connect/route.js +1 -1
- package/.next-prod/server/app/api/db/disconnect/route.js +1 -1
- package/.next-prod/server/app/api/db/export/route.js +1 -1
- package/.next-prod/server/app/api/db/query/route.js +1 -1
- package/.next-prod/server/app/api/db/schemas/route.js +2 -2
- package/.next-prod/server/app/api/deepseek/balance/route.js +1 -1
- package/.next-prod/server/app/api/deepseek/credentials/route.js +1 -1
- package/.next-prod/server/app/api/deepseek/models/route.js +1 -1
- package/.next-prod/server/app/api/dev/spans/route.js +1 -1
- package/.next-prod/server/app/api/extension/version/route.js +1 -1
- package/.next-prod/server/app/api/file/route.js +1 -1
- package/.next-prod/server/app/api/files/blame/route.js +1 -1
- package/.next-prod/server/app/api/files/clipboard/route.js +1 -1
- package/.next-prod/server/app/api/files/copy/route.js +1 -1
- package/.next-prod/server/app/api/files/delete/route.js +1 -1
- package/.next-prod/server/app/api/files/expanded/route.js +1 -1
- package/.next-prod/server/app/api/files/index/route.js +1 -1
- package/.next-prod/server/app/api/files/init/route.js +1 -1
- package/.next-prod/server/app/api/files/paste/route.js +1 -1
- package/.next-prod/server/app/api/files/read/route.js +1 -1
- package/.next-prod/server/app/api/files/readdir/route.js +1 -1
- package/.next-prod/server/app/api/files/recent/route.js +1 -1
- package/.next-prod/server/app/api/files/save/route.js +1 -1
- package/.next-prod/server/app/api/files/search/route.js +1 -1
- package/.next-prod/server/app/api/files/stat/route.js +1 -1
- package/.next-prod/server/app/api/files/text/route.js +1 -1
- package/.next-prod/server/app/api/git/branch-diff/route.js +1 -1
- package/.next-prod/server/app/api/git/branches/route.js +1 -1
- package/.next-prod/server/app/api/git/commit-diff/route.js +1 -1
- package/.next-prod/server/app/api/git/commits/route.js +1 -1
- package/.next-prod/server/app/api/git/current-branch/route.js +1 -1
- package/.next-prod/server/app/api/git/diff/route.js +1 -1
- package/.next-prod/server/app/api/git/discard/route.js +1 -1
- package/.next-prod/server/app/api/git/stage/route.js +1 -1
- package/.next-prod/server/app/api/git/status/route.js +1 -1
- package/.next-prod/server/app/api/git/unstage/route.js +1 -1
- package/.next-prod/server/app/api/git/worktree/route.js +1 -1
- package/.next-prod/server/app/api/glm/credentials/route.js +1 -1
- package/.next-prod/server/app/api/glm/models/route.js +1 -1
- package/.next-prod/server/app/api/glm/usage/route.js +1 -1
- package/.next-prod/server/app/api/global-state/route.js +1 -1
- package/.next-prod/server/app/api/health/route.js +1 -1
- package/.next-prod/server/app/api/html-apps/[id]/route.js +1 -1
- package/.next-prod/server/app/api/html-apps/route.js +1 -1
- package/.next-prod/server/app/api/jupyter/load/route.js +1 -1
- package/.next-prod/server/app/api/jupyter/save/route.js +1 -1
- package/.next-prod/server/app/api/jupyter/shutdown/route.js +1 -1
- package/.next-prod/server/app/api/kimi/credentials/route.js +1 -1
- package/.next-prod/server/app/api/kimi/models/route.js +1 -1
- package/.next-prod/server/app/api/kimi/usage/route.js +1 -1
- package/.next-prod/server/app/api/lsp/definition/route.js +1 -1
- package/.next-prod/server/app/api/lsp/hover/route.js +1 -1
- package/.next-prod/server/app/api/lsp/references/route.js +1 -1
- package/.next-prod/server/app/api/lsp/status/route.js +1 -1
- package/.next-prod/server/app/api/lsp/warmup/route.js +1 -1
- package/.next-prod/server/app/api/mysql/columns/route.js +2 -2
- package/.next-prod/server/app/api/mysql/connect/route.js +1 -1
- package/.next-prod/server/app/api/mysql/disconnect/route.js +1 -1
- package/.next-prod/server/app/api/mysql/export/route.js +1 -1
- package/.next-prod/server/app/api/mysql/query/route.js +1 -1
- package/.next-prod/server/app/api/mysql/schemas/route.js +1 -1
- package/.next-prod/server/app/api/neo4j/connect/route.js +1 -1
- package/.next-prod/server/app/api/neo4j/disconnect/route.js +1 -1
- package/.next-prod/server/app/api/neo4j/query/route.js +1 -1
- package/.next-prod/server/app/api/neo4j/schema/route.js +1 -1
- package/.next-prod/server/app/api/note/route.js +1 -1
- package/.next-prod/server/app/api/ollama/config/route.js +1 -1
- package/.next-prod/server/app/api/ollama/models/route.js +1 -1
- package/.next-prod/server/app/api/ollama/start/route.js +1 -1
- package/.next-prod/server/app/api/open-cursor/route.js +1 -1
- package/.next-prod/server/app/api/open-vscode/route.js +1 -1
- package/.next-prod/server/app/api/pick-folder/route.js +1 -1
- package/.next-prod/server/app/api/pinned-sessions/route.js +1 -1
- package/.next-prod/server/app/api/project-settings/route.js +1 -1
- package/.next-prod/server/app/api/project-state/route.js +2 -2
- package/.next-prod/server/app/api/projectGraph/affected/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/callees/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/callers/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/coedit/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/context/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/file/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/file-functions/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/impact/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/related/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/risk/route.js +1 -1
- package/.next-prod/server/app/api/projectGraph/search/route.js +1 -1
- package/.next-prod/server/app/api/projects/route.js +1 -1
- package/.next-prod/server/app/api/prompts/config/route.js +1 -1
- package/.next-prod/server/app/api/push/public-key/route.js +1 -1
- package/.next-prod/server/app/api/push/subscribe/route.js +1 -1
- package/.next-prod/server/app/api/push/unsubscribe/route.js +1 -1
- package/.next-prod/server/app/api/redis/command/route.js +1 -1
- package/.next-prod/server/app/api/redis/connect/route.js +1 -1
- package/.next-prod/server/app/api/redis/delete/route.js +1 -1
- package/.next-prod/server/app/api/redis/disconnect/route.js +1 -1
- package/.next-prod/server/app/api/redis/get/route.js +1 -1
- package/.next-prod/server/app/api/redis/keys/route.js +1 -1
- package/.next-prod/server/app/api/redis/set/route.js +1 -1
- package/.next-prod/server/app/api/restart/route.js +1 -0
- package/.next-prod/server/app/api/restart/route.js.nft.json +1 -0
- package/.next-prod/server/app/api/restart/route_client-reference-manifest.js +1 -0
- package/.next-prod/server/app/api/review/[id]/comments/route.js +1 -1
- package/.next-prod/server/app/api/review/[id]/replies/route.js +1 -1
- package/.next-prod/server/app/api/review/[id]/route.js +1 -1
- package/.next-prod/server/app/api/review/identify/route.js +1 -1
- package/.next-prod/server/app/api/review/order/route.js +1 -1
- package/.next-prod/server/app/api/review/route.js +1 -1
- package/.next-prod/server/app/api/review/share-info/route.js +1 -1
- package/.next-prod/server/app/api/review/users/route.js +1 -1
- package/.next-prod/server/app/api/scheduled-tasks/route.js +2 -2
- package/.next-prod/server/app/api/services/config/route.js +1 -1
- package/.next-prod/server/app/api/services/scripts/route.js +1 -1
- package/.next-prod/server/app/api/session/[sessionId]/fork/route.js +1 -1
- package/.next-prod/server/app/api/session/[sessionId]/history/route.js +1 -1
- package/.next-prod/server/app/api/session-by-path/route.js +1 -1
- package/.next-prod/server/app/api/sessions/projects/[encodedPath]/route.js +1 -1
- package/.next-prod/server/app/api/sessions/projects/route.js +1 -1
- package/.next-prod/server/app/api/sessions/route.js +1 -1
- package/.next-prod/server/app/api/settings/route.js +1 -1
- package/.next-prod/server/app/api/shutdown/route.js +1 -0
- package/.next-prod/server/app/api/shutdown/route.js.nft.json +1 -0
- package/.next-prod/server/app/api/shutdown/route_client-reference-manifest.js +1 -0
- package/.next-prod/server/app/api/skills/[id]/route.js +1 -1
- package/.next-prod/server/app/api/skills/content/route.js +1 -1
- package/.next-prod/server/app/api/skills/route.js +1 -1
- package/.next-prod/server/app/api/snapshots/diff/route.js +1 -1
- package/.next-prod/server/app/api/snapshots/route.js +1 -1
- package/.next-prod/server/app/api/terminal/aliases/route.js +1 -1
- package/.next-prod/server/app/api/terminal/autocomplete/route.js +1 -1
- package/.next-prod/server/app/api/terminal/bubble-order/route.js +1 -1
- package/.next-prod/server/app/api/terminal/env/route.js +1 -1
- package/.next-prod/server/app/api/terminal/history/route.js +1 -1
- package/.next-prod/server/app/api/update/route.js +1 -0
- package/.next-prod/server/app/api/update/route.js.nft.json +1 -0
- package/.next-prod/server/app/api/update/route_client-reference-manifest.js +1 -0
- package/.next-prod/server/app/api/version/route.js +1 -1
- package/.next-prod/server/app/apps/[...path]/route.js +1 -1
- package/.next-prod/server/app/favicon.ico/route.js +1 -1
- package/.next-prod/server/app/m/page.js +1 -1
- package/.next-prod/server/app/m/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/manifest.webmanifest/route.js +2 -2
- package/.next-prod/server/app/page.js +1 -1
- package/.next-prod/server/app/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/project/page.js +1 -1
- package/.next-prod/server/app/project/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/review/[id]/page.js +1 -1
- package/.next-prod/server/app/review/[id]/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app-paths-manifest.json +6 -3
- package/.next-prod/server/chunks/1564.js +1 -1
- package/.next-prod/server/chunks/5750.js +42 -40
- package/.next-prod/server/chunks/6495.js +1 -1
- package/.next-prod/server/chunks/6548.js +1 -1
- package/.next-prod/server/chunks/7184.js +1 -1
- package/.next-prod/server/chunks/841.js +1 -1
- package/.next-prod/server/chunks/8764.js +2 -2
- package/.next-prod/server/functions-config-manifest.json +3 -0
- package/.next-prod/server/middleware-build-manifest.js +1 -1
- package/.next-prod/server/middleware-react-loadable-manifest.js +1 -1
- package/.next-prod/server/pages/404.html +2 -2
- package/.next-prod/server/pages/500.html +1 -1
- package/.next-prod/server/server-reference-manifest.json +1 -1
- package/.next-prod/static/Jy5sAJFfhng774VeXYdQS/_buildManifest.js +1 -0
- package/.next-prod/static/chunks/1372-c2e2e52980e95aec.js +15 -0
- package/.next-prod/static/chunks/{1959.a8039e13d14ada11.js → 1959.1d5dbd36400b94d2.js} +4 -4
- package/.next-prod/static/chunks/2032-8326efdf5830d58c.js +1 -0
- package/.next-prod/static/chunks/6722-1252a1399ff10e47.js +35 -0
- package/.next-prod/static/chunks/6784-20cc834d161af395.js +381 -0
- package/.next-prod/static/chunks/app/_global-error/page-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/agent/test/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/bash/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/chat/codex/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/chat/deepseek/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/chat/glm/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/chat/kimi/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/chat/ollama/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/chat/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/chat/stop/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/claude-stats/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/commands/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/comments/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/db/columns/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/db/connect/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/db/disconnect/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/db/export/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/db/query/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/db/schemas/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/deepseek/balance/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/deepseek/credentials/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/deepseek/models/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/dev/spans/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/extension/version/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/file/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/blame/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/clipboard/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/copy/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/delete/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/expanded/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/index/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/init/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/paste/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/read/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/readdir/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/recent/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/save/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/search/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/stat/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/files/text/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/branch-diff/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/branches/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/commit-diff/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/commits/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/current-branch/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/diff/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/discard/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/stage/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/status/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/unstage/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/git/worktree/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/glm/credentials/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/glm/models/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/glm/usage/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/global-state/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/health/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/html-apps/[id]/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/html-apps/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/jupyter/load/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/jupyter/save/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/jupyter/shutdown/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/kimi/credentials/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/kimi/models/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/kimi/usage/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/lsp/definition/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/lsp/hover/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/lsp/references/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/lsp/status/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/lsp/warmup/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/mysql/columns/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/mysql/connect/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/mysql/disconnect/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/mysql/export/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/mysql/query/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/mysql/schemas/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/neo4j/connect/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/neo4j/disconnect/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/neo4j/query/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/neo4j/schema/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/note/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/ollama/config/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/ollama/models/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/ollama/start/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/open-cursor/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/open-vscode/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/pick-folder/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/pinned-sessions/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/project-settings/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/project-state/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/affected/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/callees/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/callers/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/coedit/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/context/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/file/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/file-functions/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/impact/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/related/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/risk/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projectGraph/search/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/projects/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/prompts/config/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/push/public-key/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/push/subscribe/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/push/unsubscribe/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/redis/command/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/redis/connect/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/redis/delete/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/redis/disconnect/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/redis/get/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/redis/keys/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/redis/set/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/restart/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/review/[id]/comments/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/review/[id]/replies/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/review/[id]/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/review/identify/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/review/order/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/review/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/review/share-info/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/review/users/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/scheduled-tasks/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/services/config/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/services/scripts/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/session/[sessionId]/fork/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/session/[sessionId]/history/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/session-by-path/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/sessions/projects/[encodedPath]/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/sessions/projects/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/sessions/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/settings/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/shutdown/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/skills/[id]/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/skills/content/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/skills/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/snapshots/diff/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/snapshots/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/terminal/aliases/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/terminal/autocomplete/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/terminal/bubble-order/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/terminal/env/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/terminal/history/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/update/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/api/version/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/apps/[...path]/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/{layout-ab52fc1a83af968b.js → layout-b11ccf3395201b18.js} +1 -1
- package/.next-prod/static/chunks/app/m/page-d7c162f2db6b377c.js +1 -0
- package/.next-prod/static/chunks/app/manifest.webmanifest/route-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/app/{page-5de8b6584e328a6f.js → page-e03b50ea13cd6198.js} +1 -1
- package/.next-prod/static/chunks/app/project/{page-5de8b6584e328a6f.js → page-e03b50ea13cd6198.js} +1 -1
- package/.next-prod/static/chunks/app/review/[id]/page-556db82704d074ab.js +1 -0
- package/.next-prod/static/chunks/next/dist/client/components/builtin/app-error-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/next/dist/client/components/builtin/forbidden-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/next/dist/client/components/builtin/not-found-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/next/dist/client/components/builtin/unauthorized-7c7e4c414aa6453c.js +1 -0
- package/.next-prod/static/chunks/{webpack-ce60587570394496.js → webpack-e959a5364a05b2ac.js} +1 -1
- package/.next-prod/static/css/237348b31ba05918.css +1 -0
- package/.next-prod/trace +14 -14
- package/.next-prod/trace-build +1 -1
- package/.next-prod/types/app/api/restart/route.ts +353 -0
- package/.next-prod/types/app/api/shutdown/route.ts +353 -0
- package/.next-prod/types/app/api/update/route.ts +353 -0
- package/.next-prod/types/routes.d.ts +4 -1
- package/.next-prod/types/validator.ts +27 -0
- package/README.md +75 -0
- package/README.zh.md +64 -0
- package/bin/cock-service.mjs +498 -0
- package/bin/cock.mjs +35 -27
- package/bin/cockpitHome.mjs +33 -0
- package/bin/rotateLog.mjs +52 -0
- package/bin/updater.mjs +231 -0
- package/dist/{chunk-B5LXMESP.mjs → chunk-FBAFMLUC.mjs} +1 -1
- package/dist/{chunk-CLPJYIFC.mjs → chunk-H6AI4XJC.mjs} +4 -3
- package/dist/{chunk-TU3GL2HK.mjs → chunk-ZE2JXL6E.mjs} +18 -7
- package/dist/httpApi.mjs +2 -2
- package/dist/scheduledTasks.mjs +24 -4
- package/dist/{server-2UJDVZ32.mjs → server-HRP33LCV.mjs} +2 -2
- package/dist/wsServer.mjs +144 -112
- package/package.json +1 -1
- package/public/html-lib/json-viewer.js +9 -9
- package/public/html-lib/markdown.css +0 -7
- package/public/html-lib/markdown.js +1 -1
- package/public/html-lib/pdf-viewer.css +0 -11
- package/public/html-lib/pdf-viewer.js +1 -1
- package/public/html-lib/theme.css +95 -11
- package/server.mjs +127 -11
- package/.next-prod/static/chunks/1157-164bcf046a0a9b15.js +0 -32
- package/.next-prod/static/chunks/1372-d16d68b1b03a345a.js +0 -15
- package/.next-prod/static/chunks/2032-f224a93f7a22bc21.js +0 -1
- package/.next-prod/static/chunks/6784-09dffdb0e8ca7fb3.js +0 -381
- package/.next-prod/static/chunks/app/_global-error/page-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/agent/test/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/bash/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/chat/codex/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/chat/deepseek/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/chat/glm/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/chat/kimi/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/chat/ollama/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/chat/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/chat/stop/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/claude-stats/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/commands/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/comments/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/db/columns/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/db/connect/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/db/disconnect/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/db/export/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/db/query/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/db/schemas/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/deepseek/balance/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/deepseek/credentials/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/deepseek/models/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/dev/spans/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/extension/version/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/file/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/blame/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/clipboard/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/copy/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/delete/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/expanded/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/index/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/init/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/paste/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/read/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/readdir/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/recent/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/save/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/search/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/stat/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/files/text/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/branch-diff/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/branches/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/commit-diff/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/commits/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/current-branch/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/diff/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/discard/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/stage/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/status/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/unstage/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/git/worktree/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/glm/credentials/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/glm/models/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/glm/usage/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/global-state/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/health/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/html-apps/[id]/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/html-apps/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/jupyter/load/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/jupyter/save/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/jupyter/shutdown/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/kimi/credentials/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/kimi/models/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/kimi/usage/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/lsp/definition/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/lsp/hover/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/lsp/references/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/lsp/status/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/lsp/warmup/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/mysql/columns/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/mysql/connect/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/mysql/disconnect/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/mysql/export/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/mysql/query/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/mysql/schemas/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/neo4j/connect/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/neo4j/disconnect/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/neo4j/query/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/neo4j/schema/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/note/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/ollama/config/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/ollama/models/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/ollama/start/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/open-cursor/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/open-vscode/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/pick-folder/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/pinned-sessions/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/project-settings/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/project-state/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/affected/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/callees/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/callers/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/coedit/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/context/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/file/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/file-functions/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/impact/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/related/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/risk/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projectGraph/search/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/projects/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/prompts/config/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/push/public-key/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/push/subscribe/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/push/unsubscribe/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/redis/command/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/redis/connect/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/redis/delete/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/redis/disconnect/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/redis/get/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/redis/keys/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/redis/set/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/review/[id]/comments/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/review/[id]/replies/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/review/[id]/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/review/identify/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/review/order/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/review/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/review/share-info/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/review/users/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/scheduled-tasks/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/services/config/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/services/scripts/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/session/[sessionId]/fork/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/session/[sessionId]/history/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/session-by-path/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/sessions/projects/[encodedPath]/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/sessions/projects/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/sessions/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/settings/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/skills/[id]/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/skills/content/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/skills/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/snapshots/diff/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/snapshots/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/terminal/aliases/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/terminal/autocomplete/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/terminal/bubble-order/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/terminal/env/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/terminal/history/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/api/version/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/apps/[...path]/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/m/page-7dcf56a65528216f.js +0 -1
- package/.next-prod/static/chunks/app/manifest.webmanifest/route-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/app/review/[id]/page-c0136423507b7547.js +0 -1
- package/.next-prod/static/chunks/next/dist/client/components/builtin/app-error-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/next/dist/client/components/builtin/forbidden-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/next/dist/client/components/builtin/not-found-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/chunks/next/dist/client/components/builtin/unauthorized-3c1c06e2de280418.js +0 -1
- package/.next-prod/static/css/83c134c954630942.css +0 -1
- package/.next-prod/static/pgteRwI6FQcp683smeSNO/_buildManifest.js +0 -1
- /package/.next-prod/static/{pgteRwI6FQcp683smeSNO → Jy5sAJFfhng774VeXYdQS}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
// cockpit start | stop | restart | status
|
|
2
|
+
//
|
|
3
|
+
// Background ("bare") process management, with no supervisor involved: the
|
|
4
|
+
// server is spawned detached, its pid/port live in server.json, and stopping
|
|
5
|
+
// goes through POST /api/shutdown so the process leaves via its own exit hook
|
|
6
|
+
// (which flushes PTY scrollback). Signals are only the fallback — see the note
|
|
7
|
+
// on stopProcess() for why they cannot be the primary mechanism.
|
|
8
|
+
//
|
|
9
|
+
// Deliberately no daemon-manager integration yet: launchd/systemd/service
|
|
10
|
+
// registration is a separate step, and this layer has to work on its own for
|
|
11
|
+
// the environments those do not cover (WSL1, containers, Linux without
|
|
12
|
+
// systemd).
|
|
13
|
+
import { spawnSync, spawn } from 'child_process';
|
|
14
|
+
import { existsSync, mkdirSync, openSync, readFileSync } from 'fs';
|
|
15
|
+
import { dirname, join, resolve } from 'path';
|
|
16
|
+
import { fileURLToPath } from 'url';
|
|
17
|
+
import { SERVER_JSON_PATH, LOG_DIR, SERVER_LOG_PATH, COCKPIT_HOME_DIR } from './cockpitHome.mjs';
|
|
18
|
+
import { rotateIfLarge } from './rotateLog.mjs';
|
|
19
|
+
import { hasClaudeBinary } from '../scripts/claudeBinary.mjs';
|
|
20
|
+
|
|
21
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
22
|
+
const PROJECT_ROOT = resolve(__dirname, '..');
|
|
23
|
+
|
|
24
|
+
const isWindows = process.platform === 'win32';
|
|
25
|
+
const START_TIMEOUT_MS = 30_000;
|
|
26
|
+
const STOP_TIMEOUT_MS = 10_000;
|
|
27
|
+
const POLL_INTERVAL_MS = 250;
|
|
28
|
+
|
|
29
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
30
|
+
|
|
31
|
+
// ─────────────────────────────────────────────────────────
|
|
32
|
+
// State
|
|
33
|
+
// ─────────────────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
function readRecord() {
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(readFileSync(SERVER_JSON_PATH, 'utf8'));
|
|
38
|
+
} catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function defaultPort() {
|
|
44
|
+
return Number(process.env.PORT || process.env.COCKPIT_PORT || 3457);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Ask the instance on `port` to identify itself.
|
|
49
|
+
*
|
|
50
|
+
* Returns the /api/health body only when it is a cockpit serving THIS data dir.
|
|
51
|
+
* Anything else — connection refused, a timeout, or some unrelated service that
|
|
52
|
+
* happens to hold the port — reads as "not running", matching the
|
|
53
|
+
* single-instance guard in server.mjs.
|
|
54
|
+
*/
|
|
55
|
+
async function probe(port, timeoutMs = 1000) {
|
|
56
|
+
try {
|
|
57
|
+
const res = await fetch(`http://127.0.0.1:${port}/api/health`, {
|
|
58
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
59
|
+
});
|
|
60
|
+
if (!res.ok) return null;
|
|
61
|
+
const body = await res.json();
|
|
62
|
+
if (body?.app !== 'cockpit') return null;
|
|
63
|
+
return body;
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** The live instance for this data dir, or null. */
|
|
70
|
+
async function findRunning() {
|
|
71
|
+
const rec = readRecord();
|
|
72
|
+
const port = rec?.port || defaultPort();
|
|
73
|
+
const health = await probe(port);
|
|
74
|
+
if (!health) return null;
|
|
75
|
+
// The probe wins on liveness facts, but must not blank out fields it may
|
|
76
|
+
// legitimately report as null (an older server predating COCKPIT_VERSION);
|
|
77
|
+
// server.json is the fallback for those.
|
|
78
|
+
return {
|
|
79
|
+
...rec,
|
|
80
|
+
...health,
|
|
81
|
+
port,
|
|
82
|
+
version: health.version || rec?.version || null,
|
|
83
|
+
buildId: health.buildId || rec?.buildId || null,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function pidAlive(pid) {
|
|
88
|
+
if (!pid) return false;
|
|
89
|
+
try {
|
|
90
|
+
process.kill(pid, 0);
|
|
91
|
+
return true;
|
|
92
|
+
} catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ─────────────────────────────────────────────────────────
|
|
98
|
+
// start
|
|
99
|
+
// ─────────────────────────────────────────────────────────
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Start in the background.
|
|
103
|
+
*
|
|
104
|
+
* Takes no project path. A backgrounded server never opens a browser, so there
|
|
105
|
+
* is no "open this project" action for a path to attach to — it would only
|
|
106
|
+
* decorate a printed URL, while implying the server is bound to one project
|
|
107
|
+
* (it is not; cockpit serves them all). Use `cockpit <path>` for the
|
|
108
|
+
* foreground/open-a-project flow, or pick the project in the UI.
|
|
109
|
+
*/
|
|
110
|
+
export async function start({ quiet = false } = {}) {
|
|
111
|
+
const existing = await findRunning();
|
|
112
|
+
if (existing) {
|
|
113
|
+
console.log(`Cockpit is already running → http://localhost:${existing.port}`);
|
|
114
|
+
// Name the data dir. "Already running" is confusing when the user believed
|
|
115
|
+
// they were starting an isolated instance — a mistyped COCKPIT_HOME silently
|
|
116
|
+
// falls back to ~/.cockpit and lands on the everyday server instead.
|
|
117
|
+
console.log(` data dir: ${COCKPIT_HOME_DIR}`);
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!existsSync(resolve(PROJECT_ROOT, '.next-prod', 'BUILD_ID'))) {
|
|
122
|
+
console.error('No production build found.\n');
|
|
123
|
+
console.error('Run: npm run build');
|
|
124
|
+
return 1;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
mkdirSync(LOG_DIR, { recursive: true });
|
|
128
|
+
// Rotate before opening: once the fd is held, renaming the file underneath it
|
|
129
|
+
// would silently keep writing to the old inode.
|
|
130
|
+
rotateIfLarge(SERVER_LOG_PATH);
|
|
131
|
+
// Append, never truncate: a previous run's tail is often the only record of
|
|
132
|
+
// why it died.
|
|
133
|
+
const logFd = openSync(SERVER_LOG_PATH, 'a');
|
|
134
|
+
|
|
135
|
+
// COCKPIT_OPEN_PROJECT is deliberately NOT set: server.mjs only reads it to
|
|
136
|
+
// build the URL it auto-opens, and that is suppressed below.
|
|
137
|
+
const env = { ...process.env, COCKPIT_MANAGED: 'bare' };
|
|
138
|
+
// The detached server has no terminal to open a browser from meaningfully,
|
|
139
|
+
// and doing so on every `cockpit start` would be surprising.
|
|
140
|
+
env.COCKPIT_NO_OPEN = '1';
|
|
141
|
+
|
|
142
|
+
const child = spawn(process.execPath, ['server.mjs'], {
|
|
143
|
+
cwd: PROJECT_ROOT,
|
|
144
|
+
env,
|
|
145
|
+
// POSIX: new session, so closing the terminal does not take the server
|
|
146
|
+
// with it. Windows: a new process group; windowsHide stops a console
|
|
147
|
+
// window from flashing up.
|
|
148
|
+
detached: true,
|
|
149
|
+
windowsHide: true,
|
|
150
|
+
// stdio must go to a file, not 'ignore' — otherwise every log line and
|
|
151
|
+
// crash message is discarded.
|
|
152
|
+
stdio: ['ignore', logFd, logFd],
|
|
153
|
+
});
|
|
154
|
+
child.unref();
|
|
155
|
+
|
|
156
|
+
const port = defaultPort();
|
|
157
|
+
const deadline = Date.now() + START_TIMEOUT_MS;
|
|
158
|
+
while (Date.now() < deadline) {
|
|
159
|
+
await sleep(POLL_INTERVAL_MS);
|
|
160
|
+
const health = await probe(port);
|
|
161
|
+
if (health) {
|
|
162
|
+
if (!quiet) {
|
|
163
|
+
console.log(`Cockpit started → http://localhost:${health.port || port}`);
|
|
164
|
+
console.log(` pid ${health.pid} logs: ${SERVER_LOG_PATH}`);
|
|
165
|
+
}
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
// Spawned but already gone → it failed at boot; the reason is in the log.
|
|
169
|
+
if (child.exitCode !== null) break;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
console.error(`Cockpit did not come up within ${START_TIMEOUT_MS / 1000}s.`);
|
|
173
|
+
console.error(`Check the log: ${SERVER_LOG_PATH}`);
|
|
174
|
+
return 1;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ─────────────────────────────────────────────────────────
|
|
178
|
+
// stop
|
|
179
|
+
// ─────────────────────────────────────────────────────────
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Escalating stop. HTTP first, signals only as a fallback.
|
|
183
|
+
*
|
|
184
|
+
* Windows has no SIGTERM: process.kill(pid) there maps to TerminateProcess,
|
|
185
|
+
* which kills without running the exit hook, losing unflushed PTY scrollback.
|
|
186
|
+
* POST /api/shutdown behaves identically on every platform and lets the server
|
|
187
|
+
* exit through its normal path, so it is the primary mechanism and the signal
|
|
188
|
+
* path only covers a process too wedged to answer HTTP.
|
|
189
|
+
*/
|
|
190
|
+
async function stopProcess(rec) {
|
|
191
|
+
const { port, pid } = rec;
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
await fetch(`http://127.0.0.1:${port}/api/shutdown`, {
|
|
195
|
+
method: 'POST',
|
|
196
|
+
signal: AbortSignal.timeout(3000),
|
|
197
|
+
});
|
|
198
|
+
} catch {
|
|
199
|
+
// Unreachable or already going down — fall through to the wait, which
|
|
200
|
+
// decides whether anything still needs killing.
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const deadline = Date.now() + STOP_TIMEOUT_MS;
|
|
204
|
+
while (Date.now() < deadline) {
|
|
205
|
+
await sleep(POLL_INTERVAL_MS);
|
|
206
|
+
if (!(await probe(port, 500)) && !pidAlive(pid)) return true;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!pid) return false;
|
|
210
|
+
|
|
211
|
+
console.error('Graceful shutdown timed out — forcing.');
|
|
212
|
+
if (isWindows) {
|
|
213
|
+
spawnSync('taskkill', ['/PID', String(pid), '/T', '/F'], { stdio: 'ignore' });
|
|
214
|
+
} else {
|
|
215
|
+
try { process.kill(pid, 'SIGTERM'); } catch { /* already gone */ }
|
|
216
|
+
await sleep(2000);
|
|
217
|
+
if (pidAlive(pid)) {
|
|
218
|
+
try { process.kill(pid, 'SIGKILL'); } catch { /* already gone */ }
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
await sleep(POLL_INTERVAL_MS);
|
|
222
|
+
return !pidAlive(pid);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export async function stop() {
|
|
226
|
+
const running = await findRunning();
|
|
227
|
+
if (!running) {
|
|
228
|
+
const rec = readRecord();
|
|
229
|
+
// A record with a live pid but no HTTP answer means a wedged process, not
|
|
230
|
+
// a clean "not running" — say so instead of silently doing nothing.
|
|
231
|
+
if (rec && pidAlive(rec.pid)) {
|
|
232
|
+
console.log(`Cockpit (pid ${rec.pid}) is not answering HTTP — forcing.`);
|
|
233
|
+
const ok = await stopProcess(rec);
|
|
234
|
+
console.log(ok ? 'Cockpit stopped.' : 'Failed to stop cockpit.');
|
|
235
|
+
return ok ? 0 : 1;
|
|
236
|
+
}
|
|
237
|
+
console.log('Cockpit is not running.');
|
|
238
|
+
return 0;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const ok = await stopProcess(running);
|
|
242
|
+
console.log(ok ? 'Cockpit stopped.' : 'Failed to stop cockpit.');
|
|
243
|
+
return ok ? 0 : 1;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// ─────────────────────────────────────────────────────────
|
|
247
|
+
// status
|
|
248
|
+
// ─────────────────────────────────────────────────────────
|
|
249
|
+
|
|
250
|
+
function formatUptime(startedAt) {
|
|
251
|
+
if (!startedAt) return null;
|
|
252
|
+
let s = Math.floor((Date.now() - startedAt) / 1000);
|
|
253
|
+
if (s < 0) return null;
|
|
254
|
+
const d = Math.floor(s / 86400); s %= 86400;
|
|
255
|
+
const h = Math.floor(s / 3600); s %= 3600;
|
|
256
|
+
const m = Math.floor(s / 60); s %= 60;
|
|
257
|
+
if (d) return `${d}d ${h}h ${m}m`;
|
|
258
|
+
if (h) return `${h}h ${m}m`;
|
|
259
|
+
if (m) return `${m}m ${s}s`;
|
|
260
|
+
return `${s}s`;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export async function status() {
|
|
264
|
+
const running = await findRunning();
|
|
265
|
+
if (!running) {
|
|
266
|
+
const rec = readRecord();
|
|
267
|
+
if (rec && pidAlive(rec.pid)) {
|
|
268
|
+
console.log('Cockpit: process alive but not answering HTTP');
|
|
269
|
+
console.log(` pid ${rec.pid}`);
|
|
270
|
+
console.log(` port ${rec.port}`);
|
|
271
|
+
console.log(` logs ${SERVER_LOG_PATH}`);
|
|
272
|
+
return 1;
|
|
273
|
+
}
|
|
274
|
+
console.log('Cockpit is not running.');
|
|
275
|
+
console.log(` data dir ${COCKPIT_HOME_DIR}`);
|
|
276
|
+
return 1;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const uptime = formatUptime(running.startedAt);
|
|
280
|
+
console.log('Cockpit is running.');
|
|
281
|
+
console.log(` version ${running.version || 'unknown'}`);
|
|
282
|
+
console.log(` pid ${running.pid}`);
|
|
283
|
+
console.log(` port ${running.port}`);
|
|
284
|
+
if (uptime) console.log(` uptime ${uptime}`);
|
|
285
|
+
console.log(` managed ${running.managed || 'foreground'}`);
|
|
286
|
+
console.log(` data dir ${running.home || COCKPIT_HOME_DIR}`);
|
|
287
|
+
console.log(` logs ${SERVER_LOG_PATH}`);
|
|
288
|
+
console.log(` url http://localhost:${running.port}`);
|
|
289
|
+
return 0;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// ─────────────────────────────────────────────────────────
|
|
293
|
+
// restart
|
|
294
|
+
// ─────────────────────────────────────────────────────────
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Is the running instance enforcing a token gate?
|
|
298
|
+
*
|
|
299
|
+
* Probed, not read from disk: the token is deliberately never persisted (it
|
|
300
|
+
* would only widen the blast radius), so asking the server is the only way to
|
|
301
|
+
* find out. A request carrying a forwarding header cannot qualify as "local",
|
|
302
|
+
* so it gets 401 exactly when COCKPIT_TOKEN is set. 203.0.113.x is TEST-NET-3
|
|
303
|
+
* and never routable.
|
|
304
|
+
*/
|
|
305
|
+
async function hasTokenGate(port) {
|
|
306
|
+
try {
|
|
307
|
+
const res = await fetch(`http://127.0.0.1:${port}/api/health`, {
|
|
308
|
+
headers: { 'X-Forwarded-For': '203.0.113.1' },
|
|
309
|
+
signal: AbortSignal.timeout(2000),
|
|
310
|
+
});
|
|
311
|
+
return res.status === 401;
|
|
312
|
+
} catch {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Restart in place.
|
|
319
|
+
*
|
|
320
|
+
* Takes no project argument on purpose: restarting means "bring back what was
|
|
321
|
+
* running", and the started URL is not shown to anyone here anyway — the user
|
|
322
|
+
* is typically already looking at an open tab.
|
|
323
|
+
*/
|
|
324
|
+
// ─────────────────────────────────────────────────────────
|
|
325
|
+
// update
|
|
326
|
+
// ─────────────────────────────────────────────────────────
|
|
327
|
+
|
|
328
|
+
const PKG = '@surething/cockpit';
|
|
329
|
+
/** Install + rollback + respawn; generous because npm is the slow part. */
|
|
330
|
+
const UPDATE_TIMEOUT_MS = 5 * 60_000;
|
|
331
|
+
|
|
332
|
+
function runNpm(args) {
|
|
333
|
+
const r = spawnSync('npm', args, {
|
|
334
|
+
stdio: 'inherit',
|
|
335
|
+
// On Windows npm is npm.cmd, a batch file. Node 18.20+/20.12+ refuses to
|
|
336
|
+
// spawn .cmd without a shell (CVE-2024-27980) — without this the call fails
|
|
337
|
+
// to launch rather than merely returning a non-zero status.
|
|
338
|
+
shell: process.platform === 'win32',
|
|
339
|
+
});
|
|
340
|
+
if (r.error) {
|
|
341
|
+
console.error(`\n✗ Could not run npm: ${r.error.message}`);
|
|
342
|
+
console.error(' Cockpit updates itself through the global npm install, so npm must be on PATH.');
|
|
343
|
+
return 1;
|
|
344
|
+
}
|
|
345
|
+
// spawnSync reports a failure to *launch* through `error` with a null status;
|
|
346
|
+
// checking only `status` would turn that into a silent exit(1).
|
|
347
|
+
return r.status ?? 1;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Install directly with npm. Only valid when no server is running: replacing
|
|
352
|
+
* the install directory under a live process breaks it — on POSIX the moment
|
|
353
|
+
* Next lazily imports a chunk npm has deleted, and on Windows immediately,
|
|
354
|
+
* because node-pty's dlopen'd .node files are locked.
|
|
355
|
+
*/
|
|
356
|
+
async function updateOffline() {
|
|
357
|
+
console.log(`Updating ${PKG}...`);
|
|
358
|
+
const installArgs = ['install', '-g', `${PKG}@latest`, '--include=optional'];
|
|
359
|
+
let status = runNpm(installArgs);
|
|
360
|
+
|
|
361
|
+
// An in-place `npm i -g` can drop the SDK's platform-specific native binary
|
|
362
|
+
// (an optional dependency) when the SDK version bumps — see
|
|
363
|
+
// scripts/claudeBinary.mjs. A clean uninstall + reinstall reliably refetches
|
|
364
|
+
// it, so chat is never left silently broken.
|
|
365
|
+
if (status === 0 && !hasClaudeBinary()) {
|
|
366
|
+
console.log('Native Claude binary missing after update — reinstalling to repair...');
|
|
367
|
+
runNpm(['uninstall', '-g', PKG]);
|
|
368
|
+
status = runNpm(installArgs);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (status === 0) {
|
|
372
|
+
let version = 'unknown';
|
|
373
|
+
try {
|
|
374
|
+
version = JSON.parse(readFileSync(resolve(PROJECT_ROOT, 'package.json'), 'utf8')).version;
|
|
375
|
+
} catch { /* report what we can */ }
|
|
376
|
+
console.log(`\nUpdated to v${version}`);
|
|
377
|
+
if (!hasClaudeBinary()) {
|
|
378
|
+
console.error('\nWarning: the native Claude CLI binary is still missing; chat will not work.');
|
|
379
|
+
console.error(`Fix manually: npm uninstall -g ${PKG} && npm install -g ${PKG}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return status;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Update, picking the right mechanism for the current state.
|
|
387
|
+
*
|
|
388
|
+
* running -> ask the server to update itself. It hands off to a detached
|
|
389
|
+
* helper that installs while nothing holds the install directory,
|
|
390
|
+
* then relaunches with the server's own environment (token, port,
|
|
391
|
+
* host) intact. Same path the UI button uses.
|
|
392
|
+
* stopped -> install directly; nothing to preserve, nothing to coordinate.
|
|
393
|
+
*
|
|
394
|
+
* The old behaviour — always npm, regardless — corrupted a live install and
|
|
395
|
+
* still left the user running the previous code with no hint that a restart
|
|
396
|
+
* was needed.
|
|
397
|
+
*/
|
|
398
|
+
export async function update() {
|
|
399
|
+
const running = await findRunning();
|
|
400
|
+
if (!running) return updateOffline();
|
|
401
|
+
|
|
402
|
+
console.log(`Cockpit is running (pid ${running.pid}) — updating in place.`);
|
|
403
|
+
let res;
|
|
404
|
+
try {
|
|
405
|
+
res = await fetch(`http://127.0.0.1:${running.port}/api/update`, {
|
|
406
|
+
method: 'POST',
|
|
407
|
+
signal: AbortSignal.timeout(5000),
|
|
408
|
+
});
|
|
409
|
+
} catch {
|
|
410
|
+
console.error('\n✗ The running server did not accept the update request.');
|
|
411
|
+
console.error(' Stop it first (`cockpit stop`), then run `cockpit update` again.');
|
|
412
|
+
return 1;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (!res.ok) {
|
|
416
|
+
// Refusals are deliberate — dev mode, or a non-local caller. Never fall
|
|
417
|
+
// back to npm here: in dev that would install the published package over
|
|
418
|
+
// the user's source tree.
|
|
419
|
+
const body = await res.json().catch(() => ({}));
|
|
420
|
+
console.error(`\n✗ Update refused: ${body.error ?? `HTTP ${res.status}`}`);
|
|
421
|
+
return 1;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
console.log('Installing and restarting...');
|
|
425
|
+
const replacement = await waitForReplacement(running.port, running.pid, UPDATE_TIMEOUT_MS);
|
|
426
|
+
if (!replacement) {
|
|
427
|
+
console.error('\n✗ The update was accepted but the server has not come back.');
|
|
428
|
+
console.error(` Log: ${join(LOG_DIR, 'updater.log')}`);
|
|
429
|
+
console.error(` State: ${join(COCKPIT_HOME_DIR, 'update-state.json')}`);
|
|
430
|
+
return 1;
|
|
431
|
+
}
|
|
432
|
+
console.log(`\nUpdated to v${replacement.version ?? 'unknown'} (pid ${replacement.pid})`);
|
|
433
|
+
return 0;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/** Wait for a pid other than `oldPid` to be serving, i.e. the replacement is up. */
|
|
437
|
+
async function waitForReplacement(port, oldPid, timeoutMs = 60_000) {
|
|
438
|
+
const deadline = Date.now() + timeoutMs;
|
|
439
|
+
while (Date.now() < deadline) {
|
|
440
|
+
await sleep(POLL_INTERVAL_MS);
|
|
441
|
+
const health = await probe(port, 1000);
|
|
442
|
+
if (health && health.pid !== oldPid) return health;
|
|
443
|
+
}
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export async function restart({ force = false } = {}) {
|
|
448
|
+
const running = await findRunning();
|
|
449
|
+
|
|
450
|
+
if (running) {
|
|
451
|
+
// Preferred path: ask the SERVER to restart itself. It hands off to a
|
|
452
|
+
// detached helper that inherits its environment, so COCKPIT_TOKEN, PORT and
|
|
453
|
+
// COCKPIT_HOST carry over untouched. Doing it from here instead would
|
|
454
|
+
// rebuild the environment out of the current shell — dropping a token gate
|
|
455
|
+
// without saying so, and forcing the user to re-supply every flag.
|
|
456
|
+
try {
|
|
457
|
+
const res = await fetch(`http://127.0.0.1:${running.port}/api/restart`, {
|
|
458
|
+
method: 'POST',
|
|
459
|
+
signal: AbortSignal.timeout(5000),
|
|
460
|
+
});
|
|
461
|
+
if (res.ok) {
|
|
462
|
+
const replacement = await waitForReplacement(running.port, running.pid);
|
|
463
|
+
if (replacement) {
|
|
464
|
+
console.log(`Cockpit restarted → http://localhost:${replacement.port || running.port}`);
|
|
465
|
+
console.log(` pid ${replacement.pid} logs: ${SERVER_LOG_PATH}`);
|
|
466
|
+
return 0;
|
|
467
|
+
}
|
|
468
|
+
console.error('Restart was accepted but the server did not come back.');
|
|
469
|
+
console.error(`Check the log: ${join(LOG_DIR, 'updater.log')}`);
|
|
470
|
+
return 1;
|
|
471
|
+
}
|
|
472
|
+
// Non-OK means the server refused (dev mode, for instance). Fall through
|
|
473
|
+
// to the local path, which reports its own reasons.
|
|
474
|
+
} catch {
|
|
475
|
+
// Unreachable or wedged — fall through and do it the blunt way.
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (running) {
|
|
480
|
+
// FALLBACK PATH ONLY — reached when the server could not restart itself
|
|
481
|
+
// (wedged, or it refused). Here the environment comes from this shell
|
|
482
|
+
// rather than from the running server, so a token gate would be dropped
|
|
483
|
+
// silently and nothing afterwards would look wrong. Refuse instead.
|
|
484
|
+
if (!force && !process.env.COCKPIT_TOKEN && (await hasTokenGate(running.port))) {
|
|
485
|
+
console.error('\n✗ The running instance requires an access token, but COCKPIT_TOKEN is not set here.');
|
|
486
|
+
console.error(' Restarting now would bring cockpit back with authentication disabled.\n');
|
|
487
|
+
console.error(' Restart with the token: COCKPIT_TOKEN=<token> cockpit restart');
|
|
488
|
+
console.error(' Or accept the change: cockpit restart --force\n');
|
|
489
|
+
return 1;
|
|
490
|
+
}
|
|
491
|
+
const ok = await stopProcess(running);
|
|
492
|
+
if (!ok) {
|
|
493
|
+
console.error('Could not stop the running instance; not restarting.');
|
|
494
|
+
return 1;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return start();
|
|
498
|
+
}
|
package/bin/cock.mjs
CHANGED
|
@@ -17,9 +17,13 @@ if (process.argv[2] === '--help' || process.argv[2] === '-h' || process.argv[2]
|
|
|
17
17
|
Usage: cockpit [path] [options] (alias: cock)
|
|
18
18
|
|
|
19
19
|
Commands:
|
|
20
|
-
cockpit Start server, open last project
|
|
20
|
+
cockpit Start server in the foreground, open last project
|
|
21
21
|
cockpit . Start server, open current directory
|
|
22
22
|
cockpit <path> Start server, open specified directory
|
|
23
|
+
start Start in the background (survives closing the terminal)
|
|
24
|
+
stop Stop the background server
|
|
25
|
+
restart Restart it (--force to drop a token gate)
|
|
26
|
+
status Show whether cockpit is running, and where
|
|
23
27
|
browser <id> <action> Control browser bubbles
|
|
24
28
|
terminal <id> <action> Control terminal bubbles
|
|
25
29
|
codegraph <subcmd> [...] Query the project code graph (search/risk/affected/...)
|
|
@@ -27,9 +31,9 @@ Commands:
|
|
|
27
31
|
update Update to latest version
|
|
28
32
|
|
|
29
33
|
Options:
|
|
30
|
-
--port <port> Set server port (default: 3457)
|
|
34
|
+
--port <port> Set server port (default: 3457); works with start too
|
|
31
35
|
--token <token> Require this token for remote access (local stays open)
|
|
32
|
-
--no-open Don't open browser after start
|
|
36
|
+
--no-open Don't open browser after start (start never opens one)
|
|
33
37
|
-v, --version Show version
|
|
34
38
|
-h, --help Show this help
|
|
35
39
|
|
|
@@ -124,30 +128,10 @@ if (process.argv[2] === 'connection') {
|
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
if (process.argv[2] === 'update') {
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
// An in-place `npm i -g` can drop the SDK's platform-specific native binary
|
|
132
|
-
// (an optional dependency) when the SDK version bumps — see
|
|
133
|
-
// scripts/claudeBinary.mjs. A clean uninstall + reinstall reliably refetches
|
|
134
|
-
// it. Guard here so `cockpit update` never leaves chat silently broken.
|
|
135
|
-
if (result.status === 0 && !hasClaudeBinary()) {
|
|
136
|
-
console.log('Native Claude binary missing after update — reinstalling to repair...');
|
|
137
|
-
spawnSync('npm', ['uninstall', '-g', '@surething/cockpit'], { stdio: 'inherit' });
|
|
138
|
-
result = spawnSync('npm', installArgs, { stdio: 'inherit' });
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (result.status === 0) {
|
|
142
|
-
const { readFileSync } = await import('fs');
|
|
143
|
-
const pkg = JSON.parse(readFileSync(resolve(PROJECT_ROOT, 'package.json'), 'utf8'));
|
|
144
|
-
console.log(`\nUpdated to v${pkg.version}`);
|
|
145
|
-
if (!hasClaudeBinary()) {
|
|
146
|
-
console.error('\nWarning: the native Claude CLI binary is still missing; chat will not work.');
|
|
147
|
-
console.error('Fix manually: npm uninstall -g @surething/cockpit && npm install -g @surething/cockpit');
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
process.exit(result.status ?? 1);
|
|
131
|
+
// Two mechanisms, picked by whether a server is live — see cock-service.mjs.
|
|
132
|
+
const svc = await import('./cock-service.mjs');
|
|
133
|
+
const code = await svc.update();
|
|
134
|
+
await flushAndExit(code);
|
|
151
135
|
}
|
|
152
136
|
|
|
153
137
|
// ============================================
|
|
@@ -156,6 +140,30 @@ if (process.argv[2] === 'update') {
|
|
|
156
140
|
const { existsSync, mkdirSync } = await import('fs');
|
|
157
141
|
const { homedir } = await import('os');
|
|
158
142
|
|
|
143
|
+
// Background process management. Must be routed BEFORE the project-directory
|
|
144
|
+
// fallback below, which treats any unrecognised first argument as a path and
|
|
145
|
+
// creates it — `cockpit start` would otherwise mkdir ./start.
|
|
146
|
+
const SERVICE_COMMANDS = new Set(['start', 'stop', 'restart', 'status']);
|
|
147
|
+
if (SERVICE_COMMANDS.has(process.argv[2])) {
|
|
148
|
+
const sub = process.argv[2];
|
|
149
|
+
const svc = await import('./cock-service.mjs');
|
|
150
|
+
// `restart --force` acknowledges dropping a token gate (see cock-service.mjs).
|
|
151
|
+
const forceIdx = process.argv.indexOf('--force');
|
|
152
|
+
const svcForce = forceIdx !== -1;
|
|
153
|
+
if (svcForce) process.argv.splice(forceIdx, 1);
|
|
154
|
+
// None of these take a project path — the background server is not tied to a
|
|
155
|
+
// project. Say so rather than silently ignoring the argument, since
|
|
156
|
+
// `cockpit <path>` (foreground) does accept one and the difference is easy
|
|
157
|
+
// to trip over.
|
|
158
|
+
const stray = process.argv[3];
|
|
159
|
+
if (stray && !stray.startsWith('-')) {
|
|
160
|
+
console.error(`cockpit ${sub}: ignoring '${stray}' — the background server is not bound to a project.`);
|
|
161
|
+
console.error(` Open a project from the UI, or run \`cockpit ${stray}\` to start in the foreground.\n`);
|
|
162
|
+
}
|
|
163
|
+
const code = await svc[sub]({ force: svcForce });
|
|
164
|
+
await flushAndExit(code);
|
|
165
|
+
}
|
|
166
|
+
|
|
159
167
|
const knownCommands = new Set(['browser', 'terminal', 'update', 'help', 'codegraph', 'connection']);
|
|
160
168
|
const arg = process.argv[2];
|
|
161
169
|
let projectDir = null;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Single definition of the data dir for the plain-JS side (server.mjs + the
|
|
2
|
+
// bin/ CLI). packages/shared/utils/src/paths.ts carries the TypeScript twin for
|
|
3
|
+
// app code; that one cannot be shared here without pulling TS into the CLI, but
|
|
4
|
+
// there is no reason for the .mjs side to hold two copies of it.
|
|
5
|
+
//
|
|
6
|
+
// Keep the two in sync: COCKPIT_HOME wins, `~` expands, and the path is
|
|
7
|
+
// resolved so a relative value behaves.
|
|
8
|
+
import { homedir } from 'os';
|
|
9
|
+
import { join, resolve } from 'path';
|
|
10
|
+
|
|
11
|
+
export const COCKPIT_HOME_DIR = process.env.COCKPIT_HOME
|
|
12
|
+
? resolve(process.env.COCKPIT_HOME.replace(/^~(?=$|\/)/, homedir()))
|
|
13
|
+
: join(homedir(), '.cockpit');
|
|
14
|
+
|
|
15
|
+
export const SERVER_JSON_PATH = join(COCKPIT_HOME_DIR, 'server.json');
|
|
16
|
+
export const LOG_DIR = join(COCKPIT_HOME_DIR, 'logs');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Structured JSON lines from the app's Effect logger
|
|
20
|
+
* (packages/shared/effect-core/src/logger.ts).
|
|
21
|
+
*/
|
|
22
|
+
export const APP_LOG_PATH = join(LOG_DIR, 'cockpit.log');
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Raw stdout/stderr of a backgrounded server (`cockpit start`).
|
|
26
|
+
*
|
|
27
|
+
* Deliberately NOT cockpit.log: that file is one JSON object per line and is
|
|
28
|
+
* parsed as such, while this captures plain text (console output, Next's
|
|
29
|
+
* startup banner, a stack trace from a crash). Mixing the two would break any
|
|
30
|
+
* reader of either, and they want different rotation policies — this one is
|
|
31
|
+
* held open as an fd for the life of the process.
|
|
32
|
+
*/
|
|
33
|
+
export const SERVER_LOG_PATH = join(LOG_DIR, 'server.log');
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Size-based log rotation, performed at startup only.
|
|
2
|
+
//
|
|
3
|
+
// Startup rather than on every write, because:
|
|
4
|
+
// - it costs nothing at runtime (one stat per boot);
|
|
5
|
+
// - `cockpit start` hands the server an already-open fd for its stdout, and
|
|
6
|
+
// rotating a file out from under a held fd is a no-op on POSIX (the writer
|
|
7
|
+
// keeps the old inode) and fails outright on Windows. Doing it before the
|
|
8
|
+
// open sidesteps both.
|
|
9
|
+
//
|
|
10
|
+
// The trade-off: an instance that runs for months without a restart can exceed
|
|
11
|
+
// the cap. Acceptable here — Cockpit ships patches every ~1.5 days, so restarts
|
|
12
|
+
// are frequent, and the real fix for volume is not logging noise in the first
|
|
13
|
+
// place (see the git.status note in feature/explorer/.../effect/git.ts).
|
|
14
|
+
//
|
|
15
|
+
// One generation is kept (`<name>.1`), so the on-disk ceiling per log is
|
|
16
|
+
// 2x maxBytes. Cockpit rotates two logs (cockpit.log, server.log), i.e. at most
|
|
17
|
+
// four files.
|
|
18
|
+
//
|
|
19
|
+
// Cross-platform notes — rename/unlink are where the platforms differ:
|
|
20
|
+
//
|
|
21
|
+
// POSIX renameSync and unlinkSync succeed even while another process holds
|
|
22
|
+
// the file open; the old inode simply stays alive for that writer.
|
|
23
|
+
// Windows both fail with EPERM/EBUSY if any process has the file open
|
|
24
|
+
// without FILE_SHARE_DELETE. So on Windows rotation only works when
|
|
25
|
+
// nothing holds the file, which is why each caller rotates at a point
|
|
26
|
+
// where that is guaranteed:
|
|
27
|
+
// - server.log is rotated before openSync() hands its fd to the
|
|
28
|
+
// spawned server, and `cockpit start` bails out earlier if an
|
|
29
|
+
// instance is already running;
|
|
30
|
+
// - cockpit.log is written with per-line appendFile (no retained
|
|
31
|
+
// fd) and is rotated right after the single-instance check.
|
|
32
|
+
//
|
|
33
|
+
// A failure here is never fatal: an external holder (a tail -f, an editor with
|
|
34
|
+
// the file open) just means the rotation is skipped and retried next boot.
|
|
35
|
+
import { statSync, renameSync, unlinkSync, existsSync } from 'fs';
|
|
36
|
+
|
|
37
|
+
export const DEFAULT_MAX_LOG_BYTES = 10 * 1024 * 1024; // 10 MB
|
|
38
|
+
|
|
39
|
+
export function rotateIfLarge(path, maxBytes = DEFAULT_MAX_LOG_BYTES) {
|
|
40
|
+
try {
|
|
41
|
+
if (!existsSync(path)) return false;
|
|
42
|
+
if (statSync(path).size < maxBytes) return false;
|
|
43
|
+
const previous = `${path}.1`;
|
|
44
|
+
if (existsSync(previous)) unlinkSync(previous);
|
|
45
|
+
renameSync(path, previous);
|
|
46
|
+
return true;
|
|
47
|
+
} catch {
|
|
48
|
+
// Best effort: a log that cannot be rotated must never stop the server from
|
|
49
|
+
// starting.
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|