@open-mercato/cezar 0.1.5-pr506.357

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 (264) hide show
  1. package/README.md +573 -0
  2. package/dist/config.d.ts +144 -0
  3. package/dist/config.js +106 -0
  4. package/dist/config.js.map +1 -0
  5. package/dist/core/agent-runner.d.ts +169 -0
  6. package/dist/core/agent-runner.js +23 -0
  7. package/dist/core/agent-runner.js.map +1 -0
  8. package/dist/core/backend-detect.d.ts +16 -0
  9. package/dist/core/backend-detect.js +118 -0
  10. package/dist/core/backend-detect.js.map +1 -0
  11. package/dist/core/claude-cli-runner.d.ts +56 -0
  12. package/dist/core/claude-cli-runner.js +416 -0
  13. package/dist/core/claude-cli-runner.js.map +1 -0
  14. package/dist/core/claude-ui-mapper.d.ts +71 -0
  15. package/dist/core/claude-ui-mapper.js +567 -0
  16. package/dist/core/claude-ui-mapper.js.map +1 -0
  17. package/dist/core/codex-app-server-runner.d.ts +29 -0
  18. package/dist/core/codex-app-server-runner.js +489 -0
  19. package/dist/core/codex-app-server-runner.js.map +1 -0
  20. package/dist/core/codex-ui-mapper.d.ts +63 -0
  21. package/dist/core/codex-ui-mapper.js +491 -0
  22. package/dist/core/codex-ui-mapper.js.map +1 -0
  23. package/dist/core/ndjson.d.ts +6 -0
  24. package/dist/core/ndjson.js +23 -0
  25. package/dist/core/ndjson.js.map +1 -0
  26. package/dist/core/opencode-server-runner.d.ts +30 -0
  27. package/dist/core/opencode-server-runner.js +488 -0
  28. package/dist/core/opencode-server-runner.js.map +1 -0
  29. package/dist/core/opencode-ui-mapper.d.ts +105 -0
  30. package/dist/core/opencode-ui-mapper.js +588 -0
  31. package/dist/core/opencode-ui-mapper.js.map +1 -0
  32. package/dist/core/process-usage.d.ts +63 -0
  33. package/dist/core/process-usage.js +181 -0
  34. package/dist/core/process-usage.js.map +1 -0
  35. package/dist/core/runner-factory.d.ts +8 -0
  36. package/dist/core/runner-factory.js +22 -0
  37. package/dist/core/runner-factory.js.map +1 -0
  38. package/dist/core/tool-display.d.ts +30 -0
  39. package/dist/core/tool-display.js +156 -0
  40. package/dist/core/tool-display.js.map +1 -0
  41. package/dist/core/ui-events.d.ts +308 -0
  42. package/dist/core/ui-events.js +25 -0
  43. package/dist/core/ui-events.js.map +1 -0
  44. package/dist/core/usage.d.ts +11 -0
  45. package/dist/core/usage.js +15 -0
  46. package/dist/core/usage.js.map +1 -0
  47. package/dist/git-worktree.d.ts +88 -0
  48. package/dist/git-worktree.js +297 -0
  49. package/dist/git-worktree.js.map +1 -0
  50. package/dist/handoff.d.ts +62 -0
  51. package/dist/handoff.js +147 -0
  52. package/dist/handoff.js.map +1 -0
  53. package/dist/index.d.ts +2 -0
  54. package/dist/index.js +466 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/install-as-command.d.ts +39 -0
  57. package/dist/install-as-command.js +51 -0
  58. package/dist/install-as-command.js.map +1 -0
  59. package/dist/pack-check.d.ts +17 -0
  60. package/dist/pack-check.js +27 -0
  61. package/dist/pack-check.js.map +1 -0
  62. package/dist/paths.d.ts +23 -0
  63. package/dist/paths.js +34 -0
  64. package/dist/paths.js.map +1 -0
  65. package/dist/planner.d.ts +17 -0
  66. package/dist/planner.js +248 -0
  67. package/dist/planner.js.map +1 -0
  68. package/dist/release/snapshot.d.ts +64 -0
  69. package/dist/release/snapshot.js +75 -0
  70. package/dist/release/snapshot.js.map +1 -0
  71. package/dist/release/stable.d.ts +46 -0
  72. package/dist/release/stable.js +57 -0
  73. package/dist/release/stable.js.map +1 -0
  74. package/dist/runs/auto-name.d.ts +75 -0
  75. package/dist/runs/auto-name.js +168 -0
  76. package/dist/runs/auto-name.js.map +1 -0
  77. package/dist/runs/retention.d.ts +60 -0
  78. package/dist/runs/retention.js +86 -0
  79. package/dist/runs/retention.js.map +1 -0
  80. package/dist/runs/review-gate.d.ts +18 -0
  81. package/dist/runs/review-gate.js +21 -0
  82. package/dist/runs/review-gate.js.map +1 -0
  83. package/dist/runs/store.d.ts +408 -0
  84. package/dist/runs/store.js +526 -0
  85. package/dist/runs/store.js.map +1 -0
  86. package/dist/runs/task-refs.d.ts +24 -0
  87. package/dist/runs/task-refs.js +74 -0
  88. package/dist/runs/task-refs.js.map +1 -0
  89. package/dist/runs/ui-event-sink.d.ts +81 -0
  90. package/dist/runs/ui-event-sink.js +210 -0
  91. package/dist/runs/ui-event-sink.js.map +1 -0
  92. package/dist/server/capabilities.d.ts +33 -0
  93. package/dist/server/capabilities.js +43 -0
  94. package/dist/server/capabilities.js.map +1 -0
  95. package/dist/server/forge/github.d.ts +70 -0
  96. package/dist/server/forge/github.js +375 -0
  97. package/dist/server/forge/github.js.map +1 -0
  98. package/dist/server/forge/index.d.ts +24 -0
  99. package/dist/server/forge/index.js +45 -0
  100. package/dist/server/forge/index.js.map +1 -0
  101. package/dist/server/forge/types.d.ts +80 -0
  102. package/dist/server/forge/types.js +2 -0
  103. package/dist/server/forge/types.js.map +1 -0
  104. package/dist/server/git-changes.d.ts +195 -0
  105. package/dist/server/git-changes.js +497 -0
  106. package/dist/server/git-changes.js.map +1 -0
  107. package/dist/server/git.d.ts +26 -0
  108. package/dist/server/git.js +103 -0
  109. package/dist/server/git.js.map +1 -0
  110. package/dist/server/github.d.ts +8 -0
  111. package/dist/server/github.js +8 -0
  112. package/dist/server/github.js.map +1 -0
  113. package/dist/server/launch-key.d.ts +7 -0
  114. package/dist/server/launch-key.js +33 -0
  115. package/dist/server/launch-key.js.map +1 -0
  116. package/dist/server/open-in-app.d.ts +51 -0
  117. package/dist/server/open-in-app.js +189 -0
  118. package/dist/server/open-in-app.js.map +1 -0
  119. package/dist/server/open-in-terminal.d.ts +25 -0
  120. package/dist/server/open-in-terminal.js +120 -0
  121. package/dist/server/open-in-terminal.js.map +1 -0
  122. package/dist/server/pr.d.ts +7 -0
  123. package/dist/server/pr.js +7 -0
  124. package/dist/server/pr.js.map +1 -0
  125. package/dist/server/server.d.ts +41 -0
  126. package/dist/server/server.js +1390 -0
  127. package/dist/server/server.js.map +1 -0
  128. package/dist/server/static-ui.d.ts +49 -0
  129. package/dist/server/static-ui.js +92 -0
  130. package/dist/server/static-ui.js.map +1 -0
  131. package/dist/server/wsl.d.ts +25 -0
  132. package/dist/server/wsl.js +92 -0
  133. package/dist/server/wsl.js.map +1 -0
  134. package/dist/server-install/engine.d.ts +33 -0
  135. package/dist/server-install/engine.js +314 -0
  136. package/dist/server-install/engine.js.map +1 -0
  137. package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
  138. package/dist/server-install/platforms/macosx-ngrok.js +345 -0
  139. package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
  140. package/dist/server-install/platforms/ubuntu-vps.d.ts +39 -0
  141. package/dist/server-install/platforms/ubuntu-vps.js +746 -0
  142. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
  143. package/dist/server-install/state.d.ts +26 -0
  144. package/dist/server-install/state.js +125 -0
  145. package/dist/server-install/state.js.map +1 -0
  146. package/dist/server-install/steps.d.ts +109 -0
  147. package/dist/server-install/steps.js +330 -0
  148. package/dist/server-install/steps.js.map +1 -0
  149. package/dist/server-install/strategies.d.ts +4 -0
  150. package/dist/server-install/strategies.js +20 -0
  151. package/dist/server-install/strategies.js.map +1 -0
  152. package/dist/server-install/types.d.ts +597 -0
  153. package/dist/server-install/types.js +98 -0
  154. package/dist/server-install/types.js.map +1 -0
  155. package/dist/server-install/ui.d.ts +42 -0
  156. package/dist/server-install/ui.js +130 -0
  157. package/dist/server-install/ui.js.map +1 -0
  158. package/dist/skills-banner.d.ts +21 -0
  159. package/dist/skills-banner.js +40 -0
  160. package/dist/skills-banner.js.map +1 -0
  161. package/dist/skills-remote.d.ts +35 -0
  162. package/dist/skills-remote.js +266 -0
  163. package/dist/skills-remote.js.map +1 -0
  164. package/dist/skills.d.ts +45 -0
  165. package/dist/skills.js +182 -0
  166. package/dist/skills.js.map +1 -0
  167. package/dist/todos.d.ts +63 -0
  168. package/dist/todos.js +168 -0
  169. package/dist/todos.js.map +1 -0
  170. package/dist/ui-state.d.ts +12 -0
  171. package/dist/ui-state.js +25 -0
  172. package/dist/ui-state.js.map +1 -0
  173. package/dist/update-check.d.ts +12 -0
  174. package/dist/update-check.js +41 -0
  175. package/dist/update-check.js.map +1 -0
  176. package/dist/workflows/load.d.ts +15 -0
  177. package/dist/workflows/load.js +56 -0
  178. package/dist/workflows/load.js.map +1 -0
  179. package/dist/workflows/run.d.ts +281 -0
  180. package/dist/workflows/run.js +1511 -0
  181. package/dist/workflows/run.js.map +1 -0
  182. package/dist/workflows/types.d.ts +307 -0
  183. package/dist/workflows/types.js +171 -0
  184. package/dist/workflows/types.js.map +1 -0
  185. package/package.json +90 -0
  186. package/scripts/check-pack.mjs +46 -0
  187. package/scripts/dev.mjs +74 -0
  188. package/scripts/install-as-command.mjs +120 -0
  189. package/scripts/mock-claude.mjs +310 -0
  190. package/scripts/release-snapshot.mjs +130 -0
  191. package/scripts/release.mjs +119 -0
  192. package/scripts/test-process-usage.mjs +47 -0
  193. package/web/dist/assets/arrow-left-BE957rJs.js +1 -0
  194. package/web/dist/assets/bundle-mjs-DLPpRFyl.js +1 -0
  195. package/web/dist/assets/centered-state-BddhEEtO.js +43 -0
  196. package/web/dist/assets/chunk-BO2N2NFS-f5igTtpB.js +131 -0
  197. package/web/dist/assets/command-CjhFbABo.js +1 -0
  198. package/web/dist/assets/compare-variants-Cs52IAEG.js +1 -0
  199. package/web/dist/assets/core-BuMqAF_1.js +12 -0
  200. package/web/dist/assets/css-BsVw1vtW.js +1 -0
  201. package/web/dist/assets/dialog-DFvXTkFv.js +1 -0
  202. package/web/dist/assets/diff-view-C9b8AITq.js +4 -0
  203. package/web/dist/assets/diff-woXpYk--.js +1 -0
  204. package/web/dist/assets/dist-FBs4wmIY.js +1 -0
  205. package/web/dist/assets/dist-o_kVMXjg.js +1 -0
  206. package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
  207. package/web/dist/assets/file-BVuztAOd.js +1 -0
  208. package/web/dist/assets/folder-0pJ1NZ_S.js +1 -0
  209. package/web/dist/assets/git-pull-request-DJkAMT0f.js +1 -0
  210. package/web/dist/assets/git-toolbar-CwhQdx3J.js +1 -0
  211. package/web/dist/assets/github-D0rAX4-r.js +1 -0
  212. package/web/dist/assets/go-rLFTqkRN.js +1 -0
  213. package/web/dist/assets/highlighted-body-OFNGDK62-DGHHie_q.js +1 -0
  214. package/web/dist/assets/highlighter-BKVEsACy.js +3 -0
  215. package/web/dist/assets/html-BY76lXLH.js +1 -0
  216. package/web/dist/assets/index-CEkI7QxN.css +2 -0
  217. package/web/dist/assets/index-CO2lH2et.js +11 -0
  218. package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  219. package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  220. package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
  221. package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  222. package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  223. package/web/dist/assets/json-qhed-kSA.js +1 -0
  224. package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
  225. package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
  226. package/web/dist/assets/lib-CNGa3Dig.js +1 -0
  227. package/web/dist/assets/loader-circle-BV3DO9mE.js +1 -0
  228. package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
  229. package/web/dist/assets/markdown-D4-ADgH9.js +1 -0
  230. package/web/dist/assets/mermaid-GHXKKRXX-DM2VsGBG.js +1 -0
  231. package/web/dist/assets/open-mercato-toBr6SOa.svg +11 -0
  232. package/web/dist/assets/prompt-templates-C7ptKvDd.js +15 -0
  233. package/web/dist/assets/python-gzcpVVnB.js +1 -0
  234. package/web/dist/assets/react-dom-Ddtik4qM.js +1 -0
  235. package/web/dist/assets/refresh-cw-DCa-Rlwz.js +1 -0
  236. package/web/dist/assets/repo-git-DIhryGDx.js +1 -0
  237. package/web/dist/assets/run-diff-Dyow8B1q.js +3 -0
  238. package/web/dist/assets/run-header-jx9-18b8.js +1 -0
  239. package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
  240. package/web/dist/assets/search-x-CoCyl7zT.js +1 -0
  241. package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
  242. package/web/dist/assets/skill-detail-DB7x_FQp.js +1 -0
  243. package/web/dist/assets/skills-98vCroU8.js +1 -0
  244. package/web/dist/assets/skills-BKIoqD6K.js +1 -0
  245. package/web/dist/assets/sql-BsFa4tDR.js +1 -0
  246. package/web/dist/assets/square-terminal-B6PZX4Qp.js +1 -0
  247. package/web/dist/assets/tab-link-C5--YMQd.js +1 -0
  248. package/web/dist/assets/task-changes-ejxPGVJw.js +1 -0
  249. package/web/dist/assets/task-commits-C6GO5qT-.js +1 -0
  250. package/web/dist/assets/task-files-CatpCBXa.js +2 -0
  251. package/web/dist/assets/task-thread-BMbXDM3d.js +5 -0
  252. package/web/dist/assets/tasks-table-dgezlCcg.js +1 -0
  253. package/web/dist/assets/trash-2-CDtxmmc8.js +1 -0
  254. package/web/dist/assets/triangle-alert-6su4Js5O.js +1 -0
  255. package/web/dist/assets/tsx-udAQXfEw.js +1 -0
  256. package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
  257. package/web/dist/assets/upload-Bp7hQxll.js +1 -0
  258. package/web/dist/assets/use-desktop-CvTwojOJ.js +3 -0
  259. package/web/dist/assets/utils-rQGbOrwc.js +1 -0
  260. package/web/dist/assets/workflows-Dy2c6790.js +11 -0
  261. package/web/dist/assets/x-Br_jIDBw.js +1 -0
  262. package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
  263. package/web/dist/index.html +70 -0
  264. package/web/open-mercato.svg +11 -0
