dataiku-sdk 0.12.0 → 0.12.2

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 CHANGED
@@ -2,7 +2,23 @@
2
2
 
3
3
  Agent-only TypeScript SDK and `dss` CLI for Dataiku DSS automation.
4
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 ...`.
5
+ ## Platform support
6
+
7
+ The published `dss` CLI supports Linux, macOS, and Windows under Bun >= 1.3.14 or Node.js >= 22.15.0. The release gate runs Bun 1.3.14 with Node 24 on all three operating systems, plus a lightweight minimum-Node 22.15 package smoke on Linux. The runtime dependency is pure JavaScript, so the same package also runs on runtime-supported x64 and ARM64 systems.
8
+
9
+ Run directly with Bun:
10
+
11
+ ```text
12
+ bunx --bun dataiku-sdk version
13
+ ```
14
+
15
+ Or install the npm binary:
16
+
17
+ ```text
18
+ npm install --global dataiku-sdk
19
+ ```
20
+
21
+ Bun is the primary development runtime and package manager. Examples below assume an installed `dss` binary. From a checkout, use `bun --no-env-file src/cli.ts ...` or the cross-runtime `bun --no-env-file ./bin/dss.js ...` launcher. Node users can invoke the same launcher as `node ./bin/dss.js ...`; if `dist/` is absent, it delegates to Bun. From another working directory, pass the checkout's absolute `bin/dss.js` path to Bun or Node.
6
22
  `--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
23
 
8
24
  ## CLI contract
@@ -13,12 +29,12 @@ Examples below assume the installed `dss` binary. From this checkout, use `./bin
13
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.
14
30
  - No prompts, help screens, tables, banners, or prose output are part of the contract.
15
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.
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).
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.
17
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.
18
34
 
19
35
  Discover the agent protocol and complete machine-readable command surface:
20
36
 
21
- ```bash
37
+ ```text
22
38
  dss agent contract
23
39
  dss commands run
24
40
  ```
@@ -27,7 +43,7 @@ Agents should parse `agent contract` once for protocol/schema compatibility, the
27
43
 
28
44
  ## Agent skill installation
29
45
 
30
- ```bash
46
+ ```text
31
47
  dss install-skill --list-agents
32
48
  dss install-skill --agent omp --target .
33
49
  dss install-skill --agent omp --target . --dry-run
@@ -48,22 +64,41 @@ Global installs write under the agent's home config path, for example OMP: `~/.o
48
64
 
49
65
  ## Credentials
50
66
 
51
- Use environment variables for ephemeral runs:
52
- For disposable agent tests, set `DSS_CONFIG_DIR` to a temporary directory so saved credentials never touch your real profile.
67
+ 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.
53
68
  Credential precedence is flags first, then `DATAIKU_*` environment variables, then saved credentials in `DSS_CONFIG_DIR` or the platform config directory.
54
69
  Set `DATAIKU_DISABLE_ENV=1` when a test must ignore both `.env` files and `DATAIKU_*` environment variables.
55
70
  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`.
56
71
 
57
- ```bash
58
- DATAIKU_URL=https://dss.example.com \
59
- DATAIKU_API_KEY=your-api-key \
60
- DATAIKU_PROJECT_KEY=MYPROJ \
72
+ POSIX shell:
73
+
74
+ ```sh
75
+ export DATAIKU_URL=https://dss.example.com
76
+ export DATAIKU_API_KEY=your-api-key
77
+ export DATAIKU_PROJECT_KEY=MYPROJ
78
+ dss project list
79
+ ```
80
+
81
+ PowerShell:
82
+
83
+ ```powershell
84
+ $env:DATAIKU_URL = "https://dss.example.com"
85
+ $env:DATAIKU_API_KEY = "your-api-key"
86
+ $env:DATAIKU_PROJECT_KEY = "MYPROJ"
87
+ dss project list
88
+ ```
89
+
90
+ Windows Command Prompt:
91
+
92
+ ```bat
93
+ set "DATAIKU_URL=https://dss.example.com"
94
+ set "DATAIKU_API_KEY=your-api-key"
95
+ set "DATAIKU_PROJECT_KEY=MYPROJ"
61
96
  dss project list
62
97
  ```
