@sjawhar/pi-legion-envoy 5.16.6 → 5.16.7
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/legion.js +157 -28
- package/package.json +1 -1
package/dist/legion.js
CHANGED
|
@@ -33415,7 +33415,7 @@ import { logger } from "@oh-my-pi/pi-utils";
|
|
|
33415
33415
|
// package.json
|
|
33416
33416
|
var package_default = {
|
|
33417
33417
|
name: "@sjawhar/pi-legion-envoy",
|
|
33418
|
-
version: "5.16.
|
|
33418
|
+
version: "5.16.7",
|
|
33419
33419
|
type: "module",
|
|
33420
33420
|
omp: {
|
|
33421
33421
|
extensions: [
|
|
@@ -41227,6 +41227,15 @@ function scanIpythonShell(source, sinks) {
|
|
|
41227
41227
|
}
|
|
41228
41228
|
|
|
41229
41229
|
// src/legion/pane-guard.ts
|
|
41230
|
+
var definitions = new WeakMap;
|
|
41231
|
+
function trapSignal(operand) {
|
|
41232
|
+
const name = operand.toUpperCase();
|
|
41233
|
+
if (name === "0")
|
|
41234
|
+
return "EXIT";
|
|
41235
|
+
return name.startsWith("SIG") && name !== "SIGEXIT" ? name.slice(3) : name;
|
|
41236
|
+
}
|
|
41237
|
+
var UNREADABLE_CONDITION = "an unreadable condition";
|
|
41238
|
+
|
|
41230
41239
|
class Refusal extends Error {
|
|
41231
41240
|
snippet;
|
|
41232
41241
|
line;
|
|
@@ -41252,7 +41261,7 @@ function wrapRefusal(error48, site, label) {
|
|
|
41252
41261
|
throw new Refusal(site.snippet, site.line, `line ${error48.line} of ${source}, \`${error48.snippet}\`: ${error48.detail}`);
|
|
41253
41262
|
}
|
|
41254
41263
|
var MAX_DEPTH = 8;
|
|
41255
|
-
var MAX_WALK_STEPS =
|
|
41264
|
+
var MAX_WALK_STEPS = 1e5;
|
|
41256
41265
|
var MAX_ALTERNATIVES = 64;
|
|
41257
41266
|
var MAX_SCRIPT_BYTES = 1024 * 1024;
|
|
41258
41267
|
var FRESH_TEMP_NAME = "tmp.XXXXXXXXXX";
|
|
@@ -41570,12 +41579,22 @@ function substitution(script, text, st, ctx) {
|
|
|
41570
41579
|
}
|
|
41571
41580
|
const only = script?.commands.length === 1 ? script.commands[0]?.command : undefined;
|
|
41572
41581
|
const invocation = substitutionInvocation(only, st, ctx);
|
|
41573
|
-
const
|
|
41574
|
-
if (
|
|
41575
|
-
const
|
|
41576
|
-
|
|
41577
|
-
|
|
41582
|
+
const callee = invocation === undefined ? undefined : st.functions.get(invocation.base);
|
|
41583
|
+
if (callee !== undefined && invocation !== undefined) {
|
|
41584
|
+
const alternatives = [];
|
|
41585
|
+
let external2 = false;
|
|
41586
|
+
for (const definition of callee) {
|
|
41587
|
+
const output = definition === undefined ? undefined : functionOutput(invocation.base, definition, invocation.rest, st, ctx);
|
|
41588
|
+
if (output !== undefined)
|
|
41589
|
+
alternatives.push(...output.map((value) => [...value]));
|
|
41590
|
+
else
|
|
41591
|
+
external2 = true;
|
|
41592
|
+
}
|
|
41593
|
+
return external2 ? [...alternatives, ...commandOutput(only, invocation, text, st, ctx)] : alternatives;
|
|
41578
41594
|
}
|
|
41595
|
+
return commandOutput(only, invocation, text, st, ctx);
|
|
41596
|
+
}
|
|
41597
|
+
function commandOutput(only, invocation, text, st, ctx) {
|
|
41579
41598
|
if (invocation !== undefined) {
|
|
41580
41599
|
if (invocation.base === "pwd" && invocation.rest.length === 0 && st.cwd !== undefined) {
|
|
41581
41600
|
return [[literal2(st.cwd)]];
|
|
@@ -41813,7 +41832,7 @@ function walkSubstitution(script, inner, text, st, ctx) {
|
|
|
41813
41832
|
throw new Refusal(text, 1, `the guard could not read the command in \`${text}\``);
|
|
41814
41833
|
}
|
|
41815
41834
|
const source = parsed.source ?? (script === undefined ? inner ?? "" : st.source);
|
|
41816
|
-
walkScript(parsed,
|
|
41835
|
+
walkScript(parsed, subshell(st, { source }), ctx);
|
|
41817
41836
|
}
|
|
41818
41837
|
function clone2(st) {
|
|
41819
41838
|
return {
|
|
@@ -41856,6 +41875,8 @@ function merge2(target, branches) {
|
|
|
41856
41875
|
target.arrays.set(name, new Map([[UNKNOWN_ARRAY_INDEX, unknownElement]]));
|
|
41857
41876
|
}
|
|
41858
41877
|
}
|
|
41878
|
+
const positionals = branches.map((branch) => JSON.stringify(branch.positional ?? null));
|
|
41879
|
+
target.positional = positionals.every((value) => value === positionals[0]) ? branches[0]?.positional : undefined;
|
|
41859
41880
|
const cwds = new Set(branches.map((branch) => branch.cwd));
|
|
41860
41881
|
if (cwds.size > 1) {
|
|
41861
41882
|
target.cwd = undefined;
|
|
@@ -41869,6 +41890,46 @@ function merge2(target, branches) {
|
|
|
41869
41890
|
target.exported.add(name);
|
|
41870
41891
|
target.backgroundStarted ||= branch.backgroundStarted;
|
|
41871
41892
|
}
|
|
41893
|
+
const functionNames = new Set;
|
|
41894
|
+
for (const branch of branches)
|
|
41895
|
+
for (const name of branch.functions.keys())
|
|
41896
|
+
functionNames.add(name);
|
|
41897
|
+
const functions = new Map;
|
|
41898
|
+
for (const name of functionNames) {
|
|
41899
|
+
const callees = branches.map((branch) => branch.functions.get(name));
|
|
41900
|
+
const first = callees[0];
|
|
41901
|
+
if (first !== undefined && callees.every((callee) => callee === first)) {
|
|
41902
|
+
functions.set(name, first);
|
|
41903
|
+
continue;
|
|
41904
|
+
}
|
|
41905
|
+
const candidates = new Set;
|
|
41906
|
+
for (const callee of callees)
|
|
41907
|
+
for (const definition of callee ?? [undefined])
|
|
41908
|
+
candidates.add(definition);
|
|
41909
|
+
functions.set(name, [...candidates]);
|
|
41910
|
+
}
|
|
41911
|
+
target.functions = functions;
|
|
41912
|
+
const lifted = [];
|
|
41913
|
+
let merged;
|
|
41914
|
+
for (const branch of branches) {
|
|
41915
|
+
for (const trap of branch.traps) {
|
|
41916
|
+
if (target.traps.includes(trap))
|
|
41917
|
+
continue;
|
|
41918
|
+
merged ??= new Map(target.vars);
|
|
41919
|
+
lifted.push({ ...trap, vars: handlerVars(trap, branch.vars), merged });
|
|
41920
|
+
}
|
|
41921
|
+
}
|
|
41922
|
+
target.traps = [...target.traps, ...lifted];
|
|
41923
|
+
}
|
|
41924
|
+
function handlerVars(trap, vars) {
|
|
41925
|
+
const { vars: branch, merged } = trap;
|
|
41926
|
+
if (branch === undefined || merged === undefined)
|
|
41927
|
+
return vars;
|
|
41928
|
+
const out = new Map(vars);
|
|
41929
|
+
for (const [name, value] of branch)
|
|
41930
|
+
if (vars.get(name) === merged.get(name))
|
|
41931
|
+
out.set(name, value);
|
|
41932
|
+
return out;
|
|
41872
41933
|
}
|
|
41873
41934
|
function lineOf(source, pos) {
|
|
41874
41935
|
let line = 1;
|
|
@@ -41894,13 +41955,19 @@ function walkScript(script, st, ctx, runTraps = true) {
|
|
|
41894
41955
|
}
|
|
41895
41956
|
for (const statement of script.commands)
|
|
41896
41957
|
walkNode(statement, st, ctx, false);
|
|
41897
|
-
if (
|
|
41898
|
-
|
|
41958
|
+
if (runTraps)
|
|
41959
|
+
runSetTraps(st, ctx);
|
|
41960
|
+
}
|
|
41961
|
+
function subshell(st, patch) {
|
|
41962
|
+
return { ...clone2(st), traps: [], ...patch };
|
|
41963
|
+
}
|
|
41964
|
+
function runSetTraps(st, ctx) {
|
|
41899
41965
|
for (const trap of st.traps) {
|
|
41966
|
+
const vars = new Map([...handlerVars(trap, st.vars), ...trap.pids ?? []]);
|
|
41900
41967
|
try {
|
|
41901
|
-
runText(trap.text, "the EXIT trap",
|
|
41902
|
-
} catch (
|
|
41903
|
-
locateRefusal(
|
|
41968
|
+
runText(trap.text, "the EXIT trap", subshell(st, { source: trap.file, vars }), ctx, trap.site);
|
|
41969
|
+
} catch (error48) {
|
|
41970
|
+
locateRefusal(error48, trap.file);
|
|
41904
41971
|
}
|
|
41905
41972
|
}
|
|
41906
41973
|
}
|
|
@@ -41919,20 +41986,34 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
41919
41986
|
switch (node.type) {
|
|
41920
41987
|
case "Statement": {
|
|
41921
41988
|
checkRedirects(node.redirects, undefined, siteOf(node, st), st, ctx);
|
|
41922
|
-
|
|
41923
|
-
|
|
41989
|
+
if (node.background) {
|
|
41990
|
+
const before = st.output;
|
|
41991
|
+
const child = subshell(st);
|
|
41992
|
+
walkNode(node.command, child, ctx, pipeIn);
|
|
41993
|
+
runSetTraps(child, ctx);
|
|
41994
|
+
if (outputChanged(before, child.output))
|
|
41995
|
+
st.output = undefined;
|
|
41924
41996
|
st.backgroundStarted = true;
|
|
41997
|
+
return;
|
|
41998
|
+
}
|
|
41999
|
+
walkNode(node.command, st, ctx, pipeIn);
|
|
41925
42000
|
return;
|
|
41926
42001
|
}
|
|
41927
42002
|
case "Command":
|
|
41928
42003
|
handleCommand(node, st, ctx, pipeIn);
|
|
41929
42004
|
return;
|
|
41930
42005
|
case "Pipeline": {
|
|
42006
|
+
if (node.commands.length === 1) {
|
|
42007
|
+
for (const command of node.commands)
|
|
42008
|
+
walkNode(command, st, ctx, pipeIn);
|
|
42009
|
+
return;
|
|
42010
|
+
}
|
|
41931
42011
|
const before = st.output;
|
|
41932
42012
|
const parts = [];
|
|
41933
42013
|
for (const [index, command] of node.commands.entries()) {
|
|
41934
|
-
const part =
|
|
42014
|
+
const part = subshell(st);
|
|
41935
42015
|
walkNode(command, part, ctx, index > 0);
|
|
42016
|
+
runSetTraps(part, ctx);
|
|
41936
42017
|
parts.push(part);
|
|
41937
42018
|
}
|
|
41938
42019
|
if (parts.some((part) => outputChanged(before, part.output)))
|
|
@@ -41951,8 +42032,9 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
41951
42032
|
return;
|
|
41952
42033
|
case "Subshell": {
|
|
41953
42034
|
const before = st.output;
|
|
41954
|
-
const child =
|
|
42035
|
+
const child = subshell(st);
|
|
41955
42036
|
walkList(node.body.commands, child, ctx);
|
|
42037
|
+
runSetTraps(child, ctx);
|
|
41956
42038
|
if (outputChanged(before, child.output))
|
|
41957
42039
|
st.output = undefined;
|
|
41958
42040
|
return;
|
|
@@ -42041,14 +42123,21 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42041
42123
|
st.output = undefined;
|
|
42042
42124
|
return;
|
|
42043
42125
|
}
|
|
42044
|
-
case "Function":
|
|
42045
|
-
|
|
42126
|
+
case "Function": {
|
|
42127
|
+
let callee = definitions.get(node);
|
|
42128
|
+
if (callee === undefined) {
|
|
42129
|
+
callee = [{ body: node.body, source: st.source, file: st.script }];
|
|
42130
|
+
definitions.set(node, callee);
|
|
42131
|
+
}
|
|
42132
|
+
st.functions.set(node.name.value, callee);
|
|
42046
42133
|
checkRedirects(node.redirects, undefined, siteOf(node, st), st, ctx);
|
|
42047
42134
|
return;
|
|
42135
|
+
}
|
|
42048
42136
|
case "Coproc": {
|
|
42049
42137
|
const before = st.output;
|
|
42050
|
-
const child =
|
|
42138
|
+
const child = subshell(st);
|
|
42051
42139
|
walkNode(node.body, child, ctx, false);
|
|
42140
|
+
runSetTraps(child, ctx);
|
|
42052
42141
|
if (outputChanged(before, child.output))
|
|
42053
42142
|
st.output = undefined;
|
|
42054
42143
|
checkRedirects(node.redirects, undefined, siteOf(node, st), st, ctx);
|
|
@@ -42359,9 +42448,24 @@ function dispatch(invocation, outer, ctx) {
|
|
|
42359
42448
|
const base = path4.basename(name);
|
|
42360
42449
|
const rest = argv.slice(1);
|
|
42361
42450
|
const site = invocation.site;
|
|
42362
|
-
const
|
|
42363
|
-
if (
|
|
42364
|
-
|
|
42451
|
+
const callee = outer.functions.get(base);
|
|
42452
|
+
if (callee !== undefined) {
|
|
42453
|
+
const [only] = callee;
|
|
42454
|
+
if (callee.length === 1 && only !== undefined) {
|
|
42455
|
+
runFunction(base, only, rest, outer, ctx);
|
|
42456
|
+
return;
|
|
42457
|
+
}
|
|
42458
|
+
const runs = callee.map((definition) => {
|
|
42459
|
+
const run = clone2(outer);
|
|
42460
|
+
if (definition !== undefined)
|
|
42461
|
+
runFunction(base, definition, rest, run, ctx);
|
|
42462
|
+
else {
|
|
42463
|
+
run.functions.delete(base);
|
|
42464
|
+
dispatch(invocation, run, ctx);
|
|
42465
|
+
}
|
|
42466
|
+
return run;
|
|
42467
|
+
});
|
|
42468
|
+
merge2(outer, runs);
|
|
42365
42469
|
return;
|
|
42366
42470
|
}
|
|
42367
42471
|
const stdoutRedirected = invocation.redirects.some((redirect) => (redirect.fileDescriptor === undefined || redirect.fileDescriptor === 1) && [">", ">>", ">|", "&>", "&>>", ">&"].includes(redirect.operator));
|
|
@@ -42453,11 +42557,34 @@ function dispatch(invocation, outer, ctx) {
|
|
|
42453
42557
|
return;
|
|
42454
42558
|
}
|
|
42455
42559
|
case "trap": {
|
|
42456
|
-
const
|
|
42560
|
+
const [handler, ...conditions] = operands(rest, "").operands;
|
|
42561
|
+
if (handler === undefined)
|
|
42562
|
+
return;
|
|
42563
|
+
const text = literalText(handler.exp);
|
|
42564
|
+
const readable = conditions.map((arg) => literalText(arg.exp));
|
|
42565
|
+
const signals = readable.map((condition) => condition === undefined ? UNREADABLE_CONDITION : trapSignal(condition));
|
|
42566
|
+
const handled = signals.length === 0 ? ["EXIT"] : signals;
|
|
42567
|
+
const file2 = outer.script ?? outer.source;
|
|
42457
42568
|
if (text === "-") {
|
|
42458
|
-
|
|
42459
|
-
|
|
42460
|
-
|
|
42569
|
+
const named = readable.flatMap((condition) => condition === undefined ? [] : [trapSignal(condition)]);
|
|
42570
|
+
outer.traps = outer.traps.flatMap((trap) => {
|
|
42571
|
+
const signals2 = trap.signals.filter((signal) => !named.includes(signal));
|
|
42572
|
+
return signals2.length === 0 ? [] : [{ ...trap, signals: signals2 }];
|
|
42573
|
+
});
|
|
42574
|
+
} else if (text === undefined && handler.exp.every((piece) => piece.kind === "literal" || piece.descendantPid)) {
|
|
42575
|
+
const pids = new Map;
|
|
42576
|
+
const handlerText = handler.exp.map((piece) => {
|
|
42577
|
+
if (piece.kind === "literal")
|
|
42578
|
+
return piece.text;
|
|
42579
|
+
const name2 = `__legion_guard_trap_pid_${pids.size}`;
|
|
42580
|
+
pids.set(name2, [piece]);
|
|
42581
|
+
return `\${${name2}}`;
|
|
42582
|
+
}).join("");
|
|
42583
|
+
outer.traps = [...outer.traps, { text: handlerText, site, signals: handled, file: file2, pids }];
|
|
42584
|
+
} else if (text === undefined) {
|
|
42585
|
+
throw new Refusal(site.snippet, site.line, `the guard cannot read the handler this \`trap\` sets, \`${handler.text}\` (${handler.exp.find((piece) => piece.kind !== "literal")?.why ?? "a value the guard cannot know"}), so it cannot check what runs when this shell exits; write the handler out, or put it in a function`);
|
|
42586
|
+
} else if (!text.startsWith("-")) {
|
|
42587
|
+
outer.traps = [...outer.traps, { text, site, signals: handled, file: file2 }];
|
|
42461
42588
|
}
|
|
42462
42589
|
return;
|
|
42463
42590
|
}
|
|
@@ -43139,9 +43266,11 @@ function runFile(file2, positional, st, ctx, site, kind, source = false) {
|
|
|
43139
43266
|
throw new Refusal(site.snippet, site.line, "the guard stops following scripts this deep; run the inner script directly");
|
|
43140
43267
|
}
|
|
43141
43268
|
const child = { ...clone2(st), source: content, script: abs, depth: st.depth + 1 };
|
|
43142
|
-
|
|
43269
|
+
const operands2 = positional.map((arg) => arg.exp);
|
|
43270
|
+
child.positional = source && operands2.length === 0 ? st.positional : operands2;
|
|
43143
43271
|
walkScript(parse5(content), child, ctx, !source);
|
|
43144
43272
|
if (source) {
|
|
43273
|
+
st.positional = operands2.length === 0 ? child.positional : child.positional === operands2 ? st.positional : undefined;
|
|
43145
43274
|
st.vars = child.vars;
|
|
43146
43275
|
st.exported = child.exported;
|
|
43147
43276
|
st.arrays.clear();
|