@h-rig/cli 0.0.6-alpha.9 → 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.
Files changed (116) hide show
  1. package/README.md +18 -19
  2. package/dist/bin/build-rig-binaries.d.ts +2 -0
  3. package/dist/bin/build-rig-binaries.js +22 -10
  4. package/dist/bin/rig.d.ts +72 -0
  5. package/dist/bin/rig.js +15637 -7344
  6. package/dist/config/rig-default-config.yml +5 -0
  7. package/dist/src/app/drone-ui.d.ts +34 -0
  8. package/dist/src/app/drone-ui.js +278 -0
  9. package/dist/src/commands/_async-ui.d.ts +10 -0
  10. package/dist/src/commands/_async-ui.js +121 -0
  11. package/dist/src/commands/_cli-format.d.ts +56 -0
  12. package/dist/src/commands/_cli-format.js +319 -0
  13. package/dist/src/commands/_connection-state.d.ts +54 -0
  14. package/dist/src/commands/_connection-state.js +75 -11
  15. package/dist/src/commands/_doctor-checks.d.ts +46 -0
  16. package/dist/src/commands/_doctor-checks.js +100 -267
  17. package/dist/src/commands/_help-catalog.d.ts +51 -0
  18. package/dist/src/commands/_help-catalog.js +502 -0
  19. package/dist/src/commands/_inprocess-services.d.ts +33 -0
  20. package/dist/src/commands/_inprocess-services.js +102 -0
  21. package/dist/src/commands/_json-output.d.ts +11 -0
  22. package/dist/src/commands/_json-output.js +60 -0
  23. package/dist/src/commands/_lazy-reconcile.d.ts +34 -0
  24. package/dist/src/commands/_lazy-reconcile.js +102 -0
  25. package/dist/src/commands/_parsers.d.ts +15 -0
  26. package/dist/src/commands/_parsers.js +18 -11
  27. package/dist/src/commands/_paths.d.ts +11 -0
  28. package/dist/src/commands/_paths.js +1 -1
  29. package/dist/src/commands/_pi-frontend.d.ts +35 -0
  30. package/dist/src/commands/_pi-frontend.js +64 -0
  31. package/dist/src/commands/_pi-install.d.ts +42 -0
  32. package/dist/src/commands/_pi-install.js +19 -36
  33. package/dist/src/commands/_policy.d.ts +8 -0
  34. package/dist/src/commands/_policy.js +67 -19
  35. package/dist/src/commands/_probes.d.ts +1 -0
  36. package/dist/src/commands/_run-bridge.d.ts +114 -0
  37. package/dist/src/commands/_run-bridge.js +387 -0
  38. package/dist/src/commands/_run-diagnostics.d.ts +9 -0
  39. package/dist/src/commands/_run-diagnostics.js +51 -0
  40. package/dist/src/commands/_run-driver-helpers.d.ts +26 -0
  41. package/dist/src/commands/_run-driver-helpers.js +79 -230
  42. package/dist/src/commands/_run-projection.d.ts +50 -0
  43. package/dist/src/commands/_run-projection.js +349 -0
  44. package/dist/src/commands/_run-subcommands.d.ts +3 -0
  45. package/dist/src/commands/_run-subcommands.js +31 -0
  46. package/dist/src/commands/_spinner.d.ts +25 -0
  47. package/dist/src/commands/_spinner.js +65 -0
  48. package/dist/src/commands/agent.d.ts +3 -0
  49. package/dist/src/commands/agent.js +8575 -236
  50. package/dist/src/commands/dist.d.ts +28 -0
  51. package/dist/src/commands/dist.js +44 -29
  52. package/dist/src/commands/doctor.d.ts +3 -0
  53. package/dist/src/commands/doctor.js +219 -268
  54. package/dist/src/commands/github.d.ts +3 -0
  55. package/dist/src/commands/github.js +236 -188
  56. package/dist/src/commands/inbox.d.ts +28 -0
  57. package/dist/src/commands/inbox.js +530 -111
  58. package/dist/src/commands/init.d.ts +64 -0
  59. package/dist/src/commands/init.js +912 -705
  60. package/dist/src/commands/inspect.d.ts +20 -0
  61. package/dist/src/commands/inspect.js +709 -119
  62. package/dist/src/commands/pi.d.ts +3 -0
  63. package/dist/src/commands/pi.js +177 -0
  64. package/dist/src/commands/plugin.d.ts +16 -0
  65. package/dist/src/commands/plugin.js +576 -29
  66. package/dist/src/commands/profile-and-review.d.ts +4 -0
  67. package/dist/src/commands/profile-and-review.js +112 -67
  68. package/dist/src/commands/queue.d.ts +3 -0
  69. package/dist/src/commands/queue.js +20 -20
  70. package/dist/src/commands/remote.d.ts +3 -0
  71. package/dist/src/commands/remote.js +880 -50
  72. package/dist/src/commands/repo-git-harness.d.ts +5 -0
  73. package/dist/src/commands/repo-git-harness.js +78 -28
  74. package/dist/src/commands/run.d.ts +21 -0
  75. package/dist/src/commands/run.js +17701 -661
  76. package/dist/src/commands/server.d.ts +3 -0
  77. package/dist/src/commands/server.js +166 -303
  78. package/dist/src/commands/setup.d.ts +16 -0
  79. package/dist/src/commands/setup.js +244 -299
  80. package/dist/src/commands/stats.d.ts +15 -0
  81. package/dist/src/commands/stats.js +979 -0
  82. package/dist/src/commands/task-run-driver.d.ts +94 -0
  83. package/dist/src/commands/task-run-driver.js +116 -1961
  84. package/dist/src/commands/task.d.ts +35 -0
  85. package/dist/src/commands/task.js +676 -1201
  86. package/dist/src/commands/test.d.ts +3 -0
  87. package/dist/src/commands/test.js +15 -8
  88. package/dist/src/commands/triage.d.ts +11 -0
  89. package/dist/src/commands/triage.js +227 -0
  90. package/dist/src/commands/workspace.d.ts +3 -0
  91. package/dist/src/commands/workspace.js +18 -11
  92. package/dist/src/commands.d.ts +13 -0
  93. package/dist/src/commands.js +16792 -8055
  94. package/dist/src/index.d.ts +4 -0
  95. package/dist/src/index.js +16862 -8450
  96. package/dist/src/launcher.d.ts +61 -0
  97. package/dist/src/launcher.js +81 -13
  98. package/dist/src/operator-cli.d.ts +2 -0
  99. package/dist/src/operator-cli.js +17837 -0
  100. package/dist/src/operator-entry.d.ts +1 -0
  101. package/dist/src/operator-entry.js +3 -0
  102. package/dist/src/runner.d.ts +47 -0
  103. package/dist/src/runner.js +16 -22
  104. package/dist/src/withMutedConsole.d.ts +2 -0
  105. package/package.json +21 -8
  106. package/dist/src/commands/_authority-runs.js +0 -111
  107. package/dist/src/commands/_operator-view.js +0 -340
  108. package/dist/src/commands/_preflight.js +0 -478
  109. package/dist/src/commands/_server-client.js +0 -382
  110. package/dist/src/commands/_snapshot-upload.js +0 -331
  111. package/dist/src/commands/_task-picker.js +0 -48
  112. package/dist/src/commands/browser.js +0 -890
  113. package/dist/src/commands/connect.js +0 -180
  114. package/dist/src/commands/inspector.js +0 -256
  115. package/dist/src/commands/task-report-bug.js +0 -1083
  116. package/dist/src/report-bug.js +0 -260
