@x-code-cli/core 0.2.10 → 0.3.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 (251) hide show
  1. package/dist/agent/compression.d.ts +12 -2
  2. package/dist/agent/compression.d.ts.map +1 -1
  3. package/dist/agent/compression.js +51 -2
  4. package/dist/agent/compression.js.map +1 -1
  5. package/dist/agent/file-ingest.js +2 -2
  6. package/dist/agent/file-ingest.js.map +1 -1
  7. package/dist/agent/loop-state.d.ts +3 -2
  8. package/dist/agent/loop-state.d.ts.map +1 -1
  9. package/dist/agent/loop-state.js.map +1 -1
  10. package/dist/agent/loop.d.ts.map +1 -1
  11. package/dist/agent/loop.js +134 -5
  12. package/dist/agent/loop.js.map +1 -1
  13. package/dist/agent/memory-extractor.js +5 -5
  14. package/dist/agent/memory-extractor.js.map +1 -1
  15. package/dist/agent/plan-storage.js +1 -1
  16. package/dist/agent/plan-storage.js.map +1 -1
  17. package/dist/agent/sub-agents/index.d.ts +2 -1
  18. package/dist/agent/sub-agents/index.d.ts.map +1 -1
  19. package/dist/agent/sub-agents/index.js +1 -1
  20. package/dist/agent/sub-agents/index.js.map +1 -1
  21. package/dist/agent/sub-agents/loader.d.ts +13 -3
  22. package/dist/agent/sub-agents/loader.d.ts.map +1 -1
  23. package/dist/agent/sub-agents/loader.js +36 -9
  24. package/dist/agent/sub-agents/loader.js.map +1 -1
  25. package/dist/agent/sub-agents/registry.d.ts +18 -1
  26. package/dist/agent/sub-agents/registry.d.ts.map +1 -1
  27. package/dist/agent/sub-agents/registry.js +38 -5
  28. package/dist/agent/sub-agents/registry.js.map +1 -1
  29. package/dist/agent/sub-agents/runner.d.ts.map +1 -1
  30. package/dist/agent/sub-agents/runner.js +45 -1
  31. package/dist/agent/sub-agents/runner.js.map +1 -1
  32. package/dist/agent/sub-agents/types.d.ts +4 -1
  33. package/dist/agent/sub-agents/types.d.ts.map +1 -1
  34. package/dist/agent/system-prompt.d.ts +21 -0
  35. package/dist/agent/system-prompt.d.ts.map +1 -1
  36. package/dist/agent/system-prompt.js +68 -2
  37. package/dist/agent/system-prompt.js.map +1 -1
  38. package/dist/agent/tool-execution.d.ts.map +1 -1
  39. package/dist/agent/tool-execution.js +220 -1
  40. package/dist/agent/tool-execution.js.map +1 -1
  41. package/dist/commands/index.d.ts +6 -0
  42. package/dist/commands/index.d.ts.map +1 -0
  43. package/dist/commands/index.js +3 -0
  44. package/dist/commands/index.js.map +1 -0
  45. package/dist/commands/loader.d.ts +13 -0
  46. package/dist/commands/loader.d.ts.map +1 -0
  47. package/dist/commands/loader.js +93 -0
  48. package/dist/commands/loader.js.map +1 -0
  49. package/dist/commands/registry.d.ts +44 -0
  50. package/dist/commands/registry.d.ts.map +1 -0
  51. package/dist/commands/registry.js +102 -0
  52. package/dist/commands/registry.js.map +1 -0
  53. package/dist/commands/types.d.ts +23 -0
  54. package/dist/commands/types.d.ts.map +1 -0
  55. package/dist/commands/types.js +26 -0
  56. package/dist/commands/types.js.map +1 -0
  57. package/dist/config/index.d.ts +9 -0
  58. package/dist/config/index.d.ts.map +1 -1
  59. package/dist/config/index.js +12 -10
  60. package/dist/config/index.js.map +1 -1
  61. package/dist/hooks/bus.d.ts +54 -0
  62. package/dist/hooks/bus.d.ts.map +1 -0
  63. package/dist/hooks/bus.js +165 -0
  64. package/dist/hooks/bus.js.map +1 -0
  65. package/dist/hooks/config-schema.d.ts +854 -0
  66. package/dist/hooks/config-schema.d.ts.map +1 -0
  67. package/dist/hooks/config-schema.js +79 -0
  68. package/dist/hooks/config-schema.js.map +1 -0
  69. package/dist/hooks/executor.d.ts +16 -0
  70. package/dist/hooks/executor.d.ts.map +1 -0
  71. package/dist/hooks/executor.js +183 -0
  72. package/dist/hooks/executor.js.map +1 -0
  73. package/dist/hooks/index.d.ts +10 -0
  74. package/dist/hooks/index.d.ts.map +1 -0
  75. package/dist/hooks/index.js +6 -0
  76. package/dist/hooks/index.js.map +1 -0
  77. package/dist/hooks/registry.d.ts +23 -0
  78. package/dist/hooks/registry.d.ts.map +1 -0
  79. package/dist/hooks/registry.js +49 -0
  80. package/dist/hooks/registry.js.map +1 -0
  81. package/dist/hooks/types.d.ts +165 -0
  82. package/dist/hooks/types.d.ts.map +1 -0
  83. package/dist/hooks/types.js +25 -0
  84. package/dist/hooks/types.js.map +1 -0
  85. package/dist/hooks/variables.d.ts +22 -0
  86. package/dist/hooks/variables.d.ts.map +1 -0
  87. package/dist/hooks/variables.js +80 -0
  88. package/dist/hooks/variables.js.map +1 -0
  89. package/dist/index.d.ts +56 -1
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +37 -1
  92. package/dist/index.js.map +1 -1
  93. package/dist/knowledge/auto-memory.d.ts +1 -1
  94. package/dist/knowledge/auto-memory.d.ts.map +1 -1
  95. package/dist/knowledge/auto-memory.js +10 -10
  96. package/dist/knowledge/auto-memory.js.map +1 -1
  97. package/dist/knowledge/loader.js +12 -12
  98. package/dist/knowledge/loader.js.map +1 -1
  99. package/dist/mcp/arg-parser.d.ts +49 -0
  100. package/dist/mcp/arg-parser.d.ts.map +1 -0
  101. package/dist/mcp/arg-parser.js +357 -0
  102. package/dist/mcp/arg-parser.js.map +1 -0
  103. package/dist/mcp/client.d.ts +73 -0
  104. package/dist/mcp/client.d.ts.map +1 -0
  105. package/dist/mcp/client.js +376 -0
  106. package/dist/mcp/client.js.map +1 -0
  107. package/dist/mcp/config-schema.d.ts +64 -0
  108. package/dist/mcp/config-schema.d.ts.map +1 -0
  109. package/dist/mcp/config-schema.js +86 -0
  110. package/dist/mcp/config-schema.js.map +1 -0
  111. package/dist/mcp/config-writer.d.ts +41 -0
  112. package/dist/mcp/config-writer.d.ts.map +1 -0
  113. package/dist/mcp/config-writer.js +138 -0
  114. package/dist/mcp/config-writer.js.map +1 -0
  115. package/dist/mcp/env-safety.d.ts +12 -0
  116. package/dist/mcp/env-safety.d.ts.map +1 -0
  117. package/dist/mcp/env-safety.js +80 -0
  118. package/dist/mcp/env-safety.js.map +1 -0
  119. package/dist/mcp/expand-env.d.ts +14 -0
  120. package/dist/mcp/expand-env.d.ts.map +1 -0
  121. package/dist/mcp/expand-env.js +52 -0
  122. package/dist/mcp/expand-env.js.map +1 -0
  123. package/dist/mcp/loader.d.ts +81 -0
  124. package/dist/mcp/loader.d.ts.map +1 -0
  125. package/dist/mcp/loader.js +223 -0
  126. package/dist/mcp/loader.js.map +1 -0
  127. package/dist/mcp/name-mangling.d.ts +11 -0
  128. package/dist/mcp/name-mangling.d.ts.map +1 -0
  129. package/dist/mcp/name-mangling.js +82 -0
  130. package/dist/mcp/name-mangling.js.map +1 -0
  131. package/dist/mcp/oauth/callback-server.d.ts +25 -0
  132. package/dist/mcp/oauth/callback-server.d.ts.map +1 -0
  133. package/dist/mcp/oauth/callback-server.js +118 -0
  134. package/dist/mcp/oauth/callback-server.js.map +1 -0
  135. package/dist/mcp/oauth/provider.d.ts +80 -0
  136. package/dist/mcp/oauth/provider.d.ts.map +1 -0
  137. package/dist/mcp/oauth/provider.js +292 -0
  138. package/dist/mcp/oauth/provider.js.map +1 -0
  139. package/dist/mcp/oauth/token-storage.d.ts +42 -0
  140. package/dist/mcp/oauth/token-storage.d.ts.map +1 -0
  141. package/dist/mcp/oauth/token-storage.js +121 -0
  142. package/dist/mcp/oauth/token-storage.js.map +1 -0
  143. package/dist/mcp/permissions.d.ts +28 -0
  144. package/dist/mcp/permissions.d.ts.map +1 -0
  145. package/dist/mcp/permissions.js +105 -0
  146. package/dist/mcp/permissions.js.map +1 -0
  147. package/dist/mcp/registry.d.ts +150 -0
  148. package/dist/mcp/registry.d.ts.map +1 -0
  149. package/dist/mcp/registry.js +334 -0
  150. package/dist/mcp/registry.js.map +1 -0
  151. package/dist/mcp/resources.d.ts +7 -0
  152. package/dist/mcp/resources.d.ts.map +1 -0
  153. package/dist/mcp/resources.js +40 -0
  154. package/dist/mcp/resources.js.map +1 -0
  155. package/dist/mcp/tool-bridge.d.ts +16 -0
  156. package/dist/mcp/tool-bridge.d.ts.map +1 -0
  157. package/dist/mcp/tool-bridge.js +56 -0
  158. package/dist/mcp/tool-bridge.js.map +1 -0
  159. package/dist/mcp/trust.d.ts +31 -0
  160. package/dist/mcp/trust.d.ts.map +1 -0
  161. package/dist/mcp/trust.js +103 -0
  162. package/dist/mcp/trust.js.map +1 -0
  163. package/dist/mcp/types.d.ts +73 -0
  164. package/dist/mcp/types.d.ts.map +1 -0
  165. package/dist/mcp/types.js +13 -0
  166. package/dist/mcp/types.js.map +1 -0
  167. package/dist/permissions/session-store.d.ts +4 -1
  168. package/dist/permissions/session-store.d.ts.map +1 -1
  169. package/dist/permissions/session-store.js +6 -1
  170. package/dist/permissions/session-store.js.map +1 -1
  171. package/dist/plugins/consent.d.ts +87 -0
  172. package/dist/plugins/consent.d.ts.map +1 -0
  173. package/dist/plugins/consent.js +181 -0
  174. package/dist/plugins/consent.js.map +1 -0
  175. package/dist/plugins/enable-state.d.ts +34 -0
  176. package/dist/plugins/enable-state.d.ts.map +1 -0
  177. package/dist/plugins/enable-state.js +159 -0
  178. package/dist/plugins/enable-state.js.map +1 -0
  179. package/dist/plugins/installer.d.ts +64 -0
  180. package/dist/plugins/installer.d.ts.map +1 -0
  181. package/dist/plugins/installer.js +416 -0
  182. package/dist/plugins/installer.js.map +1 -0
  183. package/dist/plugins/integration.d.ts +91 -0
  184. package/dist/plugins/integration.d.ts.map +1 -0
  185. package/dist/plugins/integration.js +233 -0
  186. package/dist/plugins/integration.js.map +1 -0
  187. package/dist/plugins/loader.d.ts +69 -0
  188. package/dist/plugins/loader.d.ts.map +1 -0
  189. package/dist/plugins/loader.js +243 -0
  190. package/dist/plugins/loader.js.map +1 -0
  191. package/dist/plugins/manifest.d.ts +23 -0
  192. package/dist/plugins/manifest.d.ts.map +1 -0
  193. package/dist/plugins/manifest.js +143 -0
  194. package/dist/plugins/manifest.js.map +1 -0
  195. package/dist/plugins/marketplace.d.ts +100 -0
  196. package/dist/plugins/marketplace.d.ts.map +1 -0
  197. package/dist/plugins/marketplace.js +529 -0
  198. package/dist/plugins/marketplace.js.map +1 -0
  199. package/dist/plugins/paths.d.ts +44 -0
  200. package/dist/plugins/paths.d.ts.map +1 -0
  201. package/dist/plugins/paths.js +89 -0
  202. package/dist/plugins/paths.js.map +1 -0
  203. package/dist/plugins/refresh.d.ts +61 -0
  204. package/dist/plugins/refresh.d.ts.map +1 -0
  205. package/dist/plugins/refresh.js +98 -0
  206. package/dist/plugins/refresh.js.map +1 -0
  207. package/dist/plugins/registry.d.ts +40 -0
  208. package/dist/plugins/registry.d.ts.map +1 -0
  209. package/dist/plugins/registry.js +80 -0
  210. package/dist/plugins/registry.js.map +1 -0
  211. package/dist/plugins/types.d.ts +225 -0
  212. package/dist/plugins/types.d.ts.map +1 -0
  213. package/dist/plugins/types.js +16 -0
  214. package/dist/plugins/types.js.map +1 -0
  215. package/dist/plugins/user-config.d.ts +22 -0
  216. package/dist/plugins/user-config.d.ts.map +1 -0
  217. package/dist/plugins/user-config.js +96 -0
  218. package/dist/plugins/user-config.js.map +1 -0
  219. package/dist/skills/loader.d.ts +19 -0
  220. package/dist/skills/loader.d.ts.map +1 -0
  221. package/dist/skills/loader.js +197 -0
  222. package/dist/skills/loader.js.map +1 -0
  223. package/dist/skills/registry.d.ts +74 -0
  224. package/dist/skills/registry.d.ts.map +1 -0
  225. package/dist/skills/registry.js +136 -0
  226. package/dist/skills/registry.js.map +1 -0
  227. package/dist/skills/settings.d.ts +13 -0
  228. package/dist/skills/settings.d.ts.map +1 -0
  229. package/dist/skills/settings.js +100 -0
  230. package/dist/skills/settings.js.map +1 -0
  231. package/dist/tools/activate-skill.d.ts +5 -0
  232. package/dist/tools/activate-skill.d.ts.map +1 -0
  233. package/dist/tools/activate-skill.js +33 -0
  234. package/dist/tools/activate-skill.js.map +1 -0
  235. package/dist/tools/index.d.ts +1 -1
  236. package/dist/tools/todo-write.d.ts +1 -1
  237. package/dist/tools/web-fetch.d.ts.map +1 -1
  238. package/dist/tools/web-fetch.js +2 -1
  239. package/dist/tools/web-fetch.js.map +1 -1
  240. package/dist/types/index.d.ts +46 -1
  241. package/dist/types/index.d.ts.map +1 -1
  242. package/dist/types/index.js.map +1 -1
  243. package/dist/utils.d.ts +23 -2
  244. package/dist/utils.d.ts.map +1 -1
  245. package/dist/utils.js +76 -20
  246. package/dist/utils.js.map +1 -1
  247. package/dist/version.d.ts +2 -0
  248. package/dist/version.d.ts.map +1 -0
  249. package/dist/version.js +47 -0
  250. package/dist/version.js.map +1 -0
  251. package/package.json +2 -1
