@surething/cockpit 1.0.232 → 1.0.234
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/build-manifest.json +3 -3
- package/.next-prod/prerender-manifest.json +3 -3
- package/.next-prod/react-loadable-manifest.json +7 -0
- package/.next-prod/server/app/_global-error/page.js.nft.json +1 -1
- 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/_global-error.segment.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_index.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.nft.json +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 +3 -3
- package/.next-prod/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/.next-prod/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next-prod/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/.next-prod/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next-prod/server/app/_not-found.segments/_not-found.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.nft.json +1 -1
- package/.next-prod/server/app/api/bash/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/codex/route.js +1 -1
- package/.next-prod/server/app/api/chat/codex/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/deepseek/route.js +1 -1
- package/.next-prod/server/app/api/chat/deepseek/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/kimi/route.js +1 -1
- package/.next-prod/server/app/api/chat/kimi/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/ollama/route.js +1 -1
- package/.next-prod/server/app/api/chat/ollama/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/pty-input/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/route.js +1 -1
- package/.next-prod/server/app/api/chat/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/stop/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/claude-stats/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/commands/route.js +1 -1
- package/.next-prod/server/app/api/commands/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/comments/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/columns/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/connect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/disconnect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/export/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/query/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/schemas/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/dev/spans/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/extension/version/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/file/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/blame/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/clipboard/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/copy/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/delete/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/expanded/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/index/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/init/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/paste/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/read/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/readdir/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/recent/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/save/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/search/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/stat/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/text/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/branch-diff/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/branches/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/commit-diff/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/commits/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/current-branch/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/diff/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/discard/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/stage/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/status/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/unstage/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/worktree/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/global-state/route.js +1 -1
- package/.next-prod/server/app/api/global-state/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/health/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/jupyter/load/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/jupyter/save/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/jupyter/shutdown/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/definition/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/hover/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/references/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/status/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/warmup/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/columns/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/connect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/disconnect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/export/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/query/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/schemas/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/neo4j/connect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/neo4j/disconnect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/neo4j/query/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/neo4j/schema/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/note/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/ollama/models/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/ollama/start/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/open-cursor/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/open-vscode/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/pick-folder/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/pinned-sessions/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/project-settings/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/project-state/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/affected/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/callees/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/callers/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/coedit/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/context/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/file/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/file-functions/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/impact/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/related/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/risk/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/search/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projects/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/push/public-key/route.js +1 -1
- package/.next-prod/server/app/api/push/public-key/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/push/subscribe/route.js +1 -1
- package/.next-prod/server/app/api/push/subscribe/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/push/unsubscribe/route.js +1 -1
- package/.next-prod/server/app/api/push/unsubscribe/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/command/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/connect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/delete/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/disconnect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/get/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/keys/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/set/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/[id]/comments/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/[id]/replies/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/[id]/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/identify/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/order/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/share-info/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/users/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/scheduled-tasks/route.js +2 -2
- package/.next-prod/server/app/api/scheduled-tasks/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/services/config/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/services/scripts/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/session/[sessionId]/fork/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/session/[sessionId]/history/route.js +1 -1
- package/.next-prod/server/app/api/session/[sessionId]/history/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/session-by-path/route.js +1 -1
- package/.next-prod/server/app/api/session-by-path/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/sessions/projects/[encodedPath]/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/sessions/projects/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/sessions/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/settings/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/skills/[id]/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/skills/content/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/skills/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/aliases/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/autocomplete/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/bubble-order/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/env/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/history/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/version/route.js.nft.json +1 -1
- package/.next-prod/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next-prod/server/app/m/page.js +2 -2
- package/.next-prod/server/app/m/page.js.nft.json +1 -1
- package/.next-prod/server/app/m/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/.next-prod/server/app/page.js +1 -1
- package/.next-prod/server/app/page.js.nft.json +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.js.nft.json +1 -1
- package/.next-prod/server/app/project/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/review/[id]/page.js +2 -2
- package/.next-prod/server/app/review/[id]/page.js.nft.json +1 -1
- package/.next-prod/server/app/review/[id]/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/chunks/3863.js +2 -2
- package/.next-prod/server/chunks/{3633.js → 5897.js} +373 -3
- package/.next-prod/server/chunks/9658.js +26 -26
- package/.next-prod/server/chunks/9830.js +1 -1
- 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/chunks/{2625-bc4748f0cd7db618.js → 1332-5e141e2acf28015a.js} +10 -10
- package/.next-prod/static/chunks/{217-4f8250a204080159.js → 217-e929c46c0bd599a7.js} +4 -4
- package/.next-prod/static/chunks/2502-fb8682bc7a61e04d.js +4 -0
- package/.next-prod/static/chunks/{2576-6420f6bad0b8ffb3.js → 2576-11e41242c7dd98f1.js} +2 -2
- package/.next-prod/static/chunks/4523.3f277a24fbcfde6d.js +138 -0
- package/.next-prod/static/chunks/9304-ddde9008da31b2ce.js +1 -0
- package/.next-prod/static/chunks/app/{layout-ac2f1f67df01cc89.js → layout-d202f8e0bcc90661.js} +1 -1
- package/.next-prod/static/chunks/app/m/page-71570a066f3eacf8.js +1 -0
- package/.next-prod/static/chunks/app/{page-1f0a6f49656a4c52.js → page-814b50b5b440249d.js} +1 -1
- package/.next-prod/static/chunks/app/project/{page-1f0a6f49656a4c52.js → page-814b50b5b440249d.js} +1 -1
- package/.next-prod/static/chunks/app/review/[id]/{page-39fa3a843adf617e.js → page-0c5d03d65758c7dc.js} +1 -1
- package/.next-prod/static/chunks/webpack-2c71a79c277961bc.js +1 -0
- package/.next-prod/static/css/fa7218e60ff464b5.css +1 -0
- package/.next-prod/trace +13 -13
- package/.next-prod/trace-build +1 -1
- package/bin/cock-browser.mjs +12 -9
- package/bin/cock.mjs +5 -5
- package/bin/postinstall.mjs +6 -6
- package/chrome-extension/automation.js +45 -40
- package/chrome-extension/background.js +70 -67
- package/chrome-extension/content.js +38 -38
- package/chrome-extension/disguise.js +4 -4
- package/chrome-extension/network-capture.js +16 -16
- package/dist/{chunk-VHFWPI2X.mjs → chunk-3M3JSZ5R.mjs} +28 -1
- package/dist/scheduledTasks.mjs +437 -3
- package/dist/wsServer.mjs +6 -31
- package/package.json +1 -1
- package/server.mjs +122 -26
- package/.next-prod/server/chunks/7003.js +0 -1
- package/.next-prod/static/chunks/471-504b396c8302f4f2.js +0 -4
- package/.next-prod/static/chunks/app/m/page-8b1af6f31b60c485.js +0 -1
- package/.next-prod/static/chunks/webpack-dbba7fa77ee1faa4.js +0 -1
- package/.next-prod/static/css/2a854655f4108c3a.css +0 -1
- /package/.next-prod/static/{Z3Em1C_kM7x4RjcH7E7v2 → JfwcuC5YjyhQWeQD-4Gvn}/_buildManifest.js +0 -0
- /package/.next-prod/static/{Z3Em1C_kM7x4RjcH7E7v2 → JfwcuC5YjyhQWeQD-4Gvn}/_ssgManifest.js +0 -0
package/server.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createServer } from 'http';
|
|
2
|
+
import { createGzip, constants as zlibConstants } from 'zlib';
|
|
2
3
|
import { exec, execSync } from 'child_process';
|
|
3
4
|
import { networkInterfaces, homedir } from 'os';
|
|
4
5
|
import { writeFileSync, mkdirSync, readFileSync, realpathSync } from 'fs';
|
|
@@ -53,17 +54,22 @@ async function ensureSingleInstance() {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
// ============================================
|
|
56
|
-
//
|
|
57
|
+
// Process lifecycle guards
|
|
57
58
|
//
|
|
58
|
-
// 1)
|
|
59
|
-
//
|
|
60
|
-
//
|
|
59
|
+
// 1) When the parent process dies, the stdout/stderr pipes break. Next.js's
|
|
60
|
+
// uncaughtException handler then tries to console.log the error → writes
|
|
61
|
+
// to stdout → EPIPE → triggers the handler again → CPU spin loop.
|
|
62
|
+
// Intercept pipe errors before they escalate to uncaughtException and
|
|
63
|
+
// exit immediately.
|
|
61
64
|
//
|
|
62
|
-
// 2) Next.js
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
65
|
+
// 2) In dev mode Next.js runs a `next-server` worker (turbopack) in its own
|
|
66
|
+
// child process. If the parent is killed abnormally (npm reinstall,
|
|
67
|
+
// Ctrl+C through an npm wrapper, IDE killing the task, etc.), the
|
|
68
|
+
// next-server child doesn't die with it — having lost its parent it
|
|
69
|
+
// **re-binds to Next's default port 3000** and then wedges every later
|
|
70
|
+
// `npm run dev` (Next detects "a dev server is already running" via
|
|
71
|
+
// .next/dev/logs and refuses to start). So the parent must explicitly
|
|
72
|
+
// kill all direct children before exiting.
|
|
67
73
|
// ============================================
|
|
68
74
|
// Assigned once the server-side bundle is loaded (see app.prepare below). Lets the
|
|
69
75
|
// synchronous exit hook flush live PTY scrollback to disk so a graceful restart
|
|
@@ -75,7 +81,8 @@ function killChildren() {
|
|
|
75
81
|
if (_cleanupRan) return;
|
|
76
82
|
_cleanupRan = true;
|
|
77
83
|
if (process.platform === 'win32') {
|
|
78
|
-
// Windows:
|
|
84
|
+
// Windows: list child PIDs via wmic, then taskkill /F /T each one —
|
|
85
|
+
// running /T on ourselves would take this process down too
|
|
79
86
|
try {
|
|
80
87
|
const out = execSync(`wmic process where (ParentProcessId=${process.pid}) get ProcessId /value`, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
81
88
|
const pids = (out.match(/ProcessId=(\d+)/g) || []).map(s => s.split('=')[1]).filter(Boolean);
|
|
@@ -85,34 +92,39 @@ function killChildren() {
|
|
|
85
92
|
} catch {}
|
|
86
93
|
return;
|
|
87
94
|
}
|
|
88
|
-
// POSIX: pkill -P
|
|
89
|
-
//
|
|
95
|
+
// POSIX: pkill -P kills direct children only, no recursion (next-server
|
|
96
|
+
// and friends are all direct children — enough).
|
|
97
|
+
// pkill exits 1 when nothing matches; not treated as an error.
|
|
90
98
|
try { execSync(`pkill -TERM -P ${process.pid}`, { stdio: 'ignore' }); } catch {}
|
|
91
99
|
}
|
|
92
100
|
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
101
|
+
// Normal exit path (including every process.exit() call) — Node guarantees
|
|
102
|
+
// this handler runs synchronously. All signal/exception paths ultimately go
|
|
103
|
+
// through process.exit() → 'exit' fires → this single hook covers every
|
|
104
|
+
// graceful shutdown. Flush live PTY scrollback to disk first, then kill the
|
|
105
|
+
// children (the flush reads this process's own memory — independent of them).
|
|
96
106
|
process.on('exit', () => {
|
|
97
107
|
try { flushRunningSync?.(); } catch {}
|
|
98
108
|
killChildren();
|
|
99
109
|
});
|
|
100
110
|
|
|
101
|
-
//
|
|
111
|
+
// Signal paths — kill children first, then exit with the code the shell expects
|
|
102
112
|
const cleanupAndExit = (code) => () => { killChildren(); process.exit(code); };
|
|
103
113
|
process.on('SIGINT', cleanupAndExit(130));
|
|
104
114
|
process.on('SIGTERM', cleanupAndExit(143));
|
|
105
115
|
process.on('SIGQUIT', cleanupAndExit(131));
|
|
106
116
|
process.on('SIGHUP', cleanupAndExit(0));
|
|
107
117
|
|
|
108
|
-
//
|
|
118
|
+
// Uncaught exceptions — don't let Next.js's default handler console.log its
|
|
119
|
+
// way back into the EPIPE spin loop
|
|
109
120
|
process.on('uncaughtException', (err) => {
|
|
110
121
|
try { console.error('uncaughtException:', err); } catch {}
|
|
111
122
|
killChildren();
|
|
112
123
|
process.exit(1);
|
|
113
124
|
});
|
|
114
125
|
|
|
115
|
-
// stdout/stderr
|
|
126
|
+
// Broken stdout/stderr pipe → exit immediately (the exit handler cleans up
|
|
127
|
+
// the children on the way out)
|
|
116
128
|
process.stdout.on('error', (err) => {
|
|
117
129
|
if (err.code === 'EPIPE' || err.code === 'ERR_STREAM_DESTROYED') process.exit(0);
|
|
118
130
|
});
|
|
@@ -134,7 +146,7 @@ app.prepare().then(async () => {
|
|
|
134
146
|
flushRunningSync = httpApi.flushAllRunningSync || null;
|
|
135
147
|
const { scheduledTaskManager } = await import(dev ? '@cockpit/feature-agent/server/scheduledTasks' : './dist/scheduledTasks.mjs');
|
|
136
148
|
|
|
137
|
-
//
|
|
149
|
+
// Initialize the scheduled-task manager
|
|
138
150
|
scheduledTaskManager.setOnTaskFired((task) => {
|
|
139
151
|
broadcastToGlobalState({ type: 'task-fired', taskId: task.id, cwd: task.cwd, tabId: task.tabId, sessionId: task.sessionId });
|
|
140
152
|
});
|
|
@@ -176,10 +188,92 @@ app.prepare().then(async () => {
|
|
|
176
188
|
return false;
|
|
177
189
|
};
|
|
178
190
|
|
|
191
|
+
// ============================================
|
|
192
|
+
// /api/* JSON gzip — Next's built-in compression only runs under
|
|
193
|
+
// `next start`; with this custom server, API JSON goes out uncompressed
|
|
194
|
+
// (fine locally at <10ms, but behind a tunnel like ngrok a 200KB+
|
|
195
|
+
// session-by-path response means seconds of latency). Transparently wrap
|
|
196
|
+
// application/json responses in gzip; SSE / HTML / static assets (which
|
|
197
|
+
// Next already compresses) are untouched.
|
|
198
|
+
// ============================================
|
|
199
|
+
const gzipJsonResponse = (req, res) => {
|
|
200
|
+
if (!/\bgzip\b/i.test(String(req.headers['accept-encoding'] || ''))) return;
|
|
201
|
+
const origWriteHead = res.writeHead.bind(res);
|
|
202
|
+
const origWrite = res.write.bind(res);
|
|
203
|
+
const origEnd = res.end.bind(res);
|
|
204
|
+
let gzip = null;
|
|
205
|
+
let decided = false;
|
|
206
|
+
|
|
207
|
+
// Decide at first output (writeHead/write/end): only compress JSON that
|
|
208
|
+
// isn't already encoded.
|
|
209
|
+
const decide = () => {
|
|
210
|
+
if (decided) return;
|
|
211
|
+
decided = true;
|
|
212
|
+
const ct = String(res.getHeader('content-type') || '');
|
|
213
|
+
if (!ct.includes('application/json') || res.getHeader('content-encoding')) return;
|
|
214
|
+
res.removeHeader('content-length');
|
|
215
|
+
res.setHeader('content-encoding', 'gzip');
|
|
216
|
+
const vary = String(res.getHeader('vary') || '');
|
|
217
|
+
if (!/\baccept-encoding\b/i.test(vary)) {
|
|
218
|
+
res.setHeader('vary', vary ? `${vary}, Accept-Encoding` : 'Accept-Encoding');
|
|
219
|
+
}
|
|
220
|
+
gzip = createGzip({ flush: zlibConstants.Z_SYNC_FLUSH });
|
|
221
|
+
gzip.on('data', (chunk) => origWrite(chunk));
|
|
222
|
+
gzip.on('end', () => origEnd());
|
|
223
|
+
gzip.on('error', () => { try { origEnd(); } catch {} });
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// writeHead accepts headers in three shapes: object, flat array
|
|
227
|
+
// [k1,v1,k2,v2,...] (what Next uses internally), and nested array
|
|
228
|
+
// [[k,v],...]. Normalize all of them through setHeader before deciding
|
|
229
|
+
// on compression.
|
|
230
|
+
const applyHeaders = (h) => {
|
|
231
|
+
if (!h) return;
|
|
232
|
+
if (Array.isArray(h)) {
|
|
233
|
+
const pairs = Array.isArray(h[0])
|
|
234
|
+
? h
|
|
235
|
+
: Array.from({ length: h.length >> 1 }, (_, i) => [h[i * 2], h[i * 2 + 1]]);
|
|
236
|
+
for (const [k, v] of pairs) {
|
|
237
|
+
if (k === undefined || v === undefined) continue;
|
|
238
|
+
const key = String(k);
|
|
239
|
+
const prev = res.getHeader(key);
|
|
240
|
+
// Merge duplicate headers (e.g. set-cookie) into an array instead of overwriting
|
|
241
|
+
res.setHeader(key, prev === undefined ? v : [].concat(prev, v));
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
for (const [k, v] of Object.entries(h)) {
|
|
245
|
+
if (v !== undefined) res.setHeader(k, v);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
res.writeHead = (status, arg2, arg3) => {
|
|
251
|
+
applyHeaders(typeof arg2 === 'object' ? arg2 : arg3);
|
|
252
|
+
decide();
|
|
253
|
+
return typeof arg2 === 'string' ? origWriteHead(status, arg2) : origWriteHead(status);
|
|
254
|
+
};
|
|
255
|
+
res.write = (chunk, ...args) => {
|
|
256
|
+
decide();
|
|
257
|
+
if (gzip) { gzip.write(chunk); return true; }
|
|
258
|
+
return origWrite(chunk, ...args);
|
|
259
|
+
};
|
|
260
|
+
res.end = (chunk, ...args) => {
|
|
261
|
+
decide();
|
|
262
|
+
if (gzip) {
|
|
263
|
+
if (chunk && typeof chunk !== 'function') gzip.write(chunk);
|
|
264
|
+
gzip.end();
|
|
265
|
+
return res;
|
|
266
|
+
}
|
|
267
|
+
return origEnd(chunk, ...args);
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
|
|
179
271
|
const server = createServer(async (req, res) => {
|
|
180
272
|
if (applyHttpGate(req, res)) return;
|
|
273
|
+
if (req.url?.startsWith('/api/')) gzipJsonResponse(req, res);
|
|
181
274
|
|
|
182
|
-
// /api/browser/*
|
|
275
|
+
// /api/browser/* must be handled inside the custom server (it shares
|
|
276
|
+
// BrowserBridge memory with the WS side)
|
|
183
277
|
if (req.url?.startsWith('/api/browser/') && req.method === 'POST') {
|
|
184
278
|
const handled = await handleBrowserApi(req, res);
|
|
185
279
|
if (handled) return;
|
|
@@ -207,19 +301,20 @@ app.prepare().then(async () => {
|
|
|
207
301
|
}
|
|
208
302
|
});
|
|
209
303
|
|
|
210
|
-
// COCKPIT_HOST:
|
|
304
|
+
// COCKPIT_HOST: defaults to 127.0.0.1 (local-only); set 0.0.0.0 for cloud
|
|
305
|
+
// sandboxes and similar environments
|
|
211
306
|
const host = process.env.COCKPIT_HOST || '127.0.0.1';
|
|
212
307
|
server.listen(port, host, () => {
|
|
213
308
|
const url = `http://localhost:${port}`;
|
|
214
309
|
console.log(`> Ready on ${url}`);
|
|
215
310
|
|
|
216
|
-
//
|
|
311
|
+
// Write server.json so CLI subcommands can read the port
|
|
217
312
|
try {
|
|
218
313
|
mkdirSync(cockpitHome, { recursive: true });
|
|
219
314
|
writeFileSync(join(cockpitHome, 'server.json'), JSON.stringify({ pid: process.pid, port }, null, 2));
|
|
220
315
|
} catch {}
|
|
221
316
|
|
|
222
|
-
// prod
|
|
317
|
+
// Auto-open the browser in prod mode (disable with --no-open)
|
|
223
318
|
if (!dev && !process.env.COCKPIT_NO_OPEN) {
|
|
224
319
|
const openProject = process.env.COCKPIT_OPEN_PROJECT;
|
|
225
320
|
const openUrl = openProject ? `${url}/?cwd=${encodeURIComponent(openProject)}` : url;
|
|
@@ -229,8 +324,8 @@ app.prepare().then(async () => {
|
|
|
229
324
|
});
|
|
230
325
|
|
|
231
326
|
// ============================================
|
|
232
|
-
// Share Server
|
|
233
|
-
//
|
|
327
|
+
// Share Server — LAN review-sharing service.
|
|
328
|
+
// Route allowlist: only /review/* and its supporting assets are exposed.
|
|
234
329
|
// ============================================
|
|
235
330
|
const sharePort = port + 1000; // dev 3456→4456, prod 3457→4457
|
|
236
331
|
|
|
@@ -260,8 +355,9 @@ app.prepare().then(async () => {
|
|
|
260
355
|
// Token gate first (share is also covered). Read the gate BEFORE we inject
|
|
261
356
|
// x-forwarded-for below, so the injection can't fool the local check.
|
|
262
357
|
if (applyHttpGate(req, res)) return;
|
|
358
|
+
if (req.url?.startsWith('/api/')) gzipJsonResponse(req, res);
|
|
263
359
|
if (isShareAllowed(req.url || '')) {
|
|
264
|
-
//
|
|
360
|
+
// Inject the client's real IP for /api/review/identify
|
|
265
361
|
const clientIp = req.socket.remoteAddress || '';
|
|
266
362
|
req.headers['x-forwarded-for'] = clientIp;
|
|
267
363
|
handle(req, res);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=7003,exports.ids=[7003],exports.modules={7939:(a,b,c)=>{c.d(b,{$A:()=>M,A0:()=>X,An:()=>$,BF:()=>I,Ct:()=>Q,Eu:()=>H,Ex:()=>u,GB:()=>r,JE:()=>Z,JY:()=>L,Ki:()=>C,Kk:()=>R,Kv:()=>j,LN:()=>k,Mx:()=>D,N9:()=>ac,O0:()=>B,Sr:()=>J,Tb:()=>s,Ux:()=>ab,Wd:()=>Y,aO:()=>m,at:()=>y,ec:()=>o,eg:()=>V,h9:()=>x,i4:()=>G,iK:()=>p,im:()=>T,iy:()=>P,jp:()=>t,lT:()=>z,lq:()=>F,ls:()=>K,mT:()=>w,n6:()=>n,oK:()=>O,oZ:()=>S,of:()=>E,po:()=>N,tP:()=>q,th:()=>v,v4:()=>l,vI:()=>W,yw:()=>U});var d=c(21820),e=c(33873),f=c(79748),g=c(29021),h=c(79646);let i=(0,d.homedir)(),j=process.env.COCKPIT_HOME?(0,e.resolve)(process.env.COCKPIT_HOME.replace(/^~(?=$|\/)/,i)):(0,e.join)(i,".cockpit"),k=(0,e.join)(j,"projects"),l=(0,e.join)(j,"state.json"),m=(0,e.join)(j,"pinned-sessions.json"),n=(0,e.join)(j,"push-subscriptions.json"),o=(0,e.join)(j,"note.md"),p=(0,e.join)(j,"scheduled-tasks.json"),q=(0,e.join)(j,"settings.json"),r=(0,e.join)(j,"skills.json"),s=(0,e.join)(j,"review"),t=(0,e.join)(s,"_signal");function u(){try{(0,g.existsSync)(s)||(0,g.mkdirSync)(s,{recursive:!0}),(0,g.writeFileSync)(t,Date.now().toString())}catch{}}let v=(0,e.join)(i,".claude"),w=(0,e.join)(v,"projects"),x=(0,e.join)(i,".claude2"),y=(0,e.join)(x,"projects"),z=(0,e.join)(j,"deepseek"),A=(0,e.join)(z,"projects");function B(a){return a.replace(/[/.]/g,"-")}function C(a){return(0,e.join)(k,B(a))}function D(a){return(0,e.join)(C(a),"session.json")}function E(a){return(0,e.join)(C(a),"recent-files.json")}function F(a){return(0,e.join)(C(a),"expanded-paths.json")}function G(a){return(0,e.join)(C(a),"comments.json")}function H(a){return(0,e.join)(C(a),"services.json")}function I(a){return(0,e.join)(C(a),"note.md")}function J(a,b){return(0,e.join)(C(a),`terminal-history-${b}.jsonl`)}function K(a,b){return(0,e.join)(C(a),`terminal-output-${b}.txt`)}function L(a,b){let c=b?`terminal-env-${b}.json`:"terminal-env-global.json";return(0,e.join)(C(a),c)}function M(){return(0,e.join)(j,"terminal-aliases.json")}function N(){return(0,e.join)(j,"services.json")}function O(a){return(0,e.join)(C(a),"project-settings.json")}function P(a,b){return(0,e.join)(C(a),`terminal-bubble-order-${b}.json`)}function Q(a){return(0,e.join)(s,`${a}.json`)}function R(a,b){return(0,e.join)((0,e.join)(w,B(a)),`${b}.jsonl`)}function S(a,b){return(0,e.join)((0,e.join)(y,B(a)),`${b}.jsonl`)}function T(a,b){return(0,e.join)((0,e.join)(A,B(a)),`${b}.jsonl`)}function U(a,b){return(0,e.join)((0,e.join)(j,"ollama-sessions",B(a)),`${b}.jsonl`)}function V(a){let b=(0,e.join)(i,".codex","sessions");if(!(0,g.existsSync)(b))return null;try{let c=(0,h.execSync)(`find ${JSON.stringify(b)} -name "*${a}.jsonl" -type f 2>/dev/null`,{encoding:"utf8",timeout:3e3}).trim();if(c)return c.split("\n")[0]}catch{}return null}function W(a){let b=(0,e.join)(i,".kimi","sessions");if(!(0,g.existsSync)(b))return null;try{for(let c of(0,g.readdirSync)(b)){let d=(0,e.join)(b,c,a,"context.jsonl");if((0,g.existsSync)(d))return d}}catch{}return null}async function X(a){(0,g.existsSync)(a)||await (0,f.mkdir)(a,{recursive:!0})}async function Y(a){let b=(0,e.join)(a,"..");await X(b)}async function Z(a,b){try{let b=await (0,f.readFile)(a,"utf-8");return JSON.parse(b)}catch{return b}}async function $(a,b){await Y(a),await (0,f.writeFile)(a,JSON.stringify(b,null,2),"utf-8")}let _=globalThis,aa=_.__cockpitFileLocks??(_.__cockpitFileLocks=new Map);function ab(a,b){let c=(aa.get(a)??Promise.resolve()).then(b),d=c.then(()=>{},()=>{});return aa.set(a,d),d.then(()=>{aa.get(a)===d&&aa.delete(a)}),c}function ac(a,b,c){return ab(a,async()=>{let d=await Z(a,b),e=await c(d);return await $(a,e),e})}},38433:(a,b,c)=>{c.d(b,{SG:()=>m,a_:()=>l,hO:()=>k,lG:()=>j});var d=c(51181),e=c.n(d),f=c(7939);let g=null,h="https://github.com/Surething-io/cockpit";async function i(){if(g)return g;let a=await (0,f.Ux)(f.tP,async()=>{let a=await (0,f.JE)(f.tP,{});if(a.push?.publicKey&&a.push?.privateKey){let b=!function(a){if(!a||a.includes("localhost"))return!1;if(a.startsWith("https://"))return!0;let b=/^mailto:[^\s@]+@([^\s@]+)$/.exec(a);return!!b&&b[1].includes(".")}(a.push.subject)?h:a.push.subject;return b!==a.push.subject&&await (0,f.An)(f.tP,{...a,push:{...a.push,subject:b}}),{publicKey:a.push.publicKey,privateKey:a.push.privateKey,subject:b}}let b=e().generateVAPIDKeys(),c={publicKey:b.publicKey,privateKey:b.privateKey,subject:h};return await (0,f.An)(f.tP,{...a,push:c}),c});return e().setVapidDetails(a.subject,a.publicKey,a.privateKey),g=a,a}async function j(){return(await i()).publicKey}async function k(a){await (0,f.Ux)(f.n6,async()=>{let b=await (0,f.JE)(f.n6,{subscriptions:[]});b.subscriptions.some(b=>b.endpoint===a.endpoint)||(b.subscriptions.push(a),await (0,f.An)(f.n6,b))})}async function l(a){await (0,f.Ux)(f.n6,async()=>{let b=await (0,f.JE)(f.n6,{subscriptions:[]}),c=b.subscriptions.filter(b=>b.endpoint!==a);c.length!==b.subscriptions.length&&await (0,f.An)(f.n6,{subscriptions:c})})}async function m(a){try{await i()}catch{return{sent:0,pruned:0}}let b=await (0,f.JE)(f.n6,{subscriptions:[]});if(0===b.subscriptions.length)return{sent:0,pruned:0};let c=JSON.stringify(a),d=[],g=0;return await Promise.all(b.subscriptions.map(async a=>{try{await e().sendNotification(a,c),g++}catch(c){let b=c?.statusCode;if(404===b||410===b)d.push(a.endpoint);else{let d=a.endpoint;try{d=new URL(a.endpoint).host}catch{}console.error(`[push] send failed (${b??"?"}) to ${d}: ${c?.body||c?.message||"unknown"}`)}}})),d.length&&await (0,f.Ux)(f.n6,async()=>{let a=await (0,f.JE)(f.n6,{subscriptions:[]});await (0,f.An)(f.n6,{subscriptions:a.subscriptions.filter(a=>!d.includes(a.endpoint))})}),{sent:g,pruned:d.length}}},72891:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{OZ:()=>o,RL:()=>n,k9:()=>p,ok:()=>l});var e=c(37625),f=c(52693),g=c(18412),h=c(89705),i=c(94506),j=c(770),k=a([i]);i=(k.then?(await k)():k)[0];let l=(a,b=200)=>new Response(JSON.stringify(a),{status:b,headers:{"content-type":"application/json"}}),m=a=>{let b=e.od(a);if(f.Ru(b)){let a=b.value,c=(0,j.Sh)(a);return new Response(JSON.stringify({error:(a=>{let b=a.message;if("string"==typeof b&&b.length>0)return b;let c=a.cause;if(c instanceof Error&&c.message.length>0)return c.message;switch(a._tag){case"ValidationError":return`Invalid ${a.field}: ${a.reason}`;case"NotFoundError":return`${a.resource} not found: ${a.id}`;case"PermissionError":return`Permission denied: ${a.action} on ${a.resource}`;case"DBError":return`${a.db} ${a.op} failed`;case"FSError":return`${a.op} ${a.path} failed`;case"WSError":return`${a.proto} ${a.kind} failed`;case"AgentError":return`${a.provider} ${a.kind} failed`;default:return a._tag}})(a),tag:a._tag}),{status:c,headers:{"content-type":"application/json"}})}return console.error("[handler] uncaught defect:\n"+e.j9(a)),new Response(JSON.stringify({error:"Internal Server Error",tag:"InternalError"}),{status:500,headers:{"content-type":"application/json"}})},n=a=>async b=>{let c=await i.s9.runPromiseExit(a(b));return g.YW(c,{onFailure:a=>m(a),onSuccess:a=>a})},o=a=>async(b,c)=>{let d=await c.params,e=await i.s9.runPromiseExit(a(b,d));return g.YW(e,{onFailure:a=>m(a),onSuccess:a=>a})},p=a=>h.$mh({try:()=>a.json(),catch:()=>new j.yI({field:"body",reason:"invalid JSON"})});d()}catch(a){d(a)}})}};
|