@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/.next-prod/trace-build
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"name":"run-webpack","duration":
|
|
1
|
+
[{"name":"run-webpack","duration":20216814,"timestamp":210001581,"id":14,"parentId":1,"tags":{},"startTime":1782998700158,"traceId":"01c8448817b155b6"},{"name":"run-typescript","duration":18380914,"timestamp":230222194,"id":1604,"parentId":1,"tags":{},"startTime":1782998720378,"traceId":"01c8448817b155b6"},{"name":"static-check","duration":1181334,"timestamp":248649550,"id":1607,"parentId":1,"tags":{},"startTime":1782998738806,"traceId":"01c8448817b155b6"},{"name":"static-generation","duration":6411700,"timestamp":249973703,"id":1879,"parentId":1,"tags":{},"startTime":1782998740130,"traceId":"01c8448817b155b6"},{"name":"collect-build-traces","duration":20480963,"timestamp":249831652,"id":1876,"parentId":1,"tags":{},"startTime":1782998739988,"traceId":"01c8448817b155b6"},{"name":"telemetry-flush","duration":72,"timestamp":270317441,"id":1888,"parentId":1,"tags":{},"startTime":1782998760474,"traceId":"01c8448817b155b6"},{"name":"next-build","duration":60489593,"timestamp":209827934,"id":1,"tags":{"buildMode":"default","version":"16.2.6","bundler":"webpack","has-custom-webpack-config":"true","use-build-worker":"false"},"startTime":1782998699984,"traceId":"01c8448817b155b6"}]
|
package/bin/cock-browser.mjs
CHANGED
|
@@ -332,12 +332,13 @@ async function fetchBrowserInfo(shortId) {
|
|
|
332
332
|
|
|
333
333
|
// Chunked evaluate result resolver
|
|
334
334
|
//
|
|
335
|
-
// Chrome extension
|
|
336
|
-
//
|
|
337
|
-
//
|
|
338
|
-
//
|
|
339
|
-
//
|
|
340
|
-
// payload
|
|
335
|
+
// Chrome extension runtime messaging has an implicit ~8 KiB structured-clone
|
|
336
|
+
// truncation point at the sendResponse boundary. To keep large evaluate
|
|
337
|
+
// results from being silently cut off, the extension side stashes any result
|
|
338
|
+
// >6 KiB in a Map on the page window and returns a
|
|
339
|
+
// { __cockpit_chunked: true, token, totalBytes, isString } descriptor.
|
|
340
|
+
// Whenever we see that descriptor here, we pull the full payload back via
|
|
341
|
+
// the evaluate_chunk action — fully transparent to formatOutput above.
|
|
341
342
|
async function fetchOneChunk(baseUrl, id, token, offset, cmdTimeout) {
|
|
342
343
|
const resp = await fetch(`${baseUrl}/api/browser/evaluate_chunk`, {
|
|
343
344
|
method: 'POST',
|
|
@@ -382,7 +383,8 @@ async function autoResolveChunked(baseUrl, id, data, cmdTimeout) {
|
|
|
382
383
|
if (data.__cockpit_chunked === true && typeof data.token === 'string') {
|
|
383
384
|
return await resolveChunkedDescriptor(baseUrl, id, data, cmdTimeout);
|
|
384
385
|
}
|
|
385
|
-
// allFrames=true
|
|
386
|
+
// With allFrames=true the aggregate may be an array, and each element
|
|
387
|
+
// may be independently chunked
|
|
386
388
|
if (Array.isArray(data)) {
|
|
387
389
|
return Promise.all(data.map(item => autoResolveChunked(baseUrl, id, item, cmdTimeout)));
|
|
388
390
|
}
|
|
@@ -491,8 +493,9 @@ async function run() {
|
|
|
491
493
|
process.exit(1);
|
|
492
494
|
}
|
|
493
495
|
|
|
494
|
-
//
|
|
495
|
-
//
|
|
496
|
+
// Large results are auto-stashed by the extension side, which returns a
|
|
497
|
+
// chunked descriptor; we transparently pull the full content back here —
|
|
498
|
+
// callers never see the chunking.
|
|
496
499
|
const resolved = await autoResolveChunked(baseUrl, id, data.data, timeout);
|
|
497
500
|
|
|
498
501
|
// Post-`type` verification — `type` via CDP dispatchKeyEvent silently no-ops
|
package/bin/cock.mjs
CHANGED
|
@@ -143,12 +143,12 @@ const knownCommands = new Set(['browser', 'terminal', 'update', 'help', 'codegra
|
|
|
143
143
|
const arg = process.argv[2];
|
|
144
144
|
let projectDir = null;
|
|
145
145
|
|
|
146
|
-
//
|
|
146
|
+
// First arg is neither a flag nor a known subcommand → treat it as a directory path
|
|
147
147
|
if (arg && !arg.startsWith('-') && !knownCommands.has(arg)) {
|
|
148
|
-
//
|
|
148
|
+
// Expand ~ to the home directory
|
|
149
149
|
const raw = arg.startsWith('~') ? arg.replace(/^~/, homedir()) : arg;
|
|
150
150
|
projectDir = resolve(raw);
|
|
151
|
-
//
|
|
151
|
+
// Create the directory if it doesn't exist
|
|
152
152
|
if (!existsSync(projectDir)) {
|
|
153
153
|
mkdirSync(projectDir, { recursive: true });
|
|
154
154
|
console.log(`Created ${projectDir}`);
|
|
@@ -173,7 +173,7 @@ const { exec } = await import('child_process');
|
|
|
173
173
|
const running = await isServerRunning();
|
|
174
174
|
|
|
175
175
|
if (running) {
|
|
176
|
-
//
|
|
176
|
+
// Server already running → open the browser and exit immediately
|
|
177
177
|
const base = `http://localhost:${port}`;
|
|
178
178
|
const url = projectDir ? `${base}/?cwd=${encodeURIComponent(projectDir)}` : base;
|
|
179
179
|
if (!process.env.COCKPIT_NO_OPEN) {
|
|
@@ -194,7 +194,7 @@ if (!isDev && !existsSync(resolve(PROJECT_ROOT, '.next-prod', 'BUILD_ID'))) {
|
|
|
194
194
|
process.exit(1);
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
//
|
|
197
|
+
// Hand the project directory to server.mjs so it opens the right URL
|
|
198
198
|
if (projectDir) {
|
|
199
199
|
process.env.COCKPIT_OPEN_PROJECT = projectDir;
|
|
200
200
|
}
|
package/bin/postinstall.mjs
CHANGED
|
@@ -21,7 +21,7 @@ try {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
if (process.platform !== 'win32') {
|
|
24
|
-
// node-pty: spawn-helper
|
|
24
|
+
// node-pty: spawn-helper needs the executable bit
|
|
25
25
|
try {
|
|
26
26
|
const spawnHelper = join(
|
|
27
27
|
projectRoot,
|
|
@@ -33,8 +33,8 @@ if (process.platform !== 'win32') {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// chrome-extension → ~/.cockpit/chrome-extension/
|
|
36
|
-
// npm
|
|
37
|
-
// npm link
|
|
36
|
+
// Installed via npm: projectRoot sits under node_modules (no src/ dir) → copy into the user dir.
|
|
37
|
+
// Via npm link: projectRoot is the source checkout (has src/) → no copy needed.
|
|
38
38
|
const isNpmInstall = !existsSync(join(projectRoot, 'src'));
|
|
39
39
|
if (isNpmInstall) {
|
|
40
40
|
try {
|
|
@@ -46,13 +46,13 @@ if (isNpmInstall) {
|
|
|
46
46
|
cpSync(src, dest, { recursive: true, force: true });
|
|
47
47
|
|
|
48
48
|
if (process.platform !== 'win32') {
|
|
49
|
-
// sudo
|
|
50
|
-
//
|
|
49
|
+
// Under a sudo install the files end up owned by root and Chrome can't
|
|
50
|
+
// write _metadata/ — restore ownership to the real user via SUDO_USER
|
|
51
51
|
const realUser = process.env.SUDO_USER;
|
|
52
52
|
if (realUser) {
|
|
53
53
|
try { execSync(`chown -R "${realUser}" "${cockpitDir}"`); } catch {}
|
|
54
54
|
}
|
|
55
|
-
// macOS:
|
|
55
|
+
// macOS: strip extended attributes like com.apple.provenance
|
|
56
56
|
if (process.platform === 'darwin') {
|
|
57
57
|
try { execSync(`xattr -cr "${dest}"`); } catch {}
|
|
58
58
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cockpit Browser Automation Layer (ES Module)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Injected into the Cockpit iframe; receives automation commands from
|
|
5
|
+
* BrowserBubble, builds the a11y tree, performs DOM operations, and
|
|
6
|
+
* returns results.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
8
|
+
* Dynamically import()-ed by activateCockpitBridge() in content.js.
|
|
9
|
+
* Runs in the content script isolated world (retains chrome.runtime access).
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
let _realParent = null;
|
|
@@ -14,7 +15,7 @@ let _chrome = null;
|
|
|
14
15
|
const LOG_PREFIX = '[Cockpit Automation]';
|
|
15
16
|
|
|
16
17
|
// ============================================================================
|
|
17
|
-
// Ref
|
|
18
|
+
// Ref system: assigns stable ref IDs to elements in the a11y tree
|
|
18
19
|
// ============================================================================
|
|
19
20
|
|
|
20
21
|
let refCounter = 0;
|
|
@@ -91,7 +92,7 @@ function findByRef(ref) {
|
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
// ============================================================================
|
|
94
|
-
// A11y Tree
|
|
95
|
+
// A11y Tree construction
|
|
95
96
|
// ============================================================================
|
|
96
97
|
|
|
97
98
|
const IMPLICIT_ROLES = {
|
|
@@ -284,7 +285,7 @@ function safeRegex(src) {
|
|
|
284
285
|
}
|
|
285
286
|
|
|
286
287
|
// ============================================================================
|
|
287
|
-
// Console
|
|
288
|
+
// Console interception
|
|
288
289
|
// ============================================================================
|
|
289
290
|
|
|
290
291
|
const consoleBuffer = [];
|
|
@@ -312,24 +313,26 @@ function initConsoleCapture() {
|
|
|
312
313
|
}
|
|
313
314
|
|
|
314
315
|
// ============================================================================
|
|
315
|
-
// Network
|
|
316
|
+
// Network capture (receives entries sent via CustomEvent from the Main
|
|
317
|
+
// World's network-capture.js)
|
|
316
318
|
//
|
|
317
|
-
// fetch / XHR
|
|
318
|
-
//
|
|
319
|
+
// fetch / XHR interception runs in the Main World (network-capture.js);
|
|
320
|
+
// this layer is only responsible for: storing the buffer, managing
|
|
321
|
+
// recording state, and handling CLI commands.
|
|
319
322
|
// ============================================================================
|
|
320
323
|
|
|
321
324
|
const networkBuffer = [];
|
|
322
325
|
const MAX_NETWORK_BUFFER = 500;
|
|
323
326
|
|
|
324
|
-
//
|
|
327
|
+
// Recording state: managed by this layer, synced to the Main World via CustomEvent
|
|
325
328
|
const networkRecording = {
|
|
326
329
|
active: false,
|
|
327
330
|
filters: {}, // { url, method, status }
|
|
328
|
-
timer: null, //
|
|
331
|
+
timer: null, // auto-expiry timer
|
|
329
332
|
startedAt: 0,
|
|
330
333
|
};
|
|
331
334
|
|
|
332
|
-
//
|
|
335
|
+
// Clear body data from all entries (called on expiry)
|
|
333
336
|
function clearAllBodies() {
|
|
334
337
|
for (const entry of networkBuffer) {
|
|
335
338
|
entry.requestHeaders = null;
|
|
@@ -339,32 +342,32 @@ function clearAllBodies() {
|
|
|
339
342
|
}
|
|
340
343
|
}
|
|
341
344
|
|
|
342
|
-
//
|
|
345
|
+
// Sync recording state to the Main World's network-capture.js
|
|
343
346
|
function syncRecordingToMainWorld() {
|
|
344
347
|
window.dispatchEvent(new CustomEvent('cockpit:network-recording', {
|
|
345
348
|
detail: { active: networkRecording.active, filters: networkRecording.filters },
|
|
346
349
|
}));
|
|
347
350
|
}
|
|
348
351
|
|
|
349
|
-
//
|
|
352
|
+
// Listen for network entries sent from the Main World
|
|
350
353
|
function initNetworkListener() {
|
|
351
|
-
//
|
|
354
|
+
// Placeholder entry received when a request starts (preserves initiation order)
|
|
352
355
|
window.addEventListener('cockpit:network-entry', (e) => {
|
|
353
356
|
networkBuffer.push(e.detail);
|
|
354
357
|
if (networkBuffer.length > MAX_NETWORK_BUFFER) networkBuffer.splice(0, 1);
|
|
355
358
|
});
|
|
356
|
-
//
|
|
359
|
+
// Update received when the response completes (fills in status / duration / body etc.)
|
|
357
360
|
window.addEventListener('cockpit:network-update', (e) => {
|
|
358
361
|
const update = e.detail;
|
|
359
362
|
const entry = networkBuffer.find(r => r.id === update.id);
|
|
360
363
|
if (entry) Object.assign(entry, update);
|
|
361
364
|
});
|
|
362
|
-
//
|
|
365
|
+
// Notify the Main World: the Isolated World is ready, cached entries can be flushed
|
|
363
366
|
window.dispatchEvent(new CustomEvent('cockpit:network-bridge-ready'));
|
|
364
367
|
}
|
|
365
368
|
|
|
366
369
|
// ============================================================================
|
|
367
|
-
//
|
|
370
|
+
// Command handlers
|
|
368
371
|
// ============================================================================
|
|
369
372
|
|
|
370
373
|
const handlers = {
|
|
@@ -382,7 +385,7 @@ const handlers = {
|
|
|
382
385
|
buildA11yTree(document.body, { filter, includeHiddenText, maxDepth }),
|
|
383
386
|
|
|
384
387
|
screenshot: async () => {
|
|
385
|
-
// 1)
|
|
388
|
+
// 1) Notify the parent page (project iframe): switch to console view + switch to this project + return the iframe bounds
|
|
386
389
|
const boundsReqId = 'ss-' + Date.now();
|
|
387
390
|
const bounds = await new Promise((resolve, reject) => {
|
|
388
391
|
const timeout = setTimeout(() => reject(new Error('Timeout preparing screenshot')), 5000);
|
|
@@ -397,7 +400,7 @@ const handlers = {
|
|
|
397
400
|
_realParent.postMessage({ type: 'cockpit:prepare-screenshot', reqId: boundsReqId }, '*');
|
|
398
401
|
});
|
|
399
402
|
|
|
400
|
-
// 2) captureVisibleTab
|
|
403
|
+
// 2) captureVisibleTab captures the entire browser tab
|
|
401
404
|
const dataUrl = await new Promise((resolve, reject) => {
|
|
402
405
|
_chrome.runtime.sendMessage({ type: 'cockpit:capture-tab' }, (response) => {
|
|
403
406
|
if (_chrome.runtime.lastError) { reject(new Error(_chrome.runtime.lastError.message)); return; }
|
|
@@ -406,7 +409,7 @@ const handlers = {
|
|
|
406
409
|
});
|
|
407
410
|
});
|
|
408
411
|
|
|
409
|
-
// 3)
|
|
412
|
+
// 3) Crop to the iframe area
|
|
410
413
|
const img = new Image();
|
|
411
414
|
await new Promise((resolve, reject) => { img.onload = resolve; img.onerror = reject; img.src = dataUrl; });
|
|
412
415
|
const cropCanvas = document.createElement('canvas');
|
|
@@ -416,7 +419,7 @@ const handlers = {
|
|
|
416
419
|
cropCtx.drawImage(img, bounds.x, bounds.y, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height);
|
|
417
420
|
const result = cropCanvas.toDataURL('image/png');
|
|
418
421
|
|
|
419
|
-
// 4)
|
|
422
|
+
// 4) Notify the parent page the screenshot is done, restore the UI
|
|
420
423
|
_realParent.postMessage({ type: 'cockpit:screenshot-done' }, '*');
|
|
421
424
|
|
|
422
425
|
return { image: result, format: 'png' };
|
|
@@ -659,11 +662,11 @@ const handlers = {
|
|
|
659
662
|
},
|
|
660
663
|
|
|
661
664
|
evaluate: async ({ js, allFrames }) => {
|
|
662
|
-
//
|
|
663
|
-
//
|
|
664
|
-
// allFrames: true →
|
|
665
|
-
//
|
|
666
|
-
// cock-browser CLI
|
|
665
|
+
// Executed in the main world via background.js's chrome.scripting.executeScript.
|
|
666
|
+
// Not restricted by the page's CSP; can access page JS variables (React state, etc.).
|
|
667
|
+
// allFrames: true → execute in all frames (solves cross-origin iframe access).
|
|
668
|
+
// Large results (>6 KiB) are auto-stashed in the MAIN world and returned as a descriptor;
|
|
669
|
+
// the cock-browser CLI recognizes the descriptor and backfills the content via evaluate_chunk.
|
|
667
670
|
return new Promise((resolve) => {
|
|
668
671
|
_chrome.runtime.sendMessage({ type: 'cockpit:evaluate', js, allFrames: !!allFrames }, (response) => {
|
|
669
672
|
if (_chrome.runtime.lastError) {
|
|
@@ -677,13 +680,15 @@ const handlers = {
|
|
|
677
680
|
},
|
|
678
681
|
|
|
679
682
|
evaluate_chunk: async ({ token, offset = 0, size = 5000 }) => {
|
|
680
|
-
//
|
|
681
|
-
//
|
|
682
|
-
//
|
|
683
|
+
// Reads a slice of a token's content from the MAIN-world stash. The token
|
|
684
|
+
// comes from the descriptor returned by the previous evaluate. Note the
|
|
685
|
+
// stash lives on the page window, so page navigation/reload loses it;
|
|
686
|
+
// must be the same browser session and the same page context.
|
|
683
687
|
//
|
|
684
|
-
//
|
|
685
|
-
// size
|
|
686
|
-
//
|
|
688
|
+
// Returns { chunk, done, nextOffset, totalBytes, isString };
|
|
689
|
+
// size defaults to 5000 to keep each returned object's JSON serialization
|
|
690
|
+
// < 6000, well below Chrome's ~8192-byte implicit truncation threshold at
|
|
691
|
+
// the chrome.runtime message boundary.
|
|
687
692
|
const offNum = Number(offset) || 0;
|
|
688
693
|
const szNum = Math.min(Math.max(1, Number(size) || 5000), 7000);
|
|
689
694
|
const tokStr = String(token);
|
|
@@ -755,10 +760,10 @@ const handlers = {
|
|
|
755
760
|
};
|
|
756
761
|
},
|
|
757
762
|
|
|
758
|
-
//
|
|
763
|
+
// Recording control: start begins body capture, stop ends it, status shows state
|
|
759
764
|
network_record: async ({ action = 'status', url, method, status, ttl = 600 }) => {
|
|
760
765
|
if (action === 'start') {
|
|
761
|
-
//
|
|
766
|
+
// Clear the old expiry timer
|
|
762
767
|
if (networkRecording.timer) clearTimeout(networkRecording.timer);
|
|
763
768
|
networkRecording.active = true;
|
|
764
769
|
networkRecording.filters = {};
|
|
@@ -767,7 +772,7 @@ const handlers = {
|
|
|
767
772
|
if (status) networkRecording.filters.status = status;
|
|
768
773
|
networkRecording.startedAt = Date.now();
|
|
769
774
|
syncRecordingToMainWorld();
|
|
770
|
-
// ttl
|
|
775
|
+
// Auto-expire after ttl seconds (default 10 minutes)
|
|
771
776
|
networkRecording.timer = setTimeout(() => {
|
|
772
777
|
networkRecording.active = false;
|
|
773
778
|
clearAllBodies();
|
|
@@ -784,7 +789,7 @@ const handlers = {
|
|
|
784
789
|
networkRecording.active = false;
|
|
785
790
|
if (networkRecording.timer) { clearTimeout(networkRecording.timer); networkRecording.timer = null; }
|
|
786
791
|
syncRecordingToMainWorld();
|
|
787
|
-
//
|
|
792
|
+
// Don't clear bodies immediately after stopping; allow querying the recorded data
|
|
788
793
|
return { recording: false, recordedCount: networkBuffer.filter(r => r.recorded).length };
|
|
789
794
|
}
|
|
790
795
|
// status
|
|
@@ -1299,7 +1304,7 @@ function simpleJsonPath(data, path) {
|
|
|
1299
1304
|
}
|
|
1300
1305
|
|
|
1301
1306
|
// ============================================================================
|
|
1302
|
-
//
|
|
1307
|
+
// Command dispatch
|
|
1303
1308
|
// ============================================================================
|
|
1304
1309
|
|
|
1305
1310
|
function handleCommand(event) {
|
|
@@ -1357,7 +1362,7 @@ function bagCounts(s) {
|
|
|
1357
1362
|
}
|
|
1358
1363
|
|
|
1359
1364
|
// ============================================================================
|
|
1360
|
-
//
|
|
1365
|
+
// Exported initialization function
|
|
1361
1366
|
// ============================================================================
|
|
1362
1367
|
|
|
1363
1368
|
export function initAutomation(realParent, chromeApi) {
|