@h-rig/rig-host 0.0.6-alpha.91
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 +1 -0
- package/dist/bin/rig-run.d.ts +2 -0
- package/dist/bin/rig-run.js +283 -0
- package/dist/src/cli-entry.d.ts +1 -0
- package/dist/src/cli-entry.js +476 -0
- package/dist/src/domain/approval.d.ts +1 -0
- package/dist/src/domain/approval.js +9 -0
- package/dist/src/domain/input.d.ts +1 -0
- package/dist/src/domain/input.js +9 -0
- package/dist/src/domain/run.d.ts +28 -0
- package/dist/src/domain/run.js +176 -0
- package/dist/src/domain/task.d.ts +4 -0
- package/dist/src/domain/task.js +94 -0
- package/dist/src/domain/workspace.d.ts +4 -0
- package/dist/src/domain/workspace.js +183 -0
- package/dist/src/host-session.d.ts +47 -0
- package/dist/src/host-session.js +355 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +684 -0
- package/dist/src/local-omp-runner.d.ts +52 -0
- package/dist/src/local-omp-runner.js +184 -0
- package/dist/src/operator-entry.d.ts +7 -0
- package/dist/src/operator-entry.js +79 -0
- package/dist/src/protocol.d.ts +123 -0
- package/dist/src/protocol.js +8 -0
- package/dist/src/pty-spawn.d.ts +25 -0
- package/dist/src/pty-spawn.js +34 -0
- package/dist/src/replication/broadcast.d.ts +13 -0
- package/dist/src/replication/broadcast.js +63 -0
- package/dist/src/replication/replay.d.ts +12 -0
- package/dist/src/replication/replay.js +25 -0
- package/dist/src/replication/welcome.d.ts +3 -0
- package/dist/src/replication/welcome.js +45 -0
- package/package.json +39 -0
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/rig-host/src/cli-entry.ts
|
|
3
|
+
import { existsSync, readFileSync } from "fs";
|
|
4
|
+
import { dirname, resolve as resolve4 } from "path";
|
|
5
|
+
|
|
6
|
+
// packages/rig-host/src/host-session.ts
|
|
7
|
+
import { resolve as resolve3 } from "path";
|
|
8
|
+
|
|
9
|
+
// packages/rig-host/src/domain/run.ts
|
|
10
|
+
import { basename, resolve as resolve2 } from "path";
|
|
11
|
+
|
|
12
|
+
// packages/rig-host/src/domain/task.ts
|
|
13
|
+
import { resolve } from "path";
|
|
14
|
+
import { createPluginHost } from "@rig/core";
|
|
15
|
+
import { loadConfig } from "@rig/core/load-config";
|
|
16
|
+
function stringList(value) {
|
|
17
|
+
if (!Array.isArray(value))
|
|
18
|
+
return [];
|
|
19
|
+
return value.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
20
|
+
}
|
|
21
|
+
function stringOrNull(value) {
|
|
22
|
+
if (typeof value !== "string")
|
|
23
|
+
return null;
|
|
24
|
+
const trimmed = value.trim();
|
|
25
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
26
|
+
}
|
|
27
|
+
function titleFor(record) {
|
|
28
|
+
return stringOrNull(record.title) ?? stringOrNull(record.name) ?? record.id;
|
|
29
|
+
}
|
|
30
|
+
function descriptionFor(record) {
|
|
31
|
+
return stringOrNull(record.description) ?? stringOrNull(record.body) ?? "";
|
|
32
|
+
}
|
|
33
|
+
function scopeFor(record) {
|
|
34
|
+
const direct = stringList(record.scope);
|
|
35
|
+
if (direct.length > 0)
|
|
36
|
+
return direct;
|
|
37
|
+
return stringList(record.labels).filter((label) => label.startsWith("scope:")).map((label) => label.slice("scope:".length).trim()).filter((label) => label.length > 0);
|
|
38
|
+
}
|
|
39
|
+
function validationKeysFor(record) {
|
|
40
|
+
const direct = stringList(record.validationKeys);
|
|
41
|
+
if (direct.length > 0)
|
|
42
|
+
return direct;
|
|
43
|
+
const validation = stringList(record.validation);
|
|
44
|
+
if (validation.length > 0)
|
|
45
|
+
return validation;
|
|
46
|
+
return stringList(record.labels).filter((label) => label.startsWith("validator:")).map((label) => label.slice("validator:".length).trim()).filter((label) => label.length > 0);
|
|
47
|
+
}
|
|
48
|
+
function createdAtFor(record, fallback) {
|
|
49
|
+
return stringOrNull(record.createdAt) ?? fallback;
|
|
50
|
+
}
|
|
51
|
+
function updatedAtFor(record, fallback) {
|
|
52
|
+
return stringOrNull(record.updatedAt) ?? createdAtFor(record, fallback) ?? fallback;
|
|
53
|
+
}
|
|
54
|
+
function mapTaskRecordToSummary(record, workspaceId, fallbackTimestamp) {
|
|
55
|
+
const metadata = record;
|
|
56
|
+
const createdAt = createdAtFor(record, fallbackTimestamp);
|
|
57
|
+
const updatedAt = updatedAtFor(record, fallbackTimestamp);
|
|
58
|
+
return {
|
|
59
|
+
id: record.id,
|
|
60
|
+
workspaceId,
|
|
61
|
+
graphId: null,
|
|
62
|
+
externalId: stringOrNull(metadata.externalId) ?? stringOrNull(metadata.externalRef),
|
|
63
|
+
title: titleFor(record),
|
|
64
|
+
description: descriptionFor(record),
|
|
65
|
+
status: record.status,
|
|
66
|
+
priority: typeof metadata.priority === "number" && Number.isInteger(metadata.priority) && metadata.priority > 0 ? metadata.priority : null,
|
|
67
|
+
role: stringOrNull(metadata.role),
|
|
68
|
+
scope: scopeFor(record),
|
|
69
|
+
validationKeys: validationKeysFor(record),
|
|
70
|
+
sourceIssueId: stringOrNull(metadata.sourceIssueId),
|
|
71
|
+
dependencies: [...record.deps],
|
|
72
|
+
parentChildDeps: [],
|
|
73
|
+
metadata,
|
|
74
|
+
createdAt,
|
|
75
|
+
updatedAt
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async function loadRigIdeaTasks(workspaceRoot) {
|
|
79
|
+
const normalizedRoot = resolve(workspaceRoot);
|
|
80
|
+
const config = await loadConfig(normalizedRoot);
|
|
81
|
+
const pluginHost = createPluginHost(config.plugins);
|
|
82
|
+
const taskSourceFactory = pluginHost.resolveTaskSourceFactoryByKind(config.taskSource.kind);
|
|
83
|
+
if (!taskSourceFactory) {
|
|
84
|
+
const kinds = pluginHost.listExecutableTaskSources().map((entry) => entry.kind).join(", ") || "none";
|
|
85
|
+
throw new Error(`No task source factory registered for kind "${config.taskSource.kind}". Registered kinds: ${kinds}.`);
|
|
86
|
+
}
|
|
87
|
+
const source = taskSourceFactory.factory(config.taskSource, { projectRoot: normalizedRoot });
|
|
88
|
+
const fallbackTimestamp = new Date().toISOString();
|
|
89
|
+
const workspaceId = normalizedRoot;
|
|
90
|
+
const tasks = await source.list();
|
|
91
|
+
return tasks.map((task) => mapTaskRecordToSummary(task, workspaceId, fallbackTimestamp));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// packages/rig-host/src/domain/run.ts
|
|
95
|
+
var LEGACY_AUTHORITY_RUN_CREATION_RETIRED_MESSAGE = "Legacy rig-host run-record creation is retired for the product path. Use the default Rig OMP extension/collab session flow instead.";
|
|
96
|
+
var LEGACY_AUTHORITY_RUN_CONTROL_RETIRED_MESSAGE = "Legacy rig-host run-record control, inspection, and active-run state are retired for the product path. Use the default Rig OMP extension/collab session flow instead.";
|
|
97
|
+
function legacyAuthorityRunUnsupportedMessage() {
|
|
98
|
+
return LEGACY_AUTHORITY_RUN_CREATION_RETIRED_MESSAGE;
|
|
99
|
+
}
|
|
100
|
+
function legacyAuthorityRunControlUnsupportedMessage() {
|
|
101
|
+
return LEGACY_AUTHORITY_RUN_CONTROL_RETIRED_MESSAGE;
|
|
102
|
+
}
|
|
103
|
+
function legacyAuthorityRunControlUnsupportedError() {
|
|
104
|
+
return new Error(legacyAuthorityRunControlUnsupportedMessage());
|
|
105
|
+
}
|
|
106
|
+
function projectRetiredLegacyRigIdeaWorkspace(workspaceRoot, tasks) {
|
|
107
|
+
const normalizedRoot = resolve2(workspaceRoot);
|
|
108
|
+
const updatedAt = new Date().toISOString();
|
|
109
|
+
const title = basename(normalizedRoot) || normalizedRoot;
|
|
110
|
+
return {
|
|
111
|
+
workspaceRoot: normalizedRoot,
|
|
112
|
+
activeRunId: null,
|
|
113
|
+
sequence: 0,
|
|
114
|
+
workspaces: [{
|
|
115
|
+
id: normalizedRoot,
|
|
116
|
+
title,
|
|
117
|
+
rootPath: normalizedRoot,
|
|
118
|
+
sourceKind: "native",
|
|
119
|
+
defaultModel: null,
|
|
120
|
+
createdAt: updatedAt,
|
|
121
|
+
updatedAt
|
|
122
|
+
}],
|
|
123
|
+
graphs: [],
|
|
124
|
+
tasks: [...tasks],
|
|
125
|
+
runs: [],
|
|
126
|
+
runtimes: [],
|
|
127
|
+
conversations: [],
|
|
128
|
+
messages: [],
|
|
129
|
+
actions: [],
|
|
130
|
+
logs: [],
|
|
131
|
+
approvals: [],
|
|
132
|
+
userInputs: [],
|
|
133
|
+
validations: [],
|
|
134
|
+
reviews: [],
|
|
135
|
+
artifacts: [],
|
|
136
|
+
policyDecisions: [],
|
|
137
|
+
queue: [],
|
|
138
|
+
worktrees: [],
|
|
139
|
+
remoteEndpoints: [],
|
|
140
|
+
remoteConnections: [],
|
|
141
|
+
remoteOrchestrations: [],
|
|
142
|
+
updatedAt
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
async function createRigIdeaHarness(workspaceRoot) {
|
|
146
|
+
const normalizedRoot = resolve2(workspaceRoot);
|
|
147
|
+
const tasks = await loadRigIdeaTasks(normalizedRoot).catch(() => []);
|
|
148
|
+
return {
|
|
149
|
+
snapshot() {
|
|
150
|
+
return projectRetiredLegacyRigIdeaWorkspace(normalizedRoot, tasks);
|
|
151
|
+
},
|
|
152
|
+
async stopRun(_runId) {
|
|
153
|
+
throw legacyAuthorityRunControlUnsupportedError();
|
|
154
|
+
},
|
|
155
|
+
async resolveApproval(_runId, _requestId, _decision) {
|
|
156
|
+
throw legacyAuthorityRunControlUnsupportedError();
|
|
157
|
+
},
|
|
158
|
+
async resolveUserInput(_runId, _requestId, _answers) {
|
|
159
|
+
throw legacyAuthorityRunControlUnsupportedError();
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// packages/rig-host/src/replication/broadcast.ts
|
|
165
|
+
function createRigHostBroadcaster(listener, collab) {
|
|
166
|
+
const backlog = [];
|
|
167
|
+
const welcomedPeers = new Set;
|
|
168
|
+
const hasWelcomedRelayPeer = () => {
|
|
169
|
+
for (const peer of welcomedPeers) {
|
|
170
|
+
if (peer !== 0)
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
return false;
|
|
174
|
+
};
|
|
175
|
+
const emit = (frame, targetPeer = 0) => {
|
|
176
|
+
listener?.(frame);
|
|
177
|
+
collab?.send(frame, targetPeer);
|
|
178
|
+
};
|
|
179
|
+
const flush = (targetPeer) => {
|
|
180
|
+
let write = 0;
|
|
181
|
+
for (let read = 0;read < backlog.length; read += 1) {
|
|
182
|
+
const next = backlog[read];
|
|
183
|
+
if (next.targetPeer === targetPeer) {
|
|
184
|
+
emit(next.frame, next.targetPeer);
|
|
185
|
+
} else {
|
|
186
|
+
backlog[write] = next;
|
|
187
|
+
write += 1;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
backlog.length = write;
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
publish(frame, targetPeer = 0) {
|
|
194
|
+
if (frame.t === "welcome") {
|
|
195
|
+
welcomedPeers.add(targetPeer);
|
|
196
|
+
emit(frame, targetPeer);
|
|
197
|
+
flush(targetPeer);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (!welcomedPeers.has(targetPeer) && frame.t !== "bye" && frame.t !== "error") {
|
|
201
|
+
if (targetPeer === 0) {
|
|
202
|
+
if (hasWelcomedRelayPeer())
|
|
203
|
+
emit(frame, targetPeer);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
backlog.push({ frame, targetPeer });
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
emit(frame, targetPeer);
|
|
210
|
+
},
|
|
211
|
+
publishWelcome(snapshot, readOnly, targetPeer) {
|
|
212
|
+
this.publish({ t: "welcome", snapshot, readOnly }, targetPeer);
|
|
213
|
+
},
|
|
214
|
+
rejectReadOnly(action, targetPeer) {
|
|
215
|
+
this.publish({
|
|
216
|
+
t: "error",
|
|
217
|
+
code: "READ_ONLY",
|
|
218
|
+
message: `${action} is disabled on a read-only link`
|
|
219
|
+
}, targetPeer);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// packages/rig-host/src/host-session.ts
|
|
225
|
+
var LOCAL_PEER_ID = 0;
|
|
226
|
+
var RIG_GENERIC_OMP_JOIN_LIMITATION = "Legacy rig-host remote join and attachment are retired for the product path. Use the default Rig OMP extension/collab session flow instead.";
|
|
227
|
+
async function startRigHostSession(options) {
|
|
228
|
+
if (options.relayUrl) {
|
|
229
|
+
throw new Error(RIG_GENERIC_OMP_JOIN_LIMITATION);
|
|
230
|
+
}
|
|
231
|
+
const workspaceRoot = resolve3(options.workspaceRoot);
|
|
232
|
+
let stopped = false;
|
|
233
|
+
let harness = await createRigIdeaHarness(workspaceRoot);
|
|
234
|
+
let snapshot = harness.snapshot();
|
|
235
|
+
let hostSequence = snapshot.sequence;
|
|
236
|
+
const guests = new Map;
|
|
237
|
+
const broadcast = createRigHostBroadcaster(options.onFrame);
|
|
238
|
+
function publishState(nextSnapshot) {
|
|
239
|
+
hostSequence = Math.max(hostSequence, nextSnapshot.sequence) + 1;
|
|
240
|
+
snapshot = { ...nextSnapshot, sequence: hostSequence };
|
|
241
|
+
broadcast.publish({ t: "state", snapshot });
|
|
242
|
+
return snapshot;
|
|
243
|
+
}
|
|
244
|
+
async function refreshWorkspaceState() {
|
|
245
|
+
harness = await createRigIdeaHarness(workspaceRoot);
|
|
246
|
+
publishState(harness.snapshot());
|
|
247
|
+
}
|
|
248
|
+
function publishLegacyRunError(message, fromPeer) {
|
|
249
|
+
broadcast.publish({
|
|
250
|
+
t: "error",
|
|
251
|
+
code: "LEGACY_AUTHORITY_RUN_UNSUPPORTED",
|
|
252
|
+
message
|
|
253
|
+
}, fromPeer);
|
|
254
|
+
}
|
|
255
|
+
async function handleCommand(frame, fromPeer) {
|
|
256
|
+
switch (frame.command.kind) {
|
|
257
|
+
case "workspace.refresh":
|
|
258
|
+
await refreshWorkspaceState();
|
|
259
|
+
return;
|
|
260
|
+
case "run.createAdhoc":
|
|
261
|
+
case "task.run":
|
|
262
|
+
publishLegacyRunError(legacyAuthorityRunUnsupportedMessage(), fromPeer);
|
|
263
|
+
return;
|
|
264
|
+
case "run.stop":
|
|
265
|
+
case "run.resume":
|
|
266
|
+
case "run.interrupt":
|
|
267
|
+
case "run.submitMessage":
|
|
268
|
+
case "approval.resolve":
|
|
269
|
+
case "input.resolve":
|
|
270
|
+
publishLegacyRunError(legacyAuthorityRunControlUnsupportedMessage(), fromPeer);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
async function handleGuestFrame(frame, fromPeer = LOCAL_PEER_ID) {
|
|
275
|
+
if (stopped)
|
|
276
|
+
return;
|
|
277
|
+
switch (frame.t) {
|
|
278
|
+
case "hello": {
|
|
279
|
+
const guest = {
|
|
280
|
+
sessionName: frame.sessionName.trim().slice(0, 64) || `guest-${fromPeer}`,
|
|
281
|
+
readOnly: frame.readOnly === true
|
|
282
|
+
};
|
|
283
|
+
guests.set(fromPeer, guest);
|
|
284
|
+
broadcast.publishWelcome(snapshot, guest.readOnly, fromPeer);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
case "command": {
|
|
288
|
+
if (guests.get(fromPeer)?.readOnly !== false) {
|
|
289
|
+
broadcast.rejectReadOnly("command", fromPeer);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
try {
|
|
293
|
+
await handleCommand(frame, fromPeer);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
broadcast.publish({
|
|
296
|
+
t: "error",
|
|
297
|
+
code: "COMMAND_FAILED",
|
|
298
|
+
message: error instanceof Error ? error.message : String(error)
|
|
299
|
+
}, fromPeer);
|
|
300
|
+
}
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
case "abort": {
|
|
304
|
+
if (guests.get(fromPeer)?.readOnly !== false) {
|
|
305
|
+
broadcast.rejectReadOnly("abort", fromPeer);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
publishLegacyRunError(legacyAuthorityRunControlUnsupportedMessage(), fromPeer);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
case "fetch-transcript": {
|
|
312
|
+
publishLegacyRunError(legacyAuthorityRunControlUnsupportedMessage(), fromPeer);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
snapshot() {
|
|
319
|
+
return snapshot;
|
|
320
|
+
},
|
|
321
|
+
async createShareLink(_readOnly = false) {
|
|
322
|
+
throw new Error(RIG_GENERIC_OMP_JOIN_LIMITATION);
|
|
323
|
+
},
|
|
324
|
+
handleGuestFrame(frame) {
|
|
325
|
+
return handleGuestFrame(frame);
|
|
326
|
+
},
|
|
327
|
+
async stop(reason) {
|
|
328
|
+
if (stopped)
|
|
329
|
+
return;
|
|
330
|
+
stopped = true;
|
|
331
|
+
broadcast.publish({ t: "bye", reason });
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// packages/rig-host/src/cli-entry.ts
|
|
337
|
+
function packageVersionFrom(startDir) {
|
|
338
|
+
let current = resolve4(startDir);
|
|
339
|
+
while (true) {
|
|
340
|
+
const pkgPath = resolve4(current, "package.json");
|
|
341
|
+
if (existsSync(pkgPath)) {
|
|
342
|
+
try {
|
|
343
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
344
|
+
if ((pkg.name === "rig" || pkg.name === "@rig/cli" || pkg.name === "@h-rig/cli") && pkg.version)
|
|
345
|
+
return pkg.version;
|
|
346
|
+
} catch {}
|
|
347
|
+
}
|
|
348
|
+
const parent = dirname(current);
|
|
349
|
+
if (parent === current)
|
|
350
|
+
return null;
|
|
351
|
+
current = parent;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function usageText() {
|
|
355
|
+
return [
|
|
356
|
+
"Usage: rig [host|share] [--workspace <path>] [--json]",
|
|
357
|
+
"",
|
|
358
|
+
"Commands:",
|
|
359
|
+
" host Boot the host-authoritative runtime and print the current workspace summary.",
|
|
360
|
+
" share Boot the host-authoritative runtime and print a read-only share link.",
|
|
361
|
+
"",
|
|
362
|
+
"Flags:",
|
|
363
|
+
" --workspace <path> Override the workspace root (defaults to the current working directory).",
|
|
364
|
+
" --json Emit JSON instead of the text summary.",
|
|
365
|
+
" --write For share, emit a writable collaboration link instead of read-only.",
|
|
366
|
+
" --help, -h Show this help text.",
|
|
367
|
+
" --version, -V Show the rig CLI version."
|
|
368
|
+
].join(`
|
|
369
|
+
`);
|
|
370
|
+
}
|
|
371
|
+
function parseRigHostCli(args) {
|
|
372
|
+
let command = "host";
|
|
373
|
+
let help = false;
|
|
374
|
+
let json = false;
|
|
375
|
+
let readOnly = true;
|
|
376
|
+
let version = false;
|
|
377
|
+
let workspaceRoot = process.cwd();
|
|
378
|
+
for (let index = 0;index < args.length; index += 1) {
|
|
379
|
+
const arg = args[index];
|
|
380
|
+
if (arg === undefined)
|
|
381
|
+
continue;
|
|
382
|
+
if (arg === "--help" || arg === "-h" || arg === "help") {
|
|
383
|
+
help = true;
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
if (arg === "--version" || arg === "-V" || arg === "version") {
|
|
387
|
+
version = true;
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
if (arg === "--json") {
|
|
391
|
+
json = true;
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
if (arg === "--write") {
|
|
395
|
+
readOnly = false;
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (arg === "--workspace") {
|
|
399
|
+
const next = args[index + 1];
|
|
400
|
+
if (!next)
|
|
401
|
+
throw new Error("Missing value for --workspace");
|
|
402
|
+
workspaceRoot = next;
|
|
403
|
+
index += 1;
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
if (arg === "host" || arg === "share") {
|
|
407
|
+
command = arg;
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
command,
|
|
414
|
+
help,
|
|
415
|
+
json,
|
|
416
|
+
readOnly,
|
|
417
|
+
version,
|
|
418
|
+
workspaceRoot: resolve4(workspaceRoot)
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function writeLine(text) {
|
|
422
|
+
process.stdout.write(`${text}
|
|
423
|
+
`);
|
|
424
|
+
}
|
|
425
|
+
function renderHostSummary(workspaceRoot, snapshot) {
|
|
426
|
+
const pendingApprovals = snapshot.approvals.filter((item) => item.status === "pending").length;
|
|
427
|
+
const pendingInputs = (snapshot.userInputs ?? []).filter((item) => item.status === "pending").length;
|
|
428
|
+
return [
|
|
429
|
+
`Workspace: ${workspaceRoot}`,
|
|
430
|
+
`Tasks: ${snapshot.tasks.length}`,
|
|
431
|
+
`Runs: ${snapshot.runs.length}`,
|
|
432
|
+
`Approvals: ${pendingApprovals}`,
|
|
433
|
+
`Inputs: ${pendingInputs}`
|
|
434
|
+
];
|
|
435
|
+
}
|
|
436
|
+
async function runRigHostCli(args) {
|
|
437
|
+
const options = parseRigHostCli(args);
|
|
438
|
+
if (!options) {
|
|
439
|
+
throw new Error("__RIG_HOST_CLI_FALLBACK__");
|
|
440
|
+
}
|
|
441
|
+
if (options.version) {
|
|
442
|
+
writeLine(`rig ${process.env.RIG_CLI_VERSION?.trim() || packageVersionFrom(import.meta.dir) || "0.0.0-dev"}`);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
if (options.help) {
|
|
446
|
+
writeLine(usageText());
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
const host = await startRigHostSession({ workspaceRoot: options.workspaceRoot });
|
|
450
|
+
try {
|
|
451
|
+
if (options.command === "share") {
|
|
452
|
+
const link = await host.createShareLink(options.readOnly);
|
|
453
|
+
if (options.json) {
|
|
454
|
+
writeLine(JSON.stringify({ link, readOnly: options.readOnly, workspaceRoot: options.workspaceRoot }, null, 2));
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
writeLine(`Share link (${options.readOnly ? "read-only" : "write"}): ${link}`);
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const snapshot = host.snapshot();
|
|
461
|
+
if (options.json) {
|
|
462
|
+
writeLine(JSON.stringify({
|
|
463
|
+
connection: "connected",
|
|
464
|
+
snapshot
|
|
465
|
+
}, null, 2));
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
for (const line of renderHostSummary(options.workspaceRoot, snapshot))
|
|
469
|
+
writeLine(line);
|
|
470
|
+
} finally {
|
|
471
|
+
await host.stop("rig host cli complete");
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
export {
|
|
475
|
+
runRigHostCli
|
|
476
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolveApproval(_workspaceRoot: string, runId: string, requestId: string, decision: "approve" | "reject"): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/rig-host/src/domain/approval.ts
|
|
3
|
+
var OMP_COLLAB_APPROVAL_RETIRED_MESSAGE = "Approval resolution through rig-host file append is retired. Resolve approvals through the OMP collab inbox/run detail flow.";
|
|
4
|
+
async function resolveApproval(_workspaceRoot, runId, requestId, decision) {
|
|
5
|
+
throw new Error(`${OMP_COLLAB_APPROVAL_RETIRED_MESSAGE} Refusing to ${decision} approval ${requestId} for run ${runId}.`);
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
resolveApproval
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolveUserInput(_workspaceRoot: string, runId: string, requestId: string, _answers: Record<string, string>): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/rig-host/src/domain/input.ts
|
|
3
|
+
var OMP_COLLAB_INPUT_RETIRED_MESSAGE = "User input resolution through rig-host file append is retired. Resolve user input requests through the OMP collab inbox/run detail flow.";
|
|
4
|
+
async function resolveUserInput(_workspaceRoot, runId, requestId, _answers) {
|
|
5
|
+
throw new Error(`${OMP_COLLAB_INPUT_RETIRED_MESSAGE} Refusing to resolve user input ${requestId} for run ${runId}.`);
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
resolveUserInput
|
|
9
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TaskSummary } from "@rig/contracts";
|
|
2
|
+
import type { RigIdeaSnapshot } from "../protocol";
|
|
3
|
+
export type LegacyAuthorityRunStartOptions = {
|
|
4
|
+
readonly runtimeAdapter?: string | null;
|
|
5
|
+
readonly model?: string | null;
|
|
6
|
+
readonly runtimeMode?: string | null;
|
|
7
|
+
readonly interactionMode?: string | null;
|
|
8
|
+
readonly initialPrompt?: string | null;
|
|
9
|
+
readonly baselineMode?: string | null;
|
|
10
|
+
readonly prMode?: "auto" | "ask" | "off" | null;
|
|
11
|
+
};
|
|
12
|
+
export type RigIdeaHarness = {
|
|
13
|
+
snapshot(): RigIdeaSnapshot;
|
|
14
|
+
stopRun(runId: string): Promise<void>;
|
|
15
|
+
resolveApproval(runId: string, requestId: string, decision: "approve" | "reject"): Promise<void>;
|
|
16
|
+
resolveUserInput(runId: string, requestId: string, answers: Record<string, string>): Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
export declare function legacyAuthorityRunUnsupportedMessage(): string;
|
|
19
|
+
export declare function legacyAuthorityRunControlUnsupportedMessage(): string;
|
|
20
|
+
export declare function projectRetiredLegacyRigIdeaWorkspace(workspaceRoot: string, tasks: readonly TaskSummary[]): RigIdeaSnapshot;
|
|
21
|
+
export declare function startLegacyRigIdeaAdhocAuthorityRun(_workspaceRoot: string, _prompt: string, _options?: LegacyAuthorityRunStartOptions): Promise<{
|
|
22
|
+
runId: string;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function startLegacyRigIdeaTaskAuthorityRun(_workspaceRoot: string, _task: RigIdeaSnapshot["tasks"][number], _options?: LegacyAuthorityRunStartOptions): Promise<{
|
|
25
|
+
runId: string;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function stopRigIdeaRun(_workspaceRoot: string, _runId: string): never;
|
|
28
|
+
export declare function createRigIdeaHarness(workspaceRoot: string): Promise<RigIdeaHarness>;
|