@slycode/slycode 0.1.18 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/web/.next/BUILD_ID +1 -1
  2. package/dist/web/.next/build-manifest.json +2 -2
  3. package/dist/web/.next/server/app/_global-error.html +2 -2
  4. package/dist/web/.next/server/app/_global-error.rsc +1 -1
  5. package/dist/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  6. package/dist/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  7. package/dist/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  8. package/dist/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  9. package/dist/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/dist/web/.next/server/app/_not-found.html +1 -1
  11. package/dist/web/.next/server/app/_not-found.rsc +1 -1
  12. package/dist/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  13. package/dist/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  14. package/dist/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  15. package/dist/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  16. package/dist/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  17. package/dist/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  18. package/dist/web/.next/server/app/page_client-reference-manifest.js +1 -1
  19. package/dist/web/.next/server/app/project/[id]/page_client-reference-manifest.js +1 -1
  20. package/dist/web/.next/server/chunks/[root-of-the-server]__46b023d4._.js +1 -1
  21. package/dist/web/.next/server/chunks/[root-of-the-server]__4c7995bf._.js +1 -1
  22. package/dist/web/.next/server/chunks/[root-of-the-server]__4d0d3464._.js +1 -1
  23. package/dist/web/.next/server/chunks/[root-of-the-server]__543058c2._.js +3 -3
  24. package/dist/web/.next/server/chunks/[root-of-the-server]__6d330d40._.js +1 -1
  25. package/dist/web/.next/server/chunks/[root-of-the-server]__884d73e4._.js +1 -1
  26. package/dist/web/.next/server/chunks/[root-of-the-server]__949bb248._.js +1 -1
  27. package/dist/web/.next/server/chunks/[root-of-the-server]__949d814c._.js +1 -1
  28. package/dist/web/.next/server/chunks/[root-of-the-server]__aa814a86._.js +1 -1
  29. package/dist/web/.next/server/chunks/[root-of-the-server]__ad64e04f._.js +2 -2
  30. package/dist/web/.next/server/chunks/[root-of-the-server]__baa99257._.js +1 -1
  31. package/dist/web/.next/server/chunks/[root-of-the-server]__bbb4b3ac._.js +1 -1
  32. package/dist/web/.next/server/chunks/[root-of-the-server]__bf286c26._.js +1 -1
  33. package/dist/web/.next/server/chunks/[root-of-the-server]__ce429522._.js +1 -1
  34. package/dist/web/.next/server/chunks/[root-of-the-server]__d38c7a96._.js +1 -1
  35. package/dist/web/.next/server/chunks/[root-of-the-server]__e9b0e744._.js +1 -1
  36. package/dist/web/.next/server/chunks/[root-of-the-server]__f1fe18e6._.js +2 -2
  37. package/dist/web/.next/server/chunks/ssr/[root-of-the-server]__677b7660._.js +1 -1
  38. package/dist/web/.next/server/chunks/ssr/[root-of-the-server]__79c0188d._.js +1 -1
  39. package/dist/web/.next/server/chunks/ssr/src_lib_registry_ts_2fc87c9c._.js +1 -1
  40. package/dist/web/.next/server/pages/404.html +1 -1
  41. package/dist/web/.next/server/pages/500.html +2 -2
  42. package/dist/web/.next/static/chunks/7660448872d80e27.js +4 -0
  43. package/dist/web/.next/static/chunks/{4793f1f83885d568.js → b694f741bb34ac84.js} +1 -1
  44. package/dist/web/src/components/ClaudeTerminalPanel.tsx +15 -11
  45. package/dist/web/src/lib/store-scanner.ts +70 -10
  46. package/dist/web/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +1 -1
  48. package/templates/kanban-seed.json +1 -1
  49. package/dist/store/.backups/actions/onboard.md +0 -33
  50. package/dist/store/.backups/actions/review.md +0 -37
  51. package/dist/store/.backups/actions/show-card.md +0 -20
  52. package/dist/store/.backups/checkpoint/SKILL.md +0 -43
  53. package/dist/store/.backups/context-priming/SKILL.md +0 -153
  54. package/dist/store/.backups/context-priming/references/area-index.md +0 -101
  55. package/dist/store/.backups/context-priming/references/areas/claude-actions.md +0 -120
  56. package/dist/store/.backups/context-priming/references/areas/messaging.md +0 -177
  57. package/dist/store/.backups/context-priming/references/areas/scripts-deployment.md +0 -138
  58. package/dist/store/.backups/context-priming/references/areas/skills.md +0 -135
  59. package/dist/store/.backups/context-priming/references/areas/terminal-bridge.md +0 -232
  60. package/dist/store/.backups/context-priming/references/areas/web-frontend.md +0 -252
  61. package/dist/store/.backups/context-priming/references/maintenance.md +0 -128
  62. package/dist/store/.ignored-updates.json +0 -37
  63. package/dist/store/actions/analyse-implementation.md +0 -72
  64. package/dist/store/actions/archive.md +0 -36
  65. package/dist/store/actions/clear.md +0 -13
  66. package/dist/store/actions/complete.md +0 -34
  67. package/dist/store/actions/continue.md +0 -20
  68. package/dist/store/agents/doc-updater.md +0 -619
  69. package/dist/store/mcp/context7.json +0 -8
  70. package/dist/store/skills/claude-code-docs-maintainer/SKILL.md +0 -168
  71. package/dist/store/skills/create-command/SKILL.md +0 -92
  72. package/dist/store/skills/doc-discovery/SKILL.md +0 -18
  73. package/dist/store/skills/doc-update/SKILL.md +0 -15
  74. package/dist/store/skills/dummy/SKILL.md +0 -22
  75. package/dist/store/skills/interactive-explainer/SKILL.md +0 -557
  76. package/dist/store/skills/interactive-explainer/assets/base_template.html +0 -780
  77. package/dist/store/skills/interactive-explainer/references/design_patterns.md +0 -486
  78. package/dist/store/skills/interactive-explainer/references/visualization_libraries.md +0 -512
  79. package/dist/store/skills/problem_summary/SKILL.md +0 -11
  80. package/dist/store/skills/reference-fetch/SKILL.md +0 -206
  81. package/dist/store/skills/skill-creator/LICENSE.txt +0 -202
  82. package/dist/store/skills/skill-creator/SKILL.md +0 -246
  83. package/dist/store/skills/skill-creator/scripts/init_skill.py +0 -303
  84. package/dist/store/skills/skill-creator/scripts/package_skill.py +0 -110
  85. package/dist/store/skills/skill-creator/scripts/quick_validate.py +0 -65
  86. package/dist/web/.next/static/chunks/5b44413f6e5b9e66.js +0 -4
  87. /package/dist/web/.next/static/{heUrgyJAcziZUlrZpGOPA → BbBq5FNe-sYRKe8Pc24UW}/_buildManifest.js +0 -0
  88. /package/dist/web/.next/static/{heUrgyJAcziZUlrZpGOPA → BbBq5FNe-sYRKe8Pc24UW}/_clientMiddlewareManifest.json +0 -0
  89. /package/dist/web/.next/static/{heUrgyJAcziZUlrZpGOPA → BbBq5FNe-sYRKe8Pc24UW}/_ssgManifest.js +0 -0
