@moxxy/plugin-provider-admin 0.26.0 → 0.27.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,MAAM,EACX,KAAK,iBAAiB,EAEtB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAsBpB,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,CAAC;AAChG,YAAY,EAAE,cAAc,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE7E;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;IACnC;;;;;OAKG;IACH,aAAa,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC;IAChC;;;;;OAKG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CACrE;AAED,MAAM,WAAW,+BAA+B;IAC9C,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;IAChD,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7G;AAkJD;;;;;GAKG;AACH,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5D;;;;;OAKG;IACH,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAsFD;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,+BAA+B,GAAG;IACtF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;CACjC,CA8CA;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,+BAA+B,EACrC,YAAY,CAAC,EAAE,mBAAmB,GACjC,MAAM,CAmMR;AAcD,eAAO,MAAM,mBAAmB,EAAE,MAsC9B,CAAC;AAGL,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,MAAM,EACX,KAAK,iBAAiB,EAEtB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAsBpB,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,CAAC;AAChG,YAAY,EAAE,cAAc,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE7E;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;IACnC;;;;;OAKG;IACH,aAAa,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC;IAChC;;;;;OAKG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CACrE;AAED,MAAM,WAAW,+BAA+B;IAC9C,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;IAChD,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7G;AAkJD;;;;;GAKG;AACH,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5D;;;;;OAKG;IACH,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAsFD;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,+BAA+B,GAAG;IACtF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;CACjC,CA8CA;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,+BAA+B,EACrC,YAAY,CAAC,EAAE,mBAAmB,GACjC,MAAM,CAwOR;AAcD,eAAO,MAAM,mBAAmB,EAAE,MAsC9B,CAAC;AAGL,eAAe,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -256,7 +256,7 @@ export function buildProviderAdminPluginWithApi(opts) {
256
256
  throw new MoxxyError({
257
257
  code: 'CONFIG_INVALID',
258
258
  message: `provider-admin: "${name}" is a built-in provider and cannot be reconfigured here — ` +
259
- `built-ins are code. Only runtime-registered (providers.json) providers are editable.`,
259
+ `built-ins are code. Only runtime-registered (stored) providers are editable.`,
260
260
  });
261
261
  }
262
262
  // Defense-in-depth: validate the patch HERE (where it is persisted), not
@@ -268,7 +268,7 @@ export function buildProviderAdminPluginWithApi(opts) {
268
268
  throw new MoxxyError({
269
269
  code: 'CONFIG_INVALID',
270
270
  message: `provider-admin: no stored provider named "${name}" — only runtime-registered ` +
271
- `(providers.json) providers are configurable; built-ins are code.`,
271
+ `(stored) providers are configurable; built-ins are code.`,
272
272
  });
273
273
  }
