@kaelio/ktx 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/assets/python/{kaelio_ktx-0.1.1-py3-none-any.whl → kaelio_ktx-0.3.0-py3-none-any.whl} +0 -0
  2. package/assets/python/manifest.json +4 -4
  3. package/dist/admin-reindex.d.ts +15 -0
  4. package/dist/admin-reindex.js +161 -0
  5. package/dist/admin-reindex.test.js +116 -0
  6. package/dist/{dev.d.ts → admin.d.ts} +1 -1
  7. package/dist/{dev.js → admin.js} +14 -12
  8. package/dist/{dev.test.js → admin.test.js} +36 -31
  9. package/dist/cli-program.js +7 -7
  10. package/dist/cli-program.test.js +1 -3
  11. package/dist/cli-project.d.ts +18 -0
  12. package/dist/cli-project.js +52 -0
  13. package/dist/cli-project.test.d.ts +1 -0
  14. package/dist/cli-project.test.js +149 -0
  15. package/dist/cli-runtime.d.ts +2 -2
  16. package/dist/cli-runtime.js +2 -8
  17. package/dist/commands/connection-commands.js +11 -10
  18. package/dist/commands/connection-selection.d.ts +11 -0
  19. package/dist/commands/connection-selection.js +9 -0
  20. package/dist/commands/ingest-commands.js +32 -26
  21. package/dist/commands/knowledge-commands.js +17 -28
  22. package/dist/commands/mcp-commands.js +17 -11
  23. package/dist/commands/runtime-commands.js +2 -2
  24. package/dist/commands/sl-commands.js +27 -32
  25. package/dist/context-build-view.js +1 -1
  26. package/dist/doctor.test.js +4 -4
  27. package/dist/example-smoke.test.js +3 -3
  28. package/dist/index.test.js +97 -85
  29. package/dist/ingest.js +9 -2
  30. package/dist/ingest.test.js +27 -3
  31. package/dist/io/print-list.test.js +4 -4
  32. package/dist/knowledge.js +1 -1
  33. package/dist/managed-local-embeddings.d.ts +0 -2
  34. package/dist/managed-local-embeddings.js +2 -5
  35. package/dist/managed-local-embeddings.test.js +5 -8
  36. package/dist/managed-python-command.js +2 -2
  37. package/dist/managed-python-command.test.js +3 -3
  38. package/dist/managed-python-daemon.js +2 -2
  39. package/dist/managed-python-daemon.test.js +1 -1
  40. package/dist/managed-python-http.js +3 -3
  41. package/dist/managed-python-http.test.js +6 -6
  42. package/dist/managed-python-runtime.d.ts +1 -1
  43. package/dist/managed-python-runtime.js +3 -3
  44. package/dist/managed-python-runtime.test.js +2 -2
  45. package/dist/memory-flow-tui.test.js +2 -2
  46. package/dist/next-steps.d.ts +6 -6
  47. package/dist/next-steps.js +4 -4
  48. package/dist/next-steps.test.js +5 -5
  49. package/dist/print-command-tree.js +0 -2
  50. package/dist/print-command-tree.test.js +1 -1
  51. package/dist/public-ingest.d.ts +4 -2
  52. package/dist/public-ingest.js +12 -8
  53. package/dist/public-ingest.test.js +7 -3
  54. package/dist/release-version.d.ts +1 -5
  55. package/dist/release-version.js +2 -39
  56. package/dist/runtime-requirements.js +1 -1
  57. package/dist/runtime.js +6 -6
  58. package/dist/runtime.test.js +8 -8
  59. package/dist/scan.js +7 -2
  60. package/dist/scan.test.js +3 -3
  61. package/dist/setup-agents.js +3 -3
  62. package/dist/setup-agents.test.js +1 -1
  63. package/dist/setup-embeddings.js +2 -2
  64. package/dist/setup-embeddings.test.js +5 -5
  65. package/dist/setup-runtime.test.js +3 -3
  66. package/dist/sl.js +1 -1
  67. package/dist/standalone-smoke.test.js +6 -2
  68. package/node_modules/@ktx/context/dist/core/git.service.d.ts +1 -0
  69. package/node_modules/@ktx/context/dist/core/git.service.js +12 -0
  70. package/node_modules/@ktx/context/dist/index-sync/index.d.ts +2 -0
  71. package/node_modules/@ktx/context/dist/index-sync/index.js +1 -0
  72. package/node_modules/@ktx/context/dist/index-sync/reindex.d.ts +20 -0
  73. package/node_modules/@ktx/context/dist/index-sync/reindex.js +141 -0
  74. package/node_modules/@ktx/context/dist/index-sync/reindex.test.d.ts +1 -0
  75. package/node_modules/@ktx/context/dist/index-sync/reindex.test.js +139 -0
  76. package/node_modules/@ktx/context/dist/index-sync/types.d.ts +29 -0
  77. package/node_modules/@ktx/context/dist/index-sync/types.js +1 -0
  78. package/node_modules/@ktx/context/dist/index.d.ts +1 -0
  79. package/node_modules/@ktx/context/dist/index.js +1 -0
  80. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/historic-sql.adapter.d.ts +2 -1
  81. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/historic-sql.adapter.js +18 -0
  82. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/local-ingest-acceptance.test.js +6 -6
  83. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/projection.d.ts +5 -0
  84. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/projection.js +48 -0
  85. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/projection.test.js +83 -0
  86. package/node_modules/@ktx/context/dist/ingest/adapters/live-database/daemon-introspection.js +4 -1
  87. package/node_modules/@ktx/context/dist/ingest/adapters/live-database/daemon-introspection.test.js +32 -0
  88. package/node_modules/@ktx/context/dist/ingest/finalization-scope.d.ts +22 -0
  89. package/node_modules/@ktx/context/dist/ingest/finalization-scope.js +95 -0
  90. package/node_modules/@ktx/context/dist/ingest/finalization-scope.test.d.ts +1 -0
  91. package/node_modules/@ktx/context/dist/ingest/finalization-scope.test.js +114 -0
  92. package/node_modules/@ktx/context/dist/ingest/index.d.ts +1 -2
  93. package/node_modules/@ktx/context/dist/ingest/index.js +0 -1
  94. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.d.ts +2 -0
  95. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.isolated-diff.test.js +166 -0
  96. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.js +235 -45
  97. package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.test.js +193 -38
  98. package/node_modules/@ktx/context/dist/ingest/local-bundle-ingest.test.js +22 -3
  99. package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.js +3 -4
  100. package/node_modules/@ktx/context/dist/ingest/local-ingest.js +0 -7
  101. package/node_modules/@ktx/context/dist/ingest/local-stage-ingest.js +15 -5
  102. package/node_modules/@ktx/context/dist/ingest/local-stage-ingest.test.js +29 -0
  103. package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.d.ts +4 -4
  104. package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.js +1 -1
  105. package/node_modules/@ktx/context/dist/ingest/memory-flow/types.d.ts +1 -1
  106. package/node_modules/@ktx/context/dist/ingest/ports.d.ts +1 -20
  107. package/node_modules/@ktx/context/dist/ingest/report-snapshot.d.ts +73 -2
  108. package/node_modules/@ktx/context/dist/ingest/report-snapshot.js +27 -0
  109. package/node_modules/@ktx/context/dist/ingest/reports.d.ts +23 -5
  110. package/node_modules/@ktx/context/dist/ingest/reports.js +7 -24
  111. package/node_modules/@ktx/context/dist/ingest/types.d.ts +33 -0
  112. package/node_modules/@ktx/context/dist/llm/index.d.ts +1 -1
  113. package/node_modules/@ktx/context/dist/llm/index.js +1 -1
  114. package/node_modules/@ktx/context/dist/llm/local-config.d.ts +0 -1
  115. package/node_modules/@ktx/context/dist/llm/local-config.js +2 -12
  116. package/node_modules/@ktx/context/dist/llm/local-config.test.js +2 -23
  117. package/node_modules/@ktx/context/dist/memory/local-memory.js +9 -3
  118. package/node_modules/@ktx/context/dist/package-exports.test.js +2 -2
  119. package/node_modules/@ktx/context/dist/project/config.d.ts +16 -0
  120. package/node_modules/@ktx/context/dist/project/driver-schemas.d.ts +8 -0
  121. package/node_modules/@ktx/context/dist/project/driver-schemas.js +4 -0
  122. package/node_modules/@ktx/context/dist/scan/enabled-tables.d.ts +3 -0
  123. package/node_modules/@ktx/context/dist/scan/enabled-tables.js +15 -0
  124. package/node_modules/@ktx/context/dist/scan/local-scan.d.ts +2 -4
  125. package/node_modules/@ktx/context/dist/scan/local-scan.js +2 -15
  126. package/node_modules/@ktx/context/dist/sl/ports.d.ts +3 -3
  127. package/node_modules/@ktx/context/dist/sl/sl-search.service.d.ts +3 -2
  128. package/node_modules/@ktx/context/dist/sl/sl-search.service.js +47 -45
  129. package/node_modules/@ktx/context/dist/sl/sl-search.service.test.js +61 -0
  130. package/node_modules/@ktx/context/dist/sl/sqlite-sl-sources-index.d.ts +4 -3
  131. package/node_modules/@ktx/context/dist/sl/sqlite-sl-sources-index.js +15 -5
  132. package/node_modules/@ktx/context/dist/sl/sqlite-sl-sources-index.test.js +24 -0
  133. package/node_modules/@ktx/context/dist/wiki/knowledge-wiki.service.d.ts +3 -2
  134. package/node_modules/@ktx/context/dist/wiki/knowledge-wiki.service.js +62 -51
  135. package/node_modules/@ktx/context/dist/wiki/knowledge-wiki.service.test.js +59 -3
  136. package/node_modules/@ktx/context/dist/wiki/ports.d.ts +3 -3
  137. package/node_modules/@ktx/context/dist/wiki/sqlite-knowledge-index.d.ts +33 -0
  138. package/node_modules/@ktx/context/dist/wiki/sqlite-knowledge-index.js +155 -2
  139. package/node_modules/@ktx/context/dist/wiki/sqlite-knowledge-index.test.js +26 -0
  140. package/node_modules/@ktx/context/package.json +5 -0
  141. package/package.json +1 -1
  142. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.d.ts +0 -4
  143. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.js +0 -38
  144. package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.test.js +0 -63
  145. /package/dist/{dev.test.d.ts → admin-reindex.test.d.ts} +0 -0
  146. /package/{node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.test.d.ts → dist/admin.test.d.ts} +0 -0
