@kwonye/mcpx 0.1.93 → 0.1.94

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 (47) hide show
  1. package/dist/adapters/cline.d.ts.map +1 -1
  2. package/dist/adapters/codex.d.ts.map +1 -1
  3. package/dist/adapters/kiro.d.ts.map +1 -1
  4. package/dist/adapters/opencode.d.ts.map +1 -1
  5. package/dist/adapters/utils/index.d.ts +11 -3
  6. package/dist/adapters/utils/index.d.ts.map +1 -1
  7. package/dist/{cli-y7ba5qvr.js → cli-154shqmt.js} +126 -68
  8. package/dist/{cli-qvkpwy9w.js → cli-9fmn9y72.js} +36 -17
  9. package/dist/{cli-np0wwh6m.js → cli-csfsg1yf.js} +78 -4
  10. package/dist/{cli-m2645syd.js → cli-mxmgxdm2.js} +127 -69
  11. package/dist/{cli-kwyp9ywh.js → cli-n8vt375e.js} +306 -172
  12. package/dist/{cli-8vxva0cb.js → cli-tk8bggg5.js} +81 -8
  13. package/dist/cli.d.ts.map +1 -1
  14. package/dist/cli.js +45 -21
  15. package/dist/{config-2s5nsm2g.js → config-dtc3c79c.js} +6 -2
  16. package/dist/core/config-repair.d.ts.map +1 -1
  17. package/dist/core/config-store.d.ts +3 -0
  18. package/dist/core/config-store.d.ts.map +1 -0
  19. package/dist/core/config.d.ts +13 -1
  20. package/dist/core/config.d.ts.map +1 -1
  21. package/dist/core/daemon.d.ts +1 -1
  22. package/dist/core/daemon.d.ts.map +1 -1
  23. package/dist/core/errors.d.ts +18 -0
  24. package/dist/core/errors.d.ts.map +1 -0
  25. package/dist/core/index.d.ts +5 -2
  26. package/dist/core/index.d.ts.map +1 -1
  27. package/dist/core/index.js +81 -6
  28. package/dist/core/oauth.d.ts.map +1 -1
  29. package/dist/core/plugin-manager.d.ts.map +1 -1
  30. package/dist/core/plugin-projections.d.ts +6 -2
  31. package/dist/core/plugin-projections.d.ts.map +1 -1
  32. package/dist/core/registry.d.ts +4 -1
  33. package/dist/core/registry.d.ts.map +1 -1
  34. package/dist/core/secrets.d.ts.map +1 -1
  35. package/dist/core/server-auth.d.ts.map +1 -1
  36. package/dist/core/status.d.ts +1 -0
  37. package/dist/core/status.d.ts.map +1 -1
  38. package/dist/core/sync.d.ts +19 -2
  39. package/dist/core/sync.d.ts.map +1 -1
  40. package/dist/gateway/server.d.ts +4 -1
  41. package/dist/gateway/server.d.ts.map +1 -1
  42. package/dist/{plugin-manager-1sc4b6am.js → plugin-manager-1sjwfnah.js} +4 -4
  43. package/dist/{registry-mztfy0cz.js → registry-n12thgf2.js} +1 -1
  44. package/dist/types.d.ts +2 -0
  45. package/dist/types.d.ts.map +1 -1
  46. package/dist/version.d.ts +1 -1
  47. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"cline.d.ts","sourceRoot":"","sources":["../../src/adapters/cline.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA2D1G,qBAAa,YAAa,YAAW,aAAa;IAChD,QAAQ,CAAC,EAAE,EAAG,OAAO,CAAU;IAE/B,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAWjC,YAAY,IAAI,OAAO;IAIvB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY;IAmE9D,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU;CAgEzE"}
