deepline 0.3.213 → 0.3.215

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.
Files changed (33) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +122 -32
  2. package/dist/bundling-sources/sdk/src/compat.ts +2 -0
  3. package/dist/bundling-sources/sdk/src/deployment-protection.ts +19 -0
  4. package/dist/bundling-sources/sdk/src/http.ts +3 -7
  5. package/dist/bundling-sources/sdk/src/index.ts +7 -0
  6. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  7. package/dist/bundling-sources/sdk/src/types.ts +25 -0
  8. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +18 -0
  9. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +1 -0
  10. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +33 -7
  11. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +11 -1
  12. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +3 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +53 -1
  14. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +187 -6
  15. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +12 -3
  16. package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +5 -2
  17. package/dist/bundling-sources/shared_libs/plays/deploy/api-client.ts +40 -0
  18. package/dist/bundling-sources/shared_libs/plays/deploy/manifest.ts +51 -28
  19. package/dist/bundling-sources/shared_libs/plays/deploy/monitor-files.ts +52 -0
  20. package/dist/bundling-sources/shared_libs/plays/deploy/run-deployment.ts +146 -19
  21. package/dist/bundling-sources/shared_libs/plays/settings-contract.ts +176 -0
  22. package/dist/cli/index.js +1046 -416
  23. package/dist/cli/index.mjs +894 -264
  24. package/dist/index.d.mts +165 -3
  25. package/dist/index.d.ts +165 -3
  26. package/dist/index.js +67 -35
  27. package/dist/index.mjs +67 -35
  28. package/dist/install-integrity.json +3 -0
  29. package/dist/release.d.mts +1 -1
  30. package/dist/release.d.ts +1 -1
  31. package/dist/release.js +1 -1
  32. package/dist/release.mjs +1 -1
  33. package/package.json +3 -2
@@ -1951,7 +1951,7 @@ configureProxyFromEnv();
1951
1951
 
1952
1952
  // src/cli/index.ts
1953
1953
  import { mkdtemp as mkdtemp4, rm as rm4, writeFile as writeFile6 } from "fs/promises";
1954
- import { join as join27 } from "path";
1954
+ import { join as join28 } from "path";
1955
1955
  import { tmpdir as tmpdir7 } from "os";
1956
1956
  import { Command as Command5 } from "commander";
1957
1957
 
