jorgex-stack 1.9.64 → 1.9.65

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 (2) hide show
  1. package/dist/cli.js +55 -24
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -2115,6 +2115,12 @@ function isManagedOptionalStdioServer(server, value) {
2115
2115
  const expectedCommand = [server.command, ...server.args ?? []];
2116
2116
  return Object.keys(current).length === 2 && current.type === "local" && Array.isArray(current.command) && current.command.length === expectedCommand.length && current.command.every((arg, index) => arg === expectedCommand[index]);
2117
2117
  }
2118
+ function isOwnedDevtoolsServer(name, server, value, ctx) {
2119
+ if (isManagedOptionalStdioServer(server, value)) return true;
2120
+ if (name !== DEVTOOLS_MCP_SERVER) return false;
2121
+ const template = loadCanonicalMcp(ctx.stackDir).servers[DEVTOOLS_MCP_SERVER];
2122
+ return template !== void 0 && isManagedOptionalStdioServer(materializeCanonicalDevtoolsServerForRemoval(template), value);
2123
+ }
2118
2124
  function objectValue(value) {
2119
2125
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
2120
2126
  }
@@ -2654,16 +2660,14 @@ ${gitReadCommands.map((command) => `- \`${command}\``).join("\n")}
2654
2660
  }
2655
2661
  if (!isCanonicalMcpServerEnabled(name, server, ctx.enabledMcpServers)) {
2656
2662
  if (owned) {
2657
- if (isManagedOptionalStdioServer(server, existing)) delete mcp[name];
2663
+ if (isOwnedDevtoolsServer(name, server, existing, ctx)) delete mcp[name];
2658
2664
  mcpOwnership.push({ server: name, owned: false });
2659
2665
  }
2660
2666
  continue;
2661
2667
  }
2662
2668
  if (server.optional && existing !== void 0) {
2663
- if (!owned || !isManagedOptionalStdioServer(server, existing)) {
2664
- if (owned) mcpOwnership.push({ server: name, owned: false });
2665
- ctx.warnings.push(`OpenCode: MCP opcional '${name}' ya pertenece a la configuraci\xF3n del usuario; se conserva.`);
2666
- continue;
2669
+ if (!owned || !isOwnedDevtoolsServer(name, server, existing, ctx)) {
2670
+ throw new Error(`OpenCode: ${name}: conflicto con servidor MCP existente ajeno o modificado; se conserva. Retira esa entrada expl\xEDcitamente antes de activar DevTools gestionado.`);
2667
2671
  }
2668
2672
  }
2669
2673
  if (server.transport === "stdio") {
@@ -2792,7 +2796,7 @@ ${gitReadCommands.map((command) => `- \`${command}\``).join("\n")}
2792
2796
  continue;
2793
2797
  }
2794
2798
  if (ctx.ownedMcpServers?.has(name) === true) {
2795
- if (isManagedOptionalStdioServer(server, mcpBlock[name])) delete mcpBlock[name];
2799
+ if (isOwnedDevtoolsServer(name, server, mcpBlock[name], ctx)) delete mcpBlock[name];
2796
2800
  mcpOwnership.push({ server: name, owned: false });
2797
2801
  }
2798
2802
  }
@@ -2938,6 +2942,12 @@ function isManagedOptionalStdioServer2(server, value) {
2938
2942
  const expectedArgs = server.args ?? [];
2939
2943
  return Object.keys(current).length === 3 && current.type === "stdio" && current.command === server.command && Array.isArray(current.args) && current.args.length === expectedArgs.length && current.args.every((arg, index) => arg === expectedArgs[index]);
2940
2944
  }
