opencode-landstrip 0.17.17 → 0.17.19
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 +23 -25
- package/package.json +2 -2
- package/tui.ts +8 -0
package/README.md
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
# opencode-landstrip
|
|
2
2
|
|
|
3
|
-
`opencode-landstrip` is
|
|
4
|
-
|
|
5
|
-
[`landstrip`](https://github.com/landstrip/landstrip)
|
|
3
|
+
`opencode-landstrip` is an [OpenCode](https://opencode.ai/) plugin that sandboxes
|
|
4
|
+
commands using an Anthropic-compatible policy. It delegates OS-level enforcement
|
|
5
|
+
to [`landstrip`](https://github.com/landstrip/landstrip).
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
The plugin includes a default [sandbox policy](./sandbox.json). Global and
|
|
8
|
+
project-specific policies can override it.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Installation
|
|
11
11
|
|
|
12
12
|
### Automatic install
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Install for the current project:
|
|
15
15
|
|
|
16
|
-
```
|
|
16
|
+
```sh
|
|
17
17
|
opencode plugin install opencode-landstrip
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Install globally:
|
|
21
21
|
|
|
22
|
-
```
|
|
22
|
+
```sh
|
|
23
23
|
opencode plugin install opencode-landstrip --global
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
### Manual install
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
For a manual installation, update OpenCode's configuration files.
|
|
29
29
|
|
|
30
30
|
Add the plugin to `opencode.json`:
|
|
31
31
|
|
|
@@ -45,7 +45,7 @@ Add TUI entry point to `tui.json`:
|
|
|
45
45
|
}
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
To disable the plugin later:
|
|
49
49
|
|
|
50
50
|
```json
|
|
51
51
|
{
|
|
@@ -60,24 +60,22 @@ sets it, otherwise to the global config.
|
|
|
60
60
|
|
|
61
61
|
## Behavior
|
|
62
62
|
|
|
63
|
-
When OpenCode
|
|
64
|
-
notification
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
When OpenCode requests a sandboxed permission, the plugin sends a host
|
|
64
|
+
notification and opens a dialog. The user can allow once, allow for the session,
|
|
65
|
+
persist for the project or globally, or reject. The dialog shows the exact path
|
|
66
|
+
or domain being approved.
|
|
67
67
|
|
|
68
|
-
Project approvals are written to `.opencode/sandbox.json`; global approvals
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
Project approvals are written to `.opencode/sandbox.json`; global approvals go
|
|
69
|
+
to `~/.config/opencode/sandbox.json`. A newly created global file starts with the
|
|
70
|
+
default sandbox policy.
|
|
71
71
|
|
|
72
|
-
OpenCode's
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
but they are not process-sandboxed by this plugin.
|
|
72
|
+
OpenCode's plugin API can wrap AI `bash` tool calls, but cannot replace manually
|
|
73
|
+
typed shell-mode commands with a Landstrip wrapper. Those commands can inherit
|
|
74
|
+
OpenCode's proxy environment, but this plugin does not process-sandbox them.
|
|
76
75
|
|
|
77
76
|
## License
|
|
78
77
|
|
|
79
|
-
`opencode-landstrip` is licensed under `Apache-2.0`. See [LICENSE](LICENSE)
|
|
80
|
-
information.
|
|
78
|
+
`opencode-landstrip` is licensed under `Apache-2.0`. See [LICENSE](LICENSE).
|
|
81
79
|
|
|
82
80
|
The bundled `@landstrip/landstrip` package is licensed separately as
|
|
83
81
|
`Apache-2.0 AND LGPL-2.1-or-later`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-landstrip",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.19",
|
|
4
4
|
"description": "Landlock-based sandboxing for opencode with landstrip",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"landlock",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"ci:test": "npm test"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@landstrip/landstrip": "^0.17.
|
|
51
|
+
"@landstrip/landstrip": "^0.17.19",
|
|
52
52
|
"@opentui/solid": ">=0.3.4",
|
|
53
53
|
"solid-js": "1.9.12"
|
|
54
54
|
},
|
package/tui.ts
CHANGED
|
@@ -444,6 +444,8 @@ const tui: TuiPlugin = async (api, options, meta) => {
|
|
|
444
444
|
}
|
|
445
445
|
|
|
446
446
|
const unsubscribeAsked = api.event.on('permission.asked', (event) => {
|
|
447
|
+
const directory = api.state.path.directory || process.cwd();
|
|
448
|
+
if (!loadConfig(directory, optionOverrides).enabled) return;
|
|
447
449
|
const pending = event.properties as PendingPermission;
|
|
448
450
|
enqueue(pending);
|
|
449
451
|
reconcile(pending.sessionID);
|
|
@@ -483,11 +485,17 @@ const tui: TuiPlugin = async (api, options, meta) => {
|
|
|
483
485
|
buffer = buffer.slice(newline + 1);
|
|
484
486
|
|
|
485
487
|
for (const trap of parseLandstripTraps(line)) {
|
|
488
|
+
const directory = api.state.path.directory || process.cwd();
|
|
486
489
|
if (trap.kind !== 'filesystem' && trap.kind !== 'network') continue;
|
|
487
490
|
if (trap.state !== 'query') continue;
|
|
488
491
|
if (seen.has(trap.query_id)) continue;
|
|
489
492
|
seen.add(trap.query_id);
|
|
490
493
|
|
|
494
|
+
if (!loadConfig(directory, optionOverrides).enabled) {
|
|
495
|
+
respondQuery(socket, trap.query_id, 'allow');
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
|
|
491
499
|
if (trap.kind === 'filesystem') {
|
|
492
500
|
const sessionPaths =
|
|
493
501
|
trap.operation === 'read' ? sessionAllowedReadPaths : sessionAllowedWritePaths;
|