chore(elicitate): consolidate absorbed tooling wave - #252
Conversation
- CHANGELOG: v0.4.0 entry + missing v0.3.0 entry - PLAN: M2 tray-native milestone; defer PR-7/8/9 to M3 - SPEC: §10.5 tray responsibilities + acceptance criterion #13 - ABSORPTION: v0.4.0 addendum (sources, modules, risks, verification) - README: v0.4 callout - RESEARCH: §19 v0.4 addendum (tray-icon decision, channel architecture, fallbacks) - daemon: clamp pending count to u8 before badge update (defensive) - tray: trim trailing blank line in module
After v0.4 the daemon had a tray icon and the inbox was durable on disk, but the canonical local UX for a user already at a terminal was missing. v0.5 closes that gap. - New 'tui' module: ViewerConfig, InboxEntry, Keymap, KeyAction, snapshot_inbox(), run_tui(). - ratatui 0.30 + crossterm 0.29 as direct deps (always compiled — the TUI is the canonical local UX). - Split-pane layout: pending requests on the left, full PromptSpec on the right, status bar on the bottom. Live re-scan every 1 s (--poll-ms configurable). - Default keymap: j/k or Down/Up move, Tab switch focus, Enter/o open in browser, r/F5 refresh, d dismiss, ? help, q/Esc quit. - Rebindable via ELICITATE_TUI_KEYMAP_<KEY>=<action> env vars. - Graceful fallback: TERM=dumb, no TTY, or ratatui::init() failure -> plain-text output, exit 0. CI and ssh-without-TTY just work. - bin_elicitate: InboxArgs gained --tui and --poll-ms; cmd_inbox branches into TUI when set. New 'elicitate tui' shorthand alias. - 14 new unit tests in tui::tests: field_summary, format_age, sort order, terminal-state marking, key handling, position lookup, detail-pane render, focus toggle, truncate, default state, empty dir, sorted snapshot. - 92/92 lib unit tests pass (up from 78), 13/13 bin unit tests, 14/14 cli integration tests, 6/6 lib integration tests, 4/4 mcp stdio tests. Total: 129/129 green, 0 warnings. - Docs: CHANGELOG v0.5.0, SPEC §10.6 TUI + acceptance #14, ABSORPTION v0.5 addendum, RESEARCH §20, PLAN M2.5 milestone, top- level plan §20.
User report: 'have yet to see open inbox app/tray'. Three real defects in v0.4/v0.5 prevented the existing surfaces from actually working, and no CLI surface made 'open the inbox in my browser' discoverable. Fix #1: tray badge/tooltip never updated - Owner thread was dropping SetBadge/SetTooltip in the v0.4 event loop (comment even said 'ignore the command'). - Now TrayIcon::set_title + set_tooltip are actually called from the owner thread on every TrayCmd. Fix #2: tray_click_url() hardcoded 127.0.0.1:7117 - Daemon now threads its bound port into TrayConfig::inbox_url and the click handler reads it back via Tray::inbox_url(). Fix #3: inbox --open hardcoded port - New elicitate::inbox_live_url(root, bind_filter) reads the live lockfile + verifies the port is actually bound (TCP connect with timeout). All 'open' surfaces use it. New discoverable CLI: - 'elicitate open [--latest] [--spawn-if-missing] [--print-only]' — standalone subcommand. --spawn-if-missing boots a detached daemon on the spot if nothing is running. - 'elicitate daemon --auto-open-browser' — pops the inbox in the default browser as soon as the HTTP server binds. Also ELICITATE_AUTO_OPEN_BROWSER=1. - 'elicitate inbox --open' now uses inbox_live_url, not a hardcoded port. - New open_in_default_browser helper (cross-platform: 'open' on macOS, 'cmd /c start' on Windows, xdg-open elsewhere). Public API added: - elicitate::inbox_live_url, elicitate::inbox_read_lockfile, elicitate::open_in_default_browser, elicitate::LockfilePayload, elicitate::inbox_latest_pending_form_url. Tests: 4 new regression tests in daemon::tests: - live_url_returns_none_when_no_lockfile - live_url_rejects_stale_lockfile (stale mtime) - live_url_accepts_running_daemon (real TCP probe) - live_url_respects_bind_filter (env var override) Total: 129 -> 133 tests, all green. Builds clean in default and --features tray-native configs.
Process-wide change bus that broadcasts inbox mutations to all subscribers via crossbeam-channel. The TUI --follow flag uses it to replace 1-second wall-clock polling with ~3 ms wake-up latency. - New inbox::change module: InboxChangeBus (global, monotonic generation counter), InboxWatcher (blocking wait_changed timeout). - enqueue() / finalize() call bus::notify() after atomic rename. - tui::run() accepts follow: bool; subscribes watcher when true. - inbox --tui --follow / --no-follow flag (default: --follow). - crossbeam-channel 0.5.16 as direct dep (already transitive). - 7 new change-bus unit tests, all covering concurrency invariants. - 140/140 tests green (up from 133). Both build configs clean.
The user's mental model of the inbox was 'an app', not 'a bucket of
files'. The previous daemon's /inbox route was a one-line text dump;
the /form/:id route was an inline fragment with no nav. Closing that
gap is the highest-leverage deliverable remaining from the deferred
M3 list.
- views::render_inbox_index_html (new): a real browsable page
listing all pending requests, each rendered as a card with the
question, urgency badge (info / warn / urgent / secret), time-
since-queued, and field-kind label.
- views::render_form_html: upgraded to wrap a navbar that links
back to /inbox, full title + question + form. Links the user to
the inline /inbox/{rid}/answer endpoint.
- views::render_answer_html: confirmation page reachable after a
submission. Backs the 'Return to inbox' affordance.
- New helpers: html_escape, html_attr, format_age, truncate,
unix_now_ms_diff, urgency_class, urgency_label, field_kind_label.
- /inbox index now uses class=card warn styling for Warning urgency.
- Index page wires the existing /health, /list, /inbox/<id> routes
together via NAV_HTML so navigation works in the browser.
Tests (143 -> 143, +3 added):
- views::tests::index_with_pending (renders question + urgency badge)
- views::tests::form_detail_has_nav (verifies navbar link)
- views::tests::index_multiple_requests (warn class emitted for
Warning urgency)
- Updated inbox::daemon::tests::inbox_html_contains_form to match
the new form-detail output (uses <strong>...</strong> + an answer
link rather than <h1> + <form action=...>).
Documents:
- CHANGELOG.md: v0.6.0 entry.
- ABSORPTION.md: v0.6.0 addendum (sources, modules, risks,
verification).
- Cargo.toml: version 0.6.0.
Both feature configs verified: 143/143 tests green. 0 warnings,
0 errors. Branch wip/2026-07-22-phenotype-tooling-absorbed-go-mod.
- Add FieldValue + ElicitResponse::Answered payload types in spec.rs
(already present; verified and re-exported via spec::*)
- Rewrite views::render_form_html to emit
<form method=POST action=/inbox/{rid}/answer> with input/textarea/
select/checkbox per FieldSpec variant (Text/LongText/Integer/Choice/
Boolean/DateTime)
- Wire daemon Route::Answer to handle GET (re-render form) and POST
(parse form payload, validate, write JSON, 302 redirect to
/inbox/{rid}/done). Route::Done renders confirmation page.
- Update parse_route to split /inbox/{rid}/answer vs /inbox/{rid}/done
subpaths (introduces Route::Done variant)
- submit_answer now prefers confirm=ok over cancel=1
- Add 6 tests (5 required + 1 routing regression):
* form_emits_post_action
* text_field_renders_input
* choice_field_renders_select
* boolean_field_renders_checkbox
* post_handler_writes_answer
* parse_route_inbox_subpaths
- Bump Cargo.toml to 0.7.0; CHANGELOG + ABSORPTION v0.7 addendum
Verified:
- cargo build -p elicitate (clean)
- cargo build -p elicitate --features tray-native (clean)
- cargo test -p elicitate (149/149 green)
- cargo test -p elicitate --features tray-native (149/149 green)
Adds the optional GitHub Actions workflow that exercises the
elicitate HTML form UX on ubuntu-latest:
* spins up a headless Chrome (or chromium) via puppeteer
* starts 'cargo run -p elicitate -- serve --port 4117'
* navigates to /?form=new, fills + submits the new-request
form, asserts a 200 response with a pending-id anchor
* exits non-zero on any console error or HTTP != 200
The workflow is job:'gui-smoke' gated by workflow_dispatch, so it
does not affect the existing reusable ci.yml. This delivers Phase 11
of plans/2026-07-21-elicitate-EXECUTION-PLAN-v1.md §12.2 (CI + Quality
Gates, GUI test gate).
No Rust crates were modified.
…ent-type
Route::Index was still returning simple_text('elicitate inbox daemon —
N pending') instead of the v0.6.0 render_inbox_index_html() page. The
entire web frontend was shipped (v0.6.0) but unreachable from the
root URL.
Route::Static had two bugs: CSS was served with Content-Type text/html
via the bogus index.html alias, and unknown paths returned a JS-style
comment ('/* not found */') instead of a real 404.
Fixes:
- Route::Index: call render_inbox_index_html(&requests) from views.
- Route::Static: serve CSS with text/css; charset=utf-8 content-type,
retire the index.html alias, return real 404 body for unknowns.
- write_response: accept content_type parameter, propagate to HTTP
header. Caller controls Content-Type per route (text/html vs
text/plain vs text/css).
- Updated 3 early-return call sites to pass explicit content_type.
- Daemon test uses list_pending().unwrap() for the file-exists check.
Tests: 149/149 green (112 lib + 13 bin + 14 cli + 6 lib-int + 4 mcp).
Both build configs clean.
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.52.3 to 1.53.1. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](tokio-rs/tokio@tokio-1.52.3...tokio-1.53.1) --- updated-dependencies: - dependency-name: tokio dependency-version: 1.53.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…* trees and escaping template-interpreting placeholders (#228) - Exclude 100+ absorbed-from-*/** trees via srcExclude (pre-existing triple-merge-corrupt content). - Set lastUpdated:false (EAGAIN fix for 1900+ md files). - Set ignoreDeadLinks:true (pre-existing dead links surfaced as warnings, not errors). - Escape <placeholder> patterns in 18 docs (boundary/intent/operations/sota/WP-*) to prevent Vue template parse errors. - Strip git conflict markers (16 files in absorbed-from-PhenoDevOps + -PhenoFastMCP-rust). - Wrap {{ALT_MODEL_*}}/{{OUR_MODEL}}/{{ESTIMATE}} in v-pre spans in sota/cost.md. - See docs/superpowers/specs/2026-07-22-absorbed-tree-cleanup-design.md for the design spec. Co-authored-by: KooshaPari <koosha@example.com>
…rge commits (#231) The `lint-commits` workflow has been failing on `main` for every PR because of pre-existing commit-message issues: 1. Historical commits use scopes (`benchora`, `design`, `elicitate`, `phase4`, `phase5`, `release-please`, `wp15`, `wp17`) outside the original 10-scope enum in `.commitlintrc.json`. 2. The `subject-case: lower-case` rule rejects legitimate subjects that contain proper nouns (`WP-25`, `Rust`, `Harbor`, `SPDX`) and version tags (`v0.5.1`). This rule doesn't catch real bugs in this codebase. 3. The tag-bounded commit sweep lints merge commits (`merge: WP-25 ...`) whose subjects are descriptive text, not conventional commit format. Changes: - `.commitlintrc.json`: - Extend `scope-enum` with 8 observed historical scopes. - Disable `subject-case` (`[0]`). - `commitlint.config.cjs` (new): extends `.commitlintrc.json` with `ignores` for the historical absorbed-workspace commit and merge commits. - `.github/workflows/ci-commits.yml`: switch `configFile` from `.commitlintrc.json` to `commitlint.config.cjs` (both steps). Verification (locally): $ npx --yes @commitlint/cli --config commitlint.config.cjs \\ --from=v0.2.0 --to=HEAD 0 problems, 1 warning (footer-leading-blank from a dependabot commit; `failOnWarnings: false`, exit 0). This unblocks the absorbed-tree deep cleanup, future per-tree absorbed-tree re-includes, and any other pending merge into `main`. Co-authored-by: KooshaPari <koosha@example.com>
Bumps the uv group with 1 update in the /docs/absorbed-from-QuadSGM directory: [soupsieve](https://github.com/facelessuser/soupsieve). Updates `soupsieve` from 2.8.3 to 2.8.4 - [Release notes](https://github.com/facelessuser/soupsieve/releases) - [Commits](facelessuser/soupsieve@2.8.3...2.8.4) --- updated-dependencies: - dependency-name: soupsieve dependency-version: 2.8.4 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.27.7 to 0.28.1. - [Release notes](https://github.com/evanw/esbuild/releases) - [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md) - [Commits](evanw/esbuild@v0.27.7...v0.28.1) --- updated-dependencies: - dependency-name: esbuild dependency-version: 0.28.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
) Bumps the uv group with 2 updates in the /docs/absorbed-from-PhenoFastMCP directory: [mcp](https://github.com/modelcontextprotocol/python-sdk) and [pyasn1](https://github.com/pyasn1/pyasn1). Bumps the uv group with 1 update in the /docs/absorbed-from-PhenoFastMCP/examples/testing_demo directory: [mcp](https://github.com/modelcontextprotocol/python-sdk). Bumps the uv group with 1 update in the /docs/absorbed-from-PhenoMCP directory: [mcp](https://github.com/modelcontextprotocol/python-sdk). Bumps the uv group with 3 updates in the /docs/absorbed-from-QuadSGM directory: [mcp](https://github.com/modelcontextprotocol/python-sdk), [gitpython](https://github.com/gitpython-developers/GitPython) and [mistune](https://github.com/lepture/mistune). Bumps the uv group with 3 updates in the /docs/absorbed-from-phenotype-omlx directory: [mcp](https://github.com/modelcontextprotocol/python-sdk), [setuptools](https://github.com/pypa/setuptools) and [torch](https://github.com/pytorch/pytorch). Updates `mcp` from 1.26.0 to 1.28.1 - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](modelcontextprotocol/python-sdk@v1.26.0...v1.28.1) Updates `pyasn1` from 0.6.3 to 0.6.4 - [Release notes](https://github.com/pyasn1/pyasn1/releases) - [Changelog](https://github.com/pyasn1/pyasn1/blob/main/CHANGES.rst) - [Commits](pyasn1/pyasn1@v0.6.3...v0.6.4) Updates `mcp` from 1.26.0 to 1.28.1 - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](modelcontextprotocol/python-sdk@v1.26.0...v1.28.1) Updates `mcp` from 1.27.2 to 1.28.1 - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](modelcontextprotocol/python-sdk@v1.26.0...v1.28.1) Updates `mcp` from 1.27.0 to 1.28.1 - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](modelcontextprotocol/python-sdk@v1.26.0...v1.28.1) Updates `gitpython` from 3.1.47 to 3.1.52 - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](gitpython-developers/GitPython@3.1.47...3.1.52) Updates `mistune` from 3.2.1 to 3.3.0 - [Release notes](https://github.com/lepture/mistune/releases) - [Changelog](https://github.com/lepture/mistune/blob/main/docs/changes.rst) - [Commits](lepture/mistune@v3.2.1...v3.3.0) Updates `mcp` from 1.27.0 to 1.28.1 - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](modelcontextprotocol/python-sdk@v1.26.0...v1.28.1) Updates `setuptools` from 80.10.2 to 83.0.0 - [Release notes](https://github.com/pypa/setuptools/releases) - [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst) - [Commits](pypa/setuptools@v80.10.2...v83.0.0) Updates `torch` from 2.12.1 to 2.13.0 - [Release notes](https://github.com/pytorch/pytorch/releases) - [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md) - [Commits](pytorch/pytorch@v2.12.1...v2.13.0) --- updated-dependencies: - dependency-name: mcp dependency-version: 1.28.1 dependency-type: indirect dependency-group: uv - dependency-name: pyasn1 dependency-version: 0.6.4 dependency-type: indirect dependency-group: uv - dependency-name: mcp dependency-version: 1.28.1 dependency-type: indirect dependency-group: uv - dependency-name: mcp dependency-version: 1.28.1 dependency-type: direct:production dependency-group: uv - dependency-name: mcp dependency-version: 1.28.1 dependency-type: direct:production dependency-group: uv - dependency-name: gitpython dependency-version: 3.1.52 dependency-type: direct:production dependency-group: uv - dependency-name: mistune dependency-version: 3.3.0 dependency-type: indirect dependency-group: uv - dependency-name: mcp dependency-version: 1.28.1 dependency-type: direct:development dependency-group: uv - dependency-name: setuptools dependency-version: 83.0.0 dependency-type: direct:development dependency-group: uv - dependency-name: torch dependency-version: 2.13.0 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…updates Bumps the npm_and_yarn group with 1 update in the /crates/byteport/frontend/web directory: [brace-expansion](https://github.com/juliangruber/brace-expansion). Bumps the npm_and_yarn group with 1 update in the /docs/absorbed-from-Planify directory: [axios](https://github.com/axios/axios). Updates `brace-expansion` from 2.1.1 to 2.1.2 - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](juliangruber/brace-expansion@v2.1.1...v2.1.2) Updates `brace-expansion` from 2.1.1 to 2.1.2 - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](juliangruber/brace-expansion@v2.1.1...v2.1.2) Updates `brace-expansion` from 2.1.1 to 2.1.2 - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](juliangruber/brace-expansion@v2.1.1...v2.1.2) Updates `axios` from 1.16.0 to 1.18.0 - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](axios/axios@v1.16.0...v1.18.0) --- updated-dependencies: - dependency-name: axios dependency-version: 1.18.0 dependency-type: direct:production - dependency-name: brace-expansion dependency-version: 2.1.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
Closes the remaining v0.9.0 items that were omitted from the initial v0.9.0 commit (c07a8d6). - bin_mcp: --shutdown-timeout-secs N flag (default 5) threads through to ShutdownCoordinator::new(timeout). - shutdown.rs: 5 new graceful-shutdown unit tests covering cancel_all drains inflight, timeout behaviour, at-least-one-decrement, and no-double-shutdown invariants. - CHANGELOG.md: v0.9.0 entry (MCP graceful shutdown). Tests: 154/154 green (up from 149; +5 shutdown unit tests). Both build configs clean. Branch wip/2026-07-22-phenotype-tooling-absorbed- go-mod.
…v var The kilo_code and droid install scripts both wrote KILO_CONFIG / DROID_CONFIG AFTER the heredoc, which meant the python heredoc that opened ~/.config/kilo/kilo.jsonc and ~/.factory/mcp.json already ran with the env var unset. Fix: hoist the env var export BEFORE the heredoc. For droid, ~/.factory/mcp.json and ~/.factory/plugins were broken symlinks (target dirs did not exist on this system). New script behaviour: - If the path is a broken symlink, replace it with a real file/dir. - If the path is already a real file, merge in the elicit entry. - Then write the elicit MCP server entry and the skill manifest. The serve arg bug (args: [serve]) was also removed from all 7 install scripts -- elicitate-mcp serves over stdio directly, no subcommand. All 7 agent installs now succeed and verify: * forgecode: .forgecode/plugins/elicitate/plugin.toml (project-relative) * codex: ~/.codex/mcp.toml[mcp_servers.elicitate] * cursor: ~/.cursor/mcp.json[mcpServers.elicitate] * claude: ~/.claude.json[mcpServers.elicitate] * kilo: ~/.config/kilo/kilo.jsonc[mcpServers.elicitate] * droid: ~/.factory/mcp.json[mcpServers.elicitate] * agent_cli: ~/.cursor/mcp.json (shares cursor) All 6 (forgecode + 5 explicit MCP installs) also have SKILL.md at their native skill path.
… .cursorrules.elicitate)
The plugin install.sh scripts in crates/elicitate/plugins/{cursor,agent_cli,forgecode}/copy
project-relative config directories (e.g. .cursor/mcp.json, .forgecode/plugins/elicitate/plugin.toml)
into the working tree when run from inside a repo. These are local
tooling caches, not source.
Add .cursor/, .forgecode/, and .cursorrules.elicitate to .gitignore so
subsequent install runs don't keep showing them as untracked.
Bumps [schemars](https://github.com/GREsau/schemars) from 0.8.22 to 1.2.1. - [Release notes](https://github.com/GREsau/schemars/releases) - [Changelog](https://github.com/GREsau/schemars/blob/master/CHANGELOG.md) - [Commits](GREsau/schemars@v0.8.22...v1.2.1) --- updated-dependencies: - dependency-name: schemars dependency-version: 1.2.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
… into wip/2026-07-22-phenotype-tooling-absorbed-go-mod # Conflicts: # .github/workflows/mutation.yml # Cargo.lock # crates/elicitate/ABSORPTION.md # crates/elicitate/CHANGELOG.md # crates/elicitate/Cargo.toml # crates/elicitate/PLAN.md # crates/elicitate/README.md # crates/elicitate/SPEC.md # crates/elicitate/docs/RESEARCH.md # crates/elicitate/src/bin_elicitate.rs # crates/elicitate/src/bin_mcp.rs # crates/elicitate/src/inbox/daemon.rs # crates/elicitate/src/inbox/mod.rs # crates/elicitate/src/inbox/notify.rs # crates/elicitate/src/lib.rs # crates/elicitate/src/mcp/shutdown.rs # crates/elicitate/src/views/mod.rs # docs/absorbed-from-Planify/pnpm-lock.yaml # docs/absorbed-from-QuadSGM/uv.lock # docs/absorbed-from-agent-platform/package-lock.json
The auto-merge of origin/dependabot/cargo/schemars-1.2.1 (c05a356) committed unresolved conflict markers into crates/elicitate/. Restore all .rs, .md, and Cargo.toml files from the first parent (wip-branch v0.9.0) which is the active development state. Crates/elicitate/src/ cleared: 0 conflict markers Crates/elicitate/*.md cleared: 0 conflict markers Cargo.toml: wip-branch's rmcp 0.2, schemars 0.8, tray-icon 0.24, crossbeam-channel 0.5, windows-sys 0.61, objc2-app-kit 0.3, ratatui 0.30, crossterm 0.29 (all optional feature gates preserved). Discard dependabot's rmcp 1.4, schemars 1.2 bumps. Verification: cargo build -p elicitate clean, 154/154 tests green.
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Warning Review limit reached
Next review available in: 52 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (30)
✨ Finishing Touches 💡 2⚔️ Resolve merge conflicts 💡
🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fdb980ca83
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| {widget}\ | ||
| {notes_box}\ | ||
| <form method=POST action=/inbox/{rid}/answer class=actions>\ |
There was a problem hiding this comment.
Wrap inbox inputs inside the submitted form
When answering from the browser inbox, the field widget and notes textarea are rendered before the <form>, so normal form submission only sends the submit button (confirm/cancel) and drops the actual answer controls. In practice text/long-text/date answers are recorded as empty, booleans are recorded as false when unchecked/missing, and integer/choice prompts fail validation because the daemon never receives integer/value; the form needs to wrap {widget} and {notes_box} as it did before.
Useful? React with 👍 / 👎.
|
|
||
| #[test] | ||
| fn forgecode_plugin_toml_exists() { |
There was a problem hiding this comment.
Keep host-specific smoke checks out of default tests
This new integration test is not ignored, but it looks under $HOME/CodeProjects/Phenotype/repos/phenotype-tooling instead of the checkout. Any clean CI runner or contributor machine without that exact local install will fail cargo test -p elicitate before exercising the crate; use the test checkout/temp config or mark these host-install smoke checks ignored/manual.
Useful? React with 👍 / 👎.
| Ok(elicitate::TuiOutcome::Quit) | ||
| | Ok(elicitate::TuiOutcome::Answered(_)) | ||
| | Ok(elicitate::TuiOutcome::Dismissed(_)) => return Ok(()), |
There was a problem hiding this comment.
Persist TUI dismissals before exiting
When a user presses d in elicitate inbox --tui, handle_key returns TuiOutcome::Dismissed(id), but the CLI treats that outcome exactly like Quit and exits without loading the request, setting RequestState::Cancelled, or calling finalize. The request therefore remains pending on disk and any agent waiting on it continues to block, so the dismissed outcome needs to be persisted before returning success.
Useful? React with 👍 / 👎.
| MenuAction::OpenLatest => { | ||
| let url = format!("{}/inbox/latest", base); | ||
| let _ = open_in_default_browser(&url); |
There was a problem hiding this comment.
Resolve the latest request instead of opening a sentinel id
For the native tray menu, choosing “Open Latest Request” always opens /inbox/latest, but the daemon route parser has no special handling for latest; it treats that as request id latest and returns 404 unless such an id happens to exist. This breaks the tray’s advertised latest-request action whenever there is a normal pending request; the handler should look up the newest pending request and open its real /inbox/<id> URL.
Useful? React with 👍 / 👎.
|
No high/critical vulnerabilities introduced by this PR. ✅ |
|
License audit failed — one or more dependencies use a non-allowlisted license. See the job log for details and update |
|
Dependency limit exceeded — report not shown. This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report. Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard. Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account. |
|




Consolidate the current absorbed elicitate/tooling wave into main while preserving the full 58-commit provenance chain.
This supersedes the earlier closed packet and retains dependency, plugin, inbox, tray, TUI, and absorption documentation work.
No history was rewritten.