agentplane 0.2.19 → 0.2.21
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/assets/AGENTS.md +4 -3
- package/bin/agentplane.js +24 -0
- package/dist/backends/task-backend/load.d.ts +2 -0
- package/dist/backends/task-backend/load.d.ts.map +1 -1
- package/dist/backends/task-backend/load.js +38 -18
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +12 -11
- package/dist/cli/run-cli/command-catalog.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog.js +12 -1
- package/dist/cli/run-cli/commands/core.d.ts +9 -1
- package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core.js +268 -8
- package/dist/cli/run-cli/commands/init/write-config.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-config.js +2 -0
- package/dist/cli/run-cli/commands/init/write-gitignore.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-gitignore.js +3 -18
- package/dist/cli/run-cli/commands/init.d.ts +1 -0
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +55 -30
- package/dist/cli/run-cli.d.ts.map +1 -1
- package/dist/cli/run-cli.js +85 -14
- package/dist/commands/commit.command.d.ts.map +1 -1
- package/dist/commands/commit.command.js +2 -0
- package/dist/commands/commit.spec.d.ts +2 -0
- package/dist/commands/commit.spec.d.ts.map +1 -1
- package/dist/commands/commit.spec.js +26 -0
- package/dist/commands/doctor.run.d.ts.map +1 -1
- package/dist/commands/doctor.run.js +15 -6
- package/dist/commands/finish.run.d.ts.map +1 -1
- package/dist/commands/finish.run.js +2 -0
- package/dist/commands/finish.spec.d.ts +2 -0
- package/dist/commands/finish.spec.d.ts.map +1 -1
- package/dist/commands/finish.spec.js +36 -0
- package/dist/commands/guard/impl/allow.d.ts.map +1 -1
- package/dist/commands/guard/impl/allow.js +33 -7
- package/dist/commands/guard/impl/commands.d.ts +2 -0
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +24 -4
- package/dist/commands/guard/impl/comment-commit.d.ts +1 -0
- package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
- package/dist/commands/guard/impl/comment-commit.js +16 -24
- package/dist/commands/release/apply.command.d.ts.map +1 -1
- package/dist/commands/release/apply.command.js +51 -3
- package/dist/commands/release/plan.command.d.ts.map +1 -1
- package/dist/commands/release/plan.command.js +25 -1
- package/dist/commands/shared/task-backend.d.ts +3 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +4 -1
- package/dist/commands/task/block.d.ts.map +1 -1
- package/dist/commands/task/block.js +12 -9
- package/dist/commands/task/close-duplicate.command.d.ts +14 -0
- package/dist/commands/task/close-duplicate.command.d.ts.map +1 -0
- package/dist/commands/task/close-duplicate.command.js +102 -0
- package/dist/commands/task/close-duplicate.d.ts +14 -0
- package/dist/commands/task/close-duplicate.d.ts.map +1 -0
- package/dist/commands/task/close-duplicate.js +90 -0
- package/dist/commands/task/close-noop.command.d.ts +14 -0
- package/dist/commands/task/close-noop.command.d.ts.map +1 -0
- package/dist/commands/task/close-noop.command.js +77 -0
- package/dist/commands/task/close-noop.d.ts +13 -0
- package/dist/commands/task/close-noop.d.ts.map +1 -0
- package/dist/commands/task/close-noop.js +77 -0
- package/dist/commands/task/finish.d.ts +2 -0
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +52 -10
- package/dist/commands/task/index.d.ts +3 -0
- package/dist/commands/task/index.d.ts.map +1 -1
- package/dist/commands/task/index.js +3 -0
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +34 -6
- package/dist/commands/task/new.spec.js +1 -1
- package/dist/commands/task/plan.d.ts.map +1 -1
- package/dist/commands/task/plan.js +2 -3
- package/dist/commands/task/set-status.d.ts.map +1 -1
- package/dist/commands/task/set-status.js +12 -9
- package/dist/commands/task/shared.d.ts +19 -0
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +137 -0
- package/dist/commands/task/start-ready.command.d.ts +14 -0
- package/dist/commands/task/start-ready.command.d.ts.map +1 -0
- package/dist/commands/task/start-ready.command.js +77 -0
- package/dist/commands/task/start-ready.d.ts +13 -0
- package/dist/commands/task/start-ready.d.ts.map +1 -0
- package/dist/commands/task/start-ready.js +46 -0
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +13 -11
- package/dist/commands/task/update.command.d.ts +1 -0
- package/dist/commands/task/update.command.d.ts.map +1 -1
- package/dist/commands/task/update.command.js +8 -0
- package/dist/commands/task/update.d.ts +1 -0
- package/dist/commands/task/update.d.ts.map +1 -1
- package/dist/commands/task/update.js +19 -3
- package/dist/shared/errors.d.ts +9 -1
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/errors.js +3 -1
- package/dist/shared/runtime-artifacts.d.ts +3 -0
- package/dist/shared/runtime-artifacts.d.ts.map +1 -0
- package/dist/shared/runtime-artifacts.js +18 -0
- package/dist/usecases/context/resolve-context.d.ts +3 -0
- package/dist/usecases/context/resolve-context.d.ts.map +1 -1
- package/dist/usecases/context/resolve-context.js +6 -1
- package/package.json +2 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CommandCtx, CommandSpec } from "../../cli/spec/spec.js";
|
|
2
|
+
import type { CommandContext } from "../shared/task-backend.js";
|
|
3
|
+
type TaskCloseNoopParsed = {
|
|
4
|
+
taskId: string;
|
|
5
|
+
author: string;
|
|
6
|
+
note?: string;
|
|
7
|
+
force: boolean;
|
|
8
|
+
yes: boolean;
|
|
9
|
+
quiet: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare const taskCloseNoopSpec: CommandSpec<TaskCloseNoopParsed>;
|
|
12
|
+
export declare function makeRunTaskCloseNoopHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: TaskCloseNoopParsed) => Promise<number>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=close-noop.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"close-noop.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/close-noop.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,KAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,mBAAmB,CA2D9D,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC5E,KAAK,UAAU,EAAE,GAAG,mBAAmB,KAAG,OAAO,CAAC,MAAM,CAAC,CAaxE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { usageError } from "../../cli/spec/errors.js";
|
|
2
|
+
import { cmdTaskCloseNoop } from "./close-noop.js";
|
|
3
|
+
export const taskCloseNoopSpec = {
|
|
4
|
+
id: ["task", "close-noop"],
|
|
5
|
+
group: "Task",
|
|
6
|
+
summary: "Close a task as a verified no-op in one command.",
|
|
7
|
+
args: [{ name: "task-id", required: true, valueHint: "<task-id>" }],
|
|
8
|
+
options: [
|
|
9
|
+
{
|
|
10
|
+
kind: "string",
|
|
11
|
+
name: "author",
|
|
12
|
+
valueHint: "<id>",
|
|
13
|
+
required: true,
|
|
14
|
+
description: "Comment author id (e.g. ORCHESTRATOR).",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
kind: "string",
|
|
18
|
+
name: "note",
|
|
19
|
+
valueHint: "<text>",
|
|
20
|
+
description: "Optional closure note.",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
kind: "boolean",
|
|
24
|
+
name: "force",
|
|
25
|
+
default: false,
|
|
26
|
+
description: "Override status/verification gates.",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
kind: "boolean",
|
|
30
|
+
name: "yes",
|
|
31
|
+
default: false,
|
|
32
|
+
description: "Auto-approve force-action checks when required.",
|
|
33
|
+
},
|
|
34
|
+
{ kind: "boolean", name: "quiet", default: false, description: "Suppress output." },
|
|
35
|
+
],
|
|
36
|
+
examples: [
|
|
37
|
+
{
|
|
38
|
+
cmd: 'agentplane task close-noop 202602030608-F1Q8AB --author ORCHESTRATOR --note "Duplicate tracking artifact"',
|
|
39
|
+
why: "Close bookkeeping-only tasks without manual verify+finish choreography.",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
validateRaw: (raw) => {
|
|
43
|
+
const taskId = typeof raw.args["task-id"] === "string" ? raw.args["task-id"].trim() : "";
|
|
44
|
+
const author = typeof raw.opts.author === "string" ? raw.opts.author.trim() : "";
|
|
45
|
+
const note = raw.opts.note;
|
|
46
|
+
if (!taskId)
|
|
47
|
+
throw usageError({ spec: taskCloseNoopSpec, message: "Invalid value for task-id: empty." });
|
|
48
|
+
if (!author)
|
|
49
|
+
throw usageError({ spec: taskCloseNoopSpec, message: "Invalid value for --author: empty." });
|
|
50
|
+
if (typeof note === "string" && note.trim().length === 0) {
|
|
51
|
+
throw usageError({ spec: taskCloseNoopSpec, message: "Invalid value for --note: empty." });
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
parse: (raw) => ({
|
|
55
|
+
taskId: String(raw.args["task-id"]),
|
|
56
|
+
author: String(raw.opts.author),
|
|
57
|
+
note: typeof raw.opts.note === "string" ? raw.opts.note : undefined,
|
|
58
|
+
force: raw.opts.force === true,
|
|
59
|
+
yes: raw.opts.yes === true,
|
|
60
|
+
quiet: raw.opts.quiet === true,
|
|
61
|
+
}),
|
|
62
|
+
};
|
|
63
|
+
export function makeRunTaskCloseNoopHandler(getCtx) {
|
|
64
|
+
return async (ctx, p) => {
|
|
65
|
+
return await cmdTaskCloseNoop({
|
|
66
|
+
ctx: await getCtx("task close-noop"),
|
|
67
|
+
cwd: ctx.cwd,
|
|
68
|
+
rootOverride: ctx.rootOverride,
|
|
69
|
+
taskId: p.taskId,
|
|
70
|
+
author: p.author,
|
|
71
|
+
note: p.note,
|
|
72
|
+
force: p.force,
|
|
73
|
+
yes: p.yes,
|
|
74
|
+
quiet: p.quiet,
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CommandContext } from "../shared/task-backend.js";
|
|
2
|
+
export declare function cmdTaskCloseNoop(opts: {
|
|
3
|
+
ctx?: CommandContext;
|
|
4
|
+
cwd: string;
|
|
5
|
+
rootOverride?: string;
|
|
6
|
+
taskId: string;
|
|
7
|
+
author: string;
|
|
8
|
+
note?: string;
|
|
9
|
+
force: boolean;
|
|
10
|
+
yes: boolean;
|
|
11
|
+
quiet: boolean;
|
|
12
|
+
}): Promise<number>;
|
|
13
|
+
//# sourceMappingURL=close-noop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"close-noop.d.ts","sourceRoot":"","sources":["../../../src/commands/task/close-noop.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGpF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsElB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { mapBackendError } from "../../cli/error-map.js";
|
|
2
|
+
import { CliError } from "../../shared/errors.js";
|
|
3
|
+
import { ensureActionApproved } from "../shared/approval-requirements.js";
|
|
4
|
+
import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
|
|
5
|
+
import { loadCommandContext } from "../shared/task-backend.js";
|
|
6
|
+
import { appendTaskEvent, nowIso, requireStructuredComment } from "./shared.js";
|
|
7
|
+
export async function cmdTaskCloseNoop(opts) {
|
|
8
|
+
try {
|
|
9
|
+
const ctx = opts.ctx ??
|
|
10
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
11
|
+
if (opts.force) {
|
|
12
|
+
await ensureActionApproved({
|
|
13
|
+
action: "force_action",
|
|
14
|
+
config: ctx.config,
|
|
15
|
+
yes: opts.yes,
|
|
16
|
+
reason: "task close-noop --force",
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const useStore = backendIsLocalFileBackend(ctx);
|
|
20
|
+
const store = useStore ? getTaskStore(ctx) : null;
|
|
21
|
+
const task = useStore
|
|
22
|
+
? await store.get(opts.taskId)
|
|
23
|
+
: await ctx.taskBackend.getTask(opts.taskId);
|
|
24
|
+
if (!task) {
|
|
25
|
+
throw new CliError({
|
|
26
|
+
exitCode: 4,
|
|
27
|
+
code: "E_IO",
|
|
28
|
+
message: `Task not found: ${opts.taskId}`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (!opts.force && String(task.status || "TODO").toUpperCase() === "DONE") {
|
|
32
|
+
throw new CliError({
|
|
33
|
+
exitCode: 2,
|
|
34
|
+
code: "E_USAGE",
|
|
35
|
+
message: `Task is already DONE: ${opts.taskId} (use --force to override)`,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const normalizedNote = opts.note?.trim();
|
|
39
|
+
const baseBody = "Verified: no implementation changes were required; closure is recorded as no-op bookkeeping.";
|
|
40
|
+
const body = normalizedNote ? `${baseBody}\n\nNote: ${normalizedNote}` : baseBody;
|
|
41
|
+
const verifiedCfg = ctx.config.tasks.comments.verified;
|
|
42
|
+
requireStructuredComment(body, verifiedCfg.prefix, verifiedCfg.min_chars);
|
|
43
|
+
const at = nowIso();
|
|
44
|
+
const next = {
|
|
45
|
+
...task,
|
|
46
|
+
status: "DONE",
|
|
47
|
+
comments: [
|
|
48
|
+
...(Array.isArray(task.comments) ? task.comments : []),
|
|
49
|
+
{ author: opts.author, body },
|
|
50
|
+
],
|
|
51
|
+
events: appendTaskEvent(task, {
|
|
52
|
+
type: "status",
|
|
53
|
+
at,
|
|
54
|
+
author: opts.author,
|
|
55
|
+
from: String(task.status || "TODO").toUpperCase(),
|
|
56
|
+
to: "DONE",
|
|
57
|
+
note: body,
|
|
58
|
+
}),
|
|
59
|
+
result_summary: "No-op closure recorded.",
|
|
60
|
+
risk_level: "low",
|
|
61
|
+
breaking: false,
|
|
62
|
+
doc_version: 2,
|
|
63
|
+
doc_updated_at: at,
|
|
64
|
+
doc_updated_by: opts.author,
|
|
65
|
+
};
|
|
66
|
+
await (useStore ? store.update(opts.taskId, () => next) : ctx.taskBackend.writeTask(next));
|
|
67
|
+
if (!opts.quiet) {
|
|
68
|
+
process.stdout.write(`task.done: ${opts.taskId} (no-op)\n`);
|
|
69
|
+
}
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
if (err instanceof CliError)
|
|
74
|
+
throw err;
|
|
75
|
+
throw mapBackendError(err, { command: "task close-noop", root: opts.rootOverride ?? null });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -24,6 +24,8 @@ export declare function cmdFinish(opts: {
|
|
|
24
24
|
statusCommitAutoAllow: boolean;
|
|
25
25
|
statusCommitRequireClean: boolean;
|
|
26
26
|
confirmStatusCommit: boolean;
|
|
27
|
+
closeCommit?: boolean;
|
|
28
|
+
closeUnstageOthers?: boolean;
|
|
27
29
|
quiet: boolean;
|
|
28
30
|
}): Promise<number>;
|
|
29
31
|
//# sourceMappingURL=finish.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAmCnC,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,OAAO,CAAC;IAClC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6TlB"}
|
|
@@ -4,12 +4,12 @@ import { formatCommentBodyForCommit } from "../../shared/comment-format.js";
|
|
|
4
4
|
import { CliError } from "../../shared/errors.js";
|
|
5
5
|
import { readFile, rm } from "node:fs/promises";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import { buildGitCommitEnv, commitFromComment } from "../guard/index.js";
|
|
7
|
+
import { buildGitCommitEnv, cmdCommit, commitFromComment } from "../guard/index.js";
|
|
8
8
|
import { ensureActionApproved } from "../shared/approval-requirements.js";
|
|
9
9
|
import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
|
|
10
10
|
import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
|
|
11
11
|
import { readDirectWorkLock } from "../../shared/direct-work-lock.js";
|
|
12
|
-
import { appendTaskEvent, defaultCommitEmojiForStatus, enforceStatusCommitPolicy, ensureVerificationSatisfiedIfRequired, nowIso, readCommitInfo, readHeadCommit, requireStructuredComment, } from "./shared.js";
|
|
12
|
+
import { appendTaskEvent, defaultCommitEmojiForStatus, enforceStatusCommitPolicy, ensureVerificationSatisfiedIfRequired, nowIso, readCommitInfo, readHeadCommit, requireStructuredComment, resolvePrimaryTag, toStringArray, } from "./shared.js";
|
|
13
13
|
async function clearDirectWorkLockIfMatches(opts) {
|
|
14
14
|
const lockPath = path.join(opts.agentplaneDir, "cache", "direct-work.json");
|
|
15
15
|
try {
|
|
@@ -40,14 +40,6 @@ export async function cmdFinish(opts) {
|
|
|
40
40
|
}
|
|
41
41
|
const { prefix, min_chars: minChars } = ctx.config.tasks.comments.verified;
|
|
42
42
|
requireStructuredComment(opts.body, prefix, minChars);
|
|
43
|
-
if (opts.commitFromComment || opts.statusCommit) {
|
|
44
|
-
enforceStatusCommitPolicy({
|
|
45
|
-
policy: ctx.config.status_commit_policy,
|
|
46
|
-
action: "finish",
|
|
47
|
-
confirmed: opts.confirmStatusCommit,
|
|
48
|
-
quiet: opts.quiet,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
43
|
if ((opts.commitFromComment || opts.statusCommit) && opts.taskIds.length !== 1) {
|
|
52
44
|
throw new CliError({
|
|
53
45
|
exitCode: 2,
|
|
@@ -55,6 +47,20 @@ export async function cmdFinish(opts) {
|
|
|
55
47
|
message: "--commit-from-comment/--status-commit requires exactly one task id",
|
|
56
48
|
});
|
|
57
49
|
}
|
|
50
|
+
if (opts.closeCommit && opts.taskIds.length !== 1) {
|
|
51
|
+
throw new CliError({
|
|
52
|
+
exitCode: 2,
|
|
53
|
+
code: "E_USAGE",
|
|
54
|
+
message: "--close-commit requires exactly one task id",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (opts.closeCommit && (opts.commitFromComment || opts.statusCommit)) {
|
|
58
|
+
throw new CliError({
|
|
59
|
+
exitCode: 2,
|
|
60
|
+
code: "E_USAGE",
|
|
61
|
+
message: "--close-commit cannot be combined with --commit-from-comment/--status-commit",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
58
64
|
const primaryTaskId = opts.taskIds[0] ?? "";
|
|
59
65
|
if ((opts.commitFromComment || opts.statusCommit) && !primaryTaskId) {
|
|
60
66
|
throw new CliError({
|
|
@@ -82,6 +88,7 @@ export async function cmdFinish(opts) {
|
|
|
82
88
|
const riskLevel = opts.risk;
|
|
83
89
|
const breaking = opts.breaking === true;
|
|
84
90
|
let primaryStatusFrom = null;
|
|
91
|
+
let primaryTag = null;
|
|
85
92
|
for (const taskId of opts.taskIds) {
|
|
86
93
|
const task = useStore ? await store.get(taskId) : await loadTaskFromContext({ ctx, taskId });
|
|
87
94
|
if (!opts.force) {
|
|
@@ -98,6 +105,7 @@ export async function cmdFinish(opts) {
|
|
|
98
105
|
(opts.commitFromComment || opts.statusCommit) &&
|
|
99
106
|
primaryStatusFrom === null) {
|
|
100
107
|
primaryStatusFrom = String(task.status || "TODO").toUpperCase();
|
|
108
|
+
primaryTag = resolvePrimaryTag(toStringArray(task.tags), ctx).primary;
|
|
101
109
|
}
|
|
102
110
|
ensureVerificationSatisfiedIfRequired(task, ctx.config);
|
|
103
111
|
if (taskId === metaTaskId) {
|
|
@@ -149,6 +157,16 @@ export async function cmdFinish(opts) {
|
|
|
149
157
|
? store.update(taskId, () => nextTask)
|
|
150
158
|
: ctx.taskBackend.writeTask(nextTask));
|
|
151
159
|
}
|
|
160
|
+
if (opts.commitFromComment || opts.statusCommit) {
|
|
161
|
+
enforceStatusCommitPolicy({
|
|
162
|
+
policy: ctx.config.status_commit_policy,
|
|
163
|
+
action: "finish",
|
|
164
|
+
confirmed: opts.confirmStatusCommit,
|
|
165
|
+
quiet: opts.quiet,
|
|
166
|
+
statusFrom: primaryStatusFrom ?? "UNKNOWN",
|
|
167
|
+
statusTo: "DONE",
|
|
168
|
+
});
|
|
169
|
+
}
|
|
152
170
|
// tasks.json is export-only; generated via `agentplane task export`.
|
|
153
171
|
let executorAgent = null;
|
|
154
172
|
if (opts.commitFromComment || opts.statusCommit) {
|
|
@@ -174,6 +192,7 @@ export async function cmdFinish(opts) {
|
|
|
174
192
|
cwd: opts.cwd,
|
|
175
193
|
rootOverride: opts.rootOverride,
|
|
176
194
|
taskId: primaryTaskId,
|
|
195
|
+
primaryTag: primaryTag ?? "meta",
|
|
177
196
|
executorAgent: executorAgent ?? undefined,
|
|
178
197
|
author: opts.author,
|
|
179
198
|
statusFrom: primaryStatusFrom ?? undefined,
|
|
@@ -234,6 +253,7 @@ export async function cmdFinish(opts) {
|
|
|
234
253
|
cwd: opts.cwd,
|
|
235
254
|
rootOverride: opts.rootOverride,
|
|
236
255
|
taskId: primaryTaskId,
|
|
256
|
+
primaryTag: primaryTag ?? "meta",
|
|
237
257
|
executorAgent: executorAgent ?? undefined,
|
|
238
258
|
author: opts.author,
|
|
239
259
|
statusFrom: primaryStatusFrom ?? undefined,
|
|
@@ -249,6 +269,28 @@ export async function cmdFinish(opts) {
|
|
|
249
269
|
config: ctx.config,
|
|
250
270
|
});
|
|
251
271
|
}
|
|
272
|
+
if (opts.closeCommit && primaryTaskId) {
|
|
273
|
+
await cmdCommit({
|
|
274
|
+
ctx,
|
|
275
|
+
cwd: opts.cwd,
|
|
276
|
+
rootOverride: opts.rootOverride,
|
|
277
|
+
taskId: primaryTaskId,
|
|
278
|
+
message: "",
|
|
279
|
+
close: true,
|
|
280
|
+
allow: [],
|
|
281
|
+
autoAllow: false,
|
|
282
|
+
allowTasks: true,
|
|
283
|
+
allowBase: false,
|
|
284
|
+
allowPolicy: false,
|
|
285
|
+
allowConfig: false,
|
|
286
|
+
allowHooks: false,
|
|
287
|
+
allowCI: false,
|
|
288
|
+
requireClean: true,
|
|
289
|
+
quiet: opts.quiet,
|
|
290
|
+
closeUnstageOthers: opts.closeUnstageOthers === true,
|
|
291
|
+
closeCheckOnly: false,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
252
294
|
if (ctx.config.workflow_mode === "direct") {
|
|
253
295
|
await clearDirectWorkLockIfMatches({
|
|
254
296
|
agentplaneDir: ctx.resolvedProject.agentplaneDir,
|
|
@@ -15,6 +15,9 @@ export { cmdTaskComment } from "./comment.js";
|
|
|
15
15
|
export { cmdTaskSetStatus } from "./set-status.js";
|
|
16
16
|
export { cmdTaskShow } from "./show.js";
|
|
17
17
|
export { cmdTaskDerive } from "./derive.js";
|
|
18
|
+
export { cmdTaskCloseDuplicate } from "./close-duplicate.js";
|
|
19
|
+
export { cmdTaskStartReady } from "./start-ready.js";
|
|
20
|
+
export { cmdTaskCloseNoop } from "./close-noop.js";
|
|
18
21
|
export { cmdTaskExport } from "./export.js";
|
|
19
22
|
export { cmdTaskLint } from "./lint.js";
|
|
20
23
|
export { cmdTaskPlanSet, cmdTaskPlanApprove, cmdTaskPlanReject } from "./plan.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/task/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/task/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAElF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -14,6 +14,9 @@ export { cmdTaskComment } from "./comment.js";
|
|
|
14
14
|
export { cmdTaskSetStatus } from "./set-status.js";
|
|
15
15
|
export { cmdTaskShow } from "./show.js";
|
|
16
16
|
export { cmdTaskDerive } from "./derive.js";
|
|
17
|
+
export { cmdTaskCloseDuplicate } from "./close-duplicate.js";
|
|
18
|
+
export { cmdTaskStartReady } from "./start-ready.js";
|
|
19
|
+
export { cmdTaskCloseNoop } from "./close-noop.js";
|
|
17
20
|
export { cmdTaskExport } from "./export.js";
|
|
18
21
|
export { cmdTaskLint } from "./lint.js";
|
|
19
22
|
export { cmdTaskPlanSet, cmdTaskPlanApprove, cmdTaskPlanReject } from "./plan.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/commands/task/new.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/commands/task/new.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAQpF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC5C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAyBF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,aAAa,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsElB"}
|
|
@@ -2,7 +2,28 @@ import { mapBackendError } from "../../cli/error-map.js";
|
|
|
2
2
|
import { backendNotSupportedMessage, warnMessage } from "../../cli/output.js";
|
|
3
3
|
import { CliError } from "../../shared/errors.js";
|
|
4
4
|
import { loadCommandContext } from "../shared/task-backend.js";
|
|
5
|
-
import { nowIso,
|
|
5
|
+
import { nowIso, requiresVerifyStepsByPrimary, resolvePrimaryTag, warnIfUnknownOwner, } from "./shared.js";
|
|
6
|
+
function buildDefaultVerifyStepsDoc(opts) {
|
|
7
|
+
const checks = opts.verifyCommands.length > 0
|
|
8
|
+
? opts.verifyCommands.map((command) => `- \`${command}\``).join("\n")
|
|
9
|
+
: "- Add explicit checks/commands for this task before approval.";
|
|
10
|
+
return [
|
|
11
|
+
"## Verify Steps",
|
|
12
|
+
"",
|
|
13
|
+
"### Scope",
|
|
14
|
+
`- Primary tag: \`${opts.primary}\``,
|
|
15
|
+
"",
|
|
16
|
+
"### Checks",
|
|
17
|
+
checks,
|
|
18
|
+
"",
|
|
19
|
+
"### Evidence / Commands",
|
|
20
|
+
"- Record executed commands and key outputs.",
|
|
21
|
+
"",
|
|
22
|
+
"### Pass criteria",
|
|
23
|
+
"- Steps are reproducible and produce expected results.",
|
|
24
|
+
"",
|
|
25
|
+
].join("\n");
|
|
26
|
+
}
|
|
6
27
|
export async function runTaskNewParsed(opts) {
|
|
7
28
|
const p = opts.parsed;
|
|
8
29
|
try {
|
|
@@ -33,17 +54,24 @@ export async function runTaskNewParsed(opts) {
|
|
|
33
54
|
doc_updated_by: p.owner,
|
|
34
55
|
id_source: "generated",
|
|
35
56
|
};
|
|
36
|
-
const requireStepsTags = ctx.config.tasks.verify.require_steps_for_tags ?? ctx.config.tasks.verify.required_tags;
|
|
37
57
|
const spikeTag = (ctx.config.tasks.verify.spike_tag ?? "spike").trim().toLowerCase();
|
|
38
|
-
const
|
|
58
|
+
const primary = resolvePrimaryTag(p.tags, ctx);
|
|
59
|
+
if (primary.usedFallback) {
|
|
60
|
+
process.stderr.write(`${warnMessage(`primary tag not found in task tags; using fallback primary=${primary.primary}`)}\n`);
|
|
61
|
+
}
|
|
62
|
+
const requiresVerifySteps = requiresVerifyStepsByPrimary(p.tags, ctx.config);
|
|
39
63
|
await warnIfUnknownOwner(ctx, p.owner);
|
|
40
64
|
if (requiresVerifySteps) {
|
|
41
|
-
|
|
65
|
+
task.doc = buildDefaultVerifyStepsDoc({
|
|
66
|
+
primary: primary.primary,
|
|
67
|
+
verifyCommands: p.verify,
|
|
68
|
+
});
|
|
69
|
+
process.stderr.write(`${warnMessage("task requires Verify Steps by primary tag; seeded a default ## Verify Steps section in README (review and refine before approval/start)")}\n`);
|
|
42
70
|
}
|
|
43
71
|
const hasSpike = p.tags.some((tag) => tag.trim().toLowerCase() === spikeTag);
|
|
44
|
-
const hasImplementationTags =
|
|
72
|
+
const hasImplementationTags = requiresVerifyStepsByPrimary(p.tags, ctx.config);
|
|
45
73
|
if (hasSpike && hasImplementationTags) {
|
|
46
|
-
process.stderr.write(`${warnMessage("spike is combined with
|
|
74
|
+
process.stderr.write(`${warnMessage("spike is combined with a primary tag that requires verify steps; consider splitting spike vs implementation tasks")}\n`);
|
|
47
75
|
}
|
|
48
76
|
await ctx.taskBackend.writeTask(task);
|
|
49
77
|
process.stdout.write(`${taskId}\n`);
|
|
@@ -65,7 +65,7 @@ export const taskNewSpec = {
|
|
|
65
65
|
},
|
|
66
66
|
],
|
|
67
67
|
notes: [
|
|
68
|
-
"
|
|
68
|
+
"For verify-required primary tags, this command seeds a default ## Verify Steps section in README.",
|
|
69
69
|
],
|
|
70
70
|
parse: (raw) => ({
|
|
71
71
|
title: raw.opts.title,
|
|
@@ -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;AA+CnC,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,CAmElB;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,
|
|
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;AA+CnC,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,CAmElB;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,CAgFlB;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,CAuDlB"}
|
|
@@ -6,7 +6,7 @@ import { backendNotSupportedMessage } from "../../cli/output.js";
|
|
|
6
6
|
import { CliError } from "../../shared/errors.js";
|
|
7
7
|
import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
|
|
8
8
|
import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
|
|
9
|
-
import { extractDocSection, isVerifyStepsFilled, nowIso,
|
|
9
|
+
import { extractDocSection, isVerifyStepsFilled, nowIso, requiresVerifyStepsByPrimary, toStringArray, } from "./shared.js";
|
|
10
10
|
async function loadPlanTask(opts) {
|
|
11
11
|
const ctx = opts.ctx ??
|
|
12
12
|
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
@@ -120,9 +120,8 @@ export async function cmdTaskPlanApprove(opts) {
|
|
|
120
120
|
const enforceVerifySteps = config.tasks.verify.enforce_on_plan_approve !== false;
|
|
121
121
|
if (enforceVerifySteps) {
|
|
122
122
|
const tags = toStringArray(task.tags);
|
|
123
|
-
const requireStepsTags = config.tasks.verify.require_steps_for_tags ?? config.tasks.verify.required_tags;
|
|
124
123
|
const spikeTag = (config.tasks.verify.spike_tag ?? "spike").trim().toLowerCase();
|
|
125
|
-
const verifyRequired =
|
|
124
|
+
const verifyRequired = requiresVerifyStepsByPrimary(tags, config);
|
|
126
125
|
const isSpike = tags.some((tag) => tag.trim().toLowerCase() === spikeTag);
|
|
127
126
|
if (verifyRequired || isSpike) {
|
|
128
127
|
const verifySteps = extractDocSection(baseDoc, "Verify Steps");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set-status.d.ts","sourceRoot":"","sources":["../../../src/commands/task/set-status.ts"],"names":[],"mappings":"AAQA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"set-status.d.ts","sourceRoot":"","sources":["../../../src/commands/task/set-status.ts"],"names":[],"mappings":"AAQA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAgBnC,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6JlB"}
|
|
@@ -6,7 +6,7 @@ import { commitFromComment } from "../guard/index.js";
|
|
|
6
6
|
import { ensureActionApproved } from "../shared/approval-requirements.js";
|
|
7
7
|
import { listTasksMemo, loadCommandContext, loadTaskFromContext, resolveDocUpdatedBy, } from "../shared/task-backend.js";
|
|
8
8
|
import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
|
|
9
|
-
import { appendTaskEvent, buildDependencyState, defaultCommitEmojiForStatus, enforceStatusCommitPolicy, isTransitionAllowed, normalizeTaskStatus, nowIso, readCommitInfo, } from "./shared.js";
|
|
9
|
+
import { appendTaskEvent, buildDependencyState, defaultCommitEmojiForStatus, enforceStatusCommitPolicy, isTransitionAllowed, normalizeTaskStatus, nowIso, readCommitInfo, resolvePrimaryTag, toStringArray, } from "./shared.js";
|
|
10
10
|
export async function cmdTaskSetStatus(opts) {
|
|
11
11
|
const nextStatus = normalizeTaskStatus(opts.status);
|
|
12
12
|
if (nextStatus === "DONE" && !opts.force) {
|
|
@@ -41,14 +41,6 @@ export async function cmdTaskSetStatus(opts) {
|
|
|
41
41
|
const task = useStore
|
|
42
42
|
? await store.get(opts.taskId)
|
|
43
43
|
: await loadTaskFromContext({ ctx, taskId: opts.taskId });
|
|
44
|
-
if (opts.commitFromComment) {
|
|
45
|
-
enforceStatusCommitPolicy({
|
|
46
|
-
policy: config.status_commit_policy,
|
|
47
|
-
action: "task set-status",
|
|
48
|
-
confirmed: opts.confirmStatusCommit,
|
|
49
|
-
quiet: opts.quiet,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
44
|
const currentStatus = String(task.status || "TODO").toUpperCase();
|
|
53
45
|
if (!opts.force && !isTransitionAllowed(currentStatus, nextStatus)) {
|
|
54
46
|
throw new CliError({
|
|
@@ -77,6 +69,16 @@ export async function cmdTaskSetStatus(opts) {
|
|
|
77
69
|
});
|
|
78
70
|
}
|
|
79
71
|
}
|
|
72
|
+
if (opts.commitFromComment) {
|
|
73
|
+
enforceStatusCommitPolicy({
|
|
74
|
+
policy: config.status_commit_policy,
|
|
75
|
+
action: "task set-status",
|
|
76
|
+
confirmed: opts.confirmStatusCommit,
|
|
77
|
+
quiet: opts.quiet,
|
|
78
|
+
statusFrom: currentStatus,
|
|
79
|
+
statusTo: nextStatus,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
80
82
|
const existingComments = Array.isArray(task.comments)
|
|
81
83
|
? task.comments.filter((item) => !!item && typeof item.author === "string" && typeof item.body === "string")
|
|
82
84
|
: [];
|
|
@@ -125,6 +127,7 @@ export async function cmdTaskSetStatus(opts) {
|
|
|
125
127
|
cwd: opts.cwd,
|
|
126
128
|
rootOverride: opts.rootOverride,
|
|
127
129
|
taskId: opts.taskId,
|
|
130
|
+
primaryTag: resolvePrimaryTag(toStringArray(task.tags), ctx).primary,
|
|
128
131
|
author: opts.author,
|
|
129
132
|
statusFrom: currentStatus,
|
|
130
133
|
statusTo: nextStatus,
|
|
@@ -12,6 +12,22 @@ export declare function normalizeDependsOnInput(value: string): string[];
|
|
|
12
12
|
export declare function normalizeTaskStatus(value: string): string;
|
|
13
13
|
export declare function toStringArray(value: unknown): string[];
|
|
14
14
|
export declare function requiresVerify(tags: string[], requiredTags: string[]): boolean;
|
|
15
|
+
export type PrimaryTagResolution = {
|
|
16
|
+
primary: string;
|
|
17
|
+
matched: string[];
|
|
18
|
+
usedFallback: boolean;
|
|
19
|
+
};
|
|
20
|
+
export type TaskTagPolicy = {
|
|
21
|
+
primaryAllowlist: string[];
|
|
22
|
+
strictPrimary: boolean;
|
|
23
|
+
fallbackPrimary: string;
|
|
24
|
+
lockPrimaryOnUpdate: boolean;
|
|
25
|
+
};
|
|
26
|
+
export declare function readTaskTagPolicy(input: CommandContext | AgentplaneConfig): TaskTagPolicy;
|
|
27
|
+
export declare function resolvePrimaryTagFromConfig(tags: string[], config: AgentplaneConfig): PrimaryTagResolution;
|
|
28
|
+
export declare function requiresVerifyStepsByPrimary(tags: string[], config: AgentplaneConfig): boolean;
|
|
29
|
+
export declare function requiresVerificationByPrimary(tags: string[], config: AgentplaneConfig): boolean;
|
|
30
|
+
export declare function resolvePrimaryTag(tags: string[], ctx: CommandContext): PrimaryTagResolution;
|
|
15
31
|
export declare function warnIfUnknownOwner(ctx: CommandContext, owner: string): Promise<void>;
|
|
16
32
|
export declare function appendTaskEvent(task: TaskData, event: TaskEvent): TaskEvent[];
|
|
17
33
|
export declare function ensurePlanApprovedIfRequired(task: TaskData, config: AgentplaneConfig): void;
|
|
@@ -34,7 +50,10 @@ export declare function enforceStatusCommitPolicy(opts: {
|
|
|
34
50
|
action: string;
|
|
35
51
|
confirmed: boolean;
|
|
36
52
|
quiet: boolean;
|
|
53
|
+
statusFrom: string;
|
|
54
|
+
statusTo: string;
|
|
37
55
|
}): void;
|
|
56
|
+
export declare function isMajorStatusCommitTransition(statusFrom: string, statusTo: string): boolean;
|
|
38
57
|
export declare function readCommitInfo(cwd: string, rev: string): Promise<{
|
|
39
58
|
hash: string;
|
|
40
59
|
message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/task/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAK9C,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAW5D,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/task/shared.ts"],"names":[],"mappings":"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"}
|