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.
Files changed (261) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +108 -0
  3. package/bundled/loadouts/loadouts.yaml +5 -0
  4. package/bundled/skills/loadout-usage/SKILL.md +110 -0
  5. package/dist/builtins/index.d.ts +14 -0
  6. package/dist/builtins/index.d.ts.map +1 -0
  7. package/dist/builtins/index.js +58 -0
  8. package/dist/builtins/index.js.map +1 -0
  9. package/dist/builtins/kinds/extension.d.ts +3 -0
  10. package/dist/builtins/kinds/extension.d.ts.map +1 -0
  11. package/dist/builtins/kinds/extension.js +9 -0
  12. package/dist/builtins/kinds/extension.js.map +1 -0
  13. package/dist/builtins/kinds/instruction.d.ts +3 -0
  14. package/dist/builtins/kinds/instruction.d.ts.map +1 -0
  15. package/dist/builtins/kinds/instruction.js +8 -0
  16. package/dist/builtins/kinds/instruction.js.map +1 -0
  17. package/dist/builtins/kinds/prompt.d.ts +3 -0
  18. package/dist/builtins/kinds/prompt.d.ts.map +1 -0
  19. package/dist/builtins/kinds/prompt.js +8 -0
  20. package/dist/builtins/kinds/prompt.js.map +1 -0
  21. package/dist/builtins/kinds/rule.d.ts +3 -0
  22. package/dist/builtins/kinds/rule.d.ts.map +1 -0
  23. package/dist/builtins/kinds/rule.js +10 -0
  24. package/dist/builtins/kinds/rule.js.map +1 -0
  25. package/dist/builtins/kinds/skill.d.ts +3 -0
  26. package/dist/builtins/kinds/skill.d.ts.map +1 -0
  27. package/dist/builtins/kinds/skill.js +8 -0
  28. package/dist/builtins/kinds/skill.js.map +1 -0
  29. package/dist/builtins/kinds/theme.d.ts +3 -0
  30. package/dist/builtins/kinds/theme.d.ts.map +1 -0
  31. package/dist/builtins/kinds/theme.js +8 -0
  32. package/dist/builtins/kinds/theme.js.map +1 -0
  33. package/dist/builtins/tools/claude-code.d.ts +3 -0
  34. package/dist/builtins/tools/claude-code.d.ts.map +1 -0
  35. package/dist/builtins/tools/claude-code.js +30 -0
  36. package/dist/builtins/tools/claude-code.js.map +1 -0
  37. package/dist/builtins/tools/codex.d.ts +3 -0
  38. package/dist/builtins/tools/codex.d.ts.map +1 -0
  39. package/dist/builtins/tools/codex.js +17 -0
  40. package/dist/builtins/tools/codex.js.map +1 -0
  41. package/dist/builtins/tools/cursor.d.ts +3 -0
  42. package/dist/builtins/tools/cursor.d.ts.map +1 -0
  43. package/dist/builtins/tools/cursor.js +22 -0
  44. package/dist/builtins/tools/cursor.js.map +1 -0
  45. package/dist/builtins/tools/opencode.d.ts +3 -0
  46. package/dist/builtins/tools/opencode.d.ts.map +1 -0
  47. package/dist/builtins/tools/opencode.js +45 -0
  48. package/dist/builtins/tools/opencode.js.map +1 -0
  49. package/dist/builtins/tools/pi.d.ts +3 -0
  50. package/dist/builtins/tools/pi.d.ts.map +1 -0
  51. package/dist/builtins/tools/pi.js +22 -0
  52. package/dist/builtins/tools/pi.js.map +1 -0
  53. package/dist/cli/commands/activate.d.ts +12 -0
  54. package/dist/cli/commands/activate.d.ts.map +1 -0
  55. package/dist/cli/commands/activate.js +70 -0
  56. package/dist/cli/commands/activate.js.map +1 -0
  57. package/dist/cli/commands/check.d.ts +12 -0
  58. package/dist/cli/commands/check.d.ts.map +1 -0
  59. package/dist/cli/commands/check.js +152 -0
  60. package/dist/cli/commands/check.js.map +1 -0
  61. package/dist/cli/commands/clear.d.ts +12 -0
  62. package/dist/cli/commands/clear.d.ts.map +1 -0
  63. package/dist/cli/commands/clear.js +25 -0
  64. package/dist/cli/commands/clear.js.map +1 -0
  65. package/dist/cli/commands/create.d.ts +11 -0
  66. package/dist/cli/commands/create.d.ts.map +1 -0
  67. package/dist/cli/commands/create.js +113 -0
  68. package/dist/cli/commands/create.js.map +1 -0
  69. package/dist/cli/commands/deactivate.d.ts +12 -0
  70. package/dist/cli/commands/deactivate.d.ts.map +1 -0
  71. package/dist/cli/commands/deactivate.js +67 -0
  72. package/dist/cli/commands/deactivate.js.map +1 -0
  73. package/dist/cli/commands/diff.d.ts +16 -0
  74. package/dist/cli/commands/diff.d.ts.map +1 -0
  75. package/dist/cli/commands/diff.js +144 -0
  76. package/dist/cli/commands/diff.js.map +1 -0
  77. package/dist/cli/commands/docs.d.ts +12 -0
  78. package/dist/cli/commands/docs.d.ts.map +1 -0
  79. package/dist/cli/commands/docs.js +115 -0
  80. package/dist/cli/commands/docs.js.map +1 -0
  81. package/dist/cli/commands/edit.d.ts +11 -0
  82. package/dist/cli/commands/edit.d.ts.map +1 -0
  83. package/dist/cli/commands/edit.js +71 -0
  84. package/dist/cli/commands/edit.js.map +1 -0
  85. package/dist/cli/commands/fallback.d.ts +9 -0
  86. package/dist/cli/commands/fallback.d.ts.map +1 -0
  87. package/dist/cli/commands/fallback.js +35 -0
  88. package/dist/cli/commands/fallback.js.map +1 -0
  89. package/dist/cli/commands/info.d.ts +23 -0
  90. package/dist/cli/commands/info.d.ts.map +1 -0
  91. package/dist/cli/commands/info.js +314 -0
  92. package/dist/cli/commands/info.js.map +1 -0
  93. package/dist/cli/commands/init.d.ts +18 -0
  94. package/dist/cli/commands/init.d.ts.map +1 -0
  95. package/dist/cli/commands/init.js +255 -0
  96. package/dist/cli/commands/init.js.map +1 -0
  97. package/dist/cli/commands/install.d.ts +27 -0
  98. package/dist/cli/commands/install.d.ts.map +1 -0
  99. package/dist/cli/commands/install.js +586 -0
  100. package/dist/cli/commands/install.js.map +1 -0
  101. package/dist/cli/commands/instructions.d.ts +8 -0
  102. package/dist/cli/commands/instructions.d.ts.map +1 -0
  103. package/dist/cli/commands/instructions.js +218 -0
  104. package/dist/cli/commands/instructions.js.map +1 -0
  105. package/dist/cli/commands/kinds.d.ts +6 -0
  106. package/dist/cli/commands/kinds.d.ts.map +1 -0
  107. package/dist/cli/commands/kinds.js +59 -0
  108. package/dist/cli/commands/kinds.js.map +1 -0
  109. package/dist/cli/commands/list.d.ts +12 -0
  110. package/dist/cli/commands/list.d.ts.map +1 -0
  111. package/dist/cli/commands/list.js +182 -0
  112. package/dist/cli/commands/list.js.map +1 -0
  113. package/dist/cli/commands/policy.d.ts +28 -0
  114. package/dist/cli/commands/policy.d.ts.map +1 -0
  115. package/dist/cli/commands/policy.js +50 -0
  116. package/dist/cli/commands/policy.js.map +1 -0
  117. package/dist/cli/commands/remove.d.ts +24 -0
  118. package/dist/cli/commands/remove.d.ts.map +1 -0
  119. package/dist/cli/commands/remove.js +64 -0
  120. package/dist/cli/commands/remove.js.map +1 -0
  121. package/dist/cli/commands/render-engine.d.ts +36 -0
  122. package/dist/cli/commands/render-engine.d.ts.map +1 -0
  123. package/dist/cli/commands/render-engine.js +177 -0
  124. package/dist/cli/commands/render-engine.js.map +1 -0
  125. package/dist/cli/commands/rule.d.ts +11 -0
  126. package/dist/cli/commands/rule.d.ts.map +1 -0
  127. package/dist/cli/commands/rule.js +302 -0
  128. package/dist/cli/commands/rule.js.map +1 -0
  129. package/dist/cli/commands/sanitize.d.ts +14 -0
  130. package/dist/cli/commands/sanitize.d.ts.map +1 -0
  131. package/dist/cli/commands/sanitize.js +62 -0
  132. package/dist/cli/commands/sanitize.js.map +1 -0
  133. package/dist/cli/commands/skill.d.ts +11 -0
  134. package/dist/cli/commands/skill.d.ts.map +1 -0
  135. package/dist/cli/commands/skill.js +380 -0
  136. package/dist/cli/commands/skill.js.map +1 -0
  137. package/dist/cli/commands/status.d.ts +26 -0
  138. package/dist/cli/commands/status.d.ts.map +1 -0
  139. package/dist/cli/commands/status.js +454 -0
  140. package/dist/cli/commands/status.js.map +1 -0
  141. package/dist/cli/commands/sync.d.ts +14 -0
  142. package/dist/cli/commands/sync.d.ts.map +1 -0
  143. package/dist/cli/commands/sync.js +53 -0
  144. package/dist/cli/commands/sync.js.map +1 -0
  145. package/dist/cli/commands/update.d.ts +3 -0
  146. package/dist/cli/commands/update.d.ts.map +1 -0
  147. package/dist/cli/commands/update.js +48 -0
  148. package/dist/cli/commands/update.js.map +1 -0
  149. package/dist/cli/index.d.ts +11 -0
  150. package/dist/cli/index.d.ts.map +1 -0
  151. package/dist/cli/index.js +134 -0
  152. package/dist/cli/index.js.map +1 -0
  153. package/dist/core/config.d.ts +64 -0
  154. package/dist/core/config.d.ts.map +1 -0
  155. package/dist/core/config.js +166 -0
  156. package/dist/core/config.js.map +1 -0
  157. package/dist/core/discovery.d.ts +50 -0
  158. package/dist/core/discovery.d.ts.map +1 -0
  159. package/dist/core/discovery.js +249 -0
  160. package/dist/core/discovery.js.map +1 -0
  161. package/dist/core/fallback.d.ts +23 -0
  162. package/dist/core/fallback.d.ts.map +1 -0
  163. package/dist/core/fallback.js +119 -0
  164. package/dist/core/fallback.js.map +1 -0
  165. package/dist/core/import-discovery.d.ts +56 -0
  166. package/dist/core/import-discovery.d.ts.map +1 -0
  167. package/dist/core/import-discovery.js +304 -0
  168. package/dist/core/import-discovery.js.map +1 -0
  169. package/dist/core/kindLoader.d.ts +119 -0
  170. package/dist/core/kindLoader.d.ts.map +1 -0
  171. package/dist/core/kindLoader.js +141 -0
  172. package/dist/core/kindLoader.js.map +1 -0
  173. package/dist/core/manifest.d.ts +39 -0
  174. package/dist/core/manifest.d.ts.map +1 -0
  175. package/dist/core/manifest.js +167 -0
  176. package/dist/core/manifest.js.map +1 -0
  177. package/dist/core/plugin.d.ts +22 -0
  178. package/dist/core/plugin.d.ts.map +1 -0
  179. package/dist/core/plugin.js +20 -0
  180. package/dist/core/plugin.js.map +1 -0
  181. package/dist/core/registry.d.ts +115 -0
  182. package/dist/core/registry.d.ts.map +1 -0
  183. package/dist/core/registry.js +105 -0
  184. package/dist/core/registry.js.map +1 -0
  185. package/dist/core/render.d.ts +64 -0
  186. package/dist/core/render.d.ts.map +1 -0
  187. package/dist/core/render.js +457 -0
  188. package/dist/core/render.js.map +1 -0
  189. package/dist/core/resolve.d.ts +39 -0
  190. package/dist/core/resolve.d.ts.map +1 -0
  191. package/dist/core/resolve.js +128 -0
  192. package/dist/core/resolve.js.map +1 -0
  193. package/dist/core/schema.d.ts +308 -0
  194. package/dist/core/schema.d.ts.map +1 -0
  195. package/dist/core/schema.js +81 -0
  196. package/dist/core/schema.js.map +1 -0
  197. package/dist/core/scope.d.ts +74 -0
  198. package/dist/core/scope.d.ts.map +1 -0
  199. package/dist/core/scope.js +176 -0
  200. package/dist/core/scope.js.map +1 -0
  201. package/dist/core/template.d.ts +32 -0
  202. package/dist/core/template.d.ts.map +1 -0
  203. package/dist/core/template.js +32 -0
  204. package/dist/core/template.js.map +1 -0
  205. package/dist/core/tokens.d.ts +33 -0
  206. package/dist/core/tokens.d.ts.map +1 -0
  207. package/dist/core/tokens.js +97 -0
  208. package/dist/core/tokens.js.map +1 -0
  209. package/dist/core/types.d.ts +103 -0
  210. package/dist/core/types.d.ts.map +1 -0
  211. package/dist/core/types.js +10 -0
  212. package/dist/core/types.js.map +1 -0
  213. package/dist/index.d.ts +12 -0
  214. package/dist/index.d.ts.map +1 -0
  215. package/dist/index.js +24 -0
  216. package/dist/index.js.map +1 -0
  217. package/dist/lib/artifact-paths.d.ts +39 -0
  218. package/dist/lib/artifact-paths.d.ts.map +1 -0
  219. package/dist/lib/artifact-paths.js +83 -0
  220. package/dist/lib/artifact-paths.js.map +1 -0
  221. package/dist/lib/artifact-table.d.ts +126 -0
  222. package/dist/lib/artifact-table.d.ts.map +1 -0
  223. package/dist/lib/artifact-table.js +263 -0
  224. package/dist/lib/artifact-table.js.map +1 -0
  225. package/dist/lib/editor.d.ts +17 -0
  226. package/dist/lib/editor.d.ts.map +1 -0
  227. package/dist/lib/editor.js +33 -0
  228. package/dist/lib/editor.js.map +1 -0
  229. package/dist/lib/fs.d.ts +87 -0
  230. package/dist/lib/fs.d.ts.map +1 -0
  231. package/dist/lib/fs.js +229 -0
  232. package/dist/lib/fs.js.map +1 -0
  233. package/dist/lib/git.d.ts +13 -0
  234. package/dist/lib/git.d.ts.map +1 -0
  235. package/dist/lib/git.js +28 -0
  236. package/dist/lib/git.js.map +1 -0
  237. package/dist/lib/gitignore.d.ts +26 -0
  238. package/dist/lib/gitignore.d.ts.map +1 -0
  239. package/dist/lib/gitignore.js +97 -0
  240. package/dist/lib/gitignore.js.map +1 -0
  241. package/dist/lib/loadout-column.d.ts +66 -0
  242. package/dist/lib/loadout-column.d.ts.map +1 -0
  243. package/dist/lib/loadout-column.js +66 -0
  244. package/dist/lib/loadout-column.js.map +1 -0
  245. package/dist/lib/output.d.ts +15 -0
  246. package/dist/lib/output.d.ts.map +1 -0
  247. package/dist/lib/output.js +32 -0
  248. package/dist/lib/output.js.map +1 -0
  249. package/dist/lib/scope-indicators.d.ts +60 -0
  250. package/dist/lib/scope-indicators.d.ts.map +1 -0
  251. package/dist/lib/scope-indicators.js +110 -0
  252. package/dist/lib/scope-indicators.js.map +1 -0
  253. package/docs/authoring.md +182 -0
  254. package/docs/commands.md +192 -0
  255. package/docs/concepts.md +114 -0
  256. package/docs/index.md +60 -0
  257. package/docs/quickstart.md +100 -0
  258. package/docs/troubleshooting.md +147 -0
  259. package/docs/visual-language.md +251 -0
  260. package/docs/workflows.md +184 -0
  261. 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"}