@slycode/slycode 0.1.14 → 0.1.15

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 (81) hide show
  1. package/dist/bridge/session-manager.js +1 -8
  2. package/dist/bridge/session-manager.js.map +1 -1
  3. package/dist/store/skills/context-priming/references/area-index.md +121 -68
  4. package/{templates/store/skills/context-priming/references → dist/store/skills/context-priming}/references/areas/feature-guide.md +44 -18
  5. package/dist/store/skills/context-priming/references/areas/messaging.md +108 -34
  6. package/dist/store/skills/context-priming/references/areas/scripts-deployment.md +61 -16
  7. package/dist/store/skills/context-priming/references/areas/skills.md +99 -38
  8. package/{templates/updates/skills/context-priming/references → dist/store/skills/context-priming}/references/areas/terminal-actions.md +1 -1
  9. package/dist/store/skills/context-priming/references/areas/terminal-bridge.md +74 -42
  10. package/dist/store/skills/context-priming/references/areas/web-frontend.md +259 -74
  11. package/dist/web/.next/BUILD_ID +1 -1
  12. package/dist/web/.next/build-manifest.json +2 -2
  13. package/dist/web/.next/server/app/_global-error.html +2 -2
  14. package/dist/web/.next/server/app/_global-error.rsc +1 -1
  15. package/dist/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  16. package/dist/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  17. package/dist/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/dist/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/dist/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/dist/web/.next/server/app/_not-found.html +1 -1
  21. package/dist/web/.next/server/app/_not-found.rsc +1 -1
  22. package/dist/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  23. package/dist/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  24. package/dist/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  25. package/dist/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  26. package/dist/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  27. package/dist/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  28. package/dist/web/.next/server/pages/404.html +1 -1
  29. package/dist/web/.next/server/pages/500.html +2 -2
  30. package/lib/cli/sync.d.ts +7 -0
  31. package/lib/cli/sync.d.ts.map +1 -1
  32. package/lib/cli/sync.js +32 -0
  33. package/lib/cli/sync.js.map +1 -1
  34. package/lib/cli/update.d.ts.map +1 -1
  35. package/lib/cli/update.js +9 -0
  36. package/lib/cli/update.js.map +1 -1
  37. package/package.json +1 -1
  38. package/templates/kanban-seed.json +1 -1
  39. package/templates/store/skills/context-priming/references/area-index.md +121 -68
  40. package/templates/{updates/skills/context-priming/references → store/skills/context-priming}/references/areas/feature-guide.md +44 -18
  41. package/templates/store/skills/context-priming/references/areas/messaging.md +108 -34
  42. package/templates/store/skills/context-priming/references/areas/scripts-deployment.md +61 -16
  43. package/templates/store/skills/context-priming/references/areas/skills.md +99 -38
  44. package/{dist/store/skills/context-priming/references → templates/store/skills/context-priming}/references/areas/terminal-actions.md +1 -1
  45. package/templates/store/skills/context-priming/references/areas/terminal-bridge.md +74 -42
  46. package/templates/store/skills/context-priming/references/areas/web-frontend.md +259 -74
  47. package/templates/updates/skills/context-priming/references/area-index.md +121 -68
  48. package/{dist/store/skills/context-priming/references → templates/updates/skills/context-priming}/references/areas/feature-guide.md +44 -18
  49. package/templates/updates/skills/context-priming/references/areas/messaging.md +108 -34
  50. package/templates/updates/skills/context-priming/references/areas/scripts-deployment.md +61 -16
  51. package/templates/updates/skills/context-priming/references/areas/skills.md +99 -38
  52. package/templates/{store/skills/context-priming/references → updates/skills/context-priming}/references/areas/terminal-actions.md +1 -1
  53. package/templates/updates/skills/context-priming/references/areas/terminal-bridge.md +74 -42
  54. package/templates/updates/skills/context-priming/references/areas/web-frontend.md +259 -74
  55. package/dist/store/skills/context-priming/references/areas/claude-actions.md +0 -120
  56. package/dist/store/skills/context-priming/references/references/area-index.md +0 -152
  57. package/dist/store/skills/context-priming/references/references/areas/messaging.md +0 -251
  58. package/dist/store/skills/context-priming/references/references/areas/scripts-deployment.md +0 -183
  59. package/dist/store/skills/context-priming/references/references/areas/skills.md +0 -196
  60. package/dist/store/skills/context-priming/references/references/areas/terminal-bridge.md +0 -263
  61. package/dist/store/skills/context-priming/references/references/areas/web-frontend.md +0 -437
  62. package/dist/store/skills/context-priming/references/references/maintenance.md +0 -128
  63. package/templates/store/skills/context-priming/references/areas/claude-actions.md +0 -120
  64. package/templates/store/skills/context-priming/references/references/area-index.md +0 -152
  65. package/templates/store/skills/context-priming/references/references/areas/messaging.md +0 -251
  66. package/templates/store/skills/context-priming/references/references/areas/scripts-deployment.md +0 -183
  67. package/templates/store/skills/context-priming/references/references/areas/skills.md +0 -196
  68. package/templates/store/skills/context-priming/references/references/areas/terminal-bridge.md +0 -263
  69. package/templates/store/skills/context-priming/references/references/areas/web-frontend.md +0 -437
  70. package/templates/store/skills/context-priming/references/references/maintenance.md +0 -128
  71. package/templates/updates/skills/context-priming/references/areas/claude-actions.md +0 -120
  72. package/templates/updates/skills/context-priming/references/references/area-index.md +0 -152
  73. package/templates/updates/skills/context-priming/references/references/areas/messaging.md +0 -251
  74. package/templates/updates/skills/context-priming/references/references/areas/scripts-deployment.md +0 -183
  75. package/templates/updates/skills/context-priming/references/references/areas/skills.md +0 -196
  76. package/templates/updates/skills/context-priming/references/references/areas/terminal-bridge.md +0 -263
  77. package/templates/updates/skills/context-priming/references/references/areas/web-frontend.md +0 -437
  78. package/templates/updates/skills/context-priming/references/references/maintenance.md +0 -128
  79. /package/dist/web/.next/static/{wMUaNt62q8VYjpVs4m1_t → sAL_sqPSOaOIrKiwdPzL2}/_buildManifest.js +0 -0
  80. /package/dist/web/.next/static/{wMUaNt62q8VYjpVs4m1_t → sAL_sqPSOaOIrKiwdPzL2}/_clientMiddlewareManifest.json +0 -0
  81. /package/dist/web/.next/static/{wMUaNt62q8VYjpVs4m1_t → sAL_sqPSOaOIrKiwdPzL2}/_ssgManifest.js +0 -0
