jorgex-pi 0.8.30 → 0.8.31

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 CHANGED
@@ -132,7 +132,7 @@ Context7 uses the canonical endpoint `https://mcp.context7.com/mcp`. `CONTEXT7_A
132
132
 
133
133
  The runner's `status` and `doctor` commands report whether Context7 configuration permits registration; `available` does not mean that an HTTP handshake has occurred. `sync` fails closed on a Context7 conflict and does not modify MCP configuration. At `session_start`, JorgeX registers Context7 and strict DevTools through the external adapter's runtime event bus; it does not create a bundled adapter or fallback factory. Missing, duplicate, malformed, unreadable, or conflicting official setup fails closed with a remediation to run `engram setup pi` and correct the external configuration.
134
134
 
135
- When a compatible Stack projection provides `PI_CODING_AGENT_DIR/jorgex-pi/devtools.v1.json`, the bridge validates that optional handoff and registers strict DevTools through the external adapter. The handoff must contain only `schemaVersion: 1`, `enabled: true`, an absolute executable command and the canonical `dlx chrome-devtools-mcp@1.6.0 --isolated --redact-network-headers --no-performance-crux --no-usage-statistics` arguments. Pi reads it at bootstrap and never edits it; Stack owns its lifecycle. DevTools is advertised only when that managed handoff is valid and the external adapter accepts the registration. The registration is lazy/proxy (`directTools: false`); `MCP_DIRECT_TOOLS` is not used. Changing or removing the handoff requires reloading Pi because registration is created once per session.
135
+ When a compatible Stack projection provides `PI_CODING_AGENT_DIR/jorgex-pi/devtools.v1.json`, the bridge validates that optional handoff and registers strict DevTools through the external adapter. The handoff must contain only `schemaVersion: 1`, `enabled: true`, an absolute executable command, and `dlx chrome-devtools-mcp@<exact-stable-version> --isolated --redact-network-headers --no-performance-crux --no-usage-statistics`. Pi accepts only an exact stable semver in the package argument, reads the handoff at bootstrap, and never edits it; Stack owns its lifecycle. This Pi consumer validates the handoff shape, executable path, version form, and privacy flags; it does not download, checksum, or authenticate the DevTools binary. DevTools is advertised only when that managed handoff is valid and the external adapter accepts the registration. The registration is lazy/proxy (`directTools: false`); `MCP_DIRECT_TOOLS` is not used. Changing or removing the handoff requires reloading Pi because registration is created once per session.
136
136
 
137
137
  The official setup owns the Engram binary, database, and memories. Pi only validates the external configuration needed for the session and never installs, updates, removes, or takes ownership of that state. Child environment handling is provider/runtime-owned; JorgeX defines no environment allowlist. Provider-managed `gentle-engram` hooks may automatically persist session, prompt, and compaction context; JorgeX does not own or configure those hooks.
138
138
 
@@ -176,12 +176,12 @@ The optional Stack handoff is `PI_CODING_AGENT_DIR/jorgex-pi/playwright.v1.json`
176
176
  {
177
177
  "schemaVersion": 1,
178
178
  "enabled": true,
179
- "version": "0.1.18",
179
+ "version": "<exact-stable-version>",
180
180
  "command": "/absolute/path/to/playwright-cli"
181
181
  }
182
182
  ```
183
183
 
184
- Pi accepts the handoff only when `schemaVersion` is `1`, `enabled` is `true`, `version` is exactly `0.1.18`, `command` is absolute and executable, and invoking that path with `--version` returns the pinned version. The resolver does not search `PATH`, inspect browser profiles, open a user session, or test whether a live browser can launch. Stack owns installation of the global CLI and Chromium, including browser readiness checks; the Pi capability check validates only the executable handoff.
184
+ Pi accepts the handoff only when `schemaVersion` is `1`, `enabled` is `true`, `version` is an exact stable semver, `command` is absolute and executable, and invoking that path with `--version` returns exactly the handoff version. The resolver does not search `PATH`, inspect browser profiles, open a user session, or test whether a live browser can launch. Stack owns installation of the global CLI and Chromium, including browser readiness checks; the Pi capability check validates only the executable handoff and does not download, checksum, or authenticate the CLI binary.
185
185
 
186
186
  When the handoff is absent, malformed, or fails the version check, the capability stays hidden and the browser guidance is omitted. A manually written file that satisfies the same schema and executable/version checks is accepted; Pi does not authenticate its provenance. Once a valid handoff is present, Pi exposes the routing with the managed command path. The bootstrap resolves it in `before_agent_start` for each agent turn and does not rewrite it; changing or removing the file is re-evaluated on the next turn. The capability is advertised as `playwright-handoff-v1`; this resolver state does not certify live browser readiness. Its adoption is a separate Stack change and does not alter Pi's canonical snapshot or shared source commit.
187
187
 
@@ -2,8 +2,8 @@
2
2
  "schemaVersion": 1,
3
3
  "package": {
4
4
  "name": "jorgex-pi",
5
- "version": "0.8.30",
6
- "source": "npm:jorgex-pi@0.8.30"
5
+ "version": "0.8.31",
6
+ "source": "npm:jorgex-pi@0.8.31"
7
7
  },