2945
+ function isOwnedDevtoolsServer2(name, server, value, ctx) {
2946
+ if (isManagedOptionalStdioServer2(server, value)) return true;
2947
+ if (name !== DEVTOOLS_MCP_SERVER) return false;
2948
+ const template = loadCanonicalMcp(ctx.stackDir).servers[DEVTOOLS_MCP_SERVER];
2949
+ return template !== void 0 && isManagedOptionalStdioServer2(materializeCanonicalDevtoolsServerForRemoval(template), value);
2950
+ }
2941
2951
  function errnoCodeOf(error) {
2942
2952
  return error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : "UNKNOWN";
2943
2953
  }
@@ -3288,16 +3298,14 @@ ${agent.body}`,
3288
3298
  }
3289
3299
  if (!isCanonicalMcpServerEnabled(name, server, ctx.enabledMcpServers)) {
3290
3300
  if (owned) {
3291
- if (isManagedOptionalStdioServer2(server, existing)) delete servers[name];
3301
+ if (isOwnedDevtoolsServer2(name, server, existing, ctx)) delete servers[name];
3292
3302
  mcpOwnership.push({ server: name, owned: false });
3293
3303
  }
3294
3304
  continue;
3295
3305
  }
3296
3306
  if (server.optional && existing !== void 0) {
3297
- if (!owned || !isManagedOptionalStdioServer2(server, existing)) {
3298
- if (owned) mcpOwnership.push({ server: name, owned: false });
3299
- ctx.warnings.push(`Claude Code: MCP opcional '${name}' ya pertenece a la configuraci\xF3n del usuario; se conserva.`);
3300
- continue;
3307
+ if (!owned || !isOwnedDevtoolsServer2(name, server, existing, ctx)) {
3308
+ throw new Error(`Claude Code: ${name}: conflicto con servidor MCP existente ajeno o modificado; se conserva. Retira esa entrada expl\xEDcitamente antes de activar DevTools gestionado.`);
3301
3309
  }
3302
3310
  }
3303
3311
  if (server.transport === "stdio") {
@@ -3378,7 +3386,7 @@ ${agent.body}`,
3378
3386
  continue;
3379
3387
  }
3380
3388
  if (ctx.ownedMcpServers?.has(name) === true) {
3381
- if (isManagedOptionalStdioServer2(server, servers[name])) delete servers[name];
3389
+ if (isOwnedDevtoolsServer2(name, server, servers[name], ctx)) delete servers[name];
3382
3390
  mcpOwnership.push({ server: name, owned: false });
3383
3391
  }
3384
3392
  }
@@ -3427,6 +3435,12 @@ args = [${args}]`;
3427
3435
  function isManagedOptionalStdioServer3(server, section) {
3428
3436
  return server.optional === true && server.transport === "stdio" && section?.trim() === stdioMcpSection(server);
3429
3437
  }
3438
+ function isOwnedDevtoolsServer3(name, server, section, ctx) {
3439
+ if (isManagedOptionalStdioServer3(server, section)) return true;
3440
+ if (name !== DEVTOOLS_MCP_SERVER) return false;
3441
+ const template = loadCanonicalMcp(ctx.stackDir).servers[DEVTOOLS_MCP_SERVER];
3442
+ return template !== void 0 && isManagedOptionalStdioServer3(materializeCanonicalDevtoolsServerForRemoval(template), section);
3443
+ }
3430
3444
  function hasActiveEngramPlugin(configDir) {
3431
3445
  const config = readTextIfExists(path14.join(configDir, "config.toml"));
3432
3446
  if (config === null) return false;
@@ -3953,16 +3967,14 @@ ${body}`
3953
3967
  }
3954
3968
  if (!isCanonicalMcpServerEnabled(name, server, ctx.enabledMcpServers)) {
3955
3969
  if (owned) {
3956
- if (isManagedOptionalStdioServer3(server, existing)) content = removeTomlSection(content, section);
3970
+ if (isOwnedDevtoolsServer3(name, server, existing, ctx)) content = removeTomlSection(content, section);
3957
3971
  mcpOwnership.push({ server: name, owned: false });
3958
3972
  }
3959
3973
  continue;
3960
3974
  }
