agentinit 1.22.1 → 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 +28 -0
- package/README.md +62 -0
- package/dist/agents/CodexCliAgent.js +1 -1
- package/dist/agents/CodexCliAgent.js.map +1 -1
- package/dist/cli.js +1747 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +391 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +55 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/core/agentSettings/adapters/claude.d.ts +3 -0
- package/dist/core/agentSettings/adapters/claude.d.ts.map +1 -0
- package/dist/core/agentSettings/adapters/claude.js +285 -0
- package/dist/core/agentSettings/adapters/claude.js.map +1 -0
- 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 +6 -0
- package/dist/core/agentSettings/registry.d.ts.map +1 -0
- package/dist/core/agentSettings/registry.js +24 -0
- package/dist/core/agentSettings/registry.js.map +1 -0
- package/dist/core/agentSettings/settingsManager.d.ts +14 -0
- package/dist/core/agentSettings/settingsManager.d.ts.map +1 -0
- package/dist/core/agentSettings/settingsManager.js +593 -0
- package/dist/core/agentSettings/settingsManager.js.map +1 -0
- package/dist/core/agentSettings/types.d.ts +113 -0
- package/dist/core/agentSettings/types.d.ts.map +1 -0
- package/dist/core/agentSettings/types.js +2 -0
- package/dist/core/agentSettings/types.js.map +1 -0
- package/dist/core/agentSettings/valueParser.d.ts +3 -0
- package/dist/core/agentSettings/valueParser.d.ts.map +1 -0
- package/dist/core/agentSettings/valueParser.js +80 -0
- package/dist/core/agentSettings/valueParser.js.map +1 -0
- package/dist/core/userConfig.d.ts +5 -0
- package/dist/core/userConfig.d.ts.map +1 -1
- package/dist/core/userConfig.js +33 -0
- package/dist/core/userConfig.js.map +1 -1
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -15070,7 +15070,7 @@ class CodexCliAgent extends Agent {
|
|
|
15070
15070
|
sse: false
|
|
15071
15071
|
},
|
|
15072
15072
|
rules: true,
|
|
15073
|
-
hooks:
|
|
15073
|
+
hooks: true,
|
|
15074
15074
|
commands: false,
|
|
15075
15075
|
subagents: false,
|
|
15076
15076
|
statusline: false,
|
|
@@ -16888,6 +16888,13 @@ function createDefaultUserConfig() {
|
|
|
16888
16888
|
verifiedGithubRepos: []
|
|
16889
16889
|
};
|
|
16890
16890
|
}
|
|
16891
|
+
function normalizeAgentSettingsDefaultScope(scope) {
|
|
16892
|
+
const normalized = scope.trim().toLowerCase();
|
|
16893
|
+
if (!AGENT_SETTINGS_SCOPES.has(normalized)) {
|
|
16894
|
+
throw new Error("Invalid agent settings default scope. Use global, project, or local.");
|
|
16895
|
+
}
|
|
16896
|
+
return normalized;
|
|
16897
|
+
}
|
|
16891
16898
|
function normalizeMarketplaceIdentifier(identifier) {
|
|
16892
16899
|
const normalized = identifier.trim().toLowerCase();
|
|
16893
16900
|
if (!MARKETPLACE_IDENTIFIER_PATTERN.test(normalized)) {
|
|
@@ -16959,8 +16966,17 @@ function sanitizeUserConfig(raw) {
|
|
|
16959
16966
|
defaultMarketplace = undefined;
|
|
16960
16967
|
}
|
|
16961
16968
|
}
|
|
16969
|
+
let defaultAgentSettingsScope;
|
|
16970
|
+
if (typeof parsed.defaultAgentSettingsScope === "string") {
|
|
16971
|
+
try {
|
|
16972
|
+
defaultAgentSettingsScope = normalizeAgentSettingsDefaultScope(parsed.defaultAgentSettingsScope);
|
|
16973
|
+
} catch {
|
|
16974
|
+
defaultAgentSettingsScope = undefined;
|
|
16975
|
+
}
|
|
16976
|
+
}
|
|
16962
16977
|
return {
|
|
16963
16978
|
...defaultMarketplace ? { defaultMarketplace } : {},
|
|
16979
|
+
...defaultAgentSettingsScope ? { defaultAgentSettingsScope } : {},
|
|
16964
16980
|
customMarketplaces,
|
|
16965
16981
|
verifiedGithubRepos
|
|
16966
16982
|
};
|
|
@@ -16993,6 +17009,19 @@ async function writeUserConfig(config) {
|
|
|
16993
17009
|
function getBuiltInVerifiedGithubRepos() {
|
|
16994
17010
|
return [...BUILTIN_VERIFIED_GITHUB_REPOS];
|
|
16995
17011
|
}
|
|
17012
|
+
function getConfiguredAgentSettingsDefaultScopeSync() {
|
|
17013
|
+
return readUserConfigSync().defaultAgentSettingsScope;
|
|
17014
|
+
}
|
|
17015
|
+
function getEffectiveAgentSettingsDefaultScopeSync() {
|
|
17016
|
+
const envScope = process.env.AGENTINIT_AGENT_DEFAULT_SCOPE;
|
|
17017
|
+
if (typeof envScope === "string") {
|
|
17018
|
+
try {
|
|
17019
|
+
return normalizeAgentSettingsDefaultScope(envScope);
|
|
17020
|
+
} catch {
|
|
17021
|
+
}
|
|
17022
|
+
}
|
|
17023
|
+
return getConfiguredAgentSettingsDefaultScopeSync() ?? "global";
|
|
17024
|
+
}
|
|
16996
17025
|
function getEffectiveVerifiedGithubReposSync() {
|
|
16997
17026
|
const repos = new Set(BUILTIN_VERIFIED_GITHUB_REPOS);
|
|
16998
17027
|
for (const repo of readUserConfigSync().verifiedGithubRepos) {
|
|
@@ -17004,7 +17033,7 @@ function isVerifiedGitHubRepoSync(owner, repo) {
|
|
|
17004
17033
|
const normalized = normalizeGitHubRepoRef(`${owner}/${repo}`);
|
|
17005
17034
|
return getEffectiveVerifiedGithubReposSync().includes(normalized);
|
|
17006
17035
|
}
|
|
17007
|
-
var sanitizeCustomMarketplaceConfig, MARKETPLACE_IDENTIFIER_PATTERN, GITHUB_REPO_PATTERN, GIT_REPO_URL_PATTERN, BUILTIN_VERIFIED_GITHUB_REPOS;
|
|
17036
|
+
var sanitizeCustomMarketplaceConfig, MARKETPLACE_IDENTIFIER_PATTERN, GITHUB_REPO_PATTERN, GIT_REPO_URL_PATTERN, BUILTIN_VERIFIED_GITHUB_REPOS, AGENT_SETTINGS_SCOPES;
|
|
17008
17037
|
var init_userConfig = __esm(() => {
|
|
17009
17038
|
init_fs();
|
|
17010
17039
|
sanitizeCustomMarketplaceConfig = function(entry) {
|
|
@@ -17027,6 +17056,7 @@ var init_userConfig = __esm(() => {
|
|
|
17027
17056
|
GITHUB_REPO_PATTERN = /^([A-Za-z0-9._-]+)\/([A-Za-z0-9._-]+)$/;
|
|
17028
17057
|
GIT_REPO_URL_PATTERN = /^(https?:\/\/|ssh:\/\/|git@).+/;
|
|
17029
17058
|
BUILTIN_VERIFIED_GITHUB_REPOS = ["openai/codex-plugin-cc"];
|
|
17059
|
+
AGENT_SETTINGS_SCOPES = new Set(["global", "project", "local"]);
|
|
17030
17060
|
});
|
|
17031
17061
|
|
|
17032
17062
|
// dist/core/marketplaceRegistry.js
|
|
@@ -27085,6 +27115,152 @@ var require_cross_spawn = __commonJS((exports, module) => {
|
|
|
27085
27115
|
module.exports._enoent = enoent;
|
|
27086
27116
|
});
|
|
27087
27117
|
|
|
27118
|
+
// node_modules/jsonc-parser/lib/umd/main.js
|
|
27119
|
+
var require_main = __commonJS((exports, module) => {
|
|
27120
|
+
(function(factory) {
|
|
27121
|
+
if (typeof module === "object" && typeof exports === "object") {
|
|
27122
|
+
var v = factory(__require, exports);
|
|
27123
|
+
if (v !== undefined)
|
|
27124
|
+
module.exports = v;
|
|
27125
|
+
} else if (typeof define === "function" && define.amd) {
|
|
27126
|
+
define(["require", "exports", "./impl/format", "./impl/edit", "./impl/scanner", "./impl/parser"], factory);
|
|
27127
|
+
}
|
|
27128
|
+
})(function(require2, exports2) {
|
|
27129
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
27130
|
+
exports2.applyEdits = exports2.modify = exports2.format = exports2.printParseErrorCode = exports2.ParseErrorCode = exports2.stripComments = exports2.visit = exports2.getNodeValue = exports2.getNodePath = exports2.findNodeAtOffset = exports2.findNodeAtLocation = exports2.parseTree = exports2.parse = exports2.getLocation = exports2.SyntaxKind = exports2.ScanError = exports2.createScanner = undefined;
|
|
27131
|
+
const formatter = require2("./impl/format");
|
|
27132
|
+
const edit = require2("./impl/edit");
|
|
27133
|
+
const scanner = require2("./impl/scanner");
|
|
27134
|
+
const parser = require2("./impl/parser");
|
|
27135
|
+
exports2.createScanner = scanner.createScanner;
|
|
27136
|
+
var ScanError;
|
|
27137
|
+
(function(ScanError2) {
|
|
27138
|
+
ScanError2[ScanError2["None"] = 0] = "None";
|
|
27139
|
+
ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
|
|
27140
|
+
ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
|
|
27141
|
+
ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
|
|
27142
|
+
ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
|
|
27143
|
+
ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
|
|
27144
|
+
ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
|
|
27145
|
+
})(ScanError || (exports2.ScanError = ScanError = {}));
|
|
27146
|
+
var SyntaxKind;
|
|
27147
|
+
(function(SyntaxKind2) {
|
|
27148
|
+
SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
|
|
27149
|
+
SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
|
|
27150
|
+
SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
|
|
27151
|
+
SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
|
|
27152
|
+
SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
|
|
27153
|
+
SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
|
|
27154
|
+
SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
|
|
27155
|
+
SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
|
|
27156
|
+
SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
|
|
27157
|
+
SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
|
|
27158
|
+
SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
|
|
27159
|
+
SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
|
|
27160
|
+
SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
|
|
27161
|
+
SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
|
|
27162
|
+
SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
|
|
27163
|
+
SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
|
|
27164
|
+
SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
|
|
27165
|
+
})(SyntaxKind || (exports2.SyntaxKind = SyntaxKind = {}));
|
|
27166
|
+
exports2.getLocation = parser.getLocation;
|
|
27167
|
+
exports2.parse = parser.parse;
|
|
27168
|
+
exports2.parseTree = parser.parseTree;
|
|
27169
|
+
exports2.findNodeAtLocation = parser.findNodeAtLocation;
|
|
27170
|
+
exports2.findNodeAtOffset = parser.findNodeAtOffset;
|
|
27171
|
+
exports2.getNodePath = parser.getNodePath;
|
|
27172
|
+
exports2.getNodeValue = parser.getNodeValue;
|
|
27173
|
+
exports2.visit = parser.visit;
|
|
27174
|
+
exports2.stripComments = parser.stripComments;
|
|
27175
|
+
var ParseErrorCode;
|
|
27176
|
+
(function(ParseErrorCode2) {
|
|
27177
|
+
ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
|
|
27178
|
+
ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
|
|
27179
|
+
ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
|
|
27180
|
+
ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
|
|
27181
|
+
ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
|
|
27182
|
+
ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
|
|
27183
|
+
ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
|
|
27184
|
+
ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
|
|
27185
|
+
ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
|
|
27186
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
|
|
27187
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
|
|
27188
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
|
|
27189
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
|
|
27190
|
+
ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
|
|
27191
|
+
ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
|
|
27192
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
|
|
27193
|
+
})(ParseErrorCode || (exports2.ParseErrorCode = ParseErrorCode = {}));
|
|
27194
|
+
function printParseErrorCode(code) {
|
|
27195
|
+
switch (code) {
|
|
27196
|
+
case 1:
|
|
27197
|
+
return "InvalidSymbol";
|
|
27198
|
+
case 2:
|
|
27199
|
+
return "InvalidNumberFormat";
|
|
27200
|
+
case 3:
|
|
27201
|
+
return "PropertyNameExpected";
|
|
27202
|
+
case 4:
|
|
27203
|
+
return "ValueExpected";
|
|
27204
|
+
case 5:
|
|
27205
|
+
return "ColonExpected";
|
|
27206
|
+
case 6:
|
|
27207
|
+
return "CommaExpected";
|
|
27208
|
+
case 7:
|
|
27209
|
+
return "CloseBraceExpected";
|
|
27210
|
+
case 8:
|
|
27211
|
+
return "CloseBracketExpected";
|
|
27212
|
+
case 9:
|
|
27213
|
+
return "EndOfFileExpected";
|
|
27214
|
+
case 10:
|
|
27215
|
+
return "InvalidCommentToken";
|
|
27216
|
+
case 11:
|
|
27217
|
+
return "UnexpectedEndOfComment";
|
|
27218
|
+
case 12:
|
|
27219
|
+
return "UnexpectedEndOfString";
|
|
27220
|
+
case 13:
|
|
27221
|
+
return "UnexpectedEndOfNumber";
|
|
27222
|
+
case 14:
|
|
27223
|
+
return "InvalidUnicode";
|
|
27224
|
+
case 15:
|
|
27225
|
+
return "InvalidEscapeCharacter";
|
|
27226
|
+
case 16:
|
|
27227
|
+
return "InvalidCharacter";
|
|
27228
|
+
}
|
|
27229
|
+
return "<unknown ParseErrorCode>";
|
|
27230
|
+
}
|
|
27231
|
+
exports2.printParseErrorCode = printParseErrorCode;
|
|
27232
|
+
function format(documentText, range, options2) {
|
|
27233
|
+
return formatter.format(documentText, range, options2);
|
|
27234
|
+
}
|
|
27235
|
+
exports2.format = format;
|
|
27236
|
+
function modify(text, path, value, options2) {
|
|
27237
|
+
return edit.setProperty(text, path, value, options2);
|
|
27238
|
+
}
|
|
27239
|
+
exports2.modify = modify;
|
|
27240
|
+
function applyEdits(text, edits) {
|
|
27241
|
+
let sortedEdits = edits.slice(0).sort((a, b) => {
|
|
27242
|
+
const diff = a.offset - b.offset;
|
|
27243
|
+
if (diff === 0) {
|
|
27244
|
+
return a.length - b.length;
|
|
27245
|
+
}
|
|
27246
|
+
return diff;
|
|
27247
|
+
});
|
|
27248
|
+
let lastModifiedOffset = text.length;
|
|
27249
|
+
for (let i = sortedEdits.length - 1;i >= 0; i--) {
|
|
27250
|
+
let e = sortedEdits[i];
|
|
27251
|
+
if (e.offset + e.length <= lastModifiedOffset) {
|
|
27252
|
+
text = edit.applyEdit(text, e);
|
|
27253
|
+
} else {
|
|
27254
|
+
throw new Error("Overlapping edit");
|
|
27255
|
+
}
|
|
27256
|
+
lastModifiedOffset = e.offset;
|
|
27257
|
+
}
|
|
27258
|
+
return text;
|
|
27259
|
+
}
|
|
27260
|
+
exports2.applyEdits = applyEdits;
|
|
27261
|
+
});
|
|
27262
|
+
});
|
|
27263
|
+
|
|
27088
27264
|
// node_modules/commander/esm.mjs
|
|
27089
27265
|
var import_ = __toESM(require_commander(), 1);
|
|
27090
27266
|
var {
|
|
@@ -42094,6 +42270,49 @@ function registerConfigCommand(program2) {
|
|
|
42094
42270
|
await writeUserConfig(sortConfig(configState));
|
|
42095
42271
|
logger.success("Cleared the configured default marketplace.");
|
|
42096
42272
|
});
|
|
42273
|
+
const agentSettings = config.command("agent-settings").description("Manage AgentInit defaults for agent settings commands");
|
|
42274
|
+
agentSettings.command("scope [scope]").description("Get or set the default scope used by `agentinit agent` when no scope flag is provided").action(async (scopeArg) => {
|
|
42275
|
+
logger.titleBox("AgentInit Configuration");
|
|
42276
|
+
try {
|
|
42277
|
+
if (!scopeArg) {
|
|
42278
|
+
const configState2 = await readUserConfig();
|
|
42279
|
+
const configuredScope = configState2.defaultAgentSettingsScope;
|
|
42280
|
+
const effectiveScope = getEffectiveAgentSettingsDefaultScopeSync();
|
|
42281
|
+
logger.info(`Effective default agent settings scope: ${cyan(effectiveScope)}`);
|
|
42282
|
+
if (configuredScope) {
|
|
42283
|
+
logger.info(`Configured in user config: ${cyan(configuredScope)}`);
|
|
42284
|
+
} else {
|
|
42285
|
+
logger.info("No user-configured agent settings scope. Built-in default is global.");
|
|
42286
|
+
}
|
|
42287
|
+
if (process.env.AGENTINIT_AGENT_DEFAULT_SCOPE !== undefined) {
|
|
42288
|
+
try {
|
|
42289
|
+
logger.info(`Environment override: ${cyan(normalizeAgentSettingsDefaultScope(process.env.AGENTINIT_AGENT_DEFAULT_SCOPE))}`);
|
|
42290
|
+
} catch {
|
|
42291
|
+
logger.info(`Invalid environment override ignored: ${cyan(process.env.AGENTINIT_AGENT_DEFAULT_SCOPE)}`);
|
|
42292
|
+
}
|
|
42293
|
+
}
|
|
42294
|
+
return;
|
|
42295
|
+
}
|
|
42296
|
+
const scope = normalizeAgentSettingsDefaultScope(scopeArg);
|
|
42297
|
+
const configState = await readUserConfig();
|
|
42298
|
+
configState.defaultAgentSettingsScope = scope;
|
|
42299
|
+
await writeUserConfig(sortConfig(configState));
|
|
42300
|
+
logger.success(`Set default agent settings scope to ${green(scope)}.`);
|
|
42301
|
+
} catch (error) {
|
|
42302
|
+
failConfigCommand(error);
|
|
42303
|
+
}
|
|
42304
|
+
});
|
|
42305
|
+
agentSettings.command("clear-scope").description("Clear the user-configured default scope used by `agentinit agent`").action(async () => {
|
|
42306
|
+
logger.titleBox("AgentInit Configuration");
|
|
42307
|
+
const configState = await readUserConfig();
|
|
42308
|
+
if (!configState.defaultAgentSettingsScope) {
|
|
42309
|
+
logger.info("No user-configured agent settings scope to clear.");
|
|
42310
|
+
return;
|
|
42311
|
+
}
|
|
42312
|
+
delete configState.defaultAgentSettingsScope;
|
|
42313
|
+
await writeUserConfig(sortConfig(configState));
|
|
42314
|
+
logger.success("Cleared the user-configured default agent settings scope.");
|
|
42315
|
+
});
|
|
42097
42316
|
const verifiedRepos = config.command("verified-repos").description("Manage exact verified GitHub repositories");
|
|
42098
42317
|
verifiedRepos.command("list").description("List verified GitHub repositories").action(async () => {
|
|
42099
42318
|
logger.titleBox("AgentInit Configuration");
|
|
@@ -45137,6 +45356,1531 @@ Dry run \u2014 no changes made.`));
|
|
|
45137
45356
|
});
|
|
45138
45357
|
}
|
|
45139
45358
|
|
|
45359
|
+
// dist/core/agentSettings/settingsManager.js
|
|
45360
|
+
var TOML4 = __toESM(require_toml(), 1);
|
|
45361
|
+
var import_jsonc_parser = __toESM(require_main(), 1);
|
|
45362
|
+
init_fs();
|
|
45363
|
+
init_userConfig();
|
|
45364
|
+
|
|
45365
|
+
// dist/core/agentSettings/valueParser.js
|
|
45366
|
+
var parseJsonValue = function(raw, key) {
|
|
45367
|
+
try {
|
|
45368
|
+
return JSON.parse(raw);
|
|
45369
|
+
} catch (error) {
|
|
45370
|
+
throw new Error(`Value for "${key}" is not valid JSON.`);
|
|
45371
|
+
}
|
|
45372
|
+
};
|
|
45373
|
+
function parseAgentSettingValue(definition, raw, parseJson = false) {
|
|
45374
|
+
switch (definition.valueType) {
|
|
45375
|
+
case "string":
|
|
45376
|
+
return raw;
|
|
45377
|
+
case "boolean": {
|
|
45378
|
+
const normalized = raw.trim().toLowerCase();
|
|
45379
|
+
if (TRUE_VALUES.has(normalized)) {
|
|
45380
|
+
return true;
|
|
45381
|
+
}
|
|
45382
|
+
if (FALSE_VALUES.has(normalized)) {
|
|
45383
|
+
return false;
|
|
45384
|
+
}
|
|
45385
|
+
throw new Error(`Value for "${definition.key}" must be one of: on, off, true, false, yes, no, 1, 0.`);
|
|
45386
|
+
}
|
|
45387
|
+
case "number": {
|
|
45388
|
+
const value = Number(raw);
|
|
45389
|
+
if (!Number.isFinite(value)) {
|
|
45390
|
+
throw new Error(`Value for "${definition.key}" must be a finite number.`);
|
|
45391
|
+
}
|
|
45392
|
+
return value;
|
|
45393
|
+
}
|
|
45394
|
+
case "positiveInteger": {
|
|
45395
|
+
const value = Number(raw);
|
|
45396
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
45397
|
+
throw new Error(`Value for "${definition.key}" must be a positive integer.`);
|
|
45398
|
+
}
|
|
45399
|
+
return value;
|
|
45400
|
+
}
|
|
45401
|
+
case "enum": {
|
|
45402
|
+
if (!definition.allowedValues?.includes(raw)) {
|
|
45403
|
+
throw new Error(`Value for "${definition.key}" must be one of: ${definition.allowedValues?.join(", ")}.`);
|
|
45404
|
+
}
|
|
45405
|
+
return raw;
|
|
45406
|
+
}
|
|
45407
|
+
case "booleanOrEnum": {
|
|
45408
|
+
const normalized = raw.trim().toLowerCase();
|
|
45409
|
+
if (TRUE_VALUES.has(normalized)) {
|
|
45410
|
+
return true;
|
|
45411
|
+
}
|
|
45412
|
+
if (FALSE_VALUES.has(normalized)) {
|
|
45413
|
+
return false;
|
|
45414
|
+
}
|
|
45415
|
+
if (definition.allowedValues?.includes(raw)) {
|
|
45416
|
+
return raw;
|
|
45417
|
+
}
|
|
45418
|
+
throw new Error(`Value for "${definition.key}" must be one of: on, off, true, false, yes, no, 1, 0, ${definition.allowedValues?.join(", ")}.`);
|
|
45419
|
+
}
|
|
45420
|
+
case "array": {
|
|
45421
|
+
if (parseJson) {
|
|
45422
|
+
const value = parseJsonValue(raw, definition.key);
|
|
45423
|
+
if (!Array.isArray(value)) {
|
|
45424
|
+
throw new Error(`JSON value for "${definition.key}" must be an array.`);
|
|
45425
|
+
}
|
|
45426
|
+
return value;
|
|
45427
|
+
}
|
|
45428
|
+
return [raw];
|
|
45429
|
+
}
|
|
45430
|
+
case "object": {
|
|
45431
|
+
if (!parseJson) {
|
|
45432
|
+
throw new Error(`Value for "${definition.key}" must be valid JSON. Use --value-json when setting it from the CLI.`);
|
|
45433
|
+
}
|
|
45434
|
+
const value = parseJsonValue(raw, definition.key);
|
|
45435
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
45436
|
+
throw new Error(`JSON value for "${definition.key}" must be an object.`);
|
|
45437
|
+
}
|
|
45438
|
+
return value;
|
|
45439
|
+
}
|
|
45440
|
+
}
|
|
45441
|
+
}
|
|
45442
|
+
var TRUE_VALUES = new Set(["true", "on", "yes", "1"]);
|
|
45443
|
+
var FALSE_VALUES = new Set(["false", "off", "no", "0"]);
|
|
45444
|
+
|
|
45445
|
+
// dist/core/agentSettings/adapters/claude.js
|
|
45446
|
+
init_paths();
|
|
45447
|
+
import {join as join12} from "path";
|
|
45448
|
+
var setting = function(key, valueType, title, description, options2 = {}) {
|
|
45449
|
+
const definition = {
|
|
45450
|
+
agent: "claude",
|
|
45451
|
+
key,
|
|
45452
|
+
nativePath: key.split("."),
|
|
45453
|
+
title,
|
|
45454
|
+
description,
|
|
45455
|
+
valueType,
|
|
45456
|
+
scopes: options2.scopes ?? ALL_SCOPES,
|
|
45457
|
+
defaultScope: options2.defaultScope ?? "global",
|
|
45458
|
+
category: options2.category ?? "settings",
|
|
45459
|
+
risk: options2.risk ?? "safe"
|
|
45460
|
+
};
|
|
45461
|
+
if (options2.allowedValues) {
|
|
45462
|
+
definition.allowedValues = options2.allowedValues;
|
|
45463
|
+
}
|
|
45464
|
+
if (options2.store) {
|
|
45465
|
+
definition.store = options2.store;
|
|
45466
|
+
}
|
|
45467
|
+
if (options2.deprecated !== undefined) {
|
|
45468
|
+
definition.deprecated = options2.deprecated;
|
|
45469
|
+
}
|
|
45470
|
+
if (options2.replacement) {
|
|
45471
|
+
definition.replacement = options2.replacement;
|
|
45472
|
+
}
|
|
45473
|
+
return definition;
|
|
45474
|
+
};
|
|
45475
|
+
var globalConfigSetting = function(key, valueType, title, description, options2 = {}) {
|
|
45476
|
+
return setting(key, valueType, title, description, {
|
|
45477
|
+
...options2,
|
|
45478
|
+
scopes: GLOBAL_CONFIG_SCOPES,
|
|
45479
|
+
defaultScope: "global",
|
|
45480
|
+
store: "globalConfig"
|
|
45481
|
+
});
|
|
45482
|
+
};
|
|
45483
|
+
var ALL_SCOPES = ["global", "project", "local"];
|
|
45484
|
+
var PERSONAL_SCOPES = ["global", "local"];
|
|
45485
|
+
var GLOBAL_CONFIG_SCOPES = ["global"];
|
|
45486
|
+
var CLAUDE_HOOK_EVENTS = [
|
|
45487
|
+
"PreToolUse",
|
|
45488
|
+
"PostToolUse",
|
|
45489
|
+
"PostToolUseFailure",
|
|
45490
|
+
"Notification",
|
|
45491
|
+
"PermissionRequest",
|
|
45492
|
+
"Stop",
|
|
45493
|
+
"SessionStart",
|
|
45494
|
+
"SessionEnd"
|
|
45495
|
+
];
|
|
45496
|
+
var THEME_VALUES = ["auto", "dark", "light", "light-daltonized", "dark-daltonized", "light-ansi", "dark-ansi"];
|
|
45497
|
+
var NOTIFICATION_CHANNELS = ["auto", "iterm2", "iterm2_with_bell", "terminal_bell", "kitty", "ghostty", "notifications_disabled"];
|
|
45498
|
+
var TEAMMATE_MODES = ["auto", "tmux", "in-process"];
|
|
45499
|
+
var claudeSettingsAdapter = {
|
|
45500
|
+
agent: "claude",
|
|
45501
|
+
displayName: "Claude Code",
|
|
45502
|
+
hookEvents: CLAUDE_HOOK_EVENTS,
|
|
45503
|
+
hookScopes: ALL_SCOPES,
|
|
45504
|
+
definitions: [
|
|
45505
|
+
globalConfigSetting("theme", "enum", "Theme", "Claude Code UI color theme.", {
|
|
45506
|
+
allowedValues: THEME_VALUES,
|
|
45507
|
+
category: "ui"
|
|
45508
|
+
}),
|
|
45509
|
+
globalConfigSetting("editorMode", "enum", "Editor mode", "Keyboard editing mode.", {
|
|
45510
|
+
allowedValues: ["normal", "vim"],
|
|
45511
|
+
category: "ui"
|
|
45512
|
+
}),
|
|
45513
|
+
globalConfigSetting("verbose", "boolean", "Verbose output", "Show detailed debug output.", {
|
|
45514
|
+
category: "runtime"
|
|
45515
|
+
}),
|
|
45516
|
+
globalConfigSetting("preferredNotifChannel", "enum", "Notification channel", "Preferred local notification delivery method.", {
|
|
45517
|
+
allowedValues: NOTIFICATION_CHANNELS,
|
|
45518
|
+
category: "notifications"
|
|
45519
|
+
}),
|
|
45520
|
+
globalConfigSetting("autoCompactEnabled", "boolean", "Auto compact", "Auto-compact conversation context when it gets full.", {
|
|
45521
|
+
category: "runtime"
|
|
45522
|
+
}),
|
|
45523
|
+
globalConfigSetting("fileCheckpointingEnabled", "boolean", "File checkpointing", "Enable code rewind checkpoint snapshots.", {
|
|
45524
|
+
category: "runtime"
|
|
45525
|
+
}),
|
|
45526
|
+
globalConfigSetting("showTurnDuration", "boolean", "Turn duration", "Show how long Claude spent on each turn.", {
|
|
45527
|
+
category: "ui"
|
|
45528
|
+
}),
|
|
45529
|
+
globalConfigSetting("terminalProgressBarEnabled", "boolean", "Terminal progress bar", "Show terminal progress in supported terminals.", {
|
|
45530
|
+
category: "ui"
|
|
45531
|
+
}),
|
|
45532
|
+
globalConfigSetting("todoFeatureEnabled", "boolean", "Todo feature", "Enable Claude todo and task tracking.", {
|
|
45533
|
+
category: "ui"
|
|
45534
|
+
}),
|
|
45535
|
+
globalConfigSetting("teammateMode", "enum", "Teammate mode", "Control how Claude spawns teammate agents.", {
|
|
45536
|
+
allowedValues: TEAMMATE_MODES,
|
|
45537
|
+
category: "agents"
|
|
45538
|
+
}),
|
|
45539
|
+
globalConfigSetting("autoConnectIde", "boolean", "Auto-connect IDE", "Auto-connect to an IDE from external terminals.", {
|
|
45540
|
+
category: "ide"
|
|
45541
|
+
}),
|
|
45542
|
+
globalConfigSetting("autoInstallIdeExtension", "boolean", "Auto-install IDE extension", "Auto-install the IDE extension when supported.", {
|
|
45543
|
+
category: "ide"
|
|
45544
|
+
}),
|
|
45545
|
+
globalConfigSetting("diffTool", "enum", "Diff tool", "Choose where diffs are shown.", {
|
|
45546
|
+
allowedValues: ["terminal", "auto"],
|
|
45547
|
+
category: "ide"
|
|
45548
|
+
}),
|
|
45549
|
+
globalConfigSetting("respectGitignore", "boolean", "Respect gitignore", "Hide gitignored files from Claude file pickers.", {
|
|
45550
|
+
category: "ui"
|
|
45551
|
+
}),
|
|
45552
|
+
globalConfigSetting("copyFullResponse", "boolean", "Copy full response", "Copy full responses without the copy picker flow.", {
|
|
45553
|
+
category: "ui"
|
|
45554
|
+
}),
|
|
45555
|
+
globalConfigSetting("copyOnSelect", "boolean", "Copy on select", "Copy selected text automatically in fullscreen mode.", {
|
|
45556
|
+
category: "ui"
|
|
45557
|
+
}),
|
|
45558
|
+
globalConfigSetting("remoteControlAtStartup", "boolean", "Remote control at startup", "Enable Remote Control for new Claude sessions. Unset to restore Claude defaults.", {
|
|
45559
|
+
category: "remote-control"
|
|
45560
|
+
}),
|
|
45561
|
+
globalConfigSetting("taskCompleteNotifEnabled", "boolean", "Task complete push notifications", "Push when Claude finishes and becomes idle.", {
|
|
45562
|
+
category: "notifications"
|
|
45563
|
+
}),
|
|
45564
|
+
globalConfigSetting("inputNeededNotifEnabled", "boolean", "Input needed push notifications", "Push when Claude needs user input.", {
|
|
45565
|
+
category: "notifications"
|
|
45566
|
+
}),
|
|
45567
|
+
globalConfigSetting("agentPushNotifEnabled", "boolean", "Agent push notifications", "Allow Claude to decide when to send push notifications.", {
|
|
45568
|
+
category: "notifications"
|
|
45569
|
+
}),
|
|
45570
|
+
globalConfigSetting("showStatusInTerminalTab", "boolean", "Terminal tab status", "Show Claude status in the terminal tab status area.", {
|
|
45571
|
+
category: "ui"
|
|
45572
|
+
}),
|
|
45573
|
+
globalConfigSetting("prStatusFooterEnabled", "boolean", "PR status footer", "Show pull request status in Claude footer.", {
|
|
45574
|
+
category: "git"
|
|
45575
|
+
}),
|
|
45576
|
+
globalConfigSetting("claudeInChromeDefaultEnabled", "boolean", "Claude in Chrome default", "Enable Claude in Chrome by default.", {
|
|
45577
|
+
category: "browser"
|
|
45578
|
+
}),
|
|
45579
|
+
globalConfigSetting("teammateDefaultModel", "string", "Teammate default model", "Default model for spawned teammate agents.", {
|
|
45580
|
+
category: "agents"
|
|
45581
|
+
}),
|
|
45582
|
+
setting("model", "string", "Model", "Override the default Claude Code model.", {
|
|
45583
|
+
defaultScope: "global",
|
|
45584
|
+
category: "model"
|
|
45585
|
+
}),
|
|
45586
|
+
setting("agent", "string", "Agent", "Run the main thread as a named Claude subagent.", {
|
|
45587
|
+
category: "model"
|
|
45588
|
+
}),
|
|
45589
|
+
setting("env", "object", "Environment", "Environment variables applied to every Claude Code session.", {
|
|
45590
|
+
category: "runtime"
|
|
45591
|
+
}),
|
|
45592
|
+
setting("permissions.allow", "array", "Allowed permissions", "Permission rules to allow.", {
|
|
45593
|
+
category: "permissions"
|
|
45594
|
+
}),
|
|
45595
|
+
setting("permissions.deny", "array", "Denied permissions", "Permission rules to deny.", {
|
|
45596
|
+
category: "permissions"
|
|
45597
|
+
}),
|
|
45598
|
+
setting("permissions.ask", "array", "Ask permissions", "Permission rules that require confirmation.", {
|
|
45599
|
+
category: "permissions"
|
|
45600
|
+
}),
|
|
45601
|
+
setting("permissions.defaultMode", "enum", "Default permission mode", "Default permission mode when opening Claude Code.", {
|
|
45602
|
+
allowedValues: ["default", "acceptEdits", "plan", "dontAsk"],
|
|
45603
|
+
category: "permissions",
|
|
45604
|
+
risk: "security-sensitive"
|
|
45605
|
+
}),
|
|
45606
|
+
setting("permissions.disableBypassPermissionsMode", "enum", "Disable bypass permissions mode", "Disable Claude bypass-permissions mode.", {
|
|
45607
|
+
allowedValues: ["disable"],
|
|
45608
|
+
category: "permissions",
|
|
45609
|
+
risk: "security-sensitive"
|
|
45610
|
+
}),
|
|
45611
|
+
setting("permissions.additionalDirectories", "array", "Additional directories", "Additional working directories for file access.", {
|
|
45612
|
+
category: "permissions"
|
|
45613
|
+
}),
|
|
45614
|
+
setting("worktree.symlinkDirectories", "array", "Worktree symlink directories", "Directories to symlink into Claude Code worktrees.", {
|
|
45615
|
+
category: "worktree"
|
|
45616
|
+
}),
|
|
45617
|
+
setting("worktree.sparsePaths", "array", "Worktree sparse paths", "Paths to check out via sparse checkout in Claude Code worktrees.", {
|
|
45618
|
+
category: "worktree"
|
|
45619
|
+
}),
|
|
45620
|
+
setting("plansDirectory", "string", "Plans directory", "Directory where Claude Code stores plan files.", {
|
|
45621
|
+
category: "runtime"
|
|
45622
|
+
}),
|
|
45623
|
+
setting("autoMemoryDirectory", "string", "Auto memory directory", "Custom directory for Claude Code auto memory storage.", {
|
|
45624
|
+
scopes: PERSONAL_SCOPES,
|
|
45625
|
+
defaultScope: "global",
|
|
45626
|
+
category: "memory"
|
|
45627
|
+
}),
|
|
45628
|
+
setting("autoMemoryEnabled", "boolean", "Auto memory", "Enable automatic memory capture.", {
|
|
45629
|
+
defaultScope: "global",
|
|
45630
|
+
category: "memory"
|
|
45631
|
+
}),
|
|
45632
|
+
setting("autoDreamEnabled", "boolean", "Auto dream", "Enable background memory consolidation.", {
|
|
45633
|
+
defaultScope: "global",
|
|
45634
|
+
category: "memory"
|
|
45635
|
+
}),
|
|
45636
|
+
setting("alwaysThinkingEnabled", "boolean", "Always thinking", "Enable extended thinking by default for Claude Code sessions.", {
|
|
45637
|
+
defaultScope: "global",
|
|
45638
|
+
category: "model"
|
|
45639
|
+
}),
|
|
45640
|
+
setting("effortLevel", "enum", "Effort level", "Persist Claude Code effort level across sessions.", {
|
|
45641
|
+
allowedValues: ["low", "medium", "high", "xhigh"],
|
|
45642
|
+
defaultScope: "global",
|
|
45643
|
+
category: "model"
|
|
45644
|
+
}),
|
|
45645
|
+
setting("prefersReducedMotion", "boolean", "Reduced motion", "Reduce or disable Claude Code UI animations.", {
|
|
45646
|
+
defaultScope: "global",
|
|
45647
|
+
category: "ui"
|
|
45648
|
+
}),
|
|
45649
|
+
setting("attribution", "object", "Attribution", "Customize Claude Code git commit and pull request attribution.", {
|
|
45650
|
+
defaultScope: "global",
|
|
45651
|
+
category: "git"
|
|
45652
|
+
}),
|
|
45653
|
+
setting("includeGitInstructions", "boolean", "Git instructions", "Include built-in git workflow instructions in Claude Code context.", {
|
|
45654
|
+
defaultScope: "global",
|
|
45655
|
+
category: "git"
|
|
45656
|
+
}),
|
|
45657
|
+
setting("cleanupPeriodDays", "number", "Cleanup period", "Delete session files older than this many days at startup.", {
|
|
45658
|
+
defaultScope: "global",
|
|
45659
|
+
category: "runtime"
|
|
45660
|
+
}),
|
|
45661
|
+
setting("showThinkingSummaries", "boolean", "Thinking summaries", "Show extended thinking summaries in interactive sessions.", {
|
|
45662
|
+
defaultScope: "global",
|
|
45663
|
+
category: "ui"
|
|
45664
|
+
}),
|
|
45665
|
+
setting("spinnerTipsEnabled", "boolean", "Spinner tips", "Show or hide tips while Claude Code is working.", {
|
|
45666
|
+
defaultScope: "global",
|
|
45667
|
+
category: "ui"
|
|
45668
|
+
}),
|
|
45669
|
+
setting("autoUpdatesChannel", "enum", "Auto updates channel", "Claude Code release channel for automatic updates.", {
|
|
45670
|
+
allowedValues: ["stable", "latest"],
|
|
45671
|
+
defaultScope: "global",
|
|
45672
|
+
category: "runtime"
|
|
45673
|
+
}),
|
|
45674
|
+
setting("language", "string", "Language", "Preferred language for Claude responses and voice dictation.", {
|
|
45675
|
+
defaultScope: "global",
|
|
45676
|
+
category: "ui"
|
|
45677
|
+
}),
|
|
45678
|
+
setting("outputStyle", "string", "Output style", "Claude response output style.", {
|
|
45679
|
+
defaultScope: "global",
|
|
45680
|
+
category: "ui"
|
|
45681
|
+
}),
|
|
45682
|
+
setting("defaultView", "enum", "Default view", "Default Claude view. Unset to restore Claude defaults.", {
|
|
45683
|
+
allowedValues: ["transcript", "chat"],
|
|
45684
|
+
category: "ui"
|
|
45685
|
+
}),
|
|
45686
|
+
setting("useAutoModeDuringPlan", "boolean", "Use auto mode during plan", "Allow auto permission mode during plan mode.", {
|
|
45687
|
+
scopes: PERSONAL_SCOPES,
|
|
45688
|
+
defaultScope: "global",
|
|
45689
|
+
category: "permissions",
|
|
45690
|
+
risk: "security-sensitive"
|
|
45691
|
+
}),
|
|
45692
|
+
setting("includeCoAuthoredBy", "boolean", "Include co-authored-by", "Deprecated Claude Code attribution toggle.", {
|
|
45693
|
+
defaultScope: "global",
|
|
45694
|
+
category: "git",
|
|
45695
|
+
risk: "deprecated",
|
|
45696
|
+
deprecated: true,
|
|
45697
|
+
replacement: "attribution"
|
|
45698
|
+
}),
|
|
45699
|
+
setting("enableAllProjectMcpServers", "boolean", "Enable all project MCP servers", "Automatically approve project .mcp.json servers.", {
|
|
45700
|
+
category: "mcp",
|
|
45701
|
+
risk: "security-sensitive"
|
|
45702
|
+
}),
|
|
45703
|
+
setting("enabledMcpjsonServers", "array", "Enabled MCP JSON servers", "Specific project .mcp.json servers to approve.", {
|
|
45704
|
+
category: "mcp"
|
|
45705
|
+
}),
|
|
45706
|
+
setting("disabledMcpjsonServers", "array", "Disabled MCP JSON servers", "Specific project .mcp.json servers to reject.", {
|
|
45707
|
+
category: "mcp"
|
|
45708
|
+
}),
|
|
45709
|
+
setting("skipDangerousModePermissionPrompt", "boolean", "Skip dangerous mode prompt", "Skip confirmation before bypass permissions mode.", {
|
|
45710
|
+
scopes: PERSONAL_SCOPES,
|
|
45711
|
+
defaultScope: "global",
|
|
45712
|
+
category: "permissions",
|
|
45713
|
+
risk: "security-sensitive"
|
|
45714
|
+
})
|
|
45715
|
+
],
|
|
45716
|
+
getSettingsPath(scope, projectPath, definition) {
|
|
45717
|
+
if (definition?.store === "globalConfig") {
|
|
45718
|
+
return expandTilde("~/.claude.json");
|
|
45719
|
+
}
|
|
45720
|
+
switch (scope) {
|
|
45721
|
+
case "global":
|
|
45722
|
+
return expandTilde("~/.claude/settings.json");
|
|
45723
|
+
case "project":
|
|
45724
|
+
return join12(projectPath, ".claude", "settings.json");
|
|
45725
|
+
case "local":
|
|
45726
|
+
return join12(projectPath, ".claude", "settings.local.json");
|
|
45727
|
+
}
|
|
45728
|
+
}
|
|
45729
|
+
};
|
|
45730
|
+
|
|
45731
|
+
// dist/core/agentSettings/adapters/codex.js
|
|
45732
|
+
init_paths();
|
|
45733
|
+
import {join as join13} from "path";
|
|
45734
|
+
var setting2 = function(key, valueType, title, description, options2 = {}) {
|
|
45735
|
+
const definition = {
|
|
45736
|
+
agent: "codex",
|
|
45737
|
+
key,
|
|
45738
|
+
nativePath: key.split("."),
|
|
45739
|
+
title,
|
|
45740
|
+
description,
|
|
45741
|
+
valueType,
|
|
45742
|
+
scopes: options2.scopes ?? ALL_SCOPES2,
|
|
45743
|
+
defaultScope: options2.defaultScope ?? "global",
|
|
45744
|
+
category: options2.category ?? "settings",
|
|
45745
|
+
risk: options2.risk ?? "safe"
|
|
45746
|
+
};
|
|
45747
|
+
if (options2.allowedValues) {
|
|
45748
|
+
definition.allowedValues = options2.allowedValues;
|
|
45749
|
+
}
|
|
45750
|
+
if (options2.deprecated !== undefined) {
|
|
45751
|
+
definition.deprecated = options2.deprecated;
|
|
45752
|
+
}
|
|
45753
|
+
if (options2.replacement) {
|
|
45754
|
+
definition.replacement = options2.replacement;
|
|
45755
|
+
}
|
|
45756
|
+
return definition;
|
|
45757
|
+
};
|
|
45758
|
+
var featureSetting = function(key, title, description, options2 = {}) {
|
|
45759
|
+
return setting2(`features.${key}`, "boolean", title, description, {
|
|
45760
|
+
...options2,
|
|
45761
|
+
category: "features"
|
|
45762
|
+
});
|
|
45763
|
+
};
|
|
45764
|
+
var ALL_SCOPES2 = ["global", "project"];
|
|
45765
|
+
var CODEX_HOOK_EVENTS = [
|
|
45766
|
+
"PreToolUse",
|
|
45767
|
+
"PermissionRequest",
|
|
45768
|
+
"PostToolUse",
|
|
45769
|
+
"SessionStart",
|
|
45770
|
+
"UserPromptSubmit",
|
|
45771
|
+
"Stop"
|
|
45772
|
+
];
|
|
45773
|
+
var codexSettingsAdapter = {
|
|
45774
|
+
agent: "codex",
|
|
45775
|
+
displayName: "OpenAI Codex CLI",
|
|
45776
|
+
format: "toml",
|
|
45777
|
+
hookEvents: CODEX_HOOK_EVENTS,
|
|
45778
|
+
hookScopes: ALL_SCOPES2,
|
|
45779
|
+
definitions: [
|
|
45780
|
+
setting2("model", "string", "Model", "Override the default Codex model.", {
|
|
45781
|
+
category: "model"
|
|
45782
|
+
}),
|
|
45783
|
+
setting2("model_provider", "string", "Model provider", "Select a configured model provider.", {
|
|
45784
|
+
category: "model"
|
|
45785
|
+
}),
|
|
45786
|
+
setting2("model_reasoning_effort", "enum", "Reasoning effort", "Reasoning effort for supported models.", {
|
|
45787
|
+
allowedValues: ["minimal", "low", "medium", "high"],
|
|
45788
|
+
category: "model"
|
|
45789
|
+
}),
|
|
45790
|
+
setting2("approval_policy", "enum", "Approval policy", "Control when Codex asks for approval before running commands.", {
|
|
45791
|
+
allowedValues: ["untrusted", "on-failure", "on-request", "never"],
|
|
45792
|
+
category: "permissions",
|
|
45793
|
+
risk: "security-sensitive"
|
|
45794
|
+
}),
|
|
45795
|
+
setting2("sandbox_mode", "enum", "Sandbox mode", "Control Codex command sandboxing.", {
|
|
45796
|
+
allowedValues: ["read-only", "workspace-write", "danger-full-access"],
|
|
45797
|
+
category: "permissions",
|
|
45798
|
+
risk: "security-sensitive"
|
|
45799
|
+
}),
|
|
45800
|
+
setting2("web_search", "enum", "Web search", "Top-level Codex web search mode.", {
|
|
45801
|
+
allowedValues: ["live", "cached", "disabled"],
|
|
45802
|
+
category: "tools"
|
|
45803
|
+
}),
|
|
45804
|
+
setting2("notify", "array", "Notifications", "Program arguments for a notification command run after agent turns.", {
|
|
45805
|
+
category: "notifications"
|
|
45806
|
+
}),
|
|
45807
|
+
setting2("instructions", "string", "Instructions", "Additional user instructions for Codex.", {
|
|
45808
|
+
category: "runtime"
|
|
45809
|
+
}),
|
|
45810
|
+
setting2("model_instructions_file", "string", "Model instructions file", "Path to a model instructions file for Codex.", {
|
|
45811
|
+
category: "runtime"
|
|
45812
|
+
}),
|
|
45813
|
+
featureSetting("apps", "Apps", "Enable ChatGPT Apps/connectors support.", {
|
|
45814
|
+
risk: "risky"
|
|
45815
|
+
}),
|
|
45816
|
+
featureSetting("codex_hooks", "Codex hooks", "Enable lifecycle hooks from hooks.json or inline [hooks]."),
|
|
45817
|
+
featureSetting("fast_mode", "Fast mode", 'Enable Fast mode selection and the service_tier = "fast" path.'),
|
|
45818
|
+
featureSetting("memories", "Memories", "Enable Codex Memories."),
|
|
45819
|
+
featureSetting("multi_agent", "Multi-agent", "Enable subagent collaboration tools."),
|
|
45820
|
+
featureSetting("personality", "Personality", "Enable personality selection controls."),
|
|
45821
|
+
featureSetting("shell_snapshot", "Shell snapshot", "Snapshot your shell environment to speed up repeated commands."),
|
|
45822
|
+
featureSetting("shell_tool", "Shell tool", "Enable the default shell tool."),
|
|
45823
|
+
featureSetting("unified_exec", "Unified exec", "Use the unified PTY-backed exec tool."),
|
|
45824
|
+
featureSetting("undo", "Undo", "Enable undo via per-turn git ghost snapshots."),
|
|
45825
|
+
featureSetting("web_search", "Legacy web search feature", "Deprecated legacy web search feature toggle; prefer top-level web_search.", {
|
|
45826
|
+
risk: "deprecated",
|
|
45827
|
+
deprecated: true,
|
|
45828
|
+
replacement: "web_search"
|
|
45829
|
+
}),
|
|
45830
|
+
featureSetting("web_search_cached", "Legacy cached web search", 'Deprecated legacy toggle that maps to web_search = "cached" when unset.', {
|
|
45831
|
+
risk: "deprecated",
|
|
45832
|
+
deprecated: true,
|
|
45833
|
+
replacement: "web_search"
|
|
45834
|
+
}),
|
|
45835
|
+
featureSetting("web_search_request", "Legacy live web search", 'Deprecated legacy toggle that maps to web_search = "live" when unset.', {
|
|
45836
|
+
risk: "deprecated",
|
|
45837
|
+
deprecated: true,
|
|
45838
|
+
replacement: "web_search"
|
|
45839
|
+
})
|
|
45840
|
+
],
|
|
45841
|
+
getSettingsPath(scope, projectPath) {
|
|
45842
|
+
switch (scope) {
|
|
45843
|
+
case "global":
|
|
45844
|
+
return expandTilde("~/.codex/config.toml");
|
|
45845
|
+
case "project":
|
|
45846
|
+
return join13(projectPath, ".codex", "config.toml");
|
|
45847
|
+
case "local":
|
|
45848
|
+
return join13(projectPath, ".codex", "config.toml");
|
|
45849
|
+
}
|
|
45850
|
+
}
|
|
45851
|
+
};
|
|
45852
|
+
|
|
45853
|
+
// dist/core/agentSettings/adapters/opencode.js
|
|
45854
|
+
init_paths();
|
|
45855
|
+
import {existsSync as existsSync3} from "fs";
|
|
45856
|
+
import {join as join14} from "path";
|
|
45857
|
+
var firstExistingPath = function(paths9, fallback2) {
|
|
45858
|
+
return paths9.find((candidate) => existsSync3(candidate)) ?? fallback2;
|
|
45859
|
+
};
|
|
45860
|
+
var setting3 = function(key, valueType, title, description, options2 = {}) {
|
|
45861
|
+
const definition = {
|
|
45862
|
+
agent: "opencode",
|
|
45863
|
+
key,
|
|
45864
|
+
nativePath: options2.nativePath ?? key.split("."),
|
|
45865
|
+
title,
|
|
45866
|
+
description,
|
|
45867
|
+
valueType,
|
|
45868
|
+
scopes: options2.scopes ?? SUPPORTED_SCOPES,
|
|
45869
|
+
defaultScope: options2.defaultScope ?? "global",
|
|
45870
|
+
category: options2.category ?? "settings",
|
|
45871
|
+
risk: options2.risk ?? "safe"
|
|
45872
|
+
};
|
|
45873
|
+
if (options2.allowedValues) {
|
|
45874
|
+
definition.allowedValues = options2.allowedValues;
|
|
45875
|
+
}
|
|
45876
|
+
if (options2.deprecated !== undefined) {
|
|
45877
|
+
definition.deprecated = options2.deprecated;
|
|
45878
|
+
}
|
|
45879
|
+
if (options2.replacement) {
|
|
45880
|
+
definition.replacement = options2.replacement;
|
|
45881
|
+
}
|
|
45882
|
+
return definition;
|
|
45883
|
+
};
|
|
45884
|
+
var SUPPORTED_SCOPES = ["global", "project"];
|
|
45885
|
+
var PERMISSION_ACTIONS = ["allow", "ask", "deny"];
|
|
45886
|
+
var opencodeSettingsAdapter = {
|
|
45887
|
+
agent: "opencode",
|
|
45888
|
+
displayName: "OpenCode",
|
|
45889
|
+
format: "jsonc",
|
|
45890
|
+
definitions: [
|
|
45891
|
+
setting3("model", "string", "Model", "Default model identifier in provider/model format (e.g. anthropic/claude-sonnet-4-5).", {
|
|
45892
|
+
category: "model"
|
|
45893
|
+
}),
|
|
45894
|
+
setting3("small_model", "string", "Small model", "Small model used for tasks such as title generation, in provider/model format.", {
|
|
45895
|
+
category: "model"
|
|
45896
|
+
}),
|
|
45897
|
+
setting3("provider", "object", "Providers", "Custom OpenCode provider configurations and model overrides.", {
|
|
45898
|
+
category: "provider",
|
|
45899
|
+
risk: "security-sensitive"
|
|
45900
|
+
}),
|
|
45901
|
+
setting3("default_agent", "string", "Default agent", "Default primary agent to use when none is specified.", {
|
|
45902
|
+
category: "agent"
|
|
45903
|
+
}),
|
|
45904
|
+
setting3("autoupdate", "booleanOrEnum", "Auto update", "Control automatic updates: true, false, or notify.", {
|
|
45905
|
+
allowedValues: ["notify"],
|
|
45906
|
+
scopes: ["global"],
|
|
45907
|
+
defaultScope: "global",
|
|
45908
|
+
category: "runtime"
|
|
45909
|
+
}),
|
|
45910
|
+
setting3("shell", "string", "Shell", "Default shell to use for terminal and bash tool execution.", {
|
|
45911
|
+
category: "runtime"
|
|
45912
|
+
}),
|
|
45913
|
+
setting3("share", "enum", "Share", "Control sharing behavior: manual, auto, or disabled.", {
|
|
45914
|
+
allowedValues: ["manual", "auto", "disabled"],
|
|
45915
|
+
category: "sharing"
|
|
45916
|
+
}),
|
|
45917
|
+
setting3("username", "string", "Username", "Custom username displayed in conversations instead of system username.", {
|
|
45918
|
+
category: "ui"
|
|
45919
|
+
}),
|
|
45920
|
+
setting3("logLevel", "enum", "Log level", "Log verbosity level.", {
|
|
45921
|
+
allowedValues: ["DEBUG", "INFO", "WARN", "ERROR"],
|
|
45922
|
+
category: "runtime"
|
|
45923
|
+
}),
|
|
45924
|
+
setting3("snapshot", "boolean", "Snapshot tracking", "Enable or disable filesystem snapshot tracking for undo/redo.", {
|
|
45925
|
+
category: "runtime"
|
|
45926
|
+
}),
|
|
45927
|
+
setting3("permission.*", "enum", "Default permission", "Fallback permission rule for all tools: allow, ask, or deny.", {
|
|
45928
|
+
nativePath: ["permission", "*"],
|
|
45929
|
+
category: "permissions",
|
|
45930
|
+
risk: "security-sensitive",
|
|
45931
|
+
allowedValues: PERMISSION_ACTIONS
|
|
45932
|
+
}),
|
|
45933
|
+
setting3("permission.bash", "enum", "Bash permission", "Permission rule for shell command execution.", {
|
|
45934
|
+
category: "permissions",
|
|
45935
|
+
risk: "security-sensitive",
|
|
45936
|
+
allowedValues: PERMISSION_ACTIONS
|
|
45937
|
+
}),
|
|
45938
|
+
setting3("permission.read", "enum", "Read permission", "Permission rule for file reads.", {
|
|
45939
|
+
category: "permissions",
|
|
45940
|
+
allowedValues: PERMISSION_ACTIONS
|
|
45941
|
+
}),
|
|
45942
|
+
setting3("permission.edit", "enum", "Edit permission", "Permission rule for editing and writing files.", {
|
|
45943
|
+
category: "permissions",
|
|
45944
|
+
risk: "risky",
|
|
45945
|
+
allowedValues: PERMISSION_ACTIONS
|
|
45946
|
+
}),
|
|
45947
|
+
setting3("permission.webfetch", "enum", "Web fetch permission", "Permission rule for fetching external URLs.", {
|
|
45948
|
+
category: "permissions",
|
|
45949
|
+
allowedValues: PERMISSION_ACTIONS
|
|
45950
|
+
}),
|
|
45951
|
+
setting3("permission.task", "enum", "Task permission", "Permission rule for spawning subagent tasks.", {
|
|
45952
|
+
category: "permissions",
|
|
45953
|
+
allowedValues: PERMISSION_ACTIONS
|
|
45954
|
+
}),
|
|
45955
|
+
setting3("permission.websearch", "enum", "Web search permission", "Permission rule for web search operations.", {
|
|
45956
|
+
category: "permissions",
|
|
45957
|
+
allowedValues: PERMISSION_ACTIONS
|
|
45958
|
+
}),
|
|
45959
|
+
setting3("compaction.auto", "boolean", "Auto compaction", "Enable automatic context compaction when context is full.", {
|
|
45960
|
+
category: "compaction"
|
|
45961
|
+
}),
|
|
45962
|
+
setting3("tool_output.max_lines", "positiveInteger", "Tool output max lines", "Maximum lines of tool output before truncation.", {
|
|
45963
|
+
category: "output"
|
|
45964
|
+
}),
|
|
45965
|
+
setting3("tool_output.max_bytes", "positiveInteger", "Tool output max bytes", "Maximum bytes of tool output before truncation.", {
|
|
45966
|
+
category: "output"
|
|
45967
|
+
})
|
|
45968
|
+
],
|
|
45969
|
+
getSettingsPath(scope, projectPath) {
|
|
45970
|
+
switch (scope) {
|
|
45971
|
+
case "global":
|
|
45972
|
+
return firstExistingPath([
|
|
45973
|
+
expandTilde("~/.config/opencode/opencode.jsonc"),
|
|
45974
|
+
expandTilde("~/.config/opencode/opencode.json"),
|
|
45975
|
+
expandTilde("~/.config/opencode/config.json")
|
|
45976
|
+
], expandTilde("~/.config/opencode/opencode.json"));
|
|
45977
|
+
case "project":
|
|
45978
|
+
return firstExistingPath([
|
|
45979
|
+
join14(projectPath, ".opencode", "opencode.jsonc"),
|
|
45980
|
+
join14(projectPath, ".opencode", "opencode.json")
|
|
45981
|
+
], join14(projectPath, ".opencode", "opencode.json"));
|
|
45982
|
+
case "local":
|
|
45983
|
+
throw new Error("OpenCode settings do not support local scope. Use --global or --project.");
|
|
45984
|
+
}
|
|
45985
|
+
}
|
|
45986
|
+
};
|
|
45987
|
+
|
|
45988
|
+
// dist/core/agentSettings/registry.js
|
|
45989
|
+
function getAgentSettingsAdapters() {
|
|
45990
|
+
return [...ADAPTERS];
|
|
45991
|
+
}
|
|
45992
|
+
function getAgentSettingsAdapter(agent) {
|
|
45993
|
+
return ADAPTERS.find((adapter) => adapter.agent === agent);
|
|
45994
|
+
}
|
|
45995
|
+
function getAgentSettingDefinition(agent, key) {
|
|
45996
|
+
return getAgentSettingsAdapter(agent)?.definitions.find((definition) => definition.key === key);
|
|
45997
|
+
}
|
|
45998
|
+
function toSchemaEntry(definition) {
|
|
45999
|
+
return {
|
|
46000
|
+
...definition,
|
|
46001
|
+
nativePath: definition.nativePath.join(".")
|
|
46002
|
+
};
|
|
46003
|
+
}
|
|
46004
|
+
var ADAPTERS = [
|
|
46005
|
+
claudeSettingsAdapter,
|
|
46006
|
+
codexSettingsAdapter,
|
|
46007
|
+
opencodeSettingsAdapter
|
|
46008
|
+
];
|
|
46009
|
+
|
|
46010
|
+
// dist/core/agentSettings/settingsManager.js
|
|
46011
|
+
var assertObject = function(value, path) {
|
|
46012
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
46013
|
+
throw new Error(`${path} contains JSON that is not an object.`);
|
|
46014
|
+
}
|
|
46015
|
+
return value;
|
|
46016
|
+
};
|
|
46017
|
+
var getNestedValue = function(config, path) {
|
|
46018
|
+
let current = config;
|
|
46019
|
+
for (const segment of path) {
|
|
46020
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) {
|
|
46021
|
+
return;
|
|
46022
|
+
}
|
|
46023
|
+
current = current[segment];
|
|
46024
|
+
}
|
|
46025
|
+
return current;
|
|
46026
|
+
};
|
|
46027
|
+
var setNestedValue = function(config, path, value) {
|
|
46028
|
+
let current = config;
|
|
46029
|
+
for (const segment of path.slice(0, -1)) {
|
|
46030
|
+
const next = current[segment];
|
|
46031
|
+
if (!next || typeof next !== "object" || Array.isArray(next)) {
|
|
46032
|
+
current[segment] = {};
|
|
46033
|
+
}
|
|
46034
|
+
current = current[segment];
|
|
46035
|
+
}
|
|
46036
|
+
current[path[path.length - 1]] = value;
|
|
46037
|
+
};
|
|
46038
|
+
var normalizeHookEvent = function(event) {
|
|
46039
|
+
const exact = event;
|
|
46040
|
+
if (HOOK_EVENTS.has(exact)) {
|
|
46041
|
+
return exact;
|
|
46042
|
+
}
|
|
46043
|
+
const normalized = event.trim().replace(/_/g, "-").toLowerCase();
|
|
46044
|
+
const mapped = HOOK_EVENT_ALIASES[normalized];
|
|
46045
|
+
if (mapped) {
|
|
46046
|
+
return mapped;
|
|
46047
|
+
}
|
|
46048
|
+
throw new Error(`Unsupported hook event: ${event}. Supported: ${[...HOOK_EVENTS].join(", ")}.`);
|
|
46049
|
+
};
|
|
46050
|
+
var assertHookMatchers = function(value) {
|
|
46051
|
+
if (value === undefined) {
|
|
46052
|
+
return [];
|
|
46053
|
+
}
|
|
46054
|
+
if (!Array.isArray(value)) {
|
|
46055
|
+
throw new Error("Existing hooks value is not an array.");
|
|
46056
|
+
}
|
|
46057
|
+
return value.map((entry) => {
|
|
46058
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
46059
|
+
throw new Error("Existing hook matcher is not an object.");
|
|
46060
|
+
}
|
|
46061
|
+
const entryObject = entry;
|
|
46062
|
+
const matcher = entryObject.matcher;
|
|
46063
|
+
const hooks = entryObject.hooks;
|
|
46064
|
+
if (matcher !== undefined && typeof matcher !== "string") {
|
|
46065
|
+
throw new Error("Existing hook matcher must be a string.");
|
|
46066
|
+
}
|
|
46067
|
+
if (!Array.isArray(hooks)) {
|
|
46068
|
+
throw new Error("Existing hook commands must be an array.");
|
|
46069
|
+
}
|
|
46070
|
+
return {
|
|
46071
|
+
...entryObject,
|
|
46072
|
+
...matcher !== undefined ? { matcher } : {},
|
|
46073
|
+
hooks: hooks.map((hook) => {
|
|
46074
|
+
if (!hook || typeof hook !== "object" || Array.isArray(hook)) {
|
|
46075
|
+
throw new Error("Existing hook command is not an object.");
|
|
46076
|
+
}
|
|
46077
|
+
const hookObject = hook;
|
|
46078
|
+
const type2 = hookObject.type;
|
|
46079
|
+
const command = hookObject.command;
|
|
46080
|
+
const name = hookObject.name;
|
|
46081
|
+
if (type2 !== undefined && typeof type2 !== "string") {
|
|
46082
|
+
throw new Error("Existing hook command type must be a string when present.");
|
|
46083
|
+
}
|
|
46084
|
+
if (command !== undefined && typeof command !== "string") {
|
|
46085
|
+
throw new Error("Existing hook command must be a string when present.");
|
|
46086
|
+
}
|
|
46087
|
+
if (name !== undefined && typeof name !== "string") {
|
|
46088
|
+
throw new Error("Existing hook name must be a string when present.");
|
|
46089
|
+
}
|
|
46090
|
+
return {
|
|
46091
|
+
...hookObject,
|
|
46092
|
+
...typeof type2 === "string" ? { type: type2 } : {},
|
|
46093
|
+
...typeof command === "string" ? { command } : {},
|
|
46094
|
+
...typeof name === "string" ? { name } : {}
|
|
46095
|
+
};
|
|
46096
|
+
})
|
|
46097
|
+
};
|
|
46098
|
+
});
|
|
46099
|
+
};
|
|
46100
|
+
var getHookMatchers = function(config, event) {
|
|
46101
|
+
const hooks = getNestedValue(config, ["hooks"]);
|
|
46102
|
+
if (hooks === undefined) {
|
|
46103
|
+
return [];
|
|
46104
|
+
}
|
|
46105
|
+
if (!hooks || typeof hooks !== "object" || Array.isArray(hooks)) {
|
|
46106
|
+
throw new Error("Existing hooks value is not an object.");
|
|
46107
|
+
}
|
|
46108
|
+
return assertHookMatchers(hooks[event]);
|
|
46109
|
+
};
|
|
46110
|
+
var setHookMatchers = function(config, event, matchers) {
|
|
46111
|
+
const hooks = getNestedValue(config, ["hooks"]);
|
|
46112
|
+
if (hooks !== undefined && (!hooks || typeof hooks !== "object" || Array.isArray(hooks))) {
|
|
46113
|
+
throw new Error("Existing hooks value is not an object.");
|
|
46114
|
+
}
|
|
46115
|
+
const hooksObject = hooks;
|
|
46116
|
+
const nextHooks = hooksObject ?? {};
|
|
46117
|
+
if (matchers.length === 0) {
|
|
46118
|
+
delete nextHooks[event];
|
|
46119
|
+
} else {
|
|
46120
|
+
nextHooks[event] = matchers;
|
|
46121
|
+
}
|
|
46122
|
+
if (Object.keys(nextHooks).length === 0) {
|
|
46123
|
+
deleteNestedValue(config, ["hooks"]);
|
|
46124
|
+
return;
|
|
46125
|
+
}
|
|
46126
|
+
setNestedValue(config, ["hooks"], nextHooks);
|
|
46127
|
+
};
|
|
46128
|
+
var buildHookCommand = function(command, name) {
|
|
46129
|
+
const trimmed = command.trim();
|
|
46130
|
+
if (!trimmed) {
|
|
46131
|
+
throw new Error("Hook command cannot be empty.");
|
|
46132
|
+
}
|
|
46133
|
+
return {
|
|
46134
|
+
type: "command",
|
|
46135
|
+
command: trimmed,
|
|
46136
|
+
...name ? { name } : {}
|
|
46137
|
+
};
|
|
46138
|
+
};
|
|
46139
|
+
var normalizeApiKeyForConfig = function(apiKey) {
|
|
46140
|
+
const trimmed = apiKey.trim();
|
|
46141
|
+
if (!trimmed) {
|
|
46142
|
+
throw new Error("API key cannot be empty.");
|
|
46143
|
+
}
|
|
46144
|
+
return trimmed.slice(-20);
|
|
46145
|
+
};
|
|
46146
|
+
var getApiKeyResponses = function(config) {
|
|
46147
|
+
const current = config.customApiKeyResponses;
|
|
46148
|
+
if (current !== undefined && (!current || typeof current !== "object" || Array.isArray(current))) {
|
|
46149
|
+
throw new Error("Existing customApiKeyResponses value is not an object.");
|
|
46150
|
+
}
|
|
46151
|
+
const responses = current ?? {};
|
|
46152
|
+
const approved = responses.approved ?? [];
|
|
46153
|
+
const rejected = responses.rejected ?? [];
|
|
46154
|
+
if (!Array.isArray(approved) || !approved.every((value) => typeof value === "string")) {
|
|
46155
|
+
throw new Error("Existing customApiKeyResponses.approved value must be an array of strings.");
|
|
46156
|
+
}
|
|
46157
|
+
if (!Array.isArray(rejected) || !rejected.every((value) => typeof value === "string")) {
|
|
46158
|
+
throw new Error("Existing customApiKeyResponses.rejected value must be an array of strings.");
|
|
46159
|
+
}
|
|
46160
|
+
return {
|
|
46161
|
+
approved,
|
|
46162
|
+
rejected
|
|
46163
|
+
};
|
|
46164
|
+
};
|
|
46165
|
+
var getApiKeyStatusFromResponses = function(responses, fingerprint) {
|
|
46166
|
+
if (responses.approved.includes(fingerprint)) {
|
|
46167
|
+
return "approved";
|
|
46168
|
+
}
|
|
46169
|
+
if (responses.rejected.includes(fingerprint)) {
|
|
46170
|
+
return "rejected";
|
|
46171
|
+
}
|
|
46172
|
+
return "unknown";
|
|
46173
|
+
};
|
|
46174
|
+
var setApiKeyResponses = function(config, approved, rejected) {
|
|
46175
|
+
config.customApiKeyResponses = {
|
|
46176
|
+
...config.customApiKeyResponses && typeof config.customApiKeyResponses === "object" && !Array.isArray(config.customApiKeyResponses) ? config.customApiKeyResponses : {},
|
|
46177
|
+
approved,
|
|
46178
|
+
rejected
|
|
46179
|
+
};
|
|
46180
|
+
};
|
|
46181
|
+
var deleteNestedValue = function(config, path) {
|
|
46182
|
+
const parents = [];
|
|
46183
|
+
let current = config;
|
|
46184
|
+
for (const segment of path.slice(0, -1)) {
|
|
46185
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) {
|
|
46186
|
+
return false;
|
|
46187
|
+
}
|
|
46188
|
+
parents.push({ object: current, key: segment });
|
|
46189
|
+
current = current[segment];
|
|
46190
|
+
}
|
|
46191
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) {
|
|
46192
|
+
return false;
|
|
46193
|
+
}
|
|
46194
|
+
const finalKey = path[path.length - 1];
|
|
46195
|
+
if (!(finalKey in current)) {
|
|
46196
|
+
return false;
|
|
46197
|
+
}
|
|
46198
|
+
delete current[finalKey];
|
|
46199
|
+
for (let i = parents.length - 1;i >= 0; i--) {
|
|
46200
|
+
const { object, key } = parents[i];
|
|
46201
|
+
const value = object[key];
|
|
46202
|
+
if (value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0) {
|
|
46203
|
+
delete object[key];
|
|
46204
|
+
} else {
|
|
46205
|
+
break;
|
|
46206
|
+
}
|
|
46207
|
+
}
|
|
46208
|
+
return true;
|
|
46209
|
+
};
|
|
46210
|
+
var resolveProjectPath = function(projectPath) {
|
|
46211
|
+
return projectPath ?? process.cwd();
|
|
46212
|
+
};
|
|
46213
|
+
var resolveScope = function(definition, scope) {
|
|
46214
|
+
const defaultScope = getEffectiveAgentSettingsDefaultScopeSync();
|
|
46215
|
+
const resolvedScope = scope ?? (definition.store === "globalConfig" && !definition.scopes.includes(defaultScope) ? definition.defaultScope : defaultScope);
|
|
46216
|
+
if (!definition.scopes.includes(resolvedScope)) {
|
|
46217
|
+
throw new Error(`"${definition.key}" does not support ${resolvedScope} scope. Supported scopes: ${definition.scopes.join(", ")}.`);
|
|
46218
|
+
}
|
|
46219
|
+
return resolvedScope;
|
|
46220
|
+
};
|
|
46221
|
+
var getSupportedSettingScopes = function(adapter) {
|
|
46222
|
+
return [...new Set(adapter.definitions.flatMap((definition) => definition.scopes))];
|
|
46223
|
+
};
|
|
46224
|
+
var resolveFullReadScope = function(adapter, scope) {
|
|
46225
|
+
const resolvedScope = scope ?? getEffectiveAgentSettingsDefaultScopeSync();
|
|
46226
|
+
const supportedScopes = getSupportedSettingScopes(adapter);
|
|
46227
|
+
if (!supportedScopes.includes(resolvedScope)) {
|
|
46228
|
+
throw new Error(`Agent ${adapter.agent} settings do not support ${resolvedScope} scope. Supported scopes: ${supportedScopes.join(", ")}.`);
|
|
46229
|
+
}
|
|
46230
|
+
return resolvedScope;
|
|
46231
|
+
};
|
|
46232
|
+
async function readConfigObject(adapter, path) {
|
|
46233
|
+
const content = await readFileIfExists(path);
|
|
46234
|
+
if (!content) {
|
|
46235
|
+
return {};
|
|
46236
|
+
}
|
|
46237
|
+
if (adapter.format === "toml") {
|
|
46238
|
+
try {
|
|
46239
|
+
return assertObject(TOML4.parse(content), path);
|
|
46240
|
+
} catch (error) {
|
|
46241
|
+
if (error instanceof SyntaxError || error instanceof Error) {
|
|
46242
|
+
throw new Error(`${path} contains invalid TOML.`);
|
|
46243
|
+
}
|
|
46244
|
+
throw error;
|
|
46245
|
+
}
|
|
46246
|
+
}
|
|
46247
|
+
try {
|
|
46248
|
+
const errors5 = [];
|
|
46249
|
+
const value = adapter.format === "jsonc" ? import_jsonc_parser.parse(content, errors5, { allowTrailingComma: true }) : JSON.parse(content);
|
|
46250
|
+
if (errors5.length > 0) {
|
|
46251
|
+
throw new SyntaxError("Invalid JSONC");
|
|
46252
|
+
}
|
|
46253
|
+
return assertObject(value, path);
|
|
46254
|
+
} catch (error) {
|
|
46255
|
+
if (error instanceof SyntaxError) {
|
|
46256
|
+
throw new Error(`${path} contains invalid ${adapter.format === "jsonc" ? "JSONC" : "JSON"}.`);
|
|
46257
|
+
}
|
|
46258
|
+
throw error;
|
|
46259
|
+
}
|
|
46260
|
+
}
|
|
46261
|
+
var stringifyConfigObject = function(adapter, config) {
|
|
46262
|
+
if (adapter.format === "toml") {
|
|
46263
|
+
return TOML4.stringify(config);
|
|
46264
|
+
}
|
|
46265
|
+
return `${JSON.stringify(config, null, 2)}\n`;
|
|
46266
|
+
};
|
|
46267
|
+
async function writeConfigObject(adapter, path, config) {
|
|
46268
|
+
await writeFile(path, stringifyConfigObject(adapter, config));
|
|
46269
|
+
}
|
|
46270
|
+
var assertHookEventSupported = function(adapter, event) {
|
|
46271
|
+
if (adapter.hookEvents && !adapter.hookEvents.includes(event)) {
|
|
46272
|
+
throw new Error(`Agent ${adapter.agent} does not support ${event} hooks. Supported: ${adapter.hookEvents.join(", ")}.`);
|
|
46273
|
+
}
|
|
46274
|
+
};
|
|
46275
|
+
var resolveHookScope = function(adapter, scope) {
|
|
46276
|
+
const resolvedScope = scope ?? getEffectiveAgentSettingsDefaultScopeSync();
|
|
46277
|
+
const supportedScopes = adapter.hookScopes ?? ["global", "project", "local"];
|
|
46278
|
+
if (!supportedScopes.includes(resolvedScope)) {
|
|
46279
|
+
throw new Error(`Agent ${adapter.agent} hooks do not support ${resolvedScope} scope. Supported scopes: ${supportedScopes.join(", ")}.`);
|
|
46280
|
+
}
|
|
46281
|
+
return resolvedScope;
|
|
46282
|
+
};
|
|
46283
|
+
var HOOK_EVENT_ALIASES = {
|
|
46284
|
+
"pre-tool-use": "PreToolUse",
|
|
46285
|
+
"before-tool-use": "PreToolUse",
|
|
46286
|
+
"post-tool-use": "PostToolUse",
|
|
46287
|
+
"after-tool-use": "PostToolUse",
|
|
46288
|
+
"post-tool-use-failure": "PostToolUseFailure",
|
|
46289
|
+
notification: "Notification",
|
|
46290
|
+
"permission-request": "PermissionRequest",
|
|
46291
|
+
stop: "Stop",
|
|
46292
|
+
"session-start": "SessionStart",
|
|
46293
|
+
"session-end": "SessionEnd",
|
|
46294
|
+
"user-prompt-submit": "UserPromptSubmit"
|
|
46295
|
+
};
|
|
46296
|
+
var HOOK_EVENTS = new Set(Object.values(HOOK_EVENT_ALIASES));
|
|
46297
|
+
var CLAUDE_API_KEY_RESPONSES_DEFINITION = {
|
|
46298
|
+
agent: "claude",
|
|
46299
|
+
key: "customApiKeyResponses",
|
|
46300
|
+
nativePath: ["customApiKeyResponses"],
|
|
46301
|
+
title: "Custom API key responses",
|
|
46302
|
+
description: "Remembered custom API key trust responses.",
|
|
46303
|
+
valueType: "object",
|
|
46304
|
+
scopes: ["global"],
|
|
46305
|
+
defaultScope: "global",
|
|
46306
|
+
category: "auth",
|
|
46307
|
+
risk: "security-sensitive",
|
|
46308
|
+
store: "globalConfig"
|
|
46309
|
+
};
|
|
46310
|
+
|
|
46311
|
+
class AgentSettingsManager {
|
|
46312
|
+
getSupportedAgents() {
|
|
46313
|
+
return getAgentSettingsAdapters().map((adapter) => adapter.agent);
|
|
46314
|
+
}
|
|
46315
|
+
getSchema(agent) {
|
|
46316
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
46317
|
+
if (!adapter) {
|
|
46318
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(", ")}`);
|
|
46319
|
+
}
|
|
46320
|
+
return {
|
|
46321
|
+
agent: adapter.agent,
|
|
46322
|
+
displayName: adapter.displayName,
|
|
46323
|
+
effectiveDefaultScope: getEffectiveAgentSettingsDefaultScopeSync(),
|
|
46324
|
+
settings: adapter.definitions.map(toSchemaEntry)
|
|
46325
|
+
};
|
|
46326
|
+
}
|
|
46327
|
+
async get(agent, key, options2 = {}) {
|
|
46328
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
46329
|
+
if (!adapter) {
|
|
46330
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(", ")}`);
|
|
46331
|
+
}
|
|
46332
|
+
if (!key) {
|
|
46333
|
+
const scope2 = resolveFullReadScope(adapter, options2.scope);
|
|
46334
|
+
const path2 = adapter.getSettingsPath(scope2, resolveProjectPath(options2.projectPath));
|
|
46335
|
+
const config2 = await readConfigObject(adapter, path2);
|
|
46336
|
+
if (scope2 !== "global") {
|
|
46337
|
+
return config2;
|
|
46338
|
+
}
|
|
46339
|
+
const globalConfigDefinitions = adapter.definitions.filter((definition2) => definition2.store === "globalConfig" && definition2.scopes.includes("global"));
|
|
46340
|
+
if (globalConfigDefinitions.length === 0) {
|
|
46341
|
+
return config2;
|
|
46342
|
+
}
|
|
46343
|
+
const globalConfigPath = adapter.getSettingsPath("global", resolveProjectPath(options2.projectPath), globalConfigDefinitions[0]);
|
|
46344
|
+
const globalConfig = await readConfigObject(adapter, globalConfigPath);
|
|
46345
|
+
const result = { ...config2 };
|
|
46346
|
+
for (const definition2 of globalConfigDefinitions) {
|
|
46347
|
+
const value = getNestedValue(globalConfig, definition2.nativePath);
|
|
46348
|
+
if (value !== undefined) {
|
|
46349
|
+
setNestedValue(result, definition2.nativePath, value);
|
|
46350
|
+
}
|
|
46351
|
+
}
|
|
46352
|
+
return result;
|
|
46353
|
+
}
|
|
46354
|
+
const definition = getAgentSettingDefinition(agent, key);
|
|
46355
|
+
if (!definition) {
|
|
46356
|
+
throw new Error(`Unknown ${agent} setting: ${key}.`);
|
|
46357
|
+
}
|
|
46358
|
+
const scope = resolveScope(definition, options2.scope);
|
|
46359
|
+
const path = adapter.getSettingsPath(scope, resolveProjectPath(options2.projectPath), definition);
|
|
46360
|
+
const config = await readConfigObject(adapter, path);
|
|
46361
|
+
return getNestedValue(config, definition.nativePath);
|
|
46362
|
+
}
|
|
46363
|
+
async set(agent, key, rawValue, options2 = {}) {
|
|
46364
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
46365
|
+
if (!adapter) {
|
|
46366
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(", ")}`);
|
|
46367
|
+
}
|
|
46368
|
+
const definition = getAgentSettingDefinition(agent, key);
|
|
46369
|
+
if (!definition) {
|
|
46370
|
+
throw new Error(`Unknown ${agent} setting: ${key}.`);
|
|
46371
|
+
}
|
|
46372
|
+
const scope = resolveScope(definition, options2.scope);
|
|
46373
|
+
const path = adapter.getSettingsPath(scope, resolveProjectPath(options2.projectPath), definition);
|
|
46374
|
+
const config = await readConfigObject(adapter, path);
|
|
46375
|
+
const previousValue = getNestedValue(config, definition.nativePath);
|
|
46376
|
+
const value = parseAgentSettingValue(definition, rawValue, options2.parseJson);
|
|
46377
|
+
setNestedValue(config, definition.nativePath, value);
|
|
46378
|
+
if (!options2.dryRun) {
|
|
46379
|
+
await writeConfigObject(adapter, path, config);
|
|
46380
|
+
}
|
|
46381
|
+
return {
|
|
46382
|
+
agent,
|
|
46383
|
+
key,
|
|
46384
|
+
scope,
|
|
46385
|
+
path,
|
|
46386
|
+
value,
|
|
46387
|
+
previousValue,
|
|
46388
|
+
dryRun: Boolean(options2.dryRun)
|
|
46389
|
+
};
|
|
46390
|
+
}
|
|
46391
|
+
async unset(agent, key, options2 = {}) {
|
|
46392
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
46393
|
+
if (!adapter) {
|
|
46394
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(", ")}`);
|
|
46395
|
+
}
|
|
46396
|
+
const definition = getAgentSettingDefinition(agent, key);
|
|
46397
|
+
if (!definition) {
|
|
46398
|
+
throw new Error(`Unknown ${agent} setting: ${key}.`);
|
|
46399
|
+
}
|
|
46400
|
+
const scope = resolveScope(definition, options2.scope);
|
|
46401
|
+
const path = adapter.getSettingsPath(scope, resolveProjectPath(options2.projectPath), definition);
|
|
46402
|
+
const config = await readConfigObject(adapter, path);
|
|
46403
|
+
const previousValue = getNestedValue(config, definition.nativePath);
|
|
46404
|
+
deleteNestedValue(config, definition.nativePath);
|
|
46405
|
+
if (!options2.dryRun) {
|
|
46406
|
+
await writeConfigObject(adapter, path, config);
|
|
46407
|
+
}
|
|
46408
|
+
return {
|
|
46409
|
+
agent,
|
|
46410
|
+
key,
|
|
46411
|
+
scope,
|
|
46412
|
+
path,
|
|
46413
|
+
previousValue,
|
|
46414
|
+
dryRun: Boolean(options2.dryRun)
|
|
46415
|
+
};
|
|
46416
|
+
}
|
|
46417
|
+
async listHooks(agent, event, options2 = {}) {
|
|
46418
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
46419
|
+
if (!adapter) {
|
|
46420
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(", ")}`);
|
|
46421
|
+
}
|
|
46422
|
+
if (!adapter.hookEvents) {
|
|
46423
|
+
throw new Error(`Agent ${agent} does not support hook management.`);
|
|
46424
|
+
}
|
|
46425
|
+
const hookEvent = event ? normalizeHookEvent(event) : undefined;
|
|
46426
|
+
if (hookEvent) {
|
|
46427
|
+
assertHookEventSupported(adapter, hookEvent);
|
|
46428
|
+
}
|
|
46429
|
+
const scope = resolveHookScope(adapter, options2.scope);
|
|
46430
|
+
const path = adapter.getSettingsPath(scope, resolveProjectPath(options2.projectPath));
|
|
46431
|
+
const config = await readConfigObject(adapter, path);
|
|
46432
|
+
if (hookEvent) {
|
|
46433
|
+
return getHookMatchers(config, hookEvent);
|
|
46434
|
+
}
|
|
46435
|
+
const hooks = getNestedValue(config, ["hooks"]);
|
|
46436
|
+
if (hooks === undefined) {
|
|
46437
|
+
return {};
|
|
46438
|
+
}
|
|
46439
|
+
if (!hooks || typeof hooks !== "object" || Array.isArray(hooks)) {
|
|
46440
|
+
throw new Error("Existing hooks value is not an object.");
|
|
46441
|
+
}
|
|
46442
|
+
const result = {};
|
|
46443
|
+
for (const [hookEvent2, value] of Object.entries(hooks)) {
|
|
46444
|
+
result[hookEvent2] = assertHookMatchers(value);
|
|
46445
|
+
}
|
|
46446
|
+
return result;
|
|
46447
|
+
}
|
|
46448
|
+
async addHook(agent, event, command, options2 = {}) {
|
|
46449
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
46450
|
+
if (!adapter) {
|
|
46451
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(", ")}`);
|
|
46452
|
+
}
|
|
46453
|
+
if (!adapter.hookEvents) {
|
|
46454
|
+
throw new Error(`Agent ${agent} does not support hook management.`);
|
|
46455
|
+
}
|
|
46456
|
+
const hookEvent = normalizeHookEvent(event);
|
|
46457
|
+
assertHookEventSupported(adapter, hookEvent);
|
|
46458
|
+
const scope = resolveHookScope(adapter, options2.scope);
|
|
46459
|
+
const path = adapter.getSettingsPath(scope, resolveProjectPath(options2.projectPath));
|
|
46460
|
+
const config = await readConfigObject(adapter, path);
|
|
46461
|
+
const hook = buildHookCommand(command, options2.name);
|
|
46462
|
+
const matchers = getHookMatchers(config, hookEvent);
|
|
46463
|
+
const matcher = options2.matcher ?? "*";
|
|
46464
|
+
const existingMatcher = matchers.find((entry) => (entry.matcher ?? "*") === matcher);
|
|
46465
|
+
if (existingMatcher) {
|
|
46466
|
+
existingMatcher.hooks.push(hook);
|
|
46467
|
+
} else {
|
|
46468
|
+
matchers.push({
|
|
46469
|
+
...matcher === "*" ? {} : { matcher },
|
|
46470
|
+
hooks: [hook]
|
|
46471
|
+
});
|
|
46472
|
+
}
|
|
46473
|
+
setHookMatchers(config, hookEvent, matchers);
|
|
46474
|
+
if (!options2.dryRun) {
|
|
46475
|
+
await writeConfigObject(adapter, path, config);
|
|
46476
|
+
}
|
|
46477
|
+
return {
|
|
46478
|
+
agent,
|
|
46479
|
+
event: hookEvent,
|
|
46480
|
+
scope,
|
|
46481
|
+
path,
|
|
46482
|
+
hook,
|
|
46483
|
+
dryRun: Boolean(options2.dryRun)
|
|
46484
|
+
};
|
|
46485
|
+
}
|
|
46486
|
+
async removeHook(agent, event, commandOrName, options2 = {}) {
|
|
46487
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
46488
|
+
if (!adapter) {
|
|
46489
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(", ")}`);
|
|
46490
|
+
}
|
|
46491
|
+
if (!adapter.hookEvents) {
|
|
46492
|
+
throw new Error(`Agent ${agent} does not support hook management.`);
|
|
46493
|
+
}
|
|
46494
|
+
const hookEvent = normalizeHookEvent(event);
|
|
46495
|
+
assertHookEventSupported(adapter, hookEvent);
|
|
46496
|
+
const scope = resolveHookScope(adapter, options2.scope);
|
|
46497
|
+
const path = adapter.getSettingsPath(scope, resolveProjectPath(options2.projectPath));
|
|
46498
|
+
const config = await readConfigObject(adapter, path);
|
|
46499
|
+
const matchers = getHookMatchers(config, hookEvent);
|
|
46500
|
+
let removed = 0;
|
|
46501
|
+
const nextMatchers = matchers.map((entry) => {
|
|
46502
|
+
if (options2.matcher !== undefined && (entry.matcher ?? "*") !== options2.matcher) {
|
|
46503
|
+
return entry;
|
|
46504
|
+
}
|
|
46505
|
+
const hooks = entry.hooks.filter((hook) => {
|
|
46506
|
+
const matches = hook.name === commandOrName || hook.command === commandOrName;
|
|
46507
|
+
if (matches) {
|
|
46508
|
+
removed++;
|
|
46509
|
+
}
|
|
46510
|
+
return !matches;
|
|
46511
|
+
});
|
|
46512
|
+
return { ...entry, hooks };
|
|
46513
|
+
}).filter((entry) => entry.hooks.length > 0);
|
|
46514
|
+
setHookMatchers(config, hookEvent, nextMatchers);
|
|
46515
|
+
if (!options2.dryRun) {
|
|
46516
|
+
await writeConfigObject(adapter, path, config);
|
|
46517
|
+
}
|
|
46518
|
+
return {
|
|
46519
|
+
agent,
|
|
46520
|
+
event: hookEvent,
|
|
46521
|
+
scope,
|
|
46522
|
+
path,
|
|
46523
|
+
removed,
|
|
46524
|
+
dryRun: Boolean(options2.dryRun)
|
|
46525
|
+
};
|
|
46526
|
+
}
|
|
46527
|
+
async getApiKeyStatus(agent, apiKey, options2 = {}) {
|
|
46528
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
46529
|
+
if (!adapter) {
|
|
46530
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(", ")}`);
|
|
46531
|
+
}
|
|
46532
|
+
if (agent !== "claude") {
|
|
46533
|
+
throw new Error(`Agent ${agent} does not support API key trust management.`);
|
|
46534
|
+
}
|
|
46535
|
+
const path = adapter.getSettingsPath("global", resolveProjectPath(options2.projectPath), CLAUDE_API_KEY_RESPONSES_DEFINITION);
|
|
46536
|
+
const config = await readConfigObject(adapter, path);
|
|
46537
|
+
const fingerprint = normalizeApiKeyForConfig(apiKey);
|
|
46538
|
+
const responses = getApiKeyResponses(config);
|
|
46539
|
+
return {
|
|
46540
|
+
agent,
|
|
46541
|
+
path,
|
|
46542
|
+
fingerprint,
|
|
46543
|
+
status: getApiKeyStatusFromResponses(responses, fingerprint),
|
|
46544
|
+
dryRun: false
|
|
46545
|
+
};
|
|
46546
|
+
}
|
|
46547
|
+
async updateApiKeyTrust(agent, action, apiKey, options2 = {}) {
|
|
46548
|
+
const adapter = getAgentSettingsAdapter(agent);
|
|
46549
|
+
if (!adapter) {
|
|
46550
|
+
throw new Error(`Unsupported agent settings adapter: ${agent}. Supported: ${this.getSupportedAgents().join(", ")}`);
|
|
46551
|
+
}
|
|
46552
|
+
if (agent !== "claude") {
|
|
46553
|
+
throw new Error(`Agent ${agent} does not support API key trust management.`);
|
|
46554
|
+
}
|
|
46555
|
+
const path = adapter.getSettingsPath("global", resolveProjectPath(options2.projectPath), CLAUDE_API_KEY_RESPONSES_DEFINITION);
|
|
46556
|
+
const config = await readConfigObject(adapter, path);
|
|
46557
|
+
const fingerprint = normalizeApiKeyForConfig(apiKey);
|
|
46558
|
+
const responses = getApiKeyResponses(config);
|
|
46559
|
+
const previousStatus = getApiKeyStatusFromResponses(responses, fingerprint);
|
|
46560
|
+
let approved = responses.approved.filter((value) => value !== fingerprint);
|
|
46561
|
+
let rejected = responses.rejected.filter((value) => value !== fingerprint);
|
|
46562
|
+
if (action === "approve") {
|
|
46563
|
+
approved = [...approved, fingerprint];
|
|
46564
|
+
} else if (action === "reject") {
|
|
46565
|
+
rejected = [...rejected, fingerprint];
|
|
46566
|
+
}
|
|
46567
|
+
const status = action === "approve" ? "approved" : action === "reject" ? "rejected" : "unknown";
|
|
46568
|
+
setApiKeyResponses(config, approved, rejected);
|
|
46569
|
+
if (!options2.dryRun) {
|
|
46570
|
+
await writeConfigObject(adapter, path, config);
|
|
46571
|
+
}
|
|
46572
|
+
return {
|
|
46573
|
+
agent,
|
|
46574
|
+
path,
|
|
46575
|
+
fingerprint,
|
|
46576
|
+
status,
|
|
46577
|
+
previousStatus,
|
|
46578
|
+
dryRun: Boolean(options2.dryRun)
|
|
46579
|
+
};
|
|
46580
|
+
}
|
|
46581
|
+
}
|
|
46582
|
+
|
|
46583
|
+
// dist/commands/agent.js
|
|
46584
|
+
init_logger();
|
|
46585
|
+
var failAgentCommand = function(error) {
|
|
46586
|
+
logger.error(error instanceof Error ? error.message : "Agent settings command failed.");
|
|
46587
|
+
process.exitCode = 1;
|
|
46588
|
+
};
|
|
46589
|
+
var resolveScopeOption = function(options2) {
|
|
46590
|
+
const requested = [
|
|
46591
|
+
options2.global ? "global" : null,
|
|
46592
|
+
options2.project ? "project" : null,
|
|
46593
|
+
options2.local ? "local" : null
|
|
46594
|
+
].filter(Boolean);
|
|
46595
|
+
if (requested.length > 1) {
|
|
46596
|
+
throw new Error("Choose only one scope: --global, --project, or --local.");
|
|
46597
|
+
}
|
|
46598
|
+
return requested[0];
|
|
46599
|
+
};
|
|
46600
|
+
var printJson = function(value) {
|
|
46601
|
+
console.log(JSON.stringify(value === undefined ? null : value, null, 2));
|
|
46602
|
+
};
|
|
46603
|
+
var printValue = function(value) {
|
|
46604
|
+
if (value === undefined) {
|
|
46605
|
+
logger.info("Not set.");
|
|
46606
|
+
return;
|
|
46607
|
+
}
|
|
46608
|
+
if (typeof value === "string") {
|
|
46609
|
+
console.log(value);
|
|
46610
|
+
return;
|
|
46611
|
+
}
|
|
46612
|
+
printJson(value);
|
|
46613
|
+
};
|
|
46614
|
+
var buildSetOptions = function(options2) {
|
|
46615
|
+
const result = {};
|
|
46616
|
+
const scope = resolveScopeOption(options2);
|
|
46617
|
+
if (scope) {
|
|
46618
|
+
result.scope = scope;
|
|
46619
|
+
}
|
|
46620
|
+
if (options2.valueJson !== undefined) {
|
|
46621
|
+
result.parseJson = options2.valueJson;
|
|
46622
|
+
}
|
|
46623
|
+
if (options2.dryRun !== undefined) {
|
|
46624
|
+
result.dryRun = options2.dryRun;
|
|
46625
|
+
}
|
|
46626
|
+
return result;
|
|
46627
|
+
};
|
|
46628
|
+
var buildReadOptions = function(options2) {
|
|
46629
|
+
const result = {};
|
|
46630
|
+
const scope = resolveScopeOption(options2);
|
|
46631
|
+
if (scope) {
|
|
46632
|
+
result.scope = scope;
|
|
46633
|
+
}
|
|
46634
|
+
return result;
|
|
46635
|
+
};
|
|
46636
|
+
var buildHookAddOptions = function(options2) {
|
|
46637
|
+
const result = {};
|
|
46638
|
+
const scope = resolveScopeOption(options2);
|
|
46639
|
+
if (scope) {
|
|
46640
|
+
result.scope = scope;
|
|
46641
|
+
}
|
|
46642
|
+
if (options2.matcher !== undefined) {
|
|
46643
|
+
result.matcher = options2.matcher;
|
|
46644
|
+
}
|
|
46645
|
+
if (options2.name !== undefined) {
|
|
46646
|
+
result.name = options2.name;
|
|
46647
|
+
}
|
|
46648
|
+
if (options2.dryRun !== undefined) {
|
|
46649
|
+
result.dryRun = options2.dryRun;
|
|
46650
|
+
}
|
|
46651
|
+
return result;
|
|
46652
|
+
};
|
|
46653
|
+
var buildHookRemoveOptions = function(options2) {
|
|
46654
|
+
const result = {};
|
|
46655
|
+
const scope = resolveScopeOption(options2);
|
|
46656
|
+
if (scope) {
|
|
46657
|
+
result.scope = scope;
|
|
46658
|
+
}
|
|
46659
|
+
if (options2.matcher !== undefined) {
|
|
46660
|
+
result.matcher = options2.matcher;
|
|
46661
|
+
}
|
|
46662
|
+
if (options2.dryRun !== undefined) {
|
|
46663
|
+
result.dryRun = options2.dryRun;
|
|
46664
|
+
}
|
|
46665
|
+
return result;
|
|
46666
|
+
};
|
|
46667
|
+
var resolveApiKeyOption = function(options2) {
|
|
46668
|
+
if (options2.env && options2.key) {
|
|
46669
|
+
throw new Error("Choose only one API key source: --env or --key.");
|
|
46670
|
+
}
|
|
46671
|
+
if (options2.env) {
|
|
46672
|
+
const value = process.env[options2.env];
|
|
46673
|
+
if (!value) {
|
|
46674
|
+
throw new Error(`Environment variable ${options2.env} is not set.`);
|
|
46675
|
+
}
|
|
46676
|
+
return value;
|
|
46677
|
+
}
|
|
46678
|
+
if (options2.key) {
|
|
46679
|
+
return options2.key;
|
|
46680
|
+
}
|
|
46681
|
+
throw new Error("API key source is required. Use --env <name> or --key <key>.");
|
|
46682
|
+
};
|
|
46683
|
+
var warnForRawApiKeyOption = function(options2) {
|
|
46684
|
+
if (options2.key && !options2.json) {
|
|
46685
|
+
logger.warning("Using --key can expose the raw API key in shell history and process listings. Prefer --env when possible.");
|
|
46686
|
+
}
|
|
46687
|
+
};
|
|
46688
|
+
var buildApiKeyOptions = function(options2) {
|
|
46689
|
+
return {
|
|
46690
|
+
dryRun: Boolean(options2.dryRun)
|
|
46691
|
+
};
|
|
46692
|
+
};
|
|
46693
|
+
var apiKeyActionVerb = function(action, dryRun) {
|
|
46694
|
+
if (dryRun) {
|
|
46695
|
+
return `Would ${action}`;
|
|
46696
|
+
}
|
|
46697
|
+
switch (action) {
|
|
46698
|
+
case "approve":
|
|
46699
|
+
return "Approved";
|
|
46700
|
+
case "reject":
|
|
46701
|
+
return "Rejected";
|
|
46702
|
+
case "forget":
|
|
46703
|
+
return "Forgot";
|
|
46704
|
+
}
|
|
46705
|
+
};
|
|
46706
|
+
function registerAgentCommand(program2) {
|
|
46707
|
+
const manager = new AgentSettingsManager;
|
|
46708
|
+
const agent = program2.command("agent").description("Manage native agent settings");
|
|
46709
|
+
agent.command("set <agent> <key> <value...>").description("Set an agent setting").option("--global", "Write global user settings").option("--project", "Write shared project settings").option("--local", "Write local project settings").option("--value-json", "Parse the value as JSON for arrays and objects").option("--json", "Print JSON output").option("--dry-run", "Preview the write without changing files").action(async (agentId, key, valueParts, options2) => {
|
|
46710
|
+
try {
|
|
46711
|
+
const value = valueParts.join(" ");
|
|
46712
|
+
const result = await manager.set(agentId, key, value, buildSetOptions(options2));
|
|
46713
|
+
if (options2.json) {
|
|
46714
|
+
printJson(result);
|
|
46715
|
+
return;
|
|
46716
|
+
}
|
|
46717
|
+
const verb = result.dryRun ? "Would set" : "Set";
|
|
46718
|
+
logger.success(`${verb} ${green(result.agent)} ${cyan(result.key)} in ${result.scope} settings.`);
|
|
46719
|
+
logger.info(`Path: ${result.path}`);
|
|
46720
|
+
} catch (error) {
|
|
46721
|
+
failAgentCommand(error);
|
|
46722
|
+
}
|
|
46723
|
+
});
|
|
46724
|
+
const hook = agent.command("hook").description("Manage native agent hooks with typed operations");
|
|
46725
|
+
hook.command("add <agent> <event>").description("Add a command hook without replacing existing hooks").option("--command <command>", "Shell command to execute for this hook").option("--matcher <matcher>", "Claude hook matcher, defaults to all matching tools/events").option("--name <name>", "Stable name used to identify this hook later").option("--global", "Write global user settings").option("--project", "Write shared project settings").option("--local", "Write local project settings").option("--json", "Print JSON output").option("--dry-run", "Preview the write without changing files").action(async (agentId, event, options2) => {
|
|
46726
|
+
try {
|
|
46727
|
+
if (!options2.command) {
|
|
46728
|
+
throw new Error("agent hook add requires --command <command>.");
|
|
46729
|
+
}
|
|
46730
|
+
const result = await manager.addHook(agentId, event, options2.command, buildHookAddOptions(options2));
|
|
46731
|
+
if (options2.json) {
|
|
46732
|
+
printJson(result);
|
|
46733
|
+
return;
|
|
46734
|
+
}
|
|
46735
|
+
const verb = result.dryRun ? "Would add" : "Added";
|
|
46736
|
+
logger.success(`${verb} ${green(result.agent)} ${cyan(result.event)} hook in ${result.scope} settings.`);
|
|
46737
|
+
logger.info(`Path: ${result.path}`);
|
|
46738
|
+
} catch (error) {
|
|
46739
|
+
failAgentCommand(error);
|
|
46740
|
+
}
|
|
46741
|
+
});
|
|
46742
|
+
hook.command("list <agent> [event]").description("List configured hooks").option("--global", "Read global user settings").option("--project", "Read shared project settings").option("--local", "Read local project settings").option("--json", "Print JSON output").action(async (agentId, event, options2) => {
|
|
46743
|
+
try {
|
|
46744
|
+
const hooks = await manager.listHooks(agentId, event, buildReadOptions(options2));
|
|
46745
|
+
if (options2.json) {
|
|
46746
|
+
printJson(hooks);
|
|
46747
|
+
return;
|
|
46748
|
+
}
|
|
46749
|
+
logger.titleBox(`AgentInit ${agentId} Hooks`);
|
|
46750
|
+
if (Array.isArray(hooks)) {
|
|
46751
|
+
hooks.forEach((entry, index) => logger.tree(`${cyan(entry.matcher ?? "*")} ${entry.hooks.map((hook2) => hook2.name ?? hook2.command ?? hook2.type ?? "hook").join(", ")}`, index === hooks.length - 1));
|
|
46752
|
+
return;
|
|
46753
|
+
}
|
|
46754
|
+
const entries = Object.entries(hooks);
|
|
46755
|
+
if (entries.length === 0) {
|
|
46756
|
+
logger.info("No hooks configured.");
|
|
46757
|
+
return;
|
|
46758
|
+
}
|
|
46759
|
+
entries.forEach(([hookEvent, matchers], index) => logger.tree(`${cyan(hookEvent)} ${matchers.length} matcher(s)`, index === entries.length - 1));
|
|
46760
|
+
} catch (error) {
|
|
46761
|
+
failAgentCommand(error);
|
|
46762
|
+
}
|
|
46763
|
+
});
|
|
46764
|
+
hook.command("remove <agent> <event> <commandOrName>").alias("rm").description("Remove hooks by command string or hook name").option("--matcher <matcher>", "Only remove hooks from this matcher").option("--global", "Write global user settings").option("--project", "Write shared project settings").option("--local", "Write local project settings").option("--json", "Print JSON output").option("--dry-run", "Preview the write without changing files").action(async (agentId, event, commandOrName, options2) => {
|
|
46765
|
+
try {
|
|
46766
|
+
const result = await manager.removeHook(agentId, event, commandOrName, buildHookRemoveOptions(options2));
|
|
46767
|
+
if (options2.json) {
|
|
46768
|
+
printJson(result);
|
|
46769
|
+
return;
|
|
46770
|
+
}
|
|
46771
|
+
const verb = result.dryRun ? "Would remove" : "Removed";
|
|
46772
|
+
logger.success(`${verb} ${result.removed ?? 0} ${green(result.agent)} ${cyan(result.event)} hook(s) from ${result.scope} settings.`);
|
|
46773
|
+
logger.info(`Path: ${result.path}`);
|
|
46774
|
+
} catch (error) {
|
|
46775
|
+
failAgentCommand(error);
|
|
46776
|
+
}
|
|
46777
|
+
});
|
|
46778
|
+
const apiKey = agent.command("api-key").description("Manage Claude custom API key trust responses");
|
|
46779
|
+
apiKey.command("status <agent>").description("Check whether a custom API key is approved, rejected, or unknown").option("--env <name>", "Read the API key from this environment variable").option("--key <key>", "Use this API key value directly; prefer --env to avoid shell-history exposure").option("--json", "Print JSON output").action(async (agentId, options2) => {
|
|
46780
|
+
try {
|
|
46781
|
+
warnForRawApiKeyOption(options2);
|
|
46782
|
+
const result = await manager.getApiKeyStatus(agentId, resolveApiKeyOption(options2));
|
|
46783
|
+
if (options2.json) {
|
|
46784
|
+
printJson(result);
|
|
46785
|
+
return;
|
|
46786
|
+
}
|
|
46787
|
+
logger.info(`${green(result.agent)} API key fingerprint ${cyan(result.fingerprint)} is ${result.status}.`);
|
|
46788
|
+
logger.info(`Path: ${result.path}`);
|
|
46789
|
+
} catch (error) {
|
|
46790
|
+
failAgentCommand(error);
|
|
46791
|
+
}
|
|
46792
|
+
});
|
|
46793
|
+
for (const action of ["approve", "reject", "forget"]) {
|
|
46794
|
+
apiKey.command(`${action} <agent>`).description(`${action[0].toUpperCase()}${action.slice(1)} a custom API key trust response`).option("--env <name>", "Read the API key from this environment variable").option("--key <key>", "Use this API key value directly; prefer --env to avoid shell-history exposure").option("--json", "Print JSON output").option("--dry-run", "Preview the write without changing files").action(async (agentId, options2) => {
|
|
46795
|
+
try {
|
|
46796
|
+
warnForRawApiKeyOption(options2);
|
|
46797
|
+
const result = await manager.updateApiKeyTrust(agentId, action, resolveApiKeyOption(options2), buildApiKeyOptions(options2));
|
|
46798
|
+
if (options2.json) {
|
|
46799
|
+
printJson(result);
|
|
46800
|
+
return;
|
|
46801
|
+
}
|
|
46802
|
+
logger.success(`${apiKeyActionVerb(action, result.dryRun)} ${green(result.agent)} API key fingerprint ${cyan(result.fingerprint)}.`);
|
|
46803
|
+
logger.info(`Status: ${result.status}`);
|
|
46804
|
+
logger.info(`Path: ${result.path}`);
|
|
46805
|
+
} catch (error) {
|
|
46806
|
+
failAgentCommand(error);
|
|
46807
|
+
}
|
|
46808
|
+
});
|
|
46809
|
+
}
|
|
46810
|
+
agent.command("get <agent> [key]").description("Get an agent setting or settings file").option("--global", "Read global user settings").option("--project", "Read shared project settings").option("--local", "Read local project settings").option("--json", "Print JSON output").action(async (agentId, key, options2) => {
|
|
46811
|
+
try {
|
|
46812
|
+
const value = await manager.get(agentId, key, buildReadOptions(options2));
|
|
46813
|
+
if (options2.json) {
|
|
46814
|
+
printJson(value);
|
|
46815
|
+
return;
|
|
46816
|
+
}
|
|
46817
|
+
printValue(value);
|
|
46818
|
+
} catch (error) {
|
|
46819
|
+
failAgentCommand(error);
|
|
46820
|
+
}
|
|
46821
|
+
});
|
|
46822
|
+
agent.command("unset <agent> <key>").description("Unset an agent setting").option("--global", "Write global user settings").option("--project", "Write shared project settings").option("--local", "Write local project settings").option("--json", "Print JSON output").option("--dry-run", "Preview the write without changing files").action(async (agentId, key, options2) => {
|
|
46823
|
+
try {
|
|
46824
|
+
const result = await manager.unset(agentId, key, buildSetOptions(options2));
|
|
46825
|
+
if (options2.json) {
|
|
46826
|
+
printJson(result);
|
|
46827
|
+
return;
|
|
46828
|
+
}
|
|
46829
|
+
const verb = result.dryRun ? "Would unset" : "Unset";
|
|
46830
|
+
logger.success(`${verb} ${green(result.agent)} ${cyan(result.key)} in ${result.scope} settings.`);
|
|
46831
|
+
logger.info(`Path: ${result.path}`);
|
|
46832
|
+
} catch (error) {
|
|
46833
|
+
failAgentCommand(error);
|
|
46834
|
+
}
|
|
46835
|
+
});
|
|
46836
|
+
agent.command("list [agent]").description("List supported agents or setting keys for one agent").option("--json", "Print JSON output").action((agentId, options2) => {
|
|
46837
|
+
try {
|
|
46838
|
+
if (!agentId) {
|
|
46839
|
+
const agents = manager.getSupportedAgents();
|
|
46840
|
+
if (options2.json) {
|
|
46841
|
+
printJson(agents);
|
|
46842
|
+
return;
|
|
46843
|
+
}
|
|
46844
|
+
logger.titleBox("AgentInit Agent Settings");
|
|
46845
|
+
agents.forEach((entry, index) => logger.tree(cyan(entry), index === agents.length - 1));
|
|
46846
|
+
return;
|
|
46847
|
+
}
|
|
46848
|
+
const schema2 = manager.getSchema(agentId);
|
|
46849
|
+
const keys = schema2.settings.map((setting4) => setting4.key);
|
|
46850
|
+
if (options2.json) {
|
|
46851
|
+
printJson(keys);
|
|
46852
|
+
return;
|
|
46853
|
+
}
|
|
46854
|
+
logger.titleBox(`AgentInit ${agentId} Settings`);
|
|
46855
|
+
schema2.settings.forEach((setting4, index) => logger.tree(`${cyan(setting4.key)} ${dim(setting4.category)}`, index === schema2.settings.length - 1));
|
|
46856
|
+
} catch (error) {
|
|
46857
|
+
failAgentCommand(error);
|
|
46858
|
+
}
|
|
46859
|
+
});
|
|
46860
|
+
agent.command("schema <agent>").description("Show the setting schema for an agent").option("--json", "Print JSON output").action((agentId, options2) => {
|
|
46861
|
+
try {
|
|
46862
|
+
const schema2 = manager.getSchema(agentId);
|
|
46863
|
+
if (options2.json) {
|
|
46864
|
+
printJson(schema2);
|
|
46865
|
+
return;
|
|
46866
|
+
}
|
|
46867
|
+
logger.titleBox(`AgentInit ${schema2.displayName} Schema`);
|
|
46868
|
+
logger.info(`Default omitted scope: ${cyan(schema2.effectiveDefaultScope)}`);
|
|
46869
|
+
for (const setting4 of schema2.settings) {
|
|
46870
|
+
const flags = [
|
|
46871
|
+
setting4.valueType,
|
|
46872
|
+
setting4.category,
|
|
46873
|
+
setting4.risk !== "safe" ? setting4.risk : null,
|
|
46874
|
+
setting4.deprecated ? `use ${setting4.replacement}` : null
|
|
46875
|
+
].filter(Boolean).join(", ");
|
|
46876
|
+
logger.tree(`${cyan(setting4.key)} ${dim(`[${flags}]`)} ${setting4.description}`, false);
|
|
46877
|
+
}
|
|
46878
|
+
} catch (error) {
|
|
46879
|
+
failAgentCommand(error);
|
|
46880
|
+
}
|
|
46881
|
+
});
|
|
46882
|
+
}
|
|
46883
|
+
|
|
45140
46884
|
// dist/cli.js
|
|
45141
46885
|
init_logger();
|
|
45142
46886
|
var program2 = new Command;
|
|
@@ -45147,6 +46891,7 @@ registerRulesCommand(program2);
|
|
|
45147
46891
|
registerPluginsCommand(program2);
|
|
45148
46892
|
registerConfigCommand(program2);
|
|
45149
46893
|
registerLockCommand(program2);
|
|
46894
|
+
registerAgentCommand(program2);
|
|
45150
46895
|
program2.command("init").description("Initialize agents.md configuration for the current project").option("-f, --force", "Overwrite existing configuration").option("-t, --template <template>", "Use specific template (web, cli, library)").action(initCommand);
|
|
45151
46896
|
program2.command("detect").description("Detect current project stack and existing agent configurations").option("-v, --verbose", "Show detailed detection results").action(detectCommand);
|
|
45152
46897
|
program2.command("sync").description("Sync agents.md with agent-specific configuration files").option("-a, --agent <agents...>", "Target specific agent(s)").option("-d, --dry-run", "Show what would be changed without making changes").option("-b, --backup", "Create backup before syncing").action(syncCommand);
|