docs: link source references to GitHub
This commit is contained in:
parent
9b22e1f6e9
commit
4845c615cb
@ -99,7 +99,7 @@ Run `clawdbot doctor` to surface risky/misconfigured DM policies.
|
|||||||
|
|
||||||
- **[Local-first Gateway](https://docs.clawd.bot/gateway)** — single control plane for sessions, providers, tools, and events.
|
- **[Local-first Gateway](https://docs.clawd.bot/gateway)** — single control plane for sessions, providers, tools, and events.
|
||||||
- **[Multi-provider inbox](https://docs.clawd.bot/surface)** — WhatsApp, Telegram, Slack, Discord, Signal, iMessage, WebChat, macOS, iOS/Android.
|
- **[Multi-provider inbox](https://docs.clawd.bot/surface)** — WhatsApp, Telegram, Slack, Discord, Signal, iMessage, WebChat, macOS, iOS/Android.
|
||||||
- **[Multi-agent routing](docs/configuration.md)** — route inbound providers/accounts/peers to isolated agents (workspaces + per-agent sessions).
|
- **[Multi-agent routing](https://docs.clawd.bot/configuration)** — route inbound providers/accounts/peers to isolated agents (workspaces + per-agent sessions).
|
||||||
- **[Voice Wake](https://docs.clawd.bot/voicewake) + [Talk Mode](https://docs.clawd.bot/talk)** — always-on speech for macOS/iOS/Android with ElevenLabs.
|
- **[Voice Wake](https://docs.clawd.bot/voicewake) + [Talk Mode](https://docs.clawd.bot/talk)** — always-on speech for macOS/iOS/Android with ElevenLabs.
|
||||||
- **[Live Canvas](https://docs.clawd.bot/mac/canvas)** — agent-driven visual workspace with [A2UI](https://docs.clawd.bot/mac/canvas#canvas-a2ui).
|
- **[Live Canvas](https://docs.clawd.bot/mac/canvas)** — agent-driven visual workspace with [A2UI](https://docs.clawd.bot/mac/canvas#canvas-a2ui).
|
||||||
- **[First-class tools](https://docs.clawd.bot/tools)** — browser, canvas, nodes, cron, sessions, and Discord/Slack actions.
|
- **[First-class tools](https://docs.clawd.bot/tools)** — browser, canvas, nodes, cron, sessions, and Discord/Slack actions.
|
||||||
|
|||||||
@ -12,12 +12,12 @@ Use `pnpm` (Node 22+) from the repo root. Keep the working tree clean before tag
|
|||||||
|
|
||||||
1) **Version & metadata**
|
1) **Version & metadata**
|
||||||
- [ ] Bump `package.json` version (e.g., `1.1.0`).
|
- [ ] Bump `package.json` version (e.g., `1.1.0`).
|
||||||
- [ ] Update CLI/version strings: `src/cli/program.ts` and the Baileys user agent in `src/provider-web.ts`.
|
- [ ] Update CLI/version strings: [`src/cli/program.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/cli/program.ts) and the Baileys user agent in [`src/provider-web.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/provider-web.ts).
|
||||||
- [ ] Confirm package metadata (name, description, repository, keywords, license) and `bin` map points to `dist/index.js` for `clawdbot`.
|
- [ ] Confirm package metadata (name, description, repository, keywords, license) and `bin` map points to [`dist/index.js`](https://github.com/clawdbot/clawdbot/blob/main/dist/index.js) for `clawdbot`.
|
||||||
- [ ] If dependencies changed, run `pnpm install` so `pnpm-lock.yaml` is current.
|
- [ ] If dependencies changed, run `pnpm install` so `pnpm-lock.yaml` is current.
|
||||||
|
|
||||||
2) **Build & artifacts**
|
2) **Build & artifacts**
|
||||||
- [ ] If A2UI inputs changed, run `pnpm canvas:a2ui:bundle` and commit any updated `src/canvas-host/a2ui/a2ui.bundle.js`.
|
- [ ] If A2UI inputs changed, run `pnpm canvas:a2ui:bundle` and commit any updated [`src/canvas-host/a2ui/a2ui.bundle.js`](https://github.com/clawdbot/clawdbot/blob/main/src/canvas-host/a2ui/a2ui.bundle.js).
|
||||||
- [ ] `pnpm run build` (regenerates `dist/`).
|
- [ ] `pnpm run build` (regenerates `dist/`).
|
||||||
- [ ] Optional: `npm pack --pack-destination /tmp` after the build; inspect the tarball contents and keep it handy for the GitHub release (do **not** commit it).
|
- [ ] Optional: `npm pack --pack-destination /tmp` after the build; inspect the tarball contents and keep it handy for the GitHub release (do **not** commit it).
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ Use `pnpm` (Node 22+) from the repo root. Keep the working tree clean before tag
|
|||||||
|
|
||||||
5) **macOS app (Sparkle)**
|
5) **macOS app (Sparkle)**
|
||||||
- [ ] Build + sign the macOS app, then zip it for distribution.
|
- [ ] Build + sign the macOS app, then zip it for distribution.
|
||||||
- [ ] Generate the Sparkle appcast (HTML notes via `scripts/make_appcast.sh`) and update `appcast.xml`.
|
- [ ] Generate the Sparkle appcast (HTML notes via [`scripts/make_appcast.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/make_appcast.sh)) and update `appcast.xml`.
|
||||||
- [ ] Keep the app zip (and optional dSYM zip) ready to attach to the GitHub release.
|
- [ ] Keep the app zip (and optional dSYM zip) ready to attach to the GitHub release.
|
||||||
- [ ] Follow [`docs/mac/release.md`](https://docs.clawd.bot/mac/release) for the exact commands and required env vars.
|
- [ ] Follow [`docs/mac/release.md`](https://docs.clawd.bot/mac/release) for the exact commands and required env vars.
|
||||||
- `APP_BUILD` must be numeric + monotonic (no `-beta`) so Sparkle compares versions correctly.
|
- `APP_BUILD` must be numeric + monotonic (no `-beta`) so Sparkle compares versions correctly.
|
||||||
|
|||||||
@ -8,8 +8,8 @@ read_when:
|
|||||||
Short, exact flow of one agent run. Source of truth: current code in `src/`.
|
Short, exact flow of one agent run. Source of truth: current code in `src/`.
|
||||||
|
|
||||||
## Entry points
|
## Entry points
|
||||||
- Gateway RPC: `agent` and `agent.wait` in `src/gateway/server-methods/agent.ts`.
|
- Gateway RPC: `agent` and `agent.wait` in [`src/gateway/server-methods/agent.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server-methods/agent.ts).
|
||||||
- CLI: `agentCommand` in `src/commands/agent.ts`.
|
- CLI: `agentCommand` in [`src/commands/agent.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/commands/agent.ts).
|
||||||
|
|
||||||
## High-level flow
|
## High-level flow
|
||||||
1) `agent` RPC validates params, resolves session (sessionKey/sessionId), persists session metadata, returns `{ runId, acceptedAt }` immediately.
|
1) `agent` RPC validates params, resolves session (sessionKey/sessionId), persists session metadata, returns `{ runId, acceptedAt }` immediately.
|
||||||
@ -37,7 +37,7 @@ Short, exact flow of one agent run. Source of truth: current code in `src/`.
|
|||||||
- `tool`: streamed tool events from pi-agent-core
|
- `tool`: streamed tool events from pi-agent-core
|
||||||
|
|
||||||
## Chat provider handling
|
## Chat provider handling
|
||||||
- `createAgentEventHandler` in `src/gateway/server-chat.ts`:
|
- `createAgentEventHandler` in [`src/gateway/server-chat.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server-chat.ts):
|
||||||
- buffers assistant deltas
|
- buffers assistant deltas
|
||||||
- emits chat `delta` messages
|
- emits chat `delta` messages
|
||||||
- emits chat `final` when **lifecycle end/error** arrives
|
- emits chat `final` when **lifecycle end/error** arrives
|
||||||
@ -53,9 +53,9 @@ Short, exact flow of one agent run. Source of truth: current code in `src/`.
|
|||||||
- `agent.wait` timeout (wait-only, does not stop agent)
|
- `agent.wait` timeout (wait-only, does not stop agent)
|
||||||
|
|
||||||
## Files
|
## Files
|
||||||
- `src/gateway/server-methods/agent.ts`
|
- [`src/gateway/server-methods/agent.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server-methods/agent.ts)
|
||||||
- `src/gateway/server-methods/agent-job.ts`
|
- [`src/gateway/server-methods/agent-job.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server-methods/agent-job.ts)
|
||||||
- `src/commands/agent.ts`
|
- [`src/commands/agent.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/commands/agent.ts)
|
||||||
- `src/agents/pi-embedded-runner.ts`
|
- [`src/agents/pi-embedded-runner.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/agents/pi-embedded-runner.ts)
|
||||||
- `src/agents/pi-embedded-subscribe.ts`
|
- [`src/agents/pi-embedded-subscribe.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/agents/pi-embedded-subscribe.ts)
|
||||||
- `src/gateway/server-chat.ts`
|
- [`src/gateway/server-chat.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server-chat.ts)
|
||||||
|
|||||||
@ -15,14 +15,14 @@ Last updated: 2026-01-05
|
|||||||
|
|
||||||
## Implementation snapshot (current code)
|
## Implementation snapshot (current code)
|
||||||
|
|
||||||
### TypeScript Gateway (`src/gateway/server.ts`)
|
### TypeScript Gateway ([`src/gateway/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server.ts))
|
||||||
- Single HTTP + WebSocket server (default `18789`); bind policy `loopback|lan|tailnet|auto`. Refuses non-loopback binds without auth; Tailscale serve/funnel requires loopback.
|
- Single HTTP + WebSocket server (default `18789`); bind policy `loopback|lan|tailnet|auto`. Refuses non-loopback binds without auth; Tailscale serve/funnel requires loopback.
|
||||||
- Handshake: first frame must be a `connect` request; AJV validates request + params against TypeBox schemas; protocol negotiated via `minProtocol`/`maxProtocol`.
|
- Handshake: first frame must be a `connect` request; AJV validates request + params against TypeBox schemas; protocol negotiated via `minProtocol`/`maxProtocol`.
|
||||||
- `hello-ok` includes snapshot (presence/health/stateVersion/uptime/configPath/stateDir), features (methods/events), policy (max payload/buffer/tick), and `canvasHostUrl` when available.
|
- `hello-ok` includes snapshot (presence/health/stateVersion/uptime/configPath/stateDir), features (methods/events), policy (max payload/buffer/tick), and `canvasHostUrl` when available.
|
||||||
- Events emitted: `agent`, `chat`, `presence`, `tick`, `health`, `heartbeat`, `cron`, `talk.mode`, `node.pair.requested`, `node.pair.resolved`, `voicewake.changed`, `shutdown`.
|
- Events emitted: `agent`, `chat`, `presence`, `tick`, `health`, `heartbeat`, `cron`, `talk.mode`, `node.pair.requested`, `node.pair.resolved`, `voicewake.changed`, `shutdown`.
|
||||||
- Idempotency keys are required for `send`, `agent`, `chat.send`, and node invokes; the dedupe cache avoids double-sends on reconnects. Payload sizes are capped per connection.
|
- Idempotency keys are required for `send`, `agent`, `chat.send`, and node invokes; the dedupe cache avoids double-sends on reconnects. Payload sizes are capped per connection.
|
||||||
- Optional node bridge (`src/infra/bridge/server.ts`): TCP JSONL frames (`hello`, `pair-request`, `req/res`, `event`, `invoke`, `ping`). Node connect/disconnect updates presence and flows into the session bus.
|
- Optional node bridge ([`src/infra/bridge/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/infra/bridge/server.ts)): TCP JSONL frames (`hello`, `pair-request`, `req/res`, `event`, `invoke`, `ping`). Node connect/disconnect updates presence and flows into the session bus.
|
||||||
- Control UI + Canvas host: HTTP serves Control UI (base path configurable) and can host the A2UI canvas via `src/canvas-host/server.ts` (live reload). Canvas host URL is advertised to nodes + clients.
|
- Control UI + Canvas host: HTTP serves Control UI (base path configurable) and can host the A2UI canvas via [`src/canvas-host/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/canvas-host/server.ts) (live reload). Canvas host URL is advertised to nodes + clients.
|
||||||
|
|
||||||
### iOS node (`apps/ios`)
|
### iOS node (`apps/ios`)
|
||||||
- Discovery + pairing: `BridgeDiscoveryModel` uses `NWBrowser` Bonjour discovery and reads TXT fields for LAN/tailnet host hints plus gateway/bridge/canvas ports.
|
- Discovery + pairing: `BridgeDiscoveryModel` uses `NWBrowser` Bonjour discovery and reads TXT fields for LAN/tailnet host hints plus gateway/bridge/canvas ports.
|
||||||
|
|||||||
@ -69,7 +69,7 @@ The bridge port (default `18790`) is a plain TCP service. By default it binds to
|
|||||||
For a tailnet-only setup, bind it to the Tailscale IP instead:
|
For a tailnet-only setup, bind it to the Tailscale IP instead:
|
||||||
|
|
||||||
- Set `bridge.bind: "tailnet"` in `~/.clawdbot/clawdbot.json`.
|
- Set `bridge.bind: "tailnet"` in `~/.clawdbot/clawdbot.json`.
|
||||||
- Restart the Gateway (or restart the macOS menubar app via `./scripts/restart-mac.sh` on that machine).
|
- Restart the Gateway (or restart the macOS menubar app via [`./scripts/restart-mac.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/restart-mac.sh) on that machine).
|
||||||
|
|
||||||
This keeps the bridge reachable only from devices on your tailnet (while still listening on loopback for local/SSH port-forwards).
|
This keeps the bridge reachable only from devices on your tailnet (while still listening on loopback for local/SSH port-forwards).
|
||||||
|
|
||||||
@ -77,8 +77,8 @@ This keeps the bridge reachable only from devices on your tailnet (while still l
|
|||||||
|
|
||||||
Only the **Node Gateway** (`clawd` / `clawdbot gateway`) advertises Bonjour beacons.
|
Only the **Node Gateway** (`clawd` / `clawdbot gateway`) advertises Bonjour beacons.
|
||||||
|
|
||||||
- Implementation: `src/infra/bonjour.ts`
|
- Implementation: [`src/infra/bonjour.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/infra/bonjour.ts)
|
||||||
- Gateway wiring: `src/gateway/server.ts`
|
- Gateway wiring: [`src/gateway/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server.ts)
|
||||||
|
|
||||||
## Service types
|
## Service types
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ The log includes browser state transitions (`ready`, `waiting`, `failed`, `cance
|
|||||||
- **Sleep / interface churn**: macOS may temporarily drop mDNS results when switching networks; retry.
|
- **Sleep / interface churn**: macOS may temporarily drop mDNS results when switching networks; retry.
|
||||||
- **Browse works but resolve fails (iOS “NoSuchRecord”)**: make sure the advertiser publishes a valid SRV target hostname.
|
- **Browse works but resolve fails (iOS “NoSuchRecord”)**: make sure the advertiser publishes a valid SRV target hostname.
|
||||||
- Implementation detail: `@homebridge/ciao` defaults `hostname` to the *service instance name* when `hostname` is omitted. If your instance name contains spaces/parentheses, some resolvers can fail to resolve the implied A/AAAA record.
|
- Implementation detail: `@homebridge/ciao` defaults `hostname` to the *service instance name* when `hostname` is omitted. If your instance name contains spaces/parentheses, some resolvers can fail to resolve the implied A/AAAA record.
|
||||||
- Fix: set an explicit DNS-safe `hostname` (single label; no `.local`) in `src/infra/bonjour.ts`.
|
- Fix: set an explicit DNS-safe `hostname` (single label; no `.local`) in [`src/infra/bonjour.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/infra/bonjour.ts).
|
||||||
|
|
||||||
## Escaped instance names (`\\032`)
|
## Escaped instance names (`\\032`)
|
||||||
Bonjour/DNS-SD often escapes bytes in service instance names as decimal `\\DDD` sequences (e.g. spaces become `\\032`).
|
Bonjour/DNS-SD often escapes bytes in service instance names as decimal `\\DDD` sequences (e.g. spaces become `\\032`).
|
||||||
|
|||||||
@ -41,7 +41,7 @@ bun run vitest run
|
|||||||
pnpm supports `package.json#pnpm.patchedDependencies` and records it in `pnpm-lock.yaml`.
|
pnpm supports `package.json#pnpm.patchedDependencies` and records it in `pnpm-lock.yaml`.
|
||||||
Bun does not support pnpm patches, so we apply them in `postinstall` when Bun is detected:
|
Bun does not support pnpm patches, so we apply them in `postinstall` when Bun is detected:
|
||||||
|
|
||||||
- `scripts/postinstall.js` runs only for Bun installs and applies every entry from `package.json#pnpm.patchedDependencies` into `node_modules/...` using `git apply` (idempotent).
|
- [`scripts/postinstall.js`](https://github.com/clawdbot/clawdbot/blob/main/scripts/postinstall.js) runs only for Bun installs and applies every entry from `package.json#pnpm.patchedDependencies` into `node_modules/...` using `git apply` (idempotent).
|
||||||
|
|
||||||
To add a new patch that works in both pnpm + Bun:
|
To add a new patch that works in both pnpm + Bun:
|
||||||
|
|
||||||
|
|||||||
@ -14,8 +14,8 @@ Last updated: 2025-12-13
|
|||||||
## Context
|
## Context
|
||||||
|
|
||||||
Clawdbot already has:
|
Clawdbot already has:
|
||||||
- A **gateway heartbeat runner** that runs the agent with `HEARTBEAT` and suppresses `HEARTBEAT_OK` (`src/infra/heartbeat-runner.ts`).
|
- A **gateway heartbeat runner** that runs the agent with `HEARTBEAT` and suppresses `HEARTBEAT_OK` ([`src/infra/heartbeat-runner.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/infra/heartbeat-runner.ts)).
|
||||||
- A lightweight, in-memory **system event queue** (`enqueueSystemEvent`) that is injected into the next **main session** turn (`drainSystemEvents` in `src/auto-reply/reply.ts`).
|
- A lightweight, in-memory **system event queue** (`enqueueSystemEvent`) that is injected into the next **main session** turn (`drainSystemEvents` in [`src/auto-reply/reply.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/auto-reply/reply.ts)).
|
||||||
- A WebSocket **Gateway** daemon that is intended to be always-on ([`docs/gateway.md`](https://docs.clawd.bot/gateway)).
|
- A WebSocket **Gateway** daemon that is intended to be always-on ([`docs/gateway.md`](https://docs.clawd.bot/gateway)).
|
||||||
|
|
||||||
This RFC adds a small “cron job system” so Clawd can schedule future work and reliably wake itself up:
|
This RFC adds a small “cron job system” so Clawd can schedule future work and reliably wake itself up:
|
||||||
@ -180,7 +180,7 @@ When due:
|
|||||||
|
|
||||||
### “Run in parallel to main”
|
### “Run in parallel to main”
|
||||||
|
|
||||||
Clawdbot currently serializes command execution through a global in-process queue (`src/process/command-queue.ts`) to avoid collisions.
|
Clawdbot currently serializes command execution through a global in-process queue ([`src/process/command-queue.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/process/command-queue.ts)) to avoid collisions.
|
||||||
|
|
||||||
To support isolated cron jobs running “in parallel”, we should introduce **lanes** (keyed queues) plus a global concurrency cap:
|
To support isolated cron jobs running “in parallel”, we should introduce **lanes** (keyed queues) plus a global concurrency cap:
|
||||||
- Lane `"main"`: inbound auto-replies + main heartbeat.
|
- Lane `"main"`: inbound auto-replies + main heartbeat.
|
||||||
@ -198,7 +198,7 @@ We need a way for the Gateway (or the scheduler) to request an immediate heartbe
|
|||||||
|
|
||||||
Design:
|
Design:
|
||||||
- `startHeartbeatRunner` owns the real heartbeat execution and installs a wake handler.
|
- `startHeartbeatRunner` owns the real heartbeat execution and installs a wake handler.
|
||||||
- Wake hook lives in `src/infra/heartbeat-wake.ts`:
|
- Wake hook lives in [`src/infra/heartbeat-wake.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/infra/heartbeat-wake.ts):
|
||||||
- `setHeartbeatWakeHandler(fn | null)` installed by the heartbeat runner
|
- `setHeartbeatWakeHandler(fn | null)` installed by the heartbeat runner
|
||||||
- `requestHeartbeatNow({ reason, coalesceMs? })`
|
- `requestHeartbeatNow({ reason, coalesceMs? })`
|
||||||
- If the handler is absent, the request is stored as “pending”; the next time the handler is installed, it runs once.
|
- If the handler is absent, the request is stored as “pending”; the next time the handler is installed, it runs once.
|
||||||
|
|||||||
@ -252,7 +252,7 @@ Example:
|
|||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
- Image missing: build with `scripts/sandbox-setup.sh` or set `agent.sandbox.docker.image`.
|
- Image missing: build with [`scripts/sandbox-setup.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/sandbox-setup.sh) or set `agent.sandbox.docker.image`.
|
||||||
- Container not running: it will auto-create per session on demand.
|
- Container not running: it will auto-create per session on demand.
|
||||||
- Permission errors in sandbox: set `docker.user` to a UID:GID that matches your
|
- Permission errors in sandbox: set `docker.user` to a UID:GID that matches your
|
||||||
mounted workspace ownership (or chown the workspace folder).
|
mounted workspace ownership (or chown the workspace folder).
|
||||||
|
|||||||
@ -127,7 +127,7 @@ See also: [`docs/presence.md`](https://docs.clawd.bot/presence) for how presence
|
|||||||
## Typing and validation
|
## Typing and validation
|
||||||
- Server validates every inbound frame with AJV against JSON Schema emitted from the protocol definitions.
|
- Server validates every inbound frame with AJV against JSON Schema emitted from the protocol definitions.
|
||||||
- Clients (TS/Swift) consume generated types (TS directly; Swift via the repo’s generator).
|
- Clients (TS/Swift) consume generated types (TS directly; Swift via the repo’s generator).
|
||||||
- Types live in `src/gateway/protocol/*.ts`; regenerate schemas/models with `pnpm protocol:gen` (writes `dist/protocol.schema.json`) and `pnpm protocol:gen:swift` (writes `apps/macos/Sources/ClawdbotProtocol/GatewayModels.swift`).
|
- Types live in [`src/gateway/protocol/*.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/protocol/*.ts); regenerate schemas/models with `pnpm protocol:gen` (writes [`dist/protocol.schema.json`](https://github.com/clawdbot/clawdbot/blob/main/dist/protocol.schema.json)) and `pnpm protocol:gen:swift` (writes [`apps/macos/Sources/ClawdbotProtocol/GatewayModels.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/ClawdbotProtocol/GatewayModels.swift)).
|
||||||
|
|
||||||
## Connection snapshot
|
## Connection snapshot
|
||||||
- `hello-ok` includes a `snapshot` with `presence`, `health`, `stateVersion`, and `uptimeMs` plus `policy {maxPayload,maxBufferedBytes,tickIntervalMs}` so clients can render immediately without extra requests.
|
- `hello-ok` includes a `snapshot` with `presence`, `health`, `stateVersion`, and `uptimeMs` plus `policy {maxPayload,maxBufferedBytes,tickIntervalMs}` so clients can render immediately without extra requests.
|
||||||
|
|||||||
@ -194,7 +194,7 @@ Non-goals (v1):
|
|||||||
- Perfect App Store compliance; this is **internal-only** initially.
|
- Perfect App Store compliance; this is **internal-only** initially.
|
||||||
|
|
||||||
### Current repo reality (constraints we respect)
|
### Current repo reality (constraints we respect)
|
||||||
- The Gateway WebSocket server binds to `127.0.0.1:18789` (`src/gateway/server.ts`) with an optional `CLAWDBOT_GATEWAY_TOKEN`.
|
- The Gateway WebSocket server binds to `127.0.0.1:18789` ([`src/gateway/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server.ts)) with an optional `CLAWDBOT_GATEWAY_TOKEN`.
|
||||||
- The Gateway exposes a Canvas file server (`canvasHost`) on `canvasHost.port` (default `18793`), so nodes can `canvas.navigate` to `http://<lanHost>:18793/__clawdbot__/canvas/` and auto-reload on file changes ([`docs/configuration.md`](https://docs.clawd.bot/configuration)).
|
- The Gateway exposes a Canvas file server (`canvasHost`) on `canvasHost.port` (default `18793`), so nodes can `canvas.navigate` to `http://<lanHost>:18793/__clawdbot__/canvas/` and auto-reload on file changes ([`docs/configuration.md`](https://docs.clawd.bot/configuration)).
|
||||||
- macOS “Canvas” is controlled via the Gateway node protocol (`canvas.*`), matching iOS/Android ([`docs/mac/canvas.md`](https://docs.clawd.bot/mac/canvas)).
|
- macOS “Canvas” is controlled via the Gateway node protocol (`canvas.*`), matching iOS/Android ([`docs/mac/canvas.md`](https://docs.clawd.bot/mac/canvas)).
|
||||||
- Voice wake forwards via `GatewayChannel` to Gateway `agent` (mac app: `VoiceWakeForwarder` → `GatewayConnection.sendAgent`).
|
- Voice wake forwards via `GatewayChannel` to Gateway `agent` (mac app: `VoiceWakeForwarder` → `GatewayConnection.sendAgent`).
|
||||||
@ -267,7 +267,7 @@ Unify mac Canvas + iOS Canvas under a single conceptual surface:
|
|||||||
- remote iOS node via the bridge
|
- remote iOS node via the bridge
|
||||||
|
|
||||||
#### Minimal protocol additions (v1)
|
#### Minimal protocol additions (v1)
|
||||||
Add to `src/gateway/protocol/schema.ts` (and regenerate Swift models):
|
Add to [`src/gateway/protocol/schema.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/protocol/schema.ts) (and regenerate Swift models):
|
||||||
|
|
||||||
**Identity**
|
**Identity**
|
||||||
- Node identity comes from `connect.params.client.instanceId` (stable), and `connect.params.client.mode = "node"` (or `"ios-node"`).
|
- Node identity comes from `connect.params.client.instanceId` (stable), and `connect.params.client.mode = "node"` (or `"ios-node"`).
|
||||||
|
|||||||
@ -14,7 +14,7 @@ Clawdbot has two log “surfaces”:
|
|||||||
|
|
||||||
## File-based logger
|
## File-based logger
|
||||||
|
|
||||||
Clawdbot uses a file logger backed by `tslog` (`src/logging.ts`).
|
Clawdbot uses a file logger backed by `tslog` ([`src/logging.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/logging.ts)).
|
||||||
|
|
||||||
- Default rolling log file is under `/tmp/clawdbot/` (one file per day): `clawdbot-YYYY-MM-DD.log`
|
- Default rolling log file is under `/tmp/clawdbot/` (one file per day): `clawdbot-YYYY-MM-DD.log`
|
||||||
- The log file path and level can be configured via `~/.clawdbot/clawdbot.json`:
|
- The log file path and level can be configured via `~/.clawdbot/clawdbot.json`:
|
||||||
@ -33,7 +33,7 @@ The file format is one JSON object per line.
|
|||||||
|
|
||||||
## Console capture
|
## Console capture
|
||||||
|
|
||||||
The CLI entrypoint enables console capture (`src/index.ts` calls `enableConsoleCapture()`).
|
The CLI entrypoint enables console capture ([`src/index.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/index.ts) calls `enableConsoleCapture()`).
|
||||||
That means every `console.log/info/warn/error/debug/trace` is also written into the file logs,
|
That means every `console.log/info/warn/error/debug/trace` is also written into the file logs,
|
||||||
while still behaving normally on stdout/stderr.
|
while still behaving normally on stdout/stderr.
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ clawdbot gateway --verbose --ws-log full
|
|||||||
|
|
||||||
Clawdbot formats console logs via a small wrapper on top of the existing stack:
|
Clawdbot formats console logs via a small wrapper on top of the existing stack:
|
||||||
|
|
||||||
- **tslog** for structured file logs (`src/logging.ts`)
|
- **tslog** for structured file logs ([`src/logging.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/logging.ts))
|
||||||
- **chalk** for colors (`src/globals.ts`)
|
- **chalk** for colors ([`src/globals.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/globals.ts))
|
||||||
|
|
||||||
The console formatter is **TTY-aware** and prints consistent, prefixed lines.
|
The console formatter is **TTY-aware** and prints consistent, prefixed lines.
|
||||||
Subsystem loggers are created via `createSubsystemLogger("gateway")`.
|
Subsystem loggers are created via `createSubsystemLogger("gateway")`.
|
||||||
|
|||||||
@ -15,7 +15,7 @@ Goal: ship **Clawdbot.app** with a self-contained relay binary that can run both
|
|||||||
App bundle layout:
|
App bundle layout:
|
||||||
|
|
||||||
- `Clawdbot.app/Contents/Resources/Relay/clawdbot`
|
- `Clawdbot.app/Contents/Resources/Relay/clawdbot`
|
||||||
- bun `--compile` relay executable built from `dist/macos/relay.js`
|
- bun `--compile` relay executable built from [`dist/macos/relay.js`](https://github.com/clawdbot/clawdbot/blob/main/dist/macos/relay.js)
|
||||||
- Supports:
|
- Supports:
|
||||||
- `clawdbot …` (CLI)
|
- `clawdbot …` (CLI)
|
||||||
- `clawdbot gateway-daemon …` (LaunchAgent daemon)
|
- `clawdbot gateway-daemon …` (LaunchAgent daemon)
|
||||||
@ -31,7 +31,7 @@ Why the sidecar files matter:
|
|||||||
## Build pipeline
|
## Build pipeline
|
||||||
|
|
||||||
Packaging script:
|
Packaging script:
|
||||||
- `scripts/package-mac-app.sh`
|
- [`scripts/package-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/package-mac-app.sh)
|
||||||
|
|
||||||
It builds:
|
It builds:
|
||||||
- TS: `pnpm exec tsc`
|
- TS: `pnpm exec tsc`
|
||||||
@ -47,7 +47,7 @@ Important bundler flags:
|
|||||||
|
|
||||||
Version injection:
|
Version injection:
|
||||||
- `--define "__CLAWDBOT_VERSION__=\"<pkg version>\""`
|
- `--define "__CLAWDBOT_VERSION__=\"<pkg version>\""`
|
||||||
- `src/version.ts` also supports `__CLAWDBOT_VERSION__` (and `CLAWDBOT_BUNDLED_VERSION`) so `--version` doesn’t depend on reading `package.json` at runtime.
|
- [`src/version.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/version.ts) also supports `__CLAWDBOT_VERSION__` (and `CLAWDBOT_BUNDLED_VERSION`) so `--version` doesn’t depend on reading `package.json` at runtime.
|
||||||
|
|
||||||
## Launchd (Gateway as LaunchAgent)
|
## Launchd (Gateway as LaunchAgent)
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ Plist location (per-user):
|
|||||||
- `~/Library/LaunchAgents/com.clawdbot.gateway.plist`
|
- `~/Library/LaunchAgents/com.clawdbot.gateway.plist`
|
||||||
|
|
||||||
Manager:
|
Manager:
|
||||||
- `apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift`
|
- [`apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift)
|
||||||
|
|
||||||
Behavior:
|
Behavior:
|
||||||
- “Clawdbot Active” enables/disables the LaunchAgent.
|
- “Clawdbot Active” enables/disables the LaunchAgent.
|
||||||
@ -77,7 +77,7 @@ Symptom (when mis-signed):
|
|||||||
|
|
||||||
Fix:
|
Fix:
|
||||||
- The bun executable needs JIT-ish permissions under hardened runtime.
|
- The bun executable needs JIT-ish permissions under hardened runtime.
|
||||||
- `scripts/codesign-mac-app.sh` signs `Relay/clawdbot` with:
|
- [`scripts/codesign-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/codesign-mac-app.sh) signs `Relay/clawdbot` with:
|
||||||
- `com.apple.security.cs.allow-jit`
|
- `com.apple.security.cs.allow-jit`
|
||||||
- `com.apple.security.cs.allow-unsigned-executable-memory`
|
- `com.apple.security.cs.allow-unsigned-executable-memory`
|
||||||
|
|
||||||
@ -87,17 +87,17 @@ Problem:
|
|||||||
- bun can’t load some native Node addons like `sharp` (and we don’t want to ship native addon trees for the gateway).
|
- bun can’t load some native Node addons like `sharp` (and we don’t want to ship native addon trees for the gateway).
|
||||||
|
|
||||||
Solution:
|
Solution:
|
||||||
- Central helper `src/media/image-ops.ts`
|
- Central helper [`src/media/image-ops.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/media/image-ops.ts)
|
||||||
- Prefers `/usr/bin/sips` on macOS (esp. when running under bun)
|
- Prefers `/usr/bin/sips` on macOS (esp. when running under bun)
|
||||||
- Falls back to `sharp` when available (Node/dev)
|
- Falls back to `sharp` when available (Node/dev)
|
||||||
- Used by:
|
- Used by:
|
||||||
- `src/web/media.ts` (optimize inbound/outbound images)
|
- [`src/web/media.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/web/media.ts) (optimize inbound/outbound images)
|
||||||
- `src/browser/screenshot.ts`
|
- [`src/browser/screenshot.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/browser/screenshot.ts)
|
||||||
- `src/agents/pi-tools.ts` (image sanitization)
|
- [`src/agents/pi-tools.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/agents/pi-tools.ts) (image sanitization)
|
||||||
|
|
||||||
## Browser control server
|
## Browser control server
|
||||||
|
|
||||||
The Gateway starts the browser control server (loopback only) from `src/gateway/server.ts`.
|
The Gateway starts the browser control server (loopback only) from [`src/gateway/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server.ts).
|
||||||
It’s started from the relay daemon process, so the relay binary includes Playwright deps.
|
It’s started from the relay daemon process, so the relay binary includes Playwright deps.
|
||||||
|
|
||||||
## Tests / smoke checks
|
## Tests / smoke checks
|
||||||
@ -125,7 +125,7 @@ Bun may leave dotfiles like `*.bun-build` in the repo root or subfolders.
|
|||||||
|
|
||||||
## DMG styling (human installer)
|
## DMG styling (human installer)
|
||||||
|
|
||||||
`scripts/create-dmg.sh` styles the DMG via Finder AppleScript.
|
[`scripts/create-dmg.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/create-dmg.sh) styles the DMG via Finder AppleScript.
|
||||||
|
|
||||||
Rules of thumb:
|
Rules of thumb:
|
||||||
- Use a **72dpi** background image that matches the Finder window size in points.
|
- Use a **72dpi** background image that matches the Finder window size in points.
|
||||||
|
|||||||
@ -70,7 +70,7 @@ If the app crashes when you try to allow **Speech Recognition** or **Microphone*
|
|||||||
```bash
|
```bash
|
||||||
tccutil reset All com.clawdbot.mac.debug
|
tccutil reset All com.clawdbot.mac.debug
|
||||||
```
|
```
|
||||||
2. If that fails, change the `BUNDLE_ID` temporarily in `scripts/package-mac-app.sh` to force a "clean slate" from macOS.
|
2. If that fails, change the `BUNDLE_ID` temporarily in [`scripts/package-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/package-mac-app.sh) to force a "clean slate" from macOS.
|
||||||
|
|
||||||
### Gateway "Starting..." indefinitely
|
### Gateway "Starting..." indefinitely
|
||||||
If the gateway status stays on "Starting...", check if a zombie process is holding the port:
|
If the gateway status stays on "Starting...", check if a zombie process is holding the port:
|
||||||
|
|||||||
@ -62,7 +62,7 @@ Use the release note generator so Sparkle renders formatted HTML notes:
|
|||||||
```bash
|
```bash
|
||||||
SPARKLE_PRIVATE_KEY_FILE=/Users/steipete/Library/CloudStorage/Dropbox/Backup/Sparkle/ed25519-private-key scripts/make_appcast.sh dist/Clawdbot-0.1.0.zip https://raw.githubusercontent.com/clawdbot/clawdbot/main/appcast.xml
|
SPARKLE_PRIVATE_KEY_FILE=/Users/steipete/Library/CloudStorage/Dropbox/Backup/Sparkle/ed25519-private-key scripts/make_appcast.sh dist/Clawdbot-0.1.0.zip https://raw.githubusercontent.com/clawdbot/clawdbot/main/appcast.xml
|
||||||
```
|
```
|
||||||
Generates HTML release notes from `CHANGELOG.md` (via `scripts/changelog-to-html.sh`) and embeds them in the appcast entry.
|
Generates HTML release notes from `CHANGELOG.md` (via [`scripts/changelog-to-html.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/changelog-to-html.sh)) and embeds them in the appcast entry.
|
||||||
Commit the updated `appcast.xml` alongside the release assets (zip + dSYM) when publishing.
|
Commit the updated `appcast.xml` alongside the release assets (zip + dSYM) when publishing.
|
||||||
|
|
||||||
## Publish & verify
|
## Publish & verify
|
||||||
|
|||||||
@ -5,11 +5,11 @@ read_when:
|
|||||||
---
|
---
|
||||||
# mac signing (debug builds)
|
# mac signing (debug builds)
|
||||||
|
|
||||||
This app is usually built from `scripts/package-mac-app.sh`, which now:
|
This app is usually built from [`scripts/package-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/package-mac-app.sh), which now:
|
||||||
|
|
||||||
- sets a stable debug bundle identifier: `com.clawdbot.mac.debug`
|
- sets a stable debug bundle identifier: `com.clawdbot.mac.debug`
|
||||||
- writes the Info.plist with that bundle id (override via `BUNDLE_ID=...`)
|
- writes the Info.plist with that bundle id (override via `BUNDLE_ID=...`)
|
||||||
- calls `scripts/codesign-mac-app.sh` to sign the main binary, bundled CLI, and app bundle so macOS treats each rebuild as the same signed bundle and keeps TCC permissions (notifications, accessibility, screen recording, mic, speech). For stable permissions, use a real signing identity; ad-hoc is opt-in and fragile (see [`docs/mac/permissions.md`](https://docs.clawd.bot/mac/permissions)).
|
- calls [`scripts/codesign-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/codesign-mac-app.sh) to sign the main binary, bundled CLI, and app bundle so macOS treats each rebuild as the same signed bundle and keeps TCC permissions (notifications, accessibility, screen recording, mic, speech). For stable permissions, use a real signing identity; ad-hoc is opt-in and fragile (see [`docs/mac/permissions.md`](https://docs.clawd.bot/mac/permissions)).
|
||||||
- uses `CODESIGN_TIMESTAMP=auto` by default; it enables trusted timestamps for Developer ID signatures. Set `CODESIGN_TIMESTAMP=off` to skip timestamping (offline debug builds).
|
- uses `CODESIGN_TIMESTAMP=auto` by default; it enables trusted timestamps for Developer ID signatures. Set `CODESIGN_TIMESTAMP=off` to skip timestamping (offline debug builds).
|
||||||
- inject build metadata into Info.plist: `ClawdbotBuildTimestamp` (UTC) and `ClawdbotGitCommit` (short hash) so the About pane can show build, git, and debug/release channel.
|
- inject build metadata into Info.plist: `ClawdbotBuildTimestamp` (UTC) and `ClawdbotGitCommit` (short hash) so the About pane can show build, git, and debug/release channel.
|
||||||
- **Packaging requires Bun**: The embedded gateway relay is compiled using `bun`. Ensure it is installed (`curl -fsSL https://bun.sh/install | bash`).
|
- **Packaging requires Bun**: The embedded gateway relay is compiled using `bun`. Ensure it is installed (`curl -fsSL https://bun.sh/install | bash`).
|
||||||
|
|||||||
@ -13,10 +13,10 @@ The macOS menu bar app shows the WebChat UI as a native SwiftUI view and reuses
|
|||||||
## Launch & debugging
|
## Launch & debugging
|
||||||
- Manual: Lobster menu → “Open Chat”.
|
- Manual: Lobster menu → “Open Chat”.
|
||||||
- Auto-open for testing: run `dist/Clawdbot.app/Contents/MacOS/Clawdbot --webchat` (or pass `--webchat` to the binary launched by launchd). The window opens on startup.
|
- Auto-open for testing: run `dist/Clawdbot.app/Contents/MacOS/Clawdbot --webchat` (or pass `--webchat` to the binary launched by launchd). The window opens on startup.
|
||||||
- Logs: see `./scripts/clawlog.sh` (subsystem `com.clawdbot`, category `WebChatSwiftUI`).
|
- Logs: see [`./scripts/clawlog.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/clawlog.sh) (subsystem `com.clawdbot`, category `WebChatSwiftUI`).
|
||||||
|
|
||||||
## How it’s wired
|
## How it’s wired
|
||||||
- Implementation: `apps/macos/Sources/Clawdbot/WebChatSwiftUI.swift` hosts `ClawdbotChatUI` and speaks to the Gateway over `GatewayConnection`.
|
- Implementation: [`apps/macos/Sources/Clawdbot/WebChatSwiftUI.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/Clawdbot/WebChatSwiftUI.swift) hosts `ClawdbotChatUI` and speaks to the Gateway over `GatewayConnection`.
|
||||||
- Data plane: Gateway WebSocket methods `chat.history`, `chat.send`, `chat.abort`; events `chat`, `agent`, `presence`, `tick`, `health`.
|
- Data plane: Gateway WebSocket methods `chat.history`, `chat.send`, `chat.abort`; events `chat`, `agent`, `presence`, `tick`, `health`.
|
||||||
- Session: usually primary (`main`); multiple transports (WhatsApp/Telegram/Discord/Desktop) share the same key. The onboarding flow uses a dedicated `onboarding` session to keep first-run setup separate.
|
- Session: usually primary (`main`); multiple transports (WhatsApp/Telegram/Discord/Desktop) share the same key. The onboarding flow uses a dedicated `onboarding` session to keep first-run setup separate.
|
||||||
|
|
||||||
|
|||||||
@ -37,4 +37,4 @@ read_when:
|
|||||||
- Prefer requiring a TeamID match for all privileged surfaces.
|
- Prefer requiring a TeamID match for all privileged surfaces.
|
||||||
- PeekabooBridge: `PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1` (DEBUG-only) may allow same-UID callers for local development.
|
- PeekabooBridge: `PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1` (DEBUG-only) may allow same-UID callers for local development.
|
||||||
- All communication remains local-only; no network sockets are exposed.
|
- All communication remains local-only; no network sockets are exposed.
|
||||||
- TCC prompts originate only from the GUI app bundle; run `scripts/package-mac-app.sh` so the signed bundle ID stays stable.
|
- TCC prompts originate only from the GUI app bundle; run [`scripts/package-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/package-mac-app.sh) so the signed bundle ID stays stable.
|
||||||
|
|||||||
@ -96,7 +96,7 @@ Notes:
|
|||||||
## Build & dev workflow (native)
|
## Build & dev workflow (native)
|
||||||
- `cd apps/macos && swift build` (debug) / `swift build -c release`.
|
- `cd apps/macos && swift build` (debug) / `swift build -c release`.
|
||||||
- Run app for dev: `swift run Clawdbot` (or Xcode scheme).
|
- Run app for dev: `swift run Clawdbot` (or Xcode scheme).
|
||||||
- Package app + CLI: `scripts/package-mac-app.sh` (builds bun CLI + gateway).
|
- Package app + CLI: [`scripts/package-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/package-mac-app.sh) (builds bun CLI + gateway).
|
||||||
- Tests: add Swift Testing suites under `apps/macos/Tests`.
|
- Tests: add Swift Testing suites under `apps/macos/Tests`.
|
||||||
|
|
||||||
## Open questions / decisions
|
## Open questions / decisions
|
||||||
|
|||||||
@ -84,7 +84,7 @@ The macOS packaging flow expects a stable Info.plist template at:
|
|||||||
apps/macos/Sources/Clawdbot/Resources/Info.plist
|
apps/macos/Sources/Clawdbot/Resources/Info.plist
|
||||||
```
|
```
|
||||||
|
|
||||||
`scripts/package-mac-app.sh` copies this template into the app bundle and patches dynamic fields
|
[`scripts/package-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/package-mac-app.sh) copies this template into the app bundle and patches dynamic fields
|
||||||
(bundle ID, version/build, Git SHA, Sparkle keys). This keeps the plist deterministic for SwiftPM
|
(bundle ID, version/build, Git SHA, Sparkle keys). This keeps the plist deterministic for SwiftPM
|
||||||
packaging and Nix builds (which do not rely on a full Xcode toolchain).
|
packaging and Nix builds (which do not rely on a full Xcode toolchain).
|
||||||
|
|
||||||
|
|||||||
@ -150,8 +150,8 @@ Nodes may include a `permissions` map in `node.list` / `node.describe`, keyed by
|
|||||||
|
|
||||||
## Where to look in code
|
## Where to look in code
|
||||||
|
|
||||||
- CLI wiring: `src/cli/nodes-cli.ts`
|
- CLI wiring: [`src/cli/nodes-cli.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/cli/nodes-cli.ts)
|
||||||
- Canvas snapshot decoding/temp paths: `src/cli/nodes-canvas.ts`
|
- Canvas snapshot decoding/temp paths: [`src/cli/nodes-canvas.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/cli/nodes-canvas.ts)
|
||||||
- Duration parsing for CLI: `src/cli/parse-duration.ts`
|
- Duration parsing for CLI: [`src/cli/parse-duration.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/cli/parse-duration.ts)
|
||||||
- iOS node commands: `apps/ios/Sources/Model/NodeAppModel.swift`
|
- iOS node commands: [`apps/ios/Sources/Model/NodeAppModel.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/ios/Sources/Model/NodeAppModel.swift)
|
||||||
- Android node commands: `apps/android/app/src/main/java/com/clawdbot/android/node/*`
|
- Android node commands: `apps/android/app/src/main/java/com/clawdbot/android/node/*`
|
||||||
|
|||||||
@ -9,7 +9,7 @@ Purpose: shared onboarding + config surfaces across CLI, macOS app, and Web UI.
|
|||||||
|
|
||||||
## Components
|
## Components
|
||||||
- Wizard engine: `src/wizard` (session + prompts + onboarding state).
|
- Wizard engine: `src/wizard` (session + prompts + onboarding state).
|
||||||
- CLI: `src/commands/onboard-*.ts` uses the wizard with the CLI prompter.
|
- CLI: [`src/commands/onboard-*.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/commands/onboard-*.ts) uses the wizard with the CLI prompter.
|
||||||
- Gateway RPC: wizard + config schema endpoints serve UI clients.
|
- Gateway RPC: wizard + config schema endpoints serve UI clients.
|
||||||
- macOS: SwiftUI onboarding uses the wizard step model.
|
- macOS: SwiftUI onboarding uses the wizard step model.
|
||||||
- Web UI: config form renders from JSON Schema + hints.
|
- Web UI: config form renders from JSON Schema + hints.
|
||||||
|
|||||||
@ -16,7 +16,7 @@ Follow-up hardening work ensures Telegram allowlists behave consistently across
|
|||||||
|
|
||||||
### [MED] F1: Telegram Allowlist Prefix Handling Is Case-Sensitive and Excludes `tg:`
|
### [MED] F1: Telegram Allowlist Prefix Handling Is Case-Sensitive and Excludes `tg:`
|
||||||
|
|
||||||
**Location**: `src/telegram/bot.ts`
|
**Location**: [`src/telegram/bot.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/telegram/bot.ts)
|
||||||
|
|
||||||
**Problem**: Inbound allowlist normalization only stripped a lowercase `telegram:` prefix. This rejected `TG:123` / `Telegram:123` and did not accept the `tg:` shorthand even though outbound send normalization already accepts `tg:` and case-insensitive prefixes.
|
**Problem**: Inbound allowlist normalization only stripped a lowercase `telegram:` prefix. This rejected `TG:123` / `Telegram:123` and did not accept the `tg:` shorthand even though outbound send normalization already accepts `tg:` and case-insensitive prefixes.
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ Follow-up hardening work ensures Telegram allowlists behave consistently across
|
|||||||
|
|
||||||
### [LOW] F2: Allowlist Entries Are Not Trimmed
|
### [LOW] F2: Allowlist Entries Are Not Trimmed
|
||||||
|
|
||||||
**Location**: `src/telegram/bot.ts`
|
**Location**: [`src/telegram/bot.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/telegram/bot.ts)
|
||||||
|
|
||||||
**Problem**: Allowlist entries are not trimmed; accidental whitespace causes mismatches.
|
**Problem**: Allowlist entries are not trimmed; accidental whitespace causes mismatches.
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ Follow-up hardening work ensures Telegram allowlists behave consistently across
|
|||||||
|
|
||||||
### Phase 1: Normalize Telegram Allowlist Inputs
|
### Phase 1: Normalize Telegram Allowlist Inputs
|
||||||
|
|
||||||
**File**: `src/telegram/bot.ts`
|
**File**: [`src/telegram/bot.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/telegram/bot.ts)
|
||||||
|
|
||||||
**Changes**:
|
**Changes**:
|
||||||
1. Trim allowlist entries and drop empty values.
|
1. Trim allowlist entries and drop empty values.
|
||||||
@ -53,7 +53,7 @@ Follow-up hardening work ensures Telegram allowlists behave consistently across
|
|||||||
|
|
||||||
### Phase 2: Add Coverage for Prefix + Whitespace
|
### Phase 2: Add Coverage for Prefix + Whitespace
|
||||||
|
|
||||||
**File**: `src/telegram/bot.test.ts`
|
**File**: [`src/telegram/bot.test.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/telegram/bot.test.ts)
|
||||||
|
|
||||||
**Add Tests**:
|
**Add Tests**:
|
||||||
- DM allowlist accepts `TG:` prefix with surrounding whitespace.
|
- DM allowlist accepts `TG:` prefix with surrounding whitespace.
|
||||||
@ -83,8 +83,8 @@ Follow-up hardening work ensures Telegram allowlists behave consistently across
|
|||||||
|
|
||||||
| File | Change Type | Description |
|
| File | Change Type | Description |
|
||||||
|------|-------------|-------------|
|
|------|-------------|-------------|
|
||||||
| `src/telegram/bot.ts` | Fix | Trim allowlist values; strip `telegram:` / `tg:` prefixes case-insensitively |
|
| [`src/telegram/bot.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/telegram/bot.ts) | Fix | Trim allowlist values; strip `telegram:` / `tg:` prefixes case-insensitively |
|
||||||
| `src/telegram/bot.test.ts` | Test | Add DM + group allowlist coverage for `TG:` prefix + whitespace |
|
| [`src/telegram/bot.test.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/telegram/bot.test.ts) | Test | Add DM + group allowlist coverage for `TG:` prefix + whitespace |
|
||||||
| [`docs/groups.md`](https://docs.clawd.bot/groups) | Docs | Mention `tg:` alias + case-insensitive prefixes |
|
| [`docs/groups.md`](https://docs.clawd.bot/groups) | Docs | Mention `tg:` alias + case-insensitive prefixes |
|
||||||
| [`docs/telegram.md`](https://docs.clawd.bot/telegram) | Docs | Mention `tg:` alias + case-insensitive prefixes |
|
| [`docs/telegram.md`](https://docs.clawd.bot/telegram) | Docs | Mention `tg:` alias + case-insensitive prefixes |
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ Presence entries are produced by multiple sources and then **merged**.
|
|||||||
|
|
||||||
The Gateway seeds a “self” entry at startup so UIs always show at least the current gateway host.
|
The Gateway seeds a “self” entry at startup so UIs always show at least the current gateway host.
|
||||||
|
|
||||||
Implementation: `src/infra/system-presence.ts` (`initSelfPresence()`).
|
Implementation: [`src/infra/system-presence.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/infra/system-presence.ts) (`initSelfPresence()`).
|
||||||
|
|
||||||
### 2) WebSocket connect (connection-derived presence)
|
### 2) WebSocket connect (connection-derived presence)
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ Every WS client must begin with a `connect` request. On successful handshake, th
|
|||||||
|
|
||||||
This is meant to answer: “Which clients are currently connected?”
|
This is meant to answer: “Which clients are currently connected?”
|
||||||
|
|
||||||
Implementation: `src/gateway/server.ts` (connect handling uses `connect.params.client.instanceId` when provided; otherwise falls back to `connId`).
|
Implementation: [`src/gateway/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server.ts) (connect handling uses `connect.params.client.instanceId` when provided; otherwise falls back to `connId`).
|
||||||
|
|
||||||
#### Why one-off CLI commands do not show up
|
#### Why one-off CLI commands do not show up
|
||||||
|
|
||||||
@ -58,8 +58,8 @@ Clients can publish richer periodic beacons via the `system-event` method. The m
|
|||||||
- `lastInputSeconds`
|
- `lastInputSeconds`
|
||||||
|
|
||||||
Implementation:
|
Implementation:
|
||||||
- Gateway: `src/gateway/server.ts` handles method `system-event` by calling `updateSystemPresence(...)`.
|
- Gateway: [`src/gateway/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server.ts) handles method `system-event` by calling `updateSystemPresence(...)`.
|
||||||
- mac app beaconing: `apps/macos/Sources/Clawdbot/PresenceReporter.swift`.
|
- mac app beaconing: [`apps/macos/Sources/Clawdbot/PresenceReporter.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/Clawdbot/PresenceReporter.swift).
|
||||||
|
|
||||||
### 4) Node bridge beacons (gateway-owned presence)
|
### 4) Node bridge beacons (gateway-owned presence)
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ for that node and starts periodic refresh beacons so it does not expire.
|
|||||||
- Connect/disconnect markers: `node-connected`, `node-disconnected`
|
- Connect/disconnect markers: `node-connected`, `node-disconnected`
|
||||||
- Periodic heartbeat: every 3 minutes (`reason: periodic`)
|
- Periodic heartbeat: every 3 minutes (`reason: periodic`)
|
||||||
|
|
||||||
Implementation: `src/gateway/server.ts` (node bridge handlers + timer beacons).
|
Implementation: [`src/gateway/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server.ts) (node bridge handlers + timer beacons).
|
||||||
|
|
||||||
## Merge + dedupe rules (why `instanceId` matters)
|
## Merge + dedupe rules (why `instanceId` matters)
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ Key points:
|
|||||||
- The best key is a stable, opaque `instanceId` that does not change across restarts.
|
- The best key is a stable, opaque `instanceId` that does not change across restarts.
|
||||||
- Keys are treated case-insensitively.
|
- Keys are treated case-insensitively.
|
||||||
|
|
||||||
Implementation: `src/infra/system-presence.ts` (`normalizePresenceKey()`).
|
Implementation: [`src/infra/system-presence.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/infra/system-presence.ts) (`normalizePresenceKey()`).
|
||||||
|
|
||||||
### mac app identity (stable UUID)
|
### mac app identity (stable UUID)
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ The mac app uses a persisted UUID as `instanceId` so:
|
|||||||
- renaming the Mac does not create a new “instance”
|
- renaming the Mac does not create a new “instance”
|
||||||
- debug/release builds can share the same identity
|
- debug/release builds can share the same identity
|
||||||
|
|
||||||
Implementation: `apps/macos/Sources/Clawdbot/InstanceIdentity.swift`.
|
Implementation: [`apps/macos/Sources/Clawdbot/InstanceIdentity.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/Clawdbot/InstanceIdentity.swift).
|
||||||
|
|
||||||
`displayName` (machine name) is used for UI, while `instanceId` is used for dedupe.
|
`displayName` (machine name) is used for UI, while `instanceId` is used for dedupe.
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ Presence entries are not permanent:
|
|||||||
- TTL: entries older than 5 minutes are pruned
|
- TTL: entries older than 5 minutes are pruned
|
||||||
- Max: map is capped at 200 entries (LRU by `ts`)
|
- Max: map is capped at 200 entries (LRU by `ts`)
|
||||||
|
|
||||||
Implementation: `src/infra/system-presence.ts` (`TTL_MS`, `MAX_ENTRIES`, pruning in `listSystemPresence()`).
|
Implementation: [`src/infra/system-presence.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/infra/system-presence.ts) (`TTL_MS`, `MAX_ENTRIES`, pruning in `listSystemPresence()`).
|
||||||
|
|
||||||
## Remote/tunnel caveat (loopback IPs)
|
## Remote/tunnel caveat (loopback IPs)
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ When a client connects over an SSH tunnel / local port forward, the Gateway may
|
|||||||
|
|
||||||
To avoid degrading an otherwise-correct client beacon IP, the Gateway avoids writing loopback remote addresses into presence entries.
|
To avoid degrading an otherwise-correct client beacon IP, the Gateway avoids writing loopback remote addresses into presence entries.
|
||||||
|
|
||||||
Implementation: `src/gateway/server.ts` (`isLoopbackAddress()`).
|
Implementation: [`src/gateway/server.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/server.ts) (`isLoopbackAddress()`).
|
||||||
|
|
||||||
## Consumers (who reads presence)
|
## Consumers (who reads presence)
|
||||||
|
|
||||||
@ -116,8 +116,8 @@ Implementation: `src/gateway/server.ts` (`isLoopbackAddress()`).
|
|||||||
The mac app’s Instances tab renders the result of `system-presence`.
|
The mac app’s Instances tab renders the result of `system-presence`.
|
||||||
|
|
||||||
Implementation:
|
Implementation:
|
||||||
- View: `apps/macos/Sources/Clawdbot/InstancesSettings.swift`
|
- View: [`apps/macos/Sources/Clawdbot/InstancesSettings.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/Clawdbot/InstancesSettings.swift)
|
||||||
- Store: `apps/macos/Sources/Clawdbot/InstancesStore.swift`
|
- Store: [`apps/macos/Sources/Clawdbot/InstancesStore.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/Clawdbot/InstancesStore.swift)
|
||||||
|
|
||||||
The Instances rows show a small presence indicator (Active/Idle/Stale) based on
|
The Instances rows show a small presence indicator (Active/Idle/Stale) based on
|
||||||
the last beacon age. The label is derived from the entry timestamp (`ts`).
|
the last beacon age. The label is derived from the entry timestamp (`ts`).
|
||||||
|
|||||||
@ -12,7 +12,7 @@ We now serialize command-based auto-replies (WhatsApp Web listener) through a ti
|
|||||||
- Serializing avoids competing for terminal/stdin, keeps logs readable, and reduces the chance of rate limits from upstream tools.
|
- Serializing avoids competing for terminal/stdin, keeps logs readable, and reduces the chance of rate limits from upstream tools.
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
- `src/process/command-queue.ts` holds a lane-aware FIFO queue and drains each lane synchronously.
|
- [`src/process/command-queue.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/process/command-queue.ts) holds a lane-aware FIFO queue and drains each lane synchronously.
|
||||||
- `runEmbeddedPiAgent` enqueues by **session key** (lane `session:<key>`) to guarantee only one active run per session.
|
- `runEmbeddedPiAgent` enqueues by **session key** (lane `session:<key>`) to guarantee only one active run per session.
|
||||||
- Each session run is then queued into a **global lane** (`main` by default) so overall parallelism is capped by `agent.maxConcurrent`.
|
- Each session run is then queued into a **global lane** (`main` by default) so overall parallelism is capped by `agent.maxConcurrent`.
|
||||||
- When verbose logging is enabled, queued commands emit a short notice if they waited more than ~2s before starting.
|
- When verbose logging is enabled, queued commands emit a short notice if they waited more than ~2s before starting.
|
||||||
|
|||||||
@ -172,7 +172,7 @@ Recommendation: **deep integration in Clawdbot**, but keep a separable core libr
|
|||||||
|
|
||||||
Shape:
|
Shape:
|
||||||
- `src/memory/*` (library-ish core; pure functions + sqlite adapter)
|
- `src/memory/*` (library-ish core; pure functions + sqlite adapter)
|
||||||
- `src/commands/memory/*.ts` (CLI glue)
|
- [`src/commands/memory/*.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/commands/memory/*.ts) (CLI glue)
|
||||||
|
|
||||||
## “S-Collide” / SuCo: when to use it (research)
|
## “S-Collide” / SuCo: when to use it (research)
|
||||||
|
|
||||||
|
|||||||
@ -77,7 +77,7 @@ pnpm install
|
|||||||
pnpm gateway:watch
|
pnpm gateway:watch
|
||||||
```
|
```
|
||||||
|
|
||||||
`gateway:watch` runs `src/index.ts gateway --force` and reloads on `src/**/*.ts` changes.
|
`gateway:watch` runs `src/index.ts gateway --force` and reloads on [`src/**/*.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/**/*.ts) changes.
|
||||||
|
|
||||||
### 2) Point the macOS app at your running Gateway
|
### 2) Point the macOS app at your running Gateway
|
||||||
|
|
||||||
|
|||||||
@ -109,12 +109,12 @@ https://api.slack.com/docs/conversations-api for the overview.
|
|||||||
- `im:write` (open DMs via `conversations.open` for user DMs)
|
- `im:write` (open DMs via `conversations.open` for user DMs)
|
||||||
https://api.slack.com/methods/conversations.open
|
https://api.slack.com/methods/conversations.open
|
||||||
- `channels:history`, `groups:history`, `im:history`, `mpim:history`
|
- `channels:history`, `groups:history`, `im:history`, `mpim:history`
|
||||||
(`conversations.history` in `src/slack/actions.ts`)
|
(`conversations.history` in [`src/slack/actions.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/slack/actions.ts))
|
||||||
https://api.slack.com/methods/conversations.history
|
https://api.slack.com/methods/conversations.history
|
||||||
- `channels:read`, `groups:read`, `im:read`, `mpim:read`
|
- `channels:read`, `groups:read`, `im:read`, `mpim:read`
|
||||||
(`conversations.info` in `src/slack/monitor.ts`)
|
(`conversations.info` in [`src/slack/monitor.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/slack/monitor.ts))
|
||||||
https://api.slack.com/methods/conversations.info
|
https://api.slack.com/methods/conversations.info
|
||||||
- `users:read` (`users.info` in `src/slack/monitor.ts` + `src/slack/actions.ts`)
|
- `users:read` (`users.info` in [`src/slack/monitor.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/slack/monitor.ts) + [`src/slack/actions.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/slack/actions.ts))
|
||||||
https://api.slack.com/methods/users.info
|
https://api.slack.com/methods/users.info
|
||||||
- `reactions:read`, `reactions:write` (`reactions.get` / `reactions.add`)
|
- `reactions:read`, `reactions:write` (`reactions.get` / `reactions.add`)
|
||||||
https://api.slack.com/methods/reactions.get
|
https://api.slack.com/methods/reactions.get
|
||||||
|
|||||||
@ -68,7 +68,7 @@ Example config:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- Tests: grammY-based paths in `src/telegram/*.test.ts` cover DM + group gating; add more media and webhook cases as needed.
|
- Tests: grammY-based paths in [`src/telegram/*.test.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/telegram/*.test.ts) cover DM + group gating; add more media and webhook cases as needed.
|
||||||
|
|
||||||
## Group etiquette
|
## Group etiquette
|
||||||
- Keep privacy mode off if you expect the bot to read all messages; with privacy on, it only sees commands/mentions.
|
- Keep privacy mode off if you expect the bot to read all messages; with privacy on, it only sees commands/mentions.
|
||||||
|
|||||||
@ -11,7 +11,7 @@ read_when:
|
|||||||
|
|
||||||
## Model latency bench (local keys)
|
## Model latency bench (local keys)
|
||||||
|
|
||||||
Script: `scripts/bench-model.ts`
|
Script: [`scripts/bench-model.ts`](https://github.com/clawdbot/clawdbot/blob/main/scripts/bench-model.ts)
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
- `source ~/.profile && bun scripts/bench-model.ts --runs 10`
|
- `source ~/.profile && bun scripts/bench-model.ts --runs 10`
|
||||||
|
|||||||
@ -247,17 +247,17 @@ Tools are exposed to the model in **two parallel channels**:
|
|||||||
2) **Provider tool schema**: the actual function/tool declarations sent to the model API.
|
2) **Provider tool schema**: the actual function/tool declarations sent to the model API.
|
||||||
|
|
||||||
In pi-mono:
|
In pi-mono:
|
||||||
- System prompt builder: `packages/coding-agent/src/core/system-prompt.ts`
|
- System prompt builder: [`packages/coding-agent/src/core/system-prompt.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/system-prompt.ts)
|
||||||
- Builds the `Available tools:` list from `toolDescriptions`.
|
- Builds the `Available tools:` list from `toolDescriptions`.
|
||||||
- Appends skills and project context.
|
- Appends skills and project context.
|
||||||
- Tool schemas passed to providers:
|
- Tool schemas passed to providers:
|
||||||
- OpenAI: `packages/ai/src/providers/openai-responses.ts` (`convertTools`)
|
- OpenAI: [`packages/ai/src/providers/openai-responses.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/providers/openai-responses.ts) (`convertTools`)
|
||||||
- Anthropic: `packages/ai/src/providers/anthropic.ts` (`convertTools`)
|
- Anthropic: [`packages/ai/src/providers/anthropic.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/providers/anthropic.ts) (`convertTools`)
|
||||||
- Gemini: `packages/ai/src/providers/google-shared.ts` (`convertTools`)
|
- Gemini: [`packages/ai/src/providers/google-shared.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/providers/google-shared.ts) (`convertTools`)
|
||||||
- Tool execution loop:
|
- Tool execution loop:
|
||||||
- Agent loop: `packages/ai/src/agent/agent-loop.ts`
|
- Agent loop: [`packages/ai/src/agent/agent-loop.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/agent/agent-loop.ts)
|
||||||
- Validates tool arguments and executes tools, then appends `toolResult` messages.
|
- Validates tool arguments and executes tools, then appends `toolResult` messages.
|
||||||
|
|
||||||
In Clawdbot:
|
In Clawdbot:
|
||||||
- System prompt append: `src/agents/system-prompt.ts`
|
- System prompt append: [`src/agents/system-prompt.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/agents/system-prompt.ts)
|
||||||
- Tool list injected via `createClawdbotCodingTools()` in `src/agents/pi-tools.ts`
|
- Tool list injected via `createClawdbotCodingTools()` in [`src/agents/pi-tools.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/agents/pi-tools.ts)
|
||||||
|
|||||||
@ -146,7 +146,7 @@ tccutil reset All com.clawdbot.mac.debug
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Fix 2: Force New Bundle ID**
|
**Fix 2: Force New Bundle ID**
|
||||||
If resetting doesn't work, change the `BUNDLE_ID` in `scripts/package-mac-app.sh` (e.g., add a `.test` suffix) and rebuild. This forces macOS to treat it as a new app.
|
If resetting doesn't work, change the `BUNDLE_ID` in [`scripts/package-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/package-mac-app.sh) (e.g., add a `.test` suffix) and rebuild. This forces macOS to treat it as a new app.
|
||||||
|
|
||||||
### Gateway stuck on "Starting..."
|
### Gateway stuck on "Starting..."
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ clawdbot gateway stop
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Fix 2: Check embedded gateway**
|
**Fix 2: Check embedded gateway**
|
||||||
Ensure the gateway relay was properly bundled. Run `./scripts/package-mac-app.sh` and ensure `bun` is installed.
|
Ensure the gateway relay was properly bundled. Run [`./scripts/package-mac-app.sh`](https://github.com/clawdbot/clawdbot/blob/main/scripts/package-mac-app.sh) and ensure `bun` is installed.
|
||||||
|
|
||||||
## Debug Mode
|
## Debug Mode
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,6 @@ Use SSH tunneling or Tailscale to reach the Gateway WS.
|
|||||||
- It registers as a Gateway client with `mode: "tui"` for presence and debugging.
|
- It registers as a Gateway client with `mode: "tui"` for presence and debugging.
|
||||||
|
|
||||||
## Files
|
## Files
|
||||||
- CLI: `src/cli/tui-cli.ts`
|
- CLI: [`src/cli/tui-cli.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/cli/tui-cli.ts)
|
||||||
- Runner: `src/tui/tui.ts`
|
- Runner: [`src/tui/tui.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/tui/tui.ts)
|
||||||
- Gateway client: `src/tui/gateway-chat.ts`
|
- Gateway client: [`src/tui/gateway-chat.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/tui/gateway-chat.ts)
|
||||||
|
|||||||
@ -7,12 +7,12 @@ read_when:
|
|||||||
|
|
||||||
Last updated: 2025-12-09
|
Last updated: 2025-12-09
|
||||||
|
|
||||||
We use TypeBox schemas in `src/gateway/protocol/schema.ts` as the single source of truth for the Gateway control plane (connect/req/res/event frames and payloads). All derived artifacts should be generated from these schemas, not edited by hand.
|
We use TypeBox schemas in [`src/gateway/protocol/schema.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/gateway/protocol/schema.ts) as the single source of truth for the Gateway control plane (connect/req/res/event frames and payloads). All derived artifacts should be generated from these schemas, not edited by hand.
|
||||||
|
|
||||||
## Current pipeline
|
## Current pipeline
|
||||||
|
|
||||||
- **TypeBox → JSON Schema**: `pnpm protocol:gen` writes `dist/protocol.schema.json` (draft-07) and runs AJV in the server tests.
|
- **TypeBox → JSON Schema**: `pnpm protocol:gen` writes [`dist/protocol.schema.json`](https://github.com/clawdbot/clawdbot/blob/main/dist/protocol.schema.json) (draft-07) and runs AJV in the server tests.
|
||||||
- **TypeBox → Swift**: `pnpm protocol:gen:swift` generates `apps/macos/Sources/ClawdbotProtocol/GatewayModels.swift`.
|
- **TypeBox → Swift**: `pnpm protocol:gen:swift` generates [`apps/macos/Sources/ClawdbotProtocol/GatewayModels.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/ClawdbotProtocol/GatewayModels.swift).
|
||||||
|
|
||||||
## Problem
|
## Problem
|
||||||
|
|
||||||
|
|||||||
@ -57,7 +57,7 @@ pnpm clawdbot health
|
|||||||
```
|
```
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- `pnpm build` matters when you run the packaged `clawdbot` binary (`dist/entry.js`) or use Node to run `dist/`.
|
- `pnpm build` matters when you run the packaged `clawdbot` binary ([`dist/entry.js`](https://github.com/clawdbot/clawdbot/blob/main/dist/entry.js)) or use Node to run `dist/`.
|
||||||
- If you run directly from TypeScript (`pnpm clawdbot ...` / `bun run clawdbot ...`), a rebuild is usually unnecessary, but **config migrations still apply** → run doctor.
|
- If you run directly from TypeScript (`pnpm clawdbot ...` / `bun run clawdbot ...`), a rebuild is usually unnecessary, but **config migrations still apply** → run doctor.
|
||||||
|
|
||||||
## Always run: `clawdbot doctor`
|
## Always run: `clawdbot doctor`
|
||||||
|
|||||||
@ -30,5 +30,5 @@ Updated: 2025-12-17
|
|||||||
- No fallback transport; the Gateway WS is required.
|
- No fallback transport; the Gateway WS is required.
|
||||||
|
|
||||||
## Dev notes
|
## Dev notes
|
||||||
- macOS glue: `apps/macos/Sources/Clawdbot/WebChatSwiftUI.swift` + `apps/macos/Sources/Clawdbot/WebChatManager.swift`.
|
- macOS glue: [`apps/macos/Sources/Clawdbot/WebChatSwiftUI.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/Clawdbot/WebChatSwiftUI.swift) + [`apps/macos/Sources/Clawdbot/WebChatManager.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/Clawdbot/WebChatManager.swift).
|
||||||
- Remote tunnel helper: `apps/macos/Sources/Clawdbot/RemotePortTunnel.swift`.
|
- Remote tunnel helper: [`apps/macos/Sources/Clawdbot/RemotePortTunnel.swift`](https://github.com/clawdbot/clawdbot/blob/main/apps/macos/Sources/Clawdbot/RemotePortTunnel.swift).
|
||||||
|
|||||||
@ -151,6 +151,6 @@ WhatsApp requires a real mobile number for verification. VoIP and virtual number
|
|||||||
- Troubleshooting guide: [`docs/troubleshooting.md`](https://docs.clawd.bot/troubleshooting).
|
- Troubleshooting guide: [`docs/troubleshooting.md`](https://docs.clawd.bot/troubleshooting).
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
- `src/web/auto-reply.test.ts` (mention gating, history injection, reply flow)
|
- [`src/web/auto-reply.test.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/web/auto-reply.test.ts) (mention gating, history injection, reply flow)
|
||||||
- `src/web/monitor-inbox.test.ts` (inbound parsing + reply context)
|
- [`src/web/monitor-inbox.test.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/web/monitor-inbox.test.ts) (inbound parsing + reply context)
|
||||||
- `src/web/outbound.test.ts` (send mapping + media)
|
- [`src/web/outbound.test.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/web/outbound.test.ts) (send mapping + media)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user