diff --git a/README.md b/README.md index 3ff0271..19e1701 100644 --- a/README.md +++ b/README.md @@ -357,7 +357,7 @@ On first run it writes `~/.diffity/inbox/config.json`: | `worktreesDir` | Where each pull request gets its worktree. | | `skipTitles` | Regular expressions matched against the title, one per line in the page — `\(payments\)`, `Release$`. A match skips the pull request before any agent runs, and ↑ overrides it; the match is re-decided at every poll, so a retitle brings the pull request back to the queue. For what a regex cannot express, `filter`. Editable from the page's Settings panel. | | `filter` | Your own words on what does and doesn't need your attention, handed to the agent — it answers with a skip instead of reviewing when a PR matches (e.g. "Skip payments-focused PRs"). The agent has to load the skill and read the diff to decide, so every skip costs an agent run; `skipTitles` above costs nothing. Editable from the page's Settings panel. | -| `alertWhen` | Your own words on what needs you *now*. The agent judges each prepared review against them and flags the ones that match; the page notifies for those only — empty means every prepared review. Editable from the page's Settings panel. | +| `alertWhen` | Your own words on what needs you *now*. The agent judges each prepared review against them and flags the ones that match, naming the findings behind the flag; the flagged ones are listed under **Alerted**, above Ready, and the page notifies for those only — empty means every prepared review. Editable from the page's Settings panel. | | `alertPaths` | Globs against the pull request's changed paths, one per line in the page — `packages/shared/src/model/**`, `**/dbref/**`. A changed file matching one marks the review as needing you now, whatever the agent made of `alertWhen`. Editable from the page's Settings panel. | | `agent.model` | `--model` for the review agent; `null` leaves its own default. Editable from the page. | | `agent.effort` | `--effort`: `low`, `medium`, `high`, `xhigh` or `max`; `null` leaves its own default. Editable from the page. | diff --git a/package-lock.json b/package-lock.json index cf63643..100a4a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8457,7 +8457,7 @@ }, "packages/api": { "name": "@diffity/api", - "version": "0.10.29", + "version": "0.10.30", "dependencies": { "@diffity/parser": "*" }, @@ -8468,7 +8468,7 @@ }, "packages/cli": { "name": "@naturalcycles/diffity", - "version": "0.10.29", + "version": "0.10.30", "license": "MIT", "dependencies": { "commander": "^14.0.3", @@ -8492,7 +8492,7 @@ }, "packages/git": { "name": "@diffity/git", - "version": "0.10.29", + "version": "0.10.30", "devDependencies": { "@types/node": "^25.5.0", "typescript": "^5.9.3", @@ -8501,7 +8501,7 @@ }, "packages/github": { "name": "@diffity/github", - "version": "0.10.29", + "version": "0.10.30", "dependencies": { "@diffity/api": "*", "@diffity/parser": "*" @@ -8514,7 +8514,7 @@ }, "packages/parser": { "name": "@diffity/parser", - "version": "0.10.29", + "version": "0.10.30", "devDependencies": { "typescript": "^5.9.3", "vitest": "^4.1.0" @@ -8522,7 +8522,7 @@ }, "packages/ui": { "name": "@diffity/ui", - "version": "0.10.29", + "version": "0.10.30", "dependencies": { "@diffity/api": "*", "@diffity/parser": "*", diff --git a/packages/api/package.json b/packages/api/package.json index 639dfbd..f338e50 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@diffity/api", - "version": "0.10.29", + "version": "0.10.30", "private": true, "type": "module", "main": "./dist/index.js", diff --git a/packages/cli/package.json b/packages/cli/package.json index 8fa4dc4..f0834a4 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@naturalcycles/diffity", - "version": "0.10.29", + "version": "0.10.30", "description": "Agent-agnostic, GitHub-style diff viewer and code review tool with a live agent loop", "type": "module", "bin": { diff --git a/packages/cli/src/commands/inbox.ts b/packages/cli/src/commands/inbox.ts index f099e4e..a5c109b 100644 --- a/packages/cli/src/commands/inbox.ts +++ b/packages/cli/src/commands/inbox.ts @@ -6,7 +6,7 @@ import { inboxConfigPath, inboxStorePath } from '../inbox/paths.js'; import { InboxStore, type RunTotals } from '../inbox/store.js'; import { runDaemon } from '../inbox/daemon.js'; import { allowFromEnv, mcpGateDecision } from '../inbox/mcp-gate.js'; -import { buildView } from '../inbox/view.js'; +import { buildView, type InboxRow } from '../inbox/view.js'; import { localHhMm, localWhen, minutesOf, money, tokensLabel } from '../inbox/runs.js'; export function registerInboxCommand(program: Command): void { @@ -87,16 +87,15 @@ export function registerInboxCommand(program: Command): void { return; } - if (view.ready.length === 0 && view.working.length === 0 && view.handled.length === 0 - && view.other.length === 0 && view.dismissed.length === 0) { + if (view.alerted.length === 0 && view.ready.length === 0 && view.working.length === 0 + && view.handled.length === 0 && view.other.length === 0 && view.dismissed.length === 0) { console.log(pc.dim('Nothing in the inbox yet. Run `diffity inbox` to start watching.')); spent(view); return; } - section('Ready to review', view.ready.map(row => - ` ${sizeBadge(row)} ${pc.bold(`${row.repo}#${row.number}`)} ${row.title}${row.summary ? pc.dim(` ${row.summary}`) : ''}${row.alert ? pc.red(` ⚠ ${row.alert}`) : ''}${row.stale ? pc.yellow(' (stale — new commits)') : ''}`, - )); + section('Alerted', view.alerted.map(preparedLine)); + section('Ready to review', view.ready.map(preparedLine)); section('Queue', view.working.map(row => ` ${pc.dim(row.status.padEnd(9))} ${row.repo}#${row.number} ${row.title} ${pc.dim(row.statusReason ?? '')}`, )); @@ -199,6 +198,16 @@ function section(title: string, lines: string[]): void { } } +/** A prepared review as one line: its size, what was found, and what was raised about it. */ +function preparedLine(row: InboxRow): string { + const findings = row.alertFindings.length; + return ` ${sizeBadge(row)} ${pc.bold(`${row.repo}#${row.number}`)} ${row.title}` + + `${row.summary ? pc.dim(` ${row.summary}`) : ''}` + + `${row.alert ? pc.red(` ⚠ ${row.alert}`) : ''}` + + `${findings ? pc.red(` ${findings} finding${findings === 1 ? '' : 's'}`) : ''}` + + `${row.stale ? pc.yellow(' (stale — new commits)') : ''}`; +} + function sizeBadge(row: { additions: number; deletions: number }): string { return pc.dim(`+${row.additions}/-${row.deletions}`.padEnd(12)); } diff --git a/packages/cli/src/inbox/page.ts b/packages/cli/src/inbox/page.ts index c7d880c..a13a856 100644 --- a/packages/cli/src/inbox/page.ts +++ b/packages/cli/src/inbox/page.ts @@ -113,6 +113,10 @@ export function inboxPage(): string {
+