@@ -0,0 +1,143 @@
1
+ // @x-code-cli/core — Plugin manifest discovery + zod validation
2
+ //
3
+ // One job: given a plugin root directory on disk, find its manifest
4
+ // (probing the three accepted relative paths in priority order), parse +
5
+ // validate the JSON, and return a `PluginManifest`. The caller resolves
6
+ // contribution paths and figures out scope / enable state.
7
+ //
8
+ // Unknown top-level fields in the manifest are silently stripped (zod's
9
+ // default behaviour with `z.object`). This is intentional: it lets newer
10
+ // Claude Code manifests with fields we don't understand (e.g.
11
+ // `output-styles`, `lspServers`) still parse — we just don't act on them.
12
+ // `/plugin doctor` later surfaces them as "loaded but contributing X
13
+ // unsupported fields" so users know they're getting partial behaviour.
14
+ import fs from 'node:fs/promises';
15
+ import path from 'node:path';
16
+ import { z } from 'zod';
17
+ import { GEMINI_MANIFEST_REL, MANIFEST_CANDIDATES } from './paths.js';
18
+ // ── Zod schemas ─────────────────────────────────────────────────────────
19
+ const authorSchema = z.union([
20
+ z.string(),
21
+ z.object({
22
+ name: z.string().optional(),
23
+ email: z.string().optional(),
24
+ url: z.string().optional(),
25
+ }),
26
+ ]);
27
+ const userConfigItemSchema = z.object({
28
+ key: z.string().min(1),
29
+ type: z.enum(['string', 'number', 'boolean']),
30
+ sensitive: z.boolean().optional(),
31
+ prompt: z.string().optional(),
32
+ required: z.boolean().optional(),
33
+ default: z.union([z.string(), z.number(), z.boolean()]).optional(),
34
+ description: z.string().optional(),
35
+ });
36
+ /** Some contribution fields accept either a relative path (string) OR an
37
+ * inline object — Claude Code's `mcpServers` and `hooks` work this way.
38
+ * We don't validate the inline object's shape here; that's the job of
39
+ * the mcp / hooks subsystems, which already own their own schemas. */
40
+ const pathOrInline = z.union([z.string().min(1), z.record(z.string(), z.unknown())]);
41
+ /** Plugin name: lowercase letters, digits, dashes; must start with a
42
+ * letter or digit. Matches Claude Code / Codex / Gemini and keeps names
43
+ * safe to use as filesystem path components on Windows. */
44
+ const NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
45
+ const manifestSchema = z.object({
46
+ schemaVersion: z.string().optional(),
47
+ name: z
48
+ .string()
49
+ .min(1)
50
+ .regex(NAME_RE, 'name must be lowercase letters, digits, and dashes only (e.g. "linear-issues")'),
51
+ // version is optional in real Claude Code plugins (verified against
52
+ // anthropics/claude-plugins-official — many ship without one,
53
+ // including major third-party plugins like amplitude). We default
54
+ // to "0.0.0" so cache paths and the installed_plugins.json record
55
+ // still have a usable string.
56
+ version: z.string().min(1).optional(),
57
+ description: z.string().optional(),
58
+ author: authorSchema.optional(),
59
+ keywords: z.array(z.string()).optional(),
60
+ homepage: z.string().optional(),
61
+ license: z.string().optional(),
62
+ skills: z.string().min(1).optional(),
63
+ agents: z.string().min(1).optional(),
64
+ commands: z.string().min(1).optional(),
65
+ mcpServers: pathOrInline.optional(),
66
+ hooks: pathOrInline.optional(),
67
+ userConfig: z.array(userConfigItemSchema).optional(),
68
+ dependencies: z.array(z.string().min(1)).optional(),
69
+ engines: z.object({ 'x-code': z.string().optional() }).optional(),
70
+ });
71
+ /** Probe a plugin root for a manifest. Returns the highest-priority
72
+ * match. Returns `{ format: 'gemini', ... }` when ONLY a Gemini manifest
73
+ * exists — the installer uses this to produce a friendly "we don't
74
+ * support Gemini extensions" error rather than a confusing
75
+ * "no manifest found". */
76
+ export async function discoverManifest(rootDir) {
77
+ for (const candidate of MANIFEST_CANDIDATES) {
78
+ const full = path.join(rootDir, candidate.rel);
79
+ if (await fileExists(full)) {
80
+ return { manifestPath: full, format: candidate.format };
81
+ }
82
+ }
83
+ const gemini = path.join(rootDir, GEMINI_MANIFEST_REL);
84
+ if (await fileExists(gemini)) {
85
+ return { manifestPath: gemini, format: 'gemini' };
86
+ }
87
+ return null;
88
+ }
89
+ // ── Parsing ─────────────────────────────────────────────────────────────
90
+ export class ManifestParseError extends Error {
91
+ manifestPath;
92
+ constructor(message, manifestPath) {
93
+ super(message);
94
+ this.manifestPath = manifestPath;
95
+ this.name = 'ManifestParseError';
96
+ }
97
+ }
98
+ /** Parse + validate a manifest JSON file. Fills in `schemaVersion: "1"`
99
+ * when absent (the implicit default — most existing Claude Code plugins
100
+ * don't set this field). Throws `ManifestParseError` with a path-tagged
101
+ * message on failure so the loader can collect it as a doctor entry
102
+ * without aborting the whole boot. */
103
+ export async function parseManifest(manifestPath) {
104
+ let raw;
105
+ try {
106
+ raw = await fs.readFile(manifestPath, 'utf-8');
107
+ }
108
+ catch (err) {
109
+ throw new ManifestParseError(`failed to read manifest: ${err instanceof Error ? err.message : String(err)}`, manifestPath);
110
+ }
111
+ let json;
112
+ try {
113
+ json = JSON.parse(raw);
114
+ }
115
+ catch (err) {
116
+ throw new ManifestParseError(`manifest is not valid JSON: ${err instanceof Error ? err.message : String(err)}`, manifestPath);
117
+ }
118
+ const result = manifestSchema.safeParse(json);
119
+ if (!result.success) {
120
+ const issues = result.error.issues.map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`).join('; ');
121
+ throw new ManifestParseError(`invalid manifest — ${issues}`, manifestPath);
122
+ }
123
+ const data = result.data;
124
+ return {
125
+ ...data,
126
+ schemaVersion: data.schemaVersion ?? '1',
127
+ version: data.version ?? '0.0.0',
128
+ // Normalise the author union — internal callers only deal with the
129
+ // object form. String authors are turned into `{ name: <string> }`.
130
+ author: typeof data.author === 'string' ? { name: data.author } : data.author,
131
+ };
132
+ }
133
+ // ── Helpers ─────────────────────────────────────────────────────────────
134
+ async function fileExists(p) {
135
+ try {
136
+ await fs.access(p);
137
+ return true;
138
+ }
139
+ catch {
140
+ return false;
141
+ }
142
+ }
143
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/plugins/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ import type { KnownMarketplace, KnownMarketplaces, Marketplace, MarketplaceEntry, PluginSource } from './types.js';
2
+ /** Names that may only be registered if their source matches the canonical
3
+ * upstream. Prevents a malicious actor from publishing
4
+ * `anthropic-marketplace` from their own repo and impersonating Anthropic.
5
+ * Maps to expected GitHub org. */
6
+ export declare const RESERVED_MARKETPLACE_NAMES: Readonly<Record<string, string>>;
7
+ /** Convert a marketplace `source` field (in its on-disk wire form) into
8
+ * our internal `PluginSource`. Supports every shape we've seen in real
9
+ * Claude Code marketplaces:
10
+ *
11
+ * | Wire form | Normalised PluginSource |
12
+ * |-------------------------------------------------------------|--------------------------------------------------|
13
+ * | `"./plugins/foo"` or `"../shared/x"` | `{kind:'git', url:<marketplace-clone-url>, subdir:'plugins/foo'}` |
14
+ * | `"github:owner/repo[#ref]"` | `{kind:'github', owner, repo, ref?}` |
15
+ * | `"https://…"` or `"git@…"` | `{kind:'git', url}` |
16
+ * | `{source:'git-subdir', url, path, ref?, sha?}` | `{kind:'git', url, ref?, subdir:path}` |
17
+ * | `{source:'url', url, sha?}` | `{kind:'git', url}` |
18
+ * | `{source:'git', url, ref?, subdir?}` | `{kind:'git', url, ref?, subdir?}` |
19
+ * | `{source:'github', owner, repo, ref?, subdir?}` | `{kind:'github', owner, repo, ref?, subdir?}` |
20
+ * | `{source:'local', path}` | `{kind:'local', path}` |
21
+ * | `{kind:'git'\|'github'\|'local', …}` (our legacy form) | passes through |
22
+ *
23
+ * The relative-string form (`./plugins/foo`) needs the marketplace's
24
+ * own clone URL — that's the repo we'll subdir into. Passed in via
25
+ * `ctx.marketplaceCloneUrl`. Throws when the string is relative but
26
+ * no context was provided (HTTPS-fetched marketplaces can't host
27
+ * relative-path plugins for obvious reasons).
28
+ *
29
+ * The `sha` field from `git-subdir` / `url` is intentionally dropped
30
+ * today — we don't yet verify integrity. Reserved for a follow-up. */
31
+ export declare function normalizeMarketplaceSource(raw: unknown, ctx?: {
32
+ marketplaceCloneUrl?: string;
33
+ }): PluginSource;
34
+ export declare class MarketplaceParseError extends Error {
35
+ readonly sourceLabel: string;
36
+ constructor(message: string, sourceLabel: string);
37
+ }
38
+ export interface ParseMarketplaceContext {
39
+ /** The git clone URL of the marketplace's own repo, used to resolve
40
+ * relative-string sources like `"./plugins/foo"`. Absent when the
41
+ * marketplace was fetched from a raw HTTPS URL (those can't host
42
+ * relative plugins). */
43
+ marketplaceCloneUrl?: string;
44
+ }
45
+ /** Parse + validate a marketplace.json string and normalise every
46
+ * plugin's `source` into our internal `PluginSource`. `sourceLabel` is
47
+ * included in error messages so the user knows which marketplace
48
+ * failed. */
49
+ export declare function parseMarketplace(raw: string, sourceLabel: string, ctx?: ParseMarketplaceContext): Marketplace;
50
+ export declare function readKnownMarketplaces(): Promise<KnownMarketplaces>;
51
+ /** Ensure the default marketplace subscriptions exist. Called from CLI
52
+ * startup so a fresh install lands with Anthropic's official
53
+ * marketplace pre-subscribed and `/plugin search` returns hits without
54
+ * the user having to manually add anything. Idempotent — never
55
+ * overwrites an existing entry, so a user who removed the
56
+ * subscription stays unsubscribed.
57
+ *
58
+ * Target is `anthropics/claude-plugins-official` (203 plugins) rather
59
+ * than the smaller bundled marketplace in `anthropics/claude-code`
60
+ * itself — the dedicated repo is the canonical discovery surface. */
61
+ export declare function ensureDefaultMarketplaces(): Promise<void>;
62
+ /** Register a new marketplace subscription. Rejects reserved names whose
63
+ * source doesn't match the canonical upstream — see
64
+ * RESERVED_MARKETPLACE_NAMES. Idempotent: re-adding the same name
65
+ * updates the source. */
66
+ export declare function addKnownMarketplace(entry: KnownMarketplace): Promise<void>;
67
+ export declare function removeKnownMarketplace(name: string): Promise<'removed' | 'noop'>;
68
+ export interface FetchOptions {
69
+ signal?: AbortSignal;
70
+ /** Skip network if a cached index exists and is younger than this. */
71
+ maxAgeMs?: number;
72
+ }
73
+ /** Pull a fresh marketplace.json into the local cache and parse it.
74
+ * Supports two source shapes:
75
+ *
76
+ * - `https://...` or `http://...` — direct URL to marketplace.json
77
+ * - anything else (`github:owner/repo`, git URL) — shallow clone,
78
+ * then read `.claude-plugin/marketplace.json` (the canonical
79
+ * Claude Code path — see `anthropics/claude-code` and
80
+ * `anthropics/claude-plugins-official` for reference layouts)
81
+ *
82
+ * Writes the parsed file to ~/.x-code/plugins/marketplaces/<name>/marketplace.json
83
+ * before returning. */
84
+ export declare function fetchMarketplace(entry: KnownMarketplace, opts?: FetchOptions): Promise<Marketplace>;
85
+ /** Turn a source string into something `git clone` understands:
86
+ * `github:owner/repo` → `https://github.com/owner/repo.git`. Anything
87
+ * else is passed through (real git URLs, ssh:, etc.). */
88
+ export declare function resolveCloneUrl(source: string): string;
89
+ /** Read every cached marketplace index. Used by `/plugin search` and
90
+ * `/plugin install <name@marketplace>` lookups. Marketplaces with broken
91
+ * cached indexes are skipped + logged; one bad marketplace doesn't break
92
+ * the others. */
93
+ export declare function readAllCachedMarketplaces(): Promise<Marketplace[]>;
94
+ /** Find one plugin entry by `name@marketplace` id. Returns `undefined`
95
+ * when the marketplace isn't subscribed or the plugin isn't listed. */
96
+ export declare function lookupPlugin(pluginId: string): Promise<{
97
+ marketplace: Marketplace;
98
+ entry: MarketplaceEntry;
99
+ } | undefined>;
100
+ //# sourceMappingURL=marketplace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/plugins/marketplace.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAIlH;;;mCAGmC;AACnC,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIvE,CAAA;AAID;;;;;;;;;;;;;;;;;;;;;;;uEAuBuE;AACvE,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,GAAE;IAAE,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,CA+FjH;AAuCD,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,WAAW,EAAE,MAAM;gBADnC,OAAO,EAAE,MAAM,EACC,WAAW,EAAE,MAAM;CAKtC;AAED,MAAM,WAAW,uBAAuB;IACtC;;;6BAGyB;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;;cAGc;AACd,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,uBAA4B,GAAG,WAAW,CA2DjH;AAWD,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAqBxE;AAoBD;;;;;;;;;sEASsE;AACtE,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAe/D;AAED;;;0BAG0B;AAC1B,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBhF;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,CAOtF;AAaD,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;;;wBAUwB;AACxB,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAsB7G;AA+DD;;0DAE0D;AAC1D,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMtD;AAID;;;kBAGkB;AAClB,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAYxE;AAED;wEACwE;AACxE,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,GAAG,SAAS,CAAC,CAkB5E"}