dataiku-sdk 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # dataiku-sdk
2
+
3
+ Agent-only TypeScript SDK and `dss` CLI for Dataiku DSS automation.
4
+
5
+ Examples below assume the installed `dss` binary. From this checkout, use `./bin/dss ...` or `bun --no-env-file src/cli.ts ...` with the same arguments; from another working directory, call `/path/to/dataiku-sdk/bin/dss ...`.
6
+ `--no-env-file` disables Bun's automatic preloading only; the CLI still applies its documented `.env` handling unless `DATAIKU_DISABLE_ENV=1` is set.
7
+
8
+ ## CLI contract
9
+
10
+ - Success: stdout contains one JSON result.
11
+ - Failure: stderr contains one JSON error envelope with `ok:false`, `error`, `code`, and `exitCode`.
12
+ - `--verbose` may add HTTP trace lines to stderr.
13
+ - `--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.
14
+ - No prompts, help screens, tables, banners, or prose output are part of the contract.
15
+ - 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.
16
+ - The exit code is the success signal: chain mutations with `&&` and never infer success from piped output that discards the exit code (e.g. `dss ... 2>&1 | helper; echo done` reports success even when the command failed).
17
+ - `--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.
18
+
19
+ Discover the complete machine-readable command surface:
20
+
21
+ ```bash
22
+ dss commands run
23
+ ```
24
+
25
+ Agents should parse `commands run` before choosing syntax; inspect `flags`, `requiresAuth`, `requiresProject`, `sideEffect`, and `outputShape` instead of guessing.
26
+
27
+ ## Agent skill installation
28
+
29
+ ```bash
30
+ dss install-skill --list-agents
31
+ dss install-skill --agent omp --target .
32
+ dss install-skill --agent omp --target . --dry-run
33
+ dss install-skill --global --agent omp
34
+ ```
35
+
36
+ `--list-agents` only reports targetable agents; it does not write files. Auto-detection checks supported agent binaries/config directories (`claude`, `codex`, `cursor`, `pi`, `omp`). Passing `--agent NAME` forces one entry and reports `via:"flag"`.
37
+
38
+ Project installs write `SKILL.md` under the target workspace:
39
+
40
+ - Claude: `.claude/skills/dataiku-dss/SKILL.md`
41
+ - Codex: `.codex/skills/dataiku-dss/SKILL.md`
42
+ - Cursor: `.cursor/skills/dataiku-dss/SKILL.md`
43
+ - Pi: `.pi/skills/dataiku-dss/SKILL.md`
44
+ - OMP: `.omp/skills/dataiku-dss/SKILL.md`
45
+
46
+ Global installs write under the agent's home config path, for example OMP: `~/.omp/agent/skills/dataiku-dss/SKILL.md`.
47
+
48
+ ## Credentials
49
+
50
+ Use environment variables for ephemeral runs:
51
+ For disposable agent tests, set `DSS_CONFIG_DIR` to a temporary directory so saved credentials never touch your real profile.
52
+ Credential precedence is flags first, then `DATAIKU_*` environment variables, then saved credentials in `DSS_CONFIG_DIR` or the platform config directory.
53
+ Set `DATAIKU_DISABLE_ENV=1` when a test must ignore both `.env` files and `DATAIKU_*` environment variables.
54
+ When `.env` loading is enabled, the CLI reads `.env` from the CLI build/root directory and from the command's current working directory; put test-specific `.env` files in the directory where you invoke `dss`.
55
+
56
+ ```bash
57
+ DATAIKU_URL=https://dss.example.com \
58
+ DATAIKU_API_KEY=your-api-key \
59
+ DATAIKU_PROJECT_KEY=MYPROJ \
60
+ dss project list
61
+ ```
62
+
63
+ Persist credentials when needed:
64
+
65
+ ```bash
66
+ dss auth login --url https://dss.example.com --api-key YOUR_KEY --project-key MYPROJ
67
+ ```
68
+
69
+ The command saves credentials and returns `{ "saved": true, "path": "..." }`.
70
+ `auth login` validates by listing accessible projects before saving credentials, so the API key must be allowed to call DSS project-list APIs.
71
+
72
+ ## Examples
73
+
74
+ ```bash
75
+ dss version
76
+ dss doctor --fast
77
+ dss project list
78
+ dss dataset list --project-key MYPROJ
79
+ dss recipe get-payload compute_orders --project-key MYPROJ
80
+ dss recipe get-payload compute_orders --raw --project-key MYPROJ
81
+ dss recipe get-payload compute_orders --raw --output code.py --project-key MYPROJ
82
+ dss install-skill --dry-run
83
+ ```
84
+
85
+ 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
@@ -1,18 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawnSync, } from "node:child_process";
3
+ import { existsSync, } from "node:fs";
3
4
  import { dirname, resolve, } from "node:path";
