deepline 0.1.165 → 0.1.167
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/apps/play-runner-workers/src/entry.ts +291 -107
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-receipts.ts +12 -2
- package/dist/bundling-sources/sdk/src/agent-runtime.ts +2 -2
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +80 -6
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +77 -8
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +41 -35
- package/dist/cli/index.js +61 -22
- package/dist/cli/index.mjs +61 -22
- package/dist/index.js +4 -4
- package/dist/index.mjs +4 -4
- package/package.json +1 -1
|
@@ -104,10 +104,10 @@ export const SDK_RELEASE = {
|
|
|
104
104
|
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
105
105
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
106
106
|
// fields shipped in 0.1.153.
|
|
107
|
-
version: '0.1.
|
|
107
|
+
version: '0.1.167',
|
|
108
108
|
apiContract: '2026-06-dataset-handle-results-hard-cutover',
|
|
109
109
|
supportPolicy: {
|
|
110
|
-
latest: '0.1.
|
|
110
|
+
latest: '0.1.167',
|
|
111
111
|
minimumSupported: '0.1.53',
|
|
112
112
|
deprecatedBelow: '0.1.53',
|
|
113
113
|
commandMinimumSupported: [
|
|
@@ -4335,7 +4335,7 @@ export class PlayContextImpl {
|
|
|
4335
4335
|
}
|
|
4336
4336
|
};
|
|
4337
4337
|
|
|
4338
|
-
const
|
|
4338
|
+
const durableExistingRunningHandlers: Promise<void>[] = [];
|
|
4339
4339
|
if (
|
|
4340
4340
|
pendingRequests.length > 0 &&
|
|
4341
4341
|
(this.#options.claimRuntimeStepReceipts ||
|
|
@@ -4448,7 +4448,7 @@ export class PlayContextImpl {
|
|
|
4448
4448
|
liveFollowersByOwnerCallId.set(owner.callId, followers);
|
|
4449
4449
|
}
|
|
4450
4450
|
};
|
|
4451
|
-
const
|
|
4451
|
+
const reclaimExistingRunningReceiptAfterWait = async (
|
|
4452
4452
|
receiptKey: string,
|
|
4453
4453
|
requestsForKey: ToolCallRequest[],
|
|
4454
4454
|
): Promise<void> => {
|
|
@@ -4469,6 +4469,65 @@ export class PlayContextImpl {
|
|
|
4469
4469
|
return;
|
|
4470
4470
|
}
|
|
4471
4471
|
}
|
|
4472
|
+
const reclaimed = (
|
|
4473
|
+
await this.claimRuntimeStepReceipts(
|
|
4474
|
+
[receiptKey],
|
|
4475
|
+
this.currentRunId,
|
|
4476
|
+
true,
|
|
4477
|
+
)
|
|
4478
|
+
).get(receiptKey);
|
|
4479
|
+
if (
|
|
4480
|
+
reclaimed?.status === 'completed' ||
|
|
4481
|
+
reclaimed?.status === 'skipped'
|
|
4482
|
+
) {
|
|
4483
|
+
await resolveRequestsFromReceipt(
|
|
4484
|
+
requestsForKey,
|
|
4485
|
+
reclaimed,
|
|
4486
|
+
'cache',
|
|
4487
|
+
);
|
|
4488
|
+
durableRecoveredRequests.push(...requestsForKey);
|
|
4489
|
+
return;
|
|
4490
|
+
}
|
|
4491
|
+
if (reclaimed?.status === 'failed') {
|
|
4492
|
+
for (const request of requestsForKey) {
|
|
4493
|
+
await this.rejectToolCall(
|
|
4494
|
+
toolId,
|
|
4495
|
+
request,
|
|
4496
|
+
new Error(reclaimed.error ?? 'Durable tool call failed.'),
|
|
4497
|
+
);
|
|
4498
|
+
}
|
|
4499
|
+
return;
|
|
4500
|
+
}
|
|
4501
|
+
if (
|
|
4502
|
+
reclaimed?.status === 'running' &&
|
|
4503
|
+
reclaimed.claimState !== 'existing'
|
|
4504
|
+
) {
|
|
4505
|
+
const [owner, ...waiters] = requestsForKey;
|
|
4506
|
+
if (!owner) return;
|
|
4507
|
+
if (waiters.length > 0) {
|
|
4508
|
+
liveFollowersByOwnerCallId.set(owner.callId, waiters);
|
|
4509
|
+
}
|
|
4510
|
+
try {
|
|
4511
|
+
const execution = await this.callToolExecutionAPI(
|
|
4512
|
+
toolId,
|
|
4513
|
+
owner.input,
|
|
4514
|
+
);
|
|
4515
|
+
const result = await this.resolveToolCall(
|
|
4516
|
+
toolId,
|
|
4517
|
+
owner,
|
|
4518
|
+
execution?.result ?? null,
|
|
4519
|
+
execution?.metadata ?? null,
|
|
4520
|
+
execution?.jobId,
|
|
4521
|
+
execution?.meta,
|
|
4522
|
+
);
|
|
4523
|
+
resolveLiveFollowers(owner, result);
|
|
4524
|
+
recordToolStep([owner]);
|
|
4525
|
+
this.#options.onBatchComplete?.(this.checkpoint);
|
|
4526
|
+
} catch (error) {
|
|
4527
|
+
await rejectWithLiveFollowers(owner, error);
|
|
4528
|
+
}
|
|
4529
|
+
return;
|
|
4530
|
+
}
|
|
4472
4531
|
for (const request of requestsForKey) {
|
|
4473
4532
|
await this.rejectToolCall(
|
|
4474
4533
|
toolId,
|
|
@@ -4510,8 +4569,23 @@ export class PlayContextImpl {
|
|
|
4510
4569
|
claimOwnerWithLiveFollowers(owner, waiters);
|
|
4511
4570
|
continue;
|
|
4512
4571
|
}
|
|
4513
|
-
|
|
4514
|
-
|
|
4572
|
+
if (
|
|
4573
|
+
claim?.status === 'running' &&
|
|
4574
|
+
claim.claimState === 'existing'
|
|
4575
|
+
) {
|
|
4576
|
+
durableExistingRunningHandlers.push(
|
|
4577
|
+
reclaimExistingRunningReceiptAfterWait(
|
|
4578
|
+
receiptKey,
|
|
4579
|
+
requestsForKey,
|
|
4580
|
+
),
|
|
4581
|
+
);
|
|
4582
|
+
continue;
|
|
4583
|
+
}
|
|
4584
|
+
durableExistingRunningHandlers.push(
|
|
4585
|
+
reclaimExistingRunningReceiptAfterWait(
|
|
4586
|
+
receiptKey,
|
|
4587
|
+
requestsForKey,
|
|
4588
|
+
),
|
|
4515
4589
|
);
|
|
4516
4590
|
}
|
|
4517
4591
|
|
|
@@ -4621,8 +4695,8 @@ export class PlayContextImpl {
|
|
|
4621
4695
|
}
|
|
4622
4696
|
}
|
|
4623
4697
|
}
|
|
4624
|
-
if (
|
|
4625
|
-
await Promise.allSettled(
|
|
4698
|
+
if (durableExistingRunningHandlers.length > 0) {
|
|
4699
|
+
await Promise.allSettled(durableExistingRunningHandlers);
|
|
4626
4700
|
}
|
|
4627
4701
|
}),
|
|
4628
4702
|
);
|
|
@@ -10,6 +10,9 @@ import type { DurableReceiptRecoverySource } from './tool-execution-outcome';
|
|
|
10
10
|
|
|
11
11
|
const DURABLE_RECEIPT_WAIT_MAX_ATTEMPTS = 240;
|
|
12
12
|
const DURABLE_RECEIPT_WAIT_DELAY_MS = 250;
|
|
13
|
+
const TOOL_RECEIPT_DEFAULT_WAIT_MS = 300_000;
|
|
14
|
+
const TOOL_RECEIPT_COMPLETION_BUFFER_MS = 30_000;
|
|
15
|
+
const TOOL_RECEIPT_MAX_WAIT_MS = 30 * 60_000;
|
|
13
16
|
|
|
14
17
|
export class RuntimeReceiptWaitTimeoutError extends Error {
|
|
15
18
|
constructor(key: string) {
|
|
@@ -18,6 +21,76 @@ export class RuntimeReceiptWaitTimeoutError extends Error {
|
|
|
18
21
|
}
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
export function resolveRuntimeToolReceiptWaitTimeoutMs(
|
|
25
|
+
requestInput: Record<string, unknown>,
|
|
26
|
+
): number {
|
|
27
|
+
const explicitTimeoutCandidate =
|
|
28
|
+
requestInput.timeoutMs ??
|
|
29
|
+
requestInput.timeout_ms ??
|
|
30
|
+
requestInput.max_wait_ms;
|
|
31
|
+
const explicitTimeoutMs =
|
|
32
|
+
typeof explicitTimeoutCandidate === 'number' &&
|
|
33
|
+
isFinite(explicitTimeoutCandidate) &&
|
|
34
|
+
explicitTimeoutCandidate > 0
|
|
35
|
+
? explicitTimeoutCandidate
|
|
36
|
+
: undefined;
|
|
37
|
+
const toolTimeoutMs = explicitTimeoutMs ?? TOOL_RECEIPT_DEFAULT_WAIT_MS;
|
|
38
|
+
return Math.min(
|
|
39
|
+
TOOL_RECEIPT_MAX_WAIT_MS,
|
|
40
|
+
Math.max(60_000, toolTimeoutMs + TOOL_RECEIPT_COMPLETION_BUFFER_MS),
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function resolveRuntimeToolReceiptWaitMaxAttempts(
|
|
45
|
+
requestInput: Record<string, unknown>,
|
|
46
|
+
): number {
|
|
47
|
+
return Math.ceil(
|
|
48
|
+
resolveRuntimeToolReceiptWaitTimeoutMs(requestInput) /
|
|
49
|
+
DURABLE_RECEIPT_WAIT_DELAY_MS,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function throwIfReceiptWaitAborted(signal?: AbortSignal): void {
|
|
54
|
+
if (!signal?.aborted) return;
|
|
55
|
+
throw signal.reason instanceof Error
|
|
56
|
+
? signal.reason
|
|
57
|
+
: new Error(
|
|
58
|
+
typeof signal.reason === 'string' && signal.reason.trim()
|
|
59
|
+
? signal.reason
|
|
60
|
+
: 'Durable receipt wait aborted.',
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function sleepReceiptWait(
|
|
65
|
+
delayMs: number,
|
|
66
|
+
signal?: AbortSignal,
|
|
67
|
+
): Promise<void> {
|
|
68
|
+
throwIfReceiptWaitAborted(signal);
|
|
69
|
+
if (delayMs <= 0) return;
|
|
70
|
+
await new Promise<void>((resolve, reject) => {
|
|
71
|
+
const timeout = setTimeout(finish, delayMs);
|
|
72
|
+
const abort = () => {
|
|
73
|
+
clearTimeout(timeout);
|
|
74
|
+
reject(
|
|
75
|
+
signal?.reason instanceof Error
|
|
76
|
+
? signal.reason
|
|
77
|
+
: new Error(
|
|
78
|
+
typeof signal?.reason === 'string' && signal.reason.trim()
|
|
79
|
+
? signal.reason
|
|
80
|
+
: 'Durable receipt wait aborted.',
|
|
81
|
+
),
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
function finish() {
|
|
85
|
+
signal?.removeEventListener('abort', abort);
|
|
86
|
+
resolve();
|
|
87
|
+
}
|
|
88
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
89
|
+
if (signal?.aborted) abort();
|
|
90
|
+
});
|
|
91
|
+
throwIfReceiptWaitAborted(signal);
|
|
92
|
+
}
|
|
93
|
+
|
|
21
94
|
export type DurableReceiptOperation = 'step' | 'tool' | 'fetch' | 'runPlay';
|
|
22
95
|
|
|
23
96
|
export type DurableReceiptExecutionStore = {
|
|
@@ -55,12 +128,14 @@ export async function waitForCompletedRuntimeReceipt(input: {
|
|
|
55
128
|
store: Pick<DurableReceiptExecutionStore, 'getMany'>;
|
|
56
129
|
maxAttempts?: number;
|
|
57
130
|
delayMs?: number;
|
|
131
|
+
abortSignal?: AbortSignal;
|
|
58
132
|
}): Promise<RuntimeStepReceipt> {
|
|
59
133
|
const maxAttempts = input.maxAttempts ?? DURABLE_RECEIPT_WAIT_MAX_ATTEMPTS;
|
|
60
134
|
const delayMs = input.delayMs ?? DURABLE_RECEIPT_WAIT_DELAY_MS;
|
|
61
135
|
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
136
|
+
throwIfReceiptWaitAborted(input.abortSignal);
|
|
62
137
|
if (attempt > 0) {
|
|
63
|
-
await
|
|
138
|
+
await sleepReceiptWait(delayMs, input.abortSignal);
|
|
64
139
|
}
|
|
65
140
|
const receipt = (await input.store.getMany([input.receiptKey])).get(
|
|
66
141
|
input.receiptKey,
|
|
@@ -189,13 +264,7 @@ export async function executeWithDurableRuntimeReceipt<T>(input: {
|
|
|
189
264
|
try {
|
|
190
265
|
return await waitForRunningReceiptOrTimeout();
|
|
191
266
|
} catch (error) {
|
|
192
|
-
if (
|
|
193
|
-
input.repairRunningReceiptForSameRunAfterWaitTimeout === true &&
|
|
194
|
-
error instanceof RuntimeReceiptWaitTimeoutError &&
|
|
195
|
-
receipt.status === 'running' &&
|
|
196
|
-
typeof receipt.runId === 'string' &&
|
|
197
|
-
receipt.runId.trim() === input.runId
|
|
198
|
-
) {
|
|
267
|
+
if (error instanceof RuntimeReceiptWaitTimeoutError) {
|
|
199
268
|
const recovered = await reclaimRunningReceipt();
|
|
200
269
|
if (recovered.kind === 'recovered') return recovered;
|
|
201
270
|
return { kind: 'claimed' };
|
|
@@ -16,7 +16,6 @@ import type {
|
|
|
16
16
|
import type { PlayBundleArtifact } from '../plays/artifact-types';
|
|
17
17
|
import {
|
|
18
18
|
augmentSheetContractWithDatasetFields,
|
|
19
|
-
outputPhysicalSheetColumnNames,
|
|
20
19
|
outputPhysicalSheetColumnProjections,
|
|
21
20
|
physicalSheetColumnNames,
|
|
22
21
|
physicalSheetColumnProjections,
|
|
@@ -1633,15 +1632,17 @@ function nextRuntimeSheetVersionExpression(
|
|
|
1633
1632
|
|
|
1634
1633
|
function missingOutputCellSql(
|
|
1635
1634
|
tableAlias: string,
|
|
1636
|
-
outputPhysicalColumns: readonly
|
|
1635
|
+
outputPhysicalColumns: readonly PhysicalSheetColumnProjection[],
|
|
1637
1636
|
): string {
|
|
1638
1637
|
if (outputPhysicalColumns.length === 0) {
|
|
1639
1638
|
return 'false';
|
|
1640
1639
|
}
|
|
1641
1640
|
return outputPhysicalColumns
|
|
1642
1641
|
.map((column) => {
|
|
1643
|
-
const quoted = `${tableAlias}.${quoteIdentifier(column)}`;
|
|
1644
|
-
|
|
1642
|
+
const quoted = `${tableAlias}.${quoteIdentifier(column.sqlName)}`;
|
|
1643
|
+
const staleAt = `${tableAlias}._cell_meta -> ${quoteLiteral(column.fieldName)} -> 'staleAt'`;
|
|
1644
|
+
const staleAtMs = `(CASE WHEN jsonb_typeof(${staleAt}) = 'number' THEN (${staleAt})::text::double precision ELSE NULL END)`;
|
|
1645
|
+
return `(${quoted} IS NULL OR ${quoted} = 'null'::jsonb OR ${quoted} = '""'::jsonb OR (${staleAtMs} IS NOT NULL AND ${staleAtMs} <= extract(epoch from now()) * 1000))`;
|
|
1645
1646
|
})
|
|
1646
1647
|
.join(' OR ');
|
|
1647
1648
|
}
|
|
@@ -2186,7 +2187,7 @@ async function prepareRuntimeSheetDatasetRows(
|
|
|
2186
2187
|
normalizedTableNamespace: string;
|
|
2187
2188
|
physicalInsertColumnsSql: string;
|
|
2188
2189
|
physicalInsertValuesSql: string;
|
|
2189
|
-
outputPhysicalColumns:
|
|
2190
|
+
outputPhysicalColumns: PhysicalSheetColumnProjection[];
|
|
2190
2191
|
},
|
|
2191
2192
|
): Promise<{ inserted: number; pendingKeys: string[] }> {
|
|
2192
2193
|
let inserted = 0;
|
|
@@ -2363,7 +2364,6 @@ async function buildRuntimeSheetDatasetStartResult(
|
|
|
2363
2364
|
timings?: RuntimeSheetTiming[];
|
|
2364
2365
|
},
|
|
2365
2366
|
): Promise<PrepareRuntimeSheetResult> {
|
|
2366
|
-
void input.pendingKeys;
|
|
2367
2367
|
if (input.inserted === input.rowEntries.length) {
|
|
2368
2368
|
const datasetFields = input.sheetContract.columns.flatMap((column) =>
|
|
2369
2369
|
column.source === 'datasetColumn' && typeof column.field === 'string'
|
|
@@ -2390,47 +2390,55 @@ async function buildRuntimeSheetDatasetStartResult(
|
|
|
2390
2390
|
};
|
|
2391
2391
|
}
|
|
2392
2392
|
|
|
2393
|
+
const pendingKeys = new Set(input.pendingKeys);
|
|
2393
2394
|
const startedAt = Date.now();
|
|
2394
2395
|
await markRuntimeRowsPendingForRecompute(client, session, {
|
|
2395
|
-
keys:
|
|
2396
|
+
keys: [...pendingKeys],
|
|
2396
2397
|
runId: input.runId,
|
|
2397
2398
|
normalizedPlayName: input.normalizedPlayName,
|
|
2398
2399
|
normalizedTableNamespace: input.normalizedTableNamespace,
|
|
2399
2400
|
});
|
|
2400
|
-
const
|
|
2401
|
+
const persistedRows = await readRuntimeRowsByKey(
|
|
2401
2402
|
client,
|
|
2402
2403
|
session,
|
|
2403
2404
|
input.rowEntries.map((entry) => entry.key),
|
|
2404
2405
|
input.sheetContract,
|
|
2405
2406
|
);
|
|
2406
2407
|
const persistedRowsByKey = new Map(
|
|
2407
|
-
|
|
2408
|
+
persistedRows.map((row) => [row.key, row.data]),
|
|
2408
2409
|
);
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2410
|
+
if (pendingKeys.size > 0) {
|
|
2411
|
+
input.timings?.push({
|
|
2412
|
+
phase: 'mark_rows_pending_for_recompute',
|
|
2413
|
+
ms: Date.now() - startedAt,
|
|
2414
|
+
rows: pendingKeys.size,
|
|
2415
|
+
});
|
|
2416
|
+
}
|
|
2417
|
+
const buildMergedRow = (entry: RuntimeDatasetRowEntry) => {
|
|
2418
|
+
const merged = { ...entry.row };
|
|
2419
|
+
for (const [field, value] of Object.entries(
|
|
2420
|
+
persistedRowsByKey.get(entry.key) ?? {},
|
|
2421
|
+
)) {
|
|
2422
|
+
if (
|
|
2423
|
+
value !== null ||
|
|
2424
|
+
!Object.prototype.hasOwnProperty.call(merged, field)
|
|
2425
|
+
) {
|
|
2426
|
+
merged[field] = value;
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
return {
|
|
2430
|
+
...merged,
|
|
2431
|
+
__deeplineRowKey: entry.key,
|
|
2432
|
+
};
|
|
2433
|
+
};
|
|
2434
|
+
const pendingRows: Record<string, unknown>[] = [];
|
|
2435
|
+
for (const entry of input.rowEntries) {
|
|
2436
|
+
pendingRows.push(buildMergedRow(entry));
|
|
2437
|
+
}
|
|
2414
2438
|
return {
|
|
2415
2439
|
inserted: input.inserted,
|
|
2416
2440
|
skipped: input.sourceRowsLength - input.rowEntries.length,
|
|
2417
|
-
pendingRows
|
|
2418
|
-
const merged = { ...entry.row };
|
|
2419
|
-
for (const [field, value] of Object.entries(
|
|
2420
|
-
persistedRowsByKey.get(entry.key) ?? {},
|
|
2421
|
-
)) {
|
|
2422
|
-
if (
|
|
2423
|
-
value !== null ||
|
|
2424
|
-
!Object.prototype.hasOwnProperty.call(merged, field)
|
|
2425
|
-
) {
|
|
2426
|
-
merged[field] = value;
|
|
2427
|
-
}
|
|
2428
|
-
}
|
|
2429
|
-
return {
|
|
2430
|
-
...merged,
|
|
2431
|
-
__deeplineRowKey: entry.key,
|
|
2432
|
-
};
|
|
2433
|
-
}),
|
|
2441
|
+
pendingRows,
|
|
2434
2442
|
completedRows: [],
|
|
2435
2443
|
tableNamespace: input.tableNamespace,
|
|
2436
2444
|
};
|
|
@@ -3289,7 +3297,7 @@ export async function startRuntimeSheetDataset(
|
|
|
3289
3297
|
.map((column) => `payload -> ${quoteLiteral(column)}`)
|
|
3290
3298
|
.join(', ')}`
|
|
3291
3299
|
: '';
|
|
3292
|
-
const outputPhysicalColumns =
|
|
3300
|
+
const outputPhysicalColumns = outputPhysicalSheetColumnProjections(
|
|
3293
3301
|
input.sheetContract,
|
|
3294
3302
|
);
|
|
3295
3303
|
const normalizedPlayName = normalizePlayNameForSheet(playName);
|
|
@@ -4271,9 +4279,7 @@ export async function readRuntimeSheetDatasetRowKeys(
|
|
|
4271
4279
|
): Promise<{ keys: string[] }> {
|
|
4272
4280
|
const keys = [
|
|
4273
4281
|
...new Set(
|
|
4274
|
-
input.keys
|
|
4275
|
-
.map((key) => key.trim())
|
|
4276
|
-
.filter((key) => key.length > 0),
|
|
4282
|
+
input.keys.map((key) => key.trim()).filter((key) => key.length > 0),
|
|
4277
4283
|
),
|
|
4278
4284
|
];
|
|
4279
4285
|
if (keys.length === 0) {
|
package/dist/cli/index.js
CHANGED
|
@@ -622,10 +622,10 @@ var SDK_RELEASE = {
|
|
|
622
622
|
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
623
623
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
624
624
|
// fields shipped in 0.1.153.
|
|
625
|
-
version: "0.1.
|
|
625
|
+
version: "0.1.167",
|
|
626
626
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
627
627
|
supportPolicy: {
|
|
628
|
-
latest: "0.1.
|
|
628
|
+
latest: "0.1.167",
|
|
629
629
|
minimumSupported: "0.1.53",
|
|
630
630
|
deprecatedBelow: "0.1.53",
|
|
631
631
|
commandMinimumSupported: [
|
|
@@ -749,8 +749,8 @@ function isCoworkLikeSandbox2() {
|
|
|
749
749
|
const projectDir = Boolean(process.env.CLAUDE_PROJECT_DIR?.trim());
|
|
750
750
|
const pluginRoot = Boolean(process.env.DEEPLINE_PLUGIN_ROOT?.trim());
|
|
751
751
|
const home = process.env.HOME?.trim() || (0, import_node_os2.homedir)();
|
|
752
|
-
const sessionHome = home.startsWith("/sessions/");
|
|
753
|
-
return (pluginMode || pluginRoot) &&
|
|
752
|
+
const sessionHome = home === "/sessions" || home.startsWith("/sessions/");
|
|
753
|
+
return claudeRemote || sessionHome || (pluginMode || pluginRoot) && projectDir;
|
|
754
754
|
}
|
|
755
755
|
function detectAgentRuntime(options = {}) {
|
|
756
756
|
const explicit = normalizeAgentRuntime(process.env.DEEPLINE_AGENT_RUNTIME);
|
|
@@ -4419,10 +4419,11 @@ function sleep3(ms) {
|
|
|
4419
4419
|
return new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
|
|
4420
4420
|
}
|
|
4421
4421
|
function collectLocalEnvInfo() {
|
|
4422
|
+
const homeDir2 = process.env.HOME?.trim() || (0, import_node_os5.homedir)();
|
|
4422
4423
|
const info = {
|
|
4423
4424
|
os: `${process.platform} ${process.arch}`,
|
|
4424
4425
|
node_version: process.version,
|
|
4425
|
-
home_dir:
|
|
4426
|
+
home_dir: homeDir2,
|
|
4426
4427
|
agent_runtime: detectAgentRuntime()
|
|
4427
4428
|
};
|
|
4428
4429
|
const env = process.env;
|
|
@@ -4442,7 +4443,7 @@ function collectLocalEnvInfo() {
|
|
|
4442
4443
|
if (env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim()) {
|
|
4443
4444
|
info.deepline_plugin_skills_dir_present = "true";
|
|
4444
4445
|
}
|
|
4445
|
-
if (info.home_dir.startsWith("/sessions/")) {
|
|
4446
|
+
if (info.home_dir === "/sessions" || info.home_dir.startsWith("/sessions/")) {
|
|
4446
4447
|
info.home_scope = "sessions";
|
|
4447
4448
|
}
|
|
4448
4449
|
return info;
|
|
@@ -4707,6 +4708,27 @@ function clearPendingClaimToken(baseUrl) {
|
|
|
4707
4708
|
} catch {
|
|
4708
4709
|
}
|
|
4709
4710
|
}
|
|
4711
|
+
function parseRegisterWaitMode(args) {
|
|
4712
|
+
let mode = "auto";
|
|
4713
|
+
for (let i = 0; i < args.length; i++) {
|
|
4714
|
+
if (args[i] === "--no-wait") {
|
|
4715
|
+
mode = "no";
|
|
4716
|
+
} else if (args[i] === "--wait" && args[i + 1]) {
|
|
4717
|
+
const value = args[++i].trim().toLowerCase();
|
|
4718
|
+
if (value === "auto" || value === "yes" || value === "no") {
|
|
4719
|
+
mode = value;
|
|
4720
|
+
} else {
|
|
4721
|
+
throw new Error("--wait must be one of: auto, yes, no");
|
|
4722
|
+
}
|
|
4723
|
+
}
|
|
4724
|
+
}
|
|
4725
|
+
return mode;
|
|
4726
|
+
}
|
|
4727
|
+
function shouldWaitForRegisterClaim(mode) {
|
|
4728
|
+
if (mode === "yes") return true;
|
|
4729
|
+
if (mode === "no") return false;
|
|
4730
|
+
return detectAgentRuntime() !== "claude_cowork";
|
|
4731
|
+
}
|
|
4710
4732
|
function saveEnvValues(values, baseUrl) {
|
|
4711
4733
|
const filtered = {
|
|
4712
4734
|
...values[HOST_URL_ENV] ? { [HOST_URL_ENV]: values[HOST_URL_ENV] } : {},
|
|
@@ -4835,11 +4857,16 @@ async function handleRegister(args) {
|
|
|
4835
4857
|
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
4836
4858
|
let orgName = "";
|
|
4837
4859
|
let agentName = "";
|
|
4838
|
-
let
|
|
4860
|
+
let waitMode;
|
|
4861
|
+
try {
|
|
4862
|
+
waitMode = parseRegisterWaitMode(args);
|
|
4863
|
+
} catch (error) {
|
|
4864
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
4865
|
+
return 2;
|
|
4866
|
+
}
|
|
4839
4867
|
for (let i = 0; i < args.length; i++) {
|
|
4840
4868
|
if (args[i] === "--org-name" && args[i + 1]) orgName = args[++i];
|
|
4841
4869
|
else if (args[i] === "--agent-name" && args[i + 1]) agentName = args[++i];
|
|
4842
|
-
else if (args[i] === "--no-wait") noWait = true;
|
|
4843
4870
|
}
|
|
4844
4871
|
if (!agentName) {
|
|
4845
4872
|
try {
|
|
@@ -4881,7 +4908,7 @@ async function handleRegister(args) {
|
|
|
4881
4908
|
if (data.cli_message) {
|
|
4882
4909
|
console.log(String(data.cli_message));
|
|
4883
4910
|
}
|
|
4884
|
-
if (
|
|
4911
|
+
if (!shouldWaitForRegisterClaim(waitMode)) return EXIT_OK;
|
|
4885
4912
|
if (!claimToken) {
|
|
4886
4913
|
console.error("Missing claim token from register response.");
|
|
4887
4914
|
return EXIT_SERVER;
|
|
@@ -4949,7 +4976,7 @@ async function handleWait(args) {
|
|
|
4949
4976
|
console.log("Already connected.");
|
|
4950
4977
|
return EXIT_OK;
|
|
4951
4978
|
}
|
|
4952
|
-
console.error("No pending approval. Run: deepline auth register --no
|
|
4979
|
+
console.error("No pending approval. Run: deepline auth register --wait no");
|
|
4953
4980
|
return EXIT_AUTH;
|
|
4954
4981
|
}
|
|
4955
4982
|
const deadline = Date.now() + timeoutSeconds * 1e3;
|
|
@@ -5059,7 +5086,7 @@ async function handleStatus(args) {
|
|
|
5059
5086
|
...hostStatusPayload ?? { host: baseUrl },
|
|
5060
5087
|
status: "not connected",
|
|
5061
5088
|
connected: false,
|
|
5062
|
-
next: "deepline auth register --
|
|
5089
|
+
next: "deepline auth register --wait auto && deepline auth wait",
|
|
5063
5090
|
render: {
|
|
5064
5091
|
sections: [
|
|
5065
5092
|
{
|
|
@@ -5068,7 +5095,10 @@ async function handleStatus(args) {
|
|
|
5068
5095
|
}
|
|
5069
5096
|
],
|
|
5070
5097
|
actions: [
|
|
5071
|
-
{
|
|
5098
|
+
{
|
|
5099
|
+
label: "Register",
|
|
5100
|
+
command: "deepline auth register --wait auto"
|
|
5101
|
+
},
|
|
5072
5102
|
{ label: "Wait", command: "deepline auth wait" }
|
|
5073
5103
|
]
|
|
5074
5104
|
}
|
|
@@ -5092,7 +5122,7 @@ async function handleStatus(args) {
|
|
|
5092
5122
|
...hostStatusPayload ?? { host: baseUrl },
|
|
5093
5123
|
status: "unauthorized",
|
|
5094
5124
|
connected: false,
|
|
5095
|
-
next: "deepline auth register --
|
|
5125
|
+
next: "deepline auth register --wait auto && deepline auth wait",
|
|
5096
5126
|
render: {
|
|
5097
5127
|
sections: [
|
|
5098
5128
|
{
|
|
@@ -5101,7 +5131,10 @@ async function handleStatus(args) {
|
|
|
5101
5131
|
}
|
|
5102
5132
|
],
|
|
5103
5133
|
actions: [
|
|
5104
|
-
{
|
|
5134
|
+
{
|
|
5135
|
+
label: "Register",
|
|
5136
|
+
command: "deepline auth register --wait auto"
|
|
5137
|
+
},
|
|
5105
5138
|
{ label: "Wait", command: "deepline auth wait" }
|
|
5106
5139
|
]
|
|
5107
5140
|
}
|
|
@@ -5180,14 +5213,15 @@ function registerAuthCommands(program) {
|
|
|
5180
5213
|
`
|
|
5181
5214
|
Common commands:
|
|
5182
5215
|
deepline auth register
|
|
5183
|
-
deepline auth register --no
|
|
5216
|
+
deepline auth register --wait no
|
|
5184
5217
|
deepline auth wait --timeout 300
|
|
5185
5218
|
deepline auth status
|
|
5186
5219
|
deepline auth status --json
|
|
5187
5220
|
|
|
5188
5221
|
Notes:
|
|
5189
|
-
Registration
|
|
5190
|
-
or agent runs, then
|
|
5222
|
+
Registration uses --wait auto by default: it waits locally and returns after
|
|
5223
|
+
opening the approval page in Cowork. Use --wait no in CI or agent runs, then
|
|
5224
|
+
finish with deepline auth wait.
|
|
5191
5225
|
Auth status shows the target host and active workspace without printing secrets.
|
|
5192
5226
|
`
|
|
5193
5227
|
);
|
|
@@ -5197,26 +5231,27 @@ Notes:
|
|
|
5197
5231
|
"after",
|
|
5198
5232
|
`
|
|
5199
5233
|
Notes:
|
|
5200
|
-
Opens a browser approval page
|
|
5234
|
+
Opens a browser approval page. --wait auto waits locally and returns after
|
|
5235
|
+
opening the approval page in Cowork.
|
|
5201
5236
|
The saved API key is scoped to the selected workspace and host.
|
|
5202
5237
|
|
|
5203
5238
|
Examples:
|
|
5204
5239
|
deepline auth register
|
|
5205
5240
|
deepline auth register --org-name Acme --agent-name local-cli
|
|
5206
|
-
deepline auth register --no
|
|
5241
|
+
deepline auth register --wait no
|
|
5207
5242
|
`
|
|
5208
|
-
).option("--org-name <name>", "Workspace name to prefill").option("--agent-name <name>", "Agent name to register").option("--
|
|
5243
|
+
).option("--org-name <name>", "Workspace name to prefill").option("--agent-name <name>", "Agent name to register").option("--wait <mode>", "Wait mode: auto, yes, or no", "auto").option("--no-wait", "Alias for --wait no").action(async (options) => {
|
|
5209
5244
|
process.exitCode = await handleRegister([
|
|
5210
5245
|
...options.orgName ? ["--org-name", options.orgName] : [],
|
|
5211
5246
|
...options.agentName ? ["--agent-name", options.agentName] : [],
|
|
5212
|
-
...options.noWait || options.wait === false ? ["--
|
|
5247
|
+
...options.noWait || options.wait === false ? ["--wait", "no"] : ["--wait", String(options.wait ?? "auto")]
|
|
5213
5248
|
]);
|
|
5214
5249
|
});
|
|
5215
5250
|
auth.command("wait").description("Wait for a pending browser approval and save the API key.").addHelpText(
|
|
5216
5251
|
"after",
|
|
5217
5252
|
`
|
|
5218
5253
|
Notes:
|
|
5219
|
-
Completes a previous deepline auth register --
|
|
5254
|
+
Completes a previous deepline auth register --wait no flow.
|
|
5220
5255
|
Saves the approved API key into the host auth file.
|
|
5221
5256
|
|
|
5222
5257
|
Examples:
|
|
@@ -24252,6 +24287,9 @@ function sdkNpmGlobalInstallCommand() {
|
|
|
24252
24287
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
24253
24288
|
var attemptedSync = false;
|
|
24254
24289
|
function shouldSkipSkillsSync() {
|
|
24290
|
+
if (detectAgentRuntime() === "claude_cowork") {
|
|
24291
|
+
return true;
|
|
24292
|
+
}
|
|
24255
24293
|
const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
|
|
24256
24294
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
24257
24295
|
}
|
|
@@ -24477,6 +24515,7 @@ function runLegacySkillsCleanup() {
|
|
|
24477
24515
|
for (const candidate of candidates) {
|
|
24478
24516
|
const result = (0, import_node_child_process3.spawnSync)(candidate.command, candidate.args, {
|
|
24479
24517
|
stdio: "ignore",
|
|
24518
|
+
env: process.env,
|
|
24480
24519
|
shell: process.platform === "win32"
|
|
24481
24520
|
});
|
|
24482
24521
|
if (result.status === 0) return;
|