@michaelfromyeg/weft-adapter-cursor 1.3.0 → 1.4.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.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -150,6 +150,8 @@ function importMarketplace(manifest, namespace) {
|
|
|
150
150
|
...p.category ? { category: String(p.category) } : {},
|
|
151
151
|
...Array.isArray(p.tags) ? { tags: p.tags } : {}
|
|
152
152
|
}));
|
|
153
|
+
const meta = manifest.metadata;
|
|
154
|
+
const description = meta?.description ?? (manifest.description ? String(manifest.description) : "");
|
|
153
155
|
const marketplace = {
|
|
154
156
|
name: String(manifest.name),
|
|
155
157
|
owner: {
|
|
@@ -157,7 +159,7 @@ function importMarketplace(manifest, namespace) {
|
|
|
157
159
|
namespace,
|
|
158
160
|
...owner?.email ? { email: owner.email } : {}
|
|
159
161
|
},
|
|
160
|
-
...
|
|
162
|
+
...description ? { description } : {},
|
|
161
163
|
plugins
|
|
162
164
|
};
|
|
163
165
|
return { kind: "marketplace", marketplace };
|
|
@@ -210,7 +212,7 @@ function mcpRunConfig(server) {
|
|
|
210
212
|
}
|
|
211
213
|
|
|
212
214
|
// src/index.ts
|
|
213
|
-
var TARGET_SCHEMA = "cursor-plugin/
|
|
215
|
+
var TARGET_SCHEMA = "cursor-plugin/2";
|
|
214
216
|
var json2 = (o) => `${JSON.stringify(o, null, 2)}
|
|
215
217
|
`;
|
|
216
218
|
function author(name, email) {
|
|
@@ -233,6 +235,12 @@ var cursorAdapter = {
|
|
|
233
235
|
target: "cursor",
|
|
234
236
|
version: "0.1.0",
|
|
235
237
|
targetSchema: TARGET_SCHEMA,
|
|
238
|
+
harness: {
|
|
239
|
+
name: "Cursor",
|
|
240
|
+
versionCommand: "cursor-agent --version",
|
|
241
|
+
// Plugin marketplace shipped in the Cursor 2.x line. Bump when re-verified.
|
|
242
|
+
range: ">=2.0.0 <3.0.0"
|
|
243
|
+
},
|
|
236
244
|
detect(scope, cwd) {
|
|
237
245
|
const root = scope === "user" ? join(homedir(), ".cursor") : join(cwd, ".cursor");
|
|
238
246
|
return {
|
|
@@ -295,7 +303,9 @@ var cursorAdapter = {
|
|
|
295
303
|
const plugins = marketplace.entries.map((entry) => {
|
|
296
304
|
const entryPlugin = {
|
|
297
305
|
name: entry.name,
|
|
298
|
-
source
|
|
306
|
+
// Cursor's `source` is a bare repo-root-relative path (e.g. "plugins/x"),
|
|
307
|
+
// not "./"-prefixed -- matching its own example marketplaces.
|
|
308
|
+
source: entry.source.replace(/^\.\//, "")
|
|
299
309
|
};
|
|
300
310
|
if (entry.description) entryPlugin.description = entry.description;
|
|
301
311
|
if (entry.version) entryPlugin.version = entry.version;
|
|
@@ -308,13 +318,13 @@ var cursorAdapter = {
|
|
|
308
318
|
owner: author(marketplace.owner.name, marketplace.owner.email),
|
|
309
319
|
plugins
|
|
310
320
|
};
|
|
311
|
-
if (marketplace.description) catalog.
|
|
321
|
+
if (marketplace.description) catalog.metadata = { description: marketplace.description };
|
|
312
322
|
return [artifact(".cursor-plugin/marketplace.json", json2(catalog), { kind: "catalog" })];
|
|
313
323
|
},
|
|
314
324
|
importNative: importCursor
|
|
315
325
|
};
|
|
316
326
|
var index_default = cursorAdapter;
|
|
317
327
|
|
|
318
|
-
export {
|
|
328
|
+
export { index_default as default };
|
|
319
329
|
//# sourceMappingURL=index.js.map
|
|
320
330
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/import.ts","../src/mcp.ts","../src/index.ts"],"names":["author","json","artifact","join"],"mappings":"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","file":"index.js","sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport {\n artifact,\n type CompiledArtifact,\n type ImportedMarketplace,\n type ImportedPlugin,\n type ImportOptions,\n type ImportResult,\n} from \"@michaelfromyeg/weft-adapter-kit\";\nimport type { Component, Marketplace, Plugin } from \"@michaelfromyeg/weft-schema\";\n\nconst MCP_SCHEMA = \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\";\nconst json = (o: unknown): string => `${JSON.stringify(o, null, 2)}\\n`;\n\nfunction readJson(path: string): Record<string, unknown> | null {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n } catch {\n return null;\n }\n}\n\n/** Subdirectories of `dir` that contain `marker`. */\nfunction subdirsWith(dir: string, marker: string): string[] {\n if (!(existsSync(dir) && statSync(dir).isDirectory())) return [];\n return readdirSync(dir)\n .filter((n) => statSync(join(dir, n)).isDirectory() && existsSync(join(dir, n, marker)))\n .sort();\n}\n\nfunction filesWithExt(dir: string, ext: string): string[] {\n if (!(existsSync(dir) && statSync(dir).isDirectory())) return [];\n return readdirSync(dir)\n .filter((n) => n.endsWith(ext) && statSync(join(dir, n)).isFile())\n .sort();\n}\n\nfunction copyTree(\n srcDir: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n const out: CompiledArtifact[] = [];\n const walk = (d: string) => {\n for (const n of readdirSync(d).sort()) {\n const abs = join(d, n);\n if (statSync(abs).isDirectory()) walk(abs);\n else\n out.push(artifact(`${destPrefix}/${relative(srcDir, abs)}`, readFileSync(abs), { kind }));\n }\n };\n walk(srcDir);\n return out;\n}\n\n/** A Weft source string from a Cursor marketplace `source` (string or object). */\nfunction sourceToString(source: unknown): string {\n if (typeof source === \"string\") return source;\n const s = source as Record<string, unknown>;\n switch (s?.source) {\n case \"github\":\n return `github:${s.repo}${s.ref ? `#${s.ref}` : \"\"}`;\n case \"url\":\n case \"git-subdir\":\n return String(s.url);\n case \"npm\":\n return `npm:${s.package}${s.version ? `@${s.version}` : \"\"}`;\n default:\n return String(source);\n }\n}\n\ninterface McpServerCfg {\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Reconstruct an MCP-standard server.json from a Cursor `mcpServers` run config\n * (lossy but functional). Cursor has no `type` discriminator on a remote entry —\n * transport is inferred from `url` vs `command` — so a reconstructed remote\n * defaults to `streamable-http`.\n */\nfunction synthesizeServerJson(namespace: string, name: string, cfg: McpServerCfg): unknown {\n const base = {\n $schema: MCP_SCHEMA,\n name: `${namespace}/${name}`,\n description: `Imported ${name} MCP server.`,\n version: \"0.0.0\",\n };\n if (cfg.url) {\n const remote: Record<string, unknown> = { type: \"streamable-http\", url: cfg.url };\n if (cfg.headers) {\n remote.headers = Object.entries(cfg.headers).map(([nm, value]) => ({ name: nm, value }));\n }\n return { ...base, remotes: [remote] };\n }\n if (cfg.command === \"npx\" && Array.isArray(cfg.args)) {\n const ident = cfg.args.find((a) => a !== \"-y\" && !a.startsWith(\"-\"));\n if (ident) {\n const at = ident.lastIndexOf(\"@\");\n const id = at > 0 ? ident.slice(0, at) : ident;\n const version = at > 0 ? ident.slice(at + 1) : undefined;\n return {\n ...base,\n packages: [\n {\n registryType: \"npm\",\n identifier: id,\n ...(version ? { version } : {}),\n transport: { type: \"stdio\" },\n },\n ],\n };\n }\n }\n return {\n ...base,\n ...(cfg.command ? { command: cfg.command } : {}),\n ...(cfg.args ? { args: cfg.args } : {}),\n ...(cfg.env ? { env: cfg.env } : {}),\n };\n}\n\nfunction importPlugin(\n dir: string,\n manifest: Record<string, unknown>,\n namespace: string,\n): ImportedPlugin {\n const components: Component[] = [];\n const files: CompiledArtifact[] = [];\n\n for (const sk of subdirsWith(join(dir, \"skills\"), \"SKILL.md\")) {\n components.push({ skill: `skills/${sk}` });\n files.push(...copyTree(join(dir, \"skills\", sk), `skills/${sk}`, \"skill\"));\n }\n for (const f of filesWithExt(join(dir, \"agents\"), \".md\")) {\n components.push({ agent: `agents/${f}` });\n files.push(artifact(`agents/${f}`, readFileSync(join(dir, \"agents\", f)), { kind: \"agent\" }));\n }\n for (const f of filesWithExt(join(dir, \"commands\"), \".md\")) {\n components.push({ command: `commands/${f}` });\n files.push(\n artifact(`commands/${f}`, readFileSync(join(dir, \"commands\", f)), { kind: \"command\" }),\n );\n }\n\n // Prefer a verbatim mcp/<leaf>/server.json (a Weft-built plugin keeps it); only\n // reconstruct from the native `mcpServers` config when there is no mcp/ dir.\n const mcpRoot = join(dir, \"mcp\");\n const verbatim = subdirsWith(mcpRoot, \"server.json\");\n if (verbatim.length > 0) {\n for (const leaf of verbatim) {\n components.push({ mcp: `mcp/${leaf}` });\n files.push(...copyTree(join(mcpRoot, leaf), `mcp/${leaf}`, \"mcp\"));\n }\n } else {\n const mcpServers =\n (manifest.mcpServers as Record<string, McpServerCfg> | undefined) ??\n (readJson(join(dir, \"mcp.json\"))?.mcpServers as Record<string, McpServerCfg>) ??\n {};\n for (const [serverName, cfg] of Object.entries(mcpServers)) {\n components.push({ mcp: `mcp/${serverName}` });\n files.push(\n artifact(\n `mcp/${serverName}/server.json`,\n json(synthesizeServerJson(namespace, serverName, cfg)),\n { kind: \"mcp\" },\n ),\n );\n }\n }\n\n const author = manifest.author as { name?: string; email?: string } | undefined;\n const plugin: Plugin = {\n name: String(manifest.name),\n version: String(manifest.version ?? \"0.1.0\"),\n owner: {\n name: author?.name ?? String(manifest.name),\n namespace,\n ...(author?.email ? { email: author.email } : {}),\n },\n ...(manifest.description ? { description: String(manifest.description) } : {}),\n components,\n };\n return { kind: \"plugin\", plugin, files };\n}\n\nfunction importMarketplace(\n manifest: Record<string, unknown>,\n namespace: string,\n): ImportedMarketplace {\n const owner = manifest.owner as { name?: string; email?: string } | undefined;\n const plugins = ((manifest.plugins as Record<string, unknown>[]) ?? []).map((p) => ({\n plugin: sourceToString(p.source),\n ...(p.version ? { version: String(p.version) } : {}),\n ...(p.category ? { category: String(p.category) } : {}),\n ...(Array.isArray(p.tags) ? { tags: p.tags as string[] } : {}),\n }));\n const marketplace: Marketplace = {\n name: String(manifest.name),\n owner: {\n name: owner?.name ?? String(manifest.name),\n namespace,\n ...(owner?.email ? { email: owner.email } : {}),\n },\n ...(manifest.description ? { description: String(manifest.description) } : {}),\n plugins,\n };\n return { kind: \"marketplace\", marketplace };\n}\n\n/** Reverse-compile a Cursor plugin or marketplace dir into the Weft model. */\nexport function importCursor(dir: string, opts?: ImportOptions): ImportResult | null {\n const namespace = opts?.namespace ?? \"com.imported\";\n const marketplace = readJson(join(dir, \".cursor-plugin\", \"marketplace.json\"));\n if (marketplace) return importMarketplace(marketplace, namespace);\n\n const manifest =\n readJson(join(dir, \".cursor-plugin\", \"plugin.json\")) ?? readJson(join(dir, \"plugin.json\"));\n if (manifest) return importPlugin(dir, manifest, namespace);\n\n // No manifest, but a bare plugin layout (skills/ etc.) is still importable.\n if (existsSync(join(dir, \"skills\"))) {\n return importPlugin(dir, { name: \"imported-plugin\" }, namespace);\n }\n return null;\n}\n","/**\n * Derives a runnable Cursor `mcpServers` entry from an MCP-standard `server.json`\n * (the registry's ServerJSON shape: packages[] / remotes[] / a bare command).\n * Stored standards stay verbatim in the plugin; this is the tool-specific view.\n *\n * Cursor's `mcp.json` / plugin.json `mcpServers` map uses the same stdio\n * `{command,args,env}` and remote `{url,headers}` shape as Claude (research §Cursor,\n * \"stdio {command,args,env}; remote {url,headers,auth?}\"). Unlike Claude, Cursor's\n * remote entry has no `type` discriminator key — transport is inferred from\n * `command` vs `url`.\n */\n\nexport interface McpServerConfig {\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n}\n\ninterface McpPackage {\n registryType?: string;\n identifier?: string;\n version?: string;\n transport?: { type?: string };\n}\ninterface McpRemote {\n type?: string;\n url?: string;\n headers?: Array<{ name: string; value: string }>;\n}\ninterface ServerJson {\n name?: string;\n packages?: McpPackage[];\n remotes?: McpRemote[];\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n/** The short server key Cursor uses (the part after the reverse-DNS namespace). */\nexport function mcpServerName(server: ServerJson): string {\n const raw = server.name ?? \"server\";\n const afterSlash = raw.includes(\"/\") ? raw.slice(raw.lastIndexOf(\"/\") + 1) : raw;\n return afterSlash || \"server\";\n}\n\nconst RUNNERS: Record<string, string> = { npm: \"npx\", pypi: \"uvx\" };\n\nexport function mcpRunConfig(server: ServerJson): McpServerConfig {\n const pkg = server.packages?.[0];\n if (pkg?.identifier) {\n if (pkg.registryType === \"oci\") {\n return { command: \"docker\", args: [\"run\", \"-i\", \"--rm\", pkg.identifier] };\n }\n const runner = RUNNERS[pkg.registryType ?? \"npm\"] ?? \"npx\";\n const ident = pkg.version ? `${pkg.identifier}@${pkg.version}` : pkg.identifier;\n const args = runner === \"npx\" ? [\"-y\", ident] : [ident];\n return { command: runner, args };\n }\n\n const remote = server.remotes?.[0];\n if (remote?.url) {\n // TODO(verify): Cursor's remote mcpServers entry shape — research confirms\n // `{url, headers, auth?}` with no `type` discriminator, but the exact header\n // serialization (map vs array) is unverified; emitting a flat header map here.\n const config: McpServerConfig = { url: remote.url };\n if (remote.headers?.length) {\n config.headers = Object.fromEntries(remote.headers.map((h) => [h.name, h.value]));\n }\n return config;\n }\n\n if (server.command) {\n const config: McpServerConfig = { command: server.command };\n if (server.args) config.args = server.args;\n if (server.env) config.env = server.env;\n return config;\n }\n\n return { command: \"echo\", args: [\"server.json declares no runnable transport\"] };\n}\n","import { homedir } from \"node:os\";\nimport { basename, extname, join } from \"node:path\";\nimport {\n artifact,\n type CompiledArtifact,\n type HarnessAdapter,\n type InstallPaths,\n type PluginCtx,\n type ResolvedMarketplace,\n} from \"@michaelfromyeg/weft-adapter-kit\";\nimport {\n type Component,\n kindOf,\n leafNameOf,\n type Plugin,\n refOf,\n type Scope,\n} from \"@michaelfromyeg/weft-schema\";\nimport { importCursor } from \"./import\";\nimport { type McpServerConfig, mcpRunConfig, mcpServerName } from \"./mcp\";\n\n/** Bump on any change to Cursor's plugin/marketplace manifest shape (spec §5). */\nconst TARGET_SCHEMA = \"cursor-plugin/1\";\n\ninterface CursorAuthor {\n name: string;\n email?: string;\n}\ninterface CursorPluginManifest {\n name: string;\n description?: string;\n version?: string;\n author?: CursorAuthor;\n mcpServers?: Record<string, McpServerConfig>;\n}\ninterface CursorMarketplacePlugin {\n name: string;\n source: string;\n description?: string;\n version?: string;\n category?: string;\n tags?: string[];\n}\ninterface CursorMarketplace {\n name: string;\n owner: CursorAuthor;\n description?: string;\n plugins: CursorMarketplacePlugin[];\n}\n\nconst json = (o: unknown): string => `${JSON.stringify(o, null, 2)}\\n`;\n\nfunction author(name: string, email?: string): CursorAuthor {\n return email ? { name, email } : { name };\n}\n\n/** Copy every file under a plugin dir into `destPrefix/`, preserving structure. */\nfunction copyDir(\n ctx: PluginCtx,\n ref: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n return ctx.list(ref).map((file) => {\n const within = file.startsWith(`${ref}/`) ? file.slice(ref.length + 1) : basename(file);\n return artifact(`${destPrefix}/${within}`, ctx.read(file), { kind });\n });\n}\n\n/** Place a component that may be a single Markdown file or a directory. */\nfunction copyFileOrDir(\n ctx: PluginCtx,\n ref: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n const files = ctx.list(ref);\n if (files.length === 0) {\n // ref is a single file (e.g. agents/code-review.md).\n return [artifact(`${destPrefix}${extname(ref) || \".md\"}`, ctx.read(ref), { kind })];\n }\n return copyDir(ctx, ref, destPrefix, kind);\n}\n\nexport const cursorAdapter: HarnessAdapter = {\n target: \"cursor\",\n version: \"0.1.0\",\n targetSchema: TARGET_SCHEMA,\n\n detect(scope: Scope, cwd: string): InstallPaths {\n const root = scope === \"user\" ? join(homedir(), \".cursor\") : join(cwd, \".cursor\");\n return {\n root,\n plugins: join(root, \"plugins\"),\n skills: join(root, \"skills\"),\n // Cursor's mcp.json lives at the .cursor root, not in a category dir.\n mcp: root,\n // TODO(verify): Cursor auto-discovers agents/ commands/ hooks/hooks.json at a\n // plugin root, but the user/project install dir names are unverified — using\n // the Claude-style category dirs as a best-effort.\n agents: join(root, \"agents\"),\n commands: join(root, \"commands\"),\n hooks: join(root, \"hooks\"),\n catalog: join(root, \"plugins\"),\n };\n },\n\n transform(component: Component, ctx: PluginCtx): CompiledArtifact[] {\n const ref = refOf(component);\n const leaf = leafNameOf(component);\n switch (kindOf(component)) {\n case \"skill\":\n // Cursor reads .cursor/skills AND .claude/skills; copy the dir verbatim.\n return copyDir(ctx, ref, `skills/${leaf}`, \"skill\");\n case \"agent\":\n return copyFileOrDir(ctx, ref, `agents/${leaf}`, \"agent\");\n case \"command\":\n return copyFileOrDir(ctx, ref, `commands/${leaf}`, \"command\");\n case \"hook\":\n return copyFileOrDir(ctx, ref, `hooks/${leaf}`, \"hook\");\n case \"mcp\":\n // Verbatim provenance copy; the runnable config goes inline in plugin.json.\n return copyDir(ctx, ref, `mcp/${leaf}`, \"mcp\");\n case \"passthrough\":\n return [\n artifact(`hooks/${basename(ref)}`, ctx.read(ref), { kind: \"hook\", executable: true }),\n ];\n default:\n return [];\n }\n },\n\n emitManifest(plugin: Plugin, ctx: PluginCtx): CompiledArtifact[] {\n const manifest: CursorPluginManifest = {\n name: plugin.name,\n version: plugin.version,\n author: author(plugin.owner.name, plugin.owner.email),\n };\n if (plugin.description) manifest.description = plugin.description;\n\n const mcpServers: Record<string, McpServerConfig> = {};\n for (const c of plugin.components) {\n if (kindOf(c) !== \"mcp\") continue;\n try {\n const server = JSON.parse(ctx.read(`${refOf(c)}/server.json`).toString(\"utf8\"));\n mcpServers[mcpServerName(server)] = mcpRunConfig(server);\n } catch {\n // validate.ts already surfaced an error for an unparsable server.json.\n }\n }\n if (Object.keys(mcpServers).length > 0) manifest.mcpServers = mcpServers;\n\n return [artifact(\".cursor-plugin/plugin.json\", json(manifest), { kind: \"manifest\" })];\n },\n\n emitCatalog(marketplace: ResolvedMarketplace): CompiledArtifact[] {\n const plugins: CursorMarketplacePlugin[] = marketplace.entries.map((entry) => {\n const entryPlugin: CursorMarketplacePlugin = {\n name: entry.name,\n source: entry.source.startsWith(\"./\") ? entry.source : `./${entry.source}`,\n };\n if (entry.description) entryPlugin.description = entry.description;\n if (entry.version) entryPlugin.version = entry.version;\n if (entry.category) entryPlugin.category = entry.category;\n if (entry.tags) entryPlugin.tags = entry.tags;\n return entryPlugin;\n });\n\n const catalog: CursorMarketplace = {\n name: marketplace.name,\n owner: author(marketplace.owner.name, marketplace.owner.email),\n plugins,\n };\n if (marketplace.description) catalog.description = marketplace.description;\n\n return [artifact(\".cursor-plugin/marketplace.json\", json(catalog), { kind: \"catalog\" })];\n },\n\n importNative: importCursor,\n};\n\nexport default cursorAdapter;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/import.ts","../src/mcp.ts","../src/index.ts"],"names":["author","json","artifact","join"],"mappings":"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","file":"index.js","sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport {\n artifact,\n type CompiledArtifact,\n type ImportedMarketplace,\n type ImportedPlugin,\n type ImportOptions,\n type ImportResult,\n} from \"@michaelfromyeg/weft-adapter-kit\";\nimport type { Component, Marketplace, Plugin } from \"@michaelfromyeg/weft-schema\";\n\nconst MCP_SCHEMA = \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\";\nconst json = (o: unknown): string => `${JSON.stringify(o, null, 2)}\\n`;\n\nfunction readJson(path: string): Record<string, unknown> | null {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n } catch {\n return null;\n }\n}\n\n/** Subdirectories of `dir` that contain `marker`. */\nfunction subdirsWith(dir: string, marker: string): string[] {\n if (!(existsSync(dir) && statSync(dir).isDirectory())) return [];\n return readdirSync(dir)\n .filter((n) => statSync(join(dir, n)).isDirectory() && existsSync(join(dir, n, marker)))\n .sort();\n}\n\nfunction filesWithExt(dir: string, ext: string): string[] {\n if (!(existsSync(dir) && statSync(dir).isDirectory())) return [];\n return readdirSync(dir)\n .filter((n) => n.endsWith(ext) && statSync(join(dir, n)).isFile())\n .sort();\n}\n\nfunction copyTree(\n srcDir: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n const out: CompiledArtifact[] = [];\n const walk = (d: string) => {\n for (const n of readdirSync(d).sort()) {\n const abs = join(d, n);\n if (statSync(abs).isDirectory()) walk(abs);\n else\n out.push(artifact(`${destPrefix}/${relative(srcDir, abs)}`, readFileSync(abs), { kind }));\n }\n };\n walk(srcDir);\n return out;\n}\n\n/** A Weft source string from a Cursor marketplace `source` (string or object). */\nfunction sourceToString(source: unknown): string {\n if (typeof source === \"string\") return source;\n const s = source as Record<string, unknown>;\n switch (s?.source) {\n case \"github\":\n return `github:${s.repo}${s.ref ? `#${s.ref}` : \"\"}`;\n case \"url\":\n case \"git-subdir\":\n return String(s.url);\n case \"npm\":\n return `npm:${s.package}${s.version ? `@${s.version}` : \"\"}`;\n default:\n return String(source);\n }\n}\n\ninterface McpServerCfg {\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Reconstruct an MCP-standard server.json from a Cursor `mcpServers` run config\n * (lossy but functional). Cursor has no `type` discriminator on a remote entry —\n * transport is inferred from `url` vs `command` — so a reconstructed remote\n * defaults to `streamable-http`.\n */\nfunction synthesizeServerJson(namespace: string, name: string, cfg: McpServerCfg): unknown {\n const base = {\n $schema: MCP_SCHEMA,\n name: `${namespace}/${name}`,\n description: `Imported ${name} MCP server.`,\n version: \"0.0.0\",\n };\n if (cfg.url) {\n const remote: Record<string, unknown> = { type: \"streamable-http\", url: cfg.url };\n if (cfg.headers) {\n remote.headers = Object.entries(cfg.headers).map(([nm, value]) => ({ name: nm, value }));\n }\n return { ...base, remotes: [remote] };\n }\n if (cfg.command === \"npx\" && Array.isArray(cfg.args)) {\n const ident = cfg.args.find((a) => a !== \"-y\" && !a.startsWith(\"-\"));\n if (ident) {\n const at = ident.lastIndexOf(\"@\");\n const id = at > 0 ? ident.slice(0, at) : ident;\n const version = at > 0 ? ident.slice(at + 1) : undefined;\n return {\n ...base,\n packages: [\n {\n registryType: \"npm\",\n identifier: id,\n ...(version ? { version } : {}),\n transport: { type: \"stdio\" },\n },\n ],\n };\n }\n }\n return {\n ...base,\n ...(cfg.command ? { command: cfg.command } : {}),\n ...(cfg.args ? { args: cfg.args } : {}),\n ...(cfg.env ? { env: cfg.env } : {}),\n };\n}\n\nfunction importPlugin(\n dir: string,\n manifest: Record<string, unknown>,\n namespace: string,\n): ImportedPlugin {\n const components: Component[] = [];\n const files: CompiledArtifact[] = [];\n\n for (const sk of subdirsWith(join(dir, \"skills\"), \"SKILL.md\")) {\n components.push({ skill: `skills/${sk}` });\n files.push(...copyTree(join(dir, \"skills\", sk), `skills/${sk}`, \"skill\"));\n }\n for (const f of filesWithExt(join(dir, \"agents\"), \".md\")) {\n components.push({ agent: `agents/${f}` });\n files.push(artifact(`agents/${f}`, readFileSync(join(dir, \"agents\", f)), { kind: \"agent\" }));\n }\n for (const f of filesWithExt(join(dir, \"commands\"), \".md\")) {\n components.push({ command: `commands/${f}` });\n files.push(\n artifact(`commands/${f}`, readFileSync(join(dir, \"commands\", f)), { kind: \"command\" }),\n );\n }\n\n // Prefer a verbatim mcp/<leaf>/server.json (a Weft-built plugin keeps it); only\n // reconstruct from the native `mcpServers` config when there is no mcp/ dir.\n const mcpRoot = join(dir, \"mcp\");\n const verbatim = subdirsWith(mcpRoot, \"server.json\");\n if (verbatim.length > 0) {\n for (const leaf of verbatim) {\n components.push({ mcp: `mcp/${leaf}` });\n files.push(...copyTree(join(mcpRoot, leaf), `mcp/${leaf}`, \"mcp\"));\n }\n } else {\n const mcpServers =\n (manifest.mcpServers as Record<string, McpServerCfg> | undefined) ??\n (readJson(join(dir, \"mcp.json\"))?.mcpServers as Record<string, McpServerCfg>) ??\n {};\n for (const [serverName, cfg] of Object.entries(mcpServers)) {\n components.push({ mcp: `mcp/${serverName}` });\n files.push(\n artifact(\n `mcp/${serverName}/server.json`,\n json(synthesizeServerJson(namespace, serverName, cfg)),\n { kind: \"mcp\" },\n ),\n );\n }\n }\n\n const author = manifest.author as { name?: string; email?: string } | undefined;\n const plugin: Plugin = {\n name: String(manifest.name),\n version: String(manifest.version ?? \"0.1.0\"),\n owner: {\n name: author?.name ?? String(manifest.name),\n namespace,\n ...(author?.email ? { email: author.email } : {}),\n },\n ...(manifest.description ? { description: String(manifest.description) } : {}),\n components,\n };\n return { kind: \"plugin\", plugin, files };\n}\n\nfunction importMarketplace(\n manifest: Record<string, unknown>,\n namespace: string,\n): ImportedMarketplace {\n const owner = manifest.owner as { name?: string; email?: string } | undefined;\n const plugins = ((manifest.plugins as Record<string, unknown>[]) ?? []).map((p) => ({\n plugin: sourceToString(p.source),\n ...(p.version ? { version: String(p.version) } : {}),\n ...(p.category ? { category: String(p.category) } : {}),\n ...(Array.isArray(p.tags) ? { tags: p.tags as string[] } : {}),\n }));\n // Marketplace-level description nests under `metadata` (top-level is the legacy form).\n const meta = manifest.metadata as { description?: string } | undefined;\n const description =\n meta?.description ?? (manifest.description ? String(manifest.description) : \"\");\n const marketplace: Marketplace = {\n name: String(manifest.name),\n owner: {\n name: owner?.name ?? String(manifest.name),\n namespace,\n ...(owner?.email ? { email: owner.email } : {}),\n },\n ...(description ? { description } : {}),\n plugins,\n };\n return { kind: \"marketplace\", marketplace };\n}\n\n/** Reverse-compile a Cursor plugin or marketplace dir into the Weft model. */\nexport function importCursor(dir: string, opts?: ImportOptions): ImportResult | null {\n const namespace = opts?.namespace ?? \"com.imported\";\n const marketplace = readJson(join(dir, \".cursor-plugin\", \"marketplace.json\"));\n if (marketplace) return importMarketplace(marketplace, namespace);\n\n const manifest =\n readJson(join(dir, \".cursor-plugin\", \"plugin.json\")) ?? readJson(join(dir, \"plugin.json\"));\n if (manifest) return importPlugin(dir, manifest, namespace);\n\n // No manifest, but a bare plugin layout (skills/ etc.) is still importable.\n if (existsSync(join(dir, \"skills\"))) {\n return importPlugin(dir, { name: \"imported-plugin\" }, namespace);\n }\n return null;\n}\n","/**\n * Derives a runnable Cursor `mcpServers` entry from an MCP-standard `server.json`\n * (the registry's ServerJSON shape: packages[] / remotes[] / a bare command).\n * Stored standards stay verbatim in the plugin; this is the tool-specific view.\n *\n * Cursor's `mcp.json` / plugin.json `mcpServers` map uses the same stdio\n * `{command,args,env}` and remote `{url,headers}` shape as Claude (research §Cursor,\n * \"stdio {command,args,env}; remote {url,headers,auth?}\"). Unlike Claude, Cursor's\n * remote entry has no `type` discriminator key — transport is inferred from\n * `command` vs `url`.\n */\n\nexport interface McpServerConfig {\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n}\n\ninterface McpPackage {\n registryType?: string;\n identifier?: string;\n version?: string;\n transport?: { type?: string };\n}\ninterface McpRemote {\n type?: string;\n url?: string;\n headers?: Array<{ name: string; value: string }>;\n}\ninterface ServerJson {\n name?: string;\n packages?: McpPackage[];\n remotes?: McpRemote[];\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n/** The short server key Cursor uses (the part after the reverse-DNS namespace). */\nexport function mcpServerName(server: ServerJson): string {\n const raw = server.name ?? \"server\";\n const afterSlash = raw.includes(\"/\") ? raw.slice(raw.lastIndexOf(\"/\") + 1) : raw;\n return afterSlash || \"server\";\n}\n\nconst RUNNERS: Record<string, string> = { npm: \"npx\", pypi: \"uvx\" };\n\nexport function mcpRunConfig(server: ServerJson): McpServerConfig {\n const pkg = server.packages?.[0];\n if (pkg?.identifier) {\n if (pkg.registryType === \"oci\") {\n return { command: \"docker\", args: [\"run\", \"-i\", \"--rm\", pkg.identifier] };\n }\n const runner = RUNNERS[pkg.registryType ?? \"npm\"] ?? \"npx\";\n const ident = pkg.version ? `${pkg.identifier}@${pkg.version}` : pkg.identifier;\n const args = runner === \"npx\" ? [\"-y\", ident] : [ident];\n return { command: runner, args };\n }\n\n const remote = server.remotes?.[0];\n if (remote?.url) {\n // TODO(verify): Cursor's remote mcpServers entry shape — research confirms\n // `{url, headers, auth?}` with no `type` discriminator, but the exact header\n // serialization (map vs array) is unverified; emitting a flat header map here.\n const config: McpServerConfig = { url: remote.url };\n if (remote.headers?.length) {\n config.headers = Object.fromEntries(remote.headers.map((h) => [h.name, h.value]));\n }\n return config;\n }\n\n if (server.command) {\n const config: McpServerConfig = { command: server.command };\n if (server.args) config.args = server.args;\n if (server.env) config.env = server.env;\n return config;\n }\n\n return { command: \"echo\", args: [\"server.json declares no runnable transport\"] };\n}\n","import { homedir } from \"node:os\";\nimport { basename, extname, join } from \"node:path\";\nimport {\n artifact,\n type CompiledArtifact,\n type HarnessAdapter,\n type InstallPaths,\n type PluginCtx,\n type ResolvedMarketplace,\n} from \"@michaelfromyeg/weft-adapter-kit\";\nimport {\n type Component,\n kindOf,\n leafNameOf,\n type Plugin,\n refOf,\n type Scope,\n} from \"@michaelfromyeg/weft-schema\";\nimport { importCursor } from \"./import\";\nimport { type McpServerConfig, mcpRunConfig, mcpServerName } from \"./mcp\";\n\n/** Bump on any change to Cursor's plugin/marketplace manifest shape (spec §5). */\nconst TARGET_SCHEMA = \"cursor-plugin/2\";\n\ninterface CursorAuthor {\n name: string;\n email?: string;\n}\ninterface CursorPluginManifest {\n name: string;\n description?: string;\n version?: string;\n author?: CursorAuthor;\n mcpServers?: Record<string, McpServerConfig>;\n}\ninterface CursorMarketplacePlugin {\n name: string;\n source: string;\n description?: string;\n version?: string;\n category?: string;\n tags?: string[];\n}\ninterface CursorMarketplace {\n name: string;\n metadata?: { description?: string; version?: string; pluginRoot?: string };\n owner: CursorAuthor;\n plugins: CursorMarketplacePlugin[];\n}\n\nconst json = (o: unknown): string => `${JSON.stringify(o, null, 2)}\\n`;\n\nfunction author(name: string, email?: string): CursorAuthor {\n return email ? { name, email } : { name };\n}\n\n/** Copy every file under a plugin dir into `destPrefix/`, preserving structure. */\nfunction copyDir(\n ctx: PluginCtx,\n ref: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n return ctx.list(ref).map((file) => {\n const within = file.startsWith(`${ref}/`) ? file.slice(ref.length + 1) : basename(file);\n return artifact(`${destPrefix}/${within}`, ctx.read(file), { kind });\n });\n}\n\n/** Place a component that may be a single Markdown file or a directory. */\nfunction copyFileOrDir(\n ctx: PluginCtx,\n ref: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n const files = ctx.list(ref);\n if (files.length === 0) {\n // ref is a single file (e.g. agents/code-review.md).\n return [artifact(`${destPrefix}${extname(ref) || \".md\"}`, ctx.read(ref), { kind })];\n }\n return copyDir(ctx, ref, destPrefix, kind);\n}\n\nconst cursorAdapter: HarnessAdapter = {\n target: \"cursor\",\n version: \"0.1.0\",\n targetSchema: TARGET_SCHEMA,\n harness: {\n name: \"Cursor\",\n versionCommand: \"cursor-agent --version\",\n // Plugin marketplace shipped in the Cursor 2.x line. Bump when re-verified.\n range: \">=2.0.0 <3.0.0\",\n },\n\n detect(scope: Scope, cwd: string): InstallPaths {\n const root = scope === \"user\" ? join(homedir(), \".cursor\") : join(cwd, \".cursor\");\n return {\n root,\n plugins: join(root, \"plugins\"),\n skills: join(root, \"skills\"),\n // Cursor's mcp.json lives at the .cursor root, not in a category dir.\n mcp: root,\n // TODO(verify): Cursor auto-discovers agents/ commands/ hooks/hooks.json at a\n // plugin root, but the user/project install dir names are unverified — using\n // the Claude-style category dirs as a best-effort.\n agents: join(root, \"agents\"),\n commands: join(root, \"commands\"),\n hooks: join(root, \"hooks\"),\n catalog: join(root, \"plugins\"),\n };\n },\n\n transform(component: Component, ctx: PluginCtx): CompiledArtifact[] {\n const ref = refOf(component);\n const leaf = leafNameOf(component);\n switch (kindOf(component)) {\n case \"skill\":\n // Cursor reads .cursor/skills AND .claude/skills; copy the dir verbatim.\n return copyDir(ctx, ref, `skills/${leaf}`, \"skill\");\n case \"agent\":\n return copyFileOrDir(ctx, ref, `agents/${leaf}`, \"agent\");\n case \"command\":\n return copyFileOrDir(ctx, ref, `commands/${leaf}`, \"command\");\n case \"hook\":\n return copyFileOrDir(ctx, ref, `hooks/${leaf}`, \"hook\");\n case \"mcp\":\n // Verbatim provenance copy; the runnable config goes inline in plugin.json.\n return copyDir(ctx, ref, `mcp/${leaf}`, \"mcp\");\n case \"passthrough\":\n return [\n artifact(`hooks/${basename(ref)}`, ctx.read(ref), { kind: \"hook\", executable: true }),\n ];\n default:\n return [];\n }\n },\n\n emitManifest(plugin: Plugin, ctx: PluginCtx): CompiledArtifact[] {\n const manifest: CursorPluginManifest = {\n name: plugin.name,\n version: plugin.version,\n author: author(plugin.owner.name, plugin.owner.email),\n };\n if (plugin.description) manifest.description = plugin.description;\n\n const mcpServers: Record<string, McpServerConfig> = {};\n for (const c of plugin.components) {\n if (kindOf(c) !== \"mcp\") continue;\n try {\n const server = JSON.parse(ctx.read(`${refOf(c)}/server.json`).toString(\"utf8\"));\n mcpServers[mcpServerName(server)] = mcpRunConfig(server);\n } catch {\n // validate.ts already surfaced an error for an unparsable server.json.\n }\n }\n if (Object.keys(mcpServers).length > 0) manifest.mcpServers = mcpServers;\n\n return [artifact(\".cursor-plugin/plugin.json\", json(manifest), { kind: \"manifest\" })];\n },\n\n emitCatalog(marketplace: ResolvedMarketplace): CompiledArtifact[] {\n const plugins: CursorMarketplacePlugin[] = marketplace.entries.map((entry) => {\n const entryPlugin: CursorMarketplacePlugin = {\n name: entry.name,\n // Cursor's `source` is a bare repo-root-relative path (e.g. \"plugins/x\"),\n // not \"./\"-prefixed -- matching its own example marketplaces.\n source: entry.source.replace(/^\\.\\//, \"\"),\n };\n if (entry.description) entryPlugin.description = entry.description;\n if (entry.version) entryPlugin.version = entry.version;\n if (entry.category) entryPlugin.category = entry.category;\n if (entry.tags) entryPlugin.tags = entry.tags;\n return entryPlugin;\n });\n\n const catalog: CursorMarketplace = {\n name: marketplace.name,\n owner: author(marketplace.owner.name, marketplace.owner.email),\n plugins,\n };\n // Marketplace-level description nests under `metadata` (NOT top-level).\n if (marketplace.description) catalog.metadata = { description: marketplace.description };\n\n return [artifact(\".cursor-plugin/marketplace.json\", json(catalog), { kind: \"catalog\" })];\n },\n\n importNative: importCursor,\n};\n\nexport default cursorAdapter;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michaelfromyeg/weft-adapter-cursor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Weft adapter for Cursor: plugin.json + marketplace.json + component placement.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@michaelfromyeg/weft-
|
|
20
|
-
"@michaelfromyeg/weft-
|
|
19
|
+
"@michaelfromyeg/weft-adapter-kit": "1.4.0",
|
|
20
|
+
"@michaelfromyeg/weft-schema": "1.4.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@michaelfromyeg/weft-core": "1.
|
|
23
|
+
"@michaelfromyeg/weft-core": "1.4.0"
|
|
24
24
|
},
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"author": "Michael DeMarco",
|