litmus-cli 1.4.92 → 1.4.94

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 (95) hide show
  1. package/README.md +48 -0
  2. package/dist/commands/connect.d.ts +6 -2
  3. package/dist/commands/connect.d.ts.map +1 -1
  4. package/dist/commands/connect.js +222 -35
  5. package/dist/commands/connect.js.map +1 -1
  6. package/dist/commands/forward.d.ts +7 -1
  7. package/dist/commands/forward.d.ts.map +1 -1
  8. package/dist/commands/forward.js +8 -7
  9. package/dist/commands/forward.js.map +1 -1
  10. package/dist/commands/init.d.ts.map +1 -1
  11. package/dist/commands/init.js +12 -2
  12. package/dist/commands/init.js.map +1 -1
  13. package/dist/lib/ai-tracking.d.ts +8 -0
  14. package/dist/lib/ai-tracking.d.ts.map +1 -1
  15. package/dist/lib/ai-tracking.js +96 -1
  16. package/dist/lib/ai-tracking.js.map +1 -1
  17. package/dist/lib/connect-skills.d.ts +1 -0
  18. package/dist/lib/connect-skills.d.ts.map +1 -1
  19. package/dist/lib/connect-skills.js +1 -1
  20. package/dist/lib/connect-skills.js.map +1 -1
  21. package/dist/lib/desktop-readiness.d.ts +9 -0
  22. package/dist/lib/desktop-readiness.d.ts.map +1 -0
  23. package/dist/lib/desktop-readiness.js +131 -0
  24. package/dist/lib/desktop-readiness.js.map +1 -0
  25. package/dist/lib/editor-foreground.d.ts +6 -0
  26. package/dist/lib/editor-foreground.d.ts.map +1 -0
  27. package/dist/lib/editor-foreground.js +38 -0
  28. package/dist/lib/editor-foreground.js.map +1 -0
  29. package/dist/lib/environment-checks.d.ts +2 -0
  30. package/dist/lib/environment-checks.d.ts.map +1 -1
  31. package/dist/lib/environment-checks.js +4 -2
  32. package/dist/lib/environment-checks.js.map +1 -1
  33. package/dist/lib/file-monitor.d.ts +18 -0
  34. package/dist/lib/file-monitor.d.ts.map +1 -0
  35. package/dist/lib/file-monitor.js +87 -0
  36. package/dist/lib/file-monitor.js.map +1 -0
  37. package/dist/lib/hosted-capture.d.ts +1 -1
  38. package/dist/lib/hosted-capture.d.ts.map +1 -1
  39. package/dist/lib/hosted-capture.js +22 -12
  40. package/dist/lib/hosted-capture.js.map +1 -1
  41. package/dist/lib/init-location.d.ts +4 -0
  42. package/dist/lib/init-location.d.ts.map +1 -0
  43. package/dist/lib/init-location.js +36 -0
  44. package/dist/lib/init-location.js.map +1 -0
  45. package/dist/lib/installed-tools.d.ts +29 -0
  46. package/dist/lib/installed-tools.d.ts.map +1 -0
  47. package/dist/lib/installed-tools.js +159 -0
  48. package/dist/lib/installed-tools.js.map +1 -0
  49. package/dist/lib/portal-launcher-background.d.ts +13 -0
  50. package/dist/lib/portal-launcher-background.d.ts.map +1 -0
  51. package/dist/lib/portal-launcher-background.js +51 -0
  52. package/dist/lib/portal-launcher-background.js.map +1 -0
  53. package/dist/lib/portal-launcher-worker.d.ts +2 -0
  54. package/dist/lib/portal-launcher-worker.d.ts.map +1 -0
  55. package/dist/lib/portal-launcher-worker.js +43 -0
  56. package/dist/lib/portal-launcher-worker.js.map +1 -0
  57. package/dist/lib/portal-launcher.d.ts +43 -0
  58. package/dist/lib/portal-launcher.d.ts.map +1 -0
  59. package/dist/lib/portal-launcher.js +408 -0
  60. package/dist/lib/portal-launcher.js.map +1 -0
  61. package/dist/lib/prepared-desktop.d.ts +7 -0
  62. package/dist/lib/prepared-desktop.d.ts.map +1 -0
  63. package/dist/lib/prepared-desktop.js +35 -0
  64. package/dist/lib/prepared-desktop.js.map +1 -0
  65. package/dist/lib/prepared-editor.d.ts +26 -0
  66. package/dist/lib/prepared-editor.d.ts.map +1 -0
  67. package/dist/lib/prepared-editor.js +150 -0
  68. package/dist/lib/prepared-editor.js.map +1 -0
  69. package/dist/lib/schemas.d.ts +1 -0
  70. package/dist/lib/schemas.d.ts.map +1 -1
  71. package/dist/lib/schemas.js +2 -0
  72. package/dist/lib/schemas.js.map +1 -1
  73. package/dist/lib/ssh-client.d.ts +12 -0
  74. package/dist/lib/ssh-client.d.ts.map +1 -1
  75. package/dist/lib/ssh-client.js +1 -1
  76. package/dist/lib/ssh-client.js.map +1 -1
  77. package/dist/lib/ssh-config-file.d.ts +3 -0
  78. package/dist/lib/ssh-config-file.d.ts.map +1 -1
  79. package/dist/lib/ssh-config-file.js +42 -0
  80. package/dist/lib/ssh-config-file.js.map +1 -1
  81. package/dist/lib/tracker.d.ts +1 -0
  82. package/dist/lib/tracker.d.ts.map +1 -1
  83. package/dist/lib/tracker.js +4 -2
  84. package/dist/lib/tracker.js.map +1 -1
  85. package/dist/lib/vscode-server-preparation.d.ts +7 -0
  86. package/dist/lib/vscode-server-preparation.d.ts.map +1 -0
  87. package/dist/lib/vscode-server-preparation.js +78 -0
  88. package/dist/lib/vscode-server-preparation.js.map +1 -0
  89. package/dist/lib/watcher.js +98 -77
  90. package/dist/lib/watcher.js.map +1 -1
  91. package/dist/lib/workspace-start-wait.d.ts +23 -0
  92. package/dist/lib/workspace-start-wait.d.ts.map +1 -0
  93. package/dist/lib/workspace-start-wait.js +50 -0
  94. package/dist/lib/workspace-start-wait.js.map +1 -0
  95. package/package.json +1 -1
