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,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import Discovery — scan tool directories for existing configurations
|
|
3
|
+
* that can be imported into loadout.
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
import { fileExists, isDirectory, isSymlink, listFiles, listFilesWithExtension } from "../lib/fs.js";
|
|
8
|
+
const TOOL_LOCATIONS = {
|
|
9
|
+
"claude-code": {
|
|
10
|
+
rules: { dir: ".claude/rules", ext: ".md" },
|
|
11
|
+
skills: { dir: ".claude/skills" },
|
|
12
|
+
},
|
|
13
|
+
cursor: {
|
|
14
|
+
rules: { dir: ".cursor/rules", ext: ".mdc" },
|
|
15
|
+
skills: { dir: ".cursor/skills" },
|
|
16
|
+
},
|
|
17
|
+
opencode: {
|
|
18
|
+
rules: { dir: ".opencode/rules", ext: ".md" },
|
|
19
|
+
skills: { dir: ".opencode/skills" },
|
|
20
|
+
},
|
|
21
|
+
codex: {
|
|
22
|
+
// codex doesn't support rules
|
|
23
|
+
skills: { dir: ".agents/skills" },
|
|
24
|
+
},
|
|
25
|
+
pi: {
|
|
26
|
+
// pi doesn't have native rules support
|
|
27
|
+
skills: { dir: ".pi/skills" },
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
// Instruction file locations to check (in priority order)
|
|
31
|
+
const INSTRUCTION_FILES = ["AGENTS.md", "CLAUDE.md"];
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Discovery functions
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
/**
|
|
36
|
+
* Get file/directory size.
|
|
37
|
+
*/
|
|
38
|
+
function getSize(filePath) {
|
|
39
|
+
const stat = fs.statSync(filePath);
|
|
40
|
+
if (stat.isDirectory()) {
|
|
41
|
+
let total = 0;
|
|
42
|
+
const entries = fs.readdirSync(filePath, { withFileTypes: true });
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
total += getSize(path.join(filePath, entry.name));
|
|
45
|
+
}
|
|
46
|
+
return total;
|
|
47
|
+
}
|
|
48
|
+
return stat.size;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get modification time.
|
|
52
|
+
*/
|
|
53
|
+
function getMtime(filePath) {
|
|
54
|
+
return fs.statSync(filePath).mtime;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Discover rules in a tool directory.
|
|
58
|
+
*/
|
|
59
|
+
function discoverRules(projectRoot, tool, locations) {
|
|
60
|
+
if (!locations.rules)
|
|
61
|
+
return [];
|
|
62
|
+
const rulesDir = path.join(projectRoot, locations.rules.dir);
|
|
63
|
+
if (!isDirectory(rulesDir))
|
|
64
|
+
return [];
|
|
65
|
+
const artifacts = [];
|
|
66
|
+
const files = listFilesWithExtension(rulesDir, locations.rules.ext);
|
|
67
|
+
for (const file of files) {
|
|
68
|
+
const sourcePath = path.join(rulesDir, file);
|
|
69
|
+
const name = file.replace(/\.(md|mdc)$/, "");
|
|
70
|
+
artifacts.push({
|
|
71
|
+
kind: "rule",
|
|
72
|
+
name,
|
|
73
|
+
sourcePath,
|
|
74
|
+
displayPath: path.join(locations.rules.dir, file),
|
|
75
|
+
tool,
|
|
76
|
+
size: getSize(sourcePath),
|
|
77
|
+
mtime: getMtime(sourcePath),
|
|
78
|
+
destPath: `rules/${name}.md`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return artifacts;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Discover skills in a tool directory.
|
|
85
|
+
* Skips symlinked directories that point to other tool directories
|
|
86
|
+
* to avoid duplicate detection.
|
|
87
|
+
*/
|
|
88
|
+
function discoverSkills(projectRoot, tool, locations) {
|
|
89
|
+
if (!locations.skills)
|
|
90
|
+
return [];
|
|
91
|
+
const skillsDir = path.join(projectRoot, locations.skills.dir);
|
|
92
|
+
if (!isDirectory(skillsDir))
|
|
93
|
+
return [];
|
|
94
|
+
// Skip if this skills dir is a symlink pointing to another tool's directory
|
|
95
|
+
// (e.g., .cursor/skills -> ../.claude/skills)
|
|
96
|
+
if (isSymlink(skillsDir)) {
|
|
97
|
+
try {
|
|
98
|
+
const target = fs.realpathSync(skillsDir);
|
|
99
|
+
// Check if target is inside another tool's directory
|
|
100
|
+
for (const [otherTool, otherLoc] of Object.entries(TOOL_LOCATIONS)) {
|
|
101
|
+
if (otherTool === tool || !otherLoc.skills)
|
|
102
|
+
continue;
|
|
103
|
+
const otherSkillsDir = path.join(projectRoot, otherLoc.skills.dir);
|
|
104
|
+
if (target.startsWith(fs.realpathSync(path.dirname(otherSkillsDir)))) {
|
|
105
|
+
// This is a symlink to another tool's skills - skip to avoid duplicates
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// If we can't resolve the symlink, proceed normally
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const artifacts = [];
|
|
115
|
+
const entries = listFiles(skillsDir);
|
|
116
|
+
for (const entry of entries) {
|
|
117
|
+
const skillPath = path.join(skillsDir, entry);
|
|
118
|
+
if (!isDirectory(skillPath))
|
|
119
|
+
continue;
|
|
120
|
+
// Check for SKILL.md to confirm it's a valid skill
|
|
121
|
+
const skillMdPath = path.join(skillPath, "SKILL.md");
|
|
122
|
+
if (!fileExists(skillMdPath))
|
|
123
|
+
continue;
|
|
124
|
+
artifacts.push({
|
|
125
|
+
kind: "skill",
|
|
126
|
+
name: entry,
|
|
127
|
+
sourcePath: skillPath,
|
|
128
|
+
displayPath: path.join(locations.skills.dir, entry),
|
|
129
|
+
tool,
|
|
130
|
+
size: getSize(skillPath),
|
|
131
|
+
mtime: getMtime(skillPath),
|
|
132
|
+
destPath: `skills/${entry}`,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return artifacts;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Check if a file at project root is managed by loadout.
|
|
139
|
+
* A file is managed if it's a symlink pointing into .loadouts/.
|
|
140
|
+
*/
|
|
141
|
+
function isManagedByLoadout(filePath, loadoutPath) {
|
|
142
|
+
if (!loadoutPath)
|
|
143
|
+
return false;
|
|
144
|
+
if (!isSymlink(filePath))
|
|
145
|
+
return false;
|
|
146
|
+
try {
|
|
147
|
+
const target = fs.readlinkSync(filePath);
|
|
148
|
+
const absoluteTarget = path.isAbsolute(target)
|
|
149
|
+
? target
|
|
150
|
+
: path.resolve(path.dirname(filePath), target);
|
|
151
|
+
return absoluteTarget.startsWith(loadoutPath);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if a file is the auto-generated CLAUDE.md wrapper.
|
|
159
|
+
*/
|
|
160
|
+
function isClaudeWrapper(filePath) {
|
|
161
|
+
if (!fileExists(filePath))
|
|
162
|
+
return false;
|
|
163
|
+
try {
|
|
164
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
165
|
+
return content.includes("auto-generated by Loadout") || content.includes("auto-generated by Loadouts");
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Discover instruction files at project root.
|
|
173
|
+
* Only discovers files that are NOT managed by loadout.
|
|
174
|
+
*/
|
|
175
|
+
function discoverInstructions(projectRoot, loadoutPath) {
|
|
176
|
+
const artifacts = [];
|
|
177
|
+
for (const filename of INSTRUCTION_FILES) {
|
|
178
|
+
const filePath = path.join(projectRoot, filename);
|
|
179
|
+
if (!fileExists(filePath))
|
|
180
|
+
continue;
|
|
181
|
+
// Skip if this file is managed by loadout (symlink to .loadouts/)
|
|
182
|
+
if (isManagedByLoadout(filePath, loadoutPath))
|
|
183
|
+
continue;
|
|
184
|
+
// Skip auto-generated CLAUDE.md wrapper
|
|
185
|
+
if (filename === "CLAUDE.md" && isClaudeWrapper(filePath))
|
|
186
|
+
continue;
|
|
187
|
+
artifacts.push({
|
|
188
|
+
kind: "instruction",
|
|
189
|
+
name: "AGENTS.md",
|
|
190
|
+
sourcePath: filePath,
|
|
191
|
+
displayPath: filename,
|
|
192
|
+
tool: "project-root",
|
|
193
|
+
size: getSize(filePath),
|
|
194
|
+
mtime: getMtime(filePath),
|
|
195
|
+
destPath: "instructions/AGENTS.base.md", // Will be updated by install based on target loadout
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
return artifacts;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Check if an artifact already exists in .loadouts/.
|
|
202
|
+
* For instructions, we DON'T filter them out since unmanaged files at project root
|
|
203
|
+
* should be offered for import (to replace the template).
|
|
204
|
+
*/
|
|
205
|
+
function artifactExistsInLoadout(loadoutPath, artifact) {
|
|
206
|
+
// Instructions at project root are already filtered by discoverInstructions
|
|
207
|
+
// if they're managed. If they reach here, they're unmanaged and should be imported.
|
|
208
|
+
if (artifact.kind === "instruction") {
|
|
209
|
+
return false; // Always offer to import unmanaged instruction files
|
|
210
|
+
}
|
|
211
|
+
const destPath = path.join(loadoutPath, artifact.destPath);
|
|
212
|
+
return artifact.kind === "skill" ? isDirectory(destPath) : fileExists(destPath);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Discover all importable artifacts in a project.
|
|
216
|
+
*/
|
|
217
|
+
export function discoverImportableArtifacts(projectRoot, options = {}) {
|
|
218
|
+
const artifacts = [];
|
|
219
|
+
const warnings = [];
|
|
220
|
+
const { tools, kinds, loadoutPath } = options;
|
|
221
|
+
// Filter tools if specified
|
|
222
|
+
const toolsToScan = tools
|
|
223
|
+
? Object.keys(TOOL_LOCATIONS).filter((t) => tools.includes(t))
|
|
224
|
+
: Object.keys(TOOL_LOCATIONS);
|
|
225
|
+
// Discover from each tool directory
|
|
226
|
+
for (const tool of toolsToScan) {
|
|
227
|
+
const locations = TOOL_LOCATIONS[tool];
|
|
228
|
+
// Rules
|
|
229
|
+
if (!kinds || kinds.includes("rule")) {
|
|
230
|
+
artifacts.push(...discoverRules(projectRoot, tool, locations));
|
|
231
|
+
}
|
|
232
|
+
// Skills
|
|
233
|
+
if (!kinds || kinds.includes("skill")) {
|
|
234
|
+
artifacts.push(...discoverSkills(projectRoot, tool, locations));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Instructions (not tool-specific)
|
|
238
|
+
if (!kinds || kinds.includes("instruction")) {
|
|
239
|
+
artifacts.push(...discoverInstructions(projectRoot, loadoutPath));
|
|
240
|
+
}
|
|
241
|
+
// Filter out artifacts that already exist in .loadouts/
|
|
242
|
+
const filteredArtifacts = loadoutPath
|
|
243
|
+
? artifacts.filter((a) => !artifactExistsInLoadout(loadoutPath, a))
|
|
244
|
+
: artifacts;
|
|
245
|
+
// Detect conflicts (same name from different tools)
|
|
246
|
+
const byName = new Map();
|
|
247
|
+
for (const artifact of filteredArtifacts) {
|
|
248
|
+
const key = `${artifact.kind}:${artifact.name}`;
|
|
249
|
+
const existing = byName.get(key) || [];
|
|
250
|
+
existing.push(artifact);
|
|
251
|
+
byName.set(key, existing);
|
|
252
|
+
}
|
|
253
|
+
const conflicts = new Map();
|
|
254
|
+
for (const [key, items] of byName) {
|
|
255
|
+
if (items.length > 1) {
|
|
256
|
+
conflicts.set(key, items);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return { artifacts: filteredArtifacts, conflicts, warnings };
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Group artifacts by kind for display.
|
|
263
|
+
*/
|
|
264
|
+
export function groupByKind(artifacts) {
|
|
265
|
+
const groups = {
|
|
266
|
+
instruction: [],
|
|
267
|
+
rule: [],
|
|
268
|
+
skill: [],
|
|
269
|
+
};
|
|
270
|
+
for (const artifact of artifacts) {
|
|
271
|
+
groups[artifact.kind].push(artifact);
|
|
272
|
+
}
|
|
273
|
+
return groups;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Format file size for display.
|
|
277
|
+
*/
|
|
278
|
+
export function formatSize(bytes) {
|
|
279
|
+
if (bytes < 1024)
|
|
280
|
+
return `${bytes} B`;
|
|
281
|
+
if (bytes < 1024 * 1024)
|
|
282
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
283
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Format relative time for display.
|
|
287
|
+
*/
|
|
288
|
+
export function formatRelativeTime(date) {
|
|
289
|
+
const now = new Date();
|
|
290
|
+
const diffMs = now.getTime() - date.getTime();
|
|
291
|
+
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
292
|
+
if (diffDays === 0)
|
|
293
|
+
return "today";
|
|
294
|
+
if (diffDays === 1)
|
|
295
|
+
return "yesterday";
|
|
296
|
+
if (diffDays < 7)
|
|
297
|
+
return `${diffDays} days ago`;
|
|
298
|
+
if (diffDays < 30)
|
|
299
|
+
return `${Math.floor(diffDays / 7)} weeks ago`;
|
|
300
|
+
if (diffDays < 365)
|
|
301
|
+
return `${Math.floor(diffDays / 30)} months ago`;
|
|
302
|
+
return `${Math.floor(diffDays / 365)} years ago`;
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=import-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-discovery.js","sourceRoot":"","sources":["../../src/core/import-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAML kind loader — reads *.yaml / *.yml files from .loadouts/kinds/ directories
|
|
3
|
+
* and registers them as KindSpec entries in the registry.
|
|
4
|
+
*
|
|
5
|
+
* Declarative kind files let teams add new artifact types without writing code.
|
|
6
|
+
* See plans/EXTENSIBILITY.md §3a for the full format.
|
|
7
|
+
*
|
|
8
|
+
* Loading is idempotent: kind IDs already present in the registry are skipped
|
|
9
|
+
* with a warning (built-ins always take precedence over YAML definitions).
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import { type KindSpec } from "./registry.js";
|
|
13
|
+
import type { LoadoutRoot } from "./types.js";
|
|
14
|
+
export declare const YamlKindSchema: z.ZodObject<{
|
|
15
|
+
/**
|
|
16
|
+
* Unique kind identifier. Convention: namespace with a dot (e.g. "myteam.prompt")
|
|
17
|
+
* to avoid collision with built-ins ("rule", "skill", "instruction") and other teams.
|
|
18
|
+
*/
|
|
19
|
+
id: z.ZodString;
|
|
20
|
+
description: z.ZodOptional<z.ZodString>;
|
|
21
|
+
detect: z.ZodUnion<[z.ZodObject<{
|
|
22
|
+
pathPrefix: z.ZodString;
|
|
23
|
+
}, "strip", z.ZodTypeAny, {
|
|
24
|
+
pathPrefix: string;
|
|
25
|
+
}, {
|
|
26
|
+
pathPrefix: string;
|
|
27
|
+
}>, z.ZodObject<{
|
|
28
|
+
pathExact: z.ZodString;
|
|
29
|
+
}, "strip", z.ZodTypeAny, {
|
|
30
|
+
pathExact: string;
|
|
31
|
+
}, {
|
|
32
|
+
pathExact: string;
|
|
33
|
+
}>]>;
|
|
34
|
+
layout: z.ZodEnum<["file", "dir"]>;
|
|
35
|
+
targets: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
36
|
+
path: z.ZodUnion<[z.ZodString, z.ZodObject<{
|
|
37
|
+
project: z.ZodString;
|
|
38
|
+
global: z.ZodString;
|
|
39
|
+
}, "strip", z.ZodTypeAny, {
|
|
40
|
+
global: string;
|
|
41
|
+
project: string;
|
|
42
|
+
}, {
|
|
43
|
+
global: string;
|
|
44
|
+
project: string;
|
|
45
|
+
}>]>;
|
|
46
|
+
ext: z.ZodOptional<z.ZodString>;
|
|
47
|
+
mode: z.ZodOptional<z.ZodEnum<["symlink", "copy"]>>;
|
|
48
|
+
transform: z.ZodOptional<z.ZodString>;
|
|
49
|
+
}, "strip", z.ZodTypeAny, {
|
|
50
|
+
path: string | {
|
|
51
|
+
global: string;
|
|
52
|
+
project: string;
|
|
53
|
+
};
|
|
54
|
+
mode?: "symlink" | "copy" | undefined;
|
|
55
|
+
ext?: string | undefined;
|
|
56
|
+
transform?: string | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
path: string | {
|
|
59
|
+
global: string;
|
|
60
|
+
project: string;
|
|
61
|
+
};
|
|
62
|
+
mode?: "symlink" | "copy" | undefined;
|
|
63
|
+
ext?: string | undefined;
|
|
64
|
+
transform?: string | undefined;
|
|
65
|
+
}>>>;
|
|
66
|
+
}, "strip", z.ZodTypeAny, {
|
|
67
|
+
id: string;
|
|
68
|
+
detect: {
|
|
69
|
+
pathPrefix: string;
|
|
70
|
+
} | {
|
|
71
|
+
pathExact: string;
|
|
72
|
+
};
|
|
73
|
+
layout: "file" | "dir";
|
|
74
|
+
targets?: Record<string, {
|
|
75
|
+
path: string | {
|
|
76
|
+
global: string;
|
|
77
|
+
project: string;
|
|
78
|
+
};
|
|
79
|
+
mode?: "symlink" | "copy" | undefined;
|
|
80
|
+
ext?: string | undefined;
|
|
81
|
+
transform?: string | undefined;
|
|
82
|
+
}> | undefined;
|
|
83
|
+
description?: string | undefined;
|
|
84
|
+
}, {
|
|
85
|
+
id: string;
|
|
86
|
+
detect: {
|
|
87
|
+
pathPrefix: string;
|
|
88
|
+
} | {
|
|
89
|
+
pathExact: string;
|
|
90
|
+
};
|
|
91
|
+
layout: "file" | "dir";
|
|
92
|
+
targets?: Record<string, {
|
|
93
|
+
path: string | {
|
|
94
|
+
global: string;
|
|
95
|
+
project: string;
|
|
96
|
+
};
|
|
97
|
+
mode?: "symlink" | "copy" | undefined;
|
|
98
|
+
ext?: string | undefined;
|
|
99
|
+
transform?: string | undefined;
|
|
100
|
+
}> | undefined;
|
|
101
|
+
description?: string | undefined;
|
|
102
|
+
}>;
|
|
103
|
+
export type YamlKindDefinition = z.infer<typeof YamlKindSchema>;
|
|
104
|
+
/**
|
|
105
|
+
* Parse a YAML kind definition file into a KindSpec.
|
|
106
|
+
*/
|
|
107
|
+
export declare function parseYamlKind(filePath: string): KindSpec;
|
|
108
|
+
/**
|
|
109
|
+
* Load all YAML kinds from the `kinds/` subdirectory of each discovered root
|
|
110
|
+
* and register them into the global registry.
|
|
111
|
+
*
|
|
112
|
+
* Already-registered IDs are skipped with a warning (built-ins win).
|
|
113
|
+
* Parse errors are reported but do not abort loading.
|
|
114
|
+
*
|
|
115
|
+
* This is called synchronously from `resolveLoadout` after root discovery,
|
|
116
|
+
* so YAML kinds are available for `inferKind()` during item resolution.
|
|
117
|
+
*/
|
|
118
|
+
export declare function loadYamlKindsFromRoots(roots: LoadoutRoot[]): void;
|
|
119
|
+
//# sourceMappingURL=kindLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kindLoader.d.ts","sourceRoot":"","sources":["../../src/core/kindLoader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAY,KAAK,QAAQ,EAAyC,MAAM,eAAe,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAuB9C,eAAO,MAAM,cAAc;IACzB;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMH,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAMhE;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CA2BxD;AAqBD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,CAyCjE"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAML kind loader — reads *.yaml / *.yml files from .loadouts/kinds/ directories
|
|
3
|
+
* and registers them as KindSpec entries in the registry.
|
|
4
|
+
*
|
|
5
|
+
* Declarative kind files let teams add new artifact types without writing code.
|
|
6
|
+
* See plans/EXTENSIBILITY.md §3a for the full format.
|
|
7
|
+
*
|
|
8
|
+
* Loading is idempotent: kind IDs already present in the registry are skipped
|
|
9
|
+
* with a warning (built-ins always take precedence over YAML definitions).
|
|
10
|
+
*/
|
|
11
|
+
import * as path from "node:path";
|
|
12
|
+
import * as yaml from "yaml";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import { readFile, fileExists, isDirectory, listFiles } from "../lib/fs.js";
|
|
15
|
+
import { registry } from "./registry.js";
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// YAML schema
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const YamlOutputMappingSchema = z.object({
|
|
20
|
+
path: z.union([
|
|
21
|
+
z.string(),
|
|
22
|
+
z.object({ project: z.string(), global: z.string() }),
|
|
23
|
+
]),
|
|
24
|
+
ext: z.string().optional(),
|
|
25
|
+
// "generate" is code-only — YAML kinds cannot generate arbitrary content.
|
|
26
|
+
mode: z.enum(["symlink", "copy"]).optional(),
|
|
27
|
+
// Inline transforms require code; YAML kinds can only reference a named transform.
|
|
28
|
+
transform: z.string().optional(),
|
|
29
|
+
});
|
|
30
|
+
const YamlKindDetectSchema = z.union([
|
|
31
|
+
z.object({ pathPrefix: z.string() }),
|
|
32
|
+
z.object({ pathExact: z.string() }),
|
|
33
|
+
]);
|
|
34
|
+
export const YamlKindSchema = z.object({
|
|
35
|
+
/**
|
|
36
|
+
* Unique kind identifier. Convention: namespace with a dot (e.g. "myteam.prompt")
|
|
37
|
+
* to avoid collision with built-ins ("rule", "skill", "instruction") and other teams.
|
|
38
|
+
*/
|
|
39
|
+
id: z.string().min(1),
|
|
40
|
+
description: z.string().optional(),
|
|
41
|
+
detect: YamlKindDetectSchema,
|
|
42
|
+
layout: z.enum(["file", "dir"]),
|
|
43
|
+
targets: z.record(z.string(), YamlOutputMappingSchema).optional(),
|
|
44
|
+
});
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Parsing
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* Parse a YAML kind definition file into a KindSpec.
|
|
50
|
+
*/
|
|
51
|
+
export function parseYamlKind(filePath) {
|
|
52
|
+
const content = readFile(filePath);
|
|
53
|
+
const raw = yaml.parse(content);
|
|
54
|
+
const def = YamlKindSchema.parse(raw);
|
|
55
|
+
// Build detect predicate from the declarative spec
|
|
56
|
+
const detect = buildDetect(def.detect);
|
|
57
|
+
// Convert targets to OutputMappings
|
|
58
|
+
const defaultTargets = {};
|
|
59
|
+
for (const [toolName, target] of Object.entries(def.targets ?? {})) {
|
|
60
|
+
const mapping = {
|
|
61
|
+
path: target.path,
|
|
62
|
+
};
|
|
63
|
+
if (target.ext !== undefined)
|
|
64
|
+
mapping.ext = target.ext;
|
|
65
|
+
if (target.mode !== undefined)
|
|
66
|
+
mapping.mode = target.mode;
|
|
67
|
+
if (target.transform !== undefined)
|
|
68
|
+
mapping.transform = target.transform;
|
|
69
|
+
defaultTargets[toolName] = mapping;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
id: def.id,
|
|
73
|
+
description: def.description,
|
|
74
|
+
detect,
|
|
75
|
+
layout: def.layout,
|
|
76
|
+
defaultTargets,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function buildDetect(spec) {
|
|
80
|
+
if ("pathPrefix" in spec) {
|
|
81
|
+
const prefix = spec.pathPrefix;
|
|
82
|
+
return (rel) => rel.startsWith(prefix);
|
|
83
|
+
}
|
|
84
|
+
if ("pathExact" in spec) {
|
|
85
|
+
const exact = spec.pathExact;
|
|
86
|
+
return (rel) => rel === exact;
|
|
87
|
+
}
|
|
88
|
+
// TypeScript exhaustiveness guard
|
|
89
|
+
throw new Error("Invalid detect spec");
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Loading
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
/**
|
|
95
|
+
* Load all YAML kinds from the `kinds/` subdirectory of each discovered root
|
|
96
|
+
* and register them into the global registry.
|
|
97
|
+
*
|
|
98
|
+
* Already-registered IDs are skipped with a warning (built-ins win).
|
|
99
|
+
* Parse errors are reported but do not abort loading.
|
|
100
|
+
*
|
|
101
|
+
* This is called synchronously from `resolveLoadout` after root discovery,
|
|
102
|
+
* so YAML kinds are available for `inferKind()` during item resolution.
|
|
103
|
+
*/
|
|
104
|
+
export function loadYamlKindsFromRoots(roots) {
|
|
105
|
+
for (const root of roots) {
|
|
106
|
+
const kindsDir = path.join(root.path, "kinds");
|
|
107
|
+
if (!isDirectory(kindsDir))
|
|
108
|
+
continue;
|
|
109
|
+
const files = listFiles(kindsDir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
|
|
110
|
+
for (const file of files) {
|
|
111
|
+
const filePath = path.join(kindsDir, file);
|
|
112
|
+
if (!fileExists(filePath))
|
|
113
|
+
continue;
|
|
114
|
+
try {
|
|
115
|
+
const kind = parseYamlKind(filePath);
|
|
116
|
+
// Warn if ID looks like a built-in or has no namespace separator
|
|
117
|
+
if (!kind.id.includes(".")) {
|
|
118
|
+
console.warn(`[loadout] Warning: custom kind "${kind.id}" in ${filePath} ` +
|
|
119
|
+
`has no namespace (e.g. "myteam.${kind.id}"). ` +
|
|
120
|
+
`Dot-namespaced IDs are recommended to avoid collisions with built-ins.`);
|
|
121
|
+
}
|
|
122
|
+
registry.registerKind(kind);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
if (err instanceof Error && err.message.includes("already registered")) {
|
|
126
|
+
console.warn(`[loadout] Warning: kind from ${filePath} was skipped — ` +
|
|
127
|
+
`"${extractId(err.message)}" is already registered (built-in takes precedence).`);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
console.warn(`[loadout] Warning: could not load kind from ${filePath}: ` +
|
|
131
|
+
(err instanceof Error ? err.message : String(err)));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function extractId(errMsg) {
|
|
138
|
+
const m = errMsg.match(/Kind "([^"]+)"/);
|
|
139
|
+
return m ? m[1] : "unknown";
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=kindLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kindLoader.js","sourceRoot":"","sources":["../../src/core/kindLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ownership manifest and drift detection
|
|
3
|
+
*/
|
|
4
|
+
import type { AppliedState, ManifestEntry } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Load the applied state from disk.
|
|
7
|
+
* Handles migration from legacy single-loadout format to multi-loadout format.
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadState(loadoutRoot: string): AppliedState | null;
|
|
10
|
+
/**
|
|
11
|
+
* Save the applied state to disk.
|
|
12
|
+
*/
|
|
13
|
+
export declare function saveState(loadoutRoot: string, state: AppliedState): void;
|
|
14
|
+
/**
|
|
15
|
+
* Clear the applied state.
|
|
16
|
+
*/
|
|
17
|
+
export declare function clearState(loadoutRoot: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a target path is owned by the manifest.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isOwned(state: AppliedState | null, targetPath: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check if a target path exists and is NOT owned by the manifest.
|
|
24
|
+
* This is what we need to detect before overwriting.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isUnmanagedCollision(state: AppliedState | null, targetPath: string, projectRoot: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Detect drift in managed outputs.
|
|
29
|
+
*/
|
|
30
|
+
export interface DriftResult {
|
|
31
|
+
entry: ManifestEntry;
|
|
32
|
+
status: "ok" | "missing" | "modified" | "unlinked" | "broken" | "misdirected";
|
|
33
|
+
}
|
|
34
|
+
export declare function detectDrift(state: AppliedState, projectRoot: string): DriftResult[];
|
|
35
|
+
/**
|
|
36
|
+
* Get all target paths that would be affected by applying new entries.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getAffectedPaths(entries: ManifestEntry[]): Set<string>;
|
|
39
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/core/manifest.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAc,MAAM,YAAY,CAAC;AAW1E;;;GAGG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CA+DlE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAGxE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAGpD;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAG/E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAWT;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,aAAa,CAAC;CAC/E;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,YAAY,EACnB,WAAW,EAAE,MAAM,GAClB,WAAW,EAAE,CA0Df;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAEtE"}
|