dataiku-sdk 2.0.0 → 3.1.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 (80) hide show
  1. package/LICENSE +107 -17
  2. package/README.md +144 -17
  3. package/dist/build-metadata.json +1 -1
  4. package/dist/packages/types/src/index.d.ts +39 -4
  5. package/dist/packages/types/src/index.js +31 -2
  6. package/dist/src/cli/commands/api-service.js +62 -16
  7. package/dist/src/cli/commands/bundle.js +49 -15
  8. package/dist/src/cli/commands/code-env.js +210 -49
  9. package/dist/src/cli/commands/code.d.ts +19 -0
  10. package/dist/src/cli/commands/code.js +87 -15
  11. package/dist/src/cli/commands/dataset.js +8 -3
  12. package/dist/src/cli/commands/flow-zone.js +33 -5
  13. package/dist/src/cli/commands/notebook.js +72 -41
  14. package/dist/src/cli/commands/project-git.js +8 -5
  15. package/dist/src/cli/commands/project-library.d.ts +21 -0
  16. package/dist/src/cli/commands/project-library.js +121 -50
  17. package/dist/src/cli/commands/project.js +16 -2
  18. package/dist/src/cli/commands/recipe.js +37 -12
  19. package/dist/src/cli/commands/sql.d.ts +10 -0
  20. package/dist/src/cli/commands/sql.js +39 -17
  21. package/dist/src/cli/commands/webapp.js +67 -13
  22. package/dist/src/cli/contract.d.ts +15 -0
  23. package/dist/src/cli/contract.js +870 -107
  24. package/dist/src/cli/env.d.ts +9 -0
  25. package/dist/src/cli/env.js +20 -2
  26. package/dist/src/cli/flags.js +9 -0
  27. package/dist/src/cli/helpers/cleanup.js +104 -3
  28. package/dist/src/cli/helpers/flow-zone.d.ts +3 -0
  29. package/dist/src/cli/helpers/flow-zone.js +33 -3
  30. package/dist/src/cli/helpers/recipe.d.ts +20 -0
  31. package/dist/src/cli/helpers/recipe.js +158 -3
  32. package/dist/src/cli/output.d.ts +2 -0
  33. package/dist/src/cli/output.js +33 -6
  34. package/dist/src/cli/runtime.d.ts +35 -1
  35. package/dist/src/cli/runtime.js +125 -18
  36. package/dist/src/cli/types.d.ts +7 -0
  37. package/dist/src/cli.js +135 -28
  38. package/dist/src/client.d.ts +60 -0
  39. package/dist/src/client.js +237 -42
  40. package/dist/src/errors.d.ts +8 -2
  41. package/dist/src/errors.js +40 -0
  42. package/dist/src/index.d.ts +4 -3
  43. package/dist/src/index.js +2 -1
  44. package/dist/src/resources/api-services.d.ts +48 -6
  45. package/dist/src/resources/api-services.js +54 -8
  46. package/dist/src/resources/bundles.d.ts +51 -6
  47. package/dist/src/resources/bundles.js +39 -9
  48. package/dist/src/resources/code-envs.d.ts +25 -3
  49. package/dist/src/resources/code-envs.js +104 -2
  50. package/dist/src/resources/datasets.d.ts +20 -0
  51. package/dist/src/resources/datasets.js +232 -52
  52. package/dist/src/resources/jobs.d.ts +35 -10
  53. package/dist/src/resources/jobs.js +92 -17
  54. package/dist/src/resources/notebooks.d.ts +77 -7
  55. package/dist/src/resources/notebooks.js +143 -19
  56. package/dist/src/resources/project-git.d.ts +12 -0
  57. package/dist/src/resources/project-git.js +39 -8
  58. package/dist/src/resources/project-library.d.ts +122 -7
  59. package/dist/src/resources/project-library.js +494 -25
  60. package/dist/src/resources/projects.d.ts +5 -2
  61. package/dist/src/resources/projects.js +18 -2
  62. package/dist/src/resources/scenarios.d.ts +30 -0
  63. package/dist/src/resources/scenarios.js +73 -27
  64. package/dist/src/resources/sql.d.ts +6 -0
  65. package/dist/src/resources/sql.js +22 -2
  66. package/dist/src/resources/webapps.d.ts +35 -4
  67. package/dist/src/resources/webapps.js +54 -5
  68. package/dist/src/schemas.d.ts +2 -2
  69. package/dist/src/schemas.js +1 -1
  70. package/dist/src/skill.d.ts +9 -0
  71. package/dist/src/skill.js +37 -4
  72. package/dist/src/utils/flow-analysis.d.ts +53 -0
  73. package/dist/src/utils/flow-analysis.js +382 -0
  74. package/dist/src/utils/project-archive.d.ts +41 -2
  75. package/dist/src/utils/project-archive.js +159 -16
  76. package/package.json +5 -5
  77. package/packages/types/dist/index.d.ts +39 -4
  78. package/packages/types/dist/index.js +31 -2
  79. package/plugin.json +2 -2
  80. package/skills/dataiku-dss/SKILL.md +75 -48
package/LICENSE CHANGED
@@ -1,21 +1,111 @@
1
- MIT License
1
+ Dataiku SDK Limited Use License
2
+ Version 1.0 — 31 August 2026
2
3
 
3
4
  Copyright (c) 2026 clssck
