deepline 0.1.185 → 0.1.187
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/apps/play-runner-workers/src/coordinator-entry.ts +43 -4
- package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +2 -2
- package/dist/bundling-sources/sdk/src/play.ts +24 -3
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/sdk/src/types.ts +88 -0
- package/dist/cli/index.js +1424 -239
- package/dist/cli/index.mjs +1371 -186
- package/dist/index.d.mts +113 -3
- package/dist/index.d.ts +113 -3
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -181,7 +181,7 @@ function configureProxyFromEnv() {
|
|
|
181
181
|
configureProxyFromEnv();
|
|
182
182
|
|
|
183
183
|
// src/cli/index.ts
|
|
184
|
-
var
|
|
184
|
+
var import_promises6 = require("fs/promises");
|
|
185
185
|
var import_node_path20 = require("path");
|
|
186
186
|
var import_node_os15 = require("os");
|
|
187
187
|
var import_commander3 = require("commander");
|
|
@@ -623,10 +623,10 @@ var SDK_RELEASE = {
|
|
|
623
623
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
624
624
|
// fields shipped in 0.1.153.
|
|
625
625
|
// 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
|
|
626
|
-
version: "0.1.
|
|
626
|
+
version: "0.1.187",
|
|
627
627
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
628
628
|
supportPolicy: {
|
|
629
|
-
latest: "0.1.
|
|
629
|
+
latest: "0.1.187",
|
|
630
630
|
minimumSupported: "0.1.53",
|
|
631
631
|
deprecatedBelow: "0.1.53",
|
|
632
632
|
commandMinimumSupported: [
|
|
@@ -8278,13 +8278,155 @@ var PLAY_BOOTSTRAP_STAGE_NAMES = [
|
|
|
8278
8278
|
"email",
|
|
8279
8279
|
"phone"
|
|
8280
8280
|
];
|
|
8281
|
+
var MONITOR_BOOTSTRAP_TEMPLATE = "monitor-triggered";
|
|
8282
|
+
var MONITOR_BOOTSTRAP_DEFAULT_TOOL = "instantly.campaign_events";
|
|
8283
|
+
var MONITOR_BOOTSTRAP_DEFAULT_STREAM = "webhook_events";
|
|
8284
|
+
function isMonitorBootstrapTemplate(value) {
|
|
8285
|
+
return value === MONITOR_BOOTSTRAP_TEMPLATE;
|
|
8286
|
+
}
|
|
8287
|
+
function hasMonitorBootstrapForbiddenChar(value) {
|
|
8288
|
+
for (const char of value) {
|
|
8289
|
+
const code = char.codePointAt(0) ?? 0;
|
|
8290
|
+
if (code < 32 || code === 127) return true;
|
|
8291
|
+
if (char === "'" || char === '"' || char === "`" || char === "\\") {
|
|
8292
|
+
return true;
|
|
8293
|
+
}
|
|
8294
|
+
}
|
|
8295
|
+
return false;
|
|
8296
|
+
}
|
|
8297
|
+
function validateMonitorBootstrapFlagValue(flag, value) {
|
|
8298
|
+
if (hasMonitorBootstrapForbiddenChar(value)) {
|
|
8299
|
+
throw new PlayBootstrapUsageError(
|
|
8300
|
+
`${flag} may not contain line breaks, control characters, quotes, or backticks. It is interpolated into the generated play source (including comments); use a plain monitor tool id / stream key / name.`
|
|
8301
|
+
);
|
|
8302
|
+
}
|
|
8303
|
+
return value;
|
|
8304
|
+
}
|
|
8305
|
+
function parseMonitorBootstrapOptions(args) {
|
|
8306
|
+
const [, ...rest] = args;
|
|
8307
|
+
const options = {
|
|
8308
|
+
name: MONITOR_BOOTSTRAP_TEMPLATE,
|
|
8309
|
+
tool: MONITOR_BOOTSTRAP_DEFAULT_TOOL,
|
|
8310
|
+
stream: MONITOR_BOOTSTRAP_DEFAULT_STREAM,
|
|
8311
|
+
out: null
|
|
8312
|
+
};
|
|
8313
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
8314
|
+
const arg = rest[index];
|
|
8315
|
+
const value = () => nextFlagValue(rest, index, arg);
|
|
8316
|
+
switch (arg) {
|
|
8317
|
+
case "--name":
|
|
8318
|
+
options.name = validateMonitorBootstrapFlagValue("--name", value());
|
|
8319
|
+
index += 1;
|
|
8320
|
+
break;
|
|
8321
|
+
case "--tool":
|
|
8322
|
+
options.tool = validateMonitorBootstrapFlagValue("--tool", value());
|
|
8323
|
+
index += 1;
|
|
8324
|
+
break;
|
|
8325
|
+
case "--stream":
|
|
8326
|
+
options.stream = validateMonitorBootstrapFlagValue("--stream", value());
|
|
8327
|
+
index += 1;
|
|
8328
|
+
break;
|
|
8329
|
+
case "--out":
|
|
8330
|
+
options.out = value();
|
|
8331
|
+
index += 1;
|
|
8332
|
+
break;
|
|
8333
|
+
default:
|
|
8334
|
+
throw new PlayBootstrapUsageError(
|
|
8335
|
+
`Unknown plays bootstrap option for ${MONITOR_BOOTSTRAP_TEMPLATE}: ${arg}
|
|
8336
|
+
Usage: deepline plays bootstrap ${MONITOR_BOOTSTRAP_TEMPLATE} [--tool <monitor-tool-id>] [--stream <stream-key>] [--name NAME] [--out monitor.play.ts]`
|
|
8337
|
+
);
|
|
8338
|
+
}
|
|
8339
|
+
}
|
|
8340
|
+
if (!options.tool) {
|
|
8341
|
+
throw new PlayBootstrapUsageError(
|
|
8342
|
+
`${MONITOR_BOOTSTRAP_TEMPLATE} needs a non-empty --tool.`
|
|
8343
|
+
);
|
|
8344
|
+
}
|
|
8345
|
+
if (!options.stream) {
|
|
8346
|
+
throw new PlayBootstrapUsageError(
|
|
8347
|
+
`${MONITOR_BOOTSTRAP_TEMPLATE} needs a non-empty --stream.`
|
|
8348
|
+
);
|
|
8349
|
+
}
|
|
8350
|
+
return options;
|
|
8351
|
+
}
|
|
8352
|
+
function generateMonitorTriggeredPlaySource(options) {
|
|
8353
|
+
return `import { definePlay } from 'deepline';
|
|
8354
|
+
import type { SqlListenerEvent } from 'deepline';
|
|
8355
|
+
|
|
8356
|
+
// Row shape delivered by ${options.tool} / ${options.stream}. This is a starting
|
|
8357
|
+
// point only: inspect the real columns with
|
|
8358
|
+
// deepline monitors available ${options.tool}
|
|
8359
|
+
// and tighten this type to the fields you read below.
|
|
8360
|
+
//
|
|
8361
|
+
// Before deploying a NEW monitor, run \`deepline monitors list\` \u2014 if one
|
|
8362
|
+
// already feeds this stream for your scope, this play will already react to its
|
|
8363
|
+
// rows (a play binds to the shared stream), so you may not need to deploy at all.
|
|
8364
|
+
type MonitorRow = Record<string, unknown>;
|
|
8365
|
+
|
|
8366
|
+
export default definePlay(
|
|
8367
|
+
${jsString(options.name)},
|
|
8368
|
+
async (ctx, event: SqlListenerEvent<MonitorRow>) => {
|
|
8369
|
+
// The monitor delivers the changed row as event.after. It is null for
|
|
8370
|
+
// DELETE operations, so guard before reading fields.
|
|
8371
|
+
const row = event.after;
|
|
8372
|
+
if (!row) {
|
|
8373
|
+
ctx.log(\`Monitor \${event.tool}/\${event.stream} \${event.operation} with no row; nothing to do.\`);
|
|
8374
|
+
return { handled: false, operation: event.operation };
|
|
8375
|
+
}
|
|
8376
|
+
|
|
8377
|
+
ctx.log(
|
|
8378
|
+
\`Monitor \${event.tool}/\${event.stream} \${event.operation}: \${JSON.stringify(row).slice(0, 200)}\`,
|
|
8379
|
+
);
|
|
8380
|
+
|
|
8381
|
+
// Capture the changed row into a durable dataset so the run has inspectable,
|
|
8382
|
+
// exportable output. ctx.dataset is a CALLABLE: ctx.dataset(key, rows) where
|
|
8383
|
+
// key is a compile-time string LITERAL and rows is an array of row objects.
|
|
8384
|
+
// It returns a builder; add per-row columns with .withColumn(name, resolver)
|
|
8385
|
+
// and finish with .run(). There is no .push/.add \u2014 pass all rows up front.
|
|
8386
|
+
// TODO: replace this plain persist with your real per-row work \u2014 enrich each
|
|
8387
|
+
// row via .withColumn('...', (row, rowCtx) => rowCtx.tools.execute(...)),
|
|
8388
|
+
// notify, write to another table, or fan out with rowCtx.runPlay.
|
|
8389
|
+
const captured = await ctx.dataset('monitor_events', [row]).run({
|
|
8390
|
+
description: \`Captured \${event.tool}/\${event.stream} \${event.operation} rows.\`,
|
|
8391
|
+
});
|
|
8392
|
+
|
|
8393
|
+
return {
|
|
8394
|
+
handled: true,
|
|
8395
|
+
tool: event.tool,
|
|
8396
|
+
stream: event.stream,
|
|
8397
|
+
operation: event.operation,
|
|
8398
|
+
changedAt: event.changedAt,
|
|
8399
|
+
capturedRows: await captured.count(),
|
|
8400
|
+
};
|
|
8401
|
+
},
|
|
8402
|
+
{
|
|
8403
|
+
description: ${jsString(`Run whenever ${options.tool} writes a new ${options.stream} row.`)},
|
|
8404
|
+
// A monitor trigger: this play wakes on row changes written by the bound
|
|
8405
|
+
// monitor tool + stream. Discover a tool's streams and columns with:
|
|
8406
|
+
// deepline monitors available ${options.tool}
|
|
8407
|
+
// To bind a different monitor, swap tool/stream (and re-check operations)
|
|
8408
|
+
// for one of its (tool, stream) pairs.
|
|
8409
|
+
sqlListeners: [
|
|
8410
|
+
{
|
|
8411
|
+
id: 'events',
|
|
8412
|
+
tool: ${jsString(options.tool)},
|
|
8413
|
+
stream: ${jsString(options.stream)},
|
|
8414
|
+
operations: ['INSERT'],
|
|
8415
|
+
// Optional: only wake on some rows \u2014 add a where filter to the binding above:
|
|
8416
|
+
// where: { after: { <column>: { eq: 'value' } } } // operators: eq, neq, in, notIn, isNull, isNotNull, ilike
|
|
8417
|
+
},
|
|
8418
|
+
],
|
|
8419
|
+
},
|
|
8420
|
+
);
|
|
8421
|
+
`;
|
|
8422
|
+
}
|
|
8281
8423
|
function playBootstrapUsageLine() {
|
|
8282
8424
|
return `Usage: deepline plays bootstrap <${formatPlayBootstrapTemplates()}> --from <csv:PATH|play:REF|provider:ID|providers:ID,ID> [--using <play:REF|providers:ID,ID>] [--people play:REF] [--email <play:REF|providers:ID,ID>] [--phone <play:REF|providers:ID,ID>] [--limit 5] [--out flow.play.ts]`;
|
|
8283
8425
|
}
|
|
8284
8426
|
function requireBootstrapTemplate(rawTemplate) {
|
|
8285
8427
|
if (!rawTemplate) {
|
|
8286
8428
|
throw new PlayBootstrapUsageError(
|
|
8287
|
-
`plays bootstrap needs a route template: ${formatPlayBootstrapTemplates()}.
|
|
8429
|
+
`plays bootstrap needs a route template: ${formatPlayBootstrapTemplates()}|${MONITOR_BOOTSTRAP_TEMPLATE}.
|
|
8288
8430
|
Example: deepline plays bootstrap people-email --from csv:data/leads.csv --using play:prebuilt/name-and-domain-to-email-waterfall --out email-flow.play.ts`
|
|
8289
8431
|
);
|
|
8290
8432
|
}
|
|
@@ -8292,7 +8434,7 @@ Example: deepline plays bootstrap people-email --from csv:data/leads.csv --using
|
|
|
8292
8434
|
const looksLikePlayReference = rawTemplate.includes("/") || rawTemplate.endsWith(".play.ts");
|
|
8293
8435
|
throw new PlayBootstrapUsageError(
|
|
8294
8436
|
`Unknown plays bootstrap template: ${rawTemplate}
|
|
8295
|
-
Supported templates: ${formatPlayBootstrapTemplates()}` + (looksLikePlayReference ? `
|
|
8437
|
+
Supported templates: ${formatPlayBootstrapTemplates()}|${MONITOR_BOOTSTRAP_TEMPLATE}` + (looksLikePlayReference ? `
|
|
8296
8438
|
|
|
8297
8439
|
"${rawTemplate}" looks like an existing play reference or file, not a bootstrap template. Do not run plays bootstrap on prebuilt/<play-name>. Use "deepline plays run ${rawTemplate} --input '{...}' --watch" to run it directly, "deepline plays describe ${rawTemplate} --json" to inspect its contract, or "deepline plays get ${rawTemplate} --source --out scratchpad.play.ts" to clone/edit it.` : "")
|
|
8298
8440
|
);
|
|
@@ -9501,7 +9643,25 @@ function renderPlayBootstrapError(error) {
|
|
|
9501
9643
|
console.error(errorMessage2(error));
|
|
9502
9644
|
return error instanceof PlayBootstrapError ? error.exitCode : 1;
|
|
9503
9645
|
}
|
|
9646
|
+
function writeBootstrapSource(source, out) {
|
|
9647
|
+
if (out) {
|
|
9648
|
+
(0, import_node_fs9.writeFileSync)((0, import_node_path10.resolve)(out), source, "utf-8");
|
|
9649
|
+
process.stdout.write(`Wrote ${(0, import_node_path10.resolve)(out)}
|
|
9650
|
+
`);
|
|
9651
|
+
return 0;
|
|
9652
|
+
}
|
|
9653
|
+
process.stdout.write(source);
|
|
9654
|
+
return 0;
|
|
9655
|
+
}
|
|
9656
|
+
function runMonitorBootstrap(args) {
|
|
9657
|
+
const options = parseMonitorBootstrapOptions(args);
|
|
9658
|
+
const source = generateMonitorTriggeredPlaySource(options);
|
|
9659
|
+
return writeBootstrapSource(source, options.out);
|
|
9660
|
+
}
|
|
9504
9661
|
async function runPlayBootstrap(args) {
|
|
9662
|
+
if (isMonitorBootstrapTemplate(args[0])) {
|
|
9663
|
+
return runMonitorBootstrap(args);
|
|
9664
|
+
}
|
|
9505
9665
|
const options = parsePlayBootstrapOptions(args);
|
|
9506
9666
|
const client2 = new DeeplineClient();
|
|
9507
9667
|
const contracts = await loadBootstrapContracts(client2, options);
|
|
@@ -9511,20 +9671,15 @@ async function runPlayBootstrap(args) {
|
|
|
9511
9671
|
...contracts,
|
|
9512
9672
|
...csvContext
|
|
9513
9673
|
});
|
|
9514
|
-
|
|
9515
|
-
(0, import_node_fs9.writeFileSync)((0, import_node_path10.resolve)(options.out), source, "utf-8");
|
|
9516
|
-
process.stdout.write(`Wrote ${(0, import_node_path10.resolve)(options.out)}
|
|
9517
|
-
`);
|
|
9518
|
-
return 0;
|
|
9519
|
-
}
|
|
9520
|
-
process.stdout.write(source);
|
|
9521
|
-
return 0;
|
|
9674
|
+
return writeBootstrapSource(source, options.out);
|
|
9522
9675
|
}
|
|
9523
9676
|
async function handlePlayBootstrap(args) {
|
|
9524
9677
|
return runPlayBootstrap(args).catch(renderPlayBootstrapError);
|
|
9525
9678
|
}
|
|
9526
9679
|
function registerPlayBootstrapCommand(play) {
|
|
9527
|
-
play.command("bootstrap <template>").description(
|
|
9680
|
+
play.command("bootstrap <template>").description(
|
|
9681
|
+
"Print a scratchpad play for a GTM route or monitor-triggered template."
|
|
9682
|
+
).addHelpText(
|
|
9528
9683
|
"after",
|
|
9529
9684
|
`
|
|
9530
9685
|
Notes:
|
|
@@ -9548,6 +9703,13 @@ Notes:
|
|
|
9548
9703
|
company-people company/account rows -> people play
|
|
9549
9704
|
company-people-email company/account rows -> people play -> email finder
|
|
9550
9705
|
company-people-phone company/account rows -> people play -> phone finder
|
|
9706
|
+
monitor-triggered run a play whenever a monitor writes a new row
|
|
9707
|
+
(definePlay with sqlListeners; no --from/stage flags)
|
|
9708
|
+
|
|
9709
|
+
Monitor-triggered options (only for the monitor-triggered template):
|
|
9710
|
+
--tool <monitor-tool-id> monitor tool to bind (default instantly.campaign_events)
|
|
9711
|
+
--stream <stream-key> output stream to listen on (default webhook_events)
|
|
9712
|
+
Discover a tool's streams/columns with: deepline monitors available <id>
|
|
9551
9713
|
|
|
9552
9714
|
Resource refs:
|
|
9553
9715
|
csv:./contacts.csv
|
|
@@ -9577,6 +9739,9 @@ Examples:
|
|
|
9577
9739
|
deepline plays bootstrap people-email --from provider:dropleads_search_people --using providers:hunter_email_finder,leadmagic_email_finder --limit 5 --out prospecting.play.ts
|
|
9578
9740
|
deepline plays bootstrap company-people-email --from provider:crustdata_companydb_search --people play:prebuilt/company-to-contact --email play:prebuilt/name-and-domain-to-email-waterfall --limit 5 --out account-contacts.play.ts
|
|
9579
9741
|
deepline plays bootstrap company-list --from provider:crustdata_companydb_search --limit 5 --out companies.play.ts
|
|
9742
|
+
|
|
9743
|
+
deepline plays bootstrap monitor-triggered --out on-new-row.play.ts
|
|
9744
|
+
deepline plays bootstrap monitor-triggered --tool tamradar.company_radar --stream company_job_openings --out on-new-job.play.ts
|
|
9580
9745
|
`
|
|
9581
9746
|
).option("--name <name>", "Generated play name").option(
|
|
9582
9747
|
"--from <ref>",
|
|
@@ -9593,7 +9758,13 @@ Examples:
|
|
|
9593
9758
|
).option(
|
|
9594
9759
|
"--phone <ref>",
|
|
9595
9760
|
"Phone finder stage: play:REF, provider:ID, or providers:ID,ID"
|
|
9596
|
-
).option("--limit <n>", "Maximum rows to fan out in the generated play").option(
|
|
9761
|
+
).option("--limit <n>", "Maximum rows to fan out in the generated play").option(
|
|
9762
|
+
"--tool <id>",
|
|
9763
|
+
"monitor-triggered only: monitor tool id to bind (e.g. instantly.campaign_events)"
|
|
9764
|
+
).option(
|
|
9765
|
+
"--stream <key>",
|
|
9766
|
+
"monitor-triggered only: monitor output stream to listen on (e.g. webhook_events)"
|
|
9767
|
+
).option("--out <path>", "Write generated play source to a file").action(async (template, options) => {
|
|
9597
9768
|
process.exitCode = await handlePlayBootstrap([
|
|
9598
9769
|
template,
|
|
9599
9770
|
...options.name ? ["--name", options.name] : [],
|
|
@@ -9603,6 +9774,8 @@ Examples:
|
|
|
9603
9774
|
...options.email ? ["--email", options.email] : [],
|
|
9604
9775
|
...options.phone ? ["--phone", options.phone] : [],
|
|
9605
9776
|
...options.limit ? ["--limit", options.limit] : [],
|
|
9777
|
+
...options.tool ? ["--tool", options.tool] : [],
|
|
9778
|
+
...options.stream ? ["--stream", options.stream] : [],
|
|
9606
9779
|
...options.out ? ["--out", options.out] : []
|
|
9607
9780
|
]);
|
|
9608
9781
|
});
|
|
@@ -13527,6 +13700,89 @@ function printToolGetterHints(hints) {
|
|
|
13527
13700
|
if (hint.unavailable) console.log(` - warning: ${hint.unavailable}`);
|
|
13528
13701
|
}
|
|
13529
13702
|
}
|
|
13703
|
+
function printPlayTriggers(triggers) {
|
|
13704
|
+
if (!triggers) return;
|
|
13705
|
+
const hasAny = (triggers.sqlListeners?.length ?? 0) > 0 || Boolean(triggers.cron) || triggers.webhook === true;
|
|
13706
|
+
if (!hasAny) return;
|
|
13707
|
+
console.log(" triggers:");
|
|
13708
|
+
for (const listener of triggers.sqlListeners ?? []) {
|
|
13709
|
+
const target = listener.tool && listener.stream ? `${listener.tool}/${listener.stream}` : listener.tool ?? listener.stream ?? listener.id;
|
|
13710
|
+
const operations = listener.operations.length ? listener.operations.join(", ") : "INSERT, UPDATE";
|
|
13711
|
+
const whereNote = listener.where ? " (with where filter)" : "";
|
|
13712
|
+
console.log(` sqlListeners \u2192 ${target} on ${operations}${whereNote}`);
|
|
13713
|
+
}
|
|
13714
|
+
if (triggers.cron) {
|
|
13715
|
+
const timezone = triggers.cron.timezone ? ` (${triggers.cron.timezone})` : "";
|
|
13716
|
+
console.log(` cron \u2192 ${triggers.cron.schedule}${timezone}`);
|
|
13717
|
+
}
|
|
13718
|
+
if (triggers.webhook === true) {
|
|
13719
|
+
console.log(" webhook \u2192 enabled");
|
|
13720
|
+
}
|
|
13721
|
+
}
|
|
13722
|
+
function printRecognizedSummary(recognized) {
|
|
13723
|
+
if (!recognized) return;
|
|
13724
|
+
if (recognized.tools?.length) {
|
|
13725
|
+
console.log(` tools: ${recognized.tools.join(", ")}`);
|
|
13726
|
+
}
|
|
13727
|
+
for (const dataset of recognized.datasets ?? []) {
|
|
13728
|
+
const columns = dataset.columns?.length ? ` (${dataset.columns.length} col${dataset.columns.length === 1 ? "" : "s"}: ${dataset.columns.join(", ")})` : "";
|
|
13729
|
+
console.log(` dataset ${dataset.name}${columns}`);
|
|
13730
|
+
}
|
|
13731
|
+
if (recognized.inputs?.length) {
|
|
13732
|
+
console.log(` inputs: ${recognized.inputs.join(", ")}`);
|
|
13733
|
+
}
|
|
13734
|
+
if (recognized.outputs?.length) {
|
|
13735
|
+
console.log(` outputs: ${recognized.outputs.join(", ")}`);
|
|
13736
|
+
}
|
|
13737
|
+
}
|
|
13738
|
+
function formatPlayCheckIssueLines(issue) {
|
|
13739
|
+
const lines = [` - ${issue.message}`];
|
|
13740
|
+
if (issue.path) {
|
|
13741
|
+
lines.push(` at ${issue.path}`);
|
|
13742
|
+
}
|
|
13743
|
+
if (issue.validOptions?.length) {
|
|
13744
|
+
lines.push(` \u2192 valid: [${issue.validOptions.join(", ")}]`);
|
|
13745
|
+
}
|
|
13746
|
+
if (issue.hint?.trim()) {
|
|
13747
|
+
lines.push(` hint: ${issue.hint.trim()}`);
|
|
13748
|
+
}
|
|
13749
|
+
if (issue.docsHint?.trim()) {
|
|
13750
|
+
lines.push(` next: ${issue.docsHint.trim()}`);
|
|
13751
|
+
}
|
|
13752
|
+
return lines;
|
|
13753
|
+
}
|
|
13754
|
+
function printPlayCheckIssues(issues, writer) {
|
|
13755
|
+
if (!issues?.length) return;
|
|
13756
|
+
const errorIssues = issues.filter((issue) => issue.severity === "error");
|
|
13757
|
+
const warningIssues = issues.filter((issue) => issue.severity === "warning");
|
|
13758
|
+
if (errorIssues.length) {
|
|
13759
|
+
writer(" issues:");
|
|
13760
|
+
for (const issue of errorIssues) {
|
|
13761
|
+
for (const line of formatPlayCheckIssueLines(issue)) writer(line);
|
|
13762
|
+
}
|
|
13763
|
+
}
|
|
13764
|
+
if (warningIssues.length) {
|
|
13765
|
+
writer(" warnings:");
|
|
13766
|
+
for (const issue of warningIssues) {
|
|
13767
|
+
for (const line of formatPlayCheckIssueLines(issue)) writer(line);
|
|
13768
|
+
}
|
|
13769
|
+
}
|
|
13770
|
+
}
|
|
13771
|
+
function partitionMirroredErrors(errors, issues) {
|
|
13772
|
+
const errorMessages = (issues ?? []).filter((issue) => issue.severity === "error").map((issue) => issue.message.trim()).filter((message) => message.length > 0);
|
|
13773
|
+
if (errorMessages.length === 0) {
|
|
13774
|
+
return { unstructuredErrors: errors ?? [] };
|
|
13775
|
+
}
|
|
13776
|
+
const isMirror = (error) => {
|
|
13777
|
+
const trimmed = error.trim();
|
|
13778
|
+
return errorMessages.some(
|
|
13779
|
+
(message) => trimmed === message || trimmed.startsWith(message)
|
|
13780
|
+
);
|
|
13781
|
+
};
|
|
13782
|
+
return {
|
|
13783
|
+
unstructuredErrors: (errors ?? []).filter((error) => !isMirror(error))
|
|
13784
|
+
};
|
|
13785
|
+
}
|
|
13530
13786
|
async function handlePlayCheck(args) {
|
|
13531
13787
|
const options = parsePlayCheckOptions(args);
|
|
13532
13788
|
if (!isFileTarget(options.target)) {
|
|
@@ -13659,16 +13915,27 @@ async function handlePlayCheck(args) {
|
|
|
13659
13915
|
`
|
|
13660
13916
|
);
|
|
13661
13917
|
} else if (enrichedResult.valid) {
|
|
13662
|
-
|
|
13918
|
+
const summary = enrichedResult.summary?.trim();
|
|
13919
|
+
console.log(
|
|
13920
|
+
summary ? `\u2713 ${playName} valid \u2014 ${summary}` : `\u2713 ${playName} passed cloud play check`
|
|
13921
|
+
);
|
|
13663
13922
|
if (enrichedResult.artifactHash) {
|
|
13664
13923
|
console.log(` artifact: ${enrichedResult.artifactHash.slice(0, 12)}`);
|
|
13665
13924
|
}
|
|
13925
|
+
printPlayTriggers(enrichedResult.triggers);
|
|
13926
|
+
printRecognizedSummary(enrichedResult.recognized);
|
|
13927
|
+
printPlayCheckIssues(enrichedResult.issues, (line) => console.log(line));
|
|
13666
13928
|
printToolGetterHints(enrichedResult.toolGetterHints);
|
|
13667
13929
|
} else {
|
|
13668
13930
|
console.error(`\u2717 ${playName} failed cloud play check`);
|
|
13669
|
-
|
|
13931
|
+
const { unstructuredErrors } = partitionMirroredErrors(
|
|
13932
|
+
enrichedResult.errors,
|
|
13933
|
+
enrichedResult.issues
|
|
13934
|
+
);
|
|
13935
|
+
for (const error of unstructuredErrors) {
|
|
13670
13936
|
console.error(` ${error}`);
|
|
13671
13937
|
}
|
|
13938
|
+
printPlayCheckIssues(enrichedResult.issues, (line) => console.error(line));
|
|
13672
13939
|
printToolGetterHints(enrichedResult.toolGetterHints);
|
|
13673
13940
|
}
|
|
13674
13941
|
return enrichedResult.valid ? 0 : 1;
|
|
@@ -16188,7 +16455,7 @@ function canInlineRunJavascript(command) {
|
|
|
16188
16455
|
return true;
|
|
16189
16456
|
}
|
|
16190
16457
|
function renderExtractFunction(command, indentSpaces) {
|
|
16191
|
-
return command.extract_js ? `({ row, result, data, raw, pick, extract, extractList, target, get }) => { const input = row; const context = row;
|
|
16458
|
+
return command.extract_js ? `({ row, result, data, raw, pick, extract, extractList, target, get }) => { const input = row; const context = row; const output_data = __dlLegacyOutputData(result, raw);
|
|
16192
16459
|
${indent(renderJavascriptBody(command.extract_js), indentSpaces)}
|
|
16193
16460
|
}` : "null";
|
|
16194
16461
|
}
|
|
@@ -16816,8 +17083,13 @@ function helperSource() {
|
|
|
16816
17083
|
` __dlPushCandidate(candidates, record.data);`,
|
|
16817
17084
|
` __dlPushCandidate(candidates, record.result);`,
|
|
16818
17085
|
` __dlPushCandidate(candidates, record.output);`,
|
|
17086
|
+
` __dlPushCandidate(candidates, __dlGetByPath(record, 'data.data'));`,
|
|
16819
17087
|
` __dlPushCandidate(candidates, __dlGetByPath(record, 'result.data'));`,
|
|
17088
|
+
` __dlPushCandidate(candidates, __dlGetByPath(record, 'result.data.data'));`,
|
|
17089
|
+
` __dlPushCandidate(candidates, __dlGetByPath(record, 'output.data'));`,
|
|
17090
|
+
` __dlPushCandidate(candidates, __dlGetByPath(record, 'output.data.data'));`,
|
|
16820
17091
|
` __dlPushCandidate(candidates, __dlGetByPath(record, 'output.body'));`,
|
|
17092
|
+
` __dlPushCandidate(candidates, __dlGetByPath(record, 'output.body.data'));`,
|
|
16821
17093
|
` __dlPushCandidate(candidates, __dlGetByPath(record, 'toolResponse.raw'));`,
|
|
16822
17094
|
` __dlPushCandidate(candidates, __dlGetByPath(record, 'toolOutput.raw'));`,
|
|
16823
17095
|
` return candidates;`,
|
|
@@ -17214,13 +17486,37 @@ function helperSource() {
|
|
|
17214
17486
|
` return { ...defaults, ...(existing as Record<string, unknown>) };`,
|
|
17215
17487
|
`}`,
|
|
17216
17488
|
``,
|
|
17489
|
+
`function __dlCompactJavascriptContext(value: unknown, depth = 0): unknown {`,
|
|
17490
|
+
` if (depth > 8) return '[Object]';`,
|
|
17491
|
+
` if (typeof value === 'string') return value.length > 20000 ? value.slice(0, 20000) + '...[truncated]' : value;`,
|
|
17492
|
+
` if (!value || typeof value !== 'object') return value;`,
|
|
17493
|
+
` if (Array.isArray(value)) {`,
|
|
17494
|
+
` const limit = depth <= 2 ? 25 : 10;`,
|
|
17495
|
+
` const items = value.slice(0, limit).map((entry) => __dlCompactJavascriptContext(entry, depth + 1));`,
|
|
17496
|
+
` if (value.length > limit) items.push({ __deepline_truncated_items: value.length - limit });`,
|
|
17497
|
+
` return items;`,
|
|
17498
|
+
` }`,
|
|
17499
|
+
` const out: Record<string, unknown> = {};`,
|
|
17500
|
+
` let count = 0;`,
|
|
17501
|
+
` for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {`,
|
|
17502
|
+
` count += 1;`,
|
|
17503
|
+
` if (count > 80) {`,
|
|
17504
|
+
` out.__deepline_truncated_fields = count - 80;`,
|
|
17505
|
+
` break;`,
|
|
17506
|
+
` }`,
|
|
17507
|
+
` out[key] = __dlCompactJavascriptContext(entry, depth + 1);`,
|
|
17508
|
+
` }`,
|
|
17509
|
+
` return out;`,
|
|
17510
|
+
`}`,
|
|
17511
|
+
``,
|
|
17217
17512
|
`function __dlRuntimePayload(tool: string, payload: Record<string, unknown>, row: Record<string, unknown>): Record<string, unknown> {`,
|
|
17218
17513
|
` if (tool !== 'run_javascript') return payload;`,
|
|
17514
|
+
` const compactRow = __dlCompactJavascriptContext(row) as Record<string, unknown>;`,
|
|
17219
17515
|
` return {`,
|
|
17220
17516
|
` ...payload,`,
|
|
17221
|
-
` row: __dlMergeContextRecord(payload.row,
|
|
17222
|
-
` input: __dlMergeContextRecord(payload.input,
|
|
17223
|
-
` context: __dlMergeContextRecord(payload.context,
|
|
17517
|
+
` row: __dlMergeContextRecord(payload.row, compactRow),`,
|
|
17518
|
+
` input: __dlMergeContextRecord(payload.input, compactRow),`,
|
|
17519
|
+
` context: __dlMergeContextRecord(payload.context, compactRow),`,
|
|
17224
17520
|
` };`,
|
|
17225
17521
|
`}`,
|
|
17226
17522
|
``,
|
|
@@ -18223,6 +18519,125 @@ function enrichOutputJson(exportResult) {
|
|
|
18223
18519
|
...exportResult.partial ? { rows: exportResult.rows, partial: true } : {}
|
|
18224
18520
|
};
|
|
18225
18521
|
}
|
|
18522
|
+
function readFirstEnrichDatasetActions(value) {
|
|
18523
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18524
|
+
const walk = (candidate, options) => {
|
|
18525
|
+
if (!candidate || typeof candidate !== "object" || seen.has(candidate)) {
|
|
18526
|
+
return null;
|
|
18527
|
+
}
|
|
18528
|
+
seen.add(candidate);
|
|
18529
|
+
if (Array.isArray(candidate)) {
|
|
18530
|
+
for (const entry of candidate) {
|
|
18531
|
+
const found = walk(entry, options);
|
|
18532
|
+
if (found) return found;
|
|
18533
|
+
}
|
|
18534
|
+
return null;
|
|
18535
|
+
}
|
|
18536
|
+
const record = candidate;
|
|
18537
|
+
const actions = isRecord7(record.actions) ? record.actions : null;
|
|
18538
|
+
const query = isRecord7(actions?.query) ? actions.query : null;
|
|
18539
|
+
if (query?.kind === "deepline_db_query") {
|
|
18540
|
+
return {
|
|
18541
|
+
dataset: record,
|
|
18542
|
+
query,
|
|
18543
|
+
...isRecord7(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
|
|
18544
|
+
};
|
|
18545
|
+
}
|
|
18546
|
+
if (options.allowLegacy && record.kind === "dataset" && typeof record.queryDatasetCommand === "string" && record.queryDatasetCommand.trim()) {
|
|
18547
|
+
return {
|
|
18548
|
+
dataset: record,
|
|
18549
|
+
queryDatasetCommand: record.queryDatasetCommand.trim(),
|
|
18550
|
+
...typeof record.slowExportAsCsvCommand === "string" && record.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record.slowExportAsCsvCommand.trim() } : {}
|
|
18551
|
+
};
|
|
18552
|
+
}
|
|
18553
|
+
for (const [key, entry] of Object.entries(record)) {
|
|
18554
|
+
if (key === "preview") {
|
|
18555
|
+
continue;
|
|
18556
|
+
}
|
|
18557
|
+
const found = walk(entry, options);
|
|
18558
|
+
if (found) return found;
|
|
18559
|
+
}
|
|
18560
|
+
return null;
|
|
18561
|
+
};
|
|
18562
|
+
const modern = walk(value, { allowLegacy: false });
|
|
18563
|
+
if (modern) {
|
|
18564
|
+
return modern;
|
|
18565
|
+
}
|
|
18566
|
+
seen.clear();
|
|
18567
|
+
return walk(value, { allowLegacy: true });
|
|
18568
|
+
}
|
|
18569
|
+
function actionStringField(record, key) {
|
|
18570
|
+
const value = record[key];
|
|
18571
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
18572
|
+
}
|
|
18573
|
+
function parseSqlFromDbQueryCommand(command) {
|
|
18574
|
+
if (!command) {
|
|
18575
|
+
return null;
|
|
18576
|
+
}
|
|
18577
|
+
const match = command.match(/\s--sql\s+('(?:'\\''|[^'])*'|"(?:"\\"|[^"])*")/);
|
|
18578
|
+
if (!match?.[1]) {
|
|
18579
|
+
return null;
|
|
18580
|
+
}
|
|
18581
|
+
const raw = match[1];
|
|
18582
|
+
if (raw.startsWith("'") && raw.endsWith("'")) {
|
|
18583
|
+
return raw.slice(1, -1).replace(/'\\''/g, "'");
|
|
18584
|
+
}
|
|
18585
|
+
return decodeStringLiteral(raw);
|
|
18586
|
+
}
|
|
18587
|
+
function enrichCustomerDbJson(input2) {
|
|
18588
|
+
const actions = readFirstEnrichDatasetActions(input2.status);
|
|
18589
|
+
if (!actions) {
|
|
18590
|
+
return null;
|
|
18591
|
+
}
|
|
18592
|
+
const query = actions.query ?? {};
|
|
18593
|
+
const dataset = actions.dataset;
|
|
18594
|
+
const sql = actionStringField(query, "sql") ?? parseSqlFromDbQueryCommand(actions.queryDatasetCommand);
|
|
18595
|
+
const datasetPath = actionStringField(query, "datasetPath") ?? actionStringField(dataset, "path") ?? actionStringField(dataset, "tableNamespace");
|
|
18596
|
+
const api = isRecord7(query.api) ? query.api : null;
|
|
18597
|
+
const apiPath = actionStringField(api ?? {}, "path") ?? "/api/v2/db/query";
|
|
18598
|
+
const apiMethod = actionStringField(api ?? {}, "method") ?? "POST";
|
|
18599
|
+
if (!datasetPath) {
|
|
18600
|
+
return null;
|
|
18601
|
+
}
|
|
18602
|
+
const maxRows = typeof query.maxRows === "number" && Number.isFinite(query.maxRows) ? Math.trunc(query.maxRows) : void 0;
|
|
18603
|
+
const runId = extractRunId(input2.status) ?? actionStringField(actions.exportCsv ?? {}, "runId");
|
|
18604
|
+
const exportDatasetPath = actionStringField(actions.exportCsv ?? {}, "datasetPath") ?? datasetPath;
|
|
18605
|
+
const tableNamespace = actionStringField(query, "tableNamespace") ?? actionStringField(dataset, "tableNamespace");
|
|
18606
|
+
const sqlTableName = actionStringField(query, "sqlTableName");
|
|
18607
|
+
const sqlQualifiedTableName = actionStringField(
|
|
18608
|
+
query,
|
|
18609
|
+
"sqlQualifiedTableName"
|
|
18610
|
+
);
|
|
18611
|
+
const command = actions.queryDatasetCommand ?? (sql ? `deepline db query --sql ${shellSingleQuote2(sql)}${maxRows !== void 0 ? ` --max-rows ${maxRows}` : ""} --json` : null);
|
|
18612
|
+
return {
|
|
18613
|
+
runId,
|
|
18614
|
+
datasetPath,
|
|
18615
|
+
...tableNamespace ? { tableNamespace } : {},
|
|
18616
|
+
...sqlTableName ? { sqlTableName } : {},
|
|
18617
|
+
...sqlQualifiedTableName ? { sqlQualifiedTableName } : {},
|
|
18618
|
+
...sql ? { sql } : {},
|
|
18619
|
+
...actions.query ? {
|
|
18620
|
+
api: {
|
|
18621
|
+
method: apiMethod,
|
|
18622
|
+
path: apiPath,
|
|
18623
|
+
url: `${input2.client.baseUrl.replace(/\/$/, "")}${apiPath}`
|
|
18624
|
+
}
|
|
18625
|
+
} : {},
|
|
18626
|
+
...maxRows !== void 0 ? { maxRows } : {},
|
|
18627
|
+
...command ? { command } : {},
|
|
18628
|
+
...actions.exportCsv || actions.slowExportAsCsvCommand ? {
|
|
18629
|
+
export: {
|
|
18630
|
+
datasetPath: exportDatasetPath,
|
|
18631
|
+
...actions.slowExportAsCsvCommand ? { command: actions.slowExportAsCsvCommand } : runId && input2.outputPath ? {
|
|
18632
|
+
command: `deepline runs export ${runId} --dataset ${shellSingleQuote2(
|
|
18633
|
+
exportDatasetPath
|
|
18634
|
+
)} --out ${shellSingleQuote2((0, import_node_path12.resolve)(input2.outputPath))}`
|
|
18635
|
+
} : {},
|
|
18636
|
+
action: actions.exportCsv ?? {}
|
|
18637
|
+
}
|
|
18638
|
+
} : {}
|
|
18639
|
+
};
|
|
18640
|
+
}
|
|
18226
18641
|
function enrichReportJson(report) {
|
|
18227
18642
|
if (!report) {
|
|
18228
18643
|
return {};
|
|
@@ -18243,6 +18658,78 @@ function enrichReportJson(report) {
|
|
|
18243
18658
|
} : {}
|
|
18244
18659
|
};
|
|
18245
18660
|
}
|
|
18661
|
+
function sqlStringLiteral(value) {
|
|
18662
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
18663
|
+
}
|
|
18664
|
+
function failureAliasFromCellMeta(cellMeta) {
|
|
18665
|
+
if (!isRecord7(cellMeta)) {
|
|
18666
|
+
return null;
|
|
18667
|
+
}
|
|
18668
|
+
for (const [alias, meta] of Object.entries(cellMeta)) {
|
|
18669
|
+
if (!isRecord7(meta)) {
|
|
18670
|
+
continue;
|
|
18671
|
+
}
|
|
18672
|
+
const failure = failureCellFromMeta(meta, {});
|
|
18673
|
+
if (!failure) {
|
|
18674
|
+
continue;
|
|
18675
|
+
}
|
|
18676
|
+
return {
|
|
18677
|
+
alias,
|
|
18678
|
+
...typeof failure.error === "string" ? { error: failure.error } : {},
|
|
18679
|
+
...typeof failure.operation === "string" ? { operation: failure.operation } : {},
|
|
18680
|
+
...typeof failure.provider === "string" ? { provider: failure.provider } : {}
|
|
18681
|
+
};
|
|
18682
|
+
}
|
|
18683
|
+
return null;
|
|
18684
|
+
}
|
|
18685
|
+
async function collectCustomerDbFailureJobs(input2) {
|
|
18686
|
+
const customerDb = enrichCustomerDbJson({
|
|
18687
|
+
status: input2.status,
|
|
18688
|
+
client: input2.client
|
|
18689
|
+
});
|
|
18690
|
+
if (!customerDb?.runId || !customerDb.sqlQualifiedTableName) {
|
|
18691
|
+
return [];
|
|
18692
|
+
}
|
|
18693
|
+
const fallbackAliases = collectHardFailureAliasSpecs(input2.config);
|
|
18694
|
+
const fallbackAlias = fallbackAliases[0]?.alias ?? "enrich";
|
|
18695
|
+
const aliasIndexByName = new Map(
|
|
18696
|
+
fallbackAliases.map((spec, index) => [normalizeAlias2(spec.alias), index])
|
|
18697
|
+
);
|
|
18698
|
+
const sql = `select _input_index, _status, _error, _cell_meta from ${customerDb.sqlQualifiedTableName} where _run_id = ${sqlStringLiteral(customerDb.runId)} and (_error is not null or lower(coalesce(_status, '')) in ('failed', 'error')) order by _input_index limit 1000`;
|
|
18699
|
+
const result = await input2.client.queryCustomerDb({
|
|
18700
|
+
sql,
|
|
18701
|
+
maxRows: 1e3
|
|
18702
|
+
});
|
|
18703
|
+
const rows = Array.isArray(result.rows) ? result.rows : [];
|
|
18704
|
+
const failedRows = rows.filter((row) => {
|
|
18705
|
+
const status = typeof row._status === "string" ? row._status.trim().toLowerCase() : "";
|
|
18706
|
+
return typeof row._error === "string" && row._error.trim() || status === "failed" || status === "error";
|
|
18707
|
+
});
|
|
18708
|
+
return failedRows.map((row, index) => {
|
|
18709
|
+
const metaFailure = failureAliasFromCellMeta(row._cell_meta);
|
|
18710
|
+
const alias = metaFailure?.alias ?? fallbackAlias;
|
|
18711
|
+
const normalizedAlias = normalizeAlias2(alias);
|
|
18712
|
+
const rowId = typeof row._input_index === "number" ? row._input_index : typeof row._input_index === "string" && row._input_index.trim() ? Number.parseInt(row._input_index, 10) : index;
|
|
18713
|
+
const rawError = metaFailure?.error ?? (typeof row._error === "string" && row._error.trim() ? row._error.trim() : `Column status: ${String(row._status ?? "failed")}`);
|
|
18714
|
+
const message = enrichFailureMessageWithOperation(
|
|
18715
|
+
rawError,
|
|
18716
|
+
metaFailure?.operation ?? fallbackAliases.find(
|
|
18717
|
+
(spec) => normalizeAlias2(spec.alias) === normalizedAlias
|
|
18718
|
+
)?.operation
|
|
18719
|
+
);
|
|
18720
|
+
return {
|
|
18721
|
+
job_id: `row-${Number.isFinite(rowId) ? rowId : index}-${normalizedAlias || "enrich"}`,
|
|
18722
|
+
row_id: Number.isFinite(rowId) ? rowId : index,
|
|
18723
|
+
col_index: aliasIndexByName.get(normalizedAlias) ?? 0,
|
|
18724
|
+
column: alias,
|
|
18725
|
+
status: "failed",
|
|
18726
|
+
last_error: message,
|
|
18727
|
+
error: message,
|
|
18728
|
+
...metaFailure?.operation ? { operation: metaFailure.operation } : {},
|
|
18729
|
+
...metaFailure?.provider ? { provider: metaFailure.provider } : {}
|
|
18730
|
+
};
|
|
18731
|
+
});
|
|
18732
|
+
}
|
|
18246
18733
|
async function buildEnrichFailureReport(input2) {
|
|
18247
18734
|
const fallbackRowsInfo = input2.exportResult ? null : extractCanonicalRowsInfo(input2.status);
|
|
18248
18735
|
return maybeEmitEnrichFailureReport({
|
|
@@ -18344,9 +18831,7 @@ async function writeSlimBatchedRuntimeCsv(input2) {
|
|
|
18344
18831
|
};
|
|
18345
18832
|
cleanRows[rowIndex] = {
|
|
18346
18833
|
...baseRow,
|
|
18347
|
-
...Object.fromEntries(
|
|
18348
|
-
Object.entries(mergeRow).map(compactOverlayCell)
|
|
18349
|
-
)
|
|
18834
|
+
...Object.fromEntries(Object.entries(mergeRow).map(compactOverlayCell))
|
|
18350
18835
|
};
|
|
18351
18836
|
}
|
|
18352
18837
|
const columns = dataExportColumns(
|
|
@@ -18770,6 +19255,11 @@ function collectWaterfallAliasSpecs(config) {
|
|
|
18770
19255
|
aliases.push({
|
|
18771
19256
|
alias,
|
|
18772
19257
|
childAliases: activeChildren.map((child) => child.alias).filter(Boolean),
|
|
19258
|
+
childRunIfJsByAlias: new Map(
|
|
19259
|
+
activeChildren.map(
|
|
19260
|
+
(child) => [child.alias, child.run_if_js]
|
|
19261
|
+
)
|
|
19262
|
+
),
|
|
18773
19263
|
childToolsByAlias: new Map(
|
|
18774
19264
|
activeChildren.map(
|
|
18775
19265
|
(child) => [child.alias, child.tool.trim()]
|
|
@@ -19004,7 +19494,8 @@ function collectEmptyWaterfallIssues(input2) {
|
|
|
19004
19494
|
});
|
|
19005
19495
|
const issues = [];
|
|
19006
19496
|
aliases.forEach((spec) => {
|
|
19007
|
-
|
|
19497
|
+
const executionSignal = waterfallExecutionSignal(input2.status, spec);
|
|
19498
|
+
if (executionSignal === "all_condition_skipped" || executionSignal === "unknown" && waterfallChildrenAreStaticallySkipped(spec)) {
|
|
19008
19499
|
return;
|
|
19009
19500
|
}
|
|
19010
19501
|
const logicalRows = /* @__PURE__ */ new Map();
|
|
@@ -19046,6 +19537,22 @@ function collectEmptyWaterfallIssues(input2) {
|
|
|
19046
19537
|
});
|
|
19047
19538
|
return issues;
|
|
19048
19539
|
}
|
|
19540
|
+
function waterfallChildrenAreStaticallySkipped(spec) {
|
|
19541
|
+
const childAliases = spec.childAliases ?? [];
|
|
19542
|
+
if (childAliases.length === 0 || !spec.childRunIfJsByAlias) {
|
|
19543
|
+
return false;
|
|
19544
|
+
}
|
|
19545
|
+
return childAliases.every(
|
|
19546
|
+
(alias) => runIfJsAlwaysReturnsFalse(spec.childRunIfJsByAlias?.get(alias))
|
|
19547
|
+
);
|
|
19548
|
+
}
|
|
19549
|
+
function runIfJsAlwaysReturnsFalse(source) {
|
|
19550
|
+
if (typeof source !== "string") {
|
|
19551
|
+
return false;
|
|
19552
|
+
}
|
|
19553
|
+
const normalized = source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|\s)\/\/.*$/gm, "").trim();
|
|
19554
|
+
return /^(?:return\s+)?\(?\s*false\s*\)?\s*;?$/.test(normalized);
|
|
19555
|
+
}
|
|
19049
19556
|
function waterfallExecutionSignal(status, spec) {
|
|
19050
19557
|
const childAliases = spec.childAliases ?? [];
|
|
19051
19558
|
if (childAliases.length === 0) {
|
|
@@ -19322,10 +19829,11 @@ function rewriteEnrichJsonStatus(input2) {
|
|
|
19322
19829
|
if (failedRows === 0 || !isRecord7(rewritten)) {
|
|
19323
19830
|
return rewritten;
|
|
19324
19831
|
}
|
|
19832
|
+
const partialStatus = selectedRows > 0 && failedRows < selectedRows ? "partial_success" : "failed";
|
|
19325
19833
|
return {
|
|
19326
19834
|
...rewritten,
|
|
19327
|
-
...rewritten.status === "completed" ? { status:
|
|
19328
|
-
...isRecord7(rewritten.run) && rewritten.run.status === "completed" ? { run: { ...rewritten.run, status:
|
|
19835
|
+
...rewritten.status === "completed" || rewritten.status === "failed" ? { status: partialStatus } : {},
|
|
19836
|
+
...isRecord7(rewritten.run) && (rewritten.run.status === "completed" || rewritten.run.status === "failed") ? { run: { ...rewritten.run, status: partialStatus } } : {}
|
|
19329
19837
|
};
|
|
19330
19838
|
}
|
|
19331
19839
|
function summarizeFailedJobError(value) {
|
|
@@ -19361,6 +19869,12 @@ function collectEnrichFollowUpCommands(input2) {
|
|
|
19361
19869
|
command: `deepline runs get ${input2.runId} --full --json`
|
|
19362
19870
|
});
|
|
19363
19871
|
}
|
|
19872
|
+
if (input2.runId && input2.outputPath) {
|
|
19873
|
+
addEnrichRowsExportFollowUpCommand(commands, seen, {
|
|
19874
|
+
runId: input2.runId,
|
|
19875
|
+
outputPath: input2.outputPath
|
|
19876
|
+
});
|
|
19877
|
+
}
|
|
19364
19878
|
collectDatasetFollowUpCommands(input2.status, {
|
|
19365
19879
|
runId: input2.runId,
|
|
19366
19880
|
outputPath: input2.outputPath,
|
|
@@ -19369,17 +19883,17 @@ function collectEnrichFollowUpCommands(input2) {
|
|
|
19369
19883
|
path: "result",
|
|
19370
19884
|
depth: 0
|
|
19371
19885
|
});
|
|
19372
|
-
if (input2.runId && input2.outputPath && !commands.some((command) => command.label === "export enrich rows")) {
|
|
19373
|
-
addEnrichFollowUpCommand(commands, seen, {
|
|
19374
|
-
label: "export enrich rows",
|
|
19375
|
-
path: GENERATED_ENRICH_ROWS_TABLE_NAMESPACE,
|
|
19376
|
-
command: `deepline runs export ${input2.runId} --dataset ${GENERATED_ENRICH_ROWS_TABLE_NAMESPACE} --out ${shellSingleQuote2(
|
|
19377
|
-
(0, import_node_path12.resolve)(input2.outputPath)
|
|
19378
|
-
)}`
|
|
19379
|
-
});
|
|
19380
|
-
}
|
|
19381
19886
|
return commands.slice(0, 8);
|
|
19382
19887
|
}
|
|
19888
|
+
function addEnrichRowsExportFollowUpCommand(commands, seen, input2) {
|
|
19889
|
+
addEnrichFollowUpCommand(commands, seen, {
|
|
19890
|
+
label: "export enrich rows",
|
|
19891
|
+
path: GENERATED_ENRICH_ROWS_TABLE_NAMESPACE,
|
|
19892
|
+
command: `deepline runs export ${input2.runId} --dataset ${GENERATED_ENRICH_ROWS_TABLE_NAMESPACE} --out ${shellSingleQuote2(
|
|
19893
|
+
(0, import_node_path12.resolve)(input2.outputPath)
|
|
19894
|
+
)}`
|
|
19895
|
+
});
|
|
19896
|
+
}
|
|
19383
19897
|
function sidecarEnrichRowsExportPath(outputPath) {
|
|
19384
19898
|
const resolved = (0, import_node_path12.resolve)(outputPath);
|
|
19385
19899
|
const ext = (0, import_node_path12.extname)(resolved) || ".csv";
|
|
@@ -19520,7 +20034,15 @@ async function maybeEmitEnrichFailureReport(input2) {
|
|
|
19520
20034
|
status: input2.status,
|
|
19521
20035
|
rowRange: input2.statusRowRange ?? input2.rowRange
|
|
19522
20036
|
});
|
|
19523
|
-
const
|
|
20037
|
+
const customerDbJobs = input2.status === void 0 || rowJobs.length > 0 || statusJobs.length > 0 ? [] : await collectCustomerDbFailureJobs({
|
|
20038
|
+
client: input2.client,
|
|
20039
|
+
status: input2.status,
|
|
20040
|
+
config: input2.config
|
|
20041
|
+
});
|
|
20042
|
+
const jobs = rowJobs.length > 0 || statusJobs.length > 0 || customerDbJobs.length > 0 || input2.status === void 0 ? mergeEnrichFailureJobs(
|
|
20043
|
+
mergeEnrichFailureJobs(rowJobs, statusJobs),
|
|
20044
|
+
customerDbJobs
|
|
20045
|
+
) : [];
|
|
19524
20046
|
if (jobs.length === 0 && enrichIssues.length === 0) {
|
|
19525
20047
|
return null;
|
|
19526
20048
|
}
|
|
@@ -19626,6 +20148,8 @@ async function fetchBackingRowsForCsvExport(input2) {
|
|
|
19626
20148
|
const hasExplicitExpectedRows = typeof input2.expectedRows === "number" && input2.expectedRows > 0;
|
|
19627
20149
|
const minimumExpectedRows = hasExplicitExpectedRows ? Math.trunc(Number(input2.expectedRows)) : input2.rowsInfo.totalRows;
|
|
19628
20150
|
let lastExpectedTotal = minimumExpectedRows;
|
|
20151
|
+
const expectedSourceRowStart = input2.sourceRowStart ?? 0;
|
|
20152
|
+
const expectedSourceRowEnd = expectedSourceRowStart + Math.max(0, minimumExpectedRows) - 1;
|
|
19629
20153
|
for (; ; ) {
|
|
19630
20154
|
const sheetRows = [];
|
|
19631
20155
|
let offset = 0;
|
|
@@ -19641,19 +20165,39 @@ async function fetchBackingRowsForCsvExport(input2) {
|
|
|
19641
20165
|
});
|
|
19642
20166
|
sheetRows.push(...page.rows);
|
|
19643
20167
|
const summaryTotal = page.summary?.stats?.total;
|
|
19644
|
-
if (typeof summaryTotal === "number" && Number.isFinite(summaryTotal)) {
|
|
20168
|
+
if (!hasExplicitExpectedRows && typeof summaryTotal === "number" && Number.isFinite(summaryTotal)) {
|
|
19645
20169
|
expectedTotal = Math.max(expectedTotal, Math.trunc(summaryTotal));
|
|
19646
20170
|
}
|
|
19647
|
-
|
|
20171
|
+
let hasRequiredRows = sheetRows.length >= expectedTotal;
|
|
20172
|
+
if (hasExplicitExpectedRows) {
|
|
20173
|
+
const exportableRows = coalesceExportableSheetRows(
|
|
20174
|
+
sheetRows.map((row) => exportableSheetRow2(row, input2.sourceRowStart ?? 0)).filter((row) => Boolean(row)),
|
|
20175
|
+
input2.sourceRowStart ?? 0
|
|
20176
|
+
).filter(
|
|
20177
|
+
(row) => sourceRowIndexFromEnrichRow(
|
|
20178
|
+
row,
|
|
20179
|
+
expectedSourceRowStart,
|
|
20180
|
+
expectedSourceRowEnd
|
|
20181
|
+
) !== null
|
|
20182
|
+
);
|
|
20183
|
+
hasRequiredRows = exportableRows.length >= minimumExpectedRows;
|
|
20184
|
+
}
|
|
20185
|
+
if (page.rows.length < ENRICH_EXPORT_PAGE_SIZE || hasRequiredRows) {
|
|
19648
20186
|
break;
|
|
19649
20187
|
}
|
|
19650
20188
|
offset += page.rows.length;
|
|
19651
20189
|
}
|
|
19652
20190
|
const rawRows = sheetRows.map((row) => exportableSheetRow2(row, input2.sourceRowStart ?? 0)).filter((row) => Boolean(row));
|
|
19653
|
-
|
|
19654
|
-
|
|
19655
|
-
|
|
19656
|
-
|
|
20191
|
+
let rows = coalesceExportableSheetRows(rawRows, input2.sourceRowStart ?? 0);
|
|
20192
|
+
if (hasExplicitExpectedRows) {
|
|
20193
|
+
rows = rows.filter(
|
|
20194
|
+
(row) => sourceRowIndexFromEnrichRow(
|
|
20195
|
+
row,
|
|
20196
|
+
expectedSourceRowStart,
|
|
20197
|
+
expectedSourceRowEnd
|
|
20198
|
+
) !== null
|
|
20199
|
+
);
|
|
20200
|
+
}
|
|
19657
20201
|
lastRows = rows;
|
|
19658
20202
|
lastExpectedTotal = expectedTotal;
|
|
19659
20203
|
const requiredExportRows = hasExplicitExpectedRows ? minimumExpectedRows : expectedTotal;
|
|
@@ -20307,6 +20851,7 @@ function registerEnrichCommand(program) {
|
|
|
20307
20851
|
}
|
|
20308
20852
|
if (input2.json) {
|
|
20309
20853
|
runArgs.push("--json");
|
|
20854
|
+
runArgs.push("--full");
|
|
20310
20855
|
} else {
|
|
20311
20856
|
runArgs.push("--logs");
|
|
20312
20857
|
}
|
|
@@ -20429,6 +20974,11 @@ function registerEnrichCommand(program) {
|
|
|
20429
20974
|
partial: true
|
|
20430
20975
|
} : {}
|
|
20431
20976
|
} : null,
|
|
20977
|
+
customer_db: enrichCustomerDbJson({
|
|
20978
|
+
status: chunk.status,
|
|
20979
|
+
client: client2,
|
|
20980
|
+
outputPath: enrichIssueFollowUpOutputPath ?? committedExportResult2?.path ?? outputPath
|
|
20981
|
+
}),
|
|
20432
20982
|
...enrichReportJson(failureReport3)
|
|
20433
20983
|
});
|
|
20434
20984
|
} else {
|
|
@@ -20503,6 +21053,11 @@ function registerEnrichCommand(program) {
|
|
|
20503
21053
|
enrichedRows: totalEnrichedRows,
|
|
20504
21054
|
path: finalExportResult.path
|
|
20505
21055
|
} : null,
|
|
21056
|
+
customer_db: enrichCustomerDbJson({
|
|
21057
|
+
status: lastStatus,
|
|
21058
|
+
client: client2,
|
|
21059
|
+
outputPath: enrichIssueFollowUpOutputPath ?? finalExportResult?.path ?? outputPath
|
|
21060
|
+
}),
|
|
20506
21061
|
...enrichReportJson(failureReport2)
|
|
20507
21062
|
});
|
|
20508
21063
|
}
|
|
@@ -20542,6 +21097,11 @@ function registerEnrichCommand(program) {
|
|
|
20542
21097
|
ok: false,
|
|
20543
21098
|
run: status,
|
|
20544
21099
|
output: enrichOutputJson(committedExportResult2),
|
|
21100
|
+
customer_db: enrichCustomerDbJson({
|
|
21101
|
+
status,
|
|
21102
|
+
client: client2,
|
|
21103
|
+
outputPath: enrichIssueFollowUpOutputPath ?? committedExportResult2?.path ?? outputPath
|
|
21104
|
+
}),
|
|
20545
21105
|
...enrichReportJson(failureReport2)
|
|
20546
21106
|
});
|
|
20547
21107
|
}
|
|
@@ -20572,6 +21132,11 @@ function registerEnrichCommand(program) {
|
|
|
20572
21132
|
ok: !failureReport2,
|
|
20573
21133
|
run,
|
|
20574
21134
|
output: enrichOutputJson(committedExportResult2),
|
|
21135
|
+
customer_db: enrichCustomerDbJson({
|
|
21136
|
+
status,
|
|
21137
|
+
client: client2,
|
|
21138
|
+
outputPath: enrichIssueFollowUpOutputPath ?? committedExportResult2?.path ?? outputPath
|
|
21139
|
+
}),
|
|
20575
21140
|
...enrichReportJson(failureReport2)
|
|
20576
21141
|
});
|
|
20577
21142
|
if (failureReport2) {
|
|
@@ -21465,72 +22030,494 @@ Examples:
|
|
|
21465
22030
|
}
|
|
21466
22031
|
|
|
21467
22032
|
// src/cli/commands/monitors.ts
|
|
22033
|
+
var import_node_fs12 = require("fs");
|
|
22034
|
+
var import_promises4 = require("readline/promises");
|
|
21468
22035
|
var FORBIDDEN_AS_API_ERROR = { forbiddenAsApiError: true };
|
|
22036
|
+
var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
|
|
22037
|
+
function withJsonOption(command) {
|
|
22038
|
+
return command.option("--json", JSON_OPTION_DESCRIPTION);
|
|
22039
|
+
}
|
|
22040
|
+
var COMPACT_OPTION_DESCRIPTION = "Ask the server for high-signal fields only (smaller output for agent loops)";
|
|
21469
22041
|
function buildHttpClient() {
|
|
21470
22042
|
return new HttpClient(resolveConfig());
|
|
21471
22043
|
}
|
|
21472
|
-
|
|
21473
|
-
|
|
21474
|
-
|
|
21475
|
-
|
|
21476
|
-
|
|
21477
|
-
throw new Error(
|
|
21478
|
-
`${flag} must be a JSON object. ${error instanceof Error ? error.message : String(error)}`
|
|
21479
|
-
);
|
|
22044
|
+
var MonitorsUsageError = class extends Error {
|
|
22045
|
+
code = "MONITORS_USAGE_ERROR";
|
|
22046
|
+
constructor(message) {
|
|
22047
|
+
super(message);
|
|
22048
|
+
this.name = "MonitorsUsageError";
|
|
21480
22049
|
}
|
|
21481
|
-
|
|
21482
|
-
|
|
22050
|
+
};
|
|
22051
|
+
var MonitorDryRunUnsupportedError = class extends Error {
|
|
22052
|
+
code = "MONITOR_DRY_RUN_UNSUPPORTED";
|
|
22053
|
+
constructor(message) {
|
|
22054
|
+
super(message);
|
|
22055
|
+
this.name = "MonitorDryRunUnsupportedError";
|
|
21483
22056
|
}
|
|
21484
|
-
|
|
21485
|
-
|
|
21486
|
-
|
|
21487
|
-
|
|
22057
|
+
};
|
|
22058
|
+
function monitorsErrorExitCode(error) {
|
|
22059
|
+
if (error instanceof MonitorsUsageError) return 2;
|
|
22060
|
+
if (error instanceof AuthError) return 3;
|
|
22061
|
+
if (error instanceof DeeplineError) {
|
|
22062
|
+
const status = error.statusCode;
|
|
22063
|
+
if (status === 401 || status === 403) return 3;
|
|
22064
|
+
if (status === 404) return 4;
|
|
22065
|
+
if (status === 400 || status === 422) return 7;
|
|
22066
|
+
return 5;
|
|
22067
|
+
}
|
|
22068
|
+
return 5;
|
|
21488
22069
|
}
|
|
21489
|
-
|
|
21490
|
-
|
|
21491
|
-
|
|
21492
|
-
|
|
21493
|
-
if (
|
|
21494
|
-
if (
|
|
21495
|
-
|
|
21496
|
-
const query = params.toString();
|
|
21497
|
-
const payload = await http.request(
|
|
21498
|
-
`/api/v2/monitors/tools${query ? `?${query}` : ""}`,
|
|
21499
|
-
{ method: "GET", ...FORBIDDEN_AS_API_ERROR }
|
|
21500
|
-
);
|
|
21501
|
-
printCommandEnvelope(payload, { json: options.json });
|
|
22070
|
+
function monitorsFailureNextCommand(error, exitCode) {
|
|
22071
|
+
if (error instanceof DeeplineError && error.code === "monitor_access_required") {
|
|
22072
|
+
return "deepline monitors status";
|
|
22073
|
+
}
|
|
22074
|
+
if (exitCode === 3) return "deepline auth status --json";
|
|
22075
|
+
if (exitCode === 4) return "deepline monitors list --status all --json";
|
|
22076
|
+
return void 0;
|
|
21502
22077
|
}
|
|
21503
|
-
|
|
22078
|
+
function readValidationIssues(error) {
|
|
22079
|
+
if (!(error instanceof DeeplineError)) return [];
|
|
22080
|
+
const response = asRecord(asRecord(error.details)?.response);
|
|
22081
|
+
const issues = Array.isArray(response?.issues) ? response.issues : [];
|
|
22082
|
+
return issues.flatMap((raw) => {
|
|
22083
|
+
const issue = asRecord(raw);
|
|
22084
|
+
if (!issue) return [];
|
|
22085
|
+
return [
|
|
22086
|
+
{
|
|
22087
|
+
...asString(issue.path) ? { path: asString(issue.path) } : {},
|
|
22088
|
+
...asString(issue.message) ? { message: asString(issue.message) } : {}
|
|
22089
|
+
}
|
|
22090
|
+
];
|
|
22091
|
+
});
|
|
22092
|
+
}
|
|
22093
|
+
function reportMonitorsFailure(error) {
|
|
22094
|
+
const exitCode = monitorsErrorExitCode(error);
|
|
22095
|
+
const next = monitorsFailureNextCommand(error, exitCode);
|
|
22096
|
+
const wantsJson = shouldEmitJson(process.argv.includes("--json"));
|
|
22097
|
+
if (wantsJson) {
|
|
22098
|
+
const payload = errorToJsonPayload(error);
|
|
22099
|
+
printJson({
|
|
22100
|
+
ok: false,
|
|
22101
|
+
exitCode,
|
|
22102
|
+
...next ? { next } : {},
|
|
22103
|
+
error: payload.error
|
|
22104
|
+
});
|
|
22105
|
+
} else {
|
|
22106
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
22107
|
+
process.stderr.write(`Error: ${message}
|
|
22108
|
+
`);
|
|
22109
|
+
for (const issue of readValidationIssues(error)) {
|
|
22110
|
+
process.stderr.write(
|
|
22111
|
+
` - ${issue.path ? `${issue.path}: ` : ""}${issue.message ?? ""}
|
|
22112
|
+
`
|
|
22113
|
+
);
|
|
22114
|
+
}
|
|
22115
|
+
if (next) process.stderr.write(`Next: ${next}
|
|
22116
|
+
`);
|
|
22117
|
+
}
|
|
22118
|
+
process.exitCode = exitCode;
|
|
22119
|
+
}
|
|
22120
|
+
function monitorsAction(handler) {
|
|
22121
|
+
return async (...args) => {
|
|
22122
|
+
try {
|
|
22123
|
+
await handler(...args);
|
|
22124
|
+
} catch (error) {
|
|
22125
|
+
reportMonitorsFailure(error);
|
|
22126
|
+
}
|
|
22127
|
+
};
|
|
22128
|
+
}
|
|
22129
|
+
function parseJsonObjectArg(raw, argLabel) {
|
|
22130
|
+
let parsed;
|
|
22131
|
+
try {
|
|
22132
|
+
parsed = JSON.parse(raw);
|
|
22133
|
+
} catch (error) {
|
|
22134
|
+
throw new MonitorsUsageError(
|
|
22135
|
+
`${argLabel} must be a JSON object. ${error instanceof Error ? error.message : String(error)}`
|
|
22136
|
+
);
|
|
22137
|
+
}
|
|
22138
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
22139
|
+
throw new MonitorsUsageError(`${argLabel} must be a JSON object.`);
|
|
22140
|
+
}
|
|
22141
|
+
return parsed;
|
|
22142
|
+
}
|
|
22143
|
+
function resolveMonitorJsonBody(input2) {
|
|
22144
|
+
const readFile3 = input2.readFile ?? ((path) => (0, import_node_fs12.readFileSync)(path, "utf-8"));
|
|
22145
|
+
const readStdin = input2.readStdin ?? (() => (0, import_node_fs12.readFileSync)(0, "utf-8"));
|
|
22146
|
+
if (input2.positional !== void 0 && input2.file !== void 0) {
|
|
22147
|
+
throw new MonitorsUsageError(
|
|
22148
|
+
`Pass exactly one source for ${input2.argLabel}: the positional JSON or --file, not both.`
|
|
22149
|
+
);
|
|
22150
|
+
}
|
|
22151
|
+
if (input2.positional !== void 0) {
|
|
22152
|
+
return parseJsonObjectArg(input2.positional, input2.argLabel);
|
|
22153
|
+
}
|
|
22154
|
+
if (input2.file !== void 0) {
|
|
22155
|
+
if (input2.file === "-") {
|
|
22156
|
+
return parseJsonObjectArg(readStdin(), `${input2.argLabel} (stdin)`);
|
|
22157
|
+
}
|
|
22158
|
+
let raw;
|
|
22159
|
+
try {
|
|
22160
|
+
raw = readFile3(input2.file);
|
|
22161
|
+
} catch (error) {
|
|
22162
|
+
throw new MonitorsUsageError(
|
|
22163
|
+
`Could not read --file ${input2.file}: ${error instanceof Error ? error.message : String(error)}`
|
|
22164
|
+
);
|
|
22165
|
+
}
|
|
22166
|
+
return parseJsonObjectArg(raw, `${input2.argLabel} (--file ${input2.file})`);
|
|
22167
|
+
}
|
|
22168
|
+
throw new MonitorsUsageError(
|
|
22169
|
+
`${input2.command} needs ${input2.argLabel} (a JSON object). Pass it positionally:
|
|
22170
|
+
${input2.command} '{"key":"my-monitor","tool":"theirstack.saved_search_webhook","payload":{}}'
|
|
22171
|
+
or from a file / stdin:
|
|
22172
|
+
${input2.command} --file monitor.json
|
|
22173
|
+
cat monitor.json | ${input2.command} --file -`
|
|
22174
|
+
);
|
|
22175
|
+
}
|
|
22176
|
+
function encodeKey(key) {
|
|
22177
|
+
return encodeURIComponent(key);
|
|
22178
|
+
}
|
|
22179
|
+
function asRecord(value) {
|
|
22180
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
22181
|
+
}
|
|
22182
|
+
function asString(value) {
|
|
22183
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
22184
|
+
}
|
|
22185
|
+
function asFiniteNumber(value) {
|
|
22186
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
22187
|
+
}
|
|
22188
|
+
function yesNo(value) {
|
|
22189
|
+
if (value === true) return "yes";
|
|
22190
|
+
if (value === false) return "no";
|
|
22191
|
+
return "unknown";
|
|
22192
|
+
}
|
|
22193
|
+
function readDeployOutputContract(payload) {
|
|
22194
|
+
const contract = asRecord(payload.output_contract);
|
|
22195
|
+
if (!contract) return { streams: [] };
|
|
22196
|
+
const rawOutputs = Array.isArray(contract.outputs) ? contract.outputs : [];
|
|
22197
|
+
const streams = rawOutputs.flatMap((raw) => {
|
|
22198
|
+
const output2 = asRecord(raw);
|
|
22199
|
+
const stream = output2 ? asString(output2.stream) : void 0;
|
|
22200
|
+
const table = output2 ? asString(output2.table) : void 0;
|
|
22201
|
+
if (!output2 || !stream || !table) return [];
|
|
22202
|
+
const columns = Array.isArray(output2.columns) ? output2.columns.flatMap((rawColumn) => {
|
|
22203
|
+
const column = asRecord(rawColumn);
|
|
22204
|
+
const name = column ? asString(column.name) : void 0;
|
|
22205
|
+
return name ? [name] : [];
|
|
22206
|
+
}) : [];
|
|
22207
|
+
return [
|
|
22208
|
+
{
|
|
22209
|
+
stream,
|
|
22210
|
+
table,
|
|
22211
|
+
columns,
|
|
22212
|
+
isEvent: output2.is_event_stream === true,
|
|
22213
|
+
matchesPayload: output2.matches_payload === true
|
|
22214
|
+
}
|
|
22215
|
+
];
|
|
22216
|
+
});
|
|
22217
|
+
return { tool: asString(contract.tool), streams };
|
|
22218
|
+
}
|
|
22219
|
+
function renderMonitorDeployCompletion(payload) {
|
|
22220
|
+
const monitor = asRecord(payload.monitor);
|
|
22221
|
+
const key = monitor ? asString(monitor.key) : void 0;
|
|
22222
|
+
const { tool, streams } = readDeployOutputContract(payload);
|
|
22223
|
+
if (!key || streams.length === 0) return void 0;
|
|
22224
|
+
const toolId = tool ?? (monitor ? asString(monitor.tool) : void 0) ?? "<tool>";
|
|
22225
|
+
const name = monitor ? asString(monitor.name) : void 0;
|
|
22226
|
+
const status = monitor ? asString(monitor.status) : void 0;
|
|
22227
|
+
const eventStreams = streams.filter((stream) => stream.isEvent);
|
|
22228
|
+
const matched = eventStreams.filter((stream) => stream.matchesPayload);
|
|
22229
|
+
const shown = matched.length ? matched : eventStreams.length ? eventStreams : streams;
|
|
22230
|
+
const primary = shown[0];
|
|
22231
|
+
const lines = [
|
|
22232
|
+
`\u2713 Deployed monitor "${key}"${name ? ` (${name})` : ""} \u2014 tool ${toolId}${status ? `, status ${status}` : ""}`,
|
|
22233
|
+
"",
|
|
22234
|
+
"Output \u2192 Customer DB:"
|
|
22235
|
+
];
|
|
22236
|
+
for (const stream of shown) {
|
|
22237
|
+
lines.push(` ${stream.table} (stream: ${stream.stream})`);
|
|
22238
|
+
lines.push(
|
|
22239
|
+
` columns: ${stream.columns.length ? stream.columns.join(", ") : "(promoted dynamically as events arrive)"}`
|
|
22240
|
+
);
|
|
22241
|
+
}
|
|
22242
|
+
lines.push(
|
|
22243
|
+
"",
|
|
22244
|
+
"This monitor streams new rows into your Customer DB \u2014 there is no manual run.",
|
|
22245
|
+
"Next:",
|
|
22246
|
+
" \u2022 Query the table above directly, or",
|
|
22247
|
+
" \u2022 Run a play on each new row (third arg to definePlay in your .play.ts):",
|
|
22248
|
+
` sqlListeners: [{ id: '${primary.stream}', tool: '${toolId}', stream: '${primary.stream}', operations: ['INSERT'] }]`,
|
|
22249
|
+
" The changed row arrives to your handler as the sqlListener event's `after`.",
|
|
22250
|
+
"",
|
|
22251
|
+
"Reuse: many plays can bind to this one stream \u2014 you do NOT need a separate",
|
|
22252
|
+
"monitor per play. Before deploying another monitor on this tool, run",
|
|
22253
|
+
"`deepline monitors list` and reuse an existing one that covers your scope."
|
|
22254
|
+
);
|
|
22255
|
+
return `${lines.join("\n")}
|
|
22256
|
+
`;
|
|
22257
|
+
}
|
|
22258
|
+
function renderMonitorDeployPlan(payload) {
|
|
22259
|
+
const valid = payload.valid !== false;
|
|
22260
|
+
const lines = [
|
|
22261
|
+
"DRY RUN \u2014 nothing was deployed.",
|
|
22262
|
+
valid ? "Definition: valid" : "Definition: INVALID"
|
|
22263
|
+
];
|
|
22264
|
+
if (!valid) {
|
|
22265
|
+
const issues = Array.isArray(payload.issues) ? payload.issues : [];
|
|
22266
|
+
for (const raw of issues) {
|
|
22267
|
+
const issue = asRecord(raw);
|
|
22268
|
+
const path = issue ? asString(issue.path) : void 0;
|
|
22269
|
+
const message = issue ? asString(issue.message) : void 0;
|
|
22270
|
+
if (message) lines.push(` - ${path ? `${path}: ` : ""}${message}`);
|
|
22271
|
+
}
|
|
22272
|
+
}
|
|
22273
|
+
const estimate = asRecord(payload.deploy_cost_estimate);
|
|
22274
|
+
const credits = estimate ? asFiniteNumber(estimate.credits) : void 0;
|
|
22275
|
+
if (credits !== void 0) {
|
|
22276
|
+
const note = estimate ? asString(estimate.note) : void 0;
|
|
22277
|
+
lines.push(
|
|
22278
|
+
`Deploy cost: would cost ${credits} Deepline credits${note ? ` \u2014 ${note}` : ""}.`
|
|
22279
|
+
);
|
|
22280
|
+
} else {
|
|
22281
|
+
lines.push(
|
|
22282
|
+
"Deploy cost: estimate unavailable from this server (validation only)."
|
|
22283
|
+
);
|
|
22284
|
+
}
|
|
22285
|
+
const candidates = Array.isArray(payload.reuse_candidates) ? payload.reuse_candidates : [];
|
|
22286
|
+
const candidateLines = candidates.flatMap((raw) => {
|
|
22287
|
+
const candidate = asRecord(raw);
|
|
22288
|
+
const key = candidate ? asString(candidate.key) : void 0;
|
|
22289
|
+
if (!candidate || !key) return [];
|
|
22290
|
+
const name = asString(candidate.name);
|
|
22291
|
+
const status = asString(candidate.status);
|
|
22292
|
+
const covers = asString(candidate.covers);
|
|
22293
|
+
return [
|
|
22294
|
+
` ${key}${name ? ` (${name})` : ""}${status ? ` \u2014 ${status}` : ""}${covers ? `; covers ${covers}` : ""}`
|
|
22295
|
+
];
|
|
22296
|
+
});
|
|
22297
|
+
if (candidateLines.length > 0) {
|
|
22298
|
+
lines.push(
|
|
22299
|
+
"",
|
|
22300
|
+
"You may already have a monitor covering this \u2014 check before deploying:",
|
|
22301
|
+
...candidateLines,
|
|
22302
|
+
" Inspect: deepline monitors get <key> --json"
|
|
22303
|
+
);
|
|
22304
|
+
}
|
|
22305
|
+
lines.push(
|
|
22306
|
+
"",
|
|
22307
|
+
valid ? "Deploy for real: re-run this command without --dry-run." : "Fix the definition, then re-run this command."
|
|
22308
|
+
);
|
|
22309
|
+
return `${lines.join("\n")}
|
|
22310
|
+
`;
|
|
22311
|
+
}
|
|
22312
|
+
function renderMonitorDeletePlan(payload, fallbackKey) {
|
|
22313
|
+
const plan = asRecord(payload.plan);
|
|
22314
|
+
const key = (plan ? asString(plan.monitor_key) : void 0) ?? fallbackKey;
|
|
22315
|
+
const lines = [
|
|
22316
|
+
"DRY RUN \u2014 nothing was deleted.",
|
|
22317
|
+
`Delete plan for monitor "${key}":`,
|
|
22318
|
+
` delete Deepline record: ${yesNo(plan?.would_delete_record)}`,
|
|
22319
|
+
` deprovision upstream provider resource: ${yesNo(plan?.would_deprovision_upstream)}`,
|
|
22320
|
+
"",
|
|
22321
|
+
`Delete for real: deepline monitors delete ${key} --yes`
|
|
22322
|
+
];
|
|
22323
|
+
return `${lines.join("\n")}
|
|
22324
|
+
`;
|
|
22325
|
+
}
|
|
22326
|
+
function renderMonitorReactivatePlan(payload, key) {
|
|
22327
|
+
const estimate = asRecord(payload.cost_estimate);
|
|
22328
|
+
const credits = estimate ? asFiniteNumber(estimate.credits) : void 0;
|
|
22329
|
+
const lines = [
|
|
22330
|
+
"DRY RUN \u2014 nothing was reactivated.",
|
|
22331
|
+
credits !== void 0 ? `Reactivate cost: would cost ${credits} Deepline credits.` : "Reactivate cost: estimate unavailable from this server.",
|
|
22332
|
+
"",
|
|
22333
|
+
`Reactivate for real: deepline monitors reactivate ${key}`
|
|
22334
|
+
];
|
|
22335
|
+
return `${lines.join("\n")}
|
|
22336
|
+
`;
|
|
22337
|
+
}
|
|
22338
|
+
function assertMonitorDryRunAcknowledged(payload, context) {
|
|
22339
|
+
if (payload.dry_run === true) return;
|
|
22340
|
+
throw new MonitorDryRunUnsupportedError(
|
|
22341
|
+
`${context.command} --dry-run: the server response did not acknowledge dry-run mode (missing "dry_run": true). This Deepline server may not support --dry-run for ${context.mutation}, so the response cannot be trusted as a plan. Nothing was rendered as a plan. Verify current state with \`deepline monitors get <key> --json\`, and re-run without --dry-run only when you intend the real ${context.mutation}.`
|
|
22342
|
+
);
|
|
22343
|
+
}
|
|
22344
|
+
function monitorDeleteRequiresYesError(key, options = {}) {
|
|
22345
|
+
const flags = options.localOnly ? " --local-only" : "";
|
|
22346
|
+
return new MonitorsUsageError(
|
|
22347
|
+
`monitors delete is destructive: it deletes monitor "${key}"${options.localOnly ? " (Deepline record only)" : " and deprovisions its upstream provider resource"}. Non-interactive runs must confirm with --yes:
|
|
22348
|
+
deepline monitors delete ${key}${flags} --yes
|
|
22349
|
+
Preview the plan first with:
|
|
22350
|
+
deepline monitors delete ${key}${flags} --dry-run`
|
|
22351
|
+
);
|
|
22352
|
+
}
|
|
22353
|
+
async function handleMonitorsStatus(options) {
|
|
21504
22354
|
const http = buildHttpClient();
|
|
21505
|
-
const body = parseJsonObjectArg(definition, "--definition");
|
|
21506
22355
|
const payload = await http.request(
|
|
21507
|
-
"/api/v2/monitors/
|
|
21508
|
-
{ method: "
|
|
22356
|
+
"/api/v2/monitors/access",
|
|
22357
|
+
{ method: "GET" }
|
|
22358
|
+
);
|
|
22359
|
+
const hasAccess = payload.has_access === true;
|
|
22360
|
+
const reason = typeof payload.reason === "string" && payload.reason.trim() ? payload.reason.trim() : void 0;
|
|
22361
|
+
const text = hasAccess ? `\u2713 You have access to Deepline Monitors${reason ? `
|
|
22362
|
+
${reason}` : ""}
|
|
22363
|
+
` : `\u2717 No access to Deepline Monitors${reason ? ` \u2014 ${reason}` : ""}
|
|
22364
|
+
`;
|
|
22365
|
+
printCommandEnvelope(
|
|
22366
|
+
{ has_access: hasAccess, ...reason ? { reason } : {} },
|
|
22367
|
+
{ json: options.json, text }
|
|
21509
22368
|
);
|
|
21510
|
-
|
|
22369
|
+
if (!hasAccess) {
|
|
22370
|
+
process.exitCode = 1;
|
|
22371
|
+
}
|
|
21511
22372
|
}
|
|
21512
|
-
|
|
22373
|
+
function renderAvailableToolsText(payload) {
|
|
22374
|
+
const tools = Array.isArray(payload.tools) ? payload.tools : null;
|
|
22375
|
+
if (!tools) return void 0;
|
|
22376
|
+
const returned = asFiniteNumber(payload.returned) ?? tools.length;
|
|
22377
|
+
const total = asFiniteNumber(payload.total);
|
|
22378
|
+
const lines = [
|
|
22379
|
+
total !== void 0 ? `Monitor tools you can deploy (${returned} of ${total}):` : "Monitor tools you can deploy:"
|
|
22380
|
+
];
|
|
22381
|
+
for (const raw of tools) {
|
|
22382
|
+
const entry = asRecord(raw);
|
|
22383
|
+
const id = entry ? asString(entry.tool) : void 0;
|
|
22384
|
+
if (!entry || !id) continue;
|
|
22385
|
+
const name = asString(entry.name) ?? asString(entry.display_name);
|
|
22386
|
+
const deployedCount = asFiniteNumber(entry.deployed_count);
|
|
22387
|
+
lines.push(
|
|
22388
|
+
` ${id}${name ? ` \u2014 ${name}` : ""}${deployedCount !== void 0 ? ` (deployed: ${deployedCount})` : ""}`
|
|
22389
|
+
);
|
|
22390
|
+
}
|
|
22391
|
+
if (payload.is_truncated === true) {
|
|
22392
|
+
lines.push("List truncated; raise --limit to see more.");
|
|
22393
|
+
}
|
|
22394
|
+
lines.push(
|
|
22395
|
+
"",
|
|
22396
|
+
"Describe one (payload schema + output streams): deepline monitors available <tool-id> --json"
|
|
22397
|
+
);
|
|
22398
|
+
return `${lines.join("\n")}
|
|
22399
|
+
`;
|
|
22400
|
+
}
|
|
22401
|
+
async function handleMonitorsAvailable(toolId, options) {
|
|
22402
|
+
if (toolId !== void 0 && options.tool !== void 0) {
|
|
22403
|
+
if (toolId !== options.tool) {
|
|
22404
|
+
throw new MonitorsUsageError(
|
|
22405
|
+
`Pass the tool id once: got positional "${toolId}" and --tool "${options.tool}". Use: deepline monitors available ${toolId}`
|
|
22406
|
+
);
|
|
22407
|
+
}
|
|
22408
|
+
}
|
|
22409
|
+
const tool = toolId ?? options.tool;
|
|
21513
22410
|
const http = buildHttpClient();
|
|
21514
|
-
const
|
|
22411
|
+
const params = new URLSearchParams();
|
|
22412
|
+
if (options.provider) params.set("provider", options.provider);
|
|
22413
|
+
if (tool) params.set("tool", tool);
|
|
22414
|
+
if (options.search) params.set("search", options.search);
|
|
22415
|
+
if (options.limit) params.set("limit", options.limit);
|
|
22416
|
+
const compactList = !tool && !options.full;
|
|
22417
|
+
if (compactList || options.compact) params.set("compact", "true");
|
|
22418
|
+
const query = params.toString();
|
|
21515
22419
|
const payload = await http.request(
|
|
21516
|
-
|
|
21517
|
-
{ method: "
|
|
22420
|
+
`/api/v2/monitors/tools${query ? `?${query}` : ""}`,
|
|
22421
|
+
{ method: "GET", ...FORBIDDEN_AS_API_ERROR }
|
|
21518
22422
|
);
|
|
21519
|
-
printCommandEnvelope(payload, {
|
|
22423
|
+
printCommandEnvelope(payload, {
|
|
22424
|
+
json: options.json,
|
|
22425
|
+
// Human list view shows id + name + deployed_count ("deployed: N") so
|
|
22426
|
+
// can-deploy vs already-deployed is visible in one view. Describing a
|
|
22427
|
+
// single tool keeps the full JSON contract (payload schema, streams).
|
|
22428
|
+
text: tool ? void 0 : renderAvailableToolsText(payload)
|
|
22429
|
+
});
|
|
22430
|
+
}
|
|
22431
|
+
function renderDeployedListText(payload, requestedStatus) {
|
|
22432
|
+
const monitors = Array.isArray(payload.monitors) ? payload.monitors : null;
|
|
22433
|
+
if (!monitors) return void 0;
|
|
22434
|
+
const lines = [
|
|
22435
|
+
monitors.length === 0 ? "No deployed monitors matched." : `Deployed monitors (${monitors.length}):`
|
|
22436
|
+
];
|
|
22437
|
+
for (const raw of monitors) {
|
|
22438
|
+
const entry = asRecord(raw);
|
|
22439
|
+
const key = entry ? asString(entry.key) ?? asString(entry.monitor_key) : void 0;
|
|
22440
|
+
if (!entry || !key) continue;
|
|
22441
|
+
const status = asString(entry.status);
|
|
22442
|
+
const tool = asString(entry.tool);
|
|
22443
|
+
const name = asString(entry.name);
|
|
22444
|
+
lines.push(
|
|
22445
|
+
` ${key}${status ? ` ${status}` : ""}${tool ? ` ${tool}` : ""}${name ? ` (${name})` : ""}`
|
|
22446
|
+
);
|
|
22447
|
+
}
|
|
22448
|
+
const applied = asString(payload.status_filter_applied) ?? requestedStatus ?? "active";
|
|
22449
|
+
lines.push(
|
|
22450
|
+
`Status filter: ${applied}${requestedStatus === void 0 && applied === "active" ? " (default)" : ""} \u2014 use --status all to include disabled monitors.`
|
|
22451
|
+
);
|
|
22452
|
+
if (monitors.length > 0) {
|
|
22453
|
+
lines.push("", "Inspect one: deepline monitors get <key> --json");
|
|
22454
|
+
}
|
|
22455
|
+
return `${lines.join("\n")}
|
|
22456
|
+
`;
|
|
21520
22457
|
}
|
|
21521
|
-
async function
|
|
22458
|
+
async function handleMonitorsList(options) {
|
|
21522
22459
|
const http = buildHttpClient();
|
|
21523
22460
|
const params = new URLSearchParams();
|
|
21524
22461
|
if (options.status) params.set("status", options.status);
|
|
21525
22462
|
if (options.limit) params.set("limit", options.limit);
|
|
22463
|
+
if (options.compact) params.set("compact", "true");
|
|
21526
22464
|
const query = params.toString();
|
|
21527
22465
|
const payload = await http.request(
|
|
21528
22466
|
`/api/v2/monitors/deployed${query ? `?${query}` : ""}`,
|
|
21529
22467
|
{ method: "GET", ...FORBIDDEN_AS_API_ERROR }
|
|
21530
22468
|
);
|
|
22469
|
+
printCommandEnvelope(payload, {
|
|
22470
|
+
json: options.json,
|
|
22471
|
+
text: renderDeployedListText(payload, options.status)
|
|
22472
|
+
});
|
|
22473
|
+
}
|
|
22474
|
+
async function handleMonitorsCheck(definition, options) {
|
|
22475
|
+
const http = buildHttpClient();
|
|
22476
|
+
const body = resolveMonitorJsonBody({
|
|
22477
|
+
positional: definition,
|
|
22478
|
+
file: options.file,
|
|
22479
|
+
argLabel: "<definition>",
|
|
22480
|
+
command: "deepline monitors check"
|
|
22481
|
+
});
|
|
22482
|
+
const payload = await http.request(
|
|
22483
|
+
"/api/v2/monitors/check",
|
|
22484
|
+
{ method: "POST", body, ...FORBIDDEN_AS_API_ERROR }
|
|
22485
|
+
);
|
|
21531
22486
|
printCommandEnvelope(payload, { json: options.json });
|
|
21532
22487
|
}
|
|
21533
|
-
async function
|
|
22488
|
+
async function handleMonitorsDeploy(definition, options) {
|
|
22489
|
+
const http = buildHttpClient();
|
|
22490
|
+
const body = resolveMonitorJsonBody({
|
|
22491
|
+
positional: definition,
|
|
22492
|
+
file: options.file,
|
|
22493
|
+
argLabel: "<definition>",
|
|
22494
|
+
command: "deepline monitors deploy"
|
|
22495
|
+
});
|
|
22496
|
+
if (options.dryRun) {
|
|
22497
|
+
const payload2 = await http.request(
|
|
22498
|
+
"/api/v2/monitors/check",
|
|
22499
|
+
{ method: "POST", body, ...FORBIDDEN_AS_API_ERROR }
|
|
22500
|
+
);
|
|
22501
|
+
const valid = payload2.valid !== false;
|
|
22502
|
+
printCommandEnvelope(
|
|
22503
|
+
{ dry_run: true, ...payload2 },
|
|
22504
|
+
{ json: options.json, text: renderMonitorDeployPlan(payload2) }
|
|
22505
|
+
);
|
|
22506
|
+
if (!valid) {
|
|
22507
|
+
process.exitCode = 7;
|
|
22508
|
+
}
|
|
22509
|
+
return;
|
|
22510
|
+
}
|
|
22511
|
+
const payload = await http.request(
|
|
22512
|
+
"/api/v2/monitors/deploy",
|
|
22513
|
+
{ method: "POST", body, ...FORBIDDEN_AS_API_ERROR }
|
|
22514
|
+
);
|
|
22515
|
+
printCommandEnvelope(payload, {
|
|
22516
|
+
json: options.json,
|
|
22517
|
+
text: renderMonitorDeployCompletion(payload)
|
|
22518
|
+
});
|
|
22519
|
+
}
|
|
22520
|
+
async function handleMonitorsGet(key, options) {
|
|
21534
22521
|
const http = buildHttpClient();
|
|
21535
22522
|
const payload = await http.request(
|
|
21536
22523
|
`/api/v2/monitors/deployed/${encodeKey(key)}`,
|
|
@@ -21538,10 +22525,58 @@ async function handleDeployedGet(key, options) {
|
|
|
21538
22525
|
);
|
|
21539
22526
|
printCommandEnvelope(payload, { json: options.json });
|
|
21540
22527
|
}
|
|
21541
|
-
async function
|
|
22528
|
+
async function confirmMonitorDelete(key, options) {
|
|
22529
|
+
const rl = (0, import_promises4.createInterface)({
|
|
22530
|
+
input: process.stdin,
|
|
22531
|
+
output: process.stderr
|
|
22532
|
+
});
|
|
22533
|
+
try {
|
|
22534
|
+
const consequence = options.localOnly ? "This removes the Deepline record only (the upstream provider resource is left in place)." : "This deprovisions the upstream provider resource.";
|
|
22535
|
+
const answer = await rl.question(
|
|
22536
|
+
`Delete monitor "${key}"? ${consequence} [y/N] `
|
|
22537
|
+
);
|
|
22538
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
22539
|
+
} finally {
|
|
22540
|
+
rl.close();
|
|
22541
|
+
}
|
|
22542
|
+
}
|
|
22543
|
+
async function handleMonitorsDelete(key, options) {
|
|
21542
22544
|
const http = buildHttpClient();
|
|
21543
22545
|
const params = new URLSearchParams();
|
|
21544
22546
|
if (options.localOnly) params.set("local_only", "true");
|
|
22547
|
+
if (options.dryRun) {
|
|
22548
|
+
params.set("dry_run", "true");
|
|
22549
|
+
const payload2 = await http.request(
|
|
22550
|
+
`/api/v2/monitors/deployed/${encodeKey(key)}?${params.toString()}`,
|
|
22551
|
+
{ method: "DELETE", ...FORBIDDEN_AS_API_ERROR }
|
|
22552
|
+
);
|
|
22553
|
+
assertMonitorDryRunAcknowledged(payload2, {
|
|
22554
|
+
command: "deepline monitors delete",
|
|
22555
|
+
mutation: "delete"
|
|
22556
|
+
});
|
|
22557
|
+
printCommandEnvelope(payload2, {
|
|
22558
|
+
json: options.json,
|
|
22559
|
+
text: renderMonitorDeletePlan(payload2, key)
|
|
22560
|
+
});
|
|
22561
|
+
return;
|
|
22562
|
+
}
|
|
22563
|
+
if (!options.yes) {
|
|
22564
|
+
const interactive = process.stdout.isTTY === true && process.stdin.isTTY === true;
|
|
22565
|
+
if (!interactive) {
|
|
22566
|
+
throw monitorDeleteRequiresYesError(key, {
|
|
22567
|
+
localOnly: options.localOnly
|
|
22568
|
+
});
|
|
22569
|
+
}
|
|
22570
|
+
const confirmed = await confirmMonitorDelete(key, {
|
|
22571
|
+
localOnly: options.localOnly
|
|
22572
|
+
});
|
|
22573
|
+
if (!confirmed) {
|
|
22574
|
+
process.stderr.write(`Aborted. Monitor "${key}" was not deleted.
|
|
22575
|
+
`);
|
|
22576
|
+
process.exitCode = 2;
|
|
22577
|
+
return;
|
|
22578
|
+
}
|
|
22579
|
+
}
|
|
21545
22580
|
const query = params.toString();
|
|
21546
22581
|
const payload = await http.request(
|
|
21547
22582
|
`/api/v2/monitors/deployed/${encodeKey(key)}${query ? `?${query}` : ""}`,
|
|
@@ -21549,17 +22584,37 @@ async function handleDeployedDelete(key, options) {
|
|
|
21549
22584
|
);
|
|
21550
22585
|
printCommandEnvelope(payload, { json: options.json });
|
|
21551
22586
|
}
|
|
21552
|
-
async function
|
|
22587
|
+
async function handleMonitorsUpdate(key, patch, options) {
|
|
21553
22588
|
const http = buildHttpClient();
|
|
21554
|
-
const body =
|
|
22589
|
+
const body = resolveMonitorJsonBody({
|
|
22590
|
+
positional: patch,
|
|
22591
|
+
file: options.file,
|
|
22592
|
+
argLabel: "<patch>",
|
|
22593
|
+
command: `deepline monitors update ${key}`
|
|
22594
|
+
});
|
|
21555
22595
|
const payload = await http.request(
|
|
21556
22596
|
`/api/v2/monitors/deployed/${encodeKey(key)}`,
|
|
21557
22597
|
{ method: "PATCH", body, ...FORBIDDEN_AS_API_ERROR }
|
|
21558
22598
|
);
|
|
21559
22599
|
printCommandEnvelope(payload, { json: options.json });
|
|
21560
22600
|
}
|
|
21561
|
-
async function
|
|
22601
|
+
async function handleMonitorsReactivate(key, options) {
|
|
21562
22602
|
const http = buildHttpClient();
|
|
22603
|
+
if (options.dryRun) {
|
|
22604
|
+
const payload2 = await http.request(
|
|
22605
|
+
`/api/v2/monitors/deployed/${encodeKey(key)}/reactivate?dry_run=true`,
|
|
22606
|
+
{ method: "POST", body: {}, ...FORBIDDEN_AS_API_ERROR }
|
|
22607
|
+
);
|
|
22608
|
+
assertMonitorDryRunAcknowledged(payload2, {
|
|
22609
|
+
command: "deepline monitors reactivate",
|
|
22610
|
+
mutation: "reactivate"
|
|
22611
|
+
});
|
|
22612
|
+
printCommandEnvelope(payload2, {
|
|
22613
|
+
json: options.json,
|
|
22614
|
+
text: renderMonitorReactivatePlan(payload2, key)
|
|
22615
|
+
});
|
|
22616
|
+
return;
|
|
22617
|
+
}
|
|
21563
22618
|
const payload = await http.request(
|
|
21564
22619
|
`/api/v2/monitors/deployed/${encodeKey(key)}/reactivate`,
|
|
21565
22620
|
{ method: "POST", body: {}, ...FORBIDDEN_AS_API_ERROR }
|
|
@@ -21567,116 +22622,240 @@ async function handleReactivate(key, options) {
|
|
|
21567
22622
|
printCommandEnvelope(payload, { json: options.json });
|
|
21568
22623
|
}
|
|
21569
22624
|
function registerMonitorsCommands(program) {
|
|
21570
|
-
const monitors = program.command("monitors").description("Discover, deploy, and manage Deepline monitors.").addHelpText(
|
|
22625
|
+
const monitors = program.command("monitors").description("Discover, deploy, and manage Deepline monitors.").showSuggestionAfterError(true).addHelpText(
|
|
21571
22626
|
"after",
|
|
21572
22627
|
`
|
|
21573
22628
|
Notes:
|
|
21574
|
-
|
|
21575
|
-
|
|
21576
|
-
|
|
22629
|
+
Deepline monitors are provider-backed signal feeds: a monitor writes provider
|
|
22630
|
+
events into a Customer DB table; a play reacts to each new row via a
|
|
22631
|
+
sqlListeners trigger \u2014 see \`deepline plays bootstrap monitor-triggered\`.
|
|
22632
|
+
Access is granted by a Deepline admin via Admin -> Rollouts; until then these
|
|
22633
|
+
commands return a clear monitor_access_required error.
|
|
22634
|
+
|
|
22635
|
+
Exit codes:
|
|
22636
|
+
0 success; 2 usage/local input; 3 auth or permission; 4 not found;
|
|
22637
|
+
5 server failure; 7 validation failed.
|
|
22638
|
+
\`monitors status\` exits 1 when you lack monitor access (documented contract).
|
|
21577
22639
|
|
|
21578
22640
|
Examples:
|
|
21579
|
-
deepline monitors
|
|
21580
|
-
deepline monitors
|
|
21581
|
-
deepline monitors
|
|
21582
|
-
deepline monitors
|
|
21583
|
-
deepline monitors
|
|
21584
|
-
deepline monitors
|
|
22641
|
+
deepline monitors status --json
|
|
22642
|
+
deepline monitors available --json # compact list by default
|
|
22643
|
+
deepline monitors available --full --json # complete catalog
|
|
22644
|
+
deepline monitors available theirstack.saved_search_webhook --json
|
|
22645
|
+
deepline monitors check '{"key":"my-monitor","tool":"theirstack.saved_search_webhook","payload":{}}'
|
|
22646
|
+
deepline monitors deploy --dry-run --file monitor.json
|
|
22647
|
+
deepline monitors deploy --file monitor.json
|
|
22648
|
+
deepline monitors list --status all --json
|
|
22649
|
+
deepline monitors get my-monitor --json
|
|
22650
|
+
deepline monitors update my-monitor '{"controls":{"enabled":false}}' --json
|
|
22651
|
+
deepline monitors delete my-monitor --dry-run
|
|
22652
|
+
deepline monitors reactivate my-monitor --dry-run
|
|
21585
22653
|
`
|
|
21586
22654
|
);
|
|
21587
|
-
|
|
21588
|
-
"
|
|
21589
|
-
|
|
22655
|
+
withJsonOption(
|
|
22656
|
+
monitors.command("status").description("Check whether you have access to Deepline monitors.").addHelpText(
|
|
22657
|
+
"after",
|
|
22658
|
+
`
|
|
21590
22659
|
Notes:
|
|
21591
|
-
Read-only.
|
|
21592
|
-
|
|
22660
|
+
Read-only access check. Requires authentication but NOT monitor access, so it
|
|
22661
|
+
is safe to run first to confirm whether you can use the monitor commands. Exits
|
|
22662
|
+
0 when you have access and 1 when you do not, so agents can branch on it (this
|
|
22663
|
+
exit-1 denial contract predates the typed monitor exit codes and is kept).
|
|
21593
22664
|
|
|
21594
22665
|
Examples:
|
|
21595
|
-
deepline monitors
|
|
21596
|
-
deepline monitors
|
|
21597
|
-
deepline monitors tools --tool theirstack_jobs --json
|
|
22666
|
+
deepline monitors status
|
|
22667
|
+
deepline monitors status --json
|
|
21598
22668
|
`
|
|
21599
|
-
|
|
21600
|
-
|
|
21601
|
-
|
|
21602
|
-
|
|
22669
|
+
)
|
|
22670
|
+
).action(monitorsAction(handleMonitorsStatus));
|
|
22671
|
+
withJsonOption(
|
|
22672
|
+
monitors.command("available [tool-id]").alias("tools").description(
|
|
22673
|
+
"List the monitor types you can deploy, or describe one by tool id."
|
|
22674
|
+
).addHelpText(
|
|
22675
|
+
"after",
|
|
22676
|
+
`
|
|
21603
22677
|
Notes:
|
|
21604
|
-
Read-only
|
|
21605
|
-
|
|
22678
|
+
Read-only catalog of deployable monitor types. Pass a tool id positionally to
|
|
22679
|
+
describe one (payload schema + output streams). Filter the list with
|
|
22680
|
+
--provider, --search, or --limit. List entries include how many monitors you
|
|
22681
|
+
already have deployed on each tool ("deployed: N") when the server reports it.
|
|
22682
|
+
The list is compact by default (id + name + deployed count); pass --full to
|
|
22683
|
+
get the complete catalog (payload schemas + output streams for every tool).
|
|
22684
|
+
Describing a single tool by id always returns the full contract.
|
|
21606
22685
|
|
|
21607
22686
|
Examples:
|
|
21608
|
-
deepline monitors
|
|
22687
|
+
deepline monitors available
|
|
22688
|
+
deepline monitors available --full --json
|
|
22689
|
+
deepline monitors available --provider theirstack --json
|
|
22690
|
+
deepline monitors available theirstack.saved_search_webhook --json
|
|
22691
|
+
deepline monitors available --search jobs --json
|
|
21609
22692
|
`
|
|
21610
|
-
|
|
21611
|
-
|
|
21612
|
-
|
|
21613
|
-
|
|
22693
|
+
).option("--provider <provider>", "Filter by provider").option(
|
|
22694
|
+
"--tool <tool>",
|
|
22695
|
+
"Describe a single monitor tool by id (same as the positional tool-id)"
|
|
22696
|
+
).option("--search <query>", "Search monitor tools by text").option("--limit <n>", "Limit the number of monitor tools returned").option(
|
|
22697
|
+
"--full",
|
|
22698
|
+
"Return the complete monitor catalog (payload schemas + output streams). The list is compact by default."
|
|
22699
|
+
).option("--compact", COMPACT_OPTION_DESCRIPTION)
|
|
22700
|
+
).action(monitorsAction(handleMonitorsAvailable));
|
|
22701
|
+
withJsonOption(
|
|
22702
|
+
monitors.command("list").description("List the monitors you have deployed.").addHelpText(
|
|
22703
|
+
"after",
|
|
22704
|
+
`
|
|
21614
22705
|
Notes:
|
|
21615
|
-
|
|
21616
|
-
|
|
22706
|
+
Read-only. --status filters by monitor status: active (default), disabled, or
|
|
22707
|
+
all. The output echoes the status filter that was applied. --compact returns
|
|
22708
|
+
high-signal fields only.
|
|
21617
22709
|
|
|
21618
22710
|
Examples:
|
|
21619
|
-
deepline monitors
|
|
22711
|
+
deepline monitors list
|
|
22712
|
+
deepline monitors list --status all --json
|
|
22713
|
+
deepline monitors list --compact --json
|
|
21620
22714
|
`
|
|
21621
|
-
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
22715
|
+
).option(
|
|
22716
|
+
"--status <status>",
|
|
22717
|
+
"Filter by monitor status: active (default), disabled, or all"
|
|
22718
|
+
).option("--limit <n>", "Limit the number of deployed monitors returned").option("--compact", COMPACT_OPTION_DESCRIPTION)
|
|
22719
|
+
).action(monitorsAction(handleMonitorsList));
|
|
22720
|
+
withJsonOption(
|
|
22721
|
+
monitors.command("get <key>").description("Show a single deployed monitor by its public key.").addHelpText(
|
|
22722
|
+
"after",
|
|
22723
|
+
`
|
|
21625
22724
|
Notes:
|
|
21626
|
-
|
|
22725
|
+
Read-only.
|
|
21627
22726
|
|
|
21628
22727
|
Examples:
|
|
21629
|
-
deepline monitors
|
|
22728
|
+
deepline monitors get my-monitor --json
|
|
21630
22729
|
`
|
|
21631
|
-
|
|
21632
|
-
|
|
21633
|
-
|
|
21634
|
-
|
|
22730
|
+
)
|
|
22731
|
+
).action(monitorsAction(handleMonitorsGet));
|
|
22732
|
+
withJsonOption(
|
|
22733
|
+
monitors.command("check [definition]").description("Validate a monitor definition without deploying it.").addHelpText(
|
|
22734
|
+
"after",
|
|
22735
|
+
`
|
|
21635
22736
|
Notes:
|
|
21636
|
-
|
|
21637
|
-
|
|
22737
|
+
Read-only validation. <definition> is a JSON object with key, tool, payload,
|
|
22738
|
+
and optional controls (Deepline lifecycle metadata, e.g.
|
|
22739
|
+
"controls":{"enabled":false}). Pass it positionally, via --file <path>, or
|
|
22740
|
+
from stdin with --file -. Does not deploy or spend credits.
|
|
21638
22741
|
|
|
21639
22742
|
Examples:
|
|
21640
|
-
deepline monitors
|
|
21641
|
-
deepline monitors
|
|
21642
|
-
deepline monitors
|
|
22743
|
+
deepline monitors check '{"key":"my-monitor","tool":"theirstack.saved_search_webhook","payload":{}}'
|
|
22744
|
+
deepline monitors check --file monitor.json
|
|
22745
|
+
cat monitor.json | deepline monitors check --file -
|
|
21643
22746
|
`
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
|
|
22747
|
+
).option(
|
|
22748
|
+
"-f, --file <path>",
|
|
22749
|
+
"Read the definition JSON from a file, or - for stdin"
|
|
22750
|
+
)
|
|
22751
|
+
).action(monitorsAction(handleMonitorsCheck));
|
|
22752
|
+
withJsonOption(
|
|
22753
|
+
monitors.command("deploy [definition]").description("Deploy a monitor from a definition.").addHelpText(
|
|
22754
|
+
"after",
|
|
22755
|
+
`
|
|
21648
22756
|
Notes:
|
|
21649
|
-
|
|
22757
|
+
Mutates workspace state and may spend Deepline credits. <definition> is a JSON
|
|
22758
|
+
object with key, tool, payload, and optional controls (e.g.
|
|
22759
|
+
"controls":{"enabled":false}). Pass it positionally, via --file <path>, or
|
|
22760
|
+
from stdin with --file -.
|
|
22761
|
+
--dry-run validates the definition and shows the plan (deploy cost in Deepline
|
|
22762
|
+
credits when the server reports it, plus any existing monitors that may
|
|
22763
|
+
already cover this scope) WITHOUT deploying. Exits 0 when valid, 7 when not.
|
|
21650
22764
|
|
|
21651
22765
|
Examples:
|
|
21652
|
-
deepline monitors
|
|
22766
|
+
deepline monitors deploy '{"key":"my-monitor","tool":"theirstack.saved_search_webhook","payload":{}}'
|
|
22767
|
+
deepline monitors deploy --dry-run --file monitor.json
|
|
22768
|
+
deepline monitors deploy --file monitor.json
|
|
21653
22769
|
`
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
22770
|
+
).option(
|
|
22771
|
+
"-f, --file <path>",
|
|
22772
|
+
"Read the definition JSON from a file, or - for stdin"
|
|
22773
|
+
).option(
|
|
22774
|
+
"--dry-run",
|
|
22775
|
+
"Validate and show the deploy plan (cost, reuse candidates) without deploying"
|
|
22776
|
+
)
|
|
22777
|
+
).action(monitorsAction(handleMonitorsDeploy));
|
|
22778
|
+
withJsonOption(
|
|
22779
|
+
monitors.command("update <key> [patch]").description("Update a deployed monitor by its public key.").addHelpText(
|
|
22780
|
+
"after",
|
|
22781
|
+
`
|
|
21658
22782
|
Notes:
|
|
21659
|
-
Mutates workspace state. <patch> is a JSON object of fields to update.
|
|
22783
|
+
Mutates workspace state. <patch> is a JSON object of fields to update, e.g.
|
|
22784
|
+
'{"controls":{"enabled":false}}' to disable a monitor. Pass it positionally,
|
|
22785
|
+
via --file <path>, or from stdin with --file -.
|
|
21660
22786
|
|
|
21661
22787
|
Examples:
|
|
21662
|
-
deepline monitors
|
|
22788
|
+
deepline monitors update my-monitor '{"controls":{"enabled":false}}' --json
|
|
22789
|
+
deepline monitors update my-monitor --file patch.json
|
|
21663
22790
|
`
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
22791
|
+
).option(
|
|
22792
|
+
"-f, --file <path>",
|
|
22793
|
+
"Read the patch JSON from a file, or - for stdin"
|
|
22794
|
+
)
|
|
22795
|
+
).action(monitorsAction(handleMonitorsUpdate));
|
|
22796
|
+
withJsonOption(
|
|
22797
|
+
monitors.command("delete <key>").description("Delete a deployed monitor by its public key.").addHelpText(
|
|
22798
|
+
"after",
|
|
22799
|
+
`
|
|
21668
22800
|
Notes:
|
|
21669
|
-
|
|
21670
|
-
|
|
22801
|
+
DESTRUCTIVE. By default deprovisions the upstream provider resource; pass
|
|
22802
|
+
--local-only to remove only the Deepline-managed record.
|
|
22803
|
+
--dry-run shows the delete plan without deleting anything.
|
|
22804
|
+
Interactive terminals get a y/N confirmation; non-interactive runs (agents,
|
|
22805
|
+
scripts, pipes) must pass --yes.
|
|
21671
22806
|
|
|
21672
22807
|
Examples:
|
|
21673
|
-
deepline monitors
|
|
21674
|
-
deepline monitors
|
|
22808
|
+
deepline monitors delete my-monitor --dry-run
|
|
22809
|
+
deepline monitors delete my-monitor --yes --json
|
|
22810
|
+
deepline monitors delete my-monitor --local-only --yes --json
|
|
21675
22811
|
`
|
|
21676
|
-
|
|
21677
|
-
|
|
21678
|
-
|
|
21679
|
-
|
|
22812
|
+
).option(
|
|
22813
|
+
"--local-only",
|
|
22814
|
+
"Remove only the Deepline-managed record, leaving the upstream resource"
|
|
22815
|
+
).option("--dry-run", "Show the delete plan without deleting anything").option(
|
|
22816
|
+
"--yes",
|
|
22817
|
+
"Skip the confirmation prompt (required non-interactively)"
|
|
22818
|
+
)
|
|
22819
|
+
).action(monitorsAction(handleMonitorsDelete));
|
|
22820
|
+
withJsonOption(
|
|
22821
|
+
monitors.command("reactivate <key>").description("Reactivate a previously disabled deployed monitor.").addHelpText(
|
|
22822
|
+
"after",
|
|
22823
|
+
`
|
|
22824
|
+
Notes:
|
|
22825
|
+
Mutates workspace state and may spend Deepline credits.
|
|
22826
|
+
--dry-run shows the reactivation cost (in Deepline credits) without changing
|
|
22827
|
+
anything.
|
|
22828
|
+
|
|
22829
|
+
Examples:
|
|
22830
|
+
deepline monitors reactivate my-monitor --dry-run
|
|
22831
|
+
deepline monitors reactivate my-monitor --json
|
|
22832
|
+
`
|
|
22833
|
+
).option("--dry-run", "Show the reactivation cost without reactivating")
|
|
22834
|
+
).action(monitorsAction(handleMonitorsReactivate));
|
|
22835
|
+
const deployed = withJsonOption(
|
|
22836
|
+
monitors.command("deployed", { hidden: true }).description("Alias of `monitors list` (plus get/update/delete aliases).").option(
|
|
22837
|
+
"--status <status>",
|
|
22838
|
+
"Filter by monitor status: active (default), disabled, or all"
|
|
22839
|
+
).option("--limit <n>", "Limit the number of deployed monitors returned").option("--compact", COMPACT_OPTION_DESCRIPTION)
|
|
22840
|
+
).action(monitorsAction(handleMonitorsList));
|
|
22841
|
+
withJsonOption(
|
|
22842
|
+
deployed.command("get <key>").description("Alias of `monitors get <key>`.")
|
|
22843
|
+
).action(monitorsAction(handleMonitorsGet));
|
|
22844
|
+
withJsonOption(
|
|
22845
|
+
deployed.command("update <key> [patch]").description("Alias of `monitors update <key>`.").option(
|
|
22846
|
+
"-f, --file <path>",
|
|
22847
|
+
"Read the patch JSON from a file, or - for stdin"
|
|
22848
|
+
)
|
|
22849
|
+
).action(monitorsAction(handleMonitorsUpdate));
|
|
22850
|
+
withJsonOption(
|
|
22851
|
+
deployed.command("delete <key>").description("Alias of `monitors delete <key>`.").option(
|
|
22852
|
+
"--local-only",
|
|
22853
|
+
"Remove only the Deepline-managed record, leaving the upstream resource"
|
|
22854
|
+
).option("--dry-run", "Show the delete plan without deleting anything").option(
|
|
22855
|
+
"--yes",
|
|
22856
|
+
"Skip the confirmation prompt (required non-interactively)"
|
|
22857
|
+
)
|
|
22858
|
+
).action(monitorsAction(handleMonitorsDelete));
|
|
21680
22859
|
}
|
|
21681
22860
|
|
|
21682
22861
|
// src/cli/commands/org.ts
|
|
@@ -22701,7 +23880,7 @@ Examples:
|
|
|
22701
23880
|
}
|
|
22702
23881
|
|
|
22703
23882
|
// src/cli/commands/switch.ts
|
|
22704
|
-
var
|
|
23883
|
+
var import_node_fs13 = require("fs");
|
|
22705
23884
|
var import_node_os10 = require("os");
|
|
22706
23885
|
var import_node_path14 = require("path");
|
|
22707
23886
|
function hostSlugFromBaseUrl(baseUrl) {
|
|
@@ -22736,15 +23915,15 @@ function activeFamilyPath() {
|
|
|
22736
23915
|
function readActiveFamily() {
|
|
22737
23916
|
const path = activeFamilyPath();
|
|
22738
23917
|
try {
|
|
22739
|
-
return (0,
|
|
23918
|
+
return (0, import_node_fs13.readFileSync)(path, "utf-8").trim() || "sdk";
|
|
22740
23919
|
} catch {
|
|
22741
23920
|
return "sdk";
|
|
22742
23921
|
}
|
|
22743
23922
|
}
|
|
22744
23923
|
function writeActiveFamily(family) {
|
|
22745
23924
|
const path = activeFamilyPath();
|
|
22746
|
-
(0,
|
|
22747
|
-
(0,
|
|
23925
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path14.dirname)(path), { recursive: true });
|
|
23926
|
+
(0, import_node_fs13.writeFileSync)(path, `${family}
|
|
22748
23927
|
`, "utf-8");
|
|
22749
23928
|
return path;
|
|
22750
23929
|
}
|
|
@@ -22761,7 +23940,7 @@ function handleSwitch(action, options) {
|
|
|
22761
23940
|
ok: true,
|
|
22762
23941
|
active_family: activeFamily,
|
|
22763
23942
|
active_family_path: path,
|
|
22764
|
-
active_family_file_exists: (0,
|
|
23943
|
+
active_family_file_exists: (0, import_node_fs13.existsSync)(path),
|
|
22765
23944
|
render: {
|
|
22766
23945
|
sections: [
|
|
22767
23946
|
{
|
|
@@ -22861,12 +24040,12 @@ Examples:
|
|
|
22861
24040
|
|
|
22862
24041
|
// src/cli/commands/tools.ts
|
|
22863
24042
|
var import_commander2 = require("commander");
|
|
22864
|
-
var
|
|
24043
|
+
var import_node_fs15 = require("fs");
|
|
22865
24044
|
var import_node_os12 = require("os");
|
|
22866
24045
|
var import_node_path16 = require("path");
|
|
22867
24046
|
|
|
22868
24047
|
// src/tool-output.ts
|
|
22869
|
-
var
|
|
24048
|
+
var import_node_fs14 = require("fs");
|
|
22870
24049
|
var import_node_os11 = require("os");
|
|
22871
24050
|
var import_node_path15 = require("path");
|
|
22872
24051
|
function isPlainObject(value) {
|
|
@@ -22996,18 +24175,18 @@ function projectRowOutput(conversion) {
|
|
|
22996
24175
|
}
|
|
22997
24176
|
function ensureOutputDir() {
|
|
22998
24177
|
const outputDir = (0, import_node_path15.join)((0, import_node_os11.homedir)(), ".local", "share", "deepline", "data");
|
|
22999
|
-
(0,
|
|
24178
|
+
(0, import_node_fs14.mkdirSync)(outputDir, { recursive: true });
|
|
23000
24179
|
return outputDir;
|
|
23001
24180
|
}
|
|
23002
24181
|
function writeJsonOutputFile(payload, stem) {
|
|
23003
24182
|
const outputDir = ensureOutputDir();
|
|
23004
24183
|
const outputPath = (0, import_node_path15.join)(outputDir, `${stem}_${Date.now()}.json`);
|
|
23005
|
-
(0,
|
|
24184
|
+
(0, import_node_fs14.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
23006
24185
|
return outputPath;
|
|
23007
24186
|
}
|
|
23008
24187
|
function writeCsvOutputFile(rows, stem, options) {
|
|
23009
24188
|
const outputPath = options?.outPath ? options.outPath : (0, import_node_path15.join)(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
|
|
23010
|
-
(0,
|
|
24189
|
+
(0, import_node_fs14.mkdirSync)((0, import_node_path15.dirname)(outputPath), { recursive: true });
|
|
23011
24190
|
const columns = columnsForRows(rows);
|
|
23012
24191
|
const escapeCell = (value) => {
|
|
23013
24192
|
const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
|
|
@@ -23016,19 +24195,19 @@ function writeCsvOutputFile(rows, stem, options) {
|
|
|
23016
24195
|
}
|
|
23017
24196
|
return normalized;
|
|
23018
24197
|
};
|
|
23019
|
-
const fd = (0,
|
|
24198
|
+
const fd = (0, import_node_fs14.openSync)(outputPath, "w");
|
|
23020
24199
|
try {
|
|
23021
|
-
(0,
|
|
24200
|
+
(0, import_node_fs14.writeSync)(fd, `${columns.map(escapeCell).join(",")}
|
|
23022
24201
|
`);
|
|
23023
24202
|
for (const row of rows) {
|
|
23024
|
-
(0,
|
|
24203
|
+
(0, import_node_fs14.writeSync)(
|
|
23025
24204
|
fd,
|
|
23026
24205
|
`${columns.map((column) => escapeCell(row[column])).join(",")}
|
|
23027
24206
|
`
|
|
23028
24207
|
);
|
|
23029
24208
|
}
|
|
23030
24209
|
} finally {
|
|
23031
|
-
(0,
|
|
24210
|
+
(0, import_node_fs14.closeSync)(fd);
|
|
23032
24211
|
}
|
|
23033
24212
|
const previewRows = rows.slice(0, 5);
|
|
23034
24213
|
const previewColumns = columns.slice(0, 5);
|
|
@@ -24242,10 +25421,10 @@ function normalizeOutputFormat(raw) {
|
|
|
24242
25421
|
function resolveAtFilePath(rawPath) {
|
|
24243
25422
|
const trimmed = rawPath.trim();
|
|
24244
25423
|
const resolved = (0, import_node_path16.resolve)(trimmed);
|
|
24245
|
-
if ((0,
|
|
25424
|
+
if ((0, import_node_fs15.existsSync)(resolved)) return resolved;
|
|
24246
25425
|
if (process.platform !== "win32" && trimmed.includes("\\")) {
|
|
24247
25426
|
const normalized = (0, import_node_path16.resolve)(trimmed.replace(/\\/g, "/"));
|
|
24248
|
-
if ((0,
|
|
25427
|
+
if ((0, import_node_fs15.existsSync)(normalized)) return normalized;
|
|
24249
25428
|
}
|
|
24250
25429
|
return resolved;
|
|
24251
25430
|
}
|
|
@@ -24256,7 +25435,7 @@ function readJsonArgument(raw, flagName) {
|
|
|
24256
25435
|
throw new Error(`Invalid ${flagName} value: empty @file path.`);
|
|
24257
25436
|
}
|
|
24258
25437
|
try {
|
|
24259
|
-
return (0,
|
|
25438
|
+
return (0, import_node_fs15.readFileSync)(resolveAtFilePath(filePath), "utf8").replace(
|
|
24260
25439
|
/^\uFEFF/,
|
|
24261
25440
|
""
|
|
24262
25441
|
);
|
|
@@ -24363,8 +25542,8 @@ function starterScriptJson(script) {
|
|
|
24363
25542
|
function seedToolListScript(input2) {
|
|
24364
25543
|
const stem = safeFileStem(input2.toolId);
|
|
24365
25544
|
const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
|
|
24366
|
-
const scriptDir = (0,
|
|
24367
|
-
(0,
|
|
25545
|
+
const scriptDir = (0, import_node_fs15.mkdtempSync)((0, import_node_path16.join)((0, import_node_os12.tmpdir)(), "deepline-workflow-seed-"));
|
|
25546
|
+
(0, import_node_fs15.chmodSync)(scriptDir, 448);
|
|
24368
25547
|
const scriptPath = (0, import_node_path16.join)(scriptDir, fileName);
|
|
24369
25548
|
const projectDir = `deepline/projects/${stem}-workflow`;
|
|
24370
25549
|
const playName = `${stem}-workflow`;
|
|
@@ -24408,7 +25587,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
|
|
|
24408
25587
|
description: ${JSON.stringify(`Seed ${input2.toolId} rows into a Deepline workflow-ready dataset.`)},
|
|
24409
25588
|
});
|
|
24410
25589
|
`;
|
|
24411
|
-
(0,
|
|
25590
|
+
(0, import_node_fs15.writeFileSync)(scriptPath, script, { encoding: "utf-8", mode: 384 });
|
|
24412
25591
|
return {
|
|
24413
25592
|
path: scriptPath,
|
|
24414
25593
|
sourceCode: script,
|
|
@@ -24738,7 +25917,7 @@ async function executeTool(args) {
|
|
|
24738
25917
|
}
|
|
24739
25918
|
|
|
24740
25919
|
// src/cli/commands/workflow.ts
|
|
24741
|
-
var
|
|
25920
|
+
var import_promises5 = require("fs/promises");
|
|
24742
25921
|
var import_node_path17 = require("path");
|
|
24743
25922
|
|
|
24744
25923
|
// src/cli/workflow-to-play.ts
|
|
@@ -24926,9 +26105,10 @@ var PLAY_EQUIVALENT = {
|
|
|
24926
26105
|
delete: "deepline plays delete <name>"
|
|
24927
26106
|
};
|
|
24928
26107
|
var MIGRATE_HINT = "deepline workflows transform <id>";
|
|
24929
|
-
var
|
|
24930
|
-
|
|
24931
|
-
|
|
26108
|
+
var TRIGGER_REDIRECT = "Looking to trigger a play automatically? Use a trigger binding in definePlay \u2014 `cron`/`webhook`, or `sqlListeners` to run on a monitor\u2019s output (see `deepline monitors available <id>` for a monitor\u2019s streams and the deepline-monitors skill). `workflows` only manages prebuilt plays and is deprecated in favor of `plays`.";
|
|
26109
|
+
var JSON_OPTION_DESCRIPTION2 = "Emit JSON output. Also automatic when stdout is piped";
|
|
26110
|
+
function withJsonOption2(command) {
|
|
26111
|
+
return command.option("--json", JSON_OPTION_DESCRIPTION2);
|
|
24932
26112
|
}
|
|
24933
26113
|
var TERMINAL_RUN_STATUSES = /* @__PURE__ */ new Set([
|
|
24934
26114
|
"completed",
|
|
@@ -24953,6 +26133,7 @@ function noticeToStderr(command) {
|
|
|
24953
26133
|
`note: \`deepline workflows ${command}\` is a legacy surface \u2014 workflows are becoming plays.
|
|
24954
26134
|
equivalent: \`${deprecation.use}\`
|
|
24955
26135
|
migrate this workflow: \`${MIGRATE_HINT}\`
|
|
26136
|
+
${TRIGGER_REDIRECT}
|
|
24956
26137
|
`
|
|
24957
26138
|
);
|
|
24958
26139
|
}
|
|
@@ -24983,7 +26164,7 @@ function readStatus(payload) {
|
|
|
24983
26164
|
}
|
|
24984
26165
|
async function readJsonOption(payload, file) {
|
|
24985
26166
|
if (file) {
|
|
24986
|
-
const raw = await (0,
|
|
26167
|
+
const raw = await (0, import_promises5.readFile)((0, import_node_path17.resolve)(file), "utf8");
|
|
24987
26168
|
return JSON.parse(raw);
|
|
24988
26169
|
}
|
|
24989
26170
|
if (payload) {
|
|
@@ -25018,8 +26199,8 @@ async function transformOne(api, workflowId, outDir, publish) {
|
|
|
25018
26199
|
{ workflowName: workflow.name, version: revision.version }
|
|
25019
26200
|
);
|
|
25020
26201
|
const file = (0, import_node_path17.join)((0, import_node_path17.resolve)(outDir), `${compiled.playName}.play.ts`);
|
|
25021
|
-
await (0,
|
|
25022
|
-
await (0,
|
|
26202
|
+
await (0, import_promises5.mkdir)((0, import_node_path17.dirname)(file), { recursive: true });
|
|
26203
|
+
await (0, import_promises5.writeFile)(file, compiled.sourceCode, "utf8");
|
|
25023
26204
|
let published = false;
|
|
25024
26205
|
if (publish) {
|
|
25025
26206
|
const code = await handlePlayPublish([file]);
|
|
@@ -25186,7 +26367,7 @@ async function handleTail(id, runId, options) {
|
|
|
25186
26367
|
}
|
|
25187
26368
|
function registerWorkflowCommands(program) {
|
|
25188
26369
|
const workflows = program.command("workflows").description(
|
|
25189
|
-
"Legacy cloud workflows (now becoming plays). Commands still work; use `workflows transform` to migrate one to a play."
|
|
26370
|
+
"Legacy cloud workflows (now becoming plays). Commands still work; use `workflows transform` to migrate one to a play. " + TRIGGER_REDIRECT
|
|
25190
26371
|
).addHelpText(
|
|
25191
26372
|
"after",
|
|
25192
26373
|
`
|
|
@@ -25198,9 +26379,13 @@ keep working, but new work belongs in plays. Migrate a workflow with:
|
|
|
25198
26379
|
|
|
25199
26380
|
Equivalents: list\u2192plays list \xB7 call\u2192plays run \xB7 apply\u2192plays publish \xB7
|
|
25200
26381
|
lint\u2192plays check \xB7 runs\u2192runs list.
|
|
26382
|
+
|
|
26383
|
+
${TRIGGER_REDIRECT}
|
|
26384
|
+
Add the binding as the third arg to definePlay in your .play.ts; the
|
|
26385
|
+
deepline-monitors skill has a monitor-triggered example.
|
|
25201
26386
|
`
|
|
25202
26387
|
);
|
|
25203
|
-
|
|
26388
|
+
withJsonOption2(
|
|
25204
26389
|
workflows.command("transform [id]").description("Compile a workflow into a reviewable V2 play (.play.ts).").option("--all", "Transform every workflow in the workspace").option("--out <dir>", "Output directory for generated plays", "./plays").option("--publish", "Publish each clean play immediately")
|
|
25205
26390
|
).addHelpText(
|
|
25206
26391
|
"after",
|
|
@@ -25217,61 +26402,61 @@ Notes:
|
|
|
25217
26402
|
).action(async (id, options) => {
|
|
25218
26403
|
process.exitCode = await handleTransform(id, options);
|
|
25219
26404
|
});
|
|
25220
|
-
|
|
26405
|
+
withJsonOption2(
|
|
25221
26406
|
workflows.command("list").description("List workspace workflows.").option("--limit <n>", "Max workflows to return")
|
|
25222
26407
|
).action(handleList2);
|
|
25223
|
-
|
|
26408
|
+
withJsonOption2(
|
|
25224
26409
|
workflows.command("get <id>").description(
|
|
25225
26410
|
"Fetch a workflow, including its published-revision config."
|
|
25226
26411
|
)
|
|
25227
26412
|
).action(handleGet);
|
|
25228
|
-
|
|
26413
|
+
withJsonOption2(
|
|
25229
26414
|
workflows.command("disable <id>").description("Turn a workflow off.")
|
|
25230
26415
|
).action(handleDisable);
|
|
25231
|
-
|
|
26416
|
+
withJsonOption2(
|
|
25232
26417
|
workflows.command("enable <id>").description("Turn a workflow back on.")
|
|
25233
26418
|
).action(handleEnable);
|
|
25234
|
-
|
|
26419
|
+
withJsonOption2(
|
|
25235
26420
|
workflows.command("delete <id>").description("Delete a workflow and its revisions/runs.")
|
|
25236
26421
|
).action(handleDelete);
|
|
25237
|
-
|
|
26422
|
+
withJsonOption2(
|
|
25238
26423
|
workflows.command("apply").description("Create or update a workflow from config.").option("--payload <json>", "Inline config JSON").option("--file <path>", "Path to a config JSON file")
|
|
25239
26424
|
).action(handleApply);
|
|
25240
|
-
|
|
26425
|
+
withJsonOption2(
|
|
25241
26426
|
workflows.command("lint").description("Validate a workflow config without saving.").option("--payload <json>", "Inline config JSON").option("--file <path>", "Path to a config JSON file")
|
|
25242
26427
|
).action(handleLint);
|
|
25243
|
-
|
|
26428
|
+
withJsonOption2(
|
|
25244
26429
|
workflows.command("schema").description("Fetch live workflow request schemas.").option(
|
|
25245
26430
|
"--subject <subject>",
|
|
25246
26431
|
"Schema subject (apply|call|trigger|all|\u2026)"
|
|
25247
26432
|
)
|
|
25248
26433
|
).action(handleSchema);
|
|
25249
|
-
|
|
26434
|
+
withJsonOption2(
|
|
25250
26435
|
workflows.command("call").description("Queue a workflow run.").option("--workflow-id <id>", "Workflow id").option("--workflow-name <name>", "Workflow name").option("--payload <json>", "Run input JSON").option("--mode <mode>", "live | dry_run | smoke_test")
|
|
25251
26436
|
).action(handleCall);
|
|
25252
|
-
|
|
26437
|
+
withJsonOption2(
|
|
25253
26438
|
workflows.command("runs <id>").description("List a workflow\u2019s runs.").option("--limit <n>", "Max runs to return")
|
|
25254
26439
|
).action(handleRuns);
|
|
25255
|
-
|
|
26440
|
+
withJsonOption2(
|
|
25256
26441
|
workflows.command("run <id> <runId>").description("Fetch a single workflow run.")
|
|
25257
26442
|
).action(handleRun);
|
|
25258
|
-
|
|
26443
|
+
withJsonOption2(
|
|
25259
26444
|
workflows.command("tail <id> <runId>").description("Poll a workflow run until it reaches a terminal status.").option("--interval-ms <n>", "Poll interval in ms (default 2000)")
|
|
25260
26445
|
).action(handleTail);
|
|
25261
|
-
|
|
26446
|
+
withJsonOption2(
|
|
25262
26447
|
workflows.command("cancel <id> <runId>").description("Cancel a running workflow run.")
|
|
25263
26448
|
).action(handleCancel);
|
|
25264
26449
|
}
|
|
25265
26450
|
|
|
25266
26451
|
// src/cli/commands/update.ts
|
|
25267
26452
|
var import_node_child_process4 = require("child_process");
|
|
25268
|
-
var
|
|
26453
|
+
var import_node_fs17 = require("fs");
|
|
25269
26454
|
var import_node_os13 = require("os");
|
|
25270
26455
|
var import_node_path19 = require("path");
|
|
25271
26456
|
|
|
25272
26457
|
// src/cli/skills-sync.ts
|
|
25273
26458
|
var import_node_child_process3 = require("child_process");
|
|
25274
|
-
var
|
|
26459
|
+
var import_node_fs16 = require("fs");
|
|
25275
26460
|
var import_node_path18 = require("path");
|
|
25276
26461
|
|
|
25277
26462
|
// ../shared_libs/cli/install-commands.json
|
|
@@ -25394,13 +26579,13 @@ function activePluginSkillsDir() {
|
|
|
25394
26579
|
return "";
|
|
25395
26580
|
}
|
|
25396
26581
|
const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
|
|
25397
|
-
return dir && (0,
|
|
26582
|
+
return dir && (0, import_node_fs16.existsSync)(dir) ? dir : "";
|
|
25398
26583
|
}
|
|
25399
26584
|
function readPluginSkillsVersion() {
|
|
25400
26585
|
const dir = activePluginSkillsDir();
|
|
25401
26586
|
if (!dir) return "";
|
|
25402
26587
|
try {
|
|
25403
|
-
return (0,
|
|
26588
|
+
return (0, import_node_fs16.readFileSync)((0, import_node_path18.join)(dir, ".version"), "utf-8").trim();
|
|
25404
26589
|
} catch {
|
|
25405
26590
|
return "";
|
|
25406
26591
|
}
|
|
@@ -25414,18 +26599,18 @@ function legacySdkSkillsVersionPath(baseUrl) {
|
|
|
25414
26599
|
function readSdkSkillsLocalVersion(baseUrl) {
|
|
25415
26600
|
const pluginVersion = readPluginSkillsVersion();
|
|
25416
26601
|
if (pluginVersion) return pluginVersion;
|
|
25417
|
-
const path = (0,
|
|
25418
|
-
if (!(0,
|
|
26602
|
+
const path = (0, import_node_fs16.existsSync)(sdkSkillsVersionPath(baseUrl)) ? sdkSkillsVersionPath(baseUrl) : legacySdkSkillsVersionPath(baseUrl);
|
|
26603
|
+
if (!(0, import_node_fs16.existsSync)(path)) return "";
|
|
25419
26604
|
try {
|
|
25420
|
-
return (0,
|
|
26605
|
+
return (0, import_node_fs16.readFileSync)(path, "utf-8").trim();
|
|
25421
26606
|
} catch {
|
|
25422
26607
|
return "";
|
|
25423
26608
|
}
|
|
25424
26609
|
}
|
|
25425
26610
|
function writeLocalSkillsVersion(baseUrl, version) {
|
|
25426
26611
|
const path = sdkSkillsVersionPath(baseUrl);
|
|
25427
|
-
(0,
|
|
25428
|
-
(0,
|
|
26612
|
+
(0, import_node_fs16.mkdirSync)((0, import_node_path18.dirname)(path), { recursive: true });
|
|
26613
|
+
(0, import_node_fs16.writeFileSync)(path, `${version}
|
|
25429
26614
|
`, "utf-8");
|
|
25430
26615
|
}
|
|
25431
26616
|
function sortedUniqueSkillNames(names) {
|
|
@@ -25712,7 +26897,7 @@ function sidecarStateDir(input2) {
|
|
|
25712
26897
|
}
|
|
25713
26898
|
function readOptionalText(path) {
|
|
25714
26899
|
try {
|
|
25715
|
-
return (0,
|
|
26900
|
+
return (0, import_node_fs17.readFileSync)(path, "utf8").trim();
|
|
25716
26901
|
} catch {
|
|
25717
26902
|
return "";
|
|
25718
26903
|
}
|
|
@@ -25756,7 +26941,7 @@ function resolvePythonSidecarUpdatePlan(options) {
|
|
|
25756
26941
|
function findRepoBackedSdkRoot(startPath) {
|
|
25757
26942
|
let current = (0, import_node_path19.resolve)(startPath);
|
|
25758
26943
|
while (true) {
|
|
25759
|
-
if ((0,
|
|
26944
|
+
if ((0, import_node_fs17.existsSync)((0, import_node_path19.join)(current, "sdk", "package.json")) && (0, import_node_fs17.existsSync)((0, import_node_path19.join)(current, "sdk", "bin", "deepline-dev.ts"))) {
|
|
25760
26945
|
return current;
|
|
25761
26946
|
}
|
|
25762
26947
|
const parent = (0, import_node_path19.dirname)(current);
|
|
@@ -25767,7 +26952,7 @@ function findRepoBackedSdkRoot(startPath) {
|
|
|
25767
26952
|
function inferNpmGlobalPrefixFromEntrypoint(entrypoint) {
|
|
25768
26953
|
const normalized = (() => {
|
|
25769
26954
|
try {
|
|
25770
|
-
return (0,
|
|
26955
|
+
return (0, import_node_fs17.realpathSync)(entrypoint);
|
|
25771
26956
|
} catch {
|
|
25772
26957
|
return (0, import_node_path19.resolve)(entrypoint);
|
|
25773
26958
|
}
|
|
@@ -25847,7 +27032,7 @@ function readAutoUpdateFailure(plan) {
|
|
|
25847
27032
|
if (!path) return null;
|
|
25848
27033
|
try {
|
|
25849
27034
|
const parsed = JSON.parse(
|
|
25850
|
-
(0,
|
|
27035
|
+
(0, import_node_fs17.readFileSync)(path, "utf8")
|
|
25851
27036
|
);
|
|
25852
27037
|
if ((parsed.kind === "npm-global" || parsed.kind === "python-sidecar") && typeof parsed.packageSpec === "string" && typeof parsed.failedAt === "string" && typeof parsed.exitCode === "number" && typeof parsed.manualCommand === "string") {
|
|
25853
27038
|
return parsed;
|
|
@@ -25868,8 +27053,8 @@ function writeAutoUpdateFailure(plan, exitCode) {
|
|
|
25868
27053
|
manualCommand: plan.manualCommand
|
|
25869
27054
|
};
|
|
25870
27055
|
try {
|
|
25871
|
-
(0,
|
|
25872
|
-
(0,
|
|
27056
|
+
(0, import_node_fs17.mkdirSync)((0, import_node_path19.dirname)(path), { recursive: true });
|
|
27057
|
+
(0, import_node_fs17.writeFileSync)(path, `${JSON.stringify(marker, null, 2)}
|
|
25873
27058
|
`, "utf8");
|
|
25874
27059
|
} catch {
|
|
25875
27060
|
}
|
|
@@ -25878,7 +27063,7 @@ function clearAutoUpdateFailure(plan) {
|
|
|
25878
27063
|
const path = autoUpdateFailurePath(plan);
|
|
25879
27064
|
if (!path) return;
|
|
25880
27065
|
try {
|
|
25881
|
-
(0,
|
|
27066
|
+
(0, import_node_fs17.unlinkSync)(path);
|
|
25882
27067
|
} catch {
|
|
25883
27068
|
}
|
|
25884
27069
|
}
|
|
@@ -25931,7 +27116,7 @@ function installedPackageVersion(versionDir) {
|
|
|
25931
27116
|
"package.json"
|
|
25932
27117
|
);
|
|
25933
27118
|
try {
|
|
25934
|
-
const parsed = JSON.parse((0,
|
|
27119
|
+
const parsed = JSON.parse((0, import_node_fs17.readFileSync)(packageJsonPath, "utf8"));
|
|
25935
27120
|
return typeof parsed.version === "string" ? safeVersionSegment(parsed.version) : "";
|
|
25936
27121
|
} catch {
|
|
25937
27122
|
return "";
|
|
@@ -25963,9 +27148,9 @@ function runCommand(command, args, env = process.env, options = {}) {
|
|
|
25963
27148
|
});
|
|
25964
27149
|
}
|
|
25965
27150
|
function writeSidecarLauncher(input2) {
|
|
25966
|
-
(0,
|
|
27151
|
+
(0, import_node_fs17.mkdirSync)((0, import_node_path19.dirname)(input2.path), { recursive: true });
|
|
25967
27152
|
if (process.platform === "win32") {
|
|
25968
|
-
(0,
|
|
27153
|
+
(0, import_node_fs17.writeFileSync)(
|
|
25969
27154
|
input2.path,
|
|
25970
27155
|
[
|
|
25971
27156
|
`@set DEEPLINE_HOST_URL=${input2.hostUrl.replace(/\r?\n/g, "")}`,
|
|
@@ -25977,7 +27162,7 @@ function writeSidecarLauncher(input2) {
|
|
|
25977
27162
|
);
|
|
25978
27163
|
return;
|
|
25979
27164
|
}
|
|
25980
|
-
(0,
|
|
27165
|
+
(0, import_node_fs17.writeFileSync)(
|
|
25981
27166
|
input2.path,
|
|
25982
27167
|
[
|
|
25983
27168
|
"#!/usr/bin/env sh",
|
|
@@ -25995,9 +27180,9 @@ async function runPythonSidecarUpdatePlan(plan, options = {}) {
|
|
|
25995
27180
|
versionsDir,
|
|
25996
27181
|
`.tmp-sdk-update-${process.pid}-${Date.now()}`
|
|
25997
27182
|
);
|
|
25998
|
-
(0,
|
|
25999
|
-
(0,
|
|
26000
|
-
(0,
|
|
27183
|
+
(0, import_node_fs17.rmSync)(tempDir, { recursive: true, force: true });
|
|
27184
|
+
(0, import_node_fs17.mkdirSync)(tempDir, { recursive: true });
|
|
27185
|
+
(0, import_node_fs17.writeFileSync)((0, import_node_path19.join)(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
|
|
26001
27186
|
const env = {
|
|
26002
27187
|
...process.env,
|
|
26003
27188
|
PATH: `${(0, import_node_path19.dirname)(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
|
|
@@ -26015,7 +27200,7 @@ async function runPythonSidecarUpdatePlan(plan, options = {}) {
|
|
|
26015
27200
|
options
|
|
26016
27201
|
);
|
|
26017
27202
|
if (installExitCode !== 0) {
|
|
26018
|
-
(0,
|
|
27203
|
+
(0, import_node_fs17.rmSync)(tempDir, { recursive: true, force: true });
|
|
26019
27204
|
return installExitCode;
|
|
26020
27205
|
}
|
|
26021
27206
|
const installedVersion = installedPackageVersion(tempDir);
|
|
@@ -26023,19 +27208,19 @@ async function runPythonSidecarUpdatePlan(plan, options = {}) {
|
|
|
26023
27208
|
process.stderr.write(
|
|
26024
27209
|
"Updated Deepline SDK package did not report a version.\n"
|
|
26025
27210
|
);
|
|
26026
|
-
(0,
|
|
27211
|
+
(0, import_node_fs17.rmSync)(tempDir, { recursive: true, force: true });
|
|
26027
27212
|
return 1;
|
|
26028
27213
|
}
|
|
26029
27214
|
const finalDir = (0, import_node_path19.join)(versionsDir, installedVersion);
|
|
26030
27215
|
const finalEntryPath = entryPathInVersionDir(finalDir);
|
|
26031
|
-
if ((0,
|
|
26032
|
-
(0,
|
|
27216
|
+
if ((0, import_node_fs17.existsSync)(finalEntryPath)) {
|
|
27217
|
+
(0, import_node_fs17.rmSync)(tempDir, { recursive: true, force: true });
|
|
26033
27218
|
} else {
|
|
26034
|
-
(0,
|
|
27219
|
+
(0, import_node_fs17.rmSync)(finalDir, { recursive: true, force: true });
|
|
26035
27220
|
try {
|
|
26036
|
-
(0,
|
|
27221
|
+
(0, import_node_fs17.renameSync)(tempDir, finalDir);
|
|
26037
27222
|
} catch (error) {
|
|
26038
|
-
(0,
|
|
27223
|
+
(0, import_node_fs17.rmSync)(tempDir, { recursive: true, force: true });
|
|
26039
27224
|
process.stderr.write(
|
|
26040
27225
|
`Failed to publish Deepline SDK sidecar update: ${error.message}
|
|
26041
27226
|
`
|
|
@@ -26043,7 +27228,7 @@ async function runPythonSidecarUpdatePlan(plan, options = {}) {
|
|
|
26043
27228
|
return 1;
|
|
26044
27229
|
}
|
|
26045
27230
|
}
|
|
26046
|
-
if (!(0,
|
|
27231
|
+
if (!(0, import_node_fs17.existsSync)(finalEntryPath)) {
|
|
26047
27232
|
process.stderr.write(
|
|
26048
27233
|
`Updated Deepline SDK CLI entrypoint missing: ${finalEntryPath}
|
|
26049
27234
|
`
|
|
@@ -26057,27 +27242,27 @@ async function runPythonSidecarUpdatePlan(plan, options = {}) {
|
|
|
26057
27242
|
nodeBin: plan.nodeBin,
|
|
26058
27243
|
entryPath: finalEntryPath
|
|
26059
27244
|
});
|
|
26060
|
-
(0,
|
|
27245
|
+
(0, import_node_fs17.writeFileSync)(
|
|
26061
27246
|
(0, import_node_path19.join)(plan.stateDir, ".version"),
|
|
26062
27247
|
`${installedVersion}
|
|
26063
27248
|
`,
|
|
26064
27249
|
"utf8"
|
|
26065
27250
|
);
|
|
26066
|
-
(0,
|
|
27251
|
+
(0, import_node_fs17.writeFileSync)(
|
|
26067
27252
|
(0, import_node_path19.join)(plan.stateDir, ".install-method"),
|
|
26068
27253
|
"python-sidecar\n",
|
|
26069
27254
|
"utf8"
|
|
26070
27255
|
);
|
|
26071
|
-
(0,
|
|
27256
|
+
(0, import_node_fs17.writeFileSync)(
|
|
26072
27257
|
(0, import_node_path19.join)(plan.stateDir, ".command-path"),
|
|
26073
27258
|
`${plan.sidecarPath}
|
|
26074
27259
|
`,
|
|
26075
27260
|
"utf8"
|
|
26076
27261
|
);
|
|
26077
|
-
(0,
|
|
26078
|
-
(0,
|
|
27262
|
+
(0, import_node_fs17.writeFileSync)((0, import_node_path19.join)(plan.stateDir, ".runner"), "node\n", "utf8");
|
|
27263
|
+
(0, import_node_fs17.writeFileSync)((0, import_node_path19.join)(plan.stateDir, ".node-bin"), `${plan.nodeBin}
|
|
26079
27264
|
`, "utf8");
|
|
26080
|
-
(0,
|
|
27265
|
+
(0, import_node_fs17.writeFileSync)(
|
|
26081
27266
|
(0, import_node_path19.join)(plan.stateDir, ".entry-path"),
|
|
26082
27267
|
`${finalEntryPath}
|
|
26083
27268
|
`,
|
|
@@ -26681,10 +27866,10 @@ function topLevelCommandKnown(program, commandName) {
|
|
|
26681
27866
|
);
|
|
26682
27867
|
}
|
|
26683
27868
|
async function runPlayRunnerHealthCheck() {
|
|
26684
|
-
const dir = await (0,
|
|
27869
|
+
const dir = await (0, import_promises6.mkdtemp)((0, import_node_path20.join)((0, import_node_os15.tmpdir)(), "deepline-health-play-"));
|
|
26685
27870
|
const file = (0, import_node_path20.join)(dir, "health-check.play.ts");
|
|
26686
27871
|
try {
|
|
26687
|
-
await (0,
|
|
27872
|
+
await (0, import_promises6.writeFile)(
|
|
26688
27873
|
file,
|
|
26689
27874
|
[
|
|
26690
27875
|
"import { definePlay } from 'deepline';",
|
|
@@ -26734,7 +27919,7 @@ async function runPlayRunnerHealthCheck() {
|
|
|
26734
27919
|
}
|
|
26735
27920
|
};
|
|
26736
27921
|
} finally {
|
|
26737
|
-
await (0,
|
|
27922
|
+
await (0, import_promises6.rm)(dir, { recursive: true, force: true });
|
|
26738
27923
|
}
|
|
26739
27924
|
}
|
|
26740
27925
|
function pickString(value, ...keys) {
|