deepline 0.3.48 → 0.3.50

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.
@@ -164,7 +164,7 @@ configureProxyFromEnv();
164
164
 
165
165
  // src/cli/index.ts
166
166
  import { mkdtemp as mkdtemp2, rm as rm2, writeFile as writeFile6 } from "fs/promises";
167
- import { join as join22 } from "path";
167
+ import { join as join23 } from "path";
168
168
  import { tmpdir as tmpdir6 } from "os";
169
169
  import { Command as Command4 } from "commander";
170
170
 
@@ -1065,7 +1065,7 @@ var SDK_RELEASE = {
1065
1065
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1066
1066
  // getters keep their established compatibility behavior.
1067
1067
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1068
- version: "0.3.48",
1068
+ version: "0.3.50",
1069
1069
  updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
1070
1070
  packageCapabilities: {
1071
1071
  updatePreferences: 1
@@ -1954,7 +1954,7 @@ var HttpClient = class {
1954
1954
  body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0,
1955
1955
  signal: options?.signal
1956
1956
  });
1957
- if (!response.ok || response.status === 202) {
1957
+ if (!response.ok) {
1958
1958
  const body = await response.text();
1959
1959
  const parsed = parseResponseBody(body);
1960
1960
  if (response.status === 401 && !isProviderOriginatedHttpError(parsed)) {
@@ -2202,7 +2202,7 @@ function decodeSseFrame(frame) {
2202
2202
  return parsed;
2203
2203
  }
2204
2204
  function sleep(ms) {
2205
- return new Promise((resolve19) => setTimeout(resolve19, ms));
2205
+ return new Promise((resolve20) => setTimeout(resolve20, ms));
2206
2206
  }
2207
2207
  function withCoworkNetworkHint(message) {
2208
2208
  if (!isCoworkLikeSandbox2() || message.includes(COWORK_NETWORK_HINT)) {
@@ -3967,14 +3967,14 @@ async function* observeRunEvents(options) {
3967
3967
  try {
3968
3968
  for (; ; ) {
3969
3969
  if (queue.length === 0) {
3970
- const waitForItem = new Promise((resolve19) => {
3971
- wake = resolve19;
3970
+ const waitForItem = new Promise((resolve20) => {
3971
+ wake = resolve20;
3972
3972
  });
3973
3973
  if (!sawFirstSnapshot) {
3974
3974
  const timedOut = await Promise.race([
3975
3975
  waitForItem.then(() => false),
3976
3976
  new Promise(
3977
- (resolve19) => setTimeout(() => resolve19(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
3977
+ (resolve20) => setTimeout(() => resolve20(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
3978
3978
  )
3979
3979
  ]);
3980
3980
  if (timedOut && queue.length === 0) {
@@ -4333,7 +4333,7 @@ function parseEnvTestPolicyOverrides() {
4333
4333
  return normalizeTestPolicyOverrides(parsed, "DEEPLINE_TEST_POLICY_OVERRIDES");
4334
4334
  }
4335
4335
  function sleep2(ms) {
4336
- return new Promise((resolve19) => setTimeout(resolve19, ms));
4336
+ return new Promise((resolve20) => setTimeout(resolve20, ms));
4337
4337
  }
4338
4338
  function isTransientCompileManifestError(error) {
4339
4339
  if (error instanceof DeeplineError && typeof error.statusCode === "number") {
@@ -5683,26 +5683,12 @@ var DeeplineClient = class {
5683
5683
  const headers = options?.lastEventId && options.lastEventId.trim() ? { "Last-Event-ID": options.lastEventId.trim() } : void 0;
5684
5684
  const params = new URLSearchParams();
5685
5685
  params.set("mode", options?.mode ?? "cli");
5686
- const projectionDeadline = Date.now() + 3e4;
5687
- let projectionAttempt = 0;
5688
- for (; ; ) {
5689
- let sawEvent = false;
5690
- try {
5691
- for await (const event of this.http.streamSse(
5692
- `/api/v2/runs/${encodeURIComponent(workflowId)}/tail?${params.toString()}`,
5693
- { signal: options?.signal, headers }
5694
- )) {
5695
- sawEvent = true;
5696
- if (event.scope === "play") {
5697
- yield event;
5698
- }
5699
- }
5700
- return;
5701
- } catch (error) {
5702
- const projectionPending = options?.waitForProjection === true && !sawEvent && error instanceof DeeplineError && (error.statusCode === 404 || error.statusCode === 202 && error.code === "RUN_PROJECTION_PENDING") && Date.now() < projectionDeadline;
5703
- if (!projectionPending) throw error;
5704
- await sleep2(streamReconnectDelayMs(projectionAttempt));
5705
- projectionAttempt += 1;
5686
+ for await (const event of this.http.streamSse(
5687
+ `/api/v2/runs/${encodeURIComponent(workflowId)}/tail?${params.toString()}`,
5688
+ { signal: options?.signal, headers }
5689
+ )) {
5690
+ if (event.scope === "play") {
5691
+ yield event;
5706
5692
  }
5707
5693
  }
5708
5694
  }
@@ -6731,8 +6717,7 @@ var DeeplineClient = class {
6731
6717
  }
6732
6718
  for await (const event of this.streamPlayRunEvents(workflowId, {
6733
6719
  mode: "cli",
6734
- signal: options?.signal,
6735
- waitForProjection: true
6720
+ signal: options?.signal
6736
6721
  })) {
6737
6722
  if (options?.signal?.aborted) {
6738
6723
  await this.cancelPlay(workflowId);
@@ -7767,6 +7752,10 @@ function flattenObjectColumns(row, options = {}) {
7767
7752
  }
7768
7753
  if (value && typeof value === "object" && !Array.isArray(value)) {
7769
7754
  const record = value;
7755
+ if (options.objectColumns === "json") {
7756
+ flattened[key] = csvSafeJsonString(record);
7757
+ continue;
7758
+ }
7770
7759
  const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record, "matched_result") || Object.prototype.hasOwnProperty.call(record, "matchedResult");
7771
7760
  if (hasMatchedEnvelope) {
7772
7761
  flattened[key] = csvSafeJsonString(record);
@@ -8091,6 +8080,8 @@ async function httpJson(method, url, apiKey, body) {
8091
8080
  "X-Deepline-API-Contract": SDK_API_CONTRACT
8092
8081
  };
8093
8082
  if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
8083
+ const bypassToken = process.env.VERCEL_PROTECTION_BYPASS_TOKEN?.trim();
8084
+ if (bypassToken) headers["x-vercel-protection-bypass"] = bypassToken;
8094
8085
  let response = null;
8095
8086
  let lastError = null;
8096
8087
  for (const candidateUrl of buildCandidateUrls2(url)) {
@@ -8157,7 +8148,7 @@ function buildCandidateUrls2(url) {
8157
8148
  }
8158
8149
  }
8159
8150
  function sleep4(ms) {
8160
- return new Promise((resolve19) => setTimeout(resolve19, ms));
8151
+ return new Promise((resolve20) => setTimeout(resolve20, ms));
8161
8152
  }
8162
8153
  function printDeeplineLogo() {
8163
8154
  if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
@@ -10128,10 +10119,6 @@ import {
10128
10119
  import { homedir as homedir5 } from "os";
10129
10120
  import { join as join6, resolve as resolve5 } from "path";
10130
10121
 
10131
- // src/cli/dataset-stats.ts
10132
- import { writeFileSync as writeFileSync6 } from "fs";
10133
- import { resolve as resolve4 } from "path";
10134
-
10135
10122
  // ../plays/dataset-summary.ts
10136
10123
  function formatDatasetRowCountsLine(counts) {
10137
10124
  const { persisted, succeeded, failed } = counts;
@@ -10185,6 +10172,103 @@ function formatDatasetExecutionStats(raw, _persistedRowTotal) {
10185
10172
  return stats;
10186
10173
  }
10187
10174
 
10175
+ // src/cli/run-dataset-csv.ts
10176
+ import { writeFileSync as writeFileSync6 } from "fs";
10177
+ import { resolve as resolve4 } from "path";
10178
+ var RunDatasetCsv = class _RunDatasetCsv {
10179
+ #projection;
10180
+ constructor(input2) {
10181
+ const rows = input2.rows.map(projectRunDatasetRow);
10182
+ this.#projection = {
10183
+ rows,
10184
+ columns: runDatasetCsvColumns(rows, input2.columns)
10185
+ };
10186
+ }
10187
+ static from(input2) {
10188
+ return new _RunDatasetCsv(input2);
10189
+ }
10190
+ projection() {
10191
+ return this.#projection;
10192
+ }
10193
+ write(outPath) {
10194
+ const absolutePath = resolve4(outPath);
10195
+ writeFileSync6(
10196
+ absolutePath,
10197
+ csvStringFromRows(this.#projection.rows, this.#projection.columns),
10198
+ "utf-8"
10199
+ );
10200
+ return absolutePath;
10201
+ }
10202
+ };
10203
+ function writeRunDatasetCsv(input2) {
10204
+ return RunDatasetCsv.from(input2).write(input2.outPath);
10205
+ }
10206
+ function projectRunDatasetRow(row) {
10207
+ return Object.fromEntries(
10208
+ Object.entries(row).map(([column, value]) => [
10209
+ column,
10210
+ projectRunDatasetCell(value)
10211
+ ])
10212
+ );
10213
+ }
10214
+ function projectRunDatasetCell(value) {
10215
+ const logicalValue = parseSerializedDatasetValue(value);
10216
+ if (logicalValue === null || logicalValue === void 0) return logicalValue;
10217
+ if (typeof logicalValue === "object") {
10218
+ return csvSafeJsonString(canonicalDatasetJson(logicalValue));
10219
+ }
10220
+ return logicalValue;
10221
+ }
10222
+ function canonicalDatasetJson(value) {
10223
+ return canonicalDatasetJsonValue(value, /* @__PURE__ */ new WeakSet());
10224
+ }
10225
+ function canonicalDatasetJsonValue(value, ancestors) {
10226
+ if (Array.isArray(value)) {
10227
+ if (ancestors.has(value)) return value;
10228
+ ancestors.add(value);
10229
+ const normalized2 = value.map(
10230
+ (item) => canonicalDatasetJsonValue(item, ancestors)
10231
+ );
10232
+ ancestors.delete(value);
10233
+ return normalized2;
10234
+ }
10235
+ if (!value || typeof value !== "object" || value instanceof Date) {
10236
+ return value;
10237
+ }
10238
+ if (ancestors.has(value)) return value;
10239
+ ancestors.add(value);
10240
+ const record = value;
10241
+ const normalized = Object.fromEntries(
10242
+ Object.keys(record).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record[key], ancestors)])
10243
+ );
10244
+ ancestors.delete(value);
10245
+ return normalized;
10246
+ }
10247
+ function parseSerializedDatasetValue(value) {
10248
+ if (typeof value !== "string") return value;
10249
+ const text = value.trim();
10250
+ if (!text || !["{", "["].includes(text[0] ?? "")) return value;
10251
+ try {
10252
+ return JSON.parse(text);
10253
+ } catch {
10254
+ return value;
10255
+ }
10256
+ }
10257
+ function runDatasetCsvColumns(rows, declaredColumns) {
10258
+ const columns = [];
10259
+ const seen = /* @__PURE__ */ new Set();
10260
+ const add = (column) => {
10261
+ if (!column || seen.has(column)) return;
10262
+ seen.add(column);
10263
+ columns.push(column);
10264
+ };
10265
+ for (const column of declaredColumns) add(column);
10266
+ for (const row of rows) {
10267
+ for (const column of Object.keys(row)) add(column);
10268
+ }
10269
+ return columns;
10270
+ }
10271
+
10188
10272
  // src/cli/dataset-stats.ts
10189
10273
  function mergeCanonicalRowsInfo(left, right) {
10190
10274
  const preferred = right.rows.length > left.rows.length || right.complete && !left.complete && right.rows.length === left.rows.length ? right : left;
@@ -10602,6 +10686,11 @@ function collectSerializedDatasetRowsInfos(statusOrResult) {
10602
10686
  }
10603
10687
  return infos;
10604
10688
  }
10689
+ var LegacyRunDatasetCatalogAdapter = class {
10690
+ static datasets(statusOrResult) {
10691
+ return collectSerializedDatasetRowsInfos(statusOrResult);
10692
+ }
10693
+ };
10605
10694
  function extractCanonicalRowsInfo(statusOrResult) {
10606
10695
  return collectCanonicalRowsInfos(statusOrResult)[0] ?? null;
10607
10696
  }
@@ -10771,22 +10860,6 @@ function buildDatasetStats(rows, totalRows = rows.length, columns = inferColumns
10771
10860
  columnStats
10772
10861
  };
10773
10862
  }
10774
- function writeCanonicalRowsCsv(rowsInfo, outPath) {
10775
- if (!rowsInfo.complete) {
10776
- throw new Error(
10777
- `Run output only includes ${rowsInfo.rows.length} preview row(s) of ${rowsInfo.totalRows}; cannot export a complete CSV from this status payload yet.`
10778
- );
10779
- }
10780
- const sanitized = sanitizeCsvProjectionInfo({
10781
- rows: rowsInfo.rows,
10782
- columns: rowsInfo.columns
10783
- });
10784
- const rows = dataExportRows(sanitized.rows);
10785
- const columns = dataExportColumns(rows, sanitized.columns);
10786
- const resolved = resolve4(outPath);
10787
- writeFileSync6(resolved, csvStringFromRows(rows, columns), "utf-8");
10788
- return resolved;
10789
- }
10790
10863
 
10791
10864
  // src/cli/commands/csv.ts
10792
10865
  function parseRowRange(raw) {
@@ -18324,6 +18397,207 @@ var SDK_PACKAGE_JSON = resolve10(SDK_PACKAGE_ROOT, "package.json");
18324
18397
  var SDK_ENTRY_FILE = resolve10(SDK_SOURCE_ROOT, "index.ts");
18325
18398
  var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : resolve10(SDK_PACKAGE_ROOT, "dist", "index.d.ts");
18326
18399
 
18400
+ // src/cli/run-dataset-selection.ts
18401
+ var Run = class _Run {
18402
+ #datasets;
18403
+ constructor(input2) {
18404
+ this.#datasets = RunDatasetCatalog.from({
18405
+ runPackage: input2.runPackage,
18406
+ datasets: input2.datasets
18407
+ });
18408
+ }
18409
+ static open(input2) {
18410
+ return new _Run(input2);
18411
+ }
18412
+ datasets() {
18413
+ return this.#datasets;
18414
+ }
18415
+ /** Select the Dataset a caller wants to export; enumerate with datasets(). */
18416
+ dataset(path) {
18417
+ return this.#datasets.choose(path);
18418
+ }
18419
+ };
18420
+ var RunDatasetCatalog = class _RunDatasetCatalog {
18421
+ #available;
18422
+ #returned;
18423
+ #recovered;
18424
+ constructor(input2) {
18425
+ this.#available = input2.available.map((info) => RunDataset.from(info));
18426
+ this.#returned = input2.returned.map((info) => RunDataset.from(info));
18427
+ this.#recovered = input2.available.filter((info) => info.recovered).map((info) => RunDataset.from(info));
18428
+ }
18429
+ static from(input2) {
18430
+ const available = withReturnedDatasetAliases(
18431
+ input2.runPackage,
18432
+ distinctRunDatasets(input2.datasets)
18433
+ );
18434
+ return new _RunDatasetCatalog({
18435
+ available,
18436
+ returned: returnedRunDatasets(input2.runPackage, available)
18437
+ });
18438
+ }
18439
+ available() {
18440
+ return this.#available;
18441
+ }
18442
+ returned() {
18443
+ return this.#returned;
18444
+ }
18445
+ recovered() {
18446
+ return this.#recovered;
18447
+ }
18448
+ /**
18449
+ * Select an exact public Dataset path/id/namespace. With no requested path,
18450
+ * a Run returns its sole returned Dataset, or its sole recovered Dataset.
18451
+ */
18452
+ choose(path) {
18453
+ const requested = path?.trim();
18454
+ if (requested) {
18455
+ return this.#available.find((dataset) => dataset.matches(requested)) ?? null;
18456
+ }
18457
+ if (this.#returned.length === 1) return this.#returned[0];
18458
+ return this.#returned.length === 0 && this.#recovered.length === 1 ? this.#recovered[0] : null;
18459
+ }
18460
+ };
18461
+ var RunDataset = class _RunDataset {
18462
+ #info;
18463
+ constructor(info) {
18464
+ this.#info = info;
18465
+ }
18466
+ static from(info) {
18467
+ return new _RunDataset(info);
18468
+ }
18469
+ get source() {
18470
+ return this.#info.source;
18471
+ }
18472
+ get datasetId() {
18473
+ return this.#info.datasetId;
18474
+ }
18475
+ get tableNamespace() {
18476
+ return this.#info.tableNamespace;
18477
+ }
18478
+ get rows() {
18479
+ return this.#info.rows;
18480
+ }
18481
+ get totalRows() {
18482
+ return this.#info.totalRows;
18483
+ }
18484
+ get complete() {
18485
+ return this.#info.complete;
18486
+ }
18487
+ get recovered() {
18488
+ return this.#info.recovered;
18489
+ }
18490
+ get exportUnavailableReason() {
18491
+ return this.#info.exportUnavailableReason;
18492
+ }
18493
+ get exportUnavailableMessage() {
18494
+ return this.#info.exportUnavailableMessage;
18495
+ }
18496
+ matches(path) {
18497
+ return this.source === path || this.datasetId === path || this.tableNamespace === path;
18498
+ }
18499
+ /** Return a new Handle when its preview has been replaced by fetched rows. */
18500
+ withRows(info) {
18501
+ return _RunDataset.from(info);
18502
+ }
18503
+ /** Write this Dataset's stable, non-flattening CSV Projection. */
18504
+ exportCsv(outPath) {
18505
+ if (!this.complete) {
18506
+ throw new Error(
18507
+ `Run Dataset '${this.source ?? this.tableNamespace ?? "dataset"}' only includes ${this.rows.length} preview row(s) of ${this.totalRows}; cannot export a complete CSV yet.`
18508
+ );
18509
+ }
18510
+ return writeRunDatasetCsv({
18511
+ rows: this.rows,
18512
+ columns: this.#info.columns,
18513
+ outPath
18514
+ });
18515
+ }
18516
+ /** Compatibility seam for callers which still return CanonicalRowsInfo. */
18517
+ info() {
18518
+ return this.#info;
18519
+ }
18520
+ };
18521
+ function distinctRunDatasets(infos) {
18522
+ const byIdentity = /* @__PURE__ */ new Map();
18523
+ for (const info of infos) {
18524
+ const identity = info.datasetId?.trim() ? `id:${info.datasetId.trim()}` : `path:${info.source ?? info.tableNamespace ?? "dataset"}`;
18525
+ const existing = byIdentity.get(identity);
18526
+ byIdentity.set(
18527
+ identity,
18528
+ existing ? mergeCanonicalRowsInfo(existing, info) : info
18529
+ );
18530
+ }
18531
+ return [...byIdentity.values()];
18532
+ }
18533
+ function packageForDatasetSelection(runPackage) {
18534
+ const root = recordValue(runPackage);
18535
+ const nested = recordValue(root.package);
18536
+ if (nested?.kind === "play_run") return nested;
18537
+ return root.kind === "play_run" ? root : null;
18538
+ }
18539
+ function withReturnedDatasetAliases(runPackage, available) {
18540
+ const outputs = recordValue(packageForDatasetSelection(runPackage)?.outputs);
18541
+ if (Object.keys(outputs).length === 0) return available;
18542
+ const expanded = [...available];
18543
+ for (const outputValue of Object.values(outputs)) {
18544
+ const output2 = recordValue(outputValue);
18545
+ if (output2.kind !== "dataset") continue;
18546
+ const alias = stringValue2(output2.path);
18547
+ if (!alias) continue;
18548
+ const datasetId = stringValue2(output2.datasetId);
18549
+ const canonicalPath2 = stringValue2(output2.dataset);
18550
+ const canonical = available.find(
18551
+ (info) => datasetId && info.datasetId === datasetId || canonicalPath2 && info.source === canonicalPath2
18552
+ );
18553
+ if (!canonical) continue;
18554
+ const aliasIndex = expanded.findIndex((info) => info.source === alias);
18555
+ if (aliasIndex >= 0) {
18556
+ expanded[aliasIndex] = {
18557
+ ...mergeCanonicalRowsInfo(expanded[aliasIndex], canonical),
18558
+ source: alias
18559
+ };
18560
+ } else {
18561
+ expanded.push({ ...canonical, source: alias });
18562
+ }
18563
+ }
18564
+ return expanded;
18565
+ }
18566
+ function returnedRunDatasets(runPackage, available) {
18567
+ const outputs = recordValue(packageForDatasetSelection(runPackage)?.outputs);
18568
+ if (Object.keys(outputs).length > 0) {
18569
+ const selected = /* @__PURE__ */ new Map();
18570
+ for (const outputValue of Object.values(outputs)) {
18571
+ const output2 = recordValue(outputValue);
18572
+ if (output2.kind !== "dataset") continue;
18573
+ const datasetId = stringValue2(output2.datasetId);
18574
+ const alias = stringValue2(output2.path);
18575
+ const canonicalPath2 = stringValue2(output2.dataset);
18576
+ const info = (alias ? available.find((candidate) => candidate.source === alias) : null) ?? (datasetId ? available.find((candidate) => candidate.datasetId === datasetId) : null) ?? (canonicalPath2 ? available.find((candidate) => candidate.source === canonicalPath2) : null);
18577
+ if (!info) continue;
18578
+ const identity = datasetId ? `id:${datasetId}` : `path:${canonicalPath2 ?? alias ?? info.source ?? "dataset"}`;
18579
+ const aliased = { ...info, source: alias ?? info.source };
18580
+ const existing = selected.get(identity);
18581
+ selected.set(
18582
+ identity,
18583
+ existing ? mergeCanonicalRowsInfo(existing, aliased) : aliased
18584
+ );
18585
+ }
18586
+ if (selected.size > 0) return [...selected.values()];
18587
+ }
18588
+ return distinctRunDatasets(
18589
+ available.filter(
18590
+ (info) => Boolean(info.source?.startsWith("result.")) && !info.recovered
18591
+ )
18592
+ );
18593
+ }
18594
+ function recordValue(value) {
18595
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
18596
+ }
18597
+ function stringValue2(value) {
18598
+ return typeof value === "string" && value.trim() ? value.trim() : null;
18599
+ }
18600
+
18327
18601
  // src/cli/progress.ts
18328
18602
  import { Worker } from "worker_threads";
18329
18603
  var CliProgress = class {
@@ -18593,7 +18867,7 @@ ${hint}`;
18593
18867
 
18594
18868
  // ../play-runtime/governor/policy.ts
18595
18869
  var DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS = 64;
18596
- var MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS = 256;
18870
+ var MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS = 1e3;
18597
18871
  var MAX_CONFIGURABLE_CONCURRENT_ROWS = 1e3;
18598
18872
  function resolveMaxConcurrentExternalCalls(requested) {
18599
18873
  if (requested === void 0 || requested === null) {
@@ -19135,8 +19409,7 @@ var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
19135
19409
  "--force",
19136
19410
  "--force-tool-refresh",
19137
19411
  "--open",
19138
- "--debug-map-latency",
19139
- "--debug-fixture-provider-pacing"
19412
+ "--debug-map-latency"
19140
19413
  ]);
19141
19414
  async function pathExistsIncludingSymlink(path) {
19142
19415
  try {
@@ -19271,7 +19544,7 @@ function traceCliSync(phase, fields, run) {
19271
19544
  }
19272
19545
  }
19273
19546
  function sleep5(ms) {
19274
- return new Promise((resolve19) => setTimeout(resolve19, ms));
19547
+ return new Promise((resolve20) => setTimeout(resolve20, ms));
19275
19548
  }
19276
19549
  function parseReferencedPlayTarget2(target) {
19277
19550
  const trimmed = target.trim();
@@ -20842,7 +21115,7 @@ async function waitForPlayCompletionByStream(input2) {
20842
21115
  try {
20843
21116
  for await (const event of input2.client.streamPlayRunEvents(
20844
21117
  input2.workflowId,
20845
- { signal: controller.signal, waitForProjection: true }
21118
+ { signal: controller.signal }
20846
21119
  )) {
20847
21120
  sawEvent = true;
20848
21121
  const terminal = await handleLiveEvent(event);
@@ -22584,103 +22857,6 @@ async function fetchBackingDatasetRows(input2) {
22584
22857
  source: `${input2.rowsInfo.source ?? "result.rows"} -> /api/v2/plays/${playName}/sheet?tableNamespace=${tableNamespace}`
22585
22858
  };
22586
22859
  }
22587
- function resolveDatasetByName(available, datasetPath) {
22588
- const target = datasetPath.trim();
22589
- const exact = available.find((info) => info.source === target);
22590
- if (exact) {
22591
- return exact;
22592
- }
22593
- const byDatasetId = available.find((info) => info.datasetId === target);
22594
- if (byDatasetId) {
22595
- return byDatasetId;
22596
- }
22597
- const byNamespace = available.find(
22598
- (info) => info.tableNamespace && info.tableNamespace === target
22599
- );
22600
- if (byNamespace) {
22601
- return byNamespace;
22602
- }
22603
- return null;
22604
- }
22605
- function canonicalRowsIdentity(info) {
22606
- return info.datasetId?.trim() ? `id:${info.datasetId.trim()}` : `path:${info.source ?? info.tableNamespace ?? "dataset"}`;
22607
- }
22608
- function distinctCanonicalRowsInfos(infos) {
22609
- const byIdentity = /* @__PURE__ */ new Map();
22610
- for (const info of infos) {
22611
- const identity = canonicalRowsIdentity(info);
22612
- const existing = byIdentity.get(identity);
22613
- byIdentity.set(
22614
- identity,
22615
- existing ? mergeCanonicalRowsInfo(existing, info) : info
22616
- );
22617
- }
22618
- return [...byIdentity.values()];
22619
- }
22620
- function packageForExportSelection(status) {
22621
- const root = status;
22622
- const nested = readRecord(root.package);
22623
- if (nested?.kind === "play_run") return nested;
22624
- return root.kind === "play_run" ? root : null;
22625
- }
22626
- function withReturnedDatasetAliases(status, available) {
22627
- const packaged = packageForExportSelection(status);
22628
- const outputs = readRecord(packaged?.outputs);
22629
- if (!outputs) return available;
22630
- const expanded = [...available];
22631
- for (const outputValue of Object.values(outputs)) {
22632
- const output2 = readRecord(outputValue);
22633
- if (output2?.kind !== "dataset") continue;
22634
- const alias = typeof output2.path === "string" && output2.path.trim() ? output2.path.trim() : null;
22635
- if (!alias) continue;
22636
- const datasetId = typeof output2.datasetId === "string" && output2.datasetId.trim() ? output2.datasetId.trim() : null;
22637
- const canonicalPath2 = typeof output2.dataset === "string" && output2.dataset.trim() ? output2.dataset.trim() : null;
22638
- const canonical = available.find(
22639
- (info) => datasetId && info.datasetId === datasetId || canonicalPath2 && info.source === canonicalPath2
22640
- );
22641
- if (canonical) {
22642
- const aliasIndex = expanded.findIndex((info) => info.source === alias);
22643
- if (aliasIndex >= 0) {
22644
- expanded[aliasIndex] = {
22645
- ...mergeCanonicalRowsInfo(expanded[aliasIndex], canonical),
22646
- source: alias
22647
- };
22648
- } else {
22649
- expanded.push({ ...canonical, source: alias });
22650
- }
22651
- }
22652
- }
22653
- return expanded;
22654
- }
22655
- function returnedRowsInfos(status, available) {
22656
- const packaged = packageForExportSelection(status);
22657
- const outputs = readRecord(packaged?.outputs);
22658
- if (outputs) {
22659
- const selected = /* @__PURE__ */ new Map();
22660
- for (const outputValue of Object.values(outputs)) {
22661
- const output2 = readRecord(outputValue);
22662
- if (output2?.kind !== "dataset") continue;
22663
- const datasetId = typeof output2.datasetId === "string" && output2.datasetId.trim() ? output2.datasetId.trim() : null;
22664
- const alias = typeof output2.path === "string" && output2.path.trim() ? output2.path.trim() : null;
22665
- const canonicalPath2 = typeof output2.dataset === "string" && output2.dataset.trim() ? output2.dataset.trim() : null;
22666
- const info = (alias ? available.find((candidate) => candidate.source === alias) : null) ?? (datasetId ? available.find((candidate) => candidate.datasetId === datasetId) : null) ?? (canonicalPath2 ? available.find((candidate) => candidate.source === canonicalPath2) : null);
22667
- if (!info) continue;
22668
- const identity = datasetId ? `id:${datasetId}` : `path:${canonicalPath2 ?? alias ?? info.source ?? "dataset"}`;
22669
- const aliased = { ...info, source: alias ?? info.source };
22670
- const existing = selected.get(identity);
22671
- selected.set(
22672
- identity,
22673
- existing ? mergeCanonicalRowsInfo(existing, aliased) : aliased
22674
- );
22675
- }
22676
- if (selected.size > 0) return [...selected.values()];
22677
- }
22678
- return distinctCanonicalRowsInfos(
22679
- available.filter(
22680
- (info) => Boolean(info.source?.startsWith("result.")) && !info.recovered
22681
- )
22682
- );
22683
- }
22684
22860
  function exportDatasetCommand(input2) {
22685
22861
  return `deepline runs export ${input2.runId} --dataset ${shellSingleQuote(
22686
22862
  input2.datasetPath
@@ -22739,16 +22915,17 @@ async function exportPlayStatusRows(client2, status, outPath, options = {}) {
22739
22915
  if (!outPath) {
22740
22916
  return null;
22741
22917
  }
22742
- const availableRows = withReturnedDatasetAliases(
22743
- status,
22744
- distinctCanonicalRowsInfos(collectSerializedDatasetRowsInfos(status))
22745
- );
22746
- const returnedRows = returnedRowsInfos(status, availableRows);
22747
- const recoveredRows = distinctCanonicalRowsInfos(
22748
- availableRows.filter((info) => info.recovered)
22749
- );
22750
- const rowsInfo = options.datasetPath ? resolveDatasetByName(availableRows, options.datasetPath) ?? null : returnedRows.length === 1 ? returnedRows[0] : returnedRows.length === 0 && recoveredRows.length === 1 ? recoveredRows[0] : null;
22751
- if (!rowsInfo && options.datasetPath) {
22918
+ const run = Run.open({
22919
+ runPackage: status,
22920
+ datasets: LegacyRunDatasetCatalogAdapter.datasets(status)
22921
+ });
22922
+ const datasets = run.datasets();
22923
+ const availableRows = datasets.available().map((dataset) => dataset.info());
22924
+ const returnedRows = datasets.returned().map((dataset) => dataset.info());
22925
+ const recoveredRows = datasets.recovered().map((dataset) => dataset.info());
22926
+ const selectedDataset = run.dataset(options.datasetPath);
22927
+ const rowsInfo = selectedDataset?.info() ?? null;
22928
+ if (!selectedDataset && options.datasetPath) {
22752
22929
  const available = availableRows.map((info) => info.source).filter((source) => typeof source === "string");
22753
22930
  const commands = datasetChoiceLines({
22754
22931
  runId: status.runId,
@@ -22839,7 +23016,7 @@ ${commands.join("\n")}`,
22839
23016
  datasetPath: options.datasetPath
22840
23017
  });
22841
23018
  return {
22842
- path: writeCanonicalRowsCsv(guarded2, outPath),
23019
+ path: RunDataset.from(guarded2).exportCsv(outPath),
22843
23020
  rowsInfo: guarded2
22844
23021
  };
22845
23022
  }
@@ -22851,7 +23028,7 @@ ${commands.join("\n")}`,
22851
23028
  datasetPath: options.datasetPath
22852
23029
  });
22853
23030
  return {
22854
- path: writeCanonicalRowsCsv(guarded2, outPath),
23031
+ path: RunDataset.from(guarded2).exportCsv(outPath),
22855
23032
  rowsInfo: guarded2
22856
23033
  };
22857
23034
  }
@@ -22885,7 +23062,10 @@ ${commands.join("\n")}`,
22885
23062
  availableRows,
22886
23063
  datasetPath: options.datasetPath
22887
23064
  });
22888
- return { path: writeCanonicalRowsCsv(guarded, outPath), rowsInfo: guarded };
23065
+ return {
23066
+ path: RunDataset.from(guarded).exportCsv(outPath),
23067
+ rowsInfo: guarded
23068
+ };
22889
23069
  }
22890
23070
  function extractActiveRunsFromError(error) {
22891
23071
  if (!(error instanceof DeeplineError)) {
@@ -23179,9 +23359,6 @@ function parsePlayRunOptions(args) {
23179
23359
  const forceToolRefresh = args.includes("--force-tool-refresh");
23180
23360
  const open2 = args.includes("--open");
23181
23361
  const debugMapLatency = args.includes("--debug-map-latency");
23182
- const debugFixtureProviderPacing = args.includes(
23183
- "--debug-fixture-provider-pacing"
23184
- );
23185
23362
  const verboseLogs = args.includes("--logs") || debugMapLatency;
23186
23363
  let waitTimeoutMs = null;
23187
23364
  let maxConcurrentExternalCalls = null;
@@ -23385,7 +23562,6 @@ function parsePlayRunOptions(args) {
23385
23562
  open: open2,
23386
23563
  profile,
23387
23564
  debugMapLatency,
23388
- debugFixtureProviderPacing,
23389
23565
  fixtureBehavior,
23390
23566
  runIdFile
23391
23567
  };
@@ -23551,7 +23727,7 @@ function formatPlayRuntimeLimit(runtimeLimit) {
23551
23727
  function isRecord10(value) {
23552
23728
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
23553
23729
  }
23554
- function stringValue2(value) {
23730
+ function stringValue3(value) {
23555
23731
  return typeof value === "string" ? value.trim() : "";
23556
23732
  }
23557
23733
  function asArray(value) {
@@ -23571,11 +23747,11 @@ function firstRawPath(entry) {
23571
23747
  ...asArray(details.raw_tool_output_paths),
23572
23748
  ...asArray(details.candidatePaths),
23573
23749
  ...asArray(details.candidate_paths)
23574
- ].map(stringValue2).filter(Boolean);
23750
+ ].map(stringValue3).filter(Boolean);
23575
23751
  return paths[0];
23576
23752
  }
23577
23753
  function checkHintExpression(value) {
23578
- return stringValue2(value).replace(/^toolExecutionResult\./, "result.");
23754
+ return stringValue3(value).replace(/^toolExecutionResult\./, "result.");
23579
23755
  }
23580
23756
  function checkHintRawPath(value) {
23581
23757
  return value?.replace(/^toolResponse\./, "result.toolResponse.");
@@ -23590,7 +23766,7 @@ function collectStaticPipelineToolIds(staticPipeline) {
23590
23766
  ]) {
23591
23767
  if (!isRecord10(step)) continue;
23592
23768
  if (step.type === "tool") {
23593
- const toolId = stringValue2(step.toolId) || stringValue2(step.tool);
23769
+ const toolId = stringValue3(step.toolId) || stringValue3(step.tool);
23594
23770
  if (toolId) seen.add(toolId);
23595
23771
  }
23596
23772
  if (step.type === "play_call") {
@@ -23608,14 +23784,14 @@ function toolGetterHintFromMetadata(toolId, tool) {
23608
23784
  const lists = extractionEntries2(
23609
23785
  resultGuidance.extractedLists ?? resultGuidance.extracted_lists
23610
23786
  ).map((entry) => ({
23611
- name: stringValue2(entry.name),
23787
+ name: stringValue3(entry.name),
23612
23788
  expression: checkHintExpression(entry.expression),
23613
23789
  raw: checkHintRawPath(firstRawPath(entry))
23614
23790
  })).filter((entry) => entry.name && entry.expression);
23615
23791
  const values = extractionEntries2(
23616
23792
  resultGuidance.extractedValues ?? resultGuidance.extracted_values
23617
23793
  ).map((entry) => ({
23618
- name: stringValue2(entry.name),
23794
+ name: stringValue3(entry.name),
23619
23795
  expression: checkHintExpression(entry.expression),
23620
23796
  raw: checkHintRawPath(firstRawPath(entry))
23621
23797
  })).filter((entry) => entry.name && entry.expression);
@@ -24176,14 +24352,8 @@ async function handleFileBackedRun(options, hooks) {
24176
24352
  "--fixture-behavior requires DEEPLINE_EVAL_INTEGRATION_MODE=fixture."
24177
24353
  );
24178
24354
  }
24179
- if (options.debugFixtureProviderPacing && integrationMode !== "fixture") {
24180
- throw new Error(
24181
- "--debug-fixture-provider-pacing requires DEEPLINE_EVAL_INTEGRATION_MODE=fixture."
24182
- );
24183
- }
24184
24355
  const testPolicyOverrides = {
24185
- ...options.debugMapLatency ? { mapLatencyProfile: true } : {},
24186
- ...options.debugFixtureProviderPacing ? { enforceFixtureProviderPacing: true } : {}
24356
+ ...options.debugMapLatency ? { mapLatencyProfile: true } : {}
24187
24357
  };
24188
24358
  const startRequest = {
24189
24359
  name: playName,
@@ -24365,14 +24535,8 @@ async function handleNamedRun(options, hooks) {
24365
24535
  "--fixture-behavior requires DEEPLINE_EVAL_INTEGRATION_MODE=fixture."
24366
24536
  );
24367
24537
  }
24368
- if (options.debugFixtureProviderPacing && integrationMode !== "fixture") {
24369
- throw new Error(
24370
- "--debug-fixture-provider-pacing requires DEEPLINE_EVAL_INTEGRATION_MODE=fixture."
24371
- );
24372
- }
24373
24538
  const testPolicyOverrides = {
24374
- ...options.debugMapLatency ? { mapLatencyProfile: true } : {},
24375
- ...options.debugFixtureProviderPacing ? { enforceFixtureProviderPacing: true } : {}
24539
+ ...options.debugMapLatency ? { mapLatencyProfile: true } : {}
24376
24540
  };
24377
24541
  const startRequest = {
24378
24542
  name: playName,
@@ -26257,9 +26421,6 @@ Examples:
26257
26421
  ).option("--open", "Open the play page in a browser after the run starts").option(
26258
26422
  "--debug-map-latency",
26259
26423
  "Internal diagnostics: emit one aggregate latency profile per dataset map"
26260
- ).option(
26261
- "--debug-fixture-provider-pacing",
26262
- "Internal diagnostics: retain provider pacing while fixture mode is active"
26263
26424
  ).option("--json", "Emit JSON output").option("--full", "Debug only: with --json, emit the raw status payload").addHelpText(
26264
26425
  "afterAll",
26265
26426
  `
@@ -26306,7 +26467,6 @@ Pass-through input flags:
26306
26467
  ...options.maxConcurrentRows ? ["--max-concurrent-rows", options.maxConcurrentRows] : [],
26307
26468
  ...options.open ? ["--open"] : [],
26308
26469
  ...options.debugMapLatency ? ["--debug-map-latency"] : [],
26309
- ...options.debugFixtureProviderPacing ? ["--debug-fixture-provider-pacing"] : [],
26310
26470
  ...options.json ? ["--json"] : [],
26311
26471
  ...options.full ? ["--full"] : [],
26312
26472
  ...passthroughArgs
@@ -28728,7 +28888,7 @@ function emitEnrichDebug(message) {
28728
28888
  );
28729
28889
  }
28730
28890
  function sleep6(ms) {
28731
- return new Promise((resolve19) => setTimeout(resolve19, ms));
28891
+ return new Promise((resolve20) => setTimeout(resolve20, ms));
28732
28892
  }
28733
28893
  function enrichExportBackingRowsWaitMs() {
28734
28894
  const raw = process.env.DEEPLINE_ENRICH_EXPORT_BACKING_ROWS_WAIT_MS?.trim();
@@ -35168,7 +35328,7 @@ async function readHiddenLine(prompt, streams = {}) {
35168
35328
  }
35169
35329
  let value = "";
35170
35330
  inputStream.resume();
35171
- return await new Promise((resolve19, reject) => {
35331
+ return await new Promise((resolve20, reject) => {
35172
35332
  let settled = false;
35173
35333
  const cleanup = () => {
35174
35334
  inputStream.off("data", onData);
@@ -35186,7 +35346,7 @@ async function readHiddenLine(prompt, streams = {}) {
35186
35346
  settled = true;
35187
35347
  outputStream.write("\n");
35188
35348
  cleanup();
35189
- resolve19(line);
35349
+ resolve20(line);
35190
35350
  };
35191
35351
  const fail = (error) => {
35192
35352
  if (settled) return;
@@ -35359,22 +35519,149 @@ Examples:
35359
35519
  // src/cli/commands/setup.ts
35360
35520
  import { spawnSync as spawnSync2 } from "child_process";
35361
35521
  import {
35362
- existsSync as existsSync13,
35363
- lstatSync,
35522
+ existsSync as existsSync14,
35523
+ lstatSync as lstatSync2,
35364
35524
  mkdirSync as mkdirSync11,
35365
- readFileSync as readFileSync13,
35366
- realpathSync as realpathSync3,
35367
- rmSync as rmSync4,
35525
+ readFileSync as readFileSync14,
35526
+ realpathSync as realpathSync4,
35368
35527
  writeFileSync as writeFileSync14
35369
35528
  } from "fs";
35370
35529
  import { homedir as homedir9 } from "os";
35371
- import { basename as basename6, dirname as dirname15, join as join15, relative as relative5, resolve as resolve14 } from "path";
35530
+ import { dirname as dirname16, join as join16, resolve as resolve15 } from "path";
35531
+
35532
+ // src/cli/installation-lifecycle.ts
35533
+ import {
35534
+ existsSync as existsSync11,
35535
+ lstatSync,
35536
+ readFileSync as readFileSync11,
35537
+ realpathSync as realpathSync3,
35538
+ rmSync as rmSync4
35539
+ } from "fs";
35540
+ import { basename as basename6, dirname as dirname13, join as join13, relative as relative5, resolve as resolve14 } from "path";
35541
+ var nodeFileSystem = {
35542
+ exists: existsSync11,
35543
+ isSymbolicLink(path) {
35544
+ try {
35545
+ return lstatSync(path).isSymbolicLink();
35546
+ } catch {
35547
+ return false;
35548
+ }
35549
+ },
35550
+ read(path) {
35551
+ try {
35552
+ return readFileSync11(path, "utf8");
35553
+ } catch {
35554
+ return "";
35555
+ }
35556
+ },
35557
+ realpath(path) {
35558
+ try {
35559
+ return realpathSync3(path);
35560
+ } catch {
35561
+ return null;
35562
+ }
35563
+ },
35564
+ remove(path) {
35565
+ rmSync4(path, { force: true });
35566
+ }
35567
+ };
35568
+ function inspectLauncher(path, fileSystem = nodeFileSystem) {
35569
+ if (!fileSystem.exists(path)) {
35570
+ return { ownership: "missing", resolvedPath: null };
35571
+ }
35572
+ const resolvedPath = fileSystem.realpath(path);
35573
+ if (CliInstallation.isNpmPackagePath(resolvedPath)) {
35574
+ return { ownership: "npm", resolvedPath };
35575
+ }
35576
+ if (fileSystem.isSymbolicLink(path)) {
35577
+ return { ownership: "symlink", resolvedPath };
35578
+ }
35579
+ const content = fileSystem.read(path);
35580
+ if (content.includes("DEEPLINE_REAL_BINARY") && content.includes("DEEPLINE_ACTIVE_FILE")) {
35581
+ return { ownership: "installer_legacy", resolvedPath };
35582
+ }
35583
+ return { ownership: "user", resolvedPath };
35584
+ }
35585
+ var CliInstallation = class _CliInstallation {
35586
+ constructor(input2) {
35587
+ this.input = input2;
35588
+ }
35589
+ static forUser(input2) {
35590
+ return new _CliInstallation({
35591
+ ...input2,
35592
+ fileSystem: input2.fileSystem ?? nodeFileSystem
35593
+ });
35594
+ }
35595
+ static isNpmPackagePath(path) {
35596
+ return path?.includes(`${join13("node_modules", "deepline")}`) ?? false;
35597
+ }
35598
+ launcher(path) {
35599
+ return inspectLauncher(path, this.input.fileSystem);
35600
+ }
35601
+ retiredArtifacts() {
35602
+ const hostDir = join13(
35603
+ this.input.home,
35604
+ ".local",
35605
+ "deepline",
35606
+ this.input.baseUrlSlug
35607
+ );
35608
+ const legacyLauncherPath = join13(
35609
+ this.input.home,
35610
+ ".local",
35611
+ "bin",
35612
+ "deepline"
35613
+ );
35614
+ const installerCommandPath = this.input.fileSystem.read(join13(hostDir, "sdk", ".command-path")).trim();
35615
+ const ownedInstallerCommand = isOwnedInstallerCommandPath({
35616
+ hostDir,
35617
+ commandPath: installerCommandPath
35618
+ });
35619
+ const legacyLauncher = this.launcher(legacyLauncherPath);
35620
+ const candidates = [
35621
+ ...legacyLauncher.ownership === "installer_legacy" ? [legacyLauncherPath] : [],
35622
+ join13(this.input.home, ".local", "bin", "deepline-real"),
35623
+ join13(hostDir, "bin", "deepline"),
35624
+ join13(hostDir, "bin", "deepline-real"),
35625
+ join13(hostDir, "cli", ".install-method"),
35626
+ join13(hostDir, "cli", ".version"),
35627
+ join13(hostDir, "sdk", ".install-method"),
35628
+ join13(hostDir, "sdk", ".command-path"),
35629
+ ...ownedInstallerCommand ? [
35630
+ installerCommandPath,
35631
+ join13(dirname13(installerCommandPath), "deepline-sdk")
35632
+ ] : []
35633
+ ];
35634
+ return {
35635
+ paths: candidates.filter((path) => {
35636
+ if (!this.input.fileSystem.exists(path)) return false;
35637
+ return this.launcher(path).ownership !== "npm";
35638
+ })
35639
+ };
35640
+ }
35641
+ removeRetiredArtifacts() {
35642
+ return removeArtifacts(this.retiredArtifacts(), this.input.fileSystem);
35643
+ }
35644
+ };
35645
+ function removeArtifacts(plan, fileSystem) {
35646
+ for (const path of plan.paths) {
35647
+ fileSystem.remove(path);
35648
+ }
35649
+ return plan.paths;
35650
+ }
35651
+ function isOwnedInstallerCommandPath(input2) {
35652
+ if (!input2.commandPath || basename6(input2.commandPath) !== "deepline") {
35653
+ return false;
35654
+ }
35655
+ const commandPath = resolve14(input2.commandPath);
35656
+ const fromHost = relative5(resolve14(input2.hostDir), commandPath);
35657
+ return fromHost !== "" && fromHost !== ".." && !fromHost.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`);
35658
+ }
35372
35659
 
35373
35660
  // src/cli/commands/skills.ts
35374
35661
  import { spawn as spawn3 } from "child_process";
35375
- import { existsSync as existsSync12, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync13 } from "fs";
35662
+ import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
35376
35663
  import { homedir as homedir8 } from "os";
35377
- import { dirname as dirname14, join as join14 } from "path";
35664
+ import { dirname as dirname15, join as join15 } from "path";
35378
35665
 
35379
35666
  // ../../shared_libs/cli/install-commands.json
35380
35667
  var install_commands_default = {
@@ -35479,13 +35766,13 @@ function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
35479
35766
  // src/cli/skills-sync.ts
35480
35767
  import { spawn as spawn2, spawnSync } from "child_process";
35481
35768
  import {
35482
- existsSync as existsSync11,
35769
+ existsSync as existsSync12,
35483
35770
  mkdirSync as mkdirSync9,
35484
- readFileSync as readFileSync11,
35771
+ readFileSync as readFileSync12,
35485
35772
  unlinkSync,
35486
35773
  writeFileSync as writeFileSync12
35487
35774
  } from "fs";
35488
- import { dirname as dirname13, join as join13 } from "path";
35775
+ import { dirname as dirname14, join as join14 } from "path";
35489
35776
 
35490
35777
  // src/cli/windows-arg-escape.ts
35491
35778
  var CMD_META_CHARS = /([()\][%!^"`<>&|;, *?])/g;
@@ -35520,10 +35807,10 @@ function shouldSkipSkillsSync() {
35520
35807
  return value === "1" || value === "true" || value === "yes" || value === "on";
35521
35808
  }
35522
35809
  function unavailableSkillsNoticePath(baseUrl) {
35523
- return join13(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
35810
+ return join14(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
35524
35811
  }
35525
35812
  function failedSkillsSyncPath(baseUrl, agents) {
35526
- return join13(
35813
+ return join14(
35527
35814
  sdkCliStateDirPath(baseUrl),
35528
35815
  `skills-sync-failed-${agents.join("-")}-version`
35529
35816
  );
@@ -35533,14 +35820,14 @@ function hasMarkedSkillsSyncVersion(path, version) {
35533
35820
  }
35534
35821
  function readMarkedSkillsSyncVersion(path) {
35535
35822
  try {
35536
- return existsSync11(path) ? readFileSync11(path, "utf-8").trim() : "";
35823
+ return existsSync12(path) ? readFileSync12(path, "utf-8").trim() : "";
35537
35824
  } catch {
35538
35825
  return "";
35539
35826
  }
35540
35827
  }
35541
35828
  function writeMarkedSkillsSyncVersion(path, version) {
35542
35829
  try {
35543
- mkdirSync9(dirname13(path), { recursive: true });
35830
+ mkdirSync9(dirname14(path), { recursive: true });
35544
35831
  writeFileSync12(path, `${version}
35545
35832
  `, "utf-8");
35546
35833
  } catch {
@@ -35569,7 +35856,7 @@ function hasFailedSkillsSync(baseUrl, remoteVersion, agents) {
35569
35856
  );
35570
35857
  }
35571
35858
  function hasFailedAutomaticSkillsSync(baseUrl, agents) {
35572
- return existsSync11(failedSkillsSyncPath(baseUrl, agents));
35859
+ return existsSync12(failedSkillsSyncPath(baseUrl, agents));
35573
35860
  }
35574
35861
  function markFailedSkillsSync(baseUrl, remoteVersion, agents) {
35575
35862
  writeMarkedSkillsSyncVersion(
@@ -35694,7 +35981,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
35694
35981
  return commands;
35695
35982
  }
35696
35983
  function runOneSkillsInstall(install) {
35697
- return new Promise((resolve19) => {
35984
+ return new Promise((resolve20) => {
35698
35985
  const plan = resolveSkillsInstallSpawn(install);
35699
35986
  const child = spawn2(plan.command, plan.args, {
35700
35987
  stdio: ["ignore", "ignore", "pipe"],
@@ -35706,7 +35993,7 @@ function runOneSkillsInstall(install) {
35706
35993
  stderr += chunk.toString("utf-8");
35707
35994
  });
35708
35995
  child.on("error", (error) => {
35709
- resolve19({
35996
+ resolve20({
35710
35997
  ok: false,
35711
35998
  detail: `failed to start ${install.command}: ${error.message}`,
35712
35999
  manualCommand: install.manualCommand
@@ -35714,11 +36001,11 @@ function runOneSkillsInstall(install) {
35714
36001
  });
35715
36002
  child.on("close", (code) => {
35716
36003
  if (code === 0) {
35717
- resolve19({ ok: true, detail: "", manualCommand: install.manualCommand });
36004
+ resolve20({ ok: true, detail: "", manualCommand: install.manualCommand });
35718
36005
  return;
35719
36006
  }
35720
36007
  const detail = stderr.trim();
35721
- resolve19({
36008
+ resolve20({
35722
36009
  ok: false,
35723
36010
  detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
35724
36011
  manualCommand: install.manualCommand
@@ -35920,13 +36207,13 @@ function detectSkillsAgents(input2) {
35920
36207
  ];
35921
36208
  const detected = AGENT_MARKERS.filter(
35922
36209
  (marker) => roots.some(
35923
- (root) => marker.paths.some((path) => existsSync12(join14(root, path)))
36210
+ (root) => marker.paths.some((path) => existsSync13(join15(root, path)))
35924
36211
  )
35925
36212
  ).map((marker) => marker.agent);
35926
36213
  return detected.length > 0 ? detected : ["*"];
35927
36214
  }
35928
36215
  function skillsStatePathForScope(baseUrl, scope, root) {
35929
- return scope === "local" && root ? join14(root, ".deepline", "setup", "skills.json") : join14(sdkCliStateDirPath(baseUrl), "skills-install.json");
36216
+ return scope === "local" && root ? join15(root, ".deepline", "setup", "skills.json") : join15(sdkCliStateDirPath(baseUrl), "skills-install.json");
35930
36217
  }
35931
36218
  function buildSkillsPlan(input2) {
35932
36219
  const scopeArgs = input2.scope === "global" ? ["--global"] : [];
@@ -35993,14 +36280,14 @@ function isSkillsPlanCurrent(plan, state) {
35993
36280
  }
35994
36281
  function readSkillsInstallState(path) {
35995
36282
  try {
35996
- const parsed = JSON.parse(readFileSync12(path, "utf8"));
36283
+ const parsed = JSON.parse(readFileSync13(path, "utf8"));
35997
36284
  return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
35998
36285
  } catch {
35999
36286
  return null;
36000
36287
  }
36001
36288
  }
36002
36289
  function runProcess(command, args, cwd) {
36003
- return new Promise((resolve19, reject) => {
36290
+ return new Promise((resolve20, reject) => {
36004
36291
  const plan = resolveShellSpawn(command, args);
36005
36292
  const child = spawn3(plan.command, plan.args, {
36006
36293
  cwd,
@@ -36019,7 +36306,7 @@ function runProcess(command, args, cwd) {
36019
36306
  process.stderr.write(`${SKILLS_NPX_PACKAGE} exited ${code}.
36020
36307
  `);
36021
36308
  }
36022
- resolve19(code ?? 1);
36309
+ resolve20(code ?? 1);
36023
36310
  });
36024
36311
  });
36025
36312
  }
@@ -36137,7 +36424,7 @@ async function runSkillsCommand(options, dependencies = {}) {
36137
36424
  );
36138
36425
  return 5;
36139
36426
  }
36140
- mkdirSync10(dirname14(plan.statePath), { recursive: true });
36427
+ mkdirSync10(dirname15(plan.statePath), { recursive: true });
36141
36428
  writeFileSync13(
36142
36429
  plan.statePath,
36143
36430
  `${JSON.stringify(
@@ -36275,7 +36562,7 @@ function phasesFromLegacyStatus(status) {
36275
36562
  function readSetupState(input2) {
36276
36563
  try {
36277
36564
  const parsed = JSON.parse(
36278
- readFileSync13(
36565
+ readFileSync14(
36279
36566
  setupStatePath(input2.baseUrl, input2.scope, input2.root),
36280
36567
  "utf8"
36281
36568
  )
@@ -36351,7 +36638,7 @@ function buildPendingAuthorizationOutput(input2) {
36351
36638
  };
36352
36639
  }
36353
36640
  function setupStatePath(baseUrl, scope, root) {
36354
- return scope === "local" && root ? join15(root, ".deepline", "setup", "state.json") : join15(sdkCliStateDirPath(baseUrl), "setup.json");
36641
+ return scope === "local" && root ? join16(root, ".deepline", "setup", "state.json") : join16(sdkCliStateDirPath(baseUrl), "setup.json");
36355
36642
  }
36356
36643
  async function captureStdout2(run) {
36357
36644
  let stdout = "";
@@ -36380,57 +36667,16 @@ function asRecord3(value) {
36380
36667
  }
36381
36668
  function safeRead(path) {
36382
36669
  try {
36383
- return readFileSync13(path, "utf8");
36670
+ return readFileSync14(path, "utf8");
36384
36671
  } catch {
36385
36672
  return "";
36386
36673
  }
36387
36674
  }
36388
- function isNpmManagedDeeplinePath(path) {
36389
- try {
36390
- return realpathSync3(path).includes(`${join15("node_modules", "deepline")}`);
36391
- } catch {
36392
- return false;
36393
- }
36394
- }
36395
- function isInstallerManagedLegacyLauncher(path) {
36396
- const content = safeRead(path);
36397
- return content.includes("DEEPLINE_REAL_BINARY") && content.includes("DEEPLINE_ACTIVE_FILE");
36398
- }
36399
36675
  function removeKnownLegacyPaths(baseUrl) {
36400
- const home = homedir9();
36401
- const hostDir = join15(home, ".local", "deepline", baseUrlSlug(baseUrl));
36402
- const legacyLauncherPath = join15(home, ".local", "bin", "deepline");
36403
- const installerCommandPath = safeRead(
36404
- join15(hostDir, "sdk", ".command-path")
36405
- ).trim();
36406
- const relativeInstallerCommandPath = installerCommandPath ? relative5(resolve14(hostDir), resolve14(installerCommandPath)) : "";
36407
- const isOwnedInstallerCommand = Boolean(installerCommandPath) && relativeInstallerCommandPath !== "" && !relativeInstallerCommandPath.startsWith(
36408
- `..${process.platform === "win32" ? "\\" : "/"}`
36409
- ) && relativeInstallerCommandPath !== ".." && basename6(installerCommandPath) === "deepline";
36410
- const candidates = [
36411
- ...isInstallerManagedLegacyLauncher(legacyLauncherPath) ? [legacyLauncherPath] : [],
36412
- join15(home, ".local", "bin", "deepline-real"),
36413
- join15(hostDir, "bin", "deepline"),
36414
- join15(hostDir, "bin", "deepline-real"),
36415
- join15(hostDir, "cli", ".install-method"),
36416
- join15(hostDir, "cli", ".version"),
36417
- join15(hostDir, "sdk", ".install-method"),
36418
- join15(hostDir, "sdk", ".command-path"),
36419
- ...isOwnedInstallerCommand ? [
36420
- installerCommandPath,
36421
- join15(dirname15(installerCommandPath), "deepline-sdk")
36422
- ] : []
36423
- ];
36424
- const removed = [];
36425
- for (const path of candidates) {
36426
- if (!existsSync13(path)) continue;
36427
- if (path === installerCommandPath && isNpmManagedDeeplinePath(path)) {
36428
- continue;
36429
- }
36430
- rmSync4(path, { force: true });
36431
- removed.push(path);
36432
- }
36433
- return removed;
36676
+ return CliInstallation.forUser({
36677
+ baseUrlSlug: baseUrlSlug(baseUrl),
36678
+ home: homedir9()
36679
+ }).removeRetiredArtifacts();
36434
36680
  }
36435
36681
  function resolvePathCommands(command) {
36436
36682
  const lookup = spawnSync2(
@@ -36440,7 +36686,7 @@ function resolvePathCommands(command) {
36440
36686
  );
36441
36687
  return [
36442
36688
  ...new Set(
36443
- String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) => resolve14(path))
36689
+ String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) => resolve15(path))
36444
36690
  )
36445
36691
  ];
36446
36692
  }
@@ -36450,7 +36696,7 @@ function resolvePathCommand(command) {
36450
36696
  function isHomebrewFormulaCommand(path) {
36451
36697
  let resolvedPath = path;
36452
36698
  try {
36453
- resolvedPath = realpathSync3(path);
36699
+ resolvedPath = realpathSync4(path);
36454
36700
  } catch {
36455
36701
  return false;
36456
36702
  }
@@ -36461,7 +36707,7 @@ function isHomebrewFormulaCommand(path) {
36461
36707
  function resolvePersistentGlobalCommand(dependencies = {}) {
36462
36708
  const platform3 = dependencies.platform ?? process.platform;
36463
36709
  const run = dependencies.spawn ?? spawnSync2;
36464
- const pathExists = dependencies.exists ?? existsSync13;
36710
+ const pathExists = dependencies.exists ?? existsSync14;
36465
36711
  const pathClis = dependencies.pathClis ?? resolvePathCommands("deepline");
36466
36712
  const homebrewCommand = pathClis.find(isHomebrewFormulaCommand);
36467
36713
  if (homebrewCommand) return homebrewCommand;
@@ -36473,7 +36719,7 @@ function resolvePersistentGlobalCommand(dependencies = {}) {
36473
36719
  if (prefix.status !== 0) return null;
36474
36720
  const root = String(prefix.stdout ?? "").trim();
36475
36721
  if (!root) return null;
36476
- const candidates = platform3 === "win32" ? [join15(root, "deepline.cmd"), join15(root, "deepline")] : [join15(root, "bin", "deepline")];
36722
+ const candidates = platform3 === "win32" ? [join16(root, "deepline.cmd"), join16(root, "deepline")] : [join16(root, "bin", "deepline")];
36477
36723
  return candidates.find((candidate) => pathExists(candidate)) ?? null;
36478
36724
  }
36479
36725
  function inspectGlobalCliAvailability(input2) {
@@ -36486,20 +36732,20 @@ function inspectGlobalCliAvailability(input2) {
36486
36732
  }
36487
36733
  function pathsResolveToSameFile(left, right) {
36488
36734
  try {
36489
- return realpathSync3(left) === realpathSync3(right);
36735
+ return realpathSync4(left) === realpathSync4(right);
36490
36736
  } catch {
36491
- return resolve14(left) === resolve14(right);
36737
+ return resolve15(left) === resolve15(right);
36492
36738
  }
36493
36739
  }
36494
36740
  function isKnownDeeplineCommand(path) {
36495
- const entrypoint = process.argv[1] ? resolve14(process.argv[1]) : "";
36741
+ const entrypoint = process.argv[1] ? resolve15(process.argv[1]) : "";
36496
36742
  let resolvedPath = path;
36497
36743
  try {
36498
- resolvedPath = realpathSync3(path);
36744
+ resolvedPath = realpathSync4(path);
36499
36745
  } catch {
36500
36746
  }
36501
36747
  if (entrypoint && resolvedPath === entrypoint) return true;
36502
- if (resolvedPath.includes(`${join15("node_modules", "deepline")}`)) return true;
36748
+ if (resolvedPath.includes(`${join16("node_modules", "deepline")}`)) return true;
36503
36749
  const content = safeRead(path);
36504
36750
  return content.includes("node_modules/deepline") || content.includes("node_modules\\deepline") || content.includes("DEEPLINE_CONFIG_SCOPE") || content.includes("deepline-real");
36505
36751
  }
@@ -36507,9 +36753,9 @@ function inspectPathConflict() {
36507
36753
  const commandPath = resolvePathCommand("deepline");
36508
36754
  if (!commandPath || isKnownDeeplineCommand(commandPath)) return null;
36509
36755
  try {
36510
- if (lstatSync(commandPath).isSymbolicLink()) {
36511
- const target = realpathSync3(commandPath);
36512
- if (target.includes(`${join15("node_modules", "deepline")}`)) return null;
36756
+ if (lstatSync2(commandPath).isSymbolicLink()) {
36757
+ const target = realpathSync4(commandPath);
36758
+ if (target.includes(`${join16("node_modules", "deepline")}`)) return null;
36513
36759
  }
36514
36760
  } catch {
36515
36761
  }
@@ -36517,7 +36763,7 @@ function inspectPathConflict() {
36517
36763
  }
36518
36764
  function writeSetupState(input2) {
36519
36765
  const path = setupStatePath(input2.baseUrl, input2.scope, input2.root);
36520
- mkdirSync11(dirname15(path), { recursive: true });
36766
+ mkdirSync11(dirname16(path), { recursive: true });
36521
36767
  writeFileSync14(
36522
36768
  path,
36523
36769
  `${JSON.stringify(
@@ -36558,7 +36804,7 @@ function failSetupPhase(phases, phase, code) {
36558
36804
  phases[phase] = { status: "failed", code };
36559
36805
  }
36560
36806
  function rollbackCommand(scope, root) {
36561
- const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify(join15(root, ".deepline", "runtime"))}` : "";
36807
+ const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify(join16(root, ".deepline", "runtime"))}` : "";
36562
36808
  return `npm install -g${prefix} --no-audit --no-fund --include=optional --allow-scripts=esbuild deepline@${SDK_VERSION}`;
36563
36809
  }
36564
36810
  function setupResumeCommand(baseUrl, scope) {
@@ -36645,12 +36891,12 @@ function buildDoctorAssessment(input2) {
36645
36891
  const connected = input2.authStatus.payload?.connected === true;
36646
36892
  const authScopeOk = input2.scope === "local" ? Boolean(projectAuth) : Boolean(apiKey && !projectAuth);
36647
36893
  const skillsOk = skillsState?.scope === input2.scope && typeof skillsState.skillsVersion === "string" && Array.isArray(skillsState.agents) && skillsState.agents.length > 0;
36648
- const runningCliPath = process.argv[1] ? resolve14(process.argv[1]) : null;
36894
+ const runningCliPath = process.argv[1] ? resolve15(process.argv[1]) : null;
36649
36895
  const globalCli = input2.scope === "global" ? inspectGlobalCliAvailability() : null;
36650
36896
  const pathGlobalCli = globalCli?.path ?? null;
36651
36897
  const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
36652
36898
  const cliScopeOk = input2.scope === "global" ? Boolean(pathGlobalCli) : Boolean(
36653
- input2.root && runningCliPath?.includes(join15(input2.root, ".deepline", "runtime"))
36899
+ input2.root && runningCliPath?.includes(join16(input2.root, ".deepline", "runtime"))
36654
36900
  );
36655
36901
  const checks = {
36656
36902
  cli: {
@@ -37178,15 +37424,15 @@ Examples:
37178
37424
 
37179
37425
  // src/cli/update-preferences.ts
37180
37426
  import {
37181
- existsSync as existsSync14,
37427
+ existsSync as existsSync15,
37182
37428
  mkdirSync as mkdirSync12,
37183
- readFileSync as readFileSync14,
37429
+ readFileSync as readFileSync15,
37184
37430
  renameSync,
37185
37431
  rmSync as rmSync5,
37186
37432
  writeFileSync as writeFileSync15
37187
37433
  } from "fs";
37188
37434
  import { homedir as homedir10 } from "os";
37189
- import { dirname as dirname16, join as join16 } from "path";
37435
+ import { dirname as dirname17, join as join17 } from "path";
37190
37436
  var UPDATE_PREFERENCES_SCHEMA_VERSION = 1;
37191
37437
  var CLI_UPDATE_MESSAGES = [
37192
37438
  {
@@ -37215,7 +37461,7 @@ function unreadablePreferences(path, error) {
37215
37461
  };
37216
37462
  }
37217
37463
  function cliUpdatePreferencesPath(homeDir2 = homedir10()) {
37218
- return join16(
37464
+ return join17(
37219
37465
  homeDir2,
37220
37466
  ".local",
37221
37467
  "deepline",
@@ -37225,9 +37471,9 @@ function cliUpdatePreferencesPath(homeDir2 = homedir10()) {
37225
37471
  }
37226
37472
  function readCliUpdatePreferences(homeDir2 = homedir10()) {
37227
37473
  const path = cliUpdatePreferencesPath(homeDir2);
37228
- if (!existsSync14(path)) return defaultPreferences();
37474
+ if (!existsSync15(path)) return defaultPreferences();
37229
37475
  try {
37230
- const parsed = JSON.parse(readFileSync14(path, "utf8"));
37476
+ const parsed = JSON.parse(readFileSync15(path, "utf8"));
37231
37477
  return {
37232
37478
  schemaVersion: UPDATE_PREFERENCES_SCHEMA_VERSION,
37233
37479
  autoUpdateEnabled: typeof parsed.autoUpdateEnabled === "boolean" ? parsed.autoUpdateEnabled : true,
@@ -37243,7 +37489,7 @@ function readCliUpdatePreferences(homeDir2 = homedir10()) {
37243
37489
  function writeCliUpdatePreferences(preferences, homeDir2 = homedir10()) {
37244
37490
  const path = cliUpdatePreferencesPath(homeDir2);
37245
37491
  const tempPath = `${path}.${process.pid}.tmp`;
37246
- mkdirSync12(dirname16(path), { recursive: true });
37492
+ mkdirSync12(dirname17(path), { recursive: true });
37247
37493
  try {
37248
37494
  writeFileSync15(tempPath, `${JSON.stringify(preferences, null, 2)}
37249
37495
  `, {
@@ -37303,10 +37549,10 @@ function consumePendingCliUpdateMessages(homeDir2 = homedir10()) {
37303
37549
  // src/cli/commands/update.ts
37304
37550
  import { spawn as spawn4, spawnSync as spawnSync3 } from "child_process";
37305
37551
  import {
37306
- existsSync as existsSync16,
37552
+ existsSync as existsSync17,
37307
37553
  mkdirSync as mkdirSync13,
37308
- realpathSync as realpathSync4,
37309
- readFileSync as readFileSync16,
37554
+ realpathSync as realpathSync5,
37555
+ readFileSync as readFileSync17,
37310
37556
  renameSync as renameSync2,
37311
37557
  rmSync as rmSync6,
37312
37558
  unlinkSync as unlinkSync2,
@@ -37315,17 +37561,17 @@ import {
37315
37561
  import { homedir as homedir11 } from "os";
37316
37562
  import {
37317
37563
  basename as basename7,
37318
- dirname as dirname17,
37564
+ dirname as dirname18,
37319
37565
  isAbsolute as isAbsolute7,
37320
- join as join18,
37566
+ join as join19,
37321
37567
  relative as relative7,
37322
- resolve as resolve16
37568
+ resolve as resolve17
37323
37569
  } from "path";
37324
37570
 
37325
37571
  // src/cli/install-integrity.ts
37326
37572
  import { createRequire } from "module";
37327
- import { existsSync as existsSync15, readFileSync as readFileSync15, statSync as statSync5 } from "fs";
37328
- import { isAbsolute as isAbsolute6, join as join17, relative as relative6, resolve as resolve15 } from "path";
37573
+ import { existsSync as existsSync16, readFileSync as readFileSync16, statSync as statSync5 } from "fs";
37574
+ import { isAbsolute as isAbsolute6, join as join18, relative as relative6, resolve as resolve16 } from "path";
37329
37575
  var SDK_SIDECAR_CRITICAL_PACKAGE_FILES = [
37330
37576
  "dist/cli/index.mjs",
37331
37577
  "dist/index.mjs",
@@ -37350,15 +37596,15 @@ function safeRelativePath(value) {
37350
37596
  }
37351
37597
  function resolveContainedPath(root, value) {
37352
37598
  if (!safeRelativePath(value)) return null;
37353
- const target = resolve15(root, value);
37354
- const relativeTarget = relative6(resolve15(root), target);
37599
+ const target = resolve16(root, value);
37600
+ const relativeTarget = relative6(resolve16(root), target);
37355
37601
  if (!relativeTarget || relativeTarget.startsWith("..") || isAbsolute6(relativeTarget)) {
37356
37602
  return null;
37357
37603
  }
37358
37604
  return target;
37359
37605
  }
37360
37606
  function parseJson(path) {
37361
- return JSON.parse(readFileSync15(path, "utf8"));
37607
+ return JSON.parse(readFileSync16(path, "utf8"));
37362
37608
  }
37363
37609
  function isFile(path) {
37364
37610
  try {
@@ -37368,7 +37614,7 @@ function isFile(path) {
37368
37614
  }
37369
37615
  }
37370
37616
  function readManifest(packageRoot) {
37371
- const packageJsonPath = join17(packageRoot, "package.json");
37617
+ const packageJsonPath = join18(packageRoot, "package.json");
37372
37618
  let packageJson;
37373
37619
  try {
37374
37620
  packageJson = parseJson(packageJsonPath);
@@ -37376,7 +37622,7 @@ function readManifest(packageRoot) {
37376
37622
  return {
37377
37623
  mode: "manifest",
37378
37624
  invalidReason: `invalid Deepline package metadata: ${error.message}`,
37379
- missing: existsSync15(packageJsonPath) ? [] : ["deepline/package.json"]
37625
+ missing: existsSync16(packageJsonPath) ? [] : ["deepline/package.json"]
37380
37626
  };
37381
37627
  }
37382
37628
  if (!packageJson || typeof packageJson !== "object" || Array.isArray(packageJson)) {
@@ -37442,8 +37688,8 @@ function readManifest(packageRoot) {
37442
37688
  return { mode: "manifest", manifest };
37443
37689
  }
37444
37690
  function inspectSdkSidecarInstall(versionDir) {
37445
- const nodeModulesRoot = join17(versionDir, "node_modules");
37446
- const packageRoot = join17(nodeModulesRoot, "deepline");
37691
+ const nodeModulesRoot = join18(versionDir, "node_modules");
37692
+ const packageRoot = join18(nodeModulesRoot, "deepline");
37447
37693
  const manifestResult = readManifest(packageRoot);
37448
37694
  if ("invalidReason" in manifestResult) {
37449
37695
  return {
@@ -37454,8 +37700,8 @@ function inspectSdkSidecarInstall(versionDir) {
37454
37700
  };
37455
37701
  }
37456
37702
  const missing = [
37457
- ...manifestResult.manifest.packageFiles.filter((path) => !isFile(join17(packageRoot, path))).map((path) => `deepline/${path}`),
37458
- ...manifestResult.manifest.dependencyFiles.filter((path) => !isFile(join17(nodeModulesRoot, path))).map((path) => `node_modules/${path}`)
37703
+ ...manifestResult.manifest.packageFiles.filter((path) => !isFile(join18(packageRoot, path))).map((path) => `deepline/${path}`),
37704
+ ...manifestResult.manifest.dependencyFiles.filter((path) => !isFile(join18(nodeModulesRoot, path))).map((path) => `node_modules/${path}`)
37459
37705
  ];
37460
37706
  return {
37461
37707
  ok: missing.length === 0,
@@ -37466,7 +37712,7 @@ function inspectSdkSidecarInstall(versionDir) {
37466
37712
  }
37467
37713
  function probeSdkSidecarEsbuild(versionDir) {
37468
37714
  try {
37469
- const requireFromInstall = createRequire(join17(versionDir, "package.json"));
37715
+ const requireFromInstall = createRequire(join18(versionDir, "package.json"));
37470
37716
  const esbuild = requireFromInstall("esbuild");
37471
37717
  if (typeof esbuild.transformSync !== "function") {
37472
37718
  return "esbuild does not export transformSync";
@@ -37541,7 +37787,7 @@ function sidecarStateDir(input2) {
37541
37787
  if (!scope || scope.includes("/") || scope.includes("\\")) {
37542
37788
  return null;
37543
37789
  }
37544
- return join18(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
37790
+ return join19(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
37545
37791
  }
37546
37792
  function sidecarRegistryUrl(hostUrl) {
37547
37793
  let url;
@@ -37568,7 +37814,7 @@ function publicNpmFallbackRegistryUrl(hostUrl) {
37568
37814
  }
37569
37815
  function readOptionalText(path) {
37570
37816
  try {
37571
- return readFileSync16(path, "utf8").trim();
37817
+ return readFileSync17(path, "utf8").trim();
37572
37818
  } catch {
37573
37819
  return "";
37574
37820
  }
@@ -37577,18 +37823,18 @@ function resolvePythonSidecarUpdatePlan(options) {
37577
37823
  const stateDir = sidecarStateDir(options);
37578
37824
  if (!stateDir) return null;
37579
37825
  const relativeEntrypoint = relative7(
37580
- resolve16(stateDir),
37581
- resolve16(options.entrypoint)
37826
+ resolve17(stateDir),
37827
+ resolve17(options.entrypoint)
37582
37828
  );
37583
37829
  if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || isAbsolute7(relativeEntrypoint)) {
37584
37830
  return null;
37585
37831
  }
37586
- const installMethod = readOptionalText(join18(stateDir, ".install-method"));
37832
+ const installMethod = readOptionalText(join19(stateDir, ".install-method"));
37587
37833
  if (installMethod !== "python-sidecar") return null;
37588
37834
  const scope = options.env.DEEPLINE_CONFIG_SCOPE?.trim() || "";
37589
37835
  const hostUrl = options.env.DEEPLINE_HOST_URL?.trim() || "";
37590
- const nodeBin = readOptionalText(join18(stateDir, ".node-bin")) || process.execPath;
37591
- const sidecarPath = readOptionalText(join18(stateDir, ".command-path")) || join18(
37836
+ const nodeBin = readOptionalText(join19(stateDir, ".node-bin")) || process.execPath;
37837
+ const sidecarPath = readOptionalText(join19(stateDir, ".command-path")) || join19(
37592
37838
  stateDir,
37593
37839
  "bin",
37594
37840
  process.platform === "win32" ? "deepline-sdk.cmd" : "deepline-sdk"
@@ -37596,7 +37842,7 @@ function resolvePythonSidecarUpdatePlan(options) {
37596
37842
  const packageSpec = options.packageSpec || "deepline@latest";
37597
37843
  const npmCommand = "npm";
37598
37844
  const registryUrl = sidecarRegistryUrl(hostUrl);
37599
- const versionDir = join18(stateDir, "versions", "<version>");
37845
+ const versionDir = join19(stateDir, "versions", "<version>");
37600
37846
  const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote4(versionDir)} --registry ${shellQuote4(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote4).join(" ")} ${shellQuote4(packageSpec)}`;
37601
37847
  return {
37602
37848
  kind: "python-sidecar",
@@ -37612,16 +37858,16 @@ function resolvePythonSidecarUpdatePlan(options) {
37612
37858
  };
37613
37859
  }
37614
37860
  function findRepoBackedSdkRoot(startPath) {
37615
- let current = resolve16(startPath);
37861
+ let current = resolve17(startPath);
37616
37862
  while (true) {
37617
- if (existsSync16(join18(current, "package.json")) && existsSync16(join18(current, "bin", "deepline-dev.ts"))) {
37618
- const parent2 = dirname17(current);
37619
- return basename7(parent2) === "packages" && basename7(current) === "sdk" ? dirname17(parent2) : parent2;
37863
+ if (existsSync17(join19(current, "package.json")) && existsSync17(join19(current, "bin", "deepline-dev.ts"))) {
37864
+ const parent2 = dirname18(current);
37865
+ return basename7(parent2) === "packages" && basename7(current) === "sdk" ? dirname18(parent2) : parent2;
37620
37866
  }
37621
- if (existsSync16(join18(current, "sdk", "package.json")) && existsSync16(join18(current, "sdk", "bin", "deepline-dev.ts"))) {
37867
+ if (existsSync17(join19(current, "sdk", "package.json")) && existsSync17(join19(current, "sdk", "bin", "deepline-dev.ts"))) {
37622
37868
  return current;
37623
37869
  }
37624
- const parent = dirname17(current);
37870
+ const parent = dirname18(current);
37625
37871
  if (parent === current) return null;
37626
37872
  current = parent;
37627
37873
  }
@@ -37629,9 +37875,9 @@ function findRepoBackedSdkRoot(startPath) {
37629
37875
  function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
37630
37876
  const normalized = (() => {
37631
37877
  try {
37632
- return realpathSync4(entrypoint);
37878
+ return realpathSync5(entrypoint);
37633
37879
  } catch {
37634
- return resolve16(entrypoint);
37880
+ return resolve17(entrypoint);
37635
37881
  }
37636
37882
  })();
37637
37883
  const parts = normalized.split(/[\\/]+/);
@@ -37646,10 +37892,10 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
37646
37892
  const directPrefix = prefixParts.join("/").toLowerCase();
37647
37893
  const knownWindowsPrefixes = [
37648
37894
  env.npm_config_prefix,
37649
- env.APPDATA ? join18(env.APPDATA, "npm") : void 0
37650
- ].filter((value) => Boolean(value)).map((value) => resolve16(value).replace(/\\/g, "/").toLowerCase());
37895
+ env.APPDATA ? join19(env.APPDATA, "npm") : void 0
37896
+ ].filter((value) => Boolean(value)).map((value) => resolve17(value).replace(/\\/g, "/").toLowerCase());
37651
37897
  if (!knownWindowsPrefixes.includes(
37652
- resolve16(directPrefix).replace(/\\/g, "/").toLowerCase()
37898
+ resolve17(directPrefix).replace(/\\/g, "/").toLowerCase()
37653
37899
  )) {
37654
37900
  return null;
37655
37901
  }
@@ -37662,9 +37908,9 @@ function normalizedNpmPrefix(value) {
37662
37908
  if (!trimmed) return null;
37663
37909
  const normalized = (() => {
37664
37910
  try {
37665
- return realpathSync4(resolve16(trimmed));
37911
+ return realpathSync5(resolve17(trimmed));
37666
37912
  } catch {
37667
- return resolve16(trimmed);
37913
+ return resolve17(trimmed);
37668
37914
  }
37669
37915
  })().replace(/\\/g, "/");
37670
37916
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
@@ -37687,9 +37933,9 @@ function resolveNpmGlobalPrefix(env) {
37687
37933
  function isHomebrewFormulaEntrypoint(entrypoint) {
37688
37934
  const normalized = (() => {
37689
37935
  try {
37690
- return realpathSync4(entrypoint);
37936
+ return realpathSync5(entrypoint);
37691
37937
  } catch {
37692
- return resolve16(entrypoint);
37938
+ return resolve17(entrypoint);
37693
37939
  }
37694
37940
  })();
37695
37941
  const parts = normalized.split(/[\\/]+/);
@@ -37699,8 +37945,8 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
37699
37945
  function resolveUpdatePlan(options = {}) {
37700
37946
  const env = options.env ?? process.env;
37701
37947
  const homeDir2 = options.homeDir ?? homedir11();
37702
- const entrypoint = options.entrypoint ?? (process.argv[1] ? resolve16(process.argv[1]) : "");
37703
- const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname17(entrypoint)) : null;
37948
+ const entrypoint = options.entrypoint ?? (process.argv[1] ? resolve17(process.argv[1]) : "");
37949
+ const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname18(entrypoint)) : null;
37704
37950
  if (sourceRoot) {
37705
37951
  return {
37706
37952
  kind: "source",
@@ -37751,9 +37997,9 @@ var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
37751
37997
  function autoUpdateFailurePath(plan) {
37752
37998
  if (plan.kind === "source" || plan.kind === "homebrew") return null;
37753
37999
  if (plan.kind === "python-sidecar") {
37754
- return join18(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
38000
+ return join19(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
37755
38001
  }
37756
- return join18(
38002
+ return join19(
37757
38003
  homedir11(),
37758
38004
  ".local",
37759
38005
  "deepline",
@@ -37771,7 +38017,7 @@ function readAutoUpdateFailure(plan) {
37771
38017
  if (!path) return null;
37772
38018
  try {
37773
38019
  const parsed = JSON.parse(
37774
- readFileSync16(path, "utf8")
38020
+ readFileSync17(path, "utf8")
37775
38021
  );
37776
38022
  if ((parsed.kind === "npm-global" || parsed.kind === "python-sidecar") && typeof parsed.packageSpec === "string" && typeof parsed.failedAt === "string" && typeof parsed.exitCode === "number" && typeof parsed.manualCommand === "string") {
37777
38023
  return parsed;
@@ -37792,7 +38038,7 @@ function writeAutoUpdateFailure(plan, exitCode) {
37792
38038
  manualCommand: plan.manualCommand
37793
38039
  };
37794
38040
  try {
37795
- mkdirSync13(dirname17(path), { recursive: true });
38041
+ mkdirSync13(dirname18(path), { recursive: true });
37796
38042
  writeFileSync16(path, `${JSON.stringify(marker, null, 2)}
37797
38043
  `, "utf8");
37798
38044
  } catch {
@@ -37840,7 +38086,7 @@ function safeVersionSegment(value) {
37840
38086
  return /^[0-9A-Za-z._-]+$/.test(normalized) ? normalized : "";
37841
38087
  }
37842
38088
  function entryPathInVersionDir(versionDir) {
37843
- return join18(
38089
+ return join19(
37844
38090
  versionDir,
37845
38091
  "node_modules",
37846
38092
  "deepline",
@@ -37850,14 +38096,14 @@ function entryPathInVersionDir(versionDir) {
37850
38096
  );
37851
38097
  }
37852
38098
  function installedPackageVersion(versionDir) {
37853
- const packageJsonPath = join18(
38099
+ const packageJsonPath = join19(
37854
38100
  versionDir,
37855
38101
  "node_modules",
37856
38102
  "deepline",
37857
38103
  "package.json"
37858
38104
  );
37859
38105
  try {
37860
- const parsed = JSON.parse(readFileSync16(packageJsonPath, "utf8"));
38106
+ const parsed = JSON.parse(readFileSync17(packageJsonPath, "utf8"));
37861
38107
  return typeof parsed.version === "string" ? safeVersionSegment(parsed.version) : "";
37862
38108
  } catch {
37863
38109
  return "";
@@ -37972,16 +38218,16 @@ async function runNpmInstallWithRegistryFallback(input2) {
37972
38218
  return first.exitCode;
37973
38219
  }
37974
38220
  function writeSidecarLauncher(input2) {
37975
- mkdirSync13(dirname17(input2.path), { recursive: true });
37976
- const packageRoot = dirname17(dirname17(dirname17(input2.entryPath)));
37977
- const versionDir = dirname17(dirname17(packageRoot));
38221
+ mkdirSync13(dirname18(input2.path), { recursive: true });
38222
+ const packageRoot = dirname18(dirname18(dirname18(input2.entryPath)));
38223
+ const versionDir = dirname18(dirname18(packageRoot));
37978
38224
  const esbuildProbe = "const {createRequire}=require('node:module');const path=require('node:path');const req=createRequire(path.join(process.argv[1],'package.json'));const result=req('esbuild').transformSync('const value: number = 1;',{loader:'ts'});if(!result||typeof result.code!=='string')process.exit(3);";
37979
38225
  const criticalPaths = [
37980
38226
  ...SDK_SIDECAR_CRITICAL_PACKAGE_FILES.map(
37981
- (path) => join18(packageRoot, path)
38227
+ (path) => join19(packageRoot, path)
37982
38228
  ),
37983
38229
  ...SDK_SIDECAR_CRITICAL_DEPENDENCY_FILES.map(
37984
- (path) => join18(versionDir, "node_modules", path)
38230
+ (path) => join19(versionDir, "node_modules", path)
37985
38231
  )
37986
38232
  ];
37987
38233
  if (process.platform === "win32") {
@@ -38035,17 +38281,17 @@ function writeSidecarLauncher(input2) {
38035
38281
  );
38036
38282
  }
38037
38283
  async function runPythonSidecarUpdatePlan(plan) {
38038
- const versionsDir = join18(plan.stateDir, "versions");
38039
- const tempDir = join18(
38284
+ const versionsDir = join19(plan.stateDir, "versions");
38285
+ const tempDir = join19(
38040
38286
  versionsDir,
38041
38287
  `.tmp-sdk-update-${process.pid}-${Date.now()}`
38042
38288
  );
38043
38289
  rmSync6(tempDir, { recursive: true, force: true });
38044
38290
  mkdirSync13(tempDir, { recursive: true });
38045
- writeFileSync16(join18(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
38291
+ writeFileSync16(join19(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
38046
38292
  const env = {
38047
38293
  ...process.env,
38048
- PATH: `${dirname17(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
38294
+ PATH: `${dirname18(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
38049
38295
  };
38050
38296
  const installResult = await runCommand(
38051
38297
  plan.npmCommand,
@@ -38082,7 +38328,7 @@ async function runPythonSidecarUpdatePlan(plan) {
38082
38328
  rmSync6(tempDir, { recursive: true, force: true });
38083
38329
  return 1;
38084
38330
  }
38085
- const finalDir = join18(versionsDir, installedVersion);
38331
+ const finalDir = join19(versionsDir, installedVersion);
38086
38332
  const finalEntryPath = entryPathInVersionDir(finalDir);
38087
38333
  const finalFailure = sidecarInstallFailure(finalDir);
38088
38334
  let backupDir = null;
@@ -38090,8 +38336,8 @@ async function runPythonSidecarUpdatePlan(plan) {
38090
38336
  rmSync6(tempDir, { recursive: true, force: true });
38091
38337
  } else {
38092
38338
  let shouldPublishTemp = true;
38093
- if (existsSync16(finalDir)) {
38094
- backupDir = join18(
38339
+ if (existsSync17(finalDir)) {
38340
+ backupDir = join19(
38095
38341
  versionsDir,
38096
38342
  `.backup-${installedVersion}-${process.pid}-${Date.now()}`
38097
38343
  );
@@ -38124,7 +38370,7 @@ async function runPythonSidecarUpdatePlan(plan) {
38124
38370
  backupDir = null;
38125
38371
  } else {
38126
38372
  let restoreFailure = "";
38127
- if (backupDir && existsSync16(backupDir) && !existsSync16(finalDir)) {
38373
+ if (backupDir && existsSync17(backupDir) && !existsSync17(finalDir)) {
38128
38374
  try {
38129
38375
  renameSync2(backupDir, finalDir);
38130
38376
  backupDir = null;
@@ -38143,7 +38389,7 @@ async function runPythonSidecarUpdatePlan(plan) {
38143
38389
  }
38144
38390
  const publishedFailure = sidecarStructureFailure(finalDir);
38145
38391
  if (publishedFailure) {
38146
- if (backupDir && existsSync16(backupDir)) {
38392
+ if (backupDir && existsSync17(backupDir)) {
38147
38393
  rmSync6(finalDir, { recursive: true, force: true });
38148
38394
  try {
38149
38395
  renameSync2(backupDir, finalDir);
@@ -38166,27 +38412,27 @@ async function runPythonSidecarUpdatePlan(plan) {
38166
38412
  entryPath: finalEntryPath
38167
38413
  });
38168
38414
  writeFileSync16(
38169
- join18(plan.stateDir, ".version"),
38415
+ join19(plan.stateDir, ".version"),
38170
38416
  `${installedVersion}
38171
38417
  `,
38172
38418
  "utf8"
38173
38419
  );
38174
38420
  writeFileSync16(
38175
- join18(plan.stateDir, ".install-method"),
38421
+ join19(plan.stateDir, ".install-method"),
38176
38422
  "python-sidecar\n",
38177
38423
  "utf8"
38178
38424
  );
38179
38425
  writeFileSync16(
38180
- join18(plan.stateDir, ".command-path"),
38426
+ join19(plan.stateDir, ".command-path"),
38181
38427
  `${plan.sidecarPath}
38182
38428
  `,
38183
38429
  "utf8"
38184
38430
  );
38185
- writeFileSync16(join18(plan.stateDir, ".runner"), "node\n", "utf8");
38186
- writeFileSync16(join18(plan.stateDir, ".node-bin"), `${plan.nodeBin}
38431
+ writeFileSync16(join19(plan.stateDir, ".runner"), "node\n", "utf8");
38432
+ writeFileSync16(join19(plan.stateDir, ".node-bin"), `${plan.nodeBin}
38187
38433
  `, "utf8");
38188
38434
  writeFileSync16(
38189
- join18(plan.stateDir, ".entry-path"),
38435
+ join19(plan.stateDir, ".entry-path"),
38190
38436
  `${finalEntryPath}
38191
38437
  `,
38192
38438
  "utf8"
@@ -39115,13 +39361,13 @@ chooses the connected Slack channel or member and the events it receives.
39115
39361
  import { Option as Option2 } from "commander";
39116
39362
  import {
39117
39363
  chmodSync,
39118
- existsSync as existsSync17,
39364
+ existsSync as existsSync18,
39119
39365
  mkdtempSync,
39120
- readFileSync as readFileSync17,
39366
+ readFileSync as readFileSync18,
39121
39367
  writeFileSync as writeFileSync18
39122
39368
  } from "fs";
39123
39369
  import { tmpdir as tmpdir5 } from "os";
39124
- import { join as join20, resolve as resolve17 } from "path";
39370
+ import { join as join21, resolve as resolve18 } from "path";
39125
39371
 
39126
39372
  // src/tool-output.ts
39127
39373
  import {
@@ -39132,7 +39378,7 @@ import {
39132
39378
  writeSync
39133
39379
  } from "fs";
39134
39380
  import { homedir as homedir12 } from "os";
39135
- import { dirname as dirname18, join as join19 } from "path";
39381
+ import { dirname as dirname19, join as join20 } from "path";
39136
39382
  function isPlainObject(value) {
39137
39383
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
39138
39384
  }
@@ -39259,19 +39505,19 @@ function projectRowOutput(conversion) {
39259
39505
  };
39260
39506
  }
39261
39507
  function ensureOutputDir() {
39262
- const outputDir = join19(homedir12(), ".local", "share", "deepline", "data");
39508
+ const outputDir = join20(homedir12(), ".local", "share", "deepline", "data");
39263
39509
  mkdirSync14(outputDir, { recursive: true });
39264
39510
  return outputDir;
39265
39511
  }
39266
39512
  function writeJsonOutputFile(payload, stem) {
39267
39513
  const outputDir = ensureOutputDir();
39268
- const outputPath = join19(outputDir, `${stem}_${Date.now()}.json`);
39514
+ const outputPath = join20(outputDir, `${stem}_${Date.now()}.json`);
39269
39515
  writeFileSync17(outputPath, JSON.stringify(payload, null, 2), "utf-8");
39270
39516
  return outputPath;
39271
39517
  }
39272
39518
  function writeCsvOutputFile(rows, stem, options) {
39273
- const outputPath = options?.outPath ? options.outPath : join19(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
39274
- mkdirSync14(dirname18(outputPath), { recursive: true });
39519
+ const outputPath = options?.outPath ? options.outPath : join20(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
39520
+ mkdirSync14(dirname19(outputPath), { recursive: true });
39275
39521
  const columns = columnsForRows(rows);
39276
39522
  const escapeCell = (value) => {
39277
39523
  const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
@@ -39414,6 +39660,78 @@ function arrayField(value, key) {
39414
39660
  return Array.isArray(candidate) ? candidate : [];
39415
39661
  }
39416
39662
 
39663
+ // src/cli/tool-description.ts
39664
+ var Capability = class _Capability {
39665
+ #catalogEntry;
39666
+ constructor(catalogEntry) {
39667
+ this.#catalogEntry = catalogEntry;
39668
+ }
39669
+ static fromCatalogEntry(catalogEntry) {
39670
+ return new _Capability(catalogEntry);
39671
+ }
39672
+ describe() {
39673
+ return CapabilityDescription.fromCatalogEntry(this.#catalogEntry);
39674
+ }
39675
+ };
39676
+ var CapabilityDescription = class _CapabilityDescription {
39677
+ #catalogEntry;
39678
+ constructor(catalogEntry) {
39679
+ this.#catalogEntry = catalogEntry;
39680
+ }
39681
+ static fromCatalogEntry(catalogEntry) {
39682
+ return new _CapabilityDescription(catalogEntry);
39683
+ }
39684
+ /**
39685
+ * The customer price already resolved by the catalog. This intentionally
39686
+ * omits provider-price fields, even when a catalog Adapter carried them.
39687
+ */
39688
+ customerCost() {
39689
+ const legacyCost = recordValue2(this.#catalogEntry.cost);
39690
+ const pricing = recordValue2(this.#catalogEntry.pricing);
39691
+ const unit = stringValue4(pricing.unit);
39692
+ const legacyPricingModel = stringValue4(
39693
+ legacyCost.pricingModel ?? legacyCost.pricing_model
39694
+ );
39695
+ const pricingModel = unit === "call" ? "fixed" : unit === "result" || unit === "page" ? `per_${unit}` : unit === "usage" ? "provider_usage" : legacyPricingModel;
39696
+ const canonicalCredits = numberValue(
39697
+ pricing.creditsPerUnit ?? pricing.credits_per_unit
39698
+ );
39699
+ const canonicalUsd = numberValue(
39700
+ pricing.usdPerUnit ?? pricing.usd_per_unit
39701
+ );
39702
+ return {
39703
+ pricingModel: pricingModel || null,
39704
+ unit: unit || null,
39705
+ displayText: stringValue4(pricing.displayText ?? pricing.display_text),
39706
+ summary: stringValue4(pricing.summary),
39707
+ billingMode: stringValue4(
39708
+ legacyCost.billingMode ?? legacyCost.billing_mode
39709
+ ),
39710
+ billingSource: stringValue4(
39711
+ this.#catalogEntry.billingSource ?? this.#catalogEntry.billing_source
39712
+ ),
39713
+ billingSourceLabel: stringValue4(
39714
+ this.#catalogEntry.billingSourceLabel ?? this.#catalogEntry.billing_source_label
39715
+ ),
39716
+ deeplineCreditsPerPricingUnit: canonicalCredits ?? numberValue(
39717
+ this.#catalogEntry.deeplineCreditsPerPricingUnit ?? this.#catalogEntry.deepline_credits_per_pricing_unit
39718
+ ),
39719
+ deeplineUsdPerPricingUnit: canonicalUsd ?? numberValue(
39720
+ this.#catalogEntry.deeplineUsdPerPricingUnit ?? this.#catalogEntry.deepline_usd_per_pricing_unit
39721
+ )
39722
+ };
39723
+ }
39724
+ };
39725
+ function recordValue2(value) {
39726
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
39727
+ }
39728
+ function stringValue4(value) {
39729
+ return typeof value === "string" && value.trim() ? value : null;
39730
+ }
39731
+ function numberValue(value) {
39732
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
39733
+ }
39734
+
39417
39735
  // src/cli/commands/tools.ts
39418
39736
  var TOOL_COMMAND_TEMPLATES = {
39419
39737
  describe: "deepline tools describe <toolId>",
@@ -40334,7 +40652,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
40334
40652
  const extractedValues = extractionContractEntries(
40335
40653
  arrayField2(toolExecutionResult, "extractedValues", "extracted_values")
40336
40654
  );
40337
- const pricing = toolPricingContractForDescribe(tool);
40655
+ const pricing = Capability.fromCatalogEntry(tool).describe().customerCost();
40338
40656
  const deprecation = recordField2(tool, "deprecation");
40339
40657
  const replacementToolId = stringField2(
40340
40658
  deprecation,
@@ -40385,38 +40703,6 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
40385
40703
  ...starterScript ? { starterScript } : {}
40386
40704
  };
40387
40705
  }
40388
- function toolPricingContractForDescribe(tool) {
40389
- const legacyCost = recordField2(tool, "cost");
40390
- const pricingValue = tool.pricing;
40391
- const hasCanonicalPricing = isRecord12(pricingValue);
40392
- const canonicalPricing = hasCanonicalPricing ? pricingValue : {};
40393
- const unit = stringField2(canonicalPricing, "unit");
40394
- const legacyPricingModel = stringField2(
40395
- legacyCost,
40396
- "pricingModel",
40397
- "pricing_model"
40398
- );
40399
- const pricingModel = unit === "call" ? "fixed" : unit === "result" || unit === "page" ? `per_${unit}` : unit === "usage" ? "provider_usage" : legacyPricingModel;
40400
- return {
40401
- pricingModel: pricingModel || null,
40402
- unit: unit || null,
40403
- displayText: stringField2(canonicalPricing, "displayText", "display_text") || null,
40404
- summary: stringField2(canonicalPricing, "summary") || null,
40405
- billingMode: stringField2(legacyCost, "billingMode", "billing_mode") || null,
40406
- billingSource: stringField2(tool, "billingSource", "billing_source") || null,
40407
- billingSourceLabel: stringField2(tool, "billingSourceLabel", "billing_source_label") || null,
40408
- deeplineCreditsPerPricingUnit: hasCanonicalPricing ? numberField2(canonicalPricing, "creditsPerUnit", "credits_per_unit") : numberField2(
40409
- tool,
40410
- "deeplineCreditsPerPricingUnit",
40411
- "deepline_credits_per_pricing_unit"
40412
- ),
40413
- deeplineUsdPerPricingUnit: hasCanonicalPricing ? numberField2(canonicalPricing, "usdPerUnit", "usd_per_unit") : numberField2(
40414
- tool,
40415
- "deeplineUsdPerPricingUnit",
40416
- "deepline_usd_per_pricing_unit"
40417
- )
40418
- };
40419
- }
40420
40706
  function extractionContractEntries(entries) {
40421
40707
  return entries.flatMap((entry) => {
40422
40708
  if (!isRecord12(entry)) return [];
@@ -40869,6 +41155,7 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
40869
41155
  toolId,
40870
41156
  provider: tool.provider,
40871
41157
  displayName: tool.displayName,
41158
+ cost: Capability.fromCatalogEntry(tool).describe().customerCost(),
40872
41159
  usageGuidance,
40873
41160
  runtimeOutputHelp: {
40874
41161
  contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
@@ -41199,11 +41486,11 @@ function normalizeOutputFormat(raw) {
41199
41486
  }
41200
41487
  function resolveAtFilePath(rawPath) {
41201
41488
  const trimmed = rawPath.trim();
41202
- const resolved = resolve17(trimmed);
41203
- if (existsSync17(resolved)) return resolved;
41489
+ const resolved = resolve18(trimmed);
41490
+ if (existsSync18(resolved)) return resolved;
41204
41491
  if (process.platform !== "win32" && trimmed.includes("\\")) {
41205
- const normalized = resolve17(trimmed.replace(/\\/g, "/"));
41206
- if (existsSync17(normalized)) return normalized;
41492
+ const normalized = resolve18(trimmed.replace(/\\/g, "/"));
41493
+ if (existsSync18(normalized)) return normalized;
41207
41494
  }
41208
41495
  return resolved;
41209
41496
  }
@@ -41214,7 +41501,7 @@ function readJsonArgument(raw, flagName) {
41214
41501
  throw new Error(`Invalid ${flagName} value: empty @file path.`);
41215
41502
  }
41216
41503
  try {
41217
- return readFileSync17(resolveAtFilePath(filePath), "utf8").replace(
41504
+ return readFileSync18(resolveAtFilePath(filePath), "utf8").replace(
41218
41505
  /^\uFEFF/,
41219
41506
  ""
41220
41507
  );
@@ -41291,7 +41578,7 @@ function parseExecuteOptions(args) {
41291
41578
  continue;
41292
41579
  }
41293
41580
  if ((arg === "--out" || arg === "-o") && args[index + 1]) {
41294
- outPath = resolve17(args[++index]);
41581
+ outPath = resolve18(args[++index]);
41295
41582
  continue;
41296
41583
  }
41297
41584
  throw new Error(`Unknown option: ${arg}`);
@@ -41321,9 +41608,9 @@ function starterScriptJson(script) {
41321
41608
  function seedToolListScript(input2) {
41322
41609
  const stem = safeFileStem(input2.toolId);
41323
41610
  const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
41324
- const scriptDir = mkdtempSync(join20(tmpdir5(), "deepline-workflow-seed-"));
41611
+ const scriptDir = mkdtempSync(join21(tmpdir5(), "deepline-workflow-seed-"));
41325
41612
  chmodSync(scriptDir, 448);
41326
- const scriptPath = join20(scriptDir, fileName);
41613
+ const scriptPath = join21(scriptDir, fileName);
41327
41614
  const projectDir = `deepline/projects/${stem}-workflow`;
41328
41615
  const playName = `${stem}-workflow`;
41329
41616
  const sampleRows = input2.rows.length > 0 ? `${JSON.stringify(input2.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
@@ -41792,7 +42079,7 @@ Examples:
41792
42079
 
41793
42080
  // src/cli/commands/workflow.ts
41794
42081
  import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
41795
- import { dirname as dirname19, join as join21, resolve as resolve18 } from "path";
42082
+ import { dirname as dirname20, join as join22, resolve as resolve19 } from "path";
41796
42083
 
41797
42084
  // src/cli/workflow-to-play.ts
41798
42085
  import { createHash as createHash5 } from "crypto";
@@ -42009,7 +42296,7 @@ function readStatus(payload) {
42009
42296
  }
42010
42297
  async function readJsonOption(payload, file) {
42011
42298
  if (file) {
42012
- const raw = await readFile4(resolve18(file), "utf8");
42299
+ const raw = await readFile4(resolve19(file), "utf8");
42013
42300
  return JSON.parse(raw);
42014
42301
  }
42015
42302
  if (payload) {
@@ -42043,8 +42330,8 @@ async function transformOne(api, workflowId, outDir, publish) {
42043
42330
  revision.config,
42044
42331
  { workflowName: workflow.name, version: revision.version }
42045
42332
  );
42046
- const file = join21(resolve18(outDir), `${compiled.playName}.play.ts`);
42047
- await mkdir5(dirname19(file), { recursive: true });
42333
+ const file = join22(resolve19(outDir), `${compiled.playName}.play.ts`);
42334
+ await mkdir5(dirname20(file), { recursive: true });
42048
42335
  await writeFile5(file, compiled.sourceCode, "utf8");
42049
42336
  let published = false;
42050
42337
  if (publish) {
@@ -42419,7 +42706,7 @@ function isDowngradeAutoUpdateResponse(response) {
42419
42706
  return compareSemver(target, current) < 0;
42420
42707
  }
42421
42708
  function relaunchCurrentCommand(plan) {
42422
- return new Promise((resolve19) => {
42709
+ return new Promise((resolve20) => {
42423
42710
  const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
42424
42711
  const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
42425
42712
  const child = spawn5(command, args, {
@@ -42435,9 +42722,9 @@ function relaunchCurrentCommand(plan) {
42435
42722
  `Deepline SDK/CLI updated, but relaunch failed: ${error.message}
42436
42723
  `
42437
42724
  );
42438
- resolve19(1);
42725
+ resolve20(1);
42439
42726
  });
42440
- child.on("close", (code) => resolve19(code ?? 1));
42727
+ child.on("close", (code) => resolve20(code ?? 1));
42441
42728
  });
42442
42729
  }
42443
42730
  async function maybeAutoUpdateAndRelaunch(response, baseUrl) {
@@ -42828,8 +43115,8 @@ function topLevelCommandKnown(program, commandName) {
42828
43115
  );
42829
43116
  }
42830
43117
  async function runPlayRunnerHealthCheck() {
42831
- const dir = await mkdtemp2(join22(tmpdir6(), "deepline-health-play-"));
42832
- const file = join22(dir, "health-check.play.ts");
43118
+ const dir = await mkdtemp2(join23(tmpdir6(), "deepline-health-play-"));
43119
+ const file = join23(dir, "health-check.play.ts");
42833
43120
  try {
42834
43121
  await writeFile6(
42835
43122
  file,