@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.
- package/dist/web/.next/BUILD_ID +1 -1
- package/dist/web/.next/build-manifest.json +2 -2
- package/dist/web/.next/server/app/_global-error.html +2 -2
- package/dist/web/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/.next/server/app/_not-found.html +1 -1
- package/dist/web/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/.next/server/app/project/[id]/page_client-reference-manifest.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__46b023d4._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__4c7995bf._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__4d0d3464._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__543058c2._.js +3 -3
- package/dist/web/.next/server/chunks/[root-of-the-server]__6d330d40._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__884d73e4._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__949bb248._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__949d814c._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__aa814a86._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__ad64e04f._.js +2 -2
- package/dist/web/.next/server/chunks/[root-of-the-server]__baa99257._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__bbb4b3ac._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__bf286c26._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__ce429522._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__d38c7a96._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__e9b0e744._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__f1fe18e6._.js +2 -2
- package/dist/web/.next/server/chunks/ssr/[root-of-the-server]__677b7660._.js +1 -1
- package/dist/web/.next/server/chunks/ssr/[root-of-the-server]__79c0188d._.js +1 -1
- package/dist/web/.next/server/chunks/ssr/src_lib_registry_ts_2fc87c9c._.js +1 -1
- package/dist/web/.next/server/pages/404.html +1 -1
- package/dist/web/.next/server/pages/500.html +2 -2
- package/dist/web/.next/static/chunks/7660448872d80e27.js +4 -0
- package/dist/web/.next/static/chunks/{4793f1f83885d568.js → b694f741bb34ac84.js} +1 -1
- package/dist/web/src/components/ClaudeTerminalPanel.tsx +15 -11
- package/dist/web/src/lib/store-scanner.ts +70 -10
- package/dist/web/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/templates/kanban-seed.json +1 -1
- package/dist/store/.backups/actions/onboard.md +0 -33
- package/dist/store/.backups/actions/review.md +0 -37
- package/dist/store/.backups/actions/show-card.md +0 -20
- package/dist/store/.backups/checkpoint/SKILL.md +0 -43
- package/dist/store/.backups/context-priming/SKILL.md +0 -153
- package/dist/store/.backups/context-priming/references/area-index.md +0 -101
- package/dist/store/.backups/context-priming/references/areas/claude-actions.md +0 -120
- package/dist/store/.backups/context-priming/references/areas/messaging.md +0 -177
- package/dist/store/.backups/context-priming/references/areas/scripts-deployment.md +0 -138
- package/dist/store/.backups/context-priming/references/areas/skills.md +0 -135
- package/dist/store/.backups/context-priming/references/areas/terminal-bridge.md +0 -232
- package/dist/store/.backups/context-priming/references/areas/web-frontend.md +0 -252
- package/dist/store/.backups/context-priming/references/maintenance.md +0 -128
- package/dist/store/.ignored-updates.json +0 -37
- package/dist/store/actions/analyse-implementation.md +0 -72
- package/dist/store/actions/archive.md +0 -36
- package/dist/store/actions/clear.md +0 -13
- package/dist/store/actions/complete.md +0 -34
- package/dist/store/actions/continue.md +0 -20
- package/dist/store/agents/doc-updater.md +0 -619
- package/dist/store/mcp/context7.json +0 -8
- package/dist/store/skills/claude-code-docs-maintainer/SKILL.md +0 -168
- package/dist/store/skills/create-command/SKILL.md +0 -92
- package/dist/store/skills/doc-discovery/SKILL.md +0 -18
- package/dist/store/skills/doc-update/SKILL.md +0 -15
- package/dist/store/skills/dummy/SKILL.md +0 -22
- package/dist/store/skills/interactive-explainer/SKILL.md +0 -557
- package/dist/store/skills/interactive-explainer/assets/base_template.html +0 -780
- package/dist/store/skills/interactive-explainer/references/design_patterns.md +0 -486
- package/dist/store/skills/interactive-explainer/references/visualization_libraries.md +0 -512
- package/dist/store/skills/problem_summary/SKILL.md +0 -11
- package/dist/store/skills/reference-fetch/SKILL.md +0 -206
- package/dist/store/skills/skill-creator/LICENSE.txt +0 -202
- package/dist/store/skills/skill-creator/SKILL.md +0 -246
- package/dist/store/skills/skill-creator/scripts/init_skill.py +0 -303
- package/dist/store/skills/skill-creator/scripts/package_skill.py +0 -110
- package/dist/store/skills/skill-creator/scripts/quick_validate.py +0 -65
- package/dist/web/.next/static/chunks/5b44413f6e5b9e66.js +0 -4
- /package/dist/web/.next/static/{heUrgyJAcziZUlrZpGOPA → BbBq5FNe-sYRKe8Pc24UW}/_buildManifest.js +0 -0
- /package/dist/web/.next/static/{heUrgyJAcziZUlrZpGOPA → BbBq5FNe-sYRKe8Pc24UW}/_clientMiddlewareManifest.json +0 -0
- /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()
|