@wjarka/cezarion 0.14.8 → 0.14.9-dev.829
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/README.md +76 -2
- package/dist/application-update/bin-recovery.d.ts +5 -0
- package/dist/application-update/bin-recovery.js +96 -0
- package/dist/application-update/bin-recovery.js.map +1 -0
- package/dist/application-update/discovery.d.ts +22 -0
- package/dist/application-update/discovery.js +91 -0
- package/dist/application-update/discovery.js.map +1 -0
- package/dist/application-update/helper.d.ts +57 -0
- package/dist/application-update/helper.js +374 -0
- package/dist/application-update/helper.js.map +1 -0
- package/dist/application-update/launcher.d.ts +8 -0
- package/dist/application-update/launcher.js +53 -0
- package/dist/application-update/launcher.js.map +1 -0
- package/dist/application-update/lock.d.ts +4 -0
- package/dist/application-update/lock.js +70 -0
- package/dist/application-update/lock.js.map +1 -0
- package/dist/application-update/npm-process.d.ts +17 -0
- package/dist/application-update/npm-process.js +133 -0
- package/dist/application-update/npm-process.js.map +1 -0
- package/dist/application-update/service.d.ts +69 -0
- package/dist/application-update/service.js +456 -0
- package/dist/application-update/service.js.map +1 -0
- package/dist/artifacts/cli.d.ts +1 -0
- package/dist/artifacts/cli.js +32 -0
- package/dist/artifacts/cli.js.map +1 -0
- package/dist/artifacts/lifecycle.d.ts +4 -0
- package/dist/artifacts/lifecycle.js +42 -0
- package/dist/artifacts/lifecycle.js.map +1 -0
- package/dist/artifacts/resolve.d.ts +18 -0
- package/dist/artifacts/resolve.js +102 -0
- package/dist/artifacts/resolve.js.map +1 -0
- package/dist/artifacts/store.d.ts +8 -0
- package/dist/artifacts/store.js +323 -0
- package/dist/artifacts/store.js.map +1 -0
- package/dist/ci-wait/mcp.d.ts +3 -0
- package/dist/ci-wait/mcp.js +14 -3
- package/dist/ci-wait/mcp.js.map +1 -1
- package/dist/contract/application-update.d.ts +32 -0
- package/dist/contract/artifacts.d.ts +83 -0
- package/dist/contract/ask-schema.d.ts +32 -0
- package/dist/contract/ask.d.ts +2 -32
- package/dist/contract/conversations.d.ts +165 -0
- package/dist/contract/delegation.d.ts +39 -0
- package/dist/contract/events.d.ts +49 -0
- package/dist/contract/health.d.ts +12 -0
- package/dist/contract/index.d.ts +2 -0
- package/dist/contract/index.js +1374 -1247
- package/dist/contract/runs.d.ts +143 -0
- package/dist/contract/skills.d.ts +28 -0
- package/dist/core/agent-runner.d.ts +33 -4
- package/dist/core/agent-runner.js +5 -0
- package/dist/core/agent-runner.js.map +1 -1
- package/dist/core/claude-cli-runner.d.ts +6 -12
- package/dist/core/claude-cli-runner.js +89 -19
- package/dist/core/claude-cli-runner.js.map +1 -1
- package/dist/core/codex-app-server-runner.d.ts +2 -1
- package/dist/core/codex-app-server-runner.js +327 -92
- package/dist/core/codex-app-server-runner.js.map +1 -1
- package/dist/core/codex-app-server-transport.d.ts +13 -1
- package/dist/core/codex-app-server-transport.js +58 -17
- package/dist/core/codex-app-server-transport.js.map +1 -1
- package/dist/core/cursor-acp-runner.d.ts +4 -1
- package/dist/core/cursor-acp-runner.js +3 -0
- package/dist/core/cursor-acp-runner.js.map +1 -1
- package/dist/core/cursor-provider-error.js +3 -1
- package/dist/core/cursor-provider-error.js.map +1 -1
- package/dist/core/input-submissions.d.ts +14 -0
- package/dist/core/input-submissions.js +26 -0
- package/dist/core/input-submissions.js.map +1 -0
- package/dist/core/opencode-server-runner.d.ts +4 -1
- package/dist/core/opencode-server-runner.js +144 -21
- package/dist/core/opencode-server-runner.js.map +1 -1
- package/dist/core/pi-runner.d.ts +2 -1
- package/dist/core/pi-runner.js +72 -7
- package/dist/core/pi-runner.js.map +1 -1
- package/dist/delegation/cli.js +102 -6
- package/dist/delegation/cli.js.map +1 -1
- package/dist/delegation/conversations.js +13 -5
- package/dist/delegation/conversations.js.map +1 -1
- package/dist/delegation/input.d.ts +2 -1
- package/dist/delegation/input.js +6 -1
- package/dist/delegation/input.js.map +1 -1
- package/dist/delegation/provision.js +5 -3
- package/dist/delegation/provision.js.map +1 -1
- package/dist/delegation/questions.d.ts +19 -0
- package/dist/delegation/questions.js +45 -0
- package/dist/delegation/questions.js.map +1 -0
- package/dist/delegation/results.d.ts +1 -1
- package/dist/delegation/results.js +23 -13
- package/dist/delegation/results.js.map +1 -1
- package/dist/delegation/routes.d.ts +142 -15
- package/dist/delegation/routes.js +4 -1
- package/dist/delegation/routes.js.map +1 -1
- package/dist/delegation/service.d.ts +9 -5
- package/dist/delegation/service.js +106 -7
- package/dist/delegation/service.js.map +1 -1
- package/dist/delegation/transport.d.ts +138 -11
- package/dist/index.js +72 -26
- package/dist/index.js.map +1 -1
- package/dist/open-url.d.ts +2 -0
- package/dist/open-url.js +20 -0
- package/dist/open-url.js.map +1 -0
- package/dist/release/snapshot.d.ts +3 -3
- package/dist/release/snapshot.js +6 -6
- package/dist/release/snapshot.js.map +1 -1
- package/dist/runs/client-request.d.ts +11 -0
- package/dist/runs/client-request.js +26 -0
- package/dist/runs/client-request.js.map +1 -0
- package/dist/runs/delegation-state.d.ts +17 -0
- package/dist/runs/event-history.js +6 -0
- package/dist/runs/event-history.js.map +1 -1
- package/dist/runs/store.d.ts +78 -6
- package/dist/runs/store.js +163 -1
- package/dist/runs/store.js.map +1 -1
- package/dist/server/server.d.ts +3761 -1648
- package/dist/server/server.js +170 -4
- package/dist/server/server.js.map +1 -1
- package/dist/task-cli/cli.d.ts +38 -0
- package/dist/task-cli/cli.js +463 -0
- package/dist/task-cli/cli.js.map +1 -0
- package/dist/task-cli/discovery.d.ts +22 -0
- package/dist/task-cli/discovery.js +95 -0
- package/dist/task-cli/discovery.js.map +1 -0
- package/dist/task-cli/http.d.ts +43 -0
- package/dist/task-cli/http.js +101 -0
- package/dist/task-cli/http.js.map +1 -0
- package/dist/task-cli/projections.d.ts +40 -0
- package/dist/task-cli/projections.js +45 -0
- package/dist/task-cli/projections.js.map +1 -0
- package/dist/task-cli/watch.d.ts +78 -0
- package/dist/task-cli/watch.js +336 -0
- package/dist/task-cli/watch.js.map +1 -0
- package/dist/workflows/run.d.ts +93 -0
- package/dist/workflows/run.js +816 -81
- package/dist/workflows/run.js.map +1 -1
- package/dist/workspace/projects-cli.js +1 -1
- package/package.json +3 -3
- package/scripts/mock-claude.mjs +38 -2
- package/scripts/mock-codex-app-server.mjs +98 -1
- package/scripts/mock-cursor-acp.mjs +3 -0
- package/scripts/mock-opencode-serve.mjs +69 -2
- package/scripts/mock-pi-rpc.mjs +63 -2
- package/web/dist/assets/agent-accounts-JPfZPgKn.js +1 -0
- package/web/dist/assets/centered-state-HwCqQkH3.js +43 -0
- package/web/dist/assets/collapsible-CTymFdL7.js +1 -0
- package/web/dist/assets/commit-list-BZpYGQl2.js +1 -0
- package/web/dist/assets/compare-variants-9VkybaQ7.js +1 -0
- package/web/dist/assets/{diff-tRE59UNb2.js → diff-CZcD4D1r2.js} +2 -2
- package/web/dist/assets/diff-controls-CpcHG3Mm.js +1 -0
- package/web/dist/assets/{diff-stat-Cgnl_hYF.js → diff-stat-Cn7rzy1H.js} +1 -1
- package/web/dist/assets/{diff-view-DN1ort7Q.js → diff-view-C46nHiP2.js} +2 -2
- package/web/dist/assets/dropdown-menu-_YAzCaoQ.js +1 -0
- package/web/dist/assets/git-toolbar-BvKDz6uS.js +1 -0
- package/web/dist/assets/github-CgjJCGrD.js +1 -0
- package/web/dist/assets/{image-preview-C2JGcBlC.js → image-preview-B618kDBH.js} +1 -1
- package/web/dist/assets/index-BJtve0Pm.js +7 -0
- package/web/dist/assets/index-D0WAgmTQ.css +1 -0
- package/web/dist/assets/markdown-CFWZnvMh.js +2 -0
- package/web/dist/assets/pill-QfwkuR50.js +1 -0
- package/web/dist/assets/project-router-CkAA39N5.js +1 -0
- package/web/dist/assets/prompt-templates-Cfna_S0T.js +15 -0
- package/web/dist/assets/repo-git-DgzgJ0cP.js +1 -0
- package/web/dist/assets/{run-diff-CyG0Nciv.js → run-diff-YbCEQn5I.js} +2 -2
- package/web/dist/assets/run-header-DMgIbr1d.js +1 -0
- package/web/dist/assets/skills-BW79kUTd.js +1 -0
- package/web/dist/assets/{tab-link-BWNp3mLY.js → tab-link-MIHvczEm.js} +1 -1
- package/web/dist/assets/task-changes-C96ekt94.js +1 -0
- package/web/dist/assets/task-commits-DBfcMZyG.js +1 -0
- package/web/dist/assets/task-files-BKpH8dKQ.js +2 -0
- package/web/dist/assets/task-thread-Bw_nQuTx.css +1 -0
- package/web/dist/assets/task-thread-Dnq7Ek6W.js +9 -0
- package/web/dist/assets/textarea-D2vAVgYW.js +1 -0
- package/web/dist/assets/thread-loading-NW8Mthco.js +1 -0
- package/web/dist/assets/token-metrics-D188e6_0.js +1 -0
- package/web/dist/assets/utils-DKheTxGD.js +64 -0
- package/web/dist/assets/workflows-BFY1hgp3.js +11 -0
- package/web/dist/assets/{zoomable-image-Z3JDnm0b.js → zoomable-image-YW3Qdrr_.js} +1 -1
- package/web/dist/index.html +14 -14
- package/web/dist/assets/agent-accounts-BZm_2WAv.js +0 -1
- package/web/dist/assets/alert-dialog-B422RI-k.js +0 -43
- package/web/dist/assets/collapsible-Cy_Fmkrd.js +0 -1
- package/web/dist/assets/commit-list-Dcnk7TnI.js +0 -1
- package/web/dist/assets/compare-variants-Ciqwvd_f.js +0 -1
- package/web/dist/assets/diff-controls-BGrXGi7O.js +0 -1
- package/web/dist/assets/dropdown-menu-dwDGT8MM.js +0 -1
- package/web/dist/assets/git-toolbar-UiHnGvE0.js +0 -1
- package/web/dist/assets/github-D-MrkbJ7.js +0 -1
- package/web/dist/assets/ibm-plex-mono-regular-BF3vfe7_.ttf +0 -0
- package/web/dist/assets/index-BszfYvBq.js +0 -7
- package/web/dist/assets/index-CWh4pKP3.css +0 -1
- package/web/dist/assets/markdown-C_IcKVQd.js +0 -2
- package/web/dist/assets/pill-BsbO6G7y.js +0 -1
- package/web/dist/assets/project-router-DbLkll25.js +0 -1
- package/web/dist/assets/prompt-templates-BlTGJB5W.js +0 -15
- package/web/dist/assets/repo-git-Bm3s6Why.js +0 -1
- package/web/dist/assets/run-header-IFyIGCey.js +0 -1
- package/web/dist/assets/skills-C-C4DVFY.js +0 -1
- package/web/dist/assets/task-changes-D2PHtWUW.js +0 -1
- package/web/dist/assets/task-commits-N5u9U0_R.js +0 -1
- package/web/dist/assets/task-files-BS7c7CFm.js +0 -2
- package/web/dist/assets/task-thread-BQFdz1dJ.css +0 -1
- package/web/dist/assets/task-thread-DGM2dZV-.js +0 -9
- package/web/dist/assets/textarea-FjaU370i.js +0 -1
- package/web/dist/assets/thread-loading-77sJ8Yu_.js +0 -1
- package/web/dist/assets/token-metrics-Clxh03bE.js +0 -1
- package/web/dist/assets/utils-PYYcpCFZ.js +0 -64
- package/web/dist/assets/workflows-Czl0ZfXH.js +0 -11
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type DiscoverOptions } from './discovery.ts';
|
|
2
|
+
import { type Cockpit } from './http.ts';
|
|
3
|
+
/**
|
|
4
|
+
* `cez task` — start, watch and steer cockpit tasks from a terminal or a bot (#504, spec
|
|
5
|
+
* 2026-09-24-cez-task-cli). A thin JSON client over the cockpit's own run routes: one JSON
|
|
6
|
+
* object per invocation, and an exit code a caller can branch on without parsing a status.
|
|
7
|
+
*/
|
|
8
|
+
export declare const EXIT: {
|
|
9
|
+
readonly ok: 0;
|
|
10
|
+
readonly failed: 1;
|
|
11
|
+
readonly refused: 2;
|
|
12
|
+
readonly timeout: 3;
|
|
13
|
+
readonly usage: 64;
|
|
14
|
+
};
|
|
15
|
+
export interface TaskIo {
|
|
16
|
+
stdout(line: string): void;
|
|
17
|
+
/** The whole of stdin, for `--task-file -` / `--text-file -`. */
|
|
18
|
+
stdin?: () => Promise<string>;
|
|
19
|
+
discover?: (options: DiscoverOptions) => Promise<Cockpit>;
|
|
20
|
+
open?: (url: string) => void;
|
|
21
|
+
/** `wait`'s poll interval; tests shorten it. */
|
|
22
|
+
pollMs?: number;
|
|
23
|
+
}
|
|
24
|
+
type FlagSpec = {
|
|
25
|
+
type: 'string' | 'boolean';
|
|
26
|
+
multiple?: boolean;
|
|
27
|
+
help: string;
|
|
28
|
+
};
|
|
29
|
+
interface Operation {
|
|
30
|
+
args: string;
|
|
31
|
+
description: string;
|
|
32
|
+
positionals: [min: number, max: number];
|
|
33
|
+
flags: Record<string, FlagSpec>;
|
|
34
|
+
}
|
|
35
|
+
export declare const OPERATIONS: Record<string, Operation>;
|
|
36
|
+
export declare function taskHelp(operation?: string): string;
|
|
37
|
+
export declare function runTaskCommand(argv: string[], env: NodeJS.ProcessEnv, io?: TaskIo): Promise<number>;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { open as openFile } from 'node:fs/promises';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { parseArgs } from 'node:util';
|
|
5
|
+
import { apiRunSchema, cancelResponseSchema, changesPayloadSchema, finishResponseSchema, messageResponseSchema, runHistoryContextSchema, runRecordSchema, runStatusSchema, } from '../contract/index.js';
|
|
6
|
+
import { openUrl } from '../open-url.js';
|
|
7
|
+
import { discoverCockpit } from './discovery.js';
|
|
8
|
+
import { invalidResponse, refuse, request, TaskCliError, threadUrl } from './http.js';
|
|
9
|
+
import { projectListRow, projectStatus } from './projections.js';
|
|
10
|
+
import { readLog, waitForRuns } from './watch.js';
|
|
11
|
+
/**
|
|
12
|
+
* `cez task` — start, watch and steer cockpit tasks from a terminal or a bot (#504, spec
|
|
13
|
+
* 2026-09-24-cez-task-cli). A thin JSON client over the cockpit's own run routes: one JSON
|
|
14
|
+
* object per invocation, and an exit code a caller can branch on without parsing a status.
|
|
15
|
+
*/
|
|
16
|
+
export const EXIT = { ok: 0, failed: 1, refused: 2, timeout: 3, usage: 64 };
|
|
17
|
+
const COMMON = {
|
|
18
|
+
url: { type: 'string', help: '<origin> Cockpit to use instead of discovery (also CEZ_URL).' },
|
|
19
|
+
repo: { type: 'string', help: '<dir> Checkout whose cockpit to find (default: cwd).' },
|
|
20
|
+
help: { type: 'boolean', help: ' Show help; needs no cockpit.' },
|
|
21
|
+
};
|
|
22
|
+
const TASK_TEXT_MAX_CHARS = 100_000;
|
|
23
|
+
const DEFAULT_TIMEOUT_SECONDS = 600;
|
|
24
|
+
const MAX_TIMEOUT_SECONDS = 1_800;
|
|
25
|
+
const TIMEOUT_FLAG = { type: 'string', help: `<1-${MAX_TIMEOUT_SECONDS}> Give up after this many seconds (default ${DEFAULT_TIMEOUT_SECONDS}).` };
|
|
26
|
+
export const OPERATIONS = {
|
|
27
|
+
start: {
|
|
28
|
+
args: "'<task>' | --task-file <path|->",
|
|
29
|
+
description: 'Start a task in the cockpit serving this checkout.',
|
|
30
|
+
positionals: [0, 1],
|
|
31
|
+
flags: {
|
|
32
|
+
'task-file': { type: 'string', help: '<path|-> Read the task from a file, or stdin with -.' },
|
|
33
|
+
'request-id': { type: 'string', help: '<UUID> Retry-safe id; reuse it when retrying this start.' },
|
|
34
|
+
workflow: { type: 'string', help: '<name> Workflow (default quick-task).' },
|
|
35
|
+
backend: { type: 'string', help: '<id> claude | codex | opencode | pi | cursor.' },
|
|
36
|
+
model: { type: 'string', help: '<model> Model override.' },
|
|
37
|
+
effort: { type: 'string', help: '<level> Reasoning effort.' },
|
|
38
|
+
autonomous: { type: 'boolean', help: ' Never park for input; run to completion.' },
|
|
39
|
+
'no-worktree': { type: 'boolean', help: ' Run in the repo working tree, not a worktree.' },
|
|
40
|
+
wait: { type: 'boolean', help: ' Then wait until the task settles (see wait).' },
|
|
41
|
+
'timeout-seconds': TIMEOUT_FLAG,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
list: {
|
|
45
|
+
args: '',
|
|
46
|
+
description: 'List tasks, newest first.',
|
|
47
|
+
positionals: [0, 0],
|
|
48
|
+
flags: {
|
|
49
|
+
status: { type: 'string', help: '<s>[,<s>…] Only these statuses.' },
|
|
50
|
+
limit: { type: 'string', help: '<n> At most n rows (default 20).' },
|
|
51
|
+
all: { type: 'boolean', help: ' Include archived tasks.' },
|
|
52
|
+
full: { type: 'boolean', help: ' Print contract ApiRun rows.' },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
status: {
|
|
56
|
+
args: '<id>',
|
|
57
|
+
description: 'Show one task.',
|
|
58
|
+
positionals: [1, 1],
|
|
59
|
+
flags: { full: { type: 'boolean', help: ' Print the contract ApiRun.' } },
|
|
60
|
+
},
|
|
61
|
+
log: {
|
|
62
|
+
args: '<id>',
|
|
63
|
+
description: "Print a task's recent transcript as JSON lines, oldest first.",
|
|
64
|
+
positionals: [1, 1],
|
|
65
|
+
flags: {
|
|
66
|
+
since: { type: 'string', help: '<seq> Only events after this seq.' },
|
|
67
|
+
'max-chars': { type: 'string', help: '<n> Keep the newest lines within n characters (default 8000).' },
|
|
68
|
+
follow: { type: 'boolean', help: ' Keep streaming until the task ends or the timeout.' },
|
|
69
|
+
'timeout-seconds': TIMEOUT_FLAG,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
wait: {
|
|
73
|
+
args: '<id>...',
|
|
74
|
+
description: 'Block until the tasks settle; exit 0 done/review, 1 failed/cancelled, 3 timeout.',
|
|
75
|
+
positionals: [1, 32],
|
|
76
|
+
flags: {
|
|
77
|
+
mode: { type: 'string', help: '<any|all> Return on the first task or on all of them (default all).' },
|
|
78
|
+
until: { type: 'string', help: '<settled|attention> Also stop on waiting or a pending question (attention).' },
|
|
79
|
+
'timeout-seconds': TIMEOUT_FLAG,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
send: {
|
|
83
|
+
args: "<id> '<text>' | <id> --text-file <path|->",
|
|
84
|
+
description: 'Steer a task: deliver, queue or (with --resume) reopen.',
|
|
85
|
+
positionals: [1, 2],
|
|
86
|
+
flags: {
|
|
87
|
+
'text-file': { type: 'string', help: '<path|-> Read the text from a file, or stdin with -.' },
|
|
88
|
+
resume: { type: 'boolean', help: ' Reopen a closed session with this text.' },
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
stop: { args: '<id>', description: 'Cancel a task.', positionals: [1, 1], flags: {} },
|
|
92
|
+
finish: { args: '<id>', description: 'Close a waiting session as done.', positionals: [1, 1], flags: {} },
|
|
93
|
+
diff: {
|
|
94
|
+
args: '<id>',
|
|
95
|
+
description: "Show a task's changes.",
|
|
96
|
+
positionals: [1, 1],
|
|
97
|
+
flags: { stat: { type: 'boolean', help: ' Per-file counts instead of the patch.' } },
|
|
98
|
+
},
|
|
99
|
+
open: {
|
|
100
|
+
args: '<id>',
|
|
101
|
+
description: "Print (and open) a task's thread URL.",
|
|
102
|
+
positionals: [1, 1],
|
|
103
|
+
flags: { 'no-open': { type: 'boolean', help: ' Print the URL only.' } },
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
function usage() {
|
|
107
|
+
return { operations: Object.entries(OPERATIONS).map(([name, op]) => ({ name, synopsis: `cez task ${name} ${op.args}`.trim() })) };
|
|
108
|
+
}
|
|
109
|
+
function usageError(error) {
|
|
110
|
+
throw new TaskCliError(EXIT.usage, { code: 'invalid_input', error, usage: usage() });
|
|
111
|
+
}
|
|
112
|
+
export function taskHelp(operation) {
|
|
113
|
+
const names = operation ? [operation] : Object.keys(OPERATIONS);
|
|
114
|
+
const flags = new Map();
|
|
115
|
+
for (const name of names)
|
|
116
|
+
for (const [flag, spec] of Object.entries(OPERATIONS[name].flags))
|
|
117
|
+
flags.set(flag, spec);
|
|
118
|
+
for (const [flag, spec] of Object.entries(COMMON))
|
|
119
|
+
flags.set(flag, spec);
|
|
120
|
+
return [
|
|
121
|
+
'cezar task — start, watch and steer cockpit tasks from the terminal', '', 'Usage:',
|
|
122
|
+
...names.flatMap((name) => {
|
|
123
|
+
const op = OPERATIONS[name];
|
|
124
|
+
return [` cez task ${name} ${op.args}`.trimEnd(), ` ${op.description}`];
|
|
125
|
+
}), '', 'Options:',
|
|
126
|
+
...[...flags].map(([flag, spec]) => ` --${flag} ${spec.help}`), '',
|
|
127
|
+
'Commands find the running cockpit that serves this checkout (ports 4321-4370) and print JSON.',
|
|
128
|
+
'Exit codes: 0 ok · 1 task failed/cancelled or message not delivered · 2 no cockpit or refused ·',
|
|
129
|
+
'3 timed out · 64 usage error.',
|
|
130
|
+
].join('\n');
|
|
131
|
+
}
|
|
132
|
+
async function readStdin() {
|
|
133
|
+
const chunks = [];
|
|
134
|
+
let size = 0;
|
|
135
|
+
for await (const chunk of process.stdin) {
|
|
136
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
|
|
137
|
+
size += buffer.length;
|
|
138
|
+
if (size > TASK_TEXT_MAX_CHARS * 4)
|
|
139
|
+
usageError('stdin is larger than the 100000-character limit');
|
|
140
|
+
chunks.push(buffer);
|
|
141
|
+
}
|
|
142
|
+
return Buffer.concat(chunks, size).toString('utf8');
|
|
143
|
+
}
|
|
144
|
+
async function readTextFile(path) {
|
|
145
|
+
let handle;
|
|
146
|
+
try {
|
|
147
|
+
handle = await openFile(path, 'r');
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
usageError(`cannot read ${path}`);
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const buffer = Buffer.alloc(TASK_TEXT_MAX_CHARS * 4 + 1);
|
|
154
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
155
|
+
if (bytesRead > TASK_TEXT_MAX_CHARS * 4)
|
|
156
|
+
usageError(`${path} is larger than the 100000-character limit`);
|
|
157
|
+
return buffer.subarray(0, bytesRead).toString('utf8');
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
await handle.close();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** A positional, or `--*-file <path|->`; never both, never empty. */
|
|
164
|
+
async function textArgument(io, operation, positional, file, what) {
|
|
165
|
+
if (positional !== undefined && file !== undefined)
|
|
166
|
+
usageError(`${operation} takes the ${what} as an argument or a file, not both`);
|
|
167
|
+
const text = file === undefined ? positional : file === '-' ? await (io.stdin ?? readStdin)() : await readTextFile(file);
|
|
168
|
+
if (text === undefined || !text.trim())
|
|
169
|
+
usageError(`${operation} is missing the ${what}`);
|
|
170
|
+
if (text.length > TASK_TEXT_MAX_CHARS)
|
|
171
|
+
usageError(`${what} is longer than ${TASK_TEXT_MAX_CHARS} characters`);
|
|
172
|
+
return text;
|
|
173
|
+
}
|
|
174
|
+
function parseOperation(argv) {
|
|
175
|
+
const [name, ...rest] = argv;
|
|
176
|
+
if (name === undefined)
|
|
177
|
+
usageError('missing operation');
|
|
178
|
+
const operation = OPERATIONS[name];
|
|
179
|
+
if (!operation)
|
|
180
|
+
usageError(`unknown operation '${name}'`);
|
|
181
|
+
const options = Object.fromEntries(Object.entries({ ...operation.flags, ...COMMON }).map(([flag, spec]) => [flag, { type: spec.type, ...(spec.multiple ? { multiple: true } : {}) }]));
|
|
182
|
+
let parsed;
|
|
183
|
+
try {
|
|
184
|
+
parsed = parseArgs({ args: rest, options, allowPositionals: true, strict: true });
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
usageError(`${name}: ${error instanceof Error ? error.message : 'invalid arguments'}`);
|
|
188
|
+
}
|
|
189
|
+
const values = parsed.values;
|
|
190
|
+
if (!values.help) {
|
|
191
|
+
const [min, max] = operation.positionals;
|
|
192
|
+
if (parsed.positionals.length < min)
|
|
193
|
+
usageError(`${name} is missing a positional`);
|
|
194
|
+
if (parsed.positionals.length > max)
|
|
195
|
+
usageError(`${name} has an extra argument`);
|
|
196
|
+
}
|
|
197
|
+
return { name, values, positionals: parsed.positionals };
|
|
198
|
+
}
|
|
199
|
+
function positiveInt(value, flag, max) {
|
|
200
|
+
if (value === undefined)
|
|
201
|
+
return undefined;
|
|
202
|
+
if (typeof value !== 'string' || !/^\d+$/.test(value) || Number(value) < 1 || Number(value) > max) {
|
|
203
|
+
usageError(`--${flag} must be an integer from 1 to ${max}`);
|
|
204
|
+
}
|
|
205
|
+
return Number(value);
|
|
206
|
+
}
|
|
207
|
+
function nonNegativeInt(value, flag) {
|
|
208
|
+
if (value === undefined)
|
|
209
|
+
return undefined;
|
|
210
|
+
if (typeof value !== 'string' || !/^\d+$/.test(value))
|
|
211
|
+
usageError(`--${flag} must be a non-negative integer`);
|
|
212
|
+
return Number(value);
|
|
213
|
+
}
|
|
214
|
+
function timeoutMs(values) {
|
|
215
|
+
return (positiveInt(values['timeout-seconds'], 'timeout-seconds', MAX_TIMEOUT_SECONDS) ?? DEFAULT_TIMEOUT_SECONDS) * 1_000;
|
|
216
|
+
}
|
|
217
|
+
function oneOf(value, flag, allowed, fallback) {
|
|
218
|
+
if (value === undefined)
|
|
219
|
+
return fallback;
|
|
220
|
+
if (typeof value !== 'string' || !allowed.includes(value))
|
|
221
|
+
usageError(`--${flag} must be one of ${allowed.join(', ')}`);
|
|
222
|
+
return value;
|
|
223
|
+
}
|
|
224
|
+
function statuses(value) {
|
|
225
|
+
if (typeof value !== 'string')
|
|
226
|
+
return undefined;
|
|
227
|
+
const list = value.split(',').map((entry) => entry.trim()).filter(Boolean);
|
|
228
|
+
const invalid = list.find((entry) => !runStatusSchema.safeParse(entry).success);
|
|
229
|
+
if (invalid)
|
|
230
|
+
usageError(`unknown status '${invalid}'`);
|
|
231
|
+
return new Set(list);
|
|
232
|
+
}
|
|
233
|
+
/** Every flag check `execute` makes, run up front so a bad flag never waits on discovery. */
|
|
234
|
+
function validateFlags(name, values) {
|
|
235
|
+
if (name === 'list') {
|
|
236
|
+
statuses(values.status);
|
|
237
|
+
positiveInt(values.limit, 'limit', 1_000);
|
|
238
|
+
}
|
|
239
|
+
if (name === 'wait') {
|
|
240
|
+
oneOf(values.mode, 'mode', ['any', 'all'], 'all');
|
|
241
|
+
oneOf(values.until, 'until', ['settled', 'attention'], 'settled');
|
|
242
|
+
}
|
|
243
|
+
if (name === 'log') {
|
|
244
|
+
nonNegativeInt(values.since, 'since');
|
|
245
|
+
positiveInt(values['max-chars'], 'max-chars', 1_000_000);
|
|
246
|
+
}
|
|
247
|
+
if (name === 'wait' || name === 'log' || (name === 'start' && values.wait))
|
|
248
|
+
timeoutMs(values);
|
|
249
|
+
}
|
|
250
|
+
async function getRun(cockpit, id) {
|
|
251
|
+
const result = await request(cockpit, `/runs/${encodeURIComponent(id)}`);
|
|
252
|
+
if (result.status !== 200)
|
|
253
|
+
refuse(result);
|
|
254
|
+
const run = apiRunSchema.safeParse(result.data);
|
|
255
|
+
return run.success ? run.data : invalidResponse('run');
|
|
256
|
+
}
|
|
257
|
+
async function listRuns(cockpit) {
|
|
258
|
+
const result = await request(cockpit, '/runs');
|
|
259
|
+
if (result.status !== 200)
|
|
260
|
+
refuse(result);
|
|
261
|
+
const runs = apiRunSchema.array().safeParse(result.data);
|
|
262
|
+
return runs.success ? runs.data : invalidResponse('run list');
|
|
263
|
+
}
|
|
264
|
+
/** The latest valid unanswered question, from the same derivation the cockpit renders. */
|
|
265
|
+
async function pendingQuestion(cockpit, id) {
|
|
266
|
+
const result = await request(cockpit, `/runs/${encodeURIComponent(id)}/history-context`);
|
|
267
|
+
const context = runHistoryContextSchema.safeParse(result.data);
|
|
268
|
+
if (result.status !== 200 || !context.success)
|
|
269
|
+
return undefined;
|
|
270
|
+
const ask = [...context.data.contextEvents].reverse().find((event) => event.type === 'ask.requested');
|
|
271
|
+
return ask?.questions;
|
|
272
|
+
}
|
|
273
|
+
async function start(cockpit, io, values, task, print) {
|
|
274
|
+
const waitMs = values.wait ? timeoutMs(values) : undefined;
|
|
275
|
+
const requestId = values['request-id'] ?? randomUUID();
|
|
276
|
+
const result = await request(cockpit, '/runs', {
|
|
277
|
+
body: {
|
|
278
|
+
task,
|
|
279
|
+
workflow: values.workflow ?? 'quick-task',
|
|
280
|
+
...(values.backend === undefined ? {} : { runner: values.backend }),
|
|
281
|
+
...(values.model === undefined ? {} : { model: values.model }),
|
|
282
|
+
...(values.effort === undefined ? {} : { effort: values.effort }),
|
|
283
|
+
...(values.autonomous ? { autonomous: true } : {}),
|
|
284
|
+
...(values['no-worktree'] ? { worktree: false } : {}),
|
|
285
|
+
clientRequestId: requestId,
|
|
286
|
+
},
|
|
287
|
+
});
|
|
288
|
+
if (result.status !== 200 && result.status !== 201)
|
|
289
|
+
refuse(result);
|
|
290
|
+
const run = runRecordSchema.safeParse(result.data);
|
|
291
|
+
if (!run.success)
|
|
292
|
+
invalidResponse('start');
|
|
293
|
+
const started = {
|
|
294
|
+
id: run.data.id,
|
|
295
|
+
url: threadUrl(cockpit, run.data.id),
|
|
296
|
+
status: run.data.status,
|
|
297
|
+
created: result.status === 201,
|
|
298
|
+
requestId,
|
|
299
|
+
...(run.data.branch === undefined ? {} : { branch: run.data.branch }),
|
|
300
|
+
};
|
|
301
|
+
if (waitMs === undefined) {
|
|
302
|
+
print(started);
|
|
303
|
+
return EXIT.ok;
|
|
304
|
+
}
|
|
305
|
+
const waited = await waitForRuns(cockpit, [run.data.id], { mode: 'all', until: 'settled', timeoutMs: waitMs, pollMs: io.pollMs });
|
|
306
|
+
const final = waited.runs[0];
|
|
307
|
+
print({ ...started, ...final, timedOut: waited.timedOut });
|
|
308
|
+
return waited.exitCode;
|
|
309
|
+
}
|
|
310
|
+
async function send(cockpit, values, id, text, print) {
|
|
311
|
+
const path = `/runs/${encodeURIComponent(id)}`;
|
|
312
|
+
const delivered = await request(cockpit, `${path}/messages`, { body: { text } });
|
|
313
|
+
if (delivered.status === 200) {
|
|
314
|
+
const answer = messageResponseSchema.safeParse(delivered.data);
|
|
315
|
+
if (!answer.success)
|
|
316
|
+
invalidResponse('message');
|
|
317
|
+
const delivery = 'delivered' in answer.data ? 'delivered' : 'queued' in answer.data ? 'queued' : 'deferred';
|
|
318
|
+
print({ id, delivery });
|
|
319
|
+
return EXIT.ok;
|
|
320
|
+
}
|
|
321
|
+
const closed = delivered.status === 409 && delivered.data?.error === 'session closed';
|
|
322
|
+
if (!closed)
|
|
323
|
+
refuse(delivered);
|
|
324
|
+
if (!values.resume) {
|
|
325
|
+
print({ id, delivery: 'not-delivered', reason: 'session closed', next: `cez task send ${id} '…' --resume` });
|
|
326
|
+
return EXIT.failed;
|
|
327
|
+
}
|
|
328
|
+
const resumed = await request(cockpit, `${path}/continue`, { body: { text } });
|
|
329
|
+
if (resumed.status !== 200)
|
|
330
|
+
refuse(resumed);
|
|
331
|
+
print({ id, delivery: 'resumed' });
|
|
332
|
+
return EXIT.ok;
|
|
333
|
+
}
|
|
334
|
+
async function execute(name, cockpit, io, values, positionals, text, print) {
|
|
335
|
+
const id = positionals[0];
|
|
336
|
+
const path = `/runs/${encodeURIComponent(id)}`;
|
|
337
|
+
switch (name) {
|
|
338
|
+
case 'start':
|
|
339
|
+
return start(cockpit, io, values, text, print);
|
|
340
|
+
case 'send':
|
|
341
|
+
return send(cockpit, values, id, text, print);
|
|
342
|
+
case 'wait': {
|
|
343
|
+
const mode = oneOf(values.mode, 'mode', ['any', 'all'], 'all');
|
|
344
|
+
const until = oneOf(values.until, 'until', ['settled', 'attention'], 'settled');
|
|
345
|
+
const waited = await waitForRuns(cockpit, positionals, { mode, until, timeoutMs: timeoutMs(values), pollMs: io.pollMs });
|
|
346
|
+
print({ runs: waited.runs, timedOut: waited.timedOut });
|
|
347
|
+
return waited.exitCode;
|
|
348
|
+
}
|
|
349
|
+
case 'log': {
|
|
350
|
+
const since = nonNegativeInt(values.since, 'since') ?? 0;
|
|
351
|
+
const maxChars = positiveInt(values['max-chars'], 'max-chars', 1_000_000) ?? 8_000;
|
|
352
|
+
// An unknown run is the history route's 404, passed through. Without --follow the replay
|
|
353
|
+
// ends at its boundary; the deadline is only a backstop there.
|
|
354
|
+
return readLog(cockpit, id, {
|
|
355
|
+
afterSeq: since, maxChars, follow: values.follow === true,
|
|
356
|
+
deadline: Date.now() + (values.follow ? timeoutMs(values) : 45_000),
|
|
357
|
+
print: (line) => io.stdout(line),
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
case 'status': {
|
|
361
|
+
const run = await getRun(cockpit, id);
|
|
362
|
+
if (values.full) {
|
|
363
|
+
print(run);
|
|
364
|
+
return EXIT.ok;
|
|
365
|
+
}
|
|
366
|
+
const question = run.hasPendingHumanAsk ? await pendingQuestion(cockpit, id) : undefined;
|
|
367
|
+
print(projectStatus(run, threadUrl(cockpit, id), question));
|
|
368
|
+
return EXIT.ok;
|
|
369
|
+
}
|
|
370
|
+
case 'list': {
|
|
371
|
+
const wanted = statuses(values.status);
|
|
372
|
+
const limit = positiveInt(values.limit, 'limit', 1_000) ?? 20;
|
|
373
|
+
const runs = (await listRuns(cockpit))
|
|
374
|
+
.filter((run) => values.all || !run.archived)
|
|
375
|
+
.filter((run) => !wanted || wanted.has(run.status))
|
|
376
|
+
.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
377
|
+
print({ runs: runs.slice(0, limit).map((run) => (values.full ? run : projectListRow(run))), total: runs.length });
|
|
378
|
+
return EXIT.ok;
|
|
379
|
+
}
|
|
380
|
+
case 'stop': {
|
|
381
|
+
const result = await request(cockpit, `${path}/cancel`, { body: {} });
|
|
382
|
+
const answer = cancelResponseSchema.safeParse(result.data);
|
|
383
|
+
if (result.status !== 200)
|
|
384
|
+
refuse(result);
|
|
385
|
+
if (!answer.success)
|
|
386
|
+
invalidResponse('cancel');
|
|
387
|
+
print({ id, cancelled: answer.data.cancelled });
|
|
388
|
+
return EXIT.ok;
|
|
389
|
+
}
|
|
390
|
+
case 'finish': {
|
|
391
|
+
const result = await request(cockpit, `${path}/finish`, { body: {} });
|
|
392
|
+
if (result.status !== 200)
|
|
393
|
+
refuse(result);
|
|
394
|
+
if (!finishResponseSchema.safeParse(result.data).success)
|
|
395
|
+
invalidResponse('finish');
|
|
396
|
+
print({ id, finished: true });
|
|
397
|
+
return EXIT.ok;
|
|
398
|
+
}
|
|
399
|
+
case 'diff': {
|
|
400
|
+
if (values.stat) {
|
|
401
|
+
const result = await request(cockpit, `${path}/changes`);
|
|
402
|
+
if (result.status !== 200)
|
|
403
|
+
refuse(result);
|
|
404
|
+
const changes = changesPayloadSchema.safeParse(result.data);
|
|
405
|
+
if (!changes.success)
|
|
406
|
+
invalidResponse('changes');
|
|
407
|
+
print({ id, stat: changes.data.stat, files: changes.data.files.map((file) => ({ path: file.path, status: file.status, adds: file.adds, dels: file.dels })) });
|
|
408
|
+
return EXIT.ok;
|
|
409
|
+
}
|
|
410
|
+
const result = await request(cockpit, `${path}/diff`);
|
|
411
|
+
if (result.status !== 200)
|
|
412
|
+
refuse(result);
|
|
413
|
+
print({ id, diff: typeof result.data === 'string' ? result.data : invalidResponse('diff') });
|
|
414
|
+
return EXIT.ok;
|
|
415
|
+
}
|
|
416
|
+
case 'open': {
|
|
417
|
+
const run = await getRun(cockpit, id);
|
|
418
|
+
const url = threadUrl(cockpit, run.id);
|
|
419
|
+
if (!values['no-open'])
|
|
420
|
+
(io.open ?? openUrl)(url);
|
|
421
|
+
print({ id: run.id, url, opened: !values['no-open'] });
|
|
422
|
+
return EXIT.ok;
|
|
423
|
+
}
|
|
424
|
+
default:
|
|
425
|
+
return usageError(`unknown operation '${name}'`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
export async function runTaskCommand(argv, env, io = { stdout: (line) => console.log(line) }) {
|
|
429
|
+
const print = (value) => io.stdout(JSON.stringify(value));
|
|
430
|
+
try {
|
|
431
|
+
if (argv.length === 1 && (argv[0] === '-h' || argv[0] === '--help')) {
|
|
432
|
+
io.stdout(taskHelp());
|
|
433
|
+
return EXIT.ok;
|
|
434
|
+
}
|
|
435
|
+
const { name, values, positionals } = parseOperation(argv);
|
|
436
|
+
if (values.help) {
|
|
437
|
+
io.stdout(taskHelp(name));
|
|
438
|
+
return EXIT.ok;
|
|
439
|
+
}
|
|
440
|
+
// Input is judged before any cockpit is looked for: a usage error is exit 64 whether or not
|
|
441
|
+
// a cockpit is running, and stdin is read once, here.
|
|
442
|
+
const text = name === 'start'
|
|
443
|
+
? await textArgument(io, 'start', positionals[0], values['task-file'], 'task')
|
|
444
|
+
: name === 'send'
|
|
445
|
+
? await textArgument(io, 'send', positionals[1], values['text-file'], 'text')
|
|
446
|
+
: undefined;
|
|
447
|
+
validateFlags(name, values);
|
|
448
|
+
const cockpit = await (io.discover ?? discoverCockpit)({
|
|
449
|
+
url: values.url ?? (env.CEZ_URL?.trim() || undefined),
|
|
450
|
+
repoDir: resolve(values.repo ?? process.cwd()),
|
|
451
|
+
});
|
|
452
|
+
return await execute(name, cockpit, io, values, positionals, text, print);
|
|
453
|
+
}
|
|
454
|
+
catch (error) {
|
|
455
|
+
if (error instanceof TaskCliError) {
|
|
456
|
+
print(error.body);
|
|
457
|
+
return error.exitCode;
|
|
458
|
+
}
|
|
459
|
+
print({ code: 'internal', error: error instanceof Error ? error.message : String(error) });
|
|
460
|
+
return EXIT.refused;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/task-cli/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Cockpit } from './http.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Which cockpit serves this checkout (#504, spec 2026-09-24-cez-task-cli). Zero config: probe the
|
|
4
|
+
* range `pickPort` can land on and match the registry's project roots against this repo. Never
|
|
5
|
+
* starts a server and never writes anything — a missing cockpit is an answer, not a fallback.
|
|
6
|
+
*/
|
|
7
|
+
/** The ports `cez` can bind: 4321 plus the 49 `pickPort` tries after it. */
|
|
8
|
+
export declare const COCKPIT_PORTS: readonly number[];
|
|
9
|
+
/**
|
|
10
|
+
* The main checkout that owns `dir`. A task worktree's common git dir is the parent repo's
|
|
11
|
+
* `.git`, so this is what maps `.ai/cezar/worktrees/<id>` back to the project that ran it.
|
|
12
|
+
* Submodules instead keep their git dir under `.git/modules/` and record `core.worktree`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function checkoutRoot(dir: string): Promise<string>;
|
|
15
|
+
export interface DiscoverOptions {
|
|
16
|
+
/** `--url` / `CEZ_URL`: skip the probe. */
|
|
17
|
+
url?: string;
|
|
18
|
+
repoDir: string;
|
|
19
|
+
ports?: readonly number[];
|
|
20
|
+
timeoutMs?: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function discoverCockpit(options: DiscoverOptions): Promise<Cockpit>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { realpath } from 'node:fs/promises';
|
|
3
|
+
import { basename, dirname, resolve } from 'node:path';
|
|
4
|
+
import { healthResponseSchema, projectsResponseSchema } from '../contract/index.js';
|
|
5
|
+
import { fetchJson, TaskCliError } from './http.js';
|
|
6
|
+
/**
|
|
7
|
+
* Which cockpit serves this checkout (#504, spec 2026-09-24-cez-task-cli). Zero config: probe the
|
|
8
|
+
* range `pickPort` can land on and match the registry's project roots against this repo. Never
|
|
9
|
+
* starts a server and never writes anything — a missing cockpit is an answer, not a fallback.
|
|
10
|
+
*/
|
|
11
|
+
/** The ports `cez` can bind: 4321 plus the 49 `pickPort` tries after it. */
|
|
12
|
+
export const COCKPIT_PORTS = Array.from({ length: 50 }, (_, index) => 4321 + index);
|
|
13
|
+
const PROBE_TIMEOUT_MS = 1_500;
|
|
14
|
+
function git(cwd, args) {
|
|
15
|
+
return new Promise((done) => {
|
|
16
|
+
execFile('git', ['-C', cwd, ...args], { timeout: 5_000 }, (error, stdout) => done(error ? undefined : stdout.trim()));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function realpathOr(path) {
|
|
20
|
+
try {
|
|
21
|
+
return await realpath(path);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return resolve(path);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The main checkout that owns `dir`. A task worktree's common git dir is the parent repo's
|
|
29
|
+
* `.git`, so this is what maps `.ai/cezar/worktrees/<id>` back to the project that ran it.
|
|
30
|
+
* Submodules instead keep their git dir under `.git/modules/` and record `core.worktree`.
|
|
31
|
+
*/
|
|
32
|
+
export async function checkoutRoot(dir) {
|
|
33
|
+
const common = await git(dir, ['rev-parse', '--path-format=absolute', '--git-common-dir']);
|
|
34
|
+
if (common && basename(common) === '.git')
|
|
35
|
+
return realpathOr(dirname(common));
|
|
36
|
+
if (common) {
|
|
37
|
+
// Read the main worktree's config, not a linked worktree override. Git resolves a relative
|
|
38
|
+
// core.worktree against this shared git dir, even when the caller is in a task worktree.
|
|
39
|
+
const main = await git(dir, ['--git-dir', common, 'config', '--path', '--get', 'core.worktree']);
|
|
40
|
+
if (main)
|
|
41
|
+
return realpathOr(resolve(common, main));
|
|
42
|
+
}
|
|
43
|
+
const top = await git(dir, ['rev-parse', '--show-toplevel']);
|
|
44
|
+
return realpathOr(top ?? dir);
|
|
45
|
+
}
|
|
46
|
+
/** Health first (cheap, and it proves this is a cezar), then the registry with its roots. */
|
|
47
|
+
async function probe(origin, timeoutMs) {
|
|
48
|
+
try {
|
|
49
|
+
const health = await fetchJson(`${origin}/api/v1/health`, { timeoutMs });
|
|
50
|
+
if (health.status !== 200 || !healthResponseSchema.safeParse(health.data).success)
|
|
51
|
+
return undefined;
|
|
52
|
+
const registry = await fetchJson(`${origin}/api/v1/projects`, { timeoutMs });
|
|
53
|
+
const parsed = projectsResponseSchema.safeParse(registry.data);
|
|
54
|
+
if (registry.status !== 200 || !parsed.success)
|
|
55
|
+
return undefined;
|
|
56
|
+
const projects = await Promise.all(parsed.data.projects.map(async (entry) => ({ id: entry.id, root: await realpathOr(entry.root) })));
|
|
57
|
+
return { origin, projects, bootProject: parsed.data.bootProject };
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function cockpitFor(origin, projectId) {
|
|
64
|
+
return { origin, projectId, api: `${origin}/api/v1/p/${encodeURIComponent(projectId)}` };
|
|
65
|
+
}
|
|
66
|
+
export async function discoverCockpit(options) {
|
|
67
|
+
const root = await checkoutRoot(options.repoDir);
|
|
68
|
+
const timeoutMs = options.timeoutMs ?? PROBE_TIMEOUT_MS;
|
|
69
|
+
const hint = `start the cockpit in ${root} with: cez`;
|
|
70
|
+
if (options.url) {
|
|
71
|
+
let origin;
|
|
72
|
+
try {
|
|
73
|
+
origin = new URL(options.url).origin;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
throw new TaskCliError(64, { code: 'invalid_input', error: `invalid cockpit url: ${options.url}` });
|
|
77
|
+
}
|
|
78
|
+
const found = await probe(origin, Math.max(timeoutMs, 5_000));
|
|
79
|
+
if (!found)
|
|
80
|
+
throw new TaskCliError(2, { code: 'no-cockpit', error: `no cezar cockpit answered at ${origin}`, hint });
|
|
81
|
+
// A remote cockpit's roots are its own paths, so no match is the ordinary case there.
|
|
82
|
+
const match = found.projects.find((entry) => entry.root === root);
|
|
83
|
+
return cockpitFor(origin, match?.id ?? found.bootProject);
|
|
84
|
+
}
|
|
85
|
+
const ports = options.ports ?? COCKPIT_PORTS;
|
|
86
|
+
const candidates = await Promise.all(ports.map((port) => probe(`http://127.0.0.1:${port}`, timeoutMs)));
|
|
87
|
+
// `ports` is ascending, so the first match is the lowest port serving this checkout.
|
|
88
|
+
for (const candidate of candidates) {
|
|
89
|
+
const match = candidate?.projects.find((entry) => entry.root === root);
|
|
90
|
+
if (candidate && match)
|
|
91
|
+
return cockpitFor(candidate.origin, match.id);
|
|
92
|
+
}
|
|
93
|
+
throw new TaskCliError(2, { code: 'no-cockpit', error: `no running cockpit serves ${root}`, hint });
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=discovery.js.map
|