dataiku-sdk 0.12.4 → 0.12.5

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 (84) hide show
  1. package/README.md +118 -7
  2. package/dist/packages/types/src/index.d.ts +5 -0
  3. package/dist/packages/types/src/index.js +5 -0
  4. package/dist/src/cli/coerce.d.ts +1 -3
  5. package/dist/src/cli/coerce.js +1 -17
  6. package/dist/src/cli/commands/app.js +709 -14
  7. package/dist/src/cli/commands/code-env.js +2 -2
  8. package/dist/src/cli/commands/dashboard.js +1 -1
  9. package/dist/src/cli/commands/dataset.js +2 -2
  10. package/dist/src/cli/commands/folder.js +1 -1
  11. package/dist/src/cli/commands/insight.js +2 -2
  12. package/dist/src/cli/commands/notebook.js +2 -2
  13. package/dist/src/cli/commands/recipe.js +3 -3
  14. package/dist/src/cli/commands/scenario.js +1 -1
  15. package/dist/src/cli/commands/sql.js +1 -1
  16. package/dist/src/cli/commands/variable.js +1 -1
  17. package/dist/src/cli/commands/wiki.js +1 -1
  18. package/dist/src/cli/contract.d.ts +12 -3
  19. package/dist/src/cli/contract.js +805 -49
  20. package/dist/src/cli/flags.js +8 -0
  21. package/dist/src/cli/helpers/app-permissions.d.ts +63 -0
  22. package/dist/src/cli/helpers/app-permissions.js +239 -0
  23. package/dist/src/cli/helpers/app-successor.d.ts +106 -0
  24. package/dist/src/cli/helpers/app-successor.js +625 -0
  25. package/dist/src/cli/helpers/cleanup.js +46 -12
  26. package/dist/src/cli/output.d.ts +12 -1
  27. package/dist/src/cli/output.js +53 -6
  28. package/dist/src/cli/usage.d.ts +1 -1
  29. package/dist/src/cli/usage.js +5 -2
  30. package/dist/src/cli.js +329 -32
  31. package/dist/src/client.d.ts +6 -0
  32. package/dist/src/client.js +28 -1
  33. package/dist/src/errors.d.ts +1 -1
  34. package/dist/src/resources/applications.d.ts +191 -1
  35. package/dist/src/resources/applications.js +549 -10
  36. package/dist/src/resources/datasets.js +8 -0
  37. package/dist/src/resources/futures.js +7 -2
  38. package/dist/src/skill.js +76 -18
  39. package/dist/src/utils/cleanup-ledger.d.ts +34 -1
  40. package/dist/src/utils/cleanup-ledger.js +118 -7
  41. package/dist/src/utils/dss-url.d.ts +6 -0
  42. package/dist/src/utils/dss-url.js +17 -0
  43. package/dist/src/utils/project-incarnation.d.ts +6 -0
  44. package/dist/src/utils/project-incarnation.js +27 -0
  45. package/dist/src/utils/stable-hash.d.ts +11 -0
  46. package/dist/src/utils/stable-hash.js +27 -0
  47. package/node_modules/@sinclair/typebox/build/cjs/compiler/compiler.js +26 -46
  48. package/node_modules/@sinclair/typebox/build/cjs/parser/runtime/guard.d.ts +1 -1
  49. package/node_modules/@sinclair/typebox/build/cjs/parser/runtime/token.d.ts +2 -2
  50. package/node_modules/@sinclair/typebox/build/cjs/syntax/mapping.d.ts +1 -1
  51. package/node_modules/@sinclair/typebox/build/cjs/system/evaluate.d.ts +5 -0
  52. package/node_modules/@sinclair/typebox/build/cjs/system/evaluate.js +11 -0
  53. package/node_modules/@sinclair/typebox/build/cjs/system/index.d.ts +1 -0
  54. package/node_modules/@sinclair/typebox/build/cjs/system/index.js +1 -0
  55. package/node_modules/@sinclair/typebox/build/cjs/type/object/object.d.ts +2 -2
  56. package/node_modules/@sinclair/typebox/build/cjs/type/object/object.js +18 -2
  57. package/node_modules/@sinclair/typebox/build/cjs/value/parse/parse.d.ts +1 -1
  58. package/node_modules/@sinclair/typebox/build/esm/compiler/compiler.mjs +27 -47
  59. package/node_modules/@sinclair/typebox/build/esm/parser/runtime/guard.d.mts +1 -1
  60. package/node_modules/@sinclair/typebox/build/esm/parser/runtime/token.d.mts +2 -2
  61. package/node_modules/@sinclair/typebox/build/esm/syntax/mapping.d.mts +1 -1
  62. package/node_modules/@sinclair/typebox/build/esm/system/evaluate.d.mts +5 -0
  63. package/node_modules/@sinclair/typebox/build/esm/system/evaluate.mjs +7 -0
  64. package/node_modules/@sinclair/typebox/build/esm/system/index.d.mts +1 -0
  65. package/node_modules/@sinclair/typebox/build/esm/system/index.mjs +1 -0
  66. package/node_modules/@sinclair/typebox/build/esm/type/composite/composite.mjs +2 -2
  67. package/node_modules/@sinclair/typebox/build/esm/type/const/const.mjs +3 -3
  68. package/node_modules/@sinclair/typebox/build/esm/type/instantiate/instantiate.mjs +2 -2
  69. package/node_modules/@sinclair/typebox/build/esm/type/mapped/mapped.mjs +3 -3
  70. package/node_modules/@sinclair/typebox/build/esm/type/module/compute.mjs +2 -2
  71. package/node_modules/@sinclair/typebox/build/esm/type/object/object.d.mts +2 -2
  72. package/node_modules/@sinclair/typebox/build/esm/type/object/object.mjs +18 -2
  73. package/node_modules/@sinclair/typebox/build/esm/type/omit/omit.mjs +3 -3
  74. package/node_modules/@sinclair/typebox/build/esm/type/partial/partial.mjs +3 -3
  75. package/node_modules/@sinclair/typebox/build/esm/type/pick/pick.mjs +3 -3
  76. package/node_modules/@sinclair/typebox/build/esm/type/record/record.mjs +3 -3
  77. package/node_modules/@sinclair/typebox/build/esm/type/required/required.mjs +3 -3
  78. package/node_modules/@sinclair/typebox/build/esm/type/type/json.mjs +2 -2
  79. package/node_modules/@sinclair/typebox/build/esm/value/delta/delta.mjs +4 -4
  80. package/node_modules/@sinclair/typebox/build/esm/value/parse/parse.d.mts +1 -1
  81. package/node_modules/@sinclair/typebox/package.json +1 -1
  82. package/package.json +7 -5
  83. package/packages/types/dist/index.d.ts +5 -0
  84. package/packages/types/dist/index.js +5 -0
