@poe-platform/safe-bash 0.1.755 → 0.1.757

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 (131) hide show
  1. package/dist/image-ast/index.browser.js +30 -6
  2. package/dist/image-ast/index.js +30 -6
  3. package/dist/pdf-ast/canvas.d.ts +1 -0
  4. package/dist/pdf-ast/index.js +26 -2
  5. package/dist/safe-bash/chunks/{chunk-LESPJ3OG.js → chunk-WNWIBBJZ.js} +15 -2
  6. package/dist/safe-bash/command-chunks/{chunk-S4J6MSLY.js → chunk-444OTXM7.js} +3 -3
  7. package/dist/safe-bash/command-chunks/{chunk-6AIOGLZO.js → chunk-CE6Z2ULX.js} +2 -2
  8. package/dist/safe-bash/command-chunks/{chunk-5VSGEE6J.js → chunk-F4IQCXZG.js} +5 -5
  9. package/dist/safe-bash/command-chunks/{chunk-F5MORDSU.js → chunk-FDNCPZQS.js} +32 -1
  10. package/dist/safe-bash/command-chunks/{chunk-SG3ZDZCX.js → chunk-FLMLM7Y4.js} +2 -2
  11. package/dist/safe-bash/command-chunks/{chunk-XRVNFK7Z.js → chunk-H2FQA4OU.js} +26 -2
  12. package/dist/safe-bash/command-chunks/{chunk-CT3FB722.js → chunk-J7UMKBRK.js} +1 -1
  13. package/dist/safe-bash/command-chunks/{chunk-KB2LQ4HG.js → chunk-KBBI4CSU.js} +2 -2
  14. package/dist/safe-bash/command-chunks/{chunk-QQOAK7JQ.js → chunk-KKJCKPTA.js} +1 -1
  15. package/dist/safe-bash/command-chunks/{chunk-7KS6PX4U.js → chunk-KSIGF4AG.js} +3 -3
  16. package/dist/safe-bash/command-chunks/{chunk-4HQ7WYSI.js → chunk-MED2BOOW.js} +30 -5
  17. package/dist/safe-bash/command-chunks/{chunk-JRNLDPLI.js → chunk-OZSWW23M.js} +1 -1
  18. package/dist/safe-bash/command-chunks/{chunk-DKQ5REXF.js → chunk-QDPRSPHQ.js} +1 -1
  19. package/dist/safe-bash/command-chunks/{chunk-WOPU2VWF.js → chunk-RID3B5RE.js} +1 -1
  20. package/dist/safe-bash/command-chunks/{chunk-DVZCHNB5.js → chunk-S4MLIYSN.js} +7 -7
  21. package/dist/safe-bash/command-chunks/{chunk-REYTQLLB.js → chunk-TT2DMDBY.js} +1 -1
  22. package/dist/safe-bash/command-chunks/{chunk-UGX6MXDD.js → chunk-UIIT4ULR.js} +3 -3
  23. package/dist/safe-bash/command-chunks/{chunk-MENC7RPR.js → chunk-WI35236J.js} +1 -1
  24. package/dist/safe-bash/command-chunks/{chunk-A6NFLWZI.js → chunk-WKPOGTZY.js} +22 -6
  25. package/dist/safe-bash/command-chunks/{chunk-3DOHQQJR.js → chunk-Y64PA6IA.js} +8 -8
  26. package/dist/safe-bash/command-chunks/{chunk-6Z7OS3TZ.js → chunk-ZP5KDHB4.js} +7 -7
  27. package/dist/safe-bash/commands/pandoc/index.d.ts +1 -1
  28. package/dist/safe-bash/commands/pandoc/index.js +5 -3
  29. package/dist/safe-bash/commands/python/index.browser.js +1 -1
  30. package/dist/safe-bash/commands/python/index.js +6 -0
  31. package/dist/safe-bash/commands/python/jspi.js +11 -2
  32. package/dist/safe-bash/core.browser.js +6 -4
  33. package/dist/safe-bash-command-csvkit/index.js +8 -8
  34. package/dist/safe-bash-command-ffmpeg/index.js +20 -2
  35. package/dist/safe-bash-command-imagemagick/index.js +2 -2
  36. package/dist/safe-bash-command-pandoc/command.js +3 -3
  37. package/dist/safe-bash-command-pandoc/index.js +3 -3
  38. package/dist/safe-bash-command-pdfimages/index.js +26 -2
  39. package/dist/safe-bash-command-pdfinfo/index.js +26 -2
  40. package/dist/safe-bash-command-pdftk/index.js +26 -2
  41. package/dist/safe-bash-command-pdftoppm/index.js +26 -2
  42. package/dist/safe-bash-command-pdftotext/index.js +26 -2
  43. package/dist/safe-bash-command-qpdf/index.js +26 -2
  44. package/dist/safe-bash-command-sips/index.js +2 -2
  45. package/dist/safe-bash-command-soffice/index.js +17 -17
  46. package/dist/safe-bash-command-ssconvert/core.js +8 -8
  47. package/dist/safe-bash-command-ssconvert/formats/csv.js +9 -9
  48. package/dist/safe-bash-command-ssconvert/formats/ods.js +8 -8
  49. package/dist/safe-bash-command-ssconvert/formats/spreadsheetml.js +1 -1
  50. package/dist/safe-bash-command-ssconvert/formats/xls.js +9 -8
  51. package/dist/safe-bash-command-ssconvert/formats/xlsx.js +8 -8
  52. package/dist/safe-bash-command-ssconvert/index.js +133 -29
  53. package/dist/safe-bash-command-wkhtmltopdf/index.js +26 -2
  54. package/dist/safe-bash-contracts/filesystem-descriptor.js +1 -1
  55. package/dist/safe-bash-contracts/filesystem-output.js +1 -1
  56. package/dist/safe-bash-mcp/index.js +4 -4
  57. package/dist/spreadsheet-engine/formulas/ast.d.ts +13 -0
  58. package/dist/spreadsheet-engine/formulas/conventions.js +1 -1
  59. package/dist/spreadsheet-engine/formulas/dependencies.js +2 -2
  60. package/dist/spreadsheet-engine/formulas/evaluator.js +2 -2
  61. package/dist/spreadsheet-engine/formulas/named-expressions.d.ts +2 -2
  62. package/dist/spreadsheet-engine/formulas/named-expressions.js +31 -5
  63. package/dist/spreadsheet-engine/formulas/parser.js +34 -0
  64. package/dist/spreadsheet-engine/formulas/rewriting.js +19 -1
  65. package/dist/spreadsheet-engine/formulas/serialization.js +6 -0
  66. package/dist/spreadsheet-format-xls/biff-write-formulas.js +2 -0
  67. package/dist/xlsx-ast/formula-semantics.js +2 -0
  68. package/package.json +2 -2
  69. package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +1 -1
  70. package/dist/safe-bash/chunks/browser-ECQX6GMK.js +0 -6766
  71. package/dist/safe-bash/chunks/bz2-4OP3OWW3.js +0 -8
  72. package/dist/safe-bash/chunks/chunk-22XPAAOI.js +0 -173
  73. package/dist/safe-bash/chunks/chunk-44WUNUPV.js +0 -649
  74. package/dist/safe-bash/chunks/chunk-4E3SGG37.js +0 -876
  75. package/dist/safe-bash/chunks/chunk-4QTSSQKP.js +0 -898
  76. package/dist/safe-bash/chunks/chunk-5UVGPVXP.js +0 -410
  77. package/dist/safe-bash/chunks/chunk-64OE6Q6X.js +0 -3487
  78. package/dist/safe-bash/chunks/chunk-6IIFUPN2.js +0 -1526
  79. package/dist/safe-bash/chunks/chunk-6XDKK63A.js +0 -38959
  80. package/dist/safe-bash/chunks/chunk-BENDLTQD.js +0 -7065
  81. package/dist/safe-bash/chunks/chunk-BMO5LWEX.js +0 -534
  82. package/dist/safe-bash/chunks/chunk-BPMCPTNP.js +0 -1920
  83. package/dist/safe-bash/chunks/chunk-BRJTAWP5.js +0 -2955
  84. package/dist/safe-bash/chunks/chunk-C3GEIN7Q.js +0 -20054
  85. package/dist/safe-bash/chunks/chunk-CEWCRI6H.js +0 -2813
  86. package/dist/safe-bash/chunks/chunk-CGL53DQQ.js +0 -37
  87. package/dist/safe-bash/chunks/chunk-CTYJJD4O.js +0 -869
  88. package/dist/safe-bash/chunks/chunk-CWSS4MQA.js +0 -7
  89. package/dist/safe-bash/chunks/chunk-DLIGMTCP.js +0 -3266
  90. package/dist/safe-bash/chunks/chunk-EMAJ7WUW.js +0 -1031
  91. package/dist/safe-bash/chunks/chunk-FDKIZ2IJ.js +0 -1950
  92. package/dist/safe-bash/chunks/chunk-FZWJ2A7V.js +0 -3093
  93. package/dist/safe-bash/chunks/chunk-G2VCIF2J.js +0 -22
  94. package/dist/safe-bash/chunks/chunk-GVKBUQDX.js +0 -2649
  95. package/dist/safe-bash/chunks/chunk-IO2OGW3E.js +0 -28051
  96. package/dist/safe-bash/chunks/chunk-ISCZG7WA.js +0 -2648
  97. package/dist/safe-bash/chunks/chunk-JEFBTRY7.js +0 -174814
  98. package/dist/safe-bash/chunks/chunk-KJHDD4A2.js +0 -759
  99. package/dist/safe-bash/chunks/chunk-LB6HVRXS.js +0 -857
  100. package/dist/safe-bash/chunks/chunk-LLWAJOZH.js +0 -15
  101. package/dist/safe-bash/chunks/chunk-LMUKYZIJ.js +0 -708
  102. package/dist/safe-bash/chunks/chunk-M5SCNKIK.js +0 -2012
  103. package/dist/safe-bash/chunks/chunk-MJPFHANT.js +0 -3350
  104. package/dist/safe-bash/chunks/chunk-MZQW2DOL.js +0 -82
  105. package/dist/safe-bash/chunks/chunk-NB2V7EOY.js +0 -1348
  106. package/dist/safe-bash/chunks/chunk-NJVGOIYN.js +0 -17
  107. package/dist/safe-bash/chunks/chunk-OLNZHDIQ.js +0 -5141
  108. package/dist/safe-bash/chunks/chunk-OUUVROTM.js +0 -38
  109. package/dist/safe-bash/chunks/chunk-PA6GYKBQ.js +0 -151
  110. package/dist/safe-bash/chunks/chunk-PEFHZ226.js +0 -6957
  111. package/dist/safe-bash/chunks/chunk-QBB5P5KW.js +0 -4839
  112. package/dist/safe-bash/chunks/chunk-QHB7HBLA.js +0 -2317
  113. package/dist/safe-bash/chunks/chunk-RSAWYAEH.js +0 -973
  114. package/dist/safe-bash/chunks/chunk-UWLYRWT4.js +0 -739
  115. package/dist/safe-bash/chunks/chunk-V463NBQH.js +0 -13
  116. package/dist/safe-bash/chunks/chunk-WPUALYUS.js +0 -843
  117. package/dist/safe-bash/chunks/chunk-XHKFSRGU.js +0 -5747
  118. package/dist/safe-bash/chunks/chunk-XHRCLZ3N.js +0 -13391
  119. package/dist/safe-bash/chunks/chunk-XPF5XHLY.js +0 -15
  120. package/dist/safe-bash/chunks/chunk-ZBFOWARG.js +0 -305
  121. package/dist/safe-bash/chunks/chunk-ZG7GWQ5P.js +0 -1859
  122. package/dist/safe-bash/chunks/model-store-EIY3ZQLZ.js +0 -10
  123. package/dist/safe-bash/chunks/pdf-renderer-XIFUTX34.js +0 -22
  124. package/dist/safe-bash/chunks/pptx-ZL6L7KP2-O425BFIU.js +0 -30658
  125. package/dist/safe-bash/chunks/src-HHEPGR7U.js +0 -18969
  126. package/dist/safe-bash/chunks/src-V4VCM5OX.js +0 -187
  127. package/dist/safe-bash/chunks/usage-6TGVA2OM.js +0 -35
  128. package/dist/safe-bash/chunks/xz-EGQGQUEI.js +0 -8
  129. package/dist/safe-bash/chunks/xz-K2E2WLM6.js +0 -9
  130. package/dist/safe-bash/chunks/zstd-6JBLP5EF.js +0 -8
  131. package/dist/safe-bash/git_rust-C3QYOAZL.wasm +0 -0
