deepline 0.3.207 → 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.
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
200
200
  // getters keep their established compatibility behavior.
201
201
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
202
202
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
203
- version: '0.3.207',
203
+ version: '0.3.208',
204
204
  updateSummary:
205
205
  '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.',
206
206
  packageCapabilities: {
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.207",
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"
@@ -45452,11 +45487,24 @@ function openSetupAuthorization(authorizationUrl, options = {}) {
45452
45487
  }
45453
45488
  function buildPendingAuthorizationOutput(input2) {
45454
45489
  const authorizationUrl = input2.authorizationUrl.trim();
45455
- if (input2.browserOpenStatus === "opened") {
45490
+ if (input2.browserOpenStatus === "existing_claim" && authorizationUrl) {
45456
45491
  return {
45457
- authorizationUrl: null,
45458
- next: `Complete browser approval, then run: ${input2.resumeCommand}`,
45459
- 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
+ ]
45460
45508
  };
45461
45509
  }
45462
45510
  if (authorizationUrl) {
@@ -45646,15 +45694,16 @@ function rollbackCommand(scope, root) {
45646
45694
  const allowScriptsFlag = npmSupportsAllowScripts(readNpmVersion(process.env)) ? " --allow-scripts=esbuild" : "";
45647
45695
  return `npm install -g${prefix} --no-audit --no-fund --include=optional${allowScriptsFlag} deepline@${SDK_VERSION}`;
45648
45696
  }
45649
- function setupResumeCommand(baseUrl, scope) {
45697
+ function setupResumeCommand(baseUrl, scope, orgName) {
45650
45698
  const hostPrefix = baseUrl === "https://code.deepline.com" ? "" : `DEEPLINE_HOST_URL=${JSON.stringify(baseUrl)} `;
45651
- 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`;
45652
45701
  }
45653
45702
  function setupRetry(input2) {
45654
45703
  return {
45655
45704
  phase: input2.phase,
45656
- command: setupResumeCommand(input2.baseUrl, input2.scope),
45657
- automatic: true
45705
+ command: setupResumeCommand(input2.baseUrl, input2.scope, input2.orgName),
45706
+ automatic: input2.retryAutomatic ?? true
45658
45707
  };
45659
45708
  }
45660
45709
  function reportSetupPhaseFailure(input2) {
@@ -45710,6 +45759,7 @@ function reportSetupAuthStatusFailure(input2) {
45710
45759
  scope: input2.scope,
45711
45760
  root: input2.root,
45712
45761
  phases: input2.phases,
45762
+ orgName: input2.orgName,
45713
45763
  phase: "auth",
45714
45764
  code: "AUTH_STATUS_FAILED",
45715
45765
  exitCode: 4,
@@ -45832,22 +45882,14 @@ function pendingResult(input2) {
45832
45882
  status: "authorization_pending",
45833
45883
  phases: input2.phases
45834
45884
  });
45835
- let browserOpenStatus = "failed";
45836
- if (input2.authorizationUrl) {
45837
- browserOpenStatus = openSetupAuthorization(input2.authorizationUrl);
45838
- if (browserOpenStatus === "opened") {
45839
- process.stderr.write(
45840
- "Opened Deepline authorization in your browser. Complete approval there.\n"
45841
- );
45842
- } else if (browserOpenStatus === "failed") {
45843
- process.stderr.write(`Authorize Deepline: ${input2.authorizationUrl}
45844
- `);
45845
- }
45846
- }
45847
45885
  const pendingOutput = buildPendingAuthorizationOutput({
45848
45886
  authorizationUrl: input2.authorizationUrl,
45849
- browserOpenStatus,
45850
- resumeCommand: setupResumeCommand(input2.baseUrl, input2.scope)
45887
+ browserOpenStatus: input2.browserOpenStatus,
45888
+ resumeCommand: setupResumeCommand(
45889
+ input2.baseUrl,
45890
+ input2.scope,
45891
+ input2.orgName
45892
+ )
45851
45893
  });
45852
45894
  printCommandEnvelope(
45853
45895
  {
@@ -45856,8 +45898,9 @@ function pendingResult(input2) {
45856
45898
  complete: false,
45857
45899
  scope: input2.scope,
45858
45900
  authorizationUrl: pendingOutput.authorizationUrl,
45859
- browserOpened: browserOpenStatus === "opened",
45860
- browserOpenStatus,
45901
+ browserOpened: input2.browserOpenStatus === "timed_out",
45902
+ browserOpenStatus: input2.browserOpenStatus,
45903
+ authClaimSource: input2.authClaimSource,
45861
45904
  statePath,
45862
45905
  phases: input2.phases,
45863
45906
  currentPhase: "auth",
@@ -45865,7 +45908,8 @@ function pendingResult(input2) {
45865
45908
  retry: setupRetry({
45866
45909
  baseUrl: input2.baseUrl,
45867
45910
  scope: input2.scope,
45868
- phase: "auth"
45911
+ phase: "auth",
45912
+ orgName: input2.orgName
45869
45913
  }),
45870
45914
  next: pendingOutput.next,
45871
45915
  render: {
@@ -45882,6 +45926,20 @@ function pendingResult(input2) {
45882
45926
  return 0;
45883
45927
  }
45884
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
+ }
45885
45943
  let scope;
45886
45944
  let root;
45887
45945
  try {
@@ -45926,6 +45984,7 @@ async function runSetupCommand(options) {
45926
45984
  exitCode: 7,
45927
45985
  message: installedButUnreachable ? `The global Deepline executable is not reachable on PATH: ${globalCli.persistentPath}` : "No persistent global Deepline executable was found.",
45928
45986
  json: options.json,
45987
+ orgName,
45929
45988
  extra: {
45930
45989
  persistentPath: globalCli.persistentPath,
45931
45990
  fallback: "https://code.deepline.com/INSTALL.md"
@@ -45945,6 +46004,7 @@ async function runSetupCommand(options) {
45945
46004
  exitCode: 7,
45946
46005
  message: `An unknown executable named deepline is first on PATH: ${conflict}`,
45947
46006
  json: options.json,
46007
+ orgName,
45948
46008
  extra: { path: conflict }
45949
46009
  });
45950
46010
  }
@@ -45978,7 +46038,8 @@ async function runSetupCommand(options) {
45978
46038
  code: "LEGACY_CLEANUP_FAILED",
45979
46039
  exitCode: 5,
45980
46040
  message: error instanceof Error ? error.message : String(error),
45981
- json: options.json
46041
+ json: options.json,
46042
+ orgName
45982
46043
  });
45983
46044
  }
45984
46045
  }
@@ -45999,7 +46060,7 @@ async function runSetupCommand(options) {
45999
46060
  process.stderr.write(
46000
46061
  "Global skill setup failed. Trying project-local skills instead.\n"
46001
46062
  );
46002
- return runSetupCommand({ scope: "local", json: options.json });
46063
+ return runSetupCommand({ scope: "local", json: options.json, orgName });
46003
46064
  }
46004
46065
  return reportSetupPhaseFailure({
46005
46066
  baseUrl,
@@ -46011,7 +46072,8 @@ async function runSetupCommand(options) {
46011
46072
  exitCode: skills.exitCode,
46012
46073
  message: typeof skillsPayload?.message === "string" ? skillsPayload.message : "Deepline skills could not be installed.",
46013
46074
  json: options.json,
46014
- next: `! ${setupResumeCommand(baseUrl, scope)}`,
46075
+ orgName,
46076
+ next: `! ${setupResumeCommand(baseUrl, scope, orgName)}`,
46015
46077
  extra: { detail: skillsPayload }
46016
46078
  });
46017
46079
  }
@@ -46033,6 +46095,13 @@ async function runSetupCommand(options) {
46033
46095
  );
46034
46096
  }
46035
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
+ }
46036
46105
  beginSetupPhase(phases, "auth");
46037
46106
  persistSetupProgress({ baseUrl, scope, root, phases });
46038
46107
  let auth = await readAuthStatus(authScope);
@@ -46043,88 +46112,146 @@ async function runSetupCommand(options) {
46043
46112
  scope,
46044
46113
  root,
46045
46114
  phases,
46115
+ orgName,
46046
46116
  json: options.json
46047
46117
  });
46048
46118
  if (initialAuthFailure !== null) return initialAuthFailure;
46049
- if (auth.payload?.connected !== true) {
46050
- const pending = readPendingAuthClaim(baseUrl, authScope);
46051
- if (pending) {
46052
- process.stderr.write("Checking pending Deepline authorization...\n");
46053
- await captureStdout2(
46054
- () => handleWait(["--timeout", "1", "--auth-scope", authScope])
46055
- );
46056
- auth = await readAuthStatus(authScope);
46057
- const resumedAuthFailure = reportSetupAuthStatusFailure({
46058
- auth,
46059
- baseUrl,
46060
- authScope,
46061
- scope,
46062
- root,
46063
- phases,
46064
- json: options.json
46065
- });
46066
- if (resumedAuthFailure !== null) return resumedAuthFailure;
46067
- if (auth.payload?.connected !== true) {
46068
- const stillPending = readPendingAuthClaim(baseUrl, authScope);
46069
- if (stillPending) {
46070
- return pendingResult({
46071
- baseUrl,
46072
- scope,
46073
- root,
46074
- phases,
46075
- authorizationUrl: stillPending.claimUrl,
46076
- resumed,
46077
- json: options.json
46078
- });
46079
- }
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
+ });
46080
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
+ });
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");
46081
46190
  }
46082
- }
46083
- if (auth.payload?.connected !== true) {
46084
- process.stderr.write("Starting Deepline browser authorization...\n");
46085
- const agentRuntime = detectAgentRuntime();
46086
- const agentLed = agentRuntime !== "unknown";
46087
- const waitMode = options.json || agentLed || !process.stdin.isTTY ? "no" : "auto";
46088
- const registered = await captureStdout2(
46089
- () => 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])
46090
46196
  );
46091
- if (registered.exitCode !== 0) {
46092
- return reportSetupPhaseFailure({
46093
- baseUrl,
46094
- scope,
46095
- root,
46096
- phases,
46097
- phase: "auth",
46098
- code: "AUTH_REGISTER_FAILED",
46099
- exitCode: registered.exitCode,
46100
- message: "Deepline browser authorization could not be started.",
46101
- json: options.json,
46102
- extra: {
46103
- detail: parseCapturedJson(registered.stdout),
46104
- authScope
46105
- }
46106
- });
46107
- }
46108
46197
  auth = await readAuthStatus(authScope);
46109
- const registeredAuthFailure = reportSetupAuthStatusFailure({
46198
+ const authFailure = reportSetupAuthStatusFailure({
46110
46199
  auth,
46111
46200
  baseUrl,
46112
46201
  authScope,
46113
46202
  scope,
46114
46203
  root,
46115
46204
  phases,
46205
+ orgName,
46116
46206
  json: options.json
46117
46207
  });
46118
- if (registeredAuthFailure !== null) return registeredAuthFailure;
46119
- if (auth.payload?.connected !== true) {
46120
- const pending = readPendingAuthClaim(baseUrl, authScope);
46121
- return pendingResult({
46208
+ if (authFailure !== null) return authFailure;
46209
+ if (waited.exitCode === EXIT_WORKSPACE_MISMATCH) {
46210
+ return reportSetupPhaseFailure({
46122
46211
  baseUrl,
46123
46212
  scope,
46124
46213
  root,
46125
46214
  phases,
46126
- authorizationUrl: pending?.claimUrl ?? "",
46127
- resumed,
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({
46242
+ baseUrl,
46243
+ scope,
46244
+ root,
46245
+ phases,
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
+ } : {},
46128
46255
  json: options.json
46129
46256
  });
46130
46257
  }
@@ -46158,6 +46285,7 @@ async function runSetupCommand(options) {
46158
46285
  code: "DOCTOR_FAILED",
46159
46286
  exitCode: 7,
46160
46287
  message: "Deepline setup verification found one or more failed checks.",
46288
+ orgName,
46161
46289
  json: options.json,
46162
46290
  extra: {
46163
46291
  doctor: doctorPayload,
@@ -46198,6 +46326,9 @@ async function runSetupCommand(options) {
46198
46326
  cliVersion: SDK_VERSION,
46199
46327
  agents: installedAgents,
46200
46328
  workspace: apiCheck?.workspace ?? null,
46329
+ businessDomain: typeof auth.payload?.businessDomain === "string" ? auth.payload.businessDomain : null,
46330
+ authClaimSource,
46331
+ browserOpened: authClaimSource === "new",
46201
46332
  rollbackCommand: rollbackCommand(scope, root),
46202
46333
  statePath,
46203
46334
  doctor: doctorPayload,
@@ -46229,7 +46360,10 @@ async function runSetupCommand(options) {
46229
46360
  return 0;
46230
46361
  }
46231
46362
  function registerSetupCommands(program) {
46232
- 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(
46233
46367
  "after",
46234
46368
  `
46235
46369
  Notes:
@@ -46239,6 +46373,7 @@ Notes:
46239
46373
 
46240
46374
  Examples:
46241
46375
  deepline setup --json
46376
+ deepline setup --org-name Acme --json
46242
46377
  deepline setup --scope local --json
46243
46378
  `
46244
46379
  ).action(async (options) => {
@@ -3046,7 +3046,7 @@ var SDK_RELEASE = {
3046
3046
  // getters keep their established compatibility behavior.
3047
3047
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3048
3048
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3049
- version: "0.3.207",
3049
+ version: "0.3.208",
3050
3050
  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.",
3051
3051
  packageCapabilities: {
3052
3052
  updatePreferences: 1
@@ -11652,6 +11652,7 @@ function printCommandEnvelope(envelope, options = {}) {
11652
11652
  var EXIT_OK = 0;
11653
11653
  var EXIT_AUTH = 3;
11654
11654
  var EXIT_SERVER = 5;
11655
+ var EXIT_WORKSPACE_MISMATCH = 6;
11655
11656
  var AUTH_HTTP_TIMEOUT_MS = 1e4;
11656
11657
  var AUTH_REGISTER_HTTP_TIMEOUT_MS = 3e4;
11657
11658
  function statusBannerLine(value) {
@@ -11742,7 +11743,8 @@ function readPendingAuthClaim(baseUrl, scope) {
11742
11743
  if (!claimToken) return null;
11743
11744
  return {
11744
11745
  claimToken,
11745
- claimUrl: typeof parsed.claimUrl === "string" ? parsed.claimUrl.trim() : "",
11746
+ claimUrl: typeof parsed.claimUrl === "string" && parsed.claimUrl.trim() ? parsed.claimUrl.trim() : `${baseUrl}/api/v2/auth/cli/claim/${encodeURIComponent(claimToken)}`,
11747
+ orgName: typeof parsed.orgName === "string" ? parsed.orgName.trim() : void 0,
11746
11748
  // The record's own scope, when it has one. `register` writes this field
11747
11749
  // precisely so a resume can learn where the credential belongs; reading
11748
11750
  // back the caller's argument instead made it decorative, and a record
@@ -11763,6 +11765,14 @@ function clearPendingClaim(baseUrl, scope) {
11763
11765
  } catch {
11764
11766
  }
11765
11767
  }
11768
+ function clearSatisfiedPendingClaim(baseUrl, scope, connectedWorkspaceName) {
11769
+ const pending = readPendingAuthClaim(baseUrl, scope);
11770
+ if (!pending) return;
11771
+ if (pending.orgName && pending.orgName.toLowerCase() !== connectedWorkspaceName?.trim().toLowerCase()) {
11772
+ return;
11773
+ }
11774
+ clearPendingClaim(baseUrl, scope);
11775
+ }
11766
11776
  function parseRegisterWaitMode(args) {
11767
11777
  let mode = "auto";
11768
11778
  for (let i = 0; i < args.length; i++) {
@@ -12000,7 +12010,12 @@ async function handleRegister(args) {
12000
12010
  const claimUrl = String(data.claim_url || "");
12001
12011
  const claimToken = String(data.claim_token || "");
12002
12012
  if (claimToken) {
12003
- savePendingClaim(baseUrl, { claimToken, claimUrl, scope: authScope });
12013
+ savePendingClaim(baseUrl, {
12014
+ claimToken,
12015
+ claimUrl,
12016
+ scope: authScope,
12017
+ ...orgName ? { orgName } : {}
12018
+ });
12004
12019
  saveEnvValues(
12005
12020
  {
12006
12021
  [HOST_URL_ENV]: baseUrl
@@ -12046,6 +12061,13 @@ async function handleRegister(args) {
12046
12061
  return EXIT_SERVER;
12047
12062
  }
12048
12063
  const state = String(statusData.status || "").toLowerCase();
12064
+ if (statusData.code === "REQUESTED_WORKSPACE_NOT_IN_ACCOUNT") {
12065
+ clearPendingClaim(baseUrl, authScope);
12066
+ console.error(
12067
+ "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."
12068
+ );
12069
+ return EXIT_WORKSPACE_MISMATCH;
12070
+ }
12049
12071
  if (state === "claimed") {
12050
12072
  const apiKey = String(statusData.api_key || "");
12051
12073
  if (apiKey) {
@@ -12107,12 +12129,13 @@ async function handleWait(args) {
12107
12129
  return EXIT_AUTH;
12108
12130
  }
12109
12131
  const deadline = Date.now() + timeoutSeconds * 1e3;
12110
- while (Date.now() <= deadline) {
12132
+ while (Date.now() < deadline) {
12111
12133
  const { status, data } = await httpJson(
12112
12134
  "POST",
12113
12135
  `${baseUrl}/api/v2/auth/cli/status`,
12114
12136
  null,
12115
- { claim_token: claimToken, reveal: true }
12137
+ { claim_token: claimToken, reveal: true },
12138
+ Math.min(AUTH_HTTP_TIMEOUT_MS, Math.max(1, deadline - Date.now()))
12116
12139
  );
12117
12140
  if (status === 401 || status === 403) {
12118
12141
  clearPendingClaim(baseUrl, authScope);
@@ -12120,7 +12143,7 @@ async function handleWait(args) {
12120
12143
  return EXIT_AUTH;
12121
12144
  }
12122
12145
  if (status >= 500 || status === 0 || status === 400) {
12123
- await sleep4(2e3);
12146
+ await sleep4(Math.min(2e3, Math.max(0, deadline - Date.now())));
12124
12147
  continue;
12125
12148
  }
12126
12149
  if (status >= 400) {
@@ -12128,6 +12151,13 @@ async function handleWait(args) {
12128
12151
  return EXIT_SERVER;
12129
12152
  }
12130
12153
  const state = String(data.status || "").toLowerCase();
12154
+ if (data.code === "REQUESTED_WORKSPACE_NOT_IN_ACCOUNT") {
12155
+ clearPendingClaim(baseUrl, authScope);
12156
+ console.error(
12157
+ "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."
12158
+ );
12159
+ return EXIT_WORKSPACE_MISMATCH;
12160
+ }
12131
12161
  if (state === "claimed") {
12132
12162
  const apiKey = String(data.api_key || "");
12133
12163
  if (apiKey) {
@@ -12150,7 +12180,7 @@ async function handleWait(args) {
12150
12180
  console.error("That approval link expired. Run: deepline auth register");
12151
12181
  return EXIT_AUTH;
12152
12182
  }
12153
- await sleep4(2e3);
12183
+ await sleep4(Math.min(2e3, Math.max(0, deadline - Date.now())));
12154
12184
  }
12155
12185
  console.error(
12156
12186
  "Still pending. Approve the browser link, then run: deepline auth wait"
@@ -12295,7 +12325,11 @@ async function handleStatus(args) {
12295
12325
  return EXIT_SERVER;
12296
12326
  }
12297
12327
  const resolvedAuthScope = authScope ?? (getResolvedProjectAuthSource(baseUrl, apiKey) ? "folder" : "global");
12298
- clearPendingClaim(baseUrl, resolvedAuthScope);
12328
+ clearSatisfiedPendingClaim(
12329
+ baseUrl,
12330
+ resolvedAuthScope,
12331
+ typeof data.org_name === "string" ? data.org_name : null
12332
+ );
12299
12333
  const payload = {
12300
12334
  ...hostStatusPayload ?? { host: baseUrl },
12301
12335
  status: data.status || "(unknown)",
@@ -12309,6 +12343,7 @@ async function handleStatus(args) {
12309
12343
  user: {
12310
12344
  id: data.user_id ?? null
12311
12345
  },
12346
+ businessDomain: typeof data.business_domain === "string" ? data.business_domain : null,
12312
12347
  examples: Array.isArray(data.examples) ? data.examples : []
12313
12348
  };
12314
12349
  let savedApiKeyPath = null;
@@ -12420,7 +12455,7 @@ Examples:
12420
12455
  `
12421
12456
  ).option(
12422
12457
  "--org-name <name>",
12423
- "Use this workspace, or create a separate one with this name"
12458
+ "Connect to an existing workspace, or name your first workspace"
12424
12459
  ).option(
12425
12460
  "--org-id <id>",
12426
12461
  "Bind to this workspace directly, skipping the browser picker"
@@ -45562,11 +45597,24 @@ function openSetupAuthorization(authorizationUrl, options = {}) {
45562
45597
  }
45563
45598
  function buildPendingAuthorizationOutput(input2) {
45564
45599
  const authorizationUrl = input2.authorizationUrl.trim();
45565
- if (input2.browserOpenStatus === "opened") {
45600
+ if (input2.browserOpenStatus === "existing_claim" && authorizationUrl) {
45566
45601
  return {
45567
- authorizationUrl: null,
45568
- next: `Complete browser approval, then run: ${input2.resumeCommand}`,
45569
- lines: ["Complete authorization in the browser window Deepline opened."]
45602
+ authorizationUrl,
45603
+ next: `The existing approval is still pending. Use its authorization URL if needed, then run: ${input2.resumeCommand}`,
45604
+ lines: [
45605
+ "Deepline did not open another browser tab. Use the existing approval page or this link:",
45606
+ authorizationUrl
45607
+ ]
45608
+ };
45609
+ }
45610
+ if (input2.browserOpenStatus === "timed_out" && authorizationUrl) {
45611
+ return {
45612
+ authorizationUrl,
45613
+ next: `Approval is still pending after five minutes. Use the authorization URL if needed, then run: ${input2.resumeCommand}`,
45614
+ lines: [
45615
+ "Approval is still pending. Use this link if the tab was missed:",
45616
+ authorizationUrl
45617
+ ]
45570
45618
  };
45571
45619
  }
45572
45620
  if (authorizationUrl) {
@@ -45756,15 +45804,16 @@ function rollbackCommand(scope, root) {
45756
45804
  const allowScriptsFlag = npmSupportsAllowScripts(readNpmVersion(process.env)) ? " --allow-scripts=esbuild" : "";
45757
45805
  return `npm install -g${prefix} --no-audit --no-fund --include=optional${allowScriptsFlag} deepline@${SDK_VERSION}`;
45758
45806
  }
45759
- function setupResumeCommand(baseUrl, scope) {
45807
+ function setupResumeCommand(baseUrl, scope, orgName) {
45760
45808
  const hostPrefix = baseUrl === "https://code.deepline.com" ? "" : `DEEPLINE_HOST_URL=${JSON.stringify(baseUrl)} `;
45761
- return `${hostPrefix}deepline setup --scope ${scope} --json`;
45809
+ const quotedOrgName = orgName ? process.platform === "win32" ? ` --org-name "${orgName.replace(/"/g, '""')}"` : ` --org-name '${orgName.replace(/'/g, `'\\''`)}'` : "";
45810
+ return `${hostPrefix}deepline setup --scope ${scope}${quotedOrgName} --json`;
45762
45811
  }
45763
45812
  function setupRetry(input2) {
45764
45813
  return {
45765
45814
  phase: input2.phase,
45766
- command: setupResumeCommand(input2.baseUrl, input2.scope),
45767
- automatic: true
45815
+ command: setupResumeCommand(input2.baseUrl, input2.scope, input2.orgName),
45816
+ automatic: input2.retryAutomatic ?? true
45768
45817
  };
45769
45818
  }
45770
45819
  function reportSetupPhaseFailure(input2) {
@@ -45820,6 +45869,7 @@ function reportSetupAuthStatusFailure(input2) {
45820
45869
  scope: input2.scope,
45821
45870
  root: input2.root,
45822
45871
  phases: input2.phases,
45872
+ orgName: input2.orgName,
45823
45873
  phase: "auth",
45824
45874
  code: "AUTH_STATUS_FAILED",
45825
45875
  exitCode: 4,
@@ -45942,22 +45992,14 @@ function pendingResult(input2) {
45942
45992
  status: "authorization_pending",
45943
45993
  phases: input2.phases
45944
45994
  });
45945
- let browserOpenStatus = "failed";
45946
- if (input2.authorizationUrl) {
45947
- browserOpenStatus = openSetupAuthorization(input2.authorizationUrl);
45948
- if (browserOpenStatus === "opened") {
45949
- process.stderr.write(
45950
- "Opened Deepline authorization in your browser. Complete approval there.\n"
45951
- );
45952
- } else if (browserOpenStatus === "failed") {
45953
- process.stderr.write(`Authorize Deepline: ${input2.authorizationUrl}
45954
- `);
45955
- }
45956
- }
45957
45995
  const pendingOutput = buildPendingAuthorizationOutput({
45958
45996
  authorizationUrl: input2.authorizationUrl,
45959
- browserOpenStatus,
45960
- resumeCommand: setupResumeCommand(input2.baseUrl, input2.scope)
45997
+ browserOpenStatus: input2.browserOpenStatus,
45998
+ resumeCommand: setupResumeCommand(
45999
+ input2.baseUrl,
46000
+ input2.scope,
46001
+ input2.orgName
46002
+ )
45961
46003
  });
45962
46004
  printCommandEnvelope(
45963
46005
  {
@@ -45966,8 +46008,9 @@ function pendingResult(input2) {
45966
46008
  complete: false,
45967
46009
  scope: input2.scope,
45968
46010
  authorizationUrl: pendingOutput.authorizationUrl,
45969
- browserOpened: browserOpenStatus === "opened",
45970
- browserOpenStatus,
46011
+ browserOpened: input2.browserOpenStatus === "timed_out",
46012
+ browserOpenStatus: input2.browserOpenStatus,
46013
+ authClaimSource: input2.authClaimSource,
45971
46014
  statePath,
45972
46015
  phases: input2.phases,
45973
46016
  currentPhase: "auth",
@@ -45975,7 +46018,8 @@ function pendingResult(input2) {
45975
46018
  retry: setupRetry({
45976
46019
  baseUrl: input2.baseUrl,
45977
46020
  scope: input2.scope,
45978
- phase: "auth"
46021
+ phase: "auth",
46022
+ orgName: input2.orgName
45979
46023
  }),
45980
46024
  next: pendingOutput.next,
45981
46025
  render: {
@@ -45992,6 +46036,20 @@ function pendingResult(input2) {
45992
46036
  return 0;
45993
46037
  }
45994
46038
  async function runSetupCommand(options) {
46039
+ let orgName = options.orgName?.trim();
46040
+ if (options.orgName !== void 0 && !orgName) {
46041
+ printCommandEnvelope(
46042
+ {
46043
+ ok: false,
46044
+ status: "failed",
46045
+ code: "INVALID_ORG_NAME",
46046
+ exitCode: 2,
46047
+ message: "Workspace name cannot be empty."
46048
+ },
46049
+ { json: options.json }
46050
+ );
46051
+ return 2;
46052
+ }
45995
46053
  let scope;
45996
46054
  let root;
45997
46055
  try {
@@ -46036,6 +46094,7 @@ async function runSetupCommand(options) {
46036
46094
  exitCode: 7,
46037
46095
  message: installedButUnreachable ? `The global Deepline executable is not reachable on PATH: ${globalCli.persistentPath}` : "No persistent global Deepline executable was found.",
46038
46096
  json: options.json,
46097
+ orgName,
46039
46098
  extra: {
46040
46099
  persistentPath: globalCli.persistentPath,
46041
46100
  fallback: "https://code.deepline.com/INSTALL.md"
@@ -46055,6 +46114,7 @@ async function runSetupCommand(options) {
46055
46114
  exitCode: 7,
46056
46115
  message: `An unknown executable named deepline is first on PATH: ${conflict}`,
46057
46116
  json: options.json,
46117
+ orgName,
46058
46118
  extra: { path: conflict }
46059
46119
  });
46060
46120
  }
@@ -46088,7 +46148,8 @@ async function runSetupCommand(options) {
46088
46148
  code: "LEGACY_CLEANUP_FAILED",
46089
46149
  exitCode: 5,
46090
46150
  message: error instanceof Error ? error.message : String(error),
46091
- json: options.json
46151
+ json: options.json,
46152
+ orgName
46092
46153
  });
46093
46154
  }
46094
46155
  }
@@ -46109,7 +46170,7 @@ async function runSetupCommand(options) {
46109
46170
  process.stderr.write(
46110
46171
  "Global skill setup failed. Trying project-local skills instead.\n"
46111
46172
  );
46112
- return runSetupCommand({ scope: "local", json: options.json });
46173
+ return runSetupCommand({ scope: "local", json: options.json, orgName });
46113
46174
  }
46114
46175
  return reportSetupPhaseFailure({
46115
46176
  baseUrl,
@@ -46121,7 +46182,8 @@ async function runSetupCommand(options) {
46121
46182
  exitCode: skills.exitCode,
46122
46183
  message: typeof skillsPayload?.message === "string" ? skillsPayload.message : "Deepline skills could not be installed.",
46123
46184
  json: options.json,
46124
- next: `! ${setupResumeCommand(baseUrl, scope)}`,
46185
+ orgName,
46186
+ next: `! ${setupResumeCommand(baseUrl, scope, orgName)}`,
46125
46187
  extra: { detail: skillsPayload }
46126
46188
  });
46127
46189
  }
@@ -46143,6 +46205,13 @@ async function runSetupCommand(options) {
46143
46205
  );
46144
46206
  }
46145
46207
  const authScope = authScopeForSetup(scope);
46208
+ const pendingAtStart = readPendingAuthClaim(baseUrl, authScope);
46209
+ const replacingPendingClaim = Boolean(
46210
+ pendingAtStart && orgName && pendingAtStart.orgName?.toLowerCase() !== orgName.toLowerCase()
46211
+ );
46212
+ if (pendingAtStart && !replacingPendingClaim) {
46213
+ if (pendingAtStart.orgName) orgName = pendingAtStart.orgName;
46214
+ }
46146
46215
  beginSetupPhase(phases, "auth");
46147
46216
  persistSetupProgress({ baseUrl, scope, root, phases });
46148
46217
  let auth = await readAuthStatus(authScope);
@@ -46153,88 +46222,146 @@ async function runSetupCommand(options) {
46153
46222
  scope,
46154
46223
  root,
46155
46224
  phases,
46225
+ orgName,
46156
46226
  json: options.json
46157
46227
  });
46158
46228
  if (initialAuthFailure !== null) return initialAuthFailure;
46159
- if (auth.payload?.connected !== true) {
46160
- const pending = readPendingAuthClaim(baseUrl, authScope);
46161
- if (pending) {
46162
- process.stderr.write("Checking pending Deepline authorization...\n");
46163
- await captureStdout2(
46164
- () => handleWait(["--timeout", "1", "--auth-scope", authScope])
46165
- );
46166
- auth = await readAuthStatus(authScope);
46167
- const resumedAuthFailure = reportSetupAuthStatusFailure({
46168
- auth,
46169
- baseUrl,
46170
- authScope,
46171
- scope,
46172
- root,
46173
- phases,
46174
- json: options.json
46175
- });
46176
- if (resumedAuthFailure !== null) return resumedAuthFailure;
46177
- if (auth.payload?.connected !== true) {
46178
- const stillPending = readPendingAuthClaim(baseUrl, authScope);
46179
- if (stillPending) {
46180
- return pendingResult({
46181
- baseUrl,
46182
- scope,
46183
- root,
46184
- phases,
46185
- authorizationUrl: stillPending.claimUrl,
46186
- resumed,
46187
- json: options.json
46188
- });
46189
- }
46229
+ const connectedToRequestedWorkspace = () => {
46230
+ if (auth.payload?.connected !== true) return false;
46231
+ if (!orgName) return true;
46232
+ const workspace = asRecord3(auth.payload.workspace);
46233
+ return typeof workspace?.name === "string" && workspace.name.trim().toLowerCase() === orgName.toLowerCase();
46234
+ };
46235
+ let pending = replacingPendingClaim ? null : readPendingAuthClaim(baseUrl, authScope);
46236
+ if (replacingPendingClaim && connectedToRequestedWorkspace()) {
46237
+ clearPendingClaim(baseUrl, authScope);
46238
+ }
46239
+ let authClaimSource = "none";
46240
+ if (pending || !connectedToRequestedWorkspace()) {
46241
+ const reusedClaim = Boolean(pending);
46242
+ authClaimSource = reusedClaim ? "existing" : "new";
46243
+ if (!pending) {
46244
+ process.stderr.write("Starting Deepline browser authorization...\n");
46245
+ const registered = await captureStdout2(
46246
+ () => handleRegister([
46247
+ "--wait",
46248
+ "no",
46249
+ "--auth-scope",
46250
+ authScope,
46251
+ ...orgName ? ["--org-name", orgName] : []
46252
+ ])
46253
+ );
46254
+ if (registered.exitCode !== 0) {
46255
+ return reportSetupPhaseFailure({
46256
+ baseUrl,
46257
+ scope,
46258
+ root,
46259
+ phases,
46260
+ phase: "auth",
46261
+ code: "AUTH_REGISTER_FAILED",
46262
+ exitCode: registered.exitCode,
46263
+ message: "Deepline browser authorization could not be started.",
46264
+ orgName,
46265
+ json: options.json,
46266
+ extra: { detail: parseCapturedJson(registered.stdout), authScope }
46267
+ });
46190
46268
  }
46269
+ pending = readPendingAuthClaim(baseUrl, authScope);
46270
+ if (!pending?.claimUrl) {
46271
+ return reportSetupPhaseFailure({
46272
+ baseUrl,
46273
+ scope,
46274
+ root,
46275
+ phases,
46276
+ phase: "auth",
46277
+ code: "AUTH_CLAIM_URL_MISSING",
46278
+ exitCode: 4,
46279
+ message: "Deepline authorization did not return a usable claim URL.",
46280
+ orgName,
46281
+ json: options.json
46282
+ });
46283
+ }
46284
+ const browserOpenStatus = openSetupAuthorization(pending.claimUrl);
46285
+ if (browserOpenStatus === "failed") {
46286
+ return pendingResult({
46287
+ baseUrl,
46288
+ scope,
46289
+ root,
46290
+ phases,
46291
+ authorizationUrl: pending.claimUrl,
46292
+ browserOpenStatus: "failed",
46293
+ authClaimSource,
46294
+ orgName,
46295
+ resumed,
46296
+ json: options.json
46297
+ });
46298
+ }
46299
+ process.stderr.write("Opened Deepline sign-in in the browser.\n");
46191
46300
  }
46192
- }
46193
- if (auth.payload?.connected !== true) {
46194
- process.stderr.write("Starting Deepline browser authorization...\n");
46195
- const agentRuntime = detectAgentRuntime();
46196
- const agentLed = agentRuntime !== "unknown";
46197
- const waitMode = options.json || agentLed || !process.stdin.isTTY ? "no" : "auto";
46198
- const registered = await captureStdout2(
46199
- () => handleRegister(["--wait", waitMode, "--auth-scope", authScope])
46301
+ process.stderr.write(
46302
+ "Waiting up to five minutes for Deepline approval...\n"
46303
+ );
46304
+ const waited = await captureStdout2(
46305
+ () => handleWait(["--timeout", "300", "--auth-scope", authScope])
46200
46306
  );
46201
- if (registered.exitCode !== 0) {
46202
- return reportSetupPhaseFailure({
46203
- baseUrl,
46204
- scope,
46205
- root,
46206
- phases,
46207
- phase: "auth",
46208
- code: "AUTH_REGISTER_FAILED",
46209
- exitCode: registered.exitCode,
46210
- message: "Deepline browser authorization could not be started.",
46211
- json: options.json,
46212
- extra: {
46213
- detail: parseCapturedJson(registered.stdout),
46214
- authScope
46215
- }
46216
- });
46217
- }
46218
46307
  auth = await readAuthStatus(authScope);
46219
- const registeredAuthFailure = reportSetupAuthStatusFailure({
46308
+ const authFailure = reportSetupAuthStatusFailure({
46220
46309
  auth,
46221
46310
  baseUrl,
46222
46311
  authScope,
46223
46312
  scope,
46224
46313
  root,
46225
46314
  phases,
46315
+ orgName,
46226
46316
  json: options.json
46227
46317
  });
46228
- if (registeredAuthFailure !== null) return registeredAuthFailure;
46229
- if (auth.payload?.connected !== true) {
46230
- const pending = readPendingAuthClaim(baseUrl, authScope);
46231
- return pendingResult({
46318
+ if (authFailure !== null) return authFailure;
46319
+ if (waited.exitCode === EXIT_WORKSPACE_MISMATCH) {
46320
+ return reportSetupPhaseFailure({
46232
46321
  baseUrl,
46233
46322
  scope,
46234
46323
  root,
46235
46324
  phases,
46236
- authorizationUrl: pending?.claimUrl ?? "",
46237
- resumed,
46325
+ phase: "auth",
46326
+ code: "REQUESTED_WORKSPACE_NOT_IN_ACCOUNT",
46327
+ exitCode: EXIT_WORKSPACE_MISMATCH,
46328
+ 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.`,
46329
+ orgName,
46330
+ retryAutomatic: false,
46331
+ 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.",
46332
+ json: options.json
46333
+ });
46334
+ }
46335
+ if (!connectedToRequestedWorkspace()) {
46336
+ const stillPending = readPendingAuthClaim(baseUrl, authScope);
46337
+ if (stillPending?.claimUrl) {
46338
+ return pendingResult({
46339
+ baseUrl,
46340
+ scope,
46341
+ root,
46342
+ phases,
46343
+ authorizationUrl: stillPending.claimUrl,
46344
+ browserOpenStatus: reusedClaim ? "existing_claim" : "timed_out",
46345
+ authClaimSource,
46346
+ orgName,
46347
+ resumed,
46348
+ json: options.json
46349
+ });
46350
+ }
46351
+ return reportSetupPhaseFailure({
46352
+ baseUrl,
46353
+ scope,
46354
+ root,
46355
+ phases,
46356
+ phase: "auth",
46357
+ code: orgName && auth.payload?.connected ? "AUTH_WORKSPACE_MISMATCH" : "AUTH_WAIT_FAILED",
46358
+ exitCode: waited.exitCode || 4,
46359
+ message: orgName && auth.payload?.connected ? `Deepline is connected to a different workspace than ${orgName}.` : "Deepline authorization did not complete.",
46360
+ orgName,
46361
+ ...orgName && auth.payload?.connected ? {
46362
+ retryAutomatic: false,
46363
+ next: "Ask the user which existing workspace or account to use. Rerun setup with --org-name set to the confirmed workspace."
46364
+ } : {},
46238
46365
  json: options.json
46239
46366
  });
46240
46367
  }
@@ -46268,6 +46395,7 @@ async function runSetupCommand(options) {
46268
46395
  code: "DOCTOR_FAILED",
46269
46396
  exitCode: 7,
46270
46397
  message: "Deepline setup verification found one or more failed checks.",
46398
+ orgName,
46271
46399
  json: options.json,
46272
46400
  extra: {
46273
46401
  doctor: doctorPayload,
@@ -46308,6 +46436,9 @@ async function runSetupCommand(options) {
46308
46436
  cliVersion: SDK_VERSION,
46309
46437
  agents: installedAgents,
46310
46438
  workspace: apiCheck?.workspace ?? null,
46439
+ businessDomain: typeof auth.payload?.businessDomain === "string" ? auth.payload.businessDomain : null,
46440
+ authClaimSource,
46441
+ browserOpened: authClaimSource === "new",
46311
46442
  rollbackCommand: rollbackCommand(scope, root),
46312
46443
  statePath,
46313
46444
  doctor: doctorPayload,
@@ -46339,7 +46470,10 @@ async function runSetupCommand(options) {
46339
46470
  return 0;
46340
46471
  }
46341
46472
  function registerSetupCommands(program) {
46342
- 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(
46473
+ program.command("setup").description("Install skills, authenticate, and verify Deepline.").option("--scope <scope>", "Setup scope: global or local", "global").option(
46474
+ "--org-name <name>",
46475
+ "Connect to an existing workspace, or name your first workspace"
46476
+ ).option("--json", "Emit one final JSON result envelope").addHelpText(
46343
46477
  "after",
46344
46478
  `
46345
46479
  Notes:
@@ -46349,6 +46483,7 @@ Notes:
46349
46483
 
46350
46484
  Examples:
46351
46485
  deepline setup --json
46486
+ deepline setup --org-name Acme --json
46352
46487
  deepline setup --scope local --json
46353
46488
  `
46354
46489
  ).action(async (options) => {
package/dist/index.js CHANGED
@@ -864,7 +864,7 @@ var SDK_RELEASE = {
864
864
  // getters keep their established compatibility behavior.
865
865
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
866
866
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
867
- version: "0.3.207",
867
+ version: "0.3.208",
868
868
  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.",
869
869
  packageCapabilities: {
870
870
  updatePreferences: 1
package/dist/index.mjs CHANGED
@@ -768,7 +768,7 @@ var SDK_RELEASE = {
768
768
  // getters keep their established compatibility behavior.
769
769
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
770
770
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
771
- version: "0.3.207",
771
+ version: "0.3.208",
772
772
  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.",
773
773
  packageCapabilities: {
774
774
  updatePreferences: 1
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.207";
152
+ readonly version: "0.3.208";
153
153
  readonly 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.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.d.ts CHANGED
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.207";
152
+ readonly version: "0.3.208";
153
153
  readonly 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.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.js CHANGED
@@ -74,7 +74,7 @@ var SDK_RELEASE = {
74
74
  // getters keep their established compatibility behavior.
75
75
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
76
76
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
77
- version: "0.3.207",
77
+ version: "0.3.208",
78
78
  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.",
79
79
  packageCapabilities: {
80
80
  updatePreferences: 1
package/dist/release.mjs CHANGED
@@ -48,7 +48,7 @@ var SDK_RELEASE = {
48
48
  // getters keep their established compatibility behavior.
49
49
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
50
50
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
51
- version: "0.3.207",
51
+ version: "0.3.208",
52
52
  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.",
53
53
  packageCapabilities: {
54
54
  updatePreferences: 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.3.207",
3
+ "version": "0.3.208",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",