@h-rig/cli 0.0.6-alpha.82 → 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/build-rig-binaries.js +40 -8
- package/dist/bin/rig.js +23402 -14577
- package/dist/src/app/board.js +217 -41
- package/dist/src/app-opentui/adapters/command.d.ts +2 -0
- package/dist/src/app-opentui/adapters/command.js +329 -0
- package/dist/src/app-opentui/adapters/common.js +2 -2
- package/dist/src/app-opentui/adapters/doctor.d.ts +0 -2
- package/dist/src/app-opentui/adapters/doctor.js +64 -39
- 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 +90 -60
- package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
- package/dist/src/app-opentui/adapters/inbox.js +137 -78
- package/dist/src/app-opentui/adapters/init.d.ts +0 -2
- package/dist/src/app-opentui/adapters/init.js +85 -47
- 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 +442 -125
- 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 +180 -63
- package/dist/src/app-opentui/adapters/server.d.ts +10 -2
- package/dist/src/app-opentui/adapters/server.js +191 -45
- package/dist/src/app-opentui/adapters/tasks.d.ts +11 -2
- package/dist/src/app-opentui/adapters/tasks.js +1123 -143
- 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.d.ts +1 -6
- package/dist/src/app-opentui/bootstrap.js +25252 -16474
- 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/command-pty-host.d.ts +62 -0
- package/dist/src/app-opentui/command-pty-host.js +248 -0
- package/dist/src/app-opentui/drone.js +8 -6
- package/dist/src/app-opentui/events.js +1 -1
- 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/focus-manager.d.ts +14 -0
- package/dist/src/app-opentui/focus-manager.js +24 -0
- package/dist/src/app-opentui/index.js +5431 -2797
- package/dist/src/app-opentui/intent.js +179 -50
- package/dist/src/app-opentui/keymap.d.ts +21 -0
- package/dist/src/app-opentui/keymap.js +1748 -0
- package/dist/src/app-opentui/launch-routing.d.ts +16 -0
- package/dist/src/app-opentui/launch-routing.js +55 -0
- 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 +99 -17
- package/dist/src/app-opentui/pi-pty-host.d.ts +14 -0
- package/dist/src/app-opentui/pi-pty-host.js +30 -14
- 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 +20428 -4828
- package/dist/src/app-opentui/render/ascii-fleet.d.ts +15 -0
- package/dist/src/app-opentui/render/ascii-fleet.js +82 -0
- 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 +228 -46
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +469 -930
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +25 -10
- package/dist/src/app-opentui/render/image-visual-layer.js +448 -329
- 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/panel-layout.d.ts +38 -0
- package/dist/src/app-opentui/render/panel-layout.js +48 -0
- package/dist/src/app-opentui/render/panels.d.ts +2 -0
- package/dist/src/app-opentui/render/panels.js +78 -38
- package/dist/src/app-opentui/render/preloader.d.ts +10 -0
- package/dist/src/app-opentui/render/preloader.js +165 -0
- package/dist/src/app-opentui/render/scene.d.ts +53 -1
- package/dist/src/app-opentui/render/scene.js +195 -6
- package/dist/src/app-opentui/render/text.d.ts +7 -1
- package/dist/src/app-opentui/render/text.js +15 -8
- package/dist/src/app-opentui/render/type-bar.d.ts +2 -1
- package/dist/src/app-opentui/render/type-bar.js +113 -39
- package/dist/src/app-opentui/runtime-resources.d.ts +16 -0
- package/dist/src/app-opentui/runtime-resources.js +62 -0
- package/dist/src/app-opentui/runtime.d.ts +44 -1
- package/dist/src/app-opentui/runtime.js +5415 -2738
- package/dist/src/app-opentui/scenes/command.d.ts +3 -0
- package/dist/src/app-opentui/scenes/command.js +117 -0
- package/dist/src/app-opentui/scenes/doctor.d.ts +2 -1
- package/dist/src/app-opentui/scenes/doctor.js +221 -17
- package/dist/src/app-opentui/scenes/error.js +60 -20
- 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 +552 -43
- package/dist/src/app-opentui/scenes/handoff.js +342 -35
- package/dist/src/app-opentui/scenes/help.js +640 -56
- package/dist/src/app-opentui/scenes/inbox.d.ts +2 -1
- package/dist/src/app-opentui/scenes/inbox.js +329 -21
- package/dist/src/app-opentui/scenes/init.d.ts +2 -1
- package/dist/src/app-opentui/scenes/init.js +120 -34
- 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.d.ts +2 -1
- package/dist/src/app-opentui/scenes/main.js +264 -29
- 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.d.ts +2 -1
- package/dist/src/app-opentui/scenes/run-detail.js +362 -35
- package/dist/src/app-opentui/scenes/server.d.ts +2 -1
- package/dist/src/app-opentui/scenes/server.js +243 -26
- package/dist/src/app-opentui/scenes/tasks.js +518 -41
- 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 +129 -36
- 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/terminal-capabilities.d.ts +7 -0
- package/dist/src/app-opentui/terminal-capabilities.js +15 -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 +130 -5
- package/dist/src/commands/_authority-runs.d.ts +1 -1
- package/dist/src/commands/_authority-runs.js +2 -12
- package/dist/src/commands/_doctor-checks.js +62 -13
- package/dist/src/commands/_help-catalog.js +95 -15
- package/dist/src/commands/_operator-view.js +97 -15
- package/dist/src/commands/_pi-frontend.d.ts +2 -0
- package/dist/src/commands/_pi-frontend.js +97 -13
- package/dist/src/commands/_preflight.js +64 -14
- package/dist/src/commands/_server-client.js +82 -18
- package/dist/src/commands/_server-events.d.ts +26 -0
- package/dist/src/commands/_server-events.js +310 -0
- package/dist/src/commands/_snapshot-upload.js +62 -13
- package/dist/src/commands/agent.js +2 -12
- package/dist/src/commands/connect.js +7 -1
- package/dist/src/commands/doctor.js +62 -13
- package/dist/src/commands/github.js +144 -23
- package/dist/src/commands/inbox.js +62 -13
- package/dist/src/commands/init.js +82 -18
- package/dist/src/commands/inspect.js +62 -13
- package/dist/src/commands/run.js +100 -15
- package/dist/src/commands/server.js +71 -26
- package/dist/src/commands/setup.js +62 -13
- package/dist/src/commands/stats.js +157 -28
- package/dist/src/commands/task-run-driver.js +64 -25
- package/dist/src/commands/task.js +196 -43
- package/dist/src/commands.js +419 -123
- package/dist/src/index.js +426 -130
- package/package.json +11 -10
- package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +0 -2
- package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +0 -1484
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/cli/src/app-opentui/adapters/common.ts
|
|
3
|
+
function projectRootOf(ctx) {
|
|
4
|
+
const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
|
|
5
|
+
if (typeof root === "string" && root.trim())
|
|
6
|
+
return root;
|
|
7
|
+
throw new Error("App adapter requires a projectRoot.");
|
|
8
|
+
}
|
|
9
|
+
function normalizeAppError(error) {
|
|
10
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
11
|
+
const rawHint = error instanceof Error ? error.hint : undefined;
|
|
12
|
+
return {
|
|
13
|
+
message,
|
|
14
|
+
...typeof rawHint === "string" && rawHint.trim() ? { hint: rawHint.trim() } : {}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function emitStarted(ctx, label, optimistic) {
|
|
18
|
+
ctx.emit({ type: "action.started", label, ...optimistic ? { optimistic } : {} });
|
|
19
|
+
}
|
|
20
|
+
function emitCompleted(ctx, label, data) {
|
|
21
|
+
ctx.emit({ type: "action.completed", label, ...data ? { data } : {} });
|
|
22
|
+
}
|
|
23
|
+
function emitFailed(ctx, label, error, data) {
|
|
24
|
+
if (data)
|
|
25
|
+
patchData(ctx, data);
|
|
26
|
+
const normalized = normalizeAppError(error);
|
|
27
|
+
ctx.emit({
|
|
28
|
+
type: "action.failed",
|
|
29
|
+
label,
|
|
30
|
+
message: normalized.message,
|
|
31
|
+
...normalized.hint ? { hint: normalized.hint } : {},
|
|
32
|
+
cause: error
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function patchData(ctx, data) {
|
|
36
|
+
ctx.emit({ type: "data.patch", data });
|
|
37
|
+
}
|
|
38
|
+
function patchFooter(ctx, footer) {
|
|
39
|
+
ctx.emit({ type: "footer.patch", footer });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// packages/cli/src/app-opentui/command-pty-host.ts
|
|
43
|
+
import { basename } from "path";
|
|
44
|
+
import { fileURLToPath } from "url";
|
|
45
|
+
import { Terminal as XtermTerminal } from "@xterm/headless";
|
|
46
|
+
var MIN_COLS = 40;
|
|
47
|
+
var MIN_ROWS = 10;
|
|
48
|
+
var MAX_ROWS = 300;
|
|
49
|
+
var MAX_SNAPSHOT_LINES = 420;
|
|
50
|
+
var SNAPSHOT_DELAY_MS = 80;
|
|
51
|
+
var fallbackCliScriptPath = fileURLToPath(new URL("../../bin/rig.ts", import.meta.url));
|
|
52
|
+
var activeHost = null;
|
|
53
|
+
function clampCols(cols) {
|
|
54
|
+
return Math.max(MIN_COLS, Math.trunc(cols || 120));
|
|
55
|
+
}
|
|
56
|
+
function clampRows(rows) {
|
|
57
|
+
return Math.max(MIN_ROWS, Math.min(MAX_ROWS, Math.trunc(rows || 36)));
|
|
58
|
+
}
|
|
59
|
+
function childCommandPrefix() {
|
|
60
|
+
const execName = basename(process.execPath).toLowerCase();
|
|
61
|
+
const currentEntry = process.argv[1];
|
|
62
|
+
if (execName === "bun" || execName === "bun.exe") {
|
|
63
|
+
return currentEntry ? [process.execPath, currentEntry] : [process.execPath, fallbackCliScriptPath];
|
|
64
|
+
}
|
|
65
|
+
return [process.execPath];
|
|
66
|
+
}
|
|
67
|
+
function withEnv(base) {
|
|
68
|
+
const env = {};
|
|
69
|
+
for (const [key, value] of Object.entries(base ?? process.env)) {
|
|
70
|
+
if (key === "NO_COLOR")
|
|
71
|
+
continue;
|
|
72
|
+
if (typeof value === "string")
|
|
73
|
+
env[key] = value;
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
...env,
|
|
77
|
+
TERM: "xterm-256color",
|
|
78
|
+
COLORTERM: "truecolor",
|
|
79
|
+
FORCE_COLOR: env.FORCE_COLOR ?? "1",
|
|
80
|
+
RIG_PLAIN: "1",
|
|
81
|
+
RIG_OPENTUI_COMMAND_HOST: "1",
|
|
82
|
+
RIG_CLI_PLAIN_HELP: env.RIG_CLI_PLAIN_HELP ?? "1"
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function commandLabel(argv, fallback) {
|
|
86
|
+
const command = argv.join(" ").trim();
|
|
87
|
+
return fallback?.trim() || (command ? `rig ${command}` : "rig");
|
|
88
|
+
}
|
|
89
|
+
async function startCommandPtyHost(options) {
|
|
90
|
+
activeHost?.dispose("replace");
|
|
91
|
+
const host = new CommandPtyHost(options);
|
|
92
|
+
activeHost = host;
|
|
93
|
+
await host.start();
|
|
94
|
+
return host;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
class CommandPtyHost {
|
|
98
|
+
argv;
|
|
99
|
+
projectRoot;
|
|
100
|
+
label;
|
|
101
|
+
env;
|
|
102
|
+
onSnapshot;
|
|
103
|
+
onExit;
|
|
104
|
+
onError;
|
|
105
|
+
terminal;
|
|
106
|
+
decoder = new TextDecoder("utf-8");
|
|
107
|
+
proc = null;
|
|
108
|
+
pty = null;
|
|
109
|
+
status = "starting";
|
|
110
|
+
cols;
|
|
111
|
+
rows;
|
|
112
|
+
message = "starting command";
|
|
113
|
+
exitCode;
|
|
114
|
+
signal;
|
|
115
|
+
notifyTimer = null;
|
|
116
|
+
_disposed = false;
|
|
117
|
+
constructor(options) {
|
|
118
|
+
this.argv = [...options.argv];
|
|
119
|
+
this.projectRoot = options.projectRoot;
|
|
120
|
+
this.label = commandLabel(options.argv, options.label);
|
|
121
|
+
this.env = options.env;
|
|
122
|
+
this.cols = clampCols(options.cols);
|
|
123
|
+
this.rows = clampRows(options.rows);
|
|
124
|
+
this.onSnapshot = options.onSnapshot;
|
|
125
|
+
this.onExit = options.onExit;
|
|
126
|
+
this.onError = options.onError;
|
|
127
|
+
this.terminal = new XtermTerminal({ allowProposedApi: true, cols: this.cols, rows: this.rows, scrollback: 2000 });
|
|
128
|
+
}
|
|
129
|
+
get disposed() {
|
|
130
|
+
return this._disposed;
|
|
131
|
+
}
|
|
132
|
+
get snapshot() {
|
|
133
|
+
return this.createSnapshot();
|
|
134
|
+
}
|
|
135
|
+
async start() {
|
|
136
|
+
if (this._disposed)
|
|
137
|
+
throw new Error("Command PTY host is disposed.");
|
|
138
|
+
if (typeof Bun.Terminal !== "function") {
|
|
139
|
+
throw new Error("Bun native PTY is unavailable in this runtime. Command host requires Bun.Terminal.");
|
|
140
|
+
}
|
|
141
|
+
const spawnOptions = {
|
|
142
|
+
cwd: this.projectRoot,
|
|
143
|
+
env: withEnv(this.env),
|
|
144
|
+
terminal: {
|
|
145
|
+
cols: this.cols,
|
|
146
|
+
rows: this.rows,
|
|
147
|
+
name: "xterm-256color",
|
|
148
|
+
data: (_terminal, data) => this.handlePtyData(data)
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
const proc = Bun.spawn([...childCommandPrefix(), ...this.argv], spawnOptions);
|
|
152
|
+
if (!proc.terminal)
|
|
153
|
+
throw new Error("Bun did not attach a terminal to the command child process.");
|
|
154
|
+
this.proc = proc;
|
|
155
|
+
this.pty = proc.terminal;
|
|
156
|
+
this.status = "running";
|
|
157
|
+
this.message = "running";
|
|
158
|
+
this.emitSnapshotSoon(0);
|
|
159
|
+
proc.exited.then((exitCode) => {
|
|
160
|
+
if (this._disposed)
|
|
161
|
+
return;
|
|
162
|
+
this.status = exitCode === 0 ? "exited" : "failed";
|
|
163
|
+
this.exitCode = exitCode;
|
|
164
|
+
this.signal = null;
|
|
165
|
+
this.message = exitCode === 0 ? "completed" : `exited with code ${exitCode}`;
|
|
166
|
+
const snapshot = this.createSnapshot();
|
|
167
|
+
this.onSnapshot?.(snapshot);
|
|
168
|
+
this.onExit?.(snapshot);
|
|
169
|
+
if (activeHost === this)
|
|
170
|
+
activeHost = null;
|
|
171
|
+
this.dispose("exit", { kill: false, notify: false });
|
|
172
|
+
}).catch((error) => {
|
|
173
|
+
if (this._disposed)
|
|
174
|
+
return;
|
|
175
|
+
this.status = "failed";
|
|
176
|
+
this.message = error instanceof Error ? error.message : String(error);
|
|
177
|
+
const snapshot = this.createSnapshot();
|
|
178
|
+
this.onSnapshot?.(snapshot);
|
|
179
|
+
this.onError?.(error, snapshot);
|
|
180
|
+
if (activeHost === this)
|
|
181
|
+
activeHost = null;
|
|
182
|
+
this.dispose("error", { kill: false, notify: false });
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
write(data) {
|
|
186
|
+
if (this._disposed || !this.pty)
|
|
187
|
+
return;
|
|
188
|
+
try {
|
|
189
|
+
this.pty.write(data);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
this.status = "failed";
|
|
192
|
+
this.message = error instanceof Error ? error.message : String(error);
|
|
193
|
+
const snapshot = this.createSnapshot();
|
|
194
|
+
this.onSnapshot?.(snapshot);
|
|
195
|
+
this.onError?.(error, snapshot);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
resize(cols, rows) {
|
|
199
|
+
const nextCols = clampCols(cols);
|
|
200
|
+
const nextRows = clampRows(rows);
|
|
201
|
+
if (nextCols === this.cols && nextRows === this.rows)
|
|
202
|
+
return;
|
|
203
|
+
this.cols = nextCols;
|
|
204
|
+
this.rows = nextRows;
|
|
205
|
+
this.terminal.resize(nextCols, nextRows);
|
|
206
|
+
try {
|
|
207
|
+
this.pty?.resize(nextCols, nextRows);
|
|
208
|
+
} catch {}
|
|
209
|
+
this.emitSnapshotSoon(0);
|
|
210
|
+
}
|
|
211
|
+
dispose(reason = "dispose", options = {}) {
|
|
212
|
+
if (this._disposed)
|
|
213
|
+
return;
|
|
214
|
+
this._disposed = true;
|
|
215
|
+
if (this.notifyTimer)
|
|
216
|
+
clearTimeout(this.notifyTimer);
|
|
217
|
+
this.notifyTimer = null;
|
|
218
|
+
if (options.kill !== false) {
|
|
219
|
+
try {
|
|
220
|
+
this.proc?.kill("SIGTERM");
|
|
221
|
+
} catch {}
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
this.pty?.close();
|
|
225
|
+
} catch {}
|
|
226
|
+
try {
|
|
227
|
+
this.terminal.dispose();
|
|
228
|
+
} catch {}
|
|
229
|
+
if (activeHost === this)
|
|
230
|
+
activeHost = null;
|
|
231
|
+
if (options.notify) {
|
|
232
|
+
this.message = reason;
|
|
233
|
+
this.onSnapshot?.(this.createSnapshot(reason));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
handlePtyData(data) {
|
|
237
|
+
if (this._disposed)
|
|
238
|
+
return;
|
|
239
|
+
this.decoder.decode(data, { stream: true });
|
|
240
|
+
this.terminal.write(data, () => this.emitSnapshotSoon());
|
|
241
|
+
}
|
|
242
|
+
emitSnapshotSoon(delayMs = SNAPSHOT_DELAY_MS) {
|
|
243
|
+
if (this._disposed || this.notifyTimer)
|
|
244
|
+
return;
|
|
245
|
+
this.notifyTimer = setTimeout(() => {
|
|
246
|
+
this.notifyTimer = null;
|
|
247
|
+
if (this._disposed)
|
|
248
|
+
return;
|
|
249
|
+
this.onSnapshot?.(this.createSnapshot());
|
|
250
|
+
}, delayMs);
|
|
251
|
+
}
|
|
252
|
+
createSnapshot(message = this.message) {
|
|
253
|
+
const buffer = this.terminal.buffer.active;
|
|
254
|
+
const end = buffer.length;
|
|
255
|
+
const start = Math.max(0, end - MAX_SNAPSHOT_LINES);
|
|
256
|
+
const lines = [];
|
|
257
|
+
for (let row = start;row < end; row += 1) {
|
|
258
|
+
const line = buffer.getLine(row);
|
|
259
|
+
lines.push((line?.translateToString(false) ?? "").slice(0, this.cols));
|
|
260
|
+
}
|
|
261
|
+
while (lines.length < this.rows)
|
|
262
|
+
lines.push("");
|
|
263
|
+
return {
|
|
264
|
+
command: this.argv,
|
|
265
|
+
label: this.label,
|
|
266
|
+
status: this.status,
|
|
267
|
+
cols: this.cols,
|
|
268
|
+
rows: this.rows,
|
|
269
|
+
lines,
|
|
270
|
+
message,
|
|
271
|
+
...this.exitCode !== undefined ? { exitCode: this.exitCode } : {},
|
|
272
|
+
...this.signal !== undefined ? { signal: this.signal } : {}
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// packages/cli/src/app-opentui/adapters/command.ts
|
|
278
|
+
function commandLabel2(argv) {
|
|
279
|
+
const command = argv.join(" ").trim();
|
|
280
|
+
return command ? `rig ${command}` : "rig";
|
|
281
|
+
}
|
|
282
|
+
async function runCommandInAppPty(ctx, argv) {
|
|
283
|
+
const label = commandLabel2(argv);
|
|
284
|
+
emitStarted(ctx, label, { command: { label, argv, status: "starting" } });
|
|
285
|
+
patchData(ctx, {
|
|
286
|
+
command: { label, argv, status: "starting" },
|
|
287
|
+
commandTerminal: {
|
|
288
|
+
command: argv,
|
|
289
|
+
label,
|
|
290
|
+
status: "starting",
|
|
291
|
+
cols: 120,
|
|
292
|
+
rows: 32,
|
|
293
|
+
lines: [],
|
|
294
|
+
message: "starting"
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
patchFooter(ctx, { message: label });
|
|
298
|
+
try {
|
|
299
|
+
const host = await startCommandPtyHost({
|
|
300
|
+
argv,
|
|
301
|
+
projectRoot: projectRootOf(ctx),
|
|
302
|
+
cols: 120,
|
|
303
|
+
rows: 32,
|
|
304
|
+
label,
|
|
305
|
+
onSnapshot(snapshot) {
|
|
306
|
+
patchData(ctx, { commandTerminal: snapshot, command: { label, argv, status: snapshot.status, message: snapshot.message } });
|
|
307
|
+
patchFooter(ctx, { message: `${label} \xB7 ${snapshot.message ?? snapshot.status}` });
|
|
308
|
+
},
|
|
309
|
+
onExit(snapshot) {
|
|
310
|
+
patchData(ctx, { commandTerminal: snapshot, command: { label, argv, status: snapshot.status, message: snapshot.message } });
|
|
311
|
+
if (snapshot.status === "exited")
|
|
312
|
+
emitCompleted(ctx, label, { exitCode: snapshot.exitCode ?? 0 });
|
|
313
|
+
else
|
|
314
|
+
emitFailed(ctx, label, new Error(snapshot.message ?? "Command failed"), { commandTerminal: snapshot });
|
|
315
|
+
},
|
|
316
|
+
onError(error, snapshot) {
|
|
317
|
+
patchData(ctx, { commandTerminal: snapshot, command: { label, argv, status: "failed", message: snapshot.message } });
|
|
318
|
+
emitFailed(ctx, label, error, { commandTerminal: snapshot });
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
patchData(ctx, { commandTerminal: host.snapshot });
|
|
322
|
+
} catch (error) {
|
|
323
|
+
emitFailed(ctx, label, error);
|
|
324
|
+
throw error;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
export {
|
|
328
|
+
runCommandInAppPty
|
|
329
|
+
};
|
|
@@ -13,7 +13,7 @@ function projectRootOf(ctx) {
|
|
|
13
13
|
const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
|
|
14
14
|
if (typeof root === "string" && root.trim())
|
|
15
15
|
return root;
|
|
16
|
-
throw new Error("
|
|
16
|
+
throw new Error("App adapter requires a projectRoot.");
|
|
17
17
|
}
|
|
18
18
|
async function runtimeOf(ctx) {
|
|
19
19
|
if (ctx.rig && "runId" in ctx.rig && ctx.ensureRuntime === undefined) {
|
|
@@ -21,7 +21,7 @@ async function runtimeOf(ctx) {
|
|
|
21
21
|
}
|
|
22
22
|
if (ctx.ensureRuntime)
|
|
23
23
|
return ctx.ensureRuntime();
|
|
24
|
-
throw new Error("
|
|
24
|
+
throw new Error("App adapter requires ensureRuntime() before this action can run.");
|
|
25
25
|
}
|
|
26
26
|
function normalizeAppError(error) {
|
|
27
27
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -145,17 +145,21 @@ function cleanToken(value) {
|
|
|
145
145
|
const trimmed = value?.trim();
|
|
146
146
|
return trimmed ? trimmed : null;
|
|
147
147
|
}
|
|
148
|
-
function
|
|
148
|
+
function readRemoteAuthState(projectRoot) {
|
|
149
149
|
const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
|
|
150
150
|
if (!existsSync2(path))
|
|
151
151
|
return null;
|
|
152
152
|
try {
|
|
153
153
|
const parsed = JSON.parse(readFileSync2(path, "utf8"));
|
|
154
|
-
return
|
|
154
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
155
155
|
} catch {
|
|
156
156
|
return null;
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
+
function readPrivateRemoteSessionToken(projectRoot) {
|
|
160
|
+
const parsed = readRemoteAuthState(projectRoot);
|
|
161
|
+
return parsed ? cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined) : null;
|
|
162
|
+
}
|
|
159
163
|
function readGitHubBearerTokenForRemote(projectRoot) {
|
|
160
164
|
const scopedKey = resolve2(projectRoot);
|
|
161
165
|
if (scopedGitHubBearerTokens.has(scopedKey))
|
|
@@ -166,15 +170,25 @@ function readGitHubBearerTokenForRemote(projectRoot) {
|
|
|
166
170
|
return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
|
|
167
171
|
}
|
|
168
172
|
function readStoredGitHubAuthToken(projectRoot) {
|
|
169
|
-
const
|
|
170
|
-
|
|
173
|
+
const parsed = readRemoteAuthState(projectRoot);
|
|
174
|
+
return parsed ? cleanToken(typeof parsed.token === "string" ? parsed.token : undefined) : null;
|
|
175
|
+
}
|
|
176
|
+
function inferRemoteServerProjectRootFromAuthState(projectRoot) {
|
|
177
|
+
const repo = readRepoConnection(projectRoot);
|
|
178
|
+
const slug = repo?.project?.trim();
|
|
179
|
+
if (!slug || !/^[^/]+\/[^/]+$/.test(slug))
|
|
171
180
|
return null;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
181
|
+
const auth = readRemoteAuthState(projectRoot);
|
|
182
|
+
const authUpdatedAt = typeof auth?.updatedAt === "string" ? Date.parse(auth.updatedAt) : Number.NaN;
|
|
183
|
+
const repoLinkedAt = typeof repo?.linkedAt === "string" ? Date.parse(repo.linkedAt) : Number.NaN;
|
|
184
|
+
if (Number.isFinite(authUpdatedAt) && Number.isFinite(repoLinkedAt) && authUpdatedAt + 1000 < repoLinkedAt)
|
|
176
185
|
return null;
|
|
177
|
-
|
|
186
|
+
const checkoutBaseDir = typeof auth?.checkoutBaseDir === "string" && auth.checkoutBaseDir.trim() ? auth.checkoutBaseDir.trim() : null;
|
|
187
|
+
if (!checkoutBaseDir)
|
|
188
|
+
return null;
|
|
189
|
+
const inferred = `${checkoutBaseDir.replace(/\/+$/, "")}/${slug}`;
|
|
190
|
+
writeRepoServerProjectRoot(projectRoot, inferred);
|
|
191
|
+
return inferred;
|
|
178
192
|
}
|
|
179
193
|
function readLocalConnectionFallbackToken(projectRoot) {
|
|
180
194
|
return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
|
|
@@ -185,7 +199,7 @@ async function ensureServerForCli(projectRoot) {
|
|
|
185
199
|
if (selected?.connection.kind === "remote") {
|
|
186
200
|
reportServerPhase(`Connecting to ${selected.alias}\u2026`);
|
|
187
201
|
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
188
|
-
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
202
|
+
const serverProjectRoot = selected.serverProjectRoot ?? inferRemoteServerProjectRootFromAuthState(projectRoot) ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
189
203
|
return {
|
|
190
204
|
baseUrl: selected.connection.baseUrl,
|
|
191
205
|
authToken,
|
|
@@ -214,7 +228,10 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
|
|
|
214
228
|
if (!slug)
|
|
215
229
|
return null;
|
|
216
230
|
try {
|
|
217
|
-
const
|
|
231
|
+
const url = new URL(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`);
|
|
232
|
+
if (authToken && queryAuthFallbackEnabled())
|
|
233
|
+
url.searchParams.set("rt", authToken);
|
|
234
|
+
const response = await fetch(url, {
|
|
218
235
|
headers: mergeHeaders(undefined, authToken)
|
|
219
236
|
});
|
|
220
237
|
if (!response.ok)
|
|
@@ -231,10 +248,23 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
|
|
|
231
248
|
return null;
|
|
232
249
|
}
|
|
233
250
|
}
|
|
251
|
+
function mergeCookie(existing, name, value) {
|
|
252
|
+
const encoded = `${name}=${encodeURIComponent(value)}`;
|
|
253
|
+
if (!existing?.trim())
|
|
254
|
+
return encoded;
|
|
255
|
+
const parts = existing.split(";").map((part) => part.trim()).filter((part) => part && !part.startsWith(`${name}=`));
|
|
256
|
+
return [...parts, encoded].join("; ");
|
|
257
|
+
}
|
|
258
|
+
function queryAuthFallbackEnabled(env = process.env) {
|
|
259
|
+
return env.RIG_ENABLE_QUERY_AUTH_FALLBACK === "1" || env.RIG_QUERY_AUTH_FALLBACK === "1";
|
|
260
|
+
}
|
|
234
261
|
function mergeHeaders(headers, authToken) {
|
|
235
262
|
const merged = new Headers(headers);
|
|
236
263
|
if (authToken) {
|
|
237
|
-
|
|
264
|
+
const bearer = `Bearer ${authToken}`;
|
|
265
|
+
merged.set("authorization", bearer);
|
|
266
|
+
merged.set("x-auth", bearer);
|
|
267
|
+
merged.set("cookie", mergeCookie(merged.get("cookie"), "rig_auth", authToken));
|
|
238
268
|
}
|
|
239
269
|
return merged;
|
|
240
270
|
}
|
|
@@ -294,15 +324,34 @@ async function buildServerFailureContext(projectRoot, server) {
|
|
|
294
324
|
hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
|
|
295
325
|
};
|
|
296
326
|
}
|
|
327
|
+
function isLoopbackRemoteBaseUrl(baseUrl) {
|
|
328
|
+
try {
|
|
329
|
+
const host = new URL(baseUrl).hostname.toLowerCase();
|
|
330
|
+
return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
|
|
331
|
+
} catch {
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function canUseRemoteWithoutProjectRoot(pathname) {
|
|
336
|
+
return pathname === "/health" || pathname === "/api/health" || pathname === "/api/server/status" || pathname === "/api/server/project-root" || pathname.startsWith("/api/github/auth/") || pathname === "/api/projects" || pathname.startsWith("/api/projects/");
|
|
337
|
+
}
|
|
297
338
|
async function requestServerJson(context, pathname, init = {}) {
|
|
298
339
|
const server = await ensureServerForCli(context.projectRoot);
|
|
340
|
+
const requestUrl = new URL(`${server.baseUrl}${pathname}`);
|
|
341
|
+
if (server.connectionKind === "remote" && !server.serverProjectRoot && !canUseRemoteWithoutProjectRoot(requestUrl.pathname) && (server.authToken || !isLoopbackRemoteBaseUrl(server.baseUrl))) {
|
|
342
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
343
|
+
throw new CliError(`Remote server is selected for ${repo?.project ?? "this repo"}, but this checkout has no server-host project root link.`, 1, { hint: "Run `rig init --repair` or `rig init --yes --repo owner/repo --server remote` to repair the remote project link before task/run commands." });
|
|
344
|
+
}
|
|
299
345
|
const headers = mergeHeaders(init.headers, server.authToken);
|
|
300
346
|
if (server.serverProjectRoot)
|
|
301
347
|
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
348
|
+
if (server.connectionKind === "remote" && server.authToken && queryAuthFallbackEnabled()) {
|
|
349
|
+
requestUrl.searchParams.set("rt", server.authToken);
|
|
350
|
+
}
|
|
302
351
|
reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
|
|
303
352
|
let response;
|
|
304
353
|
try {
|
|
305
|
-
response = await fetch(
|
|
354
|
+
response = await fetch(requestUrl, {
|
|
306
355
|
...init,
|
|
307
356
|
headers
|
|
308
357
|
});
|
|
@@ -686,20 +735,11 @@ var init__doctor_checks = __esm(() => {
|
|
|
686
735
|
});
|
|
687
736
|
|
|
688
737
|
// packages/cli/src/app-opentui/adapters/common.ts
|
|
689
|
-
function adapterContextFromRuntime(runtime, renderer) {
|
|
690
|
-
return {
|
|
691
|
-
projectRoot: runtime.getState().projectRoot,
|
|
692
|
-
renderer,
|
|
693
|
-
ensureRuntime: () => runtime.getRunnerContext(),
|
|
694
|
-
emit: (event) => runtime.emit(event),
|
|
695
|
-
getState: () => runtime.getState()
|
|
696
|
-
};
|
|
697
|
-
}
|
|
698
738
|
function projectRootOf(ctx) {
|
|
699
739
|
const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
|
|
700
740
|
if (typeof root === "string" && root.trim())
|
|
701
741
|
return root;
|
|
702
|
-
throw new Error("
|
|
742
|
+
throw new Error("App adapter requires a projectRoot.");
|
|
703
743
|
}
|
|
704
744
|
function normalizeAppError(error) {
|
|
705
745
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -735,20 +775,6 @@ function patchData(ctx, data) {
|
|
|
735
775
|
}
|
|
736
776
|
|
|
737
777
|
// packages/cli/src/app-opentui/adapters/doctor.ts
|
|
738
|
-
function createDoctorAdapter() {
|
|
739
|
-
return {
|
|
740
|
-
id: "doctor",
|
|
741
|
-
async handleIntent(runtime, intent) {
|
|
742
|
-
if (intent.scene !== "doctor" && intent.action.kind !== "doctor-run")
|
|
743
|
-
return false;
|
|
744
|
-
if (intent.action.kind === "doctor-run" || intent.action.kind === "refresh" || intent.action.kind === "navigate") {
|
|
745
|
-
await runDoctorChecksForApp(adapterContextFromRuntime(runtime));
|
|
746
|
-
return true;
|
|
747
|
-
}
|
|
748
|
-
return false;
|
|
749
|
-
}
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
778
|
async function runDoctorChecksForApp(ctx) {
|
|
753
779
|
const label = "Running doctor";
|
|
754
780
|
emitStarted(ctx, label);
|
|
@@ -775,6 +801,5 @@ async function runDoctorChecksForApp(ctx) {
|
|
|
775
801
|
}
|
|
776
802
|
}
|
|
777
803
|
export {
|
|
778
|
-
runDoctorChecksForApp
|
|
779
|
-
createDoctorAdapter
|
|
804
|
+
runDoctorChecksForApp
|
|
780
805
|
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { AppIntent } from "../types";
|
|
2
|
+
import { type AppAdapterContext } from "./common";
|
|
3
|
+
/** A subcommand's flag/option/positional adapted into a typed UI field. */
|
|
4
|
+
export type AppFamilyField = {
|
|
5
|
+
readonly kind: "flag";
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly token: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: "value";
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly token: string;
|
|
12
|
+
readonly placeholder: string;
|
|
13
|
+
readonly required: boolean;
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: "select";
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly token: string;
|
|
18
|
+
readonly choices: readonly string[];
|
|
19
|
+
readonly required: boolean;
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: "positional";
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly placeholder: string;
|
|
24
|
+
readonly required: boolean;
|
|
25
|
+
readonly repeatable: boolean;
|
|
26
|
+
};
|
|
27
|
+
/** A catalog subcommand parsed into its base words + adapted fields. */
|
|
28
|
+
export type AppFamilySubcommand = {
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly template: string;
|
|
31
|
+
readonly description: string;
|
|
32
|
+
/** The words before the first placeholder/flag — the command's verb path. */
|
|
33
|
+
readonly base: readonly string[];
|
|
34
|
+
readonly fields: readonly AppFamilyField[];
|
|
35
|
+
/** No fields at all → safe to run directly with one Enter. */
|
|
36
|
+
readonly direct: boolean;
|
|
37
|
+
readonly primary: boolean;
|
|
38
|
+
};
|
|
39
|
+
export type AppFamilySnapshot = {
|
|
40
|
+
readonly family: string;
|
|
41
|
+
readonly summary: string;
|
|
42
|
+
readonly usage: readonly string[];
|
|
43
|
+
readonly subcommands: readonly AppFamilySubcommand[];
|
|
44
|
+
/** Captured live state from the family's safe list/status subcommand. */
|
|
45
|
+
readonly state: {
|
|
46
|
+
readonly subcommand: readonly string[] | null;
|
|
47
|
+
readonly ran: boolean;
|
|
48
|
+
readonly ok: boolean;
|
|
49
|
+
readonly lines: readonly string[];
|
|
50
|
+
readonly details: Record<string, unknown> | null;
|
|
51
|
+
};
|
|
52
|
+
readonly refreshedAt: number;
|
|
53
|
+
};
|
|
54
|
+
/** In-progress form: which subcommand is open and the value/flag selections. */
|
|
55
|
+
export type AppFamilyForm = {
|
|
56
|
+
readonly family: string;
|
|
57
|
+
readonly subId: string | null;
|
|
58
|
+
/** flag/positional/value name → set value. Flags store "on"; cleared = unset. */
|
|
59
|
+
readonly values: Record<string, string>;
|
|
60
|
+
};
|
|
61
|
+
export declare function familyCatalog(family: string): AppFamilySnapshot["subcommands"];
|
|
62
|
+
export declare function refreshFamily(ctx: AppAdapterContext, intent?: AppIntent): Promise<AppFamilySnapshot>;
|