Skip to content

Gaps vs. Claude Code / Codex / Gemini CLI (second pass) #26

Closed

Description

@blockmandev

A fresh comparison against the big agent CLIs, after #12–#17 landed. Items already tracked elsewhere are linked; everything here was missing or only partly there when this was written. Each item says where to start.

Missing

1. OpenTelemetry (metrics + traces)

All three big CLIs can export usage to OTLP.

  • Have: tokens and cost per model per session (src/runtime/usage.rs, AgentSession::usage_by_model, /cost); a trace writer (src/trace.rs).
  • Build: opt-in OTEL_EXPORTER_OTLP_ENDPOINT (plus _HEADERS and _PROTOCOL http/protobuf, or json to avoid a gRPC stack), and INCODE_TELEMETRY=1 or telemetry in admin.json.
    • Metrics: tokens by type and model, cost, tool calls by tool and outcome (allowed, denied, asked), turn duration, session count.
    • Events: tool decision, permission prompt, compaction.
    • Off by default; never send prompt or code contents unless OTEL_LOG_USER_PROMPTS=1.
  • Crate choice: opentelemetry + opentelemetry-otlp (http feature) is a new dependency, so decide deliberately. Alternatively, POST OTLP/JSON by hand with the existing reqwest.
  • Test: a fake OTLP collector on loopback (the same pattern as the MCP HTTP fakes).

2. Shell completions

  • Build: incode completions bash|zsh|fish|powershell.
  • Note: the parser is hand-written (src/main.rs parse_args), so there's no clap to generate completions from. Generate them from a static table of flags and subcommands kept next to USAGE, with a test that every flag in USAGE is in the table. Also complete incode mcp|plugin|review|update subcommands, and custom slash command names inside the REPL (already done).

3. Package managers

4. Corporate proxy and custom CA

  • Check: every outbound path honours HTTPS_PROXY, HTTP_PROXY and NO_PROXY: model APIs (src/agent/api.rs), web fetch/search (src/web.rs), MCP HTTP (src/toolbox/mcp_http.rs), OAuth (src/mcp_oauth.rs), incode update and the memory service. Some clients are built with no_redirect_client(); confirm the proxy still applies there.
  • Add: a custom CA bundle, INCODE_CA_CERTS / SSL_CERT_FILE, added to every reqwest client builder.
  • Document both in the README.
  • Test: a loopback CONNECT proxy (crates/sandbox/src/proxy.rs has one to reuse).

5. Hook events

Claude Code has SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Notification, Stop, SubagentStop, PreCompact and SessionEnd.

  • Check: which of these incode's hooks have (src/hooks/, src/runtime/lifecycle.rs), and add the missing ones.
  • Known: on_compact is not fired when the API route compacts (src/agent/compact.rs; noted in src/wiring.rs). UserPromptSubmit, which can block or rewrite a prompt, and Notification, wired to src/cli/notify.rs, are the most useful.

6. /bug / feedback

  • Build: a command that gathers the version, OS, the last turn's trace (with secrets scrubbed) and settings (keys redacted), and opens a prefilled GitHub issue URL. It must not upload anything itself.
  • Add .github/ISSUE_TEMPLATE/bug.yml to match.