@@ -0,0 +1,497 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { rmSync } from 'node:fs';
3
+ import { lstat, open, readFile, readdir, realpath, stat } from 'node:fs/promises';
4
+ import { tmpdir } from 'node:os';
5
+ import { join, resolve, sep } from 'node:path';
6
+ /** Run git, never throw — degradation is the caller's policy. `env` overrides (e.g. a scratch
7
+ * `GIT_INDEX_FILE`) merge over the process env. */
8
+ function git(cwd, args, env) {
9
+ return new Promise((resolvePromise) => {
10
+ execFile('git', args, {
11
+ cwd,
12
+ maxBuffer: 32 * 1024 * 1024,
13
+ encoding: 'utf8',
14
+ ...(env ? { env: { ...process.env, ...env } } : {}),
15
+ }, (err, stdout, stderr) => resolvePromise({ ok: !err, stdout: stdout ?? '', stderr: stderr ?? '' }));
16
+ });
17
+ }
18
+ /** First line of git's stderr (or stdout) as a one-line human reason. */
19
+ function gitReason(res, fallback) {
20
+ const text = (res.stderr.trim() || res.stdout.trim()).split('\n')[0]?.trim();
21
+ return text || fallback;
22
+ }
23
+ // ---- structured changes -----------------------------------------------------
24
+ /** Per-file patch cap — the GUI shows a "truncated" note past this. */
25
+ const PATCH_CAP = 200_000;
26
+ /** Parse `git diff --numstat -z -M`: `adds TAB dels TAB path NUL`, or for a
27
+ * rename/copy `adds TAB dels TAB NUL old NUL new NUL`. Binary files report
28
+ * `-` for both counters. Exported for tests. */
29
+ export function parseNumstatZ(out) {
30
+ const tokens = out.split('\0');
31
+ const entries = [];
32
+ let i = 0;
33
+ while (i < tokens.length) {
34
+ const head = tokens[i] ?? '';
35
+ if (!head) {
36
+ i += 1;
37
+ continue;
38
+ }
39
+ const m = /^(\d+|-)\t(\d+|-)\t([\s\S]*)$/.exec(head);
40
+ if (!m) {
41
+ i += 1;
42
+ continue;
43
+ }
44
+ const binary = m[1] === '-';
45
+ const adds = binary ? 0 : Number(m[1]);
46
+ const dels = m[2] === '-' ? 0 : Number(m[2]);
47
+ if (m[3]) {
48
+ entries.push({ adds, dels, binary, path: m[3] });
49
+ i += 1;
50
+ }
51
+ else {
52
+ entries.push({ adds, dels, binary, oldPath: tokens[i + 1] ?? '', path: tokens[i + 2] ?? '' });
53
+ i += 3;
54
+ }
55
+ }
56
+ return entries;
57
+ }
58
+ /** Parse `git diff --name-status -z -M`: `X NUL path NUL`, renames/copies
59
+ * `Rnnn NUL old NUL new NUL`. Exported for tests. */
60
+ export function parseNameStatusZ(out) {
61
+ const tokens = out.split('\0');
62
+ const entries = [];
63
+ let i = 0;
64
+ while (i < tokens.length) {
65
+ const status = tokens[i] ?? '';
66
+ if (!status) {
67
+ i += 1;
68
+ continue;
69
+ }
70
+ if (/^[RC]/.test(status)) {
71
+ entries.push({ status, oldPath: tokens[i + 1] ?? '', path: tokens[i + 2] ?? '' });
72
+ i += 3;
73
+ }
74
+ else {
75
+ entries.push({ status, path: tokens[i + 1] ?? '' });
76
+ i += 2;
77
+ }
78
+ }
79
+ return entries;
80
+ }
81
+ /** Split one `git diff --patch` blob into per-file sections, in git's file
82
+ * order (the same order `--numstat`/`--name-status` use). Exported for tests. */
83
+ export function splitPatch(patch) {
84
+ if (!patch.trim())
85
+ return [];
86
+ const starts = [];
87
+ const re = /^diff --git /gm;
88
+ for (let m = re.exec(patch); m; m = re.exec(patch))
89
+ starts.push(m.index);
90
+ return starts.map((start, idx) => patch.slice(start, starts[idx + 1] ?? patch.length));
91
+ }
92
+ /** Undo git's C-style path quoting (`core.quotePath`): git wraps paths with
93
+ * special bytes in double-quotes and escapes `\`, `"`, `\t`, `\n`, `\r`, `\f`
94
+ * plus octal `\NNN` byte escapes. Unquoted input (the common ASCII case, and
95
+ * anything containing only a space) is returned verbatim. Octal escapes are
96
+ * decoded per byte, which is lossy for multibyte UTF-8 names — those rare
97
+ * paths simply miss the map and fall back to positional matching below. */
98
+ function unquoteGitPath(raw) {
99
+ if (!raw.startsWith('"') || !raw.endsWith('"'))
100
+ return raw;
101
+ const inner = raw.slice(1, -1);
102
+ return inner.replace(/\\([\\"tnrf])|\\([0-7]{3})/g, (_m, esc, oct) => {
103
+ if (oct)
104
+ return String.fromCharCode(parseInt(oct, 8));
105
+ switch (esc) {
106
+ case 't':
107
+ return '\t';
108
+ case 'n':
109
+ return '\n';
110
+ case 'r':
111
+ return '\r';
112
+ case 'f':
113
+ return '\f';
114
+ default:
115
+ return esc ?? '';
116
+ }
117
+ });
118
+ }
119
+ /** The new-side ("b/") path a single `git diff` section describes, or null when
120
+ * it can't be resolved. Renames/copies report their target; a deletion reports
121
+ * its removed ("a/") path — the exact path `git diff --name-status` lists for
122
+ * the same entry, so the two associate by path. The `---`/`+++` lines carry one
123
+ * path each (never ambiguous, even with spaces); only binary/mode-only/submodule
124
+ * sections, which lack them, fall back to the `diff --git` header. */
125
+ function sectionPath(section) {
126
+ const renameTo = section.match(/^rename to (.+)$/m) ?? section.match(/^copy to (.+)$/m);
127
+ if (renameTo)
128
+ return unquoteGitPath(renameTo[1] ?? '');
129
+ const plus = section.match(/^\+\+\+ (.+)$/m);
130
+ if (plus && plus[1] !== '/dev/null')
131
+ return stripSidePrefix(unquoteGitPath(plus[1] ?? ''));
132
+ const minus = section.match(/^--- (.+)$/m);
133
+ if (minus && minus[1] !== '/dev/null')
134
+ return stripSidePrefix(unquoteGitPath(minus[1] ?? ''));
135
+ const nl = section.indexOf('\n');
136
+ const header = nl < 0 ? section : section.slice(0, nl);
137
+ const quoted = header.match(/^diff --git (?:"a\/.*"|a\/\S+) (?:"b\/(.*)"|b\/(\S+))$/);
138
+ if (quoted)
139
+ return unquoteGitPath(quoted[1] != null ? `"${quoted[1]}"` : (quoted[2] ?? ''));
140
+ return null;
141
+ }
142
+ /** Strip the single leading `a/` or `b/` diff prefix (a real path segment named
143
+ * `a`/`b` keeps its later segments — only the first prefix is removed). */
144
+ function stripSidePrefix(p) {
145
+ return p.replace(/^[ab]\//, '');
146
+ }
147
+ /** Map each `git diff --patch` section to the file path it describes, so a file's
148
+ * patch is looked up by path rather than by position. This is robust to the two
149
+ * listings (`--name-status` and `--patch`) disagreeing on file count — the case
150
+ * where positional matching used to blank *every* file's patch. Exported for tests. */
151
+ export function patchByPath(sections) {
152
+ const map = new Map();
153
+ for (const section of sections) {
154
+ const path = sectionPath(section);
155
+ if (path != null && !map.has(path))
156
+ map.set(path, section);
157
+ }
158
+ return map;
159
+ }
160
+ function statusWord(letter) {
161
+ switch (letter[0]) {
162
+ case 'A':
163
+ return 'added';
164
+ case 'D':
165
+ return 'deleted';
166
+ case 'R':
167
+ return 'renamed';
168
+ case 'C':
169
+ return 'copied';
170
+ default:
171
+ // M, T (typechange), U — the GUI treats them all as "modified".
172
+ return 'modified';
173
+ }
174
+ }
175
+ /**
176
+ * Structured "what changed here" for a directory vs its base branch:
177
+ * committed + uncommitted + untracked (via `add -N`), anchored at the
178
+ * merge-base so the diff stays *this task's* changes even after the base
179
+ * moves on — the exact resolution `worktreeDiff` (src/git-worktree.ts) uses
180
+ * for the text-blob `/diff` endpoint, which stays untouched.
181
+ */
182
+ export async function collectChanges(dir, baseBranch, opts = {}) {
183
+ const patchCap = opts.patchCap ?? PATCH_CAP;
184
+ // `git add -N .` (intent-to-add) makes untracked files appear in the diff, but it MUTATES the
185
+ // index — fine in a task worktree cezar owns, but forbidden on the user's real main tree (a
186
+ // read-only GET must never stage files, #major-index-mutation). When `intentToAdd` is false we
187
+ // build a SCRATCH index (GIT_INDEX_FILE) seeded from HEAD + intent-to-add, so untracked files
188
+ // still show WITHOUT touching the user's real index.
189
+ let env;
190
+ let scratchIndex;
191
+ try {
192
+ if (opts.intentToAdd === false) {
193
+ scratchIndex = join(tmpdir(), `cez-scratch-index-${process.pid}-${scratchSeq++}`);
194
+ env = { GIT_INDEX_FILE: scratchIndex };
195
+ await git(dir, ['read-tree', 'HEAD'], env); // seed with tracked files; harmless if no HEAD
196
+ await git(dir, ['add', '-N', '.'], env);
197
+ }
198
+ else {
199
+ await git(dir, ['add', '-N', '.']);
200
+ }
201
+ const mergeBase = await git(dir, ['merge-base', baseBranch, 'HEAD']);
202
+ const base = mergeBase.ok && mergeBase.stdout.trim() ? mergeBase.stdout.trim() : baseBranch;
203
+ const nameStatus = await git(dir, ['diff', '--name-status', '-z', '-M', base], env);
204
+ if (!nameStatus.ok)
205
+ return { ok: false, error: gitReason(nameStatus, 'git diff failed') };
206
+ const numstat = await git(dir, ['diff', '--numstat', '-z', '-M', base], env);
207
+ if (!numstat.ok)
208
+ return { ok: false, error: gitReason(numstat, 'git diff failed') };
209
+ const patchOut = await git(dir, ['diff', '--patch', '-M', '--no-color', base], env);
210
+ if (!patchOut.ok)
211
+ return { ok: false, error: gitReason(patchOut, 'git diff failed') };
212
+ return { ok: true, changes: assemblePayload(nameStatus.stdout, numstat.stdout, patchOut.stdout, patchCap) };
213
+ }
214
+ finally {
215
+ if (scratchIndex)
216
+ rmSync(scratchIndex, { force: true });
217
+ }
218
+ }
219
+ /** Monotonic suffix for scratch index files, so concurrent /api/repo/changes calls never share
220
+ * one (each is cleaned up in the finally above). */
221
+ let scratchSeq = 0;
222
+ /** The three raw `git diff` listings (name-status, numstat, patch) → the `{files, stat}`
223
+ * payload. Shared by the working-tree diff above and the commit diff below. Each file's
224
+ * patch is matched by path (`patchByPath`), so a mismatch between the name-status and
225
+ * patch file counts — a typechange, submodule, or any entry that emits no `diff --git`
226
+ * block — drops at most that one file's patch instead of blanking every file's. Positional
227
+ * matching remains the fallback for a section whose path can't be parsed, but only when the
228
+ * counts agree (the same condition the old all-or-nothing guard required). Exported for tests. */
229
+ export function assemblePayload(nameStatusOut, numstatOut, patchOut, patchCap) {
230
+ const statuses = parseNameStatusZ(nameStatusOut);
231
+ const counts = parseNumstatZ(numstatOut);
232
+ const patches = splitPatch(patchOut);
233
+ const countByPath = new Map(counts.map((entry) => [entry.path, entry]));
234
+ const patchesByPath = patchByPath(patches);
235
+ const alignable = patches.length === statuses.length;
236
+ const files = statuses.map((entry, idx) => {
237
+ const count = countByPath.get(entry.path);
238
+ let patch = patchesByPath.get(entry.path) ?? (alignable ? (patches[idx] ?? '') : '');
239
+ if (patch.length > patchCap)
240
+ patch = `${patch.slice(0, patchCap)}\n… (patch truncated)`;
241
+ return {
242
+ path: entry.path,
243
+ ...(entry.oldPath ? { oldPath: entry.oldPath } : {}),
244
+ status: statusWord(entry.status),
245
+ adds: count?.adds ?? 0,
246
+ dels: count?.dels ?? 0,
247
+ binary: count?.binary ?? false,
248
+ patch,
249
+ };
250
+ });
251
+ return {
252
+ files,
253
+ stat: {
254
+ adds: files.reduce((sum, f) => sum + f.adds, 0),
255
+ dels: files.reduce((sum, f) => sum + f.dels, 0),
256
+ files: files.length,
257
+ },
258
+ };
259
+ }
260
+ /**
261
+ * The commits a run made on its worktree branch: `<merge-base>..HEAD`, newest first — the same
262
+ * range `collectChanges` diffs, so the commit list and the aggregate Changes tab always agree on
263
+ * what "this task's work" means. Empty (not an error) when the branch has no commits past base.
264
+ */
265
+ export async function collectRunCommits(dir, baseBranch) {
266
+ const mergeBase = await git(dir, ['merge-base', baseBranch, 'HEAD']);
267
+ const base = mergeBase.ok && mergeBase.stdout.trim() ? mergeBase.stdout.trim() : baseBranch;
268
+ const log = await git(dir, ['log', '--pretty=format:%H%x1f%s%x1f%an%x1f%cr', `${base}..HEAD`]);
269
+ if (!log.ok)
270
+ return { ok: false, error: gitReason(log, 'git log failed') };
271
+ const commits = log.stdout
272
+ .split('\n')
273
+ .filter(Boolean)
274
+ .map((line) => {
275
+ const [sha = '', subject = '', author = '', when = ''] = line.split('\x1f');
276
+ return { sha, subject, author, when };
277
+ });
278
+ return { ok: true, commits };
279
+ }
280
+ /**
281
+ * Structured diff of ONE commit vs its first parent (`--root` covers the initial commit).
282
+ * A merge commit honestly answers zero files — `git diff-tree` shows no diff for merges
283
+ * without `-m`/`-c`, and inventing one side's diff would misattribute the changes.
284
+ * Unknown/invalid shas degrade to `{ ok:false, error }` for the route's 409.
285
+ */
286
+ export async function collectCommitChanges(dir, sha, patchCap = PATCH_CAP) {
287
+ if (!/^[0-9a-f]{4,40}$/i.test(sha))
288
+ return { ok: false, error: `not a commit hash: ${sha}` };
289
+ const meta = await git(dir, ['show', '-s', '--format=%H%x1f%s%x1f%an%x1f%cr', `${sha}^{commit}`]);
290
+ if (!meta.ok)
291
+ return { ok: false, error: gitReason(meta, `unknown commit: ${sha}`) };
292
+ const [fullSha = '', subject = '', author = '', when = ''] = meta.stdout.trim().split('\x1f');
293
+ const common = ['diff-tree', '--no-commit-id', '--root', '-r', '-M'];
294
+ const nameStatus = await git(dir, [...common, '--name-status', '-z', fullSha]);
295
+ if (!nameStatus.ok)
296
+ return { ok: false, error: gitReason(nameStatus, 'git diff-tree failed') };
297
+ const numstat = await git(dir, [...common, '--numstat', '-z', fullSha]);
298
+ if (!numstat.ok)
299
+ return { ok: false, error: gitReason(numstat, 'git diff-tree failed') };
300
+ const patchOut = await git(dir, [...common, '--patch', '--no-color', fullSha]);
301
+ if (!patchOut.ok)
302
+ return { ok: false, error: gitReason(patchOut, 'git diff-tree failed') };
303
+ const payload = assemblePayload(nameStatus.stdout, numstat.stdout, patchOut.stdout, patchCap);
304
+ return { ok: true, commit: { sha: fullSha, subject, author, when, ...payload } };
305
+ }
306
+ // ---- worktree file browsing ---------------------------------------------------
307
+ /** Max file content served to the Files tab — past this the GUI shows an
308
+ * honest "too large" state instead of the bytes. */
309
+ export const FILE_CONTENT_CAP = 512_000;
310
+ /**
311
+ * Extensions the Files tab renders inline as `<img>` — the only kinds the
312
+ * `/files?raw=1` mode will ever serve as bytes (anything else stays JSON, so a
313
+ * worktree HTML file can never become a same-origin document). SVG is included:
314
+ * inert inside `<img>`, and the raw response carries a no-script CSP for the
315
+ * "opened the URL directly" case. Keep in sync with IMAGE_EXTENSIONS in
316
+ * web/app/src/routes/task-git/file-preview.tsx.
317
+ */
318
+ const IMAGE_MIME = {
319
+ png: 'image/png',
320
+ jpg: 'image/jpeg',
321
+ jpeg: 'image/jpeg',
322
+ gif: 'image/gif',
323
+ webp: 'image/webp',
324
+ svg: 'image/svg+xml',
325
+ bmp: 'image/bmp',
326
+ ico: 'image/x-icon',
327
+ avif: 'image/avif',
328
+ };
329
+ /** The image MIME type for a path, or null when it is not an image we serve raw. */
330
+ export function imageMimeType(path) {
331
+ const name = path.slice(path.lastIndexOf('/') + 1);
332
+ const dot = name.lastIndexOf('.');
333
+ if (dot <= 0)
334
+ return null;
335
+ return IMAGE_MIME[name.slice(dot + 1).toLowerCase()] ?? null;
336
+ }
337
+ /** True when the first 8 KB contain a NUL byte — good enough for a viewer flag. */
338
+ async function sniffBinary(path, size) {
339
+ const handle = await open(path, 'r');
340
+ try {
341
+ const len = Math.min(size, 8192);
342
+ if (len === 0)
343
+ return false;
344
+ const buf = Buffer.alloc(len);
345
+ await handle.read(buf, 0, len, 0);
346
+ return buf.includes(0);
347
+ }
348
+ finally {
349
+ await handle.close();
350
+ }
351
+ }
352
+ /**
353
+ * Directory listing or file content from inside `root`, traversal-safe:
354
+ * anything resolving outside the root (dot-segments, absolute paths, NUL) is
355
+ * rejected — same "not a file we serve" stance as `isSafeAssetFilename` in
356
+ * src/server/static-ui.ts. `.git` and symlinks are off-limits too.
357
+ */
358
+ export async function readWorktreePath(root, relPath, contentCap = FILE_CONTENT_CAP) {
359
+ if (relPath.includes('\0'))
360
+ return { kind: 'invalid', error: 'invalid path' };
361
+ const rootAbs = resolve(root);
362
+ const target = resolve(rootAbs, relPath);
363
+ if (target !== rootAbs && !target.startsWith(rootAbs + sep)) {
364
+ return { kind: 'invalid', error: `path escapes the worktree: ${relPath}` };
365
+ }
366
+ const gitDir = join(rootAbs, '.git');
367
+ if (target === gitDir || target.startsWith(gitDir + sep)) {
368
+ return { kind: 'invalid', error: '.git internals are not browsable' };
369
+ }
370
+ const display = target === rootAbs ? '' : target.slice(rootAbs.length + 1).split(sep).join('/');
371
+ let info;
372
+ try {
373
+ info = await lstat(target);
374
+ }
375
+ catch {
376
+ return { kind: 'missing', error: `no such file or directory in the worktree: ${relPath || '/'}` };
377
+ }
378
+ if (info.isSymbolicLink()) {
379
+ return { kind: 'invalid', error: `symlinks are not served: ${display}` };
380
+ }
381
+ // Intermediate symlinked DIRECTORIES: `resolve()` never follows links and the `lstat` above
382
+ // only guards the final component, so a path through a symlinked dir (e.g. `link/secret.txt`
383
+ // where `link -> /etc`) would otherwise be served. Resolve the whole chain and re-check
384
+ // containment against the real root (#blocker-symlink-traversal).
385
+ let realTarget;
386
+ let realRoot;
387
+ try {
388
+ realTarget = await realpath(target);
389
+ realRoot = await realpath(rootAbs);
390
+ }
391
+ catch {
392
+ return { kind: 'missing', error: `no such file or directory in the worktree: ${relPath || '/'}` };
393
+ }
394
+ if (realTarget !== realRoot && !realTarget.startsWith(realRoot + sep)) {
395
+ return { kind: 'invalid', error: `path escapes the worktree: ${relPath}` };
396
+ }
397
+ if (info.isDirectory()) {
398
+ const dirents = await readdir(target, { withFileTypes: true });
399
+ const entries = [];
400
+ for (const d of dirents) {
401
+ if (d.name === '.git')
402
+ continue;
403
+ if (d.isDirectory()) {
404
+ entries.push({ name: d.name, type: 'dir' });
405
+ }
406
+ else if (d.isFile()) {
407
+ const size = await stat(join(target, d.name))
408
+ .then((s) => s.size)
409
+ .catch(() => undefined);
410
+ entries.push({ name: d.name, type: 'file', ...(size !== undefined ? { size } : {}) });
411
+ }
412
+ // Symlinks, sockets, … deliberately omitted from the listing.
413
+ }
414
+ entries.sort((a, b) => (a.type === b.type ? a.name.localeCompare(b.name) : a.type === 'dir' ? -1 : 1));
415
+ return { kind: 'dir', path: display, entries };
416
+ }
417
+ if (!info.isFile())
418
+ return { kind: 'invalid', error: `not a regular file: ${display}` };
419
+ const binary = await sniffBinary(target, info.size).catch(() => true);
420
+ const tooLarge = info.size > contentCap;
421
+ if (binary || tooLarge) {
422
+ return { kind: 'file', path: display, size: info.size, binary, tooLarge };
423
+ }
424
+ const content = await readFile(target, 'utf8');
425
+ return { kind: 'file', path: display, size: info.size, binary: false, tooLarge: false, content };
426
+ }
427
+ /**
428
+ * Repo-view branch action (`POST /api/repo/branch`): switch to `name` when it
429
+ * already exists locally, otherwise create it from `from` (or HEAD) and switch.
430
+ * Name validation is delegated to `git check-ref-format --branch` — git's own
431
+ * rules, not a reimplementation. Predictable failures (invalid name, unknown
432
+ * `from`, dirty-tree checkout conflict) come back as `{ ok:false, error }`.
433
+ */
434
+ export async function createOrSwitchBranch(dir, name, from) {
435
+ const check = await git(dir, ['check-ref-format', '--branch', name]);
436
+ if (!check.ok)
437
+ return { ok: false, error: `invalid branch name: ${name}` };
438
+ const exists = await git(dir, ['rev-parse', '--verify', '--quiet', `refs/heads/${name}`]);
439
+ if (exists.ok) {
440
+ const sw = await git(dir, ['checkout', name]);
441
+ if (!sw.ok)
442
+ return { ok: false, error: gitReason(sw, `git checkout ${name} failed`) };
443
+ return { ok: true, branch: name, created: false };
444
+ }
445
+ if (from) {
446
+ // `--quiet` keeps git silent on failure, so supply our own reason.
447
+ const start = await git(dir, ['rev-parse', '--verify', '--quiet', `${from}^{commit}`]);
448
+ if (!start.ok)
449
+ return { ok: false, error: `unknown start point: ${from}` };
450
+ }
451
+ const create = await git(dir, from ? ['checkout', '-b', name, from] : ['checkout', '-b', name]);
452
+ if (!create.ok)
453
+ return { ok: false, error: gitReason(create, `git checkout -b ${name} failed`) };
454
+ return { ok: true, branch: name, created: true };
455
+ }
456
+ /** `git add -A && git commit -m <message>` in `dir`. A clean tree, a failing
457
+ * hook or missing identity all come back as `{ ok:false, error }`. */
458
+ export async function commitAll(dir, message) {
459
+ const status = await git(dir, ['status', '--porcelain']);
460
+ if (!status.ok)
461
+ return { ok: false, error: gitReason(status, 'git status failed') };
462
+ if (!status.stdout.trim()) {
463
+ return { ok: false, error: 'nothing to commit — the working tree is clean' };
464
+ }
465
+ const add = await git(dir, ['add', '-A']);
466
+ if (!add.ok)
467
+ return { ok: false, error: gitReason(add, 'git add failed') };
468
+ const commit = await git(dir, ['commit', '-m', message]);
469
+ if (!commit.ok)
470
+ return { ok: false, error: gitReason(commit, 'git commit failed') };
471
+ const head = await git(dir, ['rev-parse', 'HEAD']);
472
+ return { ok: true, sha: head.ok ? head.stdout.trim() : '' };
473
+ }
474
+ /** Push the current branch, setting upstream when it has none. No remote,
475
+ * detached HEAD and rejected pushes all degrade to `{ ok:false, error }`. */
476
+ export async function pushCurrentBranch(dir) {
477
+ const branchRes = await git(dir, ['rev-parse', '--abbrev-ref', 'HEAD']);
478
+ if (!branchRes.ok)
479
+ return { ok: false, error: gitReason(branchRes, 'not a git repository') };
480
+ const branch = branchRes.stdout.trim();
481
+ if (!branch || branch === 'HEAD') {
482
+ return { ok: false, error: 'detached HEAD — check out a branch before pushing' };
483
+ }
484
+ const remotesRes = await git(dir, ['remote']);
485
+ const remotes = remotesRes.stdout.split('\n').map((r) => r.trim()).filter(Boolean);
486
+ if (remotes.length === 0) {
487
+ return { ok: false, error: 'no remote configured — add one with `git remote add origin <url>`' };
488
+ }
489
+ const remote = remotes.includes('origin') ? 'origin' : remotes[0];
490
+ const upstream = await git(dir, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}']);
491
+ const args = upstream.ok ? ['push'] : ['push', '-u', remote, branch];
492
+ const push = await git(dir, args);
493
+ if (!push.ok)
494
+ return { ok: false, error: gitReason(push, 'git push failed') };
495
+ return { ok: true, branch, remote, upstreamSet: !upstream.ok };
496
+ }
497
+ //# sourceMappingURL=git-changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-changes.js","sourceRoot":"","sources":["../../src/server/git-changes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export interface RepoInfo {
2
+ root: string;
3
+ branch: string;
4
+ remote?: string;
5
+ }
6
+ export interface StatusEntry {
7
+ status: string;
8
+ path: string;
9
+ }
10
+ export interface LogEntry {
11
+ hash: string;
12
+ subject: string;
13
+ author: string;
14
+ when: string;
15
+ }
16
+ /** Null when `dir` isn't inside a git repository. */
17
+ export declare function getRepoInfo(dir: string): Promise<RepoInfo | null>;
18
+ export declare function getStatus(root: string): Promise<StatusEntry[]>;
19
+ /** Working-tree diff vs HEAD (staged + unstaged), capped for the GUI. */
20
+ export declare function getDiff(root: string, cap?: number): Promise<string>;
21
+ /** Local + origin branch names, deduped (origin/x counts as x), sorted.
22
+ * Feeds the Repo tab's base-branch picker. */
23
+ export declare function getBranches(root: string): Promise<string[]>;
24
+ /** One commit — message + stat + patch — for the Repo view's expandable rows. */
25
+ export declare function getCommit(root: string, sha: string, cap?: number): Promise<string>;
26
+ export declare function getLog(root: string, count?: number): Promise<LogEntry[]>;
@@ -0,0 +1,103 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const exec = promisify(execFile);
4
+ async function git(root, args) {
5
+ const { stdout } = await exec('git', args, { cwd: root, maxBuffer: 10 * 1024 * 1024 });
6
+ return stdout;
7
+ }
8
+ /** Null when `dir` isn't inside a git repository. */
9
+ export async function getRepoInfo(dir) {
10
+ try {
11
+ const root = (await git(dir, ['rev-parse', '--show-toplevel'])).trim();
12
+ const branch = (await git(root, ['rev-parse', '--abbrev-ref', 'HEAD'])).trim();
13
+ let remote;
14
+ try {
15
+ remote = (await git(root, ['remote', 'get-url', 'origin'])).trim() || undefined;
16
+ }
17
+ catch {
18
+ // No remote named `origin` — fall back to the first configured remote,
19
+ // so repos whose only remote is named e.g. `github` or `upstream` still
20
+ // get forge detection. Truly remote-less repos land in the inner catch.
21
+ try {
22
+ const names = (await git(root, ['remote'])).split('\n').map((n) => n.trim()).filter(Boolean);
23
+ if (names[0]) {
24
+ remote = (await git(root, ['remote', 'get-url', names[0]])).trim() || undefined;
25
+ }
26
+ }
27
+ catch {
28
+ // no remotes at all — local-only repo
29
+ }
30
+ }
31
+ return { root, branch, remote };
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ export async function getStatus(root) {
38
+ const out = await git(root, ['status', '--porcelain']);
39
+ return out
40
+ .split('\n')
41
+ .filter(Boolean)
42
+ .map((line) => ({ status: line.slice(0, 2).trim() || '??', path: line.slice(3) }));
43
+ }
44
+ /** Working-tree diff vs HEAD (staged + unstaged), capped for the GUI. */
45
+ export async function getDiff(root, cap = 400_000) {
46
+ const diff = await git(root, ['diff', 'HEAD']);
47
+ if (diff.length > cap)
48
+ return `${diff.slice(0, cap)}\n… (diff truncated)`;
49
+ return diff;
50
+ }
51
+ /** Local + origin branch names, deduped (origin/x counts as x), sorted.
52
+ * Feeds the Repo tab's base-branch picker. */
53
+ export async function getBranches(root) {
54
+ const names = new Set();
55
+ try {
56
+ const local = await git(root, ['branch', '--list', '--format=%(refname:short)']);
57
+ for (const line of local.split('\n')) {
58
+ const name = line.trim();
59
+ if (name)
60
+ names.add(name);
61
+ }
62
+ }
63
+ catch {
64
+ // no branches — empty list
65
+ }
66
+ try {
67
+ const remote = await git(root, ['branch', '-r', '--list', '--format=%(refname:short)']);
68
+ for (const line of remote.split('\n')) {
69
+ const name = line.trim();
70
+ if (!name || name.includes('HEAD'))
71
+ continue;
72
+ names.add(name.replace(/^origin\//, ''));
73
+ }
74
+ }
75
+ catch {
76
+ // no remotes — local only
77
+ }
78
+ return [...names].filter((n) => !n.startsWith('cez/')).sort((a, b) => a.localeCompare(b));
79
+ }
80
+ /** One commit — message + stat + patch — for the Repo view's expandable rows. */
81
+ export async function getCommit(root, sha, cap = 200_000) {
82
+ if (!/^[0-9a-f]{4,40}$/i.test(sha))
83
+ return '(not a commit hash)';
84
+ const out = await git(root, ['show', '--stat', '--patch', '--no-color', sha]);
85
+ if (out.length > cap)
86
+ return `${out.slice(0, cap)}\n… (diff truncated)`;
87
+ return out;
88
+ }
89
+ export async function getLog(root, count = 20) {
90
+ const out = await git(root, [
91
+ 'log',
92
+ `-${count}`,
93
+ '--pretty=format:%h%x1f%s%x1f%an%x1f%cr',
94
+ ]);
95
+ return out
96
+ .split('\n')
97
+ .filter(Boolean)
98
+ .map((line) => {
99
+ const [hash = '', subject = '', author = '', when = ''] = line.split('\x1f');
100
+ return { hash, subject, author, when };
101
+ });
102
+ }
103
+ //# sourceMappingURL=git.js.map