agentplane 0.3.11 → 0.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/AGENTS.md +2 -2
- package/assets/RUNNER.md +1 -1
- package/assets/agents/CODER.json +4 -0
- package/assets/agents/CREATOR.json +1 -0
- package/assets/agents/DOCS.json +2 -1
- package/assets/agents/INTEGRATOR.json +2 -1
- package/assets/agents/ORCHESTRATOR.json +3 -1
- package/assets/agents/PLANNER.json +3 -1
- package/assets/agents/REVIEWER.json +1 -0
- package/assets/agents/TESTER.json +2 -2
- package/assets/agents/UPDATER.json +1 -0
- package/assets/agents/UPGRADER.json +1 -1
- package/assets/codex-plugin/assets/header.png +0 -0
- package/assets/codex-plugin/assets/icon.svg +1 -0
- package/assets/codex-plugin/assets/logo.svg +1 -0
- package/assets/codex-plugin/skills/agentplane/SKILL.md +35 -0
- package/assets/policy/governance.md +4 -2
- package/assets/policy/incidents.md +3 -19
- package/assets/policy/workflow.release.md +5 -2
- package/bin/agentplane.js +58 -3
- package/bin/stale-dist-policy.js +6 -1
- package/dist/.build-manifest.json +271 -161
- package/dist/cli/exit-codes.d.ts.map +1 -1
- package/dist/cli/exit-codes.js +1 -0
- package/dist/cli/reason-codes.d.ts +1 -1
- package/dist/cli/reason-codes.d.ts.map +1 -1
- package/dist/cli/reason-codes.js +12 -0
- package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/core.js +22 -1
- package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/project.js +21 -3
- package/dist/cli/run-cli/command-catalog.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/codex.d.ts +14 -0
- package/dist/cli/run-cli/commands/codex.d.ts.map +1 -0
- package/dist/cli/run-cli/commands/codex.js +100 -0
- package/dist/cli/run-cli/commands/core.d.ts +1 -0
- package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core.js +1 -0
- package/dist/cli/run-cli/commands/init/recipes.d.ts +9 -1
- package/dist/cli/run-cli/commands/init/recipes.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/recipes.js +32 -22
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +26 -21
- package/dist/cli/run-cli/error-guidance.js +20 -0
- package/dist/cli/run-cli.test-helpers.d.ts +1 -0
- package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +36 -19
- package/dist/commands/branch/cleanup-merged.d.ts +1 -0
- package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
- package/dist/commands/branch/cleanup-merged.js +18 -9
- package/dist/commands/branch/work-start.d.ts.map +1 -1
- package/dist/commands/branch/work-start.js +82 -5
- package/dist/commands/codex/plugin-install.d.ts +26 -0
- package/dist/commands/codex/plugin-install.d.ts.map +1 -0
- package/dist/commands/codex/plugin-install.js +209 -0
- package/dist/commands/doctor/branch-pr.js +2 -2
- package/dist/commands/guard/impl/commands.d.ts +1 -0
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +78 -8
- package/dist/commands/hooks/index.d.ts +1 -1
- package/dist/commands/hooks/index.d.ts.map +1 -1
- package/dist/commands/hooks/index.js +48 -12
- package/dist/commands/pr/check.d.ts.map +1 -1
- package/dist/commands/pr/check.js +3 -0
- package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
- package/dist/commands/pr/integrate/cmd.js +103 -2
- package/dist/commands/pr/integrate/internal/cleanup.d.ts +1 -11
- package/dist/commands/pr/integrate/internal/cleanup.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/cleanup.js +1 -46
- package/dist/commands/pr/integrate/internal/finalize.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/finalize.js +3 -0
- package/dist/commands/pr/integrate/internal/github-protection.d.ts +5 -0
- package/dist/commands/pr/integrate/internal/github-protection.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/github-protection.js +13 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts +15 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.js +35 -0
- package/dist/commands/pr/integrate/internal/prepare.d.ts +1 -0
- package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/prepare.js +46 -7
- package/dist/commands/pr/internal/auto-commit.d.ts +7 -0
- package/dist/commands/pr/internal/auto-commit.d.ts.map +1 -0
- package/dist/commands/pr/internal/auto-commit.js +69 -0
- package/dist/commands/pr/internal/freshness.d.ts +1 -0
- package/dist/commands/pr/internal/freshness.d.ts.map +1 -1
- package/dist/commands/pr/internal/freshness.js +2 -0
- package/dist/commands/pr/internal/sync.d.ts.map +1 -1
- package/dist/commands/pr/internal/sync.js +98 -27
- package/dist/commands/pr/open.d.ts.map +1 -1
- package/dist/commands/pr/open.js +52 -3
- package/dist/commands/pr/update.d.ts.map +1 -1
- package/dist/commands/pr/update.js +13 -2
- package/dist/commands/recipes/active.command.d.ts +7 -0
- package/dist/commands/recipes/active.command.d.ts.map +1 -0
- package/dist/commands/recipes/active.command.js +12 -0
- package/dist/commands/recipes/add.command.d.ts +8 -0
- package/dist/commands/recipes/add.command.d.ts.map +1 -0
- package/dist/commands/recipes/add.command.js +33 -0
- package/dist/commands/recipes/detach.command.d.ts +7 -0
- package/dist/commands/recipes/detach.command.d.ts.map +1 -0
- package/dist/commands/recipes/detach.command.js +19 -0
- package/dist/commands/recipes/disable.command.d.ts +7 -0
- package/dist/commands/recipes/disable.command.d.ts.map +1 -0
- package/dist/commands/recipes/disable.command.js +10 -0
- package/dist/commands/recipes/enable.command.d.ts +7 -0
- package/dist/commands/recipes/enable.command.d.ts.map +1 -0
- package/dist/commands/recipes/enable.command.js +10 -0
- package/dist/commands/recipes/explain-active.command.d.ts +5 -0
- package/dist/commands/recipes/explain-active.command.d.ts.map +1 -0
- package/dist/commands/recipes/explain-active.command.js +11 -0
- package/dist/commands/recipes/explain.command.d.ts.map +1 -1
- package/dist/commands/recipes/explain.command.js +4 -2
- package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
- package/dist/commands/recipes/impl/apply.js +33 -14
- package/dist/commands/recipes/impl/commands/active.d.ts +6 -0
- package/dist/commands/recipes/impl/commands/active.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/active.js +46 -0
- package/dist/commands/recipes/impl/commands/add.d.ts +7 -0
- package/dist/commands/recipes/impl/commands/add.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/add.js +100 -0
- package/dist/commands/recipes/impl/commands/detach.d.ts +6 -0
- package/dist/commands/recipes/impl/commands/detach.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/detach.js +85 -0
- package/dist/commands/recipes/impl/commands/disable.d.ts +6 -0
- package/dist/commands/recipes/impl/commands/disable.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/disable.js +21 -0
- package/dist/commands/recipes/impl/commands/enable.d.ts +6 -0
- package/dist/commands/recipes/impl/commands/enable.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/enable.js +39 -0
- package/dist/commands/recipes/impl/commands/explain-active.d.ts +5 -0
- package/dist/commands/recipes/impl/commands/explain-active.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/explain-active.js +20 -0
- package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/explain.js +40 -3
- package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/info.js +21 -8
- package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/install.js +32 -29
- package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/list.js +11 -11
- package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands/remove.js +5 -0
- package/dist/commands/recipes/impl/commands/update.d.ts +7 -0
- package/dist/commands/recipes/impl/commands/update.d.ts.map +1 -0
- package/dist/commands/recipes/impl/commands/update.js +93 -0
- package/dist/commands/recipes/impl/commands.d.ts +7 -0
- package/dist/commands/recipes/impl/commands.d.ts.map +1 -1
- package/dist/commands/recipes/impl/commands.js +7 -0
- package/dist/commands/recipes/impl/constants.d.ts +1 -14
- package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
- package/dist/commands/recipes/impl/constants.js +1 -18
- package/dist/commands/recipes/impl/manifest.d.ts +2 -2
- package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
- package/dist/commands/recipes/impl/manifest.js +4 -226
- package/dist/commands/recipes/impl/overlay-project.d.ts +32 -0
- package/dist/commands/recipes/impl/overlay-project.d.ts.map +1 -0
- package/dist/commands/recipes/impl/overlay-project.js +282 -0
- package/dist/commands/recipes/impl/paths.d.ts +20 -2
- package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
- package/dist/commands/recipes/impl/paths.js +23 -5
- package/dist/commands/recipes/impl/project-installed-recipes.d.ts +2 -4
- package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -1
- package/dist/commands/recipes/impl/project-installed-recipes.js +30 -74
- package/dist/commands/recipes/impl/project-recipe-state.d.ts +18 -0
- package/dist/commands/recipes/impl/project-recipe-state.d.ts.map +1 -0
- package/dist/commands/recipes/impl/project-recipe-state.js +94 -0
- package/dist/commands/recipes/impl/project-registry.d.ts +20 -0
- package/dist/commands/recipes/impl/project-registry.d.ts.map +1 -0
- package/dist/commands/recipes/impl/project-registry.js +104 -0
- package/dist/commands/recipes/impl/resolver.d.ts.map +1 -1
- package/dist/commands/recipes/impl/resolver.js +5 -3
- package/dist/commands/recipes/impl/types.d.ts +1 -240
- package/dist/commands/recipes/impl/types.d.ts.map +1 -1
- package/dist/commands/recipes/info.command.js +2 -2
- package/dist/commands/recipes/install.spec.js +4 -4
- package/dist/commands/recipes/list.command.js +4 -4
- package/dist/commands/recipes/remove.command.js +2 -2
- package/dist/commands/recipes/update.command.d.ts +8 -0
- package/dist/commands/recipes/update.command.d.ts.map +1 -0
- package/dist/commands/recipes/update.command.js +35 -0
- package/dist/commands/recipes.d.ts +7 -4
- package/dist/commands/recipes.d.ts.map +1 -1
- package/dist/commands/recipes.js +6 -3
- package/dist/commands/recipes.test-helpers.d.ts +3 -3
- package/dist/commands/recipes.test-helpers.d.ts.map +1 -1
- package/dist/commands/recipes.test-helpers.js +105 -15
- package/dist/commands/release/apply.command.d.ts +3 -1
- package/dist/commands/release/apply.command.d.ts.map +1 -1
- package/dist/commands/release/apply.command.js +354 -18
- package/dist/commands/release/apply.mutation.d.ts.map +1 -1
- package/dist/commands/release/apply.mutation.js +1 -0
- package/dist/commands/release/apply.reporting.d.ts +1 -0
- package/dist/commands/release/apply.reporting.d.ts.map +1 -1
- package/dist/commands/release/apply.reporting.js +12 -8
- package/dist/commands/release/apply.types.d.ts +13 -0
- package/dist/commands/release/apply.types.d.ts.map +1 -1
- package/dist/commands/release/plan.command.d.ts.map +1 -1
- package/dist/commands/release/plan.command.js +48 -0
- package/dist/commands/scenario/execute.command.js +4 -4
- package/dist/commands/scenario/impl/commands.js +4 -4
- package/dist/commands/scenario/info.command.js +4 -4
- package/dist/commands/scenario/list.command.js +3 -3
- package/dist/commands/scenario/run.command.js +5 -5
- package/dist/commands/scenario/scenario.command.js +7 -7
- package/dist/commands/shared/merged-branch-cleanup.d.ts +12 -0
- package/dist/commands/shared/merged-branch-cleanup.d.ts.map +1 -0
- package/dist/commands/shared/merged-branch-cleanup.js +46 -0
- package/dist/commands/shared/post-commit-pr-artifacts.d.ts.map +1 -1
- package/dist/commands/shared/post-commit-pr-artifacts.js +35 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +37 -5
- package/dist/commands/shared/task-handoff.d.ts +2 -1
- package/dist/commands/shared/task-handoff.d.ts.map +1 -1
- package/dist/commands/shared/task-handoff.js +15 -0
- package/dist/commands/shared/task-local-freshness.d.ts +2 -0
- package/dist/commands/shared/task-local-freshness.d.ts.map +1 -1
- package/dist/commands/shared/task-local-freshness.js +7 -1
- package/dist/commands/task/finish-shared.d.ts +1 -0
- package/dist/commands/task/finish-shared.d.ts.map +1 -1
- package/dist/commands/task/finish-shared.js +1 -0
- package/dist/commands/task/handoff-show.command.d.ts.map +1 -1
- package/dist/commands/task/handoff-show.command.js +24 -0
- package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -1
- package/dist/commands/task/hosted-close-pr.command.js +35 -0
- package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
- package/dist/commands/task/hosted-close.command.js +185 -18
- package/dist/commands/task/hosted-merge-sync.d.ts +4 -1
- package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
- package/dist/commands/task/hosted-merge-sync.js +52 -10
- package/dist/commands/task/start-ready.d.ts.map +1 -1
- package/dist/commands/task/start-ready.js +0 -86
- package/dist/runner/context/base-prompts.d.ts +2 -1
- package/dist/runner/context/base-prompts.d.ts.map +1 -1
- package/dist/runner/context/base-prompts.js +109 -13
- package/dist/runner/context/recipe-context.d.ts.map +1 -1
- package/dist/runner/context/recipe-context.js +40 -8
- package/dist/runner/types.d.ts +4 -0
- package/dist/runner/types.d.ts.map +1 -1
- package/dist/runner/usecases/task-run.d.ts.map +1 -1
- package/dist/runner/usecases/task-run.js +2 -1
- package/dist/runtime/behavior/resolve.d.ts +2 -1
- package/dist/runtime/behavior/resolve.d.ts.map +1 -1
- package/dist/runtime/behavior/resolve.js +25 -5
- package/dist/runtime/behavior/types.d.ts +1 -0
- package/dist/runtime/behavior/types.d.ts.map +1 -1
- package/dist/runtime/capabilities/recipe.d.ts +2 -1
- package/dist/runtime/capabilities/recipe.d.ts.map +1 -1
- package/dist/runtime/capabilities/recipe.js +88 -28
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/runtime-source.d.ts.map +1 -1
- package/dist/shared/runtime-source.js +8 -3
- package/package.json +3 -2
- package/dist/cli/recipes-bundled.d.ts +0 -10
- package/dist/cli/recipes-bundled.d.ts.map +0 -1
- package/dist/cli/recipes-bundled.js +0 -36
|
@@ -1,229 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { dedupeStrings } from "../../../shared/strings.js";
|
|
5
|
-
import { normalizeAgentId, normalizeRecipeId, normalizeRecipeRelativePath, normalizeRecipeTags, normalizeScenarioId, normalizeSkillId, normalizeToolId, } from "./normalize.js";
|
|
6
|
-
function normalizeRequiredString(raw, field) {
|
|
7
|
-
if (typeof raw !== "string")
|
|
8
|
-
throw new Error(invalidFieldMessage(field, "string"));
|
|
9
|
-
const value = raw.trim();
|
|
10
|
-
if (!value)
|
|
11
|
-
throw new Error(requiredFieldMessage(field));
|
|
12
|
-
return value;
|
|
13
|
-
}
|
|
14
|
-
function normalizeOptionalString(raw, field) {
|
|
15
|
-
if (raw === undefined)
|
|
16
|
-
return undefined;
|
|
17
|
-
if (typeof raw !== "string")
|
|
18
|
-
throw new Error(invalidFieldMessage(field, "string"));
|
|
19
|
-
const value = raw.trim();
|
|
20
|
-
return value || undefined;
|
|
21
|
-
}
|
|
22
|
-
function normalizeStringList(raw, field, opts) {
|
|
23
|
-
if (!Array.isArray(raw))
|
|
24
|
-
throw new Error(invalidFieldMessage(field, "string[]"));
|
|
25
|
-
const values = raw.map((value) => {
|
|
26
|
-
if (typeof value !== "string")
|
|
27
|
-
throw new Error(invalidFieldMessage(field, "string[]"));
|
|
28
|
-
const trimmed = value.trim();
|
|
29
|
-
if (!trimmed)
|
|
30
|
-
throw new Error(invalidFieldMessage(field, "string[]"));
|
|
31
|
-
return trimmed;
|
|
32
|
-
});
|
|
33
|
-
const deduped = dedupeStrings(values);
|
|
34
|
-
if ((opts?.minLength ?? 0) > 0 && deduped.length < (opts?.minLength ?? 0)) {
|
|
35
|
-
throw new Error(invalidFieldMessage(field, `string[${opts?.minLength ?? 0}+]`));
|
|
36
|
-
}
|
|
37
|
-
return deduped;
|
|
38
|
-
}
|
|
39
|
-
function normalizeOptionalStringList(raw, field) {
|
|
40
|
-
if (raw === undefined)
|
|
41
|
-
return undefined;
|
|
42
|
-
return normalizeStringList(raw, field);
|
|
43
|
-
}
|
|
44
|
-
function normalizeNumber(raw, field) {
|
|
45
|
-
if (raw === undefined)
|
|
46
|
-
return undefined;
|
|
47
|
-
if (typeof raw !== "number" || Number.isNaN(raw)) {
|
|
48
|
-
throw new Error(invalidFieldMessage(field, "number"));
|
|
49
|
-
}
|
|
50
|
-
return raw;
|
|
51
|
-
}
|
|
52
|
-
function normalizeCompatibility(raw) {
|
|
53
|
-
if (raw === undefined)
|
|
54
|
-
return undefined;
|
|
55
|
-
if (!isRecord(raw))
|
|
56
|
-
throw new Error(invalidFieldMessage("manifest.compatibility", "object"));
|
|
57
|
-
return {
|
|
58
|
-
min_agentplane_version: normalizeOptionalString(raw.min_agentplane_version, "manifest.compatibility.min_agentplane_version"),
|
|
59
|
-
manifest_api_version: normalizeOptionalString(raw.manifest_api_version, "manifest.compatibility.manifest_api_version"),
|
|
60
|
-
scenario_api_version: normalizeOptionalString(raw.scenario_api_version, "manifest.compatibility.scenario_api_version"),
|
|
61
|
-
runtime_api_version: normalizeOptionalString(raw.runtime_api_version, "manifest.compatibility.runtime_api_version"),
|
|
62
|
-
platforms: normalizeOptionalStringList(raw.platforms, "manifest.compatibility.platforms"),
|
|
63
|
-
repo_types: normalizeOptionalStringList(raw.repo_types, "manifest.compatibility.repo_types"),
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function normalizeRunProfile(raw, field) {
|
|
67
|
-
if (!isRecord(raw))
|
|
68
|
-
throw new Error(invalidFieldMessage(field, "object"));
|
|
69
|
-
return {
|
|
70
|
-
mode: normalizeRequiredString(raw.mode, `${field}.mode`),
|
|
71
|
-
sandbox: normalizeOptionalString(raw.sandbox, `${field}.sandbox`),
|
|
72
|
-
writes_artifacts_to: normalizeOptionalStringList(raw.writes_artifacts_to, `${field}.writes_artifacts_to`),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function normalizeSkills(raw) {
|
|
76
|
-
if (raw === undefined)
|
|
77
|
-
return undefined;
|
|
78
|
-
if (!Array.isArray(raw))
|
|
79
|
-
throw new Error(invalidFieldMessage("manifest.skills", "array"));
|
|
80
|
-
return raw.map((entry, index) => {
|
|
81
|
-
if (!isRecord(entry))
|
|
82
|
-
throw new Error(invalidFieldMessage(`manifest.skills[${index}]`, "object"));
|
|
83
|
-
return {
|
|
84
|
-
id: normalizeSkillId(normalizeRequiredString(entry.id, `manifest.skills[${index}].id`)),
|
|
85
|
-
summary: normalizeRequiredString(entry.summary, `manifest.skills[${index}].summary`),
|
|
86
|
-
kind: normalizeRequiredString(entry.kind, `manifest.skills[${index}].kind`),
|
|
87
|
-
file: normalizeRecipeRelativePath(`manifest.skills[${index}].file`, normalizeRequiredString(entry.file, `manifest.skills[${index}].file`)),
|
|
88
|
-
};
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
function normalizeTools(raw) {
|
|
92
|
-
if (raw === undefined)
|
|
93
|
-
return undefined;
|
|
94
|
-
if (!Array.isArray(raw))
|
|
95
|
-
throw new Error(invalidFieldMessage("manifest.tools", "array"));
|
|
96
|
-
return raw.map((entry, index) => {
|
|
97
|
-
if (!isRecord(entry))
|
|
98
|
-
throw new Error(invalidFieldMessage(`manifest.tools[${index}]`, "object"));
|
|
99
|
-
const runtime = normalizeRequiredString(entry.runtime, `manifest.tools[${index}].runtime`);
|
|
100
|
-
if (runtime !== "node" && runtime !== "bash") {
|
|
101
|
-
throw new Error(invalidFieldMessage(`manifest.tools[${index}].runtime`, '"node" | "bash"'));
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
id: normalizeToolId(normalizeRequiredString(entry.id, `manifest.tools[${index}].id`)),
|
|
105
|
-
summary: normalizeRequiredString(entry.summary, `manifest.tools[${index}].summary`),
|
|
106
|
-
runtime,
|
|
107
|
-
entrypoint: normalizeRecipeRelativePath(`manifest.tools[${index}].entrypoint`, normalizeRequiredString(entry.entrypoint, `manifest.tools[${index}].entrypoint`)),
|
|
108
|
-
permissions: normalizeOptionalStringList(entry.permissions, `manifest.tools[${index}].permissions`),
|
|
109
|
-
timeout_ms: normalizeNumber(entry.timeout_ms, `manifest.tools[${index}].timeout_ms`),
|
|
110
|
-
cwd_policy: normalizeOptionalString(entry.cwd_policy, `manifest.tools[${index}].cwd_policy`),
|
|
111
|
-
};
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
function normalizeAgents(raw) {
|
|
115
|
-
if (raw === undefined)
|
|
116
|
-
return undefined;
|
|
117
|
-
if (!Array.isArray(raw))
|
|
118
|
-
throw new Error(invalidFieldMessage("manifest.agents", "array"));
|
|
119
|
-
return raw.map((entry, index) => {
|
|
120
|
-
if (!isRecord(entry))
|
|
121
|
-
throw new Error(invalidFieldMessage(`manifest.agents[${index}]`, "object"));
|
|
122
|
-
return {
|
|
123
|
-
id: normalizeAgentId(normalizeRequiredString(entry.id, `manifest.agents[${index}].id`)),
|
|
124
|
-
display_name: normalizeRequiredString(entry.display_name, `manifest.agents[${index}].display_name`),
|
|
125
|
-
role: normalizeRequiredString(entry.role, `manifest.agents[${index}].role`),
|
|
126
|
-
summary: normalizeRequiredString(entry.summary, `manifest.agents[${index}].summary`),
|
|
127
|
-
skills: normalizeOptionalStringList(entry.skills, `manifest.agents[${index}].skills`),
|
|
128
|
-
tools: normalizeOptionalStringList(entry.tools, `manifest.agents[${index}].tools`),
|
|
129
|
-
file: normalizeRecipeRelativePath(`manifest.agents[${index}].file`, normalizeRequiredString(entry.file, `manifest.agents[${index}].file`)),
|
|
130
|
-
};
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
function normalizeScenarios(raw) {
|
|
134
|
-
if (!Array.isArray(raw) || raw.length === 0) {
|
|
135
|
-
throw new Error(invalidFieldMessage("manifest.scenarios", "non-empty array"));
|
|
136
|
-
}
|
|
137
|
-
return raw.map((entry, index) => {
|
|
138
|
-
if (!isRecord(entry)) {
|
|
139
|
-
throw new Error(invalidFieldMessage(`manifest.scenarios[${index}]`, "object"));
|
|
140
|
-
}
|
|
141
|
-
return {
|
|
142
|
-
id: normalizeScenarioId(normalizeRequiredString(entry.id, `manifest.scenarios[${index}].id`)),
|
|
143
|
-
name: normalizeRequiredString(entry.name, `manifest.scenarios[${index}].name`),
|
|
144
|
-
summary: normalizeRequiredString(entry.summary, `manifest.scenarios[${index}].summary`),
|
|
145
|
-
description: normalizeOptionalString(entry.description, `manifest.scenarios[${index}].description`),
|
|
146
|
-
use_when: normalizeStringList(entry.use_when, `manifest.scenarios[${index}].use_when`, {
|
|
147
|
-
minLength: 1,
|
|
148
|
-
}),
|
|
149
|
-
avoid_when: normalizeOptionalStringList(entry.avoid_when, `manifest.scenarios[${index}].avoid_when`),
|
|
150
|
-
required_inputs: normalizeStringList(entry.required_inputs, `manifest.scenarios[${index}].required_inputs`),
|
|
151
|
-
outputs: normalizeStringList(entry.outputs, `manifest.scenarios[${index}].outputs`),
|
|
152
|
-
permissions: normalizeStringList(Array.isArray(entry.permissions) ? entry.permissions : [], `manifest.scenarios[${index}].permissions`),
|
|
153
|
-
artifacts: normalizeStringList(Array.isArray(entry.artifacts) ? entry.artifacts : [], `manifest.scenarios[${index}].artifacts`),
|
|
154
|
-
agents_involved: normalizeStringList(entry.agents_involved, `manifest.scenarios[${index}].agents_involved`, { minLength: 1 }),
|
|
155
|
-
skills_used: normalizeStringList(Array.isArray(entry.skills_used) ? entry.skills_used : [], `manifest.scenarios[${index}].skills_used`),
|
|
156
|
-
tools_used: normalizeStringList(Array.isArray(entry.tools_used) ? entry.tools_used : [], `manifest.scenarios[${index}].tools_used`),
|
|
157
|
-
run_profile: normalizeRunProfile(entry.run_profile, `manifest.scenarios[${index}].run_profile`),
|
|
158
|
-
file: normalizeRecipeRelativePath(`manifest.scenarios[${index}].file`, normalizeRequiredString(entry.file, `manifest.scenarios[${index}].file`)),
|
|
159
|
-
};
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
function assertUniqueIds(field, items) {
|
|
163
|
-
const seen = new Set();
|
|
164
|
-
for (const item of items) {
|
|
165
|
-
if (seen.has(item.id)) {
|
|
166
|
-
throw new Error(invalidFieldMessage(field, `unique ids (duplicate: ${item.id})`));
|
|
167
|
-
}
|
|
168
|
-
seen.add(item.id);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
function assertKnownReferences(field, refs, known) {
|
|
172
|
-
if (!refs || refs.length === 0)
|
|
173
|
-
return;
|
|
174
|
-
const missing = refs.filter((ref) => !known.has(ref));
|
|
175
|
-
if (missing.length > 0) {
|
|
176
|
-
throw new Error(invalidFieldMessage(field, `known ids (missing: ${missing.join(", ")})`));
|
|
177
|
-
}
|
|
1
|
+
import { readRecipeManifest as readRecipeManifestBase, validateRecipeManifest as validateRecipeManifestBase, } from "@agentplaneorg/recipes";
|
|
2
|
+
export async function readRecipeManifest(manifestPath) {
|
|
3
|
+
return readRecipeManifestBase(manifestPath);
|
|
178
4
|
}
|
|
179
5
|
export function validateRecipeManifest(raw) {
|
|
180
|
-
|
|
181
|
-
throw new Error(invalidFieldMessage("manifest", "object"));
|
|
182
|
-
if (raw.schema_version !== "1")
|
|
183
|
-
throw new Error(invalidFieldMessage("manifest.schema_version", '"1"'));
|
|
184
|
-
const id = normalizeRecipeId(normalizeRequiredString(raw.id, "manifest.id"));
|
|
185
|
-
const version = normalizeRequiredString(raw.version, "manifest.version");
|
|
186
|
-
const tags = normalizeRecipeTags(raw.tags);
|
|
187
|
-
const compatibility = normalizeCompatibility(raw.compatibility);
|
|
188
|
-
const skills = normalizeSkills(raw.skills);
|
|
189
|
-
const tools = normalizeTools(raw.tools);
|
|
190
|
-
const agents = normalizeAgents(raw.agents);
|
|
191
|
-
const scenarios = normalizeScenarios(raw.scenarios);
|
|
192
|
-
if (skills)
|
|
193
|
-
assertUniqueIds("manifest.skills", skills);
|
|
194
|
-
if (tools)
|
|
195
|
-
assertUniqueIds("manifest.tools", tools);
|
|
196
|
-
if (agents)
|
|
197
|
-
assertUniqueIds("manifest.agents", agents);
|
|
198
|
-
assertUniqueIds("manifest.scenarios", scenarios);
|
|
199
|
-
const skillIds = new Set((skills ?? []).map((skill) => skill.id));
|
|
200
|
-
const toolIds = new Set((tools ?? []).map((tool) => tool.id));
|
|
201
|
-
const agentIds = new Set((agents ?? []).map((agent) => agent.id));
|
|
202
|
-
for (const [index, agent] of (agents ?? []).entries()) {
|
|
203
|
-
assertKnownReferences(`manifest.agents[${index}].skills`, agent.skills, skillIds);
|
|
204
|
-
assertKnownReferences(`manifest.agents[${index}].tools`, agent.tools, toolIds);
|
|
205
|
-
}
|
|
206
|
-
for (const [index, scenario] of scenarios.entries()) {
|
|
207
|
-
assertKnownReferences(`manifest.scenarios[${index}].agents_involved`, scenario.agents_involved, agentIds);
|
|
208
|
-
assertKnownReferences(`manifest.scenarios[${index}].skills_used`, scenario.skills_used, skillIds);
|
|
209
|
-
assertKnownReferences(`manifest.scenarios[${index}].tools_used`, scenario.tools_used, toolIds);
|
|
210
|
-
}
|
|
211
|
-
return {
|
|
212
|
-
schema_version: "1",
|
|
213
|
-
id,
|
|
214
|
-
version,
|
|
215
|
-
name: normalizeRequiredString(raw.name, "manifest.name"),
|
|
216
|
-
summary: normalizeRequiredString(raw.summary, "manifest.summary"),
|
|
217
|
-
description: normalizeRequiredString(raw.description, "manifest.description"),
|
|
218
|
-
tags: tags.length > 0 ? tags : undefined,
|
|
219
|
-
compatibility,
|
|
220
|
-
skills,
|
|
221
|
-
agents,
|
|
222
|
-
tools,
|
|
223
|
-
scenarios,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
export async function readRecipeManifest(manifestPath) {
|
|
227
|
-
const raw = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
228
|
-
return validateRecipeManifest(raw);
|
|
6
|
+
return validateRecipeManifestBase(raw);
|
|
229
7
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type CompiledRecipeAssetRegistry, type CompiledOverlayBundle, type ProjectRecipesLockFile } from "@agentplaneorg/recipes";
|
|
2
|
+
export declare function readActiveRecipeIds(project: {
|
|
3
|
+
agentplaneDir: string;
|
|
4
|
+
}): Promise<string[]>;
|
|
5
|
+
export declare function setRecipeActive(opts: {
|
|
6
|
+
project: {
|
|
7
|
+
agentplaneDir: string;
|
|
8
|
+
};
|
|
9
|
+
recipeId: string;
|
|
10
|
+
active: boolean;
|
|
11
|
+
}): Promise<string[]>;
|
|
12
|
+
export declare function compileProjectOverlayArtifacts(project: {
|
|
13
|
+
agentplaneDir: string;
|
|
14
|
+
}): Promise<{
|
|
15
|
+
bundle: CompiledOverlayBundle;
|
|
16
|
+
lock: ProjectRecipesLockFile;
|
|
17
|
+
assets: CompiledRecipeAssetRegistry;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function refreshProjectOverlayArtifacts(project: {
|
|
20
|
+
agentplaneDir: string;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
bundle: CompiledOverlayBundle;
|
|
23
|
+
lock: ProjectRecipesLockFile;
|
|
24
|
+
assets: CompiledRecipeAssetRegistry;
|
|
25
|
+
}>;
|
|
26
|
+
export declare function readProjectOverlayBundle(project: {
|
|
27
|
+
agentplaneDir: string;
|
|
28
|
+
}): Promise<CompiledOverlayBundle | null>;
|
|
29
|
+
export declare function readProjectRecipeAssetRegistry(project: {
|
|
30
|
+
agentplaneDir: string;
|
|
31
|
+
}): Promise<CompiledRecipeAssetRegistry | null>;
|
|
32
|
+
//# sourceMappingURL=overlay-project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay-project.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/overlay-project.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC5B,MAAM,wBAAwB,CAAC;AAiJhC,wBAAsB,mBAAmB,CAAC,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAM/F;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAepB;AAED,wBAAsB,8BAA8B,CAAC,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC;IAChG,MAAM,EAAE,qBAAqB,CAAC;IAC9B,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,2BAA2B,CAAC;CACrC,CAAC,CAiHD;AAED,wBAAsB,8BAA8B,CAAC,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC;IAChG,MAAM,EAAE,qBAAqB,CAAC;IAC9B,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,2BAA2B,CAAC;CACrC,CAAC,CAUD;AAED,wBAAsB,wBAAwB,CAAC,OAAO,EAAE;IACtD,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAUxC;AAED,wBAAsB,8BAA8B,CAAC,OAAO,EAAE;IAC5D,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC,CAU9C"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { mkdir, readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createEmptyOverlayBundle, hashOverlayInputs, } from "@agentplaneorg/recipes";
|
|
4
|
+
import { writeJsonStableIfChanged } from "../../../shared/write-if-changed.js";
|
|
5
|
+
import { readProjectInstalledRecipes } from "./project-installed-recipes.js";
|
|
6
|
+
import { readProjectRecipesRegistry, writeProjectRecipesRegistry } from "./project-registry.js";
|
|
7
|
+
import { resolveProjectInstalledRecipeDir, resolveProjectOverlayBundlePath, resolveProjectRecipeAssetsPath, resolveProjectRecipesDir, resolveProjectRecipesLockPath, } from "./paths.js";
|
|
8
|
+
function ensureTrailingNewline(text) {
|
|
9
|
+
return text.endsWith("\n") ? text : `${text}\n`;
|
|
10
|
+
}
|
|
11
|
+
function stripMarkdownFrontmatter(text) {
|
|
12
|
+
if (!text.startsWith("---\n"))
|
|
13
|
+
return text;
|
|
14
|
+
const end = text.indexOf("\n---\n", 4);
|
|
15
|
+
if (end === -1)
|
|
16
|
+
return text;
|
|
17
|
+
return text.slice(end + 5);
|
|
18
|
+
}
|
|
19
|
+
function normalizePromptContent(text) {
|
|
20
|
+
return ensureTrailingNewline(stripMarkdownFrontmatter(text).trim());
|
|
21
|
+
}
|
|
22
|
+
function normalizeRecipeAssetContent(text) {
|
|
23
|
+
return ensureTrailingNewline(text.trimEnd());
|
|
24
|
+
}
|
|
25
|
+
function uniqueById(items) {
|
|
26
|
+
const seen = new Set();
|
|
27
|
+
const result = [];
|
|
28
|
+
for (const item of items) {
|
|
29
|
+
if (seen.has(item.id))
|
|
30
|
+
continue;
|
|
31
|
+
seen.add(item.id);
|
|
32
|
+
result.push(item);
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
function recipeAssetId(recipeId, kind, assetId) {
|
|
37
|
+
return `recipe:${recipeId}/${kind}:${assetId}`;
|
|
38
|
+
}
|
|
39
|
+
function relativeSource(project, absolutePath) {
|
|
40
|
+
return path.relative(project.agentplaneDir, absolutePath).replaceAll("\\", "/");
|
|
41
|
+
}
|
|
42
|
+
async function compileProjectRecipeAssets(opts) {
|
|
43
|
+
const entries = [];
|
|
44
|
+
for (const recipe of opts.installed.recipes) {
|
|
45
|
+
const recipeDir = recipe.project_path
|
|
46
|
+
? path.join(resolveProjectRecipesDir(opts.project), recipe.project_path)
|
|
47
|
+
: resolveProjectInstalledRecipeDir(opts.project, recipe.id);
|
|
48
|
+
const manifest = recipe.manifest;
|
|
49
|
+
for (const agent of manifest.agents ?? []) {
|
|
50
|
+
const sourcePath = path.join(recipeDir, agent.file);
|
|
51
|
+
entries.push({
|
|
52
|
+
id: recipeAssetId(recipe.id, "agent", agent.id),
|
|
53
|
+
kind: "agent",
|
|
54
|
+
recipe_id: recipe.id,
|
|
55
|
+
recipe_version: recipe.version,
|
|
56
|
+
recipe_name: manifest.name,
|
|
57
|
+
asset_id: agent.id,
|
|
58
|
+
source: relativeSource(opts.project, sourcePath),
|
|
59
|
+
summary: agent.summary,
|
|
60
|
+
definition: agent,
|
|
61
|
+
content: normalizeRecipeAssetContent(await readFile(sourcePath, "utf8")),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
for (const skill of manifest.skills ?? []) {
|
|
65
|
+
const sourcePath = path.join(recipeDir, skill.file);
|
|
66
|
+
entries.push({
|
|
67
|
+
id: recipeAssetId(recipe.id, "skill", skill.id),
|
|
68
|
+
kind: "skill",
|
|
69
|
+
recipe_id: recipe.id,
|
|
70
|
+
recipe_version: recipe.version,
|
|
71
|
+
recipe_name: manifest.name,
|
|
72
|
+
asset_id: skill.id,
|
|
73
|
+
source: relativeSource(opts.project, sourcePath),
|
|
74
|
+
summary: skill.summary,
|
|
75
|
+
definition: skill,
|
|
76
|
+
content: normalizeRecipeAssetContent(await readFile(sourcePath, "utf8")),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
for (const tool of manifest.tools ?? []) {
|
|
80
|
+
entries.push({
|
|
81
|
+
id: recipeAssetId(recipe.id, "tool", tool.id),
|
|
82
|
+
kind: "tool",
|
|
83
|
+
recipe_id: recipe.id,
|
|
84
|
+
recipe_version: recipe.version,
|
|
85
|
+
recipe_name: manifest.name,
|
|
86
|
+
asset_id: tool.id,
|
|
87
|
+
source: relativeSource(opts.project, path.join(recipeDir, tool.entrypoint)),
|
|
88
|
+
summary: tool.summary,
|
|
89
|
+
definition: tool,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
for (const scenario of manifest.scenarios ?? []) {
|
|
93
|
+
entries.push({
|
|
94
|
+
id: recipeAssetId(recipe.id, "scenario", scenario.id),
|
|
95
|
+
kind: "scenario",
|
|
96
|
+
recipe_id: recipe.id,
|
|
97
|
+
recipe_version: recipe.version,
|
|
98
|
+
recipe_name: manifest.name,
|
|
99
|
+
asset_id: scenario.id,
|
|
100
|
+
source: relativeSource(opts.project, path.join(recipeDir, scenario.file)),
|
|
101
|
+
summary: scenario.summary,
|
|
102
|
+
definition: scenario,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
for (const [templateKey, content] of Object.entries(manifest.templates ?? {})) {
|
|
106
|
+
entries.push({
|
|
107
|
+
id: recipeAssetId(recipe.id, "template", templateKey),
|
|
108
|
+
kind: "template",
|
|
109
|
+
recipe_id: recipe.id,
|
|
110
|
+
recipe_version: recipe.version,
|
|
111
|
+
recipe_name: manifest.name,
|
|
112
|
+
asset_id: templateKey,
|
|
113
|
+
source: relativeSource(opts.project, path.join(recipeDir, "manifest.json")),
|
|
114
|
+
content,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
schema_version: 1,
|
|
120
|
+
kind: "recipe_asset_registry",
|
|
121
|
+
entries: uniqueById(entries).toSorted((left, right) => left.id.localeCompare(right.id)),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export async function readActiveRecipeIds(project) {
|
|
125
|
+
const registry = await readProjectRecipesRegistry(project);
|
|
126
|
+
return registry.recipes
|
|
127
|
+
.filter((entry) => entry.active)
|
|
128
|
+
.map((entry) => entry.id)
|
|
129
|
+
.toSorted();
|
|
130
|
+
}
|
|
131
|
+
export async function setRecipeActive(opts) {
|
|
132
|
+
const registry = await readProjectRecipesRegistry(opts.project);
|
|
133
|
+
const current = new Set();
|
|
134
|
+
const recipes = registry.recipes.map((entry) => {
|
|
135
|
+
const isTarget = entry.id === opts.recipeId;
|
|
136
|
+
const active = isTarget ? opts.active : entry.active;
|
|
137
|
+
if (active)
|
|
138
|
+
current.add(entry.id);
|
|
139
|
+
return isTarget ? { ...entry, active } : entry;
|
|
140
|
+
});
|
|
141
|
+
await writeProjectRecipesRegistry(opts.project, {
|
|
142
|
+
schema_version: 1,
|
|
143
|
+
updated_at: registry.updated_at,
|
|
144
|
+
recipes,
|
|
145
|
+
});
|
|
146
|
+
return [...current].toSorted();
|
|
147
|
+
}
|
|
148
|
+
export async function compileProjectOverlayArtifacts(project) {
|
|
149
|
+
const [activeIds, installed] = await Promise.all([
|
|
150
|
+
readActiveRecipeIds(project),
|
|
151
|
+
readProjectInstalledRecipes(project),
|
|
152
|
+
]);
|
|
153
|
+
const bundle = createEmptyOverlayBundle();
|
|
154
|
+
const lock = { schema_version: 1, active: [] };
|
|
155
|
+
for (const recipeId of activeIds) {
|
|
156
|
+
const entry = installed.recipes.find((candidate) => candidate.id === recipeId);
|
|
157
|
+
if (!entry) {
|
|
158
|
+
throw new Error(`Active overlay is not installed: ${recipeId}`);
|
|
159
|
+
}
|
|
160
|
+
if (entry.manifest.kind !== "project_overlay") {
|
|
161
|
+
throw new Error(`Active recipe ${recipeId} is not a project overlay`);
|
|
162
|
+
}
|
|
163
|
+
const manifest = entry.manifest;
|
|
164
|
+
const recipeDir = entry.project_path
|
|
165
|
+
? path.join(resolveProjectRecipesDir(project), entry.project_path)
|
|
166
|
+
: resolveProjectInstalledRecipeDir(project, entry.id);
|
|
167
|
+
const promptInputs = [];
|
|
168
|
+
if (manifest.requires) {
|
|
169
|
+
for (const required of manifest.requires) {
|
|
170
|
+
if (!activeIds.includes(required)) {
|
|
171
|
+
throw new Error(`Overlay ${manifest.id} requires active overlay ${required}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (manifest.conflicts) {
|
|
176
|
+
for (const conflict of manifest.conflicts) {
|
|
177
|
+
if (activeIds.includes(conflict.recipe_id)) {
|
|
178
|
+
throw new Error(`Overlay ${manifest.id} conflicts with ${conflict.recipe_id}: ${conflict.reason}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
for (const fragment of manifest.prompts ?? []) {
|
|
183
|
+
const absPath = path.join(recipeDir, fragment.file);
|
|
184
|
+
const content = normalizePromptContent(await readFile(absPath, "utf8"));
|
|
185
|
+
promptInputs.push({ id: fragment.id, content });
|
|
186
|
+
bundle.surfaces[fragment.surface].push({
|
|
187
|
+
...fragment,
|
|
188
|
+
recipe_id: manifest.id,
|
|
189
|
+
recipe_version: manifest.version,
|
|
190
|
+
recipe_name: manifest.name,
|
|
191
|
+
summary: manifest.summary,
|
|
192
|
+
source: path.relative(project.agentplaneDir, absPath).replaceAll("\\", "/"),
|
|
193
|
+
content,
|
|
194
|
+
});
|
|
195
|
+
bundle.trace.push({
|
|
196
|
+
recipe_id: manifest.id,
|
|
197
|
+
recipe_version: manifest.version,
|
|
198
|
+
accepted: true,
|
|
199
|
+
reason: "compiled prompt fragment",
|
|
200
|
+
source: fragment.file,
|
|
201
|
+
surface: fragment.surface,
|
|
202
|
+
fragment_id: fragment.id,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
for (const validator of manifest.validators ?? []) {
|
|
206
|
+
bundle.validators.push({
|
|
207
|
+
...validator,
|
|
208
|
+
recipe_id: manifest.id,
|
|
209
|
+
recipe_version: manifest.version,
|
|
210
|
+
});
|
|
211
|
+
bundle.trace.push({
|
|
212
|
+
recipe_id: manifest.id,
|
|
213
|
+
recipe_version: manifest.version,
|
|
214
|
+
accepted: true,
|
|
215
|
+
reason: "compiled validator",
|
|
216
|
+
validator_id: validator.id,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
bundle.active.push({
|
|
220
|
+
id: manifest.id,
|
|
221
|
+
version: manifest.version,
|
|
222
|
+
name: manifest.name,
|
|
223
|
+
summary: manifest.summary,
|
|
224
|
+
});
|
|
225
|
+
bundle.agents.push(...(manifest.agents ?? []));
|
|
226
|
+
bundle.tools.push(...(manifest.tools ?? []));
|
|
227
|
+
Object.assign(bundle.templates, manifest.templates ?? {});
|
|
228
|
+
lock.active.push({
|
|
229
|
+
id: manifest.id,
|
|
230
|
+
version: manifest.version,
|
|
231
|
+
kind: manifest.kind,
|
|
232
|
+
source: entry.source,
|
|
233
|
+
hash: hashOverlayInputs({ manifest, prompts: promptInputs }),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
bundle.agents = uniqueById(bundle.agents);
|
|
237
|
+
bundle.tools = uniqueById(bundle.tools);
|
|
238
|
+
for (const surface of Object.keys(bundle.surfaces)) {
|
|
239
|
+
bundle.surfaces[surface] = bundle.surfaces[surface].toSorted((left, right) => (left.order ?? 0) - (right.order ?? 0) ||
|
|
240
|
+
left.recipe_id.localeCompare(right.recipe_id) ||
|
|
241
|
+
left.id.localeCompare(right.id));
|
|
242
|
+
}
|
|
243
|
+
lock.active = lock.active.toSorted((left, right) => left.id.localeCompare(right.id));
|
|
244
|
+
return {
|
|
245
|
+
bundle,
|
|
246
|
+
lock,
|
|
247
|
+
assets: await compileProjectRecipeAssets({ project, installed }),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
export async function refreshProjectOverlayArtifacts(project) {
|
|
251
|
+
const compiled = await compileProjectOverlayArtifacts(project);
|
|
252
|
+
const bundlePath = resolveProjectOverlayBundlePath(project);
|
|
253
|
+
const lockPath = resolveProjectRecipesLockPath(project);
|
|
254
|
+
const assetsPath = resolveProjectRecipeAssetsPath(project);
|
|
255
|
+
await mkdir(path.dirname(bundlePath), { recursive: true });
|
|
256
|
+
await writeJsonStableIfChanged(bundlePath, compiled.bundle);
|
|
257
|
+
await writeJsonStableIfChanged(lockPath, compiled.lock);
|
|
258
|
+
await writeJsonStableIfChanged(assetsPath, compiled.assets);
|
|
259
|
+
return compiled;
|
|
260
|
+
}
|
|
261
|
+
export async function readProjectOverlayBundle(project) {
|
|
262
|
+
try {
|
|
263
|
+
return JSON.parse(await readFile(resolveProjectOverlayBundlePath(project), "utf8"));
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
const code = err?.code;
|
|
267
|
+
if (code === "ENOENT")
|
|
268
|
+
return null;
|
|
269
|
+
throw err;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
export async function readProjectRecipeAssetRegistry(project) {
|
|
273
|
+
try {
|
|
274
|
+
return JSON.parse(await readFile(resolveProjectRecipeAssetsPath(project), "utf8"));
|
|
275
|
+
}
|
|
276
|
+
catch (err) {
|
|
277
|
+
const code = err?.code;
|
|
278
|
+
if (code === "ENOENT")
|
|
279
|
+
return null;
|
|
280
|
+
throw err;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
@@ -10,13 +10,31 @@ export declare function resolveInstalledRecipeDir(entry: {
|
|
|
10
10
|
export declare function resolveProjectRecipesDir(resolved: {
|
|
11
11
|
agentplaneDir: string;
|
|
12
12
|
}): string;
|
|
13
|
-
export declare function
|
|
13
|
+
export declare function resolveProjectRecipesPackagesDir(resolved: {
|
|
14
|
+
agentplaneDir: string;
|
|
15
|
+
}): string;
|
|
16
|
+
export declare function resolveProjectRecipesRegistryPath(resolved: {
|
|
17
|
+
agentplaneDir: string;
|
|
18
|
+
}): string;
|
|
19
|
+
export declare function resolveProjectVendoredRecipeDir(resolved: {
|
|
14
20
|
agentplaneDir: string;
|
|
15
21
|
}, recipeId: string): string;
|
|
16
|
-
export declare function
|
|
22
|
+
export declare function resolveProjectInstalledRecipeDir(resolved: {
|
|
17
23
|
agentplaneDir: string;
|
|
18
24
|
}, recipeId: string): string;
|
|
19
25
|
export declare function resolveProjectRecipesCacheDir(resolved: {
|
|
20
26
|
agentplaneDir: string;
|
|
21
27
|
}): string;
|
|
28
|
+
export declare function resolveProjectRecipesLockPath(resolved: {
|
|
29
|
+
agentplaneDir: string;
|
|
30
|
+
}): string;
|
|
31
|
+
export declare function resolveProjectGeneratedDir(resolved: {
|
|
32
|
+
agentplaneDir: string;
|
|
33
|
+
}): string;
|
|
34
|
+
export declare function resolveProjectOverlayBundlePath(resolved: {
|
|
35
|
+
agentplaneDir: string;
|
|
36
|
+
}): string;
|
|
37
|
+
export declare function resolveProjectRecipeAssetsPath(resolved: {
|
|
38
|
+
agentplaneDir: string;
|
|
39
|
+
}): string;
|
|
22
40
|
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/paths.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/paths.ts"],"names":[],"mappings":"AAeA,wBAAgB,qBAAqB,IAAI,MAAM,CAI9C;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,wBAAgB,2BAA2B,IAAI,MAAM,CAEpD;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAgB,+BAA+B,IAAI,MAAM,CAExD;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAExF;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEpF;AAED,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE5F;AAED,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE7F;AAED,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,EACnC,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AAED,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,EACnC,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEzF;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEzF;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEtF;AAED,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE3F;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE1F"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { AGENTPLANE_HOME_ENV, GLOBAL_RECIPES_DIR_NAME, INSTALLED_RECIPES_NAME,
|
|
3
|
+
import { AGENTPLANE_HOME_ENV, GLOBAL_RECIPES_DIR_NAME, INSTALLED_RECIPES_NAME, PROJECT_RECIPES_PACKAGES_DIR_NAME, PROJECT_RECIPES_REGISTRY_NAME, PROJECT_RECIPES_CACHE_DIR_NAME, RECIPES_DIR_NAME, RECIPES_REMOTE_INDEX_NAME, RECIPES_REMOTE_INDEX_SIG_NAME, } from "./constants.js";
|
|
4
4
|
export function resolveAgentplaneHome() {
|
|
5
5
|
const overridden = process.env[AGENTPLANE_HOME_ENV]?.trim();
|
|
6
6
|
if (overridden)
|
|
@@ -25,12 +25,30 @@ export function resolveInstalledRecipeDir(entry) {
|
|
|
25
25
|
export function resolveProjectRecipesDir(resolved) {
|
|
26
26
|
return path.join(resolved.agentplaneDir, RECIPES_DIR_NAME);
|
|
27
27
|
}
|
|
28
|
-
export function
|
|
29
|
-
return path.join(resolveProjectRecipesDir(resolved),
|
|
28
|
+
export function resolveProjectRecipesPackagesDir(resolved) {
|
|
29
|
+
return path.join(resolveProjectRecipesDir(resolved), PROJECT_RECIPES_PACKAGES_DIR_NAME);
|
|
30
|
+
}
|
|
31
|
+
export function resolveProjectRecipesRegistryPath(resolved) {
|
|
32
|
+
return path.join(resolveProjectRecipesDir(resolved), PROJECT_RECIPES_REGISTRY_NAME);
|
|
30
33
|
}
|
|
31
|
-
export function
|
|
32
|
-
return path.join(
|
|
34
|
+
export function resolveProjectVendoredRecipeDir(resolved, recipeId) {
|
|
35
|
+
return path.join(resolveProjectRecipesPackagesDir(resolved), recipeId);
|
|
36
|
+
}
|
|
37
|
+
export function resolveProjectInstalledRecipeDir(resolved, recipeId) {
|
|
38
|
+
return resolveProjectVendoredRecipeDir(resolved, recipeId);
|
|
33
39
|
}
|
|
34
40
|
export function resolveProjectRecipesCacheDir(resolved) {
|
|
35
41
|
return path.join(resolved.agentplaneDir, PROJECT_RECIPES_CACHE_DIR_NAME);
|
|
36
42
|
}
|
|
43
|
+
export function resolveProjectRecipesLockPath(resolved) {
|
|
44
|
+
return path.join(resolved.agentplaneDir, "recipes.lock.json");
|
|
45
|
+
}
|
|
46
|
+
export function resolveProjectGeneratedDir(resolved) {
|
|
47
|
+
return path.join(resolved.agentplaneDir, "generated");
|
|
48
|
+
}
|
|
49
|
+
export function resolveProjectOverlayBundlePath(resolved) {
|
|
50
|
+
return path.join(resolveProjectGeneratedDir(resolved), "overlay-bundle.json");
|
|
51
|
+
}
|
|
52
|
+
export function resolveProjectRecipeAssetsPath(resolved) {
|
|
53
|
+
return path.join(resolveProjectGeneratedDir(resolved), "recipe-assets.json");
|
|
54
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function readRecipeInstallMetadata(filePath: string): Promise<RecipeInstallMetadata | null>;
|
|
3
|
-
export declare function writeRecipeInstallMetadata(filePath: string, metadata: RecipeInstallMetadata): Promise<void>;
|
|
1
|
+
import type { ProjectInstalledRecipesFile } from "./types.js";
|
|
4
2
|
export declare function readProjectInstalledRecipes(opts: {
|
|
5
3
|
agentplaneDir: string;
|
|
6
|
-
}): Promise<
|
|
4
|
+
}): Promise<ProjectInstalledRecipesFile>;
|
|
7
5
|
//# sourceMappingURL=project-installed-recipes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-installed-recipes.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/project-installed-recipes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"project-installed-recipes.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/project-installed-recipes.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAA+B,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAiB3F,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CA8CvC"}
|