Slicc CLAUDE.md
A browser-native AI agent (claw) for everyone that loves ice cream
> Sourced from [ai-ecoverse/slicc](https://github.com/ai-ecoverse/slicc) β [Apache-2.0](https://github.com/ai-ecoverse/slicc/blob/a3a551da51e9dc0578af1b2ad4c1d2186eea08f6/packages/webapp/CLAUDE.md).
# CLAUDE.md
This root file is the repo navigation hub. Keep package-specific architecture and implementation detail in the nearest package `CLAUDE.md`, and keep fast-changing how-to material in `docs/`.
## Module Map
### Packages
| Path | Purpose |
| ----------------------------- | ------------------------------------------------------------------------------------ |
| `packages/webapp/` | Browser app core: UI, VFS, shell, CDP, tools, providers, skills, scoops |
| `packages/chrome-extension/` | Manifest V3 extension entry points, HTML shells, and message bridges |
| `packages/cloudflare-worker/` | Tray hub worker for session coordination, signaling, and TURN credentials |
| `packages/node-server/` | Node.js CLI/Electron server: Chrome launch, CDP proxy, dev serving |
| `packages/vfs-root/` | Default VFS content copied into the app on init/reset |
| `packages/swift-launcher/` | Native macOS SwiftUI launcher app (`Sliccstart`) |
| `packages/swift-server/` | Native macOS Hummingbird server (`slicc-server`) |
| `packages/dev-tools/` | Repo-level tooling guidance for build helpers, QA setup, configs, and test utilities |
| `packages/assets/` | Shared static files (logos, fonts, favicon) used by multiple packages |
### Other Top-Level Directories
| Path | Purpose |
| ------------------- | ----------------------------------------------------------------------------------------- |
| `docs/` | Long-form developer and agent reference docs, including screenshots and other docs assets |
| `packages/*/tests/` | Per-package TypeScript/Vitest tests mirrored by subsystem |
| `dist/` | Generated build output; do not hand-edit |
## Top-Level Commands
```bash
npm install # Install dependencies (first time)
npm run build # Production build (all workspaces)
npm run build -w @slicc/webapp # UI-only build (faster for UI changes)
npm run build -w @slicc/chrome-extension # Chrome extension build into dist/extension/
npm run test # Vitest run
npm run typecheck # Browser + Node typecheck
npm run dev # Dev mode with Vite HMR + Chrome + CDP
```
For runtime-specific commands, use the nearest guide:
- [`packages/webapp/CLAUDE.md`](packages/webapp/CLAUDE.md)
- [`packages/chrome-extension/CLAUDE.md`](packages/chrome-extension/CLAUDE.md)
- [`packages/cloudflare-worker/CLAUDE.md`](packages/cloudflare-worker/CLAUDE.md)
- [`packages/node-server/CLAUDE.md`](packages/node-server/CLAUDE.md)
- [`packages/vfs-root/CLAUDE.md`](packages/vfs-root/CLAUDE.md)
- [`packages/swift-launcher/CLAUDE.md`](packages/swift-launcher/CLAUDE.md)
- [`packages/swift-server/CLAUDE.md`](packages/swift-server/CLAUDE.md)
- [`packages/dev-tools/CLAUDE.md`](packages/dev-tools/CLAUDE.md)
- [`docs/CLAUDE.md`](docs/CLAUDE.md)
## External Handoffs
In this repo, phrases like `handoff to slicc` or `move this to slicc` mean:
- compose a verb-prefixed instruction: `handoff:<free text>` or `upskill:<github url>`
- open `https://www.sliccy.ai/handoff?msg=<urlencoded>` in the local browser
- the cloudflare-worker serves that URL with an `x-slicc: <msg>` response header
- SLICC observes the header on main-frame navigations via a `navigate` lick and shows an approval prompt to the user
Prefer the helper in `.agents/skills/slicc-handoff/scripts/slicc-handoff` when it exists.
## Cross-Cutting Principles
### Philosophy
1. **The Claw Pattern**: SLICC is a persistent orchestration layer over LLM agents, centered in the browser.
2. **Agents Love the CLI**: Prefer shell commands and composable command surfaces over bespoke tools.
3. **The Browser is the OS**: Keep state client-side and use server code only for work browsers cannot do themselves.
### Ice Cream Vocabulary
- **Cone**: the main agent.
- **Scoops**: isolated sub-agents with sandboxed filesystems.
- **Licks**: external events such as webhooks or cron tasks.
- **Floats**: runtime environments such as CLI, extension, Electron, and cloud.
Use the ice cream terms in code review comments and docs when they match the domain.
## Git Conventions
- Keep commits focused and package-local when possible.
- Do not hand-edit generated output in `dist/`.
- Webapp git behavior is implemented with `isomorphic-git` over LightningFS.
- Auth uses `git config github.token <PAT>`.
- Network behavior differs by runtime: CLI routes git/fetch traffic through `/api/fetch-proxy`; the extension uses direct fetch.
**Requires Node >= 22** (LTS). Ports: 5710 (UI), 9222 (Chrome CDP), 9223 (Electron CDP). Vite HMR shares the UI server via `/__vite_hmr`.
### Parallel Instances
Multiple standalone SLICC instances can run simultaneously. All ports auto-resolve to avoid conflicts β just override the UI port:
```bash
PORT=5720 npm run dev # Second instance on port 5720
PORT=5730 npm run dev # Third instance on port 5730
```
Each instance gets an isolated Chrome profile (keyed by port) and separate CDP port (auto-detected). HMR shares the UI server. No shared state between instances.
## Philosophy
1. **The Claw Pattern**: SLICC is a persistent orchestration layer ("claw") on top of LLM agents, running in the browser. Agent engine is [Pi](https://github.com/badlogic/pi-mono) (pi-agent-core, pi-ai).
2. **Agents Love the CLI**: Shell-first core β new capabilities should be shell commands, not dedicated tools. MCP burns context tokens; CLI tools compose naturally.
3. **The Browser is the OS**: All logic/state runs client-side. Server is a stateless relay. Prefer browser-native APIs (IndexedDB, Service Workers, WASM, fetch).
## Principles
1. **Virtual CLIs over dedicated tools** β Shell commands first. Only create dedicated tools if bash can't do it.
2. **Browser-first** β State in IndexedDB. Server only does what browsers physically cannot.
3. **Minimal server** β Extension float has zero server. That's the target.
4. **Skills over hardcoded features** β New agent capabilities should be SKILL.md files, not code changes.
## Concepts (Ice Cream Vocabulary)
- **Cone**: Main agent ("sliccy"). Full filesystem access, all tools. Code: `orchestrator.ts`, `RegisteredScoop` with `isCone: true`.
- **Scoops**: Isolated sub-agents with sandboxed filesystem (`/scoops/{name}/` + `/shared/`), own shell/conversation. Tools: `scoop_scoop`, `feed_scoop`, `drop_scoop`. Code: `scoop-context.ts`, `restricted-fs.ts`.
- **Licks**: External events triggering scoops (webhooks, cron tasks). Code: `LickManager`, `LickEvent`. Shell: `webhook`, `crontask`.
- **Floats**: Runtime environments β CLI (`packages/node-server/src/`), Extension (`packages/chrome-extension/src/`), Electron (`packages/node-server/src/electron-main.ts`), Sliccstart (`packages/swift-launcher/` β native macOS launcher), Cloud (planned).
Use ice cream terms over technical jargon (e.g., "feed_scoop" not "delegate_to_scoop").
## Architecture
Browser-based AI coding agent running as Chrome extension (side panel), standalone CLI server, or Electron float.
### Three Deployment Modes
- **Chrome extension** (Manifest V3): Three-layer β side panel (UI), service worker (relay + CDP proxy), offscreen document (agent engine). Agent survives side panel close.
- **Standalone CLI**: Express server launches Chrome, proxies CDP. Split layout with scoops + chat + terminal + files/memory.
- **Electron float**: Reuses CLI server in `--serve-only` mode, injects overlay shell.
### Layer Stack
```
Virtual Filesystem (packages/webapp/src/fs/) β RestrictedFS β Shell (packages/webapp/src/shell/) + Git (packages/webapp/src/git/)
β CDP (packages/webapp/src/cdp/) β Tools (packages/webapp/src/tools/) β Core Agent (packages/webapp/src/core/)
β Scoops Orchestrator (packages/webapp/src/scoops/) β UI (packages/webapp/src/ui/)
β CLI/Electron (packages/node-server/src/) | Extension (packages/chrome-extension/src/)
```
### Build Targets
- **Browser bundle** (tsconfig.json): Everything except `packages/node-server/src/`. Bundled by Vite.
- **CLI/Electron** (tsconfig.cli.json): Only `packages/node-server/src/`. Compiled by TSC to dist/node-server/.
- **Extension** (packages/chrome-extension/vite.config.ts): Browser bundle + extension entry points + bundled Pyodide.
### Key Subsystems
**Orchestrator** (`packages/webapp/src/scoops/orchestrator.ts`): Creates/destroys scoops, routes messages, manages VFS. Cone delegates via `feed_scoop` β scoops get complete self-contained prompts (no access to cone's conversation). Exposes `observeScoop(jid, handler)` for per-scoop event taps (observers are dropped defensively on both `unregisterScoop` and `destroyScoopTab`). `agent-bridge.ts` publishes `globalThis.__slicc_agent` β the shell-facing surface used by the `agent` supplemental command to spawn ephemeral one-shot sub-scoops with `notifyOnComplete: false` (no cone turn on completion). Extension float proxies the bridge from the side panel to the offscreen agent engine via `chrome.runtime` messages.
**VirtualFS** (`packages/webapp/src/fs/`): POSIX-like async FS backed by LightningFS (IndexedDB). `RestrictedFS` wraps it with path ACLs for scoops. `FsError` carries POSIX error codes.
**Mount backends** (`packages/webapp/src/fs/mount/`): `LocalMountBackend` (FS Access), `S3MountBackend`, `DaMountBackend` are **signing-naive** in the browser bundle β they construct logical requests and call an injected `SignedFetch*` transport. The transport routes to `/api/s3-sign-and-forward` / `/api/da-sign-and-forward` (CLI; node-server resolves credentials, signs SigV4, forwards) or to `chrome.runtime.sendMessage` (extension; service worker reads `s3.<profile>.*` from `chrome.storage.local`, signs, forwards via `host_permissions: <all_urls>`). The agent never holds S3 credentials in either deployment. The IMS bearer token for DA flows transiently in the envelope; v2 will move that OAuth flow server-side too.
**Shell** (`packages/webapp/src/shell/`): WasmShell wraps just-bash 2.14.3 (WASM). 78+ commands including `git`, `node -e`, `python3 -c`, `playwright-cli`, `open`, `serve`, `sqlite3`, `convert`, `pdftk`, `skill`, `upskill`, `webhook`, `crontask`, `mount` (local + S3 / S3-compatible / DA via `--source`), `oauth-token`, `debug`, `agent` (spawn a one-shot sub-scoop via AgentBridge β shell surface for scoop delegation from any float). Any `*.jsh` file on VFS is auto-discovered as a command. Extension CSP workaround: dynamic code routes through `sandbox.html`. **Two shell contexts in extension mode**: side panel has its own WasmShell (mounted in terminal tab), offscreen document has the agent's WasmShell (runs bash tool calls). Commands that affect the UI must handle both β use `window.__slicc_*` hooks for direct calls (panel) and `chrome.runtime.sendMessage` relay for offscreenβpanel communication.
**CDP** (`packages/webapp/src/cdp/`): `CDPTransport` interface with WebSocket (CLI) and `chrome.debugger` (extension) implementations. `BrowserAPI` provides Playwright-style API (listPages, navigate, screenshot, evaluate, click, etc.). Screenshots normalize DPR to 1.
**Tools** (`packages/webapp/src/tools/`): Active tool surface: `read_file`, `write_file`, `edit_file`, `bash`, plus NanoClaw tools (`send_message`, cone-only: `list_scoops`, `scoop_scoop`, `feed_scoop`, `drop_scoop`, `update_global_memory`). Browser automation goes through shell commands via `bash`.
**Core Agent** (`packages/webapp/src/core/`): Uses pi-agent-core for agent loop, pi-ai for LLM streaming. `tool-adapter.ts` bridges legacy ToolDefinition to pi-compatible AgentTool. `SessionStore` persists conversations to IndexedDB.
**Context Compaction** (`packages/webapp/src/core/context-compaction.ts`): LLM-summarized compaction at ~183K tokens. Images auto-resized before LLM (5MB base64 limit). Overflow recovery replaces oversized messages (>40K chars) with placeholders.
**UI** (`packages/webapp/src/ui/`): Vanilla TypeScript, no framework. Extension mode: compact tabbed interface (Chat + Files visible by default; Terminal + Memory hidden β toggle with `debug on`). Standalone: resizable split layout with all panels visible. `main.ts` delegates to `mainExtension()` (OffscreenClient) or bootstraps Orchestrator directly. Tab bar is fully dynamic β `TabZone.addTab()`/`removeTab()` adds/removes tabs at runtime (used by sprinkle panels and the `debug` command).
**Extension** (`packages/chrome-extension/src/`): Service worker relays messages + proxies chrome.debugger. Offscreen document runs agent engine (survives side panel close). Chat persistence: `browser-coding-agent` IndexedDB is single source of truth. **Key architecture detail**: the extension has two separate execution contexts with independent shell instances β the side panel (UI, terminal shell, Layout) and the offscreen document (agent engine, bash tool shell, Orchestrator). They share IndexedDB but NOT window globals. Communication is via `chrome.runtime` messages routed through the service worker. See `docs/architecture.md` "Extension Three-Layer Architecture".
**Preview SW** (`packages/webapp/src/ui/preview-sw.ts`): Intercepts `/preview/*` requests, serves VFS content. Built as IIFE via esbuild (not rollup β avoids code-splitting issues in SWs).
**Sprinkle Rendering** (`packages/webapp/src/ui/sprinkle-renderer.ts`): Renders `.shtml` files as interactive UI panels. CLI mode: fragments injected into DOM directly, full documents rendered via srcdoc iframe. Extension mode: ALL content routes through `sprinkle-sandbox.html` (CSP-exempt manifest sandbox) β fragments rendered in sandbox body, full documents via nested srcdoc iframe inside sandbox. See the sprinkles skill (`packages/vfs-root/workspace/skills/sprinkles/`) for rendering modes, bridge API, and style guide.
**Dips** (`packages/webapp/src/ui/dip.ts`): Agent ` ```shtml ` code blocks in chat messages are hydrated into sandboxed iframes after streaming completes. Minimal bridge (lick-only, no state) via postMessage. Auto-height via ResizeObserver. CLI mode: direct srcdoc iframe. Extension mode: routes through `sprinkle-sandbox.html` (same CSP-exempt sandbox as panel sprinkles). Lick events route to the cone via `routeLickToScoop` (CLI) or `client.sendSprinkleLick` (extension). CSS: `.msg__dip` container, `.sprinkle-action-card` component.
**Skills** (`packages/webapp/src/skills/`, `packages/webapp/src/scoops/skills.ts`): native `/workspace/skills/` packages auto-load into the system prompt alongside accessible compatibility skills discovered from `.agents/skills/*/SKILL.md` and `.claude/skills/*/SKILL.md` anywhere in the reachable VFS. Only native `/workspace/skills/` entries are install-managed; compatibility roots stay read-only.
### Data Flow
```
User β ChatPanel β Orchestrator β ScoopContext.prompt() β pi-agent-core β LLM API
β Tool calls β RestrictedFS / WasmShell / BrowserAPI β results β back to agent loop
β Scoop completes β Orchestrator β Cone's message queue
```
### Tray / Teleport Addendum
- Tray hub code lives in `packages/cloudflare-worker/src/` with config in `wrangler.jsonc`; treat it as coordination infrastructure, not canonical session storage.
- When a tray is connected, remote browser targets are exposed through federated target routing; keep CDP local to the runtime that owns the page.
- Teleport is part of the browser/shell workflow: `playwright teleport --start=<regex> --return=<regex>` and equivalent flags on `open`, `tab-new`, and navigation commands.
- Any `*.bsh` file is a browser-navigation helper. Keep detailed behavior in docs rather than growing this root guide.
## Key Conventions
- **Two type systems**: Legacy ToolDefinition (`packages/webapp/src/tools/`) and pi-compatible AgentTool (`packages/webapp/src/core/`). Bridged by `tool-adapter.ts`.
- **Tests**: `packages/*/tests/` mirrors the `src/` structure. Vitest, globals: true, environment: node. Use `fake-indexeddb/auto` for VFS tests.
- **Logging**: `createLogger('namespace')` from `packages/webapp/src/core/logger.ts`. DEBUG in dev, ERROR in prod.
- **Extension detection**: `typeof chrome !== 'undefined' && !!chrome?.runtime?.id`
- **Dual-mode compatibility**: Features MUST work in both CLI and extension. Extension CSP blocks eval/CDN β use `sandbox.html` for dynamic code, `sprinkle-sandbox.html` for sprinkles/inline widgets, `chrome.runtime.getURL()` for bundled assets.
- **Extension `window.open()` returns `null`**: Fire-and-forget; don't treat null as failure.
- **Model ID aliases**: Use pi-ai aliases (e.g., `claude-opus-4-6`) not dated snapshot IDs.
- **Provider composition**: Auto-discovered from pi-ai. External providers: drop `.ts` in `packages/webapp/providers/`. OAuth via `createOAuthLauncher()` in `packages/webapp/src/providers/oauth-service.ts`. Registration runs in both `main.ts` and `offscreen.ts`. Providers can override model capabilities via `modelOverrides` (static) or `getModelIds()` metadata (dynamic). Three-layer merge: pi-ai β modelOverrides β getModelIds. OpenAI-compatible models route through `streamOpenAICompletions` when `api: 'openai'` is set in metadata.
- **Two CLAUDE.md files**: This one (project root) is for Claude Code. `packages/vfs-root/shared/CLAUDE.md` is for the agent (bundled to `/shared/CLAUDE.md`).
- **Default VFS content**: `packages/vfs-root/` bundled into VFS via `import.meta.glob`.
- **Preview URLs**: Use `toPreviewUrl(vfsPath)` from `packages/webapp/src/shell/supplemental-commands/shared.ts`.
## Change Requirements
Every change must satisfy **tests**, **docs**, and **verification**.
### Tests
- Add or update tests for behavior changes.
- TypeScript tests live in `packages/*/tests/`, mirrored by subsystem.
- See `docs/testing.md` for patterns and command selection.
- **Coverage thresholds are enforced in CI** for every package. New code
must keep coverage at or above the current floor β CI fails if any of
the tracked metrics drops below the threshold for that package.
- **TypeScript packages**: `vitest --coverage` (v8 provider). Run
`npm run test:coverage:<package>` locally; CI runs the same script
as the package's only test step. Per-package floors:
- `cloudflare-worker`: 75% lines/statements, 65% branches, 85% functions
- `node-server`: 65% lines/statements/functions, 55% branches
- `chrome-extension`: 55% lines/statements, 45% branches, 60% functions
- `webapp`: global default 50% lines/statements/functions, 40% branches
- **Swift packages**: `swift test --enable-code-coverage` plus
`xcrun llvm-cov report` via
`packages/dev-tools/tools/swift-coverage-check.sh`. Tests/.build
paths are excluded; the TOTAL row is checked against per-package
floors:
- `swift-server`: 40% lines, 40% functions, 35% regions
- `swift-launcher`: 5% lines, 5% functions, 8% regions
(most of the bundle is SwiftUI views that resist unit tests; the
floor exists to prevent regression below the current baseline)
### Documentation
| Tier | File | Update when... |
| --------------- | ----------------- | ------------------------------------------------------------ |
| Public | `README.md` | User-facing behavior changes |
| Development | `CLAUDE.md` files | Developer conventions, package architecture, build workflows |
| Agent reference | `docs/` | Detailed tools, commands, and patterns |
### Verification
These are the repo's CI gates and the default full verification pass before commit:
```bash
npx prettier --write <changed-files> # Format FIRST β CI fails on unformatted code
npm run typecheck
npm run test
npm run test:coverage # Enforces minimum coverage thresholds
npm run build
npm run build -w @slicc/chrome-extension
```
**Always run Prettier before committing.** CI runs `npx prettier --check .` as a lint gate and will reject unformatted code. Run `npx prettier --write <files>` on every file you touch. This is the most common CI failure β don't skip it.
CI runs these gates in `.github/workflows/ci.yml`.
Add to your project
Paste into your project's CLAUDE.md or ~/.claude/CLAUDE.md for global rules.
More for TypeScript
Python FastAPI Expert
by @Claude Rules
Building high-performance REST APIs with FastAPI, Pydantic, and async Python.
Node.js Express API
by @Claude Rules
Building scalable Node.js REST APIs with Express, middleware, and proper async patterns.
Django Web Framework
by @Claude Rules
Full-stack Django development with DRF, proper models, and security best practices.
Vue.js Composition API
by @Claude Rules
Modern Vue 3 development with Composition API, Pinia, and TypeScript.
Angular Enterprise
by @Claude Rules
Enterprise Angular development with RxJS, NgRx, standalone components, and best practices.
Swift iOS Development
by @Claude Rules
Modern iOS development with SwiftUI, Combine, and Swift concurrency.
MCP servers for TypeScript
microsoft/markitdown
ποΈ π π - MCP tool access to MarkItDown -- a library that converts many file formats (local or remote) to Markdown for LLM consumption.
netdata/netdata#Netdata
ποΈ π βοΈ π π πͺ π§ - Discovery, exploration, reporting and root cause analysis using all observability data, including metrics, logs, systems, containers, processes, and network connections
upstash/context7
π βοΈ - Up-to-date code documentation for LLMs and AI code editors.
Browse by Tag
Get the Claude Code Starter Pack
Top CLAUDE.md rules for Next.js, TypeScript, Python, Go, and React β free.