package/README.md CHANGED
@@ -23,23 +23,28 @@ Bun is the primary development runtime and package manager. Examples below assum
23
23
 
24
24
  ## CLI contract
25
25
 
26
- - Success: stdout contains one JSON result.
27
- - Failure: stderr contains one JSONL error event with `type:"error"`, `ok:false`, `error`, `code`, and `exitCode`.
26
+ - Command results write exactly one JSON value to stdout, including `doctor`, `batch`, and `cleanup` failure reports; use the exit code and result fields.
27
+ - Dispatch/runtime failures write one JSONL error event to stderr with `type:"error"`, `ok:false`, `error`, `code`, and `exitCode`, while stdout stays empty.
28
28
  - Non-fatal diagnostics and `--verbose` traces are JSONL stderr events (`type:"warning"` / `type:"trace"`); no prose trace lines are part of the contract.
29
29
  - `--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.
30
30
  - No prompts, help screens, tables, banners, or prose output are part of the contract.
31
- - Exit codes: `0` success, `1` usage/configuration error, `2` DSS/internal error, `3` transient DSS error, `4` completed command with failed long-running DSS work.
31
+ - 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.
32
32
  - 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.
33
33
  - `--raw` is only for recipe payload commands. Without `--output`, stdout is raw bytes; with `--output PATH`, stdout is the JSON string equal to `PATH` and the file contains the exact raw bytes.
34
34
 
35
- Discover the agent protocol and complete machine-readable command surface:
35
+ Discover the agent contract and command surface with compact, scoped, `--json` calls:
36
36
 
37
37
  ```text
