pi-landstrip 0.20.1 → 0.20.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/README.md +2 -3
- package/dist/index.ts +28 -110
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,8 +15,8 @@ unsandboxed execution.
|
|
|
15
15
|
## Permissions and configuration
|
|
16
16
|
|
|
17
17
|
With sandboxing enabled, Bash (`bash`, `!`, `!!`) and workers are OS-isolated.
|
|
18
|
-
Primary file tools
|
|
19
|
-
|
|
18
|
+
Primary file tools run in trusted Pi and preflight paths against the sandbox
|
|
19
|
+
filesystem policy. Tool approval never bypasses hard denials.
|
|
20
20
|
|
|
21
21
|
Configuration: bundled [`sandbox.json`](sandbox.json) → `~/.pi/agent/sandbox.json`
|
|
22
22
|
→ trusted-project `.pi/sandbox.json`. Arrays combine; later scalars win.
|
|
@@ -52,7 +52,6 @@ Configure `~/.pi/agent/landstrip.json`, trusted-project `.pi/landstrip.json`, or
|
|
|
52
52
|
```json
|
|
53
53
|
{
|
|
54
54
|
"maxSubagents": 2,
|
|
55
|
-
"toolFilesystemPolicy": "sandbox",
|
|
56
55
|
"permission": { "task": { "*": "deny", "review": "allow" } }
|
|
57
56
|
}
|
|
58
57
|
```
|
package/dist/index.ts
CHANGED
|
@@ -255,7 +255,6 @@ import {
|
|
|
255
255
|
fuzzyFilter as fuzzyFilter2,
|
|
256
256
|
matchesKey,
|
|
257
257
|
Input,
|
|
258
|
-
SelectList,
|
|
259
258
|
SettingsList,
|
|
260
259
|
Text,
|
|
261
260
|
truncateToWidth,
|
|
@@ -488,7 +487,6 @@ class PermissionPromptCoordinator {
|
|
|
488
487
|
// config.ts
|
|
489
488
|
var BUILT_IN_LANDSTRIP_CONFIG = {
|
|
490
489
|
maxSubagents: 0,
|
|
491
|
-
toolFilesystemPolicy: "host",
|
|
492
490
|
agent: {
|
|
493
491
|
build: {
|
|
494
492
|
description: "Implement and test requested changes",
|
|
@@ -561,7 +559,7 @@ function isProjectTrusted(ctx) {
|
|
|
561
559
|
return trustContext.isProjectTrusted?.() ?? false;
|
|
562
560
|
}
|
|
563
561
|
var MAX_SUBAGENTS = 16;
|
|
564
|
-
var LANDSTRIP_KEYS = ["maxSubagents", "agent", "permission"
|
|
562
|
+
var LANDSTRIP_KEYS = ["maxSubagents", "agent", "permission"];
|
|
565
563
|
var JSON_FORMAT = { formattingOptions: { insertSpaces: true, tabSize: 2, eol: `
|
|
566
564
|
` } };
|
|
567
565
|
function ensureFinalNewline(content) {
|
|
@@ -625,12 +623,6 @@ function parseLandstripConfig(value, path, kind) {
|
|
|
625
623
|
}
|
|
626
624
|
if ("permission" in value)
|
|
627
625
|
config.permission = value.permission;
|
|
628
|
-
if ("toolFilesystemPolicy" in value) {
|
|
629
|
-
if (value.toolFilesystemPolicy !== "host" && value.toolFilesystemPolicy !== "sandbox") {
|
|
630
|
-
throw new Error(`${path}: ${field("toolFilesystemPolicy")} must be host or sandbox`);
|
|
631
|
-
}
|
|
632
|
-
config.toolFilesystemPolicy = value.toolFilesystemPolicy;
|
|
633
|
-
}
|
|
634
626
|
return config;
|
|
635
627
|
}
|
|
636
628
|
function readLandstripConfigSource(cwd, scope, agentDir) {
|
|
@@ -745,23 +737,6 @@ async function setMaxSubagentsConfigForScope(cwd, maxSubagents, scope, agentDir
|
|
|
745
737
|
async function clearMaxSubagentsConfigForScope(cwd, scope, agentDir = getAgentDir()) {
|
|
746
738
|
await writeMaxSubagentsConfigForScope(cwd, undefined, scope, agentDir);
|
|
747
739
|
}
|
|
748
|
-
async function writeToolFilesystemPolicyConfigForScope(cwd, policy, scope, agentDir) {
|
|
749
|
-
await updateLandstripConfigForScope(cwd, scope, agentDir, (landstrip) => {
|
|
750
|
-
if (policy === undefined)
|
|
751
|
-
delete landstrip.toolFilesystemPolicy;
|
|
752
|
-
else
|
|
753
|
-
landstrip.toolFilesystemPolicy = policy;
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
async function setToolFilesystemPolicyConfigForScope(cwd, policy, scope, agentDir = getAgentDir()) {
|
|
757
|
-
if (policy !== "host" && policy !== "sandbox") {
|
|
758
|
-
throw new Error("toolFilesystemPolicy must be host or sandbox");
|
|
759
|
-
}
|
|
760
|
-
await writeToolFilesystemPolicyConfigForScope(cwd, policy, scope, agentDir);
|
|
761
|
-
}
|
|
762
|
-
async function clearToolFilesystemPolicyConfigForScope(cwd, scope, agentDir = getAgentDir()) {
|
|
763
|
-
await writeToolFilesystemPolicyConfigForScope(cwd, undefined, scope, agentDir);
|
|
764
|
-
}
|
|
765
740
|
async function setAgentDisabledForScope(cwd, name, disabled, scope, agentDir = getAgentDir()) {
|
|
766
741
|
await updateLandstripConfigForScope(cwd, scope, agentDir, (landstrip) => {
|
|
767
742
|
if (landstrip.agent !== undefined && !isRecord2(landstrip.agent)) {
|
|
@@ -834,7 +809,6 @@ function loadLandstripConfig(cwd, includeProject = true, agentDir = getAgentDir(
|
|
|
834
809
|
if (projectConfig)
|
|
835
810
|
config = mergeValue(config, projectConfig);
|
|
836
811
|
const maxSubagents = config.maxSubagents ?? 0;
|
|
837
|
-
const toolFilesystemPolicy = config.toolFilesystemPolicy ?? "host";
|
|
838
812
|
if (!Number.isInteger(maxSubagents) || maxSubagents < 0 || maxSubagents > MAX_SUBAGENTS) {
|
|
839
813
|
throw new Error(`maxSubagents must be an integer from 0 to ${MAX_SUBAGENTS}`);
|
|
840
814
|
}
|
|
@@ -844,7 +818,6 @@ function loadLandstripConfig(cwd, includeProject = true, agentDir = getAgentDir(
|
|
|
844
818
|
...config,
|
|
845
819
|
maxSubagents,
|
|
846
820
|
agent: config.agent,
|
|
847
|
-
toolFilesystemPolicy,
|
|
848
821
|
agentSources,
|
|
849
822
|
agentPaths
|
|
850
823
|
};
|
|
@@ -859,16 +832,6 @@ function loadMaxSubagentsSettings(cwd, includeProject = true, agentDir = getAgen
|
|
|
859
832
|
}
|
|
860
833
|
return { global, project };
|
|
861
834
|
}
|
|
862
|
-
function loadToolFilesystemPolicySettings(cwd, includeProject = true, agentDir = getAgentDir()) {
|
|
863
|
-
const global = loadLandstripConfig(cwd, false, agentDir).toolFilesystemPolicy;
|
|
864
|
-
if (!includeProject)
|
|
865
|
-
return { global };
|
|
866
|
-
const project = readLandstripConfigSource(cwd, "project", agentDir).config.toolFilesystemPolicy;
|
|
867
|
-
if (project !== undefined && project !== "host" && project !== "sandbox") {
|
|
868
|
-
throw new Error("toolFilesystemPolicy must be host or sandbox");
|
|
869
|
-
}
|
|
870
|
-
return { global, project };
|
|
871
|
-
}
|
|
872
835
|
|
|
873
836
|
// opencode-agents.ts
|
|
874
837
|
import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync3, statSync } from "node:fs";
|
|
@@ -1121,7 +1084,6 @@ function validateAgentRaw(name, raw) {
|
|
|
1121
1084
|
function loadAgentCatalog(cwd, piAgentDir = getAgentDir2(), includeProject = true) {
|
|
1122
1085
|
const diagnostics = [];
|
|
1123
1086
|
let maxSubagents = 0;
|
|
1124
|
-
let toolFilesystemPolicy = "host";
|
|
1125
1087
|
let configuredAgents = {};
|
|
1126
1088
|
let configuredPermission;
|
|
1127
1089
|
let agentSources = new Map;
|
|
@@ -1129,7 +1091,6 @@ function loadAgentCatalog(cwd, piAgentDir = getAgentDir2(), includeProject = tru
|
|
|
1129
1091
|
try {
|
|
1130
1092
|
const config = loadLandstripConfig(cwd, includeProject, piAgentDir);
|
|
1131
1093
|
maxSubagents = config.maxSubagents;
|
|
1132
|
-
toolFilesystemPolicy = config.toolFilesystemPolicy;
|
|
1133
1094
|
configuredAgents = config.agent;
|
|
1134
1095
|
configuredPermission = config.permission;
|
|
1135
1096
|
agentSources = new Map(config.agentSources);
|
|
@@ -1194,7 +1155,7 @@ function loadAgentCatalog(cwd, piAgentDir = getAgentDir2(), includeProject = tru
|
|
|
1194
1155
|
} catch (error) {
|
|
1195
1156
|
diagnostics.push(formatError(error));
|
|
1196
1157
|
}
|
|
1197
|
-
return { agents: normalized, permissions, diagnostics, maxSubagents
|
|
1158
|
+
return { agents: normalized, permissions, diagnostics, maxSubagents };
|
|
1198
1159
|
}
|
|
1199
1160
|
function permissionMatches(pattern, permission) {
|
|
1200
1161
|
return pattern === "*" || minimatch(permission, pattern, { dot: true });
|
|
@@ -1558,13 +1519,12 @@ var sandboxSubcommand = {
|
|
|
1558
1519
|
};
|
|
1559
1520
|
var settingsSubcommand = {
|
|
1560
1521
|
name: "settings",
|
|
1561
|
-
summary: "Manage concurrency
|
|
1522
|
+
summary: "Manage subagent concurrency settings",
|
|
1562
1523
|
pane: (argv) => argv.rest ? undefined : "settings",
|
|
1563
1524
|
run: (_argv, { ctx }) => {
|
|
1564
1525
|
const projectTrusted = isProjectTrusted(ctx);
|
|
1565
1526
|
const maxSubagents = loadMaxSubagentsSettings(ctx.cwd, projectTrusted);
|
|
1566
|
-
|
|
1567
|
-
ctx.ui.notify(`Settings: maxSubagents=${maxSubagents.project ?? maxSubagents.global} · toolFilesystemPolicy=${policy.project ?? policy.global}`, "info");
|
|
1527
|
+
ctx.ui.notify(`Settings: maxSubagents=${maxSubagents.project ?? maxSubagents.global}`, "info");
|
|
1568
1528
|
}
|
|
1569
1529
|
};
|
|
1570
1530
|
var agentsSubcommand = {
|
|
@@ -3628,7 +3588,6 @@ class SubagentRuntime {
|
|
|
3628
3588
|
primaryRules;
|
|
3629
3589
|
primaryConfigurationError = false;
|
|
3630
3590
|
maxSubagents = 0;
|
|
3631
|
-
toolFilesystemPolicy = "host";
|
|
3632
3591
|
primaryAgentSwitching = false;
|
|
3633
3592
|
shuttingDown = false;
|
|
3634
3593
|
activeSessionId;
|
|
@@ -3736,7 +3695,7 @@ ${this.primaryAgent.prompt}` };
|
|
|
3736
3695
|
}
|
|
3737
3696
|
}
|
|
3738
3697
|
const filesystem = filesystemToolAccesses(event.toolName, input, ctx.cwd);
|
|
3739
|
-
if (this.
|
|
3698
|
+
if (filesystem && typeof this.integration.authorizeFilesystemToolAccess === "function") {
|
|
3740
3699
|
if (!filesystem.valid) {
|
|
3741
3700
|
return { block: true, reason: `Filesystem path unavailable for ${event.toolName}` };
|
|
3742
3701
|
}
|
|
@@ -3822,7 +3781,6 @@ ${this.primaryAgent.prompt}` };
|
|
|
3822
3781
|
refreshDeletableAgents();
|
|
3823
3782
|
let overview = this.integration.sandboxCallbacks?.overview?.(ctx.cwd, projectTrusted);
|
|
3824
3783
|
let maxSubagentsSettings = loadMaxSubagentsSettings(ctx.cwd, projectTrusted);
|
|
3825
|
-
let policySettings = loadToolFilesystemPolicySettings(ctx.cwd, projectTrusted);
|
|
3826
3784
|
let settingsList;
|
|
3827
3785
|
let saving = false;
|
|
3828
3786
|
let confirmingSandboxDisable = false;
|
|
@@ -3935,9 +3893,8 @@ ${this.primaryAgent.prompt}` };
|
|
|
3935
3893
|
const settingValue = (project, global) => project === undefined ? `${global} (global)` : String(project);
|
|
3936
3894
|
const syncSettingsList = () => {
|
|
3937
3895
|
settingsList?.updateValue("maxSubagents", settingValue(maxSubagentsSettings.project, maxSubagentsSettings.global));
|
|
3938
|
-
settingsList?.updateValue("toolFilesystemPolicy", settingValue(policySettings.project, policySettings.global));
|
|
3939
3896
|
};
|
|
3940
|
-
const saveSetting = (
|
|
3897
|
+
const saveSetting = (_id, value) => {
|
|
3941
3898
|
if (!projectTrusted) {
|
|
3942
3899
|
ctx.ui.notify("Project settings require a trusted project", "warning");
|
|
3943
3900
|
syncSettingsList();
|
|
@@ -3945,35 +3902,24 @@ ${this.primaryAgent.prompt}` };
|
|
|
3945
3902
|
}
|
|
3946
3903
|
let save;
|
|
3947
3904
|
let notifyMessage;
|
|
3948
|
-
if (
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
notifyMessage = "Project maxSubagents inherits Global";
|
|
3952
|
-
} else {
|
|
3953
|
-
const parsed = Number(value);
|
|
3954
|
-
if (!/^\d+$/.test(value) || !Number.isSafeInteger(parsed) || parsed < 0 || parsed > MAX_SUBAGENTS) {
|
|
3955
|
-
ctx.ui.notify(`Enter a whole number between 0 and ${MAX_SUBAGENTS}`, "error");
|
|
3956
|
-
syncSettingsList();
|
|
3957
|
-
return;
|
|
3958
|
-
}
|
|
3959
|
-
save = setMaxSubagentsConfigForScope(ctx.cwd, parsed, "project");
|
|
3960
|
-
notifyMessage = `Project maxSubagents = ${parsed}`;
|
|
3961
|
-
}
|
|
3962
|
-
} else if (value === INHERIT) {
|
|
3963
|
-
save = clearToolFilesystemPolicyConfigForScope(ctx.cwd, "project");
|
|
3964
|
-
notifyMessage = "Project toolFilesystemPolicy inherits Global";
|
|
3905
|
+
if (value === INHERIT || value === "") {
|
|
3906
|
+
save = clearMaxSubagentsConfigForScope(ctx.cwd, "project");
|
|
3907
|
+
notifyMessage = "Project maxSubagents inherits global setting";
|
|
3965
3908
|
} else {
|
|
3966
|
-
const
|
|
3967
|
-
|
|
3968
|
-
|
|
3909
|
+
const parsed = Number(value);
|
|
3910
|
+
if (!/^\d+$/.test(value) || !Number.isSafeInteger(parsed) || parsed < 0 || parsed > MAX_SUBAGENTS) {
|
|
3911
|
+
ctx.ui.notify(`Enter a whole number between 0 and ${MAX_SUBAGENTS}`, "error");
|
|
3912
|
+
syncSettingsList();
|
|
3913
|
+
return;
|
|
3914
|
+
}
|
|
3915
|
+
save = setMaxSubagentsConfigForScope(ctx.cwd, parsed, "project");
|
|
3916
|
+
notifyMessage = `Project maxSubagents = ${parsed}`;
|
|
3969
3917
|
}
|
|
3970
3918
|
saving = true;
|
|
3971
3919
|
tui.requestRender();
|
|
3972
3920
|
save.then(() => {
|
|
3973
3921
|
maxSubagentsSettings = loadMaxSubagentsSettings(ctx.cwd, projectTrusted);
|
|
3974
|
-
policySettings = loadToolFilesystemPolicySettings(ctx.cwd, projectTrusted);
|
|
3975
3922
|
this.setMaxSubagents(maxSubagentsSettings.project ?? maxSubagentsSettings.global);
|
|
3976
|
-
this.toolFilesystemPolicy = policySettings.project ?? policySettings.global;
|
|
3977
3923
|
ctx.ui.notify(notifyMessage, "info");
|
|
3978
3924
|
}).catch((error) => ctx.ui.notify(`Could not save setting: ${formatError(error)}`, "error")).finally(() => {
|
|
3979
3925
|
saving = false;
|
|
@@ -3986,7 +3932,7 @@ ${this.primaryAgent.prompt}` };
|
|
|
3986
3932
|
id: "maxSubagents",
|
|
3987
3933
|
label: "Maximum Subagents",
|
|
3988
3934
|
currentValue: settingValue(maxSubagentsSettings.project, maxSubagentsSettings.global),
|
|
3989
|
-
description: "Concurrent subagent tasks. Enter to edit, empty to inherit
|
|
3935
|
+
description: "Concurrent subagent tasks. Enter to edit, empty to inherit global setting.",
|
|
3990
3936
|
submenu: (_currentValue, doneEditing) => {
|
|
3991
3937
|
const input = new Input;
|
|
3992
3938
|
input.focused = true;
|
|
@@ -3998,38 +3944,6 @@ ${this.primaryAgent.prompt}` };
|
|
|
3998
3944
|
input.onEscape = () => doneEditing(undefined);
|
|
3999
3945
|
return input;
|
|
4000
3946
|
}
|
|
4001
|
-
},
|
|
4002
|
-
{
|
|
4003
|
-
id: "toolFilesystemPolicy",
|
|
4004
|
-
label: "Filesystem Tool Policy",
|
|
4005
|
-
currentValue: settingValue(policySettings.project, policySettings.global),
|
|
4006
|
-
description: "How file tools resolve paths. Enter to choose.",
|
|
4007
|
-
submenu: (_currentValue, doneEditing) => {
|
|
4008
|
-
const options = [
|
|
4009
|
-
{
|
|
4010
|
-
value: INHERIT,
|
|
4011
|
-
label: "inherit",
|
|
4012
|
-
description: `Use Global (${policySettings.global})`
|
|
4013
|
-
},
|
|
4014
|
-
{ value: "host", label: "host", description: "Resolve paths on the host" },
|
|
4015
|
-
{
|
|
4016
|
-
value: "sandbox",
|
|
4017
|
-
label: "sandbox",
|
|
4018
|
-
description: "Resolve paths inside the sandbox"
|
|
4019
|
-
}
|
|
4020
|
-
];
|
|
4021
|
-
const list = new SelectList(options, options.length, {
|
|
4022
|
-
selectedPrefix: (text) => theme.fg("accent", text),
|
|
4023
|
-
selectedText: (text) => theme.fg("accent", text),
|
|
4024
|
-
description: (text) => theme.fg("dim", text),
|
|
4025
|
-
scrollInfo: (text) => theme.fg("dim", text),
|
|
4026
|
-
noMatch: (text) => theme.fg("dim", text)
|
|
4027
|
-
});
|
|
4028
|
-
list.setSelectedIndex(options.findIndex((option) => option.value === (policySettings.project ?? INHERIT)));
|
|
4029
|
-
list.onSelect = (item) => doneEditing(item.value);
|
|
4030
|
-
list.onCancel = () => doneEditing(undefined);
|
|
4031
|
-
return list;
|
|
4032
|
-
}
|
|
4033
3947
|
}
|
|
4034
3948
|
];
|
|
4035
3949
|
settingsList = new SettingsList(items, INSPECTOR_BODY_LINES, {
|
|
@@ -6296,7 +6210,6 @@ ${renderTaskResult(task.id, failed ? "error" : "completed", value)}`;
|
|
|
6296
6210
|
this.primaryConfigurationError = false;
|
|
6297
6211
|
const catalog = this.loadCatalog(ctx.cwd, getAgentDir4(), isProjectTrusted(ctx));
|
|
6298
6212
|
this.maxSubagents = catalog.maxSubagents;
|
|
6299
|
-
this.toolFilesystemPolicy = catalog.toolFilesystemPolicy;
|
|
6300
6213
|
this.semaphore = new Semaphore(this.maxSubagents);
|
|
6301
6214
|
if (catalog.diagnostics.length > 0) {
|
|
6302
6215
|
this.invalidatePrimaryAgent(catalog, ctx);
|
|
@@ -6365,7 +6278,6 @@ ${renderTaskResult(task.id, failed ? "error" : "completed", value)}`;
|
|
|
6365
6278
|
return false;
|
|
6366
6279
|
this.primaryAgent = agent;
|
|
6367
6280
|
this.primaryRules = mergePermissionRules(catalog.permissions, agent.permissions);
|
|
6368
|
-
this.toolFilesystemPolicy = catalog.toolFilesystemPolicy;
|
|
6369
6281
|
this.primaryConfigurationError = false;
|
|
6370
6282
|
this.broker.reset();
|
|
6371
6283
|
this.pi.registerTool(this.createTaskTool(undefined, this.primaryRules, ctx));
|
|
@@ -7087,8 +6999,16 @@ function createLandstripIntegrationWithPrompts(options, permissionPrompts) {
|
|
|
7087
6999
|
return [`${access.operation}\x00${path}`, { ...access, path }];
|
|
7088
7000
|
})).values()
|
|
7089
7001
|
];
|
|
7002
|
+
if (getNoSandboxFlag())
|
|
7003
|
+
return { allowed: true, prompted: false };
|
|
7004
|
+
const blockedAccesses = (config) => {
|
|
7005
|
+
const enforceReads = enforcesShellReadPolicy(config.shell.readAccess);
|
|
7006
|
+
return normalized.filter((access) => access.operation === "read" ? enforceReads && !readAllowed(access.path, getEffectiveAllowRead(config, ctx.cwd), getEffectiveDenyRead(config, ctx.cwd), ctx.cwd) : shouldPromptForWrite(access.path, getEffectiveAllowWrite(config), ctx.cwd));
|
|
7007
|
+
};
|
|
7090
7008
|
const current = () => {
|
|
7091
7009
|
const config = loadConfig(ctx.cwd);
|
|
7010
|
+
if (!config.enabled)
|
|
7011
|
+
return { allowed: true, prompted: false };
|
|
7092
7012
|
for (const access of normalized) {
|
|
7093
7013
|
if (matchesPattern(access.path, access.operation === "read" ? config.filesystem.denyReadAlways : mergeArray(config.filesystem.denyWriteAlways, config.filesystem.denyWrite), ctx.cwd)) {
|
|
7094
7014
|
return {
|
|
@@ -7098,8 +7018,7 @@ function createLandstripIntegrationWithPrompts(options, permissionPrompts) {
|
|
|
7098
7018
|
};
|
|
7099
7019
|
}
|
|
7100
7020
|
}
|
|
7101
|
-
|
|
7102
|
-
return blocked.length === 0 ? { allowed: true, prompted: false } : undefined;
|
|
7021
|
+
return blockedAccesses(config).length === 0 ? { allowed: true, prompted: false } : undefined;
|
|
7103
7022
|
};
|
|
7104
7023
|
const existing = current();
|
|
7105
7024
|
if (existing)
|
|
@@ -7108,8 +7027,7 @@ function createLandstripIntegrationWithPrompts(options, permissionPrompts) {
|
|
|
7108
7027
|
return { allowed: false, prompted: false, reason: "Filesystem access requires approval" };
|
|
7109
7028
|
}
|
|
7110
7029
|
return permissionPrompts.resolve(current, async (promptSignal) => {
|
|
7111
|
-
const
|
|
7112
|
-
const blocked = normalized.filter((access) => access.operation === "read" ? !readAllowed(access.path, getEffectiveAllowRead(config, ctx.cwd), getEffectiveDenyRead(config, ctx.cwd), ctx.cwd) : shouldPromptForWrite(access.path, getEffectiveAllowWrite(config), ctx.cwd));
|
|
7030
|
+
const blocked = blockedAccesses(loadConfig(ctx.cwd));
|
|
7113
7031
|
const paths = blocked.map(({ operation, path }) => `${operation}: ${path}`).join(`
|
|
7114
7032
|
`);
|
|
7115
7033
|
const note = options.authorizationNote ? `
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-landstrip",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.2",
|
|
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-api": "^0.20.
|
|
42
|
+
"@landstrip/landstrip-api": "^0.20.2",
|
|
43
43
|
"jsonc-parser": "^3.3.1",
|
|
44
44
|
"minimatch": "^10.2.5",
|
|
45
45
|
"undici": "^8.9.0",
|