4
5
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
6
+ By copying, installing, accessing, or using this software and its associated
7
+ documentation (the "Software"), you agree to this license.
8
+
9
+ 1. Definitions
10
+
11
+ "Licensor" means clssck, the copyright holder.
12
+
13
+ "Individual" means a natural person acting solely on their own behalf. A person
14
+ acting for an employer, client, company, or other organization is not acting as
15
+ an Individual for that use.
16
+
17
+ "Company" means a for-profit legal entity, including a sole proprietorship,
18
+ partnership, corporation, or limited liability company. Companies under common
19
+ control are treated as one Company.
20
+
21
+ "Annual Revenue" means a Company's total gross revenue, together with the gross
22
+ revenue of every entity under common control, for its most recently completed
23
+ fiscal year, before deductions. A Company without a completed fiscal year must
24
+ use its good-faith projected gross revenue for its first twelve months. Revenue
25
+ in another currency must be converted to United States dollars using a
26
+ reasonable, consistently applied exchange rate.
27
+
28
+ "Qualified User" means either:
29
+
30
+ (a) an Individual; or
31
+ (b) a Company with Annual Revenue of less than US $1,000,000.
32
+
33
+ 2. Free Limited License for Qualified Users
34
+
35
+ Subject to every term of this license, the Licensor grants each Qualified User
36
+ a non-exclusive, non-transferable, and non-sublicensable license, without
37
+ a license fee, to copy, install, and run unmodified copies of the Software for
38
+ the Qualified User's own use.
39
+
40
+ Use by an employee, contractor, agent, or other person on behalf of a Company is
41
+ use by that Company. An Individual license does not extend to such use.
42
+
43
+ 3. Users That Do Not Qualify
44
+
45
+ A Company with Annual Revenue of US $1,000,000 or more, and any person or entity
46
+ that is not a Qualified User, receives no right to use the Software under
47
+ Section 2. Such a user must request and obtain a separate written license from
48
+ the Licensor before copying, installing, or using the Software. Public access
49
+ to the source code does not itself grant permission to use it.
50
+
51
+ License and approval requests may be submitted to the Licensor through:
52
+ https://github.com/clssck/dataiku-sdk
53
+
54
+ 4. Prior Written Approval Required
55
+
56
+ The rights granted in Section 2 do not include any right to:
57
+
58
+ (a) modify, adapt, translate, or create derivative works of the Software,
59
+ including modifications made only for private or internal use; or
60
+ (b) publish, distribute, provide, transfer, sublicense, sell, or otherwise make
61
+ all or any part of the Software available to another person or entity, whether
62
+ in source, binary, modified, or unmodified form.
63
+
64
+ Each activity listed above requires the Licensor's prior written approval.
65
+ Approval of one activity or version does not approve another. The Licensor may
66
+ condition or deny approval at its discretion.
67
+
68
+ 5. Attribution and Citation
69
+
70
+ Every permitted use must preserve all copyright, attribution, and license
71
+ notices included with the Software. The following credit and link must also
72
+ appear in documentation, notices, or an About page accompanying the use:
73
+
74
+ dataiku-sdk by clssck — https://github.com/clssck/dataiku-sdk
75
+
76
+ The credit must be reasonably prominent and may not suggest endorsement by the
77
+ Licensor. Prior written approval under Section 4 does not waive these
78
+ requirements unless the approval expressly says so.
79
+
80
+ 6. No Other Rights
81
+
82
+ The Software is licensed, not sold. Except for the limited rights expressly
83
+ granted in this license or in a separate written agreement signed by the
84
+ Licensor, the Licensor reserves all rights. This license grants no right to use
85
+ any trademark, service mark, trade name, or logo of the Licensor.
86
+
87
+ 7. Termination
88
+
89
+ This license terminates automatically upon breach. After termination, you must
90
+ stop using the Software and delete every copy in your possession or control.
91
+ Sections 5, 6, 8, 9, and 10 survive termination.
92
+
93
+ 8. Disclaimer of Warranty
94
+
95
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
96
+ IMPLIED, INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
97
+ PURPOSE, TITLE, AND NON-INFRINGEMENT. YOU BEAR ALL RISK ARISING FROM USE OF THE
21
98
  SOFTWARE.
99
+
100
+ 9. Limitation of Liability
101
+
102
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE LICENSOR WILL NOT BE LIABLE FOR ANY
103
+ CLAIM, LOSS, OR DAMAGES ARISING FROM OR RELATED TO THE SOFTWARE OR THIS LICENSE,
104
+ WHETHER IN CONTRACT, TORT, OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF
105
+ SUCH DAMAGES.
106
+
107
+ 10. Earlier Licenses
108
+
109
+ This license applies only to copies of the Software distributed with this
110
+ license. It does not revoke or restrict rights validly granted for copies that a
111
+ recipient previously received under another license.
package/README.md CHANGED
@@ -25,31 +25,30 @@ Bun is the only supported runtime and the package manager. Examples below assume
25
25
 
26
26
  ## CLI contract
27
27
 
