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.
Files changed (166) hide show
  1. package/README.md +11 -0
  2. package/assets/AGENTS.md +35 -0
  3. package/assets/agents/CODER.json +0 -1
  4. package/assets/agents/INTEGRATOR.json +0 -1
  5. package/assets/agents/ORCHESTRATOR.json +1 -2
  6. package/assets/agents/PLANNER.json +1 -3
  7. package/assets/agents/TESTER.json +0 -1
  8. package/assets/agents/UPGRADER.json +17 -15
  9. package/dist/cli/archive.d.ts.map +1 -1
  10. package/dist/cli/archive.js +61 -36
  11. package/dist/cli/command-guide.d.ts.map +1 -1
  12. package/dist/cli/command-guide.js +5 -3
  13. package/dist/cli/run-cli/command-catalog.d.ts +4 -1
  14. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  15. package/dist/cli/run-cli/command-catalog.js +44 -26
  16. package/dist/cli/run-cli/commands/config.d.ts +5 -4
  17. package/dist/cli/run-cli/commands/config.d.ts.map +1 -1
  18. package/dist/cli/run-cli/commands/config.js +47 -58
  19. package/dist/cli/run-cli/commands/core.d.ts +2 -1
  20. package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
  21. package/dist/cli/run-cli/commands/core.js +187 -51
  22. package/dist/cli/run-cli/commands/ide.d.ts +3 -1
  23. package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
  24. package/dist/cli/run-cli/commands/ide.js +7 -12
  25. package/dist/cli/run-cli/commands/init/ide-sync.d.ts.map +1 -1
  26. package/dist/cli/run-cli/commands/init/ide-sync.js +10 -1
  27. package/dist/cli/run-cli/commands/init/write-agents.d.ts.map +1 -1
  28. package/dist/cli/run-cli/commands/init/write-agents.js +4 -24
  29. package/dist/cli/run-cli/commands/init/write-gitignore.d.ts +5 -0
  30. package/dist/cli/run-cli/commands/init/write-gitignore.d.ts.map +1 -0
  31. package/dist/cli/run-cli/commands/init/write-gitignore.js +48 -0
  32. package/dist/cli/run-cli/commands/init.d.ts +1 -0
  33. package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
  34. package/dist/cli/run-cli/commands/init.js +34 -8
  35. package/dist/cli/run-cli/commands/wrap-command.d.ts +6 -0
  36. package/dist/cli/run-cli/commands/wrap-command.d.ts.map +1 -0
  37. package/dist/cli/run-cli/commands/wrap-command.js +17 -0
  38. package/dist/cli/run-cli/registry.run.d.ts +6 -2
  39. package/dist/cli/run-cli/registry.run.d.ts.map +1 -1
  40. package/dist/cli/run-cli/registry.run.js +7 -2
  41. package/dist/cli/run-cli.d.ts.map +1 -1
  42. package/dist/cli/run-cli.js +96 -75
  43. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  44. package/dist/cli/run-cli.test-helpers.js +99 -3
  45. package/dist/cli/spec/parse-utils.d.ts +11 -0
  46. package/dist/cli/spec/parse-utils.d.ts.map +1 -0
  47. package/dist/cli/spec/parse-utils.js +28 -0
  48. package/dist/commands/block.command.d.ts +3 -18
  49. package/dist/commands/block.command.d.ts.map +1 -1
  50. package/dist/commands/block.command.js +2 -143
  51. package/dist/commands/block.run.d.ts +5 -0
  52. package/dist/commands/block.run.d.ts.map +1 -0
  53. package/dist/commands/block.run.js +22 -0
  54. package/dist/commands/block.spec.d.ts +17 -0
  55. package/dist/commands/block.spec.d.ts.map +1 -0
  56. package/dist/commands/block.spec.js +115 -0
  57. package/dist/commands/doctor.command.d.ts +2 -7
  58. package/dist/commands/doctor.command.d.ts.map +1 -1
  59. package/dist/commands/doctor.command.js +2 -137
  60. package/dist/commands/doctor.run.d.ts +4 -0
  61. package/dist/commands/doctor.run.d.ts.map +1 -0
  62. package/dist/commands/doctor.run.js +174 -0
  63. package/dist/commands/doctor.spec.d.ts +7 -0
  64. package/dist/commands/doctor.spec.d.ts.map +1 -0
  65. package/dist/commands/doctor.spec.js +20 -0
  66. package/dist/commands/finish.command.d.ts +3 -27
  67. package/dist/commands/finish.command.d.ts.map +1 -1
  68. package/dist/commands/finish.command.js +2 -237
  69. package/dist/commands/finish.run.d.ts +5 -0
  70. package/dist/commands/finish.run.d.ts.map +1 -0
  71. package/dist/commands/finish.run.js +40 -0
  72. package/dist/commands/finish.spec.d.ts +26 -0
  73. package/dist/commands/finish.spec.d.ts.map +1 -0
  74. package/dist/commands/finish.spec.js +193 -0
  75. package/dist/commands/recipes/install.command.d.ts +2 -11
  76. package/dist/commands/recipes/install.command.d.ts.map +1 -1
  77. package/dist/commands/recipes/install.command.js +2 -161
  78. package/dist/commands/recipes/install.run.d.ts +4 -0
  79. package/dist/commands/recipes/install.run.d.ts.map +1 -0
  80. package/dist/commands/recipes/install.run.js +23 -0
  81. package/dist/commands/recipes/install.spec.d.ts +11 -0
  82. package/dist/commands/recipes/install.spec.d.ts.map +1 -0
  83. package/dist/commands/recipes/install.spec.js +140 -0
  84. package/dist/commands/release/apply.command.d.ts +11 -0
  85. package/dist/commands/release/apply.command.d.ts.map +1 -0
  86. package/dist/commands/release/apply.command.js +343 -0
  87. package/dist/commands/release/plan.command.d.ts +12 -0
  88. package/dist/commands/release/plan.command.d.ts.map +1 -0
  89. package/dist/commands/release/plan.command.js +206 -0
  90. package/dist/commands/release/release.command.d.ts +5 -0
  91. package/dist/commands/release/release.command.d.ts.map +1 -0
  92. package/dist/commands/release/release.command.js +18 -0
  93. package/dist/commands/shared/git-context.d.ts +3 -0
  94. package/dist/commands/shared/git-context.d.ts.map +1 -1
  95. package/dist/commands/shared/git-context.js +10 -0
  96. package/dist/commands/shared/task-backend.d.ts +1 -0
  97. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  98. package/dist/commands/start.command.d.ts +3 -18
  99. package/dist/commands/start.command.d.ts.map +1 -1
  100. package/dist/commands/start.command.js +2 -143
  101. package/dist/commands/start.run.d.ts +5 -0
  102. package/dist/commands/start.run.d.ts.map +1 -0
  103. package/dist/commands/start.run.js +22 -0
  104. package/dist/commands/start.spec.d.ts +17 -0
  105. package/dist/commands/start.spec.d.ts.map +1 -0
  106. package/dist/commands/start.spec.js +115 -0
  107. package/dist/commands/task/add.command.d.ts.map +1 -1
  108. package/dist/commands/task/add.command.js +1 -7
  109. package/dist/commands/task/derive.command.d.ts.map +1 -1
  110. package/dist/commands/task/derive.command.js +1 -7
  111. package/dist/commands/task/finish.d.ts.map +1 -1
  112. package/dist/commands/task/finish.js +34 -2
  113. package/dist/commands/task/list.command.d.ts +3 -8
  114. package/dist/commands/task/list.command.d.ts.map +1 -1
  115. package/dist/commands/task/list.command.js +2 -67
  116. package/dist/commands/task/list.run.d.ts +5 -0
  117. package/dist/commands/task/list.run.d.ts.map +1 -0
  118. package/dist/commands/task/list.run.js +10 -0
  119. package/dist/commands/task/list.spec.d.ts +7 -0
  120. package/dist/commands/task/list.spec.d.ts.map +1 -0
  121. package/dist/commands/task/list.spec.js +51 -0
  122. package/dist/commands/task/next.command.d.ts +3 -8
  123. package/dist/commands/task/next.command.d.ts.map +1 -1
  124. package/dist/commands/task/next.command.js +2 -89
  125. package/dist/commands/task/next.run.d.ts +5 -0
  126. package/dist/commands/task/next.run.d.ts.map +1 -0
  127. package/dist/commands/task/next.run.js +11 -0
  128. package/dist/commands/task/next.spec.d.ts +7 -0
  129. package/dist/commands/task/next.spec.d.ts.map +1 -0
  130. package/dist/commands/task/next.spec.js +69 -0
  131. package/dist/commands/task/search.command.d.ts +3 -10
  132. package/dist/commands/task/search.command.d.ts.map +1 -1
  133. package/dist/commands/task/search.command.js +2 -101
  134. package/dist/commands/task/search.run.d.ts +5 -0
  135. package/dist/commands/task/search.run.d.ts.map +1 -0
  136. package/dist/commands/task/search.run.js +13 -0
  137. package/dist/commands/task/search.spec.d.ts +9 -0
  138. package/dist/commands/task/search.spec.d.ts.map +1 -0
  139. package/dist/commands/task/search.spec.js +79 -0
  140. package/dist/commands/task/set-status.command.d.ts.map +1 -1
  141. package/dist/commands/task/set-status.command.js +1 -7
  142. package/dist/commands/task/shared.d.ts.map +1 -1
  143. package/dist/commands/task/shared.js +15 -8
  144. package/dist/commands/task/show.command.d.ts +3 -7
  145. package/dist/commands/task/show.command.d.ts.map +1 -1
  146. package/dist/commands/task/show.command.js +2 -19
  147. package/dist/commands/task/show.run.d.ts +5 -0
  148. package/dist/commands/task/show.run.d.ts.map +1 -0
  149. package/dist/commands/task/show.run.js +11 -0
  150. package/dist/commands/task/show.spec.d.ts +6 -0
  151. package/dist/commands/task/show.spec.d.ts.map +1 -0
  152. package/dist/commands/task/show.spec.js +8 -0
  153. package/dist/commands/task/update.command.d.ts.map +1 -1
  154. package/dist/commands/task/update.command.js +1 -7
  155. package/dist/commands/upgrade.d.ts.map +1 -1
  156. package/dist/commands/upgrade.js +171 -32
  157. package/dist/commands/verify.command.d.ts +3 -15
  158. package/dist/commands/verify.command.d.ts.map +1 -1
  159. package/dist/commands/verify.command.js +2 -113
  160. package/dist/commands/verify.run.d.ts +5 -0
  161. package/dist/commands/verify.run.d.ts.map +1 -0
  162. package/dist/commands/verify.run.js +17 -0
  163. package/dist/commands/verify.spec.d.ts +14 -0
  164. package/dist/commands/verify.spec.d.ts.map +1 -0
  165. package/dist/commands/verify.spec.js +96 -0
  166. package/package.json +1 -1