38
- dss agent contract
39
- dss commands run
38
+ dss agent contract --fields protocol,agentContractVersion,cli,stdio,planning,compatibility --json
39
+ dss commands run --fields dataset.create --json
40
+ dss commands run --fields dataset.create.usage,dataset.create.description,dataset.create.flags,dataset.create.examples --json
41
+ dss commands run --fields dataset --json
42
+ dss agent contract --fields commands.actions --json
40
43
  ```
41
44
 
42
- Agents should parse `agent contract` once for protocol/schema compatibility, then parse `commands run` before choosing syntax; inspect `flags`, `structuredExamples`, `schemas`, `requiresAuth`, `requiresProject`, `sideEffect`, `unsafeOutputs`, and `outputShape` instead of guessing.
45
+ For JSON outputs, prefer `--json`: compact single-line JSON cuts the full registry's context usage by about 40% (~220k tokens versus ~358k pretty-printed). Bootstrap by scoping `agent contract` to `protocol,agentContractVersion,cli,stdio,planning,compatibility` (~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, 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.
46
+
47
+ `--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": {...}}`). Enumerate every resource and action with `dss agent contract --fields commands.actions --json` (~1k tokens); the ~220k-token unscoped registry remains a compatibility surface, not a discovery workflow. An unknown resource or action exits with code 1 and a JSON error envelope on stderr containing the valid options.
43
48
 
44
49
  ## Agent skill installation
45
50
 
@@ -116,6 +121,112 @@ dss recipe get-payload compute_orders --project-key MYPROJ
116
121
  dss recipe get-payload compute_orders --raw --project-key MYPROJ
117
122
  dss recipe get-payload compute_orders --raw --output code.py --project-key MYPROJ
118
123
  dss install-skill --dry-run
