@samuelho-dev/coordinator 0.3.0-beta.3 → 0.3.0-beta.4
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 +9 -7
- package/dist/plugins/omp.js +9 -19
- package/dist/plugins/pi.js +10 -20
- package/dist/src/plugin.js +11 -20
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ There are two parts: **one inspector service**, plus **native integrations on ea
|
|
|
9
9
|
The API and setup CLI require Node >=22.19. Install the version-pinned release:
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
npm install --global @samuelho-dev/coordinator@0.3.0-beta.
|
|
12
|
+
npm install --global @samuelho-dev/coordinator@0.3.0-beta.4
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
For source development only, use a reviewed checkout with `pnpm install --frozen-lockfile && pnpm build` (pnpm 11.9.0). `coordinator-install --source` deliberately activates that exact local package; never source-link a native package manager's own `node_modules` directory.
|
|
@@ -100,8 +100,8 @@ The installer validates prerequisites and creates launchers/config fragments. `-
|
|
|
100
100
|
|
|
101
101
|
| Target | Activation | Presence publisher |
|
|
102
102
|
| --- | --- | --- |
|
|
103
|
-
| OMP | `omp plugin install @samuelho-dev/coordinator@0.3.0-beta.
|
|
104
|
-
| Pi | `pi install npm:@samuelho-dev/coordinator@0.3.0-beta.
|
|
103
|
+
| OMP | `omp plugin install @samuelho-dev/coordinator@0.3.0-beta.4`; merge only the generated `mcp.json` coordinator entry into native MCP settings. `/coordinator list` needs no MCP registration. | In-session extension. |
|
|
104
|
+
| Pi | `pi install npm:@samuelho-dev/coordinator@0.3.0-beta.4`; directly registers `coordinator_session_list` / `coordinator_session_inspect`, without an MCP bridge. | In-session extension. |
|
|
105
105
|
| Claude Code | `claude --plugin-dir "$PRIVATE/claude-host"`; approve generated hooks/MCP tools; preserve existing status-line configuration. | Separate `connector.sh`. |
|
|
106
106
|
| Codex CLI | Merge generated `hooks/hooks.json` and coordinator `mcp.toml`; trust only Coordinator's handlers in native `/hooks`. | Separate `connector.sh`. |
|
|
107
107
|
| Hermes | Merge generated hook entries and `mcp_servers.coordinator` from `mcp.yaml` into the selected profile; no Python plugin installation. | Separate `connector.sh`. |
|
|
@@ -118,7 +118,7 @@ Hook/status-line/notification capture is local and can initialize identity/cache
|
|
|
118
118
|
|
|
119
119
|
### Native session commands and Rex
|
|
120
120
|
|
|
121
|
-
Pi/OMP register `/coordinator list`. It follows every API page visible to the owner key and
|
|
121
|
+
Pi/OMP register `/coordinator list`. It follows every API page visible to the owner key and returns pretty JSON (`{ "sessions": [...] }`) using Effect's JSON formatter, with native JSON syntax highlighting in the terminal. Each session preserves full native session/agent IDs, machine names/installation IDs, harness and all reported metadata: model/provider, workspace, activity, connection liveness, process identity and Rex association. Missing metadata is omitted; an empty listing returns `{ "sessions": [] }`. It reads the API directly, with no model turn, per-session resource sampling or separate MCP registration.
|
|
122
122
|
|
|
123
123
|
Session JSON is Coordinator's fleet model, not an OSC wire payload. `rex` preserves `REX_SERVER` as `serverAddress` and the actual full `REX_SESSION`/`REX_BLOCK` IDs; these are separate from native agent IDs. Optional `programStatus` uses [Rex Program Status Protocol](https://www.superlogical.com/rex/docs/build/program-status) semantics: idle/working/done/error, or blocked with permission/question/auth kind. Agent `kind` remains separate. Tool/API waits are working; unknown outcomes are omitted, not inferred from disconnects or generic stops. API connection leases do not expire terminal status records.
|
|
124
124
|
|
|
@@ -133,13 +133,13 @@ This is a clean schema cutover, with no legacy aliases or compatibility shims. B
|
|
|
133
133
|
|
|
134
134
|
## Plugin publication
|
|
135
135
|
|
|
136
|
-
The version-pinned beta is `@samuelho-dev/coordinator@0.3.0-beta.
|
|
136
|
+
The version-pinned beta is `@samuelho-dev/coordinator@0.3.0-beta.4`. The [npm workflow](.github/workflows/npm-release.yaml) promotes the exact-source CI-accepted tarball with owner authorization; [first-publication authentication and trust setup](#first-npm-publication) are prerequisites for a new publisher. The existing [release workflow](.github/workflows/release.yaml) publishes server/chart/GitHub artifacts, not native marketplace listings. Generated per-machine configuration is not a portable marketplace package.
|
|
137
137
|
|
|
138
138
|
For a version-pinned install, use your native package manager, then follow [configuration](#configuration) and [native host setup](#native-host-setup):
|
|
139
139
|
|
|
140
140
|
```sh
|
|
141
|
-
omp plugin install @samuelho-dev/coordinator@0.3.0-beta.
|
|
142
|
-
pi install npm:@samuelho-dev/coordinator@0.3.0-beta.
|
|
141
|
+
omp plugin install @samuelho-dev/coordinator@0.3.0-beta.4
|
|
142
|
+
pi install npm:@samuelho-dev/coordinator@0.3.0-beta.4
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
Stock OMP 18.12.6 does not automatically update npm plugins. Until upstream fixes its channel handling and dry-run behavior, use explicit versioned installs for updates; avoid `omp plugin upgrade` and `upgrade --dry-run` for beta releases.
|
|
@@ -148,6 +148,8 @@ Stock OMP 18.12.6 does not automatically update npm plugins. Until upstream fixe
|
|
|
148
148
|
|
|
149
149
|
`0.3.0-beta.3` adds native `/coordinator list`, secure self-host bootstrap/authenticated client setup, and Rex references/status normalization without an OMP fork. Runtime dependency pins are unchanged.
|
|
150
150
|
|
|
151
|
+
`0.3.0-beta.4` fixes `/coordinator list` output: Effect-formatted, indented JSON with native syntax highlighting instead of hand-built text and literal fences. Native UI imports are static and selected at build time; the renderer registers once at startup. The session wire format and runtime dependencies are unchanged, so the existing beta.3 API needs no redeployment.
|
|
152
|
+
|
|
151
153
|
| Host | Publication route |
|
|
152
154
|
| --- | --- |
|
|
153
155
|
| [OMP](https://github.com/can1357/oh-my-pi/blob/main/docs/marketplace.md) | Publish a Git-backed `.omp-plugin/marketplace.json` catalog and runnable plugin tree with `package.json` `omp.extensions`. Claude-compatible `.claude-plugin/marketplace.json` is a fallback. npm catalog sources are not supported; ordinary `omp plugin install PACKAGE` is a separate npm route. |
|
package/dist/plugins/omp.js
CHANGED
|
@@ -72327,6 +72327,8 @@ var Cache = Schema_exports.Struct({ version: Schema_exports.Literal(2), kind: Sc
|
|
|
72327
72327
|
var ClaudeRoster = Schema_exports.Array(Schema_exports.Struct({ sessionId: Schema_exports.optional(Id2), id: Schema_exports.optional(Id2), pid: Schema_exports.optional(Schema_exports.Int), cwd: Schema_exports.optional(Schema_exports.String), kind: Schema_exports.optional(Id2), status: Schema_exports.optional(Schema_exports.Literals(["busy", "waiting", "idle"])), waitingFor: Schema_exports.optional(Schema_exports.String) })).check(Schema_exports.isMaxLength(256));
|
|
72328
72328
|
|
|
72329
72329
|
// src/plugin.ts
|
|
72330
|
+
import { highlightCode } from "@oh-my-pi/pi-coding-agent";
|
|
72331
|
+
import { Text } from "@oh-my-pi/pi-tui";
|
|
72330
72332
|
var provenance = (source, scope3, scopeDescription, observedAt, nativeUpdatedAt = null) => ({
|
|
72331
72333
|
source,
|
|
72332
72334
|
scope: scope3,
|
|
@@ -72550,23 +72552,6 @@ var registerCoordinateKeyword = Effect_exports.gen(function* () {
|
|
|
72550
72552
|
const { isMagicKeyword, setMagicKeywords } = yield* Effect_exports.tryPromise({ try: () => import("@oh-my-pi/pi-tui/prompt/magic-keywords"), catch: () => new NativeError({ operation: "Load native keyword highlighter" }) });
|
|
72551
72553
|
setMagicKeywords([...MAGIC_KEYWORDS.filter(({ word }) => isMagicKeyword(word)), { word: "coordinate", hue: [190, 260] }]);
|
|
72552
72554
|
});
|
|
72553
|
-
var formatSessionList = (sessions) => {
|
|
72554
|
-
if (sessions.length === 0) return "No sessions are currently visible to this API key.";
|
|
72555
|
-
const lines = [`Coordinator: ${sessions.length} sessions visible to this API key.`, "", "~~~text"];
|
|
72556
|
-
for (const session of sessions) {
|
|
72557
|
-
lines.push(
|
|
72558
|
-
`Machine: ${JSON.stringify(session.machineName ?? "unavailable")} (${JSON.stringify(session.ref.machineId)})`,
|
|
72559
|
-
`Session: ${session.ref.harness} ${JSON.stringify(session.ref.nativeSessionId)}`
|
|
72560
|
-
);
|
|
72561
|
-
if (session.ref.nativeAgentId !== void 0) lines.push(`Agent ID: ${JSON.stringify(session.ref.nativeAgentId)}`);
|
|
72562
|
-
for (const [field, value5] of Object.entries(session)) {
|
|
72563
|
-
if (field !== "ref" && field !== "machineName" && value5 !== void 0) lines.push(`${field}: ${JSON.stringify(value5)}`);
|
|
72564
|
-
}
|
|
72565
|
-
lines.push("");
|
|
72566
|
-
}
|
|
72567
|
-
lines.push("~~~");
|
|
72568
|
-
return lines.join("\n");
|
|
72569
|
-
};
|
|
72570
72555
|
function plugin(host) {
|
|
72571
72556
|
const harness = "omp";
|
|
72572
72557
|
const runtime2 = ManagedRuntime_exports.make(Layer_exports.mergeAll(NodeServices_exports.layer, Host2.layer, Mcp.layer, Layer_exports.succeed(Logger_exports.LogToStderr, true)));
|
|
@@ -72576,6 +72561,10 @@ function plugin(host) {
|
|
|
72576
72561
|
let stopped = false;
|
|
72577
72562
|
const rexReporter = harness === "pi" ? createRexReporter((sequence) => process.stdout.write(sequence)) : void 0;
|
|
72578
72563
|
let terminal = false;
|
|
72564
|
+
host.registerMessageRenderer("coordinator-list", (message) => {
|
|
72565
|
+
if (typeof message.content !== "string") return void 0;
|
|
72566
|
+
return new Text(message.details === void 0 ? message.content : highlightCode(message.content, "json").join("\n"), 0, 0);
|
|
72567
|
+
});
|
|
72579
72568
|
host.registerCommand("coordinator", {
|
|
72580
72569
|
description: "List visible sessions, their machines, and native metadata",
|
|
72581
72570
|
handler: async (args2) => {
|
|
@@ -72608,11 +72597,12 @@ function plugin(host) {
|
|
|
72608
72597
|
}, { triggerTurn: false });
|
|
72609
72598
|
return;
|
|
72610
72599
|
}
|
|
72600
|
+
const result5 = { sessions: exit3.value };
|
|
72611
72601
|
host.sendMessage({
|
|
72612
72602
|
customType: "coordinator-list",
|
|
72613
|
-
content:
|
|
72603
|
+
content: Formatter_exports.formatJson(result5, { space: 2 }),
|
|
72614
72604
|
display: true,
|
|
72615
|
-
details:
|
|
72605
|
+
details: result5
|
|
72616
72606
|
}, { triggerTurn: false });
|
|
72617
72607
|
}
|
|
72618
72608
|
});
|
package/dist/plugins/pi.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/plugin.ts
|
|
2
2
|
import { NodeServices } from "@effect/platform-node";
|
|
3
|
-
import { Cause as Cause3, Clock as Clock3, Console as Console2, Effect as Effect7, Layer as Layer3, Logger, ManagedRuntime, Schema as Schema5 } from "effect";
|
|
3
|
+
import { Cause as Cause3, Clock as Clock3, Console as Console2, Effect as Effect7, Formatter as Formatter2, Layer as Layer3, Logger, ManagedRuntime, Schema as Schema5 } from "effect";
|
|
4
4
|
|
|
5
5
|
// src/inspection.ts
|
|
6
6
|
import { Effect, Option, Path as PlatformPath, Schema, SchemaParser } from "effect";
|
|
@@ -1191,6 +1191,8 @@ var Cache = Schema4.Struct({ version: Schema4.Literal(2), kind: Schema4.Literal(
|
|
|
1191
1191
|
var ClaudeRoster = Schema4.Array(Schema4.Struct({ sessionId: Schema4.optional(Id2), id: Schema4.optional(Id2), pid: Schema4.optional(Schema4.Int), cwd: Schema4.optional(Schema4.String), kind: Schema4.optional(Id2), status: Schema4.optional(Schema4.Literals(["busy", "waiting", "idle"])), waitingFor: Schema4.optional(Schema4.String) })).check(Schema4.isMaxLength(256));
|
|
1192
1192
|
|
|
1193
1193
|
// src/plugin.ts
|
|
1194
|
+
import { highlightCode } from "@earendil-works/pi-coding-agent";
|
|
1195
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
1194
1196
|
var provenance = (source, scope, scopeDescription, observedAt, nativeUpdatedAt = null) => ({
|
|
1195
1197
|
source,
|
|
1196
1198
|
scope,
|
|
@@ -1414,23 +1416,6 @@ var registerCoordinateKeyword = Effect7.gen(function* () {
|
|
|
1414
1416
|
const { isMagicKeyword, setMagicKeywords } = yield* Effect7.tryPromise({ try: () => import("@oh-my-pi/pi-tui/prompt/magic-keywords"), catch: () => new NativeError({ operation: "Load native keyword highlighter" }) });
|
|
1415
1417
|
setMagicKeywords([...MAGIC_KEYWORDS.filter(({ word }) => isMagicKeyword(word)), { word: "coordinate", hue: [190, 260] }]);
|
|
1416
1418
|
});
|
|
1417
|
-
var formatSessionList = (sessions) => {
|
|
1418
|
-
if (sessions.length === 0) return "No sessions are currently visible to this API key.";
|
|
1419
|
-
const lines = [`Coordinator: ${sessions.length} sessions visible to this API key.`, "", "~~~text"];
|
|
1420
|
-
for (const session of sessions) {
|
|
1421
|
-
lines.push(
|
|
1422
|
-
`Machine: ${JSON.stringify(session.machineName ?? "unavailable")} (${JSON.stringify(session.ref.machineId)})`,
|
|
1423
|
-
`Session: ${session.ref.harness} ${JSON.stringify(session.ref.nativeSessionId)}`
|
|
1424
|
-
);
|
|
1425
|
-
if (session.ref.nativeAgentId !== void 0) lines.push(`Agent ID: ${JSON.stringify(session.ref.nativeAgentId)}`);
|
|
1426
|
-
for (const [field, value] of Object.entries(session)) {
|
|
1427
|
-
if (field !== "ref" && field !== "machineName" && value !== void 0) lines.push(`${field}: ${JSON.stringify(value)}`);
|
|
1428
|
-
}
|
|
1429
|
-
lines.push("");
|
|
1430
|
-
}
|
|
1431
|
-
lines.push("~~~");
|
|
1432
|
-
return lines.join("\n");
|
|
1433
|
-
};
|
|
1434
1419
|
function plugin(host) {
|
|
1435
1420
|
const harness = "pi";
|
|
1436
1421
|
const runtime = ManagedRuntime.make(Layer3.mergeAll(NodeServices.layer, Host.layer, Mcp.layer, Layer3.succeed(Logger.LogToStderr, true)));
|
|
@@ -1440,6 +1425,10 @@ function plugin(host) {
|
|
|
1440
1425
|
let stopped = false;
|
|
1441
1426
|
const rexReporter = harness === "pi" ? createRexReporter((sequence) => process.stdout.write(sequence)) : void 0;
|
|
1442
1427
|
let terminal = false;
|
|
1428
|
+
host.registerMessageRenderer("coordinator-list", (message) => {
|
|
1429
|
+
if (typeof message.content !== "string") return void 0;
|
|
1430
|
+
return new Text(message.details === void 0 ? message.content : highlightCode(message.content, "json").join("\n"), 0, 0);
|
|
1431
|
+
});
|
|
1443
1432
|
host.registerCommand("coordinator", {
|
|
1444
1433
|
description: "List visible sessions, their machines, and native metadata",
|
|
1445
1434
|
handler: async (args) => {
|
|
@@ -1472,11 +1461,12 @@ function plugin(host) {
|
|
|
1472
1461
|
}, { triggerTurn: false });
|
|
1473
1462
|
return;
|
|
1474
1463
|
}
|
|
1464
|
+
const result = { sessions: exit.value };
|
|
1475
1465
|
host.sendMessage({
|
|
1476
1466
|
customType: "coordinator-list",
|
|
1477
|
-
content:
|
|
1467
|
+
content: Formatter2.formatJson(result, { space: 2 }),
|
|
1478
1468
|
display: true,
|
|
1479
|
-
details:
|
|
1469
|
+
details: result
|
|
1480
1470
|
}, { triggerTurn: false });
|
|
1481
1471
|
}
|
|
1482
1472
|
});
|
package/dist/src/plugin.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { NodeServices } from "@effect/platform-node";
|
|
2
|
-
import { Cause, Clock, Console, Effect, Layer, Logger, ManagedRuntime, Schema } from "effect";
|
|
2
|
+
import { Cause, Clock, Console, Effect, Formatter, Layer, Logger, ManagedRuntime, Schema } from "effect";
|
|
3
3
|
import { createInspection, HttpError, InspectionTools, metric, sessionRefKey, unavailableMetric } from "./inspection.js";
|
|
4
4
|
import { Mcp } from "./mcp.js";
|
|
5
5
|
import { connectNative, loadConnectorConfig, NativeError, readConnectorToken, resolveNativeConfig, withProcessResources } from "./native.js";
|
|
6
6
|
import { identifyProcess } from "./resources.js";
|
|
7
7
|
import { Host as PlatformHost } from "./platform.js";
|
|
8
8
|
import { createRexReporter, readRexContext } from "./rex.js";
|
|
9
|
+
import { highlightCode } from "@earendil-works/pi-coding-agent";
|
|
10
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
9
11
|
const provenance = (source, scope, scopeDescription, observedAt, nativeUpdatedAt = null) => ({
|
|
10
12
|
source, scope, scopeDescription, observedAt, nativeUpdatedAt, estimated: false, derived: false, shared: false, partial: false, stale: false,
|
|
11
13
|
});
|
|
@@ -197,23 +199,6 @@ export const registerCoordinateKeyword = Effect.gen(function* () {
|
|
|
197
199
|
// ponytail: native exposes no registry getter/append; only known core keywords can be preserved.
|
|
198
200
|
setMagicKeywords([...MAGIC_KEYWORDS.filter(({ word }) => isMagicKeyword(word)), { word: "coordinate", hue: [190, 260] }]);
|
|
199
201
|
});
|
|
200
|
-
const formatSessionList = (sessions) => {
|
|
201
|
-
if (sessions.length === 0)
|
|
202
|
-
return "No sessions are currently visible to this API key.";
|
|
203
|
-
const lines = [`Coordinator: ${sessions.length} sessions visible to this API key.`, "", "~~~text"];
|
|
204
|
-
for (const session of sessions) {
|
|
205
|
-
lines.push(`Machine: ${JSON.stringify(session.machineName ?? "unavailable")} (${JSON.stringify(session.ref.machineId)})`, `Session: ${session.ref.harness} ${JSON.stringify(session.ref.nativeSessionId)}`);
|
|
206
|
-
if (session.ref.nativeAgentId !== undefined)
|
|
207
|
-
lines.push(`Agent ID: ${JSON.stringify(session.ref.nativeAgentId)}`);
|
|
208
|
-
for (const [field, value] of Object.entries(session)) {
|
|
209
|
-
if (field !== "ref" && field !== "machineName" && value !== undefined)
|
|
210
|
-
lines.push(`${field}: ${JSON.stringify(value)}`);
|
|
211
|
-
}
|
|
212
|
-
lines.push("");
|
|
213
|
-
}
|
|
214
|
-
lines.push("~~~");
|
|
215
|
-
return lines.join("\n");
|
|
216
|
-
};
|
|
217
202
|
export default function plugin(host) {
|
|
218
203
|
const harness = COORDINATOR_HARNESS;
|
|
219
204
|
const runtime = ManagedRuntime.make(Layer.mergeAll(NodeServices.layer, PlatformHost.layer, Mcp.layer, Layer.succeed(Logger.LogToStderr, true)));
|
|
@@ -224,6 +209,11 @@ export default function plugin(host) {
|
|
|
224
209
|
// Stock OMP owns OSC 7501 (terminal.programStatus); never duplicate or override it.
|
|
225
210
|
const rexReporter = harness === "pi" ? createRexReporter((sequence) => process.stdout.write(sequence)) : undefined;
|
|
226
211
|
let terminal = false;
|
|
212
|
+
host.registerMessageRenderer("coordinator-list", (message) => {
|
|
213
|
+
if (typeof message.content !== "string")
|
|
214
|
+
return undefined;
|
|
215
|
+
return new Text(message.details === undefined ? message.content : highlightCode(message.content, "json").join("\n"), 0, 0);
|
|
216
|
+
});
|
|
227
217
|
host.registerCommand("coordinator", {
|
|
228
218
|
description: "List visible sessions, their machines, and native metadata",
|
|
229
219
|
handler: async (args) => {
|
|
@@ -259,9 +249,10 @@ export default function plugin(host) {
|
|
|
259
249
|
}, { triggerTurn: false });
|
|
260
250
|
return;
|
|
261
251
|
}
|
|
252
|
+
const result = { sessions: exit.value };
|
|
262
253
|
host.sendMessage({
|
|
263
|
-
customType: "coordinator-list", content:
|
|
264
|
-
details:
|
|
254
|
+
customType: "coordinator-list", content: Formatter.formatJson(result, { space: 2 }), display: true,
|
|
255
|
+
details: result,
|
|
265
256
|
}, { triggerTurn: false });
|
|
266
257
|
},
|
|
267
258
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@samuelho-dev/coordinator",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Read-only native agent session inspection across self-hosted machines",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@earendil-works/pi-coding-agent": "1.0.4",
|
|
56
|
+
"@earendil-works/pi-tui": "1.0.4",
|
|
56
57
|
"@effect/tsgo": "0.49.0",
|
|
57
58
|
"@effect/vitest": "4.0.3",
|
|
58
59
|
"@oh-my-pi/pi-coding-agent": "18.6.1",
|