1
+ {"version":3,"file":"cline.d.ts","sourceRoot":"","sources":["../../src/adapters/cline.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA2D1G,qBAAa,YAAa,YAAW,aAAa;IAChD,QAAQ,CAAC,EAAE,EAAG,OAAO,CAAU;IAE/B,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAWjC,YAAY,IAAI,OAAO;IAIvB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY;IAmE9D,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU;CA2DzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/adapters/codex.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAoC7I,qBAAa,YAAa,YAAW,aAAa;IAChD,QAAQ,CAAC,EAAE,EAAG,OAAO,CAAU;IAE/B,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,YAAY,IAAI,OAAO;IAIvB,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,gBAAgB;IAIzD,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY;IA+D9D,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU;CAwDzE"}
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/adapters/codex.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAoC7I,qBAAa,YAAa,YAAW,aAAa;IAChD,QAAQ,CAAC,EAAE,EAAG,OAAO,CAAU;IAE/B,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,YAAY,IAAI,OAAO;IAIvB,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,gBAAgB;IAIzD,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY;IA+D9D,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU;CAyDzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"kiro.d.ts","sourceRoot":"","sources":["../../src/adapters/kiro.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAqCpJ,qBAAa,WAAY,YAAW,aAAa;IAC/C,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAU;IAE9B,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,YAAY,IAAI,OAAO;IAIvB,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,gBAAgB;IAIzD,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY;IAgE9D,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU;IAwDxE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI;CAyBlC"}
1
+ {"version":3,"file":"kiro.d.ts","sourceRoot":"","sources":["../../src/adapters/kiro.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAqCpJ,qBAAa,WAAY,YAAW,aAAa;IAC/C,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAU;IAE9B,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,YAAY,IAAI,OAAO;IAIvB,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,gBAAgB;IAIzD,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY;IAgE9D,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU;IAyDxE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI;CAyBlC"}
@@ -1 +1 @@
1
- {"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/adapters/opencode.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+B1G,qBAAa,eAAgB,YAAW,aAAa;IACnD,QAAQ,CAAC,EAAE,EAAG,UAAU,CAAU;IAElC,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,YAAY,IAAI,OAAO;IAIvB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY;IAuE9D,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU;CAwDzE"}
1
+ {"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/adapters/opencode.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+B1G,qBAAa,eAAgB,YAAW,aAAa;IACnD,QAAQ,CAAC,EAAE,EAAG,UAAU,CAAU;IAElC,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,YAAY,IAAI,OAAO;IAIvB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY;IAuE9D,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU;CAyDzE"}
@@ -1,4 +1,4 @@
1
- import type { ClientId, ClientImportScanResult, ClientImportSkippedEntry, ManagedGatewayEntry, ManagedIndex, SyncResult, UpstreamServerSpec } from "../../types.js";
1
+ import type { ClientId, ClientImportScanResult, ClientImportSkippedEntry, ManagedIndex, SyncResult, UpstreamServerSpec } from "../../types.js";
2
2
  export declare function getManagedEntryNames(managedIndex: ManagedIndex, clientId: ClientId): string[];
3
3
  export declare function isManagedEntry(managedIndex: ManagedIndex, clientId: ClientId, entryName: string): boolean;
4
4
  export declare function pruneStaleManagedEntries(managedIndex: ManagedIndex, clientId: ClientId, servers: Record<string, unknown>, keepEntryNames: string[]): void;
@@ -16,6 +16,14 @@ export declare function serverSpecsEqual(left: UpstreamServerSpec, right: Upstre
16
16
  export declare function emptyImportScan(clientId: ClientId, configPath?: string): ClientImportScanResult;
17
17
  export declare function buildImportSkip(clientId: ClientId, sourceEntryName: string, reason: string, configPath?: string, serverName?: string): ClientImportSkippedEntry;
18
18
  export declare function removeSourceEntries(entries: Record<string, unknown>, names: string[] | undefined): void;
19
- export declare function syncDisabledMcpServersArray(raw: Record<string, unknown>, managedNames: string[], managedEntries: ManagedGatewayEntry[]): void;
20
- export declare function syncMcpExcludedArray(raw: Record<string, unknown>, managedNames: string[], managedEntries: ManagedGatewayEntry[]): void;
19
+ /**
20
+ * Purge managed entry names from the native disabledMcpServers array.
21
+ * Disabled managed servers are simply absent from the client config (no entry written).
22
+ */
23
+ export declare function purgeManagedFromDisabledArray(raw: Record<string, unknown>, managedNames: string[]): void;
24
+ /**
25
+ * Purge managed entry names from the mcp.excluded array.
26
+ * Disabled managed servers are simply absent from the client config (no entry written).
27
+ */
28
+ export declare function purgeManagedFromExcludedArray(raw: Record<string, unknown>, managedNames: string[]): void;
21
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAGxB,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,CAE7F;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEzG;AAED,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,cAAc,EAAE,MAAM,EAAE,GACvB,IAAI,CAcN;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,GACrB,MAAM,GAAG,IAAI,CAUf;AAED,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,IAAI,CAeN;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,CAO7F;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAMjF;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAO3G;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAM7E;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAErE;AAaD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,GAAG,kBAAkB,CAgBhF;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAEpE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAE7F;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,sBAAsB,CAO/F;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,SAAkB,GAC3B,wBAAwB,CAQ1B;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,CAIvG;AAED,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,YAAY,EAAE,MAAM,EAAE,EACtB,cAAc,EAAE,mBAAmB,EAAE,GACpC,IAAI,CAON;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,YAAY,EAAE,MAAM,EAAE,EACtB,cAAc,EAAE,mBAAmB,EAAE,GACpC,IAAI,CASN"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,sBAAsB,EACtB,wBAAwB,EAExB,YAAY,EACZ,UAAU,EACV,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAGxB,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,CAE7F;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEzG;AAED,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,cAAc,EAAE,MAAM,EAAE,GACvB,IAAI,CAcN;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,GACrB,MAAM,GAAG,IAAI,CAUf;AAED,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,IAAI,CAeN;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,CAO7F;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAMjF;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAO3G;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAM7E;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAErE;AAaD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,GAAG,kBAAkB,CAgBhF;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAEpE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAE7F;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,sBAAsB,CAO/F;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,SAAkB,GAC3B,wBAAwB,CAQ1B;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,CAIvG;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,YAAY,EAAE,MAAM,EAAE,GACrB,IAAI,CAMN;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,YAAY,EAAE,MAAM,EAAE,GACrB,IAAI,CAQN"}
@@ -1,16 +1,19 @@
1
1
  import {
2
2
  getGatewayUrl,
3
+ persistSyncState,
3
4
  syncAllClients
4
- } from "./cli-kwyp9ywh.js";
5
+ } from "./cli-n8vt375e.js";
5
6
  import {
6
7
  loadConfig,
7
8
  loadMergedConfig,
8
9
  saveConfig
9
- } from "./cli-np0wwh6m.js";
10
+ } from "./cli-csfsg1yf.js";
10
11
  import {
11
12
  SecretsManager,
13
+ UpstreamError,
14
+ classifyUpstreamError,
12
15
  ensureGatewayToken
13
- } from "./cli-8vxva0cb.js";
16
+ } from "./cli-tk8bggg5.js";
14
17
  import {
15
18
  ensureDir,
16
19
  ensureParentDir,
@@ -344,6 +347,7 @@ function listAuthBindings(spec) {
344
347
  value
345
348
  }));
