yamchart 0.6.0 → 0.7.1
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/dist/{advisor-IJG6UFTJ.js → advisor-YW2EBXGR.js} +6 -6
- package/dist/chunk-IVD4OP3K.js +35 -0
- package/dist/chunk-IVD4OP3K.js.map +1 -0
- package/dist/{describe-HD2RJQX3.js → describe-ZM2JI2XS.js} +4 -4
- package/dist/{dev-LCYHM7UA.js → dev-CBUHSRXH.js} +2 -2
- package/dist/{dist-D5NLPC5X.js → dist-YTGUIBKG.js} +9 -2
- package/dist/dist-YTGUIBKG.js.map +1 -0
- package/dist/index.js +34 -7
- package/dist/index.js.map +1 -1
- package/dist/lineage-XSITWW2O.js +184 -0
- package/dist/lineage-XSITWW2O.js.map +1 -0
- package/dist/rewrite-database-FDJIXKZ2.js +12 -0
- package/dist/rewrite-database-FDJIXKZ2.js.map +1 -0
- package/dist/{sync-dbt-RKEHTN4P.js → sync-dbt-22QQKT3A.js} +26 -3
- package/dist/sync-dbt-22QQKT3A.js.map +1 -0
- package/dist/templates/default/docs/yamchart-reference.md +35 -2
- package/package.json +4 -4
- package/dist/dist-D5NLPC5X.js.map +0 -1
- package/dist/lineage-TX33DUDP.js +0 -81
- package/dist/lineage-TX33DUDP.js.map +0 -1
- package/dist/sync-dbt-RKEHTN4P.js.map +0 -1
- /package/dist/{advisor-IJG6UFTJ.js.map → advisor-YW2EBXGR.js.map} +0 -0
- /package/dist/{describe-HD2RJQX3.js.map → describe-ZM2JI2XS.js.map} +0 -0
- /package/dist/{dev-LCYHM7UA.js.map → dev-CBUHSRXH.js.map} +0 -0
|
@@ -139,7 +139,7 @@ async function buildContext(projectDir, options) {
|
|
|
139
139
|
};
|
|
140
140
|
if (dbtPath) {
|
|
141
141
|
try {
|
|
142
|
-
const { detectConventions, listDbtModels } = await import("./dist-
|
|
142
|
+
const { detectConventions, listDbtModels } = await import("./dist-YTGUIBKG.js");
|
|
143
143
|
const dbtProjectYml = await readFile(join(dbtPath, "dbt_project.yml"), "utf-8");
|
|
144
144
|
const dbtConfig = parseYaml(dbtProjectYml);
|
|
145
145
|
const conventions = await detectConventions(dbtPath);
|
|
@@ -235,7 +235,7 @@ async function runAdvisor(projectDir, questionOrMode, options) {
|
|
|
235
235
|
`warehouse: ${context.warehouse ? `connected (${context.warehouse.connectionType})` : "not connected"}`
|
|
236
236
|
);
|
|
237
237
|
console.log("");
|
|
238
|
-
const { AdvisorAgent, AnthropicProvider, buildModelPath } = await import("./dist-
|
|
238
|
+
const { AdvisorAgent, AnthropicProvider, buildModelPath } = await import("./dist-YTGUIBKG.js");
|
|
239
239
|
const provider = new AnthropicProvider(apiKey);
|
|
240
240
|
const agent = new AdvisorAgent(provider);
|
|
241
241
|
const isAudit = questionOrMode === "audit";
|
|
@@ -280,7 +280,7 @@ ${pc.bold(`[${i + 1}]`)} ${formatProposal(proposal, context.dbt.conventions, bui
|
|
|
280
280
|
spin2.stop();
|
|
281
281
|
console.log(result.response);
|
|
282
282
|
if (result.proposals.length > 0) {
|
|
283
|
-
const { buildModelPath: bmp } = await import("./dist-
|
|
283
|
+
const { buildModelPath: bmp } = await import("./dist-YTGUIBKG.js");
|
|
284
284
|
for (const proposal of result.proposals) {
|
|
285
285
|
console.log(
|
|
286
286
|
`
|
|
@@ -321,7 +321,7 @@ ${formatProposal(proposal, context.dbt.conventions, bmp)}`
|
|
|
321
321
|
conversationHistory.length = 0;
|
|
322
322
|
conversationHistory.push(...result.messages);
|
|
323
323
|
if (result.proposals.length > 0) {
|
|
324
|
-
const { buildModelPath: bmp } = await import("./dist-
|
|
324
|
+
const { buildModelPath: bmp } = await import("./dist-YTGUIBKG.js");
|
|
325
325
|
for (const proposal of result.proposals) {
|
|
326
326
|
console.log(
|
|
327
327
|
`
|
|
@@ -339,7 +339,7 @@ async function offerApply(context, proposals) {
|
|
|
339
339
|
return;
|
|
340
340
|
}
|
|
341
341
|
const { confirm } = await import("@inquirer/prompts");
|
|
342
|
-
const { writeDbtModel, buildModelPath, formatModelSql, updateSchemaYml } = await import("./dist-
|
|
342
|
+
const { writeDbtModel, buildModelPath, formatModelSql, updateSchemaYml } = await import("./dist-YTGUIBKG.js");
|
|
343
343
|
for (const proposal of proposals) {
|
|
344
344
|
console.log("");
|
|
345
345
|
const shouldApply = await confirm({
|
|
@@ -378,4 +378,4 @@ async function offerApply(context, proposals) {
|
|
|
378
378
|
export {
|
|
379
379
|
runAdvisor
|
|
380
380
|
};
|
|
381
|
-
//# sourceMappingURL=advisor-
|
|
381
|
+
//# sourceMappingURL=advisor-YW2EBXGR.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/dbt/rewrite-database.ts
|
|
2
|
+
function extractDatabase(tablePath) {
|
|
3
|
+
if (!tablePath) return null;
|
|
4
|
+
const parts = tablePath.split(".");
|
|
5
|
+
return parts.length >= 3 ? parts[0] : null;
|
|
6
|
+
}
|
|
7
|
+
function rewriteTableDatabase(tablePath, targetDatabase) {
|
|
8
|
+
if (!tablePath) return tablePath;
|
|
9
|
+
const parts = tablePath.split(".");
|
|
10
|
+
if (parts.length >= 3) {
|
|
11
|
+
parts[0] = targetDatabase;
|
|
12
|
+
return parts.join(".");
|
|
13
|
+
}
|
|
14
|
+
return tablePath;
|
|
15
|
+
}
|
|
16
|
+
function detectDatabaseMismatch(models, connectionDatabase) {
|
|
17
|
+
if (!connectionDatabase) return { mismatch: false };
|
|
18
|
+
for (const model of models) {
|
|
19
|
+
const db = extractDatabase(model.table || "");
|
|
20
|
+
if (db) {
|
|
21
|
+
if (db.toUpperCase() !== connectionDatabase.toUpperCase()) {
|
|
22
|
+
return { mismatch: true, catalogDatabase: db, connectionDatabase };
|
|
23
|
+
}
|
|
24
|
+
return { mismatch: false };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return { mismatch: false };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
extractDatabase,
|
|
32
|
+
rewriteTableDatabase,
|
|
33
|
+
detectDatabaseMismatch
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=chunk-IVD4OP3K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/dbt/rewrite-database.ts"],"sourcesContent":["/**\n * Extract the database portion from a fully-qualified table path.\n * Returns null if the path has fewer than 3 parts (no database).\n */\nexport function extractDatabase(tablePath: string): string | null {\n if (!tablePath) return null;\n const parts = tablePath.split('.');\n return parts.length >= 3 ? parts[0]! : null;\n}\n\n/**\n * Rewrite the database portion of a table path.\n * Only rewrites 3-part paths (DATABASE.SCHEMA.TABLE).\n * 2-part and 1-part paths are returned unchanged.\n */\nexport function rewriteTableDatabase(\n tablePath: string | undefined,\n targetDatabase: string,\n): string | undefined {\n if (!tablePath) return tablePath;\n const parts = tablePath.split('.');\n if (parts.length >= 3) {\n parts[0] = targetDatabase;\n return parts.join('.');\n }\n return tablePath;\n}\n\nexport interface MismatchResult {\n mismatch: boolean;\n catalogDatabase?: string;\n connectionDatabase?: string;\n}\n\n/**\n * Check if the catalog's table paths reference a different database\n * than the active connection. Compares case-insensitively.\n */\nexport function detectDatabaseMismatch(\n models: Array<{ name: string; table?: string }>,\n connectionDatabase: string | undefined,\n): MismatchResult {\n if (!connectionDatabase) return { mismatch: false };\n\n // Find first model with a 3-part table path\n for (const model of models) {\n const db = extractDatabase(model.table || '');\n if (db) {\n if (db.toUpperCase() !== connectionDatabase.toUpperCase()) {\n return { mismatch: true, catalogDatabase: db, connectionDatabase };\n }\n return { mismatch: false };\n }\n }\n\n return { mismatch: false };\n}\n"],"mappings":";AAIO,SAAS,gBAAgB,WAAkC;AAChE,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,QAAQ,UAAU,MAAM,GAAG;AACjC,SAAO,MAAM,UAAU,IAAI,MAAM,CAAC,IAAK;AACzC;AAOO,SAAS,qBACd,WACA,gBACoB;AACpB,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,QAAQ,UAAU,MAAM,GAAG;AACjC,MAAI,MAAM,UAAU,GAAG;AACrB,UAAM,CAAC,IAAI;AACX,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB;AACA,SAAO;AACT;AAYO,SAAS,uBACd,QACA,oBACgB;AAChB,MAAI,CAAC,mBAAoB,QAAO,EAAE,UAAU,MAAM;AAGlD,aAAW,SAAS,QAAQ;AAC1B,UAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAC5C,QAAI,IAAI;AACN,UAAI,GAAG,YAAY,MAAM,mBAAmB,YAAY,GAAG;AACzD,eAAO,EAAE,UAAU,MAAM,iBAAiB,IAAI,mBAAmB;AAAA,MACnE;AACA,aAAO,EAAE,UAAU,MAAM;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,MAAM;AAC3B;","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getDescribeQuery
|
|
3
|
-
} from "./chunk-EHM6AMMA.js";
|
|
4
1
|
import {
|
|
5
2
|
resolveTableName
|
|
6
3
|
} from "./chunk-VJC24RKT.js";
|
|
4
|
+
import {
|
|
5
|
+
getDescribeQuery
|
|
6
|
+
} from "./chunk-EHM6AMMA.js";
|
|
7
7
|
import {
|
|
8
8
|
createConnector,
|
|
9
9
|
resolveConnection
|
|
@@ -40,4 +40,4 @@ async function describeTable(projectDir, table, options) {
|
|
|
40
40
|
export {
|
|
41
41
|
describeTable
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=describe-
|
|
43
|
+
//# sourceMappingURL=describe-ZM2JI2XS.js.map
|
|
@@ -13608,7 +13608,7 @@ async function chatRoutes(fastify, options) {
|
|
|
13608
13608
|
systemParts.push("Output ONLY the new text to insert. Do NOT repeat the existing content.");
|
|
13609
13609
|
}
|
|
13610
13610
|
const systemPrompt = systemParts.join("\n");
|
|
13611
|
-
const { AnthropicProvider } = await import("./dist-
|
|
13611
|
+
const { AnthropicProvider } = await import("./dist-YTGUIBKG.js");
|
|
13612
13612
|
const provider = new AnthropicProvider(apiKey);
|
|
13613
13613
|
const response = await provider.chat({
|
|
13614
13614
|
system: systemPrompt,
|
|
@@ -14023,4 +14023,4 @@ async function runDevServer(projectDir, options) {
|
|
|
14023
14023
|
export {
|
|
14024
14024
|
runDevServer
|
|
14025
14025
|
};
|
|
14026
|
-
//# sourceMappingURL=dev-
|
|
14026
|
+
//# sourceMappingURL=dev-CBUHSRXH.js.map
|
|
@@ -12,7 +12,8 @@ var KNOWLEDGE_TOPICS = [
|
|
|
12
12
|
"macros",
|
|
13
13
|
"testing",
|
|
14
14
|
"naming",
|
|
15
|
-
"performance"
|
|
15
|
+
"performance",
|
|
16
|
+
"sources"
|
|
16
17
|
];
|
|
17
18
|
async function loadKnowledge(topic) {
|
|
18
19
|
if (!KNOWLEDGE_TOPICS.includes(topic)) {
|
|
@@ -452,6 +453,12 @@ When proposing models:
|
|
|
452
453
|
- Explain WHY the model helps, not just WHAT it does
|
|
453
454
|
- Use ref() and source() macros correctly
|
|
454
455
|
|
|
456
|
+
When working with cross-database tables:
|
|
457
|
+
- If a table lives outside the primary analytics database, recommend creating a dbt source definition in sources.yml
|
|
458
|
+
- Follow the pattern: source \u2192 staging model \u2192 downstream refs
|
|
459
|
+
- Use get_knowledge('sources') for detailed source patterns
|
|
460
|
+
- Check the warehouse catalog (get_warehouse_tables) to identify tables in other databases
|
|
461
|
+
|
|
455
462
|
When in audit mode:
|
|
456
463
|
- Evaluate: coverage gaps, convention violations, materialization mismatches, missing tests
|
|
457
464
|
- Rank suggestions by impact
|
|
@@ -709,4 +716,4 @@ export {
|
|
|
709
716
|
updateSchemaYml,
|
|
710
717
|
writeDbtModel
|
|
711
718
|
};
|
|
712
|
-
//# sourceMappingURL=dist-
|
|
719
|
+
//# sourceMappingURL=dist-YTGUIBKG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../packages/advisor/src/dbt/knowledge.ts","../../../packages/advisor/src/dbt/project.ts","../../../packages/advisor/src/tools.ts","../../../packages/advisor/src/agent.ts","../../../packages/advisor/src/providers/anthropic.ts","../../../packages/advisor/src/dbt/writer.ts"],"sourcesContent":["import { readFile } from 'fs/promises';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst KNOWLEDGE_DIR = join(__dirname, '..', 'knowledge');\n\nexport const KNOWLEDGE_TOPICS = [\n 'materializations',\n 'incremental',\n 'macros',\n 'testing',\n 'naming',\n 'performance',\n 'sources',\n] as const;\n\nexport type KnowledgeTopic = (typeof KNOWLEDGE_TOPICS)[number];\n\nexport async function loadKnowledge(topic: string): Promise<string> {\n if (!KNOWLEDGE_TOPICS.includes(topic as KnowledgeTopic)) {\n return `Unknown topic: \"${topic}\". Available topics: ${KNOWLEDGE_TOPICS.join(', ')}`;\n }\n\n const filePath = join(KNOWLEDGE_DIR, `${topic}.md`);\n return readFile(filePath, 'utf-8');\n}\n\nexport function getKnowledgeOverview(): string {\n return `You have access to a dbt knowledge base via the get_knowledge tool. Available topics:\n${KNOWLEDGE_TOPICS.map((t) => `- ${t}`).join('\\n')}\n\nUse get_knowledge when you need specifics on materializations, incremental strategies, Jinja macros, testing, naming conventions, or performance optimization.`;\n}\n","import { readFile } from 'fs/promises';\nimport { join, basename, relative, dirname } from 'path';\nimport fg from 'fast-glob';\nimport { parse as parseYaml } from 'yaml';\n\nexport interface DbtConventions {\n folderStructure: string[];\n namingPrefixes: Record<string, string>;\n commonMaterializations: Record<string, string>;\n schemaYmlPattern: 'per-folder' | 'per-model' | 'single-file';\n testPatterns: string[];\n}\n\nexport interface DbtModelInfo {\n name: string;\n path: string;\n layer: string;\n materialization: string;\n folder: string;\n}\n\ninterface DbtProjectYml {\n name: string;\n 'model-paths'?: string[];\n model_paths?: string[];\n}\n\nasync function getModelPaths(projectPath: string): Promise<string[]> {\n const content = await readFile(join(projectPath, 'dbt_project.yml'), 'utf-8');\n const parsed = parseYaml(content) as DbtProjectYml;\n return parsed['model-paths'] ?? parsed.model_paths ?? ['models'];\n}\n\nfunction extractMaterialization(sql: string): string {\n const match = sql.match(/materialized\\s*=\\s*['\"](\\w+)['\"]/);\n return match?.[1] ?? 'view';\n}\n\nfunction detectLayer(relativePath: string): string {\n const parts = relativePath.split('/');\n return parts[0] ?? 'unknown';\n}\n\nfunction detectPrefix(\n models: Array<{ name: string; layer: string }>\n): Record<string, string> {\n const prefixesByLayer = new Map<string, Map<string, number>>();\n\n for (const model of models) {\n const underscoreIdx = model.name.indexOf('_');\n if (underscoreIdx === -1) continue;\n const prefix = model.name.slice(0, underscoreIdx + 1);\n\n if (!prefixesByLayer.has(model.layer)) {\n prefixesByLayer.set(model.layer, new Map());\n }\n const counts = prefixesByLayer.get(model.layer)!;\n counts.set(prefix, (counts.get(prefix) ?? 0) + 1);\n }\n\n const result: Record<string, string> = {};\n for (const [layer, counts] of prefixesByLayer) {\n let maxCount = 0;\n let maxPrefix = '';\n for (const [prefix, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n maxPrefix = prefix;\n }\n }\n if (maxPrefix && maxCount >= 2) {\n result[layer] = maxPrefix;\n }\n }\n\n return result;\n}\n\nfunction detectMaterializations(\n models: Array<{ layer: string; materialization: string }>\n): Record<string, string> {\n const matByLayer = new Map<string, Map<string, number>>();\n\n for (const model of models) {\n if (!matByLayer.has(model.layer)) {\n matByLayer.set(model.layer, new Map());\n }\n const counts = matByLayer.get(model.layer)!;\n counts.set(model.materialization, (counts.get(model.materialization) ?? 0) + 1);\n }\n\n const result: Record<string, string> = {};\n for (const [layer, counts] of matByLayer) {\n let maxCount = 0;\n let maxMat = '';\n for (const [mat, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n maxMat = mat;\n }\n }\n if (maxMat) result[layer] = maxMat;\n }\n\n return result;\n}\n\nasync function detectSchemaYmlPattern(\n projectPath: string,\n modelPaths: string[]\n): Promise<'per-folder' | 'per-model' | 'single-file'> {\n const ymlFiles: string[] = [];\n for (const mp of modelPaths) {\n const pattern = join(projectPath, mp, '**/*.yml');\n const files = await fg(pattern, { ignore: ['**/node_modules/**'] });\n ymlFiles.push(...files);\n }\n\n if (ymlFiles.length === 0) return 'per-folder';\n if (ymlFiles.length === 1) return 'single-file';\n\n const dirs = new Set(ymlFiles.map((f) => dirname(f)));\n return dirs.size > 1 ? 'per-folder' : 'single-file';\n}\n\nexport async function detectConventions(projectPath: string): Promise<DbtConventions> {\n const modelPaths = await getModelPaths(projectPath);\n const models = await listDbtModels(projectPath);\n\n const folders = [...new Set(models.map((m) => m.layer))].filter((l) => l !== 'unknown');\n\n return {\n folderStructure: folders,\n namingPrefixes: detectPrefix(models),\n commonMaterializations: detectMaterializations(models),\n schemaYmlPattern: await detectSchemaYmlPattern(projectPath, modelPaths),\n testPatterns: [],\n };\n}\n\nexport async function listDbtModels(projectPath: string): Promise<DbtModelInfo[]> {\n const modelPaths = await getModelPaths(projectPath);\n const models: DbtModelInfo[] = [];\n\n for (const mp of modelPaths) {\n const pattern = join(projectPath, mp, '**/*.sql');\n const files = await fg(pattern, { ignore: ['**/node_modules/**'] });\n\n for (const file of files) {\n const relPath = relative(join(projectPath, mp), file);\n const name = basename(file, '.sql');\n const sql = await readFile(file, 'utf-8');\n const materialization = extractMaterialization(sql);\n const layer = detectLayer(relPath);\n const folder = dirname(relPath);\n\n models.push({ name, path: relPath, layer, materialization, folder });\n }\n }\n\n return models;\n}\n\nexport async function readDbtModel(\n projectPath: string,\n modelName: string\n): Promise<string | null> {\n const models = await listDbtModels(projectPath);\n const model = models.find((m) => m.name === modelName);\n if (!model) return null;\n\n const modelPaths = await getModelPaths(projectPath);\n for (const mp of modelPaths) {\n const fullPath = join(projectPath, mp, model.path);\n try {\n return await readFile(fullPath, 'utf-8');\n } catch {\n continue;\n }\n }\n return null;\n}\n","import type { ToolDefinition } from './providers/types.js';\nimport type { AdvisorContext } from './context.js';\nimport { loadKnowledge } from './dbt/knowledge.js';\nimport { readDbtModel } from './dbt/project.js';\n\nexport type { AdvisorContext } from './context.js';\n\nexport const TOOL_DEFINITIONS: ToolDefinition[] = [\n // Read-only tools\n {\n name: 'list_yamchart_models',\n description: 'List all yamchart SQL models with names, descriptions, parameters, and return columns',\n parameters: { type: 'object', properties: {}, required: [] },\n },\n {\n name: 'list_charts',\n description: 'List all yamchart charts showing which models they reference and their chart type',\n parameters: { type: 'object', properties: {}, required: [] },\n },\n {\n name: 'get_catalog',\n description: 'Get the dbt catalog (.yamchart/catalog.md) with upstream table schemas and column metadata',\n parameters: { type: 'object', properties: {}, required: [] },\n },\n {\n name: 'get_warehouse_table',\n description: 'Get detailed column metadata and sample rows for a specific warehouse table from the cached catalog. Instant — reads from local catalog, no live query. Use the fully-qualified name (e.g. RAW.PAYMENTS).',\n parameters: {\n type: 'object',\n properties: {\n table: { type: 'string', description: 'Fully-qualified table name (e.g. RAW.PAYMENTS, STAGING.CUSTOMERS)' },\n },\n required: ['table'],\n },\n },\n {\n name: 'get_warehouse_tables',\n description: 'Get detailed metadata for multiple warehouse tables at once from the cached catalog.',\n parameters: {\n type: 'object',\n properties: {\n tables: { type: 'array', items: { type: 'string' }, description: 'List of fully-qualified table names' },\n },\n required: ['tables'],\n },\n },\n {\n name: 'introspect_warehouse',\n description: 'Query the live warehouse. Use for discovering raw tables not yet modeled in dbt.',\n parameters: {\n type: 'object',\n properties: {\n sql: { type: 'string', description: 'SQL query to execute (e.g. SHOW TABLES, SELECT * FROM information_schema.columns)' },\n },\n required: ['sql'],\n },\n },\n {\n name: 'sample_data',\n description: 'Preview rows from a table in the warehouse',\n parameters: {\n type: 'object',\n properties: {\n table: { type: 'string', description: 'Table name (can be schema-qualified)' },\n limit: { type: 'number', description: 'Number of rows to return (default: 5)' },\n },\n required: ['table'],\n },\n },\n {\n name: 'read_dbt_model',\n description: 'Read the full SQL source of an existing dbt model',\n parameters: {\n type: 'object',\n properties: {\n model_name: { type: 'string', description: 'Name of the dbt model to read' },\n },\n required: ['model_name'],\n },\n },\n {\n name: 'list_dbt_models',\n description: 'List all dbt models with their layer (staging/intermediate/marts), materialization, and folder',\n parameters: { type: 'object', properties: {}, required: [] },\n },\n {\n name: 'get_knowledge',\n description: 'Look up dbt reference documentation on a topic: materializations, incremental, macros, testing, naming, performance',\n parameters: {\n type: 'object',\n properties: {\n topic: { type: 'string', description: 'Topic name: materializations, incremental, macros, testing, naming, performance' },\n },\n required: ['topic'],\n },\n },\n\n // Action tools\n {\n name: 'propose_model',\n description: 'Propose a new dbt model. Call this when you have a suggestion to present to the user.',\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Model name (snake_case)' },\n description: { type: 'string', description: 'One-line description of what this model does' },\n sql: { type: 'string', description: 'Full SQL for the model (may include Jinja)' },\n layer: { type: 'string', description: 'dbt layer: staging, intermediate, or marts' },\n materialization: { type: 'string', description: 'Materialization: view, table, or incremental' },\n explanation: { type: 'string', description: 'Why this model is useful (2-3 sentences)' },\n subfolder: { type: 'string', description: 'Optional subfolder within the layer (e.g. \"stripe\", \"core\")' },\n columns: {\n type: 'array',\n description: 'Column definitions for schema.yml',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n description: { type: 'string' },\n tests: { type: 'array', items: { type: 'string' } },\n },\n required: ['name'],\n },\n },\n },\n required: ['name', 'description', 'sql', 'layer', 'materialization', 'explanation'],\n },\n },\n {\n name: 'write_dbt_model',\n description: 'Write a proposed dbt model SQL file to the dbt project. Only call after proposing and user confirmation.',\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Model name (must match a previous proposal)' },\n },\n required: ['name'],\n },\n },\n {\n name: 'update_schema_yml',\n description: 'Add or update the model entry in the appropriate schema.yml file. Only call after writing the model.',\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Model name (must match a written model)' },\n },\n required: ['name'],\n },\n },\n];\n\nexport async function executeToolCall(\n context: AdvisorContext,\n toolName: string,\n input: Record<string, unknown>\n): Promise<string> {\n switch (toolName) {\n case 'list_yamchart_models':\n return JSON.stringify(\n context.yamchart.models.map((m) => ({\n name: m.name,\n description: m.description,\n params: m.params,\n returns: m.returns,\n }))\n );\n\n case 'list_charts':\n return JSON.stringify(\n context.yamchart.charts.map((c) => ({\n name: c.name,\n title: c.title,\n model: c.model,\n type: c.type,\n }))\n );\n\n case 'get_catalog':\n return context.yamchart.catalog ?? 'No dbt catalog found. Run `yamchart sync-dbt` to create one.';\n\n case 'get_warehouse_table': {\n if (!context.yamchart.catalogJson) {\n return 'Warehouse catalog not available. Run `yamchart sync-warehouse` to populate it.';\n }\n const tableName = (input.table as string).toUpperCase();\n const match = context.yamchart.catalogJson.models.find(\n (m) => (m.table || '').toUpperCase() === tableName || m.name.toUpperCase() === tableName\n );\n if (!match) {\n return JSON.stringify({ error: `Table not found in catalog: ${input.table}. Use get_catalog to see available tables.` });\n }\n return JSON.stringify({\n name: match.name,\n table: match.table,\n tableType: match.tableType,\n source: match.source,\n columns: match.columns,\n sampleRows: match.sampleRows || [],\n });\n }\n\n case 'get_warehouse_tables': {\n if (!context.yamchart.catalogJson) {\n return 'Warehouse catalog not available. Run `yamchart sync-warehouse` to populate it.';\n }\n const tableNames = (input.tables as string[]).map((t) => t.toUpperCase());\n const results = tableNames.map((name) => {\n const match = context.yamchart.catalogJson!.models.find(\n (m) => (m.table || '').toUpperCase() === name || m.name.toUpperCase() === name\n );\n if (!match) {\n return { error: `Not found: ${name}` };\n }\n return {\n name: match.name,\n table: match.table,\n tableType: match.tableType,\n source: match.source,\n columns: match.columns,\n sampleRows: match.sampleRows || [],\n };\n });\n return JSON.stringify(results);\n }\n\n case 'introspect_warehouse': {\n if (!context.warehouse) {\n return 'Warehouse introspection not available. No database connection configured.';\n }\n const sql = input.sql as string;\n try {\n const result = await context.warehouse.executeSql(sql);\n return JSON.stringify(result);\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n }\n\n case 'sample_data': {\n if (!context.warehouse) {\n return 'Warehouse not available. No database connection configured.';\n }\n const table = input.table as string;\n const limit = (input.limit as number) ?? 5;\n try {\n const result = await context.warehouse.executeSql(\n `SELECT * FROM ${table} LIMIT ${limit}`\n );\n return JSON.stringify(result);\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n }\n\n case 'read_dbt_model': {\n const modelName = input.model_name as string;\n const sql = await readDbtModel(context.dbt.projectPath, modelName);\n if (!sql) {\n return JSON.stringify({ error: `Model not found: ${modelName}` });\n }\n return JSON.stringify({ name: modelName, sql });\n }\n\n case 'list_dbt_models':\n return JSON.stringify(\n context.dbt.models.map((m) => ({\n name: m.name,\n path: m.path,\n layer: m.layer,\n materialization: m.materialization,\n folder: m.folder,\n }))\n );\n\n case 'get_knowledge': {\n const topic = input.topic as string;\n return loadKnowledge(topic);\n }\n\n case 'propose_model':\n return JSON.stringify({\n status: 'proposed',\n name: input.name,\n description: input.description,\n sql: input.sql,\n layer: input.layer,\n materialization: input.materialization,\n explanation: input.explanation,\n subfolder: input.subfolder,\n columns: input.columns,\n });\n\n case 'write_dbt_model':\n // Actual writing happens in the CLI command, not here.\n // The agent tool just signals intent — the CLI confirms with the user.\n return JSON.stringify({\n status: 'pending_confirmation',\n name: input.name,\n message: 'Model write requested. Waiting for user confirmation.',\n });\n\n case 'update_schema_yml':\n return JSON.stringify({\n status: 'pending_confirmation',\n name: input.name,\n message: 'Schema.yml update requested. Waiting for user confirmation.',\n });\n\n default:\n return JSON.stringify({ error: `Unknown tool: ${toolName}` });\n }\n}\n","import type {\n LLMProvider,\n Message,\n ContentBlock,\n TextBlock,\n ToolUseBlock,\n ToolResultBlock,\n} from './providers/types.js';\nimport type { AdvisorContext } from './context.js';\nimport { TOOL_DEFINITIONS, executeToolCall } from './tools.js';\nimport { getKnowledgeOverview } from './dbt/knowledge.js';\n\nexport interface Proposal {\n name: string;\n description: string;\n sql: string;\n layer: string;\n materialization: string;\n explanation: string;\n subfolder?: string;\n columns?: Array<{ name: string; description?: string; tests?: string[] }>;\n}\n\nexport interface AgentResult {\n response: string;\n proposals: Proposal[];\n messages: Message[];\n}\n\nexport const SYSTEM_PROMPT = `You are a dbt advisor for yamchart projects. You analyze the BI layer (yamchart models, charts, dashboards) and the data engineering layer (dbt models, warehouse tables) to suggest improvements to dbt models.\n\nThink like a senior data engineer. Your goals:\n- Understand what the BI layer needs (charts, filters, drill-downs, date ranges)\n- Identify gaps in the dbt project (missing models, incomplete staging, opportunities for pre-aggregation)\n- Suggest new dbt models that serve the BI layer better\n- Follow the project's existing conventions (folder structure, naming, materializations)\n\nWhen proposing models:\n- Match the project's naming conventions (detect and follow existing prefixes like stg_, fct_, dim_)\n- Place models in the correct layer and folder\n- Choose appropriate materializations\n- Include column descriptions and tests in proposals\n- Explain WHY the model helps, not just WHAT it does\n- Use ref() and source() macros correctly\n\nWhen working with cross-database tables:\n- If a table lives outside the primary analytics database, recommend creating a dbt source definition in sources.yml\n- Follow the pattern: source → staging model → downstream refs\n- Use get_knowledge('sources') for detailed source patterns\n- Check the warehouse catalog (get_warehouse_tables) to identify tables in other databases\n\nWhen in audit mode:\n- Evaluate: coverage gaps, convention violations, materialization mismatches, missing tests\n- Rank suggestions by impact\n- Be concise — focus on actionable improvements\n\n${getKnowledgeOverview()}\n\nWhen you have a suggestion, call propose_model with the full SQL and metadata. Do NOT call write_dbt_model or update_schema_yml directly — the user will be prompted to confirm before writing.`;\n\nconst MAX_TOOL_ROUNDS = 15;\n\nexport class AdvisorAgent {\n private provider: LLMProvider;\n\n constructor(provider: LLMProvider) {\n this.provider = provider;\n }\n\n async run(\n context: AdvisorContext,\n userMessages: Message[]\n ): Promise<AgentResult> {\n const proposals: Proposal[] = [];\n const messages: Message[] = [...userMessages];\n\n // Build context-specific system prompt\n const systemPrompt = this.buildSystemPrompt(context);\n\n for (let round = 0; round < MAX_TOOL_ROUNDS; round++) {\n const response = await this.provider.chat({\n system: systemPrompt,\n messages,\n tools: TOOL_DEFINITIONS,\n });\n\n const textBlocks = response.content.filter(\n (b): b is TextBlock => b.type === 'text'\n );\n const toolUseBlocks = response.content.filter(\n (b): b is ToolUseBlock => b.type === 'tool_use'\n );\n\n // No tool calls — return final text response\n if (toolUseBlocks.length === 0) {\n const responseText = textBlocks.map((b) => b.text).join('\\n');\n return { response: responseText, proposals, messages };\n }\n\n // Add assistant message with tool calls\n messages.push({ role: 'assistant', content: response.content });\n\n // Execute each tool call\n const toolResults: ContentBlock[] = [];\n for (const toolUse of toolUseBlocks) {\n const result = await executeToolCall(context, toolUse.name, toolUse.input);\n\n // Collect proposals\n if (toolUse.name === 'propose_model') {\n const parsed = JSON.parse(result) as Record<string, unknown>;\n proposals.push({\n name: parsed.name as string,\n description: parsed.description as string,\n sql: toolUse.input.sql as string,\n layer: toolUse.input.layer as string,\n materialization: toolUse.input.materialization as string,\n explanation: toolUse.input.explanation as string,\n subfolder: toolUse.input.subfolder as string | undefined,\n columns: toolUse.input.columns as Proposal['columns'],\n });\n }\n\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolUse.id,\n content: result,\n } as ToolResultBlock);\n }\n\n // Add tool results as user message\n messages.push({ role: 'user', content: toolResults });\n }\n\n // Hit max rounds — return what we have\n return {\n response: 'Reached maximum tool call rounds. Here are the suggestions gathered so far.',\n proposals,\n messages,\n };\n }\n\n private buildSystemPrompt(context: AdvisorContext): string {\n const parts = [SYSTEM_PROMPT];\n\n // Add project summary\n parts.push(`\\n## Current Project Summary`);\n parts.push(`- Yamchart: ${context.yamchart.models.length} SQL models, ${context.yamchart.charts.length} charts, ${context.yamchart.dashboards.length} dashboards`);\n parts.push(`- dbt project: \"${context.dbt.projectName}\" at ${context.dbt.projectPath}`);\n parts.push(`- dbt models: ${context.dbt.models.length} (layers: ${context.dbt.conventions.folderStructure.join(', ') || 'none detected'})`);\n\n if (Object.keys(context.dbt.conventions.namingPrefixes).length > 0) {\n const prefixes = Object.entries(context.dbt.conventions.namingPrefixes)\n .map(([layer, prefix]) => `${layer}: ${prefix}`)\n .join(', ');\n parts.push(`- Naming prefixes: ${prefixes}`);\n }\n\n if (Object.keys(context.dbt.conventions.commonMaterializations).length > 0) {\n const mats = Object.entries(context.dbt.conventions.commonMaterializations)\n .map(([layer, mat]) => `${layer}: ${mat}`)\n .join(', ');\n parts.push(`- Materializations: ${mats}`);\n }\n\n parts.push(`- Schema.yml pattern: ${context.dbt.conventions.schemaYmlPattern}`);\n parts.push(`- Catalog: ${context.yamchart.catalog ? 'available' : 'not synced'}`);\n parts.push(`- Warehouse: ${context.warehouse ? `connected (${context.warehouse.connectionType})` : 'not connected'}`);\n\n return parts.join('\\n');\n }\n}\n","import Anthropic from '@anthropic-ai/sdk';\nimport type {\n LLMProvider,\n LLMResponse,\n Message,\n ToolDefinition,\n ContentBlock,\n TextBlock,\n ToolUseBlock,\n} from './types.js';\n\nexport class AnthropicProvider implements LLMProvider {\n private client: Anthropic;\n private model: string;\n\n constructor(apiKey: string, model: string = 'claude-sonnet-4-5-20250929') {\n this.client = new Anthropic({ apiKey });\n this.model = model;\n }\n\n async chat(options: {\n system: string;\n messages: Message[];\n tools: ToolDefinition[];\n maxTokens?: number;\n }): Promise<LLMResponse> {\n const tools: Anthropic.Tool[] = options.tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: {\n type: 'object' as const,\n properties: t.parameters.properties,\n required: t.parameters.required ?? [],\n },\n }));\n\n const messages: Anthropic.MessageParam[] = options.messages.map((m) => {\n if (typeof m.content === 'string') {\n return { role: m.role, content: m.content };\n }\n const blocks: Anthropic.ContentBlockParam[] = m.content.map((block) => {\n if (block.type === 'text') {\n return { type: 'text' as const, text: (block as TextBlock).text };\n }\n if (block.type === 'tool_use') {\n const tu = block as ToolUseBlock;\n return { type: 'tool_use' as const, id: tu.id, name: tu.name, input: tu.input };\n }\n if (block.type === 'tool_result') {\n const tr = block as { type: 'tool_result'; tool_use_id: string; content: string };\n return { type: 'tool_result' as const, tool_use_id: tr.tool_use_id, content: tr.content };\n }\n throw new Error(`Unknown block type: ${block.type}`);\n });\n return { role: m.role, content: blocks };\n });\n\n const response = await this.client.messages.create({\n model: this.model,\n max_tokens: options.maxTokens ?? 4096,\n system: options.system,\n tools,\n messages,\n });\n\n const content: ContentBlock[] = response.content.map((block) => {\n if (block.type === 'text') {\n return { type: 'text', text: block.text } as TextBlock;\n }\n if (block.type === 'tool_use') {\n return {\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: block.input as Record<string, unknown>,\n } as ToolUseBlock;\n }\n throw new Error(`Unexpected block type: ${block.type}`);\n });\n\n return {\n content,\n stopReason: response.stop_reason === 'tool_use' ? 'tool_use' : 'end',\n };\n }\n}\n","import { readFile, writeFile, mkdir, access } from 'fs/promises';\nimport { join, dirname } from 'path';\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport type { DbtConventions } from './project.js';\n\nexport function buildModelPath(\n modelName: string,\n layer: string | undefined,\n conventions: DbtConventions,\n subfolder?: string\n): string {\n const effectiveLayer = layer ?? (conventions.folderStructure.includes('marts') ? 'marts' : conventions.folderStructure[0] ?? 'models');\n const parts = ['models', effectiveLayer];\n if (subfolder) parts.push(subfolder);\n parts.push(`${modelName}.sql`);\n return parts.join('/');\n}\n\nexport function formatModelSql(options: {\n materialization: string;\n tags?: string[];\n sql: string;\n description?: string;\n}): string {\n const lines: string[] = [];\n\n // Only add config block for non-default materializations\n if (options.materialization !== 'view') {\n const configParts: string[] = [`materialized='${options.materialization}'`];\n if (options.tags && options.tags.length > 0) {\n configParts.push(`tags=[${options.tags.map((t) => `'${t}'`).join(', ')}]`);\n }\n lines.push(`{{\\n config(\\n ${configParts.join(',\\n ')}\\n )\\n}}\\n`);\n }\n\n lines.push(options.sql);\n return lines.join('\\n');\n}\n\nexport interface SchemaColumn {\n name: string;\n description?: string;\n tests?: string[];\n}\n\nexport function buildSchemaYmlEntry(options: {\n name: string;\n description: string;\n columns?: SchemaColumn[];\n}): string {\n const model: Record<string, unknown> = {\n name: options.name,\n description: options.description,\n };\n\n if (options.columns && options.columns.length > 0) {\n model.columns = options.columns.map((col) => {\n const entry: Record<string, unknown> = { name: col.name };\n if (col.description) entry.description = col.description;\n if (col.tests && col.tests.length > 0) entry.tests = col.tests;\n return entry;\n });\n }\n\n return stringifyYaml({ models: [model] }, { indent: 2 });\n}\n\nexport async function writeDbtModel(\n projectPath: string,\n modelPath: string,\n sql: string\n): Promise<string> {\n const fullPath = join(projectPath, modelPath);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, sql + '\\n', 'utf-8');\n return fullPath;\n}\n\nexport async function updateSchemaYml(\n projectPath: string,\n schemaPath: string,\n entry: { name: string; description: string; columns?: SchemaColumn[] }\n): Promise<string> {\n const fullPath = join(projectPath, schemaPath);\n\n let existing: { version?: number; models?: Array<Record<string, unknown>> } = {\n version: 2,\n models: [],\n };\n\n try {\n await access(fullPath);\n const content = await readFile(fullPath, 'utf-8');\n existing = parseYaml(content) as typeof existing;\n if (!existing.models) existing.models = [];\n } catch {\n // File doesn't exist, start fresh\n await mkdir(dirname(fullPath), { recursive: true });\n }\n\n // Check if model already exists\n const idx = existing.models!.findIndex(\n (m) => m.name === entry.name\n );\n\n const modelEntry: Record<string, unknown> = {\n name: entry.name,\n description: entry.description,\n };\n if (entry.columns && entry.columns.length > 0) {\n modelEntry.columns = entry.columns.map((col) => {\n const c: Record<string, unknown> = { name: col.name };\n if (col.description) c.description = col.description;\n if (col.tests && col.tests.length > 0) c.tests = col.tests;\n return c;\n });\n }\n\n if (idx >= 0) {\n existing.models![idx] = modelEntry;\n } else {\n existing.models!.push(modelEntry);\n }\n\n await writeFile(fullPath, stringifyYaml(existing, { indent: 2 }), 'utf-8');\n return fullPath;\n}\n"],"mappings":";;;AAAA,SAAS,gBAAgB;AACzB,SAAS,MAAM,eAAe;AAC9B,SAAS,qBAAqB;AAE9B,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,IAAM,gBAAgB,KAAK,WAAW,MAAM,WAAW;AAEhD,IAAM,mBAAmB;EAC9B;EACA;EACA;EACA;EACA;EACA;EACA;;AAKF,eAAsB,cAAc,OAAa;AAC/C,MAAI,CAAC,iBAAiB,SAAS,KAAuB,GAAG;AACvD,WAAO,mBAAmB,KAAK,wBAAwB,iBAAiB,KAAK,IAAI,CAAC;EACpF;AAEA,QAAM,WAAW,KAAK,eAAe,GAAG,KAAK,KAAK;AAClD,SAAO,SAAS,UAAU,OAAO;AACnC;AAEM,SAAU,uBAAoB;AAClC,SAAO;EACP,iBAAiB,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;;;AAGlD;;;ACjCA,SAAS,YAAAA,iBAAgB;AACzB,SAAS,QAAAC,OAAM,UAAU,UAAU,WAAAC,gBAAe;AAClD,OAAO,QAAQ;AACf,SAAS,SAAS,iBAAiB;AAwBnC,eAAe,cAAc,aAAmB;AAC9C,QAAM,UAAU,MAAMF,UAASC,MAAK,aAAa,iBAAiB,GAAG,OAAO;AAC5E,QAAM,SAAS,UAAU,OAAO;AAChC,SAAO,OAAO,aAAa,KAAK,OAAO,eAAe,CAAC,QAAQ;AACjE;AAEA,SAAS,uBAAuB,KAAW;AACzC,QAAM,QAAQ,IAAI,MAAM,kCAAkC;AAC1D,SAAO,QAAQ,CAAC,KAAK;AACvB;AAEA,SAAS,YAAY,cAAoB;AACvC,QAAM,QAAQ,aAAa,MAAM,GAAG;AACpC,SAAO,MAAM,CAAC,KAAK;AACrB;AAEA,SAAS,aACP,QAA8C;AAE9C,QAAM,kBAAkB,oBAAI,IAAG;AAE/B,aAAW,SAAS,QAAQ;AAC1B,UAAM,gBAAgB,MAAM,KAAK,QAAQ,GAAG;AAC5C,QAAI,kBAAkB;AAAI;AAC1B,UAAM,SAAS,MAAM,KAAK,MAAM,GAAG,gBAAgB,CAAC;AAEpD,QAAI,CAAC,gBAAgB,IAAI,MAAM,KAAK,GAAG;AACrC,sBAAgB,IAAI,MAAM,OAAO,oBAAI,IAAG,CAAE;IAC5C;AACA,UAAM,SAAS,gBAAgB,IAAI,MAAM,KAAK;AAC9C,WAAO,IAAI,SAAS,OAAO,IAAI,MAAM,KAAK,KAAK,CAAC;EAClD;AAEA,QAAM,SAAiC,CAAA;AACvC,aAAW,CAAC,OAAO,MAAM,KAAK,iBAAiB;AAC7C,QAAI,WAAW;AACf,QAAI,YAAY;AAChB,eAAW,CAAC,QAAQ,KAAK,KAAK,QAAQ;AACpC,UAAI,QAAQ,UAAU;AACpB,mBAAW;AACX,oBAAY;MACd;IACF;AACA,QAAI,aAAa,YAAY,GAAG;AAC9B,aAAO,KAAK,IAAI;IAClB;EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBACP,QAAyD;AAEzD,QAAM,aAAa,oBAAI,IAAG;AAE1B,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,WAAW,IAAI,MAAM,KAAK,GAAG;AAChC,iBAAW,IAAI,MAAM,OAAO,oBAAI,IAAG,CAAE;IACvC;AACA,UAAM,SAAS,WAAW,IAAI,MAAM,KAAK;AACzC,WAAO,IAAI,MAAM,kBAAkB,OAAO,IAAI,MAAM,eAAe,KAAK,KAAK,CAAC;EAChF;AAEA,QAAM,SAAiC,CAAA;AACvC,aAAW,CAAC,OAAO,MAAM,KAAK,YAAY;AACxC,QAAI,WAAW;AACf,QAAI,SAAS;AACb,eAAW,CAAC,KAAK,KAAK,KAAK,QAAQ;AACjC,UAAI,QAAQ,UAAU;AACpB,mBAAW;AACX,iBAAS;MACX;IACF;AACA,QAAI;AAAQ,aAAO,KAAK,IAAI;EAC9B;AAEA,SAAO;AACT;AAEA,eAAe,uBACb,aACA,YAAoB;AAEpB,QAAM,WAAqB,CAAA;AAC3B,aAAW,MAAM,YAAY;AAC3B,UAAM,UAAUA,MAAK,aAAa,IAAI,UAAU;AAChD,UAAM,QAAQ,MAAM,GAAG,SAAS,EAAE,QAAQ,CAAC,oBAAoB,EAAC,CAAE;AAClE,aAAS,KAAK,GAAG,KAAK;EACxB;AAEA,MAAI,SAAS,WAAW;AAAG,WAAO;AAClC,MAAI,SAAS,WAAW;AAAG,WAAO;AAElC,QAAM,OAAO,IAAI,IAAI,SAAS,IAAI,CAAC,MAAMC,SAAQ,CAAC,CAAC,CAAC;AACpD,SAAO,KAAK,OAAO,IAAI,eAAe;AACxC;AAEA,eAAsB,kBAAkB,aAAmB;AACzD,QAAM,aAAa,MAAM,cAAc,WAAW;AAClD,QAAM,SAAS,MAAM,cAAc,WAAW;AAE9C,QAAM,UAAU,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,SAAS;AAEtF,SAAO;IACL,iBAAiB;IACjB,gBAAgB,aAAa,MAAM;IACnC,wBAAwB,uBAAuB,MAAM;IACrD,kBAAkB,MAAM,uBAAuB,aAAa,UAAU;IACtE,cAAc,CAAA;;AAElB;AAEA,eAAsB,cAAc,aAAmB;AACrD,QAAM,aAAa,MAAM,cAAc,WAAW;AAClD,QAAM,SAAyB,CAAA;AAE/B,aAAW,MAAM,YAAY;AAC3B,UAAM,UAAUD,MAAK,aAAa,IAAI,UAAU;AAChD,UAAM,QAAQ,MAAM,GAAG,SAAS,EAAE,QAAQ,CAAC,oBAAoB,EAAC,CAAE;AAElE,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,SAASA,MAAK,aAAa,EAAE,GAAG,IAAI;AACpD,YAAM,OAAO,SAAS,MAAM,MAAM;AAClC,YAAM,MAAM,MAAMD,UAAS,MAAM,OAAO;AACxC,YAAM,kBAAkB,uBAAuB,GAAG;AAClD,YAAM,QAAQ,YAAY,OAAO;AACjC,YAAM,SAASE,SAAQ,OAAO;AAE9B,aAAO,KAAK,EAAE,MAAM,MAAM,SAAS,OAAO,iBAAiB,OAAM,CAAE;IACrE;EACF;AAEA,SAAO;AACT;AAEA,eAAsB,aACpB,aACA,WAAiB;AAEjB,QAAM,SAAS,MAAM,cAAc,WAAW;AAC9C,QAAM,QAAQ,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS;AACrD,MAAI,CAAC;AAAO,WAAO;AAEnB,QAAM,aAAa,MAAM,cAAc,WAAW;AAClD,aAAW,MAAM,YAAY;AAC3B,UAAM,WAAWD,MAAK,aAAa,IAAI,MAAM,IAAI;AACjD,QAAI;AACF,aAAO,MAAMD,UAAS,UAAU,OAAO;IACzC,QAAQ;AACN;IACF;EACF;AACA,SAAO;AACT;;;AC9KO,IAAM,mBAAqC;;EAEhD;IACE,MAAM;IACN,aAAa;IACb,YAAY,EAAE,MAAM,UAAU,YAAY,CAAA,GAAI,UAAU,CAAA,EAAE;;EAE5D;IACE,MAAM;IACN,aAAa;IACb,YAAY,EAAE,MAAM,UAAU,YAAY,CAAA,GAAI,UAAU,CAAA,EAAE;;EAE5D;IACE,MAAM;IACN,aAAa;IACb,YAAY,EAAE,MAAM,UAAU,YAAY,CAAA,GAAI,UAAU,CAAA,EAAE;;EAE5D;IACE,MAAM;IACN,aAAa;IACb,YAAY;MACV,MAAM;MACN,YAAY;QACV,OAAO,EAAE,MAAM,UAAU,aAAa,oEAAmE;;MAE3G,UAAU,CAAC,OAAO;;;EAGtB;IACE,MAAM;IACN,aAAa;IACb,YAAY;MACV,MAAM;MACN,YAAY;QACV,QAAQ,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAQ,GAAI,aAAa,sCAAqC;;MAExG,UAAU,CAAC,QAAQ;;;EAGvB;IACE,MAAM;IACN,aAAa;IACb,YAAY;MACV,MAAM;MACN,YAAY;QACV,KAAK,EAAE,MAAM,UAAU,aAAa,oFAAmF;;MAEzH,UAAU,CAAC,KAAK;;;EAGpB;IACE,MAAM;IACN,aAAa;IACb,YAAY;MACV,MAAM;MACN,YAAY;QACV,OAAO,EAAE,MAAM,UAAU,aAAa,uCAAsC;QAC5E,OAAO,EAAE,MAAM,UAAU,aAAa,wCAAuC;;MAE/E,UAAU,CAAC,OAAO;;;EAGtB;IACE,MAAM;IACN,aAAa;IACb,YAAY;MACV,MAAM;MACN,YAAY;QACV,YAAY,EAAE,MAAM,UAAU,aAAa,gCAA+B;;MAE5E,UAAU,CAAC,YAAY;;;EAG3B;IACE,MAAM;IACN,aAAa;IACb,YAAY,EAAE,MAAM,UAAU,YAAY,CAAA,GAAI,UAAU,CAAA,EAAE;;EAE5D;IACE,MAAM;IACN,aAAa;IACb,YAAY;MACV,MAAM;MACN,YAAY;QACV,OAAO,EAAE,MAAM,UAAU,aAAa,kFAAiF;;MAEzH,UAAU,CAAC,OAAO;;;;EAKtB;IACE,MAAM;IACN,aAAa;IACb,YAAY;MACV,MAAM;MACN,YAAY;QACV,MAAM,EAAE,MAAM,UAAU,aAAa,0BAAyB;QAC9D,aAAa,EAAE,MAAM,UAAU,aAAa,+CAA8C;QAC1F,KAAK,EAAE,MAAM,UAAU,aAAa,6CAA4C;QAChF,OAAO,EAAE,MAAM,UAAU,aAAa,6CAA4C;QAClF,iBAAiB,EAAE,MAAM,UAAU,aAAa,+CAA8C;QAC9F,aAAa,EAAE,MAAM,UAAU,aAAa,2CAA0C;QACtF,WAAW,EAAE,MAAM,UAAU,aAAa,8DAA6D;QACvG,SAAS;UACP,MAAM;UACN,aAAa;UACb,OAAO;YACL,MAAM;YACN,YAAY;cACV,MAAM,EAAE,MAAM,SAAQ;cACtB,aAAa,EAAE,MAAM,SAAQ;cAC7B,OAAO,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAQ,EAAE;;YAEnD,UAAU,CAAC,MAAM;;;;MAIvB,UAAU,CAAC,QAAQ,eAAe,OAAO,SAAS,mBAAmB,aAAa;;;EAGtF;IACE,MAAM;IACN,aAAa;IACb,YAAY;MACV,MAAM;MACN,YAAY;QACV,MAAM,EAAE,MAAM,UAAU,aAAa,8CAA6C;;MAEpF,UAAU,CAAC,MAAM;;;EAGrB;IACE,MAAM;IACN,aAAa;IACb,YAAY;MACV,MAAM;MACN,YAAY;QACV,MAAM,EAAE,MAAM,UAAU,aAAa,0CAAyC;;MAEhF,UAAU,CAAC,MAAM;;;;AAKvB,eAAsB,gBACpB,SACA,UACA,OAA8B;AAE9B,UAAQ,UAAU;IAChB,KAAK;AACH,aAAO,KAAK,UACV,QAAQ,SAAS,OAAO,IAAI,CAAC,OAAO;QAClC,MAAM,EAAE;QACR,aAAa,EAAE;QACf,QAAQ,EAAE;QACV,SAAS,EAAE;QACX,CAAC;IAGP,KAAK;AACH,aAAO,KAAK,UACV,QAAQ,SAAS,OAAO,IAAI,CAAC,OAAO;QAClC,MAAM,EAAE;QACR,OAAO,EAAE;QACT,OAAO,EAAE;QACT,MAAM,EAAE;QACR,CAAC;IAGP,KAAK;AACH,aAAO,QAAQ,SAAS,WAAW;IAErC,KAAK,uBAAuB;AAC1B,UAAI,CAAC,QAAQ,SAAS,aAAa;AACjC,eAAO;MACT;AACA,YAAM,YAAa,MAAM,MAAiB,YAAW;AACrD,YAAM,QAAQ,QAAQ,SAAS,YAAY,OAAO,KAChD,CAAC,OAAO,EAAE,SAAS,IAAI,YAAW,MAAO,aAAa,EAAE,KAAK,YAAW,MAAO,SAAS;AAE1F,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,UAAU,EAAE,OAAO,+BAA+B,MAAM,KAAK,6CAA4C,CAAE;MACzH;AACA,aAAO,KAAK,UAAU;QACpB,MAAM,MAAM;QACZ,OAAO,MAAM;QACb,WAAW,MAAM;QACjB,QAAQ,MAAM;QACd,SAAS,MAAM;QACf,YAAY,MAAM,cAAc,CAAA;OACjC;IACH;IAEA,KAAK,wBAAwB;AAC3B,UAAI,CAAC,QAAQ,SAAS,aAAa;AACjC,eAAO;MACT;AACA,YAAM,aAAc,MAAM,OAAoB,IAAI,CAAC,MAAM,EAAE,YAAW,CAAE;AACxE,YAAM,UAAU,WAAW,IAAI,CAAC,SAAQ;AACtC,cAAM,QAAQ,QAAQ,SAAS,YAAa,OAAO,KACjD,CAAC,OAAO,EAAE,SAAS,IAAI,YAAW,MAAO,QAAQ,EAAE,KAAK,YAAW,MAAO,IAAI;AAEhF,YAAI,CAAC,OAAO;AACV,iBAAO,EAAE,OAAO,cAAc,IAAI,GAAE;QACtC;AACA,eAAO;UACL,MAAM,MAAM;UACZ,OAAO,MAAM;UACb,WAAW,MAAM;UACjB,QAAQ,MAAM;UACd,SAAS,MAAM;UACf,YAAY,MAAM,cAAc,CAAA;;MAEpC,CAAC;AACD,aAAO,KAAK,UAAU,OAAO;IAC/B;IAEA,KAAK,wBAAwB;AAC3B,UAAI,CAAC,QAAQ,WAAW;AACtB,eAAO;MACT;AACA,YAAM,MAAM,MAAM;AAClB,UAAI;AACF,cAAM,SAAS,MAAM,QAAQ,UAAU,WAAW,GAAG;AACrD,eAAO,KAAK,UAAU,MAAM;MAC9B,SAAS,KAAK;AACZ,eAAO,KAAK,UAAU,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAC,CAAE;MACnF;IACF;IAEA,KAAK,eAAe;AAClB,UAAI,CAAC,QAAQ,WAAW;AACtB,eAAO;MACT;AACA,YAAM,QAAQ,MAAM;AACpB,YAAM,QAAS,MAAM,SAAoB;AACzC,UAAI;AACF,cAAM,SAAS,MAAM,QAAQ,UAAU,WACrC,iBAAiB,KAAK,UAAU,KAAK,EAAE;AAEzC,eAAO,KAAK,UAAU,MAAM;MAC9B,SAAS,KAAK;AACZ,eAAO,KAAK,UAAU,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAC,CAAE;MACnF;IACF;IAEA,KAAK,kBAAkB;AACrB,YAAM,YAAY,MAAM;AACxB,YAAM,MAAM,MAAM,aAAa,QAAQ,IAAI,aAAa,SAAS;AACjE,UAAI,CAAC,KAAK;AACR,eAAO,KAAK,UAAU,EAAE,OAAO,oBAAoB,SAAS,GAAE,CAAE;MAClE;AACA,aAAO,KAAK,UAAU,EAAE,MAAM,WAAW,IAAG,CAAE;IAChD;IAEA,KAAK;AACH,aAAO,KAAK,UACV,QAAQ,IAAI,OAAO,IAAI,CAAC,OAAO;QAC7B,MAAM,EAAE;QACR,MAAM,EAAE;QACR,OAAO,EAAE;QACT,iBAAiB,EAAE;QACnB,QAAQ,EAAE;QACV,CAAC;IAGP,KAAK,iBAAiB;AACpB,YAAM,QAAQ,MAAM;AACpB,aAAO,cAAc,KAAK;IAC5B;IAEA,KAAK;AACH,aAAO,KAAK,UAAU;QACpB,QAAQ;QACR,MAAM,MAAM;QACZ,aAAa,MAAM;QACnB,KAAK,MAAM;QACX,OAAO,MAAM;QACb,iBAAiB,MAAM;QACvB,aAAa,MAAM;QACnB,WAAW,MAAM;QACjB,SAAS,MAAM;OAChB;IAEH,KAAK;AAGH,aAAO,KAAK,UAAU;QACpB,QAAQ;QACR,MAAM,MAAM;QACZ,SAAS;OACV;IAEH,KAAK;AACH,aAAO,KAAK,UAAU;QACpB,QAAQ;QACR,MAAM,MAAM;QACZ,SAAS;OACV;IAEH;AACE,aAAO,KAAK,UAAU,EAAE,OAAO,iBAAiB,QAAQ,GAAE,CAAE;EAChE;AACF;;;AC3RO,IAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2B3B,qBAAoB,CAAE;;;AAIxB,IAAM,kBAAkB;AAElB,IAAO,eAAP,MAAmB;EACf;EAER,YAAY,UAAqB;AAC/B,SAAK,WAAW;EAClB;EAEA,MAAM,IACJ,SACA,cAAuB;AAEvB,UAAM,YAAwB,CAAA;AAC9B,UAAM,WAAsB,CAAC,GAAG,YAAY;AAG5C,UAAM,eAAe,KAAK,kBAAkB,OAAO;AAEnD,aAAS,QAAQ,GAAG,QAAQ,iBAAiB,SAAS;AACpD,YAAM,WAAW,MAAM,KAAK,SAAS,KAAK;QACxC,QAAQ;QACR;QACA,OAAO;OACR;AAED,YAAM,aAAa,SAAS,QAAQ,OAClC,CAAC,MAAsB,EAAE,SAAS,MAAM;AAE1C,YAAM,gBAAgB,SAAS,QAAQ,OACrC,CAAC,MAAyB,EAAE,SAAS,UAAU;AAIjD,UAAI,cAAc,WAAW,GAAG;AAC9B,cAAM,eAAe,WAAW,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI;AAC5D,eAAO,EAAE,UAAU,cAAc,WAAW,SAAQ;MACtD;AAGA,eAAS,KAAK,EAAE,MAAM,aAAa,SAAS,SAAS,QAAO,CAAE;AAG9D,YAAM,cAA8B,CAAA;AACpC,iBAAW,WAAW,eAAe;AACnC,cAAM,SAAS,MAAM,gBAAgB,SAAS,QAAQ,MAAM,QAAQ,KAAK;AAGzE,YAAI,QAAQ,SAAS,iBAAiB;AACpC,gBAAM,SAAS,KAAK,MAAM,MAAM;AAChC,oBAAU,KAAK;YACb,MAAM,OAAO;YACb,aAAa,OAAO;YACpB,KAAK,QAAQ,MAAM;YACnB,OAAO,QAAQ,MAAM;YACrB,iBAAiB,QAAQ,MAAM;YAC/B,aAAa,QAAQ,MAAM;YAC3B,WAAW,QAAQ,MAAM;YACzB,SAAS,QAAQ,MAAM;WACxB;QACH;AAEA,oBAAY,KAAK;UACf,MAAM;UACN,aAAa,QAAQ;UACrB,SAAS;SACS;MACtB;AAGA,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,YAAW,CAAE;IACtD;AAGA,WAAO;MACL,UAAU;MACV;MACA;;EAEJ;EAEQ,kBAAkB,SAAuB;AAC/C,UAAM,QAAQ,CAAC,aAAa;AAG5B,UAAM,KAAK;2BAA8B;AACzC,UAAM,KAAK,eAAe,QAAQ,SAAS,OAAO,MAAM,gBAAgB,QAAQ,SAAS,OAAO,MAAM,YAAY,QAAQ,SAAS,WAAW,MAAM,aAAa;AACjK,UAAM,KAAK,mBAAmB,QAAQ,IAAI,WAAW,QAAQ,QAAQ,IAAI,WAAW,EAAE;AACtF,UAAM,KAAK,iBAAiB,QAAQ,IAAI,OAAO,MAAM,aAAa,QAAQ,IAAI,YAAY,gBAAgB,KAAK,IAAI,KAAK,eAAe,GAAG;AAE1I,QAAI,OAAO,KAAK,QAAQ,IAAI,YAAY,cAAc,EAAE,SAAS,GAAG;AAClE,YAAM,WAAW,OAAO,QAAQ,QAAQ,IAAI,YAAY,cAAc,EACnE,IAAI,CAAC,CAAC,OAAO,MAAM,MAAM,GAAG,KAAK,KAAK,MAAM,EAAE,EAC9C,KAAK,IAAI;AACZ,YAAM,KAAK,sBAAsB,QAAQ,EAAE;IAC7C;AAEA,QAAI,OAAO,KAAK,QAAQ,IAAI,YAAY,sBAAsB,EAAE,SAAS,GAAG;AAC1E,YAAM,OAAO,OAAO,QAAQ,QAAQ,IAAI,YAAY,sBAAsB,EACvE,IAAI,CAAC,CAAC,OAAO,GAAG,MAAM,GAAG,KAAK,KAAK,GAAG,EAAE,EACxC,KAAK,IAAI;AACZ,YAAM,KAAK,uBAAuB,IAAI,EAAE;IAC1C;AAEA,UAAM,KAAK,yBAAyB,QAAQ,IAAI,YAAY,gBAAgB,EAAE;AAC9E,UAAM,KAAK,cAAc,QAAQ,SAAS,UAAU,cAAc,YAAY,EAAE;AAChF,UAAM,KAAK,gBAAgB,QAAQ,YAAY,cAAc,QAAQ,UAAU,cAAc,MAAM,eAAe,EAAE;AAEpH,WAAO,MAAM,KAAK,IAAI;EACxB;;;;ACzKF,OAAO,eAAe;AAWhB,IAAO,oBAAP,MAAwB;EACpB;EACA;EAER,YAAY,QAAgB,QAAgB,8BAA4B;AACtE,SAAK,SAAS,IAAI,UAAU,EAAE,OAAM,CAAE;AACtC,SAAK,QAAQ;EACf;EAEA,MAAM,KAAK,SAKV;AACC,UAAM,QAA0B,QAAQ,MAAM,IAAI,CAAC,OAAO;MACxD,MAAM,EAAE;MACR,aAAa,EAAE;MACf,cAAc;QACZ,MAAM;QACN,YAAY,EAAE,WAAW;QACzB,UAAU,EAAE,WAAW,YAAY,CAAA;;MAErC;AAEF,UAAM,WAAqC,QAAQ,SAAS,IAAI,CAAC,MAAK;AACpE,UAAI,OAAO,EAAE,YAAY,UAAU;AACjC,eAAO,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,QAAO;MAC3C;AACA,YAAM,SAAwC,EAAE,QAAQ,IAAI,CAAC,UAAS;AACpE,YAAI,MAAM,SAAS,QAAQ;AACzB,iBAAO,EAAE,MAAM,QAAiB,MAAO,MAAoB,KAAI;QACjE;AACA,YAAI,MAAM,SAAS,YAAY;AAC7B,gBAAM,KAAK;AACX,iBAAO,EAAE,MAAM,YAAqB,IAAI,GAAG,IAAI,MAAM,GAAG,MAAM,OAAO,GAAG,MAAK;QAC/E;AACA,YAAI,MAAM,SAAS,eAAe;AAChC,gBAAM,KAAK;AACX,iBAAO,EAAE,MAAM,eAAwB,aAAa,GAAG,aAAa,SAAS,GAAG,QAAO;QACzF;AACA,cAAM,IAAI,MAAM,uBAAuB,MAAM,IAAI,EAAE;MACrD,CAAC;AACD,aAAO,EAAE,MAAM,EAAE,MAAM,SAAS,OAAM;IACxC,CAAC;AAED,UAAM,WAAW,MAAM,KAAK,OAAO,SAAS,OAAO;MACjD,OAAO,KAAK;MACZ,YAAY,QAAQ,aAAa;MACjC,QAAQ,QAAQ;MAChB;MACA;KACD;AAED,UAAM,UAA0B,SAAS,QAAQ,IAAI,CAAC,UAAS;AAC7D,UAAI,MAAM,SAAS,QAAQ;AACzB,eAAO,EAAE,MAAM,QAAQ,MAAM,MAAM,KAAI;MACzC;AACA,UAAI,MAAM,SAAS,YAAY;AAC7B,eAAO;UACL,MAAM;UACN,IAAI,MAAM;UACV,MAAM,MAAM;UACZ,OAAO,MAAM;;MAEjB;AACA,YAAM,IAAI,MAAM,0BAA0B,MAAM,IAAI,EAAE;IACxD,CAAC;AAED,WAAO;MACL;MACA,YAAY,SAAS,gBAAgB,aAAa,aAAa;;EAEnE;;;;ACpFF,SAAS,YAAAG,WAAU,WAAW,OAAO,cAAc;AACnD,SAAS,QAAAC,OAAM,WAAAC,gBAAe;AAC9B,SAAS,SAASC,YAAW,aAAa,qBAAqB;AAGzD,SAAU,eACd,WACA,OACA,aACA,WAAkB;AAElB,QAAM,iBAAiB,UAAU,YAAY,gBAAgB,SAAS,OAAO,IAAI,UAAU,YAAY,gBAAgB,CAAC,KAAK;AAC7H,QAAM,QAAQ,CAAC,UAAU,cAAc;AACvC,MAAI;AAAW,UAAM,KAAK,SAAS;AACnC,QAAM,KAAK,GAAG,SAAS,MAAM;AAC7B,SAAO,MAAM,KAAK,GAAG;AACvB;AAEM,SAAU,eAAe,SAK9B;AACC,QAAM,QAAkB,CAAA;AAGxB,MAAI,QAAQ,oBAAoB,QAAQ;AACtC,UAAM,cAAwB,CAAC,iBAAiB,QAAQ,eAAe,GAAG;AAC1E,QAAI,QAAQ,QAAQ,QAAQ,KAAK,SAAS,GAAG;AAC3C,kBAAY,KAAK,SAAS,QAAQ,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG;IAC3E;AACA,UAAM,KAAK;;MAAsB,YAAY,KAAK,SAAS,CAAC;;;CAAa;EAC3E;AAEA,QAAM,KAAK,QAAQ,GAAG;AACtB,SAAO,MAAM,KAAK,IAAI;AACxB;AAQM,SAAU,oBAAoB,SAInC;AACC,QAAM,QAAiC;IACrC,MAAM,QAAQ;IACd,aAAa,QAAQ;;AAGvB,MAAI,QAAQ,WAAW,QAAQ,QAAQ,SAAS,GAAG;AACjD,UAAM,UAAU,QAAQ,QAAQ,IAAI,CAAC,QAAO;AAC1C,YAAM,QAAiC,EAAE,MAAM,IAAI,KAAI;AACvD,UAAI,IAAI;AAAa,cAAM,cAAc,IAAI;AAC7C,UAAI,IAAI,SAAS,IAAI,MAAM,SAAS;AAAG,cAAM,QAAQ,IAAI;AACzD,aAAO;IACT,CAAC;EACH;AAEA,SAAO,cAAc,EAAE,QAAQ,CAAC,KAAK,EAAC,GAAI,EAAE,QAAQ,EAAC,CAAE;AACzD;AAEA,eAAsB,cACpB,aACA,WACA,KAAW;AAEX,QAAM,WAAWF,MAAK,aAAa,SAAS;AAC5C,QAAM,MAAMC,SAAQ,QAAQ,GAAG,EAAE,WAAW,KAAI,CAAE;AAClD,QAAM,UAAU,UAAU,MAAM,MAAM,OAAO;AAC7C,SAAO;AACT;AAEA,eAAsB,gBACpB,aACA,YACA,OAAsE;AAEtE,QAAM,WAAWD,MAAK,aAAa,UAAU;AAE7C,MAAI,WAA0E;IAC5E,SAAS;IACT,QAAQ,CAAA;;AAGV,MAAI;AACF,UAAM,OAAO,QAAQ;AACrB,UAAM,UAAU,MAAMD,UAAS,UAAU,OAAO;AAChD,eAAWG,WAAU,OAAO;AAC5B,QAAI,CAAC,SAAS;AAAQ,eAAS,SAAS,CAAA;EAC1C,QAAQ;AAEN,UAAM,MAAMD,SAAQ,QAAQ,GAAG,EAAE,WAAW,KAAI,CAAE;EACpD;AAGA,QAAM,MAAM,SAAS,OAAQ,UAC3B,CAAC,MAAM,EAAE,SAAS,MAAM,IAAI;AAG9B,QAAM,aAAsC;IAC1C,MAAM,MAAM;IACZ,aAAa,MAAM;;AAErB,MAAI,MAAM,WAAW,MAAM,QAAQ,SAAS,GAAG;AAC7C,eAAW,UAAU,MAAM,QAAQ,IAAI,CAAC,QAAO;AAC7C,YAAM,IAA6B,EAAE,MAAM,IAAI,KAAI;AACnD,UAAI,IAAI;AAAa,UAAE,cAAc,IAAI;AACzC,UAAI,IAAI,SAAS,IAAI,MAAM,SAAS;AAAG,UAAE,QAAQ,IAAI;AACrD,aAAO;IACT,CAAC;EACH;AAEA,MAAI,OAAO,GAAG;AACZ,aAAS,OAAQ,GAAG,IAAI;EAC1B,OAAO;AACL,aAAS,OAAQ,KAAK,UAAU;EAClC;AAEA,QAAM,UAAU,UAAU,cAAc,UAAU,EAAE,QAAQ,EAAC,CAAE,GAAG,OAAO;AACzE,SAAO;AACT;","names":["readFile","join","dirname","readFile","join","dirname","parseYaml"]}
|
package/dist/index.js
CHANGED
|
@@ -96,7 +96,7 @@ program.command("dev").description("Start development server with hot reload").a
|
|
|
96
96
|
detail("Run this command from a yamchart project directory");
|
|
97
97
|
process.exit(2);
|
|
98
98
|
}
|
|
99
|
-
const { runDevServer } = await import("./dev-
|
|
99
|
+
const { runDevServer } = await import("./dev-CBUHSRXH.js");
|
|
100
100
|
await runDevServer(projectDir, {
|
|
101
101
|
port: parseInt(options.port, 10),
|
|
102
102
|
apiOnly: options.apiOnly ?? false,
|
|
@@ -122,8 +122,8 @@ program.command("init").description("Create a new yamchart project").argument("[
|
|
|
122
122
|
newline();
|
|
123
123
|
info(`Run \`cd ${directory === "." ? basename(targetDir) : directory} && yamchart dev\` to start.`);
|
|
124
124
|
});
|
|
125
|
-
program.command("sync-dbt").description("Sync dbt project metadata into AI-readable catalog").option("-s, --source <type>", "Source type: local, github, dbt-cloud", "local").option("-p, --path <dir>", "Path to dbt project (for local source)").option("--repo <repo>", "GitHub repository (for github source)").option("--branch <branch>", "Git branch (for github source)", "main").option("-i, --include <patterns...>", "Include glob patterns").option("-e, --exclude <patterns...>", "Exclude glob patterns").option("-t, --tag <tags...>", "Filter by dbt tags").option("--refresh", "Re-sync using saved configuration").action(async (options) => {
|
|
126
|
-
const { syncDbt, loadSyncConfig } = await import("./sync-dbt-
|
|
125
|
+
program.command("sync-dbt").description("Sync dbt project metadata into AI-readable catalog").option("-s, --source <type>", "Source type: local, github, dbt-cloud", "local").option("-p, --path <dir>", "Path to dbt project (for local source)").option("--repo <repo>", "GitHub repository (for github source)").option("--branch <branch>", "Git branch (for github source)", "main").option("-i, --include <patterns...>", "Include glob patterns").option("-e, --exclude <patterns...>", "Exclude glob patterns").option("-t, --tag <tags...>", "Filter by dbt tags").option("--refresh", "Re-sync using saved configuration").option("--target-database <database>", "Override database in ref() paths (e.g. switch from dev to prod)").action(async (options) => {
|
|
126
|
+
const { syncDbt, loadSyncConfig } = await import("./sync-dbt-22QQKT3A.js");
|
|
127
127
|
const projectDir = await findProjectRoot(process.cwd());
|
|
128
128
|
if (!projectDir) {
|
|
129
129
|
error("yamchart.yaml not found");
|
|
@@ -148,7 +148,8 @@ program.command("sync-dbt").description("Sync dbt project metadata into AI-reada
|
|
|
148
148
|
include: options.include || [],
|
|
149
149
|
exclude: options.exclude || [],
|
|
150
150
|
tags: options.tag || [],
|
|
151
|
-
refresh: options.refresh
|
|
151
|
+
refresh: options.refresh,
|
|
152
|
+
targetDatabase: options.targetDatabase
|
|
152
153
|
});
|
|
153
154
|
spin.stop();
|
|
154
155
|
if (!result.success) {
|
|
@@ -159,6 +160,32 @@ program.command("sync-dbt").description("Sync dbt project metadata into AI-reada
|
|
|
159
160
|
if (result.modelsExcluded > 0) {
|
|
160
161
|
detail(`${result.modelsExcluded} models filtered out`);
|
|
161
162
|
}
|
|
163
|
+
if (result.warnings) {
|
|
164
|
+
for (const w of result.warnings) {
|
|
165
|
+
warning(w);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (!options.targetDatabase) {
|
|
169
|
+
try {
|
|
170
|
+
const { readFile } = await import("fs/promises");
|
|
171
|
+
const { resolveConnection } = await import("./connection-utils-26ZE4KUZ.js");
|
|
172
|
+
const { detectDatabaseMismatch } = await import("./rewrite-database-FDJIXKZ2.js");
|
|
173
|
+
const catalogJsonStr = await readFile(join(projectDir, ".yamchart", "catalog.json"), "utf-8");
|
|
174
|
+
const catalogData = JSON.parse(catalogJsonStr);
|
|
175
|
+
const connection = await resolveConnection(projectDir);
|
|
176
|
+
const connDb = connection.config?.database;
|
|
177
|
+
const mismatch = detectDatabaseMismatch(catalogData.models, connDb);
|
|
178
|
+
if (mismatch.mismatch) {
|
|
179
|
+
warning(
|
|
180
|
+
`Catalog tables reference database "${mismatch.catalogDatabase}" but your default connection uses "${mismatch.connectionDatabase}". Models using ref() may query the wrong database.`
|
|
181
|
+
);
|
|
182
|
+
detail(
|
|
183
|
+
`To fix: yamchart sync-dbt --refresh --target-database ${mismatch.connectionDatabase}`
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
} catch {
|
|
187
|
+
}
|
|
188
|
+
}
|
|
162
189
|
});
|
|
163
190
|
program.command("generate").description("Generate SQL model stubs from dbt catalog").argument("[model]", "Specific model to generate (optional)").option("--yolo", "Skip all prompts, use defaults for everything").action(async (model, options) => {
|
|
164
191
|
const { generate } = await import("./generate-KNER36CB.js");
|
|
@@ -276,7 +303,7 @@ program.command("describe").description("Show columns and types for a table").ar
|
|
|
276
303
|
}
|
|
277
304
|
loadEnvFile(projectDir);
|
|
278
305
|
try {
|
|
279
|
-
const { describeTable } = await import("./describe-
|
|
306
|
+
const { describeTable } = await import("./describe-ZM2JI2XS.js");
|
|
280
307
|
const result = await describeTable(projectDir, table, options);
|
|
281
308
|
if (options.json) {
|
|
282
309
|
console.log(JSON.stringify(result.columns, null, 2));
|
|
@@ -436,7 +463,7 @@ program.command("lineage").description("Show upstream dependencies for a model")
|
|
|
436
463
|
process.exit(2);
|
|
437
464
|
}
|
|
438
465
|
try {
|
|
439
|
-
const { getLineage } = await import("./lineage-
|
|
466
|
+
const { getLineage } = await import("./lineage-XSITWW2O.js");
|
|
440
467
|
const depth = options.depth ? parseInt(options.depth, 10) : void 0;
|
|
441
468
|
const result = await getLineage(projectDir, model, { depth, json: options.json });
|
|
442
469
|
if (options.json) {
|
|
@@ -466,7 +493,7 @@ program.command("advisor").description("AI-powered dbt model advisor \u2014 sugg
|
|
|
466
493
|
process.exit(2);
|
|
467
494
|
}
|
|
468
495
|
loadEnvFile(projectDir);
|
|
469
|
-
const { runAdvisor } = await import("./advisor-
|
|
496
|
+
const { runAdvisor } = await import("./advisor-YW2EBXGR.js");
|
|
470
497
|
await runAdvisor(projectDir, question, {
|
|
471
498
|
top: options.top ? parseInt(options.top, 10) : 5,
|
|
472
499
|
json: options.json,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { resolve, basename, dirname, join } from 'path';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { validateProject } from './commands/validate.js';\nimport { findProjectRoot, loadEnvFile } from './utils/config.js';\nimport pc from 'picocolors';\nimport * as output from './utils/output.js';\nimport { checkForUpdate } from './utils/update-check.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('yamchart')\n .description('Git-native business intelligence dashboards')\n .version(pkg.version);\n\nprogram\n .command('validate')\n .description('Validate configuration files')\n .argument('[path]', 'Path to yamchart project', '.')\n .option('--dry-run', 'Connect to database and test queries with EXPLAIN')\n .option('-c, --connection <name>', 'Connection to use for dry-run')\n .option('--json', 'Output as JSON')\n .action(async (path: string, options: { dryRun?: boolean; connection?: string; json?: boolean }) => {\n const startPath = resolve(path);\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n // Load .env file\n loadEnvFile(projectDir);\n\n if (!options.json) {\n output.header('Validating yamchart project...');\n }\n\n const result = await validateProject(projectDir, {\n dryRun: options.dryRun ?? false,\n connection: options.connection,\n });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n // Print results\n for (const error of result.errors) {\n output.error(error.file);\n output.detail(error.message);\n if (error.suggestion) {\n output.detail(error.suggestion);\n }\n }\n\n for (const warning of result.warnings) {\n output.warning(warning.file);\n output.detail(warning.message);\n }\n\n output.newline();\n\n if (result.success) {\n output.success(`Schema: ${result.stats.passed} passed`);\n } else {\n output.error(`Schema: ${result.stats.passed} passed, ${result.stats.failed} failed`);\n }\n\n if (result.dryRunStats) {\n output.newline();\n if (result.dryRunStats.failed === 0) {\n output.success(`Queries: ${result.dryRunStats.passed} passed (EXPLAIN OK)`);\n } else {\n output.error(`Queries: ${result.dryRunStats.passed} passed, ${result.dryRunStats.failed} failed`);\n }\n }\n\n output.newline();\n\n if (result.success) {\n output.success('Validation passed');\n } else {\n output.error(`Validation failed with ${result.errors.length} error(s)`);\n }\n }\n\n process.exit(result.success ? 0 : 1);\n });\n\nprogram\n .command('dev')\n .description('Start development server with hot reload')\n .argument('[path]', 'Path to yamchart project', '.')\n .option('-p, --port <number>', 'Port to listen on', '3001')\n .option('--api-only', 'Only serve API, no web UI')\n .option('--no-open', 'Do not open browser automatically')\n .action(async (path: string, options: { port: string; apiOnly?: boolean; open: boolean }) => {\n const startPath = resolve(path);\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n const { runDevServer } = await import('./commands/dev.js');\n\n await runDevServer(projectDir, {\n port: parseInt(options.port, 10),\n apiOnly: options.apiOnly ?? false,\n open: options.open,\n });\n });\n\nprogram\n .command('init')\n .description('Create a new yamchart project')\n .argument('[directory]', 'Target directory', '.')\n .option('--example', 'Create full example project with sample database')\n .option('--empty', 'Create only yamchart.yaml (no connections, models, or charts)')\n .option('--force', 'Overwrite existing files')\n .action(async (directory: string, options: { example?: boolean; empty?: boolean; force?: boolean }) => {\n const { initProject } = await import('./commands/init.js');\n const targetDir = resolve(directory);\n\n const result = await initProject(targetDir, options);\n\n if (!result.success) {\n output.error(result.error || 'Failed to create project');\n process.exit(1);\n }\n\n output.newline();\n output.success(`Created ${directory === '.' ? basename(targetDir) : directory}/`);\n for (const file of result.files.slice(0, 10)) {\n output.detail(file);\n }\n if (result.files.length > 10) {\n output.detail(`... and ${result.files.length - 10} more files`);\n }\n output.newline();\n output.info(`Run \\`cd ${directory === '.' ? basename(targetDir) : directory} && yamchart dev\\` to start.`);\n });\n\nprogram\n .command('sync-dbt')\n .description('Sync dbt project metadata into AI-readable catalog')\n .option('-s, --source <type>', 'Source type: local, github, dbt-cloud', 'local')\n .option('-p, --path <dir>', 'Path to dbt project (for local source)')\n .option('--repo <repo>', 'GitHub repository (for github source)')\n .option('--branch <branch>', 'Git branch (for github source)', 'main')\n .option('-i, --include <patterns...>', 'Include glob patterns')\n .option('-e, --exclude <patterns...>', 'Exclude glob patterns')\n .option('-t, --tag <tags...>', 'Filter by dbt tags')\n .option('--refresh', 'Re-sync using saved configuration')\n .action(async (options: {\n source: 'local' | 'github' | 'dbt-cloud';\n path?: string;\n repo?: string;\n branch?: string;\n include?: string[];\n exclude?: string[];\n tag?: string[];\n refresh?: boolean;\n }) => {\n const { syncDbt, loadSyncConfig } = await import('./commands/sync-dbt.js');\n\n // Find project root\n const projectDir = await findProjectRoot(process.cwd());\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n // Handle refresh mode\n if (options.refresh) {\n const savedConfig = await loadSyncConfig(projectDir);\n if (!savedConfig) {\n output.error('No saved sync config found');\n output.detail('Run sync-dbt without --refresh first');\n process.exit(1);\n }\n output.info(`Re-syncing from ${savedConfig.source}:${savedConfig.path || savedConfig.repo}`);\n }\n\n const spin = output.spinner('Syncing dbt metadata...');\n\n const result = await syncDbt(projectDir, {\n source: options.source,\n path: options.path,\n repo: options.repo,\n branch: options.branch,\n include: options.include || [],\n exclude: options.exclude || [],\n tags: options.tag || [],\n refresh: options.refresh,\n });\n\n spin.stop();\n\n if (!result.success) {\n output.error(result.error || 'Sync failed');\n process.exit(1);\n }\n\n output.success(`Synced ${result.modelsIncluded} models to .yamchart/catalog.md`);\n if (result.modelsExcluded > 0) {\n output.detail(`${result.modelsExcluded} models filtered out`);\n }\n });\n\nprogram\n .command('generate')\n .description('Generate SQL model stubs from dbt catalog')\n .argument('[model]', 'Specific model to generate (optional)')\n .option('--yolo', 'Skip all prompts, use defaults for everything')\n .action(async (model: string | undefined, options: { yolo?: boolean }) => {\n const { generate } = await import('./commands/generate.js');\n\n const projectDir = await findProjectRoot(process.cwd());\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n const result = await generate(projectDir, {\n model,\n yolo: options.yolo,\n });\n\n if (!result.success) {\n output.error(result.error || 'Generate failed');\n process.exit(1);\n }\n\n output.success(`Generated ${result.filesCreated} model stubs`);\n if (result.filesSkipped > 0) {\n output.detail(`${result.filesSkipped} files skipped`);\n }\n });\n\nprogram\n .command('test')\n .description('Run model tests (@returns schema checks and @tests data assertions)')\n .argument('[model]', 'Specific model to test (optional, tests all if omitted)')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (model: string | undefined, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { testProject, formatTestOutput } = await import('./commands/test.js');\n const result = await testProject(projectDir, model, {\n connection: options.connection,\n json: options.json,\n });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n formatTestOutput(result, result.connectionName);\n }\n\n process.exit(result.success ? 0 : 1);\n } catch (err) {\n if (options.json) {\n console.log(\n JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }),\n );\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(2);\n }\n });\n\nprogram\n .command('update')\n .description('Check for yamchart updates')\n .action(async () => {\n const { runUpdate } = await import('./commands/update.js');\n await runUpdate(pkg.version);\n });\n\nprogram\n .command('reset-password')\n .description('Reset a user password (requires auth to be enabled)')\n .requiredOption('-e, --email <email>', 'Email address of the user')\n .action(async (options: { email: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n const { resetPassword } = await import('./commands/reset-password.js');\n await resetPassword(projectDir, options.email);\n });\n\nprogram\n .command('tables')\n .description('List tables and views in the connected database')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-s, --schema <name>', 'Filter to schema')\n .option('-d, --database <name>', 'Filter to database (Snowflake/Databricks)')\n .option('--json', 'Output as JSON')\n .action(async (options: { connection?: string; schema?: string; database?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { listTables } = await import('./commands/tables.js');\n const result = await listTables(projectDir, options);\n\n if (options.json) {\n console.log(JSON.stringify(result.tables, null, 2));\n } else {\n output.header(`Tables in ${result.connectionName} (${result.connectionType})`);\n if (result.tables.length === 0) {\n output.info('No tables found');\n } else {\n for (const table of result.tables) {\n const schema = table.schema ? `${table.schema}.` : '';\n const typeLabel = table.type === 'VIEW' ? pc.dim(' (view)') : '';\n console.log(` ${schema}${table.name}${typeLabel}`);\n }\n output.newline();\n output.info(`${result.tables.length} table(s) found (${result.durationMs.toFixed(0)}ms)`);\n }\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('describe')\n .description('Show columns and types for a table')\n .argument('<table>', 'Table name (can be fully qualified, e.g. schema.table)')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (table: string, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { describeTable } = await import('./commands/describe.js');\n const result = await describeTable(projectDir, table, options);\n\n if (options.json) {\n console.log(JSON.stringify(result.columns, null, 2));\n } else {\n if (result.resolvedFrom) {\n output.detail(`Resolved \"${result.resolvedFrom}\" → ${result.table}`);\n }\n output.header(`${result.table} (${result.connectionName})`);\n\n const nameWidth = Math.max(4, ...result.columns.map((c) => c.name.length));\n const typeWidth = Math.max(4, ...result.columns.map((c) => c.type.length));\n\n console.log(` ${'name'.padEnd(nameWidth)} ${'type'.padEnd(typeWidth)} nullable`);\n console.log(` ${'─'.repeat(nameWidth)} ${'─'.repeat(typeWidth)} ${'─'.repeat(8)}`);\n\n for (const col of result.columns) {\n const nullable = col.nullable === 'YES' ? pc.dim('yes') : 'no';\n console.log(` ${col.name.padEnd(nameWidth)} ${pc.dim(col.type.padEnd(typeWidth))} ${nullable}`);\n }\n\n output.newline();\n output.info(`${result.columns.length} column(s) (${result.durationMs.toFixed(0)}ms)`);\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('query')\n .description('Execute SQL against a connection')\n .argument('<sql>', 'SQL query to execute')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .option('-l, --limit <number>', 'Max rows to return (default: 100)')\n .action(async (sql: string, options: { connection?: string; json?: boolean; limit?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { executeQuery } = await import('./commands/query.js');\n const { formatTable, formatJSON } = await import('./commands/connection-utils.js');\n\n const limit = options.limit ? parseInt(options.limit, 10) : undefined;\n const result = await executeQuery(projectDir, sql, {\n connection: options.connection,\n json: options.json,\n limit,\n });\n\n if (options.json) {\n console.log(formatJSON(result));\n } else {\n console.log(formatTable(result));\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('sample')\n .description('Show sample rows from a table or dbt model')\n .argument('<table>', 'Table name or dbt model name')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-l, --limit <number>', 'Rows to show (default: 5)')\n .option('--json', 'Output as JSON')\n .action(async (table: string, options: { connection?: string; json?: boolean; limit?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { sampleTable } = await import('./commands/sample.js');\n const { formatTable, formatJSON } = await import('./commands/connection-utils.js');\n\n const limit = options.limit ? parseInt(options.limit, 10) : undefined;\n const result = await sampleTable(projectDir, table, {\n connection: options.connection,\n json: options.json,\n limit,\n });\n\n if (options.json) {\n console.log(formatJSON(result));\n } else {\n if (result.resolvedFrom) {\n output.detail(`Resolved \"${result.resolvedFrom}\" → ${result.table}`);\n }\n console.log(formatTable(result));\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('search')\n .description('Search for tables and columns by keyword')\n .argument('<keyword>', 'Keyword to search for')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (keyword: string, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { searchDatabase } = await import('./commands/search.js');\n const result = await searchDatabase(projectDir, keyword, options);\n\n if (options.json) {\n console.log(JSON.stringify(result.results, null, 2));\n } else {\n output.header(`Search results for \"${result.keyword}\" in ${result.connectionName} (${result.connectionType})`);\n\n const tables = result.results.filter((r) => r.type === 'table');\n const columns = result.results.filter((r) => r.type === 'column');\n\n if (tables.length > 0) {\n output.newline();\n console.log(' Tables:');\n for (const t of tables) {\n const qualified = t.schema ? `${t.schema}.${t.table}` : t.table;\n console.log(` ${qualified}`);\n }\n }\n\n if (columns.length > 0) {\n output.newline();\n console.log(' Columns:');\n const nameWidth = Math.max(...columns.map((c) => {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n return qualified.length;\n }));\n for (const c of columns) {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n const colType = c.columnType ? pc.dim(c.columnType) : '';\n console.log(` ${qualified.padEnd(nameWidth + 2)}${colType}`);\n }\n }\n\n if (result.results.length === 0) {\n output.detail('No matches found');\n }\n\n output.newline();\n output.info(`${result.results.length} result(s) (${result.durationMs.toFixed(0)}ms)`);\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('sync-warehouse')\n .description('Sync warehouse table metadata into the catalog')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-s, --schema <schemas>', 'Comma-separated schemas to sync')\n .option('-d, --database <name>', 'Database to sync (Snowflake/Databricks)')\n .option('--skip-samples', 'Skip sample row collection')\n .option('--refresh', 'Re-run with saved connection/schema config')\n .option('--full', 'Force full re-sync (ignore incremental state)')\n .option('--json', 'Output sync summary as JSON')\n .action(async (options) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { runSyncWarehouse } = await import('./commands/sync-warehouse.js');\n await runSyncWarehouse(projectDir, options);\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('lineage')\n .description('Show upstream dependencies for a model')\n .argument('<model>', 'Model name to trace lineage for')\n .option('--depth <n>', 'Maximum depth to trace (default: unlimited)')\n .option('--json', 'Output as JSON')\n .action(async (model: string, options: { depth?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n try {\n const { getLineage } = await import('./commands/lineage.js');\n const depth = options.depth ? parseInt(options.depth, 10) : undefined;\n const result = await getLineage(projectDir, model, { depth, json: options.json });\n\n if (options.json) {\n console.log(JSON.stringify(result.tree, null, 2));\n } else {\n console.log(result.rendered);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('ENOENT')) {\n output.error('No catalog found. Run `yamchart sync-dbt` first.');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\nprogram\n .command('advisor')\n .description('AI-powered dbt model advisor — suggests improvements informed by your BI layer')\n .argument('[question]', 'Question to ask, or \"audit\" for comprehensive analysis')\n .option('--top <n>', 'Limit audit suggestions (default: 5)')\n .option('--json', 'Output as JSON')\n .option('--dbt-path <path>', 'Override the synced dbt project path')\n .option('-c, --connection <name>', 'Connection to use for warehouse introspection')\n .action(async (question: string | undefined, options: { top?: string; json?: boolean; dbtPath?: string; connection?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n const { runAdvisor } = await import('./commands/advisor.js');\n await runAdvisor(projectDir, question, {\n top: options.top ? parseInt(options.top, 10) : 5,\n json: options.json,\n dbtPath: options.dbtPath,\n connection: options.connection,\n });\n });\n\nprogram.parse();\n\n// Passive update check — runs in background, prints on exit if outdated\nlet updateNotification: string | null = null;\n\ncheckForUpdate(pkg.version).then((update) => {\n if (update) {\n updateNotification = `\\n Update available: ${update.current} → ${update.latest}\\n Run: yamchart update to see what's new\\n`;\n }\n});\n\nprocess.on('exit', () => {\n if (updateNotification) {\n // Use dim styling so it doesn't compete with command output\n console.error(`\\n${pc.dim(updateNotification)}`);\n }\n});\n"],"mappings":"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","names":["error","warning"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { resolve, basename, dirname, join } from 'path';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { validateProject } from './commands/validate.js';\nimport { findProjectRoot, loadEnvFile } from './utils/config.js';\nimport pc from 'picocolors';\nimport * as output from './utils/output.js';\nimport { checkForUpdate } from './utils/update-check.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('yamchart')\n .description('Git-native business intelligence dashboards')\n .version(pkg.version);\n\nprogram\n .command('validate')\n .description('Validate configuration files')\n .argument('[path]', 'Path to yamchart project', '.')\n .option('--dry-run', 'Connect to database and test queries with EXPLAIN')\n .option('-c, --connection <name>', 'Connection to use for dry-run')\n .option('--json', 'Output as JSON')\n .action(async (path: string, options: { dryRun?: boolean; connection?: string; json?: boolean }) => {\n const startPath = resolve(path);\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n // Load .env file\n loadEnvFile(projectDir);\n\n if (!options.json) {\n output.header('Validating yamchart project...');\n }\n\n const result = await validateProject(projectDir, {\n dryRun: options.dryRun ?? false,\n connection: options.connection,\n });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n // Print results\n for (const error of result.errors) {\n output.error(error.file);\n output.detail(error.message);\n if (error.suggestion) {\n output.detail(error.suggestion);\n }\n }\n\n for (const warning of result.warnings) {\n output.warning(warning.file);\n output.detail(warning.message);\n }\n\n output.newline();\n\n if (result.success) {\n output.success(`Schema: ${result.stats.passed} passed`);\n } else {\n output.error(`Schema: ${result.stats.passed} passed, ${result.stats.failed} failed`);\n }\n\n if (result.dryRunStats) {\n output.newline();\n if (result.dryRunStats.failed === 0) {\n output.success(`Queries: ${result.dryRunStats.passed} passed (EXPLAIN OK)`);\n } else {\n output.error(`Queries: ${result.dryRunStats.passed} passed, ${result.dryRunStats.failed} failed`);\n }\n }\n\n output.newline();\n\n if (result.success) {\n output.success('Validation passed');\n } else {\n output.error(`Validation failed with ${result.errors.length} error(s)`);\n }\n }\n\n process.exit(result.success ? 0 : 1);\n });\n\nprogram\n .command('dev')\n .description('Start development server with hot reload')\n .argument('[path]', 'Path to yamchart project', '.')\n .option('-p, --port <number>', 'Port to listen on', '3001')\n .option('--api-only', 'Only serve API, no web UI')\n .option('--no-open', 'Do not open browser automatically')\n .action(async (path: string, options: { port: string; apiOnly?: boolean; open: boolean }) => {\n const startPath = resolve(path);\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n const { runDevServer } = await import('./commands/dev.js');\n\n await runDevServer(projectDir, {\n port: parseInt(options.port, 10),\n apiOnly: options.apiOnly ?? false,\n open: options.open,\n });\n });\n\nprogram\n .command('init')\n .description('Create a new yamchart project')\n .argument('[directory]', 'Target directory', '.')\n .option('--example', 'Create full example project with sample database')\n .option('--empty', 'Create only yamchart.yaml (no connections, models, or charts)')\n .option('--force', 'Overwrite existing files')\n .action(async (directory: string, options: { example?: boolean; empty?: boolean; force?: boolean }) => {\n const { initProject } = await import('./commands/init.js');\n const targetDir = resolve(directory);\n\n const result = await initProject(targetDir, options);\n\n if (!result.success) {\n output.error(result.error || 'Failed to create project');\n process.exit(1);\n }\n\n output.newline();\n output.success(`Created ${directory === '.' ? basename(targetDir) : directory}/`);\n for (const file of result.files.slice(0, 10)) {\n output.detail(file);\n }\n if (result.files.length > 10) {\n output.detail(`... and ${result.files.length - 10} more files`);\n }\n output.newline();\n output.info(`Run \\`cd ${directory === '.' ? basename(targetDir) : directory} && yamchart dev\\` to start.`);\n });\n\nprogram\n .command('sync-dbt')\n .description('Sync dbt project metadata into AI-readable catalog')\n .option('-s, --source <type>', 'Source type: local, github, dbt-cloud', 'local')\n .option('-p, --path <dir>', 'Path to dbt project (for local source)')\n .option('--repo <repo>', 'GitHub repository (for github source)')\n .option('--branch <branch>', 'Git branch (for github source)', 'main')\n .option('-i, --include <patterns...>', 'Include glob patterns')\n .option('-e, --exclude <patterns...>', 'Exclude glob patterns')\n .option('-t, --tag <tags...>', 'Filter by dbt tags')\n .option('--refresh', 'Re-sync using saved configuration')\n .option('--target-database <database>', 'Override database in ref() paths (e.g. switch from dev to prod)')\n .action(async (options: {\n source: 'local' | 'github' | 'dbt-cloud';\n path?: string;\n repo?: string;\n branch?: string;\n include?: string[];\n exclude?: string[];\n tag?: string[];\n refresh?: boolean;\n targetDatabase?: string;\n }) => {\n const { syncDbt, loadSyncConfig } = await import('./commands/sync-dbt.js');\n\n // Find project root\n const projectDir = await findProjectRoot(process.cwd());\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n // Handle refresh mode\n if (options.refresh) {\n const savedConfig = await loadSyncConfig(projectDir);\n if (!savedConfig) {\n output.error('No saved sync config found');\n output.detail('Run sync-dbt without --refresh first');\n process.exit(1);\n }\n output.info(`Re-syncing from ${savedConfig.source}:${savedConfig.path || savedConfig.repo}`);\n }\n\n const spin = output.spinner('Syncing dbt metadata...');\n\n const result = await syncDbt(projectDir, {\n source: options.source,\n path: options.path,\n repo: options.repo,\n branch: options.branch,\n include: options.include || [],\n exclude: options.exclude || [],\n tags: options.tag || [],\n refresh: options.refresh,\n targetDatabase: options.targetDatabase,\n });\n\n spin.stop();\n\n if (!result.success) {\n output.error(result.error || 'Sync failed');\n process.exit(1);\n }\n\n output.success(`Synced ${result.modelsIncluded} models to .yamchart/catalog.md`);\n if (result.modelsExcluded > 0) {\n output.detail(`${result.modelsExcluded} models filtered out`);\n }\n\n // Show lineage warnings\n if (result.warnings) {\n for (const w of result.warnings) {\n output.warning(w);\n }\n }\n\n // Check for database mismatch (skip if --target-database was used)\n if (!options.targetDatabase) {\n try {\n const { readFile } = await import('fs/promises');\n const { resolveConnection } = await import('./commands/connection-utils.js');\n const { detectDatabaseMismatch } = await import('./dbt/rewrite-database.js');\n const catalogJsonStr = await readFile(join(projectDir, '.yamchart', 'catalog.json'), 'utf-8');\n const catalogData = JSON.parse(catalogJsonStr);\n const connection = await resolveConnection(projectDir);\n // Extract database from connection config (varies by type)\n const connDb = (connection as Record<string, any>).config?.database as string | undefined;\n const mismatch = detectDatabaseMismatch(catalogData.models, connDb);\n if (mismatch.mismatch) {\n output.warning(\n `Catalog tables reference database \"${mismatch.catalogDatabase}\" but your default ` +\n `connection uses \"${mismatch.connectionDatabase}\". Models using ref() may query the wrong database.`\n );\n output.detail(\n `To fix: yamchart sync-dbt --refresh --target-database ${mismatch.connectionDatabase}`\n );\n }\n } catch {\n // Connection not configured or unreadable — skip silently\n }\n }\n });\n\nprogram\n .command('generate')\n .description('Generate SQL model stubs from dbt catalog')\n .argument('[model]', 'Specific model to generate (optional)')\n .option('--yolo', 'Skip all prompts, use defaults for everything')\n .action(async (model: string | undefined, options: { yolo?: boolean }) => {\n const { generate } = await import('./commands/generate.js');\n\n const projectDir = await findProjectRoot(process.cwd());\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n const result = await generate(projectDir, {\n model,\n yolo: options.yolo,\n });\n\n if (!result.success) {\n output.error(result.error || 'Generate failed');\n process.exit(1);\n }\n\n output.success(`Generated ${result.filesCreated} model stubs`);\n if (result.filesSkipped > 0) {\n output.detail(`${result.filesSkipped} files skipped`);\n }\n });\n\nprogram\n .command('test')\n .description('Run model tests (@returns schema checks and @tests data assertions)')\n .argument('[model]', 'Specific model to test (optional, tests all if omitted)')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (model: string | undefined, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { testProject, formatTestOutput } = await import('./commands/test.js');\n const result = await testProject(projectDir, model, {\n connection: options.connection,\n json: options.json,\n });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n formatTestOutput(result, result.connectionName);\n }\n\n process.exit(result.success ? 0 : 1);\n } catch (err) {\n if (options.json) {\n console.log(\n JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }),\n );\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(2);\n }\n });\n\nprogram\n .command('update')\n .description('Check for yamchart updates')\n .action(async () => {\n const { runUpdate } = await import('./commands/update.js');\n await runUpdate(pkg.version);\n });\n\nprogram\n .command('reset-password')\n .description('Reset a user password (requires auth to be enabled)')\n .requiredOption('-e, --email <email>', 'Email address of the user')\n .action(async (options: { email: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n const { resetPassword } = await import('./commands/reset-password.js');\n await resetPassword(projectDir, options.email);\n });\n\nprogram\n .command('tables')\n .description('List tables and views in the connected database')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-s, --schema <name>', 'Filter to schema')\n .option('-d, --database <name>', 'Filter to database (Snowflake/Databricks)')\n .option('--json', 'Output as JSON')\n .action(async (options: { connection?: string; schema?: string; database?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { listTables } = await import('./commands/tables.js');\n const result = await listTables(projectDir, options);\n\n if (options.json) {\n console.log(JSON.stringify(result.tables, null, 2));\n } else {\n output.header(`Tables in ${result.connectionName} (${result.connectionType})`);\n if (result.tables.length === 0) {\n output.info('No tables found');\n } else {\n for (const table of result.tables) {\n const schema = table.schema ? `${table.schema}.` : '';\n const typeLabel = table.type === 'VIEW' ? pc.dim(' (view)') : '';\n console.log(` ${schema}${table.name}${typeLabel}`);\n }\n output.newline();\n output.info(`${result.tables.length} table(s) found (${result.durationMs.toFixed(0)}ms)`);\n }\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('describe')\n .description('Show columns and types for a table')\n .argument('<table>', 'Table name (can be fully qualified, e.g. schema.table)')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (table: string, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { describeTable } = await import('./commands/describe.js');\n const result = await describeTable(projectDir, table, options);\n\n if (options.json) {\n console.log(JSON.stringify(result.columns, null, 2));\n } else {\n if (result.resolvedFrom) {\n output.detail(`Resolved \"${result.resolvedFrom}\" → ${result.table}`);\n }\n output.header(`${result.table} (${result.connectionName})`);\n\n const nameWidth = Math.max(4, ...result.columns.map((c) => c.name.length));\n const typeWidth = Math.max(4, ...result.columns.map((c) => c.type.length));\n\n console.log(` ${'name'.padEnd(nameWidth)} ${'type'.padEnd(typeWidth)} nullable`);\n console.log(` ${'─'.repeat(nameWidth)} ${'─'.repeat(typeWidth)} ${'─'.repeat(8)}`);\n\n for (const col of result.columns) {\n const nullable = col.nullable === 'YES' ? pc.dim('yes') : 'no';\n console.log(` ${col.name.padEnd(nameWidth)} ${pc.dim(col.type.padEnd(typeWidth))} ${nullable}`);\n }\n\n output.newline();\n output.info(`${result.columns.length} column(s) (${result.durationMs.toFixed(0)}ms)`);\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('query')\n .description('Execute SQL against a connection')\n .argument('<sql>', 'SQL query to execute')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .option('-l, --limit <number>', 'Max rows to return (default: 100)')\n .action(async (sql: string, options: { connection?: string; json?: boolean; limit?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { executeQuery } = await import('./commands/query.js');\n const { formatTable, formatJSON } = await import('./commands/connection-utils.js');\n\n const limit = options.limit ? parseInt(options.limit, 10) : undefined;\n const result = await executeQuery(projectDir, sql, {\n connection: options.connection,\n json: options.json,\n limit,\n });\n\n if (options.json) {\n console.log(formatJSON(result));\n } else {\n console.log(formatTable(result));\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('sample')\n .description('Show sample rows from a table or dbt model')\n .argument('<table>', 'Table name or dbt model name')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-l, --limit <number>', 'Rows to show (default: 5)')\n .option('--json', 'Output as JSON')\n .action(async (table: string, options: { connection?: string; json?: boolean; limit?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { sampleTable } = await import('./commands/sample.js');\n const { formatTable, formatJSON } = await import('./commands/connection-utils.js');\n\n const limit = options.limit ? parseInt(options.limit, 10) : undefined;\n const result = await sampleTable(projectDir, table, {\n connection: options.connection,\n json: options.json,\n limit,\n });\n\n if (options.json) {\n console.log(formatJSON(result));\n } else {\n if (result.resolvedFrom) {\n output.detail(`Resolved \"${result.resolvedFrom}\" → ${result.table}`);\n }\n console.log(formatTable(result));\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('search')\n .description('Search for tables and columns by keyword')\n .argument('<keyword>', 'Keyword to search for')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (keyword: string, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { searchDatabase } = await import('./commands/search.js');\n const result = await searchDatabase(projectDir, keyword, options);\n\n if (options.json) {\n console.log(JSON.stringify(result.results, null, 2));\n } else {\n output.header(`Search results for \"${result.keyword}\" in ${result.connectionName} (${result.connectionType})`);\n\n const tables = result.results.filter((r) => r.type === 'table');\n const columns = result.results.filter((r) => r.type === 'column');\n\n if (tables.length > 0) {\n output.newline();\n console.log(' Tables:');\n for (const t of tables) {\n const qualified = t.schema ? `${t.schema}.${t.table}` : t.table;\n console.log(` ${qualified}`);\n }\n }\n\n if (columns.length > 0) {\n output.newline();\n console.log(' Columns:');\n const nameWidth = Math.max(...columns.map((c) => {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n return qualified.length;\n }));\n for (const c of columns) {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n const colType = c.columnType ? pc.dim(c.columnType) : '';\n console.log(` ${qualified.padEnd(nameWidth + 2)}${colType}`);\n }\n }\n\n if (result.results.length === 0) {\n output.detail('No matches found');\n }\n\n output.newline();\n output.info(`${result.results.length} result(s) (${result.durationMs.toFixed(0)}ms)`);\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('sync-warehouse')\n .description('Sync warehouse table metadata into the catalog')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-s, --schema <schemas>', 'Comma-separated schemas to sync')\n .option('-d, --database <name>', 'Database to sync (Snowflake/Databricks)')\n .option('--skip-samples', 'Skip sample row collection')\n .option('--refresh', 'Re-run with saved connection/schema config')\n .option('--full', 'Force full re-sync (ignore incremental state)')\n .option('--json', 'Output sync summary as JSON')\n .action(async (options) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { runSyncWarehouse } = await import('./commands/sync-warehouse.js');\n await runSyncWarehouse(projectDir, options);\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('lineage')\n .description('Show upstream dependencies for a model')\n .argument('<model>', 'Model name to trace lineage for')\n .option('--depth <n>', 'Maximum depth to trace (default: unlimited)')\n .option('--json', 'Output as JSON')\n .action(async (model: string, options: { depth?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n try {\n const { getLineage } = await import('./commands/lineage.js');\n const depth = options.depth ? parseInt(options.depth, 10) : undefined;\n const result = await getLineage(projectDir, model, { depth, json: options.json });\n\n if (options.json) {\n console.log(JSON.stringify(result.tree, null, 2));\n } else {\n console.log(result.rendered);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('ENOENT')) {\n output.error('No catalog found. Run `yamchart sync-dbt` first.');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\nprogram\n .command('advisor')\n .description('AI-powered dbt model advisor — suggests improvements informed by your BI layer')\n .argument('[question]', 'Question to ask, or \"audit\" for comprehensive analysis')\n .option('--top <n>', 'Limit audit suggestions (default: 5)')\n .option('--json', 'Output as JSON')\n .option('--dbt-path <path>', 'Override the synced dbt project path')\n .option('-c, --connection <name>', 'Connection to use for warehouse introspection')\n .action(async (question: string | undefined, options: { top?: string; json?: boolean; dbtPath?: string; connection?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n const { runAdvisor } = await import('./commands/advisor.js');\n await runAdvisor(projectDir, question, {\n top: options.top ? parseInt(options.top, 10) : 5,\n json: options.json,\n dbtPath: options.dbtPath,\n connection: options.connection,\n });\n });\n\nprogram.parse();\n\n// Passive update check — runs in background, prints on exit if outdated\nlet updateNotification: string | null = null;\n\ncheckForUpdate(pkg.version).then((update) => {\n if (update) {\n updateNotification = `\\n Update available: ${update.current} → ${update.latest}\\n Run: yamchart update to see what's new\\n`;\n }\n});\n\nprocess.on('exit', () => {\n if (updateNotification) {\n // Use dim styling so it doesn't compete with command output\n console.error(`\\n${pc.dim(updateNotification)}`);\n }\n});\n"],"mappings":"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","names":["error","warning"]}
|