deepline 0.3.97 → 0.3.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/client.ts +152 -5
- package/dist/bundling-sources/sdk/src/index.ts +17 -4
- package/dist/bundling-sources/sdk/src/monitor-fleets.ts +1 -0
- package/dist/bundling-sources/sdk/src/monitor-input-contract.ts +1 -0
- package/dist/bundling-sources/sdk/src/monitors.ts +8 -25
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/integration-contracts/index.ts +1 -0
- package/dist/bundling-sources/shared_libs/integration-contracts/monitor-fleet-contract.ts +218 -16
- package/dist/bundling-sources/shared_libs/integration-contracts/monitor-input-contract.ts +455 -0
- package/dist/bundling-sources/shared_libs/monitors/fleets/plan.ts +6 -1
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +2 -1
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +12 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +19 -3
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +5 -1
- package/dist/cli/index.js +1030 -295
- package/dist/cli/index.mjs +1038 -303
- package/dist/index.d.mts +48 -25
- package/dist/index.d.ts +48 -25
- package/dist/index.js +606 -42
- package/dist/index.mjs +602 -42
- package/dist/install-integrity.json +6 -0
- package/dist/monitor-fleet-contract.d.mts +44 -8
- package/dist/monitor-fleet-contract.d.ts +44 -8
- package/dist/monitor-fleet-contract.js +354 -27
- package/dist/monitor-fleet-contract.mjs +343 -27
- package/dist/monitor-input-contract.d.mts +33 -0
- package/dist/monitor-input-contract.d.ts +33 -0
- package/dist/monitor-input-contract.js +392 -0
- package/dist/monitor-input-contract.mjs +353 -0
- package/dist/plays/bundle-play-file.mjs +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +7 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -1271,7 +1271,7 @@ var SDK_RELEASE = {
|
|
|
1271
1271
|
// getters keep their established compatibility behavior.
|
|
1272
1272
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1273
1273
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
1274
|
-
version: "0.3.
|
|
1274
|
+
version: "0.3.99",
|
|
1275
1275
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
1276
1276
|
packageCapabilities: {
|
|
1277
1277
|
updatePreferences: 1
|
|
@@ -3343,9 +3343,9 @@ function nonEmptyString(value) {
|
|
|
3343
3343
|
}
|
|
3344
3344
|
function normalizeDatasetBornFrom(value) {
|
|
3345
3345
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
3346
|
-
const
|
|
3347
|
-
const table = nonEmptyString(
|
|
3348
|
-
const rowCountIn = finiteNonNegativeInteger2(
|
|
3346
|
+
const record3 = value;
|
|
3347
|
+
const table = nonEmptyString(record3.table);
|
|
3348
|
+
const rowCountIn = finiteNonNegativeInteger2(record3.rowCountIn);
|
|
3349
3349
|
if (!table || rowCountIn === null) return null;
|
|
3350
3350
|
return { table, rowCountIn };
|
|
3351
3351
|
}
|
|
@@ -4534,21 +4534,21 @@ function normalizePlayRuntimeNamespace(value) {
|
|
|
4534
4534
|
}
|
|
4535
4535
|
function normalizePlayRuntimeSelection(value) {
|
|
4536
4536
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
4537
|
-
const
|
|
4538
|
-
if (Object.keys(
|
|
4537
|
+
const record3 = value;
|
|
4538
|
+
if (Object.keys(record3).some(
|
|
4539
4539
|
(key) => key !== "environment" && key !== "namespace" && key !== "backend"
|
|
4540
|
-
) ||
|
|
4540
|
+
) || record3.environment !== "preview") {
|
|
4541
4541
|
return null;
|
|
4542
4542
|
}
|
|
4543
|
-
const namespace = normalizePlayRuntimeNamespace(
|
|
4543
|
+
const namespace = normalizePlayRuntimeNamespace(record3.namespace);
|
|
4544
4544
|
if (!namespace) return null;
|
|
4545
|
-
if (
|
|
4545
|
+
if (record3.backend === void 0) {
|
|
4546
4546
|
return { environment: "preview", namespace };
|
|
4547
4547
|
}
|
|
4548
|
-
if (
|
|
4548
|
+
if (record3.backend !== PLAY_RUNTIME_BACKENDS.daytona && record3.backend !== PLAY_RUNTIME_BACKENDS.modal) {
|
|
4549
4549
|
return null;
|
|
4550
4550
|
}
|
|
4551
|
-
return { environment: "preview", namespace, backend:
|
|
4551
|
+
return { environment: "preview", namespace, backend: record3.backend };
|
|
4552
4552
|
}
|
|
4553
4553
|
function normalizePlayRuntimeEnvironment(value) {
|
|
4554
4554
|
return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
|
|
@@ -5193,10 +5193,18 @@ var DeeplineClient = class {
|
|
|
5193
5193
|
repair: (options2) => this.repairMonitors(options2),
|
|
5194
5194
|
health: (options2) => this.readMonitorsHealth(options2),
|
|
5195
5195
|
batch: {
|
|
5196
|
+
deploy: (definitions, options2) => this.deployMonitorBatch(definitions, options2),
|
|
5196
5197
|
submit: (options2) => this.submitMonitorBatch(options2),
|
|
5197
5198
|
get: (operationId, options2) => this.getMonitorBatch(operationId, options2)
|
|
5198
5199
|
},
|
|
5200
|
+
jobs: {
|
|
5201
|
+
get: (jobId) => this.getMonitorJob(jobId),
|
|
5202
|
+
logs: (jobId, options2) => this.getMonitorJobLogs(jobId, options2),
|
|
5203
|
+
cancel: (jobId) => this.cancelMonitorJob(jobId),
|
|
5204
|
+
wait: (jobId, options2) => this.waitForMonitorJob(jobId, options2)
|
|
5205
|
+
},
|
|
5199
5206
|
fleets: {
|
|
5207
|
+
deploy: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
5200
5208
|
sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
5201
5209
|
get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
|
|
5202
5210
|
list: () => this.listMonitorFleets(),
|
|
@@ -7540,7 +7548,8 @@ var DeeplineClient = class {
|
|
|
7540
7548
|
enabled: true,
|
|
7541
7549
|
threshold_credits: options.thresholdCredits,
|
|
7542
7550
|
refill_to_credits: options.refillToCredits,
|
|
7543
|
-
...options.purchaseLimitCents !== void 0 ? { purchase_limit_cents: options.purchaseLimitCents } : {}
|
|
7551
|
+
...options.purchaseLimitCents !== void 0 ? { purchase_limit_cents: options.purchaseLimitCents } : {},
|
|
7552
|
+
...options.purchaseLimitCredits !== void 0 ? { purchase_limit_credits: options.purchaseLimitCredits } : {}
|
|
7544
7553
|
} : { enabled: false },
|
|
7545
7554
|
{ "Idempotency-Key": idempotencyKey }
|
|
7546
7555
|
);
|
|
@@ -7948,6 +7957,68 @@ var DeeplineClient = class {
|
|
|
7948
7957
|
);
|
|
7949
7958
|
}
|
|
7950
7959
|
// ——————————————————————————————————————————————————————————
|
|
7960
|
+
// Monitor Jobs, Batches, and Fleets
|
|
7961
|
+
// ——————————————————————————————————————————————————————————
|
|
7962
|
+
monitorJobIdempotencyKey(operation) {
|
|
7963
|
+
const uuid = globalThis.crypto?.randomUUID?.();
|
|
7964
|
+
return `monitor-job-${operation}-${uuid ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`}`;
|
|
7965
|
+
}
|
|
7966
|
+
monitorJobHeaders(operation, idempotencyKey) {
|
|
7967
|
+
return {
|
|
7968
|
+
"Idempotency-Key": idempotencyKey?.trim() || this.monitorJobIdempotencyKey(operation)
|
|
7969
|
+
};
|
|
7970
|
+
}
|
|
7971
|
+
async deployMonitorBatch(definitions, options) {
|
|
7972
|
+
return this.http.request(
|
|
7973
|
+
"/api/v2/monitors/batch/deploy",
|
|
7974
|
+
{
|
|
7975
|
+
method: "POST",
|
|
7976
|
+
body: { version: 1, kind: "batch", monitors: definitions },
|
|
7977
|
+
headers: this.monitorJobHeaders(
|
|
7978
|
+
"batch-deploy",
|
|
7979
|
+
options?.idempotencyKey
|
|
7980
|
+
),
|
|
7981
|
+
maxRetries: 0,
|
|
7982
|
+
exactUrlOnly: true
|
|
7983
|
+
}
|
|
7984
|
+
);
|
|
7985
|
+
}
|
|
7986
|
+
async getMonitorJob(jobId) {
|
|
7987
|
+
return this.http.request(
|
|
7988
|
+
`/api/v2/monitors/jobs/${encodeURIComponent(jobId)}`,
|
|
7989
|
+
{ method: "GET" }
|
|
7990
|
+
);
|
|
7991
|
+
}
|
|
7992
|
+
async getMonitorJobLogs(jobId, options) {
|
|
7993
|
+
const query = options?.limit === void 0 ? "" : `?limit=${encodeURIComponent(String(options.limit))}`;
|
|
7994
|
+
return this.http.request(
|
|
7995
|
+
`/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/logs${query}`,
|
|
7996
|
+
{ method: "GET" }
|
|
7997
|
+
);
|
|
7998
|
+
}
|
|
7999
|
+
async cancelMonitorJob(jobId) {
|
|
8000
|
+
return this.http.request(
|
|
8001
|
+
`/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/cancel`,
|
|
8002
|
+
{ method: "POST", body: {}, maxRetries: 0, exactUrlOnly: true }
|
|
8003
|
+
);
|
|
8004
|
+
}
|
|
8005
|
+
async waitForMonitorJob(jobId, options) {
|
|
8006
|
+
const timeoutMs = Math.max(1, options?.timeoutMs ?? 10 * 6e4);
|
|
8007
|
+
const pollIntervalMs = Math.max(1, options?.pollIntervalMs ?? 2e3);
|
|
8008
|
+
const terminal = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled"]);
|
|
8009
|
+
const startedAt = Date.now();
|
|
8010
|
+
let latest = await this.getMonitorJob(jobId);
|
|
8011
|
+
while (true) {
|
|
8012
|
+
options?.onProgress?.(latest);
|
|
8013
|
+
const job = latest.job;
|
|
8014
|
+
const state = typeof job?.state === "string" ? job.state : void 0;
|
|
8015
|
+
if (state && terminal.has(state)) return latest;
|
|
8016
|
+
if (Date.now() - startedAt >= timeoutMs) return latest;
|
|
8017
|
+
await sleep2(pollIntervalMs);
|
|
8018
|
+
latest = await this.getMonitorJob(jobId);
|
|
8019
|
+
}
|
|
8020
|
+
}
|
|
8021
|
+
// ——————————————————————————————————————————————————————————
|
|
7951
8022
|
// Monitor Fleets
|
|
7952
8023
|
// ——————————————————————————————————————————————————————————
|
|
7953
8024
|
monitorFleetIdempotencyKey(operation) {
|
|
@@ -8731,30 +8802,30 @@ function flattenObjectColumns(row, options = {}) {
|
|
|
8731
8802
|
continue;
|
|
8732
8803
|
}
|
|
8733
8804
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
8734
|
-
const
|
|
8805
|
+
const record3 = value;
|
|
8735
8806
|
if (options.objectColumns === "json") {
|
|
8736
|
-
flattened[key] = csvSafeJsonString(
|
|
8807
|
+
flattened[key] = csvSafeJsonString(record3);
|
|
8737
8808
|
continue;
|
|
8738
8809
|
}
|
|
8739
|
-
const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(
|
|
8810
|
+
const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record3, "matched_result") || Object.prototype.hasOwnProperty.call(record3, "matchedResult");
|
|
8740
8811
|
if (hasMatchedEnvelope) {
|
|
8741
|
-
flattened[key] = csvSafeJsonString(
|
|
8812
|
+
flattened[key] = csvSafeJsonString(record3);
|
|
8742
8813
|
continue;
|
|
8743
8814
|
}
|
|
8744
8815
|
if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
|
|
8745
8816
|
flattened[key] = rawValue;
|
|
8746
8817
|
continue;
|
|
8747
8818
|
} else {
|
|
8748
|
-
const failureMessage = failureMessageFromRecord(
|
|
8819
|
+
const failureMessage = failureMessageFromRecord(record3);
|
|
8749
8820
|
if (failureMessage) {
|
|
8750
8821
|
flattened[key] = failureMessage;
|
|
8751
8822
|
continue;
|
|
8752
|
-
} else if (Object.prototype.hasOwnProperty.call(
|
|
8753
|
-
flattened[key] = csvSafeJsonString(
|
|
8823
|
+
} else if (Object.prototype.hasOwnProperty.call(record3, "result")) {
|
|
8824
|
+
flattened[key] = csvSafeJsonString(record3);
|
|
8754
8825
|
continue;
|
|
8755
8826
|
}
|
|
8756
8827
|
}
|
|
8757
|
-
for (const [nestedKey, nestedValue] of Object.entries(
|
|
8828
|
+
for (const [nestedKey, nestedValue] of Object.entries(record3)) {
|
|
8758
8829
|
flattened[`${key}.${nestedKey}`] = nestedValue && typeof nestedValue === "object" ? csvSafeJsonString(nestedValue) : nestedValue;
|
|
8759
8830
|
}
|
|
8760
8831
|
continue;
|
|
@@ -9760,7 +9831,7 @@ Examples:
|
|
|
9760
9831
|
}
|
|
9761
9832
|
|
|
9762
9833
|
// src/cli/commands/billing.ts
|
|
9763
|
-
import { Command } from "commander";
|
|
9834
|
+
import { Command, Option } from "commander";
|
|
9764
9835
|
import { randomUUID } from "crypto";
|
|
9765
9836
|
import { appendFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
9766
9837
|
import { dirname as dirname6, resolve as resolve3 } from "path";
|
|
@@ -10703,8 +10774,8 @@ async function handleAutoRechargeStatus(options) {
|
|
|
10703
10774
|
`State: ${state}`,
|
|
10704
10775
|
...payload.threshold_credits !== null ? [`Threshold: ${payload.threshold_credits} credits`] : [],
|
|
10705
10776
|
...payload.refill_to_credits !== null ? [`Refill balance to: ${payload.refill_to_credits} credits`] : [],
|
|
10706
|
-
...payload.
|
|
10707
|
-
|
|
10777
|
+
...payload.purchase_limit_credits != null ? [
|
|
10778
|
+
`Automatic credit purchase cap: ${payload.purchase_limit_credits} credits per rolling 30 days`
|
|
10708
10779
|
] : []
|
|
10709
10780
|
];
|
|
10710
10781
|
printCommandEnvelope(
|
|
@@ -10720,6 +10791,18 @@ async function handleAutoRechargeSet(options) {
|
|
|
10720
10791
|
const thresholdCredits = parseTopUpCredits(options.thresholdCredits);
|
|
10721
10792
|
const refillToCredits = parseTopUpCredits(options.refillToCredits);
|
|
10722
10793
|
const rollingLimitCents = options.purchaseLimitCents === void 0 ? void 0 : options.purchaseLimitCents === "none" ? null : Number(options.purchaseLimitCents);
|
|
10794
|
+
const rollingLimitCredits = options.purchaseLimitCredits === void 0 ? void 0 : options.purchaseLimitCredits === "none" ? null : Number(options.purchaseLimitCredits);
|
|
10795
|
+
if (rollingLimitCredits != null && (!Number.isSafeInteger(rollingLimitCredits) || rollingLimitCredits < 0)) {
|
|
10796
|
+
reportBillingFailure(
|
|
10797
|
+
{
|
|
10798
|
+
exitCode: 2,
|
|
10799
|
+
code: "INVALID_AUTO_RECHARGE_CONFIGURATION",
|
|
10800
|
+
message: "--purchase-limit-credits must be a nonnegative whole number of credits or none."
|
|
10801
|
+
},
|
|
10802
|
+
options
|
|
10803
|
+
);
|
|
10804
|
+
return;
|
|
10805
|
+
}
|
|
10723
10806
|
if (rollingLimitCents !== void 0 && rollingLimitCents !== null && (!Number.isSafeInteger(rollingLimitCents) || rollingLimitCents <= 0)) {
|
|
10724
10807
|
reportBillingFailure(
|
|
10725
10808
|
{
|
|
@@ -10756,7 +10839,8 @@ async function handleAutoRechargeSet(options) {
|
|
|
10756
10839
|
enabled: true,
|
|
10757
10840
|
threshold_credits: thresholdCredits,
|
|
10758
10841
|
refill_to_credits: refillToCredits,
|
|
10759
|
-
...rollingLimitCents !== void 0 ? { purchase_limit_cents: rollingLimitCents } : {}
|
|
10842
|
+
...rollingLimitCents !== void 0 ? { purchase_limit_cents: rollingLimitCents } : {},
|
|
10843
|
+
...rollingLimitCredits !== void 0 ? { purchase_limit_credits: rollingLimitCredits } : {}
|
|
10760
10844
|
}
|
|
10761
10845
|
}
|
|
10762
10846
|
},
|
|
@@ -10769,6 +10853,7 @@ async function handleAutoRechargeSet(options) {
|
|
|
10769
10853
|
thresholdCredits,
|
|
10770
10854
|
refillToCredits,
|
|
10771
10855
|
...rollingLimitCents !== void 0 ? { purchaseLimitCents: rollingLimitCents } : {},
|
|
10856
|
+
...rollingLimitCredits !== void 0 ? { purchaseLimitCredits: rollingLimitCredits } : {},
|
|
10772
10857
|
idempotencyKey
|
|
10773
10858
|
});
|
|
10774
10859
|
printCommandEnvelope(
|
|
@@ -11156,9 +11241,14 @@ Examples:
|
|
|
11156
11241
|
).requiredOption(
|
|
11157
11242
|
"--refill-to-credits <credits>",
|
|
11158
11243
|
"Recharge the balance to this amount"
|
|
11244
|
+
).addOption(
|
|
11245
|
+
new Option(
|
|
11246
|
+
"--purchase-limit-cents <cents>",
|
|
11247
|
+
"Deprecated: converted to credits"
|
|
11248
|
+
).hideHelp()
|
|
11159
11249
|
).option(
|
|
11160
|
-
"--purchase-limit-
|
|
11161
|
-
"Limit automatic purchases over rolling 30 days (
|
|
11250
|
+
"--purchase-limit-credits <credits>",
|
|
11251
|
+
"Limit automatic credit purchases over rolling 30 days (or none to remove)"
|
|
11162
11252
|
).option("--idempotency-key <key>", "Stable retry key").option("--dry-run", "Print the planned update without applying it").option("--json", "Emit JSON output").action(handleAutoRechargeSet)
|
|
11163
11253
|
).addCommand(
|
|
11164
11254
|
new Command("off").description(
|
|
@@ -11429,9 +11519,9 @@ function canonicalDatasetJsonValue(value, ancestors) {
|
|
|
11429
11519
|
}
|
|
11430
11520
|
if (ancestors.has(value)) return value;
|
|
11431
11521
|
ancestors.add(value);
|
|
11432
|
-
const
|
|
11522
|
+
const record3 = value;
|
|
11433
11523
|
const normalized = Object.fromEntries(
|
|
11434
|
-
Object.keys(
|
|
11524
|
+
Object.keys(record3).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record3[key], ancestors)])
|
|
11435
11525
|
);
|
|
11436
11526
|
ancestors.delete(value);
|
|
11437
11527
|
return normalized;
|
|
@@ -12628,16 +12718,16 @@ function collectErrorText(value) {
|
|
|
12628
12718
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
12629
12719
|
return errorMessage(value);
|
|
12630
12720
|
}
|
|
12631
|
-
const
|
|
12721
|
+
const record3 = value;
|
|
12632
12722
|
return [
|
|
12633
12723
|
errorMessage(value),
|
|
12634
|
-
typeof
|
|
12635
|
-
typeof
|
|
12636
|
-
typeof
|
|
12637
|
-
typeof
|
|
12638
|
-
typeof
|
|
12639
|
-
|
|
12640
|
-
|
|
12724
|
+
typeof record3.error === "string" ? record3.error : "",
|
|
12725
|
+
typeof record3.message === "string" ? record3.message : "",
|
|
12726
|
+
typeof record3.detail === "string" ? record3.detail : "",
|
|
12727
|
+
typeof record3.hint === "string" ? record3.hint : "",
|
|
12728
|
+
typeof record3.code === "string" ? record3.code : "",
|
|
12729
|
+
record3.response ? collectErrorText(record3.response) : "",
|
|
12730
|
+
record3.details ? collectErrorText(record3.details) : ""
|
|
12641
12731
|
].filter(Boolean).join("\n");
|
|
12642
12732
|
}
|
|
12643
12733
|
function formatDbQueryError(sql, error) {
|
|
@@ -12988,7 +13078,7 @@ import {
|
|
|
12988
13078
|
} from "fs/promises";
|
|
12989
13079
|
import { homedir as homedir6, tmpdir as tmpdir4 } from "os";
|
|
12990
13080
|
import { basename as basename4, dirname as dirname11, extname as extname3, join as join11, resolve as resolve12 } from "path";
|
|
12991
|
-
import { Option } from "commander";
|
|
13081
|
+
import { Option as Option2 } from "commander";
|
|
12992
13082
|
|
|
12993
13083
|
// src/cli/commands/play.ts
|
|
12994
13084
|
import { createHash as createHash4, randomUUID as randomUUID3 } from "crypto";
|
|
@@ -13689,8 +13779,8 @@ function getterNamesFromTool(tool, kind) {
|
|
|
13689
13779
|
return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
|
|
13690
13780
|
}
|
|
13691
13781
|
function targetGettersFromTool(tool) {
|
|
13692
|
-
const
|
|
13693
|
-
const raw =
|
|
13782
|
+
const record3 = isRecord9(tool) ? tool : {};
|
|
13783
|
+
const raw = record3.targetGetters ?? record3.target_getters;
|
|
13694
13784
|
if (!isRecord9(raw)) return {};
|
|
13695
13785
|
const entries = [];
|
|
13696
13786
|
for (const [target, value] of Object.entries(raw)) {
|
|
@@ -17805,13 +17895,13 @@ function validateFixtureBehavior(value) {
|
|
|
17805
17895
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
17806
17896
|
return { ok: false, error: "fixtureBehavior must be a JSON object." };
|
|
17807
17897
|
}
|
|
17808
|
-
const
|
|
17809
|
-
const supportedKeys =
|
|
17898
|
+
const record3 = value;
|
|
17899
|
+
const supportedKeys = record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
|
|
17810
17900
|
"version",
|
|
17811
17901
|
"responseSamples",
|
|
17812
|
-
...
|
|
17902
|
+
...record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
|
|
17813
17903
|
]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
|
|
17814
|
-
const unknownKeys = Object.keys(
|
|
17904
|
+
const unknownKeys = Object.keys(record3).filter(
|
|
17815
17905
|
(key) => !supportedKeys.has(key)
|
|
17816
17906
|
);
|
|
17817
17907
|
if (unknownKeys.length > 0) {
|
|
@@ -17820,22 +17910,22 @@ function validateFixtureBehavior(value) {
|
|
|
17820
17910
|
error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
|
|
17821
17911
|
};
|
|
17822
17912
|
}
|
|
17823
|
-
if (
|
|
17913
|
+
if (record3.version !== FIXTURE_BEHAVIOR_VERSION && record3.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record3.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17824
17914
|
return {
|
|
17825
17915
|
ok: false,
|
|
17826
17916
|
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
|
|
17827
17917
|
};
|
|
17828
17918
|
}
|
|
17829
|
-
if (
|
|
17830
|
-
if (!Array.isArray(
|
|
17919
|
+
if (record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17920
|
+
if (!Array.isArray(record3.responseSamples) || record3.responseSamples.length === 0 || record3.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
17831
17921
|
return {
|
|
17832
17922
|
ok: false,
|
|
17833
17923
|
error: `fixtureBehavior.responseSamples must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
|
|
17834
17924
|
};
|
|
17835
17925
|
}
|
|
17836
17926
|
const samples2 = [];
|
|
17837
|
-
for (let index = 0; index <
|
|
17838
|
-
const value2 =
|
|
17927
|
+
for (let index = 0; index < record3.responseSamples.length; index += 1) {
|
|
17928
|
+
const value2 = record3.responseSamples[index];
|
|
17839
17929
|
if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
|
|
17840
17930
|
return {
|
|
17841
17931
|
ok: false,
|
|
@@ -17934,14 +18024,14 @@ function validateFixtureBehavior(value) {
|
|
|
17934
18024
|
});
|
|
17935
18025
|
}
|
|
17936
18026
|
let replayBundle;
|
|
17937
|
-
if (
|
|
17938
|
-
if (!
|
|
18027
|
+
if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
18028
|
+
if (!record3.replayBundle || typeof record3.replayBundle !== "object" || Array.isArray(record3.replayBundle)) {
|
|
17939
18029
|
return {
|
|
17940
18030
|
ok: false,
|
|
17941
18031
|
error: "fixtureBehavior.replayBundle must be an object."
|
|
17942
18032
|
};
|
|
17943
18033
|
}
|
|
17944
|
-
const replay =
|
|
18034
|
+
const replay = record3.replayBundle;
|
|
17945
18035
|
const replayUnknownKeys = Object.keys(replay).filter(
|
|
17946
18036
|
(key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
|
|
17947
18037
|
);
|
|
@@ -17989,7 +18079,7 @@ function validateFixtureBehavior(value) {
|
|
|
17989
18079
|
...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
|
|
17990
18080
|
};
|
|
17991
18081
|
}
|
|
17992
|
-
if (
|
|
18082
|
+
if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17993
18083
|
return {
|
|
17994
18084
|
ok: true,
|
|
17995
18085
|
behavior: {
|
|
@@ -18007,15 +18097,15 @@ function validateFixtureBehavior(value) {
|
|
|
18007
18097
|
}
|
|
18008
18098
|
};
|
|
18009
18099
|
}
|
|
18010
|
-
if (!Array.isArray(
|
|
18100
|
+
if (!Array.isArray(record3.responseDelaySamplesMs) || record3.responseDelaySamplesMs.length === 0 || record3.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
18011
18101
|
return {
|
|
18012
18102
|
ok: false,
|
|
18013
18103
|
error: `fixtureBehavior.responseDelaySamplesMs must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
|
|
18014
18104
|
};
|
|
18015
18105
|
}
|
|
18016
18106
|
const samples = [];
|
|
18017
|
-
for (let index = 0; index <
|
|
18018
|
-
const value2 =
|
|
18107
|
+
for (let index = 0; index < record3.responseDelaySamplesMs.length; index += 1) {
|
|
18108
|
+
const value2 = record3.responseDelaySamplesMs[index];
|
|
18019
18109
|
if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 0 || value2 > MAX_FIXTURE_RESPONSE_DELAY_MS) {
|
|
18020
18110
|
return {
|
|
18021
18111
|
ok: false,
|
|
@@ -18794,8 +18884,8 @@ function looksLikeStagedFileRef(value) {
|
|
|
18794
18884
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
18795
18885
|
return false;
|
|
18796
18886
|
}
|
|
18797
|
-
const
|
|
18798
|
-
return typeof
|
|
18887
|
+
const record3 = value;
|
|
18888
|
+
return typeof record3.contentHash === "string" || typeof record3.contentBase64 === "string" || typeof record3.logicalPath === "string" && typeof record3.bytes === "number";
|
|
18799
18889
|
}
|
|
18800
18890
|
var CSV_DATA_INPUT_KEY = "csv";
|
|
18801
18891
|
function collectLocalFileInputRefs(value, inputPath, key, out) {
|
|
@@ -19308,8 +19398,8 @@ function readLiveRunField(event, field) {
|
|
|
19308
19398
|
const records = [payload, payload.progress, run, run?.progress].filter(
|
|
19309
19399
|
(value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
|
|
19310
19400
|
);
|
|
19311
|
-
for (const
|
|
19312
|
-
if (
|
|
19401
|
+
for (const record3 of records) {
|
|
19402
|
+
if (record3[field] !== void 0) return record3[field];
|
|
19313
19403
|
}
|
|
19314
19404
|
return void 0;
|
|
19315
19405
|
}
|
|
@@ -19611,8 +19701,8 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
19611
19701
|
if (!state || typeof state !== "object" || Array.isArray(state)) {
|
|
19612
19702
|
continue;
|
|
19613
19703
|
}
|
|
19614
|
-
const
|
|
19615
|
-
const progress =
|
|
19704
|
+
const record3 = state;
|
|
19705
|
+
const progress = record3.progress && typeof record3.progress === "object" && !Array.isArray(record3.progress) ? record3.progress : null;
|
|
19616
19706
|
if (!progress) {
|
|
19617
19707
|
continue;
|
|
19618
19708
|
}
|
|
@@ -19629,7 +19719,7 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
19629
19719
|
completed: progress.completed
|
|
19630
19720
|
});
|
|
19631
19721
|
lines.push(
|
|
19632
|
-
`progress ${formatProgressLabel(
|
|
19722
|
+
`progress ${formatProgressLabel(record3.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
|
|
19633
19723
|
);
|
|
19634
19724
|
}
|
|
19635
19725
|
return lines;
|
|
@@ -20309,11 +20399,11 @@ function truncateErrorForDisplay(message, runId, maxChars = RUN_ERROR_DISPLAY_MA
|
|
|
20309
20399
|
const fullErrorHint = runId ? ` (full error: deepline runs get ${runId} --full)` : " (full error: deepline runs get <runId> --full)";
|
|
20310
20400
|
return `${wordBoundary}\u2026${fullErrorHint}`;
|
|
20311
20401
|
}
|
|
20312
|
-
function clampJsonPreviewText(
|
|
20313
|
-
if (
|
|
20314
|
-
return
|
|
20402
|
+
function clampJsonPreviewText(json2, maxChars) {
|
|
20403
|
+
if (json2.length <= maxChars) {
|
|
20404
|
+
return json2;
|
|
20315
20405
|
}
|
|
20316
|
-
const slice =
|
|
20406
|
+
const slice = json2.slice(0, maxChars);
|
|
20317
20407
|
const lastNewline = slice.lastIndexOf("\n");
|
|
20318
20408
|
const head = lastNewline > 0 ? slice.slice(0, lastNewline) : slice;
|
|
20319
20409
|
return `${head}
|
|
@@ -20439,12 +20529,12 @@ function defaultResultForEnvelope(value, depth = 0) {
|
|
|
20439
20529
|
return output2;
|
|
20440
20530
|
}
|
|
20441
20531
|
function formatJsonPreview(value) {
|
|
20442
|
-
const
|
|
20443
|
-
if (!
|
|
20532
|
+
const json2 = JSON.stringify(value, null, 2);
|
|
20533
|
+
if (!json2 || json2 === "{}") {
|
|
20444
20534
|
return [];
|
|
20445
20535
|
}
|
|
20446
20536
|
const MAX_CHARS = 4e3;
|
|
20447
|
-
const truncated = clampJsonPreviewText(
|
|
20537
|
+
const truncated = clampJsonPreviewText(json2, MAX_CHARS);
|
|
20448
20538
|
return truncated.split("\n").map((line) => ` ${line}`);
|
|
20449
20539
|
}
|
|
20450
20540
|
function formatReturnValue(result) {
|
|
@@ -20472,17 +20562,17 @@ function collectDatasetHandleLines(value, path = "result") {
|
|
|
20472
20562
|
return [];
|
|
20473
20563
|
}
|
|
20474
20564
|
if (isDatasetHandle(value)) {
|
|
20475
|
-
const
|
|
20476
|
-
const count = typeof
|
|
20477
|
-
const preview = Array.isArray(
|
|
20565
|
+
const record3 = value;
|
|
20566
|
+
const count = typeof record3.count === "number" ? record3.count : typeof record3.rowCount === "number" ? record3.rowCount : null;
|
|
20567
|
+
const preview = Array.isArray(record3.preview) ? record3.preview : [];
|
|
20478
20568
|
const lines2 = [
|
|
20479
|
-
` dataset ${typeof
|
|
20569
|
+
` dataset ${typeof record3.path === "string" ? record3.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
|
|
20480
20570
|
];
|
|
20481
|
-
if (typeof
|
|
20482
|
-
lines2.push(` query dataset: ${
|
|
20571
|
+
if (typeof record3.queryDatasetCommand === "string") {
|
|
20572
|
+
lines2.push(` query dataset: ${record3.queryDatasetCommand}`);
|
|
20483
20573
|
}
|
|
20484
|
-
if (typeof
|
|
20485
|
-
lines2.push(` export CSV: ${
|
|
20574
|
+
if (typeof record3.slowExportAsCsvCommand === "string") {
|
|
20575
|
+
lines2.push(` export CSV: ${record3.slowExportAsCsvCommand}`);
|
|
20486
20576
|
}
|
|
20487
20577
|
return lines2;
|
|
20488
20578
|
}
|
|
@@ -20879,8 +20969,8 @@ function withTerminalPlayIdentity(status, playName) {
|
|
|
20879
20969
|
if (!playName.trim() || getPlayRunPackage(status)) {
|
|
20880
20970
|
return status;
|
|
20881
20971
|
}
|
|
20882
|
-
const
|
|
20883
|
-
const hasIdentity = typeof
|
|
20972
|
+
const record3 = status;
|
|
20973
|
+
const hasIdentity = typeof record3.playName === "string" && record3.playName.trim().length > 0 || typeof record3.name === "string" && record3.name.trim().length > 0 || Boolean(getStringField(record3.run, "playName"));
|
|
20884
20974
|
if (hasIdentity) {
|
|
20885
20975
|
return status;
|
|
20886
20976
|
}
|
|
@@ -20993,9 +21083,9 @@ function formatSummaryScalar(value) {
|
|
|
20993
21083
|
}
|
|
20994
21084
|
return null;
|
|
20995
21085
|
}
|
|
20996
|
-
function formatSummaryScalarParts(
|
|
21086
|
+
function formatSummaryScalarParts(record3, skipKeys = /* @__PURE__ */ new Set()) {
|
|
20997
21087
|
const parts = [];
|
|
20998
|
-
for (const [key, value] of Object.entries(
|
|
21088
|
+
for (const [key, value] of Object.entries(record3)) {
|
|
20999
21089
|
if (skipKeys.has(key)) {
|
|
21000
21090
|
continue;
|
|
21001
21091
|
}
|
|
@@ -21022,13 +21112,13 @@ function formatTopValuesPart(value) {
|
|
|
21022
21112
|
return `top_values=${entries.map(([topValue, count]) => `${topValue}=${String(count)}`).join(", ")}`;
|
|
21023
21113
|
}
|
|
21024
21114
|
function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
|
|
21025
|
-
const
|
|
21026
|
-
const columnStats = readRecord(
|
|
21027
|
-
if (!
|
|
21115
|
+
const record3 = readRecord(summary);
|
|
21116
|
+
const columnStats = readRecord(record3?.columnStats);
|
|
21117
|
+
if (!record3 || !columnStats) {
|
|
21028
21118
|
return [];
|
|
21029
21119
|
}
|
|
21030
21120
|
const lines = [];
|
|
21031
|
-
const rowCounts = readRecord(
|
|
21121
|
+
const rowCounts = readRecord(record3.rowCounts);
|
|
21032
21122
|
if (rowCounts) {
|
|
21033
21123
|
const persisted = readNonNegativeInteger(rowCounts.persisted);
|
|
21034
21124
|
const succeeded = readNonNegativeInteger(rowCounts.succeeded);
|
|
@@ -21044,7 +21134,7 @@ function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
|
|
|
21044
21134
|
}
|
|
21045
21135
|
}
|
|
21046
21136
|
const parts = formatSummaryScalarParts(
|
|
21047
|
-
|
|
21137
|
+
record3,
|
|
21048
21138
|
/* @__PURE__ */ new Set(["columnStats", "rowCounts"])
|
|
21049
21139
|
);
|
|
21050
21140
|
if (parts.length > 0) {
|
|
@@ -21074,35 +21164,35 @@ function actionToCommand(action) {
|
|
|
21074
21164
|
if (!action || typeof action !== "object" || Array.isArray(action)) {
|
|
21075
21165
|
return null;
|
|
21076
21166
|
}
|
|
21077
|
-
const
|
|
21078
|
-
if (typeof
|
|
21079
|
-
return
|
|
21167
|
+
const record3 = action;
|
|
21168
|
+
if (typeof record3.command === "string" && record3.command.trim()) {
|
|
21169
|
+
return record3.command.trim();
|
|
21080
21170
|
}
|
|
21081
|
-
if (
|
|
21082
|
-
return `deepline runs get ${
|
|
21171
|
+
if (record3.kind === "deepline_run_inspect" && typeof record3.runId === "string") {
|
|
21172
|
+
return `deepline runs get ${record3.runId} --json`;
|
|
21083
21173
|
}
|
|
21084
|
-
if (
|
|
21085
|
-
return `deepline runs get ${
|
|
21174
|
+
if (record3.kind === "deepline_run_full" && typeof record3.runId === "string") {
|
|
21175
|
+
return `deepline runs get ${record3.runId} --full --json`;
|
|
21086
21176
|
}
|
|
21087
|
-
if (
|
|
21088
|
-
return `deepline runs get ${
|
|
21177
|
+
if (record3.kind === "deepline_run_billing" && typeof record3.runId === "string") {
|
|
21178
|
+
return `deepline runs get ${record3.runId} --full --json | jq '.billing'`;
|
|
21089
21179
|
}
|
|
21090
|
-
if (
|
|
21091
|
-
return `deepline runs export ${
|
|
21092
|
-
|
|
21093
|
-
)} --out ${shellSingleQuote(`${
|
|
21180
|
+
if (record3.kind === "deepline_run_export" && typeof record3.runId === "string" && typeof record3.datasetPath === "string") {
|
|
21181
|
+
return `deepline runs export ${record3.runId} --dataset ${shellSingleQuote(
|
|
21182
|
+
record3.datasetPath
|
|
21183
|
+
)} --out ${shellSingleQuote(`${record3.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
|
|
21094
21184
|
}
|
|
21095
|
-
if (
|
|
21096
|
-
if (typeof
|
|
21097
|
-
return
|
|
21185
|
+
if (record3.kind === "deepline_run_logs") {
|
|
21186
|
+
if (typeof record3.command === "string" && record3.command.trim()) {
|
|
21187
|
+
return record3.command;
|
|
21098
21188
|
}
|
|
21099
|
-
if (typeof
|
|
21100
|
-
return
|
|
21189
|
+
if (typeof record3.runId === "string") {
|
|
21190
|
+
return record3.view === "failed" ? `deepline runs get ${record3.runId} --log-failed --json` : `deepline runs logs ${record3.runId} --json`;
|
|
21101
21191
|
}
|
|
21102
21192
|
}
|
|
21103
|
-
if (
|
|
21104
|
-
const maxRows = typeof
|
|
21105
|
-
return `deepline db query --sql ${shellSingleQuote(
|
|
21193
|
+
if (record3.kind === "deepline_db_query" && typeof record3.sql === "string") {
|
|
21194
|
+
const maxRows = typeof record3.maxRows === "number" && Number.isFinite(record3.maxRows) ? Math.trunc(record3.maxRows) : 20;
|
|
21195
|
+
return `deepline db query --sql ${shellSingleQuote(record3.sql)} --max-rows ${maxRows} --json`;
|
|
21106
21196
|
}
|
|
21107
21197
|
return null;
|
|
21108
21198
|
}
|
|
@@ -21177,8 +21267,8 @@ function formatPackageDatasetActionLines(packaged) {
|
|
|
21177
21267
|
}
|
|
21178
21268
|
function formatInlinePackageValue(value) {
|
|
21179
21269
|
const compacted = compactReturnValue(value);
|
|
21180
|
-
const
|
|
21181
|
-
return clampJsonPreviewText(
|
|
21270
|
+
const json2 = JSON.stringify(compacted);
|
|
21271
|
+
return clampJsonPreviewText(json2 ?? String(compacted), 500);
|
|
21182
21272
|
}
|
|
21183
21273
|
function formatPackageValueOutputLines(packaged) {
|
|
21184
21274
|
const outputs = packaged.outputs && typeof packaged.outputs === "object" && !Array.isArray(packaged.outputs) ? packaged.outputs : null;
|
|
@@ -21511,12 +21601,12 @@ function exportableSheetRow(row) {
|
|
|
21511
21601
|
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
21512
21602
|
return null;
|
|
21513
21603
|
}
|
|
21514
|
-
const
|
|
21515
|
-
const data =
|
|
21604
|
+
const record3 = row;
|
|
21605
|
+
const data = record3.data;
|
|
21516
21606
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
21517
21607
|
return data;
|
|
21518
21608
|
}
|
|
21519
|
-
const fallback = { ...
|
|
21609
|
+
const fallback = { ...record3 };
|
|
21520
21610
|
for (const key of [
|
|
21521
21611
|
"key",
|
|
21522
21612
|
"status",
|
|
@@ -21864,8 +21954,8 @@ var PLAY_SYNTAX_MIGRATION_ERROR_MARKERS = [
|
|
|
21864
21954
|
"ctx.map(...) has been replaced by ctx.dataset(...)",
|
|
21865
21955
|
"Dataset .step(...) has been replaced by .withColumn(...)"
|
|
21866
21956
|
];
|
|
21867
|
-
function stringArrayField(
|
|
21868
|
-
const value =
|
|
21957
|
+
function stringArrayField(record3, key) {
|
|
21958
|
+
const value = record3[key];
|
|
21869
21959
|
if (!Array.isArray(value)) return [];
|
|
21870
21960
|
return value.filter((entry) => typeof entry === "string");
|
|
21871
21961
|
}
|
|
@@ -22696,8 +22786,8 @@ function cronExecutionLabel(status) {
|
|
|
22696
22786
|
return status;
|
|
22697
22787
|
}
|
|
22698
22788
|
function readLiveCronMetadata(play) {
|
|
22699
|
-
const
|
|
22700
|
-
const metadata = readRecord(
|
|
22789
|
+
const record3 = readRecord(play);
|
|
22790
|
+
const metadata = readRecord(record3?.triggerMetadata);
|
|
22701
22791
|
return {
|
|
22702
22792
|
schedule: typeof metadata?.cronSchedule === "string" ? metadata.cronSchedule : null,
|
|
22703
22793
|
timezone: typeof metadata?.cronTimezone === "string" ? metadata.cronTimezone : null,
|
|
@@ -28028,9 +28118,9 @@ async function expandCompiledConfigAtFiles(value) {
|
|
|
28028
28118
|
if (!value || typeof value !== "object") {
|
|
28029
28119
|
return value;
|
|
28030
28120
|
}
|
|
28031
|
-
const
|
|
28121
|
+
const record3 = value;
|
|
28032
28122
|
const expanded = {};
|
|
28033
|
-
for (const [key, entry] of Object.entries(
|
|
28123
|
+
for (const [key, entry] of Object.entries(record3)) {
|
|
28034
28124
|
expanded[key] = await expandCompiledConfigAtFiles(entry);
|
|
28035
28125
|
}
|
|
28036
28126
|
for (const field of ["extract_js", "run_if_js"]) {
|
|
@@ -28828,26 +28918,26 @@ function readFirstEnrichDatasetActions(value) {
|
|
|
28828
28918
|
}
|
|
28829
28919
|
return null;
|
|
28830
28920
|
}
|
|
28831
|
-
const
|
|
28832
|
-
const actions = isRecord11(
|
|
28921
|
+
const record3 = candidate;
|
|
28922
|
+
const actions = isRecord11(record3.actions) ? record3.actions : null;
|
|
28833
28923
|
const currentQuery = isRecord11(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
|
|
28834
28924
|
const legacyQuery = isRecord11(actions?.query) ? actions.query : null;
|
|
28835
28925
|
const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
|
|
28836
28926
|
if (query?.kind === "deepline_db_query") {
|
|
28837
28927
|
return {
|
|
28838
|
-
dataset:
|
|
28928
|
+
dataset: record3,
|
|
28839
28929
|
query,
|
|
28840
28930
|
...isRecord11(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
|
|
28841
28931
|
};
|
|
28842
28932
|
}
|
|
28843
|
-
if (options.allowLegacy &&
|
|
28933
|
+
if (options.allowLegacy && record3.kind === "dataset" && typeof record3.queryDatasetCommand === "string" && record3.queryDatasetCommand.trim()) {
|
|
28844
28934
|
return {
|
|
28845
|
-
dataset:
|
|
28846
|
-
queryDatasetCommand:
|
|
28847
|
-
...typeof
|
|
28935
|
+
dataset: record3,
|
|
28936
|
+
queryDatasetCommand: record3.queryDatasetCommand.trim(),
|
|
28937
|
+
...typeof record3.slowExportAsCsvCommand === "string" && record3.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record3.slowExportAsCsvCommand.trim() } : {}
|
|
28848
28938
|
};
|
|
28849
28939
|
}
|
|
28850
|
-
for (const [key, entry] of Object.entries(
|
|
28940
|
+
for (const [key, entry] of Object.entries(record3)) {
|
|
28851
28941
|
if (key === "preview") {
|
|
28852
28942
|
continue;
|
|
28853
28943
|
}
|
|
@@ -28863,8 +28953,8 @@ function readFirstEnrichDatasetActions(value) {
|
|
|
28863
28953
|
seen.clear();
|
|
28864
28954
|
return walk(value, { allowLegacy: true });
|
|
28865
28955
|
}
|
|
28866
|
-
function actionStringField(
|
|
28867
|
-
const value =
|
|
28956
|
+
function actionStringField(record3, key) {
|
|
28957
|
+
const value = record3[key];
|
|
28868
28958
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
28869
28959
|
}
|
|
28870
28960
|
function parseSqlFromDbQueryCommand(command) {
|
|
@@ -29208,12 +29298,12 @@ function collectStringFields(value, key, output2, depth = 0) {
|
|
|
29208
29298
|
}
|
|
29209
29299
|
return;
|
|
29210
29300
|
}
|
|
29211
|
-
const
|
|
29212
|
-
const direct =
|
|
29301
|
+
const record3 = value;
|
|
29302
|
+
const direct = record3[key];
|
|
29213
29303
|
if (typeof direct === "string" && direct.trim()) {
|
|
29214
29304
|
output2.add(direct.trim());
|
|
29215
29305
|
}
|
|
29216
|
-
for (const child of Object.values(
|
|
29306
|
+
for (const child of Object.values(record3)) {
|
|
29217
29307
|
collectStringFields(child, key, output2, depth + 1);
|
|
29218
29308
|
}
|
|
29219
29309
|
}
|
|
@@ -29399,23 +29489,23 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
|
|
|
29399
29489
|
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
29400
29490
|
return null;
|
|
29401
29491
|
}
|
|
29402
|
-
const
|
|
29403
|
-
const data =
|
|
29492
|
+
const record3 = row;
|
|
29493
|
+
const data = record3.data;
|
|
29404
29494
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
29405
29495
|
const exported = { ...data };
|
|
29406
29496
|
applyFailureCellMeta(exported, exported[ENRICH_CELL_META_FIELD], {
|
|
29407
|
-
rowError:
|
|
29497
|
+
rowError: record3.error
|
|
29408
29498
|
});
|
|
29409
|
-
applyFailureCellMeta(exported,
|
|
29410
|
-
applyFailureCellMeta(exported,
|
|
29411
|
-
rowError:
|
|
29499
|
+
applyFailureCellMeta(exported, record3.cellMeta, { rowError: record3.error });
|
|
29500
|
+
applyFailureCellMeta(exported, record3.cellMetaPatch, {
|
|
29501
|
+
rowError: record3.error
|
|
29412
29502
|
});
|
|
29413
|
-
applyFailureCellMeta(exported,
|
|
29414
|
-
rowError:
|
|
29503
|
+
applyFailureCellMeta(exported, record3[ENRICH_CELL_META_PATCH_FIELD], {
|
|
29504
|
+
rowError: record3.error
|
|
29415
29505
|
});
|
|
29416
29506
|
delete exported[ENRICH_CELL_META_FIELD];
|
|
29417
29507
|
delete exported[ENRICH_CELL_META_PATCH_FIELD];
|
|
29418
|
-
const inputIndex = typeof
|
|
29508
|
+
const inputIndex = typeof record3.inputIndex === "number" ? record3.inputIndex : typeof record3.inputIndex === "string" && record3.inputIndex.trim() ? Number(record3.inputIndex) : Number.NaN;
|
|
29419
29509
|
if (Number.isInteger(inputIndex) && inputIndex >= 0) {
|
|
29420
29510
|
if (ENRICH_SOURCE_ROW_INDEX_COLUMN in exported) {
|
|
29421
29511
|
exported[ENRICH_ORIGINAL_SOURCE_ROW_INDEX_COLUMN] = exported[ENRICH_SOURCE_ROW_INDEX_COLUMN];
|
|
@@ -29424,18 +29514,18 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
|
|
|
29424
29514
|
}
|
|
29425
29515
|
return exported;
|
|
29426
29516
|
}
|
|
29427
|
-
const fallback = { ...
|
|
29517
|
+
const fallback = { ...record3 };
|
|
29428
29518
|
applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_FIELD], {
|
|
29429
|
-
rowError:
|
|
29519
|
+
rowError: record3.error
|
|
29430
29520
|
});
|
|
29431
|
-
applyFailureCellMeta(fallback,
|
|
29432
|
-
rowError:
|
|
29521
|
+
applyFailureCellMeta(fallback, record3.cellMeta, {
|
|
29522
|
+
rowError: record3.error
|
|
29433
29523
|
});
|
|
29434
|
-
applyFailureCellMeta(fallback,
|
|
29435
|
-
rowError:
|
|
29524
|
+
applyFailureCellMeta(fallback, record3.cellMetaPatch, {
|
|
29525
|
+
rowError: record3.error
|
|
29436
29526
|
});
|
|
29437
29527
|
applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_PATCH_FIELD], {
|
|
29438
|
-
rowError:
|
|
29528
|
+
rowError: record3.error
|
|
29439
29529
|
});
|
|
29440
29530
|
for (const key of [
|
|
29441
29531
|
"key",
|
|
@@ -29654,16 +29744,16 @@ function isWaterfallResultMeaningful(value) {
|
|
|
29654
29744
|
return value.some(isWaterfallResultMeaningful);
|
|
29655
29745
|
}
|
|
29656
29746
|
if (value && typeof value === "object") {
|
|
29657
|
-
const
|
|
29658
|
-
const status = typeof
|
|
29747
|
+
const record3 = value;
|
|
29748
|
+
const status = typeof record3.status === "string" ? record3.status.trim().toLowerCase() : "";
|
|
29659
29749
|
if (status === "error" || status === "failed") {
|
|
29660
29750
|
return false;
|
|
29661
29751
|
}
|
|
29662
|
-
if (typeof
|
|
29752
|
+
if (typeof record3.error === "string" && record3.error.trim()) {
|
|
29663
29753
|
return false;
|
|
29664
29754
|
}
|
|
29665
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
29666
|
-
return isWaterfallResultMeaningful(
|
|
29755
|
+
if (Object.prototype.hasOwnProperty.call(record3, "matched_result")) {
|
|
29756
|
+
return isWaterfallResultMeaningful(record3.matched_result);
|
|
29667
29757
|
}
|
|
29668
29758
|
for (const key of [
|
|
29669
29759
|
"value",
|
|
@@ -29678,11 +29768,11 @@ function isWaterfallResultMeaningful(value) {
|
|
|
29678
29768
|
"result",
|
|
29679
29769
|
"data"
|
|
29680
29770
|
]) {
|
|
29681
|
-
if (isWaterfallResultMeaningful(
|
|
29771
|
+
if (isWaterfallResultMeaningful(record3[key])) {
|
|
29682
29772
|
return true;
|
|
29683
29773
|
}
|
|
29684
29774
|
}
|
|
29685
|
-
return Object.entries(
|
|
29775
|
+
return Object.entries(record3).some(
|
|
29686
29776
|
([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
|
|
29687
29777
|
);
|
|
29688
29778
|
}
|
|
@@ -29698,8 +29788,8 @@ function stableRowSnapshot(value) {
|
|
|
29698
29788
|
return `[${value.map(stableRowSnapshot).join(",")}]`;
|
|
29699
29789
|
}
|
|
29700
29790
|
if (value && typeof value === "object") {
|
|
29701
|
-
const
|
|
29702
|
-
return `{${Object.keys(
|
|
29791
|
+
const record3 = value;
|
|
29792
|
+
return `{${Object.keys(record3).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record3[key])}`).join(",")}}`;
|
|
29703
29793
|
}
|
|
29704
29794
|
return JSON.stringify(value);
|
|
29705
29795
|
}
|
|
@@ -30286,8 +30376,8 @@ function addEnrichFollowUpCommand(commands, seen, command) {
|
|
|
30286
30376
|
seen.add(normalized);
|
|
30287
30377
|
commands.push({ ...command, command: normalized });
|
|
30288
30378
|
}
|
|
30289
|
-
function datasetSelectorForEnrichCommand(
|
|
30290
|
-
const candidates = [
|
|
30379
|
+
function datasetSelectorForEnrichCommand(record3, fallbackPath) {
|
|
30380
|
+
const candidates = [record3.path, record3.tableNamespace, fallbackPath];
|
|
30291
30381
|
for (const candidate of candidates) {
|
|
30292
30382
|
if (typeof candidate === "string" && candidate.trim()) {
|
|
30293
30383
|
return candidate.trim();
|
|
@@ -30349,19 +30439,19 @@ function collectDatasetFollowUpCommands(value, state) {
|
|
|
30349
30439
|
);
|
|
30350
30440
|
return;
|
|
30351
30441
|
}
|
|
30352
|
-
const
|
|
30353
|
-
const isDataset =
|
|
30442
|
+
const record3 = value;
|
|
30443
|
+
const isDataset = record3.kind === "dataset";
|
|
30354
30444
|
if (isDataset) {
|
|
30355
|
-
const selector = datasetSelectorForEnrichCommand(
|
|
30356
|
-
const labelPath = typeof
|
|
30357
|
-
if (typeof
|
|
30445
|
+
const selector = datasetSelectorForEnrichCommand(record3, state.path);
|
|
30446
|
+
const labelPath = typeof record3.path === "string" && record3.path.trim() ? record3.path.trim() : selector ?? state.path;
|
|
30447
|
+
if (typeof record3.queryDatasetCommand === "string") {
|
|
30358
30448
|
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
30359
30449
|
label: `query ${labelPath}`,
|
|
30360
30450
|
path: labelPath,
|
|
30361
|
-
command:
|
|
30451
|
+
command: record3.queryDatasetCommand
|
|
30362
30452
|
});
|
|
30363
30453
|
}
|
|
30364
|
-
const exportCommand = typeof
|
|
30454
|
+
const exportCommand = typeof record3.slowExportAsCsvCommand === "string" ? record3.slowExportAsCsvCommand : typeof record3.fullExportCommand === "string" ? record3.fullExportCommand : null;
|
|
30365
30455
|
if (exportCommand) {
|
|
30366
30456
|
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
30367
30457
|
label: `export ${labelPath}`,
|
|
@@ -30378,7 +30468,7 @@ function collectDatasetFollowUpCommands(value, state) {
|
|
|
30378
30468
|
});
|
|
30379
30469
|
}
|
|
30380
30470
|
}
|
|
30381
|
-
for (const [key, child] of Object.entries(
|
|
30471
|
+
for (const [key, child] of Object.entries(record3)) {
|
|
30382
30472
|
if (key === "preview" || key === "access") {
|
|
30383
30473
|
continue;
|
|
30384
30474
|
}
|
|
@@ -31236,7 +31326,7 @@ function registerEnrichCommand(program) {
|
|
|
31236
31326
|
"--open",
|
|
31237
31327
|
"Open the generated play page in a browser after the run starts."
|
|
31238
31328
|
).addOption(
|
|
31239
|
-
new
|
|
31329
|
+
new Option2(
|
|
31240
31330
|
"--no-open [legacy-value]",
|
|
31241
31331
|
"Removed legacy option"
|
|
31242
31332
|
).hideHelp()
|
|
@@ -31612,7 +31702,7 @@ function registerEnrichCommand(program) {
|
|
|
31612
31702
|
}
|
|
31613
31703
|
|
|
31614
31704
|
// src/cli/commands/feedback.ts
|
|
31615
|
-
import { Option as
|
|
31705
|
+
import { Option as Option3 } from "commander";
|
|
31616
31706
|
import { readFileSync as readFileSync9 } from "fs";
|
|
31617
31707
|
async function handleFeedback(text, options) {
|
|
31618
31708
|
const message = resolveFeedbackText(text, options.file);
|
|
@@ -31693,7 +31783,7 @@ Examples:
|
|
|
31693
31783
|
deepline feedback send "plays run failed after upload" --command "deepline plays run my.play.ts --watch" --error-outcome terminal
|
|
31694
31784
|
`
|
|
31695
31785
|
).argument("[text]", "Feedback text").option("--file <path>", "Read feedback text from a file, or - for stdin").option("--command <command>", "Command that reproduced the issue").option("--payload <payload>", "JSON or plain-text payload for the repro").addOption(
|
|
31696
|
-
new
|
|
31786
|
+
new Option3(
|
|
31697
31787
|
"--error-outcome <outcome>",
|
|
31698
31788
|
"Error impact on the task: terminal or continued"
|
|
31699
31789
|
).choices(["terminal", "continued"])
|
|
@@ -31852,9 +31942,9 @@ function readCodexSessionId(filePath) {
|
|
|
31852
31942
|
)) {
|
|
31853
31943
|
const parsed = parseJsonLine(line);
|
|
31854
31944
|
if (!parsed || typeof parsed !== "object") continue;
|
|
31855
|
-
const
|
|
31856
|
-
const payload =
|
|
31857
|
-
const id =
|
|
31945
|
+
const record3 = parsed;
|
|
31946
|
+
const payload = record3.payload && typeof record3.payload === "object" ? record3.payload : null;
|
|
31947
|
+
const id = record3.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
|
|
31858
31948
|
if (id && UUID_RE.test(id)) return id;
|
|
31859
31949
|
}
|
|
31860
31950
|
} catch {
|
|
@@ -31953,15 +32043,15 @@ function messageContentKey(value) {
|
|
|
31953
32043
|
if (!Array.isArray(content)) return null;
|
|
31954
32044
|
return content.map((block) => {
|
|
31955
32045
|
if (!block || typeof block !== "object") return String(block);
|
|
31956
|
-
const
|
|
31957
|
-
const type = String(
|
|
32046
|
+
const record3 = block;
|
|
32047
|
+
const type = String(record3.type ?? "");
|
|
31958
32048
|
if (type === "tool_use") {
|
|
31959
|
-
return `tool_use:${String(
|
|
32049
|
+
return `tool_use:${String(record3.name ?? "")}:${String(record3.id ?? "")}`;
|
|
31960
32050
|
}
|
|
31961
32051
|
if (type === "tool_result") {
|
|
31962
|
-
return `tool_result:${String(
|
|
32052
|
+
return `tool_result:${String(record3.tool_use_id ?? "")}`;
|
|
31963
32053
|
}
|
|
31964
|
-
return String(
|
|
32054
|
+
return String(record3.text ?? type);
|
|
31965
32055
|
}).join("\n");
|
|
31966
32056
|
}
|
|
31967
32057
|
function dedupConsecutiveEvents(raw) {
|
|
@@ -31976,9 +32066,9 @@ function dedupConsecutiveEvents(raw) {
|
|
|
31976
32066
|
index += 1;
|
|
31977
32067
|
continue;
|
|
31978
32068
|
}
|
|
31979
|
-
const
|
|
31980
|
-
const eventType = String(
|
|
31981
|
-
const eventKey = messageContentKey(
|
|
32069
|
+
const record3 = event;
|
|
32070
|
+
const eventType = String(record3.type ?? "");
|
|
32071
|
+
const eventKey = messageContentKey(record3);
|
|
31982
32072
|
if (!["user", "assistant"].includes(eventType) || !eventKey) {
|
|
31983
32073
|
output2.push(rawLines[index] ?? "");
|
|
31984
32074
|
index += 1;
|
|
@@ -31997,9 +32087,9 @@ function dedupConsecutiveEvents(raw) {
|
|
|
31997
32087
|
cursor += 1;
|
|
31998
32088
|
}
|
|
31999
32089
|
if (runCount > 1) {
|
|
32000
|
-
|
|
32001
|
-
|
|
32002
|
-
output2.push(JSON.stringify(
|
|
32090
|
+
record3._repeat_count = runCount;
|
|
32091
|
+
record3._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
|
|
32092
|
+
output2.push(JSON.stringify(record3));
|
|
32003
32093
|
index = cursor;
|
|
32004
32094
|
continue;
|
|
32005
32095
|
}
|
|
@@ -32044,9 +32134,9 @@ function selectiveCompactToolResults(raw) {
|
|
|
32044
32134
|
lines.push(line);
|
|
32045
32135
|
continue;
|
|
32046
32136
|
}
|
|
32047
|
-
const
|
|
32048
|
-
if (
|
|
32049
|
-
const message =
|
|
32137
|
+
const record3 = parsed;
|
|
32138
|
+
if (record3.type === "user") {
|
|
32139
|
+
const message = record3.message;
|
|
32050
32140
|
const content = message && typeof message === "object" ? message.content : null;
|
|
32051
32141
|
if (Array.isArray(content)) {
|
|
32052
32142
|
message.content = content.map(
|
|
@@ -32054,7 +32144,7 @@ function selectiveCompactToolResults(raw) {
|
|
|
32054
32144
|
);
|
|
32055
32145
|
}
|
|
32056
32146
|
}
|
|
32057
|
-
lines.push(JSON.stringify(
|
|
32147
|
+
lines.push(JSON.stringify(record3));
|
|
32058
32148
|
}
|
|
32059
32149
|
return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
|
|
32060
32150
|
` : "", "utf8");
|
|
@@ -32080,15 +32170,15 @@ function compactCodexEvents(raw) {
|
|
|
32080
32170
|
lines.push(rawLines[index] ?? "");
|
|
32081
32171
|
return;
|
|
32082
32172
|
}
|
|
32083
|
-
const
|
|
32084
|
-
if (
|
|
32085
|
-
const payload =
|
|
32173
|
+
const record3 = event;
|
|
32174
|
+
if (record3.type === "world_state") return;
|
|
32175
|
+
const payload = record3.payload;
|
|
32086
32176
|
const payloadType = payload && typeof payload === "object" ? String(payload.type ?? "") : "";
|
|
32087
32177
|
if (payloadType === "token_count" && index !== lastTokenCountIndex) return;
|
|
32088
32178
|
if (payloadType === "custom_tool_call_output" || payloadType === "function_call_output" || payloadType === "tool_search_output") {
|
|
32089
32179
|
const record_payload = payload;
|
|
32090
32180
|
record_payload.output = compactEventValue(record_payload.output);
|
|
32091
|
-
lines.push(JSON.stringify(
|
|
32181
|
+
lines.push(JSON.stringify(record3));
|
|
32092
32182
|
return;
|
|
32093
32183
|
}
|
|
32094
32184
|
lines.push(rawLines[index] ?? "");
|
|
@@ -32294,8 +32384,8 @@ function parsePreparedEvents(buffer) {
|
|
|
32294
32384
|
return parsed ?? line;
|
|
32295
32385
|
});
|
|
32296
32386
|
}
|
|
32297
|
-
function escapeJsonForHtmlScript(
|
|
32298
|
-
return
|
|
32387
|
+
function escapeJsonForHtmlScript(json2) {
|
|
32388
|
+
return json2.replace(/</g, "\\u003c");
|
|
32299
32389
|
}
|
|
32300
32390
|
async function handleSessionsRender(options) {
|
|
32301
32391
|
const targets = resolveSessionTargets({
|
|
@@ -32556,11 +32646,317 @@ import { readFileSync as readFileSync11, writeFileSync as writeFileSync12 } from
|
|
|
32556
32646
|
import { resolve as resolve14 } from "path";
|
|
32557
32647
|
import { createInterface } from "readline/promises";
|
|
32558
32648
|
|
|
32649
|
+
// ../integration-contracts/monitor-input-contract.ts
|
|
32650
|
+
import Handlebars from "handlebars";
|
|
32651
|
+
function authoredMonitorFieldPath(path, field) {
|
|
32652
|
+
const batch = /^monitors\.(\d+)$/.exec(path);
|
|
32653
|
+
return `${batch ? `monitors[${batch[1]}]` : path}.${field}`;
|
|
32654
|
+
}
|
|
32655
|
+
function record(value) {
|
|
32656
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
32657
|
+
}
|
|
32658
|
+
function json(value, path, issues) {
|
|
32659
|
+
if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
|
|
32660
|
+
return;
|
|
32661
|
+
}
|
|
32662
|
+
if (Array.isArray(value)) {
|
|
32663
|
+
value.forEach((child, index) => json(child, `${path}.${index}`, issues));
|
|
32664
|
+
return;
|
|
32665
|
+
}
|
|
32666
|
+
const object = record(value);
|
|
32667
|
+
if (!object) {
|
|
32668
|
+
issues.push({
|
|
32669
|
+
severity: "error",
|
|
32670
|
+
code: "invalid_monitor_json_value",
|
|
32671
|
+
path,
|
|
32672
|
+
message: "Monitor values must be JSON values."
|
|
32673
|
+
});
|
|
32674
|
+
return;
|
|
32675
|
+
}
|
|
32676
|
+
for (const [key, child] of Object.entries(object)) {
|
|
32677
|
+
json(child, `${path}.${key}`, issues);
|
|
32678
|
+
}
|
|
32679
|
+
}
|
|
32680
|
+
function monitorSpec(value, path, issues) {
|
|
32681
|
+
const input2 = record(value);
|
|
32682
|
+
if (!input2) {
|
|
32683
|
+
issues.push({
|
|
32684
|
+
severity: "error",
|
|
32685
|
+
code: "invalid_monitor_spec",
|
|
32686
|
+
path,
|
|
32687
|
+
message: "A monitor must be a JSON object."
|
|
32688
|
+
});
|
|
32689
|
+
return null;
|
|
32690
|
+
}
|
|
32691
|
+
const allowed = /* @__PURE__ */ new Set(["key", "tool", "name", "payload"]);
|
|
32692
|
+
for (const key2 of Object.keys(input2)) {
|
|
32693
|
+
if (!allowed.has(key2)) {
|
|
32694
|
+
if (key2 === "controls") {
|
|
32695
|
+
issues.push({
|
|
32696
|
+
severity: "error",
|
|
32697
|
+
code: "CONTROLS_NOT_SUPPORTED",
|
|
32698
|
+
path: authoredMonitorFieldPath(path, "controls"),
|
|
32699
|
+
message: "Operational controls are managed by Deepline and cannot be authored in Batch or Fleet JSON.",
|
|
32700
|
+
suggestion: "Remove controls. Bind downstream automation in a Play with sqlListeners."
|
|
32701
|
+
});
|
|
32702
|
+
continue;
|
|
32703
|
+
}
|
|
32704
|
+
if (key2 === "play") {
|
|
32705
|
+
issues.push({
|
|
32706
|
+
severity: "error",
|
|
32707
|
+
code: "PLAY_BINDING_NOT_IN_MONITOR_SPEC",
|
|
32708
|
+
path: authoredMonitorFieldPath(path, "play"),
|
|
32709
|
+
message: "A monitor does not own Play bindings.",
|
|
32710
|
+
suggestion: "Declare sqlListeners in the Play, or run: deepline plays bootstrap monitor-triggered --out on-event.play.ts"
|
|
32711
|
+
});
|
|
32712
|
+
continue;
|
|
32713
|
+
}
|
|
32714
|
+
issues.push({
|
|
32715
|
+
severity: "error",
|
|
32716
|
+
code: "unknown_monitor_field",
|
|
32717
|
+
path: `${path}.${key2}`,
|
|
32718
|
+
message: `Monitor definitions do not accept '${key2}'.`
|
|
32719
|
+
});
|
|
32720
|
+
}
|
|
32721
|
+
}
|
|
32722
|
+
const key = typeof input2.key === "string" ? input2.key.trim() : "";
|
|
32723
|
+
const tool = typeof input2.tool === "string" ? input2.tool.trim() : "";
|
|
32724
|
+
const name = input2.name === void 0 ? void 0 : typeof input2.name === "string" && input2.name.trim() ? input2.name.trim() : null;
|
|
32725
|
+
const payload = record(input2.payload);
|
|
32726
|
+
if (!key) {
|
|
32727
|
+
issues.push({
|
|
32728
|
+
severity: "error",
|
|
32729
|
+
code: "invalid_monitor_key",
|
|
32730
|
+
path: `${path}.key`,
|
|
32731
|
+
message: "Monitor key must be a non-empty string."
|
|
32732
|
+
});
|
|
32733
|
+
}
|
|
32734
|
+
if (!tool) {
|
|
32735
|
+
issues.push({
|
|
32736
|
+
severity: "error",
|
|
32737
|
+
code: "invalid_monitor_tool",
|
|
32738
|
+
path: `${path}.tool`,
|
|
32739
|
+
message: "Monitor tool must be a non-empty literal string."
|
|
32740
|
+
});
|
|
32741
|
+
}
|
|
32742
|
+
if (name === null) {
|
|
32743
|
+
issues.push({
|
|
32744
|
+
severity: "error",
|
|
32745
|
+
code: "invalid_monitor_name",
|
|
32746
|
+
path: `${path}.name`,
|
|
32747
|
+
message: "Monitor name must be a non-empty string when supplied."
|
|
32748
|
+
});
|
|
32749
|
+
}
|
|
32750
|
+
if (!payload) {
|
|
32751
|
+
issues.push({
|
|
32752
|
+
severity: "error",
|
|
32753
|
+
code: "invalid_monitor_payload",
|
|
32754
|
+
path: `${path}.payload`,
|
|
32755
|
+
message: "Monitor payload must be an object."
|
|
32756
|
+
});
|
|
32757
|
+
} else {
|
|
32758
|
+
json(payload, `${path}.payload`, issues);
|
|
32759
|
+
}
|
|
32760
|
+
if (!key || !tool || !payload || name === null) {
|
|
32761
|
+
return null;
|
|
32762
|
+
}
|
|
32763
|
+
return {
|
|
32764
|
+
key,
|
|
32765
|
+
tool,
|
|
32766
|
+
...name ? { name } : {},
|
|
32767
|
+
payload
|
|
32768
|
+
};
|
|
32769
|
+
}
|
|
32770
|
+
function issueOrder(left, right) {
|
|
32771
|
+
return left.path.localeCompare(right.path) || left.severity.localeCompare(right.severity) || left.code.localeCompare(right.code);
|
|
32772
|
+
}
|
|
32773
|
+
function lintMonitorBatchInput(value) {
|
|
32774
|
+
const issues = [];
|
|
32775
|
+
const versionlessEnvelope = !Array.isArray(value) && (() => {
|
|
32776
|
+
const candidate = record(value);
|
|
32777
|
+
return candidate !== null && Object.keys(candidate).length === 1 && Object.prototype.hasOwnProperty.call(candidate, "monitors");
|
|
32778
|
+
})();
|
|
32779
|
+
const legacy = Array.isArray(value) || versionlessEnvelope;
|
|
32780
|
+
const input2 = legacy ? null : record(value);
|
|
32781
|
+
let monitors = Array.isArray(value) ? value : versionlessEnvelope ? (() => {
|
|
32782
|
+
const candidate = record(value)?.monitors;
|
|
32783
|
+
return Array.isArray(candidate) ? candidate : null;
|
|
32784
|
+
})() : null;
|
|
32785
|
+
if (Array.isArray(value)) {
|
|
32786
|
+
issues.push({
|
|
32787
|
+
severity: "warning",
|
|
32788
|
+
code: "deprecated_batch_array",
|
|
32789
|
+
path: "",
|
|
32790
|
+
message: "Bare monitor arrays are supported for compatibility.",
|
|
32791
|
+
suggestion: 'Wrap the list in {"version":1,"kind":"batch","monitors":[...]}.'
|
|
32792
|
+
});
|
|
32793
|
+
} else if (versionlessEnvelope) {
|
|
32794
|
+
issues.push({
|
|
32795
|
+
severity: "warning",
|
|
32796
|
+
code: "deprecated_batch_missing_envelope_fields",
|
|
32797
|
+
path: "",
|
|
32798
|
+
message: "Versionless monitor envelopes are supported for compatibility.",
|
|
32799
|
+
suggestion: 'Add "version": 1 and "kind": "batch".'
|
|
32800
|
+
});
|
|
32801
|
+
if (!monitors) {
|
|
32802
|
+
issues.push({
|
|
32803
|
+
severity: "error",
|
|
32804
|
+
code: "invalid_batch_monitors",
|
|
32805
|
+
path: "monitors",
|
|
32806
|
+
message: "Batch monitors must be an array."
|
|
32807
|
+
});
|
|
32808
|
+
}
|
|
32809
|
+
} else if (!input2) {
|
|
32810
|
+
issues.push({
|
|
32811
|
+
severity: "error",
|
|
32812
|
+
code: "invalid_batch",
|
|
32813
|
+
path: "",
|
|
32814
|
+
message: "Batch input must be an object or a legacy array."
|
|
32815
|
+
});
|
|
32816
|
+
} else {
|
|
32817
|
+
for (const key of Object.keys(input2)) {
|
|
32818
|
+
if (!["version", "kind", "monitors"].includes(key)) {
|
|
32819
|
+
issues.push({
|
|
32820
|
+
severity: "error",
|
|
32821
|
+
code: key === "source" || key === "monitor" ? "batch_fleet_shape_mixup" : "unknown_batch_field",
|
|
32822
|
+
path: key,
|
|
32823
|
+
message: `Batch input does not accept '${key}'.`
|
|
32824
|
+
});
|
|
32825
|
+
}
|
|
32826
|
+
}
|
|
32827
|
+
if (input2.version !== 1) {
|
|
32828
|
+
issues.push({
|
|
32829
|
+
severity: "error",
|
|
32830
|
+
code: "unsupported_batch_version",
|
|
32831
|
+
path: "version",
|
|
32832
|
+
message: "Batch input version must be 1."
|
|
32833
|
+
});
|
|
32834
|
+
}
|
|
32835
|
+
if (input2.kind !== "batch") {
|
|
32836
|
+
issues.push({
|
|
32837
|
+
severity: "error",
|
|
32838
|
+
code: "invalid_batch_kind",
|
|
32839
|
+
path: "kind",
|
|
32840
|
+
message: 'Batch input kind must be "batch".'
|
|
32841
|
+
});
|
|
32842
|
+
}
|
|
32843
|
+
monitors = Array.isArray(input2.monitors) ? input2.monitors : null;
|
|
32844
|
+
if (!monitors) {
|
|
32845
|
+
issues.push({
|
|
32846
|
+
severity: "error",
|
|
32847
|
+
code: "invalid_batch_monitors",
|
|
32848
|
+
path: "monitors",
|
|
32849
|
+
message: "Batch monitors must be an array."
|
|
32850
|
+
});
|
|
32851
|
+
}
|
|
32852
|
+
}
|
|
32853
|
+
if (!monitors || monitors.length === 0) {
|
|
32854
|
+
if (monitors?.length === 0) {
|
|
32855
|
+
issues.push({
|
|
32856
|
+
severity: "error",
|
|
32857
|
+
code: "empty_batch",
|
|
32858
|
+
path: "monitors",
|
|
32859
|
+
message: "A Batch needs at least one monitor."
|
|
32860
|
+
});
|
|
32861
|
+
}
|
|
32862
|
+
return { issues: issues.sort(issueOrder) };
|
|
32863
|
+
}
|
|
32864
|
+
const normalized = monitors.map(
|
|
32865
|
+
(item, index) => monitorSpec(item, `monitors.${index}`, issues)
|
|
32866
|
+
);
|
|
32867
|
+
const seen = /* @__PURE__ */ new Map();
|
|
32868
|
+
normalized.forEach((item, index) => {
|
|
32869
|
+
if (!item) return;
|
|
32870
|
+
const first = seen.get(item.key);
|
|
32871
|
+
if (first !== void 0) {
|
|
32872
|
+
for (const position of [first, index]) {
|
|
32873
|
+
issues.push({
|
|
32874
|
+
severity: "error",
|
|
32875
|
+
code: "duplicate_monitor_key",
|
|
32876
|
+
path: `monitors.${position}.key`,
|
|
32877
|
+
message: `Duplicate monitor key '${item.key}'.`
|
|
32878
|
+
});
|
|
32879
|
+
}
|
|
32880
|
+
} else {
|
|
32881
|
+
seen.set(item.key, index);
|
|
32882
|
+
}
|
|
32883
|
+
});
|
|
32884
|
+
const ordered = issues.sort(issueOrder);
|
|
32885
|
+
return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : {
|
|
32886
|
+
normalized: {
|
|
32887
|
+
version: 1,
|
|
32888
|
+
kind: "batch",
|
|
32889
|
+
monitors: normalized
|
|
32890
|
+
},
|
|
32891
|
+
issues: ordered
|
|
32892
|
+
};
|
|
32893
|
+
}
|
|
32894
|
+
function validateHandlebars(value, path, issues) {
|
|
32895
|
+
if (!value.includes("{{")) return;
|
|
32896
|
+
try {
|
|
32897
|
+
Handlebars.parse(value);
|
|
32898
|
+
} catch (error) {
|
|
32899
|
+
issues.push({
|
|
32900
|
+
severity: "error",
|
|
32901
|
+
code: "invalid_handlebars_template",
|
|
32902
|
+
path,
|
|
32903
|
+
message: error instanceof Error ? error.message : "Invalid Handlebars template."
|
|
32904
|
+
});
|
|
32905
|
+
return;
|
|
32906
|
+
}
|
|
32907
|
+
const expressions = value.match(/{{[\s\S]*?}}/g) ?? [];
|
|
32908
|
+
if (expressions.some(
|
|
32909
|
+
(expression) => !/^{{\s*[A-Za-z_][A-Za-z0-9_]*\s*}}$/.test(expression)
|
|
32910
|
+
)) {
|
|
32911
|
+
issues.push({
|
|
32912
|
+
severity: "error",
|
|
32913
|
+
code: "unsupported_handlebars_expression",
|
|
32914
|
+
path,
|
|
32915
|
+
message: "Fleet templates allow only direct source-row fields such as {{domain}}; helpers, blocks, partials, paths, and prototype access are disabled."
|
|
32916
|
+
});
|
|
32917
|
+
}
|
|
32918
|
+
}
|
|
32919
|
+
function walkTemplates(value, path, issues) {
|
|
32920
|
+
if (typeof value === "string") return validateHandlebars(value, path, issues);
|
|
32921
|
+
if (Array.isArray(value)) {
|
|
32922
|
+
value.forEach(
|
|
32923
|
+
(item, index) => walkTemplates(item, `${path}.${index}`, issues)
|
|
32924
|
+
);
|
|
32925
|
+
return;
|
|
32926
|
+
}
|
|
32927
|
+
const input2 = record(value);
|
|
32928
|
+
if (!input2) return;
|
|
32929
|
+
for (const [key, child] of Object.entries(input2)) {
|
|
32930
|
+
walkTemplates(child, `${path}.${key}`, issues);
|
|
32931
|
+
}
|
|
32932
|
+
}
|
|
32933
|
+
function lintMonitorSpecTemplate(value, path = "monitor") {
|
|
32934
|
+
const issues = [];
|
|
32935
|
+
const normalized = monitorSpec(value, path, issues);
|
|
32936
|
+
const input2 = record(value);
|
|
32937
|
+
if (input2 && typeof input2.tool === "string" && input2.tool.includes("{{")) {
|
|
32938
|
+
issues.push({
|
|
32939
|
+
severity: "error",
|
|
32940
|
+
code: "templated_monitor_tool",
|
|
32941
|
+
path: `${path}.tool`,
|
|
32942
|
+
message: "Fleet monitor tool must be literal; only key, name, and payload may be templated."
|
|
32943
|
+
});
|
|
32944
|
+
}
|
|
32945
|
+
if (input2) {
|
|
32946
|
+
for (const field of ["key", "name", "payload"]) {
|
|
32947
|
+
if (input2[field] !== void 0)
|
|
32948
|
+
walkTemplates(input2[field], `${path}.${field}`, issues);
|
|
32949
|
+
}
|
|
32950
|
+
}
|
|
32951
|
+
const ordered = issues.sort(issueOrder);
|
|
32952
|
+
return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : { normalized, issues: ordered };
|
|
32953
|
+
}
|
|
32954
|
+
|
|
32559
32955
|
// ../integration-contracts/monitor-fleet-contract.ts
|
|
32560
32956
|
var MONITOR_FLEET_MAX_MEMBERS = 1e3;
|
|
32561
|
-
var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
|
|
32562
32957
|
var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
|
|
32563
|
-
|
|
32958
|
+
1,
|
|
32959
|
+
2
|
|
32564
32960
|
];
|
|
32565
32961
|
var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
|
|
32566
32962
|
var MONITOR_FLEET_DOCUMENTATION = {
|
|
@@ -32568,11 +32964,11 @@ var MONITOR_FLEET_DOCUMENTATION = {
|
|
|
32568
32964
|
authoredFields: {
|
|
32569
32965
|
id: "Stable lowercase fleet id used by sync, get, and deactivate.",
|
|
32570
32966
|
source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
|
|
32571
|
-
|
|
32967
|
+
monitor: "One Batch-compatible MonitorSpec. Direct Handlebars source-row fields such as {{domain}} are rendered for each selected row.",
|
|
32572
32968
|
selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
|
|
32573
32969
|
},
|
|
32574
32970
|
fixedPolicy: {
|
|
32575
|
-
cadence: "
|
|
32971
|
+
cadence: "60s fair bounded source refresh",
|
|
32576
32972
|
membership: "sticky",
|
|
32577
32973
|
removalGrace: "7d",
|
|
32578
32974
|
onRemoved: "deactivate",
|
|
@@ -32580,9 +32976,10 @@ var MONITOR_FLEET_DOCUMENTATION = {
|
|
|
32580
32976
|
billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
|
|
32581
32977
|
},
|
|
32582
32978
|
stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
|
|
32583
|
-
|
|
32979
|
+
templating: "Use direct Handlebars fields such as {{domain}} in monitor key, name, or payload. Helpers, blocks, partials, paths, and prototype access are disabled.",
|
|
32980
|
+
legacyCompatibility: 'Edition 1 member/$fleet files remain readable with a lint warning; new files should use version: 2, kind: "fleet", and monitor.'
|
|
32584
32981
|
};
|
|
32585
|
-
function
|
|
32982
|
+
function record2(value) {
|
|
32586
32983
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
32587
32984
|
}
|
|
32588
32985
|
function identifier(value) {
|
|
@@ -32607,7 +33004,7 @@ function jsonValue(value, path, issues) {
|
|
|
32607
33004
|
value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
|
|
32608
33005
|
return;
|
|
32609
33006
|
}
|
|
32610
|
-
const input2 =
|
|
33007
|
+
const input2 = record2(value);
|
|
32611
33008
|
if (!input2) {
|
|
32612
33009
|
issues.push({
|
|
32613
33010
|
path,
|
|
@@ -32621,7 +33018,7 @@ function jsonValue(value, path, issues) {
|
|
|
32621
33018
|
}
|
|
32622
33019
|
}
|
|
32623
33020
|
function validateExpression(value, path, issues) {
|
|
32624
|
-
const input2 =
|
|
33021
|
+
const input2 = record2(value);
|
|
32625
33022
|
if (!input2 || input2.$fleet !== "column" || !identifier(input2.name)) {
|
|
32626
33023
|
issues.push({
|
|
32627
33024
|
path,
|
|
@@ -32639,7 +33036,7 @@ function walkPayload(value, path, issues) {
|
|
|
32639
33036
|
);
|
|
32640
33037
|
return;
|
|
32641
33038
|
}
|
|
32642
|
-
const input2 =
|
|
33039
|
+
const input2 = record2(value);
|
|
32643
33040
|
if (!input2) return;
|
|
32644
33041
|
if ("$fleet" in input2) {
|
|
32645
33042
|
validateExpression(input2, path, issues);
|
|
@@ -32649,9 +33046,9 @@ function walkPayload(value, path, issues) {
|
|
|
32649
33046
|
walkPayload(item, `${path}.${key}`, issues);
|
|
32650
33047
|
}
|
|
32651
33048
|
}
|
|
32652
|
-
function
|
|
33049
|
+
function validateMonitorFleetDefinitionV1(value) {
|
|
32653
33050
|
const issues = [];
|
|
32654
|
-
const input2 =
|
|
33051
|
+
const input2 = record2(value);
|
|
32655
33052
|
if (!input2) {
|
|
32656
33053
|
return {
|
|
32657
33054
|
valid: false,
|
|
@@ -32672,7 +33069,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32672
33069
|
message: "Fleet id must be lowercase kebab-case."
|
|
32673
33070
|
});
|
|
32674
33071
|
}
|
|
32675
|
-
const source =
|
|
33072
|
+
const source = record2(input2.source);
|
|
32676
33073
|
exactKeys(
|
|
32677
33074
|
source,
|
|
32678
33075
|
["kind", "schema", "table", "key", "where"],
|
|
@@ -32693,7 +33090,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32693
33090
|
message: "Source schema and table must be SQL identifiers."
|
|
32694
33091
|
});
|
|
32695
33092
|
}
|
|
32696
|
-
const sourceKey =
|
|
33093
|
+
const sourceKey = record2(source?.key);
|
|
32697
33094
|
exactKeys(sourceKey, ["column", "type"], "source.key", issues);
|
|
32698
33095
|
if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
|
|
32699
33096
|
issues.push({
|
|
@@ -32703,7 +33100,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32703
33100
|
});
|
|
32704
33101
|
}
|
|
32705
33102
|
if (source?.where !== void 0) {
|
|
32706
|
-
const where =
|
|
33103
|
+
const where = record2(source.where);
|
|
32707
33104
|
if (!where) {
|
|
32708
33105
|
issues.push({
|
|
32709
33106
|
path: "source.where",
|
|
@@ -32729,9 +33126,9 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32729
33126
|
}
|
|
32730
33127
|
}
|
|
32731
33128
|
}
|
|
32732
|
-
const member =
|
|
33129
|
+
const member = record2(input2.member);
|
|
32733
33130
|
exactKeys(member, ["tool", "key", "payload"], "member", issues);
|
|
32734
|
-
const key =
|
|
33131
|
+
const key = record2(member?.key);
|
|
32735
33132
|
if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
|
|
32736
33133
|
issues.push({
|
|
32737
33134
|
path: "member.tool",
|
|
@@ -32752,7 +33149,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32752
33149
|
validateExpression(part, `member.key.parts.${index}`, issues);
|
|
32753
33150
|
}
|
|
32754
33151
|
if (sourceKey && !key.parts.some(
|
|
32755
|
-
(part) =>
|
|
33152
|
+
(part) => record2(part)?.$fleet === "column" && record2(part)?.name === sourceKey.column
|
|
32756
33153
|
)) {
|
|
32757
33154
|
issues.push({
|
|
32758
33155
|
path: "member.key.parts",
|
|
@@ -32771,7 +33168,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32771
33168
|
jsonValue(member.payload, "member.payload", issues);
|
|
32772
33169
|
}
|
|
32773
33170
|
walkPayload(member?.payload, "member.payload", issues);
|
|
32774
|
-
const selection =
|
|
33171
|
+
const selection = record2(input2.selection);
|
|
32775
33172
|
exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
|
|
32776
33173
|
if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
|
|
32777
33174
|
issues.push({
|
|
@@ -32797,7 +33194,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32797
33194
|
} else {
|
|
32798
33195
|
const orderColumns = /* @__PURE__ */ new Set();
|
|
32799
33196
|
for (const [index, order] of orderBy.entries()) {
|
|
32800
|
-
const item =
|
|
33197
|
+
const item = record2(order);
|
|
32801
33198
|
exactKeys(
|
|
32802
33199
|
item,
|
|
32803
33200
|
["column", "direction"],
|
|
@@ -32820,7 +33217,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32820
33217
|
orderColumns.add(item.column);
|
|
32821
33218
|
}
|
|
32822
33219
|
}
|
|
32823
|
-
if (sourceKey &&
|
|
33220
|
+
if (sourceKey && record2(orderBy.at(-1))?.column !== sourceKey.column) {
|
|
32824
33221
|
issues.push({
|
|
32825
33222
|
path: "selection.orderBy",
|
|
32826
33223
|
code: "fleet_order_missing_key",
|
|
@@ -32839,9 +33236,100 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32839
33236
|
}
|
|
32840
33237
|
return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
|
|
32841
33238
|
}
|
|
32842
|
-
function
|
|
33239
|
+
function v2Issue(issue) {
|
|
33240
|
+
return { path: issue.path, code: issue.code, message: issue.message };
|
|
33241
|
+
}
|
|
33242
|
+
function validateMonitorFleetDefinitionV2(value) {
|
|
33243
|
+
const issues = [];
|
|
33244
|
+
const input2 = record2(value);
|
|
33245
|
+
if (!input2) {
|
|
33246
|
+
return {
|
|
33247
|
+
valid: false,
|
|
33248
|
+
issues: [
|
|
33249
|
+
{
|
|
33250
|
+
path: "",
|
|
33251
|
+
code: "invalid_fleet",
|
|
33252
|
+
message: "Fleet must be an object."
|
|
33253
|
+
}
|
|
33254
|
+
]
|
|
33255
|
+
};
|
|
33256
|
+
}
|
|
33257
|
+
exactKeys(
|
|
33258
|
+
input2,
|
|
33259
|
+
["version", "kind", "id", "source", "monitor", "selection"],
|
|
33260
|
+
"",
|
|
33261
|
+
issues
|
|
33262
|
+
);
|
|
33263
|
+
if (input2.version !== 2) {
|
|
33264
|
+
issues.push({
|
|
33265
|
+
path: "version",
|
|
33266
|
+
code: "unsupported_fleet_version",
|
|
33267
|
+
message: "Canonical Fleet input version must be 2."
|
|
33268
|
+
});
|
|
33269
|
+
}
|
|
33270
|
+
if (input2.kind !== "fleet") {
|
|
33271
|
+
issues.push({
|
|
33272
|
+
path: "kind",
|
|
33273
|
+
code: "invalid_fleet_kind",
|
|
33274
|
+
message: 'Canonical Fleet input kind must be "fleet".'
|
|
33275
|
+
});
|
|
33276
|
+
}
|
|
33277
|
+
const source = record2(input2.source);
|
|
33278
|
+
const sourceKey = record2(source?.key);
|
|
33279
|
+
const legacyShape = {
|
|
33280
|
+
id: input2.id,
|
|
33281
|
+
source: input2.source,
|
|
33282
|
+
member: {
|
|
33283
|
+
tool: record2(input2.monitor)?.tool,
|
|
33284
|
+
key: {
|
|
33285
|
+
$fleet: "template",
|
|
33286
|
+
parts: [
|
|
33287
|
+
"fleet-",
|
|
33288
|
+
{
|
|
33289
|
+
$fleet: "column",
|
|
33290
|
+
name: typeof sourceKey?.column === "string" ? sourceKey.column : "invalid_source_key"
|
|
33291
|
+
}
|
|
33292
|
+
]
|
|
33293
|
+
},
|
|
33294
|
+
payload: record2(input2.monitor)?.payload
|
|
33295
|
+
},
|
|
33296
|
+
selection: input2.selection
|
|
33297
|
+
};
|
|
33298
|
+
const legacyCheck = validateMonitorFleetDefinitionV1(legacyShape);
|
|
33299
|
+
for (const issue of legacyCheck.issues) {
|
|
33300
|
+
issues.push({
|
|
33301
|
+
...issue,
|
|
33302
|
+
path: issue.path.replace(/^member\./, "monitor.")
|
|
33303
|
+
});
|
|
33304
|
+
}
|
|
33305
|
+
const monitorInput = record2(input2.monitor);
|
|
33306
|
+
const monitorKey = monitorInput?.key;
|
|
33307
|
+
const monitor = lintMonitorSpecTemplate(input2.monitor);
|
|
33308
|
+
issues.push(...monitor.issues.map(v2Issue));
|
|
33309
|
+
if (typeof monitorKey === "string" && typeof sourceKey?.column === "string" && !monitorKey.includes(`{{${sourceKey.column}}}`)) {
|
|
33310
|
+
issues.push({
|
|
33311
|
+
path: "monitor.key",
|
|
33312
|
+
code: "fleet_key_missing_source_key",
|
|
33313
|
+
message: "Monitor key must include the source key as a direct Handlebars expression."
|
|
33314
|
+
});
|
|
33315
|
+
}
|
|
33316
|
+
return issues.length === 0 && monitor.normalized ? {
|
|
33317
|
+
valid: true,
|
|
33318
|
+
definition: {
|
|
33319
|
+
version: 2,
|
|
33320
|
+
kind: "fleet",
|
|
33321
|
+
id: String(input2.id),
|
|
33322
|
+
source: input2.source,
|
|
33323
|
+
monitor: monitor.normalized,
|
|
33324
|
+
selection: input2.selection
|
|
33325
|
+
},
|
|
33326
|
+
issues
|
|
33327
|
+
} : { valid: false, issues };
|
|
33328
|
+
}
|
|
33329
|
+
function admitMonitorFleetAuthoringContract(value, edition) {
|
|
33330
|
+
const detectedEdition = edition ?? (record2(value)?.version === 2 || record2(value)?.kind === "fleet" ? 2 : 1);
|
|
32843
33331
|
if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
|
|
32844
|
-
|
|
33332
|
+
detectedEdition
|
|
32845
33333
|
)) {
|
|
32846
33334
|
return {
|
|
32847
33335
|
valid: false,
|
|
@@ -32849,16 +33337,16 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
|
|
|
32849
33337
|
{
|
|
32850
33338
|
path: "authoring_contract_edition",
|
|
32851
33339
|
code: "unsupported_fleet_authoring_contract_edition",
|
|
32852
|
-
message: `Monitor Fleet authoring contract edition ${
|
|
33340
|
+
message: `Monitor Fleet authoring contract edition ${detectedEdition} is not supported.`
|
|
32853
33341
|
}
|
|
32854
33342
|
]
|
|
32855
33343
|
};
|
|
32856
33344
|
}
|
|
32857
|
-
const result =
|
|
33345
|
+
const result = detectedEdition === 2 ? validateMonitorFleetDefinitionV2(value) : validateMonitorFleetDefinitionV1(value);
|
|
32858
33346
|
return result.valid && result.definition ? {
|
|
32859
33347
|
valid: true,
|
|
32860
33348
|
contract: {
|
|
32861
|
-
edition,
|
|
33349
|
+
edition: detectedEdition,
|
|
32862
33350
|
// JSON cloning prevents later caller mutation from changing the
|
|
32863
33351
|
// admitted snapshot.
|
|
32864
33352
|
definition: JSON.parse(
|
|
@@ -32868,6 +33356,32 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
|
|
|
32868
33356
|
issues: []
|
|
32869
33357
|
} : { valid: false, issues: result.issues };
|
|
32870
33358
|
}
|
|
33359
|
+
function lintMonitorFleetInput(value) {
|
|
33360
|
+
const input2 = record2(value);
|
|
33361
|
+
const legacy = input2?.member !== void 0;
|
|
33362
|
+
const admitted = admitMonitorFleetAuthoringContract(value);
|
|
33363
|
+
const issues = admitted.issues.map((issue) => ({
|
|
33364
|
+
...issue,
|
|
33365
|
+
severity: "error"
|
|
33366
|
+
}));
|
|
33367
|
+
if (legacy) {
|
|
33368
|
+
issues.push({
|
|
33369
|
+
severity: "warning",
|
|
33370
|
+
code: "deprecated_fleet_member",
|
|
33371
|
+
path: "member",
|
|
33372
|
+
message: "Legacy Fleet member syntax remains supported."
|
|
33373
|
+
});
|
|
33374
|
+
if (JSON.stringify(input2).includes('"$fleet"')) {
|
|
33375
|
+
issues.push({
|
|
33376
|
+
severity: "warning",
|
|
33377
|
+
code: "deprecated_fleet_expression",
|
|
33378
|
+
path: "member",
|
|
33379
|
+
message: "Legacy $fleet expressions remain supported; use direct Handlebars fields in monitor instead."
|
|
33380
|
+
});
|
|
33381
|
+
}
|
|
33382
|
+
}
|
|
33383
|
+
return admitted.valid && admitted.contract ? { normalized: admitted.contract.definition, issues } : { issues };
|
|
33384
|
+
}
|
|
32871
33385
|
|
|
32872
33386
|
// src/cli/commands/monitors.ts
|
|
32873
33387
|
var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
|
|
@@ -33553,6 +34067,155 @@ function fleetIdempotencyKey(operation, supplied) {
|
|
|
33553
34067
|
}
|
|
33554
34068
|
return normalized ?? `monitor-fleet-${operation}-${randomUUID5()}`;
|
|
33555
34069
|
}
|
|
34070
|
+
function monitorJobIdempotencyKey(operation, supplied) {
|
|
34071
|
+
const normalized = supplied?.trim();
|
|
34072
|
+
if (supplied !== void 0 && !normalized) {
|
|
34073
|
+
throw new MonitorsUsageError("--idempotency-key must not be empty.");
|
|
34074
|
+
}
|
|
34075
|
+
return normalized ?? `monitor-job-${operation}-${randomUUID5()}`;
|
|
34076
|
+
}
|
|
34077
|
+
function readMonitorDefinitionsJsonFile(file) {
|
|
34078
|
+
let raw;
|
|
34079
|
+
try {
|
|
34080
|
+
raw = file === "-" ? readFileSync11(0, "utf8") : readFileSync11(file, "utf8");
|
|
34081
|
+
} catch (error) {
|
|
34082
|
+
throw new MonitorsUsageError(
|
|
34083
|
+
`Could not read --file ${file}: ${error instanceof Error ? error.message : String(error)}`
|
|
34084
|
+
);
|
|
34085
|
+
}
|
|
34086
|
+
try {
|
|
34087
|
+
return JSON.parse(raw);
|
|
34088
|
+
} catch (error) {
|
|
34089
|
+
throw new MonitorsUsageError(
|
|
34090
|
+
`Monitor definitions must be valid JSON. ${error instanceof Error ? error.message : String(error)}`
|
|
34091
|
+
);
|
|
34092
|
+
}
|
|
34093
|
+
}
|
|
34094
|
+
function renderMonitorJob(payload) {
|
|
34095
|
+
const job = asRecord2(payload.job);
|
|
34096
|
+
if (!job) return void 0;
|
|
34097
|
+
const id = asString(job.id) ?? "<unknown>";
|
|
34098
|
+
const state = asString(job.state) ?? "unknown";
|
|
34099
|
+
const phase = asString(job.phase);
|
|
34100
|
+
const counts = asRecord2(job.counts);
|
|
34101
|
+
const reconciliation = asRecord2(job.reconciliation);
|
|
34102
|
+
const lines = [
|
|
34103
|
+
`Monitor job: ${id}`,
|
|
34104
|
+
`State: ${state}${phase ? ` (${phase})` : ""}`
|
|
34105
|
+
];
|
|
34106
|
+
if (counts) {
|
|
34107
|
+
lines.push(
|
|
34108
|
+
`Counts: requested ${asFiniteNumber(counts.requested) ?? 0}, created ${asFiniteNumber(counts.created) ?? 0}, unchanged ${asFiniteNumber(counts.unchanged) ?? 0}, verified ${asFiniteNumber(counts.verified) ?? 0}, failed ${asFiniteNumber(counts.failed) ?? 0}`
|
|
34109
|
+
);
|
|
34110
|
+
}
|
|
34111
|
+
if (reconciliation) {
|
|
34112
|
+
lines.push(
|
|
34113
|
+
`Reconciliation: ${asString(reconciliation.state) ?? "pending"} (${asFiniteNumber(reconciliation.observed_bindings) ?? 0}/${asFiniteNumber(reconciliation.expected_bindings) ?? 0} bindings observed)`
|
|
34114
|
+
);
|
|
34115
|
+
}
|
|
34116
|
+
const next = asString(payload.next);
|
|
34117
|
+
if (next) lines.push(`Next: ${next}`);
|
|
34118
|
+
return `${lines.join("\n")}
|
|
34119
|
+
`;
|
|
34120
|
+
}
|
|
34121
|
+
async function handleMonitorJobBatchDeploy(options, idempotencyKey) {
|
|
34122
|
+
if (!options.file) {
|
|
34123
|
+
throw new MonitorsUsageError(
|
|
34124
|
+
"A Batch file is required. Pass --file batch.json (or --file - for stdin)."
|
|
34125
|
+
);
|
|
34126
|
+
}
|
|
34127
|
+
const lint = lintMonitorBatchInput(
|
|
34128
|
+
readMonitorDefinitionsJsonFile(options.file)
|
|
34129
|
+
);
|
|
34130
|
+
if (!lint.normalized) {
|
|
34131
|
+
throw new MonitorsUsageError(
|
|
34132
|
+
lint.issues.filter((issue) => issue.severity === "error").map((issue) => `${issue.path || "batch"}: ${issue.message}`).join("; ")
|
|
34133
|
+
);
|
|
34134
|
+
}
|
|
34135
|
+
const payload = await new DeeplineClient().monitors.batch.deploy(
|
|
34136
|
+
lint.normalized.monitors,
|
|
34137
|
+
{ idempotencyKey }
|
|
34138
|
+
);
|
|
34139
|
+
printCommandEnvelope(
|
|
34140
|
+
{
|
|
34141
|
+
...payload,
|
|
34142
|
+
idempotency_key: idempotencyKey,
|
|
34143
|
+
...lint.issues.length ? { lint: { issues: lint.issues } } : {}
|
|
34144
|
+
},
|
|
34145
|
+
{ json: options.json, text: renderMonitorJob(payload) }
|
|
34146
|
+
);
|
|
34147
|
+
}
|
|
34148
|
+
async function handleMonitorBatchLint(options) {
|
|
34149
|
+
if (!options.file) {
|
|
34150
|
+
throw new MonitorsUsageError(
|
|
34151
|
+
"monitors batch lint requires --file <batch.json>."
|
|
34152
|
+
);
|
|
34153
|
+
}
|
|
34154
|
+
const result = lintMonitorBatchInput(
|
|
34155
|
+
readMonitorDefinitionsJsonFile(options.file)
|
|
34156
|
+
);
|
|
34157
|
+
printCommandEnvelope(
|
|
34158
|
+
{
|
|
34159
|
+
ok: !result.issues.some((issue) => issue.severity === "error"),
|
|
34160
|
+
...result.normalized ? { normalized: result.normalized } : {},
|
|
34161
|
+
issues: result.issues
|
|
34162
|
+
},
|
|
34163
|
+
{ json: options.json }
|
|
34164
|
+
);
|
|
34165
|
+
if (result.issues.some((issue) => issue.severity === "error"))
|
|
34166
|
+
process.exitCode = 2;
|
|
34167
|
+
}
|
|
34168
|
+
async function handleMonitorFleetLint(options) {
|
|
34169
|
+
if (!options.file) {
|
|
34170
|
+
throw new MonitorsUsageError(
|
|
34171
|
+
"monitors fleets lint requires --file <fleet.json>."
|
|
34172
|
+
);
|
|
34173
|
+
}
|
|
34174
|
+
const result = lintMonitorFleetInput(
|
|
34175
|
+
readMonitorDefinitionsJsonFile(options.file)
|
|
34176
|
+
);
|
|
34177
|
+
printCommandEnvelope(
|
|
34178
|
+
{
|
|
34179
|
+
ok: !result.issues.some((issue) => issue.severity === "error"),
|
|
34180
|
+
...result.normalized ? { normalized: result.normalized } : {},
|
|
34181
|
+
issues: result.issues
|
|
34182
|
+
},
|
|
34183
|
+
{ json: options.json }
|
|
34184
|
+
);
|
|
34185
|
+
if (result.issues.some((issue) => issue.severity === "error"))
|
|
34186
|
+
process.exitCode = 2;
|
|
34187
|
+
}
|
|
34188
|
+
async function handleMonitorJobGet(jobId, options) {
|
|
34189
|
+
const payload = await new DeeplineClient().monitors.jobs.get(jobId);
|
|
34190
|
+
printCommandEnvelope(payload, {
|
|
34191
|
+
json: options.json,
|
|
34192
|
+
text: renderMonitorJob(payload)
|
|
34193
|
+
});
|
|
34194
|
+
}
|
|
34195
|
+
async function handleMonitorJobWait(jobId, options) {
|
|
34196
|
+
const payload = await new DeeplineClient().monitors.jobs.wait(jobId, {
|
|
34197
|
+
timeoutMs: fleetTimeoutMs(options.timeout),
|
|
34198
|
+
pollIntervalMs: FLEET_POLL_INTERVAL_MS
|
|
34199
|
+
});
|
|
34200
|
+
printCommandEnvelope(payload, {
|
|
34201
|
+
json: options.json,
|
|
34202
|
+
text: renderMonitorJob(payload)
|
|
34203
|
+
});
|
|
34204
|
+
}
|
|
34205
|
+
async function handleMonitorJobLogs(jobId, options) {
|
|
34206
|
+
const limit = options.limit ? fleetIntegerOption(options.limit, "--limit") : void 0;
|
|
34207
|
+
const payload = await new DeeplineClient().monitors.jobs.logs(jobId, {
|
|
34208
|
+
...limit === void 0 ? {} : { limit }
|
|
34209
|
+
});
|
|
34210
|
+
printCommandEnvelope(payload, { json: options.json });
|
|
34211
|
+
}
|
|
34212
|
+
async function handleMonitorJobCancel(jobId, options) {
|
|
34213
|
+
const payload = await new DeeplineClient().monitors.jobs.cancel(jobId);
|
|
34214
|
+
printCommandEnvelope(payload, {
|
|
34215
|
+
json: options.json,
|
|
34216
|
+
text: renderMonitorJob(payload)
|
|
34217
|
+
});
|
|
34218
|
+
}
|
|
33556
34219
|
var FLEET_COUNT_KEYS = [
|
|
33557
34220
|
"pending",
|
|
33558
34221
|
"submitting",
|
|
@@ -33574,12 +34237,12 @@ var MONITOR_FLEET_LIFECYCLE = [
|
|
|
33574
34237
|
{
|
|
33575
34238
|
step: 2,
|
|
33576
34239
|
what: "See the plan and the credits before anything changes.",
|
|
33577
|
-
command: "deepline monitors fleets
|
|
34240
|
+
command: "deepline monitors fleets deploy --file fleet.json --dry-run"
|
|
33578
34241
|
},
|
|
33579
34242
|
{
|
|
33580
34243
|
step: 3,
|
|
33581
34244
|
what: "Apply it and wait for the server to call it converged.",
|
|
33582
|
-
command: "deepline monitors fleets
|
|
34245
|
+
command: "deepline monitors fleets deploy --file fleet.json --wait"
|
|
33583
34246
|
},
|
|
33584
34247
|
{
|
|
33585
34248
|
step: 4,
|
|
@@ -33588,6 +34251,11 @@ var MONITOR_FLEET_LIFECYCLE = [
|
|
|
33588
34251
|
}
|
|
33589
34252
|
];
|
|
33590
34253
|
var MONITOR_FLEET_COMMANDS = [
|
|
34254
|
+
{
|
|
34255
|
+
name: "deploy",
|
|
34256
|
+
summary: "Create or update one table-backed Fleet from Customer DB rows."
|
|
34257
|
+
},
|
|
34258
|
+
{ name: "lint", summary: "Validate and normalize Fleet JSON locally." },
|
|
33591
34259
|
{ name: "init", summary: "Write a Fleet definition JSON file." },
|
|
33592
34260
|
{
|
|
33593
34261
|
name: "sync",
|
|
@@ -33733,6 +34401,26 @@ function renderFleetGet(payload) {
|
|
|
33733
34401
|
` counts ${fleetCountsLine(payload)}`,
|
|
33734
34402
|
` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 converged generation ${asFiniteNumber(payload.converged_generation) ?? "none"}`
|
|
33735
34403
|
];
|
|
34404
|
+
const boundPlays = Array.isArray(payload.bound_plays) ? payload.bound_plays.flatMap((value) => {
|
|
34405
|
+
const play = asRecord2(value);
|
|
34406
|
+
return play ? [play] : [];
|
|
34407
|
+
}) : [];
|
|
34408
|
+
lines.push("", `Observed Play bindings (${boundPlays.length}):`);
|
|
34409
|
+
if (boundPlays.length === 0) {
|
|
34410
|
+
lines.push(" none");
|
|
34411
|
+
} else {
|
|
34412
|
+
for (const play of boundPlays) {
|
|
34413
|
+
const name = asString(play.name) ?? "unnamed Play";
|
|
34414
|
+
const listeners = asFiniteNumber(play.listener_count) ?? 0;
|
|
34415
|
+
const status2 = asString(play.status);
|
|
34416
|
+
lines.push(
|
|
34417
|
+
` ${name}${listeners ? ` (${listeners} listener${listeners === 1 ? "" : "s"})` : ""}${status2 ? ` \u2014 ${status2}` : ""}`
|
|
34418
|
+
);
|
|
34419
|
+
}
|
|
34420
|
+
}
|
|
34421
|
+
lines.push(
|
|
34422
|
+
" Read-only observation. Define or change bindings in the Play with sqlListeners."
|
|
34423
|
+
);
|
|
33736
34424
|
lines.push(...renderFleetDriftRows(payload));
|
|
33737
34425
|
const next = fleetServerNext(payload) ?? (status === "degraded" ? `deepline monitors fleets get ${fleetShellArg(id)} --drift` : void 0);
|
|
33738
34426
|
if (next) lines.push(`Next: ${next}`);
|
|
@@ -33909,6 +34597,8 @@ async function handleMonitorFleetsInit(fleetId, options) {
|
|
|
33909
34597
|
const out = options.out?.trim();
|
|
33910
34598
|
if (!out) throw new MonitorsUsageError("--out is required.");
|
|
33911
34599
|
const authoredDefinition = {
|
|
34600
|
+
version: 2,
|
|
34601
|
+
kind: "fleet",
|
|
33912
34602
|
id: fleetId,
|
|
33913
34603
|
source: {
|
|
33914
34604
|
kind: "customer_db_table",
|
|
@@ -33917,12 +34607,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
|
|
|
33917
34607
|
key: { column: key, type: keyType },
|
|
33918
34608
|
...where ? { where } : {}
|
|
33919
34609
|
},
|
|
33920
|
-
|
|
34610
|
+
monitor: {
|
|
33921
34611
|
tool,
|
|
33922
|
-
key: {
|
|
33923
|
-
$fleet: "template",
|
|
33924
|
-
parts: [`${fleetId}-`, { $fleet: "column", name: key }]
|
|
33925
|
-
},
|
|
34612
|
+
key: `${fleetId}-{{${key}}}`,
|
|
33926
34613
|
payload
|
|
33927
34614
|
},
|
|
33928
34615
|
selection: {
|
|
@@ -33935,9 +34622,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
|
|
|
33935
34622
|
const file = resolve14(out);
|
|
33936
34623
|
writeFileSync12(file, `${JSON.stringify(definition, null, 2)}
|
|
33937
34624
|
`, "utf8");
|
|
33938
|
-
const next = `deepline monitors fleets
|
|
34625
|
+
const next = `deepline monitors fleets deploy --file ${fleetShellArg(file)} --dry-run --json`;
|
|
33939
34626
|
printCommandEnvelope(
|
|
33940
|
-
{ schemaVersion:
|
|
34627
|
+
{ schemaVersion: 2, file, definition, next },
|
|
33941
34628
|
{
|
|
33942
34629
|
json: options.json,
|
|
33943
34630
|
text: `Wrote ${file}
|
|
@@ -33947,8 +34634,8 @@ Next: ${next}
|
|
|
33947
34634
|
);
|
|
33948
34635
|
}
|
|
33949
34636
|
function requireCompiledFleetDefinition(definition) {
|
|
33950
|
-
const result =
|
|
33951
|
-
if (result.
|
|
34637
|
+
const result = lintMonitorFleetInput(definition);
|
|
34638
|
+
if (result.normalized) return result.normalized;
|
|
33952
34639
|
const messages = result.issues.map((issue) => `${issue.path || "definition"}: ${issue.message}`).join("; ");
|
|
33953
34640
|
throw new MonitorsUsageError(
|
|
33954
34641
|
`Monitor Fleet definition failed local contract check. ${messages}
|
|
@@ -33975,6 +34662,7 @@ function fleetSyncCommandLine(target, options) {
|
|
|
33975
34662
|
return parts.join(" ");
|
|
33976
34663
|
}
|
|
33977
34664
|
async function handleMonitorFleetsSync(target, options, idempotencyKey) {
|
|
34665
|
+
const fileDefinitions = options.file ? readMonitorDefinitionsJsonFile(options.file) : void 0;
|
|
33978
34666
|
const usesDefinition = options.file !== void 0 || target?.trim().startsWith("{") === true;
|
|
33979
34667
|
if (!usesDefinition && !target?.trim()) {
|
|
33980
34668
|
throw new MonitorsUsageError(
|
|
@@ -33982,12 +34670,14 @@ async function handleMonitorFleetsSync(target, options, idempotencyKey) {
|
|
|
33982
34670
|
);
|
|
33983
34671
|
}
|
|
33984
34672
|
const definition = usesDefinition ? requireCompiledFleetDefinition(
|
|
33985
|
-
|
|
33986
|
-
|
|
33987
|
-
|
|
33988
|
-
|
|
33989
|
-
|
|
33990
|
-
|
|
34673
|
+
asRecord2(
|
|
34674
|
+
fileDefinitions ?? resolveMonitorJsonBody({
|
|
34675
|
+
positional: target,
|
|
34676
|
+
file: options.file,
|
|
34677
|
+
argLabel: "<definition>",
|
|
34678
|
+
command: "deepline monitors fleets sync"
|
|
34679
|
+
})
|
|
34680
|
+
) ?? {}
|
|
33991
34681
|
) : void 0;
|
|
33992
34682
|
const fleetId = definition ? asString(definition.id) ?? "" : target.trim();
|
|
33993
34683
|
if (!fleetId) {
|
|
@@ -34388,14 +35078,14 @@ function renderMonitorGet(payload) {
|
|
|
34388
35078
|
` deepline monitors test ${key} '${JSON.stringify(samplePayload2)}' --json`
|
|
34389
35079
|
);
|
|
34390
35080
|
}
|
|
34391
|
-
const
|
|
34392
|
-
if (
|
|
35081
|
+
const monitorSpec2 = asRecord2(payload.monitor_spec);
|
|
35082
|
+
if (monitorSpec2?.available === false) {
|
|
34393
35083
|
lines.push(
|
|
34394
35084
|
"",
|
|
34395
|
-
`Monitor spec: unavailable \u2014 ${asString(
|
|
35085
|
+
`Monitor spec: unavailable \u2014 ${asString(monitorSpec2.message) ?? "use the stored definition and check before an update."}`
|
|
34396
35086
|
);
|
|
34397
35087
|
}
|
|
34398
|
-
const specFields = Array.isArray(
|
|
35088
|
+
const specFields = Array.isArray(monitorSpec2?.fields) ? monitorSpec2.fields.flatMap((value) => {
|
|
34399
35089
|
const field = asRecord2(value);
|
|
34400
35090
|
const path = asString(field?.path);
|
|
34401
35091
|
const description = asString(field?.description);
|
|
@@ -34869,6 +35559,8 @@ Notes:
|
|
|
34869
35559
|
Deepline monitors are Deepline-native signal feeds: a monitor writes events
|
|
34870
35560
|
into a Customer DB table; a play reacts to each new row via a
|
|
34871
35561
|
sqlListeners trigger \u2014 see \`deepline plays bootstrap monitor-triggered\`.
|
|
35562
|
+
Monitor JSON declares only what to watch (key, tool, optional name, payload).
|
|
35563
|
+
Play bindings belong in the Play; monitor deployment never changes them.
|
|
34872
35564
|
The Monitors rollout controls access to the live provider catalog; use
|
|
34873
35565
|
\`deepline tools list --categories monitors\` for the exact tool ids available to you.
|
|
34874
35566
|
Contact the Deepline team to request access; until access is enabled, these
|
|
@@ -34981,19 +35673,31 @@ Examples:
|
|
|
34981
35673
|
);
|
|
34982
35674
|
withJsonOption(
|
|
34983
35675
|
batch.command("deploy").description(
|
|
34984
|
-
"
|
|
35676
|
+
"Create a Monitor Job from canonical Batch JSON; legacy NDJSON remains available with --yes or --dry-run."
|
|
34985
35677
|
).requiredOption(
|
|
34986
35678
|
"--file <path>",
|
|
34987
|
-
"
|
|
34988
|
-
).option("--dry-run", "
|
|
35679
|
+
'Batch JSON ({"version":1,"kind":"batch","monitors":[...]}), or legacy NDJSON with --yes/--dry-run'
|
|
35680
|
+
).option("--dry-run", "Use the retained legacy batch-operation plan").option("--yes", "Use the retained legacy NDJSON batch operation").option(
|
|
34989
35681
|
"--idempotency-key <key>",
|
|
34990
35682
|
"Stable retry key (generated when omitted)"
|
|
34991
35683
|
)
|
|
34992
35684
|
).action(
|
|
34993
|
-
monitorsAction(
|
|
34994
|
-
(options
|
|
34995
|
-
|
|
35685
|
+
monitorsAction(async (options) => {
|
|
35686
|
+
if (options.dryRun === true || options.yes === true) {
|
|
35687
|
+
return await handleMonitorBatchDeploy(options);
|
|
35688
|
+
}
|
|
35689
|
+
const idempotencyKey = monitorJobIdempotencyKey(
|
|
35690
|
+
"batch-deploy",
|
|
35691
|
+
options.idempotencyKey
|
|
35692
|
+
);
|
|
35693
|
+
return await handleMonitorJobBatchDeploy(options, idempotencyKey);
|
|
35694
|
+
})
|
|
34996
35695
|
);
|
|
35696
|
+
withJsonOption(
|
|
35697
|
+
batch.command("lint").description(
|
|
35698
|
+
"Validate and normalize Batch JSON without network or provider work."
|
|
35699
|
+
).requiredOption("--file <path>", "Batch JSON file, or - for stdin")
|
|
35700
|
+
).action(monitorsAction(handleMonitorBatchLint));
|
|
34997
35701
|
withJsonOption(
|
|
34998
35702
|
batchSelectorOptions(
|
|
34999
35703
|
batch.command("audit").description("Durably audit a selection; defaults to --target all.")
|
|
@@ -35162,9 +35866,8 @@ Examples:
|
|
|
35162
35866
|
"after",
|
|
35163
35867
|
`
|
|
35164
35868
|
Notes:
|
|
35165
|
-
Read-only validation. <definition> is a JSON object with key, tool,
|
|
35166
|
-
and
|
|
35167
|
-
via --file <path>, or
|
|
35869
|
+
Read-only validation. <definition> is a JSON object with key, tool, optional
|
|
35870
|
+
name, and payload. Pass it positionally, via --file <path>, or
|
|
35168
35871
|
from stdin with --file -. Does not deploy or spend credits.
|
|
35169
35872
|
Check validates the local definition only. It does not contact an existing
|
|
35170
35873
|
upstream resource, prove that future events will arrive, or verify downstream
|
|
@@ -35172,12 +35875,8 @@ Notes:
|
|
|
35172
35875
|
Provider-specific grammar, precedence, enum applicability, examples, and
|
|
35173
35876
|
update semantics are returned by the live monitor contract. Inspect it with
|
|
35174
35877
|
\`deepline tools get deepline_native.company_radar --json\`.
|
|
35175
|
-
|
|
35176
|
-
|
|
35177
|
-
do not author custom_fields yourself. Priority is capped at ten upstream or
|
|
35178
|
-
reserved recovery, replacement, or reactivation slots per org. Use
|
|
35179
|
-
\`monitors list --status all\` to find priority holders; it is not for regular
|
|
35180
|
-
or bulk-scale monitoring.
|
|
35878
|
+
Operational controls are Deepline-managed. Bind downstream automation in a
|
|
35879
|
+
Play with sqlListeners; monitor definitions never name Plays.
|
|
35181
35880
|
|
|
35182
35881
|
Examples:
|
|
35183
35882
|
deepline monitors check '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
|
|
@@ -35195,8 +35894,8 @@ Examples:
|
|
|
35195
35894
|
`
|
|
35196
35895
|
Notes:
|
|
35197
35896
|
Mutates workspace state and may spend Deepline credits. <definition> is a JSON
|
|
35198
|
-
object with key, tool,
|
|
35199
|
-
|
|
35897
|
+
object with key, tool, optional name, and payload. Pass it positionally, via
|
|
35898
|
+
--file <path>, or from stdin with --file -.
|
|
35200
35899
|
--dry-run validates the definition and shows the plan (deploy cost in Deepline
|
|
35201
35900
|
credits when the server reports it, plus any existing monitors that may
|
|
35202
35901
|
already cover this scope) WITHOUT deploying. Exits 0 when valid, 7 when not.
|
|
@@ -35213,10 +35912,8 @@ Notes:
|
|
|
35213
35912
|
historical replay request, including when redeploying a disabled monitor.
|
|
35214
35913
|
Deepline preserves that selected boundary; filter-only deploys and ordinary
|
|
35215
35914
|
reactivation start from a fresh future-only source boundary instead.
|
|
35216
|
-
|
|
35217
|
-
|
|
35218
|
-
field and enforces a ten-slot per-org cap; do not use it for regular or bulk
|
|
35219
|
-
monitoring, and do not delete another radar automatically to make room.
|
|
35915
|
+
Operational controls are Deepline-managed. A monitor writes rows; downstream
|
|
35916
|
+
automation belongs in a Play with sqlListeners.
|
|
35220
35917
|
|
|
35221
35918
|
Examples:
|
|
35222
35919
|
deepline monitors deploy '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
|
|
@@ -35247,10 +35944,6 @@ request. Deepline passes that requested boundary upstream, but previously
|
|
|
35247
35944
|
delivered canonical findings are deduplicated before dispatch and billing; only
|
|
35248
35945
|
previously unseen historical findings are chargeable. Filter-only updates,
|
|
35249
35946
|
repair, and reactivation instead use a fresh future-only source boundary.
|
|
35250
|
-
Use {"controls":{"execution_type":"priority"}} only for a bounded urgent
|
|
35251
|
-
Deepline Native preview. The ten-radar priority cap applies on update too.
|
|
35252
|
-
Use {"controls":{"execution_type":null}} to release priority without
|
|
35253
|
-
deleting the monitor.
|
|
35254
35947
|
|
|
35255
35948
|
Examples:
|
|
35256
35949
|
deepline monitors update my-monitor '{"name":"Interested replies"}' --json
|
|
@@ -35298,13 +35991,30 @@ Examples:
|
|
|
35298
35991
|
`
|
|
35299
35992
|
).option("--dry-run", "Show the reactivation cost without reactivating")
|
|
35300
35993
|
).action(monitorsAction(handleMonitorsReactivate));
|
|
35301
|
-
const
|
|
35994
|
+
const jobs = monitors.command("jobs").description("Read, wait for, inspect, or cancel Monitor Jobs.");
|
|
35995
|
+
withJsonOption(jobs);
|
|
35996
|
+
withJsonOption(
|
|
35997
|
+
jobs.command("get <job-id>").description("Read the durable Monitor Job state.")
|
|
35998
|
+
).action(monitorsAction(handleMonitorJobGet));
|
|
35999
|
+
withJsonOption(
|
|
36000
|
+
jobs.command("wait <job-id>").description(
|
|
36001
|
+
"Wait for real provider reconciliation, not request acceptance."
|
|
36002
|
+
).option("--timeout <duration>", "How long to wait (default 10m)")
|
|
36003
|
+
).action(monitorsAction(handleMonitorJobWait));
|
|
36004
|
+
withJsonOption(
|
|
36005
|
+
jobs.command("logs <job-id>").description("Read bounded operator logs for one Monitor Job.").option("--limit <n>", "Maximum log entries (1..200)")
|
|
36006
|
+
).action(monitorsAction(handleMonitorJobLogs));
|
|
36007
|
+
withJsonOption(
|
|
36008
|
+
jobs.command("cancel <job-id>").description("Stop unscheduled work and reconcile the partial result.")
|
|
36009
|
+
).action(monitorsAction(handleMonitorJobCancel));
|
|
36010
|
+
const fleets = monitors.command("fleets").description("Manage table-backed Fleets.").addHelpText(
|
|
35302
36011
|
"after",
|
|
35303
36012
|
`
|
|
35304
36013
|
Notes:
|
|
35305
36014
|
A Monitor Fleet maps eligible rows in one Customer DB table to ordinary
|
|
35306
|
-
monitors. Fleet definitions are canonical JSON, and \`
|
|
35307
|
-
|
|
36015
|
+
monitors. Fleet definitions are canonical JSON, and \`deploy\` applies one;
|
|
36016
|
+
\`sync\` remains its exact compatibility alias. Applying the same definition
|
|
36017
|
+
twice is the same operation,
|
|
35308
36018
|
so the server answers \`replayed: true\` instead of building a second fleet.
|
|
35309
36019
|
The fleet's status is computed by Deepline; this CLI reports it and never
|
|
35310
36020
|
recomputes a verdict from the counts.
|
|
@@ -35326,6 +36036,29 @@ ${MONITOR_FLEET_HELP_EPILOG}`
|
|
|
35326
36036
|
})
|
|
35327
36037
|
);
|
|
35328
36038
|
withJsonOption(fleets);
|
|
36039
|
+
withJsonOption(
|
|
36040
|
+
fleets.command("deploy [fleet-id]").description(
|
|
36041
|
+
"Apply a table-backed Fleet definition; sync remains an exact alias."
|
|
36042
|
+
).option("-f, --file <path>", "Fleet JSON file, or - for stdin").option("--dry-run", "Show the table-backed convergence plan").option("--wait", "Wait for the current Fleet generation to converge").option("--timeout <duration>", "How long --wait may poll (default 10m)").option(
|
|
36043
|
+
"--expected-generation <generation>",
|
|
36044
|
+
"Optimistic generation fence"
|
|
36045
|
+
).option("--idempotency-key <key>", "Stable retry key")
|
|
36046
|
+
).action(
|
|
36047
|
+
monitorsAction(
|
|
36048
|
+
async (fleetId, options) => {
|
|
36049
|
+
const idempotencyKey = fleetIdempotencyKey(
|
|
36050
|
+
"deploy",
|
|
36051
|
+
options.idempotencyKey
|
|
36052
|
+
);
|
|
36053
|
+
await handleMonitorFleetsSync(fleetId, options, idempotencyKey);
|
|
36054
|
+
}
|
|
36055
|
+
)
|
|
36056
|
+
);
|
|
36057
|
+
withJsonOption(
|
|
36058
|
+
fleets.command("lint").description(
|
|
36059
|
+
"Validate and normalize Fleet JSON without network or provider work."
|
|
36060
|
+
).requiredOption("--file <path>", "Fleet JSON file, or - for stdin")
|
|
36061
|
+
).action(monitorsAction(handleMonitorFleetLint));
|
|
35329
36062
|
withJsonOption(
|
|
35330
36063
|
fleets.command("init <fleet-id>").description("Write an opinionated Fleet definition JSON file.").addHelpText(
|
|
35331
36064
|
"after",
|
|
@@ -35339,13 +36072,13 @@ Example:
|
|
|
35339
36072
|
deepline monitors fleets init account-job-openings \\
|
|
35340
36073
|
--source public.accounts --key account_id --key-type uuid \\
|
|
35341
36074
|
--tool deepline_native.company_radar \\
|
|
35342
|
-
--payload '{"domain":{
|
|
36075
|
+
--payload '{"domain":"{{domain}}","radar_type":"company_job_openings"}' \\
|
|
35343
36076
|
--order-by intent_score:desc \\
|
|
35344
36077
|
--out fleet.json
|
|
35345
36078
|
`
|
|
35346
36079
|
).requiredOption("--source <schema.table>", "Customer DB source table").requiredOption("--key <column>", "Unique source-row key column").option("--key-type <type>", "text, uuid, int4, or int8 (default text)").requiredOption("--tool <tool>", "Monitor tool to create per source row").requiredOption(
|
|
35347
36080
|
"--payload <json>",
|
|
35348
|
-
"Monitor payload JSON for --tool; use
|
|
36081
|
+
"Monitor payload JSON for --tool; use Handlebars fields such as {{domain}} for row values"
|
|
35349
36082
|
).option(
|
|
35350
36083
|
"--where <json>",
|
|
35351
36084
|
"Optional source-row equality filter JSON; not arbitrary SQL"
|
|
@@ -35421,7 +36154,9 @@ Examples:
|
|
|
35421
36154
|
Notes:
|
|
35422
36155
|
Status is the server's verdict. --check turns it into an exit code so a
|
|
35423
36156
|
script can branch without parsing output: 0 converged, 6 anything else.
|
|
35424
|
-
--drift lists the members that have not settled and why.
|
|
36157
|
+
--drift lists the members that have not settled and why. The detail also
|
|
36158
|
+
shows the current Plays that observe this Fleet's output; those bindings are
|
|
36159
|
+
read-only here and are defined by each Play's sqlListeners.
|
|
35425
36160
|
|
|
35426
36161
|
Examples:
|
|
35427
36162
|
deepline monitors fleets get --json
|
|
@@ -37549,8 +38284,8 @@ function classifyNetworkFailure(error) {
|
|
|
37549
38284
|
let current = error;
|
|
37550
38285
|
while (current && !seen.has(current)) {
|
|
37551
38286
|
seen.add(current);
|
|
37552
|
-
const
|
|
37553
|
-
const code = String(
|
|
38287
|
+
const record3 = typeof current === "object" && current !== null ? current : {};
|
|
38288
|
+
const code = String(record3.code ?? "").toLowerCase();
|
|
37554
38289
|
const name = current instanceof Error ? current.name.toLowerCase() : "";
|
|
37555
38290
|
const text = String(
|
|
37556
38291
|
current instanceof Error ? current.message : current
|
|
@@ -37577,7 +38312,7 @@ function classifyNetworkFailure(error) {
|
|
|
37577
38312
|
if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
|
|
37578
38313
|
return "network_ssl_error";
|
|
37579
38314
|
}
|
|
37580
|
-
current =
|
|
38315
|
+
current = record3.cause ?? record3.context;
|
|
37581
38316
|
}
|
|
37582
38317
|
return "network_error";
|
|
37583
38318
|
}
|
|
@@ -38654,26 +39389,26 @@ function parseSetupPhases(value) {
|
|
|
38654
39389
|
if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
|
|
38655
39390
|
return null;
|
|
38656
39391
|
}
|
|
38657
|
-
const
|
|
38658
|
-
if (!isSetupPhaseStatus(
|
|
38659
|
-
switch (
|
|
39392
|
+
const record3 = phase;
|
|
39393
|
+
if (!isSetupPhaseStatus(record3.status)) return null;
|
|
39394
|
+
switch (record3.status) {
|
|
38660
39395
|
case "pending":
|
|
38661
39396
|
case "in_progress":
|
|
38662
|
-
phases[name] = { status:
|
|
39397
|
+
phases[name] = { status: record3.status };
|
|
38663
39398
|
break;
|
|
38664
39399
|
case "complete":
|
|
38665
39400
|
phases[name] = {
|
|
38666
39401
|
status: "complete",
|
|
38667
|
-
...typeof
|
|
39402
|
+
...typeof record3.outcome === "string" ? { outcome: record3.outcome } : {}
|
|
38668
39403
|
};
|
|
38669
39404
|
break;
|
|
38670
39405
|
case "waiting":
|
|
38671
|
-
if (typeof
|
|
38672
|
-
phases[name] = { status: "waiting", outcome:
|
|
39406
|
+
if (typeof record3.outcome !== "string") return null;
|
|
39407
|
+
phases[name] = { status: "waiting", outcome: record3.outcome };
|
|
38673
39408
|
break;
|
|
38674
39409
|
case "failed":
|
|
38675
|
-
if (typeof
|
|
38676
|
-
phases[name] = { status: "failed", code:
|
|
39410
|
+
if (typeof record3.code !== "string") return null;
|
|
39411
|
+
phases[name] = { status: "failed", code: record3.code };
|
|
38677
39412
|
break;
|
|
38678
39413
|
}
|
|
38679
39414
|
}
|
|
@@ -41618,7 +42353,7 @@ Examples:
|
|
|
41618
42353
|
}
|
|
41619
42354
|
|
|
41620
42355
|
// src/cli/commands/tools.ts
|
|
41621
|
-
import { Option as
|
|
42356
|
+
import { Option as Option4 } from "commander";
|
|
41622
42357
|
import {
|
|
41623
42358
|
chmodSync,
|
|
41624
42359
|
existsSync as existsSync19,
|
|
@@ -42124,9 +42859,9 @@ function requiredInputIds(tool) {
|
|
|
42124
42859
|
return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
|
|
42125
42860
|
}
|
|
42126
42861
|
function notConnectedSuffix(tool) {
|
|
42127
|
-
const
|
|
42128
|
-
const status = stringField2(
|
|
42129
|
-
const connected =
|
|
42862
|
+
const record3 = tool;
|
|
42863
|
+
const status = stringField2(record3, "credentialStatus", "credential_status");
|
|
42864
|
+
const connected = record3.connected;
|
|
42130
42865
|
const message = toolConnectionStatusMessage({
|
|
42131
42866
|
connected: connected === false ? false : void 0,
|
|
42132
42867
|
credentialStatus: status || void 0
|
|
@@ -42505,19 +43240,19 @@ function printPlayAliasToolError(toolId, play) {
|
|
|
42505
43240
|
console.error(playAliasToolErrorMessage(toolId, play));
|
|
42506
43241
|
}
|
|
42507
43242
|
function isPlayLikeTool(tool) {
|
|
42508
|
-
const
|
|
42509
|
-
if (
|
|
42510
|
-
const playExpansion = recordField2(
|
|
43243
|
+
const record3 = tool;
|
|
43244
|
+
if (record3.isPlay === true || record3.is_play === true) return true;
|
|
43245
|
+
const playExpansion = recordField2(record3, "playExpansion", "play_expansion");
|
|
42511
43246
|
if (Object.keys(playExpansion).length > 0) return true;
|
|
42512
|
-
const toolId = typeof
|
|
43247
|
+
const toolId = typeof record3.toolId === "string" ? record3.toolId : "";
|
|
42513
43248
|
return toolId.endsWith("_waterfall");
|
|
42514
43249
|
}
|
|
42515
43250
|
function isMonitorTypeTool(tool) {
|
|
42516
43251
|
return stringField2(tool, "kind") === "monitor_type";
|
|
42517
43252
|
}
|
|
42518
43253
|
function playReferenceForTool(tool) {
|
|
42519
|
-
const
|
|
42520
|
-
const declared = stringField2(
|
|
43254
|
+
const record3 = tool;
|
|
43255
|
+
const declared = stringField2(record3, "playReference", "play_reference");
|
|
42521
43256
|
if (declared.startsWith("prebuilt/")) {
|
|
42522
43257
|
return declared;
|
|
42523
43258
|
}
|
|
@@ -42690,12 +43425,12 @@ Examples:
|
|
|
42690
43425
|
"--examples-only",
|
|
42691
43426
|
"Only print runnable examples and sample payloads"
|
|
42692
43427
|
).option("--getters-only", "Only print extracted list/value getters").addOption(
|
|
42693
|
-
new
|
|
43428
|
+
new Option4(
|
|
42694
43429
|
"--compact",
|
|
42695
43430
|
"Compatibility alias for the default compact view"
|
|
42696
43431
|
).hideHelp()
|
|
42697
43432
|
).addOption(
|
|
42698
|
-
new
|
|
43433
|
+
new Option4(
|
|
42699
43434
|
"--contract-json",
|
|
42700
43435
|
"Compatibility alias for compact contract JSON"
|
|
42701
43436
|
).hideHelp()
|
|
@@ -43457,12 +44192,12 @@ function singleLineText(value, maxLength = 260) {
|
|
|
43457
44192
|
return `${text.slice(0, maxLength - 3).trimEnd()}...`;
|
|
43458
44193
|
}
|
|
43459
44194
|
function listedToolDescription(tool) {
|
|
43460
|
-
const
|
|
43461
|
-
return singleLineText(
|
|
44195
|
+
const record3 = tool;
|
|
44196
|
+
return singleLineText(record3.bestFor ?? record3.best_for ?? tool.description);
|
|
43462
44197
|
}
|
|
43463
44198
|
function formatListedToolCost(tool) {
|
|
43464
|
-
const
|
|
43465
|
-
const pricing = recordField2(
|
|
44199
|
+
const record3 = tool;
|
|
44200
|
+
const pricing = recordField2(record3, "pricing");
|
|
43466
44201
|
const displayText = stringField2(pricing, "displayText", "display_text");
|
|
43467
44202
|
return displayText ? `Cost: ${displayText}` : "";
|
|
43468
44203
|
}
|
|
@@ -44518,9 +45253,9 @@ function noticeToStderr(command) {
|
|
|
44518
45253
|
);
|
|
44519
45254
|
}
|
|
44520
45255
|
function emitPassThrough(command, payload, options) {
|
|
44521
|
-
const
|
|
45256
|
+
const json2 = shouldEmitJson(options.json);
|
|
44522
45257
|
const deprecation = migrationDeprecation(command);
|
|
44523
|
-
if (
|
|
45258
|
+
if (json2) {
|
|
44524
45259
|
const enriched = payload && typeof payload === "object" && !Array.isArray(payload) ? { ...payload, deprecation } : { result: payload, deprecation };
|
|
44525
45260
|
printJson(enriched);
|
|
44526
45261
|
return;
|
|
@@ -44541,9 +45276,9 @@ function clientWithTimeout(timeoutSeconds) {
|
|
|
44541
45276
|
}
|
|
44542
45277
|
function readStatus(payload) {
|
|
44543
45278
|
if (!payload || typeof payload !== "object") return null;
|
|
44544
|
-
const
|
|
44545
|
-
if (typeof
|
|
44546
|
-
const run =
|
|
45279
|
+
const record3 = payload;
|
|
45280
|
+
if (typeof record3.status === "string") return record3.status;
|
|
45281
|
+
const run = record3.run;
|
|
44547
45282
|
if (run && typeof run === "object") {
|
|
44548
45283
|
const status = run.status;
|
|
44549
45284
|
if (typeof status === "string") return status;
|