litmus-cli 1.4.28 → 1.4.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/commands/connect.d.ts +349 -7
  2. package/dist/commands/connect.d.ts.map +1 -1
  3. package/dist/commands/connect.js +751 -58
  4. package/dist/commands/connect.js.map +1 -1
  5. package/dist/commands/doctor.d.ts +52 -0
  6. package/dist/commands/doctor.d.ts.map +1 -1
  7. package/dist/commands/doctor.js +76 -7
  8. package/dist/commands/doctor.js.map +1 -1
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +6 -2
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/pause.d.ts +13 -8
  13. package/dist/commands/pause.d.ts.map +1 -1
  14. package/dist/commands/pause.js +18 -10
  15. package/dist/commands/pause.js.map +1 -1
  16. package/dist/commands/push.d.ts.map +1 -1
  17. package/dist/commands/push.js +6 -2
  18. package/dist/commands/push.js.map +1 -1
  19. package/dist/index.js +2 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/lib/api-base.d.ts +80 -0
  22. package/dist/lib/api-base.d.ts.map +1 -1
  23. package/dist/lib/api-base.js +83 -0
  24. package/dist/lib/api-base.js.map +1 -1
  25. package/dist/lib/editor-binary.d.ts +110 -0
  26. package/dist/lib/editor-binary.d.ts.map +1 -0
  27. package/dist/lib/editor-binary.js +72 -0
  28. package/dist/lib/editor-binary.js.map +1 -0
  29. package/dist/lib/editor-ide.d.ts +11 -0
  30. package/dist/lib/editor-ide.d.ts.map +1 -0
  31. package/dist/lib/editor-ide.js +2 -0
  32. package/dist/lib/editor-ide.js.map +1 -0
  33. package/dist/lib/editor-server.d.ts +253 -0
  34. package/dist/lib/editor-server.d.ts.map +1 -0
  35. package/dist/lib/editor-server.js +286 -0
  36. package/dist/lib/editor-server.js.map +1 -0
  37. package/dist/lib/watcher.js +18 -1
  38. package/dist/lib/watcher.js.map +1 -1
  39. package/package.json +1 -1
