Skip to content

fix(ingest): detect active question tools awaiting input#45

Open
EZotoff wants to merge 2 commits into
masterfrom
fix/question-state-detection
Open

fix(ingest): detect active question tools awaiting input#45
EZotoff wants to merge 2 commits into
masterfrom
fix/question-state-detection

Conversation

@EZotoff
Copy link
Copy Markdown
Owner

@EZotoff EZotoff commented May 10, 2026

Summary

Fixes incorrect question-state detection when canonical question tools have status: "running" in OpenCode's SQLite database.

Problem

  • Live question tools were classified as running_tool instead of question because detection only accepted status: "pending".
  • This caused missing question styling (active/cyan instead of question style) and missing question sounds.

Solution

  • Add isActiveQuestionTool(toolName, status) for known question tools in pending | running.
  • Use it in main-session, inclusion, and background-task derivation paths.
  • Keep isPendingQuestionTool() pending-only to preserve stale-running suppression behavior.
  • Add regressions for file-based, SQLite bridge/background, and sound-diff paths.

Test Results

  • Full suite: 27 files, 235 tests passed
  • Focused regression: 5 files, 41 tests passed
  • LSP diagnostics clean on all changed files

EZotoff added 2 commits May 6, 2026 21:14
Users typing ~/projects/foo in the add-project form got a 'directory does
not exist' error because Node's fs.existsSync doesn't expand tilde. The
new expandTilde() helper (reusing the same pattern from XDG path handling)
resolves ~ to os.homedir() before validation and storage.
- Add isActiveQuestionTool() for known question tools in pending|running
- Use it in main-session, inclusion, and background-task derivation
- Keep isPendingQuestionTool() pending-only for stale suppression
- Add regressions for file-based, SQLite, and sound-diff paths
Copilot AI review requested due to automatic review settings May 10, 2026 13:07
@github-actions github-actions Bot added the code label May 10, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves ingest/UI status derivation so canonical “question” tools are detected as question not only when status: "pending", but also when status: "running" (as observed in OpenCode’s SQLite DB), restoring question styling and question sounds.

Changes:

  • Add isActiveQuestionTool(toolName, status) to treat known question tools as active for pending | running, and use it across main-session, inclusion, and background-task derivation paths.
  • Update file-based and SQLite background-task derivation to surface question status when canonical question tools are running.
  • Add regression tests covering file-based, SQLite bridge/background, and sound-diff behavior; also add ~ expansion for project source registration.

[RISK:medium]

[SCORES]
{"security":4,"safety":4,"performance":4,"featureQuality":3,"confidence":4}
[/SCORES]

[SUMMARY]
The question-tool detection changes look well-covered by targeted regressions and align with the PR’s stated problem. However, the SQLite session inclusion path now appears unable to derive error status while still treating error as an attention/severity state, which can cause errored sessions to be filtered out after the idle window; this should be addressed before approval.
[/SUMMARY]

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/ui/components/AddProjectForm.tsx Updates project-root placeholder to a ~-based example path.
src/server/api.ts Expands ~ in projectRoot before validating and persisting a new source.
src/ingest/tool-names.ts Adds isActiveQuestionTool() (pending or running) while keeping isPendingQuestionTool() for stale suppression.
src/ingest/sqlite-derive.ts Uses active-question detection for SQLite-derived session/background task statuses.
src/ingest/session-status.ts Classifies active running canonical question tools as question for main session status.
src/ingest/session-inclusion.ts Updates inclusion prefilter to treat active running question tools as question; refactors batch-query maps.
src/ingest/paths.ts Adds expandTilde() helper for ~ / ~/... expansion.
src/ingest/background-tasks.ts Uses active-question detection for file-based background task status derivation.
src/tests/session-status-derivation.test.ts Adds regression for file-based “running question tool => question”.
src/tests/session-inclusion.test.ts Adds regression asserting question sessions sort ahead of busy sessions.
src/tests/session-diff.test.ts New regression ensuring question sound plays on transition into question.
src/tests/question-bridge-sqlite.test.ts Adds regression for SQLite background question tool with status: "running".
src/tests/background-tasks-derive.test.ts Adds regression for SQLite background task marked question when child tool is running.
Comments suppressed due to low confidence (1)

src/ingest/session-inclusion.ts:12

  • [SEVERITY:warning] [DIM:featureQuality]

findIncludedSessionsSqlite no longer queries terminal part statuses (e.g. error), but the inclusion/ordering logic still treats error as an attention status (STATUS_SEVERITY.error = 0, isAttentionStatus includes it). As written, deriveSessionStatusFromMaps cannot return "error", so sessions with tool errors may be filtered out once they age past idleWindowMs, and the error severity branch becomes unreachable.

Consider restoring a lightweight terminal-part query for state.status = 'error' (or otherwise deriving error from available data) and returning "error" from deriveSessionStatusFromMaps when applicable; alternatively, if error-attention is intentionally removed, delete the error severity/attention handling to avoid misleading logic.

// Severity levels for attention-first ordering
const STATUS_SEVERITY: Record<string, number> = {
  error: 0,
  question: 1,
  running_tool: 2,

Comment thread src/server/api.ts
Comment on lines 74 to +84
if (!projectRoot || typeof projectRoot !== "string" || projectRoot.trim() === "") {
return c.json({ ok: false, error: "projectRoot is required and must be a non-empty string" }, 400)
}

if (!fs.existsSync(projectRoot)) {
const resolvedRoot = expandTilde(projectRoot.trim())

if (!fs.existsSync(resolvedRoot)) {
return c.json({ ok: false, error: "projectRoot directory does not exist" }, 400)
}

const sourceId = addOrUpdateSource(opts.storageRoot, projectRoot, label)
const sourceId = addOrUpdateSource(opts.storageRoot, resolvedRoot, label)
Comment thread src/ingest/paths.ts
Comment on lines +7 to +14
export function expandTilde(p: string, hd?: string): string {
const home = hd ?? os.homedir()
if (p === "~") return home
if (p.startsWith("~/") || p.startsWith("~\\")) {
return path.join(home, p.slice(2).replace(/[\\/]+/g, path.sep))
}
return p
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants