deepline 0.1.266 → 0.1.268
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 +127 -42
- package/dist/cli/index.mjs +127 -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.268',
|
|
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.268",
|
|
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");
|
|
@@ -30134,13 +30204,19 @@ function isNpmManagedDeeplinePath(path) {
|
|
|
30134
30204
|
return false;
|
|
30135
30205
|
}
|
|
30136
30206
|
}
|
|
30207
|
+
function isInstallerManagedLegacyLauncher(path) {
|
|
30208
|
+
const content = safeRead(path);
|
|
30209
|
+
return content.includes("DEEPLINE_REAL_BINARY") && content.includes("DEEPLINE_ACTIVE_FILE");
|
|
30210
|
+
}
|
|
30137
30211
|
function removeKnownLegacyPaths(baseUrl) {
|
|
30138
30212
|
const home = (0, import_node_os15.homedir)();
|
|
30139
30213
|
const hostDir = (0, import_node_path20.join)(home, ".local", "deepline", baseUrlSlug(baseUrl));
|
|
30214
|
+
const legacyLauncherPath = (0, import_node_path20.join)(home, ".local", "bin", "deepline");
|
|
30140
30215
|
const installerCommandPath = safeRead(
|
|
30141
30216
|
(0, import_node_path20.join)(hostDir, "sdk", ".command-path")
|
|
30142
30217
|
).trim();
|
|
30143
30218
|
const candidates = [
|
|
30219
|
+
...isInstallerManagedLegacyLauncher(legacyLauncherPath) ? [legacyLauncherPath] : [],
|
|
30144
30220
|
(0, import_node_path20.join)(home, ".local", "bin", "deepline-real"),
|
|
30145
30221
|
(0, import_node_path20.join)(hostDir, "bin", "deepline"),
|
|
30146
30222
|
(0, import_node_path20.join)(hostDir, "bin", "deepline-real"),
|
|
@@ -30458,18 +30534,32 @@ function pendingResult(input2) {
|
|
|
30458
30534
|
status: "authorization_pending",
|
|
30459
30535
|
phases: input2.phases
|
|
30460
30536
|
});
|
|
30537
|
+
let browserOpenStatus = "failed";
|
|
30461
30538
|
if (input2.authorizationUrl) {
|
|
30462
|
-
openSetupAuthorization(input2.authorizationUrl);
|
|
30463
|
-
|
|
30539
|
+
browserOpenStatus = openSetupAuthorization(input2.authorizationUrl);
|
|
30540
|
+
if (browserOpenStatus === "opened") {
|
|
30541
|
+
process.stderr.write(
|
|
30542
|
+
"Opened Deepline authorization in your browser. Complete approval there.\n"
|
|
30543
|
+
);
|
|
30544
|
+
} else if (browserOpenStatus === "failed") {
|
|
30545
|
+
process.stderr.write(`Authorize Deepline: ${input2.authorizationUrl}
|
|
30464
30546
|
`);
|
|
30547
|
+
}
|
|
30465
30548
|
}
|
|
30549
|
+
const pendingOutput = buildPendingAuthorizationOutput({
|
|
30550
|
+
authorizationUrl: input2.authorizationUrl,
|
|
30551
|
+
browserOpenStatus,
|
|
30552
|
+
resumeCommand: setupResumeCommand(input2.baseUrl, input2.scope)
|
|
30553
|
+
});
|
|
30466
30554
|
printCommandEnvelope(
|
|
30467
30555
|
{
|
|
30468
30556
|
ok: true,
|
|
30469
30557
|
status: "authorization_pending",
|
|
30470
30558
|
complete: false,
|
|
30471
30559
|
scope: input2.scope,
|
|
30472
|
-
authorizationUrl:
|
|
30560
|
+
authorizationUrl: pendingOutput.authorizationUrl,
|
|
30561
|
+
browserOpened: browserOpenStatus === "opened",
|
|
30562
|
+
browserOpenStatus,
|
|
30473
30563
|
statePath,
|
|
30474
30564
|
phases: input2.phases,
|
|
30475
30565
|
currentPhase: "auth",
|
|
@@ -30479,15 +30569,12 @@ function pendingResult(input2) {
|
|
|
30479
30569
|
scope: input2.scope,
|
|
30480
30570
|
phase: "auth"
|
|
30481
30571
|
}),
|
|
30482
|
-
next:
|
|
30572
|
+
next: pendingOutput.next,
|
|
30483
30573
|
render: {
|
|
30484
30574
|
sections: [
|
|
30485
30575
|
{
|
|
30486
30576
|
title: "setup",
|
|
30487
|
-
lines:
|
|
30488
|
-
"Authorization is waiting for browser approval.",
|
|
30489
|
-
...input2.authorizationUrl ? [input2.authorizationUrl] : []
|
|
30490
|
-
]
|
|
30577
|
+
lines: pendingOutput.lines
|
|
30491
30578
|
}
|
|
30492
30579
|
]
|
|
30493
30580
|
}
|
|
@@ -30656,10 +30743,9 @@ async function runSetupCommand(options) {
|
|
|
30656
30743
|
const pending = readPendingAuthClaim(baseUrl, authScope);
|
|
30657
30744
|
if (pending) {
|
|
30658
30745
|
process.stderr.write("Checking pending Deepline authorization...\n");
|
|
30659
|
-
|
|
30746
|
+
await captureStdout2(
|
|
30660
30747
|
() => handleWait(["--timeout", "1", "--auth-scope", authScope])
|
|
30661
30748
|
);
|
|
30662
|
-
printCapturedAuthorizationUrl(waited.stdout);
|
|
30663
30749
|
auth = await readAuthStatus(authScope);
|
|
30664
30750
|
const resumedAuthFailure = reportSetupAuthStatusFailure({
|
|
30665
30751
|
auth,
|
|
@@ -30695,7 +30781,6 @@ async function runSetupCommand(options) {
|
|
|
30695
30781
|
const registered = await captureStdout2(
|
|
30696
30782
|
() => handleRegister(["--wait", waitMode, "--auth-scope", authScope])
|
|
30697
30783
|
);
|
|
30698
|
-
printCapturedAuthorizationUrl(registered.stdout);
|
|
30699
30784
|
if (registered.exitCode !== 0) {
|
|
30700
30785
|
return reportSetupPhaseFailure({
|
|
30701
30786
|
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.268",
|
|
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");
|
|
@@ -30199,13 +30269,19 @@ function isNpmManagedDeeplinePath(path) {
|
|
|
30199
30269
|
return false;
|
|
30200
30270
|
}
|
|
30201
30271
|
}
|
|
30272
|
+
function isInstallerManagedLegacyLauncher(path) {
|
|
30273
|
+
const content = safeRead(path);
|
|
30274
|
+
return content.includes("DEEPLINE_REAL_BINARY") && content.includes("DEEPLINE_ACTIVE_FILE");
|
|
30275
|
+
}
|
|
30202
30276
|
function removeKnownLegacyPaths(baseUrl) {
|
|
30203
30277
|
const home = homedir13();
|
|
30204
30278
|
const hostDir = join16(home, ".local", "deepline", baseUrlSlug(baseUrl));
|
|
30279
|
+
const legacyLauncherPath = join16(home, ".local", "bin", "deepline");
|
|
30205
30280
|
const installerCommandPath = safeRead(
|
|
30206
30281
|
join16(hostDir, "sdk", ".command-path")
|
|
30207
30282
|
).trim();
|
|
30208
30283
|
const candidates = [
|
|
30284
|
+
...isInstallerManagedLegacyLauncher(legacyLauncherPath) ? [legacyLauncherPath] : [],
|
|
30209
30285
|
join16(home, ".local", "bin", "deepline-real"),
|
|
30210
30286
|
join16(hostDir, "bin", "deepline"),
|
|
30211
30287
|
join16(hostDir, "bin", "deepline-real"),
|
|
@@ -30523,18 +30599,32 @@ function pendingResult(input2) {
|
|
|
30523
30599
|
status: "authorization_pending",
|
|
30524
30600
|
phases: input2.phases
|
|
30525
30601
|
});
|
|
30602
|
+
let browserOpenStatus = "failed";
|
|
30526
30603
|
if (input2.authorizationUrl) {
|
|
30527
|
-
openSetupAuthorization(input2.authorizationUrl);
|
|
30528
|
-
|
|
30604
|
+
browserOpenStatus = openSetupAuthorization(input2.authorizationUrl);
|
|
30605
|
+
if (browserOpenStatus === "opened") {
|
|
30606
|
+
process.stderr.write(
|
|
30607
|
+
"Opened Deepline authorization in your browser. Complete approval there.\n"
|
|
30608
|
+
);
|
|
30609
|
+
} else if (browserOpenStatus === "failed") {
|
|
30610
|
+
process.stderr.write(`Authorize Deepline: ${input2.authorizationUrl}
|
|
30529
30611
|
`);
|
|
30612
|
+
}
|
|
30530
30613
|
}
|
|
30614
|
+
const pendingOutput = buildPendingAuthorizationOutput({
|
|
30615
|
+
authorizationUrl: input2.authorizationUrl,
|
|
30616
|
+
browserOpenStatus,
|
|
30617
|
+
resumeCommand: setupResumeCommand(input2.baseUrl, input2.scope)
|
|
30618
|
+
});
|
|
30531
30619
|
printCommandEnvelope(
|
|
30532
30620
|
{
|
|
30533
30621
|
ok: true,
|
|
30534
30622
|
status: "authorization_pending",
|
|
30535
30623
|
complete: false,
|
|
30536
30624
|
scope: input2.scope,
|
|
30537
|
-
authorizationUrl:
|
|
30625
|
+
authorizationUrl: pendingOutput.authorizationUrl,
|
|
30626
|
+
browserOpened: browserOpenStatus === "opened",
|
|
30627
|
+
browserOpenStatus,
|
|
30538
30628
|
statePath,
|
|
30539
30629
|
phases: input2.phases,
|
|
30540
30630
|
currentPhase: "auth",
|
|
@@ -30544,15 +30634,12 @@ function pendingResult(input2) {
|
|
|
30544
30634
|
scope: input2.scope,
|
|
30545
30635
|
phase: "auth"
|
|
30546
30636
|
}),
|
|
30547
|
-
next:
|
|
30637
|
+
next: pendingOutput.next,
|
|
30548
30638
|
render: {
|
|
30549
30639
|
sections: [
|
|
30550
30640
|
{
|
|
30551
30641
|
title: "setup",
|
|
30552
|
-
lines:
|
|
30553
|
-
"Authorization is waiting for browser approval.",
|
|
30554
|
-
...input2.authorizationUrl ? [input2.authorizationUrl] : []
|
|
30555
|
-
]
|
|
30642
|
+
lines: pendingOutput.lines
|
|
30556
30643
|
}
|
|
30557
30644
|
]
|
|
30558
30645
|
}
|
|
@@ -30721,10 +30808,9 @@ async function runSetupCommand(options) {
|
|
|
30721
30808
|
const pending = readPendingAuthClaim(baseUrl, authScope);
|
|
30722
30809
|
if (pending) {
|
|
30723
30810
|
process.stderr.write("Checking pending Deepline authorization...\n");
|
|
30724
|
-
|
|
30811
|
+
await captureStdout2(
|
|
30725
30812
|
() => handleWait(["--timeout", "1", "--auth-scope", authScope])
|
|
30726
30813
|
);
|
|
30727
|
-
printCapturedAuthorizationUrl(waited.stdout);
|
|
30728
30814
|
auth = await readAuthStatus(authScope);
|
|
30729
30815
|
const resumedAuthFailure = reportSetupAuthStatusFailure({
|
|
30730
30816
|
auth,
|
|
@@ -30760,7 +30846,6 @@ async function runSetupCommand(options) {
|
|
|
30760
30846
|
const registered = await captureStdout2(
|
|
30761
30847
|
() => handleRegister(["--wait", waitMode, "--auth-scope", authScope])
|
|
30762
30848
|
);
|
|
30763
|
-
printCapturedAuthorizationUrl(registered.stdout);
|
|
30764
30849
|
if (registered.exitCode !== 0) {
|
|
30765
30850
|
return reportSetupPhaseFailure({
|
|
30766
30851
|
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.268",
|
|
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.268",
|
|
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.268",
|
|
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
|
}
|