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.
@@ -703,7 +703,7 @@ var SDK_RELEASE = {
703
703
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
704
704
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
705
705
  // Operators use the checkout-local deepline-admin binary instead.
706
- version: "0.1.274",
706
+ version: "0.1.276",
707
707
  contracts: {
708
708
  api: {
709
709
  name: "sdk-http-api",
@@ -917,19 +917,19 @@ function isAbortLikeError(error) {
917
917
  const message = error.message.toLowerCase();
918
918
  return name === "aborterror" || message.includes("operation was aborted") || message === "aborted";
919
919
  }
920
- function mapNetworkError(baseUrl, error, targetLabel) {
920
+ function mapNetworkError(baseUrl, error, targetLabel2) {
921
921
  const tagged = error;
922
922
  const timeoutMs = tagged?.[REQUEST_TIMEOUT_MARKER];
923
923
  if (typeof timeoutMs === "number") {
924
924
  return {
925
- message: `Request to ${targetLabel} timed out after ${timeoutMs}ms while waiting for a response.`,
925
+ message: `Request to ${targetLabel2} timed out after ${timeoutMs}ms while waiting for a response.`,
926
926
  code: "NETWORK_TIMEOUT",
927
- details: { timeoutMs, target: targetLabel }
927
+ details: { timeoutMs, target: targetLabel2 }
928
928
  };
929
929
  }
930
930
  if (tagged?.[REQUEST_ABORT_MARKER]) {
931
931
  return {
932
- message: `Request to ${targetLabel} was aborted before it completed.`,
932
+ message: `Request to ${targetLabel2} was aborted before it completed.`,
933
933
  code: "NETWORK_ABORTED"
934
934
  };
935
935
  }
@@ -1590,9 +1590,277 @@ var RUNNER_POST_TERMINAL_DIAGNOSTIC_MAX_BYTES = 64 * 1024;
1590
1590
  // ../shared_libs/play-runtime/ledger-safe-payload.ts
1591
1591
  var ledgerIngressRedactor = createSecretRedactionContext();
1592
1592
 
1593
+ // ../shared_libs/play-runtime/activity-observation.ts
1594
+ function isRecord(value) {
1595
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
1596
+ }
1597
+ function isPlayActivityObservation(value) {
1598
+ 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)) {
1599
+ return false;
1600
+ }
1601
+ const targetKinds = /* @__PURE__ */ new Set([
1602
+ "provider",
1603
+ "dataset",
1604
+ "lease",
1605
+ "runner",
1606
+ "step",
1607
+ "capacity"
1608
+ ]);
1609
+ const stateKinds = /* @__PURE__ */ new Set([
1610
+ "active",
1611
+ "queued",
1612
+ "waiting",
1613
+ "retrying",
1614
+ "scheduled",
1615
+ "completed",
1616
+ "failed"
1617
+ ]);
1618
+ return typeof value.target.kind === "string" && targetKinds.has(value.target.kind) && typeof value.state.kind === "string" && stateKinds.has(value.state.kind);
1619
+ }
1620
+ function derivePlayActivityVisibility(input2) {
1621
+ const { state } = input2.observation;
1622
+ if (state.kind === "failed") return "action";
1623
+ if (state.kind === "waiting") {
1624
+ return state.reason.kind === "external_event" ? "action" : "headline";
1625
+ }
1626
+ if (state.kind === "queued" || state.kind === "scheduled") return "headline";
1627
+ if (state.kind === "retrying") {
1628
+ return state.retryAt - input2.now <= 3e4 ? "hidden" : "timeline";
1629
+ }
1630
+ if (state.kind === "active") return "headline";
1631
+ return "timeline";
1632
+ }
1633
+ function targetLabel(target) {
1634
+ switch (target.kind) {
1635
+ case "provider":
1636
+ return target.label ?? `${target.provider} ${target.operation}`;
1637
+ case "dataset":
1638
+ return target.label ?? `dataset ${target.tableNamespace}`;
1639
+ case "lease":
1640
+ return `${target.resourceKind} ${target.resourceLabel}`;
1641
+ case "runner":
1642
+ return target.label ?? `${target.backend} runner`;
1643
+ case "step":
1644
+ return target.label ?? target.stepId;
1645
+ case "capacity":
1646
+ return target.label ?? `${target.pool} capacity`;
1647
+ }
1648
+ }
1649
+ function summarizePlayActivity(observation) {
1650
+ const label = targetLabel(observation.target);
1651
+ const { state } = observation;
1652
+ switch (state.kind) {
1653
+ case "active": {
1654
+ const progress = state.progress;
1655
+ const counts = typeof progress?.completed === "number" && typeof progress.total === "number" ? ` (${progress.completed}/${progress.total})` : "";
1656
+ return `Active: ${label}${counts}.`;
1657
+ }
1658
+ case "queued":
1659
+ return `Queued: waiting for ${label}.`;
1660
+ case "waiting":
1661
+ if (state.reason.kind === "external_event") {
1662
+ const provider = state.reason.provider ? ` from ${state.reason.provider}` : "";
1663
+ return `Blocked: waiting for an external event${provider}.`;
1664
+ }
1665
+ if (state.reason.kind === "dataset") {
1666
+ return `Blocked: waiting for dataset ${state.reason.tableNamespace} to become ${state.reason.requiredPhase}.`;
1667
+ }
1668
+ if (state.reason.kind === "lease") {
1669
+ return `Contended: waiting for ${state.reason.resourceKind} lease ${state.reason.resourceLabel}.`;
1670
+ }
1671
+ return `Paused: ${label}; the legacy producer did not report a typed reason.`;
1672
+ case "retrying":
1673
+ return `Delayed: ${label} will retry automatically.`;
1674
+ case "scheduled":
1675
+ return `Scheduled: ${label} will resume automatically.`;
1676
+ case "completed":
1677
+ return `Completed: ${label}.`;
1678
+ case "failed":
1679
+ return `Failed: ${label}.`;
1680
+ }
1681
+ }
1682
+ function isTerminalActivityState(state) {
1683
+ return state.kind === "completed" || state.kind === "failed";
1684
+ }
1685
+ function projection(observation, now, classified = true) {
1686
+ return {
1687
+ observation,
1688
+ summary: summarizePlayActivity(observation),
1689
+ visibility: derivePlayActivityVisibility({ observation, now }),
1690
+ classified
1691
+ };
1692
+ }
1693
+ function projectPlayRunActivity(input2) {
1694
+ const now = input2.now ?? Date.now();
1695
+ const observedAt = input2.updatedAt ?? now;
1696
+ const normalizedStatus = input2.status.trim().toLowerCase();
1697
+ if (normalizedStatus === "completed" || normalizedStatus === "failed" || normalizedStatus === "cancelled" || normalizedStatus === "terminated" || normalizedStatus === "timed_out") {
1698
+ return null;
1699
+ }
1700
+ const explicit = [...input2.explicit ?? []].filter((candidate) => !isTerminalActivityState(candidate.state)).sort((left, right) => right.observedAt - left.observedAt)[0];
1701
+ if (explicit) return projection(explicit, now);
1702
+ if (input2.waitKind === "detached_runner") {
1703
+ return projection(
1704
+ {
1705
+ schemaVersion: 1,
1706
+ activityId: "runner:managed",
1707
+ target: {
1708
+ kind: "runner",
1709
+ backend: input2.runtimeBackend ?? "managed",
1710
+ label: "managed play runner"
1711
+ },
1712
+ state: { kind: "active" },
1713
+ observedAt
1714
+ },
1715
+ now
1716
+ );
1717
+ }
1718
+ if (input2.waitKind === "sleep") {
1719
+ return projection(
1720
+ {
1721
+ schemaVersion: 1,
1722
+ activityId: "run:sleep",
1723
+ target: {
1724
+ kind: "step",
1725
+ stepId: input2.activeNodeId ?? "run",
1726
+ label: input2.playName ?? "play"
1727
+ },
1728
+ state: {
1729
+ kind: "scheduled",
1730
+ reason: "sleep",
1731
+ resumeAt: input2.waitUntil ?? observedAt
1732
+ },
1733
+ observedAt
1734
+ },
1735
+ now
1736
+ );
1737
+ }
1738
+ if (input2.waitKind === "integration_event" || input2.waitKind === "integration_event_batch") {
1739
+ return projection(
1740
+ {
1741
+ schemaVersion: 1,
1742
+ activityId: `event:${input2.activeNodeId ?? "run"}`,
1743
+ stepId: input2.activeNodeId ?? void 0,
1744
+ target: {
1745
+ kind: "step",
1746
+ stepId: input2.activeNodeId ?? "run",
1747
+ label: input2.playName ?? "play"
1748
+ },
1749
+ state: {
1750
+ kind: "waiting",
1751
+ reason: {
1752
+ kind: "external_event",
1753
+ eventKey: input2.eventKey ?? void 0,
1754
+ deadlineAt: input2.waitUntil ?? void 0
1755
+ }
1756
+ },
1757
+ observedAt
1758
+ },
1759
+ now
1760
+ );
1761
+ }
1762
+ if (normalizedStatus === "waiting") {
1763
+ return projection(
1764
+ {
1765
+ schemaVersion: 1,
1766
+ activityId: "run:legacy-wait",
1767
+ target: {
1768
+ kind: "step",
1769
+ stepId: input2.activeNodeId ?? "run",
1770
+ label: input2.playName ?? "play"
1771
+ },
1772
+ state: { kind: "waiting", reason: { kind: "unknown" } },
1773
+ observedAt
1774
+ },
1775
+ now,
1776
+ false
1777
+ );
1778
+ }
1779
+ const pendingDataset = [...input2.datasets ?? []].filter(
1780
+ (dataset) => dataset.phase === "registered" || dataset.complete !== true && dataset.phase !== "failed"
1781
+ ).sort((left, right) => (right.updatedAt ?? 0) - (left.updatedAt ?? 0))[0];
1782
+ if (pendingDataset) {
1783
+ return projection(
1784
+ {
1785
+ schemaVersion: 1,
1786
+ activityId: `dataset:${pendingDataset.datasetId ?? pendingDataset.tableNamespace}`,
1787
+ target: {
1788
+ kind: "dataset",
1789
+ tableNamespace: pendingDataset.tableNamespace,
1790
+ operation: "materializing"
1791
+ },
1792
+ state: {
1793
+ kind: "active",
1794
+ progress: {
1795
+ completed: pendingDataset.persistedRows,
1796
+ total: typeof pendingDataset.succeededRows === "number" || typeof pendingDataset.failedRows === "number" ? (pendingDataset.succeededRows ?? 0) + (pendingDataset.failedRows ?? 0) : void 0,
1797
+ failed: pendingDataset.failedRows
1798
+ }
1799
+ },
1800
+ observedAt: pendingDataset.updatedAt ?? observedAt
1801
+ },
1802
+ now
1803
+ );
1804
+ }
1805
+ const activeStep = input2.nodeStates?.find(
1806
+ (candidate) => candidate.nodeId === input2.activeNodeId
1807
+ ) ?? input2.nodeStates?.find((candidate) => candidate.status === "running") ?? null;
1808
+ if (activeStep) {
1809
+ const toolId = activeStep.nodeId.startsWith("tool:") ? activeStep.nodeId.split(":").at(-1)?.trim() || null : null;
1810
+ const provider = toolId?.split(/[._]/)[0]?.trim() || null;
1811
+ return projection(
1812
+ {
1813
+ schemaVersion: 1,
1814
+ activityId: `step:${activeStep.nodeId}`,
1815
+ stepId: activeStep.nodeId,
1816
+ target: toolId && provider ? {
1817
+ kind: "provider",
1818
+ provider,
1819
+ operation: toolId,
1820
+ label: activeStep.label ?? toolId
1821
+ } : {
1822
+ kind: "step",
1823
+ stepId: activeStep.nodeId,
1824
+ label: activeStep.label
1825
+ },
1826
+ state: {
1827
+ kind: "active",
1828
+ progress: activeStep.progress ?? void 0
1829
+ },
1830
+ observedAt: activeStep.updatedAt ?? observedAt
1831
+ },
1832
+ now
1833
+ );
1834
+ }
1835
+ if (normalizedStatus === "queued") {
1836
+ return projection(
1837
+ {
1838
+ schemaVersion: 1,
1839
+ activityId: "capacity:worker",
1840
+ target: { kind: "capacity", pool: "worker" },
1841
+ state: { kind: "queued", reason: "capacity" },
1842
+ observedAt
1843
+ },
1844
+ now
1845
+ );
1846
+ }
1847
+ const fallback = {
1848
+ schemaVersion: 1,
1849
+ activityId: "run:legacy",
1850
+ target: {
1851
+ kind: "step",
1852
+ stepId: input2.activeNodeId ?? "run",
1853
+ label: input2.playName ?? "play"
1854
+ },
1855
+ state: normalizedStatus === "waiting" ? { kind: "waiting", reason: { kind: "unknown" } } : { kind: "active" },
1856
+ observedAt
1857
+ };
1858
+ return projection(fallback, now, normalizedStatus !== "waiting");
1859
+ }
1860
+
1593
1861
  // ../shared_libs/play-runtime/run-ledger.ts
1594
1862
  var LOG_TAIL_LIMIT = 100;
1595
- function isRecord(value) {
1863
+ function isRecord2(value) {
1596
1864
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
1597
1865
  }
1598
1866
  function finiteNumber(value) {
@@ -1676,30 +1944,33 @@ function createEmptyPlayRunLedgerSnapshot(input2) {
1676
1944
  stepsById: {},
1677
1945
  orderedDatasetIds: [],
1678
1946
  datasetsById: {},
1947
+ orderedActivityIds: [],
1948
+ activitiesById: {},
1679
1949
  logTail: [],
1680
1950
  totalLogCount: 0,
1681
1951
  logsTruncated: false,
1682
1952
  activeStepId: null,
1953
+ activeActivityId: null,
1683
1954
  activeArtifactTableNamespace: null,
1684
1955
  resultTableNamespace: null
1685
1956
  };
1686
1957
  }
1687
1958
  function normalizePlayRunLedgerSnapshot(value, fallback) {
1688
- if (!isRecord(value)) {
1959
+ if (!isRecord2(value)) {
1689
1960
  return createEmptyPlayRunLedgerSnapshot(fallback);
1690
1961
  }
1691
1962
  const orderedStepIds = Array.isArray(value.orderedStepIds) ? value.orderedStepIds.filter(
1692
1963
  (entry) => typeof entry === "string" && Boolean(entry.trim())
1693
1964
  ) : [];
1694
- const rawSteps = isRecord(value.stepsById) ? value.stepsById : {};
1965
+ const rawSteps = isRecord2(value.stepsById) ? value.stepsById : {};
1695
1966
  const stepsById = {};
1696
1967
  for (const [stepId, rawStep] of Object.entries(rawSteps)) {
1697
- if (!stepId.trim() || !isRecord(rawStep)) continue;
1968
+ if (!stepId.trim() || !isRecord2(rawStep)) continue;
1698
1969
  const rawStatus = normalizeStepStatus(rawStep.status);
1699
1970
  if (!rawStatus) continue;
1700
1971
  const completedAt = finiteNumber(rawStep.completedAt);
1701
1972
  const status = rawStatus === "running" && completedAt !== null ? "completed" : rawStatus;
1702
- const rawProgress = isRecord(rawStep.progress) ? rawStep.progress : null;
1973
+ const rawProgress = isRecord2(rawStep.progress) ? rawStep.progress : null;
1703
1974
  stepsById[stepId] = {
1704
1975
  stepId,
1705
1976
  label: optionalString(rawStep.label),
@@ -1715,10 +1986,10 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1715
1986
  progress: rawProgress ? normalizeStepProgress(rawProgress) : null
1716
1987
  };
1717
1988
  }
1718
- const rawDatasets = isRecord(value.datasetsById) ? value.datasetsById : {};
1989
+ const rawDatasets = isRecord2(value.datasetsById) ? value.datasetsById : {};
1719
1990
  const datasetsById = {};
1720
1991
  for (const [datasetId, rawDataset] of Object.entries(rawDatasets)) {
1721
- if (!datasetId.trim() || !isRecord(rawDataset)) continue;
1992
+ if (!datasetId.trim() || !isRecord2(rawDataset)) continue;
1722
1993
  const phase = rawDataset.phase === "available" || rawDataset.phase === "failed" ? rawDataset.phase : "registered";
1723
1994
  datasetsById[datasetId] = {
1724
1995
  datasetId,
@@ -1732,6 +2003,13 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1732
2003
  updatedAt: finiteNumber(rawDataset.updatedAt) ?? 0
1733
2004
  };
1734
2005
  }
2006
+ const rawActivities = isRecord2(value.activitiesById) ? value.activitiesById : {};
2007
+ const activitiesById = {};
2008
+ for (const [activityId, rawActivity] of Object.entries(rawActivities)) {
2009
+ if (activityId.trim() && isPlayActivityObservation(rawActivity) && rawActivity.activityId === activityId) {
2010
+ activitiesById[activityId] = rawActivity;
2011
+ }
2012
+ }
1735
2013
  const createdAt = finiteNumber(value.createdAt) ?? fallback.createdAt ?? null;
1736
2014
  const startedAt = finiteNumber(value.startedAt) ?? fallback.startedAt ?? null;
1737
2015
  const finishedAt = finiteNumber(value.finishedAt) ?? fallback.finishedAt ?? null;
@@ -1755,6 +2033,10 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1755
2033
  (datasetId) => typeof datasetId === "string" && Boolean(datasetsById[datasetId])
1756
2034
  ),
1757
2035
  datasetsById,
2036
+ orderedActivityIds: (Array.isArray(value.orderedActivityIds) ? value.orderedActivityIds : Object.keys(activitiesById)).filter(
2037
+ (activityId) => typeof activityId === "string" && Boolean(activitiesById[activityId])
2038
+ ),
2039
+ activitiesById,
1758
2040
  logTail: logTail.slice(-LOG_TAIL_LIMIT),
1759
2041
  // Snapshots persisted before totalLogCount existed only know the retained
1760
2042
  // tail, so the best lower bound for the cumulative count is the tail size.
@@ -1764,6 +2046,7 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1764
2046
  ),
1765
2047
  logsTruncated: value.logsTruncated === true,
1766
2048
  activeStepId: optionalNullableString(value.activeStepId),
2049
+ activeActivityId: optionalNullableString(value.activeActivityId),
1767
2050
  activeArtifactTableNamespace: optionalNullableString(
1768
2051
  value.activeArtifactTableNamespace
1769
2052
  ),
@@ -1850,18 +2133,18 @@ function normalizePlayRunLiveStatus(value) {
1850
2133
  function isTerminalPlayRunLiveStatus(status) {
1851
2134
  return isTerminalPlayRunLifecycleStatus(status);
1852
2135
  }
1853
- function isRecord2(value) {
2136
+ function isRecord3(value) {
1854
2137
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
1855
2138
  }
1856
2139
  function finiteNumber2(value) {
1857
2140
  return typeof value === "number" && Number.isFinite(value) ? value : null;
1858
2141
  }
1859
2142
  function extractTerminalRunLogTail(result) {
1860
- if (!isRecord2(result) || !isRecord2(result._metadata)) {
2143
+ if (!isRecord3(result) || !isRecord3(result._metadata)) {
1861
2144
  return null;
1862
2145
  }
1863
2146
  const runLogTail = result._metadata.runLogTail;
1864
- if (!isRecord2(runLogTail) || !Array.isArray(runLogTail.tail)) {
2147
+ if (!isRecord3(runLogTail) || !Array.isArray(runLogTail.tail)) {
1865
2148
  return null;
1866
2149
  }
1867
2150
  const logTail = runLogTail.tail.filter(
@@ -1921,6 +2204,10 @@ function buildSnapshotFromLedger(snapshot) {
1921
2204
  datasets: snapshot.orderedDatasetIds.map((datasetId) => snapshot.datasetsById[datasetId]).filter(
1922
2205
  (dataset) => Boolean(dataset)
1923
2206
  ),
2207
+ activities: snapshot.orderedActivityIds.map((activityId) => snapshot.activitiesById[activityId]).filter(
2208
+ (activity) => Boolean(activity)
2209
+ ),
2210
+ activeActivity: snapshot.activeActivityId ? snapshot.activitiesById[snapshot.activeActivityId] ?? null : null,
1924
2211
  nodeStates,
1925
2212
  activeNodeId: snapshot.activeStepId ?? null,
1926
2213
  ...rowOutcomes ? { rowOutcomes } : {}
@@ -1937,14 +2224,29 @@ function buildPlayRunStatusSnapshot(input2) {
1937
2224
  finishedAt: input2.run.finishedAt ?? null
1938
2225
  });
1939
2226
  const terminalRunLogTail = extractTerminalRunLogTail(input2.run.result);
1940
- if (terminalRunLogTail && terminalRunLogTail.totalLogCount > ledgerSnapshot.totalLogCount) {
1941
- return buildSnapshotFromLedger({
1942
- ...ledgerSnapshot,
1943
- logTail: terminalRunLogTail.logTail,
1944
- totalLogCount: terminalRunLogTail.totalLogCount
1945
- });
1946
- }
1947
- return buildSnapshotFromLedger(ledgerSnapshot);
2227
+ const projectedSnapshot = terminalRunLogTail && terminalRunLogTail.totalLogCount > ledgerSnapshot.totalLogCount ? buildSnapshotFromLedger({
2228
+ ...ledgerSnapshot,
2229
+ logTail: terminalRunLogTail.logTail,
2230
+ totalLogCount: terminalRunLogTail.totalLogCount
2231
+ }) : buildSnapshotFromLedger(ledgerSnapshot);
2232
+ const activity = projectPlayRunActivity({
2233
+ runId: input2.run.workflowId,
2234
+ playName: input2.run.name,
2235
+ status: projectedSnapshot.status,
2236
+ updatedAt: projectedSnapshot.updatedAt,
2237
+ waitKind: input2.run.waitKind ?? input2.run.wait?.kind ?? null,
2238
+ waitUntil: input2.run.waitUntil,
2239
+ eventKey: input2.run.wait?.eventKey ?? null,
2240
+ runtimeBackend: input2.run.runtimeBackend,
2241
+ activeNodeId: input2.run.activeBoundaryId ?? projectedSnapshot.activeNodeId,
2242
+ nodeStates: projectedSnapshot.nodeStates,
2243
+ datasets: projectedSnapshot.datasets,
2244
+ explicit: projectedSnapshot.activities
2245
+ });
2246
+ return {
2247
+ ...projectedSnapshot,
2248
+ activity
2249
+ };
1948
2250
  }
1949
2251
  function makeRunStreamEvent(input2) {
1950
2252
  return {
@@ -2165,7 +2467,8 @@ function diffPlayRunStreamEvents(input2) {
2165
2467
  payload: {
2166
2468
  runId: snapshot.runId,
2167
2469
  status: snapshot.status,
2168
- updatedAt: snapshot.updatedAt
2470
+ updatedAt: snapshot.updatedAt,
2471
+ ...snapshot.activity ? { activity: snapshot.activity } : {}
2169
2472
  }
2170
2473
  })
2171
2474
  );
@@ -2685,7 +2988,7 @@ function resolveToolExecuteTimeoutMs(toolId, input2) {
2685
2988
  }
2686
2989
  var RUNS_FAILED_LOG_LIMIT = 20;
2687
2990
  var RUN_LOGS_PAGE_LIMIT = 1e3;
2688
- function isRecord3(value) {
2991
+ function isRecord4(value) {
2689
2992
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
2690
2993
  }
2691
2994
  function isPrebuiltPlayDescription(play) {
@@ -2842,7 +3145,7 @@ function updatePlayLiveStatusState(state, event) {
2842
3145
  }
2843
3146
  const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : isPlayRunPackage(payload) ? payload.run.id : state.runId;
2844
3147
  const status = normalizeLiveStatus(payload.status) ?? (isPlayRunPackage(payload) ? normalizeLiveStatus(payload.run.status) : null) ?? state.status;
2845
- const progressPayload = isRecord3(payload.progress) ? payload.progress : {};
3148
+ const progressPayload = isRecord4(payload.progress) ? payload.progress : {};
2846
3149
  if (event.type === "play.run.final_status" && state.logs.length === 0 && state.lastLogSeq === 0) {
2847
3150
  const payloadLogs = readStringArray(payload.logs);
2848
3151
  const progressLogs = readStringArray(progressPayload.logs);
@@ -2976,9 +3279,9 @@ var DeeplineClient = class {
2976
3279
  return fields.length > 0 ? { fields } : schema;
2977
3280
  }
2978
3281
  schemaMetadata(schema, key) {
2979
- if (!isRecord3(schema)) return null;
3282
+ if (!isRecord4(schema)) return null;
2980
3283
  const value = schema[key];
2981
- return isRecord3(value) ? value : null;
3284
+ return isRecord4(value) ? value : null;
2982
3285
  }
2983
3286
  playRunCommand(play, options) {
2984
3287
  const target = play.reference || play.name;
@@ -3027,7 +3330,7 @@ var DeeplineClient = class {
3027
3330
  aliases,
3028
3331
  inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
3029
3332
  outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
3030
- staticPipeline: isRecord3(play.staticPipeline) ? play.staticPipeline : isRecord3(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord3(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
3333
+ staticPipeline: isRecord4(play.staticPipeline) ? play.staticPipeline : isRecord4(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord4(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
3031
3334
  ...csvInput ? { csvInput } : {},
3032
3335
  ...rowOutputSchema ? { rowOutputSchema } : {},
3033
3336
  runCommand: runCommand2,
@@ -3105,6 +3408,14 @@ var DeeplineClient = class {
3105
3408
  );
3106
3409
  return res.tools;
3107
3410
  }
3411
+ /** List discoverable providers without requiring a local plugin catalog. */
3412
+ async listProviders(options) {
3413
+ const suffix = options?.changed ? "?changed=true" : "";
3414
+ const res = await this.http.get(
3415
+ `/api/v2/tools/providers${suffix}`
3416
+ );
3417
+ return res.providers;
3418
+ }
3108
3419
  /**
3109
3420
  * Search available tools using Deepline's ranked backend search.
3110
3421
  *
@@ -7864,14 +8175,14 @@ function sanitizeCsvProjectionInfo(input2) {
7864
8175
  const rows = input2.rows.map(stripCsvProjectionFields);
7865
8176
  return { rows, columns };
7866
8177
  }
7867
- function isRecord4(value) {
8178
+ function isRecord5(value) {
7868
8179
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
7869
8180
  }
7870
8181
  function isSerializedDataset(value) {
7871
- return isRecord4(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
8182
+ return isRecord5(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
7872
8183
  }
7873
8184
  function isPackagedDatasetOutput(value) {
7874
- return isRecord4(value) && value.kind === "dataset" && isRecord4(value.preview) && Array.isArray(value.preview.rows);
8185
+ return isRecord5(value) && value.kind === "dataset" && isRecord5(value.preview) && Array.isArray(value.preview.rows);
7875
8186
  }
7876
8187
  function pathParts(path) {
7877
8188
  return path.split(".").map((part) => part.trim()).filter(Boolean);
@@ -7879,7 +8190,7 @@ function pathParts(path) {
7879
8190
  function valueAtPath(root, path) {
7880
8191
  let cursor = root;
7881
8192
  for (const part of pathParts(path)) {
7882
- if (!isRecord4(cursor)) {
8193
+ if (!isRecord5(cursor)) {
7883
8194
  return void 0;
7884
8195
  }
7885
8196
  cursor = cursor[part];
@@ -7887,17 +8198,17 @@ function valueAtPath(root, path) {
7887
8198
  return cursor;
7888
8199
  }
7889
8200
  function totalRowsForDataset(result, datasetPath) {
7890
- const metadata = isRecord4(result._metadata) ? result._metadata : null;
8201
+ const metadata = isRecord5(result._metadata) ? result._metadata : null;
7891
8202
  const parentPath = datasetPath.split(".").slice(0, -1).join(".");
7892
8203
  const parent = parentPath ? valueAtPath({ result }, parentPath) : result;
7893
- return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord4(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
8204
+ return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord5(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
7894
8205
  }
7895
8206
  function rowArray(value) {
7896
8207
  if (!Array.isArray(value)) {
7897
8208
  return null;
7898
8209
  }
7899
8210
  const rows = value.filter(
7900
- (row) => isRecord4(row)
8211
+ (row) => isRecord5(row)
7901
8212
  );
7902
8213
  return rows.length === value.length ? rows : null;
7903
8214
  }
@@ -7921,7 +8232,7 @@ function inferColumns(rows) {
7921
8232
  return columns;
7922
8233
  }
7923
8234
  function columnsFromDatasetSummary(summary) {
7924
- if (!isRecord4(summary) || !isRecord4(summary.columnStats)) {
8235
+ if (!isRecord5(summary) || !isRecord5(summary.columnStats)) {
7925
8236
  return [];
7926
8237
  }
7927
8238
  return Object.keys(summary.columnStats).filter((column) => column);
@@ -7969,7 +8280,7 @@ function canonicalRowsInfoFromCandidate(input2) {
7969
8280
  datasetId: typeof candidate.value.datasetId === "string" ? candidate.value.datasetId : null,
7970
8281
  tableNamespace: typeof candidate.value.tableNamespace === "string" ? candidate.value.tableNamespace : null,
7971
8282
  ...candidate.value.recovered === true ? { recovered: true } : {},
7972
- ...isRecord4(candidate.value.exportUnavailable) && (candidate.value.exportUnavailable.reason === "empty_dataset" || candidate.value.exportUnavailable.reason === "shared_table_namespace") ? {
8283
+ ...isRecord5(candidate.value.exportUnavailable) && (candidate.value.exportUnavailable.reason === "empty_dataset" || candidate.value.exportUnavailable.reason === "shared_table_namespace") ? {
7973
8284
  exportUnavailableReason: candidate.value.exportUnavailable.reason,
7974
8285
  ...typeof candidate.value.exportUnavailable.message === "string" ? {
7975
8286
  exportUnavailableMessage: candidate.value.exportUnavailable.message
@@ -8017,7 +8328,7 @@ function collectDatasetCandidates(input2) {
8017
8328
  });
8018
8329
  return;
8019
8330
  }
8020
- if (!isRecord4(input2.value)) {
8331
+ if (!isRecord5(input2.value)) {
8021
8332
  return;
8022
8333
  }
8023
8334
  for (const [key, child] of Object.entries(input2.value)) {
@@ -8034,12 +8345,12 @@ function collectDatasetCandidates(input2) {
8034
8345
  }
8035
8346
  }
8036
8347
  function collectCanonicalRowsInfos(statusOrResult) {
8037
- const root = isRecord4(statusOrResult) ? statusOrResult : null;
8038
- const result = isRecord4(root?.result) ? root.result : root;
8348
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
8349
+ const result = isRecord5(root?.result) ? root.result : root;
8039
8350
  if (!result) {
8040
8351
  return [];
8041
8352
  }
8042
- const metadata = isRecord4(result._metadata) ? result._metadata : null;
8353
+ const metadata = isRecord5(result._metadata) ? result._metadata : null;
8043
8354
  const totalFromMetadata = metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count;
8044
8355
  const candidates = [
8045
8356
  {
@@ -8063,8 +8374,8 @@ function collectCanonicalRowsInfos(statusOrResult) {
8063
8374
  total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
8064
8375
  }
8065
8376
  ];
8066
- if (isRecord4(result.output)) {
8067
- const outputMetadata = isRecord4(result.output._metadata) ? result.output._metadata : null;
8377
+ if (isRecord5(result.output)) {
8378
+ const outputMetadata = isRecord5(result.output._metadata) ? result.output._metadata : null;
8068
8379
  const outputTotalFromMetadata = outputMetadata?.totalRows ?? outputMetadata?.rowCount ?? outputMetadata?.count;
8069
8380
  candidates.push(
8070
8381
  {
@@ -8091,14 +8402,14 @@ function collectCanonicalRowsInfos(statusOrResult) {
8091
8402
  }
8092
8403
  if (Array.isArray(result.steps)) {
8093
8404
  result.steps.forEach((step, index) => {
8094
- if (!isRecord4(step) || !isRecord4(step.output)) {
8405
+ if (!isRecord5(step) || !isRecord5(step.output)) {
8095
8406
  return;
8096
8407
  }
8097
8408
  const source = typeof step.output.path === "string" ? step.output.path : typeof step.id === "string" ? `steps.${step.id}.output` : `steps.${index}.output`;
8098
8409
  candidates.push({
8099
8410
  source,
8100
8411
  value: step.output,
8101
- total: step.output.rowCount ?? (isRecord4(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord4(step.progress) ? step.progress.total : void 0)
8412
+ total: step.output.rowCount ?? (isRecord5(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord5(step.progress) ? step.progress.total : void 0)
8102
8413
  });
8103
8414
  });
8104
8415
  }
@@ -8126,15 +8437,15 @@ function collectCanonicalRowsInfos(statusOrResult) {
8126
8437
  return infos;
8127
8438
  }
8128
8439
  function collectPackagedDatasetCandidates(statusOrResult) {
8129
- const root = isRecord4(statusOrResult) ? statusOrResult : null;
8440
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
8130
8441
  if (!root) {
8131
8442
  return [];
8132
8443
  }
8133
- const pkg = isRecord4(root.package) ? root.package : root;
8444
+ const pkg = isRecord5(root.package) ? root.package : root;
8134
8445
  const datasets = Array.isArray(pkg.datasets) ? pkg.datasets : [];
8135
8446
  const candidates = [];
8136
8447
  for (const output2 of datasets) {
8137
- if (!isRecord4(output2) || !isPackagedDatasetOutput(output2)) {
8448
+ if (!isRecord5(output2) || !isPackagedDatasetOutput(output2)) {
8138
8449
  continue;
8139
8450
  }
8140
8451
  const source = typeof output2.path === "string" && output2.path.trim() ? output2.path.trim() : null;
@@ -8144,18 +8455,18 @@ function collectPackagedDatasetCandidates(statusOrResult) {
8144
8455
  candidates.push({
8145
8456
  source,
8146
8457
  value: output2,
8147
- total: output2.rowCount ?? (isRecord4(output2.preview) ? output2.preview.totalRows : void 0)
8458
+ total: output2.rowCount ?? (isRecord5(output2.preview) ? output2.preview.totalRows : void 0)
8148
8459
  });
8149
8460
  }
8150
8461
  return candidates;
8151
8462
  }
8152
8463
  function collectPackagedStepDatasetCandidates(statusOrResult) {
8153
- const root = isRecord4(statusOrResult) ? statusOrResult : null;
8464
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
8154
8465
  if (!root) return [];
8155
- const pkg = isRecord4(root.package) ? root.package : root;
8466
+ const pkg = isRecord5(root.package) ? root.package : root;
8156
8467
  const steps = Array.isArray(pkg.steps) ? pkg.steps : [];
8157
8468
  return steps.flatMap((step) => {
8158
- if (!isRecord4(step) || !isPackagedDatasetOutput(step.output)) return [];
8469
+ if (!isRecord5(step) || !isPackagedDatasetOutput(step.output)) return [];
8159
8470
  const source = typeof step.output.path === "string" && step.output.path.trim() ? step.output.path.trim() : null;
8160
8471
  return source ? [
8161
8472
  {
@@ -8167,8 +8478,8 @@ function collectPackagedStepDatasetCandidates(statusOrResult) {
8167
8478
  });
8168
8479
  }
8169
8480
  function collectSerializedDatasetRowsInfos(statusOrResult) {
8170
- const root = isRecord4(statusOrResult) ? statusOrResult : null;
8171
- const result = isRecord4(root?.result) ? root.result : root;
8481
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
8482
+ const result = isRecord5(root?.result) ? root.result : root;
8172
8483
  const candidates = [];
8173
8484
  if (result) {
8174
8485
  collectDatasetCandidates({
@@ -8176,7 +8487,7 @@ function collectSerializedDatasetRowsInfos(statusOrResult) {
8176
8487
  path: "result",
8177
8488
  output: candidates
8178
8489
  });
8179
- if (isRecord4(result.output)) {
8490
+ if (isRecord5(result.output)) {
8180
8491
  collectDatasetCandidates({
8181
8492
  value: result.output,
8182
8493
  path: "result",
@@ -8254,13 +8565,13 @@ function summarizeSampleValue(value, depth = 0) {
8254
8565
  if (typeof parsed === "number" || typeof parsed === "boolean") return parsed;
8255
8566
  if (depth >= 3) {
8256
8567
  if (Array.isArray(parsed)) return [];
8257
- if (isRecord4(parsed)) return {};
8568
+ if (isRecord5(parsed)) return {};
8258
8569
  return compactScalar(parsed);
8259
8570
  }
8260
8571
  if (Array.isArray(parsed)) {
8261
8572
  return parsed.slice(0, 3).map((item) => summarizeSampleValue(item, depth + 1));
8262
8573
  }
8263
- if (isRecord4(parsed)) {
8574
+ if (isRecord5(parsed)) {
8264
8575
  const out = {};
8265
8576
  for (const [key, nested] of Object.entries(parsed)) {
8266
8577
  if (["__dl", "meta", "metadata"].includes(key)) {
@@ -8291,7 +8602,7 @@ function compactCell(value) {
8291
8602
  }
8292
8603
  return `[${parsed.length} items]`;
8293
8604
  }
8294
- if (isRecord4(parsed)) {
8605
+ if (isRecord5(parsed)) {
8295
8606
  for (const key of ["matched_result", "output"]) {
8296
8607
  if (parsed[key] !== null && parsed[key] !== void 0 && parsed[key] !== "") {
8297
8608
  return compactCell(parsed[key]);
@@ -9380,17 +9691,17 @@ function parsePositiveInteger2(value, flagName) {
9380
9691
  }
9381
9692
  return parsed;
9382
9693
  }
9383
- function isRecord5(value) {
9694
+ function isRecord6(value) {
9384
9695
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
9385
9696
  }
9386
9697
  function stringValue(value) {
9387
9698
  return typeof value === "string" ? value.trim() : "";
9388
9699
  }
9389
9700
  function extractionEntries(value) {
9390
- if (Array.isArray(value)) return value.filter(isRecord5);
9391
- if (!isRecord5(value)) return [];
9701
+ if (Array.isArray(value)) return value.filter(isRecord6);
9702
+ if (!isRecord6(value)) return [];
9392
9703
  return Object.entries(value).map(
9393
- ([name, entry]) => isRecord5(entry) ? { name, ...entry } : { name }
9704
+ ([name, entry]) => isRecord6(entry) ? { name, ...entry } : { name }
9394
9705
  );
9395
9706
  }
9396
9707
  var PlayBootstrapError = class extends Error {
@@ -9952,7 +10263,7 @@ function readCsvSampleRows(sample) {
9952
10263
  relax_column_count: true,
9953
10264
  trim: true
9954
10265
  });
9955
- return Array.isArray(parsedRows) ? parsedRows.filter(isRecord5) : [];
10266
+ return Array.isArray(parsedRows) ? parsedRows.filter(isRecord6) : [];
9956
10267
  }
9957
10268
  function readSourceCsvColumnSpecs(csvPath) {
9958
10269
  const sample = readCsvSample(csvPath);
@@ -9985,16 +10296,16 @@ function packagedCsvPathForPlay(csvPath) {
9985
10296
  return portablePath.startsWith(".") ? portablePath : `./${portablePath}`;
9986
10297
  }
9987
10298
  function getterNamesFromTool(tool, kind) {
9988
- const usageGuidance = isRecord5(tool?.usageGuidance) ? tool.usageGuidance : {};
9989
- const resultGuidance = isRecord5(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord5(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
10299
+ const usageGuidance = isRecord6(tool?.usageGuidance) ? tool.usageGuidance : {};
10300
+ const resultGuidance = isRecord6(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord6(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
9990
10301
  const key = kind === "list" ? "extractedLists" : "extractedValues";
9991
10302
  const snakeKey = kind === "list" ? "extracted_lists" : "extracted_values";
9992
10303
  return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
9993
10304
  }
9994
10305
  function targetGettersFromTool(tool) {
9995
- const record = isRecord5(tool) ? tool : {};
10306
+ const record = isRecord6(tool) ? tool : {};
9996
10307
  const raw = record.targetGetters ?? record.target_getters;
9997
- if (!isRecord5(raw)) return {};
10308
+ if (!isRecord6(raw)) return {};
9998
10309
  const entries = [];
9999
10310
  for (const [target, value] of Object.entries(raw)) {
10000
10311
  const paths = Array.isArray(value) ? value.map((path) => typeof path === "string" ? path.trim() : "").filter(Boolean) : [];
@@ -10015,10 +10326,10 @@ function listRowCandidateKeysFromTool(tool) {
10015
10326
  return [...keys].sort();
10016
10327
  }
10017
10328
  function inputPropertyNames(schema) {
10018
- if (!isRecord5(schema)) return [];
10019
- if (isRecord5(schema.properties)) return Object.keys(schema.properties);
10329
+ if (!isRecord6(schema)) return [];
10330
+ if (isRecord6(schema.properties)) return Object.keys(schema.properties);
10020
10331
  if (Array.isArray(schema.fields)) {
10021
- return schema.fields.filter(isRecord5).map((field) => stringValue(field.name)).filter(Boolean);
10332
+ return schema.fields.filter(isRecord6).map((field) => stringValue(field.name)).filter(Boolean);
10022
10333
  }
10023
10334
  return [];
10024
10335
  }
@@ -10032,7 +10343,7 @@ function schemaFieldDetails(schema) {
10032
10343
  return { required, optional };
10033
10344
  }
10034
10345
  function jsonSchemaTypeExpression(schema) {
10035
- if (!isRecord5(schema)) return "unknown";
10346
+ if (!isRecord6(schema)) return "unknown";
10036
10347
  const type = schema.type;
10037
10348
  if (Array.isArray(type)) {
10038
10349
  return type.map((entry) => jsonSchemaTypeExpression({ ...schema, type: entry })).join(" | ");
@@ -10062,7 +10373,7 @@ function jsonSchemaTypeExpression(schema) {
10062
10373
  }
10063
10374
  }
10064
10375
  function objectPropertySchema(schema, property) {
10065
- return isRecord5(schema) && isRecord5(schema.properties) ? schema.properties[property] : null;
10376
+ return isRecord6(schema) && isRecord6(schema.properties) ? schema.properties[property] : null;
10066
10377
  }
10067
10378
  function playOutputHasField(schema, field) {
10068
10379
  return objectPropertySchema(schema, field) != null;
@@ -10238,14 +10549,14 @@ ${indent2.slice(2)}}`;
10238
10549
  }
10239
10550
  function requiredPlayInputFields(play) {
10240
10551
  const schema = play?.inputSchema;
10241
- if (!isRecord5(schema)) return [];
10552
+ if (!isRecord6(schema)) return [];
10242
10553
  if (Array.isArray(schema.required)) {
10243
10554
  return schema.required.filter(
10244
10555
  (value) => typeof value === "string"
10245
10556
  );
10246
10557
  }
10247
10558
  if (Array.isArray(schema.fields)) {
10248
- return schema.fields.filter(isRecord5).filter(
10559
+ return schema.fields.filter(isRecord6).filter(
10249
10560
  (field) => field.required === true && typeof field.name === "string"
10250
10561
  ).map((field) => String(field.name));
10251
10562
  }
@@ -10426,7 +10737,7 @@ function validateBootstrapRoutes(input2) {
10426
10737
  }
10427
10738
  }
10428
10739
  function staticPipelineSubsteps(pipeline) {
10429
- if (!isRecord5(pipeline)) return [];
10740
+ if (!isRecord6(pipeline)) return [];
10430
10741
  return [
10431
10742
  ...extractionEntries(pipeline.stages),
10432
10743
  ...extractionEntries(pipeline.substeps)
@@ -10434,7 +10745,7 @@ function staticPipelineSubsteps(pipeline) {
10434
10745
  }
10435
10746
  function playUsesMapBackedRuntime(play) {
10436
10747
  const pipeline = play?.staticPipeline;
10437
- if (!isRecord5(pipeline)) return false;
10748
+ if (!isRecord6(pipeline)) return false;
10438
10749
  if (stringValue(pipeline.tableNamespace)) return true;
10439
10750
  return staticPipelineSubsteps(pipeline).some((substep) => {
10440
10751
  if (stringValue(substep.type) === "map") return true;
@@ -10443,7 +10754,7 @@ function playUsesMapBackedRuntime(play) {
10443
10754
  aliases: [],
10444
10755
  runCommand: "",
10445
10756
  examples: [],
10446
- staticPipeline: isRecord5(substep.pipeline) ? substep.pipeline : null
10757
+ staticPipeline: isRecord6(substep.pipeline) ? substep.pipeline : null
10447
10758
  });
10448
10759
  });
10449
10760
  }
@@ -12566,22 +12877,96 @@ function getStatusFromLiveEvent(event) {
12566
12877
  const payload = getEventPayload(event);
12567
12878
  return playStatusValue(payload.status) ?? playStatusValue(getRunRecordFromPackage(payload)?.status);
12568
12879
  }
12569
- function getWaitKindFromLiveEvent(event) {
12880
+ function readLiveRunField(event, field) {
12570
12881
  const payload = getEventPayload(event);
12571
- const progress = payload.progress && typeof payload.progress === "object" ? payload.progress : null;
12572
- const waitKind = payload.waitKind ?? progress?.waitKind;
12573
- return typeof waitKind === "string" && waitKind.trim() ? waitKind.trim() : null;
12882
+ const run = getRunRecordFromPackage(payload);
12883
+ const records = [payload, payload.progress, run, run?.progress].filter(
12884
+ (value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
12885
+ );
12886
+ for (const record of records) {
12887
+ if (record[field] !== void 0) return record[field];
12888
+ }
12889
+ return void 0;
12574
12890
  }
12575
- function writePlayWaitingHint(input2) {
12576
- if (getStatusFromLiveEvent(input2.event) !== "waiting") return;
12891
+ function getLiveRunStringField(event, field) {
12892
+ const value = readLiveRunField(event, field);
12893
+ return typeof value === "string" && value.trim() ? value.trim() : null;
12894
+ }
12895
+ function getLiveRunActivity(event) {
12896
+ const payload = getEventPayload(event);
12897
+ const run = getRunRecordFromPackage(payload);
12898
+ const candidates = [payload.activity, run?.activity];
12899
+ for (const candidate of candidates) {
12900
+ if (candidate && typeof candidate === "object" && !Array.isArray(candidate) && typeof candidate.summary === "string" && candidate.observation && typeof candidate.observation === "object") {
12901
+ return candidate;
12902
+ }
12903
+ }
12904
+ return null;
12905
+ }
12906
+ function getRunLifecycleHint(input2) {
12577
12907
  const runId = getRunIdFromLiveEvent(input2.event);
12578
- if (!runId || input2.state.waitingRunId === runId) return;
12579
- input2.state.waitingRunId = runId;
12580
- const waitKind = getWaitKindFromLiveEvent(input2.event);
12581
- 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.";
12582
- input2.progress.writeLine(
12583
- `[play waiting] ${runId} ${message} The command will continue watching; inspect it with 'deepline runs get ${runId} --full --json'.`
12908
+ const status = getStatusFromLiveEvent(input2.event);
12909
+ if (!runId || status !== "queued" && status !== "running" && status !== "waiting") {
12910
+ return null;
12911
+ }
12912
+ const activity = getLiveRunActivity(input2.event);
12913
+ const activityConflictsWithDurableWait = status === "waiting" && activity?.observation.state.kind === "active" && activity.observation.target.kind !== "runner";
12914
+ if (activity && activity.classified !== false && !activityConflictsWithDurableWait) {
12915
+ const state = activity.observation.state;
12916
+ const signature2 = [
12917
+ runId,
12918
+ "activity",
12919
+ activity.observation.activityId,
12920
+ JSON.stringify(state)
12921
+ ].join(":");
12922
+ const inspect2 = `'deepline runs get ${runId} --full --json'`;
12923
+ 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}.`;
12924
+ return {
12925
+ signature: signature2,
12926
+ line: `[play activity] ${runId} ${activity.summary} ${followUp}`
12927
+ };
12928
+ }
12929
+ const waitKind = getLiveRunStringField(input2.event, "waitKind");
12930
+ const activeBoundaryId = getLiveRunStringField(
12931
+ input2.event,
12932
+ "activeBoundaryId"
12584
12933
  );
12934
+ const signature = [
12935
+ runId,
12936
+ status,
12937
+ waitKind ?? "",
12938
+ activeBoundaryId ?? ""
12939
+ ].join(":");
12940
+ const inspect = `'deepline runs get ${runId} --full --json'`;
12941
+ if (waitKind === "detached_runner") {
12942
+ return {
12943
+ signature,
12944
+ 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}.`
12945
+ };
12946
+ }
12947
+ if (status !== "waiting") return null;
12948
+ if (waitKind === "sleep") {
12949
+ return {
12950
+ signature,
12951
+ line: `[play waiting] ${runId} is sleeping until its scheduled resume. The command will continue watching; inspect it with ${inspect}.`
12952
+ };
12953
+ }
12954
+ if (waitKind === "integration_event" || waitKind === "integration_event_batch" || waitKind === null) {
12955
+ return {
12956
+ signature,
12957
+ line: `[play waiting] ${runId} is waiting for an external approval or event. The command will continue watching; inspect it with ${inspect}.`
12958
+ };
12959
+ }
12960
+ return {
12961
+ signature,
12962
+ line: `[play waiting] ${runId} is paused on durable work (${waitKind}). The command will continue watching; inspect it with ${inspect}.`
12963
+ };
12964
+ }
12965
+ function writePlayWaitingHint(input2) {
12966
+ const hint = getRunLifecycleHint({ event: input2.event });
12967
+ if (!hint || input2.state.lifecycleHintSignature === hint.signature) return;
12968
+ input2.state.lifecycleHintSignature = hint.signature;
12969
+ input2.progress.writeLine(hint.line);
12585
12970
  }
12586
12971
  function getFinalStatusFromLiveEvent(event) {
12587
12972
  if (event.type !== "play.run.snapshot" && event.type !== "play.run.status" && event.type !== "play.run.final_status") {
@@ -12837,13 +13222,18 @@ function getRunningHeartbeatLine(input2) {
12837
13222
  if (status !== "queued" && status !== "running" && status !== "waiting") {
12838
13223
  return null;
12839
13224
  }
13225
+ const activity = getLiveRunActivity(input2.event);
13226
+ const activityConflictsWithDurableWait = status === "waiting" && activity?.observation.state.kind === "active" && activity.observation.target.kind !== "runner";
13227
+ if (activity && activity.classified !== false && !activityConflictsWithDurableWait) {
13228
+ return `activity ${input2.playName}: ${activity.summary}`;
13229
+ }
12840
13230
  const tableNamespace = extractTableNamespaceFromLiveEvent(input2.event);
12841
13231
  const target = tableNamespace ? formatProgressLabel(tableNamespace) : input2.playName;
12842
13232
  if (status === "queued") {
12843
13233
  return `queued ${target}: waiting for worker capacity`;
12844
13234
  }
12845
13235
  if (status === "waiting") {
12846
- if (getWaitKindFromLiveEvent(input2.event) === "detached_runner") {
13236
+ if (getLiveRunStringField(input2.event, "waitKind") === "detached_runner") {
12847
13237
  return `running ${target}: executing in detached runtime`;
12848
13238
  }
12849
13239
  return `waiting ${target}: waiting on external work`;
@@ -15102,7 +15492,7 @@ function extractPlayValidationErrors(value) {
15102
15492
  if (value instanceof DeeplineError) {
15103
15493
  return extractPlayValidationErrors(value.details);
15104
15494
  }
15105
- if (!isRecord6(value)) {
15495
+ if (!isRecord7(value)) {
15106
15496
  return [];
15107
15497
  }
15108
15498
  const directErrors = stringArrayField(value, "errors");
@@ -15542,7 +15932,7 @@ function shouldUseLocalOnlyPlayCheck() {
15542
15932
  const value = process.env.DEEPLINE_PLAY_CHECK_LOCAL_ONLY?.trim().toLowerCase();
15543
15933
  return value === "1" || value === "true" || value === "yes" || value === "on";
15544
15934
  }
15545
- function isRecord6(value) {
15935
+ function isRecord7(value) {
15546
15936
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
15547
15937
  }
15548
15938
  function stringValue2(value) {
@@ -15552,14 +15942,14 @@ function asArray(value) {
15552
15942
  return Array.isArray(value) ? value : [];
15553
15943
  }
15554
15944
  function extractionEntries2(value) {
15555
- if (Array.isArray(value)) return value.filter(isRecord6);
15556
- if (!isRecord6(value)) return [];
15945
+ if (Array.isArray(value)) return value.filter(isRecord7);
15946
+ if (!isRecord7(value)) return [];
15557
15947
  return Object.entries(value).map(
15558
- ([name, entry]) => isRecord6(entry) ? { name, ...entry } : { name }
15948
+ ([name, entry]) => isRecord7(entry) ? { name, ...entry } : { name }
15559
15949
  );
15560
15950
  }
15561
15951
  function firstRawPath(entry) {
15562
- const details = isRecord6(entry.details) ? entry.details : {};
15952
+ const details = isRecord7(entry.details) ? entry.details : {};
15563
15953
  const paths = [
15564
15954
  ...asArray(details.rawToolOutputPaths),
15565
15955
  ...asArray(details.raw_tool_output_paths),
@@ -15577,12 +15967,12 @@ function checkHintRawPath(value) {
15577
15967
  function collectStaticPipelineToolIds(staticPipeline) {
15578
15968
  const seen = /* @__PURE__ */ new Set();
15579
15969
  const visitPipeline = (pipeline) => {
15580
- if (!isRecord6(pipeline)) return;
15970
+ if (!isRecord7(pipeline)) return;
15581
15971
  for (const step of [
15582
15972
  ...asArray(pipeline.stages),
15583
15973
  ...asArray(pipeline.substeps)
15584
15974
  ]) {
15585
- if (!isRecord6(step)) continue;
15975
+ if (!isRecord7(step)) continue;
15586
15976
  if (step.type === "tool") {
15587
15977
  const toolId = stringValue2(step.toolId) || stringValue2(step.tool);
15588
15978
  if (toolId) seen.add(toolId);
@@ -15596,9 +15986,9 @@ function collectStaticPipelineToolIds(staticPipeline) {
15596
15986
  return [...seen].sort();
15597
15987
  }
15598
15988
  function toolGetterHintFromMetadata(toolId, tool) {
15599
- const usageGuidance = isRecord6(tool.usageGuidance) ? tool.usageGuidance : {};
15600
- const resultGuidance = isRecord6(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord6(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
15601
- const toolResponse = isRecord6(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord6(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
15989
+ const usageGuidance = isRecord7(tool.usageGuidance) ? tool.usageGuidance : {};
15990
+ const resultGuidance = isRecord7(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord7(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
15991
+ const toolResponse = isRecord7(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord7(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
15602
15992
  const lists = extractionEntries2(
15603
15993
  resultGuidance.extractedLists ?? resultGuidance.extracted_lists
15604
15994
  ).map((entry) => ({
@@ -19848,7 +20238,7 @@ function isMarkedTestAiInferenceCommand(command) {
19848
20238
  if (normalizeEnrichPlayRef(command.tool) !== "run_javascript") {
19849
20239
  return false;
19850
20240
  }
19851
- return isRecord7(command.payload) && command.payload[ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER] === true;
20241
+ return isRecord8(command.payload) && command.payload[ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER] === true;
19852
20242
  }
19853
20243
  function enrichDebugEnabled(env = process.env) {
19854
20244
  const raw = String(env.DEEPLINE_DEBUG_ENRICH ?? "").trim().toLowerCase();
@@ -20112,7 +20502,7 @@ function rewriteGeneratedPlayRerunForEnrich(status, enrichCommand) {
20112
20502
  if (Array.isArray(value)) {
20113
20503
  return value.map(rewrite);
20114
20504
  }
20115
- if (!isRecord7(value)) {
20505
+ if (!isRecord8(value)) {
20116
20506
  return value;
20117
20507
  }
20118
20508
  const next = Object.fromEntries(
@@ -20121,7 +20511,7 @@ function rewriteGeneratedPlayRerunForEnrich(status, enrichCommand) {
20121
20511
  key === "rerunCommand" && typeof entry === "string" ? enrichCommand : rewrite(entry)
20122
20512
  ])
20123
20513
  );
20124
- if (isRecord7(next.next) && typeof next.next.run === "string") {
20514
+ if (isRecord8(next.next) && typeof next.next.run === "string") {
20125
20515
  next.next = { ...next.next, run: enrichCommand };
20126
20516
  }
20127
20517
  return next;
@@ -20592,7 +20982,7 @@ async function resolveWatchedGeneratedPlayStatus(input2) {
20592
20982
  }
20593
20983
  return input2.client.runs.get(runId, { full: true });
20594
20984
  }
20595
- function isRecord7(value) {
20985
+ function isRecord8(value) {
20596
20986
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
20597
20987
  }
20598
20988
  async function captureStdout(run, options = {}) {
@@ -20844,15 +21234,15 @@ function readFirstEnrichDatasetActions(value) {
20844
21234
  return null;
20845
21235
  }
20846
21236
  const record = candidate;
20847
- const actions = isRecord7(record.actions) ? record.actions : null;
20848
- const currentQuery = isRecord7(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
20849
- const legacyQuery = isRecord7(actions?.query) ? actions.query : null;
21237
+ const actions = isRecord8(record.actions) ? record.actions : null;
21238
+ const currentQuery = isRecord8(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
21239
+ const legacyQuery = isRecord8(actions?.query) ? actions.query : null;
20850
21240
  const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
20851
21241
  if (query?.kind === "deepline_db_query") {
20852
21242
  return {
20853
21243
  dataset: record,
20854
21244
  query,
20855
- ...isRecord7(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
21245
+ ...isRecord8(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
20856
21246
  };
20857
21247
  }
20858
21248
  if (options.allowLegacy && record.kind === "dataset" && typeof record.queryDatasetCommand === "string" && record.queryDatasetCommand.trim()) {
@@ -20905,7 +21295,7 @@ function enrichCustomerDbJson(input2) {
20905
21295
  const dataset = actions.dataset;
20906
21296
  const sql = actionStringField(query, "sql") ?? parseSqlFromDbQueryCommand(actions.queryDatasetCommand);
20907
21297
  const datasetPath = actionStringField(query, "datasetPath") ?? actionStringField(dataset, "path") ?? actionStringField(dataset, "tableNamespace");
20908
- const api = isRecord7(query.api) ? query.api : null;
21298
+ const api = isRecord8(query.api) ? query.api : null;
20909
21299
  const apiPath = actionStringField(api ?? {}, "path") ?? "/api/v2/db/query";
20910
21300
  const apiMethod = actionStringField(api ?? {}, "method") ?? "POST";
20911
21301
  if (!datasetPath) {
@@ -20974,11 +21364,11 @@ function sqlStringLiteral(value) {
20974
21364
  return `'${value.replace(/'/g, "''")}'`;
20975
21365
  }
20976
21366
  function failureAliasFromCellMeta(cellMeta) {
20977
- if (!isRecord7(cellMeta)) {
21367
+ if (!isRecord8(cellMeta)) {
20978
21368
  return null;
20979
21369
  }
20980
21370
  for (const [alias, meta] of Object.entries(cellMeta)) {
20981
- if (!isRecord7(meta)) {
21371
+ if (!isRecord8(meta)) {
20982
21372
  continue;
20983
21373
  }
20984
21374
  const failure = failureCellFromMeta(meta, {});
@@ -21471,7 +21861,7 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
21471
21861
  return fallback;
21472
21862
  }
21473
21863
  function failureCellFromMeta(meta, fallback) {
21474
- if (!isRecord7(meta)) {
21864
+ if (!isRecord8(meta)) {
21475
21865
  return null;
21476
21866
  }
21477
21867
  const status = typeof meta.status === "string" ? meta.status.trim().toLowerCase() : "";
@@ -21491,7 +21881,7 @@ function failureCellFromMeta(meta, fallback) {
21491
21881
  };
21492
21882
  }
21493
21883
  function applyFailureCellMeta(row, cellMeta, fallback) {
21494
- if (!isRecord7(cellMeta)) {
21884
+ if (!isRecord8(cellMeta)) {
21495
21885
  return;
21496
21886
  }
21497
21887
  for (const [field, meta] of Object.entries(cellMeta)) {
@@ -21719,7 +22109,7 @@ function stableRowSnapshot(value) {
21719
22109
  }
21720
22110
  function cellFailureError(value) {
21721
22111
  const parsed = parseMaybeJsonObject(value);
21722
- if (!isRecord7(parsed)) {
22112
+ if (!isRecord8(parsed)) {
21723
22113
  const text = typeof parsed === "string" ? parsed.trim() : "";
21724
22114
  if (/^(?:[A-Za-z0-9_:-]+:\s*)?(?:Error|TypeError|ReferenceError|SyntaxError|RangeError):\s+/.test(
21725
22115
  text
@@ -21727,12 +22117,12 @@ function cellFailureError(value) {
21727
22117
  return { message: text };
21728
22118
  }
21729
22119
  }
21730
- if (!isRecord7(parsed)) {
22120
+ if (!isRecord8(parsed)) {
21731
22121
  return null;
21732
22122
  }
21733
22123
  const status = typeof parsed.status === "string" ? parsed.status.trim().toLowerCase() : "";
21734
22124
  const directError = typeof parsed.error === "string" ? parsed.error.trim() : typeof parsed.last_error === "string" ? parsed.last_error.trim() : "";
21735
- const result = isRecord7(parsed.result) ? parsed.result : null;
22125
+ const result = isRecord8(parsed.result) ? parsed.result : null;
21736
22126
  const resultError = typeof result?.error === "string" ? result.error.trim() : typeof result?.message === "string" ? result.message.trim() : "";
21737
22127
  if (!directError && !resultError && status !== "error" && status !== "failed") {
21738
22128
  return null;
@@ -21802,7 +22192,7 @@ function assignFlattenedFailurePath(target, field, value) {
21802
22192
  let cursor = target;
21803
22193
  for (const part of normalized.slice(0, -1)) {
21804
22194
  const existing = cursor[part];
21805
- if (!isRecord7(existing)) {
22195
+ if (!isRecord8(existing)) {
21806
22196
  const next = {};
21807
22197
  cursor[part] = next;
21808
22198
  cursor = next;
@@ -21966,10 +22356,10 @@ function waterfallExecutionSignal(status, spec) {
21966
22356
  let everyChildStatOnlyConditionSkipped = true;
21967
22357
  const childAliasesWithStats = /* @__PURE__ */ new Set();
21968
22358
  for (const childAlias of childAliases) {
21969
- for (const stat2 of summaries.map((summary) => summary[childAlias]).filter(isRecord7)) {
22359
+ for (const stat2 of summaries.map((summary) => summary[childAlias]).filter(isRecord8)) {
21970
22360
  sawChildStats = true;
21971
22361
  childAliasesWithStats.add(childAlias);
21972
- const execution = isRecord7(stat2.execution) ? stat2.execution : null;
22362
+ const execution = isRecord8(stat2.execution) ? stat2.execution : null;
21973
22363
  const executedSummary = parseExecutionSummary(
21974
22364
  execution?.["completed:executed"]
21975
22365
  );
@@ -21999,7 +22389,7 @@ function waterfallExecutionSignal(status, spec) {
21999
22389
  }
22000
22390
  function emptyWaterfallStatsEvidence(status, spec) {
22001
22391
  const summaries = collectColumnStats(status);
22002
- const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord7);
22392
+ const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord8);
22003
22393
  for (const stat2 of parentStats) {
22004
22394
  const nonEmpty = parseExecutionSummary(stat2.non_empty);
22005
22395
  if (nonEmpty?.total && nonEmpty.count === 0) {
@@ -22013,7 +22403,7 @@ function emptyWaterfallStatsEvidence(status, spec) {
22013
22403
  let selectedRows = 0;
22014
22404
  let sawStatsForEveryChild = true;
22015
22405
  for (const childAlias of childAliases) {
22016
- const stat2 = summaries.map((summary) => summary[childAlias]).find(isRecord7);
22406
+ const stat2 = summaries.map((summary) => summary[childAlias]).find(isRecord8);
22017
22407
  if (!stat2) {
22018
22408
  sawStatsForEveryChild = false;
22019
22409
  break;
@@ -22022,7 +22412,7 @@ function emptyWaterfallStatsEvidence(status, spec) {
22022
22412
  if ((nonEmpty?.count ?? 0) > 0) {
22023
22413
  return null;
22024
22414
  }
22025
- const execution = isRecord7(stat2.execution) ? stat2.execution : null;
22415
+ const execution = isRecord8(stat2.execution) ? stat2.execution : null;
22026
22416
  const executed = parseExecutionSummary(execution?.["completed:executed"]);
22027
22417
  const reused = parseExecutionSummary(execution?.["completed:reused"]);
22028
22418
  const skipped = parseExecutionSummary(execution?.["skipped:condition"]);
@@ -22064,11 +22454,11 @@ function collectStatusFailureJobs(input2) {
22064
22454
  const jobs = [];
22065
22455
  aliases.forEach((spec, aliasIndex) => {
22066
22456
  const { alias } = spec;
22067
- const stat2 = summaries.map((summary) => summary[alias]).find(isRecord7);
22457
+ const stat2 = summaries.map((summary) => summary[alias]).find(isRecord8);
22068
22458
  if (!stat2) {
22069
22459
  return;
22070
22460
  }
22071
- const execution = isRecord7(stat2.execution) ? stat2.execution : null;
22461
+ const execution = isRecord8(stat2.execution) ? stat2.execution : null;
22072
22462
  const failedCount = Math.min(
22073
22463
  selectedRows,
22074
22464
  Math.max(
@@ -22175,10 +22565,10 @@ function collectColumnStats(status) {
22175
22565
  value.forEach(visit);
22176
22566
  return;
22177
22567
  }
22178
- if (!isRecord7(value)) {
22568
+ if (!isRecord8(value)) {
22179
22569
  return;
22180
22570
  }
22181
- if (isRecord7(value.columnStats)) {
22571
+ if (isRecord8(value.columnStats)) {
22182
22572
  summaries.push(value.columnStats);
22183
22573
  }
22184
22574
  Object.values(value).forEach(visit);
@@ -22190,12 +22580,12 @@ function firstAliasExecutionCounts(input2) {
22190
22580
  const aliases = collectConfigScalarAliasOrder(input2.config);
22191
22581
  const summaries = collectColumnStats(input2.status);
22192
22582
  for (const alias of aliases) {
22193
- const stat2 = summaries.map((summary) => summary[alias]).find(isRecord7);
22583
+ const stat2 = summaries.map((summary) => summary[alias]).find(isRecord8);
22194
22584
  if (!stat2) continue;
22195
22585
  if (input2.forceAliases.has(normalizeAlias2(alias))) {
22196
22586
  return { executed: input2.selectedRows, reused: 0 };
22197
22587
  }
22198
- const execution = isRecord7(stat2.execution) ? stat2.execution : null;
22588
+ const execution = isRecord8(stat2.execution) ? stat2.execution : null;
22199
22589
  if (!execution) continue;
22200
22590
  return {
22201
22591
  executed: parseExecutionCount(execution["completed:executed"]),
@@ -22222,14 +22612,14 @@ function rewriteEnrichJsonStatus(input2) {
22222
22612
  if (Array.isArray(value)) {
22223
22613
  return value.map(rewrite);
22224
22614
  }
22225
- if (!isRecord7(value)) {
22615
+ if (!isRecord8(value)) {
22226
22616
  return value;
22227
22617
  }
22228
22618
  const next = {};
22229
22619
  for (const [key, entry] of Object.entries(value)) {
22230
22620
  next[key] = rewrite(entry);
22231
22621
  }
22232
- if (isRecord7(next.progress)) {
22622
+ if (isRecord8(next.progress)) {
22233
22623
  next.progress = {
22234
22624
  ...next.progress,
22235
22625
  ...selectedRows > 0 ? { total: selectedRows } : {},
@@ -22238,8 +22628,8 @@ function rewriteEnrichJsonStatus(input2) {
22238
22628
  ...failedRows > 0 ? { failed: failedRows, pending: 0 } : {}
22239
22629
  };
22240
22630
  }
22241
- if (isRecord7(next.summary)) {
22242
- const rowCounts = isRecord7(next.summary.rowCounts) ? next.summary.rowCounts : null;
22631
+ if (isRecord8(next.summary)) {
22632
+ const rowCounts = isRecord8(next.summary.rowCounts) ? next.summary.rowCounts : null;
22243
22633
  if (failedRows > 0) {
22244
22634
  next.summary = {
22245
22635
  ...next.summary,
@@ -22252,11 +22642,11 @@ function rewriteEnrichJsonStatus(input2) {
22252
22642
  };
22253
22643
  }
22254
22644
  }
22255
- if (isRecord7(next.columnStats) && selectedRows > 0) {
22645
+ if (isRecord8(next.columnStats) && selectedRows > 0) {
22256
22646
  const columnStats = { ...next.columnStats };
22257
22647
  for (const alias of forcedAliases) {
22258
- const stat2 = isRecord7(columnStats[alias]) ? columnStats[alias] : null;
22259
- const execution = isRecord7(stat2?.execution) ? stat2.execution : null;
22648
+ const stat2 = isRecord8(columnStats[alias]) ? columnStats[alias] : null;
22649
+ const execution = isRecord8(stat2?.execution) ? stat2.execution : null;
22260
22650
  if (!stat2 || !execution) continue;
22261
22651
  columnStats[alias] = {
22262
22652
  ...stat2,
@@ -22275,14 +22665,14 @@ function rewriteEnrichJsonStatus(input2) {
22275
22665
  return next;
22276
22666
  };
22277
22667
  const rewritten = rewrite(input2.status);
22278
- if (failedRows === 0 || !isRecord7(rewritten)) {
22668
+ if (failedRows === 0 || !isRecord8(rewritten)) {
22279
22669
  return rewritten;
22280
22670
  }
22281
22671
  const partialStatus = selectedRows > 0 && failedRows < selectedRows ? "partial_success" : "failed";
22282
22672
  return {
22283
22673
  ...rewritten,
22284
22674
  ...rewritten.status === "completed" || rewritten.status === "failed" ? { status: partialStatus } : {},
22285
- ...isRecord7(rewritten.run) && (rewritten.run.status === "completed" || rewritten.run.status === "failed") ? { run: { ...rewritten.run, status: partialStatus } } : {}
22675
+ ...isRecord8(rewritten.run) && (rewritten.run.status === "completed" || rewritten.run.status === "failed") ? { run: { ...rewritten.run, status: partialStatus } } : {}
22286
22676
  };
22287
22677
  }
22288
22678
  function summarizeFailedJobError(value) {
@@ -22888,7 +23278,7 @@ function materializeCsvCellValue(value) {
22888
23278
  return value;
22889
23279
  }
22890
23280
  function compactArrayEnvelopeCompleteValue(value) {
22891
- if (!isRecord7(value) || value.kind !== "array") {
23281
+ if (!isRecord8(value) || value.kind !== "array") {
22892
23282
  return null;
22893
23283
  }
22894
23284
  if (!Array.isArray(value.preview)) {
@@ -22902,7 +23292,7 @@ function compactArrayEnvelopeCompleteValue(value) {
22902
23292
  }
22903
23293
  function disambiguateCompactAiInferencePayload(value) {
22904
23294
  const parsed = parseMaybeJsonObject(value);
22905
- if (!isRecord7(parsed) || !cellFailureError(parsed)) {
23295
+ if (!isRecord8(parsed) || !cellFailureError(parsed)) {
22906
23296
  return value;
22907
23297
  }
22908
23298
  return {
@@ -22911,14 +23301,14 @@ function disambiguateCompactAiInferencePayload(value) {
22911
23301
  };
22912
23302
  }
22913
23303
  function compactAiInferenceCellForCsv(value) {
22914
- if (!isRecord7(value)) {
23304
+ if (!isRecord8(value)) {
22915
23305
  return value;
22916
23306
  }
22917
23307
  const extractedJson = value.extracted_json;
22918
23308
  if (extractedJson !== null && extractedJson !== void 0) {
22919
23309
  return disambiguateCompactAiInferencePayload(extractedJson);
22920
23310
  }
22921
- const result = isRecord7(value.result) ? value.result : null;
23311
+ const result = isRecord8(value.result) ? value.result : null;
22922
23312
  const object = result?.object;
22923
23313
  if (object !== null && object !== void 0) {
22924
23314
  return disambiguateCompactAiInferencePayload(object);
@@ -22935,12 +23325,12 @@ function compactAiInferenceCellForCsv(value) {
22935
23325
  }
22936
23326
  function materializeEnrichAliasCellForCsv(row, alias, options) {
22937
23327
  const direct = row[alias];
22938
- if (isRecord7(direct)) {
23328
+ if (isRecord8(direct)) {
22939
23329
  const completeArray = compactArrayEnvelopeCompleteValue(direct);
22940
23330
  if (completeArray) {
22941
23331
  return materializeCsvCellValue(completeArray);
22942
23332
  }
22943
- if (options?.compactAiCell && direct.status === "completed" && (isRecord7(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
23333
+ if (options?.compactAiCell && direct.status === "completed" && (isRecord8(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
22944
23334
  return materializeCsvCellValue(compactAiInferenceCellForCsv(direct));
22945
23335
  }
22946
23336
  if (Object.prototype.hasOwnProperty.call(direct, "matched_result") || Object.prototype.hasOwnProperty.call(direct, "matchedResult") || Object.prototype.hasOwnProperty.call(direct, "result")) {
@@ -23081,11 +23471,11 @@ function normalizeEnrichRowsForCsvExport(rows, config, options) {
23081
23471
  }
23082
23472
  function legacyMetadataFromRow(row) {
23083
23473
  const direct = parseLegacyMetadataCell(row._metadata);
23084
- if (direct && isRecord7(direct.columns)) {
23474
+ if (direct && isRecord8(direct.columns)) {
23085
23475
  return direct;
23086
23476
  }
23087
23477
  const relocated = parseLegacyMetadataCell(row.metadata);
23088
- if (relocated && isRecord7(relocated.columns)) {
23478
+ if (relocated && isRecord8(relocated.columns)) {
23089
23479
  return relocated;
23090
23480
  }
23091
23481
  const flattenedColumns = parseLegacyMetadataCell(row["metadata.columns"]);
@@ -23102,7 +23492,7 @@ function legacyMetadataFromRow(row) {
23102
23492
  }
23103
23493
  function parseLegacyMetadataCell(value) {
23104
23494
  const parsed = parseMaybeJsonObject(value);
23105
- if (isRecord7(parsed)) {
23495
+ if (isRecord8(parsed)) {
23106
23496
  return parsed;
23107
23497
  }
23108
23498
  if (typeof value !== "string") {
@@ -23119,12 +23509,12 @@ function parseLegacyMetadataCell(value) {
23119
23509
  for (const candidate of candidates) {
23120
23510
  try {
23121
23511
  const decoded = JSON.parse(candidate);
23122
- if (isRecord7(decoded)) {
23512
+ if (isRecord8(decoded)) {
23123
23513
  return decoded;
23124
23514
  }
23125
23515
  if (typeof decoded === "string") {
23126
23516
  const nested = JSON.parse(decoded);
23127
- if (isRecord7(nested)) {
23517
+ if (isRecord8(nested)) {
23128
23518
  return nested;
23129
23519
  }
23130
23520
  }
@@ -23134,8 +23524,8 @@ function parseLegacyMetadataCell(value) {
23134
23524
  return null;
23135
23525
  }
23136
23526
  function mergeLegacyMetadataRecords(base, enriched) {
23137
- const baseColumns = isRecord7(base.columns) ? base.columns : null;
23138
- const enrichedColumns = isRecord7(enriched.columns) ? enriched.columns : null;
23527
+ const baseColumns = isRecord8(base.columns) ? base.columns : null;
23528
+ const enrichedColumns = isRecord8(enriched.columns) ? enriched.columns : null;
23139
23529
  const merged = {
23140
23530
  ...base,
23141
23531
  ...enriched
@@ -27023,6 +27413,43 @@ async function listTools(category, options = {}) {
27023
27413
  }
27024
27414
  return listToolCategories(emitJson, compact);
27025
27415
  }
27416
+ async function listProviders(options = {}) {
27417
+ const client2 = new DeeplineClient();
27418
+ const changed = options.changed === true;
27419
+ const emitJson = options.json === true || shouldEmitJson();
27420
+ const providers = await client2.listProviders({ changed });
27421
+ const render = {
27422
+ sections: [
27423
+ {
27424
+ title: changed ? `${providers.length} recently added providers:` : `${providers.length} providers:`,
27425
+ lines: providers.map((provider) => {
27426
+ const release2 = provider.releasedAt ? ` - v${provider.version ?? "unknown"} (${provider.releasedAt})` : "";
27427
+ return `${provider.provider} (${provider.displayName}) - ${provider.toolCount} tools${release2}`;
27428
+ })
27429
+ },
27430
+ {
27431
+ title: "next",
27432
+ lines: [
27433
+ "Run `deepline tools list <category>` to browse provider tools by category."
27434
+ ]
27435
+ }
27436
+ ]
27437
+ };
27438
+ printCommandEnvelope(
27439
+ {
27440
+ providers,
27441
+ count: providers.length,
27442
+ filters: { changed },
27443
+ commandTemplates: {
27444
+ list: "deepline tools providers",
27445
+ changed: "deepline tools providers --changed"
27446
+ },
27447
+ render
27448
+ },
27449
+ { json: emitJson }
27450
+ );
27451
+ return 0;
27452
+ }
27026
27453
  async function searchTools(queryInput, options = {}) {
27027
27454
  const query = queryInput?.trim() ?? "";
27028
27455
  const hasStructuredSearch = Boolean(
@@ -27215,6 +27642,7 @@ Concepts:
27215
27642
  through the plays namespace.
27216
27643
 
27217
27644
  Common commands:
27645
+ deepline tools providers --changed --json
27218
27646
  deepline tools search email --json
27219
27647
  deepline tools describe hunter_email_verifier --json
27220
27648
  deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
@@ -27224,6 +27652,28 @@ Output:
27224
27652
  Use execute to run a tool.
27225
27653
  `
27226
27654
  );
27655
+ tools.command("providers").description("List discoverable providers and their available tool counts.").addHelpText(
27656
+ "after",
27657
+ `
27658
+ Notes:
27659
+ This directory is served by Deepline's provider catalog; it does not require
27660
+ cloning a public plugins repository. Use --changed to show recently added
27661
+ providers with their catalog version and release date.
27662
+
27663
+ Examples:
27664
+ deepline tools providers
27665
+ deepline tools providers --changed
27666
+ deepline tools providers --changed --json
27667
+ `
27668
+ ).option(
27669
+ "--changed",
27670
+ "Only list recently added providers with release metadata"
27671
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
27672
+ process.exitCode = await listProviders({
27673
+ changed: Boolean(options.changed),
27674
+ json: Boolean(options.json)
27675
+ });
27676
+ });
27227
27677
  tools.command("list [category]").description("Browse tool categories, or list every tool in a category.").addHelpText(
27228
27678
  "after",
27229
27679
  `
@@ -27585,7 +28035,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
27585
28035
  }
27586
28036
  function extractionContractEntries(entries) {
27587
28037
  return entries.flatMap((entry) => {
27588
- if (!isRecord8(entry)) return [];
28038
+ if (!isRecord9(entry)) return [];
27589
28039
  const name = stringField2(entry, "name");
27590
28040
  const expression = stringField2(entry, "expression");
27591
28041
  return name && expression ? [{ name, expression }] : [];
@@ -27606,7 +28056,7 @@ function printMonitorTypeFilters(tool) {
27606
28056
  }
27607
28057
  console.log("Deploy filters (set in the monitor payload):");
27608
28058
  for (const name of names) {
27609
- const field = isRecord8(properties[name]) ? properties[name] : {};
28059
+ const field = isRecord9(properties[name]) ? properties[name] : {};
27610
28060
  const star = required.has(name) ? "*" : "";
27611
28061
  const enumVals = arrayField2(field, "enum").filter(
27612
28062
  (v) => typeof v === "string"
@@ -27617,13 +28067,13 @@ function printMonitorTypeFilters(tool) {
27617
28067
  }
27618
28068
  }
27619
28069
  function printMonitorTypeStreams(tool) {
27620
- const streams = arrayField2(tool, "streams", "output_streams").filter(isRecord8);
28070
+ const streams = arrayField2(tool, "streams", "output_streams").filter(isRecord9);
27621
28071
  if (!streams.length) return;
27622
28072
  console.log("");
27623
28073
  console.log("Filter columns (a play's sqlListeners.where, per stream):");
27624
28074
  for (const stream of streams) {
27625
28075
  const name = stringField2(stream, "stream");
27626
- const cols = arrayField2(stream, "columns").filter(isRecord8).map((col) => stringField2(col, "name")).filter(Boolean);
28076
+ const cols = arrayField2(stream, "columns").filter(isRecord9).map((col) => stringField2(col, "name")).filter(Boolean);
27627
28077
  console.log(`- ${name}: ${cols.join(", ")}`);
27628
28078
  }
27629
28079
  }
@@ -27641,7 +28091,7 @@ function printMonitorTypePricing(tool) {
27641
28091
  }
27642
28092
  console.log("Pricing (Deepline credits per accepted event):");
27643
28093
  for (const key of keys) {
27644
- const entry = isRecord8(byType[key]) ? byType[key] : {};
28094
+ const entry = isRecord9(byType[key]) ? byType[key] : {};
27645
28095
  const credits = numberField2(entry, "deepline_credits", "deeplineCredits");
27646
28096
  const display = stringField2(entry, "display");
27647
28097
  const shown = display || (credits !== null ? `${formatDecimal(credits)} credits/event` : "see --json");
@@ -27686,8 +28136,8 @@ function printCompactToolContract(tool, requestedToolId) {
27686
28136
  return;
27687
28137
  }
27688
28138
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
27689
- const cost = isRecord8(contract.cost) ? contract.cost : {};
27690
- const getters = isRecord8(contract.getters) ? contract.getters : {};
28139
+ const cost = isRecord9(contract.cost) ? contract.cost : {};
28140
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
27691
28141
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
27692
28142
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
27693
28143
  const inputFields = Array.isArray(contract.inputFields) ? contract.inputFields : [];
@@ -27704,7 +28154,7 @@ function printCompactToolContract(tool, requestedToolId) {
27704
28154
  console.log("");
27705
28155
  console.log("Inputs:");
27706
28156
  for (const field of inputFields) {
27707
- if (!isRecord8(field)) continue;
28157
+ if (!isRecord9(field)) continue;
27708
28158
  const name = stringField2(field, "name");
27709
28159
  if (!name) continue;
27710
28160
  const required = field.required ? "*" : "";
@@ -27717,7 +28167,7 @@ function printCompactToolContract(tool, requestedToolId) {
27717
28167
  }
27718
28168
  console.log("");
27719
28169
  printToolExamplesOnly(tool, requestedToolId, { includeSamples: false });
27720
- const starterScript = isRecord8(contract.starterScript) ? contract.starterScript : {};
28170
+ const starterScript = isRecord9(contract.starterScript) ? contract.starterScript : {};
27721
28171
  const starterPath = stringField2(starterScript, "path");
27722
28172
  if (starterPath) {
27723
28173
  console.log("");
@@ -27731,14 +28181,14 @@ function printCompactToolContract(tool, requestedToolId) {
27731
28181
  console.log("Getters:");
27732
28182
  if (listGetters.length) console.log("Lists:");
27733
28183
  for (const entry of listGetters) {
27734
- if (isRecord8(entry))
28184
+ if (isRecord9(entry))
27735
28185
  console.log(
27736
28186
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
27737
28187
  );
27738
28188
  }
27739
28189
  if (valueGetters.length) console.log("Values:");
27740
28190
  for (const entry of valueGetters) {
27741
- if (isRecord8(entry))
28191
+ if (isRecord9(entry))
27742
28192
  console.log(
27743
28193
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
27744
28194
  );
@@ -27755,7 +28205,7 @@ function printToolPricingOnly(tool, requestedToolId, options = {}) {
27755
28205
  return;
27756
28206
  }
27757
28207
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
27758
- const cost = isRecord8(contract.cost) ? contract.cost : {};
28208
+ const cost = isRecord9(contract.cost) ? contract.cost : {};
27759
28209
  const pricingModel = stringField2(cost, "pricingModel") || "unknown";
27760
28210
  const billingMode = stringField2(cost, "billingMode") || "unknown";
27761
28211
  const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit";
@@ -27780,7 +28230,7 @@ function printToolSchemaOnly(tool, requestedToolId) {
27780
28230
  }
27781
28231
  console.log("Inputs:");
27782
28232
  for (const field of inputFields) {
27783
- if (!isRecord8(field)) continue;
28233
+ if (!isRecord9(field)) continue;
27784
28234
  const name = stringField2(field, "name");
27785
28235
  if (!name) continue;
27786
28236
  const required = field.required ? "*" : "";
@@ -27814,10 +28264,10 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
27814
28264
  ` input: ${JSON.stringify(sampleInput || {}, null, 2).replace(/\n/g, "\n ")},`
27815
28265
  );
27816
28266
  console.log("});");
27817
- const getters = isRecord8(contract.getters) ? contract.getters : {};
28267
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
27818
28268
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
27819
28269
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
27820
- const firstGetter = [...valueGetters, ...listGetters].find(isRecord8);
28270
+ const firstGetter = [...valueGetters, ...listGetters].find(isRecord9);
27821
28271
  if (firstGetter) {
27822
28272
  const name = stringField2(firstGetter, "name") || "value";
27823
28273
  const expression = stringField2(firstGetter, "expression");
@@ -27853,7 +28303,7 @@ function printPlayLikeToolUsage(tool, requestedToolId) {
27853
28303
  }
27854
28304
  function printToolGettersOnly(tool, requestedToolId) {
27855
28305
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
27856
- const getters = isRecord8(contract.getters) ? contract.getters : {};
28306
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
27857
28307
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
27858
28308
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
27859
28309
  console.log(`Getters: ${contract.toolId}`);
@@ -27866,7 +28316,7 @@ function printToolGettersOnly(tool, requestedToolId) {
27866
28316
  if (listGetters.length) {
27867
28317
  console.log("Lists:");
27868
28318
  for (const entry of listGetters) {
27869
- if (isRecord8(entry))
28319
+ if (isRecord9(entry))
27870
28320
  console.log(
27871
28321
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
27872
28322
  );
@@ -27875,7 +28325,7 @@ function printToolGettersOnly(tool, requestedToolId) {
27875
28325
  if (valueGetters.length) {
27876
28326
  console.log("Values:");
27877
28327
  for (const entry of valueGetters) {
27878
- if (isRecord8(entry))
28328
+ if (isRecord9(entry))
27879
28329
  console.log(
27880
28330
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
27881
28331
  );
@@ -27901,7 +28351,7 @@ function sampleValueForField(field) {
27901
28351
  function samplePayloadForInputFields(fields) {
27902
28352
  return Object.fromEntries(
27903
28353
  fields.slice(0, 4).flatMap((field) => {
27904
- if (!isRecord8(field)) return [];
28354
+ if (!isRecord9(field)) return [];
27905
28355
  const name = stringField2(field, "name");
27906
28356
  if (!name) return [];
27907
28357
  return [[name, sampleValueForField(field)]];
@@ -28019,12 +28469,12 @@ function formatListedToolCost(tool) {
28019
28469
  }
28020
28470
  function toolInputFieldsForDisplay(inputSchema) {
28021
28471
  if (Array.isArray(inputSchema.fields))
28022
- return inputSchema.fields.filter(isRecord8);
28023
- const jsonSchema = isRecord8(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
28024
- const properties = isRecord8(jsonSchema.properties) ? jsonSchema.properties : {};
28472
+ return inputSchema.fields.filter(isRecord9);
28473
+ const jsonSchema = isRecord9(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
28474
+ const properties = isRecord9(jsonSchema.properties) ? jsonSchema.properties : {};
28025
28475
  const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
28026
28476
  return Object.entries(properties).map(([name, value]) => {
28027
- const property = isRecord8(value) ? value : {};
28477
+ const property = isRecord9(value) ? value : {};
28028
28478
  return {
28029
28479
  name,
28030
28480
  type: typeof property.type === "string" ? property.type : "unknown",
@@ -28053,14 +28503,14 @@ function printJsonPreview(label, payload) {
28053
28503
  }
28054
28504
  function samplePayload(samples, key) {
28055
28505
  const entry = samples[key];
28056
- if (!isRecord8(entry)) return void 0;
28506
+ if (!isRecord9(entry)) return void 0;
28057
28507
  return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
28058
28508
  }
28059
28509
  function commandEnvelopeFromRawResponse(rawResponse) {
28060
- return isRecord8(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
28510
+ return isRecord9(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
28061
28511
  }
28062
28512
  function apifySyncRecoveryNext(rawResponse) {
28063
- if (!isRecord8(rawResponse) || rawResponse.status !== "running") return null;
28513
+ if (!isRecord9(rawResponse) || rawResponse.status !== "running") return null;
28064
28514
  const toolResponse = recordField2(rawResponse, "toolResponse");
28065
28515
  const raw = recordField2(toolResponse, "raw");
28066
28516
  if (raw.state !== "awaiting_apify") return null;
@@ -28083,7 +28533,7 @@ function apifySyncRecoveryNext(rawResponse) {
28083
28533
  }
28084
28534
  function listExtractorPathsFromUsageGuidance(tool) {
28085
28535
  const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
28086
- const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord8(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
28536
+ const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord9(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
28087
28537
  return extractedLists.flatMap((entry) => {
28088
28538
  const paths = entry.details?.candidatePaths ?? entry.details?.rawToolOutputPaths;
28089
28539
  if (!Array.isArray(paths)) return [];
@@ -28099,7 +28549,7 @@ function formatDecimal(value) {
28099
28549
  function formatUsd(value) {
28100
28550
  return `$${formatDecimal(value)}`;
28101
28551
  }
28102
- function isRecord8(value) {
28552
+ function isRecord9(value) {
28103
28553
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
28104
28554
  }
28105
28555
  function stringField2(source, ...keys) {
@@ -28126,7 +28576,7 @@ function arrayField2(source, ...keys) {
28126
28576
  function recordField2(source, ...keys) {
28127
28577
  for (const key of keys) {
28128
28578
  const value = source[key];
28129
- if (isRecord8(value)) return value;
28579
+ if (isRecord9(value)) return value;
28130
28580
  }
28131
28581
  return {};
28132
28582
  }
@@ -28192,7 +28642,7 @@ function parseJsonObjectArgument(raw, flagName) {
28192
28642
  }
28193
28643
  throw invalidJsonError(flagName, message);
28194
28644
  }
28195
- if (!isRecord8(parsed)) {
28645
+ if (!isRecord9(parsed)) {
28196
28646
  throw invalidJsonError(flagName, "expected an object.");
28197
28647
  }
28198
28648
  return parsed;
@@ -28339,7 +28789,7 @@ function buildToolExecuteBaseEnvelope(input2) {
28339
28789
  kind: summaryEntries.length > 0 ? "object" : "raw",
28340
28790
  summary: input2.summary
28341
28791
  };
28342
- const envelopeHasCanonicalOutput = isRecord8(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
28792
+ const envelopeHasCanonicalOutput = isRecord9(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
28343
28793
  const envelopeHasDeclaredOutput = Object.prototype.hasOwnProperty.call(
28344
28794
  envelope,
28345
28795
  "output"
@@ -28569,7 +29019,7 @@ async function executeTool(args) {
28569
29019
  {
28570
29020
  ...baseEnvelope,
28571
29021
  local: {
28572
- ...isRecord8(baseEnvelope.local) ? baseEnvelope.local : {},
29022
+ ...isRecord9(baseEnvelope.local) ? baseEnvelope.local : {},
28573
29023
  payload_file: jsonPath
28574
29024
  }
28575
29025
  },
@@ -32058,7 +32508,9 @@ function shouldDeferSkillsSyncForCommand() {
32058
32508
  const args = process.argv.slice(2);
32059
32509
  const command = args[0];
32060
32510
  const subcommand = args[1];
32061
- if (command === "tools" && ["list", "search", "grep", "describe", "get"].includes(subcommand ?? "")) {
32511
+ if (command === "tools" && ["list", "providers", "search", "grep", "describe", "get"].includes(
32512
+ subcommand ?? ""
32513
+ )) {
32062
32514
  return true;
32063
32515
  }
32064
32516
  return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
@@ -32284,6 +32736,7 @@ Common commands:
32284
32736
  deepline plays describe prebuilt/person-linkedin-to-email --json
32285
32737
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
32286
32738
  deepline secrets check HUBSPOT_TOKEN
32739
+ deepline tools providers --changed --json
32287
32740
  deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
32288
32741
  deepline update
32289
32742