Use when editing NanoClaw backend TypeScript under src. Covers Express routes, conversation flow, database persistence, runtime state, providers, scheduler, and agent execution.
Install
mkdir -p .claude/skills/nanoclaw-backend-ts && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13666" && unzip -o skill.zip -d .claude/skills/nanoclaw-backend-ts && rm skill.zipInstalls to .claude/skills/nanoclaw-backend-ts
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when editing NanoClaw backend TypeScript under src. Covers Express routes, conversation flow, database persistence, runtime state, providers, scheduler, and agent execution.177 chars✓ has a “when” trigger
About this skill
NanoClaw Backend TS
Use this skill for backend changes under src/**.
Stack
- Node.js + TypeScript
- Express for Web API
better-sqlite3, MySQL/TiDB, and PostgreSQL viasrc/database/*- Channel adapters for Web, Feishu, Telegram, Discord, Slack, Gmail, and WhatsApp
Current Module Map
src/index.ts— process startup and runtime orchestration entrysrc/runtime/*— runtime state, dispatch, channel lifecycle, realtime events, persistence, startup hydrationsrc/web/web-server.ts— Express/WebSocket compositionsrc/web/*— web support services, uploads, terminal shell, doctor, IPCsrc/routes/*— HTTP route contracts and dependency injectionsrc/db.ts,src/db/*— business persistence, schema DDL, SQL adapters, engine accesssrc/database/*— database engine abstraction and dialect implementationssrc/agent/agent-runner.ts,src/agent/*— local agent process bridge, mounts, snapshots, workspace cleanupsrc/subagent/*— subagent runtime registry, filesystem, lifecycle control, recoverysrc/provider/*— provider registry, adapters, API calls, HTTP config, model serializationsrc/assistant/*— assistant runtime, config, MCP bindings, repo bindingssrc/conversation/*— conversation support, ownership, summaries, output merging, channel metadatasrc/channels/*— channel adapters and per-channel metadatasrc/repo-review.ts,src/repo-review/*— repo review service, executor, budget, digest, git, sync, repository servicesrc/code-intelligence/*— code search, code index, code map, document searchsrc/config-store.ts,src/config/*— runtime config and web-search configsrc/slash-commands/*— slash command parser and handlerssrc/scheduler/*— task scheduler, task draft/schedule, trash cleanupsrc/stock-analysis/*,src/soul/*,src/extension/live2d-service.ts— domain servicessrc/types.ts,src/types/*— shared backend types- tests generally live beside domains or at
src/*.test.ts
Working Rules
- Keep transport metadata and user-facing naming separate: channel-discovered names belong in
name; user-defined labels belong incustom_title. - For conversation creation or routing changes, check route contract, runtime dispatch, persistence, websocket events, and frontend expectations together.
- For restart/recovery bugs, inspect both in-memory state and persisted router state.
- If touching message consumption or replay, verify cursor advancement, pending state, restart behavior, and final reply acknowledgement together.
- Do not silently broaden route contracts. Keep backward compatibility where practical.
- When editing a barrel module, put business logic in the domain submodule and export only stable public API.
Database Rules
- Schema changes must cover SQLite, MySQL/TiDB, and PostgreSQL:
src/db/schema-sqlite.tssrc/db/schema-mysql.tssrc/db/schema-postgres.ts
- No foreign keys in any dialect; application code owns referential integrity.
- MySQL/TiDB index byte budget is
SUM(varchar_len * 4) <= 3072. - Use the smallest reasonable VARCHAR tier:
VARCHAR(64)for UUID/nanoid and*_idVARCHAR(128)for medium names, JIDs, scopes, folders, branches, keysVARCHAR(255)for long bounded strings such as tokens, idempotency keys, path refs, cache keys, emailTEXT/MEDIUMTEXTfor unbounded content and JSON arrays
- Do not add MySQL/TiDB defaults to TEXT/MEDIUMTEXT columns.
- Use
DEFAULT '[]', notDEFAULT ('[]'), for TiDB-compatible literal defaults. - Do not use SQL
||for string concatenation; MySQL treats it as logical OR. - Business SQL should use
LIMIT ? OFFSET ?; MySQL inlining is handled by the engine layer. - New composite-PK tables using
INSERT OR REPLACEmust be registered inPG_TABLE_PK_COLUMNS. - Custom
INSERT OR IGNOREconflict columns must be registered inPG_TABLE_IGNORE_CONFLICT_COLUMNS.
Verification
- Backend build:
npm run build - Targeted test:
npx vitest run src/<name>.test.ts - Merge-ready confidence:
npm run check