@@ -0,0 +1,51 @@
1
+ // @bun
2
+ // packages/cli/src/commands/_run-diagnostics.ts
3
+ function normalizeString(value) {
4
+ if (typeof value !== "string")
5
+ return null;
6
+ const normalized = value.replace(/\s+/g, " ").trim();
7
+ return normalized.length > 0 ? normalized : null;
8
+ }
9
+ function isGenericRunFailure(value) {
10
+ const text = normalizeString(value);
11
+ return Boolean(text && /^Task run failed \([^)]*\)$/i.test(text));
12
+ }
13
+ function appendCandidate(candidates, value) {
14
+ const text = normalizeString(value);
15
+ if (text && !candidates.includes(text))
16
+ candidates.push(text);
17
+ }
18
+ function categorizeUsefulRunError(lines) {
19
+ const taskSourceFailure = lines.find((line) => /failed to update task source/i.test(line));
20
+ if (taskSourceFailure)
21
+ return `Task source update failed: ${taskSourceFailure}`;
22
+ const moduleFailure = lines.find((line) => /cannot find module/i.test(line));
23
+ if (moduleFailure)
24
+ return `Runtime module resolution failed: ${moduleFailure}`;
25
+ const providerFailure = lines.find((line) => /no api key found|unauthorized|authentication failed|invalid api key/i.test(line));
26
+ if (providerFailure)
27
+ return `Provider authentication failed: ${providerFailure}`;
28
+ return null;
29
+ }
30
+ function summarizeUsefulRunError(projection) {
31
+ if (projection.status !== "failed")
32
+ return null;
33
+ const candidates = [];
34
+ for (const anomaly of projection.anomalies) {
35
+ appendCandidate(candidates, `Journal anomaly (${anomaly.kind}): ${anomaly.detail}`);
36
+ }
37
+ for (const phase of projection.closeoutPhases) {
38
+ if (phase.outcome === "failed")
39
+ appendCandidate(candidates, phase.detail);
40
+ }
41
+ for (const entry of projection.statusHistory) {
42
+ appendCandidate(candidates, entry.reason);
43
+ }
44
+ appendCandidate(candidates, projection.record.statusDetail);
45
+ appendCandidate(candidates, projection.record.errorText);
46
+ const nonGeneric = candidates.filter((candidate) => !isGenericRunFailure(candidate));
47
+ return categorizeUsefulRunError(nonGeneric) ?? nonGeneric.at(-1) ?? normalizeString(projection.record.errorText);
48
+ }
49
+ export {
50
+ summarizeUsefulRunError
51
+ };
@@ -0,0 +1,26 @@
1
+ export type SourceTaskContract = {
2
+ id: string;
3
+ title?: string | null;
4
+ description?: string | null;
5
+ body?: string | null;
6
+ acceptanceCriteria?: string | null;
7
+ acceptance_criteria?: string | null;
8
+ sourceIssueId?: string | null;
9
+ status?: string | null;
10
+ issueType?: string | null;
11
+ role?: string | null;
12
+ validation?: string[];
13
+ validators?: string[];
14
+ labels?: string[];
15
+ scope?: string[];
16
+ };
17
+ export declare function buildRunPrompt(input: {
18
+ projectRoot: string;
19
+ taskId?: string | undefined;
20
+ fallbackTitle?: string | undefined;
21
+ fallbackDescription?: string | undefined;
22
+ fallbackAcceptanceCriteria?: string | undefined;
23
+ sourceTask?: SourceTaskContract | null;
24
+ initialPrompt?: string;
25
+ runtimeAdapter: "claude-code" | "codex" | "pi";
26
+ }): string;
@@ -1,41 +1,11 @@
1
1
  // @bun
