@wjarka/cezarion 0.10.0-pr30.54

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 (478) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +838 -0
  3. package/dist/agent-config/account-identity.d.ts +44 -0
  4. package/dist/agent-config/account-identity.js +128 -0
  5. package/dist/agent-config/account-identity.js.map +1 -0
  6. package/dist/agent-config/catalog.d.ts +72 -0
  7. package/dist/agent-config/catalog.js +223 -0
  8. package/dist/agent-config/catalog.js.map +1 -0
  9. package/dist/agent-config/files.d.ts +46 -0
  10. package/dist/agent-config/files.js +119 -0
  11. package/dist/agent-config/files.js.map +1 -0
  12. package/dist/agent-config/model-settings/claude.d.ts +2 -0
  13. package/dist/agent-config/model-settings/claude.js +11 -0
  14. package/dist/agent-config/model-settings/claude.js.map +1 -0
  15. package/dist/agent-config/model-settings/codex.d.ts +2 -0
  16. package/dist/agent-config/model-settings/codex.js +16 -0
  17. package/dist/agent-config/model-settings/codex.js.map +1 -0
  18. package/dist/agent-config/model-settings/opencode.d.ts +2 -0
  19. package/dist/agent-config/model-settings/opencode.js +8 -0
  20. package/dist/agent-config/model-settings/opencode.js.map +1 -0
  21. package/dist/agent-config/model-settings/pi.d.ts +12 -0
  22. package/dist/agent-config/model-settings/pi.js +18 -0
  23. package/dist/agent-config/model-settings/pi.js.map +1 -0
  24. package/dist/agent-config/model-settings/shared.d.ts +9 -0
  25. package/dist/agent-config/model-settings/shared.js +93 -0
  26. package/dist/agent-config/model-settings/shared.js.map +1 -0
  27. package/dist/agent-config/model-settings/types.d.ts +9 -0
  28. package/dist/agent-config/model-settings/types.js +2 -0
  29. package/dist/agent-config/model-settings/types.js.map +1 -0
  30. package/dist/agent-config/models.d.ts +9 -0
  31. package/dist/agent-config/models.js +32 -0
  32. package/dist/agent-config/models.js.map +1 -0
  33. package/dist/agent-config/seed.d.ts +7 -0
  34. package/dist/agent-config/seed.js +90 -0
  35. package/dist/agent-config/seed.js.map +1 -0
  36. package/dist/agent-config/service.d.ts +44 -0
  37. package/dist/agent-config/service.js +71 -0
  38. package/dist/agent-config/service.js.map +1 -0
  39. package/dist/agent-config/validate.d.ts +21 -0
  40. package/dist/agent-config/validate.js +76 -0
  41. package/dist/agent-config/validate.js.map +1 -0
  42. package/dist/automations/coordinator.d.ts +26 -0
  43. package/dist/automations/coordinator.js +66 -0
  44. package/dist/automations/coordinator.js.map +1 -0
  45. package/dist/automations/github-poller.d.ts +74 -0
  46. package/dist/automations/github-poller.js +234 -0
  47. package/dist/automations/github-poller.js.map +1 -0
  48. package/dist/automations/scheduler.d.ts +42 -0
  49. package/dist/automations/scheduler.js +192 -0
  50. package/dist/automations/scheduler.js.map +1 -0
  51. package/dist/automations/store.d.ts +65 -0
  52. package/dist/automations/store.js +298 -0
  53. package/dist/automations/store.js.map +1 -0
  54. package/dist/automations/task-template.d.ts +18 -0
  55. package/dist/automations/task-template.js +95 -0
  56. package/dist/automations/task-template.js.map +1 -0
  57. package/dist/automations/types.d.ts +255 -0
  58. package/dist/automations/types.js +159 -0
  59. package/dist/automations/types.js.map +1 -0
  60. package/dist/config.d.ts +77 -0
  61. package/dist/config.js +242 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/contract/agent-config.d.ts +153 -0
  64. package/dist/contract/agent-profiles.d.ts +347 -0
  65. package/dist/contract/automations.d.ts +935 -0
  66. package/dist/contract/events.d.ts +104 -0
  67. package/dist/contract/github.d.ts +556 -0
  68. package/dist/contract/health.d.ts +102 -0
  69. package/dist/contract/index.d.ts +16 -0
  70. package/dist/contract/index.js +1895 -0
  71. package/dist/contract/projects.d.ts +210 -0
  72. package/dist/contract/repo.d.ts +234 -0
  73. package/dist/contract/runs.d.ts +1473 -0
  74. package/dist/contract/skills.d.ts +232 -0
  75. package/dist/contract/workflows.d.ts +218 -0
  76. package/dist/contract/workspace.d.ts +579 -0
  77. package/dist/core/agent-env.d.ts +31 -0
  78. package/dist/core/agent-env.js +371 -0
  79. package/dist/core/agent-env.js.map +1 -0
  80. package/dist/core/agent-model-policy.d.ts +10 -0
  81. package/dist/core/agent-model-policy.js +36 -0
  82. package/dist/core/agent-model-policy.js.map +1 -0
  83. package/dist/core/agent-profiles.d.ts +62 -0
  84. package/dist/core/agent-profiles.js +90 -0
  85. package/dist/core/agent-profiles.js.map +1 -0
  86. package/dist/core/agent-runner.d.ts +211 -0
  87. package/dist/core/agent-runner.js +68 -0
  88. package/dist/core/agent-runner.js.map +1 -0
  89. package/dist/core/ask.d.ts +105 -0
  90. package/dist/core/ask.js +187 -0
  91. package/dist/core/ask.js.map +1 -0
  92. package/dist/core/backend-detect.d.ts +16 -0
  93. package/dist/core/backend-detect.js +155 -0
  94. package/dist/core/backend-detect.js.map +1 -0
  95. package/dist/core/claude-cli-runner.d.ts +59 -0
  96. package/dist/core/claude-cli-runner.js +483 -0
  97. package/dist/core/claude-cli-runner.js.map +1 -0
  98. package/dist/core/claude-ui-mapper.d.ts +80 -0
  99. package/dist/core/claude-ui-mapper.js +598 -0
  100. package/dist/core/claude-ui-mapper.js.map +1 -0
  101. package/dist/core/codex-app-server-runner.d.ts +41 -0
  102. package/dist/core/codex-app-server-runner.js +584 -0
  103. package/dist/core/codex-app-server-runner.js.map +1 -0
  104. package/dist/core/codex-app-server-transport.d.ts +35 -0
  105. package/dist/core/codex-app-server-transport.js +150 -0
  106. package/dist/core/codex-app-server-transport.js.map +1 -0
  107. package/dist/core/codex-model-catalog.d.ts +10 -0
  108. package/dist/core/codex-model-catalog.js +110 -0
  109. package/dist/core/codex-model-catalog.js.map +1 -0
  110. package/dist/core/codex-ui-mapper.d.ts +112 -0
  111. package/dist/core/codex-ui-mapper.js +766 -0
  112. package/dist/core/codex-ui-mapper.js.map +1 -0
  113. package/dist/core/model-identity.d.ts +125 -0
  114. package/dist/core/model-identity.js +132 -0
  115. package/dist/core/model-identity.js.map +1 -0
  116. package/dist/core/model-presets.d.ts +21 -0
  117. package/dist/core/model-presets.js +81 -0
  118. package/dist/core/model-presets.js.map +1 -0
  119. package/dist/core/ndjson.d.ts +6 -0
  120. package/dist/core/ndjson.js +23 -0
  121. package/dist/core/ndjson.js.map +1 -0
  122. package/dist/core/opencode-model-catalog.d.ts +32 -0
  123. package/dist/core/opencode-model-catalog.js +153 -0
  124. package/dist/core/opencode-model-catalog.js.map +1 -0
  125. package/dist/core/opencode-server-runner.d.ts +32 -0
  126. package/dist/core/opencode-server-runner.js +882 -0
  127. package/dist/core/opencode-server-runner.js.map +1 -0
  128. package/dist/core/opencode-ui-mapper.d.ts +137 -0
  129. package/dist/core/opencode-ui-mapper.js +800 -0
  130. package/dist/core/opencode-ui-mapper.js.map +1 -0
  131. package/dist/core/pi-model-catalog.d.ts +31 -0
  132. package/dist/core/pi-model-catalog.js +152 -0
  133. package/dist/core/pi-model-catalog.js.map +1 -0
  134. package/dist/core/pi-runner.d.ts +24 -0
  135. package/dist/core/pi-runner.js +403 -0
  136. package/dist/core/pi-runner.js.map +1 -0
  137. package/dist/core/pi-ui-mapper.d.ts +36 -0
  138. package/dist/core/pi-ui-mapper.js +304 -0
  139. package/dist/core/pi-ui-mapper.js.map +1 -0
  140. package/dist/core/process-usage.d.ts +66 -0
  141. package/dist/core/process-usage.js +193 -0
  142. package/dist/core/process-usage.js.map +1 -0
  143. package/dist/core/provider-auth.d.ts +154 -0
  144. package/dist/core/provider-auth.js +509 -0
  145. package/dist/core/provider-auth.js.map +1 -0
  146. package/dist/core/provider-availability.d.ts +3 -0
  147. package/dist/core/provider-availability.js +14 -0
  148. package/dist/core/provider-availability.js.map +1 -0
  149. package/dist/core/runner-factory.d.ts +8 -0
  150. package/dist/core/runner-factory.js +25 -0
  151. package/dist/core/runner-factory.js.map +1 -0
  152. package/dist/core/runner-model-catalog.d.ts +29 -0
  153. package/dist/core/runner-model-catalog.js +78 -0
  154. package/dist/core/runner-model-catalog.js.map +1 -0
  155. package/dist/core/secret-redaction.d.ts +37 -0
  156. package/dist/core/secret-redaction.js +115 -0
  157. package/dist/core/secret-redaction.js.map +1 -0
  158. package/dist/core/shell-env.d.ts +28 -0
  159. package/dist/core/shell-env.js +56 -0
  160. package/dist/core/shell-env.js.map +1 -0
  161. package/dist/core/tool-display.d.ts +31 -0
  162. package/dist/core/tool-display.js +179 -0
  163. package/dist/core/tool-display.js.map +1 -0
  164. package/dist/core/ui-events.d.ts +335 -0
  165. package/dist/core/ui-events.js +25 -0
  166. package/dist/core/ui-events.js.map +1 -0
  167. package/dist/core/usage-limit.d.ts +42 -0
  168. package/dist/core/usage-limit.js +209 -0
  169. package/dist/core/usage-limit.js.map +1 -0
  170. package/dist/core/usage.d.ts +11 -0
  171. package/dist/core/usage.js +15 -0
  172. package/dist/core/usage.js.map +1 -0
  173. package/dist/core/v1-text-coalescer.d.ts +36 -0
  174. package/dist/core/v1-text-coalescer.js +72 -0
  175. package/dist/core/v1-text-coalescer.js.map +1 -0
  176. package/dist/git-diff-base.d.ts +85 -0
  177. package/dist/git-diff-base.js +180 -0
  178. package/dist/git-diff-base.js.map +1 -0
  179. package/dist/git-refs.d.ts +11 -0
  180. package/dist/git-refs.js +14 -0
  181. package/dist/git-refs.js.map +1 -0
  182. package/dist/git-worktree.d.ts +161 -0
  183. package/dist/git-worktree.js +508 -0
  184. package/dist/git-worktree.js.map +1 -0
  185. package/dist/handoff.d.ts +62 -0
  186. package/dist/handoff.js +154 -0
  187. package/dist/handoff.js.map +1 -0
  188. package/dist/index.d.ts +2 -0
  189. package/dist/index.js +680 -0
  190. package/dist/index.js.map +1 -0
  191. package/dist/install-as-command.d.ts +40 -0
  192. package/dist/install-as-command.js +52 -0
  193. package/dist/install-as-command.js.map +1 -0
  194. package/dist/pack-check.d.ts +17 -0
  195. package/dist/pack-check.js +27 -0
  196. package/dist/pack-check.js.map +1 -0
  197. package/dist/paths.d.ts +140 -0
  198. package/dist/paths.js +192 -0
  199. package/dist/paths.js.map +1 -0
  200. package/dist/planner.d.ts +27 -0
  201. package/dist/planner.js +268 -0
  202. package/dist/planner.js.map +1 -0
  203. package/dist/release/manifests.d.ts +81 -0
  204. package/dist/release/manifests.js +74 -0
  205. package/dist/release/manifests.js.map +1 -0
  206. package/dist/release/snapshot.d.ts +67 -0
  207. package/dist/release/snapshot.js +97 -0
  208. package/dist/release/snapshot.js.map +1 -0
  209. package/dist/release/stable.d.ts +38 -0
  210. package/dist/release/stable.js +55 -0
  211. package/dist/release/stable.js.map +1 -0
  212. package/dist/runs/agent-tmpdir.d.ts +41 -0
  213. package/dist/runs/agent-tmpdir.js +183 -0
  214. package/dist/runs/agent-tmpdir.js.map +1 -0
  215. package/dist/runs/auto-name.d.ts +75 -0
  216. package/dist/runs/auto-name.js +179 -0
  217. package/dist/runs/auto-name.js.map +1 -0
  218. package/dist/runs/event-history.d.ts +50 -0
  219. package/dist/runs/event-history.js +613 -0
  220. package/dist/runs/event-history.js.map +1 -0
  221. package/dist/runs/retention.d.ts +60 -0
  222. package/dist/runs/retention.js +86 -0
  223. package/dist/runs/retention.js.map +1 -0
  224. package/dist/runs/review-gate.d.ts +18 -0
  225. package/dist/runs/review-gate.js +21 -0
  226. package/dist/runs/review-gate.js.map +1 -0
  227. package/dist/runs/run-index.d.ts +19 -0
  228. package/dist/runs/run-index.js +43 -0
  229. package/dist/runs/run-index.js.map +1 -0
  230. package/dist/runs/store.d.ts +446 -0
  231. package/dist/runs/store.js +1118 -0
  232. package/dist/runs/store.js.map +1 -0
  233. package/dist/runs/task-markers.d.ts +28 -0
  234. package/dist/runs/task-markers.js +74 -0
  235. package/dist/runs/task-markers.js.map +1 -0
  236. package/dist/runs/task-refs.d.ts +25 -0
  237. package/dist/runs/task-refs.js +74 -0
  238. package/dist/runs/task-refs.js.map +1 -0
  239. package/dist/runs/ui-event-sink.d.ts +81 -0
  240. package/dist/runs/ui-event-sink.js +210 -0
  241. package/dist/runs/ui-event-sink.js.map +1 -0
  242. package/dist/server/app-type.d.ts +21 -0
  243. package/dist/server/app-type.js +2 -0
  244. package/dist/server/app-type.js.map +1 -0
  245. package/dist/server/capabilities.d.ts +70 -0
  246. package/dist/server/capabilities.js +152 -0
  247. package/dist/server/capabilities.js.map +1 -0
  248. package/dist/server/checkout.d.ts +128 -0
  249. package/dist/server/checkout.js +296 -0
  250. package/dist/server/checkout.js.map +1 -0
  251. package/dist/server/forge/github.d.ts +513 -0
  252. package/dist/server/forge/github.js +2364 -0
  253. package/dist/server/forge/github.js.map +1 -0
  254. package/dist/server/forge/index.d.ts +40 -0
  255. package/dist/server/forge/index.js +72 -0
  256. package/dist/server/forge/index.js.map +1 -0
  257. package/dist/server/forge/types.d.ts +242 -0
  258. package/dist/server/forge/types.js +2 -0
  259. package/dist/server/forge/types.js.map +1 -0
  260. package/dist/server/fs-browse.d.ts +105 -0
  261. package/dist/server/fs-browse.js +182 -0
  262. package/dist/server/fs-browse.js.map +1 -0
  263. package/dist/server/git-changes.d.ts +213 -0
  264. package/dist/server/git-changes.js +555 -0
  265. package/dist/server/git-changes.js.map +1 -0
  266. package/dist/server/git.d.ts +28 -0
  267. package/dist/server/git.js +112 -0
  268. package/dist/server/git.js.map +1 -0
  269. package/dist/server/github.d.ts +9 -0
  270. package/dist/server/github.js +8 -0
  271. package/dist/server/github.js.map +1 -0
  272. package/dist/server/launch-key.d.ts +7 -0
  273. package/dist/server/launch-key.js +33 -0
  274. package/dist/server/launch-key.js.map +1 -0
  275. package/dist/server/open-in-app.d.ts +66 -0
  276. package/dist/server/open-in-app.js +211 -0
  277. package/dist/server/open-in-app.js.map +1 -0
  278. package/dist/server/open-in-terminal.d.ts +70 -0
  279. package/dist/server/open-in-terminal.js +179 -0
  280. package/dist/server/open-in-terminal.js.map +1 -0
  281. package/dist/server/pr.d.ts +7 -0
  282. package/dist/server/pr.js +7 -0
  283. package/dist/server/pr.js.map +1 -0
  284. package/dist/server/project-context.d.ts +120 -0
  285. package/dist/server/project-context.js +182 -0
  286. package/dist/server/project-context.js.map +1 -0
  287. package/dist/server/provider-action-gate.d.ts +8 -0
  288. package/dist/server/provider-action-gate.js +56 -0
  289. package/dist/server/provider-action-gate.js.map +1 -0
  290. package/dist/server/provider-auth-runtime.d.ts +21 -0
  291. package/dist/server/provider-auth-runtime.js +66 -0
  292. package/dist/server/provider-auth-runtime.js.map +1 -0
  293. package/dist/server/server.d.ts +13138 -0
  294. package/dist/server/server.js +5263 -0
  295. package/dist/server/server.js.map +1 -0
  296. package/dist/server/static-ui.d.ts +49 -0
  297. package/dist/server/static-ui.js +92 -0
  298. package/dist/server/static-ui.js.map +1 -0
  299. package/dist/server/validators.d.ts +97 -0
  300. package/dist/server/validators.js +86 -0
  301. package/dist/server/validators.js.map +1 -0
  302. package/dist/server/ws.d.ts +85 -0
  303. package/dist/server/ws.js +218 -0
  304. package/dist/server/ws.js.map +1 -0
  305. package/dist/server/wsl.d.ts +25 -0
  306. package/dist/server/wsl.js +92 -0
  307. package/dist/server/wsl.js.map +1 -0
  308. package/dist/server-install/engine.d.ts +50 -0
  309. package/dist/server-install/engine.js +324 -0
  310. package/dist/server-install/engine.js.map +1 -0
  311. package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
  312. package/dist/server-install/platforms/macosx-ngrok.js +345 -0
  313. package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
  314. package/dist/server-install/platforms/ubuntu-vps.d.ts +78 -0
  315. package/dist/server-install/platforms/ubuntu-vps.js +1016 -0
  316. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
  317. package/dist/server-install/state.d.ts +52 -0
  318. package/dist/server-install/state.js +182 -0
  319. package/dist/server-install/state.js.map +1 -0
  320. package/dist/server-install/steps.d.ts +109 -0
  321. package/dist/server-install/steps.js +334 -0
  322. package/dist/server-install/steps.js.map +1 -0
  323. package/dist/server-install/strategies.d.ts +4 -0
  324. package/dist/server-install/strategies.js +20 -0
  325. package/dist/server-install/strategies.js.map +1 -0
  326. package/dist/server-install/types.d.ts +287 -0
  327. package/dist/server-install/types.js +121 -0
  328. package/dist/server-install/types.js.map +1 -0
  329. package/dist/server-install/ui.d.ts +42 -0
  330. package/dist/server-install/ui.js +130 -0
  331. package/dist/server-install/ui.js.map +1 -0
  332. package/dist/skills-banner.d.ts +22 -0
  333. package/dist/skills-banner.js +41 -0
  334. package/dist/skills-banner.js.map +1 -0
  335. package/dist/skills-remote.d.ts +84 -0
  336. package/dist/skills-remote.js +468 -0
  337. package/dist/skills-remote.js.map +1 -0
  338. package/dist/skills-update.d.ts +88 -0
  339. package/dist/skills-update.js +392 -0
  340. package/dist/skills-update.js.map +1 -0
  341. package/dist/skills.d.ts +82 -0
  342. package/dist/skills.js +251 -0
  343. package/dist/skills.js.map +1 -0
  344. package/dist/todos.d.ts +48 -0
  345. package/dist/todos.js +201 -0
  346. package/dist/todos.js.map +1 -0
  347. package/dist/ui-state.d.ts +26 -0
  348. package/dist/ui-state.js +38 -0
  349. package/dist/ui-state.js.map +1 -0
  350. package/dist/update-check.d.ts +12 -0
  351. package/dist/update-check.js +41 -0
  352. package/dist/update-check.js.map +1 -0
  353. package/dist/workflows/load.d.ts +15 -0
  354. package/dist/workflows/load.js +56 -0
  355. package/dist/workflows/load.js.map +1 -0
  356. package/dist/workflows/run.d.ts +758 -0
  357. package/dist/workflows/run.js +3389 -0
  358. package/dist/workflows/run.js.map +1 -0
  359. package/dist/workflows/types.d.ts +153 -0
  360. package/dist/workflows/types.js +212 -0
  361. package/dist/workflows/types.js.map +1 -0
  362. package/dist/workspace/agent-accounts.d.ts +153 -0
  363. package/dist/workspace/agent-accounts.js +304 -0
  364. package/dist/workspace/agent-accounts.js.map +1 -0
  365. package/dist/workspace/agent-profiles.d.ts +78 -0
  366. package/dist/workspace/agent-profiles.js +115 -0
  367. package/dist/workspace/agent-profiles.js.map +1 -0
  368. package/dist/workspace/config.d.ts +169 -0
  369. package/dist/workspace/config.js +379 -0
  370. package/dist/workspace/config.js.map +1 -0
  371. package/dist/workspace/migrations.d.ts +45 -0
  372. package/dist/workspace/migrations.js +147 -0
  373. package/dist/workspace/migrations.js.map +1 -0
  374. package/dist/workspace/projects-cli.d.ts +25 -0
  375. package/dist/workspace/projects-cli.js +172 -0
  376. package/dist/workspace/projects-cli.js.map +1 -0
  377. package/dist/workspace/projects.d.ts +109 -0
  378. package/dist/workspace/projects.js +250 -0
  379. package/dist/workspace/projects.js.map +1 -0
  380. package/dist/workspace/semaphore.d.ts +179 -0
  381. package/dist/workspace/semaphore.js +195 -0
  382. package/dist/workspace/semaphore.js.map +1 -0
  383. package/dist/workspace/ui-state.d.ts +34 -0
  384. package/dist/workspace/ui-state.js +53 -0
  385. package/dist/workspace/ui-state.js.map +1 -0
  386. package/package.json +70 -0
  387. package/scripts/check-pack.mjs +46 -0
  388. package/scripts/inline-contract.mjs +112 -0
  389. package/scripts/install-as-command.mjs +120 -0
  390. package/scripts/mock-claude.mjs +520 -0
  391. package/scripts/mock-pi-rpc.mjs +83 -0
  392. package/scripts/sync-readme.mjs +20 -0
  393. package/scripts/test-process-usage.mjs +47 -0
  394. package/web/dist/assets/alert-dialog-B4Ofsgv7.js +1 -0
  395. package/web/dist/assets/arrow-down-Dy8dup7j.js +1 -0
  396. package/web/dist/assets/arrow-left-BJaucbhn.js +1 -0
  397. package/web/dist/assets/bundle-mjs-BT31bpU6.js +1 -0
  398. package/web/dist/assets/centered-state-duPW0phQ.js +43 -0
  399. package/web/dist/assets/chevron-right-Be4A5TCS.js +1 -0
  400. package/web/dist/assets/chunk-BO2N2NFS-DE6qKn3r.js +131 -0
  401. package/web/dist/assets/collapsible-DdcNBdSk.js +1 -0
  402. package/web/dist/assets/commit-list-CgvN9vec.js +1 -0
  403. package/web/dist/assets/compare-variants-CQA2nd65.js +1 -0
  404. package/web/dist/assets/core-BCsw8oQw.js +12 -0
  405. package/web/dist/assets/css-BsVw1vtW.js +1 -0
  406. package/web/dist/assets/diff-B6Agp5Hl.js +3 -0
  407. package/web/dist/assets/diff-stat-BoXuGkgq.js +1 -0
  408. package/web/dist/assets/diff-view-CD8XI-fj.js +6 -0
  409. package/web/dist/assets/diff-woXpYk--.js +1 -0
  410. package/web/dist/assets/dropdown-menu-B3SYw-k5.js +1 -0
  411. package/web/dist/assets/editable-title-B-hjp5wl.js +1 -0
  412. package/web/dist/assets/ellipsis-vertical-BYwzw0xl.js +1 -0
  413. package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
  414. package/web/dist/assets/file-BRj5eISx.js +1 -0
  415. package/web/dist/assets/folder-z4oT5981.js +1 -0
  416. package/web/dist/assets/git-toolbar-owSEkYld.js +1 -0
  417. package/web/dist/assets/github-Bz2VgRX3.js +1 -0
  418. package/web/dist/assets/go-rLFTqkRN.js +1 -0
  419. package/web/dist/assets/highlighted-body-OFNGDK62-BL-MfFgl.js +1 -0
  420. package/web/dist/assets/highlighter-CdHqIwFr.js +3 -0
  421. package/web/dist/assets/html-BY76lXLH.js +1 -0
  422. package/web/dist/assets/image-preview-h3WFluuy.js +1 -0
  423. package/web/dist/assets/index-BbcQNT92.css +2 -0
  424. package/web/dist/assets/index-EtQQQ6Kj.js +7 -0
  425. package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  426. package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  427. package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
  428. package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  429. package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  430. package/web/dist/assets/json-qhed-kSA.js +1 -0
  431. package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
  432. package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
  433. package/web/dist/assets/lib-BQXq3kEf.js +1 -0
  434. package/web/dist/assets/lib-BxQXEXDF.js +1 -0
  435. package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
  436. package/web/dist/assets/markdown-DqBKYPiB.js +2 -0
  437. package/web/dist/assets/mermaid-GHXKKRXX-C4jxqUUb.js +1 -0
  438. package/web/dist/assets/new-task-form-BdJKRBJX.js +1 -0
  439. package/web/dist/assets/pill-BQfmfpYp.js +1 -0
  440. package/web/dist/assets/project-router-DxgFZY1l.js +1 -0
  441. package/web/dist/assets/prompt-templates-B6m16gq-.js +15 -0
  442. package/web/dist/assets/python-gzcpVVnB.js +1 -0
  443. package/web/dist/assets/react-runtime-CCIEwYL0.js +9 -0
  444. package/web/dist/assets/refresh-cw-mhSpxf2a.js +1 -0
  445. package/web/dist/assets/repo-git-CUNRxR3_.js +1 -0
  446. package/web/dist/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  447. package/web/dist/assets/run-diff-DsmmDVfx.js +3 -0
  448. package/web/dist/assets/run-header-BkhrseLJ.js +1 -0
  449. package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
  450. package/web/dist/assets/search-x-BqDMB2g8.js +1 -0
  451. package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
  452. package/web/dist/assets/skill-empty-hint-BWEvTggc.js +1 -0
  453. package/web/dist/assets/skills-9oR_oHse.js +1 -0
  454. package/web/dist/assets/skills-DwIxnnWO.js +1 -0
  455. package/web/dist/assets/sparkles-DIoTQpyx.js +1 -0
  456. package/web/dist/assets/sql-BsFa4tDR.js +1 -0
  457. package/web/dist/assets/square-terminal-Cc7CuQxc.js +1 -0
  458. package/web/dist/assets/tab-link-D1fQgpmO.js +1 -0
  459. package/web/dist/assets/task-changes-BKeLlDpK.js +1 -0
  460. package/web/dist/assets/task-commits-gcEFZIa5.js +1 -0
  461. package/web/dist/assets/task-files-BGAqoXTW.js +2 -0
  462. package/web/dist/assets/task-thread-DT8aUYTS.js +9 -0
  463. package/web/dist/assets/textarea-BOVbfy5C.js +1 -0
  464. package/web/dist/assets/thread-loading-CypW73KD.js +1 -0
  465. package/web/dist/assets/toml-CcmNWLt0.js +1 -0
  466. package/web/dist/assets/trash-2-CJq6LHWn.js +1 -0
  467. package/web/dist/assets/triangle-alert-CjDFvU27.js +1 -0
  468. package/web/dist/assets/tsx-udAQXfEw.js +1 -0
  469. package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
  470. package/web/dist/assets/upload-CPDZlJeK.js +1 -0
  471. package/web/dist/assets/use-desktop-5JsLmi0a.js +1 -0
  472. package/web/dist/assets/use-submit-shortcut-CHVFevty.js +1 -0
  473. package/web/dist/assets/utils-DiO6zyJd.js +64 -0
  474. package/web/dist/assets/workflows-rQDFzWRt.js +11 -0
  475. package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
  476. package/web/dist/assets/zoomable-image-COWqb11v.js +1 -0
  477. package/web/dist/index.html +80 -0
  478. package/web/dist/open-mercato.svg +11 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * `GET /api/fs/browse` — the directory picker behind "Add project → open local
