opencode-landstrip 0.16.7 → 0.16.9
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/index.ts +25 -18
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -267,9 +267,10 @@ function extractBlockedPath(
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
270
|
+
if (
|
|
271
|
+
landstripTraps.some((trap) => trap.kind === 'filesystem' || trap.kind === 'internal') &&
|
|
272
|
+
command
|
|
273
|
+
) {
|
|
273
274
|
for (const candidate of extractCandidatePaths(command)) {
|
|
274
275
|
const resolved = canonicalizePath(candidate, baseDirectory);
|
|
275
276
|
return resolved;
|
|
@@ -279,14 +280,6 @@ function extractBlockedPath(
|
|
|
279
280
|
return null;
|
|
280
281
|
}
|
|
281
282
|
|
|
282
|
-
function extractBlockedWritePath(
|
|
283
|
-
output: string,
|
|
284
|
-
baseDirectory: string,
|
|
285
|
-
command?: string,
|
|
286
|
-
): string | null {
|
|
287
|
-
return extractBlockedPath(output, baseDirectory, command);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
283
|
function evaluateReadPermission(
|
|
291
284
|
path: string,
|
|
292
285
|
config: SandboxConfig,
|
|
@@ -652,6 +645,15 @@ function socketQueryPort(baseDirectory: string): number | null {
|
|
|
652
645
|
return readDiscoveryPort(baseDirectory);
|
|
653
646
|
}
|
|
654
647
|
|
|
648
|
+
async function awaitQueryPort(baseDirectory: string): Promise<number | null> {
|
|
649
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
650
|
+
const port = socketQueryPort(baseDirectory);
|
|
651
|
+
if (port !== null) return port;
|
|
652
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
653
|
+
}
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
|
|
655
657
|
function buildWrappedCommand(
|
|
656
658
|
policyPath: string,
|
|
657
659
|
shell: string,
|
|
@@ -663,12 +665,17 @@ function buildWrappedCommand(
|
|
|
663
665
|
if (trapPort === null) return plain;
|
|
664
666
|
|
|
665
667
|
// Connect fd 3 to the TUI's query-response socket BEFORE landstrip applies the
|
|
666
|
-
// sandbox, so a denied
|
|
667
|
-
//
|
|
668
|
-
//
|
|
669
|
-
//
|
|
668
|
+
// sandbox, so a denied filesystem access can be approved live instead of
|
|
669
|
+
// forcing a re-run.
|
|
670
|
+
//
|
|
671
|
+
// /dev/tcp is a bash/ksh built-in — it does not work in zsh, dash, or fish.
|
|
672
|
+
// We try the native redirect first (fast path when the host shell supports it)
|
|
673
|
+
// and fall back to an explicit bash invocation that always speaks /dev/tcp.
|
|
674
|
+
// If both fail (no bash, dead port, set -e in the outer shell) landstrip runs
|
|
675
|
+
// without --trap-fd so the toast-notify path still works.
|
|
670
676
|
const trapped = [landstripBinaryPath(), '--trap-fd', '3', ...baseArgs].map(shellQuote).join(' ');
|
|
671
|
-
|
|
677
|
+
const bashTrap = `bash -c ${shellQuote(`exec 3<>/dev/tcp/127.0.0.1/${trapPort} && exec "$@"`)} bash ${trapped}`;
|
|
678
|
+
return `{ exec 3<>/dev/tcp/127.0.0.1/${trapPort} ; } 2>/dev/null && ${trapped} || ${bashTrap} 2>/dev/null || ${plain}`;
|
|
672
679
|
}
|
|
673
680
|
|
|
674
681
|
function isGeneratedWrappedCommand(command: string): boolean {
|
|
@@ -1062,7 +1069,7 @@ const plugin: Plugin = async ({ client, directory }: PluginInput, options?: Plug
|
|
|
1062
1069
|
policy.path,
|
|
1063
1070
|
configuredShell ?? process.env.SHELL ?? '/bin/sh',
|
|
1064
1071
|
originalCommand,
|
|
1065
|
-
|
|
1072
|
+
await awaitQueryPort(directory),
|
|
1066
1073
|
);
|
|
1067
1074
|
|
|
1068
1075
|
activeBash.set(callID, {
|
|
@@ -1239,7 +1246,7 @@ const plugin: Plugin = async ({ client, directory }: PluginInput, options?: Plug
|
|
|
1239
1246
|
?.catch?.(() => undefined);
|
|
1240
1247
|
}
|
|
1241
1248
|
|
|
1242
|
-
const blockedPath =
|
|
1249
|
+
const blockedPath = extractBlockedPath(outputText, directory, state.originalCommand);
|
|
1243
1250
|
if (blockedPath) {
|
|
1244
1251
|
await notifyOnce(
|
|
1245
1252
|
`blocked:${blockedPath}`,
|