63
98
 
64
99
  Persist credentials when needed:
65
100
 
66
- ```bash
101
+ ```text
67
102
  dss auth login --url https://dss.example.com --api-key YOUR_KEY --project-key MYPROJ
68
103
  ```
69
104
 
package/bin/dss.js CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawnSync, } from "node:child_process";
3
- import { existsSync, } from "node:fs";
4
- import { dirname, resolve, } from "node:path";
3
+ import * as fs from "node:fs";
4
+ import * as path from "node:path";
5
5
  import { fileURLToPath, pathToFileURL, } from "node:url";
6
6
 
7
7
  const args = process.argv.slice(2,);
8
8
  const optionArgs = args.includes("--",) ? args.slice(0, args.indexOf("--",),) : args;
9
- const here = dirname(fileURLToPath(import.meta.url,),);
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
+ const here = path.dirname(fileURLToPath(import.meta.url,),);
10
+ const distCliPath = path.resolve(here, "../dist/src/cli.js",);
11
+ const sourceCliPath = path.resolve(here, "../src/cli.ts",);
12
+ const cliPath = fs.existsSync(distCliPath,) ? distCliPath : sourceCliPath;
13
13
  const cliUrl = pathToFileURL(cliPath,).href;
14
14
 
15
15
  function flagValue(names,) {
@@ -40,11 +40,6 @@ async function loadSavedTlsSettings() {
40
40
  }
41
41
  }
42
42
 
43
- function supportsSystemCa(nodeBin,) {
44
- const probe = spawnSync(nodeBin, ["--use-system-ca", "-e", "",], { stdio: "ignore", },);
45
- return !probe.error && probe.status === 0;
46
- }
47
-
48
43
  const savedTls = await loadSavedTlsSettings();
49
44
  const env = { ...process.env, };
50
45
  const explicitCaCert = flagValue(["--ca-cert", "--extra-ca-certs",],);
@@ -62,12 +57,13 @@ if (hasFlag(["--insecure", "--skip-tls-verify",],)) {
62
57
  env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
63
58
  }
64
59
 
65
- const nodeBin = process.versions.bun ? "node" : process.execPath;
60
+ const runningOnBun = Boolean(process.versions.bun,);
66
61
  const usesSourceCli = cliPath === sourceCliPath;
67
- const nodeArgs = !usesSourceCli && supportsSystemCa(nodeBin,) ? ["--use-system-ca",] : [];
62
+ const runtimeBin = runningOnBun ? process.execPath : usesSourceCli ? "bun" : process.execPath;
63
+ const runtimeArgs = runningOnBun || usesSourceCli ? ["--no-env-file",] : ["--use-system-ca",];
68
64
  const result = spawnSync(
69
- usesSourceCli ? "bun" : nodeBin,
70
- [...(usesSourceCli ? ["--no-env-file",] : nodeArgs), cliPath, ...args,],
65
+ runtimeBin,
66
+ [...runtimeArgs, cliPath, ...args,],
71
67
  {
72
68
  stdio: "inherit",
73
69
  env,
@@ -77,25 +73,24 @@ const result = spawnSync(
77
73
  if (result.error) {
78
74
  const message = usesSourceCli
79
75
  ? `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.`;
76
+ : `Unable to start ${
77
+ runningOnBun ? "Bun" : "Node"
78
+ } runtime for packaged dss CLI (${result.error.message}); falling back to the current runtime.`;
81
79
  if (usesSourceCli) {
82
80
  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
- )
81
+ JSON.stringify({
82
+ type: "error",
83
+ ok: false,
84
+ error: message,
85
+ code: "internal_error",
86
+ category: "internal",
87
+ exitCode: 2,
88
+ },)
95
89
  }\n`,);
