dataiku-sdk 3.3.0 → 3.5.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 +6 -4
- package/dist/build-metadata.json +1 -1
- package/dist/src/cli/command-syntax.json +14524 -0
- package/dist/src/cli/commands/analysis.js +6 -9
- package/dist/src/cli/commands/api-deployer.js +15 -33
- package/dist/src/cli/commands/api-service.js +17 -27
- package/dist/src/cli/commands/app.js +22 -39
- package/dist/src/cli/commands/bundle.js +15 -24
- package/dist/src/cli/commands/business-app.js +10 -17
- package/dist/src/cli/commands/code-env.js +23 -36
- package/dist/src/cli/commands/code.js +5 -5
- package/dist/src/cli/commands/connection.js +12 -22
- package/dist/src/cli/commands/continuous-activity.js +6 -9
- package/dist/src/cli/commands/dashboard.js +8 -13
- package/dist/src/cli/commands/data-collection.js +9 -16
- package/dist/src/cli/commands/data-quality.js +14 -26
- package/dist/src/cli/commands/dataset.js +28 -51
- package/dist/src/cli/commands/discussion.js +7 -10
- package/dist/src/cli/commands/doctor.js +3 -3
- package/dist/src/cli/commands/flow-zone.js +8 -17
- package/dist/src/cli/commands/folder.js +12 -20
- package/dist/src/cli/commands/future.js +7 -10
- package/dist/src/cli/commands/group.js +7 -11
- package/dist/src/cli/commands/insight.js +7 -11
- package/dist/src/cli/commands/job.js +17 -25
- package/dist/src/cli/commands/knowledge-bank.js +5 -6
- package/dist/src/cli/commands/llm.js +5 -8
- package/dist/src/cli/commands/macro.js +11 -18
- package/dist/src/cli/commands/meaning.js +7 -11
- package/dist/src/cli/commands/metrics.js +7 -10
- package/dist/src/cli/commands/ml-task.js +12 -20
- package/dist/src/cli/commands/model-evaluation-store.js +7 -11
- package/dist/src/cli/commands/notebook.js +15 -27
- package/dist/src/cli/commands/plugin.js +35 -68
- package/dist/src/cli/commands/project-deployer.js +10 -22
- package/dist/src/cli/commands/project-folder.js +10 -17
- package/dist/src/cli/commands/project-git.js +39 -71
- package/dist/src/cli/commands/project-library.js +15 -23
- package/dist/src/cli/commands/project.js +9 -26
- package/dist/src/cli/commands/recipe.d.ts +16 -0
- package/dist/src/cli/commands/recipe.js +83 -94
- package/dist/src/cli/commands/saved-model.js +23 -39
- package/dist/src/cli/commands/scenario.js +21 -35
- package/dist/src/cli/commands/sql.js +4 -4
- package/dist/src/cli/commands/statistics.js +11 -18
- package/dist/src/cli/commands/streaming-endpoint.js +7 -11
- package/dist/src/cli/commands/user.js +11 -22
- package/dist/src/cli/commands/variable.js +3 -4
- package/dist/src/cli/commands/webapp.js +10 -16
- package/dist/src/cli/commands/wiki.js +9 -13
- package/dist/src/cli/commands/workspace.js +8 -14
- package/dist/src/cli/contract.d.ts +5 -15
- package/dist/src/cli/contract.js +179 -461
- package/dist/src/cli/doctor.js +1 -0
- package/dist/src/cli/env.d.ts +2 -0
- package/dist/src/cli/env.js +15 -1
- package/dist/src/cli/helpers/app-permissions.js +2 -1
- package/dist/src/cli/helpers/flow-zone.js +2 -1
- package/dist/src/cli/helpers/recipe.js +2 -1
- package/dist/src/cli/output-schemas.d.ts +24 -0
- package/dist/src/cli/output-schemas.js +233 -0
- package/dist/src/cli/syntax.d.ts +83 -0
- package/dist/src/cli/syntax.js +217 -0
- package/dist/src/cli/types.d.ts +3 -0
- package/dist/src/cli/usage.d.ts +1 -1
- package/dist/src/cli/usage.js +4 -2
- package/dist/src/cli/version.js +2 -0
- package/dist/src/cli.js +37 -64
- package/dist/src/client.d.ts +10 -1
- package/dist/src/client.js +27 -11
- package/dist/src/errors.d.ts +12 -1
- package/dist/src/errors.js +34 -7
- package/dist/src/generated/action-output-schemas.json +1735 -0
- package/dist/src/index.d.ts +1 -3
- package/dist/src/index.js +2 -2
- package/dist/src/resources/api-services.js +2 -3
- package/dist/src/resources/applications.js +2 -4
- package/dist/src/resources/code-envs.js +2 -2
- package/dist/src/resources/data-quality.js +4 -3
- package/dist/src/resources/datasets.d.ts +13 -0
- package/dist/src/resources/datasets.js +42 -8
- package/dist/src/resources/flow-zones.d.ts +6 -2
- package/dist/src/resources/flow-zones.js +10 -5
- package/dist/src/resources/folders.js +4 -2
- package/dist/src/resources/futures.d.ts +2 -0
- package/dist/src/resources/futures.js +39 -27
- package/dist/src/resources/insights.js +3 -2
- package/dist/src/resources/jobs.js +41 -31
- package/dist/src/resources/macros.js +2 -4
- package/dist/src/resources/ml-tasks.js +28 -19
- package/dist/src/resources/notebooks.js +2 -3
- package/dist/src/resources/plugins.d.ts +0 -2
- package/dist/src/resources/plugins.js +0 -3
- package/dist/src/resources/project-git.d.ts +6 -12
- package/dist/src/resources/project-git.js +31 -58
- package/dist/src/resources/project-library.d.ts +0 -2
- package/dist/src/resources/project-library.js +2 -7
- package/dist/src/resources/projects.d.ts +4 -2
- package/dist/src/resources/projects.js +37 -36
- package/dist/src/resources/recipes.d.ts +28 -0
- package/dist/src/resources/recipes.js +116 -84
- package/dist/src/resources/sql.js +8 -3
- package/dist/src/resources/statistics.js +2 -1
- package/dist/src/resources/variables.js +2 -1
- package/dist/src/resources/webapps.js +2 -3
- package/dist/src/schemas.d.ts +1 -2
- package/dist/src/schemas.js +1 -1
- package/dist/src/skill.js +6 -7
- package/dist/src/utils/cleanup-ledger.js +9 -8
- package/dist/src/utils/git-reference.d.ts +12 -0
- package/dist/src/utils/git-reference.js +38 -0
- package/dist/src/utils/polling.d.ts +3 -0
- package/dist/src/utils/polling.js +3 -0
- package/dist/src/utils/project-archive.js +2 -2
- package/dist/src/utils/stable-hash.d.ts +3 -1
- package/dist/src/utils/stable-hash.js +2 -0
- package/package.json +8 -8
- package/plugin.json +1 -1
- package/skills/dataiku-dss/SKILL.md +3 -2
- package/skills/dataiku-dss/references/app-releases.md +2 -3
- package/skills/dataiku-dss/references/authentication.md +7 -7
- package/skills/dataiku-dss/references/coding.md +1 -1
- package/skills/dataiku-dss/references/mutations.md +1 -1
- package/skills/dataiku-dss/references/troubleshooting.md +2 -2
- package/dist/src/utils/pagination.d.ts +0 -8
- package/dist/src/utils/pagination.js +0 -23
package/dist/src/cli/contract.js
CHANGED
|
@@ -3,21 +3,27 @@ import * as path from "node:path";
|
|
|
3
3
|
import { validateCredentials, } from "../auth.js";
|
|
4
4
|
import { getCredentialsPath, saveCredentials, } from "../config.js";
|
|
5
5
|
import { DataikuError, } from "../errors.js";
|
|
6
|
+
import actionOutputSchemasMetadata from "../generated/action-output-schemas.json" with { type: "json"
|
|
7
|
+
};
|
|
6
8
|
import { APP_MANIFEST_CONCURRENCY_CONTROL, } from "../resources/applications.js";
|
|
7
|
-
import {
|
|
9
|
+
import { buildDatasetCreateBody, } from "../resources/datasets.js";
|
|
10
|
+
import { validatePluginDestinationPath, validatePluginPath, } from "../resources/plugins.js";
|
|
8
11
|
import { encodeLibraryPath, PROJECT_LIBRARY_CONCURRENCY_CONTROL, validateLibraryDestinationPath, validateLibraryName, validateLibraryPath, } from "../resources/project-library.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
12
|
+
import { buildRecipeCreateRequest, } from "../resources/recipes.js";
|
|
13
|
+
import { encodeGitReferencePath, validateGitReferencePath, } from "../utils/git-reference.js";
|
|
14
|
+
import { jobBuildTargetTypeFromFlags, json, jsonInput, num, parseBooleanOption, parseJsonObject, requiredJsonInput, rewritePairsFromFlags, schemaColumnsInput, sha256Hex, stableHash, stringField, textInput, } from "./coerce.js";
|
|
11
15
|
import { parseCodeRunIntegerFlag, resolveCodeInputWithSource, } from "./commands/code.js";
|
|
12
16
|
import { commands, } from "./commands/index.js";
|
|
13
17
|
import { projectLibraryPutPayload, } from "./commands/project-library.js";
|
|
18
|
+
import { recipeCreateOptionsFromFlags, } from "./commands/recipe.js";
|
|
14
19
|
import { resolveSqlQueryInvocation, } from "./commands/sql.js";
|
|
15
|
-
import {
|
|
16
|
-
import { BOOLEAN_FLAGS, executionMode, FLAG_ALIASES,
|
|
20
|
+
import { ambientProjectKey, } from "./env.js";
|
|
21
|
+
import { BOOLEAN_FLAGS, executionMode, FLAG_ALIASES, SHORT_FLAGS, } from "./flags.js";
|
|
17
22
|
import { flowZoneColor, flowZoneMoveItems, flowZoneName, } from "./helpers/flow-zone.js";
|
|
18
23
|
import { recipeBackupPath, recipeRunShouldWait, } from "./helpers/recipe.js";
|
|
19
24
|
import { encodedProjectEndpointForPlan, planResult, } from "./output.js";
|
|
20
25
|
import { resolveLoginCredentials, } from "./runtime.js";
|
|
26
|
+
import { commandSyntax, commandSyntaxTree, commandUsage, renderNodes, syntaxCommandWords, syntaxHasFlag, } from "./syntax.js";
|
|
21
27
|
import { inferRequiresProject, requireArgs, UsageError, } from "./usage.js";
|
|
22
28
|
import { AGENT_CONTRACT_SCHEMA_ID, AGENT_CONTRACT_VERSION, cliVersionResult, JSON_SCHEMA_DRAFT, } from "./version.js";
|
|
23
29
|
function codeEnvWait(flags) {
|
|
@@ -80,7 +86,6 @@ export const AUTH_ACTIONS = {
|
|
|
80
86
|
saveCredentials({ url, apiKey, projectKey, ...tlsSettings, });
|
|
81
87
|
return { saved: true, path: credentialsPath, };
|
|
82
88
|
},
|
|
83
|
-
usage: "dss auth login --url URL --api-key KEY [--project-key KEY] [--insecure] [--ca-cert PATH]",
|
|
84
89
|
description: "Validate and save DSS credentials from flags or environment variables.",
|
|
85
90
|
examples: [
|
|
86
91
|
"dss auth login --url https://dss.example.com --api-key YOUR_KEY",
|
|
@@ -237,7 +242,7 @@ const AUTHENTICATED_AGENT_FLAGS = [
|
|
|
237
242
|
"insecure",
|
|
238
243
|
"ca-cert",
|
|
239
244
|
];
|
|
240
|
-
export const COMMANDS_USAGE = "
|
|
245
|
+
export const COMMANDS_USAGE = commandUsage("commands", "run");
|
|
241
246
|
const COMMANDS_DESCRIPTION = "Print a compact resource/action summary by default; use --fields for scoped command metadata or --output PATH to export the full registry without sending it through stdout.";
|
|
242
247
|
const COMMANDS_EXAMPLES = [
|
|
243
248
|
"dss commands run",
|
|
@@ -247,28 +252,28 @@ const COMMANDS_EXAMPLES = [
|
|
|
247
252
|
"dss commands run --output commands.json",
|
|
248
253
|
];
|
|
249
254
|
export const AGENT_CONTRACT_COMMAND = "dss agent contract";
|
|
250
|
-
export const AGENT_CONTRACT_USAGE = "
|
|
255
|
+
export const AGENT_CONTRACT_USAGE = commandUsage("agent", "contract");
|
|
251
256
|
const AGENT_CONTRACT_DESCRIPTION = "Print the versioned JSON agent contract; scope bootstrap fields, use commands.actions to enumerate the surface, and read schemas only when needed.";
|
|
252
257
|
const AGENT_CONTRACT_EXAMPLES = [
|
|
253
258
|
"dss agent contract --fields protocol,agentContractVersion,cli,stdio,planning,compatibility",
|
|
254
259
|
"dss agent contract --fields commands.actions",
|
|
255
260
|
];
|
|
256
|
-
const VERSION_USAGE = "
|
|
261
|
+
const VERSION_USAGE = commandUsage("version", "run");
|
|
257
262
|
const VERSION_DESCRIPTION = "Print the CLI version, checkout/build revisions, load source, runtime, and stale-build status as JSON.";
|
|
258
263
|
const VERSION_EXAMPLES = ["dss version", "dss --version",];
|
|
259
|
-
const INSTALL_SKILL_USAGE = "
|
|
264
|
+
const INSTALL_SKILL_USAGE = commandUsage("install-skill", "run");
|
|
260
265
|
const INSTALL_SKILL_DESCRIPTION = "Report missing/stale/current skill status and atomically install changed dataiku-dss agent skills.";
|
|
261
266
|
const INSTALL_SKILL_EXAMPLES = [
|
|
262
267
|
"dss install-skill --list-agents",
|
|
263
268
|
"dss install-skill --agent omp --dry-run",
|
|
264
269
|
];
|
|
265
|
-
export const CLEANUP_USAGE = "
|
|
270
|
+
export const CLEANUP_USAGE = commandUsage("cleanup", "run");
|
|
266
271
|
const CLEANUP_DESCRIPTION = "Replay cleanup entries in reverse order; failures include structured code/category/exitCode/retryability summaries.";
|
|
267
272
|
const CLEANUP_EXAMPLES = [
|
|
268
273
|
"dss cleanup --file cleanup.jsonl",
|
|
269
274
|
"dss cleanup --file cleanup.jsonl --apply",
|
|
270
275
|
];
|
|
271
|
-
const FIXTURES_USAGE = "
|
|
276
|
+
const FIXTURES_USAGE = commandUsage("fixtures", "run");
|
|
272
277
|
const FIXTURES_DESCRIPTION = "Discover safe live-test fixtures for agent workflows.";
|
|
273
278
|
const FIXTURES_EXAMPLES = [
|
|
274
279
|
"dss fixtures",
|
|
@@ -433,212 +438,18 @@ function structuredExamples(examples, examplePayload) {
|
|
|
433
438
|
};
|
|
434
439
|
});
|
|
435
440
|
}
|
|
436
|
-
const PROJECT_LIBRARY_ITEM_OUTPUT_SCHEMA = {
|
|
437
|
-
type: "object",
|
|
438
|
-
additionalProperties: false,
|
|
439
|
-
required: ["name",],
|
|
440
|
-
properties: {
|
|
441
|
-
name: { type: "string", },
|
|
442
|
-
path: { type: "string", },
|
|
443
|
-
size: { type: "integer", minimum: 0, },
|
|
444
|
-
mimeType: { type: "string", },
|
|
445
|
-
hasData: { type: "boolean", },
|
|
446
|
-
lastModified: { type: "number", },
|
|
447
|
-
children: { type: "array", items: { type: "object", additionalProperties: true, }, },
|
|
448
|
-
},
|
|
449
|
-
};
|
|
450
|
-
const NOTEBOOK_SAVE_OUTPUT_SCHEMA = {
|
|
451
|
-
type: "object",
|
|
452
|
-
additionalProperties: false,
|
|
453
|
-
required: ["saved", "resource", "created", "hash",],
|
|
454
|
-
properties: {
|
|
455
|
-
saved: { type: "string", },
|
|
456
|
-
resource: { enum: ["jupyter-notebook", "sql-notebook",], },
|
|
457
|
-
created: { type: "boolean", },
|
|
458
|
-
hash: { type: "string", pattern: "^[a-f0-9]{64}$", },
|
|
459
|
-
},
|
|
460
|
-
};
|
|
461
441
|
/**
|
|
462
|
-
*
|
|
463
|
-
*
|
|
442
|
+
* Discovery output schemas: the generated declarative metadata committed at
|
|
443
|
+
* `src/generated/action-output-schemas.json`. Plain data only, so discovery
|
|
444
|
+
* (`dss commands run`, `dss agent contract`) never loads the TypeBox graph.
|
|
445
|
+
* The content matches `typeBoxCommandOutputSchemas()` exactly; parity and
|
|
446
|
+
* freshness are enforced by tests/cli/discovery-output-schemas.test.ts and
|
|
447
|
+
* `bun run check`.
|
|
464
448
|
*/
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
required: ["saved", "requested", "resource", "created", "hash",],
|
|
468
|
-
properties: {
|
|
469
|
-
...NOTEBOOK_SAVE_OUTPUT_SCHEMA["properties"],
|
|
470
|
-
requested: { type: "string", },
|
|
471
|
-
},
|
|
472
|
-
};
|
|
473
|
-
const COMMAND_OUTPUT_SCHEMAS = {
|
|
474
|
-
"code-env.list": CodeEnvSummaryArraySchema,
|
|
475
|
-
"code-env.get": CodeEnvDetailsSchema,
|
|
476
|
-
"code-env.list-logs": CodeEnvLogSummaryArraySchema,
|
|
477
|
-
"code-env.get-log": {
|
|
478
|
-
oneOf: [
|
|
479
|
-
{
|
|
480
|
-
type: "object",
|
|
481
|
-
required: ["log", "bytes", "truncated", "tailed", "envLang", "envName", "logName",],
|
|
482
|
-
properties: {
|
|
483
|
-
log: { type: "string", },
|
|
484
|
-
bytes: { type: "integer", minimum: 0, },
|
|
485
|
-
truncated: { type: "boolean", },
|
|
486
|
-
tailed: { type: "boolean", },
|
|
487
|
-
envLang: { enum: ["PYTHON", "R",], },
|
|
488
|
-
envName: { type: "string", },
|
|
489
|
-
logName: { type: "string", },
|
|
490
|
-
},
|
|
491
|
-
},
|
|
492
|
-
{
|
|
493
|
-
type: "object",
|
|
494
|
-
required: ["path", "bytes", "truncated", "tailed", "envLang", "envName", "logName",],
|
|
495
|
-
properties: {
|
|
496
|
-
path: { type: "string", },
|
|
497
|
-
bytes: { type: "integer", minimum: 0, },
|
|
498
|
-
truncated: { type: "boolean", },
|
|
499
|
-
tailed: { type: "boolean", },
|
|
500
|
-
envLang: { enum: ["PYTHON", "R",], },
|
|
501
|
-
envName: { type: "string", },
|
|
502
|
-
logName: { type: "string", },
|
|
503
|
-
},
|
|
504
|
-
},
|
|
505
|
-
],
|
|
506
|
-
},
|
|
507
|
-
"code-env.version": CodeEnvVersionForProjectSchema,
|
|
508
|
-
"code-env.usages": CodeEnvUsageArraySchema,
|
|
509
|
-
"code.run": {
|
|
510
|
-
type: "object",
|
|
511
|
-
additionalProperties: false,
|
|
512
|
-
required: [
|
|
513
|
-
"outcome",
|
|
514
|
-
"success",
|
|
515
|
-
"runId",
|
|
516
|
-
"elapsedMs",
|
|
517
|
-
"pollCount",
|
|
518
|
-
"output",
|
|
519
|
-
"logTruncated",
|
|
520
|
-
"maxLogBytes",
|
|
521
|
-
"cleanup",
|
|
522
|
-
],
|
|
523
|
-
properties: {
|
|
524
|
-
outcome: { type: "string", },
|
|
525
|
-
success: { type: "boolean", },
|
|
526
|
-
runId: { type: "string", },
|
|
527
|
-
elapsedMs: { type: "number", minimum: 0, },
|
|
528
|
-
pollCount: { type: "integer", minimum: 0, },
|
|
529
|
-
output: { type: "string", },
|
|
530
|
-
log: { type: "string", },
|
|
531
|
-
logTruncated: { type: "boolean", },
|
|
532
|
-
maxLogBytes: { type: "integer", minimum: 0, },
|
|
533
|
-
timedOut: { const: true, },
|
|
534
|
-
timeoutMs: { type: "integer", minimum: 0, },
|
|
535
|
-
cleanup: {
|
|
536
|
-
type: "object",
|
|
537
|
-
additionalProperties: false,
|
|
538
|
-
required: ["status",],
|
|
539
|
-
properties: {
|
|
540
|
-
status: { enum: ["deleted", "kept", "failed",], },
|
|
541
|
-
error: { type: "string", },
|
|
542
|
-
},
|
|
543
|
-
},
|
|
544
|
-
},
|
|
545
|
-
},
|
|
546
|
-
"notebook.list-jupyter": JupyterNotebookSummaryArraySchema,
|
|
547
|
-
"notebook.get-jupyter": JupyterNotebookContentSchema,
|
|
548
|
-
"notebook.sessions-jupyter": NotebookSessionArraySchema,
|
|
549
|
-
"notebook.list-sql": SqlNotebookSummaryArraySchema,
|
|
550
|
-
"notebook.get-sql": SqlNotebookContentSchema,
|
|
551
|
-
"notebook.history-sql": SqlNotebookHistorySchema,
|
|
552
|
-
"notebook.save-jupyter": NOTEBOOK_SAVE_OUTPUT_SCHEMA,
|
|
553
|
-
"notebook.save-sql": NOTEBOOK_SAVE_SQL_OUTPUT_SCHEMA,
|
|
554
|
-
"project-library.list": { type: "array", items: PROJECT_LIBRARY_ITEM_OUTPUT_SCHEMA, },
|
|
555
|
-
"project-library.get-bytes": {
|
|
556
|
-
type: "object",
|
|
557
|
-
additionalProperties: false,
|
|
558
|
-
required: ["path", "bytes", "sha256",],
|
|
559
|
-
properties: {
|
|
560
|
-
path: { type: "string", },
|
|
561
|
-
bytes: { type: "integer", minimum: 0, },
|
|
562
|
-
sha256: { type: "string", pattern: "^[a-f0-9]{64}$", },
|
|
563
|
-
},
|
|
564
|
-
},
|
|
565
|
-
"project-library.put": {
|
|
566
|
-
type: "object",
|
|
567
|
-
additionalProperties: false,
|
|
568
|
-
required: ["updated", "bytes", "sha256",],
|
|
569
|
-
properties: {
|
|
570
|
-
updated: { type: "string", },
|
|
571
|
-
bytes: { type: "integer", minimum: 0, },
|
|
572
|
-
sha256: { type: "string", pattern: "^[a-f0-9]{64}$", },
|
|
573
|
-
beforeSha256: { type: "string", pattern: "^[a-f0-9]{64}$", },
|
|
574
|
-
},
|
|
575
|
-
},
|
|
576
|
-
"project-library.diff": {
|
|
577
|
-
type: "object",
|
|
578
|
-
additionalProperties: false,
|
|
579
|
-
required: [
|
|
580
|
-
"path",
|
|
581
|
-
"unchanged",
|
|
582
|
-
"added",
|
|
583
|
-
"removed",
|
|
584
|
-
"diff",
|
|
585
|
-
"diffTruncated",
|
|
586
|
-
"localSha256",
|
|
587
|
-
"localBytes",
|
|
588
|
-
"maxLines",
|
|
589
|
-
],
|
|
590
|
-
properties: {
|
|
591
|
-
path: { type: "string", },
|
|
592
|
-
unchanged: { type: "boolean", },
|
|
593
|
-
added: { type: "integer", minimum: 0, },
|
|
594
|
-
removed: { type: "integer", minimum: 0, },
|
|
595
|
-
diff: { type: "string", },
|
|
596
|
-
diffTruncated: { type: "boolean", },
|
|
597
|
-
binary: { type: "boolean", },
|
|
598
|
-
remoteAbsent: { type: "boolean", },
|
|
599
|
-
remoteSha256: { type: "string", pattern: "^[a-f0-9]{64}$", },
|
|
600
|
-
remoteBytes: { type: "integer", minimum: 0, },
|
|
601
|
-
localSha256: { type: "string", pattern: "^[a-f0-9]{64}$", },
|
|
602
|
-
localBytes: { type: "integer", minimum: 0, },
|
|
603
|
-
maxLines: { type: "integer", minimum: 0, },
|
|
604
|
-
},
|
|
605
|
-
},
|
|
606
|
-
"project.list": ProjectSummaryArraySchema,
|
|
607
|
-
"project.get": ProjectDetailsSchema,
|
|
608
|
-
"project.metadata": ProjectMetadataSchema,
|
|
609
|
-
"dataset.list": DatasetSummaryArraySchema,
|
|
610
|
-
"dataset.get": DatasetDetailsSchema,
|
|
611
|
-
"dataset.schema": DatasetSchemaSchema,
|
|
612
|
-
"recipe.list": RecipeSummaryArraySchema,
|
|
613
|
-
"job.list": JobSummaryArraySchema,
|
|
614
|
-
"job.wait": JobWaitResultSchema,
|
|
615
|
-
"job.monitor": JobWaitResultSchema,
|
|
616
|
-
"scenario.list": ScenarioSummaryArraySchema,
|
|
617
|
-
"scenario.get": ScenarioDetailsSchema,
|
|
618
|
-
"scenario.status": ScenarioStatusSchema,
|
|
619
|
-
"flow-zone.list": FlowZoneArraySchema,
|
|
620
|
-
"flow-zone.get": FlowZoneSchema,
|
|
621
|
-
"sql.query": {
|
|
622
|
-
anyOf: [
|
|
623
|
-
SqlQueryResponseSchema,
|
|
624
|
-
{
|
|
625
|
-
type: "object",
|
|
626
|
-
required: ["queryId", "rowCount", "preview",],
|
|
627
|
-
additionalProperties: true,
|
|
628
|
-
properties: {
|
|
629
|
-
queryId: { type: "string", },
|
|
630
|
-
rowCount: { type: "number", },
|
|
631
|
-
preview: { type: "array", items: true, },
|
|
632
|
-
truncated: { type: "boolean", },
|
|
633
|
-
outputPath: { type: "string", },
|
|
634
|
-
written: { type: "string", },
|
|
635
|
-
},
|
|
636
|
-
},
|
|
637
|
-
],
|
|
638
|
-
},
|
|
639
|
-
};
|
|
449
|
+
const actionOutputSchemas = actionOutputSchemasMetadata
|
|
450
|
+
.schemas;
|
|
640
451
|
function outputJsonSchema(resource, action, shape) {
|
|
641
|
-
const precise =
|
|
452
|
+
const precise = actionOutputSchemas[registryKey(resource, action)];
|
|
642
453
|
if (precise)
|
|
643
454
|
return precise;
|
|
644
455
|
if (shape === "array")
|
|
@@ -693,10 +504,9 @@ function shortFlagPattern(flags) {
|
|
|
693
504
|
* use an actionless prefix, while real command paths that spell `run` in their
|
|
694
505
|
* usage (e.g. `dss commands run`) keep the action token.
|
|
695
506
|
*/
|
|
696
|
-
function argvPrefix(resource, action
|
|
697
|
-
const
|
|
698
|
-
|
|
699
|
-
return head[0] === resource && head[1] === action ? [resource, action,] : [resource,];
|
|
507
|
+
function argvPrefix(resource, action) {
|
|
508
|
+
const words = syntaxCommandWords(commandSyntaxTree(resource, action) ?? []);
|
|
509
|
+
return words[0] === resource && words[1] === action ? [resource, action,] : [resource,];
|
|
700
510
|
}
|
|
701
511
|
/**
|
|
702
512
|
* Describe one invocation as a canonical argv token array. Agents emit the
|
|
@@ -713,7 +523,7 @@ function argvPrefix(resource, action, usage) {
|
|
|
713
523
|
* negative-number and `--` separator rules.
|
|
714
524
|
*/
|
|
715
525
|
function argvJsonSchema(resource, action, flags, usage, requiredFlags, requiredOneOf) {
|
|
716
|
-
const prefix = argvPrefix(resource, action
|
|
526
|
+
const prefix = argvPrefix(resource, action);
|
|
717
527
|
const aliases = {};
|
|
718
528
|
for (const flag of flags) {
|
|
719
529
|
aliases[flag.name] = flag.aliases ?? [];
|
|
@@ -721,7 +531,8 @@ function argvJsonSchema(resource, action, flags, usage, requiredFlags, requiredO
|
|
|
721
531
|
const booleanNames = flags.filter((flag) => flag.kind === "boolean")
|
|
722
532
|
.flatMap((flag) => [flag.name, ...(flag.aliases ?? []),]);
|
|
723
533
|
const valueFlags = flags.filter((flag) => flag.kind === "value");
|
|
724
|
-
const requiredPositionals =
|
|
534
|
+
const requiredPositionals = commandSyntax(resource, action).positionalArguments
|
|
535
|
+
.filter((positional) => positional.required).map((positional) => positional.name);
|
|
725
536
|
const itemSchemas = [
|
|
726
537
|
{ not: { pattern: "^-", }, },
|
|
727
538
|
{ const: "-", },
|
|
@@ -852,45 +663,6 @@ const EXPLICIT_REGISTRY_OVERRIDES = {
|
|
|
852
663
|
examplePayload: { article: { name: "Updated article", }, },
|
|
853
664
|
},
|
|
854
665
|
};
|
|
855
|
-
function extractUsageFlags(usage) {
|
|
856
|
-
const flags = [];
|
|
857
|
-
for (const match of usage.matchAll(/--([a-z0-9-]+)/g)) {
|
|
858
|
-
flags.push(FLAG_ALIASES[match[1]] ?? match[1]);
|
|
859
|
-
}
|
|
860
|
-
return uniqueStrings(flags).filter((flag) => KNOWN_LONG_FLAGS.has(flag));
|
|
861
|
-
}
|
|
862
|
-
function extractPositionalArguments(usage) {
|
|
863
|
-
const positionals = [];
|
|
864
|
-
const add = (name, required) => {
|
|
865
|
-
const existing = positionals.find((positional) => positional.name === name);
|
|
866
|
-
if (existing)
|
|
867
|
-
existing.required ||= required;
|
|
868
|
-
else
|
|
869
|
-
positionals.push({ name, required, });
|
|
870
|
-
};
|
|
871
|
-
for (const match of usage.matchAll(/<([^>]+)>/g)) {
|
|
872
|
-
const before = usage.slice(0, match.index);
|
|
873
|
-
const openParen = before.lastIndexOf("(");
|
|
874
|
-
const insideParen = openParen > before.lastIndexOf(")");
|
|
875
|
-
const closeParen = insideParen ? usage.indexOf(")", match.index) : -1;
|
|
876
|
-
const group = closeParen >= 0 ? usage.slice(openParen + 1, closeParen) : "";
|
|
877
|
-
const hasFlagAlternative = group.split("|").some((alternative) => alternative.includes("--"));
|
|
878
|
-
const required = before.lastIndexOf("[") <= before.lastIndexOf("]")
|
|
879
|
-
&& !hasFlagAlternative;
|
|
880
|
-
add(match[1], required);
|
|
881
|
-
}
|
|
882
|
-
for (const suffix of usage.split("[").slice(1)) {
|
|
883
|
-
const candidate = suffix.split("]", 1)[0];
|
|
884
|
-
if (candidate && /^[A-Za-z][A-Za-z0-9_-]*$/.test(candidate))
|
|
885
|
-
add(candidate, false);
|
|
886
|
-
}
|
|
887
|
-
for (const group of topLevelParenGroups(usage)) {
|
|
888
|
-
const candidate = group.split("|", 1)[0]?.trim();
|
|
889
|
-
if (candidate && /^[A-Z][A-Z0-9_-]*$/.test(candidate))
|
|
890
|
-
add(candidate, false);
|
|
891
|
-
}
|
|
892
|
-
return positionals;
|
|
893
|
-
}
|
|
894
666
|
const COMMAND_REQUIRED_INPUT_GROUPS = {
|
|
895
667
|
"notebook.unload-jupyter": [
|
|
896
668
|
{
|
|
@@ -1049,102 +821,6 @@ function inferOutputShape(resource, action) {
|
|
|
1049
821
|
return "string";
|
|
1050
822
|
return "object";
|
|
1051
823
|
}
|
|
1052
|
-
export function inferInputContract(usage) {
|
|
1053
|
-
return {
|
|
1054
|
-
...(usage.includes("--stdin") ? { stdin: true, } : {}),
|
|
1055
|
-
...(usage.includes("--data ") || usage.includes("--data JSON") ? { dataFlag: true, } : {}),
|
|
1056
|
-
...(usage.includes("--data-file") ? { dataFileFlag: true, } : {}),
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
|
-
function stripOptionalUsageGroups(usage) {
|
|
1060
|
-
return usage.replace(/\[[^\]]*\]/g, " ");
|
|
1061
|
-
}
|
|
1062
|
-
function stripAllUsageGroups(usage) {
|
|
1063
|
-
return usage.replace(/\[[^\]]*\]/g, " ").replace(/\([^)]*\)/g, " ");
|
|
1064
|
-
}
|
|
1065
|
-
function topLevelParenGroups(usage) {
|
|
1066
|
-
const groups = [];
|
|
1067
|
-
let depth = 0;
|
|
1068
|
-
let current = "";
|
|
1069
|
-
for (const char of usage) {
|
|
1070
|
-
if (char === "(") {
|
|
1071
|
-
if (depth > 0)
|
|
1072
|
-
current += char;
|
|
1073
|
-
else
|
|
1074
|
-
current = "";
|
|
1075
|
-
depth++;
|
|
1076
|
-
}
|
|
1077
|
-
else if (char === ")") {
|
|
1078
|
-
depth--;
|
|
1079
|
-
if (depth === 0)
|
|
1080
|
-
groups.push(current);
|
|
1081
|
-
else
|
|
1082
|
-
current += char;
|
|
1083
|
-
}
|
|
1084
|
-
else if (depth > 0) {
|
|
1085
|
-
current += char;
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
return groups;
|
|
1089
|
-
}
|
|
1090
|
-
function splitTopLevelChoices(group) {
|
|
1091
|
-
const parts = [];
|
|
1092
|
-
let depth = 0;
|
|
1093
|
-
let current = "";
|
|
1094
|
-
for (let index = 0; index < group.length; index++) {
|
|
1095
|
-
const char = group[index];
|
|
1096
|
-
if (char === "[" || char === "(")
|
|
1097
|
-
depth++;
|
|
1098
|
-
else if (char === "]" || char === ")")
|
|
1099
|
-
depth--;
|
|
1100
|
-
const nextAlternative = group.slice(index + 1).trimStart();
|
|
1101
|
-
if (char === "|" && depth === 0 && nextAlternative.startsWith("--")) {
|
|
1102
|
-
parts.push(current);
|
|
1103
|
-
current = "";
|
|
1104
|
-
}
|
|
1105
|
-
else {
|
|
1106
|
-
current += char;
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
parts.push(current);
|
|
1110
|
-
return parts;
|
|
1111
|
-
}
|
|
1112
|
-
function flagsInUsageFragment(fragment) {
|
|
1113
|
-
return extractUsageFlags(fragment.replace(/\[[^\]]*\]/g, " "));
|
|
1114
|
-
}
|
|
1115
|
-
/**
|
|
1116
|
-
* Split required usage flags into unconditional flags and required choice
|
|
1117
|
-
* groups. A required `(--a X | --b Y)` group becomes a requiredOneOf entry
|
|
1118
|
-
* (at least one alternative; an alternative listing several flags must be
|
|
1119
|
-
* supplied together) instead of marking every flag as unconditionally required.
|
|
1120
|
-
*/
|
|
1121
|
-
function deriveRequiredUsage(usage) {
|
|
1122
|
-
const requiredFlags = extractUsageFlags(stripAllUsageGroups(usage));
|
|
1123
|
-
const requiredOneOf = [];
|
|
1124
|
-
for (const group of topLevelParenGroups(usage)) {
|
|
1125
|
-
const alternatives = splitTopLevelChoices(group);
|
|
1126
|
-
if (alternatives.length <= 1) {
|
|
1127
|
-
requiredFlags.push(...flagsInUsageFragment(group));
|
|
1128
|
-
continue;
|
|
1129
|
-
}
|
|
1130
|
-
const oneOf = alternatives
|
|
1131
|
-
.map((alternative) => flagsInUsageFragment(alternative))
|
|
1132
|
-
.filter((alternativeFlags) => alternativeFlags.length > 0);
|
|
1133
|
-
// A group mixing a positional alternative with flags (e.g. sql query's
|
|
1134
|
-
// `(SQL | --sql QUERY | --sql-file PATH | --sql - | --stdin)`) cannot be
|
|
1135
|
-
// expressed as a flag-only choice: filtering out the flagless alternative
|
|
1136
|
-
// would falsely require one of the flags. Omit the group from the flag
|
|
1137
|
-
// contract entirely; the handler stays the runtime authority.
|
|
1138
|
-
if (alternatives.some((alternative) => flagsInUsageFragment(alternative).length === 0)) {
|
|
1139
|
-
continue;
|
|
1140
|
-
}
|
|
1141
|
-
if (oneOf.length > 1)
|
|
1142
|
-
requiredOneOf.push({ oneOf, });
|
|
1143
|
-
else if (oneOf.length === 1)
|
|
1144
|
-
requiredFlags.push(...oneOf[0]);
|
|
1145
|
-
}
|
|
1146
|
-
return { requiredFlags: uniqueStrings(requiredFlags), requiredOneOf, };
|
|
1147
|
-
}
|
|
1148
824
|
const GLOBAL_FLAG_VALUE_HINTS = {
|
|
1149
825
|
url: { valueType: "URL", },
|
|
1150
826
|
fields: { valueType: "CSV", },
|
|
@@ -1160,22 +836,6 @@ const GLOBAL_FLAG_VALUE_HINTS = {
|
|
|
1160
836
|
standard: { valueType: "JSON", },
|
|
1161
837
|
until: { valueType: "STATE", },
|
|
1162
838
|
};
|
|
1163
|
-
/** Derive a value placeholder (and enum members) for each value flag from its usage token. */
|
|
1164
|
-
function extractFlagValueHints(usage) {
|
|
1165
|
-
const hints = new Map();
|
|
1166
|
-
for (const match of usage.matchAll(/--([a-z0-9-]+)\s+([A-Za-z][A-Za-z0-9_-]*(?:\|[A-Za-z][A-Za-z0-9_-]*)+)(?![A-Za-z0-9_=-])/g)) {
|
|
1167
|
-
const flag = FLAG_ALIASES[match[1]] ?? match[1];
|
|
1168
|
-
if (!hints.has(flag)) {
|
|
1169
|
-
hints.set(flag, { valueType: "enum", enumValues: match[2].split("|"), });
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
for (const match of usage.matchAll(/--([a-z0-9-]+)\s+(<[^>]+>|[A-Z][A-Za-z0-9_]*)/g)) {
|
|
1173
|
-
const flag = FLAG_ALIASES[match[1]] ?? match[1];
|
|
1174
|
-
if (!hints.has(flag))
|
|
1175
|
-
hints.set(flag, { valueType: match[2], });
|
|
1176
|
-
}
|
|
1177
|
-
return hints;
|
|
1178
|
-
}
|
|
1179
839
|
function inferPayloadSchema(inputContract) {
|
|
1180
840
|
if (!inputContract.stdin && !inputContract.dataFlag && !inputContract.dataFileFlag) {
|
|
1181
841
|
return undefined;
|
|
@@ -1229,11 +889,11 @@ function cleanupCommandFromDeleteUsage(resource, action) {
|
|
|
1229
889
|
: action === "create-instance" || action === "create-successor-instance"
|
|
1230
890
|
? "delete-instance"
|
|
1231
891
|
: "delete";
|
|
1232
|
-
const
|
|
1233
|
-
if (!
|
|
892
|
+
const deleteSyntax = commandSyntaxTree(resource, deleteAction);
|
|
893
|
+
if (!deleteSyntax)
|
|
1234
894
|
return undefined;
|
|
1235
|
-
const base =
|
|
1236
|
-
if (
|
|
895
|
+
const base = renderNodes(deleteSyntax, true);
|
|
896
|
+
if (syntaxHasFlag(deleteSyntax, "if-exists"))
|
|
1237
897
|
return `${base} --if-exists`;
|
|
1238
898
|
return base;
|
|
1239
899
|
}
|
|
@@ -1316,14 +976,15 @@ function inferAsyncKind(resource, action) {
|
|
|
1316
976
|
}
|
|
1317
977
|
return "none";
|
|
1318
978
|
}
|
|
1319
|
-
function inferIdempotency(resource, sideEffect, action,
|
|
979
|
+
function inferIdempotency(resource, sideEffect, action, syntax) {
|
|
1320
980
|
if (sideEffect === "read")
|
|
1321
981
|
return "safe";
|
|
1322
982
|
if (`${resource}.${action}` === "install-skill.run")
|
|
1323
983
|
return "convergent";
|
|
1324
|
-
if (action.startsWith("create") &&
|
|
984
|
+
if (action.startsWith("create") && syntaxHasFlag(syntax, "if-not-exists")) {
|
|
1325
985
|
return "if-not-exists";
|
|
1326
|
-
|
|
986
|
+
}
|
|
987
|
+
if (action.startsWith("delete") && syntaxHasFlag(syntax, "if-exists"))
|
|
1327
988
|
return "if-exists";
|
|
1328
989
|
if (`${resource}.${action}` === "app.set-manifest-version")
|
|
1329
990
|
return "none";
|
|
@@ -1375,10 +1036,10 @@ export function inferCleanupHint(resource, action) {
|
|
|
1375
1036
|
: action === "create-instance" || action === "create-successor-instance"
|
|
1376
1037
|
? "delete-instance"
|
|
1377
1038
|
: "delete";
|
|
1378
|
-
const
|
|
1379
|
-
if (!
|
|
1039
|
+
const deleteSyntax = commandSyntaxTree(resource, deleteAction);
|
|
1040
|
+
if (!deleteSyntax)
|
|
1380
1041
|
return undefined;
|
|
1381
|
-
const ifExists =
|
|
1042
|
+
const ifExists = syntaxHasFlag(deleteSyntax, "if-exists") ? " --if-exists" : "";
|
|
1382
1043
|
if (resource === "code-env") {
|
|
1383
1044
|
return `Delete with \`dss code-env delete <lang> <name>${ifExists}\`.`;
|
|
1384
1045
|
}
|
|
@@ -1389,14 +1050,16 @@ export function inferCleanupHint(resource, action) {
|
|
|
1389
1050
|
}
|
|
1390
1051
|
function buildRegistryEntry(resource, action, meta) {
|
|
1391
1052
|
const requiresAuth = meta.localHandler === undefined && inferRequiresAuth(resource);
|
|
1392
|
-
const requiresProject = inferRequiresProject(resource, action
|
|
1053
|
+
const requiresProject = inferRequiresProject(resource, action);
|
|
1393
1054
|
const sideEffect = inferSideEffect(resource, action);
|
|
1394
1055
|
const destructive = inferDestructiveLevel(resource, sideEffect, action);
|
|
1395
1056
|
const asyncKind = inferAsyncKind(resource, action);
|
|
1396
1057
|
const mutatesDss = sideEffect === "write" && resource !== "auth" && resource !== "install-skill";
|
|
1397
|
-
|
|
1058
|
+
// auth login writes local credentials only; its --plan previews that write.
|
|
1059
|
+
const supportsPlan = sideEffect === "write" || resource === "auth";
|
|
1398
1060
|
const supportsCleanup = supportsCleanupLedger(resource, action);
|
|
1399
|
-
const
|
|
1061
|
+
const syntax = commandSyntax(resource, action);
|
|
1062
|
+
const usageFlags = syntax.flags;
|
|
1400
1063
|
const flags = uniqueStrings([
|
|
1401
1064
|
...usageFlags,
|
|
1402
1065
|
...(supportsPlan ? ["plan",] : []),
|
|
@@ -1405,7 +1068,7 @@ function buildRegistryEntry(resource, action, meta) {
|
|
|
1405
1068
|
...(requiresAuth ? AUTHENTICATED_AGENT_FLAGS : []),
|
|
1406
1069
|
...(requiresProject ? ["project-key",] : []),
|
|
1407
1070
|
]);
|
|
1408
|
-
const derivedRequired =
|
|
1071
|
+
const derivedRequired = syntax;
|
|
1409
1072
|
const requiredFlags = meta.requiredFlags
|
|
1410
1073
|
?? EXPLICIT_REGISTRY_OVERRIDES[registryKey(resource, action)]?.requiredFlags
|
|
1411
1074
|
?? derivedRequired.requiredFlags;
|
|
@@ -1416,8 +1079,8 @@ function buildRegistryEntry(resource, action, meta) {
|
|
|
1416
1079
|
const optionalFlags = meta.optionalFlags
|
|
1417
1080
|
?? EXPLICIT_REGISTRY_OVERRIDES[registryKey(resource, action)]?.optionalFlags
|
|
1418
1081
|
?? flags.filter((flag) => !requiredFlags.includes(flag) && !oneOfFlags.has(flag));
|
|
1419
|
-
const valueHints =
|
|
1420
|
-
const inputContract =
|
|
1082
|
+
const valueHints = syntax.valueHints;
|
|
1083
|
+
const inputContract = syntax.inputContract;
|
|
1421
1084
|
const cleanupHint = inferCleanupHint(resource, action);
|
|
1422
1085
|
const payloadSchema = meta.payloadSchema
|
|
1423
1086
|
?? EXPLICIT_REGISTRY_OVERRIDES[registryKey(resource, action)]?.payloadSchema
|
|
@@ -1431,15 +1094,13 @@ function buildRegistryEntry(resource, action, meta) {
|
|
|
1431
1094
|
? undefined
|
|
1432
1095
|
: inferredCleanupCommand;
|
|
1433
1096
|
const flagMetadata = flags.map((name) => {
|
|
1434
|
-
const aliases =
|
|
1435
|
-
.filter(([raw, canonical,]) => canonical === name && new RegExp(`--${raw}(?![a-z0-9-])`).test(meta.usage))
|
|
1436
|
-
.map(([raw,]) => raw);
|
|
1097
|
+
const aliases = syntax.aliases[name] ?? [];
|
|
1437
1098
|
const aliasPart = aliases.length > 0 ? { aliases, } : {};
|
|
1438
1099
|
const kind = flagKind(name);
|
|
1439
1100
|
if (kind === "boolean")
|
|
1440
1101
|
return { name, kind, ...aliasPart, };
|
|
1441
1102
|
const allowEmptyPart = ALLOW_EMPTY_VALUE_FLAGS[name] === true ? { allowEmptyValue: true, } : {};
|
|
1442
|
-
const hint = valueHints
|
|
1103
|
+
const hint = valueHints[name] ?? GLOBAL_FLAG_VALUE_HINTS[name];
|
|
1443
1104
|
if (!hint)
|
|
1444
1105
|
return { name, kind, ...aliasPart, ...allowEmptyPart, };
|
|
1445
1106
|
return {
|
|
@@ -1451,15 +1112,15 @@ function buildRegistryEntry(resource, action, meta) {
|
|
|
1451
1112
|
...allowEmptyPart,
|
|
1452
1113
|
};
|
|
1453
1114
|
});
|
|
1454
|
-
const positionalArguments =
|
|
1115
|
+
const positionalArguments = syntax.positionalArguments;
|
|
1455
1116
|
const positionals = positionalArguments.map((positional) => positional.name);
|
|
1456
1117
|
const inputGroups = requiredInputGroups(resource, action);
|
|
1457
1118
|
const outputShape = inferOutputShape(resource, action);
|
|
1458
|
-
const producesLocalFile =
|
|
1459
|
-
|| meta.usage.includes("--output-file PATH");
|
|
1119
|
+
const producesLocalFile = syntax.producesLocalFile;
|
|
1460
1120
|
const uniqueRequiredFlags = uniqueStrings(requiredFlags);
|
|
1461
1121
|
const uniqueOptionalFlags = uniqueStrings(optionalFlags);
|
|
1462
1122
|
const unsafe = unsafeOutputs(resource, action, producesLocalFile);
|
|
1123
|
+
let schemas;
|
|
1463
1124
|
return {
|
|
1464
1125
|
resource,
|
|
1465
1126
|
action,
|
|
@@ -1479,14 +1140,16 @@ function buildRegistryEntry(resource, action, meta) {
|
|
|
1479
1140
|
producesLocalFile,
|
|
1480
1141
|
mutatesDss,
|
|
1481
1142
|
async: asyncKind,
|
|
1482
|
-
idempotency: inferIdempotency(resource, sideEffect, action,
|
|
1483
|
-
dryRun:
|
|
1143
|
+
idempotency: inferIdempotency(resource, sideEffect, action, commandSyntaxTree(resource, action) ?? []),
|
|
1144
|
+
dryRun: syntax.dryRun,
|
|
1484
1145
|
requiredFlags: uniqueRequiredFlags,
|
|
1485
1146
|
optionalFlags: uniqueOptionalFlags,
|
|
1486
1147
|
...(requiredOneOf.length > 0 ? { requiredOneOf, } : {}),
|
|
1487
1148
|
...(inputGroups.length > 0 ? { requiredInputGroups: inputGroups, } : {}),
|
|
1488
1149
|
...(payloadSchema ? { payloadSchema, } : {}),
|
|
1489
|
-
schemas
|
|
1150
|
+
get schemas() {
|
|
1151
|
+
return schemas ??= buildCommandSchemas(resource, action, flagMetadata, uniqueRequiredFlags, requiredOneOf, payloadSchema, outputShape, meta.usage);
|
|
1152
|
+
},
|
|
1490
1153
|
...(unsafe ? { unsafeOutputs: unsafe, } : {}),
|
|
1491
1154
|
...(examplePayload !== undefined ? { examplePayload, } : {}),
|
|
1492
1155
|
...(cleanupCommand ? { cleanupCommand, } : {}),
|
|
@@ -1579,7 +1242,7 @@ function commandDefinitions(resourceFilter) {
|
|
|
1579
1242
|
for (const [action, meta,] of Object.entries(AUTH_ACTIONS)) {
|
|
1580
1243
|
registry.auth[action] = {
|
|
1581
1244
|
handler: async () => undefined,
|
|
1582
|
-
usage:
|
|
1245
|
+
usage: commandUsage("auth", action),
|
|
1583
1246
|
description: meta.description,
|
|
1584
1247
|
examples: meta.examples,
|
|
1585
1248
|
requiredFlags: meta.requiredFlags,
|
|
@@ -1591,9 +1254,14 @@ function commandDefinitions(resourceFilter) {
|
|
|
1591
1254
|
export function buildCommandRegistry(resourceFilter) {
|
|
1592
1255
|
const registry = {};
|
|
1593
1256
|
for (const [resource, actions,] of Object.entries(commandDefinitions(resourceFilter))) {
|
|
1594
|
-
|
|
1257
|
+
const entries = {};
|
|
1258
|
+
registry[resource] = entries;
|
|
1595
1259
|
for (const [action, meta,] of Object.entries(actions)) {
|
|
1596
|
-
|
|
1260
|
+
let entry;
|
|
1261
|
+
Object.defineProperty(entries, action, {
|
|
1262
|
+
enumerable: true,
|
|
1263
|
+
get: () => entry ??= buildRegistryEntry(resource, action, meta),
|
|
1264
|
+
});
|
|
1597
1265
|
}
|
|
1598
1266
|
}
|
|
1599
1267
|
return registry;
|
|
@@ -1841,9 +1509,7 @@ function planProjectKeyFromArgs(flags) {
|
|
|
1841
1509
|
const fromFlag = flags["project-key"];
|
|
1842
1510
|
if (typeof fromFlag === "string" && fromFlag.trim().length > 0)
|
|
1843
1511
|
return fromFlag.trim();
|
|
1844
|
-
|
|
1845
|
-
return undefined;
|
|
1846
|
-
const fromEnv = process.env.DATAIKU_PROJECT_KEY;
|
|
1512
|
+
const fromEnv = ambientProjectKey();
|
|
1847
1513
|
return fromEnv !== undefined && fromEnv.trim().length > 0 ? fromEnv.trim() : undefined;
|
|
1848
1514
|
}
|
|
1849
1515
|
/**
|
|
@@ -1895,11 +1561,6 @@ function optionalJsonFlag(flags, name) {
|
|
|
1895
1561
|
function requiredPlanJsonInput(flags, usage) {
|
|
1896
1562
|
return requiredJsonInput(flags, `--data, --data-file, or --stdin is required. Usage: ${usage}`);
|
|
1897
1563
|
}
|
|
1898
|
-
function requiredPlanPositionals(usage) {
|
|
1899
|
-
return extractPositionalArguments(usage)
|
|
1900
|
-
.filter((positional) => positional.required)
|
|
1901
|
-
.map((positional) => positional.name);
|
|
1902
|
-
}
|
|
1903
1564
|
function dataQualityEndpoint(projectKey, datasetName, suffix) {
|
|
1904
1565
|
return encodedProjectEndpointForPlan(projectKey, `/datasets/${encodeURIComponent(datasetName)}/data-quality${suffix}`);
|
|
1905
1566
|
}
|
|
@@ -1982,15 +1643,12 @@ function encodePluginSegmentsForPlan(contentPath) {
|
|
|
1982
1643
|
*/
|
|
1983
1644
|
function pluginGitPlanPayload(flags) {
|
|
1984
1645
|
const repository = requiredPlanFlag(flags, "repository", "dss plugin install-from-git --repository URL");
|
|
1985
|
-
|
|
1646
|
+
// Mirrors PluginsResource install/update bodies: absent options are sent as null.
|
|
1647
|
+
return {
|
|
1986
1648
|
gitRepositoryUrl: validatedPlanRepositoryUrl(repository, "repository", "--repository URL"),
|
|
1649
|
+
gitCheckout: typeof flags["checkout"] === "string" ? flags["checkout"] : null,
|
|
1650
|
+
gitSubpath: typeof flags["path-in-repository"] === "string" ? flags["path-in-repository"] : null,
|
|
1987
1651
|
};
|
|
1988
|
-
if (typeof flags["checkout"] === "string")
|
|
1989
|
-
payload.gitCheckout = flags["checkout"];
|
|
1990
|
-
if (typeof flags["path-in-repository"] === "string") {
|
|
1991
|
-
payload.gitSubpath = flags["path-in-repository"];
|
|
1992
|
-
}
|
|
1993
|
-
return payload;
|
|
1994
1652
|
}
|
|
1995
1653
|
function optionalPlanProjectScope(flags) {
|
|
1996
1654
|
const projectKey = flags["project-key"];
|
|
@@ -2123,16 +1781,28 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2123
1781
|
};
|
|
2124
1782
|
case "wiki.create": {
|
|
2125
1783
|
const name = requiredPlanFlag(flags, "name", entry.usage);
|
|
2126
|
-
|
|
1784
|
+
const content = textInput(flags);
|
|
1785
|
+
const create = {
|
|
2127
1786
|
method: "POST",
|
|
2128
1787
|
endpoint: projectEndpoint("/wiki/"),
|
|
1788
|
+
payload: { projectKey, name, parent: flags["parent"] ?? null, },
|
|
1789
|
+
};
|
|
1790
|
+
return {
|
|
1791
|
+
...create,
|
|
2129
1792
|
identifiers: { name, },
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
1793
|
+
// Content is not accepted by the create endpoint; it lands in a follow-up update.
|
|
1794
|
+
...(content === undefined ? {} : {
|
|
1795
|
+
requests: [
|
|
1796
|
+
{ sequence: 1, ...create, },
|
|
1797
|
+
{ sequence: 2, method: "GET", endpoint: projectEndpoint("/wiki/{createdArticleId}"), },
|
|
1798
|
+
{
|
|
1799
|
+
sequence: 3,
|
|
1800
|
+
method: "PUT",
|
|
1801
|
+
endpoint: projectEndpoint("/wiki/{createdArticleId}"),
|
|
1802
|
+
payload: { payload: content, },
|
|
1803
|
+
},
|
|
1804
|
+
],
|
|
1805
|
+
}),
|
|
2136
1806
|
};
|
|
2137
1807
|
}
|
|
2138
1808
|
case "wiki.update":
|
|
@@ -2158,7 +1828,7 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2158
1828
|
const dataName = data?.["name"];
|
|
2159
1829
|
const name = flagName ?? (typeof dataName === "string" ? dataName : undefined);
|
|
2160
1830
|
if (!name) {
|
|
2161
|
-
throw new UsageError(
|
|
1831
|
+
throw new UsageError(`--name or dashboard settings containing a string name are required. Usage: ${commandUsage("dashboard", "create")}`);
|
|
2162
1832
|
}
|
|
2163
1833
|
const listed = parseBooleanOption(flags["listed"], "--listed");
|
|
2164
1834
|
const payload = { ...(data ?? { pages: [], }), name, };
|
|
@@ -2196,7 +1866,7 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2196
1866
|
const name = flags["name"];
|
|
2197
1867
|
const type = flags["type"];
|
|
2198
1868
|
if (!data && (!name || !type)) {
|
|
2199
|
-
throw new UsageError(
|
|
1869
|
+
throw new UsageError(`--data or both --name and --type are required. Usage: ${commandUsage("insight", "create")}`);
|
|
2200
1870
|
}
|
|
2201
1871
|
const prototype = { ...data, };
|
|
2202
1872
|
if (name !== undefined)
|
|
@@ -2280,7 +1950,7 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2280
1950
|
};
|
|
2281
1951
|
case "flow-zone.create": {
|
|
2282
1952
|
const name = flowZoneName(flags["name"]);
|
|
2283
|
-
const payload = { name, color: flowZoneColor(flags["color"])
|
|
1953
|
+
const payload = { name, color: flowZoneColor(flags["color"]) ?? "#2ab1ac", };
|
|
2284
1954
|
return {
|
|
2285
1955
|
method: "POST",
|
|
2286
1956
|
endpoint: projectEndpoint("/flow/zones"),
|
|
@@ -2319,17 +1989,25 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2319
1989
|
if (!connection && dsType.toLowerCase() !== "uploadedfiles") {
|
|
2320
1990
|
throw new UsageError("--connection is required unless --type is UploadedFiles.");
|
|
2321
1991
|
}
|
|
1992
|
+
const endpoint = projectEndpoint("/datasets/"); // throws without a project key
|
|
2322
1993
|
return {
|
|
2323
1994
|
method: "POST",
|
|
2324
|
-
endpoint
|
|
1995
|
+
endpoint,
|
|
2325
1996
|
identifiers: { name, },
|
|
2326
|
-
payload: {
|
|
1997
|
+
payload: buildDatasetCreateBody({
|
|
1998
|
+
projectKey: projectKey,
|
|
1999
|
+
datasetName: name,
|
|
2000
|
+
connection,
|
|
2001
|
+
dsType,
|
|
2002
|
+
}),
|
|
2327
2003
|
};
|
|
2328
2004
|
}
|
|
2329
2005
|
case "dataset.clone": {
|
|
2330
2006
|
const source = args[0];
|
|
2331
2007
|
const target = args[1];
|
|
2332
2008
|
return {
|
|
2009
|
+
exact: false,
|
|
2010
|
+
reason: "Apply GETs the source dataset and copies its current connection, format, and schema into the new dataset body.",
|
|
2333
2011
|
method: "POST",
|
|
2334
2012
|
endpoint: projectEndpoint("/datasets/"),
|
|
2335
2013
|
identifiers: { source, target, },
|
|
@@ -2491,7 +2169,7 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2491
2169
|
identifiers: { name: id, },
|
|
2492
2170
|
};
|
|
2493
2171
|
case "recipe.create": {
|
|
2494
|
-
|
|
2172
|
+
requiredPlanFlag(flags, "type", entry.usage);
|
|
2495
2173
|
const outputDataset = flags["output"];
|
|
2496
2174
|
const outputFolder = flags["output-folder"];
|
|
2497
2175
|
if (outputDataset && outputFolder) {
|
|
@@ -2503,19 +2181,14 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2503
2181
|
if (outputFolder && !flags["output-connection"]) {
|
|
2504
2182
|
throw new UsageError("--output-connection is required when using --output-folder.");
|
|
2505
2183
|
}
|
|
2184
|
+
const endpoint = projectEndpoint("/recipes/"); // throws without a project key
|
|
2185
|
+
// Same flag mapping and body construction as the handler and RecipesResource.create.
|
|
2186
|
+
const { recipePrototype, creationSettings, } = buildRecipeCreateRequest(recipeCreateOptionsFromFlags(flags), projectKey);
|
|
2506
2187
|
return {
|
|
2507
2188
|
method: "POST",
|
|
2508
|
-
endpoint
|
|
2509
|
-
identifiers: { name:
|
|
2510
|
-
payload: {
|
|
2511
|
-
type,
|
|
2512
|
-
name: flags["name"],
|
|
2513
|
-
inputDatasets: recipeInputDatasetsFromFlags(flags),
|
|
2514
|
-
outputDataset,
|
|
2515
|
-
outputFolder,
|
|
2516
|
-
outputConnection: flags["output-connection"],
|
|
2517
|
-
projectKey,
|
|
2518
|
-
},
|
|
2189
|
+
endpoint,
|
|
2190
|
+
identifiers: { name: recipePrototype.name, },
|
|
2191
|
+
payload: { recipePrototype, creationSettings, },
|
|
2519
2192
|
};
|
|
2520
2193
|
}
|
|
2521
2194
|
case "recipe.run":
|
|
@@ -2641,22 +2314,54 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2641
2314
|
if (activeRaw !== "true" && activeRaw !== "false") {
|
|
2642
2315
|
throw new UsageError(`Usage: ${entry.usage}`);
|
|
2643
2316
|
}
|
|
2317
|
+
const lightEndpoint = projectEndpoint(`/scenarios/${encodeURIComponent(id)}/light`);
|
|
2318
|
+
const active = activeRaw === "true";
|
|
2319
|
+
// DSS parses the light PUT as a full Scenario, so the command echoes the
|
|
2320
|
+
// current light status with `active` overridden (see ScenariosResource.setActive).
|
|
2644
2321
|
return {
|
|
2645
2322
|
method: "PUT",
|
|
2646
|
-
endpoint:
|
|
2323
|
+
endpoint: lightEndpoint,
|
|
2647
2324
|
identifiers: { id, },
|
|
2648
|
-
payload: {
|
|
2325
|
+
payload: { active, },
|
|
2326
|
+
requests: [
|
|
2327
|
+
{ sequence: 1, method: "GET", endpoint: lightEndpoint, },
|
|
2328
|
+
{
|
|
2329
|
+
sequence: 2,
|
|
2330
|
+
method: "PUT",
|
|
2331
|
+
endpoint: lightEndpoint,
|
|
2332
|
+
payload: { "...current": true, active, },
|
|
2333
|
+
},
|
|
2334
|
+
{ sequence: 3, method: "GET", endpoint: lightEndpoint, },
|
|
2335
|
+
],
|
|
2649
2336
|
};
|
|
2650
2337
|
}
|
|
2651
2338
|
case "folder.create": {
|
|
2652
2339
|
const name = requiredPlanFlag(flags, "name", entry.usage);
|
|
2653
2340
|
const type = flags["type"];
|
|
2654
2341
|
const connection = flags["connection"];
|
|
2342
|
+
const pathFlag = flags["path"];
|
|
2343
|
+
const body = {
|
|
2344
|
+
name,
|
|
2345
|
+
projectKey,
|
|
2346
|
+
type: type ?? null,
|
|
2347
|
+
params: { connection, path: pathFlag?.trim() || "/${projectKey}/${odbId}", },
|
|
2348
|
+
};
|
|
2349
|
+
// Mirrors FoldersResource.create.
|
|
2350
|
+
if (connection === undefined) {
|
|
2351
|
+
return {
|
|
2352
|
+
exact: false,
|
|
2353
|
+
reason: "Without --connection, apply reads DSS admin settings to pick the managed-folder connection (falling back to filesystem_folders); params.connection is set then.",
|
|
2354
|
+
method: "POST",
|
|
2355
|
+
endpoint: projectEndpoint("/managedfolders/"),
|
|
2356
|
+
identifiers: { name, },
|
|
2357
|
+
payload: body,
|
|
2358
|
+
};
|
|
2359
|
+
}
|
|
2655
2360
|
return {
|
|
2656
2361
|
method: "POST",
|
|
2657
2362
|
endpoint: projectEndpoint("/managedfolders/"),
|
|
2658
2363
|
identifiers: { name, },
|
|
2659
|
-
payload:
|
|
2364
|
+
payload: body,
|
|
2660
2365
|
};
|
|
2661
2366
|
}
|
|
2662
2367
|
case "job.abort":
|
|
@@ -2680,18 +2385,22 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2680
2385
|
endpoint: projectEndpoint(`/scenarios/${encodeURIComponent(id)}/`),
|
|
2681
2386
|
identifiers: { id, },
|
|
2682
2387
|
};
|
|
2683
|
-
case "scenario.create":
|
|
2388
|
+
case "scenario.create": {
|
|
2389
|
+
const type = flags["type"] ?? "step_based";
|
|
2684
2390
|
return {
|
|
2685
2391
|
method: "POST",
|
|
2686
2392
|
endpoint: projectEndpoint("/scenarios/"),
|
|
2687
2393
|
identifiers: { id: args[0], name: args[1], },
|
|
2394
|
+
// Mirrors ScenariosResource.create's default params for step-based scenarios.
|
|
2688
2395
|
payload: {
|
|
2689
2396
|
id: args[0],
|
|
2690
2397
|
name: args[1],
|
|
2691
2398
|
projectKey,
|
|
2692
|
-
type
|
|
2399
|
+
type,
|
|
2400
|
+
params: type === "step_based" ? { steps: [], triggers: [], reporters: [], } : {},
|
|
2693
2401
|
},
|
|
2694
2402
|
};
|
|
2403
|
+
}
|
|
2695
2404
|
case "scenario.update":
|
|
2696
2405
|
return {
|
|
2697
2406
|
method: "PUT",
|
|
@@ -2726,6 +2435,8 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
2726
2435
|
};
|
|
2727
2436
|
case "variable.set":
|
|
2728
2437
|
return {
|
|
2438
|
+
exact: false,
|
|
2439
|
+
reason: "The payload lists the requested changes; apply PUTs the full {standard, local} object (merged with the current variables unless --replace).",
|
|
2729
2440
|
method: "PUT",
|
|
2730
2441
|
endpoint: projectEndpoint("/variables/"),
|
|
2731
2442
|
payload: {
|
|
@@ -3153,6 +2864,8 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
3153
2864
|
};
|
|
3154
2865
|
case "saved-model.import-mlflow-version-from-folder":
|
|
3155
2866
|
return {
|
|
2867
|
+
exact: false,
|
|
2868
|
+
reason: "Apply sends these values as query parameters (with codeEnvName and binaryClassificationThreshold defaults) on an empty multipart body; the payload shows them structured.",
|
|
3156
2869
|
method: "POST",
|
|
3157
2870
|
endpoint: projectEndpoint(`/savedmodels/${encodeURIComponent(id)}/versions/${encodeURIComponent(args[1] ?? "")}`),
|
|
3158
2871
|
identifiers: { savedModelId: id, versionId: args[1], },
|
|
@@ -3203,7 +2916,7 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
3203
2916
|
}
|
|
3204
2917
|
return {
|
|
3205
2918
|
method: "POST",
|
|
3206
|
-
endpoint: projectEndpoint(`/savedmodels/${encodeURIComponent(id)}/versions/${encodeURIComponent(args[1] ?? "")}/external-ml/actions/evaluate`),
|
|
2919
|
+
endpoint: `${projectEndpoint(`/savedmodels/${encodeURIComponent(id)}/versions/${encodeURIComponent(args[1] ?? "")}/external-ml/actions/evaluate`)}?useOptimalThreshold=${parseBooleanOption(flags["use-optimal-threshold"], "--use-optimal-threshold") ?? true}&skipExpensiveReports=${parseBooleanOption(flags["skip-expensive-reports"], "--skip-expensive-reports") ?? true}`,
|
|
3207
2920
|
identifiers: { savedModelId: id, versionId: args[1], },
|
|
3208
2921
|
payload,
|
|
3209
2922
|
};
|
|
@@ -3402,17 +3115,19 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
3402
3115
|
};
|
|
3403
3116
|
case "plugin.create-dev": {
|
|
3404
3117
|
const creationMode = requiredPlanFlag(flags, "creation-mode", entry.usage);
|
|
3118
|
+
const needsGit = creationMode !== "EMPTY";
|
|
3119
|
+
// Mirrors PluginsResource.createDev: git fields are always present, null when unused.
|
|
3405
3120
|
const payload = {
|
|
3406
3121
|
pluginId: id,
|
|
3407
3122
|
creationMode,
|
|
3123
|
+
gitRepository: needsGit && typeof flags["repository"] === "string"
|
|
3124
|
+
? validatedPlanRepositoryUrl(flags["repository"], "repository", "--repository URL")
|
|
3125
|
+
: null,
|
|
3126
|
+
gitCheckout: needsGit && typeof flags["checkout"] === "string" ? flags["checkout"] : null,
|
|
3127
|
+
gitSubpath: creationMode === "GIT_EXPORT" && typeof flags["path-in-repository"] === "string"
|
|
3128
|
+
? flags["path-in-repository"]
|
|
3129
|
+
: null,
|
|
3408
3130
|
};
|
|
3409
|
-
if (typeof flags["repository"] === "string")
|
|
3410
|
-
payload.gitRepository = flags["repository"];
|
|
3411
|
-
if (typeof flags["checkout"] === "string")
|
|
3412
|
-
payload.gitCheckout = flags["checkout"];
|
|
3413
|
-
if (typeof flags["path-in-repository"] === "string") {
|
|
3414
|
-
payload.gitSubpath = flags["path-in-repository"];
|
|
3415
|
-
}
|
|
3416
3131
|
return {
|
|
3417
3132
|
method: "POST",
|
|
3418
3133
|
endpoint: "/public/api/plugins/actions/createDev",
|
|
@@ -3473,14 +3188,13 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
3473
3188
|
identifiers: { pluginId: id, path: args[1], },
|
|
3474
3189
|
};
|
|
3475
3190
|
case "plugin.rename": {
|
|
3476
|
-
|
|
3477
|
-
if (!newName)
|
|
3191
|
+
if (!args[2])
|
|
3478
3192
|
throw new UsageError(`Usage: ${entry.usage}`);
|
|
3479
3193
|
return {
|
|
3480
3194
|
method: "POST",
|
|
3481
3195
|
endpoint: `${pluginRootEndpoint(id, "/contents-actions/rename")}`,
|
|
3482
3196
|
identifiers: { pluginId: id, path: args[1], },
|
|
3483
|
-
payload: { oldPath: args[1]
|
|
3197
|
+
payload: { oldPath: `/${validatePluginPath(args[1] ?? "")}`, newName: args[2], },
|
|
3484
3198
|
};
|
|
3485
3199
|
}
|
|
3486
3200
|
case "plugin.move": {
|
|
@@ -3491,7 +3205,10 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
3491
3205
|
method: "POST",
|
|
3492
3206
|
endpoint: `${pluginRootEndpoint(id, "/contents-actions/move")}`,
|
|
3493
3207
|
identifiers: { pluginId: id, path: args[1], },
|
|
3494
|
-
payload: {
|
|
3208
|
+
payload: {
|
|
3209
|
+
oldPath: `/${validatePluginPath(args[1] ?? "")}`,
|
|
3210
|
+
newPath: validatePluginDestinationPath(destination),
|
|
3211
|
+
},
|
|
3495
3212
|
};
|
|
3496
3213
|
}
|
|
3497
3214
|
case "business-app.save-settings":
|
|
@@ -3541,6 +3258,8 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
3541
3258
|
// plan carries no preflight requests and no fake concrete GET
|
|
3542
3259
|
// path: `{targetProjectKey}` resolves at apply time.
|
|
3543
3260
|
return {
|
|
3261
|
+
exact: false,
|
|
3262
|
+
reason: "targetProjectKey (and targetProjectName when omitted) are generated during apply; the sent body adds them.",
|
|
3544
3263
|
method: "POST",
|
|
3545
3264
|
endpoint: `/public/api/apps/${encodeURIComponent(id)}/instances`,
|
|
3546
3265
|
identifiers: {
|
|
@@ -4222,7 +3941,6 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
4222
3941
|
evaluateProjectStandardsChecks,
|
|
4223
3942
|
}),
|
|
4224
3943
|
identifiers: { bundleId: id, },
|
|
4225
|
-
payload: {},
|
|
4226
3944
|
};
|
|
4227
3945
|
}
|
|
4228
3946
|
case "bundle.publish":
|
|
@@ -4440,7 +4158,7 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
4440
4158
|
case "code-env.set-jupyter": {
|
|
4441
4159
|
const active = parseBooleanOption(flags["active"], "--active");
|
|
4442
4160
|
if (active === undefined) {
|
|
4443
|
-
throw new UsageError(
|
|
4161
|
+
throw new UsageError(`--active is required. Usage: ${commandUsage("code-env", "set-jupyter")}`);
|
|
4444
4162
|
}
|
|
4445
4163
|
const wait = codeEnvWait(flags);
|
|
4446
4164
|
return {
|
|
@@ -5075,7 +4793,7 @@ export function buildMutationPlan(resource, action, meta, args, flags) {
|
|
|
5075
4793
|
if (!entry.mutatesDss && entry.sideEffect !== "write") {
|
|
5076
4794
|
throw new UsageError(`--plan is only supported for mutating commands. Usage: ${meta.usage}`);
|
|
5077
4795
|
}
|
|
5078
|
-
const requiredPositionals =
|
|
4796
|
+
const requiredPositionals = entry.positionalArguments.filter((positional) => positional.required);
|
|
5079
4797
|
requireArgs(args, requiredPositionals.length, meta.usage);
|
|
5080
4798
|
const projectKey = projectKeyForPlan(entry, flags);
|
|
5081
4799
|
const shape = commandPlanShape(resource, action, args, flags, entry, projectKey);
|
|
@@ -5099,7 +4817,7 @@ export const BATCH_PLAN_EXIT_CODES = {
|
|
|
5099
4817
|
longRunningFailure: 4,
|
|
5100
4818
|
assertionFailure: 4,
|
|
5101
4819
|
};
|
|
5102
|
-
export const BATCH_USAGE = "
|
|
4820
|
+
export const BATCH_USAGE = commandUsage("batch", "run");
|
|
5103
4821
|
const BATCH_DESCRIPTION = "Run dss argv arrays fail-fast by default. The result aggregates failed/retryable/failureCodes; process exit remains the first failed step's exit code.";
|
|
5104
4822
|
export const BATCH_HINT = 'Pass a JSON array of argv arrays, e.g. [["dataset","list"],["recipe","update","r","--data-file","p.json"]].';
|
|
5105
4823
|
export const BATCH_EXAMPLE_PAYLOAD = [
|