@kaelio/ktx 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (875) hide show
  1. package/assets/python/{kaelio_ktx-0.5.0-py3-none-any.whl → kaelio_ktx-0.7.0-py3-none-any.whl} +0 -0
  2. package/assets/python/manifest.json +4 -4
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/clack.d.ts +8 -0
  5. package/dist/clack.js +14 -0
  6. package/dist/connection.js +2 -9
  7. package/dist/connectors/bigquery/connector.d.ts +6 -1
  8. package/dist/connectors/bigquery/connector.js +38 -9
  9. package/dist/connectors/bigquery/dialect.d.ts +11 -9
  10. package/dist/connectors/bigquery/dialect.js +25 -45
  11. package/dist/connectors/clickhouse/connector.d.ts +5 -0
  12. package/dist/connectors/clickhouse/connector.js +36 -3
  13. package/dist/connectors/clickhouse/dialect.d.ts +11 -12
  14. package/dist/connectors/clickhouse/dialect.js +25 -100
  15. package/dist/connectors/mysql/connector.d.ts +7 -1
  16. package/dist/connectors/mysql/connector.js +67 -9
  17. package/dist/connectors/mysql/dialect.d.ts +11 -9
  18. package/dist/connectors/mysql/dialect.js +25 -43
  19. package/dist/connectors/postgres/connector.d.ts +6 -0
  20. package/dist/connectors/postgres/connector.js +67 -12
  21. package/dist/connectors/postgres/dialect.d.ts +11 -9
  22. package/dist/connectors/postgres/dialect.js +26 -35
  23. package/dist/connectors/snowflake/connector.d.ts +8 -3
  24. package/dist/connectors/snowflake/connector.js +39 -20
  25. package/dist/connectors/snowflake/dialect.d.ts +11 -9
  26. package/dist/connectors/snowflake/dialect.js +25 -24
  27. package/dist/connectors/sqlite/connector.d.ts +3 -1
  28. package/dist/connectors/sqlite/connector.js +23 -3
  29. package/dist/connectors/sqlite/dialect.d.ts +11 -9
  30. package/dist/connectors/sqlite/dialect.js +25 -29
  31. package/dist/connectors/sqlserver/connector.d.ts +6 -0
  32. package/dist/connectors/sqlserver/connector.js +56 -9
  33. package/dist/connectors/sqlserver/dialect.d.ts +11 -10
  34. package/dist/connectors/sqlserver/dialect.js +24 -40
  35. package/dist/context/connections/connection-type.d.ts +1 -1
  36. package/dist/context/connections/dialect-helpers.d.ts +9 -0
  37. package/dist/context/connections/dialect-helpers.js +67 -0
  38. package/dist/context/connections/dialects.d.ts +23 -5
  39. package/dist/context/connections/dialects.js +18 -56
  40. package/dist/context/connections/drivers.d.ts +23 -0
  41. package/dist/context/connections/drivers.js +171 -0
  42. package/dist/context/connections/local-query-executor.js +25 -7
  43. package/dist/context/connections/local-warehouse-descriptor.js +0 -2
  44. package/dist/context/connections/postgres-query-executor.js +1 -1
  45. package/dist/context/connections/sqlite-query-executor.js +1 -1
  46. package/dist/context/ingest/adapters/historic-sql/chunk-unified.js +1 -1
  47. package/dist/context/ingest/adapters/historic-sql/connection-dialect.js +11 -7
  48. package/dist/context/ingest/adapters/historic-sql/evidence-tool.d.ts +1 -1
  49. package/dist/context/ingest/adapters/historic-sql/evidence-tool.js +8 -5
  50. package/dist/context/ingest/adapters/historic-sql/evidence.d.ts +4 -4
  51. package/dist/context/ingest/adapters/historic-sql/evidence.js +2 -2
  52. package/dist/context/ingest/adapters/historic-sql/projection.js +5 -2
  53. package/dist/context/ingest/adapters/live-database/daemon-introspection.js +1 -1
  54. package/dist/context/ingest/adapters/live-database/stage.d.ts +2 -0
  55. package/dist/context/ingest/adapters/live-database/stage.js +9 -0
  56. package/dist/context/ingest/adapters/looker/mapping.d.ts +0 -3
  57. package/dist/context/ingest/adapters/looker/mapping.js +0 -3
  58. package/dist/context/ingest/adapters/looker/types.d.ts +1 -1
  59. package/dist/context/ingest/historic-sql-probes/bigquery-runner.d.ts +34 -0
  60. package/dist/context/ingest/historic-sql-probes/bigquery-runner.js +99 -0
  61. package/dist/context/ingest/historic-sql-probes/postgres-runner.d.ts +26 -0
  62. package/dist/context/ingest/historic-sql-probes/postgres-runner.js +76 -0
  63. package/dist/context/ingest/historic-sql-probes/snowflake-runner.d.ts +29 -0
  64. package/dist/context/ingest/historic-sql-probes/snowflake-runner.js +62 -0
  65. package/dist/context/ingest/historic-sql-probes.d.ts +46 -0
  66. package/dist/context/ingest/historic-sql-probes.js +62 -0
  67. package/dist/context/ingest/local-adapters.js +0 -1
  68. package/dist/context/ingest/local-ingest.js +1 -1
  69. package/dist/context/llm/claude-code-runtime.js +16 -1
  70. package/dist/context/mcp/context-tools.js +11 -48
  71. package/dist/context/mcp/local-project-ports.js +0 -3
  72. package/dist/context/project/config.d.ts +0 -8
  73. package/dist/context/project/driver-schemas.d.ts +0 -4
  74. package/dist/context/project/driver-schemas.js +0 -2
  75. package/dist/context/scan/constraint-discovery.d.ts +19 -0
  76. package/dist/context/scan/constraint-discovery.js +23 -0
  77. package/dist/context/scan/enabled-tables.d.ts +4 -5
  78. package/dist/context/scan/enabled-tables.js +4 -18
  79. package/dist/context/scan/entity-details.js +14 -44
  80. package/dist/context/scan/local-enrichment.js +13 -1
  81. package/dist/context/scan/local-scan.js +5 -4
  82. package/dist/context/scan/local-structural-artifacts.js +51 -0
  83. package/dist/context/scan/relationship-benchmarks.js +9 -6
  84. package/dist/context/scan/relationship-composite-candidates.d.ts +3 -2
  85. package/dist/context/scan/relationship-composite-candidates.js +21 -33
  86. package/dist/context/scan/relationship-discovery.d.ts +3 -2
  87. package/dist/context/scan/relationship-discovery.js +4 -4
  88. package/dist/context/scan/relationship-profiling.d.ts +2 -3
  89. package/dist/context/scan/relationship-profiling.js +25 -94
  90. package/dist/context/scan/relationship-validation.d.ts +3 -2
  91. package/dist/context/scan/relationship-validation.js +12 -22
  92. package/dist/context/scan/table-ref.d.ts +1 -2
  93. package/dist/context/scan/table-ref.js +3 -4
  94. package/dist/context/scan/types.d.ts +6 -2
  95. package/dist/context/scan/warehouse-catalog.js +31 -48
  96. package/dist/context/sl/local-query.js +0 -3
  97. package/dist/context/sl/local-sl.js +0 -13
  98. package/dist/context/sl/semantic-layer.service.js +1 -4
  99. package/dist/context/tools/context-candidate-write.tool.d.ts +2 -2
  100. package/dist/context-build-view.js +1 -1
  101. package/dist/database-tree-picker.js +14 -7
  102. package/dist/error-message.d.ts +1 -0
  103. package/dist/error-message.js +29 -0
  104. package/dist/ingest-depth.js +0 -1
  105. package/dist/ingest.js +2 -2
  106. package/dist/llm/embedding-health.js +2 -2
  107. package/dist/local-scan-connectors.js +13 -56
  108. package/dist/managed-local-embeddings.js +2 -1
  109. package/dist/managed-python-daemon.d.ts +5 -0
  110. package/dist/managed-python-daemon.js +29 -9
  111. package/dist/managed-python-http.js +2 -1
  112. package/dist/public-ingest.js +1 -6
  113. package/dist/runtime-requirements.js +2 -2
  114. package/dist/setup-agents.d.ts +1 -1
  115. package/dist/setup-agents.js +16 -74
  116. package/dist/setup-context.js +2 -1
  117. package/dist/setup-databases.d.ts +3 -13
  118. package/dist/setup-databases.js +141 -313
  119. package/dist/setup-embeddings.js +10 -2
  120. package/dist/setup-project.d.ts +0 -8
  121. package/dist/setup-project.js +3 -27
  122. package/dist/setup-runtime.js +2 -1
  123. package/dist/setup-sources.js +2 -1
  124. package/dist/setup.js +11 -18
  125. package/dist/skills/historic_sql_patterns/SKILL.md +1 -3
  126. package/dist/skills/historic_sql_table_digest/SKILL.md +0 -1
  127. package/dist/skills/sl/SKILL.md +2 -2
  128. package/dist/sql.js +0 -4
  129. package/dist/status-project.d.ts +3 -18
  130. package/dist/status-project.js +42 -216
  131. package/dist/telemetry/events.d.ts +1 -1
  132. package/dist/telemetry/index.js +8 -3
  133. package/dist/tree-picker-state.d.ts +2 -2
  134. package/dist/tree-picker-state.js +29 -13
  135. package/dist/tree-picker-tui.d.ts +3 -1
  136. package/dist/tree-picker-tui.js +20 -32
  137. package/package.json +6 -6
  138. package/dist/admin-reindex.test.d.ts +0 -1
  139. package/dist/admin-reindex.test.js +0 -119
  140. package/dist/admin.test.d.ts +0 -1
  141. package/dist/admin.test.js +0 -201
  142. package/dist/cli-program-telemetry.test.d.ts +0 -1
  143. package/dist/cli-program-telemetry.test.js +0 -89
  144. package/dist/cli-program.test.d.ts +0 -1
  145. package/dist/cli-program.test.js +0 -71
  146. package/dist/command-tree.test.d.ts +0 -1
  147. package/dist/command-tree.test.js +0 -126
  148. package/dist/commands/mcp-commands.test.d.ts +0 -1
  149. package/dist/commands/mcp-commands.test.js +0 -111
  150. package/dist/commands/sql-commands.test.d.ts +0 -1
  151. package/dist/commands/sql-commands.test.js +0 -68
  152. package/dist/connection.test.d.ts +0 -1
  153. package/dist/connection.test.js +0 -426
  154. package/dist/connectors/bigquery/connector.test.d.ts +0 -1
  155. package/dist/connectors/bigquery/connector.test.js +0 -363
  156. package/dist/connectors/bigquery/dialect.test.d.ts +0 -1
  157. package/dist/connectors/bigquery/dialect.test.js +0 -36
  158. package/dist/connectors/clickhouse/connector.test.d.ts +0 -1
  159. package/dist/connectors/clickhouse/connector.test.js +0 -342
  160. package/dist/connectors/clickhouse/dialect.test.d.ts +0 -1
  161. package/dist/connectors/clickhouse/dialect.test.js +0 -36
  162. package/dist/connectors/mysql/connector.test.d.ts +0 -1
  163. package/dist/connectors/mysql/connector.test.js +0 -365
  164. package/dist/connectors/mysql/dialect.test.d.ts +0 -1
  165. package/dist/connectors/mysql/dialect.test.js +0 -36
  166. package/dist/connectors/postgres/connector.test.d.ts +0 -1
  167. package/dist/connectors/postgres/connector.test.js +0 -391
  168. package/dist/connectors/postgres/dialect.test.d.ts +0 -1
  169. package/dist/connectors/postgres/dialect.test.js +0 -37
  170. package/dist/connectors/postgres/historic-sql-query-client.test.d.ts +0 -1
  171. package/dist/connectors/postgres/historic-sql-query-client.test.js +0 -45
  172. package/dist/connectors/snowflake/connector.test.d.ts +0 -1
  173. package/dist/connectors/snowflake/connector.test.js +0 -462
  174. package/dist/connectors/snowflake/dialect.test.d.ts +0 -1
  175. package/dist/connectors/snowflake/dialect.test.js +0 -34
  176. package/dist/connectors/snowflake/identifiers.test.d.ts +0 -1
  177. package/dist/connectors/snowflake/identifiers.test.js +0 -12
  178. package/dist/connectors/snowflake/sdk-logger.test.d.ts +0 -1
  179. package/dist/connectors/snowflake/sdk-logger.test.js +0 -47
  180. package/dist/connectors/sqlite/connector.test.d.ts +0 -1
  181. package/dist/connectors/sqlite/connector.test.js +0 -207
  182. package/dist/connectors/sqlite/dialect.test.d.ts +0 -1
  183. package/dist/connectors/sqlite/dialect.test.js +0 -23
  184. package/dist/connectors/sqlserver/connector.test.d.ts +0 -1
  185. package/dist/connectors/sqlserver/connector.test.js +0 -313
  186. package/dist/connectors/sqlserver/dialect.test.d.ts +0 -1
  187. package/dist/connectors/sqlserver/dialect.test.js +0 -36
  188. package/dist/context/connections/bigquery-identifiers.test.d.ts +0 -1
  189. package/dist/context/connections/bigquery-identifiers.test.js +0 -13
  190. package/dist/context/connections/dialects.test.d.ts +0 -1
  191. package/dist/context/connections/dialects.test.js +0 -24
  192. package/dist/context/connections/local-query-executor.test.d.ts +0 -1
  193. package/dist/context/connections/local-query-executor.test.js +0 -48
  194. package/dist/context/connections/local-warehouse-descriptor.test.d.ts +0 -1
  195. package/dist/context/connections/local-warehouse-descriptor.test.js +0 -53
  196. package/dist/context/connections/notion-config.test.d.ts +0 -1
  197. package/dist/context/connections/notion-config.test.js +0 -121
  198. package/dist/context/connections/postgres-query-executor.test.d.ts +0 -1
  199. package/dist/context/connections/postgres-query-executor.test.js +0 -91
  200. package/dist/context/connections/read-only-sql.test.d.ts +0 -1
  201. package/dist/context/connections/read-only-sql.test.js +0 -20
  202. package/dist/context/connections/sqlite-query-executor.test.d.ts +0 -1
  203. package/dist/context/connections/sqlite-query-executor.test.js +0 -113
  204. package/dist/context/core/config-reference.test.d.ts +0 -1
  205. package/dist/context/core/config-reference.test.js +0 -27
  206. package/dist/context/core/git.service.assert-worktree-clean.test.d.ts +0 -1
  207. package/dist/context/core/git.service.assert-worktree-clean.test.js +0 -62
  208. package/dist/context/core/git.service.delete-directories.test.d.ts +0 -1
  209. package/dist/context/core/git.service.delete-directories.test.js +0 -61
  210. package/dist/context/core/git.service.patch.test.d.ts +0 -1
  211. package/dist/context/core/git.service.patch.test.js +0 -40
  212. package/dist/context/core/git.service.reset-hard.test.d.ts +0 -1
  213. package/dist/context/core/git.service.reset-hard.test.js +0 -47
  214. package/dist/context/core/git.service.test.d.ts +0 -1
  215. package/dist/context/core/git.service.test.js +0 -357
  216. package/dist/context/core/session-worktree.service.test.d.ts +0 -1
  217. package/dist/context/core/session-worktree.service.test.js +0 -97
  218. package/dist/context/daemon/semantic-layer-compute.test.d.ts +0 -1
  219. package/dist/context/daemon/semantic-layer-compute.test.js +0 -305
  220. package/dist/context/index-sync/reindex.test.d.ts +0 -1
  221. package/dist/context/index-sync/reindex.test.js +0 -139
  222. package/dist/context/ingest/action-identity.test.d.ts +0 -1
  223. package/dist/context/ingest/action-identity.test.js +0 -19
  224. package/dist/context/ingest/adapters/dbt/chunk.test.d.ts +0 -1
  225. package/dist/context/ingest/adapters/dbt/chunk.test.js +0 -30
  226. package/dist/context/ingest/adapters/dbt/dbt.adapter.test.d.ts +0 -1
  227. package/dist/context/ingest/adapters/dbt/dbt.adapter.test.js +0 -43
  228. package/dist/context/ingest/adapters/dbt/fetch.test.d.ts +0 -1
  229. package/dist/context/ingest/adapters/dbt/fetch.test.js +0 -30
  230. package/dist/context/ingest/adapters/dbt/parse.test.d.ts +0 -1
  231. package/dist/context/ingest/adapters/dbt/parse.test.js +0 -7
  232. package/dist/context/ingest/adapters/dbt-descriptions/parse-schema.test.d.ts +0 -1
  233. package/dist/context/ingest/adapters/dbt-descriptions/parse-schema.test.js +0 -195
  234. package/dist/context/ingest/adapters/historic-sql/bigquery-query-history-reader.test.d.ts +0 -1
  235. package/dist/context/ingest/adapters/historic-sql/bigquery-query-history-reader.test.js +0 -121
  236. package/dist/context/ingest/adapters/historic-sql/buckets.test.d.ts +0 -1
  237. package/dist/context/ingest/adapters/historic-sql/buckets.test.js +0 -49
  238. package/dist/context/ingest/adapters/historic-sql/chunk-unified.test.d.ts +0 -1
  239. package/dist/context/ingest/adapters/historic-sql/chunk-unified.test.js +0 -160
  240. package/dist/context/ingest/adapters/historic-sql/detect.test.d.ts +0 -1
  241. package/dist/context/ingest/adapters/historic-sql/detect.test.js +0 -48
  242. package/dist/context/ingest/adapters/historic-sql/evidence-tool.test.d.ts +0 -1
  243. package/dist/context/ingest/adapters/historic-sql/evidence-tool.test.js +0 -67
  244. package/dist/context/ingest/adapters/historic-sql/evidence.test.d.ts +0 -1
  245. package/dist/context/ingest/adapters/historic-sql/evidence.test.js +0 -43
  246. package/dist/context/ingest/adapters/historic-sql/historic-sql.adapter.test.d.ts +0 -1
  247. package/dist/context/ingest/adapters/historic-sql/historic-sql.adapter.test.js +0 -98
  248. package/dist/context/ingest/adapters/historic-sql/local-ingest-acceptance.test.d.ts +0 -1
  249. package/dist/context/ingest/adapters/historic-sql/local-ingest-acceptance.test.js +0 -235
  250. package/dist/context/ingest/adapters/historic-sql/pattern-inputs.test.d.ts +0 -1
  251. package/dist/context/ingest/adapters/historic-sql/pattern-inputs.test.js +0 -68
  252. package/dist/context/ingest/adapters/historic-sql/postgres-pgss-reader.test.d.ts +0 -1
  253. package/dist/context/ingest/adapters/historic-sql/postgres-pgss-reader.test.js +0 -205
  254. package/dist/context/ingest/adapters/historic-sql/projection.test.d.ts +0 -1
  255. package/dist/context/ingest/adapters/historic-sql/projection.test.js +0 -392
  256. package/dist/context/ingest/adapters/historic-sql/redaction.test.d.ts +0 -1
  257. package/dist/context/ingest/adapters/historic-sql/redaction.test.js +0 -22
  258. package/dist/context/ingest/adapters/historic-sql/skill-schemas.test.d.ts +0 -1
  259. package/dist/context/ingest/adapters/historic-sql/skill-schemas.test.js +0 -62
  260. package/dist/context/ingest/adapters/historic-sql/snowflake-query-history-reader.test.d.ts +0 -1
  261. package/dist/context/ingest/adapters/historic-sql/snowflake-query-history-reader.test.js +0 -117
  262. package/dist/context/ingest/adapters/historic-sql/stage-unified.test.d.ts +0 -1
  263. package/dist/context/ingest/adapters/historic-sql/stage-unified.test.js +0 -405
  264. package/dist/context/ingest/adapters/historic-sql/types.test.d.ts +0 -1
  265. package/dist/context/ingest/adapters/historic-sql/types.test.js +0 -87
  266. package/dist/context/ingest/adapters/live-database/chunk.test.d.ts +0 -1
  267. package/dist/context/ingest/adapters/live-database/chunk.test.js +0 -95
  268. package/dist/context/ingest/adapters/live-database/daemon-introspection.test.d.ts +0 -1
  269. package/dist/context/ingest/adapters/live-database/daemon-introspection.test.js +0 -241
  270. package/dist/context/ingest/adapters/live-database/live-database.adapter.test.d.ts +0 -1
  271. package/dist/context/ingest/adapters/live-database/live-database.adapter.test.js +0 -105
  272. package/dist/context/ingest/adapters/live-database/manifest.test.d.ts +0 -1
  273. package/dist/context/ingest/adapters/live-database/manifest.test.js +0 -291
  274. package/dist/context/ingest/adapters/live-database/stage.test.d.ts +0 -1
  275. package/dist/context/ingest/adapters/live-database/stage.test.js +0 -133
  276. package/dist/context/ingest/adapters/looker/chunk.test.d.ts +0 -1
  277. package/dist/context/ingest/adapters/looker/chunk.test.js +0 -142
  278. package/dist/context/ingest/adapters/looker/client-boundary.test.d.ts +0 -1
  279. package/dist/context/ingest/adapters/looker/client-boundary.test.js +0 -12
  280. package/dist/context/ingest/adapters/looker/client.test.d.ts +0 -1
  281. package/dist/context/ingest/adapters/looker/client.test.js +0 -407
  282. package/dist/context/ingest/adapters/looker/daemon-table-identifier-parser.test.d.ts +0 -1
  283. package/dist/context/ingest/adapters/looker/daemon-table-identifier-parser.test.js +0 -40
  284. package/dist/context/ingest/adapters/looker/detect.test.d.ts +0 -1
  285. package/dist/context/ingest/adapters/looker/detect.test.js +0 -39
  286. package/dist/context/ingest/adapters/looker/evidence-documents.test.d.ts +0 -1
  287. package/dist/context/ingest/adapters/looker/evidence-documents.test.js +0 -178
  288. package/dist/context/ingest/adapters/looker/factory.test.d.ts +0 -1
  289. package/dist/context/ingest/adapters/looker/factory.test.js +0 -55
  290. package/dist/context/ingest/adapters/looker/fetch-report.test.d.ts +0 -1
  291. package/dist/context/ingest/adapters/looker/fetch-report.test.js +0 -71
  292. package/dist/context/ingest/adapters/looker/fetch.test.d.ts +0 -1
  293. package/dist/context/ingest/adapters/looker/fetch.test.js +0 -592
  294. package/dist/context/ingest/adapters/looker/local-runtime-store.test.d.ts +0 -1
  295. package/dist/context/ingest/adapters/looker/local-runtime-store.test.js +0 -106
  296. package/dist/context/ingest/adapters/looker/looker.adapter.test.d.ts +0 -1
  297. package/dist/context/ingest/adapters/looker/looker.adapter.test.js +0 -99
  298. package/dist/context/ingest/adapters/looker/mapping.test.d.ts +0 -1
  299. package/dist/context/ingest/adapters/looker/mapping.test.js +0 -334
  300. package/dist/context/ingest/adapters/looker/reconcile.test.d.ts +0 -1
  301. package/dist/context/ingest/adapters/looker/reconcile.test.js +0 -12
  302. package/dist/context/ingest/adapters/looker/scope.test.d.ts +0 -1
  303. package/dist/context/ingest/adapters/looker/scope.test.js +0 -84
  304. package/dist/context/ingest/adapters/looker/target-connections.test.d.ts +0 -1
  305. package/dist/context/ingest/adapters/looker/target-connections.test.js +0 -71
  306. package/dist/context/ingest/adapters/looker/tools/looker-query-to-sl.tool.test.d.ts +0 -1
  307. package/dist/context/ingest/adapters/looker/tools/looker-query-to-sl.tool.test.js +0 -211
  308. package/dist/context/ingest/adapters/looker/types.test.d.ts +0 -1
  309. package/dist/context/ingest/adapters/looker/types.test.js +0 -261
  310. package/dist/context/ingest/adapters/lookml/chunk.test.d.ts +0 -1
  311. package/dist/context/ingest/adapters/lookml/chunk.test.js +0 -213
  312. package/dist/context/ingest/adapters/lookml/detect.test.d.ts +0 -1
  313. package/dist/context/ingest/adapters/lookml/detect.test.js +0 -37
  314. package/dist/context/ingest/adapters/lookml/fetch-report.test.d.ts +0 -1
  315. package/dist/context/ingest/adapters/lookml/fetch-report.test.js +0 -82
  316. package/dist/context/ingest/adapters/lookml/fetch.test.d.ts +0 -1
  317. package/dist/context/ingest/adapters/lookml/fetch.test.js +0 -121
  318. package/dist/context/ingest/adapters/lookml/graph.test.d.ts +0 -1
  319. package/dist/context/ingest/adapters/lookml/graph.test.js +0 -105
  320. package/dist/context/ingest/adapters/lookml/lookml.adapter.test.d.ts +0 -1
  321. package/dist/context/ingest/adapters/lookml/lookml.adapter.test.js +0 -49
  322. package/dist/context/ingest/adapters/lookml/parse.test.d.ts +0 -1
  323. package/dist/context/ingest/adapters/lookml/parse.test.js +0 -118
  324. package/dist/context/ingest/adapters/lookml/pull-config.test.d.ts +0 -1
  325. package/dist/context/ingest/adapters/lookml/pull-config.test.js +0 -128
  326. package/dist/context/ingest/adapters/metabase/card-references.test.d.ts +0 -1
  327. package/dist/context/ingest/adapters/metabase/card-references.test.js +0 -36
  328. package/dist/context/ingest/adapters/metabase/chunk.test.d.ts +0 -1
  329. package/dist/context/ingest/adapters/metabase/chunk.test.js +0 -299
  330. package/dist/context/ingest/adapters/metabase/client-boundary.test.d.ts +0 -1
  331. package/dist/context/ingest/adapters/metabase/client-boundary.test.js +0 -38
  332. package/dist/context/ingest/adapters/metabase/client-port.test.d.ts +0 -1
  333. package/dist/context/ingest/adapters/metabase/client-port.test.js +0 -86
  334. package/dist/context/ingest/adapters/metabase/client.test.d.ts +0 -1
  335. package/dist/context/ingest/adapters/metabase/client.test.js +0 -377
  336. package/dist/context/ingest/adapters/metabase/detect.test.d.ts +0 -1
  337. package/dist/context/ingest/adapters/metabase/detect.test.js +0 -42
  338. package/dist/context/ingest/adapters/metabase/fanout-planner.test.d.ts +0 -1
  339. package/dist/context/ingest/adapters/metabase/fanout-planner.test.js +0 -44
  340. package/dist/context/ingest/adapters/metabase/fetch-scope.test.d.ts +0 -1
  341. package/dist/context/ingest/adapters/metabase/fetch-scope.test.js +0 -124
  342. package/dist/context/ingest/adapters/metabase/fetch.test.d.ts +0 -1
  343. package/dist/context/ingest/adapters/metabase/fetch.test.js +0 -557
  344. package/dist/context/ingest/adapters/metabase/local-metabase.adapter.test.d.ts +0 -1
  345. package/dist/context/ingest/adapters/metabase/local-metabase.adapter.test.js +0 -56
  346. package/dist/context/ingest/adapters/metabase/local-source-state-store.test.d.ts +0 -1
  347. package/dist/context/ingest/adapters/metabase/local-source-state-store.test.js +0 -99
  348. package/dist/context/ingest/adapters/metabase/mapping.test.d.ts +0 -1
  349. package/dist/context/ingest/adapters/metabase/mapping.test.js +0 -215
  350. package/dist/context/ingest/adapters/metabase/metabase.adapter.test.d.ts +0 -1
  351. package/dist/context/ingest/adapters/metabase/metabase.adapter.test.js +0 -129
  352. package/dist/context/ingest/adapters/metabase/serialize-card.test.d.ts +0 -1
  353. package/dist/context/ingest/adapters/metabase/serialize-card.test.js +0 -205
  354. package/dist/context/ingest/adapters/metabase/types.test.d.ts +0 -1
  355. package/dist/context/ingest/adapters/metabase/types.test.js +0 -75
  356. package/dist/context/ingest/adapters/metricflow/chunk.test.d.ts +0 -1
  357. package/dist/context/ingest/adapters/metricflow/chunk.test.js +0 -114
  358. package/dist/context/ingest/adapters/metricflow/deep-parse.test.d.ts +0 -1
  359. package/dist/context/ingest/adapters/metricflow/deep-parse.test.js +0 -1139
  360. package/dist/context/ingest/adapters/metricflow/detect.test.d.ts +0 -1
  361. package/dist/context/ingest/adapters/metricflow/detect.test.js +0 -43
  362. package/dist/context/ingest/adapters/metricflow/fetch.test.d.ts +0 -1
  363. package/dist/context/ingest/adapters/metricflow/fetch.test.js +0 -97
  364. package/dist/context/ingest/adapters/metricflow/graph.test.d.ts +0 -1
  365. package/dist/context/ingest/adapters/metricflow/graph.test.js +0 -245
  366. package/dist/context/ingest/adapters/metricflow/import-semantic-models.test.d.ts +0 -1
  367. package/dist/context/ingest/adapters/metricflow/import-semantic-models.test.js +0 -318
  368. package/dist/context/ingest/adapters/metricflow/metricflow.adapter.test.d.ts +0 -1
  369. package/dist/context/ingest/adapters/metricflow/metricflow.adapter.test.js +0 -212
  370. package/dist/context/ingest/adapters/metricflow/parse.test.d.ts +0 -1
  371. package/dist/context/ingest/adapters/metricflow/parse.test.js +0 -171
  372. package/dist/context/ingest/adapters/metricflow/pull-config.test.d.ts +0 -1
  373. package/dist/context/ingest/adapters/metricflow/pull-config.test.js +0 -57
  374. package/dist/context/ingest/adapters/metricflow/semantic-models.test.d.ts +0 -1
  375. package/dist/context/ingest/adapters/metricflow/semantic-models.test.js +0 -204
  376. package/dist/context/ingest/adapters/notion/cluster.test.d.ts +0 -1
  377. package/dist/context/ingest/adapters/notion/cluster.test.js +0 -123
  378. package/dist/context/ingest/adapters/notion/fetch.test.d.ts +0 -1
  379. package/dist/context/ingest/adapters/notion/fetch.test.js +0 -358
  380. package/dist/context/ingest/adapters/notion/local-state-store.test.d.ts +0 -1
  381. package/dist/context/ingest/adapters/notion/local-state-store.test.js +0 -29
  382. package/dist/context/ingest/adapters/notion/normalize.test.d.ts +0 -1
  383. package/dist/context/ingest/adapters/notion/normalize.test.js +0 -64
  384. package/dist/context/ingest/adapters/notion/notion-client.test.d.ts +0 -1
  385. package/dist/context/ingest/adapters/notion/notion-client.test.js +0 -49
  386. package/dist/context/ingest/adapters/notion/notion.adapter.test.d.ts +0 -1
  387. package/dist/context/ingest/adapters/notion/notion.adapter.test.js +0 -315
  388. package/dist/context/ingest/artifact-gates.test.d.ts +0 -1
  389. package/dist/context/ingest/artifact-gates.test.js +0 -167
  390. package/dist/context/ingest/canonical-pins.test.d.ts +0 -1
  391. package/dist/context/ingest/canonical-pins.test.js +0 -66
  392. package/dist/context/ingest/clustering/kmeans.test.d.ts +0 -1
  393. package/dist/context/ingest/clustering/kmeans.test.js +0 -61
  394. package/dist/context/ingest/context-candidates/candidate-dedup.service.test.d.ts +0 -1
  395. package/dist/context/ingest/context-candidates/candidate-dedup.service.test.js +0 -216
  396. package/dist/context/ingest/context-candidates/context-candidate-carryforward.service.test.d.ts +0 -1
  397. package/dist/context/ingest/context-candidates/context-candidate-carryforward.service.test.js +0 -161
  398. package/dist/context/ingest/context-candidates/curator-pagination.service.test.d.ts +0 -1
  399. package/dist/context/ingest/context-candidates/curator-pagination.service.test.js +0 -168
  400. package/dist/context/ingest/context-candidates/embedding-text.test.d.ts +0 -1
  401. package/dist/context/ingest/context-candidates/embedding-text.test.js +0 -10
  402. package/dist/context/ingest/context-candidates/store.test.d.ts +0 -1
  403. package/dist/context/ingest/context-candidates/store.test.js +0 -67
  404. package/dist/context/ingest/context-evidence/context-evidence-index.service.test.d.ts +0 -1
  405. package/dist/context/ingest/context-evidence/context-evidence-index.service.test.js +0 -374
  406. package/dist/context/ingest/context-evidence/sqlite-context-evidence-store.test.d.ts +0 -1
  407. package/dist/context/ingest/context-evidence/sqlite-context-evidence-store.test.js +0 -416
  408. package/dist/context/ingest/context-evidence/store.test.d.ts +0 -1
  409. package/dist/context/ingest/context-evidence/store.test.js +0 -55
  410. package/dist/context/ingest/dbt-shared/project-vars.test.d.ts +0 -1
  411. package/dist/context/ingest/dbt-shared/project-vars.test.js +0 -90
  412. package/dist/context/ingest/dbt-shared/schema-files.test.d.ts +0 -1
  413. package/dist/context/ingest/dbt-shared/schema-files.test.js +0 -35
  414. package/dist/context/ingest/diff-set.service.test.d.ts +0 -1
  415. package/dist/context/ingest/diff-set.service.test.js +0 -132
  416. package/dist/context/ingest/final-gate-repair.test.d.ts +0 -1
  417. package/dist/context/ingest/final-gate-repair.test.js +0 -109
  418. package/dist/context/ingest/finalization-scope.test.d.ts +0 -1
  419. package/dist/context/ingest/finalization-scope.test.js +0 -114
  420. package/dist/context/ingest/ingest-bundle.runner.isolated-diff.test.d.ts +0 -1
  421. package/dist/context/ingest/ingest-bundle.runner.isolated-diff.test.js +0 -1928
  422. package/dist/context/ingest/ingest-bundle.runner.test.d.ts +0 -1
  423. package/dist/context/ingest/ingest-bundle.runner.test.js +0 -1899
  424. package/dist/context/ingest/ingest-prompts.test.d.ts +0 -1
  425. package/dist/context/ingest/ingest-prompts.test.js +0 -32
  426. package/dist/context/ingest/ingest-runtime-assets.test.d.ts +0 -1
  427. package/dist/context/ingest/ingest-runtime-assets.test.js +0 -89
  428. package/dist/context/ingest/ingest-trace.test.d.ts +0 -1
  429. package/dist/context/ingest/ingest-trace.test.js +0 -76
  430. package/dist/context/ingest/isolated-diff/git-patch.test.d.ts +0 -1
  431. package/dist/context/ingest/isolated-diff/git-patch.test.js +0 -76
  432. package/dist/context/ingest/isolated-diff/patch-integrator.test.d.ts +0 -1
  433. package/dist/context/ingest/isolated-diff/patch-integrator.test.js +0 -369
  434. package/dist/context/ingest/isolated-diff/textual-conflict-resolver.test.d.ts +0 -1
  435. package/dist/context/ingest/isolated-diff/textual-conflict-resolver.test.js +0 -101
  436. package/dist/context/ingest/isolated-diff/work-unit-executor.test.d.ts +0 -1
  437. package/dist/context/ingest/isolated-diff/work-unit-executor.test.js +0 -137
  438. package/dist/context/ingest/local-adapters.test.d.ts +0 -1
  439. package/dist/context/ingest/local-adapters.test.js +0 -612
  440. package/dist/context/ingest/local-bundle-ingest.test.d.ts +0 -1
  441. package/dist/context/ingest/local-bundle-ingest.test.js +0 -794
  442. package/dist/context/ingest/local-bundle-runtime.test.d.ts +0 -1
  443. package/dist/context/ingest/local-bundle-runtime.test.js +0 -240
  444. package/dist/context/ingest/local-embedding-provider.integration.test.d.ts +0 -1
  445. package/dist/context/ingest/local-embedding-provider.integration.test.js +0 -139
  446. package/dist/context/ingest/local-mapping-reconcile.test.d.ts +0 -1
  447. package/dist/context/ingest/local-mapping-reconcile.test.js +0 -61
  448. package/dist/context/ingest/local-metabase-ingest.test.d.ts +0 -1
  449. package/dist/context/ingest/local-metabase-ingest.test.js +0 -227
  450. package/dist/context/ingest/local-stage-ingest.test.d.ts +0 -1
  451. package/dist/context/ingest/local-stage-ingest.test.js +0 -581
  452. package/dist/context/ingest/memory-flow/acceptance-fixtures.d.ts +0 -6
  453. package/dist/context/ingest/memory-flow/acceptance-fixtures.js +0 -155
  454. package/dist/context/ingest/memory-flow/acceptance.test.d.ts +0 -1
  455. package/dist/context/ingest/memory-flow/acceptance.test.js +0 -43
  456. package/dist/context/ingest/memory-flow/events.test.d.ts +0 -1
  457. package/dist/context/ingest/memory-flow/events.test.js +0 -319
  458. package/dist/context/ingest/memory-flow/interaction.test.d.ts +0 -1
  459. package/dist/context/ingest/memory-flow/interaction.test.js +0 -264
  460. package/dist/context/ingest/memory-flow/interactive-render.test.d.ts +0 -1
  461. package/dist/context/ingest/memory-flow/interactive-render.test.js +0 -160
  462. package/dist/context/ingest/memory-flow/live-buffer.test.d.ts +0 -1
  463. package/dist/context/ingest/memory-flow/live-buffer.test.js +0 -77
  464. package/dist/context/ingest/memory-flow/render.test.d.ts +0 -1
  465. package/dist/context/ingest/memory-flow/render.test.js +0 -105
  466. package/dist/context/ingest/memory-flow/schema.test.d.ts +0 -1
  467. package/dist/context/ingest/memory-flow/schema.test.js +0 -147
  468. package/dist/context/ingest/memory-flow/summary.test.d.ts +0 -1
  469. package/dist/context/ingest/memory-flow/summary.test.js +0 -130
  470. package/dist/context/ingest/memory-flow/view-model.test.d.ts +0 -1
  471. package/dist/context/ingest/memory-flow/view-model.test.js +0 -397
  472. package/dist/context/ingest/memory-flow/visuals.test.d.ts +0 -1
  473. package/dist/context/ingest/memory-flow/visuals.test.js +0 -49
  474. package/dist/context/ingest/page-triage/page-triage.service.test.d.ts +0 -1
  475. package/dist/context/ingest/page-triage/page-triage.service.test.js +0 -311
  476. package/dist/context/ingest/raw-sources-paths.test.d.ts +0 -1
  477. package/dist/context/ingest/raw-sources-paths.test.js +0 -18
  478. package/dist/context/ingest/repo-fetch.test.d.ts +0 -1
  479. package/dist/context/ingest/repo-fetch.test.js +0 -168
  480. package/dist/context/ingest/report-snapshot.test.d.ts +0 -1
  481. package/dist/context/ingest/report-snapshot.test.js +0 -329
  482. package/dist/context/ingest/semantic-layer-target-policy.test.d.ts +0 -1
  483. package/dist/context/ingest/semantic-layer-target-policy.test.js +0 -25
  484. package/dist/context/ingest/source-adapter-registry.test.d.ts +0 -1
  485. package/dist/context/ingest/source-adapter-registry.test.js +0 -35
  486. package/dist/context/ingest/sqlite-bundle-ingest-store.test.d.ts +0 -1
  487. package/dist/context/ingest/sqlite-bundle-ingest-store.test.js +0 -517
  488. package/dist/context/ingest/sqlite-local-ingest-store.test.d.ts +0 -1
  489. package/dist/context/ingest/sqlite-local-ingest-store.test.js +0 -143
  490. package/dist/context/ingest/stages/build-reconcile-context.context-candidates.test.d.ts +0 -1
  491. package/dist/context/ingest/stages/build-reconcile-context.context-candidates.test.js +0 -102
  492. package/dist/context/ingest/stages/build-reconcile-context.test.d.ts +0 -1
  493. package/dist/context/ingest/stages/build-reconcile-context.test.js +0 -141
  494. package/dist/context/ingest/stages/build-wu-context.test.d.ts +0 -1
  495. package/dist/context/ingest/stages/build-wu-context.test.js +0 -196
  496. package/dist/context/ingest/stages/stage-1-stage-raw-files.test.d.ts +0 -1
  497. package/dist/context/ingest/stages/stage-1-stage-raw-files.test.js +0 -54
  498. package/dist/context/ingest/stages/stage-3-work-units.test.d.ts +0 -1
  499. package/dist/context/ingest/stages/stage-3-work-units.test.js +0 -175
  500. package/dist/context/ingest/stages/stage-4-reconciliation.test.d.ts +0 -1
  501. package/dist/context/ingest/stages/stage-4-reconciliation.test.js +0 -144
  502. package/dist/context/ingest/stages/validate-wu-sources.test.d.ts +0 -1
  503. package/dist/context/ingest/stages/validate-wu-sources.test.js +0 -27
  504. package/dist/context/ingest/tools/emit-reconciliation-records.tool.test.d.ts +0 -1
  505. package/dist/context/ingest/tools/emit-reconciliation-records.tool.test.js +0 -237
  506. package/dist/context/ingest/tools/eviction-list.tool.test.d.ts +0 -1
  507. package/dist/context/ingest/tools/eviction-list.tool.test.js +0 -44
  508. package/dist/context/ingest/tools/read-raw-file.tool.test.d.ts +0 -1
  509. package/dist/context/ingest/tools/read-raw-file.tool.test.js +0 -45
  510. package/dist/context/ingest/tools/read-raw-span.tool.test.d.ts +0 -1
  511. package/dist/context/ingest/tools/read-raw-span.tool.test.js +0 -34
  512. package/dist/context/ingest/tools/stage-diff.tool.test.d.ts +0 -1
  513. package/dist/context/ingest/tools/stage-diff.tool.test.js +0 -112
  514. package/dist/context/ingest/tools/stage-list.tool.test.d.ts +0 -1
  515. package/dist/context/ingest/tools/stage-list.tool.test.js +0 -58
  516. package/dist/context/ingest/tools/tool-transcript-summary.test.d.ts +0 -1
  517. package/dist/context/ingest/tools/tool-transcript-summary.test.js +0 -141
  518. package/dist/context/ingest/tools/warehouse-verification/discover-data.tool.test.d.ts +0 -1
  519. package/dist/context/ingest/tools/warehouse-verification/discover-data.tool.test.js +0 -107
  520. package/dist/context/ingest/tools/warehouse-verification/entity-details.tool.test.d.ts +0 -1
  521. package/dist/context/ingest/tools/warehouse-verification/entity-details.tool.test.js +0 -146
  522. package/dist/context/ingest/tools/warehouse-verification/sql-execution.tool.test.d.ts +0 -1
  523. package/dist/context/ingest/tools/warehouse-verification/sql-execution.tool.test.js +0 -50
  524. package/dist/context/ingest/wiki-body-refs.test.d.ts +0 -1
  525. package/dist/context/ingest/wiki-body-refs.test.js +0 -138
  526. package/dist/context/ingest/wiki-sl-ref-repair.test.d.ts +0 -1
  527. package/dist/context/ingest/wiki-sl-ref-repair.test.js +0 -81
  528. package/dist/context/llm/ai-sdk-runtime.test.d.ts +0 -1
  529. package/dist/context/llm/ai-sdk-runtime.test.js +0 -308
  530. package/dist/context/llm/claude-code-env.test.d.ts +0 -1
  531. package/dist/context/llm/claude-code-env.test.js +0 -17
  532. package/dist/context/llm/claude-code-models.test.d.ts +0 -1
  533. package/dist/context/llm/claude-code-models.test.js +0 -15
  534. package/dist/context/llm/claude-code-runtime.test.d.ts +0 -1
  535. package/dist/context/llm/claude-code-runtime.test.js +0 -434
  536. package/dist/context/llm/debug-request-recorder.test.d.ts +0 -1
  537. package/dist/context/llm/debug-request-recorder.test.js +0 -112
  538. package/dist/context/llm/embedding-port.test.d.ts +0 -1
  539. package/dist/context/llm/embedding-port.test.js +0 -34
  540. package/dist/context/llm/local-config.test.d.ts +0 -1
  541. package/dist/context/llm/local-config.test.js +0 -164
  542. package/dist/context/llm/runtime-local-config.test.d.ts +0 -1
  543. package/dist/context/llm/runtime-local-config.test.js +0 -17
  544. package/dist/context/llm/runtime-tools.test.d.ts +0 -1
  545. package/dist/context/llm/runtime-tools.test.js +0 -36
  546. package/dist/context/mcp/local-project-ports.test.d.ts +0 -1
  547. package/dist/context/mcp/local-project-ports.test.js +0 -689
  548. package/dist/context/mcp/server.test.d.ts +0 -1
  549. package/dist/context/mcp/server.test.js +0 -902
  550. package/dist/context/memory/local-memory.test.d.ts +0 -1
  551. package/dist/context/memory/local-memory.test.js +0 -173
  552. package/dist/context/memory/memory-agent.service.ingest.test.d.ts +0 -1
  553. package/dist/context/memory/memory-agent.service.ingest.test.js +0 -355
  554. package/dist/context/memory/memory-agent.service.test.d.ts +0 -1
  555. package/dist/context/memory/memory-agent.service.test.js +0 -413
  556. package/dist/context/memory/memory-runs.test.d.ts +0 -1
  557. package/dist/context/memory/memory-runs.test.js +0 -158
  558. package/dist/context/memory/memory-runtime-assets.test.d.ts +0 -1
  559. package/dist/context/memory/memory-runtime-assets.test.js +0 -162
  560. package/dist/context/project/config.test.d.ts +0 -1
  561. package/dist/context/project/config.test.js +0 -467
  562. package/dist/context/project/driver-schemas.test.d.ts +0 -1
  563. package/dist/context/project/driver-schemas.test.js +0 -125
  564. package/dist/context/project/local-git-file-store.test.d.ts +0 -1
  565. package/dist/context/project/local-git-file-store.test.js +0 -71
  566. package/dist/context/project/mappings-yaml-schema.test.d.ts +0 -1
  567. package/dist/context/project/mappings-yaml-schema.test.js +0 -79
  568. package/dist/context/project/project.test.d.ts +0 -1
  569. package/dist/context/project/project.test.js +0 -55
  570. package/dist/context/project/setup-config.test.d.ts +0 -1
  571. package/dist/context/project/setup-config.test.js +0 -38
  572. package/dist/context/prompts/prompt.service.test.d.ts +0 -1
  573. package/dist/context/prompts/prompt.service.test.js +0 -43
  574. package/dist/context/scan/credentials.test.d.ts +0 -1
  575. package/dist/context/scan/credentials.test.js +0 -162
  576. package/dist/context/scan/data-dictionary.test.d.ts +0 -1
  577. package/dist/context/scan/data-dictionary.test.js +0 -92
  578. package/dist/context/scan/description-generation.test.d.ts +0 -1
  579. package/dist/context/scan/description-generation.test.js +0 -693
  580. package/dist/context/scan/embedding-text.test.d.ts +0 -1
  581. package/dist/context/scan/embedding-text.test.js +0 -36
  582. package/dist/context/scan/enrichment-state.test.d.ts +0 -1
  583. package/dist/context/scan/enrichment-state.test.js +0 -147
  584. package/dist/context/scan/enrichment-summary.test.d.ts +0 -1
  585. package/dist/context/scan/enrichment-summary.test.js +0 -34
  586. package/dist/context/scan/enrichment-types.test.d.ts +0 -1
  587. package/dist/context/scan/enrichment-types.test.js +0 -141
  588. package/dist/context/scan/entity-details.test.d.ts +0 -1
  589. package/dist/context/scan/entity-details.test.js +0 -234
  590. package/dist/context/scan/local-enrichment-artifacts.test.d.ts +0 -1
  591. package/dist/context/scan/local-enrichment-artifacts.test.js +0 -771
  592. package/dist/context/scan/local-enrichment.test.d.ts +0 -1
  593. package/dist/context/scan/local-enrichment.test.js +0 -765
  594. package/dist/context/scan/local-scan.test.d.ts +0 -1
  595. package/dist/context/scan/local-scan.test.js +0 -1663
  596. package/dist/context/scan/local-structural-artifacts.test.d.ts +0 -1
  597. package/dist/context/scan/local-structural-artifacts.test.js +0 -144
  598. package/dist/context/scan/relationship-benchmark-report.test.d.ts +0 -1
  599. package/dist/context/scan/relationship-benchmark-report.test.js +0 -389
  600. package/dist/context/scan/relationship-benchmarks.test.d.ts +0 -1
  601. package/dist/context/scan/relationship-benchmarks.test.js +0 -1072
  602. package/dist/context/scan/relationship-budget.test.d.ts +0 -1
  603. package/dist/context/scan/relationship-budget.test.js +0 -71
  604. package/dist/context/scan/relationship-candidates.test.d.ts +0 -1
  605. package/dist/context/scan/relationship-candidates.test.js +0 -747
  606. package/dist/context/scan/relationship-composite-candidates.test.d.ts +0 -1
  607. package/dist/context/scan/relationship-composite-candidates.test.js +0 -69
  608. package/dist/context/scan/relationship-diagnostics.test.d.ts +0 -1
  609. package/dist/context/scan/relationship-diagnostics.test.js +0 -333
  610. package/dist/context/scan/relationship-discovery.test.d.ts +0 -1
  611. package/dist/context/scan/relationship-discovery.test.js +0 -618
  612. package/dist/context/scan/relationship-formal-metadata.test.d.ts +0 -1
  613. package/dist/context/scan/relationship-formal-metadata.test.js +0 -125
  614. package/dist/context/scan/relationship-graph-resolver.test.d.ts +0 -1
  615. package/dist/context/scan/relationship-graph-resolver.test.js +0 -604
  616. package/dist/context/scan/relationship-llm-proposal.test.d.ts +0 -1
  617. package/dist/context/scan/relationship-llm-proposal.test.js +0 -197
  618. package/dist/context/scan/relationship-locality.test.d.ts +0 -1
  619. package/dist/context/scan/relationship-locality.test.js +0 -128
  620. package/dist/context/scan/relationship-name-similarity.test.d.ts +0 -1
  621. package/dist/context/scan/relationship-name-similarity.test.js +0 -68
  622. package/dist/context/scan/relationship-profiling.test.d.ts +0 -1
  623. package/dist/context/scan/relationship-profiling.test.js +0 -392
  624. package/dist/context/scan/relationship-scoring.test.d.ts +0 -1
  625. package/dist/context/scan/relationship-scoring.test.js +0 -86
  626. package/dist/context/scan/relationship-validation.test.d.ts +0 -1
  627. package/dist/context/scan/relationship-validation.test.js +0 -455
  628. package/dist/context/scan/table-ref.test.d.ts +0 -1
  629. package/dist/context/scan/table-ref.test.js +0 -53
  630. package/dist/context/scan/type-normalization.test.d.ts +0 -1
  631. package/dist/context/scan/type-normalization.test.js +0 -21
  632. package/dist/context/scan/types.test.d.ts +0 -1
  633. package/dist/context/scan/types.test.js +0 -206
  634. package/dist/context/scan/warehouse-catalog.test.d.ts +0 -1
  635. package/dist/context/scan/warehouse-catalog.test.js +0 -158
  636. package/dist/context/search/backend-conformance.test-utils.d.ts +0 -39
  637. package/dist/context/search/backend-conformance.test-utils.js +0 -88
  638. package/dist/context/search/backend-conformance.test-utils.test.d.ts +0 -1
  639. package/dist/context/search/backend-conformance.test-utils.test.js +0 -408
  640. package/dist/context/search/discover.test.d.ts +0 -1
  641. package/dist/context/search/discover.test.js +0 -197
  642. package/dist/context/search/hybrid-search-core.test.d.ts +0 -1
  643. package/dist/context/search/hybrid-search-core.test.js +0 -113
  644. package/dist/context/search/pglite-owner-process.test.d.ts +0 -1
  645. package/dist/context/search/pglite-owner-process.test.js +0 -273
  646. package/dist/context/search/pglite-runtime-boundary.test.d.ts +0 -1
  647. package/dist/context/search/pglite-runtime-boundary.test.js +0 -40
  648. package/dist/context/search/pglite-spike.test.d.ts +0 -1
  649. package/dist/context/search/pglite-spike.test.js +0 -249
  650. package/dist/context/search/query.test.d.ts +0 -1
  651. package/dist/context/search/query.test.js +0 -23
  652. package/dist/context/search/rrf.test.d.ts +0 -1
  653. package/dist/context/search/rrf.test.js +0 -47
  654. package/dist/context/skills/skills-registry.service.test.d.ts +0 -1
  655. package/dist/context/skills/skills-registry.service.test.js +0 -161
  656. package/dist/context/sl/dictionary-search.test.d.ts +0 -1
  657. package/dist/context/sl/dictionary-search.test.js +0 -204
  658. package/dist/context/sl/local-query.test.d.ts +0 -1
  659. package/dist/context/sl/local-query.test.js +0 -283
  660. package/dist/context/sl/local-sl.test.d.ts +0 -1
  661. package/dist/context/sl/local-sl.test.js +0 -334
  662. package/dist/context/sl/pglite-sl-search-prototype.test.d.ts +0 -1
  663. package/dist/context/sl/pglite-sl-search-prototype.test.js +0 -240
  664. package/dist/context/sl/schemas.contract.test.d.ts +0 -1
  665. package/dist/context/sl/schemas.contract.test.js +0 -62
  666. package/dist/context/sl/semantic-layer.service.test.d.ts +0 -1
  667. package/dist/context/sl/semantic-layer.service.test.js +0 -1107
  668. package/dist/context/sl/sl-dictionary-profile.test.d.ts +0 -1
  669. package/dist/context/sl/sl-dictionary-profile.test.js +0 -88
  670. package/dist/context/sl/sl-search.service.test.d.ts +0 -1
  671. package/dist/context/sl/sl-search.service.test.js +0 -256
  672. package/dist/context/sl/sqlite-sl-sources-index.test.d.ts +0 -1
  673. package/dist/context/sl/sqlite-sl-sources-index.test.js +0 -175
  674. package/dist/context/sl/tools/connection-id-schema.test.d.ts +0 -1
  675. package/dist/context/sl/tools/connection-id-schema.test.js +0 -14
  676. package/dist/context/sl/tools/sl-discover.tool.test.d.ts +0 -1
  677. package/dist/context/sl/tools/sl-discover.tool.test.js +0 -72
  678. package/dist/context/sl/tools/sl-edit-source.tool.test.d.ts +0 -1
  679. package/dist/context/sl/tools/sl-edit-source.tool.test.js +0 -184
  680. package/dist/context/sl/tools/sl-read-source.tool.session.test.d.ts +0 -1
  681. package/dist/context/sl/tools/sl-read-source.tool.session.test.js +0 -55
  682. package/dist/context/sl/tools/sl-rollback.tool.test.d.ts +0 -1
  683. package/dist/context/sl/tools/sl-rollback.tool.test.js +0 -57
  684. package/dist/context/sl/tools/sl-validate.tool.test.d.ts +0 -1
  685. package/dist/context/sl/tools/sl-validate.tool.test.js +0 -54
  686. package/dist/context/sl/tools/sl-warehouse-validation.test.d.ts +0 -1
  687. package/dist/context/sl/tools/sl-warehouse-validation.test.js +0 -136
  688. package/dist/context/sl/tools/sl-write-source.tool.test.d.ts +0 -1
  689. package/dist/context/sl/tools/sl-write-source.tool.test.js +0 -307
  690. package/dist/context/sql-analysis/http-sql-analysis-port.test.d.ts +0 -1
  691. package/dist/context/sql-analysis/http-sql-analysis-port.test.js +0 -147
  692. package/dist/context/test/make-local-git-repo.d.ts +0 -10
  693. package/dist/context/test/make-local-git-repo.js +0 -34
  694. package/dist/context/tools/context-evidence-tools.test.d.ts +0 -1
  695. package/dist/context/tools/context-evidence-tools.test.js +0 -486
  696. package/dist/context/tools/touched-sl-sources.test.d.ts +0 -1
  697. package/dist/context/tools/touched-sl-sources.test.js +0 -31
  698. package/dist/context/wiki/knowledge-wiki.service.test.d.ts +0 -1
  699. package/dist/context/wiki/knowledge-wiki.service.test.js +0 -205
  700. package/dist/context/wiki/local-knowledge.test.d.ts +0 -1
  701. package/dist/context/wiki/local-knowledge.test.js +0 -270
  702. package/dist/context/wiki/sqlite-knowledge-index.test.d.ts +0 -1
  703. package/dist/context/wiki/sqlite-knowledge-index.test.js +0 -129
  704. package/dist/context/wiki/tools/wiki-list-tags.tool.test.d.ts +0 -1
  705. package/dist/context/wiki/tools/wiki-list-tags.tool.test.js +0 -35
  706. package/dist/context/wiki/tools/wiki-read.tool.test.d.ts +0 -1
  707. package/dist/context/wiki/tools/wiki-read.tool.test.js +0 -66
  708. package/dist/context/wiki/tools/wiki-remove.tool.test.d.ts +0 -1
  709. package/dist/context/wiki/tools/wiki-remove.tool.test.js +0 -95
  710. package/dist/context/wiki/tools/wiki-search.tool.test.d.ts +0 -1
  711. package/dist/context/wiki/tools/wiki-search.tool.test.js +0 -35
  712. package/dist/context/wiki/tools/wiki-write.tool.test.d.ts +0 -1
  713. package/dist/context/wiki/tools/wiki-write.tool.test.js +0 -264
  714. package/dist/context/wiki/wiki-ref-validation.test.d.ts +0 -1
  715. package/dist/context/wiki/wiki-ref-validation.test.js +0 -64
  716. package/dist/context-build-view.test.d.ts +0 -1
  717. package/dist/context-build-view.test.js +0 -942
  718. package/dist/database-tree-picker.test.d.ts +0 -1
  719. package/dist/database-tree-picker.test.js +0 -188
  720. package/dist/demo-assets.test.d.ts +0 -1
  721. package/dist/demo-assets.test.js +0 -121
  722. package/dist/demo-metrics.test.d.ts +0 -1
  723. package/dist/demo-metrics.test.js +0 -108
  724. package/dist/doctor.test.d.ts +0 -1
  725. package/dist/doctor.test.js +0 -596
  726. package/dist/embedding-resolution.test.d.ts +0 -1
  727. package/dist/embedding-resolution.test.js +0 -132
  728. package/dist/example-smoke.test.d.ts +0 -1
  729. package/dist/example-smoke.test.js +0 -83
  730. package/dist/index.test.d.ts +0 -1
  731. package/dist/index.test.js +0 -1300
  732. package/dist/ingest-query-executor.test.d.ts +0 -1
  733. package/dist/ingest-query-executor.test.js +0 -71
  734. package/dist/ingest-report-file.test.d.ts +0 -1
  735. package/dist/ingest-report-file.test.js +0 -63
  736. package/dist/ingest-viz.test.d.ts +0 -1
  737. package/dist/ingest-viz.test.js +0 -691
  738. package/dist/ingest.test-utils.d.ts +0 -126
  739. package/dist/ingest.test-utils.js +0 -629
  740. package/dist/ingest.test.d.ts +0 -1
  741. package/dist/ingest.test.js +0 -1568
  742. package/dist/io/logger.test.d.ts +0 -1
  743. package/dist/io/logger.test.js +0 -55
  744. package/dist/io/mode.test.d.ts +0 -1
  745. package/dist/io/mode.test.js +0 -48
  746. package/dist/io/print-list.test.d.ts +0 -1
  747. package/dist/io/print-list.test.js +0 -277
  748. package/dist/knowledge.test.d.ts +0 -1
  749. package/dist/knowledge.test.js +0 -198
  750. package/dist/llm/embedding-health.test.d.ts +0 -1
  751. package/dist/llm/embedding-health.test.js +0 -72
  752. package/dist/llm/embedding-provider.test.d.ts +0 -1
  753. package/dist/llm/embedding-provider.test.js +0 -84
  754. package/dist/llm/message-builder.test.d.ts +0 -1
  755. package/dist/llm/message-builder.test.js +0 -127
  756. package/dist/llm/model-health.test.d.ts +0 -1
  757. package/dist/llm/model-health.test.js +0 -55
  758. package/dist/llm/model-provider.test.d.ts +0 -1
  759. package/dist/llm/model-provider.test.js +0 -246
  760. package/dist/llm/repair.test.d.ts +0 -1
  761. package/dist/llm/repair.test.js +0 -78
  762. package/dist/local-adapters.test.d.ts +0 -1
  763. package/dist/local-adapters.test.js +0 -166
  764. package/dist/local-scan-connectors.test.d.ts +0 -1
  765. package/dist/local-scan-connectors.test.js +0 -92
  766. package/dist/managed-local-embeddings.test.d.ts +0 -1
  767. package/dist/managed-local-embeddings.test.js +0 -229
  768. package/dist/managed-mcp-daemon.test.d.ts +0 -1
  769. package/dist/managed-mcp-daemon.test.js +0 -187
  770. package/dist/managed-python-command.test.d.ts +0 -1
  771. package/dist/managed-python-command.test.js +0 -262
  772. package/dist/managed-python-daemon.test.d.ts +0 -1
  773. package/dist/managed-python-daemon.test.js +0 -360
  774. package/dist/managed-python-http.test.d.ts +0 -1
  775. package/dist/managed-python-http.test.js +0 -177
  776. package/dist/managed-python-runtime.test.d.ts +0 -1
  777. package/dist/managed-python-runtime.test.js +0 -426
  778. package/dist/mcp-http-server.test.d.ts +0 -1
  779. package/dist/mcp-http-server.test.js +0 -209
  780. package/dist/mcp-server-factory.test.d.ts +0 -1
  781. package/dist/mcp-server-factory.test.js +0 -142
  782. package/dist/memory-flow-interactive.test.d.ts +0 -1
  783. package/dist/memory-flow-interactive.test.js +0 -109
  784. package/dist/memory-flow-tui.test.d.ts +0 -1
  785. package/dist/memory-flow-tui.test.js +0 -247
  786. package/dist/next-steps.test.d.ts +0 -1
  787. package/dist/next-steps.test.js +0 -77
  788. package/dist/notion-page-picker.test.d.ts +0 -1
  789. package/dist/notion-page-picker.test.js +0 -244
  790. package/dist/print-command-tree.test.d.ts +0 -1
  791. package/dist/print-command-tree.test.js +0 -37
  792. package/dist/project-dir.test.d.ts +0 -1
  793. package/dist/project-dir.test.js +0 -124
  794. package/dist/project-resolver.test.d.ts +0 -1
  795. package/dist/project-resolver.test.js +0 -49
  796. package/dist/prompt-navigation.test.d.ts +0 -1
  797. package/dist/prompt-navigation.test.js +0 -33
  798. package/dist/proxy-env.test.d.ts +0 -1
  799. package/dist/proxy-env.test.js +0 -17
  800. package/dist/public-ingest-copy.test.d.ts +0 -1
  801. package/dist/public-ingest-copy.test.js +0 -24
  802. package/dist/public-ingest.test.d.ts +0 -1
  803. package/dist/public-ingest.test.js +0 -891
  804. package/dist/runtime-requirements.test.d.ts +0 -1
  805. package/dist/runtime-requirements.test.js +0 -73
  806. package/dist/runtime.test.d.ts +0 -1
  807. package/dist/runtime.test.js +0 -381
  808. package/dist/scan.test.d.ts +0 -1
  809. package/dist/scan.test.js +0 -1123
  810. package/dist/setup-agents.test.d.ts +0 -1
  811. package/dist/setup-agents.test.js +0 -1028
  812. package/dist/setup-context.test.d.ts +0 -1
  813. package/dist/setup-context.test.js +0 -491
  814. package/dist/setup-databases.test.d.ts +0 -1
  815. package/dist/setup-databases.test.js +0 -2101
  816. package/dist/setup-demo-tour.test.d.ts +0 -1
  817. package/dist/setup-demo-tour.test.js +0 -221
  818. package/dist/setup-embeddings.test.d.ts +0 -1
  819. package/dist/setup-embeddings.test.js +0 -436
  820. package/dist/setup-interrupt.test.d.ts +0 -1
  821. package/dist/setup-interrupt.test.js +0 -77
  822. package/dist/setup-models.test.d.ts +0 -1
  823. package/dist/setup-models.test.js +0 -885
  824. package/dist/setup-project.test.d.ts +0 -1
  825. package/dist/setup-project.test.js +0 -209
  826. package/dist/setup-prompts.test.d.ts +0 -1
  827. package/dist/setup-prompts.test.js +0 -208
  828. package/dist/setup-ready-menu.test.d.ts +0 -1
  829. package/dist/setup-ready-menu.test.js +0 -44
  830. package/dist/setup-runtime.test.d.ts +0 -1
  831. package/dist/setup-runtime.test.js +0 -111
  832. package/dist/setup-secrets.test.d.ts +0 -1
  833. package/dist/setup-secrets.test.js +0 -30
  834. package/dist/setup-sources-notion.test.d.ts +0 -1
  835. package/dist/setup-sources-notion.test.js +0 -109
  836. package/dist/setup-sources.test.d.ts +0 -1
  837. package/dist/setup-sources.test.js +0 -1303
  838. package/dist/setup.test.d.ts +0 -1
  839. package/dist/setup.test.js +0 -1825
  840. package/dist/sl.test.d.ts +0 -1
  841. package/dist/sl.test.js +0 -567
  842. package/dist/source-mapping.test.d.ts +0 -1
  843. package/dist/source-mapping.test.js +0 -65
  844. package/dist/sql.test.d.ts +0 -1
  845. package/dist/sql.test.js +0 -253
  846. package/dist/standalone-smoke.test.d.ts +0 -1
  847. package/dist/standalone-smoke.test.js +0 -250
  848. package/dist/status-project.test.d.ts +0 -1
  849. package/dist/status-project.test.js +0 -502
  850. package/dist/telemetry/command-hook.test.d.ts +0 -1
  851. package/dist/telemetry/command-hook.test.js +0 -31
  852. package/dist/telemetry/demo-detect.test.d.ts +0 -1
  853. package/dist/telemetry/demo-detect.test.js +0 -22
  854. package/dist/telemetry/emitter.test.d.ts +0 -1
  855. package/dist/telemetry/emitter.test.js +0 -103
  856. package/dist/telemetry/events.snapshot.test.d.ts +0 -1
  857. package/dist/telemetry/events.snapshot.test.js +0 -135
  858. package/dist/telemetry/events.test.d.ts +0 -1
  859. package/dist/telemetry/events.test.js +0 -136
  860. package/dist/telemetry/identity.test.d.ts +0 -1
  861. package/dist/telemetry/identity.test.js +0 -148
  862. package/dist/telemetry/project-snapshot.test.d.ts +0 -1
  863. package/dist/telemetry/project-snapshot.test.js +0 -71
  864. package/dist/telemetry/schema-writer.test.d.ts +0 -1
  865. package/dist/telemetry/schema-writer.test.js +0 -23
  866. package/dist/telemetry/scrubber.test.d.ts +0 -1
  867. package/dist/telemetry/scrubber.test.js +0 -21
  868. package/dist/text-ingest.test.d.ts +0 -1
  869. package/dist/text-ingest.test.js +0 -247
  870. package/dist/tree-picker-state.test.d.ts +0 -1
  871. package/dist/tree-picker-state.test.js +0 -303
  872. package/dist/tree-picker-tui.test.d.ts +0 -1
  873. package/dist/tree-picker-tui.test.js +0 -248
  874. package/dist/viz-fallback.test.d.ts +0 -1
  875. package/dist/viz-fallback.test.js +0 -77
