pi-landstrip 0.11.11 → 0.12.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 (2) hide show
  1. package/index.ts +25 -24
  2. package/package.json +2 -2
package/index.ts CHANGED
@@ -71,6 +71,7 @@ interface LandstripPolicy {
71
71
  allowAllUnixSockets: boolean;
72
72
  allowUnixSockets: string[];
73
73
  httpProxyPort?: number;
74
+ socksProxyPort?: number;
74
75
  };
75
76
  filesystem: SandboxFilesystemConfig;
76
77
  }
@@ -86,6 +87,7 @@ interface LandstripErrorResponse {
86
87
  program?: string;
87
88
  type?: LandstripErrorType;
88
89
  source?: string;
90
+ mechanism?: string;
89
91
  }
90
92
 
91
93
  interface LandstripBashCallbacks {
@@ -93,7 +95,7 @@ interface LandstripBashCallbacks {
93
95
  onErrorFd?: (data: Buffer) => void;
94
96
  }
95
97
 
96
- const LANDSTRIP_VERSION = [0, 11, 11] as const;
98
+ const LANDSTRIP_VERSION = [0, 12, 2] as const;
97
99
  const REQUIRED_LANDSTRIP_VERSION = LANDSTRIP_VERSION.join('.');
98
100
  const LANDSTRIP_ERROR_REASONS = new Set<LandstripErrorReason>([
99
101
  'Other',
@@ -513,37 +515,36 @@ function extractBlockedWritePath(output: string, cwd: string): string | null {
513
515
  function parseLandstripErrors(output: string): LandstripErrorResponse[] {
514
516
  const errors: LandstripErrorResponse[] = [];
515
517
 
516
- for (const block of output.trim().split(/\n\n+/)) {
517
- const fields: Record<string, string> = {};
518
+ for (const line of output.trim().split('\n')) {
519
+ if (line.length === 0) continue;
518
520
 
519
- for (const line of block.split('\n')) {
520
- const colonIndex = line.indexOf(':');
521
- if (colonIndex === -1) continue;
522
- const key = line.slice(0, colonIndex).trim();
523
- const value = line.slice(colonIndex + 1).trim();
524
- if (key.length > 0 && value.length > 0) fields[key] = value;
525
- }
521
+ try {
522
+ const parsed: unknown = JSON.parse(line);
523
+ if (typeof parsed !== 'object' || parsed === null) continue;
524
+ const obj = parsed as Record<string, unknown>;
525
+
526
+ const reason = obj.reason;
527
+ if (typeof reason !== 'string' || !isLandstripErrorReason(reason)) continue;
526
528
 
527
- if (
528
- fields.reason &&
529
- isLandstripErrorReason(fields.reason) &&
530
- (fields.source || fields.reason === 'AccessDenied')
531
- ) {
532
- const error: LandstripErrorResponse = { reason: fields.reason };
529
+ const error: LandstripErrorResponse = { reason };
533
530
 
534
- if (fields.source) error.source = fields.source;
535
- if (fields.file) error.file = fields.file;
536
- if (fields.program) error.program = fields.program;
531
+ if (typeof obj.source === 'string') error.source = obj.source;
532
+ if (typeof obj.file === 'string') error.file = obj.file;
533
+ if (typeof obj.program === 'string') error.program = obj.program;
537
534
 
538
- if (fields.operation && isLandstripOperation(fields.operation)) {
539
- error.operation = fields.operation;
535
+ if (typeof obj.operation === 'string' && isLandstripOperation(obj.operation)) {
536
+ error.operation = obj.operation;
540
537
  }
541
538
 
542
- if (fields.type && isLandstripErrorType(fields.type)) {
543
- error.type = fields.type;
539
+ if (typeof obj.type === 'string' && isLandstripErrorType(obj.type)) {
540
+ error.type = obj.type;
544
541
  }
545
542
 
543
+ if (typeof obj.mechanism === 'string') error.mechanism = obj.mechanism;
544
+
546
545
  errors.push(error);
546
+ } catch {
547
+ // Ignore non-JSON lines (e.g. stderr from child processes)
547
548
  }
548
549
  }
549
550
 
@@ -1141,7 +1142,7 @@ export function createLandstripIntegration(
1141
1142
  const allowNetwork = config.network.allowNetwork;
1142
1143
  const proxy = allowNetwork ? null : await startProxy(ctx, cwd);
1143
1144
  const policy = writePolicyFile(cwd, proxy?.port ?? null);
1144
- const landstripArgs = ['--error-fd', '3', '-p', policy.path, shell, ...args, command];
1145
+ const landstripArgs = ['--trap-fd', '3', '-p', policy.path, shell, ...args, command];
1145
1146
 
1146
1147
  return new Promise((resolvePromise, reject) => {
1147
1148
  let timeoutHandle: NodeJS.Timeout | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-landstrip",
3
- "version": "0.11.11",
3
+ "version": "0.12.0",
4
4
  "description": "Landlock-based sandboxing for pi with interactive permission prompts",
5
5
  "keywords": [
6
6
  "landstrip",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@earendil-works/pi-tui": "^0.78.0",
34
- "@jarkkojs/landstrip": "^0.11.11"
34
+ "@jarkkojs/landstrip": "^0.12.2"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@earendil-works/pi-coding-agent": "^0.78.0",