@h-rig/cli 0.0.6-alpha.83 → 0.0.6-alpha.84
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/dist/bin/rig.js +22085 -14618
- package/dist/src/app/board.js +155 -28
- package/dist/src/app-opentui/adapters/doctor.d.ts +0 -2
- package/dist/src/app-opentui/adapters/doctor.js +1 -25
- package/dist/src/app-opentui/adapters/family.d.ts +62 -0
- package/dist/src/app-opentui/adapters/family.js +14305 -0
- package/dist/src/app-opentui/adapters/fleet.d.ts +0 -2
- package/dist/src/app-opentui/adapters/fleet.js +6 -40
- package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
- package/dist/src/app-opentui/adapters/inbox.js +54 -59
- package/dist/src/app-opentui/adapters/init.d.ts +0 -2
- package/dist/src/app-opentui/adapters/init.js +0 -26
- package/dist/src/app-opentui/adapters/inspect.d.ts +52 -0
- package/dist/src/app-opentui/adapters/inspect.js +1024 -0
- package/dist/src/app-opentui/adapters/pi-attach.d.ts +15 -6
- package/dist/src/app-opentui/adapters/pi-attach.js +348 -93
- package/dist/src/app-opentui/adapters/pi.d.ts +23 -0
- package/dist/src/app-opentui/adapters/pi.js +363 -0
- package/dist/src/app-opentui/adapters/plugin.d.ts +84 -0
- package/dist/src/app-opentui/adapters/plugin.js +544 -0
- package/dist/src/app-opentui/adapters/repo.d.ts +37 -0
- package/dist/src/app-opentui/adapters/repo.js +186 -0
- package/dist/src/app-opentui/adapters/run-detail.d.ts +9 -2
- package/dist/src/app-opentui/adapters/run-detail.js +97 -44
- package/dist/src/app-opentui/adapters/server.d.ts +10 -2
- package/dist/src/app-opentui/adapters/server.js +96 -27
- package/dist/src/app-opentui/adapters/tasks.d.ts +0 -2
- package/dist/src/app-opentui/adapters/tasks.js +437 -105
- package/dist/src/app-opentui/adapters/workspace.d.ts +49 -0
- package/dist/src/app-opentui/adapters/workspace.js +333 -0
- package/dist/src/app-opentui/autocomplete.d.ts +20 -0
- package/dist/src/app-opentui/autocomplete.js +576 -0
- package/dist/src/app-opentui/bootstrap.js +24296 -16919
- package/dist/src/app-opentui/command-palette.d.ts +3 -0
- package/dist/src/app-opentui/command-palette.js +1010 -0
- package/dist/src/app-opentui/drone.js +8 -6
- package/dist/src/app-opentui/fleet-stats.d.ts +32 -0
- package/dist/src/app-opentui/fleet-stats.js +114 -0
- package/dist/src/app-opentui/index.js +3438 -1724
- package/dist/src/app-opentui/intent.js +71 -48
- package/dist/src/app-opentui/keymap.d.ts +6 -5
- package/dist/src/app-opentui/keymap.js +1064 -23
- package/dist/src/app-opentui/layout.d.ts +7 -0
- package/dist/src/app-opentui/layout.js +13 -6
- package/dist/src/app-opentui/list-search.d.ts +24 -0
- package/dist/src/app-opentui/list-search.js +88 -1
- package/dist/src/app-opentui/pi-host-child.js +33 -1
- package/dist/src/app-opentui/pi-pty-host.d.ts +5 -0
- package/dist/src/app-opentui/pi-pty-host.js +21 -3
- package/dist/src/app-opentui/react/App.d.ts +9 -0
- package/dist/src/app-opentui/react/App.js +5144 -0
- package/dist/src/app-opentui/react/Backdrop.d.ts +5 -0
- package/dist/src/app-opentui/react/Backdrop.js +1834 -0
- package/dist/src/app-opentui/react/ChromeHost.d.ts +5 -0
- package/dist/src/app-opentui/react/ChromeHost.js +2942 -0
- package/dist/src/app-opentui/react/SceneFrameView.d.ts +7 -0
- package/dist/src/app-opentui/react/SceneFrameView.js +529 -0
- package/dist/src/app-opentui/react/context.d.ts +17 -0
- package/dist/src/app-opentui/react/context.js +37 -0
- package/dist/src/app-opentui/react/launch.d.ts +2 -0
- package/dist/src/app-opentui/react/launch.js +5743 -0
- package/dist/src/app-opentui/react/nav.d.ts +18 -0
- package/dist/src/app-opentui/react/nav.js +54 -0
- package/dist/src/app-opentui/react/scroll.d.ts +12 -0
- package/dist/src/app-opentui/react/scroll.js +21 -0
- package/dist/src/app-opentui/react/syntax.d.ts +2 -0
- package/dist/src/app-opentui/react/syntax.js +64 -0
- package/dist/src/app-opentui/registry.js +19923 -5151
- package/dist/src/app-opentui/render/constants.d.ts +31 -0
- package/dist/src/app-opentui/render/constants.js +66 -0
- package/dist/src/app-opentui/render/graphics.d.ts +2 -1
- package/dist/src/app-opentui/render/graphics.js +106 -39
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +108 -20
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +7 -0
- package/dist/src/app-opentui/render/image-visual-layer.js +109 -20
- package/dist/src/app-opentui/render/native-host.d.ts +37 -0
- package/dist/src/app-opentui/render/native-host.js +179 -0
- package/dist/src/app-opentui/render/panels.js +18 -11
- package/dist/src/app-opentui/render/preloader.js +8 -6
- package/dist/src/app-opentui/render/scene.d.ts +50 -1
- package/dist/src/app-opentui/render/scene.js +183 -6
- package/dist/src/app-opentui/render/text.d.ts +7 -1
- package/dist/src/app-opentui/render/text.js +10 -7
- package/dist/src/app-opentui/render/type-bar.js +69 -30
- package/dist/src/app-opentui/runtime.d.ts +44 -1
- package/dist/src/app-opentui/runtime.js +3231 -1363
- package/dist/src/app-opentui/scenes/command.js +20 -6
- package/dist/src/app-opentui/scenes/doctor.js +176 -11
- package/dist/src/app-opentui/scenes/error.js +20 -10
- package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/agent.js +348 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.js +195 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.js +243 -0
- package/dist/src/app-opentui/scenes/family-domains/git.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/git.js +195 -0
- package/dist/src/app-opentui/scenes/family-domains/github.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/github.js +274 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.js +152 -0
- package/dist/src/app-opentui/scenes/family-domains/index.d.ts +4 -0
- package/dist/src/app-opentui/scenes/family-domains/index.js +1679 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +76 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.js +305 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.js +212 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.js +146 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.js +518 -0
- package/dist/src/app-opentui/scenes/family-domains/review.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/review.js +280 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.js +267 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.js +370 -0
- package/dist/src/app-opentui/scenes/family.d.ts +3 -0
- package/dist/src/app-opentui/scenes/family.js +2144 -0
- package/dist/src/app-opentui/scenes/fleet.js +521 -31
- package/dist/src/app-opentui/scenes/handoff.js +204 -12
- package/dist/src/app-opentui/scenes/help.js +609 -40
- package/dist/src/app-opentui/scenes/inbox.js +278 -17
- package/dist/src/app-opentui/scenes/init.js +84 -39
- package/dist/src/app-opentui/scenes/inspect.d.ts +3 -0
- package/dist/src/app-opentui/scenes/inspect.js +793 -0
- package/dist/src/app-opentui/scenes/main.js +218 -39
- package/dist/src/app-opentui/scenes/pi.d.ts +3 -0
- package/dist/src/app-opentui/scenes/pi.js +508 -0
- package/dist/src/app-opentui/scenes/plugin.d.ts +3 -0
- package/dist/src/app-opentui/scenes/plugin.js +486 -0
- package/dist/src/app-opentui/scenes/repo.d.ts +3 -0
- package/dist/src/app-opentui/scenes/repo.js +424 -0
- package/dist/src/app-opentui/scenes/run-detail.js +333 -20
- package/dist/src/app-opentui/scenes/server.js +181 -15
- package/dist/src/app-opentui/scenes/tasks.js +486 -31
- package/dist/src/app-opentui/scenes/workspace.d.ts +3 -0
- package/dist/src/app-opentui/scenes/workspace.js +426 -0
- package/dist/src/app-opentui/selectable.d.ts +19 -0
- package/dist/src/app-opentui/selectable.js +79 -0
- package/dist/src/app-opentui/state.js +83 -30
- package/dist/src/app-opentui/surface-catalog.d.ts +20 -0
- package/dist/src/app-opentui/surface-catalog.js +540 -0
- package/dist/src/app-opentui/theme.d.ts +28 -6
- package/dist/src/app-opentui/theme.js +61 -8
- package/dist/src/app-opentui/types.d.ts +121 -4
- package/dist/src/commands/_authority-runs.d.ts +1 -1
- package/dist/src/commands/_authority-runs.js +2 -12
- package/dist/src/commands/_help-catalog.js +95 -15
- package/dist/src/commands/_operator-view.js +34 -2
- package/dist/src/commands/_pi-frontend.d.ts +2 -0
- package/dist/src/commands/_pi-frontend.js +34 -0
- package/dist/src/commands/_server-events.d.ts +26 -0
- package/dist/src/commands/_server-events.js +310 -0
- package/dist/src/commands/agent.js +2 -12
- package/dist/src/commands/run.js +34 -2
- package/dist/src/commands/server.js +2 -12
- package/dist/src/commands/stats.js +95 -15
- package/dist/src/commands/task-run-driver.js +2 -12
- package/dist/src/commands/task.js +131 -29
- package/dist/src/commands.js +192 -31
- package/dist/src/index.js +192 -31
- package/package.json +11 -9
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
4
|
+
// packages/cli/src/app-opentui/adapters/common.ts
|
|
5
|
+
function projectRootOf(ctx) {
|
|
6
|
+
const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
|
|
7
|
+
if (typeof root === "string" && root.trim())
|
|
8
|
+
return root;
|
|
9
|
+
throw new Error("App adapter requires a projectRoot.");
|
|
10
|
+
}
|
|
11
|
+
function normalizeAppError(error) {
|
|
12
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
13
|
+
const rawHint = error instanceof Error ? error.hint : undefined;
|
|
14
|
+
return {
|
|
15
|
+
message,
|
|
16
|
+
...typeof rawHint === "string" && rawHint.trim() ? { hint: rawHint.trim() } : {}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function emitStarted(ctx, label, optimistic) {
|
|
20
|
+
ctx.emit({ type: "action.started", label, ...optimistic ? { optimistic } : {} });
|
|
21
|
+
}
|
|
22
|
+
function emitProgress(ctx, label, detail, data) {
|
|
23
|
+
ctx.emit({ type: "action.progress", label, ...detail ? { detail } : {}, ...data ? { data } : {} });
|
|
24
|
+
}
|
|
25
|
+
function emitCompleted(ctx, label, data) {
|
|
26
|
+
ctx.emit({ type: "action.completed", label, ...data ? { data } : {} });
|
|
27
|
+
}
|
|
28
|
+
function emitFailed(ctx, label, error, data) {
|
|
29
|
+
if (data)
|
|
30
|
+
patchData(ctx, data);
|
|
31
|
+
const normalized = normalizeAppError(error);
|
|
32
|
+
ctx.emit({
|
|
33
|
+
type: "action.failed",
|
|
34
|
+
label,
|
|
35
|
+
message: normalized.message,
|
|
36
|
+
...normalized.hint ? { hint: normalized.hint } : {},
|
|
37
|
+
cause: error
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function patchData(ctx, data) {
|
|
41
|
+
ctx.emit({ type: "data.patch", data });
|
|
42
|
+
}
|
|
43
|
+
function patchFooter(ctx, footer) {
|
|
44
|
+
ctx.emit({ type: "footer.patch", footer });
|
|
45
|
+
}
|
|
46
|
+
async function captureConsole(fn) {
|
|
47
|
+
const output = [];
|
|
48
|
+
const original = {
|
|
49
|
+
log: console.log,
|
|
50
|
+
info: console.info,
|
|
51
|
+
warn: console.warn,
|
|
52
|
+
error: console.error
|
|
53
|
+
};
|
|
54
|
+
const capture = (...parts) => {
|
|
55
|
+
output.push(parts.map((part) => typeof part === "string" ? part : JSON.stringify(part)).join(" "));
|
|
56
|
+
};
|
|
57
|
+
console.log = capture;
|
|
58
|
+
console.info = capture;
|
|
59
|
+
console.warn = capture;
|
|
60
|
+
console.error = capture;
|
|
61
|
+
try {
|
|
62
|
+
const result = await fn();
|
|
63
|
+
return { result, output };
|
|
64
|
+
} finally {
|
|
65
|
+
console.log = original.log;
|
|
66
|
+
console.info = original.info;
|
|
67
|
+
console.warn = original.warn;
|
|
68
|
+
console.error = original.error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// packages/cli/src/app-opentui/adapters/repo.ts
|
|
73
|
+
function repoActionRequest(ctx) {
|
|
74
|
+
const intent = ctx.getState().intent;
|
|
75
|
+
const payload = intent?.action?.payload;
|
|
76
|
+
if (!payload)
|
|
77
|
+
return { kind: "none" };
|
|
78
|
+
if (payload.repoReset === true)
|
|
79
|
+
return { kind: "reset" };
|
|
80
|
+
const alias = payload.repoSync;
|
|
81
|
+
if (typeof alias === "string" && alias.trim())
|
|
82
|
+
return { kind: "sync", alias: alias.trim() };
|
|
83
|
+
return { kind: "none" };
|
|
84
|
+
}
|
|
85
|
+
function readRepoGitStatus(projectRoot, checkoutRoot, pinnedCommit, runCapture, existsSync, joinPath) {
|
|
86
|
+
const unavailable = { available: false, clean: false, dirtyCount: 0, head: "", branch: "", ahead: 0, behind: 0 };
|
|
87
|
+
if (!checkoutRoot || !existsSync(joinPath(checkoutRoot, ".git")))
|
|
88
|
+
return unavailable;
|
|
89
|
+
const porcelain = runCapture(["git", "-C", checkoutRoot, "status", "--porcelain"], projectRoot);
|
|
90
|
+
if (porcelain.exitCode !== 0)
|
|
91
|
+
return unavailable;
|
|
92
|
+
const dirtyLines = porcelain.stdout.split(/\r?\n/).filter((row) => row.trim().length > 0);
|
|
93
|
+
const head = runCapture(["git", "-C", checkoutRoot, "rev-parse", "--short", "HEAD"], projectRoot).stdout.trim();
|
|
94
|
+
const branchRaw = runCapture(["git", "-C", checkoutRoot, "rev-parse", "--abbrev-ref", "HEAD"], projectRoot).stdout.trim();
|
|
95
|
+
let ahead = 0;
|
|
96
|
+
let behind = 0;
|
|
97
|
+
if (pinnedCommit) {
|
|
98
|
+
const counts = runCapture(["git", "-C", checkoutRoot, "rev-list", "--left-right", "--count", `${pinnedCommit}...HEAD`], projectRoot);
|
|
99
|
+
if (counts.exitCode === 0) {
|
|
100
|
+
const [behindStr = "0", aheadStr = "0"] = counts.stdout.trim().split(/\s+/);
|
|
101
|
+
behind = Number.parseInt(behindStr, 10) || 0;
|
|
102
|
+
ahead = Number.parseInt(aheadStr, 10) || 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
available: true,
|
|
107
|
+
clean: dirtyLines.length === 0,
|
|
108
|
+
dirtyCount: dirtyLines.length,
|
|
109
|
+
head,
|
|
110
|
+
branch: branchRaw && branchRaw !== "HEAD" ? branchRaw : "(detached)",
|
|
111
|
+
ahead,
|
|
112
|
+
behind
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async function refreshRepo(ctx) {
|
|
116
|
+
const request = repoActionRequest(ctx);
|
|
117
|
+
const label = request.kind === "sync" ? `Syncing ${request.alias}` : request.kind === "reset" ? "Resetting repo baseline" : "Loading repo state";
|
|
118
|
+
emitStarted(ctx, label);
|
|
119
|
+
try {
|
|
120
|
+
const projectRoot = projectRootOf(ctx);
|
|
121
|
+
const [
|
|
122
|
+
{ repoBaseline, resetBaseline },
|
|
123
|
+
{ currentTaskId },
|
|
124
|
+
{ listManagedRepoEntries, resolveManagedRepoIdByAlias },
|
|
125
|
+
{ syncManagedRepo, resolveManagedRepoLayoutByAlias },
|
|
126
|
+
{ runCapture },
|
|
127
|
+
{ existsSync },
|
|
128
|
+
pathMod
|
|
129
|
+
] = await Promise.all([
|
|
130
|
+
import("@rig/runtime/control-plane/native/repo-ops"),
|
|
131
|
+
import("@rig/runtime/control-plane/native/task-state"),
|
|
132
|
+
import("@rig/runtime/control-plane/repos/registry"),
|
|
133
|
+
import("@rig/runtime/control-plane/repos"),
|
|
134
|
+
import("@rig/runtime/control-plane/native/utils"),
|
|
135
|
+
import("fs"),
|
|
136
|
+
import("path")
|
|
137
|
+
]);
|
|
138
|
+
const joinPath = (...parts) => pathMod.resolve(...parts);
|
|
139
|
+
if (request.kind === "sync") {
|
|
140
|
+
const repoId = resolveManagedRepoIdByAlias(request.alias);
|
|
141
|
+
if (!repoId)
|
|
142
|
+
throw new Error(`No managed repo registered for alias ${request.alias}.`);
|
|
143
|
+
emitProgress(ctx, label, `re-syncing ${request.alias} from its remote default branch`);
|
|
144
|
+
await captureConsole(() => syncManagedRepo(projectRoot, repoId));
|
|
145
|
+
} else if (request.kind === "reset") {
|
|
146
|
+
emitProgress(ctx, label, "resetting baseline to origin/main and refreshing pins");
|
|
147
|
+
await captureConsole(() => resetBaseline(projectRoot, false));
|
|
148
|
+
}
|
|
149
|
+
emitProgress(ctx, label, "reading baseline pins and managed repos");
|
|
150
|
+
const { result } = await captureConsole(() => ({
|
|
151
|
+
pins: repoBaseline(projectRoot, false),
|
|
152
|
+
taskId: currentTaskId(projectRoot),
|
|
153
|
+
managed: listManagedRepoEntries()
|
|
154
|
+
}));
|
|
155
|
+
const baselinePins = Object.entries(result.pins).map(([alias, commit]) => ({ alias, commit: String(commit) }));
|
|
156
|
+
const pinByAlias = new Map(baselinePins.map((pin) => [pin.alias, pin.commit]));
|
|
157
|
+
const managedRepos = result.managed.map((entry) => {
|
|
158
|
+
const layout = resolveManagedRepoLayoutByAlias(projectRoot, entry.alias);
|
|
159
|
+
const git = layout ? readRepoGitStatus(projectRoot, layout.checkoutRoot, pinByAlias.get(entry.alias), runCapture, existsSync, joinPath) : undefined;
|
|
160
|
+
return {
|
|
161
|
+
id: entry.id,
|
|
162
|
+
alias: entry.alias,
|
|
163
|
+
defaultBranch: entry.defaultBranch,
|
|
164
|
+
defaultRemoteUrl: entry.defaultRemoteUrl,
|
|
165
|
+
...git ? { git } : {}
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
const snapshot = {
|
|
169
|
+
activeTaskId: result.taskId.trim() ? result.taskId.trim() : null,
|
|
170
|
+
baselinePins,
|
|
171
|
+
managedRepos,
|
|
172
|
+
flatLayout: managedRepos.length === 0,
|
|
173
|
+
refreshedAt: Date.now()
|
|
174
|
+
};
|
|
175
|
+
patchData(ctx, { repo: snapshot, lastRefreshError: undefined });
|
|
176
|
+
patchFooter(ctx, { message: snapshot.flatLayout ? "flat layout \xB7 no managed repos" : `${managedRepos.length} managed repos \xB7 ${baselinePins.length} pins` });
|
|
177
|
+
emitCompleted(ctx, label, { managed: managedRepos.length, pins: baselinePins.length, task: snapshot.activeTaskId });
|
|
178
|
+
return snapshot;
|
|
179
|
+
} catch (error) {
|
|
180
|
+
emitFailed(ctx, label, error);
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
export {
|
|
185
|
+
refreshRepo
|
|
186
|
+
};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type { AppAdapter } from "../types";
|
|
2
1
|
import { type AppAdapterContext } from "./common";
|
|
3
|
-
export declare function createRunDetailAdapter(): AppAdapter;
|
|
4
2
|
export type AppRunSnapshot = {
|
|
5
3
|
readonly runId: string;
|
|
6
4
|
readonly status: string;
|
|
@@ -9,10 +7,19 @@ export type AppRunSnapshot = {
|
|
|
9
7
|
readonly logs: Record<string, unknown>[];
|
|
10
8
|
readonly timeline: Record<string, unknown>[];
|
|
11
9
|
readonly timelineCursor: string | null;
|
|
10
|
+
/** Server-reported totals (when available) so the scene can show "N of M" and
|
|
11
|
+
* decide whether a "load more" affordance is warranted (#2). */
|
|
12
|
+
readonly logsTotal?: number;
|
|
13
|
+
readonly timelineTotal?: number;
|
|
12
14
|
};
|
|
13
15
|
export declare function loadRunDetail(ctx: AppAdapterContext, runId: string, options?: {
|
|
14
16
|
readonly timelineCursor?: string | null;
|
|
15
17
|
}): Promise<AppRunSnapshot>;
|
|
18
|
+
/** "Load more" for the timeline (#2): fetch the NEXT page using the stored
|
|
19
|
+
* `timelineCursor` and APPEND it to the existing snapshot, advancing the cursor.
|
|
20
|
+
* The previously-loaded rows stay; nothing is re-fetched. No cursor ⇒ nothing
|
|
21
|
+
* more to load (the scene only offers the affordance while a cursor exists). */
|
|
22
|
+
export declare function loadMoreRunTimeline(ctx: AppAdapterContext, runId: string): Promise<AppRunSnapshot | null>;
|
|
16
23
|
export declare function steerRunFromApp(ctx: AppAdapterContext, input: {
|
|
17
24
|
readonly runId: string;
|
|
18
25
|
readonly message: string;
|
|
@@ -767,15 +767,6 @@ var init__server_client = __esm(() => {
|
|
|
767
767
|
});
|
|
768
768
|
|
|
769
769
|
// packages/cli/src/app-opentui/adapters/common.ts
|
|
770
|
-
function adapterContextFromRuntime(runtime, renderer) {
|
|
771
|
-
return {
|
|
772
|
-
projectRoot: runtime.getState().projectRoot,
|
|
773
|
-
renderer,
|
|
774
|
-
ensureRuntime: () => runtime.getRunnerContext(),
|
|
775
|
-
emit: (event) => runtime.emit(event),
|
|
776
|
-
getState: () => runtime.getState()
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
770
|
function projectRootOf(ctx) {
|
|
780
771
|
const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
|
|
781
772
|
if (typeof root === "string" && root.trim())
|
|
@@ -838,33 +829,17 @@ function stringField(record, keys, fallback = "") {
|
|
|
838
829
|
}
|
|
839
830
|
return fallback;
|
|
840
831
|
}
|
|
841
|
-
function payloadString(intent, key) {
|
|
842
|
-
const value = intent.action.payload?.[key];
|
|
843
|
-
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
844
|
-
}
|
|
845
832
|
|
|
846
833
|
// packages/cli/src/app-opentui/adapters/run-detail.ts
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
const message = payloadString(intent, "message") ?? intent.raw;
|
|
857
|
-
if (runId && message)
|
|
858
|
-
await steerRunFromApp(ctx, { runId, message });
|
|
859
|
-
return true;
|
|
860
|
-
}
|
|
861
|
-
if (runId) {
|
|
862
|
-
await loadRunDetail(ctx, runId);
|
|
863
|
-
return true;
|
|
864
|
-
}
|
|
865
|
-
return false;
|
|
866
|
-
}
|
|
867
|
-
};
|
|
834
|
+
var LOG_PAGE = 100;
|
|
835
|
+
var TIMELINE_PAGE = 200;
|
|
836
|
+
function payloadTotal(payload) {
|
|
837
|
+
for (const key of ["total", "totalCount", "count"]) {
|
|
838
|
+
const value = payload[key];
|
|
839
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
840
|
+
return value;
|
|
841
|
+
}
|
|
842
|
+
return;
|
|
868
843
|
}
|
|
869
844
|
function unwrapRun(payload) {
|
|
870
845
|
return payload.run && typeof payload.run === "object" && !Array.isArray(payload.run) ? payload.run : payload;
|
|
@@ -873,8 +848,24 @@ function nextCursor(payload) {
|
|
|
873
848
|
const cursor = payload.nextCursor ?? payload.cursor;
|
|
874
849
|
return typeof cursor === "string" && cursor.trim() ? cursor : null;
|
|
875
850
|
}
|
|
851
|
+
function loadMoreRequest(ctx, runId) {
|
|
852
|
+
const value = ctx.getState().data?.runDetailLoadMore;
|
|
853
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
854
|
+
return null;
|
|
855
|
+
const record = value;
|
|
856
|
+
if (record.runId !== runId || typeof record.cursor !== "string" || !record.cursor.trim())
|
|
857
|
+
return null;
|
|
858
|
+
return { runId, cursor: record.cursor };
|
|
859
|
+
}
|
|
876
860
|
async function loadRunDetail(ctx, runId, options = {}) {
|
|
877
861
|
const cleanRunId = runId.trim();
|
|
862
|
+
const more = loadMoreRequest(ctx, cleanRunId);
|
|
863
|
+
if (more) {
|
|
864
|
+
patchData(ctx, { runDetailLoadMore: undefined });
|
|
865
|
+
const appended = await loadMoreRunTimeline(ctx, cleanRunId).catch(() => null);
|
|
866
|
+
if (appended)
|
|
867
|
+
return appended;
|
|
868
|
+
}
|
|
878
869
|
const label = `Loading run ${cleanRunId.slice(0, 8)}`;
|
|
879
870
|
if (!cleanRunId) {
|
|
880
871
|
const error = new Error("Run detail requires a run id.");
|
|
@@ -888,10 +879,12 @@ async function loadRunDetail(ctx, runId, options = {}) {
|
|
|
888
879
|
emitProgress(ctx, label, "loading run, logs, and timeline");
|
|
889
880
|
const [runPayload, logsPayload, timelinePayload] = await Promise.all([
|
|
890
881
|
getRunDetailsViaServer2(context, cleanRunId),
|
|
891
|
-
getRunLogsViaServer2(context, cleanRunId, { limit:
|
|
892
|
-
getRunTimelineViaServer2(context, cleanRunId, { limit:
|
|
882
|
+
getRunLogsViaServer2(context, cleanRunId, { limit: LOG_PAGE }),
|
|
883
|
+
getRunTimelineViaServer2(context, cleanRunId, { limit: TIMELINE_PAGE, ...options.timelineCursor ? { cursor: options.timelineCursor } : {} })
|
|
893
884
|
]);
|
|
894
885
|
const run = unwrapRun(runPayload);
|
|
886
|
+
const logsTotal = payloadTotal(logsPayload);
|
|
887
|
+
const timelineTotal = payloadTotal(timelinePayload);
|
|
895
888
|
const snapshot = {
|
|
896
889
|
runId: cleanRunId,
|
|
897
890
|
status: stringField(run, ["status", "state"], "unknown"),
|
|
@@ -899,9 +892,12 @@ async function loadRunDetail(ctx, runId, options = {}) {
|
|
|
899
892
|
run,
|
|
900
893
|
logs: arrayFromPayload(logsPayload),
|
|
901
894
|
timeline: arrayFromPayload(timelinePayload),
|
|
902
|
-
timelineCursor: nextCursor(timelinePayload)
|
|
895
|
+
timelineCursor: nextCursor(timelinePayload),
|
|
896
|
+
...logsTotal !== undefined ? { logsTotal } : {},
|
|
897
|
+
...timelineTotal !== undefined ? { timelineTotal } : {}
|
|
903
898
|
};
|
|
904
|
-
|
|
899
|
+
const clearSettledSteer = settledSteerForRun(ctx, cleanRunId) ? { pendingRunMessage: undefined } : {};
|
|
900
|
+
patchData(ctx, { selectedRunId: cleanRunId, runDetail: snapshot, lastRefreshError: undefined, ...clearSettledSteer });
|
|
905
901
|
patchFooter(ctx, { run: `${cleanRunId.slice(0, 8)} ${snapshot.status}` });
|
|
906
902
|
emitCompleted(ctx, label, { runId: cleanRunId, status: snapshot.status, logs: snapshot.logs.length, timeline: snapshot.timeline.length });
|
|
907
903
|
return snapshot;
|
|
@@ -910,6 +906,56 @@ async function loadRunDetail(ctx, runId, options = {}) {
|
|
|
910
906
|
throw error;
|
|
911
907
|
}
|
|
912
908
|
}
|
|
909
|
+
function settledSteerForRun(ctx, runId) {
|
|
910
|
+
const value = ctx.getState().data?.pendingRunMessage;
|
|
911
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
912
|
+
return false;
|
|
913
|
+
const record = value;
|
|
914
|
+
if (record.runId !== runId)
|
|
915
|
+
return false;
|
|
916
|
+
return record.status === "sent" || record.status === "delivered" || record.status === "failed";
|
|
917
|
+
}
|
|
918
|
+
function currentSnapshot(ctx) {
|
|
919
|
+
const value = ctx.getState().data?.runDetail;
|
|
920
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
921
|
+
}
|
|
922
|
+
async function loadMoreRunTimeline(ctx, runId) {
|
|
923
|
+
const cleanRunId = runId.trim();
|
|
924
|
+
const snapshot = currentSnapshot(ctx);
|
|
925
|
+
if (!snapshot || snapshot.runId !== cleanRunId || !snapshot.timelineCursor)
|
|
926
|
+
return snapshot;
|
|
927
|
+
const label = `More timeline ${cleanRunId.slice(0, 8)}`;
|
|
928
|
+
emitStarted(ctx, label);
|
|
929
|
+
try {
|
|
930
|
+
const { getRunTimelineViaServer: getRunTimelineViaServer2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
|
|
931
|
+
const context = { projectRoot: projectRootOf(ctx) };
|
|
932
|
+
const page = await getRunTimelineViaServer2(context, cleanRunId, { limit: TIMELINE_PAGE, cursor: snapshot.timelineCursor });
|
|
933
|
+
const more = arrayFromPayload(page);
|
|
934
|
+
const timelineTotal = payloadTotal(page) ?? snapshot.timelineTotal;
|
|
935
|
+
const next = {
|
|
936
|
+
...snapshot,
|
|
937
|
+
timeline: [...snapshot.timeline, ...more],
|
|
938
|
+
timelineCursor: nextCursor(page),
|
|
939
|
+
...timelineTotal !== undefined ? { timelineTotal } : {}
|
|
940
|
+
};
|
|
941
|
+
patchData(ctx, { runDetail: next, lastRefreshError: undefined });
|
|
942
|
+
emitCompleted(ctx, label, { runId: cleanRunId, added: more.length, timeline: next.timeline.length });
|
|
943
|
+
return next;
|
|
944
|
+
} catch (error) {
|
|
945
|
+
emitFailed(ctx, label, error, { runId: cleanRunId });
|
|
946
|
+
throw error;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
function steerResultSummary(result) {
|
|
950
|
+
for (const key of ["status", "state", "message", "detail"]) {
|
|
951
|
+
const value = result[key];
|
|
952
|
+
if (typeof value === "string" && value.trim())
|
|
953
|
+
return value.trim();
|
|
954
|
+
}
|
|
955
|
+
if (result.ok === true || result.queued === true || result.delivered === true)
|
|
956
|
+
return "accepted by run";
|
|
957
|
+
return "delivered";
|
|
958
|
+
}
|
|
913
959
|
async function steerRunFromApp(ctx, input) {
|
|
914
960
|
const label = `Steering ${input.runId.slice(0, 8)}`;
|
|
915
961
|
const message = input.message.trim();
|
|
@@ -918,17 +964,21 @@ async function steerRunFromApp(ctx, input) {
|
|
|
918
964
|
emitFailed(ctx, label, error, { runId: input.runId });
|
|
919
965
|
throw error;
|
|
920
966
|
}
|
|
921
|
-
|
|
922
|
-
|
|
967
|
+
const pending = { runId: input.runId, text: message, status: "queued" };
|
|
968
|
+
emitStarted(ctx, label, { pendingRunMessage: pending });
|
|
969
|
+
patchData(ctx, { pendingRunMessage: pending });
|
|
923
970
|
try {
|
|
924
971
|
const { sendRunPiPromptViaServer: sendRunPiPromptViaServer2, steerRunViaServer: steerRunViaServer2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
|
|
925
972
|
const context = { projectRoot: projectRootOf(ctx) };
|
|
926
973
|
const result = await sendRunPiPromptViaServer2(context, input.runId, message, "steer").catch(() => steerRunViaServer2(context, input.runId, message));
|
|
974
|
+
const summary = steerResultSummary(result);
|
|
975
|
+
patchData(ctx, { pendingRunMessage: { runId: input.runId, text: message, status: "sent", result: summary } });
|
|
927
976
|
emitCompleted(ctx, label, { runId: input.runId, result });
|
|
928
|
-
patchData(ctx, { pendingRunMessage: null });
|
|
929
977
|
return result;
|
|
930
978
|
} catch (error) {
|
|
931
|
-
|
|
979
|
+
const message2 = normalizeAppError(error).message;
|
|
980
|
+
emitFailed(ctx, label, error, { runId: input.runId });
|
|
981
|
+
patchData(ctx, { pendingRunMessage: { runId: input.runId, text: message, status: "failed", result: message2 } });
|
|
932
982
|
throw error;
|
|
933
983
|
}
|
|
934
984
|
}
|
|
@@ -942,7 +992,10 @@ async function stopRunFromDetail(ctx, runId) {
|
|
|
942
992
|
const { stopRunViaServer: stopRunViaServer2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
|
|
943
993
|
const result = await stopRunViaServer2({ projectRoot: projectRootOf(ctx) }, cleanRunId);
|
|
944
994
|
emitCompleted(ctx, label, { runId: cleanRunId, result });
|
|
945
|
-
await loadRunDetail(ctx, cleanRunId).catch(() =>
|
|
995
|
+
await loadRunDetail(ctx, cleanRunId).catch((error) => {
|
|
996
|
+
patchData(ctx, { lastRefreshError: normalizeAppError(error).message });
|
|
997
|
+
return null;
|
|
998
|
+
});
|
|
946
999
|
return result;
|
|
947
1000
|
} catch (error) {
|
|
948
1001
|
emitFailed(ctx, label, error, { runId: cleanRunId, revert: { status: "unknown" } });
|
|
@@ -953,5 +1006,5 @@ export {
|
|
|
953
1006
|
stopRunFromDetail,
|
|
954
1007
|
steerRunFromApp,
|
|
955
1008
|
loadRunDetail,
|
|
956
|
-
|
|
1009
|
+
loadMoreRunTimeline
|
|
957
1010
|
};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type { AppAdapter } from "../types";
|
|
2
1
|
import { type AppAdapterContext } from "./common";
|
|
3
|
-
export declare function createServerAdapter(): AppAdapter;
|
|
4
2
|
export type AppServerState = {
|
|
5
3
|
readonly label: string;
|
|
6
4
|
readonly baseUrl?: string;
|
|
@@ -11,4 +9,14 @@ export type AppServerState = {
|
|
|
11
9
|
readonly auth?: Record<string, unknown>;
|
|
12
10
|
readonly error?: string;
|
|
13
11
|
};
|
|
12
|
+
/** Start the local Rig server DETACHED and return to the server scene (bug #3).
|
|
13
|
+
*
|
|
14
|
+
* `rig server start` is a blocking long-running process; running it through the
|
|
15
|
+
* foreground command PTY traps the operator (kitty-mode even swallows ctrl-c).
|
|
16
|
+
* Instead we: (a) switch this repo's connection to local, (b) spawn the server
|
|
17
|
+
* detached + wait for ready via ensureLocalRigServerConnection (it writes the
|
|
18
|
+
* published server state and unrefs the child), then (c) re-probe. The operator
|
|
19
|
+
* is never blocked: this returns once the detached server answers.
|
|
20
|
+
*/
|
|
21
|
+
export declare function startLocalServerFromApp(ctx: AppAdapterContext): Promise<AppServerState>;
|
|
14
22
|
export declare function refreshServerStatus(ctx: AppAdapterContext): Promise<AppServerState>;
|
|
@@ -14,6 +14,7 @@ var __export = (target, all) => {
|
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
16
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
|
+
var __require = import.meta.require;
|
|
17
18
|
|
|
18
19
|
// packages/cli/src/runner.ts
|
|
19
20
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
@@ -34,6 +35,19 @@ var init_runner = __esm(() => {
|
|
|
34
35
|
});
|
|
35
36
|
|
|
36
37
|
// packages/cli/src/commands/_connection-state.ts
|
|
38
|
+
var exports__connection_state = {};
|
|
39
|
+
__export(exports__connection_state, {
|
|
40
|
+
writeRepoServerProjectRoot: () => writeRepoServerProjectRoot,
|
|
41
|
+
writeRepoConnection: () => writeRepoConnection,
|
|
42
|
+
writeGlobalConnections: () => writeGlobalConnections,
|
|
43
|
+
upsertGlobalConnection: () => upsertGlobalConnection,
|
|
44
|
+
resolveSelectedConnection: () => resolveSelectedConnection,
|
|
45
|
+
resolveRepoConnectionPath: () => resolveRepoConnectionPath,
|
|
46
|
+
resolveGlobalConnectionsPath: () => resolveGlobalConnectionsPath,
|
|
47
|
+
readRepoConnection: () => readRepoConnection,
|
|
48
|
+
readGlobalConnections: () => readGlobalConnections,
|
|
49
|
+
isRemoteConnectionSelected: () => isRemoteConnectionSelected
|
|
50
|
+
});
|
|
37
51
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
38
52
|
import { homedir } from "os";
|
|
39
53
|
import { dirname, resolve } from "path";
|
|
@@ -92,6 +106,18 @@ function readGlobalConnections(options = {}) {
|
|
|
92
106
|
}
|
|
93
107
|
return { connections };
|
|
94
108
|
}
|
|
109
|
+
function writeGlobalConnections(state, options = {}) {
|
|
110
|
+
writeJsonFile(resolveGlobalConnectionsPath(options.env ?? process.env), state);
|
|
111
|
+
}
|
|
112
|
+
function upsertGlobalConnection(alias, connection, options = {}) {
|
|
113
|
+
const cleanAlias = alias.trim();
|
|
114
|
+
if (!cleanAlias)
|
|
115
|
+
throw new CliError("Connection alias is required.", 1, { hint: "Save a server with `rig server add <alias> <url>`." });
|
|
116
|
+
const state = readGlobalConnections(options);
|
|
117
|
+
state.connections[cleanAlias] = connection;
|
|
118
|
+
writeGlobalConnections(state, options);
|
|
119
|
+
return state;
|
|
120
|
+
}
|
|
95
121
|
function readRepoConnection(projectRoot) {
|
|
96
122
|
const payload = readJsonFile(resolveRepoConnectionPath(projectRoot));
|
|
97
123
|
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
@@ -129,6 +155,9 @@ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
|
|
|
129
155
|
return;
|
|
130
156
|
writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
|
|
131
157
|
}
|
|
158
|
+
function isRemoteConnectionSelected(projectRoot) {
|
|
159
|
+
return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
|
|
160
|
+
}
|
|
132
161
|
var init__connection_state = __esm(() => {
|
|
133
162
|
init_runner();
|
|
134
163
|
});
|
|
@@ -767,15 +796,6 @@ var init__server_client = __esm(() => {
|
|
|
767
796
|
});
|
|
768
797
|
|
|
769
798
|
// packages/cli/src/app-opentui/adapters/common.ts
|
|
770
|
-
function adapterContextFromRuntime(runtime, renderer) {
|
|
771
|
-
return {
|
|
772
|
-
projectRoot: runtime.getState().projectRoot,
|
|
773
|
-
renderer,
|
|
774
|
-
ensureRuntime: () => runtime.getRunnerContext(),
|
|
775
|
-
emit: (event) => runtime.emit(event),
|
|
776
|
-
getState: () => runtime.getState()
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
799
|
function projectRootOf(ctx) {
|
|
780
800
|
const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
|
|
781
801
|
if (typeof root === "string" && root.trim())
|
|
@@ -799,20 +819,7 @@ function patchFooter(ctx, footer) {
|
|
|
799
819
|
}
|
|
800
820
|
|
|
801
821
|
// packages/cli/src/app-opentui/adapters/server.ts
|
|
802
|
-
|
|
803
|
-
return {
|
|
804
|
-
id: "server",
|
|
805
|
-
async handleIntent(runtime, intent) {
|
|
806
|
-
if (intent.scene !== "server")
|
|
807
|
-
return false;
|
|
808
|
-
if (intent.action.kind === "refresh" || intent.action.kind === "navigate") {
|
|
809
|
-
await refreshServerStatus(adapterContextFromRuntime(runtime));
|
|
810
|
-
return true;
|
|
811
|
-
}
|
|
812
|
-
return false;
|
|
813
|
-
}
|
|
814
|
-
};
|
|
815
|
-
}
|
|
822
|
+
var SERVER_PROBE_TIMEOUT_MS = Number(process.env.RIG_SERVER_PROBE_TIMEOUT_MS) || 5000;
|
|
816
823
|
function withTimeout(promise, ms, label) {
|
|
817
824
|
return new Promise((resolve3, reject) => {
|
|
818
825
|
const timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
|
|
@@ -825,7 +832,69 @@ function withTimeout(promise, ms, label) {
|
|
|
825
832
|
});
|
|
826
833
|
});
|
|
827
834
|
}
|
|
835
|
+
async function withRetry(label, attempt, opts) {
|
|
836
|
+
const retries = opts?.retries ?? 1;
|
|
837
|
+
const baseDelayMs = opts?.baseDelayMs ?? 250;
|
|
838
|
+
let lastError;
|
|
839
|
+
for (let n = 0;n <= retries; n++) {
|
|
840
|
+
try {
|
|
841
|
+
return await attempt();
|
|
842
|
+
} catch (error) {
|
|
843
|
+
lastError = error;
|
|
844
|
+
if (n < retries) {
|
|
845
|
+
const delay = baseDelayMs * 2 ** n;
|
|
846
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
throw lastError instanceof Error ? lastError : new Error(`${label} failed: ${String(lastError)}`);
|
|
851
|
+
}
|
|
852
|
+
function startLocalRequested(ctx) {
|
|
853
|
+
const intent = ctx.getState().data?.lastIntent;
|
|
854
|
+
if (!intent || typeof intent !== "object" || Array.isArray(intent))
|
|
855
|
+
return false;
|
|
856
|
+
const action = intent.action;
|
|
857
|
+
return action?.payload?.startLocal === true;
|
|
858
|
+
}
|
|
859
|
+
async function startLocalServerFromApp(ctx) {
|
|
860
|
+
const label = "Starting local server";
|
|
861
|
+
emitStarted(ctx, label);
|
|
862
|
+
patchData(ctx, {
|
|
863
|
+
lastIntent: undefined,
|
|
864
|
+
server: { label: "starting local server", reachable: false, error: "spawning local rig-server (detached)\u2026" }
|
|
865
|
+
});
|
|
866
|
+
try {
|
|
867
|
+
const projectRoot = projectRootOf(ctx);
|
|
868
|
+
emitProgress(ctx, label, "selecting local server for this repo");
|
|
869
|
+
const { writeRepoConnection: writeRepoConnection2, readRepoConnection: readRepoConnection2 } = await Promise.resolve().then(() => (init__connection_state(), exports__connection_state));
|
|
870
|
+
const previous = readRepoConnection2(projectRoot);
|
|
871
|
+
writeRepoConnection2(projectRoot, {
|
|
872
|
+
selected: "local",
|
|
873
|
+
...previous?.project ? { project: previous.project } : {},
|
|
874
|
+
linkedAt: new Date().toISOString()
|
|
875
|
+
});
|
|
876
|
+
emitProgress(ctx, label, "spawning local rig-server (detached) and waiting for ready");
|
|
877
|
+
const { ensureLocalRigServerConnection: ensureLocalRigServerConnection2 } = await import("@rig/runtime/local-server");
|
|
878
|
+
const connection = await ensureLocalRigServerConnection2(projectRoot);
|
|
879
|
+
emitProgress(ctx, label, "local server ready", { baseUrl: connection.baseUrl });
|
|
880
|
+
emitCompleted(ctx, label, { baseUrl: connection.baseUrl });
|
|
881
|
+
return await refreshServerStatus(ctx);
|
|
882
|
+
} catch (error) {
|
|
883
|
+
const state = {
|
|
884
|
+
label: "local server failed to start",
|
|
885
|
+
reachable: false,
|
|
886
|
+
error: error instanceof Error ? error.message : String(error)
|
|
887
|
+
};
|
|
888
|
+
patchData(ctx, { server: state, lastRefreshError: state.error });
|
|
889
|
+
patchFooter(ctx, { server: "unavailable" });
|
|
890
|
+
emitCompleted(ctx, label, { server: state.label, reachable: false, error: state.error });
|
|
891
|
+
return state;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
828
894
|
async function refreshServerStatus(ctx) {
|
|
895
|
+
if (startLocalRequested(ctx)) {
|
|
896
|
+
return startLocalServerFromApp(ctx);
|
|
897
|
+
}
|
|
829
898
|
const label = "Checking server";
|
|
830
899
|
emitStarted(ctx, label);
|
|
831
900
|
patchData(ctx, { server: { label: "checking selected server", reachable: false, error: "checking selected server\u2026" } });
|
|
@@ -840,8 +909,8 @@ async function refreshServerStatus(ctx) {
|
|
|
840
909
|
]);
|
|
841
910
|
emitProgress(ctx, label, "requesting server status", { baseUrl: server.baseUrl, kind: server.connectionKind });
|
|
842
911
|
const [status, auth] = await Promise.all([
|
|
843
|
-
withTimeout(requestServerJson2({ projectRoot }, "/api/server/status"),
|
|
844
|
-
withTimeout(requestServerJson2({ projectRoot }, "/api/github/auth/status"),
|
|
912
|
+
withRetry("server status", () => withTimeout(requestServerJson2({ projectRoot }, "/api/server/status"), SERVER_PROBE_TIMEOUT_MS, "server status")).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) })),
|
|
913
|
+
withRetry("github auth status", () => withTimeout(requestServerJson2({ projectRoot }, "/api/github/auth/status"), SERVER_PROBE_TIMEOUT_MS, "github auth status")).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }))
|
|
845
914
|
]);
|
|
846
915
|
const state = {
|
|
847
916
|
label: connectionLabel,
|
|
@@ -870,6 +939,6 @@ async function refreshServerStatus(ctx) {
|
|
|
870
939
|
}
|
|
871
940
|
}
|
|
872
941
|
export {
|
|
873
|
-
|
|
874
|
-
|
|
942
|
+
startLocalServerFromApp,
|
|
943
|
+
refreshServerStatus
|
|
875
944
|
};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type { AppAdapter } from "../types";
|
|
2
1
|
import { type AppAdapterContext } from "./common";
|
|
3
|
-
export declare function createTasksAdapter(): AppAdapter;
|
|
4
2
|
export type AppTaskSort = "priority" | "recency" | "status" | "id";
|
|
5
3
|
export type AppTaskFilters = {
|
|
6
4
|
readonly preset?: "open" | "ready" | "blocked" | "closed" | "mine" | "all" | "custom";
|