agentplane 0.2.25 → 0.3.1
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 +3 -1
- package/assets/AGENTS.md +123 -526
- package/assets/agents/UPGRADER.json +10 -9
- package/assets/framework.manifest.json +112 -7
- package/assets/policy/check-routing.mjs +180 -0
- package/assets/policy/dod.code.md +25 -0
- package/assets/policy/dod.core.md +32 -0
- package/assets/policy/dod.docs.md +32 -0
- package/assets/policy/examples/migration-note.md +6 -0
- package/assets/policy/examples/pr-note.md +16 -0
- package/assets/policy/examples/unit-test-pattern.md +19 -0
- package/assets/policy/governance.md +37 -0
- package/assets/policy/incidents.md +36 -0
- package/assets/policy/security.must.md +7 -0
- package/assets/policy/workflow.branch_pr.md +34 -0
- package/assets/policy/workflow.direct.md +46 -0
- package/assets/policy/workflow.md +9 -0
- package/assets/policy/workflow.release.md +31 -0
- package/assets/policy/workflow.upgrade.md +20 -0
- package/bin/agentplane.js +47 -57
- package/bin/dist-guard.js +124 -0
- package/dist/.build-manifest.json +11 -0
- package/dist/agents/agents-template.d.ts +7 -0
- package/dist/agents/agents-template.d.ts.map +1 -1
- package/dist/agents/agents-template.js +41 -2
- package/dist/backends/task-backend/local-backend.d.ts +2 -0
- package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/local-backend.js +12 -1
- package/dist/backends/task-backend/redmine/mapping.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine/mapping.js +26 -1
- package/dist/backends/task-backend/redmine-backend.d.ts +4 -0
- package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine-backend.js +92 -9
- package/dist/backends/task-backend/shared/types.d.ts +1 -0
- package/dist/backends/task-backend/shared/types.d.ts.map +1 -1
- package/dist/backends/task-index.d.ts.map +1 -1
- package/dist/backends/task-index.js +8 -1
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +39 -17
- package/dist/cli/command-snippets.d.ts +24 -0
- package/dist/cli/command-snippets.d.ts.map +1 -0
- package/dist/cli/command-snippets.js +23 -0
- package/dist/cli/reason-codes.d.ts +9 -0
- package/dist/cli/reason-codes.d.ts.map +1 -0
- package/dist/cli/reason-codes.js +79 -0
- package/dist/cli/recipes-bundled.d.ts +1 -0
- package/dist/cli/recipes-bundled.d.ts.map +1 -1
- package/dist/cli/recipes-bundled.js +4 -1
- 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/command-catalog.js +40 -1
- package/dist/cli/run-cli/commands/config.d.ts +5 -0
- package/dist/cli/run-cli/commands/config.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/config.js +86 -1
- package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core.js +57 -2
- package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/ide.js +8 -3
- package/dist/cli/run-cli/commands/init/recipes.d.ts +5 -1
- package/dist/cli/run-cli/commands/init/recipes.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/recipes.js +24 -4
- package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/ui.js +1 -2
- package/dist/cli/run-cli/commands/init/write-agents.d.ts +2 -0
- package/dist/cli/run-cli/commands/init/write-agents.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-agents.js +24 -5
- package/dist/cli/run-cli/commands/init/write-workflow.d.ts +12 -0
- package/dist/cli/run-cli/commands/init/write-workflow.d.ts.map +1 -0
- package/dist/cli/run-cli/commands/init/write-workflow.js +58 -0
- package/dist/cli/run-cli/commands/init.d.ts +4 -1
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +126 -48
- package/dist/cli/run-cli.d.ts.map +1 -1
- package/dist/cli/run-cli.js +195 -8
- package/dist/commands/backend/sync.command.d.ts.map +1 -1
- package/dist/commands/backend/sync.command.js +7 -6
- package/dist/commands/backend.d.ts.map +1 -1
- package/dist/commands/backend.js +2 -0
- package/dist/commands/doctor.run.d.ts.map +1 -1
- package/dist/commands/doctor.run.js +107 -16
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +12 -6
- package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/install.js +36 -13
- package/dist/commands/recipes/impl/scenario.d.ts.map +1 -1
- package/dist/commands/recipes/impl/scenario.js +25 -0
- package/dist/commands/recipes/impl/types.d.ts +4 -0
- package/dist/commands/recipes/impl/types.d.ts.map +1 -1
- package/dist/commands/release/apply.command.d.ts.map +1 -1
- package/dist/commands/release/apply.command.js +9 -4
- package/dist/commands/release/plan.command.d.ts.map +1 -1
- package/dist/commands/release/plan.command.js +9 -3
- package/dist/commands/scenario/impl/commands.d.ts.map +1 -1
- package/dist/commands/scenario/impl/commands.js +74 -3
- package/dist/commands/scenario/impl/report.d.ts +8 -0
- package/dist/commands/scenario/impl/report.d.ts.map +1 -1
- package/dist/commands/scenario/impl/report.js +1 -0
- package/dist/commands/shared/reconcile-check.d.ts +7 -0
- package/dist/commands/shared/reconcile-check.d.ts.map +1 -0
- package/dist/commands/shared/reconcile-check.js +60 -0
- package/dist/commands/sync.command.d.ts.map +1 -1
- package/dist/commands/sync.command.js +9 -2
- package/dist/commands/task/add.d.ts.map +1 -1
- package/dist/commands/task/add.js +32 -0
- package/dist/commands/task/doc.command.d.ts.map +1 -1
- package/dist/commands/task/doc.command.js +1 -0
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +11 -1
- package/dist/commands/task/list.d.ts.map +1 -1
- package/dist/commands/task/list.js +2 -1
- package/dist/commands/task/list.spec.d.ts.map +1 -1
- package/dist/commands/task/list.spec.js +7 -0
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +41 -4
- package/dist/commands/task/next.d.ts.map +1 -1
- package/dist/commands/task/next.js +2 -1
- package/dist/commands/task/next.spec.d.ts.map +1 -1
- package/dist/commands/task/next.spec.js +7 -0
- package/dist/commands/task/plan.d.ts.map +1 -1
- package/dist/commands/task/plan.js +7 -1
- package/dist/commands/task/search.d.ts.map +1 -1
- package/dist/commands/task/search.js +2 -1
- package/dist/commands/task/search.spec.d.ts.map +1 -1
- package/dist/commands/task/search.spec.js +7 -0
- package/dist/commands/task/shared.d.ts +14 -0
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +58 -1
- package/dist/commands/task/start-ready.js +1 -1
- package/dist/commands/task/verify-record.d.ts.map +1 -1
- package/dist/commands/task/verify-record.js +2 -0
- package/dist/commands/upgrade.command.d.ts.map +1 -1
- package/dist/commands/upgrade.command.js +2 -2
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +263 -294
- package/dist/commands/workflow-build.command.d.ts +8 -0
- package/dist/commands/workflow-build.command.d.ts.map +1 -0
- package/dist/commands/workflow-build.command.js +103 -0
- package/dist/commands/workflow-playbook.command.d.ts +10 -0
- package/dist/commands/workflow-playbook.command.d.ts.map +1 -0
- package/dist/commands/workflow-playbook.command.js +173 -0
- package/dist/commands/workflow-restore.command.d.ts +5 -0
- package/dist/commands/workflow-restore.command.d.ts.map +1 -0
- package/dist/commands/workflow-restore.command.js +30 -0
- package/dist/commands/workflow.command.d.ts +6 -0
- package/dist/commands/workflow.command.d.ts.map +1 -0
- package/dist/commands/workflow.command.js +36 -0
- package/dist/harness/dynamic-tool-contract.d.ts +29 -0
- package/dist/harness/dynamic-tool-contract.d.ts.map +1 -0
- package/dist/harness/dynamic-tool-contract.js +86 -0
- package/dist/harness/hooks-lifecycle.d.ts +27 -0
- package/dist/harness/hooks-lifecycle.d.ts.map +1 -0
- package/dist/harness/hooks-lifecycle.js +67 -0
- package/dist/harness/index.d.ts +9 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +8 -0
- package/dist/harness/reconcile.d.ts +37 -0
- package/dist/harness/reconcile.d.ts.map +1 -0
- package/dist/harness/reconcile.js +42 -0
- package/dist/harness/retry-policy.d.ts +31 -0
- package/dist/harness/retry-policy.d.ts.map +1 -0
- package/dist/harness/retry-policy.js +33 -0
- package/dist/harness/scheduler.d.ts +18 -0
- package/dist/harness/scheduler.d.ts.map +1 -0
- package/dist/harness/scheduler.js +55 -0
- package/dist/harness/state-machine.d.ts +17 -0
- package/dist/harness/state-machine.d.ts.map +1 -0
- package/dist/harness/state-machine.js +70 -0
- package/dist/harness/token-accounting.d.ts +19 -0
- package/dist/harness/token-accounting.d.ts.map +1 -0
- package/dist/harness/token-accounting.js +77 -0
- package/dist/harness/workspace-safety.d.ts +14 -0
- package/dist/harness/workspace-safety.d.ts.map +1 -0
- package/dist/harness/workspace-safety.js +62 -0
- package/dist/recipes/bundled-recipes.d.ts +4 -0
- package/dist/recipes/bundled-recipes.d.ts.map +1 -1
- package/dist/recipes/bundled-recipes.js +11 -0
- package/dist/shared/errors.d.ts +6 -0
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/errors.js +1 -0
- package/dist/shared/policy-gateway.d.ts +15 -0
- package/dist/shared/policy-gateway.d.ts.map +1 -0
- package/dist/shared/policy-gateway.js +49 -0
- package/dist/shared/protected-paths.d.ts.map +1 -1
- package/dist/shared/protected-paths.js +1 -0
- package/dist/shared/runtime-artifacts.d.ts +2 -2
- package/dist/shared/runtime-artifacts.d.ts.map +1 -1
- package/dist/shared/runtime-artifacts.js +4 -0
- package/dist/workflow-runtime/build.d.ts +4 -0
- package/dist/workflow-runtime/build.d.ts.map +1 -0
- package/dist/workflow-runtime/build.js +126 -0
- package/dist/workflow-runtime/enforcement.d.ts +3 -0
- package/dist/workflow-runtime/enforcement.d.ts.map +1 -0
- package/dist/workflow-runtime/enforcement.js +10 -0
- package/dist/workflow-runtime/file-ops.d.ts +11 -0
- package/dist/workflow-runtime/file-ops.d.ts.map +1 -0
- package/dist/workflow-runtime/file-ops.js +248 -0
- package/dist/workflow-runtime/fix.d.ts +9 -0
- package/dist/workflow-runtime/fix.d.ts.map +1 -0
- package/dist/workflow-runtime/fix.js +107 -0
- package/dist/workflow-runtime/index.d.ts +11 -0
- package/dist/workflow-runtime/index.d.ts.map +1 -0
- package/dist/workflow-runtime/index.js +10 -0
- package/dist/workflow-runtime/markdown.d.ts +10 -0
- package/dist/workflow-runtime/markdown.d.ts.map +1 -0
- package/dist/workflow-runtime/markdown.js +147 -0
- package/dist/workflow-runtime/observability.d.ts +12 -0
- package/dist/workflow-runtime/observability.d.ts.map +1 -0
- package/dist/workflow-runtime/observability.js +14 -0
- package/dist/workflow-runtime/paths.d.ts +3 -0
- package/dist/workflow-runtime/paths.d.ts.map +1 -0
- package/dist/workflow-runtime/paths.js +11 -0
- package/dist/workflow-runtime/template.d.ts +7 -0
- package/dist/workflow-runtime/template.d.ts.map +1 -0
- package/dist/workflow-runtime/template.js +94 -0
- package/dist/workflow-runtime/types.d.ts +68 -0
- package/dist/workflow-runtime/types.d.ts.map +1 -0
- package/dist/workflow-runtime/types.js +1 -0
- package/dist/workflow-runtime/validate.d.ts +8 -0
- package/dist/workflow-runtime/validate.d.ts.map +1 -0
- package/dist/workflow-runtime/validate.js +331 -0
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdir, mkdtemp, rm } from "node:fs/promises";
|
|
1
|
+
import { cp, mkdir, mkdtemp, rm } from "node:fs/promises";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { defaultConfig, loadConfig } from "@agentplaneorg/core";
|
|
@@ -8,6 +8,7 @@ import { mapCoreError } from "../../../../cli/error-map.js";
|
|
|
8
8
|
import { exitCodeForError } from "../../../../cli/exit-codes.js";
|
|
9
9
|
import { fileExists, getPathKind } from "../../../../cli/fs-utils.js";
|
|
10
10
|
import { downloadToFile } from "../../../../cli/http.js";
|
|
11
|
+
import { getBundledRecipeEntry, resolveBundledRecipeSourcePath, } from "../../../../recipes/bundled-recipes.js";
|
|
11
12
|
import { CliError } from "../../../../shared/errors.js";
|
|
12
13
|
import { ensureNetworkApproved } from "../../../shared/network-approval.js";
|
|
13
14
|
import { resolvePathFallback } from "../../../shared/path.js";
|
|
@@ -86,7 +87,7 @@ export async function cmdRecipeInstall(opts) {
|
|
|
86
87
|
const filename = path.basename(url.pathname) || "recipe.tar.gz";
|
|
87
88
|
const target = path.join(tempRoot, filename);
|
|
88
89
|
await downloadToFile(latest.url, target);
|
|
89
|
-
return target;
|
|
90
|
+
return { kind: "archive", path: target };
|
|
90
91
|
}
|
|
91
92
|
const resolved = path.resolve(opts.cwd, latest.url);
|
|
92
93
|
if (!(await fileExists(resolved))) {
|
|
@@ -96,11 +97,19 @@ export async function cmdRecipeInstall(opts) {
|
|
|
96
97
|
message: `Recipe archive not found: ${latest.url}`,
|
|
97
98
|
});
|
|
98
99
|
}
|
|
99
|
-
return resolved;
|
|
100
|
+
return { kind: "archive", path: resolved };
|
|
100
101
|
};
|
|
101
102
|
const resolveSourcePath = async (source) => {
|
|
102
|
-
if (source.type === "name")
|
|
103
|
+
if (source.type === "name") {
|
|
104
|
+
const bundledPath = resolveBundledRecipeSourcePath(source.value);
|
|
105
|
+
if (bundledPath && (await fileExists(path.join(bundledPath, "manifest.json")))) {
|
|
106
|
+
const bundledEntry = getBundledRecipeEntry(source.value);
|
|
107
|
+
const bundledVersion = bundledEntry?.versions.at(-1)?.version ?? "unknown";
|
|
108
|
+
sourceLabel = `bundled:${source.value}@${bundledVersion}`;
|
|
109
|
+
return { kind: "directory", path: bundledPath };
|
|
110
|
+
}
|
|
103
111
|
return await resolveFromIndex(source.value);
|
|
112
|
+
}
|
|
104
113
|
if (source.type === "url") {
|
|
105
114
|
await ensureApproved("recipes install downloads a recipe archive");
|
|
106
115
|
const url = new URL(source.value);
|
|
@@ -108,7 +117,7 @@ export async function cmdRecipeInstall(opts) {
|
|
|
108
117
|
const target = path.join(tempRoot, filename);
|
|
109
118
|
sourceLabel = source.value;
|
|
110
119
|
await downloadToFile(source.value, target);
|
|
111
|
-
return target;
|
|
120
|
+
return { kind: "archive", path: target };
|
|
112
121
|
}
|
|
113
122
|
if (source.type === "path") {
|
|
114
123
|
const candidate = await resolvePathFallback(source.value);
|
|
@@ -119,8 +128,13 @@ export async function cmdRecipeInstall(opts) {
|
|
|
119
128
|
message: `Recipe archive not found: ${source.value}`,
|
|
120
129
|
});
|
|
121
130
|
}
|
|
131
|
+
const kind = await getPathKind(candidate);
|
|
132
|
+
if (kind === "dir") {
|
|
133
|
+
sourceLabel = candidate;
|
|
134
|
+
return { kind: "directory", path: candidate };
|
|
135
|
+
}
|
|
122
136
|
sourceLabel = candidate;
|
|
123
|
-
return candidate;
|
|
137
|
+
return { kind: "archive", path: candidate };
|
|
124
138
|
}
|
|
125
139
|
if (isHttpUrl(source.value)) {
|
|
126
140
|
return await resolveSourcePath({ type: "url", value: source.value });
|
|
@@ -131,10 +145,11 @@ export async function cmdRecipeInstall(opts) {
|
|
|
131
145
|
}
|
|
132
146
|
return await resolveSourcePath({ type: "name", value: source.value });
|
|
133
147
|
};
|
|
134
|
-
const
|
|
148
|
+
const sourceInput = await resolveSourcePath(opts.source);
|
|
149
|
+
const sourcePath = sourceInput.path;
|
|
135
150
|
if (!sourceLabel)
|
|
136
151
|
sourceLabel = opts.source.value;
|
|
137
|
-
const actualSha = expectedSha ? await sha256File(sourcePath) : "";
|
|
152
|
+
const actualSha = expectedSha && sourceInput.kind === "archive" ? await sha256File(sourcePath) : "";
|
|
138
153
|
if (expectedSha && actualSha !== expectedSha) {
|
|
139
154
|
throw new CliError({
|
|
140
155
|
exitCode: 3,
|
|
@@ -142,11 +157,19 @@ export async function cmdRecipeInstall(opts) {
|
|
|
142
157
|
message: `Recipe checksum mismatch for ${sourceLabel}`,
|
|
143
158
|
});
|
|
144
159
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
160
|
+
let recipeRoot;
|
|
161
|
+
if (sourceInput.kind === "archive") {
|
|
162
|
+
await extractArchive({
|
|
163
|
+
archivePath: sourcePath,
|
|
164
|
+
destDir: tempRoot,
|
|
165
|
+
});
|
|
166
|
+
recipeRoot = await resolveRecipeRoot(tempRoot);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const stagedRecipeRoot = path.join(tempRoot, "recipe");
|
|
170
|
+
await cp(sourcePath, stagedRecipeRoot, { recursive: true });
|
|
171
|
+
recipeRoot = stagedRecipeRoot;
|
|
172
|
+
}
|
|
150
173
|
const manifest = await readRecipeManifest(path.join(recipeRoot, "manifest.json"));
|
|
151
174
|
const resolvedTags = manifest.tags && manifest.tags.length > 0 ? manifest.tags : normalizeRecipeTags(indexTags);
|
|
152
175
|
const manifestWithTags = resolvedTags.length > 0 ? { ...manifest, tags: resolvedTags } : manifest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenario.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/scenario.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"scenario.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/scenario.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAwD3F,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAG1F;AAED,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACjE,cAAc,EAAE,CAAC,CAAC;IAClB,SAAS,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC/C,CAAC,CAeD;AAED,wBAAsB,4BAA4B,CAChD,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CA+CjC;AAED,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,OAAO,EACZ,UAAU,EAAE,MAAM,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAyB/D"}
|
|
@@ -5,6 +5,30 @@ import { invalidFieldMessage, requiredFieldMessage } from "../../../cli/output.j
|
|
|
5
5
|
import { isRecord } from "../../../shared/guards.js";
|
|
6
6
|
import { RECIPES_SCENARIOS_DIR_NAME, RECIPES_SCENARIOS_INDEX_NAME } from "./constants.js";
|
|
7
7
|
import { normalizeScenarioId } from "./normalize.js";
|
|
8
|
+
function normalizeScenarioEvidence(raw, sourcePath) {
|
|
9
|
+
if (raw === undefined)
|
|
10
|
+
return undefined;
|
|
11
|
+
if (!isRecord(raw)) {
|
|
12
|
+
throw new Error(invalidFieldMessage("scenario.evidence", "object", sourcePath));
|
|
13
|
+
}
|
|
14
|
+
const required = raw.required === true;
|
|
15
|
+
let files = [];
|
|
16
|
+
if (raw.files !== undefined) {
|
|
17
|
+
if (!Array.isArray(raw.files)) {
|
|
18
|
+
throw new Error(invalidFieldMessage("scenario.evidence.files", "string[]", sourcePath));
|
|
19
|
+
}
|
|
20
|
+
files = raw.files
|
|
21
|
+
.map((value) => (typeof value === "string" ? value.trim() : ""))
|
|
22
|
+
.filter(Boolean);
|
|
23
|
+
if (files.length !== raw.files.length) {
|
|
24
|
+
throw new Error(invalidFieldMessage("scenario.evidence.files", "string[]", sourcePath));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (required && files.length === 0) {
|
|
28
|
+
files = ["evidence.json"];
|
|
29
|
+
}
|
|
30
|
+
return { required, files };
|
|
31
|
+
}
|
|
8
32
|
function validateScenarioDefinition(raw, sourcePath) {
|
|
9
33
|
if (!isRecord(raw))
|
|
10
34
|
throw new Error(invalidFieldMessage("scenario", "object", sourcePath));
|
|
@@ -31,6 +55,7 @@ function validateScenarioDefinition(raw, sourcePath) {
|
|
|
31
55
|
goal,
|
|
32
56
|
inputs: raw.inputs,
|
|
33
57
|
outputs: raw.outputs,
|
|
58
|
+
evidence: normalizeScenarioEvidence(raw.evidence, sourcePath),
|
|
34
59
|
steps: raw.steps,
|
|
35
60
|
};
|
|
36
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.command.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAU1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.command.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAU1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AA4VnD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAiF5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CAoL9D,CAAC"}
|
|
@@ -136,7 +136,7 @@ function cleanHookEnv() {
|
|
|
136
136
|
delete env.AGENTPLANE_AGENT_ID;
|
|
137
137
|
return env;
|
|
138
138
|
}
|
|
139
|
-
async function validateReleaseNotes(notesPath) {
|
|
139
|
+
async function validateReleaseNotes(notesPath, minBullets) {
|
|
140
140
|
const content = await readFile(notesPath, "utf8");
|
|
141
141
|
if (!/release\s+notes/i.test(content)) {
|
|
142
142
|
throw new CliError({
|
|
@@ -146,11 +146,11 @@ async function validateReleaseNotes(notesPath) {
|
|
|
146
146
|
});
|
|
147
147
|
}
|
|
148
148
|
const bulletCount = content.split(/\r?\n/u).filter((line) => /^\s*[-*]\s+\S+/u.test(line)).length;
|
|
149
|
-
if (bulletCount <
|
|
149
|
+
if (bulletCount < minBullets) {
|
|
150
150
|
throw new CliError({
|
|
151
151
|
exitCode: exitCodeForError("E_VALIDATION"),
|
|
152
152
|
code: "E_VALIDATION",
|
|
153
|
-
message: `Release notes must include at least
|
|
153
|
+
message: `Release notes must include at least ${minBullets} bullet points in ${notesPath}.`,
|
|
154
154
|
});
|
|
155
155
|
}
|
|
156
156
|
if (/[\u0400-\u04FF]/u.test(content)) {
|
|
@@ -383,6 +383,11 @@ export const runReleaseApply = async (ctx, flags) => {
|
|
|
383
383
|
});
|
|
384
384
|
}
|
|
385
385
|
const plan = parseVersionPlan(await readJsonFile(versionJsonPath));
|
|
386
|
+
const changesJsonPath = path.join(planDir, "changes.json");
|
|
387
|
+
const changes = (await fileExists(changesJsonPath))
|
|
388
|
+
? await readJsonFile(changesJsonPath)
|
|
389
|
+
: [];
|
|
390
|
+
const minBullets = Math.max(1, Array.isArray(changes) ? changes.length : 0);
|
|
386
391
|
if ((plan.bump === "minor" || plan.bump === "major") && flags.yes !== true) {
|
|
387
392
|
throw usageError({
|
|
388
393
|
spec: releaseApplySpec,
|
|
@@ -406,7 +411,7 @@ export const runReleaseApply = async (ctx, flags) => {
|
|
|
406
411
|
"Write this file using a DOCS agent before applying the release.",
|
|
407
412
|
});
|
|
408
413
|
}
|
|
409
|
-
await validateReleaseNotes(notesPath);
|
|
414
|
+
await validateReleaseNotes(notesPath, minBullets);
|
|
410
415
|
const corePkgPath = path.join(gitRoot, "packages", "core", "package.json");
|
|
411
416
|
const agentplanePkgPath = path.join(gitRoot, "packages", "agentplane", "package.json");
|
|
412
417
|
const [coreVersion, agentplaneVersion, coreDependencyVersion] = await Promise.all([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/plan.command.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1E,KAAK,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"plan.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/plan.command.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1E,KAAK,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AA4IjD,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CA4E1D,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,iBAAiB,CAqE5D,CAAC"}
|
|
@@ -92,6 +92,9 @@ function changesMarkdown(changes) {
|
|
|
92
92
|
.join("\n")
|
|
93
93
|
.trim() + "\n");
|
|
94
94
|
}
|
|
95
|
+
function requiredBulletCount(changeCount) {
|
|
96
|
+
return Math.max(1, changeCount);
|
|
97
|
+
}
|
|
95
98
|
function releaseInstructions(opts) {
|
|
96
99
|
return (`# Release plan\n\n` +
|
|
97
100
|
`## Target\n\n` +
|
|
@@ -103,8 +106,10 @@ function releaseInstructions(opts) {
|
|
|
103
106
|
`## Agent task: write release notes\n\n` +
|
|
104
107
|
`Write English release notes as \`docs/releases/${opts.nextTag}.md\`.\n\n` +
|
|
105
108
|
`Rules:\n` +
|
|
106
|
-
`- Use human-readable bullets focused on outcomes and user-facing improvements.\n` +
|
|
107
|
-
`-
|
|
109
|
+
`- Use detailed, human-readable bullets focused on outcomes and user-facing improvements.\n` +
|
|
110
|
+
`- Cover all listed differences from \`changes.md\`; do not omit commits.\n` +
|
|
111
|
+
`- Keep one concrete bullet per listed change in plain language.\n` +
|
|
112
|
+
`- Write at least ${opts.minBullets} bullet points.\n` +
|
|
108
113
|
`- Do not include Cyrillic.\n` +
|
|
109
114
|
`- Use \`docs/releases/TEMPLATE.md\` as the structure.\n\n` +
|
|
110
115
|
`Inputs:\n` +
|
|
@@ -216,13 +221,14 @@ export const runReleasePlan = async (ctx, flags) => {
|
|
|
216
221
|
const nextVersion = bumpVersion(coreVersion, flags.bump);
|
|
217
222
|
const nextTag = `v${nextVersion}`;
|
|
218
223
|
const changes = await listChanges(gitRoot, prevTag);
|
|
224
|
+
const minBullets = requiredBulletCount(changes.length);
|
|
219
225
|
const runId = new Date().toISOString().replaceAll(":", "-").replaceAll(".", "-");
|
|
220
226
|
const baseDir = path.join(gitRoot, ".agentplane", ".release", "plan", runId);
|
|
221
227
|
await mkdir(baseDir, { recursive: true });
|
|
222
228
|
await writeFile(path.join(baseDir, "version.json"), JSON.stringify({ prevTag, prevVersion: coreVersion, nextTag, nextVersion, bump: flags.bump }, null, 2) + "\n", "utf8");
|
|
223
229
|
await writeFile(path.join(baseDir, "changes.json"), JSON.stringify(changes, null, 2) + "\n", "utf8");
|
|
224
230
|
await writeFile(path.join(baseDir, "changes.md"), changesMarkdown(changes), "utf8");
|
|
225
|
-
await writeFile(path.join(baseDir, "instructions.md"), releaseInstructions({ nextTag, prevTag, bump: flags.bump }), "utf8");
|
|
231
|
+
await writeFile(path.join(baseDir, "instructions.md"), releaseInstructions({ nextTag, prevTag, bump: flags.bump, minBullets }), "utf8");
|
|
226
232
|
process.stdout.write(`Release plan written: ${path.relative(gitRoot, baseDir)}\n`);
|
|
227
233
|
process.stdout.write(`Next tag: ${nextTag}\n`);
|
|
228
234
|
process.stdout.write(`Hint: Create a DOCS task to write docs/releases/${nextTag}.md based on this plan.\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/commands/scenario/impl/commands.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAgCtE,KAAK,iBAAiB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzC,KAAK,oBAAoB,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EAAE,GACb,oBAAoB,CAQtB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoDlB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/commands/scenario/impl/commands.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAgCtE,KAAK,iBAAiB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzC,KAAK,oBAAoB,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EAAE,GACb,oBAAoB,CAQtB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoDlB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2ElB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,OAAO,EAAE,iBAAiB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA2ChE;AAkCD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC;CACvD,GAAG,OAAO,CAAC,MAAM,CAAC,CAiQlB"}
|
|
@@ -125,6 +125,12 @@ export async function cmdScenarioInfoParsed(opts) {
|
|
|
125
125
|
process.stdout.write(`Goal: ${scenario.goal}\n`);
|
|
126
126
|
process.stdout.write(`Inputs: ${JSON.stringify(scenario.inputs, null, 2)}\n`);
|
|
127
127
|
process.stdout.write(`Outputs: ${JSON.stringify(scenario.outputs, null, 2)}\n`);
|
|
128
|
+
if (scenario.evidence?.required) {
|
|
129
|
+
process.stdout.write(`Evidence: required (${normalizeExpectedEvidenceFiles(scenario.evidence.files).join(", ")})\n`);
|
|
130
|
+
}
|
|
131
|
+
else if (scenario.evidence?.files && scenario.evidence.files.length > 0) {
|
|
132
|
+
process.stdout.write(`Evidence: optional (${scenario.evidence.files.join(", ")})\n`);
|
|
133
|
+
}
|
|
128
134
|
process.stdout.write("Steps:\n");
|
|
129
135
|
let stepIndex = 1;
|
|
130
136
|
for (const step of scenario.steps) {
|
|
@@ -185,6 +191,33 @@ export async function executeRecipeTool(opts) {
|
|
|
185
191
|
function sanitizeRunId(value) {
|
|
186
192
|
return value.replaceAll(/[^a-zA-Z0-9._-]/g, "_");
|
|
187
193
|
}
|
|
194
|
+
function normalizeExpectedEvidenceFiles(raw) {
|
|
195
|
+
if (!raw || raw.length === 0)
|
|
196
|
+
return ["evidence.json"];
|
|
197
|
+
const unique = [];
|
|
198
|
+
for (const value of raw) {
|
|
199
|
+
const file = value.trim();
|
|
200
|
+
if (!file)
|
|
201
|
+
continue;
|
|
202
|
+
if (unique.includes(file))
|
|
203
|
+
continue;
|
|
204
|
+
unique.push(file);
|
|
205
|
+
}
|
|
206
|
+
return unique.length > 0 ? unique : ["evidence.json"];
|
|
207
|
+
}
|
|
208
|
+
async function collectStepEvidenceFiles(stepDir, expectedFiles) {
|
|
209
|
+
const present = [];
|
|
210
|
+
const missing = [];
|
|
211
|
+
for (const file of expectedFiles) {
|
|
212
|
+
if (await fileExists(path.join(stepDir, file))) {
|
|
213
|
+
present.push(file);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
missing.push(file);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return { present, missing };
|
|
220
|
+
}
|
|
188
221
|
export async function cmdScenarioRunParsed(opts) {
|
|
189
222
|
const resolved = opts.resolved ??
|
|
190
223
|
(await resolveProject({
|
|
@@ -241,6 +274,13 @@ export async function cmdScenarioRunParsed(opts) {
|
|
|
241
274
|
.replaceAll(".", "-")}-${sanitizeRunId(scenarioId)}`;
|
|
242
275
|
const runDir = path.join(runsRoot, runId);
|
|
243
276
|
await mkdir(runDir, { recursive: true });
|
|
277
|
+
const evidenceRequired = scenario.evidence?.required === true;
|
|
278
|
+
const expectedEvidenceFiles = evidenceRequired
|
|
279
|
+
? normalizeExpectedEvidenceFiles(scenario.evidence?.files)
|
|
280
|
+
: normalizeExpectedEvidenceFiles(scenario.evidence?.files && scenario.evidence.files.length > 0
|
|
281
|
+
? scenario.evidence.files
|
|
282
|
+
: undefined);
|
|
283
|
+
const missingEvidenceSteps = [];
|
|
244
284
|
const stepsMeta = [];
|
|
245
285
|
const stepsReport = [];
|
|
246
286
|
for (let index = 0; index < scenario.steps.length; index++) {
|
|
@@ -299,6 +339,11 @@ export async function cmdScenarioRunParsed(opts) {
|
|
|
299
339
|
const durationMs = Date.now() - startedAt;
|
|
300
340
|
await atomicWriteFile(path.join(stepDir, "stdout.log"), result.stdout, "utf8");
|
|
301
341
|
await atomicWriteFile(path.join(stepDir, "stderr.log"), result.stderr, "utf8");
|
|
342
|
+
const stepEvidence = await collectStepEvidenceFiles(stepDir, expectedEvidenceFiles);
|
|
343
|
+
const missingRequiredEvidence = evidenceRequired ? stepEvidence.missing : [];
|
|
344
|
+
if (missingRequiredEvidence.length > 0) {
|
|
345
|
+
missingEvidenceSteps.push(index + 1);
|
|
346
|
+
}
|
|
302
347
|
stepsMeta.push({
|
|
303
348
|
tool: step.tool,
|
|
304
349
|
runtime,
|
|
@@ -313,10 +358,12 @@ export async function cmdScenarioRunParsed(opts) {
|
|
|
313
358
|
entrypoint,
|
|
314
359
|
args: redactArgs(step.args),
|
|
315
360
|
env_keys: stepEnvKeys,
|
|
361
|
+
evidence_files: stepEvidence.present,
|
|
362
|
+
missing_evidence_files: missingRequiredEvidence.length > 0 ? missingRequiredEvidence : undefined,
|
|
316
363
|
exit_code: result.exitCode,
|
|
317
364
|
duration_ms: durationMs,
|
|
318
365
|
});
|
|
319
|
-
if (result.exitCode !== 0) {
|
|
366
|
+
if (result.exitCode !== 0 || missingRequiredEvidence.length > 0) {
|
|
320
367
|
const gitSummary = await getGitDiffSummary(resolved.gitRoot);
|
|
321
368
|
await writeScenarioReport({
|
|
322
369
|
runDir,
|
|
@@ -326,18 +373,32 @@ export async function cmdScenarioRunParsed(opts) {
|
|
|
326
373
|
startedAt: runStartedAt,
|
|
327
374
|
status: "failed",
|
|
328
375
|
steps: stepsReport,
|
|
376
|
+
evidence: {
|
|
377
|
+
required: evidenceRequired,
|
|
378
|
+
expected_files: expectedEvidenceFiles,
|
|
379
|
+
missing_steps: missingEvidenceSteps,
|
|
380
|
+
},
|
|
329
381
|
gitSummary,
|
|
330
382
|
});
|
|
331
383
|
await atomicWriteFile(path.join(runDir, "meta.json"), `${JSON.stringify({
|
|
332
384
|
recipe: recipeId,
|
|
333
385
|
scenario: scenarioId,
|
|
334
386
|
run_id: runId,
|
|
387
|
+
evidence: {
|
|
388
|
+
required: evidenceRequired,
|
|
389
|
+
expected_files: expectedEvidenceFiles,
|
|
390
|
+
missing_steps: missingEvidenceSteps,
|
|
391
|
+
},
|
|
335
392
|
steps: stepsMeta,
|
|
336
393
|
}, null, 2)}\n`, "utf8");
|
|
394
|
+
const reason = missingRequiredEvidence.length > 0
|
|
395
|
+
? `Scenario step missing required evidence: ${step.tool} (${missingRequiredEvidence.join(", ")})`
|
|
396
|
+
: `Scenario step failed: ${step.tool}`;
|
|
397
|
+
const stepExitCode = result.exitCode === 0 ? 1 : result.exitCode;
|
|
337
398
|
throw new CliError({
|
|
338
|
-
exitCode:
|
|
399
|
+
exitCode: stepExitCode,
|
|
339
400
|
code: "E_INTERNAL",
|
|
340
|
-
message:
|
|
401
|
+
message: reason,
|
|
341
402
|
});
|
|
342
403
|
}
|
|
343
404
|
}
|
|
@@ -350,12 +411,22 @@ export async function cmdScenarioRunParsed(opts) {
|
|
|
350
411
|
startedAt: runStartedAt,
|
|
351
412
|
status: "success",
|
|
352
413
|
steps: stepsReport,
|
|
414
|
+
evidence: {
|
|
415
|
+
required: evidenceRequired,
|
|
416
|
+
expected_files: expectedEvidenceFiles,
|
|
417
|
+
missing_steps: missingEvidenceSteps,
|
|
418
|
+
},
|
|
353
419
|
gitSummary,
|
|
354
420
|
});
|
|
355
421
|
await atomicWriteFile(path.join(runDir, "meta.json"), `${JSON.stringify({
|
|
356
422
|
recipe: recipeId,
|
|
357
423
|
scenario: scenarioId,
|
|
358
424
|
run_id: runId,
|
|
425
|
+
evidence: {
|
|
426
|
+
required: evidenceRequired,
|
|
427
|
+
expected_files: expectedEvidenceFiles,
|
|
428
|
+
missing_steps: missingEvidenceSteps,
|
|
429
|
+
},
|
|
359
430
|
steps: stepsMeta,
|
|
360
431
|
}, null, 2)}\n`, "utf8");
|
|
361
432
|
process.stdout.write(`Run artifacts: ${path.relative(resolved.gitRoot, runDir)}\n`);
|
|
@@ -10,9 +10,16 @@ export type ScenarioRunReportStep = {
|
|
|
10
10
|
entrypoint: string;
|
|
11
11
|
args: string[];
|
|
12
12
|
env_keys: string[];
|
|
13
|
+
evidence_files: string[];
|
|
14
|
+
missing_evidence_files?: string[];
|
|
13
15
|
exit_code: number;
|
|
14
16
|
duration_ms: number;
|
|
15
17
|
};
|
|
18
|
+
type ScenarioRunEvidenceSummary = {
|
|
19
|
+
required: boolean;
|
|
20
|
+
expected_files: string[];
|
|
21
|
+
missing_steps: number[];
|
|
22
|
+
};
|
|
16
23
|
export declare function redactArgs(args: string[]): string[];
|
|
17
24
|
export declare function getGitDiffSummary(cwd: string): Promise<ScenarioRunGitSummary | undefined>;
|
|
18
25
|
export declare function collectScenarioEnvKeys(stepEnv: Record<string, string> | undefined): string[];
|
|
@@ -24,6 +31,7 @@ export declare function writeScenarioReport(opts: {
|
|
|
24
31
|
startedAt: string;
|
|
25
32
|
status: "success" | "failed";
|
|
26
33
|
steps: ScenarioRunReportStep[];
|
|
34
|
+
evidence: ScenarioRunEvidenceSummary;
|
|
27
35
|
gitSummary?: ScenarioRunGitSummary;
|
|
28
36
|
}): Promise<void>;
|
|
29
37
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../../src/commands/scenario/impl/report.ts"],"names":[],"mappings":"AAYA,KAAK,qBAAqB,GAAG;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../../src/commands/scenario/impl/report.ts"],"names":[],"mappings":"AAYA,KAAK,qBAAqB,GAAG;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AA4BF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAmBnD;AASD,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAwB/F;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,EAAE,CAU5F;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,QAAQ,EAAE,0BAA0B,CAAC;IACrC,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhB"}
|
|
@@ -93,6 +93,7 @@ export async function writeScenarioReport(opts) {
|
|
|
93
93
|
ended_at: new Date().toISOString(),
|
|
94
94
|
status: opts.status,
|
|
95
95
|
steps: opts.steps,
|
|
96
|
+
evidence: opts.evidence,
|
|
96
97
|
git: opts.gitSummary,
|
|
97
98
|
};
|
|
98
99
|
await atomicWriteFile(path.join(opts.runDir, SCENARIO_REPORT_NAME), `${JSON.stringify(report, null, 2)}\n`, "utf8");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile-check.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/reconcile-check.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAgBvE,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,GAAG,EAAE,cAAc,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CA4ChB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { exitCodeForError } from "../../cli/exit-codes.js";
|
|
2
|
+
import { CliError } from "../../shared/errors.js";
|
|
3
|
+
import { listTasksMemo } from "./task-backend.js";
|
|
4
|
+
function compactError(err) {
|
|
5
|
+
if (err instanceof Error) {
|
|
6
|
+
const text = err.message.trim();
|
|
7
|
+
return text.length > 0 ? text : err.name;
|
|
8
|
+
}
|
|
9
|
+
return String(err);
|
|
10
|
+
}
|
|
11
|
+
function summarizeWarnings(warnings) {
|
|
12
|
+
const preview = warnings.slice(0, 3).join("; ");
|
|
13
|
+
const suffix = warnings.length > 3 ? `; +${warnings.length - 3} more` : "";
|
|
14
|
+
return `skipped ${warnings.length} task files during scan (${preview}${suffix})`;
|
|
15
|
+
}
|
|
16
|
+
export async function ensureReconciledBeforeMutation(opts) {
|
|
17
|
+
try {
|
|
18
|
+
await opts.ctx.git.statusChangedPaths();
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
throw new CliError({
|
|
22
|
+
exitCode: exitCodeForError("E_GIT"),
|
|
23
|
+
code: "E_GIT",
|
|
24
|
+
message: `reconcile check failed: cannot inspect git status (${compactError(err)})`,
|
|
25
|
+
context: {
|
|
26
|
+
command: opts.command,
|
|
27
|
+
reason_code: "reconcile_git_state_unreadable",
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (opts.strictTaskScan === false)
|
|
32
|
+
return;
|
|
33
|
+
try {
|
|
34
|
+
await listTasksMemo(opts.ctx);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
throw new CliError({
|
|
38
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
39
|
+
code: "E_VALIDATION",
|
|
40
|
+
message: `reconcile check failed: task scan error (${compactError(err)})`,
|
|
41
|
+
context: {
|
|
42
|
+
command: opts.command,
|
|
43
|
+
reason_code: "reconcile_task_scan_failed",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const warnings = opts.ctx.taskBackend.getLastListWarnings?.() ?? [];
|
|
48
|
+
if (warnings.length === 0)
|
|
49
|
+
return;
|
|
50
|
+
throw new CliError({
|
|
51
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
52
|
+
code: "E_VALIDATION",
|
|
53
|
+
message: `reconcile check failed: ${summarizeWarnings(warnings)}`,
|
|
54
|
+
context: {
|
|
55
|
+
command: opts.command,
|
|
56
|
+
reason_code: "reconcile_task_scan_incomplete",
|
|
57
|
+
warning_count: warnings.length,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.command.d.ts","sourceRoot":"","sources":["../../src/commands/sync.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.command.d.ts","sourceRoot":"","sources":["../../src/commands/sync.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE9D,eAAO,MAAM,QAAQ,EAAE,WAAW,CAAC,UAAU,CAmD5C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACnE,KAAK,UAAU,EAAE,GAAG,UAAU,KAAG,OAAO,CAAC,MAAM,CAAC,CAS/D"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { COMMAND_SNIPPETS } from "../cli/command-snippets.js";
|
|
1
2
|
import { cmdSyncParsed } from "./backend.js";
|
|
2
3
|
export const syncSpec = {
|
|
3
4
|
id: ["sync"],
|
|
@@ -33,8 +34,14 @@ export const syncSpec = {
|
|
|
33
34
|
{ kind: "boolean", name: "quiet", default: false, description: "Reduce output noise." },
|
|
34
35
|
],
|
|
35
36
|
examples: [
|
|
36
|
-
{
|
|
37
|
-
|
|
37
|
+
{
|
|
38
|
+
cmd: COMMAND_SNIPPETS.sync.pullConfigured,
|
|
39
|
+
why: "Pull from backend (configured backend id).",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
cmd: COMMAND_SNIPPETS.sync.pushRedmineExplicitWithYes,
|
|
43
|
+
why: "Push to redmine backend.",
|
|
44
|
+
},
|
|
38
45
|
],
|
|
39
46
|
parse: (raw) => ({
|
|
40
47
|
backendId: raw.args.id ? String(raw.args.id) : null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/commands/task/add.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/commands/task/add.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAoCpF,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,OAAO,CAAC,MAAM,CAAC,CA6DlB"}
|
|
@@ -2,6 +2,33 @@ import { mapBackendError } from "../../cli/error-map.js";
|
|
|
2
2
|
import { CliError } from "../../shared/errors.js";
|
|
3
3
|
import { loadCommandContext } from "../shared/task-backend.js";
|
|
4
4
|
import { dedupeStrings, normalizeTaskStatus, nowIso } from "./shared.js";
|
|
5
|
+
import { ensureDocSections, setMarkdownSection } from "@agentplaneorg/core";
|
|
6
|
+
function defaultTaskDoc(opts) {
|
|
7
|
+
const baseDoc = ensureDocSections("", opts.requiredSections);
|
|
8
|
+
const summary = `${opts.title}\n\n${opts.description}`;
|
|
9
|
+
const scope = [
|
|
10
|
+
`- In scope: ${opts.description}.`,
|
|
11
|
+
`- Out of scope: unrelated refactors not required for "${opts.title}".`,
|
|
12
|
+
].join("\n");
|
|
13
|
+
const plan = [
|
|
14
|
+
`1. Implement the change for "${opts.title}".`,
|
|
15
|
+
"2. Run required checks and capture verification evidence.",
|
|
16
|
+
"3. Finalize task notes and finish with traceable commit metadata.",
|
|
17
|
+
].join("\n");
|
|
18
|
+
const risks = [
|
|
19
|
+
"- Risk: hidden regressions in touched paths.",
|
|
20
|
+
"- Mitigation: run required checks before finish and record evidence.",
|
|
21
|
+
].join("\n");
|
|
22
|
+
const rollback = [
|
|
23
|
+
"- Revert task-related commit(s).",
|
|
24
|
+
"- Re-run required checks to confirm rollback safety.",
|
|
25
|
+
].join("\n");
|
|
26
|
+
const withSummary = setMarkdownSection(baseDoc, "Summary", summary);
|
|
27
|
+
const withScope = setMarkdownSection(withSummary, "Scope", scope);
|
|
28
|
+
const withPlan = setMarkdownSection(withScope, "Plan", plan);
|
|
29
|
+
const withRisks = setMarkdownSection(withPlan, "Risks", risks);
|
|
30
|
+
return setMarkdownSection(withRisks, "Rollback Plan", rollback);
|
|
31
|
+
}
|
|
5
32
|
export async function cmdTaskAdd(opts) {
|
|
6
33
|
try {
|
|
7
34
|
const ctx = opts.ctx ??
|
|
@@ -39,6 +66,11 @@ export async function cmdTaskAdd(opts) {
|
|
|
39
66
|
doc_updated_at: nowIso(),
|
|
40
67
|
doc_updated_by: docUpdatedBy,
|
|
41
68
|
id_source: "explicit",
|
|
69
|
+
doc: defaultTaskDoc({
|
|
70
|
+
requiredSections: ctx.config.tasks.doc.required_sections,
|
|
71
|
+
title: opts.title,
|
|
72
|
+
description: opts.description,
|
|
73
|
+
}),
|
|
42
74
|
}));
|
|
43
75
|
if (ctx.taskBackend.writeTasks) {
|
|
44
76
|
await ctx.taskBackend.writeTasks(tasks);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doc.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/doc.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtE,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"doc.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/doc.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtE,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAelD,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAK9E"}
|
|
@@ -6,6 +6,7 @@ export const taskDocSpec = {
|
|
|
6
6
|
synopsis: [
|
|
7
7
|
"agentplane task doc show <task-id> [--section <name>] [--quiet]",
|
|
8
8
|
"agentplane task doc set <task-id> --section <name> (--text <text> | --file <path>) [--updated-by <id>]",
|
|
9
|
+
"agentplane task doc set <task-id> --section Summary --file ./task-readme.md # if payload contains multiple known ## headings, apply as full-doc update",
|
|
9
10
|
],
|
|
10
11
|
args: [{ name: "subcommand", required: false, valueHint: "<show|set>" }],
|
|
11
12
|
parse: (raw) => {
|