agentplane 0.1.6 → 0.1.7

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 (111) hide show
  1. package/assets/AGENTS.md +1 -1
  2. package/assets/agents/ORCHESTRATOR.json +1 -1
  3. package/assets/agents/UPGRADER.json +1 -1
  4. package/dist/cli/run-cli.d.ts.map +1 -1
  5. package/dist/cli/run-cli.js +22 -7
  6. package/dist/commands/branch/index.d.ts +60 -0
  7. package/dist/commands/branch/index.d.ts.map +1 -0
  8. package/dist/commands/branch/index.js +511 -0
  9. package/dist/commands/guard/index.d.ts +67 -0
  10. package/dist/commands/guard/index.d.ts.map +1 -0
  11. package/dist/commands/guard/index.js +367 -0
  12. package/dist/commands/hooks/index.d.ts +18 -0
  13. package/dist/commands/hooks/index.d.ts.map +1 -0
  14. package/dist/commands/hooks/index.js +290 -0
  15. package/dist/commands/pr/index.d.ts +46 -0
  16. package/dist/commands/pr/index.d.ts.map +1 -0
  17. package/dist/commands/pr/index.js +854 -0
  18. package/dist/commands/shared/git-diff.d.ts +9 -0
  19. package/dist/commands/shared/git-diff.d.ts.map +1 -0
  20. package/dist/commands/shared/git-diff.js +41 -0
  21. package/dist/commands/shared/git-ops.d.ts +24 -0
  22. package/dist/commands/shared/git-ops.d.ts.map +1 -0
  23. package/dist/commands/shared/git-ops.js +181 -0
  24. package/dist/commands/shared/git-worktree.d.ts +8 -0
  25. package/dist/commands/shared/git-worktree.d.ts.map +1 -0
  26. package/dist/commands/shared/git-worktree.js +48 -0
  27. package/dist/commands/shared/git.d.ts +4 -0
  28. package/dist/commands/shared/git.d.ts.map +1 -0
  29. package/dist/commands/shared/git.js +14 -0
  30. package/dist/commands/shared/path.d.ts +3 -0
  31. package/dist/commands/shared/path.d.ts.map +1 -0
  32. package/dist/commands/shared/path.js +14 -0
  33. package/dist/commands/shared/pr-meta.d.ts +21 -0
  34. package/dist/commands/shared/pr-meta.d.ts.map +1 -0
  35. package/dist/commands/shared/pr-meta.js +72 -0
  36. package/dist/commands/shared/task-backend.d.ts +15 -0
  37. package/dist/commands/shared/task-backend.d.ts.map +1 -0
  38. package/dist/commands/shared/task-backend.js +55 -0
  39. package/dist/commands/task/add.d.ts +8 -0
  40. package/dist/commands/task/add.d.ts.map +1 -0
  41. package/dist/commands/task/add.js +164 -0
  42. package/dist/commands/task/block.d.ts +19 -0
  43. package/dist/commands/task/block.d.ts.map +1 -0
  44. package/dist/commands/task/block.js +86 -0
  45. package/dist/commands/task/comment.d.ts +8 -0
  46. package/dist/commands/task/comment.d.ts.map +1 -0
  47. package/dist/commands/task/comment.js +29 -0
  48. package/dist/commands/task/doc.d.ts +17 -0
  49. package/dist/commands/task/doc.d.ts.map +1 -0
  50. package/dist/commands/task/doc.js +220 -0
  51. package/dist/commands/task/export.d.ts +5 -0
  52. package/dist/commands/task/export.d.ts.map +1 -0
  53. package/dist/commands/task/export.js +27 -0
  54. package/dist/commands/task/finish.d.ts +27 -0
  55. package/dist/commands/task/finish.d.ts.map +1 -0
  56. package/dist/commands/task/finish.js +131 -0
  57. package/dist/commands/task/index.d.ts +23 -0
  58. package/dist/commands/task/index.d.ts.map +1 -0
  59. package/dist/commands/task/index.js +22 -0
  60. package/dist/commands/task/lint.d.ts +5 -0
  61. package/dist/commands/task/lint.d.ts.map +1 -0
  62. package/dist/commands/task/lint.js +22 -0
  63. package/dist/commands/task/list.d.ts +11 -0
  64. package/dist/commands/task/list.d.ts.map +1 -0
  65. package/dist/commands/task/list.js +54 -0
  66. package/dist/commands/task/migrate.d.ts +6 -0
  67. package/dist/commands/task/migrate.d.ts.map +1 -0
  68. package/dist/commands/task/migrate.js +70 -0
  69. package/dist/commands/task/new.d.ts +8 -0
  70. package/dist/commands/task/new.d.ts.map +1 -0
  71. package/dist/commands/task/new.js +117 -0
  72. package/dist/commands/task/next.d.ts +6 -0
  73. package/dist/commands/task/next.d.ts.map +1 -0
  74. package/dist/commands/task/next.js +45 -0
  75. package/dist/commands/task/normalize.d.ts +6 -0
  76. package/dist/commands/task/normalize.d.ts.map +1 -0
  77. package/dist/commands/task/normalize.js +46 -0
  78. package/dist/commands/task/ready.d.ts +6 -0
  79. package/dist/commands/task/ready.d.ts.map +1 -0
  80. package/dist/commands/task/ready.js +57 -0
  81. package/dist/commands/task/scaffold.d.ts +8 -0
  82. package/dist/commands/task/scaffold.d.ts.map +1 -0
  83. package/dist/commands/task/scaffold.js +131 -0
  84. package/dist/commands/task/scrub.d.ts +8 -0
  85. package/dist/commands/task/scrub.d.ts.map +1 -0
  86. package/dist/commands/task/scrub.js +121 -0
  87. package/dist/commands/task/search.d.ts +7 -0
  88. package/dist/commands/task/search.d.ts.map +1 -0
  89. package/dist/commands/task/search.js +79 -0
  90. package/dist/commands/task/set-status.d.ts +19 -0
  91. package/dist/commands/task/set-status.d.ts.map +1 -0
  92. package/dist/commands/task/set-status.js +123 -0
  93. package/dist/commands/task/shared.d.ts +46 -0
  94. package/dist/commands/task/shared.d.ts.map +1 -0
  95. package/dist/commands/task/shared.js +283 -0
  96. package/dist/commands/task/show.d.ts +6 -0
  97. package/dist/commands/task/show.d.ts.map +1 -0
  98. package/dist/commands/task/show.js +35 -0
  99. package/dist/commands/task/start.d.ts +19 -0
  100. package/dist/commands/task/start.d.ts.map +1 -0
  101. package/dist/commands/task/start.js +109 -0
  102. package/dist/commands/task/update.d.ts +8 -0
  103. package/dist/commands/task/update.d.ts.map +1 -0
  104. package/dist/commands/task/update.js +144 -0
  105. package/dist/commands/task/verify.d.ts +14 -0
  106. package/dist/commands/task/verify.d.ts.map +1 -0
  107. package/dist/commands/task/verify.js +362 -0
  108. package/dist/commands/workflow.d.ts +5 -364
  109. package/dist/commands/workflow.d.ts.map +1 -1
  110. package/dist/commands/workflow.js +6 -4617
  111. package/package.json +2 -2