8
8
  "pi": {
9
9
  "minimumVersion": "0.84.2",
@@ -17,9 +17,9 @@ export const RUNTIME_SNAPSHOT_VERSION = 1;
17
17
  export const CONTEXT7_URL = "https://mcp.context7.com/mcp";
18
18
  const OFFICIAL_ENGRAM_ARGS = ["mcp", "--tools=agent"];
19
19
  const DEVTOOLS_HANDOFF_RELATIVE_PATH = ["jorgex-pi", "devtools.v1.json"];
20
- const DEVTOOLS_HANDOFF_ARGS = [
21
- "dlx",
22
- "chrome-devtools-mcp@1.6.0",
20
+ const DEVTOOLS_PACKAGE_PREFIX = "chrome-devtools-mcp@";
21
+ const STABLE_EXACT_SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
22
+ const DEVTOOLS_FIXED_SUFFIX_ARGS = [
23
23
  "--isolated",
24
24
  "--redact-network-headers",
25
25
  "--no-performance-crux",
@@ -207,14 +207,27 @@ function readChromeDevToolsHandoff({ env, platform }) {
207
207
  if (!isExecutable(handoff.command, platform)) {
208
208
  throw new Error(`Chrome DevTools handoff command is not executable at ${handoffPath}`);
209
209
  }
210
- if (!Array.isArray(handoff.args)
211
- || handoff.args.length !== DEVTOOLS_HANDOFF_ARGS.length
212
- || handoff.args.some((arg, index) => arg !== DEVTOOLS_HANDOFF_ARGS[index])) {
210
+ if (!isDevToolsArgs(handoff.args)) {
213
211
  throw new Error(`Chrome DevTools handoff has invalid arguments at ${handoffPath}`);
214
212
  }
215
213
  return { command: handoff.command, args: handoff.args };
216
214
  }
217
215
 
216
+ function isDevToolsArgs(args) {
217
+ if (!Array.isArray(args) || args.length !== 6) return false;
218
+ if (args[0] !== "dlx" || !isDevToolsPackageArg(args[1])) return false;
219
+ return args.slice(2).every((arg, index) => arg === DEVTOOLS_FIXED_SUFFIX_ARGS[index]);
220
+ }
221
+
222
+ function isDevToolsPackageArg(arg) {
223
+ if (typeof arg !== "string" || !arg.startsWith(DEVTOOLS_PACKAGE_PREFIX)) return false;
224
+ return isStableExactVersion(arg.slice(DEVTOOLS_PACKAGE_PREFIX.length));
225
+ }
226
+
227
+ function isStableExactVersion(version) {
228
+ return typeof version === "string" && STABLE_EXACT_SEMVER.test(version);
229
+ }
230
+
218
231
  export function resolveConfiguredEngramBinary({
219
232
  env = process.env,
220
233
  platform = process.platform,
@@ -4,7 +4,7 @@ import { homedir } from "node:os";
4
4
  import { posix, win32 } from "node:path";
5
5
 
6
6
  const HANDOFF_RELATIVE_PATH = ["jorgex-pi", "playwright.v1.json"];
7
- const PLAYWRIGHT_VERSION = "0.1.18";
7
+ const STABLE_EXACT_SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
8
8
  const VERSION_TIMEOUT_MS = 5_000;
9
9
  const CONTROL_CHARACTERS = /[\u0000-\u001f\u007f]/;
10
10
  const WINDOWS_CMD_METACHARACTERS = /[&|<>()^%!"\r\n]/;
@@ -35,7 +35,7 @@ export function resolvePlaywrightCapability({
35
35
  ...(invocation.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}),
36
36
  env: { ...env, NO_UPDATE_NOTIFIER: "1" },
37
37
  });
38
- if (!isExpectedVersion(output)) return hiddenCapability();
38
+ if (!isExpectedVersion(output, handoff.version)) return hiddenCapability();
39
39
 
40
40
  return { status: "ready", commandPath: handoff.command };
41
41
  } catch {
@@ -60,10 +60,10 @@ function readHandoff(handoffPath, paths) {
60
60
  if (!isRecord(parsed)) return undefined;
61
61
  const keys = Object.keys(parsed).sort();
62
62
  if (keys.join("\0") !== ["command", "enabled", "schemaVersion", "version"].join("\0")) return undefined;
63
- if (parsed.schemaVersion !== 1 || parsed.enabled !== true || parsed.version !== PLAYWRIGHT_VERSION) return undefined;
63
+ if (parsed.schemaVersion !== 1 || parsed.enabled !== true || !isStableExactVersion(parsed.version)) return undefined;
64
64
  if (typeof parsed.command !== "string" || CONTROL_CHARACTERS.test(parsed.command)) return undefined;
65
65
  if (!paths.isAbsolute(parsed.command)) return undefined;
66
- return { command: parsed.command };
66
+ return { command: parsed.command, version: parsed.version };
67
67
  }
68
68
 
69
69
  function resolveDefaultAgentDir({ env, platform, paths }) {
@@ -97,8 +97,14 @@ function planExecutable(command, platform, env) {
97
97
  };
98
98
  }
99
99
 
100
- function isExpectedVersion(output) {
101
- return /^(?:playwright-cli\s+)?0\.1\.18$/i.test(String(output).trim());
100
+ function isExpectedVersion(output, version) {
101
+ const trimmed = String(output).trim();
102
+ const reported = /^playwright-cli\s+/i.test(trimmed) ? trimmed.replace(/^playwright-cli\s+/i, "") : trimmed;
103
+ return reported === version;
104
+ }
105
+
106
+ function isStableExactVersion(version) {
107
+ return typeof version === "string" && STABLE_EXACT_SEMVER.test(version);
102
108
  }
103
109
 
104
110
  function isExecutable(path, platform) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jorgex-pi",
3
- "version": "0.8.30",
3
+ "version": "0.8.31",
4
4
  "description": "Pi-native runtime package for the JorgeX harness.",
5
5
  "license": "MIT",
6
6
  "repository": {