@@ -1,177 +0,0 @@
1
- # Messaging Service
2
-
3
- Updated: 2026-02-14
4
-
5
- ## Overview
6
-
7
- Multi-channel messaging service for remote AI interaction via Telegram (and future channels). Supports text and voice messages, project selection, voice swapping, response mode/tone preferences, multi-provider support (Claude/Gemini/Codex), stop command for session interruption, permission mismatch detection, context-aware command filtering, and two-way communication with AI sessions through the terminal bridge. Runs as a standalone Node/Express service with a CLI for outbound messages.
8
-
9
- ## Key Files
10
-
11
- ### Service Core
12
- - `messaging/src/index.ts` - Main entry, channel wiring, HTTP server, bot commands, stop interception
13
- - `messaging/src/types.ts` - Channel interface, configs, bridge types, ResponseMode
14
- - `messaging/src/state.ts` - StateManager: project selection, voice state, response mode, voice tone, provider selection, persistence
15
- - `messaging/src/bridge-client.ts` - BridgeClient: session management, provider-aware creation, permission mismatch detection, activity watching, soft stop
16
-
17
- ### Channels
18
- - `messaging/src/channels/telegram.ts` - TelegramChannel: bot polling, inline buttons, chat actions
19
-
20
- ### Voice Pipeline
21
- - `messaging/src/stt.ts` - Whisper STT via OpenAI API
22
- - `messaging/src/tts.ts` - ElevenLabs v3 TTS with audio tag support, optional voice override
23
- - `messaging/src/voices.ts` - Voice search across personal + community library (v2 + v1 APIs)
24
-
25
- ### Command System
26
- - `messaging/src/command-filter.ts` - Context-aware command filtering by terminal class, session state, card type
27
- - `messaging/src/kanban-client.ts` - Direct access to project kanban boards for card metadata
28
-
29
- ### CLI & Skill
30
- - `messaging/src/cli.ts` - CLI tool for sending text/voice from Claude skills
31
- - `.claude/skills/messaging/SKILL.md` - Skill definition (v2.2.0) with mode/tone system and audio tags
32
-
33
- ### Config
34
- - `messaging/package.json` - Dependencies: node-telegram-bot-api, openai, express, dotenv
35
- - `messaging/tsconfig.json` - TypeScript config (ESM, ES2022)
36
- - `.env` - Runtime config (tokens, API keys, ports)
37
-
38
- ## Channel Interface
39
-
40
- ```typescript
41
- Channel {
42
- name: string;
43
- start(): Promise<void>;
44
- stop(): void;
45
- onText(handler): void;
46
- onVoice(handler): void;
47
- onCommand(command, handler): void;
48
- onProjectSelect(handler): void;
49
- sendText(text): Promise<void>; // With Markdown
50
- sendTextRaw(text): Promise<void>; // Without Markdown (preserves [brackets])
51
- sendVoice(audio: Buffer): Promise<void>;
52
- sendProjectList(projects): Promise<void>;
53
- sendTyping(): Promise<void>;
54
- sendChatAction(action): Promise<void>;
55
- sendVoiceList?(voices): Promise<void>; // Optional
56
- onVoiceSelect?(handler): void; // Optional
57
- isReady(): boolean;
58
- }
59
- ```
60
-
61
- ## Bot Commands
62
-
63
- - `/start` - Help text with available commands
64
- - `/projects` - Inline keyboard for project selection
65
- - `/select N` - Select project by number
66
- - `/status` - Current project, voice, response mode, and tone
67
- - `/voice` - Search/swap TTS voices, reset to default
68
- - `/voice <name>` - Search voices, auto-select on exact match, inline buttons for multiple
69
-
70
- ## Message Flow
71
-
72
- ### Inbound (user → Claude)
73
- 1. User sends text/voice on Telegram
74
- 2. **Stop interception**: "stop" text (case-insensitive) sends Escape to active session instead of forwarding
75
- 3. TelegramChannel routes to handler in index.ts
76
- 4. Voice: `record_voice` chat action → Whisper transcription → typing indicator
77
- 5. BridgeClient.ensureSession() creates/finds session (with selected provider, always skipPermissions)
78
- 6. If permission mismatch (existing session without skipPermissions), warns user and offers restart
79
- 7. BridgeClient.sendMessage() writes text + CR to PTY
80
- 8. BridgeClient.watchActivity() polls /stats, sends typing while active
81
-
82
- ### Outbound (Claude → user)
83
- 1. Claude skill calls CLI: `tsx cli.ts send "message" [--tts]`
84
- 2. CLI POSTs to HTTP server `/send` or `/voice`
85
- 3. `/send` → channel.sendText()
86
- 4. `/voice` → `upload_voice` chat action → TTS generation → channel.sendVoice() + sendTextRaw()
87
-
88
- ### Stop Command
89
- 1. User sends "stop" (exact, case-insensitive)
90
- 2. BridgeClient.stopSession() calls `POST /sessions/:name/stop` (sends Escape key)
91
- 3. Returns feedback: "Interrupted active session" or "Already stopped"
92
- 4. Message NOT forwarded as a prompt
93
-
94
- ## Response Mode System
95
-
96
- - **Mode**: `text` | `voice` | `both` - determines response format
97
- - `text` - Text replies only (default)
98
- - `voice` - Voice messages with text companion
99
- - `both` - Both voice and text responses
100
- - **Tone**: Free-text description of voice style and length
101
- - Mode shown in message footer: `(Reply using /messaging | Mode: text)`
102
- - Persisted in messaging-state.json
103
-
104
- ## Command Filtering
105
-
106
- - `CommandFilter.loadCommands()` - Hot-reloads commands.json on each call
107
- - `CommandFilter.filterCommands(terminalClass, sessionState, cardType?)` - Context-aware filtering
108
- - `CommandFilter.resolveTemplate(prompt, context)` - Template variable resolution
109
- - `CommandFilter.getTerminalClass(target)` - Maps navigation target to terminal class
110
- - Supports card context from KanbanClient for prompt templates
111
-
112
- ## Kanban Client
113
-
114
- - `KanbanClient.getBoard(projectId)` - Load project's kanban board
115
- - `KanbanClient.getCard(projectId, cardId)` - Find card with its stage
116
- - `KanbanClient.getCardsByStage(projectId, stage)` - Cards in a stage
117
- - Resolves kanban.json paths per project
118
-
119
- ## Voice System
120
-
121
- - **STT**: OpenAI Whisper (`whisper-1`), accepts OGG from Telegram
122
- - **TTS**: ElevenLabs v3 (`eleven_v3`), supports `[tag]` audio tags
123
- - **Voice selection**: Persisted in messaging-state.json, overrides .env default
124
- - **Voice search**: Queries both `/v2/voices` (personal) and `/v1/shared-voices` (community), deduplicates
125
- - **Conversion**: ffmpeg MP3→OGG/Opus for Telegram compatibility
126
-
127
- ## Provider Support
128
-
129
- - `StateManager.selectedProvider` - Persisted provider choice (default: 'claude')
130
- - Session names include provider segment: `{projectId}:{provider}:global`
131
- - `getLegacySessionName()` provides backward-compat format for existing session lookups
132
- - Messaging always forces `skipPermissions: true` (remote interaction can't approve prompts)
133
- - `BridgeClient.ensureSession()` returns `{ session, permissionMismatch? }` — detects sessions started from web UI without skip-permissions
134
- - `BridgeClient.restartSession()` stops old session and creates fresh one with correct provider + skip-permissions
135
-
136
- ## State Persistence
137
-
138
- `messaging-state.json` stores:
139
- - `selectedProjectId` - Active project
140
- - `selectedProvider` - Active AI provider (claude/gemini/codex)
141
- - `voiceId` / `voiceName` - Selected TTS voice (null = use .env default)
142
- - `responseMode` - text/voice/both preference
143
- - `voiceTone` - Free-text tone description
144
-
145
- Projects loaded from `projects/registry.json` at startup.
146
-
147
- ## HTTP Endpoints
148
-
149
- - `POST /send` - Send text message to active channel
150
- - `POST /voice` - Generate TTS and send voice + text to channel
151
- - `GET /health` - Service health check (channel name, ready state)
152
-
153
- ## Patterns & Invariants
154
-
155
- - Chat actions for status: `record_voice` (transcribing), `typing` (processing), `upload_voice` (TTS)
156
- - Session names include provider: `{projectId}:{provider}:global` (with legacy fallback)
157
- - Messages include channel header: `[Telegram] text (Reply using /messaging | Mode: text)`
158
- - Voice messages: `[Telegram/Voice] transcription (Reply using /messaging | Mode: text)`
159
- - sendTextRaw used for voice text companions (preserves [audio tags]) and voice IDs
160
- - Authorization: single authorized user ID per Telegram bot
161
- - Telegram message limit: 4096 chars, auto-split at newline boundaries
162
- - "stop" text intercepted before forwarding to session (soft stop via Escape key)
163
- - Card titles truncated to 35 chars in breadcrumb rendering
164
-
165
- ## When to Expand
166
-
167
- - Adding new channel → implement Channel interface, add to createChannel() in index.ts
168
- - Voice issues → tts.ts (generation), voices.ts (search), stt.ts (transcription)
169
- - Bot command issues → index.ts setupChannel()
170
- - Bridge routing → bridge-client.ts
171
- - State persistence → state.ts
172
- - Telegram-specific behavior → channels/telegram.ts
173
- - Command filtering → command-filter.ts, kanban-client.ts
174
- - Stop command → bridge-client.ts stopSession(), index.ts stop interception
175
- - Response modes → state.ts, SKILL.md mode/tone guidelines
176
- - Provider selection → state.ts (selectedProvider), bridge-client.ts (ensureSession provider param)
177
- - Permission mismatch → bridge-client.ts ensureSession/sendMessage permissionMismatch detection
@@ -1,138 +0,0 @@
1
- # Scripts & Deployment
2
-
3
- Updated: 2026-02-11
4
-
5
- ## Overview
6
-
7
- SlyCode has a two-tier deployment model: **dev** (individual services via tmux) and **prod** (background processes with builds). All scripts live in `scripts/`. A guided installer (`setup.sh`) handles first-time and repeat setup. No hardcoded paths — everything is derived at runtime.
8
-
9
- ## Scripts
10
-
11
- | Script | Purpose |
12
- |--------|---------|
13
- | `setup.sh` | Interactive guided installer — deps, builds, CLI symlinks, optional services, linger |
14
- | `sly-start.sh` | Build all services then start in production (background processes or systemd/launchd) |
15
- | `sly-stop.sh` | Stop production services by finding processes on their ports |
16
- | `sly-restart.sh` | Stop then start (delegates to sly-stop + sly-start) |
17
- | `sly-dev.sh` | Tmux session "sly" with three side-by-side panes running `npm run dev` |
18
- | `kanban.js` | Kanban CLI (standalone Node.js, no build needed) |
19
- | `scaffold.js` | Project scaffolding CLI (standalone Node.js) |
20
-
21
- ## Port Architecture
22
-
23
- Two separate port ranges — dev and prod never overlap:
24
-
25
- | Service | Dev port | Prod port | Env var |
26
- |---------|----------|-----------|---------|
27
- | Web | 3003 | 7591 | `WEB_PORT` |
28
- | Bridge | 3004 | 7592 | `BRIDGE_PORT` |
29
- | Messaging | 3005 | 7593 | `MESSAGING_SERVICE_PORT` |
30
-
31
- - **7591/2/3**: "sly" = 759 on a phone keypad
32
- - **Dev ports**: hardcoded in each service's `package.json` dev scripts
33
- - **Prod ports**: configured in `.env`, read by `sly-start.sh`, passed as `PORT` env var to `npm start`
34
- - `BRIDGE_URL` must match bridge port — `sly-start.sh` derives it automatically
35
- - Next.js reads `PORT` env var natively (no `--port` flag in prod `npm start`)
36
-
37
- ## Process Management
38
-
39
- ### Production (`sly-start.sh` / `sly-stop.sh`)
40
-
41
- - **Start**: runs `npm start` in background with `nohup` (assumes services are already built via `setup.sh`)
42
- - **Stop**: finds PIDs by port (not PID files — those are unreliable with npm subshells), kills process tree with `pkill -P` + `kill`
43
- - Ports file at `~/.slycode/ports` records which ports were started for stop to read
44
- - Health check after start: verifies each port is listening
45
- - Log files: `~/.slycode/logs/{web,bridge,messaging}.log` with 10MB rotation
46
-
47
- ### Dev (`sly-dev.sh`)
48
-
49
- - Creates tmux session "sly" with three horizontal panes
50
- - Each pane runs `npm run dev` in its service directory
51
- - `session-closed` hook calls `sly-stop.sh` to prevent zombie processes
52
- - If session already exists, just attaches
53
- - Switch panes: `Ctrl-b` + arrows. Zoom: `Ctrl-b z`
54
-
55
- ### Platform Services (optional, via `setup.sh`)
56
-
57
- - **Linux**: systemd user services (`~/.config/systemd/user/slycode-{web,bridge,messaging}.service`)
58
- - **macOS**: launchd user agents (`~/Library/LaunchAgents/com.slycode.{web,bridge,messaging}.plist`)
59
- - `sly-start.sh` / `sly-stop.sh` detect installed services and use them instead of background processes
60
- - `setup.sh --service` installs, `setup.sh --remove-service` removes
61
-
62
- ## Setup Flow (`setup.sh`)
63
-
64
- 1. Welcome banner (platform, SlyCode root, Node version)
65
- 2. Create directories (`~/bin`, `~/.slycode/logs`)
66
- 3. `npm install` in web, bridge, messaging
67
- 4. Build bridge, messaging, web (web last — heaviest, needs most memory)
68
- 5. `chmod +x` on CLI scripts
69
- 6. Symlink CLIs to `~/bin` (sly-kanban, sly-scaffold, sly-messaging)
70
- 7. Update `registry.json` with correct SlyCode path
71
- 8. Copy `.env.example` to `.env` if missing
72
- 9. Prompt: install as system service?
73
- 10. Linux: check linger, offer to enable
74
-
75
- **Flags**: `--yes` (non-interactive), `--service` (auto-install services), `--remove-service` (cleanup)
76
-
77
- ## Global CLIs
78
-
79
- Symlinked to `~/bin` by `setup.sh`:
80
-
81
- | Command | Target | Type |
82
- |---------|--------|------|
83
- | `sly-kanban` | `scripts/kanban.js` | Standalone Node.js |
84
- | `sly-scaffold` | `scripts/scaffold.js` | Standalone Node.js |
85
- | `sly-messaging` | `messaging/dist/cli.js` | Built from TypeScript |
86
-
87
- ### CLI Port Detection (`sly-messaging`)
88
-
89
- The CLI auto-detects which mode (dev/prod) the messaging service is running in:
90
-
91
- 1. Read cached port from `~/.slycode/messaging-port` (if exists), try it first
92
- 2. Probe dev port (3005) then prod port (7593) via `/health`
93
- 3. Cache the successful port for next time
94
-
95
- This means `sly-messaging` works regardless of whether you started with `sly-dev.sh` or `sly-start.sh`. After the first successful call, subsequent calls skip probing entirely.
96
-
97
- ## Key Design Decisions
98
-
99
- ### No hardcoded paths anywhere
100
- - Web: `web/src/lib/paths.ts` derives SlyCode root from `process.cwd()` (detects `/web` suffix)
101
- - Bridge: reads `BRIDGE_PORT` from env
102
- - Messaging: CLI auto-detects service port (dev 3005 / prod 7593) with caching; service reads port from env
103
- - Skills: reference `sly-kanban` and `sly-messaging` by global command name, not paths
104
- - Documentation: uses `<slycode-root>` placeholder instead of absolute paths
105
- - `registry.json`: `setup.sh` updates the SlyCode path entry at install time
106
-
107
- ### Stop by port, not PID files
108
- PID files are unreliable because `npm start` spawns child processes — the recorded PID is the npm wrapper which dies, leaving orphaned node/next-server children. Port-based discovery always finds the actual listening process.
109
-
110
- ### Build in setup, not start
111
- `sly-start.sh` does NOT build — it assumes services are already built. Builds happen in `setup.sh` (which users rerun when code changes). This keeps start fast and avoids memory-heavy builds blocking service startup.
112
-
113
- ### XDG_RUNTIME_DIR fix
114
- Code-server terminals don't set `XDG_RUNTIME_DIR`, breaking `systemctl --user`. All scripts set it to `/run/user/$(id -u)` if missing and the directory exists. Safe, standard, no side effects.
115
-
116
- ### bridge-sessions.json protection
117
- - Path resolved via `__dirname` (never relative — avoids reading wrong file from wrong cwd)
118
- - Only starts fresh on ENOENT (file doesn't exist = first run)
119
- - Any other read error crashes loudly instead of silently wiping session data
120
- - Saves are atomic (write `.tmp` then `rename`)
121
-
122
- ### Bridge CWD validation
123
- Bridge requires absolute path for session `cwd` — no defaults, no relative paths. This ensures Claude associates sessions with the correct project directory in `~/.claude/projects/`.
124
-
125
- ## Env Files
126
-
127
- - **`.env.example`**: template with all config vars, prod port defaults, placeholder secrets
128
- - **`.env`**: actual config, created from example by `setup.sh`, gitignored
129
- - `.env` lives at repo root — messaging loads it via `dotenv`, bridge reads env vars, web gets them via `sly-start.sh` exports
130
-
131
- ## Related Files
132
-
133
- - `documentation/designs/global_cli_setup.md` — full design document
134
- - `documentation/features/020_global_cli_setup.md` — 9-phase implementation plan
135
- - `web/src/lib/paths.ts` — runtime path resolution for web app
136
- - `bridge/src/session-manager.ts` — session persistence, CWD validation
137
- - `bridge/bridge-sessions.json` — persisted session state (NEVER wipe)
138
- - `.env.example` / `.env` — environment configuration
@@ -1,135 +0,0 @@
1
- # Skills & Infrastructure
2
-
3
- Updated: 2026-02-09
4
-
5
- ## Overview
6
-
7
- SlyCode is the central hub for reusable Claude Code assets. Skills provide specialized capabilities, commands are user-invocable shortcuts, agents handle autonomous workflows, and hooks execute on events. Includes global CLI setup, service management scripts, and project scaffolding. This repo tests new skills before deploying to other projects.
8
-
9
- ## Key Files
10
-
11
- ### Skills
12
- - `.claude/skills/context-priming/` - Dynamic codebase context loader
13
- - `.claude/skills/interactive-explainer/` - Creates visual HTML explainers
14
- - `.claude/skills/skill-creator/` - Guide for creating new skills
15
- - `.claude/skills/messaging/` - Send text/voice responses to messaging channels (v2.2.0)
16
- - `.claude/skills/claude-code-docs-maintainer/` - Maintains Claude Code documentation
17
- - `.claude/skills/kanban/` - Kanban board management skill
18
-
19
- ### Agents
20
- - `.claude/agents/doc-updater.md` - Autonomous documentation maintenance agent
21
-
22
- ### Commands
23
- - `.claude/commands/checkpoint.md` - Git checkpoint creation
24
- - `.claude/commands/feature.md` - Create feature specifications
25
- - `.claude/commands/chore.md` - Create chore/maintenance plans
26
- - `.claude/commands/implement.md` - Execute plans
27
- - `.claude/commands/design.md` - Start iterative design document
28
- - `.claude/commands/doc-discovery.md` - Documentation discovery
29
- - `.claude/commands/doc-update.md` - Documentation updates
30
- - `.claude/commands/reference-fetch.md` - Fetch external docs
31
- - `.claude/commands/create-command.md` - Meta-command for new commands
32
- - `.claude/commands/problem_summary.md` - Summarize debugging issues
33
-
34
- ### Scripts
35
- - `scripts/setup.sh` - Guided setup: environment, services, global CLI, linger
36
- - `scripts/sly-start.sh` - Start all services (web, bridge, messaging)
37
- - `scripts/sly-stop.sh` - Stop all services
38
- - `scripts/sly-restart.sh` - Restart all services
39
- - `scripts/sly-dev.sh` - Development mode launcher
40
- - `scripts/kanban.js` - Kanban CLI tool (installed globally as `sly-kanban`)
41
- - `scripts/scaffold.js` - Project scaffolding CLI (installed globally as `sly-scaffold`)
42
-
43
- ### Scaffold Templates
44
- - `data/scaffold-templates/` - Templates for project scaffolding
45
- - `claude-md.md`, `kanban.json`, `mcp.json`, `gitignore`, `archive-readme.md`, `seed-cards.json`
46
-
47
- ### Config
48
- - `.claude/settings.local.json` - Local Claude settings
49
- - `.mcp.json` - MCP server configuration (Context7, etc.)
50
- - `.env` / `.env.example` - Environment config with service ports
51
- - `CLAUDE.md` - Project instructions for Claude
52
-
53
- ### Documentation
54
- - `documentation/kanban.json` - Kanban card data
55
- - `documentation/events.json` - Activity event log (card moves, asset operations, sessions)
56
- - `documentation/terminal-classes.json` - Terminal class definitions
57
- - `documentation/features/` - Feature specs (001-020)
58
- - `documentation/chores/` - Chore plans (active + completed/)
59
- - `documentation/designs/` - Design documents
60
- - `documentation/reference/` - Reference documentation
61
-
62
- ## Skill Structure
63
-
64
- ```
65
- .claude/skills/{skill-name}/
66
- ├── SKILL.md # Main skill definition, invocation rules
67
- └── references/ # Supporting docs, templates, examples
68
- ```
69
-
70
- ## Command Structure
71
-
72
- ```markdown
73
- ---
74
- version: X.Y.Z
75
- updated: YYYY-MM-DD
76
- allowed-tools: [Tool1, Tool2]
77
- ---
78
- # Command Name
79
- Instructions for Claude when command is invoked
80
- ```
81
-
82
- ## Global CLI Commands
83
-
84
- After `scripts/setup.sh`, these are available globally:
85
- - `sly-kanban` - Kanban board management
86
- - `sly-messaging` - Send messages via messaging channels
87
- - `sly-scaffold` - Project scaffolding
88
-
89
- ## Service Management
90
-
91
- - `scripts/sly-start.sh` - Start all services (web on 7591, bridge on 7592, messaging on 7593)
92
- - `scripts/sly-stop.sh` - Stop all services
93
- - `scripts/setup.sh --service` - Install as persistent system services
94
- - `scripts/setup.sh --remove-service` - Remove persistent services
95
-
96
- ## Environment Variables (.env.example)
97
-
98
- - **Ports**: WEB_PORT=7591, BRIDGE_PORT=7592, MESSAGING_SERVICE_PORT=7593
99
- - **Bridge**: BRIDGE_URL for bridge connection
100
- - **Telegram**: TELEGRAM_BOT_TOKEN, TELEGRAM_AUTHORIZED_USER_ID
101
- - **STT**: OPENAI_API_KEY (Whisper)
102
- - **TTS**: ELEVENLABS_API_KEY, ELEVENLABS_VOICE_ID, ELEVENLABS_VOICE_SPEED
103
-
104
- ## Hooks
105
-
106
- - `web/src/hooks/useKeyboardShortcuts.ts` - Number keys 1-9 for project navigation, Escape
107
- - `web/src/hooks/useCommandsConfig.ts` - Polling-based commands config (30s)
108
- - `web/src/hooks/useConnectionStatus.ts` - SSE connection state
109
- - `web/src/hooks/usePolling.ts` - Generic polling hook
110
-
111
- ## Patterns & Invariants
112
-
113
- - Skills use semantic versioning (MAJOR.MINOR.PATCH)
114
- - Always update version and date when modifying skills/commands
115
- - Commands invoked via `/command-name` shorthand
116
- - CLAUDE.md applies to entire project, overrides defaults
117
- - MCP servers configured in .mcp.json (Context7 for docs)
118
- - Event log in documentation/events.json tracks card moves, asset ops, sessions (500 cap)
119
-
120
- ## Environment
121
-
122
- - `CLAUDE_ENV` - 'home' or 'work' for environment detection
123
- - Projects tracked in `projects/registry.json`
124
-
125
- ## When to Expand
126
-
127
- - Creating new skill → skill-creator skill, .claude/skills/
128
- - Creating new command → create-command, .claude/commands/
129
- - Creating new agent → .claude/agents/
130
- - Modifying Claude behavior → CLAUDE.md
131
- - Adding MCP servers → .mcp.json
132
- - Service management → scripts/sly-*.sh
133
- - Setup/installation → scripts/setup.sh
134
- - Project scaffolding → scripts/scaffold.js, data/scaffold-templates/
135
- - Activity events → documentation/events.json, web/src/lib/event-log.ts
@@ -1,232 +0,0 @@
1
- # Terminal Bridge
2
-
3
- Updated: 2026-02-14
4
-
5
- ## Overview
6
-
7
- PTY bridge server manages AI coding sessions across multiple providers (Claude, Gemini, Codex). Express server spawns/manages PTY processes, streams output via SSE. Provider-agnostic command building via data-driven config (`providers.json`). Includes security hardening (command whitelist, CWD validation, localhost binding), activity tracking with transition logging for debugging, atomic state persistence, bulk session management, and graceful idle timeout handling. React components connect through Next.js API proxy.
8
-
9
- ## Key Files
10
-
11
- ### Bridge Server (Node/Express)
12
- - `bridge/src/index.ts` - Express server entry, routes setup, localhost binding
13
- - `bridge/src/session-manager.ts` - Session lifecycle, PTY spawning, provider resolution, activity tracking, atomic state saving
14
- - `bridge/src/provider-utils.ts` - Provider config loading, command building, session detection helpers
15
- - `bridge/src/pty-handler.ts` - PTY process wrapper, output buffering
16
- - `bridge/src/api.ts` - REST endpoints for session CRUD, /stats, stop-all, activity-log
17
- - `bridge/src/websocket.ts` - WebSocket upgrade handling (legacy, SSE preferred)
18
- - `bridge/src/claude-utils.ts` - Claude session ID detection from ~/.claude/projects/
19
- - `bridge/src/types.ts` - Session, BridgeConfig, BridgeStats, ActivityTransition, provider interfaces
20
-
21
- ### Configuration
22
- - `bridge/bridge-config.json` - Runtime config: allowedCommands (claude, codex, gemini, bash), CORS origins
23
- - `data/providers.json` - Provider registry: CLI commands, permission flags, resume types, prompt handling, stage defaults
24
- - `documentation/terminal-classes.json` - Terminal class definitions for command visibility
25
- - `data/commands.json` - Unified command configuration with visibility per class
26
-
27
- ### Web Components
28
- - `web/src/components/Terminal.tsx` - xterm.js terminal, SSE via ConnectionManager
29
- - `web/src/components/ClaudeTerminalPanel.tsx` - Terminal panel with startupCommands/activeCommands
30
- - `web/src/components/GlobalClaudePanel.tsx` - Floating panel for project-wide session
31
- - `web/src/app/api/bridge/[...path]/route.ts` - Next.js proxy to bridge server
32
-
33
- ## Key Functions
34
-
35
- - `SessionManager.createSession()` - Resolves provider, builds command via `buildProviderCommand()`, validates CWD, spawns PTY
36
- - `SessionManager.resolveSessionName()` - Checks both new (with provider) and legacy session name formats
37
- - `SessionManager.stopSession()` - Graceful SIGINT, waits for exit
38
- - `SessionManager.stopAllSessions()` - Bulk stop all running/detached sessions, returns count
39
- - `SessionManager.getStats()` - Returns BridgeStats with activity info
40
- - `SessionManager.checkIdleSessions()` - Idle timeout with grace period after disconnect
41
- - `buildProviderCommand()` - Assembles { command, args } from provider config, handles flag vs subcommand resume
42
- - `getProvider()` - Loads provider config by ID from providers.json (30s cache)
43
- - `supportsSessionDetection()` - Check if provider supports GUID-based session detection
44
- - `Terminal.connectSSE()` - Via ConnectionManager for auto-reconnection
45
-
46
- ## Data Models
47
-
48
- ```typescript
49
- SessionInfo {
50
- name, status (running|stopped|detached), pid, connectedClients,
51
- hasHistory, claudeSessionId, lastOutputAt,
52
- provider?, skipPermissions?,
53
- lastOutputSnippet?, lastOutputRawHex?, lastOutputDataLength?
54
- }
55
-
56
- BridgeStats {
57
- bridgeTerminals: number; // Total PTY sessions
58
- connectedClients: number; // Total SSE/WS connections
59
- activelyWorking: number; // Sessions with output in last 2s
60
- sessions: SessionActivity[]; // Per-session activity
61
- }
62
-
63
- SessionActivity {
64
- name, status, lastOutputAt, isActive
65
- }
66
-
67
- ActivityTransition {
68
- timestamp: string;
69
- from: string; // Previous state
70
- to: string; // New state
71
- lastOutputAt: string;
72
- outputAge: number;
73
- trigger?: { // Debug info for phantom blips
74
- snippet: string;
75
- hex: string;
76
- dataLength: number;
77
- }
78
- }
79
-
80
- BridgeConfig {
81
- host, port, sessionFile, defaultIdleTimeout, maxSessions
82
- }
83
-
84
- BridgeRuntimeConfig {
85
- allowedCommands: string[]; // e.g., ['claude', 'codex', 'gemini', 'bash']
86
- cors: { origins: string[] }
87
- }
88
-
89
- CreateSessionRequest {
90
- name: string;
91
- provider?: string; // Provider id from providers.json
92
- skipPermissions?: boolean; // Whether to add permission-skip flag
93
- command?: string; // Legacy: direct command (backward compat)
94
- cwd: string;
95
- prompt?: string;
96
- fresh?: boolean;
97
- }
98
-
99
- PersistedSession {
100
- claudeSessionId?, cwd, createdAt, lastActive,
101
- provider?: string; // Defaults to 'claude' for old sessions
102
- skipPermissions?: boolean; // Defaults to true for old sessions
103
- }
104
-
105
- // Provider config types (provider-utils.ts)
106
- ProviderConfig {
107
- id, displayName, command, install,
108
- permissions: { flag, label, default },
109
- resume: { supported, type ('flag'|'subcommand'), flag?, subcommand?, lastFlag?, detectSession, sessionDir? },
110
- prompt: { type ('positional'|'flag'), interactive?, nonInteractive? }
111
- }
112
-
113
- ProvidersData {
114
- providers: Record<string, ProviderConfig>;
115
- defaults: {
116
- stages: Record<string, { provider, skipPermissions }>;
117
- global: { provider, skipPermissions };
118
- projects: Record<string, { provider, skipPermissions }>;
119
- }
120
- }
121
- ```
122
-
123
- ## Security Hardening
124
-
125
- - **Localhost binding**: HOST defaults to `localhost` (not `0.0.0.0`)
126
- - **Command whitelist**: Only commands in `bridge-config.json` allowedCommands can be spawned (claude, codex, gemini, bash)
127
- - **Provider validation**: Provider ID must exist in providers.json; resolved command must be in allowedCommands
128
- - **CWD validation**: Requires absolute path, verifies exists and is accessible before spawning PTY
129
- - **CORS origins**: Configured in bridge-config.json, not wide-open
130
-
131
- ## Activity Tracking
132
-
133
- - `lastOutputAt` timestamp updated on every PTY output
134
- - `isActive` = output within last 2 seconds (with 1s debounce)
135
- - `activelyWorking` count in BridgeStats for health monitor
136
- - Cards with active sessions show pulsing green glow in UI
137
- - **Activity transitions**: Logged with trigger details (snippet, hex, data length) for debugging phantom blips
138
- - `GET /activity-log/:name` endpoint exposes transition history per session
139
-
140
- ## State Persistence
141
-
142
- - Session state saved to bridge-sessions.json via atomic writes (temp file + rename)
143
- - State file uses `__dirname` resolution for reliable file location
144
- - Missing file (ENOENT) handled gracefully; corrupt JSON throws fatal error
145
- - Prevents silent data loss from corrupted state
146
-
147
- ## Race Condition Handling
148
-
149
- - **Disconnect grace period**: 5 seconds before session eligible for idle timeout
150
- - **Status transitions**: Protected against reconnect during disconnect
151
- - **SSE cleanup**: Proper client tracking on connection/disconnection
152
-
153
- ## Terminal Classes
154
-
155
- Controls which commands appear in each context:
156
- - `global-terminal` - Dashboard terminal (future)
157
- - `project-terminal` - Project-level panel at bottom
158
- - `backlog`, `design`, `implementation`, `testing`, `done` - Card terminals by stage
159
- - `command-assistant` - Terminal in CommandConfigModal
160
-
161
- ## Multi-Provider System
162
-
163
- ### Supported Providers
164
- - **Claude Code** (`claude`) — Positional prompts, `--resume <GUID>` with auto-detection, `--dangerously-skip-permissions`
165
- - **Codex CLI** (`codex`) — Positional prompts, `codex resume --last` (subcommand-style), `--yolo`
166
- - **Gemini CLI** (`gemini`) — Flag-based prompts (`-i`/`-p`), `--resume` (no GUID), `--yolo`
167
-
168
- ### Command Building (`buildProviderCommand`)
169
- - Returns `{ command, args }` tuple (command can change for Codex resume: `codex resume`)
170
- - Permission flag added if `skipPermissions: true`
171
- - Resume: flag-type appends `--resume [GUID]`; subcommand-type prepends `resume [GUID|--last]`
172
- - Prompt: positional appends as final arg; flag-type uses `-i <prompt>` (interactive)
173
- - No prompt on resume (user types into running session instead)
174
-
175
- ### Session Name Format
176
- - **New format**: `{projectId}:{provider}:card:{cardId}` or `{projectId}:{provider}:global`
177
- - **Legacy format**: `{projectId}:card:{cardId}` or `{projectId}:global`
178
- - `resolveSessionName()` checks new format first, falls back to legacy via `toLegacySessionName()`
179
- - Old sessions without provider field default to `provider: "claude"`
180
-
181
- ### GUID Detection (Claude only)
182
- - `supportsSessionDetection()` checks `provider.resume.detectSession`
183
- - Watches `~/.claude/projects/` for new `.jsonl` files after spawn
184
- - `getClaimedGuids()` excludes GUIDs already used by other sessions
185
- - Gemini/Codex use `--resume --last` (no GUID tracking)
186
-
187
- ### Stage-Based Defaults
188
- - `providers.json` `defaults.stages` maps each kanban stage → `{ provider, skipPermissions }`
189
- - UI pre-fills provider dropdown from stage default
190
- - `defaults.global` for project-level terminals
191
- - `defaults.projects` reserved for per-project overrides (future)
192
-
193
- ## Patterns & Invariants
194
-
195
- - Session names include provider segment: `{projectId}:{provider}:card:{cardId}` (new) or legacy `{projectId}:card:{cardId}`
196
- - Claude prompts passed as positional arg, NOT `-p` flag (that's print mode)
197
- - Resume behavior is provider-specific: flag vs subcommand, GUID vs latest
198
- - SSE streams through `/api/bridge/sessions/{name}/stream` proxy
199
- - Bridge runs on port 3456 (localhost), proxied through Next.js
200
- - Idle timeout: 4 hours default, checked every 60 seconds
201
- - Atomic state saves prevent data corruption
202
- - Provider config cached 30s in provider-utils.ts
203
-
204
- ## API Endpoints
205
-
206
- - `GET /sessions` - List all sessions
207
- - `GET /sessions/:name` - Get session info
208
- - `POST /sessions` - Create session (validates command + CWD)
209
- - `DELETE /sessions/:name` - Stop or delete session
210
- - `POST /sessions/:name/input` - Send input to PTY
211
- - `POST /sessions/:name/resize` - Resize terminal
212
- - `POST /sessions/:name/stop` - Send Escape key to active session (soft stop)
213
- - `GET /sessions/:name/stream` - SSE output stream
214
- - `POST /sessions/stop-all` - Bulk stop all running sessions
215
- - `GET /stats` - BridgeStats with activity info
216
- - `GET /activity-log/:name` - Activity transition history for debugging
217
-
218
- ## When to Expand
219
-
220
- - Session not starting → session-manager.ts createSession(), check command whitelist + provider validation
221
- - Adding new provider → data/providers.json, bridge-config.json allowedCommands
222
- - Provider command issues → provider-utils.ts buildProviderCommand()
223
- - Resume not working → provider-utils.ts (flag vs subcommand), claude-utils.ts (GUID detection)
224
- - Security concerns → bridge-config.json, session-manager.ts validation
225
- - Activity tracking issues → session-manager.ts handlePtyOutput(), getStats(), ActivityTransition
226
- - Phantom activity blips → activity-log endpoint, transition trigger data
227
- - Terminal display issues → Terminal.tsx, xterm setup
228
- - Connection problems → api/bridge proxy, connection-manager.ts
229
- - Idle timeout issues → session-manager.ts checkIdleSessions()
230
- - Bulk operations → stopAllSessions(), /sessions/stop-all
231
- - State corruption → session-manager.ts loadState/saveState
232
- - Session name resolution → session-manager.ts resolveSessionName(), toLegacySessionName()