Local Rust runtime for routing tool-improvement feedback, running tool-specific Codex triage and patch jobs, and sending status updates through Telegram.
The v1 feedback loop is wired and verified:
- stores the Telegram bot token in a local secret file
- stores the paired Telegram chat id and Telegram update offset in local config
- stores cases, case events, and maintainer runs in a local SQLite database
- dedupes repeated submissions against still-open cases
- bootstraps a local tool-owner registry with separate triage and patch settings
- runs
triagefirst for accepted cases - sends Telegram when triage closes a case or returns
awaiting_approval - starts
patchonly aftercase approve-patch ...or a Telegram reply likeapprove case_000123 - records structured maintainer results, files changed, and tests run
- keeps run artifacts under
~/.codex/tool-feedback/runs/
State lives under ~/.codex/tool-feedback/.
Run a full local health check:
cargo run -- doctorInstall the current binary into ~/.local/bin/tool-feedback so agents can call it directly:
cargo run -- installYou can override the destination:
cargo run -- install --dest /custom/bin/tool-feedbackInitialize local config:
cargo run -- telegram initStore the bot token:
cargo run -- telegram set-bot-token <token>Pair the bot to the current Telegram chat after sending /start:
cargo run -- telegram pairInspect local notifier status:
cargo run -- telegram doctorSend a test notification:
cargo run -- notify test --text "tool-feedback notifier wired successfully"Refresh the default owner registry after upgrading to the triage/patch flow:
cargo run -- owner init --forceSubmit a new tool-feedback case:
cargo run -- submit \
--tool codex-recall \
--summary "Search returns noisy snippets" \
--details "Phrase search is matching nested command echoes instead of the user's actual ask."List and inspect cases:
cargo run -- case list
cargo run -- case list --status awaiting_approval
cargo run -- case show case_000001 --events-limit 20Transition a case. Every transition runs one daemon cycle immediately, so case accept can start triage and case approve-patch can start patching right away:
cargo run -- case accept case_000001 --message "Accepted for triage."
cargo run -- case approve-patch case_000001 --message "Approved for patch."
cargo run -- case block case_000001 --message "Waiting on reproduction details."
cargo run -- case complete case_000001 --message "Patched and verified."
cargo run -- case reject case_000001 --message "Existing flag already covers this."
cargo run -- case defer case_000001 --message "Valid idea, but not for v1."
cargo run -- case duplicate case_000001 --message "Duplicate of case_000004."
cargo run -- case note case_000001 --message "Need to inspect the originating transcript with codex-recall."Telegram approval syntax from the paired chat:
approve case_000001
approve case_000001 keep the fix small and repo-local
Inspect the owner registry:
cargo run -- owner list
cargo run -- owner show codex-recallInspect maintainer runs:
cargo run -- run list
cargo run -- run list --kind triage
cargo run -- run list --kind patch
cargo run -- run list --status running
cargo run -- run list --case-id case_000001
cargo run -- run show run_000001Run the daemon once or continuously. Each cycle polls Telegram approvals, queues eligible triage/patch jobs, executes the next run per tool, and then flushes pending Telegram notifications:
cargo run -- daemon run --once
cargo run -- daemon run- config:
~/.codex/tool-feedback/config.json - bot token:
~/.codex/tool-feedback/telegram-bot-token - state db:
~/.codex/tool-feedback/state.db - owner registry:
~/.codex/tool-feedback/tool-owners.toml - run artifacts:
~/.codex/tool-feedback/runs/<tool>-<case_id>-<run_kind>-<timestamp>/
Secret and config files are written with user-only permissions on macOS and Linux.
Build a release binary first if you want launchd to run the optimized executable:
cargo build --release
./target/release/tool-feedback installRender a launchd plist without installing it:
tool-feedback launchd render \
--label com.tool-feedback \
--repo /path/to/tool-feedback \
--bin "$(command -v tool-feedback)" \
--output ~/Library/LaunchAgents/com.tool-feedback.plistInstall and bootstrap the LaunchAgent directly:
tool-feedback launchd install \
--label com.tool-feedback \
--repo /path/to/tool-feedback \
--bin "$(command -v tool-feedback)"Use --no-bootstrap if you only want the plist written under ~/Library/LaunchAgents/.
The daemon still needs an explicit developer PATH in launchd so background codex exec workers can find Node, Bun, and Cargo tools. tool-feedback launchd render and tool-feedback launchd install fill that in automatically unless you override --path.