@@ -31,9 +31,7 @@ describe('getKtxCliPackageInfo', () => {
31
31
  it('identifies the CLI package and its context dependency', () => {
32
32
  expect(getKtxCliPackageInfo()).toEqual({
33
33
  name: '@ktx/cli',
34
- version: '0.1.0-rc.1',
35
- packageVersion: '0.0.0-private',
36
- runtimeVersion: '0.1.0-rc.1',
34
+ version: '0.0.0-private',
37
35
  contextPackageName: '@ktx/context',
38
36
  });
39
37
  });
@@ -51,8 +49,6 @@ describe('getKtxCliPackageInfo', () => {
51
49
  })).toEqual({
52
50
  name: '@kaelio/ktx',
53
51
  version: '0.1.0',
54
- packageVersion: '0.1.0',
55
- runtimeVersion: '0.1.0',
56
52
  contextPackageName: '@ktx/context',
57
53
  });
58
54
  });
@@ -90,7 +86,7 @@ describe('runKtxCli', () => {
90
86
  it('prints version information', async () => {
91
87
  const testIo = makeIo();
92
88
  await expect(runKtxCli(['--version'], testIo.io)).resolves.toBe(0);
93
- expect(testIo.stdout()).toBe('@ktx/cli 0.1.0-rc.1\n');
89
+ expect(testIo.stdout()).toBe('@ktx/cli 0.0.0-private\n');
94
90
  expect(testIo.stderr()).toBe('');
95
91
  });
96
92
  it('prints the public command surface in root help', async () => {
@@ -98,9 +94,10 @@ describe('runKtxCli', () => {
98
94
  await expect(runKtxCli(['--help'], testIo.io)).resolves.toBe(0);
99
95
  expect(testIo.stdout()).toContain('Usage: ktx [options] [command]');
100
96
  expect(testIo.stdout()).toContain('KTX data agent context layer CLI');
101
- for (const command of ['setup', 'connection', 'ingest', 'wiki', 'sl', 'status', 'dev']) {
97
+ for (const command of ['setup', 'connection', 'ingest', 'wiki', 'sl', 'status', 'admin']) {
102
98
  expect(testIo.stdout()).toContain(`${command}`);
103
99
  }
100
+ expect(testIo.stdout()).not.toMatch(/^ dev\s/m);
104
101
  expect(testIo.stdout()).not.toMatch(/^ scan\s/m);
105
102
  for (const removed of ['demo', 'init', 'connect', 'ask', 'knowledge', 'agent', 'completion', 'serve']) {
106
103
  expect(testIo.stdout()).not.toMatch(new RegExp(`^\\s+${removed}(?:\\s|\\[|$)`, 'm'));
@@ -115,7 +112,7 @@ describe('runKtxCli', () => {
115
112
  it('routes supported public wiki commands', async () => {
116
113
  const knowledge = vi.fn(async () => 0);
117
114
  const listIo = makeIo();
118
- await expect(runKtxCli(['--project-dir', tempDir, 'wiki', 'list', '--json'], listIo.io, { knowledge }))
115
+ await expect(runKtxCli(['--project-dir', tempDir, 'wiki', '--json'], listIo.io, { knowledge }))
119
116
  .resolves.toBe(0);
120
117
  expect(knowledge).toHaveBeenCalledWith({
121
118
  command: 'list',
@@ -124,7 +121,7 @@ describe('runKtxCli', () => {
124
121
  json: true,
125
122
  }, listIo.io);
126
123
  const searchIo = makeIo();
127
- await expect(runKtxCli(['--project-dir', tempDir, 'wiki', 'search', 'revenue', '--limit', '5'], searchIo.io, { knowledge })).resolves.toBe(0);
124
+ await expect(runKtxCli(['--project-dir', tempDir, 'wiki', 'revenue', '--limit', '5'], searchIo.io, { knowledge })).resolves.toBe(0);
128
125
  expect(knowledge).toHaveBeenLastCalledWith({
129
126
  command: 'search',
130
127
  projectDir: tempDir,
@@ -134,7 +131,7 @@ describe('runKtxCli', () => {
134
131
  limit: 5,
135
132
  }, searchIo.io);
136
133
  const debugSearchIo = makeIo();
137
- await expect(runKtxCli(['--project-dir', tempDir, '--debug', 'wiki', 'search', 'revenue'], debugSearchIo.io, { knowledge })).resolves.toBe(0);
134
+ await expect(runKtxCli(['--project-dir', tempDir, '--debug', 'wiki', 'revenue'], debugSearchIo.io, { knowledge })).resolves.toBe(0);
138
135
  expect(knowledge).toHaveBeenLastCalledWith({
139
136
  command: 'search',
140
137
  projectDir: tempDir,
@@ -143,35 +140,32 @@ describe('runKtxCli', () => {
143
140
  json: false,
144
141
  debug: true,
145
142
  }, debugSearchIo.io);
143
+ const multiWordIo = makeIo();
144
+ await expect(runKtxCli(['--project-dir', tempDir, 'wiki', 'revenue', 'policy'], multiWordIo.io, { knowledge })).resolves.toBe(0);
145
+ expect(knowledge).toHaveBeenLastCalledWith({
146
+ command: 'search',
147
+ projectDir: tempDir,
148
+ query: 'revenue policy',
149
+ userId: 'local',
150
+ json: false,
151
+ }, multiWordIo.io);
146
152
  });
147
- it('rejects removed public wiki read and write commands', async () => {
153
+ it('rejects unknown write-style flags on the flattened wiki and sl commands', async () => {
148
154
  const knowledge = vi.fn(async () => 0);
149
- for (const argv of [
150
- ['--project-dir', tempDir, 'wiki', 'read', 'revenue', '--json'],
151
- ['--project-dir', tempDir, 'wiki', 'write', 'revenue', '--summary', 'Revenue', '--content', 'Revenue.'],
152
- ]) {
153
- const io = makeIo();
154
- await expect(runKtxCli(argv, io.io, { knowledge })).resolves.toBe(1);
155
- expect(io.stderr()).toMatch(/unknown command|error:/);
156
- }
157
- expect(knowledge).not.toHaveBeenCalled();
158
- });
159
- it('rejects removed public sl read/write commands', async () => {
160
155
  const sl = vi.fn(async () => 0);
161
- for (const argv of [
162
- ['--project-dir', tempDir, 'sl', 'read', 'orders', '--connection-id', 'warehouse'],
163
- ['--project-dir', tempDir, 'sl', 'write', 'orders', '--connection-id', 'warehouse', '--yaml', 'name: orders'],
164
- ]) {
165
- const io = makeIo();
166
- await expect(runKtxCli(argv, io.io, { sl })).resolves.toBe(1);
167
- expect(io.stderr()).toMatch(/unknown command|error:/);
168
- }
156
+ const wikiIo = makeIo();
157
+ await expect(runKtxCli(['--project-dir', tempDir, 'wiki', 'revenue', '--summary', 'Revenue', '--content', 'Revenue.'], wikiIo.io, { knowledge })).resolves.toBe(1);
158
+ expect(wikiIo.stderr()).toMatch(/unknown option|error:/);
159
+ expect(knowledge).not.toHaveBeenCalled();
160
+ const slIo = makeIo();
161
+ await expect(runKtxCli(['--project-dir', tempDir, 'sl', 'orders', '--yaml', 'name: orders'], slIo.io, { sl })).resolves.toBe(1);
162
+ expect(slIo.stderr()).toMatch(/unknown option|error:/);
169
163
  expect(sl).not.toHaveBeenCalled();
170
164
  });
171
- it('routes sl search and rejects the old sl list --query flag', async () => {
165
+ it('routes sl search via the flattened query positional and rejects unknown flags', async () => {
172
166
  const sl = vi.fn(async () => 0);
173
167
  const searchIo = makeIo();
174
- await expect(runKtxCli(['--project-dir', tempDir, 'sl', 'search', 'revenue', '--connection-id', 'warehouse', '--limit', '5', '--json'], searchIo.io, { sl })).resolves.toBe(0);
168
+ await expect(runKtxCli(['--project-dir', tempDir, 'sl', 'revenue', '--connection-id', 'warehouse', '--limit', '5', '--json'], searchIo.io, { sl })).resolves.toBe(0);
175
169
  expect(sl).toHaveBeenCalledWith({
176
170
  command: 'search',
177
171
  projectDir: tempDir,
@@ -181,11 +175,20 @@ describe('runKtxCli', () => {
181
175
  json: true,
182
176
  output: undefined,
183
177
  }, searchIo.io);
184
- const listIo = makeIo();
185
- await expect(runKtxCli(['--project-dir', tempDir, 'sl', 'list', '--query', 'revenue'], listIo.io, { sl })).resolves.toBe(1);
186
- expect(listIo.stderr()).toContain("unknown option '--query'");
178
+ const bareIo = makeIo();
179
+ await expect(runKtxCli(['--project-dir', tempDir, 'sl', '--connection-id', 'warehouse', '--json'], bareIo.io, { sl })).resolves.toBe(0);
180
+ expect(sl).toHaveBeenLastCalledWith({
181
+ command: 'list',
182
+ projectDir: tempDir,
183
+ connectionId: 'warehouse',
184
+ json: true,
185
+ output: undefined,
186
+ }, bareIo.io);
187
+ const unknownIo = makeIo();
188
+ await expect(runKtxCli(['--project-dir', tempDir, 'sl', '--query', 'revenue'], unknownIo.io, { sl })).resolves.toBe(1);
189
+ expect(unknownIo.stderr()).toContain("unknown option '--query'");
187
190
  });
188
- it('routes runtime management commands with the release runtime version', async () => {
191
+ it('routes runtime management commands with the CLI package version', async () => {
189
192
  const runtime = vi.fn(async () => 0);
190
193
  const installIo = makeIo();
191
194
  const startIo = makeIo();
@@ -193,42 +196,42 @@ describe('runKtxCli', () => {
193
196
  const stopAllIo = makeIo();
194
197
  const statusIo = makeIo();
195
198
  const pruneIo = makeIo();
196
- await expect(runKtxCli(['dev', 'runtime', 'install', '--feature', 'local-embeddings', '--force', '--yes'], installIo.io, {
199
+ await expect(runKtxCli(['admin', 'runtime', 'install', '--feature', 'local-embeddings', '--force', '--yes'], installIo.io, {
197
200
  runtime,
198
201
  })).resolves.toBe(0);
199
- await expect(runKtxCli(['dev', 'runtime', 'start', '--feature', 'local-embeddings', '--force'], startIo.io, { runtime })).resolves.toBe(0);
200
- await expect(runKtxCli(['dev', 'runtime', 'stop'], stopIo.io, { runtime })).resolves.toBe(0);
201
- await expect(runKtxCli(['dev', 'runtime', 'stop', '--all'], stopAllIo.io, { runtime })).resolves.toBe(0);
202
- await expect(runKtxCli(['dev', 'runtime', 'status', '--json'], statusIo.io, { runtime })).resolves.toBe(0);
203
- await expect(runKtxCli(['dev', 'runtime', 'prune', '--dry-run'], pruneIo.io, { runtime })).resolves.toBe(1);
202
+ await expect(runKtxCli(['admin', 'runtime', 'start', '--feature', 'local-embeddings', '--force'], startIo.io, { runtime })).resolves.toBe(0);
203
+ await expect(runKtxCli(['admin', 'runtime', 'stop'], stopIo.io, { runtime })).resolves.toBe(0);
204
+ await expect(runKtxCli(['admin', 'runtime', 'stop', '--all'], stopAllIo.io, { runtime })).resolves.toBe(0);
205
+ await expect(runKtxCli(['admin', 'runtime', 'status', '--json'], statusIo.io, { runtime })).resolves.toBe(0);
206
+ await expect(runKtxCli(['admin', 'runtime', 'prune', '--dry-run'], pruneIo.io, { runtime })).resolves.toBe(1);
204
207
  expect(runtime).toHaveBeenNthCalledWith(1, {
205
208
  command: 'install',
206
- cliVersion: '0.1.0-rc.1',
209
+ cliVersion: '0.0.0-private',
207
210
  feature: 'local-embeddings',
208
211
  force: true,
209
212
  }, installIo.io);
210
213
  expect(runtime).toHaveBeenNthCalledWith(2, {
211
214
  command: 'start',
212
- cliVersion: '0.1.0-rc.1',
215
+ cliVersion: '0.0.0-private',
213
216
  projectDir: expect.any(String),
214
217
  feature: 'local-embeddings',
215
218
  force: true,
216
219
  }, startIo.io);
217
220
  expect(runtime).toHaveBeenNthCalledWith(3, {
218
221
  command: 'stop',
219
- cliVersion: '0.1.0-rc.1',
222
+ cliVersion: '0.0.0-private',
220
223
  projectDir: expect.any(String),
221
224
  all: false,
222
225
  }, stopIo.io);
223
226
  expect(runtime).toHaveBeenNthCalledWith(4, {
224
227
  command: 'stop',
225
- cliVersion: '0.1.0-rc.1',
228
+ cliVersion: '0.0.0-private',
226
229
  projectDir: expect.any(String),
227
230
  all: true,
228
231
  }, stopAllIo.io);
229
232
  expect(runtime).toHaveBeenNthCalledWith(5, {
230
233
  command: 'status',
231
- cliVersion: '0.1.0-rc.1',
234
+ cliVersion: '0.0.0-private',
232
235
  json: true,
233
236
  }, statusIo.io);
234
237
  expect(runtime).toHaveBeenCalledTimes(5);
@@ -262,7 +265,7 @@ describe('runKtxCli', () => {
262
265
  });
263
266
  it('documents runtime stop all in command help', async () => {
264
267
  const testIo = makeIo();
265
- await expect(runKtxCli(['dev', 'runtime', 'stop', '--help'], testIo.io)).resolves.toBe(0);
268
+ await expect(runKtxCli(['admin', 'runtime', 'stop', '--help'], testIo.io)).resolves.toBe(0);
266
269
  expect(testIo.stdout()).toContain('--all');
267
270
  expect(testIo.stdout()).toContain('Stop all KTX daemon processes recorded or discoverable');
268
271
  expect(testIo.stdout()).toContain('on this machine');
@@ -275,7 +278,7 @@ describe('runKtxCli', () => {
275
278
  expect(sl).toHaveBeenLastCalledWith(expect.objectContaining({
276
279
  command: 'query',
277
280
  projectDir: tempDir,
278
- cliVersion: '0.1.0-rc.1',
281
+ cliVersion: '0.0.0-private',
279
282
  runtimeInstallPolicy: 'prompt',
280
283
  query: expect.objectContaining({ measures: ['orders.order_count'], dimensions: [] }),
281
284
  }), promptIo.io);
@@ -284,13 +287,13 @@ describe('runKtxCli', () => {
284
287
  sl,
285
288
  })).resolves.toBe(0);
286
289
  expect(sl).toHaveBeenLastCalledWith(expect.objectContaining({
287
- cliVersion: '0.1.0-rc.1',
290
+ cliVersion: '0.0.0-private',
288
291
  runtimeInstallPolicy: 'auto',
289
292
  }), autoIo.io);
290
293
  const noInputIo = makeIo();
291
294
  await expect(runKtxCli(['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count', '--no-input'], noInputIo.io, { sl })).resolves.toBe(0);
292
295
  expect(sl).toHaveBeenLastCalledWith(expect.objectContaining({
293
- cliVersion: '0.1.0-rc.1',
296
+ cliVersion: '0.0.0-private',
294
297
  runtimeInstallPolicy: 'never',
295
298
  }), noInputIo.io);
296
299
  });
@@ -367,7 +370,7 @@ describe('runKtxCli', () => {
367
370
  await initKtxProject({ projectDir });
368
371
  const commands = [
369
372
  ['--project-dir', projectDir, 'status', '--json'],
370
- ['--project-dir', projectDir, 'sl', 'list', '--json'],
373
+ ['--project-dir', projectDir, 'sl', '--json'],
371
374
  ];
372
375
  for (const argv of commands) {
373
376
  const testIo = makeIo();
@@ -400,7 +403,7 @@ describe('runKtxCli', () => {
400
403
  skipAgents: false,
401
404
  inputMode: 'auto',
402
405
  yes: false,
403
- cliVersion: '0.1.0-rc.1',
406
+ cliVersion: '0.0.0-private',
404
407
  skipLlm: false,
405
408
  skipEmbeddings: false,
406
409
  databaseSchemas: [],
@@ -483,8 +486,8 @@ describe('runKtxCli', () => {
483
486
  it('rejects removed shell completion commands', async () => {
484
487
  const completionIo = makeIo();
485
488
  const hiddenIo = makeIo();
486
- await expect(runKtxCli(['dev', 'completion', 'zsh'], completionIo.io)).resolves.toBe(1);
487
- await expect(runKtxCli(['dev', '__complete', '--shell', 'zsh', '--position', '2', '--', 'ktx', 'co'], hiddenIo.io)).resolves.toBe(1);
489
+ await expect(runKtxCli(['admin', 'completion', 'zsh'], completionIo.io)).resolves.toBe(1);
490
+ await expect(runKtxCli(['admin', '__complete', '--shell', 'zsh', '--position', '2', '--', 'ktx', 'co'], hiddenIo.io)).resolves.toBe(1);
488
491
  expect(completionIo.stderr()).toMatch(/unknown command|error:/);
489
492
  expect(hiddenIo.stderr()).toMatch(/unknown command|error:/);
490
493
  });
@@ -509,7 +512,7 @@ describe('runKtxCli', () => {
509
512
  inputMode: 'disabled',
510
513
  depth: 'fast',
511
514
  queryHistory: 'default',
512
- cliVersion: '0.1.0-rc.1',
515
+ cliVersion: '0.0.0-private',
513
516
  runtimeInstallPolicy: 'never',
514
517
  }, testIo.io);
515
518
  expect(testIo.stderr()).toBe(`Project: ${tempDir}\n`);
@@ -528,7 +531,7 @@ describe('runKtxCli', () => {
528
531
  inputMode: 'auto',
529
532
  depth: 'deep',
530
533
  queryHistory: 'default',
531
- cliVersion: '0.1.0-rc.1',
534
+ cliVersion: '0.0.0-private',
532
535
  runtimeInstallPolicy: 'prompt',
533
536
  }, testIo.io);
534
537
  expect(testIo.stderr()).toBe('');
@@ -577,7 +580,7 @@ describe('runKtxCli', () => {
577
580
  json: false,
578
581
  inputMode: 'disabled',
579
582
  queryHistory: 'default',
580
- cliVersion: '0.1.0-rc.1',
583
+ cliVersion: '0.0.0-private',
581
584
  runtimeInstallPolicy: 'never',
582
585
  }, testIo.io);
583
586
  });
@@ -636,7 +639,8 @@ describe('runKtxCli', () => {
636
639
  expect(testIo.stdout()).toContain('--query-history');
637
640
  expect(testIo.stdout()).toContain('--no-query-history');
638
641
  expect(testIo.stdout()).toContain('--query-history-window-days <days>');
639
- expect(testIo.stdout()).toContain('text');
642
+ expect(testIo.stdout()).toContain('--text');
643
+ expect(testIo.stdout()).toContain('--file');
640
644
  expect(testIo.stdout()).not.toMatch(/^ status\s/m);
641
645
  expect(testIo.stdout()).not.toMatch(/^ replay\s/m);
642
646
  expect(testIo.stdout()).not.toMatch(/^ run\s/m);
@@ -652,7 +656,6 @@ describe('runKtxCli', () => {
652
656
  '--project-dir',
653
657
  tempDir,
654
658
  'ingest',
655
- 'text',
656
659
  '--text',
657
660
  'Revenue means gross receipts.',
658
661
  '--text',
@@ -675,37 +678,46 @@ describe('runKtxCli', () => {
675
678
  }, testIo.io);
676
679
  expect(testIo.stderr()).toBe('');
677
680
  });
678
- it('documents text ingest inputs without a manifest option', async () => {
681
+ it('rejects a positional connection id when --text is supplied', async () => {
679
682
  const textIngest = vi.fn(async () => 0);
683
+ const publicIngest = vi.fn(async () => 0);
680
684
  const testIo = makeIo();
681
- await expect(runKtxCli(['ingest', 'text', '--help'], testIo.io, { textIngest })).resolves.toBe(0);
682
- expect(testIo.stdout()).toContain('Usage: ktx ingest text [options] [files...]');
683
- expect(testIo.stdout()).toContain('--text <content>');
684
- expect(testIo.stdout()).toContain('--connection-id <connectionId>');
685
- expect(testIo.stdout()).toContain('--user-id <id>');
686
- expect(testIo.stdout()).toContain('--fail-fast');
687
- expect(testIo.stdout()).not.toContain('--manifest');
685
+ await expect(runKtxCli(['--project-dir', tempDir, 'ingest', 'warehouse', '--text', 'hello'], testIo.io, { textIngest, publicIngest })).resolves.toBe(1);
688
686
  expect(textIngest).not.toHaveBeenCalled();
687
+ expect(publicIngest).not.toHaveBeenCalled();
688
+ expect(testIo.stderr()).toMatch(/--text\/--file does not accept a positional connection id/);
689
+ });
690
+ it('treats bare ingest as ingest --all', async () => {
691
+ const publicIngest = vi.fn().mockResolvedValue(0);
692
+ const testIo = makeIo();
693
+ await expect(runKtxCli(['--project-dir', tempDir, 'ingest', '--no-input'], testIo.io, { publicIngest })).resolves.toBe(0);
694
+ expect(publicIngest).toHaveBeenCalledWith(expect.objectContaining({
695
+ command: 'run',
696
+ projectDir: tempDir,
697
+ all: true,
698
+ }), testIo.io);
699
+ const args = publicIngest.mock.calls[0]?.[0];
700
+ expect(args.targetConnectionId).toBeUndefined();
689
701
  });
690
- it('rejects old adapter-backed ingest flags at the top level and under dev', async () => {
702
+ it('rejects old adapter-backed ingest flags at the top level and under admin', async () => {
691
703
  const rootRunIo = makeIo();
692
704
  const devRunIo = makeIo();
693
705
  const publicIngest = vi.fn(async () => 0);
694
706
  await expect(runKtxCli(['ingest', 'run', '--connection-id', 'warehouse', '--adapter', 'metabase'], rootRunIo.io, {
695
707
  publicIngest,
696
708
  })).resolves.toBe(1);
697
- await expect(runKtxCli(['dev', 'ingest', 'run', '--connection-id', 'warehouse', '--adapter', 'metabase'], devRunIo.io, {
709
+ await expect(runKtxCli(['admin', 'ingest', 'run', '--connection-id', 'warehouse', '--adapter', 'metabase'], devRunIo.io, {
698
710
  publicIngest,
699
711
  })).resolves.toBe(1);
700
712
  expect(publicIngest).not.toHaveBeenCalled();
701
713
  expect(rootRunIo.stderr()).toMatch(/unknown option '--connection-id'|error:/);
702
714
  expect(devRunIo.stderr()).toMatch(/unknown command|error:/);
703
715
  });
704
- it('rejects removed dev doctor and removed ingest parser cases', async () => {
716
+ it('rejects removed admin doctor and removed ingest parser cases', async () => {
705
717
  const doctor = vi.fn(async () => 0);
706
718
  const doctorIo = makeIo();
707
719
  const ingestRunIo = makeIo();
708
- await expect(runKtxCli(['dev', 'doctor', 'setup', '--json', '--no-input'], doctorIo.io, { doctor })).resolves.toBe(1);
720
+ await expect(runKtxCli(['admin', 'doctor', 'setup', '--json', '--no-input'], doctorIo.io, { doctor })).resolves.toBe(1);
709
721
  await expect(runKtxCli([
710
722
  'ingest',
711
723
  'run',
@@ -786,7 +798,7 @@ describe('runKtxCli', () => {
786
798
  command: 'run',
787
799
  projectDir: tempDir,
788
800
  inputMode: 'disabled',
789
- cliVersion: '0.1.0-rc.1',
801
+ cliVersion: '0.0.0-private',
790
802
  anthropicApiKeyEnv: 'ANTHROPIC_API_KEY', // pragma: allowlist secret
791
803
  llmModel: 'claude-sonnet-4-6',
792
804
  skipLlm: false,
@@ -813,7 +825,7 @@ describe('runKtxCli', () => {
813
825
  command: 'run',
814
826
  projectDir: tempDir,
815
827
  inputMode: 'disabled',
816
- cliVersion: '0.1.0-rc.1',
828
+ cliVersion: '0.0.0-private',
817
829
  llmBackend: 'vertex',
818
830
  vertexProject: 'local-gcp-project',
819
831
  vertexLocation: 'us-east5',
@@ -838,7 +850,7 @@ describe('runKtxCli', () => {
838
850
  command: 'run',
839
851
  projectDir: tempDir,
840
852
  inputMode: 'disabled',
841
- cliVersion: '0.1.0-rc.1',
853
+ cliVersion: '0.0.0-private',
842
854
  llmBackend: 'claude-code',
843
855
  llmModel: 'opus',
844
856
  skipLlm: false,
@@ -913,7 +925,7 @@ describe('runKtxCli', () => {
913
925
  projectDir: '/tmp/project',
914
926
  inputMode: 'disabled',
915
927
  yes: true,
916
- cliVersion: '0.1.0-rc.1',
928
+ cliVersion: '0.0.0-private',
917
929
  skipLlm: true,
918
930
  skipEmbeddings: true,
919
931
  databaseDrivers: ['postgres'],
@@ -1131,7 +1143,7 @@ describe('runKtxCli', () => {
1131
1143
  queryFile: '/tmp/query.json',
1132
1144
  execute: false,
1133
1145
  format: 'json',
1134
- cliVersion: '0.1.0-rc.1',
1146
+ cliVersion: '0.0.0-private',
1135
1147
  runtimeInstallPolicy: 'auto',
1136
1148
  }, autoIo.io);
1137
1149
  expect(sl).toHaveBeenNthCalledWith(2, {
@@ -1141,7 +1153,7 @@ describe('runKtxCli', () => {
1141
1153
  queryFile: '/tmp/query.json',
1142
1154
  execute: false,
1143
1155
  format: 'json',
1144
- cliVersion: '0.1.0-rc.1',
1156
+ cliVersion: '0.0.0-private',
1145
1157
  runtimeInstallPolicy: 'never',
1146
1158
  }, neverIo.io);
1147
1159
  expect(conflictIo.stderr()).toContain('Choose only one runtime install mode: --yes or --no-input');
@@ -1237,10 +1249,10 @@ describe('runKtxCli', () => {
1237
1249
  ], serveIo.io)).resolves.toBe(1);
1238
1250
  expect(serveIo.stderr()).toMatch(/unknown command|error:/);
1239
1251
  });
1240
- it('prints dev help for bare dev commands', async () => {
1252
+ it('prints admin help for bare admin commands', async () => {
1241
1253
  const testIo = makeIo();
1242
- await expect(runKtxCli(['dev'], testIo.io)).resolves.toBe(0);
1243
- expect(testIo.stdout()).toContain('Usage: ktx dev [options] [command]');
1254
+ await expect(runKtxCli(['admin'], testIo.io)).resolves.toBe(0);
1255
+ expect(testIo.stdout()).toContain('Usage: ktx admin [options] [command]');
1244
1256
  expect(testIo.stdout()).toContain('Low-level project initialization');
1245
1257
  expect(testIo.stdout()).toContain('init');
1246
1258
  expect(testIo.stdout()).toContain('runtime');
@@ -1251,20 +1263,20 @@ describe('runKtxCli', () => {
1251
1263
  expect(testIo.stdout()).not.toContain('knowledge');
1252
1264
  expect(testIo.stderr()).toBe('');
1253
1265
  });
1254
- it('rejects removed dev command groups without invoking execution', async () => {
1266
+ it('rejects removed admin command groups without invoking execution', async () => {
1255
1267
  for (const command of ['scan', 'ingest', 'mapping']) {
1256
1268
  const testIo = makeIo();
1257
1269
  const publicIngest = vi.fn().mockResolvedValue(0);
1258
1270
  const sl = vi.fn().mockResolvedValue(0);
1259
- await expect(runKtxCli(['dev', command], testIo.io, { publicIngest, sl })).resolves.toBe(1);
1271
+ await expect(runKtxCli(['admin', command], testIo.io, { publicIngest, sl })).resolves.toBe(1);
1260
1272
  expect(testIo.stderr()).toMatch(/unknown command|error:/);
1261
1273
  expect(publicIngest).not.toHaveBeenCalled();
1262
1274
  expect(sl).not.toHaveBeenCalled();
1263
1275
  }
1264
1276
  });
1265
- it('rejects removed reserved dev subcommands', async () => {
1277
+ it('rejects removed reserved admin subcommands', async () => {
1266
1278
  const testIo = makeIo();
1267
- await expect(runKtxCli(['dev', 'artifacts'], testIo.io)).resolves.toBe(1);
1279
+ await expect(runKtxCli(['admin', 'artifacts'], testIo.io)).resolves.toBe(1);
1268
1280
  expect(testIo.stderr()).toMatch(/unknown command|error:/);
1269
1281
  });
1270
1282
  it('rejects mutually exclusive public ingest output modes before invoking runners', async () => {
package/dist/ingest.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { buildMemoryFlowViewModel, createMemoryFlowLiveBuffer, formatMemoryFlowFinalSummary, getLatestLocalIngestStatus, getLocalIngestStatus, ingestReportToMemoryFlowReplay, renderMemoryFlowReplay, runLocalIngest, runLocalMetabaseIngest, savedMemoryCountsForReport, sanitizeMemoryFlowError, } from '@ktx/context/ingest';
2
- import { loadKtxProject } from '@ktx/context/project';
2
+ import { loadKtxCliProject } from './cli-project.js';
3
3
  import { createKtxCliIngestQueryExecutor } from './ingest-query-executor.js';
4
4
  import { readIngestReportSnapshotFile } from './ingest-report-file.js';
5
5
  import { createCliOperationalLogger } from './io/logger.js';
@@ -470,7 +470,14 @@ async function writeReportRecord(report, outputMode, io, options = {}) {
470
470
  }
471
471
  export async function runKtxIngest(args, io = process, deps = {}) {
472
472
  try {
473
- const project = await loadKtxProject({ projectDir: args.projectDir });
473
+ const cliVersion = args.command === 'run' ? args.cliVersion : undefined;
474
+ const runtimeInstallPolicy = args.command === 'run' ? args.runtimeInstallPolicy : undefined;
475
+ const project = await loadKtxCliProject({
476
+ projectDir: args.projectDir,
477
+ cliVersion: cliVersion ?? '0.0.0-private',
478
+ installPolicy: runtimeInstallPolicy ?? 'never',
479
+ io,
480
+ });
474
481
  const env = deps.env ?? process.env;
475
482
  if (args.command === 'run') {
476
483
  const ingestProject = args.allowImplicitAdapter && !project.config.ingest.adapters.includes(args.adapter)
@@ -807,9 +807,16 @@ describe('runKtxIngest', () => {
807
807
  sourceKey: 'historic-sql',
808
808
  body: {
809
809
  workUnits: [],
810
- postProcessor: {
810
+ finalization: {
811
811
  sourceKey: 'historic-sql',
812
812
  status: 'success',
813
+ commitSha: 'finalization-sha',
814
+ touchedPaths: ['semantic-layer/warehouse/_schema/public.yaml', 'wiki/global/historic-sql-orders.md'],
815
+ declaredTouchedSources: [{ connectionId: 'warehouse', sourceName: 'orders' }],
816
+ derivedTouchedSources: [{ connectionId: 'warehouse', sourceName: 'orders' }],
817
+ declaredChangedWikiPageKeys: ['historic-sql-orders'],
818
+ derivedChangedWikiPageKeys: ['historic-sql-orders'],
819
+ mismatches: [],
813
820
  result: {
814
821
  tableUsageMerged: 56,
815
822
  staleTablesMarked: 1,
@@ -819,7 +826,24 @@ describe('runKtxIngest', () => {
819
826
  },
820
827
  errors: [],
821
828
  warnings: [],
822
- touchedSources: [],
829
+ actions: [
830
+ ...Array.from({ length: 57 }, (_, index) => ({
831
+ target: 'sl',
832
+ type: 'updated',
833
+ key: `orders-${index}`,
834
+ detail: 'Merged usage',
835
+ targetConnectionId: 'warehouse',
836
+ rawPaths: ['tables/public/orders.json'],
837
+ })),
838
+ ...Array.from({ length: 35 }, (_, index) => ({
839
+ target: 'wiki',
840
+ type: 'updated',
841
+ key: `historic-sql-orders-${index}`,
842
+ detail: 'Projected pattern',
843
+ rawPaths: ['patterns/orders.json'],
844
+ })),
845
+ ],
846
+ provenanceExclusions: [],
823
847
  },
824
848
  },
825
849
  }),
@@ -1048,7 +1072,7 @@ describe('runKtxIngest', () => {
1048
1072
  }),
1049
1073
  }));
1050
1074
  });
1051
- it('passes managed daemon options to adapters and pull-config options when no explicit daemon URL is set', async () => {
1075
+ it('passes KTX daemon options to adapters and pull-config options when no explicit daemon URL is set', async () => {
1052
1076
  const projectDir = join(tempDir, 'managed-daemon-ingest-project');
1053
1077
  await initKtxProject({ projectDir });
1054
1078
  await writeWarehouseConfig(projectDir);
@@ -60,13 +60,13 @@ describe('printList — plain mode', () => {
60
60
  mode: 'plain',
61
61
  command: 'sl search',
62
62
  emptyMessage: 'No sources matched "foo"',
63
- emptyHint: 'Run `ktx sl list` to see available sources.',
63
+ emptyHint: 'Run `ktx sl` to see available sources.',
64
64
  unit: 'source',
65
65
  io: r.io,
66
66
  });
67
67
  expect(r.out()).toBe('');
68
68
  expect(r.err()).toBe('No sources matched "foo"\n' +
69
- 'Run `ktx sl list` to see available sources.\n');
69
+ 'Run `ktx sl` to see available sources.\n');
70
70
  });
71
71
  });
72
72
  describe('printList — json mode', () => {
@@ -162,13 +162,13 @@ describe('printList — pretty mode', () => {
162
162
  mode: 'pretty',
163
163
  command: 'sl search',
164
164
  emptyMessage: 'No sources matched "foo"',
165
- emptyHint: 'Run `ktx sl list` to see available sources.',
165
+ emptyHint: 'Run `ktx sl` to see available sources.',
166
166
  unit: 'source',
167
167
  io: r.io,
168
168
  });
169
169
  const out = stripAnsi(r.out());
170
170
  expect(out).toContain('No sources matched "foo"');
171
- expect(out).toContain('Run `ktx sl list` to see available sources.');
171
+ expect(out).toContain('Run `ktx sl` to see available sources.');
172
172
  });
173
173
  it('singularizes the footer when there is one row', () => {
174
174
  const r = recorder();
package/dist/knowledge.js CHANGED
@@ -74,7 +74,7 @@ export async function runKtxKnowledge(args, io = process, deps = {}) {
74
74
  }
75
75
  const mode = resolveOutputMode({ explicit: args.output, json: args.json, io });
76
76
  let emptyMessage = `No local wiki pages matched "${args.query}"`;
77
- let emptyHint = 'Run `ktx wiki list` to inspect available pages.';
77
+ let emptyHint = 'Run `ktx wiki` to inspect available pages.';
78
78
  if (results.length === 0 && mode !== 'json') {
79
79
  const pages = await listLocalKnowledgePages(project, { userId: args.userId });
80
80
  if (pages.length === 0) {
@@ -1,4 +1,3 @@
1
- import { MANAGED_SENTENCE_TRANSFORMERS_BASE_URL_ENV } from '@ktx/context';
2
1
  import type { KtxProjectEmbeddingConfig } from '@ktx/context/project';
3
2
  import type { KtxEmbeddingConfig } from '@ktx/llm';
4
3
  import type { KtxCliIo } from './cli-runtime.js';
@@ -8,7 +7,6 @@ export interface ManagedLocalEmbeddingsDaemon {
8
7
  baseUrl: string;
9
8
  stdoutLog: string;
10
9
  stderrLog: string;
11
- env: Record<typeof MANAGED_SENTENCE_TRANSFORMERS_BASE_URL_ENV, string>;
12
10
  }
13
11
  export interface ManagedLocalEmbeddingsOptions {
14
12
  cliVersion: string;
@@ -1,4 +1,4 @@
1
- import { MANAGED_SENTENCE_TRANSFORMERS_BASE_URL, MANAGED_SENTENCE_TRANSFORMERS_BASE_URL_ENV, } from '@ktx/context';
1
+ import { MANAGED_SENTENCE_TRANSFORMERS_BASE_URL } from '@ktx/context';
2
2
  import { ensureManagedPythonCommandRuntime, } from './managed-python-command.js';
3
3
  import { startManagedPythonDaemon } from './managed-python-daemon.js';
4
4
  export function managedLocalEmbeddingProjectConfig(input) {
@@ -39,13 +39,10 @@ export async function ensureManagedLocalEmbeddingsDaemon(options) {
39
39
  force: false,
40
40
  });
41
41
  const verb = daemon.status === 'started' ? 'Started' : 'Using';
42
- options.io.stderr.write(`${verb} KTX local embeddings daemon: ${daemon.baseUrl}\n`);
42
+ options.io.stderr.write(`${verb} KTX daemon: ${daemon.baseUrl}\n`);
43
43
  return {
44
44
  baseUrl: daemon.baseUrl,
45
45
  stdoutLog: daemon.state.stdoutLog,
46
46
  stderrLog: daemon.state.stderrLog,
47
- env: {
48
- [MANAGED_SENTENCE_TRANSFORMERS_BASE_URL_ENV]: daemon.baseUrl,
49
- },
50
47
  };
51
48
  }