{"id":47909345,"url":"https://github.com/nullclaw/nullclaw-chat-ui","last_synced_at":"2026-04-04T05:13:36.576Z","repository":{"id":341234348,"uuid":"1168893569","full_name":"nullclaw/nullclaw-chat-ui","owner":"nullclaw","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-13T04:32:44.000Z","size":638,"stargazers_count":22,"open_issues_count":2,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-13T12:26:11.997Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nullclaw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-27T23:12:14.000Z","updated_at":"2026-03-13T04:32:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"342915cb-26d7-4936-bc75-be8db8a8a582","html_url":"https://github.com/nullclaw/nullclaw-chat-ui","commit_stats":null,"previous_names":["nullclaw/nullclaw-ui","nullclaw/nullclaw-chat-ui"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nullclaw/nullclaw-chat-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullclaw%2Fnullclaw-chat-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullclaw%2Fnullclaw-chat-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullclaw%2Fnullclaw-chat-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullclaw%2Fnullclaw-chat-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nullclaw","download_url":"https://codeload.github.com/nullclaw/nullclaw-chat-ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullclaw%2Fnullclaw-chat-ui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31388302,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T04:26:24.776Z","status":"ssl_error","status_checked_at":"2026-04-04T04:23:34.147Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-04T05:13:35.735Z","updated_at":"2026-04-04T05:13:36.570Z","avatar_url":"https://github.com/nullclaw.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nullclaw-chat-ui\n\nA terminal-style web interface for `nullclaw`.\nThe app uses WebSocket + `WebChannel v1` and supports PIN pairing, streaming assistant responses, tool-call rendering, approval prompts, and end-to-end encryption.\n\n![Nullclaw Pairing Screen](docs/assets/pairing-screen.png)\n\n## Features\n\n- Connect to an agent via `ws://...` endpoint and a 6-digit pairing PIN.\n- E2E session bootstrap: X25519 key exchange + ChaCha20-Poly1305 message encryption.\n- Streaming assistant UI (`assistant_chunk` -\u003e `assistant_final`).\n- Tool timeline support (`tool_call` / `tool_result`).\n- Approval flow support (`approval_request` -\u003e `approval_response`).\n- Session restore from `localStorage` with token TTL.\n- Theme and visual-effects preferences persisted locally.\n\n## Stack\n\n- `Svelte 5` (Runes API)\n- `SvelteKit 2`\n- `Vite 7`\n- `Vitest 4` + `@testing-library/svelte`\n- `@noble/ciphers` for ChaCha20-Poly1305\n\nThe app is built as a static site (`adapter-static`, `fallback: index.html`, `ssr = false`).\n\n## Quick Start\n\n### 1) Requirements\n\n- `Node.js` 20+ (LTS recommended)\n- `npm` 10+\n\n### 2) Install\n\n```bash\nnpm install\n```\n\n### 3) Run locally\n\n```bash\nnpm run dev\n```\n\nOpen `http://localhost:5173`.\n\n### 4) Pair with an agent\n\n1. Enter the WebSocket endpoint (default: `ws://127.0.0.1:32123/ws`).\n2. If your backend requires `web.accounts.\u003cname\u003e.auth_token` (common for non-loopback binds), set it in the optional `auth_token` field.\n3. Enter a 6-digit pairing PIN.\n4. After `pairing_result`, the UI switches to chat mode.\n\n## Scripts\n\n- `npm run dev` - local development server.\n- `npm run build` - production build.\n- `npm run preview` - preview built app.\n- `npm run cli -- run` - serve built UI via local CLI entrypoint.\n- `npm run test` - run Vitest suite.\n- `npm run test:watch` - run Vitest in watch mode.\n- `npm run check` - `svelte-kit sync` + `svelte-check`.\n- `npm run check:watch` - `svelte-check` in watch mode.\n\n## Global CLI Usage\n\nGitHub release artifacts include a runnable CLI bundle with `build/` assets and launchers.\nAfter extracting a release archive, put the launcher on your `$PATH`:\n\n```bash\nchmod +x nullclaw-chat-ui/nullclaw-chat-ui\nsudo ln -sf \"$(pwd)/nullclaw-chat-ui/nullclaw-chat-ui\" /usr/local/bin/nullclaw-chat-ui\nnullclaw-chat-ui run --host 127.0.0.1 --port 4173\n```\n\nNotes:\n\n- Requires `Node.js 20+` available as `node`.\n- Windows users can use `nullclaw-chat-ui.cmd` from the extracted folder.\n- `nullclaw-chat-ui run` serves the built static UI bundle with SPA fallback routing and still requires a reachable `nullclaw` WebSocket backend.\n\n## Architecture (Short)\n\n- [`src/routes/+page.svelte`](src/routes/+page.svelte): page composition root.\n- [`src/lib/session/connection-controller.svelte.ts`](src/lib/session/connection-controller.svelte.ts): pairing/session orchestration, restore, logout.\n- [`src/lib/protocol/client.svelte.ts`](src/lib/protocol/client.svelte.ts): WebSocket client, envelope validation, reconnect.\n- [`src/lib/stores/session.svelte.ts`](src/lib/stores/session.svelte.ts): timeline state (messages/tool calls/approvals/errors).\n- [`src/lib/protocol/e2e.ts`](src/lib/protocol/e2e.ts): cryptography.\n- [`src/lib/ui/preferences.ts`](src/lib/ui/preferences.ts) + [`src/lib/theme.ts`](src/lib/theme.ts): UI preferences.\n\nDetailed docs:\n\n- [Architecture](docs/architecture.md)\n- [Protocol and E2E](docs/protocol.md)\n- [Development](docs/development.md)\n- [Testing](docs/testing.md)\n- [Operations and Releases](docs/operations.md)\n\n## Browser Storage\n\n`localStorage` keys:\n\n- `nullclaw_ui_auth_v1` - endpoint URL (may include `?token=` when used), `access_token`, `shared_key`, `expires_at`.\n- `nullclaw_ui_theme` - current theme.\n- `nullclaw_ui_effects` - visual effects toggle.\n\nAuth token and shared key are cleared automatically when TTL expires or when the session is rejected (`unauthorized`).\n\n## Build and Deploy\n\n```bash\nnpm run build\n```\n\nStatic output: `build/`. Deploy to any static hosting/CDN with `index.html` fallback configured.\n\n## Limitations\n\n- X25519 requires modern WebCrypto support in the browser.\n- Endpoint is currently user-entered in UI (not env-configured).\n- This repository is UI-only and expects an available WebSocket backend.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnullclaw%2Fnullclaw-chat-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnullclaw%2Fnullclaw-chat-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnullclaw%2Fnullclaw-chat-ui/lists"}