@@ -3046,7 +3046,7 @@ var SDK_RELEASE = {
3046
3046
  // getters keep their established compatibility behavior.
3047
3047
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3048
3048
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3049
- version: "0.3.213",
3049
+ version: "0.3.215",
3050
3050
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3051
3051
  packageCapabilities: {
3052
3052
  updatePreferences: 1
@@ -3367,6 +3367,22 @@ function writeSdkSkillsLocalVersion(baseUrl, version, agents) {
3367
3367
  return complete;
3368
3368
  }
3369
3369
 
3370
+ // src/deployment-protection.ts
3371
+ function deploymentProtectionHeaders() {
3372
+ const token = typeof process !== "undefined" ? process.env?.VERCEL_PROTECTION_BYPASS_TOKEN : void 0;
3373
+ return token ? { "x-vercel-protection-bypass": token } : {};
3374
+ }
3375
+ var fetchWithDeploymentProtection = (input2, init) => {
3376
+ const headers = new Headers(
3377
+ input2 instanceof Request ? input2.headers : void 0
3378
+ );
3379
+ new Headers(init?.headers).forEach((value, name) => headers.set(name, value));
3380
+ for (const [name, value] of Object.entries(deploymentProtectionHeaders())) {
3381
+ headers.set(name, value);
3382
+ }
3383
+ return fetch(input2, { ...init, headers });
3384
+ };
3385
+
3370
3386
  // ../play-runtime/coordinator-headers.ts
3371
3387
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
3372
3388
  var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
@@ -3749,16 +3765,13 @@ var HttpClient = class {
3749
3765
  "X-Deepline-SDK-Version": SDK_VERSION,
3750
3766
  "X-Deepline-API-Contract": SDK_API_CONTRACT,
3751
3767
  "X-Deepline-Run-Result-Shape": "canonical",
3752
- ...extra
3768
+ ...extra,
3769
+ ...deploymentProtectionHeaders()
3753
3770
  };
3754
3771
  const skillsVersion = this.readSkillsVersionHeader();
3755
3772
  if (skillsVersion) {
3756
3773
  headers["X-Deepline-Skills-Version"] = skillsVersion;
3757
3774
  }
3758
- const bypassToken = typeof process !== "undefined" ? process.env?.VERCEL_PROTECTION_BYPASS_TOKEN : void 0;
3759
- if (bypassToken) {
3760
- headers["x-vercel-protection-bypass"] = bypassToken;
3761
- }
3762
3775
  const playArtifactR2Prefix = typeof process !== "undefined" ? process.env?.DEEPLINE_PLAY_ARTIFACT_R2_PREFIX : void 0;
3763
3776
  if (playArtifactR2Prefix) {
3764
3777
  headers["x-deepline-play-artifact-r2-prefix"] = playArtifactR2Prefix;
@@ -4887,13 +4900,13 @@ function previewValue(value, input2) {
4887
4900
  ([, descriptor]) => descriptor.enumerable
4888
4901
  );
4889
4902
  const selected = entries.slice(0, DOCFLOW_NODE_IO_LIMITS.maxObjectFields);
4890
- const fields = {};
4903
+ const fields2 = {};
4891
4904
  for (const [key, descriptor] of selected) {
4892
4905
  const safeKey = truncateUtf8(
4893
4906
  ledgerSafeDocflowPreviewKey(input2.redactor.redactString(key)),
4894
4907
  DOCFLOW_NODE_IO_LIMITS.maxStringBytes
4895
4908
  );
4896
- fields[safeKey] = "value" in descriptor ? previewValue(descriptor.value, {
4909
+ fields2[safeKey] = "value" in descriptor ? previewValue(descriptor.value, {
4897
4910
  ...input2,
4898
4911
  depth: input2.depth + 1,
4899
4912
  key
@@ -4901,7 +4914,7 @@ function previewValue(value, input2) {
4901
4914
  }
4902
4915
  return {
4903
4916
  kind: "object",
4904
- fields,
4917
+ fields: fields2,
4905
4918
  totalFields: entries.length,
4906
4919
  ...entries.length > selected.length ? { truncated: true } : {}
4907
4920
  };
@@ -5010,20 +5023,20 @@ function normalizePreview(value, depth) {
5010
5023
  };
5011
5024
  }
5012
5025
  if (value.kind === "object" && isRecord3(value.fields)) {
5013
- const fields = {};
5026
+ const fields2 = {};
5014
5027
  for (const [key, field] of Object.entries(value.fields).slice(
5015
5028
  0,
5016
5029
  DOCFLOW_NODE_IO_LIMITS.maxObjectFields
5017
5030
  )) {
5018
5031
  const normalized = normalizePreview(field, depth + 1);
5019
- if (normalized) fields[ledgerSafeDocflowPreviewKey(key)] = normalized;
5032
+ if (normalized) fields2[ledgerSafeDocflowPreviewKey(key)] = normalized;
5020
5033
  }
5021
- const totalFields = typeof value.totalFields === "number" && Number.isFinite(value.totalFields) ? Math.max(Object.keys(fields).length, Math.floor(value.totalFields)) : Object.keys(fields).length;
5034
+ const totalFields = typeof value.totalFields === "number" && Number.isFinite(value.totalFields) ? Math.max(Object.keys(fields2).length, Math.floor(value.totalFields)) : Object.keys(fields2).length;
5022
5035
  return {
5023
5036
  kind: "object",
5024
- fields,
5037
+ fields: fields2,
5025
5038
  totalFields,
5026
- ...value.truncated === true || totalFields > Object.keys(fields).length ? { truncated: true } : {}
5039
+ ...value.truncated === true || totalFields > Object.keys(fields2).length ? { truncated: true } : {}
5027
5040
  };
5028
5041
  }
5029
5042
  return null;
@@ -7035,10 +7048,19 @@ function normalizePlayStatus(raw) {
7035
7048
  );
7036
7049
  }
7037
7050
  const runId = typeof raw.runId === "string" ? raw.runId : typeof raw.workflowId === "string" ? raw.workflowId : packageRun?.id ?? "";
7051
+ const legacyOverview = runPackage?.overview ?? raw.overview;
7052
+ const runStatus = runPackage?.runStatus ?? raw.runStatus;
7038
7053
  return {
7039
7054
  ...raw,
7040
7055
  runId,
7041
- ...runPackage ? { package: runPackage, outputs: runPackage.outputs } : {},
7056
+ ...isRecord7(legacyOverview) ? {
7057
+ overview: legacyOverview
7058
+ } : {},
7059
+ ...isRecord7(runStatus) ? { runStatus } : {},
7060
+ ...runPackage ? {
7061
+ package: runPackage,
7062
+ outputs: runPackage.outputs
7063
+ } : {},
7042
7064
  status
7043
7065
  };
7044
7066
  }
@@ -7220,18 +7242,6 @@ function playRunResultFromStatus(status, startedAt, fallbackRunId) {
7220
7242
  error: status.progress?.error ?? (status.status !== "completed" ? status.status : void 0)
7221
7243
  };
7222
7244
  }
7223
- function playRunStatusFromState(state) {
7224
- return {
7225
- runId: state.runId,
7226
- status: state.status,
7227
- progress: {
7228
- status: state.status,
7229
- logs: state.logs,
7230
- ...state.error ? { error: state.error } : {}
7231
- },
7232
- ..."result" in state ? { result: state.result } : {}
7233
- };
7234
- }
7235
7245
  var DeeplineClient = class _DeeplineClient {
7236
7246
  http;
7237
7247
  config;
@@ -7374,14 +7384,14 @@ var DeeplineClient = class _DeeplineClient {
7374
7384
  }
7375
7385
  compactSchema(schema) {
7376
7386
  if (!schema) return null;
7377
- const fields = Array.isArray(schema.fields) ? schema.fields.map(
7387
+ const fields2 = Array.isArray(schema.fields) ? schema.fields.map(
7378
7388
  (field) => field && typeof field === "object" ? {
7379
7389
  name: String(field.name ?? ""),
7380
7390
  type: field.type ?? void 0,
7381
7391
  required: field.required ?? void 0
7382
7392
  } : null
7383
7393
  ).filter((field) => Boolean(field?.name)) : [];
7384
- return fields.length > 0 ? { fields } : schema;
7394
+ return fields2.length > 0 ? { fields: fields2 } : schema;
7385
7395
  }
7386
7396
  schemaMetadata(schema, key) {
7387
7397
  if (!isRecord7(schema)) return null;
@@ -7568,6 +7578,12 @@ var DeeplineClient = class _DeeplineClient {
7568
7578
  options.includeSearchDebug ? "true" : "false"
7569
7579
  );
7570
7580
  params.set("search_mode", options.searchMode ?? "v2");
7581
+ if (options.limit !== void 0) {
7582
+ params.set("limit", String(options.limit));
7583
+ }
7584
+ if (options.offset !== void 0) {
7585
+ params.set("offset", String(options.offset));
7586
+ }
7571
7587
  if (options.categories?.trim()) {
7572
7588
  params.set("categories", options.categories.trim());
7573
7589
  }
@@ -8629,9 +8645,18 @@ var DeeplineClient = class _DeeplineClient {
8629
8645
  }
8630
8646
  const query = params.size > 0 ? `?${params.toString()}` : "";
8631
8647
  const response = await this.http.get(
8632
- `/api/v2/runs/${encodeURIComponent(runId)}${query}`
8648
+ `/api/v2/runs/${encodeURIComponent(runId)}${query}`,
8649
+ { headers: { "x-deepline-run-status": "1" } }
8633
8650
  );
8651
+ const responseRunStatus = isPlayRunPackage(response) ? response.runStatus : isPlayRunPackage(response.package) ? response.package.runStatus : response.runStatus;
8652
+ const responseOverview = isPlayRunPackage(response) ? response.overview : isPlayRunPackage(response.package) ? response.package.overview : response.overview;
8634
8653
  const status = normalizePlayStatus(response);
8654
+ if (isRecord7(responseRunStatus)) {
8655
+ status.runStatus = responseRunStatus;
8656
+ }
8657
+ if (isRecord7(responseOverview)) {
8658
+ status.overview = responseOverview;
8659
+ }
8635
8660
  if (options?.failedLogs !== true || status.status !== "failed") {
8636
8661
  return status;
8637
8662
  }
@@ -8672,7 +8697,10 @@ var DeeplineClient = class _DeeplineClient {
8672
8697
  }
8673
8698
  };
8674
8699
  }
8675
- /** Read only the bounded scalar projection; does not hydrate the run package. */
8700
+ /** Fetch only the legacy scalar lifecycle status for a run.
8701
+ *
8702
+ * @deprecated Use `client.runs.get(runId)` for the canonical run read.
8703
+ */
8676
8704
  async getRunLifecycleStatus(runId) {
8677
8705
  const response = await this.http.get(
8678
8706
  `/api/v2/runs/${encodeURIComponent(runId)}/status`
@@ -8848,9 +8876,7 @@ var DeeplineClient = class _DeeplineClient {
8848
8876
  if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
8849
8877
  continue;
8850
8878
  }
8851
- return await this.getRunStatus(status.runId || runId).catch(
8852
- () => state.latest ?? playRunStatusFromState(state)
8853
- );
8879
+ return await this.getRunStatus(status.runId || runId);
8854
8880
  }
8855
8881
  if (options?.signal?.aborted) {
8856
8882
  throw new DeeplineError("Run observation aborted.", void 0, "ABORTED");
@@ -8901,6 +8927,7 @@ var DeeplineClient = class _DeeplineClient {
8901
8927
  for (; ; ) {
8902
8928
  const connectedAt = Date.now();
8903
8929
  let sawEvent = false;
8930
+ let terminalRunId = null;
8904
8931
  let endedReason = "stream window ended before a terminal event";
8905
8932
  try {
8906
8933
  for await (const event of this.streamPlayRunEvents(runId, {
@@ -8913,9 +8940,8 @@ var DeeplineClient = class _DeeplineClient {
8913
8940
  if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
8914
8941
  continue;
8915
8942
  }
8916
- return await this.getRunStatus(status.runId || runId).catch(
8917
- () => state.latest ?? playRunStatusFromState(state)
8918
- );
8943
+ terminalRunId = status.runId || runId;
8944
+ break;
8919
8945
  }
8920
8946
  } catch (error) {
8921
8947
  if (options?.signal?.aborted || !isTransientPlayStreamError(error)) {
@@ -8923,15 +8949,11 @@ var DeeplineClient = class _DeeplineClient {
8923
8949
  }
8924
8950
  endedReason = error instanceof Error ? error.message : String(error);
8925
8951
  }
8926
- let refreshed = null;
8927
- try {
8928
- refreshed = await this.getRunStatus(runId);
8929
- } catch (error) {
8930
- if (!isTransientPlayStreamError(error)) {
8931
- throw error;
8932
- }
8952
+ if (terminalRunId) {
8953
+ return await this.getRunStatus(terminalRunId);
8933
8954
  }
8934
- if (refreshed && TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
8955
+ const refreshed = await this.getRunStatus(runId);
8956
+ if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
8935
8957
  return refreshed;
8936
8958
  }
8937
8959
  if (sawEvent || Date.now() - connectedAt >= STREAM_HEALTHY_CONNECTION_MS) {
@@ -9220,6 +9242,26 @@ var DeeplineClient = class _DeeplineClient {
9220
9242
  hasMore: Boolean(response.pagination?.hasMore ?? response.hasMore)
9221
9243
  };
9222
9244
  }
9245
+ /** Read definition-level settings, independently of code revisions. */
9246
+ async getPlaySettings(playName) {
9247
+ return this.http.get(
9248
+ `/api/v2/plays/${encodeURIComponent(playName)}/settings`
9249
+ );
9250
+ }
9251
+ /** Retry-safe field patch; omitted fields retain their current value. */
9252
+ async updatePlaySettings(playName, patch) {
9253
+ return this.http.patch(
9254
+ `/api/v2/plays/${encodeURIComponent(playName)}/settings`,
9255
+ patch
9256
+ );
9257
+ }
9258
+ /** List one bounded page of existing Play locations; continue with cursor. */
9259
+ async listPlaySettingsPaths(options = {}) {
9260
+ const query = new URLSearchParams();
9261
+ for (const [key, value] of Object.entries(options))
9262
+ if (value !== void 0) query.set(key, String(value));
9263
+ return this.http.get(`/api/v2/plays/settings/paths?${query}`);
9264
+ }
9223
9265
  /** Set whether an org-owned Play sorts before unpinned Plays. */
9224
9266
  async setPlayPinned(playName, pinned) {
9225
9267
  return this.http.post(`/api/v2/plays/${encodeURIComponent(playName)}/pin`, {
@@ -10837,6 +10879,7 @@ async function checkSdkCompatibility(baseUrl, options = {}) {
10837
10879
  const response = await fetch(url, {
10838
10880
  method: "GET",
10839
10881
  headers: {
10882
+ ...deploymentProtectionHeaders(),
10840
10883
  "User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
10841
10884
  "X-Deepline-SDK-Version": SDK_VERSION,
10842
10885
  "X-Deepline-API-Major": String(SDK_API_MAJOR),
@@ -11713,8 +11756,8 @@ function resolvePendingAuthClaimForResume(baseUrl, requestedScope) {
11713
11756
  const claim = readPendingAuthClaim(baseUrl, requestedScope);
11714
11757
  return { claim, scope: claim?.scope ?? requestedScope };
11715
11758
  }
11716
- const folder = readPendingAuthClaim(baseUrl, "folder");
11717
- if (folder) return { claim: folder, scope: folder.scope };
11759
+ const folder2 = readPendingAuthClaim(baseUrl, "folder");
11760
+ if (folder2) return { claim: folder2, scope: folder2.scope };
11718
11761
  const global = readPendingAuthClaim(baseUrl, "global");
11719
11762
  return { claim: global, scope: global?.scope ?? "global" };
11720
11763
  }
@@ -15528,14 +15571,14 @@ function customerDbColumnNames(result) {
15528
15571
  function errorMessage(value) {
15529
15572
  return value instanceof Error ? value.message : String(value ?? "");
15530
15573
  }
15531
- function resolveDbQuerySql(rawSql, readFile7 = (path) => readFileSync7(path, "utf8")) {
15574
+ function resolveDbQuerySql(rawSql, readFile8 = (path) => readFileSync7(path, "utf8")) {
15532
15575
  const value = rawSql.trim();
15533
15576
  if (!value.startsWith("@")) return value;
15534
15577
  const filePath = value.slice(1).trim();
15535
15578
  if (!filePath) {
15536
15579
  throw new Error("--sql @file requires a file path after `@`.");
15537
15580
  }
15538
- return readFile7(resolve6(filePath)).trim();
15581
+ return readFile8(resolve6(filePath)).trim();
15539
15582
  }
15540
15583
  function collectErrorText(value) {
15541
15584
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -15906,7 +15949,7 @@ import {
15906
15949
  lstat as lstat2,
15907
15950
  mkdir as mkdir5,
15908
15951
  mkdtemp as mkdtemp3,
15909
- readFile as readFile4,
15952
+ readFile as readFile5,
15910
15953
  realpath as realpath4,
15911
15954
  rename as rename2,
15912
15955
  rm as rm3,
@@ -15914,9 +15957,335 @@ import {
15914
15957
  writeFile as writeFile4
15915
15958
  } from "fs/promises";
15916
15959
  import { homedir as homedir6, tmpdir as tmpdir5 } from "os";
15917
- import { basename as basename4, dirname as dirname11, extname as extname3, join as join14, resolve as resolve13 } from "path";
15960
+ import { basename as basename4, dirname as dirname11, extname as extname3, join as join15, resolve as resolve13 } from "path";
15918
15961
  import { Option as Option2 } from "commander";
15919
15962
 
15963
+ // ../plays/settings-contract.ts
15964
+ import { z } from "zod";
15965
+ function formatPlaySettingsError(error) {
15966
+ if (error instanceof z.ZodError)
15967
+ return [...new Set(error.issues.map((issue) => issue.message))].join(" ");
15968
+ return error instanceof Error ? error.message : String(error);
15969
+ }
15970
+ var PLAY_LOCATION_ROOTS = [
15971
+ {
15972
+ value: "person",
15973
+ label: "Personal",
15974
+ description: "The creator\u2019s personal root, displayed as their name followed by \u201C\u2019s team\u201D."
15975
+ },
15976
+ {
15977
+ value: "team",
15978
+ label: "Team library",
15979
+ description: "The shared team library. Publishing moves personal locations here, keeping their folders."
15980
+ }
15981
+ ];
15982
+ var folder = z.string().min(1).max(128).refine(
15983
+ (value) => value === value.trim() && value !== "." && value !== ".." && !/[\\/\u0000-\u001f\u007f]/u.test(value),
15984
+ "Folder names must be trimmed, cannot be . or .., and cannot contain slashes or control characters."
15985
+ );
15986
+ var playPathSchema = z.union([
15987
+ z.null(),
15988
+ z.object({
15989
+ root: z.enum(["person", "team"]),
15990
+ folders: z.array(folder).max(16).default([])
15991
+ }).strict()
15992
+ ]).transform(
15993
+ (path) => path?.root === "person" && path.folders.length === 0 ? null : path
15994
+ );
15995
+ function parsePlayPath(value) {
15996
+ const [root, ...parts] = value.split("/");
15997
+ if (!PLAY_LOCATION_ROOTS.some((option) => option.value === root)) {
15998
+ throw new Error(
15999
+ "Path must start with person or team. Example: person/Research/ICP."
16000
+ );
16001
+ }
16002
+ let folders;
16003
+ try {
16004
+ folders = parts.map(decodeURIComponent);
16005
+ } catch {
16006
+ throw new Error(
16007
+ "Path contains an invalid percent escape. Encode a literal % as %25."
16008
+ );
16009
+ }
16010
+ return playPathSchema.parse({ root, folders });
16011
+ }
16012
+ function formatPlayPath(path) {
16013
+ return path === null ? "person" : [path.root, ...path.folders.map(encodeURIComponent)].join("/");
16014
+ }
16015
+ function personalPlayRootLabel(ownerName) {
16016
+ const name = ownerName?.trim();
16017
+ return name ? `${name.split(/\s+/)[0]}\u2019s team` : "Personal";
16018
+ }
16019
+ function displayPlayPath(path, ownerName) {
16020
+ return [
16021
+ path?.root === "team" ? "Team library" : personalPlayRootLabel(ownerName),
16022
+ ...path?.folders ?? []
16023
+ ].join(" / ");
16024
+ }
16025
+ var PLAY_SETTING_FIELDS = {
16026
+ path: {
16027
+ schema: playPathSchema.default(null).describe(
16028
+ "Play location. Null means the creator\u2019s personal root. Publishing moves it into Team library, preserving folders."
16029
+ ),
16030
+ label: "Location",
16031
+ description: "Organize this Play in the creator\u2019s personal root or Team library. Publishing moves it to Team library and keeps its folders. Workspace sharing permissions apply in both roots.",
16032
+ get defaultValue() {
16033
+ return this.schema.parse(void 0);
16034
+ },
16035
+ cli: {
16036
+ valueSyntax: "person[/folder/\u2026] | team[/folder/\u2026] | null",
16037
+ examples: [
16038
+ "person",
16039
+ "person/Research/ICP",
16040
+ "team",
16041
+ "team/Research",
16042
+ "null"
16043
+ ],
16044
+ parse: (value) => value === "null" ? null : parsePlayPath(value),
16045
+ format: formatPlayPath
16046
+ },
16047
+ ui: { control: "play-location-picker" }
16048
+ }
16049
+ };
16050
+ var playSettingsSchema = z.object(
16051
+ Object.fromEntries(
16052
+ Object.entries(PLAY_SETTING_FIELDS).map(([key, field]) => [
16053
+ key,
16054
+ field.schema
16055
+ ])
16056
+ )
16057
+ ).passthrough();
16058
+ var playSettingsPatchSchema = z.object(
16059
+ Object.fromEntries(
16060
+ Object.entries(PLAY_SETTING_FIELDS).map(([key, field]) => [
16061
+ key,
16062
+ field.schema.unwrap().optional()
16063
+ ])
16064
+ )
16065
+ ).strict().refine(
16066
+ (patch) => Object.keys(patch).length > 0,
16067
+ "Supply at least one setting."
16068
+ );
16069
+ function parsePlaySettings(value) {
16070
+ return playSettingsSchema.parse(value);
16071
+ }
16072
+ var DEFAULT_PLAY_SETTINGS = parsePlaySettings({});
16073
+
16074
+ // src/cli/commands/plays-settings.ts
16075
+ var fields = Object.entries(PLAY_SETTING_FIELDS);
16076
+ var help = `
16077
+ Settings live on the Play definition. Edits preserve code revisions.
16078
+ New Plays start at person (the creator\u2019s personal root, e.g. Chirag\u2019s team).
16079
+ Publishing moves a Play into team and keeps its folders. Workspace sharing
16080
+ permissions apply in both roots. Folder paths are independent of your cwd.
16081
+
16082
+ Setting names and values:
16083
+ ${fields.map(([key, field]) => ` ${key}: ${field.schema.description}
16084
+ Values: ${field.cli.valueSyntax}
16085
+ Default: ${JSON.stringify(field.defaultValue)} (${field.cli.format(field.defaultValue)})`).join("\n")}
16086
+
16087
+ Roots:
16088
+ ${PLAY_LOCATION_ROOTS.map((root) => ` ${root.value}: ${root.description}`).join("\n")}
16089
+
16090
+ Examples:
16091
+ deepline plays settings describe --name path --json
16092
+ deepline plays settings get --play company-research --json
16093
+ deepline plays settings get --play company-research --name path
16094
+ deepline plays settings set --play company-research --name path --value person/Research/ICP
16095
+ deepline plays settings set --play company-research --name path --value team/Research
16096
+ deepline plays settings reset --play company-research --name path
16097
+ deepline plays settings paths --root team --json
16098
+
16099
+ Quote values containing spaces. Use percent escapes for literal % characters.
16100
+ `;
16101
+ function resolveField(key, command) {
16102
+ const entry = fields.find(([name]) => name === key);
16103
+ if (!entry)
16104
+ command.error(
16105
+ `Unknown --name ${JSON.stringify(key)}. Available settings: ${fields.map(([name]) => name).join(", ")}. Run deepline plays settings describe.`,
16106
+ { exitCode: 2 }
16107
+ );
16108
+ return entry[1];
16109
+ }
16110
+ function printSettings(result, json2, name) {
16111
+ const selected = fields.filter(([key]) => !name || key === name);
16112
+ printCommandEnvelope(
16113
+ {
16114
+ ...result,
16115
+ settings: Object.fromEntries(
16116
+ selected.map(([key]) => [
16117
+ key,
16118
+ result.settings[key]
16119
+ ])
16120
+ ),
16121
+ render: {
16122
+ sections: [
16123
+ {
16124
+ title: "Play settings",
16125
+ lines: selected.map(
16126
+ ([key, field]) => `${field.label}: ${key === "path" ? displayPlayPath(result.settings.path, result.ownerName) : field.cli.format(result.settings[key])} (${field.cli.format(result.settings[key])})`
16127
+ )
16128
+ }
16129
+ ]
16130
+ }
16131
+ },
16132
+ { json: json2 }
16133
+ );
16134
+ }
16135
+ function registerPlaySettingsCommands(plays) {
16136
+ const settings = plays.command("settings").description("Read and change Play settings by name and value.").exitOverride((error) => {
16137
+ if (error.exitCode !== 0) error.exitCode = 2;
16138
+ throw error;
16139
+ }).addHelpText("after", help);
16140
+ settings.command("describe").usage("[--name <setting>] [options]").description(
16141
+ "List setting names, values, examples and defaults; no authentication required."
16142
+ ).option(
16143
+ "--name <setting>",
16144
+ `Describe one setting. Available: ${fields.map(([key]) => key).join(", ")}`
16145
+ ).option("--json", "Emit JSON; automatic when piped").addHelpText("after", help).action((options, command) => {
16146
+ if (options.name !== void 0) resolveField(options.name, command);
16147
+ const descriptions = fields.filter(([name]) => !options.name || options.name === name).map(([name, field]) => ({
16148
+ key: name,
16149
+ label: field.label,
16150
+ description: field.schema.description ?? field.description,
16151
+ default: field.defaultValue,
16152
+ defaultText: field.cli.format(field.defaultValue),
16153
+ valueSyntax: field.cli.valueSyntax,
16154
+ examples: field.cli.examples
16155
+ }));
16156
+ printCommandEnvelope(
16157
+ {
16158
+ fields: descriptions,
16159
+ render: {
16160
+ sections: descriptions.map((field) => ({
16161
+ title: field.key,
16162
+ lines: [
16163
+ field.description,
16164
+ `Values: ${field.valueSyntax}`,
16165
+ `Default: ${JSON.stringify(field.default)} (${field.defaultText})`,
16166
+ `Examples: ${field.examples.join(", ")}`
16167
+ ]
16168
+ }))
16169
+ }
16170
+ },
16171
+ { json: options.json }
16172
+ );
16173
+ });
16174
+ settings.command("get").usage("--play <play> [--name <setting>] [options]").description("Read all settings, or one setting selected with --name.").requiredOption("--play <play>", "Play to read").option(
16175
+ "--name <setting>",
16176
+ `Read one setting. Available: ${fields.map(([key]) => key).join(", ")}`
16177
+ ).option("--json", "Emit JSON; automatic when piped").addHelpText("after", help).action(
16178
+ async (options, command) => {
16179
+ if (options.name !== void 0) resolveField(options.name, command);
16180
+ printSettings(
16181
+ await new DeeplineClient().getPlaySettings(options.play),
16182
+ options.json,
16183
+ options.name
16184
+ );
16185
+ }
16186
+ );
16187
+ const set = settings.command("set").usage("--play <play> --name <setting> --value <value> [options]").requiredOption("--play <play>", "Play to update").requiredOption(
16188
+ "--name <setting>",
16189
+ `Setting name. Available: ${fields.map(([key]) => key).join(", ")}`
16190
+ ).requiredOption(
16191
+ "--value <value>",
16192
+ "New value; see settings describe --name <setting>"
16193
+ ).description("Set one setting without creating or publishing a revision.");
16194
+ const reset = settings.command("reset").usage("--play <play> --name <setting> [options]").requiredOption("--play <play>", "Play to update").requiredOption(
16195
+ "--name <setting>",
16196
+ `Setting name. Available: ${fields.map(([key]) => key).join(", ")}`
16197
+ ).description("Reset one setting to its schema default.");
16198
+ const change = async (command, play, key, value, options, resetting) => {
16199
+ const field = resolveField(key, command);
16200
+ let patch;
16201
+ try {
16202
+ patch = playSettingsPatchSchema.parse({
16203
+ [key]: resetting ? field.defaultValue : field.cli.parse(value)
16204
+ });
16205
+ } catch (error) {
16206
+ command.error(
16207
+ `Invalid --value for --name ${key}: ${formatPlaySettingsError(error)} Values: ${field.cli.valueSyntax}.`,
16208
+ { exitCode: 2 }
16209
+ );
16210
+ }
16211
+ if (options.dryRun) {
16212
+ printCommandEnvelope(
16213
+ {
16214
+ dryRun: true,
16215
+ play,
16216
+ patch,
16217
+ render: {
16218
+ sections: [
16219
+ {
16220
+ title: "Planned settings patch",
16221
+ lines: Object.entries(patch).map(
16222
+ ([name, setting]) => `${name}: ${JSON.stringify(setting)}`
16223
+ )
16224
+ }
16225
+ ]
16226
+ }
16227
+ },
16228
+ { json: options.json }
16229
+ );
16230
+ return;
16231
+ }
16232
+ printSettings(
16233
+ await new DeeplineClient().updatePlaySettings(play, patch),
16234
+ options.json
16235
+ );
16236
+ };
16237
+ for (const [command, resetting] of [
16238
+ [set, false],
16239
+ [reset, true]
16240
+ ])
16241
+ command.option("--dry-run", "Show the patch without changing settings").option("--json", "Emit JSON; automatic when piped").addHelpText("after", help).action(
16242
+ (options) => change(
16243
+ command,
16244
+ options.play,
16245
+ options.name,
16246
+ options.value,
16247
+ options,
16248
+ resetting
16249
+ )
16250
+ );
16251
+ settings.command("paths").description("List existing locations (one bounded page).").option("--root <person|team>", "Filter by root").option("--limit <n>", "Plays to inspect, 1\u2013100", "50").option("--cursor <cursor>", "Continue from a previous page").option("--json", "Emit JSON; automatic when piped").addHelpText("after", help).action(
16252
+ async (options, command) => {
16253
+ const limit = Number(options.limit);
16254
+ if (options.root !== void 0 && options.root !== "person" && options.root !== "team" || !Number.isInteger(limit) || limit < 1 || limit > 100)
16255
+ command.error(
16256
+ "--root must be person or team; --limit must be 1\u2013100.",
16257
+ { exitCode: 2 }
16258
+ );
16259
+ const page = await new DeeplineClient().listPlaySettingsPaths({
16260
+ root: options.root,
16261
+ limit,
16262
+ cursor: options.cursor
16263
+ });
16264
+ const nextCommand = page.hasMore ? `deepline plays settings paths --cursor '${page.cursor}'${options.root ? ` --root ${options.root}` : ""} --json` : null;
16265
+ printCommandEnvelope(
16266
+ {
16267
+ ...page,
16268
+ nextCommand,
16269
+ render: {
16270
+ sections: [
16271
+ {
16272
+ title: "Play locations",
16273
+ lines: [
16274
+ ...page.paths.map(
16275
+ (item) => `${displayPlayPath(item.path, item.ownerName)} (${formatPlayPath(item.path)}) \u2014 ${item.playName}`
16276
+ ),
16277
+ ...nextCommand ? [`More: ${nextCommand}`] : []
16278
+ ]
16279
+ }
16280
+ ]
16281
+ }
16282
+ },
16283
+ { json: options.json }
16284
+ );
16285
+ }
16286
+ );
16287
+ }
16288
+
15920
16289
  // src/cli/commands/play.ts
15921
16290
  import { createHash as createHash4, randomUUID as randomUUID4 } from "crypto";
15922
16291
  import {
@@ -15940,7 +16309,7 @@ import {
15940
16309
  basename as basename3,
15941
16310
  dirname as dirname10,
15942
16311
  isAbsolute as isAbsolute5,
15943
- join as join13,
16312
+ join as join14,
15944
16313
  relative as relative5,
15945
16314
  resolve as resolve12
15946
16315
  } from "path";
@@ -16560,8 +16929,8 @@ function readCsvHeaderFields(csvPath, sample) {
16560
16929
  skip_empty_lines: false
16561
16930
  });
16562
16931
  const firstRecord = Array.isArray(records) ? records[0] : null;
16563
- const fields = Array.isArray(firstRecord) ? firstRecord.map((field) => String(field ?? "").trim()).filter(Boolean) : [];
16564
- const uniqueFields = [...new Set(fields)];
16932
+ const fields2 = Array.isArray(firstRecord) ? firstRecord.map((field) => String(field ?? "").trim()).filter(Boolean) : [];
16933
+ const uniqueFields = [...new Set(fields2)];
16565
16934
  if (uniqueFields.length === 0) {
16566
16935
  throw new PlayBootstrapUsageError(
16567
16936
  `Could not read a header row from --from csv:${csvPath}.`
@@ -17650,6 +18019,45 @@ Examples:
17650
18019
  });
17651
18020
  }
17652
18021
 
18022
+ // src/cli/commands/plays/run-history.ts
18023
+ async function handleRunsHistory(options) {
18024
+ const query = new URLSearchParams();
18025
+ if (options.cursor) query.set("cursor", options.cursor);
18026
+ if (options.org) query.set("orgId", options.org);
18027
+ if (options.limit !== void 0) {
18028
+ const limit = Number(options.limit);
18029
+ if (!/^\d+$/.test(options.limit) || !Number.isSafeInteger(limit) || limit < 1) {
18030
+ throw new Error("--limit must be a positive integer.");
18031
+ }
18032
+ query.set("limit", String(limit));
18033
+ }
18034
+ const search = query.toString();
18035
+ const page = await new HttpClient(resolveConfig()).get(
18036
+ `/api/v2/dashboard/runs-history${search ? `?${search}` : ""}`
18037
+ );
18038
+ const lines = page.runs.map(
18039
+ (run) => `${run.workflowName} \xB7 ${run.status} \xB7 ${run.runId}`
18040
+ );
18041
+ if (lines.length === 0) lines.push("No runs found on this page.");
18042
+ if (page.hasMore) lines.push(`Next cursor: ${page.nextCursor}`);
18043
+ printCommandEnvelope(
18044
+ { ...page, render: { sections: [{ title: "Run history", lines }] } },
18045
+ options.json ? { json: true } : {}
18046
+ );
18047
+ }
18048
+ function registerRunHistoryCommand(runs) {
18049
+ runs.command("history").description("Page workspace run history.").option(
18050
+ "--cursor <cursor>",
18051
+ "Opaque nextCursor returned by the previous page"
18052
+ ).option("--limit <count>", "Maximum runs on this page").option(
18053
+ "--org <id>",
18054
+ "Workspace ID (must match the authenticated workspace)"
18055
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").addHelpText(
18056
+ "after",
18057
+ "\nUse the opaque --cursor returned by the previous page to continue.\n\nExample:\n deepline runs history --limit 100 --json\n"
18058
+ ).action(handleRunsHistory);
18059
+ }
18060
+
17653
18061
  // src/plays/bundle-play-file.ts
17654
18062
  import { tmpdir as tmpdir3 } from "os";
17655
18063
  import { dirname as dirname9, join as join9, resolve as resolve10 } from "path";
@@ -20554,7 +20962,7 @@ function recordCliTrace(event) {
20554
20962
  process.stderr.write(`[cli-trace] ${JSON.stringify(payload)}
20555
20963
  `);
20556
20964
  }
20557
- async function traceCliSpan(phase, fields, run) {
20965
+ async function traceCliSpan(phase, fields2, run) {
20558
20966
  if (!isCliTraceEnabled()) {
20559
20967
  return run();
20560
20968
  }
@@ -20565,7 +20973,7 @@ async function traceCliSpan(phase, fields, run) {
20565
20973
  phase,
20566
20974
  ms: Date.now() - startedAt,
20567
20975
  ok: true,
20568
- ...fields
20976
+ ...fields2
20569
20977
  });
20570
20978
  return result;
20571
20979
  } catch (error) {
@@ -20574,7 +20982,7 @@ async function traceCliSpan(phase, fields, run) {
20574
20982
  ms: Date.now() - startedAt,
20575
20983
  ok: false,
20576
20984
  error: error instanceof Error ? error.message : String(error),
20577
- ...fields
20985
+ ...fields2
20578
20986
  });
20579
20987
  throw error;
20580
20988
  }
@@ -21223,10 +21631,10 @@ function normalizeFixtureScopeValue(value, maxLength) {
21223
21631
  import { randomUUID as randomUUID3 } from "crypto";
21224
21632
  import { mkdtemp as mkdtemp2, realpath as realpath3, rm as rm2 } from "fs/promises";
21225
21633
  import { tmpdir as tmpdir4 } from "os";
21226
- import { join as join12, resolve as resolve11 } from "path";
21634
+ import { join as join13, resolve as resolve11 } from "path";
21227
21635
 
21228
21636
  // ../plays/deploy/run-deployment.ts
21229
- import { join as join11 } from "path";
21637
+ import { join as join12 } from "path";
21230
21638
  import { mkdir as mkdir4, mkdtemp, rm } from "fs/promises";
21231
21639
 
21232
21640
  // ../plays/deployment-status.ts
@@ -21335,6 +21743,21 @@ var DeployApiClient = class {
21335
21743
  body: { names }
21336
21744
  });
21337
21745
  }
21746
+ monitors(action, entries) {
21747
+ return this.request({
21748
+ method: "POST",
21749
+ path: this.deploymentPath("/monitors"),
21750
+ body: { action, entries }
21751
+ });
21752
+ }
21753
+ monitorJob(jobId, monitorKey) {
21754
+ return this.request({
21755
+ method: "GET",
21756
+ path: this.deploymentPath(
21757
+ `/monitors?jobId=${encodeURIComponent(jobId)}&monitorKey=${encodeURIComponent(monitorKey)}`
21758
+ )
21759
+ });
21760
+ }
21338
21761
  compileManifest(input2) {
21339
21762
  return this.request({
21340
21763
  method: "POST",
@@ -21387,7 +21810,8 @@ var import_picomatch = __toESM(require_picomatch2(), 1);
21387
21810
  import { readdir, readFile as readFile3, stat as stat3 } from "fs/promises";
21388
21811
  import { join as join10, relative as relative4 } from "path";
21389
21812
  var DEFAULT_PLAY_GLOBS = ["**/*.play.ts"];
21390
- var MAX_DISCOVERED_PLAY_FILES = 200;
21813
+ var DEFAULT_MONITOR_GLOBS = ["**/*.monitor.json"];
21814
+ var MAX_DISCOVERED_FILES = 200;
21391
21815
  var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([
21392
21816
  "node_modules",
21393
21817
  ".git",
@@ -21401,9 +21825,26 @@ var DeeplineManifestError = class extends Error {
21401
21825
  this.name = "DeeplineManifestError";
21402
21826
  }
21403
21827
  };
21828
+ function readGlobs(value, field) {
21829
+ if (!Array.isArray(value) || field === "plays" && value.length === 0 || !value.every((glob) => typeof glob === "string" && glob.trim().length > 0)) {
21830
+ throw new DeeplineManifestError(
21831
+ `deepline.json "${field}" must be ${field === "plays" ? "a non-empty" : "an"} array of glob strings.`
21832
+ );
21833
+ }
21834
+ const globs = value.map((glob) => glob.trim().replace(/^\.\//, ""));
21835
+ if (globs.some((glob) => glob.startsWith("/") || glob.includes(".."))) {
21836
+ throw new DeeplineManifestError(
21837
+ `deepline.json "${field}" globs must be relative and must not contain "..".`
21838
+ );
21839
+ }
21840
+ return globs;
21841
+ }
21404
21842
  function parseDeeplineManifest(raw) {
21405
21843
  if (raw === null) {
21406
- return { plays: DEFAULT_PLAY_GLOBS };
21844
+ return {
21845
+ plays: DEFAULT_PLAY_GLOBS,
21846
+ monitors: DEFAULT_MONITOR_GLOBS
21847
+ };
21407
21848
  }
21408
21849
  let parsed;
21409
21850
  try {
@@ -21417,24 +21858,14 @@ function parseDeeplineManifest(raw) {
21417
21858
  throw new DeeplineManifestError("deepline.json must be a JSON object.");
21418
21859
  }
21419
21860
  const record3 = parsed;
21420
- let plays = DEFAULT_PLAY_GLOBS;
21421
- if (record3.plays !== void 0) {
21422
- if (!Array.isArray(record3.plays) || record3.plays.length === 0 || !record3.plays.every(
21423
- (glob) => typeof glob === "string" && glob.trim().length > 0
21424
- )) {
21425
- throw new DeeplineManifestError(
21426
- 'deepline.json "plays" must be a non-empty array of glob strings, e.g. ["plays/**/*.play.ts"].'
21427
- );
21428
- }
21429
- plays = record3.plays.map((glob) => glob.trim().replace(/^\.\//, ""));
21430
- }
21431
- if (plays.some((glob) => glob.startsWith("/") || glob.includes(".."))) {
21432
- throw new DeeplineManifestError(
21433
- 'deepline.json "plays" globs must be relative and must not contain "..".'
21434
- );
21435
- }
21861
+ const plays = record3.plays === void 0 ? DEFAULT_PLAY_GLOBS : readGlobs(record3.plays, "plays");
21862
+ const monitors = record3.monitors === void 0 ? DEFAULT_MONITOR_GLOBS : readGlobs(record3.monitors, "monitors");
21436
21863
  const org = typeof record3.org === "string" && record3.org.trim() ? record3.org.trim() : void 0;
21437
- return { plays, ...org ? { org } : {} };
21864
+ return {
21865
+ plays,
21866
+ monitors,
21867
+ ...org ? { org } : {}
21868
+ };
21438
21869
  }
21439
21870
  var DEFAULT_MANIFEST_FILE = "deepline.json";
21440
21871
  async function readDeeplineManifest(projectRoot, manifestFile = DEFAULT_MANIFEST_FILE) {
@@ -21464,7 +21895,7 @@ async function readDeeplineManifest(projectRoot, manifestFile = DEFAULT_MANIFEST
21464
21895
  throw error;
21465
21896
  }
21466
21897
  }
21467
- async function discoverPlayFiles(input2) {
21898
+ async function discoverDeploymentFiles(input2) {
21468
21899
  const matchers = input2.globs.map((glob) => (0, import_picomatch.default)(glob));
21469
21900
  const found = [];
21470
21901
  async function walk(dir) {
@@ -21481,9 +21912,9 @@ async function discoverPlayFiles(input2) {
21481
21912
  const relativePath = relative4(input2.projectRoot, absolute);
21482
21913
  if (matchers.some((match) => match(relativePath))) {
21483
21914
  found.push(relativePath);
21484
- if (found.length > MAX_DISCOVERED_PLAY_FILES) {
21915
+ if (found.length > MAX_DISCOVERED_FILES) {
21485
21916
  throw new DeeplineManifestError(
21486
- `deepline.json globs matched more than ${MAX_DISCOVERED_PLAY_FILES} play files. Tighten the globs.`
21917
+ `deepline.json globs matched more than ${MAX_DISCOVERED_FILES} files. Tighten the globs.`
21487
21918
  );
21488
21919
  }
21489
21920
  }
@@ -21498,6 +21929,39 @@ async function discoverPlayFiles(input2) {
21498
21929
  await walk(input2.projectRoot);
21499
21930
  return found.sort();
21500
21931
  }
21932
+ var discoverPlayFiles = discoverDeploymentFiles;
21933
+
21934
+ // ../plays/deploy/monitor-files.ts
21935
+ import { readFile as readFile4 } from "fs/promises";
21936
+ import { join as join11 } from "path";
21937
+ async function readMonitorFiles(input2) {
21938
+ const files = await discoverDeploymentFiles(input2);
21939
+ if (files.length > 100) {
21940
+ throw new DeeplineManifestError(
21941
+ "A deployment may contain at most 100 monitor definitions. Split the repository into multiple linked targets."
21942
+ );
21943
+ }
21944
+ return Promise.all(
21945
+ files.map(async (file) => {
21946
+ const sourcePath = input2.rootDirectory ? `${input2.rootDirectory}/${file}` : file;
21947
+ const raw = await readFile4(join11(input2.projectRoot, file), "utf8");
21948
+ try {
21949
+ return { file: sourcePath, definition: JSON.parse(raw) };
21950
+ } catch {
21951
+ throw new DeeplineManifestError(
21952
+ `${sourcePath} must contain a monitor definition as valid JSON.`
21953
+ );
21954
+ }
21955
+ })
21956
+ );
21957
+ }
21958
+ function monitorDeploymentSummary(outcomes) {
21959
+ return outcomes.map(
21960
+ (outcome) => `- Monitor \`${outcome.key}\` (\`${outcome.file}\`): ${outcome.status}${outcome.credits != null ? ` (${outcome.credits} Deepline credits)` : ""}${outcome.jobId ? ` \u2014 job \`${outcome.jobId}\`` : ""}${outcome.error ? `
21961
+ - ${outcome.error}` : ""}${outcome.warning ? `
21962
+ - :warning: ${outcome.warning}` : ""}`
21963
+ ).join("\n");
21964
+ }
21501
21965
 
21502
21966
  // ../plays/play-reference.ts
21503
21967
  var PREBUILT_PLAY_NAMESPACE = "prebuilt";
@@ -21713,12 +22177,15 @@ async function runDeployment(params, hooks) {
21713
22177
  }
21714
22178
  }
21715
22179
  const buildSeconds = () => Math.max(0, (Date.now() - startedAt) / 1e3);
22180
+ let monitorOutcomes = [];
22181
+ const monitorResults = () => monitorOutcomes.length > 0 ? { monitors: monitorOutcomes } : {};
22182
+ const monitorRunResult = () => monitorOutcomes.length > 0 ? { monitorOutcomes } : {};
21716
22183
  const finishFailed = async (input2) => {
21717
22184
  try {
21718
22185
  await setStatus({
21719
22186
  status: "failed",
21720
22187
  error: input2.error.slice(0, 2e3),
21721
- results: { plays: input2.outcomes },
22188
+ results: { plays: input2.outcomes, ...monitorResults() },
21722
22189
  buildSeconds: buildSeconds(),
21723
22190
  ...input2.checkRunId ? { checkRunId: input2.checkRunId } : {}
21724
22191
  });
@@ -21737,15 +22204,18 @@ async function runDeployment(params, hooks) {
21737
22204
  return {
21738
22205
  finalStatus: "failed",
21739
22206
  outcomes: input2.outcomes,
22207
+ ...monitorRunResult(),
21740
22208
  checkRunId: input2.checkRunId
21741
22209
  };
21742
22210
  };
21743
22211
  const finishSucceeded = async (outcomes, checkRun) => {
21744
- const finalStatus = outcomes.some((outcome) => outcome.warning) ? "succeeded_with_warnings" : "succeeded";
22212
+ const finalStatus = [...outcomes, ...monitorOutcomes].some(
22213
+ (outcome) => outcome.warning
22214
+ ) ? "succeeded_with_warnings" : "succeeded";
21745
22215
  try {
21746
22216
  await setStatus({
21747
22217
  status: finalStatus,
21748
- results: { plays: outcomes },
22218
+ results: { plays: outcomes, ...monitorResults() },
21749
22219
  buildSeconds: buildSeconds(),
21750
22220
  ...checkRun ? { checkRunId: checkRun.checkRunId } : {}
21751
22221
  });
@@ -21762,11 +22232,12 @@ async function runDeployment(params, hooks) {
21762
22232
  return {
21763
22233
  finalStatus,
21764
22234
  outcomes,
22235
+ ...monitorRunResult(),
21765
22236
  checkRunId: checkRun?.checkRunId
21766
22237
  };
21767
22238
  };
21768
22239
  await mkdir4(hooks.workRoot, { recursive: true });
21769
- const workDir = await mkdtemp(join11(hooks.workRoot, "deploy-"));
22240
+ const workDir = await mkdtemp(join12(hooks.workRoot, "deploy-"));
21770
22241
  const postCheck = async (postCheckOnce, input2) => {
21771
22242
  let lastError;
21772
22243
  for (let attempt = 0; ; attempt += 1) {
@@ -21842,7 +22313,7 @@ async function runDeployment(params, hooks) {
21842
22313
  await writeCheck({
21843
22314
  conclusion: "neutral",
21844
22315
  title: `Deployment ${stopped}`,
21845
- summary: "This deployment was stopped before it finished. Nothing from it went live."
22316
+ summary: monitorOutcomes.some((outcome) => outcome.jobId) ? "This deployment was stopped before it finished. Monitor jobs already submitted may have changed live resources; inspect the jobs in its receipt." : "This deployment was stopped before it finished. Nothing from it went live."
21846
22317
  }).catch(() => void 0);
21847
22318
  throw revocation;
21848
22319
  });
@@ -21882,6 +22353,7 @@ async function runDeployment(params, hooks) {
21882
22353
  status: "superseded",
21883
22354
  error: `Branch ${deploymentBranch} is now at ${head?.slice(0, 12) ?? "<deleted>"}; this deployment's commit is no longer the head.`,
21884
22355
  buildSeconds: buildSeconds(),
22356
+ ...monitorOutcomes.length > 0 ? { results: monitorResults() } : {},
21885
22357
  ...head ? { observedHeadSha: head } : {}
21886
22358
  });
21887
22359
  return { finalStatus: "superseded", outcomes: [] };
@@ -21891,16 +22363,28 @@ async function runDeployment(params, hooks) {
21891
22363
  if (superseded) return superseded;
21892
22364
  }
21893
22365
  const { repoRoot } = await source.open(workDir);
21894
- const projectRoot = target.rootDirectory ? join11(repoRoot, target.rootDirectory) : repoRoot;
22366
+ const projectRoot = target.rootDirectory ? join12(repoRoot, target.rootDirectory) : repoRoot;
21895
22367
  const manifestFile = target.manifestPath || DEFAULT_MANIFEST_FILE;
21896
22368
  let manifest;
21897
22369
  let playFiles;
22370
+ let monitorEntries;
21898
22371
  try {
21899
22372
  manifest = await readDeeplineManifest(projectRoot, manifestFile);
21900
22373
  playFiles = await discoverPlayFiles({
21901
22374
  projectRoot,
21902
22375
  globs: manifest.plays
21903
22376
  });
22377
+ const discoveredMonitors = await readMonitorFiles({
22378
+ projectRoot,
22379
+ rootDirectory: target.rootDirectory,
22380
+ globs: manifest.monitors
22381
+ });
22382
+ if (!project && discoveredMonitors.length > 0) {
22383
+ throw new DeeplineManifestError(
22384
+ "Monitor Git deployment requires a linked repository. Deploy individual monitor files with deepline monitors deploy --file."
22385
+ );
22386
+ }
22387
+ monitorEntries = project && discoveredMonitors.length > 0 ? discoveredMonitors : void 0;
21904
22388
  } catch (error) {
21905
22389
  if (error instanceof DeeplineManifestError) {
21906
22390
  return await failWithCheck({
@@ -21925,7 +22409,28 @@ async function runDeployment(params, hooks) {
21925
22409
  });
21926
22410
  }
21927
22411
  }
21928
- if (playFiles.length === 0) {
22412
+ if (monitorEntries !== void 0) {
22413
+ const plan = await client2.monitors("plan", monitorEntries);
22414
+ monitorOutcomes = plan.monitors;
22415
+ const failed = monitorOutcomes.filter(
22416
+ (outcome) => outcome.status === "failed"
22417
+ );
22418
+ if (failed.length > 0) {
22419
+ return await failWithCheck({
22420
+ title: "Monitor validation failed",
22421
+ summary: monitorDeploymentSummary(monitorOutcomes),
22422
+ error: `${failed.length} monitor definition(s) failed validation.`,
22423
+ outcomes: [],
22424
+ annotations: failed.map(
22425
+ (outcome) => annotationForFailure({
22426
+ file: outcome.file,
22427
+ message: outcome.error ?? "Monitor validation failed."
22428
+ })
22429
+ )
22430
+ });
22431
+ }
22432
+ }
22433
+ if (playFiles.length === 0 && monitorOutcomes.length === 0) {
21929
22434
  const checkRun2 = await postCheckOrNull({
21930
22435
  conclusion: "neutral",
21931
22436
  title: "No plays matched",
@@ -21952,7 +22457,7 @@ async function runDeployment(params, hooks) {
21952
22457
  annotations.push(annotationForFailure({ file, message }));
21953
22458
  };
21954
22459
  for (const file of playFiles) {
21955
- const entryFile = join11(projectRoot, file);
22460
+ const entryFile = join12(projectRoot, file);
21956
22461
  const result = await hooks.bundle(entryFile, {
21957
22462
  sourceIdentityRoot: projectRoot
21958
22463
  });
@@ -22058,7 +22563,7 @@ async function runDeployment(params, hooks) {
22058
22563
  if (superseded) return superseded;
22059
22564
  }
22060
22565
  await setStatus({ status: "publishing" }).catch(() => void 0);
22061
- const states = await client2.playsState(ordered.map((play) => play.name));
22566
+ const states = ordered.length > 0 ? await client2.playsState(ordered.map((play) => play.name)) : { plays: [] };
22062
22567
  const stateByName = new Map(
22063
22568
  states.plays.map((play) => [play.name, play])
22064
22569
  );
@@ -22192,12 +22697,15 @@ async function runDeployment(params, hooks) {
22192
22697
  ).length;
22193
22698
  const checkRun2 = await postCheckOrNull({
22194
22699
  conclusion: "success",
22195
- title: `${ordered.length} play${ordered.length === 1 ? "" : "s"} validated and registered (not deployed)`,
22700
+ title: monitorEntries !== void 0 ? `${ordered.length} play(s) validated and registered; ${monitorEntries.length} monitor(s) checked (not deployed)` : `${ordered.length} play${ordered.length === 1 ? "" : "s"} validated and registered (not deployed)`,
22196
22701
  ...annotations.length > 0 ? { annotations } : {},
22197
- summary: outcomes.map(
22198
- (outcome) => `- \`${outcome.name}\`: ${outcome.status}${outcome.version !== void 0 ? ` (v${outcome.version})` : ""}${outcome.sdkUpdated ? " \u2014 SDK updated" : ""}${outcome.warning ? `
22702
+ summary: [
22703
+ outcomes.map(
22704
+ (outcome) => `- \`${outcome.name}\`: ${outcome.status}${outcome.version !== void 0 ? ` (v${outcome.version})` : ""}${outcome.sdkUpdated ? " \u2014 SDK updated" : ""}${outcome.warning ? `
22199
22705
  - :warning: ${outcome.warning}` : ""}`
22200
- ).join("\n")
22706
+ ).join("\n"),
22707
+ monitorDeploymentSummary(monitorOutcomes)
22708
+ ].filter(Boolean).join("\n")
22201
22709
  });
22202
22710
  const result = await finishSucceeded(outcomes, checkRun2);
22203
22711
  console.info("[deploy-worker] PR registration complete", {
@@ -22211,6 +22719,51 @@ async function runDeployment(params, hooks) {
22211
22719
  const superseded = await supersedeIfHeadMoved();
22212
22720
  if (superseded) return superseded;
22213
22721
  }
22722
+ if (monitorEntries !== void 0) {
22723
+ monitorOutcomes = (await client2.monitors("apply", monitorEntries)).monitors;
22724
+ await setStatus({
22725
+ status: "publishing",
22726
+ results: { plays: outcomes, ...monitorResults() }
22727
+ });
22728
+ const deadline = Date.now() + 10 * 6e4;
22729
+ while (monitorOutcomes.some((outcome) => outcome.status === "applying")) {
22730
+ if (Date.now() >= deadline) {
22731
+ throw new RetryableDeploymentError(
22732
+ "Monitor jobs are still reconciling. Retrying this deployment will resume the same jobs."
22733
+ );
22734
+ }
22735
+ await new Promise((resolve22) => setTimeout(resolve22, 1e3));
22736
+ for (let index = 0; index < monitorOutcomes.length; index += 1) {
22737
+ const outcome = monitorOutcomes[index];
22738
+ if (outcome.status !== "applying") continue;
22739
+ if (!outcome.jobId) {
22740
+ throw new Error(
22741
+ `Monitor ${outcome.key} has no reconciliation job.`
22742
+ );
22743
+ }
22744
+ const result = await client2.monitorJob(outcome.jobId, outcome.key);
22745
+ const settled = result.monitors.find(
22746
+ (monitor) => monitor.key === outcome.key && monitor.jobId === outcome.jobId
22747
+ );
22748
+ if (!settled) {
22749
+ throw new Error(`Monitor job ${outcome.jobId} returned no result.`);
22750
+ }
22751
+ monitorOutcomes[index] = { ...outcome, ...settled };
22752
+ }
22753
+ }
22754
+ if (monitorOutcomes.some(
22755
+ (outcome) => outcome.status === "failed" || outcome.status === "planned"
22756
+ )) {
22757
+ return await failWithCheck({
22758
+ title: "Monitor deployment failed",
22759
+ summary: monitorDeploymentSummary(monitorOutcomes),
22760
+ error: "Some monitor changes failed. Applied changes remain live; inspect the reported jobs before retrying.",
22761
+ outcomes
22762
+ });
22763
+ }
22764
+ const superseded = await supersedeIfHeadMoved();
22765
+ if (superseded) return { ...superseded, ...monitorRunResult() };
22766
+ }
22214
22767
  if (toPromote.length > 0) {
22215
22768
  try {
22216
22769
  const promotion = await client2.promote(toPromote);
@@ -22268,12 +22821,15 @@ async function runDeployment(params, hooks) {
22268
22821
  }
22269
22822
  const checkRun = await postCheckOrNull({
22270
22823
  conclusion: "success",
22271
- title: `Deployed ${outcomes.filter((o) => o.status === "promoted").length} play(s) (${outcomes.filter((o) => o.status === "unchanged").length} unchanged)`,
22824
+ title: `Deployed ${outcomes.filter((o) => o.status === "promoted").length} play(s) (${outcomes.filter((o) => o.status === "unchanged").length} unchanged)${monitorEntries !== void 0 ? `; ${monitorOutcomes.filter((outcome) => outcome.status === "applied").length} monitor(s) applied` : ""}`,
22272
22825
  ...annotations.length > 0 ? { annotations } : {},
22273
- summary: outcomes.map(
22274
- (outcome) => `- \`${outcome.name}\`: ${outcome.status}${outcome.sdkUpdated ? " \u2014 SDK updated" : ""}${outcome.warning ? `
22826
+ summary: [
22827
+ outcomes.map(
22828
+ (outcome) => `- \`${outcome.name}\`: ${outcome.status}${outcome.sdkUpdated ? " \u2014 SDK updated" : ""}${outcome.warning ? `
22275
22829
  - :warning: ${outcome.warning}` : ""}`
22276
- ).join("\n")
22830
+ ).join("\n"),
22831
+ monitorDeploymentSummary(monitorOutcomes)
22832
+ ].filter(Boolean).join("\n")
22277
22833
  });
22278
22834
  return await finishSucceeded(outcomes, checkRun);
22279
22835
  } catch (error) {
@@ -22319,6 +22875,7 @@ async function runDeployment(params, hooks) {
22319
22875
  await setStatus({
22320
22876
  status: "failed",
22321
22877
  error: message.slice(0, 2e3),
22878
+ ...monitorOutcomes.length > 0 ? { results: monitorResults() } : {},
22322
22879
  buildSeconds: buildSeconds(),
22323
22880
  ...checkRunId ? { checkRunId } : {}
22324
22881
  }).catch(() => void 0);
@@ -22400,7 +22957,7 @@ async function handlePlaysDeploy(directory, options) {
22400
22957
  ...options.commit ? { commit: options.commit } : {}
22401
22958
  });
22402
22959
  const { bundleDeployPlayFile } = await loadPlayBundler();
22403
- const workRoot = await mkdtemp2(join12(tmpdir4(), "deepline-deploy-"));
22960
+ const workRoot = await mkdtemp2(join13(tmpdir4(), "deepline-deploy-"));
22404
22961
  const consoleInfo = console.info;
22405
22962
  console.info = console.error;
22406
22963
  try {
@@ -22418,6 +22975,7 @@ async function handlePlaysDeploy(directory, options) {
22418
22975
  },
22419
22976
  {
22420
22977
  bundle: bundleDeployPlayFile,
22978
+ fetchImpl: fetchWithDeploymentProtection,
22421
22979
  // The plays are already here: "opening" the source is naming it.
22422
22980
  openSource: async () => ({
22423
22981
  open: async () => ({ repoRoot: root })
@@ -22801,10 +23359,22 @@ function renderDeploymentPlayLines(results) {
22801
23359
  ];
22802
23360
  });
22803
23361
  }
23362
+ function renderDeploymentMonitorLines(results) {
23363
+ const monitors = results?.monitors;
23364
+ if (!Array.isArray(monitors)) return [];
23365
+ return monitors.flatMap((monitor) => [
23366
+ `${monitor.key ?? "?"}${monitor.file ? ` (${monitor.file})` : ""} - ${monitor.status ?? "?"}`,
23367
+ ...monitor.jobId ? [` job: ${monitor.jobId}`] : [],
23368
+ ...monitor.credits != null ? [` Deepline credits: ${monitor.credits}`] : [],
23369
+ ...monitor.error ? [` error: ${monitor.error}`] : [],
23370
+ ...monitor.warning ? [` warning: ${monitor.warning}`] : []
23371
+ ]);
23372
+ }
22804
23373
  async function handleDeploymentGet(id, options) {
22805
23374
  const { http } = getAuthedHttpClient();
22806
23375
  const payload = await http.get(`/api/v2/deployments/${encodeURIComponent(id)}`);
22807
23376
  const playLines = renderDeploymentPlayLines(payload.deployment.results);
23377
+ const monitorLines = renderDeploymentMonitorLines(payload.deployment.results);
22808
23378
  const repository = payload.project?.repoFullName ?? payload.deployment.repoFullName;
22809
23379
  printCommandEnvelope(
22810
23380
  {
@@ -22816,7 +23386,8 @@ async function handleDeploymentGet(id, options) {
22816
23386
  title: `deployment ${payload.deployment.id}${repository ? ` (${repository})` : ""}`,
22817
23387
  lines: [renderDeployment(payload.deployment)]
22818
23388
  },
22819
- ...playLines.length ? [{ title: "plays", lines: playLines }] : []
23389
+ ...playLines.length ? [{ title: "plays", lines: playLines }] : [],
23390
+ ...monitorLines.length ? [{ title: "monitors", lines: monitorLines }] : []
22820
23391
  ]
22821
23392
  }
22822
23393
  },
@@ -23022,7 +23593,7 @@ async function pathExistsIncludingSymlink(path) {
23022
23593
  }
23023
23594
  }
23024
23595
  function runIdFileTempPath(destination) {
23025
- return join13(
23596
+ return join14(
23026
23597
  dirname10(destination),
23027
23598
  `.${basename3(destination)}.${process.pid}.${randomUUID4()}.tmp`
23028
23599
  );
@@ -23129,7 +23700,7 @@ async function writePlayRunIdFile(destination, runId, options = {}) {
23129
23700
  await removeRunIdTempFile(tempPath);
23130
23701
  }
23131
23702
  }
23132
- function traceCliSync(phase, fields, run) {
23703
+ function traceCliSync(phase, fields2, run) {
23133
23704
  const startedAt = Date.now();
23134
23705
  try {
23135
23706
  const result = run();
@@ -23137,7 +23708,7 @@ function traceCliSync(phase, fields, run) {
23137
23708
  phase,
23138
23709
  ms: Date.now() - startedAt,
23139
23710
  ok: true,
23140
- ...fields
23711
+ ...fields2
23141
23712
  });
23142
23713
  return result;
23143
23714
  } catch (error) {
@@ -23146,7 +23717,7 @@ function traceCliSync(phase, fields, run) {
23146
23717
  ms: Date.now() - startedAt,
23147
23718
  ok: false,
23148
23719
  error: error instanceof Error ? error.message : String(error),
23149
- ...fields
23720
+ ...fields2
23150
23721
  });
23151
23722
  throw error;
23152
23723
  }
@@ -24470,7 +25041,8 @@ function formatProgressCounts(input2) {
24470
25041
  Math.min(100, Math.round(completed / total * 100))
24471
25042
  );
24472
25043
  const failed = typeof input2.failed === "number" && Number.isFinite(input2.failed) && input2.failed > 0 ? `, failed ${formatInteger(input2.failed)}` : "";
24473
- return `${formatInteger(completed)}/${formatInteger(total)} (${percent}%)${failed}`;
25044
+ const completedLabel = typeof input2.failed === "number" ? "successful " : "";
25045
+ return `${completedLabel}${formatInteger(completed)}/${formatInteger(total)} (${percent}%)${failed}`;
24474
25046
  }
24475
25047
  function formatProgressMessageSuffix(input2) {
24476
25048
  const message = typeof input2.message === "string" ? input2.message.trim() : "";
@@ -25356,8 +25928,8 @@ function formatPlayLogLine(rawLine, status, state) {
25356
25928
  if (!logLevelReaches("info", state.logLevel ?? "info")) {
25357
25929
  return null;
25358
25930
  }
25359
- const [, rows, fields, namespace, cached, pending] = mapStart;
25360
- return `${prefix}map ${sourceLabelForNamespace(namespace)}: ${formatInteger(Number(rows))} rows, ${fields} fields, ${formatInteger(Number(cached))} cached, ${formatInteger(Number(pending))} pending`;
25931
+ const [, rows, fields2, namespace, cached, pending] = mapStart;
25932
+ return `${prefix}map ${sourceLabelForNamespace(namespace)}: ${formatInteger(Number(rows))} rows, ${fields2} fields, ${formatInteger(Number(cached))} cached, ${formatInteger(Number(pending))} pending`;
25361
25933
  }
25362
25934
  const mapDone = message.match(
25363
25935
  /^Map completed: (\d+) results \((\d+) executed, (\d+) already satisfied\)$/
@@ -26411,6 +26983,54 @@ function buildRunActivityTextLines(run) {
26411
26983
  if (observedAt) lines.push(` observed: ${observedAt}`);
26412
26984
  return lines;
26413
26985
  }
26986
+ function formatObservedRunCounter(value) {
26987
+ const counter = readRecord(value);
26988
+ const count = counter?.value;
26989
+ if (typeof count !== "number" || !Number.isSafeInteger(count) || count < 0) {
26990
+ return "unknown";
26991
+ }
26992
+ return counter?.confirmed === true ? formatInteger(count) : `${formatInteger(count)} observed`;
26993
+ }
26994
+ function buildRunStatusEvidenceTextLines(packaged) {
26995
+ const evidence = readRecord(packaged.runStatus);
26996
+ if (!evidence || evidence.available !== true) return [];
26997
+ const calls = readRecord(evidence.calls);
26998
+ const lines = [];
26999
+ if (calls) {
27000
+ lines.push(
27001
+ ` calls: ${formatObservedRunCounter(calls.logicalCalls)} logical, ${formatObservedRunCounter(calls.toolDispatches)} tool dispatches, ${formatObservedRunCounter(calls.provider429s)} provider 429s`
27002
+ );
27003
+ }
27004
+ const source = readRecord(evidence.source);
27005
+ if (source?.aligned === false) {
27006
+ lines.push(
27007
+ ` consistency: run snapshot event ${String(source.runSnapshotLedgerNextSeq)} and progress event ${String(source.ledgerNextSeq)} differ; retry this read to align them`
27008
+ );
27009
+ }
27010
+ const focus = readRecord(evidence.focusStep);
27011
+ const rows = readRecord(focus?.rows);
27012
+ if (focus) {
27013
+ const id = typeof focus.id === "string" && focus.id.trim() ? focus.id.trim() : "unknown step";
27014
+ const label = typeof focus.label === "string" && focus.label.trim() ? ` (${focus.label.trim()})` : "";
27015
+ const state = typeof focus.status === "string" && focus.status.trim() ? `: ${focus.status.trim()}` : "";
27016
+ const rowCounts = rows ? `; rows ${formatObservedRunCounter({ value: rows.succeeded, confirmed: true })} succeeded, ${formatObservedRunCounter({ value: rows.failed, confirmed: true })} failed, ${formatObservedRunCounter({ value: rows.total, confirmed: true })} total` : "";
27017
+ lines.push(` current step: ${id}${label}${state}${rowCounts}`);
27018
+ }
27019
+ return lines;
27020
+ }
27021
+ function buildRecentRunLogTextLines(packaged) {
27022
+ const logs = readRecord(packaged.logs);
27023
+ const tail = Array.isArray(logs?.tail) ? logs.tail.filter((line) => typeof line === "string") : [];
27024
+ if (tail.length === 0) return [];
27025
+ const visible = tail.slice(-5);
27026
+ const total = typeof logs?.totalCount === "number" && Number.isFinite(logs.totalCount) ? ` of ${formatInteger(logs.totalCount)}` : "";
27027
+ const lines = [` recent logs: showing ${visible.length}${total}`];
27028
+ lines.push(...visible.map((line) => ` ${line}`));
27029
+ if (logs?.truncated === true) {
27030
+ lines.push(" older log lines were truncated by the retention cap");
27031
+ }
27032
+ return lines;
27033
+ }
26414
27034
  function buildRunPackageTextLines(packaged) {
26415
27035
  const run = readRunPackageRun(packaged);
26416
27036
  const runId = typeof run.id === "string" ? run.id : "unknown";
@@ -26480,6 +27100,8 @@ function buildRunPackageTextLines(packaged) {
26480
27100
  if (!isRuntimeLimitCheckpoint) {
26481
27101
  lines.push(...buildRunActivityTextLines(run));
26482
27102
  }
27103
+ lines.push(...buildRunStatusEvidenceTextLines(packaged));
27104
+ lines.push(...buildRecentRunLogTextLines(packaged));
26483
27105
  lines.push(...formatPackageValueOutputLines(packaged));
26484
27106
  lines.push(
26485
27107
  ...formatPackageDatasetActionLines(packaged, {
@@ -26487,12 +27109,7 @@ function buildRunPackageTextLines(packaged) {
26487
27109
  })
26488
27110
  );
26489
27111
  const next = packaged.next && typeof packaged.next === "object" && !Array.isArray(packaged.next) ? packaged.next : {};
26490
- const billingCommand = actionToCommand(next.billing);
26491
27112
  const logsCommand = actionToCommand(next.logs);
26492
- if (billingCommand) {
26493
- const costState = status === "completed" || status === "failed" || status === "cancelled" ? "settles asynchronously \u2014 run the billing command below for totals" : "pending";
26494
- lines.push(` cost: ${costState}`);
26495
- }
26496
27113
  for (const step of isRuntimeLimitCheckpoint ? [] : readRecordArray(packaged.steps).slice(0, 8)) {
26497
27114
  const id = typeof step.id === "string" ? step.id : "step";
26498
27115
  const kind = typeof step.kind === "string" ? step.kind : "step";
@@ -26522,7 +27139,6 @@ function buildRunPackageTextLines(packaged) {
26522
27139
  ` ${isRuntimeTimeout ? "full run details" : "full result"}: ${fullResultCommand}`
26523
27140
  );
26524
27141
  if (logsCommand) lines.push(` logs: ${logsCommand}`);
26525
- if (billingCommand) lines.push(` billing: ${billingCommand}`);
26526
27142
  if (legacyExportCommand) {
26527
27143
  lines.push(` export CSV: ${legacyExportCommand}`);
26528
27144
  }
@@ -28873,7 +29489,7 @@ async function handlePlayRun(args, hooks) {
28873
29489
  if (siblings.length > 0) {
28874
29490
  console.error(`Did you mean one of these?`);
28875
29491
  for (const s of siblings.slice(0, 5)) {
28876
- console.error(` ${join13(dir, s)}`);
29492
+ console.error(` ${join14(dir, s)}`);
28877
29493
  }
28878
29494
  }
28879
29495
  } catch {
@@ -30117,8 +30733,8 @@ function printPlayDescription(play) {
30117
30733
  }
30118
30734
  }
30119
30735
  function inputFieldNames(schema) {
30120
- const fields = Array.isArray(schema?.fields) ? schema.fields : [];
30121
- return fields.map(
30736
+ const fields2 = Array.isArray(schema?.fields) ? schema.fields : [];
30737
+ return fields2.map(
30122
30738
  (field) => field && typeof field === "object" ? String(field.name ?? "").trim() : ""
30123
30739
  ).filter(Boolean);
30124
30740
  }
@@ -30135,9 +30751,9 @@ function printCompactPlaySearchResult(play) {
30135
30751
  if (aliases) {
30136
30752
  console.log(` Aliases: ${aliases}`);
30137
30753
  }
30138
- const fields = inputFieldNames(play.inputSchema);
30139
- if (fields.length > 0) {
30140
- console.log(` Inputs: ${fields.join(", ")}`);
30754
+ const fields2 = inputFieldNames(play.inputSchema);
30755
+ if (fields2.length > 0) {
30756
+ console.log(` Inputs: ${fields2.join(", ")}`);
30141
30757
  } else if (play.inputSchema) {
30142
30758
  console.log(" Inputs: see describe");
30143
30759
  }
@@ -30146,14 +30762,14 @@ function printCompactPlaySearchResult(play) {
30146
30762
  }
30147
30763
  function compactPlaySchema(schema) {
30148
30764
  if (!schema) return null;
30149
- const fields = Array.isArray(schema.fields) ? schema.fields.map(
30765
+ const fields2 = Array.isArray(schema.fields) ? schema.fields.map(
30150
30766
  (field) => field && typeof field === "object" ? {
30151
30767
  name: String(field.name ?? ""),
30152
30768
  type: field.type ?? void 0,
30153
30769
  required: field.required ?? void 0
30154
30770
  } : null
30155
30771
  ).filter((field) => Boolean(field?.name)) : [];
30156
- return fields.length > 0 ? { fields } : schema;
30772
+ return fields2.length > 0 ? { fields: fields2 } : schema;
30157
30773
  }
30158
30774
  function summarizePlayGrepResult(play) {
30159
30775
  const reference = formatPlayListReference(play);
@@ -30782,6 +31398,8 @@ Concepts:
30782
31398
  Installed npm and repo-local CLIs can run saved/prebuilt plays by name or
30783
31399
  bundle local .play.ts files for development workflows.
30784
31400
  Running a local file does not make it live; use publish or set-live for that.
31401
+ plays settings organizes a Play independently of code revisions.
31402
+ New Plays start at person; publishing moves them to team, preserving folders.
30785
31403
 
30786
31404
  Authoring:
30787
31405
  Use normal TypeScript interpolation for human-facing strings:
@@ -30987,6 +31605,7 @@ Pass-through input flags:
30987
31605
  process.exitCode = exitCode;
30988
31606
  });
30989
31607
  registerPlayBootstrapCommand(play);
31608
+ registerPlaySettingsCommands(play);
30990
31609
  play.command("get <target>").description(
30991
31610
  "Fetch full play details or materialize a saved source bundle."
30992
31611
  ).addHelpText(
@@ -31255,6 +31874,8 @@ Notes:
31255
31874
  plays check to refuse publishing bytes that changed after validation.
31256
31875
  --dry-run bundles only and prints the exact artifact that would be published.
31257
31876
  Running a local file with plays run does not publish it.
31877
+ Publishing moves personal locations into Team library, preserving folders.
31878
+ Change location with: deepline plays settings set --play <play> --name path --value team/Research
31258
31879
 
31259
31880
  Examples:
31260
31881
  deepline plays set-live my-play --latest --json
@@ -31398,7 +32019,10 @@ Examples:
31398
32019
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
31399
32020
  `
31400
32021
  );
31401
- runs.command("status <runId>").description("Read bounded lifecycle and confirmed work counts for a run.").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (runId, options) => {
32022
+ registerRunHistoryCommand(runs);
32023
+ runs.command("status <runId>").description(
32024
+ "Legacy scalar-only read. Use runs get for canonical status, progress, logs, and results."
32025
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (runId, options) => {
31402
32026
  process.exitCode = await handleRunLifecycleStatus([
31403
32027
  runId,
31404
32028
  ...options.json ? ["--json"] : []
@@ -33582,7 +34206,7 @@ function expandAtFilePath(rawPath) {
33582
34206
  return homedir6();
33583
34207
  }
33584
34208
  if (expanded.startsWith("~/") || expanded.startsWith("~\\")) {
33585
- return join14(homedir6(), expanded.slice(2));
34209
+ return join15(homedir6(), expanded.slice(2));
33586
34210
  }
33587
34211
  return expanded;
33588
34212
  }
@@ -33595,7 +34219,7 @@ async function readAtFileReference(value, argumentName, strip = true) {
33595
34219
  throw new Error(`Invalid ${argumentName} value: empty @file path.`);
33596
34220
  }
33597
34221
  try {
33598
- const text = await readFile4(filePath, "utf8");
34222
+ const text = await readFile5(filePath, "utf8");
33599
34223
  const normalized = text.replace(/^\uFEFF/, "");
33600
34224
  return strip ? normalized.trim() : normalized;
33601
34225
  } catch (error) {
@@ -33946,7 +34570,7 @@ async function regularFileExists(path) {
33946
34570
  }
33947
34571
  }
33948
34572
  async function readConfig(path) {
33949
- const source = await readFile4(resolve13(path), "utf8");
34573
+ const source = await readFile5(resolve13(path), "utf8");
33950
34574
  let parsed;
33951
34575
  try {
33952
34576
  parsed = JSON.parse(source);
@@ -35004,9 +35628,9 @@ function readEnrichRunStatus(status) {
35004
35628
  return null;
35005
35629
  }
35006
35630
  function firstCollectedStringField(value, key) {
35007
- const fields = /* @__PURE__ */ new Set();
35008
- collectStringFields(value, key, fields);
35009
- return fields.values().next().value ?? null;
35631
+ const fields2 = /* @__PURE__ */ new Set();
35632
+ collectStringFields(value, key, fields2);
35633
+ return fields2.values().next().value ?? null;
35010
35634
  }
35011
35635
  function emitPlainRunFailure(status) {
35012
35636
  const runId = extractRunId(status) ?? firstCollectedStringField(status, "runId");
@@ -35964,7 +36588,7 @@ function sidecarEnrichRowsExportPath(outputPath) {
35964
36588
  const resolved = resolve13(outputPath);
35965
36589
  const ext = extname3(resolved) || ".csv";
35966
36590
  const stem = basename4(resolved, ext);
35967
- return join14(dirname11(resolved), `${stem}.deepline-enrich-rows${ext}`);
36591
+ return join15(dirname11(resolved), `${stem}.deepline-enrich-rows${ext}`);
35968
36592
  }
35969
36593
  function collectDatasetFollowUpCommands(value, state) {
35970
36594
  if (state.depth > 12 || !value || typeof value !== "object" || state.commands.length >= 8) {
@@ -36045,10 +36669,10 @@ async function persistEnrichFailureReport(input2) {
36045
36669
  if (input2.jobs.length === 0 && input2.issues.length === 0) {
36046
36670
  return null;
36047
36671
  }
36048
- const stateDir = join14(homedir6(), ".local", "deepline", "runtime", "state");
36672
+ const stateDir = join15(homedir6(), ".local", "deepline", "runtime", "state");
36049
36673
  const reportPrefix = input2.jobs.length > 0 ? "run-block-failures" : "enrich-issues";
36050
36674
  await mkdir5(stateDir, { recursive: true });
36051
- const reportPath = join14(
36675
+ const reportPath = join15(
36052
36676
  stateDir,
36053
36677
  `${reportPrefix}-${Math.floor(Date.now() / 1e3)}-${process.pid}.json`
36054
36678
  );
@@ -36977,9 +37601,9 @@ function registerEnrichCommand(program) {
36977
37601
  sdkEnrichTelemetryCompleted = true;
36978
37602
  await completeSdkEnrichTelemetry(sdkEnrichTelemetry, input2);
36979
37603
  };
36980
- const tempDir = await mkdtemp3(join14(tmpdir5(), "deepline-enrich-play-"));
37604
+ const tempDir = await mkdtemp3(join15(tmpdir5(), "deepline-enrich-play-"));
36981
37605
  await emitSdkEnrichTelemetry(sdkEnrichTelemetry, "enrich_started");
36982
- const tempPlay = join14(tempDir, "deepline-enrich.play.ts");
37606
+ const tempPlay = join15(tempDir, "deepline-enrich.play.ts");
36983
37607
  let inPlaceTempDir = null;
36984
37608
  let inPlaceTempOutputPath = null;
36985
37609
  const inPlaceFinalOutputPath = options.inPlace ? resolve13(inputCsv) : null;
@@ -37007,12 +37631,12 @@ function registerEnrichCommand(program) {
37007
37631
  await rm3(inPlaceTempDir, { recursive: true, force: true });
37008
37632
  }
37009
37633
  inPlaceTempDir = await mkdtemp3(
37010
- join14(
37634
+ join15(
37011
37635
  dirname11(inPlaceCommitOutputPath ?? resolve13(inputCsv)),
37012
37636
  ".deepline-enrich-in-place-"
37013
37637
  )
37014
37638
  );
37015
- inPlaceTempOutputPath = join14(inPlaceTempDir, "output.csv");
37639
+ inPlaceTempOutputPath = join15(inPlaceTempDir, "output.csv");
37016
37640
  await copyFile(resolve13(inputCsv), inPlaceTempOutputPath);
37017
37641
  outputPath = inPlaceTempOutputPath;
37018
37642
  };
@@ -37279,7 +37903,7 @@ async function handleFeedback(text, options) {
37279
37903
  { json: options.json }
37280
37904
  );
37281
37905
  }
37282
- function resolveFeedbackText(text, file, readFile7 = (path) => readFileSync10(path, "utf8")) {
37906
+ function resolveFeedbackText(text, file, readFile8 = (path) => readFileSync10(path, "utf8")) {
37283
37907
  if (text !== void 0 && file !== void 0) {
37284
37908
  throw new Error(
37285
37909
  "Pass feedback text positionally or with --file, not both."
@@ -37288,7 +37912,7 @@ function resolveFeedbackText(text, file, readFile7 = (path) => readFileSync10(pa
37288
37912
  let value;
37289
37913
  if (file !== void 0) {
37290
37914
  try {
37291
- value = readFile7(file === "-" ? 0 : file);
37915
+ value = readFile8(file === "-" ? 0 : file);
37292
37916
  } catch (error) {
37293
37917
  throw new Error(
37294
37918
  `Could not read feedback ${file === "-" ? "from stdin" : `file ${file}`}: ${error instanceof Error ? error.message : String(error)}`
@@ -37297,7 +37921,7 @@ function resolveFeedbackText(text, file, readFile7 = (path) => readFileSync10(pa
37297
37921
  } else if (text !== void 0) {
37298
37922
  value = text;
37299
37923
  } else if (!process.stdin.isTTY) {
37300
- value = readFile7(0);
37924
+ value = readFile8(0);
37301
37925
  } else {
37302
37926
  throw new Error(
37303
37927
  "Feedback text is required. Pass it positionally, use --file <path>, or pipe stdin."
@@ -37356,7 +37980,7 @@ import {
37356
37980
  writeFileSync as writeFileSync11
37357
37981
  } from "fs";
37358
37982
  import { homedir as homedir7, platform } from "os";
37359
- import { basename as basename5, dirname as dirname12, join as join15, resolve as resolve14 } from "path";
37983
+ import { basename as basename5, dirname as dirname12, join as join16, resolve as resolve14 } from "path";
37360
37984
  import { gzipSync } from "zlib";
37361
37985
  import { randomUUID as randomUUID5 } from "crypto";
37362
37986
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -37382,10 +38006,10 @@ function detectShellContext() {
37382
38006
  };
37383
38007
  }
37384
38008
  function claudeProjectsRoot() {
37385
- return join15(homeDir(), ".claude", "projects");
38009
+ return join16(homeDir(), ".claude", "projects");
37386
38010
  }
37387
38011
  function codexSessionsRoot() {
37388
- return join15(homeDir(), ".codex", "sessions");
38012
+ return join16(homeDir(), ".codex", "sessions");
37389
38013
  }
37390
38014
  function listClaudeSessionFiles() {
37391
38015
  const root = claudeProjectsRoot();
@@ -37393,10 +38017,10 @@ function listClaudeSessionFiles() {
37393
38017
  const projectDirs = readDirectoryNames(root);
37394
38018
  const files = [];
37395
38019
  for (const projectDir of projectDirs) {
37396
- const fullProjectDir = join15(root, projectDir);
38020
+ const fullProjectDir = join16(root, projectDir);
37397
38021
  for (const fileName of readDirectoryNames(fullProjectDir)) {
37398
38022
  if (fileName.endsWith(".jsonl")) {
37399
- const filePath = join15(fullProjectDir, fileName);
38023
+ const filePath = join16(fullProjectDir, fileName);
37400
38024
  const sessionId = sessionIdFromClaudeFilePath(filePath);
37401
38025
  const stat5 = statIfReadable(filePath);
37402
38026
  if (sessionId && stat5) {
@@ -37453,7 +38077,7 @@ function listJsonlFilesRecursive(root, maxDepth) {
37453
38077
  return;
37454
38078
  }
37455
38079
  for (const entry of entries) {
37456
- const fullPath = join15(dir, entry.name);
38080
+ const fullPath = join16(dir, entry.name);
37457
38081
  if (entry.isDirectory()) {
37458
38082
  visit(fullPath, depth + 1);
37459
38083
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -37892,8 +38516,8 @@ function loadViewerAssets() {
37892
38516
  const cliEntry = process.argv[1]?.trim() ? realpathSync3(resolve14(process.argv[1])) : null;
37893
38517
  const candidateRoots2 = [
37894
38518
  ...cliEntry ? [
37895
- join15(dirname12(dirname12(cliEntry)), "viewer"),
37896
- join15(
38519
+ join16(dirname12(dirname12(cliEntry)), "viewer"),
38520
+ join16(
37897
38521
  dirname12(dirname12(dirname12(cliEntry))),
37898
38522
  "src",
37899
38523
  "lib",
@@ -37901,12 +38525,12 @@ function loadViewerAssets() {
37901
38525
  "viewer"
37902
38526
  )
37903
38527
  ] : [],
37904
- join15(process.cwd(), "packages", "sdk", "assets", "viewer")
38528
+ join16(process.cwd(), "packages", "sdk", "assets", "viewer")
37905
38529
  ];
37906
38530
  for (const root of candidateRoots2) {
37907
38531
  try {
37908
- const cssPath = join15(root, "viewer.css");
37909
- const jsPath = join15(root, "viewer.js");
38532
+ const cssPath = join16(root, "viewer.css");
38533
+ const jsPath = join16(root, "viewer.js");
37910
38534
  if (!existsSync10(cssPath) || !existsSync10(jsPath)) continue;
37911
38535
  return {
37912
38536
  css: readFileSync11(cssPath, "utf8"),
@@ -37938,9 +38562,9 @@ async function handleSessionsRender(options) {
37938
38562
  });
37939
38563
  let outputPath = options.output ? resolve14(options.output) : "";
37940
38564
  if (!outputPath) {
37941
- const outputDir = join15(process.cwd(), "deepline", "data");
38565
+ const outputDir = join16(process.cwd(), "deepline", "data");
37942
38566
  mkdirSync8(outputDir, { recursive: true });
37943
- outputPath = join15(
38567
+ outputPath = join16(
37944
38568
  outputDir,
37945
38569
  targets.length > 1 ? "session-viewer.html" : `session-${targets[0]?.sessionId}.html`
37946
38570
  );
@@ -39052,7 +39676,7 @@ function parseJsonObjectArg(raw, argLabel) {
39052
39676
  return parsed;
39053
39677
  }
39054
39678
  function resolveMonitorJsonBody(input2) {
39055
- const readFile7 = input2.readFile ?? ((path) => readFileSync12(path, "utf-8"));
39679
+ const readFile8 = input2.readFile ?? ((path) => readFileSync12(path, "utf-8"));
39056
39680
  const readStdin = input2.readStdin ?? (() => readFileSync12(0, "utf-8"));
39057
39681
  if (input2.positional !== void 0 && input2.file !== void 0) {
39058
39682
  throw new MonitorsUsageError(
@@ -39068,7 +39692,7 @@ function resolveMonitorJsonBody(input2) {
39068
39692
  }
39069
39693
  let raw;
39070
39694
  try {
39071
- raw = readFile7(input2.file);
39695
+ raw = readFile8(input2.file);
39072
39696
  } catch (error) {
39073
39697
  throw new MonitorsUsageError(
39074
39698
  `Could not read --file ${input2.file}: ${error instanceof Error ? error.message : String(error)}`
@@ -42138,10 +42762,10 @@ import {
42138
42762
  unlinkSync,
42139
42763
  writeFileSync as writeFileSync13
42140
42764
  } from "fs";
42141
- import { join as join16 } from "path";
42765
+ import { join as join17 } from "path";
42142
42766
  function pendingOrgCreatePath(baseUrl, accountId, sourceOrgId, name) {
42143
42767
  const intent = createHash5("sha256").update(accountId).update("\0").update(sourceOrgId).update("\0").update(name).digest("hex");
42144
- return join16(sdkCliStateDirPath(baseUrl), `pending-org-create-${intent}.json`);
42768
+ return join17(sdkCliStateDirPath(baseUrl), `pending-org-create-${intent}.json`);
42145
42769
  }
42146
42770
  function readPendingOrgCreate(path, accountId, sourceOrgId, name) {
42147
42771
  let value;
@@ -43024,7 +43648,7 @@ Deprecated:
43024
43648
 
43025
43649
  // src/cli/commands/secrets.ts
43026
43650
  import { stdin as input, stdout as output } from "process";
43027
- import { readFile as readFile5 } from "fs/promises";
43651
+ import { readFile as readFile6 } from "fs/promises";
43028
43652
  var hiddenInputBuffer = "";
43029
43653
  function normalizeSecretName(value) {
43030
43654
  const normalized = value.trim().toUpperCase();
@@ -43197,7 +43821,7 @@ async function readSecretValueFromOptions(options) {
43197
43821
  }
43198
43822
  value = envValue;
43199
43823
  } else {
43200
- value = trimOneTerminalNewline(await readFile5(options.fromFile, "utf8"));
43824
+ value = trimOneTerminalNewline(await readFile6(options.fromFile, "utf8"));
43201
43825
  }
43202
43826
  if (!value) throw new Error("Secret value is required.");
43203
43827
  return value;
@@ -43408,7 +44032,7 @@ import {
43408
44032
  writeFileSync as writeFileSync16
43409
44033
  } from "fs";
43410
44034
  import { homedir as homedir10 } from "os";
43411
- import { dirname as dirname16, join as join20, resolve as resolve17 } from "path";
44035
+ import { dirname as dirname16, join as join21, resolve as resolve17 } from "path";
43412
44036
 
43413
44037
  // src/cli/installation-lifecycle.ts
43414
44038
  import {
@@ -43418,7 +44042,7 @@ import {
43418
44042
  realpathSync as realpathSync4,
43419
44043
  rmSync as rmSync4
43420
44044
  } from "fs";
43421
- import { basename as basename6, dirname as dirname13, join as join17, relative as relative6, resolve as resolve16 } from "path";
44045
+ import { basename as basename6, dirname as dirname13, join as join18, relative as relative6, resolve as resolve16 } from "path";
43422
44046
  var nodeFileSystem = {
43423
44047
  exists: existsSync12,
43424
44048
  isSymbolicLink(path) {
@@ -43474,25 +44098,25 @@ var CliInstallation = class _CliInstallation {
43474
44098
  });
43475
44099
  }
43476
44100
  static isNpmPackagePath(path) {
43477
- return path?.includes(`${join17("node_modules", "deepline")}`) ?? false;
44101
+ return path?.includes(`${join18("node_modules", "deepline")}`) ?? false;
43478
44102
  }
43479
44103
  launcher(path) {
43480
44104
  return inspectLauncher(path, this.input.fileSystem);
43481
44105
  }
43482
44106
  retiredArtifacts() {
43483
- const hostDir = join17(
44107
+ const hostDir = join18(
43484
44108
  this.input.home,
43485
44109
  ".local",
43486
44110
  "deepline",
43487
44111
  this.input.baseUrlSlug
43488
44112
  );
43489
- const legacyLauncherPath = join17(
44113
+ const legacyLauncherPath = join18(
43490
44114
  this.input.home,
43491
44115
  ".local",
43492
44116
  "bin",
43493
44117
  "deepline"
43494
44118
  );
43495
- const installerCommandPath = this.input.fileSystem.read(join17(hostDir, "sdk", ".command-path")).trim();
44119
+ const installerCommandPath = this.input.fileSystem.read(join18(hostDir, "sdk", ".command-path")).trim();
43496
44120
  const ownedInstallerCommand = isOwnedInstallerCommandPath({
43497
44121
  hostDir,
43498
44122
  commandPath: installerCommandPath
@@ -43500,16 +44124,16 @@ var CliInstallation = class _CliInstallation {
43500
44124
  const legacyLauncher = this.launcher(legacyLauncherPath);
43501
44125
  const candidates = [
43502
44126
  ...legacyLauncher.ownership === "installer_legacy" ? [legacyLauncherPath] : [],
43503
- join17(this.input.home, ".local", "bin", "deepline-real"),
43504
- join17(hostDir, "bin", "deepline"),
43505
- join17(hostDir, "bin", "deepline-real"),
43506
- join17(hostDir, "cli", ".install-method"),
43507
- join17(hostDir, "cli", ".version"),
43508
- join17(hostDir, "sdk", ".install-method"),
43509
- join17(hostDir, "sdk", ".command-path"),
44127
+ join18(this.input.home, ".local", "bin", "deepline-real"),
44128
+ join18(hostDir, "bin", "deepline"),
44129
+ join18(hostDir, "bin", "deepline-real"),
44130
+ join18(hostDir, "cli", ".install-method"),
44131
+ join18(hostDir, "cli", ".version"),
44132
+ join18(hostDir, "sdk", ".install-method"),
44133
+ join18(hostDir, "sdk", ".command-path"),
43510
44134
  ...ownedInstallerCommand ? [
43511
44135
  installerCommandPath,
43512
- join17(dirname13(installerCommandPath), "deepline-sdk")
44136
+ join18(dirname13(installerCommandPath), "deepline-sdk")
43513
44137
  ] : []
43514
44138
  ];
43515
44139
  return {
@@ -43542,7 +44166,7 @@ function isOwnedInstallerCommandPath(input2) {
43542
44166
  import { spawn as spawn3 } from "child_process";
43543
44167
  import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
43544
44168
  import { homedir as homedir9 } from "os";
43545
- import { dirname as dirname15, join as join19 } from "path";
44169
+ import { dirname as dirname15, join as join20 } from "path";
43546
44170
 
43547
44171
  // contracts/install-commands.json
43548
44172
  var install_commands_default = {
@@ -43669,7 +44293,7 @@ import {
43669
44293
  unlinkSync as unlinkSync2,
43670
44294
  writeFileSync as writeFileSync14
43671
44295
  } from "fs";
43672
- import { dirname as dirname14, join as join18 } from "path";
44296
+ import { dirname as dirname14, join as join19 } from "path";
43673
44297
 
43674
44298
  // src/cli/windows-arg-escape.ts
43675
44299
  var CMD_META_CHARS = /([()\][%!^"`<>&|;, *?])/g;
@@ -44034,7 +44658,7 @@ function shouldSkipSkillsSync() {
44034
44658
  return value === "1" || value === "true" || value === "yes" || value === "on";
44035
44659
  }
44036
44660
  function unavailableSkillsNoticePath(baseUrl) {
44037
- return join18(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
44661
+ return join19(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
44038
44662
  }
44039
44663
  var SKILLS_SYNC_IN_PROGRESS_TTL_MS = 10 * 60 * 1e3;
44040
44664
  var SKILLS_SYNC_IN_PROGRESS_PID_CAP_MS = 6 * 60 * 60 * 1e3;
@@ -44044,21 +44668,21 @@ function sortedLeaseAgents(agents) {
44044
44668
  return [...new Set(expanded)].sort((a, b) => a.localeCompare(b));
44045
44669
  }
44046
44670
  function inProgressSkillsSyncPath(baseUrl, agent) {
44047
- return join18(
44671
+ return join19(
44048
44672
  sdkCliStateDirPath(baseUrl),
44049
44673
  `skills-sync-in-progress-${agentLeaseSegment(agent)}`
44050
44674
  );
44051
44675
  }
44052
44676
  function readInProgressSkillsSyncLeaseFromDir(dir) {
44053
- const claim = readMarkedSkillsSyncVersion(join18(dir, "claim"));
44677
+ const claim = readMarkedSkillsSyncVersion(join19(dir, "claim"));
44054
44678
  const [version = "", startedAt = ""] = claim.split(" ");
44055
- const pidRaw = readMarkedSkillsSyncVersion(join18(dir, "pid"));
44679
+ const pidRaw = readMarkedSkillsSyncVersion(join19(dir, "pid"));
44056
44680
  return {
44057
44681
  claimToken: version && startedAt ? `${version} ${startedAt}` : "",
44058
44682
  version,
44059
44683
  startedAt: Number(startedAt),
44060
44684
  pid: /^\d+$/.test(pidRaw) ? Number(pidRaw) : null,
44061
- owner: readMarkedSkillsSyncVersion(join18(dir, "owner"))
44685
+ owner: readMarkedSkillsSyncVersion(join19(dir, "owner"))
44062
44686
  };
44063
44687
  }
44064
44688
  function readInProgressSkillsSyncLease(baseUrl, agent) {
@@ -44116,9 +44740,9 @@ function claimOneInProgressSkillsSync(baseUrl, remoteVersion, agent, owner) {
44116
44740
  const claimToken = `${remoteVersion} ${Date.now()}`;
44117
44741
  const staging = `${dir}.staging-${process.pid}-${Date.now()}`;
44118
44742
  mkdirSync10(staging);
44119
- writeFileSync14(join18(staging, "claim"), `${claimToken}
44743
+ writeFileSync14(join19(staging, "claim"), `${claimToken}
44120
44744
  `, "utf-8");
44121
- writeFileSync14(join18(staging, "owner"), `${owner}
44745
+ writeFileSync14(join19(staging, "owner"), `${owner}
44122
44746
  `, "utf-8");
44123
44747
  try {
44124
44748
  renameSync(staging, dir);
@@ -44192,7 +44816,7 @@ function recordOwnPidOnInProgressSkillsSync(baseUrl, leases) {
44192
44816
  if (!lease.claimToken) continue;
44193
44817
  try {
44194
44818
  writeFileSync14(
44195
- join18(inProgressSkillsSyncPath(baseUrl, agent), "pid"),
44819
+ join19(inProgressSkillsSyncPath(baseUrl, agent), "pid"),
44196
44820
  `${process.pid}
44197
44821
  `,
44198
44822
  "utf-8"
@@ -44261,7 +44885,7 @@ function skillsInstallLeasePath(baseUrl, agents) {
44261
44885
  return sortedLeaseAgents(agents).map((agent) => inProgressSkillsSyncPath(baseUrl, agent)).join(", ");
44262
44886
  }
44263
44887
  function deferredSkillsNoticePath(baseUrl, agents) {
44264
- return join18(
44888
+ return join19(
44265
44889
  sdkCliStateDirPath(baseUrl),
44266
44890
  `skills-sync-notice-${sortedLeaseAgents(agents).map(agentLeaseSegment).join("-")}`
44267
44891
  );
@@ -44312,7 +44936,7 @@ function spawnDetachedSkillsSyncChild(argv, onSpawnError) {
44312
44936
  child.unref();
44313
44937
  }
44314
44938
  function failedSkillsSyncPath(baseUrl, agents) {
44315
- return join18(
44939
+ return join19(
44316
44940
  sdkCliStateDirPath(baseUrl),
44317
44941
  `skills-sync-failed-${sortedLeaseAgents(agents).map(agentLeaseSegment).join("-")}-version`
44318
44942
  );
@@ -44439,7 +45063,7 @@ function safeSkillFilePath(value) {
44439
45063
  }
44440
45064
  function installedSkillFiles(root, prefix = "") {
44441
45065
  const files = [];
44442
- for (const entry of readdirSync4(join18(root, prefix), {
45066
+ for (const entry of readdirSync4(join19(root, prefix), {
44443
45067
  withFileTypes: true
44444
45068
  })) {
44445
45069
  const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
@@ -44559,11 +45183,11 @@ async function verifyDefaultAgentSkillsInstall(baseUrl, remoteVersion, skillName
44559
45183
  controller.abort();
44560
45184
  }
44561
45185
  const home = homedir8();
44562
- const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR?.trim() || join18(home, ".claude");
45186
+ const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR?.trim() || join19(home, ".claude");
44563
45187
  for (const [name, { files }] of published) {
44564
45188
  for (const root of [
44565
- join18(home, ".agents", "skills", name),
44566
- join18(claudeConfigDir, "skills", name)
45189
+ join19(home, ".agents", "skills", name),
45190
+ join19(claudeConfigDir, "skills", name)
44567
45191
  ]) {
44568
45192
  const installed = installedSkillFiles(root);
44569
45193
  if (installed.length !== files.length || installed.some((file, index2) => file !== files[index2])) {
@@ -44571,7 +45195,7 @@ async function verifyDefaultAgentSkillsInstall(baseUrl, remoteVersion, skillName
44571
45195
  }
44572
45196
  for (const file of files) {
44573
45197
  const publishedContent = expected.get(`${name}/${file}`);
44574
- if (!publishedContent || !readFileSync15(join18(root, file)).equals(publishedContent)) {
45198
+ if (!publishedContent || !readFileSync15(join19(root, file)).equals(publishedContent)) {
44575
45199
  throw new Error(`installed content differs for ${name}/${file}`);
44576
45200
  }
44577
45201
  }
@@ -44625,7 +45249,7 @@ function probeInstallers(timeoutMs) {
44625
45249
  };
44626
45250
  }
44627
45251
  function noInstallerProbePath(baseUrl) {
44628
- return join18(
45252
+ return join19(
44629
45253
  sdkCliStateDirPath(baseUrl),
44630
45254
  "skills-sync-no-installer-unknown.json"
44631
45255
  );
@@ -45094,13 +45718,13 @@ function detectSkillsAgents(input2) {
45094
45718
  ];
45095
45719
  const detected = AGENT_MARKERS.filter(
45096
45720
  (marker) => roots.some(
45097
- (root) => marker.paths.some((path) => existsSync14(join19(root, path)))
45721
+ (root) => marker.paths.some((path) => existsSync14(join20(root, path)))
45098
45722
  )
45099
45723
  ).map((marker) => marker.agent);
45100
45724
  return detected.length > 0 ? detected : ["*"];
45101
45725
  }
45102
45726
  function skillsStatePathForScope(baseUrl, scope, root) {
45103
- return scope === "local" && root ? join19(root, ".deepline", "setup", "skills.json") : join19(sdkCliStateDirPath(baseUrl), "skills-install.json");
45727
+ return scope === "local" && root ? join20(root, ".deepline", "setup", "skills.json") : join20(sdkCliStateDirPath(baseUrl), "skills-install.json");
45104
45728
  }
45105
45729
  function buildSkillsPlan(input2) {
45106
45730
  const scopeArgs = input2.scope === "global" ? ["--global"] : [];
@@ -45650,7 +46274,7 @@ function buildPendingAuthorizationOutput(input2) {
45650
46274
  };
45651
46275
  }
45652
46276
  function setupStatePath(baseUrl, scope, root) {
45653
- return scope === "local" && root ? join20(root, ".deepline", "setup", "state.json") : join20(sdkCliStateDirPath(baseUrl), "setup.json");
46277
+ return scope === "local" && root ? join21(root, ".deepline", "setup", "state.json") : join21(sdkCliStateDirPath(baseUrl), "setup.json");
45654
46278
  }
45655
46279
  async function captureStdout2(run) {
45656
46280
  let stdout = "";
@@ -45731,7 +46355,7 @@ function resolvePersistentGlobalCommand(dependencies = {}) {
45731
46355
  if (prefix.status !== 0) return null;
45732
46356
  const root = String(prefix.stdout ?? "").trim();
45733
46357
  if (!root) return null;
45734
- const candidates = platform3 === "win32" ? [join20(root, "deepline.cmd"), join20(root, "deepline")] : [join20(root, "bin", "deepline")];
46358
+ const candidates = platform3 === "win32" ? [join21(root, "deepline.cmd"), join21(root, "deepline")] : [join21(root, "bin", "deepline")];
45735
46359
  return candidates.find((candidate) => pathExists(candidate)) ?? null;
45736
46360
  }
45737
46361
  function inspectGlobalCliAvailability(input2) {
@@ -45757,7 +46381,7 @@ function isKnownDeeplineCommand(path) {
45757
46381
  } catch {
45758
46382
  }
45759
46383
  if (entrypoint && resolvedPath === entrypoint) return true;
45760
- if (resolvedPath.includes(`${join20("node_modules", "deepline")}`)) return true;
46384
+ if (resolvedPath.includes(`${join21("node_modules", "deepline")}`)) return true;
45761
46385
  const content = safeRead(path);
45762
46386
  return content.includes("node_modules/deepline") || content.includes("node_modules\\deepline") || content.includes("DEEPLINE_CONFIG_SCOPE") || content.includes("deepline-real");
45763
46387
  }
@@ -45767,7 +46391,7 @@ function inspectPathConflict() {
45767
46391
  try {
45768
46392
  if (lstatSync2(commandPath).isSymbolicLink()) {
45769
46393
  const target = realpathSync5(commandPath);
45770
- if (target.includes(`${join20("node_modules", "deepline")}`)) return null;
46394
+ if (target.includes(`${join21("node_modules", "deepline")}`)) return null;
45771
46395
  }
45772
46396
  } catch {
45773
46397
  }
@@ -45816,7 +46440,7 @@ function failSetupPhase(phases, phase, code) {
45816
46440
  phases[phase] = { status: "failed", code };
45817
46441
  }
45818
46442
  function rollbackCommand(scope, root) {
45819
- const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify(join20(root, ".deepline", "runtime"))}` : "";
46443
+ const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify(join21(root, ".deepline", "runtime"))}` : "";
45820
46444
  const allowScriptsFlag = npmSupportsAllowScripts(readNpmVersion(process.env)) ? " --allow-scripts=esbuild" : "";
45821
46445
  return `npm install -g${prefix} --no-audit --no-fund --include=optional${allowScriptsFlag} deepline@${SDK_VERSION}`;
45822
46446
  }
@@ -45911,7 +46535,7 @@ function buildDoctorAssessment(input2) {
45911
46535
  const pathGlobalCli = globalCli?.path ?? null;
45912
46536
  const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
45913
46537
  const cliScopeOk = input2.scope === "global" ? Boolean(pathGlobalCli) : Boolean(
45914
- input2.root && runningCliPath?.includes(join20(input2.root, ".deepline", "runtime"))
46538
+ input2.root && runningCliPath?.includes(join21(input2.root, ".deepline", "runtime"))
45915
46539
  );
45916
46540
  const checks = {
45917
46541
  cli: {
@@ -46538,7 +47162,7 @@ import {
46538
47162
  writeFileSync as writeFileSync17
46539
47163
  } from "fs";
46540
47164
  import { homedir as homedir11 } from "os";
46541
- import { dirname as dirname17, join as join21 } from "path";
47165
+ import { dirname as dirname17, join as join22 } from "path";
46542
47166
  var UPDATE_PREFERENCES_SCHEMA_VERSION = 1;
46543
47167
  var CLI_UPDATE_MESSAGES = [
46544
47168
  {
@@ -46567,7 +47191,7 @@ function unreadablePreferences(path, error) {
46567
47191
  };
46568
47192
  }
46569
47193
  function cliUpdatePreferencesPath(homeDir2 = homedir11()) {
46570
- return join21(
47194
+ return join22(
46571
47195
  homeDir2,
46572
47196
  ".local",
46573
47197
  "deepline",
@@ -46669,7 +47293,7 @@ import {
46669
47293
  basename as basename7,
46670
47294
  dirname as dirname18,
46671
47295
  isAbsolute as isAbsolute7,
46672
- join as join23,
47296
+ join as join24,
46673
47297
  relative as relative8,
46674
47298
  resolve as resolve19
46675
47299
  } from "path";
@@ -46677,7 +47301,7 @@ import {
46677
47301
  // src/cli/install-integrity.ts
46678
47302
  import { createRequire } from "module";
46679
47303
  import { existsSync as existsSync17, readFileSync as readFileSync19, statSync as statSync5 } from "fs";
46680
- import { isAbsolute as isAbsolute6, join as join22, relative as relative7, resolve as resolve18 } from "path";
47304
+ import { isAbsolute as isAbsolute6, join as join23, relative as relative7, resolve as resolve18 } from "path";
46681
47305
  var SDK_SIDECAR_CRITICAL_PACKAGE_FILES = [
46682
47306
  "dist/cli/index.mjs",
46683
47307
  "dist/index.mjs",
@@ -46722,7 +47346,7 @@ function isFile(path) {
46722
47346
  }
46723
47347
  }
46724
47348
  function readManifest(packageRoot) {
46725
- const packageJsonPath = join22(packageRoot, "package.json");
47349
+ const packageJsonPath = join23(packageRoot, "package.json");
46726
47350
  let packageJson;
46727
47351
  try {
46728
47352
  packageJson = parseJson(packageJsonPath);
@@ -46796,8 +47420,8 @@ function readManifest(packageRoot) {
46796
47420
  return { mode: "manifest", manifest };
46797
47421
  }
46798
47422
  function inspectSdkSidecarInstall(versionDir) {
46799
- const nodeModulesRoot = join22(versionDir, "node_modules");
46800
- const packageRoot = join22(nodeModulesRoot, "deepline");
47423
+ const nodeModulesRoot = join23(versionDir, "node_modules");
47424
+ const packageRoot = join23(nodeModulesRoot, "deepline");
46801
47425
  const manifestResult = readManifest(packageRoot);
46802
47426
  if ("invalidReason" in manifestResult) {
46803
47427
  return {
@@ -46808,8 +47432,8 @@ function inspectSdkSidecarInstall(versionDir) {
46808
47432
  };
46809
47433
  }
46810
47434
  const missing = [
46811
- ...manifestResult.manifest.packageFiles.filter((path) => !isFile(join22(packageRoot, path))).map((path) => `deepline/${path}`),
46812
- ...manifestResult.manifest.dependencyFiles.filter((path) => !isFile(join22(nodeModulesRoot, path))).map((path) => `node_modules/${path}`)
47435
+ ...manifestResult.manifest.packageFiles.filter((path) => !isFile(join23(packageRoot, path))).map((path) => `deepline/${path}`),
47436
+ ...manifestResult.manifest.dependencyFiles.filter((path) => !isFile(join23(nodeModulesRoot, path))).map((path) => `node_modules/${path}`)
46813
47437
  ];
46814
47438
  return {
46815
47439
  ok: missing.length === 0,
@@ -46820,7 +47444,7 @@ function inspectSdkSidecarInstall(versionDir) {
46820
47444
  }
46821
47445
  function probeSdkSidecarEsbuild(versionDir) {
46822
47446
  try {
46823
- const requireFromInstall = createRequire(join22(versionDir, "package.json"));
47447
+ const requireFromInstall = createRequire(join23(versionDir, "package.json"));
46824
47448
  const esbuild = requireFromInstall("esbuild");
46825
47449
  if (typeof esbuild.transformSync !== "function") {
46826
47450
  return "esbuild does not export transformSync";
@@ -46889,7 +47513,7 @@ function sidecarStateDir(input2) {
46889
47513
  if (!scope || scope.includes("/") || scope.includes("\\")) {
46890
47514
  return null;
46891
47515
  }
46892
- return join23(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
47516
+ return join24(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
46893
47517
  }
46894
47518
  function sidecarRegistryUrl(hostUrl) {
46895
47519
  let url;
@@ -46931,12 +47555,12 @@ function resolvePythonSidecarUpdatePlan(options) {
46931
47555
  if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || isAbsolute7(relativeEntrypoint)) {
46932
47556
  return null;
46933
47557
  }
46934
- const installMethod = readOptionalText(join23(stateDir, ".install-method"));
47558
+ const installMethod = readOptionalText(join24(stateDir, ".install-method"));
46935
47559
  if (installMethod !== "python-sidecar") return null;
46936
47560
  const scope = options.env.DEEPLINE_CONFIG_SCOPE?.trim() || "";
46937
47561
  const hostUrl = options.env.DEEPLINE_HOST_URL?.trim() || "";
46938
- const nodeBin = readOptionalText(join23(stateDir, ".node-bin")) || process.execPath;
46939
- const sidecarPath = readOptionalText(join23(stateDir, ".command-path")) || join23(
47562
+ const nodeBin = readOptionalText(join24(stateDir, ".node-bin")) || process.execPath;
47563
+ const sidecarPath = readOptionalText(join24(stateDir, ".command-path")) || join24(
46940
47564
  stateDir,
46941
47565
  "bin",
46942
47566
  process.platform === "win32" ? "deepline-sdk.cmd" : "deepline-sdk"
@@ -46944,7 +47568,7 @@ function resolvePythonSidecarUpdatePlan(options) {
46944
47568
  const packageSpec = options.packageSpec || "deepline@latest";
46945
47569
  const npmCommand = "npm";
46946
47570
  const registryUrl = sidecarRegistryUrl(hostUrl);
46947
- const versionDir = join23(stateDir, "versions", "<version>");
47571
+ const versionDir = join24(stateDir, "versions", "<version>");
46948
47572
  const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote5(versionDir)} --registry ${shellQuote5(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote5).join(" ")} ${shellQuote5(packageSpec)}`;
46949
47573
  return {
46950
47574
  kind: "python-sidecar",
@@ -46962,11 +47586,11 @@ function resolvePythonSidecarUpdatePlan(options) {
46962
47586
  function findRepoBackedSdkRoot(startPath) {
46963
47587
  let current = resolve19(startPath);
46964
47588
  while (true) {
46965
- if (existsSync18(join23(current, "package.json")) && existsSync18(join23(current, "bin", "deepline-dev.ts"))) {
47589
+ if (existsSync18(join24(current, "package.json")) && existsSync18(join24(current, "bin", "deepline-dev.ts"))) {
46966
47590
  const parent2 = dirname18(current);
46967
47591
  return basename7(parent2) === "packages" && basename7(current) === "sdk" ? dirname18(parent2) : parent2;
46968
47592
  }
46969
- if (existsSync18(join23(current, "sdk", "package.json")) && existsSync18(join23(current, "sdk", "bin", "deepline-dev.ts"))) {
47593
+ if (existsSync18(join24(current, "sdk", "package.json")) && existsSync18(join24(current, "sdk", "bin", "deepline-dev.ts"))) {
46970
47594
  return current;
46971
47595
  }
46972
47596
  const parent = dirname18(current);
@@ -46994,7 +47618,7 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
46994
47618
  const directPrefix = prefixParts.join("/").toLowerCase();
46995
47619
  const knownWindowsPrefixes = [
46996
47620
  env.npm_config_prefix,
46997
- env.APPDATA ? join23(env.APPDATA, "npm") : void 0
47621
+ env.APPDATA ? join24(env.APPDATA, "npm") : void 0
46998
47622
  ].filter((value) => Boolean(value)).map((value) => resolve19(value).replace(/\\/g, "/").toLowerCase());
46999
47623
  if (!knownWindowsPrefixes.includes(
47000
47624
  resolve19(directPrefix).replace(/\\/g, "/").toLowerCase()
@@ -47101,9 +47725,9 @@ var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
47101
47725
  function autoUpdateFailurePath(plan) {
47102
47726
  if (plan.kind === "source" || plan.kind === "homebrew") return null;
47103
47727
  if (plan.kind === "python-sidecar") {
47104
- return join23(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
47728
+ return join24(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
47105
47729
  }
47106
- return join23(
47730
+ return join24(
47107
47731
  homedir12(),
47108
47732
  ".local",
47109
47733
  "deepline",
@@ -47190,7 +47814,7 @@ function safeVersionSegment(value) {
47190
47814
  return /^[0-9A-Za-z._-]+$/.test(normalized) ? normalized : "";
47191
47815
  }
47192
47816
  function entryPathInVersionDir(versionDir) {
47193
- return join23(
47817
+ return join24(
47194
47818
  versionDir,
47195
47819
  "node_modules",
47196
47820
  "deepline",
@@ -47200,7 +47824,7 @@ function entryPathInVersionDir(versionDir) {
47200
47824
  );
47201
47825
  }
47202
47826
  function installedPackageVersion(versionDir) {
47203
- const packageJsonPath = join23(
47827
+ const packageJsonPath = join24(
47204
47828
  versionDir,
47205
47829
  "node_modules",
47206
47830
  "deepline",
@@ -47328,10 +47952,10 @@ function writeSidecarLauncher(input2) {
47328
47952
  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);";
47329
47953
  const criticalPaths = [
47330
47954
  ...SDK_SIDECAR_CRITICAL_PACKAGE_FILES.map(
47331
- (path) => join23(packageRoot, path)
47955
+ (path) => join24(packageRoot, path)
47332
47956
  ),
47333
47957
  ...SDK_SIDECAR_CRITICAL_DEPENDENCY_FILES.map(
47334
- (path) => join23(versionDir, "node_modules", path)
47958
+ (path) => join24(versionDir, "node_modules", path)
47335
47959
  )
47336
47960
  ];
47337
47961
  if (process.platform === "win32") {
@@ -47385,14 +48009,14 @@ function writeSidecarLauncher(input2) {
47385
48009
  );
47386
48010
  }
47387
48011
  async function runPythonSidecarUpdatePlan(plan) {
47388
- const versionsDir = join23(plan.stateDir, "versions");
47389
- const tempDir = join23(
48012
+ const versionsDir = join24(plan.stateDir, "versions");
48013
+ const tempDir = join24(
47390
48014
  versionsDir,
47391
48015
  `.tmp-sdk-update-${process.pid}-${Date.now()}`
47392
48016
  );
47393
48017
  rmSync7(tempDir, { recursive: true, force: true });
47394
48018
  mkdirSync14(tempDir, { recursive: true });
47395
- writeFileSync18(join23(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
48019
+ writeFileSync18(join24(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
47396
48020
  const env = {
47397
48021
  ...process.env,
47398
48022
  PATH: `${dirname18(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
@@ -47432,7 +48056,7 @@ async function runPythonSidecarUpdatePlan(plan) {
47432
48056
  rmSync7(tempDir, { recursive: true, force: true });
47433
48057
  return 1;
47434
48058
  }
47435
- const finalDir = join23(versionsDir, installedVersion);
48059
+ const finalDir = join24(versionsDir, installedVersion);
47436
48060
  const finalEntryPath = entryPathInVersionDir(finalDir);
47437
48061
  const finalFailure = sidecarInstallFailure(finalDir);
47438
48062
  let backupDir = null;
@@ -47441,7 +48065,7 @@ async function runPythonSidecarUpdatePlan(plan) {
47441
48065
  } else {
47442
48066
  let shouldPublishTemp = true;
47443
48067
  if (existsSync18(finalDir)) {
47444
- backupDir = join23(
48068
+ backupDir = join24(
47445
48069
  versionsDir,
47446
48070
  `.backup-${installedVersion}-${process.pid}-${Date.now()}`
47447
48071
  );
@@ -47516,27 +48140,27 @@ async function runPythonSidecarUpdatePlan(plan) {
47516
48140
  entryPath: finalEntryPath
47517
48141
  });
47518
48142
  writeFileSync18(
47519
- join23(plan.stateDir, ".version"),
48143
+ join24(plan.stateDir, ".version"),
47520
48144
  `${installedVersion}
47521
48145
  `,
47522
48146
  "utf8"
47523
48147
  );
47524
48148
  writeFileSync18(
47525
- join23(plan.stateDir, ".install-method"),
48149
+ join24(plan.stateDir, ".install-method"),
47526
48150
  "python-sidecar\n",
47527
48151
  "utf8"
47528
48152
  );
47529
48153
  writeFileSync18(
47530
- join23(plan.stateDir, ".command-path"),
48154
+ join24(plan.stateDir, ".command-path"),
47531
48155
  `${plan.sidecarPath}
47532
48156
  `,
47533
48157
  "utf8"
47534
48158
  );
47535
- writeFileSync18(join23(plan.stateDir, ".runner"), "node\n", "utf8");
47536
- writeFileSync18(join23(plan.stateDir, ".node-bin"), `${plan.nodeBin}
48159
+ writeFileSync18(join24(plan.stateDir, ".runner"), "node\n", "utf8");
48160
+ writeFileSync18(join24(plan.stateDir, ".node-bin"), `${plan.nodeBin}
47537
48161
  `, "utf8");
47538
48162
  writeFileSync18(
47539
- join23(plan.stateDir, ".entry-path"),
48163
+ join24(plan.stateDir, ".entry-path"),
47540
48164
  `${finalEntryPath}
47541
48165
  `,
47542
48166
  "utf8"
@@ -47803,7 +48427,7 @@ function requireCatalogEvent(settings, eventType) {
47803
48427
  }
47804
48428
  return event;
47805
48429
  }
47806
- async function printSettings(options) {
48430
+ async function printSettings2(options) {
47807
48431
  const settings = await new DeeplineClient().getNotificationSettings();
47808
48432
  const slack = slackDestination(settings);
47809
48433
  const destinationId = typeof slack?._id === "string" ? slack._id : void 0;
@@ -47930,7 +48554,7 @@ Slack is the delivery integration. This command group only manages product
47930
48554
  notifications; there is no general integrations CLI.
47931
48555
  `
47932
48556
  );
47933
- notifications.command("get").description("Show destination, subscriptions, and DLQ health.").option("--json", "Emit JSON output").action(printSettings);
48557
+ notifications.command("get").description("Show destination, subscriptions, and DLQ health.").option("--json", "Emit JSON output").action(printSettings2);
47934
48558
  notifications.command("connect").description("Start the OAuth connection required by a destination.").argument("<destination>", "Destination kind (currently slack)").option("--open", "Open the Slack authorization URL in a browser").option("--dry-run", "Describe the mutation without starting OAuth").option("--json", "Emit JSON output").action(
47935
48559
  async (destination, options) => {
47936
48560
  if (destination !== "slack")
@@ -48616,7 +49240,7 @@ import {
48616
49240
  writeFileSync as writeFileSync20
48617
49241
  } from "fs";
48618
49242
  import { tmpdir as tmpdir6 } from "os";
48619
- import { dirname as dirname20, join as join25, resolve as resolve20 } from "path";
49243
+ import { dirname as dirname20, join as join26, resolve as resolve20 } from "path";
48620
49244
 
48621
49245
  // src/tool-output.ts
48622
49246
  import {
@@ -48627,7 +49251,7 @@ import {
48627
49251
  writeSync
48628
49252
  } from "fs";
48629
49253
  import { homedir as homedir13 } from "os";
48630
- import { dirname as dirname19, join as join24 } from "path";
49254
+ import { dirname as dirname19, join as join25 } from "path";
48631
49255
  function isPlainObject(value) {
48632
49256
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
48633
49257
  }
@@ -48754,18 +49378,18 @@ function projectRowOutput(conversion) {
48754
49378
  };
48755
49379
  }
48756
49380
  function ensureOutputDir() {
48757
- const outputDir = join24(homedir13(), ".local", "share", "deepline", "data");
49381
+ const outputDir = join25(homedir13(), ".local", "share", "deepline", "data");
48758
49382
  mkdirSync15(outputDir, { recursive: true });
48759
49383
  return outputDir;
48760
49384
  }
48761
49385
  function writeJsonOutputFile(payload, stem) {
48762
49386
  const outputDir = ensureOutputDir();
48763
- const outputPath = join24(outputDir, `${stem}_${Date.now()}.json`);
49387
+ const outputPath = join25(outputDir, `${stem}_${Date.now()}.json`);
48764
49388
  writeFileSync19(outputPath, JSON.stringify(payload, null, 2), "utf-8");
48765
49389
  return outputPath;
48766
49390
  }
48767
49391
  function writeCsvOutputFile(rows, stem, options) {
48768
- const outputPath = options?.outPath ? options.outPath : join24(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
49392
+ const outputPath = options?.outPath ? options.outPath : join25(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
48769
49393
  mkdirSync15(dirname19(outputPath), { recursive: true });
48770
49394
  const columns = columnsForRows(rows);
48771
49395
  const escapeCell = (value) => {
@@ -49368,6 +49992,8 @@ async function searchTools(queryInput, options = {}) {
49368
49992
  query,
49369
49993
  categories: options.categories,
49370
49994
  searchTerms: options.searchTerms,
49995
+ limit: options.limit,
49996
+ offset: options.offset,
49371
49997
  searchMode: options.searchMode,
49372
49998
  includeSearchDebug: options.includeSearchDebug
49373
49999
  });
@@ -49598,13 +50224,15 @@ Notes:
49598
50224
  that can be passed to deepline tools describe or deepline tools execute.
49599
50225
  Provide a query, or omit it only when --categories and/or --search_terms is
49600
50226
  supplied. Providing neither is a usage error. Both filters accept
49601
- comma-separated values. Use a provider name in the query; --prefix is not a
49602
- supported option.
50227
+ comma-separated values. Use --limit and --offset to page through ranked
50228
+ results (limit 1-50, offset is zero-based); JSON includes next_offset.
50229
+ Use a provider name in the query; --prefix is not a supported option.
49603
50230
  The grep alias is the same ranked retrieval surface with a more literal name
49604
50231
  for agents that are filtering a registry rather than choosing a workflow.
49605
50232
 
49606
50233
  Examples:
49607
- deepline tools search email
50234
+ deepline tools search email --limit 10 --json
50235
+ deepline tools search email --limit 10 --offset 10 --json
49608
50236
  deepline tools search --categories company_search --search_terms "investors,funding"
49609
50237
  deepline tools grep "company enrichment" --categories enrichment --json
49610
50238
  deepline tools search verifier --search-mode v2 --json
@@ -49615,10 +50243,12 @@ Examples:
49615
50243
  ).option(
49616
50244
  "--search_terms <terms>",
49617
50245
  "Comma-separated structured search terms; may be used without a query"
49618
- ).option("--search-terms <terms>", "Alias for --search_terms").option("--search-mode <mode>", "Ranked search mode: v1 or v2").option("--include-search-debug", "Include ranked search debug metadata").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
50246
+ ).option("--search-terms <terms>", "Alias for --search_terms").option("--limit <count>", "Maximum ranked results to return (1-50)").option("--offset <count>", "Zero-based ranked result offset").option("--search-mode <mode>", "Ranked search mode: v1 or v2").option("--include-search-debug", "Include ranked search debug metadata").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
49619
50247
  process.exitCode = await searchTools(query, {
49620
50248
  json: options.json,
49621
50249
  compact: options.compact,
50250
+ limit: options.limit !== void 0 ? Number.parseInt(options.limit, 10) : void 0,
50251
+ offset: options.offset !== void 0 ? Number.parseInt(options.offset, 10) : void 0,
49622
50252
  categories: options.categories,
49623
50253
  searchTerms: options.searchTerms ?? options.search_terms,
49624
50254
  searchMode: options.searchMode === "v1" || options.searchMode === "v2" ? options.searchMode : void 0,
@@ -50021,8 +50651,8 @@ function printMonitorTypeFilters(tool) {
50021
50651
  }
50022
50652
  function printMonitorTypeFilterExamples(tool) {
50023
50653
  const documentation = recordField2(tool, "documentation");
50024
- const fields = recordField2(documentation, "fields");
50025
- const examples = Object.entries(fields).flatMap(([name, rawField]) => {
50654
+ const fields2 = recordField2(documentation, "fields");
50655
+ const examples = Object.entries(fields2).flatMap(([name, rawField]) => {
50026
50656
  const grammar = recordField2(isRecord12(rawField) ? rawField : {}, "grammar");
50027
50657
  const example = stringField2(grammar, "example");
50028
50658
  const values = [
@@ -50377,9 +51007,9 @@ function sampleValueForField(field) {
50377
51007
  if (type === "object") return {};
50378
51008
  return "...";
50379
51009
  }
50380
- function samplePayloadForInputFields(fields) {
51010
+ function samplePayloadForInputFields(fields2) {
50381
51011
  return Object.fromEntries(
50382
- fields.slice(0, 4).flatMap((field) => {
51012
+ fields2.slice(0, 4).flatMap((field) => {
50383
51013
  if (!isRecord12(field)) return [];
50384
51014
  const name = stringField2(field, "name");
50385
51015
  if (!name) return [];
@@ -50510,8 +51140,8 @@ function formatListedToolCost(tool) {
50510
51140
  }
50511
51141
  function toolInputFieldsForDisplay(inputSchema) {
50512
51142
  if (Array.isArray(inputSchema.fields)) {
50513
- const fields = inputSchema.fields.filter(isRecord12);
50514
- if (!isRecord12(inputSchema.jsonSchema)) return fields;
51143
+ const fields2 = inputSchema.fields.filter(isRecord12);
51144
+ if (!isRecord12(inputSchema.jsonSchema)) return fields2;
50515
51145
  const jsonSchemaFields = new Map(
50516
51146
  recursiveToolInputFieldsForDisplay({
50517
51147
  jsonSchema: inputSchema.jsonSchema
@@ -50519,7 +51149,7 @@ function toolInputFieldsForDisplay(inputSchema) {
50519
51149
  (field) => typeof field.name === "string" ? [[field.name, field]] : []
50520
51150
  )
50521
51151
  );
50522
- return fields.map((field) => {
51152
+ return fields2.map((field) => {
50523
51153
  const jsonSchemaField = typeof field.name === "string" ? jsonSchemaFields.get(field.name) : void 0;
50524
51154
  const minItems = typeof field.minItems === "number" ? field.minItems : jsonSchemaField?.minItems;
50525
51155
  const maxItems = typeof field.maxItems === "number" ? field.maxItems : jsonSchemaField?.maxItems;
@@ -50616,7 +51246,7 @@ function publicToolInputSchemaForDescribe(inputSchema) {
50616
51246
  }
50617
51247
  function recursiveToolInputFieldsForDisplay(inputSchema) {
50618
51248
  const root = canonicalToolJsonSchema(inputSchema);
50619
- const fields = /* @__PURE__ */ new Map();
51249
+ const fields2 = /* @__PURE__ */ new Map();
50620
51250
  const schemasById = /* @__PURE__ */ new Map();
50621
51251
  const collectSchemaIds = (value) => {
50622
51252
  if (Array.isArray(value)) {
@@ -50644,9 +51274,9 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
50644
51274
  const addField = (field) => {
50645
51275
  const name = typeof field.name === "string" ? field.name : "";
50646
51276
  if (!name) return;
50647
- const existing = fields.get(name);
51277
+ const existing = fields2.get(name);
50648
51278
  if (!existing || existing.type === "unknown") {
50649
- fields.set(name, field);
51279
+ fields2.set(name, field);
50650
51280
  }
50651
51281
  };
50652
51282
  const visit = (unresolvedSchema, path, required, activeRefs = /* @__PURE__ */ new Set()) => {
@@ -50694,7 +51324,7 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
50694
51324
  }
50695
51325
  };
50696
51326
  visit(root, "", false);
50697
- return fields.size ? [...fields.values()] : toolInputFieldsForDisplay(inputSchema);
51327
+ return fields2.size ? [...fields2.values()] : toolInputFieldsForDisplay(inputSchema);
50698
51328
  }
50699
51329
  function inputFieldJsonForDescribe(field) {
50700
51330
  const publicItems = isRecord12(field.items) ? publicToolInputSchemaForDescribe({ items: field.items }).items : void 0;
@@ -51114,7 +51744,7 @@ function parseToolExecuteTimeout(raw) {
51114
51744
  function pendingToolExecutionPath(input2) {
51115
51745
  const config = resolveConfig();
51116
51746
  const fingerprint = createHash7("sha256").update(config.baseUrl).update("\0").update(createHash7("sha256").update(config.apiKey).digest("hex")).update("\0").update(input2.toolId).update("\0").update(stableStringify(input2.params)).update("\0").update(input2.responseIntent).digest("hex");
51117
- return join25(
51747
+ return join26(
51118
51748
  sdkCliStateDirPath(resolveConfig().baseUrl),
51119
51749
  `pending-tool-execution-${fingerprint}.json`
51120
51750
  );
@@ -51198,9 +51828,9 @@ function starterScriptJson(script) {
51198
51828
  function seedToolListScript(input2) {
51199
51829
  const stem = safeFileStem(input2.toolId);
51200
51830
  const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
51201
- const scriptDir = mkdtempSync(join25(tmpdir6(), "deepline-workflow-seed-"));
51831
+ const scriptDir = mkdtempSync(join26(tmpdir6(), "deepline-workflow-seed-"));
51202
51832
  chmodSync(scriptDir, 448);
51203
- const scriptPath = join25(scriptDir, fileName);
51833
+ const scriptPath = join26(scriptDir, fileName);
51204
51834
  const projectDir = `deepline/projects/${stem}-workflow`;
51205
51835
  const playName = `${stem}-workflow`;
51206
51836
  const sampleRows = input2.rows.length > 0 ? `${JSON.stringify(input2.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
@@ -51705,8 +52335,8 @@ Examples:
51705
52335
  }
51706
52336
 
51707
52337
  // src/cli/commands/workflow.ts
51708
- import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
51709
- import { dirname as dirname21, join as join26, resolve as resolve21 } from "path";
52338
+ import { mkdir as mkdir6, readFile as readFile7, writeFile as writeFile5 } from "fs/promises";
52339
+ import { dirname as dirname21, join as join27, resolve as resolve21 } from "path";
51710
52340
 
51711
52341
  // src/cli/workflow-to-play.ts
51712
52342
  import { createHash as createHash8 } from "crypto";
@@ -51923,7 +52553,7 @@ function readStatus(payload) {
51923
52553
  }
51924
52554
  async function readJsonOption(payload, file) {
51925
52555
  if (file) {
51926
- const raw = await readFile6(resolve21(file), "utf8");
52556
+ const raw = await readFile7(resolve21(file), "utf8");
51927
52557
  return JSON.parse(raw);
51928
52558
  }
51929
52559
  if (payload) {
@@ -51957,7 +52587,7 @@ async function transformOne(api, workflowId, outDir, publish) {
51957
52587
  revision.config,
51958
52588
  { workflowName: workflow.name, version: revision.version }
51959
52589
  );
51960
- const file = join26(resolve21(outDir), `${compiled.playName}.play.ts`);
52590
+ const file = join27(resolve21(outDir), `${compiled.playName}.play.ts`);
51961
52591
  await mkdir6(dirname21(file), { recursive: true });
51962
52592
  await writeFile5(file, compiled.sourceCode, "utf8");
51963
52593
  let published = false;
@@ -52504,8 +53134,8 @@ function topLevelCommandKnown(program, commandName) {
52504
53134
  );
52505
53135
  }
52506
53136
  async function runPlayRunnerHealthCheck() {
52507
- const dir = await mkdtemp4(join27(tmpdir7(), "deepline-health-play-"));
52508
- const file = join27(dir, "health-check.play.ts");
53137
+ const dir = await mkdtemp4(join28(tmpdir7(), "deepline-health-play-"));
53138
+ const file = join28(dir, "health-check.play.ts");
52509
53139
  try {
52510
53140
  await writeFile6(
52511
53141
  file,