@kyo-so/cli 0.8.0 → 0.9.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/dist/index.js CHANGED
@@ -169498,7 +169498,7 @@ function defineConfig(config) {
169498
169498
  return config;
169499
169499
  }
169500
169500
  // src/core/runReview.ts
169501
- import { resolve as resolve4 } from "node:path";
169501
+ import { resolve as resolve6 } from "node:path";
169502
169502
 
169503
169503
  // node_modules/zod/v4/classic/external.js
169504
169504
  var exports_external = {};
@@ -184261,6 +184261,7 @@ var REDACTION = "[KYOSO_REDACTED]";
184261
184261
  // src/core/constants.ts
184262
184262
  var DEFAULT_AGENT_TIMEOUT_MS = 120000;
184263
184263
  var RAW_OUTPUT_MAX_CHARS = 16384;
184264
+ var TRACE_DIR = ".kyoso/traces";
184264
184265
  var KYOSO_CHILD_AGENT = "KYOSO_CHILD_AGENT";
184265
184266
 
184266
184267
  // src/security/sanitizeText.ts
@@ -185721,6 +185722,48 @@ function requiredDefaultOnError(schema, fallback) {
185721
185722
  return exports_external.NEVER;
185722
185723
  });
185723
185724
  }
185725
+ function stringTag(value, key) {
185726
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
185727
+ return;
185728
+ }
185729
+ const tag = value[key];
185730
+ return typeof tag === "string" ? tag : undefined;
185731
+ }
185732
+ function excludeKnownTags(schema, key, knownTags) {
185733
+ return schema.superRefine((value, context) => {
185734
+ const tag = stringTag(value, key);
185735
+ if (tag !== undefined && knownTags.includes(tag)) {
185736
+ context.addIssue({
185737
+ code: "custom",
185738
+ path: [key],
185739
+ message: `${key} ${JSON.stringify(tag)} is reserved by a known variant, ` + `but the value does not match that variant's schema`
185740
+ });
185741
+ }
185742
+ });
185743
+ }
185744
+ function preserveCustomPayload(schema, key, knownTags) {
185745
+ return exports_external.unknown().transform((value, context) => {
185746
+ const result = schema.safeParse(value);
185747
+ if (!result.success) {
185748
+ for (const issue2 of result.error.issues) {
185749
+ context.addIssue({ ...issue2, input: value });
185750
+ }
185751
+ return exports_external.NEVER;
185752
+ }
185753
+ const output = result.data;
185754
+ const tag = stringTag(value, key);
185755
+ if (tag !== undefined && !knownTags.includes(tag)) {
185756
+ const raw = value;
185757
+ for (const [property, rawValue] of Object.entries(raw)) {
185758
+ if (property === "__proto__")
185759
+ continue;
185760
+ if (!Object.hasOwn(output, property))
185761
+ output[property] = rawValue;
185762
+ }
185763
+ }
185764
+ return output;
185765
+ });
185766
+ }
185724
185767
  function vecSkipError(itemSchema) {
185725
185768
  return exports_external.array(itemSchema.catch(skippedItem)).transform((items) => items.filter((item) => item !== skippedItem));
185726
185769
  }
@@ -186144,15 +186187,15 @@ var zTitledMultiSelectItems = object({
186144
186187
  return;
186145
186188
  })
186146
186189
  });
