@kwonye/mcpx 0.1.105 → 0.1.107

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 (75) hide show
  1. package/dist/adapters/codex.d.ts +2 -0
  2. package/dist/adapters/index.d.ts +2 -1
  3. package/dist/adapters/json.d.ts +26 -0
  4. package/dist/adapters/pi.d.ts +9 -0
  5. package/dist/chunk-0xt563m1.js +126 -0
  6. package/dist/chunk-131c6axh.js +127 -0
  7. package/dist/chunk-1yq3yb66.js +126 -0
  8. package/dist/chunk-2qbt2pxv.js +755 -0
  9. package/dist/chunk-3j4g9141.js +18 -0
  10. package/dist/{chunk-tnhekcpv.js → chunk-56z18csx.js} +1 -1
  11. package/dist/chunk-5r4vs8ct.js +18166 -0
  12. package/dist/{chunk-bnbz55g6.js → chunk-65kshh9w.js} +1 -1
  13. package/dist/{chunk-xydajvzg.js → chunk-7ky3rsw9.js} +1 -1
  14. package/dist/chunk-9bjabsqb.js +563 -0
  15. package/dist/chunk-9jqdtz2y.js +26 -0
  16. package/dist/{chunk-y9a1rx7j.js → chunk-ad74zhbk.js} +5 -3
  17. package/dist/chunk-eqcsd1kw.js +33 -0
  18. package/dist/chunk-ezk8txcy.js +23 -0
  19. package/dist/chunk-f7w0a9nn.js +30542 -0
  20. package/dist/{chunk-12vgqm89.js → chunk-gvjxpk98.js} +1 -1
  21. package/dist/{chunk-am903qjk.js → chunk-h2ex6pmn.js} +11 -5
  22. package/dist/chunk-jncje8g1.js +60 -0
  23. package/dist/{chunk-h158rkts.js → chunk-kjd00ez5.js} +17 -5
  24. package/dist/{chunk-6mxr34tc.js → chunk-mazydv41.js} +4 -3
  25. package/dist/chunk-mkf7gc7q.js +14 -0
  26. package/dist/{chunk-btbww96n.js → chunk-mztnw25b.js} +69 -56
  27. package/dist/{chunk-enzmq965.js → chunk-n0462d52.js} +1 -1
  28. package/dist/chunk-n5ahyh0j.js +254 -0
  29. package/dist/{chunk-t4hqf6yh.js → chunk-naeqpnmf.js} +8136 -8262
  30. package/dist/chunk-nx22h1y3.js +33 -0
  31. package/dist/chunk-p7yzyt87.js +19426 -0
  32. package/dist/chunk-q86c5s6r.js +7 -0
  33. package/dist/chunk-qg1rbk0d.js +825 -0
  34. package/dist/chunk-r1aebtwm.js +36 -0
  35. package/dist/{chunk-01s7rhx3.js → chunk-rbra8ws6.js} +130 -113
  36. package/dist/{chunk-91vcwk5m.js → chunk-v14bg5yp.js} +1 -1
  37. package/dist/{chunk-4y0t0tfj.js → chunk-vnka4jbe.js} +39 -3
  38. package/dist/chunk-z4j5q2x0.js +30 -0
  39. package/dist/chunk-z7ykm4da.js +138 -0
  40. package/dist/{chunk-d2v9rxy0.js → chunk-zmf014br.js} +12 -6
  41. package/dist/cli.js +3879 -1061
  42. package/dist/core/adoption.d.ts +62 -0
  43. package/dist/core/analytics.d.ts +17 -0
  44. package/dist/core/consumers.d.ts +8 -0
  45. package/dist/core/control.d.ts +18 -0
  46. package/dist/core/daemon.d.ts +2 -2
  47. package/dist/core/file-state.d.ts +7 -0
  48. package/dist/core/harnesses.d.ts +25 -0
  49. package/dist/core/index.d.ts +12 -4
  50. package/dist/core/index.js +109 -71
  51. package/dist/core/managed-index-lock.d.ts +1 -1
  52. package/dist/core/management.d.ts +32 -0
  53. package/dist/core/native-document.d.ts +4 -0
  54. package/dist/core/operations.d.ts +52 -0
  55. package/dist/core/plugin-projections.d.ts +1 -0
  56. package/dist/core/runtime-entry.d.ts +6 -0
  57. package/dist/core/runtime-snapshot.d.ts +6 -0
  58. package/dist/core/secret-keychain.d.ts +31 -0
  59. package/dist/core/secrets.d.ts +12 -2
  60. package/dist/core/served-skills.d.ts +62 -0
  61. package/dist/core/status.d.ts +1 -0
  62. package/dist/core/sync-plan.d.ts +14 -0
  63. package/dist/core/sync.d.ts +3 -0
  64. package/dist/core/telemetry.d.ts +2 -2
  65. package/dist/core/tui.d.ts +20 -0
  66. package/dist/core/verify-upstreams.d.ts +4 -0
  67. package/dist/core/work-limiter.d.ts +10 -0
  68. package/dist/gateway/server.d.ts +2 -0
  69. package/dist/types.d.ts +62 -1
  70. package/dist/util/fs.d.ts +2 -0
  71. package/dist/version.d.ts +1 -1
  72. package/package.json +1 -1
  73. package/dist/adapters/opencode.d.ts +0 -11
  74. package/dist/chunk-56whm3hm.js +0 -4055
  75. package/dist/chunk-fw8dyt89.js +0 -344
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  require_src
3
- } from "./chunk-tnhekcpv.js";
3
+ } from "./chunk-56z18csx.js";
4
4
  import {
5
5
  __commonJS,
6
6
  __require
@@ -18,10 +18,16 @@ import {
18
18
  uninstallPlugin,
19
19
  unpinPlugin,
20
20
  updatePlugin
21
- } from "./chunk-56whm3hm.js";
22
- import"./chunk-01s7rhx3.js";
23
- import"./chunk-fw8dyt89.js";
24
- import"./chunk-4y0t0tfj.js";
21
+ } from "./chunk-naeqpnmf.js";
22
+ import"./chunk-f7w0a9nn.js";
23
+ import"./chunk-qg1rbk0d.js";
24
+ import"./chunk-z4j5q2x0.js";
25
+ import"./chunk-131c6axh.js";
26
+ import"./chunk-jncje8g1.js";
27
+ import"./chunk-9bjabsqb.js";
28
+ import"./chunk-rbra8ws6.js";
29
+ import"./chunk-p7yzyt87.js";
30
+ import"./chunk-vnka4jbe.js";
25
31
  import"./chunk-bjw71y54.js";