4
5
  import { fileURLToPath, pathToFileURL, } from "node:url";
5
6
 
6
7
  const args = process.argv.slice(2,);
8
+ const optionArgs = args.includes("--",) ? args.slice(0, args.indexOf("--",),) : args;
7
9
  const here = dirname(fileURLToPath(import.meta.url,),);
8
- const cliPath = resolve(here, "../dist/src/cli.js",);
10
+ const distCliPath = resolve(here, "../dist/src/cli.js",);
11
+ const sourceCliPath = resolve(here, "../src/cli.ts",);
12
+ const cliPath = existsSync(distCliPath,) ? distCliPath : sourceCliPath;
9
13
  const cliUrl = pathToFileURL(cliPath,).href;
10
14
 
11
15
  function flagValue(names,) {
12
- for (let i = 0; i < args.length; i++) {
13
- const arg = args[i];
16
+ for (let i = 0; i < optionArgs.length; i++) {
17
+ const arg = optionArgs[i];
14
18
  for (const name of names) {
15
- if (arg === name) return args[i + 1];
19
+ if (arg === name) return optionArgs[i + 1];
16
20
  if (arg.startsWith(`${name}=`,)) return arg.slice(name.length + 1,);
17
21
  }
18
22
  }
@@ -20,7 +24,7 @@ function flagValue(names,) {
20
24
  }
21
25
 
22
26
  function hasFlag(names,) {
23
- return names.some((name,) => args.includes(name,));
27
+ return names.some((name,) => optionArgs.includes(name,));
24
28
  }
25
29
 
26
30
  async function loadSavedTlsSettings() {
@@ -59,16 +63,38 @@ if (hasFlag(["--insecure", "--skip-tls-verify",],)) {
59
63
  }
60
64
 
61
65
  const nodeBin = process.versions.bun ? "node" : process.execPath;
62
- const nodeArgs = supportsSystemCa(nodeBin,) ? ["--use-system-ca",] : [];
63
- const result = spawnSync(nodeBin, [...nodeArgs, cliPath, ...args,], {
64
- stdio: "inherit",
65
- env,
66
- },);
66
+ const usesSourceCli = cliPath === sourceCliPath;
67
+ const nodeArgs = !usesSourceCli && supportsSystemCa(nodeBin,) ? ["--use-system-ca",] : [];
68
+ const result = spawnSync(
69
+ usesSourceCli ? "bun" : nodeBin,
70
+ [...(usesSourceCli ? ["--no-env-file",] : nodeArgs), cliPath, ...args,],
71
+ {
72
+ stdio: "inherit",
73
+ env,
74
+ },
75
+ );
67
76
 
68
77
  if (result.error) {
69
- process.stderr.write(
70
- `Unable to start Node runtime for packaged dss CLI (${result.error.message}); falling back to current runtime without Node system CA bootstrap.\n`,
71
- );
78
+ const message = usesSourceCli
79
+ ? `Unable to start Bun runtime for source dss CLI (${result.error.message}).`
80
+ : `Unable to start Node runtime for packaged dss CLI (${result.error.message}); falling back to current runtime without Node system CA bootstrap.`;
81
+ if (usesSourceCli) {
82
+ process.stderr.write(`${
83
+ JSON.stringify(
84
+ {
85
+ ok: false,
86
+ error: message,
87
+ code: "internal_error",
88
+ category: "internal",
89
+ message,
90
+ exitCode: 2,
91
+ },
92
+ null,
93
+ 2,
94
+ )
95
+ }\n`,);
96
+ process.exit(2,);
97
+ }
72
98
  await import(cliUrl);
73
99
  } else if (result.signal) {
74
100
  process.kill(process.pid, result.signal,);