@jean.gnc/harness-kit 0.5.1 → 0.7.0

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 (141) hide show
  1. package/README.md +91 -86
  2. package/dist/agent/schema.d.ts.map +1 -1
  3. package/dist/agent/schema.js +3 -9
  4. package/dist/agent/schema.js.map +1 -1
  5. package/dist/build.d.ts +4 -1
  6. package/dist/build.d.ts.map +1 -1
  7. package/dist/build.js +19 -3
  8. package/dist/build.js.map +1 -1
  9. package/dist/check/index.d.ts +2 -1
  10. package/dist/check/index.d.ts.map +1 -1
  11. package/dist/check/index.js +1 -0
  12. package/dist/check/index.js.map +1 -1
  13. package/dist/cli.js +64 -31
  14. package/dist/cli.js.map +1 -1
  15. package/dist/command/schema.d.ts.map +1 -1
  16. package/dist/command/schema.js +3 -9
  17. package/dist/command/schema.js.map +1 -1
  18. package/dist/compile/emit.d.ts +1 -0
  19. package/dist/compile/emit.d.ts.map +1 -1
  20. package/dist/compile/emit.js +50 -17
  21. package/dist/compile/emit.js.map +1 -1
  22. package/dist/compile/frontmatter.d.ts +1 -1
  23. package/dist/compile/frontmatter.d.ts.map +1 -1
  24. package/dist/compile/frontmatter.js +3 -4
  25. package/dist/compile/frontmatter.js.map +1 -1
  26. package/dist/compile/index.d.ts +2 -0
  27. package/dist/compile/index.d.ts.map +1 -1
  28. package/dist/compile/index.js +33 -31
  29. package/dist/compile/index.js.map +1 -1
  30. package/dist/compile/validators.d.ts.map +1 -1
  31. package/dist/compile/validators.js +6 -0
  32. package/dist/compile/validators.js.map +1 -1
  33. package/dist/config/harness.d.ts +15 -0
  34. package/dist/config/harness.d.ts.map +1 -0
  35. package/dist/config/harness.js +41 -0
  36. package/dist/config/harness.js.map +1 -0
  37. package/dist/configs/emit.d.ts +7 -0
  38. package/dist/configs/emit.d.ts.map +1 -0
  39. package/dist/configs/emit.js +12 -0
  40. package/dist/configs/emit.js.map +1 -0
  41. package/dist/configs/manifest.d.ts +16 -0
  42. package/dist/configs/manifest.d.ts.map +1 -0
  43. package/dist/configs/manifest.js +49 -0
  44. package/dist/configs/manifest.js.map +1 -0
  45. package/dist/index.d.ts +8 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +4 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/init/index.d.ts +8 -0
  50. package/dist/init/index.d.ts.map +1 -0
  51. package/dist/init/index.js +35 -0
  52. package/dist/init/index.js.map +1 -0
  53. package/dist/install/discovery.d.ts +3 -8
  54. package/dist/install/discovery.d.ts.map +1 -1
  55. package/dist/install/discovery.js +12 -10
  56. package/dist/install/discovery.js.map +1 -1
  57. package/dist/install/index.d.ts +7 -20
  58. package/dist/install/index.d.ts.map +1 -1
  59. package/dist/install/index.js +86 -27
  60. package/dist/install/index.js.map +1 -1
  61. package/dist/install/links.d.ts +16 -0
  62. package/dist/install/links.d.ts.map +1 -0
  63. package/dist/install/links.js +108 -0
  64. package/dist/install/links.js.map +1 -0
  65. package/dist/installed.d.ts +3 -1
  66. package/dist/installed.d.ts.map +1 -1
  67. package/dist/installed.js +13 -25
  68. package/dist/installed.js.map +1 -1
  69. package/dist/layout/conventions.d.ts +4 -0
  70. package/dist/layout/conventions.d.ts.map +1 -0
  71. package/dist/layout/conventions.js +4 -0
  72. package/dist/layout/conventions.js.map +1 -0
  73. package/dist/layout/index.d.ts +1 -0
  74. package/dist/layout/index.d.ts.map +1 -1
  75. package/dist/layout/index.js +10 -14
  76. package/dist/layout/index.js.map +1 -1
  77. package/dist/link/applier.d.ts +6 -0
  78. package/dist/link/applier.d.ts.map +1 -0
  79. package/dist/link/applier.js +38 -0
  80. package/dist/link/applier.js.map +1 -0
  81. package/dist/lint.d.ts +3 -0
  82. package/dist/lint.d.ts.map +1 -1
  83. package/dist/lint.js +9 -6
  84. package/dist/lint.js.map +1 -1
  85. package/dist/marketplace/schema.d.ts +1707 -88
  86. package/dist/marketplace/schema.d.ts.map +1 -1
  87. package/dist/marketplace/schema.js +15 -7
  88. package/dist/marketplace/schema.js.map +1 -1
  89. package/dist/placeholders/source-position.d.ts.map +1 -1
  90. package/dist/placeholders/source-position.js +2 -1
  91. package/dist/placeholders/source-position.js.map +1 -1
  92. package/dist/plugin/index.d.ts +1 -1
  93. package/dist/plugin/index.d.ts.map +1 -1
  94. package/dist/plugin/schema.d.ts +186 -55
  95. package/dist/plugin/schema.d.ts.map +1 -1
  96. package/dist/plugin/schema.js +21 -15
  97. package/dist/plugin/schema.js.map +1 -1
  98. package/dist/readme/index.d.ts +1 -5
  99. package/dist/readme/index.d.ts.map +1 -1
  100. package/dist/readme/index.js.map +1 -1
  101. package/dist/schema-primitives.d.ts +5 -0
  102. package/dist/schema-primitives.d.ts.map +1 -0
  103. package/dist/schema-primitives.js +15 -0
  104. package/dist/schema-primitives.js.map +1 -0
  105. package/dist/skill/schema.d.ts +2 -2
  106. package/dist/skill/schema.d.ts.map +1 -1
  107. package/dist/skill/schema.js +4 -13
  108. package/dist/skill/schema.js.map +1 -1
  109. package/dist/vendor/builtins.d.ts +3 -0
  110. package/dist/vendor/builtins.d.ts.map +1 -0
  111. package/dist/vendor/builtins.js +6 -0
  112. package/dist/vendor/builtins.js.map +1 -0
  113. package/dist/vendor/registry.d.ts +4 -0
  114. package/dist/vendor/registry.d.ts.map +1 -0
  115. package/dist/vendor/registry.js +26 -0
  116. package/dist/vendor/registry.js.map +1 -0
  117. package/dist/vendor/schema.d.ts +43 -0
  118. package/dist/vendor/schema.d.ts.map +1 -0
  119. package/dist/vendor/schema.js +2 -0
  120. package/dist/vendor/schema.js.map +1 -0
  121. package/dist/vendors/claude/index.d.ts +4 -0
  122. package/dist/vendors/claude/index.d.ts.map +1 -0
  123. package/dist/vendors/claude/index.js +69 -0
  124. package/dist/vendors/claude/index.js.map +1 -0
  125. package/dist/vendors/codex/index.d.ts +4 -0
  126. package/dist/vendors/codex/index.d.ts.map +1 -0
  127. package/dist/vendors/codex/index.js +53 -0
  128. package/dist/vendors/codex/index.js.map +1 -0
  129. package/dist/vendors/shared.d.ts +4 -0
  130. package/dist/vendors/shared.d.ts.map +1 -0
  131. package/dist/vendors/shared.js +42 -0
  132. package/dist/vendors/shared.js.map +1 -0
  133. package/package.json +9 -3
  134. package/dist/install/claude.d.ts +0 -4
  135. package/dist/install/claude.d.ts.map +0 -1
  136. package/dist/install/claude.js +0 -37
  137. package/dist/install/claude.js.map +0 -1
  138. package/dist/install/codex.d.ts +0 -4
  139. package/dist/install/codex.d.ts.map +0 -1
  140. package/dist/install/codex.js +0 -29
  141. package/dist/install/codex.js.map +0 -1