346
349
  }
350
+ var TOKEN68 = /^[A-Za-z0-9\-._~+/]+=*$/;
347
351
  function maybePrefixBearer(target, value, raw = false) {
348
352
  if (raw || target.kind !== "header" || target.key.toLowerCase() !== "authorization") {
349
353
  return value;
@@ -351,7 +355,10 @@ function maybePrefixBearer(target, value, raw = false) {
351
355
  if (/^\S+\s+\S+/.test(value)) {
352
356
  return value;
353
357
  }
354
- return `Bearer ${value}`;
358
+ if (TOKEN68.test(value)) {
359
+ return `Bearer ${value}`;
360
+ }
361
+ return value;
355
362
  }
356
363
 
357
364
  // src/core/spawn-env.ts
@@ -605,7 +612,12 @@ function bindOAuthReference(config, serverName) {
605
612
  };
606
613
  }
607
614
  async function runOAuthLogin(serverName, spec, secrets, openUrl, configPath, codeReceiver) {
608
- new McpxOAuthProvider(serverName, secrets).invalidateCredentials("all");
615
+ const oauthName = oauthSecretName(serverName, "tokens");
616
+ const clientName = oauthSecretName(serverName, "client");
617
+ const backupTokens = secrets.getSecret(oauthName);
618
+ const backupClient = secrets.getSecret(clientName);
619
+ new McpxOAuthProvider(serverName, secrets).invalidateCredentials("verifier");
620
+ new McpxOAuthProvider(serverName, secrets).invalidateCredentials("discovery");
609
621
  const state = crypto.randomUUID();
610
622
  let callbackServer;
611
623
  let redirectUrl;
@@ -638,8 +650,16 @@ async function runOAuthLogin(serverName, spec, secrets, openUrl, configPath, cod
638
650
  const config = loadConfig(configPath);
639
651
  bindOAuthReference(config, serverName);
640
652
  saveConfig(config, configPath);
641
- syncAllClients(config, secrets);
653
+ const summary = syncAllClients(config, secrets);
654
+ persistSyncState(summary, config);
655
+ saveConfig(config, configPath);
642
656
  return { serverName, authorized: true };
657
+ } catch (error) {
658
+ if (backupTokens)
659
+ secrets.setSecret(oauthName, backupTokens);
660
+ if (backupClient)
661
+ secrets.setSecret(clientName, backupClient);
662
+ throw error;
643
663
  } finally {
644
664
  if (callbackServer) {
645
665
  await closeServer(callbackServer);
@@ -649,32 +669,52 @@ async function runOAuthLogin(serverName, spec, secrets, openUrl, configPath, cod
649
669
  async function getOAuthAccessToken(serverName, spec, secrets, options = {}) {
650
670
  const stored = readJsonSecret(secrets, oauthSecretName(serverName, "tokens"));
651
671
  if (!stored) {
652
- throw new Error(`No OAuth tokens stored for "${serverName}". Run mcpx auth login ${serverName}.`);
653
- }
654
- if (!options.forceRefresh && !tokensAreExpiring(stored)) {
655
- return stored.tokens.access_token;
672
+ throw new UpstreamError(serverName, "auth_required", `No OAuth tokens stored for "${serverName}".`);
656
673
  }
657
- if (!stored.tokens.refresh_token) {
658
- if (!options.forceRefresh) {
659
- return stored.tokens.access_token;
674
+ if (options.forceRefresh || tokensAreExpiring(stored)) {
675
+ if (!stored.tokens.refresh_token) {
676
+ if (!options.forceRefresh) {
677
+ return stored.tokens.access_token;
678
+ }
679
+ throw new UpstreamError(serverName, "auth_expired", `No refresh token for "${serverName}". Re-authentication required.`);
680
+ }
681
+ const provider = new McpxOAuthProvider(serverName, secrets);
682
+ const clientInformation = provider.clientInformation();
683
+ if (!clientInformation) {
684
+ throw new UpstreamError(serverName, "auth_expired", `No OAuth client info for "${serverName}". Re-authentication required.`);
685
+ }
686
+ let serverInfo;
687
+ try {
688
+ const cachedDiscovery = provider.discoveryState();
689
+ serverInfo = cachedDiscovery ?? await discoverOAuthServerInfo(spec.url);
690
+ } catch (err) {
691
+ const message = err instanceof Error ? err.message : String(err);
692
+ if (/ECONNREFUSED|ENOTFOUND|EAI_AGAIN|fetch failed/i.test(message)) {
693
+ throw new UpstreamError(serverName, "unreachable", `OAuth discovery failed: ${message}`);
694
+ }
695
+ throw new UpstreamError(serverName, "upstream_error", `OAuth discovery failed: ${message}`);
696
+ }
697
+ try {
698
+ const refreshed = await refreshAuthorization(serverInfo.authorizationServerUrl, {
699
+ metadata: serverInfo.authorizationServerMetadata,
700
+ clientInformation,
701
+ refreshToken: stored.tokens.refresh_token,
702
+ resource: serverInfo.resourceMetadata?.resource ? new URL(serverInfo.resourceMetadata.resource) : undefined
703
+ });
704
+ provider.saveTokens(refreshed);
705
+ return refreshed.access_token;
706
+ } catch (err) {
707
+ const message = err instanceof Error ? err.message : String(err);
708
+ if (/invalid_grant|invalid_client|4\d{2}/i.test(message)) {
709
+ throw new UpstreamError(serverName, "auth_expired", `OAuth refresh failed: ${message}`);
710
+ }
711
+ if (/ECONNREFUSED|ENOTFOUND|EAI_AGAIN|fetch failed/i.test(message)) {
712
+ throw new UpstreamError(serverName, "unreachable", `OAuth refresh failed: ${message}`);
713
+ }
714
+ throw new UpstreamError(serverName, "upstream_error", `OAuth refresh failed: ${message}`);
660
715
  }
661
- throw new Error(`No OAuth refresh token stored for "${serverName}". Re-authentication required.`);
662
- }
663
- const provider = new McpxOAuthProvider(serverName, secrets);
664
- const clientInformation = provider.clientInformation();
665
- if (!clientInformation) {
666
- throw new Error(`No OAuth client information stored for "${serverName}". Re-authentication required.`);
667
716
  }
668
- const cachedDiscovery = provider.discoveryState();
669
- const serverInfo = cachedDiscovery ?? await discoverOAuthServerInfo(spec.url);
670
- const refreshed = await refreshAuthorization(serverInfo.authorizationServerUrl, {
671
- metadata: serverInfo.authorizationServerMetadata,
672
- clientInformation,
673
- refreshToken: stored.tokens.refresh_token,
674
- resource: serverInfo.resourceMetadata?.resource ? new URL(serverInfo.resourceMetadata.resource) : undefined
675
- });
676
- provider.saveTokens(refreshed);
677
- return refreshed.access_token;
717
+ return stored.tokens.access_token;
678
718
  }
679
719
 
680
720
  // src/version.ts
@@ -944,7 +984,7 @@ function performRollback() {
944
984
  // src/core/daemon.ts
945
985
  import fs4 from "node:fs";
946
986
  import net from "node:net";
947
- import { spawn as spawn2 } from "node:child_process";
987
+ import { spawn as spawn2, execFileSync as execFileSync2 } from "node:child_process";
948
988
 
949
989
  // src/gateway/server.ts
950
990
  import http2 from "node:http";
@@ -964,19 +1004,6 @@ var OAUTH_WELL_KNOWN_PREFIXES = [
964
1004
  "/.well-known/oauth-authorization-server",
965
1005
  "/.well-known/openid-configuration"
966
1006
  ];
967
-
968
- class UpstreamHttpError extends Error {
969
- status;
970
- wwwAuthenticate;
971
- bodyText;
972
- constructor(upstreamName, status, bodyText, wwwAuthenticate) {
973
- super(`Upstream ${upstreamName} returned HTTP ${status}: ${bodyText.slice(0, 400)}`);
974
- this.name = "UpstreamHttpError";
975
- this.status = status;
976
- this.bodyText = bodyText;
977
- this.wwwAuthenticate = wwwAuthenticate;
978
- }
979
- }
980
1007
  function makeError(id, code, message, data) {
981
1008
  return {
982
1009
  jsonrpc: "2.0",
@@ -1135,8 +1162,8 @@ async function getUpstreamTokenCounts(config, secrets, runtime) {
1135
1162
  const fingerprint = specFingerprint(upstream.spec);
1136
1163
  const cached = runtime.tokenCache.get(upstream.name);
1137
1164
  if (cached?.fingerprint === fingerprint) {
1138
- const runtimeError2 = runtime.upstreamErrors?.get(upstream.name);
1139
- results[upstream.name] = runtimeError2 ? { ...cached.count, runtimeError: runtimeError2 } : cached.count;
1165
+ const runtimeErr2 = runtime.upstreamErrors?.get(upstream.name);
1166
+ results[upstream.name] = runtimeErr2 ? { ...cached.count, runtimeError: runtimeErr2.message, runtimeErrorCode: runtimeErr2.code } : cached.count;
1140
1167
  continue;
1141
1168
  }
1142
1169
  let toolsCount = 0;
@@ -1178,8 +1205,8 @@ async function getUpstreamTokenCounts(config, secrets, runtime) {
1178
1205
  if (errors.length === 0) {
1179
1206
  runtime.tokenCache.set(upstream.name, { fingerprint, count: countObj });
1180
1207
  }
1181
- const runtimeError = runtime.upstreamErrors?.get(upstream.name);
1182
- results[upstream.name] = runtimeError ? { ...countObj, runtimeError } : countObj;
1208
+ const runtimeErr = runtime.upstreamErrors?.get(upstream.name);
1209
+ results[upstream.name] = runtimeErr ? { ...countObj, runtimeError: runtimeErr.message, runtimeErrorCode: runtimeErr.code } : countObj;
1183
1210
  }
1184
1211
  return results;
1185
1212
  }
@@ -1348,11 +1375,8 @@ async function callUpstreamOnce(upstream, method, params, secrets, runtime, pass
1348
1375
  if (!forceOAuthRefresh && hasOAuth && error instanceof StreamableHTTPError && (error.code === 401 || error.code === 403)) {
1349
1376
  return callUpstreamOnce(upstream, method, params, secrets, runtime, passthroughAuthorizationHeader, true);
1350
1377
  }
1351
- if (upstream.spec.transport === "http" && error instanceof StreamableHTTPError && error.code) {
1352
- const wwwAuthenticate = runtime.lastWwwAuthenticate?.get(upstream.name);
1353
- throw new UpstreamHttpError(upstream.name, error.code, error.message ?? "", wwwAuthenticate);
1354
- }
1355
- throw error;
1378
+ const wwwAuthenticate = runtime.lastWwwAuthenticate?.get(upstream.name);
1379
+ throw classifyUpstreamError(upstream.name, error, wwwAuthenticate);
1356
1380
  }
1357
1381
  }
1358
1382
  function authHeaderIsValid(request, expectedToken) {
@@ -1371,7 +1395,7 @@ function authHeaderIsValid(request, expectedToken) {
1371
1395
  return scheme === "Bearer" && token === expectedToken;
1372
1396
  }
1373
1397
  function isAuthChallenge(error) {
1374
- return error instanceof UpstreamHttpError && (error.status === 401 || error.status === 403);
1398
+ return error instanceof UpstreamError && (error.code === "auth_required" || error.code === "auth_expired");
1375
1399
  }
1376
1400
  function getClientAuthorizationForUpstream(request, expectedToken) {
1377
1401
  const authHeader = request.headers.authorization;
@@ -1412,7 +1436,8 @@ async function handleListTools(config, secrets, runtime, upstreamFilter, clientA
1412
1436
  if (upstreams.length === 1) {
1413
1437
  throw error;
1414
1438
  }
1415
- runtime.upstreamErrors?.set(upstream.name, error instanceof Error ? error.message : String(error));
1439
+ const code = error instanceof UpstreamError ? error.code : "upstream_error";
1440
+ runtime.upstreamErrors?.set(upstream.name, { code, message: error instanceof Error ? error.message : String(error) });
1416
1441
  }
1417
1442
  }
1418
1443
  return { tools };
@@ -1447,7 +1472,8 @@ async function handleListResources(config, secrets, runtime, upstreamFilter, cli
1447
1472
  if (upstreams.length === 1) {
1448
1473
  throw error;
1449
1474
  }
1450
- runtime.upstreamErrors?.set(upstream.name, error instanceof Error ? error.message : String(error));
1475
+ const code = error instanceof UpstreamError ? error.code : "upstream_error";
1476
+ runtime.upstreamErrors?.set(upstream.name, { code, message: error instanceof Error ? error.message : String(error) });
1451
1477
  }
1452
1478
  }
1453
1479
  return { resources };
@@ -1480,7 +1506,8 @@ async function handleListPrompts(config, secrets, runtime, upstreamFilter, clien
1480
1506
  if (upstreams.length === 1) {
1481
1507
  throw error;
1482
1508
  }
1483
- runtime.upstreamErrors?.set(upstream.name, error instanceof Error ? error.message : String(error));
1509
+ const code = error instanceof UpstreamError ? error.code : "upstream_error";
1510
+ runtime.upstreamErrors?.set(upstream.name, { code, message: error instanceof Error ? error.message : String(error) });
1484
1511
  }
1485
1512
  }
1486
1513
  return { prompts };
@@ -1521,8 +1548,9 @@ async function routeNamespacedCall(config, method, params, id, secrets, runtime,
1521
1548
  if (isAuthChallenge(error)) {
1522
1549
  throw error;
1523
1550
  }
1524
- runtime.upstreamErrors?.set(upstream2.name, error.message);
1525
- return makeError(id, -32000, error.message);
1551
+ const errCode = error instanceof UpstreamError ? error.code : "upstream_error";
1552
+ runtime.upstreamErrors?.set(upstream2.name, { code: errCode, message: error.message });
1553
+ return makeError(id, -32000, error.message, { mcpxCode: errCode, upstream: upstream2.name });
1526
1554
  }
1527
1555
  }
1528
1556
  if (method === "prompts/get") {
@@ -1554,8 +1582,9 @@ async function routeNamespacedCall(config, method, params, id, secrets, runtime,
1554
1582
  if (isAuthChallenge(error)) {
1555
1583
  throw error;
1556
1584
  }
1557
- runtime.upstreamErrors?.set(upstream2.name, error.message);
1558
- return makeError(id, -32000, error.message);
1585
+ const errCode = error instanceof UpstreamError ? error.code : "upstream_error";
1586
+ runtime.upstreamErrors?.set(upstream2.name, { code: errCode, message: error.message });
1587
+ return makeError(id, -32000, error.message, { mcpxCode: errCode, upstream: upstream2.name });
1559
1588
  }
1560
1589
  }
1561
1590
  const uri = typeof params.uri === "string" ? params.uri : "";
@@ -1586,8 +1615,9 @@ async function routeNamespacedCall(config, method, params, id, secrets, runtime,
1586
1615
  if (isAuthChallenge(error)) {
1587
1616
  throw error;
1588
1617
  }
1589
- runtime.upstreamErrors?.set(upstream.name, error.message);
1590
- return makeError(id, -32000, error.message);
1618
+ const errCode = error instanceof UpstreamError ? error.code : "upstream_error";
1619
+ runtime.upstreamErrors?.set(upstream.name, { code: errCode, message: error.message });
1620
+ return makeError(id, -32000, error.message, { mcpxCode: errCode, upstream: upstream.name });
1591
1621
  }
1592
1622
  }
1593
1623
  async function handleRequestObject(request, secrets, runtime, upstreamFilter, clientAuthorizationHeader) {
@@ -1858,16 +1888,16 @@ function createGatewayServer(options) {
1858
1888
  }
1859
1889
  } catch (error) {
1860
1890
  if (isAuthChallenge(error)) {
1861
- response.statusCode = error.status;
1891
+ response.statusCode = error.status ?? 401;
1862
1892
  response.setHeader("content-type", "application/json");
1863
1893
  if (error.wwwAuthenticate) {
1864
1894
  const localResourceMetadataUrl = appendUpstreamQuery(`${getLocalOriginFromRequest(request)}/.well-known/oauth-protected-resource`, getRequestedUpstream(requestUrl));
1865
1895
  response.setHeader("www-authenticate", rewriteWwwAuthenticateResourceMetadata(error.wwwAuthenticate, localResourceMetadataUrl));
1866
1896
  }
1867
1897
  response.end(JSON.stringify(makeError(null, -32001, "Upstream authentication required.", {
1898
+ mcpxCode: error.code,
1868
1899
  status: error.status,
1869
- body: error.bodyText,
1870
- wwwAuthenticate: error.wwwAuthenticate
1900
+ upstream: error.upstream
1871
1901
  })));
1872
1902
  if (debug) {
1873
1903
  console.error(`[mcpx gateway] -> ${error.status} upstream auth challenge`);
@@ -1927,7 +1957,7 @@ async function isPortAvailable(port) {
1927
1957
  tester.listen(port, "127.0.0.1");
1928
1958
  });
1929
1959
  }
1930
- async function resolveGatewayPort(config) {
1960
+ async function resolveGatewayPort(config, secrets) {
1931
1961
  if (await isPortAvailable(config.gateway.port)) {
1932
1962
  return config.gateway.port;
1933
1963
  }
@@ -1937,8 +1967,16 @@ async function resolveGatewayPort(config) {
1937
1967
  break;
1938
1968
  }
1939
1969
  if (await isPortAvailable(candidate)) {
1970
+ const oldPort = config.gateway.port;
1940
1971
  config.gateway.port = candidate;
1941
1972
  saveConfig(config);
1973
+ if (secrets) {
1974
+ try {
1975
+ const summary = syncAllClients(config, secrets);
1976
+ persistSyncState(summary, config);
1977
+ saveConfig(config);
1978
+ } catch {}
1979
+ }
1942
1980
  return candidate;
1943
1981
  }
1944
1982
  }
@@ -2002,7 +2040,7 @@ async function startDaemon(config, cliPath, secrets) {
2002
2040
  fs4.unlinkSync(getPidPath());
2003
2041
  } catch {}
2004
2042
  }
2005
- const port = await resolveGatewayPort(config);
2043
+ const port = await resolveGatewayPort(config, secrets);
2006
2044
  const token = ensureGatewayToken(config, secrets);
2007
2045
  const pidPath = getPidPath();
2008
2046
  const logPath = getLogPath();
@@ -2038,6 +2076,24 @@ function stopDaemon() {
2038
2076
  message: "mcpx daemon is not running."
2039
2077
  };
2040
2078
  }
2079
+ try {
2080
+ const cmd = execFileSync2("ps", ["-p", String(pid), "-o", "command="], { encoding: "utf8", timeout: 2000 }).trim();
2081
+ if (!cmd.includes("mcpx") && !cmd.includes("daemon") && !cmd.includes("cli.js")) {
2082
+ fs4.unlinkSync(pidPath);
2083
+ return {
2084
+ stopped: false,
2085
+ message: `PID ${pid} is not a mcpx daemon (command: ${cmd.slice(0, 80)}). Pidfile cleaned up.`
2086
+ };
2087
+ }
2088
+ } catch {
2089
+ try {
2090
+ fs4.unlinkSync(pidPath);
2091
+ } catch {}
2092
+ return {
2093
+ stopped: false,
2094
+ message: `PID ${pid} not found. Pidfile cleaned up.`
2095
+ };
2096
+ }
2041
2097
  try {
2042
2098
  process.kill(pid, "SIGTERM");
2043
2099
  } catch {}
@@ -2165,6 +2221,7 @@ async function buildStatusReport(config, managedIndex, daemon = getDaemonStatus(
2165
2221
  if (tokenCount?.error && buildAuthBindings(spec).length > 0 && tokenCount.total > 0) {
2166
2222
  tokenCount = { ...tokenCount, error: undefined };
2167
2223
  }
2224
+ const health = tokenCount ? tokenCount.error || tokenCount.runtimeError ? "error" : "ok" : "unknown";
2168
2225
  const serverEntry = {
2169
2226
  name,
2170
2227
  enabled: isServerEnabled(spec),
@@ -2172,7 +2229,8 @@ async function buildStatusReport(config, managedIndex, daemon = getDaemonStatus(
2172
2229
  target: describeServerTarget(spec),
2173
2230
  authBindings: buildAuthBindings(spec),
2174
2231
  clients: buildClientMappings(config, managedIndex, name),
2175
- tokenCount
2232
+ tokenCount,
2233
+ health
2176
2234
  };
2177
2235
  if (serverEntry.enabled && tokenCount) {
2178
2236
  totalGlobalTokens += tokenCount.total;
@@ -1,14 +1,14 @@
1
1
  import {
2
+ persistSyncState,
2
3
  syncAllClients
3
- } from "./cli-kwyp9ywh.js";
4
+ } from "./cli-n8vt375e.js";
4
5
  import {
5
6
  loadConfig,
6
- loadMergedConfig,
7
7
  saveConfig
8
- } from "./cli-np0wwh6m.js";
8
+ } from "./cli-csfsg1yf.js";
9
9
  import {
10
10
  SecretsManager
11
- } from "./cli-8vxva0cb.js";
11
+ } from "./cli-tk8bggg5.js";
12
12
  import {
13
13
  ensureDir,
14
14
  getConfigPath,
@@ -691,11 +691,18 @@ class PluginManager {
691
691
  if (config.plugins[pluginId]) {
692
692
  throw new Error(`Plugin ${pluginId} is already installed`);
693
693
  }
694
+ const serverNames = info.components.mcpServers.map((s) => `${pluginName}__${s.id}`);
695
+ for (const existing of Object.values(config.plugins)) {
696
+ for (const sn of serverNames) {
697
+ if (existing.serverNames.includes(sn)) {
698
+ throw new Error(`Server name collision: "${sn}" is already claimed by plugin "${existing.name}". Use --name to specify a different plugin name.`);
699
+ }
700
+ }
701
+ }
694
702
  const dataDir = path5.join(getPluginDataRoot(), pluginId);
695
703
  ensureDir(dataDir);
696
704
  const enabled = options?.enabled ?? true;
697
705
  const discovered = info.components;
698
- const serverNames = discovered.mcpServers.map((s) => `${pluginName}__${s.id}`);
699
706
  const plugin = {
700
707
  id: pluginId,
701
708
  name: pluginName,
@@ -736,8 +743,10 @@ class PluginManager {
736
743
  }
737
744
  saveConfig(config, this.configPath);
738
745
  this.lifecycle.initData(pluginId);
739
- const mergedConfig = loadMergedConfig(this.configPath);
740
- syncAllClients(mergedConfig, this.secrets);
746
+ const syncConfig = loadConfig(this.configPath);
747
+ const summary = syncAllClients(syncConfig, this.secrets);
748
+ persistSyncState(summary, syncConfig);
749
+ saveConfig(syncConfig, this.configPath);
741
750
  return plugin;
742
751
  }
743
752
  async updatePlugin(pluginId) {
@@ -772,8 +781,10 @@ class PluginManager {
772
781
  current.approvals = {};
773
782
  config.plugins[pluginId] = current;
774
783
  saveConfig(config, this.configPath);
775
- const mergedConfig = loadMergedConfig(this.configPath);
776
- syncAllClients(mergedConfig, this.secrets);
784
+ const syncConfig = loadConfig(this.configPath);
785
+ const summary = syncAllClients(syncConfig, this.secrets);
786
+ persistSyncState(summary, syncConfig);
787
+ saveConfig(syncConfig, this.configPath);
777
788
  return current;
778
789
  }
779
790
  async uninstallPlugin(pluginId, keepData = false) {
@@ -791,8 +802,10 @@ class PluginManager {
791
802
  if (!keepData) {
792
803
  await this.lifecycle.removeData(pluginId);
793
804
  }
794
- const mergedConfig = loadMergedConfig(this.configPath);
795
- syncAllClients(mergedConfig, this.secrets);
805
+ const syncConfig = loadConfig(this.configPath);
806
+ const summary = syncAllClients(syncConfig, this.secrets);
807
+ persistSyncState(summary, syncConfig);
808
+ saveConfig(syncConfig, this.configPath);
796
809
  }
797
810
  async enablePlugin(pluginId) {
798
811
  const config = loadConfig(this.configPath);
@@ -803,8 +816,10 @@ class PluginManager {
803
816
  throw new Error(`Plugin ${pluginId} not found`);
804
817
  plugin.enabled = true;
805
818
  saveConfig(config, this.configPath);
806
- const mergedConfig = loadMergedConfig(this.configPath);
807
- syncAllClients(mergedConfig, this.secrets);
819
+ const syncConfig = loadConfig(this.configPath);
820
+ const summary = syncAllClients(syncConfig, this.secrets);
821
+ persistSyncState(summary, syncConfig);
822
+ saveConfig(syncConfig, this.configPath);
808
823
  }
809
824
  async disablePlugin(pluginId) {
810
825
  const config = loadConfig(this.configPath);
@@ -815,8 +830,10 @@ class PluginManager {
815
830
  throw new Error(`Plugin ${pluginId} not found`);
816
831
  plugin.enabled = false;
817
832
  saveConfig(config, this.configPath);
818
- const mergedConfig = loadMergedConfig(this.configPath);
819
- syncAllClients(mergedConfig, this.secrets);
833
+ const syncConfig = loadConfig(this.configPath);
834
+ const summary = syncAllClients(syncConfig, this.secrets);
835
+ persistSyncState(summary, syncConfig);
836
+ saveConfig(syncConfig, this.configPath);
820
837
  }
821
838
  async approveComponent(pluginId, component) {
822
839
  const config = loadConfig(this.configPath);
@@ -836,8 +853,10 @@ class PluginManager {
836
853
  }
837
854
  }
838
855
  saveConfig(config, this.configPath);
839
- const mergedConfig = loadMergedConfig(this.configPath);
840
- syncAllClients(mergedConfig, this.secrets);
856
+ const syncConfig = loadConfig(this.configPath);
857
+ const summary = syncAllClients(syncConfig, this.secrets);
858
+ persistSyncState(summary, syncConfig);
859
+ saveConfig(syncConfig, this.configPath);
841
860
  }
842
861
  async getPluginStatus(pluginId) {
843
862
  const config = loadConfig(this.configPath);