@@ -1,3 +1,5 @@
1
+ import type { NativeIde } from "../lib/editor-ide.js";
2
+ import { type EditorVersion, type SeedVerdict, type VerifyVerdict, type WorkspaceProbe } from "../lib/editor-server.js";
1
3
  export interface ParsedSsh {
2
4
  user: string;
3
5
  host: string;
@@ -125,8 +127,9 @@ export declare function aliasFor(sshHostname: string | null | undefined, token:
125
127
  *
126
128
  * - `--version` CANNOT tell them apart. Both print exactly three lines — version,
127
129
  * commit, arch — with no product name anywhere ("3.18.25" from the `code` that was
128
- * Cursor). So `hasEditorCli`'s probe is not merely unchecked, it has nothing to
129
- * check, and the version numbers (1.x vs 3.x) are a coincidence, not a contract.
130
+ * Cursor). So `probeEditorCli`'s `--version` read is not merely unchecked as an
131
+ * identity, it has nothing to check, and the version numbers (1.x vs 3.x) are a
132
+ * coincidence, not a contract.
130
133
  * - `--help` line 1 IS the product name: "Visual Studio Code 1.136.1" against
131
134
  * "Cursor 3.18.25", on STDOUT (stderr empty), exit 0, no window, instant. It is
132
135
  * `product.json`'s `nameLong`, which is why the patterns below are anchored prefixes
@@ -139,7 +142,7 @@ export declare function aliasFor(sshHostname: string | null | undefined, token:
139
142
  * exit 0, mapping the Microsoft id onto its own `anysphere.remote-ssh`. So the dead
140
143
  * remote window is version-dependent and the FALSE success line is not.
141
144
  */
142
- export type NativeIde = "vscode" | "cursor";
145
+ export type { NativeIde } from "../lib/editor-ide.js";
143
146
  export interface NativeEditor {
144
147
  /** Which choice this record IS, so a record is self-describing once resolved. */
145
148
  ide: NativeIde;
@@ -161,12 +164,64 @@ export interface NativeEditor {
161
164
  remoteSshExt: string;
162
165
  /** The palette command that puts `bin` on PATH, for the no-CLI fallback. */
163
166
  shellCommand: string;
167
+ /**
168
+ * ENG-2332. The image's pointer at the server build it baked, and the directory in the
169
+ * candidate home that this editor's server lives in. Together they are what
170
+ * `lib/editor-server.ts` reads over the alias: the first answers "will this client find
171
+ * its own build already here", the second "did a server actually come up".
172
+ */
173
+ seedCommitPath: string;
174
+ serverHomeDir: string;
175
+ /**
176
+ * ENG-2332 — whether a PROVEN commit mismatch refuses the launch, or only explains a
177
+ * launch that then failed.
178
+ *
179
+ * It is not symmetric, and the asymmetry is evidence rather than taste. A client whose
180
+ * build the image did not bake has exactly one route to its own server: the mirror
181
+ * (`infra/vscode-mirror/`), which the container reaches and the open internet it does
182
+ * not. VS Code's route is the original one and is validated end to end against both
183
+ * live origins; Cursor's has now failed twice in production — ENG-1936, where the one
184
+ * listed path shape had stopped being the one clients request, and ENG-2332, where a
185
+ * 3.19.13 client asked for nothing at all and opened a dead window.
186
+ *
187
+ * So for Cursor a mismatch is a refusal: the measured outcome is a window that looks
188
+ * normal, is served by a LOCAL extension host, and records nothing, which is the worst
189
+ * thing this product can do to a candidate. For VS Code it is a note kept back and used
190
+ * to explain a failed verification, because refusing there would take away a path that
191
+ * works today on the strength of a fault that has never been seen on it.
192
+ *
193
+ * This flips to `false` for Cursor the day the mirror is measured serving a drifted
194
+ * Cursor client — not before, and not on the strength of it looking like it should.
195
+ */
196
+ requiresSeedMatch: boolean;
164
197
  }
198
+ /**
199
+ * The two editors, and the one place every measured difference between them lives.
200
+ *
201
+ * EXPORTED so the tests drive the SHIPPED record rather than literals they wrote
202
+ * themselves — an assertion against a fixture declared in the test file is a tautology,
203
+ * and `requiresSeedMatch`, `seedCommitPath` and `serverHomeDir` could all have been
204
+ * changed here with every test staying green.
205
+ *
206
+ * `seedCommitPath` and `serverHomeDir` are CROSS-TIER and their drift is silent: the
207
+ * first is `CACHE_ROOT` in `infra/codespaces-v2-image/scripts/install-{vscode,cursor}-
208
+ * server.sh`, the second the home subdir `litmus-firstboot.sh`'s `prewarm_editor` links
209
+ * into. A probe pointed at a path the image no longer writes reads "no seed" and "no
210
+ * logs" — which this module deliberately treats as missing inputs, so the launch
211
+ * proceeds unrefused and the verification stops being able to see a server. Nothing
212
+ * fails; the guarantee just quietly stops existing. `backend/tests/
213
+ * test_editor_server_paths.py` holds the pair, in pytest rather than vitest because the
214
+ * CLI suite is path-filtered on `cli/**` and an image-only edit is exactly the edit that
215
+ * has to fail.
216
+ */
217
+ export declare const NATIVE_EDITORS: Record<NativeIde, NativeEditor>;
165
218
  /**
166
219
  * ENG-2152 — what the editor CLI we are about to drive says it IS.
167
220
  *
168
- * `hasEditorCli` above answers "does this command exist", which is a different and much
169
- * weaker question, and treating the answer as an identity is the whole of this bug: the
221
+ * `resolveEditorCommand` above answers "which command can we run", which is a different
222
+ * and much weaker question `probeEditorCli` establishes only that something at that
223
+ * name ran and printed a version — and treating either answer as an identity is the whole
224
+ * of this bug: the
170
225
  * `code` on a Cursor user's PATH can be Cursor's own CLI, which is literally installed
171
226
  * under that name inside `Cursor.app`. The measurement behind `banner` is in the
172
227
  * `NATIVE_EDITORS` block comment; the three verdicts are what the caller may conclude.
@@ -198,7 +253,7 @@ export type EditorIdentity = {
198
253
  export declare function identifyEditorBanner(helpOutput: string): NativeIde | null;
199
254
  /** How the identity probe reaches the binary. Injected so the verdicts are testable. */
200
255
  export type EditorHelpRunner = (bin: string) => string | null;
201
- export declare function identifyEditorCli(ed: NativeEditor, run?: EditorHelpRunner): EditorIdentity;
256
+ export declare function identifyEditorCli(ed: NativeEditor, command: string, run?: EditorHelpRunner): EditorIdentity;
202
257
  /**
203
258
  * ENG-2152 — the refusal, when the command the candidate's PATH answers with is the
204
259
  * other editor.
@@ -222,6 +277,284 @@ export declare function identifyEditorCli(ed: NativeEditor, run?: EditorHelpRunn
222
277
  * this path is false.
223
278
  */
224
279
  export declare function editorMismatchLines(chosen: NativeEditor, actual: NativeEditor, reentry?: CursorReentry): string[];
280
+ /**
281
+ * ENG-2332 — the refusal when the candidate's editor is a different build from the one
282
+ * this workspace has, and the route to the workspace that still works.
283
+ *
284
+ * It says what was compared and what it means, because "version mismatch" on its own
285
+ * reads as pedantry and a candidate mid-assessment will look for a way round it. What it
286
+ * must never do is offer one: there is no flag, no retry and no "open it anyway" here,
287
+ * since the thing on the other side of that door is a window that looks completely normal
288
+ * and records nothing (`lib/editor-server.ts` carries the measurement).
289
+ *
290
+ * The browser IDE leads, because it is the same container, the same files and the same
291
+ * capture, and it is the one route that cannot have this fault — it is served FROM the
292
+ * workspace rather than fetched INTO it. When the workspace publishes no URL the fallback
293
+ * is the terminal, which is a real way to work and not a consolation.
294
+ */
295
+ export declare function editorSeedMismatchLines(ed: NativeEditor, verdict: Extract<SeedVerdict, {
296
+ kind: "mismatch";
297
+ }>, browserIdeUrl: string | null, alias: string): string[];
298
+ /**
299
+ * ENG-2332 — what to say when the editor CLI cannot be found anywhere.
300
+ *
301
+ * The line this replaces offered `<bin> --remote ssh-remote+<alias> …` as the
302
+ * remediation for `<bin>` not existing. Everything here is something the candidate can do
303
+ * WITHOUT that command: the editor's own Remote-SSH picker (the alias is already in their
304
+ * `~/.ssh/config`), the palette command that would put the CLI on PATH, and the browser
305
+ * IDE, which needs nothing installed at all.
306
+ */
307
+ export declare function editorNotFoundLines(ed: NativeEditor, alias: string, browserIdeUrl: string | null): string[];
308
+ /**
309
+ * ENG-2332 — the positive signal, which the CLI had none of.
310
+ *
311
+ * It states exactly what was verified and not one step more. A server running in the
312
+ * workspace means the window is editing the container's files, so the file, terminal and
313
+ * commit lanes are live — that is what "recorded" may claim here.
314
+ *
315
+ * IT MAY NOT CLAIM AI CAPTURE ON CURSOR, and that is not hedging. Cursor reads its hooks
316
+ * configuration once, at application startup (ENG-1728, measured): a candidate who
317
+ * connected from an already-running Cursor has a live, correct, never-loaded hook, and
318
+ * their prompts are not recorded although everything else is. The verification above
319
+ * cannot see that — a server is up either way — so a flat "your work is being recorded"
320
+ * would be the same false reassurance this ticket is about, moved one lane along. The
321
+ * full notice is printed at selection time; this restates only the dependency.
322
+ */
323
+ export declare function editorConnectedLines(ed: NativeEditor, alias: string): string[];
324
+ /**
325
+ * ENG-2332 — what to say when a window opened and no server came up in the workspace.
326
+ *
327
+ * This is the copy the ticket was opened about. It used to be
328
+ * "If a new window doesn't appear, run litmus connect again" — which is wrong twice: a
329
+ * window DOES appear in this failure, and re-running connect cannot change the state,
330
+ * which is exactly what had the reporter run it four times. So it names what was
331
+ * observed, and every route it offers is one this failure does not block.
332
+ *
333
+ * `seed` rides along because on VS Code a mismatch is not a refusal (see
334
+ * `requiresSeedMatch`) — so when a VS Code launch does fail, the build difference is the
335
+ * first thing worth knowing, and it is already in hand.
336
+ *
337
+ * WHAT IT MAY NOT SAY IS THAT NOTHING WILL CHANGE. That is what it said first, and it is
338
+ * a claim about the future made on a reading that stops at the verification budget. A VS
339
+ * Code client whose build the image did not bake is NOT refused (`requiresSeedMatch`), so
340
+ * its launch legitimately goes on to fetch a server through the mirror — a ~28.6 MB CLI
341
+ * and, on a prewarm miss, the whole bundle — and a slow link can still be fetching when
342
+ * the budget runs out. Telling that candidate their window is dead and pointing them
343
+ * elsewhere is the harm `unverified` exists to avoid, arriving on the branch below it.
344
+ * So it states the bound it actually waited (derived from `VERIFY_SCHEDULE_MS`, never a
345
+ * second hard-coded copy), says the window may yet attach, and offers the other two
346
+ * routes rather than instructing an exit. What it still may not do is tell them to re-run
347
+ * this command, which is the original bug.
348
+ *
349
+ * AND IT MAY NOT HAND THEM A CHECK THAT PASSES ON THE DEAD WINDOW. It pointed at the
350
+ * remote indicator — "the bottom-left corner reads SSH: <alias>" — and this repo has
351
+ * measured that indicator PRESENT in exactly the failure case: `lib/editor-server.ts`'s
352
+ * header records the never-attached window carrying `"remoteAuthority":
353
+ * "ssh-remote+<alias>"` and being indistinguishable from a working one, and
354
+ * `lib/session-end.ts` records (ENG-2154) that a window whose transport is gone still
355
+ * reads `[SSH: <host>]`. A candidate told to look at the corner sees what they were told
356
+ * to look for and goes on working unrecorded, which is this ticket's own bug re-entering
357
+ * through its remediation. The honest sentence is that the two windows look the same —
358
+ * that is WHY the CLI checks — so the copy says so and names no visual test at all.
359
+ */
360
+ export declare function editorNotConnectedLines(ed: NativeEditor, alias: string, browserIdeUrl: string | null, seed: SeedVerdict, launchLog: string | null): string[];
361
+ /**
362
+ * ENG-2332 — what to say when the editor never started at all.
363
+ *
364
+ * THIS BRANCH EXISTS BECAUSE THE ONE ABOVE MUST NOT BE REACHABLE WITHOUT A WINDOW.
365
+ * `editorNotConnectedLines` opens by stating, as a fact, that a window is on screen and
366
+ * running against the candidate's own machine; when `spawn` itself fails that sentence is
367
+ * false, and the reading the verification produces is identical either way (no server,
368
+ * empty launch log). So the spawn error is recorded (`EditorLaunchHandle`) and routed
369
+ * here instead, where the only claim made is the one we can support.
370
+ *
371
+ * It offers the same two routes and, like every other failure branch, offers rather than
372
+ * instructs: there is no window to close, and re-running this command is the remediation
373
+ * the ticket was opened about. The error text is carried verbatim because it is the whole
374
+ * of what we know — `ENOENT` on a resolved path means the app moved or was removed since
375
+ * the `--version` probe a moment earlier, which is a thing the candidate can act on and
376
+ * we cannot diagnose for them.
377
+ */
378
+ export declare function editorLaunchFailedLines(ed: NativeEditor, alias: string, browserIdeUrl: string | null, error: string, launchLog: string | null): string[];
379
+ /**
380
+ * ENG-2332 — what to say when we could not reach the workspace to ask at all.
381
+ *
382
+ * Three-valued on purpose: "we could not check" is not "nothing came up", and saying
383
+ * either of the other two here would be a claim we cannot make. It lives beside the other
384
+ * copy rather than inline in `runConnect` so that what it may and may not say is testable
385
+ * — it is bound by the same rule as `editorNotConnectedLines` and broke it the same way.
386
+ *
387
+ * It may NOT tell the candidate to look at the remote indicator. That indicator is
388
+ * rendered from the remote authority, which the never-attached window carries (see
389
+ * `lib/editor-server.ts`'s header, and ENG-2154 in `lib/session-end.ts`), so the check
390
+ * passes in exactly the case it was offered to detect. It states the ambiguity instead
391
+ * and offers the two routes that are not in doubt.
392
+ */
393
+ export declare function editorUnverifiedLines(ed: NativeEditor, alias: string, browserIdeUrl: string | null): string[];
394
+ /**
395
+ * ENG-2332 — where the editor's own output goes.
396
+ *
397
+ * It used to go to `stdio: "ignore"`, which is the mechanical half of this ticket: a
398
+ * resolver that cannot fetch its server writes its reason here and nowhere else, so
399
+ * discarding it leaves exit code 0, an empty terminal and a dead window as the entire
400
+ * record of the failure.
401
+ *
402
+ * A FILE and not a pipe, and that is not a style choice. The child is `detached` and
403
+ * outlives this process by design; a pipe belongs to the parent, so once `litmus connect`
404
+ * returns the editor would be writing into a closed pipe and could take an EPIPE for it.
405
+ * A file descriptor on a real file has neither problem, survives our exit, and is still
406
+ * here when a candidate is asked for it.
407
+ *
408
+ * THE NAME IS PER RUN, and both reasons are real. `os.tmpdir()` is a shared `/tmp` on a
409
+ * Linux box with no `TMPDIR`, so a fixed name is a name another local user can create
410
+ * first — and `openSync(path, "w")` FOLLOWS a symlink and TRUNCATES, so a link planted
411
+ * there redirects the editor's output into, or empties, a file of theirs. And two
412
+ * `litmus connect` runs on one machine would otherwise share the file, so a candidate
413
+ * being walked through one failure can be shown the other run's output. The pid plus a
414
+ * random suffix answers both; `openEditorLaunchLog` then refuses to follow a link or to
415
+ * reuse an existing name, so an attacker who guesses one gets nothing rather than a
416
+ * write.
417
+ */
418
+ export declare function editorLaunchLogPath(): string;
419
+ /**
420
+ * Open the launch log for the child, or answer null when we cannot do it safely.
421
+ *
422
+ * `O_EXCL | O_NOFOLLOW` is the whole point: EXCL means an existing name — planted or
423
+ * left over — is refused rather than written into, and NOFOLLOW means a symlink at that
424
+ * name is refused rather than followed to its target. Neither is reachable in the
425
+ * ordinary case, since the name carries a random suffix; they are what makes the
426
+ * ordinary case's safety a property of the open rather than of the name being unguessed.
427
+ * A refusal costs the diagnostics from one launch and never the launch.
428
+ */
429
+ export declare function openEditorLaunchLog(logPath: string): number | null;
430
+ /**
431
+ * A launch in flight. The one thing it can say is whether the spawn itself failed.
432
+ *
433
+ * THAT IS THE ONLY SIGNAL SEPARATING "A WINDOW OPENED AND DID NOT ATTACH" FROM "NO
434
+ * WINDOW OPENED AT ALL", and it used to be thrown away. `child.on("error", () => {})`
435
+ * carried the comment "reported through the verification below", which was false: the
436
+ * verification reads the WORKSPACE, so all it can ever report is that no server came up
437
+ * — the same reading a spawn that never happened produces, down to the empty launch log.
438
+ * `editorNotConnectedLines` then told the candidate that "a <label> window is on screen
439
+ * and it is NOT attached to your workspace", and built a whole paragraph around a window
440
+ * that had never been created. That is the same class of unverifiable claim this ticket
441
+ * exists to remove, pointed the other way, so the error is recorded and the failure it
442
+ * describes gets its own outcome.
443
+ *
444
+ * It is a READER rather than a value because `spawn` reports this asynchronously: the
445
+ * error arrives on a later tick, so anything reading it must do so after an await. The
446
+ * handler itself still has to exist for the reason it always did — an unhandled `error`
447
+ * event on a ChildProcess is an uncaught exception that would take `connect` down.
448
+ */
449
+ export interface EditorLaunchHandle {
450
+ launchFailure: () => string | null;
451
+ }
452
+ /**
453
+ * ENG-2332, Greptile P1 on #2442 — ON WINDOWS THE `error` EVENT IS NOT THE FAILURE.
454
+ *
455
+ * `editorSpawnSpec` gives every Windows launch `shell: true`, so what `spawn` starts is
456
+ * `cmd.exe`, not the editor. `cmd.exe` starts fine essentially always — a missing `.cmd`,
457
+ * a path that stopped resolving, an editor that refuses its own argv are all reported by
458
+ * cmd.exe EXITING non-zero, not by an `error` event. So a handle watching only `error`
459
+ * reports "the window opened" for every one of them, which collapses the whole
460
+ * spawn-failed / opened-but-unattached distinction back into the wrong branch on exactly
461
+ * the platform the resolution work was added for.
462
+ *
463
+ * A NON-ZERO EXIT IS THEREFORE A LAUNCH FAILURE, and a zero exit is not. Both editors'
464
+ * CLIs return immediately after handing the argv to an already-running instance, so an
465
+ * ordinary successful launch exits 0 within moments and the process being gone says
466
+ * nothing. That asymmetry is what makes the exit code readable at all.
467
+ *
468
+ * The listeners outlive `unref()`: it stops the child holding the event loop open, and we
469
+ * are awaiting the verification anyway, so an exit inside the window still reaches us.
470
+ * Whichever signal arrives first wins and neither overwrites the other, because both
471
+ * describe the same thing — no window was created — and the first is the more specific.
472
+ */
473
+ export declare function launchEditor(ed: NativeEditor, command: string, alias: string, logPath: string): EditorLaunchHandle;
474
+ /**
475
+ * Point at the editor's own output. `namePath` is for the branch where a human is
476
+ * walking a candidate through a failure: there the file is named whether or not
477
+ * `--verbose` was asked for, since `editorLaunchLogPath` gives it a per-run suffix that
478
+ * nobody can guess unaided.
479
+ *
480
+ * A PATH IS NAMED ONLY WHEN THERE IS SOMETHING AT IT, and the reason is that the file
481
+ * routinely does not exist. `launchEditor` falls back to `stdio: "ignore"` whenever
482
+ * `openEditorLaunchLog` refuses — an unwritable tmpdir, or its own `O_EXCL`/`O_NOFOLLOW`
483
+ * refusal — and even on the ordinary path the measured failure is an editor that exits 0
484
+ * and prints nothing, so an empty file is the common case rather than the odd one.
485
+ * Handing a support person a path with nothing behind it reads as the CLI having lost
486
+ * the log, which is a worse answer than saying plainly that the editor wrote nothing.
487
+ */
488
+ export declare function editorLaunchOutputLines(logPath: string, launchLog: string | null, verbose: boolean, namePath: boolean): string[];
489
+ /**
490
+ * ENG-2332 — one reading of the workspace, over the alias we have just written.
491
+ *
492
+ * `BatchMode=yes` so a key that needs a passphrase, or a host key we somehow did not
493
+ * accept, fails in seconds instead of blocking the CLI on a prompt nobody is watching
494
+ * for. Every failure answers null, which every caller reads as "we could not tell" and
495
+ * never as "there is no server" — see `verifyVerdict`.
496
+ */
497
+ export type WorkspaceProbeRunner = (remoteCommand: string) => string | null;
498
+ export declare function verifyEditorAttached(ed: NativeEditor, baseline: WorkspaceProbe | null, run: WorkspaceProbeRunner, onWait: (secondsWaited: number) => void, launched: EditorLaunchHandle): Promise<VerifyVerdict>;
499
+ /** Whether the editor's Remote-SSH extension was already there, put there, or could not be. */
500
+ export type RemoteSshExtensionState = "present" | "installed" | "failed";
501
+ /**
502
+ * ENG-2332 — the launch sequence itself, with every side effect injected.
503
+ *
504
+ * It exists as a unit because the ORDER is the guarantee, and order is not something the
505
+ * pieces can hold on their own: `seedVerdict` and `verifyVerdict` are each correct in
506
+ * isolation while a flow that installs an extension before the refusal, or takes its
507
+ * baseline after the spawn, or prints a success between the two, is the bug back. Those
508
+ * were first held by reading `connect.ts` and matching strings in it, which goes green
509
+ * for the wrong reasons — a rename breaks it and a genuinely reordered flow can still
510
+ * satisfy it. Here they are properties of what this function DOES, so the test drives it
511
+ * with recording doubles and reads the calls off them.
512
+ *
513
+ * Four things are therefore structural rather than conventional. A refused mismatch
514
+ * returns before `ensureExtension` or `launch` is reached, so "nothing was opened" is
515
+ * observable. `baseline` is taken from the probe before `launch` is called, so the
516
+ * verification is always comparing against a reading older than the spawn. The only
517
+ * success this can report is the one `verifyAttached` answered with, so there is no seam
518
+ * between the spawn and the verdict for a premature claim to live in — the caller renders
519
+ * `result.verdict` and has nothing else to render. And a spawn that FAILED returns its
520
+ * own `launch-failed` kind, which carries no `verdict` at all: the copy describing a
521
+ * window on screen is then unreachable by construction rather than by the caller
522
+ * remembering to check, which is what `EditorLaunchHandle` above exists for.
523
+ */
524
+ export interface EditorLaunchIo {
525
+ /** One reading of the workspace, for the seed check and as the verification's baseline. */
526
+ probe: (ed: NativeEditor) => WorkspaceProbe | null;
527
+ /** What the client says it is. Already in hand from the resolution — see `resolveEditorCommand`. */
528
+ clientVersion: EditorVersion;
529
+ ensureExtension: () => RemoteSshExtensionState;
530
+ /** A fresh, per-run path for the editor's own output. */
531
+ launchLogPath: () => string;
532
+ launch: (logPath: string) => EditorLaunchHandle;
533
+ readLaunchLog: (logPath: string) => string | null;
534
+ verifyAttached: (baseline: WorkspaceProbe | null, launched: EditorLaunchHandle) => Promise<VerifyVerdict>;
535
+ }
536
+ export type EditorLaunchResult = {
537
+ kind: "refused";
538
+ reason: "seed-mismatch";
539
+ seed: Extract<SeedVerdict, {
540
+ kind: "mismatch";
541
+ }>;
542
+ } | {
543
+ kind: "launch-failed";
544
+ seed: SeedVerdict;
545
+ extension: RemoteSshExtensionState;
546
+ error: string;
547
+ logPath: string;
548
+ launchLog: string | null;
549
+ } | {
550
+ kind: "launched";
551
+ seed: SeedVerdict;
552
+ extension: RemoteSshExtensionState;
553
+ verdict: VerifyVerdict;
554
+ logPath: string;
555
+ launchLog: string | null;
556
+ };
557
+ export declare function attemptEditorLaunch(ed: NativeEditor, io: EditorLaunchIo): Promise<EditorLaunchResult>;
225
558
  export type IdeChoice = "vscode" | "cursor" | "browser" | "ssh";
226
559
  /**
227
560
  * Resolve which editor to open: an explicit --ide flag wins; otherwise prompt.
@@ -392,5 +725,14 @@ export declare function chatConfigActionForIdentity(ide: IdeChoice, state: "conf
392
725
  * branch it claims to describe.
393
726
  */
394
727
  export declare function browserFallback(hasUrl: boolean, ideWasChosen: boolean): "browser" | "vscode" | "unavailable";
395
- export declare function runConnect(token: string, ideOpt?: string): Promise<void>;
728
+ export interface ConnectOptions {
729
+ /**
730
+ * ENG-2332 item 4 — print what the editor wrote while opening, and where that log is.
731
+ * The output is CAPTURED either way (a failed verification prints its tail whether or
732
+ * not this is set); this is for the case where the candidate is being walked through a
733
+ * problem by a human and everything looks fine from here.
734
+ */
735
+ verbose?: boolean;
736
+ }
737
+ export declare function runConnect(token: string, ideOpt?: string, opts?: ConnectOptions): Promise<void>;
396
738
  //# sourceMappingURL=connect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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"}