@kyo-so/cli 0.5.0 → 0.7.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 +48 -0
- package/README.ja.md +62 -29
- package/README.md +62 -29
- package/README.zh-CN.md +62 -29
- package/dist/bin/kyoso.js +1594 -208
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/config/loadConfig.d.ts +8 -0
- package/dist/config/projectScope.d.ts +15 -0
- package/dist/config/schema.d.ts +5 -0
- package/dist/config/tomlConfigLoader.d.ts +1 -0
- package/dist/core/constants.d.ts +1 -1
- package/dist/core/types.d.ts +1 -0
- package/dist/index.js +1478 -125
- package/examples/claude-only.toml +2 -0
- package/examples/codex-only.toml +2 -0
- package/examples/kyoso.toml +11 -0
- package/package.json +2 -1
- package/examples/claude-only.config.ts +0 -9
- package/examples/codex-only.config.ts +0 -9
- package/examples/kyoso.config.ts +0 -22
package/dist/index.js
CHANGED
|
@@ -8124,7 +8124,7 @@ ${lanes.join(`
|
|
|
8124
8124
|
writeOutputIsTTY() {
|
|
8125
8125
|
return process.stdout.isTTY;
|
|
8126
8126
|
},
|
|
8127
|
-
readFile,
|
|
8127
|
+
readFile: readFile2,
|
|
8128
8128
|
writeFile: writeFile2,
|
|
8129
8129
|
watchFile: watchFile2,
|
|
8130
8130
|
watchDirectory,
|
|
@@ -8317,7 +8317,7 @@ ${lanes.join(`
|
|
|
8317
8317
|
function fsWatchWorker(fileOrDirectory, recursive, callback) {
|
|
8318
8318
|
return _fs.watch(fileOrDirectory, fsSupportsRecursiveFsWatch ? { persistent: true, recursive: !!recursive } : { persistent: true }, callback);
|
|
8319
8319
|
}
|
|
8320
|
-
function
|
|
8320
|
+
function readFile2(fileName, _encoding) {
|
|
8321
8321
|
let buffer;
|
|
8322
8322
|
try {
|
|
8323
8323
|
buffer = _fs.readFileSync(fileName);
|
|
@@ -39384,7 +39384,7 @@ ${lanes.join(`
|
|
|
39384
39384
|
const possibleOption = getSpellingSuggestion(unknownOption, diagnostics.optionDeclarations, getOptionName);
|
|
39385
39385
|
return possibleOption ? createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics.unknownDidYouMeanDiagnostic, unknownOptionErrorText || unknownOption, possibleOption.name) : createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics.unknownOptionDiagnostic, unknownOptionErrorText || unknownOption);
|
|
39386
39386
|
}
|
|
39387
|
-
function parseCommandLineWorker(diagnostics, commandLine,
|
|
39387
|
+
function parseCommandLineWorker(diagnostics, commandLine, readFile2) {
|
|
39388
39388
|
const options = {};
|
|
39389
39389
|
let watchOptions;
|
|
39390
39390
|
const fileNames = [];
|
|
@@ -39422,7 +39422,7 @@ ${lanes.join(`
|
|
|
39422
39422
|
}
|
|
39423
39423
|
}
|
|
39424
39424
|
function parseResponseFile(fileName) {
|
|
39425
|
-
const text = tryReadFile(fileName,
|
|
39425
|
+
const text = tryReadFile(fileName, readFile2 || ((fileName2) => sys.readFile(fileName2)));
|
|
39426
39426
|
if (!isString(text)) {
|
|
39427
39427
|
errors3.push(text);
|
|
39428
39428
|
return;
|
|
@@ -39525,8 +39525,8 @@ ${lanes.join(`
|
|
|
39525
39525
|
unknownDidYouMeanDiagnostic: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1,
|
|
39526
39526
|
optionTypeMismatchDiagnostic: Diagnostics.Compiler_option_0_expects_an_argument
|
|
39527
39527
|
};
|
|
39528
|
-
function parseCommandLine(commandLine,
|
|
39529
|
-
return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine,
|
|
39528
|
+
function parseCommandLine(commandLine, readFile2) {
|
|
39529
|
+
return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine, readFile2);
|
|
39530
39530
|
}
|
|
39531
39531
|
function getOptionFromName(optionName, allowShort) {
|
|
39532
39532
|
return getOptionDeclarationFromName(getOptionsNameMap, optionName, allowShort);
|
|
@@ -39594,8 +39594,8 @@ ${lanes.join(`
|
|
|
39594
39594
|
result.originalFileName = result.fileName;
|
|
39595
39595
|
return parseJsonSourceFileConfigFileContent(result, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd), undefined, extraFileExtensions, extendedConfigCache, watchOptionsToExtend);
|
|
39596
39596
|
}
|
|
39597
|
-
function readConfigFile(fileName,
|
|
39598
|
-
const textOrDiagnostic = tryReadFile(fileName,
|
|
39597
|
+
function readConfigFile(fileName, readFile2) {
|
|
39598
|
+
const textOrDiagnostic = tryReadFile(fileName, readFile2);
|
|
39599
39599
|
return isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
|
|
39600
39600
|
}
|
|
39601
39601
|
function parseConfigFileTextToJson(fileName, jsonText) {
|
|
@@ -39605,14 +39605,14 @@ ${lanes.join(`
|
|
|
39605
39605
|
error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined
|
|
39606
39606
|
};
|
|
39607
39607
|
}
|
|
39608
|
-
function readJsonConfigFile(fileName,
|
|
39609
|
-
const textOrDiagnostic = tryReadFile(fileName,
|
|
39608
|
+
function readJsonConfigFile(fileName, readFile2) {
|
|
39609
|
+
const textOrDiagnostic = tryReadFile(fileName, readFile2);
|
|
39610
39610
|
return isString(textOrDiagnostic) ? parseJsonText(fileName, textOrDiagnostic) : { fileName, parseDiagnostics: [textOrDiagnostic] };
|
|
39611
39611
|
}
|
|
39612
|
-
function tryReadFile(fileName,
|
|
39612
|
+
function tryReadFile(fileName, readFile2) {
|
|
39613
39613
|
let text;
|
|
39614
39614
|
try {
|
|
39615
|
-
text =
|
|
39615
|
+
text = readFile2(fileName);
|
|
39616
39616
|
} catch (e) {
|
|
39617
39617
|
return createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message);
|
|
39618
39618
|
}
|
|
@@ -107509,12 +107509,12 @@ ${lanes.join(`
|
|
|
107509
107509
|
function createCompilerHost(options, setParentNodes) {
|
|
107510
107510
|
return createCompilerHostWorker(options, setParentNodes);
|
|
107511
107511
|
}
|
|
107512
|
-
function createGetSourceFile(
|
|
107512
|
+
function createGetSourceFile(readFile2, setParentNodes) {
|
|
107513
107513
|
return (fileName, languageVersionOrOptions, onError) => {
|
|
107514
107514
|
let text;
|
|
107515
107515
|
try {
|
|
107516
107516
|
mark("beforeIORead");
|
|
107517
|
-
text =
|
|
107517
|
+
text = readFile2(fileName);
|
|
107518
107518
|
mark("afterIORead");
|
|
107519
107519
|
measure("I/O Read", "beforeIORead", "afterIORead");
|
|
107520
107520
|
} catch (e) {
|
|
@@ -108305,7 +108305,7 @@ ${lanes.join(`
|
|
|
108305
108305
|
getRedirectFromOutput,
|
|
108306
108306
|
forEachResolvedProjectReference: forEachResolvedProjectReference2
|
|
108307
108307
|
});
|
|
108308
|
-
const
|
|
108308
|
+
const readFile2 = host.readFile.bind(host);
|
|
108309
108309
|
(_e = tracing) == null || _e.push(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram });
|
|
108310
108310
|
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
|
|
108311
108311
|
(_f = tracing) == null || _f.pop();
|
|
@@ -108482,7 +108482,7 @@ ${lanes.join(`
|
|
|
108482
108482
|
shouldTransformImportCall,
|
|
108483
108483
|
emitBuildInfo,
|
|
108484
108484
|
fileExists,
|
|
108485
|
-
readFile,
|
|
108485
|
+
readFile: readFile2,
|
|
108486
108486
|
directoryExists,
|
|
108487
108487
|
getSymlinkCache,
|
|
108488
108488
|
realpath: (_o = host.realpath) == null ? undefined : _o.bind(host),
|
|
@@ -121384,7 +121384,7 @@ ${lanes.join(`
|
|
|
121384
121384
|
if (importingFile !== usableByFileName)
|
|
121385
121385
|
return;
|
|
121386
121386
|
return forEachEntry(exportInfo, (info, key2) => {
|
|
121387
|
-
const { symbolName: symbolName2, ambientModuleName } =
|
|
121387
|
+
const { symbolName: symbolName2, ambientModuleName } = parseKey2(key2);
|
|
121388
121388
|
const name = preferCapitalized && info[0].capitalizedSymbolName || symbolName2;
|
|
121389
121389
|
if (matches(name, info[0].targetFlags)) {
|
|
121390
121390
|
const rehydrated = info.map(rehydrateCachedInfo);
|
|
@@ -121448,7 +121448,7 @@ ${lanes.join(`
|
|
|
121448
121448
|
const moduleKey = ambientModuleName || "";
|
|
121449
121449
|
return `${importedName.length} ${getSymbolId(skipAlias(symbol2, checker))} ${importedName} ${moduleKey}`;
|
|
121450
121450
|
}
|
|
121451
|
-
function
|
|
121451
|
+
function parseKey2(key2) {
|
|
121452
121452
|
const firstSpace = key2.indexOf(" ");
|
|
121453
121453
|
const secondSpace = key2.indexOf(" ", firstSpace + 1);
|
|
121454
121454
|
const symbolNameLength = parseInt(key2.substring(0, firstSpace), 10);
|
|
@@ -150512,14 +150512,14 @@ ${newComment.split(`
|
|
|
150512
150512
|
});
|
|
150513
150513
|
function mapCode(sourceFile, contents, focusLocations, host, formatContext, preferences) {
|
|
150514
150514
|
return ts_textChanges_exports.ChangeTracker.with({ host, formatContext, preferences }, (changeTracker) => {
|
|
150515
|
-
const parsed = contents.map((c) =>
|
|
150515
|
+
const parsed = contents.map((c) => parse6(sourceFile, c));
|
|
150516
150516
|
const flattenedLocations = focusLocations && flatten(focusLocations);
|
|
150517
150517
|
for (const nodes of parsed) {
|
|
150518
150518
|
placeNodeGroup(sourceFile, changeTracker, nodes, flattenedLocations);
|
|
150519
150519
|
}
|
|
150520
150520
|
});
|
|
150521
150521
|
}
|
|
150522
|
-
function
|
|
150522
|
+
function parse6(sourceFile, content) {
|
|
150523
150523
|
const nodeKinds = [
|
|
150524
150524
|
{
|
|
150525
150525
|
parse: () => createSourceFile("__mapcode_content_nodes.ts", content, sourceFile.languageVersion, true, sourceFile.scriptKind),
|
|
@@ -183783,6 +183783,7 @@ var agentSchema = exports_external.object({
|
|
|
183783
183783
|
command: exports_external.string(),
|
|
183784
183784
|
args: exports_external.array(exports_external.string()).default([]),
|
|
183785
183785
|
model: exports_external.string().optional(),
|
|
183786
|
+
effort: exports_external.string().optional(),
|
|
183786
183787
|
role: exports_external.enum([
|
|
183787
183788
|
"implementation_reviewer",
|
|
183788
183789
|
"architecture_security_reviewer",
|
|
@@ -183863,6 +183864,80 @@ var kyosoConfigSchema = exports_external.object({
|
|
|
183863
183864
|
includeFileContents: exports_external.boolean()
|
|
183864
183865
|
})
|
|
183865
183866
|
});
|
|
183867
|
+
function agentConfigLeafPaths(agent) {
|
|
183868
|
+
return [
|
|
183869
|
+
`agents.${agent}.enabled`,
|
|
183870
|
+
`agents.${agent}.type`,
|
|
183871
|
+
`agents.${agent}.command`,
|
|
183872
|
+
`agents.${agent}.args`,
|
|
183873
|
+
`agents.${agent}.model`,
|
|
183874
|
+
`agents.${agent}.effort`,
|
|
183875
|
+
`agents.${agent}.role`,
|
|
183876
|
+
`agents.${agent}.timeoutMs`,
|
|
183877
|
+
`agents.${agent}.env`,
|
|
183878
|
+
`agents.${agent}.auth.mode`,
|
|
183879
|
+
`agents.${agent}.auth.preferExistingLogin`,
|
|
183880
|
+
`agents.${agent}.auth.preferApiKey`,
|
|
183881
|
+
`agents.${agent}.auth.recommendedEnv`,
|
|
183882
|
+
`agents.${agent}.auth.envWhitelist`
|
|
183883
|
+
];
|
|
183884
|
+
}
|
|
183885
|
+
var kyosoConfigKnownLeafPaths = [
|
|
183886
|
+
"entrypoints.mcp",
|
|
183887
|
+
"entrypoints.cli",
|
|
183888
|
+
"firstClassClient",
|
|
183889
|
+
"tools.planReview",
|
|
183890
|
+
"tools.securityReview",
|
|
183891
|
+
"tools.diffReview",
|
|
183892
|
+
...agentConfigLeafPaths("codex"),
|
|
183893
|
+
...agentConfigLeafPaths("claude"),
|
|
183894
|
+
"workspace.mode",
|
|
183895
|
+
"workspace.root",
|
|
183896
|
+
"workspace.readOnly",
|
|
183897
|
+
"workspace.maxContextBytes",
|
|
183898
|
+
"workspace.maxDiffBytes",
|
|
183899
|
+
"workspace.deny",
|
|
183900
|
+
"secrets.mode",
|
|
183901
|
+
"secrets.blockOnDetectedSecret",
|
|
183902
|
+
"secrets.allowOverride",
|
|
183903
|
+
"network.defaultMode",
|
|
183904
|
+
"network.allowUnrestricted",
|
|
183905
|
+
"network.warnOnUnrestricted",
|
|
183906
|
+
"network.mediatedWeb.enabled",
|
|
183907
|
+
"securityReview.cisaSecureByDesign.enabled",
|
|
183908
|
+
"securityReview.cisaSecureByDesign.gate",
|
|
183909
|
+
"securityReview.cisaSecureByDesign.dimensions.customerSecurityOutcomes",
|
|
183910
|
+
"securityReview.cisaSecureByDesign.dimensions.secureByDefault",
|
|
183911
|
+
"securityReview.cisaSecureByDesign.dimensions.transparencyAndAccountability",
|
|
183912
|
+
"securityReview.cisaSecureByDesign.dimensions.governance",
|
|
183913
|
+
"judge.mode",
|
|
183914
|
+
"judge.provider",
|
|
183915
|
+
"judge.timeoutMs",
|
|
183916
|
+
"verification.enabled",
|
|
183917
|
+
"verification.maxFindings",
|
|
183918
|
+
"verification.timeoutMs",
|
|
183919
|
+
"verification.allowDemotion",
|
|
183920
|
+
"audit.enabled",
|
|
183921
|
+
"audit.format",
|
|
183922
|
+
"audit.directory",
|
|
183923
|
+
"audit.includeRawAgentOutput",
|
|
183924
|
+
"audit.includeFileContents"
|
|
183925
|
+
];
|
|
183926
|
+
var kyosoConfigRecordPrefixes = [
|
|
183927
|
+
"agents.codex.env",
|
|
183928
|
+
"agents.claude.env"
|
|
183929
|
+
];
|
|
183930
|
+
var kyosoConfigSecuritySensitivePrefixes = [
|
|
183931
|
+
"agents.codex",
|
|
183932
|
+
"agents.claude",
|
|
183933
|
+
"audit",
|
|
183934
|
+
"judge",
|
|
183935
|
+
"network",
|
|
183936
|
+
"secrets",
|
|
183937
|
+
"securityReview",
|
|
183938
|
+
"verification",
|
|
183939
|
+
"workspace"
|
|
183940
|
+
];
|
|
183866
183941
|
|
|
183867
183942
|
// src/config/defaultConfig.ts
|
|
183868
183943
|
var defaultConfig = {
|
|
@@ -183904,7 +183979,7 @@ var defaultConfig = {
|
|
|
183904
183979
|
command: "npx",
|
|
183905
183980
|
args: ["-y", "@agentclientprotocol/claude-agent-acp@0.57.0"],
|
|
183906
183981
|
role: "architecture_security_reviewer",
|
|
183907
|
-
timeoutMs:
|
|
183982
|
+
timeoutMs: 300000,
|
|
183908
183983
|
env: {
|
|
183909
183984
|
KYOSO_CHILD_AGENT: "1"
|
|
183910
183985
|
},
|
|
@@ -183993,11 +184068,1157 @@ var defaultConfig = {
|
|
|
183993
184068
|
};
|
|
183994
184069
|
|
|
183995
184070
|
// src/config/loadConfig.ts
|
|
183996
|
-
import { access, readFile as
|
|
184071
|
+
import { access, readFile as readFile3 } from "node:fs/promises";
|
|
184072
|
+
import { homedir as homedir2 } from "node:os";
|
|
183997
184073
|
import { stderr, stdin } from "node:process";
|
|
183998
|
-
import { resolve as resolve2 } from "node:path";
|
|
184074
|
+
import { extname as extname2, join as join2, resolve as resolve2 } from "node:path";
|
|
183999
184075
|
import { createInterface } from "node:readline/promises";
|
|
184000
184076
|
|
|
184077
|
+
// src/config/projectScope.ts
|
|
184078
|
+
var PROJECT_GLOBAL_ONLY_MESSAGE = "Move global-only settings to the user global config:";
|
|
184079
|
+
function mergeProjectTomlConfig(baseConfig, projectConfig, options) {
|
|
184080
|
+
const violations = collectProjectScopeViolations(projectConfig);
|
|
184081
|
+
if (violations.length > 0) {
|
|
184082
|
+
throw new Error(formatProjectScopeError(violations, options));
|
|
184083
|
+
}
|
|
184084
|
+
const projectDeny = readPath(projectConfig, ["workspace", "deny"]);
|
|
184085
|
+
const mergeableProjectConfig = omitPath(projectConfig, ["workspace", "deny"]);
|
|
184086
|
+
const merged = deepMerge(baseConfig, mergeableProjectConfig);
|
|
184087
|
+
if (projectDeny !== undefined) {
|
|
184088
|
+
writePath(merged, ["workspace", "deny"], Array.isArray(projectDeny) && allStrings(projectDeny) ? unionStrings(readStringArray(baseConfig, ["workspace", "deny"]), [
|
|
184089
|
+
...projectDeny
|
|
184090
|
+
]) : projectDeny);
|
|
184091
|
+
}
|
|
184092
|
+
return merged;
|
|
184093
|
+
}
|
|
184094
|
+
function collectProjectScopeViolations(config2) {
|
|
184095
|
+
const leaves = flattenLeaves(config2);
|
|
184096
|
+
const violations = [];
|
|
184097
|
+
for (const leaf of leaves) {
|
|
184098
|
+
const path = leaf.path.join(".");
|
|
184099
|
+
if (!isAllowedProjectPath(leaf.path)) {
|
|
184100
|
+
violations.push({ path });
|
|
184101
|
+
continue;
|
|
184102
|
+
}
|
|
184103
|
+
const reason = tightenOnlyReason(leaf.path, leaf.value);
|
|
184104
|
+
if (reason)
|
|
184105
|
+
violations.push({ path, reason });
|
|
184106
|
+
}
|
|
184107
|
+
return violations.sort((left, right) => left.path.localeCompare(right.path));
|
|
184108
|
+
}
|
|
184109
|
+
function isAllowedProjectPath(path) {
|
|
184110
|
+
const [top, second, third, fourth] = path;
|
|
184111
|
+
if (top === "tools" && path.length === 2 && ["planReview", "securityReview", "diffReview"].includes(second ?? "")) {
|
|
184112
|
+
return true;
|
|
184113
|
+
}
|
|
184114
|
+
if (top === "agents" && path.length === 3 && ["codex", "claude"].includes(second ?? "") && ["enabled", "model", "effort", "role", "timeoutMs"].includes(third ?? "")) {
|
|
184115
|
+
return true;
|
|
184116
|
+
}
|
|
184117
|
+
if (top === "verification" && path.length === 2 && ["enabled", "maxFindings", "timeoutMs"].includes(second ?? "")) {
|
|
184118
|
+
return true;
|
|
184119
|
+
}
|
|
184120
|
+
if (top === "workspace" && path.length === 2 && ["maxContextBytes", "maxDiffBytes", "deny"].includes(second ?? "")) {
|
|
184121
|
+
return true;
|
|
184122
|
+
}
|
|
184123
|
+
if (top === "network" && second === "defaultMode" && path.length === 2) {
|
|
184124
|
+
return true;
|
|
184125
|
+
}
|
|
184126
|
+
if (top === "secrets" && path.length === 2 && ["blockOnDetectedSecret", "allowOverride"].includes(second ?? "")) {
|
|
184127
|
+
return true;
|
|
184128
|
+
}
|
|
184129
|
+
if (top === "judge" && path.length === 2 && ["mode", "provider", "timeoutMs"].includes(second ?? "")) {
|
|
184130
|
+
return true;
|
|
184131
|
+
}
|
|
184132
|
+
if (top === "securityReview" && second === "cisaSecureByDesign" && path.length >= 3) {
|
|
184133
|
+
if (third === "dimensions") {
|
|
184134
|
+
return path.length === 4 && [
|
|
184135
|
+
"customerSecurityOutcomes",
|
|
184136
|
+
"secureByDefault",
|
|
184137
|
+
"transparencyAndAccountability",
|
|
184138
|
+
"governance"
|
|
184139
|
+
].includes(fourth ?? "");
|
|
184140
|
+
}
|
|
184141
|
+
return path.length === 3 && ["enabled", "gate"].includes(third ?? "");
|
|
184142
|
+
}
|
|
184143
|
+
return false;
|
|
184144
|
+
}
|
|
184145
|
+
function tightenOnlyReason(path, value) {
|
|
184146
|
+
const dotted = path.join(".");
|
|
184147
|
+
if (dotted === "network.defaultMode" && value !== "model_only") {
|
|
184148
|
+
return 'must be "model_only" in project TOML';
|
|
184149
|
+
}
|
|
184150
|
+
if (dotted === "secrets.blockOnDetectedSecret" && value !== true) {
|
|
184151
|
+
return "must be true in project TOML";
|
|
184152
|
+
}
|
|
184153
|
+
if (dotted === "secrets.allowOverride" && value !== false) {
|
|
184154
|
+
return "must be false in project TOML";
|
|
184155
|
+
}
|
|
184156
|
+
if (path[0] === "securityReview" && path[1] === "cisaSecureByDesign" && value !== true) {
|
|
184157
|
+
return "must be true in project TOML";
|
|
184158
|
+
}
|
|
184159
|
+
return;
|
|
184160
|
+
}
|
|
184161
|
+
function formatProjectScopeError(violations, options) {
|
|
184162
|
+
const entries = violations.map((violation) => violation.reason ? `${violation.path} (${violation.reason})` : violation.path);
|
|
184163
|
+
return [
|
|
184164
|
+
`Project TOML config ${options.projectPath} contains settings that are not allowed in project scope: ${entries.join(", ")}`,
|
|
184165
|
+
`${PROJECT_GLOBAL_ONLY_MESSAGE} ${options.globalConfigPath}. If a key is misspelled, fix the name instead.`
|
|
184166
|
+
].join(`
|
|
184167
|
+
`);
|
|
184168
|
+
}
|
|
184169
|
+
function flattenLeaves(value, path = []) {
|
|
184170
|
+
if (!isRecord(value))
|
|
184171
|
+
return path.length > 0 ? [{ path, value }] : [];
|
|
184172
|
+
const entries = Object.entries(value);
|
|
184173
|
+
if (entries.length === 0)
|
|
184174
|
+
return path.length > 0 ? [{ path, value }] : [];
|
|
184175
|
+
return entries.flatMap(([key, child]) => flattenLeaves(child, [...path, key]));
|
|
184176
|
+
}
|
|
184177
|
+
function omitPath(value, path) {
|
|
184178
|
+
if (!isRecord(value) || path.length === 0)
|
|
184179
|
+
return value;
|
|
184180
|
+
const [head, ...tail] = path;
|
|
184181
|
+
if (head === undefined)
|
|
184182
|
+
return value;
|
|
184183
|
+
const result = { ...value };
|
|
184184
|
+
if (tail.length === 0) {
|
|
184185
|
+
delete result[head];
|
|
184186
|
+
} else {
|
|
184187
|
+
const child = omitPath(result[head], tail);
|
|
184188
|
+
if (isRecord(child) && Object.keys(child).length === 0) {
|
|
184189
|
+
delete result[head];
|
|
184190
|
+
} else {
|
|
184191
|
+
result[head] = child;
|
|
184192
|
+
}
|
|
184193
|
+
}
|
|
184194
|
+
return result;
|
|
184195
|
+
}
|
|
184196
|
+
function readPath(value, path) {
|
|
184197
|
+
let current = value;
|
|
184198
|
+
for (const key of path) {
|
|
184199
|
+
if (!isRecord(current))
|
|
184200
|
+
return;
|
|
184201
|
+
current = current[key];
|
|
184202
|
+
}
|
|
184203
|
+
return current;
|
|
184204
|
+
}
|
|
184205
|
+
function writePath(target, path, value) {
|
|
184206
|
+
if (!isRecord(target))
|
|
184207
|
+
return;
|
|
184208
|
+
let current = target;
|
|
184209
|
+
for (const key of path.slice(0, -1)) {
|
|
184210
|
+
const child = current[key];
|
|
184211
|
+
if (!isRecord(child)) {
|
|
184212
|
+
current[key] = {};
|
|
184213
|
+
}
|
|
184214
|
+
current = current[key];
|
|
184215
|
+
}
|
|
184216
|
+
const leaf = path.at(-1);
|
|
184217
|
+
if (leaf)
|
|
184218
|
+
current[leaf] = value;
|
|
184219
|
+
}
|
|
184220
|
+
function readStringArray(value, path) {
|
|
184221
|
+
const found = readPath(value, path);
|
|
184222
|
+
return Array.isArray(found) && allStrings(found) ? [...found] : [];
|
|
184223
|
+
}
|
|
184224
|
+
function unionStrings(base, override) {
|
|
184225
|
+
return [...new Set([...base, ...override])];
|
|
184226
|
+
}
|
|
184227
|
+
function allStrings(values) {
|
|
184228
|
+
return values.every((value) => typeof value === "string");
|
|
184229
|
+
}
|
|
184230
|
+
function deepMerge(base, override) {
|
|
184231
|
+
if (!isRecord(base) || !isRecord(override))
|
|
184232
|
+
return override ?? base;
|
|
184233
|
+
const result = { ...base };
|
|
184234
|
+
for (const [key, value] of Object.entries(override)) {
|
|
184235
|
+
result[key] = deepMerge(result[key], value);
|
|
184236
|
+
}
|
|
184237
|
+
return result;
|
|
184238
|
+
}
|
|
184239
|
+
function isRecord(value) {
|
|
184240
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
184241
|
+
}
|
|
184242
|
+
|
|
184243
|
+
// src/security/redact.ts
|
|
184244
|
+
var REDACTION = "[KYOSO_REDACTED]";
|
|
184245
|
+
|
|
184246
|
+
// src/core/constants.ts
|
|
184247
|
+
var DEFAULT_AGENT_TIMEOUT_MS = 120000;
|
|
184248
|
+
var RAW_OUTPUT_MAX_CHARS = 16384;
|
|
184249
|
+
var KYOSO_CHILD_AGENT = "KYOSO_CHILD_AGENT";
|
|
184250
|
+
|
|
184251
|
+
// src/security/sanitizeText.ts
|
|
184252
|
+
var SENSITIVE_TEXT_PATTERNS = [
|
|
184253
|
+
/\bsk-(?:proj-)?[A-Za-z0-9_-]{8,}\b/g,
|
|
184254
|
+
/\bsk-ant-[A-Za-z0-9_-]{8,}\b/g,
|
|
184255
|
+
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{8,}\b/g,
|
|
184256
|
+
/\bAKIA[0-9A-Z]{8,}\b/g,
|
|
184257
|
+
/\bxox[baprs]-[A-Za-z0-9-]{8,}\b/g,
|
|
184258
|
+
/\bsk_(?:live|test)_[A-Za-z0-9]{8,}\b/g,
|
|
184259
|
+
/\b(?:api[_-]?key|secret|token|password)\b\s*[:=]\s*["']?[A-Za-z0-9_./+=-]{8,}["']?/gi
|
|
184260
|
+
];
|
|
184261
|
+
function sanitizeText(value) {
|
|
184262
|
+
return SENSITIVE_TEXT_PATTERNS.reduce((text, pattern) => text.replace(pattern, REDACTION), value);
|
|
184263
|
+
}
|
|
184264
|
+
function sanitizeTextForDisplay(value, maxChars = 240) {
|
|
184265
|
+
const compact = sanitizeText(value).replace(/\s+/g, " ").trim();
|
|
184266
|
+
if (compact.length <= maxChars)
|
|
184267
|
+
return compact;
|
|
184268
|
+
return `${compact.slice(0, Math.max(0, maxChars - 3))}...`;
|
|
184269
|
+
}
|
|
184270
|
+
function sanitizeTextForRawOutput(value, maxChars = RAW_OUTPUT_MAX_CHARS) {
|
|
184271
|
+
const sanitized = sanitizeText(value);
|
|
184272
|
+
const limit = Math.max(0, maxChars);
|
|
184273
|
+
if (sanitized.length <= limit)
|
|
184274
|
+
return sanitized;
|
|
184275
|
+
return `${sanitized.slice(0, limit)}
|
|
184276
|
+
[KYOSO_TRUNCATED: ${sanitized.length - limit} chars omitted]`;
|
|
184277
|
+
}
|
|
184278
|
+
|
|
184279
|
+
// src/config/tomlConfigLoader.ts
|
|
184280
|
+
import { readFile } from "node:fs/promises";
|
|
184281
|
+
|
|
184282
|
+
// node_modules/smol-toml/dist/date.js
|
|
184283
|
+
/*!
|
|
184284
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
184285
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
184286
|
+
*
|
|
184287
|
+
* Redistribution and use in source and binary forms, with or without
|
|
184288
|
+
* modification, are permitted provided that the following conditions are met:
|
|
184289
|
+
*
|
|
184290
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
184291
|
+
* list of conditions and the following disclaimer.
|
|
184292
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
184293
|
+
* this list of conditions and the following disclaimer in the
|
|
184294
|
+
* documentation and/or other materials provided with the distribution.
|
|
184295
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
184296
|
+
* may be used to endorse or promote products derived from this software without
|
|
184297
|
+
* specific prior written permission.
|
|
184298
|
+
*
|
|
184299
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
184300
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
184301
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
184302
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
184303
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
184304
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
184305
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
184306
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
184307
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
184308
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
184309
|
+
*/
|
|
184310
|
+
var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
|
|
184311
|
+
|
|
184312
|
+
class TomlDate extends Date {
|
|
184313
|
+
#hasDate = false;
|
|
184314
|
+
#hasTime = false;
|
|
184315
|
+
#offset = null;
|
|
184316
|
+
constructor(date5) {
|
|
184317
|
+
let hasDate = true;
|
|
184318
|
+
let hasTime = true;
|
|
184319
|
+
let offset = "Z";
|
|
184320
|
+
if (typeof date5 === "string") {
|
|
184321
|
+
let match = date5.match(DATE_TIME_RE);
|
|
184322
|
+
if (match) {
|
|
184323
|
+
if (!match[1]) {
|
|
184324
|
+
hasDate = false;
|
|
184325
|
+
date5 = `0000-01-01T${date5}`;
|
|
184326
|
+
}
|
|
184327
|
+
hasTime = !!match[2];
|
|
184328
|
+
hasTime && date5[10] === " " && (date5 = date5.replace(" ", "T"));
|
|
184329
|
+
if (match[2] && +match[2] > 23) {
|
|
184330
|
+
date5 = "";
|
|
184331
|
+
} else {
|
|
184332
|
+
offset = match[3] || null;
|
|
184333
|
+
date5 = date5.toUpperCase();
|
|
184334
|
+
if (!offset && hasTime)
|
|
184335
|
+
date5 += "Z";
|
|
184336
|
+
}
|
|
184337
|
+
} else {
|
|
184338
|
+
date5 = "";
|
|
184339
|
+
}
|
|
184340
|
+
}
|
|
184341
|
+
super(date5);
|
|
184342
|
+
if (!isNaN(this.getTime())) {
|
|
184343
|
+
this.#hasDate = hasDate;
|
|
184344
|
+
this.#hasTime = hasTime;
|
|
184345
|
+
this.#offset = offset;
|
|
184346
|
+
}
|
|
184347
|
+
}
|
|
184348
|
+
isDateTime() {
|
|
184349
|
+
return this.#hasDate && this.#hasTime;
|
|
184350
|
+
}
|
|
184351
|
+
isLocal() {
|
|
184352
|
+
return !this.#hasDate || !this.#hasTime || !this.#offset;
|
|
184353
|
+
}
|
|
184354
|
+
isDate() {
|
|
184355
|
+
return this.#hasDate && !this.#hasTime;
|
|
184356
|
+
}
|
|
184357
|
+
isTime() {
|
|
184358
|
+
return this.#hasTime && !this.#hasDate;
|
|
184359
|
+
}
|
|
184360
|
+
isValid() {
|
|
184361
|
+
return this.#hasDate || this.#hasTime;
|
|
184362
|
+
}
|
|
184363
|
+
toISOString() {
|
|
184364
|
+
let iso = super.toISOString();
|
|
184365
|
+
if (this.isDate())
|
|
184366
|
+
return iso.slice(0, 10);
|
|
184367
|
+
if (this.isTime())
|
|
184368
|
+
return iso.slice(11, 23);
|
|
184369
|
+
if (this.#offset === null)
|
|
184370
|
+
return iso.slice(0, -1);
|
|
184371
|
+
if (this.#offset === "Z")
|
|
184372
|
+
return iso;
|
|
184373
|
+
let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
|
|
184374
|
+
offset = this.#offset[0] === "-" ? offset : -offset;
|
|
184375
|
+
let offsetDate = new Date(this.getTime() - offset * 60000);
|
|
184376
|
+
return offsetDate.toISOString().slice(0, -1) + this.#offset;
|
|
184377
|
+
}
|
|
184378
|
+
static wrapAsOffsetDateTime(jsDate, offset = "Z") {
|
|
184379
|
+
let date5 = new TomlDate(jsDate);
|
|
184380
|
+
date5.#offset = offset;
|
|
184381
|
+
return date5;
|
|
184382
|
+
}
|
|
184383
|
+
static wrapAsLocalDateTime(jsDate) {
|
|
184384
|
+
let date5 = new TomlDate(jsDate);
|
|
184385
|
+
date5.#offset = null;
|
|
184386
|
+
return date5;
|
|
184387
|
+
}
|
|
184388
|
+
static wrapAsLocalDate(jsDate) {
|
|
184389
|
+
let date5 = new TomlDate(jsDate);
|
|
184390
|
+
date5.#hasTime = false;
|
|
184391
|
+
date5.#offset = null;
|
|
184392
|
+
return date5;
|
|
184393
|
+
}
|
|
184394
|
+
static wrapAsLocalTime(jsDate) {
|
|
184395
|
+
let date5 = new TomlDate(jsDate);
|
|
184396
|
+
date5.#hasDate = false;
|
|
184397
|
+
date5.#offset = null;
|
|
184398
|
+
return date5;
|
|
184399
|
+
}
|
|
184400
|
+
}
|
|
184401
|
+
|
|
184402
|
+
// node_modules/smol-toml/dist/error.js
|
|
184403
|
+
/*!
|
|
184404
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
184405
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
184406
|
+
*
|
|
184407
|
+
* Redistribution and use in source and binary forms, with or without
|
|
184408
|
+
* modification, are permitted provided that the following conditions are met:
|
|
184409
|
+
*
|
|
184410
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
184411
|
+
* list of conditions and the following disclaimer.
|
|
184412
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
184413
|
+
* this list of conditions and the following disclaimer in the
|
|
184414
|
+
* documentation and/or other materials provided with the distribution.
|
|
184415
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
184416
|
+
* may be used to endorse or promote products derived from this software without
|
|
184417
|
+
* specific prior written permission.
|
|
184418
|
+
*
|
|
184419
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
184420
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
184421
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
184422
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
184423
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
184424
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
184425
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
184426
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
184427
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
184428
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
184429
|
+
*/
|
|
184430
|
+
function getLineColFromPtr(string4, ptr) {
|
|
184431
|
+
let lines = string4.slice(0, ptr).split(/\r\n|\n|\r/g);
|
|
184432
|
+
return [lines.length, lines.pop().length + 1];
|
|
184433
|
+
}
|
|
184434
|
+
function makeCodeBlock(string4, line, column) {
|
|
184435
|
+
let lines = string4.split(/\r\n|\n|\r/g);
|
|
184436
|
+
let codeblock = "";
|
|
184437
|
+
let numberLen = (Math.log10(line + 1) | 0) + 1;
|
|
184438
|
+
for (let i = line - 1;i <= line + 1; i++) {
|
|
184439
|
+
let l = lines[i - 1];
|
|
184440
|
+
if (!l)
|
|
184441
|
+
continue;
|
|
184442
|
+
codeblock += i.toString().padEnd(numberLen, " ");
|
|
184443
|
+
codeblock += ": ";
|
|
184444
|
+
codeblock += l;
|
|
184445
|
+
codeblock += `
|
|
184446
|
+
`;
|
|
184447
|
+
if (i === line) {
|
|
184448
|
+
codeblock += " ".repeat(numberLen + column + 2);
|
|
184449
|
+
codeblock += `^
|
|
184450
|
+
`;
|
|
184451
|
+
}
|
|
184452
|
+
}
|
|
184453
|
+
return codeblock;
|
|
184454
|
+
}
|
|
184455
|
+
|
|
184456
|
+
class TomlError extends Error {
|
|
184457
|
+
line;
|
|
184458
|
+
column;
|
|
184459
|
+
codeblock;
|
|
184460
|
+
constructor(message, options) {
|
|
184461
|
+
const [line, column] = getLineColFromPtr(options.toml, options.ptr);
|
|
184462
|
+
const codeblock = makeCodeBlock(options.toml, line, column);
|
|
184463
|
+
super(`Invalid TOML document: ${message}
|
|
184464
|
+
|
|
184465
|
+
${codeblock}`, options);
|
|
184466
|
+
this.line = line;
|
|
184467
|
+
this.column = column;
|
|
184468
|
+
this.codeblock = codeblock;
|
|
184469
|
+
}
|
|
184470
|
+
}
|
|
184471
|
+
|
|
184472
|
+
// node_modules/smol-toml/dist/primitive.js
|
|
184473
|
+
/*!
|
|
184474
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
184475
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
184476
|
+
*
|
|
184477
|
+
* Redistribution and use in source and binary forms, with or without
|
|
184478
|
+
* modification, are permitted provided that the following conditions are met:
|
|
184479
|
+
*
|
|
184480
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
184481
|
+
* list of conditions and the following disclaimer.
|
|
184482
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
184483
|
+
* this list of conditions and the following disclaimer in the
|
|
184484
|
+
* documentation and/or other materials provided with the distribution.
|
|
184485
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
184486
|
+
* may be used to endorse or promote products derived from this software without
|
|
184487
|
+
* specific prior written permission.
|
|
184488
|
+
*
|
|
184489
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
184490
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
184491
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
184492
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
184493
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
184494
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
184495
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
184496
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
184497
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
184498
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
184499
|
+
*/
|
|
184500
|
+
var INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
|
|
184501
|
+
var FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
|
|
184502
|
+
var LEADING_ZERO = /^[+-]?0[0-9_]/;
|
|
184503
|
+
function parseString(str, ptr) {
|
|
184504
|
+
let c = str[ptr++];
|
|
184505
|
+
let first = c;
|
|
184506
|
+
let isLiteral = c === "'";
|
|
184507
|
+
let isMultiline = c === str[ptr] && c === str[ptr + 1];
|
|
184508
|
+
if (isMultiline) {
|
|
184509
|
+
if (str[ptr += 2] === `
|
|
184510
|
+
`)
|
|
184511
|
+
ptr++;
|
|
184512
|
+
else if (str[ptr] === "\r" && str[ptr + 1] === `
|
|
184513
|
+
`)
|
|
184514
|
+
ptr += 2;
|
|
184515
|
+
}
|
|
184516
|
+
let parsed = "";
|
|
184517
|
+
let sliceStart = ptr;
|
|
184518
|
+
let state = 0;
|
|
184519
|
+
for (let i = ptr;i < str.length; i++) {
|
|
184520
|
+
c = str[i];
|
|
184521
|
+
if (isMultiline && (c === `
|
|
184522
|
+
` || c === "\r" && str[i + 1] === `
|
|
184523
|
+
`)) {
|
|
184524
|
+
state = state && 3;
|
|
184525
|
+
} else if (c < " " && c !== "\t" || c === "") {
|
|
184526
|
+
throw new TomlError("control characters are not allowed in strings", {
|
|
184527
|
+
toml: str,
|
|
184528
|
+
ptr: i
|
|
184529
|
+
});
|
|
184530
|
+
} else if ((!state || state === 3) && c === first && (!isMultiline || str[i + 1] === first && str[i + 2] === first)) {
|
|
184531
|
+
if (isMultiline) {
|
|
184532
|
+
if (str[i + 3] === first)
|
|
184533
|
+
i++;
|
|
184534
|
+
if (str[i + 3] === first)
|
|
184535
|
+
i++;
|
|
184536
|
+
}
|
|
184537
|
+
return [
|
|
184538
|
+
state ? parsed : parsed + str.slice(sliceStart, i),
|
|
184539
|
+
i + (isMultiline ? 3 : 1)
|
|
184540
|
+
];
|
|
184541
|
+
} else if (!state) {
|
|
184542
|
+
if (!isLiteral && c === "\\") {
|
|
184543
|
+
parsed += str.slice(sliceStart, sliceStart = i);
|
|
184544
|
+
state = 1;
|
|
184545
|
+
}
|
|
184546
|
+
} else if (state === 1) {
|
|
184547
|
+
if (c === "x" || c === "u" || c === "U") {
|
|
184548
|
+
let value = 0;
|
|
184549
|
+
let len = c === "x" ? 2 : c === "u" ? 4 : 8;
|
|
184550
|
+
for (let j = 0;j < len; j++, i++) {
|
|
184551
|
+
let hex3 = str.charCodeAt(i + 1);
|
|
184552
|
+
let digit = hex3 >= 48 && hex3 <= 57 ? hex3 - 48 : hex3 >= 65 && hex3 <= 70 ? hex3 - 65 + 10 : hex3 >= 97 && hex3 <= 102 ? hex3 - 97 + 10 : -1;
|
|
184553
|
+
if (digit < 0)
|
|
184554
|
+
throw new TomlError("invalid non-hex character in unicode escape", { toml: str, ptr: i + 1 });
|
|
184555
|
+
value = value << 4 | digit;
|
|
184556
|
+
}
|
|
184557
|
+
if (value < 0 || value > 1114111 || value >= 55296 && value <= 57343) {
|
|
184558
|
+
throw new TomlError("invalid unicode escape", { toml: str, ptr: i });
|
|
184559
|
+
}
|
|
184560
|
+
parsed += String.fromCodePoint(value);
|
|
184561
|
+
sliceStart = i + 1;
|
|
184562
|
+
state = 0;
|
|
184563
|
+
} else if (c === " " || c === "\t") {
|
|
184564
|
+
state = 2;
|
|
184565
|
+
} else {
|
|
184566
|
+
if (c === "b")
|
|
184567
|
+
parsed += "\b";
|
|
184568
|
+
else if (c === "t")
|
|
184569
|
+
parsed += "\t";
|
|
184570
|
+
else if (c === "n")
|
|
184571
|
+
parsed += `
|
|
184572
|
+
`;
|
|
184573
|
+
else if (c === "f")
|
|
184574
|
+
parsed += "\f";
|
|
184575
|
+
else if (c === "r")
|
|
184576
|
+
parsed += "\r";
|
|
184577
|
+
else if (c === "e")
|
|
184578
|
+
parsed += "\x1B";
|
|
184579
|
+
else if (c === '"')
|
|
184580
|
+
parsed += '"';
|
|
184581
|
+
else if (c === "\\")
|
|
184582
|
+
parsed += "\\";
|
|
184583
|
+
else
|
|
184584
|
+
throw new TomlError("unrecognized escape sequence", { toml: str, ptr: i });
|
|
184585
|
+
sliceStart = i + 1;
|
|
184586
|
+
state = 0;
|
|
184587
|
+
}
|
|
184588
|
+
} else if (c !== " " && c !== "\t") {
|
|
184589
|
+
if (state === 2) {
|
|
184590
|
+
throw new TomlError("invalid escape: only line-ending whitespace may be escaped", {
|
|
184591
|
+
toml: str,
|
|
184592
|
+
ptr: sliceStart
|
|
184593
|
+
});
|
|
184594
|
+
}
|
|
184595
|
+
state = !isLiteral && c === "\\" ? 1 : 0;
|
|
184596
|
+
sliceStart = i;
|
|
184597
|
+
}
|
|
184598
|
+
}
|
|
184599
|
+
throw new TomlError("unfinished string", { toml: str, ptr });
|
|
184600
|
+
}
|
|
184601
|
+
function parseValue(value, toml, ptr, integersAsBigInt) {
|
|
184602
|
+
if (value === "true")
|
|
184603
|
+
return true;
|
|
184604
|
+
if (value === "false")
|
|
184605
|
+
return false;
|
|
184606
|
+
if (value === "-inf")
|
|
184607
|
+
return -Infinity;
|
|
184608
|
+
if (value === "inf" || value === "+inf")
|
|
184609
|
+
return Infinity;
|
|
184610
|
+
if (value === "nan" || value === "+nan" || value === "-nan")
|
|
184611
|
+
return NaN;
|
|
184612
|
+
if (value === "-0")
|
|
184613
|
+
return integersAsBigInt ? 0n : 0;
|
|
184614
|
+
let isInt = INT_REGEX.test(value);
|
|
184615
|
+
if (isInt || FLOAT_REGEX.test(value)) {
|
|
184616
|
+
if (LEADING_ZERO.test(value)) {
|
|
184617
|
+
throw new TomlError("leading zeroes are not allowed", {
|
|
184618
|
+
toml,
|
|
184619
|
+
ptr
|
|
184620
|
+
});
|
|
184621
|
+
}
|
|
184622
|
+
value = value.replace(/_/g, "");
|
|
184623
|
+
let numeric = +value;
|
|
184624
|
+
if (isNaN(numeric)) {
|
|
184625
|
+
throw new TomlError("invalid number", {
|
|
184626
|
+
toml,
|
|
184627
|
+
ptr
|
|
184628
|
+
});
|
|
184629
|
+
}
|
|
184630
|
+
if (isInt) {
|
|
184631
|
+
if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {
|
|
184632
|
+
throw new TomlError("integer value cannot be represented losslessly", {
|
|
184633
|
+
toml,
|
|
184634
|
+
ptr
|
|
184635
|
+
});
|
|
184636
|
+
}
|
|
184637
|
+
if (isInt || integersAsBigInt === true)
|
|
184638
|
+
numeric = BigInt(value);
|
|
184639
|
+
}
|
|
184640
|
+
return numeric;
|
|
184641
|
+
}
|
|
184642
|
+
const date5 = new TomlDate(value);
|
|
184643
|
+
if (!date5.isValid()) {
|
|
184644
|
+
throw new TomlError("invalid value", {
|
|
184645
|
+
toml,
|
|
184646
|
+
ptr
|
|
184647
|
+
});
|
|
184648
|
+
}
|
|
184649
|
+
return date5;
|
|
184650
|
+
}
|
|
184651
|
+
|
|
184652
|
+
// node_modules/smol-toml/dist/util.js
|
|
184653
|
+
/*!
|
|
184654
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
184655
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
184656
|
+
*
|
|
184657
|
+
* Redistribution and use in source and binary forms, with or without
|
|
184658
|
+
* modification, are permitted provided that the following conditions are met:
|
|
184659
|
+
*
|
|
184660
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
184661
|
+
* list of conditions and the following disclaimer.
|
|
184662
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
184663
|
+
* this list of conditions and the following disclaimer in the
|
|
184664
|
+
* documentation and/or other materials provided with the distribution.
|
|
184665
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
184666
|
+
* may be used to endorse or promote products derived from this software without
|
|
184667
|
+
* specific prior written permission.
|
|
184668
|
+
*
|
|
184669
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
184670
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
184671
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
184672
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
184673
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
184674
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
184675
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
184676
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
184677
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
184678
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
184679
|
+
*/
|
|
184680
|
+
function indexOfNewline(str, start = 0, end = str.length) {
|
|
184681
|
+
let idx = str.indexOf(`
|
|
184682
|
+
`, start);
|
|
184683
|
+
if (str[idx - 1] === "\r")
|
|
184684
|
+
idx--;
|
|
184685
|
+
return idx <= end ? idx : -1;
|
|
184686
|
+
}
|
|
184687
|
+
function skipComment(str, ptr) {
|
|
184688
|
+
for (let i = ptr;i < str.length; i++) {
|
|
184689
|
+
let c = str[i];
|
|
184690
|
+
if (c === `
|
|
184691
|
+
`)
|
|
184692
|
+
return i;
|
|
184693
|
+
if (c === "\r" && str[i + 1] === `
|
|
184694
|
+
`)
|
|
184695
|
+
return i + 1;
|
|
184696
|
+
if (c < " " && c !== "\t" || c === "") {
|
|
184697
|
+
throw new TomlError("control characters are not allowed in comments", {
|
|
184698
|
+
toml: str,
|
|
184699
|
+
ptr
|
|
184700
|
+
});
|
|
184701
|
+
}
|
|
184702
|
+
}
|
|
184703
|
+
return str.length;
|
|
184704
|
+
}
|
|
184705
|
+
function skipVoid(str, ptr, banNewLines, banComments) {
|
|
184706
|
+
let c;
|
|
184707
|
+
while (true) {
|
|
184708
|
+
while ((c = str[ptr]) === " " || c === "\t" || !banNewLines && (c === `
|
|
184709
|
+
` || c === "\r" && str[ptr + 1] === `
|
|
184710
|
+
`))
|
|
184711
|
+
ptr++;
|
|
184712
|
+
if (banComments || c !== "#")
|
|
184713
|
+
break;
|
|
184714
|
+
ptr = skipComment(str, ptr);
|
|
184715
|
+
}
|
|
184716
|
+
return ptr;
|
|
184717
|
+
}
|
|
184718
|
+
function skipUntil(str, ptr, sep, end, banNewLines = false) {
|
|
184719
|
+
if (!end) {
|
|
184720
|
+
ptr = indexOfNewline(str, ptr);
|
|
184721
|
+
return ptr < 0 ? str.length : ptr;
|
|
184722
|
+
}
|
|
184723
|
+
for (let i = ptr;i < str.length; i++) {
|
|
184724
|
+
let c = str[i];
|
|
184725
|
+
if (c === "#") {
|
|
184726
|
+
i = indexOfNewline(str, i);
|
|
184727
|
+
} else if (c === sep) {
|
|
184728
|
+
return i + 1;
|
|
184729
|
+
} else if (c === end || banNewLines && (c === `
|
|
184730
|
+
` || c === "\r" && str[i + 1] === `
|
|
184731
|
+
`)) {
|
|
184732
|
+
return i;
|
|
184733
|
+
}
|
|
184734
|
+
}
|
|
184735
|
+
throw new TomlError("cannot find end of structure", {
|
|
184736
|
+
toml: str,
|
|
184737
|
+
ptr
|
|
184738
|
+
});
|
|
184739
|
+
}
|
|
184740
|
+
|
|
184741
|
+
// node_modules/smol-toml/dist/extract.js
|
|
184742
|
+
/*!
|
|
184743
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
184744
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
184745
|
+
*
|
|
184746
|
+
* Redistribution and use in source and binary forms, with or without
|
|
184747
|
+
* modification, are permitted provided that the following conditions are met:
|
|
184748
|
+
*
|
|
184749
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
184750
|
+
* list of conditions and the following disclaimer.
|
|
184751
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
184752
|
+
* this list of conditions and the following disclaimer in the
|
|
184753
|
+
* documentation and/or other materials provided with the distribution.
|
|
184754
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
184755
|
+
* may be used to endorse or promote products derived from this software without
|
|
184756
|
+
* specific prior written permission.
|
|
184757
|
+
*
|
|
184758
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
184759
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
184760
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
184761
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
184762
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
184763
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
184764
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
184765
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
184766
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
184767
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
184768
|
+
*/
|
|
184769
|
+
function sliceAndTrimEndOf(str, startPtr, endPtr) {
|
|
184770
|
+
let value = str.slice(startPtr, endPtr);
|
|
184771
|
+
let commentIdx = value.indexOf("#");
|
|
184772
|
+
if (commentIdx > -1) {
|
|
184773
|
+
skipComment(str, commentIdx);
|
|
184774
|
+
value = value.slice(0, commentIdx);
|
|
184775
|
+
}
|
|
184776
|
+
return [value.trimEnd(), commentIdx];
|
|
184777
|
+
}
|
|
184778
|
+
function extractValue(str, ptr, end, depth, integersAsBigInt) {
|
|
184779
|
+
if (depth === 0) {
|
|
184780
|
+
throw new TomlError("document contains excessively nested structures. aborting.", {
|
|
184781
|
+
toml: str,
|
|
184782
|
+
ptr
|
|
184783
|
+
});
|
|
184784
|
+
}
|
|
184785
|
+
let c = str[ptr];
|
|
184786
|
+
if (c === "[" || c === "{") {
|
|
184787
|
+
let [value, endPtr2] = c === "[" ? parseArray(str, ptr, depth, integersAsBigInt) : parseInlineTable(str, ptr, depth, integersAsBigInt);
|
|
184788
|
+
if (end) {
|
|
184789
|
+
endPtr2 = skipVoid(str, endPtr2);
|
|
184790
|
+
if (str[endPtr2] === ",")
|
|
184791
|
+
endPtr2++;
|
|
184792
|
+
else if (str[endPtr2] !== end) {
|
|
184793
|
+
throw new TomlError("expected comma or end of structure", {
|
|
184794
|
+
toml: str,
|
|
184795
|
+
ptr: endPtr2
|
|
184796
|
+
});
|
|
184797
|
+
}
|
|
184798
|
+
}
|
|
184799
|
+
return [value, endPtr2];
|
|
184800
|
+
}
|
|
184801
|
+
if (c === '"' || c === "'") {
|
|
184802
|
+
let [parsed, endPtr2] = parseString(str, ptr);
|
|
184803
|
+
if (end) {
|
|
184804
|
+
endPtr2 = skipVoid(str, endPtr2);
|
|
184805
|
+
if (str[endPtr2] && str[endPtr2] !== "," && str[endPtr2] !== end && str[endPtr2] !== `
|
|
184806
|
+
` && str[endPtr2] !== "\r") {
|
|
184807
|
+
throw new TomlError("unexpected character encountered", {
|
|
184808
|
+
toml: str,
|
|
184809
|
+
ptr: endPtr2
|
|
184810
|
+
});
|
|
184811
|
+
}
|
|
184812
|
+
if (str[endPtr2] === ",")
|
|
184813
|
+
endPtr2++;
|
|
184814
|
+
}
|
|
184815
|
+
return [parsed, endPtr2];
|
|
184816
|
+
}
|
|
184817
|
+
let endPtr = skipUntil(str, ptr, ",", end);
|
|
184818
|
+
let slice = sliceAndTrimEndOf(str, ptr, endPtr - (str[endPtr - 1] === "," ? 1 : 0));
|
|
184819
|
+
if (!slice[0]) {
|
|
184820
|
+
throw new TomlError("incomplete key-value declaration: no value specified", {
|
|
184821
|
+
toml: str,
|
|
184822
|
+
ptr
|
|
184823
|
+
});
|
|
184824
|
+
}
|
|
184825
|
+
if (end && slice[1] > -1) {
|
|
184826
|
+
endPtr = skipVoid(str, ptr + slice[1]);
|
|
184827
|
+
if (str[endPtr] === ",")
|
|
184828
|
+
endPtr++;
|
|
184829
|
+
}
|
|
184830
|
+
return [
|
|
184831
|
+
parseValue(slice[0], str, ptr, integersAsBigInt),
|
|
184832
|
+
endPtr
|
|
184833
|
+
];
|
|
184834
|
+
}
|
|
184835
|
+
|
|
184836
|
+
// node_modules/smol-toml/dist/struct.js
|
|
184837
|
+
/*!
|
|
184838
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
184839
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
184840
|
+
*
|
|
184841
|
+
* Redistribution and use in source and binary forms, with or without
|
|
184842
|
+
* modification, are permitted provided that the following conditions are met:
|
|
184843
|
+
*
|
|
184844
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
184845
|
+
* list of conditions and the following disclaimer.
|
|
184846
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
184847
|
+
* this list of conditions and the following disclaimer in the
|
|
184848
|
+
* documentation and/or other materials provided with the distribution.
|
|
184849
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
184850
|
+
* may be used to endorse or promote products derived from this software without
|
|
184851
|
+
* specific prior written permission.
|
|
184852
|
+
*
|
|
184853
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
184854
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
184855
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
184856
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
184857
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
184858
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
184859
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
184860
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
184861
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
184862
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
184863
|
+
*/
|
|
184864
|
+
var KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
|
|
184865
|
+
function parseKey(str, ptr, end = "=") {
|
|
184866
|
+
let dot = ptr - 1;
|
|
184867
|
+
let parsed = [];
|
|
184868
|
+
let endPtr = str.indexOf(end, ptr);
|
|
184869
|
+
if (endPtr < 0) {
|
|
184870
|
+
throw new TomlError("incomplete key-value: cannot find end of key", {
|
|
184871
|
+
toml: str,
|
|
184872
|
+
ptr
|
|
184873
|
+
});
|
|
184874
|
+
}
|
|
184875
|
+
do {
|
|
184876
|
+
let c = str[ptr = ++dot];
|
|
184877
|
+
if (c !== " " && c !== "\t") {
|
|
184878
|
+
if (c === '"' || c === "'") {
|
|
184879
|
+
if (c === str[ptr + 1] && c === str[ptr + 2]) {
|
|
184880
|
+
throw new TomlError("multiline strings are not allowed in keys", {
|
|
184881
|
+
toml: str,
|
|
184882
|
+
ptr
|
|
184883
|
+
});
|
|
184884
|
+
}
|
|
184885
|
+
let [part, eos] = parseString(str, ptr);
|
|
184886
|
+
dot = str.indexOf(".", eos);
|
|
184887
|
+
let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot);
|
|
184888
|
+
let newLine = indexOfNewline(strEnd);
|
|
184889
|
+
if (newLine > -1) {
|
|
184890
|
+
throw new TomlError("newlines are not allowed in keys", {
|
|
184891
|
+
toml: str,
|
|
184892
|
+
ptr: ptr + dot + newLine
|
|
184893
|
+
});
|
|
184894
|
+
}
|
|
184895
|
+
if (strEnd.trimStart()) {
|
|
184896
|
+
throw new TomlError("found extra tokens after the string part", {
|
|
184897
|
+
toml: str,
|
|
184898
|
+
ptr: eos
|
|
184899
|
+
});
|
|
184900
|
+
}
|
|
184901
|
+
if (endPtr < eos) {
|
|
184902
|
+
endPtr = str.indexOf(end, eos);
|
|
184903
|
+
if (endPtr < 0) {
|
|
184904
|
+
throw new TomlError("incomplete key-value: cannot find end of key", {
|
|
184905
|
+
toml: str,
|
|
184906
|
+
ptr
|
|
184907
|
+
});
|
|
184908
|
+
}
|
|
184909
|
+
}
|
|
184910
|
+
parsed.push(part);
|
|
184911
|
+
} else {
|
|
184912
|
+
dot = str.indexOf(".", ptr);
|
|
184913
|
+
let part = str.slice(ptr, dot < 0 || dot > endPtr ? endPtr : dot);
|
|
184914
|
+
if (!KEY_PART_RE.test(part)) {
|
|
184915
|
+
throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys", {
|
|
184916
|
+
toml: str,
|
|
184917
|
+
ptr
|
|
184918
|
+
});
|
|
184919
|
+
}
|
|
184920
|
+
parsed.push(part.trimEnd());
|
|
184921
|
+
}
|
|
184922
|
+
}
|
|
184923
|
+
} while (dot + 1 && dot < endPtr);
|
|
184924
|
+
return [parsed, skipVoid(str, endPtr + 1, true, true)];
|
|
184925
|
+
}
|
|
184926
|
+
function parseInlineTable(str, ptr, depth, integersAsBigInt) {
|
|
184927
|
+
let res = {};
|
|
184928
|
+
let seen = new Set;
|
|
184929
|
+
let c;
|
|
184930
|
+
ptr++;
|
|
184931
|
+
while ((c = str[ptr++]) !== "}" && c) {
|
|
184932
|
+
if (c === ",") {
|
|
184933
|
+
throw new TomlError("expected value, found comma", {
|
|
184934
|
+
toml: str,
|
|
184935
|
+
ptr: ptr - 1
|
|
184936
|
+
});
|
|
184937
|
+
} else if (c === "#")
|
|
184938
|
+
ptr = skipComment(str, ptr);
|
|
184939
|
+
else if (c !== " " && c !== "\t" && c !== `
|
|
184940
|
+
` && c !== "\r") {
|
|
184941
|
+
let k;
|
|
184942
|
+
let t = res;
|
|
184943
|
+
let hasOwn = false;
|
|
184944
|
+
let [key, keyEndPtr] = parseKey(str, ptr - 1);
|
|
184945
|
+
for (let i = 0;i < key.length; i++) {
|
|
184946
|
+
if (i)
|
|
184947
|
+
t = hasOwn ? t[k] : t[k] = {};
|
|
184948
|
+
k = key[i];
|
|
184949
|
+
if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) {
|
|
184950
|
+
throw new TomlError("trying to redefine an already defined value", {
|
|
184951
|
+
toml: str,
|
|
184952
|
+
ptr
|
|
184953
|
+
});
|
|
184954
|
+
}
|
|
184955
|
+
if (!hasOwn && k === "__proto__") {
|
|
184956
|
+
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
184957
|
+
}
|
|
184958
|
+
}
|
|
184959
|
+
if (hasOwn) {
|
|
184960
|
+
throw new TomlError("trying to redefine an already defined value", {
|
|
184961
|
+
toml: str,
|
|
184962
|
+
ptr
|
|
184963
|
+
});
|
|
184964
|
+
}
|
|
184965
|
+
let [value, valueEndPtr] = extractValue(str, keyEndPtr, "}", depth - 1, integersAsBigInt);
|
|
184966
|
+
seen.add(value);
|
|
184967
|
+
t[k] = value;
|
|
184968
|
+
ptr = valueEndPtr;
|
|
184969
|
+
}
|
|
184970
|
+
}
|
|
184971
|
+
if (!c) {
|
|
184972
|
+
throw new TomlError("unfinished table encountered", {
|
|
184973
|
+
toml: str,
|
|
184974
|
+
ptr
|
|
184975
|
+
});
|
|
184976
|
+
}
|
|
184977
|
+
return [res, ptr];
|
|
184978
|
+
}
|
|
184979
|
+
function parseArray(str, ptr, depth, integersAsBigInt) {
|
|
184980
|
+
let res = [];
|
|
184981
|
+
let c;
|
|
184982
|
+
ptr++;
|
|
184983
|
+
while ((c = str[ptr++]) !== "]" && c) {
|
|
184984
|
+
if (c === ",") {
|
|
184985
|
+
throw new TomlError("expected value, found comma", {
|
|
184986
|
+
toml: str,
|
|
184987
|
+
ptr: ptr - 1
|
|
184988
|
+
});
|
|
184989
|
+
} else if (c === "#")
|
|
184990
|
+
ptr = skipComment(str, ptr);
|
|
184991
|
+
else if (c !== " " && c !== "\t" && c !== `
|
|
184992
|
+
` && c !== "\r") {
|
|
184993
|
+
let e = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
|
|
184994
|
+
res.push(e[0]);
|
|
184995
|
+
ptr = e[1];
|
|
184996
|
+
}
|
|
184997
|
+
}
|
|
184998
|
+
if (!c) {
|
|
184999
|
+
throw new TomlError("unfinished array encountered", {
|
|
185000
|
+
toml: str,
|
|
185001
|
+
ptr
|
|
185002
|
+
});
|
|
185003
|
+
}
|
|
185004
|
+
return [res, ptr];
|
|
185005
|
+
}
|
|
185006
|
+
|
|
185007
|
+
// node_modules/smol-toml/dist/parse.js
|
|
185008
|
+
/*!
|
|
185009
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
185010
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
185011
|
+
*
|
|
185012
|
+
* Redistribution and use in source and binary forms, with or without
|
|
185013
|
+
* modification, are permitted provided that the following conditions are met:
|
|
185014
|
+
*
|
|
185015
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
185016
|
+
* list of conditions and the following disclaimer.
|
|
185017
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
185018
|
+
* this list of conditions and the following disclaimer in the
|
|
185019
|
+
* documentation and/or other materials provided with the distribution.
|
|
185020
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
185021
|
+
* may be used to endorse or promote products derived from this software without
|
|
185022
|
+
* specific prior written permission.
|
|
185023
|
+
*
|
|
185024
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
185025
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
185026
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
185027
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
185028
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
185029
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
185030
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
185031
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
185032
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
185033
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
185034
|
+
*/
|
|
185035
|
+
function peekTable(key, table, meta3, type) {
|
|
185036
|
+
let t = table;
|
|
185037
|
+
let m = meta3;
|
|
185038
|
+
let k;
|
|
185039
|
+
let hasOwn = false;
|
|
185040
|
+
let state;
|
|
185041
|
+
for (let i = 0;i < key.length; i++) {
|
|
185042
|
+
if (i) {
|
|
185043
|
+
t = hasOwn ? t[k] : t[k] = {};
|
|
185044
|
+
m = (state = m[k]).c;
|
|
185045
|
+
if (type === 0 && (state.t === 1 || state.t === 2)) {
|
|
185046
|
+
return null;
|
|
185047
|
+
}
|
|
185048
|
+
if (state.t === 2) {
|
|
185049
|
+
let l = t.length - 1;
|
|
185050
|
+
t = t[l];
|
|
185051
|
+
m = m[l].c;
|
|
185052
|
+
}
|
|
185053
|
+
}
|
|
185054
|
+
k = key[i];
|
|
185055
|
+
if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) {
|
|
185056
|
+
return null;
|
|
185057
|
+
}
|
|
185058
|
+
if (!hasOwn) {
|
|
185059
|
+
if (k === "__proto__") {
|
|
185060
|
+
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
185061
|
+
Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
|
|
185062
|
+
}
|
|
185063
|
+
m[k] = {
|
|
185064
|
+
t: i < key.length - 1 && type === 2 ? 3 : type,
|
|
185065
|
+
d: false,
|
|
185066
|
+
i: 0,
|
|
185067
|
+
c: {}
|
|
185068
|
+
};
|
|
185069
|
+
}
|
|
185070
|
+
}
|
|
185071
|
+
state = m[k];
|
|
185072
|
+
if (state.t !== type && !(type === 1 && state.t === 3)) {
|
|
185073
|
+
return null;
|
|
185074
|
+
}
|
|
185075
|
+
if (type === 2) {
|
|
185076
|
+
if (!state.d) {
|
|
185077
|
+
state.d = true;
|
|
185078
|
+
t[k] = [];
|
|
185079
|
+
}
|
|
185080
|
+
t[k].push(t = {});
|
|
185081
|
+
state.c[state.i++] = state = { t: 1, d: false, i: 0, c: {} };
|
|
185082
|
+
}
|
|
185083
|
+
if (state.d) {
|
|
185084
|
+
return null;
|
|
185085
|
+
}
|
|
185086
|
+
state.d = true;
|
|
185087
|
+
if (type === 1) {
|
|
185088
|
+
t = hasOwn ? t[k] : t[k] = {};
|
|
185089
|
+
} else if (type === 0 && hasOwn) {
|
|
185090
|
+
return null;
|
|
185091
|
+
}
|
|
185092
|
+
return [k, t, state.c];
|
|
185093
|
+
}
|
|
185094
|
+
function parse5(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
|
|
185095
|
+
let res = {};
|
|
185096
|
+
let meta3 = {};
|
|
185097
|
+
let tbl = res;
|
|
185098
|
+
let m = meta3;
|
|
185099
|
+
for (let ptr = skipVoid(toml, 0);ptr < toml.length; ) {
|
|
185100
|
+
if (toml[ptr] === "[") {
|
|
185101
|
+
let isTableArray = toml[++ptr] === "[";
|
|
185102
|
+
let k = parseKey(toml, ptr += +isTableArray, "]");
|
|
185103
|
+
if (isTableArray) {
|
|
185104
|
+
if (toml[k[1] - 1] !== "]") {
|
|
185105
|
+
throw new TomlError("expected end of table declaration", {
|
|
185106
|
+
toml,
|
|
185107
|
+
ptr: k[1] - 1
|
|
185108
|
+
});
|
|
185109
|
+
}
|
|
185110
|
+
k[1]++;
|
|
185111
|
+
}
|
|
185112
|
+
let p = peekTable(k[0], res, meta3, isTableArray ? 2 : 1);
|
|
185113
|
+
if (!p) {
|
|
185114
|
+
throw new TomlError("trying to redefine an already defined table or value", {
|
|
185115
|
+
toml,
|
|
185116
|
+
ptr
|
|
185117
|
+
});
|
|
185118
|
+
}
|
|
185119
|
+
m = p[2];
|
|
185120
|
+
tbl = p[1];
|
|
185121
|
+
ptr = k[1];
|
|
185122
|
+
} else {
|
|
185123
|
+
let k = parseKey(toml, ptr);
|
|
185124
|
+
let p = peekTable(k[0], tbl, m, 0);
|
|
185125
|
+
if (!p) {
|
|
185126
|
+
throw new TomlError("trying to redefine an already defined table or value", {
|
|
185127
|
+
toml,
|
|
185128
|
+
ptr
|
|
185129
|
+
});
|
|
185130
|
+
}
|
|
185131
|
+
let v = extractValue(toml, k[1], undefined, maxDepth, integersAsBigInt);
|
|
185132
|
+
p[1][p[0]] = v[0];
|
|
185133
|
+
ptr = v[1];
|
|
185134
|
+
}
|
|
185135
|
+
ptr = skipVoid(toml, ptr, true);
|
|
185136
|
+
if (toml[ptr] && toml[ptr] !== `
|
|
185137
|
+
` && toml[ptr] !== "\r") {
|
|
185138
|
+
throw new TomlError("each key-value declaration must be followed by an end-of-line", {
|
|
185139
|
+
toml,
|
|
185140
|
+
ptr
|
|
185141
|
+
});
|
|
185142
|
+
}
|
|
185143
|
+
ptr = skipVoid(toml, ptr);
|
|
185144
|
+
}
|
|
185145
|
+
return res;
|
|
185146
|
+
}
|
|
185147
|
+
|
|
185148
|
+
// node_modules/smol-toml/dist/stringify.js
|
|
185149
|
+
/*!
|
|
185150
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
185151
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
185152
|
+
*
|
|
185153
|
+
* Redistribution and use in source and binary forms, with or without
|
|
185154
|
+
* modification, are permitted provided that the following conditions are met:
|
|
185155
|
+
*
|
|
185156
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
185157
|
+
* list of conditions and the following disclaimer.
|
|
185158
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
185159
|
+
* this list of conditions and the following disclaimer in the
|
|
185160
|
+
* documentation and/or other materials provided with the distribution.
|
|
185161
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
185162
|
+
* may be used to endorse or promote products derived from this software without
|
|
185163
|
+
* specific prior written permission.
|
|
185164
|
+
*
|
|
185165
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
185166
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
185167
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
185168
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
185169
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
185170
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
185171
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
185172
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
185173
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
185174
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
185175
|
+
*/
|
|
185176
|
+
|
|
185177
|
+
// node_modules/smol-toml/dist/index.js
|
|
185178
|
+
/*!
|
|
185179
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
185180
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
185181
|
+
*
|
|
185182
|
+
* Redistribution and use in source and binary forms, with or without
|
|
185183
|
+
* modification, are permitted provided that the following conditions are met:
|
|
185184
|
+
*
|
|
185185
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
185186
|
+
* list of conditions and the following disclaimer.
|
|
185187
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
185188
|
+
* this list of conditions and the following disclaimer in the
|
|
185189
|
+
* documentation and/or other materials provided with the distribution.
|
|
185190
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
185191
|
+
* may be used to endorse or promote products derived from this software without
|
|
185192
|
+
* specific prior written permission.
|
|
185193
|
+
*
|
|
185194
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
185195
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
185196
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
185197
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
185198
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
185199
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
185200
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
185201
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
185202
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
185203
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
185204
|
+
*/
|
|
185205
|
+
|
|
185206
|
+
// src/config/tomlConfigLoader.ts
|
|
185207
|
+
async function loadTomlConfigFile(configPath) {
|
|
185208
|
+
const source = await readFile(configPath, "utf8");
|
|
185209
|
+
try {
|
|
185210
|
+
return parse5(source);
|
|
185211
|
+
} catch (error51) {
|
|
185212
|
+
throw new Error(formatTomlError(configPath, error51));
|
|
185213
|
+
}
|
|
185214
|
+
}
|
|
185215
|
+
function formatTomlError(configPath, error51) {
|
|
185216
|
+
if (error51 instanceof TomlError) {
|
|
185217
|
+
return `TOML config parse failed for ${configPath} at ${error51.line}:${error51.column}: ${error51.message}`;
|
|
185218
|
+
}
|
|
185219
|
+
return `TOML config parse failed for ${configPath}: ${error51 instanceof Error ? error51.message : String(error51)}`;
|
|
185220
|
+
}
|
|
185221
|
+
|
|
184001
185222
|
// src/config/tsConfigLoader.ts
|
|
184002
185223
|
var import_typescript = __toESM(require_typescript(), 1);
|
|
184003
185224
|
import { createRequire as createRequire2 } from "node:module";
|
|
@@ -184034,14 +185255,14 @@ ${transpiled}
|
|
|
184034
185255
|
|
|
184035
185256
|
// src/config/trustedConfig.ts
|
|
184036
185257
|
import { createHash } from "node:crypto";
|
|
184037
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
185258
|
+
import { mkdir, readFile as readFile2, writeFile } from "node:fs/promises";
|
|
184038
185259
|
import { homedir } from "node:os";
|
|
184039
185260
|
import { dirname as dirname2, join, resolve } from "node:path";
|
|
184040
185261
|
function hashConfigSource(source) {
|
|
184041
185262
|
return createHash("sha256").update(source).digest("hex");
|
|
184042
185263
|
}
|
|
184043
185264
|
function defaultTrustedConfigStorePath(env = process.env) {
|
|
184044
|
-
return env.KYOSO_TRUST_STORE_PATH ? resolve(env.KYOSO_TRUST_STORE_PATH) : join(homedir(), ".kyoso", "trusted-configs.json");
|
|
185265
|
+
return env.KYOSO_TRUST_STORE_PATH ? resolve(env.KYOSO_TRUST_STORE_PATH) : join(env.HOME ? resolve(env.HOME) : homedir(), ".kyoso", "trusted-configs.json");
|
|
184045
185266
|
}
|
|
184046
185267
|
async function isTrustedConfig(storePath, configPath, configHash) {
|
|
184047
185268
|
const store = await readTrustedConfigStore(storePath);
|
|
@@ -184060,7 +185281,7 @@ async function trustConfig(storePath, configPath, configHash) {
|
|
|
184060
185281
|
async function readTrustedConfigStore(storePath) {
|
|
184061
185282
|
let parsed;
|
|
184062
185283
|
try {
|
|
184063
|
-
parsed = JSON.parse(await
|
|
185284
|
+
parsed = JSON.parse(await readFile2(storePath, "utf8"));
|
|
184064
185285
|
} catch (error51) {
|
|
184065
185286
|
if (isMissingPathError(error51))
|
|
184066
185287
|
return {};
|
|
@@ -184068,7 +185289,7 @@ async function readTrustedConfigStore(storePath) {
|
|
|
184068
185289
|
return {};
|
|
184069
185290
|
throw error51;
|
|
184070
185291
|
}
|
|
184071
|
-
if (!
|
|
185292
|
+
if (!isRecord2(parsed))
|
|
184072
185293
|
return {};
|
|
184073
185294
|
const store = {};
|
|
184074
185295
|
for (const [configPath, configHash] of Object.entries(parsed)) {
|
|
@@ -184077,7 +185298,7 @@ async function readTrustedConfigStore(storePath) {
|
|
|
184077
185298
|
}
|
|
184078
185299
|
return store;
|
|
184079
185300
|
}
|
|
184080
|
-
function
|
|
185301
|
+
function isRecord2(value) {
|
|
184081
185302
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
184082
185303
|
}
|
|
184083
185304
|
function isMissingPathError(error51) {
|
|
@@ -184085,44 +185306,178 @@ function isMissingPathError(error51) {
|
|
|
184085
185306
|
}
|
|
184086
185307
|
|
|
184087
185308
|
// src/config/loadConfig.ts
|
|
185309
|
+
var KNOWN_GLOBAL_CONFIG_LEAF_PATHS = new Set(kyosoConfigKnownLeafPaths);
|
|
185310
|
+
var GLOBAL_CONFIG_RECORD_PREFIXES = kyosoConfigRecordPrefixes.map((path) => path.split("."));
|
|
185311
|
+
var SECURITY_SENSITIVE_GLOBAL_PREFIXES = kyosoConfigSecuritySensitivePrefixes.map((path) => path.split("."));
|
|
184088
185312
|
async function loadConfig(options = {}) {
|
|
184089
185313
|
const cwd = options.cwd ?? process.cwd();
|
|
185314
|
+
const env = options.env ?? process.env;
|
|
185315
|
+
const globalConfigPath = resolveGlobalTomlConfigPath(env);
|
|
184090
185316
|
const warnings = [];
|
|
184091
|
-
|
|
185317
|
+
const sources = [];
|
|
185318
|
+
let mergedConfig = defaultConfig;
|
|
184092
185319
|
let configPath;
|
|
184093
185320
|
let configHash;
|
|
184094
185321
|
let configTrustStatus = options.ignoreConfig ? "ignored" : "not_found";
|
|
184095
185322
|
if (!options.ignoreConfig) {
|
|
184096
|
-
|
|
184097
|
-
|
|
184098
|
-
|
|
184099
|
-
const
|
|
184100
|
-
|
|
184101
|
-
|
|
184102
|
-
|
|
184103
|
-
|
|
184104
|
-
|
|
184105
|
-
|
|
184106
|
-
|
|
185323
|
+
if (await exists(globalConfigPath)) {
|
|
185324
|
+
const globalConfig2 = await loadTomlConfigFile(globalConfigPath);
|
|
185325
|
+
const globalConfigWarnings = collectGlobalConfigWarnings(globalConfigPath, globalConfig2);
|
|
185326
|
+
const securitySensitiveWarnings = globalConfigWarnings.filter((warning) => warning.startsWith("security-sensitive unknown settings "));
|
|
185327
|
+
if (securitySensitiveWarnings.length > 0 && !options.allowUnknownConfig) {
|
|
185328
|
+
throw new Error(`Security-sensitive unknown config settings rejected. Fix the key name or pass --allow-unknown-config to continue with warnings: ${securitySensitiveWarnings.join("; ")}`);
|
|
185329
|
+
}
|
|
185330
|
+
warnings.push(...globalConfigWarnings);
|
|
185331
|
+
mergedConfig = deepMerge2(mergedConfig, globalConfig2);
|
|
185332
|
+
sources.push({ path: globalConfigPath, layer: "global_toml" });
|
|
185333
|
+
}
|
|
185334
|
+
if (options.configPath) {
|
|
185335
|
+
const explicitConfigPath = resolve2(cwd, options.configPath);
|
|
185336
|
+
if (!await exists(explicitConfigPath)) {
|
|
185337
|
+
throw new Error(`Config file not found: ${explicitConfigPath} (from --config)`);
|
|
185338
|
+
}
|
|
185339
|
+
const loaded = await loadProjectConfig({
|
|
185340
|
+
configPath: explicitConfigPath,
|
|
185341
|
+
baseConfig: mergedConfig,
|
|
185342
|
+
globalConfigPath,
|
|
184107
185343
|
options
|
|
184108
185344
|
});
|
|
184109
|
-
|
|
184110
|
-
|
|
184111
|
-
|
|
184112
|
-
|
|
184113
|
-
|
|
184114
|
-
|
|
184115
|
-
|
|
184116
|
-
|
|
185345
|
+
mergedConfig = loaded.mergedConfig;
|
|
185346
|
+
configPath = loaded.configPath;
|
|
185347
|
+
configHash = loaded.configHash;
|
|
185348
|
+
configTrustStatus = loaded.configTrustStatus;
|
|
185349
|
+
sources.push(loaded.source);
|
|
185350
|
+
warnings.push(...loaded.warnings);
|
|
185351
|
+
} else {
|
|
185352
|
+
const projectTomlPath = resolve2(cwd, "kyoso.toml");
|
|
185353
|
+
const projectTsPath = resolve2(cwd, "kyoso.config.ts");
|
|
185354
|
+
const hasProjectToml = await exists(projectTomlPath);
|
|
185355
|
+
const hasProjectTs = await exists(projectTsPath);
|
|
185356
|
+
if (hasProjectToml) {
|
|
185357
|
+
mergedConfig = mergeProjectTomlConfig(mergedConfig, await loadTomlConfigFile(projectTomlPath), { projectPath: projectTomlPath, globalConfigPath });
|
|
185358
|
+
configPath = projectTomlPath;
|
|
185359
|
+
sources.push({ path: projectTomlPath, layer: "project_toml" });
|
|
185360
|
+
if (hasProjectTs) {
|
|
185361
|
+
warnings.push(`kyoso.config.ts was ignored because kyoso.toml takes precedence: ${projectTsPath}`);
|
|
185362
|
+
}
|
|
185363
|
+
} else if (hasProjectTs) {
|
|
185364
|
+
const loaded = await loadProjectTsConfig({
|
|
185365
|
+
configPath: projectTsPath,
|
|
185366
|
+
baseConfig: mergedConfig,
|
|
185367
|
+
options
|
|
185368
|
+
});
|
|
185369
|
+
mergedConfig = loaded.mergedConfig;
|
|
185370
|
+
configPath = loaded.configPath;
|
|
185371
|
+
configHash = loaded.configHash;
|
|
185372
|
+
configTrustStatus = loaded.configTrustStatus;
|
|
185373
|
+
sources.push(loaded.source);
|
|
185374
|
+
warnings.push(...loaded.warnings);
|
|
184117
185375
|
}
|
|
184118
185376
|
}
|
|
184119
185377
|
}
|
|
184120
|
-
const parsed = kyosoConfigSchema.parse(
|
|
185378
|
+
const parsed = kyosoConfigSchema.parse(mergedConfig);
|
|
184121
185379
|
return {
|
|
184122
185380
|
config: parsed,
|
|
184123
185381
|
configPath,
|
|
184124
185382
|
configHash,
|
|
184125
185383
|
configTrustStatus,
|
|
185384
|
+
sources,
|
|
185385
|
+
warnings
|
|
185386
|
+
};
|
|
185387
|
+
}
|
|
185388
|
+
function resolveGlobalTomlConfigPath(env = process.env) {
|
|
185389
|
+
const configHome = env.XDG_CONFIG_HOME ? resolve2(env.XDG_CONFIG_HOME) : join2(env.HOME ? resolve2(env.HOME) : homedir2(), ".config");
|
|
185390
|
+
return join2(configHome, "kyoso", "config.toml");
|
|
185391
|
+
}
|
|
185392
|
+
function collectGlobalConfigWarnings(configPath, config2) {
|
|
185393
|
+
const unknownSettings = flattenLeaves(config2).map((leaf) => leaf.path).filter((path) => !isKnownGlobalConfigPath(path)).map((path) => ({
|
|
185394
|
+
path: sanitizeWarningText(path.join(".")),
|
|
185395
|
+
securitySensitive: isSecuritySensitiveGlobalPath(path)
|
|
185396
|
+
})).sort((left, right) => left.path.localeCompare(right.path));
|
|
185397
|
+
const warnings = [];
|
|
185398
|
+
const securitySensitivePaths = unknownSettings.filter((setting) => setting.securitySensitive).map((setting) => setting.path);
|
|
185399
|
+
const generalPaths = unknownSettings.filter((setting) => !setting.securitySensitive).map((setting) => setting.path);
|
|
185400
|
+
const sanitizedConfigPath = sanitizeWarningText(configPath);
|
|
185401
|
+
if (securitySensitivePaths.length > 0) {
|
|
185402
|
+
warnings.push(`security-sensitive unknown settings in ${sanitizedConfigPath} were ignored: ${formatUnknownPaths(securitySensitivePaths)}`);
|
|
185403
|
+
}
|
|
185404
|
+
if (generalPaths.length > 0) {
|
|
185405
|
+
warnings.push(`unknown settings in ${sanitizedConfigPath} were ignored: ${formatUnknownPaths(generalPaths)}`);
|
|
185406
|
+
}
|
|
185407
|
+
return warnings;
|
|
185408
|
+
}
|
|
185409
|
+
function sanitizeWarningText(value) {
|
|
185410
|
+
const withoutControlChars = value.replace(/\u001b\[[0-?]*[ -/]*[@-~]/g, "").replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
|
|
185411
|
+
return sanitizeText(withoutControlChars);
|
|
185412
|
+
}
|
|
185413
|
+
function formatUnknownPaths(paths) {
|
|
185414
|
+
return paths.map((path) => JSON.stringify(path)).join("; ");
|
|
185415
|
+
}
|
|
185416
|
+
function isSecuritySensitiveGlobalPath(path) {
|
|
185417
|
+
return SECURITY_SENSITIVE_GLOBAL_PREFIXES.some((prefix) => pathStartsWith(path, prefix));
|
|
185418
|
+
}
|
|
185419
|
+
function isKnownGlobalConfigPath(path) {
|
|
185420
|
+
if (KNOWN_GLOBAL_CONFIG_LEAF_PATHS.has(path.join(".")))
|
|
185421
|
+
return true;
|
|
185422
|
+
return GLOBAL_CONFIG_RECORD_PREFIXES.some((prefix) => pathStartsWith(path, prefix));
|
|
185423
|
+
}
|
|
185424
|
+
function pathStartsWith(path, prefix) {
|
|
185425
|
+
return path.length >= prefix.length && prefix.every((part, index) => path[index] === part);
|
|
185426
|
+
}
|
|
185427
|
+
async function loadProjectConfig(input) {
|
|
185428
|
+
const extension = extname2(input.configPath);
|
|
185429
|
+
if (extension === ".toml") {
|
|
185430
|
+
return {
|
|
185431
|
+
mergedConfig: mergeProjectTomlConfig(input.baseConfig, await loadTomlConfigFile(input.configPath), {
|
|
185432
|
+
projectPath: input.configPath,
|
|
185433
|
+
globalConfigPath: input.globalConfigPath
|
|
185434
|
+
}),
|
|
185435
|
+
configPath: input.configPath,
|
|
185436
|
+
configTrustStatus: "not_found",
|
|
185437
|
+
source: { path: input.configPath, layer: "project_toml" },
|
|
185438
|
+
warnings: []
|
|
185439
|
+
};
|
|
185440
|
+
}
|
|
185441
|
+
if (extension === ".ts") {
|
|
185442
|
+
return await loadProjectTsConfig(input);
|
|
185443
|
+
}
|
|
185444
|
+
throw new Error(`Unsupported config file extension for ${input.configPath}. Expected .toml or .ts.`);
|
|
185445
|
+
}
|
|
185446
|
+
async function loadProjectTsConfig(input) {
|
|
185447
|
+
const warnings = [
|
|
185448
|
+
'kyoso.config.ts is deprecated; migrate to kyoso.toml (see README "Configuration")'
|
|
185449
|
+
];
|
|
185450
|
+
const source = await readFile3(input.configPath, "utf8");
|
|
185451
|
+
const configHash = hashConfigSource(source);
|
|
185452
|
+
const trustStorePath = input.options.trustStorePath ?? defaultTrustedConfigStorePath(input.options.env);
|
|
185453
|
+
const trusted = await isTrustedConfig(trustStorePath, input.configPath, configHash);
|
|
185454
|
+
const trustDecision = await resolveTrustDecision({
|
|
185455
|
+
configPath: input.configPath,
|
|
185456
|
+
configHash,
|
|
185457
|
+
trusted,
|
|
185458
|
+
options: input.options
|
|
185459
|
+
});
|
|
185460
|
+
if (trustDecision.execute) {
|
|
185461
|
+
const userConfig = await loadUserConfig(input.configPath, source);
|
|
185462
|
+
if (trustDecision.shouldPersist) {
|
|
185463
|
+
await trustConfig(trustStorePath, input.configPath, configHash);
|
|
185464
|
+
}
|
|
185465
|
+
return {
|
|
185466
|
+
mergedConfig: deepMerge2(input.baseConfig, userConfig),
|
|
185467
|
+
configPath: input.configPath,
|
|
185468
|
+
configHash,
|
|
185469
|
+
configTrustStatus: trustDecision.status,
|
|
185470
|
+
source: { path: input.configPath, layer: "project_ts" },
|
|
185471
|
+
warnings
|
|
185472
|
+
};
|
|
185473
|
+
}
|
|
185474
|
+
warnings.push(`untrusted config was not executed: ${input.configPath}; run \`kyoso doctor --trust-config\` or pass \`--trust-config\` once to trust it`);
|
|
185475
|
+
return {
|
|
185476
|
+
mergedConfig: input.baseConfig,
|
|
185477
|
+
configPath: input.configPath,
|
|
185478
|
+
configHash,
|
|
185479
|
+
configTrustStatus: trustDecision.status,
|
|
185480
|
+
source: { path: input.configPath, layer: "project_ts" },
|
|
184126
185481
|
warnings
|
|
184127
185482
|
};
|
|
184128
185483
|
}
|
|
@@ -184172,16 +185527,16 @@ async function promptForConfigTrust(configPath, configHash) {
|
|
|
184172
185527
|
rl.close();
|
|
184173
185528
|
}
|
|
184174
185529
|
}
|
|
184175
|
-
function
|
|
184176
|
-
if (!
|
|
185530
|
+
function deepMerge2(base, override) {
|
|
185531
|
+
if (!isRecord3(base) || !isRecord3(override))
|
|
184177
185532
|
return override ?? base;
|
|
184178
185533
|
const result = { ...base };
|
|
184179
185534
|
for (const [key, value] of Object.entries(override)) {
|
|
184180
|
-
result[key] =
|
|
185535
|
+
result[key] = deepMerge2(result[key], value);
|
|
184181
185536
|
}
|
|
184182
185537
|
return result;
|
|
184183
185538
|
}
|
|
184184
|
-
function
|
|
185539
|
+
function isRecord3(value) {
|
|
184185
185540
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
184186
185541
|
}
|
|
184187
185542
|
async function exists(path) {
|
|
@@ -184195,7 +185550,7 @@ async function exists(path) {
|
|
|
184195
185550
|
|
|
184196
185551
|
// src/acp/AcpAgentProcess.ts
|
|
184197
185552
|
import { spawn } from "node:child_process";
|
|
184198
|
-
import { readFile as
|
|
185553
|
+
import { readFile as readFile4, realpath } from "node:fs/promises";
|
|
184199
185554
|
import { isAbsolute, relative, resolve as resolve3 } from "node:path";
|
|
184200
185555
|
import { Readable, Writable } from "node:stream";
|
|
184201
185556
|
|
|
@@ -186069,14 +187424,14 @@ function ndJsonStream(output, input) {
|
|
|
186069
187424
|
}
|
|
186070
187425
|
// node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js
|
|
186071
187426
|
var CANCEL_REQUEST_METHOD = "$/cancel_request";
|
|
186072
|
-
function
|
|
187427
|
+
function isRecord4(value) {
|
|
186073
187428
|
return typeof value === "object" && value !== null;
|
|
186074
187429
|
}
|
|
186075
187430
|
function isJsonRpcId(value) {
|
|
186076
187431
|
return value === null || typeof value === "string" || typeof value === "number" && Number.isFinite(value);
|
|
186077
187432
|
}
|
|
186078
187433
|
function cancelRequestId(params) {
|
|
186079
|
-
if (!
|
|
187434
|
+
if (!isRecord4(params) || !isJsonRpcId(params["requestId"])) {
|
|
186080
187435
|
return;
|
|
186081
187436
|
}
|
|
186082
187437
|
return params["requestId"];
|
|
@@ -186578,25 +187933,25 @@ class ConnectionBuilder {
|
|
|
186578
187933
|
describe: () => this.connectionName ?? "onReceiveMessage"
|
|
186579
187934
|
});
|
|
186580
187935
|
}
|
|
186581
|
-
onReceiveRequest(method,
|
|
187936
|
+
onReceiveRequest(method, parse6, handler) {
|
|
186582
187937
|
return this.withHandler({
|
|
186583
187938
|
handleMessage: async (message, cx) => {
|
|
186584
187939
|
if (message.kind !== "request" || message.method !== method) {
|
|
186585
187940
|
return Handled.no(message);
|
|
186586
187941
|
}
|
|
186587
|
-
const request =
|
|
187942
|
+
const request = parse6(message.params);
|
|
186588
187943
|
return await handler(request, message.responder, cx) ?? Handled.yes();
|
|
186589
187944
|
},
|
|
186590
187945
|
describe: () => `${this.connectionName ?? "request"}:${method}`
|
|
186591
187946
|
});
|
|
186592
187947
|
}
|
|
186593
|
-
onReceiveNotification(method,
|
|
187948
|
+
onReceiveNotification(method, parse6, handler) {
|
|
186594
187949
|
return this.withHandler({
|
|
186595
187950
|
handleMessage: async (message, cx) => {
|
|
186596
187951
|
if (message.kind !== "notification" || message.method !== method) {
|
|
186597
187952
|
return Handled.no(message);
|
|
186598
187953
|
}
|
|
186599
|
-
const notification =
|
|
187954
|
+
const notification = parse6(message.params);
|
|
186600
187955
|
return await handler(notification, cx) ?? Handled.yes();
|
|
186601
187956
|
},
|
|
186602
187957
|
describe: () => `${this.connectionName ?? "notification"}:${method}`
|
|
@@ -187470,42 +188825,6 @@ var legacyClientNotificationMethods = new Set([
|
|
|
187470
188825
|
CLIENT_METHODS.elicitation_complete
|
|
187471
188826
|
]);
|
|
187472
188827
|
|
|
187473
|
-
// src/security/redact.ts
|
|
187474
|
-
var REDACTION = "[KYOSO_REDACTED]";
|
|
187475
|
-
|
|
187476
|
-
// src/core/constants.ts
|
|
187477
|
-
var DEFAULT_AGENT_TIMEOUT_MS = 120000;
|
|
187478
|
-
var RAW_OUTPUT_MAX_CHARS = 16384;
|
|
187479
|
-
var KYOSO_CHILD_AGENT = "KYOSO_CHILD_AGENT";
|
|
187480
|
-
|
|
187481
|
-
// src/security/sanitizeText.ts
|
|
187482
|
-
var SENSITIVE_TEXT_PATTERNS = [
|
|
187483
|
-
/\bsk-(?:proj-)?[A-Za-z0-9_-]{8,}\b/g,
|
|
187484
|
-
/\bsk-ant-[A-Za-z0-9_-]{8,}\b/g,
|
|
187485
|
-
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{8,}\b/g,
|
|
187486
|
-
/\bAKIA[0-9A-Z]{8,}\b/g,
|
|
187487
|
-
/\bxox[baprs]-[A-Za-z0-9-]{8,}\b/g,
|
|
187488
|
-
/\bsk_(?:live|test)_[A-Za-z0-9]{8,}\b/g,
|
|
187489
|
-
/\b(?:api[_-]?key|secret|token|password)\b\s*[:=]\s*["']?[A-Za-z0-9_./+=-]{8,}["']?/gi
|
|
187490
|
-
];
|
|
187491
|
-
function sanitizeText(value) {
|
|
187492
|
-
return SENSITIVE_TEXT_PATTERNS.reduce((text, pattern) => text.replace(pattern, REDACTION), value);
|
|
187493
|
-
}
|
|
187494
|
-
function sanitizeTextForDisplay(value, maxChars = 240) {
|
|
187495
|
-
const compact = sanitizeText(value).replace(/\s+/g, " ").trim();
|
|
187496
|
-
if (compact.length <= maxChars)
|
|
187497
|
-
return compact;
|
|
187498
|
-
return `${compact.slice(0, Math.max(0, maxChars - 3))}...`;
|
|
187499
|
-
}
|
|
187500
|
-
function sanitizeTextForRawOutput(value, maxChars = RAW_OUTPUT_MAX_CHARS) {
|
|
187501
|
-
const sanitized = sanitizeText(value);
|
|
187502
|
-
const limit = Math.max(0, maxChars);
|
|
187503
|
-
if (sanitized.length <= limit)
|
|
187504
|
-
return sanitized;
|
|
187505
|
-
return `${sanitized.slice(0, limit)}
|
|
187506
|
-
[KYOSO_TRUNCATED: ${sanitized.length - limit} chars omitted]`;
|
|
187507
|
-
}
|
|
187508
|
-
|
|
187509
188828
|
// src/utils/env.ts
|
|
187510
188829
|
var MINIMAL_ENV_KEYS = [
|
|
187511
188830
|
"PATH",
|
|
@@ -187685,7 +189004,7 @@ function isSeverity(value) {
|
|
|
187685
189004
|
return typeof value === "string" && severities.includes(value);
|
|
187686
189005
|
}
|
|
187687
189006
|
function normalizeCisaSecureByDesign(value) {
|
|
187688
|
-
if (!
|
|
189007
|
+
if (!isRecord5(value))
|
|
187689
189008
|
return;
|
|
187690
189009
|
const normalized = {};
|
|
187691
189010
|
const customerSecurityOutcomes = normalizeGateStatus(value.customerSecurityOutcomes);
|
|
@@ -187726,7 +189045,7 @@ function normalizeFindingFiles(value) {
|
|
|
187726
189045
|
if (!Array.isArray(value))
|
|
187727
189046
|
return;
|
|
187728
189047
|
const files = value.flatMap((item) => {
|
|
187729
|
-
if (!
|
|
189048
|
+
if (!isRecord5(item) || typeof item.path !== "string" || item.path.trim().length === 0) {
|
|
187730
189049
|
return [];
|
|
187731
189050
|
}
|
|
187732
189051
|
const file2 = {
|
|
@@ -187745,7 +189064,7 @@ function normalizeFindingFiles(value) {
|
|
|
187745
189064
|
function normalizeLineNumber(value) {
|
|
187746
189065
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : undefined;
|
|
187747
189066
|
}
|
|
187748
|
-
function
|
|
189067
|
+
function isRecord5(value) {
|
|
187749
189068
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
187750
189069
|
}
|
|
187751
189070
|
|
|
@@ -187824,7 +189143,7 @@ async function runSubprocessAgent(agent, agentConfig, input) {
|
|
|
187824
189143
|
error: failure
|
|
187825
189144
|
});
|
|
187826
189145
|
});
|
|
187827
|
-
runAcpClientWorkflow(child, input, abortController.signal).then((rawText) => {
|
|
189146
|
+
runAcpClientWorkflow(child, input, abortController.signal, resolveEffortConfigOption(agent, agentConfig.effort)).then(({ rawText, warnings }) => {
|
|
187828
189147
|
stdout = rawText;
|
|
187829
189148
|
resolveOnce({
|
|
187830
189149
|
agent,
|
|
@@ -187833,7 +189152,8 @@ async function runSubprocessAgent(agent, agentConfig, input) {
|
|
|
187833
189152
|
rawText,
|
|
187834
189153
|
normalized: normalizeAgentOutput(agent, input.role, rawText),
|
|
187835
189154
|
startedAt,
|
|
187836
|
-
completedAt: new Date().toISOString()
|
|
189155
|
+
completedAt: new Date().toISOString(),
|
|
189156
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
187837
189157
|
});
|
|
187838
189158
|
}).catch((error51) => {
|
|
187839
189159
|
if (abortController.signal.aborted)
|
|
@@ -187868,7 +189188,7 @@ async function runSubprocessAgent(agent, agentConfig, input) {
|
|
|
187868
189188
|
});
|
|
187869
189189
|
});
|
|
187870
189190
|
}
|
|
187871
|
-
async function runAcpClientWorkflow(child, input, signal) {
|
|
189191
|
+
async function runAcpClientWorkflow(child, input, signal, configOption) {
|
|
187872
189192
|
if (!child.stdin || !child.stdout) {
|
|
187873
189193
|
throw new Error("Agent process did not expose stdio streams.");
|
|
187874
189194
|
}
|
|
@@ -187916,15 +189236,36 @@ async function runAcpClientWorkflow(child, input, signal) {
|
|
|
187916
189236
|
kyosoReadOnly: true
|
|
187917
189237
|
}
|
|
187918
189238
|
}).withSession(async (session) => {
|
|
189239
|
+
const warnings = [];
|
|
189240
|
+
if (configOption) {
|
|
189241
|
+
await ctx.request(methods.agent.session.setConfigOption, { sessionId: session.sessionId, ...configOption }, { cancellationSignal: signal }).catch((error51) => {
|
|
189242
|
+
if (signal.aborted)
|
|
189243
|
+
return;
|
|
189244
|
+
const sanitizedValue = sanitizeTextForDisplay(configOption.value);
|
|
189245
|
+
const detail = sanitizeTextForDisplay(formatAgentErrorDetail(error51));
|
|
189246
|
+
const warning = `rejected effort config option (configId=${configOption.configId}, value=${sanitizedValue}); continuing without it: ${detail}`;
|
|
189247
|
+
warnings.push(warning);
|
|
189248
|
+
console.error(`kyoso: ${warning}`);
|
|
189249
|
+
});
|
|
189250
|
+
}
|
|
187919
189251
|
const promptResponse = session.prompt(input.prompt, {
|
|
187920
189252
|
cancellationSignal: signal
|
|
187921
189253
|
});
|
|
187922
189254
|
const text = await session.readText();
|
|
187923
189255
|
await promptResponse;
|
|
187924
|
-
return text;
|
|
189256
|
+
return { rawText: text, warnings };
|
|
187925
189257
|
});
|
|
187926
189258
|
});
|
|
187927
189259
|
}
|
|
189260
|
+
function resolveEffortConfigOption(agent, effort) {
|
|
189261
|
+
if (!effort)
|
|
189262
|
+
return;
|
|
189263
|
+
if (agent === "codex")
|
|
189264
|
+
return { configId: "reasoning_effort", value: effort };
|
|
189265
|
+
if (agent === "claude")
|
|
189266
|
+
return { configId: "effort", value: effort };
|
|
189267
|
+
return;
|
|
189268
|
+
}
|
|
187928
189269
|
async function readWorkspaceFile(workspaceDir, requestedPath, line, limit) {
|
|
187929
189270
|
const workspaceRoot = await realpath(workspaceDir);
|
|
187930
189271
|
const candidates = resolveReadablePaths(workspaceRoot, requestedPath);
|
|
@@ -187933,7 +189274,7 @@ async function readWorkspaceFile(workspaceDir, requestedPath, line, limit) {
|
|
|
187933
189274
|
const readablePath = await resolveReadableFile(workspaceRoot, absolute);
|
|
187934
189275
|
if (!readablePath)
|
|
187935
189276
|
continue;
|
|
187936
|
-
content = await
|
|
189277
|
+
content = await readFile4(readablePath, "utf8").catch(() => {
|
|
187937
189278
|
return;
|
|
187938
189279
|
});
|
|
187939
189280
|
if (content !== undefined)
|
|
@@ -188686,7 +190027,7 @@ function normalizeTitle(value) {
|
|
|
188686
190027
|
|
|
188687
190028
|
// src/audit/trace.ts
|
|
188688
190029
|
import { mkdir as mkdir2, appendFile } from "node:fs/promises";
|
|
188689
|
-
import { dirname as dirname3, isAbsolute as isAbsolute2, join as
|
|
190030
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3 } from "node:path";
|
|
188690
190031
|
|
|
188691
190032
|
// src/context/pathPolicy.ts
|
|
188692
190033
|
import { normalize, sep } from "node:path";
|
|
@@ -188780,7 +190121,7 @@ function createTraceWriter(options) {
|
|
|
188780
190121
|
}
|
|
188781
190122
|
const date5 = new Date().toISOString().slice(0, 10);
|
|
188782
190123
|
const directory = validateAuditDirectory(options.directory, warnings);
|
|
188783
|
-
const tracePath =
|
|
190124
|
+
const tracePath = join3(options.cwd, directory, date5, `${options.traceId}.jsonl`);
|
|
188784
190125
|
return {
|
|
188785
190126
|
tracePath,
|
|
188786
190127
|
warnings,
|
|
@@ -188961,6 +190302,10 @@ function renderMarkdownResult(tool, result, options = {}) {
|
|
|
188961
190302
|
lines.push(...result.testsToAdd.length > 0 ? result.testsToAdd.map((test) => `- ${test}`) : ["- None."]);
|
|
188962
190303
|
lines.push("", "## Residual Risks", "");
|
|
188963
190304
|
lines.push(...result.residualRisks.length > 0 ? result.residualRisks.map((risk) => `- ${risk}`) : ["- None."]);
|
|
190305
|
+
if (result.audit.warnings && result.audit.warnings.length > 0) {
|
|
190306
|
+
lines.push("", "## Warnings", "");
|
|
190307
|
+
lines.push(...result.audit.warnings.map((warning) => `- ${escapeMarkdownText(warning)}`));
|
|
190308
|
+
}
|
|
188964
190309
|
if (result.crossModelAnalysis) {
|
|
188965
190310
|
lines.push("", "## Cross-Model Analysis", "");
|
|
188966
190311
|
if (result.reviewMode === "single_agent") {
|
|
@@ -189025,6 +190370,9 @@ function formatVerification(finding) {
|
|
|
189025
190370
|
function formatList(items) {
|
|
189026
190371
|
return items.length > 0 ? items.map((item) => `- ${item}`) : ["- None."];
|
|
189027
190372
|
}
|
|
190373
|
+
function escapeMarkdownText(value) {
|
|
190374
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replace(/[\r\n]+/g, " ").replace(/([\\`*_{}\[\]()#+!|])/g, "\\$1");
|
|
190375
|
+
}
|
|
189028
190376
|
|
|
189029
190377
|
// src/judge/prompt.ts
|
|
189030
190378
|
var ANALYSIS_MAX_ITEMS = 5;
|
|
@@ -189074,7 +190422,7 @@ function parseJudgeOutput(text, fallbackSummaryText) {
|
|
|
189074
190422
|
const parsed = JSON.parse(json2);
|
|
189075
190423
|
const summaryText = typeof parsed.summaryText === "string" && parsed.summaryText.trim().length > 0 ? sanitizeText(parsed.summaryText) : fallbackSummaryText;
|
|
189076
190424
|
const disagreementComments = Array.isArray(parsed.disagreementComments) ? parsed.disagreementComments.flatMap((item) => {
|
|
189077
|
-
if (!
|
|
190425
|
+
if (!isRecord6(item) || typeof item.topic !== "string" || typeof item.judgeComment !== "string") {
|
|
189078
190426
|
return [];
|
|
189079
190427
|
}
|
|
189080
190428
|
return [
|
|
@@ -189090,7 +190438,7 @@ function parseJudgeOutput(text, fallbackSummaryText) {
|
|
|
189090
190438
|
return { summaryText, disagreementComments, analysis };
|
|
189091
190439
|
}
|
|
189092
190440
|
function parseAnalysis(value) {
|
|
189093
|
-
if (!
|
|
190441
|
+
if (!isRecord6(value))
|
|
189094
190442
|
return;
|
|
189095
190443
|
if (!Array.isArray(value.blindSpots) || !Array.isArray(value.contradictions) || !Array.isArray(value.partialCoverage)) {
|
|
189096
190444
|
return;
|
|
@@ -189098,7 +190446,7 @@ function parseAnalysis(value) {
|
|
|
189098
190446
|
return {
|
|
189099
190447
|
blindSpots: value.blindSpots.slice(0, ANALYSIS_MAX_ITEMS).flatMap((item) => typeof item === "string" ? [sanitizeAnalysisText(item)] : []),
|
|
189100
190448
|
contradictions: value.contradictions.slice(0, ANALYSIS_MAX_ITEMS).flatMap((item) => {
|
|
189101
|
-
if (!
|
|
190449
|
+
if (!isRecord6(item) || typeof item.topic !== "string" || typeof item.detail !== "string") {
|
|
189102
190450
|
return [];
|
|
189103
190451
|
}
|
|
189104
190452
|
return [
|
|
@@ -189109,7 +190457,7 @@ function parseAnalysis(value) {
|
|
|
189109
190457
|
];
|
|
189110
190458
|
}),
|
|
189111
190459
|
partialCoverage: value.partialCoverage.slice(0, ANALYSIS_MAX_ITEMS).flatMap((item) => {
|
|
189112
|
-
if (!
|
|
190460
|
+
if (!isRecord6(item) || typeof item.note !== "string")
|
|
189113
190461
|
return [];
|
|
189114
190462
|
const findingId = typeof item.findingId === "string" ? sanitizeAnalysisText(item.findingId) : undefined;
|
|
189115
190463
|
return [
|
|
@@ -189156,7 +190504,7 @@ function extractFirstJsonObject2(text) {
|
|
|
189156
190504
|
}
|
|
189157
190505
|
return;
|
|
189158
190506
|
}
|
|
189159
|
-
function
|
|
190507
|
+
function isRecord6(value) {
|
|
189160
190508
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
189161
190509
|
}
|
|
189162
190510
|
|
|
@@ -189492,12 +190840,12 @@ function decide(input) {
|
|
|
189492
190840
|
|
|
189493
190841
|
// src/workspace/createSnapshot.ts
|
|
189494
190842
|
import { chmod, mkdir as mkdir3, mkdtemp, writeFile as writeFile2 } from "node:fs/promises";
|
|
189495
|
-
import { dirname as dirname4, join as
|
|
190843
|
+
import { dirname as dirname4, join as join4 } from "node:path";
|
|
189496
190844
|
import { tmpdir } from "node:os";
|
|
189497
190845
|
async function createSnapshot(traceId, tool, request, options = {}) {
|
|
189498
|
-
const root = await mkdtemp(
|
|
189499
|
-
const repoDir =
|
|
189500
|
-
const contextDir =
|
|
190846
|
+
const root = await mkdtemp(join4(tmpdir(), `kyoso-${traceId}-`));
|
|
190847
|
+
const repoDir = join4(root, "repo");
|
|
190848
|
+
const contextDir = join4(root, "context");
|
|
189501
190849
|
await mkdir3(repoDir, { recursive: true });
|
|
189502
190850
|
await mkdir3(contextDir, { recursive: true });
|
|
189503
190851
|
let fileCount = 0;
|
|
@@ -189507,7 +190855,7 @@ async function createSnapshot(traceId, tool, request, options = {}) {
|
|
|
189507
190855
|
continue;
|
|
189508
190856
|
if (!isAllowedPath(relative2, options.allowPatterns ?? []))
|
|
189509
190857
|
continue;
|
|
189510
|
-
const dest =
|
|
190858
|
+
const dest = join4(repoDir, relative2);
|
|
189511
190859
|
await mkdir3(dirname4(dest), { recursive: true });
|
|
189512
190860
|
await writeFile2(dest, file2.content, "utf8");
|
|
189513
190861
|
await chmod(dest, 292).catch(() => {
|
|
@@ -189515,16 +190863,16 @@ async function createSnapshot(traceId, tool, request, options = {}) {
|
|
|
189515
190863
|
});
|
|
189516
190864
|
fileCount += 1;
|
|
189517
190865
|
}
|
|
189518
|
-
await writeFile2(
|
|
189519
|
-
await writeFile2(
|
|
189520
|
-
await writeFile2(
|
|
189521
|
-
await writeFile2(
|
|
190866
|
+
await writeFile2(join4(contextDir, "request.json"), JSON.stringify(stripContents(request), null, 2), "utf8");
|
|
190867
|
+
await writeFile2(join4(contextDir, "selected_files_manifest.json"), JSON.stringify(buildSelectedFilesManifest(request), null, 2), "utf8");
|
|
190868
|
+
await writeFile2(join4(contextDir, "instructions.codex.md"), buildAgentPrompt(tool, request, "codex", options.agentRoles?.codex ?? "implementation_reviewer"), "utf8");
|
|
190869
|
+
await writeFile2(join4(contextDir, "instructions.claude.md"), buildAgentPrompt(tool, request, "claude", options.agentRoles?.claude ?? "architecture_security_reviewer"), "utf8");
|
|
189522
190870
|
if (request.repoSummary)
|
|
189523
|
-
await writeFile2(
|
|
190871
|
+
await writeFile2(join4(contextDir, "repo_summary.md"), request.repoSummary, "utf8");
|
|
189524
190872
|
if (request.currentPlan)
|
|
189525
|
-
await writeFile2(
|
|
190873
|
+
await writeFile2(join4(contextDir, "current_plan.md"), request.currentPlan, "utf8");
|
|
189526
190874
|
if (request.diff?.unifiedDiff)
|
|
189527
|
-
await writeFile2(
|
|
190875
|
+
await writeFile2(join4(contextDir, "diff.patch"), request.diff.unifiedDiff, "utf8");
|
|
189528
190876
|
return { root, repoDir, contextDir, fileCount };
|
|
189529
190877
|
}
|
|
189530
190878
|
function stripContents(request) {
|
|
@@ -189614,7 +190962,7 @@ function parseVerificationVerdicts(rawText) {
|
|
|
189614
190962
|
if (!Array.isArray(parsed.verdicts))
|
|
189615
190963
|
return;
|
|
189616
190964
|
return parsed.verdicts.flatMap((item) => {
|
|
189617
|
-
if (!
|
|
190965
|
+
if (!isRecord7(item))
|
|
189618
190966
|
return [];
|
|
189619
190967
|
if (typeof item.findingId !== "string")
|
|
189620
190968
|
return [];
|
|
@@ -189692,7 +191040,7 @@ function verificationNote(reasoning) {
|
|
|
189692
191040
|
function isVerdict(value) {
|
|
189693
191041
|
return value === "confirmed" || value === "refuted" || value === "uncertain";
|
|
189694
191042
|
}
|
|
189695
|
-
function
|
|
191043
|
+
function isRecord7(value) {
|
|
189696
191044
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
189697
191045
|
}
|
|
189698
191046
|
|
|
@@ -189745,14 +191093,17 @@ async function runReview(tool, request, options = {}) {
|
|
|
189745
191093
|
config: options.config,
|
|
189746
191094
|
configHash: options.configHash,
|
|
189747
191095
|
configTrustStatus: "trusted",
|
|
191096
|
+
sources: [],
|
|
189748
191097
|
warnings: []
|
|
189749
191098
|
} : await loadConfig({
|
|
189750
191099
|
cwd,
|
|
189751
191100
|
configPath: options.configPath,
|
|
189752
191101
|
ignoreConfig: options.ignoreConfig,
|
|
189753
191102
|
trustConfig: options.trustConfig,
|
|
191103
|
+
allowUnknownConfig: options.allowUnknownConfig,
|
|
189754
191104
|
promptForTrust: options.promptForTrust,
|
|
189755
191105
|
trustStorePath: options.trustStorePath,
|
|
191106
|
+
env: options.env,
|
|
189756
191107
|
trustPrompt: options.trustPrompt
|
|
189757
191108
|
});
|
|
189758
191109
|
const trace = createTraceWriter({
|
|
@@ -189775,6 +191126,7 @@ async function runReview(tool, request, options = {}) {
|
|
|
189775
191126
|
traceId,
|
|
189776
191127
|
configHash: loaded.configHash,
|
|
189777
191128
|
configPath: loaded.configPath,
|
|
191129
|
+
configSources: loaded.sources,
|
|
189778
191130
|
configTrustStatus: loaded.configTrustStatus,
|
|
189779
191131
|
timestamp: new Date().toISOString()
|
|
189780
191132
|
});
|
|
@@ -189841,6 +191193,7 @@ async function runReview(tool, request, options = {}) {
|
|
|
189841
191193
|
manager,
|
|
189842
191194
|
trace
|
|
189843
191195
|
});
|
|
191196
|
+
warnings.push(...agentResults.flatMap((result2) => (result2.warnings ?? []).map((warning) => `Agent ${result2.agent} ${warning}`)));
|
|
189844
191197
|
const normalizedAgentResults = agentResults.map(normalizeAgentRunResult);
|
|
189845
191198
|
const agentsUsed = normalizedAgentResults.map((result2) => result2.agent);
|
|
189846
191199
|
const reviewMode = agentsUsed.length === 1 ? "single_agent" : "multi_agent";
|