26
32
  import"./chunk-wj4tjacg.js";
27
33
  export {
@@ -46,4 +52,4 @@ export {
46
52
  updatePlugin
47
53
  };
48
54
 
49
- //# debugId=F3AE0823719415BE64756E2164756E21
55
+ //# debugId=6778094E987D66A464756E2164756E21
@@ -0,0 +1,60 @@
1
+ import {
2
+ sha256
3
+ } from "./chunk-vnka4jbe.js";
4
+
5
+ // src/core/file-state.ts
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ function normalizeLinkContent(linkPath, raw) {
9
+ if (process.platform !== "win32")
10
+ return raw;
11
+ const paths = path.win32;
12
+ let target = raw;
13
+ if (target.startsWith("\\\\?\\UNC\\"))
14
+ target = `\\\\${target.slice(8)}`;
15
+ else if (target.startsWith("\\\\?\\"))
16
+ target = target.slice(4);
17
+ if (!/^[a-zA-Z]:\\?$/.test(target))
18
+ target = target.replace(/[\\/]+$/, "");
19
+ if (!paths.isAbsolute(target))
20
+ return target.replaceAll("/", "\\");
21
+ return paths.relative(paths.dirname(linkPath), target);
22
+ }
23
+ function pathFingerprint(target) {
24
+ try {
25
+ const stat = fs.lstatSync(target);
26
+ if (stat.isSymbolicLink())
27
+ return sha256(`link:${normalizeLinkContent(target, fs.readlinkSync(target))}`);
28
+ if (stat.isDirectory())
29
+ return sha256(JSON.stringify(fs.readdirSync(target).sort().map((name) => [name, pathFingerprint(path.join(target, name))])));
30
+ return sha256(fs.readFileSync(target).toString("base64"));
31
+ } catch (error) {
32
+ if (error.code === "ENOENT")
33
+ return null;
34
+ throw error;
35
+ }
36
+ }
37
+ function processAlive(pid) {
38
+ if (!Number.isSafeInteger(pid) || pid <= 0)
39
+ return false;
40
+ try {
41
+ process.kill(pid, 0);
42
+ return true;
43
+ } catch (error) {
44
+ return error.code === "EPERM";
45
+ }
46
+ }
47
+ function lockOwnerAlive(lockPath) {
48
+ try {
49
+ const owner = Number(fs.readFileSync(lockPath, "utf8").trim());
50
+ if (!owner && Date.now() - fs.statSync(lockPath).mtimeMs < 2000)
51
+ return true;
52
+ return processAlive(owner);
53
+ } catch {
54
+ return false;
55
+ }
56
+ }
57
+
58
+ export { normalizeLinkContent, pathFingerprint, processAlive, lockOwnerAlive };
59
+
60
+ //# debugId=B87555A9B022F0E264756E2164756E21
@@ -1,17 +1,24 @@
1
1
  import {
2
2
  resolvePluginId,
3
3
  resolvePluginVars
4
- } from "./chunk-56whm3hm.js";
4
+ } from "./chunk-naeqpnmf.js";
5
+ import"./chunk-f7w0a9nn.js";
6
+ import"./chunk-qg1rbk0d.js";
7
+ import"./chunk-z4j5q2x0.js";
8
+ import"./chunk-131c6axh.js";
9
+ import"./chunk-jncje8g1.js";
10
+ import"./chunk-9bjabsqb.js";
5
11
  import {
6
12
  loadConfig
7
- } from "./chunk-01s7rhx3.js";
8
- import"./chunk-fw8dyt89.js";
9
- import"./chunk-4y0t0tfj.js";
13
+ } from "./chunk-rbra8ws6.js";
14
+ import"./chunk-p7yzyt87.js";
15
+ import"./chunk-vnka4jbe.js";
10
16
  import"./chunk-bjw71y54.js";
