agentplane 0.3.5 → 0.3.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.
- package/README.md +103 -75
- package/assets/AGENTS.md +4 -2
- package/bin/dist-guard.js +13 -3
- package/bin/runtime-watch.d.ts +1 -0
- package/bin/runtime-watch.js +22 -5
- package/bin/stale-dist-policy.js +9 -2
- package/dist/.build-manifest.json +251 -821
- package/dist/adapters/task-backend/task-backend-adapter.d.ts +2 -2
- package/dist/adapters/task-backend/task-backend-adapter.d.ts.map +1 -1
- package/dist/adapters/task-backend/task-backend-adapter.js +2 -2
- package/dist/backends/task-backend/local-backend.d.ts +7 -5
- package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/local-backend.js +79 -7
- package/dist/backends/task-backend/redmine/env.d.ts +1 -1
- package/dist/backends/task-backend/redmine/env.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine/env.js +3 -0
- package/dist/backends/task-backend/redmine/inspect.d.ts +11 -0
- package/dist/backends/task-backend/redmine/inspect.d.ts.map +1 -0
- package/dist/backends/task-backend/redmine/inspect.js +75 -0
- package/dist/backends/task-backend/redmine/mapping.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine/mapping.js +21 -2
- package/dist/backends/task-backend/redmine/state.d.ts +17 -0
- package/dist/backends/task-backend/redmine/state.d.ts.map +1 -0
- package/dist/backends/task-backend/redmine/state.js +95 -0
- package/dist/backends/task-backend/redmine-backend.d.ts +10 -16
- package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine-backend.js +205 -15
- package/dist/backends/task-backend/shared/constants.d.ts +1 -1
- package/dist/backends/task-backend/shared/constants.js +1 -1
- package/dist/backends/task-backend/shared/record.d.ts.map +1 -1
- package/dist/backends/task-backend/shared/record.js +20 -1
- package/dist/backends/task-backend/shared/types.d.ts +42 -4
- package/dist/backends/task-backend/shared/types.d.ts.map +1 -1
- package/dist/backends/task-backend/shared.d.ts +1 -1
- package/dist/backends/task-backend/shared.d.ts.map +1 -1
- package/dist/backends/task-backend.d.ts +1 -1
- package/dist/backends/task-backend.d.ts.map +1 -1
- package/dist/backends/task-backend.test-helpers.d.ts +4 -0
- package/dist/backends/task-backend.test-helpers.d.ts.map +1 -0
- package/dist/backends/task-backend.test-helpers.js +33 -0
- package/dist/backends/task-index.d.ts.map +1 -1
- package/dist/backends/task-index.js +1 -0
- package/dist/cli/bootstrap-guide.d.ts.map +1 -1
- package/dist/cli/bootstrap-guide.js +1 -0
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +3 -2
- package/dist/cli/reason-codes.d.ts.map +1 -1
- package/dist/cli/reason-codes.js +30 -0
- package/dist/cli/run-cli/command-catalog/core.d.ts +3 -0
- package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/core.js +137 -0
- package/dist/cli/run-cli/command-catalog/lifecycle.d.ts +3 -0
- package/dist/cli/run-cli/command-catalog/lifecycle.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/lifecycle.js +52 -0
- package/dist/cli/run-cli/command-catalog/project.d.ts +3 -0
- package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/project.js +80 -0
- package/dist/cli/run-cli/command-catalog/shared.d.ts +19 -0
- package/dist/cli/run-cli/command-catalog/shared.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/shared.js +9 -0
- package/dist/cli/run-cli/command-catalog/task.d.ts +3 -0
- package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -0
- package/dist/cli/run-cli/command-catalog/task.js +85 -0
- package/dist/cli/run-cli/command-catalog.d.ts +3 -18
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog.js +8 -337
- package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/ide.js +64 -2
- package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/ui.js +33 -13
- package/dist/cli/run-cli/commands/init/write-env.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-env.js +12 -0
- package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts +3 -0
- package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts.map +1 -0
- package/dist/cli/run-cli.core.pr-flow.test-helpers.js +41 -0
- package/dist/cli/run-cli.core.tasks.test-helpers.d.ts +2 -0
- package/dist/cli/run-cli.core.tasks.test-helpers.d.ts.map +1 -0
- package/dist/cli/run-cli.core.tasks.test-helpers.js +6 -0
- package/dist/cli/run-cli.test-helpers.d.ts +3 -0
- package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +140 -6
- package/dist/commands/backend/sync.command.d.ts +5 -1
- package/dist/commands/backend/sync.command.d.ts.map +1 -1
- package/dist/commands/backend/sync.command.js +67 -3
- package/dist/commands/backend.d.ts +22 -0
- package/dist/commands/backend.d.ts.map +1 -1
- package/dist/commands/backend.js +110 -1
- package/dist/commands/commit.spec.d.ts.map +1 -1
- package/dist/commands/commit.spec.js +31 -7
- package/dist/commands/doctor/runtime.d.ts.map +1 -1
- package/dist/commands/doctor/runtime.js +3 -6
- package/dist/commands/doctor/workspace.d.ts +8 -0
- package/dist/commands/doctor/workspace.d.ts.map +1 -1
- package/dist/commands/doctor/workspace.js +127 -3
- package/dist/commands/guard/commit.command.d.ts.map +1 -1
- package/dist/commands/guard/commit.command.js +30 -6
- package/dist/commands/guard/impl/allow.d.ts +9 -0
- package/dist/commands/guard/impl/allow.d.ts.map +1 -1
- package/dist/commands/guard/impl/allow.js +26 -10
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +146 -18
- package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
- package/dist/commands/guard/impl/comment-commit.js +2 -0
- package/dist/commands/hooks/index.d.ts.map +1 -1
- package/dist/commands/hooks/index.js +8 -35
- package/dist/commands/recipes/impl/apply.d.ts +4 -0
- package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
- package/dist/commands/recipes/impl/apply.js +34 -0
- package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/explain.js +70 -11
- package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/info.js +24 -12
- package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/install.js +32 -36
- package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/list.js +7 -4
- package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/remove.js +9 -11
- package/dist/commands/recipes/impl/constants.d.ts +2 -0
- package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
- package/dist/commands/recipes/impl/constants.js +2 -0
- package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
- package/dist/commands/recipes/impl/manifest.js +219 -23
- package/dist/commands/recipes/impl/normalize.d.ts +3 -0
- package/dist/commands/recipes/impl/normalize.d.ts.map +1 -1
- package/dist/commands/recipes/impl/normalize.js +28 -24
- package/dist/commands/recipes/impl/paths.d.ts +9 -0
- package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
- package/dist/commands/recipes/impl/paths.js +10 -1
- package/dist/commands/recipes/impl/project-installed-recipes.d.ts +7 -0
- package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -0
- package/dist/commands/recipes/impl/project-installed-recipes.js +102 -0
- package/dist/commands/recipes/impl/resolver.d.ts +20 -0
- package/dist/commands/recipes/impl/resolver.d.ts.map +1 -0
- package/dist/commands/recipes/impl/resolver.js +220 -0
- package/dist/commands/recipes/impl/scenario.d.ts.map +1 -1
- package/dist/commands/recipes/impl/scenario.js +40 -11
- package/dist/commands/recipes/impl/types.d.ts +145 -16
- package/dist/commands/recipes/impl/types.d.ts.map +1 -1
- package/dist/commands/recipes/install.spec.d.ts.map +1 -1
- package/dist/commands/recipes/install.spec.js +3 -2
- package/dist/commands/recipes.d.ts +6 -4
- package/dist/commands/recipes.d.ts.map +1 -1
- package/dist/commands/recipes.js +5 -3
- package/dist/commands/recipes.test-helpers.d.ts +185 -0
- package/dist/commands/recipes.test-helpers.d.ts.map +1 -0
- package/dist/commands/recipes.test-helpers.js +339 -0
- package/dist/commands/scenario/impl/commands.d.ts.map +1 -1
- package/dist/commands/scenario/impl/commands.js +192 -336
- package/dist/commands/scenario/info.command.d.ts.map +1 -1
- package/dist/commands/scenario/info.command.js +7 -2
- package/dist/commands/scenario/list.command.js +2 -2
- package/dist/commands/scenario/run.command.d.ts.map +1 -1
- package/dist/commands/scenario/run.command.js +7 -2
- package/dist/commands/shared/reconcile-check.d.ts.map +1 -1
- package/dist/commands/shared/reconcile-check.js +77 -2
- package/dist/commands/shared/task-backend.d.ts +1 -1
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +9 -0
- package/dist/commands/shared/task-store.d.ts +92 -2
- package/dist/commands/shared/task-store.d.ts.map +1 -1
- package/dist/commands/shared/task-store.js +405 -43
- package/dist/commands/task/block.d.ts.map +1 -1
- package/dist/commands/task/block.js +84 -46
- package/dist/commands/task/close-duplicate.d.ts.map +1 -1
- package/dist/commands/task/close-duplicate.js +12 -37
- package/dist/commands/task/close-noop.d.ts.map +1 -1
- package/dist/commands/task/close-noop.js +12 -30
- package/dist/commands/task/close-shared.d.ts +14 -0
- package/dist/commands/task/close-shared.d.ts.map +1 -0
- package/dist/commands/task/close-shared.js +73 -0
- package/dist/commands/task/comment.d.ts.map +1 -1
- package/dist/commands/task/comment.js +34 -21
- package/dist/commands/task/derive.command.d.ts +1 -0
- package/dist/commands/task/derive.command.d.ts.map +1 -1
- package/dist/commands/task/derive.command.js +15 -2
- package/dist/commands/task/derive.d.ts +1 -0
- package/dist/commands/task/derive.d.ts.map +1 -1
- package/dist/commands/task/derive.js +27 -4
- package/dist/commands/task/doc-set.command.d.ts +2 -1
- package/dist/commands/task/doc-set.command.d.ts.map +1 -1
- package/dist/commands/task/doc-set.command.js +36 -4
- package/dist/commands/task/doc-template.d.ts.map +1 -1
- package/dist/commands/task/doc-template.js +2 -7
- package/dist/commands/task/doc.command.js +1 -1
- package/dist/commands/task/doc.d.ts +2 -1
- package/dist/commands/task/doc.d.ts.map +1 -1
- package/dist/commands/task/doc.js +139 -76
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +142 -80
- package/dist/commands/task/migrate-doc.d.ts +15 -0
- package/dist/commands/task/migrate-doc.d.ts.map +1 -1
- package/dist/commands/task/migrate-doc.js +128 -43
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +3 -1
- package/dist/commands/task/plan-set.command.js +1 -1
- package/dist/commands/task/plan.command.d.ts +8 -0
- package/dist/commands/task/plan.command.d.ts.map +1 -0
- package/dist/commands/task/plan.command.js +37 -0
- package/dist/commands/task/plan.d.ts.map +1 -1
- package/dist/commands/task/plan.js +198 -101
- package/dist/commands/task/set-status.command.d.ts.map +1 -1
- package/dist/commands/task/set-status.command.js +1 -1
- package/dist/commands/task/set-status.d.ts.map +1 -1
- package/dist/commands/task/set-status.js +115 -35
- package/dist/commands/task/shared/dependencies.d.ts +1 -0
- package/dist/commands/task/shared/dependencies.d.ts.map +1 -1
- package/dist/commands/task/shared/dependencies.js +10 -0
- package/dist/commands/task/shared/docs.d.ts +1 -0
- package/dist/commands/task/shared/docs.d.ts.map +1 -1
- package/dist/commands/task/shared/docs.js +8 -1
- package/dist/commands/task/shared/transitions.d.ts +17 -2
- package/dist/commands/task/shared/transitions.d.ts.map +1 -1
- package/dist/commands/task/shared/transitions.js +20 -13
- package/dist/commands/task/shared.d.ts +3 -3
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +3 -3
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +101 -71
- package/dist/commands/task/task.command.d.ts +8 -0
- package/dist/commands/task/task.command.d.ts.map +1 -0
- package/dist/commands/task/task.command.js +71 -0
- package/dist/commands/task/verify-command-shared.d.ts +16 -0
- package/dist/commands/task/verify-command-shared.d.ts.map +1 -0
- package/dist/commands/task/verify-command-shared.js +53 -0
- package/dist/commands/task/verify-ok.command.d.ts +2 -6
- package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
- package/dist/commands/task/verify-ok.command.js +8 -50
- package/dist/commands/task/verify-record.d.ts.map +1 -1
- package/dist/commands/task/verify-record.js +124 -145
- package/dist/commands/task/verify-rework.command.d.ts +2 -6
- package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
- package/dist/commands/task/verify-rework.command.js +8 -50
- package/dist/commands/upgrade/apply.d.ts +2 -0
- package/dist/commands/upgrade/apply.d.ts.map +1 -1
- package/dist/commands/upgrade/apply.js +33 -1
- package/dist/commands/upgrade.command.d.ts.map +1 -1
- package/dist/commands/upgrade.command.js +25 -0
- package/dist/commands/upgrade.d.ts +1 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +34 -0
- package/dist/commands/verify.spec.d.ts.map +1 -1
- package/dist/commands/verify.spec.js +3 -12
- package/dist/policy/rules/allowlist.d.ts.map +1 -1
- package/dist/policy/rules/allowlist.js +16 -4
- package/dist/policy/rules/protected-paths.d.ts.map +1 -1
- package/dist/policy/rules/protected-paths.js +6 -1
- package/dist/ports/task-backend-port.d.ts +2 -2
- package/dist/ports/task-backend-port.d.ts.map +1 -1
- package/dist/shared/agent-emoji.d.ts.map +1 -1
- package/dist/shared/protected-paths.d.ts +17 -0
- package/dist/shared/protected-paths.d.ts.map +1 -1
- package/dist/shared/protected-paths.js +59 -10
- package/dist/shared/repo-cli-version.d.ts.map +1 -1
- package/dist/shared/repo-cli-version.js +9 -3
- package/package.json +2 -2
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { normalizeDocSectionName, normalizeTaskDoc, parseDocSections, renderTaskDocFromSections, setMarkdownSection, taskDocToSectionMap, ensureDocSections, } from "@agentplaneorg/core";
|
|
4
4
|
import { mapBackendError, mapCoreError } from "../../cli/error-map.js";
|
|
5
5
|
import { infoMessage, unknownEntityMessage, backendNotSupportedMessage, warnMessage, } from "../../cli/output.js";
|
|
6
6
|
import { CliError } from "../../shared/errors.js";
|
|
7
7
|
import { loadCommandContext } from "../shared/task-backend.js";
|
|
8
8
|
import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
.replaceAll("\r\n", "\n")
|
|
12
|
-
.split("\n")
|
|
13
|
-
.map((line) => line.trimEnd())
|
|
14
|
-
.join("\n")
|
|
15
|
-
.trim();
|
|
16
|
-
}
|
|
17
|
-
function readSectionContent(doc, section) {
|
|
18
|
-
const sectionKey = normalizeDocSectionName(section);
|
|
9
|
+
import { decodeEscapedTaskTextNewlines } from "./shared.js";
|
|
10
|
+
function extractSectionTextForPatch(doc, section) {
|
|
19
11
|
const { sections } = parseDocSections(doc);
|
|
20
|
-
const
|
|
21
|
-
return
|
|
12
|
+
const entry = sections.get(normalizeDocSectionName(section));
|
|
13
|
+
return entry ? entry.lines.join("\n").trimEnd() : null;
|
|
14
|
+
}
|
|
15
|
+
function buildUpdatedTaskDoc(opts) {
|
|
16
|
+
const baseDoc = ensureDocSections(opts.baseDocRaw, opts.requiredSections);
|
|
17
|
+
if (opts.requestMode === "full-doc") {
|
|
18
|
+
return ensureDocSections(opts.text, opts.requiredSections);
|
|
19
|
+
}
|
|
20
|
+
let nextText = opts.text;
|
|
21
|
+
if (opts.headingKeys.size > 0 && opts.headingKeys.has(opts.targetKey)) {
|
|
22
|
+
const lines = nextText.replaceAll("\r\n", "\n").split("\n");
|
|
23
|
+
let firstContent = 0;
|
|
24
|
+
while (firstContent < lines.length && lines[firstContent]?.trim() === "")
|
|
25
|
+
firstContent++;
|
|
26
|
+
if ((lines[firstContent]?.trim() ?? "") === `## ${opts.section}`) {
|
|
27
|
+
lines.splice(firstContent, 1);
|
|
28
|
+
if (lines[firstContent]?.trim() === "")
|
|
29
|
+
lines.splice(firstContent, 1);
|
|
30
|
+
nextText = lines.join("\n");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return ensureDocSections(setMarkdownSection(baseDoc, opts.section ?? "", nextText), opts.requiredSections);
|
|
22
34
|
}
|
|
23
35
|
export async function cmdTaskDocSet(opts) {
|
|
24
36
|
let updatedBy;
|
|
@@ -43,6 +55,9 @@ export async function cmdTaskDocSet(opts) {
|
|
|
43
55
|
});
|
|
44
56
|
}
|
|
45
57
|
let text = opts.text ?? "";
|
|
58
|
+
if (hasText) {
|
|
59
|
+
text = decodeEscapedTaskTextNewlines(text);
|
|
60
|
+
}
|
|
46
61
|
if (hasFile) {
|
|
47
62
|
try {
|
|
48
63
|
text = await readFile(path.resolve(opts.cwd, opts.file ?? ""), "utf8");
|
|
@@ -67,15 +82,29 @@ export async function cmdTaskDocSet(opts) {
|
|
|
67
82
|
const useStore = backendIsLocalFileBackend(ctx);
|
|
68
83
|
const store = useStore ? getTaskStore(ctx) : null;
|
|
69
84
|
const allowed = config.tasks.doc.sections;
|
|
70
|
-
if (!
|
|
85
|
+
if (!opts.fullDoc && !opts.section) {
|
|
86
|
+
throw new CliError({
|
|
87
|
+
exitCode: 2,
|
|
88
|
+
code: "E_USAGE",
|
|
89
|
+
message: "Missing required option: --section (or pass --full-doc)",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (opts.fullDoc && opts.section) {
|
|
93
|
+
throw new CliError({
|
|
94
|
+
exitCode: 2,
|
|
95
|
+
code: "E_USAGE",
|
|
96
|
+
message: "Use either --section or --full-doc (not both)",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (!opts.fullDoc && !allowed.includes(opts.section ?? "")) {
|
|
71
100
|
throw new CliError({
|
|
72
101
|
exitCode: 2,
|
|
73
102
|
code: "E_USAGE",
|
|
74
|
-
message: unknownEntityMessage("doc section", opts.section),
|
|
103
|
+
message: unknownEntityMessage("doc section", opts.section ?? ""),
|
|
75
104
|
});
|
|
76
105
|
}
|
|
77
106
|
const normalizedAllowed = new Set(allowed.map((section) => normalizeDocSectionName(section)));
|
|
78
|
-
const targetKey = normalizeDocSectionName(opts.section);
|
|
107
|
+
const targetKey = normalizeDocSectionName(opts.section ?? "");
|
|
79
108
|
const headingKeys = new Set();
|
|
80
109
|
for (const line of text.replaceAll("\r\n", "\n").split("\n")) {
|
|
81
110
|
const match = /^##\s+(.*)$/.exec(line.trim());
|
|
@@ -85,68 +114,91 @@ export async function cmdTaskDocSet(opts) {
|
|
|
85
114
|
if (key && normalizedAllowed.has(key))
|
|
86
115
|
headingKeys.add(key);
|
|
87
116
|
}
|
|
88
|
-
const
|
|
89
|
-
const baseDocRaw = useStore
|
|
90
|
-
? String(storeTask.doc ?? "")
|
|
91
|
-
: ((await backend.getTaskDoc(opts.taskId)) ?? "");
|
|
92
|
-
const baseDoc = ensureDocSections(baseDocRaw, config.tasks.doc.required_sections);
|
|
93
|
-
const baseSection = readSectionContent(baseDoc, opts.section);
|
|
94
|
-
const requestMode = headingKeys.size > 0 && (headingKeys.size > 1 || !headingKeys.has(targetKey))
|
|
117
|
+
const requestMode = opts.fullDoc
|
|
95
118
|
? "full-doc"
|
|
96
|
-
:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
119
|
+
: headingKeys.size > 0 && (headingKeys.size > 1 || !headingKeys.has(targetKey))
|
|
120
|
+
? "full-doc"
|
|
121
|
+
: "section";
|
|
122
|
+
let changed = false;
|
|
123
|
+
if (useStore) {
|
|
124
|
+
let expectedCurrentDoc;
|
|
125
|
+
let expectedCurrentSectionText;
|
|
126
|
+
const result = await store.patch(opts.taskId, (current) => {
|
|
127
|
+
const currentDocRaw = String(current.doc ?? "");
|
|
128
|
+
const nextDoc = buildUpdatedTaskDoc({
|
|
129
|
+
baseDocRaw: currentDocRaw,
|
|
130
|
+
section: opts.section,
|
|
131
|
+
text,
|
|
132
|
+
requestMode,
|
|
133
|
+
requiredSections: config.tasks.doc.required_sections,
|
|
134
|
+
headingKeys,
|
|
135
|
+
targetKey,
|
|
136
|
+
});
|
|
137
|
+
const docChanged = normalizeTaskDoc(currentDocRaw) !== normalizeTaskDoc(nextDoc);
|
|
138
|
+
const shouldWrite = docChanged || updatedBy !== undefined;
|
|
139
|
+
if (!shouldWrite)
|
|
140
|
+
return null;
|
|
141
|
+
if (!docChanged) {
|
|
142
|
+
return {
|
|
143
|
+
docMeta: {
|
|
144
|
+
touch: true,
|
|
145
|
+
...(updatedBy ? { updatedBy } : {}),
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (requestMode === "full-doc") {
|
|
150
|
+
expectedCurrentDoc ??= currentDocRaw;
|
|
151
|
+
return {
|
|
152
|
+
doc: {
|
|
153
|
+
kind: "replace-doc",
|
|
154
|
+
doc: nextDoc,
|
|
155
|
+
expectedCurrentDoc,
|
|
156
|
+
},
|
|
157
|
+
...(updatedBy ? { docMeta: { updatedBy } } : {}),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
expectedCurrentSectionText ??= extractSectionTextForPatch(currentDocRaw, opts.section ?? "");
|
|
161
|
+
return {
|
|
162
|
+
doc: {
|
|
163
|
+
kind: "set-section",
|
|
164
|
+
section: opts.section ?? "",
|
|
165
|
+
text: extractSectionTextForPatch(nextDoc, opts.section ?? "") ?? "",
|
|
166
|
+
requiredSections: config.tasks.doc.required_sections,
|
|
167
|
+
expectedCurrentText: expectedCurrentSectionText,
|
|
168
|
+
},
|
|
169
|
+
...(updatedBy ? { docMeta: { updatedBy } } : {}),
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
changed = result.changed;
|
|
106
173
|
}
|
|
107
174
|
else {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
175
|
+
const baseDocRaw = (await backend.getTaskDoc(opts.taskId)) ?? "";
|
|
176
|
+
const nextDoc = buildUpdatedTaskDoc({
|
|
177
|
+
baseDocRaw,
|
|
178
|
+
section: opts.section,
|
|
179
|
+
text,
|
|
180
|
+
requestMode,
|
|
181
|
+
requiredSections: config.tasks.doc.required_sections,
|
|
182
|
+
headingKeys,
|
|
183
|
+
targetKey,
|
|
184
|
+
});
|
|
185
|
+
const docChanged = normalizeTaskDoc(baseDocRaw) !== normalizeTaskDoc(nextDoc);
|
|
186
|
+
const shouldWrite = docChanged || updatedBy !== undefined;
|
|
187
|
+
if (shouldWrite) {
|
|
188
|
+
await backend.setTaskDoc(opts.taskId, nextDoc, updatedBy);
|
|
120
189
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}))
|
|
129
|
-
: backend.setTaskDoc(opts.taskId, normalized, updatedBy));
|
|
130
|
-
}
|
|
131
|
-
const updatedTask = useStore ? await store.get(opts.taskId) : null;
|
|
132
|
-
const updatedDocRaw = useStore
|
|
133
|
-
? String(updatedTask?.doc ?? "")
|
|
134
|
-
: ((await backend.getTaskDoc(opts.taskId)) ?? "");
|
|
135
|
-
const updatedDoc = ensureDocSections(updatedDocRaw, config.tasks.doc.required_sections);
|
|
136
|
-
const updatedSection = readSectionContent(updatedDoc, opts.section);
|
|
137
|
-
const docChanged = normalizeOutcomeText(baseDoc) !== normalizeOutcomeText(updatedDoc);
|
|
138
|
-
const sectionChanged = baseSection !== updatedSection;
|
|
190
|
+
changed = shouldWrite;
|
|
191
|
+
}
|
|
192
|
+
const outcome = changed
|
|
193
|
+
? requestMode === "full-doc"
|
|
194
|
+
? "full-doc-updated"
|
|
195
|
+
: "section-updated"
|
|
196
|
+
: "no-change";
|
|
139
197
|
const tasksDir = path.join(resolved.gitRoot, config.paths.workflow_dir);
|
|
140
198
|
process.stdout.write(`${path.join(tasksDir, opts.taskId, "README.md")}\n`);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
else if (requestMode === "full-doc") {
|
|
145
|
-
process.stderr.write(`${infoMessage(`task doc set applied a full-doc update; target section ${opts.section} ${sectionChanged ? "changed" : "did not change"}`)}\n`);
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
process.stderr.write(`${infoMessage(`task doc set updated section ${opts.section}${sectionChanged ? "" : " (effective section content unchanged)"}`)}\n`);
|
|
149
|
-
}
|
|
199
|
+
const outcomeTarget = opts.fullDoc ? "<full-doc>" : (opts.section ?? "");
|
|
200
|
+
const outcomeText = `task doc set outcome=${outcome} section=${outcomeTarget}`;
|
|
201
|
+
process.stderr.write(`${outcome === "no-change" ? warnMessage(outcomeText) : infoMessage(outcomeText)}\n`);
|
|
150
202
|
return 0;
|
|
151
203
|
}
|
|
152
204
|
catch (err) {
|
|
@@ -170,19 +222,30 @@ export async function cmdTaskDocShow(opts) {
|
|
|
170
222
|
const useStore = backendIsLocalFileBackend(ctx);
|
|
171
223
|
const storeTask = useStore ? await getTaskStore(ctx).get(opts.taskId) : null;
|
|
172
224
|
const doc = useStore
|
|
173
|
-
?
|
|
225
|
+
? storeTask?.sections && Object.keys(storeTask.sections).length > 0
|
|
226
|
+
? renderTaskDocFromSections(storeTask.sections)
|
|
227
|
+
: String(storeTask?.doc ?? "")
|
|
174
228
|
: ((await backend.getTaskDoc(opts.taskId)) ?? "");
|
|
229
|
+
const canonicalSections = new Map();
|
|
230
|
+
for (const [title, text] of Object.entries(useStore && storeTask?.sections && Object.keys(storeTask.sections).length > 0
|
|
231
|
+
? storeTask.sections
|
|
232
|
+
: taskDocToSectionMap(doc))) {
|
|
233
|
+
canonicalSections.set(normalizeDocSectionName(title), {
|
|
234
|
+
title,
|
|
235
|
+
lines: String(text ?? "").split("\n"),
|
|
236
|
+
});
|
|
237
|
+
}
|
|
175
238
|
if (opts.section) {
|
|
176
239
|
const sectionKey = normalizeDocSectionName(opts.section);
|
|
177
|
-
const
|
|
178
|
-
const entry = sections.get(sectionKey);
|
|
240
|
+
const entry = canonicalSections.get(sectionKey);
|
|
179
241
|
const content = entry?.lines ?? [];
|
|
180
|
-
if (content.length > 0) {
|
|
242
|
+
if (content.some((line) => line.trim().length > 0)) {
|
|
181
243
|
process.stdout.write(`${content.join("\n").trimEnd()}\n`);
|
|
182
244
|
return 0;
|
|
183
245
|
}
|
|
184
246
|
if (!opts.quiet) {
|
|
185
247
|
process.stdout.write(`${infoMessage(`section has no content: ${opts.section}`)}\n`);
|
|
248
|
+
return 0;
|
|
186
249
|
}
|
|
187
250
|
return 0;
|
|
188
251
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAgGnC,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,OAAO,CAAC;IAClC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8YlB"}
|
|
@@ -9,7 +9,7 @@ import { buildGitCommitEnv, cmdCommit, commitFromComment } from "../guard/index.
|
|
|
9
9
|
import { ensureActionApproved } from "../shared/approval-requirements.js";
|
|
10
10
|
import { ensureReconciledBeforeMutation } from "../shared/reconcile-check.js";
|
|
11
11
|
import { loadCommandContext, loadTaskFromContext, } from "../shared/task-backend.js";
|
|
12
|
-
import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
|
|
12
|
+
import { appendTaskCommentIntent, appendTaskEventIntent, backendIsLocalFileBackend, getTaskStore, mutateTaskStore, setTaskFieldsIntent, touchTaskDocMetaIntent, } from "../shared/task-store.js";
|
|
13
13
|
import { readDirectWorkLock } from "../../shared/direct-work-lock.js";
|
|
14
14
|
import { appendTaskEvent, defaultCommitEmojiForStatus, enforceStatusCommitPolicy, ensureAgentFilledRequiredDocSections, ensureVerificationSatisfiedIfRequired, normalizeTaskDocVersion, nowIso, readCommitInfo, readHeadCommit, requireStructuredComment, resolvePrimaryTag, toStringArray, } from "./shared.js";
|
|
15
15
|
async function clearDirectWorkLockIfMatches(opts) {
|
|
@@ -28,6 +28,43 @@ async function clearDirectWorkLockIfMatches(opts) {
|
|
|
28
28
|
// best-effort
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
+
function assertTaskCanFinish(opts) {
|
|
32
|
+
if (!opts.force && String(opts.task.status || "TODO").toUpperCase() === "DONE") {
|
|
33
|
+
throw new CliError({
|
|
34
|
+
exitCode: 2,
|
|
35
|
+
code: "E_USAGE",
|
|
36
|
+
message: `Task is already DONE: ${opts.task.id} (use --force to override)`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
ensureVerificationSatisfiedIfRequired(opts.task, opts.config);
|
|
40
|
+
const normalizedDoc = ensureDocSections(typeof opts.task.doc === "string" ? opts.task.doc : "", opts.config.tasks.doc.required_sections);
|
|
41
|
+
ensureAgentFilledRequiredDocSections({
|
|
42
|
+
task: opts.task,
|
|
43
|
+
config: opts.config,
|
|
44
|
+
doc: normalizedDoc,
|
|
45
|
+
action: "finish task",
|
|
46
|
+
});
|
|
47
|
+
if (!opts.isMetaTask)
|
|
48
|
+
return;
|
|
49
|
+
const tags = Array.isArray(opts.task.tags)
|
|
50
|
+
? opts.task.tags.filter((t) => typeof t === "string")
|
|
51
|
+
: [];
|
|
52
|
+
const isSpike = tags.includes("spike");
|
|
53
|
+
if (!isSpike && opts.taskCount === 1 && !opts.resultSummary) {
|
|
54
|
+
throw new CliError({
|
|
55
|
+
exitCode: 2,
|
|
56
|
+
code: "E_USAGE",
|
|
57
|
+
message: "Missing required --result for non-spike tasks.",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (opts.resultProvided && !opts.resultSummary) {
|
|
61
|
+
throw new CliError({
|
|
62
|
+
exitCode: 2,
|
|
63
|
+
code: "E_USAGE",
|
|
64
|
+
message: "Invalid value for --result: empty.",
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
31
68
|
export async function cmdFinish(opts) {
|
|
32
69
|
try {
|
|
33
70
|
const ctx = opts.ctx ??
|
|
@@ -123,6 +160,7 @@ export async function cmdFinish(opts) {
|
|
|
123
160
|
const shouldCloseCommit = opts.closeCommit === true || (defaultDirectCloseCommit && opts.noCloseCommit !== true);
|
|
124
161
|
const metaTaskId = opts.taskIds.length === 1 ? (opts.taskIds[0] ?? "") : "";
|
|
125
162
|
const wantMeta = typeof opts.result === "string" || typeof opts.risk === "string" || opts.breaking === true;
|
|
163
|
+
const resultProvided = typeof opts.result === "string";
|
|
126
164
|
if (wantMeta && opts.taskIds.length !== 1) {
|
|
127
165
|
throw new CliError({
|
|
128
166
|
exitCode: 2,
|
|
@@ -137,78 +175,88 @@ export async function cmdFinish(opts) {
|
|
|
137
175
|
let primaryTag = null;
|
|
138
176
|
for (const taskId of opts.taskIds) {
|
|
139
177
|
const task = useStore ? await store.get(taskId) : await loadTaskFromContext({ ctx, taskId });
|
|
140
|
-
if (!
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
178
|
+
if (!useStore) {
|
|
179
|
+
assertTaskCanFinish({
|
|
180
|
+
task,
|
|
181
|
+
config: ctx.config,
|
|
182
|
+
taskCount: opts.taskIds.length,
|
|
183
|
+
isMetaTask: taskId === metaTaskId,
|
|
184
|
+
resultProvided,
|
|
185
|
+
resultSummary,
|
|
186
|
+
force: opts.force,
|
|
187
|
+
});
|
|
188
|
+
if (taskId === primaryTaskId && (opts.commitFromComment || statusCommitRequested)) {
|
|
189
|
+
primaryStatusFrom = String(task.status || "TODO").toUpperCase();
|
|
190
|
+
primaryTag = resolvePrimaryTag(toStringArray(task.tags), ctx).primary;
|
|
148
191
|
}
|
|
149
192
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
193
|
+
const at = nowIso();
|
|
194
|
+
if (useStore) {
|
|
195
|
+
await mutateTaskStore(store, taskId, (current) => {
|
|
196
|
+
assertTaskCanFinish({
|
|
197
|
+
task: current,
|
|
198
|
+
config: ctx.config,
|
|
199
|
+
taskCount: opts.taskIds.length,
|
|
200
|
+
isMetaTask: taskId === metaTaskId,
|
|
201
|
+
resultProvided,
|
|
202
|
+
resultSummary,
|
|
203
|
+
force: opts.force,
|
|
204
|
+
});
|
|
205
|
+
const currentStatus = String(current.status || "TODO").toUpperCase();
|
|
206
|
+
if (taskId === primaryTaskId && (opts.commitFromComment || statusCommitRequested)) {
|
|
207
|
+
primaryStatusFrom = currentStatus;
|
|
208
|
+
primaryTag = resolvePrimaryTag(toStringArray(current.tags), ctx).primary;
|
|
209
|
+
}
|
|
210
|
+
return [
|
|
211
|
+
setTaskFieldsIntent({
|
|
212
|
+
status: "DONE",
|
|
213
|
+
commit: { hash: commitInfo.hash, message: commitInfo.message },
|
|
214
|
+
...(taskId === metaTaskId && resultSummary ? { result_summary: resultSummary } : {}),
|
|
215
|
+
...(taskId === metaTaskId && riskLevel ? { risk_level: riskLevel } : {}),
|
|
216
|
+
...(taskId === metaTaskId && breaking ? { breaking: true } : {}),
|
|
217
|
+
}),
|
|
218
|
+
appendTaskCommentIntent({ author: opts.author, body: opts.body }),
|
|
219
|
+
appendTaskEventIntent({
|
|
220
|
+
type: "status",
|
|
221
|
+
at,
|
|
222
|
+
author: opts.author,
|
|
223
|
+
from: currentStatus,
|
|
224
|
+
to: "DONE",
|
|
225
|
+
note: opts.body,
|
|
226
|
+
}),
|
|
227
|
+
touchTaskDocMetaIntent({
|
|
228
|
+
updatedBy: opts.author,
|
|
229
|
+
version: normalizeTaskDocVersion(current.doc_version),
|
|
230
|
+
}),
|
|
231
|
+
];
|
|
232
|
+
});
|
|
155
233
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
task,
|
|
160
|
-
config: ctx.config,
|
|
161
|
-
doc: normalizedDoc,
|
|
162
|
-
action: "finish task",
|
|
163
|
-
});
|
|
164
|
-
if (taskId === metaTaskId) {
|
|
165
|
-
const tags = Array.isArray(task.tags)
|
|
166
|
-
? task.tags.filter((t) => typeof t === "string")
|
|
234
|
+
else {
|
|
235
|
+
const existingComments = Array.isArray(task.comments)
|
|
236
|
+
? task.comments.filter((item) => !!item && typeof item.author === "string" && typeof item.body === "string")
|
|
167
237
|
: [];
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
238
|
+
const nextTask = {
|
|
239
|
+
...task,
|
|
240
|
+
status: "DONE",
|
|
241
|
+
commit: { hash: commitInfo.hash, message: commitInfo.message },
|
|
242
|
+
comments: [...existingComments, { author: opts.author, body: opts.body }],
|
|
243
|
+
events: appendTaskEvent(task, {
|
|
244
|
+
type: "status",
|
|
245
|
+
at,
|
|
246
|
+
author: opts.author,
|
|
247
|
+
from: String(task.status || "TODO").toUpperCase(),
|
|
248
|
+
to: "DONE",
|
|
249
|
+
note: opts.body,
|
|
250
|
+
}),
|
|
251
|
+
result_summary: taskId === metaTaskId && resultSummary ? resultSummary : task.result_summary,
|
|
252
|
+
risk_level: taskId === metaTaskId && riskLevel ? riskLevel : task.risk_level,
|
|
253
|
+
breaking: taskId === metaTaskId && breaking ? true : task.breaking,
|
|
254
|
+
doc_version: normalizeTaskDocVersion(task.doc_version),
|
|
255
|
+
doc_updated_at: at,
|
|
256
|
+
doc_updated_by: opts.author,
|
|
257
|
+
};
|
|
258
|
+
await ctx.taskBackend.writeTask(nextTask);
|
|
183
259
|
}
|
|
184
|
-
const existingComments = Array.isArray(task.comments)
|
|
185
|
-
? task.comments.filter((item) => !!item && typeof item.author === "string" && typeof item.body === "string")
|
|
186
|
-
: [];
|
|
187
|
-
const commentsValue = [...existingComments, { author: opts.author, body: opts.body }];
|
|
188
|
-
const at = nowIso();
|
|
189
|
-
const nextTask = {
|
|
190
|
-
...task,
|
|
191
|
-
status: "DONE",
|
|
192
|
-
commit: { hash: commitInfo.hash, message: commitInfo.message },
|
|
193
|
-
comments: commentsValue,
|
|
194
|
-
events: appendTaskEvent(task, {
|
|
195
|
-
type: "status",
|
|
196
|
-
at,
|
|
197
|
-
author: opts.author,
|
|
198
|
-
from: String(task.status || "TODO").toUpperCase(),
|
|
199
|
-
to: "DONE",
|
|
200
|
-
note: opts.body,
|
|
201
|
-
}),
|
|
202
|
-
result_summary: taskId === metaTaskId && resultSummary ? resultSummary : task.result_summary,
|
|
203
|
-
risk_level: taskId === metaTaskId && riskLevel ? riskLevel : task.risk_level,
|
|
204
|
-
breaking: taskId === metaTaskId && breaking ? true : task.breaking,
|
|
205
|
-
doc_version: normalizeTaskDocVersion(task.doc_version),
|
|
206
|
-
doc_updated_at: at,
|
|
207
|
-
doc_updated_by: opts.author,
|
|
208
|
-
};
|
|
209
|
-
await (useStore
|
|
210
|
-
? store.update(taskId, () => nextTask)
|
|
211
|
-
: ctx.taskBackend.writeTask(nextTask));
|
|
212
260
|
}
|
|
213
261
|
if (opts.commitFromComment || statusCommitRequested) {
|
|
214
262
|
enforceStatusCommitPolicy({
|
|
@@ -233,6 +281,9 @@ export async function cmdFinish(opts) {
|
|
|
233
281
|
}
|
|
234
282
|
}
|
|
235
283
|
if (opts.commitFromComment) {
|
|
284
|
+
if (!opts.quiet) {
|
|
285
|
+
process.stdout.write(`${infoMessage("task marked DONE; creating commit from verification comment")}\n`);
|
|
286
|
+
}
|
|
236
287
|
if (typeof opts.commitEmoji === "string" && opts.commitEmoji.trim() !== "✅") {
|
|
237
288
|
throw new CliError({
|
|
238
289
|
exitCode: 2,
|
|
@@ -263,19 +314,27 @@ export async function cmdFinish(opts) {
|
|
|
263
314
|
// commitFromComment creates the git commit and returns the actual head hash/subject.
|
|
264
315
|
// Refresh task commit metadata to this hash and amend the same commit in local mode so
|
|
265
316
|
// "task done" metadata does not require a manual follow-up close commit.
|
|
266
|
-
const taskAfterCommit = useStore
|
|
267
|
-
? await store.get(primaryTaskId)
|
|
268
|
-
: await loadTaskFromContext({ ctx, taskId: primaryTaskId });
|
|
269
|
-
const updatedAfterCommit = {
|
|
270
|
-
...taskAfterCommit,
|
|
271
|
-
commit: { hash: committed.hash, message: committed.message },
|
|
272
|
-
doc_version: normalizeTaskDocVersion(taskAfterCommit.doc_version),
|
|
273
|
-
doc_updated_at: nowIso(),
|
|
274
|
-
doc_updated_by: opts.author,
|
|
275
|
-
};
|
|
276
317
|
await (useStore
|
|
277
|
-
? store
|
|
278
|
-
|
|
318
|
+
? mutateTaskStore(store, primaryTaskId, (current) => [
|
|
319
|
+
setTaskFieldsIntent({
|
|
320
|
+
commit: { hash: committed.hash, message: committed.message },
|
|
321
|
+
}),
|
|
322
|
+
touchTaskDocMetaIntent({
|
|
323
|
+
updatedBy: opts.author,
|
|
324
|
+
version: normalizeTaskDocVersion(current.doc_version),
|
|
325
|
+
}),
|
|
326
|
+
])
|
|
327
|
+
: (async () => {
|
|
328
|
+
const taskAfterCommit = await loadTaskFromContext({ ctx, taskId: primaryTaskId });
|
|
329
|
+
const updatedAfterCommit = {
|
|
330
|
+
...taskAfterCommit,
|
|
331
|
+
commit: { hash: committed.hash, message: committed.message },
|
|
332
|
+
doc_version: normalizeTaskDocVersion(taskAfterCommit.doc_version),
|
|
333
|
+
doc_updated_at: nowIso(),
|
|
334
|
+
doc_updated_by: opts.author,
|
|
335
|
+
};
|
|
336
|
+
await ctx.taskBackend.writeTask(updatedAfterCommit);
|
|
337
|
+
})());
|
|
279
338
|
if (backendWritesTaskReadmes) {
|
|
280
339
|
const workflowReadmeRelPath = path.join(ctx.config.paths.workflow_dir, primaryTaskId, "README.md");
|
|
281
340
|
await ctx.git.stage([workflowReadmeRelPath]);
|
|
@@ -294,6 +353,9 @@ export async function cmdFinish(opts) {
|
|
|
294
353
|
}
|
|
295
354
|
}
|
|
296
355
|
if (statusCommitRequested) {
|
|
356
|
+
if (!opts.quiet) {
|
|
357
|
+
process.stdout.write(`${infoMessage("task marked DONE; creating status commit")}\n`);
|
|
358
|
+
}
|
|
297
359
|
if (typeof opts.statusCommitEmoji === "string" && opts.statusCommitEmoji.trim() !== "✅") {
|
|
298
360
|
throw new CliError({
|
|
299
361
|
exitCode: 2,
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
import { resolveProject, type AgentplaneConfig } from "@agentplaneorg/core";
|
|
2
|
+
import { type CommandContext } from "../shared/task-backend.js";
|
|
3
|
+
export type TaskDocMigrationResult = {
|
|
4
|
+
changed: number;
|
|
5
|
+
changedPaths: string[];
|
|
6
|
+
};
|
|
7
|
+
export declare function migrateTaskDocsInWorkspace(opts: {
|
|
8
|
+
cwd: string;
|
|
9
|
+
rootOverride?: string | null;
|
|
10
|
+
all: boolean;
|
|
11
|
+
taskIds: string[];
|
|
12
|
+
resolvedProject?: Awaited<ReturnType<typeof resolveProject>>;
|
|
13
|
+
config?: AgentplaneConfig;
|
|
14
|
+
ctx?: CommandContext;
|
|
15
|
+
}): Promise<TaskDocMigrationResult>;
|
|
1
16
|
export declare function cmdTaskMigrateDoc(opts: {
|
|
2
17
|
cwd: string;
|
|
3
18
|
rootOverride?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate-doc.d.ts","sourceRoot":"","sources":["../../../src/commands/task/migrate-doc.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migrate-doc.d.ts","sourceRoot":"","sources":["../../../src/commands/task/migrate-doc.ts"],"names":[],"mappings":"AAGA,OAAO,EAUL,cAAc,EAGd,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAQ7B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAanC,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AA+TF,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC;IAC7D,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,GAAG,CAAC,EAAE,cAAc,CAAC;CACtB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA4DlC;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBlB"}
|