@duckcodeailabs/dql-cli 1.6.11 → 1.6.13

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.
Files changed (43) hide show
  1. package/dist/assets/dql-notebook/assets/index-osG-H64_.js +3835 -0
  2. package/dist/assets/dql-notebook/index.html +1 -1
  3. package/dist/llm/analytics-tools.d.ts +7 -0
  4. package/dist/llm/analytics-tools.d.ts.map +1 -0
  5. package/dist/llm/analytics-tools.js +179 -0
  6. package/dist/llm/analytics-tools.js.map +1 -0
  7. package/dist/llm/index.d.ts.map +1 -1
  8. package/dist/llm/index.js +3 -1
  9. package/dist/llm/index.js.map +1 -1
  10. package/dist/llm/mcp-config.d.ts +43 -0
  11. package/dist/llm/mcp-config.d.ts.map +1 -0
  12. package/dist/llm/mcp-config.js +327 -0
  13. package/dist/llm/mcp-config.js.map +1 -0
  14. package/dist/llm/providers/claude-agent-sdk.d.ts.map +1 -1
  15. package/dist/llm/providers/claude-agent-sdk.js +2 -1
  16. package/dist/llm/providers/claude-agent-sdk.js.map +1 -1
  17. package/dist/llm/providers/claude-code.js +1 -0
  18. package/dist/llm/providers/claude-code.js.map +1 -1
  19. package/dist/llm/providers/dql-agent-provider.d.ts +1 -1
  20. package/dist/llm/providers/dql-agent-provider.d.ts.map +1 -1
  21. package/dist/llm/providers/dql-agent-provider.js +10 -1
  22. package/dist/llm/providers/dql-agent-provider.js.map +1 -1
  23. package/dist/llm/providers/native-sdk-provider.d.ts +4 -0
  24. package/dist/llm/providers/native-sdk-provider.d.ts.map +1 -0
  25. package/dist/llm/providers/native-sdk-provider.js +319 -0
  26. package/dist/llm/providers/native-sdk-provider.js.map +1 -0
  27. package/dist/llm/types.d.ts +2 -1
  28. package/dist/llm/types.d.ts.map +1 -1
  29. package/dist/local-runtime.d.ts +13 -0
  30. package/dist/local-runtime.d.ts.map +1 -1
  31. package/dist/local-runtime.js +337 -96
  32. package/dist/local-runtime.js.map +1 -1
  33. package/dist/package.json +13 -11
  34. package/dist/settings/provider-settings.d.ts +2 -0
  35. package/dist/settings/provider-settings.d.ts.map +1 -1
  36. package/dist/settings/provider-settings.js +49 -10
  37. package/dist/settings/provider-settings.js.map +1 -1
  38. package/package.json +14 -12
  39. package/dist/assets/dql-notebook/assets/index-BbGJ8gZk.js +0 -3639
  40. package/dist/assets/dql-notebook/assets/index-C4oZK5xm.js +0 -3612
  41. package/dist/assets/dql-notebook/assets/index-CEMXuPm0.js +0 -3802
  42. package/dist/assets/dql-notebook/assets/index-CIMLd3Cb.js +0 -3289
  43. package/dist/assets/dql-notebook/assets/index-DISMWw19.js +0 -3780
@@ -1,5 +1,6 @@
1
1
  import { QueryExecutor, type ConnectionConfig, type DatabaseConnector } from '@duckcodeailabs/dql-connectors';
2
2
  import { type SemanticLayer, type SemanticLayerProviderConfig } from '@duckcodeailabs/dql-core';
3
+ import type { ProviderId } from './llm/types.js';
3
4
  import { type AgentSchemaTable } from '@duckcodeailabs/dql-agent';
