@sjawhar/pi-legion-envoy 5.17.4 → 5.17.6

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.
Files changed (2) hide show
  1. package/dist/legion.js +232 -58
  2. package/package.json +1 -1
package/dist/legion.js CHANGED
@@ -33473,7 +33473,7 @@ import { logger } from "@oh-my-pi/pi-utils";
33473
33473
  // package.json
33474
33474
  var package_default = {
33475
33475
  name: "@sjawhar/pi-legion-envoy",
33476
- version: "5.17.4",
33476
+ version: "5.17.6",
33477
33477
  type: "module",
33478
33478
  omp: {
33479
33479
  extensions: [
@@ -34780,6 +34780,7 @@ import {
34780
34780
  opendirSync,
34781
34781
  openSync,
34782
34782
  readFileSync as readFileSync3,
34783
+ readlinkSync,
34783
34784
  readSync,
34784
34785
  realpathSync,
34785
34786
  statSync
@@ -41624,6 +41625,70 @@ function realish(abs, followFinal) {
41624
41625
  return realExisting(resolved);
41625
41626
  return path4.join(realExisting(path4.dirname(resolved)), path4.basename(resolved));
41626
41627
  }
41628
+ function readlinkTarget(link) {
41629
+ try {
41630
+ return readlinkSync(link);
41631
+ } catch {
41632
+ return "a target the guard cannot read";
41633
+ }
41634
+ }
41635
+ function physical(cwd, text, followFinal) {
41636
+ const joined = text.startsWith("/") ? text : `${cwd}/${text}`;
41637
+ const parts = joined.split("/");
41638
+ const last = parts.findLastIndex((part) => part !== "" && part !== ".");
41639
+ const pending = [];
41640
+ let real = "/";
41641
+ for (let i = 0;i < parts.length; i += 1) {
41642
+ const part = parts[i];
41643
+ if (part === "" || part === ".")
41644
+ continue;
41645
+ if (pending.length > 0) {
41646
+ if (part === "..") {
41647
+ return {
41648
+ unknown: `\`${path4.join(real, ...pending)}\`, which does not exist yet, so the guard ` + "cannot know where the `..` after it leads"
41649
+ };
41650
+ }
41651
+ pending.push(part);
41652
+ continue;
41653
+ }
41654
+ if (part === "..") {
41655
+ real = path4.dirname(real);
41656
+ continue;
41657
+ }
41658
+ const candidate = real === "/" ? `/${part}` : `${real}/${part}`;
41659
+ if (!followFinal && i === last) {
41660
+ return { real: candidate };
41661
+ }
41662
+ let link;
41663
+ try {
41664
+ link = lstatSync(candidate).isSymbolicLink();
41665
+ } catch (error48) {
41666
+ if (error48.code !== "ENOENT") {
41667
+ return { unknown: `\`${candidate}\`, which the guard cannot read (${messageFor(error48)})` };
41668
+ }
41669
+ pending.push(part);
41670
+ continue;
41671
+ }
41672
+ if (!link) {
41673
+ real = candidate;
41674
+ continue;
41675
+ }
41676
+ try {
41677
+ real = realpathSync(candidate);
41678
+ } catch (error48) {
41679
+ const code = error48.code;
41680
+ const why = code === "ENOENT" ? `points at \`${readlinkTarget(candidate)}\`, which is not there` : `cannot be followed (${messageFor(error48)})`;
41681
+ return { unknown: `the link \`${candidate}\` ${why}, so the guard cannot resolve this path` };
41682
+ }
41683
+ }
41684
+ return { real: pending.length === 0 ? real : path4.join(real, ...pending) };
41685
+ }
41686
+ function kernelPath(from, text) {
41687
+ if (from === undefined && !text.startsWith("/"))
41688
+ return;
41689
+ const resolved = physical(from ?? "/", text, true);
41690
+ return "unknown" in resolved ? undefined : resolved.real;
41691
+ }
41627
41692
  function isProtectedScratchComponent(component, roots, partial2 = false) {
41628
41693
  return roots.protectedScratch.some((name) => component.startsWith(name) || partial2 && name.startsWith(component)) || roots.protectedDirectories.some((name) => component === name || partial2 && name.startsWith(component));
41629
41694
  }
@@ -41656,12 +41721,16 @@ function judgePath(exp, st, ctx, options) {
41656
41721
  resolution: `relative to a working directory unknown after ${st.cwdWhy}`
41657
41722
  };
41658
41723
  }
41659
- const abs = path4.resolve(st.cwd ?? "/", text);
41660
- const real2 = realish(abs, options.follow || text.endsWith("/"));
41724
+ const resolved2 = physical(st.cwd ?? "/", text, options.follow || text.endsWith("/"));
41725
+ if ("unknown" in resolved2) {
41726
+ return { ok: false, resolution: resolved2.unknown, unresolved: true };
41727
+ }
41728
+ const real2 = resolved2.real;
41661
41729
  if (inWorkspace(real2, roots) || inScratch(real2, roots))
41662
41730
  return { ok: true };
41663
41731
  if (options.overwrite && !existsSync(real2))
41664
41732
  return { ok: true };
41733
+ const abs = path4.resolve(st.cwd ?? "/", text);
41665
41734
  return { ok: false, resolution: real2 === abs ? real2 : `${abs}, which resolves to ${real2}` };
41666
41735
  }
41667
41736
  const piece = exp[open];
@@ -41676,11 +41745,13 @@ function judgePath(exp, st, ctx, options) {
41676
41745
  return { ok: false, resolution: `relative to a working directory unknown after ${st.cwdWhy}` };
41677
41746
  }
41678
41747
  const component = prefix.slice(slash + 1);
41679
- let stem = path4.resolve(st.cwd ?? "/", slash === -1 ? "." : slash === 0 ? "/" : prefix.slice(0, slash));
41680
- if (piece.kind === "glob" && (component === "" ? piece.text : component).startsWith(".")) {
41681
- stem = path4.dirname(stem);
41748
+ const stemText = slash === -1 ? "." : slash === 0 ? "/" : prefix.slice(0, slash);
41749
+ const resolved = physical(st.cwd ?? "/", stemText, true);
41750
+ if ("unknown" in resolved) {
41751
+ return { ok: false, resolution: resolved.unknown, unresolved: true };
41682
41752
  }
41683
- const real = realish(stem, true);
41753
+ const dotGlob = piece.kind === "glob" && (component === "" ? piece.text : component).startsWith(".");
41754
+ const real = dotGlob ? path4.dirname(resolved.real) : resolved.real;
41684
41755
  const allowed = inWorkspace(real, roots) || inScratch(real, roots) || real === roots.scratch && component !== "" && !isProtectedScratchComponent(component, roots, true);
41685
41756
  if (allowed)
41686
41757
  return { ok: true };
@@ -42014,12 +42085,13 @@ function patternExpansion(part, quoted, st, ctx) {
42014
42085
  return [unquotedLiteral(result.replaceAll("\\", "\\\\"), undefined, st, ctx)];
42015
42086
  }
42016
42087
  function substitution(script, text, st, ctx) {
42017
- const pidRead = /^\$\(<(.+)\)$/.exec(text);
42018
- const variableRead = /^\$\(<"?\$([A-Za-z_][A-Za-z0-9_]*)"?\)$/.exec(text);
42088
+ const pidRead = /^\$\(<\s*(.+?)\s*\)$/.exec(text);
42089
+ const variableRead = /^\$\(<\s*"?\$([A-Za-z_][A-Za-z0-9_]*)"?\s*\)$/.exec(text);
42019
42090
  const directFile = pidRead?.[1]?.includes("$") === true ? undefined : pidRead?.[1];
42020
42091
  const file2 = directFile ?? (variableRead === null ? undefined : literalText(lookup(variableRead[1], st, ctx)));
42021
- if (file2 !== undefined && st.cwd !== undefined) {
42022
- const pid = st.pidFiles.get(path4.resolve(st.cwd, file2));
42092
+ const pidFile = file2 === undefined ? undefined : kernelPath(st.cwd, file2);
42093
+ if (pidFile !== undefined) {
42094
+ const pid = st.pidFiles.get(pidFile);
42023
42095
  if (pid !== undefined)
42024
42096
  return [[...pid]];
42025
42097
  }
@@ -42067,28 +42139,76 @@ function commandOutput(only, invocation, text, st, ctx) {
42067
42139
  function substitutionInvocation(node, st, ctx) {
42068
42140
  if (node?.type !== "Command" || node.name === undefined || node.prefix.length !== 0)
42069
42141
  return;
42070
- const argv = args([node.name, ...node.suffix], st, ctx);
42142
+ const argv = commandArgs([node.name, ...node.suffix], st, ctx);
42071
42143
  const name = literalText(argv[0]?.exp);
42072
42144
  if (name === undefined)
42073
42145
  return;
42074
42146
  return { base: path4.basename(name), command: node, rest: argv.slice(1) };
42075
42147
  }
42148
+ function gnuDirname(text) {
42149
+ const trimmed = text.replace(/\/+$/, "");
42150
+ if (trimmed === "")
42151
+ return "/";
42152
+ const cut = trimmed.replace(/\/+[^/]+$/, "");
42153
+ if (cut === trimmed)
42154
+ return ".";
42155
+ return cut === "" ? "/" : cut;
42156
+ }
42157
+ function gnuBasename(text) {
42158
+ const trimmed = text.replace(/\/+$/, "");
42159
+ if (trimmed === "")
42160
+ return text === "" ? "" : "/";
42161
+ return trimmed.slice(trimmed.lastIndexOf("/") + 1);
42162
+ }
42076
42163
  function substitutionPath(base, list, st) {
42077
42164
  if (!["dirname", "basename", "realpath", "readlink"].includes(base))
42078
42165
  return;
42079
- const target = literalText(operands(list, "").operands.at(-1)?.exp);
42080
- if (target === undefined || st.cwd === undefined)
42166
+ const found = operands(list, "");
42167
+ if (base === "basename" && found.options.some((option) => option === "--multiple" || option.startsWith("--suffix") || /^-[^-]*[as]/.test(option))) {
42168
+ return;
42169
+ }
42170
+ const suffixed = base === "basename" && found.operands.length === 2;
42171
+ if (found.operands.length !== 1 && !suffixed)
42172
+ return;
42173
+ const target = literalText(found.operands[0]?.exp);
42174
+ const suffix = suffixed ? literalText(found.operands[1]?.exp) : "";
42175
+ if (target === undefined || suffix === undefined || st.cwd === undefined)
42081
42176
  return;
42082
42177
  if (target === "")
42083
42178
  return base === "dirname" ? "." : "";
42084
- const abs = path4.resolve(st.cwd, target);
42085
42179
  if (base === "dirname")
42086
- return path4.dirname(abs);
42087
- if (base === "basename")
42088
- return path4.basename(abs);
42089
- if (base === "readlink" && !list.some((arg) => literalText(arg.exp)?.includes("f")))
42090
- return;
42091
- return realExisting(abs);
42180
+ return gnuDirname(target);
42181
+ if (base === "basename") {
42182
+ const name = gnuBasename(target);
42183
+ return suffix !== "" && name !== suffix && name.endsWith(suffix) ? name.slice(0, -suffix.length) : name;
42184
+ }
42185
+ if (base === "readlink") {
42186
+ const mode = lastModeFlag(found.options, "fem", {
42187
+ "--canonicalize": "f",
42188
+ "--canonicalize-existing": "e",
42189
+ "--canonicalize-missing": "m"
42190
+ });
42191
+ if (mode !== "f" && mode !== "m")
42192
+ return;
42193
+ }
42194
+ if (base === "realpath") {
42195
+ if (found.options.some((option) => option.startsWith("--relative")))
42196
+ return;
42197
+ const mode = lastModeFlag(found.options, "sLP", {
42198
+ "--strip": "s",
42199
+ "--no-symlinks": "s",
42200
+ "--logical": "L",
42201
+ "--physical": "P"
42202
+ });
42203
+ if (mode === "s" || mode === "L") {
42204
+ const here = kernelPath("/", st.cwd);
42205
+ if (here === undefined)
42206
+ return;
42207
+ const lexical = path4.resolve(here, target);
42208
+ return mode === "s" ? lexical : kernelPath("/", lexical);
42209
+ }
42210
+ }
42211
+ return kernelPath(st.cwd, target);
42092
42212
  }
42093
42213
  function mktempPath(command, st, ctx) {
42094
42214
  const words = command.suffix;
@@ -42107,7 +42227,7 @@ function mktempPath(command, st, ctx) {
42107
42227
  else if (value.startsWith("-p") && value.length > 2)
42108
42228
  directory = [literal2(value.slice(2))];
42109
42229
  else if (!value.startsWith("-") && value.includes("/")) {
42110
- directory = [literal2(path4.resolve(st.cwd ?? "/", path4.dirname(value)))];
42230
+ directory = [literal2(path4.dirname(value))];
42111
42231
  }
42112
42232
  }
42113
42233
  const base = directory ?? [literal2(ctx.env.TMPDIR ?? "/tmp")];
@@ -42229,6 +42349,14 @@ function args(words, st, ctx) {
42229
42349
  });
42230
42350
  });
42231
42351
  }
42352
+ function commandArgs(words, st, ctx) {
42353
+ const argv = args(words, st, ctx);
42354
+ for (let index = argv.length - 1;index >= 0; index -= 1) {
42355
+ if (argv[index]?.fields === "none")
42356
+ argv.splice(index, 1);
42357
+ }
42358
+ return argv;
42359
+ }
42232
42360
  function positionalOf(list) {
42233
42361
  if (list.some((arg) => arg.fields === "unknown"))
42234
42362
  return;
@@ -42553,6 +42681,10 @@ function modelPidFile(st, ctx, file2, pid) {
42553
42681
  model.set(file2, [unknown2("a pid a branch or loop body wrote to this file", true)]);
42554
42682
  }
42555
42683
  }
42684
+ function forgetFileModels(st, ctx, why) {
42685
+ st.pidFiles.clear();
42686
+ ctx.unnameableWrite.why ??= why;
42687
+ }
42556
42688
  function handlerVars(trap, vars) {
42557
42689
  const { vars: branch, merged } = trap;
42558
42690
  if (branch === undefined || merged === undefined)
@@ -42944,13 +43076,15 @@ function checkRedirects(redirects, command, site, st, ctx) {
42944
43076
  if (writes || operator === ">&") {
42945
43077
  const verdict = judgePath(exp, st, ctx, { follow: true, overwrite: true });
42946
43078
  if (!verdict.ok) {
42947
- throw refusal(site, `the redirection \`${operator}\` would overwrite \`${redirect.target.text}\` (${verdict.resolution})`, ctx);
43079
+ throw refusal(site, `the redirection \`${operator}\` would overwrite \`${redirect.target.text}\` (${verdict.resolution})`, ctx, verdict.unresolved);
42948
43080
  }
42949
43081
  }
42950
43082
  const target = literalText(exp);
42951
- if (target === undefined || st.cwd === undefined && !target.startsWith("/"))
43083
+ const file2 = target === undefined ? undefined : kernelPath(st.cwd, target);
43084
+ if (file2 === undefined) {
43085
+ forgetFileModels(st, ctx, `the redirection \`${operator} ${redirect.target.text}\``);
42952
43086
  continue;
42953
- const file2 = path4.resolve(st.cwd ?? "/", target);
43087
+ }
42954
43088
  let content = null;
42955
43089
  if (command?.name === "cat" && command.args.length === 0) {
42956
43090
  if (heredoc !== undefined)
@@ -42984,9 +43118,9 @@ function groupOutputFile(statement, st, ctx) {
42984
43118
  }
42985
43119
  const targets = expandWord(redirect.target, st, ctx);
42986
43120
  const target = targets.length === 1 ? literalText(targets[0]) : undefined;
42987
- if (target === undefined || st.cwd === undefined && !target.startsWith("/"))
43121
+ if (target === undefined)
42988
43122
  return;
42989
- return path4.resolve(st.cwd ?? "/", target);
43123
+ return kernelPath(st.cwd, target);
42990
43124
  }
42991
43125
  function walkRenderingGroup(group, st, ctx) {
42992
43126
  let content = "";
@@ -43030,8 +43164,9 @@ function statementOutput(statement, st, ctx) {
43030
43164
  }
43031
43165
  if (command.name === undefined)
43032
43166
  return command.redirects.length === 0 ? "" : undefined;
43033
- const name = literalText(expandWord(command.name, st, ctx)[0]);
43034
- const rest = args(command.suffix, st, ctx);
43167
+ const argv = commandArgs([command.name, ...command.suffix], st, ctx);
43168
+ const name = literalText(argv[0]?.exp);
43169
+ const rest = argv.slice(1);
43035
43170
  if (name === "cat" && rest.length === 0) {
43036
43171
  const [heredoc, ...others] = command.redirects;
43037
43172
  if (heredoc === undefined || others.length > 0)
@@ -43105,8 +43240,10 @@ function printfText(list, limit, script = false) {
43105
43240
  } while (conversions > 0 && index < values.length);
43106
43241
  return out;
43107
43242
  }
43108
- function refusal(site, detail, ctx) {
43109
- return new Refusal(site.snippet, site.line, `${detail}, outside ${describeRoots(ctx.roots)}. ${HINT}`);
43243
+ function refusal(site, detail, ctx, unresolved = false) {
43244
+ const where = unresolved ? `. Every target is resolved as the kernel resolves it, against ${describeRoots(ctx.roots)}` : `, outside ${describeRoots(ctx.roots)}`;
43245
+ const hint = unresolved ? "Make the unresolved path component resolvable in an earlier command \u2014 create it, make " + "it readable, or fix a dangling or looping symlink \u2014 then run this command." : HINT;
43246
+ return new Refusal(site.snippet, site.line, `${detail}${where}. ${hint}`);
43110
43247
  }
43111
43248
  function handleCommand(command, st, ctx, pipeIn) {
43112
43249
  const site = siteOf(command, st);
@@ -43172,7 +43309,7 @@ function handleCommand(command, st, ctx, pipeIn) {
43172
43309
  checkRedirects(command.redirects, undefined, site, st, ctx);
43173
43310
  return;
43174
43311
  }
43175
- const argv = args(words, st, ctx);
43312
+ const argv = commandArgs(words, st, ctx);
43176
43313
  checkRedirects(command.redirects, { name: literalText(argv[0]?.exp), args: argv.slice(1) }, site, st, ctx);
43177
43314
  dispatch({ args: argv, site, overlay, redirects: command.redirects, pipeIn }, st, ctx);
43178
43315
  }
@@ -43204,6 +43341,16 @@ function operands(list, valued, longValued = []) {
43204
43341
  }
43205
43342
  return { options, operands: found };
43206
43343
  }
43344
+ function lastModeFlag(options, letters, long = {}) {
43345
+ return options.flatMap((option) => {
43346
+ const named = long[option];
43347
+ if (named !== undefined)
43348
+ return [named];
43349
+ if (!/^-[a-zA-Z]+$/.test(option))
43350
+ return [];
43351
+ return [...option.slice(1)].filter((letter) => letters.includes(letter));
43352
+ }).at(-1);
43353
+ }
43207
43354
  function unwrap2(argv, st, ctx, site) {
43208
43355
  const alts = [];
43209
43356
  let list = argv;
@@ -43287,10 +43434,10 @@ function unwrap2(argv, st, ctx, site) {
43287
43434
  i += 1;
43288
43435
  } else if (text === "-C" || text === "--chdir") {
43289
43436
  const dir = literalText(rest[i + 1]?.exp);
43290
- cwd = dir === undefined || state.cwd === undefined ? undefined : path4.resolve(state.cwd, dir);
43437
+ cwd = dir === undefined ? undefined : kernelPath(state.cwd, dir);
43291
43438
  i += 1;
43292
43439
  } else if (text?.startsWith("--chdir=")) {
43293
- cwd = state.cwd === undefined ? undefined : path4.resolve(state.cwd, text.slice(8));
43440
+ cwd = kernelPath(state.cwd, text.slice(8));
43294
43441
  } else if (text === "-S" || text === "--split-string") {
43295
43442
  const split = literalText(rest[i + 1]?.exp);
43296
43443
  const tail = rest.slice(i + 2);
@@ -43457,10 +43604,25 @@ function dispatch(invocation, outer, ctx) {
43457
43604
  outer.output = rest.length === 1 && rest[0] !== undefined ? [...outer.output, rest[0].exp] : undefined;
43458
43605
  }
43459
43606
  return;
43460
- case "cd":
43607
+ case "cd": {
43608
+ const found = operands(rest, "");
43609
+ if (found.options.some((option) => !/^-[LPe]+$/.test(option))) {
43610
+ outer.cwd = undefined;
43611
+ outer.cwdWhy = "`cd` with an option the guard does not model";
43612
+ return;
43613
+ }
43614
+ changeDirectory(found.operands[0], lastModeFlag(found.options, "LP") === "P", outer, ctx);
43615
+ return;
43616
+ }
43461
43617
  case "pushd": {
43462
- const target = operands(rest, "").operands[0];
43463
- changeDirectory(target, outer, ctx);
43618
+ const found = operands(rest, "");
43619
+ const operand = literalText(found.operands[0]?.exp);
43620
+ if (found.options.length > 0 || found.operands[0] === undefined || operand?.startsWith("+") === true) {
43621
+ outer.cwd = undefined;
43622
+ outer.cwdWhy = "`pushd` with a directory stack or option the guard does not model";
43623
+ return;
43624
+ }
43625
+ changeDirectory(found.operands[0], false, outer, ctx);
43464
43626
  return;
43465
43627
  }
43466
43628
  case "popd":
@@ -43753,7 +43915,7 @@ function dispatch(invocation, outer, ctx) {
43753
43915
  "--remote-option",
43754
43916
  "--rsync-path",
43755
43917
  "--temp-dir"
43756
- ]).operands.filter(passesAnArgument).at(-1);
43918
+ ]).operands.at(-1);
43757
43919
  if (destination !== undefined) {
43758
43920
  checkTargets("rsync", "synchronize and delete into", [destination], ACTS_THROUGH_LINK, st, ctx, site);
43759
43921
  }
@@ -43812,16 +43974,18 @@ function dispatch(invocation, outer, ctx) {
43812
43974
  if (!append) {
43813
43975
  const verdict = judgePath(arg.exp, st, ctx, { follow: true, overwrite: true });
43814
43976
  if (!verdict.ok) {
43815
- throw refusal(site, `tee would overwrite \`${arg.text}\` (${verdict.resolution})`, ctx);
43977
+ throw refusal(site, `tee would overwrite \`${arg.text}\` (${verdict.resolution})`, ctx, verdict.unresolved);
43816
43978
  }
43817
43979
  }
43818
43980
  const target = literalText(arg.exp);
43819
- if (target !== undefined && st.cwd !== undefined) {
43820
- const file2 = path4.resolve(st.cwd, target);
43821
- st.pidFiles.delete(file2);
43822
- const text = heredoc === undefined ? null : heredocText(heredoc);
43823
- modelWrite(st, ctx, file2, append ? UNREAD_FILE : text === null ? UNRENDERED_WRITE : readable(text) ?? OVERLONG_WRITE);
43981
+ const file2 = target === undefined ? undefined : kernelPath(st.cwd, target);
43982
+ if (file2 === undefined) {
43983
+ forgetFileModels(st, ctx, `\`tee ${arg.text}\``);
43984
+ continue;
43824
43985
  }
43986
+ st.pidFiles.delete(file2);
43987
+ const text = heredoc === undefined ? null : heredocText(heredoc);
43988
+ modelWrite(st, ctx, file2, append ? UNREAD_FILE : text === null ? UNRENDERED_WRITE : readable(text) ?? OVERLONG_WRITE);
43825
43989
  }
43826
43990
  return;
43827
43991
  }
@@ -43946,7 +44110,7 @@ function dispatch(invocation, outer, ctx) {
43946
44110
  runFile(argv[0], rest, childState(st, invocation.overlay), ctx, site, "auto");
43947
44111
  }
43948
44112
  }
43949
- function changeDirectory(target, st, ctx) {
44113
+ function changeDirectory(target, physicalMode, st, ctx) {
43950
44114
  if (target === undefined) {
43951
44115
  const home = literalText(lookup("HOME", st, ctx));
43952
44116
  st.cwd = home;
@@ -43959,7 +44123,13 @@ function changeDirectory(target, st, ctx) {
43959
44123
  st.cwdWhy = `\`cd ${target.text}\``;
43960
44124
  return;
43961
44125
  }
43962
- st.cwd = path4.resolve(st.cwd, text);
44126
+ if (!physicalMode) {
44127
+ st.cwd = path4.resolve(st.cwd, text);
44128
+ return;
44129
+ }
44130
+ st.cwd = kernelPath(st.cwd, text);
44131
+ if (st.cwd === undefined)
44132
+ st.cwdWhy = `\`cd -P ${target.text}\``;
43963
44133
  }
43964
44134
  function declaration(builtin, list, st, ctx, site) {
43965
44135
  const options = list.map((arg) => literalText(arg.exp) ?? "").filter((text) => /^[-+][a-zA-Z]+$/.test(text));
@@ -44155,13 +44325,13 @@ function checkTargets(program, verb, targets, reach, st, ctx, site) {
44155
44325
  continue;
44156
44326
  const verdict = judgePath(target.exp, st, ctx, { follow, overwrite: reach.overwrite });
44157
44327
  if (!verdict.ok) {
44158
- throw refusal(site, `${program} would ${verb} \`${target.text}\` (${verdict.resolution})`, ctx);
44328
+ throw refusal(site, `${program} would ${verb} \`${target.text}\` (${verdict.resolution})`, ctx, verdict.unresolved);
44159
44329
  }
44160
44330
  }
44161
44331
  const text = literalText(target.exp);
44162
- if (text !== undefined && (text.startsWith("/") || st.cwd !== undefined)) {
44163
- st.pidFiles.delete(path4.resolve(st.cwd ?? "/", text));
44164
- }
44332
+ const file2 = text === undefined ? undefined : kernelPath(st.cwd, text);
44333
+ if (file2 !== undefined)
44334
+ st.pidFiles.delete(file2);
44165
44335
  }
44166
44336
  }
44167
44337
  function completeName(prefix, names) {
@@ -44255,9 +44425,6 @@ var LN_OPTIONS = {
44255
44425
  "--verbose": false,
44256
44426
  ...GNU_INFORMATION
44257
44427
  };
44258
- function passesAnArgument(arg) {
44259
- return arg.fields !== "none";
44260
- }
44261
44428
  function writeArguments(rest, valued, long) {
44262
44429
  const names = Object.keys(long);
44263
44430
  const operands2 = [];
@@ -44268,14 +44435,13 @@ function writeArguments(rest, valued, long) {
44268
44435
  const arg = rest[i];
44269
44436
  const { text, whole } = readableWord(arg);
44270
44437
  if (whole && text === "--") {
44271
- operands2.push(...rest.slice(i + 1).filter(passesAnArgument));
44438
+ operands2.push(...rest.slice(i + 1));
44272
44439
  break;
44273
44440
  }
44274
44441
  if (!whole || !text.startsWith("-") || text === "-") {
44275
44442
  if (!whole && mayBeSomeOption(text))
44276
44443
  uncertain = arg;
44277
- if (passesAnArgument(arg))
44278
- operands2.push(arg);
44444
+ operands2.push(arg);
44279
44445
  continue;
44280
44446
  }
44281
44447
  let takesValue = false;
@@ -44917,7 +45083,14 @@ function runFile(file2, positional, st, ctx, site, kind, source = false) {
44917
45083
  if (text === undefined || !text.startsWith("/") && st.cwd === undefined) {
44918
45084
  throw new Refusal(site.snippet, site.line, `the guard cannot resolve the script \`${file2.text}\` (${file2.exp.find((p) => p.kind !== "literal")?.why ?? `a working directory unknown after ${st.cwdWhy}`}), so it cannot read what it runs`);
44919
45085
  }
44920
- const abs = path4.resolve(st.cwd ?? "/", text);
45086
+ if (ctx.unnameableWrite.why !== undefined) {
45087
+ throw new Refusal(site.snippet, site.line, `${ctx.unnameableWrite.why} writes a file the guard cannot name, so it cannot tell whether \`${file2.text}\` is the file that was written`);
45088
+ }
45089
+ const resolved = physical(st.cwd ?? "/", text, true);
45090
+ if ("unknown" in resolved) {
45091
+ throw new Refusal(site.snippet, site.line, `the guard cannot resolve the script \`${file2.text}\` (${resolved.unknown}), so it cannot read what it runs`);
45092
+ }
45093
+ const abs = resolved.real;
44921
45094
  let content;
44922
45095
  if (st.files.has(abs)) {
44923
45096
  const written = st.files.get(abs);
@@ -45045,7 +45218,7 @@ function checkCode(language, code, st, ctx, ipython = false) {
45045
45218
  overwrite: verb === "overwrite"
45046
45219
  });
45047
45220
  if (!verdict.ok) {
45048
- throw refusal({ snippet: call, line: 1 }, `${call} would ${verb} ${verdict.resolution}`, ctx);
45221
+ throw refusal({ snippet: call, line: 1 }, `${call} would ${verb} ${verdict.resolution}`, ctx, verdict.unresolved);
45049
45222
  }
45050
45223
  },
45051
45224
  signal: (call, pid, group) => {
@@ -45116,6 +45289,7 @@ function createPaneGuard(options) {
45116
45289
  ompPid: options.ompPid,
45117
45290
  parentOf: options.parentOf ?? procParent,
45118
45291
  steps: { count: 0 },
45292
+ unnameableWrite: { why: undefined },
45119
45293
  uncertain: { depth: 0 }
45120
45294
  });
45121
45295
  const initial = (cwd, source) => ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/pi-legion-envoy",
3
- "version": "5.17.4",
3
+ "version": "5.17.6",
4
4
  "type": "module",
5
5
  "omp": {
6
6
  "extensions": [