2
2
  // packages/cli/src/commands/_run-driver-helpers.ts
3
- import { readFileSync } from "fs";
4
- import { resolve as resolve3 } from "path";
5
-
6
- // packages/cli/src/runner.ts
7
- import { EventBus } from "@rig/runtime/control-plane/runtime/events";
8
- import { CliError } from "@rig/runtime/control-plane/errors";
9
- import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
10
- import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
11
- import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
12
- import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
13
- import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
14
-
15
- // packages/cli/src/commands/_run-driver-helpers.ts
16
- import {
17
- appendJsonlRecord,
18
- readAuthorityRun as readAuthorityRun2,
19
- resolveAuthorityRunDir as resolveAuthorityRunDir2,
20
- writeJsonFile as writeJsonFile2
21
- } from "@rig/runtime/control-plane/authority-files";
22
- import { taskLookup } from "@rig/runtime/control-plane/native/task-ops";
23
- import { buildProviderTaskRunInstructionLines } from "@rig/runtime/control-plane/provider/runtime-instructions";
24
- import { loadRigTaskRunSkillBody } from "@rig/runtime/control-plane/provider/rig-task-run-skill";
25
-
26
- // packages/cli/src/commands/_authority-runs.ts
27
- import { existsSync } from "fs";
3
+ import { existsSync, readFileSync } from "fs";
28
4
  import { resolve as resolve2 } from "path";
29
- import {
30
- readAuthorityRun,
31
- readJsonlFile,
32
- resolveAuthorityRunDir,
33
- writeJsonFile
34
- } from "@rig/runtime/control-plane/authority-files";
35
5
 
36
6
  // packages/cli/src/commands/_paths.ts
37
7
  import { resolve } from "path";
