agentplane 0.3.4 → 0.3.6

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 (217) hide show
  1. package/README.md +103 -75
  2. package/assets/AGENTS.md +4 -2
  3. package/bin/dist-guard.js +13 -3
  4. package/bin/runtime-watch.d.ts +1 -0
  5. package/bin/runtime-watch.js +22 -5
  6. package/bin/stale-dist-policy.js +9 -2
  7. package/dist/.build-manifest.json +220 -790
  8. package/dist/adapters/task-backend/task-backend-adapter.d.ts +1 -1
  9. package/dist/adapters/task-backend/task-backend-adapter.d.ts.map +1 -1
  10. package/dist/adapters/task-backend/task-backend-adapter.js +5 -2
  11. package/dist/backends/task-backend/local-backend.d.ts +13 -0
  12. package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
  13. package/dist/backends/task-backend/local-backend.js +17 -0
  14. package/dist/backends/task-backend/redmine-backend.d.ts +18 -0
  15. package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
  16. package/dist/backends/task-backend/redmine-backend.js +35 -25
  17. package/dist/backends/task-backend/shared/types.d.ts +20 -0
  18. package/dist/backends/task-backend/shared/types.d.ts.map +1 -1
  19. package/dist/backends/task-backend/shared.d.ts +1 -1
  20. package/dist/backends/task-backend/shared.d.ts.map +1 -1
  21. package/dist/backends/task-backend.d.ts +1 -1
  22. package/dist/backends/task-backend.d.ts.map +1 -1
  23. package/dist/backends/task-backend.test-helpers.d.ts +4 -0
  24. package/dist/backends/task-backend.test-helpers.d.ts.map +1 -0
  25. package/dist/backends/task-backend.test-helpers.js +33 -0
  26. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  27. package/dist/cli/bootstrap-guide.js +1 -0
  28. package/dist/cli/command-guide.d.ts.map +1 -1
  29. package/dist/cli/command-guide.js +3 -2
  30. package/dist/cli/reason-codes.d.ts.map +1 -1
  31. package/dist/cli/reason-codes.js +30 -0
  32. package/dist/cli/run-cli/command-catalog/core.d.ts +3 -0
  33. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -0
  34. package/dist/cli/run-cli/command-catalog/core.js +137 -0
  35. package/dist/cli/run-cli/command-catalog/lifecycle.d.ts +3 -0
  36. package/dist/cli/run-cli/command-catalog/lifecycle.d.ts.map +1 -0
  37. package/dist/cli/run-cli/command-catalog/lifecycle.js +52 -0
  38. package/dist/cli/run-cli/command-catalog/project.d.ts +3 -0
  39. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -0
  40. package/dist/cli/run-cli/command-catalog/project.js +78 -0
  41. package/dist/cli/run-cli/command-catalog/shared.d.ts +19 -0
  42. package/dist/cli/run-cli/command-catalog/shared.d.ts.map +1 -0
  43. package/dist/cli/run-cli/command-catalog/shared.js +9 -0
  44. package/dist/cli/run-cli/command-catalog/task.d.ts +3 -0
  45. package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -0
  46. package/dist/cli/run-cli/command-catalog/task.js +85 -0
  47. package/dist/cli/run-cli/command-catalog.d.ts +3 -18
  48. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  49. package/dist/cli/run-cli/command-catalog.js +8 -337
  50. package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
  51. package/dist/cli/run-cli/commands/ide.js +64 -2
  52. package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
  53. package/dist/cli/run-cli/commands/init/ui.js +33 -13
  54. package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts +3 -0
  55. package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts.map +1 -0
  56. package/dist/cli/run-cli.core.pr-flow.test-helpers.js +41 -0
  57. package/dist/cli/run-cli.core.tasks.test-helpers.d.ts +2 -0
  58. package/dist/cli/run-cli.core.tasks.test-helpers.d.ts.map +1 -0
  59. package/dist/cli/run-cli.core.tasks.test-helpers.js +6 -0
  60. package/dist/cli/run-cli.test-helpers.d.ts +3 -0
  61. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  62. package/dist/cli/run-cli.test-helpers.js +138 -6
  63. package/dist/commands/commit.spec.d.ts.map +1 -1
  64. package/dist/commands/commit.spec.js +2 -2
  65. package/dist/commands/doctor/runtime.d.ts.map +1 -1
  66. package/dist/commands/doctor/runtime.js +3 -6
  67. package/dist/commands/doctor/workspace.d.ts +4 -1
  68. package/dist/commands/doctor/workspace.d.ts.map +1 -1
  69. package/dist/commands/doctor/workspace.js +87 -4
  70. package/dist/commands/doctor.run.d.ts.map +1 -1
  71. package/dist/commands/doctor.run.js +8 -1
  72. package/dist/commands/guard/commit.command.js +1 -1
  73. package/dist/commands/guard/impl/allow.d.ts +5 -0
  74. package/dist/commands/guard/impl/allow.d.ts.map +1 -1
  75. package/dist/commands/guard/impl/allow.js +15 -10
  76. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  77. package/dist/commands/guard/impl/commands.js +137 -18
  78. package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
  79. package/dist/commands/guard/impl/comment-commit.js +2 -0
  80. package/dist/commands/hooks/index.d.ts.map +1 -1
  81. package/dist/commands/hooks/index.js +8 -35
  82. package/dist/commands/recipes/impl/apply.d.ts +4 -0
  83. package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
  84. package/dist/commands/recipes/impl/apply.js +34 -0
  85. package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
  86. package/dist/commands/recipes/impl/commands/explain.js +70 -11
  87. package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
  88. package/dist/commands/recipes/impl/commands/info.js +24 -12
  89. package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
  90. package/dist/commands/recipes/impl/commands/install.js +32 -36
  91. package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
  92. package/dist/commands/recipes/impl/commands/list.js +7 -4
  93. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  94. package/dist/commands/recipes/impl/commands/remove.js +9 -11
  95. package/dist/commands/recipes/impl/constants.d.ts +2 -0
  96. package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
  97. package/dist/commands/recipes/impl/constants.js +2 -0
  98. package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
  99. package/dist/commands/recipes/impl/manifest.js +219 -23
  100. package/dist/commands/recipes/impl/normalize.d.ts +3 -0
  101. package/dist/commands/recipes/impl/normalize.d.ts.map +1 -1
  102. package/dist/commands/recipes/impl/normalize.js +28 -24
  103. package/dist/commands/recipes/impl/paths.d.ts +9 -0
  104. package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
  105. package/dist/commands/recipes/impl/paths.js +10 -1
  106. package/dist/commands/recipes/impl/project-installed-recipes.d.ts +7 -0
  107. package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -0
  108. package/dist/commands/recipes/impl/project-installed-recipes.js +102 -0
  109. package/dist/commands/recipes/impl/resolver.d.ts +20 -0
  110. package/dist/commands/recipes/impl/resolver.d.ts.map +1 -0
  111. package/dist/commands/recipes/impl/resolver.js +220 -0
  112. package/dist/commands/recipes/impl/scenario.d.ts.map +1 -1
  113. package/dist/commands/recipes/impl/scenario.js +40 -11
  114. package/dist/commands/recipes/impl/types.d.ts +145 -16
  115. package/dist/commands/recipes/impl/types.d.ts.map +1 -1
  116. package/dist/commands/recipes/install.spec.d.ts.map +1 -1
  117. package/dist/commands/recipes/install.spec.js +3 -2
  118. package/dist/commands/recipes.d.ts +6 -4
  119. package/dist/commands/recipes.d.ts.map +1 -1
  120. package/dist/commands/recipes.js +5 -3
  121. package/dist/commands/recipes.test-helpers.d.ts +185 -0
  122. package/dist/commands/recipes.test-helpers.d.ts.map +1 -0
  123. package/dist/commands/recipes.test-helpers.js +339 -0
  124. package/dist/commands/scenario/impl/commands.d.ts.map +1 -1
  125. package/dist/commands/scenario/impl/commands.js +192 -336
  126. package/dist/commands/scenario/info.command.d.ts.map +1 -1
  127. package/dist/commands/scenario/info.command.js +7 -2
  128. package/dist/commands/scenario/list.command.js +2 -2
  129. package/dist/commands/scenario/run.command.d.ts.map +1 -1
  130. package/dist/commands/scenario/run.command.js +7 -2
  131. package/dist/commands/shared/git-context.d.ts +1 -0
  132. package/dist/commands/shared/git-context.d.ts.map +1 -1
  133. package/dist/commands/shared/git-context.js +4 -0
  134. package/dist/commands/shared/reconcile-check.d.ts.map +1 -1
  135. package/dist/commands/shared/reconcile-check.js +77 -2
  136. package/dist/commands/shared/task-backend.d.ts +5 -0
  137. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  138. package/dist/commands/shared/task-backend.js +24 -0
  139. package/dist/commands/shared/task-store.d.ts +32 -1
  140. package/dist/commands/shared/task-store.d.ts.map +1 -1
  141. package/dist/commands/shared/task-store.js +166 -42
  142. package/dist/commands/task/block.d.ts.map +1 -1
  143. package/dist/commands/task/block.js +46 -29
  144. package/dist/commands/task/close-duplicate.d.ts.map +1 -1
  145. package/dist/commands/task/close-duplicate.js +12 -37
  146. package/dist/commands/task/close-noop.d.ts.map +1 -1
  147. package/dist/commands/task/close-noop.js +12 -30
  148. package/dist/commands/task/close-shared.d.ts +14 -0
  149. package/dist/commands/task/close-shared.d.ts.map +1 -0
  150. package/dist/commands/task/close-shared.js +76 -0
  151. package/dist/commands/task/comment.d.ts.map +1 -1
  152. package/dist/commands/task/comment.js +35 -17
  153. package/dist/commands/task/doc-set.command.d.ts +2 -1
  154. package/dist/commands/task/doc-set.command.d.ts.map +1 -1
  155. package/dist/commands/task/doc-set.command.js +36 -4
  156. package/dist/commands/task/doc-template.d.ts.map +1 -1
  157. package/dist/commands/task/doc-template.js +2 -7
  158. package/dist/commands/task/doc.command.js +1 -1
  159. package/dist/commands/task/doc.d.ts +2 -1
  160. package/dist/commands/task/doc.d.ts.map +1 -1
  161. package/dist/commands/task/doc.js +123 -71
  162. package/dist/commands/task/export.d.ts.map +1 -1
  163. package/dist/commands/task/export.js +4 -4
  164. package/dist/commands/task/finish.d.ts.map +1 -1
  165. package/dist/commands/task/finish.js +141 -78
  166. package/dist/commands/task/migrate-doc.d.ts.map +1 -1
  167. package/dist/commands/task/migrate-doc.js +15 -11
  168. package/dist/commands/task/plan-set.command.js +1 -1
  169. package/dist/commands/task/plan.command.d.ts +8 -0
  170. package/dist/commands/task/plan.command.d.ts.map +1 -0
  171. package/dist/commands/task/plan.command.js +37 -0
  172. package/dist/commands/task/plan.d.ts.map +1 -1
  173. package/dist/commands/task/plan.js +190 -93
  174. package/dist/commands/task/set-status.command.d.ts.map +1 -1
  175. package/dist/commands/task/set-status.command.js +1 -1
  176. package/dist/commands/task/set-status.d.ts.map +1 -1
  177. package/dist/commands/task/set-status.js +40 -3
  178. package/dist/commands/task/shared/docs.d.ts +1 -0
  179. package/dist/commands/task/shared/docs.d.ts.map +1 -1
  180. package/dist/commands/task/shared/docs.js +7 -0
  181. package/dist/commands/task/shared/transitions.d.ts +0 -2
  182. package/dist/commands/task/shared/transitions.d.ts.map +1 -1
  183. package/dist/commands/task/shared/transitions.js +0 -6
  184. package/dist/commands/task/shared.d.ts +2 -2
  185. package/dist/commands/task/shared.d.ts.map +1 -1
  186. package/dist/commands/task/shared.js +2 -2
  187. package/dist/commands/task/start.d.ts.map +1 -1
  188. package/dist/commands/task/start.js +88 -63
  189. package/dist/commands/task/task.command.d.ts +8 -0
  190. package/dist/commands/task/task.command.d.ts.map +1 -0
  191. package/dist/commands/task/task.command.js +71 -0
  192. package/dist/commands/task/verify-command-shared.d.ts +16 -0
  193. package/dist/commands/task/verify-command-shared.d.ts.map +1 -0
  194. package/dist/commands/task/verify-command-shared.js +53 -0
  195. package/dist/commands/task/verify-ok.command.d.ts +2 -6
  196. package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
  197. package/dist/commands/task/verify-ok.command.js +8 -50
  198. package/dist/commands/task/verify-record.d.ts.map +1 -1
  199. package/dist/commands/task/verify-record.js +119 -140
  200. package/dist/commands/task/verify-rework.command.d.ts +2 -6
  201. package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
  202. package/dist/commands/task/verify-rework.command.js +8 -50
  203. package/dist/commands/verify.spec.d.ts.map +1 -1
  204. package/dist/commands/verify.spec.js +3 -12
  205. package/dist/policy/rules/allowlist.d.ts.map +1 -1
  206. package/dist/policy/rules/allowlist.js +13 -4
  207. package/dist/policy/rules/protected-paths.d.ts.map +1 -1
  208. package/dist/policy/rules/protected-paths.js +6 -1
  209. package/dist/ports/task-backend-port.d.ts +1 -1
  210. package/dist/ports/task-backend-port.d.ts.map +1 -1
  211. package/dist/shared/agent-emoji.d.ts.map +1 -1
  212. package/dist/shared/protected-paths.d.ts +7 -0
  213. package/dist/shared/protected-paths.d.ts.map +1 -1
  214. package/dist/shared/protected-paths.js +26 -10
  215. package/dist/shared/repo-cli-version.d.ts.map +1 -1
  216. package/dist/shared/repo-cli-version.js +9 -3
  217. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  import { mapBackendError } from "../../cli/error-map.js";