28
- - Command results write exactly one compact JSON value to stdout; void success is `{ok:true}`. `doctor`, `batch`, and `cleanup` failure reports are their direct result objects on stdout with a nonzero exit code — use the exit code and result fields.
29
- - Dispatch/runtime failures write one compact structured error object on stdout (`type:"error"`, `ok:false`, `error`, `code`, `category`, `exitCode`) with a nonzero exit code; stderr carries JSONL diagnostics only.
30
- - Non-fatal diagnostics and `--verbose` traces are JSONL stderr events (`type:"warning"` / `type:"trace"`), flushed before both success and failure output; no prose trace lines are part of the contract.
31
- - `--fields a,b,c` projects those fields from an object or array-of-objects result; dotted paths (`a.b.c`) drill into nested objects, and missing fields become `null`; string and scalar results pass through unchanged.
32
- - No prompts, help screens, tables, banners, or prose output are part of the contract.
33
- - Exit codes: `0` success, `1` usage/configuration error, `2` DSS/internal error, `3` transient DSS error, `4` a failed long-running result or synchronous assertion.
34
- - `--retries N` controls idempotent GET retries only. `dss sql query --start-retries N` explicitly retries transient failures while starting a query; use it only when executing the SQL more than once is safe.
35
- - The exit code is the success signal. For portable multi-step mutations, prefer `dss batch`; shell chaining and pipeline exit semantics differ across POSIX shells, Windows PowerShell, PowerShell 7, and Command Prompt.
36
- - Recipe payload commands write the payload as a JSON string on stdout; use `--output PATH` to write the exact bytes to a file instead, with stdout carrying the JSON string equal to `PATH`.
37
-
38
- Discover the agent contract and command surface with scoped calls:
28
+ The complete agent-facing contract — stdout JSON discipline, stderr JSONL diagnostics, the error
29
+ envelope, exit codes, `--fields` projection, command discovery, and planning/safety rules — is the
30
+ canonical skill at [`skills/dataiku-dss/SKILL.md`](skills/dataiku-dss/SKILL.md); keep that file as
31
+ the single source of truth for agent integrations and for the `dss install-skill` payload. Human
32
+ essentials: exactly one compact JSON value on stdout per command (void success is `{ok:true}`),
33
+ failures as one structured JSON error object on stdout with a nonzero exit code, stderr reserved
34
+ for JSONL diagnostics only, and exit codes `0` success / `1` usage error / `2` DSS or internal
35
+ error / `3` transient DSS error / `4` failed long-running result or assertion. `--retries N`
36
+ controls idempotent GET retries only; `dss sql query --start-retries N` retries transient failures
37
+ while starting a query. For portable multi-step mutations, prefer `dss batch`; shell chaining and
38
+ pipeline exit semantics differ across platforms.
39
+
40
+ Discover the command surface with scoped calls:
39
41
 
40
42
  ```text
41
43
  dss commands run
42
- dss commands run --fields dataset
43
- dss commands run --fields dataset.create
44
44
  dss commands run --fields dataset.create.usage,dataset.create.description,dataset.create.flags,dataset.create.examples
45
45
  dss commands run --output commands.json
46
46
  dss agent contract --fields protocol,agentContractVersion,cli,stdio,planning,compatibility
47
- dss agent contract --fields commands.actions
48
47
  ```
49
48
 
50
- `dss commands run` prints the compact resource/action summary — every resource keyed to its action names, about 1k tokens — and never dumps registry entries to stdout. Bootstrap contract discovery with the scoped `agent contract` call above: `protocol,agentContractVersion,cli,stdio,planning,compatibility` cover protocol/schema compatibility, stdout/stderr stream semantics, preferred discovery commands, planning rules, and compatibility guarantees in ~250 tokens; request `schemas` or `commands` only when you actually need them. Before choosing syntax, scope `commands run` with `--fields`: `--fields RESOURCE.ACTION` returns one complete registry entry, `--fields RESOURCE` returns every action of one resource, and appending `.FIELD` paths projects the metadata you need — the four-field per-action projection `usage,description,flags,examples` is the smallest self-sufficient starting point for constructing an invocation. Inspect `flags`, `structuredExamples`, `schemas`, `requiresAuth`, `requiresProject`, `sideEffect`, `async`, `idempotency`, `dryRun`, `cleanupCommand`, `unsafeOutputs`, `outputShape`, `inputContract`, and `exitCodes` instead of guessing.
51
-
52
- `--fields` takes a comma-separated list, so request several actions in one call. Each key is echoed exactly as requested (`--fields dataset.create` returns `{"dataset.create": {...}}`); an empty `--fields` is a usage error, never a silent full dump. The full registry (~220k tokens) is exported only via `--output PATH`: the command writes the registry, or the selected `--fields` subset, as compact JSON to `PATH`, and stdout carries the compact `{"path":"PATH"}` result — never the registry itself. An unknown resource or action exits with code 1 and a compact JSON error object on stdout containing the valid options.
49
+ `dss commands run` prints the compact resource/action summary; registry entries (~220k tokens
50
+ exported) never dump to stdout — they travel only via `--output PATH`. See the canonical skill for
51
+ the full `--fields` projection rules and planning workflow.
53
52
 
54
53
  ## Agent skill installation
55
54
 
@@ -72,6 +71,15 @@ Project installs write `SKILL.md` under the target workspace:
72
71
 
73
72
  Global installs write under the agent's home config path, for example OMP: `~/.omp/agent/skills/dataiku-dss/SKILL.md`.
74
73
 
74
+ Each entry in the `installed` array reports deterministic file state:
75
+
76
+ - `status`: `missing` (no file at the destination), `stale` (file present but bytes differ from the canonical skill), or `current` (byte-identical to the canonical skill).
77
+ - `changed`: whether the install writes the file — `true` for `missing` and `stale`, `false` for `current`; installs skip byte-identical files and replace missing/stale files through a same-directory temporary file followed by rename.
78
+ - `expectedSha256`: SHA-256 of the canonical skill bytes this SDK ships.
79
+ - `actualSha256`: SHA-256 of the file currently at the destination; present only when the file exists.
80
+
81
+ `--dry-run` and `--plan` never write; they report the same `status`/`changed`/hash fields so you can see which copies a real install would refresh — a `stale` copy is detected and would be refreshed, while a `current` copy is already byte-identical and needs no refresh.
82
+
75
83
  ## Credentials
76
84
 