38
- import { resolveMonorepoRoot } from "@rig/runtime/control-plane/native/utils";
8
+ import { resolveMonorepoRoot } from "@rig/runtime/layout";
39
9
  function resolveControlPlaneMonorepoRoot(projectRoot) {
40
10
  return resolveMonorepoRoot(projectRoot);
41
11
  }
@@ -43,160 +13,108 @@ function resolveControlPlaneTaskConfigPath(projectRoot) {
43
13
  return resolve(resolveControlPlaneMonorepoRoot(projectRoot), ".rig", "task-config.json");
44
14
  }
45
15
 
46
- // packages/cli/src/commands/_authority-runs.ts
16
+ // packages/cli/src/commands/_run-driver-helpers.ts
47
17
  function readLatestBeadRecord(projectRoot, taskId) {
48
18
  const issuesPath = resolve2(resolveControlPlaneMonorepoRoot(projectRoot), ".beads", "issues.jsonl");
49
19
  if (!existsSync(issuesPath)) {
50
20
  return null;
51
21
  }
52
22
  let latest = null;
53
- for (const issue of readJsonlFile(issuesPath)) {
54
- if (!issue || typeof issue !== "object") {
23
+ for (const line of readFileSync(issuesPath, "utf8").split(/\r?\n/)) {
24
+ const trimmed = line.trim();
25
+ if (!trimmed)
55
26
  continue;
56
- }
57
- const record = issue;
58
- if (record.id === taskId) {
59
- latest = record;
60
- }
27
+ try {
28
+ const parsed = JSON.parse(trimmed);
29
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
30
+ continue;
31
+ const record = parsed;
32
+ if (record.id === taskId)
33
+ latest = record;
34
+ } catch {}
61
35
  }
62
36
  return latest;
63
37
  }
64
-
65
- // packages/cli/src/commands/_run-driver-helpers.ts
66
- function patchAuthorityRun(projectRoot, runId, patch) {
67
- const current = readAuthorityRun2(projectRoot, runId);
68
- if (!current) {
69
- throw new CliError2(`Run not found: ${runId}`, 2);
70
- }
71
- const next = {
72
- ...current,
73
- ...patch,
74
- updatedAt: new Date().toISOString()
75
- };
76
- writeJsonFile2(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "run.json"), next);
77
- return next;
78
- }
79
- function touchAuthorityRun(projectRoot, runId) {
80
- const current = readAuthorityRun2(projectRoot, runId);
81
- if (!current) {
82
- return;
38
+ function firstPromptString(...values) {
39
+ for (const value of values) {
40
+ if (typeof value === "string" && value.trim())
41
+ return value.trim();
83
42
  }
84
- writeJsonFile2(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "run.json"), {
85
- ...current,
86
- updatedAt: new Date().toISOString()
87
- });
88
- }
89
- function appendRunTimeline(projectRoot, runId, value) {
90
- appendJsonlRecord(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "timeline.jsonl"), value);
91
- touchAuthorityRun(projectRoot, runId);
92
- }
93
- function appendRunLog(projectRoot, runId, value) {
94
- appendJsonlRecord(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "logs.jsonl"), value);
95
- touchAuthorityRun(projectRoot, runId);
43
+ return null;
96
44
  }
97
- function appendRunAction(projectRoot, runId, value) {
98
- appendJsonlRecord(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "timeline.jsonl"), {
99
- id: value.id,
100
- type: "action",
101
- actionType: value.actionType,
102
- title: value.title,
103
- detail: value.detail ?? null,
104
- state: value.state,
105
- createdAt: value.startedAt,
106
- completedAt: value.completedAt ?? null,
107
- payload: value.payload ?? {}
108
- });
45
+ function uniqueStrings(values) {
46
+ return Array.from(new Set(values.map((value) => value.trim()).filter(Boolean)));
109
47
  }
