pvisor-agent-plugins 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.
- package/README.md +50 -34
- package/backend.mjs +4 -2
- package/install-prompt.txt +22 -17
- package/mcp.mjs +3 -1
- package/package.json +2 -10
- package/plugin.json +1 -1
- package/runtime.mjs +48 -54
- package/skills/staged-task/SKILL.md +8 -6
- package/tools.mjs +1 -1
- package/pvisor.mjs +0 -17
- package/runtime.json +0 -14
package/README.md
CHANGED
|
@@ -6,25 +6,48 @@ for the host's built-in filesystem, terminal, or background-job tools. Each
|
|
|
6
6
|
`pvisor_spawn` starts a new native Session; later calls do not continue that Session.
|
|
7
7
|
Put dependent edits and tests in the same `argv` invocation.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
Use plugin version 0.1.1 or newer for a separately installed runtime. The
|
|
10
|
+
published 0.1.0 package requires obsolete npm runtime packages; reinstalling it
|
|
11
|
+
will not switch to Homebrew/pip. Remote marketplace refs require separate
|
|
12
|
+
publication; npm publication does not publish a marketplace tag.
|
|
12
13
|
|
|
13
|
-
Node.js 22.19+
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
Node.js 22.19+ and a separately installed pVisor runtime are required. Install
|
|
15
|
+
pVisor through Homebrew or pip before installing the plugin. Host staging still
|
|
16
|
+
needs the system's FUSE/FSKit and namespace support on Linux x64 or macOS arm64;
|
|
17
|
+
the plugin cannot install privileged OS components.
|
|
17
18
|
|
|
18
19
|
## Install
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
Install the runtime using one of these methods:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
brew tap DeepLink-org/formula https://github.com/DeepLink-org/Formula.git
|
|
25
|
+
brew install DeepLink-org/formula/pvisor
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or use a Python 3.10+ virtual environment:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
python3 -m venv ~/.venvs/pvisor
|
|
32
|
+
source ~/.venvs/pvisor/bin/activate
|
|
33
|
+
python -m pip install pvisor-sandbox
|
|
34
|
+
pvisor --version
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Follow the [installation guide](https://deeplink-org.github.io/pvisor/start/installation/)
|
|
38
|
+
for platform prerequisites. Launch your Agent host with `pvisor` on its PATH.
|
|
39
|
+
Desktop apps may not inherit your terminal PATH; set `PVISOR_PLUGIN_BINARY` in
|
|
40
|
+
the host environment to the absolute installed CLI path if needed. The plugin
|
|
41
|
+
never downloads a runtime or installs packages. It checks required CLI flags
|
|
42
|
+
before work and refuses incompatible runtimes; older releases such as 0.3.1
|
|
43
|
+
without selective apply are insufficient. Plugin and runtime versions are independent.
|
|
44
|
+
|
|
45
|
+
Activate only the Agent hosts you use.
|
|
23
46
|
|
|
24
47
|
### Pi
|
|
25
48
|
|
|
26
49
|
```sh
|
|
27
|
-
pi install npm:pvisor-agent-plugins
|
|
50
|
+
pi install npm:pvisor-agent-plugins@0.1.1
|
|
28
51
|
```
|
|
29
52
|
|
|
30
53
|
Start a new Pi session in the target project. Ask it to call `pvisor_doctor`,
|
|
@@ -35,12 +58,12 @@ do not nest task plugins inside that outer Session.
|
|
|
35
58
|
### DSH Web and Desktop
|
|
36
59
|
|
|
37
60
|
```sh
|
|
38
|
-
dsh plugin --profile web add pvisor-agent-plugins
|
|
39
|
-
dsh plugin --profile desktop add pvisor-agent-plugins
|
|
61
|
+
dsh plugin --profile web add pvisor-agent-plugins@0.1.1
|
|
62
|
+
dsh plugin --profile desktop add pvisor-agent-plugins@0.1.1
|
|
40
63
|
```
|
|
41
64
|
|
|
42
65
|
Install only the profile you use, then restart it. Desktop also accepts
|
|
43
|
-
`pvisor-agent-plugins` in **Plugins → Add plugin**. The package
|
|
66
|
+
`pvisor-agent-plugins@0.1.1` in **Plugins → Add plugin**. The package
|
|
44
67
|
uses Cordis's functional plugin interface and `dsh-tools.defineTool`; its peers
|
|
45
68
|
target DSH 0.2.x. It does not disable existing providers or change permission
|
|
46
69
|
presets. Check that `pvisor_doctor` appears in the actual tool catalog.
|
|
@@ -50,9 +73,9 @@ presets. Check that `pvisor_doctor` appears in the actual tool catalog.
|
|
|
50
73
|
Register the remote marketplace and bind the tools from your project directory:
|
|
51
74
|
|
|
52
75
|
```sh
|
|
53
|
-
codex plugin marketplace add DeepLink-org/pvisor --ref plugins-v0.1.
|
|
76
|
+
codex plugin marketplace add DeepLink-org/pvisor --ref plugins-v0.1.1
|
|
54
77
|
codex plugin add pvisor@pvisor
|
|
55
|
-
codex mcp add pvisor -- npx --yes --package pvisor-agent-plugins@0.1.
|
|
78
|
+
codex mcp add pvisor -- npx --yes --package pvisor-agent-plugins@0.1.1 pvisor-agent-mcp --project "$PWD"
|
|
56
79
|
```
|
|
57
80
|
|
|
58
81
|
The marketplace installs the workflow skill. The native `codex mcp add` command
|
|
@@ -60,14 +83,8 @@ separately binds its runtime tools to an explicit project. Start a new session
|
|
|
60
83
|
after both steps. Clients without plugin support can use MCP alone, without the
|
|
61
84
|
workflow skill. There is no duplicate bundled MCP registration.
|
|
62
85
|
|
|
63
|
-
`npx` installs the pinned plugin
|
|
64
|
-
|
|
65
|
-
install the same package globally:
|
|
66
|
-
|
|
67
|
-
```sh
|
|
68
|
-
npm install --global pvisor-agent-plugins
|
|
69
|
-
pvisor --version
|
|
70
|
-
```
|
|
86
|
+
`npx` installs only the pinned plugin, without a global npm install. Native
|
|
87
|
+
`pvisor` commands come from your Homebrew or pip installation.
|
|
71
88
|
|
|
72
89
|
This split is intentional: Codex 0.164.0 starts bundled MCP servers in the plugin
|
|
73
90
|
cache, and portable manifest cwd paths are plugin-relative.
|
|
@@ -85,7 +102,7 @@ project-controlled config file:
|
|
|
85
102
|
|
|
86
103
|
| Variable | Default | Meaning |
|
|
87
104
|
| --- | --- | --- |
|
|
88
|
-
| `PVISOR_PLUGIN_BINARY` |
|
|
105
|
+
| `PVISOR_PLUGIN_BINARY` | `pvisor` on the host's PATH | Absolute installed CLI path; an invalid override never falls back |
|
|
89
106
|
| `PVISOR_PLUGIN_STATE_DIR` | `~/.local/state/pvisor/agent-plugins/v1` | Private task records and stages, outside the project |
|
|
90
107
|
| `PVISOR_PLUGIN_PROJECT` | Unset | Explicit project for manually launched MCP; prefer native `codex mcp add ... --project DIR`; Pi/DSH use their call context |
|
|
91
108
|
|
|
@@ -127,7 +144,7 @@ the adapters never use `last`.
|
|
|
127
144
|
|
|
128
145
|
| Tool | Effect |
|
|
129
146
|
| --- | --- |
|
|
130
|
-
| `pvisor_doctor` |
|
|
147
|
+
| `pvisor_doctor` | Check required CLI capabilities and show binary path, project, runtime version and adapter scope; it does not test FUSE or certify isolation |
|
|
131
148
|
| `pvisor_spawn` | Call native `pvisor spawn` for one new staged task and retain its Session |
|
|
132
149
|
| `pvisor_status` | Query the exact Session's JSON status |
|
|
133
150
|
| `pvisor_review` | Show the bounded project diff |
|
|
@@ -166,8 +183,7 @@ Codex's MCP surface intentionally has no apply/drop tools. After reviewing the
|
|
|
166
183
|
diff, run these commands yourself in the project:
|
|
167
184
|
|
|
168
185
|
Save the returned selector in your terminal as `stage`, then use the native CLI
|
|
169
|
-
|
|
170
|
-
`npx --yes --package pvisor-agent-plugins@0.1.0`):
|
|
186
|
+
installed through Homebrew or pip:
|
|
171
187
|
|
|
172
188
|
```sh
|
|
173
189
|
pvisor status "$stage" --json
|
|
@@ -206,16 +222,16 @@ Developer tests, source installs and publication instructions live in
|
|
|
206
222
|
|
|
207
223
|
## Upgrade and uninstall
|
|
208
224
|
|
|
209
|
-
Review pending tasks before upgrading.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
runtime underneath a running task.
|
|
225
|
+
Review pending tasks before upgrading. Update the plugin through the host's
|
|
226
|
+
package manager and the runtime separately through Homebrew or pip, then restart
|
|
227
|
+
and run Doctor to check compatibility. Update a Codex pinned marketplace ref and
|
|
228
|
+
its `npx` version together. Never replace a runtime underneath a running task.
|
|
213
229
|
|
|
214
230
|
Use `pi remove npm:pvisor-agent-plugins`,
|
|
215
231
|
`dsh plugin --profile web remove pvisor-agent-plugins` (or the selected Desktop
|
|
216
232
|
profile), and `codex plugin remove pvisor@pvisor` as supported by each
|
|
217
|
-
host's help. Remove its separate
|
|
218
|
-
|
|
233
|
+
host's help. Remove its separate MCP registration with `codex mcp remove pvisor`.
|
|
234
|
+
Plugin removal leaves the separately installed runtime intact.
|
|
219
235
|
These actions do not delete retained stages. Review or drop them explicitly;
|
|
220
236
|
do not recursively delete the state root as an uninstall step.
|
|
221
237
|
|
package/backend.mjs
CHANGED
|
@@ -139,7 +139,7 @@ export function execute(binary, args, { cwd, env, signal, deadlineMs = 30_000 }
|
|
|
139
139
|
export class Backend {
|
|
140
140
|
constructor(project = process.env.PVISOR_PLUGIN_PROJECT || process.cwd(), options = {}) {
|
|
141
141
|
this.projectInput = project;
|
|
142
|
-
this.binary = options.binary
|
|
142
|
+
this.binary = options.binary ?? process.env.PVISOR_PLUGIN_BINARY;
|
|
143
143
|
this.stateInput = options.stateDir || process.env.PVISOR_PLUGIN_STATE_DIR ||
|
|
144
144
|
path.join(homedir(), ".local", "state", "pvisor", "agent-plugins", "v1");
|
|
145
145
|
}
|
|
@@ -190,9 +190,11 @@ export class Backend {
|
|
|
190
190
|
async doctor(input = {}, signal) {
|
|
191
191
|
fields(input, []);
|
|
192
192
|
const project = await this.project();
|
|
193
|
-
const
|
|
193
|
+
const binary = await resolveRuntime(this.binary);
|
|
194
|
+
const result = await execute(binary, ["--version"], { cwd: project, signal });
|
|
194
195
|
return {
|
|
195
196
|
...result,
|
|
197
|
+
binary,
|
|
196
198
|
project,
|
|
197
199
|
scope: "Task tools only; native host tools are not intercepted. Host --safe, deny-all network. No mount attestation from doctor.",
|
|
198
200
|
};
|
package/install-prompt.txt
CHANGED
|
@@ -2,45 +2,50 @@ Install the pVisor task plugin for the Agent host the user selects: Pi, DeepSeek
|
|
|
2
2
|
Harness (DSH), or Codex. Use the registry release, not a source checkout.
|
|
3
3
|
|
|
4
4
|
1. Detect OS, architecture, Node version and installed Agent hosts. Node.js
|
|
5
|
-
22.19+ is required.
|
|
5
|
+
22.19+ is required. Host staging supports Linux x64 and macOS arm64. Check
|
|
6
6
|
FUSE/FSKit and namespace prerequisites from the pVisor installation guide:
|
|
7
7
|
https://deeplink-org.github.io/pvisor/start/installation/
|
|
8
8
|
Do not infer working staging from successful package installation.
|
|
9
|
-
2. Confirm that pvisor-agent-plugins
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
2. Confirm that pvisor-agent-plugins is published on npm. The first release may
|
|
10
|
+
still be pending: report that blocker rather than inventing success.
|
|
11
|
+
Install the native pVisor runtime separately through Homebrew or pip
|
|
12
|
+
(pvisor-sandbox), following the installation guide. Explain and confirm
|
|
13
|
+
installation changes first. Reuse a compatible installed runtime.
|
|
12
14
|
3. Reuse working installations. Ask which host to use when several are present.
|
|
13
15
|
Do not install unrelated Agent applications, change model logins, or remove
|
|
14
16
|
existing plugins without permission. Explain host-profile changes first.
|
|
15
17
|
4. Use the selected host's native package manager:
|
|
16
|
-
Pi: pi install npm:pvisor-agent-plugins
|
|
17
|
-
DSH Web: dsh plugin --profile web add pvisor-agent-plugins
|
|
18
|
-
DSH Desktop: dsh plugin --profile desktop add pvisor-agent-plugins
|
|
19
|
-
npm installs the
|
|
20
|
-
|
|
18
|
+
Pi: pi install npm:pvisor-agent-plugins@0.1.1
|
|
19
|
+
DSH Web: dsh plugin --profile web add pvisor-agent-plugins@0.1.1
|
|
20
|
+
DSH Desktop: dsh plugin --profile desktop add pvisor-agent-plugins@0.1.1
|
|
21
|
+
npm installs only the plugin. The Agent host must have pvisor on its PATH;
|
|
22
|
+
desktop apps may not inherit terminal PATH. If needed, configure the absolute
|
|
23
|
+
CLI path with PVISOR_PLUGIN_BINARY in the host environment. Invalid overrides
|
|
24
|
+
or missing CLI capabilities are errors; never silently select another runtime.
|
|
21
25
|
5. For Codex, install the remote workflow and register tools from the project:
|
|
22
|
-
codex plugin marketplace add DeepLink-org/pvisor --ref plugins-v0.1.
|
|
26
|
+
codex plugin marketplace add DeepLink-org/pvisor --ref plugins-v0.1.1
|
|
23
27
|
codex plugin add pvisor@pvisor
|
|
24
|
-
codex mcp add pvisor -- npx --yes --package pvisor-agent-plugins@0.1.
|
|
28
|
+
codex mcp add pvisor -- npx --yes --package pvisor-agent-plugins@0.1.1 pvisor-agent-mcp --project "$PWD"
|
|
25
29
|
A client without plugins may use MCP alone. Do not register duplicate servers
|
|
26
30
|
or infer the project from an installed plugin's cwd.
|
|
27
31
|
6. Never print keys or put credentials in plugin config or task records. Do not
|
|
28
32
|
change host approval settings. OS-level FUSE/FSKit installation or privileged
|
|
29
33
|
policy changes require separate user permission; do not install them silently.
|
|
30
|
-
7. Restart the host. Confirm pvisor_doctor
|
|
31
|
-
version and task-only scope.
|
|
34
|
+
7. Restart the host. Confirm pvisor_doctor checks required CLI capabilities and
|
|
35
|
+
reports the intended binary path, project, runtime version and task-only scope.
|
|
36
|
+
Old releases such as 0.3.1 lack the required selective apply interface; do not
|
|
37
|
+
assume a published runtime is compatible. In a disposable project, run pvisor_spawn to
|
|
32
38
|
create two files, review both, accept one and drop the other. Verify the host
|
|
33
39
|
was unchanged before acceptance and the accepted file survives drop.
|
|
34
40
|
Test user rejection as well as approval in Pi or DSH. Codex acceptance stays
|
|
35
|
-
with the user through native pvisor review/apply/drop
|
|
36
|
-
|
|
37
|
-
plugin operation.
|
|
41
|
+
with the user through native pvisor review/apply/drop from the Homebrew or pip
|
|
42
|
+
installation. The npm plugin does not provide a pvisor launcher.
|
|
38
43
|
8. Report exact installed versions, host/profile, runtime selection, config
|
|
39
44
|
changes, verification results and remaining checks. These task tools do not
|
|
40
45
|
intercept native Agent tools. Every spawn is an independent Session.
|
|
41
46
|
Task HOME/XDG state is fresh and private, not the host's login/config/cache
|
|
42
47
|
directory. Workspace stages remain persistent in the configured state root.
|
|
43
48
|
|
|
44
|
-
Missing
|
|
49
|
+
Missing/incompatible runtime or failed confinement are errors. Never substitute
|
|
45
50
|
host execution, remove --safe, automatically retry uncertain side effects,
|
|
46
51
|
publish packages, star a repository, or delete pending stages to make setup pass.
|
package/mcp.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
2
3
|
import { Backend } from "./backend.mjs";
|
|
3
4
|
import { callTool, failed, textContent, tools } from "./tools.mjs";
|
|
4
5
|
|
|
6
|
+
const { name, version } = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8"));
|
|
5
7
|
const args = process.argv.slice(2);
|
|
6
8
|
if (args.length && (args.length !== 2 || args[0] !== "--project")) {
|
|
7
9
|
console.error("Usage: pvisor-agent-mcp [--project DIR]");
|
|
@@ -47,7 +49,7 @@ async function dispatch(message) {
|
|
|
47
49
|
send(id, {
|
|
48
50
|
protocolVersion: versions.includes(params.protocolVersion) ? params.protocolVersion : "2025-11-25",
|
|
49
51
|
capabilities: { tools: {} },
|
|
50
|
-
serverInfo: { name
|
|
52
|
+
serverInfo: { name, version },
|
|
51
53
|
instructions: "Task-only staging. Native Agent tools are not intercepted. No automatic retries or acceptance. Use the same exact stage selector as native pvisor status/review/apply/drop and let the user accept selected results.",
|
|
52
54
|
});
|
|
53
55
|
} else if (method === "ping") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pvisor-agent-plugins",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Task-level pVisor staging adapters for Pi, DSH and Codex",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://deeplink-org.github.io/pvisor/guides/agents/plugins/",
|
|
@@ -14,26 +14,19 @@
|
|
|
14
14
|
"./dsh": "./dsh.mjs"
|
|
15
15
|
},
|
|
16
16
|
"bin": {
|
|
17
|
-
"pvisor": "./pvisor.mjs",
|
|
18
17
|
"pvisor-agent-mcp": "./mcp.mjs"
|
|
19
18
|
},
|
|
20
19
|
"pi": { "extensions": ["./pi.mjs"] },
|
|
21
20
|
"dsh": { "bundle": { "patch": "./cordis.patch.yml" } },
|
|
22
21
|
"peerDependencies": { "@deepseek-ai/dsh-tools": "^0.2.0-0 || ^0.2.1-0" },
|
|
23
22
|
"peerDependenciesMeta": { "@deepseek-ai/dsh-tools": { "optional": true } },
|
|
24
|
-
"optionalDependencies": {
|
|
25
|
-
"pvisor-agent-runtime-linux-x64": "0.1.0",
|
|
26
|
-
"pvisor-agent-runtime-darwin-arm64": "0.1.0"
|
|
27
|
-
},
|
|
28
23
|
"files": [
|
|
29
24
|
"backend.mjs",
|
|
30
25
|
"tools.mjs",
|
|
31
26
|
"pi.mjs",
|
|
32
27
|
"dsh.mjs",
|
|
33
28
|
"mcp.mjs",
|
|
34
|
-
"pvisor.mjs",
|
|
35
29
|
"runtime.mjs",
|
|
36
|
-
"runtime.json",
|
|
37
30
|
"cordis.patch.yml",
|
|
38
31
|
"plugin.json",
|
|
39
32
|
"skills",
|
|
@@ -44,7 +37,6 @@
|
|
|
44
37
|
"scripts": {
|
|
45
38
|
"test": "node --test test/*.test.mjs",
|
|
46
39
|
"test:hosts": "node check-hosts.mjs",
|
|
47
|
-
"smoke": "node smoke.mjs"
|
|
48
|
-
"release:prepare": "node release.mjs"
|
|
40
|
+
"smoke": "node smoke.mjs"
|
|
49
41
|
}
|
|
50
42
|
}
|
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "pvisor",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.1",
|
|
5
5
|
"description": "Run pVisor staged tasks, review candidates and preview selective acceptance",
|
|
6
6
|
"license": "Apache-2.0"
|
|
7
7
|
}
|
package/runtime.mjs
CHANGED
|
@@ -1,71 +1,65 @@
|
|
|
1
|
-
import { access,
|
|
2
|
-
import { constants
|
|
1
|
+
import { access, stat } from "node:fs/promises";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
3
|
import { execFile } from "node:child_process";
|
|
4
|
-
import { createRequire } from "node:module";
|
|
5
4
|
import path from "node:path";
|
|
6
5
|
import { promisify } from "node:util";
|
|
7
6
|
|
|
8
|
-
const
|
|
9
|
-
export const runtime = JSON.parse(readFileSync(new URL("./runtime.json", import.meta.url), "utf8"));
|
|
10
|
-
const plugin = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8"));
|
|
11
|
-
const components = ["pvisor", "pvisor-replay", "pvisor-daemon", "libkrunfw.SOURCE"];
|
|
12
|
-
let installed;
|
|
7
|
+
const installation = "Install or upgrade pVisor through Homebrew or pip (pvisor-sandbox): https://deeplink-org.github.io/pvisor/start/installation/. Restart the Agent host after changing PATH, or set PVISOR_PLUGIN_BINARY to an absolute executable path.";
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
arch = process.arch,
|
|
18
|
-
resolve = (name) => require.resolve(`${name}/package.json`),
|
|
19
|
-
} = {}) {
|
|
20
|
-
const target = runtime.platforms[`${platform}-${arch}`];
|
|
21
|
-
if (!target) {
|
|
22
|
-
throw new Error(`pVisor task plugins do not support ${platform}/${arch}; supported: Linux x64 and macOS arm64`);
|
|
9
|
+
async function executable(binary) {
|
|
10
|
+
if (!(await stat(binary)).isFile()) {
|
|
11
|
+
throw Object.assign(new Error("Not a regular executable"), { code: "EACCES" });
|
|
23
12
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
metadata = resolve(target.package);
|
|
27
|
-
} catch {
|
|
28
|
-
throw new Error(`Missing ${target.package}@${plugin.version}. Reinstall pvisor-agent-plugins with optional dependencies enabled; no host-execution fallback is allowed.`);
|
|
29
|
-
}
|
|
30
|
-
const manifest = JSON.parse(await readFile(metadata, "utf8"));
|
|
31
|
-
if (manifest.name !== target.package || manifest.version !== plugin.version ||
|
|
32
|
-
manifest.pvisorRuntimeVersion !== runtime.version ||
|
|
33
|
-
!/^[0-9a-f]{40}$/.test(manifest.pvisorRuntimeCommit || "") ||
|
|
34
|
-
!manifest.pvisorRuntimeDistribution?.startsWith(`${runtime.version}+g`)) {
|
|
35
|
-
throw new Error("pVisor plugin/native package version mismatch; reinstall the matching plugin release");
|
|
36
|
-
}
|
|
37
|
-
const bin = path.join(path.dirname(metadata), "bin");
|
|
38
|
-
for (const component of components) {
|
|
39
|
-
const file = path.join(bin, component);
|
|
40
|
-
const info = await lstat(file);
|
|
41
|
-
if (!info.isFile() || info.isSymbolicLink() || (info.mode & 0o022) !== 0) {
|
|
42
|
-
throw new Error(`Unsafe or incomplete native runtime component: ${component}`);
|
|
43
|
-
}
|
|
44
|
-
if (component !== "libkrunfw.SOURCE") await access(file, constants.X_OK);
|
|
45
|
-
}
|
|
46
|
-
return path.join(bin, "pvisor");
|
|
13
|
+
await access(binary, constants.X_OK);
|
|
14
|
+
return binary;
|
|
47
15
|
}
|
|
48
16
|
|
|
49
|
-
/** Probe
|
|
17
|
+
/** Probe required CLI capabilities; package and runtime versions are independent. */
|
|
50
18
|
export async function checkRuntimeContract(binary) {
|
|
51
19
|
const run = promisify(execFile);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
20
|
+
try {
|
|
21
|
+
for (const [command, flags] of [
|
|
22
|
+
["spawn", ["--safe", "--no-agent-defaults", "--stage", "--timeout", "--overlaynet-deny-all"]],
|
|
23
|
+
["apply", ["--path", "--dry-run", "--json"]],
|
|
24
|
+
]) {
|
|
25
|
+
const { stdout } = await run(binary, [command, "--help"], { timeout: 10_000, maxBuffer: 256 * 1024 });
|
|
26
|
+
for (const flag of flags) {
|
|
27
|
+
if (!stdout.includes(`${flag} `) && !stdout.includes(`${flag}\n`)) {
|
|
28
|
+
throw new Error(`${command} lacks ${flag}`);
|
|
29
|
+
}
|
|
60
30
|
}
|
|
61
31
|
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
throw new Error(`Incompatible pVisor at ${binary}: ${error.message}. ${installation} No downgraded execution is allowed.`);
|
|
62
34
|
}
|
|
63
35
|
return binary;
|
|
64
36
|
}
|
|
65
37
|
|
|
66
|
-
/**
|
|
67
|
-
export async function resolveRuntime(override) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
38
|
+
/** Use an operator override or the host PATH; never install or download a runtime. */
|
|
39
|
+
export async function resolveRuntime(override, { searchPath = process.env.PATH || "" } = {}) {
|
|
40
|
+
let binary;
|
|
41
|
+
if (override !== undefined) {
|
|
42
|
+
if (typeof override !== "string" || !path.isAbsolute(override) || override.includes("\0")) {
|
|
43
|
+
throw new Error("PVISOR_PLUGIN_BINARY must be an absolute executable path");
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
binary = await executable(override);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
throw new Error(`Cannot execute PVISOR_PLUGIN_BINARY ${override}: ${error.message}. ${installation}`);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
// Ignore cwd-dependent PATH entries. Allow Homebrew and venv symlinks.
|
|
52
|
+
for (const directory of searchPath.split(path.delimiter)) {
|
|
53
|
+
if (!path.isAbsolute(directory)) continue;
|
|
54
|
+
try {
|
|
55
|
+
binary = await executable(path.join(directory, "pvisor"));
|
|
56
|
+
break;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (!["ENOENT", "ENOTDIR", "EACCES"].includes(error.code)) throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!binary) throw new Error(`pVisor was not found on the Agent host PATH. ${installation}`);
|
|
62
|
+
}
|
|
63
|
+
// Revalidate separately upgraded runtimes; never fall back from incompatibility.
|
|
64
|
+
return checkRuntimeContract(binary);
|
|
71
65
|
}
|
|
@@ -25,14 +25,16 @@ Do not change Codex's approval settings.
|
|
|
25
25
|
The user can preview, accept explicit paths, or discard remaining candidates:
|
|
26
26
|
|
|
27
27
|
```sh
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
pvisor review "$stage" --diff
|
|
29
|
+
pvisor apply "$stage" --path src --dry-run --diff
|
|
30
|
+
pvisor apply "$stage" --path src
|
|
31
|
+
pvisor drop "$stage"
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
The user saves the exact returned selector as the terminal variable `stage`.
|
|
35
|
-
The plugin tools and native CLI take the same selector.
|
|
36
|
-
|
|
35
|
+
The plugin tools and native CLI take the same selector. The user installs the
|
|
36
|
+
native runtime separately through Homebrew or pip; npm supplies only the plugin.
|
|
37
|
+
Use the runtime selected by Doctor; missing or incompatible runtimes require
|
|
38
|
+
operator installation or upgrade, never a safety downgrade. Previously
|
|
37
39
|
applied files, network effects and external API effects are not reverted by drop.
|
|
38
40
|
Do not automatically discard on session shutdown.
|
package/tools.mjs
CHANGED
|
@@ -8,7 +8,7 @@ const object = (properties, required = []) => ({ type: "object", properties, req
|
|
|
8
8
|
export const tools = [
|
|
9
9
|
{
|
|
10
10
|
name: "pvisor_doctor",
|
|
11
|
-
description: "Check the pVisor CLI version and bound project. Reports task-only scope; does not certify mount availability or interception of native Agent tools.",
|
|
11
|
+
description: "Check the installed pVisor CLI capabilities, binary path, version and bound project. Missing/incompatible runtime requires Homebrew or pip installation/upgrade. Reports task-only scope; does not certify mount availability or interception of native Agent tools.",
|
|
12
12
|
inputSchema: object({}),
|
|
13
13
|
},
|
|
14
14
|
{
|
package/pvisor.mjs
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { resolveRuntime } from "./runtime.mjs";
|
|
4
|
-
|
|
5
|
-
try {
|
|
6
|
-
const binary = await resolveRuntime(process.env.PVISOR_PLUGIN_BINARY);
|
|
7
|
-
if (!path.isAbsolute(binary)) throw new Error("PVISOR_PLUGIN_BINARY must be an absolute executable path");
|
|
8
|
-
if (typeof process.execve !== "function") {
|
|
9
|
-
throw new Error("The pVisor npm launcher requires Node.js 22.19+ on Linux or macOS");
|
|
10
|
-
}
|
|
11
|
-
// Replace this launcher rather than inserting a parent into native terminal,
|
|
12
|
-
// foreground-group, signal and exit-status ownership.
|
|
13
|
-
process.execve(binary, [binary, ...process.argv.slice(2)], process.env);
|
|
14
|
-
} catch (error) {
|
|
15
|
-
console.error(String(error));
|
|
16
|
-
process.exitCode = 1;
|
|
17
|
-
}
|
package/runtime.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "0.3.1",
|
|
3
|
-
"repository": "DeepLink-org/pvisor",
|
|
4
|
-
"platforms": {
|
|
5
|
-
"linux-x64": {
|
|
6
|
-
"package": "pvisor-agent-runtime-linux-x64",
|
|
7
|
-
"archivePlatform": "linux-x86_64"
|
|
8
|
-
},
|
|
9
|
-
"darwin-arm64": {
|
|
10
|
-
"package": "pvisor-agent-runtime-darwin-arm64",
|
|
11
|
-
"archivePlatform": "macos-arm64"
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|