124
+ dss app validate-manifest --project-key MYAPP_INSTANCE
125
+ dss app compare-manifest my-app --project-key MYAPP_INSTANCE
126
+ dss app create-instance my-app --data '{"targetProjectKey":"MYAPP_INSTANCE"}' --wait --record-cleanup cleanup.jsonl
127
+ dss app manifest-version --project-key MYAPP_TEMPLATE
128
+ dss app set-manifest-version --manifest-version 1.4.0 --project-key MYAPP_TEMPLATE
129
+ dss app create-successor-instance my-app --from MYAPP_INSTANCE --to MYAPP_INSTANCE_V2 --copy-permissions --record-cleanup cleanup.jsonl
130
+ dss app verify-instance my-app --project-key MYAPP_INSTANCE_V2 --expect-version 1.4.0
131
+ dss app permissions-snapshot --project-key MYAPP_INSTANCE --output permissions.json
132
+ dss app permissions-diff --project-key MYAPP_INSTANCE --file permissions.json
133
+ dss app permissions-restore --project-key MYAPP_INSTANCE --file permissions.json --dry-run
134
+ dss cleanup --file cleanup.jsonl
135
+ dss cleanup --file cleanup.jsonl --apply
119
136
  ```
120
137
 
138
+ ### Application release safety
139
+
140
+ Use the app commands as explicit release gates around a stable template, instance project key,
141
+ and permission set:
142
+
143
+ ```bash
144
+ # Validate source-verifiable manifest references.
145
+ dss app validate-manifest --project-key APP_TEMPLATE
146
+
147
+ # Detect governed template/instance drift. Only projectKey and projectAppType are normalized away.
148
+ dss app compare-manifest APP_ID --project-key RELEASE_INSTANCE
149
+
150
+ # Read the raw `version` from the public app manifest (string fields only; never appVersion).
151
+ dss app manifest-version --project-key APP_TEMPLATE
152
+
153
+ # Write version/versionNotes through the public app-manifest endpoint. This is NOT a publish
154
+ # transaction: it only changes the raw manifest metadata. --expect-hash SHA256 is a non-atomic
155
+ # stale-read guard, not a conditional write: it refuses the write when the manifest already
156
+ # changed since you read that hash, but DSS accepts every PUT unconditionally. This command can
157
+ # overwrite a write landing between its read and PUT, and the final read cannot detect that lost
158
+ # update when this command's payload wins. Every result reports
159
+ # concurrencyControl: "client-side-non-atomic-stale-read-check".
160
+ dss app set-manifest-version --manifest-version 1.4.0 --project-key APP_TEMPLATE
161
+
162
+ # Create an instance only after its target key is confirmed absent, wait on the DSS future, and
163
+ # record deterministic cleanup.
164
+ dss app create-instance APP_ID \
165
+ --data '{"targetProjectKey":"RELEASE_INSTANCE","targetProjectName":"Release instance"}' \
166
+ --wait --record-cleanup cleanup.jsonl
167
+
168
+ # Roll out a new template version to an existing instance as an additive successor: the old
169
+ # instance is never modified or deleted, and the command always waits on the DSS future
170
+ # (there is no --wait flag). The recorded cleanup entry targets only the new project key. If DSS
171
+ # accepts creation but returns no future ID, cleanup stops unresolved instead of racing creation.
172
+ dss app create-successor-instance APP_ID \
173
+ --from RELEASE_INSTANCE --to RELEASE_INSTANCE_V2 \
174
+ --name "Release instance v2" --copy-permissions --record-cleanup cleanup.jsonl
175
+
176
+ # API readiness gate for the successor. apiReady:true with status API_VERIFIED_UI_PENDING is an
177
+ # API-verified state only — never visual verification. The API key authenticates public REST only;
178
+ # visual confirmation stays an external SSO gate (pre-authenticated SSO browser session or a
179
+ # dedicated UI test identity).
180
+ dss app verify-instance APP_ID --project-key RELEASE_INSTANCE_V2 --expect-version 1.4.0
181
+
182
+ # Retirement of the predecessor is a separate, separately guarded step after the successor is
183
+ # verified. It is never performed implicitly by the successor flow.
184
+ dss app delete-instance --project-key RELEASE_INSTANCE
185
+
186
+ # Snapshot, compare, preview, and restore project permissions.
187
+ dss app permissions-snapshot --project-key RELEASE_INSTANCE --output permissions.json
188
+ dss app permissions-diff --project-key RELEASE_INSTANCE --file permissions.json
189
+ dss app permissions-restore --project-key RELEASE_INSTANCE --file permissions.json --dry-run
190
+ dss app permissions-restore --project-key RELEASE_INSTANCE --file permissions.json
191
+ ```
192
+
193
+ Permission snapshots are written with mode `0600` and an integrity hash covering the canonical DSS
194
+ URL, the concrete project incarnation (`creationTag`), capture metadata, and permissions. Diff and
195
+ restore reject snapshots from another DSS server, project key, or observed incarnation. These are
196
+ client-side, non-atomic stale-identity checks: DSS exposes no conditional permission PUT, so the
197
+ checks narrow and detect key-reuse races but cannot serialize the final check with the write.
198
+ Snapshots contain access-control identities; commit them only when repository policy permits.
199
+ `validate-manifest` checks `SCENARIO_RUN` scenario IDs, `DOWNLOAD_FILE`
200
+ managed-folder IDs, and runtime-form parameter names against supported public project APIs.
201
+
202
+ Some DSS deployments hide unknown project keys behind `403` instead of returning `404`.
203
+ Instance creation requires confirmed target absence before POST: an inaccessible target not present
204
+ in the visible project list is still unconfirmed and is rejected rather than risking cleanup
205
+ against a pre-existing project. A definitive create rejection never produces a cleanup entry.
206
+
207
+ Every new cleanup entry records the canonical DSS URL. App-instance cleanup records a
208
+ `creationTag` hash observed after the DSS future identifies the target key; unconfirmed creation
209
+ stops unresolved. The future target and later `creationTag` are independent, non-atomic
210
+ observations: the public API exposes neither an immutable project ID joined to the future nor a
211
+ conditional DELETE. Cleanup rechecks type and `creationTag` immediately before deletion, rejecting
212
+ detected key reuse, but cannot eliminate replacement in the remaining check-to-DELETE gap.
213
+ `cleanup --apply` validates the full ledger before issuing any request and rejects legacy entries
214
+ without server identity, mixed-server ledgers, entries for another DSS URL, and app cleanup entries
215
+ without a valid incarnation binding.
216
+
217
+ Saving `version`/`versionNotes` in the public app manifest is a metadata write, not a publish
218
+ transaction. If the manifest PUT or its verification read has an ambiguous transport/server
219
+ failure, the command exits non-zero with `persisted:null`, `after:null`, and
220
+ `outcome:"indeterminate"` rather than claiming the write failed or succeeded. Existing instances
221
+ are never upgraded in place: new instances inherit the template's
222
+ raw `version`, and an existing instance is rolled forward by creating an additive successor (the
223
+ old instance is preserved) followed by a separate, guarded retirement. `verify-instance` never
224
+ reports visual verification: its output is `apiReady:true` with
225
+ `status:"API_VERIFIED_UI_PENDING"` and `uiPublicationVerified:false`. Its `visual-ui` gate names
226
+ the required authentication and evidence: open the instance in a pre-authenticated SSO browser or
227
+ with a dedicated UI test identity, then exercise the affected tiles, forms, and actions. The CLI
228
+ never marks that external check complete. The public DSS APIs used by this SDK do not expose a
229
+ supported app-template publish/recreate/rename workflow, recipient-level app sharing setter, or
230
+ UI-click smoke test. The CLI does not guess private endpoints for those operations.
231
+
121
232
  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": "..." }`.