@@ -1,120 +0,0 @@
1
- # Claude Actions (Commands)
2
-
3
- Updated: 2026-02-09
4
-
5
- ## Overview
6
-
7
- Unified command system for Claude terminals. Commands are defined in `data/sly-actions.json` with visibility controlled by terminal classes and session state. Commands are split into **startup commands** (shown before/during session start) and **active commands** (shown in toolbar while running).
8
-
9
- ## Key Files
10
-
11
- - `data/sly-actions.json` - Unified command definitions (prompts, visibility, groups)
12
- - `documentation/terminal-classes.json` - Terminal class definitions
13
- - `web/src/lib/sly-actions.ts` - getStartupActions(), getActiveActions(), renderTemplate(), buildPrompt()
14
- - `web/src/lib/types.ts` - Command, CommandsConfig, TerminalClass types
15
- - `web/src/app/api/commands/route.ts` - CRUD for sly-actions.json
16
- - `web/src/app/api/commands/stream/route.ts` - SSE for file change detection
17
- - `web/src/app/api/terminal-classes/route.ts` - Serves terminal-classes.json
18
- - `web/src/app/api/claude-actions/route.ts` - Serves commands in ClaudeActionsConfig format
19
-
20
- ## Data Models
21
-
22
- ```typescript
23
- // Unified command (no 'type' field - filtering by class + sessionState)
24
- Command {
25
- label: string;
26
- description: string;
27
- group?: string; // Card Actions, Session, Project, Utilities, Problems
28
- cardTypes?: string[]; // Filter: feature/bug/chore
29
- prompt: string; // Template with {{placeholders}}
30
- visibleIn: {
31
- classes: string[]; // Terminal classes where this appears
32
- projects: string[]; // Specific projects (if scope='specific')
33
- };
34
- scope: 'global' | 'specific';
35
- sessionState: 'new' | 'resume' | 'active' | 'any';
36
- }
37
-
38
- // Internal format used by ClaudeTerminalPanel
39
- ClaudeCommand {
40
- id: string;
41
- label: string;
42
- description: string;
43
- group?: string;
44
- cardTypes?: string[];
45
- prompt: string;
46
- visibleIn: { classes: string[]; projects: string[] };
47
- scope: 'global' | 'specific';
48
- sessionState: 'new' | 'resume' | 'active' | 'any';
49
- }
50
-
51
- // Config format served by /api/claude-actions
52
- ClaudeActionsConfig {
53
- version: string;
54
- contextTemplate: { card: string; global: string };
55
- commands: ClaudeCommand[];
56
- }
57
- ```
58
-
59
- ## Key Functions
60
-
61
- - `getStartupActions(commands, terminalClass, hasHistory)` - Commands for session start (new/resume/any states)
62
- - `getActiveActions(commands, terminalClass)` - Commands for toolbar while running (active/any states)
63
- - `renderTemplate(template, context)` - Handles {{var}}, {{#if}}, {{#each}}
64
- - `buildPrompt(contextTemplate, actionPrompt, context)` - Combines context + task sections
65
-
66
- ## Template Syntax
67
-
68
- - `{{var}}` - Simple substitution
69
- - `{{obj.prop}}` - Nested property access (e.g., `{{card.title}}`)
70
- - `{{#if var}}...{{/if}}` - Conditional block
71
- - `{{#each arr}}...{{this}}...{{/each}}` - Array iteration
72
-
73
- ## Context Objects
74
-
75
- Card context: `{ project, projectPath, card, stage, problems[] }`
76
- Global context: `{ project, projectPath }`
77
-
78
- ## Command Groups
79
-
80
- - **Card Actions** - Stage-specific workflows (Onboard, Design Doc, Implement, Debug, etc.)
81
- - **Session** - Continue, Summarize (for resume state)
82
- - **Project** - Explore, New Card (for project-level terminals)
83
- - **Utilities** - Compact, Clear, Checkpoint, Context, Show Card
84
- - **Problems** - Log Problem, Triage Problems, Fix Issues
85
- - **Action Assistant** - Configure, Update Priming (for action-assistant terminal class)
86
-
87
- ### Additional Commands
88
- - **Chore Plan** - Create maintenance/bug fix plan from card
89
-
90
- ## Session States
91
-
92
- - `new` - No history, shown for fresh start
93
- - `resume` - Has history, shown when resuming (Continue, Summarize)
94
- - `active` - Shown in toolbar when terminal is running
95
- - `any` - Always shown regardless of state
96
-
97
- ## Command Flow
98
-
99
- 1. **No session**: Show `startupCommands` (new + any states) as buttons
100
- 2. **Has history**: Show Resume button + `startupCommands` (new + any) for fresh start options
101
- 3. **Running**: Show `activeCommands` (active + any states) in footer toolbar
102
-
103
- ## Patterns & Invariants
104
-
105
- - Commands filtered by: terminalClass + sessionState
106
- - Startup commands: sessionState in ['new', 'resume', 'any'] based on hasHistory
107
- - Active commands: sessionState in ['active', 'any']
108
- - MAX_VISIBLE_ACTIONS = 6, overflow goes to "..." menu
109
- - Context button (id: 'context') appends card.areas to command
110
- - Show Card button (id: 'show-card') appends cardId
111
- - Shift+click on active command inserts without submitting
112
-
113
- ## When to Expand
114
-
115
- - Adding new commands → data/sly-actions.json
116
- - Changing filter logic → getStartupActions/getActiveActions in sly-actions.ts
117
- - Template issues → renderTemplate() in sly-actions.ts
118
- - UI for commands → ClaudeTerminalPanel.tsx
119
- - Terminal class definitions → documentation/terminal-classes.json
120
- - Command configuration UI → SlyActionConfigModal.tsx
@@ -1,152 +0,0 @@
1
- # Area Index
2
-
3
- Updated: 2026-03-13
4
-
5
- ## Areas
6
-
7
- ### web-frontend
8
- - path: areas/web-frontend.md
9
- - updated: 2026-03-13
10
- - load-when: dashboard, kanban, cards, modal, UI components, drag-drop, project page, checklist, action config, health monitor, reconnection, cli assets, assets, search, scaffolding, activity feed, keyboard shortcuts, health score, tab sync, theme, design system, colors, gradient, texture, grain, noise, logo, neon, glow, blend mode, terminal styling, dark mode, light mode, provider selector, provider button, store, updates, update delivery, diff, assistant, asset creation, terminal prompt, pushToTerminal, Code Den, StoreView, UpdatesView, SkillDiffViewer, AssetAssistant, mcp config, automation, automations, scheduler, cron, cron-utils, timezone, TZ, agent notes, notes, summary note, wide viewport, 4K, copyright, favicon, context menu, right-click, confirm dialog, CliAssetsTab, project reorder, displayOrder, version check, VersionUpdateToast, AddProjectModal, scaffold wizard, provider overlay, placement, classAssignments, voice, voice input, voice recording, transcribe, Whisper, STT, VoiceControlBar, VoiceSettings, VoiceContext, VoiceClaimant, FloatingVoiceWidget, ThemeToggle, settings, image paste, screenshot, clipboard, DashboardData, chevron, hazard stripe, loadParentEnv, shadow, shadow depth, elevation, shadow-surface, shadow-card, shadow-overlay, lane texture, lane-texture, inset shadow, card number, glow-color, type emoji, glassmorphic, compact card, JetBrains Mono, priority glow, responsive, mobile, touch, fullscreen, snap-scroll, scrollbar-hide, import preview, ImportDialog, SKILL.md-only, skillMainOnly, activity ring, DEV_HOSTNAME, allowedDevOrigins, version display, getRepoRoot, getParentEnv, MASTER_PROJECT_ID, workspace ID, basename, fetchWithTimeout, checkSessionAlive, liveness check, soft failure, hard failure, activity detection, fresh session, resume session, action-scanner, ActionUpdatesModal, action updates, action cache, invalidateActionsCache, instruction file, instruction file warning, resize broadcast, resize sync, grace window, nextRun, getNextRun, HMR, globalThis, per-card provider
11
- - notes:
12
- - CardModal tabs: Details, Notes?, Design?, Feature?, Test?, Checklist?, Terminal. Edit session protection (2000ms grace). suppressAutoTerminal from context menu. Fullscreen on mobile (rounded-none, h-full), windowed on desktop (lg:rounded-xl, lg:max-w-4xl). Horizontal tab scroll with scrollbar-hide on mobile.
13
- - Automation uses card description as prompt. Run Now button with feedback. Orange theme. onActiveAutomationsChange drives header pulse. Timezone badge in AutomationsScreen header + AutomationConfig one-shot picker. Automation safeguards: cannot archive automation cards (CLI + web), cannot enable automation on archived cards.
14
- - Surgical save: changedCardIds in POST merges against disk. last_modified_by tracks source (web/cli/agent).
15
- - Right-click context menu on cards: move stage, set priority, copy title/ID/desc, archive, delete. Portal z-51/52, lane-colored accent bars.
16
- - Z-index layers: BackdropModal z-50, ContextMenu z-51, Submenu z-52, ConfirmDialog z-60
17
- - Provider button group pre-fills from stage defaults. Session name: {projectId}:{provider}:card:{cardId}
18
- - Store canonical flat layout (store/skills/, store/actions/, store/agents/). UpdatesView: accept/dismiss/preview workflow. CliAssetsTab (was ToolkitTab). ImportDialog for skill imports: SKILL.md-only default, full folder option. Preview API lists files before import.
19
- - Action updates: ActionUpdatesModal for accept/dismiss/preview with diff viewer. ProjectHeader polls for actionEntries count, shows badge on Actions button. SlyActionConfigModal shows "Updates" tab when available. Cache invalidated via /api/sly-actions/invalidate on modal close.
20
- - action-scanner.ts: scans store/actions/*.md, parses YAML frontmatter, assembles SlyActionsConfig with 30s cache, writes back from config (reverse-engineers classes from classAssignments), content-hash based update scanning, additive class merge on accept.
21
- - Dashboard project drag-and-drop reordering with displayOrder field. AddProjectModal wizard: details → providers → review → creating → summary.
22
- - VersionUpdateToast: npm version polling (6-hour interval, daily dismiss, bottom-left toast).
23
- - Scheduler auto-starts via instrumentation.ts (30s), 60s grace window prevents stale ticks on re-enable. HMR-safe via globalThis state/timer. pushToTerminal() dispatches to GlobalClaudePanel.
24
- - Single `actions` prop on ClaudeTerminalPanel, split by placement locally (startup/toolbar/both). CardModal and GlobalClaudePanel each call one getActionsForClass().
25
- - SlyActionConfigModal: two-tab layout — Commands tab (edit definitions + placement dropdown) and Classes tab (assign + reorder commands per terminal class). Voice-enabled assistant terminal, Escape passes through to terminal when expanded.
26
- - Voice: global VoiceContext (useVoice() hook). Claim system: CardModal/GlobalClaudePanel claim → release. FloatingVoiceWidget when unclaimed. VoiceControlBar, MediaRecorder → /api/transcribe → insert at claimant target. ThemeToggle for light/dark in Dashboard.
27
- - Image paste: Terminal.tsx intercepts Ctrl+V at keydown (before xterm), clipboard.read() for images → bridge /sessions/:name/image → inject `[Screenshot: ...]` into PTY. Screenshot toast overlay on ClaudeTerminalPanel.
28
- - Path resolution centralized: getSlycodeRoot() (workspace) + getPackageDir() (dev: repo root, prod: node_modules/slycode/dist/). All API routes use these — no local getRepoRoot(). CLI assets import/sync use registry.ts getRepoRoot() instead of hardcoded project lookup.
29
- - next.config.ts: getParentEnv() reads DEV_HOSTNAME from parent .env for allowedDevOrigins (no hardcoded hostnames). Dashboard footer shows slycode version from /api/version-check with clickable slycode.ai link.
30
- - Scrubbed hardcoded project names: asset-scanner.ts uses MASTER_PROJECT_ID (path.basename), kanban-paths.ts derives workspace ID with underscore→hyphen normalization. paths.ts removed legacy root env var fallback (SLYCODE_HOME → cwd only).
31
- - NEVER use dark-end color scales for vibrant dark mode — use bright color at low opacity instead
32
- - Shadow depth system: 3 CSS custom property tiers (--shadow-surface, --shadow-card, --shadow-overlay) with light/dark variants. All neon-pulse keyframes layer glow on top of shadow vars. CardModal uses shadow-(--shadow-overlay). KanbanColumn wrappers use lightweight shadow.
33
- - Texture: three layers (grain + perlin + depth) + lane-texture (18px grid on column card areas) + `.light-clean` suppression (hides grain/depth on headers in light mode). soft-light → warm cast on dark — use screen. drop-shadow → rectangular glow with blend-mode logos.
34
- - Global terminal rebranded from neon-orange to neon-blue (steely blue #2490b5 in light mode). All glow effects have separate light-mode keyframes for visibility. ClaudeTerminalPanel buttons are neon-blue.
35
- - KanbanColumn: light mode flat solid bg (no gradients), thicker borders (3px), neutral text colors (void-500/void-600). Inset shadows on headers (color-matched per lane). Header text has drop-shadow for legibility.
36
- - KanbanCardItem: glassmorphism (bg-white/40 + backdrop-blur, dark: bg-[#20232a]/55), priority-colored left border + hover inset glow (--glow-color CSS var), card numbers (#0001 format, JetBrains Mono), type emojis replace color dots, compact mode for done column. Session status: green ping (running), orange (paused), grey (none).
37
- - Voice-aware click-outside: GlobalClaudePanel and SlyActionConfigModal won't close while voice is recording/transcribing.
38
- - Scheduler timezone-aware (TZ env var). loadParentEnv() reads .env from workspace root (Next.js only loads web/.env). Always recalculates nextRun for accurate countdowns. Automation run header: === AUTOMATION RUN === with time, card, trigger (scheduled with cron description / manual), last run + relative time.
39
- - cronToHumanReadable() in cron-utils.ts (shared by AutomationConfig, AutomationsScreen). getNextRunISO() removed — all nextRun calculation now server-side via scheduler.ts getNextRun(). Kanban GET API dynamically computes nextRun for all enabled recurring cards. Timezone abbreviation appended to time descriptions.
40
- - AutomationsScreen redesigned: max-w-5xl centered, 2-col grid (not 3), cards have chevron texture + hazard stripe + orange left border. Large countdown timers (text-2xl), "idle" label. Collapsible tag groups via `<details>`. New CSS: `.automation-chevron`, `.hazard-stripe` + muted variants.
41
- - AgentNote extended: summary?, summarizedCount?, dateRange? for note summarization. Amber "Summary" badge in CardModal notes tab.
42
- - Responsive mobile: CardModal fullscreen on mobile, GlobalClaudePanel fullscreen when expanded (h-svh w-screen on mobile), HealthMonitor click-to-toggle (was hover), Terminal touch-scroll + debounced resize (150ms), ProjectHeader mobile search overlay + hidden Actions, KanbanColumn snap-scroll (85vw on mobile). `.scrollbar-hide` CSS utility. All header buttons min-h/w-[44px] touch targets.
43
- - Activity ring: uses isActive (not status=running) for session detection. Global terminal sessions included in counts.
44
- - Scheduler split fresh/resume: fresh uses checkSessionAlive(20s), resume uses waitForActivity()+retry. fetchWithTimeout(10s) on all bridge calls. Soft failure notifications only on hard errors.
45
- - Instruction file warning: ClaudeTerminalPanel checks /check-instruction-file on provider/cwd change. Amber warning + opt-out checkbox if missing. createInstructionFile state passed to session creation.
46
- - Resize broadcast: Terminal.tsx guards resize POST (visible tabs only), suppressResizePost prevents echo loop from SSE resize events, skips resize on reconnect.
47
-
48
- ### terminal-bridge
49
- - path: areas/terminal-bridge.md
50
- - updated: 2026-03-12
51
- - load-when: terminal, terminal panel, xterm, bridge, pty, session, websocket, SSE, spawn, terminal class, security, stats, activity log, stop-all, provider, providers.json, multi-provider, gemini, codex, claude, resume, skip-permissions, YOLO, session detection, session ID, screenshot, image, image upload, image delivery, group status, action endpoint, relink, race condition, creating, mutex, idempotent, session cleanup, stopped session, heartbeat, instruction file, instructionFile, altInstructionFile, check-instruction-file, ensureInstructionFile, resize broadcast, suppressResizePost
52
- - notes:
53
- - Pass prompts as positional args to Claude CLI, NOT -p flag (-p is print mode)
54
- - Bridge: localhost binding, command whitelist (bridge-config.json), CWD validation (absolute path)
55
- - Activity tracking: lastOutputAt, 2s threshold. Grace period (5s) prevents idle timeout race. activityStartedAt for debouncing.
56
- - Atomic state saves (temp + rename). bridge-sessions.json crash on corrupt, graceful on ENOENT.
57
- - Session names: {projectId}:{provider}:card:{cardId} with legacy fallback. POST stop = Escape, DELETE = kill.
58
- - provider-utils.ts builds command args from providers.json (flag vs subcommand resume)
59
- - Session detection ALL providers: Claude (.jsonl), Codex (rollout UUID), Gemini (chat JSON) — 60s timeout
60
- - Prompt works alongside resume: Claude positional, Codex positional after subcommand
61
- - claude-utils.ts: provider-agnostic dispatchers (getProviderSessionDir, detectNewProviderSessionId, getMostRecentProviderSessionId)
62
- - Image delivery: POST /sessions/:name/image (multer, 10MB), screenshot-utils.ts saves to screenshots/ in session CWD, 10-file retention, auto-.gitignore
63
- - ActivityTransition: became (active/inactive), outputAgeMs, triggerSnippet/RawHex/DataLength (flat, not nested)
64
- - New endpoints: GET /groups/:group/status, POST /sessions/:name/action (compact/clear/interrupt), POST /sessions/:name/relink
65
- - SessionInfo includes group, resumed, lastActive fields
66
- - Race condition fix: createSession() uses 'creating' placeholder as mutex. Concurrent requests for same session get 202 (idempotent). guidDetectionCancelled flag prevents stale detection overwrites.
67
- - Stopped sessions removed from in-memory map (frees slot), data preserved in persistedState for resume.
68
- - SSE heartbeat: 15s comment heartbeats keep connections alive through proxies (Tailscale, Next.js)
69
- - Instruction file fallback: checkInstructionFile() priority scan (primary → alt → sibling copy source). ensureInstructionFile() copies on demand. Opt-in via createInstructionFile in CreateSessionRequest. GET /check-instruction-file endpoint for pre-flight checks.
70
- - Resize broadcast: PTY resize events sent via SSE to all connected tabs. Terminal.tsx guards resize POST (visible tabs only, suppressResizePost echo-loop prevention, skip on reconnect).
71
-
72
- ### terminal-actions
73
- - path: areas/terminal-actions.md
74
- - updated: 2026-03-10
75
- - load-when: actions, prompts, templates, context injection, commands, visibility, action config, terminal commands, startup commands, active commands, test review, placement, classAssignments, deep design, deep-design, action scanner, action updates, action .md, store/actions, action frontmatter, action cache, action delivery
76
- - notes:
77
- - Provider-agnostic: same commands across Claude, Codex, Gemini. Individual .md files in store/actions/ (v4.0)
78
- - Each action is a .md file with YAML frontmatter (name, version, label, group, placement, classes map) + prompt body
79
- - classAssignments assembled at runtime from per-action classes maps, sorted by priority (ascending)
80
- - Context templates hardcoded in sly-actions.ts (no longer in JSON config)
81
- - action-scanner.ts: parse, cache (30s), assemble config, write back, update scanning (content-hash), accept with additive class merge
82
- - messaging/sly-action-filter.ts has duplicated YAML parser + 30s cache (reads store/actions/ directly)
83
- - Action update delivery: updates/actions/ → content-hash diff → accept with class merge → store/actions/
84
- - ActionUpdatesModal.tsx for accept/dismiss/preview. ProjectHeader polls for update count badge.
85
- - SlyActionConfigModal shows "Updates" tab when action updates available
86
- - Groups: Card Actions (14), Session, Project, Utilities, Action Assistant (no Problems group)
87
- - Deep Design: 4-phase workflow (design doc → parallel analysis agents → synthesis → Q&A). 6 optional agent perspectives.
88
- - Test Review: interactive testing-lane with checklist assessment, area priming, max 3 questions/round
89
- - Organise Backlog: `kanban board` snapshot + `kanban reorder` for reprioritisation
90
-
91
- ### messaging
92
- - path: areas/messaging.md
93
- - updated: 2026-03-13
94
- - load-when: telegram, messaging, voice, TTS, STT, speech, channel, bot, ElevenLabs, Whisper, whisper.cpp, local STT, STT_BACKEND, voice swap, stop command, response mode, tone, action filter, provider, provider resolution, bridge provider, explicit session, default provider, PROVIDER_LABELS, permission mismatch, /search, /provider, /sly, /switch, /global, /project, card search, photo, image, album, navigation, target, inline keyboard, callback, instruction file, ifc_, pre-flight, PendingInstructionFileConfirm
95
- - notes:
96
- - Channel interface: onText/onVoice/onPhoto/onCommand + sendText/sendTextRaw/sendVoice/sendInlineKeyboard/setPersistentKeyboard/onCallback
97
- - Navigation model: three-level targets (global/project/card) via /switch command with inline keyboards
98
- - Bot commands: /start, /switch, /global, /project, /search, /sly, /status, /provider, /voice, /mode, /tone
99
- - Callback prefixes: sw_ (switch), qc_ (quick card), cfg_ (config), perm_ (permissions), mode_, tone_
100
- - State: messaging-state.json (targetType, projectId, cardId, cardStage, provider, voice, responseMode, voiceTone)
101
- - Voice: Dual-backend STT (OpenAI Whisper or local whisper.cpp via STT_BACKEND env var) → ElevenLabs v3 TTS with [audio tags]. "stop" intercepted → Escape to session.
102
- - skipPermissions always true. Permission mismatch detection for web-started sessions.
103
- - sly-action-filter.ts: v3 classAssignments-based filtering. kanban-client.ts: card data, searchCards
104
- - Photo albums batched via media_group_id (2s window). BridgeClient.sendImage() → bridge screenshot
105
- - Persistent keyboard: [['/switch', '/search'], ['/provider', '/status'], ['/voice', '/tone'], ['/mode', '/sly']]
106
- - Session names: global:{provider}:global, {projectId}:{provider}:global, {projectId}:{provider}:card:{cardId}
107
- - Provider auto-resolution: resolveProviderFromBridge() / resolveProjectProviderFromBridge() pick provider from most recent bridge session. hasExplicitSession() determines default vs explicit. Navigation commands (sw_, /global, /project) auto-resolve provider. cfg_ callback updates providers.json global default when no explicit session.
108
- - Instruction file pre-flight: checkInstructionFilePreFlight() checks before new session creation (text/voice/photo). Shows ifc_ inline buttons if needed. PendingInstructionFileConfirm stored in StateManager (ephemeral). BridgeClient.checkInstructionFile() + createInstructionFile param on ensureSession/sendMessage.
109
-
110
- ### skills
111
- - path: areas/skills.md
112
- - updated: 2026-03-13
113
- - load-when: skills, commands, agents, hooks, slash commands, SKILL.md, scaffolding, store, cross-provider, convert-asset, notes, notes summarize, automation, kanban CLI, last_modified_by, updates, update delivery, npm, packages, slycode CLI, migrate, board, reorder, build pipeline, sync-updates, store-manifest, provider overlay, base-instructions, slycode config, slycode uninstall, tutorial project, card number, nextCardNumber, licensing, BUSL, open-core, skillMainOnly, STT_BACKEND, WHISPER_CLI_PATH, WHISPER_MODEL_PATH
114
- - notes:
115
- - ALL commands converted to skills. 17 skills + 1 agent (doc-updater) + 1 dummy skill (inert test). .claude/commands/ removed. Licensed under BUSL-1.1 (open-core).
116
- - Store: 17 canonical skills (store/skills/) + actions (store/actions/*.md). Flat layout, no provider subdirectories.
117
- - Update delivery: updates/ → accept → store/ (with backup) → deploy to projects. Actions use content-hash comparison + additive class merge.
118
- - NPM: packages/slycode/ (CLI, 11 subcommands incl config + uninstall) + packages/create-slycode/ (scaffold). .agents/skills/ for Codex format.
119
- - kanban.js: board, reorder, notes (add/list/search/edit/delete/clear/oldest/summarize), automation subcommands. stamps last_modified_by/source on writes. Notes: 100 hard cap, 30 soft suggestion threshold, summarize replaces oldest N with summary note. Archive safeguard: automation cards cannot be archived. Sequential card numbers: ensureCardNumbers() auto-backfills on first write, nextCardNumber tracked on kanban root. Kanban skill v1.4.0: multiline description example in docs. `automation enable` recalculates nextRun via croner.
120
- - Scaffold: multi-provider, tutorial content seeded into workspace root (not separate slycode_tutorial/ subdirectory). Kanban seed uses stage-based format. Clean output: suppresses zero-count lines, reports new vs existing doc dirs.
121
- - Build pipeline: build-package.ts → sync-updates.ts (skills + actions) → copy scaffold-templates/ + store/ + updates/actions/ to dist/. Templates (skills, actions, tutorial-project) removed from packages/slycode/templates/ — build pipeline is sole delivery mechanism.
122
- - Hooks: useSlyActionsConfig.ts (not useCommandsConfig.ts)
123
-
124
- ### feature-guide
125
- - path: areas/feature-guide.md
126
- - updated: 2026-03-13
127
-
128
- - load-when: feature guide, feature reference, full scope, system overview, product overview, comprehensive reference, all features, complete reference, deep dive features, product messaging, value proposition, USP, positioning, user story, what is slycode, why slycode, target audience, marketing, website copy, README copy, onboarding copy, pricing, teams tier, per-card provider selection
129
- - notes:
130
- - Auto-maintained by automation card-1772101929502
131
- - Comprehensive reference of every SlyCode feature, function, and behavior
132
- - Use when needing full product scope for design docs, comparisons, or thorough analysis
133
- - PROTECTED: documentation/features/042_slycode_product_messaging.md is the canonical product messaging framework. It defines SlyCode's positioning, value proposition, messaging pillars, target audience, pricing framing, and proof points. Load this document whenever product identity, messaging, marketing copy, or user-facing language is relevant. Do NOT remove or overwrite this reference during context priming updates.
134
-
135
- ### scripts-deployment
136
- - path: areas/scripts-deployment.md
137
- - updated: 2026-03-05
138
- - load-when: setup, scripts, deployment, start, stop, restart, dev, ports, service, systemd, launchd, linger, PID, zombie, sly-start, sly-stop, sly-dev, sly-restart, setup.sh, .env, environment, production, build, tmux, bridge-sessions, XDG_RUNTIME_DIR, build tools, gcc, npm, packages, slycode, create-slycode, migrate, build-package, sync-updates, store-manifest, SLYCODE_HOME, path resolution, getSlycodeRoot, getPackageDir, slycode.config.js, config, uninstall, DEV_HOSTNAME, legacy root env var
139
- - notes:
140
- - Two port ranges: dev (3003/4/5) and prod (7591/2/3 = "sly" on keypad)
141
- - Stop by port, NOT PID files (npm spawns children, PIDs go stale)
142
- - bridge-sessions.json is critical — crash on read errors, never silently wipe
143
- - XDG_RUNTIME_DIR must be set for systemctl --user in code-server
144
- - slycode.config.js: workspace-level config for ports, services, host. Loaded by config/loader.ts.
145
- - Default host: 127.0.0.1. Only web binds to config.host; bridge+messaging always localhost.
146
- - slycode CLI: 11 subcommands (workspace, start, stop, service, doctor, skills, sync, update, config, uninstall)
147
- - sly-dev.sh tmux hook calls sly-stop.sh on session close to prevent zombies
148
- - Global CLIs: sly-kanban, sly-messaging, sly-scaffold (symlinked to ~/bin)
149
- - Build: build-package.ts preserves tutorial-project/ template during wipe/rebuild
150
- - NPM packages: packages/slycode/ (v0.1.0 CLI) and packages/create-slycode/ (v0.1.0 scaffold)
151
- - Tutorial v3: content seeded into workspace root (not slycode_tutorial/ subdir). Registry default project = workspace root.
152
- - Path resolution simplified: legacy root env var env var removed. Resolution is now SLYCODE_HOME → cwd fallback only.
@@ -1,251 +0,0 @@
1
- # Messaging Service
2
-
3
- Updated: 2026-03-13
4
-
5
- ## Overview
6
-
7
- Multi-channel messaging service for remote AI interaction via Telegram (and future channels). Supports text, voice, and photo messages, target-based navigation (global/project/card), voice swapping, response mode/tone preferences, multi-provider support (Claude/Gemini/Codex), stop command for session interruption, cross-project card search with inline keyboards, permission mismatch detection, instruction file pre-flight checks, 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, callback handlers, stop interception
13
- - `messaging/src/types.ts` - Channel interface, InlineButton, configs, bridge types, ResponseMode, TargetType, NavigationTarget, InstructionFileCheck, PendingInstructionFileConfirm, BridgeSessionInfo
14
- - `messaging/src/state.ts` - StateManager: target navigation (global/project/card), voice state, response mode, voice tone, provider selection, persistence. Resolves paths via SLYCODE_HOME env var (messaging-state.json, registry.json).
15
- - `messaging/src/bridge-client.ts` - BridgeClient: session management, provider-aware creation, permission mismatch detection, instruction file check, activity watching, soft stop, debug logging, background activity monitor, image upload
16
-
17
- ### Channels
18
- - `messaging/src/channels/telegram.ts` - TelegramChannel: bot polling, inline buttons, persistent keyboards, callback handlers, chat actions
19
-
20
- ### Voice Pipeline
21
- - `messaging/src/stt.ts` - Dual-backend STT: OpenAI Whisper API or local whisper.cpp CLI. SttConfig interface, validateSttConfig() validation. Local backend: ffmpeg OGA→WAV conversion + whisper-cli execution (2min timeout).
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/sly-action-filter.ts` - SlyActionFilter: context-aware action filtering by terminal class, placement, card type (v3 classAssignments-based). Resolves sly-actions.json via SLYCODE_HOME env var.
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 agent 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
- onPhoto(handler): void; // Photo messages (batched for albums)
48
- onCommand(command, 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
- sendInlineKeyboard(text, buttons: InlineButton[][]): Promise<void>; // Inline buttons with breadcrumb
53
- setPersistentKeyboard(buttons: string[][]): Promise<void>; // Bottom keyboard
54
- sendTyping(): Promise<void>;
55
- sendChatAction(action): Promise<void>;
56
- sendVoiceList?(voices): Promise<void>; // Optional
57
- onVoiceSelect?(handler): void; // Optional
58
- onCallback(prefix, handler): void; // Inline button callback routing
59
- isReady(): boolean;
60
- }
61
-
62
- InlineButton { label: string; callbackData: string; }
63
- ```
64
-
65
- ## Navigation Model
66
-
67
- Three-level target system replacing old project-selection model:
68
-
69
- - **Global** - No project context, uses workspace root as CWD
70
- - **Project** - Project-level terminal (`{projectId}:{provider}:global`)
71
- - **Card** - Card-specific terminal (`{projectId}:{provider}:card:{cardId}`)
72
-
73
- `StateManager.getTarget()` returns `NavigationTarget { type, projectId?, cardId?, stage? }`
74
-
75
- ## Bot Commands
76
-
77
- - `/start` - Help text with available commands
78
- - `/switch` - Primary navigation: drill-down inline keyboards (global → projects → cards)
79
- - `/global` - Quick switch to global terminal
80
- - `/project` - Quick switch from card to project terminal (stays in same project)
81
- - `/search` - Quick-access: active sessions + recent cards as inline buttons. With args: text search across cards
82
- - `/sly` - Context-aware sly actions as inline buttons (filtered by terminal class + placement)
83
- - `/status` - Current target, project, voice, response mode, and tone
84
- - `/provider` - Provider selection inline keyboard (Claude/Gemini/Codex)
85
- - `/voice` - Search/swap TTS voices, reset to default
86
- - `/voice <name>` - Search voices, auto-select on exact match, inline buttons for multiple
87
- - `/mode` - Response mode selection (text/voice/both)
88
- - `/tone` - Voice tone customization
89
-
90
- ## Callback Handlers
91
-
92
- - `sw_` - Switch navigation (project/card selection from inline keyboards)
93
- - `qc_` - Quick card actions (from /search results)
94
- - `cfg_` - Configuration callbacks
95
- - `ifc_` - Instruction file confirmation (yes/no for creating missing instruction file)
96
- - `perm_` - Permission mismatch actions (restart session with correct perms)
97
- - `mode_` - Response mode selection callbacks
98
- - `tone_` - Voice tone selection callbacks
99
-
100
- ## Message Flow
101
-
102
- ### Inbound (user → agent session)
103
- 1. User sends text/voice on Telegram
104
- 2. **Stop interception**: "stop" text (case-insensitive) sends Escape to active session instead of forwarding
105
- 3. TelegramChannel routes to handler in index.ts
106
- 4. Voice: `record_voice` chat action → Whisper transcription → typing indicator
107
- 5. **Instruction file pre-flight**: if new session would be created, checks bridge for missing instruction file. If needed, shows inline buttons (yes/no). Pending state stored in `StateManager._pendingInstructionFileConfirm` (ephemeral, not persisted). `ifc_yes` callback creates file + delivers original message; `ifc_no` delivers without creating.
108
- 6. BridgeClient.ensureSession() creates/finds session (with selected provider, always skipPermissions, optional createInstructionFile)
109
- 7. If permission mismatch (existing session without skipPermissions), warns user and offers restart
110
- 8. BridgeClient.sendMessage() writes text + CR to PTY
111
- 9. BridgeClient.watchActivity() polls /stats, sends typing while active
112
-
113
- ### Outbound (agent → user)
114
- 1. Agent skill calls CLI: `tsx cli.ts send "message" [--tts]`
115
- 2. CLI POSTs to HTTP server `/send` or `/voice`
116
- 3. `/send` → channel.sendText()
117
- 4. `/voice` → `upload_voice` chat action → TTS generation → channel.sendVoice() + sendTextRaw()
118
-
119
- ### Photo Messages (user → agent session)
120
- 1. User sends photo(s) on Telegram (single or album)
121
- 2. TelegramChannel downloads largest resolution, batches album photos (2s window via media_group_id)
122
- 3. BridgeClient.sendImage() uploads each photo to bridge `POST /sessions/:name/image`
123
- 4. Bridge saves to `screenshots/` in session CWD, returns filename
124
- 5. Screenshot references (`[Screenshot: screenshots/<filename>]`) + optional caption built into message
125
- 6. Message sent to PTY, activity watched as normal
126
-
127
- ### Stop Command
128
- 1. User sends "stop" (exact, case-insensitive)
129
- 2. BridgeClient.stopSession() calls `POST /sessions/:name/stop` (sends Escape key)
130
- 3. Returns feedback: "Interrupted active session" or "Already stopped"
131
- 4. Message NOT forwarded as a prompt
132
-
133
- ## Response Mode System
134
-
135
- - **Mode**: `text` | `voice` | `both` - determines response format
136
- - `text` - Text replies only (default)
137
- - `voice` - Voice messages with text companion
138
- - `both` - Both voice and text responses
139
- - **Tone**: Free-text description of voice style and length
140
- - Mode shown in message footer: `(Reply using /messaging | Mode: text)`
141
- - Persisted in messaging-state.json
142
-
143
- ## Command Filtering
144
-
145
- - `SlyActionFilter.loadActions()` - Hot-reloads sly-actions.json on each call
146
- - `SlyActionFilter.filterActions(terminalClass, placement?, cardType?)` - Context-aware filtering via classAssignments lookup
147
- - `SlyActionFilter.resolveTemplate(prompt, context)` - Template variable resolution
148
- - `SlyActionFilter.getTerminalClass(target)` - Maps navigation target to terminal class
149
- - Supports card context from KanbanClient for prompt templates
150
-
151
- ## Kanban Client
152
-
153
- - `KanbanClient.getBoard(projectId)` - Load project's kanban board
154
- - `KanbanClient.getCard(projectId, cardId)` - Find card with its stage
155
- - `KanbanClient.getCardsByStage(projectId, stage)` - Cards in a stage sorted by `order` field (used by reorder command), automation cards excluded
156
- - `KanbanClient.searchCards(projectIds, query, maxResults)` - Text search across cards (title +2, description +1, archived -1)
157
- - `KanbanClient.getAllCards(projectIds)` - All non-archived, non-automation cards
158
- - Resolves kanban.json paths per project
159
-
160
- ## Voice System
161
-
162
- - **STT**: Dual-backend via `SttConfig.backend` ('openai' | 'local'). OpenAI Whisper (`whisper-1`) or local whisper.cpp CLI. Backend selected via `STT_BACKEND` env var. Local backend requires `WHISPER_CLI_PATH` and `WHISPER_MODEL_PATH`. `validateSttConfig()` checks env setup before transcription attempts.
163
- - **TTS**: ElevenLabs v3 (`eleven_v3`), supports `[tag]` audio tags
164
- - **Voice selection**: Persisted in messaging-state.json, overrides .env default
165
- - **Voice search**: Queries both `/v2/voices` (personal) and `/v1/shared-voices` (community), deduplicates
166
- - **Conversion**: ffmpeg MP3→OGG/Opus for Telegram compatibility
167
-
168
- ## Provider Support
169
-
170
- - `StateManager.selectedProvider` - Persisted provider choice (default: 'claude')
171
- - **Auto-resolution**: Provider auto-resolved on navigation. `resolveProviderFromBridge()` checks bridge for existing card sessions (picks most recently active). `resolveProjectProviderFromBridge()` does the same for project-level sessions. Resolution chain: bridge session → stage default (from providers.json) → global default.
172
- - `getProviderDefault(stage?)` reads providers.json defaults (stage-specific → global fallback)
173
- - `updateGlobalProviderDefault(provider)` writes to providers.json when changing provider on a target with no explicit bridge session
174
- - `hasExplicitSession()` checks whether the current provider was derived from a bridge session vs default. Status/lifecycle messages show "(default)" suffix when no explicit session exists.
175
- - Shared `PROVIDER_LABELS` constant and `ALL_PROVIDERS` list (no more inline duplicated maps)
176
- - Session names include provider segment: `{projectId}:{provider}:global` or `{projectId}:{provider}:card:{cardId}`
177
- - Global target uses `global:{provider}:global`
178
- - `getLegacySessionName()` provides backward-compat format for existing session lookups
179
- - Messaging always forces `skipPermissions: true` (remote interaction can't approve prompts)
180
- - `BridgeClient.ensureSession()` returns `{ session, permissionMismatch? }` — detects sessions started from web UI without skip-permissions
181
- - `BridgeClient.restartSession()` stops old session and creates fresh one with correct provider + skip-permissions
182
- - `BridgeClient.startActivityMonitor()` runs persistent background polling (4s) sending typing indicators when session is active
183
- - `BridgeClient.checkInstructionFile(provider, cwd)` checks bridge for missing instruction file, returns InstructionFileCheck
184
- - `BridgeClient.ensureSession()` accepts optional `createInstructionFile` param, passed to bridge session creation
185
- - `BridgeClient.sendMessage()` accepts optional `createInstructionFile` param, forwarded to ensureSession
186
- - `BridgeClient.sendImage(name, filePath, cwd?)` uploads image to bridge screenshot endpoint, returns filename
187
- - `BridgeClient.getActiveCardSessions(projectIds)` returns Set of card IDs with active bridge sessions (for /search quick-access)
188
- - `BridgeClient.getCardSessionRecency(projectIds)` returns Map of card IDs to lastActive timestamps (for /search recent sorting)
189
- - Debug logging via `debugLog()` writes to `messaging-debug.log` for session create/send troubleshooting
190
- - Resume+prompt flow: detects resumed sessions and types prompt via sendInput after delay
191
-
192
- ## State Persistence
193
-
194
- `messaging-state.json` stores:
195
- - `targetType` - Navigation level: global/project/card
196
- - `selectedProjectId` - Active project
197
- - `selectedCardId` - Active card (only with project)
198
- - `selectedCardStage` - Active card's stage
199
- - `selectedProvider` - Active AI provider (claude/gemini/codex)
200
- - `voiceId` / `voiceName` - Selected TTS voice (null = use .env default)
201
- - `responseMode` - text/voice/both preference
202
- - `voiceTone` - Free-text tone description
203
-
204
- Projects loaded from `projects/registry.json` at startup.
205
-
206
- ## HTTP Endpoints
207
-
208
- - `POST /send` - Send text message to active channel
209
- - `POST /voice` - Generate TTS and send voice + text to channel
210
- - `GET /health` - Service health check (channel name, ready state)
211
-
212
- ## Patterns & Invariants
213
-
214
- - Path resolution: `SLYCODE_HOME` env var (set by `slycode start`) → `process.cwd()` fallback. All file paths (state, registry, sly-actions) resolve via `getWorkspaceRoot()` helper — no `__dirname`-relative paths (breaks in npm package installs).
215
- - Chat actions for status: `record_voice` (transcribing), `typing` (processing), `upload_voice` (TTS)
216
- - Session names include provider and target type: `{projectId}:{provider}:card:{cardId}` or `global:{provider}:global`
217
- - Messages include channel header: `[Telegram] text (Reply using /messaging | Mode: text)`
218
- - Voice messages: `[Telegram/Voice] transcription (Reply using /messaging | Mode: text)`
219
- - sendTextRaw used for voice text companions (preserves [audio tags]) and voice IDs
220
- - Authorization: single authorized user ID per Telegram bot
221
- - Telegram message limit: 4096 chars, auto-split at newline boundaries
222
- - "stop" text intercepted before forwarding to session (soft stop via Escape key)
223
- - Card titles truncated to 35 chars in breadcrumb rendering
224
- - /search quick-access shows active sessions (up to 5) + recent cards sorted by laterDate(session.lastActive, card.updated_at)
225
- - /search text mode uses kanban-client.searchCards() with scoring (title +2, desc +1, archived -1)
226
- - /search supports global (multi-project) and single-project scopes with cross-project card switching
227
- - Persistent keyboard is unified single layout for all contexts: [['/switch', '/search'], ['/provider', '/status'], ['/voice', '/tone'], ['/mode', '/sly']]
228
- - /provider shows provider inline keyboard (excludes current provider, dynamic from ALL_PROVIDERS). cfg_ callback also updates global default in providers.json when no explicit bridge session exists.
229
- - Photo albums batched via media_group_id (2s flush window), single photos delivered immediately
230
- - Photos: download largest resolution, save to temp dir, upload to bridge, inject `[Screenshot: screenshots/<filename>]` into message
231
- - Instruction file pre-flight: before creating new sessions (text, voice, photo handlers), `checkInstructionFilePreFlight()` checks if provider instruction file is missing. If needed, shows inline buttons and stores pending state (PendingInstructionFileConfirm). `ifc_` callback delivers original message with `createInstructionFile` flag.
232
- - Callback prefixes route inline button presses: sw_ (switch), qc_ (quick card), cfg_ (config), ifc_ (instruction file confirm), perm_ (permissions), mode_ (mode), tone_ (tone)
233
-
234
- ## When to Expand
235
-
236
- - Adding new channel → implement Channel interface, add to createChannel() in index.ts
237
- - Voice issues → tts.ts (generation), voices.ts (search), stt.ts (transcription)
238
- - Bot command issues → index.ts setupChannel()
239
- - Bridge routing → bridge-client.ts
240
- - State persistence → state.ts
241
- - Telegram-specific behavior → channels/telegram.ts
242
- - Command filtering → sly-action-filter.ts, kanban-client.ts
243
- - Stop command → bridge-client.ts stopSession(), index.ts stop interception
244
- - Response modes → state.ts, SKILL.md mode/tone guidelines
245
- - Provider selection → state.ts (selectedProvider), index.ts (resolveProviderFromBridge, getProviderDefault, updateGlobalProviderDefault), bridge-client.ts (ensureSession provider param)
246
- - Permission mismatch → bridge-client.ts ensureSession/sendMessage permissionMismatch detection
247
- - Photo messages → channels/telegram.ts (photo listener, album batching), index.ts (onPhoto handler), bridge-client.ts (sendImage)
248
- - Card search → index.ts /search handler, kanban-client.ts searchCards/getAllCards, bridge-client.ts getActiveCardSessions/getCardSessionRecency
249
- - Navigation → index.ts /switch handler, state.ts target methods, callback handlers (sw_)
250
- - Instruction file flow → index.ts checkInstructionFilePreFlight(), ifc_ callback, bridge-client.ts checkInstructionFile(), state.ts pending confirm
251
- - Inline buttons → channels/telegram.ts, types.ts InlineButton, channel.onCallback()