package/README.md CHANGED
@@ -80,6 +80,52 @@ as `litmus push <token>` with the token from your assessment page. Either way it
80
80
  captures the workspace exactly as it stands, so there is nothing to commit or push
81
81
  first. The Submit button on your assessment page does the same thing.
82
82
 
83
+ Run `litmus connect <token>` on your laptop. It prepares
84
+ SSH, finds installed editors and desktop agents, then opens the assessment page.
85
+ The page's **Your tools** launcher enables the supported applications it finds;
86
+ you can open several tools against the same remote workspace. No local workspace
87
+ copy is created. Only tool identifiers and dispatch results are reported, not
88
+ application paths or process lists. After setup, the launcher runs in a detached
89
+ background process, so you can close the terminal. It stops when the assessment
90
+ ends, another connection replaces it, or its server authorization is lost (with
91
+ a 24-hour maximum lifetime). Run `litmus connect` again to reconnect. It does not
92
+ install an OS service or restart at login. Credentials are handed to the process
93
+ over IPC and are not written to a launcher settings or log file. Stopping the
94
+ launcher does not stop the workspace or submit your work.
95
+
96
+ The launcher waits for commands using outbound HTTP long polls (up to 25 seconds).
97
+ A committed launch wakes the request through PostgreSQL notifications; saved
98
+ commands recover missed notifications and interrupted connections. No incoming
99
+ laptop port is opened. Older backends retain five-second polling. Installed-app
100
+ discovery refreshes about every 30 seconds, separately from command delivery.
101
+
102
+ When capacity is full, connect reports that it is waiting for an available
103
+ workspace and retries allocation with backoff for up to two minutes. Once an
104
+ allocation starts, it only checks readiness. The portal distinguishes terminal
105
+ prompts, capacity waits, workspace startup and tool checks, and retains the last
106
+ known stage through a temporary polling failure.
107
+
108
+ VS Code and Cursor reuse the existing Remote-SSH setup and attachment checks.
109
+ Desktop buttons stay disabled if the app lacks its URI handler, Claude is older
110
+ than its supported SSH-link version, or the remote runtime/recording capability
111
+ probe fails. The page distinguishes an app update from a workspace setup problem.
112
+ The OS opener's exit status is checked; dispatch is not proof of an attached session.
113
+ Codex Desktop receives the SSH host, `/home/candidate/workspace`, and a request
114
+ to enable the connection and open that remote project automatically. Complete any
115
+ sign-in or trust prompt in Codex. Older versions may still require enabling the
116
+ host and selecting the folder manually. Claude Desktop receives the SSH host and
117
+ the same remote folder, then requires its own confirmation before using them
118
+ (requires SSH-link support, 2.110.0+). The portal reports **Open request sent** for
119
+ Codex and **Confirm in the app** for Claude, never an unverified claim that code
120
+ is saving.
121
+ Terminal / SSH opens a remote shell where you can run `claude` or `codex`.
122
+ The portal also retains manual connection instructions and its browser route.
123
+ Explicit `--ide vscode`, `--ide cursor`, `--ide ssh`, and `--ide browser` preserve
124
+ their existing behavior. On Linux, desktop-agent discovery is not yet supported;
125
+ PATH and known editor installations plus supported terminal launchers are detected.
126
+ Windows desktop discovery covers conventional installer locations; Store and
127
+ portable installations may require the manual route.
128
+
83
129
  `litmus connect` also asks permission to record supported local AI-agent prompts
84
130
  and responses across folders during the assessment, alongside hosted capture.
85
131
  A background capture watcher stays on your computer after connect returns. It
@@ -328,3 +374,5 @@ The bundled Litmus companion is installed for this handoff. If it is unavailable
328
374
  continue in the IDE and open Agents Window manually. Submission cleanup remains