@@ -1,1825 +0,0 @@
1
- import { execFile } from 'node:child_process';
2
- import { mkdir, mkdtemp, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises';
3
- import { tmpdir } from 'node:os';
4
- import { join } from 'node:path';
5
- import { promisify } from 'node:util';
6
- import { writeKtxSetupState } from './context/project/setup-config.js';
7
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
8
- import { localFakeBundleReport, persistLocalBundleReport } from './ingest.test-utils.js';
9
- import { contextBuildCommands, writeKtxSetupContextState } from './setup-context.js';
10
- import { runDemoTour } from './setup-demo-tour.js';
11
- import { formatKtxSetupCompletionSummary, formatKtxSetupStatus, readKtxSetupStatus, runKtxSetup } from './setup.js';
12
- vi.mock('./setup-demo-tour.js', () => ({
13
- runDemoTour: vi.fn(async () => 0),
14
- }));
15
- const execFileAsync = promisify(execFile);
16
- function makeIo() {
17
- let stdout = '';
18
- let stderr = '';
19
- return {
20
- io: {
21
- stdout: {
22
- isTTY: false,
23
- write: (chunk) => {
24
- stdout += chunk;
25
- },
26
- },
27
- stderr: {
28
- write: (chunk) => {
29
- stderr += chunk;
30
- },
31
- },
32
- },
33
- stdout: () => stdout,
34
- stderr: () => stderr,
35
- };
36
- }
37
- function runtimeReady(projectDir) {
38
- return { status: 'ready', projectDir, requirements: { features: ['core'], requirements: [] } };
39
- }
40
- async function writeReadyRuntime(rootDir, cliVersion = '0.2.0') {
41
- const runtimeRoot = join(rootDir, '.runtime');
42
- const versionDir = join(runtimeRoot, cliVersion);
43
- const pythonPath = join(versionDir, '.venv', 'bin', 'python');
44
- const daemonPath = join(versionDir, '.venv', 'bin', 'ktx-daemon');
45
- await mkdir(join(versionDir, '.venv', 'bin'), { recursive: true });
46
- await writeFile(pythonPath, '', 'utf-8');
47
- await writeFile(daemonPath, '', 'utf-8');
48
- await writeFile(join(versionDir, 'manifest.json'), `${JSON.stringify({
49
- schemaVersion: 1,
50
- cliVersion,
51
- installedAt: '2026-05-09T10:02:00.000Z',
52
- asset: {
53
- schemaVersion: 1,
54
- distributionName: 'kaelio-ktx',
55
- normalizedName: 'kaelio_ktx',
56
- version: '0.1.0',
57
- wheel: {
58
- file: 'kaelio_ktx-0.1.0-py3-none-any.whl',
59
- sha256: '0'.repeat(64),
60
- bytes: 0,
61
- },
62
- },
63
- features: ['core'],
64
- python: {
65
- executable: pythonPath,
66
- daemonExecutable: daemonPath,
67
- },
68
- installLog: join(versionDir, 'install.log'),
69
- }, null, 2)}\n`, 'utf-8');
70
- return runtimeRoot;
71
- }
72
- describe('setup status', () => {
73
- let tempDir;
74
- beforeEach(async () => {
75
- tempDir = await mkdtemp(join(tmpdir(), 'ktx-setup-status-'));
76
- });
77
- afterEach(async () => {
78
- vi.unstubAllEnvs();
79
- await rm(tempDir, { recursive: true, force: true });
80
- });
81
- it('reports a missing project without creating files', async () => {
82
- const status = await readKtxSetupStatus(tempDir);
83
- expect(status).toMatchObject({
84
- project: { path: tempDir, ready: false },
85
- llm: { ready: false },
86
- embeddings: { ready: false },
87
- databases: [],
88
- sources: [],
89
- context: { ready: false, status: 'not_started' },
90
- agents: [],
91
- });
92
- });
93
- it('reports disabled default embeddings as not setup-ready', async () => {
94
- await mkdir(tempDir, { recursive: true });
95
- await writeFile(join(tempDir, 'ktx.yaml'), [
96
- 'llm:',
97
- ' provider:',
98
- ' backend: anthropic',
99
- ' anthropic:',
100
- ' api_key: env:ANTHROPIC_API_KEY', // pragma: allowlist secret
101
- ' models:',
102
- ' default: claude-sonnet-4-6',
103
- 'ingest:',
104
- ' embeddings:',
105
- ' backend: none',
106
- ' dimensions: 8',
107
- 'connections: {}',
108
- ].join('\n'), 'utf-8');
109
- await expect(readKtxSetupStatus(tempDir)).resolves.toMatchObject({
110
- project: { path: tempDir, ready: true },
111
- llm: { backend: 'anthropic', ready: true, model: 'claude-sonnet-4-6' },
112
- embeddings: { backend: 'none', ready: false, dimensions: 8 },
113
- });
114
- });
115
- it.each([
116
- {
117
- backend: 'vertex',
118
- providerLines: [' backend: vertex', ' vertex:', ' project: kaelio-dev', ' location: us-east5'],
119
- model: 'claude-sonnet-4-6',
120
- },
121
- {
122
- backend: 'gateway',
123
- providerLines: [' backend: gateway', ' gateway:', ' api_key: env:AI_GATEWAY_API_KEY'],
124
- model: 'anthropic/claude-sonnet-4-6',
125
- },
126
- ])('reports configured $backend llm backends as setup-ready', async (fixture) => {
127
- await mkdir(tempDir, { recursive: true });
128
- await writeFile(join(tempDir, 'ktx.yaml'), [
129
- 'llm:',
130
- ' provider:',
131
- ...fixture.providerLines,
132
- ' models:',
133
- ` default: ${fixture.model}`,
134
- 'connections: {}',
135
- ].join('\n'), 'utf-8');
136
- await expect(readKtxSetupStatus(tempDir)).resolves.toMatchObject({
137
- llm: { backend: fixture.backend, ready: true, model: fixture.model },
138
- });
139
- });
140
- it('uses setup database connection ids when present', async () => {
141
- await writeFile(join(tempDir, 'ktx.yaml'), [
142
- 'setup:',
143
- ' database_connection_ids:',
144
- ' - warehouse',
145
- ' - analytics',
146
- 'connections:',
147
- ' warehouse:',
148
- ' driver: postgres',
149
- ' url: env:WAREHOUSE_URL',
150
- 'ingest:',
151
- ' embeddings:',
152
- ' backend: openai',
153
- ' model: text-embedding-3-small',
154
- ' dimensions: 1536',
155
- ' openai:',
156
- ' api_key: env:OPENAI_API_KEY', // pragma: allowlist secret
157
- ].join('\n'), 'utf-8');
158
- await writeKtxSetupState(tempDir, { completed_steps: ['project', 'databases'] });
159
- await expect(readKtxSetupStatus(tempDir)).resolves.toMatchObject({
160
- databases: [
161
- { connectionId: 'warehouse', ready: true },
162
- { connectionId: 'analytics', ready: false },
163
- ],
164
- });
165
- });
166
- it('reports selected databases as ready only after the database setup step is complete', async () => {
167
- await writeFile(join(tempDir, 'ktx.yaml'), [
168
- 'setup:',
169
- ' database_connection_ids:',
170
- ' - warehouse',
171
- 'connections:',
172
- ' warehouse:',
173
- ' driver: postgres',
174
- ' url: env:DATABASE_URL',
175
- '',
176
- ].join('\n'), 'utf-8');
177
- await writeKtxSetupState(tempDir, { completed_steps: ['project'] });
178
- await expect(readKtxSetupStatus(tempDir)).resolves.toMatchObject({
179
- databases: [{ connectionId: 'warehouse', ready: false }],
180
- });
181
- await writeFile(join(tempDir, 'ktx.yaml'), [
182
- 'setup:',
183
- ' database_connection_ids:',
184
- ' - warehouse',
185
- 'connections:',
186
- ' warehouse:',
187
- ' driver: postgres',
188
- ' url: env:DATABASE_URL',
189
- '',
190
- ].join('\n'), 'utf-8');
191
- await writeKtxSetupState(tempDir, { completed_steps: ['project', 'databases'] });
192
- await expect(readKtxSetupStatus(tempDir)).resolves.toMatchObject({
193
- databases: [{ connectionId: 'warehouse', ready: true }],
194
- });
195
- });
196
- it('reports source status from configured source connections', async () => {
197
- await writeFile(join(tempDir, 'ktx.yaml'), [
198
- 'setup:',
199
- ' database_connection_ids: []',
200
- 'connections:',
201
- ' docs:',
202
- ' driver: notion',
203
- ' auth_token_ref: env:NOTION_TOKEN',
204
- ' crawl_mode: all_accessible',
205
- ' warehouse:',
206
- ' driver: postgres',
207
- ' url: env:DATABASE_URL',
208
- '',
209
- ].join('\n'), 'utf-8');
210
- await writeKtxSetupState(tempDir, { completed_steps: ['project', 'sources'] });
211
- await expect(readKtxSetupStatus(tempDir)).resolves.toMatchObject({
212
- sources: [{ connectionId: 'docs', type: 'notion', ready: true }],
213
- });
214
- });
215
- it('reports agent status from the install manifest', async () => {
216
- await mkdir(join(tempDir, '.ktx', 'agents'), { recursive: true });
217
- await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8');
218
- await writeFile(join(tempDir, '.ktx/agents/install-manifest.json'), JSON.stringify({
219
- version: 1,
220
- projectDir: tempDir,
221
- installedAt: '2026-05-07T00:00:00.000Z',
222
- installs: [
223
- { target: 'codex', scope: 'project', mode: 'mcp' },
224
- { target: 'codex', scope: 'project', mode: 'mcp-cli' },
225
- ],
226
- entries: [],
227
- }, null, 2), 'utf-8');
228
- await expect(readKtxSetupStatus(tempDir)).resolves.toMatchObject({
229
- agents: [{ target: 'codex', scope: 'project', ready: true }],
230
- });
231
- });
232
- it('reports setup-managed context build status and commands', async () => {
233
- await writeFile(join(tempDir, 'ktx.yaml'), [
234
- 'setup:',
235
- ' database_connection_ids:',
236
- ' - warehouse',
237
- 'connections:',
238
- ' warehouse:',
239
- ' driver: postgres',
240
- ' url: env:DATABASE_URL',
241
- 'llm:',
242
- ' provider:',
243
- ' backend: anthropic',
244
- ' models:',
245
- ' default: claude-sonnet-4-6',
246
- 'ingest:',
247
- ' embeddings:',
248
- ' backend: openai',
249
- ' model: text-embedding-3-small',
250
- ' dimensions: 1536',
251
- '',
252
- ].join('\n'), 'utf-8');
253
- await writeKtxSetupState(tempDir, {
254
- completed_steps: ['project', 'llm', 'embeddings', 'databases', 'sources'],
255
- });
256
- await writeKtxSetupContextState(tempDir, {
257
- runId: 'setup-context-local-abc123',
258
- status: 'stale',
259
- startedAt: '2026-05-09T10:00:00.000Z',
260
- updatedAt: '2026-05-09T10:01:00.000Z',
261
- primarySourceConnectionIds: ['warehouse'],
262
- contextSourceConnectionIds: [],
263
- reportIds: [],
264
- artifactPaths: [],
265
- retryableFailedTargets: [],
266
- commands: contextBuildCommands(tempDir),
267
- failureReason: 'Previous foreground context build did not finish. Rerun setup or ktx ingest.',
268
- });
269
- await expect(readKtxSetupStatus(tempDir)).resolves.toMatchObject({
270
- context: {
271
- ready: false,
272
- status: 'stale',
273
- runId: 'setup-context-local-abc123',
274
- statusCommand: `ktx status --project-dir ${tempDir}`,
275
- detail: 'Previous foreground context build did not finish. Rerun setup or ktx ingest.',
276
- },
277
- });
278
- });
279
- it('reports Vertex LLM and context ready after a successful Metabase ingest report', async () => {
280
- await writeFile(join(tempDir, 'ktx.yaml'), [
281
- 'setup:',
282
- ' database_connection_ids:',
283
- ' - warehouse',
284
- 'connections:',
285
- ' warehouse:',
286
- ' driver: postgres',
287
- ' url: env:DATABASE_URL',
288
- ' metabase:',
289
- ' driver: metabase',
290
- ' api_url: https://metabase.example.test',
291
- ' api_key_ref: env:METABASE_API_KEY',
292
- ' warehouse_connection_id: warehouse',
293
- 'llm:',
294
- ' provider:',
295
- ' backend: vertex',
296
- ' vertex:',
297
- ' project: kaelio-dev',
298
- ' location: us-east5',
299
- ' models:',
300
- ' default: claude-sonnet-4-6',
301
- 'ingest:',
302
- ' embeddings:',
303
- ' backend: none',
304
- ' dimensions: 8',
305
- '',
306
- ].join('\n'), 'utf-8');
307
- await writeKtxSetupState(tempDir, { completed_steps: ['project', 'databases', 'sources'] });
308
- await persistLocalBundleReport(tempDir, localFakeBundleReport('metabase-job-1', {
309
- connectionId: 'warehouse',
310
- sourceKey: 'metabase',
311
- }));
312
- const status = await readKtxSetupStatus(tempDir);
313
- const rendered = formatKtxSetupStatus(status);
314
- expect(status.llm).toMatchObject({ backend: 'vertex', ready: true, model: 'claude-sonnet-4-6' });
315
- expect(status.context).toMatchObject({ ready: true, status: 'completed' });
316
- expect(rendered).toContain('LLM ready: yes (claude-sonnet-4-6)');
317
- expect(rendered).toContain('KTX context built: yes');
318
- });
319
- it('formats plain and JSON setup status payloads', async () => {
320
- const status = await readKtxSetupStatus(tempDir);
321
- const rendered = formatKtxSetupStatus(status);
322
- expect(rendered).toContain(`No KTX project found at ${tempDir}.`);
323
- expect(rendered).toContain('Check another project: ktx --project-dir <folder> status');
324
- expect(rendered).toContain('Or from that folder: ktx status');
325
- expect(rendered).toContain('Create a new KTX project here: ktx setup');
326
- expect(rendered).not.toContain('Project ready: no');
327
- expect(JSON.parse(JSON.stringify(status))).toMatchObject({ project: { path: tempDir, ready: false } });
328
- });
329
- it('prints the readiness checklist for an existing project', async () => {
330
- await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8');
331
- const rendered = formatKtxSetupStatus(await readKtxSetupStatus(tempDir));
332
- expect(rendered).toContain(`KTX project: ${tempDir}`);
333
- expect(rendered).toContain('Project ready: yes');
334
- expect(rendered).toContain('LLM ready: no');
335
- expect(rendered).toContain('Databases configured: no');
336
- expect(rendered).not.toContain(['Primary sources', 'configured'].join(' '));
337
- expect(rendered).toContain('KTX context built: no');
338
- expect(rendered).not.toContain('No KTX project found.');
339
- });
340
- it('formats a concise ready summary for completed agent setup', () => {
341
- const rendered = formatKtxSetupCompletionSummary({
342
- project: { path: tempDir, ready: true },
343
- llm: { ready: true, model: 'sonnet' },
344
- embeddings: { ready: true, model: 'text-embedding-3-small' },
345
- databases: [{ connectionId: 'postgres-warehouse', ready: true }],
346
- sources: [{ connectionId: 'dbt-main', type: 'dbt', ready: true }],
347
- runtime: { required: true, ready: true, features: ['core'] },
348
- context: { ready: true, status: 'completed' },
349
- agents: [
350
- { target: 'claude-code', scope: 'project', ready: true },
351
- { target: 'claude-desktop', scope: 'global', ready: true },
352
- ],
353
- }, {
354
- agentNextActions: [
355
- '1. Start MCP',
356
- ' Run this command before using Claude Code:',
357
- '',
358
- ' RUN:',
359
- ` ktx mcp start --project-dir ${tempDir}`,
360
- '',
361
- ' If you need to stop MCP later:',
362
- ` ktx mcp stop --project-dir ${tempDir}`,
363
- '',
364
- '2. Open Claude Code',
365
- ' Open Claude Code from the KTX project directory:',
366
- '',
367
- ' RUN:',
368
- ` cd '${tempDir}'`,
369
- ' claude',
370
- ].join('\n'),
371
- });
372
- expect(rendered).toContain(`Project\n ${tempDir}`);
373
- expect(rendered).toContain('Context\n built');
374
- expect(rendered).toContain('Agents configured\n Claude Code, Claude Desktop');
375
- expect(rendered).toContain('REQUIRED BEFORE USING AGENTS\n\n 1. Start MCP');
376
- expect(rendered).toContain(' Run this command before using Claude Code:');
377
- expect(rendered).toContain(' RUN:');
378
- expect(rendered).toContain(' If you need to stop MCP later:');
379
- expect(rendered).toContain(`ktx mcp stop --project-dir ${tempDir}`);
380
- expect(rendered).toContain('After that, try\n Ask your agent: "Use KTX to show me the available tables."');
381
- expect(rendered).not.toContain('Verify');
382
- expect(rendered).not.toContain('Project ready: yes');
383
- expect(rendered).not.toContain('What you can do next');
384
- });
385
- it('prints agent next actions inside the final ready summary during full setup', async () => {
386
- const testIo = makeIo();
387
- await expect(runKtxSetup({
388
- command: 'run',
389
- projectDir: tempDir,
390
- mode: 'auto',
391
- agents: false,
392
- target: 'claude-code',
393
- skipAgents: false,
394
- inputMode: 'disabled',
395
- yes: true,
396
- cliVersion: '0.2.0',
397
- skipLlm: true,
398
- skipEmbeddings: true,
399
- skipDatabases: true,
400
- skipSources: true,
401
- databaseSchemas: [],
402
- }, testIo.io, {
403
- runtime: async () => runtimeReady(tempDir),
404
- context: async () => {
405
- await writeKtxSetupContextState(tempDir, {
406
- runId: 'setup-context-local-test',
407
- status: 'completed',
408
- primarySourceConnectionIds: [],
409
- contextSourceConnectionIds: [],
410
- reportIds: [],
411
- artifactPaths: [],
412
- retryableFailedTargets: [],
413
- commands: contextBuildCommands(tempDir),
414
- });
415
- await writeKtxSetupState(tempDir, { completed_steps: ['project', 'context'] });
416
- return { status: 'ready', projectDir: tempDir, runId: 'setup-context-local-test' };
417
- },
418
- })).resolves.toBe(0);
419
- const output = testIo.stdout();
420
- expect(output).toContain('Claude Code · Project scope');
421
- expect(output).toContain(join(tempDir, '.mcp.json'));
422
- expect(output).toContain('Requires MCP to be started.');
423
- expect(output).toContain('Analytics skill installed.');
424
- expect(output).not.toContain('Agent integration complete');
425
- expect(output).toContain('Finish KTX agent setup');
426
- expect(output).not.toContain('KTX project ready');
427
- expect(output).toContain('REQUIRED BEFORE USING AGENTS');
428
- expect(output).toContain('Run this command before using Claude Code:');
429
- expect(output).toContain(`ktx mcp start --project-dir ${tempDir}`);
430
- expect(output).not.toContain('Finish agent setup');
431
- });
432
- it('emits debug telemetry for setup steps without project paths', async () => {
433
- vi.stubEnv('KTX_TELEMETRY_DEBUG', '1');
434
- vi.stubEnv('CI', '');
435
- const testIo = makeIo();
436
- testIo.io.stdout.isTTY = true;
437
- await expect(runKtxSetup({
438
- command: 'run',
439
- projectDir: tempDir,
440
- mode: 'auto',
441
- agents: false,
442
- skipAgents: true,
443
- inputMode: 'disabled',
444
- yes: true,
445
- cliVersion: '0.2.0',
446
- skipLlm: true,
447
- skipEmbeddings: true,
448
- skipDatabases: true,
449
- skipSources: true,
450
- databaseSchemas: [],
451
- }, testIo.io, {
452
- runtime: async () => runtimeReady(tempDir),
453
- context: async () => ({ status: 'ready', projectDir: tempDir, runId: 'setup-context-local-test' }),
454
- })).resolves.toBe(0);
455
- expect(testIo.stderr()).toContain('"event":"setup_step"');
456
- expect(testIo.stderr()).toContain('"step":"project"');
457
- expect(testIo.stderr()).toContain('"step":"models"');
458
- expect(testIo.stderr()).not.toContain(tempDir);
459
- });
460
- it('prints the setup shell intro for auto-created run mode', async () => {
461
- const testIo = makeIo();
462
- await expect(runKtxSetup({
463
- command: 'run',
464
- projectDir: tempDir,
465
- mode: 'auto',
466
- agents: false,
467
- skipAgents: true,
468
- inputMode: 'disabled',
469
- yes: true,
470
- cliVersion: '0.2.0',
471
- skipLlm: true,
472
- skipEmbeddings: true,
473
- databaseSchemas: [],
474
- skipDatabases: true,
475
- skipSources: true,
476
- }, testIo.io)).resolves.toBe(0);
477
- expect(testIo.stdout()).toContain('KTX setup');
478
- expect(testIo.stdout()).toContain(`Project: ${tempDir}`);
479
- expect(testIo.stdout()).toContain('Project ready: yes');
480
- expect(testIo.stdout()).toContain('What you can do next:');
481
- expect(testIo.stdout()).toContain('Connect data, then build context.');
482
- expect(testIo.stdout()).toContain('ktx setup');
483
- expect(testIo.stdout()).not.toContain('ktx agent context --json');
484
- expect(testIo.stdout()).not.toContain('Optional MCP:');
485
- expect(testIo.stderr()).toBe('');
486
- });
487
- it('removes a newly created missing project directory when a later runtime step fails', async () => {
488
- const projectDir = join(tempDir, 'missing-project');
489
- const testIo = makeIo();
490
- await expect(runKtxSetup({
491
- command: 'run',
492
- projectDir,
493
- mode: 'auto',
494
- agents: false,
495
- skipAgents: true,
496
- inputMode: 'disabled',
497
- yes: true,
498
- cliVersion: '0.2.0',
499
- skipLlm: true,
500
- skipEmbeddings: true,
501
- databaseSchemas: [],
502
- skipDatabases: true,
503
- skipSources: true,
504
- }, testIo.io, {
505
- model: async () => ({ status: 'skipped', projectDir }),
506
- embeddings: async () => ({ status: 'skipped', projectDir }),
507
- databases: async () => ({ status: 'skipped', projectDir }),
508
- sources: async () => ({ status: 'skipped', projectDir }),
509
- runtime: async () => ({ status: 'failed', projectDir, requirements: { features: ['core'], requirements: [] } }),
510
- })).resolves.toBe(1);
511
- await expect(stat(projectDir)).rejects.toThrow();
512
- });
513
- it('removes KTX scaffold files from an initially empty project directory when runtime setup fails', async () => {
514
- const testIo = makeIo();
515
- await expect(runKtxSetup({
516
- command: 'run',
517
- projectDir: tempDir,
518
- mode: 'auto',
519
- agents: false,
520
- skipAgents: true,
521
- inputMode: 'disabled',
522
- yes: true,
523
- cliVersion: '0.2.0',
524
- skipLlm: true,
525
- skipEmbeddings: true,
526
- databaseSchemas: [],
527
- skipDatabases: true,
528
- skipSources: true,
529
- }, testIo.io, {
530
- model: async () => ({ status: 'skipped', projectDir: tempDir }),
531
- embeddings: async () => ({ status: 'skipped', projectDir: tempDir }),
532
- databases: async () => ({ status: 'skipped', projectDir: tempDir }),
533
- sources: async () => ({ status: 'skipped', projectDir: tempDir }),
534
- runtime: async () => ({ status: 'failed', projectDir: tempDir, requirements: { features: ['core'], requirements: [] } }),
535
- })).resolves.toBe(1);
536
- await expect(stat(tempDir)).resolves.toBeDefined();
537
- expect(await readdir(tempDir)).toEqual([]);
538
- });
539
- it('preserves a pre-existing non-empty project directory when runtime setup fails', async () => {
540
- await writeFile(join(tempDir, 'notes.txt'), 'keep me\n', 'utf-8');
541
- const testIo = makeIo();
542
- await expect(runKtxSetup({
543
- command: 'run',
544
- projectDir: tempDir,
545
- mode: 'auto',
546
- agents: false,
547
- skipAgents: true,
548
- inputMode: 'disabled',
549
- yes: true,
550
- cliVersion: '0.2.0',
551
- skipLlm: true,
552
- skipEmbeddings: true,
553
- databaseSchemas: [],
554
- skipDatabases: true,
555
- skipSources: true,
556
- }, testIo.io, {
557
- model: async () => ({ status: 'skipped', projectDir: tempDir }),
558
- embeddings: async () => ({ status: 'skipped', projectDir: tempDir }),
559
- databases: async () => ({ status: 'skipped', projectDir: tempDir }),
560
- sources: async () => ({ status: 'skipped', projectDir: tempDir }),
561
- runtime: async () => ({ status: 'failed', projectDir: tempDir, requirements: { features: ['core'], requirements: [] } }),
562
- })).resolves.toBe(1);
563
- await expect(readFile(join(tempDir, 'notes.txt'), 'utf-8')).resolves.toBe('keep me\n');
564
- await expect(stat(join(tempDir, 'ktx.yaml'))).resolves.toBeDefined();
565
- });
566
- it('shows demo near the bottom of the first setup intent menu before project creation', async () => {
567
- const testIo = makeIo();
568
- const select = vi.fn(async (options) => {
569
- const labels = options.options.map((option) => option.label);
570
- expect(labels).toEqual([
571
- 'Set up KTX for my data',
572
- 'Check setup status',
573
- 'Explore a pre-built KTX project',
574
- 'Exit',
575
- ]);
576
- expect(labels.indexOf('Explore a pre-built KTX project')).toBe(labels.length - 2);
577
- return 'exit';
578
- });
579
- const cancel = vi.fn();
580
- await expect(runKtxSetup({
581
- command: 'run',
582
- projectDir: tempDir,
583
- mode: 'auto',
584
- agents: false,
585
- skipAgents: false,
586
- inputMode: 'auto',
587
- yes: false,
588
- cliVersion: '0.2.0',
589
- skipLlm: false,
590
- skipEmbeddings: false,
591
- databaseSchemas: [],
592
- skipDatabases: false,
593
- skipSources: false,
594
- showEntryMenu: true,
595
- }, testIo.io, { entryMenuDeps: { prompts: { select, cancel } } })).resolves.toBe(0);
596
- expect(select).toHaveBeenCalledWith(expect.objectContaining({ message: 'What do you want to do?' }));
597
- expect(cancel).toHaveBeenCalledWith('Setup cancelled.');
598
- });
599
- it('shows agent connection only when the selected setup project exists', async () => {
600
- const missingIo = makeIo();
601
- const existingIo = makeIo();
602
- const missingSelect = vi.fn(async (options) => {
603
- expect(options.options.map((option) => option.label)).not.toContain('Connect a coding agent to KTX');
604
- return 'exit';
605
- });
606
- const existingSelect = vi.fn(async (options) => {
607
- const labels = options.options.map((option) => option.label);
608
- expect(labels).toEqual([
609
- 'Resume or change an existing setup',
610
- 'Create a new KTX project',
611
- 'Connect a coding agent to KTX',
612
- 'Check setup status',
613
- 'Explore a pre-built KTX project',
614
- 'Exit',
615
- ]);
616
- return 'exit';
617
- });
618
- await expect(runKtxSetup({
619
- command: 'run',
620
- projectDir: tempDir,
621
- mode: 'auto',
622
- agents: false,
623
- skipAgents: false,
624
- inputMode: 'auto',
625
- yes: false,
626
- cliVersion: '0.2.0',
627
- skipLlm: false,
628
- skipEmbeddings: false,
629
- databaseSchemas: [],
630
- skipDatabases: false,
631
- skipSources: false,
632
- showEntryMenu: true,
633
- }, missingIo.io, { entryMenuDeps: { prompts: { select: missingSelect, cancel: vi.fn() } } })).resolves.toBe(0);
634
- await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8');
635
- await expect(runKtxSetup({
636
- command: 'run',
637
- projectDir: tempDir,
638
- mode: 'auto',
639
- agents: false,
640
- skipAgents: false,
641
- inputMode: 'auto',
642
- yes: false,
643
- cliVersion: '0.2.0',
644
- skipLlm: false,
645
- skipEmbeddings: false,
646
- databaseSchemas: [],
647
- skipDatabases: false,
648
- skipSources: false,
649
- showEntryMenu: true,
650
- }, existingIo.io, { entryMenuDeps: { prompts: { select: existingSelect, cancel: vi.fn() } } })).resolves.toBe(0);
651
- expect(missingSelect).toHaveBeenCalledTimes(1);
652
- expect(existingSelect).toHaveBeenCalledTimes(1);
653
- });
654
- it('lets Back from project selection return to the first setup intent menu', async () => {
655
- const entryChoices = ['setup', 'exit'];
656
- const entryPrompts = {
657
- select: vi.fn(async () => entryChoices.shift() ?? 'exit'),
658
- cancel: vi.fn(),
659
- };
660
- const projectPrompts = {
661
- select: vi.fn(async () => 'back'),
662
- text: vi.fn(),
663
- cancel: vi.fn(),
664
- };
665
- await expect(runKtxSetup({
666
- command: 'run',
667
- projectDir: tempDir,
668
- mode: 'auto',
669
- agents: false,
670
- skipAgents: true,
671
- inputMode: 'auto',
672
- yes: false,
673
- cliVersion: '0.2.0',
674
- skipLlm: true,
675
- skipEmbeddings: true,
676
- databaseSchemas: [],
677
- skipDatabases: true,
678
- skipSources: true,
679
- showEntryMenu: true,
680
- }, makeIo().io, {
681
- entryMenuDeps: { prompts: entryPrompts },
682
- project: { prompts: projectPrompts },
683
- })).resolves.toBe(0);
684
- expect(projectPrompts.select).toHaveBeenCalledWith(expect.objectContaining({
685
- message: 'Where should KTX create the project?',
686
- options: expect.arrayContaining([expect.objectContaining({ value: 'back', label: 'Back' })]),
687
- }));
688
- expect(projectPrompts.select).toHaveBeenCalledWith(expect.objectContaining({
689
- message: 'Where should KTX create the project?',
690
- options: expect.not.arrayContaining([expect.objectContaining({ value: 'exit', label: 'Exit' })]),
691
- }));
692
- expect(entryPrompts.select).toHaveBeenCalledTimes(2);
693
- expect(entryPrompts.cancel).toHaveBeenCalledWith('Setup cancelled.');
694
- expect(projectPrompts.cancel).not.toHaveBeenCalled();
695
- await expect(stat(join(tempDir, 'ktx.yaml'))).rejects.toThrow();
696
- });
697
- it('lets Back from new project creation return to the first setup intent menu', async () => {
698
- const existingConfig = 'connections: {}\n';
699
- await writeFile(join(tempDir, 'ktx.yaml'), existingConfig, 'utf-8');
700
- const entryChoices = ['new-project', 'exit'];
701
- const entryPrompts = {
702
- select: vi.fn(async () => entryChoices.shift() ?? 'exit'),
703
- cancel: vi.fn(),
704
- };
705
- const projectPrompts = {
706
- select: vi.fn(async () => 'back'),
707
- text: vi.fn(),
708
- cancel: vi.fn(),
709
- };
710
- await expect(runKtxSetup({
711
- command: 'run',
712
- projectDir: tempDir,
713
- mode: 'auto',
714
- agents: false,
715
- skipAgents: true,
716
- inputMode: 'auto',
717
- yes: false,
718
- cliVersion: '0.2.0',
719
- skipLlm: true,
720
- skipEmbeddings: true,
721
- databaseSchemas: [],
722
- skipDatabases: true,
723
- skipSources: true,
724
- showEntryMenu: true,
725
- }, makeIo().io, {
726
- entryMenuDeps: { prompts: entryPrompts },
727
- project: { prompts: projectPrompts },
728
- })).resolves.toBe(0);
729
- expect(projectPrompts.select).toHaveBeenCalledWith(expect.objectContaining({
730
- message: 'Where should KTX create the project?',
731
- options: expect.arrayContaining([expect.objectContaining({ value: 'back', label: 'Back' })]),
732
- }));
733
- expect(entryPrompts.select).toHaveBeenCalledTimes(2);
734
- expect(entryPrompts.cancel).toHaveBeenCalledWith('Setup cancelled.');
735
- expect(projectPrompts.cancel).not.toHaveBeenCalled();
736
- await expect(readFile(join(tempDir, 'ktx.yaml'), 'utf-8')).resolves.toBe(existingConfig);
737
- });
738
- it('creates a separate project when the existing setup menu chooses new project', async () => {
739
- const existingProjectDir = join(tempDir, 'existing');
740
- const newProjectDir = join(tempDir, 'fresh');
741
- await mkdir(existingProjectDir, { recursive: true });
742
- const existingConfig = 'connections: {}\n';
743
- await writeFile(join(existingProjectDir, 'ktx.yaml'), existingConfig, 'utf-8');
744
- const projectChoices = ['custom', 'create'];
745
- const projectPrompts = {
746
- select: vi.fn(async () => projectChoices.shift() ?? 'exit'),
747
- text: vi.fn(async () => newProjectDir),
748
- cancel: vi.fn(),
749
- };
750
- const model = vi.fn(async (args) => ({
751
- status: 'skipped',
752
- projectDir: args.projectDir,
753
- }));
754
- const embeddings = vi.fn(async (args) => ({
755
- status: 'skipped',
756
- projectDir: args.projectDir,
757
- }));
758
- const databases = vi.fn(async (args) => ({
759
- status: 'skipped',
760
- projectDir: args.projectDir,
761
- }));
762
- const sources = vi.fn(async (args) => ({
763
- status: 'skipped',
764
- projectDir: args.projectDir,
765
- }));
766
- await expect(runKtxSetup({
767
- command: 'run',
768
- projectDir: existingProjectDir,
769
- mode: 'auto',
770
- agents: false,
771
- skipAgents: true,
772
- inputMode: 'auto',
773
- yes: false,
774
- cliVersion: '0.2.0',
775
- skipLlm: true,
776
- skipEmbeddings: true,
777
- databaseSchemas: [],
778
- skipDatabases: true,
779
- skipSources: true,
780
- showEntryMenu: true,
781
- }, makeIo().io, {
782
- entryMenuDeps: { prompts: { select: vi.fn(async () => 'new-project'), cancel: vi.fn() } },
783
- project: { prompts: projectPrompts },
784
- model,
785
- embeddings,
786
- databases,
787
- sources,
788
- })).resolves.toBe(0);
789
- expect(projectPrompts.text).toHaveBeenCalledWith(expect.objectContaining({
790
- message: 'Project folder path\n│ Press Escape to go back.\n│',
791
- placeholder: './analytics-ktx, ~/analytics-ktx, or /Users/you/projects/analytics-ktx',
792
- }));
793
- expect(projectPrompts.select).toHaveBeenCalledWith(expect.objectContaining({ message: 'Where should KTX create the project?' }));
794
- await expect(stat(join(newProjectDir, 'ktx.yaml'))).resolves.toBeDefined();
795
- await expect(readFile(join(existingProjectDir, 'ktx.yaml'), 'utf-8')).resolves.toBe(existingConfig);
796
- expect(model).toHaveBeenCalledWith(expect.objectContaining({ projectDir: newProjectDir }), expect.anything());
797
- expect(embeddings).toHaveBeenCalledWith(expect.objectContaining({ projectDir: newProjectDir }), expect.anything());
798
- expect(databases).toHaveBeenCalledWith(expect.objectContaining({ projectDir: newProjectDir }), expect.anything());
799
- expect(sources).toHaveBeenCalledWith(expect.objectContaining({ projectDir: newProjectDir }), expect.anything());
800
- });
801
- it('does not print navigation instructions immediately after confirming new project creation', async () => {
802
- const existingProjectDir = join(tempDir, 'existing');
803
- const newProjectDir = join(tempDir, 'fresh');
804
- await mkdir(existingProjectDir, { recursive: true });
805
- await writeFile(join(existingProjectDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8');
806
- const projectChoices = ['custom', 'create'];
807
- const projectPrompts = {
808
- select: vi.fn(async () => projectChoices.shift() ?? 'exit'),
809
- text: vi.fn(async () => newProjectDir),
810
- cancel: vi.fn(),
811
- };
812
- const model = vi.fn(async (args) => {
813
- expect(args.showPromptInstructions).toBe(false);
814
- return { status: 'skipped', projectDir: args.projectDir };
815
- });
816
- const testIo = makeIo();
817
- await expect(runKtxSetup({
818
- command: 'run',
819
- projectDir: existingProjectDir,
820
- mode: 'auto',
821
- agents: false,
822
- skipAgents: true,
823
- inputMode: 'auto',
824
- yes: false,
825
- cliVersion: '0.2.0',
826
- skipLlm: false,
827
- skipEmbeddings: true,
828
- databaseSchemas: [],
829
- skipDatabases: true,
830
- skipSources: true,
831
- showEntryMenu: true,
832
- }, testIo.io, {
833
- entryMenuDeps: { prompts: { select: vi.fn(async () => 'new-project'), cancel: vi.fn() } },
834
- project: { prompts: projectPrompts },
835
- model,
836
- })).resolves.toBe(0);
837
- expect(testIo.stdout()).toContain(`Project: ${newProjectDir}\n`);
838
- expect(testIo.stdout()).not.toContain('Use Up/Down to move, Enter to confirm the current selection, choose Back to return to the previous step, Ctrl+C to exit.');
839
- });
840
- it('runs the demo tour when the first setup intent menu chooses demo', async () => {
841
- const testIo = makeIo();
842
- await expect(runKtxSetup({
843
- command: 'run',
844
- projectDir: tempDir,
845
- mode: 'auto',
846
- agents: false,
847
- skipAgents: false,
848
- inputMode: 'auto',
849
- yes: false,
850
- cliVersion: '0.2.0',
851
- skipLlm: false,
852
- skipEmbeddings: false,
853
- databaseSchemas: [],
854
- skipDatabases: false,
855
- skipSources: false,
856
- showEntryMenu: true,
857
- }, testIo.io, { entryMenuDeps: { prompts: { select: vi.fn(async () => 'demo'), cancel: vi.fn() } } })).resolves.toBe(0);
858
- expect(runDemoTour).toHaveBeenCalledWith({ inputMode: 'auto', cliVersion: '0.2.0' }, testIo.io, expect.objectContaining({}));
859
- });
860
- it('creates a project through run mode when --yes is selected', async () => {
861
- const testIo = makeIo();
862
- await expect(runKtxSetup({
863
- command: 'run',
864
- projectDir: tempDir,
865
- mode: 'auto',
866
- agents: false,
867
- skipAgents: true,
868
- inputMode: 'disabled',
869
- yes: true,
870
- cliVersion: '0.2.0',
871
- skipLlm: true,
872
- skipEmbeddings: true,
873
- databaseSchemas: [],
874
- skipDatabases: true,
875
- skipSources: true,
876
- }, testIo.io)).resolves.toBe(0);
877
- await expect(stat(join(tempDir, 'ktx.yaml'))).resolves.toBeDefined();
878
- expect(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')).not.toContain('completed_steps:');
879
- await expect(readFile(join(tempDir, '.ktx', 'setup', 'state.json'), 'utf-8')).resolves.toBe(`${JSON.stringify({ completed_steps: ['project', 'sources'] }, null, 2)}\n`);
880
- expect(testIo.stdout()).toContain('KTX setup');
881
- expect(testIo.stdout()).toContain(`Project: ${tempDir}`);
882
- expect(testIo.stdout()).toContain('Project ready: yes');
883
- expect(testIo.stderr()).toBe('');
884
- });
885
- it('returns nonzero when project selection is missing in no-input mode even when optional sections are skipped', async () => {
886
- const testIo = makeIo();
887
- await expect(runKtxSetup({
888
- command: 'run',
889
- projectDir: tempDir,
890
- mode: 'auto',
891
- agents: false,
892
- skipAgents: true,
893
- inputMode: 'disabled',
894
- yes: false,
895
- cliVersion: '0.2.0',
896
- skipLlm: true,
897
- skipEmbeddings: true,
898
- databaseSchemas: [],
899
- skipDatabases: true,
900
- skipSources: true,
901
- }, testIo.io)).resolves.toBe(1);
902
- expect(testIo.stderr()).toContain('Missing setup choice');
903
- await expect(stat(join(tempDir, 'ktx.yaml'))).rejects.toThrow();
904
- });
905
- it('returns nonzero when project selection is missing in non-interactive setup', async () => {
906
- const testIo = makeIo();
907
- await expect(runKtxSetup({
908
- command: 'run',
909
- projectDir: tempDir,
910
- mode: 'auto',
911
- agents: false,
912
- skipAgents: true,
913
- inputMode: 'disabled',
914
- yes: false,
915
- cliVersion: '0.2.0',
916
- skipLlm: false,
917
- skipEmbeddings: true,
918
- databaseSchemas: [],
919
- skipDatabases: true,
920
- skipSources: true,
921
- }, testIo.io)).resolves.toBe(1);
922
- expect(testIo.stderr()).toContain('Missing setup choice');
923
- await expect(stat(join(tempDir, 'ktx.yaml'))).rejects.toThrow();
924
- });
925
- it('runs the Anthropic model step after project selection succeeds', async () => {
926
- const testIo = makeIo();
927
- const model = vi.fn(async () => ({ status: 'ready', projectDir: tempDir }));
928
- await expect(runKtxSetup({
929
- command: 'run',
930
- projectDir: tempDir,
931
- mode: 'auto',
932
- agents: false,
933
- skipAgents: true,
934
- inputMode: 'disabled',
935
- yes: true,
936
- cliVersion: '0.2.0',
937
- anthropicApiKeyEnv: 'ANTHROPIC_API_KEY', // pragma: allowlist secret
938
- llmModel: 'claude-sonnet-4-6',
939
- skipLlm: false,
940
- skipEmbeddings: true,
941
- databaseSchemas: [],
942
- skipDatabases: true,
943
- skipSources: true,
944
- }, testIo.io, { model })).resolves.toBe(0);
945
- expect(model).toHaveBeenCalledWith(expect.objectContaining({
946
- projectDir: tempDir,
947
- inputMode: 'disabled',
948
- anthropicApiKeyEnv: 'ANTHROPIC_API_KEY', // pragma: allowlist secret
949
- llmModel: 'claude-sonnet-4-6',
950
- skipLlm: false,
951
- }), testIo.io);
952
- });
953
- it('passes Vertex AI model setup args after project selection succeeds', async () => {
954
- const testIo = makeIo();
955
- const model = vi.fn(async () => ({ status: 'ready', projectDir: tempDir }));
956
- await expect(runKtxSetup({
957
- command: 'run',
958
- projectDir: tempDir,
959
- mode: 'auto',
960
- agents: false,
961
- skipAgents: true,
962
- inputMode: 'disabled',
963
- yes: true,
964
- cliVersion: '0.2.0',
965
- llmBackend: 'vertex',
966
- vertexProject: 'local-gcp-project',
967
- vertexLocation: 'us-east5',
968
- llmModel: 'claude-sonnet-4-6',
969
- skipLlm: false,
970
- skipEmbeddings: true,
971
- databaseSchemas: [],
972
- skipDatabases: true,
973
- skipSources: true,
974
- }, testIo.io, { model })).resolves.toBe(0);
975
- expect(model).toHaveBeenCalledWith(expect.objectContaining({
976
- projectDir: tempDir,
977
- inputMode: 'disabled',
978
- llmBackend: 'vertex',
979
- vertexProject: 'local-gcp-project',
980
- vertexLocation: 'us-east5',
981
- llmModel: 'claude-sonnet-4-6',
982
- skipLlm: false,
983
- }), testIo.io);
984
- });
985
- it('runs the embedding setup step after the model step succeeds', async () => {
986
- const testIo = makeIo();
987
- const model = vi.fn(async () => ({ status: 'ready', projectDir: tempDir }));
988
- const embeddings = vi.fn(async () => ({ status: 'ready', projectDir: tempDir }));
989
- await expect(runKtxSetup({
990
- command: 'run',
991
- projectDir: tempDir,
992
- mode: 'auto',
993
- agents: false,
994
- skipAgents: true,
995
- inputMode: 'disabled',
996
- yes: true,
997
- cliVersion: '0.2.0',
998
- anthropicApiKeyEnv: 'ANTHROPIC_API_KEY', // pragma: allowlist secret
999
- llmModel: 'claude-sonnet-4-6',
1000
- skipLlm: false,
1001
- embeddingBackend: 'openai',
1002
- embeddingApiKeyEnv: 'OPENAI_API_KEY', // pragma: allowlist secret
1003
- skipEmbeddings: false,
1004
- databaseSchemas: [],
1005
- skipDatabases: true,
1006
- skipSources: true,
1007
- }, testIo.io, { model, embeddings })).resolves.toBe(0);
1008
- expect(embeddings).toHaveBeenCalledWith(expect.objectContaining({
1009
- projectDir: tempDir,
1010
- inputMode: 'disabled',
1011
- cliVersion: '0.2.0',
1012
- runtimeInstallPolicy: 'auto',
1013
- embeddingBackend: 'openai',
1014
- embeddingApiKeyEnv: 'OPENAI_API_KEY', // pragma: allowlist secret
1015
- skipEmbeddings: false,
1016
- }), testIo.io);
1017
- });
1018
- it('passes no-input runtime policy to the embeddings step', async () => {
1019
- const io = makeIo();
1020
- const embeddings = vi.fn(async () => ({ status: 'failed', projectDir: tempDir }));
1021
- await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8');
1022
- await expect(runKtxSetup({
1023
- command: 'run',
1024
- projectDir: tempDir,
1025
- mode: 'auto',
1026
- agents: false,
1027
- agentScope: 'project',
1028
- skipAgents: true,
1029
- inputMode: 'disabled',
1030
- yes: false,
1031
- cliVersion: '0.2.0',
1032
- skipLlm: true,
1033
- skipEmbeddings: false,
1034
- databaseSchemas: [],
1035
- skipDatabases: true,
1036
- skipSources: true,
1037
- }, io.io, { embeddings })).resolves.toBe(1);
1038
- expect(embeddings).toHaveBeenCalledWith(expect.objectContaining({
1039
- cliVersion: '0.2.0',
1040
- runtimeInstallPolicy: 'never',
1041
- }), io.io);
1042
- });
1043
- it('prompts before installing the managed runtime by default during setup', async () => {
1044
- const io = makeIo();
1045
- const embeddings = vi.fn(async () => ({ status: 'ready', projectDir: tempDir }));
1046
- const context = vi.fn(async () => ({ status: 'failed', projectDir: tempDir }));
1047
- await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8');
1048
- await expect(runKtxSetup({
1049
- command: 'run',
1050
- projectDir: tempDir,
1051
- mode: 'auto',
1052
- agents: false,
1053
- agentScope: 'project',
1054
- skipAgents: true,
1055
- inputMode: 'auto',
1056
- yes: false,
1057
- cliVersion: '0.2.0',
1058
- skipLlm: true,
1059
- skipEmbeddings: false,
1060
- databaseSchemas: [],
1061
- skipDatabases: true,
1062
- skipSources: true,
1063
- }, io.io, {
1064
- embeddings,
1065
- context,
1066
- })).resolves.toBe(1);
1067
- expect(embeddings).toHaveBeenCalledWith(expect.objectContaining({
1068
- cliVersion: '0.2.0',
1069
- runtimeInstallPolicy: 'prompt',
1070
- }), io.io);
1071
- expect(context).toHaveBeenCalledWith(expect.objectContaining({
1072
- cliVersion: '0.2.0',
1073
- runtimeInstallPolicy: 'prompt',
1074
- }), io.io);
1075
- });
1076
- it('lets Back from embedding setup return to the model step instead of exiting', async () => {
1077
- const testIo = makeIo();
1078
- await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8');
1079
- const modelResults = [
1080
- { status: 'ready', projectDir: tempDir },
1081
- { status: 'back', projectDir: tempDir },
1082
- ];
1083
- const model = vi.fn(async () => modelResults.shift() ?? { status: 'back', projectDir: tempDir });
1084
- const embeddings = vi.fn(async () => ({ status: 'back', projectDir: tempDir }));
1085
- await expect(runKtxSetup({
1086
- command: 'run',
1087
- projectDir: tempDir,
1088
- mode: 'auto',
1089
- agents: false,
1090
- skipAgents: true,
1091
- inputMode: 'auto',
1092
- yes: false,
1093
- cliVersion: '0.2.0',
1094
- skipLlm: false,
1095
- skipEmbeddings: false,
1096
- databaseSchemas: [],
1097
- skipDatabases: true,
1098
- skipSources: true,
1099
- }, testIo.io, { model, embeddings })).resolves.toBe(0);
1100
- expect(model).toHaveBeenCalledTimes(2);
1101
- expect(model).toHaveBeenNthCalledWith(2, expect.objectContaining({ forcePrompt: true }), testIo.io);
1102
- expect(embeddings).toHaveBeenCalledTimes(1);
1103
- });
1104
- it('lets Back from database selection return to embedding setup', async () => {
1105
- const testIo = makeIo();
1106
- await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8');
1107
- const modelResults = [
1108
- { status: 'ready', projectDir: tempDir },
1109
- { status: 'back', projectDir: tempDir },
1110
- ];
1111
- const model = vi.fn(async () => modelResults.shift() ?? { status: 'back', projectDir: tempDir });
1112
- const embeddingResults = [
1113
- { status: 'ready', projectDir: tempDir },
1114
- { status: 'back', projectDir: tempDir },
1115
- ];
1116
- const embeddings = vi.fn(async () => embeddingResults.shift() ?? { status: 'back', projectDir: tempDir });
1117
- const databasePrompts = {
1118
- multiselect: vi.fn(async () => ['back']),
1119
- autocompleteMultiselect: vi.fn(async () => ['back']),
1120
- select: vi.fn(async () => 'back'),
1121
- text: vi.fn(),
1122
- password: vi.fn(),
1123
- cancel: vi.fn(),
1124
- };
1125
- await expect(runKtxSetup({
1126
- command: 'run',
1127
- projectDir: tempDir,
1128
- mode: 'auto',
1129
- agents: false,
1130
- skipAgents: true,
1131
- inputMode: 'auto',
1132
- yes: true,
1133
- cliVersion: '0.2.0',
1134
- skipLlm: false,
1135
- skipEmbeddings: false,
1136
- databaseSchemas: [],
1137
- skipDatabases: false,
1138
- skipSources: true,
1139
- }, testIo.io, {
1140
- model,
1141
- embeddings,
1142
- databasesDeps: { prompts: databasePrompts },
1143
- })).resolves.toBe(0);
1144
- expect(databasePrompts.select).not.toHaveBeenCalled();
1145
- expect(embeddings).toHaveBeenCalledTimes(2);
1146
- expect(embeddings).toHaveBeenNthCalledWith(2, expect.objectContaining({ forcePrompt: true }), testIo.io);
1147
- expect(testIo.stderr()).not.toContain('No databases selected.');
1148
- });
1149
- it('lets Back from the first setup step return to the entry menu instead of exiting', async () => {
1150
- await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8');
1151
- const testIo = makeIo();
1152
- const entryChoices = ['setup', 'exit'];
1153
- const entryPrompts = {
1154
- select: vi.fn(async () => entryChoices.shift() ?? 'exit'),
1155
- cancel: vi.fn(),
1156
- };
1157
- const model = vi.fn(async () => ({ status: 'back', projectDir: tempDir }));
1158
- await expect(runKtxSetup({
1159
- command: 'run',
1160
- projectDir: tempDir,
1161
- mode: 'auto',
1162
- agents: false,
1163
- skipAgents: true,
1164
- inputMode: 'auto',
1165
- yes: true,
1166
- cliVersion: '0.2.0',
1167
- skipLlm: false,
1168
- skipEmbeddings: true,
1169
- databaseSchemas: [],
1170
- skipDatabases: true,
1171
- skipSources: true,
1172
- showEntryMenu: true,
1173
- }, testIo.io, {
1174
- entryMenuDeps: { prompts: entryPrompts },
1175
- model,
1176
- })).resolves.toBe(0);
1177
- expect(entryPrompts.select).toHaveBeenCalledTimes(2);
1178
- expect(entryPrompts.cancel).toHaveBeenCalledWith('Setup cancelled.');
1179
- expect(model).toHaveBeenCalledTimes(1);
1180
- });
1181
- it('runs database setup after embeddings succeed', async () => {
1182
- const testIo = makeIo();
1183
- const model = vi.fn(async () => ({ status: 'ready', projectDir: tempDir }));
1184
- const embeddings = vi.fn(async () => ({ status: 'ready', projectDir: tempDir }));
1185
- const databases = vi.fn(async () => ({
1186
- status: 'ready',
1187
- projectDir: tempDir,
1188
- connectionIds: ['warehouse'],
1189
- }));
1190
- await expect(runKtxSetup({
1191
- command: 'run',
1192
- projectDir: tempDir,
1193
- mode: 'auto',
1194
- agents: false,
1195
- skipAgents: true,
1196
- inputMode: 'disabled',
1197
- yes: true,
1198
- cliVersion: '0.2.0',
1199
- anthropicApiKeyEnv: 'ANTHROPIC_API_KEY', // pragma: allowlist secret
1200
- llmModel: 'claude-sonnet-4-6',
1201
- skipLlm: false,
1202
- embeddingBackend: 'openai',
1203
- embeddingApiKeyEnv: 'OPENAI_API_KEY', // pragma: allowlist secret
1204
- skipEmbeddings: false,
1205
- databaseDrivers: ['postgres'],
1206
- databaseConnectionId: 'warehouse',
1207
- databaseUrl: 'env:DATABASE_URL',
1208
- databaseSchemas: ['public'],
1209
- enableQueryHistory: true,
1210
- queryHistoryWindowDays: 30,
1211
- queryHistoryMinExecutions: 12,
1212
- queryHistoryServiceAccountPatterns: ['^svc_'],
1213
- queryHistoryRedactionPatterns: ['(?i)secret'],
1214
- skipDatabases: false,
1215
- skipSources: true,
1216
- }, testIo.io, { model, embeddings, databases })).resolves.toBe(0);
1217
- expect(databases).toHaveBeenCalledWith(expect.objectContaining({
1218
- projectDir: tempDir,
1219
- inputMode: 'disabled',
1220
- databaseDrivers: ['postgres'],
1221
- databaseConnectionId: 'warehouse',
1222
- databaseUrl: 'env:DATABASE_URL',
1223
- databaseSchemas: ['public'],
1224
- enableQueryHistory: true,
1225
- queryHistoryWindowDays: 30,
1226
- queryHistoryMinExecutions: 12,
1227
- queryHistoryServiceAccountPatterns: ['^svc_'],
1228
- queryHistoryRedactionPatterns: ['(?i)secret'],
1229
- skipDatabases: false,
1230
- }), testIo.io);
1231
- });
1232
- it('runs sources after database setup', async () => {
1233
- const calls = [];
1234
- const io = makeIo();
1235
- await writeFile(join(tempDir, 'ktx.yaml'), ['connections: {}', ''].join('\n'), 'utf-8');
1236
- await expect(runKtxSetup({
1237
- command: 'run',
1238
- projectDir: tempDir,
1239
- mode: 'auto',
1240
- agents: false,
1241
- skipAgents: true,
1242
- inputMode: 'disabled',
1243
- yes: true,
1244
- cliVersion: '0.2.0',
1245
- skipLlm: true,
1246
- skipEmbeddings: true,
1247
- skipDatabases: true,
1248
- skipSources: true,
1249
- databaseSchemas: [],
1250
- }, io.io, {
1251
- model: async () => {
1252
- calls.push('model');
1253
- return { status: 'skipped', projectDir: tempDir };
1254
- },
1255
- embeddings: async () => {
1256
- calls.push('embeddings');
1257
- return { status: 'skipped', projectDir: tempDir };
1258
- },
1259
- databases: async () => {
1260
- calls.push('databases');
1261
- return { status: 'skipped', projectDir: tempDir };
1262
- },
1263
- sources: async (args) => {
1264
- expect(args.runInitialSourceIngest).toBe(false);
1265
- calls.push('sources');
1266
- return { status: 'skipped', projectDir: tempDir };
1267
- },
1268
- })).resolves.toBe(0);
1269
- expect(calls).toEqual(['model', 'embeddings', 'databases', 'sources']);
1270
- });
1271
- it.each([
1272
- {
1273
- backend: 'vertex',
1274
- providerLines: [' backend: vertex', ' vertex:', ' project: kaelio-dev', ' location: us-east5'],
1275
- model: 'claude-sonnet-4-6',
1276
- },
1277
- {
1278
- backend: 'gateway',
1279
- providerLines: [' backend: gateway', ' gateway:', ' api_key: env:AI_GATEWAY_API_KEY'],
1280
- model: 'anthropic/claude-sonnet-4-6',
1281
- },
1282
- ])('adds a dbt source in non-interactive setup with existing $backend llm config', async (fixture) => {
1283
- const io = makeIo();
1284
- await writeFile(join(tempDir, 'ktx.yaml'), [
1285
- 'setup:',
1286
- ' database_connection_ids:',
1287
- ' - warehouse',
1288
- 'connections:',
1289
- ' warehouse:',
1290
- ' driver: postgres',
1291
- ' url: env:WAREHOUSE_URL',
1292
- 'llm:',
1293
- ' provider:',
1294
- ...fixture.providerLines,
1295
- ' models:',
1296
- ` default: ${fixture.model}`,
1297
- ].join('\n'), 'utf-8');
1298
- await writeKtxSetupState(tempDir, { completed_steps: ['project', 'databases'] });
1299
- await expect(runKtxSetup({
1300
- command: 'run',
1301
- projectDir: tempDir,
1302
- mode: 'auto',
1303
- agents: false,
1304
- skipAgents: true,
1305
- inputMode: 'disabled',
1306
- yes: true,
1307
- cliVersion: '0.2.0',
1308
- skipLlm: false,
1309
- skipEmbeddings: true,
1310
- skipDatabases: true,
1311
- source: 'dbt',
1312
- sourceConnectionId: 'dbt-main',
1313
- sourceGitUrl: 'https://github.com/Kaelio/klo-dbt-demo',
1314
- sourceBranch: 'main',
1315
- sourceProjectName: 'orbit_analytics',
1316
- sourceWarehouseConnectionId: 'warehouse',
1317
- skipSources: false,
1318
- databaseSchemas: [],
1319
- }, io.io, {
1320
- sourcesDeps: { validateDbt: vi.fn(async () => ({ ok: true, detail: 'dbt project valid' })) },
1321
- context: vi.fn(async () => ({ status: 'ready', projectDir: tempDir, runId: 'setup-context-test' })),
1322
- })).resolves.toBe(0);
1323
- expect(io.stderr()).not.toContain('Anthropic');
1324
- expect(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')).toContain('dbt-main:');
1325
- });
1326
- it('does not fail context build when prerequisites were explicitly skipped and agents are skipped', async () => {
1327
- const calls = [];
1328
- const io = makeIo();
1329
- await writeFile(join(tempDir, 'ktx.yaml'), [
1330
- 'connections:',
1331
- ' warehouse:',
1332
- ' driver: postgres',
1333
- ' url: env:DEMO_DATABASE_URL',
1334
- '',
1335
- ].join('\n'), 'utf-8');
1336
- await expect(runKtxSetup({
1337
- command: 'run',
1338
- projectDir: tempDir,
1339
- mode: 'auto',
1340
- agents: false,
1341
- skipAgents: true,
1342
- inputMode: 'disabled',
1343
- yes: true,
1344
- cliVersion: '0.2.0',
1345
- skipLlm: true,
1346
- skipEmbeddings: true,
1347
- skipDatabases: true,
1348
- skipSources: true,
1349
- databaseSchemas: [],
1350
- }, io.io, {
1351
- model: async () => {
1352
- calls.push('model');
1353
- return { status: 'skipped', projectDir: tempDir };
1354
- },
1355
- embeddings: async () => {
1356
- calls.push('embeddings');
1357
- return { status: 'skipped', projectDir: tempDir };
1358
- },
1359
- databases: async () => {
1360
- calls.push('databases');
1361
- return { status: 'skipped', projectDir: tempDir };
1362
- },
1363
- sources: async () => {
1364
- calls.push('sources');
1365
- return { status: 'skipped', projectDir: tempDir };
1366
- },
1367
- })).resolves.toBe(0);
1368
- expect(calls).toEqual(['model', 'embeddings', 'databases', 'sources']);
1369
- expect(io.stderr()).not.toContain('KTX cannot build agent-ready context yet.');
1370
- });
1371
- it('runs context after sources and before agents in full setup', async () => {
1372
- const calls = [];
1373
- const io = makeIo();
1374
- await writeFile(join(tempDir, 'ktx.yaml'), ['connections: {}', ''].join('\n'), 'utf-8');
1375
- await expect(runKtxSetup({
1376
- command: 'run',
1377
- projectDir: tempDir,
1378
- mode: 'auto',
1379
- agents: false,
1380
- inputMode: 'disabled',
1381
- yes: true,
1382
- cliVersion: '0.2.0',
1383
- skipLlm: true,
1384
- skipEmbeddings: true,
1385
- skipDatabases: true,
1386
- skipSources: true,
1387
- skipAgents: false,
1388
- databaseSchemas: [],
1389
- }, io.io, {
1390
- model: async () => {
1391
- calls.push('model');
1392
- return { status: 'skipped', projectDir: tempDir };
1393
- },
1394
- embeddings: async () => {
1395
- calls.push('embeddings');
1396
- return { status: 'skipped', projectDir: tempDir };
1397
- },
1398
- databases: async () => {
1399
- calls.push('databases');
1400
- return { status: 'skipped', projectDir: tempDir };
1401
- },
1402
- sources: async () => {
1403
- calls.push('sources');
1404
- return { status: 'skipped', projectDir: tempDir };
1405
- },
1406
- runtime: async () => {
1407
- calls.push('runtime');
1408
- return runtimeReady(tempDir);
1409
- },
1410
- context: async () => {
1411
- calls.push('context');
1412
- return { status: 'ready', projectDir: tempDir, runId: 'setup-context-local-test' };
1413
- },
1414
- agents: async () => {
1415
- calls.push('agents');
1416
- return {
1417
- status: 'ready',
1418
- projectDir: tempDir,
1419
- installs: [{ target: 'codex', scope: 'project', mode: 'mcp-cli' }],
1420
- };
1421
- },
1422
- })).resolves.toBe(0);
1423
- expect(calls).toEqual(['model', 'embeddings', 'databases', 'sources', 'runtime', 'context', 'agents']);
1424
- });
1425
- it('commits setup config changes written by later setup steps', async () => {
1426
- const io = makeIo();
1427
- await expect(runKtxSetup({
1428
- command: 'run',
1429
- projectDir: tempDir,
1430
- mode: 'auto',
1431
- agents: false,
1432
- inputMode: 'disabled',
1433
- yes: true,
1434
- cliVersion: '0.2.0',
1435
- skipLlm: true,
1436
- skipEmbeddings: true,
1437
- skipDatabases: true,
1438
- skipSources: true,
1439
- skipAgents: false,
1440
- databaseSchemas: [],
1441
- }, io.io, {
1442
- model: async () => ({ status: 'skipped', projectDir: tempDir }),
1443
- embeddings: async () => ({ status: 'skipped', projectDir: tempDir }),
1444
- databases: async () => {
1445
- const configPath = join(tempDir, 'ktx.yaml');
1446
- const current = await readFile(configPath, 'utf-8');
1447
- await writeFile(configPath, current.replace('connections: {}', ['connections:', ' warehouse:', ' driver: postgres', ' url: env:DATABASE_URL'].join('\n')), 'utf-8');
1448
- return { status: 'skipped', projectDir: tempDir };
1449
- },
1450
- sources: async () => ({ status: 'skipped', projectDir: tempDir }),
1451
- runtime: async () => runtimeReady(tempDir),
1452
- context: async () => ({ status: 'ready', projectDir: tempDir, runId: 'setup-context-local-test' }),
1453
- agents: async () => ({
1454
- status: 'ready',
1455
- projectDir: tempDir,
1456
- installs: [{ target: 'codex', scope: 'project', mode: 'mcp-cli' }],
1457
- }),
1458
- })).resolves.toBe(0);
1459
- const { stdout } = await execFileAsync('git', ['-C', tempDir, 'status', '--short', '--', 'ktx.yaml']);
1460
- expect(stdout).toBe('');
1461
- const committedConfig = await execFileAsync('git', ['-C', tempDir, 'show', 'HEAD:ktx.yaml']);
1462
- expect(committedConfig.stdout).toContain('warehouse:');
1463
- });
1464
- it('runs agent setup without runtime or context in --agents mode', async () => {
1465
- const calls = [];
1466
- const io = makeIo();
1467
- await writeFile(join(tempDir, 'ktx.yaml'), ['connections: {}', ''].join('\n'), 'utf-8');
1468
- await expect(runKtxSetup({
1469
- command: 'run',
1470
- projectDir: tempDir,
1471
- mode: 'auto',
1472
- agents: true,
1473
- target: 'codex',
1474
- agentScope: 'project',
1475
- inputMode: 'disabled',
1476
- yes: true,
1477
- cliVersion: '0.2.0',
1478
- skipLlm: true,
1479
- skipEmbeddings: true,
1480
- skipDatabases: true,
1481
- skipSources: true,
1482
- skipAgents: false,
1483
- databaseSchemas: [],
1484
- }, io.io, {
1485
- model: async () => ({ status: 'skipped', projectDir: tempDir }),
1486
- embeddings: async () => ({ status: 'skipped', projectDir: tempDir }),
1487
- databases: async () => ({ status: 'skipped', projectDir: tempDir }),
1488
- sources: async () => ({ status: 'skipped', projectDir: tempDir }),
1489
- runtime: async () => {
1490
- calls.push('runtime');
1491
- throw new Error('runtime should not run');
1492
- },
1493
- context: async () => {
1494
- calls.push('context');
1495
- throw new Error('context should not run');
1496
- },
1497
- agents: async () => {
1498
- calls.push('agents');
1499
- return {
1500
- status: 'ready',
1501
- projectDir: tempDir,
1502
- installs: [{ target: 'codex', scope: 'project', mode: 'mcp-cli' }],
1503
- };
1504
- },
1505
- })).resolves.toBe(0);
1506
- expect(calls).toEqual(['agents']);
1507
- });
1508
- it('installs agents when non-interactive --agents finds context incomplete', async () => {
1509
- const io = makeIo();
1510
- const runtime = vi.fn(async () => runtimeReady(tempDir));
1511
- const context = vi.fn(async () => ({ status: 'skipped', projectDir: tempDir }));
1512
- const agents = vi.fn(async () => ({
1513
- status: 'ready',
1514
- projectDir: tempDir,
1515
- installs: [{ target: 'codex', scope: 'project', mode: 'mcp-cli' }],
1516
- }));
1517
- await writeFile(join(tempDir, 'ktx.yaml'), ['connections: {}', ''].join('\n'), 'utf-8');
1518
- await expect(runKtxSetup({
1519
- command: 'run',
1520
- projectDir: tempDir,
1521
- mode: 'auto',
1522
- agents: true,
1523
- target: 'codex',
1524
- agentScope: 'project',
1525
- inputMode: 'disabled',
1526
- yes: true,
1527
- cliVersion: '0.2.0',
1528
- skipLlm: true,
1529
- skipEmbeddings: true,
1530
- skipDatabases: true,
1531
- skipSources: true,
1532
- skipAgents: false,
1533
- databaseSchemas: [],
1534
- }, io.io, {
1535
- runtime,
1536
- context,
1537
- agents,
1538
- })).resolves.toBe(0);
1539
- expect(runtime).not.toHaveBeenCalled();
1540
- expect(context).not.toHaveBeenCalled();
1541
- expect(agents).toHaveBeenCalledTimes(1);
1542
- expect(io.stderr()).not.toContain('KTX context is not ready for agents.');
1543
- });
1544
- it('runs non-TTY --agents with a target without requiring --no-input or --yes', async () => {
1545
- const io = makeIo();
1546
- const agents = vi.fn(async () => ({
1547
- status: 'ready',
1548
- projectDir: tempDir,
1549
- installs: [{ target: 'claude-code', scope: 'project', mode: 'mcp' }],
1550
- }));
1551
- await writeFile(join(tempDir, 'ktx.yaml'), ['connections: {}', ''].join('\n'), 'utf-8');
1552
- await expect(runKtxSetup({
1553
- command: 'run',
1554
- projectDir: tempDir,
1555
- mode: 'auto',
1556
- agents: true,
1557
- target: 'claude-code',
1558
- agentScope: 'project',
1559
- inputMode: 'auto',
1560
- yes: false,
1561
- cliVersion: '0.2.0',
1562
- skipLlm: false,
1563
- skipEmbeddings: false,
1564
- skipDatabases: false,
1565
- skipSources: false,
1566
- skipAgents: false,
1567
- databaseSchemas: [],
1568
- }, io.io, { agents })).resolves.toBe(0);
1569
- expect(agents).toHaveBeenCalledWith(expect.objectContaining({
1570
- inputMode: 'disabled',
1571
- yes: false,
1572
- agents: true,
1573
- target: 'claude-code',
1574
- scope: 'project',
1575
- mode: 'mcp',
1576
- }), io.io);
1577
- expect(io.stderr()).not.toContain('Interactive setup requires a terminal');
1578
- });
1579
- it('routes a ready project menu selection to agent setup', async () => {
1580
- const calls = [];
1581
- const io = makeIo();
1582
- await mkdir(join(tempDir, '.ktx', 'agents'), { recursive: true });
1583
- await writeFile(join(tempDir, 'ktx.yaml'), [
1584
- 'setup:',
1585
- ' database_connection_ids: []',
1586
- 'connections: {}',
1587
- 'llm:',
1588
- ' provider:',
1589
- ' backend: anthropic',
1590
- ' models:',
1591
- ' default: claude-sonnet-4-6',
1592
- 'ingest:',
1593
- ' embeddings:',
1594
- ' backend: openai',
1595
- ' model: text-embedding-3-small',
1596
- ' dimensions: 1536',
1597
- '',
1598
- ].join('\n'), 'utf-8');
1599
- await writeKtxSetupState(tempDir, {
1600
- completed_steps: ['project', 'llm', 'embeddings', 'sources', 'runtime', 'context', 'agents'],
1601
- });
1602
- await writeFile(join(tempDir, '.ktx/agents/install-manifest.json'), JSON.stringify({
1603
- version: 1,
1604
- projectDir: tempDir,
1605
- installedAt: '2026-05-07T00:00:00.000Z',
1606
- installs: [{ target: 'codex', scope: 'project', mode: 'mcp-cli' }],
1607
- entries: [],
1608
- }, null, 2), 'utf-8');
1609
- await writeKtxSetupContextState(tempDir, {
1610
- runId: 'setup-context-local-ready',
1611
- status: 'completed',
1612
- startedAt: '2026-05-09T10:00:00.000Z',
1613
- updatedAt: '2026-05-09T10:02:00.000Z',
1614
- completedAt: '2026-05-09T10:02:00.000Z',
1615
- primarySourceConnectionIds: [],
1616
- contextSourceConnectionIds: [],
1617
- reportIds: [],
1618
- artifactPaths: [],
1619
- retryableFailedTargets: [],
1620
- commands: contextBuildCommands(tempDir),
1621
- });
1622
- const previousRuntimeRoot = process.env.KTX_RUNTIME_ROOT;
1623
- process.env.KTX_RUNTIME_ROOT = await writeReadyRuntime(tempDir);
1624
- try {
1625
- await expect(runKtxSetup({
1626
- command: 'run',
1627
- projectDir: tempDir,
1628
- mode: 'auto',
1629
- agents: false,
1630
- inputMode: 'auto',
1631
- yes: false,
1632
- cliVersion: '0.2.0',
1633
- skipLlm: false,
1634
- skipEmbeddings: false,
1635
- skipDatabases: false,
1636
- skipSources: false,
1637
- skipAgents: false,
1638
- databaseSchemas: [],
1639
- }, io.io, {
1640
- readyMenuDeps: { prompts: { select: vi.fn(async () => 'agents'), cancel: vi.fn() } },
1641
- model: async (args) => {
1642
- expect(args.skipLlm).toBe(true);
1643
- return { status: 'skipped', projectDir: tempDir };
1644
- },
1645
- embeddings: async (args) => {
1646
- expect(args.skipEmbeddings).toBe(true);
1647
- return { status: 'skipped', projectDir: tempDir };
1648
- },
1649
- databases: async (args) => {
1650
- expect(args.skipDatabases).toBe(true);
1651
- return { status: 'skipped', projectDir: tempDir };
1652
- },
1653
- sources: async (args) => {
1654
- expect(args.skipSources).toBe(true);
1655
- return { status: 'skipped', projectDir: tempDir };
1656
- },
1657
- runtime: async () => {
1658
- calls.push('runtime');
1659
- return runtimeReady(tempDir);
1660
- },
1661
- agents: async () => {
1662
- calls.push('agents');
1663
- return {
1664
- status: 'ready',
1665
- projectDir: tempDir,
1666
- installs: [{ target: 'codex', scope: 'project', mode: 'mcp-cli' }],
1667
- };
1668
- },
1669
- })).resolves.toBe(0);
1670
- }
1671
- finally {
1672
- if (previousRuntimeRoot === undefined) {
1673
- delete process.env.KTX_RUNTIME_ROOT;
1674
- }
1675
- else {
1676
- process.env.KTX_RUNTIME_ROOT = previousRuntimeRoot;
1677
- }
1678
- }
1679
- expect(calls).toEqual(['agents']);
1680
- });
1681
- it('skips to agent setup when context is ready but agents are not configured', async () => {
1682
- const calls = [];
1683
- const io = makeIo();
1684
- await writeFile(join(tempDir, 'ktx.yaml'), [
1685
- 'setup:',
1686
- ' database_connection_ids: []',
1687
- 'connections: {}',
1688
- 'llm:',
1689
- ' provider:',
1690
- ' backend: anthropic',
1691
- ' models:',
1692
- ' default: claude-sonnet-4-6',
1693
- 'ingest:',
1694
- ' embeddings:',
1695
- ' backend: openai',
1696
- ' model: text-embedding-3-small',
1697
- ' dimensions: 1536',
1698
- '',
1699
- ].join('\n'), 'utf-8');
1700
- await writeKtxSetupState(tempDir, {
1701
- completed_steps: ['project', 'llm', 'embeddings', 'sources', 'context'],
1702
- });
1703
- await writeKtxSetupContextState(tempDir, {
1704
- runId: 'setup-context-local-ready',
1705
- status: 'completed',
1706
- startedAt: '2026-05-09T10:00:00.000Z',
1707
- updatedAt: '2026-05-09T10:02:00.000Z',
1708
- completedAt: '2026-05-09T10:02:00.000Z',
1709
- primarySourceConnectionIds: [],
1710
- contextSourceConnectionIds: [],
1711
- reportIds: [],
1712
- artifactPaths: [],
1713
- retryableFailedTargets: [],
1714
- commands: contextBuildCommands(tempDir),
1715
- });
1716
- const readyMenuSelect = vi.fn();
1717
- await expect(runKtxSetup({
1718
- command: 'run',
1719
- projectDir: tempDir,
1720
- mode: 'auto',
1721
- agents: false,
1722
- inputMode: 'auto',
1723
- yes: false,
1724
- cliVersion: '0.2.0',
1725
- skipLlm: false,
1726
- skipEmbeddings: false,
1727
- skipDatabases: false,
1728
- skipSources: false,
1729
- skipAgents: false,
1730
- databaseSchemas: [],
1731
- }, io.io, {
1732
- readyMenuDeps: { prompts: { select: readyMenuSelect, cancel: vi.fn() } },
1733
- model: async (args) => {
1734
- expect(args.skipLlm).toBe(true);
1735
- return { status: 'skipped', projectDir: tempDir };
1736
- },
1737
- embeddings: async (args) => {
1738
- expect(args.skipEmbeddings).toBe(true);
1739
- return { status: 'skipped', projectDir: tempDir };
1740
- },
1741
- databases: async (args) => {
1742
- expect(args.skipDatabases).toBe(true);
1743
- return { status: 'skipped', projectDir: tempDir };
1744
- },
1745
- sources: async (args) => {
1746
- expect(args.skipSources).toBe(true);
1747
- return { status: 'skipped', projectDir: tempDir };
1748
- },
1749
- runtime: async () => {
1750
- calls.push('runtime');
1751
- return runtimeReady(tempDir);
1752
- },
1753
- agents: async () => {
1754
- calls.push('agents');
1755
- return {
1756
- status: 'ready',
1757
- projectDir: tempDir,
1758
- installs: [{ target: 'codex', scope: 'project', mode: 'mcp-cli' }],
1759
- };
1760
- },
1761
- })).resolves.toBe(0);
1762
- expect(readyMenuSelect).not.toHaveBeenCalled();
1763
- expect(calls).toEqual(['agents']);
1764
- });
1765
- it('runs only project resolution and agent setup in --agents mode', async () => {
1766
- const io = makeIo();
1767
- const runtime = vi.fn(async () => runtimeReady(tempDir));
1768
- const context = vi.fn(async () => ({ status: 'ready', projectDir: tempDir, runId: 'setup-context-local-test' }));
1769
- const agents = vi.fn(async () => ({
1770
- status: 'ready',
1771
- projectDir: tempDir,
1772
- installs: [{ target: 'universal', scope: 'project', mode: 'mcp-cli' }],
1773
- }));
1774
- await expect(runKtxSetup({
1775
- command: 'run',
1776
- projectDir: tempDir,
1777
- mode: 'auto',
1778
- agents: true,
1779
- target: 'universal',
1780
- agentScope: 'project',
1781
- inputMode: 'disabled',
1782
- yes: true,
1783
- cliVersion: '0.2.0',
1784
- skipLlm: false,
1785
- skipEmbeddings: false,
1786
- skipDatabases: false,
1787
- skipSources: false,
1788
- skipAgents: false,
1789
- databaseSchemas: [],
1790
- }, io.io, {
1791
- model: async () => {
1792
- throw new Error('model should not run');
1793
- },
1794
- runtime,
1795
- context,
1796
- agents,
1797
- })).resolves.toBe(0);
1798
- expect(runtime).not.toHaveBeenCalled();
1799
- expect(context).not.toHaveBeenCalled();
1800
- expect(agents).toHaveBeenCalledTimes(1);
1801
- });
1802
- it('does not run embedding setup when the model step fails', async () => {
1803
- const testIo = makeIo();
1804
- const model = vi.fn(async () => ({ status: 'failed', projectDir: tempDir }));
1805
- const embeddings = vi.fn(async () => ({ status: 'ready', projectDir: tempDir }));
1806
- await expect(runKtxSetup({
1807
- command: 'run',
1808
- projectDir: tempDir,
1809
- mode: 'auto',
1810
- agents: false,
1811
- skipAgents: true,
1812
- inputMode: 'disabled',
1813
- yes: true,
1814
- cliVersion: '0.2.0',
1815
- anthropicApiKeyEnv: 'ANTHROPIC_API_KEY', // pragma: allowlist secret
1816
- llmModel: 'claude-sonnet-4-6',
1817
- skipLlm: false,
1818
- skipEmbeddings: false,
1819
- databaseSchemas: [],
1820
- skipDatabases: true,
1821
- }, testIo.io, { model, embeddings })).resolves.toBe(1);
1822
- expect(model).toHaveBeenCalledTimes(1);
1823
- expect(embeddings).not.toHaveBeenCalled();
1824
- });
1825
- });