@shardflux/cli 0.15.2 → 0.17.0
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/CHANGELOG.md +144 -14
- package/README.md +92 -7
- package/dist/acp-models.js +5 -1
- package/dist/agent-commands.d.ts +15 -1
- package/dist/agent-commands.js +84 -23
- package/dist/agent-models.d.ts +61 -0
- package/dist/agent-models.js +79 -0
- package/dist/agent-state.d.ts +10 -0
- package/dist/agent-state.js +13 -0
- package/dist/agent-target-commands.d.ts +13 -3
- package/dist/agent-target-commands.js +129 -23
- package/dist/agent-targets.d.ts +5 -0
- package/dist/agent-targets.js +14 -5
- package/dist/agent-terminal.d.ts +8 -0
- package/dist/agent-terminal.js +35 -2
- package/dist/args.d.ts +5 -1
- package/dist/args.js +74 -11
- package/dist/cli-proxy-forward.d.ts +45 -0
- package/dist/cli-proxy-forward.js +432 -0
- package/dist/cli-proxy-hub.d.ts +273 -0
- package/dist/cli-proxy-hub.js +749 -0
- package/dist/cli-proxy.d.ts +325 -0
- package/dist/cli-proxy.js +1016 -0
- package/dist/codex-cloud.d.ts +3 -0
- package/dist/codex-cloud.js +17 -5
- package/dist/command-center-actions.js +25 -1
- package/dist/commands.d.ts +22 -0
- package/dist/commands.js +54 -14
- package/dist/conversation-commands.js +6 -0
- package/dist/conversation-local.js +2 -2
- package/dist/conversation-stash.js +4 -3
- package/dist/conversation-terminal.d.ts +5 -0
- package/dist/conversation-terminal.js +54 -6
- package/dist/conversations.d.ts +31 -3
- package/dist/conversations.js +53 -10
- package/dist/device-approvals.d.ts +12 -0
- package/dist/device-approvals.js +73 -0
- package/dist/device-helper.d.ts +3 -1
- package/dist/device-helper.js +14 -4
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +12 -2
- package/dist/files-mirror.d.ts +164 -0
- package/dist/files-mirror.js +761 -0
- package/dist/handlers.js +5 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/linux-helper.d.ts +12 -0
- package/dist/linux-helper.js +88 -0
- package/dist/linux-terminal.d.ts +11 -0
- package/dist/linux-terminal.js +42 -0
- package/dist/main.js +38 -8
- package/dist/onboarding.d.ts +2 -0
- package/dist/onboarding.js +53 -5
- package/dist/registry.d.ts +2 -42
- package/dist/registry.js +6 -90
- package/dist/t3-launch.d.ts +37 -0
- package/dist/t3-launch.js +133 -0
- package/dist/t3-mode.d.ts +121 -0
- package/dist/t3-mode.js +654 -0
- package/dist/t3-phone.d.ts +17 -0
- package/dist/t3-phone.js +15 -0
- package/dist/t3-thread-script.d.ts +18 -0
- package/dist/t3-thread-script.js +245 -0
- package/dist/terminal-onboarding.d.ts +11 -0
- package/dist/terminal-onboarding.js +75 -0
- package/dist/thread-on-computer.d.ts +35 -0
- package/dist/thread-on-computer.js +206 -0
- package/dist/update.d.ts +1 -1
- package/dist/update.js +12 -1
- package/dist/wait-status.d.ts +22 -0
- package/dist/wait-status.js +59 -0
- package/dist/worktree-twin-engine.d.ts +125 -0
- package/dist/worktree-twin-engine.js +615 -0
- package/dist/worktree-twin-land.py +331 -0
- package/dist/worktree-twin.d.ts +313 -0
- package/dist/worktree-twin.js +843 -0
- package/package.json +3 -3
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import type { Handler, Ctx } from './commands.js';
|
|
2
|
+
import type { Values } from './args.js';
|
|
3
|
+
import type { EnsureResult, HubCloud, HubInfo } from './cli-proxy-hub.js';
|
|
4
|
+
import type { HomeProject } from './cli-proxy-hub.js';
|
|
5
|
+
/** Runs a program, stdout on success, null when it is missing or fails (detection never throws). */
|
|
6
|
+
export type ProgramRunner = (program: string, args: string[]) => Promise<string | null>;
|
|
7
|
+
export declare const runProgram: ProgramRunner;
|
|
8
|
+
/**
|
|
9
|
+
* The programs and probes detection, stop and the launchd install use by default. The CLI test support replaces them,
|
|
10
|
+
* so no test inspects, stops or replaces a CLIProxyAPI or forwarder running on the developer's computer.
|
|
11
|
+
*/
|
|
12
|
+
export declare const cliProxyTools: {
|
|
13
|
+
run: ProgramRunner;
|
|
14
|
+
answers: (port: number) => Promise<boolean>;
|
|
15
|
+
identity: (port?: number) => Promise<ForwarderIdentity | null>;
|
|
16
|
+
inVm: () => boolean;
|
|
17
|
+
kill: (pid: number) => void;
|
|
18
|
+
};
|
|
19
|
+
/** The launchd agent that keeps the forwarder on 127.0.0.1:8317 on a Mac. */
|
|
20
|
+
export declare const FORWARD_LABEL = "dev.shardflux.cli-proxy-forward";
|
|
21
|
+
/** Where every VM finds the hub info (the machine template carries it). */
|
|
22
|
+
export declare const VM_HUB_INFO_PATH = "/home/user/.config/shardflux-cli-proxy.json";
|
|
23
|
+
export interface LocalLogin {
|
|
24
|
+
file: string;
|
|
25
|
+
provider: string | null;
|
|
26
|
+
email: string | null;
|
|
27
|
+
}
|
|
28
|
+
/** A Docker container that publishes the port; `cliProxy` when its image or name is CLIProxyAPI's. */
|
|
29
|
+
export interface LocalContainer {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
image: string;
|
|
33
|
+
cliProxy: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface LocalListener {
|
|
36
|
+
pid: number;
|
|
37
|
+
command: string;
|
|
38
|
+
/** The process's executable (ps comm). */
|
|
39
|
+
executable: string;
|
|
40
|
+
/** Shardflux's own forwarder (`shard cli-proxy forward`, `sf-agent cli-proxy-forward`) holds the port. */
|
|
41
|
+
forwarder: boolean;
|
|
42
|
+
/** Verified to be CLIProxyAPI by its executable name (cli-proxy-api, cliproxyapi). Only such a process is offered to stop. */
|
|
43
|
+
cliProxy: boolean;
|
|
44
|
+
/** The listener is Docker's port proxy for this container (never the Docker process itself). */
|
|
45
|
+
container: LocalContainer | null;
|
|
46
|
+
}
|
|
47
|
+
export type LocalService = {
|
|
48
|
+
kind: 'brew';
|
|
49
|
+
formula: string;
|
|
50
|
+
label: string;
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'launchd';
|
|
53
|
+
label: string;
|
|
54
|
+
plist: string;
|
|
55
|
+
};
|
|
56
|
+
export interface LocalCliProxy {
|
|
57
|
+
/** The auth directory (`auth-dir` of the config, default ~/.cli-proxy-api). */
|
|
58
|
+
authDir: string;
|
|
59
|
+
/** Every auth directory a CLIProxyAPI on this computer reads: the config's, and ~/.cli-proxy-api while it holds logins. */
|
|
60
|
+
authDirs: string[];
|
|
61
|
+
/** One per auth file: provider and email only (never token contents). */
|
|
62
|
+
logins: LocalLogin[];
|
|
63
|
+
configPath: string | null;
|
|
64
|
+
/** The port it listens on: the config's `port` (`server.port` in the v8 layout), default 8317. */
|
|
65
|
+
port: number;
|
|
66
|
+
/** What listens on that port now. */
|
|
67
|
+
listener: LocalListener | null;
|
|
68
|
+
/** The Homebrew service or launchd agent that runs it. */
|
|
69
|
+
service: LocalService | null;
|
|
70
|
+
}
|
|
71
|
+
export interface DetectOptions {
|
|
72
|
+
env?: Record<string, string | undefined>;
|
|
73
|
+
home?: string;
|
|
74
|
+
/** An explicit config file (shard cli-proxy import --config). */
|
|
75
|
+
configPath?: string;
|
|
76
|
+
run?: ProgramRunner;
|
|
77
|
+
platform?: NodeJS.Platform;
|
|
78
|
+
}
|
|
79
|
+
/** The listening port of a CLIProxyAPI config (either layout), or null when it names none. */
|
|
80
|
+
export declare function configPort(doc: unknown): number | null;
|
|
81
|
+
/**
|
|
82
|
+
* CLIProxyAPI on this computer: its auth files (provider and email of each), its config and port, the process that
|
|
83
|
+
* listens there and the service that runs it. Null when there is none of these.
|
|
84
|
+
*/
|
|
85
|
+
export declare function detectLocalCliProxy(opts?: DetectOptions): Promise<LocalCliProxy | null>;
|
|
86
|
+
/**
|
|
87
|
+
* Who an auth file signs in as: its provider (`type`) and every identifying field it has (email, account, organization,
|
|
88
|
+
* workspace, user and project ids), from its JSON. Two files are the same login only when they have the same provider
|
|
89
|
+
* and the same fields with the same values: one email can sign in to several accounts or workspaces, so a file that
|
|
90
|
+
* names a different (or one more) account is another login. A file without any is only itself (its path).
|
|
91
|
+
*/
|
|
92
|
+
export declare function loginIdentity(text: string, file: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* After the hub has the logins: moves every auth file out of each directory a local CLIProxyAPI reads, into a sibling
|
|
95
|
+
* `<dir>.moved-to-shardflux` (0700; files keep their 0600), so a local copy started again has no tokens to refresh.
|
|
96
|
+
* Other files (a config.yaml, logs) stay where they are.
|
|
97
|
+
*/
|
|
98
|
+
export declare function moveAuthFilesAside(dirs: readonly string[], now?: Date): Array<{
|
|
99
|
+
from: string;
|
|
100
|
+
to: string;
|
|
101
|
+
files: number;
|
|
102
|
+
}>;
|
|
103
|
+
/** Whether something accepts connections on 127.0.0.1:port (also a listener on all interfaces). */
|
|
104
|
+
export declare function portAnswers(port: number, host?: string): Promise<boolean>;
|
|
105
|
+
/** How it is stopped for good: the steps, and the same as one command line to show. */
|
|
106
|
+
export interface StopPlan {
|
|
107
|
+
line: string;
|
|
108
|
+
steps: Array<{
|
|
109
|
+
run: string[];
|
|
110
|
+
} | {
|
|
111
|
+
kill: number;
|
|
112
|
+
} | {
|
|
113
|
+
move: [string, string];
|
|
114
|
+
}>;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* A Homebrew service: `brew services stop` (it also leaves login). Another launchd agent: bootout, disable, and its plist
|
|
118
|
+
* moved aside, so it cannot come back at login. A plain process: ending it.
|
|
119
|
+
*/
|
|
120
|
+
export declare function stopPlan(local: LocalCliProxy, uid?: number): StopPlan | null;
|
|
121
|
+
export interface StopDeps {
|
|
122
|
+
run?: ProgramRunner;
|
|
123
|
+
kill?: (pid: number) => void;
|
|
124
|
+
answers?: (port: number) => Promise<boolean>;
|
|
125
|
+
/** Shardflux's own forwarder answers on the port (nothing to stop). */
|
|
126
|
+
ours?: () => Promise<boolean>;
|
|
127
|
+
sleep?: (ms: number) => Promise<void>;
|
|
128
|
+
/** Longest wait for the user to stop it themselves (default 5 minutes). */
|
|
129
|
+
waitMs?: number;
|
|
130
|
+
uid?: number;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Stops the local CLIProxyAPI on its own port so only the hosted copy refreshes the logins. A Homebrew service is
|
|
134
|
+
* stopped with `brew services stop` (said first); a process or another launchd agent only with the user's consent
|
|
135
|
+
* ([Y/n] on a terminal, defaulting to yes; --yes otherwise): declined, the exact command is shown and the port is
|
|
136
|
+
* watched until it is free. Refuses when something starts it again.
|
|
137
|
+
*/
|
|
138
|
+
export declare function stopLocalCliProxy(ctx: Ctx, local: LocalCliProxy, values?: Values, deps?: StopDeps): Promise<{
|
|
139
|
+
result: 'none' | 'stopped';
|
|
140
|
+
plan: StopPlan | null;
|
|
141
|
+
}>;
|
|
142
|
+
/** How the user starts the local CLIProxyAPI again (`shard cli-proxy export` names it). */
|
|
143
|
+
export declare function startLine(local: LocalCliProxy, uid?: number): string;
|
|
144
|
+
export interface PlistOptions {
|
|
145
|
+
node: string;
|
|
146
|
+
script: string;
|
|
147
|
+
configDir: string;
|
|
148
|
+
apiUrl: string;
|
|
149
|
+
logFile: string;
|
|
150
|
+
path?: string;
|
|
151
|
+
}
|
|
152
|
+
/** The launchd agent: `shard cli-proxy forward` at login, started again whenever it exits. */
|
|
153
|
+
export declare function forwarderPlist(o: PlistOptions): string;
|
|
154
|
+
export declare function forwarderPlistPath(home: string): string;
|
|
155
|
+
/** Whether Shardflux's forwarder answers on 127.0.0.1:port, and for which hub. */
|
|
156
|
+
export interface ForwarderIdentity {
|
|
157
|
+
hub: string | null; /** `mac`: shard cli-proxy forward; `vm`: sf-agent cli-proxy-forward. */
|
|
158
|
+
kind: 'mac' | 'vm';
|
|
159
|
+
version: string | null;
|
|
160
|
+
}
|
|
161
|
+
/** Whether Shardflux's forwarder (this computer's, or a VM's sf-agent) answers on 127.0.0.1:port, and for which hub. */
|
|
162
|
+
export declare function forwarderIdentity(port?: number): Promise<ForwarderIdentity | null>;
|
|
163
|
+
/** A Shardflux VM (its guest agent is installed): the hub is set up from the computer where CLIProxyAPI runs. */
|
|
164
|
+
export declare function inShardfluxVm(): boolean;
|
|
165
|
+
export interface LaunchdDeps {
|
|
166
|
+
run?: ProgramRunner;
|
|
167
|
+
uid?: number;
|
|
168
|
+
identity?: () => Promise<ForwarderIdentity | null>;
|
|
169
|
+
sleep?: (ms: number) => Promise<void>;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* After `shard` is updated, the launchd forwarder still runs the program it started with. Called on every shard run
|
|
173
|
+
* (one file read on macOS): an installed forwarder agent recorded for another shard version is started again, on this
|
|
174
|
+
* one. Returns whether it was.
|
|
175
|
+
*/
|
|
176
|
+
export declare function refreshForwarderAgent(env: Record<string, string | undefined>, dir: string, deps?: {
|
|
177
|
+
run?: ProgramRunner;
|
|
178
|
+
uid?: number;
|
|
179
|
+
platform?: NodeJS.Platform;
|
|
180
|
+
}): Promise<boolean>;
|
|
181
|
+
/** Installs (or refreshes) the launchd agent and waits until the forwarder answers. macOS only. */
|
|
182
|
+
export declare function installForwarderAgent(ctx: Ctx, apiUrl: string, deps?: LaunchdDeps): Promise<string>;
|
|
183
|
+
/**
|
|
184
|
+
* Puts the hub info into the machine template (opening the machine VM like `shard machine`, then saving it), so every
|
|
185
|
+
* new VM's forwarder reaches the hub. Skipped when the saved machine already carries this hub info.
|
|
186
|
+
*/
|
|
187
|
+
export declare function saveHubInfoToMachine(ctx: Ctx, info: HubInfo, opts?: {
|
|
188
|
+
machine?: MachineAccess;
|
|
189
|
+
current?: () => Promise<HubInfo>;
|
|
190
|
+
}): Promise<{
|
|
191
|
+
version: number;
|
|
192
|
+
saved: boolean;
|
|
193
|
+
}>;
|
|
194
|
+
/**
|
|
195
|
+
* The hub's home: the organization's first project (oldest), listed with the user session. Null when signed out, so a
|
|
196
|
+
* new hub is never created by guesswork in another project.
|
|
197
|
+
*/
|
|
198
|
+
export declare function homeProject(ctx: Ctx, organizationId: string): Promise<HomeProject | null>;
|
|
199
|
+
/** The account's machine as the import changes it: open its VM (as `shard machine` does), write a file, save. */
|
|
200
|
+
export interface MachineAccess {
|
|
201
|
+
/** The saved machine version. */
|
|
202
|
+
version(): Promise<number>;
|
|
203
|
+
open(): Promise<{
|
|
204
|
+
write(path: string, text: string): Promise<void>;
|
|
205
|
+
save(): Promise<number>;
|
|
206
|
+
}>;
|
|
207
|
+
}
|
|
208
|
+
export declare function sdkMachine(ctx: Ctx): MachineAccess;
|
|
209
|
+
export interface HubAccount {
|
|
210
|
+
provider: string;
|
|
211
|
+
email: string | null;
|
|
212
|
+
status: string | null;
|
|
213
|
+
disabled: boolean;
|
|
214
|
+
}
|
|
215
|
+
/** The hub's logins from its management API (wakes the hub). */
|
|
216
|
+
export declare function hubAccounts(info: HubInfo, timeoutMs?: number): Promise<HubAccount[]>;
|
|
217
|
+
/** Whether the hub answers /healthz through its callback URL, and the edge's reason when it does not. */
|
|
218
|
+
export declare function hubHealth(info: HubInfo, timeoutMs?: number): Promise<{
|
|
219
|
+
ok: boolean;
|
|
220
|
+
reason: string | null;
|
|
221
|
+
}>;
|
|
222
|
+
export interface ImportOptions {
|
|
223
|
+
values?: Values;
|
|
224
|
+
/** What was found on this computer (detectLocalCliProxy() when omitted). */
|
|
225
|
+
local?: LocalCliProxy | null;
|
|
226
|
+
hub?: HubCloud;
|
|
227
|
+
stop?: StopDeps;
|
|
228
|
+
launchd?: LaunchdDeps | false;
|
|
229
|
+
/** Save the hub info into the machine template (default true). */
|
|
230
|
+
machine?: boolean;
|
|
231
|
+
platform?: NodeJS.Platform;
|
|
232
|
+
}
|
|
233
|
+
export interface ImportResult {
|
|
234
|
+
hub: {
|
|
235
|
+
workspace_id: string;
|
|
236
|
+
created: boolean;
|
|
237
|
+
process: EnsureResult['process'];
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* added: accounts this import gave the hub; already: accounts the hub had (its tokens stay); moved_aside: where this
|
|
241
|
+
* computer's auth files went once the hub had them (`<dir>.moved-to-shardflux`).
|
|
242
|
+
*/
|
|
243
|
+
logins: {
|
|
244
|
+
uploaded: string[];
|
|
245
|
+
kept: string[];
|
|
246
|
+
added: Array<{
|
|
247
|
+
provider: string | null;
|
|
248
|
+
email: string | null;
|
|
249
|
+
}>;
|
|
250
|
+
already: Array<{
|
|
251
|
+
provider: string | null;
|
|
252
|
+
email: string | null;
|
|
253
|
+
}>;
|
|
254
|
+
moved_aside: string[];
|
|
255
|
+
};
|
|
256
|
+
/** Whether the hub's config was made from this computer's, or the hub kept the one it has. */
|
|
257
|
+
config: 'from_this_computer' | 'kept';
|
|
258
|
+
local: 'none' | 'stopped';
|
|
259
|
+
/** The port the local CLIProxyAPI listened on; this computer's forwarder serves 8317. */
|
|
260
|
+
port: number;
|
|
261
|
+
forwarder: {
|
|
262
|
+
launchd: string | null;
|
|
263
|
+
};
|
|
264
|
+
/** The machine version that carries the hub info, or why it could not be saved (run the import again). */
|
|
265
|
+
machine: {
|
|
266
|
+
version: number;
|
|
267
|
+
saved: boolean;
|
|
268
|
+
} | {
|
|
269
|
+
error: string;
|
|
270
|
+
} | null;
|
|
271
|
+
dropped: string[];
|
|
272
|
+
accounts: HubAccount[] | null;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Moves CLIProxyAPI from this computer into the account (or connects this computer to the account's hub): ensure the
|
|
276
|
+
* hub from the user's config, stop the local copy, upload the auth files the hub does not have yet (never overwriting
|
|
277
|
+
* one: the hub's copy may hold a newer refresh token), start the forwarder on 127.0.0.1:8317 and put the hub info into
|
|
278
|
+
* the machine template.
|
|
279
|
+
*/
|
|
280
|
+
export declare function importCliProxy(ctx: Ctx, opts?: ImportOptions): Promise<ImportResult>;
|
|
281
|
+
export interface ExportOptions {
|
|
282
|
+
values?: Values;
|
|
283
|
+
hub?: HubCloud;
|
|
284
|
+
launchd?: LaunchdDeps | false;
|
|
285
|
+
platform?: NodeJS.Platform;
|
|
286
|
+
}
|
|
287
|
+
export interface ExportResult {
|
|
288
|
+
/** Where the logins were written (the auth directory the import took them from, else ~/.cli-proxy-api). */
|
|
289
|
+
auth_dir: string;
|
|
290
|
+
logins: string[];
|
|
291
|
+
hub: {
|
|
292
|
+
workspace_id: string;
|
|
293
|
+
state: 'stopped';
|
|
294
|
+
logins_set_aside: string | null;
|
|
295
|
+
};
|
|
296
|
+
forwarder: {
|
|
297
|
+
removed: boolean;
|
|
298
|
+
};
|
|
299
|
+
/** The command that starts the local CLIProxyAPI again. */
|
|
300
|
+
start: string;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Brings the hub's logins back to this computer: the hub stops first (from then on only this computer refreshes
|
|
304
|
+
* them), its auth files as last refreshed are written to the local auth directory (0600), the hub sets its copies
|
|
305
|
+
* aside (a later import uploads this computer's), this computer's forwarder agent goes, and the hub is suspended.
|
|
306
|
+
* Undone by `shard cli-proxy import`.
|
|
307
|
+
*/
|
|
308
|
+
export declare function exportCliProxy(ctx: Ctx, opts?: ExportOptions): Promise<ExportResult>;
|
|
309
|
+
/**
|
|
310
|
+
* After the edge refused the hub's callback URL (`callback_invalid`: the API key that created it was revoked):
|
|
311
|
+
* replaces the URLs the edge refuses (under the hub's lock), saves them locally and gives VMs the new VM address.
|
|
312
|
+
*/
|
|
313
|
+
export declare function renewHubCallbacks(ctx: Ctx, opts?: {
|
|
314
|
+
hub?: HubCloud;
|
|
315
|
+
machine?: MachineAccess;
|
|
316
|
+
}): Promise<{
|
|
317
|
+
info: HubInfo;
|
|
318
|
+
vms: Promise<{
|
|
319
|
+
machine: number | null;
|
|
320
|
+
note: string | null;
|
|
321
|
+
}>;
|
|
322
|
+
}>;
|
|
323
|
+
/** Removes the launchd agent (tests and a future `shard cli-proxy forward --stop`). */
|
|
324
|
+
export declare function removeForwarderAgent(home: string, run?: ProgramRunner, uid?: number): Promise<void>;
|
|
325
|
+
export declare const CLI_PROXY_HANDLERS: Record<string, Handler>;
|