pi-landstrip 0.11.7 → 0.11.8
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/README.md +12 -4
- package/index.ts +55 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,12 +23,20 @@ Project config takes precedence.
|
|
|
23
23
|
|
|
24
24
|
See [`sandbox.json`](./sandbox.json) for a starter config.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
|
|
26
|
+
Use Pi settings to toggle sandboxing:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"landstrip": {
|
|
31
|
+
"enabled": false
|
|
32
|
+
}
|
|
33
|
+
}
|
|
30
34
|
```
|
|
31
35
|
|
|
36
|
+
Project Pi settings override global Pi settings.
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
32
40
|
Use `/sandbox` inside Pi to show the active config.
|
|
33
41
|
|
|
34
42
|
## License
|
package/index.ts
CHANGED
|
@@ -62,6 +62,12 @@ interface SandboxConfig {
|
|
|
62
62
|
filesystem: SandboxFilesystemConfig;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
interface PiLandstripSettings {
|
|
66
|
+
landstrip?: {
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
65
71
|
interface LandstripPolicy {
|
|
66
72
|
network: {
|
|
67
73
|
allowNetwork: boolean;
|
|
@@ -184,6 +190,14 @@ function loadConfig(cwd: string): SandboxConfig {
|
|
|
184
190
|
return deepMerge(deepMerge(DEFAULT_CONFIG, globalConfig), projectConfig);
|
|
185
191
|
}
|
|
186
192
|
|
|
193
|
+
function isSandboxEnabledInPiSettings(cwd: string): boolean {
|
|
194
|
+
const settings = SettingsManager.create(cwd);
|
|
195
|
+
const globalSettings = settings.getGlobalSettings() as PiLandstripSettings;
|
|
196
|
+
const projectSettings = settings.getProjectSettings() as PiLandstripSettings;
|
|
197
|
+
|
|
198
|
+
return projectSettings.landstrip?.enabled ?? globalSettings.landstrip?.enabled ?? true;
|
|
199
|
+
}
|
|
200
|
+
|
|
187
201
|
function mergeArray(base: string[], override?: string[]): string[] {
|
|
188
202
|
if (!override) return base;
|
|
189
203
|
return [...new Set([...base, ...override])];
|
|
@@ -1430,6 +1444,34 @@ export function createLandstripIntegration(
|
|
|
1430
1444
|
return true;
|
|
1431
1445
|
}
|
|
1432
1446
|
|
|
1447
|
+
let noSandboxFlag = false;
|
|
1448
|
+
function disableSandbox(ctx: ExtensionContext): void {
|
|
1449
|
+
sandboxEnabled = false;
|
|
1450
|
+
sandboxReady = false;
|
|
1451
|
+
setTuiStatus(ctx, 'sandbox', undefined);
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
function ensureSandboxState(ctx: ExtensionContext): boolean {
|
|
1455
|
+
if (noSandboxFlag) {
|
|
1456
|
+
disableSandbox(ctx);
|
|
1457
|
+
return false;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
if (!isSandboxEnabledInPiSettings(ctx.cwd)) {
|
|
1461
|
+
disableSandbox(ctx);
|
|
1462
|
+
return false;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
const config = loadConfig(ctx.cwd);
|
|
1466
|
+
if (!config.enabled) {
|
|
1467
|
+
disableSandbox(ctx);
|
|
1468
|
+
return false;
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
if (!sandboxEnabled || !sandboxReady) return enableSandbox(ctx);
|
|
1472
|
+
return true;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1433
1475
|
function createBashTool(cwd: string, ctx?: ExtensionContext): LandstripBashTool {
|
|
1434
1476
|
const localBash = createPlainBashTool(cwd);
|
|
1435
1477
|
|
|
@@ -1438,7 +1480,7 @@ export function createLandstripIntegration(
|
|
|
1438
1480
|
label: 'bash (landstrip)',
|
|
1439
1481
|
async execute(id, params, signal, onUpdate, callCtx) {
|
|
1440
1482
|
const effectiveCtx = callCtx ?? ctx;
|
|
1441
|
-
if (!
|
|
1483
|
+
if (!effectiveCtx || !ensureSandboxState(effectiveCtx))
|
|
1442
1484
|
return localBash.execute(id, params, signal, onUpdate, effectiveCtx);
|
|
1443
1485
|
|
|
1444
1486
|
return runBashWithOptionalRetry(id, params, signal, onUpdate, effectiveCtx);
|
|
@@ -1462,9 +1504,8 @@ export function createLandstripIntegration(
|
|
|
1462
1504
|
if (shouldRegisterBashTool) pi.registerTool(createBashTool(localCwd));
|
|
1463
1505
|
|
|
1464
1506
|
pi.on('user_bash', async (event, ctx) => {
|
|
1465
|
-
if (!
|
|
1507
|
+
if (!ensureSandboxState(ctx)) return;
|
|
1466
1508
|
const config = loadConfig(ctx.cwd);
|
|
1467
|
-
if (!config.enabled) return;
|
|
1468
1509
|
|
|
1469
1510
|
if (!config.network.allowNetwork) {
|
|
1470
1511
|
const blockedDomain = await preflightCommandDomains(event.command, ctx);
|
|
@@ -1484,10 +1525,9 @@ export function createLandstripIntegration(
|
|
|
1484
1525
|
});
|
|
1485
1526
|
|
|
1486
1527
|
pi.on('tool_call', async (event, ctx) => {
|
|
1487
|
-
if (!
|
|
1528
|
+
if (!ensureSandboxState(ctx)) return;
|
|
1488
1529
|
|
|
1489
1530
|
const config = loadConfig(ctx.cwd);
|
|
1490
|
-
if (!config.enabled) return;
|
|
1491
1531
|
|
|
1492
1532
|
const { globalPath, projectPath } = getConfigPaths(ctx.cwd);
|
|
1493
1533
|
|
|
@@ -1544,53 +1584,29 @@ export function createLandstripIntegration(
|
|
|
1544
1584
|
|
|
1545
1585
|
pi.on('session_start', async (_event, ctx) => {
|
|
1546
1586
|
resetSessionAllowances();
|
|
1547
|
-
|
|
1587
|
+
noSandboxFlag = Boolean(maybePi.getFlag?.('no-sandbox'));
|
|
1548
1588
|
|
|
1549
|
-
if (
|
|
1550
|
-
|
|
1551
|
-
sandboxReady = false;
|
|
1589
|
+
if (noSandboxFlag) {
|
|
1590
|
+
disableSandbox(ctx);
|
|
1552
1591
|
notify(ctx, 'Sandbox disabled via --no-sandbox', 'warning');
|
|
1553
1592
|
return;
|
|
1554
1593
|
}
|
|
1555
1594
|
|
|
1595
|
+
if (!isSandboxEnabledInPiSettings(ctx.cwd)) {
|
|
1596
|
+
disableSandbox(ctx);
|
|
1597
|
+
notify(ctx, 'Sandbox disabled via pi settings', 'info');
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1556
1601
|
const config = loadConfig(ctx.cwd);
|
|
1557
1602
|
if (!config.enabled) {
|
|
1558
|
-
|
|
1559
|
-
sandboxReady = false;
|
|
1603
|
+
disableSandbox(ctx);
|
|
1560
1604
|
notify(ctx, 'Sandbox disabled via config', 'info');
|
|
1561
1605
|
return;
|
|
1562
1606
|
}
|
|
1563
1607
|
|
|
1564
1608
|
enableSandbox(ctx);
|
|
1565
1609
|
});
|
|
1566
|
-
|
|
1567
|
-
maybePi.registerCommand?.('sandbox-enable', {
|
|
1568
|
-
description: 'Enable the landstrip sandbox for this session',
|
|
1569
|
-
handler: async (_args, ctx) => {
|
|
1570
|
-
if (sandboxEnabled) {
|
|
1571
|
-
notify(ctx, 'Sandbox is already enabled', 'info');
|
|
1572
|
-
return;
|
|
1573
|
-
}
|
|
1574
|
-
|
|
1575
|
-
if (enableSandbox(ctx)) notify(ctx, 'Sandbox enabled', 'info');
|
|
1576
|
-
},
|
|
1577
|
-
});
|
|
1578
|
-
|
|
1579
|
-
maybePi.registerCommand?.('sandbox-disable', {
|
|
1580
|
-
description: 'Disable the landstrip sandbox for this session',
|
|
1581
|
-
handler: async (_args, ctx) => {
|
|
1582
|
-
if (!sandboxEnabled) {
|
|
1583
|
-
notify(ctx, 'Sandbox is already disabled', 'info');
|
|
1584
|
-
return;
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
sandboxEnabled = false;
|
|
1588
|
-
sandboxReady = false;
|
|
1589
|
-
setTuiStatus(ctx, 'sandbox', undefined);
|
|
1590
|
-
notify(ctx, 'Sandbox disabled', 'info');
|
|
1591
|
-
},
|
|
1592
|
-
});
|
|
1593
|
-
|
|
1594
1610
|
maybePi.registerCommand?.('sandbox', {
|
|
1595
1611
|
description: 'Show sandbox configuration',
|
|
1596
1612
|
handler: async (_args, ctx) => {
|