agentplane 0.2.21 → 0.2.22
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 +2 -1
- package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/local-backend.js +27 -7
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog.js +60 -12
- package/dist/cli/run-cli/commands/core.d.ts +2 -0
- package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core.js +32 -5
- package/dist/cli/run-cli/commands/init/write-agents.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-agents.js +33 -1
- package/dist/cli/run-cli/commands/init/write-config.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-config.js +3 -1
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +47 -7
- package/dist/cli/run-cli.d.ts.map +1 -1
- package/dist/cli/run-cli.js +1 -3
- package/dist/cli/spec/docs-render.d.ts.map +1 -1
- package/dist/cli/spec/docs-render.js +13 -6
- package/dist/commands/backend/sync.command.d.ts +3 -2
- package/dist/commands/backend/sync.command.d.ts.map +1 -1
- package/dist/commands/backend/sync.command.js +13 -15
- package/dist/commands/pr/pr.command.d.ts +1 -1
- package/dist/commands/pr/pr.command.d.ts.map +1 -1
- package/dist/commands/pr/pr.command.js +15 -15
- package/dist/commands/task/block.d.ts.map +1 -1
- package/dist/commands/task/block.js +15 -18
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +14 -7
- package/dist/commands/task/plan.d.ts.map +1 -1
- package/dist/commands/task/plan.js +14 -2
- package/dist/commands/task/ready.d.ts.map +1 -1
- package/dist/commands/task/ready.js +6 -8
- package/dist/commands/task/set-status.d.ts.map +1 -1
- package/dist/commands/task/set-status.js +18 -23
- package/dist/commands/task/shared.d.ts +16 -1
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +54 -3
- package/dist/commands/task/start-ready.d.ts.map +1 -1
- package/dist/commands/task/start-ready.js +6 -15
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +18 -23
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +67 -19
- package/package.json +2 -2
- package/dist/cli/parse/lifecycle.d.ts +0 -64
- package/dist/cli/parse/lifecycle.d.ts.map +0 -1
- package/dist/cli/parse/lifecycle.js +0 -285
|
@@ -50,21 +50,19 @@ export const backendSyncSpec = {
|
|
|
50
50
|
quiet: raw.opts.quiet === true,
|
|
51
51
|
}),
|
|
52
52
|
};
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
};
|
|
67
|
-
return handler;
|
|
53
|
+
function runBackendRootGroup(_ctx, p) {
|
|
54
|
+
const input = p.cmd.join(" ");
|
|
55
|
+
const suggestion = suggestOne(input, ["sync"]);
|
|
56
|
+
const suffix = suggestion ? ` Did you mean: ${suggestion}?` : "";
|
|
57
|
+
const msg = p.cmd.length === 0 ? "Missing subcommand." : `Unknown subcommand: ${p.cmd[0]}.`;
|
|
58
|
+
throw usageError({
|
|
59
|
+
spec: backendSyncSpec,
|
|
60
|
+
message: `${msg}${suffix}`,
|
|
61
|
+
context: { command: "backend sync" },
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export function makeRunBackendHandler(_getCtx) {
|
|
65
|
+
return runBackendRootGroup;
|
|
68
66
|
}
|
|
69
67
|
export function makeRunBackendSyncHandler(getCtx) {
|
|
70
68
|
return async (ctx, p) => {
|
|
@@ -24,7 +24,7 @@ export type PrNoteParsed = {
|
|
|
24
24
|
body: string;
|
|
25
25
|
};
|
|
26
26
|
export declare const prNoteSpec: CommandSpec<PrNoteParsed>;
|
|
27
|
-
export declare function makeRunPrHandler(
|
|
27
|
+
export declare function makeRunPrHandler(_getCtx: (cmd: string) => Promise<CommandContext>): CommandHandler<PrGroupParsed>;
|
|
28
28
|
export declare function makeRunPrOpenHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: PrOpenParsed) => Promise<number>;
|
|
29
29
|
export declare function makeRunPrUpdateHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: PrUpdateParsed) => Promise<number>;
|
|
30
30
|
export declare function makeRunPrCheckHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: PrCheckParsed) => Promise<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr.command.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/pr.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,KAAK,aAAa,GAAG;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEvC,eAAO,MAAM,MAAM,EAAE,WAAW,CAAC,aAAa,CAgB7C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAErF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAgChD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhD,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,cAAc,CAOpD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAOlD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CA0ChD,CAAC;
|
|
1
|
+
{"version":3,"file":"pr.command.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/pr.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,KAAK,aAAa,GAAG;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEvC,eAAO,MAAM,MAAM,EAAE,WAAW,CAAC,aAAa,CAgB7C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAErF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAgChD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhD,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,cAAc,CAOpD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAOlD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CA0ChD,CAAC;AAgBF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,GAChD,cAAc,CAAC,aAAa,CAAC,CAE/B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACrE,KAAK,UAAU,EAAE,GAAG,YAAY,KAAG,OAAO,CAAC,MAAM,CAAC,CAUjE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACvE,KAAK,UAAU,EAAE,GAAG,cAAc,KAAG,OAAO,CAAC,MAAM,CAAC,CAQnE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACtE,KAAK,UAAU,EAAE,GAAG,aAAa,KAAG,OAAO,CAAC,MAAM,CAAC,CAQlE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACrE,KAAK,UAAU,EAAE,GAAG,YAAY,KAAG,OAAO,CAAC,MAAM,CAAC,CAUjE"}
|
|
@@ -110,21 +110,21 @@ export const prNoteSpec = {
|
|
|
110
110
|
body: String(raw.opts.body),
|
|
111
111
|
}),
|
|
112
112
|
};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
113
|
+
function runPrRootGroup(_ctx, p) {
|
|
114
|
+
const input = p.cmd.join(" ");
|
|
115
|
+
const candidates = ["open", "update", "check", "note"];
|
|
116
|
+
const suggestion = suggestOne(input, candidates);
|
|
117
|
+
const suffix = suggestion ? ` Did you mean: ${suggestion}?` : "";
|
|
118
|
+
const msg = p.cmd.length === 0 ? "Missing subcommand." : `Unknown subcommand: ${p.cmd[0]}.`;
|
|
119
|
+
throw usageError({
|
|
120
|
+
spec: prSpec,
|
|
121
|
+
command: "pr",
|
|
122
|
+
message: `${msg}${suffix}`,
|
|
123
|
+
context: { command: "pr" },
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
export function makeRunPrHandler(_getCtx) {
|
|
127
|
+
return runPrRootGroup;
|
|
128
128
|
}
|
|
129
129
|
export function makeRunPrOpenHandler(getCtx) {
|
|
130
130
|
return async (ctx, p) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../../src/commands/task/block.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAgBnC,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,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,EAAE,MAAM,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;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../../src/commands/task/block.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAgBnC,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,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,EAAE,MAAM,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;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+HlB"}
|
|
@@ -7,7 +7,7 @@ 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, defaultCommitEmojiForAgentId,
|
|
10
|
+
import { appendTaskEvent, defaultCommitEmojiForAgentId, ensureCommentCommitAllowed, ensureStatusTransitionAllowed, nowIso, requireStructuredComment, resolvePrimaryTag, toStringArray, } from "./shared.js";
|
|
11
11
|
export async function cmdBlock(opts) {
|
|
12
12
|
try {
|
|
13
13
|
const ctx = opts.ctx ??
|
|
@@ -28,23 +28,20 @@ export async function cmdBlock(opts) {
|
|
|
28
28
|
? await store.get(opts.taskId)
|
|
29
29
|
: await loadTaskFromContext({ ctx, taskId: opts.taskId });
|
|
30
30
|
const currentStatus = String(task.status || "TODO").toUpperCase();
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
statusTo: "BLOCKED",
|
|
46
|
-
});
|
|
47
|
-
}
|
|
31
|
+
ensureStatusTransitionAllowed({
|
|
32
|
+
currentStatus,
|
|
33
|
+
nextStatus: "BLOCKED",
|
|
34
|
+
force: opts.force,
|
|
35
|
+
});
|
|
36
|
+
ensureCommentCommitAllowed({
|
|
37
|
+
enabled: opts.commitFromComment,
|
|
38
|
+
config: ctx.config,
|
|
39
|
+
action: "block",
|
|
40
|
+
confirmed: opts.confirmStatusCommit,
|
|
41
|
+
quiet: opts.quiet,
|
|
42
|
+
statusFrom: currentStatus,
|
|
43
|
+
statusTo: "BLOCKED",
|
|
44
|
+
});
|
|
48
45
|
const formattedComment = opts.commitFromComment
|
|
49
46
|
? formatCommentBodyForCommit(opts.body, ctx.config)
|
|
50
47
|
: null;
|
|
@@ -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;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,
|
|
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,CAqUlB"}
|
|
@@ -40,7 +40,14 @@ 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
|
-
|
|
43
|
+
const autoStatusCommit = (ctx.config.finish_auto_status_commit === true ||
|
|
44
|
+
ctx.config.commit_automation === "finish_only") &&
|
|
45
|
+
!opts.commitFromComment &&
|
|
46
|
+
!opts.statusCommit &&
|
|
47
|
+
opts.closeCommit !== true &&
|
|
48
|
+
opts.taskIds.length === 1;
|
|
49
|
+
const statusCommitRequested = opts.statusCommit || autoStatusCommit;
|
|
50
|
+
if ((opts.commitFromComment || statusCommitRequested) && opts.taskIds.length !== 1) {
|
|
44
51
|
throw new CliError({
|
|
45
52
|
exitCode: 2,
|
|
46
53
|
code: "E_USAGE",
|
|
@@ -62,7 +69,7 @@ export async function cmdFinish(opts) {
|
|
|
62
69
|
});
|
|
63
70
|
}
|
|
64
71
|
const primaryTaskId = opts.taskIds[0] ?? "";
|
|
65
|
-
if ((opts.commitFromComment ||
|
|
72
|
+
if ((opts.commitFromComment || statusCommitRequested) && !primaryTaskId) {
|
|
66
73
|
throw new CliError({
|
|
67
74
|
exitCode: 2,
|
|
68
75
|
code: "E_USAGE",
|
|
@@ -102,7 +109,7 @@ export async function cmdFinish(opts) {
|
|
|
102
109
|
}
|
|
103
110
|
}
|
|
104
111
|
if (taskId === primaryTaskId &&
|
|
105
|
-
(opts.commitFromComment ||
|
|
112
|
+
(opts.commitFromComment || statusCommitRequested) &&
|
|
106
113
|
primaryStatusFrom === null) {
|
|
107
114
|
primaryStatusFrom = String(task.status || "TODO").toUpperCase();
|
|
108
115
|
primaryTag = resolvePrimaryTag(toStringArray(task.tags), ctx).primary;
|
|
@@ -157,11 +164,11 @@ export async function cmdFinish(opts) {
|
|
|
157
164
|
? store.update(taskId, () => nextTask)
|
|
158
165
|
: ctx.taskBackend.writeTask(nextTask));
|
|
159
166
|
}
|
|
160
|
-
if (opts.commitFromComment ||
|
|
167
|
+
if (opts.commitFromComment || statusCommitRequested) {
|
|
161
168
|
enforceStatusCommitPolicy({
|
|
162
169
|
policy: ctx.config.status_commit_policy,
|
|
163
170
|
action: "finish",
|
|
164
|
-
confirmed: opts.confirmStatusCommit,
|
|
171
|
+
confirmed: opts.confirmStatusCommit || autoStatusCommit,
|
|
165
172
|
quiet: opts.quiet,
|
|
166
173
|
statusFrom: primaryStatusFrom ?? "UNKNOWN",
|
|
167
174
|
statusTo: "DONE",
|
|
@@ -169,7 +176,7 @@ export async function cmdFinish(opts) {
|
|
|
169
176
|
}
|
|
170
177
|
// tasks.json is export-only; generated via `agentplane task export`.
|
|
171
178
|
let executorAgent = null;
|
|
172
|
-
if (opts.commitFromComment ||
|
|
179
|
+
if (opts.commitFromComment || statusCommitRequested) {
|
|
173
180
|
const mode = ctx.config.workflow_mode;
|
|
174
181
|
executorAgent = opts.author;
|
|
175
182
|
if (mode === "direct") {
|
|
@@ -240,7 +247,7 @@ export async function cmdFinish(opts) {
|
|
|
240
247
|
await ctx.git.commitAmendNoEdit({ env });
|
|
241
248
|
}
|
|
242
249
|
}
|
|
243
|
-
if (
|
|
250
|
+
if (statusCommitRequested) {
|
|
244
251
|
if (typeof opts.statusCommitEmoji === "string" && opts.statusCommitEmoji.trim() !== "✅") {
|
|
245
252
|
throw new CliError({
|
|
246
253
|
exitCode: 2,
|
|
@@ -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;AAmDnC,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,CA6ElB;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"}
|
|
@@ -25,6 +25,9 @@ async function loadPlanTask(opts) {
|
|
|
25
25
|
}
|
|
26
26
|
return { ctx, backend: backend, task, useStore, store };
|
|
27
27
|
}
|
|
28
|
+
function normalizeForComparison(text) {
|
|
29
|
+
return text.replaceAll("\r\n", "\n").trim();
|
|
30
|
+
}
|
|
28
31
|
export async function cmdTaskPlanSet(opts) {
|
|
29
32
|
try {
|
|
30
33
|
const { ctx, backend, task, useStore, store } = await loadPlanTask({
|
|
@@ -69,15 +72,24 @@ export async function cmdTaskPlanSet(opts) {
|
|
|
69
72
|
? String(task.doc ?? "")
|
|
70
73
|
: (typeof task.doc === "string" ? task.doc : "") || (await backend.getTaskDoc(task.id));
|
|
71
74
|
const baseDoc = ensureDocSections(existingDoc ?? "", config.tasks.doc.required_sections);
|
|
75
|
+
const currentPlan = extractDocSection(baseDoc, "Plan") ?? "";
|
|
76
|
+
const planChanged = normalizeForComparison(currentPlan) !== normalizeForComparison(text);
|
|
72
77
|
const nextDoc = ensureDocSections(setMarkdownSection(baseDoc, "Plan", text), config.tasks.doc.required_sections);
|
|
78
|
+
const docChanged = nextDoc !== baseDoc;
|
|
79
|
+
const readmePath = path.join(resolved.gitRoot, config.paths.workflow_dir, task.id, "README.md");
|
|
80
|
+
if (!planChanged && !docChanged && !updatedBy) {
|
|
81
|
+
process.stdout.write(`${readmePath}\n`);
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
73
84
|
const nextTask = {
|
|
74
85
|
...task,
|
|
75
86
|
doc: nextDoc,
|
|
76
|
-
|
|
87
|
+
...(planChanged
|
|
88
|
+
? { plan_approval: { state: "pending", updated_at: null, updated_by: null, note: null } }
|
|
89
|
+
: {}),
|
|
77
90
|
...(updatedBy ? { doc_updated_by: updatedBy } : {}),
|
|
78
91
|
};
|
|
79
92
|
await (useStore ? store.update(opts.taskId, () => nextTask) : backend.writeTask(nextTask));
|
|
80
|
-
const readmePath = path.join(resolved.gitRoot, config.paths.workflow_dir, task.id, "README.md");
|
|
81
93
|
process.stdout.write(`${readmePath}\n`);
|
|
82
94
|
return 0;
|
|
83
95
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ready.d.ts","sourceRoot":"","sources":["../../../src/commands/task/ready.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIpF,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"ready.d.ts","sourceRoot":"","sources":["../../../src/commands/task/ready.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIpF,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsDlB"}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { mapBackendError } from "../../cli/error-map.js";
|
|
2
2
|
import { successMessage, unknownEntityMessage, warnMessage } from "../../cli/output.js";
|
|
3
3
|
import { loadCommandContext } from "../shared/task-backend.js";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveTaskDependencyState } from "./shared.js";
|
|
5
5
|
export async function cmdReady(opts) {
|
|
6
6
|
try {
|
|
7
7
|
const ctx = opts.ctx ??
|
|
8
8
|
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
9
|
-
const
|
|
10
|
-
const depState = buildDependencyState(tasks);
|
|
11
|
-
const task = tasks.find((item) => item.id === opts.taskId);
|
|
9
|
+
const task = await ctx.taskBackend.getTask(opts.taskId);
|
|
12
10
|
const warnings = [];
|
|
11
|
+
let dep = null;
|
|
13
12
|
if (task) {
|
|
14
|
-
|
|
15
|
-
const missing = dep
|
|
16
|
-
const incomplete = dep
|
|
13
|
+
dep = await resolveTaskDependencyState(task, ctx.taskBackend);
|
|
14
|
+
const missing = dep.missing;
|
|
15
|
+
const incomplete = dep.incomplete;
|
|
17
16
|
if (missing.length > 0) {
|
|
18
17
|
warnings.push(`${task.id}: missing deps: ${missing.join(", ")}`);
|
|
19
18
|
}
|
|
@@ -31,7 +30,6 @@ export async function cmdReady(opts) {
|
|
|
31
30
|
const status = String(task.status || "TODO").toUpperCase();
|
|
32
31
|
const title = task.title?.trim() || "(untitled task)";
|
|
33
32
|
const owner = task.owner?.trim() || "-";
|
|
34
|
-
const dep = depState.get(task.id);
|
|
35
33
|
const dependsOn = dep?.dependsOn ?? [];
|
|
36
34
|
process.stdout.write(`Task: ${task.id} [${status}] ${title}\n`);
|
|
37
35
|
process.stdout.write(`Owner: ${owner}\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set-status.d.ts","sourceRoot":"","sources":["../../../src/commands/task/set-status.ts"],"names":[],"mappings":"AAQA,OAAO,
|
|
1
|
+
{"version":3,"file":"set-status.d.ts","sourceRoot":"","sources":["../../../src/commands/task/set-status.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,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,CAwJlB"}
|
|
@@ -4,9 +4,9 @@ import { formatCommentBodyForCommit } from "../../shared/comment-format.js";
|
|
|
4
4
|
import { CliError } from "../../shared/errors.js";
|
|
5
5
|
import { commitFromComment } from "../guard/index.js";
|
|
6
6
|
import { ensureActionApproved } from "../shared/approval-requirements.js";
|
|
7
|
-
import {
|
|
7
|
+
import { loadCommandContext, loadTaskFromContext, resolveDocUpdatedBy, } from "../shared/task-backend.js";
|
|
8
8
|
import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
|
|
9
|
-
import { appendTaskEvent,
|
|
9
|
+
import { appendTaskEvent, defaultCommitEmojiForStatus, ensureCommentCommitAllowed, ensureStatusTransitionAllowed, normalizeTaskStatus, nowIso, readCommitInfo, resolveTaskDependencyState, 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) {
|
|
@@ -42,18 +42,14 @@ export async function cmdTaskSetStatus(opts) {
|
|
|
42
42
|
? await store.get(opts.taskId)
|
|
43
43
|
: await loadTaskFromContext({ ctx, taskId: opts.taskId });
|
|
44
44
|
const currentStatus = String(task.status || "TODO").toUpperCase();
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
});
|
|
51
|
-
}
|
|
45
|
+
ensureStatusTransitionAllowed({
|
|
46
|
+
currentStatus,
|
|
47
|
+
nextStatus,
|
|
48
|
+
force: opts.force,
|
|
49
|
+
});
|
|
52
50
|
if (!opts.force && (nextStatus === "DOING" || nextStatus === "DONE")) {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
const dep = depState.get(task.id);
|
|
56
|
-
if (dep && (dep.missing.length > 0 || dep.incomplete.length > 0)) {
|
|
51
|
+
const dep = await resolveTaskDependencyState(task, ctx.taskBackend);
|
|
52
|
+
if (dep.missing.length > 0 || dep.incomplete.length > 0) {
|
|
57
53
|
if (!opts.quiet) {
|
|
58
54
|
if (dep.missing.length > 0) {
|
|
59
55
|
process.stderr.write(`${warnMessage(`missing deps: ${dep.missing.join(", ")}`)}\n`);
|
|
@@ -69,16 +65,15 @@ export async function cmdTaskSetStatus(opts) {
|
|
|
69
65
|
});
|
|
70
66
|
}
|
|
71
67
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
68
|
+
ensureCommentCommitAllowed({
|
|
69
|
+
enabled: opts.commitFromComment,
|
|
70
|
+
config,
|
|
71
|
+
action: "task set-status",
|
|
72
|
+
confirmed: opts.confirmStatusCommit,
|
|
73
|
+
quiet: opts.quiet,
|
|
74
|
+
statusFrom: currentStatus,
|
|
75
|
+
statusTo: nextStatus,
|
|
76
|
+
});
|
|
82
77
|
const existingComments = Array.isArray(task.comments)
|
|
83
78
|
? task.comments.filter((item) => !!item && typeof item.author === "string" && typeof item.body === "string")
|
|
84
79
|
: [];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
2
|
import { type AgentplaneConfig } from "@agentplaneorg/core";
|
|
3
|
-
import { type TaskData, type TaskEvent } from "../../backends/task-backend.js";
|
|
3
|
+
import { type TaskBackend, type TaskData, type TaskEvent } from "../../backends/task-backend.js";
|
|
4
4
|
import type { CommandContext } from "../shared/task-backend.js";
|
|
5
5
|
export { dedupeStrings } from "../../shared/strings.js";
|
|
6
6
|
export declare const execFileAsync: typeof execFile.__promisify__;
|
|
@@ -37,9 +37,24 @@ export type DependencyState = {
|
|
|
37
37
|
missing: string[];
|
|
38
38
|
incomplete: string[];
|
|
39
39
|
};
|
|
40
|
+
export declare function resolveTaskDependencyState(task: TaskData, backend: Pick<TaskBackend, "getTask" | "getTasks">): Promise<DependencyState>;
|
|
40
41
|
export declare function buildDependencyState(tasks: TaskData[]): Map<string, DependencyState>;
|
|
41
42
|
export declare function formatTaskLine(task: TaskData, depState?: DependencyState): string;
|
|
42
43
|
export declare function isTransitionAllowed(current: string, next: string): boolean;
|
|
44
|
+
export declare function ensureStatusTransitionAllowed(opts: {
|
|
45
|
+
currentStatus: string;
|
|
46
|
+
nextStatus: string;
|
|
47
|
+
force: boolean;
|
|
48
|
+
}): void;
|
|
49
|
+
export declare function ensureCommentCommitAllowed(opts: {
|
|
50
|
+
enabled: boolean;
|
|
51
|
+
config: AgentplaneConfig;
|
|
52
|
+
action: string;
|
|
53
|
+
confirmed: boolean;
|
|
54
|
+
quiet: boolean;
|
|
55
|
+
statusFrom: string;
|
|
56
|
+
statusTo: string;
|
|
57
|
+
}): void;
|
|
43
58
|
export declare function requireStructuredComment(body: string, prefix: string, minChars: number): void;
|
|
44
59
|
export declare function readHeadCommit(cwd: string): Promise<{
|
|
45
60
|
hash: 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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"}
|
|
@@ -249,6 +249,28 @@ export function ensureVerificationSatisfiedIfRequired(task, config) {
|
|
|
249
249
|
`(verification.state=${JSON.stringify(state)}; ${hint} or set agents.approvals.require_verify=false).`,
|
|
250
250
|
});
|
|
251
251
|
}
|
|
252
|
+
export async function resolveTaskDependencyState(task, backend) {
|
|
253
|
+
const dependsOn = dedupeStrings(toStringArray(task.depends_on));
|
|
254
|
+
if (dependsOn.length === 0) {
|
|
255
|
+
return { dependsOn, missing: [], incomplete: [] };
|
|
256
|
+
}
|
|
257
|
+
const loaded = backend.getTasks
|
|
258
|
+
? await backend.getTasks(dependsOn)
|
|
259
|
+
: await Promise.all(dependsOn.map(async (depId) => await backend.getTask(depId)));
|
|
260
|
+
const missing = [];
|
|
261
|
+
const incomplete = [];
|
|
262
|
+
for (const [idx, depId] of dependsOn.entries()) {
|
|
263
|
+
const dep = loaded[idx] ?? null;
|
|
264
|
+
if (!dep) {
|
|
265
|
+
missing.push(depId);
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
const status = String(dep.status || "TODO").toUpperCase();
|
|
269
|
+
if (status !== "DONE")
|
|
270
|
+
incomplete.push(depId);
|
|
271
|
+
}
|
|
272
|
+
return { dependsOn, missing, incomplete };
|
|
273
|
+
}
|
|
252
274
|
export function buildDependencyState(tasks) {
|
|
253
275
|
const byId = new Map(tasks.map((task) => [task.id, task]));
|
|
254
276
|
const state = new Map();
|
|
@@ -321,6 +343,38 @@ export function isTransitionAllowed(current, next) {
|
|
|
321
343
|
return false;
|
|
322
344
|
return false;
|
|
323
345
|
}
|
|
346
|
+
export function ensureStatusTransitionAllowed(opts) {
|
|
347
|
+
if (opts.force)
|
|
348
|
+
return;
|
|
349
|
+
if (isTransitionAllowed(opts.currentStatus, opts.nextStatus))
|
|
350
|
+
return;
|
|
351
|
+
throw new CliError({
|
|
352
|
+
exitCode: 2,
|
|
353
|
+
code: "E_USAGE",
|
|
354
|
+
message: `Refusing status transition ${opts.currentStatus} -> ${opts.nextStatus} ` +
|
|
355
|
+
"(use --force to override)",
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
export function ensureCommentCommitAllowed(opts) {
|
|
359
|
+
if (!opts.enabled)
|
|
360
|
+
return;
|
|
361
|
+
if (opts.config.commit_automation === "finish_only") {
|
|
362
|
+
throw new CliError({
|
|
363
|
+
exitCode: 2,
|
|
364
|
+
code: "E_USAGE",
|
|
365
|
+
message: `${opts.action}: --commit-from-comment is disabled by commit_automation='finish_only' ` +
|
|
366
|
+
"(allowed only in finish).",
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
enforceStatusCommitPolicy({
|
|
370
|
+
policy: opts.config.status_commit_policy,
|
|
371
|
+
action: opts.action,
|
|
372
|
+
confirmed: opts.confirmed,
|
|
373
|
+
quiet: opts.quiet,
|
|
374
|
+
statusFrom: opts.statusFrom,
|
|
375
|
+
statusTo: opts.statusTo,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
324
378
|
export function requireStructuredComment(body, prefix, minChars) {
|
|
325
379
|
const normalized = body.trim();
|
|
326
380
|
if (!normalized.toLowerCase().startsWith(prefix.toLowerCase())) {
|
|
@@ -375,9 +429,6 @@ const MAJOR_STATUS_COMMIT_TRANSITIONS = new Set([
|
|
|
375
429
|
"DOING->BLOCKED",
|
|
376
430
|
"BLOCKED->DOING",
|
|
377
431
|
"DOING->DONE",
|
|
378
|
-
"DONE->VERIFIED",
|
|
379
|
-
"VERIFIED->FINISHED",
|
|
380
|
-
"VERIFIED->EXPORTED",
|
|
381
432
|
]);
|
|
382
433
|
export function isMajorStatusCommitTransition(statusFrom, statusTo) {
|
|
383
434
|
const from = statusFrom.trim().toUpperCase();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-ready.d.ts","sourceRoot":"","sources":["../../../src/commands/task/start-ready.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"start-ready.d.ts","sourceRoot":"","sources":["../../../src/commands/task/start-ready.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIpF,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,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BlB"}
|
|
@@ -1,26 +1,13 @@
|
|
|
1
1
|
import { mapBackendError } from "../../cli/error-map.js";
|
|
2
|
+
import { successMessage } from "../../cli/output.js";
|
|
2
3
|
import { CliError } from "../../shared/errors.js";
|
|
3
4
|
import { loadCommandContext } from "../shared/task-backend.js";
|
|
4
|
-
import { cmdReady } from "./ready.js";
|
|
5
5
|
import { cmdStart } from "./start.js";
|
|
6
6
|
export async function cmdTaskStartReady(opts) {
|
|
7
7
|
try {
|
|
8
8
|
const ctx = opts.ctx ??
|
|
9
9
|
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
10
|
-
const
|
|
11
|
-
ctx,
|
|
12
|
-
cwd: opts.cwd,
|
|
13
|
-
rootOverride: opts.rootOverride,
|
|
14
|
-
taskId: opts.taskId,
|
|
15
|
-
});
|
|
16
|
-
if (readyCode !== 0 && !opts.force) {
|
|
17
|
-
throw new CliError({
|
|
18
|
-
exitCode: 2,
|
|
19
|
-
code: "E_USAGE",
|
|
20
|
-
message: `Task is not ready: ${opts.taskId} (resolve dependencies or use --force)`,
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
return await cmdStart({
|
|
10
|
+
const result = await cmdStart({
|
|
24
11
|
ctx,
|
|
25
12
|
cwd: opts.cwd,
|
|
26
13
|
rootOverride: opts.rootOverride,
|
|
@@ -37,6 +24,10 @@ export async function cmdTaskStartReady(opts) {
|
|
|
37
24
|
yes: opts.yes,
|
|
38
25
|
quiet: opts.quiet,
|
|
39
26
|
});
|
|
27
|
+
if (!opts.quiet) {
|
|
28
|
+
process.stdout.write(`${successMessage("ready", opts.taskId)}\n`);
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
40
31
|
}
|
|
41
32
|
catch (err) {
|
|
42
33
|
if (err instanceof CliError)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/commands/task/start.ts"],"names":[],"mappings":"AAQA,OAAO,
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/commands/task/start.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAqBnC,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,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,EAAE,MAAM,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;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+LlB"}
|
|
@@ -4,10 +4,10 @@ import { formatCommentBodyForCommit } from "../../shared/comment-format.js";
|
|
|
4
4
|
import { CliError } from "../../shared/errors.js";
|
|
5
5
|
import { commitFromComment } from "../guard/index.js";
|
|
6
6
|
import { ensureActionApproved } from "../shared/approval-requirements.js";
|
|
7
|
-
import {
|
|
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,
|
|
10
|
+
import { appendTaskEvent, ensurePlanApprovedIfRequired, ensureCommentCommitAllowed, ensureStatusTransitionAllowed, defaultCommitEmojiForAgentId, extractDocSection, isVerifyStepsFilled, nowIso, requiresVerifyStepsByPrimary, requireStructuredComment, resolveTaskDependencyState, resolvePrimaryTag, toStringArray, } from "./shared.js";
|
|
11
11
|
export async function cmdStart(opts) {
|
|
12
12
|
try {
|
|
13
13
|
const ctx = opts.ctx ??
|
|
@@ -61,28 +61,23 @@ export async function cmdStart(opts) {
|
|
|
61
61
|
}
|
|
62
62
|
ensurePlanApprovedIfRequired(task, ctx.config);
|
|
63
63
|
const currentStatus = String(task.status || "TODO").toUpperCase();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
statusTo: "DOING",
|
|
79
|
-
});
|
|
80
|
-
}
|
|
64
|
+
ensureStatusTransitionAllowed({
|
|
65
|
+
currentStatus,
|
|
66
|
+
nextStatus: "DOING",
|
|
67
|
+
force: opts.force,
|
|
68
|
+
});
|
|
69
|
+
ensureCommentCommitAllowed({
|
|
70
|
+
enabled: opts.commitFromComment,
|
|
71
|
+
config: ctx.config,
|
|
72
|
+
action: "start",
|
|
73
|
+
confirmed: opts.confirmStatusCommit,
|
|
74
|
+
quiet: opts.quiet,
|
|
75
|
+
statusFrom: currentStatus,
|
|
76
|
+
statusTo: "DOING",
|
|
77
|
+
});
|
|
81
78
|
if (!opts.force) {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
const dep = depState.get(task.id);
|
|
85
|
-
if (dep && (dep.missing.length > 0 || dep.incomplete.length > 0)) {
|
|
79
|
+
const dep = await resolveTaskDependencyState(task, ctx.taskBackend);
|
|
80
|
+
if (dep.missing.length > 0 || dep.incomplete.length > 0) {
|
|
86
81
|
if (!opts.quiet) {
|
|
87
82
|
if (dep.missing.length > 0) {
|
|
88
83
|
process.stderr.write(`${warnMessage(`missing deps: ${dep.missing.join(", ")}`)}\n`);
|