dataiku-sdk 0.12.6 → 1.0.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 (55) hide show
  1. package/README.md +60 -14
  2. package/bin/dss.js +1 -1
  3. package/dist/packages/types/src/index.d.ts +128 -3
  4. package/dist/packages/types/src/index.js +106 -3
  5. package/dist/src/cli/coerce.d.ts +2 -1
  6. package/dist/src/cli/coerce.js +84 -26
  7. package/dist/src/cli/commands/app.js +6 -6
  8. package/dist/src/cli/commands/code.js +2 -2
  9. package/dist/src/cli/commands/dashboard.js +102 -13
  10. package/dist/src/cli/commands/data-quality.js +8 -8
  11. package/dist/src/cli/commands/dataset.js +11 -7
  12. package/dist/src/cli/commands/folder.js +5 -4
  13. package/dist/src/cli/commands/future.js +2 -2
  14. package/dist/src/cli/commands/index.js +2 -0
  15. package/dist/src/cli/commands/job.js +11 -11
  16. package/dist/src/cli/commands/notebook.js +1 -1
  17. package/dist/src/cli/commands/project-git.d.ts +2 -0
  18. package/dist/src/cli/commands/project-git.js +563 -0
  19. package/dist/src/cli/commands/project.js +2 -2
  20. package/dist/src/cli/commands/recipe.js +14 -17
  21. package/dist/src/cli/commands/scenario.js +4 -4
  22. package/dist/src/cli/contract.d.ts +5 -4
  23. package/dist/src/cli/contract.js +432 -62
  24. package/dist/src/cli/doctor.js +6 -6
  25. package/dist/src/cli/flags.js +25 -2
  26. package/dist/src/cli/helpers/dataset.js +1 -1
  27. package/dist/src/cli/output.d.ts +2 -1
  28. package/dist/src/cli/output.js +2 -6
  29. package/dist/src/cli/usage.d.ts +1 -1
  30. package/dist/src/cli/usage.js +2 -1
  31. package/dist/src/cli/version.d.ts +2 -2
  32. package/dist/src/cli/version.js +2 -2
  33. package/dist/src/cli.js +43 -26
  34. package/dist/src/client.d.ts +4 -0
  35. package/dist/src/client.js +12 -0
  36. package/dist/src/errors.d.ts +1 -1
  37. package/dist/src/index.d.ts +3 -2
  38. package/dist/src/index.js +2 -1
  39. package/dist/src/resources/connections.d.ts +3 -1
  40. package/dist/src/resources/connections.js +82 -21
  41. package/dist/src/resources/dashboards.d.ts +14 -0
  42. package/dist/src/resources/dashboards.js +156 -4
  43. package/dist/src/resources/datasets.js +42 -2
  44. package/dist/src/resources/folders.js +7 -3
  45. package/dist/src/resources/project-git.d.ts +154 -0
  46. package/dist/src/resources/project-git.js +427 -0
  47. package/dist/src/resources/recipes.js +4 -4
  48. package/dist/src/schemas.d.ts +2 -2
  49. package/dist/src/schemas.js +1 -1
  50. package/dist/src/skill.js +9 -211
  51. package/package.json +7 -4
  52. package/packages/types/dist/index.d.ts +128 -3
  53. package/packages/types/dist/index.js +106 -3
  54. package/plugin.json +15 -0
  55. package/skills/dataiku-dss/SKILL.md +220 -0
package/README.md CHANGED
@@ -23,29 +23,31 @@ Bun is the primary development runtime and package manager. Examples below assum
23
23
 
24
24
  ## CLI contract
25
25
 
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
- - Non-fatal diagnostics and `--verbose` traces are JSONL stderr events (`type:"warning"` / `type:"trace"`); no prose trace lines are part of the contract.
26
+ - 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.
27
+ - 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.
28
+ - 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.
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
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
  - `--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.
33
33
  - 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.
34
- - `--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
+ - 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`.
35
35
 
36
- Discover the agent contract and command surface with compact, scoped, `--json` calls:
36
+ Discover the agent contract and command surface with scoped calls:
37
37
 
38
38
  ```text
