@gajae-code/coding-agent 0.18.7 → 0.18.9

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 (344) hide show
  1. package/CHANGELOG.md +377 -1
  2. package/dist/types/async/endpoint-id.d.ts +16 -0
  3. package/dist/types/async/job-manager.d.ts +1 -1
  4. package/dist/types/async/support.d.ts +0 -14
  5. package/dist/types/capability/mcp.d.ts +2 -0
  6. package/dist/types/capability/skill.d.ts +2 -0
  7. package/dist/types/capability/types.d.ts +2 -0
  8. package/dist/types/cli/public-command-errors.d.ts +3 -1
  9. package/dist/types/cli/setup-cli.d.ts +1 -1
  10. package/dist/types/commands/deep-interview.d.ts +3 -0
  11. package/dist/types/commands/mcp-serve.d.ts +4 -0
  12. package/dist/types/config/autorouting-tier-map.d.ts +348 -9
  13. package/dist/types/config/file-lock.d.ts +1 -0
  14. package/dist/types/config/model-bindings-applier.d.ts +2 -0
  15. package/dist/types/config/model-profile-activation.d.ts +11 -3
  16. package/dist/types/config/model-registry.d.ts +4 -9
  17. package/dist/types/config/skill-settings-defaults.d.ts +2 -0
  18. package/dist/types/cursor-delete-path.d.ts +1 -0
  19. package/dist/types/cursor-mcp-name.d.ts +8 -0
  20. package/dist/types/customization/inventory.d.ts +2 -0
  21. package/dist/types/debug/report-bundle-parent.d.ts +2 -0
  22. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.d.ts +1 -0
  23. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/version-manager.d.ts +31 -0
  24. package/dist/types/defaults/gjc-skills.generated.d.ts +5 -6
  25. package/dist/types/discovery/helpers.d.ts +6 -1
  26. package/dist/types/discovery/mcp-json.d.ts +1 -0
  27. package/dist/types/eval/py/kernel.d.ts +18 -0
  28. package/dist/types/export/html/css-color.d.ts +2 -0
  29. package/dist/types/export/html/html-export-destination.d.ts +2 -0
  30. package/dist/types/export/html/template.generated.d.ts +1 -1
  31. package/dist/types/extensibility/extensions/function-hooks-internal.d.ts +5 -0
  32. package/dist/types/extensibility/extensions/types.d.ts +7 -0
  33. package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +14 -1
  34. package/dist/types/extensibility/plugins/marketplace/cache.d.ts +2 -0
  35. package/dist/types/extensibility/plugins/plugin-link-path.d.ts +2 -0
  36. package/dist/types/extensibility/runtime-skill-discovery.d.ts +3 -1
  37. package/dist/types/extensibility/skill-management.d.ts +4 -1
  38. package/dist/types/extensibility/skills.d.ts +2 -0
  39. package/dist/types/gjc-runtime/deep-interview-crystallize.d.ts +74 -0
  40. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +11 -0
  41. package/dist/types/gjc-runtime/gc-runtime.d.ts +5 -0
  42. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -3
  43. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +0 -5
  44. package/dist/types/gjc-runtime/sidecar-bootstrap-env.d.ts +6 -0
  45. package/dist/types/gjc-runtime/state-argv.d.ts +1 -1
  46. package/dist/types/gjc-runtime/state-migrations.d.ts +8 -0
  47. package/dist/types/gjc-runtime/state-runtime.d.ts +95 -0
  48. package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
  49. package/dist/types/gjc-runtime/tmux-common.d.ts +8 -5
  50. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -0
  51. package/dist/types/internal-urls/skill-path.d.ts +1 -0
  52. package/dist/types/lsp/config.d.ts +8 -5
  53. package/dist/types/lsp/workspace-path.d.ts +1 -0
  54. package/dist/types/modes/acp/acp-agent.d.ts +7 -0
  55. package/dist/types/modes/components/custom-editor.d.ts +6 -0
  56. package/dist/types/modes/components/customization/customization-dashboard.d.ts +1 -0
  57. package/dist/types/modes/components/extensions/state-manager.d.ts +4 -3
  58. package/dist/types/modes/controllers/input-controller.d.ts +9 -0
  59. package/dist/types/modes/interactive-mode.d.ts +1 -0
  60. package/dist/types/modes/utils/interrupt-ownership.d.ts +3 -0
  61. package/dist/types/modes/utils/keybinding-matchers.d.ts +1 -0
  62. package/dist/types/modes/utils/macos-option-forwarding.d.ts +17 -0
  63. package/dist/types/progress/collect-project-progress.d.ts +38 -0
  64. package/dist/types/progress/progress-contract.d.ts +154 -0
  65. package/dist/types/progress/progress-snapshot.d.ts +11 -0
  66. package/dist/types/progress/project-progress.d.ts +141 -0
  67. package/dist/types/progress/render-progress.d.ts +28 -0
  68. package/dist/types/runtime-mcp/manager.d.ts +2 -1
  69. package/dist/types/runtime-mcp/mcp-redirect.d.ts +9 -0
  70. package/dist/types/runtime-mcp/oauth-public-url.d.ts +3 -0
  71. package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +1 -0
  72. package/dist/types/runtime-mcp/project-host-values.d.ts +27 -0
  73. package/dist/types/runtime-mcp/smithery-registry.d.ts +24 -0
  74. package/dist/types/runtime-mcp/types.d.ts +6 -0
  75. package/dist/types/sdk/acp/adapter.d.ts +1 -1
  76. package/dist/types/sdk/broker/broker-exit.d.ts +6 -2
  77. package/dist/types/sdk/broker/broker.d.ts +24 -2
  78. package/dist/types/sdk/broker/doctor-restart.d.ts +5 -0
  79. package/dist/types/sdk/broker/ensure.d.ts +14 -1
  80. package/dist/types/sdk/broker/session-index.d.ts +12 -6
  81. package/dist/types/sdk/bus/index.d.ts +12 -1
  82. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -1
  83. package/dist/types/sdk/client/client.d.ts +2 -0
  84. package/dist/types/sdk/host/query/handlers.d.ts +3 -0
  85. package/dist/types/sdk/index.d.ts +1 -0
  86. package/dist/types/sdk/router/session-router.d.ts +2 -0
  87. package/dist/types/sdk/session-list.d.ts +1 -1
  88. package/dist/types/sdk/session.d.ts +8 -0
  89. package/dist/types/session/agent-session.d.ts +38 -9
  90. package/dist/types/session/artifacts.d.ts +2 -2
  91. package/dist/types/session/internal/managed-gc-retirement-codec.d.ts +32 -0
  92. package/dist/types/session/internal/managed-session-scope.d.ts +79 -2
  93. package/dist/types/session/internal/managed-session-storage.d.ts +26 -1
  94. package/dist/types/session/internal/managed-task-owner-cleanup.d.ts +62 -0
  95. package/dist/types/session/internal/task-artifact-owner-access.d.ts +2 -0
  96. package/dist/types/session/internal/task-artifact-owner-transcript.d.ts +9 -1
  97. package/dist/types/session/session-manager.d.ts +31 -5
  98. package/dist/types/session/session-retirement.d.ts +31 -7
  99. package/dist/types/session/session-storage.d.ts +69 -2
  100. package/dist/types/session/task-artifact-owner-codec.d.ts +2 -0
  101. package/dist/types/setup/credential-auto-import.d.ts +1 -1
  102. package/dist/types/setup/credential-import.d.ts +6 -4
  103. package/dist/types/skill-state/active-state.d.ts +38 -0
  104. package/dist/types/skill-state/workflow-mutation-guard.d.ts +3 -0
  105. package/dist/types/slash-commands/helpers/progress-report.d.ts +8 -0
  106. package/dist/types/task/executor.d.ts +3 -0
  107. package/dist/types/task/isolation-dir.d.ts +26 -0
  108. package/dist/types/tools/ast-edit-write-path.d.ts +13 -0
  109. package/dist/types/tools/bash-skill-urls.d.ts +1 -1
  110. package/dist/types/tools/browser/cdp-url.d.ts +2 -0
  111. package/dist/types/tools/github-side-effect.d.ts +22 -0
  112. package/dist/types/tools/index.d.ts +3 -0
  113. package/dist/types/tools/monitor-mutation.d.ts +9 -0
  114. package/dist/types/tools/python.d.ts +9 -1
  115. package/dist/types/tools/recipe/recipe-guard.d.ts +7 -0
  116. package/dist/types/tools/restricted-cwd.d.ts +1 -0
  117. package/dist/types/tools/todo-write.d.ts +6 -0
  118. package/dist/types/utils/tools-checksum.d.ts +7 -0
  119. package/package.json +7 -7
  120. package/scripts/generate-sdk-operation-inventory.ts +21 -0
  121. package/scripts/verify-managed-empty-stop.ts +28 -0
  122. package/src/async/endpoint-id.ts +26 -0
  123. package/src/async/job-manager.ts +247 -132
  124. package/src/async/support.ts +0 -25
  125. package/src/capability/index.ts +15 -0
  126. package/src/capability/mcp.ts +2 -0
  127. package/src/capability/skill.ts +2 -0
  128. package/src/capability/types.ts +2 -0
  129. package/src/cli/auth-broker-cli.ts +1 -1
  130. package/src/cli/customize-doctor.ts +15 -2
  131. package/src/cli/doctor/repairs.ts +4 -1
  132. package/src/cli/doctor-supervisor.ts +3 -0
  133. package/src/cli/public-command-errors.ts +21 -1
  134. package/src/cli/public-command-registry.ts +28 -6
  135. package/src/cli/setup-cli.ts +4 -4
  136. package/src/cli/skills-cli.ts +5 -0
  137. package/src/commands/deep-interview.ts +47 -8
  138. package/src/commands/mcp-serve.ts +7 -0
  139. package/src/commands/sdk.ts +455 -397
  140. package/src/config/autorouting-tier-map.ts +117 -7
  141. package/src/config/file-lock.ts +316 -79
  142. package/src/config/mcp-schema.json +4 -0
  143. package/src/config/model-bindings-applier.ts +20 -0
  144. package/src/config/model-profile-activation.ts +240 -46
  145. package/src/config/model-registry.ts +47 -153
  146. package/src/config/skill-settings-defaults.ts +7 -0
  147. package/src/coordinator-mcp/policy.ts +3 -2
  148. package/src/coordinator-mcp/server.ts +2 -0
  149. package/src/cursor-delete-path.ts +10 -0
  150. package/src/cursor-mcp-name.ts +15 -0
  151. package/src/cursor.ts +13 -2
  152. package/src/customization/inventory.ts +4 -13
  153. package/src/dap/config.ts +2 -2
  154. package/src/debug/report-bundle-parent.ts +22 -0
  155. package/src/debug/report-bundle.ts +3 -0
  156. package/src/debug/system-info.ts +13 -1
  157. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +10 -6
  158. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.ts +67 -4
  159. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/version-manager.ts +80 -0
  160. package/src/defaults/gjc/skills/deep-interview/SKILL.md +105 -10
  161. package/src/defaults/gjc/skills/ralplan/SKILL.md +6 -4
  162. package/src/defaults/gjc-defaults.test.ts +18 -1
  163. package/src/defaults/gjc-defaults.ts +3 -0
  164. package/src/defaults/gjc-skills.generated.ts +58 -36
  165. package/src/discovery/agents.ts +6 -1
  166. package/src/discovery/builtin.ts +13 -1
  167. package/src/discovery/helpers.ts +171 -29
  168. package/src/discovery/mcp-json.ts +26 -12
  169. package/src/discovery/ssh.ts +1 -1
  170. package/src/discovery/substitute-plugin-root.ts +3 -1
  171. package/src/edit/file-read-cache.ts +1 -1
  172. package/src/eval/py/executor.ts +796 -154
  173. package/src/eval/py/kernel.ts +79 -13
  174. package/src/eval/py/tool-bridge.ts +4 -0
  175. package/src/export/html/css-color.ts +9 -0
  176. package/src/export/html/html-export-destination.ts +16 -0
  177. package/src/export/html/index.ts +7 -10
  178. package/src/export/html/template.generated.ts +1 -1
  179. package/src/extensibility/extensions/function-hooks-internal.ts +27 -0
  180. package/src/extensibility/extensions/runner.ts +15 -1
  181. package/src/extensibility/extensions/types.ts +7 -0
  182. package/src/extensibility/gjc-plugins/mcp-policy.ts +2 -1
  183. package/src/extensibility/gjc-plugins/runtime-adapters.ts +85 -8
  184. package/src/extensibility/plugins/manager.ts +3 -2
  185. package/src/extensibility/plugins/marketplace/cache.ts +15 -0
  186. package/src/extensibility/plugins/marketplace/manager.ts +11 -3
  187. package/src/extensibility/plugins/plugin-link-path.ts +12 -0
  188. package/src/extensibility/runtime-skill-discovery.ts +20 -2
  189. package/src/extensibility/skill-management.ts +9 -2
  190. package/src/extensibility/skills.ts +6 -1
  191. package/src/gjc-runtime/deep-interview-crystallize.ts +1814 -0
  192. package/src/gjc-runtime/deep-interview-recorder.ts +20 -2
  193. package/src/gjc-runtime/deep-interview-runtime.ts +1415 -13
  194. package/src/gjc-runtime/deep-interview-stage.ts +98 -21
  195. package/src/gjc-runtime/gc-runtime.ts +206 -9
  196. package/src/gjc-runtime/launch-worktree.ts +70 -9
  197. package/src/gjc-runtime/psmux-detect.ts +28 -4
  198. package/src/gjc-runtime/ralplan-runtime.ts +447 -52
  199. package/src/gjc-runtime/session-state-sidecar.ts +3 -2
  200. package/src/gjc-runtime/sidecar-bootstrap-env.ts +19 -0
  201. package/src/gjc-runtime/state-argv.ts +2 -0
  202. package/src/gjc-runtime/state-migrations.ts +91 -29
  203. package/src/gjc-runtime/state-runtime.ts +3716 -135
  204. package/src/gjc-runtime/state-writer.ts +105 -16
  205. package/src/gjc-runtime/tmux-common.ts +8 -5
  206. package/src/gjc-runtime/ultragoal-runtime.ts +16 -4
  207. package/src/gjc-runtime/workflow-manifest.generated.json +70 -42
  208. package/src/gjc-runtime/workflow-manifest.ts +54 -21
  209. package/src/harness-control-plane/operate.ts +12 -4
  210. package/src/harness-control-plane/owner.ts +5 -1
  211. package/src/hashline/parser.ts +48 -9
  212. package/src/hashline/recovery.ts +13 -4
  213. package/src/internal-urls/docs-index.generated.ts +20 -19
  214. package/src/internal-urls/skill-path.ts +19 -0
  215. package/src/internal-urls/skill-protocol.ts +2 -0
  216. package/src/lsp/config.ts +12 -63
  217. package/src/lsp/edits.ts +6 -0
  218. package/src/lsp/workspace-path.ts +51 -0
  219. package/src/main.ts +195 -31
  220. package/src/memories/index.ts +88 -7
  221. package/src/modes/acp/acp-agent.ts +88 -4
  222. package/src/modes/components/custom-editor.ts +14 -0
  223. package/src/modes/components/customization/customization-dashboard.ts +12 -0
  224. package/src/modes/components/extensions/extension-dashboard.ts +2 -2
  225. package/src/modes/components/extensions/state-manager.ts +15 -5
  226. package/src/modes/components/hook-editor.ts +1 -1
  227. package/src/modes/components/hook-selector.ts +1 -1
  228. package/src/modes/components/model-selector.ts +1 -4
  229. package/src/modes/components/provider-onboarding-selector.ts +1 -1
  230. package/src/modes/components/status-line/segments.ts +4 -0
  231. package/src/modes/controllers/event-controller.ts +11 -4
  232. package/src/modes/controllers/input-controller.ts +76 -31
  233. package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -16
  234. package/src/modes/controllers/selector-controller.ts +24 -15
  235. package/src/modes/controllers/todo-command-controller.ts +1 -1
  236. package/src/modes/interactive-mode.ts +5 -1
  237. package/src/modes/runtime-init.ts +4 -0
  238. package/src/modes/utils/abort-message.ts +3 -1
  239. package/src/modes/utils/interrupt-ownership.ts +12 -0
  240. package/src/modes/utils/keybinding-matchers.ts +4 -0
  241. package/src/modes/utils/macos-option-forwarding.ts +80 -0
  242. package/src/progress/collect-project-progress.ts +153 -0
  243. package/src/progress/progress-contract.ts +172 -0
  244. package/src/progress/progress-snapshot.ts +140 -0
  245. package/src/progress/project-progress.ts +446 -0
  246. package/src/progress/render-progress.ts +209 -0
  247. package/src/prompts/system/master-mode.md +1 -0
  248. package/src/prompts/tools/skill-discovery.md +1 -1
  249. package/src/runtime-mcp/client.ts +4 -2
  250. package/src/runtime-mcp/config-writer.ts +10 -6
  251. package/src/runtime-mcp/config.ts +1 -0
  252. package/src/runtime-mcp/json-rpc.ts +2 -1
  253. package/src/runtime-mcp/manager.ts +29 -11
  254. package/src/runtime-mcp/mcp-redirect.ts +73 -0
  255. package/src/runtime-mcp/oauth-flow.ts +14 -2
  256. package/src/runtime-mcp/oauth-public-url.ts +14 -0
  257. package/src/runtime-mcp/plugin-network-boundary.ts +4 -0
  258. package/src/runtime-mcp/pool.ts +6 -0
  259. package/src/runtime-mcp/project-host-values.ts +46 -0
  260. package/src/runtime-mcp/smithery-registry.ts +22 -3
  261. package/src/runtime-mcp/transports/http.ts +4 -3
  262. package/src/runtime-mcp/types.ts +6 -0
  263. package/src/sdk/acp/adapter.ts +95 -8
  264. package/src/sdk/broker/broker-exit.ts +52 -23
  265. package/src/sdk/broker/broker.ts +81 -6
  266. package/src/sdk/broker/doctor-restart.ts +4 -0
  267. package/src/sdk/broker/ensure.ts +31 -2
  268. package/src/sdk/broker/lifecycle.ts +711 -66
  269. package/src/sdk/broker/session-index.ts +191 -81
  270. package/src/sdk/bus/chat-daemon-cli.ts +38 -1
  271. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  272. package/src/sdk/bus/index.ts +238 -43
  273. package/src/sdk/bus/telegram-daemon-contract.ts +6 -1
  274. package/src/sdk/cli/session-cli.ts +17 -3
  275. package/src/sdk/client/client.ts +28 -8
  276. package/src/sdk/host/query/handlers.ts +9 -1
  277. package/src/sdk/host/session-runtime.test.ts +2705 -303
  278. package/src/sdk/host/session-runtime.ts +490 -143
  279. package/src/sdk/host/surface-policy.ts +1 -0
  280. package/src/sdk/index.ts +8 -0
  281. package/src/sdk/lifecycle-session.ts +3 -1
  282. package/src/sdk/prompt-deadline-manager.ts +15 -0
  283. package/src/sdk/protocol/operation-inventory.generated.json +146 -0
  284. package/src/sdk/protocol/operation-registry.ts +9 -2
  285. package/src/sdk/router/session-router.ts +82 -18
  286. package/src/sdk/session-list.ts +1 -0
  287. package/src/sdk/session.ts +69 -45
  288. package/src/session/agent-session.ts +679 -238
  289. package/src/session/artifacts.ts +176 -71
  290. package/src/session/internal/managed-gc-retirement-codec.ts +319 -0
  291. package/src/session/internal/managed-session-scope.ts +3779 -462
  292. package/src/session/internal/managed-session-storage.ts +501 -78
  293. package/src/session/internal/managed-task-owner-cleanup.ts +473 -0
  294. package/src/session/internal/task-artifact-owner-access.ts +19 -3
  295. package/src/session/internal/task-artifact-owner-transcript.ts +547 -1
  296. package/src/session/session-manager.ts +951 -133
  297. package/src/session/session-retirement.ts +573 -14
  298. package/src/session/session-storage.ts +447 -15
  299. package/src/session/task-artifact-owner-codec.ts +71 -8
  300. package/src/session/task-artifact-owner-retirement.ts +21 -19
  301. package/src/setup/credential-auto-import.ts +12 -3
  302. package/src/setup/credential-import.ts +176 -5
  303. package/src/setup/paseo/announce.ts +6 -1
  304. package/src/skill-state/active-state.ts +145 -2
  305. package/src/skill-state/workflow-mutation-guard.ts +102 -10
  306. package/src/slash-commands/builtin-registry.ts +39 -9
  307. package/src/slash-commands/helpers/mcp.ts +8 -4
  308. package/src/slash-commands/helpers/progress-report.ts +23 -0
  309. package/src/stt/setup.ts +3 -5
  310. package/src/task/commands.ts +3 -1
  311. package/src/task/executor.ts +4 -0
  312. package/src/task/index.ts +6 -0
  313. package/src/task/isolation-dir.ts +143 -0
  314. package/src/task/worktree.ts +16 -7
  315. package/src/tools/ask.ts +205 -6
  316. package/src/tools/ast-edit-write-path.ts +68 -0
  317. package/src/tools/ast-edit.ts +10 -1
  318. package/src/tools/bash-allowed-prefixes.ts +15 -0
  319. package/src/tools/bash-skill-urls.ts +56 -3
  320. package/src/tools/bash.ts +48 -79
  321. package/src/tools/browser/cdp-url.ts +18 -0
  322. package/src/tools/browser.ts +8 -1
  323. package/src/tools/descriptors.ts +5 -1
  324. package/src/tools/eval.ts +56 -36
  325. package/src/tools/gh.ts +10 -0
  326. package/src/tools/github-side-effect.ts +112 -0
  327. package/src/tools/image-gen.ts +1 -1
  328. package/src/tools/index.ts +3 -0
  329. package/src/tools/monitor-mutation.ts +27 -0
  330. package/src/tools/monitor.ts +7 -0
  331. package/src/tools/python.ts +188 -66
  332. package/src/tools/recipe/index.ts +9 -0
  333. package/src/tools/recipe/recipe-guard.ts +19 -0
  334. package/src/tools/restricted-cwd.ts +10 -0
  335. package/src/tools/skill-discovery.ts +5 -0
  336. package/src/tools/skill.ts +28 -1
  337. package/src/tools/todo-write.ts +10 -1
  338. package/src/tools/tool-catalog.generated.ts +1 -1
  339. package/src/tools/write.ts +1 -0
  340. package/src/utils/external-editor.ts +3 -2
  341. package/src/utils/tools-checksum.ts +34 -0
  342. package/src/utils/tools-manager.ts +24 -6
  343. package/src/web/insane/url-guard.ts +2 -1
  344. package/src/web/search/providers/codex.ts +3 -2
