agentplane 0.3.4 → 0.3.6
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 +220 -790
- package/dist/adapters/task-backend/task-backend-adapter.d.ts +1 -1
- package/dist/adapters/task-backend/task-backend-adapter.d.ts.map +1 -1
- package/dist/adapters/task-backend/task-backend-adapter.js +5 -2
- package/dist/backends/task-backend/local-backend.d.ts +13 -0
- package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/local-backend.js +17 -0
- package/dist/backends/task-backend/redmine-backend.d.ts +18 -0
- package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine-backend.js +35 -25
- package/dist/backends/task-backend/shared/types.d.ts +20 -0
- 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/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 +78 -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.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 +138 -6
- package/dist/commands/commit.spec.d.ts.map +1 -1
- package/dist/commands/commit.spec.js +2 -2
- 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 +4 -1
- package/dist/commands/doctor/workspace.d.ts.map +1 -1
- package/dist/commands/doctor/workspace.js +87 -4
- package/dist/commands/doctor.run.d.ts.map +1 -1
- package/dist/commands/doctor.run.js +8 -1
- package/dist/commands/guard/commit.command.js +1 -1
- package/dist/commands/guard/impl/allow.d.ts +5 -0
- package/dist/commands/guard/impl/allow.d.ts.map +1 -1
- package/dist/commands/guard/impl/allow.js +15 -10
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +137 -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/git-context.d.ts +1 -0
- package/dist/commands/shared/git-context.d.ts.map +1 -1
- package/dist/commands/shared/git-context.js +4 -0
- 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 +5 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +24 -0
- package/dist/commands/shared/task-store.d.ts +32 -1
- package/dist/commands/shared/task-store.d.ts.map +1 -1
- package/dist/commands/shared/task-store.js +166 -42
- package/dist/commands/task/block.d.ts.map +1 -1
- package/dist/commands/task/block.js +46 -29
- 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 +76 -0
- package/dist/commands/task/comment.d.ts.map +1 -1
- package/dist/commands/task/comment.js +35 -17
- 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 +123 -71
- package/dist/commands/task/export.d.ts.map +1 -1
- package/dist/commands/task/export.js +4 -4
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +141 -78
- package/dist/commands/task/migrate-doc.d.ts.map +1 -1
- package/dist/commands/task/migrate-doc.js +15 -11
- 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 +190 -93
- 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 +40 -3
- 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 +7 -0
- package/dist/commands/task/shared/transitions.d.ts +0 -2
- package/dist/commands/task/shared/transitions.d.ts.map +1 -1
- package/dist/commands/task/shared/transitions.js +0 -6
- package/dist/commands/task/shared.d.ts +2 -2
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +2 -2
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +88 -63
- 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 +119 -140
- 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/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 +13 -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 +1 -1
- 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 +7 -0
- package/dist/shared/protected-paths.d.ts.map +1 -1
- package/dist/shared/protected-paths.js +26 -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
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileExists, getPathKind } from "../../../cli/fs-utils.js";
|
|
4
|
+
import { invalidFieldMessage, missingFileMessage } from "../../../cli/output.js";
|
|
5
|
+
import { isRecord } from "../../../shared/guards.js";
|
|
6
|
+
import { writeJsonStableIfChanged } from "../../../shared/write-if-changed.js";
|
|
7
|
+
import { readRecipeManifest } from "./manifest.js";
|
|
8
|
+
import { normalizeRecipeTags } from "./normalize.js";
|
|
9
|
+
import { resolveProjectInstalledRecipeDir, resolveProjectRecipeInstallMetaPath, resolveProjectRecipesDir, } from "./paths.js";
|
|
10
|
+
function validateRecipeInstallMetadata(raw) {
|
|
11
|
+
if (!isRecord(raw))
|
|
12
|
+
throw new Error(invalidFieldMessage("recipe install metadata", "object"));
|
|
13
|
+
const id = typeof raw.id === "string" ? raw.id.trim() : "";
|
|
14
|
+
const version = typeof raw.version === "string" ? raw.version.trim() : "";
|
|
15
|
+
const source = typeof raw.source === "string" ? raw.source.trim() : "";
|
|
16
|
+
const installedAt = typeof raw.installed_at === "string" ? raw.installed_at.trim() : "";
|
|
17
|
+
const installMode = raw.install_mode === undefined || raw.install_mode === "project-local"
|
|
18
|
+
? raw.install_mode
|
|
19
|
+
: null;
|
|
20
|
+
if (raw.schema_version !== 1) {
|
|
21
|
+
throw new Error(invalidFieldMessage("recipe install metadata.schema_version", "1"));
|
|
22
|
+
}
|
|
23
|
+
if (!id || !version || !source || !installedAt) {
|
|
24
|
+
throw new Error(invalidFieldMessage("recipe install metadata", "id, version, source, installed_at"));
|
|
25
|
+
}
|
|
26
|
+
if (installMode === null) {
|
|
27
|
+
throw new Error(invalidFieldMessage("recipe install metadata.install_mode", '"project-local"'));
|
|
28
|
+
}
|
|
29
|
+
const tags = normalizeRecipeTags(raw.tags ?? []);
|
|
30
|
+
return {
|
|
31
|
+
schema_version: 1,
|
|
32
|
+
id,
|
|
33
|
+
version,
|
|
34
|
+
source,
|
|
35
|
+
installed_at: installedAt,
|
|
36
|
+
tags,
|
|
37
|
+
install_mode: installMode,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function sortInstalledRecipes(entries) {
|
|
41
|
+
return [...entries].toSorted((a, b) => a.id.localeCompare(b.id));
|
|
42
|
+
}
|
|
43
|
+
export async function readRecipeInstallMetadata(filePath) {
|
|
44
|
+
try {
|
|
45
|
+
const raw = JSON.parse(await readFile(filePath, "utf8"));
|
|
46
|
+
return validateRecipeInstallMetadata(raw);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
const code = err?.code;
|
|
50
|
+
if (code === "ENOENT")
|
|
51
|
+
return null;
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export async function writeRecipeInstallMetadata(filePath, metadata) {
|
|
56
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
57
|
+
await writeJsonStableIfChanged(filePath, metadata);
|
|
58
|
+
}
|
|
59
|
+
export async function readProjectInstalledRecipes(opts) {
|
|
60
|
+
const recipesDir = resolveProjectRecipesDir(opts);
|
|
61
|
+
if ((await getPathKind(recipesDir)) !== "dir") {
|
|
62
|
+
return { schema_version: 1, updated_at: "", recipes: [] };
|
|
63
|
+
}
|
|
64
|
+
const entries = [];
|
|
65
|
+
const dirs = await readdir(recipesDir, { withFileTypes: true });
|
|
66
|
+
for (const dirent of dirs) {
|
|
67
|
+
if (!dirent.isDirectory())
|
|
68
|
+
continue;
|
|
69
|
+
const recipeDir = resolveProjectInstalledRecipeDir(opts, dirent.name);
|
|
70
|
+
const manifestPath = path.join(recipeDir, "manifest.json");
|
|
71
|
+
if (!(await fileExists(manifestPath))) {
|
|
72
|
+
throw new Error(missingFileMessage("installed recipe manifest", manifestPath));
|
|
73
|
+
}
|
|
74
|
+
const manifest = await readRecipeManifest(manifestPath);
|
|
75
|
+
if (manifest.id !== dirent.name) {
|
|
76
|
+
throw new Error(invalidFieldMessage(`installed recipe directory ${dirent.name}`, `manifest.id=${dirent.name}`));
|
|
77
|
+
}
|
|
78
|
+
const metadata = await readRecipeInstallMetadata(resolveProjectRecipeInstallMetaPath(opts, dirent.name));
|
|
79
|
+
if (metadata && (metadata.id !== manifest.id || metadata.version !== manifest.version)) {
|
|
80
|
+
throw new Error(invalidFieldMessage(`recipe install metadata ${dirent.name}`, "id/version matching manifest"));
|
|
81
|
+
}
|
|
82
|
+
entries.push({
|
|
83
|
+
id: manifest.id,
|
|
84
|
+
version: manifest.version,
|
|
85
|
+
source: metadata?.source ?? "project-local",
|
|
86
|
+
installed_at: metadata?.installed_at ?? "",
|
|
87
|
+
tags: normalizeRecipeTags(metadata?.tags ?? manifest.tags ?? []),
|
|
88
|
+
manifest,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
const sorted = sortInstalledRecipes(entries);
|
|
92
|
+
const updatedAt = sorted
|
|
93
|
+
.map((entry) => entry.installed_at)
|
|
94
|
+
.filter(Boolean)
|
|
95
|
+
.toSorted()
|
|
96
|
+
.at(-1);
|
|
97
|
+
return {
|
|
98
|
+
schema_version: 1,
|
|
99
|
+
updated_at: updatedAt ?? "",
|
|
100
|
+
recipes: sorted,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ResolvedProject } from "@agentplaneorg/core";
|
|
2
|
+
import type { RecipeCompatibility, RecipeResolverCompatibility, RecipeResolverContext, RecipeScenarioDescriptor, ResolveRecipeScenarioSelectionFlags, ResolvedRecipeRunProfile, ResolvedRecipeScenario, ResolvedRecipeScenarioSelection } from "./types.js";
|
|
3
|
+
export declare function buildRecipeResolverContext(opts: {
|
|
4
|
+
project: ResolvedProject;
|
|
5
|
+
}): Promise<RecipeResolverContext>;
|
|
6
|
+
export declare function resolveRecipeCompatibility(opts: {
|
|
7
|
+
compatibility?: RecipeCompatibility;
|
|
8
|
+
context: RecipeResolverContext;
|
|
9
|
+
}): RecipeResolverCompatibility;
|
|
10
|
+
export declare function normalizeResolvedRecipeRunProfile(scenario: RecipeScenarioDescriptor): ResolvedRecipeRunProfile;
|
|
11
|
+
export declare function listResolvedRecipeScenarios(opts: {
|
|
12
|
+
project: ResolvedProject;
|
|
13
|
+
recipeId?: string;
|
|
14
|
+
includeIncompatible?: boolean;
|
|
15
|
+
}): Promise<ResolvedRecipeScenario[]>;
|
|
16
|
+
export declare function resolveRecipeScenarioSelection(opts: {
|
|
17
|
+
project: ResolvedProject;
|
|
18
|
+
flags: ResolveRecipeScenarioSelectionFlags;
|
|
19
|
+
}): Promise<ResolvedRecipeScenarioSelection>;
|
|
20
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAS3D,OAAO,KAAK,EAEV,mBAAmB,EACnB,2BAA2B,EAE3B,qBAAqB,EAErB,wBAAwB,EACxB,mCAAmC,EACnC,wBAAwB,EACxB,sBAAsB,EACtB,+BAA+B,EAChC,MAAM,YAAY,CAAC;AAsBpB,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,OAAO,EAAE,eAAe,CAAC;CAC1B,GAAG,OAAO,CAAC,qBAAqB,CAAC,CASjC;AAYD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,OAAO,EAAE,qBAAqB,CAAC;CAChC,GAAG,2BAA2B,CAkG9B;AAED,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,wBAAwB,GACjC,wBAAwB,CAmB1B;AA6BD,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAsBpC;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,mCAAmC,CAAC;CAC5C,GAAG,OAAO,CAAC,+BAA+B,CAAC,CA2D3C"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileExists } from "../../../cli/fs-utils.js";
|
|
3
|
+
import { getVersion } from "../../../meta/version.js";
|
|
4
|
+
import { dedupeStrings } from "../../../shared/strings.js";
|
|
5
|
+
import { compareVersions } from "../../../shared/version-compare.js";
|
|
6
|
+
import { resolveProjectInstalledRecipeDir } from "./paths.js";
|
|
7
|
+
import { readProjectInstalledRecipes } from "./project-installed-recipes.js";
|
|
8
|
+
const SUPPORTED_MANIFEST_API_VERSION = "1";
|
|
9
|
+
const SUPPORTED_SCENARIO_API_VERSION = "1";
|
|
10
|
+
const SUPPORTED_RUNTIME_API_VERSION = "1";
|
|
11
|
+
async function detectProjectRepoTypes(project) {
|
|
12
|
+
const repoTypes = ["generic"];
|
|
13
|
+
const checks = [
|
|
14
|
+
["package.json", "node"],
|
|
15
|
+
["pyproject.toml", "python"],
|
|
16
|
+
["go.mod", "go"],
|
|
17
|
+
["Cargo.toml", "rust"],
|
|
18
|
+
];
|
|
19
|
+
for (const [relativePath, repoType] of checks) {
|
|
20
|
+
if (await fileExists(path.join(project.gitRoot, relativePath))) {
|
|
21
|
+
repoTypes.push(repoType);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return dedupeStrings(repoTypes).toSorted();
|
|
25
|
+
}
|
|
26
|
+
export async function buildRecipeResolverContext(opts) {
|
|
27
|
+
return {
|
|
28
|
+
agentplane_version: getVersion(),
|
|
29
|
+
manifest_api_version: SUPPORTED_MANIFEST_API_VERSION,
|
|
30
|
+
scenario_api_version: SUPPORTED_SCENARIO_API_VERSION,
|
|
31
|
+
runtime_api_version: SUPPORTED_RUNTIME_API_VERSION,
|
|
32
|
+
platform: process.platform,
|
|
33
|
+
repo_types: await detectProjectRepoTypes(opts.project),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function pushCompatibilityFailure(failures, field, expected, actual, reason) {
|
|
37
|
+
failures.push({ field, expected, actual, reason });
|
|
38
|
+
}
|
|
39
|
+
export function resolveRecipeCompatibility(opts) {
|
|
40
|
+
const reasons = [];
|
|
41
|
+
const failures = [];
|
|
42
|
+
const compatibility = opts.compatibility;
|
|
43
|
+
const context = opts.context;
|
|
44
|
+
if (!compatibility) {
|
|
45
|
+
reasons.push("recipe compatibility is unconstrained");
|
|
46
|
+
return { ok: true, reasons, failures };
|
|
47
|
+
}
|
|
48
|
+
if (compatibility.min_agentplane_version) {
|
|
49
|
+
if (compareVersions(context.agentplane_version, compatibility.min_agentplane_version) < 0) {
|
|
50
|
+
pushCompatibilityFailure(failures, "min_agentplane_version", compatibility.min_agentplane_version, context.agentplane_version, `agentplane ${context.agentplane_version} is older than required ${compatibility.min_agentplane_version}`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
reasons.push(`agentplane ${context.agentplane_version} satisfies min ${compatibility.min_agentplane_version}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const versionChecks = [
|
|
57
|
+
{
|
|
58
|
+
field: "manifest_api_version",
|
|
59
|
+
expected: compatibility.manifest_api_version,
|
|
60
|
+
actual: context.manifest_api_version,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
field: "scenario_api_version",
|
|
64
|
+
expected: compatibility.scenario_api_version,
|
|
65
|
+
actual: context.scenario_api_version,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
field: "runtime_api_version",
|
|
69
|
+
expected: compatibility.runtime_api_version,
|
|
70
|
+
actual: context.runtime_api_version,
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
for (const check of versionChecks) {
|
|
74
|
+
if (check.expected === undefined)
|
|
75
|
+
continue;
|
|
76
|
+
if (check.expected === check.actual) {
|
|
77
|
+
reasons.push(`${check.field}=${check.actual}`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
pushCompatibilityFailure(failures, check.field, check.expected, check.actual, `${check.field} requires ${check.expected}, active runtime exposes ${check.actual}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (compatibility.platforms && compatibility.platforms.length > 0) {
|
|
84
|
+
if (compatibility.platforms.includes(context.platform)) {
|
|
85
|
+
reasons.push(`platform ${context.platform} is supported`);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
pushCompatibilityFailure(failures, "platforms", compatibility.platforms, context.platform, `platform ${context.platform} is not supported by recipe`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (compatibility.repo_types && compatibility.repo_types.length > 0) {
|
|
92
|
+
const matched = compatibility.repo_types.filter((repoType) => context.repo_types.includes(repoType));
|
|
93
|
+
if (matched.length > 0) {
|
|
94
|
+
reasons.push(`repo types matched: ${matched.join(", ")}`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
pushCompatibilityFailure(failures, "repo_types", compatibility.repo_types, context.repo_types, `project repo types ${context.repo_types.join(", ")} do not match recipe requirements`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { ok: failures.length === 0, reasons, failures };
|
|
101
|
+
}
|
|
102
|
+
export function normalizeResolvedRecipeRunProfile(scenario) {
|
|
103
|
+
const declaredProfile = scenario.run_profile;
|
|
104
|
+
const permissions = dedupeStrings([...scenario.permissions]).toSorted();
|
|
105
|
+
const network = declaredProfile.network ?? permissions.includes("network");
|
|
106
|
+
return {
|
|
107
|
+
mode: declaredProfile.mode,
|
|
108
|
+
sandbox: declaredProfile.sandbox,
|
|
109
|
+
network,
|
|
110
|
+
requires_human_approval: declaredProfile.requires_human_approval ?? false,
|
|
111
|
+
writes_artifacts_to: dedupeStrings(declaredProfile.writes_artifacts_to ?? []).toSorted(),
|
|
112
|
+
expected_exit_contract: declaredProfile.expected_exit_contract,
|
|
113
|
+
permissions,
|
|
114
|
+
agents_involved: dedupeStrings([...scenario.agents_involved]).toSorted(),
|
|
115
|
+
skills_used: dedupeStrings([...scenario.skills_used]).toSorted(),
|
|
116
|
+
tools_used: dedupeStrings([...scenario.tools_used]).toSorted(),
|
|
117
|
+
required_inputs: dedupeStrings([...scenario.required_inputs]).toSorted(),
|
|
118
|
+
outputs: dedupeStrings([...scenario.outputs]).toSorted(),
|
|
119
|
+
artifacts: dedupeStrings([...scenario.artifacts]).toSorted(),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function toResolvedRecipeScenarios(opts) {
|
|
123
|
+
const recipeDir = resolveProjectInstalledRecipeDir(opts.project, opts.entry.id);
|
|
124
|
+
return opts.entry.manifest.scenarios
|
|
125
|
+
.map((scenario) => ({
|
|
126
|
+
recipe_id: opts.entry.id,
|
|
127
|
+
recipe_version: opts.entry.version,
|
|
128
|
+
recipe_name: opts.entry.manifest.name,
|
|
129
|
+
recipe_summary: opts.entry.manifest.summary,
|
|
130
|
+
recipe_tags: [...opts.entry.tags].toSorted(),
|
|
131
|
+
recipe_dir: recipeDir,
|
|
132
|
+
scenario_id: scenario.id,
|
|
133
|
+
scenario_name: scenario.name,
|
|
134
|
+
scenario_summary: scenario.summary,
|
|
135
|
+
scenario_description: scenario.description,
|
|
136
|
+
use_when: [...scenario.use_when],
|
|
137
|
+
avoid_when: [...(scenario.avoid_when ?? [])],
|
|
138
|
+
scenario_file: path.join(recipeDir, scenario.file),
|
|
139
|
+
compatibility: opts.compatibility,
|
|
140
|
+
run_profile: normalizeResolvedRecipeRunProfile(scenario),
|
|
141
|
+
}))
|
|
142
|
+
.toSorted((left, right) => left.scenario_id.localeCompare(right.scenario_id));
|
|
143
|
+
}
|
|
144
|
+
export async function listResolvedRecipeScenarios(opts) {
|
|
145
|
+
const [context, installed] = await Promise.all([
|
|
146
|
+
buildRecipeResolverContext({ project: opts.project }),
|
|
147
|
+
readProjectInstalledRecipes(opts.project),
|
|
148
|
+
]);
|
|
149
|
+
const results = [];
|
|
150
|
+
for (const entry of installed.recipes) {
|
|
151
|
+
if (opts.recipeId && entry.id !== opts.recipeId)
|
|
152
|
+
continue;
|
|
153
|
+
const compatibility = resolveRecipeCompatibility({
|
|
154
|
+
compatibility: entry.manifest.compatibility,
|
|
155
|
+
context,
|
|
156
|
+
});
|
|
157
|
+
if (!opts.includeIncompatible && !compatibility.ok)
|
|
158
|
+
continue;
|
|
159
|
+
results.push(...toResolvedRecipeScenarios({ project: opts.project, entry, compatibility }));
|
|
160
|
+
}
|
|
161
|
+
return results.toSorted((left, right) => {
|
|
162
|
+
const byRecipe = left.recipe_id.localeCompare(right.recipe_id);
|
|
163
|
+
if (byRecipe !== 0)
|
|
164
|
+
return byRecipe;
|
|
165
|
+
return left.scenario_id.localeCompare(right.scenario_id);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
export async function resolveRecipeScenarioSelection(opts) {
|
|
169
|
+
const requiredTags = dedupeStrings(opts.flags.tags ?? []).toSorted();
|
|
170
|
+
const availableInputs = dedupeStrings(opts.flags.available_inputs ?? []).toSorted();
|
|
171
|
+
const candidates = await listResolvedRecipeScenarios({
|
|
172
|
+
project: opts.project,
|
|
173
|
+
recipeId: opts.flags.recipeId,
|
|
174
|
+
includeIncompatible: opts.flags.includeIncompatible,
|
|
175
|
+
});
|
|
176
|
+
const matches = [];
|
|
177
|
+
for (const candidate of candidates) {
|
|
178
|
+
if (opts.flags.scenarioId && candidate.scenario_id !== opts.flags.scenarioId)
|
|
179
|
+
continue;
|
|
180
|
+
if (opts.flags.mode && candidate.run_profile.mode !== opts.flags.mode)
|
|
181
|
+
continue;
|
|
182
|
+
if (requiredTags.some((tag) => !candidate.recipe_tags.includes(tag))) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (availableInputs.length > 0 &&
|
|
186
|
+
candidate.run_profile.required_inputs.some((input) => !availableInputs.includes(input))) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const selectionReasons = [];
|
|
190
|
+
if (candidate.compatibility.ok)
|
|
191
|
+
selectionReasons.push("recipe compatibility satisfied");
|
|
192
|
+
if (opts.flags.recipeId)
|
|
193
|
+
selectionReasons.push(`matches requested recipe: ${opts.flags.recipeId}`);
|
|
194
|
+
if (opts.flags.scenarioId) {
|
|
195
|
+
selectionReasons.push(`matches requested scenario: ${opts.flags.scenarioId}`);
|
|
196
|
+
}
|
|
197
|
+
if (requiredTags.length > 0) {
|
|
198
|
+
selectionReasons.push(`matches required tags: ${requiredTags.join(", ")}`);
|
|
199
|
+
}
|
|
200
|
+
if (opts.flags.mode)
|
|
201
|
+
selectionReasons.push(`matches requested mode: ${opts.flags.mode}`);
|
|
202
|
+
if (availableInputs.length > 0 && candidate.run_profile.required_inputs.length > 0) {
|
|
203
|
+
selectionReasons.push(`required inputs satisfied: ${candidate.run_profile.required_inputs.join(", ")}`);
|
|
204
|
+
}
|
|
205
|
+
matches.push({
|
|
206
|
+
...candidate,
|
|
207
|
+
selection_reasons: selectionReasons,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
if (matches.length === 0) {
|
|
211
|
+
const requestedRecipe = opts.flags.recipeId ? ` recipe=${opts.flags.recipeId}` : "";
|
|
212
|
+
const requestedScenario = opts.flags.scenarioId ? ` scenario=${opts.flags.scenarioId}` : "";
|
|
213
|
+
throw new Error(`No recipe scenario matches the requested selection.${requestedRecipe}${requestedScenario}`);
|
|
214
|
+
}
|
|
215
|
+
if (matches.length > 1) {
|
|
216
|
+
const labels = matches.map((match) => `${match.recipe_id}:${match.scenario_id}`).join(", ");
|
|
217
|
+
throw new Error(`Scenario selection is ambiguous: ${labels}`);
|
|
218
|
+
}
|
|
219
|
+
return matches[0];
|
|
220
|
+
}
|
|
@@ -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;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,
|
|
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,CA6EjC;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"}
|
|
@@ -81,7 +81,46 @@ export async function readScenarioIndex(filePath) {
|
|
|
81
81
|
return { schema_version: 1, scenarios };
|
|
82
82
|
}
|
|
83
83
|
export async function collectRecipeScenarioDetails(recipeDir, manifest) {
|
|
84
|
+
const manifestScenarios = manifest.scenarios ?? [];
|
|
84
85
|
const scenariosDir = path.join(recipeDir, RECIPES_SCENARIOS_DIR_NAME);
|
|
86
|
+
if (manifestScenarios.length > 0) {
|
|
87
|
+
const details = manifestScenarios.map((scenario) => ({
|
|
88
|
+
id: scenario.id,
|
|
89
|
+
name: scenario.name,
|
|
90
|
+
summary: scenario.summary,
|
|
91
|
+
description: scenario.description,
|
|
92
|
+
use_when: scenario.use_when,
|
|
93
|
+
avoid_when: scenario.avoid_when,
|
|
94
|
+
required_inputs: scenario.required_inputs,
|
|
95
|
+
outputs: scenario.outputs,
|
|
96
|
+
permissions: scenario.permissions,
|
|
97
|
+
artifacts: scenario.artifacts,
|
|
98
|
+
agents_involved: scenario.agents_involved,
|
|
99
|
+
skills_used: scenario.skills_used,
|
|
100
|
+
tools_used: scenario.tools_used,
|
|
101
|
+
run_profile: scenario.run_profile,
|
|
102
|
+
file: scenario.file,
|
|
103
|
+
source: "manifest",
|
|
104
|
+
}));
|
|
105
|
+
if ((await getPathKind(scenariosDir)) === "dir") {
|
|
106
|
+
const files = await readdir(scenariosDir);
|
|
107
|
+
const jsonFiles = files.filter((file) => file.toLowerCase().endsWith(".json")).toSorted();
|
|
108
|
+
for (const file of jsonFiles) {
|
|
109
|
+
const scenario = await readScenarioDefinition(path.join(scenariosDir, file));
|
|
110
|
+
const detail = details.find((entry) => entry.id === scenario.id);
|
|
111
|
+
if (!detail)
|
|
112
|
+
continue;
|
|
113
|
+
detail.description ??= scenario.description;
|
|
114
|
+
detail.goal = scenario.goal;
|
|
115
|
+
detail.inputs = scenario.inputs;
|
|
116
|
+
detail.steps = scenario.steps;
|
|
117
|
+
detail.outputs = detail.outputs ?? scenario.outputs;
|
|
118
|
+
detail.evidence = scenario.evidence;
|
|
119
|
+
detail.source = "definition";
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return details.toSorted((a, b) => a.id.localeCompare(b.id));
|
|
123
|
+
}
|
|
85
124
|
if ((await getPathKind(scenariosDir)) === "dir") {
|
|
86
125
|
const files = await readdir(scenariosDir);
|
|
87
126
|
const jsonFiles = files.filter((file) => file.toLowerCase().endsWith(".json")).toSorted();
|
|
@@ -95,6 +134,7 @@ export async function collectRecipeScenarioDetails(recipeDir, manifest) {
|
|
|
95
134
|
goal: scenario.goal,
|
|
96
135
|
inputs: scenario.inputs,
|
|
97
136
|
outputs: scenario.outputs,
|
|
137
|
+
evidence: scenario.evidence,
|
|
98
138
|
steps: scenario.steps,
|
|
99
139
|
source: "definition",
|
|
100
140
|
});
|
|
@@ -112,17 +152,6 @@ export async function collectRecipeScenarioDetails(recipeDir, manifest) {
|
|
|
112
152
|
}))
|
|
113
153
|
.toSorted((a, b) => a.id.localeCompare(b.id));
|
|
114
154
|
}
|
|
115
|
-
const manifestScenarios = manifest.scenarios ?? [];
|
|
116
|
-
if (manifestScenarios.length > 0) {
|
|
117
|
-
return manifestScenarios
|
|
118
|
-
.map((scenario) => ({
|
|
119
|
-
id: scenario?.id ?? "",
|
|
120
|
-
summary: scenario?.summary,
|
|
121
|
-
source: "manifest",
|
|
122
|
-
}))
|
|
123
|
-
.filter((scenario) => scenario.id)
|
|
124
|
-
.toSorted((a, b) => a.id.localeCompare(b.id));
|
|
125
|
-
}
|
|
126
155
|
return [];
|
|
127
156
|
}
|
|
128
157
|
export function normalizeScenarioToolStep(raw, sourcePath) {
|
|
@@ -1,3 +1,122 @@
|
|
|
1
|
+
export type RecipeCompatibility = {
|
|
2
|
+
min_agentplane_version?: string;
|
|
3
|
+
manifest_api_version?: string;
|
|
4
|
+
scenario_api_version?: string;
|
|
5
|
+
runtime_api_version?: string;
|
|
6
|
+
platforms?: string[];
|
|
7
|
+
repo_types?: string[];
|
|
8
|
+
};
|
|
9
|
+
export type RecipeRunProfile = {
|
|
10
|
+
mode: string;
|
|
11
|
+
sandbox?: string;
|
|
12
|
+
network?: boolean;
|
|
13
|
+
requires_human_approval?: boolean;
|
|
14
|
+
writes_artifacts_to?: string[];
|
|
15
|
+
expected_exit_contract?: string;
|
|
16
|
+
};
|
|
17
|
+
export type RecipeSkillDefinition = {
|
|
18
|
+
id: string;
|
|
19
|
+
summary: string;
|
|
20
|
+
kind: string;
|
|
21
|
+
file: string;
|
|
22
|
+
};
|
|
23
|
+
export type RecipeToolDefinition = {
|
|
24
|
+
id: string;
|
|
25
|
+
summary: string;
|
|
26
|
+
runtime: "node" | "bash";
|
|
27
|
+
entrypoint: string;
|
|
28
|
+
permissions?: string[];
|
|
29
|
+
timeout_ms?: number;
|
|
30
|
+
cwd_policy?: string;
|
|
31
|
+
};
|
|
32
|
+
export type RecipeAgentDefinition = {
|
|
33
|
+
id: string;
|
|
34
|
+
display_name: string;
|
|
35
|
+
role: string;
|
|
36
|
+
summary: string;
|
|
37
|
+
skills?: string[];
|
|
38
|
+
tools?: string[];
|
|
39
|
+
file: string;
|
|
40
|
+
};
|
|
41
|
+
export type RecipeScenarioDescriptor = {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
summary: string;
|
|
45
|
+
description?: string;
|
|
46
|
+
use_when: string[];
|
|
47
|
+
avoid_when?: string[];
|
|
48
|
+
required_inputs: string[];
|
|
49
|
+
outputs: string[];
|
|
50
|
+
permissions: string[];
|
|
51
|
+
artifacts: string[];
|
|
52
|
+
agents_involved: string[];
|
|
53
|
+
skills_used: string[];
|
|
54
|
+
tools_used: string[];
|
|
55
|
+
run_profile: RecipeRunProfile;
|
|
56
|
+
file: string;
|
|
57
|
+
};
|
|
58
|
+
export type RecipeResolverContext = {
|
|
59
|
+
agentplane_version: string;
|
|
60
|
+
manifest_api_version: "1";
|
|
61
|
+
scenario_api_version: "1";
|
|
62
|
+
runtime_api_version: "1";
|
|
63
|
+
platform: string;
|
|
64
|
+
repo_types: string[];
|
|
65
|
+
};
|
|
66
|
+
export type RecipeResolverCompatibilityFailure = {
|
|
67
|
+
field: "min_agentplane_version" | "manifest_api_version" | "scenario_api_version" | "runtime_api_version" | "platforms" | "repo_types";
|
|
68
|
+
expected: string | string[];
|
|
69
|
+
actual: string | string[] | null;
|
|
70
|
+
reason: string;
|
|
71
|
+
};
|
|
72
|
+
export type RecipeResolverCompatibility = {
|
|
73
|
+
ok: boolean;
|
|
74
|
+
reasons: string[];
|
|
75
|
+
failures: RecipeResolverCompatibilityFailure[];
|
|
76
|
+
};
|
|
77
|
+
export type ResolvedRecipeRunProfile = {
|
|
78
|
+
mode: string;
|
|
79
|
+
sandbox?: string;
|
|
80
|
+
network: boolean;
|
|
81
|
+
requires_human_approval: boolean;
|
|
82
|
+
writes_artifacts_to: string[];
|
|
83
|
+
expected_exit_contract?: string;
|
|
84
|
+
permissions: string[];
|
|
85
|
+
agents_involved: string[];
|
|
86
|
+
skills_used: string[];
|
|
87
|
+
tools_used: string[];
|
|
88
|
+
required_inputs: string[];
|
|
89
|
+
outputs: string[];
|
|
90
|
+
artifacts: string[];
|
|
91
|
+
};
|
|
92
|
+
export type ResolvedRecipeScenario = {
|
|
93
|
+
recipe_id: string;
|
|
94
|
+
recipe_version: string;
|
|
95
|
+
recipe_name: string;
|
|
96
|
+
recipe_summary: string;
|
|
97
|
+
recipe_tags: string[];
|
|
98
|
+
recipe_dir: string;
|
|
99
|
+
scenario_id: string;
|
|
100
|
+
scenario_name: string;
|
|
101
|
+
scenario_summary: string;
|
|
102
|
+
scenario_description?: string;
|
|
103
|
+
use_when: string[];
|
|
104
|
+
avoid_when: string[];
|
|
105
|
+
scenario_file: string;
|
|
106
|
+
compatibility: RecipeResolverCompatibility;
|
|
107
|
+
run_profile: ResolvedRecipeRunProfile;
|
|
108
|
+
};
|
|
109
|
+
export type ResolveRecipeScenarioSelectionFlags = {
|
|
110
|
+
recipeId?: string;
|
|
111
|
+
scenarioId?: string;
|
|
112
|
+
tags?: string[];
|
|
113
|
+
mode?: string;
|
|
114
|
+
available_inputs?: string[];
|
|
115
|
+
includeIncompatible?: boolean;
|
|
116
|
+
};
|
|
117
|
+
export type ResolvedRecipeScenarioSelection = ResolvedRecipeScenario & {
|
|
118
|
+
selection_reasons: string[];
|
|
119
|
+
};
|
|
1
120
|
export type RecipeManifest = {
|
|
2
121
|
schema_version: "1";
|
|
3
122
|
id: string;
|
|
@@ -6,24 +125,22 @@ export type RecipeManifest = {
|
|
|
6
125
|
summary: string;
|
|
7
126
|
description: string;
|
|
8
127
|
tags?: string[];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
tools?: {
|
|
15
|
-
id?: string;
|
|
16
|
-
summary?: string;
|
|
17
|
-
runtime?: "node" | "bash";
|
|
18
|
-
entrypoint?: string;
|
|
19
|
-
permissions?: string[];
|
|
20
|
-
}[];
|
|
21
|
-
scenarios?: {
|
|
22
|
-
id?: string;
|
|
23
|
-
summary?: string;
|
|
24
|
-
}[];
|
|
128
|
+
compatibility?: RecipeCompatibility;
|
|
129
|
+
skills?: RecipeSkillDefinition[];
|
|
130
|
+
agents?: RecipeAgentDefinition[];
|
|
131
|
+
tools?: RecipeToolDefinition[];
|
|
132
|
+
scenarios: RecipeScenarioDescriptor[];
|
|
25
133
|
};
|
|
26
134
|
export type RecipeConflictMode = "fail" | "rename" | "overwrite";
|
|
135
|
+
export type RecipeInstallMetadata = {
|
|
136
|
+
schema_version: 1;
|
|
137
|
+
id: string;
|
|
138
|
+
version: string;
|
|
139
|
+
source: string;
|
|
140
|
+
installed_at: string;
|
|
141
|
+
tags?: string[];
|
|
142
|
+
install_mode?: "project-local";
|
|
143
|
+
};
|
|
27
144
|
export type InstalledRecipeEntry = {
|
|
28
145
|
id: string;
|
|
29
146
|
version: string;
|
|
@@ -53,11 +170,23 @@ export type ScenarioDefinition = {
|
|
|
53
170
|
};
|
|
54
171
|
export type RecipeScenarioDetail = {
|
|
55
172
|
id: string;
|
|
173
|
+
name?: string;
|
|
56
174
|
summary?: string;
|
|
57
175
|
description?: string;
|
|
176
|
+
use_when?: string[];
|
|
177
|
+
avoid_when?: string[];
|
|
178
|
+
required_inputs?: string[];
|
|
179
|
+
permissions?: string[];
|
|
180
|
+
artifacts?: string[];
|
|
181
|
+
agents_involved?: string[];
|
|
182
|
+
skills_used?: string[];
|
|
183
|
+
tools_used?: string[];
|
|
184
|
+
run_profile?: RecipeRunProfile;
|
|
58
185
|
goal?: string;
|
|
59
186
|
inputs?: unknown;
|
|
60
187
|
outputs?: unknown;
|
|
188
|
+
evidence?: ScenarioDefinition["evidence"];
|
|
189
|
+
file?: string;
|
|
61
190
|
steps?: unknown[];
|
|
62
191
|
source: "definition" | "index" | "manifest";
|
|
63
192
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,
|
|
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":"install.spec.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/install.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAE7E,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,UAAU,EAAE,kBAAkB,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"install.spec.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/install.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAE7E,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,UAAU,EAAE,kBAAkB,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,CA6IhE,CAAC"}
|
|
@@ -60,7 +60,7 @@ export const recipesInstallSpec = {
|
|
|
60
60
|
valueHint: "<fail|rename|overwrite>",
|
|
61
61
|
choices: ["fail", "rename", "overwrite"],
|
|
62
62
|
default: "fail",
|
|
63
|
-
description: "
|
|
63
|
+
description: "Deprecated compatibility no-op; recipe installs stay self-contained.",
|
|
64
64
|
},
|
|
65
65
|
],
|
|
66
66
|
validateRaw: (raw) => {
|
|
@@ -130,11 +130,12 @@ export const recipesInstallSpec = {
|
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
cmd: "agentplane recipes install viewer --on-conflict overwrite",
|
|
133
|
-
why: "
|
|
133
|
+
why: "Compatibility-only flag; ignored by self-contained recipe installs.",
|
|
134
134
|
},
|
|
135
135
|
],
|
|
136
136
|
notes: [
|
|
137
137
|
"Auto mode resolution matches v0.1.9: URL if http(s); else PATH if file exists; else NAME (remote index).",
|
|
138
138
|
"Network operations may require approval; use --yes to auto-approve when allowed by config.",
|
|
139
|
+
"--on-conflict is accepted for backward compatibility but does not change install behavior.",
|
|
139
140
|
],
|
|
140
141
|
};
|