deepline 0.3.206 → 0.3.208

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/cli/index.js CHANGED
@@ -3051,7 +3051,7 @@ var SDK_RELEASE = {
3051
3051
  // getters keep their established compatibility behavior.
3052
3052
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3053
3053
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3054
- version: "0.3.206",
3054
+ version: "0.3.208",
3055
3055
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3056
3056
  packageCapabilities: {
3057
3057
  updatePreferences: 1
@@ -11645,6 +11645,7 @@ function printCommandEnvelope(envelope, options = {}) {
11645
11645
  var EXIT_OK = 0;
11646
11646
  var EXIT_AUTH = 3;
11647
11647
  var EXIT_SERVER = 5;
11648
+ var EXIT_WORKSPACE_MISMATCH = 6;
11648
11649
  var AUTH_HTTP_TIMEOUT_MS = 1e4;
11649
11650
  var AUTH_REGISTER_HTTP_TIMEOUT_MS = 3e4;
11650
11651
  function statusBannerLine(value) {
@@ -11735,7 +11736,8 @@ function readPendingAuthClaim(baseUrl, scope) {
11735
11736
  if (!claimToken) return null;
11736
11737
  return {
11737
11738
  claimToken,
11738
- claimUrl: typeof parsed.claimUrl === "string" ? parsed.claimUrl.trim() : "",
11739
+ claimUrl: typeof parsed.claimUrl === "string" && parsed.claimUrl.trim() ? parsed.claimUrl.trim() : `${baseUrl}/api/v2/auth/cli/claim/${encodeURIComponent(claimToken)}`,
11740
+ orgName: typeof parsed.orgName === "string" ? parsed.orgName.trim() : void 0,
11739
11741
  // The record's own scope, when it has one. `register` writes this field
11740
11742
  // precisely so a resume can learn where the credential belongs; reading
11741
11743
  // back the caller's argument instead made it decorative, and a record
@@ -11756,6 +11758,14 @@ function clearPendingClaim(baseUrl, scope) {
11756
11758
  } catch {
11757
11759
  }
11758
11760
  }
11761
+ function clearSatisfiedPendingClaim(baseUrl, scope, connectedWorkspaceName) {
11762
+ const pending = readPendingAuthClaim(baseUrl, scope);
11763
+ if (!pending) return;
11764
+ if (pending.orgName && pending.orgName.toLowerCase() !== connectedWorkspaceName?.trim().toLowerCase()) {
11765
+ return;
11766
+ }
11767
+ clearPendingClaim(baseUrl, scope);
11768
+ }
11759
11769
  function parseRegisterWaitMode(args) {
11760
11770
  let mode = "auto";
11761
11771
  for (let i = 0; i < args.length; i++) {
@@ -11993,7 +12003,12 @@ async function handleRegister(args) {
11993
12003
  const claimUrl = String(data.claim_url || "");
11994
12004
  const claimToken = String(data.claim_token || "");
11995
12005
  if (claimToken) {
11996
- savePendingClaim(baseUrl, { claimToken, claimUrl, scope: authScope });
12006
+ savePendingClaim(baseUrl, {
12007
+ claimToken,
12008
+ claimUrl,
12009
+ scope: authScope,
12010
+ ...orgName ? { orgName } : {}
12011
+ });
11997
12012
  saveEnvValues(
11998
12013
  {
11999
12014
  [HOST_URL_ENV]: baseUrl
@@ -12039,6 +12054,13 @@ async function handleRegister(args) {
12039
12054
  return EXIT_SERVER;
12040
12055
  }
12041
12056
  const state = String(statusData.status || "").toLowerCase();
12057
+ if (statusData.code === "REQUESTED_WORKSPACE_NOT_IN_ACCOUNT") {
12058
+ clearPendingClaim(baseUrl, authScope);
12059
+ console.error(
12060
+ "The requested workspace does not exist in this account. Connect to an existing workspace first; then use `deepline org create` if you need a new one."
12061
+ );
12062
+ return EXIT_WORKSPACE_MISMATCH;
12063
+ }
12042
12064
  if (state === "claimed") {
12043
12065
  const apiKey = String(statusData.api_key || "");
12044
12066
  if (apiKey) {
@@ -12100,12 +12122,13 @@ async function handleWait(args) {
12100
12122
  return EXIT_AUTH;
12101
12123
  }
12102
12124
  const deadline = Date.now() + timeoutSeconds * 1e3;
12103
- while (Date.now() <= deadline) {
12125
+ while (Date.now() < deadline) {
12104
12126
  const { status, data } = await httpJson(
12105
12127
  "POST",
12106
12128
  `${baseUrl}/api/v2/auth/cli/status`,
12107
12129
  null,
12108
- { claim_token: claimToken, reveal: true }
12130
+ { claim_token: claimToken, reveal: true },
12131
+ Math.min(AUTH_HTTP_TIMEOUT_MS, Math.max(1, deadline - Date.now()))
12109
12132
  );
12110
12133
  if (status === 401 || status === 403) {
12111
12134
  clearPendingClaim(baseUrl, authScope);
@@ -12113,7 +12136,7 @@ async function handleWait(args) {
12113
12136
  return EXIT_AUTH;
12114
12137
  }
12115
12138
  if (status >= 500 || status === 0 || status === 400) {
12116
- await sleep4(2e3);
12139
+ await sleep4(Math.min(2e3, Math.max(0, deadline - Date.now())));
12117
12140
  continue;
12118
12141
  }
12119
12142
  if (status >= 400) {
@@ -12121,6 +12144,13 @@ async function handleWait(args) {
12121
12144
  return EXIT_SERVER;
12122
12145
  }
12123
12146
  const state = String(data.status || "").toLowerCase();
12147
+ if (data.code === "REQUESTED_WORKSPACE_NOT_IN_ACCOUNT") {
12148
+ clearPendingClaim(baseUrl, authScope);
12149
+ console.error(
12150
+ "The requested workspace does not exist in this account. Connect to an existing workspace first; then use `deepline org create` if you need a new one."
12151
+ );
12152
+ return EXIT_WORKSPACE_MISMATCH;
12153
+ }
12124
12154
  if (state === "claimed") {
12125
12155
  const apiKey = String(data.api_key || "");
12126
12156
  if (apiKey) {
@@ -12143,7 +12173,7 @@ async function handleWait(args) {
12143
12173
  console.error("That approval link expired. Run: deepline auth register");
12144
12174
  return EXIT_AUTH;
12145
12175
  }
12146
- await sleep4(2e3);
12176
+ await sleep4(Math.min(2e3, Math.max(0, deadline - Date.now())));
12147
12177
  }
12148
12178
  console.error(
12149
12179
  "Still pending. Approve the browser link, then run: deepline auth wait"
@@ -12288,7 +12318,11 @@ async function handleStatus(args) {
12288
12318
  return EXIT_SERVER;
12289
12319
  }
12290
12320
  const resolvedAuthScope = authScope ?? (getResolvedProjectAuthSource(baseUrl, apiKey) ? "folder" : "global");
12291
- clearPendingClaim(baseUrl, resolvedAuthScope);
12321
+ clearSatisfiedPendingClaim(
12322
+ baseUrl,
12323
+ resolvedAuthScope,
12324
+ typeof data.org_name === "string" ? data.org_name : null
12325
+ );
12292
12326
  const payload = {
12293
12327
  ...hostStatusPayload ?? { host: baseUrl },
12294
12328
  status: data.status || "(unknown)",
@@ -12302,6 +12336,7 @@ async function handleStatus(args) {
12302
12336
  user: {
12303
12337
  id: data.user_id ?? null
12304
12338
  },
12339
+ businessDomain: typeof data.business_domain === "string" ? data.business_domain : null,
12305
12340
  examples: Array.isArray(data.examples) ? data.examples : []
12306
12341
  };
12307
12342
  let savedApiKeyPath = null;
@@ -12413,7 +12448,7 @@ Examples:
12413
12448
  `
12414
12449
  ).option(
12415
12450
  "--org-name <name>",
12416
- "Use this workspace, or create a separate one with this name"
12451
+ "Connect to an existing workspace, or name your first workspace"
12417
12452
  ).option(
12418
12453
  "--org-id <id>",
12419
12454
  "Bind to this workspace directly, skipping the browser picker"
@@ -21536,6 +21571,11 @@ function carriesArtifact(revision, artifact) {
21536
21571
  revision && revision.sourceHash === artifact.sourceHash && revision.artifactHash === artifact.artifactHash && revision.graphHash === artifact.graphHash && revision.artifactKind === artifact.artifactKind
21537
21572
  );
21538
21573
  }
21574
+ function isSdkUpdated(live, artifact) {
21575
+ return Boolean(
21576
+ live && live.sourceHash === artifact.sourceHash && live.graphHash === artifact.graphHash && live.artifactHash !== artifact.artifactHash
21577
+ );
21578
+ }
21539
21579
  function annotationForFailure(input2) {
21540
21580
  return {
21541
21581
  path: input2.file,
@@ -21970,6 +22010,11 @@ async function runDeployment(params, hooks) {
21970
22010
  });
21971
22011
  }
21972
22012
  const playByName = new Map(ordered.map((play) => [play.name, play]));
22013
+ const sdkUpdated = (name) => {
22014
+ const artifact = playByName.get(name)?.result.artifact;
22015
+ const live = stateByName.get(name)?.liveRevision ?? null;
22016
+ return artifact && isSdkUpdated(live, artifact) ? { sdkUpdated: true } : {};
22017
+ };
21973
22018
  const outcomes = [];
21974
22019
  const toRegister = [];
21975
22020
  const toPromote = [];
@@ -22016,6 +22061,7 @@ async function runDeployment(params, hooks) {
22016
22061
  file: play.file,
22017
22062
  status: "registered",
22018
22063
  version: playState?.workingRevision?.version ?? void 0,
22064
+ ...sdkUpdated(play.name),
22019
22065
  ...warning ? { warning } : {}
22020
22066
  });
22021
22067
  }
@@ -22057,6 +22103,7 @@ async function runDeployment(params, hooks) {
22057
22103
  file: item.play.file,
22058
22104
  status: "registered",
22059
22105
  version: typeof artifact.version === "number" ? artifact.version : void 0,
22106
+ ...sdkUpdated(item.play.name),
22060
22107
  ...warning ? { warning } : {}
22061
22108
  });
22062
22109
  }
@@ -22071,7 +22118,7 @@ async function runDeployment(params, hooks) {
22071
22118
  title: `${ordered.length} play${ordered.length === 1 ? "" : "s"} validated and registered (not deployed)`,
22072
22119
  ...annotations.length > 0 ? { annotations } : {},
22073
22120
  summary: outcomes.map(
22074
- (outcome) => `- \`${outcome.name}\`: ${outcome.status}${outcome.version !== void 0 ? ` (v${outcome.version})` : ""}${outcome.warning ? `
22121
+ (outcome) => `- \`${outcome.name}\`: ${outcome.status}${outcome.version !== void 0 ? ` (v${outcome.version})` : ""}${outcome.sdkUpdated ? " \u2014 SDK updated" : ""}${outcome.warning ? `
22075
22122
  - :warning: ${outcome.warning}` : ""}`
22076
22123
  ).join("\n")
22077
22124
  });
@@ -22100,6 +22147,7 @@ async function runDeployment(params, hooks) {
22100
22147
  status: outcome.status === "promoted" ? "promoted" : "failed",
22101
22148
  version: outcome.version,
22102
22149
  ...outcome.status === "promoted" && typeof previousVersion === "number" && previousVersion !== outcome.version ? { previousVersion } : {},
22150
+ ...outcome.status === "promoted" ? sdkUpdated(outcome.name) : {},
22103
22151
  ...outcome.status === "promoted" && warning ? { warning } : {},
22104
22152
  ...outcome.error ? { error: outcome.error } : {}
22105
22153
  });
@@ -22146,7 +22194,7 @@ async function runDeployment(params, hooks) {
22146
22194
  title: `Deployed ${outcomes.filter((o) => o.status === "promoted").length} play(s) (${outcomes.filter((o) => o.status === "unchanged").length} unchanged)`,
22147
22195
  ...annotations.length > 0 ? { annotations } : {},
22148
22196
  summary: outcomes.map(
22149
- (outcome) => `- \`${outcome.name}\`: ${outcome.status}${outcome.warning ? `
22197
+ (outcome) => `- \`${outcome.name}\`: ${outcome.status}${outcome.sdkUpdated ? " \u2014 SDK updated" : ""}${outcome.warning ? `
22150
22198
  - :warning: ${outcome.warning}` : ""}`
22151
22199
  ).join("\n")
22152
22200
  });
@@ -22234,8 +22282,9 @@ function topoSortByPlayDependencies(plays) {
22234
22282
  var MAX_DEPLOY_ATTEMPTS = 3;
22235
22283
  function renderOutcome(outcome) {
22236
22284
  const version = outcome.version === void 0 ? "" : outcome.previousVersion === void 0 ? ` v${outcome.version}` : ` v${outcome.previousVersion} -> v${outcome.version}`;
22285
+ const sdkUpdated = outcome.sdkUpdated ? " (SDK updated)" : "";
22237
22286
  const note = outcome.error ?? outcome.warning;
22238
- return `${outcome.name} (${outcome.file}): ${outcome.status}${version}${note ? ` - ${note}` : ""}`;
22287
+ return `${outcome.name} (${outcome.file}): ${outcome.status}${version}${sdkUpdated}${note ? ` - ${note}` : ""}`;
22239
22288
  }
22240
22289
  function printResult(input2) {
22241
22290
  const failed = input2.status === "failed" || input2.status === "cancelled";
@@ -22667,8 +22716,9 @@ function renderDeploymentPlayLines(results) {
22667
22716
  return plays.flatMap((play) => {
22668
22717
  const version = play.version === void 0 ? "" : play.previousVersion === void 0 ? ` v${play.version}` : ` v${play.previousVersion} -> v${play.version}`;
22669
22718
  const file = play.file ? ` (${play.file})` : "";
22719
+ const sdkUpdated = play.sdkUpdated ? " (SDK updated)" : "";
22670
22720
  return [
22671
- `${play.name ?? "?"}${file} - ${play.status ?? "?"}${version}`,
22721
+ `${play.name ?? "?"}${file} - ${play.status ?? "?"}${version}${sdkUpdated}`,
22672
22722
  ...play.error ? [` error: ${play.error}`] : [],
22673
22723
  ...play.warning ? [` warning: ${play.warning}`] : []
22674
22724
  ];
@@ -45437,11 +45487,24 @@ function openSetupAuthorization(authorizationUrl, options = {}) {
45437
45487
  }
45438
45488
  function buildPendingAuthorizationOutput(input2) {
45439
45489
  const authorizationUrl = input2.authorizationUrl.trim();
45440
- if (input2.browserOpenStatus === "opened") {
45490
+ if (input2.browserOpenStatus === "existing_claim" && authorizationUrl) {
45441
45491
  return {
45442
- authorizationUrl: null,
45443
- next: `Complete browser approval, then run: ${input2.resumeCommand}`,
45444
- lines: ["Complete authorization in the browser window Deepline opened."]
45492
+ authorizationUrl,
45493
+ next: `The existing approval is still pending. Use its authorization URL if needed, then run: ${input2.resumeCommand}`,
45494
+ lines: [
45495
+ "Deepline did not open another browser tab. Use the existing approval page or this link:",
45496
+ authorizationUrl
45497
+ ]
45498
+ };
45499
+ }
45500
+ if (input2.browserOpenStatus === "timed_out" && authorizationUrl) {
45501
+ return {
45502
+ authorizationUrl,
45503
+ next: `Approval is still pending after five minutes. Use the authorization URL if needed, then run: ${input2.resumeCommand}`,
45504
+ lines: [
45505
+ "Approval is still pending. Use this link if the tab was missed:",
45506
+ authorizationUrl
45507
+ ]
45445
45508
  };
45446
45509
  }
45447
45510
  if (authorizationUrl) {
@@ -45631,15 +45694,16 @@ function rollbackCommand(scope, root) {
45631
45694
  const allowScriptsFlag = npmSupportsAllowScripts(readNpmVersion(process.env)) ? " --allow-scripts=esbuild" : "";
45632
45695
  return `npm install -g${prefix} --no-audit --no-fund --include=optional${allowScriptsFlag} deepline@${SDK_VERSION}`;
45633
45696
  }
45634
- function setupResumeCommand(baseUrl, scope) {
45697
+ function setupResumeCommand(baseUrl, scope, orgName) {
45635
45698
  const hostPrefix = baseUrl === "https://code.deepline.com" ? "" : `DEEPLINE_HOST_URL=${JSON.stringify(baseUrl)} `;
45636
- return `${hostPrefix}deepline setup --scope ${scope} --json`;
45699
+ const quotedOrgName = orgName ? process.platform === "win32" ? ` --org-name "${orgName.replace(/"/g, '""')}"` : ` --org-name '${orgName.replace(/'/g, `'\\''`)}'` : "";
45700
+ return `${hostPrefix}deepline setup --scope ${scope}${quotedOrgName} --json`;
45637
45701
  }
45638
45702
  function setupRetry(input2) {
45639
45703
  return {
45640
45704
  phase: input2.phase,
45641
- command: setupResumeCommand(input2.baseUrl, input2.scope),
45642
- automatic: true
45705
+ command: setupResumeCommand(input2.baseUrl, input2.scope, input2.orgName),
45706
+ automatic: input2.retryAutomatic ?? true
45643
45707
  };
45644
45708
  }
45645
45709
  function reportSetupPhaseFailure(input2) {
@@ -45695,6 +45759,7 @@ function reportSetupAuthStatusFailure(input2) {
45695
45759
  scope: input2.scope,
45696
45760
  root: input2.root,
45697
45761
  phases: input2.phases,
45762
+ orgName: input2.orgName,
45698
45763
  phase: "auth",
45699
45764
  code: "AUTH_STATUS_FAILED",
45700
45765
  exitCode: 4,
@@ -45817,22 +45882,14 @@ function pendingResult(input2) {
45817
45882
  status: "authorization_pending",
45818
45883
  phases: input2.phases
45819
45884
  });
45820
- let browserOpenStatus = "failed";
45821
- if (input2.authorizationUrl) {
45822
- browserOpenStatus = openSetupAuthorization(input2.authorizationUrl);
45823
- if (browserOpenStatus === "opened") {
45824
- process.stderr.write(
45825
- "Opened Deepline authorization in your browser. Complete approval there.\n"
45826
- );
45827
- } else if (browserOpenStatus === "failed") {
45828
- process.stderr.write(`Authorize Deepline: ${input2.authorizationUrl}
45829
- `);
45830
- }
45831
- }
45832
45885
  const pendingOutput = buildPendingAuthorizationOutput({
45833
45886
  authorizationUrl: input2.authorizationUrl,
45834
- browserOpenStatus,
45835
- resumeCommand: setupResumeCommand(input2.baseUrl, input2.scope)
45887
+ browserOpenStatus: input2.browserOpenStatus,
45888
+ resumeCommand: setupResumeCommand(
45889
+ input2.baseUrl,
45890
+ input2.scope,
45891
+ input2.orgName
45892
+ )
45836
45893
  });
45837
45894
  printCommandEnvelope(
45838
45895
  {
@@ -45841,8 +45898,9 @@ function pendingResult(input2) {
45841
45898
  complete: false,
45842
45899
  scope: input2.scope,
45843
45900
  authorizationUrl: pendingOutput.authorizationUrl,
45844
- browserOpened: browserOpenStatus === "opened",
45845
- browserOpenStatus,
45901
+ browserOpened: input2.browserOpenStatus === "timed_out",
45902
+ browserOpenStatus: input2.browserOpenStatus,
45903
+ authClaimSource: input2.authClaimSource,
45846
45904
  statePath,
45847
45905
  phases: input2.phases,
45848
45906
  currentPhase: "auth",
@@ -45850,7 +45908,8 @@ function pendingResult(input2) {
45850
45908
  retry: setupRetry({
45851
45909
  baseUrl: input2.baseUrl,
45852
45910
  scope: input2.scope,
45853
- phase: "auth"
45911
+ phase: "auth",
45912
+ orgName: input2.orgName
45854
45913
  }),
45855
45914
  next: pendingOutput.next,
45856
45915
  render: {
@@ -45867,6 +45926,20 @@ function pendingResult(input2) {
45867
45926
  return 0;
45868
45927
  }
45869
45928
  async function runSetupCommand(options) {
45929
+ let orgName = options.orgName?.trim();
45930
+ if (options.orgName !== void 0 && !orgName) {
45931
+ printCommandEnvelope(
45932
+ {
45933
+ ok: false,
45934
+ status: "failed",
45935
+ code: "INVALID_ORG_NAME",
45936
+ exitCode: 2,
45937
+ message: "Workspace name cannot be empty."
45938
+ },
45939
+ { json: options.json }
45940
+ );
45941
+ return 2;
45942
+ }
45870
45943
  let scope;
45871
45944
  let root;
45872
45945
  try {
@@ -45911,6 +45984,7 @@ async function runSetupCommand(options) {
45911
45984
  exitCode: 7,
45912
45985
  message: installedButUnreachable ? `The global Deepline executable is not reachable on PATH: ${globalCli.persistentPath}` : "No persistent global Deepline executable was found.",
45913
45986
  json: options.json,
45987
+ orgName,
45914
45988
  extra: {
45915
45989
  persistentPath: globalCli.persistentPath,
45916
45990
  fallback: "https://code.deepline.com/INSTALL.md"
@@ -45930,6 +46004,7 @@ async function runSetupCommand(options) {
45930
46004
  exitCode: 7,
45931
46005
  message: `An unknown executable named deepline is first on PATH: ${conflict}`,
45932
46006
  json: options.json,
46007
+ orgName,
45933
46008
  extra: { path: conflict }
45934
46009
  });
45935
46010
  }
@@ -45963,7 +46038,8 @@ async function runSetupCommand(options) {
45963
46038
  code: "LEGACY_CLEANUP_FAILED",
45964
46039
  exitCode: 5,
45965
46040
  message: error instanceof Error ? error.message : String(error),
45966
- json: options.json
46041
+ json: options.json,
46042
+ orgName
45967
46043
  });
45968
46044
  }
45969
46045
  }
@@ -45984,7 +46060,7 @@ async function runSetupCommand(options) {
45984
46060
  process.stderr.write(
45985
46061
  "Global skill setup failed. Trying project-local skills instead.\n"
45986
46062
  );
45987
- return runSetupCommand({ scope: "local", json: options.json });
46063
+ return runSetupCommand({ scope: "local", json: options.json, orgName });
45988
46064
  }
45989
46065
  return reportSetupPhaseFailure({
45990
46066
  baseUrl,
@@ -45996,7 +46072,8 @@ async function runSetupCommand(options) {
45996
46072
  exitCode: skills.exitCode,
45997
46073
  message: typeof skillsPayload?.message === "string" ? skillsPayload.message : "Deepline skills could not be installed.",
45998
46074
  json: options.json,
45999
- next: `! ${setupResumeCommand(baseUrl, scope)}`,
46075
+ orgName,
46076
+ next: `! ${setupResumeCommand(baseUrl, scope, orgName)}`,
46000
46077
  extra: { detail: skillsPayload }
46001
46078
  });
46002
46079
  }
@@ -46018,6 +46095,13 @@ async function runSetupCommand(options) {
46018
46095
  );
46019
46096
  }
46020
46097
  const authScope = authScopeForSetup(scope);
46098
+ const pendingAtStart = readPendingAuthClaim(baseUrl, authScope);
46099
+ const replacingPendingClaim = Boolean(
46100
+ pendingAtStart && orgName && pendingAtStart.orgName?.toLowerCase() !== orgName.toLowerCase()
46101
+ );
46102
+ if (pendingAtStart && !replacingPendingClaim) {
46103
+ if (pendingAtStart.orgName) orgName = pendingAtStart.orgName;
46104
+ }
46021
46105
  beginSetupPhase(phases, "auth");
46022
46106
  persistSetupProgress({ baseUrl, scope, root, phases });
46023
46107
  let auth = await readAuthStatus(authScope);
@@ -46028,88 +46112,146 @@ async function runSetupCommand(options) {
46028
46112
  scope,
46029
46113
  root,
46030
46114
  phases,
46115
+ orgName,
46031
46116
  json: options.json
46032
46117
  });
46033
46118
  if (initialAuthFailure !== null) return initialAuthFailure;
46034
- if (auth.payload?.connected !== true) {
46035
- const pending = readPendingAuthClaim(baseUrl, authScope);
46036
- if (pending) {
46037
- process.stderr.write("Checking pending Deepline authorization...\n");
46038
- await captureStdout2(
46039
- () => handleWait(["--timeout", "1", "--auth-scope", authScope])
46040
- );
46041
- auth = await readAuthStatus(authScope);
46042
- const resumedAuthFailure = reportSetupAuthStatusFailure({
46043
- auth,
46044
- baseUrl,
46045
- authScope,
46046
- scope,
46047
- root,
46048
- phases,
46049
- json: options.json
46050
- });
46051
- if (resumedAuthFailure !== null) return resumedAuthFailure;
46052
- if (auth.payload?.connected !== true) {
46053
- const stillPending = readPendingAuthClaim(baseUrl, authScope);
46054
- if (stillPending) {
46055
- return pendingResult({
46056
- baseUrl,
46057
- scope,
46058
- root,
46059
- phases,
46060
- authorizationUrl: stillPending.claimUrl,
46061
- resumed,
46062
- json: options.json
46063
- });
46064
- }
46119
+ const connectedToRequestedWorkspace = () => {
46120
+ if (auth.payload?.connected !== true) return false;
46121
+ if (!orgName) return true;
46122
+ const workspace = asRecord3(auth.payload.workspace);
46123
+ return typeof workspace?.name === "string" && workspace.name.trim().toLowerCase() === orgName.toLowerCase();
46124
+ };
46125
+ let pending = replacingPendingClaim ? null : readPendingAuthClaim(baseUrl, authScope);
46126
+ if (replacingPendingClaim && connectedToRequestedWorkspace()) {
46127
+ clearPendingClaim(baseUrl, authScope);
46128
+ }
46129
+ let authClaimSource = "none";
46130
+ if (pending || !connectedToRequestedWorkspace()) {
46131
+ const reusedClaim = Boolean(pending);
46132
+ authClaimSource = reusedClaim ? "existing" : "new";
46133
+ if (!pending) {
46134
+ process.stderr.write("Starting Deepline browser authorization...\n");
46135
+ const registered = await captureStdout2(
46136
+ () => handleRegister([
46137
+ "--wait",
46138
+ "no",
46139
+ "--auth-scope",
46140
+ authScope,
46141
+ ...orgName ? ["--org-name", orgName] : []
46142
+ ])
46143
+ );
46144
+ if (registered.exitCode !== 0) {
46145
+ return reportSetupPhaseFailure({
46146
+ baseUrl,
46147
+ scope,
46148
+ root,
46149
+ phases,
46150
+ phase: "auth",
46151
+ code: "AUTH_REGISTER_FAILED",
46152
+ exitCode: registered.exitCode,
46153
+ message: "Deepline browser authorization could not be started.",
46154
+ orgName,
46155
+ json: options.json,
46156
+ extra: { detail: parseCapturedJson(registered.stdout), authScope }
46157
+ });
46158
+ }
46159
+ pending = readPendingAuthClaim(baseUrl, authScope);
46160
+ if (!pending?.claimUrl) {
46161
+ return reportSetupPhaseFailure({
46162
+ baseUrl,
46163
+ scope,
46164
+ root,
46165
+ phases,
46166
+ phase: "auth",
46167
+ code: "AUTH_CLAIM_URL_MISSING",
46168
+ exitCode: 4,
46169
+ message: "Deepline authorization did not return a usable claim URL.",
46170
+ orgName,
46171
+ json: options.json
46172
+ });
46065
46173
  }
46174
+ const browserOpenStatus = openSetupAuthorization(pending.claimUrl);
46175
+ if (browserOpenStatus === "failed") {
46176
+ return pendingResult({
46177
+ baseUrl,
46178
+ scope,
46179
+ root,
46180
+ phases,
46181
+ authorizationUrl: pending.claimUrl,
46182
+ browserOpenStatus: "failed",
46183
+ authClaimSource,
46184
+ orgName,
46185
+ resumed,
46186
+ json: options.json
46187
+ });
46188
+ }
46189
+ process.stderr.write("Opened Deepline sign-in in the browser.\n");
46066
46190
  }
46067
- }
46068
- if (auth.payload?.connected !== true) {
46069
- process.stderr.write("Starting Deepline browser authorization...\n");
46070
- const agentRuntime = detectAgentRuntime();
46071
- const agentLed = agentRuntime !== "unknown";
46072
- const waitMode = options.json || agentLed || !process.stdin.isTTY ? "no" : "auto";
46073
- const registered = await captureStdout2(
46074
- () => handleRegister(["--wait", waitMode, "--auth-scope", authScope])
46191
+ process.stderr.write(
46192
+ "Waiting up to five minutes for Deepline approval...\n"
46193
+ );
46194
+ const waited = await captureStdout2(
46195
+ () => handleWait(["--timeout", "300", "--auth-scope", authScope])
46075
46196
  );
46076
- if (registered.exitCode !== 0) {
46077
- return reportSetupPhaseFailure({
46078
- baseUrl,
46079
- scope,
46080
- root,
46081
- phases,
46082
- phase: "auth",
46083
- code: "AUTH_REGISTER_FAILED",
46084
- exitCode: registered.exitCode,
46085
- message: "Deepline browser authorization could not be started.",
46086
- json: options.json,
46087
- extra: {
46088
- detail: parseCapturedJson(registered.stdout),
46089
- authScope
46090
- }
46091
- });
46092
- }
46093
46197
  auth = await readAuthStatus(authScope);
46094
- const registeredAuthFailure = reportSetupAuthStatusFailure({
46198
+ const authFailure = reportSetupAuthStatusFailure({
46095
46199
  auth,
46096
46200
  baseUrl,
46097
46201
  authScope,
46098
46202
  scope,
46099
46203
  root,
46100
46204
  phases,
46205
+ orgName,
46101
46206
  json: options.json
46102
46207
  });
46103
- if (registeredAuthFailure !== null) return registeredAuthFailure;
46104
- if (auth.payload?.connected !== true) {
46105
- const pending = readPendingAuthClaim(baseUrl, authScope);
46106
- return pendingResult({
46208
+ if (authFailure !== null) return authFailure;
46209
+ if (waited.exitCode === EXIT_WORKSPACE_MISMATCH) {
46210
+ return reportSetupPhaseFailure({
46211
+ baseUrl,
46212
+ scope,
46213
+ root,
46214
+ phases,
46215
+ phase: "auth",
46216
+ code: "REQUESTED_WORKSPACE_NOT_IN_ACCOUNT",
46217
+ exitCode: EXIT_WORKSPACE_MISMATCH,
46218
+ message: `The requested workspace${orgName ? ` ${orgName}` : ""} does not exist in this account. Connect to an existing workspace first; then use deepline org create if you need a new one.`,
46219
+ orgName,
46220
+ retryAutomatic: false,
46221
+ next: "Ask the user which existing workspace or account to use. Sign in with an account that can access it, then rerun setup with --org-name set to the confirmed workspace.",
46222
+ json: options.json
46223
+ });
46224
+ }
46225
+ if (!connectedToRequestedWorkspace()) {
46226
+ const stillPending = readPendingAuthClaim(baseUrl, authScope);
46227
+ if (stillPending?.claimUrl) {
46228
+ return pendingResult({
46229
+ baseUrl,
46230
+ scope,
46231
+ root,
46232
+ phases,
46233
+ authorizationUrl: stillPending.claimUrl,
46234
+ browserOpenStatus: reusedClaim ? "existing_claim" : "timed_out",
46235
+ authClaimSource,
46236
+ orgName,
46237
+ resumed,
46238
+ json: options.json
46239
+ });
46240
+ }
46241
+ return reportSetupPhaseFailure({
46107
46242
  baseUrl,
46108
46243
  scope,
46109
46244
  root,
46110
46245
  phases,
46111
- authorizationUrl: pending?.claimUrl ?? "",
46112
- resumed,
46246
+ phase: "auth",
46247
+ code: orgName && auth.payload?.connected ? "AUTH_WORKSPACE_MISMATCH" : "AUTH_WAIT_FAILED",
46248
+ exitCode: waited.exitCode || 4,
46249
+ message: orgName && auth.payload?.connected ? `Deepline is connected to a different workspace than ${orgName}.` : "Deepline authorization did not complete.",
46250
+ orgName,
46251
+ ...orgName && auth.payload?.connected ? {
46252
+ retryAutomatic: false,
46253
+ next: "Ask the user which existing workspace or account to use. Rerun setup with --org-name set to the confirmed workspace."
46254
+ } : {},
46113
46255
  json: options.json
46114
46256
  });
46115
46257
  }
@@ -46143,6 +46285,7 @@ async function runSetupCommand(options) {
46143
46285
  code: "DOCTOR_FAILED",
46144
46286
  exitCode: 7,
46145
46287
  message: "Deepline setup verification found one or more failed checks.",
46288
+ orgName,
46146
46289
  json: options.json,
46147
46290
  extra: {
46148
46291
  doctor: doctorPayload,
@@ -46183,6 +46326,9 @@ async function runSetupCommand(options) {
46183
46326
  cliVersion: SDK_VERSION,
46184
46327
  agents: installedAgents,
46185
46328
  workspace: apiCheck?.workspace ?? null,
46329
+ businessDomain: typeof auth.payload?.businessDomain === "string" ? auth.payload.businessDomain : null,
46330
+ authClaimSource,
46331
+ browserOpened: authClaimSource === "new",
46186
46332
  rollbackCommand: rollbackCommand(scope, root),
46187
46333
  statePath,
46188
46334
  doctor: doctorPayload,
@@ -46214,7 +46360,10 @@ async function runSetupCommand(options) {
46214
46360
  return 0;
46215
46361
  }
46216
46362
  function registerSetupCommands(program) {
46217
- program.command("setup").description("Install skills, authenticate, and verify Deepline.").option("--scope <scope>", "Setup scope: global or local", "global").option("--json", "Emit one final JSON result envelope").addHelpText(
46363
+ program.command("setup").description("Install skills, authenticate, and verify Deepline.").option("--scope <scope>", "Setup scope: global or local", "global").option(
46364
+ "--org-name <name>",
46365
+ "Connect to an existing workspace, or name your first workspace"
46366
+ ).option("--json", "Emit one final JSON result envelope").addHelpText(
46218
46367
  "after",
46219
46368
  `
46220
46369
  Notes:
@@ -46224,6 +46373,7 @@ Notes:
46224
46373
 
46225
46374
  Examples:
46226
46375
  deepline setup --json
46376
+ deepline setup --org-name Acme --json
46227
46377
  deepline setup --scope local --json
46228
46378
  `
46229
46379
  ).action(async (options) => {