186147
- var zMultiSelectItems = union([
186190
+ var zMultiSelectItems = preserveCustomPayload(union([
186148
186191
  zStringMultiSelectItems.and(object({
186149
186192
  type: literal("string")
186150
186193
  })),
186151
- object({
186194
+ excludeKnownTags(object({
186152
186195
  type: string2()
186153
- }),
186196
+ }), "type", ["string"]),
186154
186197
  zTitledMultiSelectItems
186155
- ]);
186198
+ ]), "type", ["string"]);
186156
186199
  var zMultiSelectPropertySchema = object({
186157
186200
  title: defaultOnError(string2().nullish(), () => {
186158
186201
  return;
@@ -186170,7 +186213,7 @@ var zMultiSelectPropertySchema = object({
186170
186213
  return;
186171
186214
  })
186172
186215
  });
186173
- var zElicitationPropertySchema = union([
186216
+ var zElicitationPropertySchema = preserveCustomPayload(union([
186174
186217
  zStringPropertySchema.and(object({
186175
186218
  type: literal("string")
186176
186219
  })),
@@ -186186,10 +186229,10 @@ var zElicitationPropertySchema = union([
186186
186229
  zMultiSelectPropertySchema.and(object({
186187
186230
  type: literal("array")
186188
186231
  })),
186189
- object({
186232
+ excludeKnownTags(object({
186190
186233
  type: string2()
186191
- })
186192
- ]);
186234
+ }), "type", ["array", "boolean", "integer", "number", "string"])
186235
+ ]), "type", ["array", "boolean", "integer", "number", "string"]);
186193
186236
  var zElicitationSchema = object({
186194
186237
  type: defaultOnError(zElicitationSchemaType.optional().default("object"), () => "object"),
186195
186238
  title: defaultOnError(string2().nullish(), () => {
@@ -186212,22 +186255,22 @@ var zElicitationUrlMode = intersection(union([zElicitationSessionScope, zElicita
186212
186255
  elicitationId: zElicitationId,
186213
186256
  url: url()
186214
186257
  }));
186215
- var zCreateElicitationRequest = intersection(union([
186258
+ var zCreateElicitationRequest = preserveCustomPayload(intersection(union([
186216
186259
  zElicitationFormMode.and(object({
186217
186260
  mode: literal("form")
186218
186261
  })),
186219
186262
  zElicitationUrlMode.and(object({
186220
186263
  mode: literal("url")
186221
186264
  })),
186222
- intersection(union([zElicitationSessionScope, zElicitationRequestScope]), object({
186265
+ excludeKnownTags(intersection(union([zElicitationSessionScope, zElicitationRequestScope]), object({
186223
186266
  mode: string2()
186224
- }))
186267
+ })), "mode", ["form", "url"])
186225
186268
  ]), object({
186226
186269
  message: string2(),
186227
186270
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
186228
186271
  return;
186229
186272
  })
186230
- }));
186273
+ })), "mode", ["form", "url"]);
186231
186274
  var zMcpServerAcpId = string2();
186232
186275
  var zConnectMcpRequest = object({
186233
186276
  serverId: zMcpServerAcpId,
@@ -187827,7 +187870,7 @@ var zElicitationContentValue = union([
187827
187870
  var zElicitationAcceptAction = object({
187828
187871
  content: record(string2(), zElicitationContentValue).nullish()
187829
187872
  });
187830
- var zCreateElicitationResponse = intersection(union([
187873
+ var zCreateElicitationResponse = preserveCustomPayload(intersection(union([
187831
187874
  zElicitationAcceptAction.and(object({
187832
187875
  action: literal("accept")
187833
187876
  })),
@@ -187837,14 +187880,14 @@ var zCreateElicitationResponse = intersection(union([
187837
187880
  object({
187838
187881
  action: literal("cancel")
187839
187882
  }),
187840
- object({
187883
+ excludeKnownTags(object({
187841
187884
  action: string2()
187842
- })
187885
+ }), "action", ["accept", "cancel", "decline"])
187843
187886
  ]), object({
187844
187887
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
187845
187888
  return;
187846
187889
  })
187847
- }));
187890
+ })), "action", ["accept", "cancel", "decline"]);
187848
187891
  var zConnectMcpResponse = object({
187849
187892
  connectionId: zMcpConnectionId,
187850
187893
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
@@ -187980,6 +188023,24 @@ var zCancelRequestNotification = object({
187980
188023
  return;
187981
188024
  })
187982
188025
  });
188026
+
188027
+ // node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.js
188028
+ var zGuardCreateElicitationRequestForm = zElicitationFormMode.and(object({ mode: literal("form") })).and(object({ message: string2() }));
188029
+ var zGuardCreateElicitationRequestUrl = zElicitationUrlMode.and(object({ mode: literal("url") })).and(object({ message: string2() }));
188030
+ var zGuardCreateElicitationRequestCustom = union([zElicitationSessionScope, zElicitationRequestScope]).and(object({ message: string2() }));
188031
+ var zGuardElicitationPropertySchemaString = zStringPropertySchema.and(object({ type: literal("string") }));
188032
+ var zGuardElicitationPropertySchemaNumber = zNumberPropertySchema.and(object({ type: literal("number") }));
188033
+ var zGuardElicitationPropertySchemaInteger = zIntegerPropertySchema.and(object({ type: literal("integer") }));
188034
+ var zGuardElicitationPropertySchemaBoolean = zBooleanPropertySchema.and(object({ type: literal("boolean") }));
188035
+ var zGuardElicitationPropertySchemaArray = zMultiSelectPropertySchema.and(object({ type: literal("array") }));
188036
+ var zGuardMultiSelectItemsString = zStringMultiSelectItems.and(object({ type: literal("string") }));
188037
+ var zGuardCreateElicitationResponseAccept = zElicitationAcceptAction.and(object({ action: literal("accept") }));
188038
+ var zGuardCreateElicitationResponseDecline = object({
188039
+ action: literal("decline")
188040
+ });
188041
+ var zGuardCreateElicitationResponseCancel = object({
188042
+ action: literal("cancel")
188043
+ });
187983
188044
  // node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js
187984
188045
  var CANCEL_REQUEST_METHOD = "$/cancel_request";
187985
188046
  function isRecord5(value) {
@@ -190721,9 +190782,10 @@ function normalizeTitle(value) {
190721
190782
  return value.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
190722
190783
  }
190723
190784
 
190724
- // src/audit/trace.ts
190725
- import { mkdir as mkdir2, appendFile } from "node:fs/promises";
190726
- import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3 } from "node:path";
190785
+ // src/audit/stateRoot.ts
190786
+ import { createHash as createHash2 } from "node:crypto";
190787
+ import { lstat, mkdir as mkdir2, realpath as realpath2 } from "node:fs/promises";
190788
+ import { basename, dirname as dirname3, isAbsolute as isAbsolute2, join as join3, resolve as resolve5 } from "node:path";
190727
190789
 
190728
190790
  // src/context/pathPolicy.ts
190729
190791
  import { normalize, sep } from "node:path";
@@ -190785,6 +190847,325 @@ function matchesPathPattern(path, patterns, mode) {
190785
190847
  });
190786
190848
  }
190787
190849
 
190850
+ // src/utils/pathContainment.ts
190851
+ import { resolve as resolve4, sep as sep2 } from "node:path";
190852
+ function isPathWithin(candidate, root) {
190853
+ const resolvedCandidate = resolve4(candidate);
190854
+ const resolvedRoot = resolve4(root);
190855
+ const boundary = resolvedRoot.endsWith(sep2) ? resolvedRoot : `${resolvedRoot}${sep2}`;
190856
+ return resolvedCandidate === resolvedRoot || resolvedCandidate.startsWith(boundary);
190857
+ }
190858
+
190859
+ // src/audit/stateRoot.ts
190860
+ var PRIVATE_DIRECTORY_MODE = 448;
190861
+ var UNSAFE_DIRECTORY_MODE = 18;
190862
+ var STICKY_DIRECTORY_MODE = 512;
190863
+ var AUDIT_WARNING_DIRECTORY_IGNORED = "AUDIT_DIRECTORY_IGNORED: Audit directory is invalid; using the default logical directory.";
190864
+ var AUDIT_WARNING_UNSUPPORTED_PLATFORM = "AUDIT_DISABLED_UNSUPPORTED_PLATFORM: Audit trace writing is unavailable on this platform.";
190865
+ var AUDIT_WARNING_UNSUPPORTED_CAPABILITY = "AUDIT_DISABLED_UNSUPPORTED_CAPABILITY: Audit trace writing requires unavailable filesystem capabilities.";
190866
+ var AUDIT_WARNING_UNSAFE_STATE_ROOT = "AUDIT_DISABLED_UNSAFE_STATE_ROOT: Audit state root could not be verified.";
190867
+ async function resolveAuditStateRoot(options) {
190868
+ const warnings = [];
190869
+ const logicalDirectory = validateAuditDirectory(options.directory, warnings);
190870
+ const platform = options.platform ?? process.platform;
190871
+ if (platform === "win32") {
190872
+ return { warnings: [...warnings, AUDIT_WARNING_UNSUPPORTED_PLATFORM] };
190873
+ }
190874
+ const uid = getCurrentUid(options.getuid);
190875
+ if (uid === undefined) {
190876
+ return { warnings: [...warnings, AUDIT_WARNING_UNSUPPORTED_CAPABILITY] };
190877
+ }
190878
+ try {
190879
+ const workspaceRoot = await realpath2(resolve5(options.cwd));
190880
+ const candidate = resolveStateBaseCandidate(options.env ?? process.env);
190881
+ if (!candidate)
190882
+ throw new Error("missing trusted state base");
190883
+ const stateBase = await ensureTrustedStateBase({
190884
+ candidate,
190885
+ workspaceRoot,
190886
+ uid
190887
+ });
190888
+ const kyosoRoot = await ensureTrustedDirectory({
190889
+ root: stateBase,
190890
+ segments: ["kyoso"],
190891
+ uid,
190892
+ workspaceRoot
190893
+ });
190894
+ return {
190895
+ stateBase,
190896
+ kyosoRoot,
190897
+ workspaceRoot,
190898
+ workspaceHash: createHash2("sha256").update(workspaceRoot).digest("hex"),
190899
+ logicalDirectory,
190900
+ uid,
190901
+ warnings
190902
+ };
190903
+ } catch {
190904
+ return { warnings: [...warnings, AUDIT_WARNING_UNSAFE_STATE_ROOT] };
190905
+ }
190906
+ }
190907
+ async function ensureTrustedDirectory(options) {
190908
+ const realRoot = await realpath2(options.root);
190909
+ assertSafeDirectory(realRoot, options.uid, await lstat(realRoot));
190910
+ if (options.workspaceRoot && isPathWithin(realRoot, options.workspaceRoot)) {
190911
+ throw new Error("trusted directory resolves inside workspace");
190912
+ }
190913
+ await assertTrustedAncestorChain(realRoot, options.uid);
190914
+ let current = realRoot;
190915
+ for (const segment of options.segments) {
190916
+ if (!isSafePathSegment(segment))
190917
+ throw new Error("unsafe path segment");
190918
+ const next = join3(current, segment);
190919
+ let entry = await optionalLstat(next);
190920
+ if (!entry) {
190921
+ await createDirectory(next);
190922
+ entry = await lstat(next);
190923
+ }
190924
+ assertSafeDirectory(next, options.uid, entry);
190925
+ const realNext = await realpath2(next);
190926
+ if (!isPathWithin(realNext, realRoot)) {
190927
+ throw new Error("managed directory escaped trusted root");
190928
+ }
190929
+ if (options.workspaceRoot && isPathWithin(realNext, options.workspaceRoot)) {
190930
+ throw new Error("managed directory resolves inside workspace");
190931
+ }
190932
+ current = realNext;
190933
+ }
190934
+ return current;
190935
+ }
190936
+ function isResolvedAuditStateRoot(resolution) {
190937
+ return "kyosoRoot" in resolution;
190938
+ }
190939
+ function validateAuditDirectory(directory, warnings) {
190940
+ try {
190941
+ if (directory.trim().length === 0 || isAbsolute2(directory) || directory.split(/[\\/]+/).includes("..")) {
190942
+ throw new Error("unsafe logical directory");
190943
+ }
190944
+ const normalized = normalizeRelativePath(directory);
190945
+ if (normalized === "." || normalized.split("/").includes("..")) {
190946
+ throw new Error("unsafe logical directory");
190947
+ }
190948
+ return normalized;
190949
+ } catch {
190950
+ warnings.push(AUDIT_WARNING_DIRECTORY_IGNORED);
190951
+ return TRACE_DIR;
190952
+ }
190953
+ }
190954
+ function resolveStateBaseCandidate(env) {
190955
+ const xdgStateHome = env.XDG_STATE_HOME?.trim();
190956
+ if (xdgStateHome && isAbsolute2(xdgStateHome)) {
190957
+ return resolve5(xdgStateHome);
190958
+ }
190959
+ const home = env.HOME?.trim();
190960
+ if (!home || !isAbsolute2(home))
190961
+ return;
190962
+ return join3(resolve5(home), ".local", "state");
190963
+ }
190964
+ async function ensureTrustedStateBase(options) {
190965
+ if (isPathWithin(options.candidate, options.workspaceRoot)) {
190966
+ throw new Error("state base is inside workspace");
190967
+ }
190968
+ const existing = await findExistingAncestor(options.candidate);
190969
+ assertSafeDirectory(existing.path, options.uid, await lstat(existing.path), {
190970
+ allowFilesystemRoot: true
190971
+ });
190972
+ const realExisting = await realpath2(existing.path);
190973
+ if (isPathWithin(realExisting, options.workspaceRoot)) {
190974
+ throw new Error("state base resolves inside workspace");
190975
+ }
190976
+ await assertTrustedAncestorChain(realExisting, options.uid);
190977
+ let current = realExisting;
190978
+ for (const segment of existing.missingSegments) {
190979
+ current = join3(current, segment);
190980
+ await createDirectory(current);
190981
+ const entry = await lstat(current);
190982
+ assertSafeDirectory(current, options.uid, entry);
190983
+ const realCurrent = await realpath2(current);
190984
+ if (!isPathWithin(realCurrent, realExisting)) {
190985
+ throw new Error("state base changed while being created");
190986
+ }
190987
+ if (isPathWithin(realCurrent, options.workspaceRoot)) {
190988
+ throw new Error("state base resolves inside workspace");
190989
+ }
190990
+ current = realCurrent;
190991
+ }
190992
+ const stateBase = await realpath2(current);
190993
+ assertSafeDirectory(stateBase, options.uid, await lstat(stateBase));
190994
+ if (isPathWithin(stateBase, options.workspaceRoot)) {
190995
+ throw new Error("state base resolves inside workspace");
190996
+ }
190997
+ await assertTrustedAncestorChain(stateBase, options.uid);
190998
+ return stateBase;
190999
+ }
191000
+ async function findExistingAncestor(candidate) {
191001
+ let current = resolve5(candidate);
191002
+ const missingSegments = [];
191003
+ while (true) {
191004
+ const entry = await optionalLstat(current);
191005
+ if (entry) {
191006
+ if (entry.isSymbolicLink() || !entry.isDirectory()) {
191007
+ throw new Error("state base ancestor is unsafe");
191008
+ }
191009
+ return { path: current, missingSegments };
191010
+ }
191011
+ const parent = dirname3(current);
191012
+ if (parent === current)
191013
+ throw new Error("state base has no existing ancestor");
191014
+ missingSegments.unshift(basename(current));
191015
+ current = parent;
191016
+ }
191017
+ }
191018
+ function assertSafeDirectory(path, uid, entry, options = {}) {
191019
+ const stat = entry;
191020
+ if (!stat || stat.isSymbolicLink() || !stat.isDirectory()) {
191021
+ throw new Error("state directory is unsafe");
191022
+ }
191023
+ if (numericStatValue(stat.uid) !== uid && !(options.allowFilesystemRoot && isFilesystemRoot(path))) {
191024
+ throw new Error("state directory owner is unsafe");
191025
+ }
191026
+ const mode = numericStatValue(stat.mode);
191027
+ if ((mode & UNSAFE_DIRECTORY_MODE) !== 0) {
191028
+ throw new Error("state directory mode is unsafe");
191029
+ }
191030
+ }
191031
+ function numericStatValue(value) {
191032
+ return typeof value === "number" ? value : Number(value);
191033
+ }
191034
+ function getCurrentUid(getuid) {
191035
+ const resolveUid = getuid ?? (typeof process.getuid === "function" ? process.getuid.bind(process) : undefined);
191036
+ try {
191037
+ const uid = resolveUid?.();
191038
+ return typeof uid === "number" && Number.isInteger(uid) && uid >= 0 ? uid : undefined;
191039
+ } catch {
191040
+ return;
191041
+ }
191042
+ }
191043
+ function isFilesystemRoot(path) {
191044
+ return dirname3(path) === path;
191045
+ }
191046
+ async function assertTrustedAncestorChain(path, uid) {
191047
+ let child = path;
191048
+ while (!isFilesystemRoot(child)) {
191049
+ const parent = dirname3(child);
191050
+ const [parentStat, childStat] = await Promise.all([
191051
+ lstat(parent),
191052
+ lstat(child)
191053
+ ]);
191054
+ if (parentStat.isSymbolicLink() || !parentStat.isDirectory()) {
191055
+ throw new Error("state directory ancestor is unsafe");
191056
+ }
191057
+ const parentMode = numericStatValue(parentStat.mode);
191058
+ const parentUid = numericStatValue(parentStat.uid);
191059
+ const childUid = numericStatValue(childStat.uid);
191060
+ const parentWritableByOthers = (parentMode & UNSAFE_DIRECTORY_MODE) !== 0;
191061
+ const stickyChildEntry = (parentMode & STICKY_DIRECTORY_MODE) !== 0 && childUid === uid;
191062
+ if (parentUid !== uid && parentUid !== 0 || parentWritableByOthers && !stickyChildEntry) {
191063
+ throw new Error("state directory ancestor permissions are unsafe");
191064
+ }
191065
+ child = parent;
191066
+ }
191067
+ }
191068
+ function isSafePathSegment(segment) {
191069
+ return segment.length > 0 && segment !== "." && segment !== ".." && !segment.includes("/") && !segment.includes("\\");
191070
+ }
191071
+ async function optionalLstat(path) {
191072
+ try {
191073
+ return await lstat(path);
191074
+ } catch (error51) {
191075
+ if (isMissingPathError3(error51))
191076
+ return;
191077
+ throw error51;
191078
+ }
191079
+ }
191080
+ async function createDirectory(path) {
191081
+ try {
191082
+ await mkdir2(path, { mode: PRIVATE_DIRECTORY_MODE });
191083
+ } catch (error51) {
191084
+ if (!isAlreadyExistsError(error51))
191085
+ throw error51;
191086
+ }
191087
+ }
191088
+ function isMissingPathError3(error51) {
191089
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT";
191090
+ }
191091
+ function isAlreadyExistsError(error51) {
191092
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "EEXIST";
191093
+ }
191094
+
191095
+ // src/audit/safeTraceFile.ts
191096
+ import { constants } from "node:fs";
191097
+ import { lstat as lstat2, open, realpath as realpath3, stat } from "node:fs/promises";
191098
+ import { join as join4 } from "node:path";
191099
+ var AUDIT_WARNING_UNSUPPORTED_OPEN_CAPABILITY = "AUDIT_DISABLED_UNSUPPORTED_CAPABILITY: Audit trace writing requires unavailable filesystem capabilities.";
191100
+ async function openVerifiedTraceFile(options) {
191101
+ const flags = secureOpenFlags(options.openConstants);
191102
+ if (flags === undefined)
191103
+ throw new Error("secure open capability unavailable");
191104
+ if (!isSafeTraceId(options.traceId))
191105
+ throw new Error("unsafe trace id");
191106
+ const traceDirectory = await ensureTrustedDirectory({
191107
+ root: options.kyosoRoot,
191108
+ segments: [
191109
+ "workspaces",
191110
+ options.workspaceHash,
191111
+ ...options.logicalDirectory.split("/"),
191112
+ options.date
191113
+ ],
191114
+ uid: options.uid,
191115
+ workspaceRoot: options.workspaceRoot
191116
+ });
191117
+ const tracePath = join4(traceDirectory, `${options.traceId}.jsonl`);
191118
+ if (await optionalLstat2(tracePath)) {
191119
+ throw new Error("trace path already exists");
191120
+ }
191121
+ await options.beforeOpen?.(tracePath);
191122
+ const handle = await open(tracePath, flags, 384);
191123
+ try {
191124
+ const [handleStat, pathStat, realTracePath] = await Promise.all([
191125
+ handle.stat({ bigint: true }),
191126
+ stat(tracePath, { bigint: true }),
191127
+ realpath3(tracePath)
191128
+ ]);
191129
+ if (!handleStat.isFile() || !pathStat.isFile() || handleStat.dev !== pathStat.dev || handleStat.ino !== pathStat.ino || !isPathWithin(realTracePath, options.kyosoRoot)) {
191130
+ throw new Error("trace file identity could not be verified");
191131
+ }
191132
+ return { handle, tracePath };
191133
+ } catch (error51) {
191134
+ try {
191135
+ await handle.close();
191136
+ } catch {}
191137
+ throw error51;
191138
+ }
191139
+ }
191140
+ function secureOpenFlags(provided) {
191141
+ const openConstants = provided ?? constants;
191142
+ const required2 = [
191143
+ openConstants.O_CREAT,
191144
+ openConstants.O_EXCL,
191145
+ openConstants.O_APPEND,
191146
+ openConstants.O_WRONLY,
191147
+ openConstants.O_NOFOLLOW,
191148
+ openConstants.O_NONBLOCK
191149
+ ];
191150
+ if (required2.some((flag) => typeof flag !== "number" || flag <= 0)) {
191151
+ return;
191152
+ }
191153
+ return required2.reduce((combined, flag) => combined | flag, 0);
191154
+ }
191155
+ function isSafeTraceId(traceId) {
191156
+ return traceId.length > 0 && traceId !== "." && traceId !== ".." && !traceId.includes("/") && !traceId.includes("\\");
191157
+ }
191158
+ async function optionalLstat2(path) {
191159
+ try {
191160
+ return await lstat2(path);
191161
+ } catch (error51) {
191162
+ if (typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT") {
191163
+ return;
191164
+ }
191165
+ throw error51;
191166
+ }
191167
+ }
191168
+
190788
191169
  // src/audit/sanitize.ts
190789
191170
  function sanitizeForAudit(value, options = {}) {
190790
191171
  if (typeof value === "string")
@@ -190805,46 +191186,149 @@ function sanitizeForAudit(value, options = {}) {
190805
191186
  }
190806
191187
 
190807
191188
  // src/audit/trace.ts
191189
+ var AUDIT_WARNING_WRITE_FAILED = "AUDIT_WRITE_FAILED: Audit trace writing failed; no further audit events will be written.";
191190
+ var AUDIT_WARNING_FINALIZE_FAILED = "AUDIT_FINALIZE_FAILED: Audit trace close failed.";
191191
+ var AUDIT_WARNING_WRITE_AFTER_FINALIZE = "AUDIT_WRITE_AFTER_FINALIZE: Audit trace is already finalized.";
190808
191192
  function createTraceWriter(options) {
190809
191193
  const warnings = [];
190810
- if (!options.enabled) {
190811
- return {
190812
- warnings,
190813
- async write() {
190814
- return;
190815
- }
190816
- };
190817
- }
191194
+ const warningSet = new Set;
190818
191195
  const date5 = new Date().toISOString().slice(0, 10);
190819
- const directory = validateAuditDirectory(options.directory, warnings);
190820
- const tracePath = join3(options.cwd, directory, date5, `${options.traceId}.jsonl`);
191196
+ let tracePath;
191197
+ let handle;
191198
+ let disabled = !options.enabled;
191199
+ let finalizing = false;
191200
+ let finalized = false;
191201
+ let queue = Promise.resolve();
191202
+ let finalizePromise;
191203
+ const addWarning = (warning) => {
191204
+ if (warningSet.has(warning))
191205
+ return;
191206
+ warningSet.add(warning);
191207
+ warnings.push(warning);
191208
+ };
191209
+ const closeHandle = async () => {
191210
+ const current = handle;
191211
+ handle = undefined;
191212
+ if (!current)
191213
+ return;
191214
+ try {
191215
+ await (options.closeHandle ?? defaultCloseHandle)(current);
191216
+ } catch {
191217
+ addWarning(AUDIT_WARNING_FINALIZE_FAILED);
191218
+ }
191219
+ };
191220
+ const disableAfterWriteFailure = async () => {
191221
+ disabled = true;
191222
+ addWarning(AUDIT_WARNING_WRITE_FAILED);
191223
+ await closeHandle();
191224
+ };
191225
+ const openIfNeeded = async () => {
191226
+ if (handle || disabled)
191227
+ return;
191228
+ if (secureOpenFlags(options.openConstants) === undefined) {
191229
+ disabled = true;
191230
+ addWarning(AUDIT_WARNING_UNSUPPORTED_OPEN_CAPABILITY);
191231
+ return;
191232
+ }
191233
+ const stateRoot = await resolveAuditStateRoot({
191234
+ cwd: options.cwd,
191235
+ directory: options.directory,
191236
+ env: options.env,
191237
+ platform: options.platform,
191238
+ getuid: options.getuid
191239
+ });
191240
+ for (const warning of stateRoot.warnings)
191241
+ addWarning(warning);
191242
+ if (!isResolvedAuditStateRoot(stateRoot)) {
191243
+ disabled = true;
191244
+ return;
191245
+ }
191246
+ try {
191247
+ const opened = await openVerifiedTraceFile({
191248
+ kyosoRoot: stateRoot.kyosoRoot,
191249
+ workspaceHash: stateRoot.workspaceHash,
191250
+ logicalDirectory: stateRoot.logicalDirectory,
191251
+ date: date5,
191252
+ traceId: options.traceId,
191253
+ uid: stateRoot.uid,
191254
+ workspaceRoot: stateRoot.workspaceRoot,
191255
+ openConstants: options.openConstants,
191256
+ beforeOpen: options.beforeOpen
191257
+ });
191258
+ handle = opened.handle;
191259
+ tracePath = opened.tracePath;
191260
+ } catch {
191261
+ disabled = true;
191262
+ addWarning(AUDIT_WARNING_WRITE_FAILED);
191263
+ }
191264
+ };
191265
+ const writeOne = async (event) => {
191266
+ if (disabled)
191267
+ return;
191268
+ try {
191269
+ await openIfNeeded();
191270
+ if (disabled || !handle)
191271
+ return;
191272
+ const line = Buffer.from(`${JSON.stringify(sanitizeForAudit(event, {
191273
+ includeRawAgentOutput: options.includeRawAgentOutput
191274
+ }))}
191275
+ `, "utf8");
191276
+ await writeFully(handle, line, options.writeChunk);
191277
+ } catch {
191278
+ await disableAfterWriteFailure();
191279
+ }
191280
+ };
190821
191281
  return {
190822
- tracePath,
191282
+ get tracePath() {
191283
+ return tracePath;
191284
+ },
190823
191285
  warnings,
190824
- async write(event) {
190825
- try {
190826
- await mkdir2(dirname3(tracePath), { recursive: true });
190827
- await appendFile(tracePath, `${JSON.stringify(sanitizeForAudit(event, {
190828
- includeRawAgentOutput: options.includeRawAgentOutput
190829
- }))}
190830
- `, "utf8");
190831
- } catch (error51) {
190832
- warnings.push(`Audit write failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
190833
- }
191286
+ write(event) {
191287
+ if (finalizing || finalized) {
191288
+ addWarning(AUDIT_WARNING_WRITE_AFTER_FINALIZE);
191289
+ return Promise.resolve();
191290
+ }
191291
+ const task = queue.then(() => writeOne(event));
191292
+ queue = task.catch(async () => {
191293
+ await disableAfterWriteFailure();
191294
+ });
191295
+ return task.catch(() => {
191296
+ return;
191297
+ });
191298
+ },
191299
+ finalize() {
191300
+ if (finalizePromise)
191301
+ return finalizePromise;
191302
+ finalizing = true;
191303
+ finalizePromise = queue.then(async () => {
191304
+ await closeHandle();
191305
+ finalized = true;
191306
+ }).catch(() => {
191307
+ disabled = true;
191308
+ addWarning(AUDIT_WARNING_FINALIZE_FAILED);
191309
+ finalized = true;
191310
+ });
191311
+ return finalizePromise;
190834
191312
  }
190835
191313
  };
190836
191314
  }
190837
- function validateAuditDirectory(directory, warnings) {
190838
- try {
190839
- if (isAbsolute2(directory) || directory.split(/[\\/]+/).includes("..")) {
190840
- throw new Error("unsafe path");
191315
+ async function writeFully(handle, buffer, writeChunk) {
191316
+ let offset = 0;
191317
+ while (offset < buffer.byteLength) {
191318
+ const bytesWritten = await (writeChunk ?? defaultWriteChunk)(handle, buffer, offset);
191319
+ if (!Number.isInteger(bytesWritten) || bytesWritten <= 0) {
191320
+ throw new Error("partial audit write could not advance");
190841
191321
  }
190842
- return normalizeRelativePath(directory);
190843
- } catch {
190844
- warnings.push(`Unsafe audit directory ignored: ${directory}`);
190845
- return ".kyoso/traces";
191322
+ offset += bytesWritten;
190846
191323
  }
190847
191324
  }
191325
+ async function defaultWriteChunk(handle, buffer, offset) {
191326
+ const { bytesWritten } = await handle.write(buffer, offset, buffer.byteLength - offset, null);
191327
+ return bytesWritten;
191328
+ }
191329
+ async function defaultCloseHandle(handle) {
191330
+ await handle.close();
191331
+ }
190848
191332
 
190849
191333
  // src/context/truncate.ts
190850
191334
  function truncateUtf8(input, maxBytes) {
@@ -191536,12 +192020,12 @@ function decide(input) {
191536
192020
 
191537
192021
  // src/workspace/createSnapshot.ts
191538
192022
  import { chmod, mkdir as mkdir3, mkdtemp, writeFile as writeFile2 } from "node:fs/promises";
191539
- import { dirname as dirname4, join as join4 } from "node:path";
192023
+ import { dirname as dirname4, join as join5 } from "node:path";
191540
192024
  import { tmpdir } from "node:os";
191541
192025
  async function createSnapshot(traceId, tool, request, options = {}) {
191542
- const root = await mkdtemp(join4(tmpdir(), `kyoso-${traceId}-`));
191543
- const repoDir = join4(root, "repo");
191544
- const contextDir = join4(root, "context");
192026
+ const root = await mkdtemp(join5(tmpdir(), `kyoso-${traceId}-`));
192027
+ const repoDir = join5(root, "repo");
192028
+ const contextDir = join5(root, "context");
191545
192029
  await mkdir3(repoDir, { recursive: true });
191546
192030
  await mkdir3(contextDir, { recursive: true });
191547
192031
  let fileCount = 0;
@@ -191551,7 +192035,7 @@ async function createSnapshot(traceId, tool, request, options = {}) {
191551
192035
  continue;
191552
192036
  if (!isAllowedPath(relative2, options.allowPatterns ?? []))
191553
192037
  continue;
191554
- const dest = join4(repoDir, relative2);
192038
+ const dest = join5(repoDir, relative2);
191555
192039
  await mkdir3(dirname4(dest), { recursive: true });
191556
192040
  await writeFile2(dest, file2.content, "utf8");
191557
192041
  await chmod(dest, 292).catch(() => {
@@ -191559,16 +192043,16 @@ async function createSnapshot(traceId, tool, request, options = {}) {
191559
192043
  });
191560
192044
  fileCount += 1;
191561
192045
  }
191562
- await writeFile2(join4(contextDir, "request.json"), JSON.stringify(stripContents(request), null, 2), "utf8");
191563
- await writeFile2(join4(contextDir, "selected_files_manifest.json"), JSON.stringify(buildSelectedFilesManifest(request), null, 2), "utf8");
191564
- await writeFile2(join4(contextDir, "instructions.codex.md"), buildAgentPrompt(tool, request, "codex", options.agentRoles?.codex ?? "implementation_reviewer"), "utf8");
191565
- await writeFile2(join4(contextDir, "instructions.claude.md"), buildAgentPrompt(tool, request, "claude", options.agentRoles?.claude ?? "architecture_security_reviewer"), "utf8");
192046
+ await writeFile2(join5(contextDir, "request.json"), JSON.stringify(stripContents(request), null, 2), "utf8");
192047
+ await writeFile2(join5(contextDir, "selected_files_manifest.json"), JSON.stringify(buildSelectedFilesManifest(request), null, 2), "utf8");
192048
+ await writeFile2(join5(contextDir, "instructions.codex.md"), buildAgentPrompt(tool, request, "codex", options.agentRoles?.codex ?? "implementation_reviewer"), "utf8");
192049
+ await writeFile2(join5(contextDir, "instructions.claude.md"), buildAgentPrompt(tool, request, "claude", options.agentRoles?.claude ?? "architecture_security_reviewer"), "utf8");
191566
192050
  if (request.repoSummary)
191567
- await writeFile2(join4(contextDir, "repo_summary.md"), request.repoSummary, "utf8");
192051
+ await writeFile2(join5(contextDir, "repo_summary.md"), request.repoSummary, "utf8");
191568
192052
  if (request.currentPlan)
191569
- await writeFile2(join4(contextDir, "current_plan.md"), request.currentPlan, "utf8");
192053
+ await writeFile2(join5(contextDir, "current_plan.md"), request.currentPlan, "utf8");
191570
192054
  if (request.diff?.unifiedDiff)
191571
- await writeFile2(join4(contextDir, "diff.patch"), request.diff.unifiedDiff, "utf8");
192055
+ await writeFile2(join5(contextDir, "diff.patch"), request.diff.unifiedDiff, "utf8");
191572
192056
  return { root, repoDir, contextDir, fileCount };
191573
192057
  }
191574
192058
  function stripContents(request) {
@@ -191745,43 +192229,50 @@ async function runReview(tool, request, options = {}) {
191745
192229
  const cwd = options.cwd ?? process.cwd();
191746
192230
  const traceId = newTraceId();
191747
192231
  const startedAt = new Date().toISOString();
192232
+ const auditEnv = { ...process.env, ...options.env };
192233
+ const traceWriterFactory = options.traceWriterFactory ?? createTraceWriter;
191748
192234
  let snapshot;
191749
192235
  try {
191750
192236
  assertNotChildAgent(options.env ?? process.env);
191751
192237
  } catch (error51) {
191752
192238
  if (error51 instanceof KyosoRequestError) {
191753
192239
  const config2 = kyosoConfigSchema.parse(defaultConfig);
191754
- const trace2 = createTraceWriter({
192240
+ const trace2 = traceWriterFactory({
191755
192241
  enabled: config2.audit.enabled,
191756
192242
  directory: config2.audit.directory,
191757
192243
  traceId,
191758
- cwd
191759
- });
191760
- await trace2.write({
191761
- type: "request_received",
191762
- traceId,
191763
- tool,
191764
- timestamp: new Date().toISOString()
191765
- });
191766
- return await buildPolicyBlockResult({
191767
- tool,
191768
- trace: trace2,
191769
- traceId,
191770
- startedAt,
191771
- networkMode: config2.network.defaultMode,
191772
- warning: error51.message,
191773
- finding: {
191774
- id: "KYOSO-1",
191775
- severity: "critical",
191776
- category: "other",
191777
- title: "Recursive Kyoso invocation blocked",
191778
- evidence: error51.message,
191779
- recommendation: "Do not expose Kyoso MCP tools to Kyoso child agents.",
191780
- sourceAgents: ["kyoso_policy"],
191781
- confidence: "high"
191782
- },
191783
- redactionsApplied: 0
192244
+ cwd,
192245
+ env: auditEnv
191784
192246
  });
192247
+ try {
192248
+ await trace2.write({
192249
+ type: "request_received",
192250
+ traceId,
192251
+ tool,
192252
+ timestamp: new Date().toISOString()
192253
+ });
192254
+ return await buildPolicyBlockResult({
192255
+ tool,
192256
+ trace: trace2,
192257
+ traceId,
192258
+ startedAt,
192259
+ networkMode: config2.network.defaultMode,
192260
+ warning: error51.message,
192261
+ finding: {
192262
+ id: "KYOSO-1",
192263
+ severity: "critical",
192264
+ category: "other",
192265
+ title: "Recursive Kyoso invocation blocked",
192266
+ evidence: error51.message,
192267
+ recommendation: "Do not expose Kyoso MCP tools to Kyoso child agents.",
192268
+ sourceAgents: ["kyoso_policy"],
192269
+ confidence: "high"
192270
+ },
192271
+ redactionsApplied: 0
192272
+ });
192273
+ } finally {
192274
+ await trace2.finalize();
192275
+ }
191785
192276
  }
191786
192277
  throw error51;
191787
192278
  }
@@ -191806,12 +192297,13 @@ async function runReview(tool, request, options = {}) {
191806
192297
  ...baseLoaded,
191807
192298
  config: applyConfigOverrides(baseLoaded.config, options.configOverrides)
191808
192299
  } : baseLoaded;
191809
- const trace = createTraceWriter({
192300
+ const trace = traceWriterFactory({
191810
192301
  enabled: loaded.config.audit.enabled,
191811
192302
  directory: loaded.config.audit.directory,
191812
192303
  traceId,
191813
192304
  cwd,
191814
- includeRawAgentOutput: loaded.config.audit.includeRawAgentOutput
192305
+ includeRawAgentOutput: loaded.config.audit.includeRawAgentOutput,
192306
+ env: auditEnv
191815
192307
  });
191816
192308
  const warnings = [...loaded.warnings, ...trace.warnings];
191817
192309
  try {
@@ -191893,11 +192385,11 @@ async function runReview(tool, request, options = {}) {
191893
192385
  manager,
191894
192386
  trace
191895
192387
  });
191896
- warnings.push(...agentResults.flatMap((result2) => (result2.warnings ?? []).map((warning) => `Agent ${result2.agent} ${warning}`)));
192388
+ warnings.push(...agentResults.flatMap((result) => (result.warnings ?? []).map((warning) => `Agent ${result.agent} ${warning}`)));
191897
192389
  const normalizedAgentResults = agentResults.map(normalizeAgentRunResult);
191898
- const agentsUsed = normalizedAgentResults.map((result2) => result2.agent);
192390
+ const agentsUsed = normalizedAgentResults.map((result) => result.agent);
191899
192391
  const reviewMode = agentsUsed.length === 1 ? "single_agent" : "multi_agent";
191900
- const completed = normalizedAgentResults.filter((result2) => result2.status === "completed");
192392
+ const completed = normalizedAgentResults.filter((result) => result.status === "completed");
191901
192393
  const degraded = completed.length !== agentResults.length;
191902
192394
  let aggregate = aggregateAgentResults(normalizedAgentResults, {
191903
192395
  reviewMode
@@ -191924,7 +192416,7 @@ async function runReview(tool, request, options = {}) {
191924
192416
  severity: "critical",
191925
192417
  category: "other",
191926
192418
  title: "All backend agents failed",
191927
- evidence: normalizedAgentResults.map((result2) => `${result2.agent}: ${result2.error?.code ?? result2.status}`).join("; "),
192419
+ evidence: normalizedAgentResults.map((result) => `${result.agent}: ${result.error?.code ?? result.status}`).join("; "),
191928
192420
  recommendation: "Run kyoso doctor and retry after agent authentication or adapter issues are fixed.",
191929
192421
  sourceAgents: ["kyoso_policy"],
191930
192422
  confidence: "high"
@@ -191974,7 +192466,7 @@ async function runReview(tool, request, options = {}) {
191974
192466
  residualRisks: tool === "security_review" && aggregate.residualRisks.length === 0 ? [
191975
192467
  "No residual risks were reported by completed agents; verify security assumptions before release."
191976
192468
  ] : aggregate.residualRisks,
191977
- agentOpinions: normalizedAgentResults.map((result2) => agentOpinionSummary(result2, request.options?.includeAgentRawOutputs === true)),
192469
+ agentOpinions: normalizedAgentResults.map((result) => agentOpinionSummary(result, request.options?.includeAgentRawOutputs === true)),
191978
192470
  audit: {
191979
192471
  traceId,
191980
192472
  startedAt,
@@ -192006,15 +192498,10 @@ async function runReview(tool, request, options = {}) {
192006
192498
  judgeComment: judgeComments.get(disagreement.topic) ?? disagreement.judgeComment
192007
192499
  }));
192008
192500
  const crossModelAnalysis = buildCrossModelAnalysis(judge, reviewMode);
192009
- const result = {
192501
+ const resultAfterJudge = {
192010
192502
  ...resultWithoutMarkdown,
192011
192503
  disagreements,
192012
- ...crossModelAnalysis ? { crossModelAnalysis } : {},
192013
- summaryMarkdown: renderMarkdownResult(tool, {
192014
- ...resultWithoutMarkdown,
192015
- disagreements,
192016
- ...crossModelAnalysis ? { crossModelAnalysis } : {}
192017
- }, { summaryText: judge.output.summaryText })
192504
+ ...crossModelAnalysis ? { crossModelAnalysis } : {}
192018
192505
  };
192019
192506
  const judgeEvent = {
192020
192507
  type: "judge_completed",
@@ -192026,7 +192513,7 @@ async function runReview(tool, request, options = {}) {
192026
192513
  if (judge.error)
192027
192514
  judgeEvent.error = judge.error;
192028
192515
  await trace.write(judgeEvent);
192029
- result.audit.completedAt = new Date().toISOString();
192516
+ resultAfterJudge.audit.completedAt = new Date().toISOString();
192030
192517
  await trace.write({
192031
192518
  type: "decision_completed",
192032
192519
  traceId,
@@ -192038,8 +192525,14 @@ async function runReview(tool, request, options = {}) {
192038
192525
  traceId,
192039
192526
  timestamp: new Date().toISOString()
192040
192527
  });
192041
- return result;
192528
+ return await finalizeReviewResult({
192529
+ tool,
192530
+ trace,
192531
+ result: resultAfterJudge,
192532
+ summaryText: judge.output.summaryText
192533
+ });
192042
192534
  } finally {
192535
+ await trace.finalize();
192043
192536
  if (snapshot)
192044
192537
  await cleanupSnapshot(snapshot.root);
192045
192538
  }
@@ -192288,10 +192781,6 @@ async function buildSecretBlockResult(input) {
192288
192781
  warnings: input.warnings
192289
192782
  }
192290
192783
  };
192291
- const result = {
192292
- ...resultWithoutMarkdown,
192293
- summaryMarkdown: renderMarkdownResult(input.tool, resultWithoutMarkdown)
192294
- };
192295
192784
  await input.trace.write({
192296
192785
  type: "decision_completed",
192297
192786
  traceId: input.traceId,
@@ -192303,7 +192792,11 @@ async function buildSecretBlockResult(input) {
192303
192792
  traceId: input.traceId,
192304
192793
  timestamp: new Date().toISOString()
192305
192794
  });
192306
- return result;
192795
+ return await finalizeReviewResult({
192796
+ tool: input.tool,
192797
+ trace: input.trace,
192798
+ result: resultWithoutMarkdown
192799
+ });
192307
192800
  }
192308
192801
  function buildSecretFinding(secretScan, options) {
192309
192802
  return {
@@ -192353,10 +192846,6 @@ async function buildPolicyBlockResult(input) {
192353
192846
  warnings: [input.warning]
192354
192847
  }
192355
192848
  };
192356
- const result = {
192357
- ...resultWithoutMarkdown,
192358
- summaryMarkdown: renderMarkdownResult(input.tool, resultWithoutMarkdown)
192359
- };
192360
192849
  await input.trace.write({
192361
192850
  type: "decision_completed",
192362
192851
  traceId: input.traceId,
@@ -192368,7 +192857,30 @@ async function buildPolicyBlockResult(input) {
192368
192857
  traceId: input.traceId,
192369
192858
  timestamp: new Date().toISOString()
192370
192859
  });
192371
- return result;
192860
+ return await finalizeReviewResult({
192861
+ tool: input.tool,
192862
+ trace: input.trace,
192863
+ result: resultWithoutMarkdown
192864
+ });
192865
+ }
192866
+ async function finalizeReviewResult(input) {
192867
+ await input.trace.finalize();
192868
+ const result = {
192869
+ ...input.result,
192870
+ audit: {
192871
+ ...input.result.audit,
192872
+ warnings: Array.from(new Set([
192873
+ ...input.result.audit.warnings ?? [],
192874
+ ...input.trace.warnings
192875
+ ]))
192876
+ }
192877
+ };
192878
+ return {
192879
+ ...result,
192880
+ summaryMarkdown: renderMarkdownResult(input.tool, result, {
192881
+ summaryText: input.summaryText
192882
+ })
192883
+ };
192372
192884
  }
192373
192885
  function mergeDenyPatterns(configDeny, requestDeny) {
192374
192886
  return Array.from(new Set([...configDeny, ...requestDeny ?? []]));
@@ -192376,7 +192888,7 @@ function mergeDenyPatterns(configDeny, requestDeny) {
192376
192888
  function assertTrustedWorkspaceRoot(requestRoot, configRoot, cwd) {
192377
192889
  if (!requestRoot)
192378
192890
  return;
192379
- if (resolve4(cwd, requestRoot) !== resolve4(cwd, configRoot)) {
192891
+ if (resolve6(cwd, requestRoot) !== resolve6(cwd, configRoot)) {
192380
192892
  throw new KyosoRequestError("workspace.root is not trusted by config", "UNTRUSTED_WORKSPACE_ROOT");
192381
192893
  }
192382
192894
  }