import type { ToolDef } from "@fabric-harness/sdk"; import { type DatabricksCommandRunner } from "./app-deployment.js"; import { type DatabricksManagedResourceStore } from "./managed-resource.js"; export interface DatabricksAssetBundleOptions { /** Directory containing the checked-in bundle's `databricks.yml`. */ bundleDir: string; /** * Logical bundle name from the named `assetBundles` map; scopes the managed-resource identity so * lifecycles sharing one durable store never overwrite each other's records. */ instanceName?: string; /** Bundle target (dev/prod) passed through to the Databricks CLI. */ target?: string; /** Databricks CLI profile. */ profile?: string; /** Databricks CLI executable; defaults to `databricks`. */ executable?: string; env?: NodeJS.ProcessEnv; /** Injectable command boundary for tests and managed runners. */ run?: DatabricksCommandRunner; /** Fingerprint manifest; defaults to an in-memory store. */ store?: DatabricksManagedResourceStore; /** Label recorded as `createdBy`; never a token. */ principalLabel?: string; } /** Structured handoff from bounded bundle submission to Jobs/Lakeflow polling tools. */ export interface DatabricksAssetBundleRunResult { submitted: true; resourceKey: string; runKind?: "job" | "pipeline"; /** Jobs run id, directly accepted by the Databricks jobs status/output tools. */ runId?: number; /** Lakeflow pipeline id, paired with `updateId` for pipeline status polling. */ pipelineId?: string; /** Lakeflow update id, paired with `pipelineId` for pipeline status polling. */ updateId?: string; runUrl?: string; output: string; } /** * Governed lifecycle for a checked-in Databricks Asset Bundle (DAB). * * Harness does not generate bundle YAML — it makes validate/deploy/run/destroy of an * existing bundle a fingerprinted, approval-gated operation: * * - `fingerprint()` hashes the bundle source tree (sorted relative paths + content), * excluding `.databricks/` CLI state, `node_modules/`, and `dist/`. * - `deploy()` validates, deploys, then upserts the managed-resource record. When the * caller passes `expectedFingerprint` and a record exists with a different fingerprint, * deploy fails with `DatabricksManagedResourceConflictError` (optimistic concurrency so * one agent cannot stomp a bundle recorded from another tree). * - `run()` submits a run of a bundle-defined job/pipeline by its resource key without * waiting (`--no-wait`), so bundles deployed outside Harness (e.g. by CI) stay runnable; * the approval gate is the governance boundary, not the managed-resource record. * - `destroy()` requires the managed record (`DatabricksUnmanagedResourceError` otherwise), * refuses to destroy when the current tree fingerprint differs from the recorded one * unless `force` is set, and deletes the record after a successful teardown. */ export declare class DatabricksAssetBundleLifecycle { /** Resolved bundle directory; also the governed resource identity on the tools. */ readonly bundleDir: string; /** Logical name of this bundle within a named `assetBundles` map; unset in the single-bundle form. */ readonly instanceName?: string; private readonly target?; private readonly profile?; private readonly executable; private readonly env; private readonly commandRunner; private readonly store; private readonly principalLabel; private bundleName; constructor(options: DatabricksAssetBundleOptions); /** Run `databricks bundle validate` without mutating the workspace. */ validate(): Promise<{ valid: true; output: string; }>; /** Deterministic sha256 over the sorted bundle source tree (path + content). */ fingerprint(): Promise; /** Validate, deploy, and record the source fingerprint in the managed-resource store. */ deploy(options?: { expectedFingerprint?: string; }): Promise<{ deployed: true; fingerprint: string; output: string; }>; /** * Submit a run of a bundle-defined job/pipeline by its `databricks.yml` resource key. * Always passes `--no-wait` — waiting inside a tool call would violate finite-agent * boundedness, so run status must be polled through the bounded jobs/lakeflow status * tools. No managed-resource record is required: bundles deployed outside Harness * (e.g. by CI) stay runnable, and the CLI fails cleanly against an undeployed bundle. */ run(options: { key: string; restart?: boolean; }): Promise; /** Destroy a Harness-recorded bundle deployment and delete its managed record. */ destroy(options?: { force?: boolean; }): Promise<{ destroyed: true; output: string; }>; /** * Bundle `name:` parsed from `databricks.yml`, falling back to the directory basename. Named * bundles append `#instanceName` (and `#target` when set) so two lifecycles over the same manifest * cannot collide in a shared managed-resource store; the single-bundle form keeps the bare name so * existing records stay addressable. */ private resourceId; private requireManifest; private targetArgs; private profileArgs; } export declare function databricksAssetBundleLifecycle(options: DatabricksAssetBundleOptions): DatabricksAssetBundleLifecycle; /** Several checked-in bundles keyed by logical name; the key becomes the lifecycle's `instanceName`. */ export type DatabricksAssetBundleMapOptions = Record>; /** * Discriminates the single-bundle form from the named-bundle map. A map key literally called * `bundleDir` still selects map mode because its value is an entry object, not a string. */ export declare function isDatabricksAssetBundleEntry(value: unknown): value is { bundleDir: string; } | DatabricksAssetBundleLifecycle; /** * Reject a named-bundle container that is not a plain object. Arrays are rejected too (isPlainObject * excludes them): from untyped or parsed config they would otherwise enumerate as bundles named * "0", "1", … Shared with `databricks()` so the config boundary and this helper report one message. * Only the container is checked, so the assertion says nothing about the entries — each one is * validated during enumeration in `databricksAssetBundleLifecycles`. */ export declare function requireDatabricksAssetBundleMap(value: unknown): asserts value is Record; /** * Build one lifecycle per named bundle. Names are validated (they reach the model as tool input and * the managed-resource store as ids) and sorted, so tool enums and dispatch stay deterministic. * `defaults` are applied under each entry, letting a caller set one `principalLabel` for every bundle. */ export declare function databricksAssetBundleLifecycles(options: DatabricksAssetBundleMapOptions, defaults?: Omit): Map; /** * Model-facing tools for the governed bundle lifecycle. Write tools are approval-gated * by the `databricks()` bundle like every other authoring surface. * * A single bundle keeps bundle-free tool schemas; a named map adds a required `bundle` selector to * every schema (even with one entry, so the schema and its approval digests stay stable when a second * bundle is added) and governs only the bundle the call actually names. */ export declare function databricksAssetBundleTools(options: DatabricksAssetBundleOptions | DatabricksAssetBundleLifecycle | DatabricksAssetBundleMapOptions | Map): ToolDef[]; //# sourceMappingURL=asset-bundles.d.ts.map