agentplane 0.3.8 → 0.3.10

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 (268) hide show
  1. package/assets/AGENTS.md +4 -2
  2. package/assets/agents/CODER.json +1 -1
  3. package/assets/policy/dod.core.md +1 -1
  4. package/assets/policy/governance.md +3 -0
  5. package/assets/policy/incidents.md +22 -11
  6. package/assets/policy/workflow.branch_pr.md +2 -0
  7. package/assets/policy/workflow.direct.md +3 -1
  8. package/dist/.build-manifest.json +323 -128
  9. package/dist/cli/bootstrap-guide.d.ts +1 -0
  10. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  11. package/dist/cli/bootstrap-guide.js +19 -1
  12. package/dist/cli/command-invocations.d.ts.map +1 -1
  13. package/dist/cli/command-invocations.js +2 -0
  14. package/dist/cli/command-snippets.d.ts +2 -0
  15. package/dist/cli/command-snippets.d.ts.map +1 -1
  16. package/dist/cli/command-snippets.js +2 -0
  17. package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
  18. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
  19. package/dist/cli/run-cli/command-catalog/core.js +10 -0
  20. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  21. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  22. package/dist/cli/run-cli/commands/config.d.ts.map +1 -1
  23. package/dist/cli/run-cli/commands/config.js +13 -0
  24. package/dist/cli/run-cli.js +2 -2
  25. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  26. package/dist/cli/run-cli.test-helpers.js +34 -8
  27. package/dist/commands/backend.d.ts.map +1 -1
  28. package/dist/commands/backend.js +4 -0
  29. package/dist/commands/hooks/index.d.ts.map +1 -1
  30. package/dist/commands/hooks/index.js +8 -4
  31. package/dist/commands/incidents/advise.command.d.ts +15 -0
  32. package/dist/commands/incidents/advise.command.d.ts.map +1 -0
  33. package/dist/commands/incidents/advise.command.js +139 -0
  34. package/dist/commands/incidents/collect.command.d.ts +11 -0
  35. package/dist/commands/incidents/collect.command.d.ts.map +1 -0
  36. package/dist/commands/incidents/collect.command.js +67 -0
  37. package/dist/commands/incidents/incidents.command.d.ts +5 -0
  38. package/dist/commands/incidents/incidents.command.d.ts.map +1 -0
  39. package/dist/commands/incidents/incidents.command.js +21 -0
  40. package/dist/commands/incidents/shared.d.ts +42 -0
  41. package/dist/commands/incidents/shared.d.ts.map +1 -0
  42. package/dist/commands/incidents/shared.js +107 -0
  43. package/dist/commands/pr/check.d.ts.map +1 -1
  44. package/dist/commands/pr/check.js +73 -2
  45. package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
  46. package/dist/commands/pr/integrate/cmd.js +4 -0
  47. package/dist/commands/pr/integrate/internal/merge.d.ts +4 -0
  48. package/dist/commands/pr/integrate/internal/merge.d.ts.map +1 -1
  49. package/dist/commands/pr/integrate/internal/merge.js +23 -2
  50. package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
  51. package/dist/commands/pr/integrate/internal/prepare.js +26 -1
  52. package/dist/commands/pr/internal/note-store.d.ts +18 -0
  53. package/dist/commands/pr/internal/note-store.d.ts.map +1 -0
  54. package/dist/commands/pr/internal/note-store.js +66 -0
  55. package/dist/commands/pr/internal/pr-paths.d.ts +3 -0
  56. package/dist/commands/pr/internal/pr-paths.d.ts.map +1 -1
  57. package/dist/commands/pr/internal/pr-paths.js +3 -0
  58. package/dist/commands/pr/internal/review-template.d.ts +24 -4
  59. package/dist/commands/pr/internal/review-template.d.ts.map +1 -1
  60. package/dist/commands/pr/internal/review-template.js +188 -33
  61. package/dist/commands/pr/internal/sync.d.ts +32 -0
  62. package/dist/commands/pr/internal/sync.d.ts.map +1 -0
  63. package/dist/commands/pr/internal/sync.js +258 -0
  64. package/dist/commands/pr/note.d.ts.map +1 -1
  65. package/dist/commands/pr/note.js +37 -4
  66. package/dist/commands/pr/open.d.ts.map +1 -1
  67. package/dist/commands/pr/open.js +7 -54
  68. package/dist/commands/pr/pr.command.d.ts.map +1 -1
  69. package/dist/commands/pr/pr.command.js +6 -3
  70. package/dist/commands/pr/update.d.ts.map +1 -1
  71. package/dist/commands/pr/update.js +5 -79
  72. package/dist/commands/recipes/impl/apply.d.ts +1 -1
  73. package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
  74. package/dist/commands/recipes/impl/apply.js +1 -1
  75. package/dist/commands/recipes/impl/commands/cache-prune.d.ts.map +1 -1
  76. package/dist/commands/recipes/impl/commands/cache-prune.js +14 -0
  77. package/dist/commands/recipes/impl/commands/explain.js +1 -1
  78. package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
  79. package/dist/commands/recipes/impl/commands/install.js +3 -2
  80. package/dist/commands/recipes/impl/commands/list-remote.d.ts.map +1 -1
  81. package/dist/commands/recipes/impl/commands/list-remote.js +1 -0
  82. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  83. package/dist/commands/recipes/impl/commands/remove.js +9 -1
  84. package/dist/commands/recipes/impl/installed-recipes.d.ts +1 -1
  85. package/dist/commands/recipes/impl/installed-recipes.d.ts.map +1 -1
  86. package/dist/commands/recipes/impl/installed-recipes.js +2 -1
  87. package/dist/commands/recipes/impl/project-installed-recipes.d.ts +1 -1
  88. package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -1
  89. package/dist/commands/recipes/impl/project-installed-recipes.js +2 -1
  90. package/dist/commands/recipes/impl/resolver.d.ts +1 -1
  91. package/dist/commands/recipes/impl/resolver.d.ts.map +1 -1
  92. package/dist/commands/recipes/impl/resolver.js +1 -1
  93. package/dist/commands/recipes.d.ts +4 -4
  94. package/dist/commands/recipes.d.ts.map +1 -1
  95. package/dist/commands/recipes.js +3 -3
  96. package/dist/commands/release/apply.command.d.ts.map +1 -1
  97. package/dist/commands/release/apply.command.js +9 -0
  98. package/dist/commands/release.test-helpers.d.ts +14 -0
  99. package/dist/commands/release.test-helpers.d.ts.map +1 -1
  100. package/dist/commands/release.test-helpers.js +14 -3
  101. package/dist/commands/shared/approval-requirements.d.ts +5 -7
  102. package/dist/commands/shared/approval-requirements.d.ts.map +1 -1
  103. package/dist/commands/shared/approval-requirements.js +3 -73
  104. package/dist/commands/shared/network-approval.d.ts +2 -0
  105. package/dist/commands/shared/network-approval.d.ts.map +1 -1
  106. package/dist/commands/shared/network-approval.js +1 -1
  107. package/dist/commands/shared/pr-meta.d.ts +9 -0
  108. package/dist/commands/shared/pr-meta.d.ts.map +1 -1
  109. package/dist/commands/shared/pr-meta.js +27 -3
  110. package/dist/commands/shared/task-backend.d.ts +2 -0
  111. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  112. package/dist/commands/shared/task-local-freshness.d.ts +13 -0
  113. package/dist/commands/shared/task-local-freshness.d.ts.map +1 -0
  114. package/dist/commands/shared/task-local-freshness.js +20 -0
  115. package/dist/commands/shared/task-mutation.d.ts +2 -0
  116. package/dist/commands/shared/task-mutation.d.ts.map +1 -1
  117. package/dist/commands/shared/task-mutation.js +7 -0
  118. package/dist/commands/task/block.d.ts.map +1 -1
  119. package/dist/commands/task/block.js +1 -0
  120. package/dist/commands/task/close-shared.d.ts.map +1 -1
  121. package/dist/commands/task/close-shared.js +1 -0
  122. package/dist/commands/task/finish-shared.d.ts.map +1 -1
  123. package/dist/commands/task/finish-shared.js +5 -2
  124. package/dist/commands/task/finish.d.ts.map +1 -1
  125. package/dist/commands/task/finish.js +24 -0
  126. package/dist/commands/task/new.d.ts.map +1 -1
  127. package/dist/commands/task/new.js +69 -29
  128. package/dist/commands/task/set-status.d.ts.map +1 -1
  129. package/dist/commands/task/set-status.js +1 -0
  130. package/dist/commands/task/shared/transition-command.d.ts +2 -0
  131. package/dist/commands/task/shared/transition-command.d.ts.map +1 -1
  132. package/dist/commands/task/shared/transition-command.js +1 -0
  133. package/dist/commands/task/start-ready.d.ts.map +1 -1
  134. package/dist/commands/task/start-ready.js +12 -1
  135. package/dist/commands/task/start.d.ts.map +1 -1
  136. package/dist/commands/task/start.js +11 -0
  137. package/dist/commands/task/verify-record.d.ts.map +1 -1
  138. package/dist/commands/task/verify-record.js +27 -0
  139. package/dist/commands/upgrade.d.ts.map +1 -1
  140. package/dist/commands/upgrade.js +6 -1
  141. package/dist/policy/engine.d.ts +3 -1
  142. package/dist/policy/engine.d.ts.map +1 -1
  143. package/dist/policy/engine.js +5 -6
  144. package/dist/policy/taxonomy.d.ts +17 -0
  145. package/dist/policy/taxonomy.d.ts.map +1 -0
  146. package/dist/policy/taxonomy.js +302 -0
  147. package/dist/policy/types.d.ts +2 -1
  148. package/dist/policy/types.d.ts.map +1 -1
  149. package/dist/runner/artifacts.d.ts.map +1 -1
  150. package/dist/runner/artifacts.js +2 -0
  151. package/dist/runner/context/base-prompts.d.ts +25 -0
  152. package/dist/runner/context/base-prompts.d.ts.map +1 -1
  153. package/dist/runner/context/base-prompts.js +182 -54
  154. package/dist/runner/context/recipe-context.d.ts.map +1 -1
  155. package/dist/runner/context/recipe-context.js +5 -0
  156. package/dist/runner/types.d.ts +12 -0
  157. package/dist/runner/types.d.ts.map +1 -1
  158. package/dist/runner/usecases/scenario-materialize-task.d.ts.map +1 -1
  159. package/dist/runner/usecases/scenario-materialize-task.js +81 -11
  160. package/dist/runner/usecases/task-run-inspect.d.ts.map +1 -1
  161. package/dist/runner/usecases/task-run-inspect.js +9 -7
  162. package/dist/runner/usecases/task-run-lifecycle-shared.d.ts.map +1 -1
  163. package/dist/runner/usecases/task-run-lifecycle-shared.js +8 -6
  164. package/dist/runner/usecases/task-run.d.ts.map +1 -1
  165. package/dist/runner/usecases/task-run.js +59 -12
  166. package/dist/runtime/approvals/index.d.ts +3 -0
  167. package/dist/runtime/approvals/index.d.ts.map +1 -0
  168. package/dist/runtime/approvals/index.js +1 -0
  169. package/dist/runtime/approvals/runtime.d.ts +12 -0
  170. package/dist/runtime/approvals/runtime.d.ts.map +1 -0
  171. package/dist/runtime/approvals/runtime.js +154 -0
  172. package/dist/runtime/approvals/types.d.ts +31 -0
  173. package/dist/runtime/approvals/types.d.ts.map +1 -0
  174. package/dist/runtime/approvals/types.js +1 -0
  175. package/dist/runtime/behavior/index.d.ts +3 -0
  176. package/dist/runtime/behavior/index.d.ts.map +1 -0
  177. package/dist/runtime/behavior/index.js +1 -0
  178. package/dist/runtime/behavior/resolve.d.ts +7 -0
  179. package/dist/runtime/behavior/resolve.d.ts.map +1 -0
  180. package/dist/runtime/behavior/resolve.js +66 -0
  181. package/dist/runtime/behavior/types.d.ts +25 -0
  182. package/dist/runtime/behavior/types.d.ts.map +1 -0
  183. package/dist/runtime/behavior/types.js +1 -0
  184. package/dist/runtime/capabilities/backend.d.ts +7 -0
  185. package/dist/runtime/capabilities/backend.d.ts.map +1 -0
  186. package/dist/runtime/capabilities/backend.js +104 -0
  187. package/dist/runtime/capabilities/index.d.ts +6 -0
  188. package/dist/runtime/capabilities/index.d.ts.map +1 -0
  189. package/dist/runtime/capabilities/index.js +4 -0
  190. package/dist/runtime/capabilities/recipe.d.ts +10 -0
  191. package/dist/runtime/capabilities/recipe.d.ts.map +1 -0
  192. package/dist/runtime/capabilities/recipe.js +123 -0
  193. package/dist/runtime/capabilities/registry.d.ts +6 -0
  194. package/dist/runtime/capabilities/registry.d.ts.map +1 -0
  195. package/dist/runtime/capabilities/registry.js +69 -0
  196. package/dist/runtime/capabilities/runner.d.ts +8 -0
  197. package/dist/runtime/capabilities/runner.d.ts.map +1 -0
  198. package/dist/runtime/capabilities/runner.js +73 -0
  199. package/dist/runtime/capabilities/types.d.ts +28 -0
  200. package/dist/runtime/capabilities/types.d.ts.map +1 -0
  201. package/dist/runtime/capabilities/types.js +1 -0
  202. package/dist/runtime/execution-profile/index.d.ts +3 -0
  203. package/dist/runtime/execution-profile/index.d.ts.map +1 -0
  204. package/dist/runtime/execution-profile/index.js +1 -0
  205. package/dist/runtime/execution-profile/resolve.d.ts +9 -0
  206. package/dist/runtime/execution-profile/resolve.d.ts.map +1 -0
  207. package/dist/runtime/execution-profile/resolve.js +80 -0
  208. package/dist/runtime/execution-profile/types.d.ts +27 -0
  209. package/dist/runtime/execution-profile/types.d.ts.map +1 -0
  210. package/dist/runtime/execution-profile/types.js +1 -0
  211. package/dist/runtime/explain/index.d.ts +3 -0
  212. package/dist/runtime/explain/index.d.ts.map +1 -0
  213. package/dist/runtime/explain/index.js +1 -0
  214. package/dist/runtime/explain/resolve.d.ts +14 -0
  215. package/dist/runtime/explain/resolve.d.ts.map +1 -0
  216. package/dist/runtime/explain/resolve.js +50 -0
  217. package/dist/runtime/explain/types.d.ts +28 -0
  218. package/dist/runtime/explain/types.d.ts.map +1 -0
  219. package/dist/runtime/explain/types.js +1 -0
  220. package/dist/runtime/harness/index.d.ts +4 -0
  221. package/dist/runtime/harness/index.d.ts.map +1 -0
  222. package/dist/runtime/harness/index.js +2 -0
  223. package/dist/runtime/harness/resolve-from-command-context.d.ts +4 -0
  224. package/dist/runtime/harness/resolve-from-command-context.d.ts.map +1 -0
  225. package/dist/runtime/harness/resolve-from-command-context.js +11 -0
  226. package/dist/runtime/harness/resolve.d.ts +13 -0
  227. package/dist/runtime/harness/resolve.d.ts.map +1 -0
  228. package/dist/runtime/harness/resolve.js +146 -0
  229. package/dist/runtime/harness/types.d.ts +65 -0
  230. package/dist/runtime/harness/types.d.ts.map +1 -0
  231. package/dist/runtime/harness/types.js +1 -0
  232. package/dist/runtime/incidents/index.d.ts +3 -0
  233. package/dist/runtime/incidents/index.d.ts.map +1 -0
  234. package/dist/runtime/incidents/index.js +1 -0
  235. package/dist/runtime/incidents/resolve.d.ts +26 -0
  236. package/dist/runtime/incidents/resolve.d.ts.map +1 -0
  237. package/dist/runtime/incidents/resolve.js +437 -0
  238. package/dist/runtime/incidents/types.d.ts +72 -0
  239. package/dist/runtime/incidents/types.d.ts.map +1 -0
  240. package/dist/runtime/incidents/types.js +1 -0
  241. package/dist/runtime/protocol/index.d.ts +3 -0
  242. package/dist/runtime/protocol/index.d.ts.map +1 -0
  243. package/dist/runtime/protocol/index.js +2 -0
  244. package/dist/runtime/protocol/resolve.d.ts +16 -0
  245. package/dist/runtime/protocol/resolve.d.ts.map +1 -0
  246. package/dist/runtime/protocol/resolve.js +36 -0
  247. package/dist/runtime/protocol/types.d.ts +36 -0
  248. package/dist/runtime/protocol/types.d.ts.map +1 -0
  249. package/dist/runtime/protocol/types.js +1 -0
  250. package/dist/runtime/task-intake/index.d.ts +3 -0
  251. package/dist/runtime/task-intake/index.d.ts.map +1 -0
  252. package/dist/runtime/task-intake/index.js +1 -0
  253. package/dist/runtime/task-intake/resolve.d.ts +48 -0
  254. package/dist/runtime/task-intake/resolve.d.ts.map +1 -0
  255. package/dist/runtime/task-intake/resolve.js +316 -0
  256. package/dist/runtime/task-intake/types.d.ts +117 -0
  257. package/dist/runtime/task-intake/types.d.ts.map +1 -0
  258. package/dist/runtime/task-intake/types.js +1 -0
  259. package/dist/shared/protected-paths.d.ts +4 -0
  260. package/dist/shared/protected-paths.d.ts.map +1 -1
  261. package/dist/shared/protected-paths.js +4 -4
  262. package/dist/usecases/context/resolve-context.d.ts +55 -6
  263. package/dist/usecases/context/resolve-context.d.ts.map +1 -1
  264. package/dist/usecases/context/resolve-context.js +96 -6
  265. package/dist/usecases/task/task-list-usecase.d.ts.map +1 -1
  266. package/dist/usecases/task/task-list-usecase.js +8 -2
  267. package/dist/usecases/task/task-new-usecase.js +4 -4
  268. package/package.json +2 -3
