@useorgx/orgx-opencode-plugin 0.1.0-alpha.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 ADDED
@@ -0,0 +1,98 @@
1
+ # orgx-opencode-plugin
2
+
3
+ OrgX plugin peer for **OpenCode**. One of three reference peers (alongside `orgx-claude-code-plugin` and `orgx-codex-plugin`) that implements [`@useorgx/orgx-gateway-sdk`](https://github.com/useorgx/orgx-gateway-sdk) Protocol v1.
4
+
5
+ **The peer model:** this plugin opens its own authenticated WebSocket to OrgX server, receives `task.dispatch` messages, runs them in your local OpenCode session (your subscription pays the tokens), and posts receipts + deviations back. It also writes compact, redacted Work Graph events locally so audit-first reconciliation can preserve progress and fingerprints across signup. No central broker. If another peer goes down, this one keeps running.
6
+
7
+ ## Install + run
8
+
9
+ ```bash
10
+ npm install -g @useorgx/orgx-opencode-plugin
11
+ # or pnpm: pnpm add -g @useorgx/orgx-opencode-plugin
12
+
13
+ export ORGX_API_KEY=oxk_...
14
+ export ORGX_WORKSPACE_ID=<uuid>
15
+ orgx-opencode-plugin
16
+ ```
17
+
18
+ Or programmatic:
19
+
20
+ ```ts
21
+ import { startPeer } from '@useorgx/orgx-opencode-plugin';
22
+
23
+ const peer = await startPeer({
24
+ apiKey: process.env.ORGX_API_KEY!,
25
+ workspaceId: process.env.ORGX_WORKSPACE_ID!,
26
+ });
27
+ // later:
28
+ await peer.stop();
29
+ ```
30
+
31
+ ## How it talks to OpenCode
32
+
33
+ The peer discovers the local OpenCode daemon via its state file:
34
+
35
+ | OS | Path |
36
+ |---|---|
37
+ | macOS / Linux | `~/.opencode/state.json` |
38
+ | Windows | `%APPDATA%/opencode/state.json` |
39
+
40
+ The state file tells us which local port the daemon listens on. The driver then:
41
+
42
+ 1. `GET /status` — verifies auth + reports subscription health
43
+ 2. `POST /sessions` — creates a fresh session bound to the dispatched task
44
+ 3. `GET /sessions/:id/events` (NDJSON stream) — drives progress
45
+
46
+ Each `file_edit` / `tool_call` event becomes a `task.step` wire message. Every skill rule fetched from `/api/v1/plan-skills` runs against the event stream; matches become `task.deviation` events (deduped per (run_id, skill_id, fingerprint)).
47
+
48
+ ## Work Graph reconciliation
49
+
50
+ The driver writes passive event summaries to
51
+ `~/.config/useorgx/wizard/hooks/events.jsonl` by default. Set
52
+ `ORGX_WIZARD_HOOK_OUTBOX` to override the path, or pass
53
+ `workGraphOutboxPath: false` when starting the peer programmatically to disable
54
+ the local trail.
55
+
56
+ These JSONL records are intentionally compact. They include source client,
57
+ event kind, run/session handles, repo path, evidence refs, and counts; they do
58
+ not include raw prompts, raw transcripts, API keys, tokens, or storage state.
59
+ The OrgX wizard can later use them to detect missed OrgX writeback, generate a
60
+ shareable public Work Graph readout, and hydrate the fingerprint into a signed-up
61
+ workspace.
62
+
63
+ ## License heartbeat
64
+
65
+ `startPeer()` posts `POST /api/v1/licenses/heartbeat` on boot and then every 7 days. The manifest is read from `plugin.manifest.json`; when the fingerprint + signature are missing (dev builds), the server marks the license `degraded` in permissive mode — read-only features keep working, but deviation ingestion 402s until a signed manifest ships.
66
+
67
+ ## Skills
68
+
69
+ Rules are fetched once per peer boot from `GET /api/v1/plan-skills?workspace_id=…`. The shape is:
70
+
71
+ ```ts
72
+ {
73
+ skills: [
74
+ {
75
+ id: 'parametrize-tests',
76
+ rules: [
77
+ { pattern: 'parametrize', on: 'file_edit',
78
+ dedupe_fingerprint: '...', evidence_kind: 'test_style_shift' }
79
+ ]
80
+ }
81
+ ]
82
+ }
83
+ ```
84
+
85
+ Additions / demotions take effect on peer restart (or via an in-band "rules reload" message in a follow-up).
86
+
87
+ ## Development
88
+
89
+ ```bash
90
+ npm install
91
+ npm run type-check
92
+ npm test
93
+ npm run build
94
+ ```
95
+
96
+ ## Status
97
+
98
+ Alpha. Part of the Sovereign Execution initiative (`993cabeb`).
@@ -0,0 +1,66 @@
1
+ /**
2
+ * OpenCodeDriver — the implementation detail inside orgx-opencode-plugin
3
+ * that actually drives the user's OpenCode session.
4
+ *
5
+ * OpenCode exposes a local HTTP API on http://127.0.0.1:<port> when the
6
+ * user has the `opencode` daemon running. We discover the port via the
7
+ * standard XDG state file (~/.opencode/state.json on macOS/Linux,
8
+ * %APPDATA%/opencode/state.json on Windows). When the daemon isn't
9
+ * reachable, detect() reports not-installed and the peer surfaces this
10
+ * to the server on handshake — the server then routes new tasks to a
11
+ * different driver.
12
+ *
13
+ * Dispatch flow:
14
+ * 1. POST /sessions → create a fresh session bound to the task
15
+ * 2. POST /sessions/:id/messages with the rendered prompt
16
+ * 3. Poll /sessions/:id/events until a terminal ('assistant_completed'
17
+ * or 'error') arrives, streaming task.step events as each tool call
18
+ * or file_edit lands.
19
+ * 4. Emit task.completed with the accumulated tokens + outcome.
20
+ *
21
+ * Deviation-reporting: every file_edit event is checked against the
22
+ * configured skill rules (fetched from /api/v1/plan-skills on peer
23
+ * connect and cached per run). When a rule matches, we emit
24
+ * task.deviation — the peer forwards it to the server.
25
+ */
26
+ import type { Driver, DriverStatus, DriverProbe, DispatchableTask, PeerToServerMessage } from '@useorgx/orgx-gateway-sdk';
27
+ type SkillRule = {
28
+ skill_id: string;
29
+ match: {
30
+ pattern: string;
31
+ on: 'file_edit' | 'tool_call';
32
+ };
33
+ dedupe_fingerprint: string;
34
+ evidence_kind: string;
35
+ };
36
+ export type OpenCodeDriverOptions = {
37
+ /** Override the state-file lookup — primarily for tests. */
38
+ statePath?: string;
39
+ /** Async fetcher of skill rules (injected by the peer). */
40
+ skillRules?: () => Promise<SkillRule[]>;
41
+ /** Timeout for each polling round, in ms. */
42
+ pollTimeoutMs?: number;
43
+ /** Local Work Graph JSONL outbox path. Set false to disable. */
44
+ workGraphOutboxPath?: string | false;
45
+ /** Source client name for Work Graph reconciliation. */
46
+ sourceClient?: string;
47
+ };
48
+ export declare class OpenCodeDriver implements Driver {
49
+ readonly id: "opencode";
50
+ private portCache;
51
+ private readonly opts;
52
+ constructor(opts?: OpenCodeDriverOptions);
53
+ detect(): Promise<DriverStatus>;
54
+ probe(): Promise<DriverProbe>;
55
+ dispatch(task: DispatchableTask, context: {
56
+ run_id: string;
57
+ idempotency_key: string;
58
+ }): AsyncIterable<PeerToServerMessage>;
59
+ cancel(runId: string): Promise<void>;
60
+ private recordWorkGraph;
61
+ private resolvePort;
62
+ private createSession;
63
+ private streamSessionEvents;
64
+ }
65
+ export {};
66
+ //# sourceMappingURL=OpenCodeDriver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenCodeDriver.d.ts","sourceRoot":"","sources":["../src/OpenCodeDriver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAMH,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,2BAA2B,CAAC;AAiBnC,KAAK,SAAS,GAAG;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAAA;KAAE,CAAC;IAC1D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACxC,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACrC,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,qBAAa,cAAe,YAAW,MAAM;IAC3C,QAAQ,CAAC,EAAE,EAAG,UAAU,CAAU;IAElC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;gBAEjC,IAAI,GAAE,qBAA0B;IAItC,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC;IA+B/B,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IAwB5B,QAAQ,CACb,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,GACnD,aAAa,CAAC,mBAAmB,CAAC;IA0I/B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAW5B,eAAe;YA0Bf,WAAW;YAYX,aAAa;YA6BZ,mBAAmB;CA6BnC"}
@@ -0,0 +1,323 @@
1
+ /**
2
+ * OpenCodeDriver — the implementation detail inside orgx-opencode-plugin
3
+ * that actually drives the user's OpenCode session.
4
+ *
5
+ * OpenCode exposes a local HTTP API on http://127.0.0.1:<port> when the
6
+ * user has the `opencode` daemon running. We discover the port via the
7
+ * standard XDG state file (~/.opencode/state.json on macOS/Linux,
8
+ * %APPDATA%/opencode/state.json on Windows). When the daemon isn't
9
+ * reachable, detect() reports not-installed and the peer surfaces this
10
+ * to the server on handshake — the server then routes new tasks to a
11
+ * different driver.
12
+ *
13
+ * Dispatch flow:
14
+ * 1. POST /sessions → create a fresh session bound to the task
15
+ * 2. POST /sessions/:id/messages with the rendered prompt
16
+ * 3. Poll /sessions/:id/events until a terminal ('assistant_completed'
17
+ * or 'error') arrives, streaming task.step events as each tool call
18
+ * or file_edit lands.
19
+ * 4. Emit task.completed with the accumulated tokens + outcome.
20
+ *
21
+ * Deviation-reporting: every file_edit event is checked against the
22
+ * configured skill rules (fetched from /api/v1/plan-skills on peer
23
+ * connect and cached per run). When a rule matches, we emit
24
+ * task.deviation — the peer forwards it to the server.
25
+ */
26
+ import { promises as fs } from 'fs';
27
+ import { homedir, platform } from 'os';
28
+ import { join } from 'path';
29
+ import { recordWorkGraphEvent } from './workGraphOutbox';
30
+ export class OpenCodeDriver {
31
+ id = 'opencode';
32
+ portCache = null;
33
+ opts;
34
+ constructor(opts = {}) {
35
+ this.opts = opts;
36
+ }
37
+ async detect() {
38
+ try {
39
+ const port = await this.resolvePort();
40
+ this.portCache = port;
41
+ const res = await fetch(`http://127.0.0.1:${port}/status`, {
42
+ method: 'GET',
43
+ headers: { 'x-orgx-probe': 'detect' },
44
+ });
45
+ if (!res.ok) {
46
+ return {
47
+ installed: true,
48
+ authenticated: false,
49
+ error: `status ${res.status}`,
50
+ };
51
+ }
52
+ const body = (await res.json());
53
+ return {
54
+ installed: true,
55
+ authenticated: body.authed !== false,
56
+ version: body.version,
57
+ subscription_active: body.authed !== false,
58
+ };
59
+ }
60
+ catch (err) {
61
+ return {
62
+ installed: false,
63
+ authenticated: false,
64
+ error: err instanceof Error ? err.message : String(err),
65
+ };
66
+ }
67
+ }
68
+ async probe() {
69
+ try {
70
+ const port = await this.resolvePort();
71
+ const res = await fetch(`http://127.0.0.1:${port}/status`, {
72
+ method: 'GET',
73
+ headers: { 'x-orgx-probe': 'liveness' },
74
+ });
75
+ if (!res.ok) {
76
+ return { subscription_active: false, session_alive: false };
77
+ }
78
+ const body = (await res.json());
79
+ return {
80
+ subscription_active: body.authed !== false,
81
+ session_alive: (body.session_count ?? 0) >= 0,
82
+ queue_depth: body.session_count ?? 0,
83
+ };
84
+ }
85
+ catch {
86
+ return { subscription_active: false, session_alive: false };
87
+ }
88
+ }
89
+ async *dispatch(task, context) {
90
+ const port = this.portCache ?? (await this.resolvePort());
91
+ const sessionHandle = await this.createSession(port, {
92
+ title: task.title,
93
+ description: task.description,
94
+ repo_path: task.repo_path,
95
+ skill_ids: task.skill_ids,
96
+ idempotency_key: context.idempotency_key,
97
+ });
98
+ const startedAt = new Date().toISOString();
99
+ await this.recordWorkGraph('task_started', task, context, {
100
+ sessionHandle,
101
+ timestamp: startedAt,
102
+ task_title_chars: task.title.length,
103
+ description_chars: task.description?.length ?? 0,
104
+ skill_count: task.skill_ids?.length ?? 0,
105
+ });
106
+ yield {
107
+ kind: 'task.started',
108
+ run_id: context.run_id,
109
+ started_at: startedAt,
110
+ session_handle: sessionHandle,
111
+ };
112
+ const rules = await (this.opts.skillRules?.() ?? Promise.resolve([]));
113
+ const seenFingerprints = new Set();
114
+ let tokens = 0;
115
+ let firstResponseAt = null;
116
+ for await (const event of this.streamSessionEvents(port, sessionHandle)) {
117
+ if (!firstResponseAt && (event.kind === 'chat' || event.kind === 'tool_call')) {
118
+ firstResponseAt = new Date().toISOString();
119
+ }
120
+ if (event.kind === 'error') {
121
+ await this.recordWorkGraph('task_failed', task, context, {
122
+ sessionHandle,
123
+ recoverable: event.recoverable === true,
124
+ reason_chars: event.message.length,
125
+ });
126
+ yield {
127
+ kind: 'task.failed',
128
+ run_id: context.run_id,
129
+ reason: event.message,
130
+ recoverable: event.recoverable === true,
131
+ };
132
+ return;
133
+ }
134
+ if (event.kind === 'assistant_completed') {
135
+ tokens = event.tokens_used;
136
+ await this.recordWorkGraph('task_completed', task, context, {
137
+ sessionHandle,
138
+ tokens_used: tokens,
139
+ first_response_seen: Boolean(firstResponseAt),
140
+ });
141
+ yield {
142
+ kind: 'task.completed',
143
+ run_id: context.run_id,
144
+ outcome_kind: 'shipped',
145
+ started_at: startedAt,
146
+ first_response_at: firstResponseAt ?? startedAt,
147
+ completed_at: new Date().toISOString(),
148
+ tokens_used: tokens,
149
+ provider: 'anthropic',
150
+ source_sub_type: 'subscription',
151
+ source_driver: 'opencode',
152
+ // OpenCode subscriptions don't expose a cost per token — we
153
+ // emit 0 so the server's BYOK aggregator records "zero
154
+ // server-side" and leaves saved_estimate_cents to a follow-up
155
+ // job that backfills from task_type_baselines.
156
+ cost_estimate_cents: 0,
157
+ };
158
+ return;
159
+ }
160
+ // Narrate progress to the server + check deviation rules.
161
+ if (event.kind === 'file_edit' || event.kind === 'tool_call') {
162
+ const summary = event.kind === 'file_edit'
163
+ ? `edit ${event.path} — ${event.summary}`
164
+ : `call ${event.tool} — ${event.summary}`;
165
+ await this.recordWorkGraph('task_step', task, context, {
166
+ sessionHandle,
167
+ step_kind: event.kind,
168
+ evidence_ref: event.kind === 'file_edit'
169
+ ? event.diff_ref ?? event.path
170
+ : event.ref ?? event.tool,
171
+ summary_chars: summary.length,
172
+ });
173
+ yield {
174
+ kind: 'task.step',
175
+ run_id: context.run_id,
176
+ step: {
177
+ kind: event.kind,
178
+ summary,
179
+ evidence_ref: event.kind === 'file_edit'
180
+ ? event.diff_ref
181
+ : event.ref,
182
+ },
183
+ };
184
+ for (const rule of rules) {
185
+ if (rule.match.on !== event.kind)
186
+ continue;
187
+ const text = event.kind === 'file_edit'
188
+ ? `${event.path} ${event.summary}`
189
+ : `${event.tool} ${event.summary}`;
190
+ if (!new RegExp(rule.match.pattern).test(text))
191
+ continue;
192
+ const dedupe = `${rule.skill_id}:${rule.dedupe_fingerprint}:${context.run_id}`;
193
+ if (seenFingerprints.has(dedupe))
194
+ continue;
195
+ seenFingerprints.add(dedupe);
196
+ await this.recordWorkGraph('task_deviation', task, context, {
197
+ sessionHandle,
198
+ skill_id: rule.skill_id,
199
+ evidence_kind: rule.evidence_kind,
200
+ dedupe_key: dedupe,
201
+ });
202
+ yield {
203
+ kind: 'task.deviation',
204
+ run_id: context.run_id,
205
+ skill_id: rule.skill_id,
206
+ evidence_kind: rule.evidence_kind,
207
+ evidence_ref: event.kind === 'file_edit'
208
+ ? event.diff_ref ?? event.path
209
+ : event.ref ?? event.tool,
210
+ dedupe_key: dedupe,
211
+ severity: 'warn',
212
+ };
213
+ }
214
+ }
215
+ }
216
+ }
217
+ async cancel(runId) {
218
+ const port = this.portCache ?? (await this.resolvePort());
219
+ await fetch(`http://127.0.0.1:${port}/sessions/cancel`, {
220
+ method: 'POST',
221
+ headers: { 'Content-Type': 'application/json' },
222
+ body: JSON.stringify({ correlation_run_id: runId }),
223
+ }).catch(() => undefined);
224
+ }
225
+ // ───── Internals ──────────────────────────────────────────────────────
226
+ async recordWorkGraph(event, task, context, summary) {
227
+ await recordWorkGraphEvent({
228
+ outboxPath: this.opts.workGraphOutboxPath,
229
+ sourceClient: this.opts.sourceClient ?? 'opencode',
230
+ event,
231
+ runId: context.run_id,
232
+ sessionHandle: typeof summary.sessionHandle === 'string'
233
+ ? summary.sessionHandle
234
+ : undefined,
235
+ cwd: typeof task.repo_path === 'string' && task.repo_path.trim()
236
+ ? task.repo_path
237
+ : undefined,
238
+ summary: {
239
+ ...summary,
240
+ idempotency_key: context.idempotency_key,
241
+ },
242
+ });
243
+ }
244
+ async resolvePort() {
245
+ if (this.portCache !== null)
246
+ return this.portCache;
247
+ const path = this.opts.statePath ?? defaultStatePath();
248
+ const raw = await fs.readFile(path, 'utf8');
249
+ const state = JSON.parse(raw);
250
+ if (!Number.isInteger(state.port) || state.port <= 0) {
251
+ throw new Error(`OpenCode state file missing port: ${path}`);
252
+ }
253
+ this.portCache = state.port;
254
+ return state.port;
255
+ }
256
+ async createSession(port, body) {
257
+ const res = await fetch(`http://127.0.0.1:${port}/sessions`, {
258
+ method: 'POST',
259
+ headers: {
260
+ 'Content-Type': 'application/json',
261
+ 'Idempotency-Key': body.idempotency_key,
262
+ },
263
+ body: JSON.stringify({
264
+ title: body.title,
265
+ initial_prompt: renderPrompt(body),
266
+ cwd: body.repo_path,
267
+ }),
268
+ });
269
+ if (!res.ok) {
270
+ throw new Error(`OpenCode /sessions ${res.status}`);
271
+ }
272
+ const json = (await res.json());
273
+ return json.session_id;
274
+ }
275
+ async *streamSessionEvents(port, sessionId) {
276
+ const url = `http://127.0.0.1:${port}/sessions/${sessionId}/events`;
277
+ const res = await fetch(url, { headers: { accept: 'application/x-ndjson' } });
278
+ if (!res.ok || !res.body) {
279
+ throw new Error(`OpenCode /events ${res.status}`);
280
+ }
281
+ const reader = res.body.getReader();
282
+ const decoder = new TextDecoder();
283
+ let buffer = '';
284
+ while (true) {
285
+ const { value, done } = await reader.read();
286
+ if (done)
287
+ return;
288
+ buffer += decoder.decode(value, { stream: true });
289
+ let nl;
290
+ while ((nl = buffer.indexOf('\n')) !== -1) {
291
+ const line = buffer.slice(0, nl).trim();
292
+ buffer = buffer.slice(nl + 1);
293
+ if (!line)
294
+ continue;
295
+ try {
296
+ yield JSON.parse(line);
297
+ }
298
+ catch {
299
+ // skip malformed lines
300
+ }
301
+ }
302
+ }
303
+ }
304
+ }
305
+ function defaultStatePath() {
306
+ if (platform() === 'win32') {
307
+ const base = process.env.APPDATA ?? join(homedir(), 'AppData', 'Roaming');
308
+ return join(base, 'opencode', 'state.json');
309
+ }
310
+ return join(homedir(), '.opencode', 'state.json');
311
+ }
312
+ function renderPrompt(body) {
313
+ const parts = [body.title];
314
+ if (body.description)
315
+ parts.push('\n\n', body.description);
316
+ if (body.skill_ids?.length) {
317
+ parts.push('\n\nSkills to honor:\n');
318
+ for (const id of body.skill_ids)
319
+ parts.push(` - ${id}\n`);
320
+ }
321
+ return parts.join('');
322
+ }
323
+ //# sourceMappingURL=OpenCodeDriver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenCodeDriver.js","sourceRoot":"","sources":["../src/OpenCodeDriver.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Minimal CLI entrypoint so users can run:
4
+ *
5
+ * ORGX_API_KEY=oxk_... ORGX_WORKSPACE_ID=... orgx-opencode-plugin
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;GAIG"}
package/dist/cli.js ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Minimal CLI entrypoint so users can run:
4
+ *
5
+ * ORGX_API_KEY=oxk_... ORGX_WORKSPACE_ID=... orgx-opencode-plugin
6
+ */
7
+ import { startPeer } from './peer.js';
8
+ async function main() {
9
+ const apiKey = process.env.ORGX_API_KEY;
10
+ const workspaceId = process.env.ORGX_WORKSPACE_ID;
11
+ const baseUrl = process.env.ORGX_BASE_URL ?? 'https://useorgx.com';
12
+ if (!apiKey || !workspaceId) {
13
+ // eslint-disable-next-line no-console
14
+ console.error('Missing ORGX_API_KEY and/or ORGX_WORKSPACE_ID. Export both and retry.');
15
+ process.exit(2);
16
+ }
17
+ const peer = await startPeer({ apiKey, workspaceId, baseUrl });
18
+ const shutdown = async () => {
19
+ await peer.stop();
20
+ process.exit(0);
21
+ };
22
+ process.on('SIGINT', shutdown);
23
+ process.on('SIGTERM', shutdown);
24
+ // eslint-disable-next-line no-console
25
+ console.log('[orgx-opencode-plugin] peer running — ctrl-c to stop. Dispatches will arrive when OrgX sends them.');
26
+ }
27
+ main().catch((err) => {
28
+ // eslint-disable-next-line no-console
29
+ console.error('[orgx-opencode-plugin] fatal', err);
30
+ process.exit(1);
31
+ });
32
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IACxC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,qBAAqB,CAAC;IAEnE,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC5B,sCAAsC;QACtC,OAAO,CAAC,KAAK,CACX,uEAAuE,CACxE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;IAE/D,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChC,sCAAsC;IACtC,OAAO,CAAC,GAAG,CACT,oGAAoG,CACrG,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,sCAAsC;IACtC,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { OpenCodeDriver, type OpenCodeDriverOptions } from './OpenCodeDriver';
2
+ export { startPeer } from './peer';
3
+ export { buildWorkGraphEventRecord, recordWorkGraphEvent, resolveWorkGraphOutboxPath, } from './workGraphOutbox';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EACL,yBAAyB,EACzB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { OpenCodeDriver } from './OpenCodeDriver';
2
+ export { startPeer } from './peer';
3
+ export { buildWorkGraphEventRecord, recordWorkGraphEvent, resolveWorkGraphOutboxPath, } from './workGraphOutbox';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA8B,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EACL,yBAAyB,EACzB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC"}
package/dist/peer.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Peer runtime — wires OpenCodeDriver into PeerClient and ships the
3
+ * license heartbeat on boot + every 24h.
4
+ *
5
+ * Usage (CLI or programmatic):
6
+ *
7
+ * import { startPeer } from '@useorgx/orgx-opencode-plugin';
8
+ * await startPeer({
9
+ * apiKey: process.env.ORGX_API_KEY,
10
+ * workspaceId: process.env.ORGX_WORKSPACE_ID,
11
+ * baseUrl: 'wss://useorgx.com',
12
+ * });
13
+ */
14
+ import { type Driver } from '@useorgx/orgx-gateway-sdk';
15
+ export type StartPeerOptions = {
16
+ apiKey: string;
17
+ workspaceId: string;
18
+ /** Default: https://useorgx.com */
19
+ baseUrl?: string;
20
+ /** Override for tests. */
21
+ driver?: Driver;
22
+ /** Skip the license heartbeat (tests). */
23
+ skipHeartbeat?: boolean;
24
+ /** Local Work Graph JSONL outbox path. Set false to disable. */
25
+ workGraphOutboxPath?: string | false;
26
+ };
27
+ export type StartedPeer = {
28
+ stop: () => Promise<void>;
29
+ };
30
+ export declare function startPeer(opts: StartPeerOptions): Promise<StartedPeer>;
31
+ //# sourceMappingURL=peer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer.d.ts","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAOpE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CAAC;AAEF,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAuD5E"}
package/dist/peer.js ADDED
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Peer runtime — wires OpenCodeDriver into PeerClient and ships the
3
+ * license heartbeat on boot + every 24h.
4
+ *
5
+ * Usage (CLI or programmatic):
6
+ *
7
+ * import { startPeer } from '@useorgx/orgx-opencode-plugin';
8
+ * await startPeer({
9
+ * apiKey: process.env.ORGX_API_KEY,
10
+ * workspaceId: process.env.ORGX_WORKSPACE_ID,
11
+ * baseUrl: 'wss://useorgx.com',
12
+ * });
13
+ */
14
+ import { PeerClient } from '@useorgx/orgx-gateway-sdk';
15
+ import { readFile } from 'fs/promises';
16
+ import { resolve } from 'path';
17
+ import { fileURLToPath } from 'url';
18
+ import { OpenCodeDriver } from './OpenCodeDriver';
19
+ export async function startPeer(opts) {
20
+ const baseUrl = opts.baseUrl ?? 'https://useorgx.com';
21
+ const driver = opts.driver ??
22
+ new OpenCodeDriver({
23
+ skillRules: async () => fetchSkillRules(baseUrl, opts),
24
+ workGraphOutboxPath: opts.workGraphOutboxPath,
25
+ });
26
+ const manifest = await loadManifest();
27
+ const client = new PeerClient({
28
+ baseUrl: httpsToWss(baseUrl),
29
+ apiKey: opts.apiKey,
30
+ workspaceId: opts.workspaceId,
31
+ pluginId: '@useorgx/orgx-opencode-plugin',
32
+ drivers: [driver],
33
+ onOpen: () => {
34
+ // eslint-disable-next-line no-console
35
+ console.log('[orgx-opencode-plugin] connected');
36
+ },
37
+ onClose: (code, reason) => {
38
+ // eslint-disable-next-line no-console
39
+ console.warn('[orgx-opencode-plugin] closed', { code, reason });
40
+ },
41
+ onError: (err) => {
42
+ // eslint-disable-next-line no-console
43
+ console.error('[orgx-opencode-plugin] error', err);
44
+ },
45
+ });
46
+ client.connect();
47
+ let heartbeatTimer = null;
48
+ if (!opts.skipHeartbeat) {
49
+ await postHeartbeat(baseUrl, opts, manifest).catch((err) => {
50
+ // eslint-disable-next-line no-console
51
+ console.warn('[orgx-opencode-plugin] initial heartbeat failed', err);
52
+ });
53
+ heartbeatTimer = setInterval(() => {
54
+ void postHeartbeat(baseUrl, opts, manifest).catch((err) => {
55
+ // eslint-disable-next-line no-console
56
+ console.warn('[orgx-opencode-plugin] weekly heartbeat failed', err);
57
+ });
58
+ }, 7 * 24 * 60 * 60 * 1000);
59
+ }
60
+ return {
61
+ stop: async () => {
62
+ if (heartbeatTimer)
63
+ clearInterval(heartbeatTimer);
64
+ client.disconnect();
65
+ },
66
+ };
67
+ }
68
+ async function loadManifest() {
69
+ // Manifest lives at package root. Resolved via import.meta.url so ESM + CJS agree.
70
+ const here = fileURLToPath(import.meta.url);
71
+ const manifestPath = resolve(here, '../..', 'plugin.manifest.json');
72
+ try {
73
+ const raw = await readFile(manifestPath, 'utf8');
74
+ return JSON.parse(raw);
75
+ }
76
+ catch {
77
+ // In dev, bail to a placeholder so the peer can still start. The
78
+ // server will mark the license 'degraded' in permissive mode.
79
+ return {
80
+ plugin_name: '@useorgx/orgx-opencode-plugin',
81
+ version: '0.0.0-dev',
82
+ manifest_fingerprint: 'dev-placeholder',
83
+ signature: '',
84
+ };
85
+ }
86
+ }
87
+ async function postHeartbeat(baseUrl, opts, manifest) {
88
+ const r = await fetch(`${baseUrl.replace(/\/$/, '')}/api/v1/licenses/heartbeat`, {
89
+ method: 'POST',
90
+ headers: {
91
+ 'Content-Type': 'application/json',
92
+ Authorization: `Bearer ${opts.apiKey}`,
93
+ },
94
+ body: JSON.stringify({
95
+ workspace_id: opts.workspaceId,
96
+ plugin_name: manifest.plugin_name,
97
+ version: manifest.version,
98
+ manifest_fingerprint: manifest.manifest_fingerprint,
99
+ signature: manifest.signature,
100
+ }),
101
+ });
102
+ if (!r.ok) {
103
+ throw new Error(`heartbeat ${r.status}: ${await r.text().catch(() => '')}`);
104
+ }
105
+ }
106
+ async function fetchSkillRules(baseUrl, opts) {
107
+ try {
108
+ const r = await fetch(`${baseUrl.replace(/\/$/, '')}/api/v1/plan-skills?workspace_id=${encodeURIComponent(opts.workspaceId)}`, {
109
+ method: 'GET',
110
+ headers: { Authorization: `Bearer ${opts.apiKey}` },
111
+ });
112
+ if (!r.ok)
113
+ return [];
114
+ const body = (await r.json());
115
+ const rules = [];
116
+ for (const skill of body.skills ?? []) {
117
+ for (const rule of skill.rules ?? []) {
118
+ rules.push({
119
+ skill_id: skill.id,
120
+ match: { pattern: rule.pattern, on: rule.on },
121
+ dedupe_fingerprint: rule.dedupe_fingerprint,
122
+ evidence_kind: rule.evidence_kind,
123
+ });
124
+ }
125
+ }
126
+ return rules;
127
+ }
128
+ catch {
129
+ return [];
130
+ }
131
+ }
132
+ function httpsToWss(url) {
133
+ if (url.startsWith('https://'))
134
+ return 'wss://' + url.slice('https://'.length);
135
+ if (url.startsWith('http://'))
136
+ return 'ws://' + url.slice('http://'.length);
137
+ return url;
138
+ }
139
+ //# sourceMappingURL=peer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer.js","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ type WorkGraphEventInput = {
2
+ outboxPath?: string | false;
3
+ sourceClient?: string;
4
+ event: string;
5
+ runId?: string;
6
+ sessionHandle?: string;
7
+ cwd?: string;
8
+ timestamp?: string;
9
+ summary?: Record<string, unknown>;
10
+ env?: NodeJS.ProcessEnv;
11
+ };
12
+ export declare function resolveWorkGraphOutboxPath(outboxPath?: string | false, env?: NodeJS.ProcessEnv): string | null;
13
+ export declare function buildWorkGraphEventRecord({ sourceClient, event, runId, sessionHandle, cwd, timestamp, summary, }: WorkGraphEventInput): Record<string, unknown>;
14
+ export declare function recordWorkGraphEvent(input: WorkGraphEventInput): Promise<boolean>;
15
+ export {};
16
+ //# sourceMappingURL=workGraphOutbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workGraphOutbox.d.ts","sourceRoot":"","sources":["../src/workGraphOutbox.ts"],"names":[],"mappings":"AAIA,KAAK,mBAAmB,GAAG;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,EAC3B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,GAAG,IAAI,CAOf;AAED,wBAAgB,yBAAyB,CAAC,EACxC,YAAyB,EACzB,KAAK,EACL,KAAK,EACL,aAAa,EACb,GAAG,EACH,SAAoC,EACpC,OAAY,GACb,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAY/C;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,OAAO,CAAC,CAkBlB"}
@@ -0,0 +1,44 @@
1
+ import { appendFile, mkdir } from 'fs/promises';
2
+ import { homedir } from 'os';
3
+ import { dirname, join } from 'path';
4
+ export function resolveWorkGraphOutboxPath(outboxPath, env = process.env) {
5
+ if (outboxPath === false)
6
+ return null;
7
+ const explicit = typeof outboxPath === 'string' ? outboxPath.trim() : '';
8
+ if (explicit)
9
+ return explicit;
10
+ const envPath = env.ORGX_WIZARD_HOOK_OUTBOX?.trim();
11
+ if (envPath)
12
+ return envPath;
13
+ return join(homedir(), '.config', 'useorgx', 'wizard', 'hooks', 'events.jsonl');
14
+ }
15
+ export function buildWorkGraphEventRecord({ sourceClient = 'opencode', event, runId, sessionHandle, cwd, timestamp = new Date().toISOString(), summary = {}, }) {
16
+ return {
17
+ schema_version: '2026-05-07',
18
+ source: 'orgx_opencode_plugin_runtime_hook',
19
+ source_client: sourceClient,
20
+ event,
21
+ session_id: runId,
22
+ turn_id: sessionHandle,
23
+ cwd,
24
+ timestamp,
25
+ summary,
26
+ };
27
+ }
28
+ export async function recordWorkGraphEvent(input) {
29
+ const outbox = resolveWorkGraphOutboxPath(input.outboxPath, input.env);
30
+ if (!outbox)
31
+ return false;
32
+ try {
33
+ await mkdir(dirname(outbox), { recursive: true, mode: 0o700 });
34
+ await appendFile(outbox, `${JSON.stringify(buildWorkGraphEventRecord(input))}\n`, {
35
+ encoding: 'utf8',
36
+ mode: 0o600,
37
+ });
38
+ return true;
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ }
44
+ //# sourceMappingURL=workGraphOutbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workGraphOutbox.js","sourceRoot":"","sources":["../src/workGraphOutbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAcrC,MAAM,UAAU,0BAA0B,CACxC,UAA2B,EAC3B,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,UAAU,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,QAAQ,GAAG,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,OAAO,GAAG,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,CAAC;IACpD,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,EACxC,YAAY,GAAG,UAAU,EACzB,KAAK,EACL,KAAK,EACL,aAAa,EACb,GAAG,EACH,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EACpC,OAAO,GAAG,EAAE,GACQ;IACpB,OAAO;QACL,cAAc,EAAE,YAAY;QAC5B,MAAM,EAAE,mCAAmC;QAC3C,aAAa,EAAE,YAAY;QAC3B,KAAK;QACL,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,aAAa;QACtB,GAAG;QACH,SAAS;QACT,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAA0B;IAE1B,MAAM,MAAM,GAAG,0BAA0B,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACvE,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE1B,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,MAAM,UAAU,CACd,MAAM,EACN,GAAG,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,IAAI,EACvD;YACE,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,KAAK;SACZ,CACF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@useorgx/orgx-opencode-plugin",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "OrgX plugin peer for OpenCode with task dispatch, execution receipts, deviations, and passive Work Graph reconciliation events.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "bin": {
10
+ "orgx-opencode-plugin": "dist/cli.js"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": ["dist", "README.md", "plugin.manifest.json"],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "type-check": "tsc --noEmit",
22
+ "test": "vitest run",
23
+ "start": "node dist/cli.js"
24
+ },
25
+ "dependencies": {
26
+ "@useorgx/orgx-gateway-sdk": "https://github.com/useorgx/orgx-gateway-sdk#main"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.0.0",
30
+ "typescript": "^5.4.0",
31
+ "vitest": "^2.0.0"
32
+ },
33
+ "keywords": ["orgx", "opencode", "plugin-peer", "byok"],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/useorgx/orgx-opencode-plugin.git"
37
+ },
38
+ "license": "UNLICENSED"
39
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "plugin_name": "@useorgx/orgx-opencode-plugin",
3
+ "version": "0.1.0-alpha.1",
4
+ "manifest_fingerprint": "",
5
+ "signature": "",
6
+ "capabilities": ["gateway:drive", "plugin:heartbeat"],
7
+ "driver_ids": ["opencode"],
8
+ "notes": "fingerprint + signature are populated by the npm prepublish step; the dev build ships unsigned and gets 'degraded' status from the server."
9
+ }