dataiku-sdk 3.6.1 → 3.7.0

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.
Files changed (127) hide show
  1. package/README.md +14 -6
  2. package/bin/bun-version.js +14 -0
  3. package/bin/dss.js +11 -15
  4. package/dist/build-metadata.json +1 -1
  5. package/dist/packages/types/src/index.d.ts +74 -1
  6. package/dist/packages/types/src/index.js +53 -1
  7. package/dist/src/cli/coerce.d.ts +1 -0
  8. package/dist/src/cli/coerce.js +19 -15
  9. package/dist/src/cli/command-syntax.json +3521 -416
  10. package/dist/src/cli/commands/analysis.js +19 -1
  11. package/dist/src/cli/commands/bundle.js +22 -0
  12. package/dist/src/cli/commands/connection.js +26 -2
  13. package/dist/src/cli/commands/data-quality.js +33 -1
  14. package/dist/src/cli/commands/dataset.js +35 -4
  15. package/dist/src/cli/commands/discussion.js +15 -0
  16. package/dist/src/cli/commands/doctor.js +1 -1
  17. package/dist/src/cli/commands/flow.d.ts +5 -0
  18. package/dist/src/cli/commands/flow.js +57 -0
  19. package/dist/src/cli/commands/future.js +8 -0
  20. package/dist/src/cli/commands/index.js +6 -0
  21. package/dist/src/cli/commands/job.js +29 -6
  22. package/dist/src/cli/commands/metrics.js +21 -1
  23. package/dist/src/cli/commands/ml-task.d.ts +5 -0
  24. package/dist/src/cli/commands/ml-task.js +86 -16
  25. package/dist/src/cli/commands/mlflow.d.ts +11 -0
  26. package/dist/src/cli/commands/mlflow.js +121 -0
  27. package/dist/src/cli/commands/plugin.js +5 -11
  28. package/dist/src/cli/commands/project-deployer.js +70 -0
  29. package/dist/src/cli/commands/project-library.js +2 -5
  30. package/dist/src/cli/commands/project.js +8 -0
  31. package/dist/src/cli/commands/recipe.d.ts +9 -0
  32. package/dist/src/cli/commands/recipe.js +93 -7
  33. package/dist/src/cli/commands/saved-model.d.ts +1 -1
  34. package/dist/src/cli/commands/saved-model.js +9 -76
  35. package/dist/src/cli/commands/streaming-endpoint.js +30 -1
  36. package/dist/src/cli/commands/webapp.js +8 -0
  37. package/dist/src/cli/commands/wiki.js +22 -0
  38. package/dist/src/cli/commands/workspace.js +8 -0
  39. package/dist/src/cli/contract.d.ts +16 -15
  40. package/dist/src/cli/contract.js +139 -3404
  41. package/dist/src/cli/doctor.d.ts +13 -0
  42. package/dist/src/cli/doctor.js +41 -1
  43. package/dist/src/cli/flags.d.ts +7 -1
  44. package/dist/src/cli/flags.js +78 -6
  45. package/dist/src/cli/helpers/app-successor.js +1 -2
  46. package/dist/src/cli/helpers/documentation.d.ts +21 -0
  47. package/dist/src/cli/helpers/documentation.js +53 -0
  48. package/dist/src/cli/helpers/trained-model.d.ts +26 -0
  49. package/dist/src/cli/helpers/trained-model.js +144 -0
  50. package/dist/src/cli/list-output.d.ts +7 -0
  51. package/dist/src/cli/list-output.js +77 -0
  52. package/dist/src/cli/list-shapes.d.ts +21 -0
  53. package/dist/src/cli/list-shapes.js +111 -0
  54. package/dist/src/cli/output-schemas.d.ts +0 -14
  55. package/dist/src/cli/output-schemas.js +4 -7
  56. package/dist/src/cli/output.d.ts +0 -1
  57. package/dist/src/cli/output.js +27 -19
  58. package/dist/src/cli/plans.d.ts +14 -0
  59. package/dist/src/cli/plans.js +3684 -0
  60. package/dist/src/cli/usage.d.ts +7 -0
  61. package/dist/src/cli/usage.js +20 -1
  62. package/dist/src/cli/version.d.ts +2 -2
  63. package/dist/src/cli/version.js +2 -2
  64. package/dist/src/cli.js +127 -113
  65. package/dist/src/client.d.ts +52 -43
  66. package/dist/src/client.js +267 -96
  67. package/dist/src/errors.d.ts +11 -1
  68. package/dist/src/errors.js +31 -47
  69. package/dist/src/generated/action-output-schemas.json +345 -89
  70. package/dist/src/index.d.ts +5 -1
  71. package/dist/src/index.js +3 -0
  72. package/dist/src/resources/analyses.d.ts +8 -0
  73. package/dist/src/resources/analyses.js +13 -1
  74. package/dist/src/resources/bundles.d.ts +34 -0
  75. package/dist/src/resources/bundles.js +67 -0
  76. package/dist/src/resources/connections.d.ts +9 -0
  77. package/dist/src/resources/connections.js +15 -0
  78. package/dist/src/resources/data-quality.d.ts +20 -0
  79. package/dist/src/resources/data-quality.js +30 -0
  80. package/dist/src/resources/dataset-create.d.ts +19 -0
  81. package/dist/src/resources/dataset-create.js +66 -0
  82. package/dist/src/resources/datasets.d.ts +25 -15
  83. package/dist/src/resources/datasets.js +59 -111
  84. package/dist/src/resources/discussions.d.ts +5 -0
  85. package/dist/src/resources/discussions.js +7 -0
  86. package/dist/src/resources/documentation.d.ts +25 -0
  87. package/dist/src/resources/documentation.js +16 -0
  88. package/dist/src/resources/flow.d.ts +48 -0
  89. package/dist/src/resources/flow.js +65 -0
  90. package/dist/src/resources/futures.d.ts +23 -0
  91. package/dist/src/resources/futures.js +32 -0
  92. package/dist/src/resources/jobs.js +102 -2
  93. package/dist/src/resources/metrics.d.ts +10 -0
  94. package/dist/src/resources/metrics.js +10 -0
  95. package/dist/src/resources/ml-tasks.d.ts +65 -2
  96. package/dist/src/resources/ml-tasks.js +102 -28
  97. package/dist/src/resources/mlflow-extension.d.ts +73 -0
  98. package/dist/src/resources/mlflow-extension.js +105 -0
  99. package/dist/src/resources/projects.d.ts +6 -0
  100. package/dist/src/resources/projects.js +8 -0
  101. package/dist/src/resources/recipe-create.d.ts +65 -0
  102. package/dist/src/resources/recipe-create.js +338 -0
  103. package/dist/src/resources/recipes.d.ts +28 -29
  104. package/dist/src/resources/recipes.js +126 -245
  105. package/dist/src/resources/saved-models.d.ts +10 -6
  106. package/dist/src/resources/saved-models.js +16 -14
  107. package/dist/src/resources/scenarios.js +8 -14
  108. package/dist/src/resources/streaming-endpoints.d.ts +12 -0
  109. package/dist/src/resources/streaming-endpoints.js +15 -0
  110. package/dist/src/resources/trained-model.d.ts +60 -0
  111. package/dist/src/resources/trained-model.js +98 -0
  112. package/dist/src/resources/webapps.d.ts +8 -0
  113. package/dist/src/resources/webapps.js +10 -0
  114. package/dist/src/resources/wiki.d.ts +5 -0
  115. package/dist/src/resources/wiki.js +7 -0
  116. package/dist/src/resources/workspaces.d.ts +2 -0
  117. package/dist/src/resources/workspaces.js +4 -0
  118. package/dist/src/utils/response-file.js +20 -9
  119. package/dist/src/utils/secret-sanitize.d.ts +7 -0
  120. package/dist/src/utils/secret-sanitize.js +46 -0
  121. package/package.json +25 -26
  122. package/plugin.json +1 -1
  123. package/skills/dataiku-dss/SKILL.md +1 -1
  124. package/skills/dataiku-dss/references/authentication.md +3 -1
  125. package/skills/dataiku-dss/references/coding.md +1 -0
  126. package/skills/dataiku-dss/references/discovery.md +4 -6
  127. package/skills/dataiku-dss/references/troubleshooting.md +3 -2