@@ -0,0 +1,67 @@
1
+ import { createCliEmitter } from "../../cli/output.js";
2
+ import { loadCommandContext } from "../shared/task-backend.js";
3
+ import { collectTaskIncidents } from "./shared.js";
4
+ const output = createCliEmitter();
5
+ export const incidentsCollectSpec = {
6
+ id: ["incidents", "collect"],
7
+ group: "Policy",
8
+ summary: "Promote structured external incident-candidates from a task into the incident registry.",
9
+ args: [{ name: "task-id", required: true, valueHint: "<task-id>" }],
10
+ options: [
11
+ {
12
+ kind: "boolean",
13
+ name: "check",
14
+ default: false,
15
+ description: "Validate incident promotion inputs without writing `.agentplane/policy/incidents.md`.",
16
+ },
17
+ {
18
+ kind: "boolean",
19
+ name: "json",
20
+ default: false,
21
+ description: "Emit machine-readable collection details.",
22
+ },
23
+ ],
24
+ examples: [
25
+ {
26
+ cmd: "agentplane incidents collect 202604031416-HEJWTM",
27
+ why: "Promote resolved external incident advice from task Findings into the shared registry.",
28
+ },
29
+ {
30
+ cmd: "agentplane incidents collect 202604031416-HEJWTM --check --json",
31
+ why: "Validate that incident-candidate blocks are complete before finish.",
32
+ },
33
+ ],
34
+ parse: (raw) => ({
35
+ taskId: String(raw.args["task-id"] ?? ""),
36
+ check: raw.opts.check === true,
37
+ json: raw.opts.json === true,
38
+ }),
39
+ };
40
+ export function makeRunIncidentsCollectHandler(getCtx) {
41
+ return async (ctx, p) => {
42
+ const commandContext = (await getCtx("incidents collect")) ??
43
+ (await loadCommandContext({ cwd: ctx.cwd, rootOverride: ctx.rootOverride ?? null }));
44
+ const result = await collectTaskIncidents({
45
+ ctx: commandContext,
46
+ taskId: p.taskId,
47
+ write: !p.check,
48
+ });
49
+ if (p.json) {
50
+ output.json({
51
+ task_id: p.taskId,
52
+ checked_only: p.check,
53
+ candidates: result.plan.candidates.length,
54
+ promotable: result.plan.promotable.map((item) => item.entry),
55
+ duplicates: result.plan.duplicates.map((item) => item.entry.id),
56
+ wrote: result.wrote,
57
+ registry_path: result.registryPath,
58
+ });
59
+ return 0;
60
+ }
61
+ output.success(p.check ? "checked" : "collected", p.taskId, `candidates=${result.plan.candidates.length} promoted=${result.plan.promotable.length} duplicates=${result.plan.duplicates.length}`);
62
+ if (result.plan.promotable.length > 0 && !p.check) {
63
+ output.info(`Incident registry updated: ${result.registryPath}`);
64
+ }
65
+ return 0;
66
+ };
67
+ }
@@ -0,0 +1,5 @@
1
+ import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
2
+ import { type GroupCommandParsed } from "../../cli/group-command.js";
3
+ export declare const incidentsSpec: CommandSpec<GroupCommandParsed>;
4
+ export declare const runIncidents: CommandHandler<GroupCommandParsed>;
5
+ //# sourceMappingURL=incidents.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incidents.command.d.ts","sourceRoot":"","sources":["../../../src/commands/incidents/incidents.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AAEpC,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,kBAAkB,CAWzD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,kBAAkB,CAO3D,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { loadDirectSubcommandNames, parseGroupCommand, throwGroupCommandUsage, } from "../../cli/group-command.js";
2
+ export const incidentsSpec = {
3
+ id: ["incidents"],
4
+ group: "Policy",
5
+ summary: "Promote external incident advice and resolve incident hints for analogous tasks.",
6
+ synopsis: ["agentplane incidents <collect|advise> [args] [options]"],
7
+ args: [{ name: "cmd", required: false, variadic: true, valueHint: "<command>" }],
8
+ notes: [
9
+ "Use `incidents collect` to promote structured incident-candidate findings into `.agentplane/policy/incidents.md`.",
10
+ "Use `incidents advise` to query registry advice by task id or lightweight scope/tags.",
11
+ ],
12
+ parse: (raw) => parseGroupCommand(raw),
13
+ };
14
+ export const runIncidents = async (_ctx, p) => {
15
+ throwGroupCommandUsage({
16
+ spec: incidentsSpec,
17
+ cmd: p.cmd,
18
+ subcommands: await loadDirectSubcommandNames(["incidents"]),
19
+ command: "incidents",
20
+ });
21
+ };
@@ -0,0 +1,42 @@
1
+ import type { TaskData } from "../../backends/task-backend.js";
2
+ import { type IncidentAdviceMatch, type IncidentAdviceQuery, type IncidentCollectionPlan, type IncidentRegistry } from "../../runtime/incidents/index.js";
3
+ import type { CommandContext } from "../shared/task-backend.js";
4
+ export declare const INCIDENTS_POLICY_PATH = ".agentplane/policy/incidents.md";
5
+ export type LoadedTaskIncidents = {
6
+ task: TaskData;
7
+ findings: string;
8
+ scope: string | null;
9
+ query: IncidentAdviceQuery;
10
+ };
11
+ export declare function incidentRegistryPath(ctx: CommandContext): string;
12
+ export declare function loadIncidentRegistry(ctx: CommandContext): Promise<{
13
+ registryPath: string;
14
+ registryText: string;
15
+ registry: IncidentRegistry;
16
+ }>;
17
+ export declare function loadTaskIncidents(ctx: CommandContext, taskId: string, taskOverride?: TaskData | null): Promise<LoadedTaskIncidents>;
18
+ export declare function formatIncidentCollectionIssues(taskId: string, plan: IncidentCollectionPlan): string;
19
+ export declare function collectTaskIncidents(opts: {
20
+ ctx: CommandContext;
21
+ taskId: string;
22
+ task?: TaskData | null;
23
+ write: boolean;
24
+ now?: Date;
25
+ }): Promise<{
26
+ loaded: LoadedTaskIncidents;
27
+ registryPath: string;
28
+ registryText: string;
29
+ registry: IncidentRegistry;
30
+ plan: IncidentCollectionPlan;
31
+ wrote: boolean;
32
+ }>;
33
+ export declare function adviseTaskIncidents(opts: {
34
+ ctx: CommandContext;
35
+ taskId: string;
36
+ task?: TaskData | null;
37
+ limit?: number;
38
+ }): Promise<{
39
+ loaded: LoadedTaskIncidents;
40
+ matches: IncidentAdviceMatch[];
41
+ }>;
42
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/incidents/shared.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAG/D,OAAO,EAOL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,kCAAkC,CAAC;AAM1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,eAAO,MAAM,qBAAqB,oCAAoC,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,mBAAmB,CAAC;CAC5B,CAAC;AAYF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAEhE;AAED,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC;IACvE,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,CAAC,CAQD;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,QAAQ,GAAG,IAAI,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAyB9B;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,sBAAsB,GAC3B,MAAM,CAUR;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,mBAAmB,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,IAAI,EAAE,sBAAsB,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC,CA+BD;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,mBAAmB,CAAC;IAC5B,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,CAAC,CAWD"}
@@ -0,0 +1,107 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { CliError } from "../../shared/errors.js";
4
+ import { writeTextIfChanged } from "../../shared/write-if-changed.js";
5
+ import { appendIncidentRegistryEntries, buildIncidentAdviceQueryFromTask, createIncidentRegistrySkeleton, parseIncidentRegistry, planIncidentCollection, resolveIncidentAdviceMatches, } from "../../runtime/incidents/index.js";
6
+ import { extractDocSection, extractTaskObservationSection, normalizeTaskDocVersion, } from "../task/shared.js";
7
+ export const INCIDENTS_POLICY_PATH = ".agentplane/policy/incidents.md";
8
+ async function readTextIfExists(filePath) {
9
+ try {
10
+ return await readFile(filePath, "utf8");
11
+ }
12
+ catch (err) {
13
+ const code = err?.code;
14
+ if (code === "ENOENT")
15
+ return null;
16
+ throw err;
17
+ }
18
+ }
19
+ export function incidentRegistryPath(ctx) {
20
+ return path.join(ctx.resolvedProject.gitRoot, INCIDENTS_POLICY_PATH);
21
+ }
22
+ export async function loadIncidentRegistry(ctx) {
23
+ const registryPath = incidentRegistryPath(ctx);
24
+ const registryText = (await readTextIfExists(registryPath)) ?? createIncidentRegistrySkeleton();
25
+ return {
26
+ registryPath,
27
+ registryText,
28
+ registry: parseIncidentRegistry(registryText),
29
+ };
30
+ }
31
+ export async function loadTaskIncidents(ctx, taskId, taskOverride) {
32
+ const task = taskOverride ?? (await ctx.taskBackend.getTask(taskId));
33
+ if (!task) {
34
+ throw new CliError({
35
+ exitCode: 2,
36
+ code: "E_USAGE",
37
+ message: `Unknown task: ${taskId}`,
38
+ });
39
+ }
40
+ const doc = typeof task.doc === "string" ? task.doc : "";
41
+ const docVersion = normalizeTaskDocVersion(task.doc_version);
42
+ const findings = extractTaskObservationSection(doc, docVersion)?.trim() ?? "";
43
+ const scope = extractDocSection(doc, "Scope")?.trim() ?? null;
44
+ return {
45
+ task,
46
+ findings,
47
+ scope,
48
+ query: buildIncidentAdviceQueryFromTask({
49
+ taskId: task.id,
50
+ title: task.title,
51
+ description: task.description,
52
+ scope,
53
+ tags: task.tags ?? [],
54
+ }),
55
+ };
56
+ }
57
+ export function formatIncidentCollectionIssues(taskId, plan) {
58
+ const issueLines = plan.issues.map((issue) => {
59
+ const scope = issue.candidate.incidentScope ?? issue.candidate.observation;
60
+ return `line ${issue.candidate.line}: ${scope} -> missing ${issue.missingFields.join(", ")}`;
61
+ });
62
+ return [
63
+ `${taskId}: incident-candidate entries require explicit external incident metadata before promotion.`,
64
+ "Required fields:",
65
+ ...issueLines.map((line) => `- ${line}`),
66
+ ].join("\n");
67
+ }
68
+ export async function collectTaskIncidents(opts) {
69
+ const loaded = await loadTaskIncidents(opts.ctx, opts.taskId, opts.task ?? null);
70
+ const { registryPath, registryText, registry } = await loadIncidentRegistry(opts.ctx);
71
+ const plan = planIncidentCollection({
72
+ task: {
73
+ id: loaded.task.id,
74
+ title: loaded.task.title,
75
+ description: loaded.task.description,
76
+ tags: loaded.task.tags ?? [],
77
+ commitHash: loaded.task.commit?.hash ?? null,
78
+ },
79
+ findings: loaded.findings,
80
+ registry,
81
+ now: opts.now,
82
+ });
83
+ if (plan.issues.length > 0) {
84
+ throw new CliError({
85
+ exitCode: 3,
86
+ code: "E_VALIDATION",
87
+ message: formatIncidentCollectionIssues(opts.taskId, plan),
88
+ });
89
+ }
90
+ const nextText = appendIncidentRegistryEntries(registryText, plan.promotable.map((item) => item.entry));
91
+ const wrote = opts.write && plan.promotable.length > 0
92
+ ? await writeTextIfChanged(registryPath, nextText)
93
+ : false;
94
+ return { loaded, registryPath, registryText, registry, plan, wrote };
95
+ }
96
+ export async function adviseTaskIncidents(opts) {
97
+ const loaded = await loadTaskIncidents(opts.ctx, opts.taskId, opts.task ?? null);
98
+ const { registry } = await loadIncidentRegistry(opts.ctx);
99
+ return {
100
+ loaded,
101
+ matches: resolveIncidentAdviceMatches({
102
+ query: loaded.query,
103
+ registry,
104
+ limit: opts.limit,
105
+ }),
106
+ };
107
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/check.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAsDnC,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgHlB"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/check.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AA8DnC,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiMlB"}
@@ -7,9 +7,15 @@ import { createCliEmitter, workflowModeMessage } from "../../cli/output.js";
7
7
  import { CliError } from "../../shared/errors.js";