77
85
  Use environment variables for ephemeral runs. For disposable agent tests, set `DSS_CONFIG_DIR` to a temporary directory so saved credentials never touch your real profile.
@@ -285,6 +293,48 @@ never marks that external check complete. The public DSS APIs used by this SDK d
285
293
  supported app-template publish/recreate/rename workflow, recipient-level app sharing setter, or
286
294
  UI-click smoke test. The CLI does not guess private endpoints for those operations.
287
295
 
296
+ ## Flow visualization and zone planning
297
+
298
+ `project map` returns one agent-oriented JSON view of the Flow: normalized nodes and edges,
299
+ joined zone metadata, cycle-safe topological layers, weakly connected components, diagnostics, and
300
+ a stable `topologyFingerprint`. Zone joins add `zoneId`/`zoneName` to each node; the top-level
301
+ `zones` array preserves zone color, position, item count, and visible node IDs.
302
+
303
+ ```bash
304
+ dss project map --project-key MYPROJ
305
+ dss project map --render mermaid --project-key MYPROJ
306
+ dss project map --render ascii --max-nodes 100 --max-edges 200 --project-key MYPROJ
307
+ ```
308
+
309
+ Rendering is optional and remains inside the JSON result as `rendering.content`; stdout never
310
+ switches to an unstructured diagram stream. Layers are computed after collapsing strongly connected
311
+ components, so cycles are reported without blocking the analysis. Diagnostics cover cycles,
312
+ disconnected components, isolated/default-zone nodes, cross-zone edges, duplicate assignments, and
313
+ truncated analysis. When limits truncate the returned nodes or edges, the topology fingerprint still
314
+ covers the full normalized Flow while layers/components/diagnostics cover the returned subset.
315
+
316
+ The public API exposes zone positions and membership, not individual node pixel coordinates. The CLI
317
+ therefore preserves only supported zone-level visual metadata and never fabricates node coordinates.
318
+ Use the declarative export/apply loop for visual organization:
319
+
320
+ ```bash
321
+ dss flow-zone plan --project-key MYPROJ > flow-zones.json
322
+ dss flow-zone organize --file flow-zones.json --dry-run --project-key MYPROJ
323
+ dss flow-zone organize --file flow-zones.json --project-key MYPROJ
324
+ ```
325
+
326
+ `flow-zone plan` emits JSON accepted directly by `flow-zone organize`, including every
327
+ current zone's supported metadata and explicit items. Reapplying an unchanged plan produces no
328
+ redundant moves. `organize` compares the plan's topology fingerprint before mutation and recomputes
329
+ it after mutation; a mismatch fails rather than claiming a visual-only change. Zone names, colors,
330
+ positions, and membership are deliberately excluded from the fingerprint; flow node identity/kind and
331
+ edges are included.
332
+
333
+ Recipe/code analysis is a separate audit. `project map` and `flow-zone plan` do not fetch,
334
+ hash, interpret, or grade recipe payloads. Use the recipe inspection/diff/assertion commands in a
335
+ separate workflow when code quality or semantic review is required; never mix those findings into a
336
+ layout plan.
337
+
288
338
  ## Project Git source-control safety
289
339
 
290
340
  Project Git commands require DSS 12.4.2 or newer plus read and write access to the project
@@ -330,4 +380,81 @@ applies only to external project-library operations and does not persist a remot
330
380
  The `project-git` resource does not manage these settings, so public/auth-less and
331
381
  already-configured remotes are the supported automation paths.
332
382
 