39
- dss agent contract --fields protocol,agentContractVersion,cli,stdio,planning,compatibility --json
40
- dss commands run --fields dataset.create --json
41
- dss commands run --fields dataset.create.usage,dataset.create.description,dataset.create.flags,dataset.create.examples --json
42
- dss commands run --fields dataset --json
43
- dss agent contract --fields commands.actions --json
39
+ dss commands run
40
+ dss commands run --fields dataset
41
+ dss commands run --fields dataset.create
42
+ dss commands run --fields dataset.create.usage,dataset.create.description,dataset.create.flags,dataset.create.examples
43
+ dss commands run --output commands.json
44
+ dss agent contract --fields protocol,agentContractVersion,cli,stdio,planning,compatibility
45
+ dss agent contract --fields commands.actions
44
46
  ```
45
47
 
46
- 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.
48
+ `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.
47
49
 
48
- `--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.
50
+ `--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
51
 
50
52
  ## Agent skill installation
51
53
 
@@ -119,8 +121,7 @@ dss doctor --fast
119
121
  dss project list
120
122
  dss dataset list --project-key MYPROJ
121
123
  dss recipe get-payload compute_orders --project-key MYPROJ
122
- dss recipe get-payload compute_orders --raw --project-key MYPROJ
123
- dss recipe get-payload compute_orders --raw --output code.py --project-key MYPROJ
124
+ dss recipe get-payload compute_orders --output code.py --project-key MYPROJ
124
125
  dss install-skill --dry-run
125
126
  dss app validate-manifest --project-key MYAPP_INSTANCE
126
127
  dss app compare-manifest my-app --project-key MYAPP_INSTANCE
@@ -230,4 +231,49 @@ never marks that external check complete. The public DSS APIs used by this SDK d
230
231
  supported app-template publish/recreate/rename workflow, recipient-level app sharing setter, or
231
232
  UI-click smoke test. The CLI does not guess private endpoints for those operations.
232
233
 
234
+ ## Project Git source-control safety
235
+
236
+ Project Git commands require DSS 12.4.2 or newer plus read and write access to the project
237
+ content. Inspect state before changing it:
238
+ The DSS project Git API exposes status, remotes, branches, tags, branch switching, fetch,
239
+ rebase-based pull, push, log, diff, commit, revert/reset/rebuild, external-library, and future
240
+ operations. It does not expose a separate checkout operation; use `switch`.
241
+
242
+ ```bash
243
+ dss project-git status --project-key MYPROJ
244
+ dss project-git branches --remote --project-key MYPROJ
245
+ dss project-git log --count 20 --project-key MYPROJ
246
+ ```
247
+
248
+ Creating a branch in a duplicate project is the safe UAT path; creating it in place switches the
249
+ source project to the new branch:
250
+
251
+ ```bash
252
+ dss project-git create-branch feature/orders \
253
+ --duplicate-project \
254
+ --target-project-key MYPROJ_ORDERS_UAT \
255
+ --project-key MYPROJ \
256
+ --plan
257
+ dss project-git create-branch feature/orders \
258
+ --duplicate-project \
259
+ --target-project-key MYPROJ_ORDERS_UAT \
260
+ --project-key MYPROJ
261
+ ```
262
+
263
+ `pull` rebases rather than merging. `reset-to-head`, `reset-to-upstream`, reverts, forced or
264
+ remote branch deletion, library-directory deletion, and `drop-and-rebuild` are destructive;
265
+ inspect their local `--plan` result first. `drop-and-rebuild` additionally requires
266
+ `--i-know-what-i-am-doing` and destroys all Git history. Repository URLs containing embedded
267
+ HTTP credentials are rejected. External-library credentials must come from
268
+ `--password-env ENV_NAME`; the value is never included in plans or command output. Library
269
+ operations that return a `jobId` can be observed with `project-git future-status` or completed
270
+ with `project-git future-wait`.
271
+ Project Git requests use `/dip/publicapi/projects/{projectKey}/git/*`; they do not configure
272
+ remote authentication. DSS documents administrator Git group rules plus either per-user SSH keys
273
+ under **Profile > Credentials > SSH** or non-interactive system-level credentials for the DSS
274
+ server account. Configure these before private-remote fetch, pull, or push. `--password-env`
275
+ applies only to external project-library operations and does not persist a remote credential.
276
+ The `project-git` resource does not manage these settings, so public/auth-less and
277
+ already-configured remotes are the supported automation paths.
278
+
233
279
  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": "..." }`.
