@omercnet/paseo-omp 0.4.0-next.131.1 → 0.4.0-next.134.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 CHANGED
@@ -20,7 +20,7 @@ before capture.
20
20
 
21
21
  ## Quick start
22
22
 
23
- Requirements: Paseo `>=0.9.0-beta.1 <0.10.0`, OMP `18.1.15` or newer, and OMP RPC protocol v2. Paseo 0.9 is required for the Help report's supported copy and external-link APIs, nested provider-subagent ancestry, spawning-tool links, npm-managed installation, and the complete client integration.
23
+ Requirements: Paseo `>=0.9.0 <0.10.0`, OMP `18.1.15` or newer, and OMP RPC protocol v2. Paseo 0.9 is required for the Help report's supported copy and external-link APIs, nested provider-subagent ancestry, spawning-tool links, npm-managed installation, and the complete client integration.
24
24
 
25
25
  ```bash
26
26
  paseo plugin install npm:@omercnet/paseo-omp@<version>
@@ -36,7 +36,7 @@ Open the **OMP** sidebar to review the provider-profile contract, choose which c
36
36
  - [Core-provider issue and parity audit](docs/core-provider-issue-audit.md)
37
37
  - [Alpha release checklist](docs/alpha-release-checklist.md)
38
38
 
39
- The plugin uses public Paseo 0.9 beta provider and client contracts and registers distinct `omp-plugin` and `omp-plugin-<profile>` identities; it does not modify the bundled `omp` provider.
39
+ The plugin uses public Paseo 0.9 provider and client contracts and registers distinct `omp-plugin` and `omp-plugin-<profile>` identities; it does not modify the bundled `omp` provider.
40
40
 
41
41
  ## Named OMP profiles
42
42
 
@@ -50,7 +50,7 @@ Profile selection is request-local: concurrent clients cannot change each other'
50
50
 
51
51
  ## Paseo provider SDK coverage
52
52
 
53
- This matrix inventories the complete capability set exported by the pinned `@getpaseo/plugin` 0.9.0-beta.1 provider SDK. It measures strict SDK surface coverage, not general product quality.
53
+ This matrix inventories the complete capability set exported by the pinned `@getpaseo/plugin` 0.9.0 provider SDK. It measures strict SDK surface coverage, not general product quality.
54
54
 
55
55
  **Current capability completeness: 61.8%.** The provider advertises 11 of 17 capabilities (64.7%); ten are complete and `session.configure` is partial.
56
56
 
@@ -113,7 +113,7 @@ Existing agents whose provider is `omp` remain owned by the bundled provider. Ne
113
113
 
114
114
  OMP `18.1.15` is the oldest version tested end to end. The direct provider's hard compatibility gate is `rpc-ui` protocol v2: metadata-free legacy ready frames and v1-only runtimes are rejected before a provider session opens because they cannot support the advertised persistence and conversation-rewind capabilities. Typed tool approvals remain capability-gated and fall back as described above. For terminal completion, a matching `agent_end.requestId` is authoritative and mismatches are ignored before state changes. Released OMP 18.2.x builds that omit that field use an ordered fallback requiring a fresh correlated native user entry followed by current-turn assistant activity, an idle non-compacting runtime, and no conflicting permission, tool, steer, or child-session work. Ambiguous events while OMP is active are ignored; unresolved ambiguity after confirmed idle fails only the Paseo turn. This trades a bounded residual same-agent stale-event risk for compatibility with released OMP instead of terminating and lazily restarting the runtime after every later prompt. Paseo clients, including mobile clients inside reconnect grace, do not own or terminate the daemon-managed OMP session.
115
115
 
116
- Paseo 0.9.0-beta.1 is the verified canary target and minimum supported release. It preserves nested provider-subagent ancestry and spawning-tool links, and provides npm-managed plugin sources, platform-owned external URL opening, and whole-item timeline transforms before Overview grouping. The required full Docker canary passes there with OMP 18.1.15 and 18.2.0.
116
+ Paseo 0.9.0 is the minimum supported release. The verified controlled canary evidence remains on the 0.9.0-beta.1 image, where the full Docker canary passed with OMP 18.1.15 and 18.2.0. That canary preserved nested provider-subagent ancestry and spawning-tool links, and validated npm-managed plugin sources, platform-owned external URL opening, and whole-item timeline transforms before Overview grouping.
117
117
 
118
118
  Install, update, disable, or remove `paseo-omp` independently of the bundled provider. Verify the provider snapshot contains `omp-plugin` after installation; a bundled `omp` entry may remain present and is not modified by this plugin.
119
119
 
@@ -99,7 +99,6 @@ function OrderedRoleEditor({
99
99
  return (
100
100
  <View style={styles.recordList}>
101
101
  {roles.map((role, index) => (
102
- // biome-ignore lint/suspicious/noArrayIndexKey: ordered rows are edited by position and must keep input identity while their value changes.
103
102
  <View key={index} style={styles.recordRow}>
104
103
  <Text style={styles.recordKey}>{index + 1}</Text>
105
104
  <TextInput
@@ -172,7 +171,6 @@ function RecordRoutingEditor({
172
171
  ? rawValue
173
172
  : "";
174
173
  return (
175
- // biome-ignore lint/suspicious/noArrayIndexKey: record keys are editable, so row position preserves input identity.
176
174
  <View key={index} style={styles.recordRow}>
177
175
  <TextInput
178
176
  accessibilityLabel={`${formatOmpSettingLabel(setting.path)} ${keyLabel} ${index + 1}`}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omercnet/paseo-omp",
3
- "version": "0.4.0-next.131.1",
3
+ "version": "0.4.0-next.134.1",
4
4
  "type": "module",
5
5
  "description": "Paseo integration for OMP, including its direct provider and workspace tooling.",
6
6
  "license": "MIT",
@@ -16,7 +16,7 @@
16
16
  "publishConfig": {
17
17
  "access": "public"
18
18
  },
19
- "packageManager": "npm@10.9.4",
19
+ "packageManager": "bun@1.4.2",
20
20
  "engines": {
21
21
  "node": ">=22.18.0"
22
22
  },
@@ -40,42 +40,41 @@
40
40
  "paseo-plugin.json"
41
41
  ],
42
42
  "scripts": {
43
- "check": "biome check --error-on-warnings .",
43
+ "check": "biome check .",
44
44
  "check:write": "biome check --write .",
45
- "test": "run-s test:ci:*",
45
+ "test": "vitest run",
46
46
  "test:coverage": "PASEO_OMP_COVERAGE=1 vitest run --coverage",
47
47
  "test:integration:docker": "node --import tsx scripts/test-docker-host-tools.ts",
48
48
  "test:integration:wsl": "node --import tsx scripts/test-wsl-host-tools.ts",
49
49
  "test:integration:canary": "node --import tsx scripts/test-canary.ts",
50
50
  "test:integration:install": "node --import tsx scripts/test-package-install.ts",
51
- "typecheck": "tsc --noEmit",
52
- "test:ci:unit": "vitest run",
53
- "build": "node ../.github/scripts/build-plugin.mjs"
51
+ "typecheck": "tsc --noEmit"
54
52
  },
55
53
  "dependencies": {
56
- "@getpaseo/protocol": "0.9.0-beta.1",
57
- "@modelcontextprotocol/sdk": "1.29.0",
54
+ "@getpaseo/protocol": "0.9.0",
55
+ "@modelcontextprotocol/sdk": "1.30.0",
58
56
  "yaml": "^2.9.0"
59
57
  },
60
58
  "devDependencies": {
61
- "@biomejs/biome": "^2.5.14",
62
- "@getpaseo/cli": "0.9.0-beta.1",
63
- "@getpaseo/client": "0.9.0-beta.1",
64
- "@getpaseo/plugin": "0.9.0-beta.1",
65
- "@getpaseo/server": "0.9.0-beta.1",
59
+ "@biomejs/biome": "^2.5.10",
60
+ "@getpaseo/cli": "0.9.0",
61
+ "@getpaseo/client": "0.9.0",
62
+ "@getpaseo/plugin": "0.9.0",
63
+ "@getpaseo/server": "0.9.0",
66
64
  "@oh-my-pi/pi-agent-core": "18.2.0",
67
65
  "@oh-my-pi/pi-coding-agent": "18.2.0",
68
66
  "@tanstack/react-query": "^5.102.3",
69
67
  "@types/node": "^24.10.1",
70
68
  "@types/react": "^19.2.18",
71
69
  "@vitest/coverage-v8": "^5.0.0",
72
- "npm-run-all2": "^9.0.3",
70
+ "esbuild": "0.28.2",
71
+ "pino": "10.3.1",
73
72
  "react": "19.1.0",
74
73
  "react-native": "0.81.5",
75
74
  "tsx": "^4.20.6",
76
75
  "typescript": "^7.0.2",
77
76
  "vitest": "^5.0.0",
78
- "zod": "^4.4.3"
77
+ "zod": "4.4.3"
79
78
  },
80
79
  "overrides": {
81
80
  "qs": "6.16.0"
package/paseo-plugin.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "id": "paseo-omp",
3
- "requirements": { "paseo": ">=0.9.0-beta.1 <0.10.0" },
3
+ "requirements": { "paseo": ">=0.9.0 <0.10.0" },
4
4
  "build": [["node", "scripts/prepare-dependencies.mjs"]]
5
5
  }
@@ -1,21 +1,54 @@
1
1
  import { execFileSync } from "node:child_process";
2
- import { existsSync } from "node:fs";
2
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
5
 
6
6
  const projectRoot = dirname(dirname(fileURLToPath(import.meta.url)));
7
7
 
8
- export function prepareDependencies(root = projectRoot, execute = execFileSync) {
9
- if (!existsSync(join(root, "package-lock.json"))) return false;
8
+ function loadRootCatalog(root) {
9
+ for (let directory = root; ; directory = dirname(directory)) {
10
+ const manifestPath = join(directory, "package.json");
11
+ if (existsSync(manifestPath)) {
12
+ const catalog = JSON.parse(readFileSync(manifestPath, "utf8")).catalog;
13
+ if (catalog) return catalog;
14
+ }
15
+ if (directory === dirname(directory)) return null;
16
+ }
17
+ }
18
+
19
+ function stageManifest(root, catalog, install) {
20
+ const manifestPath = join(root, "package.json");
21
+ const source = readFileSync(manifestPath, "utf8");
22
+ const manifest = JSON.parse(source);
23
+
24
+ for (const [name, spec] of Object.entries(manifest.dependencies ?? {})) {
25
+ if (spec !== "catalog:") continue;
26
+ if (typeof catalog[name] !== "string") throw new Error(`Missing catalog entry for ${name}`);
27
+ manifest.dependencies[name] = catalog[name];
28
+ }
29
+ delete manifest.devDependencies;
10
30
 
11
- execute(
12
- process.platform === "win32" ? "npm.cmd" : "npm",
13
- ["ci", "--omit=dev", "--ignore-scripts"],
14
- {
15
- cwd: root,
16
- stdio: "inherit",
17
- },
18
- );
31
+ writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
32
+ try {
33
+ install();
34
+ } finally {
35
+ writeFileSync(manifestPath, source);
36
+ }
37
+ }
38
+
39
+ export function prepareDependencies(root = projectRoot, execute = execFileSync) {
40
+ const catalog = loadRootCatalog(root);
41
+ if (!catalog) return false;
42
+ stageManifest(root, catalog, () => {
43
+ execute(
44
+ process.platform === "win32" ? "npm.cmd" : "npm",
45
+ ["install", "--omit=dev", "--ignore-scripts", "--no-package-lock", "--workspaces=false"],
46
+ {
47
+ cwd: root,
48
+ stdio: "inherit",
49
+ },
50
+ );
51
+ });
19
52
  return true;
20
53
  }
21
54
 
@@ -1,2 +1,2 @@
1
1
  /** Release Please keeps this bundle-safe constant aligned with package.json. */
2
- export const PASEO_OMP_PACKAGE_VERSION = "0.4.0-next.131.1"; // x-release-please-version
2
+ export const PASEO_OMP_PACKAGE_VERSION = "0.4.0-next.134.1"; // x-release-please-version
@@ -225,7 +225,7 @@ export class SupervisedStdioClientTransport implements Transport {
225
225
  return;
226
226
  }
227
227
  const treeCleanup = this.startTreeCleanup();
228
- if (!this.exited) {
228
+ if (this.platform !== "win32" && !this.exited) {
229
229
  try {
230
230
  child.stdin.end();
231
231
  } catch {
@@ -233,6 +233,13 @@ export class SupervisedStdioClientTransport implements Transport {
233
233
  }
234
234
  }
235
235
  const terminated = await treeCleanup;
236
+ if (this.platform === "win32" && terminated && !this.exited) {
237
+ try {
238
+ child.stdin.end();
239
+ } catch {
240
+ // Process-tree cleanup remains authoritative when the input channel is already closed.
241
+ }
242
+ }
236
243
  const exited =
237
244
  this.spawnFailedWithoutProcess ||
238
245
  this.exited ||
@@ -475,7 +475,7 @@ export class OmpRpcProcess {
475
475
  this.clearChunk();
476
476
  this.failPending(new Error("OMP RPC process was closed"));
477
477
  const cleanupPromise = this.startTreeCleanup();
478
- if (!this.exited) {
478
+ if (process.platform !== "win32" && !this.exited) {
479
479
  try {
480
480
  this.child.stdin.end();
481
481
  } catch {
@@ -484,6 +484,13 @@ export class OmpRpcProcess {
484
484
  }
485
485
  const cleanup = await cleanupPromise;
486
486
  if (cleanup !== "verified") throw new Error("OMP RPC process tree cleanup failed");
487
+ if (process.platform === "win32" && !this.exited) {
488
+ try {
489
+ this.child.stdin.end();
490
+ } catch {
491
+ // Process-tree cleanup remains authoritative when the input channel is already closed.
492
+ }
493
+ }
487
494
  if (
488
495
  !this.spawnFailedWithoutProcess &&
489
496
  !this.exited &&