3
+ * folder" (spec 2026-07-20-multi-project-workspace, step 4.1).
4
+ *
5
+ * This is the one route that hands the operator's filesystem shape to a
6
+ * browser, so the whole module is written around a single containment rule and
7
+ * nothing else:
8
+ *
9
+ * **every path this route answers about — the one browsed and every entry
10
+ * listed — must be the browse root itself or live strictly beneath it, as
11
+ * judged AFTER `realpath()` resolved the whole symlink chain.**
12
+ *
13
+ * Why realpath and not `resolve()`: `resolve()` only normalizes `..` textually.
14
+ * It cannot see that `~/tmp/escape` is a symlink to `/etc`, so a lexical-only
15
+ * check happily lists `/etc` under a path that spells as being inside home.
16
+ * The lexical check is still done FIRST (it rejects `..` traversal and absolute
17
+ * escapes without touching the disk at all, and it keeps a probe for
18
+ * "does /root exist" from ever reaching the filesystem), and the realpath check
19
+ * is done SECOND as the authoritative one.
20
+ *
21
+ * Two more deliberate choices:
22
+ *
23
+ * - **Directories only.** Files are never listed, never stat-reported, never
24
+ * read. The picker's job is to name a folder; a file name is already more of
25
+ * the operator's disk than the caller needs.
26
+ * - **Errors never echo a resolved path.** `{ error }` says what the caller did
27
+ * wrong, never where they landed — an error string carrying the realpath of
28
+ * an escape attempt would be the very leak the containment prevents (same
29
+ * reasoning as the `/api/health` `repoRoot` trim, #431).
30
+ */
31
+ /** One listed subdirectory. `path` is absolute — this route is same-origin and
32
+ * behind the cockpit, exactly like `GET /api/projects`' `root`s (health, the
33
+ * CORS-open route, is the one that must never carry absolute paths). */
34
+ export interface FsBrowseDir {
35
+ name: string;
36
+ path: string;
37
+ /** Has a `.git` entry — file or dir, so linked worktrees count. Drives the
38
+ * "repo" badge in the picker; a non-repo folder is still selectable. */
39
+ isRepo: boolean;
40
+ }
41
+ /** `GET /api/fs/browse?path=` — the spec's shape plus `truncated`. */
42
+ export interface FsBrowseResponse {
43
+ /** The realpath'd directory actually listed (never the spelling asked for —
44
+ * the picker's breadcrumb should show where it really is). */
45
+ path: string;
46
+ /** `null` AT the browse root: there is no "up" out of the root, and the UI
47
+ * needs that to be a shape it cannot mis-navigate. */
48
+ parent: string | null;
49
+ dirs: FsBrowseDir[];
50
+ /** True when `dirs` was capped — an honest signal beats a silently short
51
+ * list in a directory with tens of thousands of children. */
52
+ truncated: boolean;
53
+ }
54
+ export type BrowseResult = {
55
+ ok: true;
56
+ body: FsBrowseResponse;
57
+ } | {
58
+ ok: false;
59
+ status: 400 | 404;
60
+ error: string;
61
+ };
62
+ /**
63
+ * Expand the configured browse root. The workspace owns this independently
64
+ * from the checkout root, so browsing never follows a clone-destination edit.
65
+ */
66
+ export declare function resolveBrowseRoot(browseRoot: string): string;
67
+ /**
68
+ * Is `candidate` the browse root or strictly beneath it — the same containment
69
+ * question `browseDirectory` asks, exported for the ONE other route that must
70
+ * ask it: `POST /api/projects` (step 4.2).
71
+ *
72
+ * Configuring the browse root only limits what the picker
73
+ * can SEE. A register call naming an arbitrary absolute path would walk around
74
+ * that in one request — and a registered project's panes read its whole tree.
75
+ * So the register route re-asks containment for itself, against the same root,
76
+ * with the same realpath-based rule. Both paths are realpath'd here (unlike
77
+ * `contains`, which trusts its callers) because neither is guaranteed resolved.
78
+ */
79
+ /**
80
+ * The LEXICAL half of the containment question: does `candidate` spell as being inside `root`,
81
+ * judged without asking whether it exists?
82
+ *
83
+ * `isInsideBrowseRoot` below realpaths both sides, which makes it answer `false` for a path that
84
+ * is inside the root but simply not there — so using it alone as the first gate would tell a
85
+ * hosted user who typo'd a folder under their own checkout root that it is "outside the browsable
86
+ * root". This split lets the register route reject out-of-root paths UNIFORMLY (the existence
87
+ * oracle stays shut, because a spelling outside the root is refused whether or not it exists),
88
+ * then answer honestly about existence, then still catch symlink escapes with the realpath gate.
89
+ */
90
+ export declare function isLexicallyInsideBrowseRoot(root: string, candidate: string): Promise<boolean>;
91
+ export declare function isInsideBrowseRoot(root: string, candidate: string): Promise<boolean>;
92
+ /**
93
+ * List the directories inside `path`, contained within `root`.
94
+ *
95
+ * `path` is the raw query value: absent/empty means the root itself, `~`
96
+ * spellings are expanded, and a relative value resolves against the root (so
97
+ * the route is usable without the caller knowing the absolute root, and a
98
+ * relative `../..` is still caught by the same containment check as everything
99
+ * else).
100
+ */
101
+ export declare function browseDirectory(opts: {
102
+ root: string;
103
+ path?: string | undefined;
104
+ showHidden?: boolean;
105
+ }): Promise<BrowseResult>;
@@ -0,0 +1,182 @@
1
+ import { readdir, realpath, stat } from 'node:fs/promises';
2
+ import { dirname, isAbsolute, join, resolve, sep } from 'node:path';
3
+ import { expandTilde } from '../paths.js';
4
+ /**
5
+ * Entry cap. A picker cannot usefully render more, and an unbounded listing
6
+ * turns one request into a per-entry `stat` storm (`isRepo` + symlink
7
+ * resolution) on e.g. a node_modules parent.
8
+ */
9
+ const MAX_ENTRIES = 1000;
10
+ /**
11
+ * Expand the configured browse root. The workspace owns this independently
12
+ * from the checkout root, so browsing never follows a clone-destination edit.
13
+ */
14
+ export function resolveBrowseRoot(browseRoot) {
15
+ return expandTilde(browseRoot);
16
+ }
17
+ /** `candidate` is `root` or strictly beneath it. Both must already be
18
+ * realpath'd for this to mean anything. The explicit separator suffix is what
19
+ * stops `/home/bob-evil` from passing as inside `/home/bob`; the `endsWith`
20
+ * guard keeps a root of `/` from becoming the prefix `//`. */
21
+ function contains(root, candidate) {
22
+ if (candidate === root)
23
+ return true;
24
+ return candidate.startsWith(root.endsWith(sep) ? root : root + sep);
25
+ }
26
+ /**
27
+ * Is `candidate` the browse root or strictly beneath it — the same containment
28
+ * question `browseDirectory` asks, exported for the ONE other route that must
29
+ * ask it: `POST /api/projects` (step 4.2).
30
+ *
31
+ * Configuring the browse root only limits what the picker
32
+ * can SEE. A register call naming an arbitrary absolute path would walk around
33
+ * that in one request — and a registered project's panes read its whole tree.
34
+ * So the register route re-asks containment for itself, against the same root,
35
+ * with the same realpath-based rule. Both paths are realpath'd here (unlike
36
+ * `contains`, which trusts its callers) because neither is guaranteed resolved.
37
+ */
38
+ /**
39
+ * The LEXICAL half of the containment question: does `candidate` spell as being inside `root`,
40
+ * judged without asking whether it exists?
41
+ *
42
+ * `isInsideBrowseRoot` below realpaths both sides, which makes it answer `false` for a path that
43
+ * is inside the root but simply not there — so using it alone as the first gate would tell a
44
+ * hosted user who typo'd a folder under their own checkout root that it is "outside the browsable
45
+ * root". This split lets the register route reject out-of-root paths UNIFORMLY (the existence
46
+ * oracle stays shut, because a spelling outside the root is refused whether or not it exists),
47
+ * then answer honestly about existence, then still catch symlink escapes with the realpath gate.
48
+ */
49
+ export async function isLexicallyInsideBrowseRoot(root, candidate) {
50
+ const realRoot = await realpathOrNull(root);
51
+ if (realRoot === null)
52
+ return false;
53
+ return contains(realRoot, resolve(candidate));
54
+ }
55
+ export async function isInsideBrowseRoot(root, candidate) {
56
+ const realRoot = await realpathOrNull(root);
57
+ if (realRoot === null)
58
+ return false;
59
+ const real = await realpathOrNull(candidate);
60
+ if (real === null)
61
+ return false;
62
+ return contains(realRoot, real);
63
+ }
64
+ /** realpath or null — every "does it exist / where does it really point"
65
+ * question in this module is best-effort and answered without throwing. */
66
+ async function realpathOrNull(path) {
67
+ try {
68
+ return await realpath(path);
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ }
74
+ async function exists(path) {
75
+ try {
76
+ await stat(path);
77
+ return true;
78
+ }
79
+ catch {
80
+ return false;
81
+ }
82
+ }
83
+ /**
84
+ * List the directories inside `path`, contained within `root`.
85
+ *
86
+ * `path` is the raw query value: absent/empty means the root itself, `~`
87
+ * spellings are expanded, and a relative value resolves against the root (so
88
+ * the route is usable without the caller knowing the absolute root, and a
89
+ * relative `../..` is still caught by the same containment check as everything
90
+ * else).
91
+ */
92
+ export async function browseDirectory(opts) {
93
+ // The root is realpath'd ONCE, up front: it is the yardstick every later
94
+ // comparison uses, and comparing a resolved candidate against an
95
+ // unresolved root would reject legitimate paths on any machine whose home
96
+ // sits behind a symlink (macOS `/tmp`, NFS automounts, `/home` → `/usr/home`).
97
+ const root = await realpathOrNull(opts.root);
98
+ // A configured browse root that does not exist yet lands here. There
99
+ // is nothing to browse and nothing informative to say about a path the
100
+ // caller cannot see anyway.
101
+ if (root === null)
102
+ return { ok: false, status: 404, error: 'browse root is not available' };
103
+ const requested = (opts.path ?? '').trim();
104
+ // A NUL byte would make the fs calls throw `ERR_INVALID_ARG_VALUE` instead of
105
+ // failing containment; reject it as malformed input before it gets that far.
106
+ if (requested.includes('\0'))
107
+ return { ok: false, status: 400, error: 'invalid path' };
108
+ const expanded = requested === '' ? root : expandTilde(requested);
109
+ // `resolve` handles both spellings: an absolute value stands alone, a
110
+ // relative one is taken from the root. Either way `..` is folded away here,
111
+ // so the lexical check below sees the real intent.
112
+ const target = isAbsolute(expanded) ? resolve(expanded) : resolve(root, expanded);
113
+ // Lexical gate: `..` traversal and absolute escapes die here, before any
114
+ // syscall — so an escape attempt cannot even be used to probe which paths
115
+ // outside the root exist (the timing/`404`-vs-`400` difference would tell).
116
+ if (!contains(root, target))
117
+ return { ok: false, status: 400, error: 'path is outside the browsable root' };
118
+ const real = await realpathOrNull(target);
119
+ if (real === null)
120
+ return { ok: false, status: 404, error: 'no such directory' };
121
+ // Authoritative gate: `target` spelled as inside the root, but the symlink
122
+ // chain may land anywhere. This is the check that catches a symlink planted
123
+ // inside home pointing at `/etc` (or, in hosted mode, at the rest of the
124
+ // host's disk).
125
+ if (!contains(root, real))
126
+ return { ok: false, status: 400, error: 'path is outside the browsable root' };
127
+ const info = await stat(real).catch(() => null);
128
+ // Not a directory ⇒ same answer as "not there". The picker only navigates
129
+ // directories, and distinguishing "this is a file" would confirm the
130
+ // existence of a file the caller was never shown.
131
+ if (!info?.isDirectory())
132
+ return { ok: false, status: 404, error: 'no such directory' };
133
+ const entries = await readdir(real, { withFileTypes: true }).catch(() => null);
134
+ // Unreadable (mode 0300, permission-denied mount) — indistinguishable from
135
+ // absent, on purpose.
136
+ if (entries === null)
137
+ return { ok: false, status: 404, error: 'no such directory' };
138
+ const showHidden = opts.showHidden === true;
139
+ const candidates = entries
140
+ .filter((entry) => showHidden || !entry.name.startsWith('.'))
141
+ // Symlinks are resolved below (a symlinked project dir is a normal setup);
142
+ // everything that is neither a directory nor a symlink is not our business.
143
+ .filter((entry) => entry.isDirectory() || entry.isSymbolicLink())
144
+ .sort((a, b) => a.name.localeCompare(b.name));
145
+ const truncated = candidates.length > MAX_ENTRIES;
146
+ const dirs = [];
147
+ for (const entry of candidates.slice(0, MAX_ENTRIES)) {
148
+ const childPath = join(real, entry.name);
149
+ if (entry.isSymbolicLink()) {
150
+ const childReal = await realpathOrNull(childPath);
151
+ // A symlink is listed only when it resolves to a directory that is
152
+ // ITSELF inside the root. Listing an escaping link and rejecting it on
153
+ // click would leak the same fact one step later — that a path outside
154
+ // the root exists.
155
+ if (childReal === null || !contains(root, childReal))
156
+ continue;
157
+ const childInfo = await stat(childReal).catch(() => null);
158
+ if (!childInfo?.isDirectory())
159
+ continue;
160
+ }
161
+ dirs.push({
162
+ name: entry.name,
163
+ // The link's own path, not its target: the breadcrumb should read the
164
+ // way the operator's filesystem reads, and navigating into it re-runs
165
+ // the containment check from scratch.
166
+ path: childPath,
167
+ isRepo: await exists(join(childPath, '.git')),
168
+ });
169
+ }
170
+ return {
171
+ ok: true,
172
+ body: {
173
+ path: real,
174
+ // Never above the root, even when the real parent exists — `dirname('/')`
175
+ // is `/`, and the root's parent is simply not part of this surface.
176
+ parent: real === root ? null : dirname(real),
177
+ dirs,
178
+ truncated,
179
+ },
180
+ };
181
+ }
182
+ //# sourceMappingURL=fs-browse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-browse.js","sourceRoot":"","sources":["../../src/server/fs-browse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,213 @@
1
+ import { type RepointedHead } from '../git-diff-base.ts';
2
+ export interface ChangedFile {
3
+ path: string;
4
+ /** Rename/copy source — present only when `status` is renamed/copied. */
5
+ oldPath?: string;
6
+ status: 'added' | 'modified' | 'deleted' | 'renamed' | 'copied';
7
+ adds: number;
8
+ dels: number;
9
+ binary: boolean;
10
+ /** True when `path`'s extension is one the raw-bytes route (`/files?raw=1`) will serve as an
11
+ * `<img>` (#365) — lets the diff pane preview it inline instead of the "Binary file" note,
12
+ * even for extensions (SVG) git itself doesn't flag `binary`. Present only when true. */
13
+ image?: boolean;
14
+ patch: string;
15
+ }
16
+ export interface ChangesPayload {
17
+ files: ChangedFile[];
18
+ stat: {
19
+ adds: number;
20
+ dels: number;
21
+ files: number;
22
+ };
23
+ /** Present when a run worktree was repointed away from the task branch (#591). In that case the
24
+ * payload is intentionally limited to uncommitted changes instead of attributing the
25
+ * checked-out branch's history to this task. */
26
+ repointedHead?: RepointedHead;
27
+ }
28
+ export type ChangesResult = {
29
+ ok: true;
30
+ changes: ChangesPayload;
31
+ } | {
32
+ ok: false;
33
+ error: string;
34
+ };
35
+ interface NumstatEntry {
36
+ adds: number;
37
+ dels: number;
38
+ binary: boolean;
39
+ path: string;
40
+ oldPath?: string;
41
+ }
42
+ /** Parse `git diff --numstat -z -M`: `adds TAB dels TAB path NUL`, or for a
43
+ * rename/copy `adds TAB dels TAB NUL old NUL new NUL`. Binary files report
44
+ * `-` for both counters. Exported for tests. */
45
+ export declare function parseNumstatZ(out: string): NumstatEntry[];
46
+ interface NameStatusEntry {
47
+ status: string;
48
+ path: string;
49
+ oldPath?: string;
50
+ }
51
+ /** Parse `git diff --name-status -z -M`: `X NUL path NUL`, renames/copies
52
+ * `Rnnn NUL old NUL new NUL`. Exported for tests. */
53
+ export declare function parseNameStatusZ(out: string): NameStatusEntry[];
54
+ /** Split one `git diff --patch` blob into per-file sections, in git's file
55
+ * order (the same order `--numstat`/`--name-status` use). Exported for tests. */
56
+ export declare function splitPatch(patch: string): string[];
57
+ /** Map each `git diff --patch` section to the file path it describes, so a file's
58
+ * patch is looked up by path rather than by position. This is robust to the two
59
+ * listings (`--name-status` and `--patch`) disagreeing on file count — the case
60
+ * where positional matching used to blank *every* file's patch. Exported for tests. */
61
+ export declare function patchByPath(sections: string[]): Map<string, string>;
62
+ /**
63
+ * Structured "what changed here" for a directory vs its base branch:
64
+ * committed + uncommitted + untracked (via `add -N`), anchored by the shared
65
+ * `resolveTaskDiffBase` rule (`src/git-diff-base.ts`) — the merge-base against
66
+ * the freshest base ref, so the diff stays *this task's* changes even after the
67
+ * base moves on, and the branch's state at `runStartedAt` when the agent
68
+ * repointed the worktree onto another branch (#591, #751).
69
+ * `worktreeShortstat` resolves through the same helper; the text-blob `/diff`
70
+ * endpoint (`worktreeDiff`) deliberately does not — see its own note.
71
+ */
72
+ export declare function collectChanges(dir: string, baseBranch: string, opts?: {
73
+ patchCap?: number;
74
+ intentToAdd?: boolean;
75
+ taskBranch?: string;
76
+ runStartedAt?: string;
77
+ }): Promise<ChangesResult>;
78
+ /** The three raw `git diff` listings (name-status, numstat, patch) → the `{files, stat}`
79
+ * payload. Shared by the working-tree diff above and the commit diff below. Each file's
80
+ * patch is matched by path (`patchByPath`), so a mismatch between the name-status and
81
+ * patch file counts — a typechange, submodule, or any entry that emits no `diff --git`
82
+ * block — drops at most that one file's patch instead of blanking every file's. Positional
83
+ * matching remains the fallback for a section whose path can't be parsed, but only when the
84
+ * counts agree (the same condition the old all-or-nothing guard required). Exported for tests. */
85
+ export declare function assemblePayload(nameStatusOut: string, numstatOut: string, patchOut: string, patchCap: number): ChangesPayload;
86
+ export interface RunCommit {
87
+ sha: string;
88
+ subject: string;
89
+ author: string;
90
+ /** Relative time ("3 hours ago"), git's `%cr`. */
91
+ when: string;
92
+ }
93
+ export type RunCommitsResult = {
94
+ ok: true;
95
+ commits: RunCommit[];
96
+ } | {
97
+ ok: false;
98
+ error: string;
99
+ };
100
+ /**
101
+ * The commits reachable from the worktree's current HEAD after its base, newest first. A review
102
+ * task may deliberately repoint HEAD to the reviewed branch, so this list retains that useful
103
+ * history even though `collectChanges` narrows its payload to uncommitted work in that case.
104
+ * Empty (not an error) when the branch has no commits past base.
105
+ */
106
+ export declare function collectRunCommits(dir: string, baseBranch: string): Promise<RunCommitsResult>;
107
+ /** `GET /api/repo/commit/:sha?structured=1` — one commit's metadata plus the same
108
+ * structured `{files, stat}` shape the working-tree routes serve (R5 Step 1.7). The
109
+ * legacy text-blob answer of that route is a protected surface and stays untouched. */
110
+ export interface CommitPayload {
111
+ sha: string;
112
+ subject: string;
113
+ author: string;
114
+ /** Relative time ("3 hours ago") — same `%cr` format the /api/repo log uses. */
115
+ when: string;
116
+ files: ChangedFile[];
117
+ stat: {
118
+ adds: number;
119
+ dels: number;
120
+ files: number;
121
+ };
122
+ }
123
+ export type CommitChangesResult = {
124
+ ok: true;
125
+ commit: CommitPayload;
126
+ } | {
127
+ ok: false;
128
+ error: string;
129
+ };
130
+ /**
131
+ * Structured diff of ONE commit vs its first parent (`--root` covers the initial commit).
132
+ * A merge commit honestly answers zero files — `git diff-tree` shows no diff for merges
133
+ * without `-m`/`-c`, and inventing one side's diff would misattribute the changes.
134
+ * Unknown/invalid shas degrade to `{ ok:false, error }` for the route's 409.
135
+ */
136
+ export declare function collectCommitChanges(dir: string, sha: string, patchCap?: number): Promise<CommitChangesResult>;
137
+ /** Max file content served to the Files tab — past this the GUI shows an
138
+ * honest "too large" state instead of the bytes. */
139
+ export declare const FILE_CONTENT_CAP = 512000;
140
+ export interface DirEntry {
141
+ name: string;
142
+ type: 'dir' | 'file';
143
+ size?: number;
144
+ }
145
+ export type FilesResult = {
146
+ kind: 'dir';
147
+ path: string;
148
+ entries: DirEntry[];
149
+ } | {
150
+ kind: 'file';
151
+ path: string;
152
+ size: number;
153
+ binary: boolean;
154
+ tooLarge: boolean;
155
+ content?: string;
156
+ } | {
157
+ kind: 'invalid';
158
+ error: string;
159
+ } | {
160
+ kind: 'missing';
161
+ error: string;
162
+ };
163
+ /** The image MIME type for a path, or null when it is not an image we serve raw. */
164
+ export declare function imageMimeType(path: string): string | null;
165
+ /** True when `path` is an image safe to hand to the OS's default handler — see OS_OPENABLE_EXT. */
166
+ export declare function isOsOpenableImage(path: string): boolean;
167
+ /**
168
+ * Directory listing or file content from inside `root`, traversal-safe:
169
+ * anything resolving outside the root (dot-segments, absolute paths, NUL) is
170
+ * rejected — same "not a file we serve" stance as `isSafeAssetFilename` in
171
+ * src/server/static-ui.ts. `.git` and symlinks are off-limits too.
172
+ */
173
+ export declare function readWorktreePath(root: string, relPath: string, contentCap?: number): Promise<FilesResult>;
174
+ export type BranchResult = {
175
+ ok: true;
176
+ branch: string;
177
+ created: boolean;
178
+ } | {
179
+ ok: false;
180
+ error: string;
181
+ };
182
+ /**
183
+ * Repo-view branch action (`POST /api/repo/branch`): switch to `name` when it
184
+ * already exists locally, otherwise create it from `from` (or HEAD) and switch.
185
+ * Name validation is delegated to `git check-ref-format --branch` — git's own
186
+ * rules, not a reimplementation — behind an explicit dash-guard (#431).
187
+ * Predictable failures (invalid name, unknown `from`, dirty-tree checkout
188
+ * conflict) come back as `{ ok:false, error }`.
189
+ */
190
+ export declare function createOrSwitchBranch(dir: string, name: string, from?: string): Promise<BranchResult>;
191
+ export type CommitResult = {
192
+ ok: true;
193
+ sha: string;
194
+ } | {
195
+ ok: false;
196
+ error: string;
197
+ };
198
+ /** `git add -A && git commit -m <message>` in `dir`. A clean tree, a failing
199
+ * hook or missing identity all come back as `{ ok:false, error }`. */
200
+ export declare function commitAll(dir: string, message: string): Promise<CommitResult>;
201
+ export type PushResult = {
202
+ ok: true;
203
+ branch: string;
204
+ remote: string;
205
+ upstreamSet: boolean;
206
+ } | {
207
+ ok: false;
208
+ error: string;
209
+ };
210
+ /** Push the current branch, setting upstream when it has none. No remote,
211
+ * detached HEAD and rejected pushes all degrade to `{ ok:false, error }`. */
212
+ export declare function pushCurrentBranch(dir: string): Promise<PushResult>;
213
+ export {};