@@ -0,0 +1,174 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { resolveProject } from "@agentplaneorg/core";
4
+ import { warnMessage, successMessage } from "../cli/output.js";
5
+ import { loadCommandContext } from "./shared/task-backend.js";
6
+ async function listTsFiles(rootDir) {
7
+ const out = [];
8
+ async function walk(absDir) {
9
+ const entries = await fs.readdir(absDir, { withFileTypes: true });
10
+ for (const ent of entries) {
11
+ if (ent.name.startsWith("."))
12
+ continue;
13
+ if (ent.name === "__snapshots__")
14
+ continue;
15
+ if (ent.name === "node_modules")
16
+ continue;
17
+ const abs = path.join(absDir, ent.name);
18
+ if (ent.isDirectory()) {
19
+ await walk(abs);
20
+ continue;
21
+ }
22
+ if (ent.isFile() && ent.name.endsWith(".ts")) {
23
+ out.push({ absPath: abs, relPath: path.relative(rootDir, abs) });
24
+ }
25
+ }
26
+ }
27
+ await walk(rootDir);
28
+ return out;
29
+ }
30
+ function extractImports(source) {
31
+ const imports = [];
32
+ const re = /^\s*import\s+(?:type\s+)?(?:[^"']*?\s+from\s+)?["']([^"']+)["']\s*;?/gm;
33
+ for (const match of source.matchAll(re)) {
34
+ imports.push(match[1] ?? "");
35
+ }
36
+ return imports.filter(Boolean);
37
+ }
38
+ async function pathExists(absPath) {
39
+ try {
40
+ await fs.access(absPath);
41
+ return true;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ async function isDirectory(absPath) {
48
+ try {
49
+ const st = await fs.stat(absPath);
50
+ return st.isDirectory();
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ async function checkWorkspace(repoRoot) {
57
+ const problems = [];
58
+ const requiredFiles = [
59
+ path.join(repoRoot, "AGENTS.md"),
60
+ path.join(repoRoot, ".agentplane", "config.json"),
61
+ ];
62
+ for (const filePath of requiredFiles) {
63
+ if (!(await pathExists(filePath))) {
64
+ problems.push(`Missing required file: ${path.relative(repoRoot, filePath)}`);
65
+ }
66
+ }
67
+ const agentsDir = path.join(repoRoot, ".agentplane", "agents");
68
+ if (!(await isDirectory(agentsDir))) {
69
+ problems.push("Missing required directory: .agentplane/agents");
70
+ return problems;
71
+ }
72
+ const entries = await fs.readdir(agentsDir);
73
+ const hasJson = entries.some((name) => name.endsWith(".json"));
74
+ if (!hasJson) {
75
+ problems.push("No agent profiles found in .agentplane/agents (*.json expected).");
76
+ }
77
+ return problems;
78
+ }
79
+ async function checkLayering(repoRoot) {
80
+ const problems = [];
81
+ const agentplaneSrcRoot = path.join(repoRoot, "packages", "agentplane", "src");
82
+ if (!(await isDirectory(agentplaneSrcRoot))) {
83
+ problems.push("Dev source checks requested but packages/agentplane/src was not found in this workspace.");
84
+ return problems;
85
+ }
86
+ const cliRoot = path.join(agentplaneSrcRoot, "cli");
87
+ const cliFiles = await listTsFiles(cliRoot);
88
+ for (const f of cliFiles) {
89
+ const src = await fs.readFile(f.absPath, "utf8");
90
+ const imports = extractImports(src);
91
+ const hits = imports.filter((s) => s.includes("/adapters/") ||
92
+ s.includes("../adapters") ||
93
+ s.includes("../../adapters") ||
94
+ s.includes("../../../adapters"));
95
+ if (hits.length > 0) {
96
+ problems.push(`${f.relPath} imports adapters directly: ${hits.join(", ")}`);
97
+ }
98
+ }
99
+ const roots = [path.join(agentplaneSrcRoot, "usecases"), path.join(agentplaneSrcRoot, "ports")];
100
+ const banned = [
101
+ "node:fs",
102
+ "node:fs/promises",
103
+ "fs",
104
+ "fs/promises",
105
+ "node:path",
106
+ "path",
107
+ "simple-git",
108
+ "isomorphic-git",
109
+ ];
110
+ for (const root of roots) {
111
+ const files = await listTsFiles(root);
112
+ for (const f of files) {
113
+ const src = await fs.readFile(f.absPath, "utf8");
114
+ const imports = extractImports(src);
115
+ const hits = imports.filter((s) => banned.some((b) => s === b || s.startsWith(`${b}/`)));
116
+ if (hits.length > 0) {
117
+ problems.push(`${f.relPath} imports banned modules: ${hits.join(", ")}`);
118
+ }
119
+ }
120
+ }
121
+ return problems;
122
+ }
123
+ async function safeFixGitignore(repoRoot) {
124
+ const gitignorePath = path.join(repoRoot, ".gitignore");
125
+ let existing = "";
126
+ try {
127
+ existing = await fs.readFile(gitignorePath, "utf8");
128
+ }
129
+ catch {
130
+ // If .gitignore doesn't exist, do not create it implicitly (keep doctor safe).
131
+ return { changed: false, note: "Skip: .gitignore not found." };
132
+ }
133
+ const lines = existing.split(/\r?\n/);
134
+ const entry = ".agentplane/.upgrade/";
135
+ if (lines.some((l) => l.trim() === entry)) {
136
+ return { changed: false, note: "OK: .gitignore already ignores .agentplane/.upgrade/." };
137
+ }
138
+ const next = `${existing.trimEnd()}\n${entry}\n`;
139
+ await fs.writeFile(gitignorePath, next, "utf8");
140
+ return { changed: true, note: "Fixed: added .agentplane/.upgrade/ to .gitignore." };
141
+ }
142
+ async function safeFixTaskIndex(repoRoot) {
143
+ try {
144
+ // Best-effort: rebuilding the index is a side-effect of listing tasks for the local backend.
145
+ const ctx = await loadCommandContext({ cwd: repoRoot, rootOverride: null });
146
+ await ctx.taskBackend.listTasks();
147
+ return { changed: true, note: "OK: rebuilt tasks index cache (best-effort)." };
148
+ }
149
+ catch {
150
+ return { changed: false, note: "Skip: could not rebuild tasks index cache." };
151
+ }
152
+ }
153
+ export const runDoctor = async (ctx, p) => {
154
+ const resolved = await resolveProject({ cwd: ctx.cwd, rootOverride: ctx.rootOverride ?? null });
155
+ const repoRoot = resolved.gitRoot;
156
+ const problems = await checkWorkspace(repoRoot);
157
+ if (p.dev) {
158
+ problems.push(...(await checkLayering(repoRoot)));
159
+ }
160
+ if (problems.length > 0) {
161
+ console.error(warnMessage(`doctor found ${problems.length} problem(s):`));
162
+ for (const prob of problems)
163
+ console.error(`- ${prob}`);
164
+ return 1;
165
+ }
166
+ if (p.fix) {
167
+ const fix = await safeFixGitignore(repoRoot);
168
+ console.log(successMessage("doctor fix", undefined, fix.note));
169
+ const idx = await safeFixTaskIndex(repoRoot);
170
+ console.log(successMessage("doctor fix", undefined, idx.note));
171
+ }
172
+ console.log(successMessage("doctor", undefined, "OK"));
173
+ return 0;
174
+ };
@@ -0,0 +1,7 @@
1
+ import type { CommandSpec } from "../cli/spec/spec.js";
2
+ export type DoctorParsed = {
3
+ fix: boolean;
4
+ dev: boolean;
5
+ };
6
+ export declare const doctorSpec: CommandSpec<DoctorParsed>;
7
+ //# sourceMappingURL=doctor.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.spec.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAoBhD,CAAC"}
@@ -0,0 +1,20 @@
1
+ export const doctorSpec = {
2
+ id: ["doctor"],
3
+ group: "Quality",
4
+ summary: "Check workspace invariants for a normal agentplane installation (with optional dev source checks).",
5
+ options: [
6
+ { kind: "boolean", name: "fix", default: false, description: "Apply safe fixes." },
7
+ {
8
+ kind: "boolean",
9
+ name: "dev",
10
+ default: false,
11
+ description: "Run monorepo source-layer checks (requires packages/agentplane/src).",
12
+ },
13
+ ],
14
+ examples: [
15
+ { cmd: "agentplane doctor", why: "Check installed workspace invariants." },
16
+ { cmd: "agentplane doctor --dev", why: "Also run monorepo source-layer checks." },
17
+ { cmd: "agentplane doctor --fix", why: "Apply safe-only fixes (idempotent)." },
18
+ ],
19
+ parse: (raw) => ({ fix: raw.opts.fix === true, dev: raw.opts.dev === true }),
20
+ };
@@ -1,28 +1,4 @@
1
- import type { CommandCtx, CommandSpec } from "../cli/spec/spec.js";
2
- import type { CommandContext } from "./shared/task-backend.js";
3
- export type FinishParsed = {
4
- taskIds: string[];
5
- author: string;
6
- body: string;
7
- result?: string;
8
- risk?: "low" | "med" | "high";
9
- breaking: boolean;
10
- commit?: string;
11
- force: boolean;
12
- commitFromComment: boolean;
13
- commitEmoji?: string;
14
- commitAllow: string[];
15
- commitAutoAllow: boolean;
16
- commitAllowTasks: boolean;
17
- commitRequireClean: boolean;
18
- statusCommit: boolean;
19
- statusCommitEmoji?: string;
20
- statusCommitAllow: string[];
21
- statusCommitAutoAllow: boolean;
22
- statusCommitRequireClean: boolean;
23
- confirmStatusCommit: boolean;
24
- quiet: boolean;
25
- };
26
- export declare const finishSpec: CommandSpec<FinishParsed>;
27
- export declare function makeRunFinishHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: FinishParsed) => Promise<number>;
1
+ export { finishSpec } from "./finish.spec.js";
2
+ export type { FinishParsed } from "./finish.spec.js";
3
+ export { makeRunFinishHandler } from "./finish.run.js";
28
4
  //# sourceMappingURL=finish.command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"finish.command.d.ts","sourceRoot":"","sources":["../../src/commands/finish.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D,MAAM,MAAM,YAAY,GAAG;IACzB,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,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,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAQF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAsMhD,CAAC;AAEF,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,CAmCjE"}
1
+ {"version":3,"file":"finish.command.d.ts","sourceRoot":"","sources":["../../src/commands/finish.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,237 +1,2 @@
1
- import { usageError } from "../cli/spec/errors.js";
2
- import { cmdFinish } from "./task/finish.js";
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 finishSpec = {
11
- id: ["finish"],
12
- group: "Lifecycle",
13
- summary: "Mark task(s) as DONE and record a structured Verified comment.",
14
- args: [
15
- {
16
- name: "task-id",
17
- required: true,
18
- variadic: true,
19
- valueHint: "<task-id>",
20
- description: "One or more existing task ids.",
21
- },
22
- ],
23
- options: [
24
- {
25
- kind: "string",
26
- name: "author",
27
- valueHint: "<id>",
28
- required: true,
29
- description: "Comment author id (e.g. INTEGRATOR).",
30
- },
31
- {
32
- kind: "string",
33
- name: "body",
34
- valueHint: "<text>",
35
- required: true,
36
- description: "Structured comment body (must match the configured Verified: prefix).",
37
- },
38
- {
39
- kind: "string",
40
- name: "result",
41
- valueHint: "<one-line>",
42
- description: "One-line result summary stored in task metadata (required for non-spike tasks when finishing a single task).",
43
- },
44
- {
45
- kind: "string",
46
- name: "risk",
47
- valueHint: "<low|med|high>",
48
- choices: ["low", "med", "high"],
49
- description: "Optional. Risk level stored in task metadata.",
50
- },
51
- {
52
- kind: "boolean",
53
- name: "breaking",
54
- default: false,
55
- description: "Optional. Mark the change as breaking in task metadata.",
56
- },
57
- {
58
- kind: "string",
59
- name: "commit",
60
- valueHint: "<hash>",
61
- description: "Commit hash to record on the task (optional).",
62
- },
63
- { kind: "boolean", name: "force", default: false, description: "Force finish despite gates." },
64
- {
65
- kind: "boolean",
66
- name: "commit-from-comment",
67
- default: false,
68
- description: "Create a commit using the comment body (requires exactly one task id).",
69
- },
70
- {
71
- kind: "string",
72
- name: "commit-emoji",
73
- valueHint: "<emoji>",
74
- description: "Override the commit emoji (used with --commit-from-comment).",
75
- },
76
- {
77
- kind: "string",
78
- name: "commit-allow",
79
- valueHint: "<path-prefix>",
80
- repeatable: true,
81
- description: "Repeatable. Allowlist path prefixes to stage for the commit (used with --commit-from-comment).",
82
- },
83
- {
84
- kind: "boolean",
85
- name: "commit-auto-allow",
86
- default: false,
87
- description: "Auto-allow inferred allowlist paths if none are provided (used with --commit-from-comment).",
88
- },
89
- {
90
- kind: "boolean",
91
- name: "commit-allow-tasks",
92
- default: true,
93
- hidden: true,
94
- description: "Deprecated. Tasks are always allowed for status commits.",
95
- deprecated: "no-op",
96
- },
97
- {
98
- kind: "boolean",
99
- name: "commit-require-clean",
100
- default: false,
101
- description: "Require a clean working tree for the commit (used with --commit-from-comment).",
102
- },
103
- {
104
- kind: "boolean",
105
- name: "status-commit",
106
- default: false,
107
- description: "Create a separate status commit (requires exactly one task id).",
108
- },
109
- {
110
- kind: "string",
111
- name: "status-commit-emoji",
112
- valueHint: "<emoji>",
113
- description: "Override the status commit emoji (used with --status-commit).",
114
- },
115
- {
116
- kind: "string",
117
- name: "status-commit-allow",
118
- valueHint: "<path-prefix>",
119
- repeatable: true,
120
- description: "Repeatable. Allowlist path prefixes to stage for the status commit (used with --status-commit).",
121
- },
122
- {
123
- kind: "boolean",
124
- name: "status-commit-auto-allow",
125
- default: false,
126
- description: "Auto-allow inferred allowlist paths if none are provided (used with --status-commit).",
127
- },
128
- {
129
- kind: "boolean",
130
- name: "status-commit-require-clean",
131
- default: false,
132
- description: "Require a clean working tree for the status commit (used with --status-commit).",
133
- },
134
- {
135
- kind: "boolean",
136
- name: "confirm-status-commit",
137
- default: false,
138
- description: "Confirm status commit creation when status_commit_policy=confirm (used with --commit-from-comment or --status-commit).",
139
- },
140
- { kind: "boolean", name: "quiet", default: false, description: "Suppress output." },
141
- ],
142
- examples: [
143
- {
144
- cmd: 'agentplane finish 202602030608-F1Q8AB --author INTEGRATOR --body "Verified: all checks passed" --commit abcdef123456',
145
- why: "Finish a task and record commit metadata.",
146
- },
147
- {
148
- cmd: 'agentplane finish 202602030608-F1Q8AB --author INTEGRATOR --body "Verified: all checks passed" --commit-from-comment --commit-allow packages/agentplane/src',
149
- why: "Finish and create a commit from the comment (single-task only).",
150
- },
151
- ],
152
- validateRaw: (raw) => {
153
- const ids = raw.args["task-id"];
154
- const taskIds = Array.isArray(ids) ? ids : [];
155
- const commitFromComment = raw.opts["commit-from-comment"] === true;
156
- const statusCommit = raw.opts["status-commit"] === true;
157
- if ((commitFromComment || statusCommit) && taskIds.length !== 1) {
158
- throw usageError({
159
- spec: finishSpec,
160
- command: "finish",
161
- message: "--commit-from-comment/--status-commit requires exactly one task id",
162
- });
163
- }
164
- const hasMeta = typeof raw.opts.result === "string" ||
165
- typeof raw.opts.risk === "string" ||
166
- raw.opts.breaking === true;
167
- if (hasMeta && taskIds.length !== 1) {
168
- throw usageError({
169
- spec: finishSpec,
170
- command: "finish",
171
- message: "--result/--risk/--breaking requires exactly one task id",
172
- });
173
- }
174
- },
175
- parse: (raw) => ({
176
- taskIds: Array.isArray(raw.args["task-id"])
177
- ? raw.args["task-id"].filter((x) => typeof x === "string")
178
- : [],
179
- author: raw.opts.author,
180
- body: raw.opts.body,
181
- result: raw.opts.result,
182
- risk: raw.opts.risk,
183
- breaking: raw.opts.breaking === true,
184
- commit: raw.opts.commit,
185
- force: raw.opts.force === true,
186
- commitFromComment: raw.opts["commit-from-comment"] === true,
187
- commitEmoji: raw.opts["commit-emoji"],
188
- commitAllow: toStringList(raw.opts["commit-allow"]),
189
- commitAutoAllow: raw.opts["commit-auto-allow"] === true,
190
- commitAllowTasks: raw.opts["commit-allow-tasks"] !== false,
191
- commitRequireClean: raw.opts["commit-require-clean"] === true,
192
- statusCommit: raw.opts["status-commit"] === true,
193
- statusCommitEmoji: raw.opts["status-commit-emoji"],
194
- statusCommitAllow: toStringList(raw.opts["status-commit-allow"]),
195
- statusCommitAutoAllow: raw.opts["status-commit-auto-allow"] === true,
196
- statusCommitRequireClean: raw.opts["status-commit-require-clean"] === true,
197
- confirmStatusCommit: raw.opts["confirm-status-commit"] === true,
198
- quiet: raw.opts.quiet === true,
199
- }),
200
- };
201
- export function makeRunFinishHandler(getCtx) {
202
- return async (ctx, p) => {
203
- if (p.taskIds.length === 0) {
204
- throw usageError({
205
- spec: finishSpec,
206
- command: "finish",
207
- message: "Missing required argument: task-id",
208
- });
209
- }
210
- return await cmdFinish({
211
- ctx: await getCtx("finish"),
212
- cwd: ctx.cwd,
213
- rootOverride: ctx.rootOverride,
214
- taskIds: p.taskIds,
215
- author: p.author,
216
- body: p.body,
217
- result: p.result,
218
- risk: p.risk,
219
- breaking: p.breaking,
220
- commit: p.commit,
221
- force: p.force,
222
- commitFromComment: p.commitFromComment,
223
- commitEmoji: p.commitEmoji,
224
- commitAllow: p.commitAllow,
225
- commitAutoAllow: p.commitAutoAllow,
226
- commitAllowTasks: p.commitAllowTasks,
227
- commitRequireClean: p.commitRequireClean,
228
- statusCommit: p.statusCommit,
229
- statusCommitEmoji: p.statusCommitEmoji,
230
- statusCommitAllow: p.statusCommitAllow,
231
- statusCommitAutoAllow: p.statusCommitAutoAllow,
232
- statusCommitRequireClean: p.statusCommitRequireClean,
233
- confirmStatusCommit: p.confirmStatusCommit,
234
- quiet: p.quiet,
235
- });
236
- };
237
- }
1
+ export { finishSpec } from "./finish.spec.js";
2
+ export { makeRunFinishHandler } from "./finish.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 FinishParsed } from "./finish.spec.js";
4
+ export declare function makeRunFinishHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: FinishParsed) => Promise<number>;
5
+ //# sourceMappingURL=finish.run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finish.run.d.ts","sourceRoot":"","sources":["../../src/commands/finish.run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEjE,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,CAmCjE"}
@@ -0,0 +1,40 @@
1
+ import { usageError } from "../cli/spec/errors.js";
2
+ import { cmdFinish } from "./task/finish.js";
3
+ import { finishSpec } from "./finish.spec.js";
4
+ export function makeRunFinishHandler(getCtx) {
5
+ return async (ctx, p) => {
6
+ if (p.taskIds.length === 0) {
7
+ throw usageError({
8
+ spec: finishSpec,
9
+ command: "finish",
10
+ message: "Missing required argument: task-id",
11
+ });
12
+ }
13
+ return await cmdFinish({
14
+ ctx: await getCtx("finish"),
15
+ cwd: ctx.cwd,
16
+ rootOverride: ctx.rootOverride,
17
+ taskIds: p.taskIds,
18
+ author: p.author,
19
+ body: p.body,
20
+ result: p.result,
21
+ risk: p.risk,
22
+ breaking: p.breaking,
23
+ commit: p.commit,
24
+ force: p.force,
25
+ commitFromComment: p.commitFromComment,
26
+ commitEmoji: p.commitEmoji,
27
+ commitAllow: p.commitAllow,
28
+ commitAutoAllow: p.commitAutoAllow,
29
+ commitAllowTasks: p.commitAllowTasks,
30
+ commitRequireClean: p.commitRequireClean,
31
+ statusCommit: p.statusCommit,
32
+ statusCommitEmoji: p.statusCommitEmoji,
33
+ statusCommitAllow: p.statusCommitAllow,
34
+ statusCommitAutoAllow: p.statusCommitAutoAllow,
35
+ statusCommitRequireClean: p.statusCommitRequireClean,
36
+ confirmStatusCommit: p.confirmStatusCommit,
37
+ quiet: p.quiet,
38
+ });
39
+ };
40
+ }
@@ -0,0 +1,26 @@
1
+ import type { CommandSpec } from "../cli/spec/spec.js";
2
+ export type FinishParsed = {
3
+ taskIds: string[];
4
+ author: string;
5
+ body: string;
6
+ result?: string;
7
+ risk?: "low" | "med" | "high";
8
+ breaking: boolean;
9
+ commit?: string;
10
+ force: boolean;
11
+ commitFromComment: boolean;
12
+ commitEmoji?: string;
13
+ commitAllow: string[];
14
+ commitAutoAllow: boolean;
15
+ commitAllowTasks: boolean;
16
+ commitRequireClean: boolean;
17
+ statusCommit: boolean;
18
+ statusCommitEmoji?: string;
19
+ statusCommitAllow: string[];
20
+ statusCommitAutoAllow: boolean;
21
+ statusCommitRequireClean: boolean;
22
+ confirmStatusCommit: boolean;
23
+ quiet: boolean;
24
+ };
25
+ export declare const finishSpec: CommandSpec<FinishParsed>;
26
+ //# sourceMappingURL=finish.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finish.spec.d.ts","sourceRoot":"","sources":["../../src/commands/finish.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKvD,MAAM,MAAM,YAAY,GAAG;IACzB,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,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,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAsMhD,CAAC"}