@fitlab-ai/agent-infra 0.9.2 → 0.9.4

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 (428) hide show
  1. package/README.md +12 -9
  2. package/README.zh-CN.md +12 -9
  3. package/bin/cli.ts +12 -0
  4. package/dist/bin/cli.js +14 -0
  5. package/dist/bin/internal-cli.js +134 -108
  6. package/dist/lib/agent-clients/adapter.js +137 -4
  7. package/dist/lib/agent-clients/adapters/antigravity-cli.js +64 -0
  8. package/dist/lib/{sandbox/credentials.js → agent-clients/adapters/claude-code-credentials.js} +4 -14
  9. package/dist/lib/agent-clients/adapters/claude-code-refresh.js +85 -0
  10. package/dist/lib/agent-clients/adapters/claude-code-sandbox.js +247 -0
  11. package/dist/lib/agent-clients/adapters/claude-code.js +27 -4
  12. package/dist/lib/agent-clients/adapters/codex.js +9 -0
  13. package/dist/lib/agent-clients/adapters/index.js +2 -2
  14. package/dist/lib/agent-clients/adapters/opencode-sandbox.js +108 -0
  15. package/dist/lib/agent-clients/adapters/opencode.js +24 -3
  16. package/dist/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
  17. package/dist/lib/agent-clients/config.js +42 -4
  18. package/dist/lib/agent-clients/next-steps.js +11 -2
  19. package/dist/lib/agent-clients/reconcile.js +2 -1
  20. package/dist/lib/agent-clients/registry.js +16 -2
  21. package/dist/lib/agent-clients/schema.js +18 -0
  22. package/dist/lib/agent-clients/tokens.js +49 -0
  23. package/dist/lib/agent-clients/types.js +1 -1
  24. package/dist/lib/defaults.json +1 -1
  25. package/dist/lib/git/workflow.js +54 -1
  26. package/dist/lib/internal/agent-client.js +61 -4
  27. package/dist/lib/internal/git-workflow.js +6 -1
  28. package/dist/lib/internal/platform-checks.js +3 -3
  29. package/dist/lib/internal/platform-comment.js +29 -2
  30. package/dist/lib/internal/platform-issue.js +7 -0
  31. package/dist/lib/internal/platform-pr-review.js +132 -0
  32. package/dist/lib/internal/platform-pr.js +20 -2
  33. package/dist/lib/internal/platform-release-notes.js +52 -16
  34. package/dist/lib/internal/pr-review-grade.js +140 -0
  35. package/dist/lib/internal/release-workflow.js +13 -6
  36. package/dist/lib/internal/sandbox-control.js +24 -0
  37. package/dist/lib/internal/task-activity.js +105 -0
  38. package/dist/lib/internal/task-event.js +17 -1
  39. package/dist/lib/internal/task-ledger.js +12 -3
  40. package/dist/lib/internal/task-lifecycle.js +26 -1
  41. package/dist/lib/internal/task-orchestration.js +167 -18
  42. package/dist/lib/internal/task-review.js +8 -3
  43. package/dist/lib/platform/adapters.js +8 -1
  44. package/dist/lib/platform/completion-backfill.js +122 -0
  45. package/dist/lib/platform/github-client.js +19 -2
  46. package/dist/lib/platform/issue-comments.js +3 -2
  47. package/dist/lib/platform/merged-pr-equivalence.js +115 -5
  48. package/dist/lib/platform/pr-checks.js +65 -42
  49. package/dist/lib/platform/pr-review.js +166 -0
  50. package/dist/lib/platform/pull-requests.js +371 -4
  51. package/dist/lib/platform/release-notes.js +85 -3
  52. package/dist/lib/platform/releases.js +13 -5
  53. package/dist/lib/pr-review/evidence-grading.js +229 -0
  54. package/dist/lib/process-data/index.js +239 -0
  55. package/dist/lib/process-data/normalize.js +198 -0
  56. package/dist/lib/process-data/privacy.js +33 -0
  57. package/dist/lib/process-data/reconcile.js +95 -0
  58. package/dist/lib/process-data/repair.js +58 -0
  59. package/dist/lib/process-data/sources.js +345 -0
  60. package/dist/lib/process-data/store.js +282 -0
  61. package/dist/lib/process-data/types.js +2 -0
  62. package/dist/lib/run/index.js +4 -3
  63. package/dist/lib/run/tui.js +10 -13
  64. package/dist/lib/sandbox/agent-client-reconciler.js +26 -2
  65. package/dist/lib/sandbox/capture.js +7 -2
  66. package/dist/lib/sandbox/commands/create.js +109 -248
  67. package/dist/lib/sandbox/commands/enter.js +15 -47
  68. package/dist/lib/sandbox/commands/list-running.js +16 -6
  69. package/dist/lib/sandbox/commands/ls.js +10 -6
  70. package/dist/lib/sandbox/commands/rebuild.js +4 -3
  71. package/dist/lib/sandbox/commands/refresh.js +4 -84
  72. package/dist/lib/sandbox/commands/rm.js +24 -3
  73. package/dist/lib/sandbox/commands/show.js +13 -4
  74. package/dist/lib/sandbox/commands/start.js +7 -4
  75. package/dist/lib/sandbox/config.js +2 -0
  76. package/dist/lib/sandbox/constants.js +6 -0
  77. package/dist/lib/sandbox/control/client.js +44 -0
  78. package/dist/lib/sandbox/control/protocol.js +35 -0
  79. package/dist/lib/sandbox/control/server.js +109 -0
  80. package/dist/lib/sandbox/dockerfile.js +36 -13
  81. package/dist/lib/sandbox/mounts.js +17 -4
  82. package/dist/lib/sandbox/recovery.js +128 -5
  83. package/dist/lib/sandbox/redaction.js +12 -0
  84. package/dist/lib/sandbox/runtimes/base.dockerfile +24 -74
  85. package/dist/lib/sandbox/workspace-identity.js +95 -0
  86. package/dist/lib/sandbox/workspace-view.js +103 -0
  87. package/dist/lib/task/activity-intent.js +307 -0
  88. package/dist/lib/task/artifact-lifecycle.js +2 -1
  89. package/dist/lib/task/commands/log.js +15 -14
  90. package/dist/lib/task/commit-finalization.js +267 -0
  91. package/dist/lib/task/commit-intent.js +165 -0
  92. package/dist/lib/task/decision-intents.js +31 -17
  93. package/dist/lib/task/delegation-receipts.js +25 -4
  94. package/dist/lib/task/events.js +67 -28
  95. package/dist/lib/task/finalization-artifacts.js +35 -0
  96. package/dist/lib/task/implementation-inputs.js +54 -7
  97. package/dist/lib/task/ledger-intents.js +35 -1
  98. package/dist/lib/task/lifecycle-execution.js +46 -0
  99. package/dist/lib/task/orchestration.js +753 -54
  100. package/dist/lib/task/resolve-ref.js +41 -1
  101. package/dist/lib/task/review-finalization.js +29 -9
  102. package/dist/lib/task/task-execution-lock.js +231 -0
  103. package/dist/lib/task/verification-checks.js +1 -1
  104. package/dist/lib/task/verification-engine.js +218 -2
  105. package/dist/lib/task/verification.js +4 -3
  106. package/dist/lib/task/workspace-snapshot.js +17 -5
  107. package/lib/agent-clients/adapter.ts +201 -4
  108. package/lib/agent-clients/adapters/antigravity-cli.ts +65 -0
  109. package/lib/{sandbox/credentials.ts → agent-clients/adapters/claude-code-credentials.ts} +3 -18
  110. package/lib/agent-clients/adapters/claude-code-refresh.ts +128 -0
  111. package/lib/agent-clients/adapters/claude-code-sandbox.ts +295 -0
  112. package/lib/agent-clients/adapters/claude-code.ts +31 -4
  113. package/lib/agent-clients/adapters/codex.ts +9 -0
  114. package/lib/agent-clients/adapters/index.ts +2 -2
  115. package/lib/agent-clients/adapters/opencode-sandbox.ts +136 -0
  116. package/lib/agent-clients/adapters/opencode.ts +27 -3
  117. package/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
  118. package/lib/agent-clients/config.ts +49 -4
  119. package/lib/agent-clients/next-steps.ts +15 -2
  120. package/lib/agent-clients/reconcile.ts +2 -1
  121. package/lib/agent-clients/registry.ts +19 -1
  122. package/lib/agent-clients/schema.ts +18 -0
  123. package/lib/agent-clients/tokens.ts +53 -0
  124. package/lib/agent-clients/types.ts +15 -1
  125. package/lib/defaults.json +1 -1
  126. package/lib/git/workflow.ts +66 -2
  127. package/lib/internal/agent-client.ts +59 -4
  128. package/lib/internal/git-workflow.ts +5 -1
  129. package/lib/internal/platform-checks.ts +4 -4
  130. package/lib/internal/platform-comment.ts +17 -2
  131. package/lib/internal/platform-issue.ts +4 -0
  132. package/lib/internal/platform-pr-review.ts +104 -0
  133. package/lib/internal/platform-pr.ts +14 -1
  134. package/lib/internal/platform-release-notes.ts +59 -16
  135. package/lib/internal/pr-review-grade.ts +130 -0
  136. package/lib/internal/release-workflow.ts +13 -6
  137. package/lib/internal/sandbox-control.ts +24 -0
  138. package/lib/internal/task-activity.ts +91 -0
  139. package/lib/internal/task-event.ts +9 -1
  140. package/lib/internal/task-ledger.ts +12 -3
  141. package/lib/internal/task-lifecycle.ts +26 -1
  142. package/lib/internal/task-orchestration.ts +123 -14
  143. package/lib/internal/task-review.ts +8 -3
  144. package/lib/platform/adapters.ts +29 -2
  145. package/lib/platform/completion-backfill.ts +134 -0
  146. package/lib/platform/github-client.ts +20 -2
  147. package/lib/platform/issue-comments.ts +3 -2
  148. package/lib/platform/merged-pr-equivalence.ts +127 -5
  149. package/lib/platform/pr-checks.ts +73 -46
  150. package/lib/platform/pr-review.ts +201 -0
  151. package/lib/platform/pull-requests.ts +444 -3
  152. package/lib/platform/release-notes.ts +100 -4
  153. package/lib/platform/releases.ts +16 -4
  154. package/lib/pr-review/evidence-grading.ts +318 -0
  155. package/lib/process-data/index.ts +224 -0
  156. package/lib/process-data/normalize.ts +202 -0
  157. package/lib/process-data/privacy.ts +41 -0
  158. package/lib/process-data/reconcile.ts +110 -0
  159. package/lib/process-data/repair.ts +64 -0
  160. package/lib/process-data/sources.ts +354 -0
  161. package/lib/process-data/store.ts +315 -0
  162. package/lib/process-data/types.ts +135 -0
  163. package/lib/run/index.ts +5 -3
  164. package/lib/run/tui.ts +14 -12
  165. package/lib/sandbox/agent-client-reconciler.ts +44 -2
  166. package/lib/sandbox/capture.ts +9 -2
  167. package/lib/sandbox/commands/create.ts +126 -280
  168. package/lib/sandbox/commands/enter.ts +13 -59
  169. package/lib/sandbox/commands/list-running.ts +23 -6
  170. package/lib/sandbox/commands/ls.ts +22 -6
  171. package/lib/sandbox/commands/rebuild.ts +4 -3
  172. package/lib/sandbox/commands/refresh.ts +4 -126
  173. package/lib/sandbox/commands/rm.ts +24 -3
  174. package/lib/sandbox/commands/show.ts +30 -4
  175. package/lib/sandbox/commands/start.ts +6 -4
  176. package/lib/sandbox/config.ts +4 -0
  177. package/lib/sandbox/constants.ts +8 -0
  178. package/lib/sandbox/control/client.ts +55 -0
  179. package/lib/sandbox/control/protocol.ts +75 -0
  180. package/lib/sandbox/control/server.ts +117 -0
  181. package/lib/sandbox/dockerfile.ts +66 -13
  182. package/lib/sandbox/mounts.ts +24 -4
  183. package/lib/sandbox/recovery.ts +163 -6
  184. package/lib/sandbox/redaction.ts +14 -0
  185. package/lib/sandbox/runtimes/base.dockerfile +24 -74
  186. package/lib/sandbox/tool-types.ts +16 -0
  187. package/lib/sandbox/workspace-identity.ts +123 -0
  188. package/lib/sandbox/workspace-view.ts +143 -0
  189. package/lib/server/server.schema.json +2 -2
  190. package/lib/task/activity-intent.ts +417 -0
  191. package/lib/task/artifact-lifecycle.ts +2 -1
  192. package/lib/task/commands/log.ts +15 -14
  193. package/lib/task/commit-finalization.ts +356 -0
  194. package/lib/task/commit-intent.ts +230 -0
  195. package/lib/task/decision-intents.ts +32 -12
  196. package/lib/task/delegation-receipts.ts +34 -5
  197. package/lib/task/events.ts +75 -30
  198. package/lib/task/finalization-artifacts.ts +58 -0
  199. package/lib/task/implementation-inputs.ts +62 -8
  200. package/lib/task/ledger-intents.ts +43 -3
  201. package/lib/task/lifecycle-execution.ts +106 -0
  202. package/lib/task/orchestration.ts +1019 -72
  203. package/lib/task/resolve-ref.ts +46 -1
  204. package/lib/task/review-finalization.ts +40 -9
  205. package/lib/task/task-execution-lock.ts +296 -0
  206. package/lib/task/verification-checks.ts +1 -1
  207. package/lib/task/verification-engine.ts +249 -2
  208. package/lib/task/verification.ts +5 -3
  209. package/lib/task/workspace-snapshot.ts +26 -5
  210. package/package.json +3 -3
  211. package/templates/.agents/QUICKSTART.en.md +25 -8
  212. package/templates/.agents/QUICKSTART.zh-CN.md +25 -8
  213. package/templates/.agents/README.en.md +10 -7
  214. package/templates/.agents/README.zh-CN.md +10 -7
  215. package/templates/.agents/hooks/lifecycle-delegation.js +15 -4
  216. package/templates/.agents/rules/README.en.md +1 -1
  217. package/templates/.agents/rules/README.zh-CN.md +1 -1
  218. package/templates/.agents/rules/create-issue.github.en.md +4 -2
  219. package/templates/.agents/rules/create-issue.github.zh-CN.md +4 -2
  220. package/templates/.agents/rules/human-decision-context.en.md +11 -2
  221. package/templates/.agents/rules/human-decision-context.zh-CN.md +11 -2
  222. package/templates/.agents/rules/issue-fields.github.en.md +3 -1
  223. package/templates/.agents/rules/issue-fields.github.zh-CN.md +3 -1
  224. package/templates/.agents/rules/issue-pr-commands.en.md +5 -3
  225. package/templates/.agents/rules/issue-pr-commands.github.en.md +5 -3
  226. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +5 -3
  227. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +5 -3
  228. package/templates/.agents/rules/issue-sync.github.en.md +7 -3
  229. package/templates/.agents/rules/issue-sync.github.zh-CN.md +8 -4
  230. package/templates/.agents/rules/lifecycle-orchestration.en.md +5 -2
  231. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +5 -2
  232. package/templates/.agents/rules/milestone-inference.github.en.md +4 -2
  233. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +4 -2
  234. package/templates/.agents/rules/next-step-output.en.md +3 -1
  235. package/templates/.agents/rules/next-step-output.zh-CN.md +3 -1
  236. package/templates/.agents/rules/no-mid-flow-questions.en.md +17 -0
  237. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +17 -0
  238. package/templates/.agents/rules/pr-checks-commands.en.md +3 -3
  239. package/templates/.agents/rules/pr-checks-commands.github.en.md +2 -2
  240. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +3 -3
  241. package/templates/.agents/rules/pr-checks-commands.zh-CN.md +3 -3
  242. package/templates/.agents/rules/pr-sync.en.md +3 -1
  243. package/templates/.agents/rules/pr-sync.github.en.md +11 -1
  244. package/templates/.agents/rules/pr-sync.github.zh-CN.md +11 -1
  245. package/templates/.agents/rules/pr-sync.zh-CN.md +3 -1
  246. package/templates/.agents/rules/release-commands.en.md +1 -1
  247. package/templates/.agents/rules/release-commands.github.en.md +12 -2
  248. package/templates/.agents/rules/release-commands.github.zh-CN.md +12 -2
  249. package/templates/.agents/rules/release-commands.zh-CN.md +1 -1
  250. package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
  251. package/templates/.agents/rules/task-management.en.md +13 -0
  252. package/templates/.agents/rules/task-management.zh-CN.md +13 -0
  253. package/templates/.agents/skills/analyze-task/SKILL.en.md +10 -7
  254. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +10 -7
  255. package/templates/.agents/skills/block-task/SKILL.en.md +7 -5
  256. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +7 -5
  257. package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -4
  258. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +6 -4
  259. package/templates/.agents/skills/close-codescan/SKILL.en.md +3 -1
  260. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +3 -1
  261. package/templates/.agents/skills/close-dependabot/SKILL.en.md +3 -1
  262. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +3 -1
  263. package/templates/.agents/skills/code-task/SKILL.en.md +10 -7
  264. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +12 -9
  265. package/templates/.agents/skills/commit/SKILL.en.md +23 -11
  266. package/templates/.agents/skills/commit/SKILL.zh-CN.md +29 -11
  267. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -1
  268. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -1
  269. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +49 -0
  270. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +55 -0
  271. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +1 -1
  272. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +1 -1
  273. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  274. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  275. package/templates/.agents/skills/commit/reference/task-status-update.en.md +4 -4
  276. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +4 -4
  277. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +6 -4
  278. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +6 -4
  279. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +1 -1
  280. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +1 -1
  281. package/templates/.agents/skills/complete-task/SKILL.en.md +22 -7
  282. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +22 -7
  283. package/templates/.agents/skills/complete-task/config/verify.en.json +1 -0
  284. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +1 -0
  285. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +17 -0
  286. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +17 -0
  287. package/templates/.agents/skills/create-pr/SKILL.en.md +7 -5
  288. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -5
  289. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +1 -1
  290. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +1 -1
  291. package/templates/.agents/skills/create-release-note/SKILL.en.md +17 -16
  292. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +17 -16
  293. package/templates/.agents/skills/create-task/SKILL.en.md +5 -3
  294. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +5 -3
  295. package/templates/.agents/skills/create-task/reference/context-capture.en.md +34 -0
  296. package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +34 -0
  297. package/templates/.agents/skills/import-issue/SKILL.en.md +5 -3
  298. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -3
  299. package/templates/.agents/skills/plan-task/SKILL.en.md +8 -5
  300. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +8 -5
  301. package/templates/.agents/skills/post-release/SKILL.en.md +2 -0
  302. package/templates/.agents/skills/post-release/SKILL.zh-CN.md +2 -0
  303. package/templates/.agents/skills/release/SKILL.en.md +16 -10
  304. package/templates/.agents/skills/release/SKILL.zh-CN.md +16 -10
  305. package/templates/.agents/skills/restore-task/SKILL.en.md +4 -1
  306. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +4 -1
  307. package/templates/.agents/skills/review-analysis/SKILL.en.md +7 -4
  308. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +7 -4
  309. package/templates/.agents/skills/review-code/SKILL.en.md +11 -8
  310. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +11 -8
  311. package/templates/.agents/skills/review-code/reference/output-templates.en.md +1 -1
  312. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +1 -1
  313. package/templates/.agents/skills/review-plan/SKILL.en.md +7 -4
  314. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +7 -4
  315. package/templates/.agents/skills/review-pr/SKILL.en.md +186 -0
  316. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +186 -0
  317. package/templates/.agents/skills/review-pr/config/verify.en.json +37 -0
  318. package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +37 -0
  319. package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +65 -0
  320. package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +65 -0
  321. package/templates/.agents/skills/review-pr/reference/output-guidance.en.md +18 -0
  322. package/templates/.agents/skills/review-pr/reference/output-guidance.zh-CN.md +18 -0
  323. package/templates/.agents/skills/review-pr/reference/report-template.en.md +85 -0
  324. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +85 -0
  325. package/templates/.agents/skills/run-task/SKILL.en.md +8 -8
  326. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +8 -8
  327. package/templates/.agents/skills/run-task/config/verify.en.json +2 -1
  328. package/templates/.agents/skills/run-task/config/verify.zh-CN.json +2 -1
  329. package/templates/.agents/skills/run-task/reference/host-validation.en.md +20 -0
  330. package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +20 -0
  331. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +98 -107
  332. package/templates/.agents/skills/watch-pr/SKILL.en.md +13 -13
  333. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +13 -13
  334. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +27 -6
  335. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +26 -5
  336. package/templates/.agents/templates/task.en.md +2 -2
  337. package/templates/.agents/templates/task.zh-CN.md +2 -2
  338. package/templates/.agents/workflows/bug-fix.en.yaml +3 -3
  339. package/templates/.agents/workflows/bug-fix.zh-CN.yaml +3 -3
  340. package/templates/.agents/workflows/code-review.en.yaml +1 -1
  341. package/templates/.agents/workflows/code-review.zh-CN.yaml +1 -1
  342. package/templates/.agents/workflows/feature-development.en.yaml +4 -4
  343. package/templates/.agents/workflows/feature-development.zh-CN.yaml +4 -4
  344. package/templates/.agents/workflows/refactoring.en.yaml +3 -3
  345. package/templates/.agents/workflows/refactoring.zh-CN.yaml +3 -3
  346. package/templates/.claude/commands/post-release.en.md +1 -0
  347. package/templates/.claude/commands/post-release.zh-CN.md +1 -0
  348. package/templates/.claude/commands/review-pr.en.md +8 -0
  349. package/templates/.claude/commands/review-pr.zh-CN.md +8 -0
  350. package/templates/.claude/commands/watch-pr.en.md +1 -1
  351. package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
  352. package/templates/.claude/rules/tool-preferences.en.md +20 -0
  353. package/templates/.claude/rules/tool-preferences.zh-CN.md +20 -0
  354. package/templates/.opencode/commands/post-release.en.md +2 -0
  355. package/templates/.opencode/commands/post-release.zh-CN.md +2 -0
  356. package/templates/.opencode/commands/review-pr.en.md +11 -0
  357. package/templates/.opencode/commands/review-pr.zh-CN.md +11 -0
  358. package/templates/.opencode/commands/watch-pr.en.md +1 -1
  359. package/templates/.opencode/commands/watch-pr.zh-CN.md +1 -1
  360. package/dist/lib/agent-clients/adapters/gemini-cli.js +0 -64
  361. package/lib/agent-clients/adapters/gemini-cli.ts +0 -65
  362. package/templates/.gemini/commands/_project_/analyze-task.en.toml +0 -10
  363. package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +0 -10
  364. package/templates/.gemini/commands/_project_/archive-tasks.en.toml +0 -10
  365. package/templates/.gemini/commands/_project_/archive-tasks.zh-CN.toml +0 -10
  366. package/templates/.gemini/commands/_project_/block-task.en.toml +0 -10
  367. package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +0 -10
  368. package/templates/.gemini/commands/_project_/cancel-task.en.toml +0 -10
  369. package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +0 -10
  370. package/templates/.gemini/commands/_project_/check-task.en.toml +0 -10
  371. package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +0 -10
  372. package/templates/.gemini/commands/_project_/close-codescan.en.toml +0 -8
  373. package/templates/.gemini/commands/_project_/close-codescan.zh-CN.toml +0 -8
  374. package/templates/.gemini/commands/_project_/close-dependabot.en.toml +0 -8
  375. package/templates/.gemini/commands/_project_/close-dependabot.zh-CN.toml +0 -8
  376. package/templates/.gemini/commands/_project_/code-task.en.toml +0 -10
  377. package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +0 -10
  378. package/templates/.gemini/commands/_project_/commit.en.toml +0 -10
  379. package/templates/.gemini/commands/_project_/commit.zh-CN.toml +0 -10
  380. package/templates/.gemini/commands/_project_/complete-manual-validation.en.toml +0 -10
  381. package/templates/.gemini/commands/_project_/complete-manual-validation.zh-CN.toml +0 -10
  382. package/templates/.gemini/commands/_project_/complete-task.en.toml +0 -10
  383. package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +0 -10
  384. package/templates/.gemini/commands/_project_/create-pr.en.toml +0 -10
  385. package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +0 -10
  386. package/templates/.gemini/commands/_project_/create-release-note.en.toml +0 -8
  387. package/templates/.gemini/commands/_project_/create-release-note.zh-CN.toml +0 -8
  388. package/templates/.gemini/commands/_project_/create-task.en.toml +0 -8
  389. package/templates/.gemini/commands/_project_/create-task.zh-CN.toml +0 -8
  390. package/templates/.gemini/commands/_project_/import-codescan.en.toml +0 -8
  391. package/templates/.gemini/commands/_project_/import-codescan.zh-CN.toml +0 -8
  392. package/templates/.gemini/commands/_project_/import-dependabot.en.toml +0 -8
  393. package/templates/.gemini/commands/_project_/import-dependabot.zh-CN.toml +0 -8
  394. package/templates/.gemini/commands/_project_/import-issue.en.toml +0 -8
  395. package/templates/.gemini/commands/_project_/import-issue.zh-CN.toml +0 -8
  396. package/templates/.gemini/commands/_project_/init-labels.en.toml +0 -8
  397. package/templates/.gemini/commands/_project_/init-labels.zh-CN.toml +0 -8
  398. package/templates/.gemini/commands/_project_/init-milestones.en.toml +0 -10
  399. package/templates/.gemini/commands/_project_/init-milestones.zh-CN.toml +0 -10
  400. package/templates/.gemini/commands/_project_/plan-task.en.toml +0 -10
  401. package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +0 -10
  402. package/templates/.gemini/commands/_project_/post-release.en.toml +0 -6
  403. package/templates/.gemini/commands/_project_/post-release.zh-CN.toml +0 -6
  404. package/templates/.gemini/commands/_project_/refine-title.en.toml +0 -8
  405. package/templates/.gemini/commands/_project_/refine-title.zh-CN.toml +0 -8
  406. package/templates/.gemini/commands/_project_/release.en.toml +0 -8
  407. package/templates/.gemini/commands/_project_/release.zh-CN.toml +0 -8
  408. package/templates/.gemini/commands/_project_/restore-task.en.toml +0 -8
  409. package/templates/.gemini/commands/_project_/restore-task.zh-CN.toml +0 -8
  410. package/templates/.gemini/commands/_project_/review-analysis.en.toml +0 -10
  411. package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +0 -10
  412. package/templates/.gemini/commands/_project_/review-code.en.toml +0 -10
  413. package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +0 -10
  414. package/templates/.gemini/commands/_project_/review-plan.en.toml +0 -10
  415. package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +0 -10
  416. package/templates/.gemini/commands/_project_/run-task.en.toml +0 -8
  417. package/templates/.gemini/commands/_project_/run-task.zh-CN.toml +0 -8
  418. package/templates/.gemini/commands/_project_/test-integration.en.toml +0 -6
  419. package/templates/.gemini/commands/_project_/test-integration.zh-CN.toml +0 -6
  420. package/templates/.gemini/commands/_project_/test.en.toml +0 -6
  421. package/templates/.gemini/commands/_project_/test.zh-CN.toml +0 -6
  422. package/templates/.gemini/commands/_project_/update-agent-infra.en.toml +0 -6
  423. package/templates/.gemini/commands/_project_/update-agent-infra.zh-CN.toml +0 -6
  424. package/templates/.gemini/commands/_project_/upgrade-dependency.en.toml +0 -8
  425. package/templates/.gemini/commands/_project_/upgrade-dependency.zh-CN.toml +0 -8
  426. package/templates/.gemini/commands/_project_/watch-pr.en.toml +0 -10
  427. package/templates/.gemini/commands/_project_/watch-pr.zh-CN.toml +0 -10
  428. package/templates/.gemini/settings.json +0 -3
