deepline 0.3.97 → 0.3.98
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 +144 -4
- 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 +1004 -289
- package/dist/cli/index.mjs +1004 -289
- package/dist/index.d.mts +43 -24
- package/dist/index.d.ts +43 -24
- package/dist/index.js +604 -41
- package/dist/index.mjs +600 -41
- package/dist/install-integrity.json +6 -0
- package/dist/monitor-fleet-contract.d.mts +44 -8
- package/dist/monitor-fleet-contract.d.ts +44 -8
- package/dist/monitor-fleet-contract.js +354 -27
- package/dist/monitor-fleet-contract.mjs +343 -27
- package/dist/monitor-input-contract.d.mts +33 -0
- package/dist/monitor-input-contract.d.ts +33 -0
- package/dist/monitor-input-contract.js +392 -0
- package/dist/monitor-input-contract.mjs +353 -0
- package/dist/plays/bundle-play-file.mjs +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +7 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -1271,7 +1271,7 @@ var SDK_RELEASE = {
|
|
|
1271
1271
|
// getters keep their established compatibility behavior.
|
|
1272
1272
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1273
1273
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
1274
|
-
version: "0.3.
|
|
1274
|
+
version: "0.3.98",
|
|
1275
1275
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
1276
1276
|
packageCapabilities: {
|
|
1277
1277
|
updatePreferences: 1
|
|
@@ -3343,9 +3343,9 @@ function nonEmptyString(value) {
|
|
|
3343
3343
|
}
|
|
3344
3344
|
function normalizeDatasetBornFrom(value) {
|
|
3345
3345
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
3346
|
-
const
|
|
3347
|
-
const table = nonEmptyString(
|
|
3348
|
-
const rowCountIn = finiteNonNegativeInteger2(
|
|
3346
|
+
const record3 = value;
|
|
3347
|
+
const table = nonEmptyString(record3.table);
|
|
3348
|
+
const rowCountIn = finiteNonNegativeInteger2(record3.rowCountIn);
|
|
3349
3349
|
if (!table || rowCountIn === null) return null;
|
|
3350
3350
|
return { table, rowCountIn };
|
|
3351
3351
|
}
|
|
@@ -4534,21 +4534,21 @@ function normalizePlayRuntimeNamespace(value) {
|
|
|
4534
4534
|
}
|
|
4535
4535
|
function normalizePlayRuntimeSelection(value) {
|
|
4536
4536
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
4537
|
-
const
|
|
4538
|
-
if (Object.keys(
|
|
4537
|
+
const record3 = value;
|
|
4538
|
+
if (Object.keys(record3).some(
|
|
4539
4539
|
(key) => key !== "environment" && key !== "namespace" && key !== "backend"
|
|
4540
|
-
) ||
|
|
4540
|
+
) || record3.environment !== "preview") {
|
|
4541
4541
|
return null;
|
|
4542
4542
|
}
|
|
4543
|
-
const namespace = normalizePlayRuntimeNamespace(
|
|
4543
|
+
const namespace = normalizePlayRuntimeNamespace(record3.namespace);
|
|
4544
4544
|
if (!namespace) return null;
|
|
4545
|
-
if (
|
|
4545
|
+
if (record3.backend === void 0) {
|
|
4546
4546
|
return { environment: "preview", namespace };
|
|
4547
4547
|
}
|
|
4548
|
-
if (
|
|
4548
|
+
if (record3.backend !== PLAY_RUNTIME_BACKENDS.daytona && record3.backend !== PLAY_RUNTIME_BACKENDS.modal) {
|
|
4549
4549
|
return null;
|
|
4550
4550
|
}
|
|
4551
|
-
return { environment: "preview", namespace, backend:
|
|
4551
|
+
return { environment: "preview", namespace, backend: record3.backend };
|
|
4552
4552
|
}
|
|
4553
4553
|
function normalizePlayRuntimeEnvironment(value) {
|
|
4554
4554
|
return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
|
|
@@ -5193,10 +5193,18 @@ var DeeplineClient = class {
|
|
|
5193
5193
|
repair: (options2) => this.repairMonitors(options2),
|
|
5194
5194
|
health: (options2) => this.readMonitorsHealth(options2),
|
|
5195
5195
|
batch: {
|
|
5196
|
+
deploy: (definitions, options2) => this.deployMonitorBatch(definitions, options2),
|
|
5196
5197
|
submit: (options2) => this.submitMonitorBatch(options2),
|
|
5197
5198
|
get: (operationId, options2) => this.getMonitorBatch(operationId, options2)
|
|
5198
5199
|
},
|
|
5200
|
+
jobs: {
|
|
5201
|
+
get: (jobId) => this.getMonitorJob(jobId),
|
|
5202
|
+
logs: (jobId, options2) => this.getMonitorJobLogs(jobId, options2),
|
|
5203
|
+
cancel: (jobId) => this.cancelMonitorJob(jobId),
|
|
5204
|
+
wait: (jobId, options2) => this.waitForMonitorJob(jobId, options2)
|
|
5205
|
+
},
|
|
5199
5206
|
fleets: {
|
|
5207
|
+
deploy: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
5200
5208
|
sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
5201
5209
|
get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
|
|
5202
5210
|
list: () => this.listMonitorFleets(),
|
|
@@ -7948,6 +7956,68 @@ var DeeplineClient = class {
|
|
|
7948
7956
|
);
|
|
7949
7957
|
}
|
|
7950
7958
|
// ——————————————————————————————————————————————————————————
|
|
7959
|
+
// Monitor Jobs, Batches, and Fleets
|
|
7960
|
+
// ——————————————————————————————————————————————————————————
|
|
7961
|
+
monitorJobIdempotencyKey(operation) {
|
|
7962
|
+
const uuid = globalThis.crypto?.randomUUID?.();
|
|
7963
|
+
return `monitor-job-${operation}-${uuid ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`}`;
|
|
7964
|
+
}
|
|
7965
|
+
monitorJobHeaders(operation, idempotencyKey) {
|
|
7966
|
+
return {
|
|
7967
|
+
"Idempotency-Key": idempotencyKey?.trim() || this.monitorJobIdempotencyKey(operation)
|
|
7968
|
+
};
|
|
7969
|
+
}
|
|
7970
|
+
async deployMonitorBatch(definitions, options) {
|
|
7971
|
+
return this.http.request(
|
|
7972
|
+
"/api/v2/monitors/batch/deploy",
|
|
7973
|
+
{
|
|
7974
|
+
method: "POST",
|
|
7975
|
+
body: { version: 1, kind: "batch", monitors: definitions },
|
|
7976
|
+
headers: this.monitorJobHeaders(
|
|
7977
|
+
"batch-deploy",
|
|
7978
|
+
options?.idempotencyKey
|
|
7979
|
+
),
|
|
7980
|
+
maxRetries: 0,
|
|
7981
|
+
exactUrlOnly: true
|
|
7982
|
+
}
|
|
7983
|
+
);
|
|
7984
|
+
}
|
|
7985
|
+
async getMonitorJob(jobId) {
|
|
7986
|
+
return this.http.request(
|
|
7987
|
+
`/api/v2/monitors/jobs/${encodeURIComponent(jobId)}`,
|
|
7988
|
+
{ method: "GET" }
|
|
7989
|
+
);
|
|
7990
|
+
}
|
|
7991
|
+
async getMonitorJobLogs(jobId, options) {
|
|
7992
|
+
const query = options?.limit === void 0 ? "" : `?limit=${encodeURIComponent(String(options.limit))}`;
|
|
7993
|
+
return this.http.request(
|
|
7994
|
+
`/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/logs${query}`,
|
|
7995
|
+
{ method: "GET" }
|
|
7996
|
+
);
|
|
7997
|
+
}
|
|
7998
|
+
async cancelMonitorJob(jobId) {
|
|
7999
|
+
return this.http.request(
|
|
8000
|
+
`/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/cancel`,
|
|
8001
|
+
{ method: "POST", body: {}, maxRetries: 0, exactUrlOnly: true }
|
|
8002
|
+
);
|
|
8003
|
+
}
|
|
8004
|
+
async waitForMonitorJob(jobId, options) {
|
|
8005
|
+
const timeoutMs = Math.max(1, options?.timeoutMs ?? 10 * 6e4);
|
|
8006
|
+
const pollIntervalMs = Math.max(1, options?.pollIntervalMs ?? 2e3);
|
|
8007
|
+
const terminal = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled"]);
|
|
8008
|
+
const startedAt = Date.now();
|
|
8009
|
+
let latest = await this.getMonitorJob(jobId);
|
|
8010
|
+
while (true) {
|
|
8011
|
+
options?.onProgress?.(latest);
|
|
8012
|
+
const job = latest.job;
|
|
8013
|
+
const state = typeof job?.state === "string" ? job.state : void 0;
|
|
8014
|
+
if (state && terminal.has(state)) return latest;
|
|
8015
|
+
if (Date.now() - startedAt >= timeoutMs) return latest;
|
|
8016
|
+
await sleep2(pollIntervalMs);
|
|
8017
|
+
latest = await this.getMonitorJob(jobId);
|
|
8018
|
+
}
|
|
8019
|
+
}
|
|
8020
|
+
// ——————————————————————————————————————————————————————————
|
|
7951
8021
|
// Monitor Fleets
|
|
7952
8022
|
// ——————————————————————————————————————————————————————————
|
|
7953
8023
|
monitorFleetIdempotencyKey(operation) {
|
|
@@ -8731,30 +8801,30 @@ function flattenObjectColumns(row, options = {}) {
|
|
|
8731
8801
|
continue;
|
|
8732
8802
|
}
|
|
8733
8803
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
8734
|
-
const
|
|
8804
|
+
const record3 = value;
|
|
8735
8805
|
if (options.objectColumns === "json") {
|
|
8736
|
-
flattened[key] = csvSafeJsonString(
|
|
8806
|
+
flattened[key] = csvSafeJsonString(record3);
|
|
8737
8807
|
continue;
|
|
8738
8808
|
}
|
|
8739
|
-
const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(
|
|
8809
|
+
const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record3, "matched_result") || Object.prototype.hasOwnProperty.call(record3, "matchedResult");
|
|
8740
8810
|
if (hasMatchedEnvelope) {
|
|
8741
|
-
flattened[key] = csvSafeJsonString(
|
|
8811
|
+
flattened[key] = csvSafeJsonString(record3);
|
|
8742
8812
|
continue;
|
|
8743
8813
|
}
|
|
8744
8814
|
if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
|
|
8745
8815
|
flattened[key] = rawValue;
|
|
8746
8816
|
continue;
|
|
8747
8817
|
} else {
|
|
8748
|
-
const failureMessage = failureMessageFromRecord(
|
|
8818
|
+
const failureMessage = failureMessageFromRecord(record3);
|
|
8749
8819
|
if (failureMessage) {
|
|
8750
8820
|
flattened[key] = failureMessage;
|
|
8751
8821
|
continue;
|
|
8752
|
-
} else if (Object.prototype.hasOwnProperty.call(
|
|
8753
|
-
flattened[key] = csvSafeJsonString(
|
|
8822
|
+
} else if (Object.prototype.hasOwnProperty.call(record3, "result")) {
|
|
8823
|
+
flattened[key] = csvSafeJsonString(record3);
|
|
8754
8824
|
continue;
|
|
8755
8825
|
}
|
|
8756
8826
|
}
|
|
8757
|
-
for (const [nestedKey, nestedValue] of Object.entries(
|
|
8827
|
+
for (const [nestedKey, nestedValue] of Object.entries(record3)) {
|
|
8758
8828
|
flattened[`${key}.${nestedKey}`] = nestedValue && typeof nestedValue === "object" ? csvSafeJsonString(nestedValue) : nestedValue;
|
|
8759
8829
|
}
|
|
8760
8830
|
continue;
|
|
@@ -11429,9 +11499,9 @@ function canonicalDatasetJsonValue(value, ancestors) {
|
|
|
11429
11499
|
}
|
|
11430
11500
|
if (ancestors.has(value)) return value;
|
|
11431
11501
|
ancestors.add(value);
|
|
11432
|
-
const
|
|
11502
|
+
const record3 = value;
|
|
11433
11503
|
const normalized = Object.fromEntries(
|
|
11434
|
-
Object.keys(
|
|
11504
|
+
Object.keys(record3).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record3[key], ancestors)])
|
|
11435
11505
|
);
|
|
11436
11506
|
ancestors.delete(value);
|
|
11437
11507
|
return normalized;
|
|
@@ -12628,16 +12698,16 @@ function collectErrorText(value) {
|
|
|
12628
12698
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
12629
12699
|
return errorMessage(value);
|
|
12630
12700
|
}
|
|
12631
|
-
const
|
|
12701
|
+
const record3 = value;
|
|
12632
12702
|
return [
|
|
12633
12703
|
errorMessage(value),
|
|
12634
|
-
typeof
|
|
12635
|
-
typeof
|
|
12636
|
-
typeof
|
|
12637
|
-
typeof
|
|
12638
|
-
typeof
|
|
12639
|
-
|
|
12640
|
-
|
|
12704
|
+
typeof record3.error === "string" ? record3.error : "",
|
|
12705
|
+
typeof record3.message === "string" ? record3.message : "",
|
|
12706
|
+
typeof record3.detail === "string" ? record3.detail : "",
|
|
12707
|
+
typeof record3.hint === "string" ? record3.hint : "",
|
|
12708
|
+
typeof record3.code === "string" ? record3.code : "",
|
|
12709
|
+
record3.response ? collectErrorText(record3.response) : "",
|
|
12710
|
+
record3.details ? collectErrorText(record3.details) : ""
|
|
12641
12711
|
].filter(Boolean).join("\n");
|
|
12642
12712
|
}
|
|
12643
12713
|
function formatDbQueryError(sql, error) {
|
|
@@ -13689,8 +13759,8 @@ function getterNamesFromTool(tool, kind) {
|
|
|
13689
13759
|
return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
|
|
13690
13760
|
}
|
|
13691
13761
|
function targetGettersFromTool(tool) {
|
|
13692
|
-
const
|
|
13693
|
-
const raw =
|
|
13762
|
+
const record3 = isRecord9(tool) ? tool : {};
|
|
13763
|
+
const raw = record3.targetGetters ?? record3.target_getters;
|
|
13694
13764
|
if (!isRecord9(raw)) return {};
|
|
13695
13765
|
const entries = [];
|
|
13696
13766
|
for (const [target, value] of Object.entries(raw)) {
|
|
@@ -17805,13 +17875,13 @@ function validateFixtureBehavior(value) {
|
|
|
17805
17875
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
17806
17876
|
return { ok: false, error: "fixtureBehavior must be a JSON object." };
|
|
17807
17877
|
}
|
|
17808
|
-
const
|
|
17809
|
-
const supportedKeys =
|
|
17878
|
+
const record3 = value;
|
|
17879
|
+
const supportedKeys = record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
|
|
17810
17880
|
"version",
|
|
17811
17881
|
"responseSamples",
|
|
17812
|
-
...
|
|
17882
|
+
...record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
|
|
17813
17883
|
]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
|
|
17814
|
-
const unknownKeys = Object.keys(
|
|
17884
|
+
const unknownKeys = Object.keys(record3).filter(
|
|
17815
17885
|
(key) => !supportedKeys.has(key)
|
|
17816
17886
|
);
|
|
17817
17887
|
if (unknownKeys.length > 0) {
|
|
@@ -17820,22 +17890,22 @@ function validateFixtureBehavior(value) {
|
|
|
17820
17890
|
error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
|
|
17821
17891
|
};
|
|
17822
17892
|
}
|
|
17823
|
-
if (
|
|
17893
|
+
if (record3.version !== FIXTURE_BEHAVIOR_VERSION && record3.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record3.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17824
17894
|
return {
|
|
17825
17895
|
ok: false,
|
|
17826
17896
|
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
|
|
17827
17897
|
};
|
|
17828
17898
|
}
|
|
17829
|
-
if (
|
|
17830
|
-
if (!Array.isArray(
|
|
17899
|
+
if (record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17900
|
+
if (!Array.isArray(record3.responseSamples) || record3.responseSamples.length === 0 || record3.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
17831
17901
|
return {
|
|
17832
17902
|
ok: false,
|
|
17833
17903
|
error: `fixtureBehavior.responseSamples must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
|
|
17834
17904
|
};
|
|
17835
17905
|
}
|
|
17836
17906
|
const samples2 = [];
|
|
17837
|
-
for (let index = 0; index <
|
|
17838
|
-
const value2 =
|
|
17907
|
+
for (let index = 0; index < record3.responseSamples.length; index += 1) {
|
|
17908
|
+
const value2 = record3.responseSamples[index];
|
|
17839
17909
|
if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
|
|
17840
17910
|
return {
|
|
17841
17911
|
ok: false,
|
|
@@ -17934,14 +18004,14 @@ function validateFixtureBehavior(value) {
|
|
|
17934
18004
|
});
|
|
17935
18005
|
}
|
|
17936
18006
|
let replayBundle;
|
|
17937
|
-
if (
|
|
17938
|
-
if (!
|
|
18007
|
+
if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
18008
|
+
if (!record3.replayBundle || typeof record3.replayBundle !== "object" || Array.isArray(record3.replayBundle)) {
|
|
17939
18009
|
return {
|
|
17940
18010
|
ok: false,
|
|
17941
18011
|
error: "fixtureBehavior.replayBundle must be an object."
|
|
17942
18012
|
};
|
|
17943
18013
|
}
|
|
17944
|
-
const replay =
|
|
18014
|
+
const replay = record3.replayBundle;
|
|
17945
18015
|
const replayUnknownKeys = Object.keys(replay).filter(
|
|
17946
18016
|
(key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
|
|
17947
18017
|
);
|
|
@@ -17989,7 +18059,7 @@ function validateFixtureBehavior(value) {
|
|
|
17989
18059
|
...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
|
|
17990
18060
|
};
|
|
17991
18061
|
}
|
|
17992
|
-
if (
|
|
18062
|
+
if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
17993
18063
|
return {
|
|
17994
18064
|
ok: true,
|
|
17995
18065
|
behavior: {
|
|
@@ -18007,15 +18077,15 @@ function validateFixtureBehavior(value) {
|
|
|
18007
18077
|
}
|
|
18008
18078
|
};
|
|
18009
18079
|
}
|
|
18010
|
-
if (!Array.isArray(
|
|
18080
|
+
if (!Array.isArray(record3.responseDelaySamplesMs) || record3.responseDelaySamplesMs.length === 0 || record3.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
18011
18081
|
return {
|
|
18012
18082
|
ok: false,
|
|
18013
18083
|
error: `fixtureBehavior.responseDelaySamplesMs must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
|
|
18014
18084
|
};
|
|
18015
18085
|
}
|
|
18016
18086
|
const samples = [];
|
|
18017
|
-
for (let index = 0; index <
|
|
18018
|
-
const value2 =
|
|
18087
|
+
for (let index = 0; index < record3.responseDelaySamplesMs.length; index += 1) {
|
|
18088
|
+
const value2 = record3.responseDelaySamplesMs[index];
|
|
18019
18089
|
if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 0 || value2 > MAX_FIXTURE_RESPONSE_DELAY_MS) {
|
|
18020
18090
|
return {
|
|
18021
18091
|
ok: false,
|
|
@@ -18794,8 +18864,8 @@ function looksLikeStagedFileRef(value) {
|
|
|
18794
18864
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
18795
18865
|
return false;
|
|
18796
18866
|
}
|
|
18797
|
-
const
|
|
18798
|
-
return typeof
|
|
18867
|
+
const record3 = value;
|
|
18868
|
+
return typeof record3.contentHash === "string" || typeof record3.contentBase64 === "string" || typeof record3.logicalPath === "string" && typeof record3.bytes === "number";
|
|
18799
18869
|
}
|
|
18800
18870
|
var CSV_DATA_INPUT_KEY = "csv";
|
|
18801
18871
|
function collectLocalFileInputRefs(value, inputPath, key, out) {
|
|
@@ -19308,8 +19378,8 @@ function readLiveRunField(event, field) {
|
|
|
19308
19378
|
const records = [payload, payload.progress, run, run?.progress].filter(
|
|
19309
19379
|
(value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
|
|
19310
19380
|
);
|
|
19311
|
-
for (const
|
|
19312
|
-
if (
|
|
19381
|
+
for (const record3 of records) {
|
|
19382
|
+
if (record3[field] !== void 0) return record3[field];
|
|
19313
19383
|
}
|
|
19314
19384
|
return void 0;
|
|
19315
19385
|
}
|
|
@@ -19611,8 +19681,8 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
19611
19681
|
if (!state || typeof state !== "object" || Array.isArray(state)) {
|
|
19612
19682
|
continue;
|
|
19613
19683
|
}
|
|
19614
|
-
const
|
|
19615
|
-
const progress =
|
|
19684
|
+
const record3 = state;
|
|
19685
|
+
const progress = record3.progress && typeof record3.progress === "object" && !Array.isArray(record3.progress) ? record3.progress : null;
|
|
19616
19686
|
if (!progress) {
|
|
19617
19687
|
continue;
|
|
19618
19688
|
}
|
|
@@ -19629,7 +19699,7 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
19629
19699
|
completed: progress.completed
|
|
19630
19700
|
});
|
|
19631
19701
|
lines.push(
|
|
19632
|
-
`progress ${formatProgressLabel(
|
|
19702
|
+
`progress ${formatProgressLabel(record3.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
|
|
19633
19703
|
);
|
|
19634
19704
|
}
|
|
19635
19705
|
return lines;
|
|
@@ -20309,11 +20379,11 @@ function truncateErrorForDisplay(message, runId, maxChars = RUN_ERROR_DISPLAY_MA
|
|
|
20309
20379
|
const fullErrorHint = runId ? ` (full error: deepline runs get ${runId} --full)` : " (full error: deepline runs get <runId> --full)";
|
|
20310
20380
|
return `${wordBoundary}\u2026${fullErrorHint}`;
|
|
20311
20381
|
}
|
|
20312
|
-
function clampJsonPreviewText(
|
|
20313
|
-
if (
|
|
20314
|
-
return
|
|
20382
|
+
function clampJsonPreviewText(json2, maxChars) {
|
|
20383
|
+
if (json2.length <= maxChars) {
|
|
20384
|
+
return json2;
|
|
20315
20385
|
}
|
|
20316
|
-
const slice =
|
|
20386
|
+
const slice = json2.slice(0, maxChars);
|
|
20317
20387
|
const lastNewline = slice.lastIndexOf("\n");
|
|
20318
20388
|
const head = lastNewline > 0 ? slice.slice(0, lastNewline) : slice;
|
|
20319
20389
|
return `${head}
|
|
@@ -20439,12 +20509,12 @@ function defaultResultForEnvelope(value, depth = 0) {
|
|
|
20439
20509
|
return output2;
|
|
20440
20510
|
}
|
|
20441
20511
|
function formatJsonPreview(value) {
|
|
20442
|
-
const
|
|
20443
|
-
if (!
|
|
20512
|
+
const json2 = JSON.stringify(value, null, 2);
|
|
20513
|
+
if (!json2 || json2 === "{}") {
|
|
20444
20514
|
return [];
|
|
20445
20515
|
}
|
|
20446
20516
|
const MAX_CHARS = 4e3;
|
|
20447
|
-
const truncated = clampJsonPreviewText(
|
|
20517
|
+
const truncated = clampJsonPreviewText(json2, MAX_CHARS);
|
|
20448
20518
|
return truncated.split("\n").map((line) => ` ${line}`);
|
|
20449
20519
|
}
|
|
20450
20520
|
function formatReturnValue(result) {
|
|
@@ -20472,17 +20542,17 @@ function collectDatasetHandleLines(value, path = "result") {
|
|
|
20472
20542
|
return [];
|
|
20473
20543
|
}
|
|
20474
20544
|
if (isDatasetHandle(value)) {
|
|
20475
|
-
const
|
|
20476
|
-
const count = typeof
|
|
20477
|
-
const preview = Array.isArray(
|
|
20545
|
+
const record3 = value;
|
|
20546
|
+
const count = typeof record3.count === "number" ? record3.count : typeof record3.rowCount === "number" ? record3.rowCount : null;
|
|
20547
|
+
const preview = Array.isArray(record3.preview) ? record3.preview : [];
|
|
20478
20548
|
const lines2 = [
|
|
20479
|
-
` dataset ${typeof
|
|
20549
|
+
` dataset ${typeof record3.path === "string" ? record3.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
|
|
20480
20550
|
];
|
|
20481
|
-
if (typeof
|
|
20482
|
-
lines2.push(` query dataset: ${
|
|
20551
|
+
if (typeof record3.queryDatasetCommand === "string") {
|
|
20552
|
+
lines2.push(` query dataset: ${record3.queryDatasetCommand}`);
|
|
20483
20553
|
}
|
|
20484
|
-
if (typeof
|
|
20485
|
-
lines2.push(` export CSV: ${
|
|
20554
|
+
if (typeof record3.slowExportAsCsvCommand === "string") {
|
|
20555
|
+
lines2.push(` export CSV: ${record3.slowExportAsCsvCommand}`);
|
|
20486
20556
|
}
|
|
20487
20557
|
return lines2;
|
|
20488
20558
|
}
|
|
@@ -20879,8 +20949,8 @@ function withTerminalPlayIdentity(status, playName) {
|
|
|
20879
20949
|
if (!playName.trim() || getPlayRunPackage(status)) {
|
|
20880
20950
|
return status;
|
|
20881
20951
|
}
|
|
20882
|
-
const
|
|
20883
|
-
const hasIdentity = typeof
|
|
20952
|
+
const record3 = status;
|
|
20953
|
+
const hasIdentity = typeof record3.playName === "string" && record3.playName.trim().length > 0 || typeof record3.name === "string" && record3.name.trim().length > 0 || Boolean(getStringField(record3.run, "playName"));
|
|
20884
20954
|
if (hasIdentity) {
|
|
20885
20955
|
return status;
|
|
20886
20956
|
}
|
|
@@ -20993,9 +21063,9 @@ function formatSummaryScalar(value) {
|
|
|
20993
21063
|
}
|
|
20994
21064
|
return null;
|
|
20995
21065
|
}
|
|
20996
|
-
function formatSummaryScalarParts(
|
|
21066
|
+
function formatSummaryScalarParts(record3, skipKeys = /* @__PURE__ */ new Set()) {
|
|
20997
21067
|
const parts = [];
|
|
20998
|
-
for (const [key, value] of Object.entries(
|
|
21068
|
+
for (const [key, value] of Object.entries(record3)) {
|
|
20999
21069
|
if (skipKeys.has(key)) {
|
|
21000
21070
|
continue;
|
|
21001
21071
|
}
|
|
@@ -21022,13 +21092,13 @@ function formatTopValuesPart(value) {
|
|
|
21022
21092
|
return `top_values=${entries.map(([topValue, count]) => `${topValue}=${String(count)}`).join(", ")}`;
|
|
21023
21093
|
}
|
|
21024
21094
|
function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
|
|
21025
|
-
const
|
|
21026
|
-
const columnStats = readRecord(
|
|
21027
|
-
if (!
|
|
21095
|
+
const record3 = readRecord(summary);
|
|
21096
|
+
const columnStats = readRecord(record3?.columnStats);
|
|
21097
|
+
if (!record3 || !columnStats) {
|
|
21028
21098
|
return [];
|
|
21029
21099
|
}
|
|
21030
21100
|
const lines = [];
|
|
21031
|
-
const rowCounts = readRecord(
|
|
21101
|
+
const rowCounts = readRecord(record3.rowCounts);
|
|
21032
21102
|
if (rowCounts) {
|
|
21033
21103
|
const persisted = readNonNegativeInteger(rowCounts.persisted);
|
|
21034
21104
|
const succeeded = readNonNegativeInteger(rowCounts.succeeded);
|
|
@@ -21044,7 +21114,7 @@ function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
|
|
|
21044
21114
|
}
|
|
21045
21115
|
}
|
|
21046
21116
|
const parts = formatSummaryScalarParts(
|
|
21047
|
-
|
|
21117
|
+
record3,
|
|
21048
21118
|
/* @__PURE__ */ new Set(["columnStats", "rowCounts"])
|
|
21049
21119
|
);
|
|
21050
21120
|
if (parts.length > 0) {
|
|
@@ -21074,35 +21144,35 @@ function actionToCommand(action) {
|
|
|
21074
21144
|
if (!action || typeof action !== "object" || Array.isArray(action)) {
|
|
21075
21145
|
return null;
|
|
21076
21146
|
}
|
|
21077
|
-
const
|
|
21078
|
-
if (typeof
|
|
21079
|
-
return
|
|
21147
|
+
const record3 = action;
|
|
21148
|
+
if (typeof record3.command === "string" && record3.command.trim()) {
|
|
21149
|
+
return record3.command.trim();
|
|
21080
21150
|
}
|
|
21081
|
-
if (
|
|
21082
|
-
return `deepline runs get ${
|
|
21151
|
+
if (record3.kind === "deepline_run_inspect" && typeof record3.runId === "string") {
|
|
21152
|
+
return `deepline runs get ${record3.runId} --json`;
|
|
21083
21153
|
}
|
|
21084
|
-
if (
|
|
21085
|
-
return `deepline runs get ${
|
|
21154
|
+
if (record3.kind === "deepline_run_full" && typeof record3.runId === "string") {
|
|
21155
|
+
return `deepline runs get ${record3.runId} --full --json`;
|
|
21086
21156
|
}
|
|
21087
|
-
if (
|
|
21088
|
-
return `deepline runs get ${
|
|
21157
|
+
if (record3.kind === "deepline_run_billing" && typeof record3.runId === "string") {
|
|
21158
|
+
return `deepline runs get ${record3.runId} --full --json | jq '.billing'`;
|
|
21089
21159
|
}
|
|
21090
|
-
if (
|
|
21091
|
-
return `deepline runs export ${
|
|
21092
|
-
|
|
21093
|
-
)} --out ${shellSingleQuote(`${
|
|
21160
|
+
if (record3.kind === "deepline_run_export" && typeof record3.runId === "string" && typeof record3.datasetPath === "string") {
|
|
21161
|
+
return `deepline runs export ${record3.runId} --dataset ${shellSingleQuote(
|
|
21162
|
+
record3.datasetPath
|
|
21163
|
+
)} --out ${shellSingleQuote(`${record3.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
|
|
21094
21164
|
}
|
|
21095
|
-
if (
|
|
21096
|
-
if (typeof
|
|
21097
|
-
return
|
|
21165
|
+
if (record3.kind === "deepline_run_logs") {
|
|
21166
|
+
if (typeof record3.command === "string" && record3.command.trim()) {
|
|
21167
|
+
return record3.command;
|
|
21098
21168
|
}
|
|
21099
|
-
if (typeof
|
|
21100
|
-
return
|
|
21169
|
+
if (typeof record3.runId === "string") {
|
|
21170
|
+
return record3.view === "failed" ? `deepline runs get ${record3.runId} --log-failed --json` : `deepline runs logs ${record3.runId} --json`;
|
|
21101
21171
|
}
|
|
21102
21172
|
}
|
|
21103
|
-
if (
|
|
21104
|
-
const maxRows = typeof
|
|
21105
|
-
return `deepline db query --sql ${shellSingleQuote(
|
|
21173
|
+
if (record3.kind === "deepline_db_query" && typeof record3.sql === "string") {
|
|
21174
|
+
const maxRows = typeof record3.maxRows === "number" && Number.isFinite(record3.maxRows) ? Math.trunc(record3.maxRows) : 20;
|
|
21175
|
+
return `deepline db query --sql ${shellSingleQuote(record3.sql)} --max-rows ${maxRows} --json`;
|
|
21106
21176
|
}
|
|
21107
21177
|
return null;
|
|
21108
21178
|
}
|
|
@@ -21177,8 +21247,8 @@ function formatPackageDatasetActionLines(packaged) {
|
|
|
21177
21247
|
}
|
|
21178
21248
|
function formatInlinePackageValue(value) {
|
|
21179
21249
|
const compacted = compactReturnValue(value);
|
|
21180
|
-
const
|
|
21181
|
-
return clampJsonPreviewText(
|
|
21250
|
+
const json2 = JSON.stringify(compacted);
|
|
21251
|
+
return clampJsonPreviewText(json2 ?? String(compacted), 500);
|
|
21182
21252
|
}
|
|
21183
21253
|
function formatPackageValueOutputLines(packaged) {
|
|
21184
21254
|
const outputs = packaged.outputs && typeof packaged.outputs === "object" && !Array.isArray(packaged.outputs) ? packaged.outputs : null;
|
|
@@ -21511,12 +21581,12 @@ function exportableSheetRow(row) {
|
|
|
21511
21581
|
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
21512
21582
|
return null;
|
|
21513
21583
|
}
|
|
21514
|
-
const
|
|
21515
|
-
const data =
|
|
21584
|
+
const record3 = row;
|
|
21585
|
+
const data = record3.data;
|
|
21516
21586
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
21517
21587
|
return data;
|
|
21518
21588
|
}
|
|
21519
|
-
const fallback = { ...
|
|
21589
|
+
const fallback = { ...record3 };
|
|
21520
21590
|
for (const key of [
|
|
21521
21591
|
"key",
|
|
21522
21592
|
"status",
|
|
@@ -21864,8 +21934,8 @@ var PLAY_SYNTAX_MIGRATION_ERROR_MARKERS = [
|
|
|
21864
21934
|
"ctx.map(...) has been replaced by ctx.dataset(...)",
|
|
21865
21935
|
"Dataset .step(...) has been replaced by .withColumn(...)"
|
|
21866
21936
|
];
|
|
21867
|
-
function stringArrayField(
|
|
21868
|
-
const value =
|
|
21937
|
+
function stringArrayField(record3, key) {
|
|
21938
|
+
const value = record3[key];
|
|
21869
21939
|
if (!Array.isArray(value)) return [];
|
|
21870
21940
|
return value.filter((entry) => typeof entry === "string");
|
|
21871
21941
|
}
|
|
@@ -22696,8 +22766,8 @@ function cronExecutionLabel(status) {
|
|
|
22696
22766
|
return status;
|
|
22697
22767
|
}
|
|
22698
22768
|
function readLiveCronMetadata(play) {
|
|
22699
|
-
const
|
|
22700
|
-
const metadata = readRecord(
|
|
22769
|
+
const record3 = readRecord(play);
|
|
22770
|
+
const metadata = readRecord(record3?.triggerMetadata);
|
|
22701
22771
|
return {
|
|
22702
22772
|
schedule: typeof metadata?.cronSchedule === "string" ? metadata.cronSchedule : null,
|
|
22703
22773
|
timezone: typeof metadata?.cronTimezone === "string" ? metadata.cronTimezone : null,
|
|
@@ -28028,9 +28098,9 @@ async function expandCompiledConfigAtFiles(value) {
|
|
|
28028
28098
|
if (!value || typeof value !== "object") {
|
|
28029
28099
|
return value;
|
|
28030
28100
|
}
|
|
28031
|
-
const
|
|
28101
|
+
const record3 = value;
|
|
28032
28102
|
const expanded = {};
|
|
28033
|
-
for (const [key, entry] of Object.entries(
|
|
28103
|
+
for (const [key, entry] of Object.entries(record3)) {
|
|
28034
28104
|
expanded[key] = await expandCompiledConfigAtFiles(entry);
|
|
28035
28105
|
}
|
|
28036
28106
|
for (const field of ["extract_js", "run_if_js"]) {
|
|
@@ -28828,26 +28898,26 @@ function readFirstEnrichDatasetActions(value) {
|
|
|
28828
28898
|
}
|
|
28829
28899
|
return null;
|
|
28830
28900
|
}
|
|
28831
|
-
const
|
|
28832
|
-
const actions = isRecord11(
|
|
28901
|
+
const record3 = candidate;
|
|
28902
|
+
const actions = isRecord11(record3.actions) ? record3.actions : null;
|
|
28833
28903
|
const currentQuery = isRecord11(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
|
|
28834
28904
|
const legacyQuery = isRecord11(actions?.query) ? actions.query : null;
|
|
28835
28905
|
const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
|
|
28836
28906
|
if (query?.kind === "deepline_db_query") {
|
|
28837
28907
|
return {
|
|
28838
|
-
dataset:
|
|
28908
|
+
dataset: record3,
|
|
28839
28909
|
query,
|
|
28840
28910
|
...isRecord11(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
|
|
28841
28911
|
};
|
|
28842
28912
|
}
|
|
28843
|
-
if (options.allowLegacy &&
|
|
28913
|
+
if (options.allowLegacy && record3.kind === "dataset" && typeof record3.queryDatasetCommand === "string" && record3.queryDatasetCommand.trim()) {
|
|
28844
28914
|
return {
|
|
28845
|
-
dataset:
|
|
28846
|
-
queryDatasetCommand:
|
|
28847
|
-
...typeof
|
|
28915
|
+
dataset: record3,
|
|
28916
|
+
queryDatasetCommand: record3.queryDatasetCommand.trim(),
|
|
28917
|
+
...typeof record3.slowExportAsCsvCommand === "string" && record3.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record3.slowExportAsCsvCommand.trim() } : {}
|
|
28848
28918
|
};
|
|
28849
28919
|
}
|
|
28850
|
-
for (const [key, entry] of Object.entries(
|
|
28920
|
+
for (const [key, entry] of Object.entries(record3)) {
|
|
28851
28921
|
if (key === "preview") {
|
|
28852
28922
|
continue;
|
|
28853
28923
|
}
|
|
@@ -28863,8 +28933,8 @@ function readFirstEnrichDatasetActions(value) {
|
|
|
28863
28933
|
seen.clear();
|
|
28864
28934
|
return walk(value, { allowLegacy: true });
|
|
28865
28935
|
}
|
|
28866
|
-
function actionStringField(
|
|
28867
|
-
const value =
|
|
28936
|
+
function actionStringField(record3, key) {
|
|
28937
|
+
const value = record3[key];
|
|
28868
28938
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
28869
28939
|
}
|
|
28870
28940
|
function parseSqlFromDbQueryCommand(command) {
|
|
@@ -29208,12 +29278,12 @@ function collectStringFields(value, key, output2, depth = 0) {
|
|
|
29208
29278
|
}
|
|
29209
29279
|
return;
|
|
29210
29280
|
}
|
|
29211
|
-
const
|
|
29212
|
-
const direct =
|
|
29281
|
+
const record3 = value;
|
|
29282
|
+
const direct = record3[key];
|
|
29213
29283
|
if (typeof direct === "string" && direct.trim()) {
|
|
29214
29284
|
output2.add(direct.trim());
|
|
29215
29285
|
}
|
|
29216
|
-
for (const child of Object.values(
|
|
29286
|
+
for (const child of Object.values(record3)) {
|
|
29217
29287
|
collectStringFields(child, key, output2, depth + 1);
|
|
29218
29288
|
}
|
|
29219
29289
|
}
|
|
@@ -29399,23 +29469,23 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
|
|
|
29399
29469
|
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
29400
29470
|
return null;
|
|
29401
29471
|
}
|
|
29402
|
-
const
|
|
29403
|
-
const data =
|
|
29472
|
+
const record3 = row;
|
|
29473
|
+
const data = record3.data;
|
|
29404
29474
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
29405
29475
|
const exported = { ...data };
|
|
29406
29476
|
applyFailureCellMeta(exported, exported[ENRICH_CELL_META_FIELD], {
|
|
29407
|
-
rowError:
|
|
29477
|
+
rowError: record3.error
|
|
29408
29478
|
});
|
|
29409
|
-
applyFailureCellMeta(exported,
|
|
29410
|
-
applyFailureCellMeta(exported,
|
|
29411
|
-
rowError:
|
|
29479
|
+
applyFailureCellMeta(exported, record3.cellMeta, { rowError: record3.error });
|
|
29480
|
+
applyFailureCellMeta(exported, record3.cellMetaPatch, {
|
|
29481
|
+
rowError: record3.error
|
|
29412
29482
|
});
|
|
29413
|
-
applyFailureCellMeta(exported,
|
|
29414
|
-
rowError:
|
|
29483
|
+
applyFailureCellMeta(exported, record3[ENRICH_CELL_META_PATCH_FIELD], {
|
|
29484
|
+
rowError: record3.error
|
|
29415
29485
|
});
|
|
29416
29486
|
delete exported[ENRICH_CELL_META_FIELD];
|
|
29417
29487
|
delete exported[ENRICH_CELL_META_PATCH_FIELD];
|
|
29418
|
-
const inputIndex = typeof
|
|
29488
|
+
const inputIndex = typeof record3.inputIndex === "number" ? record3.inputIndex : typeof record3.inputIndex === "string" && record3.inputIndex.trim() ? Number(record3.inputIndex) : Number.NaN;
|
|
29419
29489
|
if (Number.isInteger(inputIndex) && inputIndex >= 0) {
|
|
29420
29490
|
if (ENRICH_SOURCE_ROW_INDEX_COLUMN in exported) {
|
|
29421
29491
|
exported[ENRICH_ORIGINAL_SOURCE_ROW_INDEX_COLUMN] = exported[ENRICH_SOURCE_ROW_INDEX_COLUMN];
|
|
@@ -29424,18 +29494,18 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
|
|
|
29424
29494
|
}
|
|
29425
29495
|
return exported;
|
|
29426
29496
|
}
|
|
29427
|
-
const fallback = { ...
|
|
29497
|
+
const fallback = { ...record3 };
|
|
29428
29498
|
applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_FIELD], {
|
|
29429
|
-
rowError:
|
|
29499
|
+
rowError: record3.error
|
|
29430
29500
|
});
|
|
29431
|
-
applyFailureCellMeta(fallback,
|
|
29432
|
-
rowError:
|
|
29501
|
+
applyFailureCellMeta(fallback, record3.cellMeta, {
|
|
29502
|
+
rowError: record3.error
|
|
29433
29503
|
});
|
|
29434
|
-
applyFailureCellMeta(fallback,
|
|
29435
|
-
rowError:
|
|
29504
|
+
applyFailureCellMeta(fallback, record3.cellMetaPatch, {
|
|
29505
|
+
rowError: record3.error
|
|
29436
29506
|
});
|
|
29437
29507
|
applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_PATCH_FIELD], {
|
|
29438
|
-
rowError:
|
|
29508
|
+
rowError: record3.error
|
|
29439
29509
|
});
|
|
29440
29510
|
for (const key of [
|
|
29441
29511
|
"key",
|
|
@@ -29654,16 +29724,16 @@ function isWaterfallResultMeaningful(value) {
|
|
|
29654
29724
|
return value.some(isWaterfallResultMeaningful);
|
|
29655
29725
|
}
|
|
29656
29726
|
if (value && typeof value === "object") {
|
|
29657
|
-
const
|
|
29658
|
-
const status = typeof
|
|
29727
|
+
const record3 = value;
|
|
29728
|
+
const status = typeof record3.status === "string" ? record3.status.trim().toLowerCase() : "";
|
|
29659
29729
|
if (status === "error" || status === "failed") {
|
|
29660
29730
|
return false;
|
|
29661
29731
|
}
|
|
29662
|
-
if (typeof
|
|
29732
|
+
if (typeof record3.error === "string" && record3.error.trim()) {
|
|
29663
29733
|
return false;
|
|
29664
29734
|
}
|
|
29665
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
29666
|
-
return isWaterfallResultMeaningful(
|
|
29735
|
+
if (Object.prototype.hasOwnProperty.call(record3, "matched_result")) {
|
|
29736
|
+
return isWaterfallResultMeaningful(record3.matched_result);
|
|
29667
29737
|
}
|
|
29668
29738
|
for (const key of [
|
|
29669
29739
|
"value",
|
|
@@ -29678,11 +29748,11 @@ function isWaterfallResultMeaningful(value) {
|
|
|
29678
29748
|
"result",
|
|
29679
29749
|
"data"
|
|
29680
29750
|
]) {
|
|
29681
|
-
if (isWaterfallResultMeaningful(
|
|
29751
|
+
if (isWaterfallResultMeaningful(record3[key])) {
|
|
29682
29752
|
return true;
|
|
29683
29753
|
}
|
|
29684
29754
|
}
|
|
29685
|
-
return Object.entries(
|
|
29755
|
+
return Object.entries(record3).some(
|
|
29686
29756
|
([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
|
|
29687
29757
|
);
|
|
29688
29758
|
}
|
|
@@ -29698,8 +29768,8 @@ function stableRowSnapshot(value) {
|
|
|
29698
29768
|
return `[${value.map(stableRowSnapshot).join(",")}]`;
|
|
29699
29769
|
}
|
|
29700
29770
|
if (value && typeof value === "object") {
|
|
29701
|
-
const
|
|
29702
|
-
return `{${Object.keys(
|
|
29771
|
+
const record3 = value;
|
|
29772
|
+
return `{${Object.keys(record3).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record3[key])}`).join(",")}}`;
|
|
29703
29773
|
}
|
|
29704
29774
|
return JSON.stringify(value);
|
|
29705
29775
|
}
|
|
@@ -30286,8 +30356,8 @@ function addEnrichFollowUpCommand(commands, seen, command) {
|
|
|
30286
30356
|
seen.add(normalized);
|
|
30287
30357
|
commands.push({ ...command, command: normalized });
|
|
30288
30358
|
}
|
|
30289
|
-
function datasetSelectorForEnrichCommand(
|
|
30290
|
-
const candidates = [
|
|
30359
|
+
function datasetSelectorForEnrichCommand(record3, fallbackPath) {
|
|
30360
|
+
const candidates = [record3.path, record3.tableNamespace, fallbackPath];
|
|
30291
30361
|
for (const candidate of candidates) {
|
|
30292
30362
|
if (typeof candidate === "string" && candidate.trim()) {
|
|
30293
30363
|
return candidate.trim();
|
|
@@ -30349,19 +30419,19 @@ function collectDatasetFollowUpCommands(value, state) {
|
|
|
30349
30419
|
);
|
|
30350
30420
|
return;
|
|
30351
30421
|
}
|
|
30352
|
-
const
|
|
30353
|
-
const isDataset =
|
|
30422
|
+
const record3 = value;
|
|
30423
|
+
const isDataset = record3.kind === "dataset";
|
|
30354
30424
|
if (isDataset) {
|
|
30355
|
-
const selector = datasetSelectorForEnrichCommand(
|
|
30356
|
-
const labelPath = typeof
|
|
30357
|
-
if (typeof
|
|
30425
|
+
const selector = datasetSelectorForEnrichCommand(record3, state.path);
|
|
30426
|
+
const labelPath = typeof record3.path === "string" && record3.path.trim() ? record3.path.trim() : selector ?? state.path;
|
|
30427
|
+
if (typeof record3.queryDatasetCommand === "string") {
|
|
30358
30428
|
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
30359
30429
|
label: `query ${labelPath}`,
|
|
30360
30430
|
path: labelPath,
|
|
30361
|
-
command:
|
|
30431
|
+
command: record3.queryDatasetCommand
|
|
30362
30432
|
});
|
|
30363
30433
|
}
|
|
30364
|
-
const exportCommand = typeof
|
|
30434
|
+
const exportCommand = typeof record3.slowExportAsCsvCommand === "string" ? record3.slowExportAsCsvCommand : typeof record3.fullExportCommand === "string" ? record3.fullExportCommand : null;
|
|
30365
30435
|
if (exportCommand) {
|
|
30366
30436
|
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
30367
30437
|
label: `export ${labelPath}`,
|
|
@@ -30378,7 +30448,7 @@ function collectDatasetFollowUpCommands(value, state) {
|
|
|
30378
30448
|
});
|
|
30379
30449
|
}
|
|
30380
30450
|
}
|
|
30381
|
-
for (const [key, child] of Object.entries(
|
|
30451
|
+
for (const [key, child] of Object.entries(record3)) {
|
|
30382
30452
|
if (key === "preview" || key === "access") {
|
|
30383
30453
|
continue;
|
|
30384
30454
|
}
|
|
@@ -31852,9 +31922,9 @@ function readCodexSessionId(filePath) {
|
|
|
31852
31922
|
)) {
|
|
31853
31923
|
const parsed = parseJsonLine(line);
|
|
31854
31924
|
if (!parsed || typeof parsed !== "object") continue;
|
|
31855
|
-
const
|
|
31856
|
-
const payload =
|
|
31857
|
-
const id =
|
|
31925
|
+
const record3 = parsed;
|
|
31926
|
+
const payload = record3.payload && typeof record3.payload === "object" ? record3.payload : null;
|
|
31927
|
+
const id = record3.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
|
|
31858
31928
|
if (id && UUID_RE.test(id)) return id;
|
|
31859
31929
|
}
|
|
31860
31930
|
} catch {
|
|
@@ -31953,15 +32023,15 @@ function messageContentKey(value) {
|
|
|
31953
32023
|
if (!Array.isArray(content)) return null;
|
|
31954
32024
|
return content.map((block) => {
|
|
31955
32025
|
if (!block || typeof block !== "object") return String(block);
|
|
31956
|
-
const
|
|
31957
|
-
const type = String(
|
|
32026
|
+
const record3 = block;
|
|
32027
|
+
const type = String(record3.type ?? "");
|
|
31958
32028
|
if (type === "tool_use") {
|
|
31959
|
-
return `tool_use:${String(
|
|
32029
|
+
return `tool_use:${String(record3.name ?? "")}:${String(record3.id ?? "")}`;
|
|
31960
32030
|
}
|
|
31961
32031
|
if (type === "tool_result") {
|
|
31962
|
-
return `tool_result:${String(
|
|
32032
|
+
return `tool_result:${String(record3.tool_use_id ?? "")}`;
|
|
31963
32033
|
}
|
|
31964
|
-
return String(
|
|
32034
|
+
return String(record3.text ?? type);
|
|
31965
32035
|
}).join("\n");
|
|
31966
32036
|
}
|
|
31967
32037
|
function dedupConsecutiveEvents(raw) {
|
|
@@ -31976,9 +32046,9 @@ function dedupConsecutiveEvents(raw) {
|
|
|
31976
32046
|
index += 1;
|
|
31977
32047
|
continue;
|
|
31978
32048
|
}
|
|
31979
|
-
const
|
|
31980
|
-
const eventType = String(
|
|
31981
|
-
const eventKey = messageContentKey(
|
|
32049
|
+
const record3 = event;
|
|
32050
|
+
const eventType = String(record3.type ?? "");
|
|
32051
|
+
const eventKey = messageContentKey(record3);
|
|
31982
32052
|
if (!["user", "assistant"].includes(eventType) || !eventKey) {
|
|
31983
32053
|
output2.push(rawLines[index] ?? "");
|
|
31984
32054
|
index += 1;
|
|
@@ -31997,9 +32067,9 @@ function dedupConsecutiveEvents(raw) {
|
|
|
31997
32067
|
cursor += 1;
|
|
31998
32068
|
}
|
|
31999
32069
|
if (runCount > 1) {
|
|
32000
|
-
|
|
32001
|
-
|
|
32002
|
-
output2.push(JSON.stringify(
|
|
32070
|
+
record3._repeat_count = runCount;
|
|
32071
|
+
record3._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
|
|
32072
|
+
output2.push(JSON.stringify(record3));
|
|
32003
32073
|
index = cursor;
|
|
32004
32074
|
continue;
|
|
32005
32075
|
}
|
|
@@ -32044,9 +32114,9 @@ function selectiveCompactToolResults(raw) {
|
|
|
32044
32114
|
lines.push(line);
|
|
32045
32115
|
continue;
|
|
32046
32116
|
}
|
|
32047
|
-
const
|
|
32048
|
-
if (
|
|
32049
|
-
const message =
|
|
32117
|
+
const record3 = parsed;
|
|
32118
|
+
if (record3.type === "user") {
|
|
32119
|
+
const message = record3.message;
|
|
32050
32120
|
const content = message && typeof message === "object" ? message.content : null;
|
|
32051
32121
|
if (Array.isArray(content)) {
|
|
32052
32122
|
message.content = content.map(
|
|
@@ -32054,7 +32124,7 @@ function selectiveCompactToolResults(raw) {
|
|
|
32054
32124
|
);
|
|
32055
32125
|
}
|
|
32056
32126
|
}
|
|
32057
|
-
lines.push(JSON.stringify(
|
|
32127
|
+
lines.push(JSON.stringify(record3));
|
|
32058
32128
|
}
|
|
32059
32129
|
return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
|
|
32060
32130
|
` : "", "utf8");
|
|
@@ -32080,15 +32150,15 @@ function compactCodexEvents(raw) {
|
|
|
32080
32150
|
lines.push(rawLines[index] ?? "");
|
|
32081
32151
|
return;
|
|
32082
32152
|
}
|
|
32083
|
-
const
|
|
32084
|
-
if (
|
|
32085
|
-
const payload =
|
|
32153
|
+
const record3 = event;
|
|
32154
|
+
if (record3.type === "world_state") return;
|
|
32155
|
+
const payload = record3.payload;
|
|
32086
32156
|
const payloadType = payload && typeof payload === "object" ? String(payload.type ?? "") : "";
|
|
32087
32157
|
if (payloadType === "token_count" && index !== lastTokenCountIndex) return;
|
|
32088
32158
|
if (payloadType === "custom_tool_call_output" || payloadType === "function_call_output" || payloadType === "tool_search_output") {
|
|
32089
32159
|
const record_payload = payload;
|
|
32090
32160
|
record_payload.output = compactEventValue(record_payload.output);
|
|
32091
|
-
lines.push(JSON.stringify(
|
|
32161
|
+
lines.push(JSON.stringify(record3));
|
|
32092
32162
|
return;
|
|
32093
32163
|
}
|
|
32094
32164
|
lines.push(rawLines[index] ?? "");
|
|
@@ -32294,8 +32364,8 @@ function parsePreparedEvents(buffer) {
|
|
|
32294
32364
|
return parsed ?? line;
|
|
32295
32365
|
});
|
|
32296
32366
|
}
|
|
32297
|
-
function escapeJsonForHtmlScript(
|
|
32298
|
-
return
|
|
32367
|
+
function escapeJsonForHtmlScript(json2) {
|
|
32368
|
+
return json2.replace(/</g, "\\u003c");
|
|
32299
32369
|
}
|
|
32300
32370
|
async function handleSessionsRender(options) {
|
|
32301
32371
|
const targets = resolveSessionTargets({
|
|
@@ -32556,11 +32626,317 @@ import { readFileSync as readFileSync11, writeFileSync as writeFileSync12 } from
|
|
|
32556
32626
|
import { resolve as resolve14 } from "path";
|
|
32557
32627
|
import { createInterface } from "readline/promises";
|
|
32558
32628
|
|
|
32629
|
+
// ../integration-contracts/monitor-input-contract.ts
|
|
32630
|
+
import Handlebars from "handlebars";
|
|
32631
|
+
function authoredMonitorFieldPath(path, field) {
|
|
32632
|
+
const batch = /^monitors\.(\d+)$/.exec(path);
|
|
32633
|
+
return `${batch ? `monitors[${batch[1]}]` : path}.${field}`;
|
|
32634
|
+
}
|
|
32635
|
+
function record(value) {
|
|
32636
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
32637
|
+
}
|
|
32638
|
+
function json(value, path, issues) {
|
|
32639
|
+
if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
|
|
32640
|
+
return;
|
|
32641
|
+
}
|
|
32642
|
+
if (Array.isArray(value)) {
|
|
32643
|
+
value.forEach((child, index) => json(child, `${path}.${index}`, issues));
|
|
32644
|
+
return;
|
|
32645
|
+
}
|
|
32646
|
+
const object = record(value);
|
|
32647
|
+
if (!object) {
|
|
32648
|
+
issues.push({
|
|
32649
|
+
severity: "error",
|
|
32650
|
+
code: "invalid_monitor_json_value",
|
|
32651
|
+
path,
|
|
32652
|
+
message: "Monitor values must be JSON values."
|
|
32653
|
+
});
|
|
32654
|
+
return;
|
|
32655
|
+
}
|
|
32656
|
+
for (const [key, child] of Object.entries(object)) {
|
|
32657
|
+
json(child, `${path}.${key}`, issues);
|
|
32658
|
+
}
|
|
32659
|
+
}
|
|
32660
|
+
function monitorSpec(value, path, issues) {
|
|
32661
|
+
const input2 = record(value);
|
|
32662
|
+
if (!input2) {
|
|
32663
|
+
issues.push({
|
|
32664
|
+
severity: "error",
|
|
32665
|
+
code: "invalid_monitor_spec",
|
|
32666
|
+
path,
|
|
32667
|
+
message: "A monitor must be a JSON object."
|
|
32668
|
+
});
|
|
32669
|
+
return null;
|
|
32670
|
+
}
|
|
32671
|
+
const allowed = /* @__PURE__ */ new Set(["key", "tool", "name", "payload"]);
|
|
32672
|
+
for (const key2 of Object.keys(input2)) {
|
|
32673
|
+
if (!allowed.has(key2)) {
|
|
32674
|
+
if (key2 === "controls") {
|
|
32675
|
+
issues.push({
|
|
32676
|
+
severity: "error",
|
|
32677
|
+
code: "CONTROLS_NOT_SUPPORTED",
|
|
32678
|
+
path: authoredMonitorFieldPath(path, "controls"),
|
|
32679
|
+
message: "Operational controls are managed by Deepline and cannot be authored in Batch or Fleet JSON.",
|
|
32680
|
+
suggestion: "Remove controls. Bind downstream automation in a Play with sqlListeners."
|
|
32681
|
+
});
|
|
32682
|
+
continue;
|
|
32683
|
+
}
|
|
32684
|
+
if (key2 === "play") {
|
|
32685
|
+
issues.push({
|
|
32686
|
+
severity: "error",
|
|
32687
|
+
code: "PLAY_BINDING_NOT_IN_MONITOR_SPEC",
|
|
32688
|
+
path: authoredMonitorFieldPath(path, "play"),
|
|
32689
|
+
message: "A monitor does not own Play bindings.",
|
|
32690
|
+
suggestion: "Declare sqlListeners in the Play, or run: deepline plays bootstrap monitor-triggered --out on-event.play.ts"
|
|
32691
|
+
});
|
|
32692
|
+
continue;
|
|
32693
|
+
}
|
|
32694
|
+
issues.push({
|
|
32695
|
+
severity: "error",
|
|
32696
|
+
code: "unknown_monitor_field",
|
|
32697
|
+
path: `${path}.${key2}`,
|
|
32698
|
+
message: `Monitor definitions do not accept '${key2}'.`
|
|
32699
|
+
});
|
|
32700
|
+
}
|
|
32701
|
+
}
|
|
32702
|
+
const key = typeof input2.key === "string" ? input2.key.trim() : "";
|
|
32703
|
+
const tool = typeof input2.tool === "string" ? input2.tool.trim() : "";
|
|
32704
|
+
const name = input2.name === void 0 ? void 0 : typeof input2.name === "string" && input2.name.trim() ? input2.name.trim() : null;
|
|
32705
|
+
const payload = record(input2.payload);
|
|
32706
|
+
if (!key) {
|
|
32707
|
+
issues.push({
|
|
32708
|
+
severity: "error",
|
|
32709
|
+
code: "invalid_monitor_key",
|
|
32710
|
+
path: `${path}.key`,
|
|
32711
|
+
message: "Monitor key must be a non-empty string."
|
|
32712
|
+
});
|
|
32713
|
+
}
|
|
32714
|
+
if (!tool) {
|
|
32715
|
+
issues.push({
|
|
32716
|
+
severity: "error",
|
|
32717
|
+
code: "invalid_monitor_tool",
|
|
32718
|
+
path: `${path}.tool`,
|
|
32719
|
+
message: "Monitor tool must be a non-empty literal string."
|
|
32720
|
+
});
|
|
32721
|
+
}
|
|
32722
|
+
if (name === null) {
|
|
32723
|
+
issues.push({
|
|
32724
|
+
severity: "error",
|
|
32725
|
+
code: "invalid_monitor_name",
|
|
32726
|
+
path: `${path}.name`,
|
|
32727
|
+
message: "Monitor name must be a non-empty string when supplied."
|
|
32728
|
+
});
|
|
32729
|
+
}
|
|
32730
|
+
if (!payload) {
|
|
32731
|
+
issues.push({
|
|
32732
|
+
severity: "error",
|
|
32733
|
+
code: "invalid_monitor_payload",
|
|
32734
|
+
path: `${path}.payload`,
|
|
32735
|
+
message: "Monitor payload must be an object."
|
|
32736
|
+
});
|
|
32737
|
+
} else {
|
|
32738
|
+
json(payload, `${path}.payload`, issues);
|
|
32739
|
+
}
|
|
32740
|
+
if (!key || !tool || !payload || name === null) {
|
|
32741
|
+
return null;
|
|
32742
|
+
}
|
|
32743
|
+
return {
|
|
32744
|
+
key,
|
|
32745
|
+
tool,
|
|
32746
|
+
...name ? { name } : {},
|
|
32747
|
+
payload
|
|
32748
|
+
};
|
|
32749
|
+
}
|
|
32750
|
+
function issueOrder(left, right) {
|
|
32751
|
+
return left.path.localeCompare(right.path) || left.severity.localeCompare(right.severity) || left.code.localeCompare(right.code);
|
|
32752
|
+
}
|
|
32753
|
+
function lintMonitorBatchInput(value) {
|
|
32754
|
+
const issues = [];
|
|
32755
|
+
const versionlessEnvelope = !Array.isArray(value) && (() => {
|
|
32756
|
+
const candidate = record(value);
|
|
32757
|
+
return candidate !== null && Object.keys(candidate).length === 1 && Object.prototype.hasOwnProperty.call(candidate, "monitors");
|
|
32758
|
+
})();
|
|
32759
|
+
const legacy = Array.isArray(value) || versionlessEnvelope;
|
|
32760
|
+
const input2 = legacy ? null : record(value);
|
|
32761
|
+
let monitors = Array.isArray(value) ? value : versionlessEnvelope ? (() => {
|
|
32762
|
+
const candidate = record(value)?.monitors;
|
|
32763
|
+
return Array.isArray(candidate) ? candidate : null;
|
|
32764
|
+
})() : null;
|
|
32765
|
+
if (Array.isArray(value)) {
|
|
32766
|
+
issues.push({
|
|
32767
|
+
severity: "warning",
|
|
32768
|
+
code: "deprecated_batch_array",
|
|
32769
|
+
path: "",
|
|
32770
|
+
message: "Bare monitor arrays are supported for compatibility.",
|
|
32771
|
+
suggestion: 'Wrap the list in {"version":1,"kind":"batch","monitors":[...]}.'
|
|
32772
|
+
});
|
|
32773
|
+
} else if (versionlessEnvelope) {
|
|
32774
|
+
issues.push({
|
|
32775
|
+
severity: "warning",
|
|
32776
|
+
code: "deprecated_batch_missing_envelope_fields",
|
|
32777
|
+
path: "",
|
|
32778
|
+
message: "Versionless monitor envelopes are supported for compatibility.",
|
|
32779
|
+
suggestion: 'Add "version": 1 and "kind": "batch".'
|
|
32780
|
+
});
|
|
32781
|
+
if (!monitors) {
|
|
32782
|
+
issues.push({
|
|
32783
|
+
severity: "error",
|
|
32784
|
+
code: "invalid_batch_monitors",
|
|
32785
|
+
path: "monitors",
|
|
32786
|
+
message: "Batch monitors must be an array."
|
|
32787
|
+
});
|
|
32788
|
+
}
|
|
32789
|
+
} else if (!input2) {
|
|
32790
|
+
issues.push({
|
|
32791
|
+
severity: "error",
|
|
32792
|
+
code: "invalid_batch",
|
|
32793
|
+
path: "",
|
|
32794
|
+
message: "Batch input must be an object or a legacy array."
|
|
32795
|
+
});
|
|
32796
|
+
} else {
|
|
32797
|
+
for (const key of Object.keys(input2)) {
|
|
32798
|
+
if (!["version", "kind", "monitors"].includes(key)) {
|
|
32799
|
+
issues.push({
|
|
32800
|
+
severity: "error",
|
|
32801
|
+
code: key === "source" || key === "monitor" ? "batch_fleet_shape_mixup" : "unknown_batch_field",
|
|
32802
|
+
path: key,
|
|
32803
|
+
message: `Batch input does not accept '${key}'.`
|
|
32804
|
+
});
|
|
32805
|
+
}
|
|
32806
|
+
}
|
|
32807
|
+
if (input2.version !== 1) {
|
|
32808
|
+
issues.push({
|
|
32809
|
+
severity: "error",
|
|
32810
|
+
code: "unsupported_batch_version",
|
|
32811
|
+
path: "version",
|
|
32812
|
+
message: "Batch input version must be 1."
|
|
32813
|
+
});
|
|
32814
|
+
}
|
|
32815
|
+
if (input2.kind !== "batch") {
|
|
32816
|
+
issues.push({
|
|
32817
|
+
severity: "error",
|
|
32818
|
+
code: "invalid_batch_kind",
|
|
32819
|
+
path: "kind",
|
|
32820
|
+
message: 'Batch input kind must be "batch".'
|
|
32821
|
+
});
|
|
32822
|
+
}
|
|
32823
|
+
monitors = Array.isArray(input2.monitors) ? input2.monitors : null;
|
|
32824
|
+
if (!monitors) {
|
|
32825
|
+
issues.push({
|
|
32826
|
+
severity: "error",
|
|
32827
|
+
code: "invalid_batch_monitors",
|
|
32828
|
+
path: "monitors",
|
|
32829
|
+
message: "Batch monitors must be an array."
|
|
32830
|
+
});
|
|
32831
|
+
}
|
|
32832
|
+
}
|
|
32833
|
+
if (!monitors || monitors.length === 0) {
|
|
32834
|
+
if (monitors?.length === 0) {
|
|
32835
|
+
issues.push({
|
|
32836
|
+
severity: "error",
|
|
32837
|
+
code: "empty_batch",
|
|
32838
|
+
path: "monitors",
|
|
32839
|
+
message: "A Batch needs at least one monitor."
|
|
32840
|
+
});
|
|
32841
|
+
}
|
|
32842
|
+
return { issues: issues.sort(issueOrder) };
|
|
32843
|
+
}
|
|
32844
|
+
const normalized = monitors.map(
|
|
32845
|
+
(item, index) => monitorSpec(item, `monitors.${index}`, issues)
|
|
32846
|
+
);
|
|
32847
|
+
const seen = /* @__PURE__ */ new Map();
|
|
32848
|
+
normalized.forEach((item, index) => {
|
|
32849
|
+
if (!item) return;
|
|
32850
|
+
const first = seen.get(item.key);
|
|
32851
|
+
if (first !== void 0) {
|
|
32852
|
+
for (const position of [first, index]) {
|
|
32853
|
+
issues.push({
|
|
32854
|
+
severity: "error",
|
|
32855
|
+
code: "duplicate_monitor_key",
|
|
32856
|
+
path: `monitors.${position}.key`,
|
|
32857
|
+
message: `Duplicate monitor key '${item.key}'.`
|
|
32858
|
+
});
|
|
32859
|
+
}
|
|
32860
|
+
} else {
|
|
32861
|
+
seen.set(item.key, index);
|
|
32862
|
+
}
|
|
32863
|
+
});
|
|
32864
|
+
const ordered = issues.sort(issueOrder);
|
|
32865
|
+
return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : {
|
|
32866
|
+
normalized: {
|
|
32867
|
+
version: 1,
|
|
32868
|
+
kind: "batch",
|
|
32869
|
+
monitors: normalized
|
|
32870
|
+
},
|
|
32871
|
+
issues: ordered
|
|
32872
|
+
};
|
|
32873
|
+
}
|
|
32874
|
+
function validateHandlebars(value, path, issues) {
|
|
32875
|
+
if (!value.includes("{{")) return;
|
|
32876
|
+
try {
|
|
32877
|
+
Handlebars.parse(value);
|
|
32878
|
+
} catch (error) {
|
|
32879
|
+
issues.push({
|
|
32880
|
+
severity: "error",
|
|
32881
|
+
code: "invalid_handlebars_template",
|
|
32882
|
+
path,
|
|
32883
|
+
message: error instanceof Error ? error.message : "Invalid Handlebars template."
|
|
32884
|
+
});
|
|
32885
|
+
return;
|
|
32886
|
+
}
|
|
32887
|
+
const expressions = value.match(/{{[\s\S]*?}}/g) ?? [];
|
|
32888
|
+
if (expressions.some(
|
|
32889
|
+
(expression) => !/^{{\s*[A-Za-z_][A-Za-z0-9_]*\s*}}$/.test(expression)
|
|
32890
|
+
)) {
|
|
32891
|
+
issues.push({
|
|
32892
|
+
severity: "error",
|
|
32893
|
+
code: "unsupported_handlebars_expression",
|
|
32894
|
+
path,
|
|
32895
|
+
message: "Fleet templates allow only direct source-row fields such as {{domain}}; helpers, blocks, partials, paths, and prototype access are disabled."
|
|
32896
|
+
});
|
|
32897
|
+
}
|
|
32898
|
+
}
|
|
32899
|
+
function walkTemplates(value, path, issues) {
|
|
32900
|
+
if (typeof value === "string") return validateHandlebars(value, path, issues);
|
|
32901
|
+
if (Array.isArray(value)) {
|
|
32902
|
+
value.forEach(
|
|
32903
|
+
(item, index) => walkTemplates(item, `${path}.${index}`, issues)
|
|
32904
|
+
);
|
|
32905
|
+
return;
|
|
32906
|
+
}
|
|
32907
|
+
const input2 = record(value);
|
|
32908
|
+
if (!input2) return;
|
|
32909
|
+
for (const [key, child] of Object.entries(input2)) {
|
|
32910
|
+
walkTemplates(child, `${path}.${key}`, issues);
|
|
32911
|
+
}
|
|
32912
|
+
}
|
|
32913
|
+
function lintMonitorSpecTemplate(value, path = "monitor") {
|
|
32914
|
+
const issues = [];
|
|
32915
|
+
const normalized = monitorSpec(value, path, issues);
|
|
32916
|
+
const input2 = record(value);
|
|
32917
|
+
if (input2 && typeof input2.tool === "string" && input2.tool.includes("{{")) {
|
|
32918
|
+
issues.push({
|
|
32919
|
+
severity: "error",
|
|
32920
|
+
code: "templated_monitor_tool",
|
|
32921
|
+
path: `${path}.tool`,
|
|
32922
|
+
message: "Fleet monitor tool must be literal; only key, name, and payload may be templated."
|
|
32923
|
+
});
|
|
32924
|
+
}
|
|
32925
|
+
if (input2) {
|
|
32926
|
+
for (const field of ["key", "name", "payload"]) {
|
|
32927
|
+
if (input2[field] !== void 0)
|
|
32928
|
+
walkTemplates(input2[field], `${path}.${field}`, issues);
|
|
32929
|
+
}
|
|
32930
|
+
}
|
|
32931
|
+
const ordered = issues.sort(issueOrder);
|
|
32932
|
+
return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : { normalized, issues: ordered };
|
|
32933
|
+
}
|
|
32934
|
+
|
|
32559
32935
|
// ../integration-contracts/monitor-fleet-contract.ts
|
|
32560
32936
|
var MONITOR_FLEET_MAX_MEMBERS = 1e3;
|
|
32561
|
-
var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
|
|
32562
32937
|
var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
|
|
32563
|
-
|
|
32938
|
+
1,
|
|
32939
|
+
2
|
|
32564
32940
|
];
|
|
32565
32941
|
var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
|
|
32566
32942
|
var MONITOR_FLEET_DOCUMENTATION = {
|
|
@@ -32568,11 +32944,11 @@ var MONITOR_FLEET_DOCUMENTATION = {
|
|
|
32568
32944
|
authoredFields: {
|
|
32569
32945
|
id: "Stable lowercase fleet id used by sync, get, and deactivate.",
|
|
32570
32946
|
source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
|
|
32571
|
-
|
|
32947
|
+
monitor: "One Batch-compatible MonitorSpec. Direct Handlebars source-row fields such as {{domain}} are rendered for each selected row.",
|
|
32572
32948
|
selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
|
|
32573
32949
|
},
|
|
32574
32950
|
fixedPolicy: {
|
|
32575
|
-
cadence: "
|
|
32951
|
+
cadence: "60s fair bounded source refresh",
|
|
32576
32952
|
membership: "sticky",
|
|
32577
32953
|
removalGrace: "7d",
|
|
32578
32954
|
onRemoved: "deactivate",
|
|
@@ -32580,9 +32956,10 @@ var MONITOR_FLEET_DOCUMENTATION = {
|
|
|
32580
32956
|
billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
|
|
32581
32957
|
},
|
|
32582
32958
|
stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
|
|
32583
|
-
|
|
32959
|
+
templating: "Use direct Handlebars fields such as {{domain}} in monitor key, name, or payload. Helpers, blocks, partials, paths, and prototype access are disabled.",
|
|
32960
|
+
legacyCompatibility: 'Edition 1 member/$fleet files remain readable with a lint warning; new files should use version: 2, kind: "fleet", and monitor.'
|
|
32584
32961
|
};
|
|
32585
|
-
function
|
|
32962
|
+
function record2(value) {
|
|
32586
32963
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
32587
32964
|
}
|
|
32588
32965
|
function identifier(value) {
|
|
@@ -32607,7 +32984,7 @@ function jsonValue(value, path, issues) {
|
|
|
32607
32984
|
value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
|
|
32608
32985
|
return;
|
|
32609
32986
|
}
|
|
32610
|
-
const input2 =
|
|
32987
|
+
const input2 = record2(value);
|
|
32611
32988
|
if (!input2) {
|
|
32612
32989
|
issues.push({
|
|
32613
32990
|
path,
|
|
@@ -32621,7 +32998,7 @@ function jsonValue(value, path, issues) {
|
|
|
32621
32998
|
}
|
|
32622
32999
|
}
|
|
32623
33000
|
function validateExpression(value, path, issues) {
|
|
32624
|
-
const input2 =
|
|
33001
|
+
const input2 = record2(value);
|
|
32625
33002
|
if (!input2 || input2.$fleet !== "column" || !identifier(input2.name)) {
|
|
32626
33003
|
issues.push({
|
|
32627
33004
|
path,
|
|
@@ -32639,7 +33016,7 @@ function walkPayload(value, path, issues) {
|
|
|
32639
33016
|
);
|
|
32640
33017
|
return;
|
|
32641
33018
|
}
|
|
32642
|
-
const input2 =
|
|
33019
|
+
const input2 = record2(value);
|
|
32643
33020
|
if (!input2) return;
|
|
32644
33021
|
if ("$fleet" in input2) {
|
|
32645
33022
|
validateExpression(input2, path, issues);
|
|
@@ -32649,9 +33026,9 @@ function walkPayload(value, path, issues) {
|
|
|
32649
33026
|
walkPayload(item, `${path}.${key}`, issues);
|
|
32650
33027
|
}
|
|
32651
33028
|
}
|
|
32652
|
-
function
|
|
33029
|
+
function validateMonitorFleetDefinitionV1(value) {
|
|
32653
33030
|
const issues = [];
|
|
32654
|
-
const input2 =
|
|
33031
|
+
const input2 = record2(value);
|
|
32655
33032
|
if (!input2) {
|
|
32656
33033
|
return {
|
|
32657
33034
|
valid: false,
|
|
@@ -32672,7 +33049,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32672
33049
|
message: "Fleet id must be lowercase kebab-case."
|
|
32673
33050
|
});
|
|
32674
33051
|
}
|
|
32675
|
-
const source =
|
|
33052
|
+
const source = record2(input2.source);
|
|
32676
33053
|
exactKeys(
|
|
32677
33054
|
source,
|
|
32678
33055
|
["kind", "schema", "table", "key", "where"],
|
|
@@ -32693,7 +33070,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32693
33070
|
message: "Source schema and table must be SQL identifiers."
|
|
32694
33071
|
});
|
|
32695
33072
|
}
|
|
32696
|
-
const sourceKey =
|
|
33073
|
+
const sourceKey = record2(source?.key);
|
|
32697
33074
|
exactKeys(sourceKey, ["column", "type"], "source.key", issues);
|
|
32698
33075
|
if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
|
|
32699
33076
|
issues.push({
|
|
@@ -32703,7 +33080,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32703
33080
|
});
|
|
32704
33081
|
}
|
|
32705
33082
|
if (source?.where !== void 0) {
|
|
32706
|
-
const where =
|
|
33083
|
+
const where = record2(source.where);
|
|
32707
33084
|
if (!where) {
|
|
32708
33085
|
issues.push({
|
|
32709
33086
|
path: "source.where",
|
|
@@ -32729,9 +33106,9 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32729
33106
|
}
|
|
32730
33107
|
}
|
|
32731
33108
|
}
|
|
32732
|
-
const member =
|
|
33109
|
+
const member = record2(input2.member);
|
|
32733
33110
|
exactKeys(member, ["tool", "key", "payload"], "member", issues);
|
|
32734
|
-
const key =
|
|
33111
|
+
const key = record2(member?.key);
|
|
32735
33112
|
if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
|
|
32736
33113
|
issues.push({
|
|
32737
33114
|
path: "member.tool",
|
|
@@ -32752,7 +33129,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32752
33129
|
validateExpression(part, `member.key.parts.${index}`, issues);
|
|
32753
33130
|
}
|
|
32754
33131
|
if (sourceKey && !key.parts.some(
|
|
32755
|
-
(part) =>
|
|
33132
|
+
(part) => record2(part)?.$fleet === "column" && record2(part)?.name === sourceKey.column
|
|
32756
33133
|
)) {
|
|
32757
33134
|
issues.push({
|
|
32758
33135
|
path: "member.key.parts",
|
|
@@ -32771,7 +33148,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32771
33148
|
jsonValue(member.payload, "member.payload", issues);
|
|
32772
33149
|
}
|
|
32773
33150
|
walkPayload(member?.payload, "member.payload", issues);
|
|
32774
|
-
const selection =
|
|
33151
|
+
const selection = record2(input2.selection);
|
|
32775
33152
|
exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
|
|
32776
33153
|
if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
|
|
32777
33154
|
issues.push({
|
|
@@ -32797,7 +33174,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32797
33174
|
} else {
|
|
32798
33175
|
const orderColumns = /* @__PURE__ */ new Set();
|
|
32799
33176
|
for (const [index, order] of orderBy.entries()) {
|
|
32800
|
-
const item =
|
|
33177
|
+
const item = record2(order);
|
|
32801
33178
|
exactKeys(
|
|
32802
33179
|
item,
|
|
32803
33180
|
["column", "direction"],
|
|
@@ -32820,7 +33197,7 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32820
33197
|
orderColumns.add(item.column);
|
|
32821
33198
|
}
|
|
32822
33199
|
}
|
|
32823
|
-
if (sourceKey &&
|
|
33200
|
+
if (sourceKey && record2(orderBy.at(-1))?.column !== sourceKey.column) {
|
|
32824
33201
|
issues.push({
|
|
32825
33202
|
path: "selection.orderBy",
|
|
32826
33203
|
code: "fleet_order_missing_key",
|
|
@@ -32839,9 +33216,100 @@ function validateMonitorFleetDefinition(value) {
|
|
|
32839
33216
|
}
|
|
32840
33217
|
return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
|
|
32841
33218
|
}
|
|
32842
|
-
function
|
|
33219
|
+
function v2Issue(issue) {
|
|
33220
|
+
return { path: issue.path, code: issue.code, message: issue.message };
|
|
33221
|
+
}
|
|
33222
|
+
function validateMonitorFleetDefinitionV2(value) {
|
|
33223
|
+
const issues = [];
|
|
33224
|
+
const input2 = record2(value);
|
|
33225
|
+
if (!input2) {
|
|
33226
|
+
return {
|
|
33227
|
+
valid: false,
|
|
33228
|
+
issues: [
|
|
33229
|
+
{
|
|
33230
|
+
path: "",
|
|
33231
|
+
code: "invalid_fleet",
|
|
33232
|
+
message: "Fleet must be an object."
|
|
33233
|
+
}
|
|
33234
|
+
]
|
|
33235
|
+
};
|
|
33236
|
+
}
|
|
33237
|
+
exactKeys(
|
|
33238
|
+
input2,
|
|
33239
|
+
["version", "kind", "id", "source", "monitor", "selection"],
|
|
33240
|
+
"",
|
|
33241
|
+
issues
|
|
33242
|
+
);
|
|
33243
|
+
if (input2.version !== 2) {
|
|
33244
|
+
issues.push({
|
|
33245
|
+
path: "version",
|
|
33246
|
+
code: "unsupported_fleet_version",
|
|
33247
|
+
message: "Canonical Fleet input version must be 2."
|
|
33248
|
+
});
|
|
33249
|
+
}
|
|
33250
|
+
if (input2.kind !== "fleet") {
|
|
33251
|
+
issues.push({
|
|
33252
|
+
path: "kind",
|
|
33253
|
+
code: "invalid_fleet_kind",
|
|
33254
|
+
message: 'Canonical Fleet input kind must be "fleet".'
|
|
33255
|
+
});
|
|
33256
|
+
}
|
|
33257
|
+
const source = record2(input2.source);
|
|
33258
|
+
const sourceKey = record2(source?.key);
|
|
33259
|
+
const legacyShape = {
|
|
33260
|
+
id: input2.id,
|
|
33261
|
+
source: input2.source,
|
|
33262
|
+
member: {
|
|
33263
|
+
tool: record2(input2.monitor)?.tool,
|
|
33264
|
+
key: {
|
|
33265
|
+
$fleet: "template",
|
|
33266
|
+
parts: [
|
|
33267
|
+
"fleet-",
|
|
33268
|
+
{
|
|
33269
|
+
$fleet: "column",
|
|
33270
|
+
name: typeof sourceKey?.column === "string" ? sourceKey.column : "invalid_source_key"
|
|
33271
|
+
}
|
|
33272
|
+
]
|
|
33273
|
+
},
|
|
33274
|
+
payload: record2(input2.monitor)?.payload
|
|
33275
|
+
},
|
|
33276
|
+
selection: input2.selection
|
|
33277
|
+
};
|
|
33278
|
+
const legacyCheck = validateMonitorFleetDefinitionV1(legacyShape);
|
|
33279
|
+
for (const issue of legacyCheck.issues) {
|
|
33280
|
+
issues.push({
|
|
33281
|
+
...issue,
|
|
33282
|
+
path: issue.path.replace(/^member\./, "monitor.")
|
|
33283
|
+
});
|
|
33284
|
+
}
|
|
33285
|
+
const monitorInput = record2(input2.monitor);
|
|
33286
|
+
const monitorKey = monitorInput?.key;
|
|
33287
|
+
const monitor = lintMonitorSpecTemplate(input2.monitor);
|
|
33288
|
+
issues.push(...monitor.issues.map(v2Issue));
|
|
33289
|
+
if (typeof monitorKey === "string" && typeof sourceKey?.column === "string" && !monitorKey.includes(`{{${sourceKey.column}}}`)) {
|
|
33290
|
+
issues.push({
|
|
33291
|
+
path: "monitor.key",
|
|
33292
|
+
code: "fleet_key_missing_source_key",
|
|
33293
|
+
message: "Monitor key must include the source key as a direct Handlebars expression."
|
|
33294
|
+
});
|
|
33295
|
+
}
|
|
33296
|
+
return issues.length === 0 && monitor.normalized ? {
|
|
33297
|
+
valid: true,
|
|
33298
|
+
definition: {
|
|
33299
|
+
version: 2,
|
|
33300
|
+
kind: "fleet",
|
|
33301
|
+
id: String(input2.id),
|
|
33302
|
+
source: input2.source,
|
|
33303
|
+
monitor: monitor.normalized,
|
|
33304
|
+
selection: input2.selection
|
|
33305
|
+
},
|
|
33306
|
+
issues
|
|
33307
|
+
} : { valid: false, issues };
|
|
33308
|
+
}
|
|
33309
|
+
function admitMonitorFleetAuthoringContract(value, edition) {
|
|
33310
|
+
const detectedEdition = edition ?? (record2(value)?.version === 2 || record2(value)?.kind === "fleet" ? 2 : 1);
|
|
32843
33311
|
if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
|
|
32844
|
-
|
|
33312
|
+
detectedEdition
|
|
32845
33313
|
)) {
|
|
32846
33314
|
return {
|
|
32847
33315
|
valid: false,
|
|
@@ -32849,16 +33317,16 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
|
|
|
32849
33317
|
{
|
|
32850
33318
|
path: "authoring_contract_edition",
|
|
32851
33319
|
code: "unsupported_fleet_authoring_contract_edition",
|
|
32852
|
-
message: `Monitor Fleet authoring contract edition ${
|
|
33320
|
+
message: `Monitor Fleet authoring contract edition ${detectedEdition} is not supported.`
|
|
32853
33321
|
}
|
|
32854
33322
|
]
|
|
32855
33323
|
};
|
|
32856
33324
|
}
|
|
32857
|
-
const result =
|
|
33325
|
+
const result = detectedEdition === 2 ? validateMonitorFleetDefinitionV2(value) : validateMonitorFleetDefinitionV1(value);
|
|
32858
33326
|
return result.valid && result.definition ? {
|
|
32859
33327
|
valid: true,
|
|
32860
33328
|
contract: {
|
|
32861
|
-
edition,
|
|
33329
|
+
edition: detectedEdition,
|
|
32862
33330
|
// JSON cloning prevents later caller mutation from changing the
|
|
32863
33331
|
// admitted snapshot.
|
|
32864
33332
|
definition: JSON.parse(
|
|
@@ -32868,6 +33336,32 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
|
|
|
32868
33336
|
issues: []
|
|
32869
33337
|
} : { valid: false, issues: result.issues };
|
|
32870
33338
|
}
|
|
33339
|
+
function lintMonitorFleetInput(value) {
|
|
33340
|
+
const input2 = record2(value);
|
|
33341
|
+
const legacy = input2?.member !== void 0;
|
|
33342
|
+
const admitted = admitMonitorFleetAuthoringContract(value);
|
|
33343
|
+
const issues = admitted.issues.map((issue) => ({
|
|
33344
|
+
...issue,
|
|
33345
|
+
severity: "error"
|
|
33346
|
+
}));
|
|
33347
|
+
if (legacy) {
|
|
33348
|
+
issues.push({
|
|
33349
|
+
severity: "warning",
|
|
33350
|
+
code: "deprecated_fleet_member",
|
|
33351
|
+
path: "member",
|
|
33352
|
+
message: "Legacy Fleet member syntax remains supported."
|
|
33353
|
+
});
|
|
33354
|
+
if (JSON.stringify(input2).includes('"$fleet"')) {
|
|
33355
|
+
issues.push({
|
|
33356
|
+
severity: "warning",
|
|
33357
|
+
code: "deprecated_fleet_expression",
|
|
33358
|
+
path: "member",
|
|
33359
|
+
message: "Legacy $fleet expressions remain supported; use direct Handlebars fields in monitor instead."
|
|
33360
|
+
});
|
|
33361
|
+
}
|
|
33362
|
+
}
|
|
33363
|
+
return admitted.valid && admitted.contract ? { normalized: admitted.contract.definition, issues } : { issues };
|
|
33364
|
+
}
|
|
32871
33365
|
|
|
32872
33366
|
// src/cli/commands/monitors.ts
|
|
32873
33367
|
var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
|
|
@@ -33553,6 +34047,155 @@ function fleetIdempotencyKey(operation, supplied) {
|
|
|
33553
34047
|
}
|
|
33554
34048
|
return normalized ?? `monitor-fleet-${operation}-${randomUUID5()}`;
|
|
33555
34049
|
}
|
|
34050
|
+
function monitorJobIdempotencyKey(operation, supplied) {
|
|
34051
|
+
const normalized = supplied?.trim();
|
|
34052
|
+
if (supplied !== void 0 && !normalized) {
|
|
34053
|
+
throw new MonitorsUsageError("--idempotency-key must not be empty.");
|
|
34054
|
+
}
|
|
34055
|
+
return normalized ?? `monitor-job-${operation}-${randomUUID5()}`;
|
|
34056
|
+
}
|
|
34057
|
+
function readMonitorDefinitionsJsonFile(file) {
|
|
34058
|
+
let raw;
|
|
34059
|
+
try {
|
|
34060
|
+
raw = file === "-" ? readFileSync11(0, "utf8") : readFileSync11(file, "utf8");
|
|
34061
|
+
} catch (error) {
|
|
34062
|
+
throw new MonitorsUsageError(
|
|
34063
|
+
`Could not read --file ${file}: ${error instanceof Error ? error.message : String(error)}`
|
|
34064
|
+
);
|
|
34065
|
+
}
|
|
34066
|
+
try {
|
|
34067
|
+
return JSON.parse(raw);
|
|
34068
|
+
} catch (error) {
|
|
34069
|
+
throw new MonitorsUsageError(
|
|
34070
|
+
`Monitor definitions must be valid JSON. ${error instanceof Error ? error.message : String(error)}`
|
|
34071
|
+
);
|
|
34072
|
+
}
|
|
34073
|
+
}
|
|
34074
|
+
function renderMonitorJob(payload) {
|
|
34075
|
+
const job = asRecord2(payload.job);
|
|
34076
|
+
if (!job) return void 0;
|
|
34077
|
+
const id = asString(job.id) ?? "<unknown>";
|
|
34078
|
+
const state = asString(job.state) ?? "unknown";
|
|
34079
|
+
const phase = asString(job.phase);
|
|
34080
|
+
const counts = asRecord2(job.counts);
|
|
34081
|
+
const reconciliation = asRecord2(job.reconciliation);
|
|
34082
|
+
const lines = [
|
|
34083
|
+
`Monitor job: ${id}`,
|
|
34084
|
+
`State: ${state}${phase ? ` (${phase})` : ""}`
|
|
34085
|
+
];
|
|
34086
|
+
if (counts) {
|
|
34087
|
+
lines.push(
|
|
34088
|
+
`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}`
|
|
34089
|
+
);
|
|
34090
|
+
}
|
|
34091
|
+
if (reconciliation) {
|
|
34092
|
+
lines.push(
|
|
34093
|
+
`Reconciliation: ${asString(reconciliation.state) ?? "pending"} (${asFiniteNumber(reconciliation.observed_bindings) ?? 0}/${asFiniteNumber(reconciliation.expected_bindings) ?? 0} bindings observed)`
|
|
34094
|
+
);
|
|
34095
|
+
}
|
|
34096
|
+
const next = asString(payload.next);
|
|
34097
|
+
if (next) lines.push(`Next: ${next}`);
|
|
34098
|
+
return `${lines.join("\n")}
|
|
34099
|
+
`;
|
|
34100
|
+
}
|
|
34101
|
+
async function handleMonitorJobBatchDeploy(options, idempotencyKey) {
|
|
34102
|
+
if (!options.file) {
|
|
34103
|
+
throw new MonitorsUsageError(
|
|
34104
|
+
"A Batch file is required. Pass --file batch.json (or --file - for stdin)."
|
|
34105
|
+
);
|
|
34106
|
+
}
|
|
34107
|
+
const lint = lintMonitorBatchInput(
|
|
34108
|
+
readMonitorDefinitionsJsonFile(options.file)
|
|
34109
|
+
);
|
|
34110
|
+
if (!lint.normalized) {
|
|
34111
|
+
throw new MonitorsUsageError(
|
|
34112
|
+
lint.issues.filter((issue) => issue.severity === "error").map((issue) => `${issue.path || "batch"}: ${issue.message}`).join("; ")
|
|
34113
|
+
);
|
|
34114
|
+
}
|
|
34115
|
+
const payload = await new DeeplineClient().monitors.batch.deploy(
|
|
34116
|
+
lint.normalized.monitors,
|
|
34117
|
+
{ idempotencyKey }
|
|
34118
|
+
);
|
|
34119
|
+
printCommandEnvelope(
|
|
34120
|
+
{
|
|
34121
|
+
...payload,
|
|
34122
|
+
idempotency_key: idempotencyKey,
|
|
34123
|
+
...lint.issues.length ? { lint: { issues: lint.issues } } : {}
|
|
34124
|
+
},
|
|
34125
|
+
{ json: options.json, text: renderMonitorJob(payload) }
|
|
34126
|
+
);
|
|
34127
|
+
}
|
|
34128
|
+
async function handleMonitorBatchLint(options) {
|
|
34129
|
+
if (!options.file) {
|
|
34130
|
+
throw new MonitorsUsageError(
|
|
34131
|
+
"monitors batch lint requires --file <batch.json>."
|
|
34132
|
+
);
|
|
34133
|
+
}
|
|
34134
|
+
const result = lintMonitorBatchInput(
|
|
34135
|
+
readMonitorDefinitionsJsonFile(options.file)
|
|
34136
|
+
);
|
|
34137
|
+
printCommandEnvelope(
|
|
34138
|
+
{
|
|
34139
|
+
ok: !result.issues.some((issue) => issue.severity === "error"),
|
|
34140
|
+
...result.normalized ? { normalized: result.normalized } : {},
|
|
34141
|
+
issues: result.issues
|
|
34142
|
+
},
|
|
34143
|
+
{ json: options.json }
|
|
34144
|
+
);
|
|
34145
|
+
if (result.issues.some((issue) => issue.severity === "error"))
|
|
34146
|
+
process.exitCode = 2;
|
|
34147
|
+
}
|
|
34148
|
+
async function handleMonitorFleetLint(options) {
|
|
34149
|
+
if (!options.file) {
|
|
34150
|
+
throw new MonitorsUsageError(
|
|
34151
|
+
"monitors fleets lint requires --file <fleet.json>."
|
|
34152
|
+
);
|
|
34153
|
+
}
|
|
34154
|
+
const result = lintMonitorFleetInput(
|
|
34155
|
+
readMonitorDefinitionsJsonFile(options.file)
|
|
34156
|
+
);
|
|
34157
|
+
printCommandEnvelope(
|
|
34158
|
+
{
|
|
34159
|
+
ok: !result.issues.some((issue) => issue.severity === "error"),
|
|
34160
|
+
...result.normalized ? { normalized: result.normalized } : {},
|
|
34161
|
+
issues: result.issues
|
|
34162
|
+
},
|
|
34163
|
+
{ json: options.json }
|
|
34164
|
+
);
|
|
34165
|
+
if (result.issues.some((issue) => issue.severity === "error"))
|
|
34166
|
+
process.exitCode = 2;
|
|
34167
|
+
}
|
|
34168
|
+
async function handleMonitorJobGet(jobId, options) {
|
|
34169
|
+
const payload = await new DeeplineClient().monitors.jobs.get(jobId);
|
|
34170
|
+
printCommandEnvelope(payload, {
|
|
34171
|
+
json: options.json,
|
|
34172
|
+
text: renderMonitorJob(payload)
|
|
34173
|
+
});
|
|
34174
|
+
}
|
|
34175
|
+
async function handleMonitorJobWait(jobId, options) {
|
|
34176
|
+
const payload = await new DeeplineClient().monitors.jobs.wait(jobId, {
|
|
34177
|
+
timeoutMs: fleetTimeoutMs(options.timeout),
|
|
34178
|
+
pollIntervalMs: FLEET_POLL_INTERVAL_MS
|
|
34179
|
+
});
|
|
34180
|
+
printCommandEnvelope(payload, {
|
|
34181
|
+
json: options.json,
|
|
34182
|
+
text: renderMonitorJob(payload)
|
|
34183
|
+
});
|
|
34184
|
+
}
|
|
34185
|
+
async function handleMonitorJobLogs(jobId, options) {
|
|
34186
|
+
const limit = options.limit ? fleetIntegerOption(options.limit, "--limit") : void 0;
|
|
34187
|
+
const payload = await new DeeplineClient().monitors.jobs.logs(jobId, {
|
|
34188
|
+
...limit === void 0 ? {} : { limit }
|
|
34189
|
+
});
|
|
34190
|
+
printCommandEnvelope(payload, { json: options.json });
|
|
34191
|
+
}
|
|
34192
|
+
async function handleMonitorJobCancel(jobId, options) {
|
|
34193
|
+
const payload = await new DeeplineClient().monitors.jobs.cancel(jobId);
|
|
34194
|
+
printCommandEnvelope(payload, {
|
|
34195
|
+
json: options.json,
|
|
34196
|
+
text: renderMonitorJob(payload)
|
|
34197
|
+
});
|
|
34198
|
+
}
|
|
33556
34199
|
var FLEET_COUNT_KEYS = [
|
|
33557
34200
|
"pending",
|
|
33558
34201
|
"submitting",
|
|
@@ -33574,12 +34217,12 @@ var MONITOR_FLEET_LIFECYCLE = [
|
|
|
33574
34217
|
{
|
|
33575
34218
|
step: 2,
|
|
33576
34219
|
what: "See the plan and the credits before anything changes.",
|
|
33577
|
-
command: "deepline monitors fleets
|
|
34220
|
+
command: "deepline monitors fleets deploy --file fleet.json --dry-run"
|
|
33578
34221
|
},
|
|
33579
34222
|
{
|
|
33580
34223
|
step: 3,
|
|
33581
34224
|
what: "Apply it and wait for the server to call it converged.",
|
|
33582
|
-
command: "deepline monitors fleets
|
|
34225
|
+
command: "deepline monitors fleets deploy --file fleet.json --wait"
|
|
33583
34226
|
},
|
|
33584
34227
|
{
|
|
33585
34228
|
step: 4,
|
|
@@ -33588,6 +34231,11 @@ var MONITOR_FLEET_LIFECYCLE = [
|
|
|
33588
34231
|
}
|
|
33589
34232
|
];
|
|
33590
34233
|
var MONITOR_FLEET_COMMANDS = [
|
|
34234
|
+
{
|
|
34235
|
+
name: "deploy",
|
|
34236
|
+
summary: "Create or update one table-backed Fleet from Customer DB rows."
|
|
34237
|
+
},
|
|
34238
|
+
{ name: "lint", summary: "Validate and normalize Fleet JSON locally." },
|
|
33591
34239
|
{ name: "init", summary: "Write a Fleet definition JSON file." },
|
|
33592
34240
|
{
|
|
33593
34241
|
name: "sync",
|
|
@@ -33733,6 +34381,26 @@ function renderFleetGet(payload) {
|
|
|
33733
34381
|
` counts ${fleetCountsLine(payload)}`,
|
|
33734
34382
|
` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 converged generation ${asFiniteNumber(payload.converged_generation) ?? "none"}`
|
|
33735
34383
|
];
|
|
34384
|
+
const boundPlays = Array.isArray(payload.bound_plays) ? payload.bound_plays.flatMap((value) => {
|
|
34385
|
+
const play = asRecord2(value);
|
|
34386
|
+
return play ? [play] : [];
|
|
34387
|
+
}) : [];
|
|
34388
|
+
lines.push("", `Observed Play bindings (${boundPlays.length}):`);
|
|
34389
|
+
if (boundPlays.length === 0) {
|
|
34390
|
+
lines.push(" none");
|
|
34391
|
+
} else {
|
|
34392
|
+
for (const play of boundPlays) {
|
|
34393
|
+
const name = asString(play.name) ?? "unnamed Play";
|
|
34394
|
+
const listeners = asFiniteNumber(play.listener_count) ?? 0;
|
|
34395
|
+
const status2 = asString(play.status);
|
|
34396
|
+
lines.push(
|
|
34397
|
+
` ${name}${listeners ? ` (${listeners} listener${listeners === 1 ? "" : "s"})` : ""}${status2 ? ` \u2014 ${status2}` : ""}`
|
|
34398
|
+
);
|
|
34399
|
+
}
|
|
34400
|
+
}
|
|
34401
|
+
lines.push(
|
|
34402
|
+
" Read-only observation. Define or change bindings in the Play with sqlListeners."
|
|
34403
|
+
);
|
|
33736
34404
|
lines.push(...renderFleetDriftRows(payload));
|
|
33737
34405
|
const next = fleetServerNext(payload) ?? (status === "degraded" ? `deepline monitors fleets get ${fleetShellArg(id)} --drift` : void 0);
|
|
33738
34406
|
if (next) lines.push(`Next: ${next}`);
|
|
@@ -33909,6 +34577,8 @@ async function handleMonitorFleetsInit(fleetId, options) {
|
|
|
33909
34577
|
const out = options.out?.trim();
|
|
33910
34578
|
if (!out) throw new MonitorsUsageError("--out is required.");
|
|
33911
34579
|
const authoredDefinition = {
|
|
34580
|
+
version: 2,
|
|
34581
|
+
kind: "fleet",
|
|
33912
34582
|
id: fleetId,
|
|
33913
34583
|
source: {
|
|
33914
34584
|
kind: "customer_db_table",
|
|
@@ -33917,12 +34587,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
|
|
|
33917
34587
|
key: { column: key, type: keyType },
|
|
33918
34588
|
...where ? { where } : {}
|
|
33919
34589
|
},
|
|
33920
|
-
|
|
34590
|
+
monitor: {
|
|
33921
34591
|
tool,
|
|
33922
|
-
key: {
|
|
33923
|
-
$fleet: "template",
|
|
33924
|
-
parts: [`${fleetId}-`, { $fleet: "column", name: key }]
|
|
33925
|
-
},
|
|
34592
|
+
key: `${fleetId}-{{${key}}}`,
|
|
33926
34593
|
payload
|
|
33927
34594
|
},
|
|
33928
34595
|
selection: {
|
|
@@ -33935,9 +34602,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
|
|
|
33935
34602
|
const file = resolve14(out);
|
|
33936
34603
|
writeFileSync12(file, `${JSON.stringify(definition, null, 2)}
|
|
33937
34604
|
`, "utf8");
|
|
33938
|
-
const next = `deepline monitors fleets
|
|
34605
|
+
const next = `deepline monitors fleets deploy --file ${fleetShellArg(file)} --dry-run --json`;
|
|
33939
34606
|
printCommandEnvelope(
|
|
33940
|
-
{ schemaVersion:
|
|
34607
|
+
{ schemaVersion: 2, file, definition, next },
|
|
33941
34608
|
{
|
|
33942
34609
|
json: options.json,
|
|
33943
34610
|
text: `Wrote ${file}
|
|
@@ -33947,8 +34614,8 @@ Next: ${next}
|
|
|
33947
34614
|
);
|
|
33948
34615
|
}
|
|
33949
34616
|
function requireCompiledFleetDefinition(definition) {
|
|
33950
|
-
const result =
|
|
33951
|
-
if (result.
|
|
34617
|
+
const result = lintMonitorFleetInput(definition);
|
|
34618
|
+
if (result.normalized) return result.normalized;
|
|
33952
34619
|
const messages = result.issues.map((issue) => `${issue.path || "definition"}: ${issue.message}`).join("; ");
|
|
33953
34620
|
throw new MonitorsUsageError(
|
|
33954
34621
|
`Monitor Fleet definition failed local contract check. ${messages}
|
|
@@ -33975,6 +34642,7 @@ function fleetSyncCommandLine(target, options) {
|
|
|
33975
34642
|
return parts.join(" ");
|
|
33976
34643
|
}
|
|
33977
34644
|
async function handleMonitorFleetsSync(target, options, idempotencyKey) {
|
|
34645
|
+
const fileDefinitions = options.file ? readMonitorDefinitionsJsonFile(options.file) : void 0;
|
|
33978
34646
|
const usesDefinition = options.file !== void 0 || target?.trim().startsWith("{") === true;
|
|
33979
34647
|
if (!usesDefinition && !target?.trim()) {
|
|
33980
34648
|
throw new MonitorsUsageError(
|
|
@@ -33982,12 +34650,14 @@ async function handleMonitorFleetsSync(target, options, idempotencyKey) {
|
|
|
33982
34650
|
);
|
|
33983
34651
|
}
|
|
33984
34652
|
const definition = usesDefinition ? requireCompiledFleetDefinition(
|
|
33985
|
-
|
|
33986
|
-
|
|
33987
|
-
|
|
33988
|
-
|
|
33989
|
-
|
|
33990
|
-
|
|
34653
|
+
asRecord2(
|
|
34654
|
+
fileDefinitions ?? resolveMonitorJsonBody({
|
|
34655
|
+
positional: target,
|
|
34656
|
+
file: options.file,
|
|
34657
|
+
argLabel: "<definition>",
|
|
34658
|
+
command: "deepline monitors fleets sync"
|
|
34659
|
+
})
|
|
34660
|
+
) ?? {}
|
|
33991
34661
|
) : void 0;
|
|
33992
34662
|
const fleetId = definition ? asString(definition.id) ?? "" : target.trim();
|
|
33993
34663
|
if (!fleetId) {
|
|
@@ -34388,14 +35058,14 @@ function renderMonitorGet(payload) {
|
|
|
34388
35058
|
` deepline monitors test ${key} '${JSON.stringify(samplePayload2)}' --json`
|
|
34389
35059
|
);
|
|
34390
35060
|
}
|
|
34391
|
-
const
|
|
34392
|
-
if (
|
|
35061
|
+
const monitorSpec2 = asRecord2(payload.monitor_spec);
|
|
35062
|
+
if (monitorSpec2?.available === false) {
|
|
34393
35063
|
lines.push(
|
|
34394
35064
|
"",
|
|
34395
|
-
`Monitor spec: unavailable \u2014 ${asString(
|
|
35065
|
+
`Monitor spec: unavailable \u2014 ${asString(monitorSpec2.message) ?? "use the stored definition and check before an update."}`
|
|
34396
35066
|
);
|
|
34397
35067
|
}
|
|
34398
|
-
const specFields = Array.isArray(
|
|
35068
|
+
const specFields = Array.isArray(monitorSpec2?.fields) ? monitorSpec2.fields.flatMap((value) => {
|
|
34399
35069
|
const field = asRecord2(value);
|
|
34400
35070
|
const path = asString(field?.path);
|
|
34401
35071
|
const description = asString(field?.description);
|
|
@@ -34869,6 +35539,8 @@ Notes:
|
|
|
34869
35539
|
Deepline monitors are Deepline-native signal feeds: a monitor writes events
|
|
34870
35540
|
into a Customer DB table; a play reacts to each new row via a
|
|
34871
35541
|
sqlListeners trigger \u2014 see \`deepline plays bootstrap monitor-triggered\`.
|
|
35542
|
+
Monitor JSON declares only what to watch (key, tool, optional name, payload).
|
|
35543
|
+
Play bindings belong in the Play; monitor deployment never changes them.
|
|
34872
35544
|
The Monitors rollout controls access to the live provider catalog; use
|
|
34873
35545
|
\`deepline tools list --categories monitors\` for the exact tool ids available to you.
|
|
34874
35546
|
Contact the Deepline team to request access; until access is enabled, these
|
|
@@ -34981,19 +35653,31 @@ Examples:
|
|
|
34981
35653
|
);
|
|
34982
35654
|
withJsonOption(
|
|
34983
35655
|
batch.command("deploy").description(
|
|
34984
|
-
"
|
|
35656
|
+
"Create a Monitor Job from canonical Batch JSON; legacy NDJSON remains available with --yes or --dry-run."
|
|
34985
35657
|
).requiredOption(
|
|
34986
35658
|
"--file <path>",
|
|
34987
|
-
"
|
|
34988
|
-
).option("--dry-run", "
|
|
35659
|
+
'Batch JSON ({"version":1,"kind":"batch","monitors":[...]}), or legacy NDJSON with --yes/--dry-run'
|
|
35660
|
+
).option("--dry-run", "Use the retained legacy batch-operation plan").option("--yes", "Use the retained legacy NDJSON batch operation").option(
|
|
34989
35661
|
"--idempotency-key <key>",
|
|
34990
35662
|
"Stable retry key (generated when omitted)"
|
|
34991
35663
|
)
|
|
34992
35664
|
).action(
|
|
34993
|
-
monitorsAction(
|
|
34994
|
-
(options
|
|
34995
|
-
|
|
35665
|
+
monitorsAction(async (options) => {
|
|
35666
|
+
if (options.dryRun === true || options.yes === true) {
|
|
35667
|
+
return await handleMonitorBatchDeploy(options);
|
|
35668
|
+
}
|
|
35669
|
+
const idempotencyKey = monitorJobIdempotencyKey(
|
|
35670
|
+
"batch-deploy",
|
|
35671
|
+
options.idempotencyKey
|
|
35672
|
+
);
|
|
35673
|
+
return await handleMonitorJobBatchDeploy(options, idempotencyKey);
|
|
35674
|
+
})
|
|
34996
35675
|
);
|
|
35676
|
+
withJsonOption(
|
|
35677
|
+
batch.command("lint").description(
|
|
35678
|
+
"Validate and normalize Batch JSON without network or provider work."
|
|
35679
|
+
).requiredOption("--file <path>", "Batch JSON file, or - for stdin")
|
|
35680
|
+
).action(monitorsAction(handleMonitorBatchLint));
|
|
34997
35681
|
withJsonOption(
|
|
34998
35682
|
batchSelectorOptions(
|
|
34999
35683
|
batch.command("audit").description("Durably audit a selection; defaults to --target all.")
|
|
@@ -35162,9 +35846,8 @@ Examples:
|
|
|
35162
35846
|
"after",
|
|
35163
35847
|
`
|
|
35164
35848
|
Notes:
|
|
35165
|
-
Read-only validation. <definition> is a JSON object with key, tool,
|
|
35166
|
-
and
|
|
35167
|
-
via --file <path>, or
|
|
35849
|
+
Read-only validation. <definition> is a JSON object with key, tool, optional
|
|
35850
|
+
name, and payload. Pass it positionally, via --file <path>, or
|
|
35168
35851
|
from stdin with --file -. Does not deploy or spend credits.
|
|
35169
35852
|
Check validates the local definition only. It does not contact an existing
|
|
35170
35853
|
upstream resource, prove that future events will arrive, or verify downstream
|
|
@@ -35172,12 +35855,8 @@ Notes:
|
|
|
35172
35855
|
Provider-specific grammar, precedence, enum applicability, examples, and
|
|
35173
35856
|
update semantics are returned by the live monitor contract. Inspect it with
|
|
35174
35857
|
\`deepline tools get deepline_native.company_radar --json\`.
|
|
35175
|
-
|
|
35176
|
-
|
|
35177
|
-
do not author custom_fields yourself. Priority is capped at ten upstream or
|
|
35178
|
-
reserved recovery, replacement, or reactivation slots per org. Use
|
|
35179
|
-
\`monitors list --status all\` to find priority holders; it is not for regular
|
|
35180
|
-
or bulk-scale monitoring.
|
|
35858
|
+
Operational controls are Deepline-managed. Bind downstream automation in a
|
|
35859
|
+
Play with sqlListeners; monitor definitions never name Plays.
|
|
35181
35860
|
|
|
35182
35861
|
Examples:
|
|
35183
35862
|
deepline monitors check '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
|
|
@@ -35195,8 +35874,8 @@ Examples:
|
|
|
35195
35874
|
`
|
|
35196
35875
|
Notes:
|
|
35197
35876
|
Mutates workspace state and may spend Deepline credits. <definition> is a JSON
|
|
35198
|
-
object with key, tool,
|
|
35199
|
-
|
|
35877
|
+
object with key, tool, optional name, and payload. Pass it positionally, via
|
|
35878
|
+
--file <path>, or from stdin with --file -.
|
|
35200
35879
|
--dry-run validates the definition and shows the plan (deploy cost in Deepline
|
|
35201
35880
|
credits when the server reports it, plus any existing monitors that may
|
|
35202
35881
|
already cover this scope) WITHOUT deploying. Exits 0 when valid, 7 when not.
|
|
@@ -35213,10 +35892,8 @@ Notes:
|
|
|
35213
35892
|
historical replay request, including when redeploying a disabled monitor.
|
|
35214
35893
|
Deepline preserves that selected boundary; filter-only deploys and ordinary
|
|
35215
35894
|
reactivation start from a fresh future-only source boundary instead.
|
|
35216
|
-
|
|
35217
|
-
|
|
35218
|
-
field and enforces a ten-slot per-org cap; do not use it for regular or bulk
|
|
35219
|
-
monitoring, and do not delete another radar automatically to make room.
|
|
35895
|
+
Operational controls are Deepline-managed. A monitor writes rows; downstream
|
|
35896
|
+
automation belongs in a Play with sqlListeners.
|
|
35220
35897
|
|
|
35221
35898
|
Examples:
|
|
35222
35899
|
deepline monitors deploy '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
|
|
@@ -35247,10 +35924,6 @@ request. Deepline passes that requested boundary upstream, but previously
|
|
|
35247
35924
|
delivered canonical findings are deduplicated before dispatch and billing; only
|
|
35248
35925
|
previously unseen historical findings are chargeable. Filter-only updates,
|
|
35249
35926
|
repair, and reactivation instead use a fresh future-only source boundary.
|
|
35250
|
-
Use {"controls":{"execution_type":"priority"}} only for a bounded urgent
|
|
35251
|
-
Deepline Native preview. The ten-radar priority cap applies on update too.
|
|
35252
|
-
Use {"controls":{"execution_type":null}} to release priority without
|
|
35253
|
-
deleting the monitor.
|
|
35254
35927
|
|
|
35255
35928
|
Examples:
|
|
35256
35929
|
deepline monitors update my-monitor '{"name":"Interested replies"}' --json
|
|
@@ -35298,13 +35971,30 @@ Examples:
|
|
|
35298
35971
|
`
|
|
35299
35972
|
).option("--dry-run", "Show the reactivation cost without reactivating")
|
|
35300
35973
|
).action(monitorsAction(handleMonitorsReactivate));
|
|
35301
|
-
const
|
|
35974
|
+
const jobs = monitors.command("jobs").description("Read, wait for, inspect, or cancel Monitor Jobs.");
|
|
35975
|
+
withJsonOption(jobs);
|
|
35976
|
+
withJsonOption(
|
|
35977
|
+
jobs.command("get <job-id>").description("Read the durable Monitor Job state.")
|
|
35978
|
+
).action(monitorsAction(handleMonitorJobGet));
|
|
35979
|
+
withJsonOption(
|
|
35980
|
+
jobs.command("wait <job-id>").description(
|
|
35981
|
+
"Wait for real provider reconciliation, not request acceptance."
|
|
35982
|
+
).option("--timeout <duration>", "How long to wait (default 10m)")
|
|
35983
|
+
).action(monitorsAction(handleMonitorJobWait));
|
|
35984
|
+
withJsonOption(
|
|
35985
|
+
jobs.command("logs <job-id>").description("Read bounded operator logs for one Monitor Job.").option("--limit <n>", "Maximum log entries (1..200)")
|
|
35986
|
+
).action(monitorsAction(handleMonitorJobLogs));
|
|
35987
|
+
withJsonOption(
|
|
35988
|
+
jobs.command("cancel <job-id>").description("Stop unscheduled work and reconcile the partial result.")
|
|
35989
|
+
).action(monitorsAction(handleMonitorJobCancel));
|
|
35990
|
+
const fleets = monitors.command("fleets").description("Manage table-backed Fleets.").addHelpText(
|
|
35302
35991
|
"after",
|
|
35303
35992
|
`
|
|
35304
35993
|
Notes:
|
|
35305
35994
|
A Monitor Fleet maps eligible rows in one Customer DB table to ordinary
|
|
35306
|
-
monitors. Fleet definitions are canonical JSON, and \`
|
|
35307
|
-
|
|
35995
|
+
monitors. Fleet definitions are canonical JSON, and \`deploy\` applies one;
|
|
35996
|
+
\`sync\` remains its exact compatibility alias. Applying the same definition
|
|
35997
|
+
twice is the same operation,
|
|
35308
35998
|
so the server answers \`replayed: true\` instead of building a second fleet.
|
|
35309
35999
|
The fleet's status is computed by Deepline; this CLI reports it and never
|
|
35310
36000
|
recomputes a verdict from the counts.
|
|
@@ -35326,6 +36016,29 @@ ${MONITOR_FLEET_HELP_EPILOG}`
|
|
|
35326
36016
|
})
|
|
35327
36017
|
);
|
|
35328
36018
|
withJsonOption(fleets);
|
|
36019
|
+
withJsonOption(
|
|
36020
|
+
fleets.command("deploy [fleet-id]").description(
|
|
36021
|
+
"Apply a table-backed Fleet definition; sync remains an exact alias."
|
|
36022
|
+
).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(
|
|
36023
|
+
"--expected-generation <generation>",
|
|
36024
|
+
"Optimistic generation fence"
|
|
36025
|
+
).option("--idempotency-key <key>", "Stable retry key")
|
|
36026
|
+
).action(
|
|
36027
|
+
monitorsAction(
|
|
36028
|
+
async (fleetId, options) => {
|
|
36029
|
+
const idempotencyKey = fleetIdempotencyKey(
|
|
36030
|
+
"deploy",
|
|
36031
|
+
options.idempotencyKey
|
|
36032
|
+
);
|
|
36033
|
+
await handleMonitorFleetsSync(fleetId, options, idempotencyKey);
|
|
36034
|
+
}
|
|
36035
|
+
)
|
|
36036
|
+
);
|
|
36037
|
+
withJsonOption(
|
|
36038
|
+
fleets.command("lint").description(
|
|
36039
|
+
"Validate and normalize Fleet JSON without network or provider work."
|
|
36040
|
+
).requiredOption("--file <path>", "Fleet JSON file, or - for stdin")
|
|
36041
|
+
).action(monitorsAction(handleMonitorFleetLint));
|
|
35329
36042
|
withJsonOption(
|
|
35330
36043
|
fleets.command("init <fleet-id>").description("Write an opinionated Fleet definition JSON file.").addHelpText(
|
|
35331
36044
|
"after",
|
|
@@ -35339,13 +36052,13 @@ Example:
|
|
|
35339
36052
|
deepline monitors fleets init account-job-openings \\
|
|
35340
36053
|
--source public.accounts --key account_id --key-type uuid \\
|
|
35341
36054
|
--tool deepline_native.company_radar \\
|
|
35342
|
-
--payload '{"domain":{
|
|
36055
|
+
--payload '{"domain":"{{domain}}","radar_type":"company_job_openings"}' \\
|
|
35343
36056
|
--order-by intent_score:desc \\
|
|
35344
36057
|
--out fleet.json
|
|
35345
36058
|
`
|
|
35346
36059
|
).requiredOption("--source <schema.table>", "Customer DB source table").requiredOption("--key <column>", "Unique source-row key column").option("--key-type <type>", "text, uuid, int4, or int8 (default text)").requiredOption("--tool <tool>", "Monitor tool to create per source row").requiredOption(
|
|
35347
36060
|
"--payload <json>",
|
|
35348
|
-
"Monitor payload JSON for --tool; use
|
|
36061
|
+
"Monitor payload JSON for --tool; use Handlebars fields such as {{domain}} for row values"
|
|
35349
36062
|
).option(
|
|
35350
36063
|
"--where <json>",
|
|
35351
36064
|
"Optional source-row equality filter JSON; not arbitrary SQL"
|
|
@@ -35421,7 +36134,9 @@ Examples:
|
|
|
35421
36134
|
Notes:
|
|
35422
36135
|
Status is the server's verdict. --check turns it into an exit code so a
|
|
35423
36136
|
script can branch without parsing output: 0 converged, 6 anything else.
|
|
35424
|
-
--drift lists the members that have not settled and why.
|
|
36137
|
+
--drift lists the members that have not settled and why. The detail also
|
|
36138
|
+
shows the current Plays that observe this Fleet's output; those bindings are
|
|
36139
|
+
read-only here and are defined by each Play's sqlListeners.
|
|
35425
36140
|
|
|
35426
36141
|
Examples:
|
|
35427
36142
|
deepline monitors fleets get --json
|
|
@@ -37549,8 +38264,8 @@ function classifyNetworkFailure(error) {
|
|
|
37549
38264
|
let current = error;
|
|
37550
38265
|
while (current && !seen.has(current)) {
|
|
37551
38266
|
seen.add(current);
|
|
37552
|
-
const
|
|
37553
|
-
const code = String(
|
|
38267
|
+
const record3 = typeof current === "object" && current !== null ? current : {};
|
|
38268
|
+
const code = String(record3.code ?? "").toLowerCase();
|
|
37554
38269
|
const name = current instanceof Error ? current.name.toLowerCase() : "";
|
|
37555
38270
|
const text = String(
|
|
37556
38271
|
current instanceof Error ? current.message : current
|
|
@@ -37577,7 +38292,7 @@ function classifyNetworkFailure(error) {
|
|
|
37577
38292
|
if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
|
|
37578
38293
|
return "network_ssl_error";
|
|
37579
38294
|
}
|
|
37580
|
-
current =
|
|
38295
|
+
current = record3.cause ?? record3.context;
|
|
37581
38296
|
}
|
|
37582
38297
|
return "network_error";
|
|
37583
38298
|
}
|
|
@@ -38654,26 +39369,26 @@ function parseSetupPhases(value) {
|
|
|
38654
39369
|
if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
|
|
38655
39370
|
return null;
|
|
38656
39371
|
}
|
|
38657
|
-
const
|
|
38658
|
-
if (!isSetupPhaseStatus(
|
|
38659
|
-
switch (
|
|
39372
|
+
const record3 = phase;
|
|
39373
|
+
if (!isSetupPhaseStatus(record3.status)) return null;
|
|
39374
|
+
switch (record3.status) {
|
|
38660
39375
|
case "pending":
|
|
38661
39376
|
case "in_progress":
|
|
38662
|
-
phases[name] = { status:
|
|
39377
|
+
phases[name] = { status: record3.status };
|
|
38663
39378
|
break;
|
|
38664
39379
|
case "complete":
|
|
38665
39380
|
phases[name] = {
|
|
38666
39381
|
status: "complete",
|
|
38667
|
-
...typeof
|
|
39382
|
+
...typeof record3.outcome === "string" ? { outcome: record3.outcome } : {}
|
|
38668
39383
|
};
|
|
38669
39384
|
break;
|
|
38670
39385
|
case "waiting":
|
|
38671
|
-
if (typeof
|
|
38672
|
-
phases[name] = { status: "waiting", outcome:
|
|
39386
|
+
if (typeof record3.outcome !== "string") return null;
|
|
39387
|
+
phases[name] = { status: "waiting", outcome: record3.outcome };
|
|
38673
39388
|
break;
|
|
38674
39389
|
case "failed":
|
|
38675
|
-
if (typeof
|
|
38676
|
-
phases[name] = { status: "failed", code:
|
|
39390
|
+
if (typeof record3.code !== "string") return null;
|
|
39391
|
+
phases[name] = { status: "failed", code: record3.code };
|
|
38677
39392
|
break;
|
|
38678
39393
|
}
|
|
38679
39394
|
}
|
|
@@ -42124,9 +42839,9 @@ function requiredInputIds(tool) {
|
|
|
42124
42839
|
return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
|
|
42125
42840
|
}
|
|
42126
42841
|
function notConnectedSuffix(tool) {
|
|
42127
|
-
const
|
|
42128
|
-
const status = stringField2(
|
|
42129
|
-
const connected =
|
|
42842
|
+
const record3 = tool;
|
|
42843
|
+
const status = stringField2(record3, "credentialStatus", "credential_status");
|
|
42844
|
+
const connected = record3.connected;
|
|
42130
42845
|
const message = toolConnectionStatusMessage({
|
|
42131
42846
|
connected: connected === false ? false : void 0,
|
|
42132
42847
|
credentialStatus: status || void 0
|
|
@@ -42505,19 +43220,19 @@ function printPlayAliasToolError(toolId, play) {
|
|
|
42505
43220
|
console.error(playAliasToolErrorMessage(toolId, play));
|
|
42506
43221
|
}
|
|
42507
43222
|
function isPlayLikeTool(tool) {
|
|
42508
|
-
const
|
|
42509
|
-
if (
|
|
42510
|
-
const playExpansion = recordField2(
|
|
43223
|
+
const record3 = tool;
|
|
43224
|
+
if (record3.isPlay === true || record3.is_play === true) return true;
|
|
43225
|
+
const playExpansion = recordField2(record3, "playExpansion", "play_expansion");
|
|
42511
43226
|
if (Object.keys(playExpansion).length > 0) return true;
|
|
42512
|
-
const toolId = typeof
|
|
43227
|
+
const toolId = typeof record3.toolId === "string" ? record3.toolId : "";
|
|
42513
43228
|
return toolId.endsWith("_waterfall");
|
|
42514
43229
|
}
|
|
42515
43230
|
function isMonitorTypeTool(tool) {
|
|
42516
43231
|
return stringField2(tool, "kind") === "monitor_type";
|
|
42517
43232
|
}
|
|
42518
43233
|
function playReferenceForTool(tool) {
|
|
42519
|
-
const
|
|
42520
|
-
const declared = stringField2(
|
|
43234
|
+
const record3 = tool;
|
|
43235
|
+
const declared = stringField2(record3, "playReference", "play_reference");
|
|
42521
43236
|
if (declared.startsWith("prebuilt/")) {
|
|
42522
43237
|
return declared;
|
|
42523
43238
|
}
|
|
@@ -43457,12 +44172,12 @@ function singleLineText(value, maxLength = 260) {
|
|
|
43457
44172
|
return `${text.slice(0, maxLength - 3).trimEnd()}...`;
|
|
43458
44173
|
}
|
|
43459
44174
|
function listedToolDescription(tool) {
|
|
43460
|
-
const
|
|
43461
|
-
return singleLineText(
|
|
44175
|
+
const record3 = tool;
|
|
44176
|
+
return singleLineText(record3.bestFor ?? record3.best_for ?? tool.description);
|
|
43462
44177
|
}
|
|
43463
44178
|
function formatListedToolCost(tool) {
|
|
43464
|
-
const
|
|
43465
|
-
const pricing = recordField2(
|
|
44179
|
+
const record3 = tool;
|
|
44180
|
+
const pricing = recordField2(record3, "pricing");
|
|
43466
44181
|
const displayText = stringField2(pricing, "displayText", "display_text");
|
|
43467
44182
|
return displayText ? `Cost: ${displayText}` : "";
|
|
43468
44183
|
}
|
|
@@ -44518,9 +45233,9 @@ function noticeToStderr(command) {
|
|
|
44518
45233
|
);
|
|
44519
45234
|
}
|
|
44520
45235
|
function emitPassThrough(command, payload, options) {
|
|
44521
|
-
const
|
|
45236
|
+
const json2 = shouldEmitJson(options.json);
|
|
44522
45237
|
const deprecation = migrationDeprecation(command);
|
|
44523
|
-
if (
|
|
45238
|
+
if (json2) {
|
|
44524
45239
|
const enriched = payload && typeof payload === "object" && !Array.isArray(payload) ? { ...payload, deprecation } : { result: payload, deprecation };
|
|
44525
45240
|
printJson(enriched);
|
|
44526
45241
|
return;
|
|
@@ -44541,9 +45256,9 @@ function clientWithTimeout(timeoutSeconds) {
|
|
|
44541
45256
|
}
|
|
44542
45257
|
function readStatus(payload) {
|
|
44543
45258
|
if (!payload || typeof payload !== "object") return null;
|
|
44544
|
-
const
|
|
44545
|
-
if (typeof
|
|
44546
|
-
const run =
|
|
45259
|
+
const record3 = payload;
|
|
45260
|
+
if (typeof record3.status === "string") return record3.status;
|
|
45261
|
+
const run = record3.run;
|
|
44547
45262
|
if (run && typeof run === "object") {
|
|
44548
45263
|
const status = run.status;
|
|
44549
45264
|
if (typeof status === "string") return status;
|