pi-landstrip 0.18.42 → 0.18.43
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/api.ts +12 -14
- package/dist/index.ts +149 -132
- package/package.json +2 -2
package/api.ts
CHANGED
|
@@ -213,13 +213,13 @@ export function useLandstrip(
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
|
|
216
|
+
function provideExtensionProvider(
|
|
217
217
|
pi: ExtensionAPI,
|
|
218
|
-
|
|
218
|
+
register: (runtime: PiLandstripRuntimeV2) => () => void,
|
|
219
219
|
): () => void {
|
|
220
220
|
let unregisterProvider: (() => void) | undefined;
|
|
221
221
|
const stopDiscovery = useLandstrip(pi, (runtime) => {
|
|
222
|
-
const unregisterNext = runtime
|
|
222
|
+
const unregisterNext = register(runtime);
|
|
223
223
|
unregisterProvider?.();
|
|
224
224
|
unregisterProvider = unregisterNext;
|
|
225
225
|
});
|
|
@@ -229,20 +229,18 @@ export function provideLandstripShell(
|
|
|
229
229
|
};
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
+
export function provideLandstripShell(
|
|
233
|
+
pi: ExtensionAPI,
|
|
234
|
+
provider: LandstripShellProvider,
|
|
235
|
+
): () => void {
|
|
236
|
+
return provideExtensionProvider(pi, (runtime) => runtime.registerShellProvider(provider));
|
|
237
|
+
}
|
|
238
|
+
|
|
232
239
|
export function provideLandstripPermissionAsk(
|
|
233
240
|
pi: ExtensionAPI,
|
|
234
241
|
provider: LandstripPermissionAskProvider,
|
|
235
242
|
): () => void {
|
|
236
|
-
|
|
237
|
-
const stopDiscovery = useLandstrip(pi, (runtime) => {
|
|
238
|
-
const unregisterNext = runtime.registerPermissionAskProvider(provider);
|
|
239
|
-
unregisterProvider?.();
|
|
240
|
-
unregisterProvider = unregisterNext;
|
|
241
|
-
});
|
|
242
|
-
return () => {
|
|
243
|
-
stopDiscovery();
|
|
244
|
-
unregisterProvider?.();
|
|
245
|
-
};
|
|
243
|
+
return provideExtensionProvider(pi, (runtime) => runtime.registerPermissionAskProvider(provider));
|
|
246
244
|
}
|
|
247
245
|
|
|
248
246
|
export function publishLandstripRuntime(
|
|
@@ -288,7 +286,7 @@ export function contextFromEnvironment(
|
|
|
288
286
|
!['enabled', 'disabled', 'unavailable'].includes(String(value.sandbox)) ||
|
|
289
287
|
typeof value.cwd !== 'string' ||
|
|
290
288
|
!Number.isInteger(value.depth) ||
|
|
291
|
-
|
|
289
|
+
(value.depth as number) < 0 ||
|
|
292
290
|
['sessionId', 'taskId', 'parentTaskId', 'agent'].some(
|
|
293
291
|
(key) => value[key] !== undefined && typeof value[key] !== 'string',
|
|
294
292
|
)
|
package/dist/index.ts
CHANGED
|
@@ -111,10 +111,11 @@ import {
|
|
|
111
111
|
SelectList,
|
|
112
112
|
SettingsList,
|
|
113
113
|
Text,
|
|
114
|
-
truncateToWidth
|
|
115
|
-
visibleWidth
|
|
114
|
+
truncateToWidth,
|
|
115
|
+
visibleWidth,
|
|
116
116
|
wrapTextWithAnsi
|
|
117
117
|
} from "@earendil-works/pi-tui";
|
|
118
|
+
import { canonicalizeHost } from "@landstrip/landstrip-api/shared";
|
|
118
119
|
import { Type } from "typebox";
|
|
119
120
|
|
|
120
121
|
// agents.ts
|
|
@@ -133,78 +134,6 @@ import {
|
|
|
133
134
|
printParseErrorCode
|
|
134
135
|
} from "jsonc-parser";
|
|
135
136
|
|
|
136
|
-
// built-in-agents.ts
|
|
137
|
-
var BUILT_IN_LANDSTRIP_CONFIG = {
|
|
138
|
-
maxSubagents: 0,
|
|
139
|
-
toolFilesystemPolicy: "host",
|
|
140
|
-
agent: {
|
|
141
|
-
build: {
|
|
142
|
-
description: "Implement and test requested changes",
|
|
143
|
-
mode: "primary",
|
|
144
|
-
color: "success",
|
|
145
|
-
prompt: "Implement, test, and complete the request."
|
|
146
|
-
},
|
|
147
|
-
plan: {
|
|
148
|
-
description: "Plan before running commands or editing files",
|
|
149
|
-
mode: "primary",
|
|
150
|
-
color: "warning",
|
|
151
|
-
prompt: "Analyze the request and produce a clear plan before making changes.",
|
|
152
|
-
permission: { edit: "ask", bash: "ask", task: "ask" }
|
|
153
|
-
},
|
|
154
|
-
general: {
|
|
155
|
-
description: "General-purpose agent for complex tasks",
|
|
156
|
-
mode: "subagent",
|
|
157
|
-
prompt: "Complete the task and return a concise result.",
|
|
158
|
-
permission: { todowrite: "deny" }
|
|
159
|
-
},
|
|
160
|
-
scout: {
|
|
161
|
-
description: "Read-only codebase reconnaissance",
|
|
162
|
-
mode: "subagent",
|
|
163
|
-
prompt: "Inspect the codebase without editing. Return concise findings with exact file references and a recommended starting point.",
|
|
164
|
-
permission: {
|
|
165
|
-
"*": "deny",
|
|
166
|
-
read: {
|
|
167
|
-
"*": "allow",
|
|
168
|
-
"**/*.env": "ask",
|
|
169
|
-
"**/*.env.*": "ask",
|
|
170
|
-
"**/*.env.example": "allow"
|
|
171
|
-
},
|
|
172
|
-
glob: "allow",
|
|
173
|
-
grep: "allow",
|
|
174
|
-
list: "allow"
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
explore: {
|
|
178
|
-
description: "Codebase research with shell and web access",
|
|
179
|
-
mode: "subagent",
|
|
180
|
-
prompt: "Explore without editing. Use shell or web tools when needed, then return concise findings with file references.",
|
|
181
|
-
permission: {
|
|
182
|
-
"*": "deny",
|
|
183
|
-
read: {
|
|
184
|
-
"*": "allow",
|
|
185
|
-
"**/*.env": "ask",
|
|
186
|
-
"**/*.env.*": "ask",
|
|
187
|
-
"**/*.env.example": "allow"
|
|
188
|
-
},
|
|
189
|
-
glob: "allow",
|
|
190
|
-
grep: "allow",
|
|
191
|
-
list: "allow",
|
|
192
|
-
bash: "allow",
|
|
193
|
-
webfetch: "allow",
|
|
194
|
-
websearch: "allow"
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
},
|
|
198
|
-
permission: {
|
|
199
|
-
"*": "allow",
|
|
200
|
-
read: {
|
|
201
|
-
"**/*.env": "ask",
|
|
202
|
-
"**/*.env.*": "ask",
|
|
203
|
-
"**/*.env.example": "allow"
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
137
|
// util.ts
|
|
209
138
|
import { readFileSync } from "node:fs";
|
|
210
139
|
import { homedir } from "node:os";
|
|
@@ -410,6 +339,76 @@ class PermissionPromptCoordinator {
|
|
|
410
339
|
}
|
|
411
340
|
|
|
412
341
|
// config.ts
|
|
342
|
+
var BUILT_IN_LANDSTRIP_CONFIG = {
|
|
343
|
+
maxSubagents: 0,
|
|
344
|
+
toolFilesystemPolicy: "host",
|
|
345
|
+
agent: {
|
|
346
|
+
build: {
|
|
347
|
+
description: "Implement and test requested changes",
|
|
348
|
+
mode: "primary",
|
|
349
|
+
color: "success",
|
|
350
|
+
prompt: "Implement, test, and complete the request."
|
|
351
|
+
},
|
|
352
|
+
plan: {
|
|
353
|
+
description: "Plan before running commands or editing files",
|
|
354
|
+
mode: "primary",
|
|
355
|
+
color: "warning",
|
|
356
|
+
prompt: "Analyze the request and produce a clear plan before making changes.",
|
|
357
|
+
permission: { edit: "ask", bash: "ask", task: "ask" }
|
|
358
|
+
},
|
|
359
|
+
general: {
|
|
360
|
+
description: "General-purpose agent for complex tasks",
|
|
361
|
+
mode: "subagent",
|
|
362
|
+
prompt: "Complete the task and return a concise result.",
|
|
363
|
+
permission: { todowrite: "deny" }
|
|
364
|
+
},
|
|
365
|
+
scout: {
|
|
366
|
+
description: "Read-only codebase reconnaissance",
|
|
367
|
+
mode: "subagent",
|
|
368
|
+
prompt: "Inspect the codebase without editing. Return concise findings with exact file references and a recommended starting point.",
|
|
369
|
+
permission: {
|
|
370
|
+
"*": "deny",
|
|
371
|
+
read: {
|
|
372
|
+
"*": "allow",
|
|
373
|
+
"**/*.env": "ask",
|
|
374
|
+
"**/*.env.*": "ask",
|
|
375
|
+
"**/*.env.example": "allow"
|
|
376
|
+
},
|
|
377
|
+
glob: "allow",
|
|
378
|
+
grep: "allow",
|
|
379
|
+
list: "allow"
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
explore: {
|
|
383
|
+
description: "Codebase research with shell and web access",
|
|
384
|
+
mode: "subagent",
|
|
385
|
+
prompt: "Explore without editing. Use shell or web tools when needed, then return concise findings with file references.",
|
|
386
|
+
permission: {
|
|
387
|
+
"*": "deny",
|
|
388
|
+
read: {
|
|
389
|
+
"*": "allow",
|
|
390
|
+
"**/*.env": "ask",
|
|
391
|
+
"**/*.env.*": "ask",
|
|
392
|
+
"**/*.env.example": "allow"
|
|
393
|
+
},
|
|
394
|
+
glob: "allow",
|
|
395
|
+
grep: "allow",
|
|
396
|
+
list: "allow",
|
|
397
|
+
bash: "allow",
|
|
398
|
+
webfetch: "allow",
|
|
399
|
+
websearch: "allow"
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
},
|
|
403
|
+
permission: {
|
|
404
|
+
"*": "allow",
|
|
405
|
+
read: {
|
|
406
|
+
"**/*.env": "ask",
|
|
407
|
+
"**/*.env.*": "ask",
|
|
408
|
+
"**/*.env.example": "allow"
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
};
|
|
413
412
|
function isProjectTrusted(ctx) {
|
|
414
413
|
const trustContext = ctx;
|
|
415
414
|
return trustContext.isProjectTrusted?.() ?? false;
|
|
@@ -1286,7 +1285,7 @@ function prepareProjectAgentEditor(cwd, agent, agentDir = getAgentDir3()) {
|
|
|
1286
1285
|
}
|
|
1287
1286
|
const sourcePath = origin?.path;
|
|
1288
1287
|
const sourceRaw = origin?.kind === "config" && sourcePath ? readAgentNode(sourcePath, basename(sourcePath) === "landstrip.json" ? "dedicated" : "settings", agent.name) : undefined;
|
|
1289
|
-
const raw = relocateGlobalPrompt(sourceRaw
|
|
1288
|
+
const raw = relocateGlobalPrompt(sourceRaw ?? (agent.raw ? { ...agent.raw } : normalizedAgentRaw(agent)), agent);
|
|
1290
1289
|
const target = getLandstripConfigTarget(cwd, "project", agentDir);
|
|
1291
1290
|
return {
|
|
1292
1291
|
title: `Edit @${agent.name}`,
|
|
@@ -1300,28 +1299,6 @@ function prepareProjectAgentEditor(cwd, agent, agentDir = getAgentDir3()) {
|
|
|
1300
1299
|
};
|
|
1301
1300
|
}
|
|
1302
1301
|
|
|
1303
|
-
// box.ts
|
|
1304
|
-
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
1305
|
-
function dialogTabs(theme, tabs, active) {
|
|
1306
|
-
return tabs.map((tab) => tab === active ? theme.fg("accent", theme.bold(`[${tab}]`)) : theme.fg("muted", tab)).join(" ");
|
|
1307
|
-
}
|
|
1308
|
-
function dialogKeys(theme, hints) {
|
|
1309
|
-
const separator = theme.fg("dim", " · ");
|
|
1310
|
-
return hints.map(([key, description]) => `${theme.fg("accent", key)} ${theme.fg("muted", description)}`).join(separator);
|
|
1311
|
-
}
|
|
1312
|
-
function paneTop(theme, width, title) {
|
|
1313
|
-
if (width < 3)
|
|
1314
|
-
return truncateToWidth(theme.fg("accent", title), Math.max(1, width));
|
|
1315
|
-
const label = theme.fg("accent", theme.bold(` ${title} `));
|
|
1316
|
-
return `${label}${theme.fg("border", "─".repeat(Math.max(0, width - visibleWidth(label))))}`;
|
|
1317
|
-
}
|
|
1318
|
-
function paneRow(_theme, width, content = "") {
|
|
1319
|
-
if (width < 2)
|
|
1320
|
-
return " ".repeat(Math.max(0, width));
|
|
1321
|
-
const line = truncateToWidth(content, Math.max(1, width - 2));
|
|
1322
|
-
return ` ${line}${" ".repeat(Math.max(0, width - visibleWidth(line) - 1))}`;
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
1302
|
// commands.ts
|
|
1326
1303
|
import { fuzzyFilter } from "@earendil-works/pi-tui";
|
|
1327
1304
|
var DEFAULT_SUBCOMMAND = "status";
|
|
@@ -2017,6 +1994,25 @@ function listRowBudget(terminalRows, floor, chrome) {
|
|
|
2017
1994
|
return floor;
|
|
2018
1995
|
return Math.max(floor, Math.floor(terminalRows * OVERLAY_HEIGHT_RATIO) - chrome);
|
|
2019
1996
|
}
|
|
1997
|
+
function dialogTabs(theme, tabs, active) {
|
|
1998
|
+
return tabs.map((tab) => tab === active ? theme.fg("accent", theme.bold(`[${tab}]`)) : theme.fg("muted", tab)).join(" ");
|
|
1999
|
+
}
|
|
2000
|
+
function dialogKeys(theme, hints) {
|
|
2001
|
+
const separator = theme.fg("dim", " · ");
|
|
2002
|
+
return hints.map(([key, description]) => `${theme.fg("accent", key)} ${theme.fg("muted", description)}`).join(separator);
|
|
2003
|
+
}
|
|
2004
|
+
function paneTop(theme, width, title) {
|
|
2005
|
+
if (width < 3)
|
|
2006
|
+
return truncateToWidth(theme.fg("accent", title), Math.max(1, width));
|
|
2007
|
+
const label = theme.fg("accent", theme.bold(` ${title} `));
|
|
2008
|
+
return `${label}${theme.fg("border", "─".repeat(Math.max(0, width - visibleWidth(label))))}`;
|
|
2009
|
+
}
|
|
2010
|
+
function paneRow(_theme, width, content = "") {
|
|
2011
|
+
if (width < 2)
|
|
2012
|
+
return " ".repeat(Math.max(0, width));
|
|
2013
|
+
const line = truncateToWidth(content, Math.max(1, width - 2));
|
|
2014
|
+
return ` ${line}${" ".repeat(Math.max(0, width - visibleWidth(line) - 1))}`;
|
|
2015
|
+
}
|
|
2020
2016
|
var PI_THINKING_LEVELS = new Set(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
2021
2017
|
var AGENTS_HELP_ROWS = [
|
|
2022
2018
|
["Tab", "Next tab"],
|
|
@@ -2417,8 +2413,27 @@ function dependencyRoot(path) {
|
|
|
2417
2413
|
const index = path.lastIndexOf(marker);
|
|
2418
2414
|
return index < 0 ? undefined : path.slice(0, index + marker.length - 1);
|
|
2419
2415
|
}
|
|
2416
|
+
function endpointHost(baseUrl) {
|
|
2417
|
+
if (!baseUrl)
|
|
2418
|
+
return;
|
|
2419
|
+
try {
|
|
2420
|
+
return canonicalizeHost(new URL(baseUrl).hostname) ?? undefined;
|
|
2421
|
+
} catch {
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
function modelEndpointDomains(ctx, selectedModel) {
|
|
2426
|
+
const models = ctx.modelRegistry?.getAll() ?? [];
|
|
2427
|
+
const qualified = models.find((model) => `${model.provider}/${model.id}` === selectedModel);
|
|
2428
|
+
const byId = models.filter((model) => model.id === selectedModel);
|
|
2429
|
+
const registered = qualified ?? (byId.length === 1 ? byId[0] : undefined);
|
|
2430
|
+
const activeName = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined;
|
|
2431
|
+
const active = selectedModel === activeName || selectedModel === ctx.model?.id ? ctx.model : undefined;
|
|
2432
|
+
const host = endpointHost(registered?.baseUrl ?? active?.baseUrl);
|
|
2433
|
+
return host ? [host] : [];
|
|
2434
|
+
}
|
|
2420
2435
|
function agentBootstrapPaths(agentDir) {
|
|
2421
|
-
|
|
2436
|
+
const entries = [
|
|
2422
2437
|
"settings.json",
|
|
2423
2438
|
"landstrip.json",
|
|
2424
2439
|
"models.json",
|
|
@@ -2435,7 +2450,8 @@ function agentBootstrapPaths(agentDir) {
|
|
|
2435
2450
|
"bin",
|
|
2436
2451
|
"npm",
|
|
2437
2452
|
"git"
|
|
2438
|
-
]
|
|
2453
|
+
];
|
|
2454
|
+
return [agentDir, ...entries.map((entry) => join6(agentDir, entry))];
|
|
2439
2455
|
}
|
|
2440
2456
|
|
|
2441
2457
|
class Semaphore {
|
|
@@ -3273,7 +3289,7 @@ ${this.primaryAgent.prompt}` };
|
|
|
3273
3289
|
const listedAgents = agentsForTab();
|
|
3274
3290
|
const agentRows = listRowBudget(tui.terminal?.rows, AGENT_LIST_ROWS, AGENT_TAB_CHROME_ROWS);
|
|
3275
3291
|
const { shown, start, status } = listWindow(listedAgents, selectedAgent, agentRows);
|
|
3276
|
-
const nameWidth = Math.min(20, Math.max(5, ...listedAgents.map((agent2) =>
|
|
3292
|
+
const nameWidth = Math.min(20, Math.max(5, ...listedAgents.map((agent2) => visibleWidth(`@${agent2.name}`))));
|
|
3277
3293
|
const modelWidth = Math.max(10, Math.min(24, Math.floor((contentWidth - 2) / 3)));
|
|
3278
3294
|
const enabledWidth = 13;
|
|
3279
3295
|
const runtimeWidth = Math.max(12, contentWidth - 2 - nameWidth - 1 - modelWidth - 1 - enabledWidth - 1);
|
|
@@ -3492,7 +3508,7 @@ ${this.primaryAgent.prompt}` };
|
|
|
3492
3508
|
const shellReadMode = overview.windowsMode !== undefined ? "Policy (required)" : overview.shellReadMode === "host" ? "Host-aligned" : "Policy";
|
|
3493
3509
|
const changePath = overview.changeScope === "project" ? overview.paths.project : overview.paths.global;
|
|
3494
3510
|
const item = (label, value) => ` ${theme.fg("dim", label.padEnd(16))} ${value}`;
|
|
3495
|
-
lines.push(`${theme.fg(status.color, "●")} ${theme.fg("text", status.label)}`, item("Configured", overview.enabled ? theme.fg("text", "Enabled") : theme.fg("warning", "Disabled")), item("Runtime", overview.running ? theme.fg("success", "Running") : theme.fg("dim", "Not running")), "", theme.fg("accent", "Protection"), item("Network", networkMode), item("Shell reads", shellReadMode), item("Read rules", `${overview.config.filesystem.denyRead.length + overview.config.filesystem.allowRead.length} · ${overview.readRuleScope}`), item("Write rules", String(overview.config.filesystem.allowWrite.length + overview.config.filesystem.denyWrite.length)), item("Session grants", String(overview.sessionDomains.length + overview.sessionReadPaths.length + overview.sessionWritePaths.length)), "", theme.fg("accent", "Configuration"), item("Change scope", overview.changeScope === "project" ? "Project" : "Global"), item("Change file",
|
|
3511
|
+
lines.push(`${theme.fg(status.color, "●")} ${theme.fg("text", status.label)}`, item("Configured", overview.enabled ? theme.fg("text", "Enabled") : theme.fg("warning", "Disabled")), item("Runtime", overview.running ? theme.fg("success", "Running") : theme.fg("dim", "Not running")), "", theme.fg("accent", "Protection"), item("Network", networkMode), item("Shell reads", shellReadMode), item("Read rules", `${overview.config.filesystem.denyRead.length + overview.config.filesystem.allowRead.length} · ${overview.readRuleScope}`), item("Write rules", String(overview.config.filesystem.allowWrite.length + overview.config.filesystem.denyWrite.length)), item("Session grants", String(overview.sessionDomains.length + overview.sessionReadPaths.length + overview.sessionWritePaths.length)), "", theme.fg("accent", "Configuration"), item("Change scope", overview.changeScope === "project" ? "Project" : "Global"), item("Change file", truncateToWidth(changePath, Math.max(10, contentWidth - 20))), item("Project file", truncateToWidth(overview.paths.project, Math.max(10, contentWidth - 20))), item("Global file", truncateToWidth(overview.paths.global, Math.max(10, contentWidth - 20))), item("Landstrip binary", truncateToWidth(overview.paths.binary, Math.max(10, contentWidth - 20))));
|
|
3496
3512
|
if (overview.windowsMode !== undefined)
|
|
3497
3513
|
lines.push(item("Windows mode", overview.windowsMode));
|
|
3498
3514
|
lines.push("", theme.fg("accent", "Network"), item("Allowed domains", listValue(overview.config.network.allowedDomains)), item("Denied domains", listValue(overview.config.network.deniedDomains)), item("Unix sockets", overview.config.network.allowAllUnixSockets ? "all" : listValue(overview.config.network.allowUnixSockets)), "", theme.fg("accent", "Filesystem"), item("Shell reads", shellReadMode), item("Read rules for", overview.readRuleScope), item("Denied reads", listValue(overview.config.filesystem.denyRead)), item("Allowed reads", listValue(overview.config.filesystem.allowRead)), item("Allowed writes", listValue(overview.config.filesystem.allowWrite)), item("Denied writes", listValue(overview.config.filesystem.denyWrite)), "", theme.fg("accent", "Session grants"), item("Domains", listValue(overview.sessionDomains)), item("Read paths", listValue(overview.sessionReadPaths)), item("Write paths", listValue(overview.sessionWritePaths)));
|
|
@@ -3597,7 +3613,7 @@ ${this.primaryAgent.prompt}` };
|
|
|
3597
3613
|
lines.push(theme.fg("dim", `${scroll + 1}–${scroll + shown.length} of ${transcript.length}`));
|
|
3598
3614
|
}
|
|
3599
3615
|
if (steering) {
|
|
3600
|
-
const input = steering.render(Math.max(2, contentWidth -
|
|
3616
|
+
const input = steering.render(Math.max(2, contentWidth - visibleWidth("Steer ")))[0] ?? "";
|
|
3601
3617
|
lines.push(`${theme.fg("accent", "Steer")} ${input.replace(/^>/, "›")}`);
|
|
3602
3618
|
} else if (task.state === "queued" || task.state === "running") {
|
|
3603
3619
|
lines.push(dialogKeys(theme, [
|
|
@@ -3606,17 +3622,17 @@ ${this.primaryAgent.prompt}` };
|
|
|
3606
3622
|
["Esc", "tasks"]
|
|
3607
3623
|
]));
|
|
3608
3624
|
}
|
|
3609
|
-
return pane(lines.map((line) =>
|
|
3625
|
+
return pane(lines.map((line) => truncateToWidth(line, contentWidth)));
|
|
3610
3626
|
},
|
|
3611
3627
|
help: (frame) => {
|
|
3612
3628
|
const { tabs, pane, contentWidth, pad } = frame;
|
|
3613
|
-
const shortcutWidth = Math.max(
|
|
3629
|
+
const shortcutWidth = Math.max(visibleWidth("Shortcut"), ...AGENTS_HELP_ROWS.map(([shortcut]) => visibleWidth(shortcut)));
|
|
3614
3630
|
const descriptionWidth = Math.max(1, contentWidth - shortcutWidth - 4);
|
|
3615
3631
|
const lines = [
|
|
3616
3632
|
tabs,
|
|
3617
3633
|
"",
|
|
3618
3634
|
theme.fg("dim", ` ${pad("Shortcut", shortcutWidth)} Description`),
|
|
3619
|
-
...AGENTS_HELP_ROWS.map(([shortcut, description]) => ` ${theme.fg("accent", pad(shortcut, shortcutWidth))} ${theme.fg("text",
|
|
3635
|
+
...AGENTS_HELP_ROWS.map(([shortcut, description]) => ` ${theme.fg("accent", pad(shortcut, shortcutWidth))} ${theme.fg("text", truncateToWidth(description, descriptionWidth))}`)
|
|
3620
3636
|
];
|
|
3621
3637
|
return pane(lines);
|
|
3622
3638
|
}
|
|
@@ -3819,12 +3835,12 @@ ${this.primaryAgent.prompt}` };
|
|
|
3819
3835
|
return rows.slice(0, paneHeight);
|
|
3820
3836
|
};
|
|
3821
3837
|
const pad = (value, cellWidth) => {
|
|
3822
|
-
const clipped =
|
|
3823
|
-
return `${clipped}${" ".repeat(Math.max(0, cellWidth -
|
|
3838
|
+
const clipped = truncateToWidth(value, cellWidth);
|
|
3839
|
+
return `${clipped}${" ".repeat(Math.max(0, cellWidth - visibleWidth(clipped)))}`;
|
|
3824
3840
|
};
|
|
3825
3841
|
const listValue = (values) => {
|
|
3826
3842
|
const value = values.join(", ") || "none";
|
|
3827
|
-
return
|
|
3843
|
+
return truncateToWidth(value, Math.max(10, contentWidth - 20));
|
|
3828
3844
|
};
|
|
3829
3845
|
refreshTasks();
|
|
3830
3846
|
const tabs = dialogTabs(theme, TAB_ORDER.map((key) => TAB_LABELS[key]), TAB_LABELS[tab]);
|
|
@@ -4443,6 +4459,7 @@ ${catalog.diagnostics.join(`
|
|
|
4443
4459
|
TEMP: temp
|
|
4444
4460
|
},
|
|
4445
4461
|
ctx,
|
|
4462
|
+
domains: modelEndpointDomains(ctx, model),
|
|
4446
4463
|
readPaths: [
|
|
4447
4464
|
...new Set([
|
|
4448
4465
|
ctx.cwd,
|
|
@@ -4737,15 +4754,15 @@ ${renderTaskResult(task.id, "error", message)}`);
|
|
|
4737
4754
|
const progress = taskProgress(record);
|
|
4738
4755
|
const suffix = progress.length > 0 ? theme.fg("dim", ` · ${progress.join(" · ")}`) : "";
|
|
4739
4756
|
const indentWidth = 3 + Math.max(0, record.depth) * 3;
|
|
4740
|
-
const descriptionWidth = Math.max(1, width - indentWidth -
|
|
4741
|
-
const description = theme.fg("text",
|
|
4757
|
+
const descriptionWidth = Math.max(1, width - indentWidth - visibleWidth(`${state} ${agent} ${suffix}`));
|
|
4758
|
+
const description = theme.fg("text", truncateToWidth(task.description, descriptionWidth));
|
|
4742
4759
|
return `${state} ${agent} ${description}${suffix}`;
|
|
4743
4760
|
});
|
|
4744
4761
|
const shown = tree.slice(0, 8);
|
|
4745
4762
|
if (tree.length > shown.length) {
|
|
4746
4763
|
shown.push(theme.fg("dim", ` … ${tree.length - shown.length} more`));
|
|
4747
4764
|
}
|
|
4748
|
-
return [header, ...shown].map((line) =>
|
|
4765
|
+
return [header, ...shown].map((line) => truncateToWidth(line, Math.max(1, width)));
|
|
4749
4766
|
},
|
|
4750
4767
|
invalidate() {}
|
|
4751
4768
|
}));
|
|
@@ -5981,7 +5998,7 @@ ${paths}${note}`, PERMISSION_OPTIONS, promptSignal);
|
|
|
5981
5998
|
return prepareUnsandboxedRpcWorker(options2);
|
|
5982
5999
|
}
|
|
5983
6000
|
const allowances = {
|
|
5984
|
-
domains: [],
|
|
6001
|
+
domains: [...options2.domains ?? []],
|
|
5985
6002
|
readPaths: [...options2.readPaths],
|
|
5986
6003
|
writePaths: [...options2.writePaths],
|
|
5987
6004
|
targets: []
|
|
@@ -6821,25 +6838,25 @@ ${message}
|
|
|
6821
6838
|
return integration;
|
|
6822
6839
|
}
|
|
6823
6840
|
export {
|
|
6824
|
-
|
|
6825
|
-
shouldPromptForWrite,
|
|
6826
|
-
sessionScopeFor,
|
|
6827
|
-
resolveProcessReadPolicy,
|
|
6828
|
-
readAllowed,
|
|
6829
|
-
parseTrapLine,
|
|
6830
|
-
matchesPattern,
|
|
6831
|
-
isQueryTrap,
|
|
6832
|
-
formatLandstripTraps,
|
|
6833
|
-
extractRetryableNativeReadDeniedPath,
|
|
6834
|
-
extractNativeWriteDeniedPath,
|
|
6835
|
-
extractNativeDeniedPath,
|
|
6836
|
-
enforcesShellReadPolicy,
|
|
6837
|
-
domainMatchesAny,
|
|
6838
|
-
pi_landstrip_default as default,
|
|
6839
|
-
createWindowsDenyRead,
|
|
6840
|
-
createPosixShellProvider,
|
|
6841
|
-
createLandstripLauncherEnvironment,
|
|
6842
|
-
createLandstripIntegration,
|
|
6841
|
+
POSIX_SHELL_PROVIDER_ID,
|
|
6843
6842
|
controlResponseLine,
|
|
6844
|
-
|
|
6843
|
+
createLandstripIntegration,
|
|
6844
|
+
createLandstripLauncherEnvironment,
|
|
6845
|
+
createPosixShellProvider,
|
|
6846
|
+
createWindowsDenyRead,
|
|
6847
|
+
pi_landstrip_default as default,
|
|
6848
|
+
domainMatchesAny,
|
|
6849
|
+
enforcesShellReadPolicy,
|
|
6850
|
+
extractNativeDeniedPath,
|
|
6851
|
+
extractNativeWriteDeniedPath,
|
|
6852
|
+
extractRetryableNativeReadDeniedPath,
|
|
6853
|
+
formatLandstripTraps,
|
|
6854
|
+
isQueryTrap,
|
|
6855
|
+
matchesPattern,
|
|
6856
|
+
parseTrapLine,
|
|
6857
|
+
readAllowed,
|
|
6858
|
+
resolveProcessReadPolicy,
|
|
6859
|
+
sessionScopeFor,
|
|
6860
|
+
shouldPromptForWrite,
|
|
6861
|
+
writeEnvFile
|
|
6845
6862
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-landstrip",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.43",
|
|
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.18.
|
|
42
|
+
"@landstrip/landstrip-api": "^0.18.43",
|
|
43
43
|
"jsonc-parser": "^3.3.1",
|
|
44
44
|
"minimatch": "^10.2.5",
|
|
45
45
|
"yaml": "^2.9.0"
|