package/dist/index.js CHANGED
@@ -7,6 +7,10 @@ export { compile } from "./compile/index.js";
7
7
  export { build } from "./build.js";
8
8
  export { lint } from "./lint.js";
9
9
  export { install, uninstall } from "./install/index.js";
10
+ export { initHarness } from "./init/index.js";
11
+ export { loadHarnessConfig } from "./config/harness.js";
12
+ export { builtinVendors } from "./vendor/builtins.js";
13
+ export { resolveVendors } from "./vendor/registry.js";
10
14
  export { check } from "./check/index.js";
11
15
  export { defaultSources, discoverInstalled, indexInstalled } from "./installed.js";
12
16
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,2BAA2B,EAC3B,SAAS,GACV,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGnF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG9E,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAGtC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AASxE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AASzC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,2BAA2B,EAC3B,SAAS,GACV,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGnF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG9E,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAGtC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AASxE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAStD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AASzC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface InitOptions {
2
+ readonly repoRoot: string;
3
+ readonly marketplace: string;
4
+ readonly vendors: readonly string[];
5
+ readonly silent?: boolean;
6
+ }
7
+ export declare function initHarness(options: InitOptions): Promise<void>;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/init/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBrE"}
@@ -0,0 +1,35 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import yaml from "js-yaml";
4
+ import { pathExists } from "../fs.js";
5
+ export async function initHarness(options) {
6
+ const configPath = join(options.repoRoot, "harness.yaml");
7
+ if (await pathExists(configPath)) {
8
+ throw new Error(`harness.yaml already exists at ${configPath}`);
9
+ }
10
+ const doc = yaml.dump({ marketplace: options.marketplace, vendors: [...options.vendors] }, { lineWidth: 120 });
11
+ await writeFile(configPath, doc);
12
+ await scaffoldKeep(join(options.repoRoot, "src/configs/common"));
13
+ for (const vendor of options.vendors) {
14
+ await scaffoldKeep(join(options.repoRoot, "src/configs", vendor));
15
+ }
16
+ await scaffoldKeep(join(options.repoRoot, "src/plugins"));
17
+ await ensureGitignore(options.repoRoot);
18
+ if (!options.silent) {
19
+ console.log(`scaffolded harness in ${options.repoRoot}`);
20
+ }
21
+ }
22
+ async function scaffoldKeep(dir) {
23
+ await mkdir(dir, { recursive: true });
24
+ await writeFile(join(dir, ".gitkeep"), "");
25
+ }
26
+ async function ensureGitignore(repoRoot) {
27
+ const path = join(repoRoot, ".gitignore");
28
+ const existing = (await pathExists(path)) ? await readFile(path, "utf8") : "";
29
+ const hasDist = /^dist\/?$/m.test(existing);
30
+ if (hasDist)
31
+ return;
32
+ const trailing = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
33
+ await writeFile(path, `${existing}${trailing}dist/\n`);
34
+ }
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAStC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAC1D,IAAI,MAAM,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,kCAAkC,UAAU,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CACnB,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,EACnE,EAAE,SAAS,EAAE,GAAG,EAAE,CACnB,CAAC;IACF,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACjE,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;IAC1D,MAAM,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,yBAAyB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,GAAW;IACrC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,QAAgB;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,OAAO;QAAE,OAAO;IACpB,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,QAAQ,GAAG,QAAQ,SAAS,CAAC,CAAC;AACzD,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import type { DiscoveredVendorPlugin, Vendor } from "../vendor/schema.js";
2
3
  export declare const PluginManifestSchema: z.ZodObject<{
3
4
  name: z.ZodString;
4
5
  version: z.ZodString;
@@ -10,12 +11,6 @@ export declare const PluginManifestSchema: z.ZodObject<{
10
11
  version: string;
11
12
  }>;
12
13
  export type PluginManifest = z.infer<typeof PluginManifestSchema>;
13
- export interface DiscoveredPlugin {
14
- readonly name: string;
15
- readonly path: string;
16
- readonly claudeManifest: PluginManifest | null;
17
- readonly codexManifest: PluginManifest | null;
18
- }
19
- export declare function readMarketplaceName(distRoot: string): Promise<string>;
20
- export declare function discoverPlugins(distRoot: string): Promise<readonly DiscoveredPlugin[]>;
14
+ export declare function readMarketplaceName(distRoot: string, vendor: Vendor): Promise<string>;
15
+ export declare function discoverPluginsForVendor(distRoot: string, vendor: Vendor): Promise<readonly DiscoveredVendorPlugin[]>;
21
16
  //# sourceMappingURL=discovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/install/discovery.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,oBAAoB;;;;;;;;;EAG/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMlE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,aAAa,EAAE,cAAc,GAAG,IAAI,CAAC;CAC/C;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU3E;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAa5F"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/install/discovery.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE1E,eAAO,MAAM,oBAAoB;;;;;;;;;EAG/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMlE,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU3F;AAED,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,sBAAsB,EAAE,CAAC,CAa5C"}
@@ -2,6 +2,7 @@ import { readdir, readFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { z } from "zod";
4
4
  import { formatZodIssues } from "../errors/index.js";
5
+ import { pathExists } from "../fs.js";
5
6
  export const PluginManifestSchema = z.object({
6
7
  name: z.string().min(1),
7
8
  version: z.string().min(1),
@@ -9,8 +10,8 @@ export const PluginManifestSchema = z.object({
9
10
  const MarketplaceManifestSchema = z.object({
10
11
  name: z.string().min(1),
11
12
  });
12
- export async function readMarketplaceName(distRoot) {
13
- const manifestPath = join(distRoot, ".claude-plugin/marketplace.json");
13
+ export async function readMarketplaceName(distRoot, vendor) {
14
+ const manifestPath = join(distRoot, vendor.marketplaceManifestPath);
14
15
  const raw = await readFile(manifestPath, "utf8");
15
16
  const parsed = MarketplaceManifestSchema.safeParse(JSON.parse(raw));
16
17
  if (!parsed.success) {
@@ -18,19 +19,20 @@ export async function readMarketplaceName(distRoot) {
18
19
  }
19
20
  return parsed.data.name;
20
21
  }
21
- export async function discoverPlugins(distRoot) {
22
- const pluginsDir = join(distRoot, "plugins");
23
- const entries = await readdir(pluginsDir, { withFileTypes: true });
22
+ export async function discoverPluginsForVendor(distRoot, vendor) {
23
+ const vendorDir = vendor.vendorOutDir(distRoot);
24
+ if (!(await pathExists(vendorDir)))
25
+ return [];
26
+ const entries = await readdir(vendorDir, { withFileTypes: true });
24
27
  const result = [];
25
28
  for (const entry of entries) {
26
29
  if (!entry.isDirectory())
27
30
  continue;
28
- const path = join(pluginsDir, entry.name);
29
- const claudeManifest = await tryReadManifest(join(path, ".claude-plugin/plugin.json"));
30
- const codexManifest = await tryReadManifest(join(path, ".codex-plugin/plugin.json"));
31
- if (!claudeManifest && !codexManifest)
31
+ const path = vendor.pluginOutDir(distRoot, entry.name);
32
+ const manifest = await tryReadManifest(join(path, vendor.pluginManifestPath));
33
+ if (!manifest)
32
34
  continue;
33
- result.push({ name: entry.name, path, claudeManifest, codexManifest });
35
+ result.push({ name: entry.name, path, version: manifest.version });
34
36
  }
35
37
  return result;
36
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/install/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3B,CAAC,CAAC;AAIH,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACxB,CAAC,CAAC;AASH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAgB;IACxD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,iCAAiC,CAAC,CAAC;IACvE,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,yBAAyB,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,mCAAmC,YAAY,KAAK,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,SAAS;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC;QACvF,MAAM,aAAa,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,2BAA2B,CAAC,CAAC,CAAC;QACrF,IAAI,CAAC,cAAc,IAAI,CAAC,aAAa;YAAE,SAAS;QAChD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY;IACzC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,8BAA8B,IAAI,KAAK,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/install/discovery.ts"],"names":[],"mappings":"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"}
@@ -1,28 +1,15 @@
1
- import type { DiscoveredPlugin } from "./discovery.js";
2
1
  import { type CommandRunner } from "./runner.js";
3
- export type Target = "claude" | "codex";
2
+ import type { Vendor } from "../vendor/schema.js";
4
3
  export interface InstallOptions {
5
4
  readonly distRoot?: string;
6
- readonly targets?: readonly Target[];
7
- readonly claudeHome?: string;
8
- readonly codexHome?: string;
5
+ readonly repoRoot?: string;
6
+ readonly vendors: readonly Vendor[];
9
7
  readonly silent?: boolean;
8
+ readonly dryRun?: boolean;
9
+ readonly log?: (msg: string) => void;
10
10
  }
11
- /** @internal Used by per-target modules; not part of the public surface. */
12
- export interface InstallContext {
13
- readonly distRoot: string;
14
- readonly claudeHome: string;
15
- readonly codexHome: string;
16
- readonly targets: ReadonlySet<Target>;
17
- readonly marketplace: string;
18
- readonly plugins: readonly DiscoveredPlugin[];
19
- readonly run: CommandRunner;
20
- readonly log: (msg: string) => void;
21
- }
22
- export declare function install(options?: InstallOptions): Promise<void>;
23
- export declare function uninstall(options?: InstallOptions): Promise<void>;
24
- /** @internal Test-only entry; lets callers inject a recording runner. */
11
+ export declare function install(options: InstallOptions): Promise<void>;
12
+ export declare function uninstall(options: InstallOptions): Promise<void>;
25
13
  export declare function installWithRunner(options: InstallOptions, runner: CommandRunner): Promise<void>;
26
- /** @internal Test-only entry; lets callers inject a recording runner. */
27
14
  export declare function uninstallWithRunner(options: InstallOptions, runner: CommandRunner): Promise<void>;
28
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/install/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAIhE,MAAM,MAAM,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAExC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAID,wBAAsB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAED,wBAAsB,SAAS,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3E;AAED,yEAAyE;AACzE,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,yEAAyE;AACzE,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAIf"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/install/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAwB,MAAM,qBAAqB,CAAC;AAExE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpE;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAUf"}
@@ -1,44 +1,103 @@
1
- import { homedir } from "node:os";
2
- import { resolve, join } from "node:path";
3
- import { discoverPlugins, readMarketplaceName } from "./discovery.js";
1
+ import { resolve } from "node:path";
2
+ import { applyConfigLinks, formatPlannedLink, planConfigLinks } from "./links.js";
3
+ import { discoverPluginsForVendor, readMarketplaceName } from "./discovery.js";
4
4
  import { defaultRunner } from "./runner.js";
5
- import { installClaude, uninstallClaude } from "./claude.js";
6
- import { installCodex, uninstallCodex } from "./codex.js";
7
- const ALL_TARGETS = ["claude", "codex"];
8
- export async function install(options = {}) {
5
+ export async function install(options) {
9
6
  await installWithRunner(options, defaultRunner);
10
7
  }
11
- export async function uninstall(options = {}) {
8
+ export async function uninstall(options) {
12
9
  await uninstallWithRunner(options, defaultRunner);
13
10
  }
14
- /** @internal Test-only entry; lets callers inject a recording runner. */
15
11
  export async function installWithRunner(options, runner) {
16
12
  const ctx = await resolveContext(options, runner);
17
- if (ctx.targets.has("claude"))
18
- await installClaude(ctx);
19
- if (ctx.targets.has("codex"))
20
- await installCodex(ctx);
13
+ if (options.dryRun) {
14
+ await runDryRun(ctx);
15
+ return;
16
+ }
17
+ await applyConfigLinks({ repoRoot: ctx.repoRoot, distRoot: ctx.distRoot, vendors: ctx.vendors });
18
+ for (const vendor of ctx.vendors) {
19
+ const plugins = await discoverPluginsForVendor(ctx.distRoot, vendor);
20
+ await vendor.install(buildVendorContext(ctx, plugins));
21
+ }
21
22
  }
22
- /** @internal Test-only entry; lets callers inject a recording runner. */
23
23
  export async function uninstallWithRunner(options, runner) {
24
24
  const ctx = await resolveContext(options, runner);
25
- if (ctx.targets.has("claude"))
26
- await uninstallClaude(ctx);
27
- if (ctx.targets.has("codex"))
28
- await uninstallCodex(ctx);
25
+ if (options.dryRun) {
26
+ await runUninstallDryRun(ctx);
27
+ return;
28
+ }
29
+ for (const vendor of ctx.vendors) {
30
+ const plugins = await discoverPluginsForVendor(ctx.distRoot, vendor);
31
+ await vendor.uninstall(buildVendorContext(ctx, plugins));
32
+ }
29
33
  }
30
34
  async function resolveContext(options, runner) {
35
+ if (options.vendors.length === 0) {
36
+ throw new Error("install requires at least one vendor");
37
+ }
31
38
  const distRoot = resolve(options.distRoot ?? "./dist");
32
- const claudeHome = options.claudeHome ?? join(homedir(), ".claude");
33
- const codexHome = options.codexHome ?? join(homedir(), ".codex");
34
- const targets = new Set(options.targets ?? ALL_TARGETS);
39
+ const repoRoot = resolve(options.repoRoot ?? ".");
35
40
  const silent = options.silent ?? false;
36
- const log = (msg) => {
37
- if (!silent)
38
- console.log(msg);
41
+ const log = options.log ??
42
+ ((msg) => {
43
+ if (!silent)
44
+ console.log(msg);
45
+ });
46
+ const marketplace = await resolveMarketplaceName(distRoot, options.vendors);
47
+ return { distRoot, repoRoot, vendors: options.vendors, marketplace, run: runner, log };
48
+ }
49
+ async function resolveMarketplaceName(distRoot, vendors) {
50
+ const names = await Promise.all(vendors.map(async (v) => readMarketplaceName(distRoot, v)));
51
+ const [first, ...rest] = names;
52
+ if (first === undefined)
53
+ throw new Error("install requires at least one vendor");
54
+ const mismatch = rest.find((n) => n !== first);
55
+ if (mismatch !== undefined) {
56
+ throw new Error(`vendor marketplaces disagree on name: got "${mismatch}", expected "${first}"`);
57
+ }
58
+ return first;
59
+ }
60
+ function buildVendorContext(ctx, plugins) {
61
+ return {
62
+ distRoot: ctx.distRoot,
63
+ marketplace: ctx.marketplace,
64
+ plugins,
65
+ run: ctx.run,
66
+ log: ctx.log,
39
67
  };
40
- const marketplace = await readMarketplaceName(distRoot);
41
- const plugins = await discoverPlugins(distRoot);
42
- return { distRoot, claudeHome, codexHome, targets, marketplace, plugins, run: runner, log };
68
+ }
69
+ async function runUninstallDryRun(ctx) {
70
+ for (const vendor of ctx.vendors) {
71
+ const plugins = await discoverPluginsForVendor(ctx.distRoot, vendor);
72
+ if (plugins.length === 0) {
73
+ ctx.log(`[dry-run] ${vendor.name}: no plugins to uninstall`);
74
+ continue;
75
+ }
76
+ ctx.log(`[dry-run] ${vendor.name}: would uninstall ${plugins.length} plugin(s):`);
77
+ for (const p of plugins)
78
+ ctx.log(` ${p.name}@${p.version}`);
79
+ }
80
+ }
81
+ async function runDryRun(ctx) {
82
+ const plan = await planConfigLinks({
83
+ repoRoot: ctx.repoRoot,
84
+ distRoot: ctx.distRoot,
85
+ vendors: ctx.vendors,
86
+ });
87
+ if (plan.length > 0) {
88
+ ctx.log("[dry-run] config links:");
89
+ for (const entry of plan)
90
+ ctx.log(` ${formatPlannedLink(entry, ctx.repoRoot)}`);
91
+ }
92
+ for (const vendor of ctx.vendors) {
93
+ const plugins = await discoverPluginsForVendor(ctx.distRoot, vendor);
94
+ if (plugins.length === 0) {
95
+ ctx.log(`[dry-run] ${vendor.name}: no plugins`);
96
+ continue;
97
+ }
98
+ ctx.log(`[dry-run] ${vendor.name}: would install ${plugins.length} plugin(s):`);
99
+ for (const p of plugins)
100
+ ctx.log(` ${p.name}@${p.version}`);
101
+ }
43
102
  }
44
103
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/install/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAsB,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAwB1D,MAAM,WAAW,GAAsB,CAAC,QAAQ,EAAE,OAAO,CAAU,CAAC;AAEpE,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,UAA0B,EAAE;IACxD,MAAM,iBAAiB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,UAA0B,EAAE;IAC1D,MAAM,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AACpD,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAuB,EACvB,MAAqB;IAErB,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAuB,EACvB,MAAqB;IAErB,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,OAAuB,EACvB,MAAqB;IAErB,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACvC,MAAM,GAAG,GAAG,CAAC,GAAW,EAAQ,EAAE;QAChC,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;IAChD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC9F,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/install/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Vendor } from "../vendor/schema.js";
2
+ export interface ApplyConfigLinksOptions {
3
+ readonly repoRoot: string;
4
+ readonly distRoot: string;
5
+ readonly vendors: readonly Vendor[];
6
+ }
7
+ export interface PlannedLink {
8
+ readonly srcAbs: string;
9
+ readonly destAbs: string;
10
+ readonly vendor: string;
11
+ readonly reason: "link" | "alias";
12
+ }
13
+ export declare function planConfigLinks(options: ApplyConfigLinksOptions): Promise<readonly PlannedLink[]>;
14
+ export declare function applyConfigLinks(options: ApplyConfigLinksOptions): Promise<void>;
15
+ export declare function formatPlannedLink(entry: PlannedLink, repoRoot: string): string;
16
+ //# sourceMappingURL=links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/install/links.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAalD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAgCjC;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtF;AAmDD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI9E"}
@@ -0,0 +1,108 @@
1
+ import { readFile, readdir, readlink, rm } from "node:fs/promises";
2
+ import { basename, dirname, join, relative, resolve } from "node:path";
3
+ import { z } from "zod";
4
+ import { formatZodIssues } from "../errors/index.js";
5
+ import { pathExists } from "../fs.js";
6
+ import { applyLink } from "../link/applier.js";
7
+ const ConfigsManifestSchema = z.object({
8
+ links: z.array(z.object({
9
+ src: z.string().min(1),
10
+ vendors: z.array(z.string().min(1)),
11
+ destRel: z.string().min(1),
12
+ kind: z.enum(["file", "dir"]),
13
+ })),
14
+ });
15
+ export async function planConfigLinks(options) {
16
+ const manifestPath = join(options.distRoot, "configs.json");
17
+ if (!(await pathExists(manifestPath)))
18
+ return [];
19
+ const raw = await readFile(manifestPath, "utf8");
20
+ const parsed = ConfigsManifestSchema.safeParse(JSON.parse(raw));
21
+ if (!parsed.success) {
22
+ throw new Error(`invalid configs manifest at ${manifestPath}: ${formatZodIssues(parsed.error).join("; ")}`);
23
+ }
24
+ const vendorsByName = new Map(options.vendors.map((v) => [v.name, v]));
25
+ const plan = [];
26
+ for (const link of parsed.data.links) {
27
+ const srcAbs = join(options.repoRoot, "src", link.src);
28
+ for (const vendorName of link.vendors) {
29
+ const vendor = vendorsByName.get(vendorName);
30
+ if (!vendor)
31
+ continue;
32
+ const destAbs = join(vendor.home, link.destRel);
33
+ plan.push({ srcAbs, destAbs, vendor: vendor.name, reason: "link" });
34
+ const aliasDests = vendor.aliases?.({
35
+ srcAbs,
36
+ destAbs,
37
+ destRel: link.destRel,
38
+ basename: basename(link.destRel),
39
+ }) ?? [];
40
+ for (const aliasDest of aliasDests) {
41
+ plan.push({ srcAbs, destAbs: aliasDest, vendor: vendor.name, reason: "alias" });
42
+ }
43
+ }
44
+ }
45
+ return plan;
46
+ }
47
+ export async function applyConfigLinks(options) {
48
+ const plan = await planConfigLinks(options);
49
+ await sweepOrphanLinks(plan, options);
50
+ for (const entry of plan) {
51
+ await applyLink({ srcAbs: entry.srcAbs, destAbs: entry.destAbs });
52
+ }
53
+ }
54
+ async function sweepOrphanLinks(plan, options) {
55
+ const managedRoot = options.repoRoot + "/";
56
+ const planned = new Set(plan.map((p) => p.destAbs));
57
+ const scanDirs = new Set([
58
+ ...options.vendors.map((v) => v.home),
59
+ ...plan.map((p) => dirname(p.destAbs)),
60
+ ]);
61
+ for (const dir of scanDirs) {
62
+ const entries = await readdirOrEmpty(dir);
63
+ for (const name of entries) {
64
+ const path = join(dir, name);
65
+ if (planned.has(path))
66
+ continue;
67
+ const target = await readlinkOrNull(path);
68
+ if (target === null)
69
+ continue;
70
+ const absTarget = resolve(dir, target);
71
+ if (!absTarget.startsWith(managedRoot))
72
+ continue;
73
+ await rm(path);
74
+ }
75
+ }
76
+ }
77
+ function errnoCode(e) {
78
+ if (e instanceof Error && "code" in e && typeof e.code === "string")
79
+ return e.code;
80
+ return null;
81
+ }
82
+ async function readdirOrEmpty(dir) {
83
+ try {
84
+ return await readdir(dir);
85
+ }
86
+ catch (e) {
87
+ if (errnoCode(e) === "ENOENT")
88
+ return [];
89
+ throw e;
90
+ }
91
+ }
92
+ async function readlinkOrNull(path) {
93
+ try {
94
+ return await readlink(path);
95
+ }
96
+ catch (e) {
97
+ const code = errnoCode(e);
98
+ if (code === "EINVAL" || code === "ENOENT")
99
+ return null;
100
+ throw e;
101
+ }
102
+ }
103
+ export function formatPlannedLink(entry, repoRoot) {
104
+ const src = relative(repoRoot, entry.srcAbs);
105
+ const tag = entry.reason === "alias" ? " (alias)" : "";
106
+ return `[${entry.vendor}] ${src} → ${entry.destAbs}${tag}`;
107
+ }
108
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/install/links.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
+ import type { Vendor } from "./vendor/schema.js";
1
2
  export interface PluginSource {
2
3
  readonly name: string;
3
4
  readonly root: string;
5
+ readonly manifestRelativePath: string;
4
6
  }
5
7
  export interface InstalledSkill {
6
8
  readonly source: string;
@@ -30,7 +32,7 @@ export interface InstalledIndex {
30
32
  readonly commands: ReadonlyMap<string, readonly InstalledCommand[]>;
31
33
  readonly agents: ReadonlyMap<string, readonly InstalledAgent[]>;
32
34
  }
33
- export declare function defaultSources(): readonly PluginSource[];
35
+ export declare function defaultSources(vendors?: readonly Vendor[]): readonly PluginSource[];
34
36
  export declare function discoverInstalled(sources: readonly PluginSource[]): Promise<InstalledArtifacts>;
35
37
  export declare function indexInstalled(artifacts: InstalledArtifacts): InstalledIndex;
36
38
  //# sourceMappingURL=installed.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"installed.d.ts","sourceRoot":"","sources":["../src/installed.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC,CAAC;IAChE,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC,CAAC;IACpE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC,CAAC;CACjE;AAED,wBAAgB,cAAc,IAAI,SAAS,YAAY,EAAE,CAMxD;AAOD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,SAAS,YAAY,EAAE,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CAiC7B;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,kBAAkB,GAAG,cAAc,CAM5E"}
1
+ {"version":3,"file":"installed.d.ts","sourceRoot":"","sources":["../src/installed.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAIjD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC,CAAC;IAChE,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC,CAAC;IACpE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC,CAAC;CACjE;AAED,wBAAgB,cAAc,CAC5B,OAAO,GAAE,SAAS,MAAM,EAAqB,GAC5C,SAAS,YAAY,EAAE,CAMzB;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,SAAS,YAAY,EAAE,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CAiC7B;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,kBAAkB,GAAG,cAAc,CAM5E"}
package/dist/installed.js CHANGED
@@ -1,25 +1,21 @@
1
- import { readFile, readdir } from "node:fs/promises";
2
- import { homedir } from "node:os";
1
+ import { access, readFile, readdir } from "node:fs/promises";
3
2
  import { join } from "node:path";
4
3
  import { z } from "zod";
4
+ import { builtinVendors } from "./vendor/builtins.js";
5
5
  const PluginManifestSchema = z.object({ name: z.string().min(1) });
6
- export function defaultSources() {
7
- const home = homedir();
8
- return [
9
- { name: "claude", root: join(home, ".claude/plugins/cache") },
10
- { name: "codex", root: join(home, ".codex/plugins/cache") },
11
- ];
6
+ export function defaultSources(vendors = builtinVendors()) {
7
+ return vendors.map((vendor) => ({
8
+ name: vendor.name,
9
+ root: join(vendor.home, "plugins/cache"),
10
+ manifestRelativePath: vendor.pluginManifestPath,
11
+ }));
12
12
  }
13
- const PLUGIN_MANIFEST_RELATIVE_PATHS = [
14
- ".claude-plugin/plugin.json",
15
- ".codex-plugin/plugin.json",
16
- ];
17
13
  export async function discoverInstalled(sources) {
18
14
  const skills = [];
19
15
  const commands = [];
20
16
  const agents = [];
21
17
  for (const source of sources) {
22
- for await (const plugin of findPluginRoots(source.root)) {
18
+ for await (const plugin of findPluginRoots(source.root, source.manifestRelativePath)) {
23
19
  for await (const skill of collectSkills(plugin.root)) {
24
20
  skills.push({
25
21
  source: source.name,
@@ -67,8 +63,8 @@ function groupBy(items, key) {
67
63
  }
68
64
  return result;
69
65
  }
70
- async function* findPluginRoots(dir) {
71
- const name = await readPluginNameAt(dir);
66
+ async function* findPluginRoots(dir, manifestRelativePath) {
67
+ const name = await readPluginName(join(dir, manifestRelativePath));
72
68
  if (name !== null) {
73
69
  yield { name, root: dir };
74
70
  return;
@@ -84,17 +80,9 @@ async function* findPluginRoots(dir) {
84
80
  if (entry.isSymbolicLink())
85
81
  continue;
86
82
  if (entry.isDirectory())
87
- yield* findPluginRoots(join(dir, entry.name));
83
+ yield* findPluginRoots(join(dir, entry.name), manifestRelativePath);
88
84
  }
89
85
  }
90
- async function readPluginNameAt(dir) {
91
- for (const rel of PLUGIN_MANIFEST_RELATIVE_PATHS) {
92
- const name = await readPluginName(join(dir, rel));
93
- if (name)
94
- return name;
95
- }
96
- return null;
97
- }
98
86
  async function* collectSkills(pluginRoot) {
99
87
  const skillsDir = join(pluginRoot, "skills");
100
88
  let entries;
@@ -109,7 +97,7 @@ async function* collectSkills(pluginRoot) {
109
97
  continue;
110
98
  const skillFile = join(skillsDir, entry.name, "SKILL.md");
111
99
  try {
112
- await readFile(skillFile, "utf8");
100
+ await access(skillFile);
113
101
  }
114
102
  catch {
115
103
  continue;