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,64 @@
1
+ /**
2
+ * loadout remove — Remove applied loadout outputs.
3
+ *
4
+ * Scope flags:
5
+ * -l / --local → project scope only
6
+ * -g / --global → global scope only
7
+ * -a / --all → remove from both scopes (default)
8
+ * (none) → all available scopes
9
+ */
10
+ import { Command } from "commander";
11
+ import { loadState, clearState } from "../../core/manifest.js";
12
+ import { removeManaged } from "../../core/render.js";
13
+ import { resolveContexts, SCOPE_FLAGS } from "../../core/scope.js";
14
+ import { log, heading, list } from "../../lib/output.js";
15
+ /**
16
+ * Remove all managed outputs for a context and clear its state.
17
+ *
18
+ * If `name` is given and doesn't match the applied loadout, this is a no-op
19
+ * with a warning (so users don't accidentally clean the wrong loadout).
20
+ */
21
+ export async function executeRemove(ctx, name, options = {}) {
22
+ const state = loadState(ctx.configPath);
23
+ if (!state) {
24
+ log.dim(`[${ctx.scope}] No loadout currently applied.`);
25
+ return;
26
+ }
27
+ const activeList = state.active.join(", ");
28
+ if (name && !state.active.includes(name)) {
29
+ log.warn(`[${ctx.scope}] Active loadouts are [${activeList}], not "${name}". ` +
30
+ `Run without a name to remove the current state.`);
31
+ return;
32
+ }
33
+ if (options.dryRun) {
34
+ heading(`Would remove loadouts: ${activeList} (${ctx.scope})`);
35
+ console.log();
36
+ log.info(`${state.entries.length} files would be removed:`);
37
+ list(state.entries.map((e) => e.targetPath));
38
+ return;
39
+ }
40
+ const { removed, missing } = await removeManaged(ctx.configPath, ctx.projectRoot, ctx.scope);
41
+ clearState(ctx.configPath);
42
+ heading(`Removed loadouts: ${activeList} (${ctx.scope})`);
43
+ if (removed.length > 0) {
44
+ log.success(`${removed.length} files removed`);
45
+ }
46
+ if (missing.length > 0) {
47
+ log.warn(`${missing.length} files were already missing:`);
48
+ list(missing);
49
+ }
50
+ }
51
+ export const removeCommand = new Command("remove")
52
+ .description("Remove applied loadout outputs")
53
+ .argument("[name]", "Loadout name (optional, validates against active)")
54
+ .option(...SCOPE_FLAGS.local)
55
+ .option(...SCOPE_FLAGS.global)
56
+ .option(...SCOPE_FLAGS.all)
57
+ .option("--dry-run", "Preview what would be removed")
58
+ .action(async (name, options) => {
59
+ const { contexts } = await resolveContexts(options);
60
+ for (const ctx of contexts) {
61
+ await executeRemove(ctx, name, options);
62
+ }
63
+ });
64
+ //# sourceMappingURL=remove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../../src/cli/commands/remove.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Render engine — the mechanism behind loadout operations.
3
+ *
4
+ * Single responsibility: given a target set of loadout names, resolve, plan,
5
+ * and render them to disk. Policy decisions (what the target set should be)
6
+ * live in policy.ts; this module is pure mechanism.
7
+ *
8
+ * Output follows the unified visual language (see docs/visual-language.md):
9
+ * - Artifacts as rows, tools as columns
10
+ * - Consistent change indicators (+, ~, -, ✓)
11
+ */
12
+ import type { CommandContext } from "../../core/types.js";
13
+ export interface ApplyOptions {
14
+ dryRun?: boolean;
15
+ /** Verb for output heading (e.g., "Activated", "Synced"). Defaults to "Applied". */
16
+ verb?: string;
17
+ }
18
+ export interface ApplyResult {
19
+ applied: boolean;
20
+ totalOutputs: number;
21
+ }
22
+ /**
23
+ * Clear all loadout outputs and state.
24
+ */
25
+ export declare function clearAllOutputs(ctx: CommandContext, options?: {
26
+ dryRun?: boolean;
27
+ }): Promise<void>;
28
+ /**
29
+ * Apply a target set of loadouts.
30
+ *
31
+ * This is the core mechanism: resolve the named loadouts, plan their outputs,
32
+ * and write them to disk. Caller is responsible for computing what the target
33
+ * set should be (see policy.ts).
34
+ */
35
+ export declare function applyTargetSet(ctx: CommandContext, targets: string[], options?: ApplyOptions): Promise<ApplyResult>;
36
+ //# sourceMappingURL=render-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-engine.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/render-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH,OAAO,KAAK,EAAE,cAAc,EAAkD,MAAM,qBAAqB,CAAC;AAE1G,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAwDD;;GAEG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,cAAc,EACnB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CA+HtB"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Render engine — the mechanism behind loadout operations.
3
+ *
4
+ * Single responsibility: given a target set of loadout names, resolve, plan,
5
+ * and render them to disk. Policy decisions (what the target set should be)
6
+ * live in policy.ts; this module is pure mechanism.
7
+ *
8
+ * Output follows the unified visual language (see docs/visual-language.md):
9
+ * - Artifacts as rows, tools as columns
10
+ * - Consistent change indicators (+, ~, -, ✓)
11
+ */
12
+ import { discoverLoadoutRoots, getGlobalRoot, collectRootsWithSources } from "../../core/discovery.js";
13
+ import { resolveLoadout, getInstructionItem } from "../../core/resolve.js";
14
+ import { parseRootConfig } from "../../core/config.js";
15
+ import { planRender, applyMultiPlan, removeManaged } from "../../core/render.js";
16
+ import { loadState, clearState } from "../../core/manifest.js";
17
+ import { log, heading, list } from "../../lib/output.js";
18
+ import { groupOutputsByArtifact, renderChangeTable, renderChangeSummary, renderDryRunSummary, } from "../../lib/artifact-table.js";
19
+ /**
20
+ * Resolve multiple loadouts and their render plans.
21
+ */
22
+ async function resolveMultipleLoadouts(names, ctx) {
23
+ // Get roots based on scope, including sources and bundled
24
+ let roots;
25
+ if (ctx.scope === "global") {
26
+ const globalRoot = getGlobalRoot();
27
+ if (!globalRoot)
28
+ throw new Error("No global loadout found at ~/.config/loadouts");
29
+ // Global scope: global root + any sources it declares + bundled
30
+ const collected = collectRootsWithSources(globalRoot, false, true);
31
+ roots = collected.roots;
32
+ }
33
+ else {
34
+ const discovered = await discoverLoadoutRoots(ctx.projectRoot);
35
+ if (discovered.length === 0) {
36
+ throw new Error("No .loadouts/ directory found. Run 'loadouts init' first.");
37
+ }
38
+ // Project scope: project root + sources + global + bundled
39
+ const collected = collectRootsWithSources(discovered[0], true, true);
40
+ roots = collected.roots;
41
+ }
42
+ const rootConfig = parseRootConfig(ctx.configPath);
43
+ const results = [];
44
+ for (const name of names) {
45
+ const loadout = resolveLoadout(name, roots, rootConfig);
46
+ // Auto-inject AGENTS.md if not already in includes
47
+ const alreadyHasInstruction = loadout.items.some((i) => i.relativePath === "AGENTS.md");
48
+ if (!alreadyHasInstruction) {
49
+ const instructionItem = getInstructionItem(ctx.configPath, loadout.tools);
50
+ if (instructionItem)
51
+ loadout.items.push(instructionItem);
52
+ }
53
+ const plan = await planRender(loadout, ctx.projectRoot, ctx.scope, ctx.configPath);
54
+ if (plan.errors.length > 0) {
55
+ log.error(`Errors planning "${name}":`);
56
+ list(plan.errors);
57
+ process.exit(1);
58
+ }
59
+ results.push({ loadout, plan });
60
+ }
61
+ return results;
62
+ }
63
+ /**
64
+ * Clear all loadout outputs and state.
65
+ */
66
+ export async function clearAllOutputs(ctx, options = {}) {
67
+ if (options.dryRun) {
68
+ const state = loadState(ctx.configPath);
69
+ const count = state?.entries.length ?? 0;
70
+ heading(`Would clear all loadouts (${ctx.scope})`);
71
+ log.dim(` ${count} outputs would be removed`);
72
+ return;
73
+ }
74
+ const { removed } = await removeManaged(ctx.configPath, ctx.projectRoot, ctx.scope);
75
+ clearState(ctx.configPath);
76
+ heading(`Cleared all loadouts (${ctx.scope})`);
77
+ log.success(`${removed.length} outputs removed`);
78
+ }
79
+ /**
80
+ * Apply a target set of loadouts.
81
+ *
82
+ * This is the core mechanism: resolve the named loadouts, plan their outputs,
83
+ * and write them to disk. Caller is responsible for computing what the target
84
+ * set should be (see policy.ts).
85
+ */
86
+ export async function applyTargetSet(ctx, targets, options = {}) {
87
+ const { dryRun, verb = "Applied" } = options;
88
+ // Empty target set means clear — delegate to clearAllOutputs
89
+ if (targets.length === 0) {
90
+ await clearAllOutputs(ctx, { dryRun });
91
+ return { applied: true, totalOutputs: 0 };
92
+ }
93
+ // Resolve all target loadouts
94
+ let plans;
95
+ try {
96
+ plans = await resolveMultipleLoadouts(targets, ctx);
97
+ }
98
+ catch (err) {
99
+ log.error(err instanceof Error ? err.message : String(err));
100
+ process.exit(1);
101
+ }
102
+ // Check for empty loadouts
103
+ const totalOutputs = plans.reduce((sum, p) => sum + p.plan.outputs.length, 0);
104
+ if (totalOutputs === 0) {
105
+ log.warn("No outputs to apply. Loadouts may be empty.");
106
+ return { applied: false, totalOutputs: 0 };
107
+ }
108
+ if (dryRun) {
109
+ heading(`Would apply loadouts: ${targets.join(", ")} (${ctx.scope})`);
110
+ // Collect all tools and build output list with "added" change type
111
+ const toolSet = new Set();
112
+ const outputs = [];
113
+ for (const { plan } of plans) {
114
+ for (const { spec } of plan.outputs) {
115
+ toolSet.add(spec.tool);
116
+ outputs.push({ spec, change: "added" });
117
+ }
118
+ }
119
+ const tools = Array.from(toolSet).sort();
120
+ const artifacts = groupOutputsByArtifact(outputs);
121
+ renderChangeTable(artifacts, tools, { showMode: true });
122
+ renderDryRunSummary(totalOutputs, tools.length);
123
+ const allShadowed = plans.flatMap((p) => p.plan.shadowed);
124
+ if (allShadowed.length > 0) {
125
+ console.log();
126
+ log.warn(`${allShadowed.length} outputs would be shadowed by unmanaged files:`);
127
+ for (const s of allShadowed) {
128
+ log.dim(` ${s.targetPath} (${s.tool})`);
129
+ }
130
+ }
131
+ return { applied: false, totalOutputs };
132
+ }
133
+ // Apply for real
134
+ const rootConfig = parseRootConfig(ctx.configPath);
135
+ const result = await applyMultiPlan(plans, ctx.configPath, ctx.projectRoot, rootConfig.mode, ctx.scope);
136
+ heading(`${verb} loadouts: ${targets.join(", ")} (${ctx.scope})`);
137
+ // Build change-tagged outputs for table display
138
+ const addedSet = new Set(result.changes.added);
139
+ const updatedSet = new Set(result.changes.updated);
140
+ const toolSet = new Set();
141
+ const outputs = [];
142
+ for (const { plan } of plans) {
143
+ for (const { spec } of plan.outputs) {
144
+ toolSet.add(spec.tool);
145
+ let change = "unchanged";
146
+ if (addedSet.has(spec.targetPath))
147
+ change = "added";
148
+ else if (updatedSet.has(spec.targetPath))
149
+ change = "updated";
150
+ outputs.push({ spec, change });
151
+ }
152
+ }
153
+ // Add removed entries (they won't be in current plans)
154
+ // We can't show these in the table since we don't have their specs anymore,
155
+ // but we include them in the summary
156
+ const tools = Array.from(toolSet).sort();
157
+ const artifacts = groupOutputsByArtifact(outputs);
158
+ // Only show table if there are changes
159
+ const totalChanges = result.changes.updated.length +
160
+ result.changes.added.length +
161
+ result.changes.removed.length;
162
+ if (totalChanges > 0 || artifacts.length > 0) {
163
+ renderChangeTable(artifacts, tools);
164
+ }
165
+ renderChangeSummary(result.changes.added.length, result.changes.updated.length, result.changes.removed.length);
166
+ const allShadowed = plans.flatMap((p) => p.plan.shadowed);
167
+ if (allShadowed.length > 0) {
168
+ console.log();
169
+ log.warn(`${allShadowed.length} outputs shadowed by unmanaged files:`);
170
+ for (const s of allShadowed) {
171
+ log.dim(` ${s.targetPath} (${s.tool})`);
172
+ }
173
+ log.dim("These files take precedence over the loadout. Use 'loadouts status' to review.");
174
+ }
175
+ return { applied: true, totalOutputs: result.totalOutputs };
176
+ }
177
+ //# sourceMappingURL=render-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-engine.js","sourceRoot":"","sources":["../../../src/cli/commands/render-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * loadout rule — Manage rules.
3
+ *
4
+ * Scope flags:
5
+ * -l / --local → project scope
6
+ * -g / --global → global scope
7
+ * (none) → project if in one, else global
8
+ */
9
+ import { Command } from "commander";
10
+ export declare const ruleCommand: Command;
11
+ //# sourceMappingURL=rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/rule.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkEpC,eAAO,MAAM,WAAW,SAAkD,CAAC"}
@@ -0,0 +1,302 @@
1
+ /**
2
+ * loadout rule — Manage rules.
3
+ *
4
+ * Scope flags:
5
+ * -l / --local → project scope
6
+ * -g / --global → global scope
7
+ * (none) → project if in one, else global
8
+ */
9
+ import { Command } from "commander";
10
+ import * as path from "node:path";
11
+ import * as yaml from "yaml";
12
+ import { findNearestLoadoutRoot, getGlobalConfigPath, } from "../../core/discovery.js";
13
+ import { writeFile, readFile, fileExists, removeFile, copyFile, listFilesWithExtension, } from "../../lib/fs.js";
14
+ import { parseFrontmatter, parseLoadoutDefinition, sanitizeRuleFrontmatter, sanitizeRuleFile, serializeFrontmatter } from "../../core/config.js";
15
+ import { inProject, hasGlobal } from "../../core/scope.js";
16
+ import { log, heading } from "../../lib/output.js";
17
+ import { openInEditor } from "../../lib/editor.js";
18
+ const RULES_DIR = "rules";
19
+ /**
20
+ * Resolve the loadout root path based on scope flags.
21
+ */
22
+ async function resolveRootPath(options, cwd = process.cwd()) {
23
+ if (options.local) {
24
+ const projectRoot = await findNearestLoadoutRoot(cwd);
25
+ if (!projectRoot) {
26
+ throw new Error("Not in a loadout project. Run 'loadouts init' first.");
27
+ }
28
+ return { rootPath: projectRoot.path, scope: "project" };
29
+ }
30
+ if (options.global) {
31
+ if (!hasGlobal()) {
32
+ throw new Error("No global loadout found. Run 'loadouts init --global' first.");
33
+ }
34
+ return { rootPath: getGlobalConfigPath(), scope: "global" };
35
+ }
36
+ // Auto-detect: prefer project if in one
37
+ if (await inProject(cwd)) {
38
+ const projectRoot = await findNearestLoadoutRoot(cwd);
39
+ return { rootPath: projectRoot.path, scope: "project" };
40
+ }
41
+ if (hasGlobal()) {
42
+ return { rootPath: getGlobalConfigPath(), scope: "global" };
43
+ }
44
+ throw new Error("No loadout found. Run 'loadouts init' or 'loadouts init --global' first.");
45
+ }
46
+ export const ruleCommand = new Command("rule").description("Manage rules");
47
+ // loadout rule add <name>
48
+ ruleCommand
49
+ .command("add")
50
+ .description("Create a new rule")
51
+ .argument("<name>", "Rule name (without .md extension)")
52
+ .option("-l, --local", "Project scope")
53
+ .option("-g, --global", "Global scope")
54
+ .option("-d, --description <desc>", "Rule description")
55
+ .option("-p, --paths <paths...>", "File path patterns")
56
+ .option("--always-apply", "Always apply this rule")
57
+ .option("--no-edit", "Don't open in editor after creating")
58
+ .action(async (name, options) => {
59
+ let rootPath;
60
+ let scope;
61
+ try {
62
+ ({ rootPath, scope } = await resolveRootPath(options));
63
+ }
64
+ catch (err) {
65
+ log.error(err instanceof Error ? err.message : String(err));
66
+ process.exit(1);
67
+ }
68
+ const rulePath = path.join(rootPath, RULES_DIR, `${name}.md`);
69
+ if (fileExists(rulePath)) {
70
+ log.error(`Rule '${name}' already exists in ${scope} scope.`);
71
+ process.exit(1);
72
+ }
73
+ let frontmatter = {};
74
+ if (options.description) {
75
+ frontmatter.description = options.description;
76
+ }
77
+ if (options.paths) {
78
+ frontmatter.paths = options.paths;
79
+ }
80
+ if (options.alwaysApply) {
81
+ frontmatter.alwaysApply = true;
82
+ }
83
+ // Sanitize for cross-tool compatibility
84
+ frontmatter = sanitizeRuleFrontmatter(frontmatter, name);
85
+ const body = `\n# ${name}\n\nAdd your rule content here.\n`;
86
+ const content = serializeFrontmatter(frontmatter, body);
87
+ writeFile(rulePath, content);
88
+ const scopeLabel = scope === "global" ? "global" : "project";
89
+ log.success(`Created ${scopeLabel} rule: ${name}`);
90
+ // Open in editor unless --no-edit (Commander sets options.edit = false for --no-edit)
91
+ if (options.edit !== false) {
92
+ log.dim(` ${rulePath}`);
93
+ await openInEditor(rulePath, { cwd: rootPath });
94
+ }
95
+ else {
96
+ // For agents/scripts: show clear path and instructions
97
+ console.log();
98
+ console.log(` File: ${rulePath}`);
99
+ console.log();
100
+ log.dim(" Replace the template content with your rule, then run 'loadouts sync'");
101
+ }
102
+ });
103
+ // loadout rule list
104
+ ruleCommand
105
+ .command("list")
106
+ .description("List rules")
107
+ .option("-l, --local", "Project scope only")
108
+ .option("-g, --global", "Global scope only")
109
+ .option("-a, --all", "Both scopes")
110
+ .action(async (options) => {
111
+ const cwd = process.cwd();
112
+ const roots = [];
113
+ // Determine which scopes to list
114
+ if (options.all || (!options.local && !options.global)) {
115
+ // Show all available
116
+ if (await inProject(cwd)) {
117
+ const projectRoot = await findNearestLoadoutRoot(cwd);
118
+ if (projectRoot) {
119
+ roots.push({ rootPath: projectRoot.path, scope: "project" });
120
+ }
121
+ }
122
+ if (hasGlobal()) {
123
+ roots.push({ rootPath: getGlobalConfigPath(), scope: "global" });
124
+ }
125
+ }
126
+ else if (options.local) {
127
+ const projectRoot = await findNearestLoadoutRoot(cwd);
128
+ if (!projectRoot) {
129
+ log.error("Not in a loadout project.");
130
+ process.exit(1);
131
+ }
132
+ roots.push({ rootPath: projectRoot.path, scope: "project" });
133
+ }
134
+ else if (options.global) {
135
+ if (!hasGlobal()) {
136
+ log.error("No global loadout found.");
137
+ process.exit(1);
138
+ }
139
+ roots.push({ rootPath: getGlobalConfigPath(), scope: "global" });
140
+ }
141
+ if (roots.length === 0) {
142
+ log.error("No loadout found.");
143
+ process.exit(1);
144
+ }
145
+ for (const { rootPath, scope } of roots) {
146
+ const rulesDir = path.join(rootPath, RULES_DIR);
147
+ const rules = listFilesWithExtension(rulesDir, ".md");
148
+ const scopeLabel = scope === "global" ? "Global rules" : "Project rules";
149
+ heading(scopeLabel);
150
+ if (rules.length === 0) {
151
+ log.dim(" No rules defined.");
152
+ const flag = scope === "global" ? " -g" : "";
153
+ log.dim(` Create one with: loadout rule add <name>${flag}`);
154
+ console.log();
155
+ continue;
156
+ }
157
+ for (const file of rules) {
158
+ const name = file.replace(/\.md$/, "");
159
+ const rulePath = path.join(rulesDir, file);
160
+ try {
161
+ const content = readFile(rulePath);
162
+ const { frontmatter } = parseFrontmatter(content);
163
+ const desc = frontmatter.description || "";
164
+ const paths = frontmatter.paths?.join(", ") || "all files";
165
+ console.log(` ${name}`);
166
+ if (desc) {
167
+ log.dim(` ${desc}`);
168
+ }
169
+ log.dim(` paths: ${paths}`);
170
+ }
171
+ catch {
172
+ console.log(` ${name} (error reading)`);
173
+ }
174
+ }
175
+ console.log();
176
+ }
177
+ });
178
+ // loadout rule edit <name>
179
+ ruleCommand
180
+ .command("edit")
181
+ .description("Edit a rule in $EDITOR")
182
+ .argument("<name>", "Rule name")
183
+ .option("-l, --local", "Project scope")
184
+ .option("-g, --global", "Global scope")
185
+ .action(async (name, options) => {
186
+ let rootPath;
187
+ let scope;
188
+ try {
189
+ ({ rootPath, scope } = await resolveRootPath(options));
190
+ }
191
+ catch (err) {
192
+ log.error(err instanceof Error ? err.message : String(err));
193
+ process.exit(1);
194
+ }
195
+ const rulePath = path.join(rootPath, RULES_DIR, `${name}.md`);
196
+ if (!fileExists(rulePath)) {
197
+ log.error(`Rule '${name}' not found in ${scope} scope.`);
198
+ process.exit(1);
199
+ }
200
+ await openInEditor(rulePath, {
201
+ cwd: rootPath,
202
+ onSuccess: () => log.success(`Edited rule: ${name}`),
203
+ });
204
+ });
205
+ // loadout rule remove <name>
206
+ ruleCommand
207
+ .command("remove")
208
+ .description("Remove a rule")
209
+ .argument("<name>", "Rule name")
210
+ .option("-l, --local", "Project scope")
211
+ .option("-g, --global", "Global scope")
212
+ .option("-f, --force", "Skip confirmation")
213
+ .action(async (name, options) => {
214
+ let rootPath;
215
+ let scope;
216
+ try {
217
+ ({ rootPath, scope } = await resolveRootPath(options));
218
+ }
219
+ catch (err) {
220
+ log.error(err instanceof Error ? err.message : String(err));
221
+ process.exit(1);
222
+ }
223
+ const rulePath = path.join(rootPath, RULES_DIR, `${name}.md`);
224
+ if (!fileExists(rulePath)) {
225
+ log.error(`Rule '${name}' not found in ${scope} scope.`);
226
+ process.exit(1);
227
+ }
228
+ if (!options.force) {
229
+ log.warn(`This will delete: ${rulePath}`);
230
+ log.dim("Use --force to skip this warning.");
231
+ process.exit(1);
232
+ }
233
+ removeFile(rulePath);
234
+ log.success(`Removed rule: ${name} (${scope})`);
235
+ });
236
+ // loadout rule import <path>
237
+ ruleCommand
238
+ .command("import")
239
+ .description("Import an existing rule file into loadout")
240
+ .argument("<path>", "Path to existing rule file")
241
+ .option("-l, --local", "Project scope")
242
+ .option("-g, --global", "Global scope")
243
+ .option("--loadout <name>", "Loadout to add rule to", "base")
244
+ .option("--keep", "Keep original file (don't delete after import)")
245
+ .action(async (filePath, options) => {
246
+ const cwd = process.cwd();
247
+ let rootPath;
248
+ let scope;
249
+ try {
250
+ ({ rootPath, scope } = await resolveRootPath(options, cwd));
251
+ }
252
+ catch (err) {
253
+ log.error(err instanceof Error ? err.message : String(err));
254
+ process.exit(1);
255
+ }
256
+ // Resolve the source path
257
+ const sourcePath = path.isAbsolute(filePath)
258
+ ? filePath
259
+ : path.resolve(cwd, filePath);
260
+ if (!fileExists(sourcePath)) {
261
+ log.error(`File not found: ${sourcePath}`);
262
+ process.exit(1);
263
+ }
264
+ // Determine the rule name from filename
265
+ const basename = path.basename(sourcePath);
266
+ const name = basename.replace(/\.(md|mdc)$/, "");
267
+ const destPath = path.join(rootPath, RULES_DIR, `${name}.md`);
268
+ if (fileExists(destPath)) {
269
+ log.error(`Rule '${name}' already exists in ${scope} scope.`);
270
+ process.exit(1);
271
+ }
272
+ // Copy the file
273
+ copyFile(sourcePath, destPath);
274
+ // Sanitize the imported rule for cross-tool compatibility
275
+ if (sanitizeRuleFile(destPath)) {
276
+ log.dim(" Sanitized frontmatter for cross-tool compatibility");
277
+ }
278
+ // Add to loadout definition
279
+ const loadoutPath = path.join(rootPath, "loadouts", `${options.loadout}.yaml`);
280
+ if (fileExists(loadoutPath)) {
281
+ try {
282
+ const def = parseLoadoutDefinition(loadoutPath);
283
+ const includeEntry = `rules/${name}.md`;
284
+ if (!def.include.some((i) => (typeof i === "string" ? i : i.path) === includeEntry)) {
285
+ def.include.push(includeEntry);
286
+ writeFile(loadoutPath, yaml.stringify(def));
287
+ log.success(`Added to ${options.loadout} loadout`);
288
+ }
289
+ }
290
+ catch (err) {
291
+ log.warn(`Could not update loadout: ${err instanceof Error ? err.message : String(err)}`);
292
+ }
293
+ }
294
+ // Remove original if not --keep
295
+ if (!options.keep) {
296
+ removeFile(sourcePath);
297
+ log.dim(`Removed original: ${sourcePath}`);
298
+ }
299
+ log.success(`Imported rule: ${name} (${scope})`);
300
+ log.dim(` ${destPath}`);
301
+ });
302
+ //# sourceMappingURL=rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.js","sourceRoot":"","sources":["../../../src/cli/commands/rule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * loadout sanitize — Sanitize artifacts for cross-tool compatibility.
3
+ *
4
+ * Currently sanitizes:
5
+ * - Rule frontmatter: ensures both `paths` and `globs` are present
6
+ *
7
+ * Scope flags:
8
+ * -l / --local → project scope only
9
+ * -g / --global → global scope only
10
+ * -a / --all → both scopes (default)
11
+ */
12
+ import { Command } from "commander";
13
+ export declare const sanitizeCommand: Command;
14
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,eAAe,SAiDxB,CAAC"}