| 2026-10-08 |

tools: list_tools defaults to the profile the run executes as
...
Asking "what tools do I have?" required the agent to know its own profile id
— and to be right about it after a switch_profile had moved the session. The
run knows: run_stream now publishes the active profile id (re-published when
switch_profile reloads the run) alongside the model, SubAgentRunner publishes
its own rather than inheriting the parent's, and ToolContext carries it into
every execute() call.
list_tools reads that when profile_id is omitted, so the bare call answers the
question, and it says which profile it assumed ("current profile") so the
answer cannot be mistaken for another profile's.
scope='agent'|'subagent' selects which of the profile's two toolsets to list —
the set spawn_agent would hand a sub-agent running that profile, which is a
different list and until now had no way to be inspected.
Item D of the list_tools plan, kept separate from the accuracy/compactness work.
Eugene Sukhodolskiy
committed
9 hours ago
|

tools: list_tools tells the truth and costs a tenth of the context
...
The tool read the profile config, not the registry: a tool the config declares
but nothing registered — mcp__navi_ui__render_component, whose server never
connects — was advertised as callable, and the agent walked into "tool not
found" (28 such warnings on prod). It now resolves every name against the live
registry and reports the rest separately as "Not registered", so a phantom
entry reads as a broken server, not as a tool to try.
It also returned every description it could find. For server_admin that was
125 tools and 35 316 bytes per call — ~9k tokens to answer "do I have anything
for ssh". Names are now grouped by source (native, then one section per MCP
server) with descriptions behind verbose, and query filters by substring over
names and descriptions: the ssh question costs 88 bytes instead of 35 KB, and
a plain listing drops to 3.7 KB (9.5x smaller).
Tests cover the phantom-tool case, query matching by name and by description,
and the size property that makes names-only the default.
Eugene Sukhodolskiy
committed
9 hours ago
|
| 2026-10-07 |
config: capture the live server configuration
...
Profiles gain the gntodo / gnexus-book / gnexus-creds scopes for agent and
subagent runs, refreshed model lists, and write access where the live setup
has it. MCP server configs pick up their user_key slots, gnexus-book learns
delete_pending_change, and the hard-panel / synapse / tgclient servers join
the tree.
root
committed
1 day ago
|
webclient: serve the PWA artwork past the images cache
...
/images/* is served cache-first from IMAGES_CACHE, which activate deliberately
keeps across builds. That is right for content whose URL is unique and wrong
for the app's own artwork: /images/icon-*, /images/logo-icon* and
/images/apple-splash/* keep their URLs while their contents change with the
logo, so a browser that had once loaded an icon would keep showing the old one
even after a deploy — and the apple-touch-icon is linked from index.html, so it
does travel through the page and the service worker.
Those paths now go network-first with a cached fallback (offline still works);
every other /images/ request is untouched.
Tests: frontend 148 passed; backend 1367 passed, 1 skipped.
Eugene Sukhodolskiy
committed
1 day ago
|

webclient: draw the PWA icons at full size again
...
The maskable icons and the apple-touch-icon carried the mark at 21% of the
canvas — the artwork scaled down and pasted in the centre — so on a home
screen the logo read as a fragment of itself. The mark takes 73.4% of the
canvas in logo.svg and in the launcher tile of the Android app icon; that is
the proportion all five files use now.
scripts/gen_pwa_icons.py redraws the mark from logo.svg's geometry with
Pillow (already a project dependency, no SVG rasterizer needed) and writes the
whole set, so the scale lives in one constant; --check measures what is on
disk and reports SUSPECT if it drifts again. Two runs produce identical bytes.
The regenerated icon-192/512 are geometrically identical to the rsvg-rendered
ones they replace: ink bbox 376x376 with 68px insets at 50% coverage, and the
same ink mass across the stroke. Only the antialiasing bytes differ.
dist/ rebuilt (it carries a copy of public/ and is served by the backend).
Tests: frontend 148 passed; backend 1367 passed, 1 skipped.
Eugene Sukhodolskiy
committed
1 day ago
|

MCP settings tab: list every connected server, slot only where declared
...
The tab was empty on every install: it listed only servers whose config
declares a `user_key` slot, and no config declared one — which read as
"no MCP servers connected" even though five are wired to profiles.
- GET /mcp-keys now returns every server referenced by at least one
profile, keyed ones first, with `accepts_user_key`, the slot location
(null when there is none) and the profile ids that connect it. The
per-user key store is skipped entirely when nothing has a slot.
- gnexus-creds declares `user_key: {header: Authorization, prefix:
"Bearer "}` — it is the one server carrying a shared credential, so its
personal-key field is now real: users with a key run under their own,
users without one fall back to the shared default.
- The panel lists all servers (transport + profiles), dims the keyless
rows, and shows a key input only for slotted ones, spelling out the
shared-key fallback.
docs/api.md and docs/mcp.md updated; backend 1367 passed, webclient 148.
Eugene Sukhodolskiy
committed
1 day ago
|
docs: fix stale VAPID env names (NAVI_VAPID_* -> NAVI_PUSH_VAPID_*, per config.py)
Eugene Sukhodolskiy
committed
1 day ago
|
mcp keys: tool-management tools aligned with BYOK (test_mcp_tool runs on user key, mcp_status marks key slots)
Eugene Sukhodolskiy
committed
1 day ago
|
docs: mcp.md (per-user MCP keys BYOK), /mcp-keys endpoints, user_key config
Eugene Sukhodolskiy
committed
1 day ago
|
| 2026-10-06 |
docs: synapse integration guide, special sessions filter, new endpoints
...
- docs/synapse.md: full guide — gateway, reaction runner pipeline,
notify tool, per-user settings, service sessions in the UI
- index/tools/config/api: entry point + built-in tools + env vars +
GET /sessions special param + synapse REST/webhook endpoints
Eugene Sukhodolskiy
committed
2 days ago
|
| 2026-10-05 |

webclient: Backgrounds tab in artifacts panel + task toasts
...
- new Backgrounds tab: task list (running first, badges, per-tool icons)
with a detail view (status, timestamps, sub-agent tokens, result/progress)
- GET /sessions/{id}/tasks snapshot endpoint: task_update events are not
replayed on reconnect, so the client fetches the task list on session
load/reload; live task_update entries are merged on top (chat.fetchTasks)
- terminal task_update no longer removes the entry — it marks it finished
so the tab shows recent completions; _terminalTaskIds still blocks
resurrection by a late running update
- toasts for background task start / finish (info / success / error) in
the WS dispatch; silent for other sessions and unknown terminal ids
- persistent background-tasks chip removed (replaced by the tab); only
the queued-messages chip stays
- fix invisible status text in terminal detail rows: filled .status-*
backgrounds now scope to .terminal-status-badge only
Eugene Sukhodolskiy
committed
3 days ago
|

background tasks: review fixes B1-B11 batch
...
- stop mid-batch cancels in-flight tools (B1) and keeps real results
of already-finished ones, mixing them with synthetic stopped notes
in call order (B2)
- queued messages: headless drain publishes session_sync (B4), the
run's teardown broadcasts session_sync to other sockets but not the
owner socket (prevents double reload) (B5)
- task_update notifications are chained per task so late running
updates can't overtake the terminal one (B7; client drops late
re-flicker of a terminal task chip) (B8)
- client: ui_component results reference the owning message via
card.parentMsg instead of a stale msg reference (B6)
- tasks cancel reports the real outcome after a bounded wait instead
of an optimistic 'cancelled' (B9)
- session delete cancels its running background jobs and drops
pending result notes (B10)
- subagent tool loop routes background:true calls through
ToolExecutor._maybe_background like the main loop (B11)
- tests for all of the above; docs/tasks.md stop/cancel semantics
Eugene Sukhodolskiy
committed
3 days ago
|
| 2026-09-26 |
e2e fixes: tasks tool in profiles, bg timeout lift, stepIcon fix, queue semantics docs
...
E2E findings addressed:
- tasks tool was registered but not in any profile's tools.agent.native —
added to all six profiles (agent could not check/wait/cancel bg tasks)
- detached terminal/code_exec/ssh_exec runs without explicit timeout are
lifted to 300s: foreground defaults (20/30/60s) marked long commands
'completed' with partial output while the process still ran
- ToolCard.vue: define stepIcon(status) — template referenced it but the
function was missing (render crash on task_update step)
- message_queued reachability documented: WS read loop is sequential, the
queue path is only reachable from a second socket/headless recall
Eugene Sukhodolskiy
committed
12 days ago
|
agent parallelism: background tools, bg spawn_agent, parallel tool batches, message queue
...
- backgroundable tools (terminal/ssh_exec/peer/spawn_agent/code_exec) detach
via TaskManager with per-session/global/spawn caps, rate limit and TTL
- completion delivery both ways: task_update event (out-of-band) + pending
notes injected into the next turn; tasks tool (list/check/wait/cancel)
- parallel tool-call batches (profile-level gate, off by default) with
ToolStarted up-front, tagged event mux, call-order results, one save,
plus dangling tool_call repair on session load
- user message queue instead of busy error: message_queued frame,
back-to-back drain on the same socket, headless fallback on disconnect
- pin mcp<2 (v2 renames FastMCP with breaking API changes)
- docs: tasks.md (new), websocket/api/agent/config updates, tasks manual,
spawn_agent background param, persona contract section
Eugene Sukhodolskiy
committed
12 days ago
|

PWA: installable webclient, offline shell, web push
...
Installability:
- public/manifest.webmanifest (standalone, theme #16161E) + PNG icons
generated from logo.svg (regular + maskable, served via /images mount)
- index.html: manifest link, theme-color, apple-touch-icon
Offline shell:
- hand-rolled sw.js (no workbox): navigation = network-first (3s race)
with cached-shell fallback + background refresh (a stale cached shell
would 404 on entry chunks after a deploy); /assets/* cache-first
(content-hashed); /images/* cache-first capped; /api,/ws,/auth,/push,
/content pass-through
- vite closeBundle plugin stamps __NAVI_BUILD_VERSION__ (digest of
index.html + asset names) into dist/sw.js; sw.js served no-store so
every deploy reactivates the SW and activation evicts old caches
- SW registration in main.js, PROD only (dev HMR untouched)
- OfflineBanner (useOnline composable) over the app shell
Web push (VAPID, pywebpush):
- navi/push/ package: push_subscriptions table (postgres, boot-time DDL),
PushSubscriptionStore, PushService (async fan-out, to_thread sends,
404/410 prunes dead endpoints, per-session cooldown)
- routes: GET /push/vapid-key, POST/DELETE /push/subscribe (auth-gated)
- trigger in orchestrator run_agent + run_recall: push on StreamEnd when
no WebSocket client watches the session; fire-and-forget, never
disturbs the run; anonymous fallback only when auth is off
- client: usePush composable + Notifications settings panel (enable/
disable via PushManager.subscribe with the server VAPID key)
- notification click focuses the app at /#<session_id> (hash routing
opens the right chat); payload body is a markdown-stripped <=140-char
preview
NAVIVAPID keys empty = push fully disabled (graceful, like other optional
integrations). dist/ artifacts committed per repo convention.
Tests: pytest push store/service/routes/trigger (+23), vitest usePush
(83 webclient tests green). Full suite 1143 passed.
Eugene Sukhodolskiy
committed
12 days ago
|

planning: fix LLM-output failure modes that killed every plan
...
Production planning_logs showed three ways a plan silently dies:
1. glm-5.3-flash wraps the whole answer in a structured envelope
(response:unknown{value:...}<tool_call|>) — the planner only knew the
gemma4 thought<channel|> artifact, so the wrapped analysis/plan failed
to parse. The stripper now unwraps response:<type>{value:...} envelopes,
including a truncated (unbalanced) one.
2. Empty content with spent completion tokens: glm on ollama-cloud puts
the whole answer in the thinking channel on some calls. Both planning
phases now fall back to thinking when content is empty; the debug log
records which channel served (source: content|thinking).
3. phase3_timeout at the shared 120s LLM_COMPLETE_TIMEOUT: planning now
has its own PLANNING_LLM_TIMEOUT_SEC (default 240).
Unit tests cover the envelope unwrap (balanced/truncated/inner braces),
the thinking fallback in both phases, and the clean-fail path.
Eugene Sukhodolskiy
committed
12 days ago
|
| 2026-09-10 |
swarm names: single female name (user preference; collisions fixed by hand)
Eugene Sukhodolskiy
committed
29 days ago
|
swarm names: two female names (Japanese/American/Spanish) instead of adjective-animal
...
Single names would collide across a swarm (peers are addressed by name),
a mixed pair like 'yuki-grace' or 'sofia-rin' gives 150x150 combinations.
Only affects NEW installs - existing instance.json names stay as they are.
Eugene Sukhodolskiy
committed
29 days ago
|
swarm stage 2: peer-to-peer channel — /peer endpoints + peer tool
...
Server side (navi/api/routes/peer.py, port 8099):
- GET /peer/hello — open discovery ping (name, uuid prefix, version)
- GET /peer/status — PSK; identity, uptime, machine facts, hive view
- POST /peer/ask — PSK; one-shot agent run under PEER_ASK_PROFILE
(default server_admin) answers, one concurrent ask at a time
- loop guard: answering agent runs without the peer tool (deterministic
recursion cut) + own-uuid asks refused with 409
- verify_swarm_key in navi/swarm.py accepts .swarm-key.previous
(rotation window, constant-time)
Client side (navi/tools/peer.py):
- peer tool: list (hive book, stale cache fallback marked), status,
ask by swarm name; asks go direct peer-to-peer, hive never on the
message path
- audit events on both sides (peer.ask_sent/received/answered/failed)
peer tool added to server_admin, navi_code, developer profiles.
Eugene Sukhodolskiy
committed
29 days ago
|
| 2026-09-09 |
swarm stage 1: instance identity, PSK, hive registry, announce loop
...
- navi/identity.py: adjective-animal names + uuid in instance.json
(generated at install, renameable by hand)
- navi/swarm.py: HiveAnnouncer - periodic POST /announce to the hive
with non-blocking reachability tracking (transitional logs, /health
export, hive_status context provider reports outages to the agent)
- hive/: standalone FastAPI address book (SQLite, port 8087, PSK via
X-Swarm-Key with .swarm-key.previous rotation window, TTL online
status, host from client IP, port from payload). Not installed or
started by default - run manually on the main server.
- ports moved to 8099 (API) / 8098 (UI MCP)
- install.sh: PYTHONIOENCODING=utf-8 in the systemd unit, generates
instance.json and .swarm-key on fresh installs
Eugene Sukhodolskiy
committed
29 days ago
|
port: 8000/8001 -> 8099/8098 everywhere
...
navi runs on shared servers where 8000/8001 are usually taken. New
defaults: API 8099, navi_ui MCP 8098. Touched: config defaults
(navi_port, navi_ui_mcp_port, public_url, gnauth_redirect_uri),
navi-server launcher docs, env.template/.env.example, install.sh
health-check fallback, terminal client base_url, webclient dev configs
(useWebSocket, contentLinks, vite proxy), android url hint, docs.
Also made the navi_ui FastMCP constructor port settings-driven instead
of a hardcoded 8001 (it was overridden at start anyway).
Eugene Sukhodolskiy
committed
29 days ago
|
deploy: one-command server bundle (dockerized postgres + systemd)
...
deploy/install.sh — everything in one command: prerequisite checks,
.env provisioning from env.template (generated DB password), dockerized
PostgreSQL (pgvector image, restart: always, bound to 127.0.0.1, vector
+ pg_trgm extensions), venv + pip install, a systemd unit with
Restart=always (the server lives from installation, per the roadmap
where these modules become each other's subagents), health check, and
navi-code/navi-server symlinks into PATH. Idempotent — safe to re-run.
Default deployed shape: web UI off, auth off, terminal client only.
Re-enabling the web panel later is editing .env + restart — nothing is
removed from the tree.
The deploy branch (next commit set) differs from master only by a
filled-in .env.
Eugene Sukhodolskiy
committed
29 days ago
|
docs: sync with the plan rework and compression pipeline
...
- planning: plan tool flow (agent-invoked, no pre-turn gate), confirmation
by COMPLEXITY, think=False + 20k-char Phase 1 window, retired flags
removed from profiles/api docs
- compression: all four triggers through compress_and_save_session,
real-baseline gates, head+tail summary input, _plan_compression shared
decision, actual config defaults (0.90 threshold, 6000 summary tokens,
32k input cap)
Eugene Sukhodolskiy
committed
29 days ago
|

security: critical batch 1 — RCE/XSS/CORS/webhook hardening
...
Backend:
- auth/deps: fix refresh-lock clock race (cleanup now monotonic like the cache)
- core/registry: add missing structlog logger (NameError on fallback path)
- config: GNAUTH_WEBHOOK_SECRET, NAVI_ALLOWED_ORIGINS (+list property)
- webhooks: HMAC-SHA256 signature verification (503 unconfigured in auth mode,
unsigned+warning in no-auth mode, 403 bad/stale signature, 400 bad JSON)
- main: CORS from NAVI_ALLOWED_ORIGINS in auth mode (fail-fast on empty),
eval router behind require_admin, /debug only registered in no-auth mode
- auth routes: mobile-done sid validation (32 hex) + CSP header + safe JS
escaping (reflected XSS); Secure cookie flag via helper (https base URL)
- websocket: anonymous WS rejected in auth mode (closes legacy-session RCE);
socket registered only after access checks; stop_session auth gate
- messages: REST agent start now takes session lock + busy flag (409 on
active run), contextvars reset in finally
Webclient:
- useMarkdown: DOMPurify.sanitize on all rendered markdown (stored XSS),
image-URL scheme whitelist, delegated error listener (no inline onerror)
- html.html artifact viewer: sandbox without allow-same-origin (opaque origin)
- tests: DOMPurify runs under jsdom (happy-dom Node.prototype.nodeName getter
breaks DOMPurify); useWebSocket tests get localStorage stub + ui-kit alias
Tests: pytest 1049 passed, 1 skipped; vitest 61 passed
Eugene Sukhodolskiy
committed
29 days ago
|
| 2026-07-13 |

terminal: session-broadcast sink + lifecycle events (Etap 1)
...
Persistent terminals emitted their stream only into a per-tool-call sink, which
closed once the open action returned — so a background dev server's output
stopped reaching the client immediately after open. TerminalClosed was never
emitted at all (the handler existed, the emitter did not).
Replace the per-tool event_sink with a single callback the orchestrator wires to
the session's WebSocket(s):
- TerminalManager: set_event_callback(cb) + _emit(session_id, event). Reader
tasks and open/close deliver TerminalOutputDelta / TerminalOpened /
TerminalClosed through the callback, which lives for the terminal's (and
session's) lifetime — not the tool call's.
- New TerminalOpened event (terminal_opened: name/description/pid/background).
TerminalClosed now actually emitted from _close_one (explicit/idle/shutdown/
session_ended). Background output keeps streaming after open returns.
- terminal.py: drop the per-tool event_sink from _tm.open (no longer needed).
- orchestrator._on_terminal_event → _notify_session (per-session WS fan-out,
same path recall/mcp updates use). container wires the callback after building
the orchestrator.
- Events imported lazily inside terminal_manager methods to avoid a circular
import (navi.core.events → navi.core.__init__ → agent → registry → navi.tools).
Tests: open emits TerminalOpened; background output streams via the callback
after open returns (gap-3 fix); close emits TerminalClosed; no callback does not
break readers. Existing terminal tests unchanged. Full suite: 968 passed, 1 skipped.
Plan: docs/terminal_tool_plan.md (5 etaps, this is Etap 1).
Eugene Sukhodolskiy
committed
on 13 Jul
|
docs: mark code-review findings as executed (5 etaps, 5 commits)
...
Status section at top + per-etap ✅ markers in the plan with commit ids.
932 → 953 passed (1 skipped). Not done by decision: 1.B2 (deferred, backend),
cosmetics/maintainability (left as working-but-no-user-value).
Eugene Sukhodolskiy
committed
on 13 Jul
|

tui: code-review Etap 1 — crash/injection/reconnect fixes + drop artifact renderer
...
Point fixes from the full TUI/terminal-client code review (docs/code_review_tui.md),
each with a covering test:
- command_palette: guard on_list_view_selected against IndexError when the
filter is empty and the placeholder row is selected.
- cli /profile: read session_id (not the absent "id") from the server — the
handler no longer KeyErrors.
- todo_list: escape task text/validation/index/milestone before interpolating
into rich markup so a task like "fix [bug]" no longer breaks the line styling.
- builtin /help: drop bold markup tags from status content — StatusRenderer
builds a literal Text() that would show the tags as literal square brackets.
- tui_app on_user_submitted: always enqueue when a bridge exists (the input loop
buffers across reconnect) instead of dropping the message on connected=False.
- chat_model stream_start: also reset _current_thinking so a dropped turn (no
thinking_end) does not glue the next turn's reasoning onto the old block.
- todo renderer update: coerce validation to str before .strip() so a non-string
JSON value does not AttributeError.
- renderers: remove the unused ArtifactRenderer (no production path emits
type=artifact — TUI shows files via the OS); keep the diff renderer test.
Full suite: 937 passed, 1 skipped.
Eugene Sukhodolskiy
committed
on 13 Jul
|
| 2026-07-12 |

permissions: remove broken client-side gate; add backend design doc
...
The terminal-TUI permission gate was a race: _execute_tools_with_sink
emits ToolStarted and starts the tool on the backend immediately, so by
the time the client dialog appeared the destructive action had already
run -- 'deny' could only stop the session, not un-execute the tool. It
also existed only in the terminal TUI (webclient/android had nothing),
and the system-prompt 'Strict Confirmation' nudge was an unreliable
duplicate.
Remove the broken machinery for a clean slate and plan the real
replacement from zero:
- delete clients/terminal/tui/permissions.py, screens/permission_dialog.py
and their tests
- strip tui_app.py (engine, _deny_tool, _show_permission_dialog,
_confirm_shell_command, _stop_session_worker, on_permission_request,
tool_started gate) and the PermissionRequest TUI event; !cmd now runs
directly (user-typed, no agent gate)
- drop the 'Strict Confirmation' prompt rule from navi_code/developer/
tool_developer
- add docs/permissions.md: authoritative backend gate design (engine +
registry + event + endpoint + agent gate + postgres policy + global
rules config, sub-agents gated) -- design only, not yet implemented
- update docs/index.md, navi_code_cli.md, profiles.md, testing.md
Until Phase 1 lands there is no destructive-action confirmation -- a
conscious period without the false security of the old race-gate.
Eugene Sukhodolskiy
committed
on 12 Jul
|

docs: index, profiles, tools, api actualization + archive historical docs
...
index.md: expand the file map to reference navi_code, navi_code_cli, store,
context_providers, eval_system, android-client, testing; point at archive/
for historical notes.
profiles.md: add the Compression section (compression_keep_recent /
compression_max_tokens / compression_prompt_file overrides), the
subagent_system_prompt field, and a note that AgentProfile allows unknown
keys (model_config extra=allow).
tools.md: rewrite the user-tools self-extension section — write_tool is
deprecated and removed; write the file via filesystem/code_exec and call
reload_tools instead.
api.md: add missing REST endpoints (GET /sessions/{id}/todos, GET
/sessions/{id}/files list, GET /sessions/{id}/messages/archive, POST
/sessions/{id}/stop) and the admin MCP management block (config CRUD,
reconnect, status, test, profile-mcp mapping, admin recalls); fix the
WS client→server table (type: message|compact, image limits 8/50MB);
add model_info / todo_updated / compression_started events; fix
recall_update action (add skipped), session_sync payload, context_compressed
threshold (70%).
Archive: move plan_01_god_object_agent.md, tech_debt_review_2026-04-29.md,
architecture_weak_spots.md, future_headless_nodes.md into docs/archive/
(historical design notes, no inbound links).
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 12 Jul
|

docs(navi-code-cli): actualize TUI to current code
...
Rewrite the TUI section for the post-Jul-10 feature avalanche:
- Layout: five regions (ChatPanel + Vertical(StatusPanel, TodoPanel) +
InputBox + bottom StatusBar); SessionsPanel removed, sessions via modal
picker. StatusPanel now shows Profile/Session/Model/Connection/Backend/
Theme/hint (no Tokens/Iter).
- StatusBar: activity indicator + live elapsed timer + context-fill gauge.
- TodoPanel: live, sorted (in_progress → pending → failed/skipped → done),
subagent-isolated.
- Per-message widgets, markdown rendering, bounded history render cost,
session history load on resume, WebSocket auto-reconnect.
- Slash-command hints (Up/Down/Enter/Tab), command palette (Ctrl+P),
permission dialog, !shell passthrough, @file refs.
- Compression summary card, request-duration metadata, model_info display.
- Keybindings table (Ctrl+P / Ctrl+X C|T|Q / Esc).
- Commands: add aliases (clear, resume/continue, exit/q, save); fix /clear
(alias of /new), /sessions (picker), /switch (hybrid); add /compact.
- --resume <session_id> flag + post-exit resume hint.
- Full event rendering list (stream_start/end/stopped, model_info,
todo_updated, compression_started, context_compressed, …).
- Full file map (ws_bridge, chat_model, screens/, permissions, shell_runner,
file_refs, duration, …).
navi_code.md left as-is (already current with bounded autonomy).
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 12 Jul
|