329
375
  opt-in with `--cursor-session-cleanup`; it disconnects the ended IDE and removes
330
376
  its Open Recent entry, but does not delete saved chats or Agents sidebar entries.
377
+
378
+ The default portal launcher reports connection preparation before workspace startup. The portal shows an indeterminate progress bar until the workspace is ready; preparation sessions expire if the CLI stops unexpectedly.
@@ -1,3 +1,4 @@
1
+ import { type PreparedLauncher } from "../lib/portal-launcher-background.js";
1
2
  import { ConnectionAttempt } from "../lib/connection-attempt.js";
2
3
  import { type ResolvedEditorCommand } from "../lib/editor-binary.js";
3
4
  import type { NativeIde } from "../lib/editor-ide.js";
@@ -53,7 +54,7 @@ export declare function parseSshCommand(cmd: string): ParsedSsh;
53
54
  * copy here is what applies when there is nothing global to lose to, and keeps this
54
55
  * block correct on its own.
55
56
  */
56
- export declare function buildSshConfigBlock(alias: string, keyPath: string, p: ParsedSsh, platform?: NodeJS.Platform): string;
57
+ export declare function buildSshConfigBlock(alias: string, keyPath: string, p: ParsedSsh, platform?: NodeJS.Platform, launcherObserve?: boolean): string;
57
58
  /**
58
59
  * ENG-2681 — an ssh_config argument, quoted so a space cannot split it.
59
60
  *
@@ -499,6 +500,7 @@ export declare function openEditorLaunchLog(logPath: string): number | null;
499
500
  */
500
501
  export interface EditorLaunchHandle {
501
502
  launchFailure: () => string | null;
503
+ waitForDispatch?: () => Promise<void>;
502
504
  }
503
505
  /**
504
506
  * ENG-3217: Windows Cursor 3.24.9 accepts --remote but routes it to the local
@@ -535,7 +537,7 @@ export declare function editorLaunchPlan(ed: NativeEditor, alias: string, platfo
535
537
  * Whichever signal arrives first wins and neither overwrites the other, because both
536
538
  * describe the same thing — no window was created — and the first is the more specific.
537
539
  */
538
- export declare function launchEditor(ed: NativeEditor, command: string, alias: string, logPath: string): EditorLaunchHandle;
540
+ export declare function launchEditor(ed: NativeEditor, command: string, alias: string, logPath: string, foreground?: boolean): EditorLaunchHandle;
539
541
  /**
540
542
  * Point at the editor's own output, under `--verbose` only (ENG-2890: the failure copy
541
543
  * says "Details: add --verbose." instead of printing a path by default).
@@ -787,4 +789,6 @@ export interface TunnelSession {
787
789
  attempt: ConnectionAttempt;
788
790
  }
789
791
  export declare function runConnect(tokenArg: string | undefined, ideOpt?: string, opts?: ConnectOptions): Promise<void>;
792
+ /** Used only by the detached launcher after the interactive setup has completed. */
793
+ export declare function runPreparedPortalLauncher(context: PreparedLauncher, onReady: () => void, signal: AbortSignal): Promise<void>;
790
794
  //# 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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"}
@@ -1,14 +1,24 @@
1
+ import { configureClaudeDesktopConnection, removeClaudeDesktopConnection } from "../lib/ai-tracking.js";
2
+ import { waitForWorkspace } from "../lib/workspace-start-wait.js";
3
+ import { startBackgroundLauncher } from "../lib/portal-launcher-background.js";
4
+ import { desktopRuntimeReady } from "../lib/desktop-readiness.js";
5
+ import { startPortalPreparation, runPortalLauncher, openDesktop, openTerminal, openNativeEditor } from "../lib/portal-launcher.js";
1
6
  import { startHostedCapture } from "../lib/hosted-capture.js";
2
7
  import { installSshForwardHook } from "../lib/install-ssh-forward-hook.js";
3
8
  import { runSsh } from "./ssh.js";
4
9
  import { cursorSessionOptions, prepareCursorSession } from "../lib/cursor-session.js";
5
10
  import { ConnectionAttempt } from "../lib/connection-attempt.js";
11
+ import { editorAppBundle, waitForEditorDispatch } from "../lib/editor-foreground.js";
12
+ import { createPreparedEditorLauncher, parseWorkspaceGeneration } from "../lib/prepared-editor.js";
13
+ import { createPreparedDesktopReadiness } from "../lib/prepared-desktop.js";
14
+ import { findInstalledExecutable } from "../lib/installed-tools.js";
15
+ import { prepareVscodeServer } from "../lib/vscode-server-preparation.js";
6
16
  import { closedState } from "../lib/session-state.js";
7
- import { updateSshConfig } from "../lib/ssh-config-file.js";
17
+ import { updateSshConfig, prepareSshConfigCleanup } from "../lib/ssh-config-file.js";
8
18
  import os from "os";
9
19
  import path from "path";
10
20
  import readline from "readline";