@@ -1,4 +1,4 @@
1
- import { requiredStringFlag, } from "../coerce.js";
1
+ import { requiredJsonInput, requiredStringFlag, } from "../coerce.js";
2
2
  import { executionMode, } from "../flags.js";
3
3
  import { readIfExists, skipResult, } from "../output.js";
4
4
  import { commandUsage, withUsage, } from "../syntax.js";
@@ -61,4 +61,22 @@ export const analysisCommands = withUsage("analysis", {
61
61
  "dss analysis delete ANALYSIS_ID --dry-run --project-key PROJECT",
62
62
  ],
63
63
  },
64
+ update: {
65
+ handler: async (c, a, f) => {
66
+ requireArgs(a, 1, commandUsage("analysis", "update"));
67
+ const definition = requiredJsonInput(f, "The analysis definition is required via --data, --data-file, or --stdin (dss analysis get, edited).");
68
+ await c.analyses.update(a[0], definition, f["project-key"]);
69
+ return { updated: a[0], resource: "analysis", };
70
+ },
71
+ description: "Replace a visual analysis definition (name, script steps, charts, tags) with the object from dss analysis get, edited.",
72
+ examples: ["dss analysis update ANALYSIS_ID --data-file analysis.json",],
73
+ },
74
+ "list-ml-tasks": {
75
+ handler: (c, a, f) => {
76
+ requireArgs(a, 1, commandUsage("analysis", "list-ml-tasks"));
77
+ return c.analyses.listMlTasks(a[0], f["project-key"]);
78
+ },
79
+ description: "List the ML tasks of one visual analysis (whole project: dss ml-task list).",
80
+ examples: ["dss analysis list-ml-tasks ANALYSIS_ID",],
81
+ },
64
82
  });
@@ -131,4 +131,26 @@ export const bundleCommands = withUsage("bundle", {
131
131
  description: "Delete an imported Automation-node bundle.",
132
132
  examples: ["dss bundle delete-imported v1",],
133
133
  },
134
+ "get-exported": {
135
+ handler: (c, a, f) => c.bundles.getExported(a[0], f["project-key"]),
136
+ description: "Get an exported bundle's details (content summary, export manifest, changelog).",
137
+ examples: ["dss bundle get-exported v1",],
138
+ },
139
+ "create-project": {
140
+ handler: async (c, _a, f) => {
141
+ const file = f["file"];
142
+ const archive = f["archive-path"];
143
+ if ((typeof file === "string") === (typeof archive === "string")) {
144
+ throw new UsageError("Pass exactly one of --file PATH (local bundle zip) or --archive-path PATH (zip on the Automation node).", "missing_required_flag");
145
+ }
146
+ const folder = f["project-folder"];
147
+ const result = await c.bundles.createProjectFromBundle(typeof file === "string" ? { filePath: file, } : { archivePath: archive, }, folder);
148
+ return result ?? { created: true, resource: "bundle", };
149
+ },
150
+ description: "Automation node (global admin): create a new project from a bundle, uploading --file PATH or using --archive-path PATH on the node host; --project-folder places it.",
151
+ examples: [
152
+ "dss bundle create-project --file bundle-v1.zip",
153
+ "dss bundle create-project --archive-path /data/bundles/v1.zip",
154
+ ],
155
+ },
134
156
  });
@@ -1,3 +1,4 @@
1
+ import { DataikuError, } from "../../errors.js";
1
2
  import { sanitizeErrorSecrets, sanitizeSecrets, } from "../../utils/secret-sanitize.js";
