Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
b6291a4
Don't auto-detect language on bare code fences
tmlxrd Jun 1, 2026
c591857
feat(composer): add Ask / Execute mode selector
tmlxrd Jun 1, 2026
0f9e144
feat(ask): hard no-tools Ask via tools-restricted agent
tmlxrd Jun 1, 2026
cd12983
feat(ask): bridge Ask->Execute via chat.inject
tmlxrd Jun 1, 2026
be97f2a
fix(ask): fail-closed — refuse Ask when no tools-restricted agent
tmlxrd Jun 2, 2026
d962f09
feat(openrouter): add OpenRouter client for Ask mode, titles, and STT
tmlxrd Jun 2, 2026
60a96a4
feat(stt): speech-to-text mic in composer
tmlxrd Jun 2, 2026
8344226
feat(settings): split settings into pages + Voice & Ask section
tmlxrd Jun 2, 2026
c860b95
feat(work-mode): add Work Mode runtime via NanoClaw fork
tmlxrd Jun 2, 2026
d0fc112
feat(runtime): auto-start iclaw-runtime as sidecar with iClaw
tmlxrd Jun 2, 2026
c0d3fb0
feat(settings): list Work Mode in OpenRouter feature list
tmlxrd Jun 2, 2026
957eeca
fix(openrouter): correct Gemini model ID to google/gemini-2.0-flash-001
tmlxrd Jun 2, 2026
df2c221
fix(openrouter): use google/gemini-2.5-flash as default model
tmlxrd Jun 2, 2026
89ea377
fix(openrouter): disable extended thinking for Ask/title completions
tmlxrd Jun 2, 2026
6c5d446
fix(composer): persist mode selector per-chat instead of globally
tmlxrd Jun 2, 2026
e2dc88b
fix(work-mode): full routing pipeline — agent responds via SSE
tmlxrd Jun 2, 2026
224fb77
feat(work-mode): replace NanoClaw agent with model-agnostic tool-call…
tmlxrd Jun 2, 2026
9b8e3d0
fix(runtime): retry on EADDRINUSE instead of crashing
tmlxrd Jun 2, 2026
7228451
fix(work-mode): persistent session per chat + ignore aborted SSE errors
tmlxrd Jun 2, 2026
0d133a1
feat(work-mode): per-chat folder picker in composer
tmlxrd Jun 2, 2026
1d88903
fix(work-mode): remove setComposerMode override that caused TDZ error
tmlxrd Jun 2, 2026
1a7cb25
fix(work-mode): hide folders button properly with [hidden] selector
tmlxrd Jun 2, 2026
b23f822
feat(work-mode): native OS folder picker via Browse button
tmlxrd Jun 2, 2026
92e3523
feat(work-mode): browse-only folder picker, remove manual input
tmlxrd Jun 2, 2026
2cf172f
feat(work-mode): persist folders per project (or globally for no-proj…
tmlxrd Jun 2, 2026
641bc7f
feat(work-mode): remove Done button from folders modal
tmlxrd Jun 2, 2026
a1f1f6d
feat(composer): new layout — textarea top, toolbar bottom
tmlxrd Jun 2, 2026
c13ab4f
feat: Secure Mode + mode-aware composer placeholders
tmlxrd Jun 2, 2026
0f3dafb
feat(chat): update empty state tagline
tmlxrd Jun 2, 2026
297298f
fix(chat): empty state — center, lower, single line
tmlxrd Jun 2, 2026
1e42728
fix(composer): restore paperclip icon on attach button
tmlxrd Jun 2, 2026
3b9198c
feat(modes): reorder Ask→Work→Secure→Execute with plain-language desc…
tmlxrd Jun 2, 2026
a4c704d
fix(modes): remove trailing dots from descriptions
tmlxrd Jun 2, 2026
8ddd0f5
fix(modes): remove trailing dots from descriptions
tmlxrd Jun 2, 2026
8aeee91
fix(composer): remove ellipsis from mode placeholders
tmlxrd Jun 2, 2026
e87d7f0
fix(composer): remove dot from folders modal hint
tmlxrd Jun 2, 2026
20d1690
fix(modes): replace em dash with hyphen in descriptions
tmlxrd Jun 2, 2026
08c90d1
feat(folders-modal): move Browse button to top-right of header
tmlxrd Jun 2, 2026
c687fda
fix(modes): add space after hyphen in descriptions
tmlxrd Jun 2, 2026
25eae00
fix(secure-mode): run agent loop on host, tools execute in Docker
tmlxrd Jun 2, 2026
2c9cfca
feat(secure-mode): persistent workspace + per-message network toggle
tmlxrd Jun 2, 2026
f075d51
feat(work+secure): pass project name and facts as system prompt
tmlxrd Jun 2, 2026
971a043
feat(secure): workspace indicator bar with size + TTL cleanup
tmlxrd Jun 2, 2026
04add60
feat(secure): persistent sandbox workspaces, in-container browser, co…
tmlxrd Jun 2, 2026
f051d17
feat(work): per-folder read/write access + sandboxed run_command
tmlxrd Jun 2, 2026
839ce7a
fix(work): live folder-access changes, clearer listings, graceful 429
tmlxrd Jun 2, 2026
c521441
feat(secure): slim sandbox image + no-root self-install tools
tmlxrd Jun 2, 2026
eb9fe15
feat(chat): smooth typewriter streaming + sticky scroll
tmlxrd Jun 2, 2026
f4a4ac4
fix(work): recreate session on Work<->Secure mode switch
tmlxrd Jun 2, 2026
4741fe5
feat(memory): per-project skills + OpenRouter-first background sub-tasks
tmlxrd Jun 2, 2026
9be3eb7
feat(modes): Incognito (read-only, ephemeral) mode; remove Ask
tmlxrd Jun 2, 2026
dfa93ae
feat(incognito): immersive surface — hide chat list, delete & share
tmlxrd Jun 2, 2026
10961d0
feat(incognito): bottom-of-menu + divider, neutral look, exit ×
tmlxrd Jun 2, 2026
eb86cb2
fix(incognito): pad chat header so the exit × doesn't overlap the title
tmlxrd Jun 2, 2026
7653fa4
ui(modes): rename Secure→Sandbox, Execute→Full Power (labels only)
tmlxrd Jun 2, 2026
17bda45
feat(runtime): add edit_file, expose web_fetch in Work, add web_search
tmlxrd Jun 2, 2026
14a2376
fix(incognito): open a fresh surface instead of converting the curren…
tmlxrd Jun 2, 2026
fa7bfc1
feat(web_search): default to OpenRouter web search (no extra key)
tmlxrd Jun 2, 2026
6b75165
refactor(web_search): drop Brave/ICLAW_SEARCH_API_KEY support
tmlxrd Jun 2, 2026
2ae1579
feat(runtime): raise step limit (40, ICLAW_MAX_ROUNDS) + batching gui…
tmlxrd Jun 2, 2026
3d1da2c
feat(dev): ICLAW_DEV_MODE — show token usage per runtime message
tmlxrd Jun 2, 2026
03519c1
feat(dev): chat-wide token total in the header
tmlxrd Jun 2, 2026
347ffc5
feat(dev): dump the exact model prompt per turn (ICLAW_DEV_MODE)
tmlxrd Jun 2, 2026
26cc2b2
perf(runtime): trim tool schemas + prompt, per-mode tools, cache visi…
tmlxrd Jun 2, 2026
4a0417f
perf(runtime): cap tool outputs (token saver step 1)
tmlxrd Jun 2, 2026
259e052
feat(runtime): read_summary + web_fetch summarize via a cheap model
tmlxrd Jun 2, 2026
657d223
perf(runtime): compact history by size too, not just message count
tmlxrd Jun 2, 2026
e77ae69
perf(runtime): mid-turn compaction — stub old tool outputs
tmlxrd Jun 2, 2026
ec6a188
fix(runtime): bake git into secure-sandbox image
tmlxrd Jun 2, 2026
4a25ab2
feat(runtime): header Stop for Work/Sandbox + analyze_link tool (WIP)
tmlxrd Jun 2, 2026
736b51f
feat(runtime): analyze_link in Work/Incognito via session container
tmlxrd Jun 3, 2026
a9cf8e2
runtime: OpenClaw token badge, single sandbox image, delete dead Nano…
tmlxrd Jun 3, 2026
bd7cafa
feat: show "saved N% cost" chat note when analyze_link summarizes a v…
tmlxrd Jun 3, 2026
6cfff03
Simplify savings note to plain, friendly language
tmlxrd Jun 3, 2026
418365a
Tweak savings note wording per request
tmlxrd Jun 3, 2026
0134939
Don't require OpenClaw to start a chat when an OpenRouter key is set
tmlxrd Jun 3, 2026
6a1148b
Fix project pick with gateway off + disable Full Power when OpenClaw …
tmlxrd Jun 3, 2026
882ab65
Fix Full Power gating: read gateway status from a source present on a…
tmlxrd Jun 3, 2026
a2909c6
Keep the mode switcher usable in the Full Power "OpenClaw off" state
tmlxrd Jun 3, 2026
39e8549
Cut agentic-loop token waste: prompt caching, tighter compaction, run…
tmlxrd Jun 3, 2026
8670046
Forward dropped files to Work/Secure + rebuild search_files on bundle…
tmlxrd Jun 3, 2026
1b61d38
Surface honest token-savings notes (read_file/run_command/read_summar…
tmlxrd Jun 3, 2026
e77862e
feat(onboarding): first-run welcome flow, conversational first chat, …
tmlxrd Jun 4, 2026
10e1e80
Remove OpenClaw gateway status badge from header
tmlxrd Jun 4, 2026
ea78765
Support Windows path translation in Work mode sandbox
tmlxrd Jun 4, 2026
6c6b38c
Gate chat modes on Docker readiness with an install flow
tmlxrd Jun 4, 2026
b48500e
Work Mode: normalized /work/<n> bind mounts + change scan
tmlxrd Jun 4, 2026
2083c72
Safe Mode: copy/clone sources into the sandbox
tmlxrd Jun 4, 2026
cc9c4ab
System-install policy: instruct, don't auto-change the host
tmlxrd Jun 4, 2026
2e7e2e0
Safe Mode: add Destroy sandbox button
tmlxrd Jun 4, 2026
89377cd
Safe Mode: spell out the copy-into-sandbox workflow in the prompt
tmlxrd Jun 4, 2026
0ed95ae
Safe Mode: ingest folders added mid-chat (incremental)
tmlxrd Jun 4, 2026
bfd7b11
Safe Mode: Export and Apply sandbox changes
tmlxrd Jun 4, 2026
73c9f8a
On-demand Docker: start when a task needs it, auto-stop when idle
tmlxrd Jun 5, 2026
d1696f3
Don't auto-start Docker during onboarding (fix untracked start)
tmlxrd Jun 5, 2026
0df8af7
Drop Docker jargon from the welcome screen
tmlxrd Jun 5, 2026
53acd3a
Run Work container as host user + scope reaping per install
tmlxrd Jun 5, 2026
5bed45d
Make Docker auto-stop survive runtime restarts (durable ownership)
tmlxrd Jun 5, 2026
d0c82a8
Stop iClaw-started Docker on graceful shutdown too
tmlxrd Jun 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
# OPENCLAW_BASE_URL=http://127.0.0.1:18789
# OPENCLAW_API_KEY=

# OpenRouter (voice messages, Ask mode, smart titles) is configured in the app
# under Settings → "Voice & Ask", not here — the key is stored in the local DB.

PORT=3000
# Default (when unset): ~/.iclaw/data/iclaw.db
# DB_PATH=./data/iclaw.db
Expand Down
22 changes: 21 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ These are intentional non-goals. Don't add them. If a request lands here that ne
- **Not a generic OpenAI-compat client.** We migrated off `/v1/chat/completions` in commit `a92c10e`. Do not re-introduce an HTTP chat completion path or SSE-based streaming — everything chat-related is native WS.
- **Not a multi-provider chat tool.** No fallback to Ollama, vLLM, Claude API, OpenAI direct, etc. OpenClaw is the only backend; switch model providers in `openclaw.json`.
- **Not a remote/hosted product.** Loopback-only. No multi-user, no auth layer, no team features. Threat model is "this user on this machine".
- **Not a re-implementation of OpenClaw's agent runtime.** We don't compact transcripts, run tools, manage `MEMORY.md`, or wrap the LLM. We display what the gateway produces and (separately) maintain a project-scoped fact layer that's *additional* to OpenClaw memory, not a replacement.
- **For the default Full Power chat, not a re-implementation of OpenClaw's agent runtime.** On that path we don't compact transcripts, run tools, or wrap the LLM — we display what the gateway produces and (separately) maintain a project-scoped fact layer *additional* to OpenClaw memory. (The Work / Safe work / Incognito modes are the deliberate exception — a small, self-contained agent loop in `packages/iclaw-runtime`; see below. Don't grow it into a general OpenClaw replacement.)
- **Not heavyweight on the frontend.** No build step beyond `tsc`. Plain CSS, vanilla JS on the client, EJS for views. If you want to add React/Vue/Svelte, open an issue first — the answer is probably no for the current scope.

## Architecture you need to know
Expand Down Expand Up @@ -62,6 +62,26 @@ These are intentional non-goals. Don't add them. If a request lands here that ne

Browser ↔ server is **one persistent WebSocket** at `/ws`. Chat traffic (send, abort, exec approval, streaming turn events, cross-tab sync) flows through it. HTTP routes exist for page rendering (EJS), form actions, the `/media/*` proxy, and JSON endpoints under `/api/gateway/*`. Every HTTP mutation that touches a chat also emits the matching `chat-updated` / `chat-deleted` over WS so other tabs catch up instantly.

### Runtime modes (Work / Safe work / Incognito)

The default **Full Power** mode goes to the gateway (above). The other three modes
are served by the bundled **iClaw runtime** (`packages/iclaw-runtime`), a small
agent runtime kept deliberately minimal:

- The host calls it over HTTP on `127.0.0.1:7430` (`src/services/workRuntime.ts` →
runtime `index.ts`). The model loop runs **on the host** via OpenRouter.
- Tool/shell execution is isolated in a **Docker sandbox**, one model per file:
`secure-runner.ts` (Safe work / Incognito — everything runs in a per-turn
container) and `work-container.ts` (Work — agent loop + file tools on the host,
only `run_command` containerized with per-folder `:ro`/`:rw` mounts). Both share
ONE image, `container/secure-sandbox.Dockerfile` (tag `iclaw-secure:latest`,
built via `npm run build:secure-image`); `node:22` is only an emergency fallback.
- The live runtime is just 9 files (`index.ts`, `sessions.ts`, `secure-runner.ts`,
`work-container.ts`, `agent/{loop,tools,security,prompt-dump}.ts`, `log.ts`).
Path/secret enforcement lives in `agent/security.ts`. Needs Docker + an
OpenRouter key; without either, these modes are unavailable and fall back to
Full Power. This is NOT the OpenClaw path — keep the two cleanly separate.

### The canonical client paths

| What you want | Use |
Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,30 @@ Hit **Share** in any chat to get an encrypted link. The chat is encrypted in you

Powered by [iClaw-cloud](https://github.com/iClawApp/iClaw-cloud) — defaults to `https://app.iclaw.digital`.

## Chat modes

The composer has a small mode selector. The selected mode is stored per message
(`messages.mode`) and rides the `frontend → WS → chatRunner` path. Missing/unknown
modes fall back to `execute`, so old chats and older clients keep working. Modes
are config-driven in [`src/services/chatModes.ts`](src/services/chatModes.ts) (the
catalog also lists disabled placeholders so new modes can be added without
touching call sites or the DB — the column is plain `TEXT`).

| Mode | What it does | Backend |
| --- | --- | --- |
| **Full Power** (default) | The full OpenClaw agent — files, tools, shell, browser. | OpenClaw Gateway |
| **Work** | AI edits files in folders you pick; you approve every change. | iClaw runtime |
| **Safe work & Internet research** | Locked Docker sandbox — run untrusted code and research the web, isolated from your system. | iClaw runtime |
| **Incognito** | Private, read-only research — reads files & the web, never writes, nothing saved. | iClaw runtime |

**Full Power** routes to the gateway exactly as before. The other three run on
the bundled **iClaw runtime** (`packages/iclaw-runtime`): the agent loop runs on
the host and reaches [OpenRouter](https://openrouter.ai), while tool/shell
execution is isolated in a per-turn Docker sandbox. They therefore need **Docker**
running and an **OpenRouter key** (Settings); without either they're unavailable
and the composer falls back to Full Power. See [AGENTS.md](AGENTS.md) for the
runtime architecture.

## Remote Access (alpha)

Open the iClaw UI from another device through an **iclaw-relay** tunnel (Settings → Remote Access).
Expand Down
Loading
Loading