deepline 0.1.138 → 0.1.140
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/README.md +2 -2
- package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +58 -18
- package/dist/bundling-sources/apps/play-runner-workers/src/workflow-retry.ts +15 -1
- package/dist/bundling-sources/sdk/src/config.ts +13 -310
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/coordinator-headers.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +27 -2
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +3 -0
- package/dist/cli/index.js +92 -576
- package/dist/cli/index.mjs +108 -600
- package/dist/index.js +14 -148
- package/dist/index.mjs +15 -157
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -237,22 +237,6 @@ var PROD_URL = "https://code.deepline.com";
|
|
|
237
237
|
var DEFAULT_TIMEOUT = 6e4;
|
|
238
238
|
var DEFAULT_MAX_RETRIES = 3;
|
|
239
239
|
var PROJECT_DEEPLINE_ENV_FILE = ".env.deepline";
|
|
240
|
-
var COWORK_IGNORED_WORKSPACE_DIRS = /* @__PURE__ */ new Set([
|
|
241
|
-
".auto-memory",
|
|
242
|
-
".claude",
|
|
243
|
-
".remote-plugins",
|
|
244
|
-
"outputs",
|
|
245
|
-
"plugins",
|
|
246
|
-
"uploads"
|
|
247
|
-
]);
|
|
248
|
-
var COWORK_PROJECT_MARKERS = [
|
|
249
|
-
".deepline",
|
|
250
|
-
".env.deepline",
|
|
251
|
-
".git",
|
|
252
|
-
"AGENTS.md",
|
|
253
|
-
"package.json",
|
|
254
|
-
"pyproject.toml"
|
|
255
|
-
];
|
|
256
240
|
function baseUrlSlug(baseUrl) {
|
|
257
241
|
let url;
|
|
258
242
|
try {
|
|
@@ -298,124 +282,9 @@ function findNearestEnvFile(name, startDir = process.cwd()) {
|
|
|
298
282
|
current = parent;
|
|
299
283
|
}
|
|
300
284
|
}
|
|
301
|
-
function
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
} catch {
|
|
305
|
-
return false;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
function canonicalPath(path) {
|
|
309
|
-
try {
|
|
310
|
-
return (0, import_node_fs.realpathSync)(path);
|
|
311
|
-
} catch {
|
|
312
|
-
return (0, import_node_path.resolve)(path);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
function isTruthy(value) {
|
|
316
|
-
return /^(1|true|yes|on)$/i.test(value?.trim() ?? "");
|
|
317
|
-
}
|
|
318
|
-
function sessionRootFromPath(path) {
|
|
319
|
-
const trimmed = path?.trim();
|
|
320
|
-
if (!trimmed) return null;
|
|
321
|
-
const match = /^\/sessions\/[^/]+(?=\/|$)/.exec(trimmed);
|
|
322
|
-
return match?.[0] ?? null;
|
|
323
|
-
}
|
|
324
|
-
function coworkSessionRoot() {
|
|
325
|
-
const home = process.env.HOME?.trim();
|
|
326
|
-
const homeSessionRoot = sessionRootFromPath(home);
|
|
327
|
-
if (homeSessionRoot && isDirectory((0, import_node_path.join)(homeSessionRoot, "mnt"))) {
|
|
328
|
-
return homeSessionRoot;
|
|
329
|
-
}
|
|
330
|
-
const cwdSessionRoot = sessionRootFromPath(process.cwd());
|
|
331
|
-
if (cwdSessionRoot && isDirectory((0, import_node_path.join)(cwdSessionRoot, "mnt"))) {
|
|
332
|
-
return cwdSessionRoot;
|
|
333
|
-
}
|
|
334
|
-
if (isTruthy(process.env.CLAUDE_CODE_REMOTE) && home) {
|
|
335
|
-
const mountedRoot = (0, import_node_path.join)(home, "mnt");
|
|
336
|
-
if (isDirectory(mountedRoot)) return (0, import_node_path.resolve)(home);
|
|
337
|
-
}
|
|
338
|
-
return null;
|
|
339
|
-
}
|
|
340
|
-
function isCoworkLikeSandbox() {
|
|
341
|
-
const home = process.env.HOME?.trim();
|
|
342
|
-
return isTruthy(process.env.CLAUDE_CODE_REMOTE) || sessionRootFromPath(home) !== null || sessionRootFromPath(process.cwd()) !== null;
|
|
343
|
-
}
|
|
344
|
-
function coworkProjectScore(path) {
|
|
345
|
-
let score = 0;
|
|
346
|
-
for (const marker of COWORK_PROJECT_MARKERS) {
|
|
347
|
-
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(path, marker))) score += 1;
|
|
348
|
-
}
|
|
349
|
-
return score;
|
|
350
|
-
}
|
|
351
|
-
function listCoworkWorkspaceDirCandidates() {
|
|
352
|
-
if (!isCoworkLikeSandbox()) {
|
|
353
|
-
return [];
|
|
354
|
-
}
|
|
355
|
-
const explicitProjectDir = process.env.CLAUDE_PROJECT_DIR?.trim();
|
|
356
|
-
if (explicitProjectDir && isDirectory(explicitProjectDir)) {
|
|
357
|
-
return [(0, import_node_path.resolve)(explicitProjectDir)];
|
|
358
|
-
}
|
|
359
|
-
const sessionRoot = coworkSessionRoot();
|
|
360
|
-
if (!sessionRoot) return [];
|
|
361
|
-
const mountedRoot = (0, import_node_path.join)(sessionRoot, "mnt");
|
|
362
|
-
if (!isDirectory(mountedRoot)) return [];
|
|
363
|
-
let names;
|
|
364
|
-
try {
|
|
365
|
-
names = (0, import_node_fs.readdirSync)(mountedRoot).sort();
|
|
366
|
-
} catch {
|
|
367
|
-
return [];
|
|
368
|
-
}
|
|
369
|
-
const candidates = [];
|
|
370
|
-
for (const name of names) {
|
|
371
|
-
if (name.startsWith(".") || COWORK_IGNORED_WORKSPACE_DIRS.has(name)) {
|
|
372
|
-
continue;
|
|
373
|
-
}
|
|
374
|
-
const candidate = (0, import_node_path.join)(mountedRoot, name);
|
|
375
|
-
if (isDirectory(candidate)) candidates.push(candidate);
|
|
376
|
-
}
|
|
377
|
-
if (candidates.length <= 1) return candidates;
|
|
378
|
-
const projectLike = candidates.filter(
|
|
379
|
-
(candidate) => coworkProjectScore(candidate) > 0
|
|
380
|
-
);
|
|
381
|
-
return projectLike.length > 0 ? projectLike : candidates;
|
|
382
|
-
}
|
|
383
|
-
function isInIgnoredCoworkMount(path) {
|
|
384
|
-
const sessionRoot = coworkSessionRoot();
|
|
385
|
-
if (!sessionRoot) return false;
|
|
386
|
-
const mountedRoot = canonicalPath((0, import_node_path.join)(sessionRoot, "mnt"));
|
|
387
|
-
const resolvedPath = canonicalPath(path);
|
|
388
|
-
const prefix = `${mountedRoot}/`;
|
|
389
|
-
if (!resolvedPath.startsWith(prefix)) return false;
|
|
390
|
-
const relativePath = resolvedPath.slice(prefix.length);
|
|
391
|
-
const mountName = relativePath.split("/")[0];
|
|
392
|
-
return mountName.startsWith(".") || COWORK_IGNORED_WORKSPACE_DIRS.has(mountName);
|
|
393
|
-
}
|
|
394
|
-
function detectCoworkWorkspaceDir() {
|
|
395
|
-
const candidates = listCoworkWorkspaceDirCandidates();
|
|
396
|
-
return candidates.length === 1 ? candidates[0] : null;
|
|
397
|
-
}
|
|
398
|
-
function loadProjectEnvCandidates(startDir = process.cwd()) {
|
|
399
|
-
const filePaths = [];
|
|
400
|
-
const sources = /* @__PURE__ */ new Map();
|
|
401
|
-
const nearestFile = findNearestEnvFile(PROJECT_DEEPLINE_ENV_FILE, startDir);
|
|
402
|
-
if (nearestFile && !isInIgnoredCoworkMount(nearestFile)) {
|
|
403
|
-
filePaths.push(nearestFile);
|
|
404
|
-
sources.set((0, import_node_path.resolve)(nearestFile), "nearest");
|
|
405
|
-
}
|
|
406
|
-
const coworkWorkspaceDir = detectCoworkWorkspaceDir();
|
|
407
|
-
if (coworkWorkspaceDir) {
|
|
408
|
-
const coworkFile = (0, import_node_path.join)(coworkWorkspaceDir, PROJECT_DEEPLINE_ENV_FILE);
|
|
409
|
-
if ((0, import_node_fs.existsSync)(coworkFile) && !filePaths.some((filePath) => (0, import_node_path.resolve)(filePath) === (0, import_node_path.resolve)(coworkFile))) {
|
|
410
|
-
filePaths.push(coworkFile);
|
|
411
|
-
sources.set((0, import_node_path.resolve)(coworkFile), "cowork");
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
return filePaths.map((filePath) => ({
|
|
415
|
-
filePath,
|
|
416
|
-
env: parseEnvFile(filePath),
|
|
417
|
-
source: sources.get((0, import_node_path.resolve)(filePath)) ?? "nearest"
|
|
418
|
-
}));
|
|
285
|
+
function loadProjectDeeplineEnv(startDir = process.cwd()) {
|
|
286
|
+
const filePath = findNearestEnvFile(PROJECT_DEEPLINE_ENV_FILE, startDir);
|
|
287
|
+
return filePath ? parseEnvFile(filePath) : {};
|
|
419
288
|
}
|
|
420
289
|
function normalizeBaseUrl(baseUrl) {
|
|
421
290
|
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
@@ -479,35 +348,23 @@ function loadGlobalCliEnv() {
|
|
|
479
348
|
return loadCliEnv(PROD_URL);
|
|
480
349
|
}
|
|
481
350
|
function autoDetectBaseUrl() {
|
|
482
|
-
const
|
|
351
|
+
const projectEnv = loadProjectDeeplineEnv();
|
|
483
352
|
const globalEnv = loadGlobalCliEnv();
|
|
484
|
-
return normalizeBaseUrl(process.env[HOST_URL_ENV] ?? "") ||
|
|
485
|
-
...projectEnvs.map(({ env }) => normalizeBaseUrl(env[HOST_URL_ENV]))
|
|
486
|
-
) || normalizeBaseUrl(globalEnv[HOST_URL_ENV] ?? "") || PROD_URL;
|
|
353
|
+
return normalizeBaseUrl(process.env[HOST_URL_ENV] ?? "") || normalizeBaseUrl(projectEnv[HOST_URL_ENV] ?? "") || normalizeBaseUrl(globalEnv[HOST_URL_ENV] ?? "") || PROD_URL;
|
|
487
354
|
}
|
|
488
355
|
function resolveApiKeyForBaseUrl(baseUrl, explicitApiKey) {
|
|
489
356
|
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
490
|
-
const
|
|
357
|
+
const projectEnv = loadProjectDeeplineEnv();
|
|
491
358
|
const cliEnv = loadCliEnv(normalizedBaseUrl || baseUrl);
|
|
359
|
+
const projectBaseUrl = normalizeBaseUrl(projectEnv[HOST_URL_ENV] ?? "");
|
|
360
|
+
const projectKeyApplies = projectBaseUrl === normalizedBaseUrl;
|
|
492
361
|
return firstNonEmpty(
|
|
493
362
|
explicitApiKey,
|
|
494
363
|
process.env[API_KEY_ENV],
|
|
495
|
-
|
|
496
|
-
const projectBaseUrl = normalizeBaseUrl(env[HOST_URL_ENV] ?? "");
|
|
497
|
-
return projectBaseUrl === normalizedBaseUrl ? env[API_KEY_ENV] : "";
|
|
498
|
-
}),
|
|
364
|
+
projectKeyApplies ? projectEnv[API_KEY_ENV] : "",
|
|
499
365
|
cliEnv[API_KEY_ENV]
|
|
500
366
|
);
|
|
501
367
|
}
|
|
502
|
-
function getResolvedProjectAuthSource(baseUrl, apiKey, startDir = process.cwd()) {
|
|
503
|
-
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
504
|
-
const normalizedApiKey = apiKey.trim();
|
|
505
|
-
if (!normalizedBaseUrl || !normalizedApiKey) return null;
|
|
506
|
-
return loadProjectEnvCandidates(startDir).find(({ env }) => {
|
|
507
|
-
const projectBaseUrl = normalizeBaseUrl(env[HOST_URL_ENV] ?? "");
|
|
508
|
-
return projectBaseUrl === normalizedBaseUrl && (env[API_KEY_ENV] ?? "").trim() === normalizedApiKey;
|
|
509
|
-
}) ?? null;
|
|
510
|
-
}
|
|
511
368
|
function resolveConfig(options) {
|
|
512
369
|
const baseUrl = normalizeBaseUrl(
|
|
513
370
|
options?.baseUrl?.trim() || autoDetectBaseUrl()
|
|
@@ -530,69 +387,6 @@ function resolveConfig(options) {
|
|
|
530
387
|
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES
|
|
531
388
|
};
|
|
532
389
|
}
|
|
533
|
-
function mergeProjectEnvFile(filePath, values) {
|
|
534
|
-
const existing = parseEnvFile(filePath);
|
|
535
|
-
const merged = { ...existing, ...values };
|
|
536
|
-
const dir = (0, import_node_path.dirname)(filePath);
|
|
537
|
-
if (!(0, import_node_fs.existsSync)(dir)) (0, import_node_fs.mkdirSync)(dir, { recursive: true });
|
|
538
|
-
ensureProjectEnvIsIgnored(dir);
|
|
539
|
-
const allowedKeys = /* @__PURE__ */ new Set([HOST_URL_ENV, API_KEY_ENV]);
|
|
540
|
-
const lines = Object.entries(merged).filter(([key, value]) => allowedKeys.has(key) && value !== "").map(([key, value]) => `${key}=${value}`);
|
|
541
|
-
(0, import_node_fs.writeFileSync)(filePath, `${lines.join("\n")}
|
|
542
|
-
`, "utf-8");
|
|
543
|
-
}
|
|
544
|
-
function ensureProjectEnvIsIgnored(dir) {
|
|
545
|
-
const gitignorePath = (0, import_node_path.join)(dir, ".gitignore");
|
|
546
|
-
const entry = PROJECT_DEEPLINE_ENV_FILE;
|
|
547
|
-
const existing = (0, import_node_fs.existsSync)(gitignorePath) ? (0, import_node_fs.readFileSync)(gitignorePath, "utf-8") : "";
|
|
548
|
-
const alreadyIgnored = existing.split(/\r?\n/).map((line) => line.trim()).some((line) => line === entry || line === `/${entry}`);
|
|
549
|
-
if (alreadyIgnored) return;
|
|
550
|
-
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
551
|
-
(0, import_node_fs.writeFileSync)(gitignorePath, `${existing}${prefix}${entry}
|
|
552
|
-
`, "utf-8");
|
|
553
|
-
}
|
|
554
|
-
function saveProjectDeeplineEnvValues(values, startDir = process.cwd()) {
|
|
555
|
-
const target = resolveProjectPinTarget(startDir);
|
|
556
|
-
if (!target.ok) {
|
|
557
|
-
throw new ConfigError(
|
|
558
|
-
`Cowork project folder is ambiguous. Candidate folders: ${target.candidates.join(
|
|
559
|
-
", "
|
|
560
|
-
)}. Set CLAUDE_PROJECT_DIR or cd into the intended project folder before running this command.`
|
|
561
|
-
);
|
|
562
|
-
}
|
|
563
|
-
const filePath = (0, import_node_path.join)(target.dir, PROJECT_DEEPLINE_ENV_FILE);
|
|
564
|
-
mergeProjectEnvFile(filePath, values);
|
|
565
|
-
return [filePath];
|
|
566
|
-
}
|
|
567
|
-
function resolveProjectPinTarget(startDir = process.cwd()) {
|
|
568
|
-
const nearestFile = findNearestEnvFile(PROJECT_DEEPLINE_ENV_FILE, startDir);
|
|
569
|
-
if (nearestFile && !isInIgnoredCoworkMount(nearestFile)) {
|
|
570
|
-
return { ok: true, dir: (0, import_node_path.dirname)(nearestFile), source: "nearest" };
|
|
571
|
-
}
|
|
572
|
-
const coworkCandidates = listCoworkWorkspaceDirCandidates();
|
|
573
|
-
if (coworkCandidates.length === 1) {
|
|
574
|
-
return { ok: true, dir: coworkCandidates[0], source: "cowork" };
|
|
575
|
-
}
|
|
576
|
-
if (coworkCandidates.length > 1) {
|
|
577
|
-
const resolvedStartDir = canonicalPath(startDir);
|
|
578
|
-
const cwdCandidate = coworkCandidates.find((candidate) => {
|
|
579
|
-
const resolvedCandidate = canonicalPath(candidate);
|
|
580
|
-
return resolvedStartDir === resolvedCandidate || resolvedStartDir.startsWith(`${resolvedCandidate}/`);
|
|
581
|
-
});
|
|
582
|
-
if (cwdCandidate) {
|
|
583
|
-
return { ok: true, dir: cwdCandidate, source: "cowork" };
|
|
584
|
-
}
|
|
585
|
-
return {
|
|
586
|
-
ok: false,
|
|
587
|
-
reason: "ambiguous_cowork_project",
|
|
588
|
-
candidates: coworkCandidates
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
return { ok: true, dir: (0, import_node_path.resolve)(startDir), source: "cwd" };
|
|
592
|
-
}
|
|
593
|
-
function getActiveProjectAuthSource(startDir = process.cwd()) {
|
|
594
|
-
return loadProjectEnvCandidates(startDir)[0] ?? null;
|
|
595
|
-
}
|
|
596
390
|
|
|
597
391
|
// src/http.ts
|
|
598
392
|
var import_node_fs2 = require("fs");
|
|
@@ -619,10 +413,10 @@ var SDK_RELEASE = {
|
|
|
619
413
|
// 0.1.108 ships explicit dataset column/tool recompute policy and removes
|
|
620
414
|
// the SDK enrich generator's one-second stale policy.
|
|
621
415
|
// 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
|
|
622
|
-
version: "0.1.
|
|
416
|
+
version: "0.1.140",
|
|
623
417
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
624
418
|
supportPolicy: {
|
|
625
|
-
latest: "0.1.
|
|
419
|
+
latest: "0.1.140",
|
|
626
420
|
minimumSupported: "0.1.53",
|
|
627
421
|
deprecatedBelow: "0.1.53",
|
|
628
422
|
commandMinimumSupported: [
|
|
@@ -713,7 +507,7 @@ function normalizeAgentRuntime(value) {
|
|
|
713
507
|
if (explicit === "gemini_cli") return "gemini";
|
|
714
508
|
return EXPLICIT_AGENT_RUNTIMES.has(explicit) ? explicit : null;
|
|
715
509
|
}
|
|
716
|
-
function
|
|
510
|
+
function isCoworkLikeSandbox() {
|
|
717
511
|
const pluginMode = truthyEnv("DEEPLINE_PLUGIN_MODE");
|
|
718
512
|
const claudeRemote = truthyEnv("CLAUDE_CODE_REMOTE");
|
|
719
513
|
const projectDir = Boolean(process.env.CLAUDE_PROJECT_DIR?.trim());
|
|
@@ -726,7 +520,7 @@ function detectAgentRuntime(options = {}) {
|
|
|
726
520
|
const explicit = normalizeAgentRuntime(process.env.DEEPLINE_AGENT_RUNTIME);
|
|
727
521
|
if (explicit) return explicit;
|
|
728
522
|
if (process.env.CODEX_THREAD_ID?.trim()) return "codex";
|
|
729
|
-
if (options.detectCowork !== false &&
|
|
523
|
+
if (options.detectCowork !== false && isCoworkLikeSandbox()) {
|
|
730
524
|
return "claude_cowork";
|
|
731
525
|
}
|
|
732
526
|
if (process.env.CLAUDECODE?.trim() === "1") return "claude_code";
|
|
@@ -1192,7 +986,7 @@ function sleep(ms) {
|
|
|
1192
986
|
return new Promise((resolve13) => setTimeout(resolve13, ms));
|
|
1193
987
|
}
|
|
1194
988
|
function withCoworkNetworkHint(message) {
|
|
1195
|
-
if (!
|
|
989
|
+
if (!isCoworkLikeSandbox() || message.includes(COWORK_NETWORK_HINT)) {
|
|
1196
990
|
return message;
|
|
1197
991
|
}
|
|
1198
992
|
return `${message}
|
|
@@ -15260,6 +15054,7 @@ function renderPlayStep(command, options) {
|
|
|
15260
15054
|
` const templateRow = __dlPrepareEnrichRow(row, [${alias}]);`,
|
|
15261
15055
|
...runIfLines,
|
|
15262
15056
|
` const payload = __dlTemplate(${payload}, templateRow) as Record<string, unknown>;`,
|
|
15057
|
+
` if (__dlShouldSkipBlankPlayPayload(payload)) return null;`,
|
|
15263
15058
|
` let result: unknown;`,
|
|
15264
15059
|
` try {`,
|
|
15265
15060
|
` result = await stepCtx.runPlay(${callId}, ${playRef}, payload, {`,
|
|
@@ -16193,6 +15988,17 @@ function helperSource() {
|
|
|
16193
15988
|
` return false;`,
|
|
16194
15989
|
`}`,
|
|
16195
15990
|
``,
|
|
15991
|
+
`function __dlPayloadHasMeaningfulValue(value: unknown): boolean {`,
|
|
15992
|
+
` if (__dlBlankPayloadValue(value)) return false;`,
|
|
15993
|
+
` if (Array.isArray(value)) return value.some(__dlPayloadHasMeaningfulValue);`,
|
|
15994
|
+
` if (value && typeof value === 'object') return Object.values(value as Record<string, unknown>).some(__dlPayloadHasMeaningfulValue);`,
|
|
15995
|
+
` return true;`,
|
|
15996
|
+
`}`,
|
|
15997
|
+
``,
|
|
15998
|
+
`function __dlShouldSkipBlankPlayPayload(payload: Record<string, unknown>): boolean {`,
|
|
15999
|
+
` return Object.keys(payload).length > 0 && !__dlPayloadHasMeaningfulValue(payload);`,
|
|
16000
|
+
`}`,
|
|
16001
|
+
``,
|
|
16196
16002
|
`function __dlAliasCandidates(alias: string): string[] {`,
|
|
16197
16003
|
` const aliases: string[] = [];`,
|
|
16198
16004
|
` for (const candidate of [alias, alias.replace(/-/g, '_'), alias.replace(/_/g, '-')]) {`,
|
|
@@ -18671,15 +18477,6 @@ Examples:
|
|
|
18671
18477
|
async function fetchOrganizations(http, apiKey) {
|
|
18672
18478
|
return http.post("/api/v2/auth/cli/organizations", { api_key: apiKey });
|
|
18673
18479
|
}
|
|
18674
|
-
function normalizeAuthScope(value) {
|
|
18675
|
-
if (!value) return "auto";
|
|
18676
|
-
if (value === "auto" || value === "folder" || value === "global") {
|
|
18677
|
-
return value;
|
|
18678
|
-
}
|
|
18679
|
-
throw new Error(
|
|
18680
|
-
`Invalid --auth-scope "${value}". Expected one of: auto, folder, global.`
|
|
18681
|
-
);
|
|
18682
|
-
}
|
|
18683
18480
|
function orgListLines(orgs) {
|
|
18684
18481
|
return orgs.map((org, index) => {
|
|
18685
18482
|
const current = org.is_current ? " (current)" : "";
|
|
@@ -18687,90 +18484,6 @@ function orgListLines(orgs) {
|
|
|
18687
18484
|
return `${index + 1}. ${org.name}${role}${current}`;
|
|
18688
18485
|
});
|
|
18689
18486
|
}
|
|
18690
|
-
function redactApiKey(value) {
|
|
18691
|
-
if (!value) return null;
|
|
18692
|
-
if (value.length <= 10) return `${value.slice(0, 3)}...`;
|
|
18693
|
-
return `${value.slice(0, 8)}...${value.slice(-4)}`;
|
|
18694
|
-
}
|
|
18695
|
-
function processEnvValue(name) {
|
|
18696
|
-
return process.env[name]?.trim() ?? "";
|
|
18697
|
-
}
|
|
18698
|
-
function resolveOrgSwitchAuthTarget(scope, config) {
|
|
18699
|
-
const activeProject = getResolvedProjectAuthSource(
|
|
18700
|
-
config.baseUrl,
|
|
18701
|
-
config.apiKey
|
|
18702
|
-
);
|
|
18703
|
-
const folderTarget = resolveProjectPinTarget();
|
|
18704
|
-
const globalOverrideWarning = activeProject && scope === "global" ? [
|
|
18705
|
-
`Folder auth in ${activeProject.filePath} overrides global auth for commands run here.`
|
|
18706
|
-
] : [];
|
|
18707
|
-
if (scope === "folder") {
|
|
18708
|
-
if (!folderTarget.ok) {
|
|
18709
|
-
throw new Error(
|
|
18710
|
-
`Cowork project folder is ambiguous. Candidate folders: ${folderTarget.candidates.join(
|
|
18711
|
-
", "
|
|
18712
|
-
)}. Set CLAUDE_PROJECT_DIR or cd into the intended project folder before running this command.`
|
|
18713
|
-
);
|
|
18714
|
-
}
|
|
18715
|
-
return {
|
|
18716
|
-
kind: "folder",
|
|
18717
|
-
requested_scope: scope,
|
|
18718
|
-
effective_scope: "folder",
|
|
18719
|
-
reason: "explicit_folder",
|
|
18720
|
-
source: folderTarget.source,
|
|
18721
|
-
warnings: []
|
|
18722
|
-
};
|
|
18723
|
-
}
|
|
18724
|
-
if (scope === "global") {
|
|
18725
|
-
return {
|
|
18726
|
-
kind: "global",
|
|
18727
|
-
requested_scope: scope,
|
|
18728
|
-
effective_scope: "global",
|
|
18729
|
-
reason: "explicit_global",
|
|
18730
|
-
warnings: globalOverrideWarning
|
|
18731
|
-
};
|
|
18732
|
-
}
|
|
18733
|
-
if (activeProject) {
|
|
18734
|
-
return {
|
|
18735
|
-
kind: "folder",
|
|
18736
|
-
requested_scope: scope,
|
|
18737
|
-
effective_scope: "folder",
|
|
18738
|
-
reason: "existing_folder_auth",
|
|
18739
|
-
source: activeProject.source,
|
|
18740
|
-
warnings: []
|
|
18741
|
-
};
|
|
18742
|
-
}
|
|
18743
|
-
if (folderTarget.ok && folderTarget.source === "cowork") {
|
|
18744
|
-
return {
|
|
18745
|
-
kind: "folder",
|
|
18746
|
-
requested_scope: scope,
|
|
18747
|
-
effective_scope: "folder",
|
|
18748
|
-
reason: "detected_cowork_project",
|
|
18749
|
-
source: "cowork",
|
|
18750
|
-
warnings: []
|
|
18751
|
-
};
|
|
18752
|
-
}
|
|
18753
|
-
if (!folderTarget.ok) {
|
|
18754
|
-
return {
|
|
18755
|
-
kind: "global",
|
|
18756
|
-
requested_scope: scope,
|
|
18757
|
-
effective_scope: "global",
|
|
18758
|
-
reason: "ambiguous_cowork_fell_back_global",
|
|
18759
|
-
warnings: [
|
|
18760
|
-
`Cowork project folder is ambiguous, so global auth was updated. Candidate folders: ${folderTarget.candidates.join(
|
|
18761
|
-
", "
|
|
18762
|
-
)}. Set CLAUDE_PROJECT_DIR or cd into the intended project folder to update folder auth.`
|
|
18763
|
-
]
|
|
18764
|
-
};
|
|
18765
|
-
}
|
|
18766
|
-
return {
|
|
18767
|
-
kind: "global",
|
|
18768
|
-
requested_scope: scope,
|
|
18769
|
-
effective_scope: "global",
|
|
18770
|
-
reason: "default_global",
|
|
18771
|
-
warnings: []
|
|
18772
|
-
};
|
|
18773
|
-
}
|
|
18774
18487
|
async function handleOrgList(options) {
|
|
18775
18488
|
const config = resolveConfig();
|
|
18776
18489
|
const http = new HttpClient(config);
|
|
@@ -18790,89 +18503,7 @@ async function handleOrgList(options) {
|
|
|
18790
18503
|
{ json: options.json }
|
|
18791
18504
|
);
|
|
18792
18505
|
}
|
|
18793
|
-
async function handleOrgStatus(options) {
|
|
18794
|
-
const config = resolveConfig();
|
|
18795
|
-
const http = new HttpClient(config);
|
|
18796
|
-
const payload = await fetchOrganizations(http, config.apiKey);
|
|
18797
|
-
const current = payload.organizations.find((org) => org.is_current) ?? payload.organizations.find((org) => org.org_id === payload.current_org_id) ?? null;
|
|
18798
|
-
const projectCandidate = getActiveProjectAuthSource();
|
|
18799
|
-
const activeProject = getResolvedProjectAuthSource(
|
|
18800
|
-
config.baseUrl,
|
|
18801
|
-
config.apiKey
|
|
18802
|
-
);
|
|
18803
|
-
const folderTarget = resolveProjectPinTarget();
|
|
18804
|
-
const hostPath = hostEnvFilePath(config.baseUrl);
|
|
18805
|
-
const envApiKey = processEnvValue(API_KEY_ENV);
|
|
18806
|
-
const envHostUrl = processEnvValue(HOST_URL_ENV);
|
|
18807
|
-
const authSource = envApiKey ? {
|
|
18808
|
-
scope: "env",
|
|
18809
|
-
source: "process",
|
|
18810
|
-
path: null,
|
|
18811
|
-
api_key: redactApiKey(envApiKey),
|
|
18812
|
-
host: envHostUrl || null,
|
|
18813
|
-
overrides_global: true,
|
|
18814
|
-
overrides_folder: Boolean(projectCandidate)
|
|
18815
|
-
} : activeProject ? {
|
|
18816
|
-
scope: "folder",
|
|
18817
|
-
source: activeProject.source,
|
|
18818
|
-
path: activeProject.filePath,
|
|
18819
|
-
api_key: redactApiKey(activeProject.env.DEEPLINE_API_KEY),
|
|
18820
|
-
overrides_global: true
|
|
18821
|
-
} : {
|
|
18822
|
-
scope: "global",
|
|
18823
|
-
source: "host",
|
|
18824
|
-
path: hostPath,
|
|
18825
|
-
api_key: redactApiKey(config.apiKey),
|
|
18826
|
-
overrides_global: false
|
|
18827
|
-
};
|
|
18828
|
-
const folderTargetPayload = folderTarget.ok ? {
|
|
18829
|
-
ok: true,
|
|
18830
|
-
source: folderTarget.source,
|
|
18831
|
-
dir: folderTarget.dir,
|
|
18832
|
-
env_path: `${folderTarget.dir}/.env.deepline`
|
|
18833
|
-
} : {
|
|
18834
|
-
ok: false,
|
|
18835
|
-
reason: folderTarget.reason,
|
|
18836
|
-
candidates: folderTarget.candidates
|
|
18837
|
-
};
|
|
18838
|
-
const lines = [
|
|
18839
|
-
`Organization: ${current?.name ?? "(unknown)"}`,
|
|
18840
|
-
`Host: ${config.baseUrl}`,
|
|
18841
|
-
`Auth scope: ${authSource.scope}`
|
|
18842
|
-
];
|
|
18843
|
-
if (authSource.path) {
|
|
18844
|
-
lines.push(`Auth file: ${authSource.path}`);
|
|
18845
|
-
} else {
|
|
18846
|
-
lines.push(`Auth source: ${API_KEY_ENV} process environment`);
|
|
18847
|
-
}
|
|
18848
|
-
if (envApiKey) {
|
|
18849
|
-
lines.push(`${API_KEY_ENV} overrides saved auth for this process.`);
|
|
18850
|
-
} else if (activeProject) {
|
|
18851
|
-
lines.push("Global auth is overridden in this folder.");
|
|
18852
|
-
}
|
|
18853
|
-
printCommandEnvelope(
|
|
18854
|
-
{
|
|
18855
|
-
ok: true,
|
|
18856
|
-
host: config.baseUrl,
|
|
18857
|
-
organization: current,
|
|
18858
|
-
current_org_id: payload.current_org_id,
|
|
18859
|
-
auth_source: authSource,
|
|
18860
|
-
host_env_path: hostPath,
|
|
18861
|
-
folder_target: folderTargetPayload,
|
|
18862
|
-
next: {
|
|
18863
|
-
set_auto: "deepline org set <org>",
|
|
18864
|
-
set_folder: "deepline org set <org> --auth-scope folder",
|
|
18865
|
-
set_global: "deepline org set <org> --auth-scope global"
|
|
18866
|
-
},
|
|
18867
|
-
render: {
|
|
18868
|
-
sections: [{ title: "org status", lines }]
|
|
18869
|
-
}
|
|
18870
|
-
},
|
|
18871
|
-
{ json: options.json }
|
|
18872
|
-
);
|
|
18873
|
-
}
|
|
18874
18506
|
async function handleOrgSwitch(selection, options) {
|
|
18875
|
-
const authScope = normalizeAuthScope(options.authScope);
|
|
18876
18507
|
const config = resolveConfig();
|
|
18877
18508
|
const http = new HttpClient(config);
|
|
18878
18509
|
const payload = await fetchOrganizations(http, config.apiKey);
|
|
@@ -18880,10 +18511,7 @@ async function handleOrgSwitch(selection, options) {
|
|
|
18880
18511
|
printCommandEnvelope(
|
|
18881
18512
|
{
|
|
18882
18513
|
...payload,
|
|
18883
|
-
next: {
|
|
18884
|
-
deprecated_command: options.deprecatedSwitch ? "org switch" : null,
|
|
18885
|
-
replacement_command: options.deprecatedSwitch ? "deepline org set" : null,
|
|
18886
|
-
warnings: options.deprecatedSwitch ? ["org switch is deprecated; use org set."] : [],
|
|
18514
|
+
next: { switch: "deepline org switch <number>" },
|
|
18887
18515
|
render: {
|
|
18888
18516
|
sections: [
|
|
18889
18517
|
{
|
|
@@ -18891,7 +18519,7 @@ async function handleOrgSwitch(selection, options) {
|
|
|
18891
18519
|
lines: orgListLines(payload.organizations)
|
|
18892
18520
|
}
|
|
18893
18521
|
],
|
|
18894
|
-
actions: [{ label: "Run", command: "deepline org
|
|
18522
|
+
actions: [{ label: "Run", command: "deepline org switch <number>" }]
|
|
18895
18523
|
}
|
|
18896
18524
|
},
|
|
18897
18525
|
{ json: options.json }
|
|
@@ -18914,56 +18542,16 @@ async function handleOrgSwitch(selection, options) {
|
|
|
18914
18542
|
if (!target) {
|
|
18915
18543
|
throw new Error("Could not resolve the selected organization.");
|
|
18916
18544
|
}
|
|
18917
|
-
const authTarget = resolveOrgSwitchAuthTarget(authScope, config);
|
|
18918
18545
|
if (target.is_current) {
|
|
18919
|
-
let project_env_paths2 = [];
|
|
18920
|
-
if (authTarget.kind === "folder") {
|
|
18921
|
-
project_env_paths2 = saveProjectDeeplineEnvValues({
|
|
18922
|
-
DEEPLINE_HOST_URL: config.baseUrl,
|
|
18923
|
-
DEEPLINE_API_KEY: config.apiKey
|
|
18924
|
-
});
|
|
18925
|
-
} else {
|
|
18926
|
-
saveHostEnvValues(config.baseUrl, {
|
|
18927
|
-
DEEPLINE_HOST_URL: config.baseUrl,
|
|
18928
|
-
DEEPLINE_API_KEY: config.apiKey
|
|
18929
|
-
});
|
|
18930
|
-
}
|
|
18931
|
-
const renderLines2 = [`Already on ${target.name}.`];
|
|
18932
|
-
for (const projectPath of project_env_paths2) {
|
|
18933
|
-
renderLines2.push(`Saved folder auth in ${projectPath}`);
|
|
18934
|
-
}
|
|
18935
|
-
if (authTarget.kind === "global") {
|
|
18936
|
-
renderLines2.push(`Saved global auth in ${hostEnvFilePath(config.baseUrl)}`);
|
|
18937
|
-
}
|
|
18938
|
-
renderLines2.push(
|
|
18939
|
-
`Scope: ${authTarget.requested_scope} -> ${authTarget.effective_scope} (${authTarget.reason})`
|
|
18940
|
-
);
|
|
18941
|
-
if (options.deprecatedSwitch) {
|
|
18942
|
-
renderLines2.push("Warning: org switch is deprecated; use org set.");
|
|
18943
|
-
}
|
|
18944
|
-
for (const warning of authTarget.warnings) {
|
|
18945
|
-
renderLines2.push(`Warning: ${warning}`);
|
|
18946
|
-
}
|
|
18947
|
-
const warnings2 = [
|
|
18948
|
-
...options.deprecatedSwitch ? ["org switch is deprecated; use org set."] : [],
|
|
18949
|
-
...authTarget.warnings
|
|
18950
|
-
];
|
|
18951
18546
|
printCommandEnvelope(
|
|
18952
18547
|
{
|
|
18953
18548
|
ok: true,
|
|
18954
18549
|
unchanged: true,
|
|
18955
18550
|
organization: target,
|
|
18956
|
-
requested_auth_scope: authTarget.requested_scope,
|
|
18957
|
-
effective_auth_scope: authTarget.effective_scope,
|
|
18958
|
-
auth_scope_reason: authTarget.reason,
|
|
18959
|
-
auth_scope: authTarget.effective_scope,
|
|
18960
|
-
host_env_path: authTarget.kind === "global" ? hostEnvFilePath(config.baseUrl) : null,
|
|
18961
|
-
project_env_paths: project_env_paths2,
|
|
18962
|
-
deprecated_command: options.deprecatedSwitch ? "org switch" : null,
|
|
18963
|
-
replacement_command: options.deprecatedSwitch ? "deepline org set" : null,
|
|
18964
|
-
warnings: warnings2,
|
|
18965
18551
|
render: {
|
|
18966
|
-
sections: [
|
|
18552
|
+
sections: [
|
|
18553
|
+
{ title: "org switch", lines: [`Already on ${target.name}.`] }
|
|
18554
|
+
]
|
|
18967
18555
|
}
|
|
18968
18556
|
},
|
|
18969
18557
|
{ json: options.json }
|
|
@@ -18974,61 +18562,26 @@ async function handleOrgSwitch(selection, options) {
|
|
|
18974
18562
|
api_key: config.apiKey,
|
|
18975
18563
|
org_id: target.org_id
|
|
18976
18564
|
});
|
|
18977
|
-
|
|
18978
|
-
|
|
18979
|
-
|
|
18980
|
-
|
|
18981
|
-
|
|
18982
|
-
});
|
|
18983
|
-
} else {
|
|
18984
|
-
saveHostEnvValues(config.baseUrl, {
|
|
18985
|
-
DEEPLINE_HOST_URL: config.baseUrl,
|
|
18986
|
-
DEEPLINE_API_KEY: switched.api_key,
|
|
18987
|
-
DEEPLINE_ACTIVE_ORG_ID: switched.org_id,
|
|
18988
|
-
DEEPLINE_ACTIVE_ORG_NAME: switched.org_name
|
|
18989
|
-
});
|
|
18990
|
-
}
|
|
18565
|
+
saveHostEnvValues(config.baseUrl, {
|
|
18566
|
+
DEEPLINE_API_KEY: switched.api_key,
|
|
18567
|
+
DEEPLINE_ACTIVE_ORG_ID: switched.org_id,
|
|
18568
|
+
DEEPLINE_ACTIVE_ORG_NAME: switched.org_name
|
|
18569
|
+
});
|
|
18991
18570
|
const { api_key: _apiKey, ...publicSwitched } = switched;
|
|
18992
|
-
const renderLines = [`Switched to ${switched.org_name}.`];
|
|
18993
|
-
if (authTarget.kind === "folder") {
|
|
18994
|
-
for (const projectPath of project_env_paths) {
|
|
18995
|
-
renderLines.push(`Saved folder auth in ${projectPath}`);
|
|
18996
|
-
}
|
|
18997
|
-
} else {
|
|
18998
|
-
renderLines.push(`Saved global auth in ${hostEnvFilePath(config.baseUrl)}`);
|
|
18999
|
-
}
|
|
19000
|
-
renderLines.push(
|
|
19001
|
-
`Scope: ${authTarget.requested_scope} -> ${authTarget.effective_scope} (${authTarget.reason})`
|
|
19002
|
-
);
|
|
19003
|
-
if (options.deprecatedSwitch) {
|
|
19004
|
-
renderLines.push("Warning: org switch is deprecated; use org set.");
|
|
19005
|
-
}
|
|
19006
|
-
for (const warning of authTarget.warnings) {
|
|
19007
|
-
renderLines.push(`Warning: ${warning}`);
|
|
19008
|
-
}
|
|
19009
|
-
const warnings = [
|
|
19010
|
-
...options.deprecatedSwitch ? ["org switch is deprecated; use org set."] : [],
|
|
19011
|
-
...authTarget.warnings
|
|
19012
|
-
];
|
|
19013
18571
|
printCommandEnvelope(
|
|
19014
18572
|
{
|
|
19015
18573
|
ok: true,
|
|
19016
|
-
host_env_path:
|
|
19017
|
-
project_env_paths,
|
|
18574
|
+
host_env_path: hostEnvFilePath(config.baseUrl),
|
|
19018
18575
|
...publicSwitched,
|
|
19019
18576
|
api_key_saved: true,
|
|
19020
|
-
requested_auth_scope: authTarget.requested_scope,
|
|
19021
|
-
effective_auth_scope: authTarget.effective_scope,
|
|
19022
|
-
auth_scope_reason: authTarget.reason,
|
|
19023
|
-
auth_scope: authTarget.effective_scope,
|
|
19024
|
-
deprecated_command: options.deprecatedSwitch ? "org switch" : null,
|
|
19025
|
-
replacement_command: options.deprecatedSwitch ? "deepline org set" : null,
|
|
19026
|
-
warnings,
|
|
19027
18577
|
render: {
|
|
19028
18578
|
sections: [
|
|
19029
18579
|
{
|
|
19030
|
-
title: "org
|
|
19031
|
-
lines:
|
|
18580
|
+
title: "org switch",
|
|
18581
|
+
lines: [
|
|
18582
|
+
`Switched to ${switched.org_name}.`,
|
|
18583
|
+
`Saved host auth in ${hostEnvFilePath(config.baseUrl)}`
|
|
18584
|
+
]
|
|
19032
18585
|
}
|
|
19033
18586
|
]
|
|
19034
18587
|
}
|
|
@@ -19044,7 +18597,6 @@ async function handleOrgCreate(name, options) {
|
|
|
19044
18597
|
name
|
|
19045
18598
|
});
|
|
19046
18599
|
saveHostEnvValues(config.baseUrl, {
|
|
19047
|
-
DEEPLINE_HOST_URL: config.baseUrl,
|
|
19048
18600
|
DEEPLINE_API_KEY: created.api_key,
|
|
19049
18601
|
DEEPLINE_ACTIVE_ORG_ID: created.org_id,
|
|
19050
18602
|
DEEPLINE_ACTIVE_ORG_NAME: created.org_name
|
|
@@ -19074,20 +18626,18 @@ async function handleOrgCreate(name, options) {
|
|
|
19074
18626
|
);
|
|
19075
18627
|
}
|
|
19076
18628
|
function registerOrgCommands(program) {
|
|
19077
|
-
const org = program.command("org").description("List, create, and
|
|
18629
|
+
const org = program.command("org").description("List, create, and switch organizations.").addHelpText(
|
|
19078
18630
|
"after",
|
|
19079
18631
|
`
|
|
19080
18632
|
Notes:
|
|
19081
|
-
Organizations are workspaces.
|
|
19082
|
-
|
|
18633
|
+
Organizations are workspaces. Switching organizations mutates the saved host
|
|
18634
|
+
auth file so later CLI commands target the selected workspace.
|
|
19083
18635
|
|
|
19084
18636
|
Examples:
|
|
19085
18637
|
deepline org list --json
|
|
19086
|
-
deepline org status --json
|
|
19087
18638
|
deepline org create Acme --json
|
|
19088
|
-
deepline org
|
|
19089
|
-
deepline org
|
|
19090
|
-
deepline org set --org-id org_123 --json
|
|
18639
|
+
deepline org switch 2
|
|
18640
|
+
deepline org switch --org-id org_123 --json
|
|
19091
18641
|
`
|
|
19092
18642
|
);
|
|
19093
18643
|
org.command("list").description("List your organizations.").addHelpText(
|
|
@@ -19114,65 +18664,21 @@ Examples:
|
|
|
19114
18664
|
deepline org create "Acme Sales" --json
|
|
19115
18665
|
`
|
|
19116
18666
|
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgCreate);
|
|
19117
|
-
org.command("
|
|
18667
|
+
org.command("switch [selection]").description(
|
|
18668
|
+
"Switch to another organization and save the new API key in the host auth file."
|
|
18669
|
+
).addHelpText(
|
|
19118
18670
|
"after",
|
|
19119
18671
|
`
|
|
19120
18672
|
Notes:
|
|
19121
|
-
|
|
19122
|
-
|
|
19123
|
-
|
|
19124
|
-
Examples:
|
|
19125
|
-
deepline org status
|
|
19126
|
-
deepline org status --json
|
|
19127
|
-
`
|
|
19128
|
-
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgStatus);
|
|
19129
|
-
const addOrgSetOptions = (command) => command.option("--org-id <id>", "Set using an explicit organization id").option(
|
|
19130
|
-
"--auth-scope <scope>",
|
|
19131
|
-
"Where to save auth: auto, folder, or global",
|
|
19132
|
-
"auto"
|
|
19133
|
-
).option("--json", "Emit JSON output. Also automatic when stdout is piped");
|
|
19134
|
-
addOrgSetOptions(
|
|
19135
|
-
org.command("set [selection]").description("Set the organization for the selected auth scope.").addHelpText(
|
|
19136
|
-
"after",
|
|
19137
|
-
`
|
|
19138
|
-
Notes:
|
|
19139
|
-
Selection can be a list number, exact organization name, or organization id.
|
|
19140
|
-
Without a selection, prints choices. The default --auth-scope auto updates
|
|
19141
|
-
the folder auth file when one controls this command, updates the detected
|
|
19142
|
-
Cowork project folder when present, and otherwise updates global host auth.
|
|
19143
|
-
|
|
19144
|
-
Examples:
|
|
19145
|
-
deepline org set
|
|
19146
|
-
deepline org set 2
|
|
19147
|
-
deepline org set 2 --auth-scope folder
|
|
19148
|
-
deepline org set 2 --auth-scope global
|
|
19149
|
-
deepline org set --org-id org_123 --json
|
|
19150
|
-
`
|
|
19151
|
-
)
|
|
19152
|
-
).action(handleOrgSwitch);
|
|
19153
|
-
addOrgSetOptions(
|
|
19154
|
-
org.command("switch [selection]").description(
|
|
19155
|
-
"Deprecated alias for org set. Set the organization for the selected auth scope."
|
|
19156
|
-
).addHelpText(
|
|
19157
|
-
"after",
|
|
19158
|
-
`
|
|
19159
|
-
Notes:
|
|
19160
|
-
Deprecated alias. Use deepline org set instead. The default --auth-scope auto
|
|
19161
|
-
updates the folder auth file when one controls this command, updates the
|
|
19162
|
-
detected Cowork project folder when present, and otherwise updates global host
|
|
19163
|
-
auth.
|
|
18673
|
+
Mutates the saved host auth file. Selection can be a list number, exact
|
|
18674
|
+
organization name, or organization id. Without a selection, prints choices.
|
|
19164
18675
|
|
|
19165
18676
|
Examples:
|
|
19166
18677
|
deepline org switch
|
|
19167
18678
|
deepline org switch 2
|
|
19168
|
-
deepline org switch 2 --auth-scope folder
|
|
19169
|
-
deepline org switch 2 --auth-scope global
|
|
19170
18679
|
deepline org switch --org-id org_123 --json
|
|
19171
18680
|
`
|
|
19172
|
-
|
|
19173
|
-
).action(
|
|
19174
|
-
(selection, options) => handleOrgSwitch(selection, { ...options, deprecatedSwitch: true })
|
|
19175
|
-
);
|
|
18681
|
+
).option("--org-id <id>", "Switch using an explicit organization id").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgSwitch);
|
|
19176
18682
|
}
|
|
19177
18683
|
|
|
19178
18684
|
// src/cli/commands/quickstart.ts
|
|
@@ -22125,6 +21631,34 @@ async function fetchV1SkillNames(baseUrl) {
|
|
|
22125
21631
|
function buildSdkSkillNames(v1SkillNames) {
|
|
22126
21632
|
return sortedUniqueSkillNames(v1SkillNames);
|
|
22127
21633
|
}
|
|
21634
|
+
async function fetchSkillsUpdate(baseUrl, localVersion) {
|
|
21635
|
+
const controller = new AbortController();
|
|
21636
|
+
const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
|
|
21637
|
+
try {
|
|
21638
|
+
const response = await fetch(new URL("/api/v2/cli/update-check", baseUrl), {
|
|
21639
|
+
method: "POST",
|
|
21640
|
+
headers: { "Content-Type": "application/json" },
|
|
21641
|
+
body: JSON.stringify({
|
|
21642
|
+
skills: {
|
|
21643
|
+
version: localVersion
|
|
21644
|
+
}
|
|
21645
|
+
}),
|
|
21646
|
+
signal: controller.signal
|
|
21647
|
+
});
|
|
21648
|
+
if (!response.ok) return null;
|
|
21649
|
+
const data = await response.json().catch(() => null);
|
|
21650
|
+
const skills = data?.skills;
|
|
21651
|
+
if (!skills) return null;
|
|
21652
|
+
return {
|
|
21653
|
+
needsUpdate: skills.needs_update === true,
|
|
21654
|
+
remoteVersion: typeof skills.remote?.version === "string" ? skills.remote.version.trim() : ""
|
|
21655
|
+
};
|
|
21656
|
+
} catch {
|
|
21657
|
+
return null;
|
|
21658
|
+
} finally {
|
|
21659
|
+
clearTimeout(timeout);
|
|
21660
|
+
}
|
|
21661
|
+
}
|
|
22128
21662
|
function buildSkillsInstallArgs(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
|
|
22129
21663
|
return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames));
|
|
22130
21664
|
}
|
|
@@ -22265,12 +21799,6 @@ function writeSdkSkillsStatusLine(line) {
|
|
|
22265
21799
|
process.stderr.write(`${line}
|
|
22266
21800
|
`);
|
|
22267
21801
|
}
|
|
22268
|
-
function skillsStaleHintLine(update) {
|
|
22269
|
-
if (!update?.needs_update || !update.remote.version) {
|
|
22270
|
-
return null;
|
|
22271
|
-
}
|
|
22272
|
-
return "Deepline agent skills are out of date. Run `deepline update` to sync.";
|
|
22273
|
-
}
|
|
22274
21802
|
async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
|
|
22275
21803
|
if (attemptedSync || shouldSkipSkillsSync()) return;
|
|
22276
21804
|
attemptedSync = true;
|
|
@@ -22278,11 +21806,14 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
|
|
|
22278
21806
|
if (usingPluginSkills) {
|
|
22279
21807
|
return;
|
|
22280
21808
|
}
|
|
22281
|
-
const
|
|
22282
|
-
|
|
21809
|
+
const localVersion = readSdkSkillsLocalVersion(baseUrl);
|
|
21810
|
+
const update = options.update === void 0 ? await fetchSkillsUpdate(baseUrl, localVersion) : options.update ? {
|
|
21811
|
+
needsUpdate: options.update.needs_update,
|
|
21812
|
+
remoteVersion: options.update.remote.version
|
|
21813
|
+
} : null;
|
|
21814
|
+
if (!update?.needsUpdate || !update.remoteVersion) {
|
|
22283
21815
|
return;
|
|
22284
21816
|
}
|
|
22285
|
-
const remoteVersion = update.remote.version;
|
|
22286
21817
|
const remoteSkillNames = await fetchV1SkillNames(baseUrl);
|
|
22287
21818
|
const skillNames = buildSdkSkillNames(
|
|
22288
21819
|
remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
|
|
@@ -22292,17 +21823,11 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
|
|
|
22292
21823
|
const installed = await runSkillsInstall(baseUrl, skillNames);
|
|
22293
21824
|
if (!installed) return;
|
|
22294
21825
|
runLegacySkillsCleanup();
|
|
22295
|
-
writeLocalSkillsVersion(baseUrl, remoteVersion);
|
|
21826
|
+
writeLocalSkillsVersion(baseUrl, update.remoteVersion);
|
|
22296
21827
|
writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
|
|
22297
21828
|
}
|
|
22298
21829
|
|
|
22299
21830
|
// src/cli/commands/update.ts
|
|
22300
|
-
async function resolveSkillsVerdictFromCompat(baseUrl) {
|
|
22301
|
-
const { response } = await checkSdkCompatibility(baseUrl, {
|
|
22302
|
-
skillsVersion: readSdkSkillsLocalVersion(baseUrl)
|
|
22303
|
-
});
|
|
22304
|
-
return response?.skills ?? null;
|
|
22305
|
-
}
|
|
22306
21831
|
var NPM_SDK_INSTALL_COMMON_FLAGS = ["--no-audit", "--no-fund"];
|
|
22307
21832
|
var NPM_SDK_GLOBAL_INSTALL_FLAGS = [
|
|
22308
21833
|
"--no-audit",
|
|
@@ -22741,7 +22266,6 @@ async function runUpdateCommand(options, dependencies = {}) {
|
|
|
22741
22266
|
const detectBaseUrl = dependencies.detectBaseUrl ?? autoDetectBaseUrl;
|
|
22742
22267
|
const resolvePlan = dependencies.resolvePlan ?? resolveUpdatePlan;
|
|
22743
22268
|
const runPlan = dependencies.runPlan ?? runUpdatePlan;
|
|
22744
|
-
const resolveSkillsVerdict = dependencies.resolveSkillsVerdict ?? resolveSkillsVerdictFromCompat;
|
|
22745
22269
|
const syncSkills = dependencies.syncSkillsIfNeeded ?? syncSdkSkillsIfNeeded;
|
|
22746
22270
|
const stderr = dependencies.stderr ?? process.stderr;
|
|
22747
22271
|
const plan = resolvePlan();
|
|
@@ -22786,9 +22310,7 @@ async function runUpdateCommand(options, dependencies = {}) {
|
|
|
22786
22310
|
if (updateExitCode !== 0) {
|
|
22787
22311
|
return updateExitCode;
|
|
22788
22312
|
}
|
|
22789
|
-
|
|
22790
|
-
const skillsUpdate = await resolveSkillsVerdict(updatedBaseUrl);
|
|
22791
|
-
await syncSkills(updatedBaseUrl, { update: skillsUpdate });
|
|
22313
|
+
await syncSkills(normalizeBaseUrl3(detectBaseUrl()));
|
|
22792
22314
|
return 0;
|
|
22793
22315
|
}
|
|
22794
22316
|
function registerUpdateCommand(program) {
|
|
@@ -23505,7 +23027,7 @@ Exit codes:
|
|
|
23505
23027
|
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
23506
23028
|
const compatibilityCommand = compatibilityCommandPath(actionCommand) || actionCommand.name();
|
|
23507
23029
|
const shouldDeferSkillsSync = shouldDeferSkillsSyncForCommand();
|
|
23508
|
-
const skillsVersion = readSdkSkillsLocalVersion(baseUrl);
|
|
23030
|
+
const skillsVersion = shouldDeferSkillsSync ? void 0 : readSdkSkillsLocalVersion(baseUrl);
|
|
23509
23031
|
const compatibility = await traceCliSpan(
|
|
23510
23032
|
"cli.sdk_compatibility",
|
|
23511
23033
|
{
|
|
@@ -23541,14 +23063,8 @@ Exit codes:
|
|
|
23541
23063
|
if (printStartupPhase) {
|
|
23542
23064
|
progress?.phase("checking sdk skills");
|
|
23543
23065
|
}
|
|
23544
|
-
|
|
23545
|
-
|
|
23546
|
-
const hint = skillsStaleHintLine(skillsUpdate);
|
|
23547
|
-
if (hint && !process.argv.includes("--json")) {
|
|
23548
|
-
process.stderr.write(`${hint}
|
|
23549
|
-
`);
|
|
23550
|
-
}
|
|
23551
|
-
} else {
|
|
23066
|
+
if (!shouldDeferSkillsSync) {
|
|
23067
|
+
const skillsUpdate = compatibility.response && Object.prototype.hasOwnProperty.call(compatibility.response, "skills") ? compatibility.response.skills ?? null : void 0;
|
|
23552
23068
|
await traceCliSpan(
|
|
23553
23069
|
"cli.sdk_skills_sync",
|
|
23554
23070
|
{ baseUrl },
|