2
- import { invalidValueMessage, successMessage, warnMessage } from "../../cli/output.js";
2
+ import { infoMessage, successMessage, warnMessage } from "../../cli/output.js";
3
3
  import { formatCommentBodyForCommit } from "../../shared/comment-format.js";
4
4
  import { CliError } from "../../shared/errors.js";
5
5
  import { commitFromComment } from "../guard/index.js";
@@ -7,7 +7,43 @@ import { ensureActionApproved } from "../shared/approval-requirements.js";
7
7
  import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
8
8
  import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
9
9
  import { readDirectWorkLock } from "../../shared/direct-work-lock.js";
10
- import { appendTaskEvent, ensurePlanApprovedIfRequired, ensureCommentCommitAllowed, ensureStatusTransitionAllowed, extractTaskObservationSection, defaultCommitEmojiForAgentId, extractDocSection, isVerifyStepsFilled, normalizeTaskDocVersion, nowIso, requiresVerifyStepsByPrimary, requireStructuredComment, resolveTaskDependencyState, resolvePrimaryTag, taskObservationSectionName, toStringArray, } from "./shared.js";
10
+ import { appendTaskEvent, ensurePlanApprovedIfRequired, ensureCommentCommitAllowed, ensureStatusTransitionAllowed, extractTaskObservationSection, defaultCommitEmojiForStatus, extractDocSection, isVerifyStepsFilled, normalizeTaskDocVersion, nowIso, requiresVerifyStepsByPrimary, requireStructuredComment, resolveTaskDependencyState, resolvePrimaryTag, taskObservationSectionName, toStringArray, } from "./shared.js";
11
+ function assertStartDocRequirements(task, config) {
12
+ if (config.agents?.approvals?.require_plan === true)
13
+ return;
14
+ const enforce = config.tasks.verify.enforce_on_start_when_no_plan !== false;
15
+ if (!enforce)
16
+ return;
17
+ const tags = toStringArray(task.tags);
18
+ const spikeTag = (config.tasks.verify.spike_tag ?? "spike").trim().toLowerCase();
19
+ const verifyRequired = requiresVerifyStepsByPrimary(tags, config);
20
+ const isSpike = tags.some((tag) => tag.trim().toLowerCase() === spikeTag);
21
+ const doc = typeof task.doc === "string" ? task.doc : "";
22
+ if (verifyRequired || isSpike) {
23
+ const verifySteps = extractDocSection(doc, "Verify Steps");
24
+ if (!isVerifyStepsFilled(verifySteps)) {
25
+ throw new CliError({
26
+ exitCode: 3,
27
+ code: "E_VALIDATION",
28
+ message: `${task.id}: cannot start work: ## Verify Steps section is missing/empty/unfilled ` +
29
+ "(fill it before starting work when plan approval is disabled)",
30
+ });
31
+ }
32
+ }
33
+ if (!isSpike)
34
+ return;
35
+ const docVersion = normalizeTaskDocVersion(task.doc_version);
36
+ const observationSection = taskObservationSectionName(docVersion);
37
+ const observation = extractTaskObservationSection(doc, docVersion);
38
+ if (!observation || observation.trim().length === 0) {
39
+ throw new CliError({
40
+ exitCode: 3,
41
+ code: "E_VALIDATION",
42
+ message: `${task.id}: cannot start spike: ## ${observationSection} section is missing or empty ` +
43
+ "(include Findings/Decision/Next Steps)",
44
+ });
45
+ }
46
+ }
11
47
  export async function cmdStart(opts) {
12
48
  try {
13
49
  const ctx = opts.ctx ??
@@ -27,40 +63,7 @@ export async function cmdStart(opts) {
27
63
  const task = useStore
28
64
  ? await store.get(opts.taskId)
29
65
  : await loadTaskFromContext({ ctx, taskId: opts.taskId });
30
- if (ctx.config.agents?.approvals?.require_plan !== true) {
31
- const enforce = ctx.config.tasks.verify.enforce_on_start_when_no_plan !== false;
32
- if (enforce) {
33
- const tags = toStringArray(task.tags);
34
- const spikeTag = (ctx.config.tasks.verify.spike_tag ?? "spike").trim().toLowerCase();
35
- const verifyRequired = requiresVerifyStepsByPrimary(tags, ctx.config);
36
- const isSpike = tags.some((tag) => tag.trim().toLowerCase() === spikeTag);
37
- const doc = typeof task.doc === "string" ? task.doc : "";
38
- if (verifyRequired || isSpike) {
39
- const verifySteps = extractDocSection(doc, "Verify Steps");
40
- if (!isVerifyStepsFilled(verifySteps)) {
41
- throw new CliError({
42
- exitCode: 3,
43
- code: "E_VALIDATION",
44
- message: `${task.id}: cannot start work: ## Verify Steps section is missing/empty/unfilled ` +
45
- "(fill it before starting work when plan approval is disabled)",
46
- });
47
- }
48
- }
49
- if (isSpike) {
50
- const docVersion = normalizeTaskDocVersion(task.doc_version);
51
- const observationSection = taskObservationSectionName(docVersion);
52
- const observation = extractTaskObservationSection(doc, docVersion);
53
- if (!observation || observation.trim().length === 0) {
54
- throw new CliError({
55
- exitCode: 3,
56
- code: "E_VALIDATION",
57
- message: `${task.id}: cannot start spike: ## ${observationSection} section is missing or empty ` +
58
- "(include Findings/Decision/Next Steps)",
59
- });
60
- }
61
- }
62
- }
63
- }
66
+ assertStartDocRequirements(task, ctx.config);
64
67
  ensurePlanApprovedIfRequired(task, ctx.config);
65
68
  const currentStatus = String(task.status || "TODO").toUpperCase();
66
69
  ensureStatusTransitionAllowed({
@@ -107,27 +110,57 @@ export async function cmdStart(opts) {
107
110
  { author: opts.author, body: commentBody },
108
111
  ];
109
112
  const at = nowIso();
110
- const nextTask = {
111
- ...task,
112
- status: "DOING",
113
- comments: commentsValue,
114
- events: appendTaskEvent(task, {
115
- type: "status",
116
- at,
117
- author: opts.author,
118
- from: currentStatus,
119
- to: "DOING",
120
- note: commentBody,
121
- }),
122
- doc_version: normalizeTaskDocVersion(task.doc_version),
123
- doc_updated_at: at,
124
- doc_updated_by: opts.author,
125
- };
126
113
  await (useStore
127
- ? store.update(opts.taskId, () => nextTask)
128
- : ctx.taskBackend.writeTask(nextTask));
114
+ ? store.patch(opts.taskId, (current) => {
115
+ assertStartDocRequirements(current, ctx.config);
116
+ ensurePlanApprovedIfRequired(current, ctx.config);
117
+ const currentStatus = String(current.status || "TODO").toUpperCase();
118
+ ensureStatusTransitionAllowed({
119
+ currentStatus,
120
+ nextStatus: "DOING",
121
+ force: opts.force,
122
+ });
123
+ return {
124
+ task: { status: "DOING" },
125
+ appendComments: [{ author: opts.author, body: commentBody }],
126
+ appendEvents: [
127
+ {
128
+ type: "status",
129
+ at,
130
+ author: opts.author,
131
+ from: currentStatus,
132
+ to: "DOING",
133
+ note: commentBody,
134
+ },
135
+ ],
136
+ docMeta: {
137
+ touch: true,
138
+ updatedBy: opts.author,
139
+ version: normalizeTaskDocVersion(current.doc_version),
140
+ },
141
+ };
142
+ })
143
+ : ctx.taskBackend.writeTask({
144
+ ...task,
145
+ status: "DOING",
146
+ comments: commentsValue,
147
+ events: appendTaskEvent(task, {
148
+ type: "status",
149
+ at,
150
+ author: opts.author,
151
+ from: currentStatus,
152
+ to: "DOING",
153
+ note: commentBody,
154
+ }),
155
+ doc_version: normalizeTaskDocVersion(task.doc_version),
156
+ doc_updated_at: at,
157
+ doc_updated_by: opts.author,
158
+ }));
129
159
  let commitInfo = null;
130
160
  if (opts.commitFromComment) {
161
+ if (!opts.quiet) {
162
+ process.stdout.write(`${infoMessage("task marked DOING; creating commit from start comment")}\n`);
163
+ }
131
164
  const mode = ctx.config.workflow_mode;
132
165
  let executorAgent = opts.author;
133
166
  if (mode === "direct") {
@@ -136,14 +169,6 @@ export async function cmdStart(opts) {
136
169
  if (lockAgent)
137
170
  executorAgent = lockAgent;
138
171
  }
139
- const expectedEmoji = await defaultCommitEmojiForAgentId(ctx, executorAgent);
140
- if (typeof opts.commitEmoji === "string" && opts.commitEmoji.trim() !== expectedEmoji) {
141
- throw new CliError({
142
- exitCode: 2,
143
- code: "E_USAGE",
144
- message: invalidValueMessage("--commit-emoji", opts.commitEmoji, `${expectedEmoji} (executor agent=${executorAgent})`),
145
- });
146
- }
147
172
  commitInfo = await commitFromComment({
148
173
  ctx,
149
174
  cwd: opts.cwd,
@@ -156,7 +181,7 @@ export async function cmdStart(opts) {
156
181
  statusTo: "DOING",
157
182
  commentBody: opts.body,
158
183
  formattedComment,
159
- emoji: opts.commitEmoji ?? expectedEmoji,
184
+ emoji: opts.commitEmoji ?? defaultCommitEmojiForStatus("DOING"),
160
185
  allow: opts.commitAllow,
161
186
  autoAllow: opts.commitAutoAllow || opts.commitAllow.length === 0,
162
187
  allowTasks: opts.commitAllowTasks,
@@ -0,0 +1,8 @@
1
+ import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
2
+ type TaskGroupParsed = {
3
+ cmd: string[];
4
+ };
5
+ export declare const taskSpec: CommandSpec<TaskGroupParsed>;
6
+ export declare const runTask: CommandHandler<TaskGroupParsed>;
7
+ export {};
8
+ //# sourceMappingURL=task.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/task.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAItF,KAAK,eAAe,GAAG;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AA6BzC,eAAO,MAAM,QAAQ,EAAE,WAAW,CAAC,eAAe,CA8BjD,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,cAAc,CAAC,eAAe,CAWnD,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { usageError } from "../../cli/spec/errors.js";
2
+ import { suggestOne } from "../../cli/spec/suggest.js";
3
+ const TASK_SUBCOMMANDS = [
4
+ "add",
5
+ "close-duplicate",
6
+ "close-noop",
7
+ "comment",
8
+ "derive",
9
+ "doc",
10
+ "export",
11
+ "lint",
12
+ "list",
13
+ "migrate",
14
+ "migrate-doc",
15
+ "new",
16
+ "next",
17
+ "normalize",
18
+ "plan",
19
+ "rebuild-index",
20
+ "scrub",
21
+ "search",
22
+ "set-status",
23
+ "show",
24
+ "start-ready",
25
+ "update",
26
+ "verify",
27
+ "verify-show",
28
+ ];
29
+ export const taskSpec = {
30
+ id: ["task"],
31
+ group: "Task",
32
+ summary: "Task lifecycle and task-store commands.",
33
+ synopsis: ["agentplane task <subcommand> [args] [options]"],
34
+ args: [{ name: "cmd", required: false, variadic: true, valueHint: "<subcommand>" }],
35
+ notes: [
36
+ "Direct task route: task new -> task plan set -> task plan approve -> task start-ready -> task verify-show -> verify -> finish.",
37
+ "Use `agentplane help task plan`, `agentplane help task doc`, and `agentplane help task verify` to inspect task sub-areas.",
38
+ "Verification recording and closure stay top-level lifecycle commands: `agentplane verify ...` and `agentplane finish ...`.",
39
+ ],
40
+ examples: [
41
+ {
42
+ cmd: 'agentplane task new --title "..." --description "..." --owner CODER --tag code',
43
+ why: "Create a task.",
44
+ },
45
+ {
46
+ cmd: 'agentplane task plan set <task-id> --text "..." --updated-by ORCHESTRATOR',
47
+ why: "Write the execution plan.",
48
+ },
49
+ {
50
+ cmd: 'agentplane task start-ready <task-id> --author CODER --body "Start: ..."',
51
+ why: "Start the task after approval.",
52
+ },
53
+ {
54
+ cmd: "agentplane task verify-show <task-id>",
55
+ why: "Show Verify Steps before running checks.",
56
+ },
57
+ ],
58
+ parse: (raw) => ({ cmd: (raw.args.cmd ?? []) }),
59
+ };
60
+ export const runTask = (_ctx, p) => {
61
+ const input = p.cmd.join(" ");
62
+ const suggestion = suggestOne(input, [...TASK_SUBCOMMANDS]);
63
+ const suffix = suggestion ? ` Did you mean: ${suggestion}?` : "";
64
+ const message = p.cmd.length === 0 ? "Missing subcommand." : `Unknown subcommand: ${p.cmd[0]}.`;
65
+ throw usageError({
66
+ spec: taskSpec,
67
+ command: "task",
68
+ message: `${message}${suffix}`,
69
+ context: { command: "task" },
70
+ });
71
+ };
@@ -0,0 +1,16 @@
1
+ import type { CommandSpec, OptionSpec, ParsedRaw } from "../../cli/spec/spec.js";
2
+ export type VerifyCommonParsed = {
3
+ by: string;
4
+ note: string;
5
+ details?: string;
6
+ file?: string;
7
+ quiet: boolean;
8
+ };
9
+ export declare const verifyCommonOptions: readonly OptionSpec[];
10
+ export declare function validateVerifyDetailsFileExclusive<TParsed>(raw: ParsedRaw, spec: CommandSpec<TParsed>, opts?: {
11
+ command?: string;
12
+ message?: string;
13
+ }): void;
14
+ export declare function validateVerifyNonEmptyInput<TParsed>(raw: ParsedRaw, spec: CommandSpec<TParsed>, name: "by" | "note"): void;
15
+ export declare function parseVerifyCommonOptions(raw: ParsedRaw): VerifyCommonParsed;
16
+ //# sourceMappingURL=verify-command-shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-command-shared.d.ts","sourceRoot":"","sources":["../../../src/commands/task/verify-command-shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEjF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,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,mBAAmB,EAAE,SAAS,UAAU,EA2B3C,CAAC;AAEX,wBAAgB,kCAAkC,CAAC,OAAO,EACxD,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,EAC1B,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,IAAI,CAQN;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EACjD,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,EAC1B,IAAI,EAAE,IAAI,GAAG,MAAM,GAClB,IAAI,CAKN;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,SAAS,GAAG,kBAAkB,CAQ3E"}
@@ -0,0 +1,53 @@
1
+ import { usageError } from "../../cli/spec/errors.js";
2
+ export const verifyCommonOptions = [
3
+ { kind: "string", name: "by", valueHint: "<id>", required: true, description: "Verifier id." },
4
+ {
5
+ kind: "string",
6
+ name: "note",
7
+ valueHint: "<text>",
8
+ required: true,
9
+ description: "Short verification note.",
10
+ },
11
+ {
12
+ kind: "string",
13
+ name: "details",
14
+ valueHint: "<text>",
15
+ description: "Optional details text (mutually exclusive with --file).",
16
+ },
17
+ {
18
+ kind: "string",
19
+ name: "file",
20
+ valueHint: "<path>",
21
+ description: "Optional details file path (mutually exclusive with --details).",
22
+ },
23
+ {
24
+ kind: "boolean",
25
+ name: "quiet",
26
+ default: false,
27
+ description: "Suppress normal output (still prints errors).",
28
+ },
29
+ ];
30
+ export function validateVerifyDetailsFileExclusive(raw, spec, opts) {
31
+ if (typeof raw.opts.details === "string" && typeof raw.opts.file === "string") {
32
+ throw usageError({
33
+ spec,
34
+ command: opts?.command,
35
+ message: opts?.message ?? "Options --details and --file are mutually exclusive.",
36
+ });
37
+ }
38
+ }
39
+ export function validateVerifyNonEmptyInput(raw, spec, name) {
40
+ const value = raw.opts[name];
41
+ if (typeof value === "string" && value.trim().length === 0) {
42
+ throw usageError({ spec, message: `Invalid value for --${name}: empty.` });
43
+ }
44
+ }
45
+ export function parseVerifyCommonOptions(raw) {
46
+ return {
47
+ by: typeof raw.opts.by === "string" ? raw.opts.by : "",
48
+ note: typeof raw.opts.note === "string" ? raw.opts.note : "",
49
+ details: typeof raw.opts.details === "string" ? raw.opts.details : undefined,
50
+ file: typeof raw.opts.file === "string" ? raw.opts.file : undefined,
51
+ quiet: raw.opts.quiet === true,
52
+ };
53
+ }
@@ -1,12 +1,8 @@
1
1
  import type { CommandCtx, CommandSpec } from "../../cli/spec/spec.js";
2
2
  import type { CommandContext } from "../shared/task-backend.js";
3
- export type TaskVerifyOkParsed = {
3
+ import { type VerifyCommonParsed } from "./verify-command-shared.js";
4
+ export type TaskVerifyOkParsed = VerifyCommonParsed & {
4
5
  taskId: string;
5
- by: string;
6
- note: string;
7
- details?: string;
8
- file?: string;
9
- quiet: boolean;
10
6
  };
11
7
  export declare const taskVerifyOkSpec: CommandSpec<TaskVerifyOkParsed>;
12
8
  export declare function makeRunTaskVerifyOkHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: TaskVerifyOkParsed) => Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"verify-ok.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/verify-ok.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,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,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAiE5D,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC3E,KAAK,UAAU,EAAE,GAAG,kBAAkB,KAAG,OAAO,CAAC,MAAM,CAAC,CAavE"}
1
+ {"version":3,"file":"verify-ok.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/verify-ok.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,kBAAkB,GAAG,kBAAkB,GAAG;IACpD,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAuB5D,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC3E,KAAK,UAAU,EAAE,GAAG,kBAAkB,KAAG,OAAO,CAAC,MAAM,CAAC,CAavE"}
@@ -1,38 +1,11 @@
1
- import { usageError } from "../../cli/spec/errors.js";
2
1
  import { cmdTaskVerifyOk } from "./verify-record.js";
2
+ import { parseVerifyCommonOptions, validateVerifyDetailsFileExclusive, validateVerifyNonEmptyInput, verifyCommonOptions, } from "./verify-command-shared.js";
3
3
  export const taskVerifyOkSpec = {
4
4
  id: ["task", "verify", "ok"],
5
5
  group: "Task",
6
6
  summary: "Record verification as OK (updates Verification section and verification frontmatter).",
7
7
  args: [{ name: "task-id", required: true, valueHint: "<task-id>" }],
8
- options: [
9
- { kind: "string", name: "by", valueHint: "<id>", required: true, description: "Verifier id." },
10
- {
11
- kind: "string",
12
- name: "note",
13
- valueHint: "<text>",
14
- required: true,
15
- description: "Short verification note.",
16
- },
17
- {
18
- kind: "string",
19
- name: "details",
20
- valueHint: "<text>",
21
- description: "Optional details text (mutually exclusive with --file).",
22
- },
23
- {
24
- kind: "string",
25
- name: "file",
26
- valueHint: "<path>",
27
- description: "Optional details file path (mutually exclusive with --details).",
28
- },
29
- {
30
- kind: "boolean",
31
- name: "quiet",
32
- default: false,
33
- description: "Suppress normal output (still prints errors).",
34
- },
35
- ],
8
+ options: verifyCommonOptions,
36
9
  examples: [
37
10
  {
38
11
  cmd: 'agentplane task verify ok 202602030608-F1Q8AB --by REVIEWER --note "Looks good"',
@@ -40,30 +13,15 @@ export const taskVerifyOkSpec = {
40
13
  },
41
14
  ],
42
15
  validateRaw: (raw) => {
43
- const details = raw.opts.details;
44
- const file = raw.opts.file;
45
- if (typeof details === "string" && typeof file === "string") {
46
- throw usageError({
47
- spec: taskVerifyOkSpec,
48
- message: "Provide at most one of --details or --file.",
49
- });
50
- }
51
- const by = raw.opts.by;
52
- if (typeof by === "string" && by.trim().length === 0) {
53
- throw usageError({ spec: taskVerifyOkSpec, message: "Invalid value for --by: empty." });
54
- }
55
- const note = raw.opts.note;
56
- if (typeof note === "string" && note.trim().length === 0) {
57
- throw usageError({ spec: taskVerifyOkSpec, message: "Invalid value for --note: empty." });
58
- }
16
+ validateVerifyDetailsFileExclusive(raw, taskVerifyOkSpec, {
17
+ message: "Provide at most one of --details or --file.",
18
+ });
19
+ validateVerifyNonEmptyInput(raw, taskVerifyOkSpec, "by");
20
+ validateVerifyNonEmptyInput(raw, taskVerifyOkSpec, "note");
59
21
  },
60
22
  parse: (raw) => ({
61
23
  taskId: String(raw.args["task-id"]),
62
- by: String(raw.opts.by),
63
- note: String(raw.opts.note),
64
- details: typeof raw.opts.details === "string" ? raw.opts.details : undefined,
65
- file: typeof raw.opts.file === "string" ? raw.opts.file : undefined,
66
- quiet: raw.opts.quiet === true,
24
+ ...parseVerifyCommonOptions(raw),
67
25
  }),
68
26
  };
69
27
  export function makeRunTaskVerifyOkHandler(getCtx) {
@@ -1 +1 @@
1
- {"version":3,"file":"verify-record.d.ts","sourceRoot":"","sources":["../../../src/commands/task/verify-record.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAanC,KAAK,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC;AAgJzC,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,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,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ClB;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,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,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ClB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,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,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ClB"}
1
+ {"version":3,"file":"verify-record.d.ts","sourceRoot":"","sources":["../../../src/commands/task/verify-record.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAanC,KAAK,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC;AAqRzC,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,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,GAAG,OAAO,CAAC,MAAM,CAAC,CAElB;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,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,GAAG,OAAO,CAAC,MAAM,CAAC,CAMlB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,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,GAAG,OAAO,CAAC,MAAM,CAAC,CAElB"}