8
8
  import { parsePrMeta } from "../shared/pr-meta.js";
9
9
  import { gitListTaskBranches, parseTaskIdFromBranch } from "../shared/git-worktree.js";
10
+ import { gitRevParse } from "../shared/git-ops.js";
11
+ import { isTaskLocalOnlyAdvance } from "../shared/task-local-freshness.js";
10
12
  import { loadBackendTask, loadCommandContext, } from "../shared/task-backend.js";
11
13
  import { readPrArtifact, resolvePrPaths } from "./internal/pr-paths.js";
12
- import { validateReviewContents } from "./internal/review-template.js";
14
+ import { validateGithubPrBodyContents, validateReviewContents, } from "./internal/review-template.js";
15
+ function isUnknownRevisionError(err) {
16
+ const message = err instanceof Error ? err.message : String(err);
17
+ return /unknown revision or path not in the working tree/i.test(message);
18
+ }
13
19
  async function resolveArtifactBranch(opts) {
14
20
  const prefix = opts.ctx.config.branch.task_prefix;
15
21
  const branches = await gitListTaskBranches(opts.resolved.gitRoot, prefix);
@@ -57,7 +63,7 @@ export async function cmdPrCheck(opts) {
57
63
  rootOverride: opts.rootOverride,
58
64
  taskId: opts.taskId,
59
65
  });
