pi-landstrip 0.18.11 → 0.18.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.ts +69 -28
- package/package.json +2 -2
package/dist/index.ts
CHANGED
|
@@ -275,38 +275,69 @@ function colorizeAgentText(color, text, themeFg, fallback = "accent") {
|
|
|
275
275
|
|
|
276
276
|
class AsyncQueue {
|
|
277
277
|
tail = Promise.resolve();
|
|
278
|
+
generation = 0;
|
|
279
|
+
resetWaiters = [];
|
|
278
280
|
async acquire(signal, cancellationMessage = "Request cancelled") {
|
|
279
281
|
if (signal?.aborted)
|
|
280
282
|
throw new Error(cancellationMessage);
|
|
283
|
+
const generation = this.generation;
|
|
281
284
|
let release;
|
|
282
285
|
const previous = this.tail;
|
|
283
286
|
this.tail = new Promise((resolve2) => {
|
|
284
287
|
release = resolve2;
|
|
285
288
|
});
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
289
|
+
const finish = () => {
|
|
290
|
+
release?.();
|
|
291
|
+
};
|
|
292
|
+
let wakeReset;
|
|
293
|
+
const resetSignal = new Promise((resolve2) => {
|
|
294
|
+
wakeReset = resolve2;
|
|
295
|
+
this.resetWaiters.push(resolve2);
|
|
296
|
+
});
|
|
297
|
+
const dropResetWaiter = () => {
|
|
298
|
+
if (!wakeReset)
|
|
299
|
+
return;
|
|
300
|
+
const index = this.resetWaiters.indexOf(wakeReset);
|
|
301
|
+
if (index >= 0)
|
|
302
|
+
this.resetWaiters.splice(index, 1);
|
|
303
|
+
wakeReset = undefined;
|
|
304
|
+
};
|
|
291
305
|
try {
|
|
292
|
-
|
|
293
|
-
previous,
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
306
|
+
if (!signal) {
|
|
307
|
+
await Promise.race([previous, resetSignal]);
|
|
308
|
+
} else {
|
|
309
|
+
let abort;
|
|
310
|
+
try {
|
|
311
|
+
await Promise.race([
|
|
312
|
+
previous,
|
|
313
|
+
resetSignal,
|
|
314
|
+
new Promise((_resolve, reject) => {
|
|
315
|
+
abort = () => reject(new Error(cancellationMessage));
|
|
316
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
317
|
+
})
|
|
318
|
+
]);
|
|
319
|
+
} finally {
|
|
320
|
+
if (abort)
|
|
321
|
+
signal.removeEventListener("abort", abort);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (this.generation !== generation) {
|
|
325
|
+
throw new Error(cancellationMessage);
|
|
326
|
+
}
|
|
327
|
+
return finish;
|
|
299
328
|
} catch (error) {
|
|
300
|
-
previous.finally(
|
|
329
|
+
previous.finally(finish);
|
|
301
330
|
throw error;
|
|
302
331
|
} finally {
|
|
303
|
-
|
|
304
|
-
signal.removeEventListener("abort", abort);
|
|
332
|
+
dropResetWaiter();
|
|
305
333
|
}
|
|
306
|
-
return release;
|
|
307
334
|
}
|
|
308
335
|
reset() {
|
|
336
|
+
this.generation += 1;
|
|
309
337
|
this.tail = Promise.resolve();
|
|
338
|
+
const waiters = this.resetWaiters.splice(0);
|
|
339
|
+
for (const wake of waiters)
|
|
340
|
+
wake();
|
|
310
341
|
}
|
|
311
342
|
}
|
|
312
343
|
|
|
@@ -2085,14 +2116,14 @@ class Semaphore {
|
|
|
2085
2116
|
if (this.active >= this.limit)
|
|
2086
2117
|
return;
|
|
2087
2118
|
this.active += 1;
|
|
2088
|
-
return
|
|
2119
|
+
return this.releaseOnce();
|
|
2089
2120
|
}
|
|
2090
2121
|
async acquire(signal) {
|
|
2091
2122
|
if (signal?.aborted)
|
|
2092
2123
|
throw new Error("Task cancelled");
|
|
2093
2124
|
if (this.active < this.limit) {
|
|
2094
2125
|
this.active += 1;
|
|
2095
|
-
return
|
|
2126
|
+
return this.releaseOnce();
|
|
2096
2127
|
}
|
|
2097
2128
|
await new Promise((resolve3, reject) => {
|
|
2098
2129
|
const abort = () => {
|
|
@@ -2109,11 +2140,17 @@ class Semaphore {
|
|
|
2109
2140
|
this.waiters.push(start);
|
|
2110
2141
|
signal?.addEventListener("abort", abort, { once: true });
|
|
2111
2142
|
});
|
|
2112
|
-
return
|
|
2143
|
+
return this.releaseOnce();
|
|
2113
2144
|
}
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2145
|
+
releaseOnce() {
|
|
2146
|
+
let released = false;
|
|
2147
|
+
return () => {
|
|
2148
|
+
if (released)
|
|
2149
|
+
return;
|
|
2150
|
+
released = true;
|
|
2151
|
+
this.active -= 1;
|
|
2152
|
+
this.waiters.shift()?.();
|
|
2153
|
+
};
|
|
2117
2154
|
}
|
|
2118
2155
|
}
|
|
2119
2156
|
|
|
@@ -2708,7 +2745,9 @@ ${this.primaryAgent.prompt}` };
|
|
|
2708
2745
|
const dirty = dirtySettings.has(index) ? theme.fg("warning", " *") : "";
|
|
2709
2746
|
lines2.push(`${cursor} ${value} ${label}${dirty}`);
|
|
2710
2747
|
}
|
|
2711
|
-
|
|
2748
|
+
if (selectedSetting === 1) {
|
|
2749
|
+
lines2.push("", theme.fg("dim", rows[1]?.inherited ? "Controls OS sandboxing. Use /sandbox to inspect its policy. Using the Global value." : "Controls OS sandboxing. Use /sandbox to inspect its policy."));
|
|
2750
|
+
}
|
|
2712
2751
|
if (saving)
|
|
2713
2752
|
lines2.push("", theme.fg("dim", "Saving…"));
|
|
2714
2753
|
return box(lines2);
|
|
@@ -3718,7 +3757,9 @@ ${catalog.diagnostics.join(`
|
|
|
3718
3757
|
});
|
|
3719
3758
|
} finally {
|
|
3720
3759
|
if (handedOff)
|
|
3721
|
-
await this.restoreLease(task.id
|
|
3760
|
+
await this.restoreLease(task.id).catch(() => {
|
|
3761
|
+
return;
|
|
3762
|
+
});
|
|
3722
3763
|
}
|
|
3723
3764
|
response = {
|
|
3724
3765
|
ok: true,
|
|
@@ -4015,11 +4056,11 @@ ${renderTaskResult(task.id, failed ? "error" : "completed", value)}`;
|
|
|
4015
4056
|
lease.release = undefined;
|
|
4016
4057
|
return true;
|
|
4017
4058
|
}
|
|
4018
|
-
async restoreLease(taskId
|
|
4059
|
+
async restoreLease(taskId) {
|
|
4019
4060
|
const lease = this.leases.get(taskId);
|
|
4020
4061
|
if (!lease || lease.release)
|
|
4021
4062
|
return;
|
|
4022
|
-
const release = await this.semaphore.acquire(
|
|
4063
|
+
const release = await this.semaphore.acquire();
|
|
4023
4064
|
const current = this.leases.get(taskId);
|
|
4024
4065
|
if (!current || current.release) {
|
|
4025
4066
|
release();
|
|
@@ -4194,8 +4235,8 @@ function readOrEmptyConfig(configPath) {
|
|
|
4194
4235
|
return {};
|
|
4195
4236
|
try {
|
|
4196
4237
|
return JSON.parse(readFileSync6(configPath, "utf-8"));
|
|
4197
|
-
} catch {
|
|
4198
|
-
|
|
4238
|
+
} catch (error) {
|
|
4239
|
+
throw new Error(`${configPath}: ${formatError(error)}`);
|
|
4199
4240
|
}
|
|
4200
4241
|
}
|
|
4201
4242
|
function writeConfigFile(configPath, config) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-landstrip",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.12",
|
|
4
4
|
"description": "Sandboxed Bash and process-backed agents for Pi",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"landstrip",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"ci:test": "npm run test"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@landstrip/landstrip": "^0.18.
|
|
42
|
+
"@landstrip/landstrip": "^0.18.12",
|
|
43
43
|
"jsonc-parser": "^3.3.1",
|
|
44
44
|
"minimatch": "^10.2.5",
|
|
45
45
|
"yaml": "^2.9.0"
|