opencode-landstrip 0.1.0 → 0.1.1

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/index.ts +46 -9
  2. package/package.json +7 -5
  3. package/sandbox.json +34 -2
package/index.ts CHANGED
@@ -62,6 +62,8 @@ interface SandboxConfigOverrides {
62
62
  }
63
63
 
64
64
  interface BashSandboxState {
65
+ originalCommand: string;
66
+ wrappedCommand: string;
65
67
  policyDir: string;
66
68
  port: number;
67
69
  stop: () => Promise<void>;
@@ -97,7 +99,7 @@ const DEFAULT_CONFIG: SandboxConfig = {
97
99
  },
98
100
  filesystem: {
99
101
  denyRead: ['/Users', '/home'],
100
- allowRead: ['.', '~/.config/opencode', '~/.local', '~/.cargo'],
102
+ allowRead: ['.', '~/.config/opencode', '~/.config/git', '~/.gitconfig', '~/.local', '~/.cargo'],
101
103
  allowWrite: ['.', '/tmp'],
102
104
  denyWrite: ['.env', '.env.*', '*.pem', '*.key'],
103
105
  },
@@ -621,6 +623,18 @@ function buildWrappedCommand(
621
623
  return args.map(shellQuote).join(' ');
622
624
  }
623
625
 
626
+ function isGeneratedWrappedCommand(config: SandboxConfig, command: string): boolean {
627
+ return (
628
+ command.startsWith(`${shellQuote(config.landstrip.command)} `) &&
629
+ command.includes(` ${shellQuote('-p')} `) &&
630
+ command.includes('opencode-landstrip-')
631
+ );
632
+ }
633
+
634
+ function landstripDescription(description: string): string {
635
+ return description.endsWith(' (landstrip)') ? description : `${description} (landstrip)`;
636
+ }
637
+
624
638
  function getToolPath(args: Record<string, unknown>): string | undefined {
625
639
  const filePath = args.filePath ?? args.path;
626
640
  return typeof filePath === 'string' ? filePath : undefined;
@@ -810,7 +824,24 @@ export default (async ({ client, directory }: PluginInput, options?: PluginOptio
810
824
  config: SandboxConfig,
811
825
  ): Promise<void> {
812
826
  if (typeof args.command !== 'string') return;
813
- await cleanupBash(callID);
827
+
828
+ const existing = activeBash.get(callID);
829
+ if (existing) {
830
+ if (args.command === existing.originalCommand || args.command === existing.wrappedCommand) {
831
+ args.command = existing.wrappedCommand;
832
+ if (typeof args.description === 'string')
833
+ args.description = landstripDescription(args.description);
834
+ return;
835
+ }
836
+
837
+ await cleanupBash(callID);
838
+ }
839
+
840
+ if (isGeneratedWrappedCommand(config, args.command)) {
841
+ if (typeof args.description === 'string')
842
+ args.description = landstripDescription(args.description);
843
+ return;
844
+ }
814
845
 
815
846
  const blockedDomain = firstBlockedDomain(args.command, config);
816
847
  if (blockedDomain) {
@@ -834,19 +865,25 @@ export default (async ({ client, directory }: PluginInput, options?: PluginOptio
834
865
  throw error;
835
866
  }
836
867
 
868
+ const originalCommand = args.command;
869
+ const wrappedCommand = buildWrappedCommand(
870
+ config,
871
+ policy.path,
872
+ configuredShell ?? process.env.SHELL ?? '/bin/sh',
873
+ originalCommand,
874
+ );
875
+
837
876
  activeBash.set(callID, {
877
+ originalCommand,
878
+ wrappedCommand,
838
879
  policyDir: policy.dir,
839
880
  port: proxy.port,
840
881
  stop: proxy.stop,
841
882
  });
842
883
 
843
- args.command = buildWrappedCommand(
844
- config,
845
- policy.path,
846
- configuredShell ?? process.env.SHELL ?? '/bin/sh',
847
- args.command,
848
- );
849
- if (typeof args.description === 'string') args.description = `${args.description} (landstrip)`;
884
+ args.command = wrappedCommand;
885
+ if (typeof args.description === 'string')
886
+ args.description = landstripDescription(args.description);
850
887
  }
851
888
 
852
889
  const hooks: Hooks = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-landstrip",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Landlock-based sandboxing for opencode with landstrip",
5
5
  "keywords": [
6
6
  "landlock",
@@ -31,13 +31,15 @@
31
31
  }
32
32
  },
33
33
  "scripts": {
34
- "fmt": "oxfmt index.ts package.json tsconfig.json sandbox.json .oxfmtrc.json README.md",
34
+ "fmt": "oxfmt index.ts package.json tsconfig.json sandbox.json .oxfmtrc.json README.md test/*.test.mjs",
35
35
  "lint": "oxlint index.ts",
36
36
  "check": "tsc --noEmit",
37
- "all": "npm run fmt && npm run lint && npm run check",
38
- "ci:fmt": "oxfmt --check index.ts package.json tsconfig.json sandbox.json .oxfmtrc.json README.md",
37
+ "test": "node --test test/*.test.mjs",
38
+ "all": "npm run fmt && npm run lint && npm run check && npm test",
39
+ "ci:fmt": "oxfmt --check index.ts package.json tsconfig.json sandbox.json .oxfmtrc.json README.md test/*.test.mjs",
39
40
  "ci:lint": "npm run lint",
40
- "ci:check": "npm run check"
41
+ "ci:check": "npm run check",
42
+ "ci:test": "npm test"
41
43
  },
42
44
  "devDependencies": {
43
45
  "@opencode-ai/plugin": "^1.16.2",
package/sandbox.json CHANGED
@@ -7,9 +7,15 @@
7
7
  "allowedDomains": [
8
8
  "github.com",
9
9
  "*.github.com",
10
+ "api.github.com",
10
11
  "raw.githubusercontent.com",
12
+ "objects.githubusercontent.com",
13
+ "codeload.github.com",
11
14
  "registry.npmjs.org",
15
+ "npmjs.org",
12
16
  "*.npmjs.org",
17
+ "nodejs.org",
18
+ "*.nodejs.org",
13
19
  "crates.io",
14
20
  "*.crates.io",
15
21
  "static.crates.io"
@@ -18,8 +24,34 @@
18
24
  },
19
25
  "filesystem": {
20
26
  "denyRead": ["/home"],
21
- "allowRead": [".", "~/.config/opencode", "~/.local", "~/.cargo"],
22
- "allowWrite": [".", "/tmp", "~/.cargo", "~/.rustup"],
27
+ "allowRead": [
28
+ ".",
29
+ "/tmp",
30
+ "/var/tmp",
31
+ "/dev/null",
32
+ "~/.config/opencode",
33
+ "~/.config/git",
34
+ "~/.gitconfig",
35
+ "~/.local",
36
+ "~/.cargo",
37
+ "~/.rustup",
38
+ "~/.npm",
39
+ "~/.cache",
40
+ "~/.bun",
41
+ "~/.node-gyp"
42
+ ],
43
+ "allowWrite": [
44
+ ".",
45
+ "/tmp",
46
+ "/var/tmp",
47
+ "/dev/null",
48
+ "~/.cargo",
49
+ "~/.rustup",
50
+ "~/.npm",
51
+ "~/.cache",
52
+ "~/.bun",
53
+ "~/.node-gyp"
54
+ ],
23
55
  "denyWrite": [".env", ".env.*", "*.pem", "*.key"]
24
56
  }
25
57
  }