Documentation
¶
Overview ¶
acp_support.go *
Slash-command surface for the ACP server: the allowlisted subset of the
REPL's commands that works headless (no TUI, no stdin prompt), announced
to ACP clients via available_commands_update and executed through the
regular CommandHandler with stdout captured (scheduler_bridge pattern).
agent_board_sync — deterministic turn-boundary reconciliation between the
squad board and the run registry. *
The orchestrator is instructed to move cards as work progresses, but an
LLM under a long ReAct loop reliably forgets: cards sit in "doing" long
after their linked runs finished. This helper detects exactly that state
mechanically and injects a compact [BOARD SYNC] block at the turn
boundary, so the model is reminded with REAL card IDs (never guessed)
in the same turn it can act on them.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
agent_context_block.go *
Injects the session's `/context attach` entries into the agent/coder system
prompt — the agent-mode counterpart of the chat pipeline's Part 1
(attachedContextParts). Historically these attachments were chat-only,
which broke the "same experience" promise for /agent, /coder and every
headless surface built on the loop (gateway, MCP server): a context the
user attached in chat silently vanished the moment a task ran.
ChatCLI - Early-exit heuristics for the ReAct loop.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
agent_events_bridge.go *
Bridges the ReAct loop (agent_mode.go) to a structured agentevents.Sink.
Protocol frontends (ACP today) install a sink for the duration of a run via
ChatCLI.agentEventSink; the loop keeps rendering its terminal UI as always
and ADDITIONALLY emits typed events from these helpers. Every helper is a
no-op when no sink is installed, so interactive/gateway/scheduler runs are
byte-identical.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Native tool_call result emission helpers
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
When the assistant message carries NATIVE tool_calls, every provider's
tool API (Anthropic, OpenAI-compatible: Moonshot, MiniMax, ZAI, ...)
requires one tool result per call, adjacent to the assistant message.
These helpers guarantee that shape at every spot where the ReAct loop
can end a turn without a complete result set: mid-batch errors
(fail-fast), @park suspension, context cancellation, stagnation stop,
and the agent_call dispatch path that supersedes the batch.
Park / resume integration for the interactive AgentMode loop. *
This file owns three concerns kept separate from agent_mode.go's huge
Run() body: *
1. handleAgentPark — called from the tool-dispatch loop when a tool
returns the park sentinel. It snapshots the loop state, schedules
the appropriate resume job, prints the park banner, and returns
a sentinel to bubble cleanly out of Run(). *
2. RunResumed — public re-entry point used when the scheduler fires
AgentResume. Restores the snapshot's history and synthesizes the
tool result the @park call would have produced, then drives
processAIResponseAndAct from the same loop position. *
3. enqueueParkResumeJob / enqueueParkPollJob — small wrappers that
build the right scheduler.Job for each ParkRequest mode and
submit it via the scheduler adapter.
Slash command handlers for the park subsystem: *
/parked list all snapshots on disk + their scheduler jobs
/resume <token> force-resume a parked agent immediately
/cancel-park <tok> cancel a parked agent (delete snapshot + job) *
Plus the auto-resume hook drainPendingResumes that the outer Run()
loop in cli.go calls between user prompts.
ChatCLI - Mid-park user directives
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
While an agent is parked the REPL stays in normal chat mode — plain
text keeps its default behavior. Directing the parked agent is an
explicit action: /park-note <msg> persists the text into the park
snapshot as a pending directive, and RunResumed injects it into the
agent's context right after the park result at wake-up. A one-time
hint per park surfaces the command when the user chats while a park
is waiting, covering the "I typed and the agent never saw it" gap
without changing what plain input does.
ChatCLI - In-turn park wait for unattended surfaces.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
On the REPL, a parked agent ends its run and the outer prompt loop later
drains pendingResumeQueue to re-enter the loop. ACP (IDE), the MCP server
and the gateway have no such loop: a park taken there used to end the turn
with nothing ever consuming the resume — the monitor kept firing forever,
invisible, and the client showed an eternally pending turn. *
This file keeps the park IN-TURN on those surfaces: handleAgentPark
registers a waiter channel before enqueueing the scheduler job, Run()
blocks in runParkedInline instead of returning, the bridge delivers the
wake straight to the waiter, and the resumed loop continues on the same
request with the same event sink. Cancelling the turn (IDE Stop /
session/cancel) cancels the scheduler job and deletes the snapshot so
nothing leaks.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Phase 2 (#2) — Plan-and-Solve / ReWOO trigger for /agent and /coder. *
Lives outside agent_mode.go (already 3800+ lines) so the wiring is
easy to audit. The trigger is invoked from AgentMode.Run after the
user's query is appended to history but before the ReAct loop
starts. When it fires, it adds two synthetic messages to history:
1. an assistant message containing the structured plan (so the
orchestrator sees what was attempted), and
2. a system message containing the deterministic execution
report so the orchestrator can finalize with the gathered
outputs.
ChatCLI - Smart chat↔agent routing heuristics.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
agent_side_commands — lets the user drive the observation commands
(/agents, /board, /mail, /jobs) WHILE the agent/coder loop runs, instead
of the terminal being fully owned by the run until it finishes. *
The centralized stdin reader classifies these lines at the producer: they
never enter the stdinLines channel, so a security prompt cannot read
"/board" as an answer and the type-ahead drain cannot hand them to the
LLM as instructions. When a live display (turn spinner or the multi-agent
dispatch panel) is active, the command executes immediately — the display
pauses, the command output prints, the display resumes. Otherwise (the
terminal is owned by a security prompt, or the loop is between displays)
the command queues and runs at the next turn boundary, right before the
type-ahead drain. *
The allowlist is deliberately small and MUST NOT include mode-switch
commands (/agent, /coder, /run, /plan, /exit): those unwind the REPL via
panic sentinels and would tear the running loop down from a goroutine
that cannot recover them.
ChatCLI - Structured system prompt assembly for agent/coder modes.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
agent_typeahead — live preview of the line being typed while the agent
loop owns the terminal. *
With the TTY in cbreak mode (see stdin_cbreak_unix.go) the centralized
reader receives bytes as they are typed; the residual partial line is
published here and the spinner / dispatch panel renders it as a `❯ …▌`
input line, so the user finally SEES what they are typing mid-run
instead of the kernel echo being eaten by the repaint.
/agents — human view over the live agent run registry. *
Shows which agent executions are alive right now (orchestrator, workers,
subagents, MoA members, scheduler headless runs) as a parent/child tree
with per-run turn/action progress, plus the recent finished history.
Mirrors what the @agents tool exposes to the LLM, rendered for people.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
/board — human view over the squad work board. *
Renders the same kanban the orchestrator LLM manages via @board:
cards grouped by column with assignee, linked runs and note counts.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - /channel command handler
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Subcommands: *
list default — show recent messages + unread count
<channel-name> filter list to that channel
inject splice last 10 messages into the next turn
as a system message (legacy behavior preserved)
ack clear unread + pending notify banner
clear [--all] drain the inbox: empty the ring + ack all state;
--all also truncates the on-disk audit trail
pause / resume toggle the trigger engine
rules show active rule set; `rules reload` re-reads
~/.chatcli/mcp/triggers.json
confirm <id> [no] accept (or deny) a pending confirm action
run <seq> manually fire the agent on a specific message
ChatCLI - MCP channel trigger plumbing
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Glue between cli.mcp.ChannelManager + cli.mcp.triggers.Engine and
the user-facing CLI loop. Three responsibilities: *
1. Boot the trigger engine, load rules from
~/.chatcli/mcp/triggers.json, and wire OnMessage into it.
2. Consume engine.Actions(), separating them by Mode:
- notify → push onto pendingNotify ring, emit one-line
toast on stderr.
- confirm → push onto pendingConfirm map, emit toast with
/channel confirm <id> hint.
- auto → push onto pendingAuto queue; drained at the
top of the next executor tick by
drainPendingAutoTriggers (analogous to
drainPendingResumes for parked agents).
3. Render the inbox banner at the top of each executor cycle. *
The /channel command file (channel_command.go) reads from the
pending stores to implement list/ack/pause/resume/rules/confirm/run.
ChatCLI - @channels Tool Adapter
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Bridges the @channels builtin (cli/plugins/builtin_channels.go) to the
live MCP channel inbox and the trigger-banner state owned by ChatCLI.
Rendering is model-facing plain text: seq + server/channel + timestamp
per line, content clamped so a chatty server cannot flood the context.
ChatCLI - Chat-mode controlled exception for ask_user.
Copyright (c) 2024 Edilson Freitas. License: Apache-2.0. *
Chat mode is tool-less by design. Sanctioned exceptions only: ask_user
(interactive choice), read-only knowledge retrieval when a knowledge base
is attached (chat_knowledge.go), graphview rendering (chat_graphview.go)
and long-term memory/profile persistence (chat_memory.go). No exec/file/
search tools, ever.
Native providers use a buffered SendPromptWithTools turn; non-native ones
(Claude OAuth) use a buffered XML turn with the formats injected and the
markup suppressed. In both cases the turn is BUFFERED and the text RETURNED
— handleChatTurnResult renders it; printing here (after the alt-screen
overlay) is what made the answer vanish.
ChatCLI - Chat-mode controlled exception for @graphview.
Copyright (c) 2024 Edilson Freitas. License: Apache-2.0. *
Chat mode is tool-less by design; ask_user and read-only knowledge retrieval
are its sanctioned exceptions. Interactive graph rendering is the third: the
user explicitly asks "draw a graph of what we discussed", so for THAT turn
the model may call @graphview once. It only writes a self-contained HTML file
and opens a viewer — it never touches the workspace — so it is a benign,
user-requested visualization rather than an execution/file tool. Gated by
CHATCLI_CHAT_GRAPHVIEW (default ON), flippable at runtime via
/config chat graphview on|off.
ChatCLI - Chat-mode controlled exception for knowledge retrieval.
Copyright (c) 2024 Edilson Freitas. License: Apache-2.0. *
Chat mode is tool-less by design; ask_user is its one interactive
exception. Knowledge retrieval is the second sanctioned exception, and the
same reasoning applies: it executes nothing and touches nothing — it only
READS the knowledge bases the user explicitly attached. With it, "attach a
corpus and talk about it" works in plain chat: when the per-turn
auto-retrieved passages are not enough, the model may pull more (search /
get / toc) for a bounded number of rounds before answering, without the
user having to switch to /agent or /coder.
ChatCLI - Chat-mode controlled exception for long-term memory.
Copyright (c) 2024 Edilson Freitas. License: Apache-2.0. *
Chat mode is tool-less by design; ask_user, knowledge retrieval and
graphview are its sanctioned exceptions. Memory is the fourth, and the same
reasoning applies: it executes nothing and touches no files outside the
memory store the background extractor already writes to. Without it, chat
could only PROMISE profile updates ("vou considerar daqui pra frente") while
the throttled extractor decided later whether anything persisted — the
model looked like a liar and the profile rotted. With it, "atualiza meu
perfil" works in plain chat, deterministically, the moment the user asks.
ChatCLI - Chat-mode request pipeline helpers
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
processLLMRequest used to host the whole chat-mode pipeline inline, which
pushed its cyclomatic complexity well above the project's Quality Gate
budget. The helpers in this file extract each pipeline phase so the main
function can be read top-to-bottom as an orchestrator and so each phase
can be unit-tested independently. *
The split mirrors the conceptual phases the chat turn actually goes
through, in order: *
1. assembleChatSystemPrompt — build the structured system prompt
(workspace, contexts, manual + pinned + auto skills, MCP, K8s),
and the model/effort hints derived from the active skills.
2. buildChatTempHistory — splice the new system message into the
conversation history without mutating cli.history.
3. resolveActiveClient — honor any skill model hint, with a
user-visible notice when the swap is cross-provider.
4. applyChatEffortHint — attach the reasoning-effort hint to
ctx so the provider can opt into extended thinking.
5. executeLLMTurn — send the prompt (streaming if the client
supports it, buffered otherwise).
6. handleChatTurnResult — append history, record cost, render.
Package cli implements the interactive terminal UI, command handlers, and orchestration glue that binds every chatcli subsystem together (LLM clients, workspace, memory, agents, plugins, MCP, hooks, quality pipeline).
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Autocomplete providers for the five seven-pattern quality slashes:
/thinking — cross-provider reasoning override (#7)
/refine — Self-Refine session toggle (#5)
/verify — Chain-of-Verification session toggle (#6)
/plan — Plan-and-Solve / ReWOO trigger (#2)
/reflect — Reflexion manual lesson persistence (#3) *
All descriptions resolve via i18n so pt-BR and en speakers get the
explanation in their locale. Keys live under complete.{thinking,
refine,verify,plan,reflect}.* in i18n/locales/*.json.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - cli_session_autosave.go *
Auto-saves the live conversation when the interactive REPL exits, so a
session is never lost just because the user didn't run /session save.
Combined with ranked session search and @session get, this closes the
recall loop: every conversation becomes retrievable memory by default. *
Autosaves live under a reserved "autosave-" name prefix — they never touch
user-named sessions — and are pruned to a small keep-count so /session list
stays readable and disk stays bounded (the 90-day session TTL applies too).
Gated by CHATCLI_SESSION_AUTOSAVE (default on).
cli_session_binding.go *
Cross-surface session continuity for the interactive REPL. Once a named
session is active (loaded or saved via /session), every completed turn is
written through to the saved-session store, and every turn start checks the
store for writes made by another surface (MCP/ACP server, gateway daemon,
another terminal) since our last sync — reloading when the file is newer. *
Conflict model is last-writer-wins on the whole file: the store's atomic
write (temp+rename) guarantees no torn files, and the refresh-before-turn
keeps surfaces converging as long as they alternate. Two surfaces answering
the SAME turn simultaneously is the conversation hub's job, not this one's. *
Guards, in order:
- CHATCLI_SESSION_WRITETHROUGH=off disables both directions;
- no named session active (currentSessionName empty) → no-op;
- machine-prefixed names (autosave-, mcp-) are rolling mirrors owned by
the autosave paths, never live bindings;
- captured RPC runs (MCP/ACP/gateway/scheduler-bridge) are skipped: the
RPC backend owns per-session persistence there, and currentSessionName
holds a surface session id, not a saved-session name.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Slash command chat→coder auto-route (post-unwind consumer)
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
A command whose resolved mode is coder cannot run as a chat turn: chat is
tool-less by design and the model refuses, pointing the user at /coder.
maybeAutorouteCoderCommand (commands_integration.go) intercepts those
invocations at the REPL dispatch and unwinds out of go-prompt exactly like
a manual /coder; this file owns what happens AFTER the unwind — expand the
template, run the coder ReAct loop one-shot, and hand the prompt back to
chat when the loop reaches its final answer.
ChatCLI - Slash command integration (dispatch, expansion, security gate)
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Wires the cli/commands catalog into every user-input surface. Expansion is
pure prompt rewriting, so a command behaves identically on REPL chat,
coder follow-ups, one-shot -p, the messaging gateway, ACP and MCP —
whatever the provider. *
Security invariants (the reason this file owns the ExecRunner):
- Every "!" pre-execution line goes through the SAME machinery as coder
tool calls: IsSafetyImmune → PolicyManager.Check → interactive
approval (PromptSecurityCheckGuarded). The gate is never bypassed.
- Unattended surfaces (gateway/MCP/ACP/scheduler) have no human to
answer an "ask": policy automode may approve, otherwise DENY
fail-safe. Never auto-approve just because nobody is watching.
- allowed-tools from the frontmatter becomes an ephemeral overlay
consumed by the next agent/coder run: a tool outside the list
escalates allow→ask; it never silently widens permissions.
ChatCLI - Adapter binding the @compress / @recall tools to the live
compression layer.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements plugins.CompressionAdapter over the session's compress.Layer:
on-demand content-aware compression (@compress), byte-identical retrieval of
offloaded originals (@recall), and a session savings summary. Wired via
plugins.SetCompressionAdapter at startup.
ChatCLI - /config agent mutator.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Closes the gap where /config agent was read-only: switching the
timeline UI (full / compact / minimal) required restarting the
process with CHATCLI_CODER_UI exported. Now it flips at runtime
and the next /coder or /agent picks up the new style on the next
NewUIRenderer call (which reads agent.DefaultUIStyleFromEnv each
time the agent loop starts). *
/config agent # read-only dump (legacy)
/config agent ui # show current style + options
/config agent ui full # switch to bordered cards
/config agent ui compact # switch to inline ↻/✓ lines
/config agent ui minimal # switch to truncated cards *
Persistence: the switch lives in process env only. The mutator
prints a hint so users that want a permanent default know to add
`CHATCLI_CODER_UI=<value>` to their .env (or wherever CHATCLI_DOTENV
points). We deliberately do NOT rewrite the .env file ourselves —
that file is user-owned territory; transparently editing it would
destroy comments / ordering and surprise anyone who reads it next.
ChatCLI - /config chat mutator.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Exposes the chat-mode ask_user exception (CHATCLI_CHAT_ASK) on the
/config surface — not just read-only: it can be toggled at runtime. *
/config chat # status (read-only panorama)
/config chat ask # status
/config chat ask on # enable (chat may use ONLY ask_user)
/config chat ask off # disable (chat stays tool-less)
/config chat ask toggle # flip *
The toggle flips process env only (chatAskEnabled reads os.Getenv each
turn, so it takes effect immediately). A hint points users to .env for a
permanent default; we never rewrite .env ourselves (user-owned territory).
ChatCLI - /config commands section
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Diagnostics for the slash-command catalog, organized for scanning: a
one-line summary, commands grouped by source (native first, then each
interop family) with aligned columns, then the two failure ledgers
(refused shadows, parse-skipped files) and the scanned directories with
existence markers. The only mutation is "reload" (re-fingerprint).
ChatCLI - /config compression mutator.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Exposes the content-aware compression layer (CCR) on the /config surface,
read-only panorama plus runtime mode switching: *
/config compression # status (mode, thresholds, CCR store, savings)
/config compression off # disable compression
/config compression lossless # only lossless reductions (no row/line dropping)
/config compression lossy # lossy-with-CCR (full reduction, reversible via @recall)
/config compression stats # session savings summary *
The mode switch takes effect immediately on the live layer (atomic) and also
sets CHATCLI_COMPRESSION so any rebuilt layer (e.g. the gateway) inherits it.
A hint points to .env for a permanent default; we never rewrite .env.
ChatCLI - /config image mutator.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Exposes the @image backend on the /config surface — read-only panorama plus
runtime mutation. The imagegen factory reads os.Getenv on every call, so each
setter takes effect immediately; a hint points to .env for a permanent
default (we never rewrite .env — user territory). *
/config image # status
/config image provider <name> # sdwebui|url|openai|responses|google|xai|zai|minimax|bedrock|auto
/config image api images|responses # OpenAI: Images API vs Responses API
/config image model <id> # CHATCLI_IMAGE_MODEL
/config image url <url> # CHATCLI_IMAGE_URL (self-hosted/SD WebUI)
/config image models # list the image-model catalog
/config image reset # clear the overrides above *
Shorthand: `/model-image [<id>]` mirrors `/config image model` (and lists the
catalog when bare), the @image counterpart to `/model` for text models.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
/config memory renders the long-term memory configuration: the injection
mode that governs the push/pull tradeoff in agent/coder, plus live store
stats. Read-only, mirroring /config quality — set the mode via the
CHATCLI_MEMORY_MODE env var (full | index | off).
ChatCLI - /config output mutator.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Output-token reduction on the /config surface — read-only panorama plus
runtime mutation: *
/config output # status (verbosity + effort routing)
/config output full # no steering (model's natural verbosity)
/config output concise # drop ceremony/restatement (default)
/config output minimal # fewest correct tokens
/config output effort on|off # complexity->effort downgrade (opt-in) *
Both knobs are read live from the environment each turn, so changes take
effect immediately. A hint points to .env for a permanent default; we never
rewrite .env.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
/config quality renders the seven-pattern quality pipeline state. The
pipeline lives in cli/agent/quality and is wired into the dispatcher
by initMultiAgent. This file only reads the live snapshot — it does
not parse env vars on its own.
ChatCLI - /config scheduler section. *
Lives in its own file (mirrors config_quality.go) and is dispatched
by config_sections.go's routeConfigCommand. Shows operator-tunable
env vars side-by-side with live runtime state (queue depth, WAL
segments, daemon status).
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
/config subsections. *
Design: each showConfigX() is self-contained and reads directly from the
live CLI state (env vars, managers, handlers). None of them pre-compute or
cache — `/config` is called interactively and performance is irrelevant. *
i18n: every user-facing string goes through i18n.T(). Keys live in
i18n/locales/*.json under cfg.*, ws.cmd.*, complete.config.* namespaces. *
Routing layout:
/config → showConfigPanorama (short overview)
/config all → showConfigAll (every section back-to-back)
/config general → showConfigGeneral
/config providers → showConfigProviders
/config agent → showConfigAgent
/config resilience → showConfigResilience
/config session → showConfigSession
/config integrations → showConfigIntegrations
/config auth → showConfigAuth
/config security → showConfigSecurity
/config server → showConfigServer
ChatCLI - /config security mutator. *
Closes the gap where /config security was read-only: operators had
to edit ~/.chatcli/coder_policy.json by hand to add an Allow or
Deny rule outside the interactive /coder "Allow always" prompt.
Now the same PolicyManager.AddRule / DeleteRule pipeline that
backs the prompt is exposed declaratively: *
/config security # read-only dump (legacy)
/config security rules # live rule table
/config security allow "<pattern>" # AddRule ActionAllow
/config security deny "<pattern>" # AddRule ActionDeny
/config security forget "<pattern>" # DeleteRule
/config security reload # re-read the JSON from disk *
Rule edits persist to ~/.chatcli/coder_policy.json (via
PolicyManager.save). They take effect:
- immediately for new /coder turns (workerPolicyAdapter reloads
per Ask prompt);
- on the very next RunShell for the scheduler bridge (it
reloads from disk on every fire, see scheduler_bridge.go). *
Destructive mutations (deny / forget) prompt for confirmation
unless --yes is passed. allow also prompts when the pattern looks
broad (wildcard-only or fewer than 3 literal chars).
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
/config selfevolve renders the self-evolution engine state: the autonomy
mode plus live observability of what the engine owns (skills it authored) vs
the total skill set. Read-only — set the mode via CHATCLI_SELFEVOLVE_MODE.
Activation analytics for individual skills live in the @skill stats tool.
ChatCLI - /config ui (read-only section).
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
The read-only counterpart to config_ui_mutate.go: the section dump shown by
`/config ui` (with no subcommand) and folded into `/config all`. It reports
the active theme, the env var backing it, the detected terminal color
profile, and the list of available themes — so an operator can see what is
driving the UI's colors without reading source.
ChatCLI - /config ui mutator.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Runtime control of the color theme that skins every surface — chat,
coder and agent cards, borders, markdown and spinners: *
/config ui # show active theme + color profile
/config ui theme # same as above (explicit)
/config ui theme dark # switch to the dark theme
/config ui theme light # switch to the light theme *
Unlike the timeline UI style (which the renderer re-reads from the env on
each NewUIRenderer), the theme is process-global state held by the theme
package, so a switch applies on the very next render with no restart. *
Persistence mirrors /config agent ui: we set the process env and print a
hint to add CHATCLI_THEME=<name> to the .env for a permanent default. We
never rewrite the user's .env ourselves.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
/config update renders the auto-update state: resolved policy mode,
detected install channel, current vs. latest release (from the on-disk
cache — no network on render) and the env vars that steer the updater.
ChatCLI - Adapter binding the @context tool to the live context manager.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements plugins.ContextAdapter over the session: create / attach / detach
/ list / status / delete of context (knowledge) bases, so the agent can
build and wire its own documentation autonomously. Wired via
plugins.SetContextAdapter at startup, right after the context manager exists.
ChatCLI - Auto-RAG upgrade for /context attach
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
A plain `/context attach <name>` injects the whole context verbatim into
the system prompt every turn. For large contexts that is the single
biggest per-turn payload in chat mode — while the agent-side @context tool
(context_adapter.go) has attached with semantic retrieval by default since
PR #1058. This file closes the asymmetry for the manual command: large
contexts upgrade to --rag semantics automatically, announced to the user,
with --full as the per-call opt-out and CHATCLI_ATTACH_AUTO_RAG as the
global kill switch.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
Package cli implements the interactive terminal interface for ChatCLI, built on Bubble Tea (Charmbracelet) with a rich TUI experience.
Architecture ¶
The CLI operates in three primary modes:
- Interactive mode: Full TUI with streaming output, syntax highlighting via glamour, and context-aware input with @file, @git, @env, @command.
- Agent mode: ReAct engine (Reason + Act) with 12 specialized agents running in parallel — File, Coder, Shell, Git, Search, Planner, Reviewer, Tester, Refactor, Diagnostics, Formatter, Deps.
- One-shot mode: Non-interactive prompt via -p flag with pipe support.
Security ¶
- Command allowlist with 150+ pre-approved commands (strict/permissive modes)
- Sensitive read path blocking (SSH keys, cloud credentials, kubeconfig)
- Environment variable redaction before LLM submission
- Command output sanitization with prompt injection detection
- Ed25519 plugin signature verification
- Session encryption at rest (AES-256-GCM)
- History file sensitive content redaction
Key Components ¶
ChatCLI: Main struct managing the TUI lifecycle and LLM interaction
AgentMode: ReAct loop with multi-agent orchestration
SessionManager: Persistent session storage with encryption and TTL
HistoryManager: Command history with sensitive content redaction
EnvRedactor: Environment variable sanitization (60+ patterns)
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - export_command.go *
/export path writes the current conversation as a ShareGPT-style JSONL
trajectory (training-data format). Provider-agnostic: it serializes the
unified history regardless of which provider produced the turns. Defaults
to ~/.chatcli/exports/trajectory-<timestamp>.jsonl.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - gateway_command.go *
/gateway [start|stop|status] runs ChatCLI as a messaging daemon. To keep the
interactive REPL free, `start` re-execs the binary as a detached child
(`chatcli gateway`) — its own process, its own stdout — and tracks it via a
pidfile + log under ~/.chatcli/. The child runs RunGatewayForeground. *
In the daemon, each inbound message runs through the real agent loop fully
unattended (no stdin confirmations; full autonomy — the operator opted in).
Progress streams back as a short, filtered action feed and the run closes
with the model's clean prose answer. Access control is at the edge: Telegram
allow-list, Slack signing secret, webhook secret, plus the agent security
mode (CHATCLI_AGENT_SECURITY_MODE).
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Platform shim for the gateway daemon: Setsid detaches the child from the
terminal's process group; SIGTERM stops it; signal(0) probes liveness.
gateway_events_sink — structured progress for gateway turns. *
Instead of scraping the rendered stdout (ANSI stripping + line
heuristics), the gateway installs this agentevents.Sink for the run and
receives typed events at the points where semantics are known: reasoning
parsed, tool classified, result structured. Each event becomes one clean
chat-friendly progress line, batched by the runner's progressSink. *
The legacy stdout-scraping path remains behind
CHATCLI_GATEWAY_STRUCTURED_PROGRESS=false as a rollback switch.
gateway_runs_watcher — per-agent progress lines for gateway turns. *
The events sink covers the orchestrator's own tool calls, but dispatched
workers/subagents report progress only to the run registry (their tool
calls happen inside their own ReAct loops). This watcher polls the
registry during a gateway turn and emits a line whenever an agent's
state changes — the chat-platform equivalent of the terminal's live
dispatch panel.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - gateway_runtime_model.go *
The gateway daemon is a SEPARATE detached process (see gateway_command.go):
it snapshots provider/model at spawn time and never shared memory with the
interactive REPL. So `/switch --model …` (or `/model …`) in the REPL was
invisible to a running daemon, and starting the daemon after a switch still
booted the .env default — both surfaced as "the gateway ignores my current
model". *
The fix is a tiny shared runtime-state file (~/.chatcli/runtime_model.json)
that the interactive process WRITES whenever the live model changes (switch,
provider switch, and right before spawning the daemon) and the daemon READS
before each inbound message. The file is the single cross-process source of
truth for "the operator's current model"; absence means "no override — keep
the env-derived snapshot", so non-gateway use is entirely unaffected. *
Only the interactive process writes; the daemon is read-only here. That keeps
the daemon from clobbering the operator's choice with its own boot snapshot.
gateway_session_binding.go *
Cross-surface session continuity for the gateway daemon: a hub principal
can be bound to a named saved session, making the durable store — not just
the ephemeral hub — the conversation's home. While bound: *
- the turn's preamble comes from the named session file (which carries
REPL/MCP/ACP turns written through by those surfaces), replacing the
hub-backlog preamble so the two threads are never interleaved;
- every completed turn is appended to the named session file
(load+append+save; the store's atomic write keeps it consistent);
- the hub keeps receiving events as before, so channel fan-out and the
co-running CLI's hub pull are unchanged. *
Bindings persist as hub runtime settings ("gateway_session:<principal>"),
the same live-read mechanism as CHATCLI_HUB_ISOLATE — a restart keeps them,
and a co-running CLI could inspect them via /config hub. *
Channel users control the binding with /session commands in the chat
(attach/detach/status/save/list/new). delete is deliberately NOT exposed to
channels: a gateway conversation may be multi-user, and destroying store
state stays an operator/REPL decision.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
graph_command.go — the /graph visualization: renders the in-core knowledge
graph to an image (the Obsidian "graph view"). It reuses the embedded
go-graphviz engine behind @diagram, so no new rendering dependency is added. *
/graph the whole graph (capped to the top hubs when large)
/graph <subject> the local graph around the node matching <subject>
ChatCLI - Adapter feeding the @graphview tool from live CLI state.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements plugins.GraphSourceProvider so @graphview's "knowledge" and
"conversation" sources render real data:
- KnowledgeGraph: the in-core knowledge graph (the same substrate /graph
draws statically), converted to the renderable node/edge shape.
- ConversationGraph: a graph of the whole session — the turn thread and the
tools it invoked, PLUS everything attached with /context (context bases
with their files, knowledge corpora) — all hanging off a session root. *
Wired via plugins.SetGraphSourceProvider at startup. The "json" source needs
no provider, so @graphview works even before this is bound.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - HyDE wiring (Phase 3 of seven-pattern rollout). *
Builds the per-call HyDE augmenter (3a) and ensures the vector
index (3b) is attached to the memory store. Both are no-ops when
the user hasn't enabled HyDE in /config quality, so the steady
state for non-HyDE users is one extra branch and zero allocation.
ChatCLI - Adapter binding the @knowledge tool to the live context manager.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements plugins.KnowledgeAdapter over the session's attached
knowledge-mode contexts: hybrid passage search (keyless BM25 floor +
embeddings when configured), paged document reads and TOC walks. Wired via
plugins.SetKnowledgeAdapter at startup. Also builds the knowledge block the
agent system prompt injects so the model knows the bases exist.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
knowledge_graph.go — derives the in-core knowledge graph from the existing
memory, skill, session and context stores, and implements the @graph tool's
adapter. *
The graph is a DERIVED index: nodes and edges are computed from data
already on disk. Edges come from the relationships those stores ALREADY
record — topic↔fact links, a fact's source project, an episode's project
and date, shared tags, a skill's triggers — plus [[wikilinks]] parsed from
note text. *
With CHATCLI_MEMORY_GRAPH on (default), the derivation is served through
the persisted cache in cli/workspace/memory/graph_cache.go: consumers call
cli.knowledgeGraph() and get an immutable snapshot that only rebuilds when
a source store changed (dirty taps + fingerprint TTL), with graph.json
carrying it across boots. Off, every call derives from scratch — the
legacy behavior, byte-identical.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - lsp_command.go *
/lsp <file> runs the matching language server (gopls, pyright, ...) against
a file and prints its diagnostics — giving the user (and, via the agent,
the model) real compiler/linter feedback without a full build.
ChatCLI - Adapter binding the @lsp tool to the session language-server pool.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements plugins.LSPAdapter over cli/agent/lsp: a lazily created,
session-scoped Pool keeps one initialized server per (project root,
language), and every subcommand formats its answer as bounded,
model-facing text with workspace-relative paths and 1-based positions.
Wired via plugins.SetLSPAdapter at startup; the pool is shut down with
the session.
/mail — human surface over the squad message bus. *
Lets the user audit recent agent↔agent traffic, see pending inboxes and
inject a directive into any agent's inbox (delivered at the recipient's
next ReAct turn — e.g. "/mail send coder prioritize the login fix").
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
mail_hub_bridge — persists the squad message bus through the Conversation
Hub's SQLite store, making mail durable across restarts and shared across
processes (REPL and gateway daemon poll the same hub.db, WAL mode). *
Wire format: one hub event per message on a DEDICATED conversation ID
("squad-mail") so squad traffic never leaks into the user-facing
conversation preamble or LLM history. Role "squad_mail" carries a JSON
payload; role "squad_mail_ack" records delivery (the drain) so other
processes — and this one after a restart — do not redeliver consumed
messages. ClientMsgID = the bus message ID gives idempotent appends. *
Delivery semantics are at-least-once ACROSS processes (two processes that
poll between a drain and its ack may both deliver) and exactly-once
WITHIN a process (Registry.Deliver dedups by globally unique ID). Squad
mail is directive text for LLM agents, so duplicate delivery is benign.
ChatCLI - MCP Dynamic Tool Notice
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Renders the mid-loop notice the agent injects when a server's dynamic
tool list changed (notifications/tools/list_changed → registry refresh
in cli/mcp/dynamic_tools.go). Without this the model keeps reasoning
against the catalog it saw in the system prompt and never discovers the
tools that appeared after a bootstrap call (e.g. HTTP Toolkit's start).
ChatCLI - Adapter binding the @mcp-login tool to the live MCP manager.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements plugins.MCPAuthAdapter over cli.mcpManager: login runs the OAuth
authorization-code flow and reconnects the server; status and logout report
and forget per-server credentials. Wired via plugins.SetMCPAuthAdapter at
startup.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - memory_adapter.go *
Implements plugins.MemoryAdapter so the @memory builtin tool can route
ReAct calls into the live memory store. Supplied to
plugins.SetMemoryAdapter when the memory store is initialized. *
Writes go through the deterministic store methods (RememberFact /
UpdateProfile / ForgetFacts) — no LLM, no throttling — and invalidate the
context builder cache so the next prompt reflects the change.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - memory_autorecall.go *
Proactive recall for the "index" memory mode. The pull model keeps per-turn
cost bounded, but it relies on the model CHOOSING to call @memory recall —
and models routinely skip the call, answering with a 600-char digest while
the relevant gotcha sits unread in the fact index. Auto-recall closes that
gap: each chat/agent/coder turn running in index mode, the hints already
extracted from recent messages rank the fact index, and the top few matches
(tiny, budget-capped) ride into the prompt alongside the digest. *
Cache discipline: the block is hint-driven, so it changes turn to turn. It
is therefore injected into the UNCACHED trailing block (with the wall-clock
dynamic context), never into the stable workspace block — a volatile line
placed early would poison every cached block after it (see the chat
pipeline's stable-prefix/volatile-suffix contract). *
Gated by CHATCLI_MEMORY_AUTORECALL (default on; only meaningful in "index"
mode — "full" already injects the whole retrieval, "off" injects nothing).
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - memory_bootstrap.go *
The persistent-memory bootstrap card: a short, stable block that tells the
model — in every surface's system prompt — that durable cross-session
memory EXISTS on this machine and how to navigate it. *
Why it exists: the memory layers (facts, episodes, saved sessions, board)
and their pull tools were all in place, yet a fresh session still opened
with the model claiming "each session starts fresh — I have no memory of
past interactions". Nothing in the system prompt ever said otherwise: the
Memory Index digest lists facts/topics/projects but never mentions saved
conversations, and the only anti-amnesia directive in the repo
(GatewayMemoryDirective) was gated to the messaging gateway. The model's
training prior ("assistants have no memory") wins by default — this card
is the explicit counter-evidence, with live counts so it reads as data,
not aspiration. *
Cache discipline: the card is computed ONCE per process (session-start
snapshot) and then reused verbatim, so it can live in the CACHED stable
prefix of the chat and agent/coder system prompts. Counts drifting
mid-session (the memory worker adds facts continuously) must NOT re-render
the card — that would invalidate the prompt-cache prefix every few turns. *
All strings are English model-facing constants, the same rationale as
memoryRecallHint and the recall block headers.
ChatCLI - Memory injection mode (push vs pull).
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Controls how long-term memory reaches the model in every mode: *
full — inject the full hint-driven retrieval every turn (the push
model; cost grows with memory size and is paid each turn).
index — inject only a small, stable digest of what memory knows and
let the model pull detail on demand via the memory recall
tool (the pull model; per-turn cost is bounded regardless of
how large memory grows). Default.
off — inject no memory (bootstrap files still apply). *
Agent/coder honor the mode verbatim (@memory tool). Chat honors "index"
through the sanctioned memory tool exception (chat_memory.go); when that
exception is disabled (CHATCLI_CHAT_MEMORY=off) chat has no pull path and
"index" degrades to "full" — see ChatCLI.chatEffectiveMemoryMode.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - memory_notice.go *
Surfaces background memory activity to the user. The memory worker runs
on its own goroutine and must not write to stdout directly (it would
corrupt go-prompt's line redraw). Instead it queues a one-line notice
here; the main loop drains and prints it at the next executor tick.
ChatCLI - Memory extraction resilience: provider fallback + on-disk pending queue.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Memory extraction is how conversations become durable knowledge. Until now a
failing extraction LLM (provider outage, timeout) meant the segment was only
retried in-process — and lost for good on exit — while the user noticed
nothing for days. This file closes both gaps: extraction walks a fallback
provider chain before giving up, and a segment that still fails is persisted
to ~/.chatcli/memory/pending as a write-ahead queue, drained on later runs —
surviving restarts. Repeated failures surface a one-line notice so silent
memory loss cannot happen again.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - moa_adapter.go *
Implements plugins.MoaAdapter: runs a Mixture-of-Agents query through the
live LLM manager. Each member model answers the same prompt in parallel;
an aggregator model then synthesizes one best answer from all candidates.
Supplied to plugins.SetMoaAdapter at startup.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - moa_command.go *
/moa <prompt> runs Mixture-of-Agents: fan the prompt out to several
reference models in parallel and synthesize their answers with an
aggregator model. Provider-agnostic — any configured provider can be a
reference or the aggregator. *
Every participant is briefed like a regular chat turn (structured system
prompt: attached contexts, workspace memory, skills, retrieval) and holds
the chat-sanctioned read-only tool exceptions (knowledge retrieval, CCR
recall) — see moa_turn.go. *
CHATCLI_MOA_MODELS="openai:gpt-5,claudeai:claude-opus-4-8,googleai:gemini-2.5-pro"
CHATCLI_MOA_AGGREGATOR="claudeai:claude-opus-4-8" (defaults to current model)
ChatCLI - Tool-aware turn executor for Mixture-of-Agents.
Copyright (c) 2024 Edilson Freitas. License: Apache-2.0. *
A MoA run is a panel of experts, and each expert should be as capable as a
regular conversation turn: able to pull from the attached knowledge bases,
to expand "<<ccr:KEY>>" compression markers back into their originals, and
to recall the user's long-term memory (profile, durable facts, notes).
This file builds the moa.Turn executor that grants exactly those three
sanctioned READ-ONLY exceptions to every participant — proposers and
aggregator alike. Memory access is recall-only by construction: the
executor pins the @memory subcommand to "recall", so the mutating forms
(remember, profile, forget) are unreachable from a panel turn. *
Deliberately excluded: ask_user (participants run concurrently and
unattended — N models racing to open interactive overlays is not a panel,
it's a mob) and graphview (a side-effecting artifact writer). No exec, file
or search tools, ever — the same rule chat mode enforces. *
Participants run in parallel goroutines, so everything here is UI-free
(no spinner/prompt coupling) and never mutates ChatCLI state; the only
shared sinks are the mutex-protected cost tracker and the read-only
knowledge/CCR stores.
ChatCLI - Mode transition cleanup.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Single source of truth for the rule "exactly one ACTIVE MODE marker
may exist in the system slot at any time". When the user moves
between /chat, /agent, and /coder mid-session, the per-mode entry
points used to leave their own system prompt behind in cli.history.
Without cleanup, the next mode's prompt assembler would ship BOTH
prompts to the LLM (the current one in slot 0 and the stale one as
a mid-history system message), and the model would receive
contradictory format rules — "don't emit tool_call" alongside "you
MUST emit tool_call". This file owns the filtering that prevents
that drift.
ChatCLI - @model tool adapter
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements plugins.ModelRoutingAdapter over the live session: lists the
configured providers/models enriched with routing metadata (pricing tier,
cost per 1M tokens, context window, capabilities), applies/clears the
agent-loop route override the AI picks via "@model use", and runs
"@model delegate" one-shots on another model without touching the main
loop's history or prompt cache. *
Resolution reuses the same pipeline as skill `model:` frontmatter
(client.ResolveModelRouting), so qualified "PROVIDER:model" handles are
deterministic and bare names fall back to catalog/family heuristics.
Supplied to plugins.SetModelRoutingAdapter at startup.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Output-token reduction wiring: verbosity steering (the universal, cache-safe
lever) plus a conservative, opt-in complexity→effort downgrade. The policy
logic is keyless and lives in cli/outputpolicy; this file only reads config
and bridges to the cli/agent/chat seams.
park_completer.go — go-prompt suggestions for /parked, /resume, and
/cancel-park. Mirrors the pattern in scheduler_completer.go: a flat
suggestion table for subcommands, plus dynamic token completion that
reads the on-disk snapshot directory.
ChatCLI - Payload Recovery Helpers
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Small helpers for the agent-mode payload/WAF rejection recovery path in
agent_mode.go. Kept in their own file so the dedup contract is unit-
testable without dragging the full agent loop into tests.
ChatCLI - Persona Command Handler
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
/plan — force Plan-First (Plan-and-Solve / ReWOO) for the next agent run. *
Shapes:
/plan → arms the one-shot flag; user then runs /agent <task>
or /coder <task> to consume it
/plan <task...> → arm + run /agent <task> (default, matches doc)
/plan agent <task...> → explicit agent mode
/plan coder <task...> → arm + run /coder <task> (coder with plan-first)
/plan preview <task...> → dry-run: generate and display the plan only
/plan dry <task...> → alias of preview *
The actual planning + execution happens inside AgentMode.Run via
runPlanFirstIfApplicable; this command only flips the trigger and
picks the consuming mode.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
policy_command.go *
/policy — session-scoped security-policy mode. In automode every coder
policy "ask" verdict auto-approves, so the agent runs uninterrupted;
explicit deny rules, the dangerous-command validator and safety-immune
operations keep gating exactly as in interactive mode. The mode is never
persisted: a new session always starts interactive. Exposed on all three
surfaces — terminal REPL, ACP (slash command), MCP (manage_session
policy_mode action).
ChatCLI - Adapter binding the @proc tool to the session process supervisor.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements plugins.ProcAdapter over cli/agent/proc: a lazily created,
session-scoped Supervisor whose command vetting is the SAME
agent.CommandValidator the one-shot exec path uses — @proc is never a side
door around policy. Every process still running dies with the session.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - ratelimit_command.go *
/ratelimit (alias /limits) shows the latest rate-limit state captured from
provider response headers. Data is populated centrally via
auth.ResponseObserver for every HTTP provider, so this works across all
providers without per-provider code.
ChatCLI - Refine convergence wiring (Phase 5 enterprise). *
Builds a convergence.Composite cascade (char → jaccard → embedding)
from the active embedding provider (shared with HyDE so there's no
duplicate provider instance). Wired by AgentMode.initWorkers into
quality.BuildPipelineDeps.ConvergenceChecker. *
Degrades gracefully: when semantic convergence is disabled in
config, returns nil and the RefineHook falls back to the legacy
char-level heuristic. When the embedding scorer is enabled but the
provider is the null one (no CHATCLI_EMBED_PROVIDER configured),
the cascade still runs char + jaccard, and embedding-related
thresholds are never applied.
ChatCLI - /refine and /verify session toggles (Phases 5 & 6). *
The hooks are normally controlled by /config quality. These slashes
give the user a way to flip the next-turn behavior without editing
env vars: /refine on|off|once, /verify on|off|once. Bare /refine or
/verify show the current state.
ChatCLI - Reflexion wiring (Phase 4 of seven-pattern rollout). *
Builds the LLM and memory-persist callbacks the ReflexionHook needs,
plus the durable lesson queue (lessonq.Runner) used in enterprise
mode. Lives in cli/ so the quality package never imports cli.ChatCLI. *
Subcommands of /reflect:
/reflect → show queue + DLQ status
/reflect <text> → persist a user-supplied lesson
/reflect list → list pending + DLQ entries
/reflect failed → list DLQ entries with errors
/reflect retry <id> → move DLQ entry back to active queue
/reflect purge <id> → permanently delete a DLQ entry
/reflect drain → force processing of pending queue
rpc_chat.go *
Full-pipeline chat turns for the MCP/ACP servers. The interactive REPL turn
(processLLMRequest) and this headless variant share every enrichment stage —
assembleChatSystemPrompt (workspace memory, /context attach, pinned + auto
skills, MCP catalog, RAG), buildChatTempHistory, skill model routing, effort
hints, token-aware history compaction, hub mirroring and the memory worker
nudge — so an MCP client gets the SAME ChatCLI experience as the terminal,
by construction rather than by reimplementation. *
Concurrency: the pipeline reads and writes shared ChatCLI state
(cli.history, cli.currentSessionName), so turns run under the same
process-wide serialization as the captured agent/coder runs (rpcStdoutSem via
captureRPCStdout). The backend owns the per-session histories; this method
swaps one in for the duration of the turn and always restores the previous
state, even on error.
rpc_support.go *
Exposes ChatCLI capabilities to the MCP/ACP servers (cmd/rpcserve.go) so an
MCP client can drive the real agent/coder loops and the built-in tools — not
just a chat passthrough. *
The agent and coder render to stdout; these helpers redirect os.Stdout to a
buffer for the duration of the run and return the captured transcript. The
JSON-RPC server holds its own copy of the original stdout (captured at
construction), so the protocol channel is unaffected by the redirect.
rpc_support_full.go *
The full capability surface behind the MCP/ACP servers: every built-in and
external plugin (not just the old curated five), the agent/coder loops with
per-call provider/model routing and quality-harness toggles, the skill
catalog (served as MCP prompts), and provider discovery. *
Beyond plugins, the server re-exports every tool discovered from the MCP
servers ChatCLI itself is connected to (mcp_servers.json), under the same
mcp_<tool> names the agent loop uses — ChatCLI as an MCP hub: one endpoint
aggregating many servers. Proxied tools keep their origin JSON Schema and
receive the caller's arguments verbatim. *
Exposure policy (CHATCLI_MCP_TOOLS):
all (default) every tool, including write/exec — the operator opted in
by starting the server.
safe only tools whose capability metadata reports read-only
for a bare invocation. For proxied MCP tools this trusts
the origin server's annotations.readOnlyHint — the same
trust the operator extended by configuring the server.
<csv> explicit allowlist of tool names (with or without '@');
proxied MCP tools are named with their mcp_ prefix
(e.g. "read,search,mcp_list_regions"). *
Interactive tools that require a live TTY/user (ask, voice, park) are
excluded unconditionally: over stdio RPC they would hang the turn waiting
for input that can never arrive.
rpc_support_resources.go *
Read-only export of ChatCLI's local state to MCP clients as resources under
the chatcli:// scheme: the user's long-term memory, profile and projects,
the /context store (including knowledge bases with paged document reads),
the skill catalog and the saved sessions. This is what lets a user who
built their knowledge in ChatCLI browse the SAME state from any MCP client
on the machine. Everything here is read-only by construction; mutations go
through the tools surface (@memory, @context, manage_session, …). *
URIs:
chatcli://memory/index | longterm | profile | projects | stats
chatcli://contexts — catalog (JSON)
chatcli://contexts/{name} — rendered content / index card
chatcli://knowledge/{kb} — TOC
chatcli://knowledge/{kb}/{source}?offset=N — paged document read
chatcli://skills — catalog with triggers (JSON)
chatcli://skills/{name} — skill body (markdown)
chatcli://sessions — saved-session names
chatcli://sessions/{name} — saved session (JSON) *
Gate: CHATCLI_MCP_RESOURCES=off disables the surface entirely.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
run_coordinator.go — the cadence/back-pressure/circuit-breaker primitive that
governs the background self-evolution pass (memory extraction + skill
detection share one run). Extracted from memoryWorker so the scheduling logic
is independently testable with an injectable clock, and reusable by any future
periodic task. *
It guarantees: at most one run at a time (back-pressure); a minimum gap and a
minimum amount of new work between runs (cadence); and, after a streak of
failures, a cooldown window during which runs are skipped entirely (circuit
breaker) instead of hammering a provider that is down — the queue is drained
on the next run once the window passes.
runs_hub_bridge — mirrors the agent run registry through the Conversation
Hub's SQLite store, giving /agents and @agents cross-process sight: a REPL
can watch runs executing inside the gateway daemon (and vice versa), and
request their cancellation. *
Writer side: an OnEvent observer marks runs dirty and a 1s flusher upserts
their JSON snapshots into the agent_runs table (see hub.AgentRunStore for
why runs are upserted, not appended). Every flush also re-upserts the
local active set, so updated_at doubles as a liveness heartbeat. *
Reader side: the bridge publishes a process-wide provider that lists runs
mirrored by OTHER instances, annotated with staleness (heartbeat silence),
and forwards cancel requests by flagging the row — the owning process
observes the flag on its next flush tick and cancels locally, since only
it holds the context.CancelFunc.
ChatCLI - scheduler_adapter.go *
Implements plugins.SchedulerAdapter so the @scheduler builtin plugin
can route ReAct tool calls into the live Scheduler. Supplied to
plugins.SetSchedulerAdapter during initScheduler.
ChatCLI - scheduler_bridge.go *
Implements scheduler.CLIBridge on top of *ChatCLI. Owned by the CLI
package so the scheduler subpackage stays free of the circular
dependency the top-level struct would introduce. *
The bridge is stateless except for a back-pointer to ChatCLI. Every
method routes through existing chatcli code paths so scheduled work
behaves identically to interactive work — hooks fire, quality
pipeline runs, session policy applies, etc.
ChatCLI - scheduler_command.go *
Top-level command handlers for /schedule, /wait, /jobs and the agent
tool adapters. Routes to either the in-process scheduler or the
remote daemon, transparently.
ChatCLI - scheduler_completer.go *
Context-aware autocomplete for /schedule, /wait and /jobs. Follows
the same pattern as getContextSuggestions / getSessionSuggestions: *
- Subcommand suggestions when the user is at position 1.
- Flag suggestions after the subcommand, with short descriptions.
- Value suggestions right after a flag that has a fixed-vocabulary
(like --status, --on-timeout, --owner), plus live lookups of
active job IDs for --depends-on / --triggers / show / cancel /
pause / resume / logs. *
All descriptions go through i18n so a future translation pass is
trivial. Lookups hit the local scheduler, or the remote daemon via
schedulerList when running in thin-client mode.
httpProbeClient — bounded, redirect-aware HTTP client used by the
scheduler's ParkPoll action via CLIBridge.RunHTTPProbe. Centralizing
timeout, redirect, and body-cap policy here keeps the action
executor terse and the security posture auditable in one place.
ChatCLI - scheduler_init.go *
Scheduler lifecycle integration into *ChatCLI. *
Initialization order (called from NewChatCLI, after hooks + bus are ready): *
1. Build scheduler.Config from env.
2. If daemon auto-connect enabled and a daemon is reachable, wrap
it in a thin proxy and skip in-process init.
3. Otherwise build the in-process scheduler, register builtins,
start it. *
Cleanup: DrainAndShutdown is invoked from ChatCLI.cleanup.
Tiny encoding/json wrappers so the command handler can stay import-
light on the json package. Kept in a separate file so the rest of
scheduler_command.go reads cleanly.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
selfevolve.go — the self-evolution engine. *
Root cause it addresses: long-term memory "happens by itself" because a
background worker extracts facts every few turns, but skills only ever got
created when the model remembered to call @skill — so users had to ASK for
them. This engine gives skills the same proactive treatment WITHOUT a second
LLM call: it piggybacks on the memory worker's existing extraction pass. The
worker appends selfEvolveSkillDirective to that prompt, and the same response
that yields facts also yields ## SKILL_CANDIDATES. applySkillCandidates then
authors or evolves them. *
Safety model (mode=auto): every authored skill is engine-OWNED and tracked by
a content hash in a sidecar manifest, mirroring builtin.Seed. The engine only
ever evolves a skill it still owns and the user has not hand-edited; a skill
the user authored or touched is never clobbered. Every authored skill is
reversible via `/skill remove` and surfaced with a one-line notice. mode=
suggest never writes to disk; mode=off disables the directive entirely. *
The only operator-facing knob is CHATCLI_SELFEVOLVE_MODE. Cadence, cost and
resilience are inherited from the memory worker — no new tuning surface.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
selfevolve_manifest.go — edit-safety ledger for engine-authored skills. *
Mirrors pkg/persona/builtin/seed.go's manifest discipline: each skill the
engine writes is recorded with the SHA-256 of the exact bytes it wrote. On a
later pass the engine only evolves a skill whose current on-disk hash still
matches — i.e. one it owns and the user has not hand-edited. A skill the user
authored (never recorded) or has since changed (hash drift) is treated as
user-owned and never overwritten. The ledger lives beside the skills it
tracks so it travels and is cleaned up with them.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
selfevolve_merge.go — the on-demand skill-body merge (the "pull" half). *
Per-turn the engine injects only a tiny skill index card (names + one-line
descriptions). The full body of a skill is never in the prompt. When — and
only when — an evolution is actually detected, this makes ONE targeted LLM
call that loads just that single skill's body and folds the improvement in.
Cost therefore scales with real evolutions, not with skill-count × turns,
mirroring memory's index/recall split.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
selfevolve_parse.go — robust, YAML-free parser for SKILL_CANDIDATES blocks. *
The extraction LLM emits zero or more self-delimited [[skill]]...[[/skill]]
blocks. We scan for those delimiters directly rather than inferring YAML, so a
stray indent or quote can never corrupt a parse. Blocks are recognized
anywhere in the response (they are self-delimiting), which tolerates models
that reorder or relabel the section header.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - send_adapter.go *
Implements plugins.SendAdapter so the @send builtin tool can deliver
proactive outbound messages through the live gateway platform adapters —
the same Telegram/WhatsApp/Discord/Slack/webhook integrations the gateway
daemon uses for replies. Supplied to plugins.SetSendAdapter at startup. *
Target resolution:
"platform" → the platform's configured home channel
(CHATCLI_<PLATFORM>_HOME_CHANNEL)
"platform:chat_id" → an explicit chat id (the rest is passed verbatim,
so "telegram:-100123:42" keeps the thread suffix) *
Adapters are built on demand via gateway.BuildConfigured() — only platforms
with valid credentials are instantiated, so an unconfigured target yields a
clear "not configured" error instead of a silent drop.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - session_adapter.go *
Implements plugins.SessionAdapter so the @session tool can search the saved
conversation store through the live SessionManager. Supplied to
plugins.SetSessionAdapter at startup.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - session_autorecall.go *
Proactive recall for SAVED SESSIONS, the sibling of the fact auto-recall
in memory_autorecall.go. Autosave made every conversation retrievable, but
retrieval relied on the model CHOOSING to call @session — and models
routinely answer "I don't have that context" while the relevant autosave
sits unread in the store. Each agent/coder turn, this ranks the recent
sessions against the turn's hints (or against the user's own words when
they explicitly reference a past conversation) and floats the top matches
as a compact pointer block; the model then pulls detail via @session get. *
Cache discipline: hint-driven text changes turn to turn, so the block
rides in the UNCACHED trailing dynamic block, exactly like the fact
auto-recall — never in the stable workspace block. *
Gated by CHATCLI_SESSION_AUTORECALL (default on). Search is scoped to the
most recent sessions (they are what "ontem"/"where we left off" point at)
and served from the corpus cache, so the per-turn cost is bounded.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - session_search_normalize.go *
Text normalization for saved-session search. Recall queries are natural
language ("o que discutimos sobre o spinner?"), while the session-level
AND filter in SearchSessions is a literal substring match — without
normalization, accents ("autenticação" vs "autenticacao") and
recall-framing words ("discutimos", "what did we decide") disqualify
exactly the sessions the user is asking about. *
Accent folding is a hand-rolled Latin table instead of x/text: the store
only sees PT/EN prose, and stdlib-only avoids a new direct dependency.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Skill auto-activation helpers
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Extracts file-like tokens from user input and composes the system-prompt
block used to inject auto-triggered / path-matched skills. Shared by chat
mode (cli_llm.go) and agent mode (agent_mode.go) so that both code paths
honor the same skill frontmatter contract.
ChatCLI - Skill Registry Command Handler
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Handles /skill commands: search, install, uninstall, list, info, registries, help.
ChatCLI - Manual skill invocation via /<skill-name>
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements the "/<skill-name> [args]" routing promised by the skill
frontmatter advanced docs:
- Only skills with `user-invocable: true` are routable.
- Skills with `disable-model-invocation: true` are still allowed via
manual invocation (the flag only blocks *auto* activation).
- The skill's full content is injected into the system prompt for the
single turn via cli.pendingManualSkill.
- The skill's `model:` / `effort:` hints are honored for that turn.
- Any trailing args become the user message passed to the LLM; when
empty, a neutral "apply skill X" instruction is synthesized and the
`argument-hint` (if any) is shown to the user as a usage nudge.
ChatCLI - Skill model/provider resolution (thin wrapper)
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Delegates to llm/client.ResolveModelRouting which holds the pure logic.
This file only wires in ChatCLI state (cachedModels, manager, logger) and
keeps the existing ChatCLI method signature so the rest of the codebase
stays unchanged.
ChatCLI - Mid-loop skill re-activation for agent/coder mode
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Skills auto-activate once at Run() start against the user's query. That
misses everything the ReAct loop produces afterwards: the model's own
<reasoning> text, the file paths its tool calls start touching, and the
follow-up instructions the user types mid-session (type-ahead queue or the
interactive continuation prompt). This file closes that gap: every turn the
loop re-scans that mid-run text against the skill catalog and injects any
NEWLY matched skill as an append-only history message — so a skill whose
trigger only surfaces in the agent's own plan ("I should write a Helm
chart…") still reaches the model in time to shape the very next action. *
Injection is append-only (a user-role message, like the tool-guard and
payload-recovery hints) so the cached system-prompt prefix is never
invalidated mid-run. A per-Run dedup set guarantees each skill is injected
at most once per session, bounding both token cost and cascade risk.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
/thinking — session-level reasoning override. *
Sits on top of llm/client/skill_hints (which maps SkillEffort to
Anthropic thinking_budget and OpenAI reasoning_effort). The override
is consumed in cli_llm.go (chat path) and agent_mode.go (orchestrator
turn) so the user can force-on, force-off, or pick an explicit tier
without touching env vars.
ChatCLI - Tool-catalog rendering and deferral policy.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
The agent system prompt used to carry the FULL definition of every builtin
(~11k tokens across 28 tools, measured) on every turn, even though a
typical session touches a handful. This file implements the same deferral
the MCP section already applies to external servers: a small CORE set keeps
full definitions inline, every other builtin appears as a one-line index
entry, and the model pulls a full definition on demand through the @tools
meta-tool. External (user-installed) plugins stay fully rendered — they are
few and explicitly chosen. *
CHATCLI_AGENT_TOOL_CATALOG=full restores the legacy always-inline behavior.
ChatCLI - Adapter binding the @tools meta-tool to the plugin registry.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Implements plugins.ToolCatalogAdapter over the live plugin manager AND the
MCP manager: Describe renders one tool's full prompt block through the SAME
renderer the agent system prompt uses (an on-demand definition is
byte-identical to an inline one) — for mcp_* names it renders the tool's
JSON Schema from the connected server instead — and List renders the
one-line index of everything available, builtins and MCP alike.
Wired via plugins.SetToolCatalogAdapter at startup.
tty_inject_unix.go — controlling-TTY input injection via TIOCSTI. *
Used by the park subsystem to wake go-prompt out of its blocking
stdin read when a parked agent's resume becomes ready. We inject
the literal string "/resume <token>\n" as if the user typed it; the
executor then runs naturally (drainPendingResumes consumes the queue,
the resume runs in foreground with full terminal control), the same
code path /coder uses to take the terminal back from go-prompt. *
Platform notes *
- Linux: TIOCSTI behavior depends on the kernel build and a
runtime sysctl introduced in 5.16:
/proc/sys/dev/tty/legacy_tiocsti
Default 0 (enabled) on older kernels and many server distros;
default 1 (restricted) on Linux 6.x+ desktop builds and the
Docker Desktop linuxkit kernel. When restricted, TIOCSTI
returns EPERM. Operators who need auto-resume injection can
toggle the flag with `sysctl -w dev.tty.legacy_tiocsti=0`
(root). The fallback path remains the executor-hook drain. *
- macOS: TIOCSTI was deprecated in macOS Ventura and is gated
behind kern.tiocsti_disable=0 on most modern installs. Calls
return EPERM under the default policy. We surface the error so
the bridge can log the limitation; the executor-hook drain in
cli.executor still consumes the queue when the user types any
character + Enter. *
- FreeBSD/NetBSD/OpenBSD: TIOCSTI works for controlling TTYs in
the same session. macOS-style restrictions don't apply.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
/update atualiza o ChatCLI pelo MESMO canal em que foi instalado
(Homebrew, go install ou binário oficial da release — detectados pelo
pacote update). Canais manuais (Docker, build local) recebem instruções
em vez de ação. Este arquivo também abriga o fluxo de boot: refresh do
cache de release + staging silencioso no modo CHATCLI_AUTO_UPDATE=auto.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Aviso de atualização descoberto DEPOIS da welcome screen: o refresh de
release roda em goroutine no boot, então quando ele detecta uma versão
nova a tela de boas-vindas já foi impressa. Em vez de esperar o próximo
boot, o aviso fica pendente e é drenado no próximo tick do executor —
o único ponto onde escrever no stdout não disputa com o redraw do
go-prompt (mesmo padrão de memNotices).
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
Renderização do relatório de versão — usada pelo /version, pela slash
tool equivalente e pela flag -v/--version do binário. Substitui a saída
antiga (hardcoded em PT, sem menção ao /update e cega ao canal de
instalação) por um card no tratamento sóbrio do welcome: régua titulada,
grid de indentação 2, canal detectado, convite ao /update e as novidades
da release quando há atualização disponível.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
ChatCLI - Windows console input sanitizer.
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0 *
On Windows, go-prompt reads keys through go-tty, which translates any key
pressed with Alt held — INCLUDING AltGr (right Alt), which Windows reports
as Ctrl+Alt — into an ESC prefix followed by the character. That is correct
for Alt-as-Meta shortcuts, but AltGr is how several layouts type everyday
characters: "/" is AltGr+Q on Brazilian ABNT2, "@"/"{"/"[" need AltGr on
German and Nordic layouts, and so on. go-prompt doesn't recognize
ESC+<printable> sequences, so it inserts the raw ESC byte into the edit
buffer, which the terminal renders as a stray "?"-like glyph before the
character the user actually typed. *
altGrParser wraps the platform ConsoleParser and strips that spurious ESC
when — and only when — the batch is ESC followed by exactly one printable
rune. Real escape sequences (CSI "ESC [", SS3 "ESC O", double-ESC) and the
Alt shortcuts chatcli itself binds (ESC f / ESC b word navigation,
ESC DEL / ESC BS delete-word) pass through untouched. The logic is
platform-neutral (and unit-tested everywhere); the wrapper is only wired
into the prompt on Windows, where the go-tty translation exists.
ChatCLI - Command Line Interface for LLM interaction
Copyright (c) 2024 Edilson Freitas
License: Apache-2.0
Index ¶
- Constants
- Variables
- func AgentMaxTurns() int
- func DetectPromptInjection(text string) (bool, []string)
- func FormatPayloadSize(bytes int) string
- func FormatVersionReport(rep version.Report) string
- func HasStdin() bool
- func IsEncrypted(data []byte) bool
- func LocalHubPrincipal() string
- func NewSlashToolPlugin(entry *SlashToolEntry) plugins.Plugin
- func ParsePayloadSize(s string) int
- func PreprocessArgs(args []string) []string
- func RegisterSlashTool(entry *SlashToolEntry)
- func SanitizeCommandOutput(cmd, output string) string
- func SweepStaleParks(cutoff time.Time) (int, []error)
- type ACPCommandInfo
- type AgentMode
- func (a *AgentMode) InjectedSkillNames() []string
- func (a *AgentMode) Run(ctx context.Context, query string, additionalContext string, ...) error
- func (a *AgentMode) RunOnce(ctx context.Context, query string, autoExecute bool) error
- func (a *AgentMode) RunResumed(ctx context.Context, snap *park.Snapshot, outcome, detail string) error
- type AnimationManager
- type BudgetLevel
- type ChatCLI
- func (cli *ChatCLI) ApplyOverrides(ctx context.Context, mgr manager.LLMManager, provider, model string) error
- func (cli *ChatCLI) CancelOperation()
- func (cli *ChatCLI) CleanExpiredMachineSessionsRPC() int
- func (cli *ChatCLI) DeleteSessionRPC(name string) error
- func (cli *ChatCLI) EnableHubSync(client HubClient)
- func (cli *ChatCLI) ExpandSlashCommandRPC(ctx context.Context, text string) (string, bool)
- func (cli *ChatCLI) ForkSessionRPC(sourceName, newName string) error
- func (cli *ChatCLI) GetContextCommands() []prompt.Suggest
- func (cli *ChatCLI) GetInternalCommands() []prompt.Suggest
- func (cli *ChatCLI) HandleOneShotOrFatal(ctx context.Context, opts *Options) bool
- func (cli *ChatCLI) IsACPCommandAllowed(token string) bool
- func (cli *ChatCLI) IsExecuting() bool
- func (cli *ChatCLI) ListACPCommands() []ACPCommandInfo
- func (cli *ChatCLI) ListAllRPCTools() []RPCToolInfo
- func (cli *ChatCLI) ListCommandPromptsRPC() [][3]string
- func (cli *ChatCLI) ListMCPProxyTools() []RPCMCPToolInfo
- func (cli *ChatCLI) ListRPCResources() []RPCResourceInfo
- func (cli *ChatCLI) ListSessionsRPC() ([]string, error)
- func (cli *ChatCLI) ListSkillsRPC() []RPCSkillInfo
- func (cli *ChatCLI) LoadSessionRPC(name string) ([]models.Message, error)
- func (cli *ChatCLI) MCPStartupDone() <-chan struct{}
- func (cli *ChatCLI) PolicyAutoMode() bool
- func (cli *ChatCLI) PolicyModeLabel() string
- func (cli *ChatCLI) PrintWelcomeScreen()
- func (cli *ChatCLI) ProvidersRPC() (string, error)
- func (cli *ChatCLI) PruneSessionsRPC(prefix string, keep int) int
- func (cli *ChatCLI) ReadRPCResource(_ context.Context, uri string) (RPCResourceContent, error)
- func (cli *ChatCLI) RenderCommandPromptRPC(ctx context.Context, name, args string) (string, bool)
- func (cli *ChatCLI) RotateHubThreadRPC(ctx context.Context)
- func (cli *ChatCLI) RunAgentCaptured(ctx context.Context, task string) (string, error)
- func (cli *ChatCLI) RunAgentFullOnce(ctx context.Context, task string) error
- func (cli *ChatCLI) RunAgentOnce(ctx context.Context, input string, autoExecute bool) error
- func (cli *ChatCLI) RunAgentRPC(ctx context.Context, task string, o RPCRunOpts) (string, error)
- func (cli *ChatCLI) RunAgentStreaming(ctx context.Context, task string, emit func(string)) (string, error)
- func (cli *ChatCLI) RunAnyRPCTool(ctx context.Context, name, args string) (string, error)
- func (cli *ChatCLI) RunAnyRPCToolArgv(ctx context.Context, name string, argv []string) (string, error)
- func (cli *ChatCLI) RunChatTurnRPC(ctx context.Context, sessionID, userInput string, history []models.Message, ...) (RPCChatTurn, error)
- func (cli *ChatCLI) RunCoderCaptured(ctx context.Context, task string) (string, error)
- func (cli *ChatCLI) RunCoderOnce(ctx context.Context, input string) error
- func (cli *ChatCLI) RunCoderRPC(ctx context.Context, task string, o RPCRunOpts) (string, error)
- func (cli *ChatCLI) RunGatewayCoderOnce(ctx context.Context, task string) error
- func (cli *ChatCLI) RunGatewayCoderStreaming(ctx context.Context, task string, emit func(string)) (string, error)
- func (cli *ChatCLI) RunGatewayForeground(ctx context.Context) error
- func (cli *ChatCLI) RunGatewayWithBroker(ctx context.Context, broker hub.Broker) error
- func (cli *ChatCLI) RunMCPProxyTool(ctx context.Context, name string, args json.RawMessage) (string, error)
- func (cli *ChatCLI) RunOnce(ctx context.Context, input string, disableAnimation bool, rawOutput bool) error
- func (cli *ChatCLI) RunSlashCommandRPC(ctx context.Context, line string) (string, error)
- func (cli *ChatCLI) SaveSessionRPC(name string, history []models.Message) error
- func (cli *ChatCLI) SearchSessionsRPC(query string) (string, error)
- func (cli *ChatCLI) SessionExistsRPC(name string) bool
- func (cli *ChatCLI) SessionModTimeRPC(name string) (time.Time, error)
- func (cli *ChatCLI) SetMCPToolsObserver(fn func())
- func (cli *ChatCLI) SetPolicyAutoMode(on bool)
- func (cli *ChatCLI) SetRPCDangerPolicy(block bool)
- func (cli *ChatCLI) SetUnattended(v bool)
- func (cli *ChatCLI) SetWatching(active bool, statusFunc func() string)
- func (cli *ChatCLI) SkillContentRPC(name string) (string, error)
- func (cli *ChatCLI) Start(ctx context.Context)
- func (cli *ChatCLI) StartHubResume(ctx context.Context, principal string) func()
- func (cli *ChatCLI) StartWatcher(ctx context.Context, cfg k8s.WatchConfig) error
- func (cli *ChatCLI) StopWatcher()
- type CommandBlock
- type CommandContextInfo
- type CommandHandler
- type CommandOutput
- type CompactConfig
- type CompactStage
- type ContextHandler
- type CostTracker
- func (ct *CostTracker) BudgetBlocked() bool
- func (ct *CostTracker) BudgetHardStopEnabled() bool
- func (ct *CostTracker) BudgetMessage() string
- func (ct *CostTracker) CheckBudget() BudgetLevel
- func (ct *CostTracker) CurrentSessionID() string
- func (ct *CostTracker) EstimateAndRecord(provider, model string, inputChars, outputChars int)
- func (ct *CostTracker) GetSummary(provider, model string, history int) string
- func (ct *CostTracker) RecordFromHistory(provider, model string, history []interface{ ... })
- func (ct *CostTracker) RecordRealUsage(provider, model string, usage *models.UsageInfo)
- func (ct *CostTracker) RecordUsage(provider, model string, promptTokens, completionTokens int)
- func (ct *CostTracker) ReloadBudget()
- func (ct *CostTracker) Reset()
- func (ct *CostTracker) RestoreSession(sessionID string) error
- func (ct *CostTracker) SaveSession() error
- func (ct *CostTracker) SetSessionName(name string)
- func (ct *CostTracker) Snapshot() SessionCostData
- func (ct *CostTracker) TakeBudgetTransition() (BudgetLevel, string, bool)
- func (ct *CostTracker) TotalCost() float64
- func (ct *CostTracker) TotalTokens() int64
- type EnvRedactMode
- type EnvRedactor
- type ExecutionProfile
- type FileChunk
- type HistoryCompactor
- func (hc *HistoryCompactor) CharBudget(cfg CompactConfig) int
- func (hc *HistoryCompactor) Compact(ctx context.Context, history []models.Message, llmClient client.LLMClient, ...) ([]models.Message, error)
- func (hc *HistoryCompactor) NeedsCompaction(history []models.Message, cfg CompactConfig) bool
- func (hc *HistoryCompactor) SetCompressionLayer(l *compress.Layer)
- func (hc *HistoryCompactor) SetStatusCallback(cb StatusCallback)
- type HistoryManager
- type HubClient
- type HubSync
- type InteractionState
- type Logger
- type MessageTrimmer
- type ModelUsageRecord
- type MultilineBuffer
- type Options
- type PersonaHandler
- func (h *PersonaHandler) AttachAgent(name string)
- func (h *PersonaHandler) DetachAgent(name string)
- func (h *PersonaHandler) GetManager() *persona.Manager
- func (h *PersonaHandler) HandleCommand(userInput string)
- func (h *PersonaHandler) ListAgents()
- func (h *PersonaHandler) ListSkills()
- func (h *PersonaHandler) LoadAgent(name string)
- func (h *PersonaHandler) ShowActive(full bool)
- func (h *PersonaHandler) ShowAgentStatus()
- func (h *PersonaHandler) ShowAttachedAgents()
- func (h *PersonaHandler) ShowHelp()
- func (h *PersonaHandler) UnloadAgent()
- func (h *PersonaHandler) UnloadAllAgents()
- type RPCChatOpts
- type RPCChatTurn
- type RPCMCPToolInfo
- type RPCResourceContent
- type RPCResourceInfo
- type RPCRunOpts
- type RPCSkillInfo
- type RPCToolInfo
- type SessionCostData
- type SessionData
- type SessionEncryptor
- type SessionManager
- func (sm *SessionManager) CleanExpiredMachineSessions() int
- func (sm *SessionManager) CleanExpiredSessions() int
- func (sm *SessionManager) DeleteSession(name string) error
- func (sm *SessionManager) ForkCurrentToNew(newName string, sd *SessionData) error
- func (sm *SessionManager) ForkSession(sourceName, newName string) error
- func (sm *SessionManager) GetSessionMessages(name string, offset, limit int) ([]models.Message, int, error)
- func (sm *SessionManager) LatestSessionInfo() (name string, saved time.Time, title string)
- func (sm *SessionManager) ListSessions() ([]string, error)
- func (sm *SessionManager) LoadSession(name string) ([]models.Message, error)
- func (sm *SessionManager) LoadSessionV2(name string) (*SessionData, error)
- func (sm *SessionManager) PruneSessionsByPrefix(prefix string, keep int) int
- func (sm *SessionManager) SaveSession(name string, history []models.Message) error
- func (sm *SessionManager) SaveSessionV2(name string, sd *SessionData) error
- func (sm *SessionManager) SearchSessions(query string, maxSnippetsPerSession int) ([]SessionSearchHit, error)
- func (sm *SessionManager) SessionExists(name string) bool
- func (sm *SessionManager) SessionModTime(name string) (time.Time, error)
- func (sm *SessionManager) SessionTitles() map[string]string
- type SessionSearchHit
- type SkillClientResolution
- type SkillHandler
- func (sh *SkillHandler) GetPinnedSkills() []*persona.Skill
- func (sh *SkillHandler) HandleCommand(ctx context.Context, userInput string)
- func (sh *SkillHandler) Info(ctx context.Context, name string, fromRegistry string)
- func (sh *SkillHandler) Install(ctx context.Context, name string, fromRegistry string)
- func (sh *SkillHandler) IsPinned(name string) bool
- func (sh *SkillHandler) List()
- func (sh *SkillHandler) Pin(name string)
- func (sh *SkillHandler) PinnedNames() []string
- func (sh *SkillHandler) Prefer(args []string)
- func (sh *SkillHandler) Search(ctx context.Context, query string)
- func (sh *SkillHandler) SetRegistryEnabled(name string, enabled bool)
- func (sh *SkillHandler) ShowHelp()
- func (sh *SkillHandler) ShowPinned()
- func (sh *SkillHandler) ShowRegistries()
- func (sh *SkillHandler) Uninstall(name string)
- func (sh *SkillHandler) Unpin(name string)
- type SlashToolEntry
- type SourceType
- type StatusCallback
Constants ¶
const ( SourceTypeUserInput = agent.SourceTypeUserInput SourceTypeFile = agent.SourceTypeFile SourceTypeCommandOutput = agent.SourceTypeCommandOutput )
Constantes re-exportadas
const ( StateNormal InteractionState = iota StateSwitchingProvider StateProcessing StateAgentMode ProfileNormal ExecutionProfile = iota ProfileAgent ProfileCoder )
Interaction states and execution profiles (iota block shared for legacy reasons; the integer values never cross paths in use).
const ( ColorReset = "\033[0m" ColorGreen = "\033[32m" ColorLime = "\033[92m" ColorCyan = "\033[36m" ColorGray = "\033[90m" ColorPurple = "\033[35m" ColorBold = "\033[1m" ColorYellow = "\033[33m" ColorRed = "\033[31m" ColorBlue = "\033[34m" )
ANSI Color Codes
Legacy path: these hue constants are the legacy color path. New and migrated code styles through semantic roles instead — kit.Colorize / kit.Style with a theme.Role — so the theme-swap contract lives in one place. The constants stay (they are load-bearing across many call sites and theme.Recolor keeps them themable) but should not gain new callers.
const ( ModeChat = "chat" ModeAgent = "/agent" ModeCoder = "/coder" )
Mode names match the canonical `[ACTIVE MODE: <name>]` markers we embed at the top of every system prompt. Anything that doesn't match is treated as a non-mode system message and left alone.
const AgentFormatInstructions = `
[ACTIVE MODE: /agent]
You are operating inside ChatCLI's /agent mode, supervised plan-and-execute on the user's terminal. Each suggested action goes through an interactive menu before running. Stay strictly within the format below.
[FORMAT — /AGENT]
PROCESS:
1. <reasoning> (step-by-step thought).
2. <explanation> (what the commands will do).
3. Actions — either ` + "```execute:<type>```" + ` blocks (types: shell, git, docker, kubectl) or <tool_call name="@tool" args="..." /> for plugins.
RULES:
- Security: NEVER suggest destructive commands (rm -rf, dd, mkfs) without an explicit warning in <explanation>.
- Clarity: prefer easy-to-understand commands; explain the complex ones briefly.
- Efficiency: combine with pipes when it actually reduces turns.
- Parallelism: batch all independent tool_calls/agent_calls in ONE response. Use <agent_call> when there are 3+ independent tasks.
- Interactivity: avoid vim/nano etc. If unavoidable, suffix the command with #interactive.
- Ambiguous request: ask before acting, no execute blocks.
`
AgentFormatInstructions contains format instructions for /agent mode (used when a persona is active - combined with persona + these instructions). Same lean pattern as CoderFormatInstructions above.
const ChatModeSystemHint = `` /* 934-byte string literal not displayed */
ChatModeSystemHint is prepended to the system prompt when the user is in the default conversational (chat) mode — i.e. NOT inside /agent or /coder. It prevents the AI from emitting execute blocks, tool_call tags, or any command-execution syntax that would be silently ignored by the chat handler.
const CoderFormatInstructions = `
[ACTIVE MODE: /coder]
You are operating inside ChatCLI's /coder mode, supervised plan-and-execute. The user can approve, deny, or roll back every action. Stay strictly within the format below.
[FORMAT — /CODER]
RESPONSE: <reasoning> (2-6 lines, numbered task list, [✓] done) → one or more <tool_call name="@coder" args='{"cmd":"SUBCOMMAND","args":{...}}' />.
RULES:
- @coder tools only (no ` + "```" + ` code blocks). JSON args on a SINGLE line; wrap with single quotes. No backslash escapes.
- Multiline content in write/patch → base64 encoding.
- Parallelism: emit ALL independent tool_calls in ONE response. Sequential only when the next call depends on the previous result. Prefer <agent_call> for 3+ independent tasks.
- No narration ("Let me…", "Now I'll…"). Call tools directly. Final text only: 1-3 sentences summarizing WHAT changed.
- If info is missing that only the user can provide, STOP — write one clear question, emit NO tool_calls.
EXAMPLES:
<tool_call name="@coder" args='{"cmd":"read","args":{"file":"main.go"}}' />
<tool_call name="@coder" args='{"cmd":"search","args":{"term":"TODO","dir":"./src","glob":"*.go"}}' />
<tool_call name="@coder" args='{"cmd":"exec","args":{"cmd":"go test ./..."}}' />
<tool_call name="@coder" args='{"cmd":"patch","args":{"file":"f.go","search":"old","replace":"new"}}' />
SUBCOMMANDS: read, write, patch, tree, search, exec, git-status, git-diff, git-log, git-changed, git-branch, test, rollback, clean, delegate.
OTHER TOOLS:
- @webfetch: <tool_call name="@webfetch" args='{"url":"https://..."}' /> (bodies >~10KB auto-save; use filter/from_line for scoping)
- @websearch: <tool_call name="@websearch" args='{"query":"..."}' />
- MCP tools: <tool_call name="mcp_toolname" args='{"param":"value"}' />
`
CoderFormatInstructions contains ONLY the format instructions for /coder mode (used when a persona is active - combined with persona + these instructions). Kept lean because it is re-sent every turn on top of the active persona prompt.
const CoderSystemPrompt = `[ACTIVE MODE: /coder]
You are a senior software engineer operating in ChatCLI's /coder mode — supervised plan-and-execute on the user's terminal. Every action you suggest goes through a security gate before running. Stay strictly within the response format below.
## RESPONSE FORMAT (mandatory)
1. Start with <reasoning> (2-6 lines): analysis + numbered task list; mark done with [✓]. On error, replan.
2. Emit one or more <tool_call name="@coder" args='{"cmd":"SUBCOMMAND","args":{...}}' /> — args MUST be a single line of JSON.
Alternative CLI syntax also works: <tool_call name="@coder" args="read --file main.go --start 1 --end 50" />
## @coder SUBCOMMANDS
read, write, patch, tree, search, exec, git-status, git-diff, git-log, git-changed, git-branch, test, rollback, clean, delegate.
## EXAMPLES (copy the shape, not the values)
<tool_call name="@coder" args='{"cmd":"read","args":{"file":"main.go","start":10,"end":50}}' />
<tool_call name="@coder" args='{"cmd":"search","args":{"term":"Login","dir":".","glob":"*.go"}}' />
<tool_call name="@coder" args='{"cmd":"exec","args":{"cmd":"go test ./...","dir":"."}}' />
<tool_call name="@coder" args='{"cmd":"git-diff","args":{"staged":true}}' />
Writing / patching:
- Multiline content → encode as base64: args='{"cmd":"write","args":{"file":"x.go","content":"BASE64","encoding":"base64"}}'
- Single-line content → plain string is fine.
- patch: provide "search" (must be unique in the file) and "replace". For diffs: {"diff":"BASE64","diff-encoding":"base64"}.
- Always read the file before patching it.
## RULES
1. Tools only: NEVER use ` + "```" + ` code blocks in lieu of <tool_call>. Shell commands go through ` + "`" + `exec` + "`" + `.
2. Args on a SINGLE line. Use single quotes around the JSON: args='{...}'. Never escape with backslashes.
3. Parallelism: emit ALL independent tool_calls in ONE response. Three reads → three <tool_call> tags together, not three turns. When <agent_call> is offered, prefer it for 3+ independent tasks.
4. Sequential only when a call depends on the previous result.
5. Fail-fast: a failing tool stops the batch.
6. Need info only the user can provide (role name, choice, ambiguous path)? STOP — write one clear question, no tool_calls. The system waits for the reply.
## NO NARRATION
No "Let me…", "I will…", "Now I'll…". Call tools directly after <reasoning>. Output text only for the final 1-3 sentence summary ("what changed", not "what I did"). If blocked, state it in one line.
## DELEGATE FOR BIG PAYLOADS
When a tool would dump a huge response (metrics scrape, verbose logs, exhaustive search) and you only need the gist, delegate:
<tool_call name="@coder" args='{"cmd":"delegate","args":{"description":"analyze metrics","prompt":"Return the top 3 memory hotspots with numbers.","tools":["read","search","tree"],"read_only":true}}' />
Keep read_only=true unless the subagent MUST write/exec. Narrow the tools allowlist. Spell out the expected output format.
## OTHER TOOLS (registered plugins)
Use the best tool for the job, not only @coder:
- @webfetch: <tool_call name="@webfetch" args='{"url":"https://..."}' /> — fetch web pages (HTML stripped). Bodies >~10KB auto-save to disk; use filter/from_line for scoping.
- @websearch: <tool_call name="@websearch" args='{"query":"..."}' />
- MCP tools: <tool_call name="mcp_toolname" args='{"param":"value"}' />
`
CoderSystemPrompt is the complete system prompt for /coder mode (used when NO persona is active). Written in English for maximum AI compliance across all model families.
Token budget: this prompt is re-sent on every agent turn (cached via SystemParts + Anthropic cache_control, but still counted by providers without prompt caching). Keep it dense: every rule here must earn its place. Prefer one crisp example over three verbose ones.
const GatewayLanguageDirective = `` /* 334-byte string literal not displayed */
GatewayLanguageDirective replaces the daemon-locale "respond in X" pin on the gateway path. A messaging gateway serves many users in many languages, so the reply must follow each incoming message rather than a fixed locale. English (instruction to the model), prominent header like the locale directive it replaces, and applied on every gateway path so language is never static.
const GatewayMemoryDirective = `` /* 833-byte string literal not displayed */
GatewayMemoryDirective is appended to the gateway core prompt (like GatewayLanguageDirective) so the daemon treats the injected Memory Index as real knowledge about the user instead of answering personal questions as a stranger. A separate composable directive rather than an edit to GatewaySystemPrompt: directives evolve independently of the base persona.
const GatewaySystemPrompt = `` /* 2366-byte string literal not displayed */
GatewaySystemPrompt is the system prompt used when the coder engine answers through the messaging gateway (Telegram/WhatsApp/Discord/Slack/webhook). It keeps the full tool-use mechanics of /coder but replaces the terse "senior engineer / no narration / plan-execute" framing with a conversational assistant voice — because here the final prose IS the chat message the user reads, not a commit summary. English for cross-model compliance, like CoderSystemPrompt.
Variables ¶
var CommandFlags = map[string]map[string][]prompt.Suggest{
"@file": {
"--mode": {
{Text: "full", Description: "Processa o conteúdo completo (padrão, trunca se necessário)"},
{Text: "summary", Description: "Gera resumo estrutural (árvore de arquivos, tamanhos, sem conteúdo)"},
{Text: "chunked", Description: "Divide grandes projetos em pedaços gerenciáveis (use /nextchunk para prosseguir)"},
{Text: "smart", Description: "Seleciona arquivos relevantes com base no seu prompt (IA decide)"},
},
},
"@command": {
"-i": {},
"--ai": {},
},
"/session": {
"new": {},
"save": {},
"load": {},
"list": {},
"delete": {},
},
"/context": {
"create": {},
"attach": {},
"detach": {},
"list": {},
"delete": {},
"show": {},
"merge": {},
"attached": {},
"export": {},
"import": {},
"metrics": {},
"help": {},
},
"/connect": {
"--token": {},
"--provider": {},
"--model": {},
"--llm-key": {},
"--use-local-auth": {},
"--tls": {},
"--ca-cert": {},
"--client-id": {},
"--client-key": {},
"--realm": {},
"--agent-id": {},
"--ollama-url": {},
},
"/agent": {
"list": {},
"load": {},
"attach": {},
"detach": {},
"skills": {},
"show": {
{Text: "--full", Description: "Mostra detalhes completos do agente"},
},
"status": {},
"off": {},
"help": {},
},
}
CommandFlags declares the completer suggestions for the flag layer of every supported slash / @ command. See cli_completer.go for the top-level suggestion list.
Functions ¶
func AgentMaxTurns ¶ added in v1.41.1
func AgentMaxTurns() int
func DetectPromptInjection ¶ added in v1.97.0
DetectPromptInjection scans text for common prompt injection patterns. Returns (detected, list of matched patterns).
func FormatPayloadSize ¶ added in v1.104.0
FormatPayloadSize returns a human-readable size for display.
func FormatVersionReport ¶ added in v1.172.0
FormatVersionReport renderiza o card completo de versão. Exportada para o main (flag -v/--version) compartilhar exatamente a mesma saída do /version.
func HasStdin ¶ added in v1.16.1
func HasStdin() bool
Detecta se há dados no stdin (pipe/arquivo ao invés de TTY).
func IsEncrypted ¶ added in v1.97.0
IsEncrypted checks if data starts with the encrypted session magic header.
func LocalHubPrincipal ¶ added in v1.123.0
func LocalHubPrincipal() string
LocalHubPrincipal returns the shared principal from env/default (no db layer). Used where no store is at hand; store-backed resolution uses resolveHubPrincipal.
func NewSlashToolPlugin ¶ added in v1.118.0
func NewSlashToolPlugin(entry *SlashToolEntry) plugins.Plugin
NewSlashToolPlugin wraps the entry. Returns nil for nil input so callers can pass the result of LookupSlashTool unchecked.
func ParsePayloadSize ¶ added in v1.104.0
ParsePayloadSize accepts human-friendly size strings and returns bytes. A bare number is interpreted as MB (the most common unit users think in for proxy caps). Explicit suffixes: B, KB/K, MB/M, GB/G (case insensitive, whitespace tolerated: "5 MB" works). Returns 0 for any non-positive or unparseable input.
func PreprocessArgs ¶ added in v1.16.2
PreprocessArgs normaliza o caso de -p/--prompt sem valor, convertendo para -p= / --prompt= Ex.: echo "msg" | chatcli -p -> trata como prompt vazio + stdin (não quebra o flag parser)
func RegisterSlashTool ¶ added in v1.118.0
func RegisterSlashTool(entry *SlashToolEntry)
RegisterSlashTool adds an entry to the registry. Idempotent: a second registration with the same Name overwrites the first.
func SanitizeCommandOutput ¶ added in v1.97.0
SanitizeCommandOutput wraps command output with delimiters, enforces size limits, and detects potential prompt injection attempts.
func SweepStaleParks ¶ added in v1.112.0
SweepStaleParks deletes snapshots whose CreatedAt is older than the cutoff. Returns the count removed and any per-file errors. Suitable for a background goroutine; we don't wire one yet but expose the helper so /parked gc can call it on demand.
Types ¶
type ACPCommandInfo ¶ added in v1.173.0
type ACPCommandInfo struct {
Name string // without the leading slash (ACP convention)
Description string
InputHint string
}
ACPCommandInfo describes one slash command advertised to ACP clients.
type AgentMode ¶
type AgentMode struct {
// contains filtered or unexported fields
}
AgentMode representa a funcionalidade de agente autônomo no ChatCLI
func NewAgentMode ¶
NewAgentMode cria uma nova instância do modo agente
func (*AgentMode) InjectedSkillNames ¶ added in v1.177.0
InjectedSkillNames returns a sorted snapshot of every skill name the current Run() has delivered to the model. Consumers: the park snapshot and the scheduler adapter (so a job scheduled mid-run inherits the creating run's skills).
func (*AgentMode) Run ¶
func (a *AgentMode) Run(ctx context.Context, query string, additionalContext string, systemPromptOverride string) error
Run inicia o modo agente com uma consulta do usuário, utilizando um loop de Raciocínio-Ação (ReAct). Agora aceita systemPromptOverride para definir personas específicas (ex: Coder).
func (*AgentMode) RunResumed ¶ added in v1.112.0
func (a *AgentMode) RunResumed(ctx context.Context, snap *park.Snapshot, outcome, detail string) error
RunResumed re-enters the agent loop using a previously-saved snapshot. It is idempotent on token: a Resume that lost the race against a /cancel-park finds a missing snapshot and returns ErrSnapshotNotFound, which the caller renders as a no-op.
outcome and detail come from the AgentResume action payload. They are woven into the synthetic tool-result message so the LLM sees:
[park completed] outcome=matched detail=<probe response>
type AnimationManager ¶
type AnimationManager struct {
// contains filtered or unexported fields
}
func NewAnimationManager ¶
func NewAnimationManager() *AnimationManager
func (*AnimationManager) SetSuppressed ¶ added in v1.65.5
func (am *AnimationManager) SetSuppressed(v bool)
SetSuppressed enables or disables animation suppression. When suppressed, ShowThinkingAnimation stores the message but does not start the spinner goroutine. This prevents the animation from conflicting with go-prompt's rendering.
func (*AnimationManager) ShowThinkingAnimation ¶
func (am *AnimationManager) ShowThinkingAnimation(message string)
ShowThinkingAnimation inicia ou atualiza a animação "pensando"
func (*AnimationManager) StopThinkingAnimation ¶
func (am *AnimationManager) StopThinkingAnimation()
StopThinkingAnimation para a animação de forma segura
func (*AnimationManager) UpdateMessage ¶
func (am *AnimationManager) UpdateMessage(message string)
UpdateMessage atualiza a mensagem sem parar e reiniciar a animação
type BudgetLevel ¶ added in v1.99.0
type BudgetLevel int
BudgetLevel indicates how close the session is to its spending limit.
const ( // BudgetOK indicates spending is within normal limits. BudgetOK BudgetLevel = iota // BudgetWarning indicates spending has reached the warning threshold. BudgetWarning // BudgetExceeded indicates spending has exceeded the configured limit. BudgetExceeded )
type ChatCLI ¶
type ChatCLI struct {
Client client.LLMClient
Provider string
Model string
UserMaxTokens int
// K8s watcher context injection
WatcherContextFunc func() string // returns K8s context to prepend to LLM prompts
// contains filtered or unexported fields
}
ChatCLI representa a interface de linha de comando do chat
func NewChatCLI ¶
func NewChatCLI(ctx context.Context, manager manager.LLMManager, logger *zap.Logger) (*ChatCLI, error)
NewChatCLI cria uma nova instância de ChatCLI
func (*ChatCLI) ApplyOverrides ¶ added in v1.16.0
func (*ChatCLI) CancelOperation ¶ added in v1.22.0
func (cli *ChatCLI) CancelOperation()
CancelOperation cancela a operação atual se houver uma
func (*ChatCLI) CleanExpiredMachineSessionsRPC ¶ added in v1.165.0
CleanExpiredMachineSessionsRPC applies the machine-session TTL. Called by the MCP/ACP server at boot so long-running daemons get the same bounded lifecycle the REPL applies on start.
func (*ChatCLI) DeleteSessionRPC ¶ added in v1.161.0
DeleteSessionRPC removes a saved session, validating the name first.
func (*ChatCLI) EnableHubSync ¶ added in v1.123.0
EnableHubSync wires a connected CLI to the shared conversation hub. Call it after setting cli.Client to the remote client and before Start.
func (*ChatCLI) ExpandSlashCommandRPC ¶ added in v1.184.0
ExpandSlashCommandRPC is the remote-surface twin of the REPL dispatch: ACP prompts and MCP chat turns call it to resolve a "/name args" input into the expanded prompt. Always non-interactive — the pre-exec gate resolves through policy/automode, never a terminal prompt.
func (*ChatCLI) ForkSessionRPC ¶ added in v1.163.0
ForkSessionRPC copies a saved session under a new name, validating both names first — this surface is reachable by remote MCP clients.
func (*ChatCLI) GetContextCommands ¶ added in v1.37.0
GetContextCommands retorna a lista de sugestões para comandos com @
func (*ChatCLI) GetInternalCommands ¶ added in v1.37.0
func (*ChatCLI) HandleOneShotOrFatal ¶ added in v1.16.3
HandleOneShotOrFatal executa o modo one-shot se solicitado (flag -p usada ou stdin presente). - Em caso de erro, imprime mensagem em Markdown (stderr) e faz logger.Fatal (sem fallback). - Retorna true se o one-shot foi tratado (com sucesso ou erro fatal). Retorna false se não foi acionado.
func (*ChatCLI) IsACPCommandAllowed ¶ added in v1.173.0
IsACPCommandAllowed reports whether a slash token (with leading slash) is runnable headless over ACP.
func (*ChatCLI) IsExecuting ¶ added in v1.22.0
IsExecuting retorna true se uma operação está em andamento
func (*ChatCLI) ListACPCommands ¶ added in v1.173.0
func (cli *ChatCLI) ListACPCommands() []ACPCommandInfo
ListACPCommands returns the commands advertised to ACP clients: the three mode switches plus the headless allowlist, with the palette registry's localized summaries and each command's real subcommands as its input hint.
func (*ChatCLI) ListAllRPCTools ¶ added in v1.158.0
func (cli *ChatCLI) ListAllRPCTools() []RPCToolInfo
ListAllRPCTools returns every plugin the exposure policy admits.
func (*ChatCLI) ListCommandPromptsRPC ¶ added in v1.184.0
ListCommandPromptsRPC exposes the catalog to the MCP prompts primitive.
func (*ChatCLI) ListMCPProxyTools ¶ added in v1.161.0
func (cli *ChatCLI) ListMCPProxyTools() []RPCMCPToolInfo
ListMCPProxyTools returns every tool discovered from connected MCP servers that the exposure policy admits (visibility masks from EnabledTools/ DisabledTools already honored by VisibleTools). Sorted by name. Waits, bounded, for the initial connect pass so an early listing doesn't miss the aggregated catalog.
func (*ChatCLI) ListRPCResources ¶ added in v1.163.0
func (cli *ChatCLI) ListRPCResources() []RPCResourceInfo
ListRPCResources enumerates the exported resources. Dynamic entries (contexts, knowledge bases, skills, sessions) are listed individually so an MCP client can browse them without knowing names in advance.
func (*ChatCLI) ListSessionsRPC ¶ added in v1.161.0
ListSessionsRPC returns the saved session names.
func (*ChatCLI) ListSkillsRPC ¶ added in v1.158.0
func (cli *ChatCLI) ListSkillsRPC() []RPCSkillInfo
ListSkillsRPC returns the installed skill catalog.
func (*ChatCLI) LoadSessionRPC ¶ added in v1.161.0
LoadSessionRPC returns a saved session's chat history. The name is validated before touching the store — this surface is reachable by remote MCP clients.
func (*ChatCLI) MCPStartupDone ¶ added in v1.161.0
func (cli *ChatCLI) MCPStartupDone() <-chan struct{}
MCPStartupDone returns a channel closed once the initial StartAll pass over the configured MCP servers has finished (regardless of per-server success). When MCP is disabled the channel is already closed, so callers can always select on it.
func (*ChatCLI) PolicyAutoMode ¶ added in v1.181.0
PolicyAutoMode reports whether the session is in policy automode ("ask" verdicts auto-approve). Safe for concurrent use: toggled from command surfaces while the agent loop reads it.
func (*ChatCLI) PolicyModeLabel ¶ added in v1.181.0
PolicyModeLabel returns the localized label of the current session mode.
func (*ChatCLI) PrintWelcomeScreen ¶ added in v1.18.0
func (cli *ChatCLI) PrintWelcomeScreen()
PrintWelcomeScreen exibe a tela de boas-vindas completa e traduzida no tratamento sóbrio: logo, versão dim, dica sob régua titulada, linha do modelo ativo com o marcador ◆ e rodapé de comandos — tudo no grid de indentação 2, sem molduras.
func (*ChatCLI) ProvidersRPC ¶ added in v1.158.0
ProvidersRPC returns a JSON document describing the configured providers, the active provider/model, and each provider's models — the discovery surface for per-call routing. Models come from the same path the interactive picker uses (ListModelsForProvider: API listing when the provider supports it, merged and deduplicated with the catalog), fetched concurrently with a bounded timeout and a catalog fallback per provider.
func (*ChatCLI) PruneSessionsRPC ¶ added in v1.165.0
PruneSessionsRPC bounds a machine-session set (e.g. the mcp- mirrors) to the newest keep files. No-op when the store is unavailable.
func (*ChatCLI) ReadRPCResource ¶ added in v1.163.0
ReadRPCResource resolves one chatcli:// URI to its content.
func (*ChatCLI) RenderCommandPromptRPC ¶ added in v1.184.0
RenderCommandPromptRPC expands one command for MCP prompts/get. The pre-exec gate runs non-interactive (policy/automode or deny).
func (*ChatCLI) RotateHubThreadRPC ¶ added in v1.179.0
RotateHubThreadRPC rotates the shared cross-channel hub conversation to a fresh thread. The RPC /session handler calls it when a session's identity changes (load/new) so the old thread's backlog is not spliced on top.
func (*ChatCLI) RunAgentCaptured ¶ added in v1.123.0
RunAgentCaptured runs the full agent (ReAct) loop one-shot on task, capturing its transcript. Used by the MCP agent_task tool.
func (*ChatCLI) RunAgentFullOnce ¶ added in v1.163.0
RunAgentFullOnce runs the FULL agent ReAct loop one-shot on a raw task — the same engine, tools, skills and workspace context the interactive /agent command gets — exiting when the loop reaches its final answer. This is the agent-profile mirror of runCoderQuery, and the entry the MCP server's agent_task tool uses; the legacy single-call RunOnce path remains only for the CLI one-shot (-p "/agent …") whose auto-exec contract predates the loop.
func (*ChatCLI) RunAgentOnce ¶ added in v1.19.0
func (*ChatCLI) RunAgentRPC ¶ added in v1.158.0
RunAgentRPC runs the FULL agent (ReAct) loop with per-call options — the same engine, tools, skills and workspace context the interactive /agent command gets.
func (*ChatCLI) RunAgentStreaming ¶ added in v1.123.0
func (cli *ChatCLI) RunAgentStreaming(ctx context.Context, task string, emit func(string)) (string, error)
RunAgentStreaming runs the full agent (ReAct) loop one-shot on task, forwarding the agent's rendered progress to emit line by line as it works, and returning the full transcript. Used by the messaging gateway to narrate task execution back to the chat platform.
func (*ChatCLI) RunAnyRPCTool ¶ added in v1.158.0
RunAnyRPCTool invokes any policy-admitted plugin by name with a raw argument string (JSON envelope or flat args, exactly as the agent passes).
func (*ChatCLI) RunAnyRPCToolArgv ¶ added in v1.180.0
func (cli *ChatCLI) RunAnyRPCToolArgv(ctx context.Context, name string, argv []string) (string, error)
RunAnyRPCToolArgv is the argv-native entry: callers that already hold a real argv (the `chatcli tool` subcommand) pass it verbatim — joining and re-splitting would corrupt values containing whitespace.
func (*ChatCLI) RunChatTurnRPC ¶ added in v1.163.0
func (cli *ChatCLI) RunChatTurnRPC( ctx context.Context, sessionID, userInput string, history []models.Message, o RPCChatOpts, ) (RPCChatTurn, error)
RunChatTurnRPC runs ONE chat turn through the full interactive pipeline, headless. history is the session history owned by the caller; the returned RPCChatTurn.History is the compacted/extended history to store back.
func (*ChatCLI) RunCoderCaptured ¶ added in v1.123.0
RunCoderCaptured runs the coder loop one-shot on task, capturing output.
func (*ChatCLI) RunCoderOnce ¶ added in v1.42.0
RunCoderOnce executa o modo coder de forma não-interativa (one-shot), mas mantendo o loop ReAct do AgentMode (com tool_calls/plugins).
func (*ChatCLI) RunCoderRPC ¶ added in v1.158.0
RunCoderRPC runs the coder loop with per-call options.
func (*ChatCLI) RunGatewayCoderOnce ¶ added in v1.123.0
RunGatewayCoderOnce runs the coder ReAct loop one-shot on a raw task for the messaging gateway: same engine and tools (create/edit files, run commands, iterate) but with the gateway persona layered on the system prompt so the answer is concise, chat-friendly prose. The caller is expected to have set cli.unattended so every confirmation auto-approves — the gateway must never block on a stdin prompt the daemon has no way to answer.
func (*ChatCLI) RunGatewayCoderStreaming ¶ added in v1.123.0
func (cli *ChatCLI) RunGatewayCoderStreaming(ctx context.Context, task string, emit func(string)) (string, error)
RunGatewayCoderStreaming runs the coder ReAct loop one-shot on task with the gateway persona, forwarding the rendered progress to emit line by line and returning the full transcript. Used by the messaging gateway: it keeps the coder engine's full capability (create/edit files, run commands, iterate) while answering as concise chat prose. The clean final answer is captured into cli.lastAgentReply during the run.
func (*ChatCLI) RunGatewayForeground ¶ added in v1.123.0
RunGatewayForeground builds the configured adapters and runs the messaging runner in the foreground until ctx is canceled. It is the body of the detached `chatcli gateway` subcommand; the agent runs fully unattended. It opens its own hub database — durable and cross-channel, but live-tail push to a remote CLI only spans processes via DB-on-connect/resync. For real-time cross-process push, co-locate the gateway in the server via RunGatewayWithBroker (see CHATCLI_GATEWAY_IN_SERVER).
func (*ChatCLI) RunGatewayWithBroker ¶ added in v1.123.0
RunGatewayWithBroker runs the gateway sharing an existing hub broker (the gRPC server's). Because the fan-out Manager is in-memory, sharing one broker in a single process is what makes a Telegram message push live to a connected notebook in real time. The caller owns the broker's lifecycle.
func (*ChatCLI) RunMCPProxyTool ¶ added in v1.161.0
func (cli *ChatCLI) RunMCPProxyTool(ctx context.Context, name string, args json.RawMessage) (string, error)
RunMCPProxyTool executes one proxied MCP tool. name accepts both the prefixed ("mcp_list_regions") and bare ("list_regions") forms; args is the caller's raw MCP arguments object, forwarded verbatim to the origin server. A tool-level error result (isError) is surfaced as a Go error carrying the origin content, so the RPC layer relays it in-band per the MCP convention.
func (*ChatCLI) RunSlashCommandRPC ¶ added in v1.173.0
RunSlashCommandRPC executes one allowlisted slash command headless, capturing its stdout as the result. Mirrors the scheduler bridge's HandleCommand invocation: panic sentinels are flow-control, not crashes. Caller must have validated the command against the allowlist — mode switches (/agent, /coder, /run) never reach here.
func (*ChatCLI) SaveSessionRPC ¶ added in v1.161.0
SaveSessionRPC persists a chat history under name in the saved-session store (the same store the REPL /session command uses). Name validation is the store's own (alphanumeric with dash/underscore/dot).
func (*ChatCLI) SearchSessionsRPC ¶ added in v1.163.0
SearchSessionsRPC runs the full-text search across the saved-session store and renders the hits compactly (session name, match count, snippets) for a model-facing tool result.
func (*ChatCLI) SessionExistsRPC ¶ added in v1.179.0
SessionExistsRPC reports whether a saved session exists in the store.
func (*ChatCLI) SessionModTimeRPC ¶ added in v1.179.0
SessionModTimeRPC returns the store mtime of a saved session — the freshness signal the RPC backend's bound sessions use to adopt writes made by other surfaces (REPL, gateway, another server) before a turn.
func (*ChatCLI) SetMCPToolsObserver ¶ added in v1.161.0
func (cli *ChatCLI) SetMCPToolsObserver(fn func())
SetMCPToolsObserver registers fn to run whenever the MCP tool catalog changes (servers connecting, dynamic list_changed refreshes, disconnects). No-op when MCP is disabled. The RPC server uses it to relay notifications/tools/list_changed to its own clients.
func (*ChatCLI) SetPolicyAutoMode ¶ added in v1.181.0
SetPolicyAutoMode switches the session's policy mode. Session-scoped by design — never persisted, so every new process starts interactive.
func (*ChatCLI) SetRPCDangerPolicy ¶ added in v1.163.0
SetRPCDangerPolicy toggles the unattended dangerous-command policy. With block=true, a command classified dangerous by the CommandValidator is declined in-band (the model sees the refusal in the transcript and can replan) instead of auto-approved the way the gateway daemon runs. The MCP server sets this from CHATCLI_MCP_DANGER; the gateway never calls it, so its opt-in auto-approve behavior is unchanged.
func (*ChatCLI) SetUnattended ¶ added in v1.123.0
SetUnattended toggles fully non-interactive agent execution (used by the gateway daemon). When set, the agent never prompts for confirmation and the "thinking" spinner is suppressed — its frames (`model... |/-\`) carry alphanumerics, so they slip past gatewayCleanLine and flood the action feed when stdout is a captured pipe rather than a TTY. Suppressing at the source kills the noise outright instead of trying to filter it downstream.
func (*ChatCLI) SetWatching ¶ added in v1.55.0
SetWatching configures the K8s watcher state for the CLI.
func (*ChatCLI) SkillContentRPC ¶ added in v1.158.0
SkillContentRPC returns a skill's markdown body for prompts/get.
func (*ChatCLI) StartHubResume ¶ added in v1.163.0
StartHubResume joins the shared conversation hub in RESUME mode: it adopts the principal's active conversation (creating it only if none exists) instead of rotating like the interactive Start does. Used by the MCP server so a thread started in the REPL or on a gateway channel continues seamlessly from any MCP client on the machine. principal overrides the hub principal ("" keeps the configured default — the same conversation as the REPL/gateway). Returns the store close function (nil when the hub is unavailable or disabled).
func (*ChatCLI) StartWatcher ¶ added in v1.56.0
StartWatcher creates and starts a K8s watcher in background from interactive mode.
func (*ChatCLI) StopWatcher ¶ added in v1.56.0
func (cli *ChatCLI) StopWatcher()
StopWatcher stops the running K8s watcher if any.
type CommandBlock ¶
type CommandBlock = agent.CommandBlock
CommandBlock and the other aliases below re-export the agent package types so legacy callers can continue to import them from cli without following the refactor chain.
type CommandContextInfo ¶
type CommandContextInfo = agent.CommandContextInfo
CommandBlock and the other aliases below re-export the agent package types so legacy callers can continue to import them from cli without following the refactor chain.
type CommandHandler ¶
type CommandHandler struct {
// contains filtered or unexported fields
}
func NewCommandHandler ¶
func NewCommandHandler(cli *ChatCLI) *CommandHandler
func (*CommandHandler) HandleCommand ¶
func (ch *CommandHandler) HandleCommand(ctx context.Context, userInput string) bool
HandleCommand dispatches a slash command. Returns true to exit the REPL.
type CommandOutput ¶
type CommandOutput = agent.CommandOutput
CommandBlock and the other aliases below re-export the agent package types so legacy callers can continue to import them from cli without following the refactor chain.
type CompactConfig ¶ added in v1.65.2
type CompactConfig struct {
Provider string
Model string
BudgetRatio float64 // fraction of context window to use (default 0.75)
MinKeepRecent int // minimum recent messages to keep verbatim (default 10)
CharsPerToken int // character-to-token ratio estimate (default 4)
// MaxPayloadBytes caps the serialized request body size in bytes.
// When > 0, overrides the context-window budget if it would yield
// a larger payload than the corporate proxy / gateway accepts
// (many enterprise proxies cap POST bodies at 1-5 MB). 0 disables
// the cap. Honors env CHATCLI_MAX_PAYLOAD (human-friendly: "5MB",
// "512KB", "5"=5MB when unit is omitted).
MaxPayloadBytes int
}
CompactConfig holds parameters for a compaction operation.
func DefaultCompactConfig ¶ added in v1.65.2
func DefaultCompactConfig(provider, model string) CompactConfig
DefaultCompactConfig returns sensible defaults for chat mode.
type CompactStage ¶ added in v1.104.0
type CompactStage string
CompactStage identifies which level of the pipeline is running. Used by the UI to render meaningful progress messages instead of a generic "Processando..." while the compactor is working.
const ( CompactStageStart CompactStage = "start" CompactStageTrim CompactStage = "trim" CompactStageSummarize CompactStage = "summarize" CompactStageEmergency CompactStage = "emergency" CompactStageDone CompactStage = "done" )
type ContextHandler ¶ added in v1.33.0
type ContextHandler struct {
// contains filtered or unexported fields
}
ContextHandler gerencia comandos relacionados a contextos
func NewContextHandler ¶ added in v1.33.0
func NewContextHandler(logger *zap.Logger) (*ContextHandler, error)
NewContextHandler cria um novo handler de contextos
func (*ContextHandler) GetManager ¶ added in v1.33.0
func (h *ContextHandler) GetManager() *ctxmgr.Manager
GetManager returns the underlying context manager.
func (*ContextHandler) HandleContextCommand ¶ added in v1.33.0
func (h *ContextHandler) HandleContextCommand(ctx context.Context, sessionID, input string) error
HandleContextCommand processa comandos /context
type CostTracker ¶ added in v1.97.0
type CostTracker struct {
// contains filtered or unexported fields
}
CostTracker tracks token usage and estimated cost for the current session, with per-model granularity, real API usage data support, cache token pricing, write-through session persistence, and configurable budget enforcement.
func NewCostTracker ¶ added in v1.97.0
func NewCostTracker() *CostTracker
NewCostTracker creates a new cost tracker with optional budget limit.
func (*CostTracker) BudgetBlocked ¶ added in v1.189.0
func (ct *CostTracker) BudgetBlocked() bool
BudgetBlocked reports whether new LLM turns must be refused: a budget is configured, CHATCLI_BUDGET_HARD_STOP is on, and the limit is exhausted.
func (*CostTracker) BudgetHardStopEnabled ¶ added in v1.189.0
func (ct *CostTracker) BudgetHardStopEnabled() bool
BudgetHardStopEnabled reports whether the hard-stop gate is armed.
func (*CostTracker) BudgetMessage ¶ added in v1.99.0
func (ct *CostTracker) BudgetMessage() string
BudgetMessage returns a human-readable budget status message. Returns empty string if no budget is configured or if spending is within limits.
func (*CostTracker) CheckBudget ¶ added in v1.99.0
func (ct *CostTracker) CheckBudget() BudgetLevel
CheckBudget returns the current budget level.
func (*CostTracker) CurrentSessionID ¶ added in v1.189.0
func (ct *CostTracker) CurrentSessionID() string
CurrentSessionID returns the id under which this session's snapshot is persisted.
func (*CostTracker) EstimateAndRecord ¶ added in v1.97.0
func (ct *CostTracker) EstimateAndRecord(provider, model string, inputChars, outputChars int)
EstimateAndRecord estimates tokens from text lengths and records usage.
func (*CostTracker) GetSummary ¶ added in v1.97.0
func (ct *CostTracker) GetSummary(provider, model string, history int) string
GetSummary returns a formatted cost summary string.
func (*CostTracker) RecordFromHistory ¶ added in v1.97.0
func (ct *CostTracker) RecordFromHistory(provider, model string, history []interface{ Content() string })
RecordFromHistory is kept for backward compatibility.
func (*CostTracker) RecordRealUsage ¶ added in v1.99.0
func (ct *CostTracker) RecordRealUsage(provider, model string, usage *models.UsageInfo)
RecordRealUsage records actual token usage from an API response. This is the preferred path — provides accurate cost tracking.
func (*CostTracker) RecordUsage ¶ added in v1.97.0
func (ct *CostTracker) RecordUsage(provider, model string, promptTokens, completionTokens int)
RecordUsage records tokens used for a single LLM request (legacy path).
func (*CostTracker) ReloadBudget ¶ added in v1.189.0
func (ct *CostTracker) ReloadBudget()
ReloadBudget re-reads the budget environment variables so /reload picks up .env changes without restarting the process.
func (*CostTracker) Reset ¶ added in v1.189.0
func (ct *CostTracker) Reset()
Reset closes the current accounting period and starts a fresh one. The closing period is persisted first so /cost last and /cost sessions can still see it — resetting never discards data.
func (*CostTracker) RestoreSession ¶ added in v1.99.0
func (ct *CostTracker) RestoreSession(sessionID string) error
RestoreSession loads a previous session's cost data into the tracker.
func (*CostTracker) SaveSession ¶ added in v1.99.0
func (ct *CostTracker) SaveSession() error
SaveSession persists the current cost data to disk for cross-session tracking (write-through from RecordRealUsage, plus explicit calls on reset/shutdown). Snapshots older than the retention window are pruned.
func (*CostTracker) SetSessionName ¶ added in v1.189.0
func (ct *CostTracker) SetSessionName(name string)
SetSessionName attaches the named-session identity to the persisted snapshot so /cost sessions can show which conversation the spend belongs to.
func (*CostTracker) Snapshot ¶ added in v1.189.0
func (ct *CostTracker) Snapshot() SessionCostData
Snapshot returns a copy of the current session cost data — the same shape that is persisted to disk, safe for the caller to serialize or render.
func (*CostTracker) TakeBudgetTransition ¶ added in v1.189.0
func (ct *CostTracker) TakeBudgetTransition() (BudgetLevel, string, bool)
TakeBudgetTransition returns a one-shot notice when the budget level has escalated since the last check (OK→Warning, Warning→Exceeded, …). The returned message is already localized; ok is false when there is nothing new to announce. De-escalations (after /cost reset or a raised limit) re-arm the notice silently.
func (*CostTracker) TotalCost ¶ added in v1.99.0
func (ct *CostTracker) TotalCost() float64
TotalCost returns the total estimated cost in USD for the session.
func (*CostTracker) TotalTokens ¶ added in v1.99.0
func (ct *CostTracker) TotalTokens() int64
TotalTokens returns total tokens used across all models.
type EnvRedactMode ¶ added in v1.97.0
type EnvRedactMode string
EnvRedactMode controls how environment variable redaction works.
const ( // EnvRedactStrict uses an allowlist — only explicitly safe vars are shown. EnvRedactStrict EnvRedactMode = "strict" // EnvRedactPermissive redacts known sensitive vars but shows the rest. EnvRedactPermissive EnvRedactMode = "permissive" )
type EnvRedactor ¶ added in v1.97.0
type EnvRedactor struct {
// contains filtered or unexported fields
}
EnvRedactor sanitizes environment variables before sending to LLM.
func NewEnvRedactor ¶ added in v1.97.0
func NewEnvRedactor() *EnvRedactor
NewEnvRedactor creates a redactor configured from environment. CHATCLI_ENV_REDACT_MODE: strict or permissive (default: permissive) CHATCLI_REDACT_PATTERNS: comma-separated additional patterns
func (*EnvRedactor) RedactEnv ¶ added in v1.97.0
func (r *EnvRedactor) RedactEnv(envVars map[string]string) map[string]string
RedactEnv sanitizes a map of environment variables, replacing sensitive values with [REDACTED].
func (*EnvRedactor) RedactEnvSlice ¶ added in v1.97.0
func (r *EnvRedactor) RedactEnvSlice(environ []string) map[string]string
RedactEnvSlice processes os.Environ()-style KEY=VALUE strings.
type ExecutionProfile ¶ added in v1.43.0
type ExecutionProfile int
ExecutionProfile selects which mode-specific defaults apply to the next LLM call (chat vs agent vs coder).
type HistoryCompactor ¶ added in v1.65.2
type HistoryCompactor struct {
// contains filtered or unexported fields
}
HistoryCompactor manages conversation history size through a 3-level pipeline:
Level 1: Near-lossless trimming (strip reasoning, compact XML, dedup) Level 2: Structured summarization (extract facts, not prose) Level 3: Emergency truncation (last resort)
func NewHistoryCompactor ¶ added in v1.65.2
func NewHistoryCompactor(logger *zap.Logger) *HistoryCompactor
NewHistoryCompactor creates a new HistoryCompactor with its embedded trimmer.
func (*HistoryCompactor) CharBudget ¶ added in v1.65.2
func (hc *HistoryCompactor) CharBudget(cfg CompactConfig) int
CharBudget returns the character budget based on the model's context window, additionally capped by MaxPayloadBytes if set (corporate-proxy scenarios). A safety factor leaves headroom for JSON overhead, system prompt and tools.
func (*HistoryCompactor) Compact ¶ added in v1.65.2
func (hc *HistoryCompactor) Compact( ctx context.Context, history []models.Message, llmClient client.LLMClient, cfg CompactConfig, ) ([]models.Message, error)
Compact runs the 3-level compaction pipeline. Each level is progressively more aggressive. Most of the time, Level 1 (trim) suffices.
func (*HistoryCompactor) NeedsCompaction ¶ added in v1.65.2
func (hc *HistoryCompactor) NeedsCompaction(history []models.Message, cfg CompactConfig) bool
NeedsCompaction returns true if the total character count exceeds the budget.
func (*HistoryCompactor) SetCompressionLayer ¶ added in v1.145.0
func (hc *HistoryCompactor) SetCompressionLayer(l *compress.Layer)
SetCompressionLayer wires the content-aware compression layer into the embedded trimmer so oversized tool feedback and injected context are reduced reversibly (CCR) during compaction instead of being byte-truncated.
func (*HistoryCompactor) SetStatusCallback ¶ added in v1.104.0
func (hc *HistoryCompactor) SetStatusCallback(cb StatusCallback)
SetStatusCallback registers a progress callback for UI feedback. Pass nil to clear. Safe to call concurrently.
type HistoryManager ¶
type HistoryManager struct {
// contains filtered or unexported fields
}
func NewHistoryManager ¶
func NewHistoryManager(logger *zap.Logger) *HistoryManager
func (*HistoryManager) AppendAndRotateHistory ¶ added in v1.19.1
func (hm *HistoryManager) AppendAndRotateHistory(newCommands []string) error
func (*HistoryManager) GetHistoryFilePath ¶ added in v1.47.4
func (hm *HistoryManager) GetHistoryFilePath() string
GetHistoryFilePath retorna o caminho atual do arquivo de histórico
func (*HistoryManager) LoadHistory ¶
func (hm *HistoryManager) LoadHistory() ([]string, error)
LoadHistory carrega o histórico do arquivo
type HubClient ¶ added in v1.123.0
type HubClient interface {
ResolveActiveConversation(ctx context.Context, principal string) (convID, principal2 string, err error)
NewConversation(ctx context.Context, principal string) (string, error)
AppendEvent(ctx context.Context, ev models.ConversationEvent) (models.ConversationEvent, error)
ReadConversation(ctx context.Context, convID string, sinceSeq int64, limit int) ([]models.ConversationEvent, error)
SubscribeConversation(ctx context.Context, convID string, sinceSeq int64) (<-chan models.ConversationEvent, error)
SetBinding(ctx context.Context, platform, userID, principal string) error
ListBindings(ctx context.Context, principal string) ([]models.HubBinding, error)
}
HubClient is the subset of the remote client the CLI needs to share a conversation through the hub. *client/remote.Client satisfies it; defining it here keeps the cli package free of a hard dependency on the remote package.
type HubSync ¶ added in v1.123.0
type HubSync struct {
// contains filtered or unexported fields
}
HubSync keeps a connected CLI in lock-step with the shared cross-channel conversation: it hydrates history on connect, mirrors each local turn, and pulls turns that arrived on other channels (Telegram/Slack/…) into history at the start of the next turn so the model has context — without printing them, which would fight the prompt. /newsession rotates the conversation. All methods are safe to call when the hub is unavailable (no-ops), so the REPL never blocks on the hub.
type InteractionState ¶ added in v1.22.0
type InteractionState int
InteractionState tracks the current phase of the chat loop so the prompt prefix, signal handlers, and spinner can coordinate.
type Logger ¶
type Logger interface {
Info(msg string, fields ...zap.Field)
Error(msg string, fields ...zap.Field)
Warn(msg string, fields ...zap.Field)
Sync() error
}
Logger interface para facilitar a testabilidade
type MessageTrimmer ¶ added in v1.65.2
type MessageTrimmer struct {
// contains filtered or unexported fields
}
MessageTrimmer performs near-lossless trimming of conversation messages to reduce token usage without losing semantic information.
func NewMessageTrimmer ¶ added in v1.65.2
func NewMessageTrimmer(logger *zap.Logger) *MessageTrimmer
NewMessageTrimmer creates a new MessageTrimmer.
func (*MessageTrimmer) SetCompressionLayer ¶ added in v1.145.0
func (t *MessageTrimmer) SetCompressionLayer(l *compress.Layer)
SetCompressionLayer wires the content-aware compression layer (optional).
func (*MessageTrimmer) TrimHistory ¶ added in v1.65.2
func (t *MessageTrimmer) TrimHistory(history []models.Message) []models.Message
TrimHistory performs near-lossless trimming on all messages in the history. It preserves system messages, user-authored messages, and summary messages intact.
type ModelUsageRecord ¶ added in v1.99.0
type ModelUsageRecord struct {
Provider string `json:"provider"`
Model string `json:"model"`
// Core token counts
PromptTokens int64 `json:"prompt_tokens"`
CompletionTokens int64 `json:"completion_tokens"`
TotalTokens int64 `json:"total_tokens"`
// Prompt-cache tokens. Anthropic reports them ALONGSIDE input_tokens
// (additive); OpenAI/Gemini report cache reads as a SUBSET of the
// prompt count — recomputeCost handles both semantics.
CacheCreationTokens int64 `json:"cache_creation_tokens,omitempty"`
CacheReadTokens int64 `json:"cache_read_tokens,omitempty"`
// Reasoning tokens (o-series / GPT-5 / Gemini thinking). Informational:
// already billed inside CompletionTokens.
ReasoningTokens int64 `json:"reasoning_tokens,omitempty"`
// Tracking
Requests int `json:"requests"`
HasRealData bool `json:"has_real_data"` // true if at least one call returned API usage
// PricingKnown is false when the model matched no pricing table entry —
// the computed cost is then zero NOT because the model is free but
// because ChatCLI does not know its price. /cost surfaces the difference.
PricingKnown bool `json:"pricing_known"`
// ProviderCostUSD accumulates the actually-billed cost reported by the
// provider itself (OpenRouter usage.cost) — authoritative for the calls
// that carried it. The Billed* pools remember WHICH tokens those calls
// covered, so a mixed key (some calls report usage.cost, some do not)
// prices only the uncovered remainder from the tables instead of
// discarding it: TotalCostUSD = table(unbilled tokens) + ProviderCostUSD.
ProviderCostUSD float64 `json:"provider_cost_usd,omitempty"`
BilledPromptTokens int64 `json:"billed_prompt_tokens,omitempty"`
BilledCompletionTokens int64 `json:"billed_completion_tokens,omitempty"`
BilledCacheReadTokens int64 `json:"billed_cache_read_tokens,omitempty"`
BilledCacheCreationTokens int64 `json:"billed_cache_creation_tokens,omitempty"`
// Computed cost (in USD)
InputCostUSD float64 `json:"input_cost_usd"`
OutputCostUSD float64 `json:"output_cost_usd"`
CacheCostUSD float64 `json:"cache_cost_usd"`
TotalCostUSD float64 `json:"total_cost_usd"`
}
ModelUsageRecord tracks cumulative token usage and cost for a single model.
type MultilineBuffer ¶ added in v1.97.0
type MultilineBuffer struct {
// contains filtered or unexported fields
}
MultilineBuffer accumulates lines between --- delimiters, providing consistent multiline input support across chat, agent, and coder modes.
Accepted delimiter (on a line by itself):
- --- (3 or more dashes)
Usage:
buf := &MultilineBuffer{}
complete, text := buf.ProcessLine(line)
if !complete { /* show continuation prompt */ }
else { /* submit text */ }
func (*MultilineBuffer) Active ¶ added in v1.97.0
func (mb *MultilineBuffer) Active() bool
Active returns true when the buffer is accumulating multiline input.
func (*MultilineBuffer) Delimiter ¶ added in v1.97.0
func (mb *MultilineBuffer) Delimiter() string
Delimiter returns the delimiter that opened the current multiline block.
func (*MultilineBuffer) LineCount ¶ added in v1.97.0
func (mb *MultilineBuffer) LineCount() int
LineCount returns the number of lines accumulated so far.
func (*MultilineBuffer) ProcessLine ¶ added in v1.97.0
func (mb *MultilineBuffer) ProcessLine(line string) (complete bool, fullText string)
ProcessLine feeds a new line into the buffer.
Returns:
- complete=false: the buffer is accumulating; show a continuation prompt.
- complete=true: fullText contains the final input to submit.
The opening and closing delimiter lines are NOT included in the output.
func (*MultilineBuffer) Reset ¶ added in v1.97.0
func (mb *MultilineBuffer) Reset()
Reset clears the buffer state (e.g., on Ctrl+C).
type Options ¶ added in v1.16.0
type Options struct {
// Geral
Version bool // --version | -v
Help bool // --help | -h
// Modo one-shot
Prompt string // -p | --prompt
Provider string // --provider
Model string // --model
Timeout time.Duration // --timeout
NoAnim bool // --no-anim
Raw bool // --raw
PromptFlagUsed bool // indica se -p/--prompt foi passado explicitamente
AgentAutoExec bool // --agent-auto-exec
MaxTokens int // --max-tokens
Realm string // --realm
AgentID string // --agent-id
}
Options representa as flags suportadas pelo binário
func NewFlagSet ¶ added in v1.16.0
NewFlagSet cria um FlagSet isolado e as Options para parsing
type PersonaHandler ¶ added in v1.48.0
type PersonaHandler struct {
// contains filtered or unexported fields
}
PersonaHandler handles agent/persona commands
func NewPersonaHandler ¶ added in v1.48.0
func NewPersonaHandler(logger *zap.Logger) *PersonaHandler
NewPersonaHandler creates a new persona handler
func (*PersonaHandler) AttachAgent ¶ added in v1.49.0
func (h *PersonaHandler) AttachAgent(name string)
AttachAgent adds an agent to active pool
func (*PersonaHandler) DetachAgent ¶ added in v1.49.0
func (h *PersonaHandler) DetachAgent(name string)
DetachAgent removes an agent from active pool
func (*PersonaHandler) GetManager ¶ added in v1.48.0
func (h *PersonaHandler) GetManager() *persona.Manager
GetManager returns the underlying persona manager
func (*PersonaHandler) HandleCommand ¶ added in v1.48.0
func (h *PersonaHandler) HandleCommand(userInput string)
HandleCommand processes /persona commands (retrocompatibilidade) Redireciona para os comandos /agent equivalentes
func (*PersonaHandler) ListAgents ¶ added in v1.48.0
func (h *PersonaHandler) ListAgents()
ListAgents shows all available agents
func (*PersonaHandler) ListSkills ¶ added in v1.48.0
func (h *PersonaHandler) ListSkills()
ListSkills shows all available skills
func (*PersonaHandler) LoadAgent ¶ added in v1.48.0
func (h *PersonaHandler) LoadAgent(name string)
LoadAgent loads an agent by name
func (*PersonaHandler) ShowActive ¶ added in v1.48.0
func (h *PersonaHandler) ShowActive(full bool)
ShowActive shows details of the currently active agent
func (*PersonaHandler) ShowAgentStatus ¶ added in v1.48.0
func (h *PersonaHandler) ShowAgentStatus()
ShowAgentStatus shows current agent/persona status (chamado por /agent sem argumentos)
func (*PersonaHandler) ShowAttachedAgents ¶ added in v1.49.0
func (h *PersonaHandler) ShowAttachedAgents()
ShowAttachedAgents shows only the list of attached agents without prompt details
func (*PersonaHandler) ShowHelp ¶ added in v1.48.0
func (h *PersonaHandler) ShowHelp()
ShowHelp shows usage information for /agent subcommands
func (*PersonaHandler) UnloadAgent ¶ added in v1.48.0
func (h *PersonaHandler) UnloadAgent()
UnloadAgent deactivates the current agent
func (*PersonaHandler) UnloadAllAgents ¶ added in v1.49.0
func (h *PersonaHandler) UnloadAllAgents()
UnloadAllAgents deactivates all agents
type RPCChatOpts ¶ added in v1.163.0
RPCChatOpts parametrizes a headless chat turn. Provider/Model are the per-call routing overrides from the MCP tool arguments; when set they win over any skill model hint (explicit beats implicit).
type RPCChatTurn ¶ added in v1.163.0
RPCChatTurn is the result of a headless chat turn: the assistant reply and the updated session history the backend should store.
type RPCMCPToolInfo ¶ added in v1.161.0
type RPCMCPToolInfo struct {
Name string // origin tool name, WITHOUT the mcp_ prefix
Server string // owning MCP server (mcp_servers.json name)
Description string
InputSchema map[string]interface{} // origin JSON Schema, passed through
ReadOnly bool // origin annotations.readOnlyHint
}
RPCMCPToolInfo describes one tool proxied from an MCP server ChatCLI is connected to, re-exported on the MCP/ACP server surface.
type RPCResourceContent ¶ added in v1.163.0
RPCResourceContent mirrors rpcserve.ResourceContent.
type RPCResourceInfo ¶ added in v1.163.0
RPCResourceInfo mirrors rpcserve.ResourceInfo without importing it (the dependency points the other way: cmd adapts between the two).
type RPCRunOpts ¶ added in v1.158.0
type RPCRunOpts struct {
// Provider/Model temporarily reroute the run to another configured
// provider (restored afterwards). Empty keeps the session default.
Provider string
Model string
// Quality maps CHATCLI_QUALITY_* env overrides applied for the run
// only (e.g. "CHATCLI_QUALITY_ENABLED": "true"). The quality pipeline
// re-reads env per run, so this is the canonical toggle surface.
Quality map[string]string
// Emit, when non-nil, receives the rendered transcript line by line
// as the loop works (ACP streaming).
Emit func(string)
// Events, when non-nil, installs a structured event sink for the run
// (ACP structured bridge). It takes precedence over Emit: the rendered
// transcript is captured and discarded, and the client consumes typed
// events plus the returned final answer instead of scraped lines.
Events agentevents.Sink
// Permissions, when non-nil, installs a per-run PermissionRequester so
// policy-gated actions can ask the connected client for approval even
// without an event sink (MCP elicitation bridge). Sinks implementing
// PermissionRequester themselves (ACP) take precedence.
Permissions agentevents.PermissionRequester
// Session scopes the run's /context attachments and knowledge bases
// (ctxmgr session id). Empty keeps the process default.
Session string
// History, together with a non-nil HistoryOut, swaps the caller's
// per-session conversation in for the run — the loop starts from it and
// HistoryOut receives the updated conversation on exit (same contract as
// RunChatTurnRPC). With HistoryOut nil the run keeps the legacy behavior
// of operating on the process-global history.
History []models.Message
HistoryOut *[]models.Message
}
RPCRunOpts parameterizes an agent/coder run driven over RPC.
type RPCSkillInfo ¶ added in v1.158.0
RPCSkillInfo describes one skill served as an MCP prompt.
type RPCToolInfo ¶ added in v1.158.0
type RPCToolInfo struct {
Name string // without the '@' prefix
Description string
Usage string
Schema string // the plugin's self-declared schema (JSON, free-form)
ReadOnly bool // capability metadata for a bare invocation
}
RPCToolInfo describes one plugin tool exposed over MCP/ACP.
type SessionCostData ¶ added in v1.99.0
type SessionCostData struct {
SessionID string `json:"session_id"`
SessionName string `json:"session_name,omitempty"`
StartTime time.Time `json:"start_time"`
LastUpdate time.Time `json:"last_update"`
ModelUsage map[string]*ModelUsageRecord `json:"model_usage"` // key: "provider:model"
TotalCostUSD float64 `json:"total_cost_usd"`
TotalRequests int `json:"total_requests"`
TotalTokens int64 `json:"total_tokens,omitempty"`
}
SessionCostData is the serializable snapshot of a cost tracking session.
func ListCostSnapshots ¶ added in v1.189.0
func ListCostSnapshots(limit int) ([]*SessionCostData, error)
ListCostSnapshots returns persisted snapshots, most recent first, capped at limit (0 = no cap). The current process's snapshot is included when it has been written.
func LoadCostSnapshot ¶ added in v1.189.0
func LoadCostSnapshot(sessionID string) (*SessionCostData, error)
LoadCostSnapshot reads one persisted snapshot by session id.
type SessionData ¶ added in v1.65.2
type SessionData = models.SessionData
SessionData is an alias for the shared models.SessionData type. Kept for local convenience within the cli package.
type SessionEncryptor ¶ added in v1.97.0
type SessionEncryptor struct {
// contains filtered or unexported fields
}
SessionEncryptor provides AES-256-GCM encryption for session files. Key is derived from the existing auth key (~/.chatcli/.auth-key) using HKDF.
func NewSessionEncryptor ¶ added in v1.97.0
func NewSessionEncryptor() (*SessionEncryptor, error)
NewSessionEncryptor creates an encryptor by deriving a key from the auth master key. If CHATCLI_ENCRYPTION_KEY env is set, uses that instead. Falls back to the auth key file at ~/.chatcli/.auth-key.
type SessionManager ¶ added in v1.23.0
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager gerencia o salvamento e carregamento de sessões de conversa.
func NewSessionManager ¶ added in v1.23.0
func NewSessionManager(logger *zap.Logger) (*SessionManager, error)
NewSessionManager cria uma nova instância do SessionManager.
func (*SessionManager) CleanExpiredMachineSessions ¶ added in v1.165.0
func (sm *SessionManager) CleanExpiredMachineSessions() int
CleanExpiredMachineSessions applies the TTL (CHATCLI_SESSION_TTL, default 90 days; "0" disables expiry entirely, honoring the documented contract) to MACHINE-created sessions only — autosaves and MCP session mirrors. User-named sessions are never expired: a checkpoint someone saved on purpose must outlive any retention policy. This is the lifecycle hook the boot paths call; the broader CleanExpiredSessions remains available for operators who explicitly want full expiry.
func (*SessionManager) CleanExpiredSessions ¶ added in v1.97.0
func (sm *SessionManager) CleanExpiredSessions() int
CleanExpiredSessions removes sessions older than the configured TTL (L6). Default TTL: 90 days, configurable via CHATCLI_SESSION_TTL (in days).
func (*SessionManager) DeleteSession ¶ added in v1.23.0
func (sm *SessionManager) DeleteSession(name string) error
DeleteSession apaga um arquivo de sessão.
func (*SessionManager) ForkCurrentToNew ¶ added in v1.97.0
func (sm *SessionManager) ForkCurrentToNew(newName string, sd *SessionData) error
ForkCurrentToNew creates a fork from in-memory session data (for forking unsaved sessions).
func (*SessionManager) ForkSession ¶ added in v1.97.0
func (sm *SessionManager) ForkSession(sourceName, newName string) error
ForkSession creates a copy of an existing session with a new name. The forked session is an independent copy — changes to either session don't affect the other.
func (*SessionManager) GetSessionMessages ¶ added in v1.164.0
func (sm *SessionManager) GetSessionMessages(name string, offset, limit int) ([]models.Message, int, error)
GetSessionMessages returns one page of a saved session's unified message stream plus the total count, so the @session tool can read an old conversation without loading it over the live one. offset is 0-based; limit <= 0 applies a default page size.
func (*SessionManager) LatestSessionInfo ¶ added in v1.167.0
func (sm *SessionManager) LatestSessionInfo() (name string, saved time.Time, title string)
LatestSessionInfo returns the newest saved session's name, save time and title, best-effort — a zero name means the store is empty or unreadable. Only the newest file is parsed, so this is cheap enough for the boot path.
func (*SessionManager) ListSessions ¶ added in v1.23.0
func (sm *SessionManager) ListSessions() ([]string, error)
ListSessions lista todas as sessões salvas.
func (*SessionManager) LoadSession ¶ added in v1.23.0
func (sm *SessionManager) LoadSession(name string) ([]models.Message, error)
LoadSession carrega o histórico de uma conversa de um arquivo JSON. Mantém assinatura original para compatibilidade com remote client. Retorna apenas o chatHistory para uso legado.
func (*SessionManager) LoadSessionV2 ¶ added in v1.65.2
func (sm *SessionManager) LoadSessionV2(name string) (*SessionData, error)
LoadSessionV2 carrega uma sessão completa com suporte a formato v2 e legacy.
func (*SessionManager) PruneSessionsByPrefix ¶ added in v1.165.0
func (sm *SessionManager) PruneSessionsByPrefix(prefix string, keep int) int
PruneSessionsByPrefix deletes the OLDEST sessions matching prefix beyond keep, ordered by file modification time (newest survive). Returns how many were removed. Safe on any cadence; missing dir is not an error.
func (*SessionManager) SaveSession ¶ added in v1.23.0
func (sm *SessionManager) SaveSession(name string, history []models.Message) error
SaveSession salva o histórico da conversa em um arquivo JSON. Mantém assinatura original para compatibilidade com remote client.
func (*SessionManager) SaveSessionV2 ¶ added in v1.65.2
func (sm *SessionManager) SaveSessionV2(name string, sd *SessionData) error
SaveSessionV2 salva uma sessão completa com históricos escopados.
func (*SessionManager) SearchSessions ¶ added in v1.123.0
func (sm *SessionManager) SearchSessions(query string, maxSnippetsPerSession int) ([]SessionSearchHit, error)
SearchSessions performs a ranked full-text search across all persisted sessions, reusing the existing JSON store (no separate index). Semantics, tuned for natural-language recall queries ("o que discutimos sobre X?"):
- Query terms are normalized (lowercase, accent-folded) and reduced to SIGNIFICANT terms — PT/EN stopwords and recall-framing verbs ("discutimos", "decided") carry no signal and used to disqualify every session under the old raw AND filter.
- A session QUALIFIES when every significant term appears somewhere in it — in ANY message, not necessarily the same one. When no session qualifies (or the query was all stopwords), the filter relaxes and BM25 ranks alone rather than returning nothing.
- Qualifying sessions RANK by BM25 over their individual messages (the same keyless scorer the knowledge corpus uses), with a bounded recency boost so yesterday's session outranks a months-old one when match quality is comparable. Snippets come from each session's top-scoring messages.
maxSnippetsPerSession caps how many context snippets each hit carries.
func (*SessionManager) SessionExists ¶ added in v1.179.0
func (sm *SessionManager) SessionExists(name string) bool
SessionModTime returns the store file's last-modified time for a saved session. It is the freshness signal for cross-surface continuity: a bound surface (REPL, MCP/ACP session, gateway principal) compares it against its own last sync stamp to decide whether another surface has written the session since, and reloads before the next turn when it has. SessionExists reports whether a saved session file exists under name. Invalid names report false — callers treat them as "nothing to load" and surface the validation error on the write path instead.
func (*SessionManager) SessionModTime ¶ added in v1.179.0
func (sm *SessionManager) SessionModTime(name string) (time.Time, error)
func (*SessionManager) SessionTitles ¶ added in v1.167.0
func (sm *SessionManager) SessionTitles() map[string]string
SessionTitles returns the stored title per session, best-effort ("" or a missing key means no title). Served from the cached search corpus, so callers can decorate listings without re-reading the store.
type SessionSearchHit ¶ added in v1.123.0
type SessionSearchHit struct {
Session string
Matches int
Score float64
Snippets []string
SavedAt time.Time // session file mtime; zero when unknown
Title string // stored session title; "" when absent
}
SessionSearchHit is one session that matched a search, with the strongest snippets for context.
type SkillClientResolution ¶ added in v1.100.0
type SkillClientResolution = client.ModelRoutingResolution
SkillClientResolution preserves the original type name used by the cli package. It is now just a re-export of the shared resolver struct.
type SkillHandler ¶ added in v1.66.0
type SkillHandler struct {
// contains filtered or unexported fields
}
SkillHandler handles /skill commands.
func NewSkillHandler ¶ added in v1.66.0
func NewSkillHandler(logger *zap.Logger, personaMgr *persona.Manager) *SkillHandler
NewSkillHandler creates a new skill handler with registry manager.
func (*SkillHandler) GetPinnedSkills ¶ added in v1.114.0
func (sh *SkillHandler) GetPinnedSkills() []*persona.Skill
GetPinnedSkills resolves every pinned name against the persona manager and returns the matching skills sorted alphabetically (stable order keeps the system-prompt injection block cache-friendly). Stale pins — skills that were uninstalled or renamed — are pruned silently from the set.
func (*SkillHandler) HandleCommand ¶ added in v1.66.0
func (sh *SkillHandler) HandleCommand(ctx context.Context, userInput string)
HandleCommand routes /skill subcommands.
func (*SkillHandler) Info ¶ added in v1.66.0
func (sh *SkillHandler) Info(ctx context.Context, name string, fromRegistry string)
Info shows metadata about a skill, checking local installed first, then registries. If fromRegistry is non-empty, only that registry is queried for remote metadata. The function is a thin orchestrator — each row of the output (name, description, version, …) is rendered by a focused helper so the function stays under the project's complexity budget and each row can be exercised independently in tests.
func (*SkillHandler) Install ¶ added in v1.66.0
func (sh *SkillHandler) Install(ctx context.Context, name string, fromRegistry string)
Install downloads and installs a skill from a registry. If fromRegistry is non-empty, only that registry is used. If multiple registries have the skill, the user is prompted to choose.
Supported invocations:
/skill install frontend-design → auto-detect or disambiguate /skill install frontend-design --from skills.sh → explicit registry /skill install anthropics/skills/frontend-design → skills.sh slug (unambiguous)
func (*SkillHandler) IsPinned ¶ added in v1.114.0
func (sh *SkillHandler) IsPinned(name string) bool
IsPinned reports whether the named skill is currently pinned. Used by /skill list to render the pin marker.
func (*SkillHandler) List ¶ added in v1.66.0
func (sh *SkillHandler) List()
List shows all installed skills.
func (*SkillHandler) Pin ¶ added in v1.114.0
func (sh *SkillHandler) Pin(name string)
Pin marks a skill to be auto-injected into every turn for the rest of the session, regardless of triggers/paths. Pinning is rejected for skills with `disable-model-invocation: true` (the flag exists precisely to forbid automatic injection; manual invocation via `/<skill-name>` remains the supported path for those).
func (*SkillHandler) PinnedNames ¶ added in v1.114.0
func (sh *SkillHandler) PinnedNames() []string
PinnedNames returns a snapshot of currently pinned skill names sorted alphabetically. Exposed for the completer.
func (*SkillHandler) Prefer ¶ added in v1.101.0
func (sh *SkillHandler) Prefer(args []string)
Prefer manages source preferences for skills with name conflicts. Usage:
/skill prefer → list all preferences /skill prefer frontend-design → show current preference /skill prefer frontend-design skills.sh → prefer the skills.sh version /skill prefer frontend-design local → prefer the local version /skill prefer frontend-design --reset → remove preference (use default order)
func (*SkillHandler) Search ¶ added in v1.66.0
func (sh *SkillHandler) Search(ctx context.Context, query string)
Search performs a fan-out search across all registries.
func (*SkillHandler) SetRegistryEnabled ¶ added in v1.101.0
func (sh *SkillHandler) SetRegistryEnabled(name string, enabled bool)
SetRegistryEnabled enables or disables a registry by name, persists the change, and hot-reloads the registry manager so the change takes effect immediately.
func (*SkillHandler) ShowHelp ¶ added in v1.66.0
func (sh *SkillHandler) ShowHelp()
ShowHelp displays usage information.
func (*SkillHandler) ShowPinned ¶ added in v1.114.0
func (sh *SkillHandler) ShowPinned()
ShowPinned lists all currently pinned skills for the session.
func (*SkillHandler) ShowRegistries ¶ added in v1.66.0
func (sh *SkillHandler) ShowRegistries()
ShowRegistries displays all configured registries.
func (*SkillHandler) Uninstall ¶ added in v1.66.0
func (sh *SkillHandler) Uninstall(name string)
Uninstall removes an installed skill. Supports both exact names ("anthropics-skills--frontend-design") and base names ("frontend-design"). When multiple installs match a base name, lists them and asks the user to specify which one to remove.
func (*SkillHandler) Unpin ¶ added in v1.114.0
func (sh *SkillHandler) Unpin(name string)
Unpin removes a skill from the pinned set. No-op (with a friendly notice) when the skill wasn't pinned to begin with.
type SlashToolEntry ¶ added in v1.118.0
type SlashToolEntry struct {
Name string // canonical slash form, e.g. "/help"
Description string // one-line, i18n-resolved
InputSchema string // JSON schema; can be empty for no-arg commands
Handler func(ctx context.Context, args map[string]any) (string, error)
// ReadOnly tells the orchestrator's partition policy whether this
// command can run in a concurrent batch with other read-only tools.
// /help, /version, /session list, /memory list are read-only.
// /context attach, /skill add are not.
ReadOnly bool
}
SlashToolEntry describes a slash command we expose to the LLM as a tool. The shape mirrors what the model needs to know about any tool: a stable name, a one-line description, a JSON schema for inputs, and the function that produces the output.
The LLM-visible name uses an `@cmd:` prefix (e.g. `@cmd:help`) so it can be discriminated in tool dispatch without colliding with the existing `@coder`/`@websearch` builtins or with MCP `mcp_*` tools. Users still type the unprefixed slash form (`/help`) at the prompt.
Handler receives the parsed input map (already JSON-decoded) and the invocation context, and returns the string to surface back to the LLM. Errors are surfaced via the second return value and mapped to IsError on the plugin side.
func AllSlashTools ¶ added in v1.118.0
func AllSlashTools() []*SlashToolEntry
AllSlashTools returns a deterministic snapshot of every registered entry, sorted by name. Used to seed the plugin manager.
func LookupSlashTool ¶ added in v1.118.0
func LookupSlashTool(name string) *SlashToolEntry
LookupSlashTool returns the entry for a canonical slash name (with or without the leading slash), or nil when not registered.
type SourceType ¶
type SourceType = agent.SourceType
CommandBlock and the other aliases below re-export the agent package types so legacy callers can continue to import them from cli without following the refactor chain.
type StatusCallback ¶ added in v1.104.0
type StatusCallback func(stage CompactStage, msg string)
StatusCallback is invoked by the compactor at the start/end of each level so callers can update spinners, status bars, or animation messages. It must be non-blocking and safe to call from any goroutine.
Source Files
¶
- acp_support.go
- agent_board_sync.go
- agent_coder_validation.go
- agent_command_blocks.go
- agent_context_block.go
- agent_earlyexit.go
- agent_events_bridge.go
- agent_feedback.go
- agent_helpers.go
- agent_mode.go
- agent_native_results.go
- agent_park.go
- agent_park_commands.go
- agent_park_directives.go
- agent_park_inline.go
- agent_plan_first.go
- agent_routing.go
- agent_side_commands.go
- agent_spinner_label.go
- agent_system_prompt.go
- agent_tool_sanitizer.go
- agent_typeahead.go
- agents_adapter.go
- agents_command.go
- agents_completer.go
- animation_manager.go
- board_adapter.go
- board_command.go
- board_completer.go
- channel_command.go
- channel_triggers.go
- channels_tool_adapter.go
- chat_ask.go
- chat_graphview.go
- chat_knowledge.go
- chat_memory.go
- chat_pipeline.go
- cli.go
- cli_commands.go
- cli_completer.go
- cli_completer_quality.go
- cli_config.go
- cli_file_processing.go
- cli_llm.go
- cli_rendering.go
- cli_session.go
- cli_session_autosave.go
- cli_session_binding.go
- cli_watcher.go
- coder_format_guard.go
- colors.go
- command_handler.go
- command_handler_connect.go
- command_handler_metrics.go
- command_handler_plugins.go
- command_handler_watch.go
- command_output_sanitizer.go
- commands_autoroute.go
- commands_integration.go
- compact_command.go
- compression_adapter.go
- config_agent_mutate.go
- config_chat_mutate.go
- config_commands_section.go
- config_compression_mutate.go
- config_env_defaults.go
- config_image_mutate.go
- config_memory.go
- config_output_mutate.go
- config_quality.go
- config_scheduler.go
- config_sections.go
- config_security_mutate.go
- config_selfevolve.go
- config_ui.go
- config_ui_mutate.go
- config_update.go
- context_adapter.go
- context_autorag.go
- context_display.go
- context_handler.go
- context_inspect.go
- context_io.go
- cost_budget.go
- cost_command.go
- cost_tracker.go
- doc.go
- env_redactor.go
- export_command.go
- gateway_command.go
- gateway_detach_unix.go
- gateway_events_sink.go
- gateway_runs_watcher.go
- gateway_runtime_model.go
- gateway_session_binding.go
- graph_command.go
- graphview_adapter.go
- history_compactor.go
- history_manager.go
- history_trimmer.go
- hooks_command.go
- hub_command.go
- hub_local.go
- hub_sync.go
- hyde_setup.go
- knowledge_adapter.go
- knowledge_graph.go
- lsp_command.go
- lsp_tool_adapter.go
- mail_adapter.go
- mail_command.go
- mail_completer.go
- mail_hub_bridge.go
- mcp_command.go
- mcp_dynamic_notice.go
- mcplogin_adapter.go
- memory_adapter.go
- memory_autorecall.go
- memory_bootstrap.go
- memory_command.go
- memory_mode.go
- memory_notice.go
- memory_pending.go
- memory_worker.go
- moa_adapter.go
- moa_command.go
- moa_turn.go
- mode_transition.go
- model_tool_adapter.go
- multiline.go
- oneshot_mode.go
- output_policy.go
- palette_bridge.go
- park_completer.go
- path_mentions.go
- payload_recovery.go
- persona_handler.go
- plan_command.go
- policy_adapter.go
- policy_command.go
- proc_tool_adapter.go
- prompts.go
- ratelimit_command.go
- refine_setup.go
- refine_verify_commands.go
- reflexion_setup.go
- rewind.go
- rpc_chat.go
- rpc_support.go
- rpc_support_full.go
- rpc_support_resources.go
- run_coordinator.go
- runs_hub_bridge.go
- scheduler_adapter.go
- scheduler_bridge.go
- scheduler_command.go
- scheduler_completer.go
- scheduler_http_probe.go
- scheduler_init.go
- scheduler_json.go
- selfevolve.go
- selfevolve_manifest.go
- selfevolve_merge.go
- selfevolve_parse.go
- send_adapter.go
- session_adapter.go
- session_autorecall.go
- session_encryption.go
- session_manager.go
- session_search_normalize.go
- signal_unix.go
- skill_activation.go
- skill_handler.go
- skill_invoke.go
- skill_model_resolve.go
- skill_rescan.go
- slash_tool_handlers.go
- slash_tool_registry.go
- stdin_cancel_other.go
- stdin_cbreak_unix.go
- stdin_ready_unix.go
- thinking_command.go
- todo_adapter.go
- tool_catalog.go
- tools_catalog_adapter.go
- tty_inject_linux.go
- tty_inject_unix.go
- ui_boxes.go
- update_command.go
- update_notice.go
- version_view.go
- vision_fallback.go
- websearch_command.go
- welcome.go
- wininput.go
- worker_context_tools.go
- worktree.go
Directories
¶
| Path | Synopsis |
|---|---|
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
ask
* ChatCLI - AskUser request/answer types and parsing.
|
* ChatCLI - AskUser request/answer types and parsing. |
|
lsp
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
mail
* Package mail is the squad's internal message bus: agents (and the user) * send short directed messages to each other, and each recipient drains its * inbox at the next safe turn boundary of its ReAct loop.
|
* Package mail is the squad's internal message bus: agents (and the user) * send short directed messages to each other, and each recipient drains its * inbox at the next safe turn boundary of its ReAct loop. |
|
moa
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
park
* Package park: durable snapshots for the agent ReAct loop.
|
* Package park: durable snapshots for the agent ReAct loop. |
|
proc
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
quality/convergence
* ChatCLI - Convergence: per-scorer circuit breaker.
|
* ChatCLI - Convergence: per-scorer circuit breaker. |
|
quality/lessonq
* ChatCLI - Lesson Queue: idempotency key derivation.
|
* ChatCLI - Lesson Queue: idempotency key derivation. |
|
runs
* Package runs is the process-wide registry of live agent executions.
|
* Package runs is the process-wide registry of live agent executions. |
|
toolguard
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
trajectory
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
workers
* ChatCLI - Builtin agent model/effort metadata * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * Shared base struct providing Model() and Effort() for built-in workers.
|
* ChatCLI - Builtin agent model/effort metadata * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * Shared base struct providing Model() and Effort() for built-in workers. |
|
* Package agentevents defines the structured event surface the agent/coder * ReAct loop exposes to protocol frontends (ACP today; gateway/MCP later).
|
* Package agentevents defines the structured event surface the agent/coder * ReAct loop exposes to protocol frontends (ACP today; gateway/MCP later). |
|
* Package board is the squad's shared work board: a small kanban of cards * (backlog → doing → review → blocked → done) that the orchestrator LLM * manages autonomously via the @board tool and humans inspect via /board.
|
* Package board is the squad's shared work board: a small kanban of cards * (backlog → doing → review → blocked → done) that the orchestrator LLM * manages autonomously via the @board tool and humans inspect via /board. |
|
* ChatCLI - Denial Tracker * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * Tracks consecutive and total denials to prevent infinite permission prompting.
|
* ChatCLI - Denial Tracker * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * Tracks consecutive and total denials to prevent infinite permission prompting. |
|
* ChatCLI - Slash command catalog (resolution + fingerprint cache) * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Slash command catalog (resolution + fingerprint cache) * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
Package compress is ChatCLI's content-aware, reversible context-compression layer.
|
Package compress is ChatCLI's content-aware, reversible context-compression layer. |
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
Package imgcompress shrinks images before they are sent to vision-capable models, cutting upload bytes, latency and (for oversized images) the actual vision-token cost — keylessly, with the standard library only (no cgo, no golang.org/x/image, no network).
|
Package imgcompress shrinks images before they are sent to vision-capable models, cutting upload bytes, latency and (for oversized images) the actual vision-token cost — keylessly, with the standard library only (no cgo, no golang.org/x/image, no network). |
|
* ChatCLI - MCP Channel Manager * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * Production-grade push-message ring for MCP servers: * * - Bounded in-memory ring (Push / GetRecent / GetByChannel / Count) * keeps the working set hot and lock-friendly.
|
* ChatCLI - MCP Channel Manager * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * Production-grade push-message ring for MCP servers: * * - Bounded in-memory ring (Push / GetRecent / GetByChannel / Count) * keeps the working set hot and lock-friendly. |
|
triggers
* ChatCLI - MCP channel reactive triggers * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * The trigger engine turns inbound MCP channel messages into actionable * events for the CLI.
|
* ChatCLI - MCP channel reactive triggers * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * The trigger engine turns inbound MCP channel messages into actionable * events for the CLI. |
|
Go Multi-Agent - Metrics Display
|
Go Multi-Agent - Metrics Display |
|
Package outputpolicy reduces the tokens a model *generates* (the output side of the bill, complementary to the input/context compression in cli/compress).
|
Package outputpolicy reduces the tokens a model *generates* (the output side of the bill, complementary to the input/context compression in cli/compress). |
|
* ChatCLI - AskUser interactive overlay.
|
* ChatCLI - AskUser interactive overlay. |
|
* ChatCLI - Paste Detection * cli/paste/detector.go * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Paste Detection * cli/paste/detector.go * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |
|
* ChatCLI - Scheduler: append-only JSONL audit log.
|
* ChatCLI - Scheduler: append-only JSONL audit log. |
|
action
* AgentResume — fires when a parked agent's wait condition is satisfied * and the interactive ReAct loop should re-enter.
|
* AgentResume — fires when a parked agent's wait condition is satisfied * and the interactive ReAct loop should re-enter. |
|
builtins
* Package builtins wires the built-in condition evaluators and action * executors into a Scheduler.
|
* Package builtins wires the built-in condition evaluators and action * executors into a Scheduler. |
|
condition
* Package condition: built-in evaluators registry.
|
* Package condition: built-in evaluators registry. |
|
memory
* ChatCLI - Change notification for memory sub-stores * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * changeNotifier is the one-line "mark derived caches stale" seam each * sub-store embeds.
|
* ChatCLI - Change notification for memory sub-stores * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 * * changeNotifier is the one-line "mark derived caches stale" seam each * sub-store embeds. |
|
memory/eval
* ChatCLI - Long-term memory: retrieval evaluation harness.
|
* ChatCLI - Long-term memory: retrieval evaluation harness. |
|
threatscan
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0
|
* ChatCLI - Command Line Interface for LLM interaction * Copyright (c) 2024 Edilson Freitas * License: Apache-2.0 |