110
- function startRunAction(projectRoot, runId, input) {
111
- const startedAt = new Date().toISOString();
112
- appendRunAction(projectRoot, runId, {
113
- id: input.actionId,
114
- actionType: input.actionType,
115
- title: input.title,
116
- detail: input.detail,
117
- state: "running",
118
- startedAt,
119
- payload: input.payload
120
- });
121
- emitServerRunEvent({ type: "timeline", runId });
122
- return {
123
- startedAt,
124
- complete: (detail, payload) => {
125
- appendRunAction(projectRoot, runId, {
126
- id: input.actionId,
127
- actionType: input.actionType,
128
- title: input.title,
129
- detail: detail ?? input.detail ?? null,
130
- state: "completed",
131
- startedAt,
132
- completedAt: new Date().toISOString(),
133
- payload: payload ?? input.payload
134
- });
135
- emitServerRunEvent({ type: "timeline", runId });
136
- },
137
- fail: (detail, payload) => {
138
- appendRunAction(projectRoot, runId, {
139
- id: input.actionId,
140
- actionType: input.actionType,
141
- title: input.title,
142
- detail,
143
- state: "failed",
144
- startedAt,
145
- completedAt: new Date().toISOString(),
146
- payload: payload ?? input.payload
147
- });
148
- emitServerRunEvent({ type: "timeline", runId });
149
- }
150
- };
48
+ function renderSourceTaskContract(task, validation) {
49
+ if (!task)
50
+ return validation.length > 0 ? [`Validation: ${validation.join(", ")}`] : [];
51
+ const lines = [`id: ${task.id}`];
52
+ if (task.sourceIssueId)
53
+ lines.push(`source issue: ${task.sourceIssueId}`);
54
+ if (task.status)
55
+ lines.push(`status: ${task.status}`);
56
+ if (task.issueType)
57
+ lines.push(`issue type: ${task.issueType}`);
58
+ if (task.role)
59
+ lines.push(`role: ${task.role}`);
60
+ if (validation.length > 0)
61
+ lines.push(`validation: ${validation.join(", ")}`);
62
+ return lines;
151
63
  }
152
- function emitServerRunEvent(event) {
153
- console.log(`__RIG_RUN_EVENT__${JSON.stringify({ ...event, at: new Date().toISOString() })}`);
64
+ function renderSourceScopeValidation(task, validation) {
65
+ if (task || validation.length === 0)
66
+ return "";
67
+ return `Validation:
68
+ - ${validation.join(`
69
+ - `)}`;
154
70
  }
155
- function buildRunPrompt(input) {
156
- const initialPrompt = input.initialPrompt?.trim() || null;
157
- if (!input.taskId) {
158
- return initialPrompt ?? input.fallbackTitle?.trim() ?? "Continue the requested Rig run and complete the work.";
159
- }
160
- const issues = (() => {
161
- try {
162
- return taskLookup(input.projectRoot, input.taskId);
163
- } catch {
164
- return "";
165
- }
166
- })();
167
- const scopeText = (() => {
168
- try {
169
- const parsed = JSON.parse(readFileSync(resolveControlPlaneTaskConfigPath(input.projectRoot), "utf8"));
170
- const entry = parsed[input.taskId] ?? {};
171
- const scope = Array.isArray(entry.scope) ? entry.scope.filter((item) => typeof item === "string") : [];
172
- const validation = Array.isArray(entry.validation) ? entry.validation.filter((item) => typeof item === "string") : [];
173
- const lines = [];
174
- if (scope.length > 0)
175
- lines.push(`Scope:
71
+ function readTaskScopeText(projectRoot, taskId) {
72
+ try {
73
+ const parsed = JSON.parse(readFileSync(resolveControlPlaneTaskConfigPath(projectRoot), "utf8"));
74
+ const entry = parsed[taskId] ?? {};
75
+ const scope = Array.isArray(entry.scope) ? entry.scope.filter((item) => typeof item === "string") : [];
76
+ const validation = Array.isArray(entry.validation) ? entry.validation.filter((item) => typeof item === "string") : [];
77
+ const lines = [];
78
+ if (scope.length > 0)
79
+ lines.push(`Scope:
176
80
  - ${scope.join(`
177
81
  - `)}`);
178
- if (validation.length > 0)
179
- lines.push(`Validation:
82
+ if (validation.length > 0)
83
+ lines.push(`Validation:
180
84
  - ${validation.join(`
181
85
  - `)}`);
182
- return lines.join(`
86
+ return lines.join(`
183
87
 
184
88
  `);
185
- } catch {
186
- return "";
187
- }
188
- })();
89
+ } catch {
90
+ return "";
91
+ }
92
+ }
93
+ function providerInstructionLines(runtimeAdapter) {
94
+ if (runtimeAdapter === "pi") {
95
+ return ["Keep file writes inside the scoped task workspace and use the bridged Pi tooling for shell and follow-up prompts."];
96
+ }
97
+ if (runtimeAdapter === "codex") {
98
+ return ["Keep file writes inside the scoped task workspace and prefer compact terminal output."];
99
+ }
100
+ return ["Keep file writes inside the scoped task workspace and stay within the provided tool surface."];
101
+ }
102
+ function buildRunPrompt(input) {
103
+ const initialPrompt = input.initialPrompt?.trim() || null;
104
+ if (!input.taskId) {
105
+ return initialPrompt ?? input.fallbackTitle?.trim() ?? "Continue the requested run and complete the work.";
106
+ }
189
107
  const bead = readLatestBeadRecord(input.projectRoot, input.taskId);
190
108
  const sourceTask = input.sourceTask ?? null;
191
109
  const sourceDescription = firstPromptString(sourceTask?.description, sourceTask?.body);
192
110
  const sourceAcceptance = firstPromptString(sourceTask?.acceptanceCriteria, sourceTask?.acceptance_criteria);
193
111
  const sourceValidation = uniqueStrings([...sourceTask?.validation ?? [], ...sourceTask?.validators ?? []]);
194
- const title = (bead && typeof bead === "object" && typeof bead.title === "string" ? bead.title : null) ?? firstPromptString(sourceTask?.title) ?? input.fallbackTitle ?? issues ?? input.taskId;
195
- const description = (bead && typeof bead === "object" && typeof bead.description === "string" ? bead.description : null) ?? sourceDescription ?? input.fallbackDescription ?? "";
196
- const acceptance = bead && typeof bead === "object" && typeof bead.acceptance_criteria === "string" ? bead.acceptance_criteria : sourceAcceptance ?? input.fallbackAcceptanceCriteria ?? "";
112
+ const title = (bead && typeof bead.title === "string" ? bead.title : null) ?? firstPromptString(sourceTask?.title) ?? input.fallbackTitle ?? input.taskId;
113
+ const description = (bead && typeof bead.description === "string" ? bead.description : null) ?? sourceDescription ?? input.fallbackDescription ?? "";
114
+ const acceptance = (bead && typeof bead.acceptance_criteria === "string" ? bead.acceptance_criteria : null) ?? sourceAcceptance ?? input.fallbackAcceptanceCriteria ?? "";
115
+ const scopeText = readTaskScopeText(input.projectRoot, input.taskId);
197
116
  const sourceContractLines = renderSourceTaskContract(sourceTask, sourceValidation);
198
- const providerLines = buildProviderTaskRunInstructionLines(input.runtimeAdapter);
199
- const skillBody = loadRigTaskRunSkillBody();
117
+ const providerLines = providerInstructionLines(input.runtimeAdapter);
200
118
  return [
201
119
  `You are working on task ${input.taskId}: ${title}.`,
202
120
  description ? `Description:
@@ -210,80 +128,11 @@ ${sourceContractLines.join(`
210
128
  initialPrompt ? `Additional operator guidance:
211
129
  ${initialPrompt}` : null,
212
130
  providerLines.length > 0 ? `Provider-specific runtime tooling:
213
- ${providerLines.join(" ")}` : null,
214
- skillBody || null
131
+ ${providerLines.join(" ")}` : null
215
132
  ].filter((value) => Boolean(value)).join(`
216
133
 
217
- `);
218
- }
219
- function firstPromptString(...values) {
220
- for (const value of values) {
221
- const trimmed = typeof value === "string" ? value.trim() : "";
222
- if (trimmed.length > 0) {
223
- return trimmed;
224
- }
225
- }
226
- return null;
227
- }
228
- function uniqueStrings(values) {
229
- return Array.from(new Set(values.map((value) => value.trim()).filter(Boolean)));
230
- }
231
- function renderSourceTaskContract(task, validation) {
232
- if (!task) {
233
- return [];
234
- }
235
- const lines = [];
236
- const sourceIssueId = firstPromptString(task.sourceIssueId);
237
- if (sourceIssueId)
238
- lines.push(`Source issue: ${sourceIssueId}`);
239
- const status = firstPromptString(task.status);
240
- if (status)
241
- lines.push(`Source status: ${status}`);
242
- const issueType = firstPromptString(task.issueType);
243
- if (issueType)
244
- lines.push(`Issue type: ${issueType}`);
245
- const role = firstPromptString(task.role);
246
- if (role)
247
- lines.push(`Role: ${role}`);
248
- const externalRef = firstPromptString(task.externalRef);
249
- if (externalRef)
250
- lines.push(`External ref: ${externalRef}`);
251
- const labels = uniqueStrings(task.labels ?? []);
252
- if (labels.length > 0)
253
- lines.push(`Labels:
254
- - ${labels.join(`
255
- - `)}`);
256
- if (validation.length > 0)
257
- lines.push(`Validators:
258
- - ${validation.join(`
259
- - `)}`);
260
- return lines;
261
- }
262
- function renderSourceScopeValidation(task, validation) {
263
- if (!task) {
264
- return "";
265
- }
266
- const lines = [];
267
- const scope = uniqueStrings(task.scope ?? []);
268
- if (scope.length > 0)
269
- lines.push(`Scope:
270
- - ${scope.join(`
271
- - `)}`);
272
- if (validation.length > 0)
273
- lines.push(`Validation:
274
- - ${validation.join(`
275
- - `)}`);
276
- return lines.join(`
277
-
278
134
  `);
279
135
  }
280
136
  export {
281
- touchAuthorityRun,
282
- startRunAction,
283
- patchAuthorityRun,
284
- emitServerRunEvent,
285
- buildRunPrompt,
286
- appendRunTimeline,
287
- appendRunLog,
288
- appendRunAction
137
+ buildRunPrompt
289
138
  };
@@ -0,0 +1,50 @@
1
+ import { type RunJournalProjection, type RunSessionCustomEntry } from "@rig/contracts";
2
+ import type { CollabRegistryFilter } from "@oh-my-pi/pi-coding-agent/collab/api";
3
+ /** A run as seen by the operator CLI: live-presence facts joined with the folded journal. */
4
+ export interface RunProjectionRecord {
5
+ readonly runId: string;
6
+ readonly taskId: string | null;
7
+ readonly title: string;
8
+ /** RunStatus from the folded journal, or a liveness-derived fallback. */
9
+ readonly status: string;
10
+ readonly source: "local" | "remote";
11
+ /** True when the run is currently discoverable (registry heartbeat or local host). */
12
+ readonly live: boolean;
13
+ readonly stale: boolean;
14
+ readonly startedAt: string | null;
15
+ readonly updatedAt: string | null;
16
+ readonly completedAt: string | null;
17
+ readonly joinLink: string | null;
18
+ readonly webLink: string | null;
19
+ readonly relayUrl: string | null;
20
+ readonly sessionPath: string | null;
21
+ readonly prUrl: string | null;
22
+ readonly worktreePath: string | null;
23
+ readonly pendingApprovals: number;
24
+ readonly pendingInputs: number;
25
+ readonly steeringCount: number;
26
+ readonly stallCount: number;
27
+ readonly errorSummary?: string | null;
28
+ /** The full folded journal (empty projection when no journal was readable). */
29
+ readonly projection: RunJournalProjection;
30
+ }
31
+ /** What an attach/steer caller needs to reach a live run over collab. */
32
+ export interface RunJoinTarget {
33
+ readonly runId: string;
34
+ readonly taskId: string | null;
35
+ readonly joinLink: string;
36
+ readonly cwd: string | null;
37
+ readonly stale: boolean;
38
+ }
39
+ /** Parse an OMP session JSONL into the custom-entry shape `foldRunSessionEntries` expects. */
40
+ export declare function readSessionRunEntries(sessionPath: string | null): RunSessionCustomEntry[];
41
+ /**
42
+ * List every discoverable run: live collab (relay-registry + local hosts) merged
43
+ * with finished/local runs recovered from on-disk agent-runtime session journals.
44
+ * Live entries win on runId collisions (they carry join links + current presence).
45
+ */
46
+ export declare function listRunProjections(projectRoot: string, filter?: CollabRegistryFilter): Promise<RunProjectionRecord[]>;
47
+ /** Resolve a single run by id (or unambiguous prefix). */
48
+ export declare function getRunProjection(projectRoot: string, runId: string, filter?: CollabRegistryFilter): Promise<RunProjectionRecord | null>;
49
+ /** Resolve the live join target for attach/steer; null when the run is not currently joinable. */
50
+ export declare function resolveRunJoinTarget(projectRoot: string, runId: string, filter?: CollabRegistryFilter): Promise<RunJoinTarget | null>;