60
- const { resolved, config, prDir, metaPath, diffstatPath, verifyLogPath, reviewPath } = await resolvePrPaths({ ...opts, ctx });
66
+ const { resolved, config, prDir, metaPath, diffstatPath, verifyLogPath, reviewPath, githubTitlePath, githubBodyPath, } = await resolvePrPaths({ ...opts, ctx });
61
67
  if (config.workflow_mode !== "branch_pr") {
62
68
  throw new CliError({
63
69
  exitCode: exitCodeForError("E_USAGE"),
@@ -71,6 +77,8 @@ export async function cmdPrCheck(opts) {
71
77
  const relDiffstatPath = path.relative(resolved.gitRoot, diffstatPath);
72
78
  const relVerifyLogPath = path.relative(resolved.gitRoot, verifyLogPath);
73
79
  const relReviewPath = path.relative(resolved.gitRoot, reviewPath);
80
+ const relGithubTitlePath = path.relative(resolved.gitRoot, githubTitlePath);
81
+ const relGithubBodyPath = path.relative(resolved.gitRoot, githubBodyPath);
74
82
  const branchCache = {};
75
83
  let meta = null;
76
84
  const metaText = await readPrArtifactWithOptionalBranch({
@@ -129,6 +137,31 @@ export async function cmdPrCheck(opts) {
129
137
  else {
130
138
  errors.push(`Missing ${relReviewPath}`);
131
139
  }
140
+ const githubTitleText = await readPrArtifactWithOptionalBranch({
141
+ ctx,
142
+ resolved,
143
+ prDir,
144
+ fileName: "github-title.txt",
145
+ taskId: task.id,
146
+ branchCache,
147
+ });
148
+ if (!githubTitleText?.trim()) {
149
+ errors.push(`Missing ${relGithubTitlePath}`);
150
+ }
151
+ const githubBodyText = await readPrArtifactWithOptionalBranch({
152
+ ctx,
153
+ resolved,
154
+ prDir,
155
+ fileName: "github-body.md",
156
+ taskId: task.id,
157
+ branchCache,
158
+ });
159
+ if (githubBodyText) {
160
+ validateGithubPrBodyContents(githubBodyText, errors);
161
+ }
162
+ else {
163
+ errors.push(`Missing ${relGithubBodyPath}`);
164
+ }
132
165
  if (task.verify && task.verify.length > 0) {
133
166
  if (meta?.verify?.status !== "pass") {
134
167
  errors.push("Verify requirements not satisfied (meta.verify.status != pass)");
@@ -137,6 +170,44 @@ export async function cmdPrCheck(opts) {
137
170
  errors.push("Verify metadata missing (last_verified_sha/last_verified_at)");
138
171
  }
139
172
  }
173
+ const branchForFreshness = branchCache.value ?? (typeof meta?.branch === "string" ? meta.branch.trim() : null);
174
+ if (meta && branchForFreshness) {
175
+ let branchHeadSha = null;
176
+ try {
177
+ branchHeadSha = await gitRevParse(resolved.gitRoot, [branchForFreshness]);
178
+ }
179
+ catch (err) {
180
+ if (!isUnknownRevisionError(err))
181
+ throw err;
182
+ }
183
+ if (branchHeadSha) {
184
+ const reviewFresh = (meta.head_sha ?? null) === branchHeadSha ||
185
+ (await isTaskLocalOnlyAdvance({
186
+ gitRoot: resolved.gitRoot,
187
+ workflowDir: config.paths.workflow_dir,
188
+ taskId: task.id,
189
+ fromRef: meta.head_sha ?? null,
190
+ toRef: branchHeadSha,
191
+ }));
192
+ if (!reviewFresh) {
193
+ errors.push(`PR artifacts stale: head_sha=${meta.head_sha ?? "<missing>"} current_head=${branchHeadSha}`);
194
+ }
195
+ const verifyFresh = !task.verify ||
196
+ task.verify.length === 0 ||
197
+ !meta.last_verified_sha ||
198
+ meta.last_verified_sha === branchHeadSha ||
199
+ (await isTaskLocalOnlyAdvance({
200
+ gitRoot: resolved.gitRoot,
201
+ workflowDir: config.paths.workflow_dir,
202
+ taskId: task.id,
203
+ fromRef: meta.last_verified_sha,
204
+ toRef: branchHeadSha,
205
+ }));
206
+ if (task.verify && task.verify.length > 0 && meta.last_verified_sha && !verifyFresh) {
207
+ errors.push(`Verify state stale: last_verified_sha=${meta.last_verified_sha} current_head=${branchHeadSha}`);
208
+ }
209
+ }
210
+ }
140
211
  if (errors.length > 0) {
141
212
  throw new CliError({
142
213
  exitCode: exitCodeForError("E_VALIDATION"),
@@ -1 +1 @@
1
- {"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/integrate/cmd.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAQnE,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgMlB"}
1
+ {"version":3,"file":"cmd.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/integrate/cmd.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAQnE,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoMlB"}
@@ -74,6 +74,8 @@ export async function cmdIntegrate(opts) {
74
74
  branch,
75
75
  headBeforeMerge,
76
76
  taskId: task.id,
77
+ taskTitle: task.title,
78
+ taskTags: task.tags,
77
79
  workflowDir: loadedConfig.paths.workflow_dir,
78
80
  changedPaths,
79
81
  genericTokens: loadedConfig.commit.generic_tokens,
@@ -84,6 +86,8 @@ export async function cmdIntegrate(opts) {
84
86
  gitRoot: resolved.gitRoot,
85
87
  branch,
86
88
  taskId: task.id,
89
+ taskTitle: task.title,
90
+ taskTags: task.tags,
87
91
  workflowDir: loadedConfig.paths.workflow_dir,
88
92
  changedPaths,
89
93
  });
@@ -5,6 +5,8 @@ export declare function runSquashMerge(opts: {
5
5
  branch: string;
6
6
  headBeforeMerge: string;
7
7
  taskId: string;
8
+ taskTitle: string;
9
+ taskTags: string[];
8
10
  workflowDir: string;
9
11
  changedPaths: string[];
10
12
  genericTokens: string[];
@@ -13,6 +15,8 @@ export declare function runMergeCommit(opts: {
13
15
  gitRoot: string;
14
16
  branch: string;
15
17
  taskId: string;
18
+ taskTitle: string;
19
+ taskTags: string[];
16
20
  workflowDir: string;
17
21
  changedPaths: string[];
18
22
  }): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/merge.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAyGzD,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiFlB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BlB;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC,CA8DD"}
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/merge.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AA6HzD,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiFlB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkClB;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC,CA8DD"}
@@ -5,8 +5,23 @@ import { exitCodeForError } from "../../../../cli/exit-codes.js";
5
5
  import { CliError } from "../../../../shared/errors.js";
6
6
  import { execFileAsync, gitEnv } from "../../../shared/git.js";
7
7
  import { gitRevParse } from "../../../shared/git-ops.js";
8
+ import { buildGithubPrTitle } from "../../internal/review-template.js";
8
9
  import { computeVerifyState, runVerifyCommands } from "../verify.js";
9
10
  const noopPromise = () => Promise.resolve();
11
+ function fallbackIntegrateSummary(opts) {
12
+ const suffix = extractTaskSuffix(opts.taskId);
13
+ return buildGithubPrTitle({
14
+ id: opts.taskId,
15
+ title: opts.taskTitle,
16
+ tags: opts.taskTags,
17
+ description: "",
18
+ status: "TODO",
19
+ priority: "med",
20
+ owner: "UNKNOWN",
21
+ depends_on: [],
22
+ verify: [],
23
+ }).replace(new RegExp(String.raw ` \(${suffix}\)$`, "u"), "");
24
+ }
10
25
  async function listUntrackedTaskArtifacts(opts) {
11
26
  const { stdout } = await execFileAsync("git", ["status", "--short", "--untracked-files=all", "--", opts.taskPrefix], {
12
27
  cwd: opts.gitRoot,
@@ -120,7 +135,7 @@ export async function runSquashMerge(opts) {
120
135
  });
121
136
  if (!subjectPolicy.ok) {
122
137
  const suffix = extractTaskSuffix(opts.taskId);
123
- subject = `🧩 ${suffix} integrate: squash ${opts.branch}`;
138
+ subject = `🧩 ${suffix} integrate: ${fallbackIntegrateSummary(opts)}`;
124
139
  }
125
140
  const env = {
126
141
  ...process.env,
@@ -161,7 +176,13 @@ export async function runMergeCommit(opts) {
161
176
  AGENTPLANE_ALLOW_TASKS: "0",
162
177
  };
163
178
  try {
164
- await execFileAsync("git", ["merge", "--no-ff", opts.branch, "-m", `🔀 ${suffix} integrate: merge ${opts.branch}`], { cwd: opts.gitRoot, env });
179
+ await execFileAsync("git", [
180
+ "merge",
181
+ "--no-ff",
182
+ opts.branch,
183
+ "-m",
184
+ `🔀 ${suffix} integrate: ${fallbackIntegrateSummary(opts)}`,
185
+ ], { cwd: opts.gitRoot, env });
165
186
  }
166
187
  catch (err) {
167
188
  await execFileAsync("git", ["merge", "--abort"], { cwd: opts.gitRoot, env: gitEnv() });
@@ -1 +1 @@
1
- {"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/prepare.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,eAAe,EAEf,KAAK,cAAc,EACpB,MAAM,iCAAiC,CAAC;AAUzC,OAAO,EAAe,KAAK,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEtE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,cAAc,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC5C,YAAY,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAE1D,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IAEtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IAEtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IAEb,aAAa,EAAE,MAAM,CAAC;IAEtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAyJ7B"}
1
+ {"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../../../../../src/commands/pr/integrate/internal/prepare.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,eAAe,EAEf,KAAK,cAAc,EACpB,MAAM,iCAAiC,CAAC;AAUzC,OAAO,EAAe,KAAK,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAGtE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,cAAc,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC5C,YAAY,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAE1D,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IAEtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IAEtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IAEb,aAAa,EAAE,MAAM,CAAC;IAEtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAoL7B"}
@@ -14,6 +14,7 @@ import { resolvePrPaths } from "../../internal/pr-paths.js";
14
14
  import { readAndValidatePrArtifacts } from "../artifacts.js";
15
15
  import { computeVerifyState } from "../verify.js";
16
16
  import { parsePrMeta } from "../../../shared/pr-meta.js";
17
+ import { isTaskLocalOnlyAdvance } from "../../../shared/task-local-freshness.js";
17
18
  export async function prepareIntegrate(opts) {
18
19
  const ctx = opts.ctx ??
19
20
  (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
@@ -116,9 +117,33 @@ export async function prepareIntegrate(opts) {
116
117
  });
117
118
  }
118
119
  const branchHeadSha = await gitRevParse(resolved.gitRoot, [branch]);
120
+ const reviewFresh = (metaSource.head_sha ?? null) === branchHeadSha ||
121
+ (await isTaskLocalOnlyAdvance({
122
+ gitRoot: resolved.gitRoot,
123
+ workflowDir: loadedConfig.paths.workflow_dir,
124
+ taskId: task.id,
125
+ fromRef: metaSource.head_sha ?? null,
126
+ toRef: branchHeadSha,
127
+ }));
128
+ if (!reviewFresh) {
129
+ throw new CliError({
130
+ exitCode: exitCodeForError("E_VALIDATION"),
131
+ code: "E_VALIDATION",
132
+ message: `PR artifacts stale for ${task.id}: meta.head_sha=${metaSource.head_sha ?? "<missing>"} ` +
133
+ `current_head=${branchHeadSha} (refresh the task branch artifacts before integrate)`,
134
+ });
135
+ }
136
+ const verifyFresh = (metaSource.last_verified_sha ?? null) === branchHeadSha ||
137
+ (await isTaskLocalOnlyAdvance({
138
+ gitRoot: resolved.gitRoot,
139
+ workflowDir: loadedConfig.paths.workflow_dir,
140
+ taskId: task.id,
141
+ fromRef: metaSource.last_verified_sha ?? null,
142
+ toRef: branchHeadSha,
143
+ }));
119
144
  const initialVerifyState = computeVerifyState({
120
145
  rawVerify: task.verify,
121
- metaLastVerifiedSha: metaSource?.last_verified_sha ?? null,
146
+ metaLastVerifiedSha: verifyFresh ? branchHeadSha : (metaSource?.last_verified_sha ?? null),
122
147
  verifyLogText,
123
148
  branchHeadSha,
124
149
  runVerify: opts.runVerify,
@@ -0,0 +1,18 @@
1
+ export type PrHandoffNote = {
2
+ schema_version: 1;
3
+ created_at: string;
4
+ author: string;
5
+ body: string;
6
+ };
7
+ export declare function buildPrHandoffNote(opts: {
8
+ createdAt: string;
9
+ author: string;
10
+ body: string;
11
+ }): PrHandoffNote;
12
+ export declare function parsePrHandoffNotes(raw: string): PrHandoffNote[];
13
+ export declare function readPrHandoffNotes(notesPath: string): Promise<PrHandoffNote[]>;
14
+ export declare function appendPrHandoffNote(opts: {
15
+ notesPath: string;
16
+ note: PrHandoffNote;
17
+ }): Promise<void>;
18
+ //# sourceMappingURL=note-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-store.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/note-store.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,aAAa,GAAG;IAC1B,cAAc,EAAE,CAAC,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAaF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,aAAa,CAOhB;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE,CA2BhE;AAED,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAQpF;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,aAAa,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhB"}
@@ -0,0 +1,66 @@
1
+ import { appendFile, mkdir, readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ function invalidNote(index, message) {
4
+ return new Error(`Invalid pr/notes.jsonl entry ${index + 1}: ${message}`);
5
+ }
6
+ function trimRequired(value, field, index) {
7
+ if (typeof value !== "string")
8
+ throw invalidNote(index, `${field} must be a string`);
9
+ const trimmed = value.trim();
10
+ if (!trimmed)
11
+ throw invalidNote(index, `${field} must not be empty`);
12
+ return trimmed;
13
+ }
14
+ export function buildPrHandoffNote(opts) {
15
+ return {
16
+ schema_version: 1,
17
+ created_at: opts.createdAt,
18
+ author: opts.author.trim(),
19
+ body: opts.body.trim(),
20
+ };
21
+ }
22
+ export function parsePrHandoffNotes(raw) {
23
+ if (!raw.trim())
24
+ return [];
25
+ return raw
26
+ .split(/\r?\n/)
27
+ .filter((line) => line.trim().length > 0)
28
+ .map((line, index) => {
29
+ let parsed;
30
+ try {
31
+ parsed = JSON.parse(line);
32
+ }
33
+ catch (err) {
34
+ const message = err instanceof Error ? err.message : String(err);
35
+ throw invalidNote(index, `invalid JSON (${message})`);
36
+ }
37
+ const record = parsed;
38
+ if (!record || typeof record !== "object") {
39
+ throw invalidNote(index, "entry must be an object");
40
+ }
41
+ if ((record.schema_version ?? 1) !== 1) {
42
+ throw invalidNote(index, "unsupported schema_version");
43
+ }
44
+ return {
45
+ schema_version: 1,
46
+ created_at: trimRequired(record.created_at, "created_at", index),
47
+ author: trimRequired(record.author, "author", index),
48
+ body: trimRequired(record.body, "body", index),
49
+ };
50
+ });
51
+ }
52
+ export async function readPrHandoffNotes(notesPath) {
53
+ try {
54
+ return parsePrHandoffNotes(await readFile(notesPath, "utf8"));
55
+ }
56
+ catch (err) {
57
+ const code = err?.code;
58
+ if (code === "ENOENT")
59
+ return [];
60
+ throw err;
61
+ }
62
+ }
63
+ export async function appendPrHandoffNote(opts) {
64
+ await mkdir(path.dirname(opts.notesPath), { recursive: true });
65
+ await appendFile(opts.notesPath, `${JSON.stringify(opts.note)}\n`, "utf8");
66
+ }
@@ -9,8 +9,11 @@ export type ResolvedPrPaths = {
9
9
  prDir: string;
10
10
  metaPath: string;
11
11
  diffstatPath: string;
12
+ notesPath: string;
12
13
  verifyLogPath: string;
13
14
  reviewPath: string;
15
+ githubTitlePath: string;
16
+ githubBodyPath: string;
14
17
  };
15
18
  export declare function resolvePrPaths(opts: {
16
19
  ctx?: CommandContext;
@@ -1 +1 @@
1
- {"version":3,"file":"pr-paths.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/pr-paths.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,eAAe,CAAC,CAoB3B;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWzB"}
1
+ {"version":3,"file":"pr-paths.d.ts","sourceRoot":"","sources":["../../../../src/commands/pr/internal/pr-paths.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,eAAe,CAAC,CAuB3B;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWzB"}
@@ -19,8 +19,11 @@ export async function resolvePrPaths(opts) {
19
19
  prDir,
20
20
  metaPath: path.join(prDir, "meta.json"),
21
21
  diffstatPath: path.join(prDir, "diffstat.txt"),
22
+ notesPath: path.join(prDir, "notes.jsonl"),
22
23
  verifyLogPath: path.join(prDir, "verify.log"),
23
24
  reviewPath: path.join(prDir, "review.md"),
25
+ githubTitlePath: path.join(prDir, "github-title.txt"),
26
+ githubBodyPath: path.join(prDir, "github-body.md"),
24
27
  };
25
28
  }
26
29
  export async function readPrArtifact(opts) {