@nexrall/code-core 1.4.77 → 1.4.78
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.
- package/dist/agent/effortCap.d.ts +24 -0
- package/dist/agent/effortCap.d.ts.map +1 -0
- package/dist/agent/effortCap.js +66 -0
- package/dist/agent/hooks.d.ts +10 -2
- package/dist/agent/hooks.d.ts.map +1 -1
- package/dist/agent/hooks.js +9 -3
- package/dist/agent/skills.d.ts.map +1 -1
- package/dist/agent/skills.js +14 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/mcp/manager.d.ts +8 -0
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +64 -57
- package/dist/permissions/destructiveTokens.d.ts +1 -0
- package/dist/permissions/destructiveTokens.d.ts.map +1 -1
- package/dist/permissions/destructiveTokens.js +93 -0
- package/dist/permissions/rules.d.ts +12 -0
- package/dist/permissions/rules.d.ts.map +1 -1
- package/dist/permissions/rules.js +89 -7
- package/dist/plugins/configStore.d.ts +43 -0
- package/dist/plugins/configStore.d.ts.map +1 -0
- package/dist/plugins/configStore.js +253 -0
- package/dist/plugins/files.d.ts +10 -0
- package/dist/plugins/files.d.ts.map +1 -0
- package/dist/plugins/files.js +85 -0
- package/dist/plugins/index.d.ts +3 -22
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +30 -40
- package/dist/plugins/resolve.d.ts +18 -0
- package/dist/plugins/resolve.d.ts.map +1 -0
- package/dist/plugins/resolve.js +152 -0
- package/dist/plugins/userConfig.d.ts +90 -0
- package/dist/plugins/userConfig.d.ts.map +1 -0
- package/dist/plugins/userConfig.js +332 -0
- package/dist/plugins/validate.d.ts +14 -0
- package/dist/plugins/validate.d.ts.map +1 -0
- package/dist/plugins/validate.js +222 -0
- package/package.json +1 -1
package/dist/plugins/index.js
CHANGED
|
@@ -33,10 +33,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.FILE_CANDIDATES = void 0;
|
|
36
|
+
exports.readPluginManifest = exports.resolvePluginFile = exports.FILE_CANDIDATES = void 0;
|
|
37
37
|
exports.isPluginDisabled = isPluginDisabled;
|
|
38
38
|
exports.setPluginDisabled = setPluginDisabled;
|
|
39
|
-
exports.resolvePluginFile = resolvePluginFile;
|
|
40
39
|
exports.loadPlugins = loadPlugins;
|
|
41
40
|
exports.findPlugin = findPlugin;
|
|
42
41
|
exports.pluginAssetDirs = pluginAssetDirs;
|
|
@@ -46,6 +45,11 @@ const fs = __importStar(require("fs"));
|
|
|
46
45
|
const path = __importStar(require("path"));
|
|
47
46
|
const os = __importStar(require("os"));
|
|
48
47
|
const data_1 = require("./data");
|
|
48
|
+
const files_1 = require("./files");
|
|
49
|
+
var files_2 = require("./files");
|
|
50
|
+
Object.defineProperty(exports, "FILE_CANDIDATES", { enumerable: true, get: function () { return files_2.FILE_CANDIDATES; } });
|
|
51
|
+
Object.defineProperty(exports, "resolvePluginFile", { enumerable: true, get: function () { return files_2.resolvePluginFile; } });
|
|
52
|
+
Object.defineProperty(exports, "readPluginManifest", { enumerable: true, get: function () { return files_2.readPluginManifest; } });
|
|
49
53
|
// ─── Enable / disable ──────────────────────────────────────────────────────────
|
|
50
54
|
//
|
|
51
55
|
// A marker file rather than a registry list, so the on/off state travels WITH
|
|
@@ -80,39 +84,13 @@ function setPluginDisabled(dir, disabled) {
|
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
86
|
/**
|
|
83
|
-
* Where each single-file component may live, in priority order
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* SECURITY: `hooks` and `mcp` here are code-execution surfaces. Every reader
|
|
89
|
-
* below and `inspectPluginDir` in installer.ts MUST resolve through this same
|
|
90
|
-
* table — if the loader reads a path the inspector does not check, a plugin can
|
|
91
|
-
* run commands that the install-time warning never mentioned. Adding a candidate
|
|
92
|
-
* without updating the inspector is exactly that bug, so the two are pinned
|
|
93
|
-
* together by a test.
|
|
87
|
+
* Where each single-file component may live, in priority order — moved to
|
|
88
|
+
* ./files.ts (S24) so parsing-only modules (validate, the config store) can
|
|
89
|
+
* resolve paths without importing this loader (which imports them back).
|
|
90
|
+
* Re-exported above for existing callers.
|
|
94
91
|
*/
|
|
95
|
-
exports.FILE_CANDIDATES = {
|
|
96
|
-
manifest: ['plugin.json', path.join('.claude-plugin', 'plugin.json')],
|
|
97
|
-
hooks: ['hooks.json', path.join('hooks', 'hooks.json')],
|
|
98
|
-
mcp: ['mcp.json', '.mcp.json'],
|
|
99
|
-
};
|
|
100
|
-
/** First existing candidate path for a component, or null. */
|
|
101
|
-
function resolvePluginFile(dir, kind) {
|
|
102
|
-
for (const rel of exports.FILE_CANDIDATES[kind]) {
|
|
103
|
-
const full = path.join(dir, rel);
|
|
104
|
-
try {
|
|
105
|
-
if (fs.statSync(full).isFile())
|
|
106
|
-
return full;
|
|
107
|
-
}
|
|
108
|
-
catch {
|
|
109
|
-
/* try the next candidate */
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
92
|
function readMeta(dir) {
|
|
115
|
-
const file = resolvePluginFile(dir, 'manifest');
|
|
93
|
+
const file = (0, files_1.resolvePluginFile)(dir, 'manifest');
|
|
116
94
|
if (!file)
|
|
117
95
|
return {};
|
|
118
96
|
try {
|
|
@@ -215,12 +193,12 @@ function pluginAssetDirs(workDir, kind) {
|
|
|
215
193
|
* processes their NEXRALL_PLUGIN_DATA (see runHookHandler). Both entry forms are stamped:
|
|
216
194
|
* the flat one (the entry IS the handler) and the nested one (each item under `hooks`).
|
|
217
195
|
*/
|
|
218
|
-
function pluginHooks(workDir) {
|
|
196
|
+
function pluginHooks(workDir, transform) {
|
|
219
197
|
const merged = {};
|
|
220
198
|
for (const p of loadPlugins(workDir)) {
|
|
221
199
|
if (p.disabled)
|
|
222
200
|
continue;
|
|
223
|
-
const file = resolvePluginFile(p.dir, 'hooks');
|
|
201
|
+
const file = (0, files_1.resolvePluginFile)(p.dir, 'hooks');
|
|
224
202
|
if (!file)
|
|
225
203
|
continue;
|
|
226
204
|
try {
|
|
@@ -231,7 +209,15 @@ function pluginHooks(workDir) {
|
|
|
231
209
|
for (const [phase, entries] of Object.entries(hooks)) {
|
|
232
210
|
if (!Array.isArray(entries))
|
|
233
211
|
continue;
|
|
234
|
-
|
|
212
|
+
// `transform` (S24) lets plugins/resolve.ts bake each handler's resolved
|
|
213
|
+
// userConfig env map in, keeping THIS loader free of value resolution.
|
|
214
|
+
merged[phase] = [
|
|
215
|
+
...(merged[phase] ?? []),
|
|
216
|
+
...entries.map((e) => {
|
|
217
|
+
const stamped = stampPlugin(e, p.name);
|
|
218
|
+
return transform ? transform(stamped, p.name) : stamped;
|
|
219
|
+
}),
|
|
220
|
+
];
|
|
235
221
|
}
|
|
236
222
|
}
|
|
237
223
|
catch {
|
|
@@ -260,12 +246,12 @@ function stampPlugin(entry, plugin) {
|
|
|
260
246
|
* this is the only place a server can keep state. A plugin that set the variable itself keeps
|
|
261
247
|
* its own value: an explicit config value is never overridden here.
|
|
262
248
|
*/
|
|
263
|
-
function pluginMcpServers(workDir) {
|
|
249
|
+
function pluginMcpServers(workDir, transform) {
|
|
264
250
|
const merged = {};
|
|
265
251
|
for (const p of loadPlugins(workDir)) {
|
|
266
252
|
if (p.disabled)
|
|
267
253
|
continue;
|
|
268
|
-
const file = resolvePluginFile(p.dir, 'mcp');
|
|
254
|
+
const file = (0, files_1.resolvePluginFile)(p.dir, 'mcp');
|
|
269
255
|
if (!file)
|
|
270
256
|
continue;
|
|
271
257
|
try {
|
|
@@ -273,8 +259,12 @@ function pluginMcpServers(workDir) {
|
|
|
273
259
|
const j = JSON.parse(raw);
|
|
274
260
|
const servers = (j.mcpServers ?? j);
|
|
275
261
|
for (const [name, cfg] of Object.entries(servers)) {
|
|
276
|
-
if (!(name in merged))
|
|
277
|
-
|
|
262
|
+
if (!(name in merged)) {
|
|
263
|
+
// `transform` (S24) is where plugins/resolve.ts substitutes
|
|
264
|
+
// `${user_config.KEY}`; the data-dir env is added after it.
|
|
265
|
+
const resolved = transform ? transform(cfg, p.name) : cfg;
|
|
266
|
+
merged[name] = withPluginDataEnv(resolved, p.name);
|
|
267
|
+
}
|
|
278
268
|
}
|
|
279
269
|
}
|
|
280
270
|
catch {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type UserConfigOption } from './userConfig';
|
|
2
|
+
export interface PluginResolvedConfig {
|
|
3
|
+
options: UserConfigOption[];
|
|
4
|
+
values: Record<string, unknown>;
|
|
5
|
+
}
|
|
6
|
+
/** pluginHooks + each handler's resolved NEXRALL_PLUGIN_OPTION_* env map. */
|
|
7
|
+
export declare function resolvePluginHooks(workDir: string): Record<string, unknown[]>;
|
|
8
|
+
/** pluginMcpServers + `${user_config.KEY}` substitution (sensitive included). */
|
|
9
|
+
export declare function resolvePluginMcpServers(workDir: string): Record<string, unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* The resolved config of the plugin a skill DIRECTORY belongs to, or null.
|
|
12
|
+
* Used by skills.ts's expandSkill: a skill under `<plugin>/skills/<name>/` gets
|
|
13
|
+
* its body substituted with that plugin's NON-SENSITIVE values.
|
|
14
|
+
*/
|
|
15
|
+
export declare function pluginConfigForSkillDir(workDir: string, skillDir: string): PluginResolvedConfig | null;
|
|
16
|
+
/** Substitute one text with a plugin's values, non-sensitive only (skill bodies). */
|
|
17
|
+
export declare function substituteSkillBody(text: string, cfg: PluginResolvedConfig): string;
|
|
18
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/plugins/resolve.ts"],"names":[],"mappings":"AAsBA,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,cAAc,CAAC;AAGtB,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAcD,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CA2B7E;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQhF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAgBtG;AAED,qFAAqF;AACrF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,oBAAoB,GAAG,MAAM,CAEnF"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── Resolved plugin surfaces (S24) ──────────────────────────────────────────
|
|
3
|
+
//
|
|
4
|
+
// plugins/index.ts stays pure of VALUES: it merges hooks/mcp across plugins and
|
|
5
|
+
// stamps provenance (which plugin a handler/server came from). This module adds
|
|
6
|
+
// the userConfig layer on top — it resolves each plugin's values (configStore)
|
|
7
|
+
// and hands the loader a transform that bakes them into the surfaces:
|
|
8
|
+
//
|
|
9
|
+
// • hooks → `pluginOptions`: the NEXRALL_PLUGIN_OPTION_<KEY> env map each
|
|
10
|
+
// handler's process receives (attached under the entry's both forms, the
|
|
11
|
+
// same way `plugin` provenance is stamped);
|
|
12
|
+
// • mcp.json → `${user_config.KEY}` substituted through the whole server
|
|
13
|
+
// config (sensitive values INCLUDED — a server config is a trusted
|
|
14
|
+
// execution surface the user explicitly installed);
|
|
15
|
+
// • skill bodies → non-sensitive values only (see skills.ts's expandSkill);
|
|
16
|
+
// a sensitive reference stays the literal token rather than entering model
|
|
17
|
+
// context.
|
|
18
|
+
//
|
|
19
|
+
// Import graph note: this module may import configStore (hooks.ts imports
|
|
20
|
+
// resolve.ts, and configStore deliberately does not import hooks back).
|
|
21
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(o, k2, desc);
|
|
28
|
+
}) : (function(o, m, k, k2) {
|
|
29
|
+
if (k2 === undefined) k2 = k;
|
|
30
|
+
o[k2] = m[k];
|
|
31
|
+
}));
|
|
32
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
33
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34
|
+
}) : function(o, v) {
|
|
35
|
+
o["default"] = v;
|
|
36
|
+
});
|
|
37
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
38
|
+
var ownKeys = function(o) {
|
|
39
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
40
|
+
var ar = [];
|
|
41
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
42
|
+
return ar;
|
|
43
|
+
};
|
|
44
|
+
return ownKeys(o);
|
|
45
|
+
};
|
|
46
|
+
return function (mod) {
|
|
47
|
+
if (mod && mod.__esModule) return mod;
|
|
48
|
+
var result = {};
|
|
49
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
50
|
+
__setModuleDefault(result, mod);
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
})();
|
|
54
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
+
exports.resolvePluginHooks = resolvePluginHooks;
|
|
56
|
+
exports.resolvePluginMcpServers = resolvePluginMcpServers;
|
|
57
|
+
exports.pluginConfigForSkillDir = pluginConfigForSkillDir;
|
|
58
|
+
exports.substituteSkillBody = substituteSkillBody;
|
|
59
|
+
const path = __importStar(require("path"));
|
|
60
|
+
const index_1 = require("./index");
|
|
61
|
+
const userConfig_1 = require("./userConfig");
|
|
62
|
+
const configStore_1 = require("./configStore");
|
|
63
|
+
/** Per-plugin resolved config for every ENABLED plugin that declares userConfig. */
|
|
64
|
+
function configsByPlugin(workDir) {
|
|
65
|
+
const out = new Map();
|
|
66
|
+
for (const p of (0, index_1.loadPlugins)(workDir)) {
|
|
67
|
+
if (p.disabled)
|
|
68
|
+
continue;
|
|
69
|
+
const { options } = (0, userConfig_1.parseUserConfig)((0, index_1.readPluginManifest)(p.dir));
|
|
70
|
+
if (!options.length)
|
|
71
|
+
continue;
|
|
72
|
+
out.set(p.name, { options, values: (0, configStore_1.resolvePluginConfig)(workDir, p.name, options).values });
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
/** pluginHooks + each handler's resolved NEXRALL_PLUGIN_OPTION_* env map. */
|
|
77
|
+
function resolvePluginHooks(workDir) {
|
|
78
|
+
const configs = configsByPlugin(workDir);
|
|
79
|
+
if (!configs.size)
|
|
80
|
+
return (0, index_1.pluginHooks)(workDir);
|
|
81
|
+
return (0, index_1.pluginHooks)(workDir, (entry, plugin) => {
|
|
82
|
+
const cfg = configs.get(plugin);
|
|
83
|
+
if (!cfg)
|
|
84
|
+
return entry;
|
|
85
|
+
const env = (0, userConfig_1.pluginOptionEnvMap)(cfg.options, cfg.values);
|
|
86
|
+
if (!Object.keys(env).length)
|
|
87
|
+
return entry;
|
|
88
|
+
if (!entry || typeof entry !== 'object')
|
|
89
|
+
return entry;
|
|
90
|
+
const e = entry;
|
|
91
|
+
// Both entry forms — the same split pluginHooks' stampPlugin walks.
|
|
92
|
+
if (Array.isArray(e.hooks)) {
|
|
93
|
+
return {
|
|
94
|
+
...e,
|
|
95
|
+
hooks: e.hooks.map((h) => {
|
|
96
|
+
if (!h || typeof h !== 'object')
|
|
97
|
+
return h;
|
|
98
|
+
const handler = h;
|
|
99
|
+
const prior = handler.pluginOptions;
|
|
100
|
+
const priors = prior && typeof prior === 'object' && !Array.isArray(prior) ? prior : {};
|
|
101
|
+
return { ...handler, pluginOptions: { ...priors, ...env } };
|
|
102
|
+
}),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const prior = e.pluginOptions;
|
|
106
|
+
const priors = prior && typeof prior === 'object' && !Array.isArray(prior) ? prior : {};
|
|
107
|
+
return { ...e, pluginOptions: { ...priors, ...env } };
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/** pluginMcpServers + `${user_config.KEY}` substitution (sensitive included). */
|
|
111
|
+
function resolvePluginMcpServers(workDir) {
|
|
112
|
+
const configs = configsByPlugin(workDir);
|
|
113
|
+
if (!configs.size)
|
|
114
|
+
return (0, index_1.pluginMcpServers)(workDir);
|
|
115
|
+
return (0, index_1.pluginMcpServers)(workDir, (cfg, plugin) => {
|
|
116
|
+
const c = configs.get(plugin);
|
|
117
|
+
if (!c)
|
|
118
|
+
return cfg;
|
|
119
|
+
return (0, userConfig_1.substituteUserConfigDeep)(cfg, { options: c.options, values: c.values, includeSensitive: true });
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The resolved config of the plugin a skill DIRECTORY belongs to, or null.
|
|
124
|
+
* Used by skills.ts's expandSkill: a skill under `<plugin>/skills/<name>/` gets
|
|
125
|
+
* its body substituted with that plugin's NON-SENSITIVE values.
|
|
126
|
+
*/
|
|
127
|
+
function pluginConfigForSkillDir(workDir, skillDir) {
|
|
128
|
+
let dir;
|
|
129
|
+
try {
|
|
130
|
+
dir = path.resolve(skillDir);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
for (const p of (0, index_1.loadPlugins)(workDir)) {
|
|
136
|
+
if (p.disabled)
|
|
137
|
+
continue;
|
|
138
|
+
const root = path.resolve(p.dir);
|
|
139
|
+
if (!dir.startsWith(root + path.sep))
|
|
140
|
+
continue;
|
|
141
|
+
const { options } = (0, userConfig_1.parseUserConfig)((0, index_1.readPluginManifest)(p.dir));
|
|
142
|
+
if (!options.length)
|
|
143
|
+
return null;
|
|
144
|
+
return { options, values: (0, configStore_1.resolvePluginConfig)(workDir, p.name, options).values };
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
/** Substitute one text with a plugin's values, non-sensitive only (skill bodies). */
|
|
149
|
+
function substituteSkillBody(text, cfg) {
|
|
150
|
+
return (0, userConfig_1.substituteUserConfig)(text, { options: cfg.options, values: cfg.values, includeSensitive: false }).text;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/** Supported value types, matching Claude Code's set. */
|
|
2
|
+
export declare const USER_CONFIG_TYPES: readonly ["string", "number", "boolean", "directory", "file"];
|
|
3
|
+
export type UserConfigType = (typeof USER_CONFIG_TYPES)[number];
|
|
4
|
+
export interface UserConfigOption {
|
|
5
|
+
/** Identifier: letters, digits, underscores; may not start with a digit. */
|
|
6
|
+
key: string;
|
|
7
|
+
type: UserConfigType;
|
|
8
|
+
/** Label shown in the configuration surface. */
|
|
9
|
+
title: string;
|
|
10
|
+
/** Help text: what the value is and what it changes. */
|
|
11
|
+
description: string;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
/** Value used when the user provides nothing. */
|
|
14
|
+
default?: string | number | boolean | string[];
|
|
15
|
+
/** For `string`: the values the field accepts (a picker, not free text). */
|
|
16
|
+
options?: string[];
|
|
17
|
+
/** For `string`: allows an array of strings. */
|
|
18
|
+
multiple?: boolean;
|
|
19
|
+
/** Masks the value and stores it OUT of settings.json (our secrets file). */
|
|
20
|
+
sensitive?: boolean;
|
|
21
|
+
/** For `number`: bounds. */
|
|
22
|
+
min?: number;
|
|
23
|
+
max?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface UserConfigParseResult {
|
|
26
|
+
options: UserConfigOption[];
|
|
27
|
+
/** Schema problems, each naming its key. A plugin with errors has NO usable options. */
|
|
28
|
+
errors: string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse the manifest's `userConfig` block strictly — Claude Code's rule: an
|
|
32
|
+
* unknown key inside an option is an error. One bad option invalidates the
|
|
33
|
+
* WHOLE block (all-or-nothing): a plugin half-configured by a typo would be
|
|
34
|
+
* worse than one that loudly needs its manifest fixed.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseUserConfig(manifest: Record<string, unknown> | null | undefined): UserConfigParseResult;
|
|
37
|
+
/** Validate one value against its option. Returns an error string, or null when valid. */
|
|
38
|
+
export declare function validateUserConfigValue(option: UserConfigOption, value: unknown): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Coerce a CLI-supplied STRING into the option's type (values arrive from
|
|
41
|
+
* `--config key=value` / `--values-stdin` where everything is text).
|
|
42
|
+
* `parseNumber` is strict: "12abc" must not become 12.
|
|
43
|
+
*/
|
|
44
|
+
export declare function coerceUserConfigValue(option: UserConfigOption, raw: string): {
|
|
45
|
+
ok: true;
|
|
46
|
+
value: unknown;
|
|
47
|
+
} | {
|
|
48
|
+
ok: false;
|
|
49
|
+
error: string;
|
|
50
|
+
};
|
|
51
|
+
/** Every `${user_config.KEY}` reference in a string, unique and in first-seen order. */
|
|
52
|
+
export declare function findUserConfigRefs(text: string): string[];
|
|
53
|
+
export interface SubstituteResult {
|
|
54
|
+
text: string;
|
|
55
|
+
/** Keys that were replaced. */
|
|
56
|
+
substituted: string[];
|
|
57
|
+
/** Sensitive keys skipped because the surface does not accept them. */
|
|
58
|
+
skippedSensitive: string[];
|
|
59
|
+
/** Referenced keys with no resolvable value (the literal token is left in place). */
|
|
60
|
+
unresolved: string[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Replace `${user_config.KEY}` with resolved values. A reference with no value
|
|
64
|
+
* keeps its literal token — a visible failure the plugin's author can debug,
|
|
65
|
+
* never an empty string masquerading as a value. `includeSensitive: false`
|
|
66
|
+
* (skill bodies) leaves sensitive tokens in place; configStore decides which
|
|
67
|
+
* values may be exposed where.
|
|
68
|
+
*/
|
|
69
|
+
export declare function substituteUserConfig(text: string, opts: {
|
|
70
|
+
options: UserConfigOption[];
|
|
71
|
+
values: Record<string, unknown>;
|
|
72
|
+
includeSensitive: boolean;
|
|
73
|
+
}): SubstituteResult;
|
|
74
|
+
/** Deep substitution over an object/array graph (MCP server configs). Strings only. */
|
|
75
|
+
export declare function substituteUserConfigDeep(value: unknown, opts: {
|
|
76
|
+
options: UserConfigOption[];
|
|
77
|
+
values: Record<string, unknown>;
|
|
78
|
+
includeSensitive: boolean;
|
|
79
|
+
}): unknown;
|
|
80
|
+
/** All `${user_config.KEY}` refs found anywhere in a JSON value graph, unique. */
|
|
81
|
+
export declare function collectUserConfigRefsDeep(value: unknown): string[];
|
|
82
|
+
/** Claude Code's naming rule: `CLAUDE_PLUGIN_OPTION_<KEY>` → ours mirrors it. */
|
|
83
|
+
export declare function pluginOptionEnvKey(key: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* The env map a plugin's hook processes receive. Only scalar values can ride
|
|
86
|
+
* an environment variable; an array/object value is skipped (a shell would see
|
|
87
|
+
* "[object Object]" — worse than absent).
|
|
88
|
+
*/
|
|
89
|
+
export declare function pluginOptionEnvMap(options: UserConfigOption[], values: Record<string, unknown>): Record<string, string>;
|
|
90
|
+
//# sourceMappingURL=userConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userConfig.d.ts","sourceRoot":"","sources":["../../src/plugins/userConfig.ts"],"names":[],"mappings":"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"}
|