@@ -30,6 +30,11 @@ export declare const ProjectDetailsSchema: import("@sinclair/typebox").TObject<{
30
30
  name: import("@sinclair/typebox").TString;
31
31
  shortDesc: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
32
32
  projectStatus: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
33
+ projectAppType: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
34
+ creationTag: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
35
+ versionNumber: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
36
+ lastModifiedOn: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TNumber, import("@sinclair/typebox").TString]>>;
37
+ }>>;
33
38
  ownerLogin: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
34
39
  tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
35
40
  versionTag: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
@@ -86,6 +86,11 @@ export const ProjectDetailsSchema = Type.Object({
86
86
  name: Type.String(),
87
87
  shortDesc: Type.Optional(Type.String()),
88
88
  projectStatus: Type.Optional(Type.String()),
89
+ projectAppType: Type.Optional(Type.String()),
90
+ creationTag: Type.Optional(Type.Object({
91
+ versionNumber: Type.Optional(Type.Number()),
92
+ lastModifiedOn: Type.Optional(Type.Union([Type.Number(), Type.String(),])),
93
+ }, { additionalProperties: true, })),
89
94
  ownerLogin: Type.Optional(Type.String()),
90
95
  tags: Type.Optional(Type.Array(Type.String())),
91
96
  versionTag: Type.Optional(Type.Object({
@@ -4,10 +4,8 @@ export declare function jobBuildTargetType(v: string | boolean | undefined): Job
4
4
  export declare function jobBuildTargetTypeFromFlags(flags: Record<string, string | boolean>): JobBuildTargetType;
5
5
  export declare function maxLogLinesFromFlags(flags: Record<string, string | boolean>): number | undefined;
6
6
  export declare function jobLogFilterFromFlag(v: string | boolean | undefined): JobLogFilter | undefined;
7
- export declare function sha256Hex(value: string): string;
7
+ export { sha256Hex, stableHash, stableJson, } from "../utils/stable-hash.js";
8
8
  export declare function normalizeLineEndings(value: string): string;
9
- export declare function stableJson(value: unknown): string;
10
- export declare function stableHash(value: unknown): string;
11
9
  export declare function splitCsvFlag(v: string | boolean | undefined): string[];
12
10
  export declare function recipeInputDatasetsFromFlags(flags: Record<string, string | boolean>): string[] | undefined;
13
11
  export declare function rewritePairsFromFlags(flags: Record<string, string | boolean>, flagName: string): Record<string, string>;
@@ -1,4 +1,3 @@
1
- import { createHash, } from "node:crypto";
2
1
  import { readFileSync, } from "node:fs";
3
2
  import { UsageError, } from "./usage.js";
4
3
  export function num(v) {
@@ -37,25 +36,10 @@ export function jobLogFilterFromFlag(v) {
37
36
  }
38
37
  throw new UsageError("Invalid --log-filter value. Use stdout, stderr, user, or errors.", "invalid_enum");
39
38
  }
40
- export function sha256Hex(value) {
41
- return createHash("sha256").update(value).digest("hex");
42
- }
39
+ export { sha256Hex, stableHash, stableJson, } from "../utils/stable-hash.js";
43
40
  export function normalizeLineEndings(value) {
44
41
  return value.replace(/\r\n/g, "\n");
45
42
  }
46
- export function stableJson(value) {
47
- if (value === undefined)
48
- return "undefined";
49
- if (value === null || typeof value !== "object")
50
- return JSON.stringify(value);
51
- if (Array.isArray(value))
52
- return `[${value.map((item) => stableJson(item)).join(",")}]`;
53
- const entries = Object.entries(value).sort(([a,], [b,]) => a.localeCompare(b));
54
- return `{${entries.map(([key, item,]) => `${JSON.stringify(key)}:${stableJson(item)}`).join(",")}}`;
55
- }
56
- export function stableHash(value) {
57
- return sha256Hex(stableJson(value));
58
- }
59
43
  export function splitCsvFlag(v) {
60
44
  if (typeof v !== "string")
61
45
  return [];