@moxxy/config 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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/dist/config-writer.d.ts +30 -0
  3. package/dist/config-writer.d.ts.map +1 -0
  4. package/dist/config-writer.js +57 -0
  5. package/dist/config-writer.js.map +1 -0
  6. package/dist/define.d.ts +17 -0
  7. package/dist/define.d.ts.map +1 -0
  8. package/dist/define.js +18 -0
  9. package/dist/define.js.map +1 -0
  10. package/dist/index.d.ts +9 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +11 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/loader.d.ts +28 -0
  15. package/dist/loader.d.ts.map +1 -0
  16. package/dist/loader.js +210 -0
  17. package/dist/loader.js.map +1 -0
  18. package/dist/merge.d.ts +9 -0
  19. package/dist/merge.d.ts.map +1 -0
  20. package/dist/merge.js +45 -0
  21. package/dist/merge.js.map +1 -0
  22. package/dist/plugin-settings-schema.d.ts +24 -0
  23. package/dist/plugin-settings-schema.d.ts.map +1 -0
  24. package/dist/plugin-settings-schema.js +17 -0
  25. package/dist/plugin-settings-schema.js.map +1 -0
  26. package/dist/plugin.d.ts +21 -0
  27. package/dist/plugin.d.ts.map +1 -0
  28. package/dist/plugin.js +329 -0
  29. package/dist/plugin.js.map +1 -0
  30. package/dist/plugins-tree-schema.d.ts +444 -0
  31. package/dist/plugins-tree-schema.d.ts.map +1 -0
  32. package/dist/plugins-tree-schema.js +93 -0
  33. package/dist/plugins-tree-schema.js.map +1 -0
  34. package/dist/schema.d.ts +1200 -0
  35. package/dist/schema.d.ts.map +1 -0
  36. package/dist/schema.js +198 -0
  37. package/dist/schema.js.map +1 -0
  38. package/dist/user-config.d.ts +77 -0
  39. package/dist/user-config.d.ts.map +1 -0
  40. package/dist/user-config.js +265 -0
  41. package/dist/user-config.js.map +1 -0
  42. package/package.json +56 -0
  43. package/src/config-writer.test.ts +52 -0
  44. package/src/config-writer.ts +88 -0
  45. package/src/define.ts +19 -0
  46. package/src/index.ts +64 -0
  47. package/src/loader.test.ts +122 -0
  48. package/src/loader.ts +232 -0
  49. package/src/loader.yaml.test.ts +149 -0
  50. package/src/merge.test.ts +78 -0
  51. package/src/merge.ts +44 -0
  52. package/src/plugin-settings-schema.ts +18 -0
  53. package/src/plugin.test.ts +310 -0
  54. package/src/plugin.ts +360 -0
  55. package/src/plugins-tree-schema.test.ts +25 -0
  56. package/src/plugins-tree-schema.ts +103 -0
  57. package/src/schema.ts +218 -0
  58. package/src/security-config.test.ts +30 -0
  59. package/src/user-config.test.ts +113 -0
  60. package/src/user-config.ts +359 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js ADDED
