@wjarka/cezarion 0.14.8 → 0.14.9-dev.1009

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.
Files changed (280) hide show
  1. package/README.md +131 -2
  2. package/dist/application-update/bin-recovery.d.ts +5 -0
  3. package/dist/application-update/bin-recovery.js +96 -0
  4. package/dist/application-update/bin-recovery.js.map +1 -0
  5. package/dist/application-update/discovery.d.ts +22 -0
  6. package/dist/application-update/discovery.js +91 -0
  7. package/dist/application-update/discovery.js.map +1 -0
  8. package/dist/application-update/helper.d.ts +57 -0
  9. package/dist/application-update/helper.js +374 -0
  10. package/dist/application-update/helper.js.map +1 -0
  11. package/dist/application-update/launcher.d.ts +8 -0
  12. package/dist/application-update/launcher.js +53 -0
  13. package/dist/application-update/launcher.js.map +1 -0
  14. package/dist/application-update/lock.d.ts +4 -0
  15. package/dist/application-update/lock.js +70 -0
  16. package/dist/application-update/lock.js.map +1 -0
  17. package/dist/application-update/npm-process.d.ts +17 -0
  18. package/dist/application-update/npm-process.js +133 -0
  19. package/dist/application-update/npm-process.js.map +1 -0
  20. package/dist/application-update/service.d.ts +69 -0
  21. package/dist/application-update/service.js +456 -0
  22. package/dist/application-update/service.js.map +1 -0
  23. package/dist/artifacts/cli.d.ts +1 -0
  24. package/dist/artifacts/cli.js +32 -0
  25. package/dist/artifacts/cli.js.map +1 -0
  26. package/dist/artifacts/lifecycle.d.ts +4 -0
  27. package/dist/artifacts/lifecycle.js +42 -0
  28. package/dist/artifacts/lifecycle.js.map +1 -0
  29. package/dist/artifacts/resolve.d.ts +18 -0
  30. package/dist/artifacts/resolve.js +102 -0
  31. package/dist/artifacts/resolve.js.map +1 -0
  32. package/dist/artifacts/store.d.ts +8 -0
  33. package/dist/artifacts/store.js +323 -0
  34. package/dist/artifacts/store.js.map +1 -0
  35. package/dist/automations/scheduler.d.ts +6 -0
  36. package/dist/automations/scheduler.js +45 -17
  37. package/dist/automations/scheduler.js.map +1 -1
  38. package/dist/automations/store.d.ts +12 -4
  39. package/dist/automations/store.js +199 -22
  40. package/dist/automations/store.js.map +1 -1
  41. package/dist/automations/types.d.ts +2 -0
  42. package/dist/automations/types.js +1 -0
  43. package/dist/automations/types.js.map +1 -1
  44. package/dist/ci-wait/mcp.d.ts +3 -0
  45. package/dist/ci-wait/mcp.js +14 -3
  46. package/dist/ci-wait/mcp.js.map +1 -1
  47. package/dist/contract/application-update.d.ts +32 -0
  48. package/dist/contract/artifacts.d.ts +83 -0
  49. package/dist/contract/ask-schema.d.ts +32 -0
  50. package/dist/contract/ask.d.ts +2 -32
  51. package/dist/contract/automations.d.ts +6 -0
  52. package/dist/contract/conversations.d.ts +165 -0
  53. package/dist/contract/delegation.d.ts +68 -0
  54. package/dist/contract/discovery.d.ts +134 -0
  55. package/dist/contract/events.d.ts +49 -0
  56. package/dist/contract/health.d.ts +12 -0
  57. package/dist/contract/index.d.ts +3 -0
  58. package/dist/contract/index.js +1654 -1454
  59. package/dist/contract/projects.d.ts +40 -0
  60. package/dist/contract/runs.d.ts +186 -0
  61. package/dist/contract/skills.d.ts +33 -0
  62. package/dist/core/agent-runner.d.ts +33 -4
  63. package/dist/core/agent-runner.js +5 -0
  64. package/dist/core/agent-runner.js.map +1 -1
  65. package/dist/core/claude-cli-runner.d.ts +6 -12
  66. package/dist/core/claude-cli-runner.js +90 -20
  67. package/dist/core/claude-cli-runner.js.map +1 -1
  68. package/dist/core/codex-app-server-runner.d.ts +2 -1
  69. package/dist/core/codex-app-server-runner.js +327 -92
  70. package/dist/core/codex-app-server-runner.js.map +1 -1
  71. package/dist/core/codex-app-server-transport.d.ts +13 -1
  72. package/dist/core/codex-app-server-transport.js +58 -17
  73. package/dist/core/codex-app-server-transport.js.map +1 -1
  74. package/dist/core/cursor-acp-runner.d.ts +6 -1
  75. package/dist/core/cursor-acp-runner.js +162 -26
  76. package/dist/core/cursor-acp-runner.js.map +1 -1
  77. package/dist/core/cursor-provider-error.d.ts +3 -0
  78. package/dist/core/cursor-provider-error.js +16 -1
  79. package/dist/core/cursor-provider-error.js.map +1 -1
  80. package/dist/core/input-submissions.d.ts +14 -0
  81. package/dist/core/input-submissions.js +26 -0
  82. package/dist/core/input-submissions.js.map +1 -0
  83. package/dist/core/opencode-server-runner.d.ts +4 -1
  84. package/dist/core/opencode-server-runner.js +156 -26
  85. package/dist/core/opencode-server-runner.js.map +1 -1
  86. package/dist/core/pi-runner.d.ts +2 -1
  87. package/dist/core/pi-runner.js +88 -10
  88. package/dist/core/pi-runner.js.map +1 -1
  89. package/dist/core/provider-auth.d.ts +99 -1
  90. package/dist/core/provider-auth.js +203 -2
  91. package/dist/core/provider-auth.js.map +1 -1
  92. package/dist/delegation/cli.d.ts +1 -0
  93. package/dist/delegation/cli.js +103 -7
  94. package/dist/delegation/cli.js.map +1 -1
  95. package/dist/delegation/conversations.js +13 -5
  96. package/dist/delegation/conversations.js.map +1 -1
  97. package/dist/delegation/input.d.ts +2 -1
  98. package/dist/delegation/input.js +6 -1
  99. package/dist/delegation/input.js.map +1 -1
  100. package/dist/delegation/policy.d.ts +3 -2
  101. package/dist/delegation/policy.js +3 -1
  102. package/dist/delegation/policy.js.map +1 -1
  103. package/dist/delegation/process-liveness.d.ts +66 -0
  104. package/dist/delegation/process-liveness.js +215 -0
  105. package/dist/delegation/process-liveness.js.map +1 -0
  106. package/dist/delegation/provision.d.ts +1 -1
  107. package/dist/delegation/provision.js +10 -5
  108. package/dist/delegation/provision.js.map +1 -1
  109. package/dist/delegation/questions.d.ts +19 -0
  110. package/dist/delegation/questions.js +45 -0
  111. package/dist/delegation/questions.js.map +1 -0
  112. package/dist/delegation/results.d.ts +1 -1
  113. package/dist/delegation/results.js +33 -19
  114. package/dist/delegation/results.js.map +1 -1
  115. package/dist/delegation/routes.d.ts +185 -11
  116. package/dist/delegation/routes.js +6 -2
  117. package/dist/delegation/routes.js.map +1 -1
  118. package/dist/delegation/service.d.ts +23 -5
  119. package/dist/delegation/service.js +240 -17
  120. package/dist/delegation/service.js.map +1 -1
  121. package/dist/delegation/transport.d.ts +178 -15
  122. package/dist/delegation/workspace.d.ts +1 -1
  123. package/dist/delegation/workspace.js +13 -6
  124. package/dist/delegation/workspace.js.map +1 -1
  125. package/dist/discovery/catalog.d.ts +14 -0
  126. package/dist/discovery/catalog.js +31 -0
  127. package/dist/discovery/catalog.js.map +1 -0
  128. package/dist/discovery/cli.d.ts +8 -0
  129. package/dist/discovery/cli.js +104 -0
  130. package/dist/discovery/cli.js.map +1 -0
  131. package/dist/git-worktree.d.ts +3 -1
  132. package/dist/git-worktree.js +26 -4
  133. package/dist/git-worktree.js.map +1 -1
  134. package/dist/index.js +93 -26
  135. package/dist/index.js.map +1 -1
  136. package/dist/open-url.d.ts +2 -0
  137. package/dist/open-url.js +20 -0
  138. package/dist/open-url.js.map +1 -0
  139. package/dist/release/snapshot.d.ts +3 -3
  140. package/dist/release/snapshot.js +6 -6
  141. package/dist/release/snapshot.js.map +1 -1
  142. package/dist/runs/agent-tmpdir.d.ts +2 -0
  143. package/dist/runs/agent-tmpdir.js +5 -2
  144. package/dist/runs/agent-tmpdir.js.map +1 -1
  145. package/dist/runs/client-request.d.ts +11 -0
  146. package/dist/runs/client-request.js +26 -0
  147. package/dist/runs/client-request.js.map +1 -0
  148. package/dist/runs/delegation-state.d.ts +17 -0
  149. package/dist/runs/event-history.js +6 -0
  150. package/dist/runs/event-history.js.map +1 -1
  151. package/dist/runs/retention.d.ts +7 -2
  152. package/dist/runs/retention.js +39 -7
  153. package/dist/runs/retention.js.map +1 -1
  154. package/dist/runs/store.d.ts +100 -6
  155. package/dist/runs/store.js +245 -2
  156. package/dist/runs/store.js.map +1 -1
  157. package/dist/runs/webhook.d.ts +125 -0
  158. package/dist/runs/webhook.js +256 -0
  159. package/dist/runs/webhook.js.map +1 -0
  160. package/dist/server/project-context.d.ts +2 -0
  161. package/dist/server/project-context.js +1 -0
  162. package/dist/server/project-context.js.map +1 -1
  163. package/dist/server/provider-auth-runtime.d.ts +30 -4
  164. package/dist/server/provider-auth-runtime.js +71 -6
  165. package/dist/server/provider-auth-runtime.js.map +1 -1
  166. package/dist/server/server.d.ts +8226 -4860
  167. package/dist/server/server.js +311 -15
  168. package/dist/server/server.js.map +1 -1
  169. package/dist/server-install/platforms/ubuntu-vps.d.ts +5 -1
  170. package/dist/server-install/platforms/ubuntu-vps.js +160 -18
  171. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -1
  172. package/dist/server-install/steps.d.ts +4 -2
  173. package/dist/server-install/steps.js +5 -4
  174. package/dist/server-install/steps.js.map +1 -1
  175. package/dist/skills-remote.d.ts +30 -5
  176. package/dist/skills-remote.js +122 -32
  177. package/dist/skills-remote.js.map +1 -1
  178. package/dist/skills.js +15 -6
  179. package/dist/skills.js.map +1 -1
  180. package/dist/task-cli/cli.d.ts +38 -0
  181. package/dist/task-cli/cli.js +580 -0
  182. package/dist/task-cli/cli.js.map +1 -0
  183. package/dist/task-cli/discovery.d.ts +22 -0
  184. package/dist/task-cli/discovery.js +96 -0
  185. package/dist/task-cli/discovery.js.map +1 -0
  186. package/dist/task-cli/http.d.ts +46 -0
  187. package/dist/task-cli/http.js +101 -0
  188. package/dist/task-cli/http.js.map +1 -0
  189. package/dist/task-cli/projections.d.ts +40 -0
  190. package/dist/task-cli/projections.js +45 -0
  191. package/dist/task-cli/projections.js.map +1 -0
  192. package/dist/task-cli/watch.d.ts +78 -0
  193. package/dist/task-cli/watch.js +336 -0
  194. package/dist/task-cli/watch.js.map +1 -0
  195. package/dist/workflows/run.d.ts +160 -2
  196. package/dist/workflows/run.js +1141 -108
  197. package/dist/workflows/run.js.map +1 -1
  198. package/dist/workspace/agent-profiles.d.ts +22 -0
  199. package/dist/workspace/agent-profiles.js +15 -0
  200. package/dist/workspace/agent-profiles.js.map +1 -1
  201. package/dist/workspace/config.d.ts +9 -0
  202. package/dist/workspace/config.js +13 -1
  203. package/dist/workspace/config.js.map +1 -1
  204. package/dist/workspace/projects-cli.js +1 -1
  205. package/dist/workspace/projects.d.ts +24 -1
  206. package/dist/workspace/projects.js +14 -1
  207. package/dist/workspace/projects.js.map +1 -1
  208. package/package.json +5 -5
  209. package/scripts/mock-claude.mjs +64 -2
  210. package/scripts/mock-codex-app-server.mjs +124 -1
  211. package/scripts/mock-cursor-acp.mjs +54 -3
  212. package/scripts/mock-cursor-hang-stdin-late.mjs +35 -0
  213. package/scripts/mock-cursor-hang-stdin.mjs +30 -0
  214. package/scripts/mock-opencode-serve.mjs +102 -2
  215. package/scripts/mock-pi-rpc.mjs +82 -3
  216. package/web/dist/assets/agent-accounts-CerclGiO.js +1 -0
  217. package/web/dist/assets/centered-state-DH8qtCz-.js +43 -0
  218. package/web/dist/assets/collapsible-De2G0xqQ.js +1 -0
  219. package/web/dist/assets/commit-list-s6JPY3qv.js +1 -0
  220. package/web/dist/assets/compare-variants-BQu_t-_g.js +1 -0
  221. package/web/dist/assets/{diff-tRE59UNb2.js → diff-8M5HlDxq2.js} +2 -2
  222. package/web/dist/assets/diff-controls-B6ok0TtQ.js +1 -0
  223. package/web/dist/assets/{diff-stat-Cgnl_hYF.js → diff-stat-D1AODN2a.js} +1 -1
  224. package/web/dist/assets/{diff-view-DN1ort7Q.js → diff-view-Bs5Gh7UF.js} +2 -2
  225. package/web/dist/assets/dropdown-menu-7KGQMoFj.js +1 -0
  226. package/web/dist/assets/git-toolbar-DqbapMXr.js +1 -0
  227. package/web/dist/assets/github-DCkk6sBm.js +1 -0
  228. package/web/dist/assets/{image-preview-C2JGcBlC.js → image-preview-jzHoEyLM.js} +1 -1
  229. package/web/dist/assets/index-Bnva-ttR.js +7 -0
  230. package/web/dist/assets/index-D5NkwqY7.css +1 -0
  231. package/web/dist/assets/markdown-DvbymqXz.js +2 -0
  232. package/web/dist/assets/pill-BL6ugwXo.js +1 -0
  233. package/web/dist/assets/project-router-ChC5Rb-Y.js +1 -0
  234. package/web/dist/assets/prompt-templates-j8qlK7c-.js +15 -0
  235. package/web/dist/assets/repo-git-_h1NjOVt.js +1 -0
  236. package/web/dist/assets/{run-diff-CyG0Nciv.js → run-diff-BuATgZpx.js} +2 -2
  237. package/web/dist/assets/run-header-DuAWswYM.js +1 -0
  238. package/web/dist/assets/skills-C-fq5BrZ.js +1 -0
  239. package/web/dist/assets/{tab-link-BWNp3mLY.js → tab-link-BmGKj9Rt.js} +1 -1
  240. package/web/dist/assets/task-changes-CHa6JWOS.js +1 -0
  241. package/web/dist/assets/task-commits-BqCqyWm1.js +1 -0
  242. package/web/dist/assets/task-files-BSA0l-YP.js +2 -0
  243. package/web/dist/assets/task-thread-Bw_nQuTx.css +1 -0
  244. package/web/dist/assets/task-thread-Q7Nj33DH.js +9 -0
  245. package/web/dist/assets/textarea-ByZ-txS7.js +1 -0
  246. package/web/dist/assets/thread-loading-DHT9p5o5.js +1 -0
  247. package/web/dist/assets/token-metrics-k4XoovDS.js +1 -0
  248. package/web/dist/assets/utils-BTFBhZ55.js +64 -0
  249. package/web/dist/assets/workflows-HJOd3lVi.js +11 -0
  250. package/web/dist/assets/{zoomable-image-Z3JDnm0b.js → zoomable-image-Ba6y6Wyl.js} +1 -1
  251. package/web/dist/index.html +14 -14
  252. package/web/dist/assets/agent-accounts-BZm_2WAv.js +0 -1
  253. package/web/dist/assets/alert-dialog-B422RI-k.js +0 -43
  254. package/web/dist/assets/collapsible-Cy_Fmkrd.js +0 -1
  255. package/web/dist/assets/commit-list-Dcnk7TnI.js +0 -1
  256. package/web/dist/assets/compare-variants-Ciqwvd_f.js +0 -1
  257. package/web/dist/assets/diff-controls-BGrXGi7O.js +0 -1
  258. package/web/dist/assets/dropdown-menu-dwDGT8MM.js +0 -1
  259. package/web/dist/assets/git-toolbar-UiHnGvE0.js +0 -1
  260. package/web/dist/assets/github-D-MrkbJ7.js +0 -1
  261. package/web/dist/assets/ibm-plex-mono-regular-BF3vfe7_.ttf +0 -0
  262. package/web/dist/assets/index-BszfYvBq.js +0 -7
  263. package/web/dist/assets/index-CWh4pKP3.css +0 -1
  264. package/web/dist/assets/markdown-C_IcKVQd.js +0 -2
  265. package/web/dist/assets/pill-BsbO6G7y.js +0 -1
  266. package/web/dist/assets/project-router-DbLkll25.js +0 -1
  267. package/web/dist/assets/prompt-templates-BlTGJB5W.js +0 -15
  268. package/web/dist/assets/repo-git-Bm3s6Why.js +0 -1
  269. package/web/dist/assets/run-header-IFyIGCey.js +0 -1
  270. package/web/dist/assets/skills-C-C4DVFY.js +0 -1
  271. package/web/dist/assets/task-changes-D2PHtWUW.js +0 -1
  272. package/web/dist/assets/task-commits-N5u9U0_R.js +0 -1
  273. package/web/dist/assets/task-files-BS7c7CFm.js +0 -2
  274. package/web/dist/assets/task-thread-BQFdz1dJ.css +0 -1
  275. package/web/dist/assets/task-thread-DGM2dZV-.js +0 -9
  276. package/web/dist/assets/textarea-FjaU370i.js +0 -1
  277. package/web/dist/assets/thread-loading-77sJ8Yu_.js +0 -1
  278. package/web/dist/assets/token-metrics-Clxh03bE.js +0 -1
  279. package/web/dist/assets/utils-PYYcpCFZ.js +0 -64
  280. package/web/dist/assets/workflows-Czl0ZfXH.js +0 -11
