@sjawhar/pi-legion-envoy 5.17.1 → 5.17.2
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 +138 -52
- 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.
|
|
33476
|
+
version: "5.17.2",
|
|
33477
33477
|
type: "module",
|
|
33478
33478
|
omp: {
|
|
33479
33479
|
extensions: [
|
|
@@ -42174,9 +42174,11 @@ function visitParts(parts, st, ctx) {
|
|
|
42174
42174
|
visitParts(part.parts, st, ctx);
|
|
42175
42175
|
break;
|
|
42176
42176
|
case "CommandExpansion":
|
|
42177
|
-
case "ProcessSubstitution":
|
|
42178
42177
|
walkSubstitution(part.script, part.inner, part.text, st, ctx);
|
|
42179
42178
|
break;
|
|
42179
|
+
case "ProcessSubstitution":
|
|
42180
|
+
uncertainly(ctx, () => walkSubstitution(part.script, part.inner, part.text, st, ctx));
|
|
42181
|
+
break;
|
|
42180
42182
|
case "ArithmeticExpansion":
|
|
42181
42183
|
visitArithmetic(part.expression, st, ctx);
|
|
42182
42184
|
break;
|
|
@@ -42396,10 +42398,47 @@ function merge2(target, branches) {
|
|
|
42396
42398
|
if (target.traps.includes(trap))
|
|
42397
42399
|
continue;
|
|
42398
42400
|
merged ??= new Map(target.vars);
|
|
42399
|
-
lifted.push({ ...trap, vars: handlerVars(trap, branch.vars), merged });
|
|
42401
|
+
lifted.push({ ...trap, vars: handlerVars(trap, branch.vars), merged, uncertainSet: true });
|
|
42400
42402
|
}
|
|
42401
42403
|
}
|
|
42402
|
-
target.traps = [
|
|
42404
|
+
target.traps = [
|
|
42405
|
+
...target.traps.map((trap) => branches.every((branch) => branch.traps.includes(trap)) ? trap : { ...trap, uncertainSet: true }),
|
|
42406
|
+
...lifted
|
|
42407
|
+
];
|
|
42408
|
+
}
|
|
42409
|
+
function uncertainly(ctx, walk) {
|
|
42410
|
+
ctx.uncertain.depth += 1;
|
|
42411
|
+
try {
|
|
42412
|
+
walk();
|
|
42413
|
+
} finally {
|
|
42414
|
+
ctx.uncertain.depth -= 1;
|
|
42415
|
+
}
|
|
42416
|
+
}
|
|
42417
|
+
function modelWrite(st, ctx, file2, content) {
|
|
42418
|
+
st.files.set(file2, ctx.uncertain.depth > 0 ? UNCERTAIN_WRITE : content);
|
|
42419
|
+
}
|
|
42420
|
+
var UNCERTAIN_WRITE = {
|
|
42421
|
+
why: "the write is inside a branch, a loop body, a handler, or a command this shell does not wait " + "for, so the guard cannot know the shell performed it"
|
|
42422
|
+
};
|
|
42423
|
+
var UNRENDERED_WRITE = {
|
|
42424
|
+
why: "the command writes output the guard cannot render"
|
|
42425
|
+
};
|
|
42426
|
+
var OVERLONG_WRITE = {
|
|
42427
|
+
why: `the command writes more than the ${MAX_SCRIPT_BYTES} bytes the guard reads of a script`
|
|
42428
|
+
};
|
|
42429
|
+
var UNREAD_FILE = {
|
|
42430
|
+
why: "the command appends to a file it has not written, whose contents on disk the guard never reads"
|
|
42431
|
+
};
|
|
42432
|
+
function modelPidFile(st, ctx, file2, pid) {
|
|
42433
|
+
const model = st.pidFiles;
|
|
42434
|
+
const before = model.get(file2);
|
|
42435
|
+
model.delete(file2);
|
|
42436
|
+
if (ctx.uncertain.depth === 0) {
|
|
42437
|
+
if (pid !== undefined)
|
|
42438
|
+
model.set(file2, pid);
|
|
42439
|
+
} else if (pid !== undefined && before !== undefined) {
|
|
42440
|
+
model.set(file2, [unknown2("a pid a branch or loop body wrote to this file", true)]);
|
|
42441
|
+
}
|
|
42403
42442
|
}
|
|
42404
42443
|
function handlerVars(trap, vars) {
|
|
42405
42444
|
const { vars: branch, merged } = trap;
|
|
@@ -42444,11 +42483,17 @@ function subshell(st, patch) {
|
|
|
42444
42483
|
function runSetTraps(st, ctx) {
|
|
42445
42484
|
for (const trap of st.traps) {
|
|
42446
42485
|
const vars = new Map([...handlerVars(trap, st.vars), ...trap.pids ?? []]);
|
|
42447
|
-
|
|
42448
|
-
|
|
42449
|
-
|
|
42450
|
-
|
|
42451
|
-
|
|
42486
|
+
const run = () => {
|
|
42487
|
+
try {
|
|
42488
|
+
runText(trap.text, "the EXIT trap", subshell(st, { source: trap.file, vars }), ctx, trap.site);
|
|
42489
|
+
} catch (error48) {
|
|
42490
|
+
locateRefusal(error48, trap.file);
|
|
42491
|
+
}
|
|
42492
|
+
};
|
|
42493
|
+
if (trap.signals.includes("EXIT") && trap.uncertainSet !== true)
|
|
42494
|
+
run();
|
|
42495
|
+
else
|
|
42496
|
+
uncertainly(ctx, run);
|
|
42452
42497
|
}
|
|
42453
42498
|
}
|
|
42454
42499
|
function walkList(statements, st, ctx) {
|
|
@@ -42459,8 +42504,10 @@ var MAX_DECIDED_PASSES = 64;
|
|
|
42459
42504
|
function walkLoopAnyPasses(node, st, ctx) {
|
|
42460
42505
|
const before = st.output;
|
|
42461
42506
|
const body = clone2(st);
|
|
42462
|
-
|
|
42463
|
-
|
|
42507
|
+
uncertainly(ctx, () => {
|
|
42508
|
+
walkList(node.clause.commands, body, ctx);
|
|
42509
|
+
walkList(node.body.commands, body, ctx);
|
|
42510
|
+
});
|
|
42464
42511
|
merge2(st, [clone2(st), body]);
|
|
42465
42512
|
if (outputChanged(before, body.output))
|
|
42466
42513
|
st.output = undefined;
|
|
@@ -42564,8 +42611,10 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42564
42611
|
if (node.background) {
|
|
42565
42612
|
const before = st.output;
|
|
42566
42613
|
const child = subshell(st);
|
|
42567
|
-
|
|
42568
|
-
|
|
42614
|
+
uncertainly(ctx, () => {
|
|
42615
|
+
walkNode(node.command, child, ctx, pipeIn);
|
|
42616
|
+
runSetTraps(child, ctx);
|
|
42617
|
+
});
|
|
42569
42618
|
if (outputChanged(before, child.output))
|
|
42570
42619
|
st.output = undefined;
|
|
42571
42620
|
st.backgroundStarted = true;
|
|
@@ -42574,7 +42623,7 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42574
42623
|
if (node.command.type === "BraceGroup") {
|
|
42575
42624
|
const written = groupOutputFile(node, st, ctx);
|
|
42576
42625
|
if (written !== undefined) {
|
|
42577
|
-
st
|
|
42626
|
+
modelWrite(st, ctx, written, walkRenderingGroup(node.command, st, ctx) ?? UNRENDERED_WRITE);
|
|
42578
42627
|
return;
|
|
42579
42628
|
}
|
|
42580
42629
|
}
|
|
@@ -42592,20 +42641,38 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42592
42641
|
}
|
|
42593
42642
|
const before = st.output;
|
|
42594
42643
|
const parts = [];
|
|
42595
|
-
|
|
42596
|
-
const
|
|
42597
|
-
|
|
42598
|
-
|
|
42599
|
-
|
|
42600
|
-
|
|
42644
|
+
uncertainly(ctx, () => {
|
|
42645
|
+
for (const [index, command] of node.commands.entries()) {
|
|
42646
|
+
const part = subshell(st);
|
|
42647
|
+
walkNode(command, part, ctx, index > 0);
|
|
42648
|
+
runSetTraps(part, ctx);
|
|
42649
|
+
parts.push(part);
|
|
42650
|
+
}
|
|
42651
|
+
});
|
|
42601
42652
|
if (parts.some((part) => outputChanged(before, part.output)))
|
|
42602
42653
|
st.output = undefined;
|
|
42603
42654
|
return;
|
|
42604
42655
|
}
|
|
42605
|
-
case "AndOr":
|
|
42606
|
-
|
|
42607
|
-
|
|
42656
|
+
case "AndOr": {
|
|
42657
|
+
const [first, ...rest] = node.commands;
|
|
42658
|
+
if (first !== undefined)
|
|
42659
|
+
walkNode(first, st, ctx, pipeIn);
|
|
42660
|
+
if (rest.length === 0)
|
|
42661
|
+
return;
|
|
42662
|
+
const before = st.output;
|
|
42663
|
+
const branches = [clone2(st)];
|
|
42664
|
+
const running = clone2(st);
|
|
42665
|
+
uncertainly(ctx, () => {
|
|
42666
|
+
for (const command of rest) {
|
|
42667
|
+
walkNode(command, running, ctx, pipeIn);
|
|
42668
|
+
branches.push(clone2(running));
|
|
42669
|
+
}
|
|
42670
|
+
});
|
|
42671
|
+
merge2(st, branches);
|
|
42672
|
+
if (branches.some((branch) => outputChanged(before, branch.output)))
|
|
42673
|
+
st.output = undefined;
|
|
42608
42674
|
return;
|
|
42675
|
+
}
|
|
42609
42676
|
case "CompoundList":
|
|
42610
42677
|
walkList(node.commands, st, ctx);
|
|
42611
42678
|
return;
|
|
@@ -42626,10 +42693,12 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42626
42693
|
walkList(node.clause.commands, st, ctx);
|
|
42627
42694
|
const clauseOutput = st.output;
|
|
42628
42695
|
const then = clone2(st);
|
|
42629
|
-
walkList(node.then.commands, then, ctx);
|
|
42630
42696
|
const otherwise = clone2(st);
|
|
42631
|
-
|
|
42632
|
-
|
|
42697
|
+
uncertainly(ctx, () => {
|
|
42698
|
+
walkList(node.then.commands, then, ctx);
|
|
42699
|
+
if (node.else !== undefined)
|
|
42700
|
+
walkNode(node.else, otherwise, ctx, pipeIn);
|
|
42701
|
+
});
|
|
42633
42702
|
merge2(st, [then, otherwise]);
|
|
42634
42703
|
if (outputChanged(before, clauseOutput) || outputChanged(clauseOutput, then.output) || outputChanged(clauseOutput, otherwise.output)) {
|
|
42635
42704
|
st.output = undefined;
|
|
@@ -42649,7 +42718,7 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42649
42718
|
for (const value of known) {
|
|
42650
42719
|
const body = clone2(st);
|
|
42651
42720
|
assignScalar(body, name, [literal2(value)]);
|
|
42652
|
-
walkList(node.body.commands, body, ctx);
|
|
42721
|
+
uncertainly(ctx, () => walkList(node.body.commands, body, ctx));
|
|
42653
42722
|
branches.push(body);
|
|
42654
42723
|
}
|
|
42655
42724
|
} else {
|
|
@@ -42661,7 +42730,7 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42661
42730
|
assignScalar(body, name, signalSafe ? [unknown2(`\`$${name}\`, a loop variable`, true)] : [unknown2(`\`$${name}\`, a loop variable`)]);
|
|
42662
42731
|
if (node.type === "Select")
|
|
42663
42732
|
assignScalar(body, "REPLY", [unknown2("`$REPLY`, read from input")]);
|
|
42664
|
-
walkList(node.body.commands, body, ctx);
|
|
42733
|
+
uncertainly(ctx, () => walkList(node.body.commands, body, ctx));
|
|
42665
42734
|
branches.push(body);
|
|
42666
42735
|
}
|
|
42667
42736
|
merge2(st, branches);
|
|
@@ -42675,7 +42744,7 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42675
42744
|
visitArithmetic(node.test, st, ctx);
|
|
42676
42745
|
visitArithmetic(node.update, st, ctx);
|
|
42677
42746
|
const body = clone2(st);
|
|
42678
|
-
walkList(node.body.commands, body, ctx);
|
|
42747
|
+
uncertainly(ctx, () => walkList(node.body.commands, body, ctx));
|
|
42679
42748
|
merge2(st, [clone2(st), body]);
|
|
42680
42749
|
if (outputChanged(before, body.output))
|
|
42681
42750
|
st.output = undefined;
|
|
@@ -42702,7 +42771,7 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42702
42771
|
for (const word of item.pattern)
|
|
42703
42772
|
visitWord(word, st, ctx);
|
|
42704
42773
|
const body = clone2(st);
|
|
42705
|
-
walkList(item.body.commands, body, ctx);
|
|
42774
|
+
uncertainly(ctx, () => walkList(item.body.commands, body, ctx));
|
|
42706
42775
|
branches.push(body);
|
|
42707
42776
|
}
|
|
42708
42777
|
merge2(st, branches);
|
|
@@ -42723,8 +42792,10 @@ function walkNode(node, st, ctx, pipeIn) {
|
|
|
42723
42792
|
case "Coproc": {
|
|
42724
42793
|
const before = st.output;
|
|
42725
42794
|
const child = subshell(st);
|
|
42726
|
-
|
|
42727
|
-
|
|
42795
|
+
uncertainly(ctx, () => {
|
|
42796
|
+
walkNode(node.body, child, ctx, false);
|
|
42797
|
+
runSetTraps(child, ctx);
|
|
42798
|
+
});
|
|
42728
42799
|
if (outputChanged(before, child.output))
|
|
42729
42800
|
st.output = undefined;
|
|
42730
42801
|
checkRedirects(node.redirects, undefined, siteOf(node, st), st, ctx);
|
|
@@ -42773,12 +42844,10 @@ function checkRedirects(redirects, command, site, st, ctx) {
|
|
|
42773
42844
|
} else if (command?.name === "printf") {
|
|
42774
42845
|
content = printfText(command.args, MAX_SCRIPT_BYTES, true) ?? null;
|
|
42775
42846
|
}
|
|
42776
|
-
st.
|
|
42777
|
-
|
|
42778
|
-
|
|
42779
|
-
|
|
42780
|
-
st.pidFiles.set(file2, command.args[0].exp);
|
|
42781
|
-
}
|
|
42847
|
+
const before = appends ? st.files.get(file2) ?? UNREAD_FILE : "";
|
|
42848
|
+
modelWrite(st, ctx, file2, content === null ? UNRENDERED_WRITE : typeof before !== "string" ? before : readable(`${before}${content}`) ?? OVERLONG_WRITE);
|
|
42849
|
+
const pidWritten = writes && !appends && command?.name === "echo" && command.args.length === 1 && command.args[0]?.exp.length > 0 && command.args[0].exp.every((piece) => piece.descendantPid);
|
|
42850
|
+
modelPidFile(st, ctx, file2, pidWritten ? command?.args[0]?.exp : undefined);
|
|
42782
42851
|
}
|
|
42783
42852
|
}
|
|
42784
42853
|
}
|
|
@@ -43222,15 +43291,18 @@ function dispatch(invocation, outer, ctx) {
|
|
|
43222
43291
|
runFunction(base, only, rest, outer, ctx);
|
|
43223
43292
|
return;
|
|
43224
43293
|
}
|
|
43225
|
-
const runs =
|
|
43226
|
-
|
|
43227
|
-
|
|
43228
|
-
|
|
43229
|
-
|
|
43230
|
-
|
|
43231
|
-
|
|
43294
|
+
const runs = [];
|
|
43295
|
+
uncertainly(ctx, () => {
|
|
43296
|
+
for (const definition of callee) {
|
|
43297
|
+
const run = clone2(outer);
|
|
43298
|
+
if (definition !== undefined)
|
|
43299
|
+
runFunction(base, definition, rest, run, ctx);
|
|
43300
|
+
else {
|
|
43301
|
+
run.functions.delete(base);
|
|
43302
|
+
dispatch(invocation, run, ctx);
|
|
43303
|
+
}
|
|
43304
|
+
runs.push(run);
|
|
43232
43305
|
}
|
|
43233
|
-
return run;
|
|
43234
43306
|
});
|
|
43235
43307
|
merge2(outer, runs);
|
|
43236
43308
|
return;
|
|
@@ -43410,11 +43482,24 @@ function dispatch(invocation, outer, ctx) {
|
|
|
43410
43482
|
pids.set(name2, [piece]);
|
|
43411
43483
|
return `\${${name2}}`;
|
|
43412
43484
|
}).join("");
|
|
43413
|
-
outer.traps = [
|
|
43485
|
+
outer.traps = [
|
|
43486
|
+
...outer.traps,
|
|
43487
|
+
{
|
|
43488
|
+
text: handlerText,
|
|
43489
|
+
site,
|
|
43490
|
+
signals: handled,
|
|
43491
|
+
file: file2,
|
|
43492
|
+
pids,
|
|
43493
|
+
uncertainSet: ctx.uncertain.depth > 0
|
|
43494
|
+
}
|
|
43495
|
+
];
|
|
43414
43496
|
} else if (text === undefined) {
|
|
43415
43497
|
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`);
|
|
43416
43498
|
} else if (!text.startsWith("-")) {
|
|
43417
|
-
outer.traps = [
|
|
43499
|
+
outer.traps = [
|
|
43500
|
+
...outer.traps,
|
|
43501
|
+
{ text, site, signals: handled, file: file2, uncertainSet: ctx.uncertain.depth > 0 }
|
|
43502
|
+
];
|
|
43418
43503
|
}
|
|
43419
43504
|
return;
|
|
43420
43505
|
}
|
|
@@ -43530,7 +43615,7 @@ function dispatch(invocation, outer, ctx) {
|
|
|
43530
43615
|
const file2 = path4.resolve(st.cwd, target);
|
|
43531
43616
|
st.pidFiles.delete(file2);
|
|
43532
43617
|
const text = heredoc === undefined ? null : heredocText(heredoc);
|
|
43533
|
-
st
|
|
43618
|
+
modelWrite(st, ctx, file2, append ? UNREAD_FILE : text === null ? UNRENDERED_WRITE : readable(text) ?? OVERLONG_WRITE);
|
|
43534
43619
|
}
|
|
43535
43620
|
}
|
|
43536
43621
|
return;
|
|
@@ -44195,8 +44280,8 @@ function runFile(file2, positional, st, ctx, site, kind, source = false) {
|
|
|
44195
44280
|
let content;
|
|
44196
44281
|
if (st.files.has(abs)) {
|
|
44197
44282
|
const written = st.files.get(abs);
|
|
44198
|
-
if (written ===
|
|
44199
|
-
throw new Refusal(site.snippet, site.line, `this command
|
|
44283
|
+
if (written === undefined || typeof written !== "string") {
|
|
44284
|
+
throw new Refusal(site.snippet, site.line, `this command may write ${abs} in a way the guard cannot read before running it (${written?.why ?? "the guard cannot say what it holds"}); write the script with the write tool first`);
|
|
44200
44285
|
}
|
|
44201
44286
|
content = written;
|
|
44202
44287
|
} else {
|
|
@@ -44389,7 +44474,8 @@ function createPaneGuard(options) {
|
|
|
44389
44474
|
env,
|
|
44390
44475
|
ompPid: options.ompPid,
|
|
44391
44476
|
parentOf: options.parentOf ?? procParent,
|
|
44392
|
-
steps: { count: 0 }
|
|
44477
|
+
steps: { count: 0 },
|
|
44478
|
+
uncertain: { depth: 0 }
|
|
44393
44479
|
});
|
|
44394
44480
|
const initial = (cwd, source) => ({
|
|
44395
44481
|
vars: new Map,
|