deepline 0.1.266 → 0.1.267
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/compat.ts +3 -1
- package/dist/bundling-sources/sdk/src/release.ts +63 -10
- package/dist/bundling-sources/sdk/src/version.ts +5 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +18 -6
- package/dist/bundling-sources/shared_libs/play-runtime/dataset-lifecycle-log.ts +30 -0
- package/dist/cli/index.js +121 -42
- package/dist/cli/index.mjs +121 -42
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +27 -3
- package/dist/index.mjs +27 -3
- package/package.json +3 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SDK_API_CONTRACT, SDK_VERSION } from './version.js';
|
|
1
|
+
import { SDK_API_CONTRACT, SDK_API_MAJOR, SDK_VERSION } from './version.js';
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
@@ -87,6 +87,7 @@ function compatibilityCacheKey(
|
|
|
87
87
|
baseUrl: baseUrl.replace(/\/$/, ''),
|
|
88
88
|
version: SDK_VERSION,
|
|
89
89
|
apiContract: SDK_API_CONTRACT,
|
|
90
|
+
apiMajor: SDK_API_MAJOR,
|
|
90
91
|
command: command?.trim() || null,
|
|
91
92
|
skillsVersion: skillsVersion ?? null,
|
|
92
93
|
});
|
|
@@ -186,6 +187,7 @@ export async function checkSdkCompatibility(
|
|
|
186
187
|
headers: {
|
|
187
188
|
'User-Agent': `deepline-ts-sdk/${SDK_VERSION}`,
|
|
188
189
|
'X-Deepline-SDK-Version': SDK_VERSION,
|
|
190
|
+
'X-Deepline-API-Major': String(SDK_API_MAJOR),
|
|
189
191
|
'X-Deepline-API-Contract': SDK_API_CONTRACT,
|
|
190
192
|
},
|
|
191
193
|
signal: controller.signal,
|
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Edit THIS file by hand only for deliberate release decisions:
|
|
14
14
|
* - minor/major version bumps (set `version`),
|
|
15
|
-
* -
|
|
15
|
+
* - API-major cutovers (set `contracts.api.currentMajor`; leave `version` to the
|
|
16
|
+
* publish-time patch selector),
|
|
16
17
|
* - support-window moves (`minimumSupported` / `deprecatedBelow`).
|
|
17
|
-
* The automation never touches
|
|
18
|
+
* The automation never touches API compatibility policy, `minimumSupported`, or
|
|
18
19
|
* `deprecatedBelow`.
|
|
19
20
|
*
|
|
20
21
|
* Everything else derives from these values:
|
|
@@ -35,6 +36,37 @@
|
|
|
35
36
|
|
|
36
37
|
export type SdkReleaseChannel = 'latest' | 'next' | 'beta';
|
|
37
38
|
|
|
39
|
+
/**
|
|
40
|
+
* The named public protocols. These are intentionally independent:
|
|
41
|
+
*
|
|
42
|
+
* - `api` is the HTTP SDK/CLI protocol. It is additive within a major.
|
|
43
|
+
* - `playArtifact` is the immutable client-bundled Play payload ABI.
|
|
44
|
+
* - `release` controls promotion/publishing; it is not a client protocol.
|
|
45
|
+
*
|
|
46
|
+
* Do not use an SDK package version or a date string as an artifact ABI.
|
|
47
|
+
*/
|
|
48
|
+
export type DeeplineContractPolicy = {
|
|
49
|
+
api: {
|
|
50
|
+
name: 'sdk-http-api';
|
|
51
|
+
currentMajor: number;
|
|
52
|
+
supportedMajors: readonly number[];
|
|
53
|
+
/** Transitional value for installed SDKs that only send the old header. */
|
|
54
|
+
legacyWireIds: readonly string[];
|
|
55
|
+
};
|
|
56
|
+
playArtifact: {
|
|
57
|
+
name: 'play-artifact-runtime';
|
|
58
|
+
currentVersion: number;
|
|
59
|
+
supportedVersions: readonly number[];
|
|
60
|
+
};
|
|
61
|
+
release: {
|
|
62
|
+
name: 'production-sdk-release';
|
|
63
|
+
/** npm may publish only from the active, healthy Production SHA. */
|
|
64
|
+
publishFrom: 'latest-successful-production-deployment';
|
|
65
|
+
/** A newer merge cancels an in-flight decision; reconciliation picks the last healthy SHA. */
|
|
66
|
+
coalesce: 'latest-healthy';
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
|
|
38
70
|
export type SdkSupportPolicy = {
|
|
39
71
|
/**
|
|
40
72
|
* Anything strictly below this returns `status: "unsupported"` from
|
|
@@ -57,6 +89,8 @@ export type SdkSupportPolicy = {
|
|
|
57
89
|
minimumSupported: string;
|
|
58
90
|
reason: string;
|
|
59
91
|
}>;
|
|
92
|
+
/** Previously published wire contracts that remain supported. */
|
|
93
|
+
compatibleApiContracts?: readonly string[];
|
|
60
94
|
/**
|
|
61
95
|
* Published package versions that must keep working for direct SDK tool
|
|
62
96
|
* callers. CI installs each package from npm and exercises `tools.get` and
|
|
@@ -77,12 +111,8 @@ export type SdkRelease = {
|
|
|
77
111
|
* publish time (auto-bump); edit by hand only for minor/major releases.
|
|
78
112
|
*/
|
|
79
113
|
version: string;
|
|
80
|
-
/**
|
|
81
|
-
|
|
82
|
-
* changes between the installed SDK/CLI and the Deepline backend.
|
|
83
|
-
* See `docs/sdk-runtime-compatibility.md`.
|
|
84
|
-
*/
|
|
85
|
-
apiContract: string;
|
|
114
|
+
/** Named compatibility policies. This is the only authored contract policy. */
|
|
115
|
+
contracts: DeeplineContractPolicy;
|
|
86
116
|
/** Public support policy reported by `/api/v2/sdk/compat`. */
|
|
87
117
|
supportPolicy: SdkSupportPolicy;
|
|
88
118
|
};
|
|
@@ -125,8 +155,31 @@ export const SDK_RELEASE = {
|
|
|
125
155
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
126
156
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
127
157
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
128
|
-
version: '0.1.
|
|
129
|
-
|
|
158
|
+
version: '0.1.267',
|
|
159
|
+
contracts: {
|
|
160
|
+
api: {
|
|
161
|
+
name: 'sdk-http-api',
|
|
162
|
+
// API v2 is append-only. A breaking public request/response change needs
|
|
163
|
+
// v3 and an explicit v2 support-window decision, never a patch release.
|
|
164
|
+
currentMajor: 2,
|
|
165
|
+
supportedMajors: [2],
|
|
166
|
+
// Accepted only to bridge SDKs released before X-Deepline-API-Major.
|
|
167
|
+
legacyWireIds: [
|
|
168
|
+
'2026-07-admin-cli-local-cutover',
|
|
169
|
+
'2026-07-native-monitor-launch-hard-cutover',
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
playArtifact: {
|
|
173
|
+
name: 'play-artifact-runtime',
|
|
174
|
+
currentVersion: 2,
|
|
175
|
+
supportedVersions: [1, 2],
|
|
176
|
+
},
|
|
177
|
+
release: {
|
|
178
|
+
name: 'production-sdk-release',
|
|
179
|
+
publishFrom: 'latest-successful-production-deployment',
|
|
180
|
+
coalesce: 'latest-healthy',
|
|
181
|
+
},
|
|
182
|
+
},
|
|
130
183
|
supportPolicy: {
|
|
131
184
|
minimumSupported: '0.1.53',
|
|
132
185
|
deprecatedBelow: '0.1.219',
|
|
@@ -3,4 +3,8 @@
|
|
|
3
3
|
import { SDK_RELEASE } from './release.js';
|
|
4
4
|
|
|
5
5
|
export const SDK_VERSION: string = SDK_RELEASE.version;
|
|
6
|
-
|
|
6
|
+
/** Numbered SDK HTTP API major sent by current SDK/CLI clients. */
|
|
7
|
+
export const SDK_API_MAJOR: number = SDK_RELEASE.contracts.api.currentMajor;
|
|
8
|
+
/** @deprecated Transitional wire id for pre-major-header SDKs only. */
|
|
9
|
+
export const SDK_API_CONTRACT: string =
|
|
10
|
+
SDK_RELEASE.contracts.api.legacyWireIds[0] ?? `api-v${SDK_API_MAJOR}`;
|
|
@@ -5432,13 +5432,13 @@ export class PlayContextImpl {
|
|
|
5432
5432
|
this.rowStates.get(idx)?.results.set(fieldName, cellValue);
|
|
5433
5433
|
const currentCellMeta =
|
|
5434
5434
|
this.activeMapCellMeta?.get(rowKey)?.[fieldName];
|
|
5435
|
-
const
|
|
5435
|
+
const currentCellRecord =
|
|
5436
5436
|
currentCellMeta &&
|
|
5437
5437
|
typeof currentCellMeta === 'object' &&
|
|
5438
|
-
!Array.isArray(currentCellMeta)
|
|
5439
|
-
|
|
5440
|
-
? (currentCellMeta as { status?: unknown }).status
|
|
5438
|
+
!Array.isArray(currentCellMeta)
|
|
5439
|
+
? (currentCellMeta as { status?: unknown; reused?: unknown })
|
|
5441
5440
|
: null;
|
|
5441
|
+
const currentCellStatus = currentCellRecord?.status ?? null;
|
|
5442
5442
|
if (currentCellStatus === 'skipped') {
|
|
5443
5443
|
if (
|
|
5444
5444
|
shouldPersistMapCellField(fieldName) &&
|
|
@@ -5455,13 +5455,25 @@ export class PlayContextImpl {
|
|
|
5455
5455
|
}
|
|
5456
5456
|
continue;
|
|
5457
5457
|
}
|
|
5458
|
+
// A cell whose underlying durable work was fully satisfied from
|
|
5459
|
+
// content-addressed receipts recorded a `cached`/`reused` cell-meta
|
|
5460
|
+
// marker while the body ran (see resolveRequestsFromReceipt). Emitting
|
|
5461
|
+
// an unconditional `completed` here would clobber that marker to a
|
|
5462
|
+
// non-reused `completed`, so the run's per-column `cached` counter
|
|
5463
|
+
// reads 0 on a full-reuse rerun even though provider spend was 0.
|
|
5464
|
+
// Preserve the reuse signal so `columnStats.cached` reflects real
|
|
5465
|
+
// receipt reuse consistent with the near-zero provider spend.
|
|
5466
|
+
const cellWasReused =
|
|
5467
|
+
currentCellStatus === 'cached' &&
|
|
5468
|
+
currentCellRecord?.reused === true;
|
|
5458
5469
|
this.emitScopedFieldMetaUpdate({
|
|
5459
5470
|
rowId: idx,
|
|
5460
5471
|
key: rowKey,
|
|
5461
5472
|
tableNamespace: normalizedTableNamespace,
|
|
5462
5473
|
fieldName,
|
|
5463
|
-
status: 'completed',
|
|
5464
|
-
stage: 'completed',
|
|
5474
|
+
status: cellWasReused ? 'cached' : 'completed',
|
|
5475
|
+
stage: cellWasReused ? 'cached' : 'completed',
|
|
5476
|
+
...(cellWasReused ? { reused: true } : {}),
|
|
5465
5477
|
completedAt: Date.now(),
|
|
5466
5478
|
dataPatch: shouldPersistMapCellField(fieldName)
|
|
5467
5479
|
? { [fieldName]: cellValue }
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type DatasetLogIdentity = {
|
|
2
|
+
path: string;
|
|
3
|
+
tableNamespace: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Dataset paths identify runtime state. They are not CLI export selectors: a
|
|
8
|
+
* returned result field (for example `result.rows`) is the supported export
|
|
9
|
+
* handle. Keep this distinction explicit in operator logs.
|
|
10
|
+
*/
|
|
11
|
+
export function formatDatasetRegistrationLog(input: {
|
|
12
|
+
dataset: DatasetLogIdentity;
|
|
13
|
+
rows: number;
|
|
14
|
+
}): string {
|
|
15
|
+
if (input.rows === 0) {
|
|
16
|
+
return `Dataset ${input.dataset.path} registered (0 rows); export unavailable: empty dataset`;
|
|
17
|
+
}
|
|
18
|
+
return `Dataset ${input.dataset.path} registered (${input.rows} rows); awaiting terminal persistence`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function formatDatasetAvailabilityLog(input: {
|
|
22
|
+
runId: string;
|
|
23
|
+
dataset: DatasetLogIdentity;
|
|
24
|
+
persistedRows: number;
|
|
25
|
+
}): string {
|
|
26
|
+
if (input.persistedRows === 0) {
|
|
27
|
+
return `Dataset ${input.dataset.path} available: 0 persisted rows; export unavailable: empty dataset`;
|
|
28
|
+
}
|
|
29
|
+
return `Dataset ${input.dataset.path} available: ${input.persistedRows} persisted rows; inspect deepline runs get ${input.runId} --full --json for the verified export action`;
|
|
30
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -718,8 +718,31 @@ var SDK_RELEASE = {
|
|
|
718
718
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
719
719
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
720
720
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
721
|
-
version: "0.1.
|
|
722
|
-
|
|
721
|
+
version: "0.1.267",
|
|
722
|
+
contracts: {
|
|
723
|
+
api: {
|
|
724
|
+
name: "sdk-http-api",
|
|
725
|
+
// API v2 is append-only. A breaking public request/response change needs
|
|
726
|
+
// v3 and an explicit v2 support-window decision, never a patch release.
|
|
727
|
+
currentMajor: 2,
|
|
728
|
+
supportedMajors: [2],
|
|
729
|
+
// Accepted only to bridge SDKs released before X-Deepline-API-Major.
|
|
730
|
+
legacyWireIds: [
|
|
731
|
+
"2026-07-admin-cli-local-cutover",
|
|
732
|
+
"2026-07-native-monitor-launch-hard-cutover"
|
|
733
|
+
]
|
|
734
|
+
},
|
|
735
|
+
playArtifact: {
|
|
736
|
+
name: "play-artifact-runtime",
|
|
737
|
+
currentVersion: 2,
|
|
738
|
+
supportedVersions: [1, 2]
|
|
739
|
+
},
|
|
740
|
+
release: {
|
|
741
|
+
name: "production-sdk-release",
|
|
742
|
+
publishFrom: "latest-successful-production-deployment",
|
|
743
|
+
coalesce: "latest-healthy"
|
|
744
|
+
}
|
|
745
|
+
},
|
|
723
746
|
supportPolicy: {
|
|
724
747
|
minimumSupported: "0.1.53",
|
|
725
748
|
deprecatedBelow: "0.1.219",
|
|
@@ -816,7 +839,8 @@ var SDK_RELEASE = {
|
|
|
816
839
|
|
|
817
840
|
// src/version.ts
|
|
818
841
|
var SDK_VERSION = SDK_RELEASE.version;
|
|
819
|
-
var
|
|
842
|
+
var SDK_API_MAJOR = SDK_RELEASE.contracts.api.currentMajor;
|
|
843
|
+
var SDK_API_CONTRACT = SDK_RELEASE.contracts.api.legacyWireIds[0] ?? `api-v${SDK_API_MAJOR}`;
|
|
820
844
|
|
|
821
845
|
// src/agent-runtime.ts
|
|
822
846
|
var import_node_os2 = require("os");
|
|
@@ -4838,6 +4862,7 @@ function compatibilityCacheKey(baseUrl, command, skillsVersion) {
|
|
|
4838
4862
|
baseUrl: baseUrl.replace(/\/$/, ""),
|
|
4839
4863
|
version: SDK_VERSION,
|
|
4840
4864
|
apiContract: SDK_API_CONTRACT,
|
|
4865
|
+
apiMajor: SDK_API_MAJOR,
|
|
4841
4866
|
command: command?.trim() || null,
|
|
4842
4867
|
skillsVersion: skillsVersion ?? null
|
|
4843
4868
|
});
|
|
@@ -4906,6 +4931,7 @@ async function checkSdkCompatibility(baseUrl, options = {}) {
|
|
|
4906
4931
|
headers: {
|
|
4907
4932
|
"User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
|
|
4908
4933
|
"X-Deepline-SDK-Version": SDK_VERSION,
|
|
4934
|
+
"X-Deepline-API-Major": String(SDK_API_MAJOR),
|
|
4909
4935
|
"X-Deepline-API-Contract": SDK_API_CONTRACT
|
|
4910
4936
|
},
|
|
4911
4937
|
signal: controller.signal
|
|
@@ -5284,26 +5310,29 @@ function browserOpeningDisabled() {
|
|
|
5284
5310
|
).trim().toLowerCase();
|
|
5285
5311
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
5286
5312
|
}
|
|
5287
|
-
function openInBrowser(url) {
|
|
5313
|
+
function openInBrowser(url, options = {}) {
|
|
5288
5314
|
try {
|
|
5289
|
-
if (browserOpeningDisabled()) return;
|
|
5315
|
+
if (browserOpeningDisabled()) return "failed";
|
|
5290
5316
|
const targetUrl = String(url || "").trim();
|
|
5291
|
-
if (!targetUrl) return;
|
|
5292
|
-
if (!claimBrowserOpen(Date.now(), void 0, targetUrl))
|
|
5317
|
+
if (!targetUrl) return "failed";
|
|
5318
|
+
if (options.deduplicate !== false && !claimBrowserOpen(Date.now(), void 0, targetUrl)) {
|
|
5319
|
+
return "suppressed";
|
|
5320
|
+
}
|
|
5293
5321
|
const allowFocus = true;
|
|
5294
5322
|
if (process.platform === "darwin") {
|
|
5295
|
-
openUrlMacos(targetUrl, allowFocus);
|
|
5296
|
-
return;
|
|
5323
|
+
return openUrlMacos(targetUrl, allowFocus) ? "opened" : "failed";
|
|
5297
5324
|
}
|
|
5298
|
-
if (!allowFocus) return;
|
|
5325
|
+
if (!allowFocus) return "failed";
|
|
5299
5326
|
if (process.platform === "win32") {
|
|
5300
5327
|
childProcess.execFileSync("cmd.exe", ["/c", "start", "", targetUrl], {
|
|
5301
5328
|
stdio: "ignore"
|
|
5302
5329
|
});
|
|
5303
|
-
return;
|
|
5330
|
+
return "opened";
|
|
5304
5331
|
}
|
|
5305
5332
|
childProcess.execFileSync("xdg-open", [targetUrl], { stdio: "ignore" });
|
|
5333
|
+
return "opened";
|
|
5306
5334
|
} catch {
|
|
5335
|
+
return "failed";
|
|
5307
5336
|
}
|
|
5308
5337
|
}
|
|
5309
5338
|
function sleep3(ms) {
|
|
@@ -29514,6 +29543,18 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint) {
|
|
|
29514
29543
|
const prefix = normalized.startsWith("/") && prefixParts[0] !== "" ? `/${prefixParts.join("/")}` : prefixParts.join("/");
|
|
29515
29544
|
return prefix || null;
|
|
29516
29545
|
}
|
|
29546
|
+
function isHomebrewFormulaEntrypoint(entrypoint) {
|
|
29547
|
+
const normalized = (() => {
|
|
29548
|
+
try {
|
|
29549
|
+
return (0, import_node_fs17.realpathSync)(entrypoint);
|
|
29550
|
+
} catch {
|
|
29551
|
+
return (0, import_node_path19.resolve)(entrypoint);
|
|
29552
|
+
}
|
|
29553
|
+
})();
|
|
29554
|
+
const parts = normalized.split(/[\\/]+/);
|
|
29555
|
+
const cellarIndex = parts.lastIndexOf("Cellar");
|
|
29556
|
+
return cellarIndex >= 0 && parts[cellarIndex + 1] === "deepline" && parts.slice(cellarIndex + 3).includes("libexec");
|
|
29557
|
+
}
|
|
29517
29558
|
function resolveUpdatePlan(options = {}) {
|
|
29518
29559
|
const env = options.env ?? process.env;
|
|
29519
29560
|
const homeDir2 = options.homeDir ?? (0, import_node_os14.homedir)();
|
|
@@ -29526,6 +29567,12 @@ function resolveUpdatePlan(options = {}) {
|
|
|
29526
29567
|
manualCommand: buildSourceUpdateCommand(sourceRoot)
|
|
29527
29568
|
};
|
|
29528
29569
|
}
|
|
29570
|
+
if (entrypoint && isHomebrewFormulaEntrypoint(entrypoint)) {
|
|
29571
|
+
return {
|
|
29572
|
+
kind: "homebrew",
|
|
29573
|
+
manualCommand: "brew upgrade deepline"
|
|
29574
|
+
};
|
|
29575
|
+
}
|
|
29529
29576
|
const sidecarPlan = resolvePythonSidecarUpdatePlan({
|
|
29530
29577
|
entrypoint,
|
|
29531
29578
|
env,
|
|
@@ -29557,7 +29604,7 @@ function resolveUpdatePlan(options = {}) {
|
|
|
29557
29604
|
}
|
|
29558
29605
|
var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
|
|
29559
29606
|
function autoUpdateFailurePath(plan) {
|
|
29560
|
-
if (plan.kind === "source") return null;
|
|
29607
|
+
if (plan.kind === "source" || plan.kind === "homebrew") return null;
|
|
29561
29608
|
if (plan.kind === "python-sidecar") {
|
|
29562
29609
|
return (0, import_node_path19.join)(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
|
|
29563
29610
|
}
|
|
@@ -29570,7 +29617,7 @@ function autoUpdateFailurePath(plan) {
|
|
|
29570
29617
|
);
|
|
29571
29618
|
}
|
|
29572
29619
|
function autoUpdatePackageSpec(plan) {
|
|
29573
|
-
if (plan.kind === "source") return "";
|
|
29620
|
+
if (plan.kind === "source" || plan.kind === "homebrew") return "";
|
|
29574
29621
|
if (plan.kind === "python-sidecar") return plan.packageSpec;
|
|
29575
29622
|
return plan.args[plan.args.length - 1] ?? plan.manualCommand;
|
|
29576
29623
|
}
|
|
@@ -29591,7 +29638,7 @@ function readAutoUpdateFailure(plan) {
|
|
|
29591
29638
|
}
|
|
29592
29639
|
function writeAutoUpdateFailure(plan, exitCode) {
|
|
29593
29640
|
const path = autoUpdateFailurePath(plan);
|
|
29594
|
-
if (!path || plan.kind === "source") return;
|
|
29641
|
+
if (!path || plan.kind === "source" || plan.kind === "homebrew") return;
|
|
29595
29642
|
const marker = {
|
|
29596
29643
|
kind: plan.kind,
|
|
29597
29644
|
packageSpec: autoUpdatePackageSpec(plan),
|
|
@@ -29616,7 +29663,9 @@ function clearAutoUpdateFailure(plan) {
|
|
|
29616
29663
|
}
|
|
29617
29664
|
function matchingAutoUpdateFailure(plan) {
|
|
29618
29665
|
const marker = readAutoUpdateFailure(plan);
|
|
29619
|
-
if (!marker || plan.kind === "source")
|
|
29666
|
+
if (!marker || plan.kind === "source" || plan.kind === "homebrew") {
|
|
29667
|
+
return null;
|
|
29668
|
+
}
|
|
29620
29669
|
if (marker.kind !== plan.kind) return null;
|
|
29621
29670
|
if (marker.packageSpec !== autoUpdatePackageSpec(plan)) return null;
|
|
29622
29671
|
return marker;
|
|
@@ -29874,6 +29923,8 @@ async function runUpdatePlan(plan) {
|
|
|
29874
29923
|
});
|
|
29875
29924
|
} else if (plan.kind === "python-sidecar") {
|
|
29876
29925
|
exitCode = await runPythonSidecarUpdatePlan(plan);
|
|
29926
|
+
} else if (plan.kind === "homebrew") {
|
|
29927
|
+
exitCode = 0;
|
|
29877
29928
|
}
|
|
29878
29929
|
if (exitCode === 0) {
|
|
29879
29930
|
clearAutoUpdateFailure(plan);
|
|
@@ -29912,6 +29963,9 @@ async function runUpdateCommand(options, dependencies = {}) {
|
|
|
29912
29963
|
lines: plan.kind === "source" ? [
|
|
29913
29964
|
"This Deepline CLI is running from SDK source, so it cannot safely update itself like an npm global.",
|
|
29914
29965
|
`Update the backing checkout with: ${plan.manualCommand}`
|
|
29966
|
+
] : plan.kind === "homebrew" ? [
|
|
29967
|
+
"This Deepline CLI was installed by Homebrew, which owns its upgrades.",
|
|
29968
|
+
`Update it with: ${plan.manualCommand}`
|
|
29915
29969
|
] : plan.kind === "python-sidecar" ? [
|
|
29916
29970
|
"This Deepline CLI is running from the Python-managed SDK sidecar.",
|
|
29917
29971
|
"Updating will refresh that sidecar, not a global npm binary."
|
|
@@ -29936,7 +29990,7 @@ async function runUpdateCommand(options, dependencies = {}) {
|
|
|
29936
29990
|
);
|
|
29937
29991
|
return 0;
|
|
29938
29992
|
}
|
|
29939
|
-
if (plan.kind === "source") {
|
|
29993
|
+
if (plan.kind === "source" || plan.kind === "homebrew") {
|
|
29940
29994
|
printCommandEnvelope({ ...plan, render }, { json: false });
|
|
29941
29995
|
return 0;
|
|
29942
29996
|
}
|
|
@@ -29955,6 +30009,8 @@ function registerUpdateCommand(program) {
|
|
|
29955
30009
|
`
|
|
29956
30010
|
Notes:
|
|
29957
30011
|
For the published npm CLI, this runs npm install -g deepline@latest.
|
|
30012
|
+
For a Homebrew installation, this prints brew upgrade deepline; Homebrew
|
|
30013
|
+
owns formula upgrades and Deepline never runs npm inside its Cellar.
|
|
29958
30014
|
For Python-managed SDK sidecars, this refreshes the sidecar that launched
|
|
29959
30015
|
the current SDK CLI instead of changing a global npm binary.
|
|
29960
30016
|
For repo-backed SDK wrappers such as cli-env sdk-prod or sdk-worktree, this
|
|
@@ -30074,14 +30130,37 @@ function resolveScopeRoot(scope) {
|
|
|
30074
30130
|
function authScopeForSetup(scope) {
|
|
30075
30131
|
return scope === "local" ? "folder" : "global";
|
|
30076
30132
|
}
|
|
30077
|
-
function shouldOpenSetupAuthorization(runtime = detectAgentRuntime()) {
|
|
30078
|
-
return runtime !== "claude_cowork";
|
|
30079
|
-
}
|
|
30080
30133
|
function openSetupAuthorization(authorizationUrl, options = {}) {
|
|
30081
30134
|
const url = authorizationUrl.trim();
|
|
30082
|
-
if (!url
|
|
30083
|
-
(options.open
|
|
30084
|
-
|
|
30135
|
+
if (!url) return "failed";
|
|
30136
|
+
if (options.open) return options.open(url);
|
|
30137
|
+
const result = openInBrowser(url, { deduplicate: false });
|
|
30138
|
+
return result === "opened" ? "opened" : "failed";
|
|
30139
|
+
}
|
|
30140
|
+
function buildPendingAuthorizationOutput(input2) {
|
|
30141
|
+
const authorizationUrl = input2.authorizationUrl.trim();
|
|
30142
|
+
if (input2.browserOpenStatus === "opened") {
|
|
30143
|
+
return {
|
|
30144
|
+
authorizationUrl: null,
|
|
30145
|
+
next: `Complete browser approval, then run: ${input2.resumeCommand}`,
|
|
30146
|
+
lines: ["Complete authorization in the browser window Deepline opened."]
|
|
30147
|
+
};
|
|
30148
|
+
}
|
|
30149
|
+
if (authorizationUrl) {
|
|
30150
|
+
return {
|
|
30151
|
+
authorizationUrl,
|
|
30152
|
+
next: `Open the authorization URL, approve it, then run: ${input2.resumeCommand}`,
|
|
30153
|
+
lines: [
|
|
30154
|
+
"Browser launch failed. Open the authorization URL to continue.",
|
|
30155
|
+
authorizationUrl
|
|
30156
|
+
]
|
|
30157
|
+
};
|
|
30158
|
+
}
|
|
30159
|
+
return {
|
|
30160
|
+
authorizationUrl: null,
|
|
30161
|
+
next: `Authorization is pending without a browser URL. Retry: ${input2.resumeCommand}`,
|
|
30162
|
+
lines: ["Authorization is pending, but no browser URL was returned."]
|
|
30163
|
+
};
|
|
30085
30164
|
}
|
|
30086
30165
|
function setupStatePath(baseUrl, scope, root) {
|
|
30087
30166
|
return scope === "local" && root ? (0, import_node_path20.join)(root, ".deepline", "setup", "state.json") : (0, import_node_path20.join)(sdkCliStateDirPath(baseUrl), "setup.json");
|
|
@@ -30111,15 +30190,6 @@ function parseCapturedJson(stdout) {
|
|
|
30111
30190
|
function asRecord2(value) {
|
|
30112
30191
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
30113
30192
|
}
|
|
30114
|
-
function printCapturedAuthorizationUrl(stdout) {
|
|
30115
|
-
const urls = stdout.match(/https:\/\/[^\s]+/g) ?? [];
|
|
30116
|
-
for (const url of new Set(
|
|
30117
|
-
urls.map((value) => value.replace(/[).,]+$/, ""))
|
|
30118
|
-
)) {
|
|
30119
|
-
process.stderr.write(`Authorize Deepline: ${url}
|
|
30120
|
-
`);
|
|
30121
|
-
}
|
|
30122
|
-
}
|
|
30123
30193
|
function safeRead(path) {
|
|
30124
30194
|
try {
|
|
30125
30195
|
return (0, import_node_fs18.readFileSync)(path, "utf8");
|
|
@@ -30458,18 +30528,32 @@ function pendingResult(input2) {
|
|
|
30458
30528
|
status: "authorization_pending",
|
|
30459
30529
|
phases: input2.phases
|
|
30460
30530
|
});
|
|
30531
|
+
let browserOpenStatus = "failed";
|
|
30461
30532
|
if (input2.authorizationUrl) {
|
|
30462
|
-
openSetupAuthorization(input2.authorizationUrl);
|
|
30463
|
-
|
|
30533
|
+
browserOpenStatus = openSetupAuthorization(input2.authorizationUrl);
|
|
30534
|
+
if (browserOpenStatus === "opened") {
|
|
30535
|
+
process.stderr.write(
|
|
30536
|
+
"Opened Deepline authorization in your browser. Complete approval there.\n"
|
|
30537
|
+
);
|
|
30538
|
+
} else if (browserOpenStatus === "failed") {
|
|
30539
|
+
process.stderr.write(`Authorize Deepline: ${input2.authorizationUrl}
|
|
30464
30540
|
`);
|
|
30541
|
+
}
|
|
30465
30542
|
}
|
|
30543
|
+
const pendingOutput = buildPendingAuthorizationOutput({
|
|
30544
|
+
authorizationUrl: input2.authorizationUrl,
|
|
30545
|
+
browserOpenStatus,
|
|
30546
|
+
resumeCommand: setupResumeCommand(input2.baseUrl, input2.scope)
|
|
30547
|
+
});
|
|
30466
30548
|
printCommandEnvelope(
|
|
30467
30549
|
{
|
|
30468
30550
|
ok: true,
|
|
30469
30551
|
status: "authorization_pending",
|
|
30470
30552
|
complete: false,
|
|
30471
30553
|
scope: input2.scope,
|
|
30472
|
-
authorizationUrl:
|
|
30554
|
+
authorizationUrl: pendingOutput.authorizationUrl,
|
|
30555
|
+
browserOpened: browserOpenStatus === "opened",
|
|
30556
|
+
browserOpenStatus,
|
|
30473
30557
|
statePath,
|
|
30474
30558
|
phases: input2.phases,
|
|
30475
30559
|
currentPhase: "auth",
|
|
@@ -30479,15 +30563,12 @@ function pendingResult(input2) {
|
|
|
30479
30563
|
scope: input2.scope,
|
|
30480
30564
|
phase: "auth"
|
|
30481
30565
|
}),
|
|
30482
|
-
next:
|
|
30566
|
+
next: pendingOutput.next,
|
|
30483
30567
|
render: {
|
|
30484
30568
|
sections: [
|
|
30485
30569
|
{
|
|
30486
30570
|
title: "setup",
|
|
30487
|
-
lines:
|
|
30488
|
-
"Authorization is waiting for browser approval.",
|
|
30489
|
-
...input2.authorizationUrl ? [input2.authorizationUrl] : []
|
|
30490
|
-
]
|
|
30571
|
+
lines: pendingOutput.lines
|
|
30491
30572
|
}
|
|
30492
30573
|
]
|
|
30493
30574
|
}
|
|
@@ -30656,10 +30737,9 @@ async function runSetupCommand(options) {
|
|
|
30656
30737
|
const pending = readPendingAuthClaim(baseUrl, authScope);
|
|
30657
30738
|
if (pending) {
|
|
30658
30739
|
process.stderr.write("Checking pending Deepline authorization...\n");
|
|
30659
|
-
|
|
30740
|
+
await captureStdout2(
|
|
30660
30741
|
() => handleWait(["--timeout", "1", "--auth-scope", authScope])
|
|
30661
30742
|
);
|
|
30662
|
-
printCapturedAuthorizationUrl(waited.stdout);
|
|
30663
30743
|
auth = await readAuthStatus(authScope);
|
|
30664
30744
|
const resumedAuthFailure = reportSetupAuthStatusFailure({
|
|
30665
30745
|
auth,
|
|
@@ -30695,7 +30775,6 @@ async function runSetupCommand(options) {
|
|
|
30695
30775
|
const registered = await captureStdout2(
|
|
30696
30776
|
() => handleRegister(["--wait", waitMode, "--auth-scope", authScope])
|
|
30697
30777
|
);
|
|
30698
|
-
printCapturedAuthorizationUrl(registered.stdout);
|
|
30699
30778
|
if (registered.exitCode !== 0) {
|
|
30700
30779
|
return reportSetupPhaseFailure({
|
|
30701
30780
|
baseUrl,
|
package/dist/cli/index.mjs
CHANGED
|
@@ -703,8 +703,31 @@ var SDK_RELEASE = {
|
|
|
703
703
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
704
704
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
705
705
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
706
|
-
version: "0.1.
|
|
707
|
-
|
|
706
|
+
version: "0.1.267",
|
|
707
|
+
contracts: {
|
|
708
|
+
api: {
|
|
709
|
+
name: "sdk-http-api",
|
|
710
|
+
// API v2 is append-only. A breaking public request/response change needs
|
|
711
|
+
// v3 and an explicit v2 support-window decision, never a patch release.
|
|
712
|
+
currentMajor: 2,
|
|
713
|
+
supportedMajors: [2],
|
|
714
|
+
// Accepted only to bridge SDKs released before X-Deepline-API-Major.
|
|
715
|
+
legacyWireIds: [
|
|
716
|
+
"2026-07-admin-cli-local-cutover",
|
|
717
|
+
"2026-07-native-monitor-launch-hard-cutover"
|
|
718
|
+
]
|
|
719
|
+
},
|
|
720
|
+
playArtifact: {
|
|
721
|
+
name: "play-artifact-runtime",
|
|
722
|
+
currentVersion: 2,
|
|
723
|
+
supportedVersions: [1, 2]
|
|
724
|
+
},
|
|
725
|
+
release: {
|
|
726
|
+
name: "production-sdk-release",
|
|
727
|
+
publishFrom: "latest-successful-production-deployment",
|
|
728
|
+
coalesce: "latest-healthy"
|
|
729
|
+
}
|
|
730
|
+
},
|
|
708
731
|
supportPolicy: {
|
|
709
732
|
minimumSupported: "0.1.53",
|
|
710
733
|
deprecatedBelow: "0.1.219",
|
|
@@ -801,7 +824,8 @@ var SDK_RELEASE = {
|
|
|
801
824
|
|
|
802
825
|
// src/version.ts
|
|
803
826
|
var SDK_VERSION = SDK_RELEASE.version;
|
|
804
|
-
var
|
|
827
|
+
var SDK_API_MAJOR = SDK_RELEASE.contracts.api.currentMajor;
|
|
828
|
+
var SDK_API_CONTRACT = SDK_RELEASE.contracts.api.legacyWireIds[0] ?? `api-v${SDK_API_MAJOR}`;
|
|
805
829
|
|
|
806
830
|
// src/agent-runtime.ts
|
|
807
831
|
import { homedir as homedir2 } from "os";
|
|
@@ -4823,6 +4847,7 @@ function compatibilityCacheKey(baseUrl, command, skillsVersion) {
|
|
|
4823
4847
|
baseUrl: baseUrl.replace(/\/$/, ""),
|
|
4824
4848
|
version: SDK_VERSION,
|
|
4825
4849
|
apiContract: SDK_API_CONTRACT,
|
|
4850
|
+
apiMajor: SDK_API_MAJOR,
|
|
4826
4851
|
command: command?.trim() || null,
|
|
4827
4852
|
skillsVersion: skillsVersion ?? null
|
|
4828
4853
|
});
|
|
@@ -4891,6 +4916,7 @@ async function checkSdkCompatibility(baseUrl, options = {}) {
|
|
|
4891
4916
|
headers: {
|
|
4892
4917
|
"User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
|
|
4893
4918
|
"X-Deepline-SDK-Version": SDK_VERSION,
|
|
4919
|
+
"X-Deepline-API-Major": String(SDK_API_MAJOR),
|
|
4894
4920
|
"X-Deepline-API-Contract": SDK_API_CONTRACT
|
|
4895
4921
|
},
|
|
4896
4922
|
signal: controller.signal
|
|
@@ -5281,26 +5307,29 @@ function browserOpeningDisabled() {
|
|
|
5281
5307
|
).trim().toLowerCase();
|
|
5282
5308
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
5283
5309
|
}
|
|
5284
|
-
function openInBrowser(url) {
|
|
5310
|
+
function openInBrowser(url, options = {}) {
|
|
5285
5311
|
try {
|
|
5286
|
-
if (browserOpeningDisabled()) return;
|
|
5312
|
+
if (browserOpeningDisabled()) return "failed";
|
|
5287
5313
|
const targetUrl = String(url || "").trim();
|
|
5288
|
-
if (!targetUrl) return;
|
|
5289
|
-
if (!claimBrowserOpen(Date.now(), void 0, targetUrl))
|
|
5314
|
+
if (!targetUrl) return "failed";
|
|
5315
|
+
if (options.deduplicate !== false && !claimBrowserOpen(Date.now(), void 0, targetUrl)) {
|
|
5316
|
+
return "suppressed";
|
|
5317
|
+
}
|
|
5290
5318
|
const allowFocus = true;
|
|
5291
5319
|
if (process.platform === "darwin") {
|
|
5292
|
-
openUrlMacos(targetUrl, allowFocus);
|
|
5293
|
-
return;
|
|
5320
|
+
return openUrlMacos(targetUrl, allowFocus) ? "opened" : "failed";
|
|
5294
5321
|
}
|
|
5295
|
-
if (!allowFocus) return;
|
|
5322
|
+
if (!allowFocus) return "failed";
|
|
5296
5323
|
if (process.platform === "win32") {
|
|
5297
5324
|
childProcess.execFileSync("cmd.exe", ["/c", "start", "", targetUrl], {
|
|
5298
5325
|
stdio: "ignore"
|
|
5299
5326
|
});
|
|
5300
|
-
return;
|
|
5327
|
+
return "opened";
|
|
5301
5328
|
}
|
|
5302
5329
|
childProcess.execFileSync("xdg-open", [targetUrl], { stdio: "ignore" });
|
|
5330
|
+
return "opened";
|
|
5303
5331
|
} catch {
|
|
5332
|
+
return "failed";
|
|
5304
5333
|
}
|
|
5305
5334
|
}
|
|
5306
5335
|
function sleep3(ms) {
|
|
@@ -29571,6 +29600,18 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint) {
|
|
|
29571
29600
|
const prefix = normalized.startsWith("/") && prefixParts[0] !== "" ? `/${prefixParts.join("/")}` : prefixParts.join("/");
|
|
29572
29601
|
return prefix || null;
|
|
29573
29602
|
}
|
|
29603
|
+
function isHomebrewFormulaEntrypoint(entrypoint) {
|
|
29604
|
+
const normalized = (() => {
|
|
29605
|
+
try {
|
|
29606
|
+
return realpathSync3(entrypoint);
|
|
29607
|
+
} catch {
|
|
29608
|
+
return resolve13(entrypoint);
|
|
29609
|
+
}
|
|
29610
|
+
})();
|
|
29611
|
+
const parts = normalized.split(/[\\/]+/);
|
|
29612
|
+
const cellarIndex = parts.lastIndexOf("Cellar");
|
|
29613
|
+
return cellarIndex >= 0 && parts[cellarIndex + 1] === "deepline" && parts.slice(cellarIndex + 3).includes("libexec");
|
|
29614
|
+
}
|
|
29574
29615
|
function resolveUpdatePlan(options = {}) {
|
|
29575
29616
|
const env = options.env ?? process.env;
|
|
29576
29617
|
const homeDir2 = options.homeDir ?? homedir12();
|
|
@@ -29583,6 +29624,12 @@ function resolveUpdatePlan(options = {}) {
|
|
|
29583
29624
|
manualCommand: buildSourceUpdateCommand(sourceRoot)
|
|
29584
29625
|
};
|
|
29585
29626
|
}
|
|
29627
|
+
if (entrypoint && isHomebrewFormulaEntrypoint(entrypoint)) {
|
|
29628
|
+
return {
|
|
29629
|
+
kind: "homebrew",
|
|
29630
|
+
manualCommand: "brew upgrade deepline"
|
|
29631
|
+
};
|
|
29632
|
+
}
|
|
29586
29633
|
const sidecarPlan = resolvePythonSidecarUpdatePlan({
|
|
29587
29634
|
entrypoint,
|
|
29588
29635
|
env,
|
|
@@ -29614,7 +29661,7 @@ function resolveUpdatePlan(options = {}) {
|
|
|
29614
29661
|
}
|
|
29615
29662
|
var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
|
|
29616
29663
|
function autoUpdateFailurePath(plan) {
|
|
29617
|
-
if (plan.kind === "source") return null;
|
|
29664
|
+
if (plan.kind === "source" || plan.kind === "homebrew") return null;
|
|
29618
29665
|
if (plan.kind === "python-sidecar") {
|
|
29619
29666
|
return join15(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
|
|
29620
29667
|
}
|
|
@@ -29627,7 +29674,7 @@ function autoUpdateFailurePath(plan) {
|
|
|
29627
29674
|
);
|
|
29628
29675
|
}
|
|
29629
29676
|
function autoUpdatePackageSpec(plan) {
|
|
29630
|
-
if (plan.kind === "source") return "";
|
|
29677
|
+
if (plan.kind === "source" || plan.kind === "homebrew") return "";
|
|
29631
29678
|
if (plan.kind === "python-sidecar") return plan.packageSpec;
|
|
29632
29679
|
return plan.args[plan.args.length - 1] ?? plan.manualCommand;
|
|
29633
29680
|
}
|
|
@@ -29648,7 +29695,7 @@ function readAutoUpdateFailure(plan) {
|
|
|
29648
29695
|
}
|
|
29649
29696
|
function writeAutoUpdateFailure(plan, exitCode) {
|
|
29650
29697
|
const path = autoUpdateFailurePath(plan);
|
|
29651
|
-
if (!path || plan.kind === "source") return;
|
|
29698
|
+
if (!path || plan.kind === "source" || plan.kind === "homebrew") return;
|
|
29652
29699
|
const marker = {
|
|
29653
29700
|
kind: plan.kind,
|
|
29654
29701
|
packageSpec: autoUpdatePackageSpec(plan),
|
|
@@ -29673,7 +29720,9 @@ function clearAutoUpdateFailure(plan) {
|
|
|
29673
29720
|
}
|
|
29674
29721
|
function matchingAutoUpdateFailure(plan) {
|
|
29675
29722
|
const marker = readAutoUpdateFailure(plan);
|
|
29676
|
-
if (!marker || plan.kind === "source")
|
|
29723
|
+
if (!marker || plan.kind === "source" || plan.kind === "homebrew") {
|
|
29724
|
+
return null;
|
|
29725
|
+
}
|
|
29677
29726
|
if (marker.kind !== plan.kind) return null;
|
|
29678
29727
|
if (marker.packageSpec !== autoUpdatePackageSpec(plan)) return null;
|
|
29679
29728
|
return marker;
|
|
@@ -29931,6 +29980,8 @@ async function runUpdatePlan(plan) {
|
|
|
29931
29980
|
});
|
|
29932
29981
|
} else if (plan.kind === "python-sidecar") {
|
|
29933
29982
|
exitCode = await runPythonSidecarUpdatePlan(plan);
|
|
29983
|
+
} else if (plan.kind === "homebrew") {
|
|
29984
|
+
exitCode = 0;
|
|
29934
29985
|
}
|
|
29935
29986
|
if (exitCode === 0) {
|
|
29936
29987
|
clearAutoUpdateFailure(plan);
|
|
@@ -29969,6 +30020,9 @@ async function runUpdateCommand(options, dependencies = {}) {
|
|
|
29969
30020
|
lines: plan.kind === "source" ? [
|
|
29970
30021
|
"This Deepline CLI is running from SDK source, so it cannot safely update itself like an npm global.",
|
|
29971
30022
|
`Update the backing checkout with: ${plan.manualCommand}`
|
|
30023
|
+
] : plan.kind === "homebrew" ? [
|
|
30024
|
+
"This Deepline CLI was installed by Homebrew, which owns its upgrades.",
|
|
30025
|
+
`Update it with: ${plan.manualCommand}`
|
|
29972
30026
|
] : plan.kind === "python-sidecar" ? [
|
|
29973
30027
|
"This Deepline CLI is running from the Python-managed SDK sidecar.",
|
|
29974
30028
|
"Updating will refresh that sidecar, not a global npm binary."
|
|
@@ -29993,7 +30047,7 @@ async function runUpdateCommand(options, dependencies = {}) {
|
|
|
29993
30047
|
);
|
|
29994
30048
|
return 0;
|
|
29995
30049
|
}
|
|
29996
|
-
if (plan.kind === "source") {
|
|
30050
|
+
if (plan.kind === "source" || plan.kind === "homebrew") {
|
|
29997
30051
|
printCommandEnvelope({ ...plan, render }, { json: false });
|
|
29998
30052
|
return 0;
|
|
29999
30053
|
}
|
|
@@ -30012,6 +30066,8 @@ function registerUpdateCommand(program) {
|
|
|
30012
30066
|
`
|
|
30013
30067
|
Notes:
|
|
30014
30068
|
For the published npm CLI, this runs npm install -g deepline@latest.
|
|
30069
|
+
For a Homebrew installation, this prints brew upgrade deepline; Homebrew
|
|
30070
|
+
owns formula upgrades and Deepline never runs npm inside its Cellar.
|
|
30015
30071
|
For Python-managed SDK sidecars, this refreshes the sidecar that launched
|
|
30016
30072
|
the current SDK CLI instead of changing a global npm binary.
|
|
30017
30073
|
For repo-backed SDK wrappers such as cli-env sdk-prod or sdk-worktree, this
|
|
@@ -30139,14 +30195,37 @@ function resolveScopeRoot(scope) {
|
|
|
30139
30195
|
function authScopeForSetup(scope) {
|
|
30140
30196
|
return scope === "local" ? "folder" : "global";
|
|
30141
30197
|
}
|
|
30142
|
-
function shouldOpenSetupAuthorization(runtime = detectAgentRuntime()) {
|
|
30143
|
-
return runtime !== "claude_cowork";
|
|
30144
|
-
}
|
|
30145
30198
|
function openSetupAuthorization(authorizationUrl, options = {}) {
|
|
30146
30199
|
const url = authorizationUrl.trim();
|
|
30147
|
-
if (!url
|
|
30148
|
-
(options.open
|
|
30149
|
-
|
|
30200
|
+
if (!url) return "failed";
|
|
30201
|
+
if (options.open) return options.open(url);
|
|
30202
|
+
const result = openInBrowser(url, { deduplicate: false });
|
|
30203
|
+
return result === "opened" ? "opened" : "failed";
|
|
30204
|
+
}
|
|
30205
|
+
function buildPendingAuthorizationOutput(input2) {
|
|
30206
|
+
const authorizationUrl = input2.authorizationUrl.trim();
|
|
30207
|
+
if (input2.browserOpenStatus === "opened") {
|
|
30208
|
+
return {
|
|
30209
|
+
authorizationUrl: null,
|
|
30210
|
+
next: `Complete browser approval, then run: ${input2.resumeCommand}`,
|
|
30211
|
+
lines: ["Complete authorization in the browser window Deepline opened."]
|
|
30212
|
+
};
|
|
30213
|
+
}
|
|
30214
|
+
if (authorizationUrl) {
|
|
30215
|
+
return {
|
|
30216
|
+
authorizationUrl,
|
|
30217
|
+
next: `Open the authorization URL, approve it, then run: ${input2.resumeCommand}`,
|
|
30218
|
+
lines: [
|
|
30219
|
+
"Browser launch failed. Open the authorization URL to continue.",
|
|
30220
|
+
authorizationUrl
|
|
30221
|
+
]
|
|
30222
|
+
};
|
|
30223
|
+
}
|
|
30224
|
+
return {
|
|
30225
|
+
authorizationUrl: null,
|
|
30226
|
+
next: `Authorization is pending without a browser URL. Retry: ${input2.resumeCommand}`,
|
|
30227
|
+
lines: ["Authorization is pending, but no browser URL was returned."]
|
|
30228
|
+
};
|
|
30150
30229
|
}
|
|
30151
30230
|
function setupStatePath(baseUrl, scope, root) {
|
|
30152
30231
|
return scope === "local" && root ? join16(root, ".deepline", "setup", "state.json") : join16(sdkCliStateDirPath(baseUrl), "setup.json");
|
|
@@ -30176,15 +30255,6 @@ function parseCapturedJson(stdout) {
|
|
|
30176
30255
|
function asRecord2(value) {
|
|
30177
30256
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
30178
30257
|
}
|
|
30179
|
-
function printCapturedAuthorizationUrl(stdout) {
|
|
30180
|
-
const urls = stdout.match(/https:\/\/[^\s]+/g) ?? [];
|
|
30181
|
-
for (const url of new Set(
|
|
30182
|
-
urls.map((value) => value.replace(/[).,]+$/, ""))
|
|
30183
|
-
)) {
|
|
30184
|
-
process.stderr.write(`Authorize Deepline: ${url}
|
|
30185
|
-
`);
|
|
30186
|
-
}
|
|
30187
|
-
}
|
|
30188
30258
|
function safeRead(path) {
|
|
30189
30259
|
try {
|
|
30190
30260
|
return readFileSync14(path, "utf8");
|
|
@@ -30523,18 +30593,32 @@ function pendingResult(input2) {
|
|
|
30523
30593
|
status: "authorization_pending",
|
|
30524
30594
|
phases: input2.phases
|
|
30525
30595
|
});
|
|
30596
|
+
let browserOpenStatus = "failed";
|
|
30526
30597
|
if (input2.authorizationUrl) {
|
|
30527
|
-
openSetupAuthorization(input2.authorizationUrl);
|
|
30528
|
-
|
|
30598
|
+
browserOpenStatus = openSetupAuthorization(input2.authorizationUrl);
|
|
30599
|
+
if (browserOpenStatus === "opened") {
|
|
30600
|
+
process.stderr.write(
|
|
30601
|
+
"Opened Deepline authorization in your browser. Complete approval there.\n"
|
|
30602
|
+
);
|
|
30603
|
+
} else if (browserOpenStatus === "failed") {
|
|
30604
|
+
process.stderr.write(`Authorize Deepline: ${input2.authorizationUrl}
|
|
30529
30605
|
`);
|
|
30606
|
+
}
|
|
30530
30607
|
}
|
|
30608
|
+
const pendingOutput = buildPendingAuthorizationOutput({
|
|
30609
|
+
authorizationUrl: input2.authorizationUrl,
|
|
30610
|
+
browserOpenStatus,
|
|
30611
|
+
resumeCommand: setupResumeCommand(input2.baseUrl, input2.scope)
|
|
30612
|
+
});
|
|
30531
30613
|
printCommandEnvelope(
|
|
30532
30614
|
{
|
|
30533
30615
|
ok: true,
|
|
30534
30616
|
status: "authorization_pending",
|
|
30535
30617
|
complete: false,
|
|
30536
30618
|
scope: input2.scope,
|
|
30537
|
-
authorizationUrl:
|
|
30619
|
+
authorizationUrl: pendingOutput.authorizationUrl,
|
|
30620
|
+
browserOpened: browserOpenStatus === "opened",
|
|
30621
|
+
browserOpenStatus,
|
|
30538
30622
|
statePath,
|
|
30539
30623
|
phases: input2.phases,
|
|
30540
30624
|
currentPhase: "auth",
|
|
@@ -30544,15 +30628,12 @@ function pendingResult(input2) {
|
|
|
30544
30628
|
scope: input2.scope,
|
|
30545
30629
|
phase: "auth"
|
|
30546
30630
|
}),
|
|
30547
|
-
next:
|
|
30631
|
+
next: pendingOutput.next,
|
|
30548
30632
|
render: {
|
|
30549
30633
|
sections: [
|
|
30550
30634
|
{
|
|
30551
30635
|
title: "setup",
|
|
30552
|
-
lines:
|
|
30553
|
-
"Authorization is waiting for browser approval.",
|
|
30554
|
-
...input2.authorizationUrl ? [input2.authorizationUrl] : []
|
|
30555
|
-
]
|
|
30636
|
+
lines: pendingOutput.lines
|
|
30556
30637
|
}
|
|
30557
30638
|
]
|
|
30558
30639
|
}
|
|
@@ -30721,10 +30802,9 @@ async function runSetupCommand(options) {
|
|
|
30721
30802
|
const pending = readPendingAuthClaim(baseUrl, authScope);
|
|
30722
30803
|
if (pending) {
|
|
30723
30804
|
process.stderr.write("Checking pending Deepline authorization...\n");
|
|
30724
|
-
|
|
30805
|
+
await captureStdout2(
|
|
30725
30806
|
() => handleWait(["--timeout", "1", "--auth-scope", authScope])
|
|
30726
30807
|
);
|
|
30727
|
-
printCapturedAuthorizationUrl(waited.stdout);
|
|
30728
30808
|
auth = await readAuthStatus(authScope);
|
|
30729
30809
|
const resumedAuthFailure = reportSetupAuthStatusFailure({
|
|
30730
30810
|
auth,
|
|
@@ -30760,7 +30840,6 @@ async function runSetupCommand(options) {
|
|
|
30760
30840
|
const registered = await captureStdout2(
|
|
30761
30841
|
() => handleRegister(["--wait", waitMode, "--auth-scope", authScope])
|
|
30762
30842
|
);
|
|
30763
|
-
printCapturedAuthorizationUrl(registered.stdout);
|
|
30764
30843
|
if (registered.exitCode !== 0) {
|
|
30765
30844
|
return reportSetupPhaseFailure({
|
|
30766
30845
|
baseUrl,
|
package/dist/index.d.mts
CHANGED
|
@@ -2703,6 +2703,7 @@ declare class RunObserveTransportUnavailableError extends Error {
|
|
|
2703
2703
|
}
|
|
2704
2704
|
|
|
2705
2705
|
declare const SDK_VERSION: string;
|
|
2706
|
+
/** @deprecated Transitional wire id for pre-major-header SDKs only. */
|
|
2706
2707
|
declare const SDK_API_CONTRACT: string;
|
|
2707
2708
|
|
|
2708
2709
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -2703,6 +2703,7 @@ declare class RunObserveTransportUnavailableError extends Error {
|
|
|
2703
2703
|
}
|
|
2704
2704
|
|
|
2705
2705
|
declare const SDK_VERSION: string;
|
|
2706
|
+
/** @deprecated Transitional wire id for pre-major-header SDKs only. */
|
|
2706
2707
|
declare const SDK_API_CONTRACT: string;
|
|
2707
2708
|
|
|
2708
2709
|
/**
|
package/dist/index.js
CHANGED
|
@@ -437,8 +437,31 @@ var SDK_RELEASE = {
|
|
|
437
437
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
438
438
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
439
439
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
440
|
-
version: "0.1.
|
|
441
|
-
|
|
440
|
+
version: "0.1.267",
|
|
441
|
+
contracts: {
|
|
442
|
+
api: {
|
|
443
|
+
name: "sdk-http-api",
|
|
444
|
+
// API v2 is append-only. A breaking public request/response change needs
|
|
445
|
+
// v3 and an explicit v2 support-window decision, never a patch release.
|
|
446
|
+
currentMajor: 2,
|
|
447
|
+
supportedMajors: [2],
|
|
448
|
+
// Accepted only to bridge SDKs released before X-Deepline-API-Major.
|
|
449
|
+
legacyWireIds: [
|
|
450
|
+
"2026-07-admin-cli-local-cutover",
|
|
451
|
+
"2026-07-native-monitor-launch-hard-cutover"
|
|
452
|
+
]
|
|
453
|
+
},
|
|
454
|
+
playArtifact: {
|
|
455
|
+
name: "play-artifact-runtime",
|
|
456
|
+
currentVersion: 2,
|
|
457
|
+
supportedVersions: [1, 2]
|
|
458
|
+
},
|
|
459
|
+
release: {
|
|
460
|
+
name: "production-sdk-release",
|
|
461
|
+
publishFrom: "latest-successful-production-deployment",
|
|
462
|
+
coalesce: "latest-healthy"
|
|
463
|
+
}
|
|
464
|
+
},
|
|
442
465
|
supportPolicy: {
|
|
443
466
|
minimumSupported: "0.1.53",
|
|
444
467
|
deprecatedBelow: "0.1.219",
|
|
@@ -535,7 +558,8 @@ var SDK_RELEASE = {
|
|
|
535
558
|
|
|
536
559
|
// src/version.ts
|
|
537
560
|
var SDK_VERSION = SDK_RELEASE.version;
|
|
538
|
-
var
|
|
561
|
+
var SDK_API_MAJOR = SDK_RELEASE.contracts.api.currentMajor;
|
|
562
|
+
var SDK_API_CONTRACT = SDK_RELEASE.contracts.api.legacyWireIds[0] ?? `api-v${SDK_API_MAJOR}`;
|
|
539
563
|
|
|
540
564
|
// src/agent-runtime.ts
|
|
541
565
|
var import_node_os2 = require("os");
|
package/dist/index.mjs
CHANGED
|
@@ -367,8 +367,31 @@ var SDK_RELEASE = {
|
|
|
367
367
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
368
368
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
369
369
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
370
|
-
version: "0.1.
|
|
371
|
-
|
|
370
|
+
version: "0.1.267",
|
|
371
|
+
contracts: {
|
|
372
|
+
api: {
|
|
373
|
+
name: "sdk-http-api",
|
|
374
|
+
// API v2 is append-only. A breaking public request/response change needs
|
|
375
|
+
// v3 and an explicit v2 support-window decision, never a patch release.
|
|
376
|
+
currentMajor: 2,
|
|
377
|
+
supportedMajors: [2],
|
|
378
|
+
// Accepted only to bridge SDKs released before X-Deepline-API-Major.
|
|
379
|
+
legacyWireIds: [
|
|
380
|
+
"2026-07-admin-cli-local-cutover",
|
|
381
|
+
"2026-07-native-monitor-launch-hard-cutover"
|
|
382
|
+
]
|
|
383
|
+
},
|
|
384
|
+
playArtifact: {
|
|
385
|
+
name: "play-artifact-runtime",
|
|
386
|
+
currentVersion: 2,
|
|
387
|
+
supportedVersions: [1, 2]
|
|
388
|
+
},
|
|
389
|
+
release: {
|
|
390
|
+
name: "production-sdk-release",
|
|
391
|
+
publishFrom: "latest-successful-production-deployment",
|
|
392
|
+
coalesce: "latest-healthy"
|
|
393
|
+
}
|
|
394
|
+
},
|
|
372
395
|
supportPolicy: {
|
|
373
396
|
minimumSupported: "0.1.53",
|
|
374
397
|
deprecatedBelow: "0.1.219",
|
|
@@ -465,7 +488,8 @@ var SDK_RELEASE = {
|
|
|
465
488
|
|
|
466
489
|
// src/version.ts
|
|
467
490
|
var SDK_VERSION = SDK_RELEASE.version;
|
|
468
|
-
var
|
|
491
|
+
var SDK_API_MAJOR = SDK_RELEASE.contracts.api.currentMajor;
|
|
492
|
+
var SDK_API_CONTRACT = SDK_RELEASE.contracts.api.legacyWireIds[0] ?? `api-v${SDK_API_MAJOR}`;
|
|
469
493
|
|
|
470
494
|
// src/agent-runtime.ts
|
|
471
495
|
import { homedir as homedir2 } from "os";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepline",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.267",
|
|
4
4
|
"description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"typescript": "^6.0.2"
|
|
63
63
|
},
|
|
64
64
|
"deepline": {
|
|
65
|
-
"apiContract": "2026-07-admin-cli-local-cutover"
|
|
65
|
+
"apiContract": "2026-07-admin-cli-local-cutover",
|
|
66
|
+
"apiMajor": 2
|
|
66
67
|
}
|
|
67
68
|
}
|