agentinit 1.23.0 → 1.24.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.
- package/CHANGELOG.md +10 -0
- package/README.md +23 -2
- package/dist/agents/CodexCliAgent.js +1 -1
- package/dist/agents/CodexCliAgent.js.map +1 -1
- package/dist/cli.js +860 -42
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +88 -0
- package/dist/commands/agent.js.map +1 -1
- package/dist/core/agentSettings/adapters/claude.d.ts.map +1 -1
- package/dist/core/agentSettings/adapters/claude.js +140 -2
- package/dist/core/agentSettings/adapters/claude.js.map +1 -1
- package/dist/core/agentSettings/adapters/codex.d.ts +3 -0
- package/dist/core/agentSettings/adapters/codex.d.ts.map +1 -0
- package/dist/core/agentSettings/adapters/codex.js +121 -0
- package/dist/core/agentSettings/adapters/codex.js.map +1 -0
- package/dist/core/agentSettings/adapters/opencode.d.ts +3 -0
- package/dist/core/agentSettings/adapters/opencode.d.ts.map +1 -0
- package/dist/core/agentSettings/adapters/opencode.js +134 -0
- package/dist/core/agentSettings/adapters/opencode.js.map +1 -0
- package/dist/core/agentSettings/registry.d.ts.map +1 -1
- package/dist/core/agentSettings/registry.js +4 -0
- package/dist/core/agentSettings/registry.js.map +1 -1
- package/dist/core/agentSettings/settingsManager.d.ts +3 -1
- package/dist/core/agentSettings/settingsManager.d.ts.map +1 -1
- package/dist/core/agentSettings/settingsManager.js +221 -27
- package/dist/core/agentSettings/settingsManager.js.map +1 -1
- package/dist/core/agentSettings/types.d.ts +23 -3
- package/dist/core/agentSettings/types.d.ts.map +1 -1
- package/dist/core/agentSettings/valueParser.d.ts.map +1 -1
- package/dist/core/agentSettings/valueParser.js +20 -0
- package/dist/core/agentSettings/valueParser.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { expandTilde } from '../../../utils/paths.js';
|
|
4
|
+
const SUPPORTED_SCOPES = ['global', 'project'];
|
|
5
|
+
const PERMISSION_ACTIONS = ['allow', 'ask', 'deny'];
|
|
6
|
+
function firstExistingPath(paths, fallback) {
|
|
7
|
+
return paths.find(candidate => existsSync(candidate)) ?? fallback;
|
|
8
|
+
}
|
|
9
|
+
function setting(key, valueType, title, description, options = {}) {
|
|
10
|
+
const definition = {
|
|
11
|
+
agent: 'opencode',
|
|
12
|
+
key,
|
|
13
|
+
nativePath: options.nativePath ?? key.split('.'),
|
|
14
|
+
title,
|
|
15
|
+
description,
|
|
16
|
+
valueType,
|
|
17
|
+
scopes: options.scopes ?? SUPPORTED_SCOPES,
|
|
18
|
+
defaultScope: options.defaultScope ?? 'global',
|
|
19
|
+
category: options.category ?? 'settings',
|
|
20
|
+
risk: options.risk ?? 'safe',
|
|
21
|
+
};
|
|
22
|
+
if (options.allowedValues) {
|
|
23
|
+
definition.allowedValues = options.allowedValues;
|
|
24
|
+
}
|
|
25
|
+
if (options.deprecated !== undefined) {
|
|
26
|
+
definition.deprecated = options.deprecated;
|
|
27
|
+
}
|
|
28
|
+
if (options.replacement) {
|
|
29
|
+
definition.replacement = options.replacement;
|
|
30
|
+
}
|
|
31
|
+
return definition;
|
|
32
|
+
}
|
|
33
|
+
export const opencodeSettingsAdapter = {
|
|
34
|
+
agent: 'opencode',
|
|
35
|
+
displayName: 'OpenCode',
|
|
36
|
+
format: 'jsonc',
|
|
37
|
+
definitions: [
|
|
38
|
+
setting('model', 'string', 'Model', 'Default model identifier in provider/model format (e.g. anthropic/claude-sonnet-4-5).', {
|
|
39
|
+
category: 'model',
|
|
40
|
+
}),
|
|
41
|
+
setting('small_model', 'string', 'Small model', 'Small model used for tasks such as title generation, in provider/model format.', {
|
|
42
|
+
category: 'model',
|
|
43
|
+
}),
|
|
44
|
+
setting('provider', 'object', 'Providers', 'Custom OpenCode provider configurations and model overrides.', {
|
|
45
|
+
category: 'provider',
|
|
46
|
+
risk: 'security-sensitive',
|
|
47
|
+
}),
|
|
48
|
+
setting('default_agent', 'string', 'Default agent', 'Default primary agent to use when none is specified.', {
|
|
49
|
+
category: 'agent',
|
|
50
|
+
}),
|
|
51
|
+
setting('autoupdate', 'booleanOrEnum', 'Auto update', 'Control automatic updates: true, false, or notify.', {
|
|
52
|
+
allowedValues: ['notify'],
|
|
53
|
+
scopes: ['global'],
|
|
54
|
+
defaultScope: 'global',
|
|
55
|
+
category: 'runtime',
|
|
56
|
+
}),
|
|
57
|
+
setting('shell', 'string', 'Shell', 'Default shell to use for terminal and bash tool execution.', {
|
|
58
|
+
category: 'runtime',
|
|
59
|
+
}),
|
|
60
|
+
setting('share', 'enum', 'Share', 'Control sharing behavior: manual, auto, or disabled.', {
|
|
61
|
+
allowedValues: ['manual', 'auto', 'disabled'],
|
|
62
|
+
category: 'sharing',
|
|
63
|
+
}),
|
|
64
|
+
setting('username', 'string', 'Username', 'Custom username displayed in conversations instead of system username.', {
|
|
65
|
+
category: 'ui',
|
|
66
|
+
}),
|
|
67
|
+
setting('logLevel', 'enum', 'Log level', 'Log verbosity level.', {
|
|
68
|
+
allowedValues: ['DEBUG', 'INFO', 'WARN', 'ERROR'],
|
|
69
|
+
category: 'runtime',
|
|
70
|
+
}),
|
|
71
|
+
setting('snapshot', 'boolean', 'Snapshot tracking', 'Enable or disable filesystem snapshot tracking for undo/redo.', {
|
|
72
|
+
category: 'runtime',
|
|
73
|
+
}),
|
|
74
|
+
setting('permission.*', 'enum', 'Default permission', 'Fallback permission rule for all tools: allow, ask, or deny.', {
|
|
75
|
+
nativePath: ['permission', '*'],
|
|
76
|
+
category: 'permissions',
|
|
77
|
+
risk: 'security-sensitive',
|
|
78
|
+
allowedValues: PERMISSION_ACTIONS,
|
|
79
|
+
}),
|
|
80
|
+
setting('permission.bash', 'enum', 'Bash permission', 'Permission rule for shell command execution.', {
|
|
81
|
+
category: 'permissions',
|
|
82
|
+
risk: 'security-sensitive',
|
|
83
|
+
allowedValues: PERMISSION_ACTIONS,
|
|
84
|
+
}),
|
|
85
|
+
setting('permission.read', 'enum', 'Read permission', 'Permission rule for file reads.', {
|
|
86
|
+
category: 'permissions',
|
|
87
|
+
allowedValues: PERMISSION_ACTIONS,
|
|
88
|
+
}),
|
|
89
|
+
setting('permission.edit', 'enum', 'Edit permission', 'Permission rule for editing and writing files.', {
|
|
90
|
+
category: 'permissions',
|
|
91
|
+
risk: 'risky',
|
|
92
|
+
allowedValues: PERMISSION_ACTIONS,
|
|
93
|
+
}),
|
|
94
|
+
setting('permission.webfetch', 'enum', 'Web fetch permission', 'Permission rule for fetching external URLs.', {
|
|
95
|
+
category: 'permissions',
|
|
96
|
+
allowedValues: PERMISSION_ACTIONS,
|
|
97
|
+
}),
|
|
98
|
+
setting('permission.task', 'enum', 'Task permission', 'Permission rule for spawning subagent tasks.', {
|
|
99
|
+
category: 'permissions',
|
|
100
|
+
allowedValues: PERMISSION_ACTIONS,
|
|
101
|
+
}),
|
|
102
|
+
setting('permission.websearch', 'enum', 'Web search permission', 'Permission rule for web search operations.', {
|
|
103
|
+
category: 'permissions',
|
|
104
|
+
allowedValues: PERMISSION_ACTIONS,
|
|
105
|
+
}),
|
|
106
|
+
setting('compaction.auto', 'boolean', 'Auto compaction', 'Enable automatic context compaction when context is full.', {
|
|
107
|
+
category: 'compaction',
|
|
108
|
+
}),
|
|
109
|
+
setting('tool_output.max_lines', 'positiveInteger', 'Tool output max lines', 'Maximum lines of tool output before truncation.', {
|
|
110
|
+
category: 'output',
|
|
111
|
+
}),
|
|
112
|
+
setting('tool_output.max_bytes', 'positiveInteger', 'Tool output max bytes', 'Maximum bytes of tool output before truncation.', {
|
|
113
|
+
category: 'output',
|
|
114
|
+
}),
|
|
115
|
+
],
|
|
116
|
+
getSettingsPath(scope, projectPath) {
|
|
117
|
+
switch (scope) {
|
|
118
|
+
case 'global':
|
|
119
|
+
return firstExistingPath([
|
|
120
|
+
expandTilde('~/.config/opencode/opencode.jsonc'),
|
|
121
|
+
expandTilde('~/.config/opencode/opencode.json'),
|
|
122
|
+
expandTilde('~/.config/opencode/config.json'),
|
|
123
|
+
], expandTilde('~/.config/opencode/opencode.json'));
|
|
124
|
+
case 'project':
|
|
125
|
+
return firstExistingPath([
|
|
126
|
+
join(projectPath, '.opencode', 'opencode.jsonc'),
|
|
127
|
+
join(projectPath, '.opencode', 'opencode.json'),
|
|
128
|
+
], join(projectPath, '.opencode', 'opencode.json'));
|
|
129
|
+
case 'local':
|
|
130
|
+
throw new Error('OpenCode settings do not support local scope. Use --global or --project.');
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
//# sourceMappingURL=opencode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../../src/core/agentSettings/adapters/opencode.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/agentSettings/registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/agentSettings/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAQxG,wBAAgB,wBAAwB,IAAI,oBAAoB,EAAE,CAEjE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAEvF;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAExG;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,sBAAsB,GAAG,uBAAuB,CAKzF"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { claudeSettingsAdapter } from './adapters/claude.js';
|
|
2
|
+
import { codexSettingsAdapter } from './adapters/codex.js';
|
|
3
|
+
import { opencodeSettingsAdapter } from './adapters/opencode.js';
|
|
2
4
|
const ADAPTERS = [
|
|
3
5
|
claudeSettingsAdapter,
|
|
6
|
+
codexSettingsAdapter,
|
|
7
|
+
opencodeSettingsAdapter,
|
|
4
8
|
];
|
|
5
9
|
export function getAgentSettingsAdapters() {
|
|
6
10
|
return [...ADAPTERS];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/agentSettings/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/agentSettings/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAGjE,MAAM,QAAQ,GAA2B;IACvC,qBAAqB;IACrB,oBAAoB;IACpB,uBAAuB;CACxB,CAAC;AAEF,MAAM,UAAU,wBAAwB;IACtC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,KAAa,EAAE,GAAW;IAClE,OAAO,uBAAuB,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,UAAkC;IAC9D,OAAO;QACL,GAAG,UAAU;QACb,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;KAC5C,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentHookAddOptions, AgentHookMatcher, AgentHookRemoveOptions, AgentHookWriteResult, AgentSettingReadOptions, AgentSettingsSchema, AgentSettingSetOptions, AgentSettingsWriteResult } from './types.js';
|
|
1
|
+
import type { AgentApiKeyAction, AgentApiKeyOptions, AgentApiKeyResult, AgentHookAddOptions, AgentHookMatcher, AgentHookRemoveOptions, AgentHookWriteResult, AgentSettingReadOptions, AgentSettingsSchema, AgentSettingSetOptions, AgentSettingsWriteResult } from './types.js';
|
|
2
2
|
export declare class AgentSettingsManager {
|
|
3
3
|
getSupportedAgents(): string[];
|
|
4
4
|
getSchema(agent: string): AgentSettingsSchema;
|
|
@@ -8,5 +8,7 @@ export declare class AgentSettingsManager {
|
|
|
8
8
|
listHooks(agent: string, event?: string, options?: AgentSettingReadOptions): Promise<Record<string, AgentHookMatcher[]> | AgentHookMatcher[]>;
|
|
9
9
|
addHook(agent: string, event: string, command: string, options?: AgentHookAddOptions): Promise<AgentHookWriteResult>;
|
|
10
10
|
removeHook(agent: string, event: string, commandOrName: string, options?: AgentHookRemoveOptions): Promise<AgentHookWriteResult>;
|
|
11
|
+
getApiKeyStatus(agent: string, apiKey: string, options?: AgentApiKeyOptions): Promise<AgentApiKeyResult>;
|
|
12
|
+
updateApiKeyTrust(agent: string, action: AgentApiKeyAction, apiKey: string, options?: AgentApiKeyOptions): Promise<AgentApiKeyResult>;
|
|
11
13
|
}
|
|
12
14
|
//# sourceMappingURL=settingsManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settingsManager.d.ts","sourceRoot":"","sources":["../../../src/core/agentSettings/settingsManager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"settingsManager.d.ts","sourceRoot":"","sources":["../../../src/core/agentSettings/settingsManager.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EAEjB,mBAAmB,EAInB,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EAEnB,sBAAsB,EACtB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAiWpB,qBAAa,oBAAoB;IAC/B,kBAAkB,IAAI,MAAM,EAAE;IAI9B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB;IAcvC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,OAAO,CAAC;IA4CzF,GAAG,CACP,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,wBAAwB,CAAC;IAkC9B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAgC1G,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,GAAG,gBAAgB,EAAE,CAAC;IAoCjJ,OAAO,CACX,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,oBAAoB,CAAC;IA4C1B,UAAU,CACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,oBAAoB,CAAC;IAmD1B,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAuB5G,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA4ChJ"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as TOML from '@iarna/toml';
|
|
2
|
+
import { parse as parseJsonc } from 'jsonc-parser';
|
|
1
3
|
import { readFileIfExists, writeFile } from '../../utils/fs.js';
|
|
2
4
|
import { getEffectiveAgentSettingsDefaultScopeSync } from '../userConfig.js';
|
|
3
5
|
import { parseAgentSettingValue } from './valueParser.js';
|
|
@@ -13,8 +15,22 @@ const HOOK_EVENT_ALIASES = {
|
|
|
13
15
|
stop: 'Stop',
|
|
14
16
|
'session-start': 'SessionStart',
|
|
15
17
|
'session-end': 'SessionEnd',
|
|
18
|
+
'user-prompt-submit': 'UserPromptSubmit',
|
|
16
19
|
};
|
|
17
20
|
const HOOK_EVENTS = new Set(Object.values(HOOK_EVENT_ALIASES));
|
|
21
|
+
const CLAUDE_API_KEY_RESPONSES_DEFINITION = {
|
|
22
|
+
agent: 'claude',
|
|
23
|
+
key: 'customApiKeyResponses',
|
|
24
|
+
nativePath: ['customApiKeyResponses'],
|
|
25
|
+
title: 'Custom API key responses',
|
|
26
|
+
description: 'Remembered custom API key trust responses.',
|
|
27
|
+
valueType: 'object',
|
|
28
|
+
scopes: ['global'],
|
|
29
|
+
defaultScope: 'global',
|
|
30
|
+
category: 'auth',
|
|
31
|
+
risk: 'security-sensitive',
|
|
32
|
+
store: 'globalConfig',
|
|
33
|
+
};
|
|
18
34
|
function assertObject(value, path) {
|
|
19
35
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
20
36
|
throw new Error(`${path} contains JSON that is not an object.`);
|
|
@@ -144,6 +160,50 @@ function buildHookCommand(command, name) {
|
|
|
144
160
|
...(name ? { name } : {}),
|
|
145
161
|
};
|
|
146
162
|
}
|
|
163
|
+
function normalizeApiKeyForConfig(apiKey) {
|
|
164
|
+
const trimmed = apiKey.trim();
|
|
165
|
+
if (!trimmed) {
|
|
166
|
+
throw new Error('API key cannot be empty.');
|
|
167
|
+
}
|
|
168
|
+
return trimmed.slice(-20);
|
|
169
|
+
}
|
|
170
|
+
function getApiKeyResponses(config) {
|
|
171
|
+
const current = config.customApiKeyResponses;
|
|
172
|
+
if (current !== undefined && (!current || typeof current !== 'object' || Array.isArray(current))) {
|
|
173
|
+
throw new Error('Existing customApiKeyResponses value is not an object.');
|
|
174
|
+
}
|
|
175
|
+
const responses = (current ?? {});
|
|
176
|
+
const approved = responses.approved ?? [];
|
|
177
|
+
const rejected = responses.rejected ?? [];
|
|
178
|
+
if (!Array.isArray(approved) || !approved.every(value => typeof value === 'string')) {
|
|
179
|
+
throw new Error('Existing customApiKeyResponses.approved value must be an array of strings.');
|
|
180
|
+
}
|
|
181
|
+
if (!Array.isArray(rejected) || !rejected.every(value => typeof value === 'string')) {
|
|
182
|
+
throw new Error('Existing customApiKeyResponses.rejected value must be an array of strings.');
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
approved,
|
|
186
|
+
rejected,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function getApiKeyStatusFromResponses(responses, fingerprint) {
|
|
190
|
+
if (responses.approved.includes(fingerprint)) {
|
|
191
|
+
return 'approved';
|
|
192
|
+
}
|
|
193
|
+
if (responses.rejected.includes(fingerprint)) {
|
|
194
|
+
return 'rejected';
|
|
195
|
+
}
|
|
196
|
+
return 'unknown';
|
|
197
|
+
}
|
|
198
|
+
function setApiKeyResponses(config, approved, rejected) {
|
|
199
|
+
config.customApiKeyResponses = {
|
|
200
|
+
...(config.customApiKeyResponses && typeof config.customApiKeyResponses === 'object' && !Array.isArray(config.customApiKeyResponses)
|
|
201
|
+
? config.customApiKeyResponses
|
|
202
|
+
: {}),
|
|
203
|
+
approved,
|
|
204
|
+
rejected,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
147
207
|
function deleteNestedValue(config, path) {
|
|
148
208
|
const parents = [];
|
|
149
209
|
let current = config;
|
|
@@ -178,27 +238,79 @@ function resolveProjectPath(projectPath) {
|
|
|
178
238
|
return projectPath ?? process.cwd();
|
|
179
239
|
}
|
|
180
240
|
function resolveScope(definition, scope) {
|
|
181
|
-
const
|
|
241
|
+
const defaultScope = getEffectiveAgentSettingsDefaultScopeSync();
|
|
242
|
+
const resolvedScope = scope ?? (definition.store === 'globalConfig' && !definition.scopes.includes(defaultScope) ? definition.defaultScope : defaultScope);
|
|
182
243
|
if (!definition.scopes.includes(resolvedScope)) {
|
|
183
244
|
throw new Error(`"${definition.key}" does not support ${resolvedScope} scope. Supported scopes: ${definition.scopes.join(', ')}.`);
|
|
184
245
|
}
|
|
185
246
|
return resolvedScope;
|
|
186
247
|
}
|
|
187
|
-
|
|
248
|
+
function getSupportedSettingScopes(adapter) {
|
|
249
|
+
return [...new Set(adapter.definitions.flatMap(definition => definition.scopes))];
|
|
250
|
+
}
|
|
251
|
+
function resolveFullReadScope(adapter, scope) {
|
|
252
|
+
const resolvedScope = scope ?? getEffectiveAgentSettingsDefaultScopeSync();
|
|
253
|
+
const supportedScopes = getSupportedSettingScopes(adapter);
|
|
254
|
+
if (!supportedScopes.includes(resolvedScope)) {
|
|
255
|
+
throw new Error(`Agent ${adapter.agent} settings do not support ${resolvedScope} scope. Supported scopes: ${supportedScopes.join(', ')}.`);
|
|
256
|
+
}
|
|
257
|
+
return resolvedScope;
|
|
258
|
+
}
|
|
259
|
+
async function readConfigObject(adapter, path) {
|
|
188
260
|
const content = await readFileIfExists(path);
|
|
189
261
|
if (!content) {
|
|
190
262
|
return {};
|
|
191
263
|
}
|
|
264
|
+
if (adapter.format === 'toml') {
|
|
265
|
+
try {
|
|
266
|
+
return assertObject(TOML.parse(content), path);
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
if (error instanceof SyntaxError || error instanceof Error) {
|
|
270
|
+
throw new Error(`${path} contains invalid TOML.`);
|
|
271
|
+
}
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
192
275
|
try {
|
|
193
|
-
|
|
276
|
+
const errors = [];
|
|
277
|
+
const value = adapter.format === 'jsonc'
|
|
278
|
+
? parseJsonc(content, errors, { allowTrailingComma: true })
|
|
279
|
+
: JSON.parse(content);
|
|
280
|
+
if (errors.length > 0) {
|
|
281
|
+
throw new SyntaxError('Invalid JSONC');
|
|
282
|
+
}
|
|
283
|
+
return assertObject(value, path);
|
|
194
284
|
}
|
|
195
285
|
catch (error) {
|
|
196
286
|
if (error instanceof SyntaxError) {
|
|
197
|
-
throw new Error(`${path} contains invalid JSON.`);
|
|
287
|
+
throw new Error(`${path} contains invalid ${adapter.format === 'jsonc' ? 'JSONC' : 'JSON'}.`);
|
|
198
288
|
}
|
|
199
289
|
throw error;
|
|
200
290
|
}
|
|
201
291
|
}
|
|
292
|
+
function stringifyConfigObject(adapter, config) {
|
|
293
|
+
if (adapter.format === 'toml') {
|
|
294
|
+
return TOML.stringify(config);
|
|
295
|
+
}
|
|
296
|
+
return `${JSON.stringify(config, null, 2)}\n`;
|
|
297
|
+
}
|
|
298
|
+
async function writeConfigObject(adapter, path, config) {
|
|
299
|
+
await writeFile(path, stringifyConfigObject(adapter, config));
|
|
300
|
+
}
|
|
301
|
+
function assertHookEventSupported(adapter, event) {
|
|
302
|
+
if (adapter.hookEvents && !adapter.hookEvents.includes(event)) {
|
|
303
|
+
throw new Error(`Agent ${adapter.agent} does not support ${event} hooks. Supported: ${adapter.hookEvents.join(', ')}.`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function resolveHookScope(adapter, scope) {
|
|
307
|
+
const resolvedScope = scope ?? getEffectiveAgentSettingsDefaultScopeSync();
|
|
308
|
+
const supportedScopes = adapter.hookScopes ?? ['global', 'project', 'local'];
|
|
309
|
+
if (!supportedScopes.includes(resolvedScope)) {
|
|
310
|
+
throw new Error(`Agent ${adapter.agent} hooks do not support ${resolvedScope} scope. Supported scopes: ${supportedScopes.join(', ')}.`);
|
|
311
|
+
}
|
|
312
|
+
return resolvedScope;
|
|
313
|
+
}
|
|
202
314
|
export class AgentSettingsManager {
|
|
203
315
|
getSupportedAgents() {
|
|
204
316
|
return getAgentSettingsAdapters().map(adapter => adapter.agent);
|
|
@@ -221,17 +333,34 @@ export class AgentSettingsManager {
|
|
|
221
333
|
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(', ')}`);
|
|
222
334
|
}
|
|
223
335
|
if (!key) {
|
|
224
|
-
const scope = options.scope
|
|
336
|
+
const scope = resolveFullReadScope(adapter, options.scope);
|
|
225
337
|
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath));
|
|
226
|
-
|
|
338
|
+
const config = await readConfigObject(adapter, path);
|
|
339
|
+
if (scope !== 'global') {
|
|
340
|
+
return config;
|
|
341
|
+
}
|
|
342
|
+
const globalConfigDefinitions = adapter.definitions.filter(definition => definition.store === 'globalConfig' && definition.scopes.includes('global'));
|
|
343
|
+
if (globalConfigDefinitions.length === 0) {
|
|
344
|
+
return config;
|
|
345
|
+
}
|
|
346
|
+
const globalConfigPath = adapter.getSettingsPath('global', resolveProjectPath(options.projectPath), globalConfigDefinitions[0]);
|
|
347
|
+
const globalConfig = await readConfigObject(adapter, globalConfigPath);
|
|
348
|
+
const result = { ...config };
|
|
349
|
+
for (const definition of globalConfigDefinitions) {
|
|
350
|
+
const value = getNestedValue(globalConfig, definition.nativePath);
|
|
351
|
+
if (value !== undefined) {
|
|
352
|
+
setNestedValue(result, definition.nativePath, value);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return result;
|
|
227
356
|
}
|
|
228
357
|
const definition = getAgentSettingDefinition(agent, key);
|
|
229
358
|
if (!definition) {
|
|
230
359
|
throw new Error(`Unknown ${agent} setting: ${key}.`);
|
|
231
360
|
}
|
|
232
361
|
const scope = resolveScope(definition, options.scope);
|
|
233
|
-
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath));
|
|
234
|
-
const config = await
|
|
362
|
+
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath), definition);
|
|
363
|
+
const config = await readConfigObject(adapter, path);
|
|
235
364
|
return getNestedValue(config, definition.nativePath);
|
|
236
365
|
}
|
|
237
366
|
async set(agent, key, rawValue, options = {}) {
|
|
@@ -244,13 +373,13 @@ export class AgentSettingsManager {
|
|
|
244
373
|
throw new Error(`Unknown ${agent} setting: ${key}.`);
|
|
245
374
|
}
|
|
246
375
|
const scope = resolveScope(definition, options.scope);
|
|
247
|
-
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath));
|
|
248
|
-
const config = await
|
|
376
|
+
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath), definition);
|
|
377
|
+
const config = await readConfigObject(adapter, path);
|
|
249
378
|
const previousValue = getNestedValue(config, definition.nativePath);
|
|
250
379
|
const value = parseAgentSettingValue(definition, rawValue, options.parseJson);
|
|
251
380
|
setNestedValue(config, definition.nativePath, value);
|
|
252
381
|
if (!options.dryRun) {
|
|
253
|
-
await
|
|
382
|
+
await writeConfigObject(adapter, path, config);
|
|
254
383
|
}
|
|
255
384
|
return {
|
|
256
385
|
agent,
|
|
@@ -272,12 +401,12 @@ export class AgentSettingsManager {
|
|
|
272
401
|
throw new Error(`Unknown ${agent} setting: ${key}.`);
|
|
273
402
|
}
|
|
274
403
|
const scope = resolveScope(definition, options.scope);
|
|
275
|
-
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath));
|
|
276
|
-
const config = await
|
|
404
|
+
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath), definition);
|
|
405
|
+
const config = await readConfigObject(adapter, path);
|
|
277
406
|
const previousValue = getNestedValue(config, definition.nativePath);
|
|
278
407
|
deleteNestedValue(config, definition.nativePath);
|
|
279
408
|
if (!options.dryRun) {
|
|
280
|
-
await
|
|
409
|
+
await writeConfigObject(adapter, path, config);
|
|
281
410
|
}
|
|
282
411
|
return {
|
|
283
412
|
agent,
|
|
@@ -293,14 +422,18 @@ export class AgentSettingsManager {
|
|
|
293
422
|
if (!adapter) {
|
|
294
423
|
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(', ')}`);
|
|
295
424
|
}
|
|
296
|
-
if (
|
|
425
|
+
if (!adapter.hookEvents) {
|
|
297
426
|
throw new Error(`Agent ${agent} does not support hook management.`);
|
|
298
427
|
}
|
|
299
|
-
const
|
|
428
|
+
const hookEvent = event ? normalizeHookEvent(event) : undefined;
|
|
429
|
+
if (hookEvent) {
|
|
430
|
+
assertHookEventSupported(adapter, hookEvent);
|
|
431
|
+
}
|
|
432
|
+
const scope = resolveHookScope(adapter, options.scope);
|
|
300
433
|
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath));
|
|
301
|
-
const config = await
|
|
302
|
-
if (
|
|
303
|
-
return getHookMatchers(config,
|
|
434
|
+
const config = await readConfigObject(adapter, path);
|
|
435
|
+
if (hookEvent) {
|
|
436
|
+
return getHookMatchers(config, hookEvent);
|
|
304
437
|
}
|
|
305
438
|
const hooks = getNestedValue(config, ['hooks']);
|
|
306
439
|
if (hooks === undefined) {
|
|
@@ -320,13 +453,14 @@ export class AgentSettingsManager {
|
|
|
320
453
|
if (!adapter) {
|
|
321
454
|
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(', ')}`);
|
|
322
455
|
}
|
|
323
|
-
if (
|
|
456
|
+
if (!adapter.hookEvents) {
|
|
324
457
|
throw new Error(`Agent ${agent} does not support hook management.`);
|
|
325
458
|
}
|
|
326
459
|
const hookEvent = normalizeHookEvent(event);
|
|
327
|
-
|
|
460
|
+
assertHookEventSupported(adapter, hookEvent);
|
|
461
|
+
const scope = resolveHookScope(adapter, options.scope);
|
|
328
462
|
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath));
|
|
329
|
-
const config = await
|
|
463
|
+
const config = await readConfigObject(adapter, path);
|
|
330
464
|
const hook = buildHookCommand(command, options.name);
|
|
331
465
|
const matchers = getHookMatchers(config, hookEvent);
|
|
332
466
|
const matcher = options.matcher ?? '*';
|
|
@@ -342,7 +476,7 @@ export class AgentSettingsManager {
|
|
|
342
476
|
}
|
|
343
477
|
setHookMatchers(config, hookEvent, matchers);
|
|
344
478
|
if (!options.dryRun) {
|
|
345
|
-
await
|
|
479
|
+
await writeConfigObject(adapter, path, config);
|
|
346
480
|
}
|
|
347
481
|
return {
|
|
348
482
|
agent,
|
|
@@ -358,13 +492,14 @@ export class AgentSettingsManager {
|
|
|
358
492
|
if (!adapter) {
|
|
359
493
|
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(', ')}`);
|
|
360
494
|
}
|
|
361
|
-
if (
|
|
495
|
+
if (!adapter.hookEvents) {
|
|
362
496
|
throw new Error(`Agent ${agent} does not support hook management.`);
|
|
363
497
|
}
|
|
364
498
|
const hookEvent = normalizeHookEvent(event);
|
|
365
|
-
|
|
499
|
+
assertHookEventSupported(adapter, hookEvent);
|
|
500
|
+
const scope = resolveHookScope(adapter, options.scope);
|
|
366
501
|
const path = adapter.getSettingsPath(scope, resolveProjectPath(options.projectPath));
|
|
367
|
-
const config = await
|
|
502
|
+
const config = await readConfigObject(adapter, path);
|
|
368
503
|
const matchers = getHookMatchers(config, hookEvent);
|
|
369
504
|
let removed = 0;
|
|
370
505
|
const nextMatchers = matchers
|
|
@@ -384,7 +519,7 @@ export class AgentSettingsManager {
|
|
|
384
519
|
.filter(entry => entry.hooks.length > 0);
|
|
385
520
|
setHookMatchers(config, hookEvent, nextMatchers);
|
|
386
521
|
if (!options.dryRun) {
|
|
387
|
-
await
|
|
522
|
+
await writeConfigObject(adapter, path, config);
|
|
388
523
|
}
|
|
389
524
|
return {
|
|
390
525
|
agent,
|
|
@@ -395,5 +530,64 @@ export class AgentSettingsManager {
|
|
|
395
530
|
dryRun: Boolean(options.dryRun),
|
|
396
531
|
};
|
|
397
532
|
}
|
|
533
|
+
async getApiKeyStatus(agent, apiKey, options = {}) {
|
|
534
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
535
|
+
if (!adapter) {
|
|
536
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(', ')}`);
|
|
537
|
+
}
|
|
538
|
+
if (agent !== 'claude') {
|
|
539
|
+
throw new Error(`Agent ${agent} does not support API key trust management.`);
|
|
540
|
+
}
|
|
541
|
+
const path = adapter.getSettingsPath('global', resolveProjectPath(options.projectPath), CLAUDE_API_KEY_RESPONSES_DEFINITION);
|
|
542
|
+
const config = await readConfigObject(adapter, path);
|
|
543
|
+
const fingerprint = normalizeApiKeyForConfig(apiKey);
|
|
544
|
+
const responses = getApiKeyResponses(config);
|
|
545
|
+
return {
|
|
546
|
+
agent,
|
|
547
|
+
path,
|
|
548
|
+
fingerprint,
|
|
549
|
+
status: getApiKeyStatusFromResponses(responses, fingerprint),
|
|
550
|
+
dryRun: false,
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
async updateApiKeyTrust(agent, action, apiKey, options = {}) {
|
|
554
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
555
|
+
if (!adapter) {
|
|
556
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(', ')}`);
|
|
557
|
+
}
|
|
558
|
+
if (agent !== 'claude') {
|
|
559
|
+
throw new Error(`Agent ${agent} does not support API key trust management.`);
|
|
560
|
+
}
|
|
561
|
+
const path = adapter.getSettingsPath('global', resolveProjectPath(options.projectPath), CLAUDE_API_KEY_RESPONSES_DEFINITION);
|
|
562
|
+
const config = await readConfigObject(adapter, path);
|
|
563
|
+
const fingerprint = normalizeApiKeyForConfig(apiKey);
|
|
564
|
+
const responses = getApiKeyResponses(config);
|
|
565
|
+
const previousStatus = getApiKeyStatusFromResponses(responses, fingerprint);
|
|
566
|
+
let approved = responses.approved.filter(value => value !== fingerprint);
|
|
567
|
+
let rejected = responses.rejected.filter(value => value !== fingerprint);
|
|
568
|
+
if (action === 'approve') {
|
|
569
|
+
approved = [...approved, fingerprint];
|
|
570
|
+
}
|
|
571
|
+
else if (action === 'reject') {
|
|
572
|
+
rejected = [...rejected, fingerprint];
|
|
573
|
+
}
|
|
574
|
+
const status = action === 'approve'
|
|
575
|
+
? 'approved'
|
|
576
|
+
: action === 'reject'
|
|
577
|
+
? 'rejected'
|
|
578
|
+
: 'unknown';
|
|
579
|
+
setApiKeyResponses(config, approved, rejected);
|
|
580
|
+
if (!options.dryRun) {
|
|
581
|
+
await writeConfigObject(adapter, path, config);
|
|
582
|
+
}
|
|
583
|
+
return {
|
|
584
|
+
agent,
|
|
585
|
+
path,
|
|
586
|
+
fingerprint,
|
|
587
|
+
status,
|
|
588
|
+
previousStatus,
|
|
589
|
+
dryRun: Boolean(options.dryRun),
|
|
590
|
+
};
|
|
591
|
+
}
|
|
398
592
|
}
|
|
399
593
|
//# sourceMappingURL=settingsManager.js.map
|