agentplane 0.3.10 → 0.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/AGENTS.md +2 -2
- package/assets/agents/CODER.json +4 -0
- package/assets/agents/CREATOR.json +1 -0
- package/assets/agents/DOCS.json +2 -1
- package/assets/agents/INTEGRATOR.json +2 -1
- package/assets/agents/ORCHESTRATOR.json +2 -0
- package/assets/agents/PLANNER.json +3 -1
- package/assets/agents/REVIEWER.json +1 -0
- package/assets/agents/TESTER.json +2 -2
- package/assets/agents/UPDATER.json +1 -0
- package/assets/agents/UPGRADER.json +1 -1
- package/assets/policy/governance.md +3 -4
- package/assets/policy/incidents.md +20 -88
- package/assets/policy/workflow.branch_pr.md +1 -1
- package/assets/policy/workflow.direct.md +2 -2
- package/bin/agentplane.js +114 -4
- package/bin/runtime-watch.js +1 -0
- package/bin/stale-dist-policy.d.ts +1 -1
- package/bin/stale-dist-policy.js +19 -1
- package/dist/.build-manifest.json +251 -166
- package/dist/cli/bootstrap-guide.d.ts.map +1 -1
- package/dist/cli/bootstrap-guide.js +3 -2
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +2 -1
- package/dist/cli/command-invocations.d.ts.map +1 -1
- package/dist/cli/command-invocations.js +4 -1
- package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/core.js +6 -1
- package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/project.js +3 -1
- package/dist/cli/run-cli/command-catalog/task.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/task.js +10 -0
- package/dist/cli/run-cli/command-catalog.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core/preflight.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core/preflight.js +44 -1
- package/dist/cli/run-cli.test-helpers.d.ts +1 -0
- package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +26 -0
- package/dist/commands/branch/cleanup-merged.d.ts +3 -0
- package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
- package/dist/commands/branch/cleanup-merged.js +149 -36
- package/dist/commands/branch/work-start.d.ts.map +1 -1
- package/dist/commands/branch/work-start.js +137 -1
- package/dist/commands/cleanup/merged.command.d.ts +2 -0
- package/dist/commands/cleanup/merged.command.d.ts.map +1 -1
- package/dist/commands/cleanup/merged.command.js +24 -0
- package/dist/commands/doctor/branch-pr.d.ts +4 -0
- package/dist/commands/doctor/branch-pr.d.ts.map +1 -0
- package/dist/commands/doctor/branch-pr.js +96 -0
- package/dist/commands/doctor/fixes.d.ts +5 -0
- package/dist/commands/doctor/fixes.d.ts.map +1 -1
- package/dist/commands/doctor/fixes.js +70 -0
- package/dist/commands/doctor.run.d.ts.map +1 -1
- package/dist/commands/doctor.run.js +6 -1
- package/dist/commands/finish.run.d.ts.map +1 -1
- package/dist/commands/finish.run.js +11 -0
- package/dist/commands/finish.spec.d.ts +11 -0
- package/dist/commands/finish.spec.d.ts.map +1 -1
- package/dist/commands/finish.spec.js +51 -0
- package/dist/commands/guard/impl/close-message.d.ts.map +1 -1
- package/dist/commands/guard/impl/close-message.js +23 -6
- package/dist/commands/guard/impl/commands.d.ts +1 -0
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +94 -2
- package/dist/commands/guard/impl/env.d.ts +1 -0
- package/dist/commands/guard/impl/env.d.ts.map +1 -1
- package/dist/commands/guard/impl/env.js +1 -0
- package/dist/commands/hooks/index.d.ts +1 -1
- package/dist/commands/hooks/index.d.ts.map +1 -1
- package/dist/commands/hooks/index.js +139 -6
- package/dist/commands/incidents/collect.command.d.ts.map +1 -1
- package/dist/commands/incidents/collect.command.js +12 -7
- package/dist/commands/incidents/incidents.command.js +1 -1
- package/dist/commands/incidents/shared.d.ts +34 -0
- package/dist/commands/incidents/shared.d.ts.map +1 -1
- package/dist/commands/incidents/shared.js +166 -12
- package/dist/commands/pr/check.d.ts.map +1 -1
- package/dist/commands/pr/check.js +241 -135
- package/dist/commands/pr/close-superseded.d.ts +9 -0
- package/dist/commands/pr/close-superseded.d.ts.map +1 -0
- package/dist/commands/pr/close-superseded.js +129 -0
- package/dist/commands/pr/close.d.ts +11 -0
- package/dist/commands/pr/close.d.ts.map +1 -0
- package/dist/commands/pr/close.js +116 -0
- package/dist/commands/pr/index.d.ts +2 -0
- package/dist/commands/pr/index.d.ts.map +1 -1
- package/dist/commands/pr/index.js +2 -0
- package/dist/commands/pr/integrate/artifacts.d.ts +7 -0
- package/dist/commands/pr/integrate/artifacts.d.ts.map +1 -1
- package/dist/commands/pr/integrate/artifacts.js +66 -1
- package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
- package/dist/commands/pr/integrate/cmd.js +43 -2
- package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts +8 -0
- package/dist/commands/pr/integrate/internal/bootstrap-guidance.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/bootstrap-guidance.js +59 -0
- package/dist/commands/pr/integrate/internal/cleanup.d.ts +1 -11
- package/dist/commands/pr/integrate/internal/cleanup.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/cleanup.js +1 -46
- package/dist/commands/pr/integrate/internal/finalize.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/finalize.js +43 -12
- package/dist/commands/pr/integrate/internal/github-protection.d.ts +5 -0
- package/dist/commands/pr/integrate/internal/github-protection.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/github-protection.js +13 -0
- package/dist/commands/pr/integrate/internal/merge.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/merge.js +36 -13
- package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts +13 -0
- package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/post-integrate-bootstrap.js +25 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts +15 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.js +35 -0
- package/dist/commands/pr/integrate/internal/prepare.d.ts +4 -2
- package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/prepare.js +109 -38
- package/dist/commands/pr/internal/auto-commit.d.ts +7 -0
- package/dist/commands/pr/internal/auto-commit.d.ts.map +1 -0
- package/dist/commands/pr/internal/auto-commit.js +64 -0
- package/dist/commands/pr/internal/freshness.d.ts +21 -0
- package/dist/commands/pr/internal/freshness.d.ts.map +1 -0
- package/dist/commands/pr/internal/freshness.js +52 -0
- package/dist/commands/pr/internal/gh-api.d.ts +6 -0
- package/dist/commands/pr/internal/gh-api.d.ts.map +1 -0
- package/dist/commands/pr/internal/gh-api.js +80 -0
- package/dist/commands/pr/internal/pr-paths.d.ts +10 -0
- package/dist/commands/pr/internal/pr-paths.d.ts.map +1 -1
- package/dist/commands/pr/internal/pr-paths.js +10 -0
- package/dist/commands/pr/internal/review-template.d.ts.map +1 -1
- package/dist/commands/pr/internal/review-template.js +37 -4
- package/dist/commands/pr/internal/sync.d.ts +9 -0
- package/dist/commands/pr/internal/sync.d.ts.map +1 -1
- package/dist/commands/pr/internal/sync.js +531 -124
- package/dist/commands/pr/open.d.ts +1 -0
- package/dist/commands/pr/open.d.ts.map +1 -1
- package/dist/commands/pr/open.js +24 -2
- package/dist/commands/pr/pr.command.d.ts +15 -0
- package/dist/commands/pr/pr.command.d.ts.map +1 -1
- package/dist/commands/pr/pr.command.js +118 -2
- package/dist/commands/pr/update.d.ts.map +1 -1
- package/dist/commands/pr/update.js +71 -2
- package/dist/commands/release/apply.command.d.ts +3 -1
- package/dist/commands/release/apply.command.d.ts.map +1 -1
- package/dist/commands/release/apply.command.js +356 -34
- package/dist/commands/release/apply.mutation.d.ts.map +1 -1
- package/dist/commands/release/apply.mutation.js +1 -0
- package/dist/commands/release/apply.preflight.d.ts.map +1 -1
- package/dist/commands/release/apply.preflight.js +1 -1
- package/dist/commands/release/apply.reporting.d.ts +1 -0
- package/dist/commands/release/apply.reporting.d.ts.map +1 -1
- package/dist/commands/release/apply.reporting.js +12 -8
- package/dist/commands/release/apply.types.d.ts +13 -0
- package/dist/commands/release/apply.types.d.ts.map +1 -1
- package/dist/commands/release/plan.command.d.ts.map +1 -1
- package/dist/commands/release/plan.command.js +48 -0
- package/dist/commands/shared/gh-transport.d.ts +16 -0
- package/dist/commands/shared/gh-transport.d.ts.map +1 -0
- package/dist/commands/shared/gh-transport.js +71 -0
- package/dist/commands/shared/git-diff.d.ts +3 -1
- package/dist/commands/shared/git-diff.d.ts.map +1 -1
- package/dist/commands/shared/git-diff.js +10 -2
- package/dist/commands/shared/git-ops.d.ts +1 -0
- package/dist/commands/shared/git-ops.d.ts.map +1 -1
- package/dist/commands/shared/git-ops.js +15 -0
- package/dist/commands/shared/git-worktree.d.ts +2 -0
- package/dist/commands/shared/git-worktree.d.ts.map +1 -1
- package/dist/commands/shared/git-worktree.js +22 -2
- package/dist/commands/shared/merged-branch-cleanup.d.ts +12 -0
- package/dist/commands/shared/merged-branch-cleanup.d.ts.map +1 -0
- package/dist/commands/shared/merged-branch-cleanup.js +46 -0
- package/dist/commands/shared/post-commit-pr-artifacts.d.ts +9 -0
- package/dist/commands/shared/post-commit-pr-artifacts.d.ts.map +1 -0
- package/dist/commands/shared/post-commit-pr-artifacts.js +57 -0
- package/dist/commands/shared/pr-meta.d.ts +20 -0
- package/dist/commands/shared/pr-meta.d.ts.map +1 -1
- package/dist/commands/shared/pr-meta.js +125 -0
- package/dist/commands/shared/task-backend.d.ts +7 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +71 -27
- package/dist/commands/shared/task-local-freshness.d.ts +2 -0
- package/dist/commands/shared/task-local-freshness.d.ts.map +1 -1
- package/dist/commands/shared/task-local-freshness.js +7 -1
- package/dist/commands/task/close-duplicate.d.ts.map +1 -1
- package/dist/commands/task/close-duplicate.js +34 -1
- package/dist/commands/task/derive.js +1 -1
- package/dist/commands/task/doc-template.d.ts.map +1 -1
- package/dist/commands/task/doc-template.js +7 -11
- package/dist/commands/task/findings-add.command.d.ts +20 -0
- package/dist/commands/task/findings-add.command.d.ts.map +1 -0
- package/dist/commands/task/findings-add.command.js +165 -0
- package/dist/commands/task/findings.command.d.ts +7 -0
- package/dist/commands/task/findings.command.d.ts.map +1 -0
- package/dist/commands/task/findings.command.js +20 -0
- package/dist/commands/task/findings.d.ts +63 -0
- package/dist/commands/task/findings.d.ts.map +1 -0
- package/dist/commands/task/findings.js +188 -0
- package/dist/commands/task/finish-shared.d.ts +2 -0
- package/dist/commands/task/finish-shared.d.ts.map +1 -1
- package/dist/commands/task/finish-shared.js +56 -1
- package/dist/commands/task/finish.d.ts +10 -0
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +125 -6
- package/dist/commands/task/hosted-close-pr.command.d.ts +11 -0
- package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -0
- package/dist/commands/task/hosted-close-pr.command.js +449 -0
- package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
- package/dist/commands/task/hosted-close.command.js +234 -19
- package/dist/commands/task/hosted-merge-sync.d.ts +41 -0
- package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
- package/dist/commands/task/hosted-merge-sync.js +291 -17
- package/dist/commands/task/index.d.ts +1 -0
- package/dist/commands/task/index.d.ts.map +1 -1
- package/dist/commands/task/index.js +1 -0
- package/dist/commands/task/new.d.ts +1 -0
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +71 -1
- package/dist/commands/task/new.spec.d.ts.map +1 -1
- package/dist/commands/task/new.spec.js +7 -0
- package/dist/commands/task/normalize.command.d.ts +2 -0
- package/dist/commands/task/normalize.command.d.ts.map +1 -1
- package/dist/commands/task/normalize.command.js +45 -0
- package/dist/commands/task/normalize.d.ts +2 -0
- package/dist/commands/task/normalize.d.ts.map +1 -1
- package/dist/commands/task/normalize.js +85 -8
- package/dist/commands/task/plan.d.ts.map +1 -1
- package/dist/commands/task/plan.js +7 -10
- package/dist/commands/task/shared/docs.d.ts +6 -0
- package/dist/commands/task/shared/docs.d.ts.map +1 -1
- package/dist/commands/task/shared/docs.js +14 -0
- package/dist/commands/task/shared/transitions.d.ts.map +1 -1
- package/dist/commands/task/shared/transitions.js +11 -1
- package/dist/commands/task/shared.d.ts +1 -1
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +1 -1
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +7 -10
- package/dist/commands/task/task.command.d.ts.map +1 -1
- package/dist/commands/task/task.command.js +4 -0
- package/dist/commands/task/verify-command-shared.d.ts +19 -0
- package/dist/commands/task/verify-command-shared.d.ts.map +1 -1
- package/dist/commands/task/verify-command-shared.js +152 -1
- package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
- package/dist/commands/task/verify-ok.command.js +15 -2
- package/dist/commands/task/verify-record.d.ts +36 -0
- package/dist/commands/task/verify-record.d.ts.map +1 -1
- package/dist/commands/task/verify-record.js +166 -11
- package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
- package/dist/commands/task/verify-rework.command.js +15 -2
- package/dist/commands/task/verify-show.command.d.ts +1 -1
- package/dist/commands/task/verify-show.command.d.ts.map +1 -1
- package/dist/commands/task/verify-show.command.js +28 -1
- package/dist/commands/verify.run.d.ts.map +1 -1
- package/dist/commands/verify.run.js +12 -0
- package/dist/commands/verify.spec.d.ts +2 -6
- package/dist/commands/verify.spec.d.ts.map +1 -1
- package/dist/commands/verify.spec.js +30 -3
- package/dist/runtime/incidents/index.d.ts +1 -1
- package/dist/runtime/incidents/index.d.ts.map +1 -1
- package/dist/runtime/incidents/resolve.d.ts.map +1 -1
- package/dist/runtime/incidents/resolve.js +319 -73
- package/dist/runtime/incidents/types.d.ts +14 -2
- package/dist/runtime/incidents/types.d.ts.map +1 -1
- package/dist/shared/env.d.ts +1 -0
- package/dist/shared/env.d.ts.map +1 -1
- package/dist/shared/env.js +22 -1
- package/dist/shared/protected-paths.d.ts +1 -1
- package/dist/shared/protected-paths.d.ts.map +1 -1
- package/dist/shared/protected-paths.js +4 -0
- package/package.json +2 -2
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { ensureDocSections, normalizeTaskDoc, setMarkdownSection, } from "@agentplaneorg/core";
|
|
2
|
+
import { mapBackendError } from "../../cli/error-map.js";
|
|
3
|
+
import { infoMessage } from "../../cli/output.js";
|
|
4
|
+
import { CliError } from "../../shared/errors.js";
|
|
5
|
+
import { loadCommandContext } from "../shared/task-backend.js";
|
|
6
|
+
import { applyTaskMutation } from "../shared/task-mutation.js";
|
|
7
|
+
import { setTaskSectionIntent, touchTaskDocMetaIntent, } from "../shared/task-store.js";
|
|
8
|
+
import { resolveWritableDocSections } from "./shared.js";
|
|
9
|
+
import { extractDocSection, extractTaskObservationSection, normalizeTaskDocVersion, taskObservationSectionName, } from "./shared/docs.js";
|
|
10
|
+
function ensureNonEmptyFlag(name, value) {
|
|
11
|
+
const trimmed = value.trim();
|
|
12
|
+
if (!trimmed) {
|
|
13
|
+
throw new CliError({
|
|
14
|
+
exitCode: 2,
|
|
15
|
+
code: "E_USAGE",
|
|
16
|
+
message: `Invalid value for --${name}: empty.`,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return trimmed;
|
|
20
|
+
}
|
|
21
|
+
function dedupeTrimmed(values) {
|
|
22
|
+
const seen = new Set();
|
|
23
|
+
const out = [];
|
|
24
|
+
for (const raw of values) {
|
|
25
|
+
const trimmed = raw.trim();
|
|
26
|
+
if (!trimmed)
|
|
27
|
+
continue;
|
|
28
|
+
const key = trimmed.toLowerCase();
|
|
29
|
+
if (seen.has(key))
|
|
30
|
+
continue;
|
|
31
|
+
seen.add(key);
|
|
32
|
+
out.push(trimmed);
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
export function renderStructuredFindingBlock(opts) {
|
|
37
|
+
const fixability = opts.fixability ?? (opts.external ? "external" : null);
|
|
38
|
+
const lines = [
|
|
39
|
+
`- Observation: ${ensureNonEmptyFlag("observation", opts.observation)}`,
|
|
40
|
+
` Impact: ${ensureNonEmptyFlag("impact", opts.impact)}`,
|
|
41
|
+
` Resolution: ${ensureNonEmptyFlag("resolution", opts.resolution)}`,
|
|
42
|
+
];
|
|
43
|
+
if (opts.promote)
|
|
44
|
+
lines.push(" Promotion: incident-candidate");
|
|
45
|
+
if (fixability === "external")
|
|
46
|
+
lines.push(" Fixability: external");
|
|
47
|
+
if (fixability === "repo-fixable")
|
|
48
|
+
lines.push(" Fixability: repo-fixable");
|
|
49
|
+
if (opts.incidentScope?.trim())
|
|
50
|
+
lines.push(` IncidentScope: ${opts.incidentScope.trim()}`);
|
|
51
|
+
const tags = dedupeTrimmed(opts.incidentTags);
|
|
52
|
+
if (tags.length > 0)
|
|
53
|
+
lines.push(` IncidentTags: ${tags.join(", ")}`);
|
|
54
|
+
const match = dedupeTrimmed(opts.incidentMatch);
|
|
55
|
+
if (match.length > 0)
|
|
56
|
+
lines.push(` IncidentMatch: ${match.join(", ")}`);
|
|
57
|
+
if (opts.incidentAdvice?.trim())
|
|
58
|
+
lines.push(` IncidentAdvice: ${opts.incidentAdvice.trim()}`);
|
|
59
|
+
if (opts.incidentRule?.trim())
|
|
60
|
+
lines.push(` IncidentRule: ${opts.incidentRule.trim()}`);
|
|
61
|
+
return lines.join("\n");
|
|
62
|
+
}
|
|
63
|
+
function appendFindingBlock(existingSection, block) {
|
|
64
|
+
const current = (existingSection ?? "").trim();
|
|
65
|
+
if (!current)
|
|
66
|
+
return block;
|
|
67
|
+
return `${current}\n\n${block}`;
|
|
68
|
+
}
|
|
69
|
+
export function buildStructuredFindingMutationPlan(opts) {
|
|
70
|
+
const currentDocRaw = typeof opts.current.doc === "string" ? opts.current.doc : "";
|
|
71
|
+
const docVersion = normalizeTaskDocVersion(opts.current.doc_version);
|
|
72
|
+
const targetSection = taskObservationSectionName(docVersion);
|
|
73
|
+
const sectionOrder = resolveWritableDocSections({
|
|
74
|
+
allowedSections: opts.config.tasks.doc.sections,
|
|
75
|
+
requiredSections: opts.config.tasks.doc.required_sections,
|
|
76
|
+
targetSection,
|
|
77
|
+
});
|
|
78
|
+
const existingSection = extractTaskObservationSection(currentDocRaw, docVersion);
|
|
79
|
+
const block = renderStructuredFindingBlock({
|
|
80
|
+
observation: opts.observation,
|
|
81
|
+
impact: opts.impact,
|
|
82
|
+
resolution: opts.resolution,
|
|
83
|
+
promote: opts.promote,
|
|
84
|
+
external: opts.external,
|
|
85
|
+
fixability: opts.fixability ?? null,
|
|
86
|
+
incidentScope: opts.incidentScope,
|
|
87
|
+
incidentTags: opts.incidentTags,
|
|
88
|
+
incidentMatch: opts.incidentMatch,
|
|
89
|
+
incidentAdvice: opts.incidentAdvice,
|
|
90
|
+
incidentRule: opts.incidentRule,
|
|
91
|
+
});
|
|
92
|
+
const nextSectionText = appendFindingBlock(existingSection, block);
|
|
93
|
+
const nextDoc = ensureDocSections(setMarkdownSection(currentDocRaw, targetSection, nextSectionText), sectionOrder);
|
|
94
|
+
if (normalizeTaskDoc(currentDocRaw) === normalizeTaskDoc(nextDoc) && !opts.updatedBy) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const expectedCurrentText = extractDocSection(currentDocRaw, targetSection);
|
|
98
|
+
const intents = [
|
|
99
|
+
setTaskSectionIntent({
|
|
100
|
+
section: targetSection,
|
|
101
|
+
text: nextSectionText,
|
|
102
|
+
requiredSections: sectionOrder,
|
|
103
|
+
expectedCurrentText,
|
|
104
|
+
}),
|
|
105
|
+
...(opts.updatedBy ? [touchTaskDocMetaIntent({ updatedBy: opts.updatedBy })] : []),
|
|
106
|
+
];
|
|
107
|
+
return { targetSection, expectedCurrentText, intents };
|
|
108
|
+
}
|
|
109
|
+
export function renderFindingsAddRegistryNote(opts) {
|
|
110
|
+
if (opts.promote && opts.external) {
|
|
111
|
+
if (opts.branchPr) {
|
|
112
|
+
return (`incident candidate recorded for ${opts.taskId}; ` +
|
|
113
|
+
"incidents.md updates later during finish, `verify --collect-incidents`, or `agentplane incidents collect <task-id>`; task-local until base-branch promotion in the current task worktree");
|
|
114
|
+
}
|
|
115
|
+
return (`incident candidate recorded for ${opts.taskId}; ` +
|
|
116
|
+
"incidents.md updates later during finish, `verify --collect-incidents`, or `agentplane incidents collect <task-id>`; task-local in the current checkout until promotion");
|
|
117
|
+
}
|
|
118
|
+
return `task-local finding recorded for ${opts.taskId}; incidents.md unchanged in the current checkout`;
|
|
119
|
+
}
|
|
120
|
+
export async function cmdTaskFindingsAdd(opts) {
|
|
121
|
+
let updatedBy;
|
|
122
|
+
if (opts.updatedBy !== undefined) {
|
|
123
|
+
updatedBy = ensureNonEmptyFlag("updated-by", opts.updatedBy);
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const ctx = opts.ctx ??
|
|
127
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
128
|
+
const backend = ctx.taskBackend;
|
|
129
|
+
const config = ctx.config;
|
|
130
|
+
const resolved = ctx.resolvedProject;
|
|
131
|
+
if (!backend.getTaskDoc || !backend.writeTask) {
|
|
132
|
+
throw new CliError({
|
|
133
|
+
exitCode: 2,
|
|
134
|
+
code: "E_USAGE",
|
|
135
|
+
message: "Configured task backend does not support task docs.",
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
let targetSection = "Findings";
|
|
139
|
+
await applyTaskMutation({
|
|
140
|
+
ctx,
|
|
141
|
+
taskId: opts.taskId,
|
|
142
|
+
build: (current) => {
|
|
143
|
+
const plan = buildStructuredFindingMutationPlan({
|
|
144
|
+
current,
|
|
145
|
+
config,
|
|
146
|
+
observation: opts.observation,
|
|
147
|
+
impact: opts.impact,
|
|
148
|
+
resolution: opts.resolution,
|
|
149
|
+
promote: opts.promote,
|
|
150
|
+
external: opts.external,
|
|
151
|
+
fixability: opts.fixability ?? null,
|
|
152
|
+
incidentScope: opts.incidentScope,
|
|
153
|
+
incidentTags: opts.incidentTags,
|
|
154
|
+
incidentMatch: opts.incidentMatch,
|
|
155
|
+
incidentAdvice: opts.incidentAdvice,
|
|
156
|
+
incidentRule: opts.incidentRule,
|
|
157
|
+
updatedBy,
|
|
158
|
+
});
|
|
159
|
+
if (!plan) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
targetSection = plan.targetSection;
|
|
163
|
+
return {
|
|
164
|
+
intents: plan.intents,
|
|
165
|
+
writeOptions: {
|
|
166
|
+
expectedCurrentText: plan.expectedCurrentText,
|
|
167
|
+
expectedSection: targetSection,
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
const tasksDir = `${resolved.gitRoot}/${config.paths.workflow_dir}`;
|
|
173
|
+
process.stdout.write(`${tasksDir}/${opts.taskId}/README.md\n`);
|
|
174
|
+
process.stderr.write(`${infoMessage(`task findings add outcome=entry-appended section=${targetSection}`)}\n`);
|
|
175
|
+
process.stderr.write(`${infoMessage(renderFindingsAddRegistryNote({
|
|
176
|
+
promote: opts.promote,
|
|
177
|
+
external: opts.external,
|
|
178
|
+
taskId: opts.taskId,
|
|
179
|
+
branchPr: config.workflow_mode === "branch_pr",
|
|
180
|
+
}))}\n`);
|
|
181
|
+
return 0;
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
if (err instanceof CliError)
|
|
185
|
+
throw err;
|
|
186
|
+
throw mapBackendError(err, { command: "task findings add", root: opts.rootOverride ?? null });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -56,5 +56,7 @@ export declare function createTaskCloseCommit(opts: {
|
|
|
56
56
|
baseBranchOverride?: string;
|
|
57
57
|
quiet: boolean;
|
|
58
58
|
closeUnstageOthers?: boolean;
|
|
59
|
+
allowPolicy?: boolean;
|
|
60
|
+
closeRefreshTaskArtifacts?: boolean;
|
|
59
61
|
}): Promise<void>;
|
|
60
62
|
//# sourceMappingURL=finish-shared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finish-shared.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish-shared.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAG/D,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAA6B,YAAY,EAAmB,MAAM,yBAAyB,CAAC;AAWnG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;
|
|
1
|
+
{"version":3,"file":"finish-shared.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish-shared.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAG/D,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAA6B,YAAY,EAAmB,MAAM,yBAAyB,CAAC;AAWnG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AA0CF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,kBAAkB,GAAG,IAAI,CAK5E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,IAAI,CAyCP;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GAAG,IAAI,CAAC;IAC9C,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,2BAA2B,EAAE,OAAO,CAAC;CACtC,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,gBAAgB,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC,CAuDD;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,GAAG,EAAE,cAAc,CAAC;IACpB,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC3C,GAAG,OAAO,CAAC,IAAI,CAAC,CAuEhB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,cAAc,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBhB"}
|
|
@@ -4,6 +4,46 @@ import { cmdCommit } from "../guard/index.js";
|
|
|
4
4
|
import { loadTaskFromContext } from "../shared/task-backend.js";
|
|
5
5
|
import { backendIsLocalFileBackend, getTaskStore, mutateTaskStore } from "../shared/task-store.js";
|
|
6
6
|
import { ensureAgentFilledRequiredDocSections, executeTaskStatusTransitionRequest, ensureVerificationSatisfiedIfRequired, nowIso, resolvePrimaryTag, toStringArray, } from "./shared.js";
|
|
7
|
+
function normalizeCommentBody(value) {
|
|
8
|
+
return typeof value === "string" ? value.trim() : "";
|
|
9
|
+
}
|
|
10
|
+
function commitInfoMatches(current, requested) {
|
|
11
|
+
if (!requested)
|
|
12
|
+
return true;
|
|
13
|
+
const existing = existingCommitInfo(current);
|
|
14
|
+
if (!existing)
|
|
15
|
+
return false;
|
|
16
|
+
return existing.hash === requested.hash && existing.message === requested.message;
|
|
17
|
+
}
|
|
18
|
+
function isIdempotentDoneRetry(opts) {
|
|
19
|
+
if (String(opts.task.status ?? "TODO").toUpperCase() !== "DONE")
|
|
20
|
+
return false;
|
|
21
|
+
const lastComment = opts.task.comments?.at(-1) ?? null;
|
|
22
|
+
const lastEvent = opts.task.events?.at(-1) ?? null;
|
|
23
|
+
if (lastComment?.author !== opts.author)
|
|
24
|
+
return false;
|
|
25
|
+
if (normalizeCommentBody(lastComment.body) !== normalizeCommentBody(opts.body))
|
|
26
|
+
return false;
|
|
27
|
+
if (lastEvent?.type !== "status" || lastEvent.author !== opts.author)
|
|
28
|
+
return false;
|
|
29
|
+
if (String(lastEvent.from ?? "").toUpperCase() !== "DOING")
|
|
30
|
+
return false;
|
|
31
|
+
if (String(lastEvent.to ?? "").toUpperCase() !== "DONE")
|
|
32
|
+
return false;
|
|
33
|
+
if (normalizeCommentBody(lastEvent.note) !== normalizeCommentBody(opts.body))
|
|
34
|
+
return false;
|
|
35
|
+
if (!commitInfoMatches(opts.task, opts.taskCommitInfo))
|
|
36
|
+
return false;
|
|
37
|
+
if (opts.taskId === opts.metaTaskId) {
|
|
38
|
+
if ((opts.task.result_summary ?? "") !== opts.resultSummary)
|
|
39
|
+
return false;
|
|
40
|
+
if ((opts.task.risk_level ?? undefined) !== opts.riskLevel)
|
|
41
|
+
return false;
|
|
42
|
+
if (Boolean(opts.task.breaking) !== opts.breaking)
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
7
47
|
export function existingCommitInfo(task) {
|
|
8
48
|
const hash = typeof task.commit?.hash === "string" ? task.commit.hash.trim() : "";
|
|
9
49
|
if (!hash)
|
|
@@ -120,6 +160,20 @@ export async function writeFinishedTasks(opts) {
|
|
|
120
160
|
resultSummary: opts.resultSummary,
|
|
121
161
|
force: opts.force,
|
|
122
162
|
});
|
|
163
|
+
if (opts.force &&
|
|
164
|
+
isIdempotentDoneRetry({
|
|
165
|
+
task: currentTask,
|
|
166
|
+
author: opts.author,
|
|
167
|
+
body: opts.body,
|
|
168
|
+
resultSummary: opts.resultSummary,
|
|
169
|
+
metaTaskId: opts.metaTaskId,
|
|
170
|
+
taskId,
|
|
171
|
+
riskLevel: opts.riskLevel,
|
|
172
|
+
breaking: opts.breaking,
|
|
173
|
+
taskCommitInfo: opts.taskCommitInfo,
|
|
174
|
+
})) {
|
|
175
|
+
return { intents: [], nextTask: currentTask };
|
|
176
|
+
}
|
|
123
177
|
return await executeTaskStatusTransitionRequest({
|
|
124
178
|
task: currentTask,
|
|
125
179
|
backend: opts.ctx.taskBackend,
|
|
@@ -171,7 +225,7 @@ export async function createTaskCloseCommit(opts) {
|
|
|
171
225
|
autoAllow: false,
|
|
172
226
|
allowTasks: true,
|
|
173
227
|
allowBase: opts.ctx.config.workflow_mode === "branch_pr",
|
|
174
|
-
allowPolicy:
|
|
228
|
+
allowPolicy: opts.allowPolicy === true,
|
|
175
229
|
allowConfig: false,
|
|
176
230
|
allowHooks: false,
|
|
177
231
|
allowCI: false,
|
|
@@ -180,5 +234,6 @@ export async function createTaskCloseCommit(opts) {
|
|
|
180
234
|
closeUnstageOthers: opts.closeUnstageOthers === true,
|
|
181
235
|
closeCheckOnly: false,
|
|
182
236
|
closeStageTaskArtifacts: opts.ctx.config.workflow_mode === "branch_pr",
|
|
237
|
+
closeRefreshTaskArtifacts: opts.closeRefreshTaskArtifacts,
|
|
183
238
|
});
|
|
184
239
|
}
|
|
@@ -28,6 +28,16 @@ export declare function cmdFinish(opts: {
|
|
|
28
28
|
noCloseCommit?: boolean;
|
|
29
29
|
closeUnstageOthers?: boolean;
|
|
30
30
|
baseBranchOverride?: string;
|
|
31
|
+
observation?: string;
|
|
32
|
+
impact?: string;
|
|
33
|
+
resolution?: string;
|
|
34
|
+
localOnly?: boolean;
|
|
35
|
+
repoFixable?: boolean;
|
|
36
|
+
incidentScope?: string;
|
|
37
|
+
incidentTags?: string[];
|
|
38
|
+
incidentMatch?: string[];
|
|
39
|
+
incidentAdvice?: string;
|
|
40
|
+
incidentRule?: string;
|
|
31
41
|
quiet: boolean;
|
|
32
42
|
}): Promise<number>;
|
|
33
43
|
//# sourceMappingURL=finish.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../../src/commands/task/finish.ts"],"names":[],"mappings":"AAYA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAsHpF,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,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0YlB"}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
import { resolveBaseBranch } from "@agentplaneorg/core";
|
|
1
2
|
import { mapBackendError } from "../../cli/error-map.js";
|
|
3
|
+
import { exitCodeForError } from "../../cli/exit-codes.js";
|
|
2
4
|
import { infoMessage, invalidValueMessage, successMessage } from "../../cli/output.js";
|
|
3
5
|
import { CliError } from "../../shared/errors.js";
|
|
4
6
|
import { readFile, rm } from "node:fs/promises";
|
|
5
7
|
import path from "node:path";
|
|
6
8
|
import { ensureActionApproved } from "../shared/approval-requirements.js";
|
|
7
9
|
import { ensureReconciledBeforeMutation } from "../shared/reconcile-check.js";
|
|
10
|
+
import { gitCurrentBranch } from "../shared/git-ops.js";
|
|
8
11
|
import { loadCommandContext } from "../shared/task-backend.js";
|
|
9
12
|
import { backendIsLocalFileBackend, getTaskStore } from "../shared/task-store.js";
|
|
10
|
-
import {
|
|
13
|
+
import { applyTaskMutation } from "../shared/task-mutation.js";
|
|
14
|
+
import { collectTaskIncidents, renderIncidentCollectionPlanOutcome } from "../incidents/shared.js";
|
|
11
15
|
import { createTaskCloseCommit, existingCommitInfo, loadTaskForFinish, writeFinishedTasks, } from "./finish-shared.js";
|
|
16
|
+
import { buildStructuredFindingMutationPlan } from "./findings.js";
|
|
12
17
|
import { defaultCommitEmojiForStatus, enforceStatusCommitPolicy, prepareTaskTransitionComment, readCommitInfo, requireStructuredComment, runTaskTransitionCommentCommit, } from "./shared.js";
|
|
13
18
|
async function clearDirectWorkLockIfMatches(opts) {
|
|
14
19
|
const lockPath = path.join(opts.agentplaneDir, "cache", "direct-work.json");
|
|
@@ -26,11 +31,68 @@ async function clearDirectWorkLockIfMatches(opts) {
|
|
|
26
31
|
// best-effort
|
|
27
32
|
}
|
|
28
33
|
}
|
|
34
|
+
async function ensureFinishRunsOnBaseBranch(opts) {
|
|
35
|
+
if (opts.ctx.config.workflow_mode !== "branch_pr")
|
|
36
|
+
return;
|
|
37
|
+
const baseBranch = await resolveBaseBranch({
|
|
38
|
+
cwd: opts.cwd,
|
|
39
|
+
rootOverride: opts.rootOverride ?? null,
|
|
40
|
+
cliBaseOpt: opts.baseBranchOverride ?? null,
|
|
41
|
+
mode: opts.ctx.config.workflow_mode,
|
|
42
|
+
});
|
|
43
|
+
if (!baseBranch) {
|
|
44
|
+
throw new CliError({
|
|
45
|
+
exitCode: exitCodeForError("E_USAGE"),
|
|
46
|
+
code: "E_USAGE",
|
|
47
|
+
message: "Base branch could not be resolved (use `agentplane branch base set` or --base).",
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const currentBranch = await gitCurrentBranch(opts.ctx.resolvedProject.gitRoot);
|
|
51
|
+
if (currentBranch === baseBranch)
|
|
52
|
+
return;
|
|
53
|
+
throw new CliError({
|
|
54
|
+
exitCode: exitCodeForError("E_GIT"),
|
|
55
|
+
code: "E_GIT",
|
|
56
|
+
message: `finish must run on base branch ${baseBranch} in branch_pr mode ` +
|
|
57
|
+
`(current: ${currentBranch}); integrate first or reconcile from the base checkout.`,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async function appendFinishStructuredFinding(opts) {
|
|
61
|
+
await applyTaskMutation({
|
|
62
|
+
ctx: opts.ctx,
|
|
63
|
+
taskId: opts.taskId,
|
|
64
|
+
build: (current) => {
|
|
65
|
+
const plan = buildStructuredFindingMutationPlan({
|
|
66
|
+
current,
|
|
67
|
+
config: opts.ctx.config,
|
|
68
|
+
observation: opts.finding.observation,
|
|
69
|
+
impact: opts.finding.impact,
|
|
70
|
+
resolution: opts.finding.resolution,
|
|
71
|
+
promote: !opts.finding.localOnly,
|
|
72
|
+
external: !opts.finding.localOnly,
|
|
73
|
+
fixability: opts.finding.repoFixable ? "repo-fixable" : null,
|
|
74
|
+
incidentScope: opts.finding.incidentScope,
|
|
75
|
+
incidentTags: opts.finding.incidentTags,
|
|
76
|
+
incidentMatch: opts.finding.incidentMatch,
|
|
77
|
+
incidentAdvice: opts.finding.incidentAdvice,
|
|
78
|
+
incidentRule: opts.finding.incidentRule,
|
|
79
|
+
updatedBy: opts.author,
|
|
80
|
+
});
|
|
81
|
+
return plan ? { intents: plan.intents } : null;
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
29
85
|
export async function cmdFinish(opts) {
|
|
30
86
|
try {
|
|
31
87
|
const ctx = opts.ctx ??
|
|
32
88
|
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
33
89
|
await ensureReconciledBeforeMutation({ ctx, command: "finish" });
|
|
90
|
+
await ensureFinishRunsOnBaseBranch({
|
|
91
|
+
ctx,
|
|
92
|
+
cwd: opts.cwd,
|
|
93
|
+
rootOverride: opts.rootOverride,
|
|
94
|
+
baseBranchOverride: opts.baseBranchOverride,
|
|
95
|
+
});
|
|
34
96
|
if (opts.force) {
|
|
35
97
|
await ensureActionApproved({
|
|
36
98
|
action: "force_action",
|
|
@@ -140,6 +202,49 @@ export async function cmdFinish(opts) {
|
|
|
140
202
|
const resultSummary = typeof opts.result === "string" ? opts.result.trim() : "";
|
|
141
203
|
const riskLevel = opts.risk;
|
|
142
204
|
const breaking = opts.breaking === true;
|
|
205
|
+
const finishFinding = typeof opts.observation === "string" &&
|
|
206
|
+
typeof opts.impact === "string" &&
|
|
207
|
+
typeof opts.resolution === "string"
|
|
208
|
+
? {
|
|
209
|
+
observation: opts.observation,
|
|
210
|
+
impact: opts.impact,
|
|
211
|
+
resolution: opts.resolution,
|
|
212
|
+
localOnly: opts.localOnly === true,
|
|
213
|
+
repoFixable: opts.repoFixable === true,
|
|
214
|
+
incidentScope: opts.incidentScope,
|
|
215
|
+
incidentTags: opts.incidentTags ?? [],
|
|
216
|
+
incidentMatch: opts.incidentMatch ?? [],
|
|
217
|
+
incidentAdvice: opts.incidentAdvice,
|
|
218
|
+
incidentRule: opts.incidentRule,
|
|
219
|
+
}
|
|
220
|
+
: null;
|
|
221
|
+
if (finishFinding && opts.taskIds.length !== 1) {
|
|
222
|
+
throw new CliError({
|
|
223
|
+
exitCode: 2,
|
|
224
|
+
code: "E_USAGE",
|
|
225
|
+
message: "--observation/--impact/--resolution and incident finding options require exactly one task id",
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
if (finishFinding && primaryTaskId) {
|
|
229
|
+
await loadTaskForFinish({
|
|
230
|
+
ctx,
|
|
231
|
+
store,
|
|
232
|
+
useStore,
|
|
233
|
+
taskId: primaryTaskId,
|
|
234
|
+
taskCount: opts.taskIds.length,
|
|
235
|
+
metaTaskId,
|
|
236
|
+
resultProvided,
|
|
237
|
+
resultSummary,
|
|
238
|
+
force: opts.force,
|
|
239
|
+
capturePrimaryLifecycleMeta: false,
|
|
240
|
+
});
|
|
241
|
+
await appendFinishStructuredFinding({
|
|
242
|
+
ctx,
|
|
243
|
+
taskId: primaryTaskId,
|
|
244
|
+
author: opts.author,
|
|
245
|
+
finding: finishFinding,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
143
248
|
let primaryStatusFrom = null;
|
|
144
249
|
let primaryTag = null;
|
|
145
250
|
const loadedTasks = [];
|
|
@@ -273,7 +378,8 @@ export async function cmdFinish(opts) {
|
|
|
273
378
|
breaking,
|
|
274
379
|
taskCommitInfo,
|
|
275
380
|
});
|
|
276
|
-
|
|
381
|
+
const incidentPlans = [];
|
|
382
|
+
const incidentRegistryPaths = [];
|
|
277
383
|
for (const taskId of opts.taskIds) {
|
|
278
384
|
const loadedTask = loadedTasks.find((candidate) => candidate.taskId === taskId) ?? null;
|
|
279
385
|
const collected = await collectTaskIncidents({
|
|
@@ -282,8 +388,10 @@ export async function cmdFinish(opts) {
|
|
|
282
388
|
task: loadedTask?.task ?? null,
|
|
283
389
|
write: true,
|
|
284
390
|
});
|
|
285
|
-
|
|
391
|
+
incidentPlans.push(collected.plan);
|
|
392
|
+
incidentRegistryPaths.push(collected.registryPaths);
|
|
286
393
|
}
|
|
394
|
+
const promotedIncidents = incidentPlans.reduce((sum, plan) => sum + plan.promotable.length, 0);
|
|
287
395
|
// tasks.json is export-only; generated via `agentplane task export`.
|
|
288
396
|
if (shouldCloseCommit && primaryTaskId) {
|
|
289
397
|
if (!opts.quiet) {
|
|
@@ -297,6 +405,7 @@ export async function cmdFinish(opts) {
|
|
|
297
405
|
baseBranchOverride: opts.baseBranchOverride,
|
|
298
406
|
quiet: opts.quiet,
|
|
299
407
|
closeUnstageOthers: opts.closeCommit === true && opts.closeUnstageOthers === true,
|
|
408
|
+
allowPolicy: promotedIncidents > 0,
|
|
300
409
|
});
|
|
301
410
|
}
|
|
302
411
|
if (ctx.config.workflow_mode === "direct") {
|
|
@@ -306,9 +415,19 @@ export async function cmdFinish(opts) {
|
|
|
306
415
|
});
|
|
307
416
|
}
|
|
308
417
|
if (!opts.quiet) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
418
|
+
const incidentPlan = incidentPlans[0] ?? {
|
|
419
|
+
candidates: [],
|
|
420
|
+
skipped: [],
|
|
421
|
+
promotable: [],
|
|
422
|
+
duplicates: [],
|
|
423
|
+
};
|
|
424
|
+
process.stdout.write(`${infoMessage(renderIncidentCollectionPlanOutcome(incidentPlan, {
|
|
425
|
+
wrote: promotedIncidents > 0,
|
|
426
|
+
context: "finish",
|
|
427
|
+
promotedIds: incidentPlan.promotable.map((item) => item.entry.id),
|
|
428
|
+
registryPaths: incidentRegistryPaths[0] ?? [],
|
|
429
|
+
taskId: opts.taskIds[0] ?? null,
|
|
430
|
+
}))}\n`);
|
|
312
431
|
process.stdout.write(`${successMessage("finished")}\n`);
|
|
313
432
|
}
|
|
314
433
|
return 0;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CommandCtx, CommandSpec } from "../../cli/spec/spec.js";
|
|
2
|
+
import { type CommandContext } from "../shared/task-backend.js";
|
|
3
|
+
type TaskHostedClosePrParsed = {
|
|
4
|
+
taskIds: string[];
|
|
5
|
+
branch: string | null;
|
|
6
|
+
repo: string | null;
|
|
7
|
+
};
|
|
8
|
+
export declare const taskHostedClosePrSpec: CommandSpec<TaskHostedClosePrParsed>;
|
|
9
|
+
export declare function makeRunTaskHostedClosePrHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: TaskHostedClosePrParsed) => Promise<number>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=hosted-close-pr.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-close-pr.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/hosted-close-pr.command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAStE,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAQnC,KAAK,uBAAuB,GAAG;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAgBF,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,uBAAuB,CAoEtE,CAAC;AA4aF,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAChF,KAAK,UAAU,EAAE,GAAG,uBAAuB,KAAG,OAAO,CAAC,MAAM,CAAC,CAsB5E"}
|