loadouts 0.1.11
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/LICENSE +201 -0
- package/README.md +108 -0
- package/bundled/loadouts/loadouts.yaml +5 -0
- package/bundled/skills/loadout-usage/SKILL.md +110 -0
- package/dist/builtins/index.d.ts +14 -0
- package/dist/builtins/index.d.ts.map +1 -0
- package/dist/builtins/index.js +58 -0
- package/dist/builtins/index.js.map +1 -0
- package/dist/builtins/kinds/extension.d.ts +3 -0
- package/dist/builtins/kinds/extension.d.ts.map +1 -0
- package/dist/builtins/kinds/extension.js +9 -0
- package/dist/builtins/kinds/extension.js.map +1 -0
- package/dist/builtins/kinds/instruction.d.ts +3 -0
- package/dist/builtins/kinds/instruction.d.ts.map +1 -0
- package/dist/builtins/kinds/instruction.js +8 -0
- package/dist/builtins/kinds/instruction.js.map +1 -0
- package/dist/builtins/kinds/prompt.d.ts +3 -0
- package/dist/builtins/kinds/prompt.d.ts.map +1 -0
- package/dist/builtins/kinds/prompt.js +8 -0
- package/dist/builtins/kinds/prompt.js.map +1 -0
- package/dist/builtins/kinds/rule.d.ts +3 -0
- package/dist/builtins/kinds/rule.d.ts.map +1 -0
- package/dist/builtins/kinds/rule.js +10 -0
- package/dist/builtins/kinds/rule.js.map +1 -0
- package/dist/builtins/kinds/skill.d.ts +3 -0
- package/dist/builtins/kinds/skill.d.ts.map +1 -0
- package/dist/builtins/kinds/skill.js +8 -0
- package/dist/builtins/kinds/skill.js.map +1 -0
- package/dist/builtins/kinds/theme.d.ts +3 -0
- package/dist/builtins/kinds/theme.d.ts.map +1 -0
- package/dist/builtins/kinds/theme.js +8 -0
- package/dist/builtins/kinds/theme.js.map +1 -0
- package/dist/builtins/tools/claude-code.d.ts +3 -0
- package/dist/builtins/tools/claude-code.d.ts.map +1 -0
- package/dist/builtins/tools/claude-code.js +30 -0
- package/dist/builtins/tools/claude-code.js.map +1 -0
- package/dist/builtins/tools/codex.d.ts +3 -0
- package/dist/builtins/tools/codex.d.ts.map +1 -0
- package/dist/builtins/tools/codex.js +17 -0
- package/dist/builtins/tools/codex.js.map +1 -0
- package/dist/builtins/tools/cursor.d.ts +3 -0
- package/dist/builtins/tools/cursor.d.ts.map +1 -0
- package/dist/builtins/tools/cursor.js +22 -0
- package/dist/builtins/tools/cursor.js.map +1 -0
- package/dist/builtins/tools/opencode.d.ts +3 -0
- package/dist/builtins/tools/opencode.d.ts.map +1 -0
- package/dist/builtins/tools/opencode.js +45 -0
- package/dist/builtins/tools/opencode.js.map +1 -0
- package/dist/builtins/tools/pi.d.ts +3 -0
- package/dist/builtins/tools/pi.d.ts.map +1 -0
- package/dist/builtins/tools/pi.js +22 -0
- package/dist/builtins/tools/pi.js.map +1 -0
- package/dist/cli/commands/activate.d.ts +12 -0
- package/dist/cli/commands/activate.d.ts.map +1 -0
- package/dist/cli/commands/activate.js +70 -0
- package/dist/cli/commands/activate.js.map +1 -0
- package/dist/cli/commands/check.d.ts +12 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +152 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/clear.d.ts +12 -0
- package/dist/cli/commands/clear.d.ts.map +1 -0
- package/dist/cli/commands/clear.js +25 -0
- package/dist/cli/commands/clear.js.map +1 -0
- package/dist/cli/commands/create.d.ts +11 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +113 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/deactivate.d.ts +12 -0
- package/dist/cli/commands/deactivate.d.ts.map +1 -0
- package/dist/cli/commands/deactivate.js +67 -0
- package/dist/cli/commands/deactivate.js.map +1 -0
- package/dist/cli/commands/diff.d.ts +16 -0
- package/dist/cli/commands/diff.d.ts.map +1 -0
- package/dist/cli/commands/diff.js +144 -0
- package/dist/cli/commands/diff.js.map +1 -0
- package/dist/cli/commands/docs.d.ts +12 -0
- package/dist/cli/commands/docs.d.ts.map +1 -0
- package/dist/cli/commands/docs.js +115 -0
- package/dist/cli/commands/docs.js.map +1 -0
- package/dist/cli/commands/edit.d.ts +11 -0
- package/dist/cli/commands/edit.d.ts.map +1 -0
- package/dist/cli/commands/edit.js +71 -0
- package/dist/cli/commands/edit.js.map +1 -0
- package/dist/cli/commands/fallback.d.ts +9 -0
- package/dist/cli/commands/fallback.d.ts.map +1 -0
- package/dist/cli/commands/fallback.js +35 -0
- package/dist/cli/commands/fallback.js.map +1 -0
- package/dist/cli/commands/info.d.ts +23 -0
- package/dist/cli/commands/info.d.ts.map +1 -0
- package/dist/cli/commands/info.js +314 -0
- package/dist/cli/commands/info.js.map +1 -0
- package/dist/cli/commands/init.d.ts +18 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +255 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/install.d.ts +27 -0
- package/dist/cli/commands/install.d.ts.map +1 -0
- package/dist/cli/commands/install.js +586 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/instructions.d.ts +8 -0
- package/dist/cli/commands/instructions.d.ts.map +1 -0
- package/dist/cli/commands/instructions.js +218 -0
- package/dist/cli/commands/instructions.js.map +1 -0
- package/dist/cli/commands/kinds.d.ts +6 -0
- package/dist/cli/commands/kinds.d.ts.map +1 -0
- package/dist/cli/commands/kinds.js +59 -0
- package/dist/cli/commands/kinds.js.map +1 -0
- package/dist/cli/commands/list.d.ts +12 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +182 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/policy.d.ts +28 -0
- package/dist/cli/commands/policy.d.ts.map +1 -0
- package/dist/cli/commands/policy.js +50 -0
- package/dist/cli/commands/policy.js.map +1 -0
- package/dist/cli/commands/remove.d.ts +24 -0
- package/dist/cli/commands/remove.d.ts.map +1 -0
- package/dist/cli/commands/remove.js +64 -0
- package/dist/cli/commands/remove.js.map +1 -0
- package/dist/cli/commands/render-engine.d.ts +36 -0
- package/dist/cli/commands/render-engine.d.ts.map +1 -0
- package/dist/cli/commands/render-engine.js +177 -0
- package/dist/cli/commands/render-engine.js.map +1 -0
- package/dist/cli/commands/rule.d.ts +11 -0
- package/dist/cli/commands/rule.d.ts.map +1 -0
- package/dist/cli/commands/rule.js +302 -0
- package/dist/cli/commands/rule.js.map +1 -0
- package/dist/cli/commands/sanitize.d.ts +14 -0
- package/dist/cli/commands/sanitize.d.ts.map +1 -0
- package/dist/cli/commands/sanitize.js +62 -0
- package/dist/cli/commands/sanitize.js.map +1 -0
- package/dist/cli/commands/skill.d.ts +11 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +380 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/commands/status.d.ts +26 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +454 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +14 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +53 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/commands/update.d.ts +3 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +48 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.d.ts +11 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +134 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/config.d.ts +64 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +166 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/discovery.d.ts +50 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +249 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/fallback.d.ts +23 -0
- package/dist/core/fallback.d.ts.map +1 -0
- package/dist/core/fallback.js +119 -0
- package/dist/core/fallback.js.map +1 -0
- package/dist/core/import-discovery.d.ts +56 -0
- package/dist/core/import-discovery.d.ts.map +1 -0
- package/dist/core/import-discovery.js +304 -0
- package/dist/core/import-discovery.js.map +1 -0
- package/dist/core/kindLoader.d.ts +119 -0
- package/dist/core/kindLoader.d.ts.map +1 -0
- package/dist/core/kindLoader.js +141 -0
- package/dist/core/kindLoader.js.map +1 -0
- package/dist/core/manifest.d.ts +39 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +167 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/core/plugin.d.ts +22 -0
- package/dist/core/plugin.d.ts.map +1 -0
- package/dist/core/plugin.js +20 -0
- package/dist/core/plugin.js.map +1 -0
- package/dist/core/registry.d.ts +115 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +105 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/render.d.ts +64 -0
- package/dist/core/render.d.ts.map +1 -0
- package/dist/core/render.js +457 -0
- package/dist/core/render.js.map +1 -0
- package/dist/core/resolve.d.ts +39 -0
- package/dist/core/resolve.d.ts.map +1 -0
- package/dist/core/resolve.js +128 -0
- package/dist/core/resolve.js.map +1 -0
- package/dist/core/schema.d.ts +308 -0
- package/dist/core/schema.d.ts.map +1 -0
- package/dist/core/schema.js +81 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/scope.d.ts +74 -0
- package/dist/core/scope.d.ts.map +1 -0
- package/dist/core/scope.js +176 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/core/template.d.ts +32 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/template.js +32 -0
- package/dist/core/template.js.map +1 -0
- package/dist/core/tokens.d.ts +33 -0
- package/dist/core/tokens.d.ts.map +1 -0
- package/dist/core/tokens.js +97 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/core/types.d.ts +103 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +10 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/artifact-paths.d.ts +39 -0
- package/dist/lib/artifact-paths.d.ts.map +1 -0
- package/dist/lib/artifact-paths.js +83 -0
- package/dist/lib/artifact-paths.js.map +1 -0
- package/dist/lib/artifact-table.d.ts +126 -0
- package/dist/lib/artifact-table.d.ts.map +1 -0
- package/dist/lib/artifact-table.js +263 -0
- package/dist/lib/artifact-table.js.map +1 -0
- package/dist/lib/editor.d.ts +17 -0
- package/dist/lib/editor.d.ts.map +1 -0
- package/dist/lib/editor.js +33 -0
- package/dist/lib/editor.js.map +1 -0
- package/dist/lib/fs.d.ts +87 -0
- package/dist/lib/fs.d.ts.map +1 -0
- package/dist/lib/fs.js +229 -0
- package/dist/lib/fs.js.map +1 -0
- package/dist/lib/git.d.ts +13 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +28 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/gitignore.d.ts +26 -0
- package/dist/lib/gitignore.d.ts.map +1 -0
- package/dist/lib/gitignore.js +97 -0
- package/dist/lib/gitignore.js.map +1 -0
- package/dist/lib/loadout-column.d.ts +66 -0
- package/dist/lib/loadout-column.d.ts.map +1 -0
- package/dist/lib/loadout-column.js +66 -0
- package/dist/lib/loadout-column.js.map +1 -0
- package/dist/lib/output.d.ts +15 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +32 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/scope-indicators.d.ts +60 -0
- package/dist/lib/scope-indicators.d.ts.map +1 -0
- package/dist/lib/scope-indicators.js +110 -0
- package/dist/lib/scope-indicators.js.map +1 -0
- package/docs/authoring.md +182 -0
- package/docs/commands.md +192 -0
- package/docs/concepts.md +114 -0
- package/docs/index.md +60 -0
- package/docs/quickstart.md +100 -0
- package/docs/troubleshooting.md +147 -0
- package/docs/visual-language.md +251 -0
- package/docs/workflows.md +184 -0
- package/package.json +54 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic render pipeline.
|
|
3
|
+
*
|
|
4
|
+
* planRender() — computes what would be written without touching disk.
|
|
5
|
+
* renderOutput() — renders one (item, spec) pair to content + hash.
|
|
6
|
+
* applyPlan() — writes the plan to disk and saves state.
|
|
7
|
+
* removeManaged() — removes all outputs recorded in a state file.
|
|
8
|
+
*
|
|
9
|
+
* All tool/kind logic is delegated to the registry; this module contains
|
|
10
|
+
* no per-tool or per-kind switch statements.
|
|
11
|
+
*/
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import * as os from "node:os";
|
|
14
|
+
import { createSymlink, writeFile, removeFile, removeDir, readFile, fileExists, isDirectory, isSymlink, findSymlinkParent, ensureDir, hashContent, walkDir, } from "../lib/fs.js";
|
|
15
|
+
import { updateGitignore, removeGitignoreSection } from "../lib/gitignore.js";
|
|
16
|
+
import { registry } from "./registry.js";
|
|
17
|
+
import { expandTemplate } from "./template.js";
|
|
18
|
+
import { isUnmanagedCollision, saveState, loadState } from "./manifest.js";
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Output spec resolution
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the OutputSpec for one (item, tool) pair using the registry.
|
|
24
|
+
* Returns null if the tool doesn't support this kind or has no mapping.
|
|
25
|
+
*/
|
|
26
|
+
export function resolveOutputSpec(toolName, item, scope) {
|
|
27
|
+
const mapping = registry.resolveMapping(toolName, item.kind);
|
|
28
|
+
if (!mapping)
|
|
29
|
+
return null;
|
|
30
|
+
const tool = registry.getTool(toolName);
|
|
31
|
+
const sourceExt = path.extname(item.sourcePath);
|
|
32
|
+
const ext = mapping.ext ?? sourceExt;
|
|
33
|
+
const vars = {
|
|
34
|
+
base: tool.basePath[scope],
|
|
35
|
+
home: os.homedir(),
|
|
36
|
+
stem: path.basename(item.sourcePath, sourceExt),
|
|
37
|
+
ext,
|
|
38
|
+
name: path.basename(item.sourcePath),
|
|
39
|
+
relative: item.relativePath,
|
|
40
|
+
kind: item.kind,
|
|
41
|
+
};
|
|
42
|
+
const targetPath = expandTemplate(mapping.path, scope, vars);
|
|
43
|
+
const mode = mapping.mode ??
|
|
44
|
+
(mapping.generate ? "generate" : mapping.transform ? "copy" : "symlink");
|
|
45
|
+
return {
|
|
46
|
+
tool: toolName,
|
|
47
|
+
kind: item.kind,
|
|
48
|
+
sourcePath: item.sourcePath,
|
|
49
|
+
targetPath,
|
|
50
|
+
mode,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Render
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
/**
|
|
57
|
+
* Render one (item, spec) pair to content + hash.
|
|
58
|
+
* No disk I/O — used for planning, token estimation, and copy/generate writes.
|
|
59
|
+
*
|
|
60
|
+
* All items are now file-based (dir-layout items are expanded in planRender).
|
|
61
|
+
*/
|
|
62
|
+
export async function renderOutput(item, spec) {
|
|
63
|
+
const kind = registry.getKind(spec.kind);
|
|
64
|
+
if (!kind)
|
|
65
|
+
throw new Error(`Unknown kind: "${spec.kind}"`);
|
|
66
|
+
const mapping = registry.resolveMapping(spec.tool, spec.kind);
|
|
67
|
+
// generate mode: produce content from a registered generator
|
|
68
|
+
if (mapping?.generate) {
|
|
69
|
+
const content = mapping.generate(item);
|
|
70
|
+
return { content, hash: hashContent(content) };
|
|
71
|
+
}
|
|
72
|
+
// file-layout: read source, optionally transform
|
|
73
|
+
const raw = readFile(item.sourcePath);
|
|
74
|
+
if (mapping?.transform) {
|
|
75
|
+
const transformFn = typeof mapping.transform === "string"
|
|
76
|
+
? registry.getTransform(mapping.transform)
|
|
77
|
+
: mapping.transform;
|
|
78
|
+
if (!transformFn) {
|
|
79
|
+
throw new Error(`Transform "${mapping.transform}" is not registered.`);
|
|
80
|
+
}
|
|
81
|
+
const content = transformFn(raw);
|
|
82
|
+
return { content, hash: hashContent(content) };
|
|
83
|
+
}
|
|
84
|
+
return { content: raw, hash: hashContent(raw) };
|
|
85
|
+
}
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Plan
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
/**
|
|
90
|
+
* Expand a dir-layout item into individual file items.
|
|
91
|
+
* Preserves the subdirectory structure within the directory.
|
|
92
|
+
*/
|
|
93
|
+
function expandDirItem(item, kind) {
|
|
94
|
+
if (kind.layout !== "dir" || !isDirectory(item.sourcePath)) {
|
|
95
|
+
return [item];
|
|
96
|
+
}
|
|
97
|
+
const files = walkDir(item.sourcePath);
|
|
98
|
+
return files.map((relativeFile) => ({
|
|
99
|
+
kind: item.kind,
|
|
100
|
+
sourcePath: path.join(item.sourcePath, relativeFile),
|
|
101
|
+
relativePath: path.join(item.relativePath, relativeFile),
|
|
102
|
+
tools: item.tools,
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Resolve output spec for an expanded file within a dir-layout item.
|
|
107
|
+
* Uses the base directory's mapping but adjusts paths for the specific file.
|
|
108
|
+
*/
|
|
109
|
+
function resolveExpandedOutputSpec(toolName, baseItem, expandedItem, scope) {
|
|
110
|
+
const mapping = registry.resolveMapping(toolName, baseItem.kind);
|
|
111
|
+
if (!mapping)
|
|
112
|
+
return null;
|
|
113
|
+
const tool = registry.getTool(toolName);
|
|
114
|
+
const sourceExt = path.extname(expandedItem.sourcePath);
|
|
115
|
+
const ext = mapping.ext ?? sourceExt;
|
|
116
|
+
// Get the relative path within the skill directory
|
|
117
|
+
const relativeWithinDir = path.relative(baseItem.sourcePath, expandedItem.sourcePath);
|
|
118
|
+
const vars = {
|
|
119
|
+
base: tool.basePath[scope],
|
|
120
|
+
home: os.homedir(),
|
|
121
|
+
stem: path.basename(baseItem.sourcePath), // Use the directory name as stem
|
|
122
|
+
ext,
|
|
123
|
+
name: path.basename(baseItem.sourcePath),
|
|
124
|
+
relative: baseItem.relativePath,
|
|
125
|
+
kind: baseItem.kind,
|
|
126
|
+
};
|
|
127
|
+
// Expand the template to get the base target path (e.g., .cursor/skills/debug)
|
|
128
|
+
const baseTargetPath = expandTemplate(mapping.path, scope, vars);
|
|
129
|
+
// Append the relative file path within the directory
|
|
130
|
+
const targetPath = path.join(baseTargetPath, relativeWithinDir);
|
|
131
|
+
const mode = mapping.mode ??
|
|
132
|
+
(mapping.generate ? "generate" : mapping.transform ? "copy" : "symlink");
|
|
133
|
+
return {
|
|
134
|
+
tool: toolName,
|
|
135
|
+
kind: expandedItem.kind,
|
|
136
|
+
sourcePath: expandedItem.sourcePath,
|
|
137
|
+
targetPath,
|
|
138
|
+
mode,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Compute what would be written for a resolved loadout without touching disk.
|
|
143
|
+
*
|
|
144
|
+
* Dir-layout items (skills) are expanded into individual file outputs,
|
|
145
|
+
* allowing users to have custom files alongside loadout-managed ones.
|
|
146
|
+
*/
|
|
147
|
+
export async function planRender(loadout, projectRoot, scope, statePath) {
|
|
148
|
+
// Use explicit statePath if provided, otherwise fall back to loadout's root.
|
|
149
|
+
// This is critical for bundled loadouts which don't have their own state file—
|
|
150
|
+
// they share state with the scope that activated them.
|
|
151
|
+
const state = loadState(statePath ?? loadout.rootPath);
|
|
152
|
+
const outputs = [];
|
|
153
|
+
const shadowed = [];
|
|
154
|
+
const errors = [];
|
|
155
|
+
for (const item of loadout.items) {
|
|
156
|
+
const kind = registry.getKind(item.kind);
|
|
157
|
+
if (!kind) {
|
|
158
|
+
errors.push(`${item.relativePath}: Unknown kind "${item.kind}"`);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
// Expand dir-layout items into individual files
|
|
162
|
+
const expandedItems = expandDirItem(item, kind);
|
|
163
|
+
for (const expandedItem of expandedItems) {
|
|
164
|
+
for (const toolName of expandedItem.tools) {
|
|
165
|
+
try {
|
|
166
|
+
// Use expanded spec resolver for dir-layout items
|
|
167
|
+
const spec = kind.layout === "dir"
|
|
168
|
+
? resolveExpandedOutputSpec(toolName, item, expandedItem, scope)
|
|
169
|
+
: resolveOutputSpec(toolName, expandedItem, scope);
|
|
170
|
+
if (!spec)
|
|
171
|
+
continue; // tool doesn't support this kind
|
|
172
|
+
if (isUnmanagedCollision(state, spec.targetPath, projectRoot)) {
|
|
173
|
+
shadowed.push({
|
|
174
|
+
tool: spec.tool,
|
|
175
|
+
kind: spec.kind,
|
|
176
|
+
sourcePath: spec.sourcePath,
|
|
177
|
+
targetPath: spec.targetPath,
|
|
178
|
+
});
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
const rendered = await renderOutput(expandedItem, spec);
|
|
182
|
+
outputs.push({ spec, item: expandedItem, hash: rendered.hash });
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
errors.push(`${expandedItem.relativePath} → ${toolName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return { outputs, shadowed, errors };
|
|
191
|
+
}
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// Apply
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
/**
|
|
196
|
+
* Resolve a target path to an absolute path.
|
|
197
|
+
* Handles both relative paths (project scope) and absolute paths (global scope).
|
|
198
|
+
*/
|
|
199
|
+
function resolveTargetPath(targetPath, projectRoot) {
|
|
200
|
+
return path.isAbsolute(targetPath)
|
|
201
|
+
? targetPath
|
|
202
|
+
: path.join(projectRoot, targetPath);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Apply a render plan to disk and save state.
|
|
206
|
+
*
|
|
207
|
+
* `mode` is top-level metadata recorded in the state file; per-output modes
|
|
208
|
+
* live on each spec and govern the actual write strategy.
|
|
209
|
+
*/
|
|
210
|
+
export async function applyPlan(plan, loadout, projectRoot, mode = "symlink", scope = "project") {
|
|
211
|
+
// Remove stale managed outputs not included in the new plan
|
|
212
|
+
const existingState = loadState(loadout.rootPath);
|
|
213
|
+
if (existingState) {
|
|
214
|
+
const newTargets = new Set(plan.outputs.map((o) => o.spec.targetPath));
|
|
215
|
+
for (const entry of existingState.entries) {
|
|
216
|
+
if (!newTargets.has(entry.targetPath)) {
|
|
217
|
+
const fullPath = resolveTargetPath(entry.targetPath, projectRoot);
|
|
218
|
+
if (isDirectory(fullPath))
|
|
219
|
+
removeDir(fullPath);
|
|
220
|
+
else
|
|
221
|
+
removeFile(fullPath);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Write each planned output
|
|
226
|
+
for (const { spec, item } of plan.outputs) {
|
|
227
|
+
const targetPath = resolveTargetPath(spec.targetPath, projectRoot);
|
|
228
|
+
// Clear whatever was there before (including broken symlinks)
|
|
229
|
+
if (fileExists(targetPath) || isDirectory(targetPath) || isSymlink(targetPath)) {
|
|
230
|
+
if (isDirectory(targetPath))
|
|
231
|
+
removeDir(targetPath);
|
|
232
|
+
else
|
|
233
|
+
removeFile(targetPath);
|
|
234
|
+
}
|
|
235
|
+
// Remove any symlinked parent directories (external symlinks)
|
|
236
|
+
const symlinkParent = findSymlinkParent(targetPath);
|
|
237
|
+
if (symlinkParent) {
|
|
238
|
+
removeFile(symlinkParent);
|
|
239
|
+
}
|
|
240
|
+
ensureDir(path.dirname(targetPath));
|
|
241
|
+
if (spec.mode === "symlink") {
|
|
242
|
+
createSymlink(spec.sourcePath, targetPath);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// copy or generate — write rendered content
|
|
246
|
+
const rendered = await renderOutput(item, spec);
|
|
247
|
+
writeFile(targetPath, rendered.content);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Build manifest entries from plan outputs, grouping tools by targetPath
|
|
251
|
+
const outputsByTarget = new Map();
|
|
252
|
+
for (const output of plan.outputs) {
|
|
253
|
+
const existing = outputsByTarget.get(output.spec.targetPath);
|
|
254
|
+
if (existing) {
|
|
255
|
+
existing.tools.add(output.spec.tool);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
outputsByTarget.set(output.spec.targetPath, {
|
|
259
|
+
output,
|
|
260
|
+
tools: new Set([output.spec.tool]),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const entries = Array.from(outputsByTarget.values()).map(({ output: { spec, hash }, tools }) => ({
|
|
265
|
+
tools: Array.from(tools).sort(),
|
|
266
|
+
kind: spec.kind,
|
|
267
|
+
sourcePath: spec.sourcePath,
|
|
268
|
+
targetPath: spec.targetPath,
|
|
269
|
+
mode: spec.mode,
|
|
270
|
+
renderedHash: hash,
|
|
271
|
+
}));
|
|
272
|
+
const newState = {
|
|
273
|
+
active: [loadout.name],
|
|
274
|
+
mode,
|
|
275
|
+
appliedAt: new Date().toISOString(),
|
|
276
|
+
entries,
|
|
277
|
+
shadowed: plan.shadowed,
|
|
278
|
+
};
|
|
279
|
+
saveState(loadout.rootPath, newState);
|
|
280
|
+
// Update .gitignore with managed paths (project scope only)
|
|
281
|
+
if (scope === "project") {
|
|
282
|
+
const managedPaths = plan.outputs.map((o) => o.spec.targetPath);
|
|
283
|
+
updateGitignore(projectRoot, managedPaths);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Apply multiple loadouts, merging their outputs with deduplication by targetPath.
|
|
288
|
+
*/
|
|
289
|
+
export async function applyMultiPlan(plans, loadoutRoot, projectRoot, mode = "symlink", scope = "project") {
|
|
290
|
+
// Merge all outputs, deduplicating by targetPath but collecting all tools
|
|
291
|
+
const outputsByTarget = new Map();
|
|
292
|
+
const mergedShadowed = [];
|
|
293
|
+
const seenShadowedTargets = new Set();
|
|
294
|
+
for (const { plan } of plans) {
|
|
295
|
+
for (const output of plan.outputs) {
|
|
296
|
+
const existing = outputsByTarget.get(output.spec.targetPath);
|
|
297
|
+
if (existing) {
|
|
298
|
+
// Same target path, collect the tool
|
|
299
|
+
existing.tools.add(output.spec.tool);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
// First output for this target
|
|
303
|
+
outputsByTarget.set(output.spec.targetPath, {
|
|
304
|
+
output,
|
|
305
|
+
tools: new Set([output.spec.tool]),
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
for (const s of plan.shadowed) {
|
|
310
|
+
if (!seenShadowedTargets.has(s.targetPath)) {
|
|
311
|
+
seenShadowedTargets.add(s.targetPath);
|
|
312
|
+
mergedShadowed.push(s);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const mergedOutputs = Array.from(outputsByTarget.values());
|
|
317
|
+
// Detect changes
|
|
318
|
+
const existingState = loadState(loadoutRoot);
|
|
319
|
+
const oldEntries = new Map(existingState?.entries.map(e => [e.targetPath, e]) ?? []);
|
|
320
|
+
const newHashes = new Map(mergedOutputs.map(o => [o.output.spec.targetPath, o.output.hash]));
|
|
321
|
+
const updated = [];
|
|
322
|
+
const added = [];
|
|
323
|
+
const removed = [];
|
|
324
|
+
// Find updated and added
|
|
325
|
+
for (const { output } of mergedOutputs) {
|
|
326
|
+
const oldEntry = oldEntries.get(output.spec.targetPath);
|
|
327
|
+
if (!oldEntry) {
|
|
328
|
+
added.push(output.spec.targetPath);
|
|
329
|
+
}
|
|
330
|
+
else if (oldEntry.renderedHash !== output.hash) {
|
|
331
|
+
updated.push(output.spec.targetPath);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// Find removed
|
|
335
|
+
const newTargets = new Set(mergedOutputs.map((o) => o.output.spec.targetPath));
|
|
336
|
+
if (existingState) {
|
|
337
|
+
for (const entry of existingState.entries) {
|
|
338
|
+
if (!newTargets.has(entry.targetPath)) {
|
|
339
|
+
removed.push(entry.targetPath);
|
|
340
|
+
const fullPath = resolveTargetPath(entry.targetPath, projectRoot);
|
|
341
|
+
if (isDirectory(fullPath))
|
|
342
|
+
removeDir(fullPath);
|
|
343
|
+
else
|
|
344
|
+
removeFile(fullPath);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// Write each merged output
|
|
349
|
+
const byTool = new Map();
|
|
350
|
+
for (const { output: { spec, item } } of mergedOutputs) {
|
|
351
|
+
const targetPath = resolveTargetPath(spec.targetPath, projectRoot);
|
|
352
|
+
// Clear whatever was there before
|
|
353
|
+
if (fileExists(targetPath) || isDirectory(targetPath) || isSymlink(targetPath)) {
|
|
354
|
+
if (isDirectory(targetPath))
|
|
355
|
+
removeDir(targetPath);
|
|
356
|
+
else
|
|
357
|
+
removeFile(targetPath);
|
|
358
|
+
}
|
|
359
|
+
// Remove any symlinked parent directories (external symlinks)
|
|
360
|
+
const symlinkParent = findSymlinkParent(targetPath);
|
|
361
|
+
if (symlinkParent) {
|
|
362
|
+
removeFile(symlinkParent);
|
|
363
|
+
}
|
|
364
|
+
ensureDir(path.dirname(targetPath));
|
|
365
|
+
if (spec.mode === "symlink") {
|
|
366
|
+
createSymlink(spec.sourcePath, targetPath);
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
// copy or generate — write rendered content
|
|
370
|
+
const rendered = await renderOutput(item, spec);
|
|
371
|
+
writeFile(targetPath, rendered.content);
|
|
372
|
+
}
|
|
373
|
+
byTool.set(spec.tool, (byTool.get(spec.tool) || 0) + 1);
|
|
374
|
+
}
|
|
375
|
+
// Build manifest entries with all tools that share each output
|
|
376
|
+
const entries = mergedOutputs.map(({ output: { spec, hash }, tools }) => ({
|
|
377
|
+
tools: Array.from(tools).sort(),
|
|
378
|
+
kind: spec.kind,
|
|
379
|
+
sourcePath: spec.sourcePath,
|
|
380
|
+
targetPath: spec.targetPath,
|
|
381
|
+
mode: spec.mode,
|
|
382
|
+
renderedHash: hash,
|
|
383
|
+
}));
|
|
384
|
+
const activeNames = plans.map((p) => p.loadout.name);
|
|
385
|
+
const newState = {
|
|
386
|
+
active: activeNames,
|
|
387
|
+
mode,
|
|
388
|
+
appliedAt: new Date().toISOString(),
|
|
389
|
+
entries,
|
|
390
|
+
shadowed: mergedShadowed,
|
|
391
|
+
};
|
|
392
|
+
saveState(loadoutRoot, newState);
|
|
393
|
+
// Update .gitignore with managed paths (project scope only)
|
|
394
|
+
if (scope === "project") {
|
|
395
|
+
const managedPaths = mergedOutputs.map((o) => o.output.spec.targetPath);
|
|
396
|
+
updateGitignore(projectRoot, managedPaths);
|
|
397
|
+
}
|
|
398
|
+
return {
|
|
399
|
+
totalOutputs: mergedOutputs.length,
|
|
400
|
+
byTool,
|
|
401
|
+
changes: { updated, added, removed },
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
// ---------------------------------------------------------------------------
|
|
405
|
+
// Remove
|
|
406
|
+
// ---------------------------------------------------------------------------
|
|
407
|
+
/**
|
|
408
|
+
* Remove all managed outputs recorded in the state file.
|
|
409
|
+
* Does NOT clear the state file — callers decide whether to call clearState().
|
|
410
|
+
* Also removes the loadout-managed section from .gitignore (project scope only).
|
|
411
|
+
*/
|
|
412
|
+
export async function removeManaged(loadoutRoot, projectRoot, scope = "project") {
|
|
413
|
+
const state = loadState(loadoutRoot);
|
|
414
|
+
const removed = [];
|
|
415
|
+
const missing = [];
|
|
416
|
+
if (!state)
|
|
417
|
+
return { removed, missing };
|
|
418
|
+
for (const entry of state.entries) {
|
|
419
|
+
const fullPath = resolveTargetPath(entry.targetPath, projectRoot);
|
|
420
|
+
if (fileExists(fullPath) || isDirectory(fullPath)) {
|
|
421
|
+
if (isDirectory(fullPath))
|
|
422
|
+
removeDir(fullPath);
|
|
423
|
+
else
|
|
424
|
+
removeFile(fullPath);
|
|
425
|
+
removed.push(entry.targetPath);
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
missing.push(entry.targetPath);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
// Remove now-empty parent directories
|
|
432
|
+
const dirs = new Set();
|
|
433
|
+
for (const entry of state.entries) {
|
|
434
|
+
let dir = path.dirname(resolveTargetPath(entry.targetPath, projectRoot));
|
|
435
|
+
while (dir !== projectRoot && dir !== path.dirname(dir)) {
|
|
436
|
+
dirs.add(dir);
|
|
437
|
+
dir = path.dirname(dir);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const sortedDirs = [...dirs].sort((a, b) => b.split(path.sep).length - a.split(path.sep).length);
|
|
441
|
+
const fs = await import("node:fs");
|
|
442
|
+
for (const dir of sortedDirs) {
|
|
443
|
+
try {
|
|
444
|
+
if (fs.readdirSync(dir).length === 0)
|
|
445
|
+
removeDir(dir);
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
// Ignore — dir may not exist or may be unremovable
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
// Clean up .gitignore (project scope only)
|
|
452
|
+
if (scope === "project") {
|
|
453
|
+
removeGitignoreSection(projectRoot);
|
|
454
|
+
}
|
|
455
|
+
return { removed, missing };
|
|
456
|
+
}
|
|
457
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/core/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve loadout graphs and included items
|
|
3
|
+
*/
|
|
4
|
+
import type { LoadoutRoot, ResolvedItem, ResolvedLoadout, Tool, RootConfig, CommandContext } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Resolve a loadout by name.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveLoadout(name: string, roots: LoadoutRoot[], rootConfig?: RootConfig): ResolvedLoadout;
|
|
9
|
+
/**
|
|
10
|
+
* Check if instructions (AGENTS.md) exist in the loadout root.
|
|
11
|
+
*/
|
|
12
|
+
export declare function hasInstructions(loadoutRoot: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Get the instruction item if it exists.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getInstructionItem(loadoutRoot: string, tools: Tool[]): ResolvedItem | null;
|
|
17
|
+
/**
|
|
18
|
+
* Result of loading and fully resolving a loadout for a command context.
|
|
19
|
+
*/
|
|
20
|
+
export interface LoadResult {
|
|
21
|
+
loadout: ResolvedLoadout;
|
|
22
|
+
rootConfig: RootConfig;
|
|
23
|
+
loadoutName: string;
|
|
24
|
+
roots: LoadoutRoot[];
|
|
25
|
+
sourceWarnings: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Discover roots, parse root config, resolve the loadout, and attach the
|
|
29
|
+
* instruction item if present. Throws on any failure — callers decide whether
|
|
30
|
+
* to exit. This consolidates the pattern previously duplicated across apply,
|
|
31
|
+
* diff, info, init, and global commands.
|
|
32
|
+
*
|
|
33
|
+
* Root collection order:
|
|
34
|
+
* 1. Primary .loadouts/ (from ctx.configPath)
|
|
35
|
+
* 2. Sources declared in loadout.yaml (transitively)
|
|
36
|
+
* 3. Global ~/.config/loadouts/ (lowest priority)
|
|
37
|
+
*/
|
|
38
|
+
export declare function loadResolvedLoadout(ctx: CommandContext, name?: string): Promise<LoadResult>;
|
|
39
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/core/resolve.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,OAAO,KAAK,EACV,WAAW,EAGX,YAAY,EACZ,eAAe,EACf,IAAI,EACJ,UAAU,EACV,cAAc,EACf,MAAM,YAAY,CAAC;AAGpB;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAAE,EACpB,UAAU,CAAC,EAAE,UAAU,GACtB,eAAe,CAyBjB;AAoCD;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,IAAI,EAAE,GACZ,YAAY,GAAG,IAAI,CAarB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,cAAc,EACnB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,CAuCrB"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve loadout graphs and included items
|
|
3
|
+
*/
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { findLoadoutDefinition, parseRootConfig, } from "./config.js";
|
|
6
|
+
import { registry } from "./registry.js";
|
|
7
|
+
import { loadYamlKindsFromRoots } from "./kindLoader.js";
|
|
8
|
+
import { fileExists, isDirectory } from "../lib/fs.js";
|
|
9
|
+
import { discoverLoadoutRoots, getGlobalRoot, collectRootsWithSources } from "./discovery.js";
|
|
10
|
+
import { BUILTIN_TOOL_NAMES } from "../builtins/index.js";
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a loadout by name.
|
|
13
|
+
*/
|
|
14
|
+
export function resolveLoadout(name, roots, rootConfig) {
|
|
15
|
+
// Load any YAML-defined kinds from the discovered roots before resolving
|
|
16
|
+
// items, so inferKind() can match custom kinds. Idempotent.
|
|
17
|
+
loadYamlKindsFromRoots(roots);
|
|
18
|
+
const found = findLoadoutDefinition(name, roots);
|
|
19
|
+
if (!found) {
|
|
20
|
+
throw new Error(`Loadout not found: ${name}`);
|
|
21
|
+
}
|
|
22
|
+
const { definition, rootPath } = found;
|
|
23
|
+
const effectiveTools = definition.tools || rootConfig?.tools || [...BUILTIN_TOOL_NAMES];
|
|
24
|
+
const items = [];
|
|
25
|
+
for (const include of definition.include || []) {
|
|
26
|
+
items.push(resolveInclude(include, rootPath, effectiveTools));
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
name,
|
|
30
|
+
description: definition.description,
|
|
31
|
+
tools: effectiveTools,
|
|
32
|
+
items,
|
|
33
|
+
rootPath,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a single include entry to a ResolvedItem.
|
|
38
|
+
*/
|
|
39
|
+
function resolveInclude(include, rootPath, defaultTools) {
|
|
40
|
+
const relativePath = typeof include === "string" ? include : include.path;
|
|
41
|
+
const tools = typeof include === "object" && include.tools
|
|
42
|
+
? include.tools
|
|
43
|
+
: defaultTools;
|
|
44
|
+
const sourcePath = path.join(rootPath, relativePath);
|
|
45
|
+
// Validate the source exists
|
|
46
|
+
if (!fileExists(sourcePath) && !isDirectory(sourcePath)) {
|
|
47
|
+
throw new Error(`Include not found: ${relativePath} (in ${rootPath})`);
|
|
48
|
+
}
|
|
49
|
+
const kind = registry.inferKind(relativePath);
|
|
50
|
+
if (!kind) {
|
|
51
|
+
throw new Error(`Cannot infer artifact kind for path: ${relativePath}`);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
kind,
|
|
55
|
+
sourcePath,
|
|
56
|
+
relativePath,
|
|
57
|
+
tools,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check if instructions (AGENTS.md) exist in the loadout root.
|
|
62
|
+
*/
|
|
63
|
+
export function hasInstructions(loadoutRoot) {
|
|
64
|
+
return fileExists(path.join(loadoutRoot, "AGENTS.md"));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get the instruction item if it exists.
|
|
68
|
+
*/
|
|
69
|
+
export function getInstructionItem(loadoutRoot, tools) {
|
|
70
|
+
const sourcePath = path.join(loadoutRoot, "AGENTS.md");
|
|
71
|
+
if (!fileExists(sourcePath)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
kind: "instruction",
|
|
76
|
+
sourcePath,
|
|
77
|
+
relativePath: "AGENTS.md",
|
|
78
|
+
tools,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Discover roots, parse root config, resolve the loadout, and attach the
|
|
83
|
+
* instruction item if present. Throws on any failure — callers decide whether
|
|
84
|
+
* to exit. This consolidates the pattern previously duplicated across apply,
|
|
85
|
+
* diff, info, init, and global commands.
|
|
86
|
+
*
|
|
87
|
+
* Root collection order:
|
|
88
|
+
* 1. Primary .loadouts/ (from ctx.configPath)
|
|
89
|
+
* 2. Sources declared in loadout.yaml (transitively)
|
|
90
|
+
* 3. Global ~/.config/loadouts/ (lowest priority)
|
|
91
|
+
*/
|
|
92
|
+
export async function loadResolvedLoadout(ctx, name) {
|
|
93
|
+
let roots;
|
|
94
|
+
let sourceWarnings = [];
|
|
95
|
+
if (ctx.scope === "global") {
|
|
96
|
+
const globalRoot = getGlobalRoot();
|
|
97
|
+
if (!globalRoot) {
|
|
98
|
+
throw new Error("No global loadout found at ~/.config/loadouts");
|
|
99
|
+
}
|
|
100
|
+
// Global scope: just the global root, plus any sources it declares
|
|
101
|
+
const collected = collectRootsWithSources(globalRoot, false);
|
|
102
|
+
roots = collected.roots;
|
|
103
|
+
sourceWarnings = collected.warnings;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
// Project scope: start with the nearest .loadouts/, collect sources
|
|
107
|
+
const discovered = await discoverLoadoutRoots(ctx.projectRoot);
|
|
108
|
+
if (discovered.length === 0) {
|
|
109
|
+
throw new Error("No .loadouts/ directory found. Run 'loadouts init' first.");
|
|
110
|
+
}
|
|
111
|
+
const primaryRoot = discovered[0];
|
|
112
|
+
const collected = collectRootsWithSources(primaryRoot, true);
|
|
113
|
+
roots = collected.roots;
|
|
114
|
+
sourceWarnings = collected.warnings;
|
|
115
|
+
}
|
|
116
|
+
const rootConfig = parseRootConfig(ctx.configPath);
|
|
117
|
+
const loadoutName = name || rootConfig.default || "base";
|
|
118
|
+
const loadout = resolveLoadout(loadoutName, roots, rootConfig);
|
|
119
|
+
// Auto-inject AGENTS.md only when not already in the loadout's include list.
|
|
120
|
+
const alreadyHasInstruction = loadout.items.some((i) => i.relativePath === "AGENTS.md");
|
|
121
|
+
if (!alreadyHasInstruction) {
|
|
122
|
+
const instructionItem = getInstructionItem(ctx.configPath, loadout.tools);
|
|
123
|
+
if (instructionItem)
|
|
124
|
+
loadout.items.push(instructionItem);
|
|
125
|
+
}
|
|
126
|
+
return { loadout, rootConfig, loadoutName, roots, sourceWarnings };
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/core/resolve.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EACL,qBAAqB,EACrB,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAW9F,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,KAAoB,EACpB,UAAuB;IAEvB,yEAAyE;IACzE,4DAA4D;IAC5D,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAE9B,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACvC,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,IAAI,UAAU,EAAE,KAAK,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC;IAExF,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,KAAK,MAAM,OAAO,IAAI,UAAU,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,OAAO;QACL,IAAI;QACJ,WAAW,EAAE,UAAU,CAAC,WAAW;QACnC,KAAK,EAAE,cAAc;QACrB,KAAK;QACL,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,OAAuB,EACvB,QAAgB,EAChB,YAAoB;IAEpB,MAAM,YAAY,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IAC1E,MAAM,KAAK,GACT,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK;QAC1C,CAAC,CAAC,OAAO,CAAC,KAAK;QACf,CAAC,CAAC,YAAY,CAAC;IAEnB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAErD,6BAA6B;IAC7B,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,sBAAsB,YAAY,QAAQ,QAAQ,GAAG,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,wCAAwC,YAAY,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO;QACL,IAAI;QACJ,UAAU;QACV,YAAY;QACZ,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,KAAa;IAEb,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAEvD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,UAAU;QACV,YAAY,EAAE,WAAW;QACzB,KAAK;KACN,CAAC;AACJ,CAAC;AAaD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAmB,EACnB,IAAa;IAEb,IAAI,KAAoB,CAAC;IACzB,IAAI,cAAc,GAAa,EAAE,CAAC;IAElC,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QACD,mEAAmE;QACnE,MAAM,SAAS,GAAG,uBAAuB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAC7D,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QACxB,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,oEAAoE;QACpE,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC/D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC/E,CAAC;QACD,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,uBAAuB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC7D,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QACxB,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC;IACtC,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,IAAI,IAAI,UAAU,CAAC,OAAO,IAAI,MAAM,CAAC;IACzD,MAAM,OAAO,GAAG,cAAc,CAAC,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAE/D,6EAA6E;IAC7E,MAAM,qBAAqB,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAC9C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,WAAW,CACtC,CAAC;IACF,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,MAAM,eAAe,GAAG,kBAAkB,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC1E,IAAI,eAAe;YAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;AACrE,CAAC"}
|