pi-landstrip 0.14.1 → 0.14.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/index.ts +61 -6
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -454,6 +454,16 @@ function extractBlockedWritePath(output: string, cwd: string): string | null {
|
|
|
454
454
|
return extractNativeWriteDeniedPath(output, cwd);
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
+
function extractBlockedReadPath(output: string, cwd: string): string | null {
|
|
458
|
+
for (const error of parseLandstripTraps(output).filter(isFilesystemTrap)) {
|
|
459
|
+
if (error.operation === 'read') {
|
|
460
|
+
return normalizeBlockedPath(error.file, cwd);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return extractNativeDeniedPath(output, cwd);
|
|
465
|
+
}
|
|
466
|
+
|
|
457
467
|
// Returns the first `length` elements of a string tuple, or null if `value` is
|
|
458
468
|
// not an array of at least that many strings.
|
|
459
469
|
function stringTuple(value: unknown, length: number): string[] | null {
|
|
@@ -1310,17 +1320,54 @@ export function createLandstripIntegration(
|
|
|
1310
1320
|
return run();
|
|
1311
1321
|
};
|
|
1312
1322
|
|
|
1323
|
+
const retryWithReadAccess = async (
|
|
1324
|
+
blockedPath: string,
|
|
1325
|
+
): Promise<AgentToolResult<BashToolDetails | undefined> | null> => {
|
|
1326
|
+
if (!ctx.hasUI) return null;
|
|
1327
|
+
|
|
1328
|
+
if (!matchesPattern(blockedPath, getEffectiveAllowRead(ctx.cwd))) {
|
|
1329
|
+
const config = loadConfig(ctx.cwd);
|
|
1330
|
+
const choice = await promptReadBlock(
|
|
1331
|
+
ctx,
|
|
1332
|
+
blockedPath,
|
|
1333
|
+
matchesPattern(blockedPath, config.filesystem.denyRead)
|
|
1334
|
+
? 'denyRead overrides allowRead'
|
|
1335
|
+
: undefined,
|
|
1336
|
+
);
|
|
1337
|
+
if (choice === 'abort') return null;
|
|
1338
|
+
await applyReadChoice(choice, blockedPath, ctx.cwd);
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
onUpdate?.({
|
|
1342
|
+
content: [
|
|
1343
|
+
{ type: 'text', text: `\n--- Read access granted for "${blockedPath}", retrying ---\n` },
|
|
1344
|
+
],
|
|
1345
|
+
details: {},
|
|
1346
|
+
});
|
|
1347
|
+
landstripErrorOutput = '';
|
|
1348
|
+
stderrOutput = '';
|
|
1349
|
+
return run();
|
|
1350
|
+
};
|
|
1351
|
+
|
|
1313
1352
|
let result: AgentToolResult<BashToolDetails | undefined>;
|
|
1314
1353
|
try {
|
|
1315
1354
|
result = await run();
|
|
1316
1355
|
} catch (error) {
|
|
1317
1356
|
const errorText = error instanceof Error ? error.message : String(error);
|
|
1318
1357
|
const fallbackOutput = `${stderrOutput}\n${errorText}`;
|
|
1319
|
-
const
|
|
1358
|
+
const blockedWritePath =
|
|
1320
1359
|
extractBlockedWritePath(landstripErrorOutput, ctx.cwd) ??
|
|
1321
1360
|
extractBlockedWritePath(fallbackOutput, ctx.cwd);
|
|
1322
|
-
if (
|
|
1323
|
-
const retryResult = await retryWithWriteAccess(
|
|
1361
|
+
if (blockedWritePath) {
|
|
1362
|
+
const retryResult = await retryWithWriteAccess(blockedWritePath);
|
|
1363
|
+
if (retryResult) return retryResult;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
const blockedReadPath =
|
|
1367
|
+
extractBlockedReadPath(landstripErrorOutput, ctx.cwd) ??
|
|
1368
|
+
extractBlockedReadPath(fallbackOutput, ctx.cwd);
|
|
1369
|
+
if (blockedReadPath) {
|
|
1370
|
+
const retryResult = await retryWithReadAccess(blockedReadPath);
|
|
1324
1371
|
if (retryResult) return retryResult;
|
|
1325
1372
|
}
|
|
1326
1373
|
|
|
@@ -1335,12 +1382,20 @@ export function createLandstripIntegration(
|
|
|
1335
1382
|
const message = formatLandstripTraps(landstripErrors);
|
|
1336
1383
|
result.content.unshift({ type: 'text', text: `\n${message}\n` });
|
|
1337
1384
|
}
|
|
1338
|
-
const
|
|
1385
|
+
const blockedWritePath =
|
|
1339
1386
|
extractBlockedWritePath(landstripErrorOutput, ctx.cwd) ??
|
|
1340
1387
|
extractBlockedWritePath(stderrOutput, ctx.cwd);
|
|
1341
|
-
if (
|
|
1388
|
+
if (blockedWritePath) {
|
|
1389
|
+
const retryResult = await retryWithWriteAccess(blockedWritePath);
|
|
1390
|
+
if (retryResult) return retryResult;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
const blockedReadPath =
|
|
1394
|
+
extractBlockedReadPath(landstripErrorOutput, ctx.cwd) ??
|
|
1395
|
+
extractBlockedReadPath(stderrOutput, ctx.cwd);
|
|
1396
|
+
if (!blockedReadPath) return result;
|
|
1342
1397
|
|
|
1343
|
-
const retryResult = await
|
|
1398
|
+
const retryResult = await retryWithReadAccess(blockedReadPath);
|
|
1344
1399
|
return retryResult ?? result;
|
|
1345
1400
|
}
|
|
1346
1401
|
|