deepline 0.1.142 → 0.1.144
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/entry.ts +4 -1
- package/dist/bundling-sources/sdk/src/config.ts +310 -13
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +4 -4
- package/dist/cli/index.js +596 -42
- package/dist/cli/index.mjs +620 -58
- package/dist/index.js +148 -14
- package/dist/index.mjs +157 -15
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -164,7 +164,15 @@ import { tmpdir as tmpdir4 } from "os";
|
|
|
164
164
|
import { Command as Command3 } from "commander";
|
|
165
165
|
|
|
166
166
|
// src/config.ts
|
|
167
|
-
import {
|
|
167
|
+
import {
|
|
168
|
+
existsSync,
|
|
169
|
+
mkdirSync,
|
|
170
|
+
readdirSync,
|
|
171
|
+
realpathSync,
|
|
172
|
+
readFileSync,
|
|
173
|
+
statSync,
|
|
174
|
+
writeFileSync
|
|
175
|
+
} from "fs";
|
|
168
176
|
import { homedir } from "os";
|
|
169
177
|
import { dirname, join, resolve } from "path";
|
|
170
178
|
|
|
@@ -214,6 +222,22 @@ var PROD_URL = "https://code.deepline.com";
|
|
|
214
222
|
var DEFAULT_TIMEOUT = 6e4;
|
|
215
223
|
var DEFAULT_MAX_RETRIES = 3;
|
|
216
224
|
var PROJECT_DEEPLINE_ENV_FILE = ".env.deepline";
|
|
225
|
+
var COWORK_IGNORED_WORKSPACE_DIRS = /* @__PURE__ */ new Set([
|
|
226
|
+
".auto-memory",
|
|
227
|
+
".claude",
|
|
228
|
+
".remote-plugins",
|
|
229
|
+
"outputs",
|
|
230
|
+
"plugins",
|
|
231
|
+
"uploads"
|
|
232
|
+
]);
|
|
233
|
+
var COWORK_PROJECT_MARKERS = [
|
|
234
|
+
".deepline",
|
|
235
|
+
".env.deepline",
|
|
236
|
+
".git",
|
|
237
|
+
"AGENTS.md",
|
|
238
|
+
"package.json",
|
|
239
|
+
"pyproject.toml"
|
|
240
|
+
];
|
|
217
241
|
function baseUrlSlug(baseUrl) {
|
|
218
242
|
let url;
|
|
219
243
|
try {
|
|
@@ -259,9 +283,124 @@ function findNearestEnvFile(name, startDir = process.cwd()) {
|
|
|
259
283
|
current = parent;
|
|
260
284
|
}
|
|
261
285
|
}
|
|
262
|
-
function
|
|
263
|
-
|
|
264
|
-
|
|
286
|
+
function isDirectory(path) {
|
|
287
|
+
try {
|
|
288
|
+
return statSync(path).isDirectory();
|
|
289
|
+
} catch {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function canonicalPath(path) {
|
|
294
|
+
try {
|
|
295
|
+
return realpathSync(path);
|
|
296
|
+
} catch {
|
|
297
|
+
return resolve(path);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function isTruthy(value) {
|
|
301
|
+
return /^(1|true|yes|on)$/i.test(value?.trim() ?? "");
|
|
302
|
+
}
|
|
303
|
+
function sessionRootFromPath(path) {
|
|
304
|
+
const trimmed = path?.trim();
|
|
305
|
+
if (!trimmed) return null;
|
|
306
|
+
const match = /^\/sessions\/[^/]+(?=\/|$)/.exec(trimmed);
|
|
307
|
+
return match?.[0] ?? null;
|
|
308
|
+
}
|
|
309
|
+
function coworkSessionRoot() {
|
|
310
|
+
const home = process.env.HOME?.trim();
|
|
311
|
+
const homeSessionRoot = sessionRootFromPath(home);
|
|
312
|
+
if (homeSessionRoot && isDirectory(join(homeSessionRoot, "mnt"))) {
|
|
313
|
+
return homeSessionRoot;
|
|
314
|
+
}
|
|
315
|
+
const cwdSessionRoot = sessionRootFromPath(process.cwd());
|
|
316
|
+
if (cwdSessionRoot && isDirectory(join(cwdSessionRoot, "mnt"))) {
|
|
317
|
+
return cwdSessionRoot;
|
|
318
|
+
}
|
|
319
|
+
if (isTruthy(process.env.CLAUDE_CODE_REMOTE) && home) {
|
|
320
|
+
const mountedRoot = join(home, "mnt");
|
|
321
|
+
if (isDirectory(mountedRoot)) return resolve(home);
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
function isCoworkLikeSandbox() {
|
|
326
|
+
const home = process.env.HOME?.trim();
|
|
327
|
+
return isTruthy(process.env.CLAUDE_CODE_REMOTE) || sessionRootFromPath(home) !== null || sessionRootFromPath(process.cwd()) !== null;
|
|
328
|
+
}
|
|
329
|
+
function coworkProjectScore(path) {
|
|
330
|
+
let score = 0;
|
|
331
|
+
for (const marker of COWORK_PROJECT_MARKERS) {
|
|
332
|
+
if (existsSync(join(path, marker))) score += 1;
|
|
333
|
+
}
|
|
334
|
+
return score;
|
|
335
|
+
}
|
|
336
|
+
function listCoworkWorkspaceDirCandidates() {
|
|
337
|
+
if (!isCoworkLikeSandbox()) {
|
|
338
|
+
return [];
|
|
339
|
+
}
|
|
340
|
+
const explicitProjectDir = process.env.CLAUDE_PROJECT_DIR?.trim();
|
|
341
|
+
if (explicitProjectDir && isDirectory(explicitProjectDir)) {
|
|
342
|
+
return [resolve(explicitProjectDir)];
|
|
343
|
+
}
|
|
344
|
+
const sessionRoot = coworkSessionRoot();
|
|
345
|
+
if (!sessionRoot) return [];
|
|
346
|
+
const mountedRoot = join(sessionRoot, "mnt");
|
|
347
|
+
if (!isDirectory(mountedRoot)) return [];
|
|
348
|
+
let names;
|
|
349
|
+
try {
|
|
350
|
+
names = readdirSync(mountedRoot).sort();
|
|
351
|
+
} catch {
|
|
352
|
+
return [];
|
|
353
|
+
}
|
|
354
|
+
const candidates = [];
|
|
355
|
+
for (const name of names) {
|
|
356
|
+
if (name.startsWith(".") || COWORK_IGNORED_WORKSPACE_DIRS.has(name)) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
const candidate = join(mountedRoot, name);
|
|
360
|
+
if (isDirectory(candidate)) candidates.push(candidate);
|
|
361
|
+
}
|
|
362
|
+
if (candidates.length <= 1) return candidates;
|
|
363
|
+
const projectLike = candidates.filter(
|
|
364
|
+
(candidate) => coworkProjectScore(candidate) > 0
|
|
365
|
+
);
|
|
366
|
+
return projectLike.length > 0 ? projectLike : candidates;
|
|
367
|
+
}
|
|
368
|
+
function isInIgnoredCoworkMount(path) {
|
|
369
|
+
const sessionRoot = coworkSessionRoot();
|
|
370
|
+
if (!sessionRoot) return false;
|
|
371
|
+
const mountedRoot = canonicalPath(join(sessionRoot, "mnt"));
|
|
372
|
+
const resolvedPath = canonicalPath(path);
|
|
373
|
+
const prefix = `${mountedRoot}/`;
|
|
374
|
+
if (!resolvedPath.startsWith(prefix)) return false;
|
|
375
|
+
const relativePath = resolvedPath.slice(prefix.length);
|
|
376
|
+
const mountName = relativePath.split("/")[0];
|
|
377
|
+
return mountName.startsWith(".") || COWORK_IGNORED_WORKSPACE_DIRS.has(mountName);
|
|
378
|
+
}
|
|
379
|
+
function detectCoworkWorkspaceDir() {
|
|
380
|
+
const candidates = listCoworkWorkspaceDirCandidates();
|
|
381
|
+
return candidates.length === 1 ? candidates[0] : null;
|
|
382
|
+
}
|
|
383
|
+
function loadProjectEnvCandidates(startDir = process.cwd()) {
|
|
384
|
+
const filePaths = [];
|
|
385
|
+
const sources = /* @__PURE__ */ new Map();
|
|
386
|
+
const nearestFile = findNearestEnvFile(PROJECT_DEEPLINE_ENV_FILE, startDir);
|
|
387
|
+
if (nearestFile && !isInIgnoredCoworkMount(nearestFile)) {
|
|
388
|
+
filePaths.push(nearestFile);
|
|
389
|
+
sources.set(resolve(nearestFile), "nearest");
|
|
390
|
+
}
|
|
391
|
+
const coworkWorkspaceDir = detectCoworkWorkspaceDir();
|
|
392
|
+
if (coworkWorkspaceDir) {
|
|
393
|
+
const coworkFile = join(coworkWorkspaceDir, PROJECT_DEEPLINE_ENV_FILE);
|
|
394
|
+
if (existsSync(coworkFile) && !filePaths.some((filePath) => resolve(filePath) === resolve(coworkFile))) {
|
|
395
|
+
filePaths.push(coworkFile);
|
|
396
|
+
sources.set(resolve(coworkFile), "cowork");
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return filePaths.map((filePath) => ({
|
|
400
|
+
filePath,
|
|
401
|
+
env: parseEnvFile(filePath),
|
|
402
|
+
source: sources.get(resolve(filePath)) ?? "nearest"
|
|
403
|
+
}));
|
|
265
404
|
}
|
|
266
405
|
function normalizeBaseUrl(baseUrl) {
|
|
267
406
|
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
@@ -325,23 +464,35 @@ function loadGlobalCliEnv() {
|
|
|
325
464
|
return loadCliEnv(PROD_URL);
|
|
326
465
|
}
|
|
327
466
|
function autoDetectBaseUrl() {
|
|
328
|
-
const
|
|
467
|
+
const projectEnvs = loadProjectEnvCandidates();
|
|
329
468
|
const globalEnv = loadGlobalCliEnv();
|
|
330
|
-
return normalizeBaseUrl(process.env[HOST_URL_ENV] ?? "") ||
|
|
469
|
+
return normalizeBaseUrl(process.env[HOST_URL_ENV] ?? "") || firstNonEmpty(
|
|
470
|
+
...projectEnvs.map(({ env }) => normalizeBaseUrl(env[HOST_URL_ENV]))
|
|
471
|
+
) || normalizeBaseUrl(globalEnv[HOST_URL_ENV] ?? "") || PROD_URL;
|
|
331
472
|
}
|
|
332
473
|
function resolveApiKeyForBaseUrl(baseUrl, explicitApiKey) {
|
|
333
474
|
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
334
|
-
const
|
|
475
|
+
const projectEnvs = loadProjectEnvCandidates();
|
|
335
476
|
const cliEnv = loadCliEnv(normalizedBaseUrl || baseUrl);
|
|
336
|
-
const projectBaseUrl = normalizeBaseUrl(projectEnv[HOST_URL_ENV] ?? "");
|
|
337
|
-
const projectKeyApplies = projectBaseUrl === normalizedBaseUrl;
|
|
338
477
|
return firstNonEmpty(
|
|
339
478
|
explicitApiKey,
|
|
340
479
|
process.env[API_KEY_ENV],
|
|
341
|
-
|
|
480
|
+
...projectEnvs.map(({ env }) => {
|
|
481
|
+
const projectBaseUrl = normalizeBaseUrl(env[HOST_URL_ENV] ?? "");
|
|
482
|
+
return projectBaseUrl === normalizedBaseUrl ? env[API_KEY_ENV] : "";
|
|
483
|
+
}),
|
|
342
484
|
cliEnv[API_KEY_ENV]
|
|
343
485
|
);
|
|
344
486
|
}
|
|
487
|
+
function getResolvedProjectAuthSource(baseUrl, apiKey, startDir = process.cwd()) {
|
|
488
|
+
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
489
|
+
const normalizedApiKey = apiKey.trim();
|
|
490
|
+
if (!normalizedBaseUrl || !normalizedApiKey) return null;
|
|
491
|
+
return loadProjectEnvCandidates(startDir).find(({ env }) => {
|
|
492
|
+
const projectBaseUrl = normalizeBaseUrl(env[HOST_URL_ENV] ?? "");
|
|
493
|
+
return projectBaseUrl === normalizedBaseUrl && (env[API_KEY_ENV] ?? "").trim() === normalizedApiKey;
|
|
494
|
+
}) ?? null;
|
|
495
|
+
}
|
|
345
496
|
function resolveConfig(options) {
|
|
346
497
|
const baseUrl = normalizeBaseUrl(
|
|
347
498
|
options?.baseUrl?.trim() || autoDetectBaseUrl()
|
|
@@ -364,6 +515,69 @@ function resolveConfig(options) {
|
|
|
364
515
|
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES
|
|
365
516
|
};
|
|
366
517
|
}
|
|
518
|
+
function mergeProjectEnvFile(filePath, values) {
|
|
519
|
+
const existing = parseEnvFile(filePath);
|
|
520
|
+
const merged = { ...existing, ...values };
|
|
521
|
+
const dir = dirname(filePath);
|
|
522
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
523
|
+
ensureProjectEnvIsIgnored(dir);
|
|
524
|
+
const allowedKeys = /* @__PURE__ */ new Set([HOST_URL_ENV, API_KEY_ENV]);
|
|
525
|
+
const lines = Object.entries(merged).filter(([key, value]) => allowedKeys.has(key) && value !== "").map(([key, value]) => `${key}=${value}`);
|
|
526
|
+
writeFileSync(filePath, `${lines.join("\n")}
|
|
527
|
+
`, "utf-8");
|
|
528
|
+
}
|
|
529
|
+
function ensureProjectEnvIsIgnored(dir) {
|
|
530
|
+
const gitignorePath = join(dir, ".gitignore");
|
|
531
|
+
const entry = PROJECT_DEEPLINE_ENV_FILE;
|
|
532
|
+
const existing = existsSync(gitignorePath) ? readFileSync(gitignorePath, "utf-8") : "";
|
|
533
|
+
const alreadyIgnored = existing.split(/\r?\n/).map((line) => line.trim()).some((line) => line === entry || line === `/${entry}`);
|
|
534
|
+
if (alreadyIgnored) return;
|
|
535
|
+
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
536
|
+
writeFileSync(gitignorePath, `${existing}${prefix}${entry}
|
|
537
|
+
`, "utf-8");
|
|
538
|
+
}
|
|
539
|
+
function saveProjectDeeplineEnvValues(values, startDir = process.cwd()) {
|
|
540
|
+
const target = resolveProjectPinTarget(startDir);
|
|
541
|
+
if (!target.ok) {
|
|
542
|
+
throw new ConfigError(
|
|
543
|
+
`Cowork project folder is ambiguous. Candidate folders: ${target.candidates.join(
|
|
544
|
+
", "
|
|
545
|
+
)}. Set CLAUDE_PROJECT_DIR or cd into the intended project folder before running this command.`
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
const filePath = join(target.dir, PROJECT_DEEPLINE_ENV_FILE);
|
|
549
|
+
mergeProjectEnvFile(filePath, values);
|
|
550
|
+
return [filePath];
|
|
551
|
+
}
|
|
552
|
+
function resolveProjectPinTarget(startDir = process.cwd()) {
|
|
553
|
+
const nearestFile = findNearestEnvFile(PROJECT_DEEPLINE_ENV_FILE, startDir);
|
|
554
|
+
if (nearestFile && !isInIgnoredCoworkMount(nearestFile)) {
|
|
555
|
+
return { ok: true, dir: dirname(nearestFile), source: "nearest" };
|
|
556
|
+
}
|
|
557
|
+
const coworkCandidates = listCoworkWorkspaceDirCandidates();
|
|
558
|
+
if (coworkCandidates.length === 1) {
|
|
559
|
+
return { ok: true, dir: coworkCandidates[0], source: "cowork" };
|
|
560
|
+
}
|
|
561
|
+
if (coworkCandidates.length > 1) {
|
|
562
|
+
const resolvedStartDir = canonicalPath(startDir);
|
|
563
|
+
const cwdCandidate = coworkCandidates.find((candidate) => {
|
|
564
|
+
const resolvedCandidate = canonicalPath(candidate);
|
|
565
|
+
return resolvedStartDir === resolvedCandidate || resolvedStartDir.startsWith(`${resolvedCandidate}/`);
|
|
566
|
+
});
|
|
567
|
+
if (cwdCandidate) {
|
|
568
|
+
return { ok: true, dir: cwdCandidate, source: "cowork" };
|
|
569
|
+
}
|
|
570
|
+
return {
|
|
571
|
+
ok: false,
|
|
572
|
+
reason: "ambiguous_cowork_project",
|
|
573
|
+
candidates: coworkCandidates
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
return { ok: true, dir: resolve(startDir), source: "cwd" };
|
|
577
|
+
}
|
|
578
|
+
function getActiveProjectAuthSource(startDir = process.cwd()) {
|
|
579
|
+
return loadProjectEnvCandidates(startDir)[0] ?? null;
|
|
580
|
+
}
|
|
367
581
|
|
|
368
582
|
// src/http.ts
|
|
369
583
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
@@ -390,10 +604,10 @@ var SDK_RELEASE = {
|
|
|
390
604
|
// 0.1.108 ships explicit dataset column/tool recompute policy and removes
|
|
391
605
|
// the SDK enrich generator's one-second stale policy.
|
|
392
606
|
// 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
|
|
393
|
-
version: "0.1.
|
|
607
|
+
version: "0.1.144",
|
|
394
608
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
395
609
|
supportPolicy: {
|
|
396
|
-
latest: "0.1.
|
|
610
|
+
latest: "0.1.144",
|
|
397
611
|
minimumSupported: "0.1.53",
|
|
398
612
|
deprecatedBelow: "0.1.53",
|
|
399
613
|
commandMinimumSupported: [
|
|
@@ -484,7 +698,7 @@ function normalizeAgentRuntime(value) {
|
|
|
484
698
|
if (explicit === "gemini_cli") return "gemini";
|
|
485
699
|
return EXPLICIT_AGENT_RUNTIMES.has(explicit) ? explicit : null;
|
|
486
700
|
}
|
|
487
|
-
function
|
|
701
|
+
function isCoworkLikeSandbox2() {
|
|
488
702
|
const pluginMode = truthyEnv("DEEPLINE_PLUGIN_MODE");
|
|
489
703
|
const claudeRemote = truthyEnv("CLAUDE_CODE_REMOTE");
|
|
490
704
|
const projectDir = Boolean(process.env.CLAUDE_PROJECT_DIR?.trim());
|
|
@@ -497,7 +711,7 @@ function detectAgentRuntime(options = {}) {
|
|
|
497
711
|
const explicit = normalizeAgentRuntime(process.env.DEEPLINE_AGENT_RUNTIME);
|
|
498
712
|
if (explicit) return explicit;
|
|
499
713
|
if (process.env.CODEX_THREAD_ID?.trim()) return "codex";
|
|
500
|
-
if (options.detectCowork !== false &&
|
|
714
|
+
if (options.detectCowork !== false && isCoworkLikeSandbox2()) {
|
|
501
715
|
return "claude_cowork";
|
|
502
716
|
}
|
|
503
717
|
if (process.env.CLAUDECODE?.trim() === "1") return "claude_code";
|
|
@@ -963,7 +1177,7 @@ function sleep(ms) {
|
|
|
963
1177
|
return new Promise((resolve13) => setTimeout(resolve13, ms));
|
|
964
1178
|
}
|
|
965
1179
|
function withCoworkNetworkHint(message) {
|
|
966
|
-
if (!
|
|
1180
|
+
if (!isCoworkLikeSandbox2() || message.includes(COWORK_NETWORK_HINT)) {
|
|
967
1181
|
return message;
|
|
968
1182
|
}
|
|
969
1183
|
return `${message}
|
|
@@ -7017,9 +7231,9 @@ import { createHash as createHash2 } from "crypto";
|
|
|
7017
7231
|
import {
|
|
7018
7232
|
existsSync as existsSync6,
|
|
7019
7233
|
readFileSync as readFileSync6,
|
|
7020
|
-
readdirSync,
|
|
7021
|
-
realpathSync,
|
|
7022
|
-
statSync as
|
|
7234
|
+
readdirSync as readdirSync2,
|
|
7235
|
+
realpathSync as realpathSync2,
|
|
7236
|
+
statSync as statSync3,
|
|
7023
7237
|
writeFileSync as writeFileSync8
|
|
7024
7238
|
} from "fs";
|
|
7025
7239
|
import { basename, dirname as dirname6, join as join5, resolve as resolve7 } from "path";
|
|
@@ -7030,7 +7244,7 @@ import {
|
|
|
7030
7244
|
closeSync,
|
|
7031
7245
|
openSync,
|
|
7032
7246
|
readSync,
|
|
7033
|
-
statSync,
|
|
7247
|
+
statSync as statSync2,
|
|
7034
7248
|
writeFileSync as writeFileSync7
|
|
7035
7249
|
} from "fs";
|
|
7036
7250
|
import { isAbsolute, relative, resolve as resolve6 } from "path";
|
|
@@ -7463,7 +7677,7 @@ function inferCsvColumnSpecs(headers, rows) {
|
|
|
7463
7677
|
}
|
|
7464
7678
|
function readCsvSample(csvPath) {
|
|
7465
7679
|
const resolvedPath = resolve6(csvPath);
|
|
7466
|
-
const size =
|
|
7680
|
+
const size = statSync2(resolvedPath).size;
|
|
7467
7681
|
const fd = openSync(resolvedPath, "r");
|
|
7468
7682
|
const byteLength = Math.min(size, CSV_HEADER_SAMPLE_BYTES);
|
|
7469
7683
|
const buffer = Buffer.alloc(byteLength);
|
|
@@ -9499,7 +9713,7 @@ function preflightLocalFileInputs(runtimeInput) {
|
|
|
9499
9713
|
}
|
|
9500
9714
|
let stat2;
|
|
9501
9715
|
try {
|
|
9502
|
-
stat2 =
|
|
9716
|
+
stat2 = statSync3(absolutePath);
|
|
9503
9717
|
} catch (error) {
|
|
9504
9718
|
throw new DeeplineError(
|
|
9505
9719
|
`Input ${ref.inputPath} references a local file that is not readable: ${ref.value} (${error instanceof Error ? error.message : String(error)}). No run was created.`,
|
|
@@ -9651,7 +9865,7 @@ function stageFile(logicalPath, absolutePath) {
|
|
|
9651
9865
|
}
|
|
9652
9866
|
function normalizePlayPath(filePath) {
|
|
9653
9867
|
try {
|
|
9654
|
-
return
|
|
9868
|
+
return realpathSync2.native(resolve7(filePath));
|
|
9655
9869
|
} catch {
|
|
9656
9870
|
return resolve7(filePath);
|
|
9657
9871
|
}
|
|
@@ -12913,7 +13127,7 @@ async function handlePlayRun(args) {
|
|
|
12913
13127
|
if (existsSync6(dir)) {
|
|
12914
13128
|
const base = basename(resolved);
|
|
12915
13129
|
try {
|
|
12916
|
-
const siblings =
|
|
13130
|
+
const siblings = readdirSync2(dir).filter(
|
|
12917
13131
|
(f) => f.includes(base.replace(/\.(play\.)?ts$/, "")) || f.endsWith(".play.ts")
|
|
12918
13132
|
);
|
|
12919
13133
|
if (siblings.length > 0) {
|
|
@@ -17718,9 +17932,9 @@ Examples:
|
|
|
17718
17932
|
import {
|
|
17719
17933
|
existsSync as existsSync7,
|
|
17720
17934
|
mkdirSync as mkdirSync5,
|
|
17721
|
-
readdirSync as
|
|
17935
|
+
readdirSync as readdirSync3,
|
|
17722
17936
|
readFileSync as readFileSync7,
|
|
17723
|
-
statSync as
|
|
17937
|
+
statSync as statSync4,
|
|
17724
17938
|
writeFileSync as writeFileSync9
|
|
17725
17939
|
} from "fs";
|
|
17726
17940
|
import { homedir as homedir7, platform } from "os";
|
|
@@ -17805,7 +18019,7 @@ function listSessionFiles(agent) {
|
|
|
17805
18019
|
}
|
|
17806
18020
|
function readDirectoryNames(dir) {
|
|
17807
18021
|
try {
|
|
17808
|
-
return
|
|
18022
|
+
return readdirSync3(dir);
|
|
17809
18023
|
} catch {
|
|
17810
18024
|
return [];
|
|
17811
18025
|
}
|
|
@@ -17816,7 +18030,7 @@ function listJsonlFilesRecursive(root, maxDepth) {
|
|
|
17816
18030
|
if (depth > maxDepth) return;
|
|
17817
18031
|
let entries;
|
|
17818
18032
|
try {
|
|
17819
|
-
entries =
|
|
18033
|
+
entries = readdirSync3(dir, { withFileTypes: true });
|
|
17820
18034
|
} catch {
|
|
17821
18035
|
return;
|
|
17822
18036
|
}
|
|
@@ -17834,7 +18048,7 @@ function listJsonlFilesRecursive(root, maxDepth) {
|
|
|
17834
18048
|
}
|
|
17835
18049
|
function statIfReadable(filePath) {
|
|
17836
18050
|
try {
|
|
17837
|
-
return
|
|
18051
|
+
return statSync4(filePath);
|
|
17838
18052
|
} catch {
|
|
17839
18053
|
return null;
|
|
17840
18054
|
}
|
|
@@ -18527,6 +18741,15 @@ Examples:
|
|
|
18527
18741
|
async function fetchOrganizations(http, apiKey) {
|
|
18528
18742
|
return http.post("/api/v2/auth/cli/organizations", { api_key: apiKey });
|
|
18529
18743
|
}
|
|
18744
|
+
function normalizeAuthScope(value) {
|
|
18745
|
+
if (!value) return "auto";
|
|
18746
|
+
if (value === "auto" || value === "folder" || value === "global") {
|
|
18747
|
+
return value;
|
|
18748
|
+
}
|
|
18749
|
+
throw new Error(
|
|
18750
|
+
`Invalid --auth-scope "${value}". Expected one of: auto, folder, global.`
|
|
18751
|
+
);
|
|
18752
|
+
}
|
|
18530
18753
|
function orgListLines(orgs) {
|
|
18531
18754
|
return orgs.map((org, index) => {
|
|
18532
18755
|
const current = org.is_current ? " (current)" : "";
|
|
@@ -18534,6 +18757,90 @@ function orgListLines(orgs) {
|
|
|
18534
18757
|
return `${index + 1}. ${org.name}${role}${current}`;
|
|
18535
18758
|
});
|
|
18536
18759
|
}
|
|
18760
|
+
function redactApiKey(value) {
|
|
18761
|
+
if (!value) return null;
|
|
18762
|
+
if (value.length <= 10) return `${value.slice(0, 3)}...`;
|
|
18763
|
+
return `${value.slice(0, 8)}...${value.slice(-4)}`;
|
|
18764
|
+
}
|
|
18765
|
+
function processEnvValue(name) {
|
|
18766
|
+
return process.env[name]?.trim() ?? "";
|
|
18767
|
+
}
|
|
18768
|
+
function resolveOrgSwitchAuthTarget(scope, config) {
|
|
18769
|
+
const activeProject = getResolvedProjectAuthSource(
|
|
18770
|
+
config.baseUrl,
|
|
18771
|
+
config.apiKey
|
|
18772
|
+
);
|
|
18773
|
+
const folderTarget = resolveProjectPinTarget();
|
|
18774
|
+
const globalOverrideWarning = activeProject && scope === "global" ? [
|
|
18775
|
+
`Folder auth in ${activeProject.filePath} overrides global auth for commands run here.`
|
|
18776
|
+
] : [];
|
|
18777
|
+
if (scope === "folder") {
|
|
18778
|
+
if (!folderTarget.ok) {
|
|
18779
|
+
throw new Error(
|
|
18780
|
+
`Cowork project folder is ambiguous. Candidate folders: ${folderTarget.candidates.join(
|
|
18781
|
+
", "
|
|
18782
|
+
)}. Set CLAUDE_PROJECT_DIR or cd into the intended project folder before running this command.`
|
|
18783
|
+
);
|
|
18784
|
+
}
|
|
18785
|
+
return {
|
|
18786
|
+
kind: "folder",
|
|
18787
|
+
requested_scope: scope,
|
|
18788
|
+
effective_scope: "folder",
|
|
18789
|
+
reason: "explicit_folder",
|
|
18790
|
+
source: folderTarget.source,
|
|
18791
|
+
warnings: []
|
|
18792
|
+
};
|
|
18793
|
+
}
|
|
18794
|
+
if (scope === "global") {
|
|
18795
|
+
return {
|
|
18796
|
+
kind: "global",
|
|
18797
|
+
requested_scope: scope,
|
|
18798
|
+
effective_scope: "global",
|
|
18799
|
+
reason: "explicit_global",
|
|
18800
|
+
warnings: globalOverrideWarning
|
|
18801
|
+
};
|
|
18802
|
+
}
|
|
18803
|
+
if (activeProject) {
|
|
18804
|
+
return {
|
|
18805
|
+
kind: "folder",
|
|
18806
|
+
requested_scope: scope,
|
|
18807
|
+
effective_scope: "folder",
|
|
18808
|
+
reason: "existing_folder_auth",
|
|
18809
|
+
source: activeProject.source,
|
|
18810
|
+
warnings: []
|
|
18811
|
+
};
|
|
18812
|
+
}
|
|
18813
|
+
if (folderTarget.ok && folderTarget.source === "cowork") {
|
|
18814
|
+
return {
|
|
18815
|
+
kind: "folder",
|
|
18816
|
+
requested_scope: scope,
|
|
18817
|
+
effective_scope: "folder",
|
|
18818
|
+
reason: "detected_cowork_project",
|
|
18819
|
+
source: "cowork",
|
|
18820
|
+
warnings: []
|
|
18821
|
+
};
|
|
18822
|
+
}
|
|
18823
|
+
if (!folderTarget.ok) {
|
|
18824
|
+
return {
|
|
18825
|
+
kind: "global",
|
|
18826
|
+
requested_scope: scope,
|
|
18827
|
+
effective_scope: "global",
|
|
18828
|
+
reason: "ambiguous_cowork_fell_back_global",
|
|
18829
|
+
warnings: [
|
|
18830
|
+
`Cowork project folder is ambiguous, so global auth was updated. Candidate folders: ${folderTarget.candidates.join(
|
|
18831
|
+
", "
|
|
18832
|
+
)}. Set CLAUDE_PROJECT_DIR or cd into the intended project folder to update folder auth.`
|
|
18833
|
+
]
|
|
18834
|
+
};
|
|
18835
|
+
}
|
|
18836
|
+
return {
|
|
18837
|
+
kind: "global",
|
|
18838
|
+
requested_scope: scope,
|
|
18839
|
+
effective_scope: "global",
|
|
18840
|
+
reason: "default_global",
|
|
18841
|
+
warnings: []
|
|
18842
|
+
};
|
|
18843
|
+
}
|
|
18537
18844
|
async function handleOrgList(options) {
|
|
18538
18845
|
const config = resolveConfig();
|
|
18539
18846
|
const http = new HttpClient(config);
|
|
@@ -18553,7 +18860,89 @@ async function handleOrgList(options) {
|
|
|
18553
18860
|
{ json: options.json }
|
|
18554
18861
|
);
|
|
18555
18862
|
}
|
|
18863
|
+
async function handleOrgStatus(options) {
|
|
18864
|
+
const config = resolveConfig();
|
|
18865
|
+
const http = new HttpClient(config);
|
|
18866
|
+
const payload = await fetchOrganizations(http, config.apiKey);
|
|
18867
|
+
const current = payload.organizations.find((org) => org.is_current) ?? payload.organizations.find((org) => org.org_id === payload.current_org_id) ?? null;
|
|
18868
|
+
const projectCandidate = getActiveProjectAuthSource();
|
|
18869
|
+
const activeProject = getResolvedProjectAuthSource(
|
|
18870
|
+
config.baseUrl,
|
|
18871
|
+
config.apiKey
|
|
18872
|
+
);
|
|
18873
|
+
const folderTarget = resolveProjectPinTarget();
|
|
18874
|
+
const hostPath = hostEnvFilePath(config.baseUrl);
|
|
18875
|
+
const envApiKey = processEnvValue(API_KEY_ENV);
|
|
18876
|
+
const envHostUrl = processEnvValue(HOST_URL_ENV);
|
|
18877
|
+
const authSource = envApiKey ? {
|
|
18878
|
+
scope: "env",
|
|
18879
|
+
source: "process",
|
|
18880
|
+
path: null,
|
|
18881
|
+
api_key: redactApiKey(envApiKey),
|
|
18882
|
+
host: envHostUrl || null,
|
|
18883
|
+
overrides_global: true,
|
|
18884
|
+
overrides_folder: Boolean(projectCandidate)
|
|
18885
|
+
} : activeProject ? {
|
|
18886
|
+
scope: "folder",
|
|
18887
|
+
source: activeProject.source,
|
|
18888
|
+
path: activeProject.filePath,
|
|
18889
|
+
api_key: redactApiKey(activeProject.env.DEEPLINE_API_KEY),
|
|
18890
|
+
overrides_global: true
|
|
18891
|
+
} : {
|
|
18892
|
+
scope: "global",
|
|
18893
|
+
source: "host",
|
|
18894
|
+
path: hostPath,
|
|
18895
|
+
api_key: redactApiKey(config.apiKey),
|
|
18896
|
+
overrides_global: false
|
|
18897
|
+
};
|
|
18898
|
+
const folderTargetPayload = folderTarget.ok ? {
|
|
18899
|
+
ok: true,
|
|
18900
|
+
source: folderTarget.source,
|
|
18901
|
+
dir: folderTarget.dir,
|
|
18902
|
+
env_path: `${folderTarget.dir}/.env.deepline`
|
|
18903
|
+
} : {
|
|
18904
|
+
ok: false,
|
|
18905
|
+
reason: folderTarget.reason,
|
|
18906
|
+
candidates: folderTarget.candidates
|
|
18907
|
+
};
|
|
18908
|
+
const lines = [
|
|
18909
|
+
`Organization: ${current?.name ?? "(unknown)"}`,
|
|
18910
|
+
`Host: ${config.baseUrl}`,
|
|
18911
|
+
`Auth scope: ${authSource.scope}`
|
|
18912
|
+
];
|
|
18913
|
+
if (authSource.path) {
|
|
18914
|
+
lines.push(`Auth file: ${authSource.path}`);
|
|
18915
|
+
} else {
|
|
18916
|
+
lines.push(`Auth source: ${API_KEY_ENV} process environment`);
|
|
18917
|
+
}
|
|
18918
|
+
if (envApiKey) {
|
|
18919
|
+
lines.push(`${API_KEY_ENV} overrides saved auth for this process.`);
|
|
18920
|
+
} else if (activeProject) {
|
|
18921
|
+
lines.push("Global auth is overridden in this folder.");
|
|
18922
|
+
}
|
|
18923
|
+
printCommandEnvelope(
|
|
18924
|
+
{
|
|
18925
|
+
ok: true,
|
|
18926
|
+
host: config.baseUrl,
|
|
18927
|
+
organization: current,
|
|
18928
|
+
current_org_id: payload.current_org_id,
|
|
18929
|
+
auth_source: authSource,
|
|
18930
|
+
host_env_path: hostPath,
|
|
18931
|
+
folder_target: folderTargetPayload,
|
|
18932
|
+
next: {
|
|
18933
|
+
set_auto: "deepline org set <org>",
|
|
18934
|
+
set_folder: "deepline org set <org> --auth-scope folder",
|
|
18935
|
+
set_global: "deepline org set <org> --auth-scope global"
|
|
18936
|
+
},
|
|
18937
|
+
render: {
|
|
18938
|
+
sections: [{ title: "org status", lines }]
|
|
18939
|
+
}
|
|
18940
|
+
},
|
|
18941
|
+
{ json: options.json }
|
|
18942
|
+
);
|
|
18943
|
+
}
|
|
18556
18944
|
async function handleOrgSwitch(selection, options) {
|
|
18945
|
+
const authScope = normalizeAuthScope(options.authScope);
|
|
18557
18946
|
const config = resolveConfig();
|
|
18558
18947
|
const http = new HttpClient(config);
|
|
18559
18948
|
const payload = await fetchOrganizations(http, config.apiKey);
|
|
@@ -18561,7 +18950,10 @@ async function handleOrgSwitch(selection, options) {
|
|
|
18561
18950
|
printCommandEnvelope(
|
|
18562
18951
|
{
|
|
18563
18952
|
...payload,
|
|
18564
|
-
next: {
|
|
18953
|
+
next: { set: "deepline org set <number>" },
|
|
18954
|
+
deprecated_command: options.deprecatedSwitch ? "org switch" : null,
|
|
18955
|
+
replacement_command: options.deprecatedSwitch ? "deepline org set" : null,
|
|
18956
|
+
warnings: options.deprecatedSwitch ? ["org switch is deprecated; use org set."] : [],
|
|
18565
18957
|
render: {
|
|
18566
18958
|
sections: [
|
|
18567
18959
|
{
|
|
@@ -18569,7 +18961,7 @@ async function handleOrgSwitch(selection, options) {
|
|
|
18569
18961
|
lines: orgListLines(payload.organizations)
|
|
18570
18962
|
}
|
|
18571
18963
|
],
|
|
18572
|
-
actions: [{ label: "Run", command: "deepline org
|
|
18964
|
+
actions: [{ label: "Run", command: "deepline org set <number>" }]
|
|
18573
18965
|
}
|
|
18574
18966
|
},
|
|
18575
18967
|
{ json: options.json }
|
|
@@ -18592,16 +18984,56 @@ async function handleOrgSwitch(selection, options) {
|
|
|
18592
18984
|
if (!target) {
|
|
18593
18985
|
throw new Error("Could not resolve the selected organization.");
|
|
18594
18986
|
}
|
|
18987
|
+
const authTarget = resolveOrgSwitchAuthTarget(authScope, config);
|
|
18595
18988
|
if (target.is_current) {
|
|
18989
|
+
let project_env_paths2 = [];
|
|
18990
|
+
if (authTarget.kind === "folder") {
|
|
18991
|
+
project_env_paths2 = saveProjectDeeplineEnvValues({
|
|
18992
|
+
DEEPLINE_HOST_URL: config.baseUrl,
|
|
18993
|
+
DEEPLINE_API_KEY: config.apiKey
|
|
18994
|
+
});
|
|
18995
|
+
} else {
|
|
18996
|
+
saveHostEnvValues(config.baseUrl, {
|
|
18997
|
+
DEEPLINE_HOST_URL: config.baseUrl,
|
|
18998
|
+
DEEPLINE_API_KEY: config.apiKey
|
|
18999
|
+
});
|
|
19000
|
+
}
|
|
19001
|
+
const renderLines2 = [`Already on ${target.name}.`];
|
|
19002
|
+
for (const projectPath of project_env_paths2) {
|
|
19003
|
+
renderLines2.push(`Saved folder auth in ${projectPath}`);
|
|
19004
|
+
}
|
|
19005
|
+
if (authTarget.kind === "global") {
|
|
19006
|
+
renderLines2.push(`Saved global auth in ${hostEnvFilePath(config.baseUrl)}`);
|
|
19007
|
+
}
|
|
19008
|
+
renderLines2.push(
|
|
19009
|
+
`Scope: ${authTarget.requested_scope} -> ${authTarget.effective_scope} (${authTarget.reason})`
|
|
19010
|
+
);
|
|
19011
|
+
if (options.deprecatedSwitch) {
|
|
19012
|
+
renderLines2.push("Warning: org switch is deprecated; use org set.");
|
|
19013
|
+
}
|
|
19014
|
+
for (const warning of authTarget.warnings) {
|
|
19015
|
+
renderLines2.push(`Warning: ${warning}`);
|
|
19016
|
+
}
|
|
19017
|
+
const warnings2 = [
|
|
19018
|
+
...options.deprecatedSwitch ? ["org switch is deprecated; use org set."] : [],
|
|
19019
|
+
...authTarget.warnings
|
|
19020
|
+
];
|
|
18596
19021
|
printCommandEnvelope(
|
|
18597
19022
|
{
|
|
18598
19023
|
ok: true,
|
|
18599
19024
|
unchanged: true,
|
|
18600
19025
|
organization: target,
|
|
19026
|
+
requested_auth_scope: authTarget.requested_scope,
|
|
19027
|
+
effective_auth_scope: authTarget.effective_scope,
|
|
19028
|
+
auth_scope_reason: authTarget.reason,
|
|
19029
|
+
auth_scope: authTarget.effective_scope,
|
|
19030
|
+
host_env_path: authTarget.kind === "global" ? hostEnvFilePath(config.baseUrl) : null,
|
|
19031
|
+
project_env_paths: project_env_paths2,
|
|
19032
|
+
deprecated_command: options.deprecatedSwitch ? "org switch" : null,
|
|
19033
|
+
replacement_command: options.deprecatedSwitch ? "deepline org set" : null,
|
|
19034
|
+
warnings: warnings2,
|
|
18601
19035
|
render: {
|
|
18602
|
-
sections: [
|
|
18603
|
-
{ title: "org switch", lines: [`Already on ${target.name}.`] }
|
|
18604
|
-
]
|
|
19036
|
+
sections: [{ title: "org set", lines: renderLines2 }]
|
|
18605
19037
|
}
|
|
18606
19038
|
},
|
|
18607
19039
|
{ json: options.json }
|
|
@@ -18612,26 +19044,61 @@ async function handleOrgSwitch(selection, options) {
|
|
|
18612
19044
|
api_key: config.apiKey,
|
|
18613
19045
|
org_id: target.org_id
|
|
18614
19046
|
});
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
19047
|
+
let project_env_paths = [];
|
|
19048
|
+
if (authTarget.kind === "folder") {
|
|
19049
|
+
project_env_paths = saveProjectDeeplineEnvValues({
|
|
19050
|
+
DEEPLINE_HOST_URL: config.baseUrl,
|
|
19051
|
+
DEEPLINE_API_KEY: switched.api_key
|
|
19052
|
+
});
|
|
19053
|
+
} else {
|
|
19054
|
+
saveHostEnvValues(config.baseUrl, {
|
|
19055
|
+
DEEPLINE_HOST_URL: config.baseUrl,
|
|
19056
|
+
DEEPLINE_API_KEY: switched.api_key,
|
|
19057
|
+
DEEPLINE_ACTIVE_ORG_ID: switched.org_id,
|
|
19058
|
+
DEEPLINE_ACTIVE_ORG_NAME: switched.org_name
|
|
19059
|
+
});
|
|
19060
|
+
}
|
|
18620
19061
|
const { api_key: _apiKey, ...publicSwitched } = switched;
|
|
19062
|
+
const renderLines = [`Switched to ${switched.org_name}.`];
|
|
19063
|
+
if (authTarget.kind === "folder") {
|
|
19064
|
+
for (const projectPath of project_env_paths) {
|
|
19065
|
+
renderLines.push(`Saved folder auth in ${projectPath}`);
|
|
19066
|
+
}
|
|
19067
|
+
} else {
|
|
19068
|
+
renderLines.push(`Saved global auth in ${hostEnvFilePath(config.baseUrl)}`);
|
|
19069
|
+
}
|
|
19070
|
+
renderLines.push(
|
|
19071
|
+
`Scope: ${authTarget.requested_scope} -> ${authTarget.effective_scope} (${authTarget.reason})`
|
|
19072
|
+
);
|
|
19073
|
+
if (options.deprecatedSwitch) {
|
|
19074
|
+
renderLines.push("Warning: org switch is deprecated; use org set.");
|
|
19075
|
+
}
|
|
19076
|
+
for (const warning of authTarget.warnings) {
|
|
19077
|
+
renderLines.push(`Warning: ${warning}`);
|
|
19078
|
+
}
|
|
19079
|
+
const warnings = [
|
|
19080
|
+
...options.deprecatedSwitch ? ["org switch is deprecated; use org set."] : [],
|
|
19081
|
+
...authTarget.warnings
|
|
19082
|
+
];
|
|
18621
19083
|
printCommandEnvelope(
|
|
18622
19084
|
{
|
|
18623
19085
|
ok: true,
|
|
18624
|
-
host_env_path: hostEnvFilePath(config.baseUrl),
|
|
19086
|
+
host_env_path: authTarget.kind === "global" ? hostEnvFilePath(config.baseUrl) : null,
|
|
19087
|
+
project_env_paths,
|
|
18625
19088
|
...publicSwitched,
|
|
18626
19089
|
api_key_saved: true,
|
|
19090
|
+
requested_auth_scope: authTarget.requested_scope,
|
|
19091
|
+
effective_auth_scope: authTarget.effective_scope,
|
|
19092
|
+
auth_scope_reason: authTarget.reason,
|
|
19093
|
+
auth_scope: authTarget.effective_scope,
|
|
19094
|
+
deprecated_command: options.deprecatedSwitch ? "org switch" : null,
|
|
19095
|
+
replacement_command: options.deprecatedSwitch ? "deepline org set" : null,
|
|
19096
|
+
warnings,
|
|
18627
19097
|
render: {
|
|
18628
19098
|
sections: [
|
|
18629
19099
|
{
|
|
18630
|
-
title: "org
|
|
18631
|
-
lines:
|
|
18632
|
-
`Switched to ${switched.org_name}.`,
|
|
18633
|
-
`Saved host auth in ${hostEnvFilePath(config.baseUrl)}`
|
|
18634
|
-
]
|
|
19100
|
+
title: "org set",
|
|
19101
|
+
lines: renderLines
|
|
18635
19102
|
}
|
|
18636
19103
|
]
|
|
18637
19104
|
}
|
|
@@ -18647,6 +19114,7 @@ async function handleOrgCreate(name, options) {
|
|
|
18647
19114
|
name
|
|
18648
19115
|
});
|
|
18649
19116
|
saveHostEnvValues(config.baseUrl, {
|
|
19117
|
+
DEEPLINE_HOST_URL: config.baseUrl,
|
|
18650
19118
|
DEEPLINE_API_KEY: created.api_key,
|
|
18651
19119
|
DEEPLINE_ACTIVE_ORG_ID: created.org_id,
|
|
18652
19120
|
DEEPLINE_ACTIVE_ORG_NAME: created.org_name
|
|
@@ -18676,18 +19144,41 @@ async function handleOrgCreate(name, options) {
|
|
|
18676
19144
|
);
|
|
18677
19145
|
}
|
|
18678
19146
|
function registerOrgCommands(program) {
|
|
18679
|
-
const org = program.command("org").description("List, create, and
|
|
19147
|
+
const org = program.command("org").description("List, create, and set organizations.").addHelpText(
|
|
18680
19148
|
"after",
|
|
18681
19149
|
`
|
|
18682
19150
|
Notes:
|
|
18683
|
-
Organizations are workspaces.
|
|
18684
|
-
|
|
19151
|
+
Organizations are workspaces. Auth is stored as an API key scoped to one
|
|
19152
|
+
organization, so setting an org saves a key for the selected auth scope.
|
|
19153
|
+
|
|
19154
|
+
Auth scopes:
|
|
19155
|
+
auto Update the folder pin that already controls this command; in
|
|
19156
|
+
Cowork, write the mounted project folder; otherwise update global
|
|
19157
|
+
host auth.
|
|
19158
|
+
folder Write .env.deepline in the current project/Cowork project and make
|
|
19159
|
+
sure .env.deepline is gitignored. Commands below that folder use
|
|
19160
|
+
this org; sibling folders can pin different orgs.
|
|
19161
|
+
global Write ~/.local/deepline/<host>/.env. Commands outside folder pins
|
|
19162
|
+
use this org. Existing folder pins still override global auth.
|
|
19163
|
+
|
|
19164
|
+
Process env DEEPLINE_API_KEY overrides saved auth for that command only.
|
|
19165
|
+
|
|
19166
|
+
Agent loop:
|
|
19167
|
+
deepline org list --json
|
|
19168
|
+
deepline org set <number-or-org-id> --auth-scope folder --json
|
|
19169
|
+
deepline org status --json
|
|
19170
|
+
deepline auth status --json
|
|
18685
19171
|
|
|
18686
19172
|
Examples:
|
|
18687
19173
|
deepline org list --json
|
|
19174
|
+
deepline org status --json
|
|
18688
19175
|
deepline org create Acme --json
|
|
18689
|
-
deepline org
|
|
18690
|
-
deepline org
|
|
19176
|
+
deepline org set 2
|
|
19177
|
+
deepline org set 2 --auth-scope folder
|
|
19178
|
+
deepline org set --org-id org_123 --json
|
|
19179
|
+
cd path/to/project-a && deepline org set Prove --auth-scope folder --json
|
|
19180
|
+
cd path/to/project-b && deepline org set Mixmax --auth-scope folder --json
|
|
19181
|
+
cd .. && deepline org status --json
|
|
18691
19182
|
`
|
|
18692
19183
|
);
|
|
18693
19184
|
org.command("list").description("List your organizations.").addHelpText(
|
|
@@ -18714,21 +19205,88 @@ Examples:
|
|
|
18714
19205
|
deepline org create "Acme Sales" --json
|
|
18715
19206
|
`
|
|
18716
19207
|
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgCreate);
|
|
18717
|
-
org.command("
|
|
18718
|
-
"Switch to another organization and save the new API key in the host auth file."
|
|
18719
|
-
).addHelpText(
|
|
19208
|
+
org.command("status").description("Show the current organization and auth source.").addHelpText(
|
|
18720
19209
|
"after",
|
|
18721
19210
|
`
|
|
18722
19211
|
Notes:
|
|
18723
|
-
|
|
18724
|
-
|
|
19212
|
+
Read-only. Shows the current org plus auth_source.scope, auth_source.path,
|
|
19213
|
+
folder_target, host_env_path, and next commands.
|
|
19214
|
+
|
|
19215
|
+
Scopes are env, folder, or global. env means DEEPLINE_API_KEY/
|
|
19216
|
+
DEEPLINE_HOST_URL in process env wins. folder means nearest/Cowork
|
|
19217
|
+
.env.deepline wins. global means host config wins.
|
|
19218
|
+
|
|
19219
|
+
Run before and after org set to verify what future commands will use.
|
|
19220
|
+
|
|
19221
|
+
Examples:
|
|
19222
|
+
deepline org status
|
|
19223
|
+
deepline org status --json
|
|
19224
|
+
`
|
|
19225
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgStatus);
|
|
19226
|
+
const addOrgSetOptions = (command) => command.option("--org-id <id>", "Set using an explicit organization id").option(
|
|
19227
|
+
"--auth-scope <scope>",
|
|
19228
|
+
"Where to save auth: auto, folder, or global",
|
|
19229
|
+
"auto"
|
|
19230
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped");
|
|
19231
|
+
addOrgSetOptions(
|
|
19232
|
+
org.command("set [selection]").description("Set the organization for the selected auth scope.").addHelpText(
|
|
19233
|
+
"after",
|
|
19234
|
+
`
|
|
19235
|
+
Notes:
|
|
19236
|
+
Selection can be a list number, exact organization name, or organization id.
|
|
19237
|
+
Without a selection, prints choices.
|
|
19238
|
+
|
|
19239
|
+
Mutates local auth state and asks Deepline for an org-scoped API key. It
|
|
19240
|
+
writes only the selected scope:
|
|
19241
|
+
auto Update the folder pin that already controls this command; in
|
|
19242
|
+
Cowork, write the mounted project folder; otherwise update global
|
|
19243
|
+
host auth.
|
|
19244
|
+
folder Write .env.deepline in the current project/Cowork project and make
|
|
19245
|
+
sure .env.deepline is gitignored.
|
|
19246
|
+
global Write ~/.local/deepline/<host>/.env.
|
|
19247
|
+
|
|
19248
|
+
Folder auth shadows global auth. If you set --auth-scope global from a pinned
|
|
19249
|
+
folder, commands in that folder still use the folder pin until it is changed
|
|
19250
|
+
or removed.
|
|
19251
|
+
|
|
19252
|
+
Use --json for stable fields including effective_auth_scope,
|
|
19253
|
+
auth_scope_reason, host_env_path, project_env_paths, warnings, org_id, and
|
|
19254
|
+
org_name.
|
|
19255
|
+
|
|
19256
|
+
Examples:
|
|
19257
|
+
deepline org set
|
|
19258
|
+
deepline org set 2
|
|
19259
|
+
deepline org set 2 --auth-scope folder
|
|
19260
|
+
deepline org set 2 --auth-scope global
|
|
19261
|
+
deepline org set --org-id org_123 --json
|
|
19262
|
+
deepline org status --json
|
|
19263
|
+
`
|
|
19264
|
+
)
|
|
19265
|
+
).action(handleOrgSwitch);
|
|
19266
|
+
addOrgSetOptions(
|
|
19267
|
+
org.command("switch [selection]").description(
|
|
19268
|
+
"Deprecated alias for org set. Set the organization for the selected auth scope."
|
|
19269
|
+
).addHelpText(
|
|
19270
|
+
"after",
|
|
19271
|
+
`
|
|
19272
|
+
Notes:
|
|
19273
|
+
Deprecated alias. Use deepline org set instead. The command still mutates
|
|
19274
|
+
local auth state with the same --auth-scope behavior as org set.
|
|
19275
|
+
|
|
19276
|
+
Run deepline org set --help for scope definitions and the agent verification
|
|
19277
|
+
loop.
|
|
18725
19278
|
|
|
18726
19279
|
Examples:
|
|
18727
19280
|
deepline org switch
|
|
18728
19281
|
deepline org switch 2
|
|
19282
|
+
deepline org switch 2 --auth-scope folder
|
|
19283
|
+
deepline org switch 2 --auth-scope global
|
|
18729
19284
|
deepline org switch --org-id org_123 --json
|
|
18730
19285
|
`
|
|
18731
|
-
|
|
19286
|
+
)
|
|
19287
|
+
).action(
|
|
19288
|
+
(selection, options) => handleOrgSwitch(selection, { ...options, deprecatedSwitch: true })
|
|
19289
|
+
);
|
|
18732
19290
|
}
|
|
18733
19291
|
|
|
18734
19292
|
// src/cli/commands/quickstart.ts
|
|
@@ -20821,6 +21379,10 @@ function buildToolExecuteBaseEnvelope(input2) {
|
|
|
20821
21379
|
summary: input2.summary
|
|
20822
21380
|
};
|
|
20823
21381
|
const envelopeHasCanonicalOutput = isRecord8(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
|
|
21382
|
+
const envelopeHasDeclaredOutput = Object.prototype.hasOwnProperty.call(
|
|
21383
|
+
envelope,
|
|
21384
|
+
"output"
|
|
21385
|
+
);
|
|
20824
21386
|
const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote2(JSON.stringify(input2.params))} --json`;
|
|
20825
21387
|
const actions = input2.listConversion ? [
|
|
20826
21388
|
{
|
|
@@ -20830,7 +21392,7 @@ function buildToolExecuteBaseEnvelope(input2) {
|
|
|
20830
21392
|
] : [];
|
|
20831
21393
|
return {
|
|
20832
21394
|
...envelope,
|
|
20833
|
-
...envelopeHasCanonicalOutput ? { output_preview: outputPreview } : { output: outputPreview },
|
|
21395
|
+
...envelopeHasCanonicalOutput || envelopeHasDeclaredOutput ? { output_preview: outputPreview } : { output: outputPreview },
|
|
20834
21396
|
...summaryEntries.length > 0 ? { summary: input2.summary } : {},
|
|
20835
21397
|
next: {
|
|
20836
21398
|
inspect: inspectCommand,
|
|
@@ -21591,7 +22153,7 @@ import { spawn as spawn3 } from "child_process";
|
|
|
21591
22153
|
import {
|
|
21592
22154
|
existsSync as existsSync11,
|
|
21593
22155
|
mkdirSync as mkdirSync9,
|
|
21594
|
-
realpathSync as
|
|
22156
|
+
realpathSync as realpathSync3,
|
|
21595
22157
|
readFileSync as readFileSync11,
|
|
21596
22158
|
renameSync,
|
|
21597
22159
|
rmSync as rmSync3,
|
|
@@ -22090,7 +22652,7 @@ function findRepoBackedSdkRoot(startPath) {
|
|
|
22090
22652
|
function inferNpmGlobalPrefixFromEntrypoint(entrypoint) {
|
|
22091
22653
|
const normalized = (() => {
|
|
22092
22654
|
try {
|
|
22093
|
-
return
|
|
22655
|
+
return realpathSync3(entrypoint);
|
|
22094
22656
|
} catch {
|
|
22095
22657
|
return resolve12(entrypoint);
|
|
22096
22658
|
}
|