Ingest progress & status: per-phase progress in the UI and CLI (#64) - #69
Merged
Conversation
One progress callback threaded through ingest_repo + a graphify stdout tee, consumed by both the JobManager (UI) and the CLI. Honest-indeterminate (phase + elapsed + heartbeat + live counts), heartbeat driven by graphify's own output so a hang reads as stalled. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPzYZXxyTdj5G25KoujpHb
Six tasks: graphify Popen tee, IngestProgress callback, JobManager/API fields, UI phase/counts/elapsed/stall, CLI progress line, verification. Spec: 60s stall threshold. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPzYZXxyTdj5G25KoujpHb
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPzYZXxyTdj5G25KoujpHb
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPzYZXxyTdj5G25KoujpHb
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
#64) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #64.
What & why
Ingest gave almost no live feedback — the UI's Ingest jobs panel sat on an indeterminate bar +
running…, andtpk ingestprinted one line then went silent through minutes of extraction, so both surfaces looked stuck. This threads one progress mechanism through the pipeline and lets both surfaces consume it.How it works
graphify_runner.py) —run_graphifyswitched fromsubprocess.runtoPopen, reading graphify's stdout line-by-line and forwarding each line to anon_linecallback (the live heartbeat for the long extract phase).PYTHONUNBUFFERED=1in the child env forces line-flushing over the pipe. stderr is merged into stdout and a bounded tail is kept for the error detail.ingest.py) —IngestProgress(phase, message, nodes, edges)+ProgressFn, threaded throughingest_repoason_progress. Phases:fetch(github repos) →extract(one event per graphify line) →parse→upsert→done; node/edge counts fromparseonward. DefaultNone= no-op.api.py) — the in-memory job record gainsphase/message/updated_atand updatesnodes/edgeslive, all under the existing lock;/api/jobsexposes them (additive, no endpoint change).Manage.tsx) — active jobs show a phase label (extracting…/saving…/…), live node/edge counts, elapsed via a local 1s ticker (advances between the 5s polls), and a "stalled?" hint whenupdated_atis older than 60s. Indeterminate bar and finished line unchanged.cli.py) — a refreshing single status line on a TTY ([i/N] key · extracting… · 2m30s · <last graphify line>), throttled plain lines when piped, and--verbosestill streams graphify's full output.Design decisions (honest-indeterminate)
graphify is an opaque subprocess with no reliable per-file total, so there's no fabricated determinate bar and no
processed/total— phase + elapsed + live heartbeat + counts. The heartbeat is driven by graphify's own stdout, so a genuine hang stopsupdated_atand the UI honestly reads "stalled" (a timer would report false liveness). Jobs stay in-memory (no persistence), as before.Behavior change to call out
tpk ingest --verbosenow line-tees graphify's output (piped) rather than inheriting the terminal. Consequence: graphify likely disables color and any\r-updated progress bar collapses to line-by-line output. In exchange, the error path now captures graphify's real output tail even under--verbose. This is inherent to the tee design.Testing
PYTHONUNBUFFERED, non-zero-exit tail), theingest_repophase sequence, theJobManagerprogress sink (tested directly, no DB), and the CLI_progress_lineformatter.tsc -b && vite buildclean.Deferred to manual verification (not runnable headlessly)
tpk ingest --repo <small>to confirm graphify's lines stream live rather than batching at the end (validates thePYTHONUNBUFFERED=1assumption). If graphify batches on a pipe, the heartbeat degrades to phase-boundary granularity — still an improvement, no code path breaks.🤖 Generated with Claude Code