@@ -1,857 +0,0 @@
1
- import {
2
- value_exports
3
- } from "./chunk-CGL53DQQ.js";
4
- import {
5
- command_exports,
6
- io_exports
7
- } from "./chunk-G2VCIF2J.js";
8
- import {
9
- init_platform
10
- } from "./chunk-ZG7GWQ5P.js";
11
-
12
- // packages/safe-bash-command-timeout/src/signal.ts
13
- init_platform();
14
- var signalNames = ["HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE", "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", "STKFLT", "CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "URG", "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "IO", "PWR", "SYS"];
15
- function signalName(number) {
16
- return signalNames[number - 1] ?? String(number);
17
- }
18
- function parseSignal(value) {
19
- let name = value.toUpperCase();
20
- if (name.startsWith("SIG")) name = name.slice(3);
21
- if (name === "EXIT") return 0;
22
- if (name.length > 0 && [...name].every((character) => character >= "0" && character <= "9")) {
23
- const number = Number(name);
24
- return number <= 64 ? number : void 0;
25
- }
26
- if (name === "IOT") name = "ABRT";
27
- if (name === "CLD") name = "CHLD";
28
- if (name === "POLL") name = "IO";
29
- const index = signalNames.indexOf(name);
30
- if (index >= 0) return index + 1;
31
- for (const [prefix, base, direction] of [["RTMIN", 34, 1], ["RTMAX", 64, -1]]) {
32
- if (name === prefix) return base;
33
- const separator = direction === 1 ? "+" : "-";
34
- if (name.startsWith(prefix + separator)) {
35
- const offset = name.slice(prefix.length + 1);
36
- if (offset.length > 0 && [...offset].every((character) => character >= "0" && character <= "9")) {
37
- const number = base + direction * Number(offset);
38
- if (number >= 34 && number <= 64) return number;
39
- }
40
- }
41
- }
42
- return void 0;
43
- }
44
-
45
- // packages/safe-bash/src/shell/extensions/jobs/index.ts
46
- init_platform();
47
-
48
- // packages/safe-bash/src/shell/extensions/jobs/state.ts
49
- init_platform();
50
- var JobRegistry = class {
51
- constructor(limits, options) {
52
- this.limits = limits;
53
- this.#owner = options.signal;
54
- this.#abortOwner = () => {
55
- void this.close(this.#owner.reason).catch(() => {
56
- });
57
- };
58
- options.registerCleanup?.(() => this.#terminal ?? this.close());
59
- if (this.#owner?.aborted) this.#abortOwner();
60
- else this.#owner?.addEventListener("abort", this.#abortOwner, { once: true });
61
- }
62
- limits;
63
- #records = /* @__PURE__ */ new Map();
64
- #jobs = /* @__PURE__ */ new Map();
65
- #listeners = /* @__PURE__ */ new Set();
66
- #owner;
67
- #abortOwner;
68
- #accepting = true;
69
- #cancelling = false;
70
- #finished = false;
71
- #waiters = 0;
72
- #terminal;
73
- async start(prepare) {
74
- this.#owner?.throwIfAborted();
75
- if (!this.#accepting) throw new Error("job state is closed to admission");
76
- if (typeof prepare !== "function") throw new TypeError("job preparation must be a function");
77
- if (this.#records.size >= this.limits.maxJobs) throw new Error("job limit exceeded: maxJobs");
78
- const occupied = [...this.#records.values()].filter((record2) => record2.state === "preparing" || record2.listed && !this.#canRetire(record2));
79
- const jobId = Math.max(0, ...occupied.map((record2) => record2.handle.jobId)) + 1;
80
- if (!Number.isSafeInteger(jobId)) throw new Error("job ID exhausted");
81
- let complete;
82
- const completion = new Promise((resolve) => {
83
- complete = resolve;
84
- });
85
- const handle = Object.freeze({ jobId, completion });
86
- const record = {
87
- handle,
88
- complete,
89
- controller: new AbortController(),
90
- cleanups: [],
91
- cleanupFailures: [],
92
- listed: false,
93
- notified: false,
94
- saved: false,
95
- state: "preparing"
96
- };
97
- this.#records.set(handle, record);
98
- this.#notify();
99
- const context = Object.freeze({
100
- signal: record.controller.signal,
101
- registerCleanup: (cleanup) => {
102
- if (record.cleaning || record.controller.signal.aborted || record.state === "done") throw new Error("job cleanup admission is closed");
103
- if (typeof cleanup !== "function") throw new TypeError("job cleanup must be a function");
104
- if (record.cleanups.length >= this.limits.maxCleanupsPerJob) throw new Error("job limit exceeded: maxCleanupsPerJob");
105
- record.cleanups.push(cleanup);
106
- }
107
- });
108
- let run;
109
- let failure;
110
- try {
111
- const prepared = await prepare(context);
112
- if (!record.controller.signal.aborted) {
113
- const runner = prepared?.run;
114
- if (typeof runner !== "function") throw new TypeError("job preparation must return a runner");
115
- run = () => Reflect.apply(runner, prepared, []);
116
- }
117
- } catch (reason) {
118
- failure = { reason };
119
- }
120
- if (failure || record.controller.signal.aborted) {
121
- await this.#settle(record, failure);
122
- this.#forget(record);
123
- throw record.outcome.reason;
124
- }
125
- this.retireNotified();
126
- record.listed = true;
127
- this.#jobs.set(jobId, record);
128
- this.#notify();
129
- queueMicrotask(() => {
130
- void this.#execute(record, run);
131
- });
132
- return handle;
133
- }
134
- async #execute(record, run) {
135
- let result = 0;
136
- let failure;
137
- if (!record.controller.signal.aborted) {
138
- record.state = "running";
139
- this.#notify();
140
- try {
141
- result = await run();
142
- if (!Number.isInteger(result) || result < 0 || result > 255) throw new TypeError("job exit status must be an integer from 0 to 255");
143
- } catch (reason) {
144
- failure = { reason };
145
- }
146
- }
147
- await this.#settle(record, failure, result);
148
- }
149
- #clean(record) {
150
- if (!record.cleaning) {
151
- record.cleaning = Promise.resolve().then(async () => {
152
- const results = await Promise.allSettled(record.cleanups.map(async (cleanup) => cleanup()));
153
- for (const result of results) if (result.status === "rejected") record.cleanupFailures.push(result.reason);
154
- record.cleanups.length = 0;
155
- });
156
- }
157
- return record.cleaning;
158
- }
159
- async #settle(record, failure, result = 0) {
160
- await this.#clean(record);
161
- let outcome;
162
- if (this.#owner?.aborted) outcome = { kind: "failure", reason: this.#owner.reason };
163
- else if (record.terminationStatus !== void 0 && (!failure || failure.reason === record.controller.signal.reason)) {
164
- outcome = record.cleanupFailures.length ? { kind: "failure", reason: record.cleanupFailures[0] } : { kind: "status", status: record.terminationStatus };
165
- } else if (failure) outcome = { kind: "failure", reason: failure.reason };
166
- else if (record.controller.signal.aborted) outcome = { kind: "failure", reason: record.controller.signal.reason };
167
- else if (record.cleanupFailures.length) outcome = { kind: "failure", reason: record.cleanupFailures[0] };
168
- else outcome = { kind: "status", status: result };
169
- record.outcome = Object.freeze(outcome);
170
- record.state = "done";
171
- record.complete(record.outcome);
172
- this.#notify();
173
- }
174
- #unlist(record) {
175
- record.listed = false;
176
- if (this.#jobs.get(record.handle.jobId) === record) this.#jobs.delete(record.handle.jobId);
177
- }
178
- #forget(record) {
179
- this.#unlist(record);
180
- this.#records.delete(record.handle);
181
- this.#notify();
182
- }
183
- #notify() {
184
- for (const listener of [...this.#listeners]) listener();
185
- }
186
- snapshot() {
187
- return Object.freeze([...this.#records.values()].map((record) => Object.freeze({
188
- handle: record.handle,
189
- listed: record.listed,
190
- notified: record.notified,
191
- state: record.state,
192
- residency: record.saved ? "saved" : record.notified ? "active-notified" : "active-unnotified",
193
- ...record.outcome === void 0 ? {} : { outcome: record.outcome }
194
- })));
195
- }
196
- #canRetire(record) {
197
- return !record.saved && record.state === "done" && record.notified && record.outcome?.kind === "status";
198
- }
199
- retireNotified() {
200
- let changed = false;
201
- for (const record of this.#records.values()) {
202
- if (this.#canRetire(record)) {
203
- record.saved = true;
204
- this.#unlist(record);
205
- changed = true;
206
- }
207
- }
208
- if (changed) this.#notify();
209
- }
210
- savedStatus(handle) {
211
- const record = this.#records.get(handle);
212
- return record?.saved && record.outcome?.kind === "status" ? record.outcome.status : void 0;
213
- }
214
- disown(handle) {
215
- const record = this.#records.get(handle);
216
- if (!record || !record.listed) return false;
217
- this.#unlist(record);
218
- record.saved = true;
219
- this.#notify();
220
- return true;
221
- }
222
- signal(handle, signal) {
223
- if (!Number.isInteger(signal) || signal < 0 || signal > 31) throw new TypeError("invalid job signal");
224
- const record = this.#records.get(handle);
225
- if (!record || record.state === "done") return false;
226
- if (signal !== 0) {
227
- record.terminationStatus ??= 128 + signal;
228
- record.controller.abort(new Error(`Job terminated by signal ${signal}`));
229
- }
230
- return true;
231
- }
232
- #targets(targets) {
233
- if (targets === void 0) return void 0;
234
- if (!Array.isArray(targets)) throw new TypeError("job targets must be an array");
235
- if (targets.length === 0) return void 0;
236
- if (targets.length > this.limits.maxJobs) throw new Error("job target limit exceeded");
237
- const selected = [];
238
- for (let index = 0; index < targets.length; index++) {
239
- const target = targets[index];
240
- if (!target || typeof target !== "object" || Reflect.ownKeys(target).length !== 1) throw new TypeError("invalid job target");
241
- if ("jobId" in target && Number.isSafeInteger(target.jobId) && target.jobId > 0) selected.push(Object.freeze({ jobId: target.jobId }));
242
- else if ("handle" in target && target.handle && typeof target.handle === "object") selected.push(Object.freeze({ handle: target.handle }));
243
- else throw new TypeError("invalid job target");
244
- }
245
- return selected;
246
- }
247
- #lookup(target) {
248
- return "handle" in target ? this.#records.get(target.handle) : this.#jobs.get(target.jobId);
249
- }
250
- #waitSignal(options) {
251
- if (!options || typeof options !== "object" || Reflect.ownKeys(options).some((key) => key !== "signal")) throw new TypeError("invalid job wait options");
252
- if (options.signal !== void 0 && !(options.signal instanceof AbortSignal)) throw new TypeError("invalid job wait signal");
253
- options.signal?.throwIfAborted();
254
- return options.signal;
255
- }
256
- #changed(signal) {
257
- return new Promise((resolve, reject) => {
258
- const cleanup = () => {
259
- this.#listeners.delete(changed);
260
- signal?.removeEventListener("abort", aborted);
261
- };
262
- const changed = () => {
263
- cleanup();
264
- resolve();
265
- };
266
- const aborted = () => {
267
- cleanup();
268
- reject(signal.reason);
269
- };
270
- this.#listeners.add(changed);
271
- if (signal?.aborted) aborted();
272
- else signal?.addEventListener("abort", aborted, { once: true });
273
- });
274
- }
275
- async wait(targets, options = {}) {
276
- const selected = this.#targets(targets);
277
- const signal = this.#waitSignal(options);
278
- if (this.#waiters >= this.limits.maxWaiters) throw new Error("job limit exceeded: maxWaiters");
279
- this.#waiters++;
280
- const unknown = [];
281
- let outcome = Object.freeze({ kind: "status", status: 0 });
282
- let failure;
283
- try {
284
- if (selected === void 0) {
285
- const records = [...this.#records.values()];
286
- for (const record of records) {
287
- while (record.state !== "done") {
288
- signal?.throwIfAborted();
289
- await this.#changed(signal);
290
- }
291
- if (record.outcome.kind === "failure") failure ??= record.outcome;
292
- }
293
- signal?.throwIfAborted();
294
- for (const record of records) this.#forget(record);
295
- } else for (const target of selected) {
296
- signal?.throwIfAborted();
297
- const record = this.#lookup(target);
298
- if (!record) {
299
- unknown.push(target);
300
- outcome = Object.freeze({ kind: "status", status: 127 });
301
- continue;
302
- }
303
- while (record.state !== "done") {
304
- signal?.throwIfAborted();
305
- await this.#changed(signal);
306
- }
307
- signal?.throwIfAborted();
308
- if (!record.saved) this.retireNotified();
309
- record.notified = true;
310
- if ("handle" in target) this.#unlist(record);
311
- outcome = record.outcome;
312
- if (outcome.kind === "failure") failure ??= outcome;
313
- this.#notify();
314
- }
315
- return Object.freeze({ outcome: failure ?? outcome, unknown: Object.freeze(unknown) });
316
- } finally {
317
- this.#waiters--;
318
- }
319
- }
320
- async waitNext(targets, options = {}) {
321
- const selected = this.#targets(targets);
322
- const signal = this.#waitSignal(options);
323
- if (this.#waiters >= this.limits.maxWaiters) throw new Error("job limit exceeded: maxWaiters");
324
- this.#waiters++;
325
- const unknown = [];
326
- const records = /* @__PURE__ */ new Set();
327
- if (selected === void 0) {
328
- for (const record of this.#records.values()) if (!record.saved) records.add(record);
329
- } else for (const target of selected) {
330
- const record = this.#lookup(target);
331
- if (!record || record.saved) unknown.push(target);
332
- else records.add(record);
333
- }
334
- try {
335
- for (; ; ) {
336
- signal?.throwIfAborted();
337
- const eligible = [...records].filter((record) => !record.saved && !record.notified).sort((first, second) => first.handle.jobId - second.handle.jobId);
338
- const ready = eligible.find((record) => record.state === "done");
339
- if (ready) {
340
- ready.notified = true;
341
- ready.saved = ready.outcome.kind === "status";
342
- this.#unlist(ready);
343
- this.#notify();
344
- return Object.freeze({ outcome: ready.outcome, handle: ready.handle, unknown: Object.freeze(unknown) });
345
- }
346
- if (!eligible.length) return Object.freeze({ outcome: Object.freeze({ kind: "status", status: 127 }), unknown: Object.freeze(unknown) });
347
- await this.#changed(signal);
348
- }
349
- } finally {
350
- this.#waiters--;
351
- }
352
- }
353
- finish() {
354
- this.#accepting = false;
355
- return this.#drain();
356
- }
357
- close(reason = new Error("job state closed")) {
358
- this.#accepting = false;
359
- if (!this.#finished && !this.#cancelling) {
360
- this.#cancelling = true;
361
- for (const record of this.#records.values()) if (record.state !== "done") {
362
- record.controller.abort(reason);
363
- void this.#clean(record);
364
- }
365
- }
366
- return this.#drain();
367
- }
368
- #drain() {
369
- if (!this.#terminal) {
370
- const records = [...this.#records.values()];
371
- this.#terminal = (async () => {
372
- try {
373
- await Promise.all(records.map((record) => record.handle.completion));
374
- if (!this.#cancelling) {
375
- const failure = records.find((record) => record.outcome?.kind === "failure");
376
- if (failure?.outcome?.kind === "failure") throw failure.outcome.reason;
377
- }
378
- const errors = records.flatMap((record) => record.cleanupFailures);
379
- if (errors.length) throw new AggregateError(errors, "job cleanup failed");
380
- } finally {
381
- this.#finished = true;
382
- this.#owner?.removeEventListener("abort", this.#abortOwner);
383
- }
384
- })();
385
- void this.#terminal.catch(() => {
386
- });
387
- }
388
- return this.#terminal;
389
- }
390
- };
391
- function createJobState(options = {}) {
392
- if (!options || typeof options !== "object" || Array.isArray(options)) throw new TypeError("invalid job options");
393
- const limits = { maxJobs: Infinity, maxWaiters: Infinity, maxCleanupsPerJob: Infinity };
394
- for (const key of Reflect.ownKeys(options)) {
395
- if (key === "signal" || key === "registerCleanup") continue;
396
- if (typeof key !== "string" || !Object.hasOwn(limits, key)) throw new TypeError("unknown job option");
397
- const name = key;
398
- const value = options[name];
399
- if (value === void 0) continue;
400
- if (!Number.isSafeInteger(value) || value < 1) throw new TypeError(`invalid job limit: ${key}`);
401
- limits[name] = value;
402
- }
403
- if (options.signal !== void 0 && !(options.signal instanceof AbortSignal)) throw new TypeError("invalid job owner signal");
404
- if (options.registerCleanup !== void 0 && typeof options.registerCleanup !== "function") throw new TypeError("invalid job owner cleanup registration");
405
- return new JobRegistry(Object.freeze(limits), options);
406
- }
407
-
408
- // packages/safe-bash/src/shell/extensions/jobs/index.ts
409
- var maximumWaitProcessId = 2147483647;
410
- function waitProcessId(operand, flexible = false) {
411
- let value = 0;
412
- let offset = 0;
413
- let negative = false;
414
- if (flexible) {
415
- while (offset < operand.length && (operand.charCodeAt(offset) === 32 || operand.charCodeAt(offset) >= 9 && operand.charCodeAt(offset) <= 13)) offset++;
416
- if (operand[offset] === "+" || operand[offset] === "-") negative = operand[offset++] === "-";
417
- }
418
- const firstDigit = offset;
419
- while (offset < operand.length) {
420
- const code = operand.charCodeAt(offset);
421
- if (code < 48 || code > 57) break;
422
- value = value * 10 + code - 48;
423
- if (value > maximumWaitProcessId + Number(negative)) return void 0;
424
- offset++;
425
- }
426
- if (offset === firstDigit) return void 0;
427
- while (offset < operand.length) {
428
- const code = operand.charCodeAt(offset++);
429
- if (code !== 32 && (code < 9 || code > 13)) return void 0;
430
- }
431
- return negative ? -value : value;
432
- }
433
- function instance(inherited, getParent) {
434
- let latest = inherited;
435
- let jobs;
436
- let failure;
437
- const children = /* @__PURE__ */ new Map();
438
- const resolveFrom = (activeJobs, activeChildren, operand, flexible = false) => {
439
- if (!operand.startsWith("%")) {
440
- const processId = waitProcessId(operand, flexible);
441
- return processId === void 0 ? void 0 : activeChildren.get(processId);
442
- }
443
- const listed = activeJobs.snapshot().filter((entry) => entry.listed);
444
- const spec = operand.slice(1);
445
- if (spec === "" || spec === "%" || spec === "+") return listed.at(-1)?.handle;
446
- if (spec === "-") return listed.at(-2)?.handle;
447
- const jobId = waitProcessId(spec);
448
- return listed.find((entry) => entry.handle.jobId === jobId)?.handle;
449
- };
450
- const resolve = (operand, flexible = false) => resolveFrom(jobs, children, operand, flexible);
451
- const list = async (context) => {
452
- let mode = "", offset = 0;
453
- for (; offset < context.args.length; offset++) {
454
- const option = context.args[offset];
455
- if (option === "--") {
456
- offset++;
457
- break;
458
- }
459
- if (!option.startsWith("-")) break;
460
- if (option === "-p" || option === "-l" || option === "-r" || option === "-s") mode = option;
461
- else {
462
- await context.diagnostic(`jobs: ${option}: invalid option`);
463
- return 2;
464
- }
465
- }
466
- let activeJobs = jobs;
467
- let activeChildren = children;
468
- let listed = activeJobs.snapshot().filter((entry) => entry.listed);
469
- if (listed.length === 0 && getParent) {
470
- const parent = getParent();
471
- if (parent.jobs) {
472
- activeJobs = parent.jobs;
473
- activeChildren = parent.children;
474
- listed = activeJobs.snapshot().filter((entry) => entry.listed);
475
- }
476
- }
477
- let result = 0;
478
- const selected = offset === context.args.length ? listed.map((entry) => entry.handle) : context.args.slice(offset).map((operand) => resolveFrom(activeJobs, activeChildren, operand.startsWith("%") ? operand : `%${operand}`));
479
- for (const [index, handle] of selected.entries()) {
480
- if (!handle) {
481
- await context.diagnostic(`jobs: ${context.args[offset + index]}: no such job`);
482
- result = 1;
483
- continue;
484
- }
485
- const entry = listed.find((entry2) => entry2.handle === handle);
486
- if (!entry || mode === "-s" || mode === "-r" && entry.state === "done") continue;
487
- const pid = [...activeChildren].find(([, child]) => child === handle)?.[0];
488
- if (mode === "-p") await (0, io_exports.writeText)(context.stdout, `${pid}
489
- `);
490
- else {
491
- const marker = handle === listed.at(-1)?.handle ? "+" : handle === listed.at(-2)?.handle ? "-" : " ";
492
- const state = entry.state === "done" ? "Done" : "Running";
493
- await (0, io_exports.writeText)(context.stdout, `[${handle.jobId}]${marker} ${mode === "-l" ? `${pid} ` : ""}${state}
494
- `);
495
- }
496
- }
497
- return result;
498
- };
499
- const kill = async (context) => {
500
- const signals = Object.fromEntries(Array.from({ length: 31 }, (_, index) => [`SIG${signalName(index + 1)}`, index + 1]));
501
- const signalNumber = (name) => {
502
- const numeric = waitProcessId(name);
503
- if (numeric !== void 0) return numeric === 0 || Object.values(signals).includes(numeric) ? numeric : void 0;
504
- return signals[name.startsWith("SIG") ? name : `SIG${name}`];
505
- };
506
- let offset = 0, signal = signals.SIGTERM;
507
- if (context.args[0] === "-l" || context.args[0] === "-L") {
508
- if (context.args.length === 1) {
509
- await (0, io_exports.writeText)(context.stdout, `${Object.keys(signals).map((name) => name.slice(3)).join(" ")}
510
- `);
511
- return 0;
512
- }
513
- let result2 = 0;
514
- for (const operand of context.args.slice(1)) {
515
- const numeric = waitProcessId(operand);
516
- const number = numeric === void 0 ? signalNumber(operand) : numeric > 128 ? numeric - 128 : numeric;
517
- const name = Object.keys(signals).find((name2) => signals[name2] === number);
518
- if (!name) {
519
- await context.diagnostic(`kill: ${operand}: invalid signal specification`);
520
- result2 = 1;
521
- } else await (0, io_exports.writeText)(context.stdout, `${numeric === void 0 ? number : name.slice(3)}
522
- `);
523
- }
524
- return result2;
525
- }
526
- if (context.args[0] === "-s" || context.args[0] === "-n") {
527
- signal = signalNumber(context.args[1] ?? "");
528
- offset = 2;
529
- } else if (context.args[0]?.startsWith("-") && context.args[0] !== "--") {
530
- signal = signalNumber(context.args[0].slice(1));
531
- offset = 1;
532
- }
533
- if (context.args[offset] === "--") offset++;
534
- if (signal === void 0 || signal > 31) {
535
- await context.diagnostic("kill: invalid signal specification");
536
- return 1;
537
- }
538
- if ([signals.SIGSTOP, signals.SIGTSTP, signals.SIGTTIN, signals.SIGTTOU, signals.SIGCONT, signals.SIGCHLD, signals.SIGURG, signals.SIGWINCH].includes(signal)) {
539
- await context.diagnostic("kill: signal is not supported by virtual job termination");
540
- return 1;
541
- }
542
- if (offset >= context.args.length) {
543
- await context.diagnostic("kill: usage: kill [-s signal | -n signal | -signal] pid | %job ...");
544
- return 2;
545
- }
546
- let result = 0;
547
- for (const operand of context.args.slice(offset)) {
548
- const handle = resolve(operand);
549
- if (!handle || !jobs.signal(handle, signal)) {
550
- await context.diagnostic(`kill: ${operand}: no such ${operand.startsWith("%") ? "job" : "process"}`);
551
- result = 1;
552
- }
553
- }
554
- return result;
555
- };
556
- const disown = async (context) => {
557
- let all = false;
558
- let runningOnly = false;
559
- let nohupOnly = false;
560
- let offset = 0;
561
- for (; offset < context.args.length; offset++) {
562
- const arg = context.args[offset];
563
- if (arg === "--") {
564
- offset++;
565
- break;
566
- }
567
- if (!arg.startsWith("-") || arg === "-") break;
568
- for (let i = 1; i < arg.length; i++) {
569
- const ch = arg[i];
570
- if (ch === "a") all = true;
571
- else if (ch === "r") runningOnly = true;
572
- else if (ch === "h") nohupOnly = true;
573
- else {
574
- await context.diagnostic(`disown: -${ch}: invalid option`);
575
- return 2;
576
- }
577
- }
578
- }
579
- const listed = jobs.snapshot().filter((entry) => entry.listed);
580
- const removeHandle = (handle) => {
581
- if (nohupOnly) return;
582
- jobs.disown(handle);
583
- for (const [pid, child] of children) {
584
- if (child === handle) children.delete(pid);
585
- }
586
- };
587
- if (offset === context.args.length) {
588
- if (all || runningOnly) {
589
- for (const entry of listed) {
590
- if (runningOnly && entry.state === "done") continue;
591
- removeHandle(entry.handle);
592
- }
593
- return 0;
594
- }
595
- const current = listed.at(-1)?.handle;
596
- if (!current) {
597
- await context.diagnostic("disown: current: no such job");
598
- return 1;
599
- }
600
- removeHandle(current);
601
- return 0;
602
- }
603
- let statusCode = 0;
604
- for (let i = offset; i < context.args.length; i++) {
605
- const operand = context.args[i];
606
- const handle = resolve(operand) ?? resolve(operand.startsWith("%") ? operand : `%${operand}`);
607
- if (!handle) {
608
- await context.diagnostic(`disown: ${operand}: no such job`);
609
- statusCode = 1;
610
- continue;
611
- }
612
- removeHandle(handle);
613
- }
614
- return statusCode;
615
- };
616
- const status = (outcome) => {
617
- if (outcome.kind === "failure") {
618
- failure ??= { reason: outcome.reason };
619
- throw outcome.reason;
620
- }
621
- return outcome.status;
622
- };
623
- const wait = async (context) => {
624
- let reference;
625
- let primary;
626
- const ordinaryWait = async (targets) => {
627
- if (context.waitInterruptibly) return context.waitInterruptibly((signal) => jobs.wait(targets, { signal }));
628
- return { kind: "completed", value: await jobs.wait(targets, { signal: context.signal }) };
629
- };
630
- const execute = async () => {
631
- let offset = 0;
632
- let next = false;
633
- let destination;
634
- while (offset < context.args.length) {
635
- context.signal.throwIfAborted();
636
- const option = (0, value_exports.shellValueBytes)(context.argumentValues[offset]);
637
- if (option.length < 2 || option[0] !== 45) break;
638
- offset++;
639
- if (option.length === 2 && option[1] === 45) break;
640
- for (let index = 1; index < option.length; index++) {
641
- if (option[index] === 102) continue;
642
- if (option[index] === 110) {
643
- next = true;
644
- continue;
645
- }
646
- if (option[index] === 112) {
647
- if (index + 1 < option.length) destination = (0, value_exports.shellValueFromBytes)(option.subarray(index + 1));
648
- else if (offset < context.args.length) destination = context.argumentValues[offset++];
649
- else {
650
- await context.diagnostic("wait: -p: option requires an argument");
651
- await (0, io_exports.writeText)(context.stderr, "wait: usage: wait [-fn] [-p var] [id ...]\n");
652
- return 2;
653
- }
654
- break;
655
- }
656
- await context.diagnostic((0, value_exports.concatShellValues)(["wait: -", (0, value_exports.shellValueFromBytes)(option.subarray(index, index + 1)), ": invalid option"]));
657
- await (0, io_exports.writeText)(context.stderr, "wait: usage: wait [-fn] [-p var] [id ...]\n");
658
- return 2;
659
- }
660
- }
661
- if (destination !== void 0) {
662
- const prepared = await context.bindings.prepareReference(destination);
663
- if (!prepared.ok) {
664
- await context.diagnostic((0, value_exports.concatShellValues)(["wait: ", prepared.diagnostic]));
665
- return 1;
666
- }
667
- reference = prepared.value;
668
- const removed = await reference.unbindName();
669
- if (!removed.ok) {
670
- await context.diagnostic((0, value_exports.concatShellValues)(["wait: ", removed.diagnostic]));
671
- return 1;
672
- }
673
- }
674
- const publish = async (result2, processId) => {
675
- if (reference && processId !== void 0) {
676
- const assigned = await reference.assignInteger(processId);
677
- if (!assigned.ok) {
678
- await context.diagnostic((0, value_exports.concatShellValues)(["wait: ", assigned.diagnostic]));
679
- return 1;
680
- }
681
- }
682
- return result2;
683
- };
684
- if (next) {
685
- for (let index = offset; index < context.args.length; index++) {
686
- context.signal.throwIfAborted();
687
- const processId2 = waitProcessId(context.args[index], true);
688
- const handle = resolve(context.args[index], true);
689
- const saved = handle && jobs.savedStatus(handle);
690
- if (saved !== void 0) return await publish(saved, processId2);
691
- }
692
- const active = new Set(jobs.snapshot().filter((entry) => entry.residency !== "saved").map((entry) => entry.handle));
693
- const targets = [];
694
- for (let index = offset; index < context.args.length; index++) {
695
- context.signal.throwIfAborted();
696
- const operand = context.args[index];
697
- const raw = context.argumentValues[index];
698
- const processId2 = waitProcessId(operand, true);
699
- const handle = resolve(operand, true);
700
- if (handle && active.has(handle)) {
701
- targets.push({ handle });
702
- continue;
703
- }
704
- if ((processId2 === void 0 || processId2 === -1) && operand.length && operand[0] !== "%") await context.diagnostic((0, value_exports.concatShellValues)(["wait: warning: ", raw, ": job specification requires leading `%'"]));
705
- await context.diagnostic((0, value_exports.concatShellValues)(["wait: `", raw, operand[0] === "%" ? "': no such job" : "': not a pid or valid job spec"]));
706
- }
707
- if (offset < context.args.length && !targets.length) return 127;
708
- const selected = offset === context.args.length ? void 0 : targets;
709
- const waited2 = context.waitInterruptibly ? await context.waitInterruptibly((signal) => jobs.waitNext(selected, { signal })) : { kind: "completed", value: await jobs.waitNext(selected, { signal: context.signal }) };
710
- if (waited2.kind === "interrupted") return waited2.status;
711
- const result2 = status(waited2.value.outcome);
712
- const processId = waited2.value.handle && [...children].find(([, handle]) => handle === waited2.value.handle)?.[0];
713
- return await publish(result2, processId);
714
- }
715
- if (offset === context.args.length) {
716
- const result2 = await ordinaryWait();
717
- if (result2.kind === "interrupted") return result2.status;
718
- children.clear();
719
- return status(result2.value.outcome);
720
- }
721
- const waitOperands = async (signal) => {
722
- let result2 = 0;
723
- let returnedProcessId;
724
- for (; offset < context.args.length; offset++) {
725
- signal.throwIfAborted();
726
- const operand = context.args[offset];
727
- const raw = context.argumentValues[offset];
728
- const processId = waitProcessId(operand);
729
- returnedProcessId = void 0;
730
- const handle = resolve(operand);
731
- if (operand.startsWith("%") && !handle) {
732
- await context.diagnostic((0, value_exports.concatShellValues)(["wait: `", raw, "': no such job"]));
733
- result2 = 127;
734
- continue;
735
- }
736
- if (processId === void 0 && !operand.startsWith("%")) {
737
- await context.diagnostic((0, value_exports.concatShellValues)(["wait: `", raw, "': not a pid or valid job spec"]));
738
- if (operand.length && operand[0] >= "0" && operand[0] <= "9") return { result: 1, processId: void 0 };
739
- result2 = 1;
740
- continue;
741
- }
742
- if (!handle) {
743
- await context.diagnostic(`wait: pid ${processId} is not a child of this shell`);
744
- result2 = 127;
745
- } else {
746
- const waited2 = await jobs.wait([{ handle }], { signal });
747
- result2 = status(waited2.outcome);
748
- returnedProcessId = [...children].find(([, child]) => child === handle)?.[0];
749
- }
750
- }
751
- return { result: result2, processId: returnedProcessId };
752
- };
753
- const waited = context.waitInterruptibly ? await context.waitInterruptibly(waitOperands) : { kind: "completed", value: await waitOperands(context.signal) };
754
- if (waited.kind === "interrupted") return waited.status;
755
- return await publish(waited.value.result, waited.value.processId);
756
- };
757
- let result = 0;
758
- try {
759
- result = await execute();
760
- } catch (reason) {
761
- primary = { reason };
762
- failure ??= primary;
763
- }
764
- try {
765
- await reference?.close();
766
- } catch (reason) {
767
- primary ??= { reason };
768
- failure ??= primary;
769
- }
770
- if (primary) throw primary.reason;
771
- return result;
772
- };
773
- const extInstance = {
774
- builtins: [{ name: "wait", execute: wait }, { name: "jobs", execute: list }, { name: "kill", execute: kill }, { name: "disown", execute: disown }],
775
- start(context) {
776
- const registerExecutionCleanup = context.registerExecutionCleanup;
777
- if (typeof registerExecutionCleanup !== "function") throw new TypeError("Jobs require execution-scoped cleanup ownership");
778
- let ownerSignal = context.signal;
779
- let retired;
780
- const retirement = new Promise((resolve2) => {
781
- retired = resolve2;
782
- });
783
- let completion;
784
- const finish = () => {
785
- retired();
786
- if (!completion) {
787
- completion = Promise.resolve().then(async () => {
788
- if (jobs) {
789
- try {
790
- if (ownerSignal.aborted) await jobs.close(ownerSignal.reason);
791
- else await jobs.finish();
792
- } catch (reason) {
793
- failure ??= { reason };
794
- }
795
- }
796
- if (failure) throw failure.reason;
797
- });
798
- void completion.catch(() => void 0);
799
- }
800
- return completion;
801
- };
802
- try {
803
- const signal = registerExecutionCleanup.call(context, async () => {
804
- try {
805
- await retirement;
806
- await finish();
807
- } finally {
808
- ownerSignal.removeEventListener("abort", retired);
809
- }
810
- });
811
- if (!(signal instanceof AbortSignal)) throw new TypeError("Execution cleanup must provide its owner cancellation signal");
812
- ownerSignal = signal;
813
- ownerSignal.addEventListener("abort", retired, { once: true });
814
- if (ownerSignal.aborted) retired();
815
- context.registerCleanup(() => {
816
- void finish();
817
- });
818
- jobs = createJobState({ signal: ownerSignal });
819
- } catch (reason) {
820
- void finish();
821
- throw reason;
822
- }
823
- },
824
- fork: () => instance(latest, () => ({ jobs, children })),
825
- checkpoint() {
826
- jobs.retireNotified();
827
- },
828
- listTerminators: [{ operator: "&", async execute(context) {
829
- let processId;
830
- const handle = await jobs.start(async (task) => {
831
- const child = await context.prepareChild({ ...task, stdin: "async-default" });
832
- processId = child.processId;
833
- return child;
834
- });
835
- children.set(processId, handle);
836
- latest = processId;
837
- return 0;
838
- } }],
839
- specialParameters: [{ name: "!", lookup: () => latest === void 0 ? void 0 : String(latest) }]
840
- };
841
- return extInstance;
842
- }
843
- function jobsExtension() {
844
- return {
845
- name: "jobs",
846
- runtimeIdentity: command_exports.commandRuntimeIdentity,
847
- syntax: { listTerminators: [{ operator: "&" }], specialParameters: [{ name: "!" }] },
848
- create: () => instance()
849
- };
850
- }
851
-
852
- export {
853
- signalName,
854
- parseSignal,
855
- jobsExtension
856
- };
857
- //# sourceMappingURL=chunk-LB6HVRXS.js.map