3961
3975
  if (server.optional && existing !== null) {
3962
- if (!owned || !isManagedOptionalStdioServer3(server, existing)) {
3963
- if (owned) mcpOwnership.push({ server: name, owned: false });
3964
- ctx.warnings.push(`Codex: MCP opcional '${name}' ya pertenece a la configuraci\xF3n del usuario; se conserva.`);
3965
- continue;
3976
+ if (!owned || !isOwnedDevtoolsServer3(name, server, existing, ctx)) {
3977
+ throw new Error(`Codex: ${name}: conflicto con servidor MCP existente ajeno o modificado; se conserva. Retira esa entrada expl\xEDcitamente antes de activar DevTools gestionado.`);
3966
3978
  }
3967
3979
  }
3968
3980
  if (server.transport === "stdio") {
@@ -4054,7 +4066,7 @@ args = [${(server.args ?? []).map(tomlString).join(", ")}]`);
4054
4066
  continue;
4055
4067
  }
4056
4068
  if (ctx.ownedMcpServers?.has(name) === true) {
4057
- if (isManagedOptionalStdioServer3(server, readTomlSection(content, section))) {
4069
+ if (isOwnedDevtoolsServer3(name, server, readTomlSection(content, section), ctx)) {
4058
4070
  content = removeTomlSection(content, section);
4059
4071
  }
4060
4072
  mcpOwnership.push({ server: name, owned: false });
@@ -7568,10 +7580,16 @@ function enabledMcpServers(runtime, explicitDevtoolsEnabled, useBrowserPreferenc
7568
7580
  const devtoolsEnabled = explicitDevtoolsEnabled ?? (useBrowserPreferences && loadDevtoolsMcpPreference(devtoolsMcpPreferenceFile(), runtime));
7569
7581
  return devtoolsEnabled ? /* @__PURE__ */ new Set([DEVTOOLS_MCP_SERVER]) : /* @__PURE__ */ new Set();
7570
7582
  }
7571
- function ownedMcpServers(runtime, useBrowserPreferences = true) {
7583
+ function ownedMcpServers(runtime, configDir, useBrowserPreferences = true) {
7572
7584
  if (!useBrowserPreferences) return /* @__PURE__ */ new Set();
7573
7585
  const file = devtoolsMcpPreferenceFile();
7574
- return new Set([DEVTOOLS_MCP_SERVER, "context7"].filter((server) => loadDevtoolsMcpOwnership(file, runtime, server)));
7586
+ const marked = [DEVTOOLS_MCP_SERVER, "context7"].filter((server) => loadDevtoolsMcpOwnership(file, runtime, server));
7587
+ if (marked.length === 0) return /* @__PURE__ */ new Set();
7588
+ const recordedDir = readManifest().runtimes[runtime]?.configDir;
7589
+ if (typeof recordedDir !== "string" || !samePath(recordedDir, configDir)) {
7590
+ throw new Error(`${runtime}: MCP ownership configDir no coincide con el perfil actual; se conserva la configuraci\xF3n. Vuelve al perfil anterior o revisa el estado gestionado antes de reintentar.`);
7591
+ }
7592
+ return new Set(marked);
7575
7593
  }
7576
7594
  function persistConfigurationOwnershipChanges(runtime, configDir, plan) {
7577
7595
  const latest = /* @__PURE__ */ new Map();
@@ -7600,7 +7618,7 @@ function makeContext(adapter, configDir, mode = DEFAULT_INSTALL_MODE_PREFERENCE,
7600
7618
  const models = loadModelMap()[adapter.id];
7601
7619
  if (!models) return null;
7602
7620
  const enabled = enabledMcpServers(adapter.id, void 0, useBrowserPreferences);
7603
- const owned = ownedMcpServers(adapter.id, useBrowserPreferences);
7621
+ const owned = ownedMcpServers(adapter.id, configDir, useBrowserPreferences);
7604
7622
  let devtoolsMcpObservedVersion;
7605
7623
  let devtoolsMcpInvocation;
7606
7624
  if (useBrowserPreferences && (enabled.has(DEVTOOLS_MCP_SERVER) || owned.has(DEVTOOLS_MCP_SERVER))) {
@@ -7849,7 +7867,12 @@ async function runInstall(opts) {
7849
7867
  }
7850
7868
  }
7851
7869
  const anyDevtoolsEnabled = opts.runtimes.some((id) => enabledMcpServers(id, opts.devtoolsMcpSelection?.[id], useManifest).has(DEVTOOLS_MCP_SERVER));
7852
- const anyDevtoolsOwned = useManifest && opts.runtimes.some((id) => ownedMcpServers(id, true).has(DEVTOOLS_MCP_SERVER));
7870
+ const anyDevtoolsOwned = useManifest && opts.runtimes.some((id) => {
7871
+ const adapter = ADAPTERS[id];
7872
+ if (adapter === void 0) return false;
7873
+ const detection = adapter.detect();
7874
+ return detection.installed && ownedMcpServers(id, detection.configDir, true).has(DEVTOOLS_MCP_SERVER);
7875
+ });
7853
7876
  if (anyDevtoolsEnabled && devtoolsManagedInvocation === void 0) {
7854
7877
  const observed = isDevtoolsTargetDir ? devtoolsTargetDirObserved : devtoolsPersistedObserved;
7855
7878
  try {
@@ -7955,7 +7978,7 @@ async function runInstall(opts) {
7955
7978
  }
7956
7979
  }
7957
7980
  const enabledForRuntime = enabledMcpServers(id, opts.devtoolsMcpSelection?.[id], useManifest);
7958
- const ownedForRuntime = ownedMcpServers(id, useManifest);
7981
+ const ownedForRuntime = ownedMcpServers(id, configDir, useManifest);
7959
7982
  let devtoolsObservedForRuntime;
7960
7983
  if (isDevtoolsTargetDir) {
7961
7984
  if (enabledForRuntime.has(DEVTOOLS_MCP_SERVER)) {
@@ -8114,7 +8137,15 @@ async function runInstall(opts) {
8114
8137
  const backup = useManifest ? createBackup([...updates.map((c) => c.action.target), ...orphans], `install-${id}`) : null;
8115
8138
  if (backup) p.log.info(`Backup: ${backup.id} (${backup.files.length} archivos)`);
8116
8139
  applyChanges(changes, useManifest ? (action) => persistConfigurationOwnershipChanges(id, configDir, [action]) : void 0);
8117
- const verifyCtx = { ...ctx, warnings: [] };
8140
+ const verifiedOwnedMcpServers = new Set(ctx.ownedMcpServers ?? []);
8141
+ for (const action of plan) {
8142
+ if (action.kind !== "write") continue;
8143
+ for (const change of action.mcpOwnership ?? []) {
8144
+ if (change.owned) verifiedOwnedMcpServers.add(change.server);
8145
+ else verifiedOwnedMcpServers.delete(change.server);
8146
+ }
8147
+ }
8148
+ const verifyCtx = { ...ctx, warnings: [], ownedMcpServers: verifiedOwnedMcpServers };
8118
8149
  const dirty = diffPlan(buildPlan(adapter, verifyCtx)).filter((d) => d.status !== "unchanged");
8119
8150
  if (dirty.length > 0) {
8120
8151
  p.log.error(`${adapter.name}: verificaci\xF3n de idempotencia FALL\xD3 (${dirty.length} acciones inestables).`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jorgex-stack",
3
- "version": "1.9.64",
3
+ "version": "1.9.65",
4
4
  "description": "Harness multi-agente portable: instala la config JorgeX (agentes, skills, hooks, Engram, MCPs) en Claude Code, Codex CLI, OpenCode y Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",