deepline 0.1.274 → 0.1.276

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -718,7 +718,7 @@ var SDK_RELEASE = {
718
718
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
719
719
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
720
720
  // Operators use the checkout-local deepline-admin binary instead.
721
- version: "0.1.274",
721
+ version: "0.1.276",
722
722
  contracts: {
723
723
  api: {
724
724
  name: "sdk-http-api",
@@ -932,19 +932,19 @@ function isAbortLikeError(error) {
932
932
  const message = error.message.toLowerCase();
933
933
  return name === "aborterror" || message.includes("operation was aborted") || message === "aborted";
934
934
  }
935
- function mapNetworkError(baseUrl, error, targetLabel) {
935
+ function mapNetworkError(baseUrl, error, targetLabel2) {
936
936
  const tagged = error;
937
937
  const timeoutMs = tagged?.[REQUEST_TIMEOUT_MARKER];
938
938
  if (typeof timeoutMs === "number") {
939
939
  return {
940
- message: `Request to ${targetLabel} timed out after ${timeoutMs}ms while waiting for a response.`,
940
+ message: `Request to ${targetLabel2} timed out after ${timeoutMs}ms while waiting for a response.`,
941
941
  code: "NETWORK_TIMEOUT",
942
- details: { timeoutMs, target: targetLabel }
942
+ details: { timeoutMs, target: targetLabel2 }
943
943
  };
944
944
  }
945
945
  if (tagged?.[REQUEST_ABORT_MARKER]) {
946
946
  return {
947
- message: `Request to ${targetLabel} was aborted before it completed.`,
947
+ message: `Request to ${targetLabel2} was aborted before it completed.`,
948
948
  code: "NETWORK_ABORTED"
949
949
  };
950
950
  }
@@ -1605,9 +1605,277 @@ var RUNNER_POST_TERMINAL_DIAGNOSTIC_MAX_BYTES = 64 * 1024;
1605
1605
  // ../shared_libs/play-runtime/ledger-safe-payload.ts
1606
1606
  var ledgerIngressRedactor = createSecretRedactionContext();
1607
1607
 
1608
+ // ../shared_libs/play-runtime/activity-observation.ts
1609
+ function isRecord(value) {
1610
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
1611
+ }
1612
+ function isPlayActivityObservation(value) {
1613
+ if (!isRecord(value) || value.schemaVersion !== 1 || typeof value.activityId !== "string" || !value.activityId.trim() || typeof value.observedAt !== "number" || !Number.isFinite(value.observedAt) || !isRecord(value.target) || !isRecord(value.state)) {
1614
+ return false;
1615
+ }
1616
+ const targetKinds = /* @__PURE__ */ new Set([
1617
+ "provider",
1618
+ "dataset",
1619
+ "lease",
1620
+ "runner",
1621
+ "step",
1622
+ "capacity"
1623
+ ]);
1624
+ const stateKinds = /* @__PURE__ */ new Set([
1625
+ "active",
1626
+ "queued",
1627
+ "waiting",
1628
+ "retrying",
1629
+ "scheduled",
1630
+ "completed",
1631
+ "failed"
1632
+ ]);
1633
+ return typeof value.target.kind === "string" && targetKinds.has(value.target.kind) && typeof value.state.kind === "string" && stateKinds.has(value.state.kind);
1634
+ }
1635
+ function derivePlayActivityVisibility(input2) {
1636
+ const { state } = input2.observation;
1637
+ if (state.kind === "failed") return "action";
1638
+ if (state.kind === "waiting") {
1639
+ return state.reason.kind === "external_event" ? "action" : "headline";
1640
+ }
1641
+ if (state.kind === "queued" || state.kind === "scheduled") return "headline";
1642
+ if (state.kind === "retrying") {
1643
+ return state.retryAt - input2.now <= 3e4 ? "hidden" : "timeline";
1644
+ }
1645
+ if (state.kind === "active") return "headline";
1646
+ return "timeline";
1647
+ }
1648
+ function targetLabel(target) {
1649
+ switch (target.kind) {
1650
+ case "provider":
1651
+ return target.label ?? `${target.provider} ${target.operation}`;
1652
+ case "dataset":
1653
+ return target.label ?? `dataset ${target.tableNamespace}`;
1654
+ case "lease":
1655
+ return `${target.resourceKind} ${target.resourceLabel}`;
1656
+ case "runner":
1657
+ return target.label ?? `${target.backend} runner`;
1658
+ case "step":
1659
+ return target.label ?? target.stepId;
1660
+ case "capacity":
1661
+ return target.label ?? `${target.pool} capacity`;
1662
+ }
1663
+ }
1664
+ function summarizePlayActivity(observation) {
1665
+ const label = targetLabel(observation.target);
1666
+ const { state } = observation;
1667
+ switch (state.kind) {
1668
+ case "active": {
1669
+ const progress = state.progress;
1670
+ const counts = typeof progress?.completed === "number" && typeof progress.total === "number" ? ` (${progress.completed}/${progress.total})` : "";
1671
+ return `Active: ${label}${counts}.`;
1672
+ }
1673
+ case "queued":
1674
+ return `Queued: waiting for ${label}.`;
1675
+ case "waiting":
1676
+ if (state.reason.kind === "external_event") {
1677
+ const provider = state.reason.provider ? ` from ${state.reason.provider}` : "";
1678
+ return `Blocked: waiting for an external event${provider}.`;
1679
+ }
1680
+ if (state.reason.kind === "dataset") {
1681
+ return `Blocked: waiting for dataset ${state.reason.tableNamespace} to become ${state.reason.requiredPhase}.`;
1682
+ }
1683
+ if (state.reason.kind === "lease") {
1684
+ return `Contended: waiting for ${state.reason.resourceKind} lease ${state.reason.resourceLabel}.`;
1685
+ }
1686
+ return `Paused: ${label}; the legacy producer did not report a typed reason.`;
1687
+ case "retrying":
1688
+ return `Delayed: ${label} will retry automatically.`;
1689
+ case "scheduled":
1690
+ return `Scheduled: ${label} will resume automatically.`;
1691
+ case "completed":
1692
+ return `Completed: ${label}.`;
1693
+ case "failed":
1694
+ return `Failed: ${label}.`;
1695
+ }
1696
+ }
1697
+ function isTerminalActivityState(state) {
1698
+ return state.kind === "completed" || state.kind === "failed";
1699
+ }
1700
+ function projection(observation, now, classified = true) {
1701
+ return {
1702
+ observation,
1703
+ summary: summarizePlayActivity(observation),
1704
+ visibility: derivePlayActivityVisibility({ observation, now }),
1705
+ classified
1706
+ };
1707
+ }
1708
+ function projectPlayRunActivity(input2) {
1709
+ const now = input2.now ?? Date.now();
1710
+ const observedAt = input2.updatedAt ?? now;
1711
+ const normalizedStatus = input2.status.trim().toLowerCase();
1712
+ if (normalizedStatus === "completed" || normalizedStatus === "failed" || normalizedStatus === "cancelled" || normalizedStatus === "terminated" || normalizedStatus === "timed_out") {
1713
+ return null;
1714
+ }
1715
+ const explicit = [...input2.explicit ?? []].filter((candidate) => !isTerminalActivityState(candidate.state)).sort((left, right) => right.observedAt - left.observedAt)[0];
1716
+ if (explicit) return projection(explicit, now);
1717
+ if (input2.waitKind === "detached_runner") {
1718
+ return projection(
1719
+ {
1720
+ schemaVersion: 1,
1721
+ activityId: "runner:managed",
1722
+ target: {
1723
+ kind: "runner",
1724
+ backend: input2.runtimeBackend ?? "managed",
1725
+ label: "managed play runner"
1726
+ },
1727
+ state: { kind: "active" },
1728
+ observedAt
1729
+ },
1730
+ now
1731
+ );
1732
+ }
1733
+ if (input2.waitKind === "sleep") {
1734
+ return projection(
1735
+ {
1736
+ schemaVersion: 1,
1737
+ activityId: "run:sleep",
1738
+ target: {
1739
+ kind: "step",
1740
+ stepId: input2.activeNodeId ?? "run",
1741
+ label: input2.playName ?? "play"
1742
+ },
1743
+ state: {
1744
+ kind: "scheduled",
1745
+ reason: "sleep",
1746
+ resumeAt: input2.waitUntil ?? observedAt
1747
+ },
1748
+ observedAt
1749
+ },
1750
+ now
1751
+ );
1752
+ }
1753
+ if (input2.waitKind === "integration_event" || input2.waitKind === "integration_event_batch") {
1754
+ return projection(
1755
+ {
1756
+ schemaVersion: 1,
1757
+ activityId: `event:${input2.activeNodeId ?? "run"}`,
1758
+ stepId: input2.activeNodeId ?? void 0,
1759
+ target: {
1760
+ kind: "step",
1761
+ stepId: input2.activeNodeId ?? "run",
1762
+ label: input2.playName ?? "play"
1763
+ },
1764
+ state: {
1765
+ kind: "waiting",
1766
+ reason: {
1767
+ kind: "external_event",
1768
+ eventKey: input2.eventKey ?? void 0,
1769
+ deadlineAt: input2.waitUntil ?? void 0
1770
+ }
1771
+ },
1772
+ observedAt
1773
+ },
1774
+ now
1775
+ );
1776
+ }
1777
+ if (normalizedStatus === "waiting") {
1778
+ return projection(
1779
+ {
1780
+ schemaVersion: 1,
1781
+ activityId: "run:legacy-wait",
1782
+ target: {
1783
+ kind: "step",
1784
+ stepId: input2.activeNodeId ?? "run",
1785
+ label: input2.playName ?? "play"
1786
+ },
1787
+ state: { kind: "waiting", reason: { kind: "unknown" } },
1788
+ observedAt
1789
+ },
1790
+ now,
1791
+ false
1792
+ );
1793
+ }
1794
+ const pendingDataset = [...input2.datasets ?? []].filter(
1795
+ (dataset) => dataset.phase === "registered" || dataset.complete !== true && dataset.phase !== "failed"
1796
+ ).sort((left, right) => (right.updatedAt ?? 0) - (left.updatedAt ?? 0))[0];
1797
+ if (pendingDataset) {
1798
+ return projection(
1799
+ {
1800
+ schemaVersion: 1,
1801
+ activityId: `dataset:${pendingDataset.datasetId ?? pendingDataset.tableNamespace}`,
1802
+ target: {
1803
+ kind: "dataset",
1804
+ tableNamespace: pendingDataset.tableNamespace,
1805
+ operation: "materializing"
1806
+ },
1807
+ state: {
1808
+ kind: "active",
1809
+ progress: {
1810
+ completed: pendingDataset.persistedRows,
1811
+ total: typeof pendingDataset.succeededRows === "number" || typeof pendingDataset.failedRows === "number" ? (pendingDataset.succeededRows ?? 0) + (pendingDataset.failedRows ?? 0) : void 0,
1812
+ failed: pendingDataset.failedRows
1813
+ }
1814
+ },
1815
+ observedAt: pendingDataset.updatedAt ?? observedAt
1816
+ },
1817
+ now
1818
+ );
1819
+ }
1820
+ const activeStep = input2.nodeStates?.find(
1821
+ (candidate) => candidate.nodeId === input2.activeNodeId
1822
+ ) ?? input2.nodeStates?.find((candidate) => candidate.status === "running") ?? null;
1823
+ if (activeStep) {
1824
+ const toolId = activeStep.nodeId.startsWith("tool:") ? activeStep.nodeId.split(":").at(-1)?.trim() || null : null;
1825
+ const provider = toolId?.split(/[._]/)[0]?.trim() || null;
1826
+ return projection(
1827
+ {
1828
+ schemaVersion: 1,
1829
+ activityId: `step:${activeStep.nodeId}`,
1830
+ stepId: activeStep.nodeId,
1831
+ target: toolId && provider ? {
1832
+ kind: "provider",
1833
+ provider,
1834
+ operation: toolId,
1835
+ label: activeStep.label ?? toolId
1836
+ } : {
1837
+ kind: "step",
1838
+ stepId: activeStep.nodeId,
1839
+ label: activeStep.label
1840
+ },
1841
+ state: {
1842
+ kind: "active",
1843
+ progress: activeStep.progress ?? void 0
1844
+ },
1845
+ observedAt: activeStep.updatedAt ?? observedAt
1846
+ },
1847
+ now
1848
+ );
1849
+ }
1850
+ if (normalizedStatus === "queued") {
1851
+ return projection(
1852
+ {
1853
+ schemaVersion: 1,
1854
+ activityId: "capacity:worker",
1855
+ target: { kind: "capacity", pool: "worker" },
1856
+ state: { kind: "queued", reason: "capacity" },
1857
+ observedAt
1858
+ },
1859
+ now
1860
+ );
1861
+ }
1862
+ const fallback = {
1863
+ schemaVersion: 1,
1864
+ activityId: "run:legacy",
1865
+ target: {
1866
+ kind: "step",
1867
+ stepId: input2.activeNodeId ?? "run",
1868
+ label: input2.playName ?? "play"
1869
+ },
1870
+ state: normalizedStatus === "waiting" ? { kind: "waiting", reason: { kind: "unknown" } } : { kind: "active" },
1871
+ observedAt
1872
+ };
1873
+ return projection(fallback, now, normalizedStatus !== "waiting");
1874
+ }
1875
+
1608
1876
  // ../shared_libs/play-runtime/run-ledger.ts
1609
1877
  var LOG_TAIL_LIMIT = 100;
1610
- function isRecord(value) {
1878
+ function isRecord2(value) {
1611
1879
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
1612
1880
  }
1613
1881
  function finiteNumber(value) {
@@ -1691,30 +1959,33 @@ function createEmptyPlayRunLedgerSnapshot(input2) {
1691
1959
  stepsById: {},
1692
1960
  orderedDatasetIds: [],
1693
1961
  datasetsById: {},
1962
+ orderedActivityIds: [],
1963
+ activitiesById: {},
1694
1964
  logTail: [],
1695
1965
  totalLogCount: 0,
1696
1966
  logsTruncated: false,
1697
1967
  activeStepId: null,
1968
+ activeActivityId: null,
1698
1969
  activeArtifactTableNamespace: null,
1699
1970
  resultTableNamespace: null
1700
1971
  };
1701
1972
  }
1702
1973
  function normalizePlayRunLedgerSnapshot(value, fallback) {
1703
- if (!isRecord(value)) {
1974
+ if (!isRecord2(value)) {
1704
1975
  return createEmptyPlayRunLedgerSnapshot(fallback);
1705
1976
  }
1706
1977
  const orderedStepIds = Array.isArray(value.orderedStepIds) ? value.orderedStepIds.filter(
1707
1978
  (entry) => typeof entry === "string" && Boolean(entry.trim())
1708
1979
  ) : [];
1709
- const rawSteps = isRecord(value.stepsById) ? value.stepsById : {};
1980
+ const rawSteps = isRecord2(value.stepsById) ? value.stepsById : {};
1710
1981
  const stepsById = {};
1711
1982
  for (const [stepId, rawStep] of Object.entries(rawSteps)) {
1712
- if (!stepId.trim() || !isRecord(rawStep)) continue;
1983
+ if (!stepId.trim() || !isRecord2(rawStep)) continue;
1713
1984
  const rawStatus = normalizeStepStatus(rawStep.status);
1714
1985
  if (!rawStatus) continue;
1715
1986
  const completedAt = finiteNumber(rawStep.completedAt);
1716
1987
  const status = rawStatus === "running" && completedAt !== null ? "completed" : rawStatus;
1717
- const rawProgress = isRecord(rawStep.progress) ? rawStep.progress : null;
1988
+ const rawProgress = isRecord2(rawStep.progress) ? rawStep.progress : null;
1718
1989
  stepsById[stepId] = {
1719
1990
  stepId,
1720
1991
  label: optionalString(rawStep.label),
@@ -1730,10 +2001,10 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1730
2001
  progress: rawProgress ? normalizeStepProgress(rawProgress) : null
1731
2002
  };
1732
2003
  }
1733
- const rawDatasets = isRecord(value.datasetsById) ? value.datasetsById : {};
2004
+ const rawDatasets = isRecord2(value.datasetsById) ? value.datasetsById : {};
1734
2005
  const datasetsById = {};
1735
2006
  for (const [datasetId, rawDataset] of Object.entries(rawDatasets)) {
1736
- if (!datasetId.trim() || !isRecord(rawDataset)) continue;
2007
+ if (!datasetId.trim() || !isRecord2(rawDataset)) continue;
1737
2008
  const phase = rawDataset.phase === "available" || rawDataset.phase === "failed" ? rawDataset.phase : "registered";
1738
2009
  datasetsById[datasetId] = {
1739
2010
  datasetId,
@@ -1747,6 +2018,13 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1747
2018
  updatedAt: finiteNumber(rawDataset.updatedAt) ?? 0
1748
2019
  };
1749
2020
  }
2021
+ const rawActivities = isRecord2(value.activitiesById) ? value.activitiesById : {};
2022
+ const activitiesById = {};
2023
+ for (const [activityId, rawActivity] of Object.entries(rawActivities)) {
2024
+ if (activityId.trim() && isPlayActivityObservation(rawActivity) && rawActivity.activityId === activityId) {
2025
+ activitiesById[activityId] = rawActivity;
2026
+ }
2027
+ }
1750
2028
  const createdAt = finiteNumber(value.createdAt) ?? fallback.createdAt ?? null;
1751
2029
  const startedAt = finiteNumber(value.startedAt) ?? fallback.startedAt ?? null;
1752
2030
  const finishedAt = finiteNumber(value.finishedAt) ?? fallback.finishedAt ?? null;
@@ -1770,6 +2048,10 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1770
2048
  (datasetId) => typeof datasetId === "string" && Boolean(datasetsById[datasetId])
1771
2049
  ),
1772
2050
  datasetsById,
2051
+ orderedActivityIds: (Array.isArray(value.orderedActivityIds) ? value.orderedActivityIds : Object.keys(activitiesById)).filter(
2052
+ (activityId) => typeof activityId === "string" && Boolean(activitiesById[activityId])
2053
+ ),
2054
+ activitiesById,
1773
2055
  logTail: logTail.slice(-LOG_TAIL_LIMIT),
1774
2056
  // Snapshots persisted before totalLogCount existed only know the retained
1775
2057
  // tail, so the best lower bound for the cumulative count is the tail size.
@@ -1779,6 +2061,7 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1779
2061
  ),
1780
2062
  logsTruncated: value.logsTruncated === true,
1781
2063
  activeStepId: optionalNullableString(value.activeStepId),
2064
+ activeActivityId: optionalNullableString(value.activeActivityId),
1782
2065
  activeArtifactTableNamespace: optionalNullableString(
1783
2066
  value.activeArtifactTableNamespace
1784
2067
  ),
@@ -1865,18 +2148,18 @@ function normalizePlayRunLiveStatus(value) {
1865
2148
  function isTerminalPlayRunLiveStatus(status) {
1866
2149
  return isTerminalPlayRunLifecycleStatus(status);
1867
2150
  }
1868
- function isRecord2(value) {
2151
+ function isRecord3(value) {
1869
2152
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
1870
2153
  }
1871
2154
  function finiteNumber2(value) {
1872
2155
  return typeof value === "number" && Number.isFinite(value) ? value : null;
1873
2156
  }
1874
2157
  function extractTerminalRunLogTail(result) {
1875
- if (!isRecord2(result) || !isRecord2(result._metadata)) {
2158
+ if (!isRecord3(result) || !isRecord3(result._metadata)) {
1876
2159
  return null;
1877
2160
  }
1878
2161
  const runLogTail = result._metadata.runLogTail;
1879
- if (!isRecord2(runLogTail) || !Array.isArray(runLogTail.tail)) {
2162
+ if (!isRecord3(runLogTail) || !Array.isArray(runLogTail.tail)) {
1880
2163
  return null;
1881
2164
  }
1882
2165
  const logTail = runLogTail.tail.filter(
@@ -1936,6 +2219,10 @@ function buildSnapshotFromLedger(snapshot) {
1936
2219
  datasets: snapshot.orderedDatasetIds.map((datasetId) => snapshot.datasetsById[datasetId]).filter(
1937
2220
  (dataset) => Boolean(dataset)
1938
2221
  ),
2222
+ activities: snapshot.orderedActivityIds.map((activityId) => snapshot.activitiesById[activityId]).filter(
2223
+ (activity) => Boolean(activity)
2224
+ ),
2225
+ activeActivity: snapshot.activeActivityId ? snapshot.activitiesById[snapshot.activeActivityId] ?? null : null,
1939
2226
  nodeStates,
1940
2227
  activeNodeId: snapshot.activeStepId ?? null,
1941
2228
  ...rowOutcomes ? { rowOutcomes } : {}
@@ -1952,14 +2239,29 @@ function buildPlayRunStatusSnapshot(input2) {
1952
2239
  finishedAt: input2.run.finishedAt ?? null
1953
2240
  });
1954
2241
  const terminalRunLogTail = extractTerminalRunLogTail(input2.run.result);
1955
- if (terminalRunLogTail && terminalRunLogTail.totalLogCount > ledgerSnapshot.totalLogCount) {
1956
- return buildSnapshotFromLedger({
1957
- ...ledgerSnapshot,
1958
- logTail: terminalRunLogTail.logTail,
1959
- totalLogCount: terminalRunLogTail.totalLogCount
1960
- });
1961
- }
1962
- return buildSnapshotFromLedger(ledgerSnapshot);
2242
+ const projectedSnapshot = terminalRunLogTail && terminalRunLogTail.totalLogCount > ledgerSnapshot.totalLogCount ? buildSnapshotFromLedger({
2243
+ ...ledgerSnapshot,
2244
+ logTail: terminalRunLogTail.logTail,
2245
+ totalLogCount: terminalRunLogTail.totalLogCount
2246
+ }) : buildSnapshotFromLedger(ledgerSnapshot);
2247
+ const activity = projectPlayRunActivity({
2248
+ runId: input2.run.workflowId,
2249
+ playName: input2.run.name,
2250
+ status: projectedSnapshot.status,
2251
+ updatedAt: projectedSnapshot.updatedAt,
2252
+ waitKind: input2.run.waitKind ?? input2.run.wait?.kind ?? null,
2253
+ waitUntil: input2.run.waitUntil,
2254
+ eventKey: input2.run.wait?.eventKey ?? null,
2255
+ runtimeBackend: input2.run.runtimeBackend,
2256
+ activeNodeId: input2.run.activeBoundaryId ?? projectedSnapshot.activeNodeId,
2257
+ nodeStates: projectedSnapshot.nodeStates,
2258
+ datasets: projectedSnapshot.datasets,
2259
+ explicit: projectedSnapshot.activities
2260
+ });
2261
+ return {
2262
+ ...projectedSnapshot,
2263
+ activity
2264
+ };
1963
2265
  }
1964
2266
  function makeRunStreamEvent(input2) {
1965
2267
  return {
@@ -2180,7 +2482,8 @@ function diffPlayRunStreamEvents(input2) {
2180
2482
  payload: {
2181
2483
  runId: snapshot.runId,
2182
2484
  status: snapshot.status,
2183
- updatedAt: snapshot.updatedAt
2485
+ updatedAt: snapshot.updatedAt,
2486
+ ...snapshot.activity ? { activity: snapshot.activity } : {}
2184
2487
  }
2185
2488
  })
2186
2489
  );
@@ -2700,7 +3003,7 @@ function resolveToolExecuteTimeoutMs(toolId, input2) {
2700
3003
  }
2701
3004
  var RUNS_FAILED_LOG_LIMIT = 20;
2702
3005
  var RUN_LOGS_PAGE_LIMIT = 1e3;
2703
- function isRecord3(value) {
3006
+ function isRecord4(value) {
2704
3007
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
2705
3008
  }
2706
3009
  function isPrebuiltPlayDescription(play) {
@@ -2857,7 +3160,7 @@ function updatePlayLiveStatusState(state, event) {
2857
3160
  }
2858
3161
  const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : isPlayRunPackage(payload) ? payload.run.id : state.runId;
2859
3162
  const status = normalizeLiveStatus(payload.status) ?? (isPlayRunPackage(payload) ? normalizeLiveStatus(payload.run.status) : null) ?? state.status;
2860
- const progressPayload = isRecord3(payload.progress) ? payload.progress : {};
3163
+ const progressPayload = isRecord4(payload.progress) ? payload.progress : {};
2861
3164
  if (event.type === "play.run.final_status" && state.logs.length === 0 && state.lastLogSeq === 0) {
2862
3165
  const payloadLogs = readStringArray(payload.logs);
2863
3166
  const progressLogs = readStringArray(progressPayload.logs);
@@ -2991,9 +3294,9 @@ var DeeplineClient = class {
2991
3294
  return fields.length > 0 ? { fields } : schema;
2992
3295
  }
2993
3296
  schemaMetadata(schema, key) {
2994
- if (!isRecord3(schema)) return null;
3297
+ if (!isRecord4(schema)) return null;
2995
3298
  const value = schema[key];
2996
- return isRecord3(value) ? value : null;
3299
+ return isRecord4(value) ? value : null;
2997
3300
  }
2998
3301
  playRunCommand(play, options) {
2999
3302
  const target = play.reference || play.name;
@@ -3042,7 +3345,7 @@ var DeeplineClient = class {
3042
3345
  aliases,
3043
3346
  inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
3044
3347
  outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
3045
- staticPipeline: isRecord3(play.staticPipeline) ? play.staticPipeline : isRecord3(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord3(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
3348
+ staticPipeline: isRecord4(play.staticPipeline) ? play.staticPipeline : isRecord4(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord4(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
3046
3349
  ...csvInput ? { csvInput } : {},
3047
3350
  ...rowOutputSchema ? { rowOutputSchema } : {},
3048
3351
  runCommand: runCommand2,
@@ -3120,6 +3423,14 @@ var DeeplineClient = class {
3120
3423
  );
3121
3424
  return res.tools;
3122
3425
  }
3426
+ /** List discoverable providers without requiring a local plugin catalog. */
3427
+ async listProviders(options) {
3428
+ const suffix = options?.changed ? "?changed=true" : "";
3429
+ const res = await this.http.get(
3430
+ `/api/v2/tools/providers${suffix}`
3431
+ );
3432
+ return res.providers;
3433
+ }
3123
3434
  /**
3124
3435
  * Search available tools using Deepline's ranked backend search.
3125
3436
  *
@@ -7859,14 +8170,14 @@ function sanitizeCsvProjectionInfo(input2) {
7859
8170
  const rows = input2.rows.map(stripCsvProjectionFields);
7860
8171
  return { rows, columns };
7861
8172
  }
7862
- function isRecord4(value) {
8173
+ function isRecord5(value) {
7863
8174
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
7864
8175
  }
7865
8176
  function isSerializedDataset(value) {
7866
- return isRecord4(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
8177
+ return isRecord5(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
7867
8178
  }
7868
8179
  function isPackagedDatasetOutput(value) {
7869
- return isRecord4(value) && value.kind === "dataset" && isRecord4(value.preview) && Array.isArray(value.preview.rows);
8180
+ return isRecord5(value) && value.kind === "dataset" && isRecord5(value.preview) && Array.isArray(value.preview.rows);
7870
8181
  }
7871
8182
  function pathParts(path) {
7872
8183
  return path.split(".").map((part) => part.trim()).filter(Boolean);
@@ -7874,7 +8185,7 @@ function pathParts(path) {
7874
8185
  function valueAtPath(root, path) {
7875
8186
  let cursor = root;
7876
8187
  for (const part of pathParts(path)) {
7877
- if (!isRecord4(cursor)) {
8188
+ if (!isRecord5(cursor)) {
7878
8189
  return void 0;
7879
8190
  }
7880
8191
  cursor = cursor[part];
@@ -7882,17 +8193,17 @@ function valueAtPath(root, path) {
7882
8193
  return cursor;
7883
8194
  }
7884
8195
  function totalRowsForDataset(result, datasetPath) {
7885
- const metadata = isRecord4(result._metadata) ? result._metadata : null;
8196
+ const metadata = isRecord5(result._metadata) ? result._metadata : null;
7886
8197
  const parentPath = datasetPath.split(".").slice(0, -1).join(".");
7887
8198
  const parent = parentPath ? valueAtPath({ result }, parentPath) : result;
7888
- return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord4(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
8199
+ return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord5(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
7889
8200
  }
7890
8201
  function rowArray(value) {
7891
8202
  if (!Array.isArray(value)) {
7892
8203
  return null;
7893
8204
  }
7894
8205
  const rows = value.filter(
7895
- (row) => isRecord4(row)
8206
+ (row) => isRecord5(row)
7896
8207
  );
7897
8208
  return rows.length === value.length ? rows : null;
7898
8209
  }
@@ -7916,7 +8227,7 @@ function inferColumns(rows) {
7916
8227
  return columns;
7917
8228
  }
7918
8229
  function columnsFromDatasetSummary(summary) {
7919
- if (!isRecord4(summary) || !isRecord4(summary.columnStats)) {
8230
+ if (!isRecord5(summary) || !isRecord5(summary.columnStats)) {
7920
8231
  return [];
7921
8232
  }
7922
8233
  return Object.keys(summary.columnStats).filter((column) => column);
@@ -7964,7 +8275,7 @@ function canonicalRowsInfoFromCandidate(input2) {
7964
8275
  datasetId: typeof candidate.value.datasetId === "string" ? candidate.value.datasetId : null,
7965
8276
  tableNamespace: typeof candidate.value.tableNamespace === "string" ? candidate.value.tableNamespace : null,
7966
8277
  ...candidate.value.recovered === true ? { recovered: true } : {},
7967
- ...isRecord4(candidate.value.exportUnavailable) && (candidate.value.exportUnavailable.reason === "empty_dataset" || candidate.value.exportUnavailable.reason === "shared_table_namespace") ? {
8278
+ ...isRecord5(candidate.value.exportUnavailable) && (candidate.value.exportUnavailable.reason === "empty_dataset" || candidate.value.exportUnavailable.reason === "shared_table_namespace") ? {
7968
8279
  exportUnavailableReason: candidate.value.exportUnavailable.reason,
7969
8280
  ...typeof candidate.value.exportUnavailable.message === "string" ? {
7970
8281
  exportUnavailableMessage: candidate.value.exportUnavailable.message
@@ -8012,7 +8323,7 @@ function collectDatasetCandidates(input2) {
8012
8323
  });
8013
8324
  return;
8014
8325
  }
8015
- if (!isRecord4(input2.value)) {
8326
+ if (!isRecord5(input2.value)) {
8016
8327
  return;
8017
8328
  }
8018
8329
  for (const [key, child] of Object.entries(input2.value)) {
@@ -8029,12 +8340,12 @@ function collectDatasetCandidates(input2) {
8029
8340
  }
8030
8341
  }
8031
8342
  function collectCanonicalRowsInfos(statusOrResult) {
8032
- const root = isRecord4(statusOrResult) ? statusOrResult : null;
8033
- const result = isRecord4(root?.result) ? root.result : root;
8343
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
8344
+ const result = isRecord5(root?.result) ? root.result : root;
8034
8345
  if (!result) {
8035
8346
  return [];
8036
8347
  }
8037
- const metadata = isRecord4(result._metadata) ? result._metadata : null;
8348
+ const metadata = isRecord5(result._metadata) ? result._metadata : null;
8038
8349
  const totalFromMetadata = metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count;
8039
8350
  const candidates = [
8040
8351
  {
@@ -8058,8 +8369,8 @@ function collectCanonicalRowsInfos(statusOrResult) {
8058
8369
  total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
8059
8370
  }
8060
8371
  ];
8061
- if (isRecord4(result.output)) {
8062
- const outputMetadata = isRecord4(result.output._metadata) ? result.output._metadata : null;
8372
+ if (isRecord5(result.output)) {
8373
+ const outputMetadata = isRecord5(result.output._metadata) ? result.output._metadata : null;
8063
8374
  const outputTotalFromMetadata = outputMetadata?.totalRows ?? outputMetadata?.rowCount ?? outputMetadata?.count;
8064
8375
  candidates.push(
8065
8376
  {
@@ -8086,14 +8397,14 @@ function collectCanonicalRowsInfos(statusOrResult) {
8086
8397
  }
8087
8398
  if (Array.isArray(result.steps)) {
8088
8399
  result.steps.forEach((step, index) => {
8089
- if (!isRecord4(step) || !isRecord4(step.output)) {
8400
+ if (!isRecord5(step) || !isRecord5(step.output)) {
8090
8401
  return;
8091
8402
  }
8092
8403
  const source = typeof step.output.path === "string" ? step.output.path : typeof step.id === "string" ? `steps.${step.id}.output` : `steps.${index}.output`;
8093
8404
  candidates.push({
8094
8405
  source,
8095
8406
  value: step.output,
8096
- total: step.output.rowCount ?? (isRecord4(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord4(step.progress) ? step.progress.total : void 0)
8407
+ total: step.output.rowCount ?? (isRecord5(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord5(step.progress) ? step.progress.total : void 0)
8097
8408
  });
8098
8409
  });
8099
8410
  }
@@ -8121,15 +8432,15 @@ function collectCanonicalRowsInfos(statusOrResult) {
8121
8432
  return infos;
8122
8433
  }
8123
8434
  function collectPackagedDatasetCandidates(statusOrResult) {
8124
- const root = isRecord4(statusOrResult) ? statusOrResult : null;
8435
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
8125
8436
  if (!root) {
8126
8437
  return [];
8127
8438
  }
8128
- const pkg = isRecord4(root.package) ? root.package : root;
8439
+ const pkg = isRecord5(root.package) ? root.package : root;
8129
8440
  const datasets = Array.isArray(pkg.datasets) ? pkg.datasets : [];
8130
8441
  const candidates = [];
8131
8442
  for (const output2 of datasets) {
8132
- if (!isRecord4(output2) || !isPackagedDatasetOutput(output2)) {
8443
+ if (!isRecord5(output2) || !isPackagedDatasetOutput(output2)) {
8133
8444
  continue;
8134
8445
  }
8135
8446
  const source = typeof output2.path === "string" && output2.path.trim() ? output2.path.trim() : null;
@@ -8139,18 +8450,18 @@ function collectPackagedDatasetCandidates(statusOrResult) {
8139
8450
  candidates.push({
8140
8451
  source,
8141
8452
  value: output2,
8142
- total: output2.rowCount ?? (isRecord4(output2.preview) ? output2.preview.totalRows : void 0)
8453
+ total: output2.rowCount ?? (isRecord5(output2.preview) ? output2.preview.totalRows : void 0)
8143
8454
  });
8144
8455
  }
8145
8456
  return candidates;
8146
8457
  }
8147
8458
  function collectPackagedStepDatasetCandidates(statusOrResult) {
8148
- const root = isRecord4(statusOrResult) ? statusOrResult : null;
8459
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
8149
8460
  if (!root) return [];
8150
- const pkg = isRecord4(root.package) ? root.package : root;
8461
+ const pkg = isRecord5(root.package) ? root.package : root;
8151
8462
  const steps = Array.isArray(pkg.steps) ? pkg.steps : [];
8152
8463
  return steps.flatMap((step) => {
8153
- if (!isRecord4(step) || !isPackagedDatasetOutput(step.output)) return [];
8464
+ if (!isRecord5(step) || !isPackagedDatasetOutput(step.output)) return [];
8154
8465
  const source = typeof step.output.path === "string" && step.output.path.trim() ? step.output.path.trim() : null;
8155
8466
  return source ? [
8156
8467
  {
@@ -8162,8 +8473,8 @@ function collectPackagedStepDatasetCandidates(statusOrResult) {
8162
8473
  });
8163
8474
  }
8164
8475
  function collectSerializedDatasetRowsInfos(statusOrResult) {
8165
- const root = isRecord4(statusOrResult) ? statusOrResult : null;
8166
- const result = isRecord4(root?.result) ? root.result : root;
8476
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
8477
+ const result = isRecord5(root?.result) ? root.result : root;
8167
8478
  const candidates = [];
8168
8479
  if (result) {
8169
8480
  collectDatasetCandidates({
@@ -8171,7 +8482,7 @@ function collectSerializedDatasetRowsInfos(statusOrResult) {
8171
8482
  path: "result",
8172
8483
  output: candidates
8173
8484
  });
8174
- if (isRecord4(result.output)) {
8485
+ if (isRecord5(result.output)) {
8175
8486
  collectDatasetCandidates({
8176
8487
  value: result.output,
8177
8488
  path: "result",
@@ -8249,13 +8560,13 @@ function summarizeSampleValue(value, depth = 0) {
8249
8560
  if (typeof parsed === "number" || typeof parsed === "boolean") return parsed;
8250
8561
  if (depth >= 3) {
8251
8562
  if (Array.isArray(parsed)) return [];
8252
- if (isRecord4(parsed)) return {};
8563
+ if (isRecord5(parsed)) return {};
8253
8564
  return compactScalar(parsed);
8254
8565
  }
8255
8566
  if (Array.isArray(parsed)) {
8256
8567
  return parsed.slice(0, 3).map((item) => summarizeSampleValue(item, depth + 1));
8257
8568
  }
8258
- if (isRecord4(parsed)) {
8569
+ if (isRecord5(parsed)) {
8259
8570
  const out = {};
8260
8571
  for (const [key, nested] of Object.entries(parsed)) {
8261
8572
  if (["__dl", "meta", "metadata"].includes(key)) {
@@ -8286,7 +8597,7 @@ function compactCell(value) {
8286
8597
  }
8287
8598
  return `[${parsed.length} items]`;
8288
8599
  }
8289
- if (isRecord4(parsed)) {
8600
+ if (isRecord5(parsed)) {
8290
8601
  for (const key of ["matched_result", "output"]) {
8291
8602
  if (parsed[key] !== null && parsed[key] !== void 0 && parsed[key] !== "") {
8292
8603
  return compactCell(parsed[key]);
@@ -9351,17 +9662,17 @@ function parsePositiveInteger2(value, flagName) {
9351
9662
  }
9352
9663
  return parsed;
9353
9664
  }
9354
- function isRecord5(value) {
9665
+ function isRecord6(value) {
9355
9666
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
9356
9667
  }
9357
9668
  function stringValue(value) {
9358
9669
  return typeof value === "string" ? value.trim() : "";
9359
9670
  }
9360
9671
  function extractionEntries(value) {
9361
- if (Array.isArray(value)) return value.filter(isRecord5);
9362
- if (!isRecord5(value)) return [];
9672
+ if (Array.isArray(value)) return value.filter(isRecord6);
9673
+ if (!isRecord6(value)) return [];
9363
9674
  return Object.entries(value).map(
9364
- ([name, entry]) => isRecord5(entry) ? { name, ...entry } : { name }
9675
+ ([name, entry]) => isRecord6(entry) ? { name, ...entry } : { name }
9365
9676
  );
9366
9677
  }
9367
9678
  var PlayBootstrapError = class extends Error {
@@ -9923,7 +10234,7 @@ function readCsvSampleRows(sample) {
9923
10234
  relax_column_count: true,
9924
10235
  trim: true
9925
10236
  });
9926
- return Array.isArray(parsedRows) ? parsedRows.filter(isRecord5) : [];
10237
+ return Array.isArray(parsedRows) ? parsedRows.filter(isRecord6) : [];
9927
10238
  }
9928
10239
  function readSourceCsvColumnSpecs(csvPath) {
9929
10240
  const sample = readCsvSample(csvPath);
@@ -9956,16 +10267,16 @@ function packagedCsvPathForPlay(csvPath) {
9956
10267
  return portablePath.startsWith(".") ? portablePath : `./${portablePath}`;
9957
10268
  }
9958
10269
  function getterNamesFromTool(tool, kind) {
9959
- const usageGuidance = isRecord5(tool?.usageGuidance) ? tool.usageGuidance : {};
9960
- const resultGuidance = isRecord5(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord5(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
10270
+ const usageGuidance = isRecord6(tool?.usageGuidance) ? tool.usageGuidance : {};
10271
+ const resultGuidance = isRecord6(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord6(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
9961
10272
  const key = kind === "list" ? "extractedLists" : "extractedValues";
9962
10273
  const snakeKey = kind === "list" ? "extracted_lists" : "extracted_values";
9963
10274
  return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
9964
10275
  }
9965
10276
  function targetGettersFromTool(tool) {
9966
- const record = isRecord5(tool) ? tool : {};
10277
+ const record = isRecord6(tool) ? tool : {};
9967
10278
  const raw = record.targetGetters ?? record.target_getters;
9968
- if (!isRecord5(raw)) return {};
10279
+ if (!isRecord6(raw)) return {};
9969
10280
  const entries = [];
9970
10281
  for (const [target, value] of Object.entries(raw)) {
9971
10282
  const paths = Array.isArray(value) ? value.map((path) => typeof path === "string" ? path.trim() : "").filter(Boolean) : [];
@@ -9986,10 +10297,10 @@ function listRowCandidateKeysFromTool(tool) {
9986
10297
  return [...keys].sort();
9987
10298
  }
9988
10299
  function inputPropertyNames(schema) {
9989
- if (!isRecord5(schema)) return [];
9990
- if (isRecord5(schema.properties)) return Object.keys(schema.properties);
10300
+ if (!isRecord6(schema)) return [];
10301
+ if (isRecord6(schema.properties)) return Object.keys(schema.properties);
9991
10302
  if (Array.isArray(schema.fields)) {
9992
- return schema.fields.filter(isRecord5).map((field) => stringValue(field.name)).filter(Boolean);
10303
+ return schema.fields.filter(isRecord6).map((field) => stringValue(field.name)).filter(Boolean);
9993
10304
  }
9994
10305
  return [];
9995
10306
  }
@@ -10003,7 +10314,7 @@ function schemaFieldDetails(schema) {
10003
10314
  return { required, optional };
10004
10315
  }
10005
10316
  function jsonSchemaTypeExpression(schema) {
10006
- if (!isRecord5(schema)) return "unknown";
10317
+ if (!isRecord6(schema)) return "unknown";
10007
10318
  const type = schema.type;
10008
10319
  if (Array.isArray(type)) {
10009
10320
  return type.map((entry) => jsonSchemaTypeExpression({ ...schema, type: entry })).join(" | ");
@@ -10033,7 +10344,7 @@ function jsonSchemaTypeExpression(schema) {
10033
10344
  }
10034
10345
  }
10035
10346
  function objectPropertySchema(schema, property) {
10036
- return isRecord5(schema) && isRecord5(schema.properties) ? schema.properties[property] : null;
10347
+ return isRecord6(schema) && isRecord6(schema.properties) ? schema.properties[property] : null;
10037
10348
  }
10038
10349
  function playOutputHasField(schema, field) {
10039
10350
  return objectPropertySchema(schema, field) != null;
@@ -10209,14 +10520,14 @@ ${indent2.slice(2)}}`;
10209
10520
  }
10210
10521
  function requiredPlayInputFields(play) {
10211
10522
  const schema = play?.inputSchema;
10212
- if (!isRecord5(schema)) return [];
10523
+ if (!isRecord6(schema)) return [];
10213
10524
  if (Array.isArray(schema.required)) {
10214
10525
  return schema.required.filter(
10215
10526
  (value) => typeof value === "string"
10216
10527
  );
10217
10528
  }
10218
10529
  if (Array.isArray(schema.fields)) {
10219
- return schema.fields.filter(isRecord5).filter(
10530
+ return schema.fields.filter(isRecord6).filter(
10220
10531
  (field) => field.required === true && typeof field.name === "string"
10221
10532
  ).map((field) => String(field.name));
10222
10533
  }
@@ -10397,7 +10708,7 @@ function validateBootstrapRoutes(input2) {
10397
10708
  }
10398
10709
  }
10399
10710
  function staticPipelineSubsteps(pipeline) {
10400
- if (!isRecord5(pipeline)) return [];
10711
+ if (!isRecord6(pipeline)) return [];
10401
10712
  return [
10402
10713
  ...extractionEntries(pipeline.stages),
10403
10714
  ...extractionEntries(pipeline.substeps)
@@ -10405,7 +10716,7 @@ function staticPipelineSubsteps(pipeline) {
10405
10716
  }
10406
10717
  function playUsesMapBackedRuntime(play) {
10407
10718
  const pipeline = play?.staticPipeline;
10408
- if (!isRecord5(pipeline)) return false;
10719
+ if (!isRecord6(pipeline)) return false;
10409
10720
  if (stringValue(pipeline.tableNamespace)) return true;
10410
10721
  return staticPipelineSubsteps(pipeline).some((substep) => {
10411
10722
  if (stringValue(substep.type) === "map") return true;
@@ -10414,7 +10725,7 @@ function playUsesMapBackedRuntime(play) {
10414
10725
  aliases: [],
10415
10726
  runCommand: "",
10416
10727
  examples: [],
10417
- staticPipeline: isRecord5(substep.pipeline) ? substep.pipeline : null
10728
+ staticPipeline: isRecord6(substep.pipeline) ? substep.pipeline : null
10418
10729
  });
10419
10730
  });
10420
10731
  }
@@ -12537,22 +12848,96 @@ function getStatusFromLiveEvent(event) {
12537
12848
  const payload = getEventPayload(event);
12538
12849
  return playStatusValue(payload.status) ?? playStatusValue(getRunRecordFromPackage(payload)?.status);
12539
12850
  }
12540
- function getWaitKindFromLiveEvent(event) {
12851
+ function readLiveRunField(event, field) {
12541
12852
  const payload = getEventPayload(event);
12542
- const progress = payload.progress && typeof payload.progress === "object" ? payload.progress : null;
12543
- const waitKind = payload.waitKind ?? progress?.waitKind;
12544
- return typeof waitKind === "string" && waitKind.trim() ? waitKind.trim() : null;
12853
+ const run = getRunRecordFromPackage(payload);
12854
+ const records = [payload, payload.progress, run, run?.progress].filter(
12855
+ (value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
12856
+ );
12857
+ for (const record of records) {
12858
+ if (record[field] !== void 0) return record[field];
12859
+ }
12860
+ return void 0;
12545
12861
  }
12546
- function writePlayWaitingHint(input2) {
12547
- if (getStatusFromLiveEvent(input2.event) !== "waiting") return;
12862
+ function getLiveRunStringField(event, field) {
12863
+ const value = readLiveRunField(event, field);
12864
+ return typeof value === "string" && value.trim() ? value.trim() : null;
12865
+ }
12866
+ function getLiveRunActivity(event) {
12867
+ const payload = getEventPayload(event);
12868
+ const run = getRunRecordFromPackage(payload);
12869
+ const candidates = [payload.activity, run?.activity];
12870
+ for (const candidate of candidates) {
12871
+ if (candidate && typeof candidate === "object" && !Array.isArray(candidate) && typeof candidate.summary === "string" && candidate.observation && typeof candidate.observation === "object") {
12872
+ return candidate;
12873
+ }
12874
+ }
12875
+ return null;
12876
+ }
12877
+ function getRunLifecycleHint(input2) {
12548
12878
  const runId = getRunIdFromLiveEvent(input2.event);
12549
- if (!runId || input2.state.waitingRunId === runId) return;
12550
- input2.state.waitingRunId = runId;
12551
- const waitKind = getWaitKindFromLiveEvent(input2.event);
12552
- const message = waitKind === "integration_event" || waitKind === "integration_event_batch" ? "is waiting for an external event." : waitKind === "sleep" ? "is waiting for its scheduled resume." : waitKind === "detached_runner" ? "is executing in the runtime." : "is waiting on a durable runtime boundary.";
12553
- input2.progress.writeLine(
12554
- `[play waiting] ${runId} ${message} The command will continue watching; inspect it with 'deepline runs get ${runId} --full --json'.`
12879
+ const status = getStatusFromLiveEvent(input2.event);
12880
+ if (!runId || status !== "queued" && status !== "running" && status !== "waiting") {
12881
+ return null;
12882
+ }
12883
+ const activity = getLiveRunActivity(input2.event);
12884
+ const activityConflictsWithDurableWait = status === "waiting" && activity?.observation.state.kind === "active" && activity.observation.target.kind !== "runner";
12885
+ if (activity && activity.classified !== false && !activityConflictsWithDurableWait) {
12886
+ const state = activity.observation.state;
12887
+ const signature2 = [
12888
+ runId,
12889
+ "activity",
12890
+ activity.observation.activityId,
12891
+ JSON.stringify(state)
12892
+ ].join(":");
12893
+ const inspect2 = `'deepline runs get ${runId} --full --json'`;
12894
+ const followUp = state.kind === "active" ? `The command will keep watching; if no new evidence arrives, check again in ~5 minutes with ${inspect2}.` : `The command will continue watching; inspect it with ${inspect2}.`;
12895
+ return {
12896
+ signature: signature2,
12897
+ line: `[play activity] ${runId} ${activity.summary} ${followUp}`
12898
+ };
12899
+ }
12900
+ const waitKind = getLiveRunStringField(input2.event, "waitKind");
12901
+ const activeBoundaryId = getLiveRunStringField(
12902
+ input2.event,
12903
+ "activeBoundaryId"
12555
12904
  );
12905
+ const signature = [
12906
+ runId,
12907
+ status,
12908
+ waitKind ?? "",
12909
+ activeBoundaryId ?? ""
12910
+ ].join(":");
12911
+ const inspect = `'deepline runs get ${runId} --full --json'`;
12912
+ if (waitKind === "detached_runner") {
12913
+ return {
12914
+ signature,
12915
+ line: `[play running] ${runId} is executing in a managed runtime (the runner started and connected its receipt gateway). This can take several minutes. The command will keep watching; if no new update arrives, check again in ~5 minutes with ${inspect}.`
12916
+ };
12917
+ }
12918
+ if (status !== "waiting") return null;
12919
+ if (waitKind === "sleep") {
12920
+ return {
12921
+ signature,
12922
+ line: `[play waiting] ${runId} is sleeping until its scheduled resume. The command will continue watching; inspect it with ${inspect}.`
12923
+ };
12924
+ }
12925
+ if (waitKind === "integration_event" || waitKind === "integration_event_batch" || waitKind === null) {
12926
+ return {
12927
+ signature,
12928
+ line: `[play waiting] ${runId} is waiting for an external approval or event. The command will continue watching; inspect it with ${inspect}.`
12929
+ };
12930
+ }
12931
+ return {
12932
+ signature,
12933
+ line: `[play waiting] ${runId} is paused on durable work (${waitKind}). The command will continue watching; inspect it with ${inspect}.`
12934
+ };
12935
+ }
12936
+ function writePlayWaitingHint(input2) {
12937
+ const hint = getRunLifecycleHint({ event: input2.event });
12938
+ if (!hint || input2.state.lifecycleHintSignature === hint.signature) return;
12939
+ input2.state.lifecycleHintSignature = hint.signature;
12940
+ input2.progress.writeLine(hint.line);
12556
12941
  }
12557
12942
  function getFinalStatusFromLiveEvent(event) {
12558
12943
  if (event.type !== "play.run.snapshot" && event.type !== "play.run.status" && event.type !== "play.run.final_status") {
@@ -12808,13 +13193,18 @@ function getRunningHeartbeatLine(input2) {
12808
13193
  if (status !== "queued" && status !== "running" && status !== "waiting") {
12809
13194
  return null;
12810
13195
  }
13196
+ const activity = getLiveRunActivity(input2.event);
13197
+ const activityConflictsWithDurableWait = status === "waiting" && activity?.observation.state.kind === "active" && activity.observation.target.kind !== "runner";
13198
+ if (activity && activity.classified !== false && !activityConflictsWithDurableWait) {
13199
+ return `activity ${input2.playName}: ${activity.summary}`;
13200
+ }
12811
13201
  const tableNamespace = extractTableNamespaceFromLiveEvent(input2.event);
12812
13202
  const target = tableNamespace ? formatProgressLabel(tableNamespace) : input2.playName;
12813
13203
  if (status === "queued") {
12814
13204
  return `queued ${target}: waiting for worker capacity`;
12815
13205
  }
12816
13206
  if (status === "waiting") {
12817
- if (getWaitKindFromLiveEvent(input2.event) === "detached_runner") {
13207
+ if (getLiveRunStringField(input2.event, "waitKind") === "detached_runner") {
12818
13208
  return `running ${target}: executing in detached runtime`;
12819
13209
  }
12820
13210
  return `waiting ${target}: waiting on external work`;
@@ -15073,7 +15463,7 @@ function extractPlayValidationErrors(value) {
15073
15463
  if (value instanceof DeeplineError) {
15074
15464
  return extractPlayValidationErrors(value.details);
15075
15465
  }
15076
- if (!isRecord6(value)) {
15466
+ if (!isRecord7(value)) {
15077
15467
  return [];
15078
15468
  }
15079
15469
  const directErrors = stringArrayField(value, "errors");
@@ -15513,7 +15903,7 @@ function shouldUseLocalOnlyPlayCheck() {
15513
15903
  const value = process.env.DEEPLINE_PLAY_CHECK_LOCAL_ONLY?.trim().toLowerCase();
15514
15904
  return value === "1" || value === "true" || value === "yes" || value === "on";
15515
15905
  }
15516
- function isRecord6(value) {
15906
+ function isRecord7(value) {
15517
15907
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
15518
15908
  }
15519
15909
  function stringValue2(value) {
@@ -15523,14 +15913,14 @@ function asArray(value) {
15523
15913
  return Array.isArray(value) ? value : [];
15524
15914
  }
15525
15915
  function extractionEntries2(value) {
15526
- if (Array.isArray(value)) return value.filter(isRecord6);
15527
- if (!isRecord6(value)) return [];
15916
+ if (Array.isArray(value)) return value.filter(isRecord7);
15917
+ if (!isRecord7(value)) return [];
15528
15918
  return Object.entries(value).map(
15529
- ([name, entry]) => isRecord6(entry) ? { name, ...entry } : { name }
15919
+ ([name, entry]) => isRecord7(entry) ? { name, ...entry } : { name }
15530
15920
  );
15531
15921
  }
15532
15922
  function firstRawPath(entry) {
15533
- const details = isRecord6(entry.details) ? entry.details : {};
15923
+ const details = isRecord7(entry.details) ? entry.details : {};
15534
15924
  const paths = [
15535
15925
  ...asArray(details.rawToolOutputPaths),
15536
15926
  ...asArray(details.raw_tool_output_paths),
@@ -15548,12 +15938,12 @@ function checkHintRawPath(value) {
15548
15938
  function collectStaticPipelineToolIds(staticPipeline) {
15549
15939
  const seen = /* @__PURE__ */ new Set();
15550
15940
  const visitPipeline = (pipeline) => {
15551
- if (!isRecord6(pipeline)) return;
15941
+ if (!isRecord7(pipeline)) return;
15552
15942
  for (const step of [
15553
15943
  ...asArray(pipeline.stages),
15554
15944
  ...asArray(pipeline.substeps)
15555
15945
  ]) {
15556
- if (!isRecord6(step)) continue;
15946
+ if (!isRecord7(step)) continue;
15557
15947
  if (step.type === "tool") {
15558
15948
  const toolId = stringValue2(step.toolId) || stringValue2(step.tool);
15559
15949
  if (toolId) seen.add(toolId);
@@ -15567,9 +15957,9 @@ function collectStaticPipelineToolIds(staticPipeline) {
15567
15957
  return [...seen].sort();
15568
15958
  }
15569
15959
  function toolGetterHintFromMetadata(toolId, tool) {
15570
- const usageGuidance = isRecord6(tool.usageGuidance) ? tool.usageGuidance : {};
15571
- const resultGuidance = isRecord6(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord6(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
15572
- const toolResponse = isRecord6(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord6(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
15960
+ const usageGuidance = isRecord7(tool.usageGuidance) ? tool.usageGuidance : {};
15961
+ const resultGuidance = isRecord7(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord7(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
15962
+ const toolResponse = isRecord7(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord7(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
15573
15963
  const lists = extractionEntries2(
15574
15964
  resultGuidance.extractedLists ?? resultGuidance.extracted_lists
15575
15965
  ).map((entry) => ({
@@ -19819,7 +20209,7 @@ function isMarkedTestAiInferenceCommand(command) {
19819
20209
  if (normalizeEnrichPlayRef(command.tool) !== "run_javascript") {
19820
20210
  return false;
19821
20211
  }
19822
- return isRecord7(command.payload) && command.payload[ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER] === true;
20212
+ return isRecord8(command.payload) && command.payload[ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER] === true;
19823
20213
  }
19824
20214
  function enrichDebugEnabled(env = process.env) {
19825
20215
  const raw = String(env.DEEPLINE_DEBUG_ENRICH ?? "").trim().toLowerCase();
@@ -20083,7 +20473,7 @@ function rewriteGeneratedPlayRerunForEnrich(status, enrichCommand) {
20083
20473
  if (Array.isArray(value)) {
20084
20474
  return value.map(rewrite);
20085
20475
  }
20086
- if (!isRecord7(value)) {
20476
+ if (!isRecord8(value)) {
20087
20477
  return value;
20088
20478
  }
20089
20479
  const next = Object.fromEntries(
@@ -20092,7 +20482,7 @@ function rewriteGeneratedPlayRerunForEnrich(status, enrichCommand) {
20092
20482
  key === "rerunCommand" && typeof entry === "string" ? enrichCommand : rewrite(entry)
20093
20483
  ])
20094
20484
  );
20095
- if (isRecord7(next.next) && typeof next.next.run === "string") {
20485
+ if (isRecord8(next.next) && typeof next.next.run === "string") {
20096
20486
  next.next = { ...next.next, run: enrichCommand };
20097
20487
  }
20098
20488
  return next;
@@ -20563,7 +20953,7 @@ async function resolveWatchedGeneratedPlayStatus(input2) {
20563
20953
  }
20564
20954
  return input2.client.runs.get(runId, { full: true });
20565
20955
  }
20566
- function isRecord7(value) {
20956
+ function isRecord8(value) {
20567
20957
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
20568
20958
  }
20569
20959
  async function captureStdout(run, options = {}) {
@@ -20815,15 +21205,15 @@ function readFirstEnrichDatasetActions(value) {
20815
21205
  return null;
20816
21206
  }
20817
21207
  const record = candidate;
20818
- const actions = isRecord7(record.actions) ? record.actions : null;
20819
- const currentQuery = isRecord7(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
20820
- const legacyQuery = isRecord7(actions?.query) ? actions.query : null;
21208
+ const actions = isRecord8(record.actions) ? record.actions : null;
21209
+ const currentQuery = isRecord8(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
21210
+ const legacyQuery = isRecord8(actions?.query) ? actions.query : null;
20821
21211
  const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
20822
21212
  if (query?.kind === "deepline_db_query") {
20823
21213
  return {
20824
21214
  dataset: record,
20825
21215
  query,
20826
- ...isRecord7(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
21216
+ ...isRecord8(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
20827
21217
  };
20828
21218
  }
20829
21219
  if (options.allowLegacy && record.kind === "dataset" && typeof record.queryDatasetCommand === "string" && record.queryDatasetCommand.trim()) {
@@ -20876,7 +21266,7 @@ function enrichCustomerDbJson(input2) {
20876
21266
  const dataset = actions.dataset;
20877
21267
  const sql = actionStringField(query, "sql") ?? parseSqlFromDbQueryCommand(actions.queryDatasetCommand);
20878
21268
  const datasetPath = actionStringField(query, "datasetPath") ?? actionStringField(dataset, "path") ?? actionStringField(dataset, "tableNamespace");
20879
- const api = isRecord7(query.api) ? query.api : null;
21269
+ const api = isRecord8(query.api) ? query.api : null;
20880
21270
  const apiPath = actionStringField(api ?? {}, "path") ?? "/api/v2/db/query";
20881
21271
  const apiMethod = actionStringField(api ?? {}, "method") ?? "POST";
20882
21272
  if (!datasetPath) {
@@ -20945,11 +21335,11 @@ function sqlStringLiteral(value) {
20945
21335
  return `'${value.replace(/'/g, "''")}'`;
20946
21336
  }
20947
21337
  function failureAliasFromCellMeta(cellMeta) {
20948
- if (!isRecord7(cellMeta)) {
21338
+ if (!isRecord8(cellMeta)) {
20949
21339
  return null;
20950
21340
  }
20951
21341
  for (const [alias, meta] of Object.entries(cellMeta)) {
20952
- if (!isRecord7(meta)) {
21342
+ if (!isRecord8(meta)) {
20953
21343
  continue;
20954
21344
  }
20955
21345
  const failure = failureCellFromMeta(meta, {});
@@ -21442,7 +21832,7 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
21442
21832
  return fallback;
21443
21833
  }
21444
21834
  function failureCellFromMeta(meta, fallback) {
21445
- if (!isRecord7(meta)) {
21835
+ if (!isRecord8(meta)) {
21446
21836
  return null;
21447
21837
  }
21448
21838
  const status = typeof meta.status === "string" ? meta.status.trim().toLowerCase() : "";
@@ -21462,7 +21852,7 @@ function failureCellFromMeta(meta, fallback) {
21462
21852
  };
21463
21853
  }
21464
21854
  function applyFailureCellMeta(row, cellMeta, fallback) {
21465
- if (!isRecord7(cellMeta)) {
21855
+ if (!isRecord8(cellMeta)) {
21466
21856
  return;
21467
21857
  }
21468
21858
  for (const [field, meta] of Object.entries(cellMeta)) {
@@ -21690,7 +22080,7 @@ function stableRowSnapshot(value) {
21690
22080
  }
21691
22081
  function cellFailureError(value) {
21692
22082
  const parsed = parseMaybeJsonObject(value);
21693
- if (!isRecord7(parsed)) {
22083
+ if (!isRecord8(parsed)) {
21694
22084
  const text = typeof parsed === "string" ? parsed.trim() : "";
21695
22085
  if (/^(?:[A-Za-z0-9_:-]+:\s*)?(?:Error|TypeError|ReferenceError|SyntaxError|RangeError):\s+/.test(
21696
22086
  text
@@ -21698,12 +22088,12 @@ function cellFailureError(value) {
21698
22088
  return { message: text };
21699
22089
  }
21700
22090
  }
21701
- if (!isRecord7(parsed)) {
22091
+ if (!isRecord8(parsed)) {
21702
22092
  return null;
21703
22093
  }
21704
22094
  const status = typeof parsed.status === "string" ? parsed.status.trim().toLowerCase() : "";
21705
22095
  const directError = typeof parsed.error === "string" ? parsed.error.trim() : typeof parsed.last_error === "string" ? parsed.last_error.trim() : "";
21706
- const result = isRecord7(parsed.result) ? parsed.result : null;
22096
+ const result = isRecord8(parsed.result) ? parsed.result : null;
21707
22097
  const resultError = typeof result?.error === "string" ? result.error.trim() : typeof result?.message === "string" ? result.message.trim() : "";
21708
22098
  if (!directError && !resultError && status !== "error" && status !== "failed") {
21709
22099
  return null;
@@ -21773,7 +22163,7 @@ function assignFlattenedFailurePath(target, field, value) {
21773
22163
  let cursor = target;
21774
22164
  for (const part of normalized.slice(0, -1)) {
21775
22165
  const existing = cursor[part];
21776
- if (!isRecord7(existing)) {
22166
+ if (!isRecord8(existing)) {
21777
22167
  const next = {};
21778
22168
  cursor[part] = next;
21779
22169
  cursor = next;
@@ -21937,10 +22327,10 @@ function waterfallExecutionSignal(status, spec) {
21937
22327
  let everyChildStatOnlyConditionSkipped = true;
21938
22328
  const childAliasesWithStats = /* @__PURE__ */ new Set();
21939
22329
  for (const childAlias of childAliases) {
21940
- for (const stat2 of summaries.map((summary) => summary[childAlias]).filter(isRecord7)) {
22330
+ for (const stat2 of summaries.map((summary) => summary[childAlias]).filter(isRecord8)) {
21941
22331
  sawChildStats = true;
21942
22332
  childAliasesWithStats.add(childAlias);
21943
- const execution = isRecord7(stat2.execution) ? stat2.execution : null;
22333
+ const execution = isRecord8(stat2.execution) ? stat2.execution : null;
21944
22334
  const executedSummary = parseExecutionSummary(
21945
22335
  execution?.["completed:executed"]
21946
22336
  );
@@ -21970,7 +22360,7 @@ function waterfallExecutionSignal(status, spec) {
21970
22360
  }
21971
22361
  function emptyWaterfallStatsEvidence(status, spec) {
21972
22362
  const summaries = collectColumnStats(status);
21973
- const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord7);
22363
+ const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord8);
21974
22364
  for (const stat2 of parentStats) {
21975
22365
  const nonEmpty = parseExecutionSummary(stat2.non_empty);
21976
22366
  if (nonEmpty?.total && nonEmpty.count === 0) {
@@ -21984,7 +22374,7 @@ function emptyWaterfallStatsEvidence(status, spec) {
21984
22374
  let selectedRows = 0;
21985
22375
  let sawStatsForEveryChild = true;
21986
22376
  for (const childAlias of childAliases) {
21987
- const stat2 = summaries.map((summary) => summary[childAlias]).find(isRecord7);
22377
+ const stat2 = summaries.map((summary) => summary[childAlias]).find(isRecord8);
21988
22378
  if (!stat2) {
21989
22379
  sawStatsForEveryChild = false;
21990
22380
  break;
@@ -21993,7 +22383,7 @@ function emptyWaterfallStatsEvidence(status, spec) {
21993
22383
  if ((nonEmpty?.count ?? 0) > 0) {
21994
22384
  return null;
21995
22385
  }
21996
- const execution = isRecord7(stat2.execution) ? stat2.execution : null;
22386
+ const execution = isRecord8(stat2.execution) ? stat2.execution : null;
21997
22387
  const executed = parseExecutionSummary(execution?.["completed:executed"]);
21998
22388
  const reused = parseExecutionSummary(execution?.["completed:reused"]);
21999
22389
  const skipped = parseExecutionSummary(execution?.["skipped:condition"]);
@@ -22035,11 +22425,11 @@ function collectStatusFailureJobs(input2) {
22035
22425
  const jobs = [];
22036
22426
  aliases.forEach((spec, aliasIndex) => {
22037
22427
  const { alias } = spec;
22038
- const stat2 = summaries.map((summary) => summary[alias]).find(isRecord7);
22428
+ const stat2 = summaries.map((summary) => summary[alias]).find(isRecord8);
22039
22429
  if (!stat2) {
22040
22430
  return;
22041
22431
  }
22042
- const execution = isRecord7(stat2.execution) ? stat2.execution : null;
22432
+ const execution = isRecord8(stat2.execution) ? stat2.execution : null;
22043
22433
  const failedCount = Math.min(
22044
22434
  selectedRows,
22045
22435
  Math.max(
@@ -22146,10 +22536,10 @@ function collectColumnStats(status) {
22146
22536
  value.forEach(visit);
22147
22537
  return;
22148
22538
  }
22149
- if (!isRecord7(value)) {
22539
+ if (!isRecord8(value)) {
22150
22540
  return;
22151
22541
  }
22152
- if (isRecord7(value.columnStats)) {
22542
+ if (isRecord8(value.columnStats)) {
22153
22543
  summaries.push(value.columnStats);
22154
22544
  }
22155
22545
  Object.values(value).forEach(visit);
@@ -22161,12 +22551,12 @@ function firstAliasExecutionCounts(input2) {
22161
22551
  const aliases = collectConfigScalarAliasOrder(input2.config);
22162
22552
  const summaries = collectColumnStats(input2.status);
22163
22553
  for (const alias of aliases) {
22164
- const stat2 = summaries.map((summary) => summary[alias]).find(isRecord7);
22554
+ const stat2 = summaries.map((summary) => summary[alias]).find(isRecord8);
22165
22555
  if (!stat2) continue;
22166
22556
  if (input2.forceAliases.has(normalizeAlias2(alias))) {
22167
22557
  return { executed: input2.selectedRows, reused: 0 };
22168
22558
  }
22169
- const execution = isRecord7(stat2.execution) ? stat2.execution : null;
22559
+ const execution = isRecord8(stat2.execution) ? stat2.execution : null;
22170
22560
  if (!execution) continue;
22171
22561
  return {
22172
22562
  executed: parseExecutionCount(execution["completed:executed"]),
@@ -22193,14 +22583,14 @@ function rewriteEnrichJsonStatus(input2) {
22193
22583
  if (Array.isArray(value)) {
22194
22584
  return value.map(rewrite);
22195
22585
  }
22196
- if (!isRecord7(value)) {
22586
+ if (!isRecord8(value)) {
22197
22587
  return value;
22198
22588
  }
22199
22589
  const next = {};
22200
22590
  for (const [key, entry] of Object.entries(value)) {
22201
22591
  next[key] = rewrite(entry);
22202
22592
  }
22203
- if (isRecord7(next.progress)) {
22593
+ if (isRecord8(next.progress)) {
22204
22594
  next.progress = {
22205
22595
  ...next.progress,
22206
22596
  ...selectedRows > 0 ? { total: selectedRows } : {},
@@ -22209,8 +22599,8 @@ function rewriteEnrichJsonStatus(input2) {
22209
22599
  ...failedRows > 0 ? { failed: failedRows, pending: 0 } : {}
22210
22600
  };
22211
22601
  }
22212
- if (isRecord7(next.summary)) {
22213
- const rowCounts = isRecord7(next.summary.rowCounts) ? next.summary.rowCounts : null;
22602
+ if (isRecord8(next.summary)) {
22603
+ const rowCounts = isRecord8(next.summary.rowCounts) ? next.summary.rowCounts : null;
22214
22604
  if (failedRows > 0) {
22215
22605
  next.summary = {
22216
22606
  ...next.summary,
@@ -22223,11 +22613,11 @@ function rewriteEnrichJsonStatus(input2) {
22223
22613
  };
22224
22614
  }
22225
22615
  }
22226
- if (isRecord7(next.columnStats) && selectedRows > 0) {
22616
+ if (isRecord8(next.columnStats) && selectedRows > 0) {
22227
22617
  const columnStats = { ...next.columnStats };
22228
22618
  for (const alias of forcedAliases) {
22229
- const stat2 = isRecord7(columnStats[alias]) ? columnStats[alias] : null;
22230
- const execution = isRecord7(stat2?.execution) ? stat2.execution : null;
22619
+ const stat2 = isRecord8(columnStats[alias]) ? columnStats[alias] : null;
22620
+ const execution = isRecord8(stat2?.execution) ? stat2.execution : null;
22231
22621
  if (!stat2 || !execution) continue;
22232
22622
  columnStats[alias] = {
22233
22623
  ...stat2,
@@ -22246,14 +22636,14 @@ function rewriteEnrichJsonStatus(input2) {
22246
22636
  return next;
22247
22637
  };
22248
22638
  const rewritten = rewrite(input2.status);
22249
- if (failedRows === 0 || !isRecord7(rewritten)) {
22639
+ if (failedRows === 0 || !isRecord8(rewritten)) {
22250
22640
  return rewritten;
22251
22641
  }
22252
22642
  const partialStatus = selectedRows > 0 && failedRows < selectedRows ? "partial_success" : "failed";
22253
22643
  return {
22254
22644
  ...rewritten,
22255
22645
  ...rewritten.status === "completed" || rewritten.status === "failed" ? { status: partialStatus } : {},
22256
- ...isRecord7(rewritten.run) && (rewritten.run.status === "completed" || rewritten.run.status === "failed") ? { run: { ...rewritten.run, status: partialStatus } } : {}
22646
+ ...isRecord8(rewritten.run) && (rewritten.run.status === "completed" || rewritten.run.status === "failed") ? { run: { ...rewritten.run, status: partialStatus } } : {}
22257
22647
  };
22258
22648
  }
22259
22649
  function summarizeFailedJobError(value) {
@@ -22859,7 +23249,7 @@ function materializeCsvCellValue(value) {
22859
23249
  return value;
22860
23250
  }
22861
23251
  function compactArrayEnvelopeCompleteValue(value) {
22862
- if (!isRecord7(value) || value.kind !== "array") {
23252
+ if (!isRecord8(value) || value.kind !== "array") {
22863
23253
  return null;
22864
23254
  }
22865
23255
  if (!Array.isArray(value.preview)) {
@@ -22873,7 +23263,7 @@ function compactArrayEnvelopeCompleteValue(value) {
22873
23263
  }
22874
23264
  function disambiguateCompactAiInferencePayload(value) {
22875
23265
  const parsed = parseMaybeJsonObject(value);
22876
- if (!isRecord7(parsed) || !cellFailureError(parsed)) {
23266
+ if (!isRecord8(parsed) || !cellFailureError(parsed)) {
22877
23267
  return value;
22878
23268
  }
22879
23269
  return {
@@ -22882,14 +23272,14 @@ function disambiguateCompactAiInferencePayload(value) {
22882
23272
  };
22883
23273
  }
22884
23274
  function compactAiInferenceCellForCsv(value) {
22885
- if (!isRecord7(value)) {
23275
+ if (!isRecord8(value)) {
22886
23276
  return value;
22887
23277
  }
22888
23278
  const extractedJson = value.extracted_json;
22889
23279
  if (extractedJson !== null && extractedJson !== void 0) {
22890
23280
  return disambiguateCompactAiInferencePayload(extractedJson);
22891
23281
  }
22892
- const result = isRecord7(value.result) ? value.result : null;
23282
+ const result = isRecord8(value.result) ? value.result : null;
22893
23283
  const object = result?.object;
22894
23284
  if (object !== null && object !== void 0) {
22895
23285
  return disambiguateCompactAiInferencePayload(object);
@@ -22906,12 +23296,12 @@ function compactAiInferenceCellForCsv(value) {
22906
23296
  }
22907
23297
  function materializeEnrichAliasCellForCsv(row, alias, options) {
22908
23298
  const direct = row[alias];
22909
- if (isRecord7(direct)) {
23299
+ if (isRecord8(direct)) {
22910
23300
  const completeArray = compactArrayEnvelopeCompleteValue(direct);
22911
23301
  if (completeArray) {
22912
23302
  return materializeCsvCellValue(completeArray);
22913
23303
  }
22914
- if (options?.compactAiCell && direct.status === "completed" && (isRecord7(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
23304
+ if (options?.compactAiCell && direct.status === "completed" && (isRecord8(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
22915
23305
  return materializeCsvCellValue(compactAiInferenceCellForCsv(direct));
22916
23306
  }
22917
23307
  if (Object.prototype.hasOwnProperty.call(direct, "matched_result") || Object.prototype.hasOwnProperty.call(direct, "matchedResult") || Object.prototype.hasOwnProperty.call(direct, "result")) {
@@ -23052,11 +23442,11 @@ function normalizeEnrichRowsForCsvExport(rows, config, options) {
23052
23442
  }
23053
23443
  function legacyMetadataFromRow(row) {
23054
23444
  const direct = parseLegacyMetadataCell(row._metadata);
23055
- if (direct && isRecord7(direct.columns)) {
23445
+ if (direct && isRecord8(direct.columns)) {
23056
23446
  return direct;
23057
23447
  }
23058
23448
  const relocated = parseLegacyMetadataCell(row.metadata);
23059
- if (relocated && isRecord7(relocated.columns)) {
23449
+ if (relocated && isRecord8(relocated.columns)) {
23060
23450
  return relocated;
23061
23451
  }
23062
23452
  const flattenedColumns = parseLegacyMetadataCell(row["metadata.columns"]);
@@ -23073,7 +23463,7 @@ function legacyMetadataFromRow(row) {
23073
23463
  }
23074
23464
  function parseLegacyMetadataCell(value) {
23075
23465
  const parsed = parseMaybeJsonObject(value);
23076
- if (isRecord7(parsed)) {
23466
+ if (isRecord8(parsed)) {
23077
23467
  return parsed;
23078
23468
  }
23079
23469
  if (typeof value !== "string") {
@@ -23090,12 +23480,12 @@ function parseLegacyMetadataCell(value) {
23090
23480
  for (const candidate of candidates) {
23091
23481
  try {
23092
23482
  const decoded = JSON.parse(candidate);
23093
- if (isRecord7(decoded)) {
23483
+ if (isRecord8(decoded)) {
23094
23484
  return decoded;
23095
23485
  }
23096
23486
  if (typeof decoded === "string") {
23097
23487
  const nested = JSON.parse(decoded);
23098
- if (isRecord7(nested)) {
23488
+ if (isRecord8(nested)) {
23099
23489
  return nested;
23100
23490
  }
23101
23491
  }
@@ -23105,8 +23495,8 @@ function parseLegacyMetadataCell(value) {
23105
23495
  return null;
23106
23496
  }
23107
23497
  function mergeLegacyMetadataRecords(base, enriched) {
23108
- const baseColumns = isRecord7(base.columns) ? base.columns : null;
23109
- const enrichedColumns = isRecord7(enriched.columns) ? enriched.columns : null;
23498
+ const baseColumns = isRecord8(base.columns) ? base.columns : null;
23499
+ const enrichedColumns = isRecord8(enriched.columns) ? enriched.columns : null;
23110
23500
  const merged = {
23111
23501
  ...base,
23112
23502
  ...enriched
@@ -26975,6 +27365,43 @@ async function listTools(category, options = {}) {
26975
27365
  }
26976
27366
  return listToolCategories(emitJson, compact);
26977
27367
  }
27368
+ async function listProviders(options = {}) {
27369
+ const client2 = new DeeplineClient();
27370
+ const changed = options.changed === true;
27371
+ const emitJson = options.json === true || shouldEmitJson();
27372
+ const providers = await client2.listProviders({ changed });
27373
+ const render = {
27374
+ sections: [
27375
+ {
27376
+ title: changed ? `${providers.length} recently added providers:` : `${providers.length} providers:`,
27377
+ lines: providers.map((provider) => {
27378
+ const release2 = provider.releasedAt ? ` - v${provider.version ?? "unknown"} (${provider.releasedAt})` : "";
27379
+ return `${provider.provider} (${provider.displayName}) - ${provider.toolCount} tools${release2}`;
27380
+ })
27381
+ },
27382
+ {
27383
+ title: "next",
27384
+ lines: [
27385
+ "Run `deepline tools list <category>` to browse provider tools by category."
27386
+ ]
27387
+ }
27388
+ ]
27389
+ };
27390
+ printCommandEnvelope(
27391
+ {
27392
+ providers,
27393
+ count: providers.length,
27394
+ filters: { changed },
27395
+ commandTemplates: {
27396
+ list: "deepline tools providers",
27397
+ changed: "deepline tools providers --changed"
27398
+ },
27399
+ render
27400
+ },
27401
+ { json: emitJson }
27402
+ );
27403
+ return 0;
27404
+ }
26978
27405
  async function searchTools(queryInput, options = {}) {
26979
27406
  const query = queryInput?.trim() ?? "";
26980
27407
  const hasStructuredSearch = Boolean(
@@ -27167,6 +27594,7 @@ Concepts:
27167
27594
  through the plays namespace.
27168
27595
 
27169
27596
  Common commands:
27597
+ deepline tools providers --changed --json
27170
27598
  deepline tools search email --json
27171
27599
  deepline tools describe hunter_email_verifier --json
27172
27600
  deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
@@ -27176,6 +27604,28 @@ Output:
27176
27604
  Use execute to run a tool.
27177
27605
  `
27178
27606
  );
27607
+ tools.command("providers").description("List discoverable providers and their available tool counts.").addHelpText(
27608
+ "after",
27609
+ `
27610
+ Notes:
27611
+ This directory is served by Deepline's provider catalog; it does not require
27612
+ cloning a public plugins repository. Use --changed to show recently added
27613
+ providers with their catalog version and release date.
27614
+
27615
+ Examples:
27616
+ deepline tools providers
27617
+ deepline tools providers --changed
27618
+ deepline tools providers --changed --json
27619
+ `
27620
+ ).option(
27621
+ "--changed",
27622
+ "Only list recently added providers with release metadata"
27623
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
27624
+ process.exitCode = await listProviders({
27625
+ changed: Boolean(options.changed),
27626
+ json: Boolean(options.json)
27627
+ });
27628
+ });
27179
27629
  tools.command("list [category]").description("Browse tool categories, or list every tool in a category.").addHelpText(
27180
27630
  "after",
27181
27631
  `
@@ -27537,7 +27987,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
27537
27987
  }
27538
27988
  function extractionContractEntries(entries) {
27539
27989
  return entries.flatMap((entry) => {
27540
- if (!isRecord8(entry)) return [];
27990
+ if (!isRecord9(entry)) return [];
27541
27991
  const name = stringField2(entry, "name");
27542
27992
  const expression = stringField2(entry, "expression");
27543
27993
  return name && expression ? [{ name, expression }] : [];
@@ -27558,7 +28008,7 @@ function printMonitorTypeFilters(tool) {
27558
28008
  }
27559
28009
  console.log("Deploy filters (set in the monitor payload):");
27560
28010
  for (const name of names) {
27561
- const field = isRecord8(properties[name]) ? properties[name] : {};
28011
+ const field = isRecord9(properties[name]) ? properties[name] : {};
27562
28012
  const star = required.has(name) ? "*" : "";
27563
28013
  const enumVals = arrayField2(field, "enum").filter(
27564
28014
  (v) => typeof v === "string"
@@ -27569,13 +28019,13 @@ function printMonitorTypeFilters(tool) {
27569
28019
  }
27570
28020
  }
27571
28021
  function printMonitorTypeStreams(tool) {
27572
- const streams = arrayField2(tool, "streams", "output_streams").filter(isRecord8);
28022
+ const streams = arrayField2(tool, "streams", "output_streams").filter(isRecord9);
27573
28023
  if (!streams.length) return;
27574
28024
  console.log("");
27575
28025
  console.log("Filter columns (a play's sqlListeners.where, per stream):");
27576
28026
  for (const stream of streams) {
27577
28027
  const name = stringField2(stream, "stream");
27578
- const cols = arrayField2(stream, "columns").filter(isRecord8).map((col) => stringField2(col, "name")).filter(Boolean);
28028
+ const cols = arrayField2(stream, "columns").filter(isRecord9).map((col) => stringField2(col, "name")).filter(Boolean);
27579
28029
  console.log(`- ${name}: ${cols.join(", ")}`);
27580
28030
  }
27581
28031
  }
@@ -27593,7 +28043,7 @@ function printMonitorTypePricing(tool) {
27593
28043
  }
27594
28044
  console.log("Pricing (Deepline credits per accepted event):");
27595
28045
  for (const key of keys) {
27596
- const entry = isRecord8(byType[key]) ? byType[key] : {};
28046
+ const entry = isRecord9(byType[key]) ? byType[key] : {};
27597
28047
  const credits = numberField2(entry, "deepline_credits", "deeplineCredits");
27598
28048
  const display = stringField2(entry, "display");
27599
28049
  const shown = display || (credits !== null ? `${formatDecimal(credits)} credits/event` : "see --json");
@@ -27638,8 +28088,8 @@ function printCompactToolContract(tool, requestedToolId) {
27638
28088
  return;
27639
28089
  }
27640
28090
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
27641
- const cost = isRecord8(contract.cost) ? contract.cost : {};
27642
- const getters = isRecord8(contract.getters) ? contract.getters : {};
28091
+ const cost = isRecord9(contract.cost) ? contract.cost : {};
28092
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
27643
28093
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
27644
28094
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
27645
28095
  const inputFields = Array.isArray(contract.inputFields) ? contract.inputFields : [];
@@ -27656,7 +28106,7 @@ function printCompactToolContract(tool, requestedToolId) {
27656
28106
  console.log("");
27657
28107
  console.log("Inputs:");
27658
28108
  for (const field of inputFields) {
27659
- if (!isRecord8(field)) continue;
28109
+ if (!isRecord9(field)) continue;
27660
28110
  const name = stringField2(field, "name");
27661
28111
  if (!name) continue;
27662
28112
  const required = field.required ? "*" : "";
@@ -27669,7 +28119,7 @@ function printCompactToolContract(tool, requestedToolId) {
27669
28119
  }
27670
28120
  console.log("");
27671
28121
  printToolExamplesOnly(tool, requestedToolId, { includeSamples: false });
27672
- const starterScript = isRecord8(contract.starterScript) ? contract.starterScript : {};
28122
+ const starterScript = isRecord9(contract.starterScript) ? contract.starterScript : {};
27673
28123
  const starterPath = stringField2(starterScript, "path");
27674
28124
  if (starterPath) {
27675
28125
  console.log("");
@@ -27683,14 +28133,14 @@ function printCompactToolContract(tool, requestedToolId) {
27683
28133
  console.log("Getters:");
27684
28134
  if (listGetters.length) console.log("Lists:");
27685
28135
  for (const entry of listGetters) {
27686
- if (isRecord8(entry))
28136
+ if (isRecord9(entry))
27687
28137
  console.log(
27688
28138
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
27689
28139
  );
27690
28140
  }
27691
28141
  if (valueGetters.length) console.log("Values:");
27692
28142
  for (const entry of valueGetters) {
27693
- if (isRecord8(entry))
28143
+ if (isRecord9(entry))
27694
28144
  console.log(
27695
28145
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
27696
28146
  );
@@ -27707,7 +28157,7 @@ function printToolPricingOnly(tool, requestedToolId, options = {}) {
27707
28157
  return;
27708
28158
  }
27709
28159
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
27710
- const cost = isRecord8(contract.cost) ? contract.cost : {};
28160
+ const cost = isRecord9(contract.cost) ? contract.cost : {};
27711
28161
  const pricingModel = stringField2(cost, "pricingModel") || "unknown";
27712
28162
  const billingMode = stringField2(cost, "billingMode") || "unknown";
27713
28163
  const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit";
@@ -27732,7 +28182,7 @@ function printToolSchemaOnly(tool, requestedToolId) {
27732
28182
  }
27733
28183
  console.log("Inputs:");
27734
28184
  for (const field of inputFields) {
27735
- if (!isRecord8(field)) continue;
28185
+ if (!isRecord9(field)) continue;
27736
28186
  const name = stringField2(field, "name");
27737
28187
  if (!name) continue;
27738
28188
  const required = field.required ? "*" : "";
@@ -27766,10 +28216,10 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
27766
28216
  ` input: ${JSON.stringify(sampleInput || {}, null, 2).replace(/\n/g, "\n ")},`
27767
28217
  );
27768
28218
  console.log("});");
27769
- const getters = isRecord8(contract.getters) ? contract.getters : {};
28219
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
27770
28220
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
27771
28221
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
27772
- const firstGetter = [...valueGetters, ...listGetters].find(isRecord8);
28222
+ const firstGetter = [...valueGetters, ...listGetters].find(isRecord9);
27773
28223
  if (firstGetter) {
27774
28224
  const name = stringField2(firstGetter, "name") || "value";
27775
28225
  const expression = stringField2(firstGetter, "expression");
@@ -27805,7 +28255,7 @@ function printPlayLikeToolUsage(tool, requestedToolId) {
27805
28255
  }
27806
28256
  function printToolGettersOnly(tool, requestedToolId) {
27807
28257
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
27808
- const getters = isRecord8(contract.getters) ? contract.getters : {};
28258
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
27809
28259
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
27810
28260
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
27811
28261
  console.log(`Getters: ${contract.toolId}`);
@@ -27818,7 +28268,7 @@ function printToolGettersOnly(tool, requestedToolId) {
27818
28268
  if (listGetters.length) {
27819
28269
  console.log("Lists:");
27820
28270
  for (const entry of listGetters) {
27821
- if (isRecord8(entry))
28271
+ if (isRecord9(entry))
27822
28272
  console.log(
27823
28273
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
27824
28274
  );
@@ -27827,7 +28277,7 @@ function printToolGettersOnly(tool, requestedToolId) {
27827
28277
  if (valueGetters.length) {
27828
28278
  console.log("Values:");
27829
28279
  for (const entry of valueGetters) {
27830
- if (isRecord8(entry))
28280
+ if (isRecord9(entry))
27831
28281
  console.log(
27832
28282
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
27833
28283
  );
@@ -27853,7 +28303,7 @@ function sampleValueForField(field) {
27853
28303
  function samplePayloadForInputFields(fields) {
27854
28304
  return Object.fromEntries(
27855
28305
  fields.slice(0, 4).flatMap((field) => {
27856
- if (!isRecord8(field)) return [];
28306
+ if (!isRecord9(field)) return [];
27857
28307
  const name = stringField2(field, "name");
27858
28308
  if (!name) return [];
27859
28309
  return [[name, sampleValueForField(field)]];
@@ -27971,12 +28421,12 @@ function formatListedToolCost(tool) {
27971
28421
  }
27972
28422
  function toolInputFieldsForDisplay(inputSchema) {
27973
28423
  if (Array.isArray(inputSchema.fields))
27974
- return inputSchema.fields.filter(isRecord8);
27975
- const jsonSchema = isRecord8(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
27976
- const properties = isRecord8(jsonSchema.properties) ? jsonSchema.properties : {};
28424
+ return inputSchema.fields.filter(isRecord9);
28425
+ const jsonSchema = isRecord9(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
28426
+ const properties = isRecord9(jsonSchema.properties) ? jsonSchema.properties : {};
27977
28427
  const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
27978
28428
  return Object.entries(properties).map(([name, value]) => {
27979
- const property = isRecord8(value) ? value : {};
28429
+ const property = isRecord9(value) ? value : {};
27980
28430
  return {
27981
28431
  name,
27982
28432
  type: typeof property.type === "string" ? property.type : "unknown",
@@ -28005,14 +28455,14 @@ function printJsonPreview(label, payload) {
28005
28455
  }
28006
28456
  function samplePayload(samples, key) {
28007
28457
  const entry = samples[key];
28008
- if (!isRecord8(entry)) return void 0;
28458
+ if (!isRecord9(entry)) return void 0;
28009
28459
  return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
28010
28460
  }
28011
28461
  function commandEnvelopeFromRawResponse(rawResponse) {
28012
- return isRecord8(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
28462
+ return isRecord9(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
28013
28463
  }
28014
28464
  function apifySyncRecoveryNext(rawResponse) {
28015
- if (!isRecord8(rawResponse) || rawResponse.status !== "running") return null;
28465
+ if (!isRecord9(rawResponse) || rawResponse.status !== "running") return null;
28016
28466
  const toolResponse = recordField2(rawResponse, "toolResponse");
28017
28467
  const raw = recordField2(toolResponse, "raw");
28018
28468
  if (raw.state !== "awaiting_apify") return null;
@@ -28035,7 +28485,7 @@ function apifySyncRecoveryNext(rawResponse) {
28035
28485
  }
28036
28486
  function listExtractorPathsFromUsageGuidance(tool) {
28037
28487
  const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
28038
- const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord8(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
28488
+ const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord9(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
28039
28489
  return extractedLists.flatMap((entry) => {
28040
28490
  const paths = entry.details?.candidatePaths ?? entry.details?.rawToolOutputPaths;
28041
28491
  if (!Array.isArray(paths)) return [];
@@ -28051,7 +28501,7 @@ function formatDecimal(value) {
28051
28501
  function formatUsd(value) {
28052
28502
  return `$${formatDecimal(value)}`;
28053
28503
  }
28054
- function isRecord8(value) {
28504
+ function isRecord9(value) {
28055
28505
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
28056
28506
  }
28057
28507
  function stringField2(source, ...keys) {
@@ -28078,7 +28528,7 @@ function arrayField2(source, ...keys) {
28078
28528
  function recordField2(source, ...keys) {
28079
28529
  for (const key of keys) {
28080
28530
  const value = source[key];
28081
- if (isRecord8(value)) return value;
28531
+ if (isRecord9(value)) return value;
28082
28532
  }
28083
28533
  return {};
28084
28534
  }
@@ -28144,7 +28594,7 @@ function parseJsonObjectArgument(raw, flagName) {
28144
28594
  }
28145
28595
  throw invalidJsonError(flagName, message);
28146
28596
  }
28147
- if (!isRecord8(parsed)) {
28597
+ if (!isRecord9(parsed)) {
28148
28598
  throw invalidJsonError(flagName, "expected an object.");
28149
28599
  }
28150
28600
  return parsed;
@@ -28291,7 +28741,7 @@ function buildToolExecuteBaseEnvelope(input2) {
28291
28741
  kind: summaryEntries.length > 0 ? "object" : "raw",
28292
28742
  summary: input2.summary
28293
28743
  };
28294
- const envelopeHasCanonicalOutput = isRecord8(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
28744
+ const envelopeHasCanonicalOutput = isRecord9(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
28295
28745
  const envelopeHasDeclaredOutput = Object.prototype.hasOwnProperty.call(
28296
28746
  envelope,
28297
28747
  "output"
@@ -28521,7 +28971,7 @@ async function executeTool(args) {
28521
28971
  {
28522
28972
  ...baseEnvelope,
28523
28973
  local: {
28524
- ...isRecord8(baseEnvelope.local) ? baseEnvelope.local : {},
28974
+ ...isRecord9(baseEnvelope.local) ? baseEnvelope.local : {},
28525
28975
  payload_file: jsonPath
28526
28976
  }
28527
28977
  },
@@ -31987,7 +32437,9 @@ function shouldDeferSkillsSyncForCommand() {
31987
32437
  const args = process.argv.slice(2);
31988
32438
  const command = args[0];
31989
32439
  const subcommand = args[1];
31990
- if (command === "tools" && ["list", "search", "grep", "describe", "get"].includes(subcommand ?? "")) {
32440
+ if (command === "tools" && ["list", "providers", "search", "grep", "describe", "get"].includes(
32441
+ subcommand ?? ""
32442
+ )) {
31991
32443
  return true;
31992
32444
  }
31993
32445
  return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
@@ -32213,6 +32665,7 @@ Common commands:
32213
32665
  deepline plays describe prebuilt/person-linkedin-to-email --json
32214
32666
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
32215
32667
  deepline secrets check HUBSPOT_TOKEN
32668
+ deepline tools providers --changed --json
32216
32669
  deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
32217
32670
  deepline update
32218
32671