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.
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +9 -1
- package/dist/cli/index.js +372 -279
- package/dist/cli/index.mjs +352 -259
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/plays/bundle-play-file.mjs +1 -1
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -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.
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
35208
|
-
if (!installed) {
|
|
35209
|
-
markFailedSkillsSync(
|
|
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 {
|