383
+ ## Coding, notebooks, and project libraries
384
+
385
+ `project-library` manages files in a project's internal `lib/` tree. External Git-backed
386
+ libraries are a different surface: inspect and change those with `project-git list-libraries`,
387
+ `set-library`, `push-library`, and the related future commands. Internal paths are canonicalized;
388
+ leading slashes are removed, while traversal (`..`) and empty segments are rejected.
389
+
390
+ Use a read/diff/guarded-write sequence for internal files. `get-bytes` preserves binary data and
391
+ returns its SHA-256; `diff` caps text output and detects binary files instead of dumping bytes.
392
+ `put --expect-sha256` re-reads the remote bytes and refuses a stale overwrite. New files and
393
+ folders never overwrite existing items; `--if-not-exists` turns an existing target into a skip.
394
+
395
+ ```bash
396
+ dss project-library get-bytes python/mylib/utils.py --output ./utils.py --project-key MYPROJ
397
+ dss project-library diff python/mylib/utils.py --file ./utils.py --project-key MYPROJ
398
+ dss project-library put python/mylib/utils.py --file ./utils.py --expect-sha256 HASH --dry-run --project-key MYPROJ
399
+ dss project-library put python/mylib/utils.py --file ./utils.py --expect-sha256 HASH --project-key MYPROJ
400
+ ```
401
+
402
+ For one-off Python, prefer a file so shell quoting cannot change the source. `code run` creates an
403
+ observable throwaway custom-Python scenario, waits with a bounded timeout, caps returned logs, and
404
+ deletes only that generated scenario unless `--keep` is set.
405
+
406
+ ```bash
407
+ dss code run --file inspect.py --env py311 --project-key MYPROJ
408
+ dss recipe diff prepare_orders --file recipe.py --project-key MYPROJ
409
+ dss recipe set-payload prepare_orders --file recipe.py --dry-run --project-key MYPROJ
410
+ dss recipe set-payload prepare_orders --file recipe.py --backup-dir .dss-backups/recipes --project-key MYPROJ
411
+ dss recipe run prepare_orders --dry-run --project-key MYPROJ
412
+ ```
413
+
414
+ Recipe payload diffs normalize LF/CRLF. `set-payload` backs up payload, graph, settings, code-env,
415
+ and version metadata by default; use `restore --backup FILE --dry-run` before applying a rollback.
416
+ `recipe run --dry-run` performs live output resolution without creating a job; static
417
+ `--plan` reports `exact:false` rather than inventing that live payload.
418
+
419
+ Notebook saves are save-or-create operations. Read first, preserve the full notebook object, then
420
+ use the persisted hash from save/dry-run output with `--expect-hash`. Jupyter output clearing uses
421
+ the official DELETE endpoint. `unload-jupyter --all` is deliberately composed: list active
422
+ notebooks, list their sessions, then delete each session; DSS has no unload-all endpoint.
423
+
424
+ ```bash
425
+ dss notebook get-jupyter analysis.ipynb --project-key MYPROJ
426
+ dss notebook save-jupyter analysis.ipynb --data-file notebook.json --dry-run --project-key MYPROJ
427
+ dss notebook save-jupyter analysis.ipynb --data-file notebook.json --expect-hash HASH --project-key MYPROJ
428
+ dss notebook clear-jupyter-outputs analysis.ipynb --dry-run --project-key MYPROJ
429
+ dss notebook unload-jupyter --all --dry-run --project-key MYPROJ
430
+ ```
431
+
432
+ Code-environment reads expose definitions, deployment mode, installed/requested packages, project
433
+ versions, usages, and bounded build logs. Fetch the definition/hash before `set-definition` or
434
+ `set-packages --expect-hash`; package, image, Jupyter, create, and delete operations can return DSS
435
+ futures with `--no-wait`.
436
+
437
+ Webapp updates use GET–deep-merge–PUT; API-service `save-settings` is explicit full replacement.
438
+ Run either with `--dry-run` to inspect `currentHash`/`nextHash`, then apply with
439
+ `--expect-hash`. Webapp restart futures support `--wait`. API packages and project bundles
440
+ forward release notes and explicit Deployer target IDs.
441
+
442
+ An agent plan with `exact:false` is an honesty boundary: live state is required and no endpoint or
443
+ payload was guessed. Use the command's own `--dry-run` when it resolves that state. The supported
444
+ public DSS API exposes no plugin-authoring lifecycle, notebook execution/checkpoint operation, or
445
+ webapp/API-service delete. Use project Git for plugin source, `code run`/recipes for execution,
446
+ and the authenticated DSS UI for unsupported lifecycle operations.
447
+
333
448
  For fake-DSS smoke tests, return project lists as JSON arrays such as `[{ "projectKey": "MYPROJ", "name": "My Project" }]` from `/public/api/projects/`; recipe payload commands read `/public/api/projects/<PROJECT>/recipes/<NAME>?includePayload=true` and expect a JSON object shaped like `{ "recipe": { "name": "<NAME>", "type": "python" }, "payload": "..." }`.
449
+
450
+ ## License
451
+
452
+ This project is source-available under the [Dataiku SDK Limited Use License 1.0](LICENSE), not an open-source license.
453
+
454
+ - Individuals acting on their own behalf may use unmodified copies without a license fee.
455
+ - Companies with total annual gross revenue below US $1,000,000 may use unmodified copies without a license fee.
456
+ - Companies at or above that threshold, and all other entities, must request and obtain a separate written license before use.
457
+ - Every modification, including private or internal changes, and every form of redistribution requires prior written approval.
458
+ - Permitted use must preserve the license notices and display: `dataiku-sdk by clssck — https://github.com/clssck/dataiku-sdk`.
459
+
460
+ Copies previously received under another license retain the rights granted for those copies. See [LICENSE](LICENSE) for the controlling terms and request path.
@@ -1 +1 @@
1
- {"format":1,"buildRevision":"730725833d165213e28d6affee90bd3c1b012ec9"}
1
+ {"format":1,"buildRevision":"ceeb399ea1f0d7ea078db09da940b79fb732e2ad"}
@@ -430,7 +430,6 @@ export type ConnectionSummary = Static<typeof ConnectionSummarySchema>;
430
430
  export declare const CodeEnvSummarySchema: import("@sinclair/typebox").TObject<{
431
431
  envName: import("@sinclair/typebox").TString;
432
432
  envLang: import("@sinclair/typebox").TString;
433
- pythonInterpreter: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
434
433
  deploymentMode: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
435
434
  }>;
436
435
  export type CodeEnvSummary = Static<typeof CodeEnvSummarySchema>;
@@ -438,10 +437,42 @@ export declare const CodeEnvDetailsSchema: import("@sinclair/typebox").TObject<{
438
437
  envName: import("@sinclair/typebox").TString;
439
438
  envLang: import("@sinclair/typebox").TString;
440
439
  pythonInterpreter: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
440
+ deploymentMode: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
441
441
  requestedPackages: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
442
442
  installedPackages: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
443
+ definitionHash: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
443
444
  }>;
444
445
  export type CodeEnvDetails = Static<typeof CodeEnvDetailsSchema>;