274
274
  const next = {
@@ -295,6 +295,9 @@ export function buildProviderAdminPluginWithApi(opts) {
295
295
  export function buildProviderAdminPlugin(opts, sharedEngine) {
296
296
  const engine = sharedEngine ?? createProviderAdminEngine(opts);
297
297
  const { providerRegistry, configPath } = engine;
298
+ // Stored vendors persist in the unified user config (or the injected
299
+ // override path in tests) — the fs surface of every tool below.
300
+ const configGlob = configPath ?? '~/.moxxy/config.yaml';
298
301
  return definePlugin({
299
302
  name: '@moxxy/plugin-provider-admin',
300
303
  version: '0.0.0',
@@ -303,11 +306,22 @@ export function buildProviderAdminPlugin(opts, sharedEngine) {
303
306
  name: 'provider_add',
304
307
  description: 'Register an OpenAI-compatible LLM provider (z.ai, deepseek, groq, openrouter, fireworks, ' +
305
308
  'together, mistral, …) with moxxy. Wraps the in-process OpenAI client with the vendor baseURL + ' +
306
- 'a user-supplied models list. Persists to ~/.moxxy/providers.json so the provider survives ' +
309
+ 'a user-supplied models list. Persists to the unified config (plugins.provider.items) so the provider survives ' +
307
310
  'restarts. The new provider is registered in the LIVE session — switch to it with /provider ' +
308
311
  'or set it as the default in moxxy.config.ts.',
309
312
  inputSchema: addProviderInput,
310
313
  permission: { action: 'prompt' },
314
+ // The handler performs NO network I/O itself (register + persist
315
+ // only), but the input carries the vendor `baseURL` — an arbitrary,
316
+ // caller-chosen endpoint the cap checker validates against `net` —
317
+ // so 'any' reflects the genuinely dynamic vendor host.
318
+ isolation: {
319
+ capabilities: {
320
+ fs: { read: [configGlob], write: [configGlob] },
321
+ net: { mode: 'any' },
322
+ timeMs: 30_000,
323
+ },
324
+ },
311
325
  handler: async (input) => {
312
326
  if (engine.isBuiltin(input.name)) {
313
327
  throw new MoxxyError({
@@ -354,9 +368,16 @@ export function buildProviderAdminPlugin(opts, sharedEngine) {
354
368
  }),
355
369
  defineTool({
356
370
  name: 'provider_list',
357
- description: 'List user-registered providers (persisted in ~/.moxxy/providers.json) plus their default model and base URL. ' +
371
+ description: 'List user-registered providers (persisted in the unified config (plugins.provider.items)) plus their default model and base URL. ' +
358
372
  'Built-in providers (anthropic, openai, openai-codex) are NOT included — query session.providers for those.',
359
373
  inputSchema: z.object({}),
374
+ isolation: {
375
+ capabilities: {
376
+ fs: { read: [configGlob] },
377
+ net: { mode: 'none' },
378
+ timeMs: 10_000,
379
+ },
380
+ },
360
381
  handler: async () => {
361
382
  const cfg = await readProvidersConfig(configPath);
362
383
  return {
@@ -374,10 +395,17 @@ export function buildProviderAdminPlugin(opts, sharedEngine) {
374
395
  }),
375
396
  defineTool({
376
397
  name: 'provider_remove',
377
- description: 'Remove a previously-added provider from ~/.moxxy/providers.json and detach it from the live session. ' +
398
+ description: 'Remove a previously-added provider from the unified config (plugins.provider.items) and detach it from the live session. ' +
378
399
  'Does NOT delete the stored API key — call vault_delete name=<NAME>_API_KEY separately if you also want to drop the credential.',
379
400
  inputSchema: removeProviderInput,
380
401
  permission: { action: 'prompt' },
402
+ isolation: {
403
+ capabilities: {
404
+ fs: { read: [configGlob], write: [configGlob] },
405
+ net: { mode: 'none' },
406
+ timeMs: 30_000,
407
+ },
408
+ },
381
409
  handler: async ({ name }) => {
382
410
  // Removing the ACTIVE provider leaves the registry with active=null, so
383
411
  // the next turn fails with a "no active provider" error. Mirror the
@@ -397,10 +425,10 @@ export function buildProviderAdminPlugin(opts, sharedEngine) {
397
425
  }
398
426
  engine.ownNames.delete(name);
399
427
  const note = removingActive
400
- ? `Removed "${name}" from providers.json and detached from session. ` +
428
+ ? `Removed "${name}" from the stored providers and detached from session. ` +
401
429
  `WARNING: "${name}" was the ACTIVE provider — the session now has NO active provider ` +
402
430
  `and the next turn will fail until you switch with the /provider command.`
403
- : `Removed "${name}" from providers.json and detached from session.`;
431
+ : `Removed "${name}" from the stored providers and detached from session.`;
404
432
  return { ok: true, name, removedActive: removingActive, note };
405
433
  });
406
434
  },
@@ -415,6 +443,15 @@ export function buildProviderAdminPlugin(opts, sharedEngine) {
415
443
  '{ ok: false, message } with the vendor error verbatim.',
416
444
  inputSchema: testProviderInput,
417
445
  permission: { action: 'prompt' },
446
+ // Probes a caller-supplied endpoint (`baseURL`/v1/models) — the host
447
+ // is genuinely dynamic. The key comes via the brokered ctx.getSecret,
448
+ // not from fs or env.
449
+ isolation: {
450
+ capabilities: {
451
+ net: { mode: 'any' },
452
+ timeMs: 60_000,
453
+ },
454
+ },
418
455
  // The plaintext key is resolved HERE, at call time, via ctx.getSecret —
419
456
  // it never appears as tool input/output, so it stays out of the model
420
457
  // context, the runner session log, and the desktop NDJSON log.
@@ -448,7 +485,7 @@ export function buildProviderAdminPlugin(opts, sharedEngine) {
448
485
  cfg = await readProvidersConfig(configPath);
449
486
  }
450
487
  catch (err) {
451
- log?.warn('provider-admin: failed to read providers.json', {
488
+ log?.warn('provider-admin: failed to read stored providers', {
452
489
  err: err instanceof Error ? err.message : String(err),
453
490
  });
454
491
  return;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/store.d.ts CHANGED
@@ -1,12 +1,7 @@
1
1
  import type { StoredProvider, StoredProvidersConfig } from './types.js';
2
- /**
3
- * User-level provider catalog. Mirrors the MCP admin storage pattern:
4
- * a JSON file in ~/.moxxy/ that the admin tools mutate and the plugin's
5
- * onInit hook reads back on every boot to repopulate the registry.
6
- */
2
+ /** The file stored vendors persist into — now the unified user config. */
7
3
  export declare function providersConfigPath(): string;
8
- export declare function readProvidersConfig(filePath?: string): Promise<StoredProvidersConfig>;
9
- export declare function writeProvidersConfig(cfg: StoredProvidersConfig, filePath?: string): Promise<void>;
10
- export declare function upsertStoredProvider(entry: StoredProvider, filePath?: string): Promise<StoredProvidersConfig>;
11
- export declare function removeStoredProvider(name: string, filePath?: string): Promise<boolean>;
4
+ export declare function readProvidersConfig(configPath?: string): Promise<StoredProvidersConfig>;
5
+ export declare function upsertStoredProvider(entry: StoredProvider, configPath?: string): Promise<StoredProvidersConfig>;
6
+ export declare function removeStoredProvider(name: string, configPath?: string): Promise<boolean>;
12
7
  //# sourceMappingURL=store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExE;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAqCD,wBAAsB,mBAAmB,CAAC,QAAQ,GAAE,MAA8B,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAwBlH;AAUD,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,qBAAqB,EAC1B,QAAQ,GAAE,MAA8B,GACvC,OAAO,CAAC,IAAI,CAAC,CAEf;AASD,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,cAAc,EACrB,QAAQ,GAAE,MAA8B,GACvC,OAAO,CAAC,qBAAqB,CAAC,CAShC;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAA8B,GACvC,OAAO,CAAC,OAAO,CAAC,CAQlB"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAuDxE,0EAA0E;AAC1E,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAsB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAQ7F;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,cAAc,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,qBAAqB,CAAC,CAOhC;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ9F"}
package/dist/store.js CHANGED
@@ -1,108 +1,85 @@
1
- import { promises as fs } from 'node:fs';
2
- import { createMutex, z } from '@moxxy/sdk';
3
- import { moxxyPath, writeFileAtomic } from '@moxxy/sdk/server';
1
+ import { defaultUserConfigPath, loadProviderItems, removeProviderItem, setProviderItemConfig, } from '@moxxy/config';
2
+ import { z } from '@moxxy/sdk';
4
3
  /**
5
- * User-level provider catalog. Mirrors the MCP admin storage pattern:
6
- * a JSON file in ~/.moxxy/ that the admin tools mutate and the plugin's
7
- * onInit hook reads back on every boot to repopulate the registry.
8
- */
9
- export function providersConfigPath() {
10
- return moxxyPath('providers.json');
11
- }
12
- /**
13
- * Schema for the on-disk providers.json. Kept loose on the model
14
- * descriptor (passthrough) so a richer descriptor written by a newer
15
- * build round-trips through an older one without losing fields, but
16
- * strict enough to discard a structurally-bogus file.
4
+ * Runtime-registered (OpenAI-compatible) vendors now live in the unified
5
+ * `plugins:` tree at `plugins.provider.items.<name>` in the USER config
6
+ * `config` carries the vendor payload (`kind: 'openai-compat'`, baseURL,
7
+ * models, envVar, createdAt), `model` the default model. This REPLACED the
8
+ * legacy `~/.moxxy/providers.json` side-store (clean-slate, no migration:
9
+ * re-add custom vendors via `provider_add` / the desktop sheet). The
10
+ * exported API is unchanged, so the admin tools, the runner's
11
+ * `provider.configure`, and the desktop settings sheet all moved with it.
17
12
  */
18
13
  const storedModelSchema = z
19
14
  .object({
20
15
  id: z.string().min(1),
21
16
  contextWindow: z.number(),
22
- // ModelDescriptor declares these as REQUIRED booleans; default them here so
23
- // a hand-edited / legacy providers.json round-trips into a complete
24
- // descriptor instead of reaching buildProviderDef with `undefined` (which
25
- // channels treat differently from `false` for tool/streaming gating).
17
+ // ModelDescriptor declares these as REQUIRED booleans; default them so a
18
+ // hand-edited entry round-trips into a complete descriptor instead of
19
+ // reaching buildProviderDef with `undefined`.
26
20
  supportsTools: z.boolean().default(true),
27
21
  supportsStreaming: z.boolean().default(true),
28
22
  })
29
23
  .passthrough();
30
- const storedProviderSchema = z
24
+ /** The `config` payload persisted under `plugins.provider.items.<name>.config`. */
25
+ const storedItemConfigSchema = z
31
26
  .object({
32
27
  kind: z.literal('openai-compat'),
33
- name: z.string().min(1),
34
28
  baseURL: z.string().min(1),
35
- defaultModel: z.string().min(1),
36
29
  models: z.array(storedModelSchema),
37
30
  envVar: z.string().optional(),
38
31
  createdAt: z.string().optional(),
39
32
  })
40
33
  .passthrough();
41
- const storedProvidersConfigSchema = z.object({
42
- providers: z.array(storedProviderSchema),
43
- });
44
- export async function readProvidersConfig(filePath = providersConfigPath()) {
45
- let raw;
46
- try {
47
- raw = await fs.readFile(filePath, 'utf8');
48
- }
49
- catch (err) {
50
- // A MISSING file means "no providers yet" — start fresh. But a genuine IO /
51
- // permission error (EACCES, EBUSY, EMFILE, …) must NOT be collapsed into an
52
- // empty catalog: doing so makes the plugin behave as if zero providers are
53
- // registered and the next read-modify-write would CLOBBER the real file.
54
- // Rethrow so callers (onInit's try/catch, the admin tools) see the failure.
55
- if (err?.code === 'ENOENT')
56
- return { providers: [] };
57
- throw err;
58
- }
59
- // Malformed JSON / structurally-bogus content is intentionally treated as an
60
- // empty catalog (start fresh) rather than a hard failure.
61
- const parsed = storedProvidersConfigSchema.safeParse(parseJsonSafe(raw));
62
- if (parsed.success) {
63
- // The schema is intentionally looser than StoredProvidersConfig (model
64
- // descriptors are validated as id+contextWindow + passthrough, not the
65
- // full ModelDescriptor) so newer/older builds round-trip without losing
66
- // fields. Assert the domain type after the structural check.
67
- return parsed.data;
68
- }
69
- return { providers: [] };
34
+ function itemToStored(name, item) {
35
+ const parsed = storedItemConfigSchema.safeParse(item.config ?? {});
36
+ if (!parsed.success)
37
+ return null;
38
+ const { kind, baseURL, models, envVar, createdAt, ...rest } = parsed.data;
39
+ const defaultModel = item.model ?? (typeof models[0]?.id === 'string' ? models[0].id : undefined);
40
+ if (!defaultModel)
41
+ return null;
42
+ return {
43
+ ...rest,
44
+ kind,
45
+ name,
46
+ baseURL,
47
+ defaultModel,
48
+ models,
49
+ ...(envVar ? { envVar } : {}),
50
+ ...(createdAt ? { createdAt } : {}),
51
+ };
70
52
  }
71
- function parseJsonSafe(raw) {
72
- try {
73
- return JSON.parse(raw);
74
- }
75
- catch {
76
- return undefined;
77
- }
53
+ /** The file stored vendors persist into — now the unified user config. */
54
+ export function providersConfigPath() {
55
+ return defaultUserConfigPath();
78
56
  }
79
- export async function writeProvidersConfig(cfg, filePath = providersConfigPath()) {
80
- await writeFileAtomic(filePath, JSON.stringify(cfg, null, 2) + '\n');
57
+ export async function readProvidersConfig(configPath) {
58
+ const items = await loadProviderItems(configPath ? { configPath } : {});
59
+ const providers = [];
60
+ for (const [name, item] of Object.entries(items)) {
61
+ const stored = itemToStored(name, item);
62
+ if (stored)
63
+ providers.push(stored);
64
+ }
65
+ return { providers };
81
66
  }
82
- /**
83
- * Serializes the read-modify-write mutators below. Without this, two
84
- * concurrent upsert/remove calls could both read the same baseline and
85
- * the second write would clobber the first.
86
- */
87
- const writeMutex = createMutex();
88
- export async function upsertStoredProvider(entry, filePath = providersConfigPath()) {
89
- return writeMutex.run(async () => {
90
- const cfg = await readProvidersConfig(filePath);
91
- const next = cfg.providers.filter((p) => p.name !== entry.name);
92
- next.push(entry);
93
- const updated = { providers: next };
94
- await writeProvidersConfig(updated, filePath);
95
- return updated;
67
+ export async function upsertStoredProvider(entry, configPath) {
68
+ const { name, defaultModel, ...payload } = entry;
69
+ await setProviderItemConfig(name, payload, {
70
+ model: defaultModel,
71
+ ...(configPath ? { configPath } : {}),
96
72
  });
73
+ return readProvidersConfig(configPath);
97
74
  }
98
- export async function removeStoredProvider(name, filePath = providersConfigPath()) {
99
- return writeMutex.run(async () => {
100
- const cfg = await readProvidersConfig(filePath);
101
- const next = cfg.providers.filter((p) => p.name !== name);
102
- if (next.length === cfg.providers.length)
103
- return false;
104
- await writeProvidersConfig({ providers: next }, filePath);
105
- return true;
106
- });
75
+ export async function removeStoredProvider(name, configPath) {
76
+ // Only remove entries that ARE stored vendors — a built-in provider's item
77
+ // (model/enabled prefs) must survive a mistaken provider_remove.
78
+ const opts = configPath ? { configPath } : {};
79
+ const items = await loadProviderItems(opts);
80
+ const item = items[name];
81
+ if (!item || !storedItemConfigSchema.safeParse(item.config ?? {}).success)
82
+ return false;
83
+ return removeProviderItem(name, opts);
107
84
  }
108
85
  //# sourceMappingURL=store.js.map
package/dist/store.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moxxy/plugin-provider-admin",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "Model-callable provider admin: provider_add / provider_list / provider_remove / provider_test. Persists user-registered providers to ~/.moxxy/providers.json and hot-registers them in the live session by wrapping the OpenAI-compatible client with a vendor baseURL.",
5
5
  "keywords": [
6
6
  "moxxy",
@@ -45,15 +45,16 @@
45
45
  "dependencies": {
46
46
  "openai": "^4.80.0",
47
47
  "zod": "^3.24.0",
48
- "@moxxy/plugin-provider-openai": "0.26.0",
49
- "@moxxy/sdk": "0.26.0"
48
+ "@moxxy/config": "0.27.0",
49
+ "@moxxy/sdk": "0.27.0",
50
+ "@moxxy/plugin-provider-openai": "0.27.0"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@types/node": "^22.10.0",
53
54
  "typescript": "^5.7.3",
54
55
  "vitest": "^2.1.8",
55
- "@moxxy/vitest-preset": "0.0.0",
56
- "@moxxy/tsconfig": "0.0.0"
56
+ "@moxxy/tsconfig": "0.0.0",
57
+ "@moxxy/vitest-preset": "0.0.0"
57
58
  },
58
59
  "scripts": {
59
60
  "build": "tsc -p tsconfig.json",
package/src/index.test.ts CHANGED
@@ -56,7 +56,7 @@ let tools: Map<string, ToolDef>;
56
56
 
57
57
  beforeEach(async () => {
58
58
  tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'mox-provider-admin-tools-'));
59
- cfgPath = path.join(tmpDir, 'providers.json');
59
+ cfgPath = path.join(tmpDir, 'config.yaml');
60
60
  registry = new FakeRegistry();
61
61
  const plugin = buildProviderAdminPlugin({ providerRegistry: registry, configPath: cfgPath });
62
62
  tools = new Map((plugin.tools ?? []).map((t) => [t.name, t]));
@@ -83,6 +83,35 @@ const zaiInput = {
83
83
  ],
84
84
  };
85
85
 
86
+
87
+ /** Seed the unified-tree store the way a previous session's provider_add
88
+ * would have written it (plugins.provider.items.<name>.{model,config}). */
89
+ async function seedStoredProviders(
90
+ file: string,
91
+ entries: ReadonlyArray<typeof zaiInput>,
92
+ ): Promise<void> {
93
+ const items = entries
94
+ .map((e) => {
95
+ const models = e.models
96
+ .map(
97
+ (m) =>
98
+ ` - id: ${m.id}\n contextWindow: ${m.contextWindow}\n supportsTools: ${m.supportsTools}\n supportsStreaming: ${m.supportsStreaming}`,
99
+ )
100
+ .join('\n');
101
+ return [
102
+ ` ${e.name}:`,
103
+ ` model: ${e.defaultModel}`,
104
+ ` config:`,
105
+ ` kind: ${e.kind}`,
106
+ ` baseURL: ${e.baseURL}`,
107
+ ` models:`,
108
+ models,
109
+ ].join('\n');
110
+ })
111
+ .join('\n');
112
+ await fs.writeFile(file, `plugins:\n provider:\n items:\n${items}\n`, 'utf8');
113
+ }
114
+
86
115
  describe('provider_add', () => {
87
116
  it('registers in the live registry AND persists to providers.json', async () => {
88
117
  const result = (await call('provider_add', zaiInput)) as { ok: boolean; replaced: boolean };
@@ -160,7 +189,7 @@ describe('provider_add', () => {
160
189
  // def must be restored, not deleted. The read path stays valid; the dir is
161
190
  // made read-only so the atomic temp-file write rejects (rollback branch).
162
191
  const reg = new FakeRegistry();
163
- await fs.writeFile(cfgPath, JSON.stringify({ providers: [{ ...zaiInput, kind: 'openai-compat' }] }), 'utf8');
192
+ await seedStoredProviders(cfgPath, [zaiInput]);
164
193
  const plugin = buildProviderAdminPlugin({ providerRegistry: reg, configPath: cfgPath });
165
194
  await plugin.hooks!.onInit!({} as never);
166
195
  expect(reg.defs.has('zai')).toBe(true);
@@ -188,7 +217,7 @@ describe('provider_add', () => {
188
217
  // Fresh slug (not owned, not in registry) → register + write. Make the dir
189
218
  // read-only so the write fails; the phantom registration must be rolled back.
190
219
  const reg = new FakeRegistry();
191
- await fs.writeFile(cfgPath, JSON.stringify({ providers: [] }), 'utf8');
220
+ await fs.writeFile(cfgPath, 'plugins:\n provider:\n items: {}\n', 'utf8');
192
221
  const plugin = buildProviderAdminPlugin({ providerRegistry: reg, configPath: cfgPath });
193
222
  const addTool = plugin.tools!.find((t) => t.name === 'provider_add')!;
194
223
  await fs.chmod(tmpDir, 0o500);
@@ -334,11 +363,7 @@ describe('onInit logger guard', () => {
334
363
  }
335
364
 
336
365
  beforeEach(async () => {
337
- await fs.writeFile(
338
- cfgPath,
339
- JSON.stringify({ providers: [{ ...zaiInput, kind: 'openai-compat' }] }),
340
- 'utf8',
341
- );
366
+ await seedStoredProviders(cfgPath, [zaiInput]);
342
367
  });
343
368
 
344
369
  it('warns through a conforming host logger', async () => {
@@ -366,11 +391,7 @@ describe('onInit logger guard', () => {
366
391
  describe('onInit', () => {
367
392
  it('re-registers everything stored on disk', async () => {
368
393
  // Pre-seed providers.json the way it would look after a previous session.
369
- await fs.writeFile(
370
- cfgPath,
371
- JSON.stringify({ providers: [{ ...zaiInput, kind: 'openai-compat' }] }),
372
- 'utf8',
373
- );
394
+ await seedStoredProviders(cfgPath, [zaiInput]);
374
395
  // Fresh registry — simulate a brand-new session pointing at the same store.
375
396
  const fresh = new FakeRegistry();
376
397
  const plugin = buildProviderAdminPlugin({ providerRegistry: fresh, configPath: cfgPath });
@@ -381,18 +402,12 @@ describe('onInit', () => {
381
402
  });
382
403
 
383
404
  it('does not clobber a built-in when providers.json contains a colliding entry', async () => {
384
- // A poisoned/legacy store smuggling an 'openai' entry must NOT overwrite the
385
- // built-in OpenAI def on boot — onInit skips reserved names.
386
- await fs.writeFile(
387
- cfgPath,
388
- JSON.stringify({
389
- providers: [
390
- { ...zaiInput, name: 'openai', baseURL: 'https://evil.example.com/v1', kind: 'openai-compat' },
391
- { ...zaiInput, kind: 'openai-compat' },
392
- ],
393
- }),
394
- 'utf8',
395
- );
405
+ // A poisoned/hand-edited store smuggling an 'openai' entry must NOT
406
+ // overwrite the built-in OpenAI def on boot — onInit skips reserved names.
407
+ await seedStoredProviders(cfgPath, [
408
+ { ...zaiInput, name: 'openai', baseURL: 'https://evil.example.com/v1' },
409
+ zaiInput,
410
+ ]);
396
411
  const withBuiltin = new FakeRegistry();
397
412
  const builtinDef = { name: 'openai', models: [{ id: 'gpt-x', contextWindow: 1 }] } as unknown as ProviderDef;
398
413
  withBuiltin.register(builtinDef);
@@ -524,7 +539,7 @@ describe('per-name lock is bounded + serializes concurrent same-slug calls', ()
524
539
  // register() throws "already registered". The per-name lock must turn the
525
540
  // race into add→replace. Run them with Promise.all (overlapping).
526
541
  const reg = new FakeRegistry();
527
- await fs.writeFile(cfgPath, JSON.stringify({ providers: [] }), 'utf8');
542
+ await fs.writeFile(cfgPath, 'plugins:\n provider:\n items: {}\n', 'utf8');
528
543
  const plugin = buildProviderAdminPlugin({ providerRegistry: reg, configPath: cfgPath });
529
544
  const addTool = plugin.tools!.find((t) => t.name === 'provider_add')!;
530
545
  const fire = (defaultModel: string): Promise<unknown> =>
@@ -553,7 +568,7 @@ describe('per-name lock is bounded + serializes concurrent same-slug calls', ()
553
568
  // (a leak would not crash, so this is a smoke that the ref-count finally
554
569
  // always runs — paired with the source-level guarantee).
555
570
  const reg = new FakeRegistry();
556
- await fs.writeFile(cfgPath, JSON.stringify({ providers: [] }), 'utf8');
571
+ await fs.writeFile(cfgPath, 'plugins:\n provider:\n items: {}\n', 'utf8');
557
572
  const plugin = buildProviderAdminPlugin({ providerRegistry: reg, configPath: cfgPath });
558
573
  const addTool = plugin.tools!.find((t) => t.name === 'provider_add')!;
559
574
  const removeTool = plugin.tools!.find((t) => t.name === 'provider_remove')!;
@@ -572,7 +587,7 @@ describe('per-name lock is bounded + serializes concurrent same-slug calls', ()
572
587
 
573
588
  describe('active-provider safety', () => {
574
589
  it('rebuilds the active provider instance after configure when a resolver is wired', async () => {
575
- await fs.writeFile(cfgPath, JSON.stringify({ providers: [{ ...zaiInput, kind: 'openai-compat' }] }), 'utf8');
590
+ await seedStoredProviders(cfgPath, [zaiInput]);
576
591
  const reg = new FakeRegistry();
577
592
  const resolved: string[] = [];
578
593
  const { plugin, api } = buildProviderAdminPluginWithApi({
@@ -600,11 +615,7 @@ describe('active-provider safety', () => {
600
615
  });
601
616
 
602
617
  it('does not rebuild a non-active provider', async () => {
603
- await fs.writeFile(
604
- cfgPath,
605
- JSON.stringify({ providers: [{ ...zaiInput, kind: 'openai-compat' }] }),
606
- 'utf8',
607
- );
618
+ await seedStoredProviders(cfgPath, [zaiInput]);
608
619
  const reg = new FakeRegistry();
609
620
  const resolved: string[] = [];
610
621
  const { plugin, api } = buildProviderAdminPluginWithApi({
@@ -625,7 +636,7 @@ describe('active-provider safety', () => {
625
636
  });
626
637
 
627
638
  it('warns when provider_remove drops the ACTIVE provider', async () => {
628
- await fs.writeFile(cfgPath, JSON.stringify({ providers: [{ ...zaiInput, kind: 'openai-compat' }] }), 'utf8');
639
+ await seedStoredProviders(cfgPath, [zaiInput]);
629
640
  const reg = new FakeRegistry();
630
641
  const plugin = buildProviderAdminPlugin({ providerRegistry: reg, configPath: cfgPath });
631
642
  await plugin.hooks!.onInit!({} as never);
@@ -645,7 +656,7 @@ describe('active-provider safety', () => {
645
656
 
646
657
  describe('configure() patch validation (defense-in-depth)', () => {
647
658
  it('rejects a malformed baseURL even when the runner schema would not run', async () => {
648
- await fs.writeFile(cfgPath, JSON.stringify({ providers: [{ ...zaiInput, kind: 'openai-compat' }] }), 'utf8');
659
+ await seedStoredProviders(cfgPath, [zaiInput]);
649
660
  const reg = new FakeRegistry();
650
661
  const { plugin, api } = buildProviderAdminPluginWithApi({ providerRegistry: reg, configPath: cfgPath });
651
662
  await plugin.hooks!.onInit!({} as never);
package/src/index.ts CHANGED
@@ -365,7 +365,7 @@ export function buildProviderAdminPluginWithApi(opts: BuildProviderAdminPluginOp
365
365
  code: 'CONFIG_INVALID',
366
366
  message:
367
367
  `provider-admin: "${name}" is a built-in provider and cannot be reconfigured here — ` +
368
- `built-ins are code. Only runtime-registered (providers.json) providers are editable.`,
368
+ `built-ins are code. Only runtime-registered (stored) providers are editable.`,
369
369
  });
370
370
  }
371
371
  // Defense-in-depth: validate the patch HERE (where it is persisted), not
@@ -378,7 +378,7 @@ export function buildProviderAdminPluginWithApi(opts: BuildProviderAdminPluginOp
378
378
  code: 'CONFIG_INVALID',
379
379
  message:
380
380
  `provider-admin: no stored provider named "${name}" — only runtime-registered ` +
381
- `(providers.json) providers are configurable; built-ins are code.`,
381
+ `(stored) providers are configurable; built-ins are code.`,
382
382
  });
383
383
  }
384
384
  const next: StoredProvider = {
@@ -410,6 +410,9 @@ export function buildProviderAdminPlugin(
410
410
  ): Plugin {
411
411
  const engine = sharedEngine ?? createProviderAdminEngine(opts);
412
412
  const { providerRegistry, configPath } = engine;
413
+ // Stored vendors persist in the unified user config (or the injected
414
+ // override path in tests) — the fs surface of every tool below.
415
+ const configGlob = configPath ?? '~/.moxxy/config.yaml';
413
416
 
414
417
  return definePlugin({
415
418
  name: '@moxxy/plugin-provider-admin',
@@ -420,11 +423,22 @@ export function buildProviderAdminPlugin(
420
423
  description:
421
424
  'Register an OpenAI-compatible LLM provider (z.ai, deepseek, groq, openrouter, fireworks, ' +
422
425
  'together, mistral, …) with moxxy. Wraps the in-process OpenAI client with the vendor baseURL + ' +
423
- 'a user-supplied models list. Persists to ~/.moxxy/providers.json so the provider survives ' +
426
+ 'a user-supplied models list. Persists to the unified config (plugins.provider.items) so the provider survives ' +
424
427
  'restarts. The new provider is registered in the LIVE session — switch to it with /provider ' +
425
428
  'or set it as the default in moxxy.config.ts.',
426
429
  inputSchema: addProviderInput,
427
430
  permission: { action: 'prompt' },
431
+ // The handler performs NO network I/O itself (register + persist
432
+ // only), but the input carries the vendor `baseURL` — an arbitrary,
433
+ // caller-chosen endpoint the cap checker validates against `net` —
434
+ // so 'any' reflects the genuinely dynamic vendor host.
435
+ isolation: {
436
+ capabilities: {
437
+ fs: { read: [configGlob], write: [configGlob] },
438
+ net: { mode: 'any' },
439
+ timeMs: 30_000,
440
+ },
441
+ },
428
442
  handler: async (input) => {
429
443
  if (engine.isBuiltin(input.name)) {
430
444
  throw new MoxxyError({
@@ -475,9 +489,16 @@ export function buildProviderAdminPlugin(
475
489
  defineTool({
476
490
  name: 'provider_list',
477
491
  description:
478
- 'List user-registered providers (persisted in ~/.moxxy/providers.json) plus their default model and base URL. ' +
492
+ 'List user-registered providers (persisted in the unified config (plugins.provider.items)) plus their default model and base URL. ' +
479
493
  'Built-in providers (anthropic, openai, openai-codex) are NOT included — query session.providers for those.',
480
494
  inputSchema: z.object({}),
495
+ isolation: {
496
+ capabilities: {
497
+ fs: { read: [configGlob] },
498
+ net: { mode: 'none' },
499
+ timeMs: 10_000,
500
+ },
501
+ },
481
502
  handler: async () => {
482
503
  const cfg = await readProvidersConfig(configPath);
483
504
  return {
@@ -496,10 +517,17 @@ export function buildProviderAdminPlugin(
496
517
  defineTool({
497
518
  name: 'provider_remove',
498
519
  description:
499
- 'Remove a previously-added provider from ~/.moxxy/providers.json and detach it from the live session. ' +
520
+ 'Remove a previously-added provider from the unified config (plugins.provider.items) and detach it from the live session. ' +
500
521
  'Does NOT delete the stored API key — call vault_delete name=<NAME>_API_KEY separately if you also want to drop the credential.',
501
522
  inputSchema: removeProviderInput,
502
523
  permission: { action: 'prompt' },
524
+ isolation: {
525
+ capabilities: {
526
+ fs: { read: [configGlob], write: [configGlob] },
527
+ net: { mode: 'none' },
528
+ timeMs: 30_000,
529
+ },
530
+ },
503
531
  handler: async ({ name }) => {
504
532
  // Removing the ACTIVE provider leaves the registry with active=null, so
505
533
  // the next turn fails with a "no active provider" error. Mirror the
@@ -518,10 +546,10 @@ export function buildProviderAdminPlugin(
518
546
  }
519
547
  engine.ownNames.delete(name);
520
548
  const note = removingActive
521
- ? `Removed "${name}" from providers.json and detached from session. ` +
549
+ ? `Removed "${name}" from the stored providers and detached from session. ` +
522
550
  `WARNING: "${name}" was the ACTIVE provider — the session now has NO active provider ` +
523
551
  `and the next turn will fail until you switch with the /provider command.`
524
- : `Removed "${name}" from providers.json and detached from session.`;
552
+ : `Removed "${name}" from the stored providers and detached from session.`;
525
553
  return { ok: true, name, removedActive: removingActive, note };
526
554
  });
527
555
  },
@@ -537,6 +565,15 @@ export function buildProviderAdminPlugin(
537
565
  '{ ok: false, message } with the vendor error verbatim.',
538
566
  inputSchema: testProviderInput,
539
567
  permission: { action: 'prompt' },
568
+ // Probes a caller-supplied endpoint (`baseURL`/v1/models) — the host
569
+ // is genuinely dynamic. The key comes via the brokered ctx.getSecret,
570
+ // not from fs or env.
571
+ isolation: {
572
+ capabilities: {
573
+ net: { mode: 'any' },
574
+ timeMs: 60_000,
575
+ },
576
+ },
540
577
  // The plaintext key is resolved HERE, at call time, via ctx.getSecret —
541
578
  // it never appears as tool input/output, so it stays out of the model
542
579
  // context, the runner session log, and the desktop NDJSON log.
@@ -571,7 +608,7 @@ export function buildProviderAdminPlugin(
571
608
  try {
572
609
  cfg = await readProvidersConfig(configPath);
573
610
  } catch (err) {
574
- log?.warn('provider-admin: failed to read providers.json', {
611
+ log?.warn('provider-admin: failed to read stored providers', {
575
612
  err: err instanceof Error ? err.message : String(err),
576
613
  });
577
614
  return;
package/src/store.test.ts CHANGED
@@ -6,7 +6,6 @@ import {
6
6
  readProvidersConfig,
7
7
  removeStoredProvider,
8
8
  upsertStoredProvider,
9
- writeProvidersConfig,
10
9
  } from './store.js';
11
10
  import type { StoredProvider } from './types.js';
12
11
 
@@ -23,24 +22,35 @@ let cfgPath: string;
23
22
 
24
23
  beforeEach(async () => {
25
24
  tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'mox-provider-admin-'));
26
- cfgPath = path.join(tmpDir, 'providers.json');
25
+ // Stored vendors now live in the unified user config (plugins.provider.items).
26
+ cfgPath = path.join(tmpDir, 'config.yaml');
27
27
  });
28
28
 
29
29
  afterEach(async () => {
30
30
  await fs.rm(tmpDir, { recursive: true, force: true });
31
31
  });
32
32
 
33
- describe('providers.json store', () => {
33
+ describe('stored-provider tree store (plugins.provider.items)', () => {
34
34
  it('returns an empty list when the file is missing', async () => {
35
35
  const cfg = await readProvidersConfig(cfgPath);
36
36
  expect(cfg.providers).toEqual([]);
37
37
  });
38
38
 
39
- it('round-trips a single provider through write/read', async () => {
40
- await writeProvidersConfig({ providers: [sampleEntry] }, cfgPath);
39
+ it('round-trips a single provider through upsert/read', async () => {
40
+ await upsertStoredProvider(sampleEntry, cfgPath);
41
41
  const cfg = await readProvidersConfig(cfgPath);
42
42
  expect(cfg.providers).toHaveLength(1);
43
- expect(cfg.providers[0]).toMatchObject({ name: 'zai', defaultModel: 'glm-4.6' });
43
+ expect(cfg.providers[0]).toMatchObject({
44
+ name: 'zai',
45
+ defaultModel: 'glm-4.6',
46
+ kind: 'openai-compat',
47
+ baseURL: sampleEntry.baseURL,
48
+ });
49
+ // The persisted YAML shape is the unified tree, not a side-store.
50
+ const text = await fs.readFile(cfgPath, 'utf8');
51
+ expect(text).toContain('provider:');
52
+ expect(text).toContain('zai:');
53
+ expect(text).toContain('kind: openai-compat');
44
54
  });
45
55
 
46
56
  it('upsert replaces an entry with the same name (no duplicates)', async () => {
@@ -70,39 +80,56 @@ describe('providers.json store', () => {
70
80
  expect(cfg.providers).toEqual([]);
71
81
  });
72
82
 
73
- it('treats malformed JSON as empty', async () => {
74
- await fs.writeFile(cfgPath, '{ not json', 'utf8');
83
+ it("remove refuses to touch a built-in provider's item (model/enabled prefs)", async () => {
84
+ // `plugins.provider.items.anthropic.model` written by the /model picker is
85
+ // NOT a stored vendor; provider_remove must never delete those prefs.
86
+ await fs.writeFile(
87
+ cfgPath,
88
+ 'plugins:\n provider:\n items:\n anthropic:\n model: claude-opus-4-8\n',
89
+ );
90
+ expect(await removeStoredProvider('anthropic', cfgPath)).toBe(false);
91
+ const text = await fs.readFile(cfgPath, 'utf8');
92
+ expect(text).toContain('claude-opus-4-8');
93
+ });
94
+
95
+ it('coexists with picker-written model/enabled prefs on OTHER items', async () => {
96
+ await fs.writeFile(
97
+ cfgPath,
98
+ 'plugins:\n provider:\n default: anthropic\n items:\n anthropic:\n model: claude-opus-4-8\n',
99
+ );
100
+ await upsertStoredProvider(sampleEntry, cfgPath);
75
101
  const cfg = await readProvidersConfig(cfgPath);
76
- expect(cfg.providers).toEqual([]);
102
+ // Only the vendor entry surfaces as a stored provider…
103
+ expect(cfg.providers.map((p) => p.name)).toEqual(['zai']);
104
+ // …and the built-in's prefs survive untouched.
105
+ const text = await fs.readFile(cfgPath, 'utf8');
106
+ expect(text).toContain('claude-opus-4-8');
107
+ expect(text).toContain('default: anthropic');
77
108
  });
78
109
 
79
- it('rethrows a genuine IO error instead of collapsing it to an empty catalog', async () => {
80
- // A read failure that is NOT "file missing" (here: the path resolves to a
81
- // DIRECTORY EISDIR) must surface as a real error, not silently become an
82
- // empty catalog the next write would then CLOBBER.
83
- const dirAsFile = path.join(tmpDir, 'a-directory');
84
- await fs.mkdir(dirAsFile);
85
- await expect(readProvidersConfig(dirAsFile)).rejects.toBeTruthy();
110
+ it('treats a malformed YAML file as empty on read', async () => {
111
+ await fs.writeFile(cfgPath, '{{{ not yaml', 'utf8');
112
+ const cfg = await readProvidersConfig(cfgPath);
113
+ expect(cfg.providers).toEqual([]);
86
114
  });
87
115
 
88
- it('defaults supportsTools/supportsStreaming on a legacy on-disk model', async () => {
89
- // A hand-edited / legacy entry with only {id, contextWindow} must round-trip
90
- // into a complete ModelDescriptor (required booleans defaulted true), not
91
- // reach buildProviderDef with `undefined` flags.
116
+ it('defaults supportsTools/supportsStreaming on a legacy hand-edited model', async () => {
92
117
  await fs.writeFile(
93
118
  cfgPath,
94
- JSON.stringify({
95
- providers: [
96
- {
97
- kind: 'openai-compat',
98
- name: 'legacy',
99
- baseURL: 'https://api.legacy.com/v1',
100
- defaultModel: 'm',
101
- models: [{ id: 'm', contextWindow: 1000 }],
102
- },
103
- ],
104
- }),
105
- 'utf8',
119
+ [
120
+ 'plugins:',
121
+ ' provider:',
122
+ ' items:',
123
+ ' legacy:',
124
+ ' model: m',
125
+ ' config:',
126
+ ' kind: openai-compat',
127
+ ' baseURL: https://api.legacy.com/v1',
128
+ ' models:',
129
+ ' - id: m',
130
+ ' contextWindow: 1000',
131
+ '',
132
+ ].join('\n'),
106
133
  );
107
134
  const cfg = await readProvidersConfig(cfgPath);
108
135
  expect(cfg.providers[0]!.models[0]).toMatchObject({
package/src/store.ts CHANGED
@@ -1,123 +1,99 @@
1
- import { promises as fs } from 'node:fs';
2
- import { createMutex, z } from '@moxxy/sdk';
3
- import { moxxyPath, writeFileAtomic } from '@moxxy/sdk/server';
1
+ import {
2
+ defaultUserConfigPath,
3
+ loadProviderItems,
4
+ removeProviderItem,
5
+ setProviderItemConfig,
6
+ type ProviderItemState,
7
+ } from '@moxxy/config';
8
+ import { z } from '@moxxy/sdk';
4
9
  import type { StoredProvider, StoredProvidersConfig } from './types.js';
5
10
 
6
11
  /**
7
- * User-level provider catalog. Mirrors the MCP admin storage pattern:
8
- * a JSON file in ~/.moxxy/ that the admin tools mutate and the plugin's
9
- * onInit hook reads back on every boot to repopulate the registry.
12
+ * Runtime-registered (OpenAI-compatible) vendors now live in the unified
13
+ * `plugins:` tree at `plugins.provider.items.<name>` in the USER config
14
+ * `config` carries the vendor payload (`kind: 'openai-compat'`, baseURL,
15
+ * models, envVar, createdAt), `model` the default model. This REPLACED the
16
+ * legacy `~/.moxxy/providers.json` side-store (clean-slate, no migration:
17
+ * re-add custom vendors via `provider_add` / the desktop sheet). The
18
+ * exported API is unchanged, so the admin tools, the runner's
19
+ * `provider.configure`, and the desktop settings sheet all moved with it.
10
20
  */
11
- export function providersConfigPath(): string {
12
- return moxxyPath('providers.json');
13
- }
14
21
 
15
- /**
16
- * Schema for the on-disk providers.json. Kept loose on the model
17
- * descriptor (passthrough) so a richer descriptor written by a newer
18
- * build round-trips through an older one without losing fields, but
19
- * strict enough to discard a structurally-bogus file.
20
- */
21
22
  const storedModelSchema = z
22
23
  .object({
23
24
  id: z.string().min(1),
24
25
  contextWindow: z.number(),
25
- // ModelDescriptor declares these as REQUIRED booleans; default them here so
26
- // a hand-edited / legacy providers.json round-trips into a complete
27
- // descriptor instead of reaching buildProviderDef with `undefined` (which
28
- // channels treat differently from `false` for tool/streaming gating).
26
+ // ModelDescriptor declares these as REQUIRED booleans; default them so a
27
+ // hand-edited entry round-trips into a complete descriptor instead of
28
+ // reaching buildProviderDef with `undefined`.
29
29
  supportsTools: z.boolean().default(true),
30
30
  supportsStreaming: z.boolean().default(true),
31
31
  })
32
32
  .passthrough();
33
33
 
34
- const storedProviderSchema = z
34
+ /** The `config` payload persisted under `plugins.provider.items.<name>.config`. */
35
+ const storedItemConfigSchema = z
35
36
  .object({
36
37
  kind: z.literal('openai-compat'),
37
- name: z.string().min(1),
38
38
  baseURL: z.string().min(1),
39
- defaultModel: z.string().min(1),
40
39
  models: z.array(storedModelSchema),
41
40
  envVar: z.string().optional(),
42
41
  createdAt: z.string().optional(),
43
42
  })
44
43
  .passthrough();
45
44
 
46
- const storedProvidersConfigSchema = z.object({
47
- providers: z.array(storedProviderSchema),
48
- });
49
-
50
- export async function readProvidersConfig(filePath: string = providersConfigPath()): Promise<StoredProvidersConfig> {
51
- let raw: string;
52
- try {
53
- raw = await fs.readFile(filePath, 'utf8');
54
- } catch (err) {
55
- // A MISSING file means "no providers yet" — start fresh. But a genuine IO /
56
- // permission error (EACCES, EBUSY, EMFILE, …) must NOT be collapsed into an
57
- // empty catalog: doing so makes the plugin behave as if zero providers are
58
- // registered and the next read-modify-write would CLOBBER the real file.
59
- // Rethrow so callers (onInit's try/catch, the admin tools) see the failure.
60
- if ((err as NodeJS.ErrnoException)?.code === 'ENOENT') return { providers: [] };
61
- throw err;
62
- }
63
- // Malformed JSON / structurally-bogus content is intentionally treated as an
64
- // empty catalog (start fresh) rather than a hard failure.
65
- const parsed = storedProvidersConfigSchema.safeParse(parseJsonSafe(raw));
66
- if (parsed.success) {
67
- // The schema is intentionally looser than StoredProvidersConfig (model
68
- // descriptors are validated as id+contextWindow + passthrough, not the
69
- // full ModelDescriptor) so newer/older builds round-trip without losing
70
- // fields. Assert the domain type after the structural check.
71
- return parsed.data as unknown as StoredProvidersConfig;
72
- }
73
- return { providers: [] };
45
+ function itemToStored(name: string, item: ProviderItemState): StoredProvider | null {
46
+ const parsed = storedItemConfigSchema.safeParse(item.config ?? {});
47
+ if (!parsed.success) return null;
48
+ const { kind, baseURL, models, envVar, createdAt, ...rest } = parsed.data;
49
+ const defaultModel =
50
+ item.model ?? (typeof models[0]?.id === 'string' ? models[0].id : undefined);
51
+ if (!defaultModel) return null;
52
+ return {
53
+ ...rest,
54
+ kind,
55
+ name,
56
+ baseURL,
57
+ defaultModel,
58
+ models,
59
+ ...(envVar ? { envVar } : {}),
60
+ ...(createdAt ? { createdAt } : {}),
61
+ } as unknown as StoredProvider;
74
62
  }
75
63
 
76
- function parseJsonSafe(raw: string): unknown {
77
- try {
78
- return JSON.parse(raw) as unknown;
79
- } catch {
80
- return undefined;
81
- }
64
+ /** The file stored vendors persist into — now the unified user config. */
65
+ export function providersConfigPath(): string {
66
+ return defaultUserConfigPath();
82
67
  }
83
68
 
84
- export async function writeProvidersConfig(
85
- cfg: StoredProvidersConfig,
86
- filePath: string = providersConfigPath(),
87
- ): Promise<void> {
88
- await writeFileAtomic(filePath, JSON.stringify(cfg, null, 2) + '\n');
69
+ export async function readProvidersConfig(configPath?: string): Promise<StoredProvidersConfig> {
70
+ const items = await loadProviderItems(configPath ? { configPath } : {});
71
+ const providers: StoredProvider[] = [];
72
+ for (const [name, item] of Object.entries(items)) {
73
+ const stored = itemToStored(name, item);
74
+ if (stored) providers.push(stored);
75
+ }
76
+ return { providers };
89
77
  }
90
78
 
91
- /**
92
- * Serializes the read-modify-write mutators below. Without this, two
93
- * concurrent upsert/remove calls could both read the same baseline and
94
- * the second write would clobber the first.
95
- */
96
- const writeMutex = createMutex();
97
-
98
79
  export async function upsertStoredProvider(
99
80
  entry: StoredProvider,
100
- filePath: string = providersConfigPath(),
81
+ configPath?: string,
101
82
  ): Promise<StoredProvidersConfig> {
102
- return writeMutex.run(async () => {
103
- const cfg = await readProvidersConfig(filePath);
104
- const next = cfg.providers.filter((p) => p.name !== entry.name);
105
- next.push(entry);
106
- const updated: StoredProvidersConfig = { providers: next };
107
- await writeProvidersConfig(updated, filePath);
108
- return updated;
83
+ const { name, defaultModel, ...payload } = entry;
84
+ await setProviderItemConfig(name, payload as Record<string, unknown>, {
85
+ model: defaultModel,
86
+ ...(configPath ? { configPath } : {}),
109
87
  });
88
+ return readProvidersConfig(configPath);
110
89
  }
111
90
 
112
- export async function removeStoredProvider(
113
- name: string,
114
- filePath: string = providersConfigPath(),
115
- ): Promise<boolean> {
116
- return writeMutex.run(async () => {
117
- const cfg = await readProvidersConfig(filePath);
118
- const next = cfg.providers.filter((p) => p.name !== name);
119
- if (next.length === cfg.providers.length) return false;
120
- await writeProvidersConfig({ providers: next }, filePath);
121
- return true;
122
- });
91
+ export async function removeStoredProvider(name: string, configPath?: string): Promise<boolean> {
92
+ // Only remove entries that ARE stored vendors — a built-in provider's item
93
+ // (model/enabled prefs) must survive a mistaken provider_remove.
94
+ const opts = configPath ? { configPath } : {};
95
+ const items = await loadProviderItems(opts);
96
+ const item = items[name];
97
+ if (!item || !storedItemConfigSchema.safeParse(item.config ?? {}).success) return false;
98
+ return removeProviderItem(name, opts);
123
99
  }