deepline 0.3.61 → 0.3.63

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.
@@ -1105,7 +1105,7 @@ var SDK_RELEASE = {
1105
1105
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1106
1106
  // getters keep their established compatibility behavior.
1107
1107
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1108
- version: "0.3.61",
1108
+ version: "0.3.63",
1109
1109
  updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
1110
1110
  packageCapabilities: {
1111
1111
  updatePreferences: 1
@@ -22148,7 +22148,7 @@ async function handleFileBackedRun(options, hooks) {
22148
22148
  package: options.fullJson ? void 0 : started.package,
22149
22149
  jsonOutput: options.jsonOutput,
22150
22150
  progress,
22151
- inputFieldCount: Object.keys(options.input ?? {}).length,
22151
+ inputFieldCount: Object.keys(runtimeInput).length,
22152
22152
  revisionLabel: "local file revision",
22153
22153
  force: options.force,
22154
22154
  forceToolRefresh: options.forceToolRefresh
@@ -22335,7 +22335,7 @@ async function handleNamedRun(options, hooks) {
22335
22335
  package: options.fullJson ? void 0 : started.package,
22336
22336
  jsonOutput: options.jsonOutput,
22337
22337
  progress,
22338
- inputFieldCount: Object.keys(options.input ?? {}).length,
22338
+ inputFieldCount: Object.keys(runtimeInput).length,
22339
22339
  revisionLabel: selectedRevisionId ? `pinned revision ${selectedRevisionId}` : "live revision",
22340
22340
  force: options.force,
22341
22341
  forceToolRefresh: options.forceToolRefresh
@@ -34871,6 +34871,318 @@ function resolveShellSpawn(command, args, platform3 = process.platform) {
34871
34871
  };
34872
34872
  }
34873
34873
 
34874
+ // src/cli/failure-reporting.ts
34875
+ import { hostname as hostname2, platform as platform2, release } from "os";
34876
+ var FAILURE_REPORT_DISABLE_ENV = "DEEPLINE_DISABLE_FAILURE_REPORTING";
34877
+ var REPORT_FAILURE_TIMEOUT_MS = 1e4;
34878
+ var BACKGROUND_REPORT_FAILURE_TIMEOUT_MS = 2e3;
34879
+ var MAX_FAILURE_TEXT_CHARS = 4e3;
34880
+ var MAX_COMMAND_TOKENS = 3;
34881
+ var REPORTABLE_EXIT_CODES = /* @__PURE__ */ new Set([4, 5]);
34882
+ var EMAIL_RE = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
34883
+ var UNIX_PATH_RE = /(?:\/Users\/|\/home\/|\/var\/folders\/|\/tmp\/|\/sessions\/)[^"'\n\r`]+/g;
34884
+ var WINDOWS_PATH_RE = /[A-Za-z]:(?:\\{1,2})(?:Users|Temp|tmp)(?:\\{1,2})[^"'\n\r`]+/g;
34885
+ var ASSIGNMENT_SECRET_RE = /\b(access[_-]?token|api[_-]?key|apikey|auth(?:orization)?|bearer|password|secret|session)\b(\s*[:=]\s*)(?!Bearer\s+\[redacted-secret\])([^\s,;]+)/gi;
34886
+ var BEARER_SECRET_RE = /\b(bearer)\s+([A-Za-z0-9._-]+)/gi;
34887
+ var GENERIC_TOKEN_RE = /\b(?:dlp|sk|ghp|xox[baprs])[-_A-Za-z0-9]{8,}\b/g;
34888
+ var SECRET_OPTION_RE = /^--?(?:access[-_]?token|api[-_]?key|apikey|auth(?:orization)?|bearer|password|secret|session|token)$/i;
34889
+ function truthyEnv2(name) {
34890
+ return ["1", "true", "yes", "on"].includes(
34891
+ String(process.env[name] ?? "").trim().toLowerCase()
34892
+ );
34893
+ }
34894
+ function isFailureReportingDisabled() {
34895
+ return truthyEnv2(FAILURE_REPORT_DISABLE_ENV);
34896
+ }
34897
+ function redactFailureText(value, maxChars = MAX_FAILURE_TEXT_CHARS) {
34898
+ const home = process.env.HOME?.trim();
34899
+ let text = String(value ?? "");
34900
+ if (!text) return "";
34901
+ if (home && home !== "/") {
34902
+ text = text.split(home).join("~");
34903
+ }
34904
+ return text.replace(EMAIL_RE, "[redacted-email]").replace(UNIX_PATH_RE, "[redacted-path]").replace(WINDOWS_PATH_RE, "[redacted-path]").replace(BEARER_SECRET_RE, "$1 [redacted-secret]").replace(ASSIGNMENT_SECRET_RE, "$1$2[redacted-secret]").replace(GENERIC_TOKEN_RE, "[redacted-secret]").slice(0, maxChars);
34905
+ }
34906
+ function sanitizeCommand(argv, prefix = "deepline") {
34907
+ const tokens = [];
34908
+ for (let index = 0; index < argv.length; index += 1) {
34909
+ const arg = argv[index];
34910
+ const value = String(arg ?? "").trim();
34911
+ if (!value) continue;
34912
+ if (value.startsWith("-")) {
34913
+ if (!value.includes("=") && SECRET_OPTION_RE.test(value)) {
34914
+ index += 1;
34915
+ }
34916
+ continue;
34917
+ }
34918
+ tokens.push(redactFailureText(value, 200));
34919
+ if (tokens.length >= MAX_COMMAND_TOKENS) break;
34920
+ }
34921
+ return tokens.length > 0 ? [prefix, ...tokens].join(" ") : prefix;
34922
+ }
34923
+ function errorMessage3(error) {
34924
+ if (error instanceof Error) return `${error.name}: ${error.message}`;
34925
+ return String(error ?? "");
34926
+ }
34927
+ function errorStack(error) {
34928
+ if (error instanceof Error && error.stack) {
34929
+ return redactFailureText(error.stack);
34930
+ }
34931
+ return null;
34932
+ }
34933
+ function classifyNetworkFailure(error) {
34934
+ const seen = /* @__PURE__ */ new Set();
34935
+ let current = error;
34936
+ while (current && !seen.has(current)) {
34937
+ seen.add(current);
34938
+ const record2 = typeof current === "object" && current !== null ? current : {};
34939
+ const code = String(record2.code ?? "").toLowerCase();
34940
+ const name = current instanceof Error ? current.name.toLowerCase() : "";
34941
+ const text = String(
34942
+ current instanceof Error ? current.message : current
34943
+ ).toLowerCase();
34944
+ const combined = `${code} ${name} ${text}`;
34945
+ if (combined.includes("aborterror") || combined.includes("timeout") || combined.includes("timed out") || combined.includes("etimedout")) {
34946
+ return "network_timeout";
34947
+ }
34948
+ if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
34949
+ return "network_dns_resolution_failed";
34950
+ }
34951
+ if (combined.includes("econnrefused") || combined.includes("connection refused")) {
34952
+ return "network_connection_refused";
34953
+ }
34954
+ if (combined.includes("econnreset") || combined.includes("connection reset")) {
34955
+ return "network_connection_reset";
34956
+ }
34957
+ if (combined.includes("incompleteread") || combined.includes("incomplete read")) {
34958
+ return "network_incomplete_read";
34959
+ }
34960
+ if (combined.includes("remotedisconnected") || combined.includes("remote end closed connection") || combined.includes("other side closed") || combined.includes("socket hang up")) {
34961
+ return "network_remote_disconnected";
34962
+ }
34963
+ if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
34964
+ return "network_ssl_error";
34965
+ }
34966
+ current = record2.cause ?? record2.context;
34967
+ }
34968
+ return "network_error";
34969
+ }
34970
+ function isNetworkFailure(error) {
34971
+ if (!(error instanceof Error)) return false;
34972
+ if (error instanceof DeeplineError && error.statusCode) return false;
34973
+ const code = classifyNetworkFailure(error);
34974
+ return code !== "network_error" || /unable to connect|unable to stream/i.test(error.message);
34975
+ }
34976
+ function buildEnvironmentContext() {
34977
+ const context = {
34978
+ os: platform2(),
34979
+ os_release: release(),
34980
+ platform: `${platform2()}-${release()}-${process.arch}`,
34981
+ node_version: process.version,
34982
+ runtime: "Node.js",
34983
+ hostname: hostname2(),
34984
+ agent_runtime: detectAgentRuntime()
34985
+ };
34986
+ for (const key of ["CLAUDE_CODE_REMOTE", "DEEPLINE_PLUGIN_MODE"]) {
34987
+ const normalized = process.env[key]?.trim();
34988
+ if (normalized) context[key.toLowerCase()] = normalized;
34989
+ }
34990
+ if (process.env.CLAUDE_PROJECT_DIR?.trim()) {
34991
+ context.claude_project_dir_present = "true";
34992
+ }
34993
+ if (process.env.DEEPLINE_PLUGIN_ROOT?.trim()) {
34994
+ context.deepline_plugin_root_present = "true";
34995
+ }
34996
+ if (process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim()) {
34997
+ context.deepline_plugin_skills_dir_present = "true";
34998
+ }
34999
+ if (process.env.HOME?.trim().startsWith("/sessions/")) {
35000
+ context.home_scope = "sessions";
35001
+ }
35002
+ return context;
35003
+ }
35004
+ function failureReportHeaders(apiKey) {
35005
+ return {
35006
+ Authorization: `Bearer ${apiKey}`,
35007
+ "Content-Type": "application/json",
35008
+ "User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
35009
+ "X-Deepline-Client-Family": "sdk",
35010
+ "X-Deepline-CLI-Family": "sdk",
35011
+ "X-Deepline-Agent-Runtime": detectAgentRuntime(),
35012
+ "X-Deepline-CLI-Version": SDK_VERSION,
35013
+ "X-Deepline-SDK-Version": SDK_VERSION
35014
+ };
35015
+ }
35016
+ async function postFailureReport(input2) {
35017
+ const controller = new AbortController();
35018
+ const timeout = setTimeout(() => controller.abort(), input2.timeoutMs);
35019
+ if (input2.background) timeout.unref();
35020
+ try {
35021
+ await fetch(new URL("/api/v2/cli/report-failure", input2.baseUrl), {
35022
+ method: "POST",
35023
+ headers: failureReportHeaders(input2.apiKey),
35024
+ body: JSON.stringify(input2.body),
35025
+ signal: controller.signal
35026
+ });
35027
+ return true;
35028
+ } catch {
35029
+ return false;
35030
+ } finally {
35031
+ clearTimeout(timeout);
35032
+ }
35033
+ }
35034
+ function boundedTelemetryString(value, maxChars) {
35035
+ return redactFailureText(value.trim(), maxChars);
35036
+ }
35037
+ async function maybeReportAutomaticSkillsSyncFailure(input2) {
35038
+ if (isFailureReportingDisabled()) return false;
35039
+ let apiKey = "";
35040
+ try {
35041
+ apiKey = resolveApiKeyForBaseUrl(input2.baseUrl);
35042
+ } catch {
35043
+ return false;
35044
+ }
35045
+ if (!apiKey) return false;
35046
+ const attempts = input2.attempts.slice(0, 2).map((attempt) => ({
35047
+ installer: attempt.installer,
35048
+ outcome: attempt.outcome,
35049
+ exit_code: typeof attempt.exitCode === "number" && Number.isFinite(attempt.exitCode) ? Math.trunc(attempt.exitCode) : null
35050
+ }));
35051
+ const agents = input2.agents.slice(0, 8).map((agent) => boundedTelemetryString(agent, 100)).filter(Boolean);
35052
+ const baseUrl = input2.baseUrl.replace(/\/$/, "");
35053
+ const failureKind = "background_warning";
35054
+ const failureCode2 = "SKILLS_AUTO_SYNC_FAILED";
35055
+ const failureStage = "skills_install";
35056
+ return postFailureReport({
35057
+ baseUrl,
35058
+ apiKey,
35059
+ timeoutMs: BACKGROUND_REPORT_FAILURE_TIMEOUT_MS,
35060
+ background: true,
35061
+ body: {
35062
+ command: "deepline skills",
35063
+ subcommand: "skills",
35064
+ failure_kind: failureKind,
35065
+ failure_code: failureCode2,
35066
+ failure_stage: failureStage,
35067
+ error_body: "Automatic Deepline skills installation failed.",
35068
+ cli_version: SDK_VERSION,
35069
+ context: {
35070
+ environment: buildEnvironmentContext(),
35071
+ skills_sync: {
35072
+ skills_package: boundedTelemetryString(input2.skillsPackage, 100),
35073
+ remote_skills_version: boundedTelemetryString(
35074
+ input2.remoteSkillsVersion,
35075
+ 200
35076
+ ),
35077
+ agents,
35078
+ target_skill_count: Math.max(
35079
+ 0,
35080
+ Math.trunc(
35081
+ Number.isFinite(input2.targetSkillCount) ? input2.targetSkillCount : 0
35082
+ )
35083
+ ),
35084
+ marker_written: input2.markerWritten,
35085
+ attempts
35086
+ }
35087
+ }
35088
+ }
35089
+ });
35090
+ }
35091
+ function subcommandFromArgv(argv) {
35092
+ return argv.find((arg) => arg && !arg.startsWith("-")) ?? null;
35093
+ }
35094
+ function commandTokens(argv) {
35095
+ return argv.map((arg) => String(arg ?? "").trim()).filter((arg) => arg && !arg.startsWith("-"));
35096
+ }
35097
+ function isServerLoggedPlayRunStartFailure(input2) {
35098
+ const [subcommand, command] = commandTokens(input2.argv);
35099
+ return subcommand === "plays" && command === "run" && input2.error instanceof DeeplineError && typeof input2.error.statusCode === "number";
35100
+ }
35101
+ function shouldReport(input2) {
35102
+ if (input2.error !== void 0) return true;
35103
+ return input2.exitCode !== null && REPORTABLE_EXIT_CODES.has(input2.exitCode);
35104
+ }
35105
+ function failureCode(input2) {
35106
+ if (input2.error !== void 0) {
35107
+ if (isNetworkFailure(input2.error))
35108
+ return classifyNetworkFailure(input2.error);
35109
+ if (input2.error instanceof DeeplineError && input2.error.code) {
35110
+ return input2.error.code;
35111
+ }
35112
+ if (input2.error instanceof Error && input2.error.name)
35113
+ return input2.error.name;
35114
+ return "CLI_FAILURE";
35115
+ }
35116
+ return input2.exitCode === 4 ? "network_error" : "command_exit";
35117
+ }
35118
+ function resolvedExitCode(input2) {
35119
+ if (typeof input2.exitCode === "number" && Number.isFinite(input2.exitCode)) {
35120
+ return Math.trunc(input2.exitCode);
35121
+ }
35122
+ if (input2.error === void 0) return null;
35123
+ return isNetworkFailure(input2.error) ? 4 : 5;
35124
+ }
35125
+ function resolveSdkCliFailureExitCode(error) {
35126
+ return isNetworkFailure(error) ? 4 : 1;
35127
+ }
35128
+ function resolvedFailureKind(input2) {
35129
+ return input2.error === void 0 ? "command_exit" : "uncaught_exception";
35130
+ }
35131
+ function buildFailureReport(input2) {
35132
+ const durationMs = Math.max(0, Date.now() - input2.startedAtMs);
35133
+ const failureKind = resolvedFailureKind({
35134
+ exitCode: input2.exitCode,
35135
+ error: input2.error
35136
+ });
35137
+ const code = failureCode({ exitCode: input2.exitCode, error: input2.error });
35138
+ const errorBody = input2.error === void 0 ? `SDK CLI command exited ${input2.exitCode ?? "unknown"}` : errorMessage3(input2.error);
35139
+ return {
35140
+ command: sanitizeCommand(input2.argv),
35141
+ subcommand: subcommandFromArgv(input2.argv),
35142
+ error_status: input2.exitCode,
35143
+ error_body: redactFailureText(errorBody),
35144
+ exit_code: input2.exitCode,
35145
+ duration_ms: durationMs,
35146
+ error_class: input2.error instanceof Error ? input2.error.name : null,
35147
+ stack_trace: errorStack(input2.error),
35148
+ failure_kind: failureKind,
35149
+ failure_code: code,
35150
+ failure_stage: input2.error === void 0 ? "command_exit" : "cli_main",
35151
+ cli_version: SDK_VERSION,
35152
+ context: {
35153
+ base_url: redactFailureText(input2.baseUrl, 400),
35154
+ command_summary: sanitizeCommand(input2.argv),
35155
+ environment: buildEnvironmentContext(),
35156
+ failure_kind: failureKind,
35157
+ failure_code: code,
35158
+ failure_stage: input2.error === void 0 ? "command_exit" : "cli_main",
35159
+ duration_ms: durationMs,
35160
+ ...input2.exitCode !== null ? { exit_code: input2.exitCode } : {}
35161
+ }
35162
+ };
35163
+ }
35164
+ async function maybeReportSdkCliFailure(input2) {
35165
+ if (isFailureReportingDisabled()) return false;
35166
+ if (isServerLoggedPlayRunStartFailure(input2)) return false;
35167
+ const exitCode = resolvedExitCode(input2);
35168
+ if (!shouldReport({ exitCode, error: input2.error })) return false;
35169
+ const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
35170
+ const apiKey = resolveApiKeyForBaseUrl(baseUrl);
35171
+ if (!apiKey) return false;
35172
+ return postFailureReport({
35173
+ baseUrl,
35174
+ apiKey,
35175
+ timeoutMs: REPORT_FAILURE_TIMEOUT_MS,
35176
+ body: buildFailureReport({
35177
+ argv: input2.argv,
35178
+ startedAtMs: input2.startedAtMs,
35179
+ error: input2.error,
35180
+ exitCode,
35181
+ baseUrl
35182
+ })
35183
+ });
35184
+ }
35185
+
34874
35186
  // src/cli/skills-sync.ts
34875
35187
  var CHECK_TIMEOUT_MS2 = 3e3;
34876
35188
  function shouldSkipSkillsSync() {
@@ -34904,7 +35216,9 @@ function writeMarkedSkillsSyncVersion(path, version) {
34904
35216
  mkdirSync9(dirname14(path), { recursive: true });
34905
35217
  writeFileSync13(path, `${version}
34906
35218
  `, "utf-8");
35219
+ return true;
34907
35220
  } catch {
35221
+ return false;
34908
35222
  }
34909
35223
  }
34910
35224
  function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames) {
@@ -34933,7 +35247,7 @@ function hasFailedAutomaticSkillsSync(baseUrl, agents) {
34933
35247
  return existsSync12(failedSkillsSyncPath(baseUrl, agents));
34934
35248
  }
34935
35249
  function markFailedSkillsSync(baseUrl, remoteVersion, agents) {
34936
- writeMarkedSkillsSyncVersion(
35250
+ return writeMarkedSkillsSyncVersion(
34937
35251
  failedSkillsSyncPath(baseUrl, agents),
34938
35252
  remoteVersion
34939
35253
  );
@@ -35070,19 +35384,29 @@ function runOneSkillsInstall(install) {
35070
35384
  resolve21({
35071
35385
  ok: false,
35072
35386
  detail: `failed to start ${install.command}: ${error.message}`,
35073
- manualCommand: install.manualCommand
35387
+ manualCommand: install.manualCommand,
35388
+ attempt: {
35389
+ installer: install.command,
35390
+ outcome: "spawn_error",
35391
+ exitCode: null
35392
+ }
35074
35393
  });
35075
35394
  });
35076
35395
  child.on("close", (code) => {
35077
35396
  if (code === 0) {
35078
- resolve21({ ok: true, detail: "", manualCommand: install.manualCommand });
35397
+ resolve21({ ok: true });
35079
35398
  return;
35080
35399
  }
35081
35400
  const detail = stderr.trim();
35082
35401
  resolve21({
35083
35402
  ok: false,
35084
35403
  detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
35085
- manualCommand: install.manualCommand
35404
+ manualCommand: install.manualCommand,
35405
+ attempt: {
35406
+ installer: install.command,
35407
+ outcome: code === null ? "terminated" : "exit",
35408
+ exitCode: code
35409
+ }
35086
35410
  });
35087
35411
  });
35088
35412
  });
@@ -35091,7 +35415,7 @@ async function runSkillsInstall(installs, agents) {
35091
35415
  const failures = [];
35092
35416
  for (const install of installs) {
35093
35417
  const result = await runOneSkillsInstall(install);
35094
- if (result.ok) return true;
35418
+ if (result.ok) return { installed: true };
35095
35419
  failures.push(result);
35096
35420
  }
35097
35421
  const details = failures.map((failure) => failure.detail).filter(Boolean).join("\n");
@@ -35107,7 +35431,10 @@ ${details}
35107
35431
  ` : "") + `To temporarily suppress automatic skills sync: ${temporarySkillsSyncSkipCommand()}
35108
35432
  `
35109
35433
  );
35110
- return false;
35434
+ return {
35435
+ installed: false,
35436
+ attempts: failures.map(({ attempt }) => attempt)
35437
+ };
35111
35438
  }
35112
35439
  function runLegacySkillsCleanup(agents) {
35113
35440
  const candidates = hasCommand("bunx") ? [
@@ -35204,9 +35531,22 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
35204
35531
  return;
35205
35532
  }
35206
35533
  writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
35207
- const installed = await runSkillsInstall(installs, agents);
35208
- if (!installed) {
35209
- markFailedSkillsSync(baseUrl, update.remoteVersion, agents);
35534
+ const installResult = await runSkillsInstall(installs, agents);
35535
+ if (!installResult.installed) {
35536
+ const markerWritten = markFailedSkillsSync(
35537
+ baseUrl,
35538
+ update.remoteVersion,
35539
+ agents
35540
+ );
35541
+ void maybeReportAutomaticSkillsSyncFailure({
35542
+ baseUrl,
35543
+ remoteSkillsVersion: update.remoteVersion,
35544
+ agents,
35545
+ skillsPackage: SKILLS_NPX_PACKAGE,
35546
+ targetSkillCount: skillNames.length,
35547
+ markerWritten,
35548
+ attempts: installResult.attempts
35549
+ });
35210
35550
  return;
35211
35551
  }
35212
35552
  runLegacySkillsCleanup(agents);
@@ -41902,253 +42242,6 @@ What changed in ${response.update_summary.version}: ${response.update_summary.su
41902
42242
  return true;
41903
42243
  }
41904
42244
 
41905
- // src/cli/failure-reporting.ts
41906
- import { hostname as hostname2, platform as platform2, release } from "os";
41907
- var FAILURE_REPORT_DISABLE_ENV = "DEEPLINE_DISABLE_FAILURE_REPORTING";
41908
- var REPORT_FAILURE_TIMEOUT_MS = 1e4;
41909
- var MAX_FAILURE_TEXT_CHARS = 4e3;
41910
- var MAX_COMMAND_TOKENS = 3;
41911
- var REPORTABLE_EXIT_CODES = /* @__PURE__ */ new Set([4, 5]);
41912
- var EMAIL_RE = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
41913
- var UNIX_PATH_RE = /(?:\/Users\/|\/home\/|\/var\/folders\/|\/tmp\/|\/sessions\/)[^"'\n\r`]+/g;
41914
- var WINDOWS_PATH_RE = /[A-Za-z]:(?:\\{1,2})(?:Users|Temp|tmp)(?:\\{1,2})[^"'\n\r`]+/g;
41915
- var ASSIGNMENT_SECRET_RE = /\b(access[_-]?token|api[_-]?key|apikey|auth(?:orization)?|bearer|password|secret|session)\b(\s*[:=]\s*)(?!Bearer\s+\[redacted-secret\])([^\s,;]+)/gi;
41916
- var BEARER_SECRET_RE = /\b(bearer)\s+([A-Za-z0-9._-]+)/gi;
41917
- var GENERIC_TOKEN_RE = /\b(?:dlp|sk|ghp|xox[baprs])[-_A-Za-z0-9]{8,}\b/g;
41918
- var SECRET_OPTION_RE = /^--?(?:access[-_]?token|api[-_]?key|apikey|auth(?:orization)?|bearer|password|secret|session|token)$/i;
41919
- function truthyEnv2(name) {
41920
- return ["1", "true", "yes", "on"].includes(
41921
- String(process.env[name] ?? "").trim().toLowerCase()
41922
- );
41923
- }
41924
- function isFailureReportingDisabled() {
41925
- return truthyEnv2(FAILURE_REPORT_DISABLE_ENV);
41926
- }
41927
- function redactFailureText(value, maxChars = MAX_FAILURE_TEXT_CHARS) {
41928
- const home = process.env.HOME?.trim();
41929
- let text = String(value ?? "");
41930
- if (!text) return "";
41931
- if (home && home !== "/") {
41932
- text = text.split(home).join("~");
41933
- }
41934
- return text.replace(EMAIL_RE, "[redacted-email]").replace(UNIX_PATH_RE, "[redacted-path]").replace(WINDOWS_PATH_RE, "[redacted-path]").replace(BEARER_SECRET_RE, "$1 [redacted-secret]").replace(ASSIGNMENT_SECRET_RE, "$1$2[redacted-secret]").replace(GENERIC_TOKEN_RE, "[redacted-secret]").slice(0, maxChars);
41935
- }
41936
- function sanitizeCommand(argv, prefix = "deepline") {
41937
- const tokens = [];
41938
- for (let index = 0; index < argv.length; index += 1) {
41939
- const arg = argv[index];
41940
- const value = String(arg ?? "").trim();
41941
- if (!value) continue;
41942
- if (value.startsWith("-")) {
41943
- if (!value.includes("=") && SECRET_OPTION_RE.test(value)) {
41944
- index += 1;
41945
- }
41946
- continue;
41947
- }
41948
- tokens.push(redactFailureText(value, 200));
41949
- if (tokens.length >= MAX_COMMAND_TOKENS) break;
41950
- }
41951
- return tokens.length > 0 ? [prefix, ...tokens].join(" ") : prefix;
41952
- }
41953
- function errorMessage3(error) {
41954
- if (error instanceof Error) return `${error.name}: ${error.message}`;
41955
- return String(error ?? "");
41956
- }
41957
- function errorStack(error) {
41958
- if (error instanceof Error && error.stack) {
41959
- return redactFailureText(error.stack);
41960
- }
41961
- return null;
41962
- }
41963
- function classifyNetworkFailure(error) {
41964
- const seen = /* @__PURE__ */ new Set();
41965
- let current = error;
41966
- while (current && !seen.has(current)) {
41967
- seen.add(current);
41968
- const record2 = typeof current === "object" && current !== null ? current : {};
41969
- const code = String(record2.code ?? "").toLowerCase();
41970
- const name = current instanceof Error ? current.name.toLowerCase() : "";
41971
- const text = String(
41972
- current instanceof Error ? current.message : current
41973
- ).toLowerCase();
41974
- const combined = `${code} ${name} ${text}`;
41975
- if (combined.includes("aborterror") || combined.includes("timeout") || combined.includes("timed out") || combined.includes("etimedout")) {
41976
- return "network_timeout";
41977
- }
41978
- if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
41979
- return "network_dns_resolution_failed";
41980
- }
41981
- if (combined.includes("econnrefused") || combined.includes("connection refused")) {
41982
- return "network_connection_refused";
41983
- }
41984
- if (combined.includes("econnreset") || combined.includes("connection reset")) {
41985
- return "network_connection_reset";
41986
- }
41987
- if (combined.includes("incompleteread") || combined.includes("incomplete read")) {
41988
- return "network_incomplete_read";
41989
- }
41990
- if (combined.includes("remotedisconnected") || combined.includes("remote end closed connection") || combined.includes("other side closed") || combined.includes("socket hang up")) {
41991
- return "network_remote_disconnected";
41992
- }
41993
- if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
41994
- return "network_ssl_error";
41995
- }
41996
- current = record2.cause ?? record2.context;
41997
- }
41998
- return "network_error";
41999
- }
42000
- function isNetworkFailure(error) {
42001
- if (!(error instanceof Error)) return false;
42002
- if (error instanceof DeeplineError && error.statusCode) return false;
42003
- const code = classifyNetworkFailure(error);
42004
- return code !== "network_error" || /unable to connect|unable to stream/i.test(error.message);
42005
- }
42006
- function buildEnvironmentContext() {
42007
- const context = {
42008
- os: platform2(),
42009
- os_release: release(),
42010
- platform: `${platform2()}-${release()}-${process.arch}`,
42011
- node_version: process.version,
42012
- runtime: "Node.js",
42013
- hostname: hostname2(),
42014
- agent_runtime: detectAgentRuntime()
42015
- };
42016
- for (const key of ["CLAUDE_CODE_REMOTE", "DEEPLINE_PLUGIN_MODE"]) {
42017
- const normalized = process.env[key]?.trim();
42018
- if (normalized) context[key.toLowerCase()] = normalized;
42019
- }
42020
- if (process.env.CLAUDE_PROJECT_DIR?.trim()) {
42021
- context.claude_project_dir_present = "true";
42022
- }
42023
- if (process.env.DEEPLINE_PLUGIN_ROOT?.trim()) {
42024
- context.deepline_plugin_root_present = "true";
42025
- }
42026
- if (process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim()) {
42027
- context.deepline_plugin_skills_dir_present = "true";
42028
- }
42029
- if (process.env.HOME?.trim().startsWith("/sessions/")) {
42030
- context.home_scope = "sessions";
42031
- }
42032
- return context;
42033
- }
42034
- function subcommandFromArgv(argv) {
42035
- return argv.find((arg) => arg && !arg.startsWith("-")) ?? null;
42036
- }
42037
- function commandTokens(argv) {
42038
- return argv.map((arg) => String(arg ?? "").trim()).filter((arg) => arg && !arg.startsWith("-"));
42039
- }
42040
- function isServerLoggedPlayRunStartFailure(input2) {
42041
- const [subcommand, command] = commandTokens(input2.argv);
42042
- return subcommand === "plays" && command === "run" && input2.error instanceof DeeplineError && typeof input2.error.statusCode === "number";
42043
- }
42044
- function shouldReport(input2) {
42045
- if (input2.error !== void 0) return true;
42046
- return input2.exitCode !== null && REPORTABLE_EXIT_CODES.has(input2.exitCode);
42047
- }
42048
- function failureCode(input2) {
42049
- if (input2.error !== void 0) {
42050
- if (isNetworkFailure(input2.error))
42051
- return classifyNetworkFailure(input2.error);
42052
- if (input2.error instanceof DeeplineError && input2.error.code) {
42053
- return input2.error.code;
42054
- }
42055
- if (input2.error instanceof Error && input2.error.name)
42056
- return input2.error.name;
42057
- return "CLI_FAILURE";
42058
- }
42059
- return input2.exitCode === 4 ? "network_error" : "command_exit";
42060
- }
42061
- function resolvedExitCode(input2) {
42062
- if (typeof input2.exitCode === "number" && Number.isFinite(input2.exitCode)) {
42063
- return Math.trunc(input2.exitCode);
42064
- }
42065
- if (input2.error === void 0) return null;
42066
- return isNetworkFailure(input2.error) ? 4 : 5;
42067
- }
42068
- function resolveSdkCliFailureExitCode(error) {
42069
- return isNetworkFailure(error) ? 4 : 1;
42070
- }
42071
- function resolvedFailureKind(input2) {
42072
- return input2.error === void 0 ? "command_exit" : "uncaught_exception";
42073
- }
42074
- function buildFailureReport(input2) {
42075
- const durationMs = Math.max(0, Date.now() - input2.startedAtMs);
42076
- const failureKind = resolvedFailureKind({
42077
- exitCode: input2.exitCode,
42078
- error: input2.error
42079
- });
42080
- const code = failureCode({ exitCode: input2.exitCode, error: input2.error });
42081
- const errorBody = input2.error === void 0 ? `SDK CLI command exited ${input2.exitCode ?? "unknown"}` : errorMessage3(input2.error);
42082
- return {
42083
- command: sanitizeCommand(input2.argv),
42084
- subcommand: subcommandFromArgv(input2.argv),
42085
- error_status: input2.exitCode,
42086
- error_body: redactFailureText(errorBody),
42087
- exit_code: input2.exitCode,
42088
- duration_ms: durationMs,
42089
- error_class: input2.error instanceof Error ? input2.error.name : null,
42090
- stack_trace: errorStack(input2.error),
42091
- failure_kind: failureKind,
42092
- failure_code: code,
42093
- failure_stage: input2.error === void 0 ? "command_exit" : "cli_main",
42094
- cli_version: SDK_VERSION,
42095
- context: {
42096
- base_url: redactFailureText(input2.baseUrl, 400),
42097
- command_summary: sanitizeCommand(input2.argv),
42098
- environment: buildEnvironmentContext(),
42099
- failure_kind: failureKind,
42100
- failure_code: code,
42101
- failure_stage: input2.error === void 0 ? "command_exit" : "cli_main",
42102
- duration_ms: durationMs,
42103
- ...input2.exitCode !== null ? { exit_code: input2.exitCode } : {}
42104
- }
42105
- };
42106
- }
42107
- async function maybeReportSdkCliFailure(input2) {
42108
- if (isFailureReportingDisabled()) return false;
42109
- if (isServerLoggedPlayRunStartFailure(input2)) return false;
42110
- const exitCode = resolvedExitCode(input2);
42111
- if (!shouldReport({ exitCode, error: input2.error })) return false;
42112
- const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
42113
- const apiKey = resolveApiKeyForBaseUrl(baseUrl);
42114
- if (!apiKey) return false;
42115
- const controller = new AbortController();
42116
- const timeout = setTimeout(
42117
- () => controller.abort(),
42118
- REPORT_FAILURE_TIMEOUT_MS
42119
- );
42120
- try {
42121
- await fetch(new URL("/api/v2/cli/report-failure", baseUrl), {
42122
- method: "POST",
42123
- headers: {
42124
- Authorization: `Bearer ${apiKey}`,
42125
- "Content-Type": "application/json",
42126
- "User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
42127
- "X-Deepline-Client-Family": "sdk",
42128
- "X-Deepline-CLI-Family": "sdk",
42129
- "X-Deepline-Agent-Runtime": detectAgentRuntime(),
42130
- "X-Deepline-CLI-Version": SDK_VERSION,
42131
- "X-Deepline-SDK-Version": SDK_VERSION
42132
- },
42133
- body: JSON.stringify(
42134
- buildFailureReport({
42135
- argv: input2.argv,
42136
- startedAtMs: input2.startedAtMs,
42137
- error: input2.error,
42138
- exitCode,
42139
- baseUrl
42140
- })
42141
- ),
42142
- signal: controller.signal
42143
- });
42144
- return true;
42145
- } catch {
42146
- return false;
42147
- } finally {
42148
- clearTimeout(timeout);
42149
- }
42150
- }
42151
-
42152
42245
  // src/cli/index.ts
42153
42246
  var PREFLIGHT_TIMEOUT_MS = 3e3;
42154
42247
  var ProjectOrgPinRequiredError = class extends Error {