dataiku-sdk 0.6.1 → 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 +85 -0
- package/bin/dss.js +39 -13
- package/dist/packages/types/src/index.d.ts +21 -0
- package/dist/packages/types/src/index.js +7 -0
- package/dist/src/cli.js +1237 -505
- package/dist/src/client.d.ts +18 -17
- package/dist/src/client.js +49 -36
- package/dist/src/config.d.ts +0 -2
- package/dist/src/config.js +1 -16
- package/dist/src/errors.d.ts +2 -1
- package/dist/src/errors.js +3 -1
- package/dist/src/index.d.ts +4 -4
- package/dist/src/index.js +2 -2
- package/dist/src/resources/datasets.d.ts +21 -7
- package/dist/src/resources/datasets.js +85 -70
- package/dist/src/resources/flow-zones.d.ts +1 -1
- package/dist/src/resources/flow-zones.js +3 -1
- package/dist/src/resources/jobs.d.ts +1 -0
- package/dist/src/resources/jobs.js +1 -1
- package/dist/src/resources/recipes.d.ts +1 -0
- package/dist/src/resources/recipes.js +42 -2
- package/dist/src/resources/scenarios.d.ts +24 -0
- package/dist/src/resources/scenarios.js +161 -0
- package/dist/src/schemas.d.ts +2 -2
- package/dist/src/schemas.js +1 -1
- package/dist/src/skill.d.ts +5 -0
- package/dist/src/skill.js +93 -100
- package/dist/src/utils/cleanup-ledger.js +22 -1
- package/package.json +2 -1
- package/packages/types/dist/index.d.ts +21 -0
- package/packages/types/dist/index.js +7 -0
|
@@ -24,15 +24,17 @@ export class FlowZonesResource extends BaseResource {
|
|
|
24
24
|
const raw = await this.client.post(`/public/api/projects/${this.enc(opts.projectKey)}/flow/zones`, {
|
|
25
25
|
name: opts.name,
|
|
26
26
|
color: opts.color ?? "#2ab1ac",
|
|
27
|
+
...(opts.position !== undefined ? { position: opts.position, } : {}),
|
|
27
28
|
});
|
|
28
29
|
return this.client.safeParse(FlowZoneSchema, raw, "flowZones.create");
|
|
29
30
|
}
|
|
30
|
-
/** Update flow zone settings such as name and
|
|
31
|
+
/** Update flow zone settings such as name, color, and manual position. */
|
|
31
32
|
async update(zoneId, opts) {
|
|
32
33
|
const current = await this.get(zoneId, opts.projectKey);
|
|
33
34
|
const merged = deepMerge(current, {
|
|
34
35
|
...(opts.name !== undefined ? { name: opts.name, } : {}),
|
|
35
36
|
...(opts.color !== undefined ? { color: opts.color, } : {}),
|
|
37
|
+
...(opts.position !== undefined ? { position: opts.position, } : {}),
|
|
36
38
|
});
|
|
37
39
|
await this.client.putVoid(`/public/api/projects/${this.enc(opts.projectKey)}/flow/zones/${encodeURIComponent(zoneId)}`, merged);
|
|
38
40
|
return this.get(zoneId, opts.projectKey);
|
|
@@ -181,7 +181,7 @@ export class JobsResource extends BaseResource {
|
|
|
181
181
|
// DSS cat-activity-log URLs require a browser session; API-key callers must use the public log endpoint.
|
|
182
182
|
const path = `/public/api/projects/${this.enc(opts?.projectKey)}/jobs/${jobEnc}/log/${query}`;
|
|
183
183
|
const log = await this.client.getText(path);
|
|
184
|
-
return limitJobLog(log, opts?.maxLogLines);
|
|
184
|
+
return limitJobLog(filterJobLog(log, opts?.logFilter), opts?.maxLogLines);
|
|
185
185
|
}
|
|
186
186
|
async logFromUrl(logUrl, opts) {
|
|
187
187
|
const parsed = new URL(logUrl, "http://dss.local");
|
|
@@ -108,7 +108,44 @@ function rewriteRefs(value, rewrites) {
|
|
|
108
108
|
function escapedRegExp(value) {
|
|
109
109
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
110
110
|
}
|
|
111
|
-
function
|
|
111
|
+
function isSqlRecipeType(recipeType) {
|
|
112
|
+
return typeof recipeType === "string" && recipeType.toLowerCase().includes("sql");
|
|
113
|
+
}
|
|
114
|
+
function rewriteSqlTableReferences(payload, rewrites) {
|
|
115
|
+
const bareIdentifierPattern = /^[A-Za-z_][A-Za-z0-9_$]*(?:\.[A-Za-z_][A-Za-z0-9_$]*)*$/;
|
|
116
|
+
const escapeQuotedIdentifier = (identifier, quote) => {
|
|
117
|
+
if (quote === "\"")
|
|
118
|
+
return identifier.replace(/"/g, '""');
|
|
119
|
+
if (quote === "`")
|
|
120
|
+
return identifier.replace(/`/g, "``");
|
|
121
|
+
return identifier;
|
|
122
|
+
};
|
|
123
|
+
const escapeBracketIdentifier = (identifier) => identifier.replace(/\]/g, "]]");
|
|
124
|
+
let next = payload;
|
|
125
|
+
for (const [from, to,] of Object.entries(rewrites)) {
|
|
126
|
+
if (!from)
|
|
127
|
+
continue;
|
|
128
|
+
const escaped = escapedRegExp(from);
|
|
129
|
+
const pattern = new RegExp(String
|
|
130
|
+
.raw `\b(FROM|JOIN)(\s+)(?:(["\`])${escaped}\3|(\[)${escaped}\]|${escaped})(?![A-Za-z0-9_.])`, "gi");
|
|
131
|
+
next = next.replace(pattern, (_match, keyword, space, quote, bracket) => {
|
|
132
|
+
if (quote) {
|
|
133
|
+
const escapedTo = escapeQuotedIdentifier(to, quote);
|
|
134
|
+
return `${keyword}${space}${quote}${escapedTo}${quote}`;
|
|
135
|
+
}
|
|
136
|
+
if (bracket) {
|
|
137
|
+
const escapedTo = escapeBracketIdentifier(to);
|
|
138
|
+
return `${keyword}${space}[${escapedTo}]`;
|
|
139
|
+
}
|
|
140
|
+
if (!bareIdentifierPattern.test(to)) {
|
|
141
|
+
throw new Error(`Unsafe SQL rewrite target for ${from}: ${to}`);
|
|
142
|
+
}
|
|
143
|
+
return `${keyword}${space}${to}`;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return next;
|
|
147
|
+
}
|
|
148
|
+
function rewritePayload(payload, rewrites, payloadTextRewrites = {}, recipeType) {
|
|
112
149
|
if (payload === undefined
|
|
113
150
|
|| (Object.keys(rewrites).length === 0 && Object.keys(payloadTextRewrites).length === 0)) {
|
|
114
151
|
return payload;
|
|
@@ -120,6 +157,9 @@ function rewritePayload(payload, rewrites, payloadTextRewrites = {}) {
|
|
|
120
157
|
const escaped = escapedRegExp(from);
|
|
121
158
|
next = next.replace(new RegExp(`\\bdataiku\\.(Dataset|Folder)\\(\\s*(['"])${escaped}\\2\\s*\\)`, "g"), (_match, kind, quote) => `dataiku.${kind}(${quote}${to}${quote})`);
|
|
122
159
|
}
|
|
160
|
+
if (isSqlRecipeType(recipeType)) {
|
|
161
|
+
next = rewriteSqlTableReferences(next, rewrites);
|
|
162
|
+
}
|
|
123
163
|
for (const [from, to,] of Object.entries(payloadTextRewrites)) {
|
|
124
164
|
if (from.length > 0)
|
|
125
165
|
next = next.split(from).join(to);
|
|
@@ -647,7 +687,7 @@ export class RecipesResource extends BaseResource {
|
|
|
647
687
|
if (opts.payloadTextRewrites)
|
|
648
688
|
Object.assign(payloadTextRewrites, opts.payloadTextRewrites);
|
|
649
689
|
const recipe = cloneRecipeDefinition(source.recipe, opts.name, pk, graphRewrites);
|
|
650
|
-
const payload = rewritePayload(source.payload, payloadRewrites, payloadTextRewrites);
|
|
690
|
+
const payload = rewritePayload(source.payload, payloadRewrites, payloadTextRewrites, opts.recipeType ?? source.recipe.type);
|
|
651
691
|
const copiedOutputDatasets = [];
|
|
652
692
|
if (opts.copyOutputSettings) {
|
|
653
693
|
for (const [from, to,] of Object.entries(outputRewrites)) {
|
|
@@ -31,6 +31,17 @@ export interface ScenarioUpdateResult extends ScenarioUpdatePreview {
|
|
|
31
31
|
verified: true;
|
|
32
32
|
mismatches: [];
|
|
33
33
|
}
|
|
34
|
+
export interface ScenarioScriptRunResult {
|
|
35
|
+
scenarioId: string;
|
|
36
|
+
runId: string;
|
|
37
|
+
outcome: string;
|
|
38
|
+
success: boolean;
|
|
39
|
+
elapsedMs: number;
|
|
40
|
+
pollCount: number;
|
|
41
|
+
output?: string;
|
|
42
|
+
log: string;
|
|
43
|
+
envName?: string;
|
|
44
|
+
}
|
|
34
45
|
export declare function normalizeScenarioUpdateData(data: Record<string, unknown>): {
|
|
35
46
|
normalizedData: Record<string, unknown>;
|
|
36
47
|
normalization: ScenarioUpdateNormalization[];
|
|
@@ -68,4 +79,17 @@ export declare class ScenariosResource extends BaseResource {
|
|
|
68
79
|
timeoutMs?: number;
|
|
69
80
|
projectKey?: string;
|
|
70
81
|
}): Promise<ScenarioWaitResult>;
|
|
82
|
+
/**
|
|
83
|
+
* Run a one-off Python script in a throwaway custom-python scenario and return
|
|
84
|
+
* its outcome plus the captured run log. The scenario is deleted afterward
|
|
85
|
+
* unless `keepScenario` is set. This is the only DSS public-API path to execute
|
|
86
|
+
* ad-hoc code in a code env without a persisted recipe or notebook.
|
|
87
|
+
*/
|
|
88
|
+
runScript(script: string, opts?: {
|
|
89
|
+
envName?: string;
|
|
90
|
+
projectKey?: string;
|
|
91
|
+
timeoutMs?: number;
|
|
92
|
+
pollIntervalMs?: number;
|
|
93
|
+
keepScenario?: boolean;
|
|
94
|
+
}): Promise<ScenarioScriptRunResult>;
|
|
71
95
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID, } from "node:crypto";
|
|
1
2
|
import { DataikuError, } from "../errors.js";
|
|
2
3
|
import { ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, } from "../schemas.js";
|
|
3
4
|
import { deepMerge, } from "../utils/deep-merge.js";
|
|
@@ -11,6 +12,76 @@ export const SCENARIO_CANONICAL_EDITABLE_FIELDS = [
|
|
|
11
12
|
"active",
|
|
12
13
|
"name",
|
|
13
14
|
];
|
|
15
|
+
const CODE_RUN_OUTPUT_START = "<<<DSS_CODE_RUN_OUTPUT_b7e3a1>>>";
|
|
16
|
+
const CODE_RUN_OUTPUT_END = "<<<DSS_CODE_RUN_OUTPUT_END_b7e3a1>>>";
|
|
17
|
+
/**
|
|
18
|
+
* Wrap a user Python script so its stdout/stderr (and any traceback) are captured
|
|
19
|
+
* into a buffer and re-emitted between unique markers, isolated from DSS scenario
|
|
20
|
+
* wrapper noise. The script is base64-encoded to avoid quoting/escaping issues and
|
|
21
|
+
* exec'd as `__main__`. A failing script re-raises SystemExit(1) so the scenario
|
|
22
|
+
* outcome is FAILED while the captured traceback still lands between the markers.
|
|
23
|
+
*/
|
|
24
|
+
function buildCodeRunScript(script) {
|
|
25
|
+
const encoded = Buffer.from(script, "utf-8").toString("base64");
|
|
26
|
+
return [
|
|
27
|
+
"import base64 as _dku_b64, sys as _dku_sys, io as _dku_io, traceback as _dku_tb",
|
|
28
|
+
`_dku_src = _dku_b64.b64decode("${encoded}").decode("utf-8")`,
|
|
29
|
+
"_dku_buf = _dku_io.StringIO()",
|
|
30
|
+
"_dku_out, _dku_err = _dku_sys.stdout, _dku_sys.stderr",
|
|
31
|
+
"_dku_sys.stdout = _dku_sys.stderr = _dku_buf",
|
|
32
|
+
"_dku_code = 0",
|
|
33
|
+
"try:",
|
|
34
|
+
'\texec(compile(_dku_src, "<dss_code_run>", "exec"), {"__name__": "__main__"})',
|
|
35
|
+
"except SystemExit as _dku_e:",
|
|
36
|
+
"\t_dku_code = _dku_e.code if isinstance(_dku_e.code, int) else (0 if _dku_e.code is None else 1)",
|
|
37
|
+
"except BaseException:",
|
|
38
|
+
"\t_dku_code = 1",
|
|
39
|
+
"\t_dku_tb.print_exc()",
|
|
40
|
+
"finally:",
|
|
41
|
+
"\t_dku_sys.stdout, _dku_sys.stderr = _dku_out, _dku_err",
|
|
42
|
+
`\t_dku_out.write("${CODE_RUN_OUTPUT_START}\\n")`,
|
|
43
|
+
"\t_dku_out.write(_dku_buf.getvalue())",
|
|
44
|
+
`\t_dku_out.write("\\n${CODE_RUN_OUTPUT_END}\\n")`,
|
|
45
|
+
"\t_dku_out.flush()",
|
|
46
|
+
"if _dku_code:",
|
|
47
|
+
"\traise SystemExit(_dku_code)",
|
|
48
|
+
"",
|
|
49
|
+
].join("\n");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Pull the script's own stdout/stderr back out of the full DSS run log by slicing
|
|
53
|
+
* the `[process]` lines between the markers emitted by {@link buildCodeRunScript}.
|
|
54
|
+
* Returns undefined if the markers are absent (e.g. the harness never ran), in which
|
|
55
|
+
* case callers should fall back to the full log.
|
|
56
|
+
*/
|
|
57
|
+
function extractCodeRunOutput(log) {
|
|
58
|
+
const messageRe = /^\[[^\]]*\] \[[^\]]*\] \[[^\]]*\] \[process\] - (.*)$/;
|
|
59
|
+
const contents = [];
|
|
60
|
+
for (const rawLine of log.split("\n")) {
|
|
61
|
+
const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
|
|
62
|
+
const match = messageRe.exec(line);
|
|
63
|
+
if (match)
|
|
64
|
+
contents.push(match[1] ?? "");
|
|
65
|
+
}
|
|
66
|
+
// First start + last end, so a script that prints a marker string stays body content.
|
|
67
|
+
const start = contents.indexOf(CODE_RUN_OUTPUT_START);
|
|
68
|
+
if (start < 0)
|
|
69
|
+
return undefined;
|
|
70
|
+
let end = -1;
|
|
71
|
+
for (let i = contents.length - 1; i > start; i--) {
|
|
72
|
+
if (contents[i] === CODE_RUN_OUTPUT_END) {
|
|
73
|
+
end = i;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (end < 0)
|
|
78
|
+
return undefined;
|
|
79
|
+
const body = contents.slice(start + 1, end);
|
|
80
|
+
// Drop only the single trailing separator the harness writes before the end marker.
|
|
81
|
+
if (body.length > 0 && body[body.length - 1] === "")
|
|
82
|
+
body.pop();
|
|
83
|
+
return body.join("\n");
|
|
84
|
+
}
|
|
14
85
|
function isRecord(value) {
|
|
15
86
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16
87
|
}
|
|
@@ -260,4 +331,94 @@ export class ScenariosResource extends BaseResource {
|
|
|
260
331
|
await new Promise((r) => setTimeout(r, Math.min(nextDelayMs, timeout - elapsedMs)));
|
|
261
332
|
}
|
|
262
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* Run a one-off Python script in a throwaway custom-python scenario and return
|
|
336
|
+
* its outcome plus the captured run log. The scenario is deleted afterward
|
|
337
|
+
* unless `keepScenario` is set. This is the only DSS public-API path to execute
|
|
338
|
+
* ad-hoc code in a code env without a persisted recipe or notebook.
|
|
339
|
+
*/
|
|
340
|
+
async runScript(script, opts) {
|
|
341
|
+
const pk = this.resolveProjectKey(opts?.projectKey);
|
|
342
|
+
const pkEnc = this.enc(opts?.projectKey);
|
|
343
|
+
const scenarioId = `dss_cli_code_run_${Date.now()}_${randomUUID().replace(/-/g, "")}`;
|
|
344
|
+
const base = `/public/api/projects/${pkEnc}/scenarios/${encodeURIComponent(scenarioId)}`;
|
|
345
|
+
const envSelection = opts?.envName
|
|
346
|
+
? { envMode: "EXPLICIT_ENV", envName: opts.envName, }
|
|
347
|
+
: { envMode: "INHERIT", };
|
|
348
|
+
const startedAt = Date.now();
|
|
349
|
+
const baseIntervalMs = Math.max(1, opts?.pollIntervalMs ?? 2_000);
|
|
350
|
+
const adaptivePolling = opts?.pollIntervalMs === undefined;
|
|
351
|
+
const timeout = Math.max(baseIntervalMs, opts?.timeoutMs ?? 120_000);
|
|
352
|
+
try {
|
|
353
|
+
await this.client.post(`/public/api/projects/${pkEnc}/scenarios/`, {
|
|
354
|
+
id: scenarioId,
|
|
355
|
+
name: `dss code run (${scenarioId})`,
|
|
356
|
+
projectKey: pk,
|
|
357
|
+
type: "custom_python",
|
|
358
|
+
params: { envSelection, },
|
|
359
|
+
});
|
|
360
|
+
await this.client.putVoid(`${base}/payload`, { script: buildCodeRunScript(script), extension: "py", });
|
|
361
|
+
const trigger = await this.client.post(`${base}/run/`, {});
|
|
362
|
+
const triggerObj = trigger.trigger;
|
|
363
|
+
const triggerId = triggerObj?.id ?? "manual";
|
|
364
|
+
const triggerRunId = String(trigger.runId ?? "");
|
|
365
|
+
if (!triggerRunId) {
|
|
366
|
+
throw new DataikuError(500, "Scenario run not started", `Scenario "${scenarioId}" run trigger returned no run id; cannot track the run.`);
|
|
367
|
+
}
|
|
368
|
+
const trigQuery = `triggerId=${encodeURIComponent(triggerId)}&triggerRunId=${encodeURIComponent(triggerRunId)}`;
|
|
369
|
+
let runId = "";
|
|
370
|
+
let outcome = "UNKNOWN";
|
|
371
|
+
let pollCount = 0;
|
|
372
|
+
while (true) {
|
|
373
|
+
if (Date.now() - startedAt >= timeout) {
|
|
374
|
+
outcome = "TIMEOUT";
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
pollCount += 1;
|
|
378
|
+
const run = await this.client.get(`${base}/get-run-for-trigger?${trigQuery}`);
|
|
379
|
+
const scenarioRun = run.scenarioRun;
|
|
380
|
+
if (scenarioRun) {
|
|
381
|
+
runId = scenarioRun.runId ?? runId;
|
|
382
|
+
const result = scenarioRun.result;
|
|
383
|
+
const finished = result?.outcome;
|
|
384
|
+
if (finished) {
|
|
385
|
+
outcome = finished;
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const nextDelayMs = computeNextPollDelayMs({
|
|
390
|
+
pollCount,
|
|
391
|
+
baseIntervalMs,
|
|
392
|
+
adaptiveEnabled: adaptivePolling,
|
|
393
|
+
});
|
|
394
|
+
await new Promise((r) => setTimeout(r, Math.min(nextDelayMs, Math.max(1, timeout - (Date.now() - startedAt)))));
|
|
395
|
+
}
|
|
396
|
+
let log = "";
|
|
397
|
+
if (runId && outcome !== "TIMEOUT") {
|
|
398
|
+
log = await this.client.getText(`${base}/${encodeURIComponent(runId)}/log`);
|
|
399
|
+
}
|
|
400
|
+
const output = extractCodeRunOutput(log);
|
|
401
|
+
return {
|
|
402
|
+
scenarioId,
|
|
403
|
+
runId,
|
|
404
|
+
outcome,
|
|
405
|
+
success: outcome === "SUCCESS",
|
|
406
|
+
elapsedMs: Date.now() - startedAt,
|
|
407
|
+
pollCount,
|
|
408
|
+
output,
|
|
409
|
+
log,
|
|
410
|
+
...(opts?.envName ? { envName: opts.envName, } : {}),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
finally {
|
|
414
|
+
if (opts?.keepScenario !== true) {
|
|
415
|
+
try {
|
|
416
|
+
await this.client.del(base);
|
|
417
|
+
}
|
|
418
|
+
catch {
|
|
419
|
+
// Best-effort cleanup of the throwaway scenario.
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
263
424
|
}
|
package/dist/src/schemas.d.ts
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* The types package (packages/types/) owns the TypeBox schema definitions.
|
|
4
4
|
* SDK consumers get everything through this re-export.
|
|
5
5
|
*/
|
|
6
|
-
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
|
|
7
|
-
export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvWaitOptions, ConnectionSummary, DashboardDetails, DashboardSummary, DataQualityComputeResult, DataQualityProjectStatus, DataQualityRule, DataQualityRuleResult, DataQualityRules, DataQualityStatus, DataQualityStatusByPartition, DataQualityTimeline, DataQualityTimelineEntry, DatasetCreateOptions, DatasetDetails, DatasetSchema, DatasetSummary, FlowMapOptions, FlowZone, FlowZoneCreateOptions, FlowZoneItem, FlowZoneObjectType, FlowZoneUpdateOptions, FolderCreateOptions, FolderDetails, FolderItem, FolderSummary, FutureState, FutureWaitResult, InsightDetails, InsightSummary, JobSummary, JobWaitResult, JupyterCell, JupyterNotebookContent, JupyterNotebookSummary, NotebookSession, ProjectDetails, ProjectMetadata, ProjectSummary, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, SafeParseResult, ScenarioDetails, ScenarioStatus, ScenarioSummary, ScenarioWaitResult, SqlNotebookCell, SqlNotebookContent, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "../packages/types/src/index.js";
|
|
6
|
+
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZonePositionSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
|
|
7
|
+
export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvWaitOptions, ConnectionSummary, DashboardDetails, DashboardSummary, DataQualityComputeResult, DataQualityProjectStatus, DataQualityRule, DataQualityRuleResult, DataQualityRules, DataQualityStatus, DataQualityStatusByPartition, DataQualityTimeline, DataQualityTimelineEntry, DatasetCreateOptions, DatasetDetails, DatasetSchema, DatasetSummary, FlowMapOptions, FlowZone, FlowZoneCreateOptions, FlowZoneItem, FlowZoneObjectType, FlowZonePosition, FlowZoneUpdateOptions, FolderCreateOptions, FolderDetails, FolderItem, FolderSummary, FutureState, FutureWaitResult, InsightDetails, InsightSummary, JobSummary, JobWaitResult, JupyterCell, JupyterNotebookContent, JupyterNotebookSummary, NotebookSession, ProjectDetails, ProjectMetadata, ProjectSummary, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, SafeParseResult, ScenarioDetails, ScenarioStatus, ScenarioSummary, ScenarioWaitResult, SqlNotebookCell, SqlNotebookContent, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "../packages/types/src/index.js";
|
package/dist/src/schemas.js
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* The types package (packages/types/) owns the TypeBox schema definitions.
|
|
4
4
|
* SDK consumers get everything through this re-export.
|
|
5
5
|
*/
|
|
6
|
-
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
|
|
6
|
+
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZonePositionSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
|
package/dist/src/skill.d.ts
CHANGED
|
@@ -31,7 +31,12 @@ export declare function findWorkspaceRoot(startDir: string): string;
|
|
|
31
31
|
export interface InstallResult {
|
|
32
32
|
agent: string;
|
|
33
33
|
path: string;
|
|
34
|
+
via: DetectedAgent["via"];
|
|
34
35
|
}
|
|
36
|
+
export declare function planSkillInstalls(agents: DetectedAgent[], opts: {
|
|
37
|
+
global: boolean;
|
|
38
|
+
cwd: string;
|
|
39
|
+
}): InstallResult[];
|
|
35
40
|
export declare function installSkill(agents: DetectedAgent[], opts: {
|
|
36
41
|
global: boolean;
|
|
37
42
|
cwd: string;
|
package/dist/src/skill.js
CHANGED
|
@@ -2,124 +2,118 @@ import { execFileSync, } from "node:child_process";
|
|
|
2
2
|
import { existsSync, mkdirSync, writeFileSync, } from "node:fs";
|
|
3
3
|
import { homedir, } from "node:os";
|
|
4
4
|
import { dirname, join, } from "node:path";
|
|
5
|
-
const SKILL_BODY = `# Dataiku DSS CLI
|
|
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 ...\`.
|
|
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.
|
|
8
10
|
|
|
9
|
-
##
|
|
11
|
+
## Contract
|
|
10
12
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
13
|
+
- Success writes exactly one JSON result to stdout.
|
|
14
|
+
- Failure writes exactly one JSON error envelope to stderr with \`ok:false\`, \`error\`, \`code\`, and \`exitCode\`.
|
|
15
|
+
- \`--verbose\` may add HTTP trace lines to stderr.
|
|
16
|
+
- No prompts, help screens, tables, banners, or prose output are part of the contract.
|
|
17
|
+
- Exit codes: 0 success, 1 usage/configuration error, 2 DSS or internal error, 3 transient/retryable DSS error, 4 completed command with failed long-running DSS work.
|
|
18
|
+
- \`--raw\` is the only stdout escape hatch: recipe payload commands emit raw bytes to stdout unless \`--output PATH\` is also set; with \`--output\`, stdout is the JSON string equal to \`PATH\` and the file receives exact raw bytes.
|
|
19
|
+
- \`--fields a,b,c\` projects those fields from object or array-of-objects results; dotted paths (\`a.b.c\`) drill into nested objects, and missing fields become \`null\`; string and scalar results pass through unchanged.
|
|
16
20
|
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
Requires [Bun](https://bun.sh) runtime.
|
|
21
|
+
## Discover commands
|
|
20
22
|
|
|
21
23
|
\`\`\`bash
|
|
22
|
-
|
|
24
|
+
dss commands run
|
|
23
25
|
\`\`\`
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
The registry is the canonical schema for resources, actions, flags, positional arguments, side effects, auth requirements, output shape, idempotency, dry-run support, payload schemas, cleanup hints, and exit codes. Use it before choosing command syntax.
|
|
28
|
+
Credential lookup order is flags first, then \`DATAIKU_*\` environment variables, then saved credentials.
|
|
29
|
+
Set \`DATAIKU_DISABLE_ENV=1\` when a test must ignore both \`.env\` files and \`DATAIKU_*\` environment variables.
|
|
30
|
+
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\`.
|
|
31
|
+
For disposable agent tests, set \`DSS_CONFIG_DIR\` to a temporary directory so saved credentials never touch the real profile.
|
|
30
32
|
|
|
31
33
|
## Authentication
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
dss auth login # interactive: prompts for URL, API key, project key
|
|
35
|
-
dss auth login --url https://dss.example.com --api-key YOUR_KEY
|
|
36
|
-
dss auth status # verify connection
|
|
37
|
-
\`\`\`
|
|
38
|
-
|
|
39
|
-
Credentials are saved to \`~/.config/dataiku/credentials.json\`. Alternatively set environment variables:
|
|
35
|
+
Prefer environment variables for ephemeral agent runs:
|
|
40
36
|
|
|
41
37
|
\`\`\`bash
|
|
42
38
|
export DATAIKU_URL=https://dss.example.com
|
|
43
39
|
export DATAIKU_API_KEY=your-api-key
|
|
44
|
-
export DATAIKU_PROJECT_KEY=MYPROJ
|
|
40
|
+
export DATAIKU_PROJECT_KEY=MYPROJ
|
|
45
41
|
\`\`\`
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
### Inspect a project
|
|
43
|
+
To persist credentials for later invocations:
|
|
50
44
|
|
|
51
45
|
\`\`\`bash
|
|
52
|
-
dss
|
|
53
|
-
dss dataset list --project-key MYPROJ # list its datasets
|
|
54
|
-
dss dataset preview orders --max-rows 10 # peek at data
|
|
55
|
-
dss dataset schema orders # inspect columns
|
|
46
|
+
dss auth login --url https://dss.example.com --api-key YOUR_KEY --project-key MYPROJ
|
|
56
47
|
\`\`\`
|
|
57
48
|
|
|
58
|
-
|
|
49
|
+
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.
|
|
50
|
+
\`auth login\` validates by listing accessible projects before saving credentials, so the API key must be allowed to call DSS project-list APIs.
|
|
59
51
|
|
|
60
|
-
|
|
61
|
-
dss recipe download-code my-recipe -o code.py # download
|
|
62
|
-
# ... edit code.py ...
|
|
63
|
-
dss recipe diff my-recipe --file code.py # review changes
|
|
64
|
-
dss recipe set-payload my-recipe --file code.py # upload
|
|
65
|
-
\`\`\`
|
|
52
|
+
TLS flags: \`--insecure\` disables certificate verification; \`--ca-cert PATH\` adds a PEM CA bundle. Environment equivalents: \`NODE_TLS_REJECT_UNAUTHORIZED\`, \`NODE_EXTRA_CA_CERTS\`.
|
|
66
53
|
|
|
67
|
-
|
|
54
|
+
## Common workflows
|
|
68
55
|
|
|
69
56
|
\`\`\`bash
|
|
70
|
-
dss
|
|
71
|
-
dss
|
|
72
|
-
dss
|
|
57
|
+
dss version
|
|
58
|
+
dss project list
|
|
59
|
+
dss doctor --fast
|
|
60
|
+
dss dataset list --project-key MYPROJ
|
|
61
|
+
dss dataset list --project-key MYPROJ --fields name,type
|
|
62
|
+
dss dataset preview orders --max-rows 10 --project-key MYPROJ
|
|
63
|
+
dss recipe get-payload compute_orders --project-key MYPROJ
|
|
64
|
+
dss recipe get-payload compute_orders --raw --project-key MYPROJ
|
|
65
|
+
dss recipe get-payload compute_orders --raw --output code.py --project-key MYPROJ
|
|
66
|
+
dss recipe diff compute_orders --file code.py --project-key MYPROJ
|
|
67
|
+
dss recipe set-payload compute_orders --file code.py --project-key MYPROJ
|
|
68
|
+
dss job build-and-wait orders --include-logs --project-key MYPROJ
|
|
69
|
+
dss scenario run daily_build --project-key MYPROJ
|
|
70
|
+
dss sql query --connection analytics --sql "select 1" --project-key MYPROJ
|
|
71
|
+
dss batch --data-file steps.json
|
|
73
72
|
\`\`\`
|
|
73
|
+
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":"..."}\`.
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
## Confirming mutations
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
dss scenario run my-scenario
|
|
79
|
-
dss scenario status my-scenario # check if finished
|
|
80
|
-
\`\`\`
|
|
77
|
+
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.
|
|
81
78
|
|
|
82
|
-
|
|
79
|
+
- 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\`.
|
|
80
|
+
- 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.
|
|
81
|
+
- To branch in code, key off the exit code or the JSON ack on stdout — never a hardcoded label.
|
|
82
|
+
- 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.
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
dss <resource> <action> [args...] [--flags]
|
|
84
|
+
## Platform & debugging notes
|
|
86
85
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
- Pass code and SQL via \`--file\`/\`--sql-file\`, not inline: shells (especially PowerShell) mangle quotes, \`$\`, and newlines in multi-line snippets.
|
|
87
|
+
- On a non-UTF-8 console (e.g. Windows cp1252), don't print non-ASCII results; write them to a UTF-8 file and read that, or use \`--output PATH\`.
|
|
88
|
+
- Build failures: \`dss job log <id> --errors-only\` surfaces just error/traceback lines, and \`--output PATH\` saves the full log to a file. Logs are one long line with JVM noise; the \`Error in Python process: At line <N>\` marker maps \`<N>\` straight to your recipe payload's source line.
|
|
89
|
+
- Schema changes aren't automatic: after changing a recipe's output columns run \`dss dataset refresh-schema\` (or rebuild) before downstream reads, and \`dss dataset validate-build\` to catch file-backed misconfig before launching a build.
|
|
90
|
+
- \`dss dataset download\` is capped (default 100k rows) and returns \`{ path, rows, truncated, limit }\`: check \`truncated\` and raise \`--limit N\` when you need more — treat it as a sample, not a guaranteed full export. For very large tables, aggregate in SQL or read inside a recipe instead.
|
|
90
91
|
|
|
91
|
-
|
|
92
|
+
## Error envelope
|
|
92
93
|
|
|
93
|
-
|
|
94
|
+
Parse stderr as JSON when exit code is non-zero:
|
|
94
95
|
|
|
96
|
+
\`\`\`json
|
|
97
|
+
{
|
|
98
|
+
"ok": false,
|
|
99
|
+
"error": "Missing API key.",
|
|
100
|
+
"code": "usage_error",
|
|
101
|
+
"category": "usage",
|
|
102
|
+
"exitCode": 1,
|
|
103
|
+
"resource": "dataset",
|
|
104
|
+
"action": "list"
|
|
105
|
+
}
|
|
95
106
|
\`\`\`
|
|
96
|
-
-f, --format FORMAT json (default) | tsv | table | quiet
|
|
97
|
-
-o, --output PATH write output to file instead of stdout
|
|
98
|
-
-v, --verbose log HTTP requests to stderr
|
|
99
|
-
--project-key KEY override default project for any command
|
|
100
|
-
--timeout MS request timeout (default: 30000)
|
|
101
|
-
--insecure disable TLS certificate verification
|
|
102
|
-
--ca-cert PATH trust an extra PEM CA bundle
|
|
103
|
-
--stdin read command input from stdin (JSON or SQL, depending on command)
|
|
104
|
-
\`\`\`
|
|
105
|
-
|
|
106
|
-
## Gotchas
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
- **Output is JSON by default.** Use \`-f table\` when showing results to a user; use \`-f tsv\` when piping to scripts.
|
|
110
|
-
- **\`dss job build\` returns immediately.** Use \`dss job build-and-wait\` to block until the build finishes. Add \`--include-logs\` to stream log output.
|
|
111
|
-
- **Folder commands accept names or IDs.** If a folder name contains spaces, quote it. The CLI resolves names to IDs automatically.
|
|
112
|
-
- **Recipe set-payload overwrites the entire payload.** Always download first, edit, diff, then upload.
|
|
113
|
-
- **Transient errors exit code 3, API errors exit code 2, usage errors exit code 1.** Check exit codes to distinguish retriable failures.
|
|
108
|
+
Use \`code\`, \`category\`, \`exitCode\`, \`retryable\`, \`status\`, and \`details\` for recovery logic. Do not scrape message text when a structured field is available.
|
|
114
109
|
`;
|
|
115
110
|
const SKILL_FRONTMATTER = `---
|
|
116
111
|
name: dataiku-dss
|
|
117
112
|
description: >-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
even if they don't explicitly mention the dss CLI.
|
|
113
|
+
Agent-only JSON CLI for Dataiku DSS. Use to inspect or mutate DSS projects,
|
|
114
|
+
datasets, recipes, jobs, scenarios, folders, notebooks, SQL, variables,
|
|
115
|
+
code envs, and connections. Discover the full machine-readable surface with
|
|
116
|
+
dss commands run.
|
|
123
117
|
---
|
|
124
118
|
|
|
125
119
|
`;
|
|
@@ -227,30 +221,29 @@ export function findWorkspaceRoot(startDir) {
|
|
|
227
221
|
}
|
|
228
222
|
return startDir;
|
|
229
223
|
}
|
|
230
|
-
export function
|
|
224
|
+
export function planSkillInstalls(agents, opts) {
|
|
231
225
|
const home = homedir();
|
|
232
226
|
const results = [];
|
|
233
|
-
for (const { id, def, } of agents) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
writeFileSync(
|
|
253
|
-
results.push({ agent: id, path: filePath, });
|
|
227
|
+
for (const { id, def, via, } of agents) {
|
|
228
|
+
const dir = opts.global
|
|
229
|
+
? def.globalPath(home)
|
|
230
|
+
: def.projectPath
|
|
231
|
+
? join(opts.cwd, def.projectPath)
|
|
232
|
+
: undefined;
|
|
233
|
+
if (!dir)
|
|
234
|
+
continue;
|
|
235
|
+
results.push({ agent: id, path: join(dir, def.filename), via, });
|
|
236
|
+
}
|
|
237
|
+
return results;
|
|
238
|
+
}
|
|
239
|
+
export function installSkill(agents, opts) {
|
|
240
|
+
const results = planSkillInstalls(agents, opts);
|
|
241
|
+
for (const result of results) {
|
|
242
|
+
const def = AGENTS[result.agent];
|
|
243
|
+
if (!def)
|
|
244
|
+
continue;
|
|
245
|
+
mkdirSync(dirname(result.path), { recursive: true, });
|
|
246
|
+
writeFileSync(result.path, def.content(), "utf-8");
|
|
254
247
|
}
|
|
255
248
|
return results;
|
|
256
249
|
}
|