2
3
  import { requiredJsonInput, } from "../coerce.js";
3
4
  import { executionMode, } from "../flags.js";
@@ -26,6 +27,7 @@ const SENSITIVE_CONNECTION_KEYS = {
26
27
  refreshtoken: true,
27
28
  secret: true,
28
29
  secretkey: true,
30
+ sessiontoken: true,
29
31
  sharesecret: true,
30
32
  token: true,
31
33
  };
@@ -97,12 +99,34 @@ export const connectionCommands = withUsage("connection", {
97
99
  handler: async (c, a) => {
98
100
  const usage = commandUsage("connection", "get");
99
101
  requireArgs(a, 1, usage);
100
- const details = await c.connections.adminGet(requireConnectionName(a[0], usage));
101
- return sanitizeConnectionSecrets(details);
102
+ const name = requireConnectionName(a[0], usage);
103
+ try {
104
+ const details = await c.connections.adminGet(name);
105
+ return sanitizeConnectionSecrets(details);
106
+ }
107
+ catch (error) {
108
+ if (error instanceof DataikuError && error.status === 403) {
109
+ // The admin endpoint refuses non-admin keys for every connection,
110
+ // including ones they can query; status, code, and exit stay as is.
111
+ error.retryHint =
112
+ "connection get reads the admin definition. For a connection this key can use, run `dss connection info NAME`; `dss doctor` shows which identity the key acts as.";
113
+ }
114
+ throw error;
115
+ }
102
116
  },
103
117
  description: "Get a connection by name (admin). Credential-bearing params (e.g. params.password) are redacted in output.",
104
118
  examples: ["dss connection get postgres",],
105
119
  },
120
+ info: {
121
+ handler: async (c, a) => {
122
+ const usage = commandUsage("connection", "info");
123
+ requireArgs(a, 1, usage);
124
+ const details = await c.connections.info(requireConnectionName(a[0], usage));
125
+ return sanitizeConnectionSecrets(details);
126
+ },
127
+ description: "Read a connection's usage view (no admin privilege required): type, params, and credentials mode for every connection the key can query, where `connection get` (admin) answers 403. Credential-bearing params (e.g. params.password) are redacted in output.",
128
+ examples: ["dss connection info postgres",],
129
+ },
106
130
  create: {
107
131
  handler: async (c, _a, f) => {
108
132
  const usage = commandUsage("connection", "create");
@@ -1,5 +1,5 @@
1
1
  import { deepMerge, } from "../../utils/deep-merge.js";
2
- import { num, parseBooleanOption, requiredJsonInput, } from "../coerce.js";
2
+ import { num, parseBooleanOption, requiredJsonInput, splitCsvFlag, } from "../coerce.js";
3
3
  import { executionMode, } from "../flags.js";
4
4
  import { encodedProjectEndpoint, readIfExists, skipResult, } from "../output.js";
5
5
  import { commandUsage, withUsage, } from "../syntax.js";
@@ -41,6 +41,38 @@ export const dataQualityCommands = withUsage("data-quality", {
41
41
  description: "Get the aggregate data quality status for a dataset.",
42
42
  examples: ["dss data-quality status orders",],
43
43
  },
44
+ "instance-status": {
45
+ handler: (c) => c.dataQuality.instanceStatus(),
46
+ description: "Data quality status of every monitored project you can read, keyed by project key (ok/warning/error/empty rule counts, last run).",
47
+ examples: ["dss data-quality instance-status",],
48
+ },
49
+ "partitions-status": {
50
+ handler: (c, a, f) => c.dataQuality.partitionsStatus(a[0], {
51
+ projectKey: f["project-key"],
52
+ partitions: splitCsvFlag(f["partitions"]),
53
+ }),
54
+ description: "Last data quality outcome for specific partitions of a dataset (--partitions P1,P2); a non-partitioned dataset needs none.",
55
+ examples: ["dss data-quality partitions-status orders --partitions 2026-01,2026-02",],
56
+ },
57
+ "delete-history": {
58
+ handler: async (c, a, f) => {
59
+ const partition = f["partition"] ?? "NP";
60
+ const pk = f["project-key"];
61
+ if (executionMode(f).dryRun) {
62
+ return {
63
+ dryRun: true,
64
+ action: "delete-history",
65
+ resource: "data-quality",
66
+ dataset: a[0],
67
+ partition,
68
+ };
69
+ }
70
+ await c.dataQuality.deleteHistory(a[0], { projectKey: pk, partition, });
71
+ return { deleted: "history", resource: "data-quality", dataset: a[0], partition, };
72
+ },
73
+ description: "Delete data quality rule history of a dataset partition (--partition, default NP; ALL for every partition).",
74
+ examples: ["dss data-quality delete-history orders --partition ALL --dry-run",],
75
+ },
44
76
  "create-rule": {
45
77
  handler: async (c, a, f) => {
46
78
  requireArgs(a, 1, commandUsage("data-quality", "create-rule"));
@@ -1,7 +1,8 @@
1
+ import { assertDatasetTypeCreatable, } from "../../resources/dataset-create.js";
1
2
  import { deepMerge, } from "../../utils/deep-merge.js";
2
3
  import { isRecord, } from "../../utils/records.js";
3
4
  import { compareStrings, stableHash, } from "../../utils/stable-hash.js";
4
- import { jsonInput, num, schemaColumnsInput, unknownJsonInput, } from "../coerce.js";
5
+ import { jsonInput, num, schemaColumnsInput, splitCsvFlag, unknownJsonInput, } from "../coerce.js";
5
6
  import { executionMode, } from "../flags.js";
6
7
  import { datasetSourceSummary, } from "../helpers/dataset.js";
7
8
  import { moveCreatedItemsToZone, resolveFlowZoneIdFromFlags, } from "../helpers/flow-zone.js";
@@ -96,6 +97,14 @@ export function compareDatasetSchemas(expected, actual) {
96
97
  differencesTruncated: acc.items.length < acc.total,
97
98
  };
98
99
  }
100
+ /** `--columns` / `--partitions` read selection (served by the POST variant of the data endpoint). */
101
+ function dataSelectionFromFlags(f) {
102
+ const columns = splitCsvFlag(f["columns"]);
103
+ return {
104
+ ...(columns.length > 0 ? { columns, } : {}),
105
+ ...(typeof f["partitions"] === "string" ? { partitions: f["partitions"], } : {}),
106
+ };
107
+ }
99
108
  export const datasetCommands = withUsage("dataset", {
100
109
  list: {
101
110
  handler: (c, _a, f) => c.datasets.list(f["project-key"]),
@@ -225,6 +234,7 @@ export const datasetCommands = withUsage("dataset", {
225
234
  maxRows,
226
235
  projectKey: f["project-key"],
227
236
  timeoutMs: num(f["timeout"], "--timeout"),
237
+ ...dataSelectionFromFlags(f),
228
238
  });
229
239
  if (result.truncated) {
230
240
  enqueueCliWarning({
@@ -239,8 +249,11 @@ export const datasetCommands = withUsage("dataset", {
239
249
  }
240
250
  return result;
241
251
  },
242
- description: "Preview dataset rows (--rows is an alias for --max-rows). Returns { columns, rows, rowCount, truncated, limit }; when the dataset has more rows than the cap, truncated is true and a dataset_preview_truncated warning is written to stderr.",
243
- examples: ["dss dataset preview orders", "dss dataset preview orders --rows 5",],
252
+ description: "Preview dataset rows (--rows is an alias for --max-rows); --columns COLS and --partitions SPEC narrow the read. Returns { columns, rows, rowCount, truncated, limit }; a dataset_preview_truncated warning on stderr flags more rows.",
253
+ examples: [
254
+ "dss dataset preview orders",
255
+ "dss dataset preview orders --rows 5 --columns id,amount",
256
+ ],
244
257
  },
245
258
  "assert-count": {
246
259
  handler: async (c, a, f) => {
@@ -291,6 +304,22 @@ export const datasetCommands = withUsage("dataset", {
291
304
  description: "Get dataset-level metadata.",
292
305
  examples: ["dss dataset metadata orders",],
293
306
  },
307
+ "sync-hive-metastore": {
308
+ handler: async (c, a, f) => {
309
+ await c.datasets.synchronizeHiveMetastore(a[0], f["project-key"]);
310
+ return { synchronized: a[0], resource: "dataset", };
311
+ },
312
+ description: "Create or update the Hive table of an HDFS dataset to match its schema (Hive metastore sync). HDFS datasets only.",
313
+ examples: ["dss dataset sync-hive-metastore web_logs",],
314
+ },
315
+ "update-from-hive": {
316
+ handler: async (c, a, f) => {
317
+ await c.datasets.updateFromHive(a[0], f["project-key"]);
318
+ return { updated: a[0], resource: "dataset", };
319
+ },
320
+ description: "Update an HDFS dataset's path, schema, partitioning, and format from its Hive metastore table. HDFS datasets only.",
321
+ examples: ["dss dataset update-from-hive web_logs --plan",],
322
+ },
294
323
  "metadata-set": {
295
324
  handler: async (c, a, f) => {
296
325
  const usage = commandUsage("dataset", "metadata-set");
@@ -333,6 +362,7 @@ export const datasetCommands = withUsage("dataset", {
333
362
  if (!name || !dsType) {
334
363
  throw new UsageError(`--name and --type are required. Usage: ${commandUsage("dataset", "create")}`);
335
364
  }
365
+ assertDatasetTypeCreatable(dsType);
336
366
  if (!connection && dsType.toLowerCase() !== "uploadedfiles") {
337
367
  throw new UsageError("--connection is required unless --type is UploadedFiles.");
338
368
  }
@@ -472,6 +502,7 @@ export const datasetCommands = withUsage("dataset", {
472
502
  projectKey: f["project-key"],
473
503
  limit: num(f["limit"], "--limit"),
474
504
  rawData: f["raw-data"] === true,
505
+ ...dataSelectionFromFlags(f),
475
506
  });
476
507
  if (result.truncated) {
477
508
  enqueueCliWarning({
@@ -495,7 +526,7 @@ export const datasetCommands = withUsage("dataset", {
495
526
  }
496
527
  return result;
497
528
  },
498
- description: "Download up to --limit rows (default 100k) as CSV and return { path, rows, truncated, limit }. Formula-like cells are neutralized for spreadsheets; --raw-data preserves exact bytes. Warnings report truncation and the default output path.",
529
+ description: "Download up to --limit rows (default 100k) as CSV and return { path, rows, truncated, limit }; --columns COLS and --partitions SPEC narrow the read. Formula-like cells are neutralized for spreadsheets; --raw-data preserves exact bytes.",
499
530
  examples: [
500
531
  "dss dataset download orders",
501
532
  "dss dataset download orders --output ./data/",
@@ -1,3 +1,4 @@
1
+ import { jsonInput, } from "../coerce.js";
1
2
  import { commandUsage, withUsage, } from "../syntax.js";
2
3
  import { requireArgs, UsageError, } from "../usage.js";
3
4
  export const discussionCommands = withUsage("discussion", {
@@ -41,4 +42,18 @@ export const discussionCommands = withUsage("discussion", {
41
42
  description: "Add a reply to an existing discussion.",
42
43
  examples: ["dss discussion reply DATASET customers d123 --text Done",],
43
44
  },
45
+ update: {
46
+ handler: async (c, a, f) => {
47
+ const pk = f["project-key"];
48
+ const body = jsonInput(f);
49
+ const topic = f["topic"];
50
+ if ((body === undefined) === (typeof topic !== "string")) {
51
+ throw new UsageError("Pass exactly one of --topic TEXT or --data/--data-file/--stdin.", "missing_required_flag");
52
+ }
53
+ const next = body ?? { ...await c.discussions.get(a[0], a[1], a[2], pk), topic, };
54
+ return c.discussions.update(a[0], a[1], a[2], next, pk);
55
+ },
56
+ description: "Update a discussion: --topic TEXT edits the topic of the current discussion, or --data sends a full discussion object from get (e.g. to move it to another object of the project).",
57
+ examples: ['dss discussion update DATASET orders L8gkpoI6 --topic "Schema change (edited)"',],
58
+ },
44
59
  });
@@ -5,7 +5,7 @@ export const doctorCommands = withUsage("doctor", {
5
5
  const { runDoctor, } = await import("../doctor.js");
6
6
  return (await runDoctor(f)).result;
7
7
  },
8
- description: "Run JSON diagnostics for DSS credentials, connectivity, and project access.",
8
+ description: "Run JSON diagnostics for DSS credentials, connectivity, and project access, and report the identity (whoami: user, groups, auth source) the API key acts as.",
9
9
  examples: ["dss doctor", "dss doctor --project-key MYPROJ", "dss doctor --capabilities --fast",],
10
10
  },
11
11
  });
@@ -0,0 +1,5 @@
1
+ import type { SchemaPropagationOptions } from "../../resources/flow.js";
2
+ import type { CommandMeta } from "../types.js";
3
+ /** Propagation options from flags; shared with the `--plan` builder. */
4
+ export declare function schemaPropagationOptionsFromFlags(flags: Record<string, string | boolean>): SchemaPropagationOptions;
5
+ export declare const flowCommands: Record<string, CommandMeta>;
@@ -0,0 +1,57 @@
1
+ import { writeResponseToFile, } from "../../utils/response-file.js";
2
+ import { splitCsvFlag, } from "../coerce.js";
3
+ import { documentationTemplateFromFlags, runDocumentationCommand, taskWaitOptions, } from "../helpers/documentation.js";
4
+ import { commandUsage, withUsage, } from "../syntax.js";
5
+ import { requireArgs, } from "../usage.js";
6
+ /** Propagation options from flags; shared with the `--plan` builder. */
7
+ export function schemaPropagationOptionsFromFlags(flags) {
8
+ const excludedRecipes = splitCsvFlag(flags["stop-at"]);
9
+ const markAsOkRecipes = splitCsvFlag(flags["mark-ok"]);
10
+ return {
11
+ ...(flags["no-auto-rebuild"] === true ? { autoRebuild: false, } : {}),
12
+ ...(excludedRecipes.length > 0 ? { excludedRecipes, } : {}),
13
+ ...(markAsOkRecipes.length > 0 ? { markAsOkRecipes, } : {}),
14
+ };
15
+ }
16
+ export const flowCommands = withUsage("flow", {
17
+ "propagate-schema": {
18
+ handler: async (c, a, f) => {
19
+ requireArgs(a, 1, commandUsage("flow", "propagate-schema"));
20
+ const opts = {
21
+ ...schemaPropagationOptionsFromFlags(f),
22
+ projectKey: f["project-key"],
23
+ };
24
+ if (f["wait"] === true) {
25
+ return c.flow.propagateSchemaAndWait(a[0], { ...opts, ...taskWaitOptions(f), });
26
+ }
27
+ return c.flow.propagateSchema(a[0], opts);
28
+ },
29
+ description: "Propagate a dataset's schema change through all downstream recipes and datasets (UI schema propagation). Rebuilds as needed unless --no-auto-rebuild; --stop-at / --mark-ok RECIPES limit it. Returns the DSS task; --wait waits. One recipe only: dss recipe update-schema.",
30
+ examples: [
31
+ "dss flow propagate-schema orders_raw --wait",
32
+ "dss flow propagate-schema orders_raw --stop-at compute_report --no-auto-rebuild --plan",
33
+ ],
34
+ },
35
+ "generate-documentation": {
36
+ handler: async (c, _a, f) => {
37
+ const pk = f["project-key"];
38
+ const task = await c.flow.generateDocumentation(documentationTemplateFromFlags(f), pk);
39
+ return runDocumentationCommand(c, f, task, (exportId) => c.flow.downloadDocumentation(exportId, pk));
40
+ },
41
+ description: "Generate the flow documentation (Word docx) from the DSS default template, an uploaded --template-file, or a template in a managed folder (--folder FOLDER_ID --path PATH). Returns the DSS future; --wait waits; --output PATH waits and downloads the document.",
42
+ examples: [
43
+ "dss flow generate-documentation --output flow.docx",
44
+ "dss flow generate-documentation --template-file template.docx --wait",
45
+ ],
46
+ },
47
+ "download-documentation": {
48
+ handler: async (c, a, f) => {
49
+ requireArgs(a, 1, commandUsage("flow", "download-documentation"));
50
+ const output = f["output"];
51
+ const res = await c.flow.downloadDocumentation(a[0], f["project-key"]);
52
+ return { path: output, bytes: await writeResponseToFile(output, res), };
53
+ },
54
+ description: "Download a generated flow documentation by the exportId from a finished generate-documentation future.",
55
+ examples: ["dss flow download-documentation EXPORT_ID --output flow.docx",],
56
+ },
57
+ });
@@ -4,6 +4,14 @@ import { planResult, } from "../output.js";
4
4
  import { commandUsage, withUsage, } from "../syntax.js";
5
5
  import { requireArgs, } from "../usage.js";
6
6
  export const futureCommands = withUsage("future", {
7
+ list: {
8
+ handler: (c, _a, f) => c.futures.list({
9
+ allUsers: f["all-users"] === true,
10
+ withScenarios: f["with-scenarios"] === true,
11
+ }),
12
+ description: "List long tasks in progress on the instance (DSS futures): your own, or every user's with --all-users; --with-scenarios adds running scenarios.",
13
+ examples: ["dss future list", "dss future list --all-users --with-scenarios",],
14
+ },
7
15
  get: {
8
16
  handler: (c, a) => {
9
17
  requireArgs(a, 1, commandUsage("future", "get"));
@@ -91,6 +91,12 @@ export const commands = {
91
91
  get "future"() {
92
92
  return require("./future.js").futureCommands;
93
93
  },
94
+ get "flow"() {
95
+ return require("./flow.js").flowCommands;
96
+ },
97
+ get "mlflow"() {
98
+ return require("./mlflow.js").mlflowCommands;
99
+ },
94
100
  get "flow-zone"() {
95
101
  return require("./flow-zone.js").flowZoneCommands;
96
102
  },
@@ -3,9 +3,26 @@ import { dirname, resolve, } from "node:path";
3
3
  import { asRecord, } from "../../utils/records.js";
4
4
  import { jobBuildTargetTypeFromFlags, jobLogFilterFromFlag, maxLogLinesFromFlags, num, } from "../coerce.js";
5
5
  import { executionMode, } from "../flags.js";
6
- import { encodedProjectEndpoint, } from "../output.js";
6
+ import { encodedProjectEndpoint, enqueueCliWarning, } from "../output.js";
7
7
  import { commandUsage, withUsage, } from "../syntax.js";
8
8
  import { requireArgs, UsageError, } from "../usage.js";
9
+ /**
10
+ * With an empty output schema DSS ends a dataset build DONE after writing no
11
+ * columns and no rows, without an error. Flag that after a successful build so
12
+ * it is not mistaken for real output.
13
+ */
14
+ async function warnIfBuiltDatasetHasNoColumns(c, target, targetType, success, projectKey) {
15
+ if (!success || targetType !== "DATASET")
16
+ return;
17
+ const schema = await c.datasets.schema(target, projectKey).catch(() => undefined);
18
+ if (!schema || schema.columns.length > 0)
19
+ return;
20
+ enqueueCliWarning({
21
+ code: "built_dataset_has_no_columns",
22
+ dataset: target,
23
+ hint: "The build succeeded but the dataset schema is empty, so no data was written. For a visual or SQL query recipe, run dss recipe update-schema RECIPE (or rebuild with --auto-update-schema).",
24
+ });
25
+ }
9
26
  // ---------------------------------------------------------------------------
10
27
  // Utility helpers
11
28
  // ---------------------------------------------------------------------------
@@ -236,7 +253,7 @@ export const jobCommands = withUsage("job", {
236
253
  await writeFile(outputPath, log.endsWith("\n") ? log : `${log}\n`, "utf-8");
237
254
  return outputPath;
238
255
  },
239
- description: "Get public API job log output. Use --errors-only (or --log-filter errors) to surface just error/traceback lines, and --output PATH to write the log to a file (stdout returns the path). --log-id is accepted for UI parity but DSS API-key auth cannot select browser-only cat-activity-log files.",
256
+ description: "Get public API job log output; find why a job failed. Use --errors-only (or --log-filter errors) to surface just error/traceback lines, and --output PATH to write the log to a file (stdout returns the path). --log-id is accepted for UI parity but DSS API-key auth cannot select browser-only cat-activity-log files.",
240
257
  examples: [
241
258
  "dss job log JOB_ID",
242
259
  "dss job log JOB_ID --activity main --max-log-lines 200",
@@ -270,6 +287,7 @@ export const jobCommands = withUsage("job", {
270
287
  requireArgs(a, 1, commandUsage("job", "build"));
271
288
  const pk = f["project-key"];
272
289
  const options = {
290
+ autoUpdateSchema: f["auto-update-schema"] === true,
273
291
  buildMode: f["build-mode"],
274
292
  partition: f["partition"],
275
293
  pollIntervalMs: num(f["poll-interval"], "--poll-interval"),
@@ -288,11 +306,13 @@ export const jobCommands = withUsage("job", {
288
306
  };
289
307
  }
290
308
  if (f["wait"] === true) {
291
- return c.jobs.buildAndWait(a[0], { ...options, projectKey: pk, });
309
+ const result = await c.jobs.buildAndWait(a[0], { ...options, projectKey: pk, });
310
+ await warnIfBuiltDatasetHasNoColumns(c, a[0], options.targetType, result.success, pk);
311
+ return result;
292
312
  }
293
313
  return c.jobs.build(a[0], { ...options, projectKey: pk, });
294
314
  },
295
- description: "Start a dataset or managed-folder build, optionally waiting for completion.",
315
+ description: "Start a dataset or managed-folder build, optionally waiting for completion. --auto-update-schema lets DSS update each recipe's output schema before it runs.",
296
316
  examples: [
297
317
  "dss job build orders",
298
318
  "dss job build orders --build-mode RECURSIVE_BUILD --wait",
@@ -304,6 +324,7 @@ export const jobCommands = withUsage("job", {
304
324
  requireArgs(a, 1, commandUsage("job", "build-and-wait"));
305
325
  const pk = f["project-key"];
306
326
  const options = {
327
+ autoUpdateSchema: f["auto-update-schema"] === true,
307
328
  buildMode: f["build-mode"],
308
329
  includeLogs: f["include-logs"] === true,
309
330
  logFilter: jobLogFilterFromFlag(f["log-filter"]),
@@ -325,9 +346,11 @@ export const jobCommands = withUsage("job", {
325
346
  method: "POST",
326
347
  };
327
348
  }
328
- return c.jobs.buildAndWait(a[0], { ...options, projectKey: pk, });
349
+ const result = await c.jobs.buildAndWait(a[0], { ...options, projectKey: pk, });
350
+ await warnIfBuiltDatasetHasNoColumns(c, a[0], options.targetType, result.success, pk);
351
+ return result;
329
352
  },
330
- description: "Build a dataset or managed folder and wait for completion.",
353
+ description: "Build a dataset or managed folder and wait for completion. --auto-update-schema lets DSS update each recipe's output schema before it runs; a successful dataset build that leaves an empty schema emits a built_dataset_has_no_columns warning.",
331
354
  examples: [
332
355
  "dss job build-and-wait orders",
333
356
  "dss job build-and-wait orders --include-logs --log-filter stdout --summary",
@@ -1,5 +1,6 @@
1
+ import { unknownJsonInput, } from "../coerce.js";
1
2
  import { commandUsage, withUsage, } from "../syntax.js";
2
- import { requireArgs, } from "../usage.js";
3
+ import { requireArgs, UsageError, } from "../usage.js";
3
4
  export const metricsCommands = withUsage("metrics", {
4
5
  "dataset-get": {
5
6
  handler: (c, a, f) => {
@@ -17,6 +18,25 @@ export const metricsCommands = withUsage("metrics", {
17
18
  description: "Compute the DSS-configured metrics for a dataset.",
18
19
  examples: ["dss metrics dataset-compute customers",],
19
20
  },
21
+ "dataset-run-checks": {
22
+ handler: (c, a, f) => {
23
+ const data = unknownJsonInput(f);
24
+ const checks = data && typeof data === "object" && "checks" in data ? data.checks : undefined;
25
+ if (data !== undefined && !Array.isArray(checks)) {
26
+ throw new UsageError('--data must be {"checks": [...]}.', "validation_failed");
27
+ }
28
+ return c.metrics.runDatasetChecks(a[0], {
29
+ projectKey: f["project-key"],
30
+ partitions: f["partitions"],
31
+ ...(Array.isArray(checks) ? { checks, } : {}),
32
+ });
33
+ },
34
+ description: 'Run the checks configured on a dataset, or the {"checks": [...]} definitions passed as JSON, and return their outcomes.',
35
+ examples: [
36
+ "dss metrics dataset-run-checks customers",
37
+ "dss metrics dataset-run-checks customers --data-file checks.json",
38
+ ],
39
+ },
20
40
  "dataset-history": {
21
41
  handler: (c, a, f) => {
22
42
  requireArgs(a, 2, commandUsage("metrics", "dataset-history"));
@@ -1,2 +1,7 @@
1
+ import type { MlTaskCreateFields, MlTaskReguessOptions } from "../../resources/ml-tasks.js";
1
2
  import type { CommandMeta } from "../types.js";
3
+ /** Task definition flags shared by `create`, `create-for-dataset`, and their --plan. */
4
+ export declare function mlTaskFieldsFromFlags(flags: Record<string, string | boolean>, usage: string): MlTaskCreateFields;
5
+ /** `reguess` flags → SDK options (shared with --plan). */
6
+ export declare function mlTaskReguessOptionsFromFlags(flags: Record<string, string | boolean>): MlTaskReguessOptions;
2
7
  export declare const mlTaskCommands: Record<string, CommandMeta>;
@@ -1,5 +1,6 @@
1
- import { num, requiredJsonInput, requiredStringFlag, } from "../coerce.js";
1
+ import { num, parseBooleanOption, requiredJsonInput, requiredStringFlag, splitCsvFlag, } from "../coerce.js";
2
2
  import { executionMode, } from "../flags.js";
3
+ import { trainedModelCommands, } from "../helpers/trained-model.js";
3
4
  import { commandUsage, withUsage, } from "../syntax.js";
4
5
  import { requireArgs, UsageError, } from "../usage.js";
5
6
  function optionalStringFlag(flags, name) {
@@ -17,27 +18,47 @@ function taskType(flags, usage) {
17
18
  return normalized;
18
19
  throw new UsageError("--task-type must be PREDICTION or CLUSTERING.", "invalid_enum");
19
20
  }
21
+ /** Task definition flags shared by `create`, `create-for-dataset`, and their --plan. */
22
+ export function mlTaskFieldsFromFlags(flags, usage) {
23
+ const normalizedTaskType = taskType(flags, usage);
24
+ const targetVariable = optionalStringFlag(flags, "target");
25
+ if (normalizedTaskType === "PREDICTION" && targetVariable === undefined) {
26
+ throw new UsageError("--target is required for PREDICTION ML tasks.", "missing_required_flag");
27
+ }
28
+ const timeseriesIdentifiers = splitCsvFlag(flags["timeseries-ids"]);
29
+ return {
30
+ taskType: normalizedTaskType,
31
+ targetVariable,
32
+ predictionType: optionalStringFlag(flags, "prediction-type"),
33
+ timeVariable: optionalStringFlag(flags, "time-variable"),
34
+ ...(timeseriesIdentifiers.length > 0 ? { timeseriesIdentifiers, } : {}),
35
+ backendType: optionalStringFlag(flags, "backend-type"),
36
+ guessPolicy: optionalStringFlag(flags, "guess-policy"),
37
+ };
38
+ }
39
+ /** `reguess` flags → SDK options (shared with --plan). */
40
+ export function mlTaskReguessOptionsFromFlags(flags) {
41
+ const timeseriesIdentifiers = splitCsvFlag(flags["timeseries-ids"]);
42
+ return {
43
+ predictionType: optionalStringFlag(flags, "prediction-type"),
44
+ targetVariable: optionalStringFlag(flags, "target"),
45
+ timeVariable: optionalStringFlag(flags, "time-variable"),
46
+ ...(timeseriesIdentifiers.length > 0 ? { timeseriesIdentifiers, } : {}),
47
+ ...(flags["full-reguess"] !== undefined
48
+ ? { fullReguess: parseBooleanOption(flags["full-reguess"], "--full-reguess"), }
49
+ : {}),
50
+ };
51
+ }
20
52
  export const mlTaskCommands = withUsage("ml-task", {
21
53
  create: {
22
54
  handler: async (c, a, f) => {
23
55
  const usage = commandUsage("ml-task", "create");
24
56
  requireArgs(a, 1, usage);
25
- const projectKey = f["project-key"];
26
- const normalizedTaskType = taskType(f, usage);
27
- const targetVariable = optionalStringFlag(f, "target");
28
- if (normalizedTaskType === "PREDICTION" && targetVariable === undefined) {
29
- throw new UsageError("--target is required for PREDICTION ML tasks.", "missing_required_flag");
30
- }
31
- const options = {
57
+ const created = await c.mlTasks.create({
32
58
  analysisId: a[0],
33
- taskType: normalizedTaskType,
34
- targetVariable,
35
- predictionType: optionalStringFlag(f, "prediction-type"),
36
- backendType: optionalStringFlag(f, "backend-type"),
37
- guessPolicy: optionalStringFlag(f, "guess-policy"),
38
- projectKey,
39
- };
40
- const created = await c.mlTasks.create(options);
59
+ ...mlTaskFieldsFromFlags(f, usage),
60
+ projectKey: f["project-key"],
61
+ });
41
62
  return { created: created.mlTaskId, resource: "ml-task", analysisId: a[0], ...created, };
42
63
  },
43
64
  description: "Create a prediction or clustering task in an analysis.",
@@ -173,4 +194,53 @@ export const mlTaskCommands = withUsage("ml-task", {
173
194
  "dss ml-task delete ANALYSIS_ID TASK_ID --dry-run --project-key PROJECT",
174
195
  ],
175
196
  },
197
+ list: {
198
+ handler: (c, _a, f) => c.mlTasks.list(f["project-key"]),
199
+ description: "List every ML task of the project with its visual analysis (one analysis: dss analysis list-ml-tasks).",
200
+ examples: ["dss ml-task list",],
201
+ },
202
+ "create-for-dataset": {
203
+ handler: async (c, a, f) => {
204
+ const usage = commandUsage("ml-task", "create-for-dataset");
205
+ requireArgs(a, 1, usage);
206
+ const created = await c.mlTasks.createForDataset({
207
+ inputDataset: a[0],
208
+ ...mlTaskFieldsFromFlags(f, usage),
209
+ projectKey: f["project-key"],
210
+ });
211
+ return { created: created.mlTaskId, resource: "ml-task", ...created, };
212
+ },
213
+ description: "Create a new visual analysis on a dataset with one prediction, clustering, or forecasting task (--prediction-type TIMESERIES_FORECAST --time-variable COL [--timeseries-ids COLS]). DSS guesses settings asynchronously: poll status until guessing is false.",
214
+ examples: [
215
+ "dss ml-task create-for-dataset customers --task-type prediction --target churn",
216
+ "dss ml-task create-for-dataset sales --task-type prediction --target amount --prediction-type TIMESERIES_FORECAST --time-variable day",
217
+ ],
218
+ },
219
+ reguess: {
220
+ handler: async (c, a, f) => {
221
+ requireArgs(a, 2, commandUsage("ml-task", "reguess"));
222
+ await c.mlTasks.reguess(a[0], a[1], mlTaskReguessOptionsFromFlags(f), f["project-key"]);
223
+ return { reguessed: a[1], resource: "ml-task", analysisId: a[0], };
224
+ },
225
+ description: "Re-guess an ML task's settings: all of them, or after changing one core parameter (--prediction-type, --target, --time-variable, --timeseries-ids), only the impacted ones unless --full-reguess true.",
226
+ examples: ["dss ml-task reguess ANALYSIS_ID TASK_ID --target churn_flag",],
227
+ },
228
+ "reguess-forecasting": {
229
+ handler: async (c, a, f) => {
230
+ requireArgs(a, 2, commandUsage("ml-task", "reguess-forecasting"));
231
+ await c.mlTasks.reguessForecasting(a[0], a[1], requiredJsonInput(f, "Forecasting parameters are required via --data, --data-file, or --stdin (forecastHorizon, validationHorizons, timestepParams, updateAlgorithmSettings)."), f["project-key"]);
232
+ return { reguessed: a[1], resource: "ml-task", analysisId: a[0], };
233
+ },
234
+ description: "Time series forecasting tasks: change forecasting parameters (forecastHorizon, validationHorizons, timestepParams {timeunit, numberOfTimeunits, ...}, updateAlgorithmSettings) and re-guess impacted algorithm settings.",
235
+ examples: [
236
+ 'dss ml-task reguess-forecasting ANALYSIS_ID TASK_ID --data \'{"forecastHorizon":7,"updateAlgorithmSettings":true}\'',
237
+ ],
238
+ },
239
+ ...trainedModelCommands({
240
+ resource: "ml-task",
241
+ ids: "ANALYSIS_ID TASK_ID MODEL_ID",
242
+ noun: "lab model",
243
+ model: (c, a, pk) => c.mlTasks.model(a[0], a[1], a[2], pk),
244
+ downloadDocumentation: (c, exportId, pk) => c.mlTasks.downloadModelDocumentation(exportId, pk),
245
+ }),
176
246
  });
@@ -0,0 +1,11 @@
1
+ import type { MlflowDeployRunOptions, MlflowExperimentsDatasetOptions, MlflowInferenceInfo } from "../../resources/mlflow-extension.js";
2
+ import type { CommandMeta } from "../types.js";
3
+ type Flags = Record<string, string | boolean>;
4
+ /** `dss mlflow set-inference-info` flags → SDK inference info (shared with --plan). */
5
+ export declare function inferenceInfoFromFlags(runId: string, f: Flags): MlflowInferenceInfo;
6
+ /** `dss mlflow deploy-run` flags → SDK deploy options (shared with --plan). */
7
+ export declare function deployRunOptionsFromFlags(runId: string, savedModelId: string, f: Flags): MlflowDeployRunOptions;
8
+ /** `dss mlflow create-experiments-dataset` flags → SDK options (shared with --plan). */
9
+ export declare function experimentsDatasetOptionsFromFlags(datasetName: string, f: Flags): MlflowExperimentsDatasetOptions;
10
+ export declare const mlflowCommands: Record<string, CommandMeta>;
11
+ export {};