11
17
  import"./chunk-wj4tjacg.js";
12
18
 
13
19
  // src/core/plugin-host.ts
14
20
  import path from "node:path";
21
+ import fs from "node:fs";
15
22
  import { spawn } from "node:child_process";
16
23
  var ALLOWLISTED_ENV = new Set(["PATH", "HOME", "TMPDIR", "LANG", "SHELL"]);
17
24
  function runPluginHost(pluginNameOrId, serverId) {
@@ -78,6 +85,11 @@ function runPluginHost(pluginNameOrId, serverId) {
78
85
  env[k] = v;
79
86
  }
80
87
  }
88
+ const venvBin = path.join(dataDir, "venv", process.platform === "win32" ? "Scripts" : "bin");
89
+ if (fs.existsSync(venvBin)) {
90
+ env.PATH = `${venvBin}${path.delimiter}${env.PATH ?? ""}`;
91
+ env.VIRTUAL_ENV = path.dirname(venvBin);
92
+ }
81
93
  env.MCPX_PLUGIN_ROOT = pluginRoot;
82
94
  env.MCPX_PLUGIN_DATA = dataDir;
83
95
  env.CLAUDE_PLUGIN_ROOT = pluginRoot;
@@ -102,4 +114,4 @@ export {
102
114
  runPluginHost
103
115
  };
104
116
 
105
- //# debugId=0C835B092C0AF76664756E2164756E21
117
+ //# debugId=97EBE0FCB0A8718C64756E2164756E21
@@ -8,8 +8,9 @@ import {
8
8
  resolveActiveConfig,
9
9
  saveConfig,
10
10
  saveProjectConfig
11
- } from "./chunk-01s7rhx3.js";
12
- import"./chunk-4y0t0tfj.js";
11
+ } from "./chunk-rbra8ws6.js";
12
+ import"./chunk-p7yzyt87.js";
13
+ import"./chunk-vnka4jbe.js";
13
14
  import"./chunk-bjw71y54.js";
14
15
  import"./chunk-wj4tjacg.js";
15
16
  export {
@@ -24,4 +25,4 @@ export {
24
25
  saveProjectConfig
25
26
  };
26
27
 
27
- //# debugId=D849CB34D71D1D5364756E2164756E21
28
+ //# debugId=A8828D397F34F54064756E2164756E21
@@ -0,0 +1,14 @@
1
+ import {
2
+ defaultManagedIndex,
3
+ loadManagedIndex,
4
+ saveManagedIndex
5
+ } from "./chunk-z4j5q2x0.js";
6
+ import"./chunk-vnka4jbe.js";
7
+ import"./chunk-wj4tjacg.js";
8
+ export {
9
+ defaultManagedIndex,
10
+ loadManagedIndex,
11
+ saveManagedIndex
12
+ };
13
+
14
+ //# debugId=D54B076878A4315964756E2164756E21
@@ -1,19 +1,27 @@
1
1
  import {
2
- PluginCache,
3
2
  PluginManager,
3
+ capture,
4
4
  discoverComponents,
5
5
  hasManifest,
6
- mutateConfig,
7
6
  readManifest,
8
7
  uninstallPlugin
9
- } from "./chunk-56whm3hm.js";
8
+ } from "./chunk-naeqpnmf.js";
9
+ import {
10
+ mutateConfig
11
+ } from "./chunk-131c6axh.js";
12
+ import {
13
+ PluginCache
14
+ } from "./chunk-9bjabsqb.js";
10
15
  import {
11
16
  loadConfig
12
- } from "./chunk-01s7rhx3.js";
17
+ } from "./chunk-rbra8ws6.js";
18
+ import {
19
+ exports_external
20
+ } from "./chunk-p7yzyt87.js";
13
21
  import {
14
22
  ensureDir,
15
23
  getMarketplaceCacheRoot
16
- } from "./chunk-4y0t0tfj.js";
24
+ } from "./chunk-vnka4jbe.js";
17
25
  import {
18
26
  __require
19
27
  } from "./chunk-wj4tjacg.js";