4
5
  export interface ProjectConfig {
5
6
  project?: string;
@@ -31,6 +32,16 @@ export interface DbtProfileConnectionCandidate {
31
32
  missingFields: string[];
32
33
  warnings: string[];
33
34
  }
35
+ export interface ConnectorInstallStatus {
36
+ driver: 'duckdb' | 'snowflake' | 'databricks';
37
+ label: string;
38
+ packageName?: string;
39
+ packageSpec?: string;
40
+ installed: boolean;
41
+ builtIn: boolean;
42
+ installPath: string;
43
+ installCommand?: string;
44
+ }
34
45
  export interface LocalServerOptions {
35
46
  rootDir: string;
36
47
  projectRoot?: string;
@@ -53,9 +64,11 @@ export interface ConnectionTestResult {
53
64
  details?: Record<string, unknown>;
54
65
  }
55
66
  export declare function validateConnectionForTest(connector: DatabaseConnector, connection: ConnectionConfig): Promise<ConnectionTestResult>;
67
+ export declare function resolveDefaultLLMProvider(projectRoot: string): ProviderId | null;
56
68
  export declare function serializeJSON(value: unknown): string;
57
69
  export declare function findProjectRoot(startDir: string): string;
58
70
  export declare function loadProjectConfig(projectRoot: string): ProjectConfig;
71
+ export declare function getConnectorInstallStatuses(projectRoot: string): ConnectorInstallStatus[];
59
72
  export declare function prepareLocalExecution(sql: string, connection: ConnectionConfig, projectRoot: string, projectConfig: ProjectConfig): {
60
73
  sql: string;
61
74
  connection: ConnectionConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"local-runtime.d.ts","sourceRoot":"","sources":["../src/local-runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local-runtime.d.ts","sourceRoot":"","sources":["../src/local-runtime.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,20 @@
1
- import { execSync } from 'node:child_process';
1
+ import { execFileSync, execSync } from 'node:child_process';
2
2
  import { createServer } from 'node:http';
3
3
  import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, watch, writeFileSync } from 'node:fs';
4
+ import { createRequire } from 'node:module';
4
5
  import { homedir } from 'node:os';
5
6
  import { dirname, extname, join, normalize, relative, resolve } from 'node:path';
7
+ import Anthropic from '@anthropic-ai/sdk';
8
+ import OpenAI from 'openai';
6
9
  import { buildExecutionPlan, createWelcomeNotebook, deserializeNotebook, getConnectorFormSchemas, hasSemanticRefs, resolveSemanticRefs, } from '@duckcodeailabs/dql-notebook';
7
10
  import { loadSemanticLayerFromDir, resolveSemanticLayerAsync, getDialect, Parser, buildLineageGraph, buildManifest, findAppDocuments, findDashboardsForApp, isBlockIdRef, loadAppDocument, loadDashboardDocument, analyzeImpact, buildTrustChain, detectDomainFlows, getDomainTrustOverview, queryLineage, queryCompleteLineagePaths, LineageGraph, canonicalize, canonicalizeNotebook, diffDQL, diffNotebook, } from '@duckcodeailabs/dql-core';
8
11
  import { load as loadYaml } from 'js-yaml';
9
12
  import { listBlockTemplates } from './block-templates.js';
10
13
  import { getRunner as getLLMRunner } from './llm/index.js';
14
+ import { listRemoteMcpSettings, saveRemoteMcpSettings } from './llm/mcp-config.js';
11
15
  import { ClaudeProvider, GeminiProvider, MemoryStore, OllamaProvider, OpenAIProvider, buildLocalContextPack, defaultMemoryPath, ensureDefaultMemoryFiles, ensureMetadataCatalogFresh, recordRuntimeSchemaSnapshot, } from '@duckcodeailabs/dql-agent';
12
16
  import { handleAppsApi } from './apps-api.js';
13
- import { getEffectiveProviderConfig, listProviderSettings, saveProviderSettings, } from './settings/provider-settings.js';
17
+ import { getActiveProvider, getEffectiveProviderConfig, listProviderSettings, saveProviderSettings, } from './settings/provider-settings.js';
14
18
  import { DQLAccessDeniedError, activePersonaAppId, assertAppAccess, loadRuntimeApp, runtimeVariables, } from './governance-runtime.js';
15
19
  import { LocalAppStorage, defaultLocalAppsDbPath } from '@duckcodeailabs/dql-project';
16
20
  import { Certifier } from '@duckcodeailabs/dql-governance';
@@ -606,6 +610,24 @@ export async function startLocalServer(opts) {
606
610
  }
607
611
  return;
608
612
  }
613
+ if (req.method === 'GET' && path === '/api/settings/mcp') {
614
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
615
+ res.end(serializeJSON({ settings: listRemoteMcpSettings(projectRoot) }));
616
+ return;
617
+ }
618
+ if (req.method === 'POST' && path === '/api/settings/mcp') {
619
+ try {
620
+ const body = await readJSON(req);
621
+ const settings = saveRemoteMcpSettings(projectRoot, { entries: body?.entries });
622
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
623
+ res.end(serializeJSON({ ok: true, settings }));
624
+ }
625
+ catch (error) {
626
+ res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
627
+ res.end(serializeJSON({ ok: false, error: error instanceof Error ? error.message : String(error) }));
628
+ }
629
+ return;
630
+ }
609
631
  if (req.method === 'GET' && path === '/api/agent/memory') {
610
632
  const memory = new MemoryStore(defaultMemoryPath(projectRoot));
611
633
  try {
@@ -1907,8 +1929,32 @@ export async function startLocalServer(opts) {
1907
1929
  ?? Object.keys(connections)[0]
1908
1930
  ?? 'default';
1909
1931
  const dbtProfiles = discoverDbtProfileConnections(projectRoot, cfg);
1932
+ const connectorStatus = getConnectorInstallStatuses(projectRoot);
1910
1933
  res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
1911
- res.end(serializeJSON({ default: defaultKey, connections, dbtProfiles }));
1934
+ res.end(serializeJSON({ default: defaultKey, connections, dbtProfiles, connectorStatus }));
1935
+ return;
1936
+ }
1937
+ if (req.method === 'POST' && path === '/api/connectors/install') {
1938
+ try {
1939
+ const body = await readJSON(req);
1940
+ const driver = typeof body.driver === 'string' ? body.driver : '';
1941
+ const status = installConnectorPackage(projectRoot, driver);
1942
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
1943
+ res.end(serializeJSON({
1944
+ ok: true,
1945
+ status,
1946
+ connectorStatus: getConnectorInstallStatuses(projectRoot),
1947
+ }));
1948
+ }
1949
+ catch (error) {
1950
+ const message = error instanceof Error ? error.message : String(error);
1951
+ res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
1952
+ res.end(serializeJSON({
1953
+ ok: false,
1954
+ error: message,
1955
+ connectorStatus: getConnectorInstallStatuses(projectRoot),
1956
+ }));
1957
+ }
1912
1958
  return;
1913
1959
  }
1914
1960
  // Save/update connections
@@ -3465,16 +3511,23 @@ function normalizeQueryResult(result, semanticRefs) {
3465
3511
  };
3466
3512
  }
3467
3513
  function isLLMProviderId(value) {
3468
- return value === 'claude-agent-sdk'
3514
+ return value === 'anthropic'
3515
+ || value === 'claude-agent-sdk'
3469
3516
  || value === 'claude-code'
3470
3517
  || value === 'openai'
3471
3518
  || value === 'gemini'
3472
3519
  || value === 'ollama'
3473
3520
  || value === 'custom-openai';
3474
3521
  }
3475
- function resolveDefaultLLMProvider(projectRoot) {
3522
+ export function resolveDefaultLLMProvider(projectRoot) {
3476
3523
  const settings = listProviderSettings(projectRoot);
3477
- const preferred = ['openai', 'gemini', 'ollama', 'custom-openai'];
3524
+ const activeProvider = getActiveProvider(projectRoot);
3525
+ if (activeProvider) {
3526
+ const active = settings.find((item) => item.id === activeProvider);
3527
+ if (active?.enabled)
3528
+ return activeProvider;
3529
+ }
3530
+ const preferred = ['openai', 'gemini', 'anthropic', 'custom-openai', 'ollama'];
3478
3531
  for (const id of preferred) {
3479
3532
  const provider = settings.find((item) => item.id === id);
3480
3533
  if (provider?.enabled && provider.hasApiKey)
@@ -3608,6 +3661,90 @@ function getProjectConnectionsForApi(config) {
3608
3661
  }
3609
3662
  return connections;
3610
3663
  }
3664
+ const CONNECTOR_INSTALLS = {
3665
+ duckdb: {
3666
+ driver: 'duckdb',
3667
+ label: 'DuckDB',
3668
+ packageName: 'duckdb',
3669
+ packageSpec: 'duckdb@^1.1.0',
3670
+ builtIn: false,
3671
+ },
3672
+ snowflake: {
3673
+ driver: 'snowflake',
3674
+ label: 'Snowflake',
3675
+ packageName: 'snowflake-sdk',
3676
+ packageSpec: 'snowflake-sdk@^1.12.0',
3677
+ builtIn: false,
3678
+ },
3679
+ databricks: {
3680
+ driver: 'databricks',
3681
+ label: 'Databricks',
3682
+ builtIn: true,
3683
+ },
3684
+ };
3685
+ function connectorInstallRoot(projectRoot) {
3686
+ return join(projectRoot, '.dql', 'connectors');
3687
+ }
3688
+ function connectorModuleSearchPaths(projectRoot) {
3689
+ return [connectorInstallRoot(projectRoot), projectRoot];
3690
+ }
3691
+ function connectorInstallCommand(projectRoot, packageSpec) {
3692
+ return `npm install --prefix ${connectorInstallRoot(projectRoot)} ${packageSpec}`;
3693
+ }
3694
+ function isConnectorPackageInstalled(projectRoot, packageName) {
3695
+ for (const basePath of connectorModuleSearchPaths(projectRoot)) {
3696
+ try {
3697
+ const req = createRequire(join(basePath, 'package.json'));
3698
+ req.resolve(packageName);
3699
+ return true;
3700
+ }
3701
+ catch {
3702
+ // Try the next supported location.
3703
+ }
3704
+ }
3705
+ return false;
3706
+ }
3707
+ export function getConnectorInstallStatuses(projectRoot) {
3708
+ return Object.values(CONNECTOR_INSTALLS).map((definition) => {
3709
+ const installPath = connectorInstallRoot(projectRoot);
3710
+ const installed = definition.builtIn || (definition.packageName
3711
+ ? isConnectorPackageInstalled(projectRoot, definition.packageName)
3712
+ : true);
3713
+ return {
3714
+ ...definition,
3715
+ installed,
3716
+ installPath,
3717
+ installCommand: definition.packageSpec
3718
+ ? connectorInstallCommand(projectRoot, definition.packageSpec)
3719
+ : undefined,
3720
+ };
3721
+ });
3722
+ }
3723
+ function installConnectorPackage(projectRoot, driver) {
3724
+ const definition = CONNECTOR_INSTALLS[driver];
3725
+ if (!definition) {
3726
+ throw new Error(`Unknown connector "${driver}".`);
3727
+ }
3728
+ if (definition.builtIn || !definition.packageSpec) {
3729
+ return getConnectorInstallStatuses(projectRoot).find((status) => status.driver === definition.driver);
3730
+ }
3731
+ const installRoot = connectorInstallRoot(projectRoot);
3732
+ mkdirSync(installRoot, { recursive: true });
3733
+ const packageJsonPath = join(installRoot, 'package.json');
3734
+ if (!existsSync(packageJsonPath)) {
3735
+ writeFileSync(packageJsonPath, JSON.stringify({
3736
+ private: true,
3737
+ description: 'Project-local DQL connector packages',
3738
+ }, null, 2) + '\n', 'utf-8');
3739
+ }
3740
+ execFileSync('npm', ['install', '--prefix', installRoot, '--no-audit', '--no-fund', definition.packageSpec], {
3741
+ cwd: projectRoot,
3742
+ encoding: 'utf-8',
3743
+ stdio: 'pipe',
3744
+ timeout: 10 * 60 * 1000,
3745
+ });
3746
+ return getConnectorInstallStatuses(projectRoot).find((status) => status.driver === definition.driver);
3747
+ }
3611
3748
  function getStoredConnections(raw) {
3612
3749
  const value = raw.connections;
3613
3750
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
@@ -3912,6 +4049,9 @@ export function normalizeProjectConnection(connection, projectRoot) {
3912
4049
  if ((normalized.driver === 'file' || normalized.driver === 'duckdb') && normalized.filepath && normalized.filepath !== ':memory:' && !isAbsoluteLikePath(normalized.filepath)) {
3913
4050
  normalized.filepath = resolve(projectRoot, normalized.filepath);
3914
4051
  }
4052
+ if (normalized.driver === 'file' || normalized.driver === 'duckdb' || normalized.driver === 'snowflake') {
4053
+ normalized.moduleSearchPaths = connectorModuleSearchPaths(projectRoot);
4054
+ }
3915
4055
  if (normalized.driver === 'sqlite' && normalized.database && normalized.database !== ':memory:' && !isAbsoluteLikePath(normalized.database)) {
3916
4056
  normalized.database = resolve(projectRoot, normalized.database);
3917
4057
  }
@@ -4931,9 +5071,11 @@ async function buildBlockStudioAiAssistSummary(projectRoot, action, candidate, v
4931
5071
  }
4932
5072
  async function createBlockStudioAssistProvider(projectRoot, requestedProvider) {
4933
5073
  const settings = listProviderSettings(projectRoot);
5074
+ const activeProvider = getActiveProvider(projectRoot);
4934
5075
  const selected = requestedProvider
4935
5076
  ? settings.find((provider) => provider.id === requestedProvider && provider.enabled && provider.hasApiKey)
4936
- : settings.find((provider) => provider.enabled && provider.hasApiKey);
5077
+ : settings.find((provider) => provider.id === activeProvider && provider.enabled)
5078
+ ?? settings.find((provider) => provider.enabled && provider.hasApiKey);
4937
5079
  if (!selected)
4938
5080
  return null;
4939
5081
  const config = getEffectiveProviderConfig(projectRoot, selected.id);
@@ -5681,45 +5823,7 @@ function mapDbtProfileOutput(output) {
5681
5823
  result.envRefs.forEach((ref) => envRefs.add(ref));
5682
5824
  return result.value;
5683
5825
  };
5684
- const port = numberValue(output, 'port');
5685
- const sslRaw = read('ssl', 'sslmode');
5686
- const ssl = sslRaw === undefined
5687
- ? undefined
5688
- : !['false', '0', 'disable', 'disabled', 'off'].includes(sslRaw.toLowerCase());
5689
5826
  switch (adapter) {
5690
- case 'postgres':
5691
- case 'postgresql':
5692
- return {
5693
- adapter,
5694
- connection: compactConnection({
5695
- driver: 'postgresql',
5696
- host: read('host'),
5697
- port,
5698
- database: read('dbname', 'database'),
5699
- schema: read('schema'),
5700
- username: read('user', 'username'),
5701
- password: read('password', 'pass'),
5702
- ssl,
5703
- }),
5704
- envRefs: [...envRefs],
5705
- warnings,
5706
- };
5707
- case 'redshift':
5708
- return {
5709
- adapter,
5710
- connection: compactConnection({
5711
- driver: 'redshift',
5712
- host: read('host'),
5713
- port: port ?? 5439,
5714
- database: read('dbname', 'database'),
5715
- schema: read('schema'),
5716
- username: read('user', 'username'),
5717
- password: read('password', 'pass'),
5718
- ssl,
5719
- }),
5720
- envRefs: [...envRefs],
5721
- warnings,
5722
- };
5723
5827
  case 'snowflake': {
5724
5828
  const privateKeyPath = read('private_key_path', 'privateKeyPath');
5725
5829
  const privateKey = read('private_key', 'privateKey');
@@ -5729,9 +5833,19 @@ function mapDbtProfileOutput(output) {
5729
5833
  ? 'key_pair'
5730
5834
  : normalizedAuthenticator === 'externalbrowser'
5731
5835
  ? 'external_browser'
5732
- : normalizedAuthenticator === 'oauth' || normalizedAuthenticator === 'programmaticaccesstoken'
5733
- ? 'oauth'
5734
- : 'password';
5836
+ : normalizedAuthenticator === 'usernamepasswordmfa'
5837
+ ? 'mfa'
5838
+ : normalizedAuthenticator === 'oauthauthorizationcode'
5839
+ ? 'oauth_authorization_code'
5840
+ : normalizedAuthenticator === 'oauthclientcredentials'
5841
+ ? 'oauth_client_credentials'
5842
+ : normalizedAuthenticator === 'programmaticaccesstoken'
5843
+ ? 'programmatic_access_token'
5844
+ : normalizedAuthenticator === 'workloadidentity'
5845
+ ? 'workload_identity'
5846
+ : normalizedAuthenticator === 'oauth'
5847
+ ? 'oauth'
5848
+ : 'password';
5735
5849
  return {
5736
5850
  adapter,
5737
5851
  connection: compactConnection({
@@ -5748,22 +5862,34 @@ function mapDbtProfileOutput(output) {
5748
5862
  privateKeyPassphrase: read('private_key_passphrase', 'privateKeyPassphrase'),
5749
5863
  authenticator,
5750
5864
  authMethod,
5751
- }),
5752
- envRefs: [...envRefs],
5753
- warnings,
5754
- };
5755
- }
5756
- case 'bigquery': {
5757
- const keyFilename = read('keyfile', 'keyFilename');
5758
- return {
5759
- adapter,
5760
- connection: compactConnection({
5761
- driver: 'bigquery',
5762
- projectId: read('project', 'projectId'),
5763
- schema: read('dataset', 'schema'),
5764
- location: read('location'),
5765
- keyFilename,
5766
- authMethod: keyFilename ? 'service_account_key_file' : 'application_default',
5865
+ token: read('token'),
5866
+ accessUrl: read('access_url', 'accessUrl'),
5867
+ application: read('application'),
5868
+ browserActionTimeout: readNumber(output, 'browser_action_timeout', 'browserActionTimeout'),
5869
+ clientRequestMFAToken: readBoolean(output, 'client_request_mfa_token', 'clientRequestMFAToken'),
5870
+ clientStoreTemporaryCredential: readBoolean(output, 'client_store_temporary_credential', 'clientStoreTemporaryCredential'),
5871
+ clientSessionKeepAlive: readBoolean(output, 'client_session_keep_alive', 'clientSessionKeepAlive'),
5872
+ clientSessionKeepAliveHeartbeatFrequency: readNumber(output, 'client_session_keep_alive_heartbeat_frequency', 'clientSessionKeepAliveHeartbeatFrequency'),
5873
+ credentialCacheDir: read('credential_cache_dir', 'credentialCacheDir'),
5874
+ keepAlive: readBoolean(output, 'keep_alive', 'keepAlive'),
5875
+ noProxy: read('no_proxy', 'noProxy'),
5876
+ oauthAuthorizationUrl: read('oauth_authorization_url', 'oauthAuthorizationUrl'),
5877
+ oauthClientId: read('oauth_client_id', 'oauthClientId'),
5878
+ oauthClientSecret: read('oauth_client_secret', 'oauthClientSecret'),
5879
+ oauthRedirectUri: read('oauth_redirect_uri', 'oauthRedirectUri'),
5880
+ oauthScope: read('oauth_scope', 'oauthScope'),
5881
+ oauthTokenRequestUrl: read('oauth_token_request_url', 'oauthTokenRequestUrl'),
5882
+ passcode: read('passcode'),
5883
+ passcodeInPassword: readBoolean(output, 'passcode_in_password', 'passcodeInPassword'),
5884
+ proxyHost: read('proxy_host', 'proxyHost'),
5885
+ proxyPassword: read('proxy_password', 'proxyPassword'),
5886
+ proxyPort: readNumber(output, 'proxy_port', 'proxyPort'),
5887
+ proxyProtocol: read('proxy_protocol', 'proxyProtocol'),
5888
+ proxyUser: read('proxy_user', 'proxyUser'),
5889
+ queryTag: read('query_tag', 'queryTag'),
5890
+ timeout: readNumber(output, 'timeout'),
5891
+ workloadIdentityProvider: read('workload_identity_provider', 'workloadIdentityProvider'),
5892
+ workloadIdentityAzureClientId: read('workload_identity_azure_client_id', 'workloadIdentityAzureClientId'),
5767
5893
  }),
5768
5894
  envRefs: [...envRefs],
5769
5895
  warnings,
@@ -5779,7 +5905,9 @@ function mapDbtProfileOutput(output) {
5779
5905
  envRefs: [...envRefs],
5780
5906
  warnings,
5781
5907
  };
5782
- case 'databricks':
5908
+ case 'databricks': {
5909
+ const databricksAuth = read('auth_type', 'auth_method', 'authMethod');
5910
+ const authMethod = databricksAuth?.toLowerCase().includes('oauth') ? 'oauth' : 'token';
5783
5911
  return {
5784
5912
  adapter,
5785
5913
  connection: compactConnection({
@@ -5791,15 +5919,44 @@ function mapDbtProfileOutput(output) {
5791
5919
  database: read('catalog', 'database'),
5792
5920
  schema: read('schema'),
5793
5921
  token: read('token'),
5794
- authMethod: 'token',
5922
+ authMethod,
5923
+ waitTimeout: read('wait_timeout', 'waitTimeout'),
5924
+ byteLimit: readNumber(output, 'byte_limit', 'byteLimit'),
5795
5925
  }),
5796
5926
  envRefs: [...envRefs],
5797
5927
  warnings,
5798
5928
  };
5929
+ }
5799
5930
  default:
5800
5931
  return null;
5801
5932
  }
5802
5933
  }
5934
+ function readBoolean(source, ...keys) {
5935
+ for (const key of keys) {
5936
+ const raw = source[key];
5937
+ if (typeof raw === 'boolean')
5938
+ return raw;
5939
+ if (raw === undefined || raw === null)
5940
+ continue;
5941
+ const value = String(raw).trim().toLowerCase();
5942
+ if (['true', '1', 'yes', 'y'].includes(value))
5943
+ return true;
5944
+ if (['false', '0', 'no', 'n'].includes(value))
5945
+ return false;
5946
+ }
5947
+ return undefined;
5948
+ }
5949
+ function readNumber(source, ...keys) {
5950
+ for (const key of keys) {
5951
+ const raw = source[key];
5952
+ if (raw === undefined || raw === null || raw === '')
5953
+ continue;
5954
+ const value = Number(raw);
5955
+ if (Number.isFinite(value))
5956
+ return value;
5957
+ }
5958
+ return undefined;
5959
+ }
5803
5960
  function text(source, ...keys) {
5804
5961
  for (const key of keys) {
5805
5962
  const raw = source[key];
@@ -5825,13 +5982,6 @@ function resolveDbtEnvVars(value) {
5825
5982
  });
5826
5983
  return { value: replaced, envRefs };
5827
5984
  }
5828
- function numberValue(source, key) {
5829
- const raw = source[key];
5830
- if (raw === undefined || raw === null || raw === '')
5831
- return undefined;
5832
- const value = Number(raw);
5833
- return Number.isFinite(value) ? value : undefined;
5834
- }
5835
5985
  function compactConnection(connection) {
5836
5986
  const compact = {};
5837
5987
  for (const [key, value] of Object.entries(connection)) {
@@ -5849,12 +5999,6 @@ function requiredConnectionFields(connection, envRefs) {
5849
5999
  missing.add(String(field));
5850
6000
  };
5851
6001
  switch (connection.driver) {
5852
- case 'postgresql':
5853
- case 'redshift':
5854
- needs('host');
5855
- needs('database');
5856
- needs('username');
5857
- break;
5858
6002
  case 'snowflake':
5859
6003
  needs('account');
5860
6004
  needs('warehouse');
@@ -5871,13 +6015,27 @@ function requiredConnectionFields(connection, envRefs) {
5871
6015
  missing.add('token');
5872
6016
  }
5873
6017
  }
6018
+ else if (connection.authMethod === 'programmatic_access_token') {
6019
+ if (!connection.token && !connection.password) {
6020
+ missing.add('token');
6021
+ }
6022
+ }
6023
+ else if (connection.authMethod === 'oauth_authorization_code') {
6024
+ needs('oauthClientId');
6025
+ needs('oauthClientSecret');
6026
+ }
6027
+ else if (connection.authMethod === 'oauth_client_credentials') {
6028
+ needs('oauthClientId');
6029
+ needs('oauthClientSecret');
6030
+ needs('oauthTokenRequestUrl');
6031
+ }
6032
+ else if (connection.authMethod === 'workload_identity') {
6033
+ needs('workloadIdentityProvider');
6034
+ }
5874
6035
  else if (connection.authMethod !== 'external_browser') {
5875
6036
  needs('password');
5876
6037
  }
5877
6038
  break;
5878
- case 'bigquery':
5879
- needs('projectId');
5880
- break;
5881
6039
  case 'duckdb':
5882
6040
  needs('filepath');
5883
6041
  break;
@@ -6497,11 +6655,17 @@ function isProviderSettingsId(value) {
6497
6655
  }
6498
6656
  async function testProviderConfig(projectRoot, id) {
6499
6657
  const config = getEffectiveProviderConfig(projectRoot, id);
6658
+ const label = providerSettingsLabel(id);
6659
+ const details = providerConfigDetails(id, config);
6660
+ if (!config.enabled) {
6661
+ return { ok: false, message: `${label} is disabled in Settings.` };
6662
+ }
6663
+ if (id === 'openai')
6664
+ return testOpenAIProviderConfig(config, label, details);
6665
+ if (id === 'anthropic')
6666
+ return testAnthropicProviderConfig(config, label, details);
6500
6667
  let provider;
6501
6668
  switch (id) {
6502
- case 'anthropic':
6503
- provider = new ClaudeProvider({ apiKey: config.apiKey, model: config.model });
6504
- break;
6505
6669
  case 'gemini':
6506
6670
  provider = new GeminiProvider({ apiKey: config.apiKey, model: config.model });
6507
6671
  break;
@@ -6509,20 +6673,97 @@ async function testProviderConfig(projectRoot, id) {
6509
6673
  provider = new OllamaProvider({ baseUrl: config.baseUrl, model: config.model });
6510
6674
  break;
6511
6675
  case 'custom-openai':
6512
- provider = new OpenAIProvider({ apiKey: config.apiKey, baseUrl: config.baseUrl, model: config.model, allowNoApiKey: true });
6513
- break;
6514
- case 'openai':
6515
6676
  default:
6516
- provider = new OpenAIProvider({ apiKey: config.apiKey, baseUrl: config.baseUrl, model: config.model });
6677
+ provider = new OpenAIProvider({ apiKey: config.apiKey, baseUrl: config.baseUrl, model: config.model, allowNoApiKey: true });
6517
6678
  break;
6518
6679
  }
6519
- const ok = await provider.available();
6520
- return {
6521
- ok,
6522
- message: ok
6523
- ? `${id} is configured.`
6524
- : `${id} is not configured or not reachable. Check API key, base URL, and local service state.`,
6525
- };
6680
+ const available = await provider.available().catch(() => false);
6681
+ if (!available) {
6682
+ return {
6683
+ ok: false,
6684
+ message: `${label} is not configured or reachable${details}. Check API key, base URL, and local service state.`,
6685
+ };
6686
+ }
6687
+ try {
6688
+ const text = await provider.generate([
6689
+ { role: 'user', content: 'Reply with exactly: OK' },
6690
+ ], { maxTokens: 8, temperature: 0 });
6691
+ return {
6692
+ ok: true,
6693
+ message: `${label} responded${details}: ${text.trim().slice(0, 80) || 'OK'}`,
6694
+ };
6695
+ }
6696
+ catch (error) {
6697
+ return {
6698
+ ok: false,
6699
+ message: `${label} is configured but the model call failed${details}: ${error instanceof Error ? error.message : String(error)}`,
6700
+ };
6701
+ }
6702
+ }
6703
+ async function testOpenAIProviderConfig(config, label, details) {
6704
+ if (!config.apiKey) {
6705
+ return { ok: false, message: `${label} is not configured${details}. Add an API key in Settings or OPENAI_API_KEY.` };
6706
+ }
6707
+ try {
6708
+ const client = new OpenAI({ apiKey: config.apiKey, baseURL: config.baseUrl });
6709
+ const response = await client.responses.create({
6710
+ model: config.model ?? 'gpt-5.5',
6711
+ input: 'Reply with exactly: OK',
6712
+ max_output_tokens: 16,
6713
+ });
6714
+ return {
6715
+ ok: true,
6716
+ message: `${label} SDK responded${details}: ${(response.output_text ?? 'OK').trim().slice(0, 80) || 'OK'}`,
6717
+ };
6718
+ }
6719
+ catch (error) {
6720
+ return {
6721
+ ok: false,
6722
+ message: `${label} SDK call failed${details}: ${error instanceof Error ? error.message : String(error)}`,
6723
+ };
6724
+ }
6725
+ }
6726
+ async function testAnthropicProviderConfig(config, label, details) {
6727
+ if (!config.apiKey) {
6728
+ return { ok: false, message: `${label} is not configured${details}. Add an API key in Settings or ANTHROPIC_API_KEY.` };
6729
+ }
6730
+ try {
6731
+ const client = new Anthropic({ apiKey: config.apiKey });
6732
+ const response = await client.messages.create({
6733
+ model: config.model ?? 'claude-opus-4-8',
6734
+ max_tokens: 16,
6735
+ temperature: 0,
6736
+ messages: [{ role: 'user', content: 'Reply with exactly: OK' }],
6737
+ });
6738
+ const text = response.content?.filter((block) => block.type === 'text').map((block) => block.text ?? '').join('') ?? '';
6739
+ return {
6740
+ ok: true,
6741
+ message: `${label} SDK responded${details}: ${text.trim().slice(0, 80) || 'OK'}`,
6742
+ };
6743
+ }
6744
+ catch (error) {
6745
+ return {
6746
+ ok: false,
6747
+ message: `${label} SDK call failed${details}: ${error instanceof Error ? error.message : String(error)}`,
6748
+ };
6749
+ }
6750
+ }
6751
+ function providerSettingsLabel(id) {
6752
+ switch (id) {
6753
+ case 'anthropic': return 'Anthropic Claude';
6754
+ case 'openai': return 'OpenAI';
6755
+ case 'gemini': return 'Gemini';
6756
+ case 'ollama': return 'Ollama';
6757
+ case 'custom-openai': return 'Custom OpenAI-compatible provider';
6758
+ }
6759
+ }
6760
+ function providerConfigDetails(id, config) {
6761
+ const parts = [
6762
+ config.model ? `model ${config.model}` : '',
6763
+ config.baseUrl ? `base URL ${config.baseUrl}` : '',
6764
+ id === 'ollama' ? 'local endpoint' : config.apiKey ? 'API key present' : 'API key missing',
6765
+ ].filter(Boolean);
6766
+ return parts.length ? ` (${parts.join(', ')})` : '';
6526
6767
  }
6527
6768
  function isAiPinRefreshDue(lastRefreshedAt) {
6528
6769
  if (!lastRefreshedAt)