@@ -0,0 +1,131 @@
1
+ import { loadConfig, resolveProject } from "@agentplaneorg/core";
2
+ import { loadTaskBackend } from "../../backends/task-backend.js";
3
+ import { mapBackendError } from "../../cli/error-map.js";
4
+ import { successMessage } from "../../cli/output.js";
5
+ import { formatCommentBodyForCommit } from "../../shared/comment-format.js";
6
+ import { CliError } from "../../shared/errors.js";
7
+ import { commitFromComment } from "../guard/index.js";
8
+ import { loadBackendTask } from "../shared/task-backend.js";
9
+ import { defaultCommitEmojiForStatus, enforceStatusCommitPolicy, nowIso, readCommitInfo, readHeadCommit, requireStructuredComment, } from "./shared.js";
10
+ export const FINISH_USAGE = "Usage: agentplane finish <task-id> [<task-id>...] --author <id> --body <text> [flags]";
11
+ export const FINISH_USAGE_EXAMPLE = 'agentplane finish 202602030608-F1Q8AB --author INTEGRATOR --body "Verified: ..."';
12
+ export async function cmdFinish(opts) {
13
+ try {
14
+ if (opts.noRequireTaskIdInCommit) {
15
+ // Parity flag (commit subject checks are not enforced in node CLI).
16
+ }
17
+ const resolved = await resolveProject({
18
+ cwd: opts.cwd,
19
+ rootOverride: opts.rootOverride ?? null,
20
+ });
21
+ const loaded = await loadConfig(resolved.agentplaneDir);
22
+ const { prefix, min_chars: minChars } = loaded.config.tasks.comments.verified;
23
+ requireStructuredComment(opts.body, prefix, minChars);
24
+ if (opts.commitFromComment || opts.statusCommit) {
25
+ enforceStatusCommitPolicy({
26
+ policy: loaded.config.status_commit_policy,
27
+ action: "finish",
28
+ confirmed: opts.confirmStatusCommit,
29
+ quiet: opts.quiet,
30
+ });
31
+ }
32
+ if ((opts.commitFromComment || opts.statusCommit) && opts.taskIds.length !== 1) {
33
+ throw new CliError({
34
+ exitCode: 2,
35
+ code: "E_USAGE",
36
+ message: "--commit-from-comment/--status-commit requires exactly one task id",
37
+ });
38
+ }
39
+ const primaryTaskId = opts.taskIds[0] ?? "";
40
+ if ((opts.commitFromComment || opts.statusCommit) && !primaryTaskId) {
41
+ throw new CliError({
42
+ exitCode: 2,
43
+ code: "E_USAGE",
44
+ message: "--commit-from-comment/--status-commit requires exactly one task id",
45
+ });
46
+ }
47
+ const { backend } = await loadTaskBackend({
48
+ cwd: opts.cwd,
49
+ rootOverride: opts.rootOverride ?? null,
50
+ });
51
+ const commitInfo = opts.commit
52
+ ? await readCommitInfo(resolved.gitRoot, opts.commit)
53
+ : await readHeadCommit(resolved.gitRoot);
54
+ for (const taskId of opts.taskIds) {
55
+ const { task } = await loadBackendTask({
56
+ cwd: opts.cwd,
57
+ rootOverride: opts.rootOverride,
58
+ taskId,
59
+ });
60
+ if (!opts.force) {
61
+ const currentStatus = String(task.status || "TODO").toUpperCase();
62
+ if (currentStatus === "DONE") {
63
+ throw new CliError({
64
+ exitCode: 2,
65
+ code: "E_USAGE",
66
+ message: `Task is already DONE: ${task.id} (use --force to override)`,
67
+ });
68
+ }
69
+ }
70
+ const existingComments = Array.isArray(task.comments)
71
+ ? task.comments.filter((item) => !!item && typeof item.author === "string" && typeof item.body === "string")
72
+ : [];
73
+ const commentsValue = [...existingComments, { author: opts.author, body: opts.body }];
74
+ const nextTask = {
75
+ ...task,
76
+ status: "DONE",
77
+ commit: { hash: commitInfo.hash, message: commitInfo.message },
78
+ comments: commentsValue,
79
+ doc_version: 2,
80
+ doc_updated_at: nowIso(),
81
+ doc_updated_by: opts.author,
82
+ };
83
+ await backend.writeTask(nextTask);
84
+ }
85
+ if (!opts.skipVerify) {
86
+ // No-op for parity; verify is handled by `agentplane verify`.
87
+ }
88
+ // tasks.json is export-only; generated via `agentplane task export`.
89
+ if (opts.commitFromComment) {
90
+ await commitFromComment({
91
+ cwd: opts.cwd,
92
+ rootOverride: opts.rootOverride,
93
+ taskId: primaryTaskId,
94
+ commentBody: opts.body,
95
+ formattedComment: formatCommentBodyForCommit(opts.body, loaded.config),
96
+ emoji: opts.commitEmoji ?? defaultCommitEmojiForStatus("DONE"),
97
+ allow: opts.commitAllow,
98
+ autoAllow: opts.commitAutoAllow || opts.commitAllow.length === 0,
99
+ allowTasks: opts.commitAllowTasks,
100
+ requireClean: opts.commitRequireClean,
101
+ quiet: opts.quiet,
102
+ config: loaded.config,
103
+ });
104
+ }
105
+ if (opts.statusCommit) {
106
+ await commitFromComment({
107
+ cwd: opts.cwd,
108
+ rootOverride: opts.rootOverride,
109
+ taskId: primaryTaskId,
110
+ commentBody: opts.body,
111
+ formattedComment: formatCommentBodyForCommit(opts.body, loaded.config),
112
+ emoji: opts.statusCommitEmoji ?? defaultCommitEmojiForStatus("DONE"),
113
+ allow: opts.statusCommitAllow,
114
+ autoAllow: opts.statusCommitAutoAllow || opts.statusCommitAllow.length === 0,
115
+ allowTasks: true,
116
+ requireClean: opts.statusCommitRequireClean,
117
+ quiet: opts.quiet,
118
+ config: loaded.config,
119
+ });
120
+ }
121
+ if (!opts.quiet) {
122
+ process.stdout.write(`${successMessage("finished")}\n`);
123
+ }
124
+ return 0;
125
+ }
126
+ catch (err) {
127
+ if (err instanceof CliError)
128
+ throw err;
129
+ throw mapBackendError(err, { command: "finish", root: opts.rootOverride ?? null });
130
+ }
131
+ }
@@ -0,0 +1,23 @@
1
+ export { TASK_NEW_USAGE, TASK_NEW_USAGE_EXAMPLE, cmdTaskNew } from "./new.js";
2
+ export { TASK_ADD_USAGE, TASK_ADD_USAGE_EXAMPLE, cmdTaskAdd } from "./add.js";
3
+ export { TASK_UPDATE_USAGE, TASK_UPDATE_USAGE_EXAMPLE, cmdTaskUpdate } from "./update.js";
4
+ export { TASK_SCRUB_USAGE, TASK_SCRUB_USAGE_EXAMPLE, cmdTaskScrub } from "./scrub.js";
5
+ export { cmdTaskListWithFilters, cmdTaskList } from "./list.js";
6
+ export { cmdTaskNext } from "./next.js";
7
+ export { cmdReady } from "./ready.js";
8
+ export { cmdTaskSearch } from "./search.js";
9
+ export { TASK_SCAFFOLD_USAGE, TASK_SCAFFOLD_USAGE_EXAMPLE, cmdTaskScaffold } from "./scaffold.js";
10
+ export { cmdTaskNormalize } from "./normalize.js";
11
+ export { cmdTaskMigrate } from "./migrate.js";
12
+ export { cmdTaskComment } from "./comment.js";
13
+ export { cmdTaskSetStatus } from "./set-status.js";
14
+ export { cmdTaskShow } from "./show.js";
15
+ export { cmdTaskExport } from "./export.js";
16
+ export { cmdTaskLint } from "./lint.js";
17
+ export { START_USAGE, START_USAGE_EXAMPLE, cmdStart } from "./start.js";
18
+ export { BLOCK_USAGE, BLOCK_USAGE_EXAMPLE, cmdBlock } from "./block.js";
19
+ export { FINISH_USAGE, FINISH_USAGE_EXAMPLE, cmdFinish } from "./finish.js";
20
+ export { VERIFY_USAGE, VERIFY_USAGE_EXAMPLE, cmdVerify } from "./verify.js";
21
+ export { TASK_DOC_SET_USAGE, TASK_DOC_SET_USAGE_EXAMPLE, TASK_DOC_SHOW_USAGE, TASK_DOC_SHOW_USAGE_EXAMPLE, cmdTaskDocSet, cmdTaskDocShow, } from "./doc.js";
22
+ export { dedupeStrings } from "./shared.js";
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/task/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtF,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,mBAAmB,EACnB,2BAA2B,EAC3B,aAAa,EACb,cAAc,GACf,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,22 @@
1
+ export { TASK_NEW_USAGE, TASK_NEW_USAGE_EXAMPLE, cmdTaskNew } from "./new.js";
2
+ export { TASK_ADD_USAGE, TASK_ADD_USAGE_EXAMPLE, cmdTaskAdd } from "./add.js";
3
+ export { TASK_UPDATE_USAGE, TASK_UPDATE_USAGE_EXAMPLE, cmdTaskUpdate } from "./update.js";
4
+ export { TASK_SCRUB_USAGE, TASK_SCRUB_USAGE_EXAMPLE, cmdTaskScrub } from "./scrub.js";
5
+ export { cmdTaskListWithFilters, cmdTaskList } from "./list.js";
6
+ export { cmdTaskNext } from "./next.js";
7
+ export { cmdReady } from "./ready.js";
8
+ export { cmdTaskSearch } from "./search.js";
9
+ export { TASK_SCAFFOLD_USAGE, TASK_SCAFFOLD_USAGE_EXAMPLE, cmdTaskScaffold } from "./scaffold.js";
10
+ export { cmdTaskNormalize } from "./normalize.js";
11
+ export { cmdTaskMigrate } from "./migrate.js";
12
+ export { cmdTaskComment } from "./comment.js";
13
+ export { cmdTaskSetStatus } from "./set-status.js";
14
+ export { cmdTaskShow } from "./show.js";
15
+ export { cmdTaskExport } from "./export.js";
16
+ export { cmdTaskLint } from "./lint.js";
17
+ export { START_USAGE, START_USAGE_EXAMPLE, cmdStart } from "./start.js";
18
+ export { BLOCK_USAGE, BLOCK_USAGE_EXAMPLE, cmdBlock } from "./block.js";
19
+ export { FINISH_USAGE, FINISH_USAGE_EXAMPLE, cmdFinish } from "./finish.js";
20
+ export { VERIFY_USAGE, VERIFY_USAGE_EXAMPLE, cmdVerify } from "./verify.js";
21
+ export { TASK_DOC_SET_USAGE, TASK_DOC_SET_USAGE_EXAMPLE, TASK_DOC_SHOW_USAGE, TASK_DOC_SHOW_USAGE_EXAMPLE, cmdTaskDocSet, cmdTaskDocShow, } from "./doc.js";
22
+ export { dedupeStrings } from "./shared.js";
@@ -0,0 +1,5 @@
1
+ export declare function cmdTaskLint(opts: {
2
+ cwd: string;
3
+ rootOverride?: string;
4
+ }): Promise<number>;
5
+ //# sourceMappingURL=lint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../../src/commands/task/lint.ts"],"names":[],"mappings":"AAKA,wBAAsB,WAAW,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB/F"}
@@ -0,0 +1,22 @@
1
+ import { lintTasksFile } from "@agentplaneorg/core";
2
+ import { mapCoreError } from "../../cli/error-map.js";
3
+ import { CliError } from "../../shared/errors.js";
4
+ export async function cmdTaskLint(opts) {
5
+ try {
6
+ const result = await lintTasksFile({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null });
7
+ if (result.errors.length > 0) {
8
+ throw new CliError({
9
+ exitCode: 3,
10
+ code: "E_VALIDATION",
11
+ message: result.errors.join("\n"),
12
+ });
13
+ }
14
+ process.stdout.write("OK\n");
15
+ return 0;
16
+ }
17
+ catch (err) {
18
+ if (err instanceof CliError)
19
+ throw err;
20
+ throw mapCoreError(err, { command: "task lint", root: opts.rootOverride ?? null });
21
+ }
22
+ }
@@ -0,0 +1,11 @@
1
+ export declare function cmdTaskListWithFilters(opts: {
2
+ cwd: string;
3
+ rootOverride?: string;
4
+ args: string[];
5
+ }): Promise<number>;
6
+ export declare function cmdTaskList(opts: {
7
+ cwd: string;
8
+ rootOverride?: string;
9
+ args: string[];
10
+ }): Promise<number>;
11
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/task/list.ts"],"names":[],"mappings":"AAWA,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8ClB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAElB"}
@@ -0,0 +1,54 @@
1
+ import { loadTaskBackend } from "../../backends/task-backend.js";
2
+ import { mapBackendError } from "../../cli/error-map.js";
3
+ import { buildDependencyState, dedupeStrings, formatTaskLine, parseTaskListFilters, toStringArray, } from "./shared.js";
4
+ export async function cmdTaskListWithFilters(opts) {
5
+ const filters = parseTaskListFilters(opts.args);
6
+ try {
7
+ const { backend } = await loadTaskBackend({
8
+ cwd: opts.cwd,
9
+ rootOverride: opts.rootOverride ?? null,
10
+ });
11
+ const tasks = await backend.listTasks();
12
+ const depState = buildDependencyState(tasks);
13
+ let filtered = tasks;
14
+ if (filters.status.length > 0) {
15
+ const wanted = new Set(filters.status.map((s) => s.trim().toUpperCase()));
16
+ filtered = filtered.filter((task) => wanted.has(String(task.status || "TODO").toUpperCase()));
17
+ }
18
+ if (filters.owner.length > 0) {
19
+ const wanted = new Set(filters.owner.map((o) => o.trim().toUpperCase()));
20
+ filtered = filtered.filter((task) => wanted.has(String(task.owner || "").toUpperCase()));
21
+ }
22
+ if (filters.tag.length > 0) {
23
+ const wanted = new Set(filters.tag.map((t) => t.trim()).filter(Boolean));
24
+ filtered = filtered.filter((task) => {
25
+ const tags = dedupeStrings(toStringArray(task.tags));
26
+ return tags.some((tag) => wanted.has(tag));
27
+ });
28
+ }
29
+ const sorted = filtered.toSorted((a, b) => a.id.localeCompare(b.id));
30
+ for (const task of sorted) {
31
+ process.stdout.write(`${formatTaskLine(task, depState.get(task.id))}\n`);
32
+ }
33
+ if (!filters.quiet) {
34
+ const counts = {};
35
+ for (const task of sorted) {
36
+ const status = String(task.status || "TODO").toUpperCase();
37
+ counts[status] = (counts[status] ?? 0) + 1;
38
+ }
39
+ const total = sorted.length;
40
+ const summary = Object.keys(counts)
41
+ .toSorted()
42
+ .map((key) => `${key}=${counts[key]}`)
43
+ .join(", ");
44
+ process.stdout.write(`Total: ${total}${summary ? ` (${summary})` : ""}\n`);
45
+ }
46
+ return 0;
47
+ }
48
+ catch (err) {
49
+ throw mapBackendError(err, { command: "task list", root: opts.rootOverride ?? null });
50
+ }
51
+ }
52
+ export async function cmdTaskList(opts) {
53
+ return await cmdTaskListWithFilters(opts);
54
+ }
@@ -0,0 +1,6 @@
1
+ export declare function cmdTaskMigrate(opts: {
2
+ cwd: string;
3
+ rootOverride?: string;
4
+ args: string[];
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/commands/task/migrate.ts"],"names":[],"mappings":"AA2CA,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BlB"}
@@ -0,0 +1,70 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { loadTaskBackend } from "../../backends/task-backend.js";
4
+ import { mapBackendError } from "../../cli/error-map.js";
5
+ import { missingValueMessage, successMessage } from "../../cli/output.js";
6
+ import { CliError } from "../../shared/errors.js";
7
+ function parseTaskMigrateFlags(args) {
8
+ const out = { quiet: false, force: false };
9
+ for (let i = 0; i < args.length; i++) {
10
+ const arg = args[i];
11
+ if (!arg)
12
+ continue;
13
+ if (arg === "--quiet") {
14
+ out.quiet = true;
15
+ continue;
16
+ }
17
+ if (arg === "--force") {
18
+ out.force = true;
19
+ continue;
20
+ }
21
+ if (arg === "--source") {
22
+ const next = args[i + 1];
23
+ if (!next) {
24
+ throw new CliError({
25
+ exitCode: 2,
26
+ code: "E_USAGE",
27
+ message: missingValueMessage("--source"),
28
+ });
29
+ }
30
+ out.source = next;
31
+ i++;
32
+ continue;
33
+ }
34
+ if (arg.startsWith("--")) {
35
+ throw new CliError({ exitCode: 2, code: "E_USAGE", message: `Unknown flag: ${arg}` });
36
+ }
37
+ }
38
+ return out;
39
+ }
40
+ export async function cmdTaskMigrate(opts) {
41
+ const flags = parseTaskMigrateFlags(opts.args);
42
+ if (flags.force) {
43
+ // Force is accepted for parity; no additional checks in node CLI.
44
+ }
45
+ try {
46
+ const { backend, resolved, config } = await loadTaskBackend({
47
+ cwd: opts.cwd,
48
+ rootOverride: opts.rootOverride ?? null,
49
+ });
50
+ const source = flags.source ?? config.paths.tasks_path;
51
+ const sourcePath = path.join(resolved.gitRoot, source);
52
+ const raw = await readFile(sourcePath, "utf8");
53
+ const parsed = JSON.parse(raw);
54
+ const tasks = Array.isArray(parsed.tasks) ? parsed.tasks : [];
55
+ if (backend.writeTasks) {
56
+ await backend.writeTasks(tasks);
57
+ }
58
+ else {
59
+ for (const task of tasks)
60
+ await backend.writeTask(task);
61
+ }
62
+ if (!flags.quiet) {
63
+ process.stdout.write(`${successMessage("migrated tasks into backend", undefined, `count=${tasks.length}`)}\n`);
64
+ }
65
+ return 0;
66
+ }
67
+ catch (err) {
68
+ throw mapBackendError(err, { command: "task migrate", root: opts.rootOverride ?? null });
69
+ }
70
+ }
@@ -0,0 +1,8 @@
1
+ export declare const TASK_NEW_USAGE = "Usage: agentplane task new --title <text> --description <text> --priority <low|normal|med|high> --owner <id> --tag <tag> [--tag <tag>...]";
2
+ export declare const TASK_NEW_USAGE_EXAMPLE = "agentplane task new --title \"Refactor CLI\" --description \"Improve CLI output\" --priority med --owner CODER --tag cli";
3
+ export declare function cmdTaskNew(opts: {
4
+ cwd: string;
5
+ rootOverride?: string;
6
+ args: string[];
7
+ }): Promise<number>;
8
+ //# sourceMappingURL=new.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/commands/task/new.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,cAAc,8IACkH,CAAC;AAC9I,eAAO,MAAM,sBAAsB,6HACqF,CAAC;AA6DzH,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0DlB"}
@@ -0,0 +1,117 @@
1
+ import { loadTaskBackend } from "../../backends/task-backend.js";
2
+ import { mapBackendError } from "../../cli/error-map.js";
3
+ import { missingValueMessage, usageMessage, backendNotSupportedMessage } from "../../cli/output.js";
4
+ import { CliError } from "../../shared/errors.js";
5
+ import { normalizeDependsOnInput, nowIso, requiresVerify } from "./shared.js";
6
+ export const TASK_NEW_USAGE = "Usage: agentplane task new --title <text> --description <text> --priority <low|normal|med|high> --owner <id> --tag <tag> [--tag <tag>...]";
7
+ export const TASK_NEW_USAGE_EXAMPLE = 'agentplane task new --title "Refactor CLI" --description "Improve CLI output" --priority med --owner CODER --tag cli';
8
+ function parseTaskNewFlags(args) {
9
+ const out = { tags: [], dependsOn: [], verify: [] };
10
+ for (let i = 0; i < args.length; i++) {
11
+ const arg = args[i];
12
+ if (!arg)
13
+ continue;
14
+ if (!arg.startsWith("--")) {
15
+ throw new CliError({
16
+ exitCode: 2,
17
+ code: "E_USAGE",
18
+ message: `Unexpected argument: ${arg}`,
19
+ });
20
+ }
21
+ const next = args[i + 1];
22
+ if (!next) {
23
+ throw new CliError({ exitCode: 2, code: "E_USAGE", message: missingValueMessage(arg) });
24
+ }
25
+ switch (arg) {
26
+ case "--title": {
27
+ out.title = next;
28
+ break;
29
+ }
30
+ case "--description": {
31
+ out.description = next;
32
+ break;
33
+ }
34
+ case "--owner": {
35
+ out.owner = next;
36
+ break;
37
+ }
38
+ case "--priority": {
39
+ out.priority = next;
40
+ break;
41
+ }
42
+ case "--tag": {
43
+ out.tags.push(next);
44
+ break;
45
+ }
46
+ case "--depends-on": {
47
+ out.dependsOn.push(...normalizeDependsOnInput(next));
48
+ break;
49
+ }
50
+ case "--verify": {
51
+ out.verify.push(next);
52
+ break;
53
+ }
54
+ default: {
55
+ throw new CliError({ exitCode: 2, code: "E_USAGE", message: `Unknown flag: ${arg}` });
56
+ }
57
+ }
58
+ i++;
59
+ }
60
+ return out;
61
+ }
62
+ export async function cmdTaskNew(opts) {
63
+ const flags = parseTaskNewFlags(opts.args);
64
+ const priority = flags.priority ?? "med";
65
+ if (!flags.title || !flags.description || !flags.owner || flags.tags.length === 0) {
66
+ throw new CliError({
67
+ exitCode: 2,
68
+ code: "E_USAGE",
69
+ message: usageMessage(TASK_NEW_USAGE, TASK_NEW_USAGE_EXAMPLE),
70
+ });
71
+ }
72
+ try {
73
+ const { backend, config } = await loadTaskBackend({
74
+ cwd: opts.cwd,
75
+ rootOverride: opts.rootOverride ?? null,
76
+ });
77
+ const suffixLength = config.tasks.id_suffix_length_default;
78
+ if (!backend.generateTaskId) {
79
+ throw new CliError({
80
+ exitCode: 3,
81
+ code: "E_VALIDATION",
82
+ message: backendNotSupportedMessage("generateTaskId()"),
83
+ });
84
+ }
85
+ const taskId = await backend.generateTaskId({ length: suffixLength, attempts: 1000 });
86
+ const task = {
87
+ id: taskId,
88
+ title: flags.title,
89
+ description: flags.description,
90
+ status: "TODO",
91
+ priority,
92
+ owner: flags.owner,
93
+ tags: flags.tags,
94
+ depends_on: flags.dependsOn,
95
+ verify: flags.verify,
96
+ comments: [],
97
+ doc_version: 2,
98
+ doc_updated_at: nowIso(),
99
+ doc_updated_by: flags.owner,
100
+ id_source: "generated",
101
+ };
102
+ if (requiresVerify(flags.tags, config.tasks.verify.required_tags) &&
103
+ flags.verify.length === 0) {
104
+ throw new CliError({
105
+ exitCode: 2,
106
+ code: "E_USAGE",
107
+ message: "Missing verify commands for tasks with code/backend/frontend tags (use --verify)",
108
+ });
109
+ }
110
+ await backend.writeTask(task);
111
+ process.stdout.write(`${taskId}\n`);
112
+ return 0;
113
+ }
114
+ catch (err) {
115
+ throw mapBackendError(err, { command: "task new", root: opts.rootOverride ?? null });
116
+ }
117
+ }
@@ -0,0 +1,6 @@
1
+ export declare function cmdTaskNext(opts: {
2
+ cwd: string;
3
+ rootOverride?: string;
4
+ args: string[];
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=next.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../../src/commands/task/next.ts"],"names":[],"mappings":"AAWA,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ClB"}
@@ -0,0 +1,45 @@
1
+ import { loadTaskBackend } from "../../backends/task-backend.js";
2
+ import { mapBackendError } from "../../cli/error-map.js";
3
+ import { buildDependencyState, dedupeStrings, formatTaskLine, parseTaskListFilters, toStringArray, } from "./shared.js";
4
+ export async function cmdTaskNext(opts) {
5
+ const filters = parseTaskListFilters(opts.args, { allowLimit: true });
6
+ try {
7
+ const { backend } = await loadTaskBackend({
8
+ cwd: opts.cwd,
9
+ rootOverride: opts.rootOverride ?? null,
10
+ });
11
+ const tasks = await backend.listTasks();
12
+ const depState = buildDependencyState(tasks);
13
+ const statuses = filters.status.length > 0
14
+ ? new Set(filters.status.map((s) => s.trim().toUpperCase()))
15
+ : new Set(["TODO"]);
16
+ let filtered = tasks.filter((task) => statuses.has(String(task.status || "TODO").toUpperCase()));
17
+ if (filters.owner.length > 0) {
18
+ const wanted = new Set(filters.owner.map((o) => o.trim().toUpperCase()));
19
+ filtered = filtered.filter((task) => wanted.has(String(task.owner || "").toUpperCase()));
20
+ }
21
+ if (filters.tag.length > 0) {
22
+ const wanted = new Set(filters.tag.map((t) => t.trim()).filter(Boolean));
23
+ filtered = filtered.filter((task) => {
24
+ const tags = dedupeStrings(toStringArray(task.tags));
25
+ return tags.some((tag) => wanted.has(tag));
26
+ });
27
+ }
28
+ const sorted = filtered.toSorted((a, b) => a.id.localeCompare(b.id));
29
+ const ready = sorted.filter((task) => {
30
+ const dep = depState.get(task.id);
31
+ return !dep || (dep.missing.length === 0 && dep.incomplete.length === 0);
32
+ });
33
+ const limited = filters.limit !== undefined && filters.limit >= 0 ? ready.slice(0, filters.limit) : ready;
34
+ for (const task of limited) {
35
+ process.stdout.write(`${formatTaskLine(task, depState.get(task.id))}\n`);
36
+ }
37
+ if (!filters.quiet) {
38
+ process.stdout.write(`Ready: ${limited.length} / ${filtered.length}\n`);
39
+ }
40
+ return 0;
41
+ }
42
+ catch (err) {
43
+ throw mapBackendError(err, { command: "task next", root: opts.rootOverride ?? null });
44
+ }
45
+ }
@@ -0,0 +1,6 @@
1
+ export declare function cmdTaskNormalize(opts: {
2
+ cwd: string;
3
+ rootOverride?: string;
4
+ args: string[];
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/commands/task/normalize.ts"],"names":[],"mappings":"AAoBA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBlB"}
@@ -0,0 +1,46 @@
1
+ import { loadTaskBackend } from "../../backends/task-backend.js";
2
+ import { mapBackendError } from "../../cli/error-map.js";
3
+ import { successMessage } from "../../cli/output.js";
4
+ import { CliError } from "../../shared/errors.js";
5
+ function parseTaskNormalizeFlags(args) {
6
+ const out = { quiet: false, force: false };
7
+ for (const arg of args) {
8
+ if (!arg)
9
+ continue;
10
+ if (arg === "--quiet")
11
+ out.quiet = true;
12
+ else if (arg === "--force")
13
+ out.force = true;
14
+ else if (arg.startsWith("--")) {
15
+ throw new CliError({ exitCode: 2, code: "E_USAGE", message: `Unknown flag: ${arg}` });
16
+ }
17
+ }
18
+ return out;
19
+ }
20
+ export async function cmdTaskNormalize(opts) {
21
+ const flags = parseTaskNormalizeFlags(opts.args);
22
+ if (flags.force) {
23
+ // Force is accepted for parity; no additional checks in node CLI.
24
+ }
25
+ try {
26
+ const { backend } = await loadTaskBackend({
27
+ cwd: opts.cwd,
28
+ rootOverride: opts.rootOverride ?? null,
29
+ });
30
+ const tasks = await backend.listTasks();
31
+ if (backend.writeTasks) {
32
+ await backend.writeTasks(tasks);
33
+ }
34
+ else {
35
+ for (const task of tasks)
36
+ await backend.writeTask(task);
37
+ }
38
+ if (!flags.quiet) {
39
+ process.stdout.write(`${successMessage("normalized tasks", undefined, `count=${tasks.length}`)}\n`);
40
+ }
41
+ return 0;
42
+ }
43
+ catch (err) {
44
+ throw mapBackendError(err, { command: "task normalize", root: opts.rootOverride ?? null });
45
+ }
46
+ }
@@ -0,0 +1,6 @@
1
+ export declare function cmdReady(opts: {
2
+ cwd: string;
3
+ rootOverride?: string;
4
+ taskId: string;
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=ready.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ready.d.ts","sourceRoot":"","sources":["../../../src/commands/task/ready.ts"],"names":[],"mappings":"AAMA,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqDlB"}