agentplane 0.2.6 → 0.2.13
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 +11 -0
- package/assets/AGENTS.md +35 -0
- package/assets/agents/CODER.json +0 -1
- package/assets/agents/INTEGRATOR.json +0 -1
- package/assets/agents/ORCHESTRATOR.json +1 -2
- package/assets/agents/PLANNER.json +1 -3
- package/assets/agents/TESTER.json +0 -1
- package/assets/agents/UPGRADER.json +17 -15
- package/dist/cli/archive.d.ts.map +1 -1
- package/dist/cli/archive.js +61 -36
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +5 -3
- package/dist/cli/run-cli/command-catalog.d.ts +4 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog.js +44 -26
- package/dist/cli/run-cli/commands/config.d.ts +5 -4
- package/dist/cli/run-cli/commands/config.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/config.js +47 -58
- package/dist/cli/run-cli/commands/core.d.ts +2 -1
- package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core.js +187 -51
- package/dist/cli/run-cli/commands/ide.d.ts +3 -1
- package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/ide.js +7 -12
- package/dist/cli/run-cli/commands/init/ide-sync.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/ide-sync.js +10 -1
- package/dist/cli/run-cli/commands/init/write-agents.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-agents.js +4 -24
- package/dist/cli/run-cli/commands/init/write-gitignore.d.ts +5 -0
- package/dist/cli/run-cli/commands/init/write-gitignore.d.ts.map +1 -0
- package/dist/cli/run-cli/commands/init/write-gitignore.js +48 -0
- 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 +34 -8
- package/dist/cli/run-cli/commands/wrap-command.d.ts +6 -0
- package/dist/cli/run-cli/commands/wrap-command.d.ts.map +1 -0
- package/dist/cli/run-cli/commands/wrap-command.js +17 -0
- package/dist/cli/run-cli/registry.run.d.ts +6 -2
- package/dist/cli/run-cli/registry.run.d.ts.map +1 -1
- package/dist/cli/run-cli/registry.run.js +7 -2
- package/dist/cli/run-cli.d.ts.map +1 -1
- package/dist/cli/run-cli.js +96 -75
- package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +99 -3
- package/dist/cli/spec/parse-utils.d.ts +11 -0
- package/dist/cli/spec/parse-utils.d.ts.map +1 -0
- package/dist/cli/spec/parse-utils.js +28 -0
- package/dist/commands/block.command.d.ts +3 -18
- package/dist/commands/block.command.d.ts.map +1 -1
- package/dist/commands/block.command.js +2 -143
- package/dist/commands/block.run.d.ts +5 -0
- package/dist/commands/block.run.d.ts.map +1 -0
- package/dist/commands/block.run.js +22 -0
- package/dist/commands/block.spec.d.ts +17 -0
- package/dist/commands/block.spec.d.ts.map +1 -0
- package/dist/commands/block.spec.js +115 -0
- package/dist/commands/doctor.command.d.ts +2 -7
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +2 -137
- package/dist/commands/doctor.run.d.ts +4 -0
- package/dist/commands/doctor.run.d.ts.map +1 -0
- package/dist/commands/doctor.run.js +174 -0
- package/dist/commands/doctor.spec.d.ts +7 -0
- package/dist/commands/doctor.spec.d.ts.map +1 -0
- package/dist/commands/doctor.spec.js +20 -0
- package/dist/commands/finish.command.d.ts +3 -27
- package/dist/commands/finish.command.d.ts.map +1 -1
- package/dist/commands/finish.command.js +2 -237
- package/dist/commands/finish.run.d.ts +5 -0
- package/dist/commands/finish.run.d.ts.map +1 -0
- package/dist/commands/finish.run.js +40 -0
- package/dist/commands/finish.spec.d.ts +26 -0
- package/dist/commands/finish.spec.d.ts.map +1 -0
- package/dist/commands/finish.spec.js +193 -0
- package/dist/commands/recipes/install.command.d.ts +2 -11
- package/dist/commands/recipes/install.command.d.ts.map +1 -1
- package/dist/commands/recipes/install.command.js +2 -161
- package/dist/commands/recipes/install.run.d.ts +4 -0
- package/dist/commands/recipes/install.run.d.ts.map +1 -0
- package/dist/commands/recipes/install.run.js +23 -0
- package/dist/commands/recipes/install.spec.d.ts +11 -0
- package/dist/commands/recipes/install.spec.d.ts.map +1 -0
- package/dist/commands/recipes/install.spec.js +140 -0
- package/dist/commands/release/apply.command.d.ts +11 -0
- package/dist/commands/release/apply.command.d.ts.map +1 -0
- package/dist/commands/release/apply.command.js +343 -0
- package/dist/commands/release/plan.command.d.ts +12 -0
- package/dist/commands/release/plan.command.d.ts.map +1 -0
- package/dist/commands/release/plan.command.js +206 -0
- package/dist/commands/release/release.command.d.ts +5 -0
- package/dist/commands/release/release.command.d.ts.map +1 -0
- package/dist/commands/release/release.command.js +18 -0
- package/dist/commands/shared/git-context.d.ts +3 -0
- package/dist/commands/shared/git-context.d.ts.map +1 -1
- package/dist/commands/shared/git-context.js +10 -0
- package/dist/commands/shared/task-backend.d.ts +1 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/start.command.d.ts +3 -18
- package/dist/commands/start.command.d.ts.map +1 -1
- package/dist/commands/start.command.js +2 -143
- package/dist/commands/start.run.d.ts +5 -0
- package/dist/commands/start.run.d.ts.map +1 -0
- package/dist/commands/start.run.js +22 -0
- package/dist/commands/start.spec.d.ts +17 -0
- package/dist/commands/start.spec.d.ts.map +1 -0
- package/dist/commands/start.spec.js +115 -0
- package/dist/commands/task/add.command.d.ts.map +1 -1
- package/dist/commands/task/add.command.js +1 -7
- package/dist/commands/task/derive.command.d.ts.map +1 -1
- package/dist/commands/task/derive.command.js +1 -7
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +34 -2
- package/dist/commands/task/list.command.d.ts +3 -8
- package/dist/commands/task/list.command.d.ts.map +1 -1
- package/dist/commands/task/list.command.js +2 -67
- package/dist/commands/task/list.run.d.ts +5 -0
- package/dist/commands/task/list.run.d.ts.map +1 -0
- package/dist/commands/task/list.run.js +10 -0
- package/dist/commands/task/list.spec.d.ts +7 -0
- package/dist/commands/task/list.spec.d.ts.map +1 -0
- package/dist/commands/task/list.spec.js +51 -0
- package/dist/commands/task/next.command.d.ts +3 -8
- package/dist/commands/task/next.command.d.ts.map +1 -1
- package/dist/commands/task/next.command.js +2 -89
- package/dist/commands/task/next.run.d.ts +5 -0
- package/dist/commands/task/next.run.d.ts.map +1 -0
- package/dist/commands/task/next.run.js +11 -0
- package/dist/commands/task/next.spec.d.ts +7 -0
- package/dist/commands/task/next.spec.d.ts.map +1 -0
- package/dist/commands/task/next.spec.js +69 -0
- package/dist/commands/task/search.command.d.ts +3 -10
- package/dist/commands/task/search.command.d.ts.map +1 -1
- package/dist/commands/task/search.command.js +2 -101
- package/dist/commands/task/search.run.d.ts +5 -0
- package/dist/commands/task/search.run.d.ts.map +1 -0
- package/dist/commands/task/search.run.js +13 -0
- package/dist/commands/task/search.spec.d.ts +9 -0
- package/dist/commands/task/search.spec.d.ts.map +1 -0
- package/dist/commands/task/search.spec.js +79 -0
- package/dist/commands/task/set-status.command.d.ts.map +1 -1
- package/dist/commands/task/set-status.command.js +1 -7
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +15 -8
- package/dist/commands/task/show.command.d.ts +3 -7
- package/dist/commands/task/show.command.d.ts.map +1 -1
- package/dist/commands/task/show.command.js +2 -19
- package/dist/commands/task/show.run.d.ts +5 -0
- package/dist/commands/task/show.run.d.ts.map +1 -0
- package/dist/commands/task/show.run.js +11 -0
- package/dist/commands/task/show.spec.d.ts +6 -0
- package/dist/commands/task/show.spec.d.ts.map +1 -0
- package/dist/commands/task/show.spec.js +8 -0
- package/dist/commands/task/update.command.d.ts.map +1 -1
- package/dist/commands/task/update.command.js +1 -7
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +171 -32
- package/dist/commands/verify.command.d.ts +3 -15
- package/dist/commands/verify.command.d.ts.map +1 -1
- package/dist/commands/verify.command.js +2 -113
- package/dist/commands/verify.run.d.ts +5 -0
- package/dist/commands/verify.run.d.ts.map +1 -0
- package/dist/commands/verify.run.js +17 -0
- package/dist/commands/verify.spec.d.ts +14 -0
- package/dist/commands/verify.spec.d.ts.map +1 -0
- package/dist/commands/verify.spec.js +96 -0
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { usageError } from "./errors.js";
|
|
2
|
+
export function asTrimmedString(value) {
|
|
3
|
+
if (value === undefined || value === null)
|
|
4
|
+
return "";
|
|
5
|
+
if (typeof value === "string")
|
|
6
|
+
return value.trim();
|
|
7
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
8
|
+
return String(value).trim();
|
|
9
|
+
}
|
|
10
|
+
// Treat all other values as invalid for "string list" purposes.
|
|
11
|
+
return "";
|
|
12
|
+
}
|
|
13
|
+
export function toStringList(value) {
|
|
14
|
+
if (!Array.isArray(value))
|
|
15
|
+
return [];
|
|
16
|
+
return value.map((x) => asTrimmedString(x)).filter(Boolean);
|
|
17
|
+
}
|
|
18
|
+
export function assertNonEmptyStrings(opts) {
|
|
19
|
+
if (opts.list.length > 0 &&
|
|
20
|
+
opts.list.every((s) => typeof s === "string" && s.trim().length > 0)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
throw usageError({
|
|
24
|
+
spec: opts.spec,
|
|
25
|
+
command: opts.command,
|
|
26
|
+
message: opts.message ?? `Invalid value for ${opts.flagName}: expected one or more strings.`,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
taskId: string;
|
|
5
|
-
author: string;
|
|
6
|
-
body: string;
|
|
7
|
-
commitFromComment: boolean;
|
|
8
|
-
commitEmoji?: string;
|
|
9
|
-
commitAllow: string[];
|
|
10
|
-
commitAutoAllow: boolean;
|
|
11
|
-
commitAllowTasks: boolean;
|
|
12
|
-
commitRequireClean: boolean;
|
|
13
|
-
confirmStatusCommit: boolean;
|
|
14
|
-
force: boolean;
|
|
15
|
-
quiet: boolean;
|
|
16
|
-
};
|
|
17
|
-
export declare const blockSpec: CommandSpec<BlockParsed>;
|
|
18
|
-
export declare function makeRunBlockHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: BlockParsed) => Promise<number>;
|
|
1
|
+
export { blockSpec } from "./block.spec.js";
|
|
2
|
+
export type { BlockParsed } from "./block.spec.js";
|
|
3
|
+
export { makeRunBlockHandler } from "./block.run.js";
|
|
19
4
|
//# sourceMappingURL=block.command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.command.d.ts","sourceRoot":"","sources":["../../src/commands/block.command.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"block.command.d.ts","sourceRoot":"","sources":["../../src/commands/block.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -1,143 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
function toStringList(v) {
|
|
4
|
-
if (typeof v === "string")
|
|
5
|
-
return [v];
|
|
6
|
-
if (Array.isArray(v))
|
|
7
|
-
return v.filter((x) => typeof x === "string");
|
|
8
|
-
return [];
|
|
9
|
-
}
|
|
10
|
-
export const blockSpec = {
|
|
11
|
-
id: ["block"],
|
|
12
|
-
group: "Lifecycle",
|
|
13
|
-
summary: "Transition a task to BLOCKED and record a structured Blocked comment.",
|
|
14
|
-
args: [
|
|
15
|
-
{
|
|
16
|
-
name: "task-id",
|
|
17
|
-
required: true,
|
|
18
|
-
valueHint: "<task-id>",
|
|
19
|
-
description: "Existing task id.",
|
|
20
|
-
},
|
|
21
|
-
],
|
|
22
|
-
options: [
|
|
23
|
-
{
|
|
24
|
-
kind: "string",
|
|
25
|
-
name: "author",
|
|
26
|
-
valueHint: "<id>",
|
|
27
|
-
required: true,
|
|
28
|
-
description: "Comment author id (e.g. CODER).",
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
kind: "string",
|
|
32
|
-
name: "body",
|
|
33
|
-
valueHint: "<text>",
|
|
34
|
-
required: true,
|
|
35
|
-
description: "Structured comment body (must match the configured Blocked: prefix).",
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
kind: "boolean",
|
|
39
|
-
name: "commit-from-comment",
|
|
40
|
-
default: false,
|
|
41
|
-
description: "Create a status commit using the comment body.",
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
kind: "string",
|
|
45
|
-
name: "commit-emoji",
|
|
46
|
-
valueHint: "<emoji>",
|
|
47
|
-
description: "Override the status commit emoji (used with --commit-from-comment).",
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
kind: "string",
|
|
51
|
-
name: "commit-allow",
|
|
52
|
-
valueHint: "<path-prefix>",
|
|
53
|
-
repeatable: true,
|
|
54
|
-
description: "Repeatable. Allowlist path prefixes to stage for the status commit (used with --commit-from-comment).",
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
kind: "boolean",
|
|
58
|
-
name: "commit-auto-allow",
|
|
59
|
-
default: false,
|
|
60
|
-
description: "Auto-allow inferred allowlist paths if none are provided (used with --commit-from-comment).",
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
kind: "boolean",
|
|
64
|
-
name: "commit-allow-tasks",
|
|
65
|
-
default: true,
|
|
66
|
-
hidden: true,
|
|
67
|
-
description: "Deprecated. Tasks are always allowed for status commits.",
|
|
68
|
-
deprecated: "no-op",
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
kind: "boolean",
|
|
72
|
-
name: "commit-require-clean",
|
|
73
|
-
default: false,
|
|
74
|
-
description: "Require a clean working tree for the status commit (used with --commit-from-comment).",
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
kind: "boolean",
|
|
78
|
-
name: "confirm-status-commit",
|
|
79
|
-
default: false,
|
|
80
|
-
description: "Confirm status commit creation when status_commit_policy=confirm (used with --commit-from-comment).",
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
kind: "boolean",
|
|
84
|
-
name: "force",
|
|
85
|
-
default: false,
|
|
86
|
-
description: "Override status transition restrictions.",
|
|
87
|
-
},
|
|
88
|
-
{ kind: "boolean", name: "quiet", default: false, description: "Suppress output." },
|
|
89
|
-
],
|
|
90
|
-
examples: [
|
|
91
|
-
{
|
|
92
|
-
cmd: 'agentplane block 202602030608-F1Q8AB --author CODER --body "Blocked: waiting for review"',
|
|
93
|
-
why: "Block work on a task.",
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
cmd: 'agentplane block 202602030608-F1Q8AB --author CODER --body "Blocked: waiting for review" --commit-from-comment --commit-allow packages/agentplane/src',
|
|
97
|
-
why: "Block work and create a status commit from the comment.",
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
validateRaw: (raw) => {
|
|
101
|
-
const author = typeof raw.opts.author === "string" ? raw.opts.author.trim() : "";
|
|
102
|
-
const body = typeof raw.opts.body === "string" ? raw.opts.body.trim() : "";
|
|
103
|
-
if (!author)
|
|
104
|
-
throw usageError({ spec: blockSpec, message: "Invalid value for --author: empty." });
|
|
105
|
-
if (!body)
|
|
106
|
-
throw usageError({ spec: blockSpec, message: "Invalid value for --body: empty." });
|
|
107
|
-
},
|
|
108
|
-
parse: (raw) => ({
|
|
109
|
-
taskId: typeof raw.args["task-id"] === "string" ? raw.args["task-id"] : "",
|
|
110
|
-
author: raw.opts.author,
|
|
111
|
-
body: raw.opts.body,
|
|
112
|
-
commitFromComment: raw.opts["commit-from-comment"] === true,
|
|
113
|
-
commitEmoji: raw.opts["commit-emoji"],
|
|
114
|
-
commitAllow: toStringList(raw.opts["commit-allow"]),
|
|
115
|
-
commitAutoAllow: raw.opts["commit-auto-allow"] === true,
|
|
116
|
-
commitAllowTasks: raw.opts["commit-allow-tasks"] !== false,
|
|
117
|
-
commitRequireClean: raw.opts["commit-require-clean"] === true,
|
|
118
|
-
confirmStatusCommit: raw.opts["confirm-status-commit"] === true,
|
|
119
|
-
force: raw.opts.force === true,
|
|
120
|
-
quiet: raw.opts.quiet === true,
|
|
121
|
-
}),
|
|
122
|
-
};
|
|
123
|
-
export function makeRunBlockHandler(getCtx) {
|
|
124
|
-
return async (ctx, p) => {
|
|
125
|
-
return await cmdBlock({
|
|
126
|
-
ctx: await getCtx("block"),
|
|
127
|
-
cwd: ctx.cwd,
|
|
128
|
-
rootOverride: ctx.rootOverride,
|
|
129
|
-
taskId: p.taskId,
|
|
130
|
-
author: p.author,
|
|
131
|
-
body: p.body,
|
|
132
|
-
commitFromComment: p.commitFromComment,
|
|
133
|
-
commitEmoji: p.commitEmoji,
|
|
134
|
-
commitAllow: p.commitAllow,
|
|
135
|
-
commitAutoAllow: p.commitAutoAllow,
|
|
136
|
-
commitAllowTasks: p.commitAllowTasks,
|
|
137
|
-
commitRequireClean: p.commitRequireClean,
|
|
138
|
-
confirmStatusCommit: p.confirmStatusCommit,
|
|
139
|
-
force: p.force,
|
|
140
|
-
quiet: p.quiet,
|
|
141
|
-
});
|
|
142
|
-
};
|
|
143
|
-
}
|
|
1
|
+
export { blockSpec } from "./block.spec.js";
|
|
2
|
+
export { makeRunBlockHandler } from "./block.run.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CommandCtx } from "../cli/spec/spec.js";
|
|
2
|
+
import type { CommandContext } from "./shared/task-backend.js";
|
|
3
|
+
import type { BlockParsed } from "./block.spec.js";
|
|
4
|
+
export declare function makeRunBlockHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: BlockParsed) => Promise<number>;
|
|
5
|
+
//# sourceMappingURL=block.run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block.run.d.ts","sourceRoot":"","sources":["../../src/commands/block.run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACpE,KAAK,UAAU,EAAE,GAAG,WAAW,KAAG,OAAO,CAAC,MAAM,CAAC,CAmBhE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { cmdBlock } from "./task/block.js";
|
|
2
|
+
export function makeRunBlockHandler(getCtx) {
|
|
3
|
+
return async (ctx, p) => {
|
|
4
|
+
return await cmdBlock({
|
|
5
|
+
ctx: await getCtx("block"),
|
|
6
|
+
cwd: ctx.cwd,
|
|
7
|
+
rootOverride: ctx.rootOverride,
|
|
8
|
+
taskId: p.taskId,
|
|
9
|
+
author: p.author,
|
|
10
|
+
body: p.body,
|
|
11
|
+
commitFromComment: p.commitFromComment,
|
|
12
|
+
commitEmoji: p.commitEmoji,
|
|
13
|
+
commitAllow: p.commitAllow,
|
|
14
|
+
commitAutoAllow: p.commitAutoAllow,
|
|
15
|
+
commitAllowTasks: p.commitAllowTasks,
|
|
16
|
+
commitRequireClean: p.commitRequireClean,
|
|
17
|
+
confirmStatusCommit: p.confirmStatusCommit,
|
|
18
|
+
force: p.force,
|
|
19
|
+
quiet: p.quiet,
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CommandSpec } from "../cli/spec/spec.js";
|
|
2
|
+
export type BlockParsed = {
|
|
3
|
+
taskId: string;
|
|
4
|
+
author: string;
|
|
5
|
+
body: string;
|
|
6
|
+
commitFromComment: boolean;
|
|
7
|
+
commitEmoji?: string;
|
|
8
|
+
commitAllow: string[];
|
|
9
|
+
commitAutoAllow: boolean;
|
|
10
|
+
commitAllowTasks: boolean;
|
|
11
|
+
commitRequireClean: boolean;
|
|
12
|
+
confirmStatusCommit: boolean;
|
|
13
|
+
force: boolean;
|
|
14
|
+
quiet: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare const blockSpec: CommandSpec<BlockParsed>;
|
|
17
|
+
//# sourceMappingURL=block.spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block.spec.d.ts","sourceRoot":"","sources":["../../src/commands/block.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKvD,MAAM,MAAM,WAAW,GAAG;IACxB,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,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,WAAW,CAAC,WAAW,CAmH9C,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { usageError } from "../cli/spec/errors.js";
|
|
2
|
+
import { toStringList } from "../cli/spec/parse-utils.js";
|
|
3
|
+
export const blockSpec = {
|
|
4
|
+
id: ["block"],
|
|
5
|
+
group: "Lifecycle",
|
|
6
|
+
summary: "Transition a task to BLOCKED and record a structured Blocked comment.",
|
|
7
|
+
args: [
|
|
8
|
+
{
|
|
9
|
+
name: "task-id",
|
|
10
|
+
required: true,
|
|
11
|
+
valueHint: "<task-id>",
|
|
12
|
+
description: "Existing task id.",
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
options: [
|
|
16
|
+
{
|
|
17
|
+
kind: "string",
|
|
18
|
+
name: "author",
|
|
19
|
+
valueHint: "<id>",
|
|
20
|
+
required: true,
|
|
21
|
+
description: "Comment author id (e.g. CODER).",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
kind: "string",
|
|
25
|
+
name: "body",
|
|
26
|
+
valueHint: "<text>",
|
|
27
|
+
required: true,
|
|
28
|
+
description: "Structured comment body (must match the configured Blocked: prefix).",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
kind: "boolean",
|
|
32
|
+
name: "commit-from-comment",
|
|
33
|
+
default: false,
|
|
34
|
+
description: "Create a status commit using the comment body.",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
kind: "string",
|
|
38
|
+
name: "commit-emoji",
|
|
39
|
+
valueHint: "<emoji>",
|
|
40
|
+
description: "Override the status commit emoji (used with --commit-from-comment).",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
kind: "string",
|
|
44
|
+
name: "commit-allow",
|
|
45
|
+
valueHint: "<path-prefix>",
|
|
46
|
+
repeatable: true,
|
|
47
|
+
description: "Repeatable. Allowlist path prefixes to stage for the status commit (used with --commit-from-comment).",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
kind: "boolean",
|
|
51
|
+
name: "commit-auto-allow",
|
|
52
|
+
default: false,
|
|
53
|
+
description: "Auto-allow inferred allowlist paths if none are provided (used with --commit-from-comment).",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
kind: "boolean",
|
|
57
|
+
name: "commit-allow-tasks",
|
|
58
|
+
default: true,
|
|
59
|
+
hidden: true,
|
|
60
|
+
description: "Deprecated. Tasks are always allowed for status commits.",
|
|
61
|
+
deprecated: "no-op",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
kind: "boolean",
|
|
65
|
+
name: "commit-require-clean",
|
|
66
|
+
default: false,
|
|
67
|
+
description: "Require a clean working tree for the status commit (used with --commit-from-comment).",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
kind: "boolean",
|
|
71
|
+
name: "confirm-status-commit",
|
|
72
|
+
default: false,
|
|
73
|
+
description: "Confirm status commit creation when status_commit_policy=confirm (used with --commit-from-comment).",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
kind: "boolean",
|
|
77
|
+
name: "force",
|
|
78
|
+
default: false,
|
|
79
|
+
description: "Override status transition restrictions.",
|
|
80
|
+
},
|
|
81
|
+
{ kind: "boolean", name: "quiet", default: false, description: "Suppress output." },
|
|
82
|
+
],
|
|
83
|
+
examples: [
|
|
84
|
+
{
|
|
85
|
+
cmd: 'agentplane block 202602030608-F1Q8AB --author CODER --body "Blocked: waiting for review"',
|
|
86
|
+
why: "Block work on a task.",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
cmd: 'agentplane block 202602030608-F1Q8AB --author CODER --body "Blocked: waiting for review" --commit-from-comment --commit-allow packages/agentplane/src',
|
|
90
|
+
why: "Block work and create a status commit from the comment.",
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
validateRaw: (raw) => {
|
|
94
|
+
const author = typeof raw.opts.author === "string" ? raw.opts.author.trim() : "";
|
|
95
|
+
const body = typeof raw.opts.body === "string" ? raw.opts.body.trim() : "";
|
|
96
|
+
if (!author)
|
|
97
|
+
throw usageError({ spec: blockSpec, message: "Invalid value for --author: empty." });
|
|
98
|
+
if (!body)
|
|
99
|
+
throw usageError({ spec: blockSpec, message: "Invalid value for --body: empty." });
|
|
100
|
+
},
|
|
101
|
+
parse: (raw) => ({
|
|
102
|
+
taskId: typeof raw.args["task-id"] === "string" ? raw.args["task-id"] : "",
|
|
103
|
+
author: raw.opts.author,
|
|
104
|
+
body: raw.opts.body,
|
|
105
|
+
commitFromComment: raw.opts["commit-from-comment"] === true,
|
|
106
|
+
commitEmoji: raw.opts["commit-emoji"],
|
|
107
|
+
commitAllow: toStringList(raw.opts["commit-allow"]),
|
|
108
|
+
commitAutoAllow: raw.opts["commit-auto-allow"] === true,
|
|
109
|
+
commitAllowTasks: raw.opts["commit-allow-tasks"] !== false,
|
|
110
|
+
commitRequireClean: raw.opts["commit-require-clean"] === true,
|
|
111
|
+
confirmStatusCommit: raw.opts["confirm-status-commit"] === true,
|
|
112
|
+
force: raw.opts.force === true,
|
|
113
|
+
quiet: raw.opts.quiet === true,
|
|
114
|
+
}),
|
|
115
|
+
};
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
fix: boolean;
|
|
4
|
-
};
|
|
5
|
-
export declare const doctorSpec: CommandSpec<DoctorParsed>;
|
|
6
|
-
export declare const runDoctor: CommandHandler<DoctorParsed>;
|
|
7
|
-
export {};
|
|
1
|
+
export { doctorSpec, type DoctorParsed } from "./doctor.spec.js";
|
|
2
|
+
export { runDoctor } from "./doctor.run.js";
|
|
8
3
|
//# sourceMappingURL=doctor.command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,137 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { resolveProject } from "@agentplaneorg/core";
|
|
4
|
-
import { warnMessage, successMessage } from "../cli/output.js";
|
|
5
|
-
import { loadCommandContext } from "./shared/task-backend.js";
|
|
6
|
-
export const doctorSpec = {
|
|
7
|
-
id: ["doctor"],
|
|
8
|
-
group: "Quality",
|
|
9
|
-
summary: "Check structural invariants of an agentplane workspace (and optionally apply safe fixes).",
|
|
10
|
-
options: [{ kind: "boolean", name: "fix", default: false, description: "Apply safe fixes." }],
|
|
11
|
-
examples: [
|
|
12
|
-
{ cmd: "agentplane doctor", why: "Check layering and workspace invariants." },
|
|
13
|
-
{ cmd: "agentplane doctor --fix", why: "Apply safe-only fixes (idempotent)." },
|
|
14
|
-
],
|
|
15
|
-
parse: (raw) => ({ fix: raw.opts.fix === true }),
|
|
16
|
-
};
|
|
17
|
-
async function listTsFiles(rootDir) {
|
|
18
|
-
const out = [];
|
|
19
|
-
async function walk(absDir) {
|
|
20
|
-
const entries = await fs.readdir(absDir, { withFileTypes: true });
|
|
21
|
-
for (const ent of entries) {
|
|
22
|
-
if (ent.name.startsWith("."))
|
|
23
|
-
continue;
|
|
24
|
-
if (ent.name === "__snapshots__")
|
|
25
|
-
continue;
|
|
26
|
-
if (ent.name === "node_modules")
|
|
27
|
-
continue;
|
|
28
|
-
const abs = path.join(absDir, ent.name);
|
|
29
|
-
if (ent.isDirectory()) {
|
|
30
|
-
await walk(abs);
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
if (ent.isFile() && ent.name.endsWith(".ts")) {
|
|
34
|
-
out.push({ absPath: abs, relPath: path.relative(rootDir, abs) });
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
await walk(rootDir);
|
|
39
|
-
return out;
|
|
40
|
-
}
|
|
41
|
-
function extractImports(source) {
|
|
42
|
-
const imports = [];
|
|
43
|
-
const re = /^\s*import\s+(?:type\s+)?(?:[^"']*?\s+from\s+)?["']([^"']+)["']\s*;?/gm;
|
|
44
|
-
for (const match of source.matchAll(re)) {
|
|
45
|
-
imports.push(match[1] ?? "");
|
|
46
|
-
}
|
|
47
|
-
return imports.filter(Boolean);
|
|
48
|
-
}
|
|
49
|
-
async function checkLayering(repoRoot) {
|
|
50
|
-
const problems = [];
|
|
51
|
-
const agentplaneSrcRoot = path.join(repoRoot, "packages", "agentplane", "src");
|
|
52
|
-
const cliRoot = path.join(agentplaneSrcRoot, "cli");
|
|
53
|
-
const cliFiles = await listTsFiles(cliRoot);
|
|
54
|
-
for (const f of cliFiles) {
|
|
55
|
-
const src = await fs.readFile(f.absPath, "utf8");
|
|
56
|
-
const imports = extractImports(src);
|
|
57
|
-
const hits = imports.filter((s) => s.includes("/adapters/") ||
|
|
58
|
-
s.includes("../adapters") ||
|
|
59
|
-
s.includes("../../adapters") ||
|
|
60
|
-
s.includes("../../../adapters"));
|
|
61
|
-
if (hits.length > 0) {
|
|
62
|
-
problems.push(`${f.relPath} imports adapters directly: ${hits.join(", ")}`);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
const roots = [path.join(agentplaneSrcRoot, "usecases"), path.join(agentplaneSrcRoot, "ports")];
|
|
66
|
-
const banned = [
|
|
67
|
-
"node:fs",
|
|
68
|
-
"node:fs/promises",
|
|
69
|
-
"fs",
|
|
70
|
-
"fs/promises",
|
|
71
|
-
"node:path",
|
|
72
|
-
"path",
|
|
73
|
-
"simple-git",
|
|
74
|
-
"isomorphic-git",
|
|
75
|
-
];
|
|
76
|
-
for (const root of roots) {
|
|
77
|
-
const files = await listTsFiles(root);
|
|
78
|
-
for (const f of files) {
|
|
79
|
-
const src = await fs.readFile(f.absPath, "utf8");
|
|
80
|
-
const imports = extractImports(src);
|
|
81
|
-
const hits = imports.filter((s) => banned.some((b) => s === b || s.startsWith(`${b}/`)));
|
|
82
|
-
if (hits.length > 0) {
|
|
83
|
-
problems.push(`${f.relPath} imports banned modules: ${hits.join(", ")}`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return problems;
|
|
88
|
-
}
|
|
89
|
-
async function safeFixGitignore(repoRoot) {
|
|
90
|
-
const gitignorePath = path.join(repoRoot, ".gitignore");
|
|
91
|
-
let existing = "";
|
|
92
|
-
try {
|
|
93
|
-
existing = await fs.readFile(gitignorePath, "utf8");
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
// If .gitignore doesn't exist, do not create it implicitly (keep doctor safe).
|
|
97
|
-
return { changed: false, note: "Skip: .gitignore not found." };
|
|
98
|
-
}
|
|
99
|
-
const lines = existing.split(/\r?\n/);
|
|
100
|
-
const entry = ".agentplane/.upgrade/";
|
|
101
|
-
if (lines.some((l) => l.trim() === entry)) {
|
|
102
|
-
return { changed: false, note: "OK: .gitignore already ignores .agentplane/.upgrade/." };
|
|
103
|
-
}
|
|
104
|
-
const next = `${existing.trimEnd()}\n${entry}\n`;
|
|
105
|
-
await fs.writeFile(gitignorePath, next, "utf8");
|
|
106
|
-
return { changed: true, note: "Fixed: added .agentplane/.upgrade/ to .gitignore." };
|
|
107
|
-
}
|
|
108
|
-
async function safeFixTaskIndex(repoRoot) {
|
|
109
|
-
try {
|
|
110
|
-
// Best-effort: rebuilding the index is a side-effect of listing tasks for the local backend.
|
|
111
|
-
const ctx = await loadCommandContext({ cwd: repoRoot, rootOverride: null });
|
|
112
|
-
await ctx.taskBackend.listTasks();
|
|
113
|
-
return { changed: true, note: "OK: rebuilt tasks index cache (best-effort)." };
|
|
114
|
-
}
|
|
115
|
-
catch {
|
|
116
|
-
return { changed: false, note: "Skip: could not rebuild tasks index cache." };
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
export const runDoctor = async (ctx, p) => {
|
|
120
|
-
const resolved = await resolveProject({ cwd: ctx.cwd, rootOverride: ctx.rootOverride ?? null });
|
|
121
|
-
const repoRoot = resolved.gitRoot;
|
|
122
|
-
const problems = await checkLayering(repoRoot);
|
|
123
|
-
if (problems.length > 0) {
|
|
124
|
-
console.error(warnMessage(`doctor found ${problems.length} problem(s):`));
|
|
125
|
-
for (const prob of problems)
|
|
126
|
-
console.error(`- ${prob}`);
|
|
127
|
-
return 1;
|
|
128
|
-
}
|
|
129
|
-
if (p.fix) {
|
|
130
|
-
const fix = await safeFixGitignore(repoRoot);
|
|
131
|
-
console.log(successMessage("doctor fix", undefined, fix.note));
|
|
132
|
-
const idx = await safeFixTaskIndex(repoRoot);
|
|
133
|
-
console.log(successMessage("doctor fix", undefined, idx.note));
|
|
134
|
-
}
|
|
135
|
-
console.log(successMessage("doctor", undefined, "OK"));
|
|
136
|
-
return 0;
|
|
137
|
-
};
|
|
1
|
+
export { doctorSpec } from "./doctor.spec.js";
|
|
2
|
+
export { runDoctor } from "./doctor.run.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.run.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.run.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAoKrD,eAAO,MAAM,SAAS,EAAE,cAAc,CAAC,YAAY,CAuBlD,CAAC"}
|