package/bin/dss.js CHANGED
@@ -77,7 +77,7 @@ if (result.error) {
77
77
  runningOnBun ? "Bun" : "Node"
78
78
  } runtime for packaged dss CLI (${result.error.message}); falling back to the current runtime.`;
79
79
  if (usesSourceCli) {
80
- process.stderr.write(`${
80
+ process.stdout.write(`${
81
81
  JSON.stringify({
82
82
  type: "error",
83
83
  ok: false,
@@ -66,6 +66,7 @@ export declare const DatasetSummarySchema: import("@sinclair/typebox").TObject<{
66
66
  managed: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
67
67
  params: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
68
68
  connection: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
69
+ uploadConnection: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
69
70
  schema: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
70
71
  catalog: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
71
72
  }>>;
@@ -86,6 +87,7 @@ export declare const DatasetDetailsSchema: import("@sinclair/typebox").TObject<{
86
87
  managed: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
87
88
  params: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
88
89
  connection: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
90
+ uploadConnection: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
89
91
  path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
90
92
  table: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
91
93
  schema: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
@@ -111,7 +113,7 @@ export declare const DatasetDetailsSchema: import("@sinclair/typebox").TObject<{
111
113
  export type DatasetDetails = Static<typeof DatasetDetailsSchema>;
112
114
  export declare const DatasetCreateOptionsSchema: import("@sinclair/typebox").TObject<{
113
115
  datasetName: import("@sinclair/typebox").TString;
114
- connection: import("@sinclair/typebox").TString;
116
+ connection: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
115
117
  dsType: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
116
118
  table: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
117
119
  dbSchema: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
@@ -382,8 +384,8 @@ export declare const FlowZoneUpdateOptionsSchema: import("@sinclair/typebox").TO
382
384
  export type FlowZoneUpdateOptions = Static<typeof FlowZoneUpdateOptionsSchema>;
383
385
  export declare const FolderCreateOptionsSchema: import("@sinclair/typebox").TObject<{
384
386
  name: import("@sinclair/typebox").TString;
385
- type: import("@sinclair/typebox").TString;
386
- connection: import("@sinclair/typebox").TString;
387
+ type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
388
+ connection: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
387
389
  path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
388
390
  params: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TUnknown>>;
389
391
  projectKey: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
@@ -677,6 +679,128 @@ export declare const FlowMapOptionsSchema: import("@sinclair/typebox").TObject<{
677
679
  includeRaw: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
678
680
  }>;
679
681
  export type FlowMapOptions = Static<typeof FlowMapOptionsSchema>;
682
+ /**
683
+ * Git working-copy status of a project. Stable fields are documented in the
684
+ * DSS 14.7.3 source; DSS additionally returns extension fields, which are
685
+ * preserved by `additionalProperties: true`.
686
+ */
687
+ export declare const ProjectGitStatusSchema: import("@sinclair/typebox").TObject<{
688
+ currentBranch: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
689
+ remotes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
690
+ name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
691
+ url: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
692
+ }>>>;
693
+ trackingCount: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
694
+ ahead: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
695
+ behind: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
696
+ }>>;
697
+ clean: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
698
+ hasUncommittedChanges: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
699
+ added: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
700
+ changed: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
701
+ removed: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
702
+ missing: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
703
+ modified: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
704
+ conflicting: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
705
+ untracked: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
706
+ untrackedFolders: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
707
+ originProjectKey: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
708
+ trackingCountWithOriginProject: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
709
+ ahead: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
710
+ behind: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
711
+ }>>;
712
+ }>;
713
+ export type ProjectGitStatus = Static<typeof ProjectGitStatusSchema>;
714
+ export declare const ProjectGitRemoteSchema: import("@sinclair/typebox").TObject<{
715
+ url: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
716
+ }>;
717
+ export type ProjectGitRemote = Static<typeof ProjectGitRemoteSchema>;
718
+ /**
719
+ * Result of a Git mutation. DSS answers with HTTP 200 even for failures, so
720
+ * `success` is the field callers must inspect before trusting the operation.
721
+ */
722
+ export declare const ProjectGitActionResultSchema: import("@sinclair/typebox").TObject<{
723
+ success: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
724
+ output: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
725
+ logs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
726
+ messages: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
727
+ }>;
728
+ export type ProjectGitActionResult = Static<typeof ProjectGitActionResultSchema>;
729
+ export declare const ProjectGitTagSchema: import("@sinclair/typebox").TObject<{
730
+ name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
731
+ shortName: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
732
+ commit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
733
+ annotations: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
734
+ readOnly: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
735
+ }>;
736
+ export type ProjectGitTag = Static<typeof ProjectGitTagSchema>;
737
+ export declare const ProjectGitTagsSchema: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
738
+ name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
739
+ shortName: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
740
+ commit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
741
+ annotations: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
742
+ readOnly: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
743
+ }>>;
744
+ export type ProjectGitTags = Static<typeof ProjectGitTagsSchema>;
745
+ /**
746
+ * Paginated commit log. `nextCommit` is the cursor DSS expects back to fetch
747
+ * the following page; entries stay unpinned because commit payloads vary.
748
+ */
749
+ export declare const ProjectGitLogResultSchema: import("@sinclair/typebox").TObject<{
750
+ entries: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnknown>;
751
+ nextCommit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
752
+ }>;
753
+ export type ProjectGitLogResult = Static<typeof ProjectGitLogResultSchema>;
754
+ /**
755
+ * Diff between two revisions. Stable fields are documented in the DSS 14.7.3
756
+ * source; DSS additionally returns extension fields, which are preserved by
757
+ * `additionalProperties: true`.
758
+ */
759
+ export declare const ProjectGitDiffResultSchema: import("@sinclair/typebox").TObject<{
760
+ commitFrom: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
761
+ commitTo: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
762
+ addedLines: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
763
+ removedLines: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
764
+ changedFiles: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
765
+ entries: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnknown>>;
766
+ }>;
767
+ export type ProjectGitDiffResult = Static<typeof ProjectGitDiffResultSchema>;
768
+ export declare const ProjectGitLibrarySchema: import("@sinclair/typebox").TObject<{
769
+ repository: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
770
+ login: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
771
+ pathInGitRepository: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
772
+ localTargetPath: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
773
+ checkout: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
774
+ addToPythonPath: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
775
+ }>;
776
+ export type ProjectGitLibrary = Static<typeof ProjectGitLibrarySchema>;
777
+ export declare const ProjectGitLibrariesSchema: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
778
+ repository: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
779
+ login: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
780
+ pathInGitRepository: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
781
+ localTargetPath: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
782
+ checkout: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
783
+ addToPythonPath: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
784
+ }>>;
785
+ export type ProjectGitLibraries = Static<typeof ProjectGitLibrariesSchema>;
786
+ /** Handle returned by Git operations that run asynchronously as a DSS future. */
787
+ export declare const ProjectGitFutureResponseSchema: import("@sinclair/typebox").TObject<{
788
+ jobId: import("@sinclair/typebox").TString;
789
+ }>;
790
+ export type ProjectGitFutureResponse = Static<typeof ProjectGitFutureResponseSchema>;
791
+ export declare const ProjectGitFutureStateSchema: import("@sinclair/typebox").TObject<{
792
+ jobId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
793
+ hasResult: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
794
+ result: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
795
+ alive: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
796
+ aborted: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
797
+ abortable: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
798
+ unknown: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
799
+ startTime: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
800
+ runningTime: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
801
+ error: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
802
+ }>;
803
+ export type ProjectGitFutureState = Static<typeof ProjectGitFutureStateSchema>;
680
804
  export declare const ProjectSummaryArraySchema: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
681
805
  projectKey: import("@sinclair/typebox").TString;
682
806
  name: import("@sinclair/typebox").TString;
@@ -689,6 +813,7 @@ export declare const DatasetSummaryArraySchema: import("@sinclair/typebox").TArr
689
813
  managed: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
690
814
  params: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
691
815
  connection: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
816
+ uploadConnection: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
692
817
  schema: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
693
818
  catalog: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
694
819
  }>>;
@@ -123,6 +123,7 @@ export const DatasetSummarySchema = Type.Object({
123
123
  managed: Type.Optional(Type.Boolean()),
124
124
  params: Type.Optional(Type.Object({
125
125
  connection: Type.Optional(Type.String()),
126
+ uploadConnection: Type.Optional(Type.String()),
126
127
  schema: Type.Optional(Type.String()),
127
128
  catalog: Type.Optional(Type.String()),
128
129
  }, { additionalProperties: true, })),
@@ -141,6 +142,7 @@ export const DatasetDetailsSchema = Type.Object({
141
142
  managed: Type.Optional(Type.Boolean()),
142
143
  params: Type.Optional(Type.Object({
143
144
  connection: Type.Optional(Type.String()),
145
+ uploadConnection: Type.Optional(Type.String()),
144
146
  path: Type.Optional(Type.String()),
145
147
  table: Type.Optional(Type.String()),
146
148
  schema: Type.Optional(Type.String()),
@@ -159,7 +161,7 @@ export const DatasetDetailsSchema = Type.Object({
159
161
  }, { additionalProperties: true, });
160
162
  export const DatasetCreateOptionsSchema = Type.Object({
161
163
  datasetName: Type.String(),
162
- connection: Type.String(),
164
+ connection: Type.Optional(Type.String()),
163
165
  dsType: Type.Optional(Type.String()),
164
166
  table: Type.Optional(Type.String()),
165
167
  dbSchema: Type.Optional(Type.String()),
@@ -393,8 +395,8 @@ export const FlowZoneUpdateOptionsSchema = Type.Object({
393
395
  // ---------------------------------------------------------------------------
394
396
  export const FolderCreateOptionsSchema = Type.Object({
395
397
  name: Type.String(),
396
- type: Type.String(),
397
- connection: Type.String(),
398
+ type: Type.Optional(Type.String()),
399
+ connection: Type.Optional(Type.String()),
398
400
  path: Type.Optional(Type.String()),
399
401
  params: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
400
402
  projectKey: Type.Optional(Type.String()),
@@ -642,6 +644,107 @@ export const FlowMapOptionsSchema = Type.Object({
642
644
  includeRaw: Type.Optional(Type.Boolean()),
643
645
  });
644
646
  // ---------------------------------------------------------------------------
647
+ // Project Git
648
+ // ---------------------------------------------------------------------------
649
+ /**
650
+ * Git working-copy status of a project. Stable fields are documented in the
651
+ * DSS 14.7.3 source; DSS additionally returns extension fields, which are
652
+ * preserved by `additionalProperties: true`.
653
+ */
654
+ export const ProjectGitStatusSchema = Type.Object({
655
+ currentBranch: Type.Optional(Type.String()),
656
+ remotes: Type.Optional(Type.Array(Type.Object({
657
+ name: Type.Optional(Type.String()),
658
+ url: Type.Optional(Type.String()),
659
+ }, { additionalProperties: true, }))),
660
+ trackingCount: Type.Optional(Type.Object({
661
+ ahead: Type.Optional(Type.Number()),
662
+ behind: Type.Optional(Type.Number()),
663
+ }, { additionalProperties: true, })),
664
+ clean: Type.Optional(Type.Boolean()),
665
+ hasUncommittedChanges: Type.Optional(Type.Boolean()),
666
+ added: Type.Optional(Type.Array(Type.String())),
667
+ changed: Type.Optional(Type.Array(Type.String())),
668
+ removed: Type.Optional(Type.Array(Type.String())),
669
+ missing: Type.Optional(Type.Array(Type.String())),
670
+ modified: Type.Optional(Type.Array(Type.String())),
671
+ conflicting: Type.Optional(Type.Array(Type.String())),
672
+ untracked: Type.Optional(Type.Array(Type.String())),
673
+ untrackedFolders: Type.Optional(Type.Array(Type.String())),
674
+ originProjectKey: Type.Optional(Type.String()),
675
+ trackingCountWithOriginProject: Type.Optional(Type.Object({
676
+ ahead: Type.Optional(Type.Number()),
677
+ behind: Type.Optional(Type.Number()),
678
+ }, { additionalProperties: true, })),
679
+ }, { additionalProperties: true, });
680
+ export const ProjectGitRemoteSchema = Type.Object({
681
+ url: Type.Optional(Type.String()),
682
+ }, { additionalProperties: true, });
683
+ /**
684
+ * Result of a Git mutation. DSS answers with HTTP 200 even for failures, so
685
+ * `success` is the field callers must inspect before trusting the operation.
686
+ */
687
+ export const ProjectGitActionResultSchema = Type.Object({
688
+ success: Type.Optional(Type.Boolean()),
689
+ output: Type.Optional(Type.Unknown()),
690
+ logs: Type.Optional(Type.Unknown()),
691
+ messages: Type.Optional(Type.Unknown()),
692
+ }, { additionalProperties: true, });
693
+ export const ProjectGitTagSchema = Type.Object({
694
+ name: Type.Optional(Type.String()),
695
+ shortName: Type.Optional(Type.String()),
696
+ commit: Type.Optional(Type.Unknown()),
697
+ annotations: Type.Optional(Type.Unknown()),
698
+ readOnly: Type.Optional(Type.Boolean()),
699
+ }, { additionalProperties: true, });
700
+ export const ProjectGitTagsSchema = Type.Array(ProjectGitTagSchema);
701
+ /**
702
+ * Paginated commit log. `nextCommit` is the cursor DSS expects back to fetch
703
+ * the following page; entries stay unpinned because commit payloads vary.
704
+ */
705
+ export const ProjectGitLogResultSchema = Type.Object({
706
+ entries: Type.Array(Type.Unknown()),
707
+ nextCommit: Type.Optional(Type.String()),
708
+ }, { additionalProperties: true, });
709
+ /**
710
+ * Diff between two revisions. Stable fields are documented in the DSS 14.7.3
711
+ * source; DSS additionally returns extension fields, which are preserved by
712
+ * `additionalProperties: true`.
713
+ */
714
+ export const ProjectGitDiffResultSchema = Type.Object({
715
+ commitFrom: Type.Optional(Type.Unknown()),
716
+ commitTo: Type.Optional(Type.Unknown()),
717
+ addedLines: Type.Optional(Type.Number()),
718
+ removedLines: Type.Optional(Type.Number()),
719
+ changedFiles: Type.Optional(Type.Number()),
720
+ entries: Type.Optional(Type.Array(Type.Unknown())),
721
+ }, { additionalProperties: true, });
722
+ export const ProjectGitLibrarySchema = Type.Object({
723
+ repository: Type.Optional(Type.String()),
724
+ login: Type.Optional(Type.String()),
725
+ pathInGitRepository: Type.Optional(Type.String()),
726
+ localTargetPath: Type.Optional(Type.String()),
727
+ checkout: Type.Optional(Type.String()),
728
+ addToPythonPath: Type.Optional(Type.Boolean()),
729
+ }, { additionalProperties: true, });
730
+ export const ProjectGitLibrariesSchema = Type.Array(ProjectGitLibrarySchema);
731
+ /** Handle returned by Git operations that run asynchronously as a DSS future. */
732
+ export const ProjectGitFutureResponseSchema = Type.Object({
733
+ jobId: Type.String(),
734
+ }, { additionalProperties: true, });
735
+ export const ProjectGitFutureStateSchema = Type.Object({
736
+ jobId: Type.Optional(Type.String()),
737
+ hasResult: Type.Optional(Type.Boolean()),
738
+ result: Type.Optional(Type.Unknown()),
739
+ alive: Type.Optional(Type.Boolean()),
740
+ aborted: Type.Optional(Type.Boolean()),
741
+ abortable: Type.Optional(Type.Boolean()),
742
+ unknown: Type.Optional(Type.Boolean()),
743
+ startTime: Type.Optional(Type.Number()),
744
+ runningTime: Type.Optional(Type.Number()),
745
+ error: Type.Optional(Type.Unknown()),
746
+ }, { additionalProperties: true, });
747
+ // ---------------------------------------------------------------------------
645
748
  // Array wrappers (for runtime validation of list() responses)
646
749
  // ---------------------------------------------------------------------------
647
750
  export const ProjectSummaryArraySchema = Type.Array(ProjectSummarySchema);
@@ -1,5 +1,6 @@
1
1
  import type { JobBuildTargetType, JobLogFilter } from "../resources/jobs.js";
2
- export declare function num(v: string | boolean | undefined): number | undefined;
2
+ export declare function num(v: string | boolean | undefined, flagName?: string): number | undefined;
3
+ export declare function numFlag(flags: Record<string, string | boolean>, flagNames: string[]): number | undefined;
3
4
  export declare function jobBuildTargetType(v: string | boolean | undefined): JobBuildTargetType;
4
5
  export declare function jobBuildTargetTypeFromFlags(flags: Record<string, string | boolean>): JobBuildTargetType;
5
6
  export declare function maxLogLinesFromFlags(flags: Record<string, string | boolean>): number | undefined;
@@ -1,10 +1,31 @@
1
1
  import { readFileSync, } from "node:fs";
2
2
  import { UsageError, } from "./usage.js";
3
- export function num(v) {
4
- if (typeof v !== "string")
3
+ function safeValuePreview(value) {
4
+ return value.length <= 32 ? value : `${value.slice(0, 32)}…`;
5
+ }
6
+ export function num(v, flagName) {
7
+ if (v === undefined || v === false)
5
8
  return undefined;
9
+ if (typeof v !== "string") {
10
+ throw new UsageError(`${flagName ?? "Numeric flag"} requires a value.`, "invalid_flag_value", undefined, flagName ? { flag: flagName, } : {});
11
+ }
12
+ if (v.trim().length === 0) {
13
+ throw new UsageError(`Invalid numeric value for ${flagName ?? "flag"}.`, "invalid_flag_value", undefined, flagName ? { flag: flagName, } : {});
14
+ }
6
15
  const n = Number(v);
7
- return Number.isFinite(n) ? n : undefined;
16
+ if (!Number.isFinite(n)) {
17
+ throw new UsageError(`Invalid numeric value for ${flagName ?? "flag"}: ${safeValuePreview(v)}.`, "invalid_flag_value", undefined, {
18
+ ...(flagName ? { flag: flagName, } : {}),
19
+ value: safeValuePreview(v),
20
+ });
21
+ }
22
+ return n;
23
+ }
24
+ export function numFlag(flags, flagNames) {
25
+ const flagName = flagNames.find((name) => flags[name] !== undefined && flags[name] !== false);
26
+ if (flagName === undefined)
27
+ return undefined;
28
+ return num(flags[flagName], `--${flagName}`);
8
29
  }
9
30
  export function jobBuildTargetType(v) {
10
31
  if (v === undefined)
@@ -21,7 +42,7 @@ export function jobBuildTargetTypeFromFlags(flags) {
21
42
  return jobBuildTargetType(flags["target-type"] ?? flags["type"]);
22
43
  }
23
44
  export function maxLogLinesFromFlags(flags) {
24
- return num(flags["max-log-lines"] ?? flags["max-lines"]);
45
+ return numFlag(flags, ["max-log-lines", "max-lines",]);
25
46
  }
26
47
  export function jobLogFilterFromFlag(v) {
27
48
  if (v === undefined)
@@ -124,32 +145,62 @@ export function parseJsonObject(text, source) {
124
145
  return expectJsonObject(parseJsonValue(text, source), source);
125
146
  }
126
147
  export function json(v, source = "JSON flag") {
127
- if (typeof v !== "string")
148
+ if (v === undefined || v === false)
128
149
  return undefined;
150
+ if (typeof v !== "string" || v.trim().length === 0) {
151
+ throw new UsageError(`${source} requires a JSON value.`, "invalid_flag_value");
152
+ }
129
153
  return parseJsonObject(v, source);
130
154
  }
131
155
  export function readStdinText() {
132
156
  return readFileSync(0, "utf-8");
133
157
  }
134
- export function jsonInput(flags) {
135
- if (flags["stdin"] === true)
136
- return parseJsonObject(readStdinText(), "stdin");
137
- if (typeof flags["data-file"] === "string") {
138
- return parseJsonObject(readFileSync(flags["data-file"], "utf-8"), flags["data-file"]);
158
+ const JSON_SOURCE_FLAGS = ["stdin", "data-file", "data",];
159
+ const TEXT_SOURCE_FLAGS = ["content", "file",];
160
+ function selectSingleSource(flags, sourceFlags) {
161
+ const provided = sourceFlags.filter((name) => {
162
+ const value = flags[name];
163
+ if (value === undefined || value === false)
164
+ return false;
165
+ return name === "stdin" ? parseBooleanOption(value, "--stdin") === true : true;
166
+ });
167
+ if (provided.length > 1) {
168
+ throw new UsageError(`Conflicting input sources: ${provided.map((name) => `--${name}`).join(" or ")}. Provide exactly one.`, "conflicting_input_sources", undefined, { sources: provided, });
139
169
  }
140
- if (typeof flags["data"] === "string")
141
- return parseJsonObject(flags["data"], "--data");
142
- return undefined;
170
+ return provided[0];
143
171
  }
144
- export function unknownJsonInput(flags) {
145
- if (flags["stdin"] === true)
146
- return parseJsonValue(readStdinText(), "stdin");
147
- if (typeof flags["data-file"] === "string") {
148
- return parseJsonValue(readFileSync(flags["data-file"], "utf-8"), flags["data-file"]);
172
+ function resolveJsonSourceText(flags, kind) {
173
+ const source = selectSingleSource(flags, JSON_SOURCE_FLAGS);
174
+ if (source === undefined)
175
+ return undefined;
176
+ if (source === "stdin") {
177
+ const jsonText = readStdinText();
178
+ return kind === "object"
179
+ ? parseJsonObject(jsonText, "stdin")
180
+ : parseJsonValue(jsonText, "stdin");
149
181
  }
150
- if (typeof flags["data"] === "string")
151
- return parseJsonValue(flags["data"], "--data");
152
- return undefined;
182
+ if (source === "data-file") {
183
+ const fileValue = flags["data-file"];
184
+ if (typeof fileValue === "string") {
185
+ const jsonText = readFileSync(fileValue, "utf-8");
186
+ return kind === "object"
187
+ ? parseJsonObject(jsonText, fileValue)
188
+ : parseJsonValue(jsonText, fileValue);
189
+ }
190
+ }
191
+ const dataValue = flags["data"];
192
+ if (typeof dataValue === "string") {
193
+ return kind === "object"
194
+ ? parseJsonObject(dataValue, "--data")
195
+ : parseJsonValue(dataValue, "--data");
196
+ }
197
+ throw new UsageError("JSON input source is present but has no value.", "invalid_flag_value");
198
+ }
199
+ export function jsonInput(flags) {
200
+ return resolveJsonSourceText(flags, "object");
201
+ }
202
+ export function unknownJsonInput(flags) {
203
+ return resolveJsonSourceText(flags, "any");
153
204
  }
154
205
  export function schemaColumnsInput(flags, usage) {
155
206
  const input = unknownJsonInput(flags);
@@ -184,11 +235,18 @@ export function schemaColumnsInput(flags, usage) {
184
235
  });
185
236
  }
186
237
  export function textInput(flags) {
187
- if (typeof flags["content"] === "string")
188
- return flags["content"];
189
- if (typeof flags["file"] === "string")
190
- return readFileSync(flags["file"], "utf-8");
191
- return undefined;
238
+ const source = selectSingleSource(flags, TEXT_SOURCE_FLAGS);
239
+ if (source === undefined)
240
+ return undefined;
241
+ if (source === "file") {
242
+ const fileValue = flags["file"];
243
+ if (typeof fileValue === "string")
244
+ return readFileSync(fileValue, "utf-8");
245
+ }
246
+ const contentValue = flags["content"];
247
+ if (typeof contentValue === "string")
248
+ return contentValue;
249
+ throw new UsageError("Text input source is present but has no value.", "invalid_flag_value");
192
250
  }
193
251
  export function requiredJsonInput(flags, message) {
194
252
  const data = jsonInput(flags);
@@ -264,8 +264,8 @@ export const appCommands = {
264
264
  let waited;
265
265
  try {
266
266
  waited = await c.futures.wait(jobId, {
267
- pollIntervalMs: num(f["poll-interval"]),
268
- timeoutMs: num(f["timeout"]),
267
+ pollIntervalMs: num(f["poll-interval"], "--poll-interval"),
268
+ timeoutMs: num(f["timeout"], "--timeout"),
269
269
  });
270
270
  }
271
271
  catch (error) {
@@ -353,8 +353,8 @@ export const appCommands = {
353
353
  ...(f["name"] !== undefined ? { name: f["name"], } : {}),
354
354
  copyPermissions: parseBooleanOption(f["copy-permissions"], "--copy-permissions") ?? false,
355
355
  dryRun: parseBooleanOption(f["dry-run"], "--dry-run") ?? false,
356
- timeoutMs: num(f["timeout"]),
357
- pollIntervalMs: num(f["poll-interval"]),
356
+ timeoutMs: num(f["timeout"], "--timeout"),
357
+ pollIntervalMs: num(f["poll-interval"], "--poll-interval"),
358
358
  }, CREATE_SUCCESSOR_USAGE);
359
359
  },
360
360
  usage: CREATE_SUCCESSOR_USAGE,
@@ -550,8 +550,8 @@ export const appCommands = {
550
550
  let waited;
551
551
  try {
552
552
  waited = await c.futures.wait(futureId, {
553
- pollIntervalMs: num(f["poll-interval"]),
554
- timeoutMs: num(f["timeout"]),
553
+ pollIntervalMs: num(f["poll-interval"], "--poll-interval"),
554
+ timeoutMs: num(f["timeout"], "--timeout"),
555
555
  });
556
556
  }
557
557
  catch (error) {