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.js
CHANGED
|
@@ -1298,7 +1298,7 @@ var SDK_RELEASE = {
|
|
|
1298
1298
|
// getters keep their established compatibility behavior.
|
|
1299
1299
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1300
1300
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
1301
|
-
version: "0.3.
|
|
1301
|
+
version: "0.3.99",
|
|
1302
1302
|
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.",
|
|
1303
1303
|
packageCapabilities: {
|
|
1304
1304
|
updatePreferences: 1
|
|
@@ -3370,9 +3370,9 @@ function nonEmptyString(value) {
|
|
|
3370
3370
|
}
|
|
3371
3371
|
function normalizeDatasetBornFrom(value) {
|
|
3372
3372
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
3373
|
-
const
|
|
3374
|
-
const table = nonEmptyString(
|
|
3375
|
-
const rowCountIn = finiteNonNegativeInteger2(
|
|
3373
|
+
const record3 = value;
|
|
3374
|
+
const table = nonEmptyString(record3.table);
|
|
3375
|
+
const rowCountIn = finiteNonNegativeInteger2(record3.rowCountIn);
|
|
3376
3376
|
if (!table || rowCountIn === null) return null;
|
|
3377
3377
|
return { table, rowCountIn };
|
|
3378
3378
|
}
|
|
@@ -4561,21 +4561,21 @@ function normalizePlayRuntimeNamespace(value) {
|
|
|
4561
4561
|
}
|
|
4562
4562
|
function normalizePlayRuntimeSelection(value) {
|
|
4563
4563
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
4564
|
-
const
|
|
4565
|
-
if (Object.keys(
|
|
4564
|
+
const record3 = value;
|
|
4565
|
+
if (Object.keys(record3).some(
|
|
4566
4566
|
(key) => key !== "environment" && key !== "namespace" && key !== "backend"
|
|
4567
|
-
) ||
|
|
4567
|
+
) || record3.environment !== "preview") {
|
|
4568
4568
|
return null;
|
|
4569
4569
|
}
|
|
4570
|
-
const namespace = normalizePlayRuntimeNamespace(
|
|
4570
|
+
const namespace = normalizePlayRuntimeNamespace(record3.namespace);
|
|
4571
4571
|
if (!namespace) return null;
|
|
4572
|
-
if (
|
|
4572
|
+
if (record3.backend === void 0) {
|
|
4573
4573
|
return { environment: "preview", namespace };
|
|
4574
4574
|
}
|
|
4575
|
-
if (
|
|
4575
|
+
if (record3.backend !== PLAY_RUNTIME_BACKENDS.daytona && record3.backend !== PLAY_RUNTIME_BACKENDS.modal) {
|
|
4576
4576
|
return null;
|
|
4577
4577
|
}
|
|
4578
|
-
return { environment: "preview", namespace, backend:
|
|
4578
|
+
return { environment: "preview", namespace, backend: record3.backend };
|
|
4579
4579
|
}
|
|
4580
4580
|
function normalizePlayRuntimeEnvironment(value) {
|
|
4581
4581
|
return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
|
|
@@ -5220,10 +5220,18 @@ var DeeplineClient = class {
|
|
|
5220
5220
|
repair: (options2) => this.repairMonitors(options2),
|
|
5221
5221
|
health: (options2) => this.readMonitorsHealth(options2),
|
|
5222
5222
|
batch: {
|
|
5223
|
+
deploy: (definitions, options2) => this.deployMonitorBatch(definitions, options2),
|
|
5223
5224
|
submit: (options2) => this.submitMonitorBatch(options2),
|
|
5224
5225
|
get: (operationId, options2) => this.getMonitorBatch(operationId, options2)
|
|
5225
5226
|
},
|
|
5227
|
+
jobs: {
|
|
5228
|
+
get: (jobId) => this.getMonitorJob(jobId),
|
|
5229
|
+
logs: (jobId, options2) => this.getMonitorJobLogs(jobId, options2),
|
|
5230
|
+
cancel: (jobId) => this.cancelMonitorJob(jobId),
|
|
5231
|
+
wait: (jobId, options2) => this.waitForMonitorJob(jobId, options2)
|
|
5232
|
+
},
|
|
5226
5233
|
fleets: {
|
|
5234
|
+
deploy: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
5227
5235
|
sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
5228
5236
|
get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
|
|
5229
5237
|
list: () => this.listMonitorFleets(),
|
|
@@ -7567,7 +7575,8 @@ var DeeplineClient = class {
|
|
|
7567
7575
|
enabled: true,
|
|
7568
7576
|
threshold_credits: options.thresholdCredits,
|
|
7569
7577
|
refill_to_credits: options.refillToCredits,
|
|
7570
|
-
...options.purchaseLimitCents !== void 0 ? { purchase_limit_cents: options.purchaseLimitCents } : {}
|
|
7578
|
+
...options.purchaseLimitCents !== void 0 ? { purchase_limit_cents: options.purchaseLimitCents } : {},
|
|
7579
|
+
...options.purchaseLimitCredits !== void 0 ? { purchase_limit_credits: options.purchaseLimitCredits } : {}
|
|
7571
7580
|
} : { enabled: false },
|
|
7572
7581
|
{ "Idempotency-Key": idempotencyKey }
|
|
7573
7582
|
);
|
|
@@ -7975,6 +7984,68 @@ var DeeplineClient = class {
|
|
|
7975
7984
|
);
|
|
7976
7985
|
}
|
|
7977
7986
|
// ——————————————————————————————————————————————————————————
|
|
7987
|
+
// Monitor Jobs, Batches, and Fleets
|
|
7988
|
+
// ——————————————————————————————————————————————————————————
|
|
7989
|
+
monitorJobIdempotencyKey(operation) {
|
|
7990
|
+
const uuid = globalThis.crypto?.randomUUID?.();
|
|
7991
|
+
return `monitor-job-${operation}-${uuid ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`}`;
|
|
7992
|
+
}
|
|
7993
|
+
monitorJobHeaders(operation, idempotencyKey) {
|
|
7994
|
+
return {
|
|
7995
|
+
"Idempotency-Key": idempotencyKey?.trim() || this.monitorJobIdempotencyKey(operation)
|
|
7996
|
+
};
|
|
7997
|
+
}
|
|
7998
|
+
async deployMonitorBatch(definitions, options) {
|
|
7999
|
+
return this.http.request(
|
|
8000
|
+
"/api/v2/monitors/batch/deploy",
|
|
8001
|
+
{
|
|
8002
|
+
method: "POST",
|
|
8003
|
+
body: { version: 1, kind: "batch", monitors: definitions },
|
|
8004
|
+
headers: this.monitorJobHeaders(
|
|
8005
|
+
"batch-deploy",
|
|
8006
|
+
options?.idempotencyKey
|
|
8007
|
+
),
|
|
8008
|
+
maxRetries: 0,
|
|
8009
|
+
exactUrlOnly: true
|
|
8010
|
+
}
|
|
8011
|
+
);
|
|
8012
|
+
}
|
|
8013
|
+
async getMonitorJob(jobId) {
|
|
8014
|
+
return this.http.request(
|
|
8015
|
+
`/api/v2/monitors/jobs/${encodeURIComponent(jobId)}`,
|
|
8016
|
+
{ method: "GET" }
|
|
8017
|
+
);
|
|
8018
|
+
}
|
|
8019
|
+
async getMonitorJobLogs(jobId, options) {
|
|
8020
|
+
const query = options?.limit === void 0 ? "" : `?limit=${encodeURIComponent(String(options.limit))}`;
|
|
8021
|
+
return this.http.request(
|
|
8022
|
+
`/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/logs${query}`,
|
|
8023
|
+
{ method: "GET" }
|
|
8024
|
+
);
|
|
8025
|
+
}
|
|
8026
|
+
async cancelMonitorJob(jobId) {
|
|
8027
|
+
return this.http.request(
|
|
8028
|
+
`/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/cancel`,
|
|
8029
|
+
{ method: "POST", body: {}, maxRetries: 0, exactUrlOnly: true }
|
|
8030
|
+
);
|
|
8031
|
+
}
|
|
8032
|
+
async waitForMonitorJob(jobId, options) {
|
|
8033
|
+
const timeoutMs = Math.max(1, options?.timeoutMs ?? 10 * 6e4);
|
|
8034
|
+
const pollIntervalMs = Math.max(1, options?.pollIntervalMs ?? 2e3);
|
|
8035
|
+
const terminal = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled"]);
|
|
8036
|
+
const startedAt = Date.now();
|
|
8037
|
+
let latest = await this.getMonitorJob(jobId);
|
|
8038
|
+
while (true) {
|
|
8039
|
+
options?.onProgress?.(latest);
|
|
8040
|
+
const job = latest.job;
|
|
8041
|
+
const state = typeof job?.state === "string" ? job.state : void 0;
|
|
8042
|
+
if (state && terminal.has(state)) return latest;
|
|
8043
|
+
if (Date.now() - startedAt >= timeoutMs) return latest;
|
|
8044
|
+
await sleep2(pollIntervalMs);
|
|
8045
|
+
latest = await this.getMonitorJob(jobId);
|
|
8046
|
+
}
|
|
8047
|
+
}
|
|
8048
|
+
// ——————————————————————————————————————————————————————————
|
|
7978
8049
|
// Monitor Fleets
|
|
7979
8050
|
// ——————————————————————————————————————————————————————————
|
|
7980
8051
|
monitorFleetIdempotencyKey(operation) {
|
|
@@ -8746,30 +8817,30 @@ function flattenObjectColumns(row, options = {}) {
|
|
|
8746
8817
|
continue;
|
|
8747
8818
|
}
|
|
8748
8819
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
8749
|
-
const
|
|
8820
|
+
const record3 = value;
|
|
8750
8821
|
if (options.objectColumns === "json") {
|
|
8751
|
-
flattened[key] = csvSafeJsonString(
|
|
8822
|
+
flattened[key] = csvSafeJsonString(record3);
|
|
8752
8823
|
continue;
|
|
8753
8824
|
}
|
|
8754
|
-
const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(
|
|
8825
|
+
const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record3, "matched_result") || Object.prototype.hasOwnProperty.call(record3, "matchedResult");
|
|
8755
8826
|
if (hasMatchedEnvelope) {
|
|
8756
|
-
flattened[key] = csvSafeJsonString(
|
|
8827
|
+
flattened[key] = csvSafeJsonString(record3);
|
|
8757
8828
|
continue;
|
|
8758
8829
|
}
|
|
8759
8830
|
if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
|
|
8760
8831
|
flattened[key] = rawValue;
|
|
8761
8832
|
continue;
|
|
8762
8833
|
} else {
|
|
8763
|
-
const failureMessage = failureMessageFromRecord(
|
|
8834
|
+
const failureMessage = failureMessageFromRecord(record3);
|
|
8764
8835
|
if (failureMessage) {
|
|
8765
8836
|
flattened[key] = failureMessage;
|
|
8766
8837
|
continue;
|
|
8767
|
-
} else if (Object.prototype.hasOwnProperty.call(
|
|
8768
|
-
flattened[key] = csvSafeJsonString(
|
|
8838
|
+
} else if (Object.prototype.hasOwnProperty.call(record3, "result")) {
|
|
8839
|
+
flattened[key] = csvSafeJsonString(record3);
|
|
8769
8840
|
continue;
|
|
8770
8841
|
}
|
|
8771
8842
|
}
|
|
8772
|
-
for (const [nestedKey, nestedValue] of Object.entries(
|
|
8843
|
+
for (const [nestedKey, nestedValue] of Object.entries(record3)) {
|
|
8773
8844
|
flattened[`${key}.${nestedKey}`] = nestedValue && typeof nestedValue === "object" ? csvSafeJsonString(nestedValue) : nestedValue;
|
|
8774
8845
|
}
|
|
8775
8846
|
continue;
|
|
@@ -10718,8 +10789,8 @@ async function handleAutoRechargeStatus(options) {
|
|
|
10718
10789
|
`State: ${state}`,
|
|
10719
10790
|
...payload.threshold_credits !== null ? [`Threshold: ${payload.threshold_credits} credits`] : [],
|
|
10720
10791
|
...payload.refill_to_credits !== null ? [`Refill balance to: ${payload.refill_to_credits} credits`] : [],
|
|
10721
|
-
...payload.
|
|
10722
|
-
|
|
10792
|
+
...payload.purchase_limit_credits != null ? [
|
|
10793
|
+
`Automatic credit purchase cap: ${payload.purchase_limit_credits} credits per rolling 30 days`
|
|
10723
10794
|
] : []
|
|
10724
10795
|
];
|
|
10725
10796
|
printCommandEnvelope(
|
|
@@ -10735,6 +10806,18 @@ async function handleAutoRechargeSet(options) {
|
|
|
10735
10806
|
const thresholdCredits = parseTopUpCredits(options.thresholdCredits);
|
|
10736
10807
|
const refillToCredits = parseTopUpCredits(options.refillToCredits);
|
|
10737
10808
|
const rollingLimitCents = options.purchaseLimitCents === void 0 ? void 0 : options.purchaseLimitCents === "none" ? null : Number(options.purchaseLimitCents);
|
|
10809
|
+
const rollingLimitCredits = options.purchaseLimitCredits === void 0 ? void 0 : options.purchaseLimitCredits === "none" ? null : Number(options.purchaseLimitCredits);
|
|
10810
|
+
if (rollingLimitCredits != null && (!Number.isSafeInteger(rollingLimitCredits) || rollingLimitCredits < 0)) {
|
|
10811
|
+
reportBillingFailure(
|
|
10812
|
+
{
|
|
10813
|
+
exitCode: 2,
|
|
10814
|
+
code: "INVALID_AUTO_RECHARGE_CONFIGURATION",
|
|
10815
|
+
message: "--purchase-limit-credits must be a nonnegative whole number of credits or none."
|
|
10816
|
+
},
|
|
10817
|
+
options
|
|
10818
|
+
);
|
|
10819
|
+
return;
|
|
10820
|
+
}
|
|
10738
10821
|
if (rollingLimitCents !== void 0 && rollingLimitCents !== null && (!Number.isSafeInteger(rollingLimitCents) || rollingLimitCents <= 0)) {
|
|
10739
10822
|
reportBillingFailure(
|
|
10740
10823
|
{
|
|
@@ -10771,7 +10854,8 @@ async function handleAutoRechargeSet(options) {
|
|
|
10771
10854
|
enabled: true,
|
|
10772
10855
|
threshold_credits: thresholdCredits,
|
|
10773
10856
|
refill_to_credits: refillToCredits,
|
|
10774
|
-
...rollingLimitCents !== void 0 ? { purchase_limit_cents: rollingLimitCents } : {}
|
|
10857
|
+
...rollingLimitCents !== void 0 ? { purchase_limit_cents: rollingLimitCents } : {},
|
|
10858
|
+
...rollingLimitCredits !== void 0 ? { purchase_limit_credits: rollingLimitCredits } : {}
|
|
10775
10859
|
}
|
|
10776
10860
|
}
|
|
10777
10861
|
},
|
|
@@ -10784,6 +10868,7 @@ async function handleAutoRechargeSet(options) {
|
|
|
10784
10868
|
thresholdCredits,
|
|
10785
10869
|
refillToCredits,
|
|
10786
10870
|
...rollingLimitCents !== void 0 ? { purchaseLimitCents: rollingLimitCents } : {},
|
|
10871
|
+
...rollingLimitCredits !== void 0 ? { purchaseLimitCredits: rollingLimitCredits } : {},
|
|
10787
10872
|
idempotencyKey
|
|
10788
10873
|
});
|
|
10789
10874
|
printCommandEnvelope(
|
|
@@ -11171,9 +11256,14 @@ Examples:
|
|
|
11171
11256
|
).requiredOption(
|
|
11172
11257
|
"--refill-to-credits <credits>",
|
|
11173
11258
|
"Recharge the balance to this amount"
|
|
11259
|
+
).addOption(
|
|
11260
|
+
new import_commander.Option(
|
|
11261
|
+
"--purchase-limit-cents <cents>",
|
|
11262
|
+
"Deprecated: converted to credits"
|
|
11263
|
+
).hideHelp()
|
|
11174
11264
|
).option(
|
|
11175
|
-
"--purchase-limit-
|
|
11176
|
-
"Limit automatic purchases over rolling 30 days (
|
|
11265
|
+
"--purchase-limit-credits <credits>",
|
|
11266
|
+
"Limit automatic credit purchases over rolling 30 days (or none to remove)"
|
|
11177
11267
|
).option("--idempotency-key <key>", "Stable retry key").option("--dry-run", "Print the planned update without applying it").option("--json", "Emit JSON output").action(handleAutoRechargeSet)
|
|
11178
11268
|
).addCommand(
|
|
11179
11269
|
new import_commander.Command("off").description(
|
|
@@ -11436,9 +11526,9 @@ function canonicalDatasetJsonValue(value, ancestors) {
|
|
|
11436
11526
|
}
|
|
11437
11527
|
if (ancestors.has(value)) return value;
|
|
11438
11528
|
ancestors.add(value);
|
|
11439
|
-
const
|
|
11529
|
+
const record3 = value;
|
|
11440
11530
|
const normalized = Object.fromEntries(
|
|
11441
|
-
Object.keys(
|
|
11531
|
+
Object.keys(record3).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record3[key], ancestors)])
|
|
11442
11532
|
);
|
|
11443
11533
|
ancestors.delete(value);
|
|
11444
11534
|
return normalized;
|
|
@@ -12635,16 +12725,16 @@ function collectErrorText(value) {
|
|
|
12635
12725
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
12636
12726
|
return errorMessage(value);
|
|
12637
12727
|
}
|
|
12638
|
-
const
|
|
12728
|
+
const record3 = value;
|
|
12639
12729
|
return [
|
|
12640
12730
|
errorMessage(value),
|
|
12641
|
-
typeof
|
|
12642
|
-
typeof
|
|
12643
|
-
typeof
|
|
12644
|
-
typeof
|
|
12645
|
-
typeof
|
|
12646
|
-
|
|
12647
|
-
|
|
12731
|
+
typeof record3.error === "string" ? record3.error : "",
|
|
12732
|
+
typeof record3.message === "string" ? record3.message : "",
|
|
12733
|
+
typeof record3.detail === "string" ? record3.detail : "",
|
|
12734
|
+
typeof record3.hint === "string" ? record3.hint : "",
|
|
12735
|
+
typeof record3.code === "string" ? record3.code : "",
|
|
12736
|
+
record3.response ? collectErrorText(record3.response) : "",
|
|
12737
|
+
record3.details ? collectErrorText(record3.details) : ""
|
|
12648
12738
|
].filter(Boolean).join("\n");
|
|
12649
12739
|
}
|
|
12650
12740
|
function formatDbQueryError(sql, error) {
|
|
@@ -13658,8 +13748,8 @@ function getterNamesFromTool(tool, kind) {
|
|
|
13658
13748
|
return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
|
|
13659
13749
|
}
|
|
13660
13750
|
function targetGettersFromTool(tool) {
|
|
13661
|
-
const
|
|
13662
|
-
const raw =
|
|
13751
|
+
const record3 = isRecord9(tool) ? tool : {};
|
|
13752
|
+
const raw = record3.targetGetters ?? record3.target_getters;
|
|
13663
13753
|
if (!isRecord9(raw)) return {};
|
|
13664
13754
|
const entries = [];
|
|
13665
13755
|
for (const [target, value] of Object.entries(raw)) {
|
|
@@ -17755,13 +17845,13 @@ function validateFixtureBehavior(value) {
|
|
|
17755
17845
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
17756
17846
|
return { ok: false, error: "fixtureBehavior must be a JSON object." };
|
|
17757
17847
|
}
|
|
17758
|
-
const
|
|
17759
|
-
const supportedKeys =
|
|
17848
|
+
const record3 = value;
|
|
17849
|
+
const supportedKeys = record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
|
|
17760
17850
|
"version",
|
|
17761
17851
|
"responseSamples",
|
|
17762
|
-
...
|
|
17852
|
+
...record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
|
|
17763
17853
|
]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
|
|
17764
|
-
const unknownKeys = Object.keys(
|
|
17854
|
+
const unknownKeys = Object.keys(record3).filter(
|
|
17765
17855
|
(key) => !supportedKeys.has(key)
|
|
17766
17856
|
);
|
|
17767
17857
|
if (unknownKeys.length > 0) {
|
|
@@ -17770,22 +17860,22 @@ function validateFixtureBehavior(value) {
|
|
|
17770
17860
|
error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
|
|
17771
17861
|
};
|
|
17772
17862
|
}
|
|
17773
|
-
if (
|
|
17863
|
+
if (record3.version !== FIXTURE_BEHAVIOR_VERSION && record3.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record3.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17774
17864
|
return {
|
|
17775
17865
|
ok: false,
|
|
17776
17866
|
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
|
|
17777
17867
|
};
|
|
17778
17868
|
}
|
|
17779
|
-
if (
|
|
17780
|
-
if (!Array.isArray(
|
|
17869
|
+
if (record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17870
|
+
if (!Array.isArray(record3.responseSamples) || record3.responseSamples.length === 0 || record3.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
17781
17871
|
return {
|
|
17782
17872
|
ok: false,
|
|
17783
17873
|
error: `fixtureBehavior.responseSamples must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
|
|
17784
17874
|
};
|
|
17785
17875
|
}
|
|
17786
17876
|
const samples2 = [];
|
|
17787
|
-
for (let index = 0; index <
|
|
17788
|
-
const value2 =
|
|
17877
|
+
for (let index = 0; index < record3.responseSamples.length; index += 1) {
|
|
17878
|
+
const value2 = record3.responseSamples[index];
|
|
17789
17879
|
if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
|
|
17790
17880
|
return {
|
|
17791
17881
|
ok: false,
|
|
@@ -17884,14 +17974,14 @@ function validateFixtureBehavior(value) {
|
|
|
17884
17974
|
});
|
|
17885
17975
|
}
|
|
17886
17976
|
let replayBundle;
|
|
17887
|
-
if (
|
|
17888
|
-
if (!
|
|
17977
|
+
if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17978
|
+
if (!record3.replayBundle || typeof record3.replayBundle !== "object" || Array.isArray(record3.replayBundle)) {
|
|
17889
17979
|
return {
|
|
17890
17980
|
ok: false,
|
|
17891
17981
|
error: "fixtureBehavior.replayBundle must be an object."
|
|
17892
17982
|
};
|
|
17893
17983
|
}
|
|
17894
|
-
const replay =
|
|
17984
|
+
const replay = record3.replayBundle;
|
|
17895
17985
|
const replayUnknownKeys = Object.keys(replay).filter(
|
|
17896
17986
|
(key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
|
|
17897
17987
|
);
|
|
@@ -17939,7 +18029,7 @@ function validateFixtureBehavior(value) {
|
|
|
17939
18029
|
...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
|
|
17940
18030
|
};
|
|
17941
18031
|
}
|
|
17942
|
-
if (
|
|
18032
|
+
if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17943
18033
|
return {
|
|
17944
18034
|
ok: true,
|
|
17945
18035
|
behavior: {
|
|
@@ -17957,15 +18047,15 @@ function validateFixtureBehavior(value) {
|
|
|
17957
18047
|
}
|
|
17958
18048
|
};
|
|
17959
18049
|
}
|
|
17960
|
-
if (!Array.isArray(
|
|
18050
|
+
if (!Array.isArray(record3.responseDelaySamplesMs) || record3.responseDelaySamplesMs.length === 0 || record3.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
17961
18051
|
return {
|
|
17962
18052
|
ok: false,
|
|
17963
18053
|
error: `fixtureBehavior.responseDelaySamplesMs must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
|
|
17964
18054
|
};
|
|
17965
18055
|
}
|
|
17966
18056
|
const samples = [];
|
|
17967
|
-
for (let index = 0; index <
|
|
17968
|
-
const value2 =
|
|
18057
|
+
for (let index = 0; index < record3.responseDelaySamplesMs.length; index += 1) {
|
|
18058
|
+
const value2 = record3.responseDelaySamplesMs[index];
|
|
17969
18059
|
if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 0 || value2 > MAX_FIXTURE_RESPONSE_DELAY_MS) {
|
|
17970
18060
|
return {
|
|
17971
18061
|
ok: false,
|
|
@@ -18744,8 +18834,8 @@ function looksLikeStagedFileRef(value) {
|
|
|
18744
18834
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
18745
18835
|
return false;
|
|
18746
18836
|
}
|
|
18747
|
-
const
|
|
18748
|
-
return typeof
|
|
18837
|
+
const record3 = value;
|
|
18838
|
+
return typeof record3.contentHash === "string" || typeof record3.contentBase64 === "string" || typeof record3.logicalPath === "string" && typeof record3.bytes === "number";
|
|
18749
18839
|
}
|
|
18750
18840
|
var CSV_DATA_INPUT_KEY = "csv";
|
|
18751
18841
|
function collectLocalFileInputRefs(value, inputPath, key, out) {
|
|
@@ -19258,8 +19348,8 @@ function readLiveRunField(event, field) {
|
|
|
19258
19348
|
const records = [payload, payload.progress, run, run?.progress].filter(
|
|
19259
19349
|
(value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
|
|
19260
19350
|
);
|
|
19261
|
-
for (const
|
|
19262
|
-
if (
|
|
19351
|
+
for (const record3 of records) {
|
|
19352
|
+
if (record3[field] !== void 0) return record3[field];
|
|
19263
19353
|
}
|
|
19264
19354
|
return void 0;
|
|
19265
19355
|
}
|
|
@@ -19561,8 +19651,8 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
19561
19651
|
if (!state || typeof state !== "object" || Array.isArray(state)) {
|
|
19562
19652
|
continue;
|
|
19563
19653
|
}
|
|
19564
|
-
const
|
|
19565
|
-
const progress =
|
|
19654
|
+
const record3 = state;
|
|
19655
|
+
const progress = record3.progress && typeof record3.progress === "object" && !Array.isArray(record3.progress) ? record3.progress : null;
|
|
19566
19656
|
if (!progress) {
|
|
19567
19657
|
continue;
|
|
19568
19658
|
}
|
|
@@ -19579,7 +19669,7 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
19579
19669
|
completed: progress.completed
|
|
19580
19670
|
});
|
|
19581
19671
|
lines.push(
|
|
19582
|
-
`progress ${formatProgressLabel(
|
|
19672
|
+
`progress ${formatProgressLabel(record3.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
|
|
19583
19673
|
);
|
|
19584
19674
|
}
|
|
19585
19675
|
return lines;
|
|
@@ -20259,11 +20349,11 @@ function truncateErrorForDisplay(message, runId, maxChars = RUN_ERROR_DISPLAY_MA
|
|
|
20259
20349
|
const fullErrorHint = runId ? ` (full error: deepline runs get ${runId} --full)` : " (full error: deepline runs get <runId> --full)";
|
|
20260
20350
|
return `${wordBoundary}\u2026${fullErrorHint}`;
|
|
20261
20351
|
}
|
|
20262
|
-
function clampJsonPreviewText(
|
|
20263
|
-
if (
|
|
20264
|
-
return
|
|
20352
|
+
function clampJsonPreviewText(json2, maxChars) {
|
|
20353
|
+
if (json2.length <= maxChars) {
|
|
20354
|
+
return json2;
|
|
20265
20355
|
}
|
|
20266
|
-
const slice =
|
|
20356
|
+
const slice = json2.slice(0, maxChars);
|
|
20267
20357
|
const lastNewline = slice.lastIndexOf("\n");
|
|
20268
20358
|
const head = lastNewline > 0 ? slice.slice(0, lastNewline) : slice;
|
|
20269
20359
|
return `${head}
|
|
@@ -20389,12 +20479,12 @@ function defaultResultForEnvelope(value, depth = 0) {
|
|
|
20389
20479
|
return output2;
|
|
20390
20480
|
}
|
|
20391
20481
|
function formatJsonPreview(value) {
|
|
20392
|
-
const
|
|
20393
|
-
if (!
|
|
20482
|
+
const json2 = JSON.stringify(value, null, 2);
|
|
20483
|
+
if (!json2 || json2 === "{}") {
|
|
20394
20484
|
return [];
|
|
20395
20485
|
}
|
|
20396
20486
|
const MAX_CHARS = 4e3;
|
|
20397
|
-
const truncated = clampJsonPreviewText(
|
|
20487
|
+
const truncated = clampJsonPreviewText(json2, MAX_CHARS);
|
|
20398
20488
|
return truncated.split("\n").map((line) => ` ${line}`);
|
|
20399
20489
|
}
|
|
20400
20490
|
function formatReturnValue(result) {
|
|
@@ -20422,17 +20512,17 @@ function collectDatasetHandleLines(value, path = "result") {
|
|
|
20422
20512
|
return [];
|
|
20423
20513
|
}
|
|
20424
20514
|
if (isDatasetHandle(value)) {
|
|
20425
|
-
const
|
|
20426
|
-
const count = typeof
|
|
20427
|
-
const preview = Array.isArray(
|
|
20515
|
+
const record3 = value;
|
|
20516
|
+
const count = typeof record3.count === "number" ? record3.count : typeof record3.rowCount === "number" ? record3.rowCount : null;
|
|
20517
|
+
const preview = Array.isArray(record3.preview) ? record3.preview : [];
|
|
20428
20518
|
const lines2 = [
|
|
20429
|
-
` dataset ${typeof
|
|
20519
|
+
` dataset ${typeof record3.path === "string" ? record3.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
|
|
20430
20520
|
];
|
|
20431
|
-
if (typeof
|
|
20432
|
-
lines2.push(` query dataset: ${
|
|
20521
|
+
if (typeof record3.queryDatasetCommand === "string") {
|
|
20522
|
+
lines2.push(` query dataset: ${record3.queryDatasetCommand}`);
|
|
20433
20523
|
}
|
|
20434
|
-
if (typeof
|
|
20435
|
-
lines2.push(` export CSV: ${
|
|
20524
|
+
if (typeof record3.slowExportAsCsvCommand === "string") {
|
|
20525
|
+
lines2.push(` export CSV: ${record3.slowExportAsCsvCommand}`);
|
|
20436
20526
|
}
|
|
20437
20527
|
return lines2;
|
|
20438
20528
|
}
|
|
@@ -20829,8 +20919,8 @@ function withTerminalPlayIdentity(status, playName) {
|
|
|
20829
20919
|
if (!playName.trim() || getPlayRunPackage(status)) {
|
|
20830
20920
|
return status;
|
|
20831
20921
|
}
|
|
20832
|
-
const
|
|
20833
|
-
const hasIdentity = typeof
|
|
20922
|
+
const record3 = status;
|
|
20923
|
+
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"));
|
|
20834
20924
|
if (hasIdentity) {
|
|
20835
20925
|
return status;
|
|
20836
20926
|
}
|
|
@@ -20943,9 +21033,9 @@ function formatSummaryScalar(value) {
|
|
|
20943
21033
|
}
|
|
20944
21034
|
return null;
|
|
20945
21035
|
}
|
|
20946
|
-
function formatSummaryScalarParts(
|
|
21036
|
+
function formatSummaryScalarParts(record3, skipKeys = /* @__PURE__ */ new Set()) {
|
|
20947
21037
|
const parts = [];
|
|
20948
|
-
for (const [key, value] of Object.entries(
|
|
21038
|
+
for (const [key, value] of Object.entries(record3)) {
|
|
20949
21039
|
if (skipKeys.has(key)) {
|
|
20950
21040
|
continue;
|
|
20951
21041
|
}
|
|
@@ -20972,13 +21062,13 @@ function formatTopValuesPart(value) {
|
|
|
20972
21062
|
return `top_values=${entries.map(([topValue, count]) => `${topValue}=${String(count)}`).join(", ")}`;
|
|
20973
21063
|
}
|
|
20974
21064
|
function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
|
|
20975
|
-
const
|
|
20976
|
-
const columnStats = readRecord(
|
|
20977
|
-
if (!
|
|
21065
|
+
const record3 = readRecord(summary);
|
|
21066
|
+
const columnStats = readRecord(record3?.columnStats);
|
|
21067
|
+
if (!record3 || !columnStats) {
|
|
20978
21068
|
return [];
|
|
20979
21069
|
}
|
|
20980
21070
|
const lines = [];
|
|
20981
|
-
const rowCounts = readRecord(
|
|
21071
|
+
const rowCounts = readRecord(record3.rowCounts);
|
|
20982
21072
|
if (rowCounts) {
|
|
20983
21073
|
const persisted = readNonNegativeInteger(rowCounts.persisted);
|
|
20984
21074
|
const succeeded = readNonNegativeInteger(rowCounts.succeeded);
|
|
@@ -20994,7 +21084,7 @@ function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
|
|
|
20994
21084
|
}
|
|
20995
21085
|
}
|
|
20996
21086
|
const parts = formatSummaryScalarParts(
|
|
20997
|
-
|
|
21087
|
+
record3,
|
|
20998
21088
|
/* @__PURE__ */ new Set(["columnStats", "rowCounts"])
|
|
20999
21089
|
);
|
|
21000
21090
|
if (parts.length > 0) {
|
|
@@ -21024,35 +21114,35 @@ function actionToCommand(action) {
|
|
|
21024
21114
|
if (!action || typeof action !== "object" || Array.isArray(action)) {
|
|
21025
21115
|
return null;
|
|
21026
21116
|
}
|
|
21027
|
-
const
|
|
21028
|
-
if (typeof
|
|
21029
|
-
return
|
|
21117
|
+
const record3 = action;
|
|
21118
|
+
if (typeof record3.command === "string" && record3.command.trim()) {
|
|
21119
|
+
return record3.command.trim();
|
|
21030
21120
|
}
|
|
21031
|
-
if (
|
|
21032
|
-
return `deepline runs get ${
|
|
21121
|
+
if (record3.kind === "deepline_run_inspect" && typeof record3.runId === "string") {
|
|
21122
|
+
return `deepline runs get ${record3.runId} --json`;
|
|
21033
21123
|
}
|
|
21034
|
-
if (
|
|
21035
|
-
return `deepline runs get ${
|
|
21124
|
+
if (record3.kind === "deepline_run_full" && typeof record3.runId === "string") {
|
|
21125
|
+
return `deepline runs get ${record3.runId} --full --json`;
|
|
21036
21126
|
}
|
|
21037
|
-
if (
|
|
21038
|
-
return `deepline runs get ${
|
|
21127
|
+
if (record3.kind === "deepline_run_billing" && typeof record3.runId === "string") {
|
|
21128
|
+
return `deepline runs get ${record3.runId} --full --json | jq '.billing'`;
|
|
21039
21129
|
}
|
|
21040
|
-
if (
|
|
21041
|
-
return `deepline runs export ${
|
|
21042
|
-
|
|
21043
|
-
)} --out ${shellSingleQuote(`${
|
|
21130
|
+
if (record3.kind === "deepline_run_export" && typeof record3.runId === "string" && typeof record3.datasetPath === "string") {
|
|
21131
|
+
return `deepline runs export ${record3.runId} --dataset ${shellSingleQuote(
|
|
21132
|
+
record3.datasetPath
|
|
21133
|
+
)} --out ${shellSingleQuote(`${record3.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
|
|
21044
21134
|
}
|
|
21045
|
-
if (
|
|
21046
|
-
if (typeof
|
|
21047
|
-
return
|
|
21135
|
+
if (record3.kind === "deepline_run_logs") {
|
|
21136
|
+
if (typeof record3.command === "string" && record3.command.trim()) {
|
|
21137
|
+
return record3.command;
|
|
21048
21138
|
}
|
|
21049
|
-
if (typeof
|
|
21050
|
-
return
|
|
21139
|
+
if (typeof record3.runId === "string") {
|
|
21140
|
+
return record3.view === "failed" ? `deepline runs get ${record3.runId} --log-failed --json` : `deepline runs logs ${record3.runId} --json`;
|
|
21051
21141
|
}
|
|
21052
21142
|
}
|
|
21053
|
-
if (
|
|
21054
|
-
const maxRows = typeof
|
|
21055
|
-
return `deepline db query --sql ${shellSingleQuote(
|
|
21143
|
+
if (record3.kind === "deepline_db_query" && typeof record3.sql === "string") {
|
|
21144
|
+
const maxRows = typeof record3.maxRows === "number" && Number.isFinite(record3.maxRows) ? Math.trunc(record3.maxRows) : 20;
|
|
21145
|
+
return `deepline db query --sql ${shellSingleQuote(record3.sql)} --max-rows ${maxRows} --json`;
|
|
21056
21146
|
}
|
|
21057
21147
|
return null;
|
|
21058
21148
|
}
|
|
@@ -21127,8 +21217,8 @@ function formatPackageDatasetActionLines(packaged) {
|
|
|
21127
21217
|
}
|
|
21128
21218
|
function formatInlinePackageValue(value) {
|
|
21129
21219
|
const compacted = compactReturnValue(value);
|
|
21130
|
-
const
|
|
21131
|
-
return clampJsonPreviewText(
|
|
21220
|
+
const json2 = JSON.stringify(compacted);
|
|
21221
|
+
return clampJsonPreviewText(json2 ?? String(compacted), 500);
|
|
21132
21222
|
}
|
|
21133
21223
|
function formatPackageValueOutputLines(packaged) {
|
|
21134
21224
|
const outputs = packaged.outputs && typeof packaged.outputs === "object" && !Array.isArray(packaged.outputs) ? packaged.outputs : null;
|
|
@@ -21461,12 +21551,12 @@ function exportableSheetRow(row) {
|
|
|
21461
21551
|
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
21462
21552
|
return null;
|
|
21463
21553
|
}
|
|
21464
|
-
const
|
|
21465
|
-
const data =
|
|
21554
|
+
const record3 = row;
|
|
21555
|
+
const data = record3.data;
|
|
21466
21556
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
21467
21557
|
return data;
|
|
21468
21558
|
}
|
|
21469
|
-
const fallback = { ...
|
|
21559
|
+
const fallback = { ...record3 };
|
|
21470
21560
|
for (const key of [
|
|
21471
21561
|
"key",
|
|
21472
21562
|
"status",
|
|
@@ -21814,8 +21904,8 @@ var PLAY_SYNTAX_MIGRATION_ERROR_MARKERS = [
|
|
|
21814
21904
|
"ctx.map(...) has been replaced by ctx.dataset(...)",
|
|
21815
21905
|
"Dataset .step(...) has been replaced by .withColumn(...)"
|
|
21816
21906
|
];
|
|
21817
|
-
function stringArrayField(
|
|
21818
|
-
const value =
|
|
21907
|
+
function stringArrayField(record3, key) {
|
|
21908
|
+
const value = record3[key];
|
|
21819
21909
|
if (!Array.isArray(value)) return [];
|
|
21820
21910
|
return value.filter((entry) => typeof entry === "string");
|
|
21821
21911
|
}
|
|
@@ -22646,8 +22736,8 @@ function cronExecutionLabel(status) {
|
|
|
22646
22736
|
return status;
|
|
22647
22737
|
}
|
|
22648
22738
|
function readLiveCronMetadata(play) {
|
|
22649
|
-
const
|
|
22650
|
-
const metadata = readRecord(
|
|
22739
|
+
const record3 = readRecord(play);
|
|
22740
|
+
const metadata = readRecord(record3?.triggerMetadata);
|
|
22651
22741
|
return {
|
|
22652
22742
|
schedule: typeof metadata?.cronSchedule === "string" ? metadata.cronSchedule : null,
|
|
22653
22743
|
timezone: typeof metadata?.cronTimezone === "string" ? metadata.cronTimezone : null,
|
|
@@ -27978,9 +28068,9 @@ async function expandCompiledConfigAtFiles(value) {
|
|
|
27978
28068
|
if (!value || typeof value !== "object") {
|
|
27979
28069
|
return value;
|
|
27980
28070
|
}
|
|
27981
|
-
const
|
|
28071
|
+
const record3 = value;
|
|
27982
28072
|
const expanded = {};
|
|
27983
|
-
for (const [key, entry] of Object.entries(
|
|
28073
|
+
for (const [key, entry] of Object.entries(record3)) {
|
|
27984
28074
|
expanded[key] = await expandCompiledConfigAtFiles(entry);
|
|
27985
28075
|
}
|
|
27986
28076
|
for (const field of ["extract_js", "run_if_js"]) {
|
|
@@ -28778,26 +28868,26 @@ function readFirstEnrichDatasetActions(value) {
|
|
|
28778
28868
|
}
|
|
28779
28869
|
return null;
|
|
28780
28870
|
}
|
|
28781
|
-
const
|
|
28782
|
-
const actions = isRecord11(
|
|
28871
|
+
const record3 = candidate;
|
|
28872
|
+
const actions = isRecord11(record3.actions) ? record3.actions : null;
|
|
28783
28873
|
const currentQuery = isRecord11(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
|
|
28784
28874
|
const legacyQuery = isRecord11(actions?.query) ? actions.query : null;
|
|
28785
28875
|
const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
|
|
28786
28876
|
if (query?.kind === "deepline_db_query") {
|
|
28787
28877
|
return {
|
|
28788
|
-
dataset:
|
|
28878
|
+
dataset: record3,
|
|
28789
28879
|
query,
|
|
28790
28880
|
...isRecord11(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
|
|
28791
28881
|
};
|
|
28792
28882
|
}
|
|
28793
|
-
if (options.allowLegacy &&
|
|
28883
|
+
if (options.allowLegacy && record3.kind === "dataset" && typeof record3.queryDatasetCommand === "string" && record3.queryDatasetCommand.trim()) {
|
|
28794
28884
|
return {
|
|
28795
|
-
dataset:
|
|
28796
|
-
queryDatasetCommand:
|
|
28797
|
-
...typeof
|
|
28885
|
+
dataset: record3,
|
|
28886
|
+
queryDatasetCommand: record3.queryDatasetCommand.trim(),
|
|
28887
|
+
...typeof record3.slowExportAsCsvCommand === "string" && record3.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record3.slowExportAsCsvCommand.trim() } : {}
|
|
28798
28888
|
};
|
|
28799
28889
|
}
|
|
28800
|
-
for (const [key, entry] of Object.entries(
|
|
28890
|
+
for (const [key, entry] of Object.entries(record3)) {
|
|
28801
28891
|
if (key === "preview") {
|
|
28802
28892
|
continue;
|
|
28803
28893
|
}
|
|
@@ -28813,8 +28903,8 @@ function readFirstEnrichDatasetActions(value) {
|
|
|
28813
28903
|
seen.clear();
|
|
28814
28904
|
return walk(value, { allowLegacy: true });
|
|
28815
28905
|
}
|
|
28816
|
-
function actionStringField(
|
|
28817
|
-
const value =
|
|
28906
|
+
function actionStringField(record3, key) {
|
|
28907
|
+
const value = record3[key];
|
|
28818
28908
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
28819
28909
|
}
|
|
28820
28910
|
function parseSqlFromDbQueryCommand(command) {
|
|
@@ -29158,12 +29248,12 @@ function collectStringFields(value, key, output2, depth = 0) {
|
|
|
29158
29248
|
}
|
|
29159
29249
|
return;
|
|
29160
29250
|
}
|
|
29161
|
-
const
|
|
29162
|
-
const direct =
|
|
29251
|
+
const record3 = value;
|
|
29252
|
+
const direct = record3[key];
|
|
29163
29253
|
if (typeof direct === "string" && direct.trim()) {
|
|
29164
29254
|
output2.add(direct.trim());
|
|
29165
29255
|
}
|
|
29166
|
-
for (const child of Object.values(
|
|
29256
|
+
for (const child of Object.values(record3)) {
|
|
29167
29257
|
collectStringFields(child, key, output2, depth + 1);
|
|
29168
29258
|
}
|
|
29169
29259
|
}
|
|
@@ -29349,23 +29439,23 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
|
|
|
29349
29439
|
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
29350
29440
|
return null;
|
|
29351
29441
|
}
|
|
29352
|
-
const
|
|
29353
|
-
const data =
|
|
29442
|
+
const record3 = row;
|
|
29443
|
+
const data = record3.data;
|
|
29354
29444
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
29355
29445
|
const exported = { ...data };
|
|
29356
29446
|
applyFailureCellMeta(exported, exported[ENRICH_CELL_META_FIELD], {
|
|
29357
|
-
rowError:
|
|
29447
|
+
rowError: record3.error
|
|
29358
29448
|
});
|
|
29359
|
-
applyFailureCellMeta(exported,
|
|
29360
|
-
applyFailureCellMeta(exported,
|
|
29361
|
-
rowError:
|
|
29449
|
+
applyFailureCellMeta(exported, record3.cellMeta, { rowError: record3.error });
|
|
29450
|
+
applyFailureCellMeta(exported, record3.cellMetaPatch, {
|
|
29451
|
+
rowError: record3.error
|
|
29362
29452
|
});
|
|
29363
|
-
applyFailureCellMeta(exported,
|
|
29364
|
-
rowError:
|
|
29453
|
+
applyFailureCellMeta(exported, record3[ENRICH_CELL_META_PATCH_FIELD], {
|
|
29454
|
+
rowError: record3.error
|
|
29365
29455
|
});
|
|
29366
29456
|
delete exported[ENRICH_CELL_META_FIELD];
|
|
29367
29457
|
delete exported[ENRICH_CELL_META_PATCH_FIELD];
|
|
29368
|
-
const inputIndex = typeof
|
|
29458
|
+
const inputIndex = typeof record3.inputIndex === "number" ? record3.inputIndex : typeof record3.inputIndex === "string" && record3.inputIndex.trim() ? Number(record3.inputIndex) : Number.NaN;
|
|
29369
29459
|
if (Number.isInteger(inputIndex) && inputIndex >= 0) {
|
|
29370
29460
|
if (ENRICH_SOURCE_ROW_INDEX_COLUMN in exported) {
|
|
29371
29461
|
exported[ENRICH_ORIGINAL_SOURCE_ROW_INDEX_COLUMN] = exported[ENRICH_SOURCE_ROW_INDEX_COLUMN];
|
|
@@ -29374,18 +29464,18 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
|
|
|
29374
29464
|
}
|
|
29375
29465
|
return exported;
|
|
29376
29466
|
}
|
|
29377
|
-
const fallback = { ...
|
|
29467
|
+
const fallback = { ...record3 };
|
|
29378
29468
|
applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_FIELD], {
|
|
29379
|
-
rowError:
|
|
29469
|
+
rowError: record3.error
|
|
29380
29470
|
});
|
|
29381
|
-
applyFailureCellMeta(fallback,
|
|
29382
|
-
rowError:
|
|
29471
|
+
applyFailureCellMeta(fallback, record3.cellMeta, {
|
|
29472
|
+
rowError: record3.error
|
|
29383
29473
|
});
|
|
29384
|
-
applyFailureCellMeta(fallback,
|
|
29385
|
-
rowError:
|
|
29474
|
+
applyFailureCellMeta(fallback, record3.cellMetaPatch, {
|
|
29475
|
+
rowError: record3.error
|
|
29386
29476
|
});
|
|
29387
29477
|
applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_PATCH_FIELD], {
|
|
29388
|
-
rowError:
|
|
29478
|
+
rowError: record3.error
|
|
29389
29479
|
});
|
|
29390
29480
|
for (const key of [
|
|
29391
29481
|
"key",
|
|
@@ -29604,16 +29694,16 @@ function isWaterfallResultMeaningful(value) {
|
|
|
29604
29694
|
return value.some(isWaterfallResultMeaningful);
|
|
29605
29695
|
}
|
|
29606
29696
|
if (value && typeof value === "object") {
|
|
29607
|
-
const
|
|
29608
|
-
const status = typeof
|
|
29697
|
+
const record3 = value;
|
|
29698
|
+
const status = typeof record3.status === "string" ? record3.status.trim().toLowerCase() : "";
|
|
29609
29699
|
if (status === "error" || status === "failed") {
|
|
29610
29700
|
return false;
|
|
29611
29701
|
}
|
|
29612
|
-
if (typeof
|
|
29702
|
+
if (typeof record3.error === "string" && record3.error.trim()) {
|
|
29613
29703
|
return false;
|
|
29614
29704
|
}
|
|
29615
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
29616
|
-
return isWaterfallResultMeaningful(
|
|
29705
|
+
if (Object.prototype.hasOwnProperty.call(record3, "matched_result")) {
|
|
29706
|
+
return isWaterfallResultMeaningful(record3.matched_result);
|
|
29617
29707
|
}
|
|
29618
29708
|
for (const key of [
|
|
29619
29709
|
"value",
|
|
@@ -29628,11 +29718,11 @@ function isWaterfallResultMeaningful(value) {
|
|
|
29628
29718
|
"result",
|
|
29629
29719
|
"data"
|
|
29630
29720
|
]) {
|
|
29631
|
-
if (isWaterfallResultMeaningful(
|
|
29721
|
+
if (isWaterfallResultMeaningful(record3[key])) {
|
|
29632
29722
|
return true;
|
|
29633
29723
|
}
|
|
29634
29724
|
}
|
|
29635
|
-
return Object.entries(
|
|
29725
|
+
return Object.entries(record3).some(
|
|
29636
29726
|
([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
|
|
29637
29727
|
);
|
|
29638
29728
|
}
|
|
@@ -29648,8 +29738,8 @@ function stableRowSnapshot(value) {
|
|
|
29648
29738
|
return `[${value.map(stableRowSnapshot).join(",")}]`;
|
|
29649
29739
|
}
|
|
29650
29740
|
if (value && typeof value === "object") {
|
|
29651
|
-
const
|
|
29652
|
-
return `{${Object.keys(
|
|
29741
|
+
const record3 = value;
|
|
29742
|
+
return `{${Object.keys(record3).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record3[key])}`).join(",")}}`;
|
|
29653
29743
|
}
|
|
29654
29744
|
return JSON.stringify(value);
|
|
29655
29745
|
}
|
|
@@ -30236,8 +30326,8 @@ function addEnrichFollowUpCommand(commands, seen, command) {
|
|
|
30236
30326
|
seen.add(normalized);
|
|
30237
30327
|
commands.push({ ...command, command: normalized });
|
|
30238
30328
|
}
|
|
30239
|
-
function datasetSelectorForEnrichCommand(
|
|
30240
|
-
const candidates = [
|
|
30329
|
+
function datasetSelectorForEnrichCommand(record3, fallbackPath) {
|
|
30330
|
+
const candidates = [record3.path, record3.tableNamespace, fallbackPath];
|
|
30241
30331
|
for (const candidate of candidates) {
|
|
30242
30332
|
if (typeof candidate === "string" && candidate.trim()) {
|
|
30243
30333
|
return candidate.trim();
|
|
@@ -30299,19 +30389,19 @@ function collectDatasetFollowUpCommands(value, state) {
|
|
|
30299
30389
|
);
|
|
30300
30390
|
return;
|
|
30301
30391
|
}
|
|
30302
|
-
const
|
|
30303
|
-
const isDataset =
|
|
30392
|
+
const record3 = value;
|
|
30393
|
+
const isDataset = record3.kind === "dataset";
|
|
30304
30394
|
if (isDataset) {
|
|
30305
|
-
const selector = datasetSelectorForEnrichCommand(
|
|
30306
|
-
const labelPath = typeof
|
|
30307
|
-
if (typeof
|
|
30395
|
+
const selector = datasetSelectorForEnrichCommand(record3, state.path);
|
|
30396
|
+
const labelPath = typeof record3.path === "string" && record3.path.trim() ? record3.path.trim() : selector ?? state.path;
|
|
30397
|
+
if (typeof record3.queryDatasetCommand === "string") {
|
|
30308
30398
|
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
30309
30399
|
label: `query ${labelPath}`,
|
|
30310
30400
|
path: labelPath,
|
|
30311
|
-
command:
|
|
30401
|
+
command: record3.queryDatasetCommand
|
|
30312
30402
|
});
|
|
30313
30403
|
}
|
|
30314
|
-
const exportCommand = typeof
|
|
30404
|
+
const exportCommand = typeof record3.slowExportAsCsvCommand === "string" ? record3.slowExportAsCsvCommand : typeof record3.fullExportCommand === "string" ? record3.fullExportCommand : null;
|
|
30315
30405
|
if (exportCommand) {
|
|
30316
30406
|
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
30317
30407
|
label: `export ${labelPath}`,
|
|
@@ -30328,7 +30418,7 @@ function collectDatasetFollowUpCommands(value, state) {
|
|
|
30328
30418
|
});
|
|
30329
30419
|
}
|
|
30330
30420
|
}
|
|
30331
|
-
for (const [key, child] of Object.entries(
|
|
30421
|
+
for (const [key, child] of Object.entries(record3)) {
|
|
30332
30422
|
if (key === "preview" || key === "access") {
|
|
30333
30423
|
continue;
|
|
30334
30424
|
}
|
|
@@ -31795,9 +31885,9 @@ function readCodexSessionId(filePath) {
|
|
|
31795
31885
|
)) {
|
|
31796
31886
|
const parsed = parseJsonLine(line);
|
|
31797
31887
|
if (!parsed || typeof parsed !== "object") continue;
|
|
31798
|
-
const
|
|
31799
|
-
const payload =
|
|
31800
|
-
const id =
|
|
31888
|
+
const record3 = parsed;
|
|
31889
|
+
const payload = record3.payload && typeof record3.payload === "object" ? record3.payload : null;
|
|
31890
|
+
const id = record3.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
|
|
31801
31891
|
if (id && UUID_RE.test(id)) return id;
|
|
31802
31892
|
}
|
|
31803
31893
|
} catch {
|
|
@@ -31896,15 +31986,15 @@ function messageContentKey(value) {
|
|
|
31896
31986
|
if (!Array.isArray(content)) return null;
|
|
31897
31987
|
return content.map((block) => {
|
|
31898
31988
|
if (!block || typeof block !== "object") return String(block);
|
|
31899
|
-
const
|
|
31900
|
-
const type = String(
|
|
31989
|
+
const record3 = block;
|
|
31990
|
+
const type = String(record3.type ?? "");
|
|
31901
31991
|
if (type === "tool_use") {
|
|
31902
|
-
return `tool_use:${String(
|
|
31992
|
+
return `tool_use:${String(record3.name ?? "")}:${String(record3.id ?? "")}`;
|
|
31903
31993
|
}
|
|
31904
31994
|
if (type === "tool_result") {
|
|
31905
|
-
return `tool_result:${String(
|
|
31995
|
+
return `tool_result:${String(record3.tool_use_id ?? "")}`;
|
|
31906
31996
|
}
|
|
31907
|
-
return String(
|
|
31997
|
+
return String(record3.text ?? type);
|
|
31908
31998
|
}).join("\n");
|
|
31909
31999
|
}
|
|
31910
32000
|
function dedupConsecutiveEvents(raw) {
|
|
@@ -31919,9 +32009,9 @@ function dedupConsecutiveEvents(raw) {
|
|
|
31919
32009
|
index += 1;
|
|
31920
32010
|
continue;
|
|
31921
32011
|
}
|
|
31922
|
-
const
|
|
31923
|
-
const eventType = String(
|
|
31924
|
-
const eventKey = messageContentKey(
|
|
32012
|
+
const record3 = event;
|
|
32013
|
+
const eventType = String(record3.type ?? "");
|
|
32014
|
+
const eventKey = messageContentKey(record3);
|
|
31925
32015
|
if (!["user", "assistant"].includes(eventType) || !eventKey) {
|
|
31926
32016
|
output2.push(rawLines[index] ?? "");
|
|
31927
32017
|
index += 1;
|
|
@@ -31940,9 +32030,9 @@ function dedupConsecutiveEvents(raw) {
|
|
|
31940
32030
|
cursor += 1;
|
|
31941
32031
|
}
|
|
31942
32032
|
if (runCount > 1) {
|
|
31943
|
-
|
|
31944
|
-
|
|
31945
|
-
output2.push(JSON.stringify(
|
|
32033
|
+
record3._repeat_count = runCount;
|
|
32034
|
+
record3._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
|
|
32035
|
+
output2.push(JSON.stringify(record3));
|
|
31946
32036
|
index = cursor;
|
|
31947
32037
|
continue;
|
|
31948
32038
|
}
|
|
@@ -31987,9 +32077,9 @@ function selectiveCompactToolResults(raw) {
|
|
|
31987
32077
|
lines.push(line);
|
|
31988
32078
|
continue;
|
|
31989
32079
|
}
|
|
31990
|
-
const
|
|
31991
|
-
if (
|
|
31992
|
-
const message =
|
|
32080
|
+
const record3 = parsed;
|
|
32081
|
+
if (record3.type === "user") {
|
|
32082
|
+
const message = record3.message;
|
|
31993
32083
|
const content = message && typeof message === "object" ? message.content : null;
|
|
31994
32084
|
if (Array.isArray(content)) {
|
|
31995
32085
|
message.content = content.map(
|
|
@@ -31997,7 +32087,7 @@ function selectiveCompactToolResults(raw) {
|
|
|
31997
32087
|
);
|
|
31998
32088
|
}
|
|
31999
32089
|
}
|
|
32000
|
-
lines.push(JSON.stringify(
|
|
32090
|
+
lines.push(JSON.stringify(record3));
|
|
32001
32091
|
}
|
|
32002
32092
|
return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
|
|
32003
32093
|
` : "", "utf8");
|
|
@@ -32023,15 +32113,15 @@ function compactCodexEvents(raw) {
|
|
|
32023
32113
|
lines.push(rawLines[index] ?? "");
|
|
32024
32114
|
return;
|
|
32025
32115
|
}
|
|
32026
|
-
const
|
|
32027
|
-
if (
|
|
32028
|
-
const payload =
|
|
32116
|
+
const record3 = event;
|
|
32117
|
+
if (record3.type === "world_state") return;
|
|
32118
|
+
const payload = record3.payload;
|
|
32029
32119
|
const payloadType = payload && typeof payload === "object" ? String(payload.type ?? "") : "";
|
|
32030
32120
|
if (payloadType === "token_count" && index !== lastTokenCountIndex) return;
|
|
32031
32121
|
if (payloadType === "custom_tool_call_output" || payloadType === "function_call_output" || payloadType === "tool_search_output") {
|
|
32032
32122
|
const record_payload = payload;
|
|
32033
32123
|
record_payload.output = compactEventValue(record_payload.output);
|
|
32034
|
-
lines.push(JSON.stringify(
|
|
32124
|
+
lines.push(JSON.stringify(record3));
|
|
32035
32125
|
return;
|
|
32036
32126
|
}
|
|
32037
32127
|
lines.push(rawLines[index] ?? "");
|
|
@@ -32237,8 +32327,8 @@ function parsePreparedEvents(buffer) {
|
|
|
32237
32327
|
return parsed ?? line;
|
|
32238
32328
|
});
|
|
32239
32329
|
}
|
|
32240
|
-
function escapeJsonForHtmlScript(
|
|
32241
|
-
return
|
|
32330
|
+
function escapeJsonForHtmlScript(json2) {
|
|
32331
|
+
return json2.replace(/</g, "\\u003c");
|
|
32242
32332
|
}
|
|
32243
32333
|
async function handleSessionsRender(options) {
|
|
32244
32334
|
const targets = resolveSessionTargets({
|
|
@@ -32499,11 +32589,317 @@ var import_node_fs15 = require("fs");
|
|
|
32499
32589
|
var import_node_path17 = require("path");
|
|
32500
32590
|
var import_promises8 = require("readline/promises");
|
|
32501
32591
|
|
|
32592
|
+
// ../integration-contracts/monitor-input-contract.ts
|
|
32593
|
+
var import_handlebars = __toESM(require("handlebars"), 1);
|
|
32594
|
+
function authoredMonitorFieldPath(path, field) {
|
|
32595
|
+
const batch = /^monitors\.(\d+)$/.exec(path);
|
|
32596
|
+
return `${batch ? `monitors[${batch[1]}]` : path}.${field}`;
|
|
32597
|
+
}
|
|
32598
|
+
function record(value) {
|
|
32599
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
32600
|
+
}
|
|
32601
|
+
function json(value, path, issues) {
|
|
32602
|
+
if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
|
|
32603
|
+
return;
|
|
32604
|
+
}
|
|
32605
|
+
if (Array.isArray(value)) {
|
|
32606
|
+
value.forEach((child, index) => json(child, `${path}.${index}`, issues));
|
|
32607
|
+
return;
|
|
32608
|
+
}
|
|
32609
|
+
const object = record(value);
|
|
32610
|
+
if (!object) {
|
|
32611
|
+
issues.push({
|
|
32612
|
+
severity: "error",
|
|
32613
|
+
code: "invalid_monitor_json_value",
|
|
32614
|
+
path,
|
|
32615
|
+
message: "Monitor values must be JSON values."
|
|
32616
|
+
});
|
|
32617
|
+
return;
|
|
32618
|
+
}
|
|
32619
|
+
for (const [key, child] of Object.entries(object)) {
|
|
32620
|
+
json(child, `${path}.${key}`, issues);
|
|
32621
|
+
}
|
|
32622
|
+
}
|
|
32623
|
+
function monitorSpec(value, path, issues) {
|
|
32624
|
+
const input2 = record(value);
|
|
32625
|
+
if (!input2) {
|
|
32626
|
+
issues.push({
|
|
32627
|
+
severity: "error",
|
|
32628
|
+
code: "invalid_monitor_spec",
|
|
32629
|
+
path,
|
|
32630
|
+
message: "A monitor must be a JSON object."
|
|
32631
|
+
});
|
|
32632
|
+
return null;
|
|
32633
|
+
}
|
|
32634
|
+
const allowed = /* @__PURE__ */ new Set(["key", "tool", "name", "payload"]);
|
|
32635
|
+
for (const key2 of Object.keys(input2)) {
|
|
32636
|
+
if (!allowed.has(key2)) {
|
|
32637
|
+
if (key2 === "controls") {
|
|
32638
|
+
issues.push({
|
|
32639
|
+
severity: "error",
|
|
32640
|
+
code: "CONTROLS_NOT_SUPPORTED",
|
|
32641
|
+
path: authoredMonitorFieldPath(path, "controls"),
|
|
32642
|
+
message: "Operational controls are managed by Deepline and cannot be authored in Batch or Fleet JSON.",
|
|
32643
|
+
suggestion: "Remove controls. Bind downstream automation in a Play with sqlListeners."
|
|
32644
|
+
});
|
|
32645
|
+
continue;
|
|
32646
|
+
}
|
|
32647
|
+
if (key2 === "play") {
|
|
32648
|
+
issues.push({
|
|
32649
|
+
severity: "error",
|
|
32650
|
+
code: "PLAY_BINDING_NOT_IN_MONITOR_SPEC",
|
|
32651
|
+
path: authoredMonitorFieldPath(path, "play"),
|
|
32652
|
+
message: "A monitor does not own Play bindings.",
|
|
32653
|
+
suggestion: "Declare sqlListeners in the Play, or run: deepline plays bootstrap monitor-triggered --out on-event.play.ts"
|
|
32654
|
+
});
|
|
32655
|
+
continue;
|
|
32656
|
+
}
|
|
32657
|
+
issues.push({
|
|
32658
|
+
severity: "error",
|
|
32659
|
+
code: "unknown_monitor_field",
|
|
32660
|
+
path: `${path}.${key2}`,
|
|
32661
|
+
message: `Monitor definitions do not accept '${key2}'.`
|
|
32662
|
+
});
|
|
32663
|
+
}
|
|
32664
|
+
}
|
|
32665
|
+
const key = typeof input2.key === "string" ? input2.key.trim() : "";
|
|
32666
|
+
const tool = typeof input2.tool === "string" ? input2.tool.trim() : "";
|
|
32667
|
+
const name = input2.name === void 0 ? void 0 : typeof input2.name === "string" && input2.name.trim() ? input2.name.trim() : null;
|
|
32668
|
+
const payload = record(input2.payload);
|
|
32669
|
+
if (!key) {
|
|
32670
|
+
issues.push({
|
|
32671
|
+
severity: "error",
|
|
32672
|
+
code: "invalid_monitor_key",
|
|
32673
|
+
path: `${path}.key`,
|
|
32674
|
+
message: "Monitor key must be a non-empty string."
|
|
32675
|
+
});
|
|
32676
|
+
}
|
|
32677
|
+
if (!tool) {
|
|
32678
|
+
issues.push({
|
|
32679
|
+
severity: "error",
|
|
32680
|
+
code: "invalid_monitor_tool",
|
|
32681
|
+
path: `${path}.tool`,
|
|
32682
|
+
message: "Monitor tool must be a non-empty literal string."
|
|
32683
|
+
});
|
|
32684
|
+
}
|
|
32685
|
+
if (name === null) {
|
|
32686
|
+
issues.push({
|
|
32687
|
+
severity: "error",
|
|
32688
|
+
code: "invalid_monitor_name",
|
|
32689
|
+
path: `${path}.name`,
|
|
32690
|
+
message: "Monitor name must be a non-empty string when supplied."
|
|
32691
|
+
});
|
|
32692
|
+
}
|
|
32693
|
+
if (!payload) {
|
|
32694
|
+
issues.push({
|
|
32695
|
+
severity: "error",
|
|
32696
|
+
code: "invalid_monitor_payload",
|
|
32697
|
+
path: `${path}.payload`,
|
|
32698
|
+
message: "Monitor payload must be an object."
|
|
32699
|
+
});
|
|
32700
|
+
} else {
|
|
32701
|
+
json(payload, `${path}.payload`, issues);
|
|
32702
|
+
}
|
|
32703
|
+
if (!key || !tool || !payload || name === null) {
|
|
32704
|
+
return null;
|
|
32705
|
+
}
|
|
32706
|
+
return {
|
|
32707
|
+
key,
|
|
32708
|
+
tool,
|
|
32709
|
+
...name ? { name } : {},
|
|
32710
|
+
payload
|
|
32711
|
+
};
|
|
32712
|
+
}
|
|
32713
|
+
function issueOrder(left, right) {
|
|
32714
|
+
return left.path.localeCompare(right.path) || left.severity.localeCompare(right.severity) || left.code.localeCompare(right.code);
|
|
32715
|
+
}
|
|
32716
|
+
function lintMonitorBatchInput(value) {
|
|
32717
|
+
const issues = [];
|
|
32718
|
+
const versionlessEnvelope = !Array.isArray(value) && (() => {
|
|
32719
|
+
const candidate = record(value);
|
|
32720
|
+
return candidate !== null && Object.keys(candidate).length === 1 && Object.prototype.hasOwnProperty.call(candidate, "monitors");
|
|
32721
|
+
})();
|
|
32722
|
+
const legacy = Array.isArray(value) || versionlessEnvelope;
|
|
32723
|
+
const input2 = legacy ? null : record(value);
|
|
32724
|
+
let monitors = Array.isArray(value) ? value : versionlessEnvelope ? (() => {
|
|
32725
|
+
const candidate = record(value)?.monitors;
|
|
32726
|
+
return Array.isArray(candidate) ? candidate : null;
|
|
32727
|
+
})() : null;
|
|
32728
|
+
if (Array.isArray(value)) {
|
|
32729
|
+
issues.push({
|
|
32730
|
+
severity: "warning",
|
|
32731
|
+
code: "deprecated_batch_array",
|
|
32732
|
+
path: "",
|
|
32733
|
+
message: "Bare monitor arrays are supported for compatibility.",
|
|
32734
|
+
suggestion: 'Wrap the list in {"version":1,"kind":"batch","monitors":[...]}.'
|
|
32735
|
+
});
|
|
32736
|
+
} else if (versionlessEnvelope) {
|
|
32737
|
+
issues.push({
|
|
32738
|
+
severity: "warning",
|
|
32739
|
+
code: "deprecated_batch_missing_envelope_fields",
|
|
32740
|
+
path: "",
|
|
32741
|
+
message: "Versionless monitor envelopes are supported for compatibility.",
|
|
32742
|
+
suggestion: 'Add "version": 1 and "kind": "batch".'
|
|
32743
|
+
});
|
|
32744
|
+
if (!monitors) {
|
|
32745
|
+
issues.push({
|
|
32746
|
+
severity: "error",
|
|
32747
|
+
code: "invalid_batch_monitors",
|
|
32748
|
+
path: "monitors",
|
|
32749
|
+
message: "Batch monitors must be an array."
|
|
32750
|
+
});
|
|
32751
|
+
}
|
|
32752
|
+
} else if (!input2) {
|
|
32753
|
+
issues.push({
|
|
32754
|
+
severity: "error",
|
|
32755
|
+
code: "invalid_batch",
|
|
32756
|
+
path: "",
|
|
32757
|
+
message: "Batch input must be an object or a legacy array."
|
|
32758
|
+
});
|
|
32759
|
+
} else {
|
|
32760
|
+
for (const key of Object.keys(input2)) {
|
|
32761
|
+
if (!["version", "kind", "monitors"].includes(key)) {
|
|
32762
|
+
issues.push({
|
|
32763
|
+
severity: "error",
|
|
32764
|
+
code: key === "source" || key === "monitor" ? "batch_fleet_shape_mixup" : "unknown_batch_field",
|
|
32765
|
+
path: key,
|
|
32766
|
+
message: `Batch input does not accept '${key}'.`
|
|
32767
|
+
});
|
|
32768
|
+
}
|
|
32769
|
+
}
|
|
32770
|
+
if (input2.version !== 1) {
|
|
32771
|
+
issues.push({
|
|
32772
|
+
severity: "error",
|
|
32773
|
+
code: "unsupported_batch_version",
|
|
32774
|
+
path: "version",
|
|
32775
|
+
message: "Batch input version must be 1."
|
|
32776
|
+
});
|
|
32777
|
+
}
|
|
32778
|
+
if (input2.kind !== "batch") {
|
|
32779
|
+
issues.push({
|
|
32780
|
+
severity: "error",
|
|
32781
|
+
code: "invalid_batch_kind",
|
|
32782
|
+
path: "kind",
|
|
32783
|
+
message: 'Batch input kind must be "batch".'
|
|
32784
|
+
});
|
|
32785
|
+
}
|
|
32786
|
+
monitors = Array.isArray(input2.monitors) ? input2.monitors : null;
|
|
32787
|
+
if (!monitors) {
|
|
32788
|
+
issues.push({
|
|
32789
|
+
severity: "error",
|
|
32790
|
+
code: "invalid_batch_monitors",
|
|
32791
|
+
path: "monitors",
|
|
32792
|
+
message: "Batch monitors must be an array."
|
|
32793
|
+
});
|
|
32794
|
+
}
|
|
32795
|
+
}
|
|
32796
|
+
if (!monitors || monitors.length === 0) {
|
|
32797
|
+
if (monitors?.length === 0) {
|
|
32798
|
+
issues.push({
|
|
32799
|
+
severity: "error",
|
|
32800
|
+
code: "empty_batch",
|
|
32801
|
+
path: "monitors",
|
|
32802
|
+
message: "A Batch needs at least one monitor."
|
|
32803
|
+
});
|
|
32804
|
+
}
|
|
32805
|
+
return { issues: issues.sort(issueOrder) };
|
|
32806
|
+
}
|
|
32807
|
+
const normalized = monitors.map(
|
|
32808
|
+
(item, index) => monitorSpec(item, `monitors.${index}`, issues)
|
|
32809
|
+
);
|
|
32810
|
+
const seen = /* @__PURE__ */ new Map();
|
|
32811
|
+
normalized.forEach((item, index) => {
|
|
32812
|
+
if (!item) return;
|
|
32813
|
+
const first = seen.get(item.key);
|
|
32814
|
+
if (first !== void 0) {
|
|
32815
|
+
for (const position of [first, index]) {
|
|
32816
|
+
issues.push({
|
|
32817
|
+
severity: "error",
|
|
32818
|
+
code: "duplicate_monitor_key",
|
|
32819
|
+
path: `monitors.${position}.key`,
|
|
32820
|
+
message: `Duplicate monitor key '${item.key}'.`
|
|
32821
|
+
});
|
|
32822
|
+
}
|
|
32823
|
+
} else {
|
|
32824
|
+
seen.set(item.key, index);
|
|
32825
|
+
}
|
|
32826
|
+
});
|
|
32827
|
+
const ordered = issues.sort(issueOrder);
|
|
32828
|
+
return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : {
|
|
32829
|
+
normalized: {
|
|
32830
|
+
version: 1,
|
|
32831
|
+
kind: "batch",
|
|
32832
|
+
monitors: normalized
|
|
32833
|
+
},
|
|
32834
|
+
issues: ordered
|
|
32835
|
+
};
|
|
32836
|
+
}
|
|
32837
|
+
function validateHandlebars(value, path, issues) {
|
|
32838
|
+
if (!value.includes("{{")) return;
|
|
32839
|
+
try {
|
|
32840
|
+
import_handlebars.default.parse(value);
|
|
32841
|
+
} catch (error) {
|
|
32842
|
+
issues.push({
|
|
32843
|
+
severity: "error",
|
|
32844
|
+
code: "invalid_handlebars_template",
|
|
32845
|
+
path,
|
|
32846
|
+
message: error instanceof Error ? error.message : "Invalid Handlebars template."
|
|
32847
|
+
});
|
|
32848
|
+
return;
|
|
32849
|
+
}
|
|
32850
|
+
const expressions = value.match(/{{[\s\S]*?}}/g) ?? [];
|
|
32851
|
+
if (expressions.some(
|
|
32852
|
+
(expression) => !/^{{\s*[A-Za-z_][A-Za-z0-9_]*\s*}}$/.test(expression)
|
|
32853
|
+
)) {
|
|
32854
|
+
issues.push({
|
|
32855
|
+
severity: "error",
|
|
32856
|
+
code: "unsupported_handlebars_expression",
|
|
32857
|
+
path,
|
|
32858
|
+
message: "Fleet templates allow only direct source-row fields such as {{domain}}; helpers, blocks, partials, paths, and prototype access are disabled."
|
|
32859
|
+
});
|
|
32860
|
+
}
|
|
32861
|
+
}
|
|
32862
|
+
function walkTemplates(value, path, issues) {
|
|
32863
|
+
if (typeof value === "string") return validateHandlebars(value, path, issues);
|
|
32864
|
+
if (Array.isArray(value)) {
|
|
32865
|
+
value.forEach(
|
|
32866
|
+
(item, index) => walkTemplates(item, `${path}.${index}`, issues)
|
|
32867
|
+
);
|
|
32868
|
+
return;
|
|
32869
|
+
}
|
|
32870
|
+
const input2 = record(value);
|
|
32871
|
+
if (!input2) return;
|
|
32872
|
+
for (const [key, child] of Object.entries(input2)) {
|
|
32873
|
+
walkTemplates(child, `${path}.${key}`, issues);
|
|
32874
|
+
}
|
|
32875
|
+
}
|
|
32876
|
+
function lintMonitorSpecTemplate(value, path = "monitor") {
|
|
32877
|
+
const issues = [];
|
|
32878
|
+
const normalized = monitorSpec(value, path, issues);
|
|
32879
|
+
const input2 = record(value);
|
|
32880
|
+
if (input2 && typeof input2.tool === "string" && input2.tool.includes("{{")) {
|
|
32881
|
+
issues.push({
|
|
32882
|
+
severity: "error",
|
|
32883
|
+
code: "templated_monitor_tool",
|
|
32884
|
+
path: `${path}.tool`,
|
|
32885
|
+
message: "Fleet monitor tool must be literal; only key, name, and payload may be templated."
|
|
32886
|
+
});
|
|
32887
|
+
}
|
|
32888
|
+
if (input2) {
|
|
32889
|
+
for (const field of ["key", "name", "payload"]) {
|
|
32890
|
+
if (input2[field] !== void 0)
|
|
32891
|
+
walkTemplates(input2[field], `${path}.${field}`, issues);
|
|
32892
|
+
}
|
|
32893
|
+
}
|
|
32894
|
+
const ordered = issues.sort(issueOrder);
|
|
32895
|
+
return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : { normalized, issues: ordered };
|
|
32896
|
+
}
|
|
32897
|
+
|
|
32502
32898
|
// ../integration-contracts/monitor-fleet-contract.ts
|
|
32503
32899
|
var MONITOR_FLEET_MAX_MEMBERS = 1e3;
|
|
32504
|
-
var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
|
|
32505
32900
|
var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
|
|
32506
|
-
|
|
32901
|
+
1,
|
|
32902
|
+
2
|
|
32507
32903
|
];
|
|
32508
32904
|
var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
|
|
32509
32905
|
var MONITOR_FLEET_DOCUMENTATION = {
|
|
@@ -32511,11 +32907,11 @@ var MONITOR_FLEET_DOCUMENTATION = {
|
|
|
32511
32907
|
authoredFields: {
|
|
32512
32908
|
id: "Stable lowercase fleet id used by sync, get, and deactivate.",
|
|
32513
32909
|
source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
|
|
32514
|
-
|
|
32910
|
+
monitor: "One Batch-compatible MonitorSpec. Direct Handlebars source-row fields such as {{domain}} are rendered for each selected row.",
|
|
32515
32911
|
selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
|
|
32516
32912
|
},
|
|
32517
32913
|
fixedPolicy: {
|
|
32518
|
-
cadence: "
|
|
32914
|
+
cadence: "60s fair bounded source refresh",
|
|
32519
32915
|
membership: "sticky",
|
|
32520
32916
|
removalGrace: "7d",
|
|
32521
32917
|
onRemoved: "deactivate",
|
|
@@ -32523,9 +32919,10 @@ var MONITOR_FLEET_DOCUMENTATION = {
|
|
|
32523
32919
|
billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
|
|
32524
32920
|
},
|
|
32525
32921
|
stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
|
|
32526
|
-
|
|
32922
|
+
templating: "Use direct Handlebars fields such as {{domain}} in monitor key, name, or payload. Helpers, blocks, partials, paths, and prototype access are disabled.",
|
|
32923
|
+
legacyCompatibility: 'Edition 1 member/$fleet files remain readable with a lint warning; new files should use version: 2, kind: "fleet", and monitor.'
|
|
32527
32924
|
};
|
|
32528
|
-
function
|
|
32925
|
+
function record2(value) {
|
|
32529
32926
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
32530
32927
|
}
|
|
32531
32928
|
function identifier(value) {
|
|
@@ -32550,7 +32947,7 @@ function jsonValue(value, path, issues) {
|
|
|
32550
32947
|
value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
|
|
32551
32948
|
return;
|
|
32552
32949
|
}
|
|
32553
|
-
const input2 =
|
|
32950
|
+
const input2 = record2(value);
|
|
32554
32951
|
if (!input2) {
|
|
32555
32952
|
issues.push({
|
|
32556
32953
|
path,
|
|
@@ -32564,7 +32961,7 @@ function jsonValue(value, path, issues) {
|
|
|
32564
32961
|
}
|
|
32565
32962
|
}
|
|
32566
32963
|
function validateExpression(value, path, issues) {
|
|
32567
|
-
const input2 =
|
|
32964
|
+
const input2 = record2(value);
|
|
32568
32965
|
if (!input2 || input2.$fleet !== "column" || !identifier(input2.name)) {
|
|
32569
32966
|
issues.push({
|
|
32570
32967
|
path,
|
|
@@ -32582,7 +32979,7 @@ function walkPayload(value, path, issues) {
|
|
|
32582
32979
|
);
|
|
32583
32980
|
return;
|
|
32584
32981
|
}
|
|
32585
|
-
const input2 =
|
|
32982
|
+
const input2 = record2(value);
|
|
32586
32983
|
if (!input2) return;
|
|
32587
32984
|
if ("$fleet" in input2) {
|
|
32588
32985
|
validateExpression(input2, path, issues);
|
|
@@ -32592,9 +32989,9 @@ function walkPayload(value, path, issues) {
|
|
|
32592
32989
|
walkPayload(item, `${path}.${key}`, issues);
|
|
32593
32990
|
}
|
|
32594
32991
|
}
|
|
32595
|
-
function
|
|
32992
|
+
function validateMonitorFleetDefinitionV1(value) {
|
|
32596
32993
|
const issues = [];
|
|
32597
|
-
const input2 =
|
|
32994
|
+
const input2 = record2(value);
|
|
32598
32995
|
if (!input2) {
|
|
32599
32996
|
return {
|
|
32600
32997
|
valid: false,
|
|
@@ -32615,7 +33012,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32615
33012
|
message: "Fleet id must be lowercase kebab-case."
|
|
32616
33013
|
});
|
|
32617
33014
|
}
|
|
32618
|
-
const source =
|
|
33015
|
+
const source = record2(input2.source);
|
|
32619
33016
|
exactKeys(
|
|
32620
33017
|
source,
|
|
32621
33018
|
["kind", "schema", "table", "key", "where"],
|
|
@@ -32636,7 +33033,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32636
33033
|
message: "Source schema and table must be SQL identifiers."
|
|
32637
33034
|
});
|
|
32638
33035
|
}
|
|
32639
|
-
const sourceKey =
|
|
33036
|
+
const sourceKey = record2(source?.key);
|
|
32640
33037
|
exactKeys(sourceKey, ["column", "type"], "source.key", issues);
|
|
32641
33038
|
if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
|
|
32642
33039
|
issues.push({
|
|
@@ -32646,7 +33043,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32646
33043
|
});
|
|
32647
33044
|
}
|
|
32648
33045
|
if (source?.where !== void 0) {
|
|
32649
|
-
const where =
|
|
33046
|
+
const where = record2(source.where);
|
|
32650
33047
|
if (!where) {
|
|
32651
33048
|
issues.push({
|
|
32652
33049
|
path: "source.where",
|
|
@@ -32672,9 +33069,9 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32672
33069
|
}
|
|
32673
33070
|
}
|
|
32674
33071
|
}
|
|
32675
|
-
const member =
|
|
33072
|
+
const member = record2(input2.member);
|
|
32676
33073
|
exactKeys(member, ["tool", "key", "payload"], "member", issues);
|
|
32677
|
-
const key =
|
|
33074
|
+
const key = record2(member?.key);
|
|
32678
33075
|
if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
|
|
32679
33076
|
issues.push({
|
|
32680
33077
|
path: "member.tool",
|
|
@@ -32695,7 +33092,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32695
33092
|
validateExpression(part, `member.key.parts.${index}`, issues);
|
|
32696
33093
|
}
|
|
32697
33094
|
if (sourceKey && !key.parts.some(
|
|
32698
|
-
(part) =>
|
|
33095
|
+
(part) => record2(part)?.$fleet === "column" && record2(part)?.name === sourceKey.column
|
|
32699
33096
|
)) {
|
|
32700
33097
|
issues.push({
|
|
32701
33098
|
path: "member.key.parts",
|
|
@@ -32714,7 +33111,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32714
33111
|
jsonValue(member.payload, "member.payload", issues);
|
|
32715
33112
|
}
|
|
32716
33113
|
walkPayload(member?.payload, "member.payload", issues);
|
|
32717
|
-
const selection =
|
|
33114
|
+
const selection = record2(input2.selection);
|
|
32718
33115
|
exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
|
|
32719
33116
|
if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
|
|
32720
33117
|
issues.push({
|
|
@@ -32740,7 +33137,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32740
33137
|
} else {
|
|
32741
33138
|
const orderColumns = /* @__PURE__ */ new Set();
|
|
32742
33139
|
for (const [index, order] of orderBy.entries()) {
|
|
32743
|
-
const item =
|
|
33140
|
+
const item = record2(order);
|
|
32744
33141
|
exactKeys(
|
|
32745
33142
|
item,
|
|
32746
33143
|
["column", "direction"],
|
|
@@ -32763,7 +33160,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32763
33160
|
orderColumns.add(item.column);
|
|
32764
33161
|
}
|
|
32765
33162
|
}
|
|
32766
|
-
if (sourceKey &&
|
|
33163
|
+
if (sourceKey && record2(orderBy.at(-1))?.column !== sourceKey.column) {
|
|
32767
33164
|
issues.push({
|
|
32768
33165
|
path: "selection.orderBy",
|
|
32769
33166
|
code: "fleet_order_missing_key",
|
|
@@ -32782,9 +33179,100 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32782
33179
|
}
|
|
32783
33180
|
return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
|
|
32784
33181
|
}
|
|
32785
|
-
function
|
|
33182
|
+
function v2Issue(issue) {
|
|
33183
|
+
return { path: issue.path, code: issue.code, message: issue.message };
|
|
33184
|
+
}
|
|
33185
|
+
function validateMonitorFleetDefinitionV2(value) {
|
|
33186
|
+
const issues = [];
|
|
33187
|
+
const input2 = record2(value);
|
|
33188
|
+
if (!input2) {
|
|
33189
|
+
return {
|
|
33190
|
+
valid: false,
|
|
33191
|
+
issues: [
|
|
33192
|
+
{
|
|
33193
|
+
path: "",
|
|
33194
|
+
code: "invalid_fleet",
|
|
33195
|
+
message: "Fleet must be an object."
|
|
33196
|
+
}
|
|
33197
|
+
]
|
|
33198
|
+
};
|
|
33199
|
+
}
|
|
33200
|
+
exactKeys(
|
|
33201
|
+
input2,
|
|
33202
|
+
["version", "kind", "id", "source", "monitor", "selection"],
|
|
33203
|
+
"",
|
|
33204
|
+
issues
|
|
33205
|
+
);
|
|
33206
|
+
if (input2.version !== 2) {
|
|
33207
|
+
issues.push({
|
|
33208
|
+
path: "version",
|
|
33209
|
+
code: "unsupported_fleet_version",
|
|
33210
|
+
message: "Canonical Fleet input version must be 2."
|
|
33211
|
+
});
|
|
33212
|
+
}
|
|
33213
|
+
if (input2.kind !== "fleet") {
|
|
33214
|
+
issues.push({
|
|
33215
|
+
path: "kind",
|
|
33216
|
+
code: "invalid_fleet_kind",
|
|
33217
|
+
message: 'Canonical Fleet input kind must be "fleet".'
|
|
33218
|
+
});
|
|
33219
|
+
}
|
|
33220
|
+
const source = record2(input2.source);
|
|
33221
|
+
const sourceKey = record2(source?.key);
|
|
33222
|
+
const legacyShape = {
|
|
33223
|
+
id: input2.id,
|
|
33224
|
+
source: input2.source,
|
|
33225
|
+
member: {
|
|
33226
|
+
tool: record2(input2.monitor)?.tool,
|
|
33227
|
+
key: {
|
|
33228
|
+
$fleet: "template",
|
|
33229
|
+
parts: [
|
|
33230
|
+
"fleet-",
|
|
33231
|
+
{
|
|
33232
|
+
$fleet: "column",
|
|
33233
|
+
name: typeof sourceKey?.column === "string" ? sourceKey.column : "invalid_source_key"
|
|
33234
|
+
}
|
|
33235
|
+
]
|
|
33236
|
+
},
|
|
33237
|
+
payload: record2(input2.monitor)?.payload
|
|
33238
|
+
},
|
|
33239
|
+
selection: input2.selection
|
|
33240
|
+
};
|
|
33241
|
+
const legacyCheck = validateMonitorFleetDefinitionV1(legacyShape);
|
|
33242
|
+
for (const issue of legacyCheck.issues) {
|
|
33243
|
+
issues.push({
|
|
33244
|
+
...issue,
|
|
33245
|
+
path: issue.path.replace(/^member\./, "monitor.")
|
|
33246
|
+
});
|
|
33247
|
+
}
|
|
33248
|
+
const monitorInput = record2(input2.monitor);
|
|
33249
|
+
const monitorKey = monitorInput?.key;
|
|
33250
|
+
const monitor = lintMonitorSpecTemplate(input2.monitor);
|
|
33251
|
+
issues.push(...monitor.issues.map(v2Issue));
|
|
33252
|
+
if (typeof monitorKey === "string" && typeof sourceKey?.column === "string" && !monitorKey.includes(`{{${sourceKey.column}}}`)) {
|
|
33253
|
+
issues.push({
|
|
33254
|
+
path: "monitor.key",
|
|
33255
|
+
code: "fleet_key_missing_source_key",
|
|
33256
|
+
message: "Monitor key must include the source key as a direct Handlebars expression."
|
|
33257
|
+
});
|
|
33258
|
+
}
|
|
33259
|
+
return issues.length === 0 && monitor.normalized ? {
|
|
33260
|
+
valid: true,
|
|
33261
|
+
definition: {
|
|
33262
|
+
version: 2,
|
|
33263
|
+
kind: "fleet",
|
|
33264
|
+
id: String(input2.id),
|
|
33265
|
+
source: input2.source,
|
|
33266
|
+
monitor: monitor.normalized,
|
|
33267
|
+
selection: input2.selection
|
|
33268
|
+
},
|
|
33269
|
+
issues
|
|
33270
|
+
} : { valid: false, issues };
|
|
33271
|
+
}
|
|
33272
|
+
function admitMonitorFleetAuthoringContract(value, edition) {
|
|
33273
|
+
const detectedEdition = edition ?? (record2(value)?.version === 2 || record2(value)?.kind === "fleet" ? 2 : 1);
|
|
32786
33274
|
if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
|
|
32787
|
-
|
|
33275
|
+
detectedEdition
|
|
32788
33276
|
)) {
|
|
32789
33277
|
return {
|
|
32790
33278
|
valid: false,
|
|
@@ -32792,16 +33280,16 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
|
|
|
32792
33280
|
{
|
|
32793
33281
|
path: "authoring_contract_edition",
|
|
32794
33282
|
code: "unsupported_fleet_authoring_contract_edition",
|
|
32795
|
-
message: `Monitor Fleet authoring contract edition ${
|
|
33283
|
+
message: `Monitor Fleet authoring contract edition ${detectedEdition} is not supported.`
|
|
32796
33284
|
}
|
|
32797
33285
|
]
|
|
32798
33286
|
};
|
|
32799
33287
|
}
|
|
32800
|
-
const result =
|
|
33288
|
+
const result = detectedEdition === 2 ? validateMonitorFleetDefinitionV2(value) : validateMonitorFleetDefinitionV1(value);
|
|
32801
33289
|
return result.valid && result.definition ? {
|
|
32802
33290
|
valid: true,
|
|
32803
33291
|
contract: {
|
|
32804
|
-
edition,
|
|
33292
|
+
edition: detectedEdition,
|
|
32805
33293
|
// JSON cloning prevents later caller mutation from changing the
|
|
32806
33294
|
// admitted snapshot.
|
|
32807
33295
|
definition: JSON.parse(
|
|
@@ -32811,6 +33299,32 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
|
|
|
32811
33299
|
issues: []
|
|
32812
33300
|
} : { valid: false, issues: result.issues };
|
|
32813
33301
|
}
|
|
33302
|
+
function lintMonitorFleetInput(value) {
|
|
33303
|
+
const input2 = record2(value);
|
|
33304
|
+
const legacy = input2?.member !== void 0;
|
|
33305
|
+
const admitted = admitMonitorFleetAuthoringContract(value);
|
|
33306
|
+
const issues = admitted.issues.map((issue) => ({
|
|
33307
|
+
...issue,
|
|
33308
|
+
severity: "error"
|
|
33309
|
+
}));
|
|
33310
|
+
if (legacy) {
|
|
33311
|
+
issues.push({
|
|
33312
|
+
severity: "warning",
|
|
33313
|
+
code: "deprecated_fleet_member",
|
|
33314
|
+
path: "member",
|
|
33315
|
+
message: "Legacy Fleet member syntax remains supported."
|
|
33316
|
+
});
|
|
33317
|
+
if (JSON.stringify(input2).includes('"$fleet"')) {
|
|
33318
|
+
issues.push({
|
|
33319
|
+
severity: "warning",
|
|
33320
|
+
code: "deprecated_fleet_expression",
|
|
33321
|
+
path: "member",
|
|
33322
|
+
message: "Legacy $fleet expressions remain supported; use direct Handlebars fields in monitor instead."
|
|
33323
|
+
});
|
|
33324
|
+
}
|
|
33325
|
+
}
|
|
33326
|
+
return admitted.valid && admitted.contract ? { normalized: admitted.contract.definition, issues } : { issues };
|
|
33327
|
+
}
|
|
32814
33328
|
|
|
32815
33329
|
// src/cli/commands/monitors.ts
|
|
32816
33330
|
var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
|
|
@@ -33496,6 +34010,155 @@ function fleetIdempotencyKey(operation, supplied) {
|
|
|
33496
34010
|
}
|
|
33497
34011
|
return normalized ?? `monitor-fleet-${operation}-${(0, import_node_crypto8.randomUUID)()}`;
|
|
33498
34012
|
}
|
|
34013
|
+
function monitorJobIdempotencyKey(operation, supplied) {
|
|
34014
|
+
const normalized = supplied?.trim();
|
|
34015
|
+
if (supplied !== void 0 && !normalized) {
|
|
34016
|
+
throw new MonitorsUsageError("--idempotency-key must not be empty.");
|
|
34017
|
+
}
|
|
34018
|
+
return normalized ?? `monitor-job-${operation}-${(0, import_node_crypto8.randomUUID)()}`;
|
|
34019
|
+
}
|
|
34020
|
+
function readMonitorDefinitionsJsonFile(file) {
|
|
34021
|
+
let raw;
|
|
34022
|
+
try {
|
|
34023
|
+
raw = file === "-" ? (0, import_node_fs15.readFileSync)(0, "utf8") : (0, import_node_fs15.readFileSync)(file, "utf8");
|
|
34024
|
+
} catch (error) {
|
|
34025
|
+
throw new MonitorsUsageError(
|
|
34026
|
+
`Could not read --file ${file}: ${error instanceof Error ? error.message : String(error)}`
|
|
34027
|
+
);
|
|
34028
|
+
}
|
|
34029
|
+
try {
|
|
34030
|
+
return JSON.parse(raw);
|
|
34031
|
+
} catch (error) {
|
|
34032
|
+
throw new MonitorsUsageError(
|
|
34033
|
+
`Monitor definitions must be valid JSON. ${error instanceof Error ? error.message : String(error)}`
|
|
34034
|
+
);
|
|
34035
|
+
}
|
|
34036
|
+
}
|
|
34037
|
+
function renderMonitorJob(payload) {
|
|
34038
|
+
const job = asRecord2(payload.job);
|
|
34039
|
+
if (!job) return void 0;
|
|
34040
|
+
const id = asString(job.id) ?? "<unknown>";
|
|
34041
|
+
const state = asString(job.state) ?? "unknown";
|
|
34042
|
+
const phase = asString(job.phase);
|
|
34043
|
+
const counts = asRecord2(job.counts);
|
|
34044
|
+
const reconciliation = asRecord2(job.reconciliation);
|
|
34045
|
+
const lines = [
|
|
34046
|
+
`Monitor job: ${id}`,
|
|
34047
|
+
`State: ${state}${phase ? ` (${phase})` : ""}`
|
|
34048
|
+
];
|
|
34049
|
+
if (counts) {
|
|
34050
|
+
lines.push(
|
|
34051
|
+
`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}`
|
|
34052
|
+
);
|
|
34053
|
+
}
|
|
34054
|
+
if (reconciliation) {
|
|
34055
|
+
lines.push(
|
|
34056
|
+
`Reconciliation: ${asString(reconciliation.state) ?? "pending"} (${asFiniteNumber(reconciliation.observed_bindings) ?? 0}/${asFiniteNumber(reconciliation.expected_bindings) ?? 0} bindings observed)`
|
|
34057
|
+
);
|
|
34058
|
+
}
|
|
34059
|
+
const next = asString(payload.next);
|
|
34060
|
+
if (next) lines.push(`Next: ${next}`);
|
|
34061
|
+
return `${lines.join("\n")}
|
|
34062
|
+
`;
|
|
34063
|
+
}
|
|
34064
|
+
async function handleMonitorJobBatchDeploy(options, idempotencyKey) {
|
|
34065
|
+
if (!options.file) {
|
|
34066
|
+
throw new MonitorsUsageError(
|
|
34067
|
+
"A Batch file is required. Pass --file batch.json (or --file - for stdin)."
|
|
34068
|
+
);
|
|
34069
|
+
}
|
|
34070
|
+
const lint = lintMonitorBatchInput(
|
|
34071
|
+
readMonitorDefinitionsJsonFile(options.file)
|
|
34072
|
+
);
|
|
34073
|
+
if (!lint.normalized) {
|
|
34074
|
+
throw new MonitorsUsageError(
|
|
34075
|
+
lint.issues.filter((issue) => issue.severity === "error").map((issue) => `${issue.path || "batch"}: ${issue.message}`).join("; ")
|
|
34076
|
+
);
|
|
34077
|
+
}
|
|
34078
|
+
const payload = await new DeeplineClient().monitors.batch.deploy(
|
|
34079
|
+
lint.normalized.monitors,
|
|
34080
|
+
{ idempotencyKey }
|
|
34081
|
+
);
|
|
34082
|
+
printCommandEnvelope(
|
|
34083
|
+
{
|
|
34084
|
+
...payload,
|
|
34085
|
+
idempotency_key: idempotencyKey,
|
|
34086
|
+
...lint.issues.length ? { lint: { issues: lint.issues } } : {}
|
|
34087
|
+
},
|
|
34088
|
+
{ json: options.json, text: renderMonitorJob(payload) }
|
|
34089
|
+
);
|
|
34090
|
+
}
|
|
34091
|
+
async function handleMonitorBatchLint(options) {
|
|
34092
|
+
if (!options.file) {
|
|
34093
|
+
throw new MonitorsUsageError(
|
|
34094
|
+
"monitors batch lint requires --file <batch.json>."
|
|
34095
|
+
);
|
|
34096
|
+
}
|
|
34097
|
+
const result = lintMonitorBatchInput(
|
|
34098
|
+
readMonitorDefinitionsJsonFile(options.file)
|
|
34099
|
+
);
|
|
34100
|
+
printCommandEnvelope(
|
|
34101
|
+
{
|
|
34102
|
+
ok: !result.issues.some((issue) => issue.severity === "error"),
|
|
34103
|
+
...result.normalized ? { normalized: result.normalized } : {},
|
|
34104
|
+
issues: result.issues
|
|
34105
|
+
},
|
|
34106
|
+
{ json: options.json }
|
|
34107
|
+
);
|
|
34108
|
+
if (result.issues.some((issue) => issue.severity === "error"))
|
|
34109
|
+
process.exitCode = 2;
|
|
34110
|
+
}
|
|
34111
|
+
async function handleMonitorFleetLint(options) {
|
|
34112
|
+
if (!options.file) {
|
|
34113
|
+
throw new MonitorsUsageError(
|
|
34114
|
+
"monitors fleets lint requires --file <fleet.json>."
|
|
34115
|
+
);
|
|
34116
|
+
}
|
|
34117
|
+
const result = lintMonitorFleetInput(
|
|
34118
|
+
readMonitorDefinitionsJsonFile(options.file)
|
|
34119
|
+
);
|
|
34120
|
+
printCommandEnvelope(
|
|
34121
|
+
{
|
|
34122
|
+
ok: !result.issues.some((issue) => issue.severity === "error"),
|
|
34123
|
+
...result.normalized ? { normalized: result.normalized } : {},
|
|
34124
|
+
issues: result.issues
|
|
34125
|
+
},
|
|
34126
|
+
{ json: options.json }
|
|
34127
|
+
);
|
|
34128
|
+
if (result.issues.some((issue) => issue.severity === "error"))
|
|
34129
|
+
process.exitCode = 2;
|
|
34130
|
+
}
|
|
34131
|
+
async function handleMonitorJobGet(jobId, options) {
|
|
34132
|
+
const payload = await new DeeplineClient().monitors.jobs.get(jobId);
|
|
34133
|
+
printCommandEnvelope(payload, {
|
|
34134
|
+
json: options.json,
|
|
34135
|
+
text: renderMonitorJob(payload)
|
|
34136
|
+
});
|
|
34137
|
+
}
|
|
34138
|
+
async function handleMonitorJobWait(jobId, options) {
|
|
34139
|
+
const payload = await new DeeplineClient().monitors.jobs.wait(jobId, {
|
|
34140
|
+
timeoutMs: fleetTimeoutMs(options.timeout),
|
|
34141
|
+
pollIntervalMs: FLEET_POLL_INTERVAL_MS
|
|
34142
|
+
});
|
|
34143
|
+
printCommandEnvelope(payload, {
|
|
34144
|
+
json: options.json,
|
|
34145
|
+
text: renderMonitorJob(payload)
|
|
34146
|
+
});
|
|
34147
|
+
}
|
|
34148
|
+
async function handleMonitorJobLogs(jobId, options) {
|
|
34149
|
+
const limit = options.limit ? fleetIntegerOption(options.limit, "--limit") : void 0;
|
|
34150
|
+
const payload = await new DeeplineClient().monitors.jobs.logs(jobId, {
|
|
34151
|
+
...limit === void 0 ? {} : { limit }
|
|
34152
|
+
});
|
|
34153
|
+
printCommandEnvelope(payload, { json: options.json });
|
|
34154
|
+
}
|
|
34155
|
+
async function handleMonitorJobCancel(jobId, options) {
|
|
34156
|
+
const payload = await new DeeplineClient().monitors.jobs.cancel(jobId);
|
|
34157
|
+
printCommandEnvelope(payload, {
|
|
34158
|
+
json: options.json,
|
|
34159
|
+
text: renderMonitorJob(payload)
|
|
34160
|
+
});
|
|
34161
|
+
}
|
|
33499
34162
|
var FLEET_COUNT_KEYS = [
|
|
33500
34163
|
"pending",
|
|
33501
34164
|
"submitting",
|
|
@@ -33517,12 +34180,12 @@ var MONITOR_FLEET_LIFECYCLE = [
|
|
|
33517
34180
|
{
|
|
33518
34181
|
step: 2,
|
|
33519
34182
|
what: "See the plan and the credits before anything changes.",
|
|
33520
|
-
command: "deepline monitors fleets
|
|
34183
|
+
command: "deepline monitors fleets deploy --file fleet.json --dry-run"
|
|
33521
34184
|
},
|
|
33522
34185
|
{
|
|
33523
34186
|
step: 3,
|
|
33524
34187
|
what: "Apply it and wait for the server to call it converged.",
|
|
33525
|
-
command: "deepline monitors fleets
|
|
34188
|
+
command: "deepline monitors fleets deploy --file fleet.json --wait"
|
|
33526
34189
|
},
|
|
33527
34190
|
{
|
|
33528
34191
|
step: 4,
|
|
@@ -33531,6 +34194,11 @@ var MONITOR_FLEET_LIFECYCLE = [
|
|
|
33531
34194
|
}
|
|
33532
34195
|
];
|
|
33533
34196
|
var MONITOR_FLEET_COMMANDS = [
|
|
34197
|
+
{
|
|
34198
|
+
name: "deploy",
|
|
34199
|
+
summary: "Create or update one table-backed Fleet from Customer DB rows."
|
|
34200
|
+
},
|
|
34201
|
+
{ name: "lint", summary: "Validate and normalize Fleet JSON locally." },
|
|
33534
34202
|
{ name: "init", summary: "Write a Fleet definition JSON file." },
|
|
33535
34203
|
{
|
|
33536
34204
|
name: "sync",
|
|
@@ -33676,6 +34344,26 @@ function renderFleetGet(payload) {
|
|
|
33676
34344
|
` counts ${fleetCountsLine(payload)}`,
|
|
33677
34345
|
` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 converged generation ${asFiniteNumber(payload.converged_generation) ?? "none"}`
|
|
33678
34346
|
];
|
|
34347
|
+
const boundPlays = Array.isArray(payload.bound_plays) ? payload.bound_plays.flatMap((value) => {
|
|
34348
|
+
const play = asRecord2(value);
|
|
34349
|
+
return play ? [play] : [];
|
|
34350
|
+
}) : [];
|
|
34351
|
+
lines.push("", `Observed Play bindings (${boundPlays.length}):`);
|
|
34352
|
+
if (boundPlays.length === 0) {
|
|
34353
|
+
lines.push(" none");
|
|
34354
|
+
} else {
|
|
34355
|
+
for (const play of boundPlays) {
|
|
34356
|
+
const name = asString(play.name) ?? "unnamed Play";
|
|
34357
|
+
const listeners = asFiniteNumber(play.listener_count) ?? 0;
|
|
34358
|
+
const status2 = asString(play.status);
|
|
34359
|
+
lines.push(
|
|
34360
|
+
` ${name}${listeners ? ` (${listeners} listener${listeners === 1 ? "" : "s"})` : ""}${status2 ? ` \u2014 ${status2}` : ""}`
|
|
34361
|
+
);
|
|
34362
|
+
}
|
|
34363
|
+
}
|
|
34364
|
+
lines.push(
|
|
34365
|
+
" Read-only observation. Define or change bindings in the Play with sqlListeners."
|
|
34366
|
+
);
|
|
33679
34367
|
lines.push(...renderFleetDriftRows(payload));
|
|
33680
34368
|
const next = fleetServerNext(payload) ?? (status === "degraded" ? `deepline monitors fleets get ${fleetShellArg(id)} --drift` : void 0);
|
|
33681
34369
|
if (next) lines.push(`Next: ${next}`);
|
|
@@ -33852,6 +34540,8 @@ async function handleMonitorFleetsInit(fleetId, options) {
|
|
|
33852
34540
|
const out = options.out?.trim();
|
|
33853
34541
|
if (!out) throw new MonitorsUsageError("--out is required.");
|
|
33854
34542
|
const authoredDefinition = {
|
|
34543
|
+
version: 2,
|
|
34544
|
+
kind: "fleet",
|
|
33855
34545
|
id: fleetId,
|
|
33856
34546
|
source: {
|
|
33857
34547
|
kind: "customer_db_table",
|
|
@@ -33860,12 +34550,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
|
|
|
33860
34550
|
key: { column: key, type: keyType },
|
|
33861
34551
|
...where ? { where } : {}
|
|
33862
34552
|
},
|
|
33863
|
-
|
|
34553
|
+
monitor: {
|
|
33864
34554
|
tool,
|
|
33865
|
-
key: {
|
|
33866
|
-
$fleet: "template",
|
|
33867
|
-
parts: [`${fleetId}-`, { $fleet: "column", name: key }]
|
|
33868
|
-
},
|
|
34555
|
+
key: `${fleetId}-{{${key}}}`,
|
|
33869
34556
|
payload
|
|
33870
34557
|
},
|
|
33871
34558
|
selection: {
|
|
@@ -33878,9 +34565,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
|
|
|
33878
34565
|
const file = (0, import_node_path17.resolve)(out);
|
|
33879
34566
|
(0, import_node_fs15.writeFileSync)(file, `${JSON.stringify(definition, null, 2)}
|
|
33880
34567
|
`, "utf8");
|
|
33881
|
-
const next = `deepline monitors fleets
|
|
34568
|
+
const next = `deepline monitors fleets deploy --file ${fleetShellArg(file)} --dry-run --json`;
|
|
33882
34569
|
printCommandEnvelope(
|
|
33883
|
-
{ schemaVersion:
|
|
34570
|
+
{ schemaVersion: 2, file, definition, next },
|
|
33884
34571
|
{
|
|
33885
34572
|
json: options.json,
|
|
33886
34573
|
text: `Wrote ${file}
|
|
@@ -33890,8 +34577,8 @@ Next: ${next}
|
|
|
33890
34577
|
);
|
|
33891
34578
|
}
|
|
33892
34579
|
function requireCompiledFleetDefinition(definition) {
|
|
33893
|
-
const result =
|
|
33894
|
-
if (result.
|
|
34580
|
+
const result = lintMonitorFleetInput(definition);
|
|
34581
|
+
if (result.normalized) return result.normalized;
|
|
33895
34582
|
const messages = result.issues.map((issue) => `${issue.path || "definition"}: ${issue.message}`).join("; ");
|
|
33896
34583
|
throw new MonitorsUsageError(
|
|
33897
34584
|
`Monitor Fleet definition failed local contract check. ${messages}
|
|
@@ -33918,6 +34605,7 @@ function fleetSyncCommandLine(target, options) {
|
|
|
33918
34605
|
return parts.join(" ");
|
|
33919
34606
|
}
|
|
33920
34607
|
async function handleMonitorFleetsSync(target, options, idempotencyKey) {
|
|
34608
|
+
const fileDefinitions = options.file ? readMonitorDefinitionsJsonFile(options.file) : void 0;
|
|
33921
34609
|
const usesDefinition = options.file !== void 0 || target?.trim().startsWith("{") === true;
|
|
33922
34610
|
if (!usesDefinition && !target?.trim()) {
|
|
33923
34611
|
throw new MonitorsUsageError(
|
|
@@ -33925,12 +34613,14 @@ async function handleMonitorFleetsSync(target, options, idempotencyKey) {
|
|
|
33925
34613
|
);
|
|
33926
34614
|
}
|
|
33927
34615
|
const definition = usesDefinition ? requireCompiledFleetDefinition(
|
|
33928
|
-
|
|
33929
|
-
|
|
33930
|
-
|
|
33931
|
-
|
|
33932
|
-
|
|
33933
|
-
|
|
34616
|
+
asRecord2(
|
|
34617
|
+
fileDefinitions ?? resolveMonitorJsonBody({
|
|
34618
|
+
positional: target,
|
|
34619
|
+
file: options.file,
|
|
34620
|
+
argLabel: "<definition>",
|
|
34621
|
+
command: "deepline monitors fleets sync"
|
|
34622
|
+
})
|
|
34623
|
+
) ?? {}
|
|
33934
34624
|
) : void 0;
|
|
33935
34625
|
const fleetId = definition ? asString(definition.id) ?? "" : target.trim();
|
|
33936
34626
|
if (!fleetId) {
|
|
@@ -34331,14 +35021,14 @@ function renderMonitorGet(payload) {
|
|
|
34331
35021
|
` deepline monitors test ${key} '${JSON.stringify(samplePayload2)}' --json`
|
|
34332
35022
|
);
|
|
34333
35023
|
}
|
|
34334
|
-
const
|
|
34335
|
-
if (
|
|
35024
|
+
const monitorSpec2 = asRecord2(payload.monitor_spec);
|
|
35025
|
+
if (monitorSpec2?.available === false) {
|
|
34336
35026
|
lines.push(
|
|
34337
35027
|
"",
|
|
34338
|
-
`Monitor spec: unavailable \u2014 ${asString(
|
|
35028
|
+
`Monitor spec: unavailable \u2014 ${asString(monitorSpec2.message) ?? "use the stored definition and check before an update."}`
|
|
34339
35029
|
);
|
|
34340
35030
|
}
|
|
34341
|
-
const specFields = Array.isArray(
|
|
35031
|
+
const specFields = Array.isArray(monitorSpec2?.fields) ? monitorSpec2.fields.flatMap((value) => {
|
|
34342
35032
|
const field = asRecord2(value);
|
|
34343
35033
|
const path = asString(field?.path);
|
|
34344
35034
|
const description = asString(field?.description);
|
|
@@ -34812,6 +35502,8 @@ Notes:
|
|
|
34812
35502
|
Deepline monitors are Deepline-native signal feeds: a monitor writes events
|
|
34813
35503
|
into a Customer DB table; a play reacts to each new row via a
|
|
34814
35504
|
sqlListeners trigger \u2014 see \`deepline plays bootstrap monitor-triggered\`.
|
|
35505
|
+
Monitor JSON declares only what to watch (key, tool, optional name, payload).
|
|
35506
|
+
Play bindings belong in the Play; monitor deployment never changes them.
|
|
34815
35507
|
The Monitors rollout controls access to the live provider catalog; use
|
|
34816
35508
|
\`deepline tools list --categories monitors\` for the exact tool ids available to you.
|
|
34817
35509
|
Contact the Deepline team to request access; until access is enabled, these
|
|
@@ -34924,19 +35616,31 @@ Examples:
|
|
|
34924
35616
|
);
|
|
34925
35617
|
withJsonOption(
|
|
34926
35618
|
batch.command("deploy").description(
|
|
34927
|
-
"
|
|
35619
|
+
"Create a Monitor Job from canonical Batch JSON; legacy NDJSON remains available with --yes or --dry-run."
|
|
34928
35620
|
).requiredOption(
|
|
34929
35621
|
"--file <path>",
|
|
34930
|
-
"
|
|
34931
|
-
).option("--dry-run", "
|
|
35622
|
+
'Batch JSON ({"version":1,"kind":"batch","monitors":[...]}), or legacy NDJSON with --yes/--dry-run'
|
|
35623
|
+
).option("--dry-run", "Use the retained legacy batch-operation plan").option("--yes", "Use the retained legacy NDJSON batch operation").option(
|
|
34932
35624
|
"--idempotency-key <key>",
|
|
34933
35625
|
"Stable retry key (generated when omitted)"
|
|
34934
35626
|
)
|
|
34935
35627
|
).action(
|
|
34936
|
-
monitorsAction(
|
|
34937
|
-
(options
|
|
34938
|
-
|
|
35628
|
+
monitorsAction(async (options) => {
|
|
35629
|
+
if (options.dryRun === true || options.yes === true) {
|
|
35630
|
+
return await handleMonitorBatchDeploy(options);
|
|
35631
|
+
}
|
|
35632
|
+
const idempotencyKey = monitorJobIdempotencyKey(
|
|
35633
|
+
"batch-deploy",
|
|
35634
|
+
options.idempotencyKey
|
|
35635
|
+
);
|
|
35636
|
+
return await handleMonitorJobBatchDeploy(options, idempotencyKey);
|
|
35637
|
+
})
|
|
34939
35638
|
);
|
|
35639
|
+
withJsonOption(
|
|
35640
|
+
batch.command("lint").description(
|
|
35641
|
+
"Validate and normalize Batch JSON without network or provider work."
|
|
35642
|
+
).requiredOption("--file <path>", "Batch JSON file, or - for stdin")
|
|
35643
|
+
).action(monitorsAction(handleMonitorBatchLint));
|
|
34940
35644
|
withJsonOption(
|
|
34941
35645
|
batchSelectorOptions(
|
|
34942
35646
|
batch.command("audit").description("Durably audit a selection; defaults to --target all.")
|
|
@@ -35105,9 +35809,8 @@ Examples:
|
|
|
35105
35809
|
"after",
|
|
35106
35810
|
`
|
|
35107
35811
|
Notes:
|
|
35108
|
-
Read-only validation. <definition> is a JSON object with key, tool,
|
|
35109
|
-
and
|
|
35110
|
-
via --file <path>, or
|
|
35812
|
+
Read-only validation. <definition> is a JSON object with key, tool, optional
|
|
35813
|
+
name, and payload. Pass it positionally, via --file <path>, or
|
|
35111
35814
|
from stdin with --file -. Does not deploy or spend credits.
|
|
35112
35815
|
Check validates the local definition only. It does not contact an existing
|
|
35113
35816
|
upstream resource, prove that future events will arrive, or verify downstream
|
|
@@ -35115,12 +35818,8 @@ Notes:
|
|
|
35115
35818
|
Provider-specific grammar, precedence, enum applicability, examples, and
|
|
35116
35819
|
update semantics are returned by the live monitor contract. Inspect it with
|
|
35117
35820
|
\`deepline tools get deepline_native.company_radar --json\`.
|
|
35118
|
-
|
|
35119
|
-
|
|
35120
|
-
do not author custom_fields yourself. Priority is capped at ten upstream or
|
|
35121
|
-
reserved recovery, replacement, or reactivation slots per org. Use
|
|
35122
|
-
\`monitors list --status all\` to find priority holders; it is not for regular
|
|
35123
|
-
or bulk-scale monitoring.
|
|
35821
|
+
Operational controls are Deepline-managed. Bind downstream automation in a
|
|
35822
|
+
Play with sqlListeners; monitor definitions never name Plays.
|
|
35124
35823
|
|
|
35125
35824
|
Examples:
|
|
35126
35825
|
deepline monitors check '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
|
|
@@ -35138,8 +35837,8 @@ Examples:
|
|
|
35138
35837
|
`
|
|
35139
35838
|
Notes:
|
|
35140
35839
|
Mutates workspace state and may spend Deepline credits. <definition> is a JSON
|
|
35141
|
-
object with key, tool,
|
|
35142
|
-
|
|
35840
|
+
object with key, tool, optional name, and payload. Pass it positionally, via
|
|
35841
|
+
--file <path>, or from stdin with --file -.
|
|
35143
35842
|
--dry-run validates the definition and shows the plan (deploy cost in Deepline
|
|
35144
35843
|
credits when the server reports it, plus any existing monitors that may
|
|
35145
35844
|
already cover this scope) WITHOUT deploying. Exits 0 when valid, 7 when not.
|
|
@@ -35156,10 +35855,8 @@ Notes:
|
|
|
35156
35855
|
historical replay request, including when redeploying a disabled monitor.
|
|
35157
35856
|
Deepline preserves that selected boundary; filter-only deploys and ordinary
|
|
35158
35857
|
reactivation start from a fresh future-only source boundary instead.
|
|
35159
|
-
|
|
35160
|
-
|
|
35161
|
-
field and enforces a ten-slot per-org cap; do not use it for regular or bulk
|
|
35162
|
-
monitoring, and do not delete another radar automatically to make room.
|
|
35858
|
+
Operational controls are Deepline-managed. A monitor writes rows; downstream
|
|
35859
|
+
automation belongs in a Play with sqlListeners.
|
|
35163
35860
|
|
|
35164
35861
|
Examples:
|
|
35165
35862
|
deepline monitors deploy '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
|
|
@@ -35190,10 +35887,6 @@ request. Deepline passes that requested boundary upstream, but previously
|
|
|
35190
35887
|
delivered canonical findings are deduplicated before dispatch and billing; only
|
|
35191
35888
|
previously unseen historical findings are chargeable. Filter-only updates,
|
|
35192
35889
|
repair, and reactivation instead use a fresh future-only source boundary.
|
|
35193
|
-
Use {"controls":{"execution_type":"priority"}} only for a bounded urgent
|
|
35194
|
-
Deepline Native preview. The ten-radar priority cap applies on update too.
|
|
35195
|
-
Use {"controls":{"execution_type":null}} to release priority without
|
|
35196
|
-
deleting the monitor.
|
|
35197
35890
|
|
|
35198
35891
|
Examples:
|
|
35199
35892
|
deepline monitors update my-monitor '{"name":"Interested replies"}' --json
|
|
@@ -35241,13 +35934,30 @@ Examples:
|
|
|
35241
35934
|
`
|
|
35242
35935
|
).option("--dry-run", "Show the reactivation cost without reactivating")
|
|
35243
35936
|
).action(monitorsAction(handleMonitorsReactivate));
|
|
35244
|
-
const
|
|
35937
|
+
const jobs = monitors.command("jobs").description("Read, wait for, inspect, or cancel Monitor Jobs.");
|
|
35938
|
+
withJsonOption(jobs);
|
|
35939
|
+
withJsonOption(
|
|
35940
|
+
jobs.command("get <job-id>").description("Read the durable Monitor Job state.")
|
|
35941
|
+
).action(monitorsAction(handleMonitorJobGet));
|
|
35942
|
+
withJsonOption(
|
|
35943
|
+
jobs.command("wait <job-id>").description(
|
|
35944
|
+
"Wait for real provider reconciliation, not request acceptance."
|
|
35945
|
+
).option("--timeout <duration>", "How long to wait (default 10m)")
|
|
35946
|
+
).action(monitorsAction(handleMonitorJobWait));
|
|
35947
|
+
withJsonOption(
|
|
35948
|
+
jobs.command("logs <job-id>").description("Read bounded operator logs for one Monitor Job.").option("--limit <n>", "Maximum log entries (1..200)")
|
|
35949
|
+
).action(monitorsAction(handleMonitorJobLogs));
|
|
35950
|
+
withJsonOption(
|
|
35951
|
+
jobs.command("cancel <job-id>").description("Stop unscheduled work and reconcile the partial result.")
|
|
35952
|
+
).action(monitorsAction(handleMonitorJobCancel));
|
|
35953
|
+
const fleets = monitors.command("fleets").description("Manage table-backed Fleets.").addHelpText(
|
|
35245
35954
|
"after",
|
|
35246
35955
|
`
|
|
35247
35956
|
Notes:
|
|
35248
35957
|
A Monitor Fleet maps eligible rows in one Customer DB table to ordinary
|
|
35249
|
-
monitors. Fleet definitions are canonical JSON, and \`
|
|
35250
|
-
|
|
35958
|
+
monitors. Fleet definitions are canonical JSON, and \`deploy\` applies one;
|
|
35959
|
+
\`sync\` remains its exact compatibility alias. Applying the same definition
|
|
35960
|
+
twice is the same operation,
|
|
35251
35961
|
so the server answers \`replayed: true\` instead of building a second fleet.
|
|
35252
35962
|
The fleet's status is computed by Deepline; this CLI reports it and never
|
|
35253
35963
|
recomputes a verdict from the counts.
|
|
@@ -35269,6 +35979,29 @@ ${MONITOR_FLEET_HELP_EPILOG}`
|
|
|
35269
35979
|
})
|
|
35270
35980
|
);
|
|
35271
35981
|
withJsonOption(fleets);
|
|
35982
|
+
withJsonOption(
|
|
35983
|
+
fleets.command("deploy [fleet-id]").description(
|
|
35984
|
+
"Apply a table-backed Fleet definition; sync remains an exact alias."
|
|
35985
|
+
).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(
|
|
35986
|
+
"--expected-generation <generation>",
|
|
35987
|
+
"Optimistic generation fence"
|
|
35988
|
+
).option("--idempotency-key <key>", "Stable retry key")
|
|
35989
|
+
).action(
|
|
35990
|
+
monitorsAction(
|
|
35991
|
+
async (fleetId, options) => {
|
|
35992
|
+
const idempotencyKey = fleetIdempotencyKey(
|
|
35993
|
+
"deploy",
|
|
35994
|
+
options.idempotencyKey
|
|
35995
|
+
);
|
|
35996
|
+
await handleMonitorFleetsSync(fleetId, options, idempotencyKey);
|
|
35997
|
+
}
|
|
35998
|
+
)
|
|
35999
|
+
);
|
|
36000
|
+
withJsonOption(
|
|
36001
|
+
fleets.command("lint").description(
|
|
36002
|
+
"Validate and normalize Fleet JSON without network or provider work."
|
|
36003
|
+
).requiredOption("--file <path>", "Fleet JSON file, or - for stdin")
|
|
36004
|
+
).action(monitorsAction(handleMonitorFleetLint));
|
|
35272
36005
|
withJsonOption(
|
|
35273
36006
|
fleets.command("init <fleet-id>").description("Write an opinionated Fleet definition JSON file.").addHelpText(
|
|
35274
36007
|
"after",
|
|
@@ -35282,13 +36015,13 @@ Example:
|
|
|
35282
36015
|
deepline monitors fleets init account-job-openings \\
|
|
35283
36016
|
--source public.accounts --key account_id --key-type uuid \\
|
|
35284
36017
|
--tool deepline_native.company_radar \\
|
|
35285
|
-
--payload '{"domain":{
|
|
36018
|
+
--payload '{"domain":"{{domain}}","radar_type":"company_job_openings"}' \\
|
|
35286
36019
|
--order-by intent_score:desc \\
|
|
35287
36020
|
--out fleet.json
|
|
35288
36021
|
`
|
|
35289
36022
|
).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(
|
|
35290
36023
|
"--payload <json>",
|
|
35291
|
-
"Monitor payload JSON for --tool; use
|
|
36024
|
+
"Monitor payload JSON for --tool; use Handlebars fields such as {{domain}} for row values"
|
|
35292
36025
|
).option(
|
|
35293
36026
|
"--where <json>",
|
|
35294
36027
|
"Optional source-row equality filter JSON; not arbitrary SQL"
|
|
@@ -35364,7 +36097,9 @@ Examples:
|
|
|
35364
36097
|
Notes:
|
|
35365
36098
|
Status is the server's verdict. --check turns it into an exit code so a
|
|
35366
36099
|
script can branch without parsing output: 0 converged, 6 anything else.
|
|
35367
|
-
--drift lists the members that have not settled and why.
|
|
36100
|
+
--drift lists the members that have not settled and why. The detail also
|
|
36101
|
+
shows the current Plays that observe this Fleet's output; those bindings are
|
|
36102
|
+
read-only here and are defined by each Play's sqlListeners.
|
|
35368
36103
|
|
|
35369
36104
|
Examples:
|
|
35370
36105
|
deepline monitors fleets get --json
|
|
@@ -37463,8 +38198,8 @@ function classifyNetworkFailure(error) {
|
|
|
37463
38198
|
let current = error;
|
|
37464
38199
|
while (current && !seen.has(current)) {
|
|
37465
38200
|
seen.add(current);
|
|
37466
|
-
const
|
|
37467
|
-
const code = String(
|
|
38201
|
+
const record3 = typeof current === "object" && current !== null ? current : {};
|
|
38202
|
+
const code = String(record3.code ?? "").toLowerCase();
|
|
37468
38203
|
const name = current instanceof Error ? current.name.toLowerCase() : "";
|
|
37469
38204
|
const text = String(
|
|
37470
38205
|
current instanceof Error ? current.message : current
|
|
@@ -37491,7 +38226,7 @@ function classifyNetworkFailure(error) {
|
|
|
37491
38226
|
if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
|
|
37492
38227
|
return "network_ssl_error";
|
|
37493
38228
|
}
|
|
37494
|
-
current =
|
|
38229
|
+
current = record3.cause ?? record3.context;
|
|
37495
38230
|
}
|
|
37496
38231
|
return "network_error";
|
|
37497
38232
|
}
|
|
@@ -38568,26 +39303,26 @@ function parseSetupPhases(value) {
|
|
|
38568
39303
|
if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
|
|
38569
39304
|
return null;
|
|
38570
39305
|
}
|
|
38571
|
-
const
|
|
38572
|
-
if (!isSetupPhaseStatus(
|
|
38573
|
-
switch (
|
|
39306
|
+
const record3 = phase;
|
|
39307
|
+
if (!isSetupPhaseStatus(record3.status)) return null;
|
|
39308
|
+
switch (record3.status) {
|
|
38574
39309
|
case "pending":
|
|
38575
39310
|
case "in_progress":
|
|
38576
|
-
phases[name] = { status:
|
|
39311
|
+
phases[name] = { status: record3.status };
|
|
38577
39312
|
break;
|
|
38578
39313
|
case "complete":
|
|
38579
39314
|
phases[name] = {
|
|
38580
39315
|
status: "complete",
|
|
38581
|
-
...typeof
|
|
39316
|
+
...typeof record3.outcome === "string" ? { outcome: record3.outcome } : {}
|
|
38582
39317
|
};
|
|
38583
39318
|
break;
|
|
38584
39319
|
case "waiting":
|
|
38585
|
-
if (typeof
|
|
38586
|
-
phases[name] = { status: "waiting", outcome:
|
|
39320
|
+
if (typeof record3.outcome !== "string") return null;
|
|
39321
|
+
phases[name] = { status: "waiting", outcome: record3.outcome };
|
|
38587
39322
|
break;
|
|
38588
39323
|
case "failed":
|
|
38589
|
-
if (typeof
|
|
38590
|
-
phases[name] = { status: "failed", code:
|
|
39324
|
+
if (typeof record3.code !== "string") return null;
|
|
39325
|
+
phases[name] = { status: "failed", code: record3.code };
|
|
38591
39326
|
break;
|
|
38592
39327
|
}
|
|
38593
39328
|
}
|
|
@@ -42003,9 +42738,9 @@ function requiredInputIds(tool) {
|
|
|
42003
42738
|
return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
|
|
42004
42739
|
}
|
|
42005
42740
|
function notConnectedSuffix(tool) {
|
|
42006
|
-
const
|
|
42007
|
-
const status = stringField2(
|
|
42008
|
-
const connected =
|
|
42741
|
+
const record3 = tool;
|
|
42742
|
+
const status = stringField2(record3, "credentialStatus", "credential_status");
|
|
42743
|
+
const connected = record3.connected;
|
|
42009
42744
|
const message = toolConnectionStatusMessage({
|
|
42010
42745
|
connected: connected === false ? false : void 0,
|
|
42011
42746
|
credentialStatus: status || void 0
|
|
@@ -42384,19 +43119,19 @@ function printPlayAliasToolError(toolId, play) {
|
|
|
42384
43119
|
console.error(playAliasToolErrorMessage(toolId, play));
|
|
42385
43120
|
}
|
|
42386
43121
|
function isPlayLikeTool(tool) {
|
|
42387
|
-
const
|
|
42388
|
-
if (
|
|
42389
|
-
const playExpansion = recordField2(
|
|
43122
|
+
const record3 = tool;
|
|
43123
|
+
if (record3.isPlay === true || record3.is_play === true) return true;
|
|
43124
|
+
const playExpansion = recordField2(record3, "playExpansion", "play_expansion");
|
|
42390
43125
|
if (Object.keys(playExpansion).length > 0) return true;
|
|
42391
|
-
const toolId = typeof
|
|
43126
|
+
const toolId = typeof record3.toolId === "string" ? record3.toolId : "";
|
|
42392
43127
|
return toolId.endsWith("_waterfall");
|
|
42393
43128
|
}
|
|
42394
43129
|
function isMonitorTypeTool(tool) {
|
|
42395
43130
|
return stringField2(tool, "kind") === "monitor_type";
|
|
42396
43131
|
}
|
|
42397
43132
|
function playReferenceForTool(tool) {
|
|
42398
|
-
const
|
|
42399
|
-
const declared = stringField2(
|
|
43133
|
+
const record3 = tool;
|
|
43134
|
+
const declared = stringField2(record3, "playReference", "play_reference");
|
|
42400
43135
|
if (declared.startsWith("prebuilt/")) {
|
|
42401
43136
|
return declared;
|
|
42402
43137
|
}
|
|
@@ -43336,12 +44071,12 @@ function singleLineText(value, maxLength = 260) {
|
|
|
43336
44071
|
return `${text.slice(0, maxLength - 3).trimEnd()}...`;
|
|
43337
44072
|
}
|
|
43338
44073
|
function listedToolDescription(tool) {
|
|
43339
|
-
const
|
|
43340
|
-
return singleLineText(
|
|
44074
|
+
const record3 = tool;
|
|
44075
|
+
return singleLineText(record3.bestFor ?? record3.best_for ?? tool.description);
|
|
43341
44076
|
}
|
|
43342
44077
|
function formatListedToolCost(tool) {
|
|
43343
|
-
const
|
|
43344
|
-
const pricing = recordField2(
|
|
44078
|
+
const record3 = tool;
|
|
44079
|
+
const pricing = recordField2(record3, "pricing");
|
|
43345
44080
|
const displayText = stringField2(pricing, "displayText", "display_text");
|
|
43346
44081
|
return displayText ? `Cost: ${displayText}` : "";
|
|
43347
44082
|
}
|
|
@@ -44397,9 +45132,9 @@ function noticeToStderr(command) {
|
|
|
44397
45132
|
);
|
|
44398
45133
|
}
|
|
44399
45134
|
function emitPassThrough(command, payload, options) {
|
|
44400
|
-
const
|
|
45135
|
+
const json2 = shouldEmitJson(options.json);
|
|
44401
45136
|
const deprecation = migrationDeprecation(command);
|
|
44402
|
-
if (
|
|
45137
|
+
if (json2) {
|
|
44403
45138
|
const enriched = payload && typeof payload === "object" && !Array.isArray(payload) ? { ...payload, deprecation } : { result: payload, deprecation };
|
|
44404
45139
|
printJson(enriched);
|
|
44405
45140
|
return;
|
|
@@ -44420,9 +45155,9 @@ function clientWithTimeout(timeoutSeconds) {
|
|
|
44420
45155
|
}
|
|
44421
45156
|
function readStatus(payload) {
|
|
44422
45157
|
if (!payload || typeof payload !== "object") return null;
|
|
44423
|
-
const
|
|
44424
|
-
if (typeof
|
|
44425
|
-
const run =
|
|
45158
|
+
const record3 = payload;
|
|
45159
|
+
if (typeof record3.status === "string") return record3.status;
|
|
45160
|
+
const run = record3.run;
|
|
44426
45161
|
if (run && typeof run === "object") {
|
|
44427
45162
|
const status = run.status;
|
|
44428
45163
|
if (typeof status === "string") return status;
|