11
- import { closeSync, constants, existsSync, mkdirSync, openSync, readFileSync } from "fs";
21
+ import { closeSync, constants, existsSync, mkdirSync, openSync, readFileSync, realpathSync } from "fs";
12
22
  import { randomBytes } from "crypto";
13
23
  import { execFileSync, spawn, spawnSync } from "child_process";
14
24
  import chalk from "chalk";
@@ -136,7 +146,7 @@ export function parseSshCommand(cmd) {
136
146
  * copy here is what applies when there is nothing global to lose to, and keeps this
137
147
  * block correct on its own.
138
148
  */
139
- export function buildSshConfigBlock(alias, keyPath, p, platform = process.platform) {
149
+ export function buildSshConfigBlock(alias, keyPath, p, platform = process.platform, launcherObserve = false) {
140
150
  const common = [
141
151
  ` IdentityFile ${quoteConfigArg(keyPath)}`,
142
152
  ` IdentitiesOnly yes`,
@@ -146,10 +156,10 @@ export function buildSshConfigBlock(alias, keyPath, p, platform = process.platfo
146
156
  const out = [CONNECT_BEGIN(alias)];
147
157
  if (p.jumpHost) {
148
158
  const bastionAlias = `${alias}-bastion`;
149
- out.push(`Host ${bastionAlias}`, ` HostName ${p.jumpHost}`, ` Port ${p.jumpPort ?? "22"}`, ` User ${p.jumpUser}`, ...common, "", `Host ${alias}`, ` HostName ${p.host}`, ` User ${p.user}`, ` ProxyJump ${bastionAlias}`, ...common);
159
+ out.push(`Host ${bastionAlias}`, ` HostName ${p.jumpHost}`, ` Port ${p.jumpPort ?? "22"}`, ` User ${p.jumpUser}`, ...common, "", `Host ${alias}`, ` HostName ${p.host}`, ` User ${p.user}`, ` ProxyJump ${bastionAlias}`, ...(launcherObserve ? [` IgnoreUnknown SetEnv`, ` SetEnv LITMUS_LAUNCHER_OBSERVE=1`] : []), ...common);
150
160
  }
151
161
  else {
152
- out.push(`Host ${alias}`, ` HostName ${p.host}`, ` User ${p.user}`, ...(p.port ? [` Port ${p.port}`] : []), ...common);
162
+ out.push(`Host ${alias}`, ` HostName ${p.host}`, ` User ${p.user}`, ...(p.port ? [` Port ${p.port}`] : []), ...(launcherObserve ? [` IgnoreUnknown SetEnv`, ` SetEnv LITMUS_LAUNCHER_OBSERVE=1`] : []), ...common);
153
163
  }
154
164
  out.push(CONNECT_END(alias));
155
165
  return out.join("\n") + "\n";
@@ -829,7 +839,7 @@ export function editorLaunchPlan(ed, alias, platform = process.platform) {
829
839
  * Whichever signal arrives first wins and neither overwrites the other, because both
830
840
  * describe the same thing — no window was created — and the first is the more specific.
831
841
  */
832
- export function launchEditor(ed, command, alias, logPath) {
842
+ export function launchEditor(ed, command, alias, logPath, foreground = false) {
833
843
  const spec = editorSpawnSpec(command, editorLaunchPlan(ed, alias).args, process.platform);
834
844
  if (!spec) {
835
845
  // No argv drives this command here, so nothing was started and nothing will be. This
@@ -870,8 +880,20 @@ export function launchEditor(ed, command, alias, logPath) {
870
880
  else if (code !== null && code !== 0)
871
881
  record(`${ed.label} exited immediately with code ${code}`);
872
882
  });
883
+ // The remote server can already be attached, so verification alone may finish
884
+ // before the local CLI has selected its window. Keep the helper alive through
885
+ // dispatch, then activate that installation (never reuse an unrelated window).
886
+ const bundle = foreground && process.platform === "darwin" ? editorAppBundle(command) : null;
887
+ const dispatched = bundle ? waitForEditorDispatch(child, () => {
888
+ try {
889
+ execFileSync("/usr/bin/open", ["-a", bundle], { timeout: 3000, stdio: "ignore" });
890
+ }
891
+ catch {
892
+ // Activation is best effort; a successful editor open remains usable.
893
+ }
894
+ }) : Promise.resolve();
873
895
  child.unref();
874
- return { launchFailure: () => failure };
896
+ return { launchFailure: () => failure, waitForDispatch: () => dispatched };
875
897
  }
876
898
  /**
877
899
  * Point at the editor's own output, under `--verbose` only (ENG-2890: the failure copy
@@ -991,6 +1013,7 @@ export async function attemptEditorLaunch(ed, io) {
991
1013
  const logPath = io.launchLogPath();
992
1014
  const launched = io.launch(logPath);
993
1015
  const verdict = await io.verifyAttached(baseline, launched);
1016
+ await launched.waitForDispatch?.();
994
1017
  const launchLog = io.readLaunchLog(logPath);
995
1018
  // Read AFTER the await, never before it: `spawn` reports this on a later tick, so a
996
1019
  // check taken at the call site would still be null for a launch that had already
@@ -1121,6 +1144,9 @@ export function shouldResendCursorOpen(ide, startedFresh, waitedSeconds, resend)
1121
1144
  export function resendableLaunch(launch) {
1122
1145
  const sent = [];
1123
1146
  const handle = {
1147
+ waitForDispatch: async () => {
1148
+ await Promise.all(sent.map((s) => s.handle.waitForDispatch?.()));
1149
+ },
1124
1150
  launchFailure: () => {
1125
1151
  const failures = sent.map((s) => s.handle.launchFailure());
1126
1152
  return failures.length > 0 && failures.every((f) => f !== null) ? failures[failures.length - 1] : null;
@@ -1277,7 +1303,7 @@ function promptIdeAnswer() {
1277
1303
  */
1278
1304
  function openBrowser(url) {
1279
1305
  const spec = process.platform === "darwin" ? ["open", [url]]
1280
- : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]]
1306
+ : process.platform === "win32" ? ["rundll32.exe", ["url.dll,FileProtocolHandler", url]]
1281
1307
  : ["xdg-open", [url]];
1282
1308
  return new Promise((resolve) => {
1283
1309
  try {
@@ -1371,6 +1397,12 @@ export async function runConnect(tokenArg, ideOpt, opts = {}) {
1371
1397
  }
1372
1398
  finally {
1373
1399
  try {
1400
+ if (process.env.LITMUS_PORTAL_LAUNCHER_CHILD === "1" && process.connected) {
1401
+ process.send?.({ type: "litmus-connect-result", result: attempt.outcome, ...(skillImport.preparedEditor ? { preparedEditor: skillImport.preparedEditor } : {}) }, () => { });
1402
+ }
1403
+ if (attempt.outcome !== "ssh_ready")
1404
+ skillImport.stopPreparation?.fail("connection_failed");
1405
+ await skillImport.stopPreparation?.();
1374
1406
  if (attempt.outcome === "not_connected")
1375
1407
  await skillImport.rollbackCapture?.();
1376
1408
  await attempt.flush();
@@ -1385,6 +1417,10 @@ export async function runConnect(tokenArg, ideOpt, opts = {}) {
1385
1417
  releaseExitHold();
1386
1418
  }
1387
1419
  }
1420
+ if (skillImport.launcher) {
1421
+ await skillImport.launcher();
1422
+ return;
1423
+ }
1388
1424
  // The ssh route's session runs last, so nothing we print lands inside the remote shell.
1389
1425
  if (!skillImport.sshAlias)
1390
1426
  return;
@@ -1443,14 +1479,21 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
1443
1479
  // carries only the assessment id, never the token.
1444
1480
  const pageUrl = candidatePageUrl(apiBase, meta.assessmentId);
1445
1481
  attempt.stage("selection");
1446
- const { ide: chosenIde, chosen: ideWasChosen } = await resolveIde(ideOpt, console.log);
1482
+ const launcherBetaEnabled = meta.launcherBetaEnabled === true;
1483
+ const portalLauncher = launcherBetaEnabled && !ideOpt && !opts.tunnel;
1484
+ const { ide: chosenIde, chosen: ideWasChosen } = portalLauncher
1485
+ ? { ide: "ssh", chosen: true }
1486
+ : await resolveIde(ideOpt, console.log);
1447
1487
  let ide = chosenIde;
1448
1488
  attempt.editor(ide);
1449
1489
  // ENG-2814: asked here, next to the editor choice, and uploaded once the workspace is
1450
1490
  // ready. Never fails the connect. See `lib/connect-skills.ts`.
1451
1491
  attempt.stage("skills");
1492
+ if (portalLauncher)
1493
+ skillImport.stopPreparation = await startPortalPreparation(backendUrl, token);
1494
+ skillImport.stopPreparation?.update("waiting_input");
1452
1495
  const pendingSkills = await offerSkillImport({
1453
- backendUrl, token, flag: opts.skills, verbose,
1496
+ backendUrl, token, flag: opts.skills, verbose, launcherBetaEnabled,
1454
1497
  });
1455
1498
  attempt.stage("ssh_key");
1456
1499
  // 2. Ensure a local SSH key (private key never leaves this machine).
@@ -1470,9 +1513,11 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
1470
1513
  skillImport.rollbackCapture = await startHostedCapture(meta, token, apiBase);
1471
1514
  // 3. Start the workspace with our public key.
1472
1515
  attempt.stage("workspace_start");
1516
+ skillImport.stopPreparation?.update("starting_workspace");
1473
1517
  const boot = ora("Starting your workspace...").start();
1518
+ let initialStart;
1474
1519
  try {
1475
- await startWorkspace(backendUrl, token, pubkey);
1520
+ initialStart = await startWorkspace(backendUrl, token, pubkey);
1476
1521
  }
1477
1522
  catch (err) {
1478
1523
  attempt.evidence(workspaceStartNetworkDetail(err));
@@ -1511,35 +1556,62 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
1511
1556
  // 4. Poll until healthy (cold provision is ~5s; give it up to ~2 min, longer while
1512
1557
  // the backend still reports it `starting` — see `keepWaitingForWorkspace`).
1513
1558
  let conn = null;
1514
- const pollStartedAt = Date.now();
1515
- while (keepWaitingForWorkspace(Date.now() - pollStartedAt, conn?.workspace_status)) {
1559
+ let capacityTimedOut = false;
1560
+ if (!launcherBetaEnabled) {
1561
+ // Preserve the stable CLI's polling and retry contract outside enrollment.
1562
+ const pollStartedAt = Date.now();
1563
+ while (keepWaitingForWorkspace(Date.now() - pollStartedAt, conn?.workspace_status)) {
1564
+ try {
1565
+ conn = await getConnection(backendUrl, token);
1566
+ }
1567
+ catch { /* transient */ }
1568
+ if (conn?.healthy && (ide === "browser" || conn.ssh_command))
1569
+ break;
1570
+ const waited = Math.round((Date.now() - pollStartedAt) / 1000);
1571
+ boot.text = Date.now() - pollStartedAt < WORKSPACE_READY_WAIT_MS
1572
+ ? `Starting your workspace... (${waited}s)`
1573
+ : `Still starting your workspace. This can take a few minutes. (${waited}s)`;
1574
+ await sleep(2000);
1575
+ }
1576
+ }
1577
+ else {
1516
1578
  try {
1517
- conn = await getConnection(backendUrl, token);
1579
+ const waited = await waitForWorkspace({
1580
+ initial: initialStart,
1581
+ start: () => startWorkspace(backendUrl, token, pubkey),
1582
+ connection: () => getConnection(backendUrl, token),
1583
+ ready: value => Boolean(value.healthy && (ide === "browser" || value.ssh_command)),
1584
+ permanentFailure: error => error instanceof ServerError && Boolean(error.statusCode && error.statusCode >= 400 && error.statusCode < 500 && ![408, 429].includes(error.statusCode)),
1585
+ keepWaiting: keepWaitingForWorkspace,
1586
+ progress: (stage, elapsed) => {
1587
+ skillImport.stopPreparation?.update(stage);
1588
+ const seconds = Math.round(elapsed / 1000);
1589
+ boot.text = stage === "waiting_capacity" ? `Waiting for an available workspace... (${seconds}s)`
1590
+ : elapsed < WORKSPACE_READY_WAIT_MS ? `Starting your workspace... (${seconds}s)`
1591
+ : `Still starting your workspace. This can take a few minutes. (${seconds}s)`;
1592
+ },
1593
+ });
1594
+ conn = waited.connection ?? null;
1595
+ capacityTimedOut = waited.capacityTimedOut;
1518
1596
  }
1519
- catch {
1520
- // transient — keep polling
1597
+ catch (error) {
1598
+ boot.stop();
1599
+ fatal(error instanceof Error ? error.message : "Could not check your workspace connection.", "Refresh your assessment page, then run the connection command again.", { severity: "warning" });
1600
+ return;
1521
1601
  }
1522
- // VS Code / SSH need the ssh_command. The browser URL is config-derived (it
1523
- // appears together with `running`, not on a timer), so break on `healthy`
1524
- // alone — the branch below then gives a fast, specific message when no URL is
1525
- // configured, instead of spinning the full 120s on a v1 / pre-ingress box.
1526
- const ready = conn?.healthy && (ide === "browser" || !!conn.ssh_command);
1527
- if (ready)
1528
- break;
1529
- // ENG-2895: elapsed time, not the backend's state name (`not_created`, `provisioning`),
1530
- // and no "fresh host": neither is something the candidate can act on.
1531
- const waited = Math.round((Date.now() - pollStartedAt) / 1000);
1532
- boot.text = Date.now() - pollStartedAt < WORKSPACE_READY_WAIT_MS
1533
- ? `Starting your workspace... (${waited}s)`
1534
- : `Still starting your workspace. This can take a few minutes. (${waited}s)`;
1535
- await sleep(2000);
1536
1602
  }
1537
1603
  if (!conn?.healthy || (ide !== "browser" && !conn.ssh_command)) {
1538
1604
  boot.stop();
1539
- fatal("Your workspace isn't ready yet.", "Run the same `litmus connect` command again in a minute. If it keeps happening, contact the company.", { severity: "warning" });
1605
+ if (capacityTimedOut)
1606
+ skillImport.stopPreparation?.fail("capacity_timeout");
1607
+ fatal(capacityTimedOut ? "No workspace is available yet." : "Your workspace isn't ready yet.", capacityTimedOut ? "We couldn't allocate a workspace. Try the connection command again shortly or contact the assessment team." : "Run the same `litmus connect` command again in a minute. If it keeps happening, contact the company.", { severity: "warning" });
1540
1608
  return;
1541
1609
  }
1542
- boot.succeed("Workspace ready");
1610
+ if (portalLauncher)
1611
+ boot.stop();
1612
+ else
1613
+ boot.succeed("Workspace ready");
1614
+ skillImport.stopPreparation?.update("checking_connection");
1543
1615
  attempt.stage("workspace_ready");
1544
1616
  attempt.checkpoint();
1545
1617
  if (pendingSkills)
@@ -1577,7 +1649,7 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
1577
1649
  const parsed = parseSshCommand(conn.ssh_command);
1578
1650
  const alias = aliasFor(conn.ssh_hostname, token);
1579
1651
  pruneStaleHostKeys(parsed);
1580
- const cfgPath = await writeSshConfig(alias, buildSshConfigBlock(alias, KEY_PATH, parsed), buildControlPathBlock(alias, parsed));
1652
+ const cfgPath = await writeSshConfig(alias, buildSshConfigBlock(alias, KEY_PATH, parsed, process.platform, launcherBetaEnabled), buildControlPathBlock(alias, parsed));
1581
1653
  if (verbose)
1582
1654
  info(`SSH config written to ${cfgPath} (Host "${alias}")`);
1583
1655
  }
@@ -1633,7 +1705,7 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
1633
1705
  attempt.stage("ssh_config");
1634
1706
  const alias = aliasFor(conn.ssh_hostname, token);
1635
1707
  pruneStaleHostKeys(parsed);
1636
- const block = buildSshConfigBlock(alias, KEY_PATH, parsed);
1708
+ const block = buildSshConfigBlock(alias, KEY_PATH, parsed, process.platform, launcherBetaEnabled);
1637
1709
  const cfgPath = await writeSshConfig(alias, block, buildControlPathBlock(alias, parsed));
1638
1710
  if (verbose)
1639
1711
  info(`SSH config written to ${cfgPath} (Host "${alias}")`);
@@ -1669,6 +1741,21 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
1669
1741
  });
1670
1742
  return true;
1671
1743
  };
1744
+ if (portalLauncher) {
1745
+ if (await preflightStops("ssh"))
1746
+ return;
1747
+ attempt.finish("ssh_ready");
1748
+ skillImport.launcher = async () => {
1749
+ const ready = await startBackgroundLauncher({ backendUrl, token, alias, pageUrl, browserAvailable: Boolean(conn.browser_ide_url), assessmentName: meta.assessmentName });
1750
+ if (ready) {
1751
+ ora().succeed("Workspace ready · Laptop connected");
1752
+ console.log("\nLaunch your tools from the assessment page.");
1753
+ }
1754
+ else
1755
+ console.log(`Tool launching is unavailable on this deployment. Use your assessment page or ssh ${alias}.`);
1756
+ };
1757
+ return;
1758
+ }
1672
1759
  // SSH option: open the shell here (no editor launch). Without a terminal on both ends
1673
1760
  // there is no one to hand a shell to, so a piped or scripted run gets the command.
1674
1761
  if (ide === "ssh") {
@@ -1879,6 +1966,11 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
1879
1966
  // property of the SEQUENCE, so it is held in one testable unit rather than in the
1880
1967
  // arrangement of the lines below. Everything this block still owns is output.
1881
1968
  const probe = sshProbeRunner(alias, sshExecutable);
1969
+ if (editor.ide === "vscode" && resolved.version.commit) {
1970
+ const preparing = ora("Preparing VS Code for your workspace...").start();
1971
+ await prepareVscodeServer(alias, resolved.version.commit, new AbortController().signal);
1972
+ preparing.stop();
1973
+ }
1882
1974
  // Read once for both the seed check and attachment baseline.
1883
1975
  const readSpinner = ora(`Checking your workspace...`).start();
1884
1976
  const baseline = probeWorkspace(editor, probe, resolved.version.commit);
@@ -1911,7 +2003,7 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
1911
2003
  const spinners = { verify: null };
1912
2004
  const resend = { done: false };
1913
2005
  const launchPlan = editorLaunchPlan(editor, alias);
1914
- const launches = resendableLaunch((logPath) => launchEditor(editor, resolved.command, alias, logPath));
2006
+ const launches = resendableLaunch((logPath) => launchEditor(editor, resolved.command, alias, logPath, launcherBetaEnabled));
1915
2007
  // Local UI extension: it survives a remote-host disconnect. Never installed on
1916
2008
  // VS Code, browser or plain SSH paths. Handoff defaults on for Mac/Windows.
1917
2009
  if (editor.ide === "cursor") {
@@ -2005,6 +2097,18 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
2005
2097
  attempt.evidence(outcome.launchLog);
2006
2098
  if (outcome.verdict.kind === "connected") {
2007
2099
  attempt.finish("server_detected");
2100
+ let generation = null;
2101
+ try {
2102
+ generation = parseWorkspaceGeneration(JSON.parse(process.env.LITMUS_LAUNCH_GENERATION ?? "null"));
2103
+ }
2104
+ catch { /* old launcher */ }
2105
+ const binary = findInstalledExecutable(resolved.command, process.platform, process.env);
2106
+ if (generation && binary && resolved.version.commit) {
2107
+ try {
2108
+ skillImport.preparedEditor = { tool: editor.ide, command: realpathSync(binary), commit: resolved.version.commit, alias, generation };
2109
+ }
2110
+ catch { /* no reusable binary */ }
2111
+ }
2008
2112
  launchSpinner?.succeed(`${editor.label}'s server is running in your workspace.`);
2009
2113
  skillImport.footer.push(...editorConnectedLines(editor, alias, verbose));
2010
2114
  }
@@ -2043,4 +2147,87 @@ async function connectFlow(token, ideOpt, opts, skillImport, attempt) {
2043
2147
  // which also carries why we do not simply close the window.
2044
2148
  skillImport.footer.push(...editorEndingForewarning());
2045
2149
  }
2150
+ /** Used only by the detached launcher after the interactive setup has completed. */
2151
+ export function runPreparedPortalLauncher(context, onReady, signal) {
2152
+ const checkedDesktopApps = new Set();
2153
+ const attemptedVscode = new Set();
2154
+ const native = createPreparedEditorLauncher(context.alias);
2155
+ const desktopReadiness = createPreparedDesktopReadiness(context.alias);
2156
+ const cleanupSsh = prepareSshConfigCleanup(path.join(os.homedir(), ".ssh", "config"), context.alias);
2157
+ return runPortalLauncher({
2158
+ ...context, onReady, signal,
2159
+ onSubmitted: async () => {
2160
+ try {
2161
+ removeClaudeDesktopConnection(context.alias, context.assessmentName ?? "Assessment");
2162
+ }
2163
+ catch { /* Preserve settings if busy or malformed. */ }
2164
+ try {
2165
+ await cleanupSsh();
2166
+ }
2167
+ catch { /* Preserve config if busy or externally edited. */ }
2168
+ },
2169
+ openUrl: url => url === context.pageUrl ? Promise.resolve(true) : openBrowser(url),
2170
+ prepareTools: async (installed, signal) => Promise.all(installed.map(async (app) => {
2171
+ if (app.tool === "vscode" && !app.unavailable) {
2172
+ if (attemptedVscode.has(app.command))
2173
+ return app;
2174
+ attemptedVscode.add(app.command);
2175
+ const resolved = resolveEditorCommand(NATIVE_EDITORS.vscode);
2176
+ const commit = resolved?.version.commit;
2177
+ if (resolved && commit && identifyEditorCli(NATIVE_EDITORS.vscode, resolved.command).kind === "match") {
2178
+ await prepareVscodeServer(context.alias, commit, signal);
2179
+ }
2180
+ return app;
2181
+ }
2182
+ if (app.unavailable || (app.tool !== "codex" && app.tool !== "claude"))
2183
+ return app;
2184
+ const key = `${app.tool}:${app.command}`;
2185
+ if (checkedDesktopApps.has(key))
2186
+ return app;
2187
+ if (await desktopRuntimeReady(context.alias, app.tool, signal)) {
2188
+ if (app.tool === "claude") {
2189
+ try {
2190
+ configureClaudeDesktopConnection(context.alias, context.assessmentName ?? "Assessment");
2191
+ }
2192
+ catch {
2193
+ return { ...app, unavailable: "desktop_setup_failed" };
2194
+ }
2195
+ }
2196
+ checkedDesktopApps.add(key);
2197
+ return app;
2198
+ }
2199
+ return { ...app, unavailable: "workspace_not_ready" };
2200
+ })),
2201
+ launch: async (tool, installed, signal, launchContext) => {
2202
+ if (tool === "vscode" || tool === "cursor") {
2203
+ return await native.launch(tool, launchContext?.generation, remember => openNativeEditor(tool, context.token, signal, undefined, remember, launchContext?.generation), signal);
2204
+ }
2205
+ if (tool === "browser") {
2206
+ const current = await getConnection(context.backendUrl, context.token);
2207
+ return current.browser_ide_url && await openBrowser(current.browser_ide_url) ? "dispatched" : "failed";
2208
+ }
2209
+ if (tool === "codex" || tool === "claude") {
2210
+ const app = installed.find(i => i.tool === tool);
2211
+ if (!app || app.unavailable || !await desktopReadiness.check(tool, app.command, launchContext?.generation, signal))
2212
+ return "failed";
2213
+ if (tool === "claude") {
2214
+ try {
2215
+ configureClaudeDesktopConnection(context.alias, context.assessmentName ?? "Assessment");
2216
+ }
2217
+ catch {
2218
+ return "failed";
2219
+ }
2220
+ }
2221
+ // OS handoff is all the opener proves. Do not invent a confirmation
2222
+ // prompt or claim an active assessment connection from its exit code.
2223
+ const opened = await openDesktop(app, context.alias, signal);
2224
+ if (!opened)
2225
+ desktopReadiness.invalidate();
2226
+ return opened ? "dispatched" : "failed";
2227
+ }
2228
+ const terminal = installed.find(i => i.tool === "ssh");
2229
+ return terminal && await openTerminal(context.alias, terminal.command, launchContext?.requestId) ? "dispatched" : "failed";
2230
+ },
2231
+ });
2232
+ }
2046
2233
  //# sourceMappingURL=connect.js.map