@@ -0,0 +1,96 @@
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), hasWebhook: entry.webhook !== undefined })));
57
+ return { origin, projects, bootProject: parsed.data.bootProject };
58
+ }
59
+ catch {
60
+ return undefined;
61
+ }
62
+ }
63
+ function cockpitFor(origin, projectId, hasWebhook) {
64
+ return { origin, projectId, api: `${origin}/api/v1/p/${encodeURIComponent(projectId)}`, hasWebhook };
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
+ const id = match?.id ?? found.bootProject;
84
+ return cockpitFor(origin, id, found.projects.some((entry) => entry.id === id && entry.hasWebhook));
85
+ }
86
+ const ports = options.ports ?? COCKPIT_PORTS;
87
+ const candidates = await Promise.all(ports.map((port) => probe(`http://127.0.0.1:${port}`, timeoutMs)));
88
+ // `ports` is ascending, so the first match is the lowest port serving this checkout.
89
+ for (const candidate of candidates) {
90
+ const match = candidate?.projects.find((entry) => entry.root === root);
91
+ if (candidate && match)
92
+ return cockpitFor(candidate.origin, match.id, match.hasWebhook);
93
+ }
94
+ throw new TaskCliError(2, { code: 'no-cockpit', error: `no running cockpit serves ${root}`, hint });
95
+ }
96
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/task-cli/discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * The loopback HTTP half of `cez task` (#504, spec 2026-09-24-cez-task-cli): plain `fetch`
3
+ * against the cockpit's own `/api/v1/p/:projectId` routes, with request deadlines.
4
+ *
5
+ * No credential is read, sent or printed: the cockpit's origin guard (#426) admits a loopback
6
+ * `Host` with no `Origin`, which is exactly what `fetch` sends.
7
+ */
8
+ export declare const REQUEST_TIMEOUT_MS = 45000;
9
+ /** Every failure carries its exit code and the JSON body the CLI prints. */
10
+ export declare class TaskCliError extends Error {
11
+ readonly exitCode: number;
12
+ readonly body: Record<string, unknown>;
13
+ constructor(exitCode: number, body: Record<string, unknown>);
14
+ }
15
+ export interface Cockpit {
16
+ /** `http://127.0.0.1:<port>` — no trailing slash. */
17
+ origin: string;
18
+ projectId: string;
19
+ /** `${origin}/api/v1/p/${projectId}` */
20
+ api: string;
21
+ /** The project has a task webhook (#589), read from the registry discovery already fetched.
22
+ * Absent = unknown, which `start` treats as "do not opt in". */
23
+ hasWebhook?: boolean;
24
+ }
25
+ export declare function threadUrl(cockpit: Cockpit, runId: string): string;
26
+ export interface HttpResult {
27
+ status: number;
28
+ data: unknown;
29
+ }
30
+ /** One request to an absolute URL. JSON bodies are parsed; anything else comes back as text. */
31
+ export declare function fetchJson(url: string, init?: {
32
+ method?: string;
33
+ body?: unknown;
34
+ timeoutMs?: number;
35
+ responseLimitBytes?: number;
36
+ }): Promise<HttpResult>;
37
+ /** A project-scoped route: `path` starts with `/`, relative to `/api/v1/p/:projectId`. */
38
+ export declare function request(cockpit: Cockpit, path: string, init?: {
39
+ method?: string;
40
+ body?: unknown;
41
+ timeoutMs?: number;
42
+ }): Promise<HttpResult>;
43
+ /** The cockpit said no: pass its `{ error }` through verbatim, exit 2. */
44
+ export declare function refuse(result: HttpResult): never;
45
+ /** A response the contract does not describe is a cockpit problem, not a caller problem. */
46
+ export declare function invalidResponse(what: string): never;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * The loopback HTTP half of `cez task` (#504, spec 2026-09-24-cez-task-cli): plain `fetch`
3
+ * against the cockpit's own `/api/v1/p/:projectId` routes, with request deadlines.
4
+ *
5
+ * No credential is read, sent or printed: the cockpit's origin guard (#426) admits a loopback
6
+ * `Host` with no `Origin`, which is exactly what `fetch` sends.
7
+ */
8
+ const RESPONSE_BYTES = 3_145_728;
9
+ export const REQUEST_TIMEOUT_MS = 45_000;
10
+ /** Every failure carries its exit code and the JSON body the CLI prints. */
11
+ export class TaskCliError extends Error {
12
+ exitCode;
13
+ body;
14
+ constructor(exitCode, body) {
15
+ super(typeof body.error === 'string' ? body.error : 'cez task failed');
16
+ this.exitCode = exitCode;
17
+ this.body = body;
18
+ }
19
+ }
20
+ export function threadUrl(cockpit, runId) {
21
+ return `${cockpit.origin}/p/${encodeURIComponent(cockpit.projectId)}/tasks/${encodeURIComponent(runId)}`;
22
+ }
23
+ /** Enforce a byte limit where the route has a bounded response, including error bodies. */
24
+ async function boundedText(response, limit) {
25
+ if (Number(response.headers.get('content-length')) > limit) {
26
+ await response.body?.cancel();
27
+ throw new Error('Response too large');
28
+ }
29
+ const reader = response.body?.getReader();
30
+ if (!reader)
31
+ return '';
32
+ let size = 0;
33
+ const chunks = [];
34
+ try {
35
+ for (;;) {
36
+ const next = await reader.read();
37
+ if (next.done)
38
+ break;
39
+ size += next.value.length;
40
+ if (size > limit) {
41
+ await reader.cancel();
42
+ throw new Error('Response too large');
43
+ }
44
+ chunks.push(next.value);
45
+ }
46
+ }
47
+ finally {
48
+ reader.releaseLock();
49
+ }
50
+ return Buffer.concat(chunks, size).toString('utf8');
51
+ }
52
+ /** One request to an absolute URL. JSON bodies are parsed; anything else comes back as text. */
53
+ export async function fetchJson(url, init = {}) {
54
+ let response;
55
+ let text;
56
+ try {
57
+ response = await fetch(url, {
58
+ method: init.method ?? (init.body === undefined ? 'GET' : 'POST'),
59
+ redirect: 'error',
60
+ headers: init.body === undefined ? {} : { 'content-type': 'application/json' },
61
+ ...(init.body === undefined ? {} : { body: JSON.stringify(init.body) }),
62
+ signal: AbortSignal.timeout(init.timeoutMs ?? REQUEST_TIMEOUT_MS),
63
+ });
64
+ text = await boundedText(response, response.ok ? (init.responseLimitBytes ?? RESPONSE_BYTES) : RESPONSE_BYTES);
65
+ }
66
+ catch (error) {
67
+ throw new TaskCliError(2, { code: 'unavailable', error: `cockpit request failed: ${error instanceof Error ? error.message : String(error)}` });
68
+ }
69
+ const json = (response.headers.get('content-type') ?? '').includes('application/json');
70
+ if (!json)
71
+ return { status: response.status, data: text };
72
+ try {
73
+ return { status: response.status, data: JSON.parse(text) };
74
+ }
75
+ catch {
76
+ throw new TaskCliError(2, { code: 'unavailable', error: 'cockpit returned invalid JSON' });
77
+ }
78
+ }
79
+ /** A project-scoped route: `path` starts with `/`, relative to `/api/v1/p/:projectId`. */
80
+ export function request(cockpit, path, init = {}) {
81
+ // GET /runs is the existing unpaginated full history. Even 32 valid 100k-character tasks
82
+ // exceed the ordinary cap. Match the cockpit's full-list read rather than making list/wait
83
+ // fail as history grows; retain deadlines, error-body caps and every other route's cap.
84
+ const fullRunList = path === '/runs' && (init.method ?? (init.body === undefined ? 'GET' : 'POST')) === 'GET';
85
+ return fetchJson(`${cockpit.api}${path}`, {
86
+ ...init,
87
+ ...(fullRunList ? { responseLimitBytes: Infinity } : {}),
88
+ });
89
+ }
90
+ /** The cockpit said no: pass its `{ error }` through verbatim, exit 2. */
91
+ export function refuse(result) {
92
+ const error = result.data && typeof result.data === 'object' && typeof result.data.error === 'string'
93
+ ? result.data.error
94
+ : `cockpit answered HTTP ${result.status}`;
95
+ throw new TaskCliError(2, { code: 'refused', status: result.status, error });
96
+ }
97
+ /** A response the contract does not describe is a cockpit problem, not a caller problem. */
98
+ export function invalidResponse(what) {
99
+ throw new TaskCliError(2, { code: 'unavailable', error: `cockpit returned an unexpected ${what} response` });
100
+ }
101
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/task-cli/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { ApiRun, RunStatus } from '../contract/index.js';
2
+ /**
3
+ * The slim shapes `cez task` prints (#504). A bot polls these every few seconds, so each one
4
+ * carries what a caller branches on and nothing it would have to pay tokens to skip: no
5
+ * `steps[]`, no `workflowDef`, no reference candidates. `--full` is the escape hatch.
6
+ */
7
+ export declare const TERMINAL_STATUSES: readonly RunStatus[];
8
+ export declare const SUCCESS_STATUSES: readonly RunStatus[];
9
+ export declare function runTitle(run: Pick<ApiRun, 'title' | 'titleSummary'>): string;
10
+ export declare function projectStatus(run: ApiRun, url: string, question?: unknown): Partial<{
11
+ id: string;
12
+ title: string;
13
+ status: "cancelled" | "done" | "failed" | "queued" | "review" | "running" | "waiting";
14
+ activity: "monitoring" | undefined;
15
+ currentStepId: string | undefined;
16
+ hasPendingHumanAsk: boolean;
17
+ question: unknown;
18
+ branch: string | undefined;
19
+ diffStat: {
20
+ adds: number;
21
+ dels: number;
22
+ files: number;
23
+ repointed?: boolean | undefined;
24
+ } | undefined;
25
+ pullRequestUrl: string | undefined;
26
+ error: string | undefined;
27
+ tokensUsed: number;
28
+ startedAt: string | undefined;
29
+ finishedAt: string | undefined;
30
+ url: string;
31
+ }>;
32
+ /** The record carries no `updatedAt`; the newest lifecycle stamp is the honest stand-in. */
33
+ export declare function projectListRow(run: ApiRun): Partial<{
34
+ id: string;
35
+ title: string;
36
+ status: "cancelled" | "done" | "failed" | "queued" | "review" | "running" | "waiting";
37
+ activity: "monitoring" | undefined;
38
+ hasPendingHumanAsk: boolean;
39
+ updatedAt: string;
40
+ }>;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The slim shapes `cez task` prints (#504). A bot polls these every few seconds, so each one
3
+ * carries what a caller branches on and nothing it would have to pay tokens to skip: no
4
+ * `steps[]`, no `workflowDef`, no reference candidates. `--full` is the escape hatch.
5
+ */
6
+ export const TERMINAL_STATUSES = ['done', 'review', 'failed', 'cancelled'];
7
+ export const SUCCESS_STATUSES = ['done', 'review'];
8
+ /** Keys with an undefined value are left off, so the JSON stays as small as the run is. */
9
+ function defined(value) {
10
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
11
+ }
12
+ export function runTitle(run) {
13
+ return run.titleSummary ?? run.title;
14
+ }
15
+ export function projectStatus(run, url, question) {
16
+ return defined({
17
+ id: run.id,
18
+ title: runTitle(run),
19
+ status: run.status,
20
+ activity: run.activity,
21
+ currentStepId: run.currentStepId,
22
+ hasPendingHumanAsk: run.hasPendingHumanAsk ?? false,
23
+ question,
24
+ branch: run.branch,
25
+ diffStat: run.diffStat,
26
+ pullRequestUrl: run.pullRequestUrl,
27
+ error: run.error,
28
+ tokensUsed: run.tokensUsed,
29
+ startedAt: run.startedAt,
30
+ finishedAt: run.finishedAt,
31
+ url,
32
+ });
33
+ }
34
+ /** The record carries no `updatedAt`; the newest lifecycle stamp is the honest stand-in. */
35
+ export function projectListRow(run) {
36
+ return defined({
37
+ id: run.id,
38
+ title: runTitle(run),
39
+ status: run.status,
40
+ activity: run.activity,
41
+ hasPendingHumanAsk: run.hasPendingHumanAsk ?? false,
42
+ updatedAt: run.finishedAt ?? run.startedAt ?? run.createdAt,
43
+ });
44
+ }
45
+ //# sourceMappingURL=projections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projections.js","sourceRoot":"","sources":["../../src/task-cli/projections.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAyB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AACjG,MAAM,CAAC,MAAM,gBAAgB,GAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEzE,2FAA2F;AAC3F,SAAS,OAAO,CAAoC,KAAQ;IAC1D,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAe,CAAC;AAC5G,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAA2C;IAClE,OAAO,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,KAAK,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,GAAW,EAAE,QAAkB;IACxE,OAAO,OAAO,CAAC;QACb,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC;QACpB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,kBAAkB,EAAE,GAAG,CAAC,kBAAkB,IAAI,KAAK;QACnD,QAAQ;QACR,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,cAAc,EAAE,GAAG,CAAC,cAAc;QAClC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,GAAG;KACJ,CAAC,CAAC;AACL,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,OAAO,CAAC;QACb,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC;QACpB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,kBAAkB,EAAE,GAAG,CAAC,kBAAkB,IAAI,KAAK;QACnD,SAAS,EAAE,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS;KAC5D,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { type RunHistoryEvent, type RunStatus } from '../contract/index.js';
2
+ import { type Cockpit } from './http.ts';
3
+ /**
4
+ * Watching a task from a terminal (#504, spec 2026-09-24-cez-task-cli). Every loop here ends —
5
+ * on a terminal status or at the caller's deadline — because a bot's tool call that never
6
+ * returns is the failure this command family exists to prevent.
7
+ */
8
+ export declare const DEFAULT_POLL_MS = 1500;
9
+ export type WaitMode = 'any' | 'all';
10
+ export type WaitUntil = 'settled' | 'attention';
11
+ export interface WaitEntry {
12
+ id: string;
13
+ /** `unknown`: the deadline passed before any poll answered. */
14
+ status: RunStatus | 'missing' | 'unknown';
15
+ activity?: string;
16
+ hasPendingHumanAsk?: boolean;
17
+ }
18
+ export interface WaitResult {
19
+ exitCode: number;
20
+ runs: WaitEntry[];
21
+ timedOut: boolean;
22
+ }
23
+ /**
24
+ * Grace for the millisecond race between a budget-bounded poll's abort and the
25
+ * deadline check (#538): `AbortSignal.timeout(budget)` can fire while
26
+ * `Date.now()` still reads just under the deadline, turning a timeout into an
27
+ * `unavailable` error (exit 2 instead of 3). A poll whose own abort consumed
28
+ * (almost) all of its budget failed *at* the deadline, so it answers "timed
29
+ * out". The grace never applies to other errors: a genuine failure stays
30
+ * `unavailable` even when it lands inside the grace window.
31
+ */
32
+ export declare const TIMEOUT_GRACE_MS = 250;
33
+ export declare function pollHitDeadline(startedAt: number, budgetMs: number, now?: number): boolean;
34
+ /**
35
+ * True when the wrapped cockpit error came from the poll's own abort (its
36
+ * budget running out) rather than a fast failure such as a refused
37
+ * connection. `fetchJson` folds every fetch failure into `unavailable`, so the
38
+ * abort surfaces only through the original message it preserves (`TimeoutError:
39
+ * The operation was aborted due to timeout`).
40
+ */
41
+ export declare function abortedPoll(error: unknown): boolean;
42
+ /**
43
+ * Polls `GET /runs`: one call covers any number of runs and holds no socket open. Each poll is
44
+ * bounded by what is left of the deadline, so a slow cockpit answers "timed out" on time rather
45
+ * than holding the caller for a full request timeout.
46
+ */
47
+ export declare function waitForRuns(cockpit: Cockpit, ids: string[], options: {
48
+ mode: WaitMode;
49
+ until: WaitUntil;
50
+ timeoutMs: number;
51
+ pollMs?: number;
52
+ }): Promise<WaitResult>;
53
+ /** One printable line per event the log keeps, or undefined for the rest. */
54
+ export declare function logLine(event: RunHistoryEvent): Record<string, unknown> | undefined;
55
+ /**
56
+ * `log`, read from the run's SSE stream, which replays every event after `afterSeq` and then
57
+ * streams live. The route subscribes to live `run` updates BEFORE it replays, so a `run` frame
58
+ * says nothing about where the replay is; the only reliable boundary is a `seq`. So:
59
+ *
60
+ * - the replay ends at `asOfSeq`, the event file's high-water mark read from `GET /history` just
61
+ * before connecting — everything up to it is the tail, bounded to `maxChars`, and without
62
+ * `follow` the command ends there;
63
+ * - with `follow`, a terminal status ends the command only once the stream has caught up with a
64
+ * SECOND high-water read taken after that status arrived, so events the engine wrote just
65
+ * before finishing are not dropped when the status frame overtakes them (exit 0/1, final line
66
+ * is the status).
67
+ *
68
+ * One `deadline` bounds every request, the history reads included (exit 3). Deduped by `seq`.
69
+ * The stream rather than `GET /history` pages: a history page starts at its first transcript
70
+ * item, so it drops lifecycle events such as the opening `step-start`.
71
+ */
72
+ export declare function readLog(cockpit: Cockpit, id: string, options: {
73
+ afterSeq: number;
74
+ maxChars: number;
75
+ follow: boolean;
76
+ deadline: number;
77
+ print: (line: string) => void;
78
+ }): Promise<number>;