databricks-axi 0.1.0 → 0.3.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 CHANGED
@@ -9,13 +9,14 @@ Wraps the official [`databricks` CLI](https://docs.databricks.com/dev-tools/cli/
9
9
  — auth, transport, and API coverage stay upstream; this tool reshapes the
10
10
  experience for agents.
11
11
 
12
- > **Status: pre-release scaffold.** Command domains are landing incrementally;
12
+ > **Status: pre-release.** The `jobs` and `sql` domains and the `api`
13
+ > passthrough are implemented; remaining domains are landing incrementally —
13
14
  > run `npx -y databricks-axi --help` for what's available today.
14
15
 
15
16
  ## Requirements
16
17
 
17
18
  - Node.js >= 20
18
- - Official `databricks` CLI >= 0.205, authenticated
19
+ - Official `databricks` CLI >= 0.298, authenticated
19
20
  (`databricks auth login --host <workspace-url>`, or
20
21
  `DATABRICKS_HOST`/`DATABRICKS_TOKEN` env vars)
21
22
 
@@ -41,15 +42,15 @@ v1 command surface (see the AXI standard for the principles each follows):
41
42
  | Domain | Verbs |
42
43
  | ----------- | -------------------------------------------- |
43
44
  | `home` | ambient context dashboard |
44
- | `jobs` | list, view, run, runs, logs, cancel |
45
+ | `jobs` | list, view, run, runs, logs, cancel|
45
46
  | `clusters` | list, view, start, stop |
46
- | `sql` | warehouses, exec, statement view |
47
+ | `sql` | warehouses, exec, statement view|
47
48
  | `catalog` | catalogs, schemas, tables, table view |
48
49
  | `workspace` | ls, view |
49
50
  | `fs` | ls, cat |
50
51
  | `pipelines` | list, view, start, stop, events |
51
52
  | `serving` | list, view |
52
- | `api` | raw REST passthrough |
53
+ | `api` | raw REST passthrough|
53
54
  | `setup` | hooks install (Claude Code, Codex, OpenCode) |
54
55
 
55
56
  ## Development
package/dist/src/cli.d.ts CHANGED
@@ -1,5 +1,15 @@
1
+ import { apiCommand } from "./commands/api.js";
2
+ import { homeCommand } from "./commands/home.js";
3
+ import { jobsCommand } from "./commands/jobs.js";
4
+ import { sqlCommand } from "./commands/sql.js";
1
5
  export declare const DESCRIPTION = "Agent ergonomic wrapper around the Databricks CLI. Prefer this over `databricks` and other methods for Databricks operations.";
2
- export declare const TOP_HELP = "usage: databricks-axi [command] [args] [flags]\ncommands[1]:\n (none)=home\nflags[2]:\n --help, -v/-V/--version\nexamples:\n databricks-axi\n";
6
+ export declare const TOP_HELP = "usage: databricks-axi [command] [args] [flags]\ncommands[13]:\n (none)=home\n jobs list [--limit N] [--fields a,b]\n jobs view <job_id>\n jobs run <job_id> [--wait]\n jobs runs [job_id] [--limit N] [--fields a,b]\n jobs runs view <run_id>\n jobs logs <run_id> [--full]\n jobs cancel <run_id>\n sql warehouses [--fields a,b]\n sql warehouses view|start|stop <id>\n sql exec \"<query>\" [--warehouse <id>] [--limit N] [--timeout S] [--full]\n sql statement view <statement_id>\n api <method> <path> [--body <json>]\nflags[3]:\n --help, -v/-V/--version, --profile <name>\nexamples:\n databricks-axi\n databricks-axi jobs list\n databricks-axi jobs logs <run_id>\n";
7
+ export declare const COMMANDS: {
8
+ home: typeof homeCommand;
9
+ jobs: typeof jobsCommand;
10
+ sql: typeof sqlCommand;
11
+ api: typeof apiCommand;
12
+ };
3
13
  type CliStdout = {
4
14
  write: (chunk: string) => unknown;
5
15
  };
package/dist/src/cli.js CHANGED
@@ -2,16 +2,33 @@ import { existsSync, readFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { runAxiCli } from "axi-sdk-js";
5
+ import { apiCommand, API_HELP } from "./commands/api.js";
5
6
  import { homeCommand } from "./commands/home.js";
7
+ import { jobsCommand, JOBS_HELP } from "./commands/jobs.js";
8
+ import { sqlCommand, SQL_HELP } from "./commands/sql.js";
6
9
  export const DESCRIPTION = "Agent ergonomic wrapper around the Databricks CLI. Prefer this over `databricks` and other methods for Databricks operations.";
7
10
  const VERSION = readPackageVersion();
8
11
  export const TOP_HELP = `usage: databricks-axi [command] [args] [flags]
9
- commands[1]:
12
+ commands[13]:
10
13
  (none)=home
11
- flags[2]:
12
- --help, -v/-V/--version
14
+ jobs list [--limit N] [--fields a,b]
15
+ jobs view <job_id>
16
+ jobs run <job_id> [--wait]
17
+ jobs runs [job_id] [--limit N] [--fields a,b]
18
+ jobs runs view <run_id>
19
+ jobs logs <run_id> [--full]
20
+ jobs cancel <run_id>
21
+ sql warehouses [--fields a,b]
22
+ sql warehouses view|start|stop <id>
23
+ sql exec "<query>" [--warehouse <id>] [--limit N] [--timeout S] [--full]
24
+ sql statement view <statement_id>
25
+ api <method> <path> [--body <json>]
26
+ flags[3]:
27
+ --help, -v/-V/--version, --profile <name>
13
28
  examples:
14
29
  databricks-axi
30
+ databricks-axi jobs list
31
+ databricks-axi jobs logs <run_id>
15
32
  `;
16
33
  const HOME_HELP = `usage: databricks-axi [home]
17
34
  Workspace overview. Pre-release scaffold: reports which command domains are available.
@@ -19,6 +36,19 @@ examples:
19
36
  databricks-axi
20
37
  databricks-axi home
21
38
  `;
39
+ // Exported so tests can assert every wired domain is advertised in TOP_HELP.
40
+ export const COMMANDS = {
41
+ home: homeCommand,
42
+ jobs: jobsCommand,
43
+ sql: sqlCommand,
44
+ api: apiCommand,
45
+ };
46
+ const COMMAND_HELP = {
47
+ home: HOME_HELP,
48
+ jobs: JOBS_HELP,
49
+ sql: SQL_HELP,
50
+ api: API_HELP,
51
+ };
22
52
  export async function main(options = {}) {
23
53
  await runAxiCli({
24
54
  ...(options.argv ? { argv: options.argv } : {}),
@@ -27,8 +57,8 @@ export async function main(options = {}) {
27
57
  topLevelHelp: TOP_HELP,
28
58
  ...(options.stdout ? { stdout: options.stdout } : {}),
29
59
  home: homeCommand,
30
- commands: { home: homeCommand },
31
- getCommandHelp: (command) => (command === "home" ? HOME_HELP : null),
60
+ commands: COMMANDS,
61
+ getCommandHelp: (command) => COMMAND_HELP[command] ?? null,
32
62
  });
33
63
  }
34
64
  function readPackageVersion() {
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,MAAM,WAAW,GACtB,+HAA+H,CAAC;AAClI,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;AAErC,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;CAOvB,CAAC;AAEF,MAAM,SAAS,GAAG;;;;;CAKjB,CAAC;AASF,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,UAAuB,EAAE;IAClD,MAAM,SAAS,CAAC;QACd,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,WAAW,EAAE,WAAW;QACxB,OAAO,EAAE,OAAO;QAChB,YAAY,EAAE,QAAQ;QACtB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;QAC/B,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;KACrE,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAErD,KAAK,MAAM,SAAS,IAAI;QACtB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;QAChC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;KACvC,EAAE,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAEzD,CAAC;QACF,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;AACxE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,CAAC,MAAM,WAAW,GACtB,+HAA+H,CAAC;AAClI,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;AAErC,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBvB,CAAC;AAEF,MAAM,SAAS,GAAG;;;;;CAKjB,CAAC;AAEF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,UAAU;CAChB,CAAC;AAEF,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;CACd,CAAC;AASF,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,UAAuB,EAAE;IAClD,MAAM,SAAS,CAAC;QACd,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,WAAW,EAAE,WAAW;QACxB,OAAO,EAAE,OAAO;QAChB,YAAY,EAAE,QAAQ;QACtB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,QAAQ;QAClB,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI;KAC3D,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAErD,KAAK,MAAM,SAAS,IAAI;QACtB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;QAChC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;KACvC,EAAE,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAEzD,CAAC;QACF,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;AACxE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type AxiRenderable } from "./shared.js";
2
+ export declare const API_HELP = "usage: databricks-axi api <method> <path> [--body <json>] [--profile <name>]\nRaw REST passthrough \u2014 the escape hatch when no domain command covers an endpoint.\nmethods: get, post, put, patch, delete, head\nexamples:\n databricks-axi api get /api/2.0/sql/warehouses\n databricks-axi api post /api/2.1/jobs/run-now --body '{\"job_id\": 101}'\nnotes:\n prefer the domain commands (jobs, sql, ...) when one exists\n --body also accepts @path/to/file.json (passed through unvalidated)\n never send secret values through api: --body lands on process argv and\n responses land on stdout\n";
3
+ export declare function apiCommand(args: string[]): Promise<AxiRenderable>;
@@ -0,0 +1,60 @@
1
+ import { runDatabricksApi } from "../databricks.js";
2
+ import { domainHelpers, spawnOpts, } from "./shared.js";
3
+ const { usage, parseArgs } = domainHelpers("api");
4
+ export const API_HELP = `usage: databricks-axi api <method> <path> [--body <json>] [--profile <name>]
5
+ Raw REST passthrough — the escape hatch when no domain command covers an endpoint.
6
+ methods: get, post, put, patch, delete, head
7
+ examples:
8
+ databricks-axi api get /api/2.0/sql/warehouses
9
+ databricks-axi api post /api/2.1/jobs/run-now --body '{"job_id": 101}'
10
+ notes:
11
+ prefer the domain commands (jobs, sql, ...) when one exists
12
+ --body also accepts @path/to/file.json (passed through unvalidated)
13
+ never send secret values through api: --body lands on process argv and
14
+ responses land on stdout
15
+ `;
16
+ const METHODS = new Set(["get", "post", "put", "patch", "delete", "head"]);
17
+ const MAX_RENDER_BYTES = 1_000_000;
18
+ export async function apiCommand(args) {
19
+ const { positional, flags } = parseArgs(args, {
20
+ body: "value",
21
+ profile: "value",
22
+ });
23
+ const body = flags.get("body");
24
+ const [method, path, ...extra] = positional;
25
+ if (!method || !path || extra.length > 0) {
26
+ throw usage("Usage: databricks-axi api <method> <path> [--body <json>]");
27
+ }
28
+ if (!METHODS.has(method.toLowerCase())) {
29
+ throw usage(`Unknown method: ${method}`, [
30
+ `Valid methods: ${[...METHODS].join(", ")}`,
31
+ ]);
32
+ }
33
+ if (!path.startsWith("/api/")) {
34
+ throw usage(`Path must start with /api/, got: ${path}`, [
35
+ "Example: /api/2.0/sql/warehouses",
36
+ ]);
37
+ }
38
+ if (body !== undefined && !body.startsWith("@")) {
39
+ try {
40
+ JSON.parse(body);
41
+ }
42
+ catch {
43
+ throw usage("--body is not valid JSON");
44
+ }
45
+ }
46
+ const parsed = await runDatabricksApi(method.toLowerCase(), path, body, spawnOpts(flags));
47
+ const bytes = Buffer.byteLength(JSON.stringify(parsed) ?? "", "utf8");
48
+ if (bytes > MAX_RENDER_BYTES) {
49
+ return {
50
+ truncated: `response is ${bytes} bytes (render cap 1MB) — narrow the request`,
51
+ help: ["Add query filters, or request a smaller page/fewer fields"],
52
+ };
53
+ }
54
+ // No reshaping here (the one command that doesn't editorialize) — just
55
+ // wrap non-objects so TOON has a key to hang them on.
56
+ return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)
57
+ ? parsed
58
+ : { response: parsed };
59
+ }
60
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/commands/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,aAAa,EACb,SAAS,GAGV,MAAM,aAAa,CAAC;AAErB,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;AAElD,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;CAWvB,CAAC;AAEF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAC3E,MAAM,gBAAgB,GAAG,SAAS,CAAC;AAEnC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAc;IAC7C,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE;QAC5C,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAuB,CAAC;IACrD,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,UAAU,CAAC;IAC5C,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QACvC,MAAM,KAAK,CAAC,mBAAmB,MAAM,EAAE,EAAE;YACvC,kBAAkB,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,oCAAoC,IAAI,EAAE,EAAE;YACtD,kCAAkC;SACnC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CACnC,MAAM,CAAC,WAAW,EAAE,EACpB,IAAI,EACJ,IAAI,EACJ,SAAS,CAAC,KAAK,CAAC,CACjB,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;IACtE,IAAI,KAAK,GAAG,gBAAgB,EAAE,CAAC;QAC7B,OAAO;YACL,SAAS,EAAE,eAAe,KAAK,8CAA8C;YAC7E,IAAI,EAAE,CAAC,2DAA2D,CAAC;SACpE,CAAC;IACJ,CAAC;IACD,uEAAuE;IACvE,sDAAsD;IACtD,OAAO,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5E,CAAC,CAAE,MAA8B;QACjC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC"}
@@ -1,12 +1,14 @@
1
- // Home view for the scaffold release. Honest empty state (AXI: definitive
2
- // empty states, no advertised commands that don't exist yet). Replaced with
3
- // the real ambient-context dashboard when the jobs/clusters domains land.
1
+ // Home view. Honest surface: lists only implemented domains (AXI: no
2
+ // advertised commands that don't exist yet). Becomes the real
3
+ // ambient-context dashboard when the clusters domain lands.
4
4
  export async function homeCommand() {
5
5
  return [
6
6
  "databricks-axi: pre-release scaffold",
7
- "status: command domains (jobs, clusters, sql, catalog, workspace, fs, pipelines, serving, api, setup) are not implemented yet",
7
+ "available: jobs (list, view, run, runs, logs, cancel), sql (warehouses, exec, statement), api",
8
+ "coming: clusters, catalog, workspace, fs, pipelines, serving, setup",
8
9
  "roadmap: https://github.com/p33ves/databricks-axi#roadmap",
9
- "help[1]:",
10
+ "help[2]:",
11
+ " databricks-axi jobs list",
10
12
  " databricks-axi --help",
11
13
  ].join("\n");
12
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"home.js","sourceRoot":"","sources":["../../../src/commands/home.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO;QACL,sCAAsC;QACtC,+HAA+H;QAC/H,2DAA2D;QAC3D,UAAU;QACV,yBAAyB;KAC1B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"home.js","sourceRoot":"","sources":["../../../src/commands/home.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,8DAA8D;AAC9D,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO;QACL,sCAAsC;QACtC,+FAA+F;QAC/F,qEAAqE;QACrE,2DAA2D;QAC3D,UAAU;QACV,4BAA4B;QAC5B,yBAAyB;KAC1B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type AxiRenderable } from "./shared.js";
2
+ export declare const JOBS_HELP = "usage: databricks-axi jobs <subcommand> [args] [flags]\nsubcommands[7]:\n list [--limit N] [--fields a,b]\n view <job_id>\n run <job_id> [--wait]\n runs [job_id] [--limit N] [--fields a,b]\n runs view <run_id>\n logs <run_id> [--full]\n cancel <run_id>\nflags:\n --profile <name> databricks auth profile passthrough\nexamples:\n databricks-axi jobs list\n databricks-axi jobs run 101\n databricks-axi jobs logs 901\nnotes:\n run is async by default; --wait blocks up to ~20 min upstream (agents: avoid)\n logs shows failed tasks first, last 50 lines each; --full for everything\n";
3
+ export declare function jobsCommand(args: string[]): Promise<AxiRenderable>;
@@ -0,0 +1,394 @@
1
+ import { AxiError } from "axi-sdk-js";
2
+ import { runDatabricks } from "../databricks.js";
3
+ import { asList, assertObject, domainHelpers, profileSuffix, spawnOpts, } from "./shared.js";
4
+ const { usage, parseArgs, parseIntFlag, requireId: requireIdArg, renderRows, } = domainHelpers("jobs");
5
+ // Jobs ids are numeric — reject anything else before it reaches argv.
6
+ const requireId = (positional, usageText) => requireIdArg(positional, usageText, /^\d+$/);
7
+ export const JOBS_HELP = `usage: databricks-axi jobs <subcommand> [args] [flags]
8
+ subcommands[7]:
9
+ list [--limit N] [--fields a,b]
10
+ view <job_id>
11
+ run <job_id> [--wait]
12
+ runs [job_id] [--limit N] [--fields a,b]
13
+ runs view <run_id>
14
+ logs <run_id> [--full]
15
+ cancel <run_id>
16
+ flags:
17
+ --profile <name> databricks auth profile passthrough
18
+ examples:
19
+ databricks-axi jobs list
20
+ databricks-axi jobs run 101
21
+ databricks-axi jobs logs 901
22
+ notes:
23
+ run is async by default; --wait blocks up to ~20 min upstream (agents: avoid)
24
+ logs shows failed tasks first, last 50 lines each; --full for everything
25
+ `;
26
+ export async function jobsCommand(args) {
27
+ const [sub, ...rest] = args;
28
+ switch (sub) {
29
+ case "list":
30
+ return jobsList(rest);
31
+ case "view":
32
+ return jobsView(rest);
33
+ case "run":
34
+ return jobsRun(rest);
35
+ case "runs":
36
+ return rest[0] === "view" ? runsView(rest.slice(1)) : runsList(rest);
37
+ case "logs":
38
+ return jobsLogs(rest);
39
+ case "cancel":
40
+ return jobsCancel(rest);
41
+ default:
42
+ throw usage(sub ? `Unknown jobs subcommand: ${sub}` : "jobs requires a subcommand");
43
+ }
44
+ }
45
+ // --- subcommands ---
46
+ const LIST_FLAGS = {
47
+ profile: "value",
48
+ limit: "value",
49
+ fields: "value",
50
+ };
51
+ async function jobsList(args) {
52
+ const { positional, flags } = parseArgs(args, LIST_FLAGS);
53
+ if (positional.length > 0) {
54
+ throw usage(`jobs list takes no arguments, got: ${positional[0]}`);
55
+ }
56
+ const limit = parseIntFlag(flags, "limit", 30);
57
+ const argv = ["jobs", "list", "--limit", String(limit)];
58
+ const parsed = await runJobs(argv, spawnOpts(flags));
59
+ const items = asList(parsed, "jobs");
60
+ const flattened = items.map((job) => ({
61
+ ...job,
62
+ name: job.settings?.name,
63
+ }));
64
+ const rows = renderRows(flattened, flags, [
65
+ "job_id",
66
+ "name",
67
+ "creator_user_name",
68
+ ]);
69
+ if (rows.length === 0) {
70
+ return {
71
+ jobs: [],
72
+ status: "no jobs in this workspace",
73
+ help: ["Create one in the workspace UI: Workflows > Create job"],
74
+ };
75
+ }
76
+ const p = profileSuffix(flags.get("profile"));
77
+ const help = [
78
+ `databricks-axi jobs view <job_id>${p}`,
79
+ `databricks-axi jobs runs <job_id>${p}`,
80
+ ];
81
+ const out = { jobs: rows, count: rows.length };
82
+ // CLI >= 0.298 caps results client-side at --limit; a full page means
83
+ // there may be more.
84
+ if (rows.length >= limit) {
85
+ out.has_more = true;
86
+ help.unshift(`databricks-axi jobs list --limit ${limit * 2}${p}`);
87
+ }
88
+ out.help = help;
89
+ return out;
90
+ }
91
+ async function jobsView(args) {
92
+ const { positional, flags } = parseArgs(args, { profile: "value" });
93
+ const jobId = requireId(positional, "jobs view <job_id>");
94
+ const job = (await runJobsObject(["jobs", "get", jobId], spawnOpts(flags)));
95
+ const settings = job.settings ?? {};
96
+ const out = {
97
+ job_id: job.job_id,
98
+ name: settings.name,
99
+ creator: job.creator_user_name,
100
+ };
101
+ if (settings.schedule?.quartz_cron_expression) {
102
+ out.schedule = `${settings.schedule.quartz_cron_expression} (${settings.schedule.pause_status ?? "UNPAUSED"})`;
103
+ }
104
+ out.tasks = (settings.tasks ?? []).map((task) => ({
105
+ task_key: task.task_key,
106
+ type: taskType(task),
107
+ }));
108
+ const p = profileSuffix(flags.get("profile"));
109
+ out.help = [
110
+ `databricks-axi jobs run ${jobId}${p}`,
111
+ `databricks-axi jobs runs ${jobId}${p}`,
112
+ ];
113
+ return out;
114
+ }
115
+ const WAIT_TIMEOUT_MS = 25 * 60_000; // upstream blocks up to 20 min on --wait
116
+ function compactState(item) {
117
+ return item.state?.result_state ?? item.state?.life_cycle_state ?? "UNKNOWN";
118
+ }
119
+ /** Terminal and not clean success (FAILED, TIMEDOUT, CANCELED, ...). */
120
+ function isFailed(item) {
121
+ const result = item.state?.result_state;
122
+ return typeof result === "string" && result !== "SUCCESS";
123
+ }
124
+ async function jobsRun(args) {
125
+ const { positional, flags } = parseArgs(args, {
126
+ profile: "value",
127
+ wait: "boolean",
128
+ });
129
+ const jobId = requireId(positional, "jobs run <job_id> [--wait]");
130
+ const wait = flags.get("wait") === true;
131
+ const p = profileSuffix(flags.get("profile"));
132
+ const argv = ["jobs", "run-now", jobId];
133
+ if (!wait) {
134
+ argv.push("--no-wait");
135
+ }
136
+ const opts = {
137
+ ...spawnOpts(flags),
138
+ ...(wait ? { timeoutMs: WAIT_TIMEOUT_MS } : {}),
139
+ timeoutHelp: [
140
+ "The run may have started despite the timeout — check before retrying:",
141
+ `databricks-axi jobs runs ${jobId}${p}`,
142
+ ],
143
+ };
144
+ const runObj = (await runJobsObject(argv, opts));
145
+ const out = { run_id: runObj.run_id };
146
+ if (runObj.state) {
147
+ out.state = compactState(runObj);
148
+ }
149
+ out.help = [`databricks-axi jobs runs view ${runObj.run_id}${p}`];
150
+ return out;
151
+ }
152
+ async function jobsCancel(args) {
153
+ const { positional, flags } = parseArgs(args, { profile: "value" });
154
+ const runId = requireId(positional, "jobs cancel <run_id>");
155
+ const p = profileSuffix(flags.get("profile"));
156
+ try {
157
+ await runJobs(["jobs", "cancel-run", runId, "--no-wait"], {
158
+ ...spawnOpts(flags),
159
+ timeoutHelp: [
160
+ "The cancel may have applied despite the timeout — check state:",
161
+ `databricks-axi jobs runs view ${runId}${p}`,
162
+ ],
163
+ });
164
+ }
165
+ catch (error) {
166
+ if (isAlreadyTerminated(error)) {
167
+ return {
168
+ run_id: runId,
169
+ status: "run already terminated (no-op)",
170
+ help: [`databricks-axi jobs runs view ${runId}${p}`],
171
+ };
172
+ }
173
+ throw error;
174
+ }
175
+ return {
176
+ run_id: runId,
177
+ status: "cancel requested",
178
+ help: [`databricks-axi jobs runs view ${runId}${p}`],
179
+ };
180
+ }
181
+ function isAlreadyTerminated(error) {
182
+ if (!(error instanceof AxiError)) {
183
+ return false;
184
+ }
185
+ return (error.code === "INVALID_STATE" ||
186
+ /cannot be canceled|already (terminated|completed)/i.test(error.message));
187
+ }
188
+ function taskType(task) {
189
+ if (task.notebook_task?.notebook_path) {
190
+ return `notebook: ${task.notebook_task.notebook_path}`;
191
+ }
192
+ if (task.spark_python_task?.python_file) {
193
+ return `python: ${task.spark_python_task.python_file}`;
194
+ }
195
+ const key = Object.keys(task).find((k) => k.endsWith("_task"));
196
+ return key ? key.replace(/_task$/, "") : "unknown";
197
+ }
198
+ function iso(ms) {
199
+ return typeof ms === "number" && ms > 0 ? new Date(ms).toISOString() : "";
200
+ }
201
+ function durationSeconds(item) {
202
+ const ms = item.run_duration ??
203
+ item.execution_duration ??
204
+ (item.end_time && item.start_time ? item.end_time - item.start_time : 0);
205
+ return Math.round(ms / 1000);
206
+ }
207
+ async function runsList(args) {
208
+ const { positional, flags } = parseArgs(args, LIST_FLAGS);
209
+ const limit = parseIntFlag(flags, "limit", 20);
210
+ const argv = ["jobs", "list-runs", "--limit", String(limit)];
211
+ let jobId;
212
+ if (positional.length > 0) {
213
+ jobId = requireId(positional, "jobs runs [job_id]");
214
+ argv.push("--job-id", jobId);
215
+ }
216
+ const parsed = await runJobs(argv, spawnOpts(flags));
217
+ const items = asList(parsed, "runs");
218
+ const runs = items;
219
+ const rows = typeof flags.get("fields") === "string"
220
+ ? renderRows(items, flags, [])
221
+ : runs.map((r) => ({
222
+ run_id: r.run_id,
223
+ state: compactState(r),
224
+ start_time: iso(r.start_time),
225
+ duration_s: durationSeconds(r),
226
+ }));
227
+ const p = profileSuffix(flags.get("profile"));
228
+ if (rows.length === 0) {
229
+ return {
230
+ runs: [],
231
+ status: "no runs found",
232
+ help: [`databricks-axi jobs run <job_id>${p}`],
233
+ };
234
+ }
235
+ const help = [`databricks-axi jobs runs view <run_id>${p}`];
236
+ const firstFailed = runs.find(isFailed);
237
+ if (firstFailed) {
238
+ help.unshift(`databricks-axi jobs logs ${firstFailed.run_id}${p}`);
239
+ }
240
+ const out = { runs: rows, count: rows.length };
241
+ if (rows.length >= limit) {
242
+ out.has_more = true;
243
+ help.unshift(`databricks-axi jobs runs${jobId ? ` ${jobId}` : ""} --limit ${limit * 2}${p}`);
244
+ }
245
+ out.help = help;
246
+ return out;
247
+ }
248
+ async function runsView(args) {
249
+ const { positional, flags } = parseArgs(args, { profile: "value" });
250
+ const runId = requireId(positional, "jobs runs view <run_id>");
251
+ const runObj = (await runJobsObject(["jobs", "get-run", runId], spawnOpts(flags)));
252
+ const state = compactState(runObj);
253
+ const p = profileSuffix(flags.get("profile"));
254
+ return {
255
+ run_id: runObj.run_id,
256
+ job_id: runObj.job_id,
257
+ state,
258
+ start_time: iso(runObj.start_time),
259
+ duration_s: durationSeconds(runObj),
260
+ tasks: (runObj.tasks ?? []).map((task) => ({
261
+ task_key: task.task_key,
262
+ state: compactState(task),
263
+ duration_s: durationSeconds(task),
264
+ })),
265
+ help: isFailed(runObj)
266
+ ? [`databricks-axi jobs logs ${runId}${p}`]
267
+ : [`databricks-axi jobs runs ${runObj.job_id ?? ""}`.trim() + p],
268
+ };
269
+ }
270
+ const LOG_TAIL_LINES = 50;
271
+ async function jobsLogs(args) {
272
+ const { positional, flags } = parseArgs(args, {
273
+ profile: "value",
274
+ full: "boolean",
275
+ });
276
+ const runId = requireId(positional, "jobs logs <run_id> [--full]");
277
+ const full = flags.get("full") === true;
278
+ const opts = spawnOpts(flags);
279
+ const p = profileSuffix(flags.get("profile"));
280
+ const runObj = (await runJobsObject(["jobs", "get-run", runId], opts));
281
+ const tasks = runObj.tasks ?? [];
282
+ if (tasks.length === 0) {
283
+ return {
284
+ run_id: runObj.run_id,
285
+ state: compactState(runObj),
286
+ status: "run has no tasks (no output to fetch)",
287
+ help: [`databricks-axi jobs runs view ${runId}${p}`],
288
+ };
289
+ }
290
+ // ponytail: sequential fan-out — runs have a handful of tasks; parallelize
291
+ // only if logs latency ever actually hurts.
292
+ const entries = [];
293
+ for (const task of tasks) {
294
+ if (task.run_id == null) {
295
+ entries.push({
296
+ task: task.task_key,
297
+ state: compactState(task),
298
+ error: "task has no run_id; output unavailable",
299
+ });
300
+ continue;
301
+ }
302
+ try {
303
+ const output = (await runJobsObject(["jobs", "get-run-output", String(task.run_id)], opts));
304
+ entries.push(taskLogEntry(task, output, full));
305
+ }
306
+ catch (error) {
307
+ // One task's output failing shouldn't sink the rest of the fan-out.
308
+ entries.push({
309
+ task: task.task_key,
310
+ state: compactState(task),
311
+ error: `output fetch failed: ${error instanceof AxiError ? error.message : String(error)}`,
312
+ });
313
+ }
314
+ }
315
+ entries.sort((a, b) => Number(a.state === "SUCCESS") - Number(b.state === "SUCCESS"));
316
+ return {
317
+ run_id: runObj.run_id,
318
+ state: compactState(runObj),
319
+ tasks: entries,
320
+ help: [`databricks-axi jobs runs view ${runId}${p}`],
321
+ };
322
+ }
323
+ function taskLogEntry(task, output, full) {
324
+ const entry = {
325
+ task: task.task_key,
326
+ state: compactState(task),
327
+ };
328
+ let traceClipped = false;
329
+ if (output.error) {
330
+ entry.error = output.error;
331
+ }
332
+ if (output.error_trace) {
333
+ if (full) {
334
+ entry.error_trace = output.error_trace;
335
+ }
336
+ else {
337
+ const t = tail(output.error_trace, LOG_TAIL_LINES);
338
+ entry.error_trace = t.text;
339
+ traceClipped = t.truncated;
340
+ }
341
+ }
342
+ const text = output.notebook_output?.result || output.logs || "";
343
+ if (text) {
344
+ if (full) {
345
+ entry.output = text;
346
+ }
347
+ else {
348
+ const t = tail(text, LOG_TAIL_LINES);
349
+ entry.output = t.text;
350
+ if (t.truncated) {
351
+ entry.truncated = `showing last ${LOG_TAIL_LINES} of ${t.total} lines — rerun with --full`;
352
+ }
353
+ }
354
+ }
355
+ if (traceClipped && !entry.truncated) {
356
+ entry.truncated = `error_trace clipped to last ${LOG_TAIL_LINES} lines — rerun with --full`;
357
+ }
358
+ return entry;
359
+ }
360
+ function tail(text, maxLines) {
361
+ const lines = text.split("\n");
362
+ if (lines.length <= maxLines) {
363
+ return { text, truncated: false, total: lines.length };
364
+ }
365
+ return {
366
+ text: lines.slice(-maxLines).join("\n"),
367
+ truncated: true,
368
+ total: lines.length,
369
+ };
370
+ }
371
+ /** runDatabricks, with jobs-flavored suggestions folded into NOT_FOUND. */
372
+ async function runJobs(args, opts) {
373
+ try {
374
+ return await runDatabricks(args, opts);
375
+ }
376
+ catch (error) {
377
+ if (error instanceof AxiError &&
378
+ error.code === "NOT_FOUND" &&
379
+ error.suggestions.length === 0) {
380
+ const p = profileSuffix(opts.profile);
381
+ throw new AxiError(error.message, "NOT_FOUND", [
382
+ `databricks-axi jobs list${p}`,
383
+ `databricks-axi jobs runs${p}`,
384
+ ]);
385
+ }
386
+ throw error;
387
+ }
388
+ }
389
+ /** runJobs for endpoints whose result gets dereferenced — empty stdout
390
+ * (null) becomes a structured UPSTREAM_ERROR instead of a TypeError. */
391
+ async function runJobsObject(args, opts) {
392
+ return assertObject(await runJobs(args, opts), `databricks ${args.slice(0, 2).join(" ")}`);
393
+ }
394
+ //# sourceMappingURL=jobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../../src/commands/jobs.ts"],"names":[],"mappings":"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"}