@@ -0,0 +1,153 @@
1
+ import type { SubagentLifecycle } from "../async/job-manager";
2
+ import { readUltragoalPlan } from "../gjc-runtime/ultragoal-runtime";
3
+ import type { Goal, GoalModeState } from "../goals/state";
4
+ import type { SessionManager } from "../session/session-manager";
5
+ import {
6
+ normalizeWorkflowHudSummary,
7
+ readVisibleSkillActiveStateWithStatus,
8
+ type VisibleSkillActiveStateReadStatus,
9
+ } from "../skill-state/active-state";
10
+ import { findLatestTodoPhasesFromEntries, type TodoPhase } from "../tools/todo-write";
11
+ import type { ProgressDurableSource } from "./progress-contract";
12
+ import {
13
+ computeProjectProgress,
14
+ type ProgressUltragoalInput,
15
+ type ProgressWorkflowInput,
16
+ type ProjectProgressInput,
17
+ type ProjectProgressReport,
18
+ } from "./project-progress";
19
+
20
+ /** Session-owned state the overview reads; everything else comes from durable `.gjc` files. */
21
+ export interface ProjectProgressSessionView {
22
+ cwd: string;
23
+ /** GJC session id that scopes `.gjc/_session-{id}` state; without it no workflow state is read. */
24
+ sessionId: string | undefined;
25
+ goal: Goal | undefined;
26
+ todoPhases: readonly TodoPhase[];
27
+ subagents: readonly SubagentLifecycle[];
28
+ }
29
+
30
+ async function readWorkflows(
31
+ cwd: string,
32
+ sessionId: string,
33
+ ): Promise<{ status: VisibleSkillActiveStateReadStatus; workflows: ProgressWorkflowInput[] }> {
34
+ // The tolerant HUD reader maps an unreadable session snapshot to "nothing
35
+ // active" and lets snapshot-only rows survive; this projection must report
36
+ // unreadable state as unreadable, and never report a row without authority.
37
+ const { status, state } = await readVisibleSkillActiveStateWithStatus(cwd, sessionId);
38
+ const workflows = (state?.active_skills ?? [])
39
+ .filter(entry => entry.active !== false)
40
+ .map(entry => {
41
+ const hud = normalizeWorkflowHudSummary(entry.hud);
42
+ return {
43
+ skill: entry.skill,
44
+ phase: entry.phase?.trim() || "unknown",
45
+ ...(hud?.summary ? { summary: hud.summary } : {}),
46
+ chips: (hud?.chips ?? []).map(chip => ({
47
+ label: chip.label,
48
+ ...(chip.value ? { value: chip.value } : {}),
49
+ ...(chip.severity ? { severity: chip.severity } : {}),
50
+ })),
51
+ };
52
+ });
53
+ return { status, workflows };
54
+ }
55
+
56
+ async function readUltragoal(cwd: string, sessionId: string): Promise<ProgressUltragoalInput | undefined> {
57
+ const plan = await readUltragoalPlan(cwd, sessionId);
58
+ if (!plan || plan.goals.length === 0) return undefined;
59
+ return {
60
+ objective: plan.gjcObjective,
61
+ stories: plan.goals.map(goal => ({
62
+ id: goal.id,
63
+ title: goal.title,
64
+ status: goal.status,
65
+ hasVerificationReceipt: typeof goal.completionVerification?.receiptId === "string",
66
+ })),
67
+ };
68
+ }
69
+
70
+ /**
71
+ * Gather progress input strictly by reading state. A source that fails to read
72
+ * is reported as unreadable and excluded; it never aborts the overview and is
73
+ * never replaced by a guess. A source rebuilt from authoritative per-entry
74
+ * records after its snapshot failed to read is reported as recovered; one whose
75
+ * readable derived snapshot listed stale rows is reported as discarded; one whose
76
+ * rows could not be attributed to an authority is reported as unresolved.
77
+ */
78
+ export async function collectProjectProgressInput(view: ProjectProgressSessionView): Promise<ProjectProgressInput> {
79
+ const unreadable: ProgressDurableSource[] = [];
80
+ const recovered: ProgressDurableSource[] = [];
81
+ const discarded: ProgressDurableSource[] = [];
82
+ const unresolved: ProgressDurableSource[] = [];
83
+ const sessionId = view.sessionId?.trim() || undefined;
84
+ let workflows: ProgressWorkflowInput[] = [];
85
+ let ultragoal: ProgressUltragoalInput | undefined;
86
+ if (sessionId) {
87
+ const [workflowResult, ultragoalResult] = await Promise.allSettled([
88
+ readWorkflows(view.cwd, sessionId),
89
+ readUltragoal(view.cwd, sessionId),
90
+ ]);
91
+ if (workflowResult.status === "rejected" || workflowResult.value.status === "failed") {
92
+ unreadable.push("workflow-state");
93
+ } else {
94
+ workflows = workflowResult.value.workflows;
95
+ if (workflowResult.value.status === "recovered") recovered.push("workflow-state");
96
+ else if (workflowResult.value.status === "discarded") discarded.push("workflow-state");
97
+ else if (workflowResult.value.status === "unresolved") unresolved.push("workflow-state");
98
+ }
99
+ if (ultragoalResult.status === "fulfilled") ultragoal = ultragoalResult.value;
100
+ else unreadable.push("ultragoal-plan");
101
+ }
102
+ return {
103
+ ...(view.goal
104
+ ? {
105
+ goal: {
106
+ objective: view.goal.objective,
107
+ status: view.goal.status,
108
+ timeUsedSeconds: view.goal.timeUsedSeconds,
109
+ },
110
+ }
111
+ : {}),
112
+ todos: view.todoPhases.flatMap(phase =>
113
+ phase.tasks.map(task => ({ content: task.content, status: task.status })),
114
+ ),
115
+ workflows,
116
+ ...(ultragoal ? { ultragoal } : {}),
117
+ subagents: [...view.subagents],
118
+ sessionStateRead: sessionId !== undefined,
119
+ unreadable,
120
+ recovered,
121
+ discarded,
122
+ unresolved,
123
+ };
124
+ }
125
+
126
+ /** The live session state `/progress` and `session.progress` read; satisfied by `AgentSession`. */
127
+ export interface ProjectProgressSessionSource {
128
+ getGoalModeState(): GoalModeState | undefined;
129
+ getTodoPhases(): TodoPhase[];
130
+ getSubagentLifecycleStatuses(): SubagentLifecycle[];
131
+ }
132
+
133
+ /**
134
+ * Single entry point shared by the human view and the machine snapshot.
135
+ *
136
+ * Todos come from the persisted branch history, as `/todo` reads them: the live
137
+ * list drops completed and abandoned items when a session is resumed, so it is
138
+ * only the fallback when no todo state was ever persisted. A persisted empty
139
+ * list is authoritative and is not replaced by live state.
140
+ */
141
+ export async function buildSessionProjectProgress(
142
+ session: ProjectProgressSessionSource,
143
+ sessionManager: Pick<SessionManager, "getCwd" | "getSessionId" | "getBranch">,
144
+ ): Promise<ProjectProgressReport> {
145
+ const input = await collectProjectProgressInput({
146
+ cwd: sessionManager.getCwd(),
147
+ sessionId: sessionManager.getSessionId(),
148
+ goal: session.getGoalModeState()?.goal,
149
+ todoPhases: findLatestTodoPhasesFromEntries(sessionManager.getBranch()) ?? session.getTodoPhases(),
150
+ subagents: session.getSubagentLifecycleStatuses(),
151
+ });
152
+ return computeProjectProgress(input);
153
+ }
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Wire contract of the `session.progress` (Q32) snapshot, `gjc.project_progress.v1`.
3
+ *
4
+ * This module is a dependency leaf on purpose: the production ACP agent renders
5
+ * `/progress` from this contract and must not reach the in-process session
6
+ * graph (enforced by `scripts/verify-gjc-sdk-canonicalization.ts`, which also
7
+ * follows type-only imports). Status unions are restated here; the projection
8
+ * in `progress-snapshot.ts` assigns the runtime statuses to them, so a new
9
+ * runtime status that the contract lacks fails type checking.
10
+ */
11
+ import { sanitizeDisplayLine } from "@gajae-code/utils";
12
+
13
+ /** Ultragoal story status (`UltragoalGoalStatus`). */
14
+ export type ProgressStoryStatus =
15
+ | "pending"
16
+ | "active"
17
+ | "complete"
18
+ | "failed"
19
+ | "blocked"
20
+ | "review_blocked"
21
+ | "superseded";
22
+ /** Session goal status (`GoalStatus`). */
23
+ export type ProgressGoalStatus = "active" | "paused" | "complete" | "dropped";
24
+ /** Todo item status (`TodoStatus`). */
25
+ export type ProgressTodoStatus = "pending" | "in_progress" | "completed" | "abandoned";
26
+ /** Workflow HUD chip severity (`WorkflowHudSeverity`). */
27
+ export type ProgressChipSeverity = "info" | "warning" | "blocked" | "error" | "success";
28
+
29
+ /** Durable `.gjc` session-state sources that can fail to read. */
30
+ export type ProgressDurableSource = "workflow-state" | "ultragoal-plan";
31
+
32
+ export type ProgressBasisKind = "ultragoal-stories" | "todos" | "goal-status" | "none";
33
+
34
+ export type ProgressHeadline =
35
+ | "complete"
36
+ | "awaiting-completion"
37
+ | "blocked"
38
+ | "in-progress"
39
+ | "not-started"
40
+ | "paused"
41
+ | "dropped"
42
+ | "no-tracked-work";
43
+
44
+ export type ProgressSignalKind = "blocker" | "pending" | "note";
45
+
46
+ export type ProgressSignalSource = "ultragoal" | "workflow" | "subagents" | "todos" | "goal" | "state";
47
+
48
+ export interface ProgressAgentCounts {
49
+ total: number;
50
+ running: number;
51
+ /** Subagents that are queued or paused. */
52
+ waiting: number;
53
+ completed: number;
54
+ failed: number;
55
+ cancelled: number;
56
+ }
57
+
58
+ export interface ProgressReviewVerdict {
59
+ skill: string;
60
+ verdict: string;
61
+ }
62
+
63
+ export const PROJECT_PROGRESS_SNAPSHOT_SCHEMA = "gjc.project_progress.v1";
64
+
65
+ /** Bounds keep one snapshot well under a single SDK query page. */
66
+ export const PROGRESS_SNAPSHOT_LIMITS = { stories: 100, todos: 100, workflows: 16, attention: 50, text: 300 } as const;
67
+
68
+ export interface ProgressSnapshotStory {
69
+ id: string;
70
+ title: string;
71
+ status: ProgressStoryStatus;
72
+ /** A completion-verification (quality-gate) receipt is recorded on the story. */
73
+ verificationReceipt: boolean;
74
+ }
75
+
76
+ export interface ProgressSnapshotTodo {
77
+ content: string;
78
+ status: ProgressTodoStatus;
79
+ }
80
+
81
+ export interface ProgressSnapshotWorkflow {
82
+ skill: string;
83
+ phase: string;
84
+ summary: string | null;
85
+ chips: { label: string; value: string | null; severity: ProgressChipSeverity | null }[];
86
+ }
87
+
88
+ export interface ProgressSnapshotAttention {
89
+ kind: ProgressSignalKind;
90
+ source: ProgressSignalSource;
91
+ ref: string | null;
92
+ text: string;
93
+ }
94
+
95
+ export interface ProjectProgressSnapshot {
96
+ schema: typeof PROJECT_PROGRESS_SNAPSHOT_SCHEMA;
97
+ /** Overall completion state; identical to the `/progress` headline. */
98
+ state: ProgressHeadline;
99
+ completion: {
100
+ /** Which countable units the indicator was derived from; `none` means nothing is countable. */
101
+ basis: ProgressBasisKind;
102
+ done: number;
103
+ total: number;
104
+ /** Whole percent; `null` when `basis` is `none`. Never 100 while a unit is open. */
105
+ percent: number | null;
106
+ /** Every counted unit is done (the session may still be awaiting goal completion or subagents). */
107
+ allUnitsDone: boolean;
108
+ /** `state === "complete"`: units done, goal (if any) complete, no subagents running, queued, or paused. */
109
+ complete: boolean;
110
+ explanation: string;
111
+ };
112
+ execution: {
113
+ goal: { objective: string; status: ProgressGoalStatus; timeUsedSeconds: number } | null;
114
+ ultragoal: {
115
+ objective: string;
116
+ counts: {
117
+ total: number;
118
+ complete: number;
119
+ active: number;
120
+ pending: number;
121
+ blocked: number;
122
+ superseded: number;
123
+ };
124
+ stories: ProgressSnapshotStory[];
125
+ omittedStories: number;
126
+ } | null;
127
+ todos: {
128
+ counts: { total: number; completed: number; inProgress: number; pending: number; abandoned: number };
129
+ items: ProgressSnapshotTodo[];
130
+ omittedItems: number;
131
+ } | null;
132
+ };
133
+ activeWork: {
134
+ /**
135
+ * Active story, else the next pending one, matching the Ultragoal scheduler.
136
+ * Blocked, review-blocked, and failed stories are never reported here (failed
137
+ * stories are retried only on explicit request); `null` when nothing is schedulable.
138
+ */
139
+ story: { id: string; title: string } | null;
140
+ /** In-progress todo, else the next pending one. */
141
+ todo: string | null;
142
+ workflows: ProgressSnapshotWorkflow[];
143
+ /** Active workflows beyond `PROGRESS_SNAPSHOT_LIMITS.workflows` that `workflows` leaves out. */
144
+ omittedWorkflows: number;
145
+ agents: ProgressAgentCounts;
146
+ };
147
+ verification: {
148
+ /** Present only when at least one story is complete. */
149
+ storyReceipts: { complete: number; withReceipt: number; withoutReceipt: number } | null;
150
+ reviewVerdicts: ProgressReviewVerdict[];
151
+ };
152
+ attention: ProgressSnapshotAttention[];
153
+ omittedAttention: number;
154
+ sources: {
155
+ /** Session-scoped `.gjc` state (workflows, ultragoal plan) was consulted. */
156
+ sessionStateRead: boolean;
157
+ /** Sources that exist but could not be read; excluded from every count. */
158
+ unreadable: ProgressDurableSource[];
159
+ /** Sources whose primary record was unreadable but whose contents were recovered from authoritative per-entry records. */
160
+ recovered: ProgressDurableSource[];
161
+ /** Sources whose readable derived snapshot listed entries the authoritative per-entry records do not; those stale entries were discarded. */
162
+ discarded: ProgressDurableSource[];
163
+ /** Sources listing entries whose authority could not be established; those entries are excluded and their absence is unconfirmed. */
164
+ unresolved: ProgressDurableSource[];
165
+ };
166
+ }
167
+
168
+ /** Strip terminal escapes/control characters and bound length; durable text is untrusted. */
169
+ export function boundSnapshotText(text: string, max: number = PROGRESS_SNAPSHOT_LIMITS.text): string {
170
+ const clean = sanitizeDisplayLine(text).replace(/\s+/g, " ").trim();
171
+ return clean.length > max ? `${clean.slice(0, max - 1)}…` : clean;
172
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Machine-facing projection of the project progress report (SDK query
3
+ * `session.progress`, Q32). It is a pure re-shaping of `ProjectProgressReport`:
4
+ * every number, state, and attention item comes from the same computation, and
5
+ * the human `/progress` view renders this snapshot (`render-progress.ts`), so
6
+ * the two can never disagree. Absent evidence is `null`/empty, never estimated.
7
+ * Every bounded list reports how many entries it omitted.
8
+ */
9
+ import {
10
+ boundSnapshotText,
11
+ PROGRESS_SNAPSHOT_LIMITS,
12
+ PROJECT_PROGRESS_SNAPSHOT_SCHEMA,
13
+ type ProjectProgressSnapshot,
14
+ } from "./progress-contract";
15
+ import type { ProjectProgressReport } from "./project-progress";
16
+
17
+ function bounded<T, U>(items: readonly T[], limit: number, map: (item: T) => U): { kept: U[]; omitted: number } {
18
+ return { kept: items.slice(0, limit).map(map), omitted: Math.max(0, items.length - limit) };
19
+ }
20
+
21
+ export function toProjectProgressSnapshot(report: ProjectProgressReport): ProjectProgressSnapshot {
22
+ const { completion } = report;
23
+ const stories = report.stories;
24
+ const ultragoal =
25
+ report.ultragoal && stories
26
+ ? (() => {
27
+ const { kept, omitted } = bounded(report.ultragoal.stories, PROGRESS_SNAPSHOT_LIMITS.stories, story => ({
28
+ id: boundSnapshotText(story.id, 64),
29
+ title: boundSnapshotText(story.title),
30
+ status: story.status,
31
+ verificationReceipt: story.hasVerificationReceipt,
32
+ }));
33
+ return {
34
+ objective: boundSnapshotText(report.ultragoal.objective),
35
+ counts: {
36
+ total: stories.total,
37
+ complete: stories.complete,
38
+ active: stories.active,
39
+ pending: stories.pending,
40
+ blocked: stories.blocked,
41
+ superseded: stories.superseded,
42
+ },
43
+ stories: kept,
44
+ omittedStories: omitted,
45
+ };
46
+ })()
47
+ : null;
48
+ const todos = report.todos
49
+ ? (() => {
50
+ const { kept, omitted } = bounded(report.todoItems, PROGRESS_SNAPSHOT_LIMITS.todos, todo => ({
51
+ content: boundSnapshotText(todo.content),
52
+ status: todo.status,
53
+ }));
54
+ const t = report.todos;
55
+ return {
56
+ counts: {
57
+ total: t.total,
58
+ completed: t.completed,
59
+ inProgress: t.inProgress,
60
+ pending: t.pending,
61
+ abandoned: t.abandoned,
62
+ },
63
+ items: kept,
64
+ omittedItems: omitted,
65
+ };
66
+ })()
67
+ : null;
68
+ const workflows = bounded(report.workflows, PROGRESS_SNAPSHOT_LIMITS.workflows, workflow => ({
69
+ skill: boundSnapshotText(workflow.skill, 64),
70
+ phase: boundSnapshotText(workflow.phase, 64),
71
+ summary: workflow.summary ? boundSnapshotText(workflow.summary) : null,
72
+ chips: workflow.chips.map(chip => ({
73
+ label: boundSnapshotText(chip.label, 64),
74
+ value: chip.value ? boundSnapshotText(chip.value) : null,
75
+ severity: chip.severity ?? null,
76
+ })),
77
+ }));
78
+ const attention = bounded(report.signals, PROGRESS_SNAPSHOT_LIMITS.attention, signal => ({
79
+ kind: signal.kind,
80
+ source: signal.source,
81
+ ref: signal.ref === undefined ? null : boundSnapshotText(signal.ref, 64),
82
+ text: boundSnapshotText(signal.text),
83
+ }));
84
+ const receipts = report.verification.storyReceipts;
85
+ return {
86
+ schema: PROJECT_PROGRESS_SNAPSHOT_SCHEMA,
87
+ state: report.headline,
88
+ completion: {
89
+ basis: completion.basis,
90
+ done: completion.done,
91
+ total: completion.total,
92
+ percent: completion.percent ?? null,
93
+ allUnitsDone: completion.total > 0 && completion.done >= completion.total,
94
+ complete: report.headline === "complete",
95
+ explanation: report.basisExplanation,
96
+ },
97
+ execution: {
98
+ goal: report.goal
99
+ ? {
100
+ objective: boundSnapshotText(report.goal.objective),
101
+ status: report.goal.status,
102
+ timeUsedSeconds: report.goal.timeUsedSeconds,
103
+ }
104
+ : null,
105
+ ultragoal,
106
+ todos,
107
+ },
108
+ activeWork: {
109
+ story: stories?.current
110
+ ? { id: boundSnapshotText(stories.current.id, 64), title: boundSnapshotText(stories.current.title) }
111
+ : null,
112
+ todo: report.todos?.current ? boundSnapshotText(report.todos.current) : null,
113
+ workflows: workflows.kept,
114
+ omittedWorkflows: workflows.omitted,
115
+ agents: { ...report.agents },
116
+ },
117
+ verification: {
118
+ storyReceipts: receipts
119
+ ? {
120
+ complete: receipts.complete,
121
+ withReceipt: receipts.withReceipt,
122
+ withoutReceipt: receipts.complete - receipts.withReceipt,
123
+ }
124
+ : null,
125
+ reviewVerdicts: report.verification.reviewVerdicts.map(({ skill, verdict }) => ({
126
+ skill: boundSnapshotText(skill, 64),
127
+ verdict: boundSnapshotText(verdict, 64),
128
+ })),
129
+ },
130
+ attention: attention.kept,
131
+ omittedAttention: attention.omitted,
132
+ sources: {
133
+ sessionStateRead: report.sessionStateRead,
134
+ unreadable: [...report.unreadable],
135
+ recovered: [...report.recovered],
136
+ discarded: [...report.discarded],
137
+ unresolved: [...report.unresolved],
138
+ },
139
+ };
140
+ }