pi-landstrip 0.19.20 → 0.20.0

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.
Files changed (3) hide show
  1. package/api.ts +28 -28
  2. package/dist/index.ts +13 -10
  3. package/package.json +2 -2
package/api.ts CHANGED
@@ -9,15 +9,15 @@ import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-a
9
9
  import { isRecord } from '@landstrip/landstrip-api/shared';
10
10
 
11
11
  export const LANDSTRIP_CONTEXT_ENV = 'LANDSTRIP_CONTEXT';
12
- export const LANDSTRIP_RUNTIME_VERSION = 2;
12
+ export const LANDSTRIP_RUNTIME_VERSION = 3;
13
13
 
14
- const RUNTIME_REGISTER_EVENT = 'landstrip:runtime:register:v2';
15
- const RUNTIME_DISCOVER_EVENT = 'landstrip:runtime:discover:v2';
14
+ const RUNTIME_REGISTER_EVENT = 'landstrip:runtime:register:v3';
15
+ const RUNTIME_DISCOVER_EVENT = 'landstrip:runtime:discover:v3';
16
16
 
17
17
  export type LandstripSandboxState = 'enabled' | 'disabled' | 'unavailable';
18
18
 
19
- export interface LandstripContextV2 {
20
- readonly version: 2;
19
+ export interface LandstripContextV3 {
20
+ readonly version: 3;
21
21
  readonly host: 'pi';
22
22
  readonly role: 'primary' | 'subagent';
23
23
  readonly sandbox: LandstripSandboxState;
@@ -64,7 +64,7 @@ export interface LandstripPermissionAsk {
64
64
  }
65
65
 
66
66
  export interface LandstripPermissionAskRequest {
67
- readonly context: LandstripContextV2;
67
+ readonly context: LandstripContextV3;
68
68
  readonly toolName: string;
69
69
  readonly input: Readonly<Record<string, unknown>>;
70
70
  readonly permissions: readonly LandstripPermissionAsk[];
@@ -134,17 +134,17 @@ export type LandstripSpawn = (
134
134
  ) => ChildProcess;
135
135
 
136
136
  export type LandstripEvent =
137
- | { readonly type: 'sandbox.changed'; readonly context: LandstripContextV2 }
138
- | { readonly type: 'subagent.start'; readonly context: LandstripContextV2 }
137
+ | { readonly type: 'sandbox.changed'; readonly context: LandstripContextV3 }
138
+ | { readonly type: 'subagent.start'; readonly context: LandstripContextV3 }
139
139
  | {
140
140
  readonly type: 'subagent.end';
141
- readonly context: LandstripContextV2;
141
+ readonly context: LandstripContextV3;
142
142
  readonly status: 'completed' | 'cancelled' | 'error';
143
143
  };
144
144
 
145
- export interface PiLandstripRuntimeV2 {
146
- readonly version: 2;
147
- getContext(ctx?: ExtensionContext): LandstripContextV2;
145
+ export interface PiLandstripRuntimeV3 {
146
+ readonly version: 3;
147
+ getContext(ctx?: ExtensionContext): LandstripContextV3;
148
148
  registerShellProvider(provider: LandstripShellProvider): () => void;
149
149
  registerPermissionAskProvider(provider: LandstripPermissionAskProvider): () => void;
150
150
  prepareProcess(options: LandstripProcessOptions): Promise<LandstripPreparedProcess>;
@@ -157,13 +157,13 @@ export interface PiLandstripRuntimeV2 {
157
157
  }
158
158
 
159
159
  interface RuntimeRegistration {
160
- readonly version: 2;
161
- readonly runtime: PiLandstripRuntimeV2;
160
+ readonly version: 3;
161
+ readonly runtime: PiLandstripRuntimeV3;
162
162
  }
163
163
 
164
164
  interface RuntimeDiscovery {
165
- readonly version: 2;
166
- register(runtime: PiLandstripRuntimeV2): void;
165
+ readonly version: 3;
166
+ register(runtime: PiLandstripRuntimeV3): void;
167
167
  }
168
168
 
169
169
  interface EventBusLike {
@@ -175,7 +175,7 @@ function eventBus(pi: ExtensionAPI): EventBusLike | undefined {
175
175
  return (pi as ExtensionAPI & { events?: EventBusLike }).events;
176
176
  }
177
177
 
178
- function isRuntime(value: unknown): value is PiLandstripRuntimeV2 {
178
+ function isRuntime(value: unknown): value is PiLandstripRuntimeV3 {
179
179
  return (
180
180
  isRecord(value) &&
181
181
  value['version'] === LANDSTRIP_RUNTIME_VERSION &&
@@ -213,18 +213,18 @@ function isPreparedProcess(value: unknown): value is LandstripPreparedProcess {
213
213
 
214
214
  function discoverLandstrip(
215
215
  pi: ExtensionAPI,
216
- callback: (runtime: PiLandstripRuntimeV2) => void,
216
+ callback: (runtime: PiLandstripRuntimeV3) => void,
217
217
  onInvalid?: (error: Error) => void,
218
218
  ): () => void {
219
219
  const events = eventBus(pi);
220
220
  if (!events) return () => undefined;
221
221
 
222
- let current: PiLandstripRuntimeV2 | undefined;
222
+ let current: PiLandstripRuntimeV3 | undefined;
223
223
  let disposed = false;
224
224
  const register = (value: unknown): void => {
225
225
  if (disposed) return;
226
226
  if (!isRuntime(value)) {
227
- onInvalid?.(new Error('Invalid Landstrip runtime v2 declaration'));
227
+ onInvalid?.(new Error('Invalid Landstrip runtime v3 declaration'));
228
228
  return;
229
229
  }
230
230
  if (value === current) return;
@@ -234,7 +234,7 @@ function discoverLandstrip(
234
234
  const unsubscribe = events.on(RUNTIME_REGISTER_EVENT, (value) => {
235
235
  if (disposed) return;
236
236
  if (!isRecord(value) || value['version'] !== LANDSTRIP_RUNTIME_VERSION) {
237
- onInvalid?.(new Error('Invalid Landstrip runtime v2 registration'));
237
+ onInvalid?.(new Error('Invalid Landstrip runtime v3 registration'));
238
238
  return;
239
239
  }
240
240
  register(value['runtime']);
@@ -258,13 +258,13 @@ function discoverLandstrip(
258
258
 
259
259
  export function useLandstrip(
260
260
  pi: ExtensionAPI,
261
- callback: (runtime: PiLandstripRuntimeV2) => void,
261
+ callback: (runtime: PiLandstripRuntimeV3) => void,
262
262
  ): () => void {
263
263
  return discoverLandstrip(pi, callback);
264
264
  }
265
265
 
266
266
  export function createLandstrip(pi: ExtensionAPI): Landstrip {
267
- let runtime: PiLandstripRuntimeV2 | undefined;
267
+ let runtime: PiLandstripRuntimeV3 | undefined;
268
268
  let runtimeError: Error | undefined;
269
269
  let disposed = false;
270
270
  const stopDiscovery = discoverLandstrip(
@@ -339,7 +339,7 @@ export function createLandstrip(pi: ExtensionAPI): Landstrip {
339
339
 
340
340
  function provideExtensionProvider(
341
341
  pi: ExtensionAPI,
342
- register: (runtime: PiLandstripRuntimeV2) => () => void,
342
+ register: (runtime: PiLandstripRuntimeV3) => () => void,
343
343
  ): () => void {
344
344
  let unregisterProvider: (() => void) | undefined;
345
345
  const stopDiscovery = useLandstrip(pi, (runtime) => {
@@ -369,7 +369,7 @@ export function provideLandstripPermissionAsk(
369
369
 
370
370
  export function publishLandstripRuntime(
371
371
  pi: ExtensionAPI,
372
- runtime: PiLandstripRuntimeV2,
372
+ runtime: PiLandstripRuntimeV3,
373
373
  ): () => void {
374
374
  const events = eventBus(pi);
375
375
  if (!events) return () => undefined;
@@ -390,13 +390,13 @@ export function publishLandstripRuntime(
390
390
  }
391
391
  }
392
392
 
393
- export function encodeLandstripContext(context: LandstripContextV2): string {
393
+ export function encodeLandstripContext(context: LandstripContextV3): string {
394
394
  return Buffer.from(JSON.stringify(context)).toString('base64url');
395
395
  }
396
396
 
397
397
  export function contextFromEnvironment(
398
398
  env: NodeJS.ProcessEnv = process.env,
399
- ): LandstripContextV2 | undefined {
399
+ ): LandstripContextV3 | undefined {
400
400
  const encoded = env[LANDSTRIP_CONTEXT_ENV];
401
401
  if (!encoded) return undefined;
402
402
 
@@ -418,7 +418,7 @@ export function contextFromEnvironment(
418
418
  ) {
419
419
  return undefined;
420
420
  }
421
- return value as unknown as LandstripContextV2;
421
+ return value as unknown as LandstripContextV3;
422
422
  } catch {
423
423
  return undefined;
424
424
  }
package/dist/index.ts CHANGED
@@ -68,9 +68,9 @@ import {
68
68
  // api.ts
69
69
  import { isRecord } from "@landstrip/landstrip-api/shared";
70
70
  var LANDSTRIP_CONTEXT_ENV = "LANDSTRIP_CONTEXT";
71
- var LANDSTRIP_RUNTIME_VERSION = 2;
72
- var RUNTIME_REGISTER_EVENT = "landstrip:runtime:register:v2";
73
- var RUNTIME_DISCOVER_EVENT = "landstrip:runtime:discover:v2";
71
+ var LANDSTRIP_RUNTIME_VERSION = 3;
72
+ var RUNTIME_REGISTER_EVENT = "landstrip:runtime:register:v3";
73
+ var RUNTIME_DISCOVER_EVENT = "landstrip:runtime:discover:v3";
74
74
  function eventBus(pi) {
75
75
  return pi.events;
76
76
  }
@@ -5402,7 +5402,7 @@ ${catalog.diagnostics.join(`
5402
5402
  }
5403
5403
  taskContext(task, ctx) {
5404
5404
  const context = this.integration.getContext?.(ctx) ?? {
5405
- version: 2,
5405
+ version: LANDSTRIP_RUNTIME_VERSION,
5406
5406
  host: "pi",
5407
5407
  role: "primary",
5408
5408
  sandbox: "unavailable",
@@ -5422,7 +5422,7 @@ ${catalog.diagnostics.join(`
5422
5422
  }
5423
5423
  permissionContext(ctx) {
5424
5424
  const context = this.integration.getContext?.(ctx) ?? {
5425
- version: 2,
5425
+ version: LANDSTRIP_RUNTIME_VERSION,
5426
5426
  host: "pi",
5427
5427
  role: "primary",
5428
5428
  sandbox: "unavailable",
@@ -6698,6 +6698,7 @@ ${paths}${note}`, PERMISSION_OPTIONS, promptSignal);
6698
6698
  denyWrite: mergeArray(config.filesystem.denyWrite, allowances?.protectedPaths),
6699
6699
  denyWriteAlways: mergeArray(config.filesystem.denyWriteAlways, allowances?.protectedPaths)
6700
6700
  },
6701
+ macos: config.macos,
6701
6702
  windows: config.windows,
6702
6703
  httpProxyPort: proxyPort
6703
6704
  });
@@ -6989,7 +6990,7 @@ ${paths}${note}`, PERMISSION_OPTIONS, promptSignal);
6989
6990
  if (spawned)
6990
6991
  throw new Error("Prepared process can only be spawned once");
6991
6992
  spawned = true;
6992
- const landstripArgs = ["-p", workerPolicy.path, "--", options.command, ...options.args];
6993
+ const landstripArgs = ["run", "-p", workerPolicy.path];
6993
6994
  const authPipe = Array.isArray(spawnOptions.stdio) && spawnOptions.stdio[WORKER_AUTH_FD] === "pipe";
6994
6995
  if (authPipe && process.platform === "win32") {
6995
6996
  throw new Error("Sandboxed worker authentication requires inherited Unix file descriptors");
@@ -6999,10 +7000,11 @@ ${paths}${note}`, PERMISSION_OPTIONS, promptSignal);
6999
7000
  stdio.push(workerChildEnd ?? "ignore");
7000
7001
  if (authPipe) {
7001
7002
  stdio.push("pipe");
7002
- landstripArgs.unshift("--inherit", String(WORKER_AUTH_FD));
7003
+ landstripArgs.push("--inherit", String(WORKER_AUTH_FD));
7003
7004
  }
7004
7005
  if (workerChildEnd)
7005
- landstripArgs.unshift("--trap", "3");
7006
+ landstripArgs.push("--trap", "3");
7007
+ landstripArgs.push("--", options.command, ...options.args);
7006
7008
  const child = spawn2(binaryPath(), landstripArgs, {
7007
7009
  ...spawnOptions,
7008
7010
  cwd: options.cwd,
@@ -7210,9 +7212,10 @@ ${paths}${note}`, PERMISSION_OPTIONS, promptSignal);
7210
7212
  };
7211
7213
  processAllowances = withWindowsProcessReadAccess(processAllowances, invocation.executable, cwd);
7212
7214
  policy = writePolicyFile(cwd, proxy?.port ?? null, "shell", processAllowances);
7213
- landstripArgs = ["-p", policy.path, "--", invocation.executable, ...invocation.args];
7215
+ landstripArgs = ["run", "-p", policy.path];
7214
7216
  if (process.platform !== "win32")
7215
- landstripArgs.unshift("--trap", "3");
7217
+ landstripArgs.push("--trap", "3");
7218
+ landstripArgs.push("--", invocation.executable, ...invocation.args);
7216
7219
  } catch (error) {
7217
7220
  await teardownResources();
7218
7221
  throw error;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-landstrip",
3
- "version": "0.19.20",
3
+ "version": "0.20.0",
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.19.20",
42
+ "@landstrip/landstrip-api": "^0.20.0",
43
43
  "jsonc-parser": "^3.3.1",
44
44
  "minimatch": "^10.2.5",
45
45
  "undici": "^8.9.0",