@slycode/slycode 0.1.0 → 0.1.2
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/chunks/[root-of-the-server]__09aec55a._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__198f01e0._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__2b639eab._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__3b9d3e43._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__3f239285._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__4244617a._.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 +1 -1
- 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]__9058a007._.js +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__933e6077._.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 +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__b90bbd70._.js +1 -1
- 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]__bc55c42a._.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]__e88a19d2._.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 +1 -1
- package/dist/web/.next/server/chunks/[root-of-the-server]__f59af2bc._.js +1 -1
- package/dist/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_ffc6c790.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/src/app/api/git-status/route.ts +1 -0
- package/dist/web/src/app/api/projects/analyze/route.ts +1 -0
- package/dist/web/src/app/api/projects/route.ts +1 -0
- package/dist/web/src/app/api/transcribe/route.ts +1 -1
- package/dist/web/src/app/api/version-check/route.ts +3 -2
- package/dist/web/src/lib/paths.ts +1 -1
- package/lib/cli/doctor.d.ts.map +1 -1
- package/lib/cli/doctor.js +2 -1
- package/lib/cli/doctor.js.map +1 -1
- package/lib/cli/service.js +3 -3
- package/lib/cli/service.js.map +1 -1
- package/lib/cli/start.d.ts.map +1 -1
- package/lib/cli/start.js +3 -2
- package/lib/cli/start.js.map +1 -1
- package/lib/cli/stop.d.ts.map +1 -1
- package/lib/cli/stop.js +6 -4
- package/lib/cli/stop.js.map +1 -1
- package/lib/cli/update.d.ts.map +1 -1
- package/lib/cli/update.js +11 -8
- package/lib/cli/update.js.map +1 -1
- package/lib/cli/workspace.js +1 -1
- package/lib/cli/workspace.js.map +1 -1
- package/lib/platform/service-macos.js +1 -1
- package/lib/platform/service-macos.js.map +1 -1
- package/lib/platform/service-windows.js +1 -1
- package/lib/platform/service-windows.js.map +1 -1
- package/lib/platform/symlinks.js +1 -1
- package/lib/platform/symlinks.js.map +1 -1
- package/package.json +1 -1
- package/templates/kanban-seed.json +1 -1
- package/templates/tutorial-project/.agents/skills/checkpoint/SKILL.md +43 -0
- package/templates/tutorial-project/.agents/skills/context-priming/SKILL.md +152 -0
- package/templates/tutorial-project/.agents/skills/context-priming/references/area-index.md +101 -0
- package/templates/tutorial-project/.agents/skills/context-priming/references/areas/claude-actions.md +120 -0
- package/templates/tutorial-project/.agents/skills/context-priming/references/areas/messaging.md +177 -0
- package/templates/tutorial-project/.agents/skills/context-priming/references/areas/scripts-deployment.md +138 -0
- package/templates/tutorial-project/.agents/skills/context-priming/references/areas/skills.md +135 -0
- package/templates/tutorial-project/.agents/skills/context-priming/references/areas/terminal-bridge.md +232 -0
- package/templates/tutorial-project/.agents/skills/context-priming/references/areas/web-frontend.md +252 -0
- package/templates/tutorial-project/.agents/skills/context-priming/references/maintenance.md +128 -0
- package/templates/tutorial-project/.agents/skills/design/SKILL.md +141 -0
- package/templates/tutorial-project/.agents/skills/feature/SKILL.md +159 -0
- package/templates/tutorial-project/.agents/skills/implement/SKILL.md +132 -0
- package/templates/tutorial-project/.agents/skills/kanban/SKILL.md +264 -0
- package/templates/tutorial-project/.claude/skills/checkpoint/SKILL.md +43 -0
- package/templates/tutorial-project/.claude/skills/context-priming/SKILL.md +152 -0
- package/templates/tutorial-project/.claude/skills/context-priming/references/area-index.md +101 -0
- package/templates/tutorial-project/.claude/skills/context-priming/references/areas/claude-actions.md +120 -0
- package/templates/tutorial-project/.claude/skills/context-priming/references/areas/messaging.md +177 -0
- package/templates/tutorial-project/.claude/skills/context-priming/references/areas/scripts-deployment.md +138 -0
- package/templates/tutorial-project/.claude/skills/context-priming/references/areas/skills.md +135 -0
- package/templates/tutorial-project/.claude/skills/context-priming/references/areas/terminal-bridge.md +232 -0
- package/templates/tutorial-project/.claude/skills/context-priming/references/areas/web-frontend.md +252 -0
- package/templates/tutorial-project/.claude/skills/context-priming/references/maintenance.md +128 -0
- package/templates/tutorial-project/.claude/skills/design/SKILL.md +141 -0
- package/templates/tutorial-project/.claude/skills/feature/SKILL.md +159 -0
- package/templates/tutorial-project/.claude/skills/implement/SKILL.md +132 -0
- package/templates/tutorial-project/.claude/skills/kanban/SKILL.md +264 -0
- package/templates/tutorial-project/CLAUDE.md +16 -0
- package/templates/tutorial-project/documentation/designs/example_welcome_dashboard.md +38 -0
- package/templates/tutorial-project/documentation/events.json +1 -0
- package/templates/tutorial-project/documentation/features/example_in_card_deliverable_feature.md +31 -0
- package/templates/tutorial-project/documentation/kanban.json +385 -0
- /package/dist/web/.next/static/{ALUsM8gaUuQnX2hccTsJd → 4GrOHGHgp_-wfmjYR4P3O}/_buildManifest.js +0 -0
- /package/dist/web/.next/static/{ALUsM8gaUuQnX2hccTsJd → 4GrOHGHgp_-wfmjYR4P3O}/_clientMiddlewareManifest.json +0 -0
- /package/dist/web/.next/static/{ALUsM8gaUuQnX2hccTsJd → 4GrOHGHgp_-wfmjYR4P3O}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,138 @@
|
|
|
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
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Skills & Infrastructure
|
|
2
|
+
|
|
3
|
+
Updated: 2026-02-09
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
ClaudeMaster 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
|
|
@@ -0,0 +1,232 @@
|
|
|
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
|
+
- `action-assistant` - Terminal in SlyActionConfigModal
|
|
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()
|