96
- process.exit(2,);
90
+ process.exitCode = 2;
91
+ } else {
92
+ await import(cliUrl);
97
93
  }
98
- await import(cliUrl);
99
94
  } else if (result.signal) {
100
95
  process.kill(process.pid, result.signal,);
101
96
  } else {
@@ -273,6 +273,11 @@ export declare const ScenarioStepRunSchema: import("@sinclair/typebox").TObject<
273
273
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
274
274
  type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
275
275
  outcome: import("@sinclair/typebox").TString;
276
+ warningCount: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
277
+ warnings: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
278
+ type: import("@sinclair/typebox").TString;
279
+ count: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
280
+ }>>>;
276
281
  }>;
277
282
  export type ScenarioStepRun = Static<typeof ScenarioStepRunSchema>;
278
283
  export declare const ScenarioWaitResultSchema: import("@sinclair/typebox").TObject<{
@@ -288,6 +293,11 @@ export declare const ScenarioWaitResultSchema: import("@sinclair/typebox").TObje
288
293
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
289
294
  type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
290
295
  outcome: import("@sinclair/typebox").TString;
296
+ warningCount: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
297
+ warnings: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
298
+ type: import("@sinclair/typebox").TString;
299
+ count: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
300
+ }>>>;
291
301
  }>>>;
292
302
  }>;
293
303
  export type ScenarioWaitResult = Static<typeof ScenarioWaitResultSchema>;
@@ -322,6 +322,11 @@ export const ScenarioStepRunSchema = Type.Object({
322
322
  name: Type.Optional(Type.String()),
323
323
  type: Type.Optional(Type.String()),
324
324
  outcome: Type.String(),
325
+ warningCount: Type.Optional(Type.Number()),
326
+ warnings: Type.Optional(Type.Array(Type.Object({
327
+ type: Type.String(),
328
+ count: Type.Optional(Type.Number()),
329
+ }, { additionalProperties: false, }))),
325
330
  }, { additionalProperties: false, });