@@ -0,0 +1,198 @@
1
+ import { z } from 'zod';
2
+ import { pluginSettingsSchema } from './plugin-settings-schema.js';
3
+ import { pluginsTreeSchema } from './plugins-tree-schema.js';
4
+ export const watcherModeSchema = z.enum(['auto', 'manual', 'off']);
5
+ export const permissionsConfigSchema = z.object({
6
+ policyPath: z.string().optional(),
7
+ allow: z
8
+ .array(z.object({
9
+ name: z.string(),
10
+ inputMatches: z.record(z.string(), z.string()).optional(),
11
+ reason: z.string().optional(),
12
+ }))
13
+ .optional(),
14
+ deny: z
15
+ .array(z.object({
16
+ name: z.string(),
17
+ inputMatches: z.record(z.string(), z.string()).optional(),
18
+ reason: z.string().optional(),
19
+ }))
20
+ .optional(),
21
+ });
22
+ export const securityConfigSchema = z.object({
23
+ /**
24
+ * Master toggle. When omitted or false (the default), `@moxxy/plugin-security`
25
+ * is a no-op even if registered — every tool runs exactly as it does
26
+ * without the plugin. Per-tool `isolation: { ... }` declarations
27
+ * remain as documentation but are not enforced. Optional so a partial
28
+ * `security:` block (e.g. only `isolator`) validates and config_set can
29
+ * write one field at a time; consumers default it to false.
30
+ */
31
+ enabled: z.boolean().optional(),
32
+ // The default isolator now lives in the unified tree at
33
+ // `plugins.isolator.default` (a registry kind like any other); it is no
34
+ // longer a bespoke `security.isolator` key.
35
+ /**
36
+ * Per-tool isolator overrides keyed by tool name. e.g.
37
+ * `{ bash: 'subprocess', memory_save: 'none' }`. Falls back to the
38
+ * default isolator above when a tool isn't listed.
39
+ */
40
+ perTool: z.record(z.string(), z.string()).optional(),
41
+ /**
42
+ * Per-plugin isolator overrides keyed by plugin name. Applies to
43
+ * every tool the plugin contributes unless overridden in `perTool`.
44
+ */
45
+ perPlugin: z.record(z.string(), z.string()).optional(),
46
+ /**
47
+ * When true, tools without a declared `isolation` field are denied
48
+ * outright (instead of falling through to the default isolator).
49
+ * Useful for hardening once every in-use tool has been audited.
50
+ */
51
+ requireDeclaration: z.boolean().optional(),
52
+ /**
53
+ * The requireDeclaration ratchet for THIRD-PARTY plugins only — packages
54
+ * outside the trusted `@moxxy/` scope. Applies when a tool has no
55
+ * `isolation` declaration and the global `requireDeclaration` above did
56
+ * not already deny it:
57
+ * - 'off' — third-party tools are treated like first-party ones.
58
+ * - 'warn' — grace mode (the default while `security.enabled`): the
59
+ * call runs, but a structured warning is logged once per
60
+ * tool per process.
61
+ * - 'enforce' — the call is denied with a reason naming this flag.
62
+ * Tools with no resolvable owning plugin (e.g. runtime-attached MCP
63
+ * tools) are exempt — the npm-scope test is meaningless for them.
64
+ * Consumed by `@moxxy/plugin-security`
65
+ * (`SecurityPluginConfig.thirdPartyRequireDeclaration`).
66
+ */
67
+ thirdPartyRequireDeclaration: z.enum(['off', 'warn', 'enforce']).optional(),
68
+ /**
69
+ * Tighten the in-process input cap-check from best-effort to fail-closed.
70
+ * By default the fs/net checks only inspect string values under a recognized
71
+ * key name (`file`, `path`, `url`, …), so a path/URL carried by an
72
+ * unrecognized field (`config`, `manifest`, `webhook`) is not checked. With
73
+ * `strict: true`, any string value that is unambiguously an absolute path or a
74
+ * bare http(s) URL is treated as in-scope-required regardless of key name, so
75
+ * an unrecognized carrier fails closed. Consumed by `@moxxy/plugin-security`
76
+ * (`SecurityPluginConfig.strict`); without this field the loader's schema would
77
+ * silently strip a user's `security.strict: true` and the hardening would be
78
+ * lost. Defaults to false at the consumer.
79
+ */
80
+ strict: z.boolean().optional(),
81
+ });
82
+ export const embeddingsConfigSchema = z.object({
83
+ /**
84
+ * 'tfidf' (default, zero deps) | 'openai' (text-embedding-3-*)
85
+ * | 'transformers' (local, @huggingface/transformers) | 'none' (disable).
86
+ * Optional so a partial `embeddings:` block (e.g. only `model`) validates and
87
+ * config_set can write one field at a time; consumers default it to 'tfidf'.
88
+ */
89
+ provider: z.enum(['tfidf', 'openai', 'transformers', 'none']).optional(),
90
+ model: z.string().optional(),
91
+ dimensions: z.number().int().positive().optional(),
92
+ apiKey: z.string().optional(),
93
+ batchSize: z.number().int().positive().optional(),
94
+ cacheDir: z.string().optional(),
95
+ /** Persist computed embeddings to ~/.moxxy/memory/.embeddings.json. */
96
+ persistIndex: z.boolean().optional(),
97
+ });
98
+ /**
99
+ * Turn-boundary elision settings (context-on-demand). Off-by-floor safety:
100
+ * `keepRecentTurns` never drops below 2 and elision is skipped while the
101
+ * context is under `minContextRatioToElide` full.
102
+ */
103
+ export const elisionConfigSchema = z.object({
104
+ enabled: z.boolean().optional(),
105
+ keepRecentTurns: z.number().int().min(2).optional(),
106
+ minContextRatioToElide: z.number().min(0).max(1).optional(),
107
+ /** Also collapse old user/assistant text turns (not just bulky tool results). */
108
+ elideConversational: z.boolean().optional(),
109
+ /** Auto-disable conversational elision after this many `recall({seq})` calls. */
110
+ conversationalRecallThreshold: z.number().int().positive().optional(),
111
+ maxRecallBytes: z.number().int().positive().optional(),
112
+ neverElideTools: z.array(z.string()).optional(),
113
+ });
114
+ /** Context-window / token-efficiency settings. */
115
+ export const contextConfigSchema = z.object({
116
+ /** Master switch for prompt caching. Default true (lossless). */
117
+ caching: z.boolean().optional(),
118
+ // The active CacheStrategy now lives at `plugins.cacheStrategy.default`.
119
+ elision: elisionConfigSchema.optional(),
120
+ /** Lazy tool loading: send only core + loaded tool schemas, index the rest. Default false. */
121
+ lazyTools: z.boolean().optional(),
122
+ /**
123
+ * Reasoning/thinking preview. `true` enables it at the model's default depth;
124
+ * `{ effort }` sets the depth. Honored only by providers/models that support
125
+ * reasoning (Anthropic adaptive thinking, OpenAI/Codex reasoning). Default off.
126
+ */
127
+ reasoning: z
128
+ .union([z.boolean(), z.object({ effort: z.enum(['low', 'medium', 'high']).optional() })])
129
+ .optional(),
130
+ /**
131
+ * Stuck-loop guard tuning. The guard bails a turn early when the model keeps
132
+ * making the same tool call; `maxIterations` is the hard backstop. Raise the
133
+ * thresholds if legitimately-repeated work is being cut short, or set
134
+ * `enabled: false` to disable the guard and rely on `maxIterations` alone.
135
+ */
136
+ loopGuard: z
137
+ .object({
138
+ enabled: z.boolean().optional(),
139
+ windowSize: z.number().int().positive().optional(),
140
+ repeatThreshold: z.number().int().positive().optional(),
141
+ nearWindowSize: z.number().int().positive().optional(),
142
+ nearThreshold: z.number().int().positive().optional(),
143
+ })
144
+ .strict()
145
+ .optional(),
146
+ });
147
+ export const moxxyConfigSchema = z.object({
148
+ /**
149
+ * The unified plugins manifest — the single source of truth for what's
150
+ * installed/enabled (`plugins.packages`) and the active default per category
151
+ * (`plugins.<category>.default`). Replaces the legacy flat
152
+ * provider/mode/compactor/workflowExecutor keys, the old `plugins:` map, and
153
+ * `preferences.json`.
154
+ */
155
+ plugins: pluginsTreeSchema.optional(),
156
+ context: contextConfigSchema.optional(),
157
+ systemPrompt: z.string().optional(),
158
+ maxIterations: z.number().int().positive().optional(),
159
+ hookTimeoutMs: z.number().int().positive().optional(),
160
+ watcher: watcherModeSchema.optional(),
161
+ skills: z
162
+ .object({
163
+ projectDir: z.string().optional(),
164
+ userDir: z.string().optional(),
165
+ extraDirs: z.array(z.string()).optional(),
166
+ })
167
+ .optional(),
168
+ security: securityConfigSchema.optional(),
169
+ channels: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),
170
+ permissions: permissionsConfigSchema.optional(),
171
+ env: z.record(z.string(), z.string()).optional(),
172
+ /** TUI presentation preferences (read at TUI boot; edited via /settings). */
173
+ tui: z
174
+ .object({
175
+ /** `mono` drops color like NO_COLOR; `default` is the standard palette. */
176
+ theme: z.enum(['default', 'mono']).optional(),
177
+ /** Hide the footer key-hint row when false. */
178
+ hints: z.boolean().optional(),
179
+ /**
180
+ * Ctrl+<letter> overrides for the input-editor command hotkeys. Values
181
+ * are single letters; unknown/conflicting letters are ignored at boot.
182
+ */
183
+ keys: z
184
+ .object({
185
+ forceSend: z.string().length(1).optional(),
186
+ dropQueued: z.string().length(1).optional(),
187
+ toggleTools: z.string().length(1).optional(),
188
+ })
189
+ .strict()
190
+ .optional(),
191
+ })
192
+ .strict()
193
+ .optional(),
194
+ });
195
+ // `pluginSettingsSchema` is defined in ./plugin-settings-schema and re-exported
196
+ // here for back-references; `PluginSettings` lives there too.
197
+ export { pluginSettingsSchema };
198
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ export interface UserConfigOptions {
2
+ readonly configPath?: string;
3
+ }
4
+ export declare function defaultUserConfigPath(): string;
5
+ export declare function loadDisabledPackageNames(opts?: UserConfigOptions): Promise<ReadonlySet<string>>;
6
+ export declare function isPluginDisabled(packageName: string, opts?: UserConfigOptions): Promise<boolean>;
7
+ export declare function setPluginEnabled(packageName: string, enabled: boolean, opts?: UserConfigOptions): Promise<void>;
8
+ export declare function clearPluginState(packageName: string, opts?: UserConfigOptions): Promise<void>;
9
+ export declare function setCategoryDefault(category: string, name: string, opts?: UserConfigOptions): Promise<void>;
10
+ /** Persist the active model for a provider (`plugins.provider.items.<name>.model`). */
11
+ export declare function setProviderModel(providerName: string, model: string, opts?: UserConfigOptions): Promise<void>;
12
+ /** Enable/disable a provider (`plugins.provider.items.<name>.enabled`). */
13
+ export declare function setProviderEnabled(providerName: string, enabled: boolean, opts?: UserConfigOptions): Promise<void>;
14
+ /**
15
+ * One stored provider item's persisted shape at
16
+ * `plugins.provider.items.<name>` — the unified-tree home of the runtime-
17
+ * registered (OpenAI-compatible) vendors that used to live in
18
+ * `~/.moxxy/providers.json`. `config` carries the vendor payload
19
+ * (`kind: 'openai-compat'`, baseURL, models, envVar, …); `model` is the
20
+ * default model the activation walk reads.
21
+ */
22
+ export interface ProviderItemState {
23
+ readonly model?: string;
24
+ readonly enabled?: boolean;
25
+ readonly config?: Record<string, unknown>;
26
+ }
27
+ /** All provider items from the USER config (tolerant: {} on missing file). */
28
+ export declare function loadProviderItems(opts?: UserConfigOptions): Promise<Record<string, ProviderItemState>>;
29
+ /** Upsert a provider item's `config` payload (and optionally its model). */
30
+ export declare function setProviderItemConfig(providerName: string, config: Record<string, unknown>, opts?: UserConfigOptions & {
31
+ readonly model?: string;
32
+ }): Promise<void>;
33
+ /** Remove a provider item entirely. Returns false when it wasn't present. */
34
+ export declare function removeProviderItem(providerName: string, opts?: UserConfigOptions): Promise<boolean>;
35
+ /** The subset of `moxxy init` selections that map onto the unified config tree. */
36
+ export interface InitConfigSelections {
37
+ /** Active provider contribution name (`plugins.provider.default`). */
38
+ readonly provider: string;
39
+ /** Default model for the provider (`plugins.provider.items.<name>.model`). */
40
+ readonly model?: string | null;
41
+ /** Ordered fallback provider names (`plugins.provider.fallbacks`); the primary is dropped. */
42
+ readonly fallbacks?: ReadonlyArray<string>;
43
+ /** Loop strategy (`plugins.mode.default`). */
44
+ readonly mode: string;
45
+ /** Memory embedder (`plugins.embedder.default`); the `tfidf` floor is left unwritten. */
46
+ readonly embedder: string;
47
+ /** Opt-in plugin-security toggle (top-level `security.enabled`). */
48
+ readonly security?: {
49
+ readonly enabled: boolean;
50
+ };
51
+ }
52
+ /**
53
+ * Persist the interactive `moxxy init` wizard's selections into
54
+ * `~/.moxxy/config.yaml` — the same store `moxxy provision` and the runtime
55
+ * quick-switches write, so init no longer drops a legacy-shaped file in the
56
+ * project cwd that the clean-slate schema silently ignores.
57
+ *
58
+ * One atomic read-modify-write over the parsed Document, so the package ledger
59
+ * the wizard already wrote (enabling the provider + extra packages via
60
+ * {@link setPluginEnabled}) and any user comments survive the merge. Like
61
+ * `provision`, the provider's API key lives in the vault under its canonical
62
+ * name and the credential resolver finds it there — so no `${vault:...}` ref is
63
+ * written here.
64
+ */
65
+ export declare function applyInitConfig(sel: InitConfigSelections, opts?: UserConfigOptions): Promise<string>;
66
+ /**
67
+ * The persisted active model — the default provider's `model` item option
68
+ * (`plugins.provider.items.<default>.model`). The user-level equivalent of the
69
+ * old `preferences.model`; used by the TUI as the effective model when no
70
+ * `--model` flag is passed. Returns undefined when unset.
71
+ */
72
+ export declare function loadActiveModel(opts?: UserConfigOptions): Promise<string | undefined>;
73
+ /** The active provider contribution name (`plugins.provider.default`), or null. */
74
+ export declare function loadActiveProvider(opts?: UserConfigOptions): Promise<string | null>;
75
+ /** Provider names disabled via `plugins.provider.items.<name>.enabled: false`. */
76
+ export declare function loadDisabledProviders(opts?: UserConfigOptions): Promise<ReadonlyArray<string>>;
77
+ //# sourceMappingURL=user-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-config.d.ts","sourceRoot":"","sources":["../src/user-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,265 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { createMutex } from '@moxxy/sdk';
3
+ import { moxxyPath, writeFileAtomic } from '@moxxy/sdk/server';
4
+ import { isMap, parse as parseYaml, parseDocument } from 'yaml';
5
+ import { PLUGIN_CATEGORY_KEYS } from './plugins-tree-schema.js';
6
+ import { pluginSettingsSchema } from './plugin-settings-schema.js';
7
+ /**
8
+ * Comment-preserving writers for the user's `~/.moxxy/config.yaml` — the single
9
+ * source of truth for the unified `plugins:` manifest. Runtime quick-switches
10
+ * (the TUI `/model` `/mode` pickers, the runner's provider switch, channel
11
+ * onboarding) persist here through these helpers, which edit the parsed YAML
12
+ * Document in place so user comments and unmodeled keys survive the round-trip.
13
+ *
14
+ * This REPLACES the old `~/.moxxy/preferences.json`: the persisted provider /
15
+ * mode / model / disabled-set now live in the same tree the rest of the config
16
+ * uses (`plugins.provider.default`, `plugins.mode.default`,
17
+ * `plugins.provider.items.<name>.{model,enabled}`), so there is no second store
18
+ * to reconcile.
19
+ */
20
+ /**
21
+ * Per-instance mutex serializing the read-modify-write of `config.yaml`. The
22
+ * atomic write prevents torn files, but two concurrent writers would otherwise
23
+ * read the same baseline and the second would clobber the first. Cross-process
24
+ * races (CLI vs running session) remain best-effort behind the atomic rename.
25
+ */
26
+ const configMutex = createMutex();
27
+ export function defaultUserConfigPath() {
28
+ return moxxyPath('config.yaml');
29
+ }
30
+ // --- package enable/disable ledger (plugins.packages.<pkg>) ---------------
31
+ export async function loadDisabledPackageNames(opts = {}) {
32
+ const packages = await readPackagesMap(opts.configPath ?? defaultUserConfigPath());
33
+ const disabled = new Set();
34
+ for (const [packageName, settings] of Object.entries(packages)) {
35
+ if (settings?.enabled === false)
36
+ disabled.add(packageName);
37
+ }
38
+ return disabled;
39
+ }
40
+ export async function isPluginDisabled(packageName, opts = {}) {
41
+ return (await loadDisabledPackageNames(opts)).has(packageName);
42
+ }
43
+ export async function setPluginEnabled(packageName, enabled, opts = {}) {
44
+ const configPath = opts.configPath ?? defaultUserConfigPath();
45
+ await configMutex.run(async () => {
46
+ const doc = await readUserConfigDoc(configPath);
47
+ pluginSettingsSchema.pick({ enabled: true }).parse({ enabled });
48
+ const existing = readRawEntry(doc, ['plugins', 'packages', packageName]);
49
+ doc.setIn(['plugins', 'packages', packageName], { ...existing, enabled });
50
+ await writeUserConfigDoc(configPath, doc);
51
+ });
52
+ }
53
+ export async function clearPluginState(packageName, opts = {}) {
54
+ const configPath = opts.configPath ?? defaultUserConfigPath();
55
+ await configMutex.run(async () => {
56
+ const doc = await readUserConfigDoc(configPath);
57
+ if (!doc.hasIn(['plugins', 'packages', packageName]))
58
+ return;
59
+ doc.deleteIn(['plugins', 'packages', packageName]);
60
+ pruneEmpty(doc, ['plugins', 'packages']);
61
+ pruneEmpty(doc, ['plugins']);
62
+ await writeUserConfigDoc(configPath, doc);
63
+ });
64
+ }
65
+ // --- category default swap (plugins.<category>.default) -------------------
66
+ export async function setCategoryDefault(category, name, opts = {}) {
67
+ if (!PLUGIN_CATEGORY_KEYS.includes(category)) {
68
+ throw new Error(`unknown plugin category '${category}' (expected one of: ${PLUGIN_CATEGORY_KEYS.join(', ')})`);
69
+ }
70
+ const configPath = opts.configPath ?? defaultUserConfigPath();
71
+ await configMutex.run(async () => {
72
+ const doc = await readUserConfigDoc(configPath);
73
+ doc.setIn(['plugins', category, 'default'], name);
74
+ await writeUserConfigDoc(configPath, doc);
75
+ });
76
+ }
77
+ // --- provider item options (plugins.provider.items.<name>.{model,enabled}) -
78
+ /** Persist the active model for a provider (`plugins.provider.items.<name>.model`). */
79
+ export async function setProviderModel(providerName, model, opts = {}) {
80
+ const configPath = opts.configPath ?? defaultUserConfigPath();
81
+ await configMutex.run(async () => {
82
+ const doc = await readUserConfigDoc(configPath);
83
+ doc.setIn(['plugins', 'provider', 'items', providerName, 'model'], model);
84
+ await writeUserConfigDoc(configPath, doc);
85
+ });
86
+ }
87
+ /** Enable/disable a provider (`plugins.provider.items.<name>.enabled`). */
88
+ export async function setProviderEnabled(providerName, enabled, opts = {}) {
89
+ const configPath = opts.configPath ?? defaultUserConfigPath();
90
+ await configMutex.run(async () => {
91
+ const doc = await readUserConfigDoc(configPath);
92
+ doc.setIn(['plugins', 'provider', 'items', providerName, 'enabled'], enabled);
93
+ await writeUserConfigDoc(configPath, doc);
94
+ });
95
+ }
96
+ /** All provider items from the USER config (tolerant: {} on missing file). */
97
+ export async function loadProviderItems(opts = {}) {
98
+ const configPath = opts.configPath ?? defaultUserConfigPath();
99
+ try {
100
+ const raw = await fs.readFile(configPath, 'utf8');
101
+ const parsed = parseYaml(raw);
102
+ return parsed?.plugins?.provider?.items ?? {};
103
+ }
104
+ catch {
105
+ return {};
106
+ }
107
+ }
108
+ /** Upsert a provider item's `config` payload (and optionally its model). */
109
+ export async function setProviderItemConfig(providerName, config, opts = {}) {
110
+ const configPath = opts.configPath ?? defaultUserConfigPath();
111
+ await configMutex.run(async () => {
112
+ const doc = await readUserConfigDoc(configPath);
113
+ doc.setIn(['plugins', 'provider', 'items', providerName, 'config'], config);
114
+ if (opts.model) {
115
+ doc.setIn(['plugins', 'provider', 'items', providerName, 'model'], opts.model);
116
+ }
117
+ await writeUserConfigDoc(configPath, doc);
118
+ });
119
+ }
120
+ /** Remove a provider item entirely. Returns false when it wasn't present. */
121
+ export async function removeProviderItem(providerName, opts = {}) {
122
+ const configPath = opts.configPath ?? defaultUserConfigPath();
123
+ return configMutex.run(async () => {
124
+ const doc = await readUserConfigDoc(configPath);
125
+ const path = ['plugins', 'provider', 'items', providerName];
126
+ if (!doc.hasIn(path))
127
+ return false;
128
+ doc.deleteIn(path);
129
+ await writeUserConfigDoc(configPath, doc);
130
+ return true;
131
+ });
132
+ }
133
+ /**
134
+ * Persist the interactive `moxxy init` wizard's selections into
135
+ * `~/.moxxy/config.yaml` — the same store `moxxy provision` and the runtime
136
+ * quick-switches write, so init no longer drops a legacy-shaped file in the
137
+ * project cwd that the clean-slate schema silently ignores.
138
+ *
139
+ * One atomic read-modify-write over the parsed Document, so the package ledger
140
+ * the wizard already wrote (enabling the provider + extra packages via
141
+ * {@link setPluginEnabled}) and any user comments survive the merge. Like
142
+ * `provision`, the provider's API key lives in the vault under its canonical
143
+ * name and the credential resolver finds it there — so no `${vault:...}` ref is
144
+ * written here.
145
+ */
146
+ export async function applyInitConfig(sel, opts = {}) {
147
+ const configPath = opts.configPath ?? defaultUserConfigPath();
148
+ await configMutex.run(async () => {
149
+ const doc = await readUserConfigDoc(configPath);
150
+ doc.setIn(['plugins', 'provider', 'default'], sel.provider);
151
+ if (sel.model) {
152
+ doc.setIn(['plugins', 'provider', 'items', sel.provider, 'model'], sel.model);
153
+ }
154
+ const fallbacks = (sel.fallbacks ?? []).filter((f) => f !== sel.provider);
155
+ if (fallbacks.length > 0) {
156
+ doc.setIn(['plugins', 'provider', 'fallbacks'], doc.createNode(fallbacks));
157
+ }
158
+ doc.setIn(['plugins', 'mode', 'default'], sel.mode);
159
+ // tfidf is the built-in floor — only persist a non-default embedder.
160
+ if (sel.embedder && sel.embedder !== 'tfidf') {
161
+ doc.setIn(['plugins', 'embedder', 'default'], sel.embedder);
162
+ }
163
+ if (sel.security?.enabled) {
164
+ doc.setIn(['security', 'enabled'], true);
165
+ }
166
+ await writeUserConfigDoc(configPath, doc);
167
+ });
168
+ return configPath;
169
+ }
170
+ /**
171
+ * The persisted active model — the default provider's `model` item option
172
+ * (`plugins.provider.items.<default>.model`). The user-level equivalent of the
173
+ * old `preferences.model`; used by the TUI as the effective model when no
174
+ * `--model` flag is passed. Returns undefined when unset.
175
+ */
176
+ export async function loadActiveModel(opts = {}) {
177
+ const doc = await readUserConfigDoc(opts.configPath ?? defaultUserConfigPath());
178
+ const provider = doc.getIn(['plugins', 'provider', 'default']);
179
+ if (typeof provider !== 'string')
180
+ return undefined;
181
+ const model = doc.getIn(['plugins', 'provider', 'items', provider, 'model']);
182
+ return typeof model === 'string' ? model : undefined;
183
+ }
184
+ /** The active provider contribution name (`plugins.provider.default`), or null. */
185
+ export async function loadActiveProvider(opts = {}) {
186
+ const doc = await readUserConfigDoc(opts.configPath ?? defaultUserConfigPath());
187
+ const provider = doc.getIn(['plugins', 'provider', 'default']);
188
+ return typeof provider === 'string' ? provider : null;
189
+ }
190
+ /** Provider names disabled via `plugins.provider.items.<name>.enabled: false`. */
191
+ export async function loadDisabledProviders(opts = {}) {
192
+ const doc = await readUserConfigDoc(opts.configPath ?? defaultUserConfigPath());
193
+ const items = doc.getIn(['plugins', 'provider', 'items']);
194
+ if (!isMap(items))
195
+ return [];
196
+ const out = [];
197
+ for (const [name, entry] of Object.entries(items.toJSON())) {
198
+ if (entry && typeof entry === 'object' && entry.enabled === false) {
199
+ out.push(name);
200
+ }
201
+ }
202
+ return out;
203
+ }
204
+ // --- shared YAML round-trip helpers ---------------------------------------
205
+ /**
206
+ * Parse `config.yaml` into a yaml Document, preserving comments and untouched
207
+ * keys for the write path. A malformed file degrades to an empty document
208
+ * rather than throwing, so a single hand-edit typo can't strand every writer.
209
+ * The bad file is left in place for the user to inspect.
210
+ */
211
+ async function readUserConfigDoc(configPath) {
212
+ let raw = '';
213
+ try {
214
+ raw = await fs.readFile(configPath, 'utf8');
215
+ }
216
+ catch (err) {
217
+ if (isNotFound(err))
218
+ return parseDocument('');
219
+ throw err;
220
+ }
221
+ const doc = parseDocument(raw);
222
+ if (doc.errors.length > 0) {
223
+ console.warn(`moxxy: ignoring unparseable user config at ${configPath} (${doc.errors[0]?.message}); ` +
224
+ 'treating as empty');
225
+ return parseDocument('');
226
+ }
227
+ return doc;
228
+ }
229
+ async function writeUserConfigDoc(configPath, doc) {
230
+ await writeFileAtomic(configPath, doc.toString());
231
+ }
232
+ /** Read the validated `plugins.packages` map for the read-only paths. */
233
+ async function readPackagesMap(configPath) {
234
+ const doc = await readUserConfigDoc(configPath);
235
+ const packages = doc.getIn(['plugins', 'packages']);
236
+ if (!isMap(packages))
237
+ return {};
238
+ const out = {};
239
+ for (const [key, entry] of Object.entries(packages.toJSON())) {
240
+ const parsed = pluginSettingsSchema.safeParse(entry);
241
+ if (parsed.success)
242
+ out[key] = parsed.data;
243
+ }
244
+ return out;
245
+ }
246
+ /** A node as plain JS (unvalidated), or {} when absent/non-object. */
247
+ function readRawEntry(doc, path) {
248
+ const node = doc.getIn(path, false);
249
+ if (!isMap(node))
250
+ return {};
251
+ const raw = node.toJSON();
252
+ return typeof raw === 'object' && raw !== null && !Array.isArray(raw)
253
+ ? raw
254
+ : {};
255
+ }
256
+ /** Delete an emptied map node so we don't leave a bare `plugins: { packages: {} }`. */
257
+ function pruneEmpty(doc, path) {
258
+ const node = doc.getIn(path);
259
+ if (isMap(node) && node.items.length === 0)
260
+ doc.deleteIn(path);
261
+ }
262
+ function isNotFound(err) {
263
+ return typeof err === 'object' && err !== null && 'code' in err && err.code === 'ENOENT';
264
+ }
265
+ //# sourceMappingURL=user-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-config.js","sourceRoot":"","sources":["../src/user-config.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@moxxy/config",
3
+ "version": "0.27.0",
4
+ "description": "defineConfig + moxxy.config.ts loader. Walks the file tree from cwd, also reads ~/.moxxy/config.{ts,js,mjs}, merges by precedence, and resolves the final shape the CLI consumes.",
5
+ "keywords": [
6
+ "moxxy",
7
+ "config",
8
+ "yaml"
9
+ ],
10
+ "homepage": "https://moxxy.ai",
11
+ "bugs": {
12
+ "url": "https://github.com/moxxy-ai/moxxy/issues"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/moxxy-ai/moxxy.git",
17
+ "directory": "packages/config"
18
+ },
19
+ "author": "Michal Makowski <michal.makowski97@gmail.com>",
20
+ "license": "MIT",
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "type": "module",
25
+ "main": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ }
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "src"
36
+ ],
37
+ "dependencies": {
38
+ "jiti": "^2.4.2",
39
+ "yaml": "^2.6.0",
40
+ "zod": "^3.24.0",
41
+ "@moxxy/sdk": "0.27.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.10.0",
45
+ "typescript": "^5.7.3",
46
+ "vitest": "^2.1.8",
47
+ "@moxxy/tsconfig": "0.0.0",
48
+ "@moxxy/vitest-preset": "0.0.0"
49
+ },
50
+ "scripts": {
51
+ "build": "tsc -p tsconfig.json",
52
+ "typecheck": "tsc -p tsconfig.json --noEmit",
53
+ "test": "vitest run",
54
+ "clean": "rm -rf dist .turbo"
55
+ }
56
+ }