446
+ export declare const CodeEnvLogSummarySchema: import("@sinclair/typebox").TObject<{
447
+ name: import("@sinclair/typebox").TString;
448
+ }>;
449
+ export type CodeEnvLogSummary = Static<typeof CodeEnvLogSummarySchema>;
450
+ export declare const CodeEnvLogSummaryArraySchema: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
451
+ name: import("@sinclair/typebox").TString;
452
+ }>>;
453
+ export type CodeEnvLogSummaryArray = Static<typeof CodeEnvLogSummaryArraySchema>;
454
+ export declare const CodeEnvLogResultSchema: import("@sinclair/typebox").TObject<{
455
+ log: import("@sinclair/typebox").TString;
456
+ bytes: import("@sinclair/typebox").TNumber;
457
+ truncated: import("@sinclair/typebox").TBoolean;
458
+ tailed: import("@sinclair/typebox").TBoolean;
459
+ }>;
460
+ export type CodeEnvLogResult = Static<typeof CodeEnvLogResultSchema>;
461
+ export declare const CodeEnvGetLogOptionsSchema: import("@sinclair/typebox").TObject<{
462
+ maxBytes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
463
+ maxLines: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
464
+ }>;
465
+ export type CodeEnvGetLogOptions = Static<typeof CodeEnvGetLogOptionsSchema>;
466
+ export declare const CodeEnvUpdateImagesOptionsSchema: import("@sinclair/typebox").TObject<{
467
+ envVersion: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
468
+ wait: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
469
+ }>;
470
+ export type CodeEnvUpdateImagesOptions = Static<typeof CodeEnvUpdateImagesOptionsSchema>;
471
+ export declare const CodeEnvVersionForProjectSchema: import("@sinclair/typebox").TObject<{
472
+ version: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
473
+ bundleId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
474
+ }>;
475
+ export type CodeEnvVersionForProject = Static<typeof CodeEnvVersionForProjectSchema>;
445
476
  export declare const CodeEnvActionResultSchema: import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TUnknown>;
446
477
  export type CodeEnvActionResult = Static<typeof CodeEnvActionResultSchema>;
447
478
  export declare const CodeEnvCreateOptionsSchema: import("@sinclair/typebox").TObject<{
@@ -457,6 +488,7 @@ export type CodeEnvPackageList = Static<typeof CodeEnvPackageListSchema>;
457
488
  export declare const CodeEnvSetPackagesOptionsSchema: import("@sinclair/typebox").TObject<{
458
489
  packages: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>]>;
459
490
  installCorePackages: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
491
+ expectHash: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
460
492
  }>;
461
493
  export type CodeEnvSetPackagesOptions = Static<typeof CodeEnvSetPackagesOptionsSchema>;
462
494
  export declare const CodeEnvUpdatePackagesOptionsSchema: import("@sinclair/typebox").TObject<{
@@ -583,7 +615,7 @@ export declare const DataQualityComputeResultSchema: import("@sinclair/typebox")
583
615
  export type DataQualityComputeResult = Static<typeof DataQualityComputeResultSchema>;
584
616
  export declare const JupyterCellSchema: import("@sinclair/typebox").TObject<{
585
617
  cell_type: import("@sinclair/typebox").TString;
586
- source: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
618
+ source: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>]>;
587
619
  metadata: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TUnknown>>;
588
620
  outputs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnknown>>;
589
621
  execution_count: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TNull, import("@sinclair/typebox").TNumber]>>;
@@ -606,7 +638,7 @@ export declare const JupyterNotebookContentSchema: import("@sinclair/typebox").T
606
638
  nbformat_minor: import("@sinclair/typebox").TNumber;
607
639
  cells: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
608
640
  cell_type: import("@sinclair/typebox").TString;
609
- source: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
641
+ source: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>]>;
610
642
  metadata: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TUnknown>>;
611
643
  outputs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnknown>>;
612
644
  execution_count: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TNull, import("@sinclair/typebox").TNumber]>>;
@@ -646,6 +678,9 @@ export declare const SqlNotebookContentSchema: import("@sinclair/typebox").TObje
646
678
  }>>;
647
679
  }>;
648
680
  export type SqlNotebookContent = Static<typeof SqlNotebookContentSchema>;
681
+ /** Execution history of a SQL notebook: cell ID to the runs recorded for it. */
682
+ export declare const SqlNotebookHistorySchema: import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnknown>>;
683
+ export type SqlNotebookHistory = Static<typeof SqlNotebookHistorySchema>;
649
684
  export declare const SqlQuerySchemaSchema: import("@sinclair/typebox").TObject<{
650
685
  name: import("@sinclair/typebox").TString;
651
686
  type: import("@sinclair/typebox").TString;
@@ -677,6 +712,7 @@ export declare const FlowMapOptionsSchema: import("@sinclair/typebox").TObject<{
677
712
  maxNodes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
678
713
  maxEdges: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
679
714
  includeRaw: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
715
+ render: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"ascii">, import("@sinclair/typebox").TLiteral<"mermaid">]>>;
680
716
  }>;
681
717
  export type FlowMapOptions = Static<typeof FlowMapOptionsSchema>;