@@ -25,57 +33,56 @@ import os from "node:os";
25
33
  import path from "node:path";
26
34
  import { execFile } from "node:child_process";
27
35
  import { promisify } from "node:util";
28
- import { z } from "zod";
29
36
  var execFileAsync = promisify(execFile);
30
37
  var CLAUDE_MANIFEST = ".claude-plugin/marketplace.json";
31
38
  var CODEX_MANIFEST = ".agents/plugins/marketplace.json";
32
39
  var SUPPORTED = new Set(["skills", "commands", "agents", "hooks", "mcpServers"]);
33
40
  var UNSUPPORTED = new Set(["apps", "lspServers", "settings", "outputStyles", "dependencies"]);
34
- var authorSchema = z.object({
35
- name: z.string(),
36
- email: z.string().optional(),
37
- url: z.string().optional()
41
+ var authorSchema = exports_external.object({
42
+ name: exports_external.string(),
43
+ email: exports_external.string().optional(),
44
+ url: exports_external.string().optional()
38
45
  }).passthrough();
39
- var claudeEntrySchema = z.object({
40
- name: z.string().min(1),
41
- displayName: z.string().optional(),
42
- description: z.string().optional(),
43
- version: z.string().optional(),
46
+ var claudeEntrySchema = exports_external.object({
47
+ name: exports_external.string().min(1),
48
+ displayName: exports_external.string().optional(),
49
+ description: exports_external.string().optional(),
50
+ version: exports_external.string().optional(),
44
51
  author: authorSchema.optional(),
45
- homepage: z.string().optional(),
46
- category: z.string().optional(),
47
- tags: z.array(z.string()).optional(),
48
- keywords: z.array(z.string()).optional(),
49
- source: z.unknown(),
50
- skills: z.unknown().optional(),
51
- commands: z.unknown().optional(),
52
- agents: z.unknown().optional(),
53
- hooks: z.unknown().optional(),
54
- mcpServers: z.unknown().optional(),
55
- lspServers: z.unknown().optional(),
56
- apps: z.unknown().optional(),
57
- settings: z.unknown().optional(),
58
- outputStyles: z.unknown().optional(),
59
- dependencies: z.unknown().optional()
52
+ homepage: exports_external.string().optional(),
53
+ category: exports_external.string().optional(),
54
+ tags: exports_external.array(exports_external.string()).optional(),
55
+ keywords: exports_external.array(exports_external.string()).optional(),
56
+ source: exports_external.unknown(),
57
+ skills: exports_external.unknown().optional(),
58
+ commands: exports_external.unknown().optional(),
59
+ agents: exports_external.unknown().optional(),
60
+ hooks: exports_external.unknown().optional(),
61
+ mcpServers: exports_external.unknown().optional(),
62
+ lspServers: exports_external.unknown().optional(),
63
+ apps: exports_external.unknown().optional(),
64
+ settings: exports_external.unknown().optional(),
65
+ outputStyles: exports_external.unknown().optional(),
66
+ dependencies: exports_external.unknown().optional()
60
67
  }).passthrough();
61
- var claudeCatalogSchema = z.object({
62
- name: z.string().min(1),
68
+ var claudeCatalogSchema = exports_external.object({
69
+ name: exports_external.string().min(1),
63
70
  owner: authorSchema,
64
- plugins: z.array(claudeEntrySchema)
71
+ plugins: exports_external.array(claudeEntrySchema)
65
72
  }).passthrough();
66
- var codexEntrySchema = z.object({
67
- name: z.string().min(1),
68
- source: z.unknown(),
69
- category: z.string().optional(),
70
- policy: z.object({
71
- installation: z.string().optional(),
72
- authentication: z.string().optional()
73
+ var codexEntrySchema = exports_external.object({
74
+ name: exports_external.string().min(1),
75
+ source: exports_external.unknown(),
76
+ category: exports_external.string().optional(),
77
+ policy: exports_external.object({
78
+ installation: exports_external.string().optional(),
79
+ authentication: exports_external.string().optional()
73
80
  }).passthrough().optional()
74
81
  }).passthrough();
75
- var codexCatalogSchema = z.object({
76
- name: z.string().min(1),
77
- interface: z.object({ displayName: z.string().optional() }).passthrough().optional(),
78
- plugins: z.array(codexEntrySchema)
82
+ var codexCatalogSchema = exports_external.object({
83
+ name: exports_external.string().min(1),
84
+ interface: exports_external.object({ displayName: exports_external.string().optional() }).passthrough().optional(),
85
+ plugins: exports_external.array(codexEntrySchema)
79
86
  }).passthrough();
80
87
  function sourceKey(source) {
81
88
  return crypto.createHash("sha256").update(source).digest("hex").slice(0, 20);
@@ -233,14 +240,14 @@ function resolveMarketplacePluginSource(catalog, entry) {
233
240
  throw new Error(`Unsupported marketplace plugin source: ${value}`);
234
241
  return { type: "local", original: resolveContained(catalog.root, value) };
235
242
  }
236
- const source = z.object({
237
- source: z.string(),
238
- repo: z.string().optional(),
239
- url: z.string().optional(),
240
- path: z.string().optional(),
241
- ref: z.string().optional(),
242
- sha: z.string().optional(),
243
- package: z.string().optional()
243
+ const source = exports_external.object({
244
+ source: exports_external.string(),
245
+ repo: exports_external.string().optional(),
246
+ url: exports_external.string().optional(),
247
+ path: exports_external.string().optional(),
248
+ ref: exports_external.string().optional(),
249
+ sha: exports_external.string().optional(),
250
+ package: exports_external.string().optional()
244
251
  }).passthrough().parse(value);
245
252
  if (source.source === "local") {
246
253
  if (!source.path)
@@ -387,6 +394,7 @@ async function addMarketplace(source, manifestPath) {
387
394
  throw new Error(`Built-in marketplace ${catalog.name} cannot be replaced`);
388
395
  fresh.marketplaces[catalog.name] = marketplace;
389
396
  });
397
+ capture("marketplace_added", { source_type: marketplace.sourceType, format: marketplace.format });
390
398
  return marketplace;
391
399
  }
392
400
  async function refreshMarketplace(name) {
@@ -451,6 +459,7 @@ async function removeMarketplace(name) {
451
459
  await mutateConfig((fresh) => {
452
460
  delete fresh.marketplaces?.[name];
453
461
  });
462
+ capture("marketplace_removed", { source_type: marketplace.sourceType, installed_plugin_count: installed.length });
454
463
  }
455
464
  async function listMarketplacePlugins(query) {
456
465
  const initial = await listMarketplaces();
@@ -527,11 +536,13 @@ async function installMarketplacePlugin(id) {
527
536
  approvals[capability] = true;
528
537
  }
529
538
  const manager = new PluginManager;
530
- return manager.installResolvedPlugin(source, {
539
+ const installed = await manager.installResolvedPlugin(source, {
531
540
  name: pluginName,
532
541
  approvals,
533
542
  marketplace: { name: marketplaceName, pluginName, sourceFingerprint: detail.sourceFingerprint }
534
543
  });
544
+ capture("plugin_installed", { marketplace: marketplaceName, capabilities: detail.supportedCapabilities });
545
+ return installed;
535
546
  }
536
547
  async function updateMarketplaceInstalledPlugin(pluginId, sync = true) {
537
548
  const plugin = loadConfig().plugins?.[pluginId];
@@ -554,7 +565,9 @@ async function updateMarketplaceInstalledPlugin(pluginId, sync = true) {
554
565
  if (!entry)
555
566
  throw new Error(`Plugin ${qualified} is no longer listed`);
556
567
  const source = resolveMarketplacePluginSource(catalog, entry);
557
- return await new PluginManager().updateResolvedPlugin(pluginId, source, detail.sourceFingerprint, sync);
568
+ const updated = await new PluginManager().updateResolvedPlugin(pluginId, source, detail.sourceFingerprint, sync);
569
+ capture("plugin_updated", { marketplace: plugin.marketplace.name, plugin_name: plugin.marketplace.pluginName });
570
+ return updated;
558
571
  } catch (error) {
559
572
  await mutateConfig((config) => {
560
573
  const current = config.plugins?.[pluginId];
@@ -580,7 +593,7 @@ async function refreshMarketplaceWithPlugins(name) {
580
593
  }
581
594
  }
582
595
  if (updated.length > 0) {
583
- const { pluginSync } = await import("./chunk-am903qjk.js");
596
+ const { pluginSync } = await import("./chunk-h2ex6pmn.js");
584
597
  await pluginSync();
585
598
  }
586
599
  return { marketplace, updated, errors };
@@ -602,4 +615,4 @@ async function refreshAutoUpdateMarketplaces() {
602
615
 
603
616
  export { resolveMarketplacePluginSource, listMarketplaces, addMarketplace, refreshMarketplace, setMarketplaceAutoUpdate, removeMarketplace, listMarketplacePlugins, inspectMarketplacePlugin, installMarketplacePlugin, updateMarketplaceInstalledPlugin, refreshMarketplaceWithPlugins, refreshAutoUpdateMarketplaces };
604
617
 
605
- //# debugId=347C06BDB5A3194064756E2164756E21
618
+ //# debugId=CA752DBB3B8B9C7764756E2164756E21
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-c7zg7ey3.js";
4
4
  import {
5
5
  require_src
6
- } from "./chunk-tnhekcpv.js";
6
+ } from "./chunk-56z18csx.js";
7
7
  import {
8
8
  __commonJS,
9
9
  __require
@@ -0,0 +1,254 @@
1
+ import {
2
+ mutateConfig
3
+ } from "./chunk-131c6axh.js";
4
+ import {
5
+ listSkills,
6
+ validateSkillId,
7
+ validateSkillPackage
8
+ } from "./chunk-9bjabsqb.js";
9
+ import {
10
+ loadConfig
11
+ } from "./chunk-rbra8ws6.js";
12
+ import {
13
+ exports_external
14
+ } from "./chunk-p7yzyt87.js";
15
+ import {
16
+ ensureDir,
17
+ getSkillsDir
18
+ } from "./chunk-vnka4jbe.js";
19
+ import {
20
+ __require
21
+ } from "./chunk-wj4tjacg.js";
22
+
23
+ // src/core/share.ts
24
+ import fs from "node:fs";
25
+ import path from "node:path";
26
+ import crypto from "node:crypto";
27
+ var ENVIRONMENT_FILE = "mcpx.environment.json";
28
+ var LOCK_FILE = "mcpx.environment.lock.json";
29
+ var packageEntrySchema = exports_external.object({
30
+ id: exports_external.string().min(1),
31
+ kind: exports_external.enum(["skill", "plugin"]),
32
+ path: exports_external.string().min(1),
33
+ source: exports_external.string().optional()
34
+ });
35
+ var shareServerSchema = exports_external.discriminatedUnion("transport", [
36
+ exports_external.object({ transport: exports_external.literal("http"), url: exports_external.url(), headers: exports_external.record(exports_external.string(), exports_external.string()).optional(), enabled: exports_external.boolean().default(true) }),
37
+ exports_external.object({ transport: exports_external.literal("stdio"), command: exports_external.string().min(1), args: exports_external.array(exports_external.string()).default([]), env: exports_external.record(exports_external.string(), exports_external.string()).optional(), cwd: exports_external.string().optional(), enabled: exports_external.boolean().default(true) })
38
+ ]);
39
+ var environmentSchema = exports_external.object({
40
+ version: exports_external.literal(1),
41
+ generatedBy: exports_external.string().min(1),
42
+ servers: exports_external.record(exports_external.string(), shareServerSchema).default({}),
43
+ skills: exports_external.array(packageEntrySchema).default([]),
44
+ plugins: exports_external.array(packageEntrySchema).default([]),
45
+ clients: exports_external.array(exports_external.string()).default([]),
46
+ inputs: exports_external.array(exports_external.object({ name: exports_external.string(), description: exports_external.string().optional() })).default([])
47
+ });
48
+ var lockSchema = exports_external.object({
49
+ version: exports_external.literal(1),
50
+ mcpxCompatibility: exports_external.string().min(1),
51
+ manifestSha256: exports_external.string().regex(/^[a-f0-9]{64}$/),
52
+ packages: exports_external.record(exports_external.string(), exports_external.object({ sha256: exports_external.string().regex(/^[a-f0-9]{64}$/), revision: exports_external.string().optional() })).default({})
53
+ });
54
+ function sha256File(filePath) {
55
+ return crypto.createHash("sha256").update(fs.readFileSync(filePath)).digest("hex");
56
+ }
57
+ function sha256Tree(root) {
58
+ const hash = crypto.createHash("sha256");
59
+ const visit = (current, relative = "") => {
60
+ const entries = fs.readdirSync(current, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
61
+ for (const entry of entries) {
62
+ if (entry.name === ".DS_Store" || entry.name === ".git")
63
+ continue;
64
+ const child = path.join(current, entry.name);
65
+ const childRelative = path.join(relative, entry.name);
66
+ hash.update(childRelative);
67
+ if (entry.isDirectory())
68
+ visit(child, childRelative);
69
+ else if (entry.isFile())
70
+ hash.update(fs.readFileSync(child));
71
+ }
72
+ };
73
+ visit(root);
74
+ return hash.digest("hex");
75
+ }
76
+ function copyDirectory(source, destination) {
77
+ ensureDir(destination);
78
+ fs.cpSync(source, destination, { recursive: true, dereference: true, filter: (sourcePath) => !sourcePath.split(path.sep).includes(".git") && !sourcePath.endsWith(`${path.sep}.DS_Store`) });
79
+ }
80
+ function resolveSharePath(root, relativePath) {
81
+ const resolvedRoot = path.resolve(root);
82
+ const resolved = path.resolve(root, relativePath);
83
+ if (resolved !== resolvedRoot && !resolved.startsWith(resolvedRoot + path.sep))
84
+ throw new Error(`Package path escapes the environment folder: ${relativePath}`);
85
+ return resolved;
86
+ }
87
+ function scrubServer(name, spec, inputs) {
88
+ const result = { transport: spec.transport, enabled: spec.enabled ?? true };
89
+ if (spec.transport === "http") {
90
+ const parsedUrl = new URL(spec.url);
91
+ if (parsedUrl.username || parsedUrl.password || /(?:token|secret|key|password|auth)/i.test(parsedUrl.search)) {
92
+ throw new Error(`Server ${name} URL contains credentials and cannot be shared`);
93
+ }
94
+ result.url = spec.url;
95
+ if (spec.headers) {
96
+ result.headers = Object.fromEntries(Object.entries(spec.headers).map(([key, value]) => {
97
+ if (value.startsWith("secret://"))
98
+ return [key, value];
99
+ const inputName = `server.${name}.header.${key}`;
100
+ inputs.push({ name: inputName, description: `HTTP header ${key} for ${name}` });
101
+ return [key, `{{input:${inputName}}}`];
102
+ }));
103
+ }
104
+ } else {
105
+ if (path.isAbsolute(spec.command))
106
+ throw new Error(`Server ${name} uses an absolute command path and cannot be shared`);
107
+ result.command = spec.command;
108
+ result.args = spec.args ?? [];
109
+ if (spec.cwd) {
110
+ if (path.isAbsolute(spec.cwd))
111
+ throw new Error(`Server ${name} uses an absolute cwd and cannot be shared`);
112
+ result.cwd = spec.cwd;
113
+ }
114
+ if (spec.env) {
115
+ result.env = Object.fromEntries(Object.entries(spec.env).map(([key, value]) => {
116
+ if (value.startsWith("secret://"))
117
+ return [key, value];
118
+ const inputName = `server.${name}.env.${key}`;
119
+ inputs.push({ name: inputName, description: `Environment variable ${key} for ${name}` });
120
+ return [key, `{{input:${inputName}}}`];
121
+ }));
122
+ }
123
+ }
124
+ return result;
125
+ }
126
+ function replaceInputs(value, inputs) {
127
+ if (typeof value === "string") {
128
+ const match = value.match(/^\{\{input:([^}]+)\}\}$/);
129
+ return match ? inputs[match[1]] ?? value : value;
130
+ }
131
+ if (Array.isArray(value))
132
+ return value.map((entry) => replaceInputs(entry, inputs));
133
+ if (value && typeof value === "object")
134
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, replaceInputs(entry, inputs)]));
135
+ return value;
136
+ }
137
+ function exportEnvironment(destination, options = {}) {
138
+ const root = path.resolve(destination);
139
+ ensureDir(root);
140
+ const config = loadConfig();
141
+ const inputs = [];
142
+ const generatedServerNames = new Set(Object.values(config.plugins ?? {}).flatMap((plugin) => plugin.serverNames));
143
+ const servers = Object.fromEntries(Object.entries(config.servers).filter(([name]) => !generatedServerNames.has(name)).map(([name, spec]) => [name, scrubServer(name, spec, inputs)]));
144
+ const packagesDir = path.join(root, "packages");
145
+ ensureDir(packagesDir);
146
+ const selectedSkills = listSkills().filter((skill) => !options.skills || options.skills.includes(skill.id));
147
+ const skills = selectedSkills.map((skill) => {
148
+ const packagePath = path.join(packagesDir, "skills", skill.id);
149
+ ensureDir(path.dirname(packagePath));
150
+ if (skill.root)
151
+ copyDirectory(skill.root, packagePath);
152
+ else {
153
+ ensureDir(packagePath);
154
+ fs.writeFileSync(path.join(packagePath, "SKILL.md"), skill.content, "utf8");
155
+ }
156
+ return { id: skill.id, kind: "skill", path: `packages/skills/${skill.id}`, source: skill.source ?? "authored" };
157
+ });
158
+ const selectedPlugins = Object.values(config.plugins ?? {}).filter((plugin) => !options.plugins || options.plugins.includes(plugin.id) || options.plugins.includes(plugin.name));
159
+ const plugins = selectedPlugins.map((plugin) => {
160
+ const packagePath = path.join(packagesDir, "plugins", plugin.name);
161
+ copyDirectory(plugin.root, packagePath);
162
+ return { id: plugin.name, kind: "plugin", path: `packages/plugins/${plugin.name}`, source: plugin.source };
163
+ });
164
+ const environment = environmentSchema.parse({ version: 1, generatedBy: "mcpx", servers, skills, plugins, clients: Object.keys(config.clients ?? {}), inputs });
165
+ const manifestPath = path.join(root, ENVIRONMENT_FILE);
166
+ fs.writeFileSync(manifestPath, JSON.stringify(environment, null, 2) + `
167
+ `, "utf8");
168
+ const lock = {
169
+ version: 1,
170
+ mcpxCompatibility: "1",
171
+ manifestSha256: sha256File(manifestPath),
172
+ packages: Object.fromEntries([
173
+ ...skills.map((entry) => [`${entry.kind}:${entry.id}`, { sha256: sha256Tree(path.join(root, entry.path)) }]),
174
+ ...plugins.map((entry) => {
175
+ const plugin = selectedPlugins.find((candidate) => candidate.name === entry.id);
176
+ return [`${entry.kind}:${entry.id}`, { sha256: sha256Tree(path.join(root, entry.path)), revision: plugin?.resolvedSha }];
177
+ })
178
+ ])
179
+ };
180
+ fs.writeFileSync(path.join(root, LOCK_FILE), JSON.stringify(lock, null, 2) + `
181
+ `, "utf8");
182
+ return { environment, lock };
183
+ }
184
+ async function importEnvironment(sourceDirectory, options = {}) {
185
+ const root = path.resolve(sourceDirectory);
186
+ const manifestPath = path.join(root, ENVIRONMENT_FILE);
187
+ const lockPath = path.join(root, LOCK_FILE);
188
+ const environment = environmentSchema.parse(JSON.parse(fs.readFileSync(manifestPath, "utf8")));
189
+ const lock = lockSchema.parse(JSON.parse(fs.readFileSync(lockPath, "utf8")));
190
+ if (options.locked && lock.manifestSha256 !== sha256File(manifestPath))
191
+ throw new Error("Environment manifest does not match its lockfile");
192
+ const allEntries = [...environment.skills, ...environment.plugins];
193
+ for (const entry of allEntries) {
194
+ const packagePath = resolveSharePath(root, entry.path);
195
+ if (!fs.existsSync(packagePath))
196
+ throw new Error(`Missing package content: ${entry.path}`);
197
+ if (entry.kind === "skill")
198
+ validateSkillPackage(packagePath);
199
+ const expected = lock.packages[`${entry.kind}:${entry.id}`]?.sha256;
200
+ if (options.locked && expected && expected !== sha256Tree(packagePath))
201
+ throw new Error(`Package integrity check failed: ${entry.id}`);
202
+ }
203
+ const inputs = options.inputs ?? {};
204
+ const missingInputs = environment.inputs.map((input) => input.name).filter((name) => !inputs[name]);
205
+ if (options.dryRun)
206
+ return { importedSkills: environment.skills.map((entry) => entry.id), importedPlugins: environment.plugins.map((entry) => entry.id), importedServers: Object.keys(environment.servers), missingInputs };
207
+ const currentConfig = loadConfig();
208
+ for (const entry of environment.skills) {
209
+ validateSkillId(entry.id);
210
+ const target = path.join(getSkillsDir(), entry.id);
211
+ if (fs.existsSync(target) && sha256Tree(target) !== sha256Tree(resolveSharePath(root, entry.path)))
212
+ throw new Error(`Skill already exists with different content: ${entry.id}`);
213
+ }
214
+ for (const [name, raw] of Object.entries(environment.servers)) {
215
+ if (currentConfig.servers[name] && JSON.stringify(currentConfig.servers[name]) !== JSON.stringify(replaceInputs(raw, inputs)))
216
+ throw new Error(`Server already exists with different configuration: ${name}`);
217
+ }
218
+ for (const entry of environment.plugins) {
219
+ if (Object.values(currentConfig.plugins ?? {}).some((plugin) => plugin.name === entry.id))
220
+ throw new Error(`Plugin already exists: ${entry.id}`);
221
+ }
222
+ const targetSkills = getSkillsDir();
223
+ for (const entry of environment.skills) {
224
+ validateSkillId(entry.id);
225
+ const target = path.join(targetSkills, entry.id);
226
+ if (fs.existsSync(target)) {
227
+ if (sha256Tree(target) !== sha256Tree(resolveSharePath(root, entry.path)))
228
+ throw new Error(`Skill already exists with different content: ${entry.id}`);
229
+ continue;
230
+ }
231
+ copyDirectory(resolveSharePath(root, entry.path), target);
232
+ }
233
+ const importedPlugins = [];
234
+ for (const entry of environment.plugins) {
235
+ const packagePath = resolveSharePath(root, entry.path);
236
+ const { installPlugin } = await import("./chunk-h2ex6pmn.js");
237
+ await installPlugin(packagePath, { name: entry.id, enabled: true });
238
+ importedPlugins.push(entry.id);
239
+ }
240
+ const importedServers = [];
241
+ await mutateConfig((fresh) => {
242
+ for (const [name, raw] of Object.entries(environment.servers)) {
243
+ if (fresh.servers[name])
244
+ continue;
245
+ fresh.servers[name] = replaceInputs(raw, inputs);
246
+ importedServers.push(name);
247
+ }
248
+ });
249
+ return { importedSkills: environment.skills.map((entry) => entry.id), importedPlugins, importedServers, missingInputs };
250
+ }
251
+
252
+ export { exportEnvironment, importEnvironment };
253
+
254
+ //# debugId=2FCD1EB3744CFAA764756E2164756E21