326
331
  export const ScenarioWaitResultSchema = Type.Object({
327
332
  scenarioId: Type.String(),
package/dist/src/cli.js CHANGED
@@ -969,7 +969,7 @@ async function main() {
969
969
  if (metaCommand) {
970
970
  writeCommandResult(metaCommand.result);
971
971
  if (metaCommand.exitCode !== 0)
972
- process.exit(metaCommand.exitCode);
972
+ process.exitCode = metaCommand.exitCode;
973
973
  return;
974
974
  }
975
975
  if (!commands[resource])
@@ -1033,5 +1033,5 @@ async function main() {
1033
1033
  }
1034
1034
  main().catch((err) => {
1035
1035
  writeErrorReport(err);
1036
- process.exit(errorExitCode(err));
1036
+ process.exitCode = errorExitCode(err);
1037
1037
  });
@@ -86,6 +86,34 @@ function extractCodeRunOutput(log) {
86
86
  function isRecord(value) {
87
87
  return typeof value === "object" && value !== null && !Array.isArray(value);
88
88
  }
89
+ function scenarioStepWarningSummary(stepResult) {
90
+ const container = stepResult?.warnings;
91
+ if (!isRecord(container))
92
+ return {};
93
+ const rawWarnings = container.warnings;
94
+ const warnings = isRecord(rawWarnings)
95
+ ? Object.entries(rawWarnings).flatMap(([key, value,]) => {
96
+ if (!isRecord(value))
97
+ return [];
98
+ const rawType = value.type;
99
+ const type = typeof rawType === "string" && rawType.length > 0 ? rawType : key;
100
+ const rawCount = value.count;
101
+ return [{
102
+ type,
103
+ ...(typeof rawCount === "number" && Number.isFinite(rawCount)
104
+ ? { count: rawCount, }
105
+ : {}),
106
+ },];
107
+ })
108
+ : [];
109
+ const rawTotal = container.totalCount;
110
+ return {
111
+ ...(typeof rawTotal === "number" && Number.isFinite(rawTotal)
112
+ ? { warningCount: rawTotal, }
113
+ : {}),
114
+ ...(warnings.length > 0 ? { warnings, } : {}),
115
+ };
116
+ }
89
117
  function jsonValueEqual(left, right) {
90
118
  if (Object.is(left, right))
91
119
  return true;
@@ -352,6 +380,7 @@ export class ScenariosResource extends BaseResource {
352
380
  name: stepDef?.name,
353
381
  type: stepDef?.type,
354
382
  outcome: stepResult?.outcome ?? "UNKNOWN",
383
+ ...scenarioStepWarningSummary(stepResult),
355
384
  };
356
385
  });
357
386
  if (mapped.length > 0)
package/dist/src/skill.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { execFileSync, } from "node:child_process";
2
- import { existsSync, mkdirSync, writeFileSync, } from "node:fs";
3
- import { homedir, } from "node:os";
4
- import { dirname, join, } from "node:path";
2
+ import * as fs from "node:fs";
3
+ import * as os from "node:os";
4
+ import * as path from "node:path";
5
5
  const SKILL_BODY = `# Dataiku DSS agent CLI
6
6
 
7
7
  Use \`dss\` when an agent needs to inspect or change Dataiku DSS resources: projects, datasets, recipes, jobs, scenarios, folders, notebooks, SQL, variables, code envs, and connections.
8
- If the installed \`dss\` binary is unavailable but the repository checkout is the current workspace, 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 ...\`.
8
+ If the installed \`dss\` binary is unavailable but the repository checkout is the current workspace, prefer \`bun --no-env-file src/cli.ts ...\` or \`bun --no-env-file ./bin/dss.js ...\`. Node users can invoke the same cross-runtime launcher as \`node ./bin/dss.js ...\`; when \`dist/\` has not been built, it delegates to Bun. From another working directory, pass the checkout's absolute \`bin/dss.js\` path to Bun or Node.
9
9
  \`--no-env-file\` disables Bun's automatic preloading only; the CLI still applies its documented \`.env\` handling unless \`DATAIKU_DISABLE_ENV=1\` is set.
10
10
 
11
11
  ## Contract
@@ -20,7 +20,7 @@ If the installed \`dss\` binary is unavailable but the repository checkout is th
20
20
 
21
21
  ## Discover commands
22
22
 
23
- \`\`\`bash
23
+ \`\`\`text
24
24
  dss agent contract
25
25
  dss commands run
26
26
  \`\`\`
@@ -31,30 +31,57 @@ Set \`DATAIKU_DISABLE_ENV=1\` when a test must ignore both \`.env\` files and \`
31
31
  When \`.env\` loading is enabled, the CLI reads \`.env\` from the command's current working directory first and then the CLI build/root directory; the invocation directory wins on conflicting keys. Put test-specific \`.env\` files in the directory where you invoke \`dss\`.
32
32
  For disposable agent tests, set \`DSS_CONFIG_DIR\` to a temporary directory so saved credentials never touch the real profile.
33
33
 
34
+ ## Planning, safety, and generic inputs
35
+
36
+ - Before any registry entry with \`sideEffect:"write"\`, run the exact argv with \`--plan\` first. Planning is local: it returns the derived operation without resolving credentials or calling DSS. Check \`destructive\`, \`idempotency\`, \`async\`, \`unsafeOutputs\`, and \`exitCodes\` before execution.
37
+ - Use \`--dry-run\` only when that action's registry entry has \`dryRun:true\`. \`--plan\` explains the operation; \`--dry-run\` exercises the action-specific simulation path. Never add an unsupported flag.
38
+ - When a create/upload action advertises \`--record-cleanup\`, pass \`--record-cleanup cleanup.jsonl\`. \`dss cleanup --file cleanup.jsonl\` previews the recorded cleanup steps in reverse order and does not mutate DSS; add \`--apply\` only after checking the preview.
39
+ - For JSON payload actions, follow \`inputContract\`, \`requiredFlags\`, and \`requiredOneOf\`. Prefer \`--data-file PATH\` or \`--stdin\` when advertised instead of inline \`--data\`; this preserves exact JSON across shells and keeps large or sensitive payloads out of process arguments.
40
+ - Authenticated actions advertise \`--request-timeout MS\` and \`--retries N\`. Long-running actions separately advertise controls such as \`--timeout MS\`, \`--poll-interval MS\`, and log limits; use only the flags in that action's registry entry.
41
+ - Before live mutation tests, use \`dss fixtures --json\` to discover compatible test resources instead of guessing project objects.
42
+
34
43
  ## Authentication
35
44
 
36
- Prefer environment variables for ephemeral agent runs:
45
+ Prefer environment variables for ephemeral agent runs. Use the syntax for the active shell:
37
46
 
38
- \`\`\`bash
47
+ POSIX shell:
48
+
49
+ \`\`\`sh
39
50
  export DATAIKU_URL=https://dss.example.com
40
51
  export DATAIKU_API_KEY=your-api-key
41
52
  export DATAIKU_PROJECT_KEY=MYPROJ
42
53
  \`\`\`
43
54
 
55
+ PowerShell:
56
+
57
+ \`\`\`powershell
58
+ $env:DATAIKU_URL = "https://dss.example.com"
59
+ $env:DATAIKU_API_KEY = "your-api-key"
60
+ $env:DATAIKU_PROJECT_KEY = "MYPROJ"
61
+ \`\`\`
62
+
63
+ Windows Command Prompt:
64
+
65
+ \`\`\`bat
66
+ set "DATAIKU_URL=https://dss.example.com"
67
+ set "DATAIKU_API_KEY=your-api-key"
68
+ set "DATAIKU_PROJECT_KEY=MYPROJ"
69
+ \`\`\`
70
+
44
71
  To persist credentials for later invocations:
45
72
 
46
73
  \`\`\`bash
47
74
  dss auth login --url https://dss.example.com --api-key YOUR_KEY --project-key MYPROJ
48
75
  \`\`\`
49
76
 
50
- The command saves credentials and returns \`{"saved":true,"path":"..."}\`. Credentials are saved to \`~/.config/dataiku/credentials.json\` unless \`DSS_CONFIG_DIR\` or platform config env vars redirect the path.
77
+ The command saves credentials and returns \`{"saved":true,"path":"..."}\`. \`DSS_CONFIG_DIR\` wins when set. Otherwise credentials use \`XDG_CONFIG_HOME/dataiku/credentials.json\`, the \`dataiku/credentials.json\` directory under \`APPDATA\` on Windows, or \`~/.config/dataiku/credentials.json\`.
51
78
  \`auth login\` validates by listing accessible projects before saving credentials, so the API key must be allowed to call DSS project-list APIs.
52
79
 
53
80
  TLS flags: \`--insecure\` disables certificate verification; \`--ca-cert PATH\` adds a PEM CA bundle. Environment equivalents: \`NODE_TLS_REJECT_UNAUTHORIZED\`, \`NODE_EXTRA_CA_CERTS\`.
54
81
 
55
82
  ## Common workflows
56
83
 
57
- \`\`\`bash
84
+ \`\`\`text
58
85
  dss version
59
86
  dss project list
60
87
  dss doctor --fast
@@ -77,10 +104,10 @@ For fake-DSS smoke tests, return project lists as JSON arrays such as \`[{"proje
77
104
 
78
105
  Mutations print a small JSON ack to stdout and exit 0 on success (e.g. \`{"updated":"NAME","resource":"recipe"}\`); on failure they print the error envelope to stderr and exit non-zero. The exit code is the source of truth.
79
106
 
80
- - Chain steps with \`&&\` so a failed step halts the sequence: \`dss recipe set-payload R --file r.py --project-key P && dss recipe update R --data-file env.json --project-key P\`.
81
- - Never pipe a mutation into a command that prints a fixed string or merges stderr (e.g. \`dss ... 2>&1 | helper; echo done\`): the pipeline returns the helper's exit code, so a failed mutation is reported as success.
107
+ - For portable multi-step writes, prefer \`dss batch\` (payload: a JSON array of argv arrays). It runs fail-fast, returns one envelope with per-step \`ok\`/\`result\`/\`error\`, and exits non-zero if any step fails.
108
+ - If separate processes are required, inspect each exit code and stop before launching the next step. Do not rely on shell chaining: syntax differs between POSIX shells, Windows PowerShell 5.1, PowerShell 7, and Command Prompt.
109
+ - Never pipe a mutation into a command that prints a fixed string or merges stderr: a pipeline may return the helper's exit code and report a failed mutation as success.
82
110
  - To branch in code, key off the exit code or the JSON ack on stdout — never a hardcoded label.
83
- - For multi-step writes, prefer \`dss batch\` (payload: a JSON array of argv arrays): it runs fail-fast, returns one envelope with per-step \`ok\`/\`result\`/\`error\`, and exits non-zero if any step fails — no shell chaining or per-step parsing.
84
111
 
85
112
  ## Platform & debugging notes
86
113
 
@@ -127,7 +154,7 @@ export const AGENTS = {
127
154
  name: "Claude Code",
128
155
  binary: "claude",
129
156
  configDir: ".claude",
130
- globalPath: (home) => join(home, ".claude", "skills", "dataiku-dss"),
157
+ globalPath: (home) => path.join(home, ".claude", "skills", "dataiku-dss"),
131
158
  projectPath: ".claude/skills/dataiku-dss",
132
159
  filename: "SKILL.md",
133
160
  content: skillContent,
@@ -136,7 +163,7 @@ export const AGENTS = {
136
163
  name: "Codex",
137
164
  binary: "codex",
138
165
  configDir: ".codex",
139
- globalPath: (home) => join(home, ".codex", "skills", "dataiku-dss"),
166
+ globalPath: (home) => path.join(home, ".codex", "skills", "dataiku-dss"),
140
167
  projectPath: ".codex/skills/dataiku-dss",
141
168
  filename: "SKILL.md",
142
169
  content: skillContent,
@@ -145,7 +172,7 @@ export const AGENTS = {
145
172
  name: "Cursor",
146
173
  binary: "cursor",
147
174
  configDir: ".cursor",
148
- globalPath: (home) => join(home, ".cursor", "skills", "dataiku-dss"),
175
+ globalPath: (home) => path.join(home, ".cursor", "skills", "dataiku-dss"),
149
176
  projectPath: ".cursor/skills/dataiku-dss",
150
177
  filename: "SKILL.md",
151
178
  content: skillContent,
@@ -154,7 +181,7 @@ export const AGENTS = {
154
181
  name: "Pi",
155
182
  binary: "pi",
156
183
  configDir: ".pi",
157
- globalPath: (home) => join(home, ".pi", "agent", "skills", "dataiku-dss"),
184
+ globalPath: (home) => path.join(home, ".pi", "agent", "skills", "dataiku-dss"),
158
185
  projectPath: ".pi/skills/dataiku-dss",
159
186
  filename: "SKILL.md",
160
187
  content: skillContent,
@@ -162,9 +189,9 @@ export const AGENTS = {
162
189
  omp: {
163
190
  name: "OhMyPi",
164
191
  binary: "omp",
165
- configDir: join(".omp", "agent"),
192
+ configDir: path.join(".omp", "agent"),
166
193
  configDirRequired: true,
167
- globalPath: (home) => join(home, ".omp", "agent", "skills", "dataiku-dss"),
194
+ globalPath: (home) => path.join(home, ".omp", "agent", "skills", "dataiku-dss"),
168
195
  projectPath: ".omp/skills/dataiku-dss",
169
196
  filename: "SKILL.md",
170
197
  content: skillContent,
@@ -184,11 +211,11 @@ function binaryExists(name) {
184
211
  }
185
212
  }
186
213
  export function detectAgents() {
187
- const home = homedir();
214
+ const home = os.homedir();
188
215
  const found = [];
189
216
  for (const [id, def,] of Object.entries(AGENTS)) {
190
217
  const hasBinary = binaryExists(def.binary);
191
- const hasConfigDir = existsSync(join(home, def.configDir));
218
+ const hasConfigDir = fs.existsSync(path.join(home, def.configDir));
192
219
  if (hasBinary && (!def.configDirRequired || hasConfigDir)) {
193
220
  found.push({ id, def, via: "binary", });
194
221
  }
@@ -213,10 +240,10 @@ export function findWorkspaceRoot(startDir) {
213
240
  let dir = startDir;
214
241
  for (let i = 0; i < 20; i++) {
215
242
  for (const marker of WORKSPACE_MARKERS) {
216
- if (existsSync(join(dir, marker)))
243
+ if (fs.existsSync(path.join(dir, marker)))
217
244
  return dir;
218
245
  }
219
- const parent = dirname(dir);
246
+ const parent = path.dirname(dir);
220
247
  if (parent === dir)
221
248
  break;
222
249
  dir = parent;
@@ -224,17 +251,17 @@ export function findWorkspaceRoot(startDir) {
224
251
  return startDir;
225
252
  }
226
253
  export function planSkillInstalls(agents, opts) {
227
- const home = homedir();
254
+ const home = os.homedir();
228
255
  const results = [];
229
256
  for (const { id, def, via, } of agents) {
230
257
  const dir = opts.global
231
258
  ? def.globalPath(home)
232
259
  : def.projectPath
233
- ? join(opts.cwd, def.projectPath)
260
+ ? path.join(opts.cwd, def.projectPath)
234
261
  : undefined;
235
262
  if (!dir)
236
263
  continue;
237
- results.push({ agent: id, path: join(dir, def.filename), via, });
264
+ results.push({ agent: id, path: path.join(dir, def.filename), via, });
238
265
  }
239
266
  return results;
240
267
  }
@@ -244,8 +271,8 @@ export function installSkill(agents, opts) {
244
271
  const def = AGENTS[result.agent];
245
272
  if (!def)
246
273
  continue;
247
- mkdirSync(dirname(result.path), { recursive: true, });
248
- writeFileSync(result.path, def.content(), "utf-8");
274
+ fs.mkdirSync(path.dirname(result.path), { recursive: true, });
275
+ fs.writeFileSync(result.path, def.content(), "utf-8");
249
276
  }
250
277
  return results;
251
278
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dataiku-sdk",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "Dataiku DSS SDK and CLI for programmatic access to DSS REST APIs",
5
5
  "type": "module",
6
6
  "workspaces": [
@@ -17,25 +17,28 @@
17
17
  "packages/types/dist/"
18
18
  ],
19
19
  "engines": {
20
- "bun": ">=1.0"
20
+ "node": ">=22.15.0",
21
+ "bun": ">=1.3.14"
21
22
  },
22
23
  "scripts": {
23
- "build": "tsc && cd packages/types && npx tsc",
24
- "prepack": "bun run build",
25
- "prepublishOnly": "bun run build",
24
+ "build": "tsc && tsc -p packages/types/tsconfig.json",
25
+ "prepack": "tsc && tsc -p packages/types/tsconfig.json",
26
+ "prepublishOnly": "tsc && tsc -p packages/types/tsconfig.json",
26
27
  "check": "tsc --noEmit",
27
28
  "lint": "oxlint src/",
28
29
  "lint:fix": "oxlint --fix src/",
29
30
  "format": "dprint fmt",
30
31
  "format:check": "dprint check",
31
32
  "test": "bun test",
32
- "test:integration": "RUN_DATAIKU_INTEGRATION=1 bun test tests/integration-playground.test.ts",
33
- "test:integration:mutating": "RUN_DATAIKU_INTEGRATION=1 RUN_DATAIKU_INTEGRATION_MUTATING=1 bun test tests/integration-playground.test.ts",
34
- "test:integration:rigorous": "RUN_DATAIKU_INTEGRATION=1 bun test tests/integration-rigorous.test.ts",
35
- "test:integration:rigorous:mutating": "RUN_DATAIKU_INTEGRATION=1 RUN_DATAIKU_INTEGRATION_MUTATING=1 bun test tests/integration-rigorous.test.ts"
33
+ "test:platform": "bun scripts/platform-smoke.mjs",
34
+ "test:integration": "cross-env RUN_DATAIKU_INTEGRATION=1 bun test tests/integration-playground.test.ts",
35
+ "test:integration:mutating": "cross-env RUN_DATAIKU_INTEGRATION=1 RUN_DATAIKU_INTEGRATION_MUTATING=1 bun test tests/integration-playground.test.ts",
36
+ "test:integration:rigorous": "cross-env RUN_DATAIKU_INTEGRATION=1 bun test tests/integration-rigorous.test.ts",
37
+ "test:integration:rigorous:mutating": "cross-env RUN_DATAIKU_INTEGRATION=1 RUN_DATAIKU_INTEGRATION_MUTATING=1 bun test tests/integration-rigorous.test.ts"
36
38
  },
37
39
  "devDependencies": {
38
40
  "@types/bun": "^1.3.14",
41
+ "cross-env": "^10.1.0",
39
42
  "dprint": "^0.54.0",
40
43
  "oxlint": "^1.68.0",
41
44
  "typescript": "^6.0.3"
@@ -53,5 +56,8 @@
53
56
  },
54
57
  "publishConfig": {
55
58
  "access": "public"
56
- }
59
+ },
60
+ "bundleDependencies": [
61
+ "@sinclair/typebox"
62
+ ]
57
63
  }
@@ -273,6 +273,11 @@ export declare const ScenarioStepRunSchema: import("@sinclair/typebox").TObject<
273
273
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
274
274
  type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
275
275
  outcome: import("@sinclair/typebox").TString;
276
+ warningCount: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
277
+ warnings: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
278
+ type: import("@sinclair/typebox").TString;
279
+ count: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
280
+ }>>>;
276
281
  }>;
277
282
  export type ScenarioStepRun = Static<typeof ScenarioStepRunSchema>;
278
283
  export declare const ScenarioWaitResultSchema: import("@sinclair/typebox").TObject<{
@@ -288,6 +293,11 @@ export declare const ScenarioWaitResultSchema: import("@sinclair/typebox").TObje
288
293
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
289
294
  type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
290
295
  outcome: import("@sinclair/typebox").TString;
296
+ warningCount: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
297
+ warnings: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
298
+ type: import("@sinclair/typebox").TString;
299
+ count: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
300
+ }>>>;
291
301
  }>>>;
292
302
  }>;
293
303
  export type ScenarioWaitResult = Static<typeof ScenarioWaitResultSchema>;
@@ -322,6 +322,11 @@ export const ScenarioStepRunSchema = Type.Object({
322
322
  name: Type.Optional(Type.String()),
323
323
  type: Type.Optional(Type.String()),
324
324
  outcome: Type.String(),
325
+ warningCount: Type.Optional(Type.Number()),
326
+ warnings: Type.Optional(Type.Array(Type.Object({
327
+ type: Type.String(),
328
+ count: Type.Optional(Type.Number()),
329
+ }, { additionalProperties: false, }))),
325
330
  }, { additionalProperties: false, });
326
331
  export const ScenarioWaitResultSchema = Type.Object({
327
332
  scenarioId: Type.String(),