agentplane 0.2.6 → 0.2.12

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 (140) hide show
  1. package/README.md +11 -0
  2. package/assets/AGENTS.md +35 -0
  3. package/assets/agents/CODER.json +0 -1
  4. package/assets/agents/INTEGRATOR.json +0 -1
  5. package/assets/agents/ORCHESTRATOR.json +1 -2
  6. package/assets/agents/PLANNER.json +1 -3
  7. package/assets/agents/TESTER.json +0 -1
  8. package/assets/agents/UPGRADER.json +17 -15
  9. package/dist/cli/archive.d.ts.map +1 -1
  10. package/dist/cli/archive.js +61 -36
  11. package/dist/cli/command-guide.d.ts.map +1 -1
  12. package/dist/cli/command-guide.js +4 -2
  13. package/dist/cli/run-cli/command-catalog.d.ts +4 -1
  14. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  15. package/dist/cli/run-cli/command-catalog.js +40 -22
  16. package/dist/cli/run-cli/commands/config.d.ts +5 -4
  17. package/dist/cli/run-cli/commands/config.d.ts.map +1 -1
  18. package/dist/cli/run-cli/commands/config.js +39 -29
  19. package/dist/cli/run-cli/commands/core.d.ts +2 -1
  20. package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
  21. package/dist/cli/run-cli/commands/core.js +174 -67
  22. package/dist/cli/run-cli/commands/ide.d.ts +3 -1
  23. package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
  24. package/dist/cli/run-cli/commands/ide.js +7 -6
  25. package/dist/cli/run-cli/commands/init/ide-sync.d.ts.map +1 -1
  26. package/dist/cli/run-cli/commands/init/ide-sync.js +10 -1
  27. package/dist/cli/run-cli/commands/init/write-agents.d.ts.map +1 -1
  28. package/dist/cli/run-cli/commands/init/write-agents.js +4 -24
  29. package/dist/cli/run-cli/commands/init/write-gitignore.d.ts +4 -0
  30. package/dist/cli/run-cli/commands/init/write-gitignore.d.ts.map +1 -0
  31. package/dist/cli/run-cli/commands/init/write-gitignore.js +35 -0
  32. package/dist/cli/run-cli/commands/init.d.ts +1 -0
  33. package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
  34. package/dist/cli/run-cli/commands/init.js +31 -8
  35. package/dist/cli/run-cli/registry.run.d.ts +6 -2
  36. package/dist/cli/run-cli/registry.run.d.ts.map +1 -1
  37. package/dist/cli/run-cli/registry.run.js +7 -2
  38. package/dist/cli/run-cli.d.ts.map +1 -1
  39. package/dist/cli/run-cli.js +94 -75
  40. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  41. package/dist/cli/run-cli.test-helpers.js +99 -3
  42. package/dist/cli/spec/parse-utils.d.ts +11 -0
  43. package/dist/cli/spec/parse-utils.d.ts.map +1 -0
  44. package/dist/cli/spec/parse-utils.js +28 -0
  45. package/dist/commands/block.command.d.ts +3 -18
  46. package/dist/commands/block.command.d.ts.map +1 -1
  47. package/dist/commands/block.command.js +2 -143
  48. package/dist/commands/block.run.d.ts +5 -0
  49. package/dist/commands/block.run.d.ts.map +1 -0
  50. package/dist/commands/block.run.js +22 -0
  51. package/dist/commands/block.spec.d.ts +17 -0
  52. package/dist/commands/block.spec.d.ts.map +1 -0
  53. package/dist/commands/block.spec.js +115 -0
  54. package/dist/commands/finish.command.d.ts +3 -27
  55. package/dist/commands/finish.command.d.ts.map +1 -1
  56. package/dist/commands/finish.command.js +2 -237
  57. package/dist/commands/finish.run.d.ts +5 -0
  58. package/dist/commands/finish.run.d.ts.map +1 -0
  59. package/dist/commands/finish.run.js +40 -0
  60. package/dist/commands/finish.spec.d.ts +26 -0
  61. package/dist/commands/finish.spec.d.ts.map +1 -0
  62. package/dist/commands/finish.spec.js +193 -0
  63. package/dist/commands/release/apply.command.d.ts +11 -0
  64. package/dist/commands/release/apply.command.d.ts.map +1 -0
  65. package/dist/commands/release/apply.command.js +343 -0
  66. package/dist/commands/release/plan.command.d.ts +12 -0
  67. package/dist/commands/release/plan.command.d.ts.map +1 -0
  68. package/dist/commands/release/plan.command.js +206 -0
  69. package/dist/commands/release/release.command.d.ts +5 -0
  70. package/dist/commands/release/release.command.d.ts.map +1 -0
  71. package/dist/commands/release/release.command.js +18 -0
  72. package/dist/commands/shared/task-backend.d.ts +1 -0
  73. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  74. package/dist/commands/start.command.d.ts +3 -18
  75. package/dist/commands/start.command.d.ts.map +1 -1
  76. package/dist/commands/start.command.js +2 -143
  77. package/dist/commands/start.run.d.ts +5 -0
  78. package/dist/commands/start.run.d.ts.map +1 -0
  79. package/dist/commands/start.run.js +22 -0
  80. package/dist/commands/start.spec.d.ts +17 -0
  81. package/dist/commands/start.spec.d.ts.map +1 -0
  82. package/dist/commands/start.spec.js +115 -0
  83. package/dist/commands/task/add.command.d.ts.map +1 -1
  84. package/dist/commands/task/add.command.js +1 -7
  85. package/dist/commands/task/derive.command.d.ts.map +1 -1
  86. package/dist/commands/task/derive.command.js +1 -7
  87. package/dist/commands/task/list.command.d.ts +3 -8
  88. package/dist/commands/task/list.command.d.ts.map +1 -1
  89. package/dist/commands/task/list.command.js +2 -67
  90. package/dist/commands/task/list.run.d.ts +5 -0
  91. package/dist/commands/task/list.run.d.ts.map +1 -0
  92. package/dist/commands/task/list.run.js +10 -0
  93. package/dist/commands/task/list.spec.d.ts +7 -0
  94. package/dist/commands/task/list.spec.d.ts.map +1 -0
  95. package/dist/commands/task/list.spec.js +51 -0
  96. package/dist/commands/task/next.command.d.ts +3 -8
  97. package/dist/commands/task/next.command.d.ts.map +1 -1
  98. package/dist/commands/task/next.command.js +2 -89
  99. package/dist/commands/task/next.run.d.ts +5 -0
  100. package/dist/commands/task/next.run.d.ts.map +1 -0
  101. package/dist/commands/task/next.run.js +11 -0
  102. package/dist/commands/task/next.spec.d.ts +7 -0
  103. package/dist/commands/task/next.spec.d.ts.map +1 -0
  104. package/dist/commands/task/next.spec.js +69 -0
  105. package/dist/commands/task/search.command.d.ts +3 -10
  106. package/dist/commands/task/search.command.d.ts.map +1 -1
  107. package/dist/commands/task/search.command.js +2 -101
  108. package/dist/commands/task/search.run.d.ts +5 -0
  109. package/dist/commands/task/search.run.d.ts.map +1 -0
  110. package/dist/commands/task/search.run.js +13 -0
  111. package/dist/commands/task/search.spec.d.ts +9 -0
  112. package/dist/commands/task/search.spec.d.ts.map +1 -0
  113. package/dist/commands/task/search.spec.js +79 -0
  114. package/dist/commands/task/set-status.command.d.ts.map +1 -1
  115. package/dist/commands/task/set-status.command.js +1 -7
  116. package/dist/commands/task/shared.d.ts.map +1 -1
  117. package/dist/commands/task/shared.js +15 -8
  118. package/dist/commands/task/show.command.d.ts +3 -7
  119. package/dist/commands/task/show.command.d.ts.map +1 -1
  120. package/dist/commands/task/show.command.js +2 -19
  121. package/dist/commands/task/show.run.d.ts +5 -0
  122. package/dist/commands/task/show.run.d.ts.map +1 -0
  123. package/dist/commands/task/show.run.js +11 -0
  124. package/dist/commands/task/show.spec.d.ts +6 -0
  125. package/dist/commands/task/show.spec.d.ts.map +1 -0
  126. package/dist/commands/task/show.spec.js +8 -0
  127. package/dist/commands/task/update.command.d.ts.map +1 -1
  128. package/dist/commands/task/update.command.js +1 -7
  129. package/dist/commands/upgrade.d.ts.map +1 -1
  130. package/dist/commands/upgrade.js +149 -31
  131. package/dist/commands/verify.command.d.ts +3 -15
  132. package/dist/commands/verify.command.d.ts.map +1 -1
  133. package/dist/commands/verify.command.js +2 -113
  134. package/dist/commands/verify.run.d.ts +5 -0
  135. package/dist/commands/verify.run.d.ts.map +1 -0
  136. package/dist/commands/verify.run.js +17 -0
  137. package/dist/commands/verify.spec.d.ts +14 -0
  138. package/dist/commands/verify.spec.d.ts.map +1 -0
  139. package/dist/commands/verify.spec.js +96 -0
  140. package/package.json +1 -1