682
718
  /**
@@ -853,7 +889,6 @@ export declare const FolderItemArraySchema: import("@sinclair/typebox").TArray<i
853
889
  export declare const CodeEnvSummaryArraySchema: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
854
890
  envName: import("@sinclair/typebox").TString;
855
891
  envLang: import("@sinclair/typebox").TString;
856
- pythonInterpreter: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
857
892
  deploymentMode: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
858
893
  }>>;
859
894
  export declare const WikiArticleDataArraySchema: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
@@ -444,16 +444,39 @@ export const ConnectionSummarySchema = Type.Object({
444
444
  export const CodeEnvSummarySchema = Type.Object({
445
445
  envName: Type.String(),
446
446
  envLang: Type.String(),
447
- pythonInterpreter: Type.Optional(Type.String()),
448
447
  deploymentMode: Type.Optional(Type.String()),
449
448
  }, { additionalProperties: true, });
450
449
  export const CodeEnvDetailsSchema = Type.Object({
451
450
  envName: Type.String(),
452
451
  envLang: Type.String(),
453
452
  pythonInterpreter: Type.Optional(Type.String()),
453
+ deploymentMode: Type.Optional(Type.String()),
454
454
  requestedPackages: Type.Array(Type.String()),
455
455
  installedPackages: Type.Array(Type.String()),
456
+ definitionHash: Type.Optional(Type.String()),
456
457
  });
458
+ export const CodeEnvLogSummarySchema = Type.Object({
459
+ name: Type.String(),
460
+ }, { additionalProperties: true, });
461
+ export const CodeEnvLogSummaryArraySchema = Type.Array(CodeEnvLogSummarySchema);
462
+ export const CodeEnvLogResultSchema = Type.Object({
463
+ log: Type.String(),
464
+ bytes: Type.Number(),
465
+ truncated: Type.Boolean(),
466
+ tailed: Type.Boolean(),
467
+ }, { additionalProperties: false, });
468
+ export const CodeEnvGetLogOptionsSchema = Type.Object({
469
+ maxBytes: Type.Optional(Type.Number()),
470
+ maxLines: Type.Optional(Type.Number()),
471
+ }, { additionalProperties: false, });
472
+ export const CodeEnvUpdateImagesOptionsSchema = Type.Object({
473
+ envVersion: Type.Optional(Type.String()),
474
+ wait: Type.Optional(Type.Boolean()),
475
+ }, { additionalProperties: false, });
476
+ export const CodeEnvVersionForProjectSchema = Type.Object({
477
+ version: Type.Optional(Type.String()),
478
+ bundleId: Type.Optional(Type.String()),
479
+ }, { additionalProperties: true, });
457
480
  export const CodeEnvActionResultSchema = Type.Record(Type.String(), Type.Unknown());
458
481
  export const CodeEnvCreateOptionsSchema = Type.Object({
459
482
  envLang: Type.String(),
@@ -469,6 +492,7 @@ export const CodeEnvPackageListSchema = Type.Union([
469
492
  export const CodeEnvSetPackagesOptionsSchema = Type.Object({
470
493
  packages: CodeEnvPackageListSchema,
471
494
  installCorePackages: Type.Optional(Type.Boolean()),
495
+ expectHash: Type.Optional(Type.String()),
472
496
  }, { additionalProperties: false, });
473
497
  export const CodeEnvUpdatePackagesOptionsSchema = Type.Object({
474
498
  forceRebuildEnv: Type.Optional(Type.Boolean()),
@@ -569,7 +593,9 @@ export const DataQualityComputeResultSchema = Type.Object({
569
593
  // ---------------------------------------------------------------------------
570
594
  export const JupyterCellSchema = Type.Object({
571
595
  cell_type: Type.String(),
572
- source: Type.Array(Type.String()),
596
+ // nbformat permits a cell's source to be either a single string or an
597
+ // array of strings; DSS returns whichever form the notebook carries.
598
+ source: Type.Union([Type.String(), Type.Array(Type.String()),]),
573
599
  metadata: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
574
600
  outputs: Type.Optional(Type.Array(Type.Unknown())),
575
601
  execution_count: Type.Optional(Type.Union([Type.Null(), Type.Number(),])),
@@ -617,6 +643,8 @@ export const SqlNotebookContentSchema = Type.Object({
617
643
  connection: Type.String(),
618
644
  cells: Type.Array(SqlNotebookCellSchema),
619
645
  }, { additionalProperties: true, });
646
+ /** Execution history of a SQL notebook: cell ID to the runs recorded for it. */
647
+ export const SqlNotebookHistorySchema = Type.Record(Type.String(), Type.Array(Type.Unknown()));
620
648
  // ---------------------------------------------------------------------------
621
649
  // SQL Queries
622
650
  // ---------------------------------------------------------------------------
@@ -642,6 +670,7 @@ export const FlowMapOptionsSchema = Type.Object({
642
670
  maxNodes: Type.Optional(Type.Number()),
643
671
  maxEdges: Type.Optional(Type.Number()),
644
672
  includeRaw: Type.Optional(Type.Boolean()),
673
+ render: Type.Optional(Type.Union([Type.Literal("ascii"), Type.Literal("mermaid"),])),
645
674
  });
646
675
  // ---------------------------------------------------------------------------
647
676
  // Project Git
@@ -1,5 +1,15 @@
1
+ import { ClientValidationError, } from "../../errors.js";
2
+ import { stableHash, } from "../../utils/stable-hash.js";
1
3
  import { requiredJsonInput, } from "../coerce.js";
2
4
  import { requireArgs, UsageError, } from "../usage.js";