@@ -0,0 +1,33 @@
1
+ import { sha256 } from './store.js';
2
+ const RULES = [
3
+ { id: 'private-key', pattern: /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/ },
4
+ { id: 'github-token', pattern: /\b(?:gh[opusr]_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,})\b/ },
5
+ { id: 'bearer-token', pattern: /\bBearer\s+[A-Za-z0-9._~+/=-]{16,}/i },
6
+ { id: 'aws-access-key', pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/ },
7
+ { id: 'slack-token', pattern: /\bxox[abprs]-[A-Za-z0-9-]{10,}\b/ },
8
+ { id: 'slack-webhook', pattern: /https:\/\/hooks\.slack\.com\/services\/[A-Za-z0-9/_-]{20,}/i },
9
+ { id: 'credential-field', pattern: /(?:api[_-]?key|password|secret)\s*[:=]\s*["']?[^\s"']{8,}/i }
10
+ ];
11
+ function inspectPrivacy(content) {
12
+ for (const rule of RULES) {
13
+ if (rule.pattern.test(content))
14
+ return { state: 'excluded-sensitive', ruleId: rule.id };
15
+ }
16
+ return { state: 'included' };
17
+ }
18
+ function captureText(sourceKind, sourceIdentity, content) {
19
+ const bytes = Buffer.byteLength(content);
20
+ const digest = sha256(Buffer.from(content, 'utf8'));
21
+ const disposition = inspectPrivacy(content);
22
+ return disposition.state === 'included'
23
+ ? { sourceKind, sourceIdentity, sha256: digest, bytes, content, disposition }
24
+ : { sourceKind, sourceIdentity, sha256: digest, bytes, disposition };
25
+ }
26
+ function redactExcerpt(content, maxBytes = 4096) {
27
+ if (inspectPrivacy(content).state !== 'included')
28
+ return null;
29
+ const buffer = Buffer.from(content, 'utf8');
30
+ return buffer.subarray(0, maxBytes).toString('utf8').replace(/\b(token|password|secret)=\S+/gi, '$1=[REDACTED]');
31
+ }
32
+ export { captureText, inspectPrivacy, redactExcerpt };
33
+ //# sourceMappingURL=privacy.js.map
@@ -0,0 +1,95 @@
1
+ import { sha256 } from './store.js';
2
+ function reconcileRecords(records, scope) {
3
+ const findings = [];
4
+ const repairs = [];
5
+ const findingKeys = new Set();
6
+ const addFinding = (category, severity, identities, repairable, reason) => {
7
+ const sortedIdentities = [...identities].sort();
8
+ const key = `${category}:${sortedIdentities.join('\0')}`;
9
+ if (findingKeys.has(key))
10
+ return;
11
+ findingKeys.add(key);
12
+ findings.push({
13
+ findingId: `quality:${sha256(key).slice(0, 20)}`,
14
+ category,
15
+ severity,
16
+ identities: sortedIdentities,
17
+ repairable,
18
+ reason
19
+ });
20
+ };
21
+ const byIdentity = new Map();
22
+ for (const record of records) {
23
+ const group = byIdentity.get(record.sourceIdentity) ?? [];
24
+ group.push(record);
25
+ byIdentity.set(record.sourceIdentity, group);
26
+ if (record.kind === 'missing' &&
27
+ record.data !== null &&
28
+ typeof record.data === 'object' &&
29
+ !Array.isArray(record.data) &&
30
+ record.data.reason === 'privacy-excluded') {
31
+ addFinding('privacy-excluded', 'warning', [record.sourceIdentity], false, 'Sensitive content was excluded by policy');
32
+ }
33
+ else if (record.kind === 'missing') {
34
+ addFinding('unrecoverable', 'info', [record.sourceIdentity], false, 'Source body is unavailable under the capture policy');
35
+ }
36
+ }
37
+ for (const [identity, group] of byIdentity) {
38
+ if (group.length < 2)
39
+ continue;
40
+ addFinding('duplicate-identity', 'error', group.map((record) => record.recordId), false, 'Multiple records claim the same stable identity');
41
+ if (group.some((record) => record.kind === 'platform-resource') && new Set(group.map((record) => record.sourceSha256)).size > 1) {
42
+ addFinding('mutable-remote', 'warning', group.map((record) => record.recordId), false, `Remote identity changed content: ${identity}`);
43
+ }
44
+ }
45
+ const tasks = records.filter((record) => record.kind === 'task');
46
+ const resources = records.filter((record) => record.kind === 'platform-resource');
47
+ const taskByIdentity = new Map(tasks.map((task) => [task.sourceIdentity, task]));
48
+ for (const task of tasks) {
49
+ const data = task.data && typeof task.data === 'object' && !Array.isArray(task.data) ? task.data : null;
50
+ const version = data?.agentInfraVersion;
51
+ if (!version || typeof version !== 'object' || Array.isArray(version) || version.state !== 'known') {
52
+ addFinding('schema-difference', 'info', [task.recordId], false, 'Task uses a legacy schema without a known agent_infra_version');
53
+ }
54
+ if (scope !== 'all' || !task.binding)
55
+ continue;
56
+ const identityCandidates = resources.filter((record) => record.sourceIdentity === task.binding);
57
+ if (identityCandidates.length === 0) {
58
+ addFinding('missing-remote', 'error', [task.recordId, task.binding], false, 'Task binding has no captured platform resource');
59
+ }
60
+ if (identityCandidates.length > 1) {
61
+ addFinding('binding-conflict', 'error', [task.recordId, ...identityCandidates.map((record) => record.recordId)], false, 'Multiple platform resources bind to one task');
62
+ }
63
+ for (const remote of identityCandidates) {
64
+ if (remote.binding && remote.binding !== task.sourceIdentity) {
65
+ addFinding('content-mismatch', 'warning', [task.recordId, remote.recordId], false, 'Local and remote binding identities disagree');
66
+ }
67
+ }
68
+ const candidates = identityCandidates.filter((record) => record.binding === task.sourceIdentity);
69
+ if (candidates.length === 1 && (byIdentity.get(candidates[0].sourceIdentity)?.length ?? 0) === 1) {
70
+ const target = candidates[0];
71
+ repairs.push({
72
+ repairId: `repair:${sha256(`${task.recordId}:${target.recordId}`).slice(0, 20)}`,
73
+ operation: 'link',
74
+ sourceRecordId: task.recordId,
75
+ targetRecordId: target.recordId,
76
+ preconditionSha256: sha256(`${task.sourceSha256}:${target.sourceSha256}`)
77
+ });
78
+ }
79
+ }
80
+ for (const resource of scope === 'all' ? resources : []) {
81
+ if (resource.binding?.startsWith('TASK-') && !taskByIdentity.has(resource.binding)) {
82
+ addFinding('missing-local', 'error', [resource.recordId, resource.binding], false, 'Platform resource binds to a task that is not captured locally');
83
+ }
84
+ const localClaims = tasks.filter((task) => task.binding === resource.sourceIdentity);
85
+ if (localClaims.length > 1 || (resource.binding && localClaims.length > 0 && !localClaims.some((task) => task.sourceIdentity === resource.binding))) {
86
+ addFinding('binding-conflict', 'error', [resource.recordId, ...localClaims.map((task) => task.recordId)], false, 'Local and remote records claim incompatible bindings');
87
+ }
88
+ }
89
+ return {
90
+ findings: findings.sort((left, right) => left.findingId.localeCompare(right.findingId)),
91
+ repairs: repairs.sort((left, right) => left.repairId.localeCompare(right.repairId))
92
+ };
93
+ }
94
+ export { reconcileRecords };
95
+ //# sourceMappingURL=reconcile.js.map
@@ -0,0 +1,58 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { canonicalJsonBytes, sha256, verifySnapshot } from './store.js';
4
+ function readRepairActions(snapshotPath) {
5
+ const filePath = path.join(snapshotPath, 'repair-manifest.jsonl');
6
+ if (!fs.existsSync(filePath))
7
+ return [];
8
+ return fs.readFileSync(filePath, 'utf8').split('\n').filter(Boolean).map((line) => {
9
+ const { schema: _schema, ...action } = JSON.parse(line);
10
+ return action;
11
+ });
12
+ }
13
+ function repairSnapshot(root, snapshotId, apply) {
14
+ const verified = verifySnapshot(root, snapshotId);
15
+ if (!verified.ok || !verified.snapshotPath)
16
+ throw new Error(`snapshot verification failed: ${verified.errors.join('; ')}`);
17
+ const actions = readRepairActions(verified.snapshotPath);
18
+ const records = new Map(fs.readFileSync(path.join(verified.snapshotPath, 'normalized.jsonl'), 'utf8').split('\n').filter(Boolean).map((line) => {
19
+ const record = JSON.parse(line);
20
+ return [record.recordId, record];
21
+ }));
22
+ for (const action of actions) {
23
+ const source = records.get(action.sourceRecordId);
24
+ const target = records.get(action.targetRecordId);
25
+ if (!source || !target)
26
+ throw new Error(`repair references a missing record: ${action.repairId}`);
27
+ if (sha256(`${source.sourceSha256}:${target.sourceSha256}`) !== action.preconditionSha256) {
28
+ throw new Error(`repair precondition failed: ${action.repairId}`);
29
+ }
30
+ }
31
+ if (!apply || actions.length === 0)
32
+ return { applied: false, repairId: null, actionCount: actions.length };
33
+ const digest = sha256(canonicalJsonBytes(actions));
34
+ const repairId = `repair-${digest.slice(0, 16)}`;
35
+ const repairDir = path.join(root, 'repairs', snapshotId, repairId);
36
+ const manifest = `${canonicalJsonBytes({ schema: 'repair-application/v1', snapshotId, repairId, actionCount: actions.length, overlaySha256: digest }).toString('utf8')}\n`;
37
+ const overlay = actions.map((action) => `${canonicalJsonBytes({ schema: 'normalized-overlay/v1', ...action }).toString('utf8')}\n`).join('');
38
+ if (fs.existsSync(repairDir)) {
39
+ if (fs.readFileSync(path.join(repairDir, 'manifest.json'), 'utf8') !== manifest)
40
+ throw new Error(`repair collision: ${repairId}`);
41
+ return { applied: false, repairId, actionCount: actions.length, path: repairDir };
42
+ }
43
+ fs.mkdirSync(repairDir, { recursive: true, mode: 0o700 });
44
+ fs.writeFileSync(path.join(repairDir, 'manifest.json'), manifest, { mode: 0o600, flag: 'wx' });
45
+ fs.writeFileSync(path.join(repairDir, 'overlay.jsonl'), overlay, { mode: 0o600, flag: 'wx' });
46
+ return { applied: true, repairId, actionCount: actions.length, path: repairDir };
47
+ }
48
+ function readAppliedOverlays(root, snapshotId) {
49
+ const base = path.join(root, 'repairs', snapshotId);
50
+ if (!fs.existsSync(base))
51
+ return '';
52
+ return fs.readdirSync(base).sort().map((entry) => {
53
+ const overlay = path.join(base, entry, 'overlay.jsonl');
54
+ return fs.existsSync(overlay) ? fs.readFileSync(overlay, 'utf8') : '';
55
+ }).join('');
56
+ }
57
+ export { readAppliedOverlays, repairSnapshot };
58
+ //# sourceMappingURL=repair.js.map
@@ -0,0 +1,345 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createGitHubClient } from '../platform/github-client.js';
4
+ import { enumerateAllTaskDirs } from '../task/resolve-ref.js';
5
+ import { captureText, inspectPrivacy, redactExcerpt } from './privacy.js';
6
+ import { canonicalJsonBytes, sha256 } from './store.js';
7
+ function endpointForPage(endpoint, page, perPage) {
8
+ const parsed = new URL(endpoint, 'https://api.github.invalid/');
9
+ if (parsed.searchParams.has('page') || parsed.searchParams.has('per_page')) {
10
+ throw new Error('endpoint must not predefine page or per_page');
11
+ }
12
+ parsed.searchParams.set('per_page', String(perPage));
13
+ parsed.searchParams.set('page', String(page));
14
+ return `${parsed.pathname.replace(/^\//, '')}${parsed.search}`;
15
+ }
16
+ function fetchRestCollection(options) {
17
+ const perPage = options.perPage ?? 100;
18
+ if (!Number.isInteger(perPage) || perPage < 1 || perPage > 100) {
19
+ return { ok: false, error: { code: 'PAGINATION_INVALID', message: 'perPage must be between 1 and 100' } };
20
+ }
21
+ let pageIndex = 1;
22
+ let previousHash = null;
23
+ const identities = new Set();
24
+ const items = [];
25
+ const pages = [];
26
+ while (true) {
27
+ let url;
28
+ try {
29
+ url = endpointForPage(options.endpoint, pageIndex, perPage);
30
+ }
31
+ catch (error) {
32
+ return { ok: false, error: { code: 'PAGINATION_INVALID', message: String(error) } };
33
+ }
34
+ const response = options.client.json(['api', url]);
35
+ if (!response.ok)
36
+ return { ok: false, error: response.error };
37
+ if (!Array.isArray(response.value) || response.value.length > perPage) {
38
+ return {
39
+ ok: false,
40
+ error: { code: 'INVALID_PLATFORM_RESPONSE', message: `GitHub page ${pageIndex} is not a valid array page` }
41
+ };
42
+ }
43
+ let selected;
44
+ try {
45
+ selected = response.value.map((entry) => options.select ? options.select(entry) : entry);
46
+ }
47
+ catch (error) {
48
+ return { ok: false, error: { code: 'INVALID_PLATFORM_RESPONSE', message: String(error) } };
49
+ }
50
+ let bytes;
51
+ try {
52
+ bytes = canonicalJsonBytes(selected);
53
+ }
54
+ catch (error) {
55
+ return { ok: false, error: { code: 'INVALID_PLATFORM_RESPONSE', message: String(error) } };
56
+ }
57
+ const canonicalSha256 = sha256(bytes);
58
+ if (previousHash === canonicalSha256 && response.value.length > 0) {
59
+ return {
60
+ ok: false,
61
+ error: { code: 'PAGINATION_UNSTABLE', message: `GitHub page ${pageIndex} repeats the previous page` }
62
+ };
63
+ }
64
+ for (const entry of selected) {
65
+ const identity = options.identify(entry);
66
+ if (!identity || identities.has(identity)) {
67
+ return {
68
+ ok: false,
69
+ error: { code: 'PAGINATION_UNSTABLE', message: `duplicate or empty identity on page ${pageIndex}` }
70
+ };
71
+ }
72
+ identities.add(identity);
73
+ items.push(entry);
74
+ }
75
+ pages.push({ evidence: { index: pageIndex, itemCount: response.value.length, canonicalSha256 }, bytes });
76
+ previousHash = canonicalSha256;
77
+ if (response.value.length < perPage)
78
+ break;
79
+ pageIndex += 1;
80
+ }
81
+ const evidence = {
82
+ endpoint: options.endpoint,
83
+ requestCount: pages.length,
84
+ dataPageCount: pages.filter((page) => page.evidence.itemCount > 0).length,
85
+ itemCount: items.length,
86
+ termination: 'short-page',
87
+ pages: pages.map((page) => page.evidence)
88
+ };
89
+ return {
90
+ ok: true,
91
+ value: {
92
+ items,
93
+ evidence,
94
+ pageObjects: pages.map((page) => ({
95
+ sourceKind: 'github-rest',
96
+ sourceIdentity: `${options.endpoint}#page=${page.evidence.index}`,
97
+ sha256: page.evidence.canonicalSha256,
98
+ bytes: page.bytes.length,
99
+ content: page.bytes.toString('utf8'),
100
+ disposition: { state: 'included' }
101
+ }))
102
+ }
103
+ };
104
+ }
105
+ function relativeIdentity(repoRoot, filePath) {
106
+ const relative = path.relative(repoRoot, filePath);
107
+ if (!relative || relative.startsWith('..') || path.isAbsolute(relative))
108
+ throw new Error(`path escapes repository: ${filePath}`);
109
+ return relative.split(path.sep).join('/');
110
+ }
111
+ function readStableFile(repoRoot, filePath, sourceKind) {
112
+ const before = fs.lstatSync(filePath);
113
+ if (!before.isFile() || before.isSymbolicLink())
114
+ throw new Error(`unsafe source file: ${filePath}`);
115
+ const content = fs.readFileSync(filePath, 'utf8');
116
+ const after = fs.lstatSync(filePath);
117
+ if (before.dev !== after.dev || before.ino !== after.ino || before.size !== after.size || before.mtimeMs !== after.mtimeMs) {
118
+ throw new Error(`source changed while reading: ${filePath}`);
119
+ }
120
+ return captureText(sourceKind, relativeIdentity(repoRoot, filePath), content);
121
+ }
122
+ function listFiles(directory) {
123
+ if (!fs.existsSync(directory))
124
+ return [];
125
+ const output = [];
126
+ const walk = (current) => {
127
+ for (const entry of fs.readdirSync(current, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
128
+ const candidate = path.join(current, entry.name);
129
+ if (entry.isSymbolicLink())
130
+ throw new Error(`symlink source is not allowed: ${candidate}`);
131
+ if (entry.isDirectory())
132
+ walk(candidate);
133
+ else if (entry.isFile())
134
+ output.push(candidate);
135
+ }
136
+ };
137
+ walk(directory);
138
+ return output;
139
+ }
140
+ function structuredReceipt(repoRoot, filePath) {
141
+ const raw = readStableFile(repoRoot, filePath, 'structured-telemetry');
142
+ if (!raw.content)
143
+ return raw;
144
+ try {
145
+ const parsed = JSON.parse(raw.content);
146
+ const fields = ['client', 'model', 'reasoning', 'stage', 'toolCategory', 'time', 'status', 'retry', 'error', 'fallback'];
147
+ const selected = Object.fromEntries(fields.filter((field) => parsed[field] !== undefined).map((field) => [field, jsonClone(parsed[field])]));
148
+ selected.sourceSha256 = raw.sha256;
149
+ return captureText('structured-telemetry', raw.sourceIdentity, canonicalJsonBytes(selected).toString('utf8'));
150
+ }
151
+ catch {
152
+ return { ...raw, content: undefined, disposition: { state: 'unavailable', reason: 'invalid receipt JSON' } };
153
+ }
154
+ }
155
+ function unavailableLog(repoRoot, filePath, includeExcerpts) {
156
+ const raw = readStableFile(repoRoot, filePath, 'local-file');
157
+ if (raw.disposition?.state === 'excluded-sensitive')
158
+ return raw;
159
+ const recognizedBody = /\/(?:sessions?|tools?)(?:\/|[-_])/i.test(raw.sourceIdentity);
160
+ if (includeExcerpts && recognizedBody && raw.content) {
161
+ const excerpt = redactExcerpt(raw.content);
162
+ if (excerpt !== null)
163
+ return captureText('local-file', `${raw.sourceIdentity}#excerpt`, excerpt);
164
+ }
165
+ return {
166
+ sourceKind: 'local-file',
167
+ sourceIdentity: raw.sourceIdentity,
168
+ sha256: raw.sha256,
169
+ bytes: raw.bytes,
170
+ disposition: { state: 'unavailable', reason: recognizedBody ? 'body-excerpts-disabled' : 'unknown-log-format' }
171
+ };
172
+ }
173
+ function collectLocalObjects(repoRoot, options = {}) {
174
+ try {
175
+ const objects = [];
176
+ for (const task of enumerateAllTaskDirs(repoRoot)) {
177
+ for (const filePath of listFiles(task.taskDir)) {
178
+ if (!/\.(?:md|json)$/i.test(filePath))
179
+ continue;
180
+ objects.push(readStableFile(repoRoot, filePath, 'local-file'));
181
+ }
182
+ }
183
+ const logsRoot = path.join(repoRoot, '.agents', 'workspace', 'logs');
184
+ for (const filePath of listFiles(logsRoot)) {
185
+ if (!/\.(?:md|json)$/i.test(filePath))
186
+ continue;
187
+ const identity = relativeIdentity(repoRoot, filePath);
188
+ if (/\/entropy-check\/.*\.md$/i.test(identity)) {
189
+ objects.push(readStableFile(repoRoot, filePath, 'operational-report'));
190
+ }
191
+ else if (/\/(?:delegation|orchestration)(?:\/|[-_]).*\.json$/i.test(identity)) {
192
+ objects.push(structuredReceipt(repoRoot, filePath));
193
+ }
194
+ else {
195
+ objects.push(unavailableLog(repoRoot, filePath, options.includeExcerpts === true));
196
+ }
197
+ }
198
+ return { ok: true, value: objects.sort((a, b) => a.sourceIdentity.localeCompare(b.sourceIdentity)) };
199
+ }
200
+ catch (error) {
201
+ return { ok: false, error: { code: 'LOCAL_SOURCE_UNSTABLE', message: error instanceof Error ? error.message : String(error) } };
202
+ }
203
+ }
204
+ function githubIdentity(item) {
205
+ if (!item || typeof item !== 'object')
206
+ return '';
207
+ const record = item;
208
+ for (const key of ['id', 'node_id', 'sha', 'number']) {
209
+ if (typeof record[key] === 'string' || typeof record[key] === 'number')
210
+ return `${key}:${String(record[key])}`;
211
+ }
212
+ return '';
213
+ }
214
+ function jsonClone(value) {
215
+ return JSON.parse(JSON.stringify(value));
216
+ }
217
+ function projectFields(value, fields) {
218
+ if (!value || typeof value !== 'object' || Array.isArray(value))
219
+ return undefined;
220
+ const record = value;
221
+ return Object.fromEntries(fields.filter((field) => record[field] !== undefined).map((field) => [field, jsonClone(record[field])]));
222
+ }
223
+ function projectSensitiveText(value) {
224
+ if (typeof value !== 'string')
225
+ return undefined;
226
+ const disposition = inspectPrivacy(value);
227
+ return disposition.state === 'included'
228
+ ? value
229
+ : { state: 'unavailable', reason: 'privacy-excluded', ruleId: disposition.ruleId, sha256: sha256(value) };
230
+ }
231
+ function projectGitHubItem(item) {
232
+ if (!item || typeof item !== 'object' || Array.isArray(item))
233
+ throw new Error('GitHub item must be an object');
234
+ const source = item;
235
+ const output = {};
236
+ const scalarFields = [
237
+ 'id', 'node_id', 'number', 'html_url', 'url', 'state', 'title', 'created_at', 'updated_at', 'closed_at',
238
+ 'merged_at', 'review_state', 'commit_id', 'sha', 'merge_commit_sha', 'milestone'
239
+ ];
240
+ for (const field of scalarFields) {
241
+ if (source[field] !== undefined)
242
+ output[field] = jsonClone(source[field]);
243
+ }
244
+ for (const field of ['user', 'head', 'base', 'author', 'committer']) {
245
+ const projected = projectFields(source[field], ['id', 'login', 'sha', 'ref']);
246
+ if (projected)
247
+ output[field] = projected;
248
+ }
249
+ for (const field of ['labels', 'assignees']) {
250
+ if (Array.isArray(source[field]))
251
+ output[field] = jsonClone(source[field]);
252
+ }
253
+ for (const field of ['body', 'message']) {
254
+ const projected = projectSensitiveText(source[field]);
255
+ if (projected !== undefined)
256
+ output[field] = projected;
257
+ }
258
+ if (Array.isArray(source.parents)) {
259
+ output.parents = source.parents.flatMap((parent) => {
260
+ const projected = projectFields(parent, ['sha']);
261
+ return projected ? [projected] : [];
262
+ });
263
+ }
264
+ const commit = projectFields(source.commit, []);
265
+ if (commit) {
266
+ const sourceCommit = source.commit;
267
+ const projectedCommit = {};
268
+ const message = projectSensitiveText(sourceCommit.message);
269
+ if (message !== undefined)
270
+ projectedCommit.message = message;
271
+ const tree = projectFields(sourceCommit.tree, ['sha']);
272
+ if (tree)
273
+ projectedCommit.tree = tree;
274
+ for (const field of ['author', 'committer']) {
275
+ const actor = projectFields(sourceCommit[field], ['name', 'email', 'date']);
276
+ if (actor)
277
+ projectedCommit[field] = actor;
278
+ }
279
+ output.commit = projectedCommit;
280
+ }
281
+ return output;
282
+ }
283
+ function collectGitHubObjects(repoRoot, client = createGitHubClient()) {
284
+ const repoResult = client.json(['repo', 'view', '--json', 'nameWithOwner'], { cwd: repoRoot });
285
+ if (!repoResult.ok)
286
+ return { ok: false, error: repoResult.error };
287
+ const repository = repoResult.value.nameWithOwner;
288
+ if (!repository || !/^[^/]+\/[^/]+$/.test(repository)) {
289
+ return { ok: false, error: { code: 'INVALID_PLATFORM_RESPONSE', message: 'GitHub repository identity is missing' } };
290
+ }
291
+ const objects = [];
292
+ const evidence = [];
293
+ const captureEndpoint = (endpoint) => {
294
+ const result = fetchRestCollection({
295
+ client,
296
+ endpoint,
297
+ identify: githubIdentity,
298
+ select: (item) => projectGitHubItem(item)
299
+ });
300
+ if (!result.ok)
301
+ return result;
302
+ objects.push(...result.value.pageObjects);
303
+ evidence.push(result.value.evidence);
304
+ return result;
305
+ };
306
+ const issues = captureEndpoint(`repos/${repository}/issues?state=all&sort=created&direction=asc`);
307
+ if (!issues.ok)
308
+ return issues;
309
+ const pulls = captureEndpoint(`repos/${repository}/pulls?state=all&sort=created&direction=asc`);
310
+ if (!pulls.ok)
311
+ return pulls;
312
+ for (const issue of issues.value.items) {
313
+ const number = issue.number;
314
+ if (typeof number !== 'number')
315
+ return { ok: false, error: { code: 'INVALID_PLATFORM_RESPONSE', message: 'Issue number is missing' } };
316
+ const comments = captureEndpoint(`repos/${repository}/issues/${number}/comments`);
317
+ if (!comments.ok)
318
+ return comments;
319
+ }
320
+ for (const pull of pulls.value.items) {
321
+ const record = pull;
322
+ const number = record.number;
323
+ const head = record.head;
324
+ const headSha = head?.sha;
325
+ if (typeof number !== 'number' || typeof headSha !== 'string') {
326
+ return { ok: false, error: { code: 'INVALID_PLATFORM_RESPONSE', message: 'Pull request identity or head SHA is missing' } };
327
+ }
328
+ for (const suffix of ['comments', 'reviews', 'commits']) {
329
+ const nested = captureEndpoint(`repos/${repository}/pulls/${number}/${suffix}`);
330
+ if (!nested.ok)
331
+ return nested;
332
+ }
333
+ const current = client.json(['api', `repos/${repository}/pulls/${number}`]);
334
+ if (!current.ok)
335
+ return { ok: false, error: current.error };
336
+ const projected = projectGitHubItem(current.value);
337
+ const currentHead = projected.head;
338
+ if (currentHead?.sha !== headSha) {
339
+ return { ok: false, error: { code: 'SOURCE_DRIFT', message: `Pull request ${number} head changed during capture` } };
340
+ }
341
+ }
342
+ return { ok: true, value: { repository, objects, endpoints: evidence } };
343
+ }
344
+ export { collectGitHubObjects, collectLocalObjects, fetchRestCollection, projectGitHubItem };
345
+ //# sourceMappingURL=sources.js.map