deepline 0.1.260 → 0.1.261
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/play-runtime/gateway-auth-session.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +2 -8
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +147 -40
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +57 -71
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +8 -0
- package/dist/cli/index.js +468 -149
- package/dist/cli/index.mjs +479 -160
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -716,7 +716,7 @@ var SDK_RELEASE = {
|
|
|
716
716
|
// Deepline-native radars. Older clients must update before discovering,
|
|
717
717
|
// checking, or deploying an unlaunched monitor integration.
|
|
718
718
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
719
|
-
version: "0.1.
|
|
719
|
+
version: "0.1.261",
|
|
720
720
|
apiContract: "2026-07-native-monitor-launch-hard-cutover",
|
|
721
721
|
supportPolicy: {
|
|
722
722
|
minimumSupported: "0.1.53",
|
|
@@ -29106,10 +29106,13 @@ function buildSkillsPlan(input2) {
|
|
|
29106
29106
|
skillNames: input2.skillNames,
|
|
29107
29107
|
version: input2.version,
|
|
29108
29108
|
remove: {
|
|
29109
|
-
command: "
|
|
29109
|
+
command: "npm",
|
|
29110
29110
|
args: [
|
|
29111
|
+
"exec",
|
|
29111
29112
|
"--yes",
|
|
29112
|
-
"skills@latest",
|
|
29113
|
+
"--package=skills@latest",
|
|
29114
|
+
"--",
|
|
29115
|
+
"skills",
|
|
29113
29116
|
"remove",
|
|
29114
29117
|
...scopeArgs,
|
|
29115
29118
|
"--agent",
|
|
@@ -29119,10 +29122,13 @@ function buildSkillsPlan(input2) {
|
|
|
29119
29122
|
]
|
|
29120
29123
|
},
|
|
29121
29124
|
install: {
|
|
29122
|
-
command: "
|
|
29125
|
+
command: "npm",
|
|
29123
29126
|
args: [
|
|
29127
|
+
"exec",
|
|
29124
29128
|
"--yes",
|
|
29125
|
-
"skills@latest",
|
|
29129
|
+
"--package=skills@latest",
|
|
29130
|
+
"--",
|
|
29131
|
+
"skills",
|
|
29126
29132
|
"add",
|
|
29127
29133
|
skillsIndexUrl(input2.baseUrl),
|
|
29128
29134
|
"--agent",
|
|
@@ -29136,6 +29142,29 @@ function buildSkillsPlan(input2) {
|
|
|
29136
29142
|
statePath: skillsStatePathForScope(input2.baseUrl, input2.scope, input2.root)
|
|
29137
29143
|
};
|
|
29138
29144
|
}
|
|
29145
|
+
function sortedStrings(value) {
|
|
29146
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
|
|
29147
|
+
return null;
|
|
29148
|
+
}
|
|
29149
|
+
return [...value].sort((a, b) => a.localeCompare(b));
|
|
29150
|
+
}
|
|
29151
|
+
function isSkillsPlanCurrent(plan, state) {
|
|
29152
|
+
if (!state || state.scope !== plan.scope || state.skillsVersion !== plan.version) {
|
|
29153
|
+
return false;
|
|
29154
|
+
}
|
|
29155
|
+
const installedAgents = sortedStrings(state.agents);
|
|
29156
|
+
const installedSkillNames = sortedStrings(state.skillNames);
|
|
29157
|
+
if (!installedAgents || !installedSkillNames) return false;
|
|
29158
|
+
return installedAgents.join("\0") === [...plan.agents].sort((a, b) => a.localeCompare(b)).join("\0") && installedSkillNames.join("\0") === [...plan.skillNames].sort((a, b) => a.localeCompare(b)).join("\0");
|
|
29159
|
+
}
|
|
29160
|
+
function readSkillsInstallState(path) {
|
|
29161
|
+
try {
|
|
29162
|
+
const parsed = JSON.parse((0, import_node_fs16.readFileSync)(path, "utf8"));
|
|
29163
|
+
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
29164
|
+
} catch {
|
|
29165
|
+
return null;
|
|
29166
|
+
}
|
|
29167
|
+
}
|
|
29139
29168
|
function runProcess(command, args, cwd) {
|
|
29140
29169
|
return new Promise((resolve15, reject) => {
|
|
29141
29170
|
const child = (0, import_node_child_process3.spawn)(command, args, {
|
|
@@ -29159,7 +29188,7 @@ function runProcess(command, args, cwd) {
|
|
|
29159
29188
|
});
|
|
29160
29189
|
});
|
|
29161
29190
|
}
|
|
29162
|
-
async function runSkillsCommand(options) {
|
|
29191
|
+
async function runSkillsCommand(options, dependencies = {}) {
|
|
29163
29192
|
let scope;
|
|
29164
29193
|
let root;
|
|
29165
29194
|
try {
|
|
@@ -29181,7 +29210,7 @@ async function runSkillsCommand(options) {
|
|
|
29181
29210
|
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
29182
29211
|
let catalog;
|
|
29183
29212
|
try {
|
|
29184
|
-
catalog = options.dryRun ? { skillNames: [...DEFAULT_SDK_SKILL_NAMES], version: "latest" } : await fetchSkillCatalog(baseUrl);
|
|
29213
|
+
catalog = options.dryRun ? { skillNames: [...DEFAULT_SDK_SKILL_NAMES], version: "latest" } : await (dependencies.fetchCatalog ?? fetchSkillCatalog)(baseUrl);
|
|
29185
29214
|
} catch (error) {
|
|
29186
29215
|
printCommandEnvelope(
|
|
29187
29216
|
{
|
|
@@ -29205,6 +29234,37 @@ async function runSkillsCommand(options) {
|
|
|
29205
29234
|
);
|
|
29206
29235
|
return 0;
|
|
29207
29236
|
}
|
|
29237
|
+
if (isSkillsPlanCurrent(plan, readSkillsInstallState(plan.statePath))) {
|
|
29238
|
+
printCommandEnvelope(
|
|
29239
|
+
{
|
|
29240
|
+
ok: true,
|
|
29241
|
+
status: "current",
|
|
29242
|
+
complete: true,
|
|
29243
|
+
changed: false,
|
|
29244
|
+
skipped: true,
|
|
29245
|
+
skipReason: "skills_version_current",
|
|
29246
|
+
scope,
|
|
29247
|
+
agents,
|
|
29248
|
+
skillsVersion: plan.version,
|
|
29249
|
+
skillCount: plan.skillNames.length,
|
|
29250
|
+
statePath: plan.statePath,
|
|
29251
|
+
render: {
|
|
29252
|
+
sections: [
|
|
29253
|
+
{
|
|
29254
|
+
title: "skills",
|
|
29255
|
+
lines: [
|
|
29256
|
+
`Scope: ${scope}`,
|
|
29257
|
+
`Agents: ${agents.join(", ")}`,
|
|
29258
|
+
`Current: ${plan.skillNames.length}`
|
|
29259
|
+
]
|
|
29260
|
+
}
|
|
29261
|
+
]
|
|
29262
|
+
}
|
|
29263
|
+
},
|
|
29264
|
+
{ json: options.json }
|
|
29265
|
+
);
|
|
29266
|
+
return 0;
|
|
29267
|
+
}
|
|
29208
29268
|
if (scope === "local" && root) {
|
|
29209
29269
|
const managedNames = [
|
|
29210
29270
|
.../* @__PURE__ */ new Set([...plan.skillNames, ...LEGACY_SKILL_NAMES_TO_REMOVE])
|
|
@@ -29222,7 +29282,8 @@ async function runSkillsCommand(options) {
|
|
|
29222
29282
|
`
|
|
29223
29283
|
);
|
|
29224
29284
|
try {
|
|
29225
|
-
const
|
|
29285
|
+
const execute = dependencies.runProcess ?? runProcess;
|
|
29286
|
+
const removeCode = await execute(
|
|
29226
29287
|
plan.remove.command,
|
|
29227
29288
|
plan.remove.args,
|
|
29228
29289
|
root ?? void 0
|
|
@@ -29230,7 +29291,7 @@ async function runSkillsCommand(options) {
|
|
|
29230
29291
|
if (removeCode !== 0) {
|
|
29231
29292
|
throw new Error("Could not remove the existing Deepline skills.");
|
|
29232
29293
|
}
|
|
29233
|
-
const installCode = await
|
|
29294
|
+
const installCode = await execute(
|
|
29234
29295
|
plan.install.command,
|
|
29235
29296
|
plan.install.args,
|
|
29236
29297
|
root ?? void 0
|
|
@@ -29935,6 +29996,85 @@ var import_node_child_process5 = require("child_process");
|
|
|
29935
29996
|
var import_node_fs18 = require("fs");
|
|
29936
29997
|
var import_node_os15 = require("os");
|
|
29937
29998
|
var import_node_path20 = require("path");
|
|
29999
|
+
var SETUP_PHASE_NAMES = [
|
|
30000
|
+
"cli",
|
|
30001
|
+
"cleanup",
|
|
30002
|
+
"skills",
|
|
30003
|
+
"auth",
|
|
30004
|
+
"verify"
|
|
30005
|
+
];
|
|
30006
|
+
function initialSetupPhases() {
|
|
30007
|
+
return {
|
|
30008
|
+
cli: { status: "pending" },
|
|
30009
|
+
cleanup: { status: "pending" },
|
|
30010
|
+
skills: { status: "pending" },
|
|
30011
|
+
auth: { status: "pending" },
|
|
30012
|
+
verify: { status: "pending" }
|
|
30013
|
+
};
|
|
30014
|
+
}
|
|
30015
|
+
function isSetupPhaseStatus(value) {
|
|
30016
|
+
return value === "pending" || value === "in_progress" || value === "complete" || value === "waiting" || value === "failed";
|
|
30017
|
+
}
|
|
30018
|
+
function parseSetupPhases(value) {
|
|
30019
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
30020
|
+
const source = value;
|
|
30021
|
+
const phases = initialSetupPhases();
|
|
30022
|
+
for (const name of SETUP_PHASE_NAMES) {
|
|
30023
|
+
const phase = source[name];
|
|
30024
|
+
if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
|
|
30025
|
+
return null;
|
|
30026
|
+
}
|
|
30027
|
+
const record = phase;
|
|
30028
|
+
if (!isSetupPhaseStatus(record.status)) return null;
|
|
30029
|
+
phases[name] = {
|
|
30030
|
+
status: record.status,
|
|
30031
|
+
...typeof record.outcome === "string" ? { outcome: record.outcome } : {},
|
|
30032
|
+
...typeof record.code === "string" ? { code: record.code } : {}
|
|
30033
|
+
};
|
|
30034
|
+
}
|
|
30035
|
+
return phases;
|
|
30036
|
+
}
|
|
30037
|
+
function phasesFromLegacyStatus(status) {
|
|
30038
|
+
const phases = initialSetupPhases();
|
|
30039
|
+
if (status === "skills_installed" || status === "authorization_pending" || status === "complete") {
|
|
30040
|
+
phases.cli = { status: "complete" };
|
|
30041
|
+
phases.cleanup = { status: "complete" };
|
|
30042
|
+
phases.skills = { status: "complete" };
|
|
30043
|
+
}
|
|
30044
|
+
if (status === "authorization_pending") {
|
|
30045
|
+
phases.auth = { status: "waiting", outcome: "authorization_pending" };
|
|
30046
|
+
} else if (status === "complete") {
|
|
30047
|
+
phases.auth = { status: "complete" };
|
|
30048
|
+
phases.verify = { status: "complete" };
|
|
30049
|
+
}
|
|
30050
|
+
return phases;
|
|
30051
|
+
}
|
|
30052
|
+
function readSetupState(input2) {
|
|
30053
|
+
try {
|
|
30054
|
+
const parsed = JSON.parse(
|
|
30055
|
+
(0, import_node_fs18.readFileSync)(
|
|
30056
|
+
setupStatePath(input2.baseUrl, input2.scope, input2.root),
|
|
30057
|
+
"utf8"
|
|
30058
|
+
)
|
|
30059
|
+
);
|
|
30060
|
+
if (parsed.host !== input2.baseUrl || parsed.scope !== input2.scope || parsed.root !== input2.root || typeof parsed.status !== "string") {
|
|
30061
|
+
return null;
|
|
30062
|
+
}
|
|
30063
|
+
return {
|
|
30064
|
+
status: parsed.status,
|
|
30065
|
+
phases: parseSetupPhases(parsed.phases) ?? phasesFromLegacyStatus(parsed.status)
|
|
30066
|
+
};
|
|
30067
|
+
} catch {
|
|
30068
|
+
return null;
|
|
30069
|
+
}
|
|
30070
|
+
}
|
|
30071
|
+
function selectSetupProgress(previousState) {
|
|
30072
|
+
const resumed = Boolean(previousState && previousState.status !== "complete");
|
|
30073
|
+
return {
|
|
30074
|
+
resumed,
|
|
30075
|
+
phases: resumed ? previousState.phases : initialSetupPhases()
|
|
30076
|
+
};
|
|
30077
|
+
}
|
|
29938
30078
|
function normalizeScope2(value) {
|
|
29939
30079
|
if (!value || value === "global") return "global";
|
|
29940
30080
|
if (value === "local") return "local";
|
|
@@ -30105,13 +30245,14 @@ function writeSetupState(input2) {
|
|
|
30105
30245
|
path,
|
|
30106
30246
|
`${JSON.stringify(
|
|
30107
30247
|
{
|
|
30108
|
-
schemaVersion:
|
|
30248
|
+
schemaVersion: 2,
|
|
30109
30249
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30110
30250
|
cliVersion: SDK_VERSION,
|
|
30111
30251
|
host: input2.baseUrl,
|
|
30112
30252
|
scope: input2.scope,
|
|
30113
30253
|
root: input2.root,
|
|
30114
|
-
status: input2.status
|
|
30254
|
+
status: input2.status,
|
|
30255
|
+
phases: input2.phases
|
|
30115
30256
|
},
|
|
30116
30257
|
null,
|
|
30117
30258
|
2
|
|
@@ -30121,6 +30262,24 @@ function writeSetupState(input2) {
|
|
|
30121
30262
|
);
|
|
30122
30263
|
return path;
|
|
30123
30264
|
}
|
|
30265
|
+
function persistSetupProgress(input2) {
|
|
30266
|
+
return writeSetupState({
|
|
30267
|
+
...input2,
|
|
30268
|
+
status: input2.status ?? "in_progress"
|
|
30269
|
+
});
|
|
30270
|
+
}
|
|
30271
|
+
function completeSetupPhase(phases, phase, outcome) {
|
|
30272
|
+
phases[phase] = {
|
|
30273
|
+
status: "complete",
|
|
30274
|
+
...outcome ? { outcome } : {}
|
|
30275
|
+
};
|
|
30276
|
+
}
|
|
30277
|
+
function beginSetupPhase(phases, phase) {
|
|
30278
|
+
phases[phase] = { status: "in_progress" };
|
|
30279
|
+
}
|
|
30280
|
+
function failSetupPhase(phases, phase, code) {
|
|
30281
|
+
phases[phase] = { status: "failed", code };
|
|
30282
|
+
}
|
|
30124
30283
|
function rollbackCommand(scope, root) {
|
|
30125
30284
|
const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify((0, import_node_path20.join)(root, ".deepline", "runtime"))}` : "";
|
|
30126
30285
|
return `npm install -g${prefix} --no-audit --no-fund --include=optional --allow-scripts=esbuild deepline@${SDK_VERSION}`;
|
|
@@ -30132,6 +30291,42 @@ function setupResumeCommand(baseUrl, scope) {
|
|
|
30132
30291
|
const hostPrefix = baseUrl === "https://code.deepline.com" ? "" : `DEEPLINE_HOST_URL=${JSON.stringify(baseUrl)} `;
|
|
30133
30292
|
return `${hostPrefix}deepline setup --scope ${scope} --json`;
|
|
30134
30293
|
}
|
|
30294
|
+
function setupRetry(input2) {
|
|
30295
|
+
return {
|
|
30296
|
+
phase: input2.phase,
|
|
30297
|
+
command: setupResumeCommand(input2.baseUrl, input2.scope),
|
|
30298
|
+
automatic: true
|
|
30299
|
+
};
|
|
30300
|
+
}
|
|
30301
|
+
function reportSetupPhaseFailure(input2) {
|
|
30302
|
+
failSetupPhase(input2.phases, input2.phase, input2.code);
|
|
30303
|
+
const statePath = persistSetupProgress({
|
|
30304
|
+
baseUrl: input2.baseUrl,
|
|
30305
|
+
scope: input2.scope,
|
|
30306
|
+
root: input2.root,
|
|
30307
|
+
phases: input2.phases,
|
|
30308
|
+
status: "failed"
|
|
30309
|
+
});
|
|
30310
|
+
const retry = setupRetry(input2);
|
|
30311
|
+
printCommandEnvelope(
|
|
30312
|
+
{
|
|
30313
|
+
ok: false,
|
|
30314
|
+
status: "failed",
|
|
30315
|
+
code: input2.code,
|
|
30316
|
+
exitCode: input2.exitCode,
|
|
30317
|
+
scope: input2.scope,
|
|
30318
|
+
message: input2.message,
|
|
30319
|
+
phases: input2.phases,
|
|
30320
|
+
failedPhase: input2.phase,
|
|
30321
|
+
retry,
|
|
30322
|
+
statePath,
|
|
30323
|
+
next: retry.command,
|
|
30324
|
+
...input2.extra ?? {}
|
|
30325
|
+
},
|
|
30326
|
+
{ json: input2.json }
|
|
30327
|
+
);
|
|
30328
|
+
return input2.exitCode;
|
|
30329
|
+
}
|
|
30135
30330
|
async function readAuthStatus(authScope) {
|
|
30136
30331
|
try {
|
|
30137
30332
|
const captured = await captureStdout2(
|
|
@@ -30151,63 +30346,44 @@ async function readAuthStatus(authScope) {
|
|
|
30151
30346
|
}
|
|
30152
30347
|
function reportSetupAuthStatusFailure(input2) {
|
|
30153
30348
|
if (!input2.auth.error) return null;
|
|
30154
|
-
|
|
30155
|
-
|
|
30156
|
-
|
|
30157
|
-
|
|
30158
|
-
|
|
30159
|
-
|
|
30160
|
-
|
|
30161
|
-
|
|
30162
|
-
|
|
30163
|
-
|
|
30164
|
-
}
|
|
30165
|
-
|
|
30166
|
-
);
|
|
30167
|
-
return 4;
|
|
30349
|
+
return reportSetupPhaseFailure({
|
|
30350
|
+
baseUrl: input2.baseUrl,
|
|
30351
|
+
scope: input2.scope,
|
|
30352
|
+
root: input2.root,
|
|
30353
|
+
phases: input2.phases,
|
|
30354
|
+
phase: "auth",
|
|
30355
|
+
code: "AUTH_STATUS_FAILED",
|
|
30356
|
+
exitCode: 4,
|
|
30357
|
+
message: "Deepline could not verify authorization with the configured host.",
|
|
30358
|
+
json: input2.json,
|
|
30359
|
+
extra: { authScope: input2.authScope }
|
|
30360
|
+
});
|
|
30168
30361
|
}
|
|
30169
|
-
|
|
30170
|
-
|
|
30171
|
-
|
|
30172
|
-
|
|
30173
|
-
|
|
30174
|
-
|
|
30175
|
-
} catch (error) {
|
|
30176
|
-
printCommandEnvelope(
|
|
30177
|
-
{
|
|
30178
|
-
ok: false,
|
|
30179
|
-
status: "failed",
|
|
30180
|
-
code: "INVALID_SETUP_SCOPE",
|
|
30181
|
-
exitCode: 2,
|
|
30182
|
-
message: error instanceof Error ? error.message : String(error)
|
|
30183
|
-
},
|
|
30184
|
-
{ json: options.json }
|
|
30185
|
-
);
|
|
30186
|
-
return 2;
|
|
30187
|
-
}
|
|
30188
|
-
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
30189
|
-
const skillsStatePath = skillsStatePathForScope(baseUrl, scope, root);
|
|
30362
|
+
function buildDoctorAssessment(input2) {
|
|
30363
|
+
const skillsStatePath = skillsStatePathForScope(
|
|
30364
|
+
input2.baseUrl,
|
|
30365
|
+
input2.scope,
|
|
30366
|
+
input2.root
|
|
30367
|
+
);
|
|
30190
30368
|
const skillsState = parseCapturedJson(safeRead(skillsStatePath));
|
|
30191
|
-
const
|
|
30192
|
-
const
|
|
30193
|
-
const
|
|
30194
|
-
const
|
|
30195
|
-
const
|
|
30196
|
-
const authScopeOk = scope === "local" ? Boolean(projectAuth) : Boolean(apiKey && !projectAuth);
|
|
30197
|
-
const skillsOk = skillsState?.scope === scope && Array.isArray(skillsState.agents) && skillsState.agents.length > 0;
|
|
30369
|
+
const apiKey = input2.scope === "local" ? resolveProjectApiKeyForBaseUrl(input2.baseUrl) : resolveGlobalApiKeyForBaseUrl(input2.baseUrl);
|
|
30370
|
+
const projectAuth = input2.scope === "local" && apiKey ? getResolvedProjectAuthSource(input2.baseUrl, apiKey) : null;
|
|
30371
|
+
const connected = input2.authStatus.payload?.connected === true;
|
|
30372
|
+
const authScopeOk = input2.scope === "local" ? Boolean(projectAuth) : Boolean(apiKey && !projectAuth);
|
|
30373
|
+
const skillsOk = skillsState?.scope === input2.scope && typeof skillsState.skillsVersion === "string" && Array.isArray(skillsState.agents) && skillsState.agents.length > 0;
|
|
30198
30374
|
const runningCliPath = process.argv[1] ? (0, import_node_path20.resolve)(process.argv[1]) : null;
|
|
30199
|
-
const globalCli = scope === "global" ? inspectGlobalCliAvailability() : null;
|
|
30375
|
+
const globalCli = input2.scope === "global" ? inspectGlobalCliAvailability() : null;
|
|
30200
30376
|
const pathGlobalCli = globalCli?.path ?? null;
|
|
30201
|
-
const cliPath = scope === "global" ? pathGlobalCli : runningCliPath;
|
|
30202
|
-
const cliScopeOk = scope === "global" ? Boolean(pathGlobalCli) : Boolean(
|
|
30203
|
-
root && runningCliPath?.includes((0, import_node_path20.join)(root, ".deepline", "runtime"))
|
|
30377
|
+
const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
|
|
30378
|
+
const cliScopeOk = input2.scope === "global" ? Boolean(pathGlobalCli) : Boolean(
|
|
30379
|
+
input2.root && runningCliPath?.includes((0, import_node_path20.join)(input2.root, ".deepline", "runtime"))
|
|
30204
30380
|
);
|
|
30205
30381
|
const checks = {
|
|
30206
30382
|
cli: {
|
|
30207
30383
|
ok: Boolean(cliPath) && cliScopeOk,
|
|
30208
30384
|
version: SDK_VERSION,
|
|
30209
30385
|
path: cliPath,
|
|
30210
|
-
scope
|
|
30386
|
+
scope: input2.scope
|
|
30211
30387
|
},
|
|
30212
30388
|
skills: {
|
|
30213
30389
|
ok: skillsOk,
|
|
@@ -30218,16 +30394,48 @@ async function runDoctorCommand(options) {
|
|
|
30218
30394
|
auth: {
|
|
30219
30395
|
ok: connected && authScopeOk,
|
|
30220
30396
|
scope: projectAuth ? "local" : apiKey ? "global" : null,
|
|
30221
|
-
status: authStatus.payload?.status ?? "not_connected"
|
|
30397
|
+
status: input2.authStatus.payload?.status ?? "not_connected"
|
|
30222
30398
|
},
|
|
30223
30399
|
api: {
|
|
30224
|
-
ok: connected && authStatus.exitCode === 0,
|
|
30225
|
-
host: baseUrl,
|
|
30226
|
-
workspace: authStatus.payload?.workspace ?? null,
|
|
30400
|
+
ok: connected && input2.authStatus.exitCode === 0,
|
|
30401
|
+
host: input2.baseUrl,
|
|
30402
|
+
workspace: input2.authStatus.payload?.workspace ?? null,
|
|
30227
30403
|
providerSpend: false
|
|
30228
30404
|
}
|
|
30229
30405
|
};
|
|
30230
|
-
|
|
30406
|
+
return {
|
|
30407
|
+
ok: Object.values(checks).every((check) => check.ok),
|
|
30408
|
+
checks
|
|
30409
|
+
};
|
|
30410
|
+
}
|
|
30411
|
+
async function runDoctorCommand(options) {
|
|
30412
|
+
let scope;
|
|
30413
|
+
let root;
|
|
30414
|
+
try {
|
|
30415
|
+
scope = normalizeScope2(options.scope);
|
|
30416
|
+
root = resolveScopeRoot(scope);
|
|
30417
|
+
} catch (error) {
|
|
30418
|
+
printCommandEnvelope(
|
|
30419
|
+
{
|
|
30420
|
+
ok: false,
|
|
30421
|
+
status: "failed",
|
|
30422
|
+
code: "INVALID_SETUP_SCOPE",
|
|
30423
|
+
exitCode: 2,
|
|
30424
|
+
message: error instanceof Error ? error.message : String(error)
|
|
30425
|
+
},
|
|
30426
|
+
{ json: options.json }
|
|
30427
|
+
);
|
|
30428
|
+
return 2;
|
|
30429
|
+
}
|
|
30430
|
+
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
30431
|
+
const authScope = authScopeForSetup(scope);
|
|
30432
|
+
const authStatus = await readAuthStatus(authScope);
|
|
30433
|
+
const { ok, checks } = buildDoctorAssessment({
|
|
30434
|
+
baseUrl,
|
|
30435
|
+
scope,
|
|
30436
|
+
root,
|
|
30437
|
+
authStatus
|
|
30438
|
+
});
|
|
30231
30439
|
const quickstart = setupQuickstartCommand(baseUrl);
|
|
30232
30440
|
printCommandEnvelope(
|
|
30233
30441
|
{
|
|
@@ -30253,11 +30461,16 @@ async function runDoctorCommand(options) {
|
|
|
30253
30461
|
return ok ? 0 : 7;
|
|
30254
30462
|
}
|
|
30255
30463
|
function pendingResult(input2) {
|
|
30464
|
+
input2.phases.auth = {
|
|
30465
|
+
status: "waiting",
|
|
30466
|
+
outcome: "authorization_pending"
|
|
30467
|
+
};
|
|
30256
30468
|
const statePath = writeSetupState({
|
|
30257
30469
|
baseUrl: input2.baseUrl,
|
|
30258
30470
|
scope: input2.scope,
|
|
30259
30471
|
root: input2.root,
|
|
30260
|
-
status: "authorization_pending"
|
|
30472
|
+
status: "authorization_pending",
|
|
30473
|
+
phases: input2.phases
|
|
30261
30474
|
});
|
|
30262
30475
|
if (input2.authorizationUrl) {
|
|
30263
30476
|
process.stderr.write(`Authorize Deepline: ${input2.authorizationUrl}
|
|
@@ -30271,6 +30484,14 @@ function pendingResult(input2) {
|
|
|
30271
30484
|
scope: input2.scope,
|
|
30272
30485
|
authorizationUrl: input2.authorizationUrl || null,
|
|
30273
30486
|
statePath,
|
|
30487
|
+
phases: input2.phases,
|
|
30488
|
+
currentPhase: "auth",
|
|
30489
|
+
resumed: input2.resumed,
|
|
30490
|
+
retry: setupRetry({
|
|
30491
|
+
baseUrl: input2.baseUrl,
|
|
30492
|
+
scope: input2.scope,
|
|
30493
|
+
phase: "auth"
|
|
30494
|
+
}),
|
|
30274
30495
|
next: `Approve the link, then run: ${setupResumeCommand(input2.baseUrl, input2.scope)}`,
|
|
30275
30496
|
render: {
|
|
30276
30497
|
sections: [
|
|
@@ -30301,84 +30522,146 @@ async function runSetupCommand(options) {
|
|
|
30301
30522
|
status: "failed",
|
|
30302
30523
|
code: "INVALID_SETUP_SCOPE",
|
|
30303
30524
|
exitCode: 2,
|
|
30304
|
-
message: error instanceof Error ? error.message : String(error)
|
|
30525
|
+
message: error instanceof Error ? error.message : String(error),
|
|
30526
|
+
phases: {
|
|
30527
|
+
...initialSetupPhases(),
|
|
30528
|
+
cli: { status: "failed", code: "INVALID_SETUP_SCOPE" }
|
|
30529
|
+
},
|
|
30530
|
+
failedPhase: "cli"
|
|
30305
30531
|
},
|
|
30306
30532
|
{ json: options.json }
|
|
30307
30533
|
);
|
|
30308
30534
|
return 2;
|
|
30309
30535
|
}
|
|
30310
30536
|
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
30311
|
-
|
|
30312
|
-
|
|
30313
|
-
|
|
30314
|
-
|
|
30315
|
-
|
|
30316
|
-
|
|
30317
|
-
|
|
30318
|
-
|
|
30319
|
-
|
|
30320
|
-
|
|
30537
|
+
const previousState = readSetupState({ baseUrl, scope, root });
|
|
30538
|
+
const { resumed, phases } = selectSetupProgress(previousState);
|
|
30539
|
+
if (phases.cli.status !== "complete") {
|
|
30540
|
+
beginSetupPhase(phases, "cli");
|
|
30541
|
+
persistSetupProgress({ baseUrl, scope, root, phases });
|
|
30542
|
+
if (scope === "global") {
|
|
30543
|
+
const globalCli = inspectGlobalCliAvailability();
|
|
30544
|
+
if (!globalCli.ok) {
|
|
30545
|
+
const installedButUnreachable = Boolean(globalCli.persistentPath);
|
|
30546
|
+
const code = installedButUnreachable ? "GLOBAL_CLI_NOT_ON_PATH" : "GLOBAL_CLI_NOT_INSTALLED";
|
|
30547
|
+
return reportSetupPhaseFailure({
|
|
30548
|
+
baseUrl,
|
|
30321
30549
|
scope,
|
|
30322
|
-
|
|
30550
|
+
root,
|
|
30551
|
+
phases,
|
|
30552
|
+
phase: "cli",
|
|
30553
|
+
code,
|
|
30554
|
+
exitCode: 7,
|
|
30323
30555
|
message: installedButUnreachable ? `The global Deepline executable is not reachable on PATH: ${globalCli.persistentPath}` : "No persistent global Deepline executable was found.",
|
|
30324
|
-
|
|
30325
|
-
|
|
30326
|
-
|
|
30327
|
-
|
|
30328
|
-
|
|
30556
|
+
json: options.json,
|
|
30557
|
+
extra: {
|
|
30558
|
+
persistentPath: globalCli.persistentPath,
|
|
30559
|
+
fallback: "https://code.deepline.com/INSTALL.md"
|
|
30560
|
+
}
|
|
30561
|
+
});
|
|
30562
|
+
}
|
|
30329
30563
|
}
|
|
30330
|
-
|
|
30331
|
-
|
|
30332
|
-
|
|
30333
|
-
|
|
30334
|
-
|
|
30335
|
-
|
|
30336
|
-
|
|
30564
|
+
const conflict = inspectPathConflict();
|
|
30565
|
+
if (conflict) {
|
|
30566
|
+
return reportSetupPhaseFailure({
|
|
30567
|
+
baseUrl,
|
|
30568
|
+
scope,
|
|
30569
|
+
root,
|
|
30570
|
+
phases,
|
|
30571
|
+
phase: "cli",
|
|
30337
30572
|
code: "PATH_CONFLICT",
|
|
30338
30573
|
exitCode: 7,
|
|
30339
|
-
path: conflict,
|
|
30340
30574
|
message: `An unknown executable named deepline is first on PATH: ${conflict}`,
|
|
30341
|
-
|
|
30342
|
-
|
|
30343
|
-
|
|
30344
|
-
|
|
30345
|
-
|
|
30575
|
+
json: options.json,
|
|
30576
|
+
extra: { path: conflict }
|
|
30577
|
+
});
|
|
30578
|
+
}
|
|
30579
|
+
completeSetupPhase(phases, "cli", "available");
|
|
30580
|
+
persistSetupProgress({ baseUrl, scope, root, phases });
|
|
30346
30581
|
}
|
|
30347
|
-
|
|
30348
|
-
|
|
30349
|
-
|
|
30350
|
-
|
|
30582
|
+
if (phases.cleanup.status !== "complete") {
|
|
30583
|
+
beginSetupPhase(phases, "cleanup");
|
|
30584
|
+
persistSetupProgress({ baseUrl, scope, root, phases });
|
|
30585
|
+
try {
|
|
30586
|
+
const removedLegacyPaths = removeKnownLegacyPaths(baseUrl);
|
|
30587
|
+
if (removedLegacyPaths.length > 0) {
|
|
30588
|
+
process.stderr.write(
|
|
30589
|
+
`Removed ${removedLegacyPaths.length} known legacy Deepline path(s).
|
|
30351
30590
|
`
|
|
30352
|
-
|
|
30591
|
+
);
|
|
30592
|
+
}
|
|
30593
|
+
completeSetupPhase(
|
|
30594
|
+
phases,
|
|
30595
|
+
"cleanup",
|
|
30596
|
+
removedLegacyPaths.length > 0 ? "removed_legacy_paths" : "clean"
|
|
30597
|
+
);
|
|
30598
|
+
persistSetupProgress({ baseUrl, scope, root, phases });
|
|
30599
|
+
} catch (error) {
|
|
30600
|
+
return reportSetupPhaseFailure({
|
|
30601
|
+
baseUrl,
|
|
30602
|
+
scope,
|
|
30603
|
+
root,
|
|
30604
|
+
phases,
|
|
30605
|
+
phase: "cleanup",
|
|
30606
|
+
code: "LEGACY_CLEANUP_FAILED",
|
|
30607
|
+
exitCode: 5,
|
|
30608
|
+
message: error instanceof Error ? error.message : String(error),
|
|
30609
|
+
json: options.json
|
|
30610
|
+
});
|
|
30611
|
+
}
|
|
30353
30612
|
}
|
|
30354
|
-
|
|
30613
|
+
let skillsPayload = null;
|
|
30614
|
+
if (phases.skills.status !== "complete") {
|
|
30615
|
+
beginSetupPhase(phases, "skills");
|
|
30616
|
+
persistSetupProgress({ baseUrl, scope, root, phases });
|
|
30617
|
+
process.stderr.write(`Installing Deepline skills (${scope})...
|
|
30355
30618
|
`);
|
|
30356
|
-
|
|
30357
|
-
|
|
30358
|
-
|
|
30359
|
-
|
|
30360
|
-
|
|
30361
|
-
|
|
30362
|
-
|
|
30363
|
-
|
|
30364
|
-
|
|
30619
|
+
const skills = await captureStdout2(
|
|
30620
|
+
() => runSkillsCommand({ scope, json: true })
|
|
30621
|
+
);
|
|
30622
|
+
skillsPayload = parseCapturedJson(skills.stdout);
|
|
30623
|
+
if (skills.exitCode !== 0) {
|
|
30624
|
+
return reportSetupPhaseFailure({
|
|
30625
|
+
baseUrl,
|
|
30626
|
+
scope,
|
|
30627
|
+
root,
|
|
30628
|
+
phases,
|
|
30629
|
+
phase: "skills",
|
|
30365
30630
|
code: "SKILLS_INSTALL_FAILED",
|
|
30366
30631
|
exitCode: skills.exitCode,
|
|
30367
|
-
|
|
30368
|
-
|
|
30369
|
-
|
|
30370
|
-
}
|
|
30371
|
-
|
|
30632
|
+
message: typeof skillsPayload?.message === "string" ? skillsPayload.message : "Deepline skills could not be installed.",
|
|
30633
|
+
json: options.json,
|
|
30634
|
+
extra: { detail: skillsPayload }
|
|
30635
|
+
});
|
|
30636
|
+
}
|
|
30637
|
+
completeSetupPhase(
|
|
30638
|
+
phases,
|
|
30639
|
+
"skills",
|
|
30640
|
+
skillsPayload?.status === "current" ? "current" : "installed"
|
|
30641
|
+
);
|
|
30642
|
+
writeSetupState({
|
|
30643
|
+
baseUrl,
|
|
30644
|
+
scope,
|
|
30645
|
+
root,
|
|
30646
|
+
status: "skills_installed",
|
|
30647
|
+
phases
|
|
30648
|
+
});
|
|
30649
|
+
} else {
|
|
30650
|
+
skillsPayload = parseCapturedJson(
|
|
30651
|
+
safeRead(skillsStatePathForScope(baseUrl, scope, root))
|
|
30372
30652
|
);
|
|
30373
|
-
return skills.exitCode;
|
|
30374
30653
|
}
|
|
30375
|
-
writeSetupState({ baseUrl, scope, root, status: "skills_installed" });
|
|
30376
30654
|
const authScope = authScopeForSetup(scope);
|
|
30655
|
+
beginSetupPhase(phases, "auth");
|
|
30656
|
+
persistSetupProgress({ baseUrl, scope, root, phases });
|
|
30377
30657
|
let auth = await readAuthStatus(authScope);
|
|
30378
30658
|
const initialAuthFailure = reportSetupAuthStatusFailure({
|
|
30379
30659
|
auth,
|
|
30660
|
+
baseUrl,
|
|
30380
30661
|
authScope,
|
|
30381
30662
|
scope,
|
|
30663
|
+
root,
|
|
30664
|
+
phases,
|
|
30382
30665
|
json: options.json
|
|
30383
30666
|
});
|
|
30384
30667
|
if (initialAuthFailure !== null) return initialAuthFailure;
|
|
@@ -30393,8 +30676,11 @@ async function runSetupCommand(options) {
|
|
|
30393
30676
|
auth = await readAuthStatus(authScope);
|
|
30394
30677
|
const resumedAuthFailure = reportSetupAuthStatusFailure({
|
|
30395
30678
|
auth,
|
|
30679
|
+
baseUrl,
|
|
30396
30680
|
authScope,
|
|
30397
30681
|
scope,
|
|
30682
|
+
root,
|
|
30683
|
+
phases,
|
|
30398
30684
|
json: options.json
|
|
30399
30685
|
});
|
|
30400
30686
|
if (resumedAuthFailure !== null) return resumedAuthFailure;
|
|
@@ -30405,7 +30691,9 @@ async function runSetupCommand(options) {
|
|
|
30405
30691
|
baseUrl,
|
|
30406
30692
|
scope,
|
|
30407
30693
|
root,
|
|
30694
|
+
phases,
|
|
30408
30695
|
authorizationUrl: stillPending.claimUrl,
|
|
30696
|
+
resumed,
|
|
30409
30697
|
json: options.json
|
|
30410
30698
|
});
|
|
30411
30699
|
}
|
|
@@ -30422,24 +30710,30 @@ async function runSetupCommand(options) {
|
|
|
30422
30710
|
);
|
|
30423
30711
|
printCapturedAuthorizationUrl(registered.stdout);
|
|
30424
30712
|
if (registered.exitCode !== 0) {
|
|
30425
|
-
|
|
30426
|
-
|
|
30427
|
-
|
|
30428
|
-
|
|
30429
|
-
|
|
30430
|
-
|
|
30431
|
-
|
|
30432
|
-
|
|
30433
|
-
|
|
30434
|
-
|
|
30435
|
-
|
|
30436
|
-
|
|
30713
|
+
return reportSetupPhaseFailure({
|
|
30714
|
+
baseUrl,
|
|
30715
|
+
scope,
|
|
30716
|
+
root,
|
|
30717
|
+
phases,
|
|
30718
|
+
phase: "auth",
|
|
30719
|
+
code: "AUTH_REGISTER_FAILED",
|
|
30720
|
+
exitCode: registered.exitCode,
|
|
30721
|
+
message: "Deepline browser authorization could not be started.",
|
|
30722
|
+
json: options.json,
|
|
30723
|
+
extra: {
|
|
30724
|
+
detail: parseCapturedJson(registered.stdout),
|
|
30725
|
+
authScope
|
|
30726
|
+
}
|
|
30727
|
+
});
|
|
30437
30728
|
}
|
|
30438
30729
|
auth = await readAuthStatus(authScope);
|
|
30439
30730
|
const registeredAuthFailure = reportSetupAuthStatusFailure({
|
|
30440
30731
|
auth,
|
|
30732
|
+
baseUrl,
|
|
30441
30733
|
authScope,
|
|
30442
30734
|
scope,
|
|
30735
|
+
root,
|
|
30736
|
+
phases,
|
|
30443
30737
|
json: options.json
|
|
30444
30738
|
});
|
|
30445
30739
|
if (registeredAuthFailure !== null) return registeredAuthFailure;
|
|
@@ -30449,40 +30743,60 @@ async function runSetupCommand(options) {
|
|
|
30449
30743
|
baseUrl,
|
|
30450
30744
|
scope,
|
|
30451
30745
|
root,
|
|
30746
|
+
phases,
|
|
30452
30747
|
authorizationUrl: pending?.claimUrl ?? "",
|
|
30748
|
+
resumed,
|
|
30453
30749
|
json: options.json
|
|
30454
30750
|
});
|
|
30455
30751
|
}
|
|
30456
30752
|
}
|
|
30457
|
-
|
|
30458
|
-
|
|
30459
|
-
|
|
30460
|
-
|
|
30461
|
-
|
|
30462
|
-
|
|
30463
|
-
|
|
30464
|
-
|
|
30465
|
-
|
|
30466
|
-
|
|
30467
|
-
|
|
30468
|
-
|
|
30469
|
-
|
|
30753
|
+
completeSetupPhase(phases, "auth", "connected");
|
|
30754
|
+
beginSetupPhase(phases, "verify");
|
|
30755
|
+
persistSetupProgress({ baseUrl, scope, root, phases });
|
|
30756
|
+
const assessment = buildDoctorAssessment({
|
|
30757
|
+
baseUrl,
|
|
30758
|
+
scope,
|
|
30759
|
+
root,
|
|
30760
|
+
authStatus: auth
|
|
30761
|
+
});
|
|
30762
|
+
const quickstart = setupQuickstartCommand(baseUrl);
|
|
30763
|
+
const doctorPayload = {
|
|
30764
|
+
ok: assessment.ok,
|
|
30765
|
+
status: assessment.ok ? "complete" : "failed",
|
|
30766
|
+
code: assessment.ok ? "DOCTOR_OK" : "DOCTOR_FAILED",
|
|
30767
|
+
exitCode: assessment.ok ? 0 : 7,
|
|
30768
|
+
checks: assessment.checks,
|
|
30769
|
+
next: assessment.ok ? quickstart : `deepline doctor --scope ${scope} --json`
|
|
30770
|
+
};
|
|
30771
|
+
if (!assessment.ok) {
|
|
30772
|
+
return reportSetupPhaseFailure({
|
|
30773
|
+
baseUrl,
|
|
30774
|
+
scope,
|
|
30775
|
+
root,
|
|
30776
|
+
phases,
|
|
30777
|
+
phase: "verify",
|
|
30778
|
+
code: "DOCTOR_FAILED",
|
|
30779
|
+
exitCode: 7,
|
|
30780
|
+
message: "Deepline setup verification found one or more failed checks.",
|
|
30781
|
+
json: options.json,
|
|
30782
|
+
extra: {
|
|
30470
30783
|
doctor: doctorPayload,
|
|
30471
|
-
|
|
30472
|
-
|
|
30473
|
-
|
|
30474
|
-
|
|
30475
|
-
|
|
30784
|
+
diagnostic: {
|
|
30785
|
+
command: `deepline doctor --scope ${scope} --json`
|
|
30786
|
+
}
|
|
30787
|
+
}
|
|
30788
|
+
});
|
|
30476
30789
|
}
|
|
30790
|
+
completeSetupPhase(phases, "verify", "verified");
|
|
30477
30791
|
const statePath = writeSetupState({
|
|
30478
30792
|
baseUrl,
|
|
30479
30793
|
scope,
|
|
30480
30794
|
root,
|
|
30481
|
-
status: "complete"
|
|
30795
|
+
status: "complete",
|
|
30796
|
+
phases
|
|
30482
30797
|
});
|
|
30483
30798
|
const doctorChecks = asRecord2(doctorPayload?.checks);
|
|
30484
30799
|
const apiCheck = asRecord2(doctorChecks?.api);
|
|
30485
|
-
const quickstart = setupQuickstartCommand(baseUrl);
|
|
30486
30800
|
printCommandEnvelope(
|
|
30487
30801
|
{
|
|
30488
30802
|
ok: true,
|
|
@@ -30495,6 +30809,10 @@ async function runSetupCommand(options) {
|
|
|
30495
30809
|
rollbackCommand: rollbackCommand(scope, root),
|
|
30496
30810
|
statePath,
|
|
30497
30811
|
doctor: doctorPayload,
|
|
30812
|
+
phases,
|
|
30813
|
+
currentPhase: null,
|
|
30814
|
+
failedPhase: null,
|
|
30815
|
+
resumed,
|
|
30498
30816
|
next: quickstart,
|
|
30499
30817
|
render: {
|
|
30500
30818
|
sections: [
|
|
@@ -30517,8 +30835,9 @@ function registerSetupCommands(program) {
|
|
|
30517
30835
|
"after",
|
|
30518
30836
|
`
|
|
30519
30837
|
Notes:
|
|
30520
|
-
Setup is idempotent. Bare setup resumes
|
|
30838
|
+
Setup is idempotent. Bare setup resumes the first incomplete or failed phase.
|
|
30521
30839
|
It installs skills before auth and does not run quickstart.
|
|
30840
|
+
JSON output includes phase status and an exact retry command.
|
|
30522
30841
|
|
|
30523
30842
|
Examples:
|
|
30524
30843
|
deepline setup --json
|