5
+ function validateExpectHash(value) {
6
+ if (value === undefined || value === false)
7
+ return undefined;
8
+ if (typeof value !== "string" || !/^[0-9a-fA-F]{64}$/.test(value)) {
9
+ throw new ClientValidationError("Expected API service settings hash must be a 64-character SHA-256 hex digest.", "validation_failed", "Run this update with --dry-run and capture currentHash before retrying.");
10
+ }
11
+ return value;
12
+ }
3
13
  export const apiServiceCommands = {
4
14
  list: {
5
15
  handler: (c, _a, f) => c.apiServices.list(f["project-key"]),
@@ -26,14 +36,42 @@ export const apiServiceCommands = {
26
36
  examples: ["dss api-service get-settings my-service",],
27
37
  },
28
38
  "save-settings": {
29
- handler: (c, a, f) => {
30
- requireArgs(a, 1, "dss api-service save-settings <serviceId> (--data JSON|--data-file PATH|--stdin) [--project-key KEY]");
39
+ handler: async (c, a, f) => {
40
+ const usage = "dss api-service save-settings <serviceId> (--data JSON|--data-file PATH|--stdin) [--expect-hash SHA256] [--dry-run] [--project-key KEY]";
41
+ requireArgs(a, 1, usage);
31
42
  const body = requiredJsonInput(f, "--data, --data-file, or --stdin is required (service settings).");
32
- return c.apiServices.saveSettings(a[0], body, f["project-key"]);
43
+ const projectKey = f["project-key"];
44
+ const expectHash = validateExpectHash(f["expect-hash"]);
45
+ if (f["dry-run"] === true) {
46
+ const current = await c.apiServices.getSettings(a[0], projectKey);
47
+ const currentHash = stableHash(current);
48
+ if (expectHash !== undefined && currentHash !== expectHash.toLowerCase()) {
49
+ throw new ClientValidationError(`The API service ${JSON.stringify(a[0])} changed since it was read.`, "validation_failed", "Re-read the service settings and retry with the current hash value.", {
50
+ serviceId: a[0],
51
+ expectedHash: expectHash.toLowerCase(),
52
+ actualHash: currentHash,
53
+ });
54
+ }
55
+ return {
56
+ dryRun: true,
57
+ action: "save-settings",
58
+ resource: "api-service",
59
+ serviceId: a[0],
60
+ current,
61
+ next: body,
62
+ currentHash,
63
+ nextHash: stableHash(body),
64
+ ...(expectHash !== undefined
65
+ ? { expectHash: expectHash.toLowerCase(), provenanceVerified: true, }
66
+ : {}),
67
+ };
68
+ }
69
+ const saved = await c.apiServices.saveSettings(a[0], body, projectKey, { expectHash, });
70
+ return { saved: a[0], ...saved, };
33
71
  },
34
- usage: "dss api-service save-settings <serviceId> (--data JSON|--data-file PATH|--stdin) [--project-key KEY]",
35
- description: "Save an API service's settings.",
36
- examples: ["dss api-service save-settings my-service --data-file service.json",],
72
+ usage: "dss api-service save-settings <serviceId> (--data JSON|--data-file PATH|--stdin) [--expect-hash SHA256] [--dry-run] [--project-key KEY]",
73
+ description: "Replace an API service's settings wholesale (explicit replacement: the supplied object is PUT as-is, so fetch get-settings first). --expect-hash refuses the write when the stored settings changed since they were fetched; --dry-run reports current, next, and both hashes without writing.",
74
+ examples: ["dss api-service save-settings my-service --data-file service.json --dry-run",],
37
75
  },
38
76
  "add-prediction-endpoint": {
39
77
  handler: async (c, a, f) => {
@@ -75,12 +113,15 @@ export const apiServiceCommands = {
75
113
  },
76
114
  "create-package": {
77
115
  handler: (c, a, f) => {
78
- requireArgs(a, 2, "dss api-service create-package <serviceId> <packageId> [--project-key KEY]");
79
- return c.apiServices.createPackage(a[0], a[1], f["project-key"]);
116
+ requireArgs(a, 2, "dss api-service create-package <serviceId> <packageId> [--release-notes TEXT] [--project-key KEY]");
117
+ return c.apiServices.createPackage(a[0], a[1], f["project-key"], typeof f["release-notes"] === "string" ? { releaseNotes: f["release-notes"], } : {});
80
118
  },
81
- usage: "dss api-service create-package <serviceId> <packageId> [--project-key KEY]",
82
- description: "Build a deployable package from the current service state.",
83
- examples: ["dss api-service create-package my-service v1",],
119
+ usage: "dss api-service create-package <serviceId> <packageId> [--release-notes TEXT] [--project-key KEY]",
120
+ description: "Build a deployable package from the current service state; --release-notes forwards the documented releaseNotes query parameter.",
121
+ examples: [
122
+ "dss api-service create-package my-service v1",
123
+ "dss api-service create-package my-service v1 --release-notes='Adds churn endpoint'",
124
+ ],
84
125
  },
85
126
  "delete-package": {
86
127
  handler: async (c, a, f) => {
@@ -111,11 +152,16 @@ export const apiServiceCommands = {
111
152
  },
112
153
  "publish-package": {
113
154
  handler: (c, a, f) => {
114
- requireArgs(a, 2, "dss api-service publish-package <serviceId> <packageId> [--project-key KEY]");
115
- return c.apiServices.publishPackage(a[0], a[1], f["project-key"]);
155
+ requireArgs(a, 2, "dss api-service publish-package <serviceId> <packageId> [--published-service-id ID] [--project-key KEY]");
156
+ return c.apiServices.publishPackage(a[0], a[1], f["project-key"], typeof f["published-service-id"] === "string"
157
+ ? { publishedServiceId: f["published-service-id"], }
158
+ : {});
116
159
  },
117
- usage: "dss api-service publish-package <serviceId> <packageId> [--project-key KEY]",
118
- description: "Publish a package to the API Deployer.",
119
- examples: ["dss api-service publish-package my-service v1",],
160
+ usage: "dss api-service publish-package <serviceId> <packageId> [--published-service-id ID] [--project-key KEY]",
161
+ description: "Publish a package to the API Deployer; --published-service-id forwards the documented publishedServiceId query parameter (a new published service is created when no match exists; the service's own id is the server-side default).",
162
+ examples: [
163
+ "dss api-service publish-package my-service v1",
164
+ "dss api-service publish-package my-service v1 --published-service-id=prod-churn",
165
+ ],
120
166
  },
121
167
  };