feat(cli): stream plain ktx ingest progress to stderr (KLO-726) (#251)

* feat(cli): share public ingest progress adapter

* feat(cli): stream plain public ingest progress

* test(cli): update plain ingest progress assertions

* chore(cli): satisfy plain ingest progress checks

* fix(artifacts): expect plain ingest stderr progress in installed-CLI smoke

* ci(coverage): make Codecov upload non-fatal and fix repo slug

The Coverage job failed because the Codecov upload returned
'Repository not found' while fail_ci_if_error was true, turning a
Codecov-side issue into a hard CI failure even though all tests pass.

- Set fail_ci_if_error: false on both uploads so Codecov outages or an
  unlinked repo no longer break CI (upload stays best-effort).
- Correct the stale slug Kaelio/ktx -> Kaelio/ktx-ai-data-agents-context
  to match the actual GitHub repo (aligns with main).

* fix(cli): isolate query-history failure capture from scan output

The plain public-ingest progress path passes one captured IO as the
target-level `io`. With progress deps set, both the schema scan and the
query-history ingest resolved their capture to that same shared buffer,
so a non-actionable query-history failure surfaced leftover scan report
text (e.g. "Mode: enriched") as the skipped-facet detail instead of the
real query-history message.

Give the query-history ingest a phase-local capture while preserving the
flow-to-io branch the foreground context-build view relies on.

---------

Co-authored-by: Andrey Avtomonov <7889985+andreybavt@users.noreply.github.com>
This commit is contained in:
Andrey Avtomonov 2026-06-01 23:31:31 +02:00 committed by GitHub
parent d01abe6f3c
commit 13774bfcef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 445 additions and 49 deletions

View file

@ -518,7 +518,10 @@ function requireExitCodeWithProjectStderr(label, result, projectDir, expectedCod
expectedCode,
label + ' failed with code ' + result.code + '\\nstdout:\\n' + result.stdout + '\\nstderr:\\n' + result.stderr,
);
assert.equal(result.stderr, 'Project: ' + projectDir + '\\n', label + ' wrote unexpected stderr');
assert.ok(
result.stderr.startsWith('Project: ' + projectDir + '\\n'),
label + ' did not lead stderr with the project notice\\nstderr:\\n' + result.stderr,
);
}
function requireSuccessWithStderr(label, result, stderrPattern) {
@ -534,6 +537,10 @@ function requireOutput(label, result, text) {
assert.match(result.stdout, text, label + ' output did not match ' + text);
}
function requireStderr(label, result, stderrPattern) {
assert.match(result.stderr, stderrPattern, label + ' stderr did not match ' + stderrPattern);
}
function escapeRegExp(value) {
return value.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&');
}
@ -857,6 +864,7 @@ try {
),
);
requireExitCodeWithProjectStderr('ktx ingest enrichment guard', databaseIngest, projectDir, 1);
requireStderr('ktx ingest enrichment guard', databaseIngest, /^ {2}failed /m);
requireOutput('ktx ingest enrichment guard', databaseIngest, /Ingest finished with partial failures/);
requireOutput('ktx ingest enrichment guard', databaseIngest, /enrichment is not configured/);
process.stdout.write('ktx ingest enrichment guard verified\\n');

View file

@ -535,6 +535,7 @@ describe('verification snippets', () => {
assert.doesNotMatch(source, /'--enrich'/);
assert.match(source, /ktx ingest enrichment guard verified/);
assert.match(source, /enrichment is not configured/);
assert.match(source, /requireStderr\('ktx ingest enrichment guard'/);
assert.match(source, /enrichment:/);
assert.match(source, /mode: deterministic/);
assert.doesNotMatch(source, /run\('pnpm', \['exec', 'ktx', 'ingest', 'run'/);