7. Output styles

  • Build: named system-prompt add-ons (e.g. "explanatory", "concise", "learning") in ~/.incode/styles/*.md and .incode/styles/, chosen with /style <name> or output_style in admin.json.
  • Reuse: the custom command loader (src/custom_commands.rs) for discovery.

8. Other editors over ACP

9. Code intelligence through a language server (optional)

  • Current approach: incode deliberately uses tree-sitter outlines and the project's own toolchain diagnostics instead of LSP (src/knowledge.rs, src/tools/diagnostics.rs).
  • Some CLIs (OpenCode, Claude Code plugins) start real language servers for go-to-definition and references, plus diagnostics after each edit.
  • Option: an opt-in lsp entry per language (command + args) that, when present, serves Outline, definition and diagnostics from the server. Weigh it against the current design before building.

Already tracked

#18 release and update · #19 codex default · #20 VS Code · #21 SDKs · #22 by-hand checks · #23 cloud runs · #24 Windows network deny · index: #25.

Already at parity (for reference)

  • Sessions: headless -t with JSON; resume (/resume); rewind (/rewind) and undo; plan and read-only modes; image input; context compaction; /cost.
  • Extending: custom slash commands with allowed-tools and @file; plugins; hooks; sub-agents (/agents); .mcp.json with approval and OAuth; per-command permission rules; managed settings.
  • Execution: OS sandbox (built-in and sbx) on Linux, macOS and Windows; git worktree lanes; background jobs; web fetch and search.
  • Terminal: notifications; status line; vim mode; keybindings.
  • Integrations: incode review; GitHub Action; VS Code extension; SDKs; auto-update.

Generated by Claude Code

Activity

  1. added a commit that references this issue on Oct 22, 2026
  2. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 2 (shell completions) is done in #29: incode completions <bash|zsh|fish|powershell>, generated from a table beside USAGE that tests hold to the help text and the parser. The scripts are driven in the real shells in CI (Linux: bash, fish, zsh, PowerShell; macOS: bash, zsh, PowerShell; Windows: bash, PowerShell), and a missing shell there fails rather than skips.

  3. added a commit that references this issue on Oct 22, 2026
  4. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 6 (/bug) is done in #30: /bug [what happened] (also /feedback) prints a report and a link to a prefilled issue on the new bug form. It sends and opens nothing; typed text is redacted and the home folder becomes ~; the link is bounded by its encoded size.

  5. added a commit that references this issue on Oct 22, 2026
  6. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 7 (output styles) is done in #31: Markdown files in ~/.incode/styles/ (yours, wins a clash) and .incode/styles/ (the project's), chosen by INCODE_OUTPUT_STYLE or output_style in admin.json, switched with /style in the REPL, on every route and -t. Symlinks are refused and the prompt names which folder a style's text came from. Not offered over --acp (its OFFERED list does not include /style).

  7. added a commit that references this issue on Oct 22, 2026
  8. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 5, first event, is done in #32: user_prompt_submit in admin.json hooks runs before a line you send is passed on (REPL, --acp, -t). Exit 2 refuses it (nothing is sent, not even to the memory engine); stdout becomes that turn's context; the line is never changed. Not taken from a project's plugins. Still to come: Stop, Notification, PreCompact, session start/end, and /review / /run coverage.

  9. added a commit that references this issue on Oct 22, 2026
  10. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 5, second slice, is done in #34: pre_compact (before /compact) and stop (when one of your turns ends) in admin.json hooks. Neither can refuse; their output is shown. A project's plugin now gives only pre_tool_use/post_tool_use, by allowlist (and only once approved, #33). Still to come: Notification, session start/end, /review and /run prompt-hook coverage, and PreCompact for automatic compaction.

  11. added a commit that references this issue on Oct 22, 2026
  12. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 5, third event, is done in #35: notification in admin.json hooks runs whenever incode would notify you (turn_done / input_needed), in the background beside notify_command. Still to come: session start/end, /review and /run prompt-hook coverage, PreCompact for automatic compaction.

  13. added a commit that references this issue on Oct 22, 2026
  14. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    SessionStart / SessionEnd: done in #36 (merged 5a89a3e).

    session_start and session_end are now operator hooks (admin.json hooks, and the operator's own plugins). Project plugins still give only the tool events.

    • When they fire: in the REPL, --acp and -t.
    • Event fields: source is startup. reason is prompt_input_exit in the REPL and other elsewhere.
    • No refusing: neither hook can refuse, so exit 2 is an ordinary exit.
    • Output: stdout is shown. For -t it goes to stderr. For --acp, the end is traced, since the client has gone by then.
    • Paired ends: the end fires beside the memory engine's own end, so the two stay paired. A -t instruction refused by user_prompt_submit still runs session_end.
    • .incode/lifecycle.json: marked superseded, and it still runs.

    Not covered: /run ledger workers. They are sessions with no person behind them and already skip user_prompt_submit.

    Remaining for this issue:

  15. added 2 commits that reference this issue on Oct 22, 2026
  16. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 5, the rest: done in #37 (merged 2c412ee).

    • user_prompt_submit now covers /review and /run.
      • /review: the hook sees the review prompt, diff included.
      • /run: the hook sees each task's instruction before a worker or lane gets it. This happens in run_memory::Remembered, which every worker goes through.
      • A refusal sends nothing. The hook's output rides that turn.
    • pre_compact also runs before the API route compacts on its own (trigger: "auto"). What it prints arrives as a new AgentEvent::Notice, which the REPL, --acp and -t all show. A CLI agent's own automatic compaction happens inside that agent, so it fires nothing.

    Item 4: done in #41.

    • Proxy. All outbound requests already followed HTTPS_PROXY/HTTP_PROXY/ALL_PROXY/NO_PROXY and the Windows/macOS proxy settings, through reqwest's system proxy. What was wrong: loopback went through the proxy too unless NO_PROXY listed it. A request to this machine (the memory engine, a local model or MCP server) now never uses a proxy. Such a client follows a redirect only while it stays on this machine.
    • Custom CA. INCODE_CA_CERTS, or SSL_CERT_FILE, names a PEM bundle that is trusted beside the system store. A bad file is reported and nothing is added.
    • Tests.
      • A child-process test with a loopback proxy.
      • An end-to-end TLS test against a CA made at test time, passing on Linux, macOS and Windows.
    • Web fetch. Through a proxy, web fetch's IP pin can't hold, because the proxy resolves the name itself. That was already the case and is now documented.
    • README: a new "Proxies and certificates" section.

    Still open from this issue:

  17. added a commit that references this issue on Oct 22, 2026
  18. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 5 finished: SubagentStop is done in #45 (merged). subagent_stop in admin.json hooks runs when a sub-agent (the Agent tool) finishes. It is told agent_type, task, last_assistant_message and outcome. It can't keep the agent working, its output is traced, and a project's plugin can't add one. incode now has every hook event Claude Code has.

    Also merged since the last update:

  19. added a commit that references this issue on Oct 22, 2026
  20. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 1, OpenTelemetry: done in #46 (merged).

    • Off by default. Turn it on with INCODE_TELEMETRY=1 or "telemetry": true in admin.json, plus an OTEL_EXPORTER_OTLP_ENDPOINT.
    • How it's sent. OTLP over HTTP as JSON, built by hand over the existing reqwest, so no new crates. It goes only to https or this machine. Another protocol, a non-https collector or malformed headers are reported, and nothing is sent.
    • Metrics, as delta sums: sessions, tokens by type and model, cost, tool calls by outcome (allowed when the tool ran, denied when a gate refused it), turns and their duration.
    • Events: permission prompts, compactions, and prompt length. Prompt text is sent only with OTEL_LOG_USER_PROMPTS=1.
    • When: after every turn, and at the end of -t.

    Still open here: item 3 (needs #18), item 8 (needs testing inside Zed and JetBrains), and item 9 (optional).

  21. blockmandev commented on Oct 22, 2026

    @blockmandev
    MemberAuthor

    Item 8 (other editors over ACP): notes written in #53, not yet tried in the editors.

    • Zed: the agent_servers custom-agent entry.
    • JetBrains AI Assistant: ~/.jetbrains/acp.json.

    Both are taken from each editor's current docs. incode --acp, spawned the way both editors do it, answers an editor's initialize and session/new.

    What's left: trying them in real Zed and a real JetBrains IDE. Neither is installed on the machine that wrote this.

    Item 3 (Homebrew/winget/Scoop) waits for the first release, #18. Item 9 (LSP) is optional and needs a decision first.

  22. added a commit that references this issue on Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions