agentplane 0.3.5 → 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.
- package/README.md +103 -75
- package/assets/AGENTS.md +4 -2
- package/bin/dist-guard.js +13 -3
- package/bin/runtime-watch.d.ts +1 -0
- package/bin/runtime-watch.js +22 -5
- package/bin/stale-dist-policy.js +9 -2
- package/dist/.build-manifest.json +196 -776
- package/dist/backends/task-backend.test-helpers.d.ts +4 -0
- package/dist/backends/task-backend.test-helpers.d.ts.map +1 -0
- package/dist/backends/task-backend.test-helpers.js +33 -0
- package/dist/cli/bootstrap-guide.d.ts.map +1 -1
- package/dist/cli/bootstrap-guide.js +1 -0
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +3 -2
- package/dist/cli/reason-codes.d.ts.map +1 -1
- package/dist/cli/reason-codes.js +30 -0
- package/dist/cli/run-cli/command-catalog/core.d.ts +3 -0
- package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/core.js +137 -0
- package/dist/cli/run-cli/command-catalog/lifecycle.d.ts +3 -0
- package/dist/cli/run-cli/command-catalog/lifecycle.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/lifecycle.js +52 -0
- package/dist/cli/run-cli/command-catalog/project.d.ts +3 -0
- package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/project.js +78 -0
- package/dist/cli/run-cli/command-catalog/shared.d.ts +19 -0
- package/dist/cli/run-cli/command-catalog/shared.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/shared.js +9 -0
- package/dist/cli/run-cli/command-catalog/task.d.ts +3 -0
- package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/task.js +85 -0
- package/dist/cli/run-cli/command-catalog.d.ts +3 -18
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog.js +8 -337
- package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/ide.js +64 -2
- package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/ui.js +33 -13
- package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts +3 -0
- package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts.map +1 -0
- package/dist/cli/run-cli.core.pr-flow.test-helpers.js +41 -0
- package/dist/cli/run-cli.core.tasks.test-helpers.d.ts +2 -0
- package/dist/cli/run-cli.core.tasks.test-helpers.d.ts.map +1 -0
- package/dist/cli/run-cli.core.tasks.test-helpers.js +6 -0
- package/dist/cli/run-cli.test-helpers.d.ts +3 -0
- package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +138 -6
- package/dist/commands/commit.spec.d.ts.map +1 -1
- package/dist/commands/commit.spec.js +2 -2
- package/dist/commands/doctor/runtime.d.ts.map +1 -1
- package/dist/commands/doctor/runtime.js +3 -6
- package/dist/commands/guard/commit.command.js +1 -1
- package/dist/commands/guard/impl/allow.d.ts +5 -0
- package/dist/commands/guard/impl/allow.d.ts.map +1 -1
- package/dist/commands/guard/impl/allow.js +15 -10
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +137 -18
- package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
- package/dist/commands/guard/impl/comment-commit.js +2 -0
- package/dist/commands/hooks/index.d.ts.map +1 -1
- package/dist/commands/hooks/index.js +8 -35
- package/dist/commands/recipes/impl/apply.d.ts +4 -0
- package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
- package/dist/commands/recipes/impl/apply.js +34 -0
- package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/explain.js +70 -11
- package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/info.js +24 -12
- package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/install.js +32 -36
- package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/list.js +7 -4
- package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/remove.js +9 -11
- package/dist/commands/recipes/impl/constants.d.ts +2 -0
- package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
- package/dist/commands/recipes/impl/constants.js +2 -0
- package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
- package/dist/commands/recipes/impl/manifest.js +219 -23
- package/dist/commands/recipes/impl/normalize.d.ts +3 -0
- package/dist/commands/recipes/impl/normalize.d.ts.map +1 -1
- package/dist/commands/recipes/impl/normalize.js +28 -24
- package/dist/commands/recipes/impl/paths.d.ts +9 -0
- package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
- package/dist/commands/recipes/impl/paths.js +10 -1
- package/dist/commands/recipes/impl/project-installed-recipes.d.ts +7 -0
- package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -0
- package/dist/commands/recipes/impl/project-installed-recipes.js +102 -0
- package/dist/commands/recipes/impl/resolver.d.ts +20 -0
- package/dist/commands/recipes/impl/resolver.d.ts.map +1 -0
- package/dist/commands/recipes/impl/resolver.js +220 -0
- package/dist/commands/recipes/impl/scenario.d.ts.map +1 -1
- package/dist/commands/recipes/impl/scenario.js +40 -11
- package/dist/commands/recipes/impl/types.d.ts +145 -16
- package/dist/commands/recipes/impl/types.d.ts.map +1 -1
- package/dist/commands/recipes/install.spec.d.ts.map +1 -1
- package/dist/commands/recipes/install.spec.js +3 -2
- package/dist/commands/recipes.d.ts +6 -4
- package/dist/commands/recipes.d.ts.map +1 -1
- package/dist/commands/recipes.js +5 -3
- package/dist/commands/recipes.test-helpers.d.ts +185 -0
- package/dist/commands/recipes.test-helpers.d.ts.map +1 -0
- package/dist/commands/recipes.test-helpers.js +339 -0
- package/dist/commands/scenario/impl/commands.d.ts.map +1 -1
- package/dist/commands/scenario/impl/commands.js +192 -336
- package/dist/commands/scenario/info.command.d.ts.map +1 -1
- package/dist/commands/scenario/info.command.js +7 -2
- package/dist/commands/scenario/list.command.js +2 -2
- package/dist/commands/scenario/run.command.d.ts.map +1 -1
- package/dist/commands/scenario/run.command.js +7 -2
- package/dist/commands/shared/reconcile-check.d.ts.map +1 -1
- package/dist/commands/shared/reconcile-check.js +77 -2
- package/dist/commands/shared/task-store.d.ts +32 -1
- package/dist/commands/shared/task-store.d.ts.map +1 -1
- package/dist/commands/shared/task-store.js +166 -42
- package/dist/commands/task/block.d.ts.map +1 -1
- package/dist/commands/task/block.js +46 -29
- package/dist/commands/task/close-duplicate.d.ts.map +1 -1
- package/dist/commands/task/close-duplicate.js +12 -37
- package/dist/commands/task/close-noop.d.ts.map +1 -1
- package/dist/commands/task/close-noop.js +12 -30
- package/dist/commands/task/close-shared.d.ts +14 -0
- package/dist/commands/task/close-shared.d.ts.map +1 -0
- package/dist/commands/task/close-shared.js +76 -0
- package/dist/commands/task/comment.d.ts.map +1 -1
- package/dist/commands/task/comment.js +35 -17
- package/dist/commands/task/doc-set.command.d.ts +2 -1
- package/dist/commands/task/doc-set.command.d.ts.map +1 -1
- package/dist/commands/task/doc-set.command.js +36 -4
- package/dist/commands/task/doc-template.d.ts.map +1 -1
- package/dist/commands/task/doc-template.js +2 -7
- package/dist/commands/task/doc.command.js +1 -1
- package/dist/commands/task/doc.d.ts +2 -1
- package/dist/commands/task/doc.d.ts.map +1 -1
- package/dist/commands/task/doc.js +123 -71
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +138 -76
- package/dist/commands/task/migrate-doc.d.ts.map +1 -1
- package/dist/commands/task/migrate-doc.js +2 -8
- package/dist/commands/task/plan-set.command.js +1 -1
- package/dist/commands/task/plan.command.d.ts +8 -0
- package/dist/commands/task/plan.command.d.ts.map +1 -0
- package/dist/commands/task/plan.command.js +37 -0
- package/dist/commands/task/plan.d.ts.map +1 -1
- package/dist/commands/task/plan.js +190 -93
- package/dist/commands/task/set-status.command.d.ts.map +1 -1
- package/dist/commands/task/set-status.command.js +1 -1
- package/dist/commands/task/set-status.d.ts.map +1 -1
- package/dist/commands/task/set-status.js +40 -3
- package/dist/commands/task/shared/docs.d.ts +1 -0
- package/dist/commands/task/shared/docs.d.ts.map +1 -1
- package/dist/commands/task/shared/docs.js +7 -0
- package/dist/commands/task/shared/transitions.d.ts +0 -2
- package/dist/commands/task/shared/transitions.d.ts.map +1 -1
- package/dist/commands/task/shared/transitions.js +0 -6
- package/dist/commands/task/shared.d.ts +2 -2
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +2 -2
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +88 -63
- package/dist/commands/task/task.command.d.ts +8 -0
- package/dist/commands/task/task.command.d.ts.map +1 -0
- package/dist/commands/task/task.command.js +71 -0
- package/dist/commands/task/verify-command-shared.d.ts +16 -0
- package/dist/commands/task/verify-command-shared.d.ts.map +1 -0
- package/dist/commands/task/verify-command-shared.js +53 -0
- package/dist/commands/task/verify-ok.command.d.ts +2 -6
- package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
- package/dist/commands/task/verify-ok.command.js +8 -50
- package/dist/commands/task/verify-record.d.ts.map +1 -1
- package/dist/commands/task/verify-record.js +119 -140
- package/dist/commands/task/verify-rework.command.d.ts +2 -6
- package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
- package/dist/commands/task/verify-rework.command.js +8 -50
- package/dist/commands/verify.spec.d.ts.map +1 -1
- package/dist/commands/verify.spec.js +3 -12
- package/dist/policy/rules/allowlist.d.ts.map +1 -1
- package/dist/policy/rules/allowlist.js +13 -4
- package/dist/policy/rules/protected-paths.d.ts.map +1 -1
- package/dist/policy/rules/protected-paths.js +6 -1
- package/dist/shared/agent-emoji.d.ts.map +1 -1
- package/dist/shared/protected-paths.d.ts +7 -0
- package/dist/shared/protected-paths.d.ts.map +1 -1
- package/dist/shared/protected-paths.js +26 -10
- package/dist/shared/repo-cli-version.d.ts.map +1 -1
- package/dist/shared/repo-cli-version.js +9 -3
- package/package.json +2 -2
|
@@ -28,6 +28,43 @@ async function clearDirectWorkLockIfMatches(opts) {
|
|
|
28
28
|
// best-effort
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
+
function assertTaskCanFinish(opts) {
|
|
32
|
+
if (!opts.force && String(opts.task.status || "TODO").toUpperCase() === "DONE") {
|
|
33
|
+
throw new CliError({
|
|
34
|
+
exitCode: 2,
|
|
35
|
+
code: "E_USAGE",
|
|
36
|
+
message: `Task is already DONE: ${opts.task.id} (use --force to override)`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
ensureVerificationSatisfiedIfRequired(opts.task, opts.config);
|
|
40
|
+
const normalizedDoc = ensureDocSections(typeof opts.task.doc === "string" ? opts.task.doc : "", opts.config.tasks.doc.required_sections);
|
|
41
|
+
ensureAgentFilledRequiredDocSections({
|
|
42
|
+
task: opts.task,
|
|
43
|
+
config: opts.config,
|
|
44
|
+
doc: normalizedDoc,
|
|
45
|
+
action: "finish task",
|
|
46
|
+
});
|
|
47
|
+
if (!opts.isMetaTask)
|
|
48
|
+
return;
|
|
49
|
+
const tags = Array.isArray(opts.task.tags)
|
|
50
|
+
? opts.task.tags.filter((t) => typeof t === "string")
|
|
51
|
+
: [];
|
|
52
|
+
const isSpike = tags.includes("spike");
|
|
53
|
+
if (!isSpike && opts.taskCount === 1 && !opts.resultSummary) {
|
|
54
|
+
throw new CliError({
|
|
55
|
+
exitCode: 2,
|
|
56
|
+
code: "E_USAGE",
|
|
57
|
+
message: "Missing required --result for non-spike tasks.",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (opts.resultProvided && !opts.resultSummary) {
|
|
61
|
+
throw new CliError({
|
|
62
|
+
exitCode: 2,
|
|
63
|
+
code: "E_USAGE",
|
|
64
|
+
message: "Invalid value for --result: empty.",
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
31
68
|
export async function cmdFinish(opts) {
|
|
32
69
|
try {
|
|
33
70
|
const ctx = opts.ctx ??
|
|
@@ -123,6 +160,7 @@ export async function cmdFinish(opts) {
|
|
|
123
160
|
const shouldCloseCommit = opts.closeCommit === true || (defaultDirectCloseCommit && opts.noCloseCommit !== true);
|
|
124
161
|
const metaTaskId = opts.taskIds.length === 1 ? (opts.taskIds[0] ?? "") : "";
|
|
125
162
|
const wantMeta = typeof opts.result === "string" || typeof opts.risk === "string" || opts.breaking === true;
|
|
163
|
+
const resultProvided = typeof opts.result === "string";
|
|
126
164
|
if (wantMeta && opts.taskIds.length !== 1) {
|
|
127
165
|
throw new CliError({
|
|
128
166
|
exitCode: 2,
|
|
@@ -137,78 +175,87 @@ export async function cmdFinish(opts) {
|
|
|
137
175
|
let primaryTag = null;
|
|
138
176
|
for (const taskId of opts.taskIds) {
|
|
139
177
|
const task = useStore ? await store.get(taskId) : await loadTaskFromContext({ ctx, taskId });
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
178
|
+
assertTaskCanFinish({
|
|
179
|
+
task,
|
|
180
|
+
config: ctx.config,
|
|
181
|
+
taskCount: opts.taskIds.length,
|
|
182
|
+
isMetaTask: taskId === metaTaskId,
|
|
183
|
+
resultProvided,
|
|
184
|
+
resultSummary,
|
|
185
|
+
force: opts.force,
|
|
186
|
+
});
|
|
150
187
|
if (taskId === primaryTaskId &&
|
|
151
188
|
(opts.commitFromComment || statusCommitRequested) &&
|
|
152
189
|
primaryStatusFrom === null) {
|
|
153
190
|
primaryStatusFrom = String(task.status || "TODO").toUpperCase();
|
|
154
191
|
primaryTag = resolvePrimaryTag(toStringArray(task.tags), ctx).primary;
|
|
155
192
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
: [];
|
|
168
|
-
const isSpike = tags.includes("spike");
|
|
169
|
-
if (!isSpike && opts.taskIds.length === 1 && !resultSummary) {
|
|
170
|
-
throw new CliError({
|
|
171
|
-
exitCode: 2,
|
|
172
|
-
code: "E_USAGE",
|
|
173
|
-
message: "Missing required --result for non-spike tasks.",
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
if (typeof opts.result === "string" && !resultSummary) {
|
|
177
|
-
throw new CliError({
|
|
178
|
-
exitCode: 2,
|
|
179
|
-
code: "E_USAGE",
|
|
180
|
-
message: "Invalid value for --result: empty.",
|
|
193
|
+
const at = nowIso();
|
|
194
|
+
if (useStore) {
|
|
195
|
+
await store.patch(taskId, (current) => {
|
|
196
|
+
assertTaskCanFinish({
|
|
197
|
+
task: current,
|
|
198
|
+
config: ctx.config,
|
|
199
|
+
taskCount: opts.taskIds.length,
|
|
200
|
+
isMetaTask: taskId === metaTaskId,
|
|
201
|
+
resultProvided,
|
|
202
|
+
resultSummary,
|
|
203
|
+
force: opts.force,
|
|
181
204
|
});
|
|
182
|
-
|
|
205
|
+
const currentStatus = String(current.status || "TODO").toUpperCase();
|
|
206
|
+
return {
|
|
207
|
+
task: {
|
|
208
|
+
status: "DONE",
|
|
209
|
+
commit: { hash: commitInfo.hash, message: commitInfo.message },
|
|
210
|
+
...(taskId === metaTaskId && resultSummary ? { result_summary: resultSummary } : {}),
|
|
211
|
+
...(taskId === metaTaskId && riskLevel ? { risk_level: riskLevel } : {}),
|
|
212
|
+
...(taskId === metaTaskId && breaking ? { breaking: true } : {}),
|
|
213
|
+
},
|
|
214
|
+
appendComments: [{ author: opts.author, body: opts.body }],
|
|
215
|
+
appendEvents: [
|
|
216
|
+
{
|
|
217
|
+
type: "status",
|
|
218
|
+
at,
|
|
219
|
+
author: opts.author,
|
|
220
|
+
from: currentStatus,
|
|
221
|
+
to: "DONE",
|
|
222
|
+
note: opts.body,
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
docMeta: {
|
|
226
|
+
touch: true,
|
|
227
|
+
updatedBy: opts.author,
|
|
228
|
+
version: normalizeTaskDocVersion(current.doc_version),
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
const existingComments = Array.isArray(task.comments)
|
|
235
|
+
? task.comments.filter((item) => !!item && typeof item.author === "string" && typeof item.body === "string")
|
|
236
|
+
: [];
|
|
237
|
+
const nextTask = {
|
|
238
|
+
...task,
|
|
239
|
+
status: "DONE",
|
|
240
|
+
commit: { hash: commitInfo.hash, message: commitInfo.message },
|
|
241
|
+
comments: [...existingComments, { author: opts.author, body: opts.body }],
|
|
242
|
+
events: appendTaskEvent(task, {
|
|
243
|
+
type: "status",
|
|
244
|
+
at,
|
|
245
|
+
author: opts.author,
|
|
246
|
+
from: String(task.status || "TODO").toUpperCase(),
|
|
247
|
+
to: "DONE",
|
|
248
|
+
note: opts.body,
|
|
249
|
+
}),
|
|
250
|
+
result_summary: taskId === metaTaskId && resultSummary ? resultSummary : task.result_summary,
|
|
251
|
+
risk_level: taskId === metaTaskId && riskLevel ? riskLevel : task.risk_level,
|
|
252
|
+
breaking: taskId === metaTaskId && breaking ? true : task.breaking,
|
|
253
|
+
doc_version: normalizeTaskDocVersion(task.doc_version),
|
|
254
|
+
doc_updated_at: at,
|
|
255
|
+
doc_updated_by: opts.author,
|
|
256
|
+
};
|
|
257
|
+
await ctx.taskBackend.writeTask(nextTask);
|
|
183
258
|
}
|
|
184
|
-
const existingComments = Array.isArray(task.comments)
|
|
185
|
-
? task.comments.filter((item) => !!item && typeof item.author === "string" && typeof item.body === "string")
|
|
186
|
-
: [];
|
|
187
|
-
const commentsValue = [...existingComments, { author: opts.author, body: opts.body }];
|
|
188
|
-
const at = nowIso();
|
|
189
|
-
const nextTask = {
|
|
190
|
-
...task,
|
|
191
|
-
status: "DONE",
|
|
192
|
-
commit: { hash: commitInfo.hash, message: commitInfo.message },
|
|
193
|
-
comments: commentsValue,
|
|
194
|
-
events: appendTaskEvent(task, {
|
|
195
|
-
type: "status",
|
|
196
|
-
at,
|
|
197
|
-
author: opts.author,
|
|
198
|
-
from: String(task.status || "TODO").toUpperCase(),
|
|
199
|
-
to: "DONE",
|
|
200
|
-
note: opts.body,
|
|
201
|
-
}),
|
|
202
|
-
result_summary: taskId === metaTaskId && resultSummary ? resultSummary : task.result_summary,
|
|
203
|
-
risk_level: taskId === metaTaskId && riskLevel ? riskLevel : task.risk_level,
|
|
204
|
-
breaking: taskId === metaTaskId && breaking ? true : task.breaking,
|
|
205
|
-
doc_version: normalizeTaskDocVersion(task.doc_version),
|
|
206
|
-
doc_updated_at: at,
|
|
207
|
-
doc_updated_by: opts.author,
|
|
208
|
-
};
|
|
209
|
-
await (useStore
|
|
210
|
-
? store.update(taskId, () => nextTask)
|
|
211
|
-
: ctx.taskBackend.writeTask(nextTask));
|
|
212
259
|
}
|
|
213
260
|
if (opts.commitFromComment || statusCommitRequested) {
|
|
214
261
|
enforceStatusCommitPolicy({
|
|
@@ -233,6 +280,9 @@ export async function cmdFinish(opts) {
|
|
|
233
280
|
}
|
|
234
281
|
}
|
|
235
282
|
if (opts.commitFromComment) {
|
|
283
|
+
if (!opts.quiet) {
|
|
284
|
+
process.stdout.write(`${infoMessage("task marked DONE; creating commit from verification comment")}\n`);
|
|
285
|
+
}
|
|
236
286
|
if (typeof opts.commitEmoji === "string" && opts.commitEmoji.trim() !== "✅") {
|
|
237
287
|
throw new CliError({
|
|
238
288
|
exitCode: 2,
|
|
@@ -263,19 +313,28 @@ export async function cmdFinish(opts) {
|
|
|
263
313
|
// commitFromComment creates the git commit and returns the actual head hash/subject.
|
|
264
314
|
// Refresh task commit metadata to this hash and amend the same commit in local mode so
|
|
265
315
|
// "task done" metadata does not require a manual follow-up close commit.
|
|
266
|
-
const taskAfterCommit = useStore
|
|
267
|
-
? await store.get(primaryTaskId)
|
|
268
|
-
: await loadTaskFromContext({ ctx, taskId: primaryTaskId });
|
|
269
|
-
const updatedAfterCommit = {
|
|
270
|
-
...taskAfterCommit,
|
|
271
|
-
commit: { hash: committed.hash, message: committed.message },
|
|
272
|
-
doc_version: normalizeTaskDocVersion(taskAfterCommit.doc_version),
|
|
273
|
-
doc_updated_at: nowIso(),
|
|
274
|
-
doc_updated_by: opts.author,
|
|
275
|
-
};
|
|
276
316
|
await (useStore
|
|
277
|
-
? store.
|
|
278
|
-
|
|
317
|
+
? store.patch(primaryTaskId, (current) => ({
|
|
318
|
+
task: {
|
|
319
|
+
commit: { hash: committed.hash, message: committed.message },
|
|
320
|
+
},
|
|
321
|
+
docMeta: {
|
|
322
|
+
touch: true,
|
|
323
|
+
updatedBy: opts.author,
|
|
324
|
+
version: normalizeTaskDocVersion(current.doc_version),
|
|
325
|
+
},
|
|
326
|
+
}))
|
|
327
|
+
: (async () => {
|
|
328
|
+
const taskAfterCommit = await loadTaskFromContext({ ctx, taskId: primaryTaskId });
|
|
329
|
+
const updatedAfterCommit = {
|
|
330
|
+
...taskAfterCommit,
|
|
331
|
+
commit: { hash: committed.hash, message: committed.message },
|
|
332
|
+
doc_version: normalizeTaskDocVersion(taskAfterCommit.doc_version),
|
|
333
|
+
doc_updated_at: nowIso(),
|
|
334
|
+
doc_updated_by: opts.author,
|
|
335
|
+
};
|
|
336
|
+
await ctx.taskBackend.writeTask(updatedAfterCommit);
|
|
337
|
+
})());
|
|
279
338
|
if (backendWritesTaskReadmes) {
|
|
280
339
|
const workflowReadmeRelPath = path.join(ctx.config.paths.workflow_dir, primaryTaskId, "README.md");
|
|
281
340
|
await ctx.git.stage([workflowReadmeRelPath]);
|
|
@@ -294,6 +353,9 @@ export async function cmdFinish(opts) {
|
|
|
294
353
|
}
|
|
295
354
|
}
|
|
296
355
|
if (statusCommitRequested) {
|
|
356
|
+
if (!opts.quiet) {
|
|
357
|
+
process.stdout.write(`${infoMessage("task marked DONE; creating status commit")}\n`);
|
|
358
|
+
}
|
|
297
359
|
if (typeof opts.statusCommitEmoji === "string" && opts.statusCommitEmoji.trim() !== "✅") {
|
|
298
360
|
throw new CliError({
|
|
299
361
|
exitCode: 2,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate-doc.d.ts","sourceRoot":"","sources":["../../../src/commands/task/migrate-doc.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migrate-doc.d.ts","sourceRoot":"","sources":["../../../src/commands/task/migrate-doc.ts"],"names":[],"mappings":"AA2RA,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqDlB"}
|
|
@@ -7,7 +7,7 @@ import { fileExists, getPathKind } from "../../cli/fs-utils.js";
|
|
|
7
7
|
import { successMessage } from "../../cli/output.js";
|
|
8
8
|
import { CliError } from "../../shared/errors.js";
|
|
9
9
|
import { exportTaskProjectionSnapshot, loadCommandContext } from "../shared/task-backend.js";
|
|
10
|
-
import { extractDocSection, extractTaskObservationSection, normalizeTaskDocVersion, normalizeVerificationSectionLayout, } from "./shared/docs.js";
|
|
10
|
+
import { extractDocSection, extractTaskObservationSection, decodeEscapedTaskTextNewlines, normalizeTaskDocVersion, normalizeVerificationSectionLayout, } from "./shared/docs.js";
|
|
11
11
|
import { defaultTaskDocV3 } from "./doc-template.js";
|
|
12
12
|
const V3_CANONICAL_ORDER = [
|
|
13
13
|
"Summary",
|
|
@@ -61,13 +61,7 @@ function renderMarkdownSections(sections) {
|
|
|
61
61
|
function normalizeLiteralNewlinesInHumanSection(title, text) {
|
|
62
62
|
if (!HUMAN_TEXT_SECTIONS.has(normalizeSectionKey(title)))
|
|
63
63
|
return text.trimEnd();
|
|
64
|
-
|
|
65
|
-
const escapedDoubleNewline = next.includes(String.raw `\n\n`) || next.includes(String.raw `\r\n\r\n`);
|
|
66
|
-
const escapedNewlineMatches = next.match(/\\n/g) ?? [];
|
|
67
|
-
if (escapedDoubleNewline || escapedNewlineMatches.length >= 2) {
|
|
68
|
-
next = next.replaceAll(String.raw `\r\n`, "\n").replaceAll(String.raw `\n`, "\n");
|
|
69
|
-
}
|
|
70
|
-
return next.trimEnd();
|
|
64
|
+
return decodeEscapedTaskTextNewlines(text).trimEnd();
|
|
71
65
|
}
|
|
72
66
|
function firstSectionText(sections, title) {
|
|
73
67
|
const target = normalizeSectionKey(title);
|
|
@@ -10,7 +10,7 @@ export const taskPlanSetSpec = {
|
|
|
10
10
|
kind: "string",
|
|
11
11
|
name: "text",
|
|
12
12
|
valueHint: "<text>",
|
|
13
|
-
description:
|
|
13
|
+
description: String.raw `Plan text to write into the task README Plan section. Literal escaped newlines (\n) are normalized for inline text.`,
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
kind: "string",
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
|
|
2
|
+
type TaskPlanGroupParsed = {
|
|
3
|
+
cmd: string[];
|
|
4
|
+
};
|
|
5
|
+
export declare const taskPlanSpec: CommandSpec<TaskPlanGroupParsed>;
|
|
6
|
+
export declare const runTaskPlan: CommandHandler<TaskPlanGroupParsed>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=plan.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/plan.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAItF,KAAK,mBAAmB,GAAG;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAI7C,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,mBAAmB,CAqBzD,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,cAAc,CAAC,mBAAmB,CAW3D,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { usageError } from "../../cli/spec/errors.js";
|
|
2
|
+
import { suggestOne } from "../../cli/spec/suggest.js";
|
|
3
|
+
const TASK_PLAN_SUBCOMMANDS = ["set", "approve", "reject"];
|
|
4
|
+
export const taskPlanSpec = {
|
|
5
|
+
id: ["task", "plan"],
|
|
6
|
+
group: "Task",
|
|
7
|
+
summary: "Task plan commands (set/approve/reject).",
|
|
8
|
+
synopsis: ["agentplane task plan <set|approve|reject> [args] [options]"],
|
|
9
|
+
args: [{ name: "cmd", required: false, variadic: true, valueHint: "<subcommand>" }],
|
|
10
|
+
examples: [
|
|
11
|
+
{
|
|
12
|
+
cmd: 'agentplane task plan set <task-id> --text "..." --updated-by ORCHESTRATOR',
|
|
13
|
+
why: "Write or replace the task plan.",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
cmd: "agentplane task plan approve <task-id> --by ORCHESTRATOR",
|
|
17
|
+
why: "Approve the current task plan.",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
cmd: 'agentplane task plan reject <task-id> --by ORCHESTRATOR --note "..."',
|
|
21
|
+
why: "Reject the current task plan with a note.",
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
parse: (raw) => ({ cmd: (raw.args.cmd ?? []) }),
|
|
25
|
+
};
|
|
26
|
+
export const runTaskPlan = (_ctx, p) => {
|
|
27
|
+
const input = p.cmd.join(" ");
|
|
28
|
+
const suggestion = suggestOne(input, [...TASK_PLAN_SUBCOMMANDS]);
|
|
29
|
+
const suffix = suggestion ? ` Did you mean: ${suggestion}?` : "";
|
|
30
|
+
const message = p.cmd.length === 0 ? "Missing subcommand." : `Unknown subcommand: ${p.cmd[0]}.`;
|
|
31
|
+
throw usageError({
|
|
32
|
+
spec: taskPlanSpec,
|
|
33
|
+
command: "task plan",
|
|
34
|
+
message: `${message}${suffix}`,
|
|
35
|
+
context: { command: "task plan" },
|
|
36
|
+
});
|
|
37
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/commands/task/plan.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/commands/task/plan.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAkJnC,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;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8HlB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,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,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,CA2DlB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,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;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,CAkElB"}
|