@@ -1,12 +1,6 @@
1
1
  import { usageError } from "../../cli/spec/errors.js";
2
+ import { toStringList } from "../../cli/spec/parse-utils.js";
2
3
  import { cmdTaskSetStatus } from "./set-status.js";
3
- function toStringList(v) {
4
- if (typeof v === "string")
5
- return [v];
6
- if (Array.isArray(v))
7
- return v.filter((x) => typeof x === "string");
8
- return [];
9
- }
10
4
  export const taskSetStatusSpec = {
11
5
  id: ["task", "set-status"],
12
6
  group: "Task",
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/task/shared.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/task/shared.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,20 @@ import { dedupeStrings } from "../../shared/strings.js";
11
11
  import { parseGitLogHashSubject } from "../../shared/git-log.js";
12
12
  export { dedupeStrings } from "../../shared/strings.js";
13
13
  export const execFileAsync = promisify(execFile);
14
+ async function listAgentIdsMemo(ctx) {
15
+ ctx.memo.agentIds ??= (async () => {
16
+ const agentsDir = path.join(ctx.resolvedProject.gitRoot, ctx.config.paths.agents_dir);
17
+ if (!(await fileExists(agentsDir)))
18
+ return [];
19
+ const entries = await readdir(agentsDir);
20
+ return entries
21
+ .filter((name) => name.endsWith(".json"))
22
+ .map((name) => name.slice(0, -".json".length))
23
+ .map((id) => id.trim())
24
+ .filter((id) => id.length > 0);
25
+ })();
26
+ return await ctx.memo.agentIds;
27
+ }
14
28
  export function nowIso() {
15
29
  return new Date().toISOString();
16
30
  }
@@ -77,14 +91,7 @@ export async function warnIfUnknownOwner(ctx, owner) {
77
91
  const trimmed = owner.trim();
78
92
  if (!trimmed)
79
93
  return;
80
- const agentsDir = path.join(ctx.resolvedProject.gitRoot, ctx.config.paths.agents_dir);
81
- if (!(await fileExists(agentsDir)))
82
- return;
83
- const entries = await readdir(agentsDir);
84
- const ids = entries
85
- .filter((name) => name.endsWith(".json"))
86
- .map((name) => name.slice(0, -".json".length))
87
- .filter((id) => id.trim().length > 0);
94
+ const ids = await listAgentIdsMemo(ctx);
88
95
  if (ids.length === 0)
89
96
  return;
90
97
  if (!ids.includes(trimmed)) {
@@ -1,8 +1,4 @@
1
- import type { CommandCtx, CommandSpec } from "../../cli/spec/spec.js";
2
- import type { CommandContext } from "../shared/task-backend.js";
3
- export type TaskShowParsed = {
4
- taskId: string;
5
- };
6
- export declare const taskShowSpec: CommandSpec<TaskShowParsed>;
7
- export declare function makeRunTaskShowHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: TaskShowParsed) => Promise<number>;
1
+ export { taskShowSpec } from "./show.spec.js";
2
+ export type { TaskShowParsed } from "./show.spec.js";
3
+ export { makeRunTaskShowHandler } from "./show.run.js";
8
4
  //# sourceMappingURL=show.command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"show.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/show.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhD,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,cAAc,CAOpD,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACvE,KAAK,UAAU,EAAE,GAAG,cAAc,KAAG,OAAO,CAAC,MAAM,CAAC,CAQnE"}
1
+ {"version":3,"file":"show.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/show.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC"}
@@ -1,19 +1,2 @@
1
- import { cmdTaskShow } from "./show.js";
2
- export const taskShowSpec = {
3
- id: ["task", "show"],
4
- group: "Task",
5
- summary: "Print task metadata as JSON (frontmatter shape).",
6
- args: [{ name: "task-id", required: true, valueHint: "<task-id>" }],
7
- examples: [{ cmd: "agentplane task show 202602030608-F1Q8AB", why: "Show task metadata." }],
8
- parse: (raw) => ({ taskId: String(raw.args["task-id"]) }),
9
- };
10
- export function makeRunTaskShowHandler(getCtx) {
11
- return async (ctx, p) => {
12
- return await cmdTaskShow({
13
- ctx: await getCtx("task show"),
14
- cwd: ctx.cwd,
15
- rootOverride: ctx.rootOverride,
16
- taskId: p.taskId,
17
- });
18
- };
19
- }
1
+ export { taskShowSpec } from "./show.spec.js";
2
+ export { makeRunTaskShowHandler } from "./show.run.js";
@@ -0,0 +1,5 @@
1
+ import type { CommandCtx } from "../../cli/spec/spec.js";
2
+ import type { CommandContext } from "../shared/task-backend.js";
3
+ import type { TaskShowParsed } from "./show.spec.js";
4
+ export declare function makeRunTaskShowHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: TaskShowParsed) => Promise<number>;
5
+ //# sourceMappingURL=show.run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.run.d.ts","sourceRoot":"","sources":["../../../src/commands/task/show.run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACvE,KAAK,UAAU,EAAE,GAAG,cAAc,KAAG,OAAO,CAAC,MAAM,CAAC,CAQnE"}
@@ -0,0 +1,11 @@
1
+ import { cmdTaskShow } from "./show.js";
2
+ export function makeRunTaskShowHandler(getCtx) {
3
+ return async (ctx, p) => {
4
+ return await cmdTaskShow({
5
+ ctx: await getCtx("task show"),
6
+ cwd: ctx.cwd,
7
+ rootOverride: ctx.rootOverride,
8
+ taskId: p.taskId,
9
+ });
10
+ };
11
+ }
@@ -0,0 +1,6 @@
1
+ import type { CommandSpec } from "../../cli/spec/spec.js";
2
+ export type TaskShowParsed = {
3
+ taskId: string;
4
+ };
5
+ export declare const taskShowSpec: CommandSpec<TaskShowParsed>;
6
+ //# sourceMappingURL=show.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.spec.d.ts","sourceRoot":"","sources":["../../../src/commands/task/show.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhD,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,cAAc,CAOpD,CAAC"}
@@ -0,0 +1,8 @@
1
+ export const taskShowSpec = {
2
+ id: ["task", "show"],
3
+ group: "Task",
4
+ summary: "Print task metadata as JSON (frontmatter shape).",
5
+ args: [{ name: "task-id", required: true, valueHint: "<task-id>" }],
6
+ examples: [{ cmd: "agentplane task show 202602030608-F1Q8AB", why: "Show task metadata." }],
7
+ parse: (raw) => ({ taskId: String(raw.args["task-id"]) }),
8
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"update.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/update.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAKhE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAQF,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAiHxD,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACzE,KAAK,UAAU,EAAE,GAAG,gBAAgB,KAAG,OAAO,CAAC,MAAM,CAAC,CAkBrE"}
1
+ {"version":3,"file":"update.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/update.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAKhE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAiHxD,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACzE,KAAK,UAAU,EAAE,GAAG,gBAAgB,KAAG,OAAO,CAAC,MAAM,CAAC,CAkBrE"}
@@ -1,13 +1,7 @@
1
1
  import { usageError } from "../../cli/spec/errors.js";
2
+ import { toStringList } from "../../cli/spec/parse-utils.js";
2
3
  import { cmdTaskUpdate } from "./update.js";
3
4
  import { normalizeDependsOnInput } from "./shared.js";
4
- function toStringList(v) {
5
- if (typeof v === "string")
6
- return [v];
7
- if (Array.isArray(v))
8
- return v.filter((x) => typeof x === "string");
9
- return [];
10
- }
11
5
  export const taskUpdateSpec = {
12
6
  id: ["task", "update"],
13
7
  group: "Task",
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAoCA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AA2DF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB,CAWA;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,GACG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAqB1C;AAUD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAgBT;AAkPD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6dlB"}
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAmCA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AA4EF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB,CAWA;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,GACG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAqB1C;AAUD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAgBT;AAqQD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqmBlB"}
@@ -1,4 +1,4 @@
1
- import { lstat, mkdir, mkdtemp, readdir, readFile, readlink, rm, symlink, writeFile, } from "node:fs/promises";
1
+ import { lstat, mkdir, mkdtemp, readdir, readFile, readlink, rm, writeFile, } from "node:fs/promises";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
@@ -230,6 +230,23 @@ function jsonEqual(a, b) {
230
230
  const cb = JSON.stringify(canonicalizeJson(b)) ?? "__undefined__";
231
231
  return ca === cb;
232
232
  }
233
+ function textChangedForType(opts) {
234
+ if (opts.aText === null && opts.bText === null)
235
+ return false;
236
+ if (opts.aText === null || opts.bText === null)
237
+ return true;
238
+ if (opts.type === "json") {
239
+ try {
240
+ const a = JSON.parse(opts.aText);
241
+ const b = JSON.parse(opts.bText);
242
+ return !jsonEqual(a, b);
243
+ }
244
+ catch {
245
+ return opts.aText.trim() !== opts.bText.trim();
246
+ }
247
+ }
248
+ return opts.aText.trimEnd() !== opts.bText.trimEnd();
249
+ }
233
250
  // Used as a fallback for 3-way merges when no baseline is available. Incoming (upstream) values
234
251
  // win for scalar/object conflicts, while user-added keys and array items are preserved.
235
252
  function mergeAgentJsonIncomingWins(incomingText, currentText) {
@@ -519,6 +536,8 @@ export async function cmdUpgradeParsed(opts) {
519
536
  const fileContents = new Map();
520
537
  const merged = [];
521
538
  const missingRequired = [];
539
+ const reviewRecords = [];
540
+ const reviewSnapshots = new Map();
522
541
  const readBaselineText = async (baselineKey) => {
523
542
  try {
524
543
  return await readFile(path.join(baselineDirNew, baselineKey), "utf8");
@@ -588,6 +607,12 @@ export async function cmdUpgradeParsed(opts) {
588
607
  if (kind !== null) {
589
608
  existingBuf = await readFile(destPath);
590
609
  }
610
+ const incomingTextOriginal = data.toString("utf8");
611
+ const currentTextForReview = existingBuf ? existingBuf.toString("utf8") : null;
612
+ const baselineKey = toBaselineKey(rel);
613
+ const baselineText = baselineKey ? await readBaselineText(baselineKey) : null;
614
+ let mergeApplied = false;
615
+ let mergePath = "none";
591
616
  // Merge logic only needs text for a small subset of managed files.
592
617
  if (existingBuf) {
593
618
  if (entry.merge_strategy === "agents_policy_markdown" && rel === "AGENTS.md") {
@@ -595,18 +620,16 @@ export async function cmdUpgradeParsed(opts) {
595
620
  const mergedText = mergeAgentsPolicyMarkdown(data.toString("utf8"), existingText);
596
621
  data = Buffer.from(mergedText, "utf8");
597
622
  merged.push(rel);
623
+ mergeApplied = true;
624
+ mergePath = "markdownOverrides";
598
625
  }
599
626
  else if (entry.merge_strategy === "agent_json_3way" &&
600
627
  rel.startsWith(".agentplane/agents/") &&
601
628
  rel.endsWith(".json")) {
602
629
  existingText = existingBuf.toString("utf8");
603
- const baselineKey = toBaselineKey(rel);
604
630
  let mergedText = null;
605
- if (baselineKey) {
631
+ if (baselineText !== null) {
606
632
  try {
607
- const baselineText = await readBaselineText(baselineKey);
608
- if (!baselineText)
609
- throw new Error("missing baseline");
610
633
  mergedText = mergeAgentJson3Way({
611
634
  incomingText: data.toString("utf8"),
612
635
  currentText: existingText,
@@ -617,13 +640,72 @@ export async function cmdUpgradeParsed(opts) {
617
640
  mergedText = null;
618
641
  }
619
642
  }
620
- mergedText ??= mergeAgentJsonIncomingWins(data.toString("utf8"), existingText);
643
+ if (mergedText) {
644
+ mergePath = "3way";
645
+ }
646
+ else {
647
+ mergedText = mergeAgentJsonIncomingWins(data.toString("utf8"), existingText);
648
+ if (mergedText) {
649
+ mergePath = baselineText === null ? "incomingWins" : "incomingWinsFallback";
650
+ }
651
+ }
621
652
  if (mergedText) {
622
653
  data = Buffer.from(mergedText, "utf8");
623
654
  merged.push(rel);
655
+ mergeApplied = true;
656
+ }
657
+ else {
658
+ mergePath = "parseFailed";
624
659
  }
625
660
  }
626
661
  }
662
+ const hasBaseline = baselineText !== null;
663
+ let changedCurrentVsBaseline = null;
664
+ let changedIncomingVsBaseline = null;
665
+ if (baselineText !== null) {
666
+ changedCurrentVsBaseline = textChangedForType({
667
+ type: entry.type,
668
+ aText: currentTextForReview,
669
+ bText: baselineText,
670
+ });
671
+ changedIncomingVsBaseline = textChangedForType({
672
+ type: entry.type,
673
+ aText: incomingTextOriginal,
674
+ bText: baselineText,
675
+ });
676
+ }
677
+ const proposedText = data.toString("utf8");
678
+ const currentDiffersFromIncoming = currentTextForReview === null
679
+ ? false
680
+ : textChangedForType({
681
+ type: entry.type,
682
+ aText: currentTextForReview,
683
+ bText: incomingTextOriginal,
684
+ });
685
+ const baselineConflict = baselineText === null
686
+ ? false
687
+ : Boolean(changedCurrentVsBaseline) && Boolean(changedIncomingVsBaseline);
688
+ const noBaselineConflict = baselineText === null ? currentDiffersFromIncoming : false;
689
+ const mergeNotAppliedConflict = mergeApplied ? false : currentDiffersFromIncoming;
690
+ const needsSemanticReview = baselineConflict || noBaselineConflict || mergeNotAppliedConflict;
691
+ reviewRecords.push({
692
+ relPath: rel,
693
+ mergeStrategy: entry.merge_strategy,
694
+ hasBaseline,
695
+ changedCurrentVsBaseline,
696
+ changedIncomingVsBaseline,
697
+ needsSemanticReview,
698
+ mergeApplied,
699
+ mergePath,
700
+ });
701
+ if (flags.mode === "agent" && needsSemanticReview) {
702
+ reviewSnapshots.set(rel, {
703
+ incomingText: incomingTextOriginal,
704
+ currentText: currentTextForReview,
705
+ baselineText,
706
+ proposedText,
707
+ });
708
+ }
627
709
  fileContents.set(rel, data);
628
710
  if (kind === null)
629
711
  additions.push(rel);
@@ -691,7 +773,7 @@ export async function cmdUpgradeParsed(opts) {
691
773
  `- .git/**\n\n` +
692
774
  `## Notes\n\n` +
693
775
  `- The upgrade bundle is validated against framework.manifest.json.\n` +
694
- `- AGENTS.md is managed under .agentplane/AGENTS.md and workspace-root AGENTS.md is a symlink.\n`;
776
+ `- AGENTS.md is the canonical policy file at the workspace root.\n`;
695
777
  const reportMd = `# Upgrade report (${runId})\n\n` +
696
778
  `## Actions taken\n\n` +
697
779
  `- [ ] Reviewed plan.md\n` +
@@ -704,7 +786,39 @@ export async function cmdUpgradeParsed(opts) {
704
786
  await writeFile(path.join(runDir, "constraints.md"), constraintsMd, "utf8");
705
787
  await writeFile(path.join(runDir, "report.md"), reportMd, "utf8");
706
788
  await writeFile(path.join(runDir, "files.json"), JSON.stringify({ additions, updates, skipped, merged }, null, 2) + "\n", "utf8");
707
- process.stdout.write(`Upgrade plan written: ${path.relative(resolved.gitRoot, runDir)}\n`);
789
+ const needsReview = reviewRecords.filter((r) => r.needsSemanticReview);
790
+ await writeFile(path.join(runDir, "review.json"), JSON.stringify({
791
+ generated_at: new Date().toISOString(),
792
+ counts: {
793
+ total: reviewRecords.length,
794
+ needsSemanticReview: needsReview.length,
795
+ },
796
+ files: reviewRecords,
797
+ }, null, 2) + "\n", "utf8");
798
+ if (needsReview.length > 0) {
799
+ const snapshotsRoot = path.join(runDir, "snapshots");
800
+ for (const [rel, snap] of reviewSnapshots.entries()) {
801
+ const variants = [
802
+ ["current", snap.currentText],
803
+ ["incoming", snap.incomingText],
804
+ ["baseline", snap.baselineText],
805
+ ["proposed", snap.proposedText],
806
+ ];
807
+ for (const [variant, text] of variants) {
808
+ if (text === null)
809
+ continue;
810
+ const outPath = path.join(snapshotsRoot, variant, rel);
811
+ await mkdir(path.dirname(outPath), { recursive: true });
812
+ await writeFile(outPath, text, "utf8");
813
+ }
814
+ }
815
+ }
816
+ const relRunDir = path.relative(resolved.gitRoot, runDir);
817
+ process.stdout.write(`Upgrade plan written: ${relRunDir}\n`);
818
+ process.stdout.write(`Prompt merge required: ${needsReview.length} files\n`);
819
+ if (needsReview.length > 0) {
820
+ process.stdout.write(`Hint: Create an UPGRADER task and attach ${relRunDir}\n`);
821
+ }
708
822
  return 0;
709
823
  }
710
824
  for (const rel of [...additions, ...updates]) {
@@ -716,36 +830,32 @@ export async function cmdUpgradeParsed(opts) {
716
830
  const data = fileContents.get(rel);
717
831
  if (data) {
718
832
  if (rel === "AGENTS.md") {
719
- // Write the managed copy under .agentplane/ and keep the workspace-root policy path
720
- // as a symlink to it.
721
- const managedPath = path.join(resolved.agentplaneDir, "AGENTS.md");
722
- await mkdir(path.dirname(managedPath), { recursive: true });
723
- await writeFile(managedPath, data);
724
- // Replace AGENTS.md with a symlink if needed.
725
- const relTarget = path.relative(resolved.gitRoot, managedPath);
833
+ // If AGENTS.md is a symlink, avoid overwriting an arbitrary external target.
834
+ // This permits repo-internal symlinks (e.g. the agentplane repo itself) while
835
+ // keeping user workspaces safe.
726
836
  try {
727
837
  const st = await lstat(destPath);
728
838
  if (st.isSymbolicLink()) {
729
- const currentTarget = await readlink(destPath);
730
- if (currentTarget !== relTarget) {
731
- await rm(destPath, { force: true });
839
+ const linkTarget = await readlink(destPath);
840
+ const targetAbs = path.resolve(path.dirname(destPath), linkTarget);
841
+ const relFromRoot = path.relative(resolved.gitRoot, targetAbs);
842
+ if (relFromRoot.startsWith("..") || path.isAbsolute(relFromRoot)) {
843
+ throw new CliError({
844
+ exitCode: exitCodeForError("E_VALIDATION"),
845
+ code: "E_VALIDATION",
846
+ message: `Refusing to overwrite symlinked AGENTS.md target outside repo: ${linkTarget}. ` +
847
+ "Replace the symlink with a regular file and retry.",
848
+ });
732
849
  }
733
850
  }
734
- else {
735
- // If it's a regular file, remove it (backup already happened above when enabled).
736
- await rm(destPath, { force: true });
737
- }
738
851
  }
739
- catch {
740
- // destPath doesn't exist
852
+ catch (err) {
853
+ const code = err?.code;
854
+ if (code !== "ENOENT")
855
+ throw err;
741
856
  }
742
- if (!(await fileExists(destPath))) {
743
- await symlink(relTarget, destPath);
744
- }
745
- }
746
- else {
747
- await writeFile(destPath, data);
748
857
  }
858
+ await writeFile(destPath, data);
749
859
  }
750
860
  // Record a baseline copy for future three-way merges.
751
861
  const baselineKey = toBaselineKey(rel);
@@ -766,6 +876,14 @@ export async function cmdUpgradeParsed(opts) {
766
876
  source: bundleLayout,
767
877
  updated: { add: additions.length, update: updates.length, unchanged: skipped.length },
768
878
  }, null, 2) + "\n", "utf8");
879
+ await writeFile(path.join(upgradeStateDir, "last-review.json"), JSON.stringify({
880
+ generated_at: new Date().toISOString(),
881
+ counts: {
882
+ total: reviewRecords.length,
883
+ needsSemanticReview: reviewRecords.filter((r) => r.needsSemanticReview).length,
884
+ },
885
+ files: reviewRecords,
886
+ }, null, 2) + "\n", "utf8");
769
887
  process.stdout.write(`Upgrade applied: ${additions.length} add, ${updates.length} update, ${skipped.length} unchanged\n`);
770
888
  return 0;
771
889
  }
@@ -1,16 +1,4 @@
1
- import type { CommandCtx, CommandSpec } from "../cli/spec/spec.js";
2
- import type { CommandContext } from "./shared/task-backend.js";
3
- type VerifyState = "ok" | "needs_rework";
4
- export type VerifyParsed = {
5
- taskId: string;
6
- state: VerifyState;
7
- by: string;
8
- note: string;
9
- details?: string;
10
- file?: string;
11
- quiet: boolean;
12
- };
13
- export declare const verifySpec: CommandSpec<VerifyParsed>;
14
- export declare function makeRunVerifyHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: VerifyParsed) => Promise<number>;
15
- export {};
1
+ export { verifySpec } from "./verify.spec.js";
2
+ export type { VerifyParsed } from "./verify.spec.js";
3
+ export { makeRunVerifyHandler } from "./verify.run.js";
16
4
  //# sourceMappingURL=verify.command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify.command.d.ts","sourceRoot":"","sources":["../../src/commands/verify.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D,KAAK,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CA8FhD,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACrE,KAAK,UAAU,EAAE,GAAG,YAAY,KAAG,OAAO,CAAC,MAAM,CAAC,CAcjE"}
1
+ {"version":3,"file":"verify.command.d.ts","sourceRoot":"","sources":["../../src/commands/verify.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,113 +1,2 @@
1
- import { usageError } from "../cli/spec/errors.js";
2
- import { cmdVerifyParsed } from "./task/verify-record.js";
3
- export const verifySpec = {
4
- id: ["verify"],
5
- group: "Lifecycle",
6
- summary: "Record a verification outcome for a task (record-only; does not execute commands).",
7
- args: [
8
- {
9
- name: "task-id",
10
- required: true,
11
- valueHint: "<task-id>",
12
- description: "Existing task id.",
13
- },
14
- ],
15
- options: [
16
- {
17
- kind: "boolean",
18
- name: "ok",
19
- default: false,
20
- description: "Record an OK verification outcome.",
21
- },
22
- {
23
- kind: "boolean",
24
- name: "rework",
25
- default: false,
26
- description: "Record a needs-rework verification outcome.",
27
- },
28
- {
29
- kind: "string",
30
- name: "by",
31
- valueHint: "<id>",
32
- required: true,
33
- description: "Verifier id (e.g. REVIEWER).",
34
- },
35
- {
36
- kind: "string",
37
- name: "note",
38
- valueHint: "<text>",
39
- required: true,
40
- description: "Short note describing the verification outcome.",
41
- },
42
- {
43
- kind: "string",
44
- name: "details",
45
- valueHint: "<text>",
46
- description: "Optional free-form details (mutually exclusive with --file).",
47
- },
48
- {
49
- kind: "string",
50
- name: "file",
51
- valueHint: "<path>",
52
- description: "Read details from a file path (mutually exclusive with --details).",
53
- },
54
- { kind: "boolean", name: "quiet", default: false, description: "Suppress output." },
55
- ],
56
- examples: [
57
- {
58
- cmd: 'agentplane verify 202602030608-F1Q8AB --ok --by REVIEWER --note "Looks good" --quiet',
59
- why: "Record an OK verification outcome.",
60
- },
61
- {
62
- cmd: 'agentplane verify 202602030608-F1Q8AB --rework --by REVIEWER --note "Needs changes" --details "Missing tests"',
63
- why: "Record a needs-rework outcome with details.",
64
- },
65
- ],
66
- validateRaw: (raw) => {
67
- const ok = raw.opts.ok === true;
68
- const rework = raw.opts.rework === true;
69
- if (ok === rework) {
70
- throw usageError({
71
- spec: verifySpec,
72
- command: "verify",
73
- message: "Exactly one of --ok or --rework must be provided.",
74
- });
75
- }
76
- if (typeof raw.opts.details === "string" && typeof raw.opts.file === "string") {
77
- throw usageError({
78
- spec: verifySpec,
79
- command: "verify",
80
- message: "Options --details and --file are mutually exclusive.",
81
- });
82
- }
83
- },
84
- parse: (raw) => {
85
- const ok = raw.opts.ok === true;
86
- const state = ok ? "ok" : "needs_rework";
87
- return {
88
- taskId: typeof raw.args["task-id"] === "string" ? raw.args["task-id"] : "",
89
- state,
90
- by: raw.opts.by,
91
- note: raw.opts.note,
92
- details: raw.opts.details,
93
- file: raw.opts.file,
94
- quiet: raw.opts.quiet === true,
95
- };
96
- },
97
- };
98
- export function makeRunVerifyHandler(getCtx) {
99
- return async (ctx, p) => {
100
- return await cmdVerifyParsed({
101
- ctx: await getCtx("verify"),
102
- cwd: ctx.cwd,
103
- rootOverride: ctx.rootOverride,
104
- taskId: p.taskId,
105
- state: p.state,
106
- by: p.by,
107
- note: p.note,
108
- details: p.details,
109
- file: p.file,
110
- quiet: p.quiet,
111
- });
112
- };
113
- }
1
+ export { verifySpec } from "./verify.spec.js";
2
+ export { makeRunVerifyHandler } from "./verify.run.js";
@@ -0,0 +1,5 @@
1
+ import type { CommandCtx } from "../cli/spec/spec.js";
2
+ import type { CommandContext } from "./shared/task-backend.js";
3
+ import type { VerifyParsed } from "./verify.spec.js";
4
+ export declare function makeRunVerifyHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: VerifyParsed) => Promise<number>;
5
+ //# sourceMappingURL=verify.run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.run.d.ts","sourceRoot":"","sources":["../../src/commands/verify.run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACrE,KAAK,UAAU,EAAE,GAAG,YAAY,KAAG,OAAO,CAAC,MAAM,CAAC,CAcjE"}
@@ -0,0 +1,17 @@
1
+ import { cmdVerifyParsed } from "./task/verify-record.js";
2
+ export function makeRunVerifyHandler(getCtx) {
3
+ return async (ctx, p) => {
4
+ return await cmdVerifyParsed({
5
+ ctx: await getCtx("verify"),
6
+ cwd: ctx.cwd,
7
+ rootOverride: ctx.rootOverride,
8
+ taskId: p.taskId,
9
+ state: p.state,
10
+ by: p.by,
11
+ note: p.note,
12
+ details: p.details,
13
+ file: p.file,
14
+ quiet: p.quiet,
15
+ });
16
+ };
17
+ }
@@ -0,0 +1,14 @@
1
+ import type { CommandSpec } from "../cli/spec/spec.js";
2
+ type VerifyState = "ok" | "needs_rework";
3
+ export type VerifyParsed = {
4
+ taskId: string;
5
+ state: VerifyState;
6
+ by: string;
7
+ note: string;
8
+ details?: string;
9
+ file?: string;
10
+ quiet: boolean;
11
+ };
12
+ export declare const verifySpec: CommandSpec<VerifyParsed>;
13
+ export {};
14
+ //# sourceMappingURL=verify.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.spec.d.ts","sourceRoot":"","sources":["../../src/commands/verify.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,KAAK,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CA8FhD,CAAC"}