@workscribe/cli 1.10.0 → 1.11.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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/capture/index.ts","../src/db/index.ts","../src/utils/paths.ts","../src/db/migrations/001_initial_schema.ts","../src/db/migrations/002_semantic_categories.ts","../src/db/migrations/index.ts","../src/capture/redact.ts","../src/capture/git.ts","../src/capture/git-snapshot.ts","../src/capture/aider.ts","../src/config/registry.ts","../src/config/ai-tools.json","../src/utils/logger.ts","../src/profiles/loader.ts","../src/config/index.ts","../src/profiles/schema.ts","../src/profiles/fetcher.ts","../src/normalize/patterns.ts","../src/capture/filter.ts","../src/cli/capture.ts","../src/cli/hook.ts","../src/cli/init.ts","../src/capture/shell-hook.ts","../src/capture/hooks/claude-code.ts","../src/capture/hooks/utils.ts","../src/capture/hooks/index.ts","../src/cli/status.ts","../src/utils/format.ts","../src/cli/events.ts","../src/cli/sessions.ts","../src/sessions/grouper.ts","../src/sessions/detector.ts","../src/cli/summary.ts","../src/ai/prompt.ts","../src/ai/fetch.ts","../src/ai/providers/anthropic.ts","../src/ai/providers/openai.ts","../src/ai/providers/ollama.ts","../src/ai/router.ts","../src/integrations/webhook.ts","../src/integrations/slack.ts","../src/cli/export.ts","../src/cli/config.ts","../src/cli/pause.ts","../src/cli/undo.ts","../src/cli/clear.ts","../src/cli/uninstall.ts","../src/cli/profile.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { registerCapture } from './cli/capture'\nimport { registerHook } from './cli/hook'\n\ndeclare const __WORKSCRIBE_VERSION__: string\nimport { registerInit } from './cli/init'\nimport { registerStatus } from './cli/status'\nimport { registerEvents } from './cli/events'\nimport { registerSessions } from './cli/sessions'\nimport { registerSummary } from './cli/summary'\nimport { registerExport } from './cli/export'\nimport { registerConfig } from './cli/config'\nimport { registerPause } from './cli/pause'\nimport { registerUndo } from './cli/undo'\nimport { registerClear } from './cli/clear'\nimport { registerUninstall } from './cli/uninstall'\nimport { registerProfile } from './cli/profile'\n\nconst program = new Command()\n\nprogram.name('workscribe').description('Automatic developer work journal').version(__WORKSCRIBE_VERSION__)\n\nregisterCapture(program)\nregisterHook(program)\nregisterInit(program)\nregisterStatus(program)\nregisterEvents(program)\nregisterSessions(program)\nregisterSummary(program)\nregisterExport(program)\nregisterConfig(program)\nregisterPause(program)\nregisterUndo(program)\nregisterClear(program)\nregisterUninstall(program)\nregisterProfile(program)\n\nprogram.parse()\n","import fs from 'fs'\nimport { insertEvent, getLastEvent } from '../db'\nimport { redact } from './redact'\nimport { getGitContext } from './git'\nimport { getCommitsSince } from './git-snapshot'\nimport { readLastAiderPrompt } from './aider'\nimport { normalizeCommand } from '../normalize/patterns'\nimport { readConfig } from '../config'\nimport { shouldFilter, isDuplicate } from './filter'\nimport { PAUSE_FLAG_PATH } from '../utils/paths'\nimport { loadAIToolRegistry } from '../config/registry'\n\nexport function captureCommand(opts: {\n command: string\n cwd: string\n exitCode: number | null\n durationMs: number | null\n gitBefore?: string\n source?: string\n}): void {\n // Check pause flag before any I/O\n if (fs.existsSync(PAUSE_FLAG_PATH)) return\n\n const config = readConfig()\n const { command, cwd, exitCode, durationMs } = opts\n\n // 1. Filter noise commands\n if (shouldFilter(command, config.capture.ignore)) return\n\n // 2. Deduplicate: same command + same cwd within 5 seconds\n const last = getLastEvent()\n if (isDuplicate(command, cwd, last ?? undefined)) return\n\n // 3. Redact sensitive patterns\n const safeCommand = redact(command, config.redact.extra)\n\n // 4. Extract git context (with optional per-project name override)\n const nameOverride = config.projects?.[cwd] ?? null\n const { repoName, branch } = getGitContext(cwd, nameOverride)\n\n // 5. Normalize to typed event\n const { category, metadata } = normalizeCommand(safeCommand)\n\n if (category === 'ai_session' && config.capture.aiTools === false) return\n\n // Hint passthrough: preserve context for unrecognised commands so the AI can describe them\n if (category === 'other') {\n const firstToken = safeCommand.trim().split(/\\s+/)[0]\n if (firstToken) metadata.tool = firstToken\n metadata.hint = safeCommand.trim().slice(0, 120)\n }\n\n if (opts.source) metadata.source = opts.source\n\n // 6. For ai_session events, enrich metadata\n if (category === 'ai_session') {\n // 6a. Commits made during the session\n if (opts.gitBefore) {\n const commits = getCommitsSince(opts.gitBefore, cwd)\n if (commits.length > 0) metadata.commits = commits\n }\n\n // 6b. Last user prompt from history file (e.g. Aider)\n if (config.capture.includeAiderPrompt !== false) {\n const toolEntry = loadAIToolRegistry().find((entry) => entry.tool === metadata.tool)\n if (toolEntry?.contextSource === 'history-file') {\n const prompt = readLastAiderPrompt(cwd)\n if (prompt) metadata.prompt = prompt\n }\n }\n }\n\n // 7. Persist\n insertEvent({\n captured_at: new Date().toISOString(),\n command: safeCommand,\n cwd,\n exit_code: exitCode,\n duration_ms: durationMs,\n repo_name: repoName,\n branch,\n category,\n metadata: Object.keys(metadata).length > 0 ? JSON.stringify(metadata) : null,\n })\n}\n","import { DatabaseSync } from 'node:sqlite'\nimport fs from 'fs'\nimport { WORKSCRIBE_DIR, DB_PATH } from '../utils/paths'\nimport type { EventRow, SessionRow } from './types'\nimport { MIGRATIONS } from './migrations'\nexport type { EventRow, SessionRow } from './types'\n\nlet _db: DatabaseSync | null = null\n\nexport function getDb(): DatabaseSync {\n if (_db) return _db\n\n // Ensure ~/.workscribe/ exists\n if (!fs.existsSync(WORKSCRIBE_DIR)) {\n fs.mkdirSync(WORKSCRIBE_DIR, { recursive: true })\n }\n\n // Don't assign to _db until after migrations succeed — if applyMigrations\n // throws, _db stays null so the next call retries cleanly instead of\n // returning a partially-initialised singleton.\n const db = new DatabaseSync(DB_PATH)\n try {\n fs.chmodSync(DB_PATH, 0o600)\n } catch {\n /* ignore if already correct */\n }\n db.exec('PRAGMA journal_mode = WAL')\n db.exec('PRAGMA foreign_keys = ON')\n applyMigrations(db)\n _db = db\n return _db\n}\n\nfunction applyMigrations(db: DatabaseSync): void {\n // Create the migration tracking table if this is the first run\n db.exec(`\n CREATE TABLE IF NOT EXISTS schema_migrations (\n version INTEGER PRIMARY KEY,\n applied_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n\n // Bootstrap: if the events table already exists but schema_migrations is\n // empty, this is an existing install that predates the migration system.\n // Seed version 1 as applied so we don't re-run the initial schema.\n const hasEvents = db.prepare(\"SELECT name FROM sqlite_master WHERE type='table' AND name='events'\").get()\n const hasVersion1 = db.prepare('SELECT version FROM schema_migrations WHERE version = 1').get()\n\n if (hasEvents && !hasVersion1) {\n db.prepare(\"INSERT INTO schema_migrations (version, applied_at) VALUES ($version, datetime('now'))\").run({\n version: 1,\n })\n }\n\n // Collect already-applied versions\n const applied = new Set(\n (db.prepare('SELECT version FROM schema_migrations').all() as { version: number }[]).map((row) => row.version)\n )\n\n // Apply each pending migration in order, wrapped in a transaction so a\n // partial failure leaves the DB cleanly at the previous version.\n for (const migration of MIGRATIONS) {\n if (applied.has(migration.version)) continue\n\n db.exec('BEGIN')\n try {\n db.exec(migration.sql)\n db.prepare(\"INSERT INTO schema_migrations (version, applied_at) VALUES ($version, datetime('now'))\").run({\n version: migration.version,\n })\n db.exec('COMMIT')\n } catch (err) {\n try {\n db.exec('ROLLBACK')\n } catch {\n /* already rolled back or connection lost */\n }\n throw new Error(`Migration ${migration.version} (${migration.description}) failed: ${(err as Error).message}`)\n }\n }\n}\n\n// ─── Typed query helpers ──────────────────────────────────────────────────────\n\nexport function insertEvent(params: {\n captured_at: string\n command: string\n cwd: string\n exit_code: number | null\n duration_ms: number | null\n repo_name: string | null\n branch: string | null\n category: string\n metadata: string | null\n}): void {\n const db = getDb()\n const stmt = db.prepare(`\n INSERT INTO events (captured_at, command, cwd, exit_code, duration_ms, repo_name, branch, category, metadata)\n VALUES ($captured_at, $command, $cwd, $exit_code, $duration_ms, $repo_name, $branch, $category, $metadata)\n `)\n stmt.run(params)\n}\n\nexport function getLastEvent(): EventRow | undefined {\n const db = getDb()\n const stmt = db.prepare('SELECT * FROM events ORDER BY id DESC LIMIT 1')\n return stmt.get() as EventRow | undefined\n}\n\nexport function getEventsForDate(date: string): EventRow[] {\n const db = getDb()\n const stmt = db.prepare(`\n SELECT * FROM events\n WHERE date(captured_at, 'localtime') = $date\n ORDER BY captured_at ASC\n `)\n return stmt.all({ date }) as unknown as EventRow[]\n}\n\nexport function getRecentEvents(limit = 20): EventRow[] {\n const db = getDb()\n const stmt = db.prepare('SELECT * FROM events ORDER BY captured_at DESC LIMIT $limit')\n return stmt.all({ limit }) as unknown as EventRow[]\n}\n\nexport function getEventCount(): number {\n const db = getDb()\n const stmt = db.prepare('SELECT COUNT(*) as count FROM events')\n const row = stmt.get() as { count: number }\n return row.count\n}\n\nexport function insertSession(params: {\n date: string\n started_at: string\n ended_at: string\n repo_name: string | null\n event_count: number\n summary: string | null\n}): number {\n const db = getDb()\n const stmt = db.prepare(`\n INSERT INTO sessions (date, started_at, ended_at, repo_name, event_count, summary)\n VALUES ($date, $started_at, $ended_at, $repo_name, $event_count, $summary)\n `)\n const result = stmt.run(params)\n return Number(result.lastInsertRowid)\n}\n\nexport function insertSessionEvent(sessionId: number, eventId: number): void {\n const db = getDb()\n const stmt = db.prepare(`\n INSERT OR IGNORE INTO session_events (session_id, event_id) VALUES ($session_id, $event_id)\n `)\n stmt.run({ session_id: sessionId, event_id: eventId })\n}\n\nexport function getEventsBySessionId(sessionId: number): EventRow[] {\n const db = getDb()\n const stmt = db.prepare(`\n SELECT e.* FROM events e\n INNER JOIN session_events se ON se.event_id = e.id\n WHERE se.session_id = $session_id\n ORDER BY e.captured_at ASC\n `)\n return stmt.all({ session_id: sessionId }) as unknown as EventRow[]\n}\n\nexport function getSessionsForDate(date: string): SessionRow[] {\n const db = getDb()\n const stmt = db.prepare('SELECT * FROM sessions WHERE date = $date ORDER BY started_at ASC')\n return stmt.all({ date }) as unknown as SessionRow[]\n}\n\nexport function updateSessionSummary(sessionId: number, summary: string): void {\n const db = getDb()\n const stmt = db.prepare('UPDATE sessions SET summary = $summary WHERE id = $id')\n stmt.run({ summary, id: sessionId })\n}\n\nexport function getLastEventIds(n: number): number[] {\n const db = getDb()\n const rows = db.prepare('SELECT id FROM events ORDER BY id DESC LIMIT $n').all({ n }) as { id: number }[]\n return rows.map((row) => row.id)\n}\n\nexport function getEventsByIds(ids: number[]): EventRow[] {\n if (ids.length === 0) return []\n const db = getDb()\n const placeholders = ids.map(() => '?').join(', ')\n return db\n .prepare(`SELECT * FROM events WHERE id IN (${placeholders}) ORDER BY id DESC`)\n .all(...ids) as unknown as EventRow[]\n}\n\nexport function deleteEventsByIds(ids: number[]): void {\n if (ids.length === 0) return\n const db = getDb()\n const placeholders = ids.map(() => '?').join(', ')\n\n const affectedDates = db\n .prepare(`SELECT DISTINCT date(captured_at, 'localtime') as date FROM events WHERE id IN (${placeholders})`)\n .all(...ids) as { date: string }[]\n\n db.prepare(`DELETE FROM events WHERE id IN (${placeholders})`).run(...ids)\n\n for (const { date } of affectedDates) {\n clearSessionsForDate(date)\n }\n}\n\nexport function deleteEventsForDate(date: string): number {\n const db = getDb()\n // Clear sessions (and session_events) before deleting events — FK constraint order\n clearSessionsForDate(date)\n const result = db.prepare(`DELETE FROM events WHERE date(captured_at, 'localtime') = $date`).run({ date }) as {\n changes: number\n }\n return result.changes\n}\n\nexport function getOtherEventToolCounts(days: number): { tool: string; count: number }[] {\n const db = getDb()\n return db\n .prepare(\n `SELECT json_extract(metadata, '$.tool') as tool, COUNT(*) as count\n FROM events\n WHERE category = 'other'\n AND captured_at >= datetime('now', $offset)\n AND json_extract(metadata, '$.tool') IS NOT NULL\n GROUP BY tool\n ORDER BY count DESC`\n )\n .all({ offset: `-${days} days` }) as { tool: string; count: number }[]\n}\n\nexport function getRecentOtherRate(days: number): { total: number; otherCount: number } {\n const db = getDb()\n const row = db\n .prepare(\n `SELECT COUNT(*) as total,\n SUM(CASE WHEN category = 'other' THEN 1 ELSE 0 END) as otherCount\n FROM events\n WHERE captured_at >= datetime('now', $offset)`\n )\n .get({ offset: `-${days} days` }) as { total: number; otherCount: number }\n return row\n}\n\nexport function clearSessionsForDate(date: string): void {\n const db = getDb()\n // Remove session_events first due to FK constraint\n db.prepare(\n `\n DELETE FROM session_events WHERE session_id IN (\n SELECT id FROM sessions WHERE date = $date\n )\n `\n ).run({ date })\n db.prepare('DELETE FROM sessions WHERE date = $date').run({ date })\n}\n","import path from 'path'\nimport os from 'os'\n\nexport const WORKSCRIBE_DIR = path.join(os.homedir(), '.workscribe')\nexport const DB_PATH = path.join(WORKSCRIBE_DIR, 'workscribe.db')\nexport const CONFIG_PATH = path.join(WORKSCRIBE_DIR, 'config.json')\nexport const DEBUG_LOG_PATH = path.join(WORKSCRIBE_DIR, 'debug.log')\nexport const EXPORTS_DIR = path.join(WORKSCRIBE_DIR, 'exports')\nexport const PAUSE_FLAG_PATH = path.join(WORKSCRIBE_DIR, 'paused')\nexport const WEEKLY_CACHE_DIR = path.join(WORKSCRIBE_DIR, 'weekly-cache')\nexport const PROFILES_DIR = path.join(WORKSCRIBE_DIR, 'profiles')\n","export default {\n version: 1,\n description: 'initial schema',\n sql: `\n CREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n captured_at TEXT NOT NULL,\n command TEXT NOT NULL,\n cwd TEXT NOT NULL,\n exit_code INTEGER,\n duration_ms INTEGER,\n repo_name TEXT,\n branch TEXT,\n category TEXT NOT NULL DEFAULT 'other',\n metadata TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_events_captured_at ON events(captured_at);\n CREATE INDEX IF NOT EXISTS idx_events_repo_name ON events(repo_name);\n\n CREATE TABLE IF NOT EXISTS sessions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n date TEXT NOT NULL,\n started_at TEXT NOT NULL,\n ended_at TEXT NOT NULL,\n repo_name TEXT,\n event_count INTEGER NOT NULL DEFAULT 0,\n summary TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_sessions_date ON sessions(date);\n\n CREATE TABLE IF NOT EXISTS session_events (\n session_id INTEGER NOT NULL REFERENCES sessions(id),\n event_id INTEGER NOT NULL REFERENCES events(id),\n PRIMARY KEY (session_id, event_id)\n );\n `,\n}\n","const migration = {\n version: 2,\n description: 'Rename granular categories to 13 universal semantic categories',\n sql: `\n UPDATE events SET category = 'shipping' WHERE category IN ('code_commit','code_push','code_merge');\n UPDATE events SET category = 'versioning' WHERE category IN ('code_pull','branch_switch','code_stash','git_other');\n UPDATE events SET category = 'building' WHERE category = 'build';\n UPDATE events SET category = 'running' WHERE category IN ('server_run','script_run');\n UPDATE events SET category = 'testing' WHERE category = 'test_run';\n UPDATE events SET category = 'linting' WHERE category = 'lint_run';\n UPDATE events SET category = 'dependencies' WHERE category IN ('dependency_install','dependency_remove');\n UPDATE events SET category = 'infrastructure' WHERE category = 'infrastructure';\n UPDATE events SET category = 'files' WHERE category IN ('file_ops','environment');\n UPDATE events SET category = 'exploring' WHERE category IN ('code_search','code_read');\n `,\n}\n\nexport default migration\n","import initialSchema from './001_initial_schema'\nimport semanticCategories from './002_semantic_categories'\n\nexport interface Migration {\n version: number\n description: string\n sql: string\n}\n\n// Ordered list — append only. Never modify or remove an existing entry.\nexport const MIGRATIONS: Migration[] = [initialSchema, semanticCategories]\n","// Patterns that match known sensitive values\nconst BUILTIN_PATTERNS: RegExp[] = [\n // AWS access keys\n /AKIA[0-9A-Z]{16}/g,\n // AWS secret access keys (40 char base64-ish after common env vars)\n /(?<=AWS_SECRET_ACCESS_KEY[=\\s]+)\\S+/gi,\n // GitHub tokens\n /ghp_[a-zA-Z0-9]{36}/g,\n /github_pat_[a-zA-Z0-9_]{82}/g,\n // GitLab tokens\n /glpat-[a-zA-Z0-9\\-]{20}/g,\n // Generic JWTs (three base64url segments)\n /eyJ[a-zA-Z0-9_-]+\\.eyJ[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]+/g,\n // Slack tokens and incoming webhook URLs\n /xox[baprs]-[a-zA-Z0-9\\-]+/g,\n /https:\\/\\/hooks\\.slack\\.com\\/services\\/[A-Z0-9]+\\/[A-Z0-9]+\\/[a-zA-Z0-9]+/g,\n // Stripe keys\n /sk_(live|test)_[a-zA-Z0-9]{24,}/g,\n // Values after long-form secret flags (single-char flags like -t/-p/-k are too ambiguous)\n /(?<=--(password|passwd|secret|token|key|api[-_]?key|auth[-_]?token)\\s+)\\S+/gi,\n // export VAR=VALUE where VAR looks sensitive\n /(?<=export\\s+(?:[A-Z_]*(?:TOKEN|SECRET|KEY|PASSWORD|PASS|AUTH|CREDENTIAL)[A-Z_]*)=)\\S+/gi,\n]\n\nexport function redact(command: string, extraPatterns: string[] = []): string {\n let result = command\n\n const allPatterns = [...BUILTIN_PATTERNS]\n\n for (const pattern of extraPatterns) {\n try {\n allPatterns.push(new RegExp(pattern, 'g'))\n } catch {\n // Invalid regex — skip silently\n }\n }\n\n for (const pattern of allPatterns) {\n // Reset lastIndex for global regexes\n pattern.lastIndex = 0\n result = result.replace(pattern, '[REDACTED]')\n }\n\n return result\n}\n","import { execSync } from 'child_process'\nimport path from 'path'\nimport fs from 'fs'\n\nexport interface GitContext {\n repoName: string | null\n branch: string | null\n}\n\nfunction nameFromRemote(root: string): string | null {\n try {\n const url = execSync('git remote get-url origin', {\n cwd: root,\n timeout: 2000,\n stdio: 'pipe',\n })\n .toString()\n .trim()\n const match = url.match(/\\/([^/]+?)(?:\\.git)?$/)\n return match ? match[1] : null\n } catch {\n return null\n }\n}\n\nfunction nameFromPackageJson(root: string): string | null {\n try {\n const raw = fs.readFileSync(path.join(root, 'package.json'), 'utf-8')\n const pkg = JSON.parse(raw) as { name?: string }\n if (!pkg.name) return null\n return pkg.name.replace(/^@[^/]+\\//, '')\n } catch {\n return null\n }\n}\n\nexport function getGitContext(cwd: string, nameOverride?: string | null): GitContext {\n try {\n const root = execSync('git rev-parse --show-toplevel', {\n cwd,\n timeout: 2000,\n stdio: 'pipe',\n })\n .toString()\n .trim()\n\n const repoName = nameOverride ?? nameFromRemote(root) ?? nameFromPackageJson(root) ?? path.basename(root)\n\n let branch: string | null = null\n try {\n branch =\n execSync('git branch --show-current', {\n cwd,\n timeout: 2000,\n stdio: 'pipe',\n })\n .toString()\n .trim() || null\n } catch {\n // Detached HEAD or not a git repo\n }\n\n return { repoName, branch }\n } catch {\n return { repoName: null, branch: null }\n }\n}\n","import { execSync } from 'child_process'\n\n/**\n * Returns commit subject lines for all commits made between `sha` and HEAD.\n * Returns an empty array if sha is empty, HEAD hasn't moved, or git fails.\n */\nexport function getCommitsSince(sha: string, cwd: string): string[] {\n if (!sha) return []\n try {\n const out = execSync(`git log ${sha}..HEAD --format=%s`, { cwd, timeout: 3000 }).toString().trim()\n return out ? out.split('\\n').filter(Boolean) : []\n } catch {\n return []\n }\n}\n","import fs from 'fs'\nimport path from 'path'\n\nconst HISTORY_FILE = '.aider.chat.history.md'\nconst PROMPT_MAX_LENGTH = 200\n\nexport function readLastAiderPrompt(cwd: string): string | null {\n try {\n const histPath = path.join(cwd, HISTORY_FILE)\n const content = fs.readFileSync(histPath, 'utf-8')\n const matches = [...content.matchAll(/^> (.+)$/gm)]\n if (!matches.length) return null\n return matches[matches.length - 1][1].trim().slice(0, PROMPT_MAX_LENGTH)\n } catch {\n return null\n }\n}\n","import fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport BUILTIN_TOOLS from './ai-tools.json'\nimport { debugLog } from '../utils/logger'\n\nexport interface AIToolEntry {\n tool: string\n displayName: string\n pattern: string\n hook: string | null\n contextSource: string | null\n}\n\nconst USER_REGISTRY_PATH = path.join(os.homedir(), '.workscribe', 'ai-tools.json')\n\nexport function loadAIToolRegistry(): AIToolEntry[] {\n let userEntries: AIToolEntry[] = []\n\n try {\n if (fs.existsSync(USER_REGISTRY_PATH)) {\n const raw = fs.readFileSync(USER_REGISTRY_PATH, 'utf-8')\n const parsed = JSON.parse(raw)\n if (Array.isArray(parsed)) {\n userEntries = parsed\n .filter((entry) => typeof entry.tool === 'string' && typeof entry.pattern === 'string')\n .map((entry) => ({\n tool: entry.tool as string,\n displayName: (entry.displayName as string | undefined) ?? (entry.tool as string),\n pattern: entry.pattern as string,\n hook: (entry.hook as string | null | undefined) ?? null,\n contextSource: (entry.contextSource as string | null | undefined) ?? null,\n }))\n }\n }\n } catch {\n debugLog('registry', 'Failed to load user AI tool registry — using built-ins only')\n }\n\n if (userEntries.length === 0) return BUILTIN_TOOLS as AIToolEntry[]\n\n const userToolSlugs = new Set(userEntries.map((entry) => entry.tool))\n const filteredBuiltins = (BUILTIN_TOOLS as AIToolEntry[]).filter((entry) => !userToolSlugs.has(entry.tool))\n return [...filteredBuiltins, ...userEntries]\n}\n","[\n {\n \"tool\": \"claude\",\n \"displayName\": \"Claude Code\",\n \"pattern\": \"^claude\\\\b\",\n \"hook\": \"claude-code\",\n \"contextSource\": \"hook\"\n },\n {\n \"tool\": \"aider\",\n \"displayName\": \"Aider\",\n \"pattern\": \"^aider\\\\b\",\n \"hook\": null,\n \"contextSource\": \"history-file\"\n },\n {\n \"tool\": \"gemini\",\n \"displayName\": \"Gemini\",\n \"pattern\": \"^gemini\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"gh copilot\",\n \"displayName\": \"GitHub Copilot\",\n \"pattern\": \"^gh\\\\s+copilot\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"cody\",\n \"displayName\": \"Cody\",\n \"pattern\": \"^cody\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"amazon-q\",\n \"displayName\": \"Amazon Q\",\n \"pattern\": \"^q\\\\s+(chat|dev)\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"continue\",\n \"displayName\": \"Continue\",\n \"pattern\": \"^continue\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"cursor\",\n \"displayName\": \"Cursor\",\n \"pattern\": \"^cursor\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n }\n]\n","import chalk from 'chalk'\nimport fs from 'fs'\nimport { DEBUG_LOG_PATH } from './paths'\n\nconst isDebug = process.env.WORKSCRIBE_DEBUG === '1'\n\nexport const log = {\n info: (msg: string) => console.log(chalk.cyan('→'), msg),\n success: (msg: string) => console.log(chalk.green('✓'), msg),\n warn: (msg: string) => console.log(chalk.yellow('⚠'), msg),\n error: (msg: string) => console.error(chalk.red('✗'), msg),\n plain: (msg: string) => console.log(msg),\n}\n\nexport function debugLog(context: string, error: unknown): void {\n if (!isDebug) return\n const entry = `[${new Date().toISOString()}] [${context}] ${error instanceof Error ? error.stack : String(error)}\\n`\n try {\n fs.appendFileSync(DEBUG_LOG_PATH, entry, { mode: 0o600 })\n } catch {\n // If we can't write to the debug log, silently ignore\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { PROFILES_DIR } from '../utils/paths'\nimport { readConfig } from '../config'\nimport { isValidProfile } from './schema'\nimport type { Profile, ManifestEntry, ProfileRule } from './schema'\nimport { readCachedManifest } from './fetcher'\nimport { debugLog } from '../utils/logger'\n\n// Matches the Rule interface in patterns.ts — structural compatibility without circular import\ninterface CompiledRule {\n match(cmd: string): { category: string; metadata: Record<string, unknown> } | null\n}\n\nfunction compileRule(profileName: string, rule: ProfileRule): CompiledRule | null {\n let regex: RegExp\n try {\n regex = new RegExp(rule.pattern)\n } catch {\n debugLog('profiles', `Profile \"${profileName}\": invalid pattern \"${rule.pattern}\" — skipping rule`)\n return null\n }\n\n return {\n match(cmd: string) {\n const match = cmd.match(regex)\n if (!match) return null\n const metadata: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(rule.metadata ?? {})) {\n metadata[key] = value.replace(/\\$(\\d+)/g, (_, index: string) => match[Number(index)] ?? '')\n }\n return { category: rule.category, metadata }\n },\n }\n}\n\nfunction loadProfileFromDisk(name: string): Profile | null {\n const filePath = path.join(PROFILES_DIR, `${name}.json`)\n if (!fs.existsSync(filePath)) {\n debugLog('profiles', `Profile \"${name}\" not found in cache — run: workscribe profile add ${name}`)\n return null\n }\n let candidate: unknown\n try {\n candidate = JSON.parse(fs.readFileSync(filePath, 'utf-8'))\n } catch {\n debugLog('profiles', `Profile \"${name}\" contains invalid JSON — skipping`)\n return null\n }\n if (!isValidProfile(candidate)) {\n debugLog('profiles', `Profile \"${name}\" failed schema validation — skipping`)\n return null\n }\n return candidate\n}\n\nfunction loadUserProfiles(): Profile[] {\n if (!fs.existsSync(PROFILES_DIR)) return []\n const activeNames = new Set(readConfig().capture.profiles)\n return fs\n .readdirSync(PROFILES_DIR)\n .filter((file) => file.endsWith('.json') && file !== 'manifest.json')\n .filter((file) => {\n const name = file.replace(/\\.json$/, '')\n return !activeNames.has(name) // avoid double-loading names already in config\n })\n .flatMap((file) => {\n const candidate = loadProfileFromDisk(file.replace(/\\.json$/, ''))\n return candidate ? [candidate] : []\n })\n .filter((profile) => fs.existsSync(path.join(PROFILES_DIR, `${profile.name}.json`)))\n}\n\nexport function getActiveProfileRules(): CompiledRule[] {\n const activeNames = readConfig().capture.profiles\n if (activeNames.length === 0) return []\n\n return activeNames.flatMap((name) => {\n const profile = loadProfileFromDisk(name)\n if (!profile) return []\n return profile.rules.flatMap((rule) => {\n const compiled = compileRule(profile.name, rule)\n return compiled ? [compiled] : []\n })\n })\n}\n\nexport function getActiveProfileAiContexts(): string[] {\n const activeNames = readConfig().capture.profiles\n if (activeNames.length === 0) return []\n\n return activeNames.flatMap((name) => {\n const profile = loadProfileFromDisk(name)\n return profile?.aiContext ? [profile.aiContext] : []\n })\n}\n\nexport function getCachedProfiles(): Profile[] {\n if (!fs.existsSync(PROFILES_DIR)) return []\n return fs\n .readdirSync(PROFILES_DIR)\n .filter((file) => file.endsWith('.json') && file !== 'manifest.json')\n .flatMap((file) => {\n const profile = loadProfileFromDisk(file.replace(/\\.json$/, ''))\n return profile ? [profile] : []\n })\n}\n\nexport function detectProfilesForDirectory(dir: string): ManifestEntry[] {\n const manifest = readCachedManifest()\n if (!manifest) return []\n\n const activeNames = new Set(readConfig().capture.profiles)\n\n return manifest.filter((entry) => {\n if (activeNames.has(entry.name)) return false\n const indicatorFiles = entry.detect?.files ?? []\n return indicatorFiles.length > 0 && indicatorFiles.every((file) => fs.existsSync(path.join(dir, file)))\n })\n}\n\nexport { loadUserProfiles }\n","import fs from 'fs'\nimport { CONFIG_PATH } from '../utils/paths'\n\nexport interface WorkscribeConfig {\n ai: {\n provider: string // 'anthropic' | 'openai' | 'ollama' | 'openai-compatible'\n apiKey: string\n model: string\n baseUrl: string\n }\n session: {\n idleTimeout: number // minutes\n }\n capture: {\n ignore: string[]\n aiTools: boolean\n includeAiderPrompt: boolean\n profiles: string[]\n }\n redact: {\n extra: string[]\n }\n summary: {\n format: 'markdown' | 'json'\n }\n projects?: Record<string, string> // absolute path → display name override\n integrations?: {\n slackWebhook?: string\n webhook?: string\n }\n}\n\nconst DEFAULTS: WorkscribeConfig = {\n ai: {\n provider: '',\n apiKey: '',\n model: '',\n baseUrl: '',\n },\n session: {\n idleTimeout: 30,\n },\n capture: {\n ignore: ['cd', 'ls', 'll', 'la', 'ls -la', 'ls -l', 'ls -a', 'pwd', 'clear', 'exit', 'history', 'man'],\n aiTools: true,\n includeAiderPrompt: true,\n profiles: [],\n },\n redact: {\n extra: [],\n },\n summary: {\n format: 'markdown',\n },\n}\n\nexport function readConfig(): WorkscribeConfig {\n if (!fs.existsSync(CONFIG_PATH)) return { ...DEFAULTS }\n try {\n const raw = fs.readFileSync(CONFIG_PATH, 'utf-8')\n const parsed = JSON.parse(raw)\n return deepMerge(DEFAULTS, parsed)\n } catch {\n return { ...DEFAULTS }\n }\n}\n\nexport function writeConfig(config: WorkscribeConfig): void {\n fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { encoding: 'utf-8', mode: 0o600 })\n // Enforce permissions on existing files (mode only applies on creation above)\n try {\n fs.chmodSync(CONFIG_PATH, 0o600)\n } catch {\n /* ignore */\n }\n}\n\nexport function getConfigValue(config: WorkscribeConfig, key: string): unknown {\n const parts = key.split('.')\n let cur: unknown = config\n for (const part of parts) {\n if (cur == null || typeof cur !== 'object') return undefined\n cur = (cur as Record<string, unknown>)[part]\n }\n return cur\n}\n\nexport function setConfigValue(config: WorkscribeConfig, key: string, value: string): WorkscribeConfig {\n const parts = key.split('.')\n const result = JSON.parse(JSON.stringify(config)) as WorkscribeConfig\n let cur = result as unknown as Record<string, unknown>\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]\n if (cur[part] == null || typeof cur[part] !== 'object') {\n cur[part] = {}\n }\n cur = cur[part] as Record<string, unknown>\n }\n const lastKey = parts[parts.length - 1]\n // Coerce value type\n if (value === 'true') cur[lastKey] = true\n else if (value === 'false') cur[lastKey] = false\n else if (!isNaN(Number(value))) cur[lastKey] = Number(value)\n else cur[lastKey] = value\n return result\n}\n\nfunction deepMerge<T extends object>(defaults: T, overrides: Partial<T>): T {\n const result = { ...defaults }\n for (const key of Object.keys(overrides) as (keyof T)[]) {\n const val = overrides[key]\n if (val !== null && typeof val === 'object' && !Array.isArray(val) && typeof defaults[key] === 'object') {\n result[key] = deepMerge(defaults[key] as object, val as object) as T[keyof T]\n } else if (val !== undefined) {\n result[key] = val as T[keyof T]\n }\n }\n return result\n}\n","export interface ProfileRule {\n pattern: string\n category: string\n metadata?: Record<string, string>\n}\n\nexport interface Profile {\n name: string\n displayName: string\n version: string\n detect?: { files?: string[] }\n rules: ProfileRule[]\n aiContext?: string\n}\n\nexport interface ManifestEntry {\n name: string\n displayName: string\n tags: string[]\n description: string\n keywords: string[]\n detect?: { files?: string[] }\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n\nfunction isValidRule(rule: unknown): boolean {\n if (!rule || typeof rule !== 'object') return false\n const { pattern, category } = rule as Record<string, unknown>\n return isNonEmptyString(pattern) && isNonEmptyString(category)\n}\n\nexport function isValidProfile(candidate: unknown): candidate is Profile {\n if (!candidate || typeof candidate !== 'object') return false\n const { name, displayName, version, rules } = candidate as Record<string, unknown>\n if (!isNonEmptyString(name) || !isNonEmptyString(displayName) || !isNonEmptyString(version)) return false\n if (!Array.isArray(rules)) return false\n return rules.every(isValidRule)\n}\n\nexport function isValidManifest(m: unknown): m is ManifestEntry[] {\n return (\n Array.isArray(m) &&\n m.every((e) => e && typeof e === 'object' && typeof (e as Record<string, unknown>).name === 'string')\n )\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { PROFILES_DIR } from '../utils/paths'\nimport { isValidProfile, isValidManifest } from './schema'\nimport type { ManifestEntry, Profile } from './schema'\nimport { debugLog } from '../utils/logger'\n\nconst REGISTRY_BASE = 'https://raw.githubusercontent.com/workscribe/profiles/main'\n\nfunction manifestCachePath(): string {\n return path.join(PROFILES_DIR, 'manifest.json')\n}\n\nexport async function fetchManifest(): Promise<ManifestEntry[]> {\n const response = await fetch(`${REGISTRY_BASE}/manifest.json`)\n if (!response.ok) throw new Error(`Registry unreachable (${response.status})`)\n const data: unknown = await response.json()\n if (!isValidManifest(data)) throw new Error('Manifest format unrecognised')\n return data\n}\n\nexport async function fetchProfile(name: string): Promise<Profile> {\n const response = await fetch(`${REGISTRY_BASE}/${name}.json`)\n if (response.status === 404) throw new Error(`Profile \"${name}\" not found in registry`)\n if (!response.ok) throw new Error(`Registry unreachable (${response.status})`)\n const data: unknown = await response.json()\n if (!isValidProfile(data)) throw new Error(`Profile \"${name}\" failed schema validation`)\n return data\n}\n\nexport async function installProfile(name: string): Promise<void> {\n ensureProfilesDir()\n const profile = await fetchProfile(name)\n const dest = path.join(PROFILES_DIR, `${name}.json`)\n fs.writeFileSync(dest, JSON.stringify(profile, null, 2), { encoding: 'utf-8', mode: 0o600 })\n debugLog('profiles', `Installed profile \"${name}\" to ${dest}`)\n}\n\nexport async function cacheManifest(): Promise<ManifestEntry[]> {\n ensureProfilesDir()\n const manifest = await fetchManifest()\n fs.writeFileSync(manifestCachePath(), JSON.stringify(manifest, null, 2), { encoding: 'utf-8', mode: 0o600 })\n return manifest\n}\n\nexport function readCachedManifest(): ManifestEntry[] | null {\n if (!fs.existsSync(manifestCachePath())) return null\n try {\n const data: unknown = JSON.parse(fs.readFileSync(manifestCachePath(), 'utf-8'))\n return isValidManifest(data) ? data : null\n } catch {\n return null\n }\n}\n\nfunction ensureProfilesDir(): void {\n if (!fs.existsSync(PROFILES_DIR)) {\n fs.mkdirSync(PROFILES_DIR, { recursive: true, mode: 0o700 })\n }\n}\n","import { loadAIToolRegistry } from '../config/registry'\nimport { getActiveProfileRules } from '../profiles/loader'\nimport { debugLog } from '../utils/logger'\n\nexport interface NormalizedEvent {\n category: string\n metadata: Record<string, unknown>\n}\n\ninterface Rule {\n match(cmd: string): NormalizedEvent | null\n}\n\nfunction makeRule(\n pattern: RegExp,\n category: string,\n extract: (match: RegExpMatchArray, cmd: string) => Record<string, unknown> = () => ({})\n): Rule {\n return {\n match(cmd) {\n const m = cmd.match(pattern)\n if (!m) return null\n return { category, metadata: extract(m, cmd) }\n },\n }\n}\n\n// Extract package names from install commands like: npm install foo bar\nfunction extractPackages(cmd: string, afterKeyword: string): string[] {\n const idx = cmd.indexOf(afterKeyword)\n if (idx === -1) return []\n return cmd\n .slice(idx + afterKeyword.length)\n .trim()\n .split(/\\s+/)\n .filter((part) => part && !part.startsWith('-'))\n}\n\nconst BASE_RULES: Rule[] = [\n // ─── Git operations ───────────────────────────────────────────────────────\n makeRule(/^git\\s+commit\\b/, 'shipping', (_m, cmd) => {\n const msgMatch = cmd.match(/-m\\s+[\"']?([^\"']+)[\"']?/)\n return { message: msgMatch ? msgMatch[1].trim() : null }\n }),\n\n makeRule(/^git\\s+push\\b/, 'shipping', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { remote: parts[2] ?? 'origin', branch: parts[3] ?? null }\n }),\n\n makeRule(/^git\\s+(pull|fetch)\\b/, 'versioning', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { subcommand: parts[1], remote: parts[2] ?? 'origin' }\n }),\n\n makeRule(/^git\\s+(checkout|switch)\\b/, 'versioning', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n const branch = parts.find((part) => !part.startsWith('-') && part !== 'git' && part !== parts[1])\n return { branch: branch ?? null }\n }),\n\n makeRule(/^git\\s+(merge|rebase)\\b/, 'shipping', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { subcommand: parts[1], target: parts[2] ?? null }\n }),\n\n makeRule(/^git\\s+stash\\b/, 'versioning', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { subcommand: parts[2] ?? 'push' }\n }),\n\n makeRule(/^git\\s+/, 'versioning', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { subcommand: parts[1] ?? null }\n }),\n\n // ─── Releasing ────────────────────────────────────────────────────────────\n makeRule(/^npm\\s+publish\\b/, 'releasing', () => ({ tool: 'npm' })),\n makeRule(/^cargo\\s+publish\\b/, 'releasing', () => ({ tool: 'cargo' })),\n makeRule(/^gem\\s+push\\b/, 'releasing', () => ({ tool: 'gem' })),\n makeRule(/^docker\\s+push\\b/, 'releasing', (_m, cmd) => ({ tool: 'docker', image: cmd.split(/\\s+/)[2] ?? null })),\n makeRule(/^gh\\s+release\\b/, 'releasing', (_m, cmd) => ({ tool: 'gh', subcommand: cmd.split(/\\s+/)[2] ?? null })),\n makeRule(/^fly\\s+(deploy|launch)\\b/, 'releasing', (match) => ({ tool: 'fly', subcommand: match[1] })),\n makeRule(/^vercel\\s+(deploy|build|--prod)\\b/, 'releasing', () => ({ tool: 'vercel' })),\n makeRule(/^netlify\\s+deploy\\b/, 'releasing', () => ({ tool: 'netlify' })),\n makeRule(/^railway\\s+up\\b/, 'releasing', () => ({ tool: 'railway' })),\n makeRule(/^wrangler\\s+deploy\\b/, 'releasing', () => ({ tool: 'wrangler' })),\n\n // ─── Dependencies ─────────────────────────────────────────────────────────\n makeRule(/^npm\\s+(install|i|add)\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'npm',\n packages: extractPackages(cmd, cmd.includes('install') ? 'install' : cmd.includes(' i ') ? ' i ' : 'add'),\n })),\n\n makeRule(/^(yarn|pnpm)\\s+(install|add)\\b/, 'dependencies', (m, cmd) => ({\n tool: m[1],\n packages: extractPackages(cmd, 'add'),\n })),\n\n makeRule(/^bun\\s+(install|add)\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'bun',\n packages: extractPackages(cmd, 'add'),\n })),\n\n makeRule(/^pip\\s+(install)\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'pip',\n packages: extractPackages(cmd, 'install'),\n })),\n\n makeRule(/^cargo\\s+add\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'cargo',\n packages: extractPackages(cmd, 'add'),\n })),\n\n makeRule(/^(brew)\\s+install\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'brew',\n packages: extractPackages(cmd, 'install'),\n })),\n\n makeRule(/^go\\s+get\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'go',\n packages: extractPackages(cmd, 'get'),\n })),\n\n makeRule(/^npm\\s+(uninstall|remove|rm)\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'npm',\n packages: extractPackages(cmd, cmd.split(/\\s+/)[1]),\n })),\n\n makeRule(/^(yarn|pnpm)\\s+remove\\b/, 'dependencies', (m, cmd) => ({\n tool: m[1],\n packages: extractPackages(cmd, 'remove'),\n })),\n\n makeRule(/^bun\\s+remove\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'bun',\n packages: extractPackages(cmd, 'remove'),\n })),\n\n makeRule(/^pip\\s+uninstall\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'pip',\n packages: extractPackages(cmd, 'uninstall'),\n })),\n\n // Runtime version managers\n makeRule(/^nvm\\b/, 'dependencies', (_m, cmd) => ({ tool: 'nvm', subcommand: cmd.split(/\\s+/)[1] ?? null })),\n makeRule(/^(fnm|volta)\\b/, 'dependencies', (m, cmd) => ({ tool: m[1], subcommand: cmd.split(/\\s+/)[1] ?? null })),\n makeRule(/^(rbenv|pyenv|asdf)\\b/, 'dependencies', (m, cmd) => ({\n tool: m[1],\n subcommand: cmd.split(/\\s+/)[1] ?? null,\n })),\n\n // ─── Tests ────────────────────────────────────────────────────────────────\n makeRule(/^npm\\s+(test|run\\s+test)\\b/, 'testing', () => ({ tool: 'npm' })),\n makeRule(/^yarn\\s+test\\b/, 'testing', () => ({ tool: 'yarn' })),\n makeRule(/^pnpm\\s+test\\b/, 'testing', () => ({ tool: 'pnpm' })),\n makeRule(/^bun\\s+test\\b/, 'testing', () => ({ tool: 'bun' })),\n makeRule(/^(jest|vitest)\\b/, 'testing', (match) => ({ tool: match[1] })),\n makeRule(/^pytest\\b/, 'testing', () => ({ tool: 'pytest' })),\n makeRule(/^go\\s+test\\b/, 'testing', () => ({ tool: 'go' })),\n makeRule(/^cargo\\s+test\\b/, 'testing', () => ({ tool: 'cargo' })),\n makeRule(/^rspec\\b/, 'testing', () => ({ tool: 'rspec' })),\n makeRule(/^(php\\s+)?phpunit\\b/, 'testing', () => ({ tool: 'phpunit' })),\n\n // ─── Build ────────────────────────────────────────────────────────────────\n makeRule(/^npm\\s+run\\s+build\\b/, 'building', () => ({ tool: 'npm' })),\n makeRule(/^(yarn|pnpm)\\s+build\\b/, 'building', (match) => ({ tool: match[1] })),\n makeRule(/^bun\\s+run\\s+build\\b/, 'building', () => ({ tool: 'bun' })),\n makeRule(/^(make|gmake)\\b/, 'building', (match) => ({ tool: match[1] })),\n makeRule(/^cargo\\s+build\\b/, 'building', () => ({ tool: 'cargo' })),\n makeRule(/^go\\s+build\\b/, 'building', () => ({ tool: 'go' })),\n makeRule(/^docker\\s+build\\b/, 'building', () => ({ tool: 'docker' })),\n makeRule(/^(mvn|gradle)\\b/, 'building', (match) => ({ tool: match[1] })),\n\n // ─── Dev server / running ─────────────────────────────────────────────────\n makeRule(/^npm\\s+run\\s+(dev|start|serve)\\b/, 'running', (_m, cmd) => ({\n tool: 'npm',\n script: cmd.split(/\\s+/)[2],\n })),\n makeRule(/^(yarn|pnpm)\\s+(dev|start)\\b/, 'running', (match) => ({ tool: match[1], script: match[2] })),\n makeRule(/^bun\\s+run\\s+(dev|start|serve)\\b/, 'running', (_m, cmd) => ({\n tool: 'bun',\n script: cmd.split(/\\s+/)[2],\n })),\n makeRule(/^python\\s+.*manage\\.py\\s+runserver\\b/, 'running', () => ({ tool: 'django' })),\n\n // ─── Infrastructure ───────────────────────────────────────────────────────\n makeRule(/^ssh\\b/, 'infrastructure', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: 'ssh', target: parts[parts.length - 1] }\n }),\n\n makeRule(/^kubectl\\b/, 'infrastructure', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: 'kubectl', subcommand: parts[1] ?? null }\n }),\n\n makeRule(/^(helm|terraform|pulumi)\\b/, 'infrastructure', (m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: m[1], subcommand: parts[1] ?? null }\n }),\n\n makeRule(/^docker\\s+(run|compose|ps|stop|start|rm|exec)\\b/, 'infrastructure', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: 'docker', subcommand: parts[1] }\n }),\n\n makeRule(/^(aws|gcloud|az)\\b/, 'infrastructure', (m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: m[1], subcommand: parts[1] ?? null }\n }),\n\n // ─── Database ─────────────────────────────────────────────────────────────\n makeRule(/^(psql|pgcli)\\b/, 'database', (m) => ({ tool: m[1] })),\n makeRule(/^(mysql|mycli)\\b/, 'database', (m) => ({ tool: m[1] })),\n makeRule(/^sqlite3\\b/, 'database', () => ({ tool: 'sqlite3' })),\n makeRule(/^(mongosh|mongo)\\b/, 'database', (m) => ({ tool: m[1] })),\n makeRule(/^redis-cli\\b/, 'database', () => ({ tool: 'redis-cli' })),\n\n // ─── npx ─────────────────────────────────────────────────────────────────\n makeRule(/^npx\\s+(jest|vitest|mocha|ava|tap)\\b/, 'testing', (_m, cmd) => ({\n tool: cmd.split(/\\s+/)[1],\n })),\n makeRule(/^npx\\s+tsc\\b/, 'building', () => ({ tool: 'tsc' })),\n makeRule(/^npx\\s+(eslint|tslint|biome)\\b/, 'linting', (_m, cmd) => ({\n tool: cmd.split(/\\s+/)[1],\n })),\n makeRule(/^npx\\s+(prettier|dprint)\\b/, 'linting', (_m, cmd) => ({\n tool: cmd.split(/\\s+/)[1],\n })),\n makeRule(/^npx\\s+\\S+/, 'running', (_m, cmd) => ({\n tool: cmd.split(/\\s+/)[1],\n })),\n\n // ─── Scripts ──────────────────────────────────────────────────────────────\n makeRule(/^(bash|sh|zsh|fish)\\s+\\S+/, 'running', (match) => ({ shell: match[1] })),\n makeRule(/^node\\s+\\S+\\.(?:js|mjs|cjs)\\b/, 'running', () => ({ runtime: 'node' })),\n makeRule(/^python3?\\s+\\S+\\.py\\b/, 'running', () => ({ runtime: 'python' })),\n\n // ─── Linting / code quality ───────────────────────────────────────────────\n makeRule(/^(eslint|tslint|biome)\\b/, 'linting', (match) => ({ tool: match[1] })),\n makeRule(/^(prettier|dprint)\\b/, 'linting', (match) => ({ tool: match[1] })),\n\n // ─── generic run scripts ──────────────────────────────────────────────────\n makeRule(/^npm\\s+run\\s+\\S+/, 'running', (_m, cmd) => ({\n tool: 'npm',\n script: cmd.split(/\\s+/)[2],\n })),\n\n makeRule(/^bun\\s+run\\s+\\S+/, 'running', (_m, cmd) => ({\n tool: 'bun',\n script: cmd.split(/\\s+/)[2],\n })),\n\n // ─── Code search ─────────────────────────────────────────────────────────\n makeRule(/^(grep|egrep|fgrep)\\b/, 'exploring', (match) => ({ tool: match[1] })),\n makeRule(/^(rg|ag|ack|ripgrep)\\b/, 'exploring', (match) => ({ tool: match[1] })),\n makeRule(/^find\\s/, 'exploring', () => ({ tool: 'find' })),\n\n // ─── Code read ────────────────────────────────────────────────────────────\n makeRule(/^(cat|bat|less|more)\\s+\\S+/, 'exploring', (match) => ({ tool: match[1] })),\n makeRule(/^(head|tail)\\b/, 'exploring', (match) => ({ tool: match[1] })),\n\n // ─── File operations ──────────────────────────────────────────────────────\n makeRule(/^(cp|rsync)\\b/, 'files', (match) => ({ tool: match[1] })),\n makeRule(/^(mv)\\b/, 'files', () => ({ tool: 'mv' })),\n makeRule(/^(rm|rmdir)\\b/, 'files', (match) => ({ tool: match[1] })),\n makeRule(/^(mkdir|touch|ln)\\b/, 'files', (match) => ({ tool: match[1] })),\n makeRule(/^(chmod|chown|chgrp)\\b/, 'files', (match) => ({ tool: match[1] })),\n\n // ─── Environment ──────────────────────────────────────────────────────────\n makeRule(/^export\\s+\\w+=/, 'files', (_m, cmd) => {\n const varName = cmd.match(/^export\\s+(\\w+)=/)?.[1] ?? null\n return { variable: varName }\n }),\n makeRule(/^source\\s+/, 'files', () => ({})),\n]\n\nfunction aiToolRules(): Rule[] {\n return loadAIToolRegistry().flatMap((entry) => {\n try {\n return [makeRule(new RegExp(entry.pattern), 'ai_session', () => ({ tool: entry.tool }))]\n } catch {\n debugLog('registry', `Skipping tool \"${entry.tool}\" — invalid pattern: ${entry.pattern}`)\n return []\n }\n })\n}\n\nexport function buildRules(profileRules: Array<{ match(cmd: string): NormalizedEvent | null }> = []): Rule[] {\n return [...BASE_RULES, ...profileRules, ...aiToolRules()]\n}\n\nexport const RULES: Rule[] = buildRules(getActiveProfileRules())\n\nexport function normalizeCommand(command: string): NormalizedEvent {\n let trimmed = command.trim().replace(/\\s+/g, ' ')\n\n // Strip `git -C <path>` prefix so rules match regardless of working directory flag\n trimmed = trimmed.replace(/^(git)\\s+-C\\s+\\S+\\s+/, '$1 ')\n\n for (const rule of RULES) {\n const result = rule.match(trimmed)\n if (result) return result\n }\n\n return { category: 'other', metadata: {} }\n}\n","import type { EventRow } from '../db/types'\n\nfunction normalizeForFilter(cmd: string): string {\n return cmd.trim().replace(/\\s+/g, ' ')\n}\n\n// Always filtered regardless of user config — internal tool noise\nconst BUILTIN_IGNORE = new Set(['workscribe'])\n\n/**\n * Returns true if the command should be dropped (noise / ignore list).\n */\nexport function shouldFilter(command: string, ignoreList: string[]): boolean {\n const normalized = normalizeForFilter(command)\n if (!normalized) return true\n\n const baseCmd = normalized.split(' ')[0]\n\n // Built-in filter: always excluded, not user-configurable\n if (BUILTIN_IGNORE.has(baseCmd)) return true\n\n // User-configurable ignore list\n const normalizedIgnore = ignoreList.map(normalizeForFilter)\n if (normalizedIgnore.includes(normalized)) return true\n if (normalizedIgnore.includes(baseCmd)) return true\n\n return false\n}\n\n/**\n * Returns true if this command is a duplicate of the last event\n * (same command + same cwd within the dedup window).\n */\nexport function isDuplicate(\n command: string,\n cwd: string,\n lastEvent: Pick<EventRow, 'command' | 'cwd' | 'captured_at'> | undefined,\n dedupWindowMs = 5000,\n now = Date.now()\n): boolean {\n if (!lastEvent) return false\n const lastTime = new Date(lastEvent.captured_at).getTime()\n return lastEvent.command === normalizeForFilter(command) && lastEvent.cwd === cwd && now - lastTime < dedupWindowMs\n}\n","import { Command } from 'commander'\nimport { captureCommand } from '../capture'\nimport { debugLog } from '../utils/logger'\n\nexport function registerCapture(program: Command): void {\n // Internal command — called by the shell hook, not by the user\n program\n .command('_capture')\n .description('Internal: capture a shell command event (called by shell hook)')\n .option('--cmd <command>', 'command that was executed')\n .option('--cwd <path>', 'working directory')\n .option('--exit <code>', 'exit code', parseInt)\n .option('--duration <ms>', 'duration in milliseconds', parseInt)\n .option('--git-before <sha>', 'git HEAD SHA before this command ran')\n .action((opts) => {\n // Never surface errors to the terminal — this runs silently in the background\n try {\n if (!opts.cmd || !opts.cwd) return\n captureCommand({\n command: opts.cmd,\n cwd: opts.cwd,\n exitCode: opts.exit ?? null,\n durationMs: opts.duration ?? null,\n gitBefore: opts.gitBefore ?? undefined,\n })\n } catch (err) {\n debugLog('_capture', err)\n }\n })\n}\n","import { Command } from 'commander'\nimport { captureCommand } from '../capture'\nimport { readConfig } from '../config'\nimport { debugLog } from '../utils/logger'\n\n/** Parses a Claude Code PostToolUse stdin payload. Returns null if required fields are missing. */\nexport function parseHookPayload(raw: string): { command: string; cwd: string } | null {\n if (!raw.trim()) return null\n const payload = JSON.parse(raw) as Record<string, unknown>\n const toolInput = payload.tool_input as Record<string, unknown> | undefined\n const command = typeof toolInput?.command === 'string' ? toolInput.command : null\n const cwd = typeof payload.cwd === 'string' ? payload.cwd : null\n if (!command || !cwd) return null\n return { command, cwd }\n}\n\nexport function registerHook(program: Command): void {\n // Internal command — called by AI tool hooks (e.g. Claude Code PostToolUse), not by the user\n program\n .command('_hook')\n .description('Internal: capture events from AI tool hooks (stdin JSON payload)')\n .option('--source <source>', 'hook source identifier (e.g. claude-code)')\n .action((opts: { source?: string }) => {\n let raw = ''\n process.stdin.setEncoding('utf-8')\n process.stdin.on('data', (chunk: string) => {\n raw += chunk\n })\n process.stdin.on('end', () => {\n try {\n if (readConfig().capture.aiTools === false) return\n const parsed = parseHookPayload(raw)\n if (!parsed) return\n captureCommand({\n command: parsed.command,\n cwd: parsed.cwd,\n exitCode: null,\n durationMs: null,\n source: opts.source,\n })\n } catch (err) {\n debugLog('_hook', err)\n }\n })\n })\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport path from 'path'\nimport os from 'os'\nimport prompts from 'prompts'\nimport chalk from 'chalk'\nimport { WORKSCRIBE_DIR, CONFIG_PATH, PROFILES_DIR } from '../utils/paths'\nimport { readConfig, writeConfig } from '../config'\nimport { detectProfilesForDirectory } from '../profiles/loader'\nimport { installProfile, cacheManifest } from '../profiles/fetcher'\nimport { getDb } from '../db'\nimport { log } from '../utils/logger'\nimport { loadAIToolRegistry } from '../config/registry'\nimport { isHookInstalled, isHookOutdated, installHook, updateHook } from '../capture/shell-hook'\nimport { AI_HOOK_INTEGRATIONS } from '../capture/hooks'\n\nfunction detectShell(): { name: string; rcFile: string } | null {\n const shell = process.env.SHELL ?? ''\n if (shell.includes('zsh')) return { name: 'zsh', rcFile: path.join(os.homedir(), '.zshrc') }\n if (shell.includes('bash')) return { name: 'bash', rcFile: path.join(os.homedir(), '.bashrc') }\n return null\n}\n\nexport function registerInit(program: Command): void {\n program\n .command('init')\n .description('Set up Workscribe and install or update shell hooks')\n .action(async () => {\n log.plain(chalk.bold('\\n Workscribe — Developer Work Journal\\n'))\n\n // 1. Create ~/.workscribe/ and ~/.workscribe/profiles/ with owner-only permissions\n if (!fs.existsSync(WORKSCRIBE_DIR)) {\n fs.mkdirSync(WORKSCRIBE_DIR, { recursive: true, mode: 0o700 })\n log.success(`Created ${WORKSCRIBE_DIR}`)\n } else {\n try {\n fs.chmodSync(WORKSCRIBE_DIR, 0o700)\n } catch {\n /* ignore */\n }\n }\n if (!fs.existsSync(PROFILES_DIR)) {\n fs.mkdirSync(PROFILES_DIR, { recursive: true, mode: 0o700 })\n }\n\n // 2. Initialize database (runs migrations)\n getDb()\n log.success('Database initialized')\n\n // 3. Detect shell and install or update hook\n const shell = detectShell()\n if (!shell) {\n log.warn('Could not detect shell. Supported: zsh, bash')\n log.plain(`Manually add the hook from: ${chalk.cyan('shell/hook.zsh')} or ${chalk.cyan('shell/hook.bash')}`)\n } else {\n const hookFile = path.join(__dirname, '..', 'shell', `hook.${shell.name}`)\n if (!fs.existsSync(hookFile)) {\n log.warn(`Hook template not found at ${hookFile}`)\n } else {\n const hookContent = fs.readFileSync(hookFile, 'utf-8')\n if (!fs.existsSync(shell.rcFile)) fs.writeFileSync(shell.rcFile, '')\n\n if (!isHookInstalled(shell.rcFile)) {\n installHook(shell.rcFile, hookContent)\n log.success(`Shell hook installed in ${shell.rcFile}`)\n } else if (isHookOutdated(shell.rcFile, hookContent)) {\n const { update } = await prompts({\n type: 'confirm',\n name: 'update',\n message: `Shell hook in ${shell.rcFile} is outdated. Update?`,\n initial: true,\n })\n if (update) {\n updateHook(shell.rcFile, hookContent)\n log.success(`Shell hook updated in ${shell.rcFile}`)\n } else {\n log.info('Shell hook update skipped')\n }\n } else {\n log.info(`Shell hook up to date in ${shell.rcFile}`)\n }\n }\n }\n\n // 4. AI tool hook integrations (registry-driven — add new tools in src/capture/hooks/)\n const installedTools = loadAIToolRegistry().filter(\n (entry) => entry.hook !== null && AI_HOOK_INTEGRATIONS[entry.hook!]?.isInstalled()\n )\n\n if (installedTools.length === 0) {\n log.info('No AI coding tools detected — re-run workscribe init after installing one')\n } else {\n for (const tool of installedTools) {\n const integration = AI_HOOK_INTEGRATIONS[tool.hook!]!\n\n if (integration.isHookInstalled()) {\n log.info(`${integration.displayName} session hook already installed`)\n } else {\n const { install } = await prompts({\n type: 'confirm',\n name: 'install',\n message: `${integration.displayName} detected. Install session capture hook?`,\n initial: false,\n })\n if (install) {\n integration.install()\n log.success(`${integration.displayName} session hook installed`)\n } else {\n log.info(`${integration.displayName} hook skipped — re-run workscribe init to install later`)\n }\n }\n }\n }\n\n // 5. Profile detection\n const config = readConfig()\n try {\n await cacheManifest()\n const detected = detectProfilesForDirectory(process.cwd())\n const alreadyActive = new Set(config.capture.profiles)\n const toPrompt = detected.filter((entry) => !alreadyActive.has(entry.name))\n\n if (toPrompt.length > 0) {\n log.plain('')\n for (const entry of toPrompt) {\n const { install } = await prompts({\n type: 'confirm',\n name: 'install',\n message: `${entry.displayName} project detected. Enable the ${entry.displayName} profile?`,\n initial: true,\n })\n if (install) {\n await installProfile(entry.name)\n config.capture.profiles = [...new Set([...config.capture.profiles, entry.name])]\n log.success(`${entry.displayName} profile enabled`)\n }\n }\n writeConfig(config)\n } else if (detected.length === 0) {\n log.info('No project profiles detected — run workscribe profile detect from your project directory')\n }\n } catch {\n log.info('Could not reach profile registry — run workscribe profile detect after connecting')\n }\n\n // 6. AI provider setup\n\n if (config.ai.provider) {\n log.info(`AI provider already configured: ${chalk.cyan(config.ai.provider)}`)\n } else {\n log.plain('')\n const { provider } = await prompts({\n type: 'select',\n name: 'provider',\n message: 'Which AI provider do you want to use?',\n choices: [\n { title: 'Anthropic (Claude) — requires API key', value: 'anthropic' },\n { title: 'OpenAI — requires API key', value: 'openai' },\n { title: 'Ollama (local) — free, runs on your machine', value: 'ollama' },\n { title: 'Other (OpenAI-compatible) — Groq, Together, Mistral…', value: 'openai-compatible' },\n { title: 'Skip — configure later', value: 'skip' },\n ],\n })\n\n if (provider && provider !== 'skip') {\n config.ai.provider = provider\n\n if (provider === 'ollama') {\n log.plain(`\\n ${chalk.dim('Make sure Ollama is running: ollama serve')}`)\n log.plain(\n ` ${chalk.dim('Default model: llama3 (change with: workscribe config set ai.model <model>)')}\\n`\n )\n } else {\n const { apiKey } = await prompts({\n type: 'password',\n name: 'apiKey',\n message: `Enter your ${provider === 'openai-compatible' ? '' : provider + ' '}API key:`,\n })\n if (apiKey) config.ai.apiKey = apiKey\n\n if (provider === 'openai-compatible') {\n const { baseUrl } = await prompts({\n type: 'text',\n name: 'baseUrl',\n message: 'Enter the base URL (e.g. https://api.groq.com/openai/v1):',\n })\n if (baseUrl) config.ai.baseUrl = baseUrl\n }\n }\n\n writeConfig(config)\n log.success(`AI provider set to ${chalk.cyan(provider)}`)\n } else if (provider === 'skip' || !provider) {\n log.info('Skipped — run later: workscribe config set ai.provider <provider>')\n }\n }\n\n // 7. Write config if not exists\n if (!fs.existsSync(CONFIG_PATH)) {\n writeConfig(config)\n log.success('Config file created')\n }\n\n log.plain('')\n log.plain(chalk.bold(' Setup complete!'))\n if (shell) {\n log.plain('')\n log.plain(` Activate capture now: ${chalk.cyan(`source ${shell.rcFile}`)}`)\n log.plain(` Or restart your terminal.`)\n }\n log.plain('')\n log.plain(` ${chalk.dim('workscribe summary')} — generate today\\'s work summary`)\n log.plain(` ${chalk.dim('workscribe status')} — check capture is working`)\n log.plain('')\n })\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { log } from '../utils/logger'\n\nconst HOOK_START = '# workscribe:hook:start'\nconst HOOK_END = '# workscribe:hook:end'\nconst HOOK_PREAMBLE = '# Workscribe — developer work journal'\n\nexport function getInstalledHookBlock(rcFile: string): string | null {\n if (!fs.existsSync(rcFile)) return null\n const content = fs.readFileSync(rcFile, 'utf-8')\n const startIdx = content.indexOf(HOOK_START)\n const endIdx = content.indexOf(HOOK_END)\n if (startIdx === -1 || endIdx === -1) return null\n return content.slice(startIdx, endIdx + HOOK_END.length)\n}\n\nexport function isHookInstalled(rcFile: string): boolean {\n return getInstalledHookBlock(rcFile) !== null\n}\n\nexport function isHookOutdated(rcFile: string, hookContent: string): boolean {\n const installed = getInstalledHookBlock(rcFile)\n if (!installed) return false\n return installed.trim() !== hookContent.trim()\n}\n\nexport function installHook(rcFile: string, hookContent: string): void {\n const backup = `${rcFile}.workscribe-backup-${Date.now()}`\n fs.copyFileSync(rcFile, backup)\n log.info(`Backed up ${rcFile} → ${path.basename(backup)}`)\n fs.appendFileSync(rcFile, `\\n${hookContent}\\n`)\n}\n\nexport function updateHook(rcFile: string, hookContent: string): void {\n const backup = `${rcFile}.workscribe-backup-${Date.now()}`\n fs.copyFileSync(rcFile, backup)\n log.info(`Backed up ${rcFile} → ${path.basename(backup)}`)\n const content = fs.readFileSync(rcFile, 'utf-8')\n const startIdx = content.indexOf(HOOK_START)\n const endIdx = content.indexOf(HOOK_END) + HOOK_END.length\n fs.writeFileSync(rcFile, content.slice(0, startIdx) + hookContent + content.slice(endIdx))\n}\n\nexport function removeHook(rcFile: string): void {\n const backup = `${rcFile}.workscribe-backup-${Date.now()}`\n fs.copyFileSync(rcFile, backup)\n log.info(`Backed up ${rcFile} → ${path.basename(backup)}`)\n const content = fs.readFileSync(rcFile, 'utf-8')\n const startIdx = content.indexOf(HOOK_START)\n const endIdx = content.indexOf(HOOK_END) + HOOK_END.length\n // Also remove the preamble comment lines that installHook writes before HOOK_START\n const preambleIdx = content.lastIndexOf(HOOK_PREAMBLE, startIdx)\n const blockStart = preambleIdx !== -1 ? preambleIdx : startIdx\n const before = content.slice(0, blockStart).replace(/\\n+$/, '\\n')\n const after = content.slice(endIdx).replace(/^\\n/, '')\n fs.writeFileSync(rcFile, before + after)\n}\n","import fs from 'fs'\nimport path from 'path'\nimport os from 'os'\nimport type { AIHookIntegration } from './types'\nimport { isCommandInstalled } from './utils'\n\nconst CLAUDE_SETTINGS_PATH = path.join(os.homedir(), '.claude', 'settings.json')\n\nfunction readSettings(): Record<string, unknown> {\n if (!fs.existsSync(CLAUDE_SETTINGS_PATH)) return {}\n try {\n return JSON.parse(fs.readFileSync(CLAUDE_SETTINGS_PATH, 'utf-8')) as Record<string, unknown>\n } catch {\n return {}\n }\n}\n\nexport const claudeCodeIntegration: AIHookIntegration = {\n displayName: 'Claude Code',\n\n isInstalled() {\n return isCommandInstalled('claude')\n },\n\n isHookInstalled() {\n const settings = readSettings()\n const postToolUse = ((settings.hooks as Record<string, unknown>)?.PostToolUse ?? []) as unknown[]\n return postToolUse.some((entry) => {\n const hooks = ((entry as Record<string, unknown>).hooks ?? []) as unknown[]\n return hooks.some((hookItem) => {\n const hook = hookItem as Record<string, unknown>\n return typeof hook.command === 'string' && hook.command.includes('workscribe _hook')\n })\n })\n },\n\n install() {\n const settings = readSettings()\n const existingHooks = (settings.hooks ?? {}) as Record<string, unknown>\n const existingPostToolUse = (existingHooks.PostToolUse ?? []) as unknown[]\n settings.hooks = {\n ...existingHooks,\n PostToolUse: [\n ...existingPostToolUse,\n {\n matcher: 'Bash',\n hooks: [{ type: 'command', command: 'workscribe _hook --source claude-code', async: true }],\n },\n ],\n }\n fs.mkdirSync(path.dirname(CLAUDE_SETTINGS_PATH), { recursive: true })\n fs.writeFileSync(CLAUDE_SETTINGS_PATH, JSON.stringify(settings, null, 2))\n },\n}\n","import { execSync } from 'child_process'\n\n/** Returns true if the given CLI command is available on PATH */\nexport function isCommandInstalled(cmd: string): boolean {\n try {\n execSync(`which ${cmd}`, { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n","import type { AIHookIntegration } from './types'\nimport { claudeCodeIntegration } from './claude-code'\n\n/**\n * Registry of AI tool hook integrations, keyed by the \"hook\" field in src/config/ai-tools.json.\n * Adding support for a new tool = add a new entry here and a corresponding integration file.\n */\nexport const AI_HOOK_INTEGRATIONS: Record<string, AIHookIntegration> = {\n 'claude-code': claudeCodeIntegration,\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport chalk from 'chalk'\nimport { getEventCount, getLastEvent, getRecentOtherRate } from '../db'\nimport { readConfig } from '../config'\nimport { log } from '../utils/logger'\nimport { formatDate, todayDate } from '../utils/format'\nimport { getEventsForDate } from '../db'\nimport { PAUSE_FLAG_PATH } from '../utils/paths'\n\nexport function registerStatus(program: Command): void {\n program\n .command('status')\n .description('Show capture status and event counts')\n .action(() => {\n const config = readConfig()\n const total = getEventCount()\n const todayEvents = getEventsForDate(todayDate())\n const last = getLastEvent()\n const isPaused = fs.existsSync(PAUSE_FLAG_PATH)\n\n log.plain('')\n log.plain(chalk.bold(' Workscribe Status'))\n log.plain('')\n\n if (isPaused) {\n log.plain(` Capture ${chalk.yellow('paused')} ${chalk.dim('(run: workscribe resume)')}`)\n } else {\n log.plain(` Capture ${chalk.green('active')}`)\n }\n\n log.plain(` Events today ${chalk.cyan(String(todayEvents.length))}`)\n log.plain(` Events total ${chalk.cyan(String(total))}`)\n\n if (last) {\n log.plain(` Last event ${formatDate(last.captured_at)} ${chalk.dim(last.command.slice(0, 60))}`)\n }\n\n log.plain('')\n log.plain(\n ` AI provider ${config.ai.provider ? chalk.cyan(config.ai.provider) : chalk.yellow('not configured')}`\n )\n if (config.ai.model) log.plain(` Model ${chalk.dim(config.ai.model)}`)\n\n const activeProfiles = config.capture.profiles\n log.plain(\n ` Profiles ${activeProfiles.length > 0 ? chalk.cyan(activeProfiles.join(', ')) : chalk.dim('none')}`\n )\n\n const { total: weekTotal, otherCount } = getRecentOtherRate(7)\n if (weekTotal > 0) {\n const otherPct = Math.round((otherCount / weekTotal) * 100)\n if (otherPct >= 25) {\n log.plain('')\n log.plain(\n ` ${chalk.yellow('⚠')} ${otherCount} of ${weekTotal} events (${otherPct}%) are uncategorised this week.`\n )\n log.plain(\n chalk.dim(\n ' Run workscribe profile detect — scan current directory for matching profiles\\n' +\n ' Run workscribe profile suggest — analyse your command history'\n )\n )\n }\n }\n\n log.plain('')\n })\n}\n","export function formatDuration(minutes: number): string {\n if (minutes < 60) return `${Math.round(minutes)}m`\n const h = Math.floor(minutes / 60)\n const m = Math.round(minutes % 60)\n return m > 0 ? `${h}h ${m}m` : `${h}h`\n}\n\nexport function formatDate(isoString: string): string {\n return new Date(isoString).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })\n}\n\nexport function todayDate(): string {\n return localDateStr(new Date())\n}\n\nexport function parseDate(input: string): string {\n // Accepts YYYY-MM-DD, returns YYYY-MM-DD. Throws on invalid.\n const d = new Date(input + 'T00:00:00')\n if (isNaN(d.getTime())) throw new Error(`Invalid date: ${input}`)\n return input\n}\n\nfunction localDateStr(d: Date): string {\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, '0')\n const day = String(d.getDate()).padStart(2, '0')\n return `${y}-${m}-${day}`\n}\n\n// Returns Monday of the ISO week containing dateStr (YYYY-MM-DD)\nexport function startOfWeek(dateStr: string): string {\n const d = new Date(dateStr + 'T00:00:00')\n const day = d.getDay() // 0=Sun\n const diff = day === 0 ? -6 : 1 - day\n d.setDate(d.getDate() + diff)\n return localDateStr(d)\n}\n\n// Returns all YYYY-MM-DD strings from start to end inclusive\nexport function eachDayOfRange(start: string, end: string): string[] {\n const days: string[] = []\n const cur = new Date(start + 'T00:00:00')\n const last = new Date(end + 'T00:00:00')\n while (cur <= last) {\n days.push(localDateStr(cur))\n cur.setDate(cur.getDate() + 1)\n }\n return days\n}\n\n// Returns ISO week string YYYY-WW for a date\nexport function isoWeekKey(dateStr: string): string {\n const d = new Date(dateStr + 'T00:00:00')\n const jan4 = new Date(d.getFullYear(), 0, 4)\n const weekNum = Math.ceil(((d.getTime() - jan4.getTime()) / 86400000 + jan4.getDay() + 1) / 7)\n return `${d.getFullYear()}-W${String(weekNum).padStart(2, '0')}`\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport { getEventsForDate } from '../db'\nimport { log } from '../utils/logger'\nimport { todayDate, parseDate, formatDate } from '../utils/format'\nimport { loadAIToolRegistry } from '../config/registry'\n\nconst CATEGORY_COLORS: Record<string, (s: string) => string> = {\n shipping: chalk.green,\n versioning: chalk.blue,\n building: chalk.cyan,\n running: chalk.white,\n testing: chalk.magenta,\n linting: chalk.yellow,\n dependencies: chalk.yellow,\n infrastructure: chalk.red,\n releasing: chalk.bold.green,\n database: chalk.bold.blue,\n files: chalk.dim.yellow,\n exploring: chalk.dim.cyan,\n ai_session: chalk.bold.magenta,\n other: chalk.gray,\n}\n\nconst AI_TOOL_DISPLAY_NAMES: Record<string, string> = Object.fromEntries(\n loadAIToolRegistry().map((entry) => [entry.tool, entry.displayName])\n)\n\nexport function registerEvents(program: Command): void {\n program\n .command('events')\n .description('List captured events')\n .option('--date <YYYY-MM-DD>', 'date to list events for (default: today)')\n .option('--limit <n>', 'max events to show', parseInt)\n .action((opts) => {\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n }\n\n const events = getEventsForDate(date)\n const limit = opts.limit ?? events.length\n\n if (events.length === 0) {\n log.plain(`No events captured for ${date}`)\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(` Events for ${date} (${events.length} total)`))\n log.plain('')\n\n for (const event of events.slice(0, limit)) {\n const colorFn = CATEGORY_COLORS[event.category] ?? chalk.gray\n const time = formatDate(event.captured_at)\n const category = colorFn(event.category.padEnd(20))\n const repo = event.repo_name ? chalk.dim(` [${event.repo_name}]`) : ''\n const exitBadge = event.exit_code && event.exit_code !== 0 ? chalk.red(` ✗${event.exit_code}`) : ''\n\n let cmdDisplay: string\n if (event.category === 'ai_session') {\n let meta: Record<string, unknown> = {}\n try {\n meta = event.metadata ? (JSON.parse(event.metadata) as Record<string, unknown>) : {}\n } catch {\n /* ignore */\n }\n const toolKey = typeof meta.tool === 'string' ? meta.tool : ''\n const toolName = AI_TOOL_DISPLAY_NAMES[toolKey] ?? toolKey\n cmdDisplay = chalk.white(toolName.padEnd(20)) + chalk.magenta(' ✦')\n } else {\n cmdDisplay = chalk.dim(event.command.slice(0, 55))\n }\n\n log.plain(` ${chalk.dim(time)} ${category} ${cmdDisplay}${repo}${exitBadge}`)\n }\n\n if (limit < events.length) {\n log.plain('')\n log.plain(chalk.dim(` … and ${events.length - limit} more (remove --limit to see all)`))\n }\n\n log.plain('')\n })\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport { getOrBuildSessions } from '../sessions/detector'\nimport { log } from '../utils/logger'\nimport { todayDate, parseDate, formatDate, formatDuration } from '../utils/format'\n\nexport function registerSessions(program: Command): void {\n program\n .command('sessions')\n .description('List detected work sessions')\n .option('--date <YYYY-MM-DD>', 'date to show sessions for (default: today)')\n .action((opts) => {\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n }\n\n const sessions = getOrBuildSessions(date)\n\n if (sessions.length === 0) {\n log.plain(`No sessions detected for ${date}`)\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(` Sessions for ${date} (${sessions.length} session${sessions.length > 1 ? 's' : ''})`))\n log.plain('')\n\n for (const session of sessions) {\n const start = formatDate(session.startedAt)\n const end = formatDate(session.endedAt)\n const duration = formatDuration(session.durationMinutes)\n const repo = session.repoName ? chalk.cyan(session.repoName) : chalk.gray('no repo')\n log.plain(\n ` ${chalk.dim(start)} – ${chalk.dim(end)} ${repo} ${chalk.dim(duration)} ${chalk.dim(session.eventCount + ' events')}`\n )\n }\n\n log.plain('')\n })\n}\n","import type { EventRow } from '../db/types'\n\n/**\n * Split a sorted list of events into groups separated by idle gaps.\n */\nexport function splitByIdleGap(events: EventRow[], idleMs: number): EventRow[][] {\n if (events.length === 0) return []\n const groups: EventRow[][] = [[events[0]]]\n\n for (let i = 1; i < events.length; i++) {\n const prev = new Date(events[i - 1].captured_at).getTime()\n const curr = new Date(events[i].captured_at).getTime()\n if (curr - prev >= idleMs) {\n groups.push([events[i]])\n } else {\n groups[groups.length - 1].push(events[i])\n }\n }\n\n return groups\n}\n\n/**\n * Split a list of events into groups by consecutive repo_name.\n * A repo change mid-stream creates a new group.\n */\nexport function splitByRepo(events: EventRow[]): EventRow[][] {\n if (events.length === 0) return []\n const groups: EventRow[][] = [[events[0]]]\n\n for (let i = 1; i < events.length; i++) {\n const prevRepo = events[i - 1].repo_name\n const currRepo = events[i].repo_name\n if (currRepo !== prevRepo) {\n groups.push([events[i]])\n } else {\n groups[groups.length - 1].push(events[i])\n }\n }\n\n return groups\n}\n\nexport function minutesBetween(start: string, end: string): number {\n return (new Date(end).getTime() - new Date(start).getTime()) / 60000\n}\n","import type { EventRow } from '../db/types'\nimport {\n insertSession,\n insertSessionEvent,\n clearSessionsForDate,\n getSessionsForDate,\n getEventsForDate,\n getEventsBySessionId,\n} from '../db'\nimport { readConfig } from '../config'\nimport { splitByIdleGap, splitByRepo, minutesBetween } from './grouper'\n\nexport interface Session {\n id: number\n date: string\n startedAt: string\n endedAt: string\n repoName: string | null\n durationMinutes: number\n eventCount: number\n summary: string | null\n events: EventRow[]\n}\n\nexport function getOrBuildSessions(date: string): Session[] {\n // Check if sessions already exist for this date\n const existing = getSessionsForDate(date)\n const events = getEventsForDate(date)\n\n if (events.length === 0) return []\n\n // If sessions exist and event count matches, use cached\n const cachedEventCount = existing.reduce((sum, sessionRow) => sum + sessionRow.event_count, 0)\n if (existing.length > 0 && cachedEventCount === events.length) {\n return existing.map((sessionRow) => ({\n id: sessionRow.id,\n date: sessionRow.date,\n startedAt: sessionRow.started_at,\n endedAt: sessionRow.ended_at,\n repoName: sessionRow.repo_name,\n durationMinutes: minutesBetween(sessionRow.started_at, sessionRow.ended_at),\n eventCount: sessionRow.event_count,\n summary: sessionRow.summary,\n events: getEventsBySessionId(sessionRow.id),\n }))\n }\n\n // Preserve any cached summaries before clearing — keyed by repo+start time\n // so they can be restored to matching sessions after rebuild\n const savedSummaries = new Map<string, string>()\n for (const s of existing) {\n if (s.summary) savedSummaries.set(`${s.repo_name}|${s.started_at}`, s.summary)\n }\n\n // Rebuild sessions\n clearSessionsForDate(date)\n return buildSessions(date, events, savedSummaries)\n}\n\nfunction buildSessions(date: string, events: EventRow[], savedSummaries: Map<string, string> = new Map()): Session[] {\n const config = readConfig()\n const idleMs = config.session.idleTimeout * 60 * 1000\n\n const sessions: Session[] = []\n const timeGroups = splitByIdleGap(events, idleMs)\n\n for (const group of timeGroups) {\n if (group.length === 0) continue\n\n const repoGroups = splitByRepo(group)\n\n for (const repoGroup of repoGroups) {\n if (repoGroup.length === 0) continue\n\n const first = repoGroup[0]\n const last = repoGroup[repoGroup.length - 1]\n const repoName = last.repo_name ?? first.repo_name ?? null\n\n // Restore a previously generated summary if the session boundaries match\n const summary = savedSummaries.get(`${repoName}|${first.captured_at}`) ?? null\n\n const sessionId = insertSession({\n date,\n started_at: first.captured_at,\n ended_at: last.captured_at,\n repo_name: repoName,\n event_count: repoGroup.length,\n summary,\n })\n\n for (const event of repoGroup) {\n insertSessionEvent(sessionId, event.id)\n }\n\n sessions.push({\n id: sessionId,\n date,\n startedAt: first.captured_at,\n endedAt: last.captured_at,\n repoName,\n durationMinutes: minutesBetween(first.captured_at, last.captured_at),\n eventCount: repoGroup.length,\n summary,\n events: repoGroup,\n })\n }\n }\n\n return sessions\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { getOrBuildSessions } from '../sessions/detector'\nimport { getProvider } from '../ai/router'\nimport { readConfig } from '../config'\nimport { updateSessionSummary } from '../db'\nimport { log } from '../utils/logger'\nimport {\n todayDate,\n parseDate,\n formatDate,\n formatDuration,\n startOfWeek,\n eachDayOfRange,\n isoWeekKey,\n} from '../utils/format'\nimport { postToWebhook } from '../integrations/webhook'\nimport { formatForSlack, isSlackWebhookUrl } from '../integrations/slack'\nimport { WEEKLY_CACHE_DIR } from '../utils/paths'\nimport type { DaySummaryPayload, SessionPayload, EventPayload, WeekSummaryPayload } from '../ai/types'\nimport type { EventRow } from '../db'\n\ninterface SessionSummaryJson {\n project: string | null\n branch: string | null\n durationMinutes: number\n bullets: string[]\n}\n\n/** Parse AI bullet output into a clean string array. Handles both - and • prefixes. */\nexport function parseBullets(text: string): string[] {\n return text\n .split('\\n')\n .map((line) => line.replace(/^[•\\-]\\s*/, '').trim())\n .filter(Boolean)\n}\n\nfunction eventRowToPayload(row: EventRow): EventPayload {\n let metadata: Record<string, unknown> = {}\n try {\n if (row.metadata) metadata = JSON.parse(row.metadata)\n } catch {\n /* ignore */\n }\n const payload: EventPayload = {\n category: row.category,\n metadata,\n exitCode: row.exit_code,\n durationMs: row.duration_ms,\n }\n if (row.category === 'other' && typeof metadata.hint === 'string') {\n payload.hint = metadata.hint\n const { hint: _h, tool: _t, ...rest } = metadata\n payload.metadata = rest\n }\n return payload\n}\n\nfunction sessionToPayload(s: ReturnType<typeof getOrBuildSessions>[number], date: string): SessionPayload {\n return {\n date,\n project: s.repoName,\n branch: s.events[0]?.branch ?? null,\n startTime: formatDate(s.startedAt),\n endTime: formatDate(s.endedAt),\n durationMinutes: s.durationMinutes,\n events: s.events.map(eventRowToPayload),\n }\n}\n\nasync function handleWebhook(\n opts: { slack?: boolean; webhook?: string },\n config: ReturnType<typeof readConfig>,\n summary: string\n): Promise<void> {\n const webhookUrl = opts.webhook ?? (opts.slack ? config.integrations?.slackWebhook : undefined)\n\n if (webhookUrl) {\n try {\n log.info('Posting to webhook…')\n const username = os.userInfo().username\n const body = isSlackWebhookUrl(webhookUrl) ? formatForSlack(summary, username) : summary\n await postToWebhook(webhookUrl, body)\n log.success('Posted.')\n } catch (e) {\n log.error(`Webhook failed: ${(e as Error).message}`)\n }\n } else if (opts.slack && !config.integrations?.slackWebhook) {\n log.warn('--slack requires integrations.slackWebhook to be set in config')\n }\n}\n\nexport function registerSummary(program: Command): void {\n program\n .command('summary')\n .description('Generate an AI work summary')\n .option('--date <YYYY-MM-DD>', 'date to summarize (default: today)')\n .option('--week', 'summarize the current week')\n .option('--fresh', 'bypass cache and regenerate')\n .option('--slack', 'post summary to Slack webhook from config')\n .option('--webhook <url>', 'post summary to a custom webhook URL')\n .action(async (opts) => {\n const config = readConfig()\n let provider\n try {\n provider = getProvider(config)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n\n // ── Weekly branch ────────────────────────────────────────────────────────\n if (opts.week) {\n const today = todayDate()\n const weekStart = startOfWeek(today)\n const days = eachDayOfRange(weekStart, today)\n\n const weeklyDays: WeekSummaryPayload['days'] = []\n for (const day of days) {\n const sessions = getOrBuildSessions(day)\n if (sessions.length > 0) {\n weeklyDays.push({ date: day, sessions: sessions.map((session) => sessionToPayload(session, day)) })\n }\n }\n\n if (weeklyDays.length === 0) {\n log.plain('No activity captured this week.')\n return\n }\n\n const cacheKey = isoWeekKey(today)\n const cacheFile = path.join(WEEKLY_CACHE_DIR, `${cacheKey}.md`)\n\n if (!opts.fresh && fs.existsSync(cacheFile)) {\n const cached = fs.readFileSync(cacheFile, 'utf-8')\n log.plain('')\n log.plain(cached)\n log.plain('')\n log.plain(chalk.dim(' (cached — use --fresh to regenerate)'))\n await handleWebhook(opts, config, cached)\n return\n }\n\n const payload: WeekSummaryPayload = { weekStart, weekEnd: today, days: weeklyDays }\n\n log.plain('')\n log.info(`Generating weekly summary via ${chalk.cyan(config.ai.provider)}…`)\n\n try {\n const summary = provider.summarizeWeek\n ? await provider.summarizeWeek(payload)\n : await provider.summarize({ date: today, sessions: weeklyDays.flatMap((day) => day.sessions) })\n\n log.plain('')\n log.plain(summary)\n log.plain('')\n\n fs.mkdirSync(WEEKLY_CACHE_DIR, { recursive: true })\n fs.writeFileSync(cacheFile, summary, { encoding: 'utf-8', mode: 0o600 })\n\n await handleWebhook(opts, config, summary)\n } catch (e) {\n log.error(`Weekly summary failed [${config.ai.provider}]: ${(e as Error).message}`)\n process.exit(1)\n }\n return\n }\n\n // ── Daily branch ─────────────────────────────────────────────────────────\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n }\n\n const sessions = getOrBuildSessions(date)\n\n if (sessions.length === 0) {\n log.plain(`No activity captured for ${date}`)\n return\n }\n\n const jsonMode = config.summary?.format === 'json'\n\n if (!opts.fresh) {\n const allCached = sessions.every((session) => session.summary)\n if (allCached) {\n const fullSummary = sessions.map((session) => session.summary!).join('\\n\\n')\n log.plain('')\n if (jsonMode) {\n const jsonOut: SessionSummaryJson[] = sessions.map((session) => ({\n project: session.repoName,\n branch: session.events[0]?.branch ?? null,\n durationMinutes: session.durationMinutes,\n bullets: parseBullets(session.summary!.replace(/^## .+\\n/, '')),\n }))\n log.plain(JSON.stringify({ date, sessions: jsonOut }, null, 2))\n } else {\n log.plain(fullSummary)\n }\n log.plain('')\n log.plain(chalk.dim(' (cached — use --fresh to regenerate)'))\n await handleWebhook(opts, config, fullSummary)\n return\n }\n }\n\n log.plain('')\n log.info(`Generating summary via ${chalk.cyan(config.ai.provider)}…`)\n\n const allSummaries: string[] = []\n const jsonSessions: SessionSummaryJson[] = []\n\n for (const session of sessions) {\n const sessionPayload: DaySummaryPayload = { date, sessions: [sessionToPayload(session, date)] }\n try {\n const bullets = await provider.summarize(sessionPayload)\n const project = session.repoName ?? 'unknown'\n const branch = session.events[0]?.branch ? ` (${session.events[0].branch})` : ''\n const duration = formatDuration(session.durationMinutes)\n const heading = `## ${project}${branch} — ${duration}`\n const summary = `${heading}\\n${bullets.trim()}`\n allSummaries.push(summary)\n updateSessionSummary(session.id, summary)\n if (jsonMode) {\n jsonSessions.push({\n project: session.repoName,\n branch: session.events[0]?.branch ?? null,\n durationMinutes: session.durationMinutes,\n bullets: parseBullets(bullets),\n })\n }\n } catch (e) {\n log.error(`Summary failed [${config.ai.provider}]: ${(e as Error).message}`)\n process.exit(1)\n }\n }\n\n const fullSummary = allSummaries.join('\\n\\n')\n log.plain('')\n if (jsonMode) {\n log.plain(JSON.stringify({ date, sessions: jsonSessions }, null, 2))\n } else {\n log.plain(fullSummary)\n }\n log.plain('')\n\n await handleWebhook(opts, config, fullSummary)\n })\n}\n","import type { DaySummaryPayload, WeekSummaryPayload } from './types'\nimport { formatDuration } from '../utils/format'\nimport { getActiveProfileAiContexts } from '../profiles/loader'\n\nexport const SYSTEM_PROMPT = `You write short developer work summaries. Here is an example:\n\nINPUT:\nProject: api-service\nBranch: feature/auth\nDuration: 2h 00m\nEvents:\n - versioning {\"branch\":\"feature/auth\"}\n - 2x dependencies {\"tool\":\"npm\",\"packages\":[\"bcrypt\",\"jsonwebtoken\"]}\n - 2x testing {\"tool\":\"jest\"} [failed]\n - testing {\"tool\":\"jest\"}\n - 2x files {\"tool\":\"mkdir\"}\n - shipping {\"message\":\"fix: auth token validation\"}\n - shipping {\"remote\":\"origin\",\"branch\":\"feature/auth\"}\n\nOUTPUT:\n- Switched to the authentication feature branch and added authentication dependencies (bcrypt, JWT)\n- Resolved failing auth tests\n- Committed and pushed authentication fixes\n\nFor dependencies events with a packages field: infer the purpose of packages from their names and describe the domain, not just the packages. Examples: bcrypt/jsonwebtoken → authentication, prisma/mongoose/pg → database, jest/vitest/mocha → testing, axios/got/node-fetch → HTTP client, stripe/paypal → payments, socket.io/ws → real-time. Use your knowledge of common packages. For unfamiliar packages, name them directly without guessing their domain.\n\nEvents like shipping (pushes), building, versioning (branch switches, stash), files (file ops, env vars), and infrastructure provide context — fold them into the surrounding narrative rather than listing them as separate bullets. Only surface them directly when they are the main activity (e.g. a standalone build fix, a deploy, or a significant restructure with no accompanying commits).\n\nFor ai_session events: describe what was built during the AI session using the tool name (e.g. \"via Claude Code\"). If a commits array is present in metadata, use those commit messages to describe what was built. Group all activity from the session into one narrative bullet.\n\nFor other events with a hint field: interpret the command snippet and describe the activity in plain language. Do not quote the raw command.\n\nMaximum 5 bullets. Output ONLY the bullet points, nothing else.`\n\nexport function getSystemPrompt(): string {\n const contexts = getActiveProfileAiContexts()\n if (contexts.length === 0) return SYSTEM_PROMPT\n return SYSTEM_PROMPT + '\\n\\n' + contexts.join('\\n')\n}\n\n// exploring (grep/find/cat) is excluded — read-only investigation adds no signal to work summaries\nconst EXCLUDED = new Set(['exploring'])\n\nexport function buildUserMessage(payload: DaySummaryPayload): string {\n const lines: string[] = [`Date: ${payload.date}`, '']\n\n for (const session of payload.sessions) {\n lines.push(`Project: ${session.project ?? 'unknown'}`)\n if (session.branch) lines.push(`Branch: ${session.branch}`)\n lines.push(`Duration: ${formatDuration(session.durationMinutes)}`)\n lines.push('Events:')\n\n // Aggregate repeated events so the model sees \"3x build\" not 3 separate build lines\n const counts = new Map<string, number>()\n for (const event of session.events) {\n if (EXCLUDED.has(event.category)) continue\n const failed = event.exitCode !== null && event.exitCode !== 0 ? ' [failed]' : ''\n let key: string\n if (event.hint) {\n key = `other [${event.hint}]${failed}`\n } else {\n const meta = Object.keys(event.metadata).length > 0 ? ` ${JSON.stringify(event.metadata)}` : ''\n key = `${event.category}${meta}${failed}`\n }\n counts.set(key, (counts.get(key) ?? 0) + 1)\n }\n\n for (const [key, count] of counts) {\n lines.push(` - ${count > 1 ? `${count}x ` : ''}${key}`)\n }\n\n lines.push('')\n }\n\n return lines.join('\\n')\n}\n\nexport const WEEKLY_SYSTEM_PROMPT = `You write short weekly developer summaries. Here is an example:\n\nINPUT:\nWeek: 2026-05-18 to 2026-05-22\n\nMonday 2026-05-18:\n Project: api-service (feature/auth) — 2h 10m\n Events: 3x code_commit, 2x test_run, dependency_install\n\nTuesday 2026-05-19:\n Project: api-service (feature/auth) — 1h 30m\n Events: 2x code_commit, test_run, build\n\nWednesday 2026-05-20:\n Project: dashboard (main) — 3h 00m\n Events: 4x code_commit, 2x build, test_run\n\nThursday 2026-05-21:\n Project: api-service (feature/auth) — 1h 00m\n Events: code_commit {\"message\":\"feat: merge auth\"}, branch_switch\n\nFriday 2026-05-22:\n Project: dashboard (main) — 2h 00m\n Events: 3x code_commit, build\n\nOUTPUT:\n## Week of 18 May — 9h 40m across 2 projects\n\n**api-service** (Mon–Thu): Built and shipped the auth feature — JWT setup, token validation fixes, and final merge.\n**dashboard** (Wed, Fri): Active development across 7 commits with builds passing.\n\nNow summarise the following week. Output ONLY the summary — a one-line header then one bullet per active project. Maximum 4 bullets.`\n\nconst DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']\n\nexport function buildWeeklyMessage(payload: WeekSummaryPayload): string {\n const lines: string[] = [`Week: ${payload.weekStart} to ${payload.weekEnd}`, '']\n\n for (const { date, sessions } of payload.days) {\n const dayName = DAY_NAMES[new Date(date + 'T00:00:00').getDay()]\n lines.push(`${dayName} ${date}:`)\n\n for (const s of sessions) {\n const project = s.project ?? 'unknown'\n const branch = s.branch ? ` (${s.branch})` : ''\n lines.push(` Project: ${project}${branch} — ${formatDuration(s.durationMinutes)}`)\n\n const counts = new Map<string, number>()\n for (const e of s.events) {\n if (EXCLUDED.has(e.category)) continue\n const failed = e.exitCode !== null && e.exitCode !== 0 ? ' [failed]' : ''\n let key: string\n if (e.hint) {\n key = `other [${e.hint}]${failed}`\n } else {\n const meta = Object.keys(e.metadata).length > 0 ? ` ${JSON.stringify(e.metadata)}` : ''\n key = `${e.category}${meta}${failed}`\n }\n counts.set(key, (counts.get(key) ?? 0) + 1)\n }\n const eventLine = [...counts.entries()].map(([k, n]) => `${n > 1 ? `${n}x ` : ''}${k}`).join(', ')\n lines.push(` Events: ${eventLine}`)\n }\n\n lines.push('')\n }\n\n return lines.join('\\n')\n}\n","const DEFAULT_TIMEOUT_MS = 30_000\n\nexport async function fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs = DEFAULT_TIMEOUT_MS\n): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n return await fetch(url, { ...init, signal: controller.signal })\n } catch (err) {\n if ((err as Error).name === 'AbortError') {\n throw new Error(`Request timed out after ${timeoutMs / 1000}s`)\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n}\n","import type { AIProvider, DaySummaryPayload, WeekSummaryPayload } from '../types'\nimport { getSystemPrompt, buildUserMessage, WEEKLY_SYSTEM_PROMPT, buildWeeklyMessage } from '../prompt'\nimport { fetchWithTimeout } from '../fetch'\n\nexport class AnthropicProvider implements AIProvider {\n private apiKey: string\n private model: string\n\n constructor(apiKey: string, model?: string) {\n this.apiKey = apiKey\n this.model = model || 'claude-haiku-4-5-20251001'\n }\n\n async summarize(payload: DaySummaryPayload): Promise<string> {\n const response = await fetchWithTimeout('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({\n model: this.model,\n max_tokens: 1024,\n system: getSystemPrompt(),\n messages: [{ role: 'user', content: buildUserMessage(payload) }],\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Anthropic API error ${response.status}: ${body}`)\n }\n\n const data = (await response.json()) as { content: Array<{ type: string; text: string }> }\n return data.content.find((block) => block.type === 'text')?.text ?? ''\n }\n\n async summarizeWeek(payload: WeekSummaryPayload): Promise<string> {\n const response = await fetchWithTimeout('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({\n model: this.model,\n max_tokens: 1024,\n system: WEEKLY_SYSTEM_PROMPT,\n messages: [{ role: 'user', content: buildWeeklyMessage(payload) }],\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Anthropic API error ${response.status}: ${body}`)\n }\n\n const data = (await response.json()) as { content: Array<{ type: string; text: string }> }\n return data.content.find((block) => block.type === 'text')?.text ?? ''\n }\n}\n","import type { AIProvider, DaySummaryPayload, WeekSummaryPayload } from '../types'\nimport { getSystemPrompt, buildUserMessage, WEEKLY_SYSTEM_PROMPT, buildWeeklyMessage } from '../prompt'\nimport { fetchWithTimeout } from '../fetch'\n\nexport class OpenAIProvider implements AIProvider {\n private apiKey: string\n private model: string\n private baseUrl: string\n\n constructor(apiKey: string, model?: string, baseUrl?: string) {\n this.apiKey = apiKey\n this.model = model || 'gpt-4o-mini'\n this.baseUrl = baseUrl || 'https://api.openai.com/v1'\n }\n\n async summarize(payload: DaySummaryPayload): Promise<string> {\n const response = await fetchWithTimeout(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n messages: [\n { role: 'system', content: getSystemPrompt() },\n { role: 'user', content: buildUserMessage(payload) },\n ],\n max_tokens: 1024,\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`OpenAI API error ${response.status}: ${body}`)\n }\n\n const data = (await response.json()) as {\n choices: Array<{ message: { content: string } }>\n }\n return data.choices[0]?.message?.content ?? ''\n }\n\n async summarizeWeek(payload: WeekSummaryPayload): Promise<string> {\n const response = await fetchWithTimeout(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n messages: [\n { role: 'system', content: WEEKLY_SYSTEM_PROMPT },\n { role: 'user', content: buildWeeklyMessage(payload) },\n ],\n max_tokens: 1024,\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`OpenAI API error ${response.status}: ${body}`)\n }\n\n const data = (await response.json()) as {\n choices: Array<{ message: { content: string } }>\n }\n return data.choices[0]?.message?.content ?? ''\n }\n}\n","import type { AIProvider, DaySummaryPayload, WeekSummaryPayload } from '../types'\nimport { getSystemPrompt, buildUserMessage, WEEKLY_SYSTEM_PROMPT, buildWeeklyMessage } from '../prompt'\nimport { fetchWithTimeout } from '../fetch'\n\nexport class OllamaProvider implements AIProvider {\n private model: string\n private baseUrl: string\n\n constructor(model?: string, baseUrl?: string) {\n this.model = model || 'llama3'\n this.baseUrl = baseUrl || 'http://localhost:11434'\n }\n\n async summarize(payload: DaySummaryPayload): Promise<string> {\n const response = await fetchWithTimeout(`${this.baseUrl}/api/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model: this.model,\n stream: false,\n messages: [\n { role: 'system', content: getSystemPrompt() },\n { role: 'user', content: buildUserMessage(payload) },\n ],\n options: {\n num_predict: 300, // hard cap on output tokens — forces conciseness\n temperature: 0.3, // lower temperature = more focused, less wandering\n },\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Ollama error ${response.status}: ${body}. Is Ollama running? Try: ollama serve`)\n }\n\n const data = (await response.json()) as { message: { content: string } }\n return data.message?.content ?? ''\n }\n\n async summarizeWeek(payload: WeekSummaryPayload): Promise<string> {\n const response = await fetchWithTimeout(`${this.baseUrl}/api/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model: this.model,\n stream: false,\n messages: [\n { role: 'system', content: WEEKLY_SYSTEM_PROMPT },\n { role: 'user', content: buildWeeklyMessage(payload) },\n ],\n options: {\n num_predict: 400,\n temperature: 0.3,\n },\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Ollama error ${response.status}: ${body}. Is Ollama running? Try: ollama serve`)\n }\n\n const data = (await response.json()) as { message: { content: string } }\n return data.message?.content ?? ''\n }\n}\n","import type { AIProvider } from './types'\nimport type { WorkscribeConfig } from '../config'\nimport { AnthropicProvider } from './providers/anthropic'\nimport { OpenAIProvider } from './providers/openai'\nimport { OllamaProvider } from './providers/ollama'\n\nexport function getProvider(config: WorkscribeConfig): AIProvider {\n const { provider, apiKey, model, baseUrl } = config.ai\n\n if (!provider) {\n throw new Error(\n 'No AI provider configured.\\nRun: workscribe config set ai.provider <anthropic|openai|ollama|openai-compatible>'\n )\n }\n\n switch (provider) {\n case 'anthropic': {\n if (!apiKey) throw new Error('Anthropic requires an API key.\\nRun: workscribe config set ai.apiKey <your-key>')\n return new AnthropicProvider(apiKey, model || undefined)\n }\n\n case 'openai': {\n if (!apiKey) throw new Error('OpenAI requires an API key.\\nRun: workscribe config set ai.apiKey <your-key>')\n return new OpenAIProvider(apiKey, model || undefined)\n }\n\n case 'openai-compatible': {\n if (!apiKey)\n throw new Error('This provider requires an API key.\\nRun: workscribe config set ai.apiKey <your-key>')\n if (!baseUrl)\n throw new Error('openai-compatible requires a base URL.\\nRun: workscribe config set ai.baseUrl <url>')\n return new OpenAIProvider(apiKey, model || undefined, baseUrl)\n }\n\n case 'ollama': {\n return new OllamaProvider(model || undefined, baseUrl || undefined)\n }\n\n default:\n throw new Error(\n `Unknown provider: \"${provider}\"\\nSupported providers: anthropic, openai, ollama, openai-compatible`\n )\n }\n}\n","import { fetchWithTimeout } from '../ai/fetch'\n\nexport async function postToWebhook(url: string, text: string): Promise<void> {\n const response = await fetchWithTimeout(\n url,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ text }),\n },\n 10_000\n )\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Webhook POST failed ${response.status}: ${body}`)\n }\n}\n","/**\n * Converts workscribe markdown summary output to Slack mrkdwn format.\n *\n * Rules:\n * ## heading → *heading* (bold)\n * - bullet → • bullet\n *\n * An optional username is prepended as a dim header line so recipients\n * can tell who sent the summary in shared channels.\n */\nexport function formatForSlack(markdown: string, username?: string): string {\n const body = markdown.replace(/^## (.+)$/gm, '*$1*').replace(/^- /gm, '• ')\n return username ? `_${username}_\\n${body}` : body\n}\n\nexport function isSlackWebhookUrl(url: string): boolean {\n return url.startsWith('https://hooks.slack.com/')\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport path from 'path'\nimport { getOrBuildSessions } from '../sessions/detector'\nimport { getProvider } from '../ai/router'\nimport { readConfig } from '../config'\nimport { log } from '../utils/logger'\nimport { todayDate, parseDate, formatDate } from '../utils/format'\nimport { EXPORTS_DIR } from '../utils/paths'\nimport type { DaySummaryPayload, SessionPayload, EventPayload } from '../ai/types'\nimport type { EventRow } from '../db'\n\nfunction eventRowToPayload(row: EventRow): EventPayload {\n let metadata: Record<string, unknown> = {}\n try {\n if (row.metadata) metadata = JSON.parse(row.metadata)\n } catch {\n /* ignore */\n }\n const payload: EventPayload = {\n category: row.category,\n metadata,\n exitCode: row.exit_code,\n durationMs: row.duration_ms,\n }\n if (row.category === 'other' && typeof metadata.hint === 'string') {\n payload.hint = metadata.hint\n const { hint: _h, tool: _t, ...rest } = metadata\n payload.metadata = rest\n }\n return payload\n}\n\nexport function registerExport(program: Command): void {\n program\n .command('export')\n .description('Export work summary as a markdown file')\n .option('--date <YYYY-MM-DD>', 'date to export (default: today)')\n .option('--output <path>', 'output file path (default: ~/.workscribe/exports/)')\n .action(async (opts) => {\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n }\n\n const sessions = getOrBuildSessions(date)\n if (sessions.length === 0) {\n log.plain(`No activity captured for ${date}`)\n return\n }\n\n const config = readConfig()\n let provider\n try {\n provider = getProvider(config)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n\n const sessionPayloads: SessionPayload[] = sessions.map((session) => ({\n date,\n project: session.repoName,\n branch: session.events[0]?.branch ?? null,\n startTime: formatDate(session.startedAt),\n endTime: formatDate(session.endedAt),\n durationMinutes: session.durationMinutes,\n events: session.events.map(eventRowToPayload),\n }))\n\n const payload: DaySummaryPayload = { date, sessions: sessionPayloads }\n\n log.info(`Generating summary via ${config.ai.provider}…`)\n const summary = await provider.summarize(payload)\n\n const outputPath = opts.output ?? path.join(EXPORTS_DIR, `workscribe-${date}.md`)\n\n if (!fs.existsSync(EXPORTS_DIR)) fs.mkdirSync(EXPORTS_DIR, { recursive: true, mode: 0o700 })\n\n fs.writeFileSync(outputPath, `# Work Summary — ${date}\\n\\n${summary}\\n`, { encoding: 'utf-8', mode: 0o600 })\n log.success(`Saved: ${outputPath}`)\n })\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport { readConfig, writeConfig, getConfigValue, setConfigValue } from '../config'\nimport { log } from '../utils/logger'\n\nexport function registerConfig(program: Command): void {\n const configCmd = program\n .command('config')\n .description('View or update Workscribe configuration')\n .action(() => {\n const config = readConfig()\n log.plain('')\n log.plain(chalk.bold(' Workscribe Config'))\n log.plain('')\n printConfig(config, ' ')\n log.plain('')\n })\n\n configCmd\n .command('set <key> <value>')\n .description('Set a config value (e.g. workscribe config set ai.provider anthropic)')\n .action((key: string, value: string) => {\n const config = readConfig()\n const updated = setConfigValue(config, key, value)\n writeConfig(updated)\n const isSensitive =\n key === 'ai.apiKey' ||\n key.toLowerCase().includes('key') ||\n key.toLowerCase().includes('secret') ||\n key.toLowerCase().includes('token')\n const displayValue = isSensitive ? '[set]' : chalk.yellow(value)\n log.success(`Set ${chalk.cyan(key)} = ${displayValue}`)\n })\n\n configCmd\n .command('get <key>')\n .description('Get a config value')\n .action((key: string) => {\n const config = readConfig()\n const value = getConfigValue(config, key)\n if (value === undefined) {\n log.warn(`Key not found: ${key}`)\n } else {\n const lastSegment = key.split('.').pop() ?? ''\n if (SENSITIVE_KEYS.has(lastSegment) && typeof value === 'string' && value.length > 0) {\n log.plain(`${value.slice(0, 4)}${'*'.repeat(8)} (${value.length} chars)`)\n } else {\n log.plain(String(value))\n }\n }\n })\n}\n\nconst SENSITIVE_KEYS = new Set([\n 'apiKey',\n 'api_key',\n 'secret',\n 'token',\n 'password',\n 'passwd',\n 'webhook',\n 'slackWebhook',\n])\n\nfunction maskValue(key: string, value: unknown): string {\n if (SENSITIVE_KEYS.has(key) && typeof value === 'string' && value.length > 0) {\n return chalk.dim(`${value.slice(0, 4)}${'*'.repeat(8)} (${value.length} chars)`)\n }\n if (Array.isArray(value)) return `[${(value as unknown[]).join(', ')}]`\n return String(value) || chalk.dim('(not set)')\n}\n\nfunction printConfig(obj: unknown, indent: string): void {\n if (typeof obj !== 'object' || obj === null) return\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n log.plain(`${indent}${chalk.bold(key)}:`)\n printConfig(value, indent + ' ')\n } else {\n log.plain(`${indent}${chalk.dim(key)}: ${chalk.yellow(maskValue(key, value))}`)\n }\n }\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport { PAUSE_FLAG_PATH } from '../utils/paths'\nimport { log } from '../utils/logger'\n\nexport function registerPause(program: Command): void {\n program\n .command('pause')\n .description('Pause capture temporarily')\n .action(() => {\n if (fs.existsSync(PAUSE_FLAG_PATH)) {\n log.info('Capture is already paused. Run workscribe resume to restart.')\n return\n }\n fs.writeFileSync(PAUSE_FLAG_PATH, '', { mode: 0o600 })\n log.success('Capture paused. Run workscribe resume to restart.')\n })\n\n program\n .command('resume')\n .description('Resume capture after a pause')\n .action(() => {\n if (!fs.existsSync(PAUSE_FLAG_PATH)) {\n log.info('Capture is not paused.')\n return\n }\n fs.rmSync(PAUSE_FLAG_PATH)\n log.success('Capture resumed.')\n })\n}\n","import { Command } from 'commander'\nimport { getLastEventIds, getEventsByIds, deleteEventsByIds } from '../db'\nimport { log } from '../utils/logger'\n\nexport function registerUndo(program: Command): void {\n program\n .command('undo')\n .description('Remove the last N captured events')\n .option('-n, --count <number>', 'number of events to remove', '1')\n .option('--dry-run', 'preview what would be deleted without deleting')\n .action((opts) => {\n const count = parseInt(opts.count, 10)\n if (isNaN(count) || count < 1) {\n log.error('--count must be a positive integer')\n process.exit(1)\n }\n\n const ids = getLastEventIds(count)\n if (ids.length === 0) {\n log.plain('No events to undo.')\n return\n }\n\n const events = getEventsByIds(ids)\n log.plain('')\n log.plain(`Events to remove (${events.length}):`)\n for (const e of events) {\n log.plain(` ${e.captured_at} ${e.category} ${e.command}`)\n }\n log.plain('')\n\n if (opts.dryRun) {\n log.plain('Dry run — nothing deleted.')\n return\n }\n\n deleteEventsByIds(ids)\n log.success(`Removed ${ids.length} event${ids.length > 1 ? 's' : ''}.`)\n })\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport prompts from 'prompts'\nimport { getEventsForDate, deleteEventsForDate } from '../db'\nimport { log } from '../utils/logger'\nimport { todayDate, parseDate } from '../utils/format'\n\nexport function registerClear(program: Command): void {\n program\n .command('clear')\n .description('Delete all captured events for a date')\n .option('--date <YYYY-MM-DD>', 'date to clear (default: today)')\n .option('--dry-run', 'preview what would be deleted without deleting')\n .option('--yes', 'skip confirmation prompt')\n .action(async (opts) => {\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n }\n\n const events = getEventsForDate(date)\n\n if (events.length === 0) {\n log.plain(`No events found for ${date}.`)\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(` Events for ${date} (${events.length} total)`))\n log.plain('')\n\n // Show a compact summary by category\n const counts = new Map<string, number>()\n for (const e of events) counts.set(e.category, (counts.get(e.category) ?? 0) + 1)\n for (const [cat, n] of counts) {\n log.plain(` ${chalk.dim(String(n).padStart(4))} ${cat}`)\n }\n log.plain('')\n\n if (opts.dryRun) {\n log.plain(chalk.dim(' Dry run — nothing deleted.'))\n log.plain('')\n return\n }\n\n if (!opts.yes) {\n const { confirm } = await prompts({\n type: 'confirm',\n name: 'confirm',\n message: `Delete all ${events.length} events for ${date}?`,\n initial: false,\n })\n if (!confirm) {\n log.plain('Cancelled.')\n return\n }\n }\n\n const deleted = deleteEventsForDate(date)\n log.success(`Cleared ${deleted} event${deleted !== 1 ? 's' : ''} for ${date}.`)\n })\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport path from 'path'\nimport os from 'os'\nimport prompts from 'prompts'\nimport chalk from 'chalk'\nimport { WORKSCRIBE_DIR } from '../utils/paths'\nimport { isHookInstalled, removeHook } from '../capture/shell-hook'\nimport { log } from '../utils/logger'\n\nfunction detectShellRcFiles(): { name: string; rcFile: string }[] {\n const candidates = [\n { name: 'zsh', rcFile: path.join(os.homedir(), '.zshrc') },\n { name: 'bash', rcFile: path.join(os.homedir(), '.bashrc') },\n { name: 'bash', rcFile: path.join(os.homedir(), '.bash_profile') },\n ]\n return candidates.filter((candidate) => fs.existsSync(candidate.rcFile) && isHookInstalled(candidate.rcFile))\n}\n\nexport function registerUninstall(program: Command): void {\n program\n .command('uninstall')\n .description('Remove shell hooks and optionally delete all Workscribe data')\n .option('--hooks-only', 'remove shell hooks only, skip data deletion prompt (used by npm preuninstall)')\n .action(async (opts) => {\n log.plain(chalk.bold('\\n Workscribe — Uninstall\\n'))\n\n // 1. Remove shell hooks from any rc files that have them\n const hooked = detectShellRcFiles()\n if (hooked.length === 0) {\n log.info('No shell hooks found')\n } else {\n for (const { name, rcFile } of hooked) {\n removeHook(rcFile)\n log.success(`Shell hook removed from ${rcFile}`)\n log.plain(` ${chalk.dim(`Run: source ${rcFile}`)} (or restart your terminal to take effect)`)\n log.plain(\n ` ${chalk.dim(`${name === 'zsh' ? 'unfunction' : 'unset -f'} _workscribe_preexec _workscribe_precmd`)}`\n )\n }\n }\n\n if (opts.hooksOnly) return\n\n // 2. Optionally delete ~/.workscribe/ data\n if (fs.existsSync(WORKSCRIBE_DIR)) {\n log.plain('')\n const { deleteData } = await prompts({\n type: 'confirm',\n name: 'deleteData',\n message: `Delete all Workscribe data in ${WORKSCRIBE_DIR}? (database, config, exports)`,\n initial: false,\n })\n\n if (deleteData) {\n fs.rmSync(WORKSCRIBE_DIR, { recursive: true, force: true })\n log.success(`Deleted ${WORKSCRIBE_DIR}`)\n } else {\n log.info(`Data kept at ${WORKSCRIBE_DIR}`)\n }\n }\n\n log.plain('')\n log.plain(` ${chalk.dim('npm uninstall -g @workscribe/cli')} — remove the CLI itself`)\n log.plain('')\n })\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport { readConfig, writeConfig } from '../config'\nimport { PROFILES_DIR } from '../utils/paths'\nimport { getCachedProfiles, detectProfilesForDirectory } from '../profiles/loader'\nimport { installProfile, cacheManifest, readCachedManifest } from '../profiles/fetcher'\nimport { getOtherEventToolCounts } from '../db'\nimport { log } from '../utils/logger'\n\nconst MIN_SUGGEST_COUNT = 5\n\nexport function registerProfile(program: Command): void {\n const profile = program.command('profile').description('Manage stack profiles for better command tracking')\n\n // ─── list ─────────────────────────────────────────────────────────────────\n profile\n .command('list')\n .description('List available profiles from the registry')\n .action(async () => {\n const config = readConfig()\n const activeNames = new Set(config.capture.profiles)\n\n let manifest = readCachedManifest()\n let offline = false\n\n if (!manifest) {\n try {\n manifest = await cacheManifest()\n } catch {\n offline = true\n manifest = getCachedProfiles().map((p) => ({\n name: p.name,\n displayName: p.displayName,\n tags: [],\n description: '',\n keywords: [],\n detect: p.detect,\n }))\n }\n } else {\n // Refresh in background — best effort, don't block output\n cacheManifest().catch(() => undefined)\n }\n\n if (offline) {\n log.warn('Registry unreachable — showing installed profiles only')\n }\n\n if (manifest.length === 0) {\n log.plain('No profiles available. Check your connection and try again.')\n return\n }\n\n // Group by tag\n const grouped = new Map<string, typeof manifest>()\n for (const entry of manifest) {\n const tag = entry.tags[0] ?? 'other'\n if (!grouped.has(tag)) grouped.set(tag, [])\n grouped.get(tag)!.push(entry)\n }\n\n log.plain('')\n for (const [tag, entries] of grouped) {\n log.plain(chalk.bold(` ${tag.charAt(0).toUpperCase() + tag.slice(1)} profiles`))\n log.plain(chalk.dim(' ' + '─'.repeat(60)))\n for (const entry of entries) {\n const badge = activeNames.has(entry.name) ? chalk.green(' [active]') : ''\n const installed = fs.existsSync(path.join(PROFILES_DIR, `${entry.name}.json`)) ? chalk.dim(' installed') : ''\n log.plain(` ${chalk.cyan(entry.name.padEnd(18))} ${entry.displayName.padEnd(28)}${badge}${installed}`)\n if (entry.description) log.plain(` ${chalk.dim(' '.repeat(18) + entry.description)}`)\n }\n log.plain('')\n }\n })\n\n // ─── add ──────────────────────────────────────────────────────────────────\n profile\n .command('add <names...>')\n .description('Install one or more profiles from the registry')\n .action(async (names: string[]) => {\n const config = readConfig()\n const activeNames = new Set(config.capture.profiles)\n\n for (const name of names) {\n if (activeNames.has(name)) {\n log.info(`Profile \"${name}\" is already active`)\n continue\n }\n try {\n log.plain(`Fetching ${chalk.cyan(name)}…`)\n await installProfile(name)\n activeNames.add(name)\n log.success(`Profile \"${name}\" installed`)\n } catch (err) {\n log.error(`Failed to install \"${name}\": ${(err as Error).message}`)\n }\n }\n\n config.capture.profiles = [...activeNames]\n writeConfig(config)\n })\n\n // ─── remove ───────────────────────────────────────────────────────────────\n profile\n .command('remove <names...>')\n .description('Uninstall one or more profiles')\n .action((names: string[]) => {\n const config = readConfig()\n const activeNames = new Set(config.capture.profiles)\n\n for (const name of names) {\n if (!activeNames.has(name)) {\n log.warn(`Profile \"${name}\" is not active`)\n continue\n }\n activeNames.delete(name)\n const cachePath = path.join(PROFILES_DIR, `${name}.json`)\n if (fs.existsSync(cachePath)) fs.unlinkSync(cachePath)\n log.success(`Profile \"${name}\" removed`)\n }\n\n config.capture.profiles = [...activeNames]\n writeConfig(config)\n })\n\n // ─── update ───────────────────────────────────────────────────────────────\n profile\n .command('update [name]')\n .description('Re-fetch installed profiles from the registry')\n .action(async (name?: string) => {\n const config = readConfig()\n const toUpdate = name ? [name] : config.capture.profiles\n\n if (toUpdate.length === 0) {\n log.plain('No profiles installed. Run workscribe profile add <name> first.')\n return\n }\n\n for (const profileName of toUpdate) {\n try {\n log.plain(`Updating ${chalk.cyan(profileName)}…`)\n await installProfile(profileName)\n log.success(`${profileName} updated`)\n } catch (err) {\n log.error(`Failed to update \"${profileName}\": ${(err as Error).message}`)\n }\n }\n })\n\n // ─── detect ───────────────────────────────────────────────────────────────\n profile\n .command('detect')\n .description('Scan the current directory and suggest matching profiles')\n .action(() => {\n const cwd = process.cwd()\n const matches = detectProfilesForDirectory(cwd)\n\n if (matches.length === 0) {\n const cached = readCachedManifest()\n if (!cached) {\n log.plain('No manifest cached. Run workscribe profile list to fetch it first.')\n } else {\n log.plain(`No profiles detected for ${chalk.dim(cwd)}`)\n log.plain(chalk.dim('Run workscribe profile list to browse available profiles.'))\n }\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(' Profiles detected for this directory:'))\n log.plain('')\n for (const entry of matches) {\n const files = entry.detect?.files?.join(', ') ?? ''\n log.plain(` ${chalk.cyan(entry.name.padEnd(18))} ${entry.displayName} ${chalk.dim('(' + files + ')')}`)\n }\n log.plain('')\n log.plain(` Run: ${chalk.cyan('workscribe profile add ' + matches.map((e) => e.name).join(' '))}`)\n log.plain('')\n })\n\n // ─── suggest ──────────────────────────────────────────────────────────────\n profile\n .command('suggest')\n .description('Analyse recent unclassified commands and suggest profiles')\n .option('--days <n>', 'number of days to analyse', '30')\n .action((opts) => {\n const days = Math.max(1, parseInt(opts.days as string, 10) || 30)\n const toolCounts = getOtherEventToolCounts(days)\n\n if (toolCounts.length === 0) {\n log.plain('No unclassified commands found in the last ' + days + ' days.')\n return\n }\n\n const manifest = readCachedManifest()\n if (!manifest) {\n log.plain('No manifest cached. Run workscribe profile list first.')\n return\n }\n\n const config = readConfig()\n const activeNames = new Set(config.capture.profiles)\n\n // Match tool counts against manifest keywords\n const suggestions: { entry: (typeof manifest)[number]; count: number }[] = []\n for (const entry of manifest) {\n if (activeNames.has(entry.name)) continue\n const matchedCount = toolCounts\n .filter((tc) => entry.keywords.some((kw) => tc.tool.toLowerCase().includes(kw.toLowerCase())))\n .reduce((sum, tc) => sum + tc.count, 0)\n if (matchedCount >= MIN_SUGGEST_COUNT) {\n suggestions.push({ entry, count: matchedCount })\n }\n }\n\n suggestions.sort((a, b) => b.count - a.count)\n\n if (suggestions.length === 0) {\n log.plain('No profile matches found. Your commands are well covered.')\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(` Analysed last ${days} days of unclassified commands:`))\n log.plain('')\n for (const { entry, count } of suggestions) {\n log.plain(\n ` ${chalk.cyan(entry.name.padEnd(18))} ${String(count).padStart(4)} commands → ${entry.displayName}`\n )\n }\n log.plain('')\n log.plain(` Run: ${chalk.cyan('workscribe profile add ' + suggestions.map((s) => s.entry.name).join(' '))}`)\n log.plain('')\n })\n}\n"],"mappings":"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","names":["import_fs","path","os","fs","migration","import_path","import_fs","fs","path","import_child_process","import_fs","import_path","path","fs","import_fs","import_os","import_path","import_fs","chalk","fs","path","os","fs","import_fs","import_path","import_fs","fs","import_fs","import_path","path","fs","path","fs","fs","path","fs","program","program","import_fs","import_path","import_os","import_chalk","import_fs","import_path","fs","path","import_fs","import_path","import_os","import_child_process","path","os","fs","path","os","program","chalk","fs","prompts","import_fs","import_chalk","program","fs","chalk","import_chalk","chalk","program","import_chalk","program","chalk","import_chalk","import_fs","import_os","import_path","os","program","sessions","path","fs","chalk","fullSummary","import_fs","import_path","eventRowToPayload","program","path","fs","import_chalk","program","chalk","import_fs","program","fs","program","import_chalk","import_prompts","program","chalk","prompts","import_fs","import_path","import_os","import_prompts","import_chalk","path","os","fs","program","chalk","prompts","import_fs","import_path","import_chalk","program","chalk","fs","path"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/node-version.ts","../src/capture/index.ts","../src/db/index.ts","../src/utils/paths.ts","../src/db/migrations/001_initial_schema.ts","../src/db/migrations/002_semantic_categories.ts","../src/db/migrations/index.ts","../src/capture/redact.ts","../src/capture/git.ts","../src/capture/git-snapshot.ts","../src/capture/aider.ts","../src/config/registry.ts","../src/config/ai-tools.json","../src/utils/logger.ts","../src/profiles/loader.ts","../src/config/index.ts","../src/profiles/schema.ts","../src/profiles/fetcher.ts","../src/normalize/patterns.ts","../src/capture/filter.ts","../src/cli/capture.ts","../src/cli/hook.ts","../src/cli/init.ts","../src/utils/format.ts","../src/ai/prompt.ts","../src/ai/fetch.ts","../src/ai/providers/index.ts","../src/ai/providers/config.ts","../src/ai/router.ts","../src/capture/shell-hook.ts","../src/capture/hooks/claude-code.ts","../src/capture/hooks/utils.ts","../src/capture/hooks/index.ts","../src/cli/status.ts","../src/cli/events.ts","../src/cli/sessions.ts","../src/sessions/grouper.ts","../src/sessions/detector.ts","../src/cli/summary.ts","../src/integrations/webhook.ts","../src/integrations/slack.ts","../src/cli/export.ts","../src/cli/config.ts","../src/cli/pause.ts","../src/cli/undo.ts","../src/cli/clear.ts","../src/cli/uninstall.ts","../src/cli/profile.ts","../src/cli/note.ts","../src/cli/week.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { assertNodeVersion } from './utils/node-version'\n\nassertNodeVersion(process.versions.node)\nimport { registerCapture } from './cli/capture'\nimport { registerHook } from './cli/hook'\n\ndeclare const __WORKSCRIBE_VERSION__: string\nimport { registerInit } from './cli/init'\nimport { registerStatus } from './cli/status'\nimport { registerEvents } from './cli/events'\nimport { registerSessions } from './cli/sessions'\nimport { registerSummary } from './cli/summary'\nimport { registerExport } from './cli/export'\nimport { registerConfig } from './cli/config'\nimport { registerPause } from './cli/pause'\nimport { registerUndo } from './cli/undo'\nimport { registerClear } from './cli/clear'\nimport { registerUninstall } from './cli/uninstall'\nimport { registerProfile } from './cli/profile'\nimport { registerNote } from './cli/note'\nimport { registerWeek } from './cli/week'\n\nconst program = new Command()\n\nprogram.name('workscribe').description('Automatic developer work journal').version(__WORKSCRIBE_VERSION__)\n\nregisterCapture(program)\nregisterHook(program)\nregisterInit(program)\nregisterStatus(program)\nregisterEvents(program)\nregisterSessions(program)\nregisterSummary(program)\nregisterExport(program)\nregisterConfig(program)\nregisterPause(program)\nregisterUndo(program)\nregisterClear(program)\nregisterUninstall(program)\nregisterProfile(program)\nregisterNote(program)\nregisterWeek(program)\n\nprogram.parse()\n","export function assertNodeVersion(nodeVersion: string): void {\n const major = Number(nodeVersion.split('.')[0])\n if (major < 22) {\n process.stderr.write(\n `workscribe requires Node.js 22 or later (you have v${nodeVersion}).\\n` +\n `Upgrade at https://nodejs.org or via your version manager:\\n` +\n ` nvm install 22 && nvm use 22\\n`\n )\n process.exit(1)\n }\n}\n","import fs from 'fs'\nimport { insertEvent, getLastEvent } from '../db'\nimport { redact } from './redact'\nimport { getGitContext } from './git'\nimport { getCommitsSince } from './git-snapshot'\nimport { readLastAiderPrompt } from './aider'\nimport { normalizeCommand } from '../normalize/patterns'\nimport { readConfig } from '../config'\nimport { shouldFilter, isDuplicate } from './filter'\nimport { PAUSE_FLAG_PATH } from '../utils/paths'\nimport { loadAIToolRegistry } from '../config/registry'\n\nexport function captureCommand(opts: {\n command: string\n cwd: string\n exitCode: number | null\n durationMs: number | null\n gitBefore?: string\n source?: string\n}): void {\n // Check pause flag before any I/O\n if (fs.existsSync(PAUSE_FLAG_PATH)) return\n\n const config = readConfig()\n const { command, cwd, exitCode, durationMs } = opts\n\n // 1. Filter noise commands\n if (shouldFilter(command, config.capture.ignore)) return\n\n // 2. Deduplicate: same command + same cwd within 5 seconds\n const last = getLastEvent()\n if (isDuplicate(command, cwd, last ?? undefined)) return\n\n // 3. Redact sensitive patterns\n const safeCommand = redact(command, config.redact.extra)\n\n // 4. Extract git context (with optional per-project name override)\n const nameOverride = config.projects?.[cwd] ?? null\n const { repoName, branch } = getGitContext(cwd, nameOverride)\n\n // 5. Normalize to typed event\n const { category, metadata } = normalizeCommand(safeCommand)\n\n if (category === 'ai_session' && config.capture.aiTools === false) return\n\n // Hint passthrough: preserve context for unrecognised commands so the AI can describe them\n if (category === 'other') {\n const firstToken = safeCommand.trim().split(/\\s+/)[0]\n if (firstToken) metadata.tool = firstToken\n metadata.hint = safeCommand.trim().slice(0, 120)\n }\n\n if (opts.source) metadata.source = opts.source\n\n // 6. For ai_session events, enrich metadata\n if (category === 'ai_session') {\n // 6a. Commits made during the session\n if (opts.gitBefore) {\n const commits = getCommitsSince(opts.gitBefore, cwd)\n if (commits.length > 0) metadata.commits = commits\n }\n\n // 6b. Last user prompt from history file (e.g. Aider)\n if (config.capture.includeAiderPrompt !== false) {\n const toolEntry = loadAIToolRegistry().find((entry) => entry.tool === metadata.tool)\n if (toolEntry?.contextSource === 'history-file') {\n const prompt = readLastAiderPrompt(cwd)\n if (prompt) metadata.prompt = prompt\n }\n }\n }\n\n // 7. Persist\n insertEvent({\n captured_at: new Date().toISOString(),\n command: safeCommand,\n cwd,\n exit_code: exitCode,\n duration_ms: durationMs,\n repo_name: repoName,\n branch,\n category,\n metadata: Object.keys(metadata).length > 0 ? JSON.stringify(metadata) : null,\n })\n}\n","import { DatabaseSync } from 'node:sqlite'\nimport fs from 'fs'\nimport { WORKSCRIBE_DIR, DB_PATH } from '../utils/paths'\nimport type { EventRow, SessionRow } from './types'\nimport { MIGRATIONS } from './migrations'\nexport type { EventRow, SessionRow } from './types'\n\nlet _db: DatabaseSync | null = null\n\nexport function getDb(): DatabaseSync {\n if (_db) return _db\n\n // Ensure ~/.workscribe/ exists\n if (!fs.existsSync(WORKSCRIBE_DIR)) {\n fs.mkdirSync(WORKSCRIBE_DIR, { recursive: true })\n }\n\n // Don't assign to _db until after migrations succeed — if applyMigrations\n // throws, _db stays null so the next call retries cleanly instead of\n // returning a partially-initialised singleton.\n const db = new DatabaseSync(DB_PATH)\n try {\n fs.chmodSync(DB_PATH, 0o600)\n } catch {\n /* ignore if already correct */\n }\n db.exec('PRAGMA journal_mode = WAL')\n db.exec('PRAGMA foreign_keys = ON')\n applyMigrations(db)\n _db = db\n return _db\n}\n\nfunction applyMigrations(db: DatabaseSync): void {\n // Create the migration tracking table if this is the first run\n db.exec(`\n CREATE TABLE IF NOT EXISTS schema_migrations (\n version INTEGER PRIMARY KEY,\n applied_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `)\n\n // Bootstrap: if the events table already exists but schema_migrations is\n // empty, this is an existing install that predates the migration system.\n // Seed version 1 as applied so we don't re-run the initial schema.\n const hasEvents = db.prepare(\"SELECT name FROM sqlite_master WHERE type='table' AND name='events'\").get()\n const hasVersion1 = db.prepare('SELECT version FROM schema_migrations WHERE version = 1').get()\n\n if (hasEvents && !hasVersion1) {\n db.prepare(\"INSERT INTO schema_migrations (version, applied_at) VALUES ($version, datetime('now'))\").run({\n version: 1,\n })\n }\n\n // Collect already-applied versions\n const applied = new Set(\n (db.prepare('SELECT version FROM schema_migrations').all() as { version: number }[]).map((row) => row.version)\n )\n\n // Apply each pending migration in order, wrapped in a transaction so a\n // partial failure leaves the DB cleanly at the previous version.\n for (const migration of MIGRATIONS) {\n if (applied.has(migration.version)) continue\n\n db.exec('BEGIN')\n try {\n db.exec(migration.sql)\n db.prepare(\"INSERT INTO schema_migrations (version, applied_at) VALUES ($version, datetime('now'))\").run({\n version: migration.version,\n })\n db.exec('COMMIT')\n } catch (err) {\n try {\n db.exec('ROLLBACK')\n } catch {\n /* already rolled back or connection lost */\n }\n throw new Error(`Migration ${migration.version} (${migration.description}) failed: ${(err as Error).message}`)\n }\n }\n}\n\n// ─── Typed query helpers ──────────────────────────────────────────────────────\n\nexport function insertEvent(params: {\n captured_at: string\n command: string\n cwd: string\n exit_code: number | null\n duration_ms: number | null\n repo_name: string | null\n branch: string | null\n category: string\n metadata: string | null\n}): void {\n const db = getDb()\n const stmt = db.prepare(`\n INSERT INTO events (captured_at, command, cwd, exit_code, duration_ms, repo_name, branch, category, metadata)\n VALUES ($captured_at, $command, $cwd, $exit_code, $duration_ms, $repo_name, $branch, $category, $metadata)\n `)\n stmt.run(params)\n}\n\nexport function getLastEvent(): EventRow | undefined {\n const db = getDb()\n const stmt = db.prepare('SELECT * FROM events ORDER BY id DESC LIMIT 1')\n return stmt.get() as EventRow | undefined\n}\n\nexport function getEventsForDate(date: string): EventRow[] {\n const db = getDb()\n const stmt = db.prepare(`\n SELECT * FROM events\n WHERE date(captured_at, 'localtime') = $date\n ORDER BY captured_at ASC\n `)\n return stmt.all({ date }) as unknown as EventRow[]\n}\n\nexport function getRecentEvents(limit = 20): EventRow[] {\n const db = getDb()\n const stmt = db.prepare('SELECT * FROM events ORDER BY captured_at DESC LIMIT $limit')\n return stmt.all({ limit }) as unknown as EventRow[]\n}\n\nexport function getEventCount(): number {\n const db = getDb()\n const stmt = db.prepare('SELECT COUNT(*) as count FROM events')\n const row = stmt.get() as { count: number }\n return row.count\n}\n\nexport function insertSession(params: {\n date: string\n started_at: string\n ended_at: string\n repo_name: string | null\n event_count: number\n summary: string | null\n}): number {\n const db = getDb()\n const stmt = db.prepare(`\n INSERT INTO sessions (date, started_at, ended_at, repo_name, event_count, summary)\n VALUES ($date, $started_at, $ended_at, $repo_name, $event_count, $summary)\n `)\n const result = stmt.run(params)\n return Number(result.lastInsertRowid)\n}\n\nexport function insertSessionEvent(sessionId: number, eventId: number): void {\n const db = getDb()\n const stmt = db.prepare(`\n INSERT OR IGNORE INTO session_events (session_id, event_id) VALUES ($session_id, $event_id)\n `)\n stmt.run({ session_id: sessionId, event_id: eventId })\n}\n\nexport function getEventsBySessionId(sessionId: number): EventRow[] {\n const db = getDb()\n const stmt = db.prepare(`\n SELECT e.* FROM events e\n INNER JOIN session_events se ON se.event_id = e.id\n WHERE se.session_id = $session_id\n ORDER BY e.captured_at ASC\n `)\n return stmt.all({ session_id: sessionId }) as unknown as EventRow[]\n}\n\nexport function getSessionsForDate(date: string): SessionRow[] {\n const db = getDb()\n const stmt = db.prepare('SELECT * FROM sessions WHERE date = $date ORDER BY started_at ASC')\n return stmt.all({ date }) as unknown as SessionRow[]\n}\n\nexport function updateSessionSummary(sessionId: number, summary: string): void {\n const db = getDb()\n const stmt = db.prepare('UPDATE sessions SET summary = $summary WHERE id = $id')\n stmt.run({ summary, id: sessionId })\n}\n\nexport function getLastEventIds(n: number): number[] {\n const db = getDb()\n const rows = db.prepare('SELECT id FROM events ORDER BY id DESC LIMIT $n').all({ n }) as { id: number }[]\n return rows.map((row) => row.id)\n}\n\nexport function getEventsByIds(ids: number[]): EventRow[] {\n if (ids.length === 0) return []\n const db = getDb()\n const placeholders = ids.map(() => '?').join(', ')\n return db\n .prepare(`SELECT * FROM events WHERE id IN (${placeholders}) ORDER BY id DESC`)\n .all(...ids) as unknown as EventRow[]\n}\n\nexport function deleteEventsByIds(ids: number[]): void {\n if (ids.length === 0) return\n const db = getDb()\n const placeholders = ids.map(() => '?').join(', ')\n\n const affectedDates = db\n .prepare(`SELECT DISTINCT date(captured_at, 'localtime') as date FROM events WHERE id IN (${placeholders})`)\n .all(...ids) as { date: string }[]\n\n db.prepare(`DELETE FROM events WHERE id IN (${placeholders})`).run(...ids)\n\n for (const { date } of affectedDates) {\n clearSessionsForDate(date)\n }\n}\n\nexport function deleteEventsForDate(date: string): number {\n const db = getDb()\n // Clear sessions (and session_events) before deleting events — FK constraint order\n clearSessionsForDate(date)\n const result = db.prepare(`DELETE FROM events WHERE date(captured_at, 'localtime') = $date`).run({ date }) as {\n changes: number\n }\n return result.changes\n}\n\nexport function getOtherEventToolCounts(days: number): { tool: string; count: number }[] {\n const db = getDb()\n return db\n .prepare(\n `SELECT json_extract(metadata, '$.tool') as tool, COUNT(*) as count\n FROM events\n WHERE category = 'other'\n AND captured_at >= datetime('now', $offset)\n AND json_extract(metadata, '$.tool') IS NOT NULL\n GROUP BY tool\n ORDER BY count DESC`\n )\n .all({ offset: `-${days} days` }) as { tool: string; count: number }[]\n}\n\nexport function getRecentOtherRate(days: number): { total: number; otherCount: number } {\n const db = getDb()\n const row = db\n .prepare(\n `SELECT COUNT(*) as total,\n SUM(CASE WHEN category = 'other' THEN 1 ELSE 0 END) as otherCount\n FROM events\n WHERE captured_at >= datetime('now', $offset)`\n )\n .get({ offset: `-${days} days` }) as { total: number; otherCount: number }\n return row\n}\n\nexport function clearSessionsForDate(date: string): void {\n const db = getDb()\n // Remove session_events first due to FK constraint\n db.prepare(\n `\n DELETE FROM session_events WHERE session_id IN (\n SELECT id FROM sessions WHERE date = $date\n )\n `\n ).run({ date })\n db.prepare('DELETE FROM sessions WHERE date = $date').run({ date })\n}\n","import path from 'path'\nimport os from 'os'\n\nexport const WORKSCRIBE_DIR = path.join(os.homedir(), '.workscribe')\nexport const DB_PATH = path.join(WORKSCRIBE_DIR, 'workscribe.db')\nexport const CONFIG_PATH = path.join(WORKSCRIBE_DIR, 'config.json')\nexport const DEBUG_LOG_PATH = path.join(WORKSCRIBE_DIR, 'debug.log')\nexport const EXPORTS_DIR = path.join(WORKSCRIBE_DIR, 'exports')\nexport const PAUSE_FLAG_PATH = path.join(WORKSCRIBE_DIR, 'paused')\nexport const WEEKLY_CACHE_DIR = path.join(WORKSCRIBE_DIR, 'weekly-cache')\nexport const PROFILES_DIR = path.join(WORKSCRIBE_DIR, 'profiles')\n","export default {\n version: 1,\n description: 'initial schema',\n sql: `\n CREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n captured_at TEXT NOT NULL,\n command TEXT NOT NULL,\n cwd TEXT NOT NULL,\n exit_code INTEGER,\n duration_ms INTEGER,\n repo_name TEXT,\n branch TEXT,\n category TEXT NOT NULL DEFAULT 'other',\n metadata TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_events_captured_at ON events(captured_at);\n CREATE INDEX IF NOT EXISTS idx_events_repo_name ON events(repo_name);\n\n CREATE TABLE IF NOT EXISTS sessions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n date TEXT NOT NULL,\n started_at TEXT NOT NULL,\n ended_at TEXT NOT NULL,\n repo_name TEXT,\n event_count INTEGER NOT NULL DEFAULT 0,\n summary TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_sessions_date ON sessions(date);\n\n CREATE TABLE IF NOT EXISTS session_events (\n session_id INTEGER NOT NULL REFERENCES sessions(id),\n event_id INTEGER NOT NULL REFERENCES events(id),\n PRIMARY KEY (session_id, event_id)\n );\n `,\n}\n","const migration = {\n version: 2,\n description: 'Rename granular categories to 13 universal semantic categories',\n sql: `\n UPDATE events SET category = 'shipping' WHERE category IN ('code_commit','code_push','code_merge');\n UPDATE events SET category = 'versioning' WHERE category IN ('code_pull','branch_switch','code_stash','git_other');\n UPDATE events SET category = 'building' WHERE category = 'build';\n UPDATE events SET category = 'running' WHERE category IN ('server_run','script_run');\n UPDATE events SET category = 'testing' WHERE category = 'test_run';\n UPDATE events SET category = 'linting' WHERE category = 'lint_run';\n UPDATE events SET category = 'dependencies' WHERE category IN ('dependency_install','dependency_remove');\n UPDATE events SET category = 'infrastructure' WHERE category = 'infrastructure';\n UPDATE events SET category = 'files' WHERE category IN ('file_ops','environment');\n UPDATE events SET category = 'exploring' WHERE category IN ('code_search','code_read');\n `,\n}\n\nexport default migration\n","import initialSchema from './001_initial_schema'\nimport semanticCategories from './002_semantic_categories'\n\nexport interface Migration {\n version: number\n description: string\n sql: string\n}\n\n// Ordered list — append only. Never modify or remove an existing entry.\nexport const MIGRATIONS: Migration[] = [initialSchema, semanticCategories]\n","// Patterns that match known sensitive values\nconst BUILTIN_PATTERNS: RegExp[] = [\n // AWS access keys\n /AKIA[0-9A-Z]{16}/g,\n // AWS secret access keys (40 char base64-ish after common env vars)\n /(?<=AWS_SECRET_ACCESS_KEY[=\\s]+)\\S+/gi,\n // GitHub tokens\n /ghp_[a-zA-Z0-9]{36}/g,\n /github_pat_[a-zA-Z0-9_]{82}/g,\n // GitLab tokens\n /glpat-[a-zA-Z0-9\\-]{20}/g,\n // Generic JWTs (three base64url segments)\n /eyJ[a-zA-Z0-9_-]+\\.eyJ[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]+/g,\n // Slack tokens and incoming webhook URLs\n /xox[baprs]-[a-zA-Z0-9\\-]+/g,\n /https:\\/\\/hooks\\.slack\\.com\\/services\\/[A-Z0-9]+\\/[A-Z0-9]+\\/[a-zA-Z0-9]+/g,\n // Stripe keys\n /sk_(live|test)_[a-zA-Z0-9]{24,}/g,\n // Values after long-form secret flags (single-char flags like -t/-p/-k are too ambiguous)\n /(?<=--(password|passwd|secret|token|key|api[-_]?key|auth[-_]?token)\\s+)\\S+/gi,\n // export VAR=VALUE where VAR looks sensitive\n /(?<=export\\s+(?:[A-Z_]*(?:TOKEN|SECRET|KEY|PASSWORD|PASS|AUTH|CREDENTIAL)[A-Z_]*)=)\\S+/gi,\n // Inline assignment: VAR_WITH_SENSITIVE_KEYWORD=value cmd (e.g. API_KEY=secret npm start)\n // Lookbehind matches only the variable-name= prefix, so only the value is replaced\n /(?<=[A-Z_][A-Z0-9_]*(?:TOKEN|SECRET|KEY|PASSWORD|PASS|AUTH|CREDENTIAL)[A-Z0-9_]*=)\\S+/gi,\n]\n\nexport function redact(command: string, extraPatterns: string[] = []): string {\n let result = command\n\n const allPatterns = [...BUILTIN_PATTERNS]\n\n for (const pattern of extraPatterns) {\n try {\n allPatterns.push(new RegExp(pattern, 'g'))\n } catch {\n // Invalid regex — skip silently\n }\n }\n\n for (const pattern of allPatterns) {\n // Reset lastIndex for global regexes\n pattern.lastIndex = 0\n result = result.replace(pattern, '[REDACTED]')\n }\n\n return result\n}\n","import { execSync } from 'child_process'\nimport path from 'path'\nimport fs from 'fs'\n\nexport interface GitContext {\n repoName: string | null\n branch: string | null\n}\n\nfunction nameFromRemote(root: string): string | null {\n try {\n const url = execSync('git remote get-url origin', {\n cwd: root,\n timeout: 2000,\n stdio: 'pipe',\n })\n .toString()\n .trim()\n const match = url.match(/\\/([^/]+?)(?:\\.git)?$/)\n return match ? match[1] : null\n } catch {\n return null\n }\n}\n\nfunction nameFromPackageJson(root: string): string | null {\n try {\n const raw = fs.readFileSync(path.join(root, 'package.json'), 'utf-8')\n const pkg = JSON.parse(raw) as { name?: string }\n if (!pkg.name) return null\n return pkg.name.replace(/^@[^/]+\\//, '')\n } catch {\n return null\n }\n}\n\nexport function getGitContext(cwd: string, nameOverride?: string | null): GitContext {\n try {\n const root = execSync('git rev-parse --show-toplevel', {\n cwd,\n timeout: 2000,\n stdio: 'pipe',\n })\n .toString()\n .trim()\n\n const repoName = nameOverride ?? nameFromRemote(root) ?? nameFromPackageJson(root) ?? path.basename(root)\n\n let branch: string | null = null\n try {\n branch =\n execSync('git branch --show-current', {\n cwd,\n timeout: 2000,\n stdio: 'pipe',\n })\n .toString()\n .trim() || null\n } catch {\n // Detached HEAD or not a git repo\n }\n\n return { repoName, branch }\n } catch {\n return { repoName: null, branch: null }\n }\n}\n","import { execSync } from 'child_process'\n\n/**\n * Returns commit subject lines for all commits made between `sha` and HEAD.\n * Returns an empty array if sha is empty, HEAD hasn't moved, or git fails.\n */\nexport function getCommitsSince(sha: string, cwd: string): string[] {\n if (!sha) return []\n try {\n const out = execSync(`git log ${sha}..HEAD --format=%s`, { cwd, timeout: 3000 }).toString().trim()\n return out ? out.split('\\n').filter(Boolean) : []\n } catch {\n return []\n }\n}\n","import fs from 'fs'\nimport path from 'path'\n\nconst HISTORY_FILE = '.aider.chat.history.md'\nconst PROMPT_MAX_LENGTH = 200\n\nexport function readLastAiderPrompt(cwd: string): string | null {\n try {\n const histPath = path.join(cwd, HISTORY_FILE)\n const content = fs.readFileSync(histPath, 'utf-8')\n const matches = [...content.matchAll(/^> (.+)$/gm)]\n if (!matches.length) return null\n return matches[matches.length - 1][1].trim().slice(0, PROMPT_MAX_LENGTH)\n } catch {\n return null\n }\n}\n","import fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport BUILTIN_TOOLS from './ai-tools.json'\nimport { debugLog } from '../utils/logger'\n\nexport interface AIToolEntry {\n tool: string\n displayName: string\n pattern: string\n hook: string | null\n contextSource: string | null\n}\n\nconst USER_REGISTRY_PATH = path.join(os.homedir(), '.workscribe', 'ai-tools.json')\n\nexport function loadAIToolRegistry(): AIToolEntry[] {\n let userEntries: AIToolEntry[] = []\n\n try {\n if (fs.existsSync(USER_REGISTRY_PATH)) {\n const raw = fs.readFileSync(USER_REGISTRY_PATH, 'utf-8')\n const parsed = JSON.parse(raw)\n if (Array.isArray(parsed)) {\n userEntries = parsed\n .filter((entry) => typeof entry.tool === 'string' && typeof entry.pattern === 'string')\n .map((entry) => ({\n tool: entry.tool as string,\n displayName: (entry.displayName as string | undefined) ?? (entry.tool as string),\n pattern: entry.pattern as string,\n hook: (entry.hook as string | null | undefined) ?? null,\n contextSource: (entry.contextSource as string | null | undefined) ?? null,\n }))\n }\n }\n } catch {\n debugLog('registry', 'Failed to load user AI tool registry — using built-ins only')\n }\n\n if (userEntries.length === 0) return BUILTIN_TOOLS as AIToolEntry[]\n\n const userToolSlugs = new Set(userEntries.map((entry) => entry.tool))\n const filteredBuiltins = (BUILTIN_TOOLS as AIToolEntry[]).filter((entry) => !userToolSlugs.has(entry.tool))\n return [...filteredBuiltins, ...userEntries]\n}\n","[\n {\n \"tool\": \"claude\",\n \"displayName\": \"Claude Code\",\n \"pattern\": \"^claude\\\\b\",\n \"hook\": \"claude-code\",\n \"contextSource\": \"hook\"\n },\n {\n \"tool\": \"aider\",\n \"displayName\": \"Aider\",\n \"pattern\": \"^aider\\\\b\",\n \"hook\": null,\n \"contextSource\": \"history-file\"\n },\n {\n \"tool\": \"gemini\",\n \"displayName\": \"Gemini\",\n \"pattern\": \"^gemini\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"gh copilot\",\n \"displayName\": \"GitHub Copilot\",\n \"pattern\": \"^gh\\\\s+copilot\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"cody\",\n \"displayName\": \"Cody\",\n \"pattern\": \"^cody\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"amazon-q\",\n \"displayName\": \"Amazon Q\",\n \"pattern\": \"^q\\\\s+(chat|dev)\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"continue\",\n \"displayName\": \"Continue\",\n \"pattern\": \"^continue\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n },\n {\n \"tool\": \"cursor\",\n \"displayName\": \"Cursor\",\n \"pattern\": \"^cursor\\\\b\",\n \"hook\": null,\n \"contextSource\": null\n }\n]\n","import chalk from 'chalk'\nimport fs from 'fs'\nimport { DEBUG_LOG_PATH } from './paths'\n\nconst isDebug = process.env.WORKSCRIBE_DEBUG === '1'\n\nexport const log = {\n info: (msg: string) => console.log(chalk.cyan('→'), msg),\n success: (msg: string) => console.log(chalk.green('✓'), msg),\n warn: (msg: string) => console.log(chalk.yellow('⚠'), msg),\n error: (msg: string) => console.error(chalk.red('✗'), msg),\n plain: (msg: string) => console.log(msg),\n}\n\nexport function debugLog(context: string, error: unknown): void {\n if (!isDebug) return\n const entry = `[${new Date().toISOString()}] [${context}] ${error instanceof Error ? error.stack : String(error)}\\n`\n try {\n fs.appendFileSync(DEBUG_LOG_PATH, entry, { mode: 0o600 })\n } catch {\n // If we can't write to the debug log, silently ignore\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { PROFILES_DIR } from '../utils/paths'\nimport { readConfig } from '../config'\nimport { isValidProfile } from './schema'\nimport type { Profile, ManifestEntry, ProfileRule } from './schema'\nimport { readCachedManifest } from './fetcher'\nimport { debugLog } from '../utils/logger'\n\n// Matches the Rule interface in patterns.ts — structural compatibility without circular import\ninterface CompiledRule {\n match(cmd: string): { category: string; metadata: Record<string, unknown> } | null\n}\n\nfunction compileRule(profileName: string, rule: ProfileRule): CompiledRule | null {\n let regex: RegExp\n try {\n regex = new RegExp(rule.pattern)\n } catch {\n debugLog('profiles', `Profile \"${profileName}\": invalid pattern \"${rule.pattern}\" — skipping rule`)\n return null\n }\n\n return {\n match(cmd: string) {\n const match = cmd.match(regex)\n if (!match) return null\n const metadata: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(rule.metadata ?? {})) {\n metadata[key] = value.replace(/\\$(\\d+)/g, (_, index: string) => match[Number(index)] ?? '')\n }\n return { category: rule.category, metadata }\n },\n }\n}\n\nfunction loadProfileFromDisk(name: string): Profile | null {\n const filePath = path.join(PROFILES_DIR, `${name}.json`)\n if (!fs.existsSync(filePath)) {\n debugLog('profiles', `Profile \"${name}\" not found in cache — run: workscribe profile add ${name}`)\n return null\n }\n let candidate: unknown\n try {\n candidate = JSON.parse(fs.readFileSync(filePath, 'utf-8'))\n } catch {\n debugLog('profiles', `Profile \"${name}\" contains invalid JSON — skipping`)\n return null\n }\n if (!isValidProfile(candidate)) {\n debugLog('profiles', `Profile \"${name}\" failed schema validation — skipping`)\n return null\n }\n return candidate\n}\n\nfunction loadUserProfiles(): Profile[] {\n if (!fs.existsSync(PROFILES_DIR)) return []\n const activeNames = new Set(readConfig().capture.profiles)\n return fs\n .readdirSync(PROFILES_DIR)\n .filter((file) => file.endsWith('.json') && file !== 'manifest.json')\n .filter((file) => {\n const name = file.replace(/\\.json$/, '')\n return !activeNames.has(name) // avoid double-loading names already in config\n })\n .flatMap((file) => {\n const candidate = loadProfileFromDisk(file.replace(/\\.json$/, ''))\n return candidate ? [candidate] : []\n })\n .filter((profile) => fs.existsSync(path.join(PROFILES_DIR, `${profile.name}.json`)))\n}\n\nexport function getActiveProfileRules(): CompiledRule[] {\n const activeNames = readConfig().capture.profiles\n if (activeNames.length === 0) return []\n\n return activeNames.flatMap((name) => {\n const profile = loadProfileFromDisk(name)\n if (!profile) return []\n return profile.rules.flatMap((rule) => {\n const compiled = compileRule(profile.name, rule)\n return compiled ? [compiled] : []\n })\n })\n}\n\nexport function getActiveProfileAiContexts(): string[] {\n const activeNames = readConfig().capture.profiles\n if (activeNames.length === 0) return []\n\n return activeNames.flatMap((name) => {\n const profile = loadProfileFromDisk(name)\n return profile?.aiContext ? [profile.aiContext] : []\n })\n}\n\nexport function getCachedProfiles(): Profile[] {\n if (!fs.existsSync(PROFILES_DIR)) return []\n return fs\n .readdirSync(PROFILES_DIR)\n .filter((file) => file.endsWith('.json') && file !== 'manifest.json')\n .flatMap((file) => {\n const profile = loadProfileFromDisk(file.replace(/\\.json$/, ''))\n return profile ? [profile] : []\n })\n}\n\nexport function detectProfilesForDirectory(dir: string): ManifestEntry[] {\n const manifest = readCachedManifest()\n if (!manifest) return []\n\n const activeNames = new Set(readConfig().capture.profiles)\n\n return manifest.filter((entry) => {\n if (activeNames.has(entry.name)) return false\n const indicatorFiles = entry.detect?.files ?? []\n return indicatorFiles.length > 0 && indicatorFiles.every((file) => fs.existsSync(path.join(dir, file)))\n })\n}\n\nexport { loadUserProfiles }\n","import fs from 'fs'\nimport { CONFIG_PATH } from '../utils/paths'\n\nexport interface WorkscribeConfig {\n ai: {\n provider: string // 'anthropic' | 'openai' | 'ollama' | 'openai-compatible'\n apiKey: string\n model: string\n baseUrl: string\n }\n session: {\n idleTimeout: number // minutes\n }\n capture: {\n ignore: string[]\n aiTools: boolean\n includeAiderPrompt: boolean\n profiles: string[]\n }\n redact: {\n extra: string[]\n }\n summary: {\n format: 'markdown' | 'json'\n // Categories re-included in the AI payload (overrides built-in exclusions).\n // Excluded by default: exploring, other, linting.\n // Example: [\"linting\"] to include lint pass/fail in summaries.\n includeCategories?: string[]\n }\n projects?: Record<string, string> // absolute path → display name override\n integrations?: {\n slackWebhook?: string\n webhook?: string\n }\n}\n\nconst DEFAULTS: WorkscribeConfig = {\n ai: {\n provider: '',\n apiKey: '',\n model: '',\n baseUrl: '',\n },\n session: {\n idleTimeout: 30,\n },\n capture: {\n ignore: ['cd', 'ls', 'll', 'la', 'ls -la', 'ls -l', 'ls -a', 'pwd', 'clear', 'exit', 'history', 'man'],\n aiTools: true,\n includeAiderPrompt: true,\n profiles: [],\n },\n redact: {\n extra: [],\n },\n summary: {\n format: 'markdown',\n },\n}\n\nexport function readConfig(): WorkscribeConfig {\n if (!fs.existsSync(CONFIG_PATH)) return { ...DEFAULTS }\n try {\n const raw = fs.readFileSync(CONFIG_PATH, 'utf-8')\n const parsed = JSON.parse(raw)\n return deepMerge(DEFAULTS, parsed)\n } catch {\n return { ...DEFAULTS }\n }\n}\n\nexport function writeConfig(config: WorkscribeConfig): void {\n fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { encoding: 'utf-8', mode: 0o600 })\n // Enforce permissions on existing files (mode only applies on creation above)\n try {\n fs.chmodSync(CONFIG_PATH, 0o600)\n } catch {\n /* ignore */\n }\n}\n\nexport function getConfigValue(config: WorkscribeConfig, key: string): unknown {\n const parts = key.split('.')\n let cur: unknown = config\n for (const part of parts) {\n if (cur == null || typeof cur !== 'object') return undefined\n cur = (cur as Record<string, unknown>)[part]\n }\n return cur\n}\n\nexport function setConfigValue(config: WorkscribeConfig, key: string, value: string): WorkscribeConfig {\n const parts = key.split('.')\n const result = JSON.parse(JSON.stringify(config)) as WorkscribeConfig\n let cur = result as unknown as Record<string, unknown>\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]\n if (cur[part] == null || typeof cur[part] !== 'object') {\n cur[part] = {}\n }\n cur = cur[part] as Record<string, unknown>\n }\n const lastKey = parts[parts.length - 1]\n // Coerce value type\n if (value === 'true') cur[lastKey] = true\n else if (value === 'false') cur[lastKey] = false\n else if (!isNaN(Number(value))) cur[lastKey] = Number(value)\n else cur[lastKey] = value\n return result\n}\n\nfunction deepMerge<T extends object>(defaults: T, overrides: Partial<T>): T {\n const result = { ...defaults }\n for (const key of Object.keys(overrides) as (keyof T)[]) {\n const val = overrides[key]\n if (val !== null && typeof val === 'object' && !Array.isArray(val) && typeof defaults[key] === 'object') {\n result[key] = deepMerge(defaults[key] as object, val as object) as T[keyof T]\n } else if (val !== undefined) {\n result[key] = val as T[keyof T]\n }\n }\n return result\n}\n","export interface ProfileRule {\n pattern: string\n category: string\n metadata?: Record<string, string>\n}\n\nexport interface Profile {\n name: string\n displayName: string\n version: string\n detect?: { files?: string[] }\n rules: ProfileRule[]\n aiContext?: string\n}\n\nexport interface ManifestEntry {\n name: string\n displayName: string\n tags: string[]\n description: string\n keywords: string[]\n detect?: { files?: string[] }\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n\nfunction isValidRule(rule: unknown): boolean {\n if (!rule || typeof rule !== 'object') return false\n const { pattern, category } = rule as Record<string, unknown>\n return isNonEmptyString(pattern) && isNonEmptyString(category)\n}\n\nexport function isValidProfile(candidate: unknown): candidate is Profile {\n if (!candidate || typeof candidate !== 'object') return false\n const { name, displayName, version, rules } = candidate as Record<string, unknown>\n if (!isNonEmptyString(name) || !isNonEmptyString(displayName) || !isNonEmptyString(version)) return false\n if (!Array.isArray(rules)) return false\n return rules.every(isValidRule)\n}\n\nexport function isValidManifest(m: unknown): m is ManifestEntry[] {\n return (\n Array.isArray(m) &&\n m.every((e) => e && typeof e === 'object' && typeof (e as Record<string, unknown>).name === 'string')\n )\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { PROFILES_DIR } from '../utils/paths'\nimport { isValidProfile, isValidManifest } from './schema'\nimport type { ManifestEntry, Profile } from './schema'\nimport { debugLog } from '../utils/logger'\n\nconst REGISTRY_BASE = 'https://raw.githubusercontent.com/workscribe/profiles/main'\n\nfunction manifestCachePath(): string {\n return path.join(PROFILES_DIR, 'manifest.json')\n}\n\nexport async function fetchManifest(): Promise<ManifestEntry[]> {\n const response = await fetch(`${REGISTRY_BASE}/manifest.json`)\n if (!response.ok) throw new Error(`Registry unreachable (${response.status})`)\n const data: unknown = await response.json()\n if (!isValidManifest(data)) throw new Error('Manifest format unrecognised')\n return data\n}\n\nexport async function fetchProfile(name: string): Promise<Profile> {\n const response = await fetch(`${REGISTRY_BASE}/${name}.json`)\n if (response.status === 404) throw new Error(`Profile \"${name}\" not found in registry`)\n if (!response.ok) throw new Error(`Registry unreachable (${response.status})`)\n const data: unknown = await response.json()\n if (!isValidProfile(data)) throw new Error(`Profile \"${name}\" failed schema validation`)\n return data\n}\n\nexport async function installProfile(name: string): Promise<void> {\n ensureProfilesDir()\n const profile = await fetchProfile(name)\n const dest = path.join(PROFILES_DIR, `${name}.json`)\n fs.writeFileSync(dest, JSON.stringify(profile, null, 2), { encoding: 'utf-8', mode: 0o600 })\n debugLog('profiles', `Installed profile \"${name}\" to ${dest}`)\n}\n\nexport async function cacheManifest(): Promise<ManifestEntry[]> {\n ensureProfilesDir()\n const manifest = await fetchManifest()\n fs.writeFileSync(manifestCachePath(), JSON.stringify(manifest, null, 2), { encoding: 'utf-8', mode: 0o600 })\n return manifest\n}\n\nexport function readCachedManifest(): ManifestEntry[] | null {\n if (!fs.existsSync(manifestCachePath())) return null\n try {\n const data: unknown = JSON.parse(fs.readFileSync(manifestCachePath(), 'utf-8'))\n return isValidManifest(data) ? data : null\n } catch {\n return null\n }\n}\n\nfunction ensureProfilesDir(): void {\n if (!fs.existsSync(PROFILES_DIR)) {\n fs.mkdirSync(PROFILES_DIR, { recursive: true, mode: 0o700 })\n }\n}\n","import { loadAIToolRegistry } from '../config/registry'\nimport { getActiveProfileRules } from '../profiles/loader'\nimport { debugLog } from '../utils/logger'\n\nexport interface NormalizedEvent {\n category: string\n metadata: Record<string, unknown>\n}\n\ninterface Rule {\n match(cmd: string): NormalizedEvent | null\n}\n\nfunction makeRule(\n pattern: RegExp,\n category: string,\n extract: (match: RegExpMatchArray, cmd: string) => Record<string, unknown> = () => ({})\n): Rule {\n return {\n match(cmd) {\n const m = cmd.match(pattern)\n if (!m) return null\n return { category, metadata: extract(m, cmd) }\n },\n }\n}\n\n// Extract package names from install commands like: npm install foo bar\nfunction extractPackages(cmd: string, afterKeyword: string): string[] {\n const idx = cmd.indexOf(afterKeyword)\n if (idx === -1) return []\n return cmd\n .slice(idx + afterKeyword.length)\n .trim()\n .split(/\\s+/)\n .filter((part) => part && !part.startsWith('-'))\n}\n\nconst BASE_RULES: Rule[] = [\n // ─── Git operations ───────────────────────────────────────────────────────\n makeRule(/^git\\s+commit\\b/, 'shipping', (_m, cmd) => {\n const msgMatch = cmd.match(/-m\\s+[\"']?([^\"']+)[\"']?/)\n return { message: msgMatch ? msgMatch[1].trim() : null }\n }),\n\n makeRule(/^git\\s+push\\b/, 'shipping', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { remote: parts[2] ?? 'origin', branch: parts[3] ?? null }\n }),\n\n makeRule(/^git\\s+(pull|fetch)\\b/, 'versioning', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { subcommand: parts[1], remote: parts[2] ?? 'origin' }\n }),\n\n makeRule(/^git\\s+(checkout|switch)\\b/, 'versioning', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n const branch = parts.find((part) => !part.startsWith('-') && part !== 'git' && part !== parts[1])\n return { branch: branch ?? null }\n }),\n\n makeRule(/^git\\s+(merge|rebase)\\b/, 'shipping', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { subcommand: parts[1], target: parts[2] ?? null }\n }),\n\n makeRule(/^git\\s+stash\\b/, 'versioning', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { subcommand: parts[2] ?? 'push' }\n }),\n\n makeRule(/^git\\s+/, 'versioning', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { subcommand: parts[1] ?? null }\n }),\n\n // ─── Releasing ────────────────────────────────────────────────────────────\n makeRule(/^npm\\s+publish\\b/, 'releasing', () => ({ tool: 'npm' })),\n makeRule(/^cargo\\s+publish\\b/, 'releasing', () => ({ tool: 'cargo' })),\n makeRule(/^gem\\s+push\\b/, 'releasing', () => ({ tool: 'gem' })),\n makeRule(/^docker\\s+push\\b/, 'releasing', (_m, cmd) => ({ tool: 'docker', image: cmd.split(/\\s+/)[2] ?? null })),\n makeRule(/^gh\\s+release\\b/, 'releasing', (_m, cmd) => ({ tool: 'gh', subcommand: cmd.split(/\\s+/)[2] ?? null })),\n makeRule(/^fly\\s+(deploy|launch)\\b/, 'releasing', (match) => ({ tool: 'fly', subcommand: match[1] })),\n makeRule(/^vercel\\s+(deploy|build|--prod)\\b/, 'releasing', () => ({ tool: 'vercel' })),\n makeRule(/^netlify\\s+deploy\\b/, 'releasing', () => ({ tool: 'netlify' })),\n makeRule(/^railway\\s+up\\b/, 'releasing', () => ({ tool: 'railway' })),\n makeRule(/^wrangler\\s+deploy\\b/, 'releasing', () => ({ tool: 'wrangler' })),\n\n // ─── Dependencies ─────────────────────────────────────────────────────────\n makeRule(/^npm\\s+(install|i|add)\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'npm',\n packages: extractPackages(cmd, cmd.includes('install') ? 'install' : cmd.includes(' i ') ? ' i ' : 'add'),\n })),\n\n makeRule(/^(yarn|pnpm)\\s+(install|add)\\b/, 'dependencies', (m, cmd) => ({\n tool: m[1],\n packages: extractPackages(cmd, 'add'),\n })),\n\n makeRule(/^bun\\s+(install|add)\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'bun',\n packages: extractPackages(cmd, 'add'),\n })),\n\n makeRule(/^pip\\s+(install)\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'pip',\n packages: extractPackages(cmd, 'install'),\n })),\n\n makeRule(/^cargo\\s+add\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'cargo',\n packages: extractPackages(cmd, 'add'),\n })),\n\n makeRule(/^(brew)\\s+install\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'brew',\n packages: extractPackages(cmd, 'install'),\n })),\n\n makeRule(/^go\\s+get\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'go',\n packages: extractPackages(cmd, 'get'),\n })),\n\n makeRule(/^npm\\s+(uninstall|remove|rm)\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'npm',\n packages: extractPackages(cmd, cmd.split(/\\s+/)[1]),\n })),\n\n makeRule(/^(yarn|pnpm)\\s+remove\\b/, 'dependencies', (m, cmd) => ({\n tool: m[1],\n packages: extractPackages(cmd, 'remove'),\n })),\n\n makeRule(/^bun\\s+remove\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'bun',\n packages: extractPackages(cmd, 'remove'),\n })),\n\n makeRule(/^pip\\s+uninstall\\b/, 'dependencies', (_m, cmd) => ({\n tool: 'pip',\n packages: extractPackages(cmd, 'uninstall'),\n })),\n\n // Runtime version managers\n makeRule(/^nvm\\b/, 'dependencies', (_m, cmd) => ({ tool: 'nvm', subcommand: cmd.split(/\\s+/)[1] ?? null })),\n makeRule(/^(fnm|volta)\\b/, 'dependencies', (m, cmd) => ({ tool: m[1], subcommand: cmd.split(/\\s+/)[1] ?? null })),\n makeRule(/^(rbenv|pyenv|asdf)\\b/, 'dependencies', (m, cmd) => ({\n tool: m[1],\n subcommand: cmd.split(/\\s+/)[1] ?? null,\n })),\n\n // ─── Tests ────────────────────────────────────────────────────────────────\n makeRule(/^npm\\s+(test|run\\s+test)\\b/, 'testing', () => ({ tool: 'npm' })),\n makeRule(/^yarn\\s+test\\b/, 'testing', () => ({ tool: 'yarn' })),\n makeRule(/^pnpm\\s+test\\b/, 'testing', () => ({ tool: 'pnpm' })),\n makeRule(/^bun\\s+test\\b/, 'testing', () => ({ tool: 'bun' })),\n makeRule(/^(jest|vitest)\\b/, 'testing', (match) => ({ tool: match[1] })),\n makeRule(/^pytest\\b/, 'testing', () => ({ tool: 'pytest' })),\n makeRule(/^go\\s+test\\b/, 'testing', () => ({ tool: 'go' })),\n makeRule(/^cargo\\s+test\\b/, 'testing', () => ({ tool: 'cargo' })),\n makeRule(/^rspec\\b/, 'testing', () => ({ tool: 'rspec' })),\n makeRule(/^(php\\s+)?phpunit\\b/, 'testing', () => ({ tool: 'phpunit' })),\n\n // ─── Build ────────────────────────────────────────────────────────────────\n makeRule(/^npm\\s+run\\s+build\\b/, 'building', () => ({ tool: 'npm' })),\n makeRule(/^(yarn|pnpm)\\s+build\\b/, 'building', (match) => ({ tool: match[1] })),\n makeRule(/^bun\\s+run\\s+build\\b/, 'building', () => ({ tool: 'bun' })),\n makeRule(/^(make|gmake)\\b/, 'building', (match) => ({ tool: match[1] })),\n makeRule(/^cargo\\s+build\\b/, 'building', () => ({ tool: 'cargo' })),\n makeRule(/^go\\s+build\\b/, 'building', () => ({ tool: 'go' })),\n makeRule(/^docker\\s+build\\b/, 'building', () => ({ tool: 'docker' })),\n makeRule(/^(mvn|gradle)\\b/, 'building', (match) => ({ tool: match[1] })),\n\n // ─── Dev server / running ─────────────────────────────────────────────────\n makeRule(/^npm\\s+run\\s+(dev|start|serve)\\b/, 'running', (_m, cmd) => ({\n tool: 'npm',\n script: cmd.split(/\\s+/)[2],\n })),\n makeRule(/^(yarn|pnpm)\\s+(dev|start)\\b/, 'running', (match) => ({ tool: match[1], script: match[2] })),\n makeRule(/^bun\\s+run\\s+(dev|start|serve)\\b/, 'running', (_m, cmd) => ({\n tool: 'bun',\n script: cmd.split(/\\s+/)[2],\n })),\n makeRule(/^python\\s+.*manage\\.py\\s+runserver\\b/, 'running', () => ({ tool: 'django' })),\n\n // ─── Infrastructure ───────────────────────────────────────────────────────\n makeRule(/^ssh\\b/, 'infrastructure', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: 'ssh', target: parts[parts.length - 1] }\n }),\n\n makeRule(/^kubectl\\b/, 'infrastructure', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: 'kubectl', subcommand: parts[1] ?? null }\n }),\n\n makeRule(/^(helm|terraform|pulumi)\\b/, 'infrastructure', (m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: m[1], subcommand: parts[1] ?? null }\n }),\n\n makeRule(/^docker\\s+(run|compose|ps|stop|start|rm|exec)\\b/, 'infrastructure', (_m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: 'docker', subcommand: parts[1] }\n }),\n\n makeRule(/^(aws|gcloud|az)\\b/, 'infrastructure', (m, cmd) => {\n const parts = cmd.split(/\\s+/)\n return { tool: m[1], subcommand: parts[1] ?? null }\n }),\n\n // ─── Database ─────────────────────────────────────────────────────────────\n makeRule(/^(psql|pgcli)\\b/, 'database', (m) => ({ tool: m[1] })),\n makeRule(/^(mysql|mycli)\\b/, 'database', (m) => ({ tool: m[1] })),\n makeRule(/^sqlite3\\b/, 'database', () => ({ tool: 'sqlite3' })),\n makeRule(/^(mongosh|mongo)\\b/, 'database', (m) => ({ tool: m[1] })),\n makeRule(/^redis-cli\\b/, 'database', () => ({ tool: 'redis-cli' })),\n\n // ─── npx ─────────────────────────────────────────────────────────────────\n makeRule(/^npx\\s+(jest|vitest|mocha|ava|tap)\\b/, 'testing', (_m, cmd) => ({\n tool: cmd.split(/\\s+/)[1],\n })),\n makeRule(/^npx\\s+tsc\\b/, 'building', () => ({ tool: 'tsc' })),\n makeRule(/^npx\\s+(eslint|tslint|biome)\\b/, 'linting', (_m, cmd) => ({\n tool: cmd.split(/\\s+/)[1],\n })),\n makeRule(/^npx\\s+(prettier|dprint)\\b/, 'linting', (_m, cmd) => ({\n tool: cmd.split(/\\s+/)[1],\n })),\n makeRule(/^npx\\s+\\S+/, 'running', (_m, cmd) => ({\n tool: cmd.split(/\\s+/)[1],\n })),\n\n // ─── Scripts ──────────────────────────────────────────────────────────────\n makeRule(/^(bash|sh|zsh|fish)\\s+\\S+/, 'running', (match) => ({ shell: match[1] })),\n makeRule(/^node\\s+\\S+\\.(?:js|mjs|cjs)\\b/, 'running', () => ({ runtime: 'node' })),\n makeRule(/^python3?\\s+\\S+\\.py\\b/, 'running', () => ({ runtime: 'python' })),\n\n // ─── Linting / code quality ───────────────────────────────────────────────\n makeRule(/^(eslint|tslint|biome)\\b/, 'linting', (match) => ({ tool: match[1] })),\n makeRule(/^(prettier|dprint)\\b/, 'linting', (match) => ({ tool: match[1] })),\n\n // ─── generic run scripts ──────────────────────────────────────────────────\n makeRule(/^npm\\s+run\\s+\\S+/, 'running', (_m, cmd) => ({\n tool: 'npm',\n script: cmd.split(/\\s+/)[2],\n })),\n\n makeRule(/^bun\\s+run\\s+\\S+/, 'running', (_m, cmd) => ({\n tool: 'bun',\n script: cmd.split(/\\s+/)[2],\n })),\n\n // ─── Code search ─────────────────────────────────────────────────────────\n makeRule(/^(grep|egrep|fgrep)\\b/, 'exploring', (match) => ({ tool: match[1] })),\n makeRule(/^(rg|ag|ack|ripgrep)\\b/, 'exploring', (match) => ({ tool: match[1] })),\n makeRule(/^find\\s/, 'exploring', () => ({ tool: 'find' })),\n\n // ─── Code read ────────────────────────────────────────────────────────────\n makeRule(/^(cat|bat|less|more)\\s+\\S+/, 'exploring', (match) => ({ tool: match[1] })),\n makeRule(/^(head|tail)\\b/, 'exploring', (match) => ({ tool: match[1] })),\n\n // ─── File operations ──────────────────────────────────────────────────────\n makeRule(/^(cp|rsync)\\b/, 'files', (match) => ({ tool: match[1] })),\n makeRule(/^(mv)\\b/, 'files', () => ({ tool: 'mv' })),\n makeRule(/^(rm|rmdir)\\b/, 'files', (match) => ({ tool: match[1] })),\n makeRule(/^(mkdir|touch|ln)\\b/, 'files', (match) => ({ tool: match[1] })),\n makeRule(/^(chmod|chown|chgrp)\\b/, 'files', (match) => ({ tool: match[1] })),\n\n // ─── Environment ──────────────────────────────────────────────────────────\n makeRule(/^export\\s+\\w+=/, 'files', (_m, cmd) => {\n const varName = cmd.match(/^export\\s+(\\w+)=/)?.[1] ?? null\n return { variable: varName }\n }),\n makeRule(/^source\\s+/, 'files', () => ({})),\n]\n\nfunction aiToolRules(): Rule[] {\n return loadAIToolRegistry().flatMap((entry) => {\n try {\n return [makeRule(new RegExp(entry.pattern), 'ai_session', () => ({ tool: entry.tool }))]\n } catch {\n debugLog('registry', `Skipping tool \"${entry.tool}\" — invalid pattern: ${entry.pattern}`)\n return []\n }\n })\n}\n\nexport function buildRules(profileRules: Array<{ match(cmd: string): NormalizedEvent | null }> = []): Rule[] {\n return [...BASE_RULES, ...profileRules, ...aiToolRules()]\n}\n\nexport const RULES: Rule[] = buildRules(getActiveProfileRules())\n\nexport function normalizeCommand(command: string): NormalizedEvent {\n let trimmed = command.trim().replace(/\\s+/g, ' ')\n\n // Strip `git -C <path>` prefix so rules match regardless of working directory flag\n trimmed = trimmed.replace(/^(git)\\s+-C\\s+\\S+\\s+/, '$1 ')\n\n for (const rule of RULES) {\n const result = rule.match(trimmed)\n if (result) return result\n }\n\n return { category: 'other', metadata: {} }\n}\n","import type { EventRow } from '../db/types'\n\nfunction normalizeForFilter(cmd: string): string {\n return cmd.trim().replace(/\\s+/g, ' ')\n}\n\n// Always filtered regardless of user config — internal tool noise\nconst BUILTIN_IGNORE = new Set(['workscribe'])\n\n/**\n * Returns true if the command should be dropped (noise / ignore list).\n */\nexport function shouldFilter(command: string, ignoreList: string[]): boolean {\n const normalized = normalizeForFilter(command)\n if (!normalized) return true\n\n const baseCmd = normalized.split(' ')[0]\n\n // Built-in filter: always excluded, not user-configurable\n if (BUILTIN_IGNORE.has(baseCmd)) return true\n\n // User-configurable ignore list\n const normalizedIgnore = ignoreList.map(normalizeForFilter)\n if (normalizedIgnore.includes(normalized)) return true\n if (normalizedIgnore.includes(baseCmd)) return true\n\n return false\n}\n\n/**\n * Returns true if this command is a duplicate of the last event\n * (same command + same cwd within the dedup window).\n */\nexport function isDuplicate(\n command: string,\n cwd: string,\n lastEvent: Pick<EventRow, 'command' | 'cwd' | 'captured_at'> | undefined,\n dedupWindowMs = 5000,\n now = Date.now()\n): boolean {\n if (!lastEvent) return false\n const lastTime = new Date(lastEvent.captured_at).getTime()\n return lastEvent.command === normalizeForFilter(command) && lastEvent.cwd === cwd && now - lastTime < dedupWindowMs\n}\n","import { Command } from 'commander'\nimport { captureCommand } from '../capture'\nimport { debugLog } from '../utils/logger'\n\nconst CAPTURE_HANG_TIMEOUT_MS = 5_000\n\nexport function registerCapture(program: Command): void {\n // Internal command — called by the shell hook, not by the user\n program\n .command('_capture')\n .description('Internal: capture a shell command event (called by shell hook)')\n .option('--cmd <command>', 'command that was executed')\n .option('--cwd <path>', 'working directory')\n .option('--exit <code>', 'exit code', parseInt)\n .option('--duration <ms>', 'duration in milliseconds', parseInt)\n .option('--git-before <sha>', 'git HEAD SHA before this command ran')\n .action((opts) => {\n // Prevent background process accumulation if the process hangs (e.g. SQLite locked).\n // unref() allows a natural exit to happen immediately without waiting for the timer.\n const hangGuard = setTimeout(() => process.exit(0), CAPTURE_HANG_TIMEOUT_MS)\n hangGuard.unref()\n\n // Never surface errors to the terminal — this runs silently in the background\n try {\n if (!opts.cmd || !opts.cwd) return\n captureCommand({\n command: opts.cmd,\n cwd: opts.cwd,\n exitCode: opts.exit ?? null,\n durationMs: opts.duration ?? null,\n gitBefore: opts.gitBefore ?? undefined,\n })\n } catch (err) {\n debugLog('_capture', err)\n }\n })\n}\n","import { Command } from 'commander'\nimport { captureCommand } from '../capture'\nimport { readConfig } from '../config'\nimport { debugLog } from '../utils/logger'\n\n/** Parses a Claude Code PostToolUse stdin payload. Returns null if required fields are missing. */\nexport function parseHookPayload(raw: string): { command: string; cwd: string } | null {\n if (!raw.trim()) return null\n const payload = JSON.parse(raw) as Record<string, unknown>\n const toolInput = payload.tool_input as Record<string, unknown> | undefined\n const command = typeof toolInput?.command === 'string' ? toolInput.command : null\n const cwd = typeof payload.cwd === 'string' ? payload.cwd : null\n if (!command || !cwd) return null\n return { command, cwd }\n}\n\nexport function registerHook(program: Command): void {\n // Internal command — called by AI tool hooks (e.g. Claude Code PostToolUse), not by the user\n program\n .command('_hook')\n .description('Internal: capture events from AI tool hooks (stdin JSON payload)')\n .option('--source <source>', 'hook source identifier (e.g. claude-code)')\n .action((opts: { source?: string }) => {\n let raw = ''\n process.stdin.setEncoding('utf-8')\n process.stdin.on('data', (chunk: string) => {\n raw += chunk\n })\n process.stdin.on('end', () => {\n try {\n if (readConfig().capture.aiTools === false) return\n const parsed = parseHookPayload(raw)\n if (!parsed) return\n captureCommand({\n command: parsed.command,\n cwd: parsed.cwd,\n exitCode: null,\n durationMs: null,\n source: opts.source,\n })\n } catch (err) {\n debugLog('_hook', err)\n }\n })\n })\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport path from 'path'\nimport os from 'os'\nimport prompts from 'prompts'\nimport chalk from 'chalk'\nimport { WORKSCRIBE_DIR, CONFIG_PATH, PROFILES_DIR } from '../utils/paths'\nimport { readConfig, writeConfig } from '../config'\nimport { detectProfilesForDirectory } from '../profiles/loader'\nimport { installProfile, cacheManifest } from '../profiles/fetcher'\nimport { getDb } from '../db'\nimport { getProvider } from '../ai/router'\nimport { log } from '../utils/logger'\nimport { loadAIToolRegistry } from '../config/registry'\nimport { isHookInstalled, isHookOutdated, installHook, updateHook } from '../capture/shell-hook'\nimport { AI_HOOK_INTEGRATIONS } from '../capture/hooks'\n\nfunction detectShell(): { name: string; rcFile: string } | null {\n const shell = process.env.SHELL ?? ''\n if (shell.includes('zsh')) return { name: 'zsh', rcFile: path.join(os.homedir(), '.zshrc') }\n if (shell.includes('bash')) return { name: 'bash', rcFile: path.join(os.homedir(), '.bashrc') }\n return null\n}\n\nfunction step(current: number, total: number, label: string): void {\n log.plain(chalk.bold(`\\n [${current}/${total}] ${label}`))\n}\n\nexport function registerInit(program: Command): void {\n program\n .command('init')\n .description('Set up Workscribe and install or update shell hooks')\n .action(async () => {\n const TOTAL_STEPS = 5\n log.plain(chalk.bold('\\n Workscribe — Developer Work Journal\\n'))\n\n // ── Step 1: Data directory ────────────────────────────────────────────────\n step(1, TOTAL_STEPS, 'Creating data directory')\n\n if (!fs.existsSync(WORKSCRIBE_DIR)) {\n fs.mkdirSync(WORKSCRIBE_DIR, { recursive: true, mode: 0o700 })\n log.success(`Created ${WORKSCRIBE_DIR}`)\n } else {\n try {\n fs.chmodSync(WORKSCRIBE_DIR, 0o700)\n } catch {\n /* ignore */\n }\n log.info(`${WORKSCRIBE_DIR} already exists`)\n }\n if (!fs.existsSync(PROFILES_DIR)) {\n fs.mkdirSync(PROFILES_DIR, { recursive: true, mode: 0o700 })\n }\n\n // ── Step 2: Database ──────────────────────────────────────────────────────\n step(2, TOTAL_STEPS, 'Initialising database')\n getDb()\n log.success('Database ready')\n\n // ── Step 3: Shell hook ────────────────────────────────────────────────────\n step(3, TOTAL_STEPS, 'Installing shell hook')\n\n const shell = detectShell()\n if (!shell) {\n log.warn('Could not detect shell. Supported: zsh, bash')\n log.plain(`Manually add the hook from: ${chalk.cyan('shell/hook.zsh')} or ${chalk.cyan('shell/hook.bash')}`)\n } else {\n const hookFile = path.join(__dirname, '..', 'shell', `hook.${shell.name}`)\n if (!fs.existsSync(hookFile)) {\n log.warn(`Hook template not found at ${hookFile}`)\n } else {\n const hookContent = fs.readFileSync(hookFile, 'utf-8')\n if (!fs.existsSync(shell.rcFile)) fs.writeFileSync(shell.rcFile, '')\n\n if (!isHookInstalled(shell.rcFile)) {\n log.plain('')\n log.plain(chalk.dim(' Workscribe adds a lightweight hook to your shell that captures each'))\n log.plain(chalk.dim(' command you run — the text, exit code, duration, and working directory.'))\n log.plain(chalk.dim(' It runs in the background and adds no latency to your terminal.'))\n log.plain(chalk.dim(' Credentials and secrets are redacted before anything is stored.'))\n log.plain('')\n installHook(shell.rcFile, hookContent)\n log.success(`Shell hook installed in ${shell.rcFile}`)\n } else if (isHookOutdated(shell.rcFile, hookContent)) {\n const { update } = await prompts({\n type: 'confirm',\n name: 'update',\n message: `Shell hook in ${shell.rcFile} is outdated. Update?`,\n initial: true,\n })\n if (update) {\n updateHook(shell.rcFile, hookContent)\n log.success(`Shell hook updated in ${shell.rcFile}`)\n } else {\n log.info('Shell hook update skipped')\n }\n } else {\n log.info(`Shell hook up to date in ${shell.rcFile}`)\n }\n }\n }\n\n // ── Step 4: AI tools ──────────────────────────────────────────────────────\n step(4, TOTAL_STEPS, 'Detecting AI coding tools')\n\n const installedTools = loadAIToolRegistry().filter(\n (entry) => entry.hook !== null && AI_HOOK_INTEGRATIONS[entry.hook!]?.isInstalled()\n )\n\n if (installedTools.length === 0) {\n log.info('No AI coding tools detected — re-run workscribe init after installing one')\n } else {\n for (const tool of installedTools) {\n const integration = AI_HOOK_INTEGRATIONS[tool.hook!]!\n\n if (integration.isHookInstalled()) {\n log.info(`${integration.displayName} session hook already installed`)\n } else {\n const { install } = await prompts({\n type: 'confirm',\n name: 'install',\n message: `${integration.displayName} detected. Install session capture hook?`,\n initial: false,\n })\n if (install) {\n integration.install()\n log.success(`${integration.displayName} session hook installed`)\n } else {\n log.info(`${integration.displayName} hook skipped — re-run workscribe init to install later`)\n }\n }\n }\n }\n\n // Profile detection (part of environment scan, no separate step)\n const config = readConfig()\n try {\n await cacheManifest()\n const detected = detectProfilesForDirectory(process.cwd())\n const alreadyActive = new Set(config.capture.profiles)\n const toPrompt = detected.filter((entry) => !alreadyActive.has(entry.name))\n\n if (toPrompt.length > 0) {\n log.plain('')\n for (const entry of toPrompt) {\n const { install } = await prompts({\n type: 'confirm',\n name: 'install',\n message: `${entry.displayName} project detected. Enable the ${entry.displayName} profile?`,\n initial: true,\n })\n if (install) {\n await installProfile(entry.name)\n config.capture.profiles = [...new Set([...config.capture.profiles, entry.name])]\n log.success(`${entry.displayName} profile enabled`)\n }\n }\n writeConfig(config)\n } else if (detected.length === 0) {\n log.info('No project profiles detected — run workscribe profile detect from your project directory')\n }\n } catch {\n log.info('Could not reach profile registry — run workscribe profile detect after connecting')\n }\n\n // ── Step 5: AI provider ───────────────────────────────────────────────────\n step(5, TOTAL_STEPS, 'Configuring AI provider')\n\n let providerConfigured = !!config.ai.provider\n\n if (config.ai.provider) {\n log.info(`AI provider already configured: ${chalk.cyan(config.ai.provider)}`)\n } else {\n log.plain('')\n const { provider } = await prompts({\n type: 'select',\n name: 'provider',\n message: 'Which AI provider do you want to use?',\n choices: [\n { title: 'Anthropic (Claude) — requires API key', value: 'anthropic' },\n { title: 'OpenAI — requires API key', value: 'openai' },\n { title: 'Ollama (local) — free, runs on your machine', value: 'ollama' },\n { title: 'Other (OpenAI-compatible) — Groq, Together, Mistral…', value: 'openai-compatible' },\n { title: 'Skip — configure later', value: 'skip' },\n ],\n })\n\n if (!provider || provider === 'skip') {\n providerConfigured = false\n log.info('Skipped — run later: workscribe config set ai.provider <provider>')\n } else {\n config.ai.provider = provider\n\n if (provider === 'ollama') {\n log.plain(`\\n ${chalk.dim('Make sure Ollama is running: ollama serve')}`)\n log.plain(\n ` ${chalk.dim('Default model: llama3 (change with: workscribe config set ai.model <model>)')}\\n`\n )\n } else {\n const { apiKey } = await prompts({\n type: 'password',\n name: 'apiKey',\n message: `Enter your ${provider === 'openai-compatible' ? '' : provider + ' '}API key:`,\n })\n if (apiKey) config.ai.apiKey = apiKey\n\n if (provider === 'openai-compatible') {\n const { baseUrl } = await prompts({\n type: 'text',\n name: 'baseUrl',\n message: 'Enter the base URL (e.g. https://api.groq.com/openai/v1):',\n })\n if (baseUrl) config.ai.baseUrl = baseUrl\n }\n }\n\n // Validate the key with a lightweight test call\n log.plain('')\n log.info(`Validating ${chalk.cyan(provider)} connection…`)\n try {\n const testProvider = getProvider(config)\n await testProvider.validate()\n log.success('API key verified')\n writeConfig(config)\n providerConfigured = true\n } catch (error) {\n log.warn(`Validation failed: ${(error as Error).message}`)\n const { retry } = await prompts({\n type: 'confirm',\n name: 'retry',\n message: 'Save anyway and configure later?',\n initial: false,\n })\n if (retry) {\n writeConfig(config)\n providerConfigured = false\n log.info('Config saved — run workscribe config set ai.apiKey <key> to update')\n } else {\n log.info('API key not saved — run workscribe init again to configure')\n providerConfigured = false\n }\n }\n }\n }\n\n // ── Config file ───────────────────────────────────────────────────────────\n if (!fs.existsSync(CONFIG_PATH)) {\n writeConfig(config)\n }\n\n // ── What to do next ───────────────────────────────────────────────────────\n log.plain('')\n log.plain(chalk.bold(' Setup complete!'))\n log.plain('')\n\n if (shell) {\n log.plain(` Activate capture now:`)\n log.plain(` ${chalk.cyan(`source ${shell.rcFile}`)}`)\n log.plain(` Or restart your terminal.`)\n log.plain('')\n }\n\n if (providerConfigured) {\n log.plain(` Then run a few commands and generate your first summary:`)\n log.plain(` ${chalk.cyan('workscribe summary')}`)\n log.plain('')\n log.plain(` Check capture is working:`)\n log.plain(` ${chalk.cyan('workscribe status')}`)\n } else {\n log.plain(` Before generating summaries, configure an AI provider:`)\n log.plain(` ${chalk.cyan('workscribe config set ai.provider anthropic')}`)\n log.plain(` ${chalk.cyan('workscribe config set ai.apiKey <your-key>')}`)\n log.plain('')\n log.plain(` Then run:`)\n log.plain(` ${chalk.cyan('workscribe summary')}`)\n }\n\n log.plain('')\n })\n}\n","export function formatDuration(minutes: number): string {\n if (minutes < 60) return `${Math.round(minutes)}m`\n const h = Math.floor(minutes / 60)\n const m = Math.round(minutes % 60)\n return m > 0 ? `${h}h ${m}m` : `${h}h`\n}\n\nexport function formatDate(isoString: string): string {\n return new Date(isoString).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })\n}\n\nexport function todayDate(): string {\n return localDateStr(new Date())\n}\n\nexport function parseDate(input: string): string {\n // Accepts YYYY-MM-DD, returns YYYY-MM-DD. Throws on invalid.\n const d = new Date(input + 'T00:00:00')\n if (isNaN(d.getTime())) throw new Error(`Invalid date: ${input}`)\n return input\n}\n\nfunction localDateStr(d: Date): string {\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, '0')\n const day = String(d.getDate()).padStart(2, '0')\n return `${y}-${m}-${day}`\n}\n\n// Returns Monday of the ISO week containing dateStr (YYYY-MM-DD)\nexport function startOfWeek(dateStr: string): string {\n const d = new Date(dateStr + 'T00:00:00')\n const day = d.getDay() // 0=Sun\n const diff = day === 0 ? -6 : 1 - day\n d.setDate(d.getDate() + diff)\n return localDateStr(d)\n}\n\n// Returns all YYYY-MM-DD strings from start to end inclusive\nexport function eachDayOfRange(start: string, end: string): string[] {\n const days: string[] = []\n const cur = new Date(start + 'T00:00:00')\n const last = new Date(end + 'T00:00:00')\n while (cur <= last) {\n days.push(localDateStr(cur))\n cur.setDate(cur.getDate() + 1)\n }\n return days\n}\n\n// Returns ISO week string YYYY-WW for a date\nexport function isoWeekKey(dateStr: string): string {\n const d = new Date(dateStr + 'T00:00:00')\n const jan4 = new Date(d.getFullYear(), 0, 4)\n const weekNum = Math.ceil(((d.getTime() - jan4.getTime()) / 86400000 + jan4.getDay() + 1) / 7)\n return `${d.getFullYear()}-W${String(weekNum).padStart(2, '0')}`\n}\n","import type { DaySummaryPayload, WeekSummaryPayload } from './types'\nimport { formatDuration } from '../utils/format'\nimport { getActiveProfileAiContexts } from '../profiles/loader'\n\nexport const SYSTEM_PROMPT = `You write short developer work summaries. Focus on what the developer accomplished and what changed — not which tools or commands were used.\n\nHere is an example:\n\nINPUT:\nProject: api-service\nBranch: feature/auth\nDuration: 2h 00m\nEvents:\n - versioning {\"branch\":\"feature/auth\"}\n - 2x dependencies {\"tool\":\"npm\",\"packages\":[\"bcrypt\",\"jsonwebtoken\"]}\n - 8x testing [failed]\n - testing\n - 2x files {\"tool\":\"mkdir\"}\n - shipping {\"message\":\"fix: auth token validation\"}\n - shipping {\"remote\":\"origin\",\"branch\":\"feature/auth\"}\n\nOUTPUT:\n- Added authentication dependencies (bcrypt, JWT)\n- Debugged and resolved failing auth tests\n- Committed and pushed the token validation fix\n\nRULES — follow these exactly:\n\n1. Interpret repeated events as patterns, not individual steps.\n - Many testing [failed] followed by a passing test = debugging a failure. Say \"resolved failing X tests\", not \"ran tests multiple times\".\n - Many versioning events = branch housekeeping. Fold into context, do not list each git command.\n\n2. Omit utility commands entirely. File size checks, file reads, grep searches, and cat commands are research steps — they are not outcomes and must not appear in the summary.\n\n3. Do not name the AI tool. For ai_session events: focus on what was built or committed. If a commits array is present in metadata, use those commit messages. Never write \"via Claude Code\", \"using Claude Code\", or similar — omit the tool name entirely.\n\n4. For other events with a hint field: describe the developer's intent, not the raw command.\n\n5. For dependencies events: infer the purpose from package names and describe the domain (bcrypt/jsonwebtoken → authentication, prisma/pg → database, jest/vitest → testing). For unfamiliar packages, name them directly.\n\n6. Fold supporting events into the narrative. Building, shipping, versioning, and file operations are context — only make them a bullet when they are the primary activity (e.g. a standalone build fix or deploy with no accompanying commits).\n\n7. Stick to what the events show. Do not infer subject matter from the branch name. Do not add details not derivable from the events.\n\nMaximum 5 bullets. Output ONLY the bullet points, nothing else.`\n\nexport function getSystemPrompt(): string {\n const contexts = getActiveProfileAiContexts()\n if (contexts.length === 0) return SYSTEM_PROMPT\n return SYSTEM_PROMPT + '\\n\\n' + contexts.join('\\n')\n}\n\n// Categories excluded from the AI payload by default:\n// - exploring/note: handled separately (notes rendered before event list; exploring is raw file reads)\n// - linting: lint/format runs are support noise, not meaningful work outcomes\n// `other` is intentionally kept — hints give the AI context for commands that don't fit known patterns\n// (e.g. docker compose up, make deploy, terraform apply). The prompt instructs the model to omit\n// utility commands (wc, head) within that category.\nexport const DEFAULT_EXCLUDED_CATEGORIES = new Set(['exploring', 'note', 'linting'])\n\nexport function buildExcludedSet(includeCategories: string[] = []): Set<string> {\n const excluded = new Set(DEFAULT_EXCLUDED_CATEGORIES)\n for (const cat of includeCategories) excluded.delete(cat)\n return excluded\n}\n\nexport function countExcludedEvents(\n sessions: DaySummaryPayload['sessions'],\n excluded: Set<string>\n): Map<string, number> {\n const counts = new Map<string, number>()\n for (const session of sessions) {\n for (const event of session.events) {\n if (excluded.has(event.category)) {\n counts.set(event.category, (counts.get(event.category) ?? 0) + 1)\n }\n }\n }\n return counts\n}\n\nexport function buildUserMessage(payload: DaySummaryPayload, includeCategories: string[] = []): string {\n const excluded = buildExcludedSet(includeCategories)\n const lines: string[] = [`Date: ${payload.date}`, '']\n\n for (const session of payload.sessions) {\n lines.push(`Project: ${session.project ?? 'unknown'}`)\n if (session.branch) lines.push(`Branch: ${session.branch}`)\n lines.push(`Duration: ${formatDuration(session.durationMinutes)}`)\n\n for (const event of session.events) {\n if (event.category === 'note') {\n lines.push(`NOTE: ${event.metadata.text as string}`)\n }\n }\n\n lines.push('Events:')\n\n // Aggregate repeated events so the model sees \"3x build\" not 3 separate build lines\n const counts = new Map<string, number>()\n for (const event of session.events) {\n if (excluded.has(event.category)) continue\n const failed = event.exitCode !== null && event.exitCode !== 0 ? ' [failed]' : ''\n let key: string\n if (event.hint) {\n key = `other [${event.hint}]${failed}`\n } else {\n const meta = Object.keys(event.metadata).length > 0 ? ` ${JSON.stringify(event.metadata)}` : ''\n key = `${event.category}${meta}${failed}`\n }\n counts.set(key, (counts.get(key) ?? 0) + 1)\n }\n\n for (const [key, count] of counts) {\n lines.push(` - ${count > 1 ? `${count}x ` : ''}${key}`)\n }\n\n lines.push('')\n }\n\n return lines.join('\\n')\n}\n\nexport const WEEKLY_SYSTEM_PROMPT = `You write short weekly developer summaries. Here is an example:\n\nINPUT:\nWeek: 2026-05-18 to 2026-05-22\n\nMonday 2026-05-18:\n Project: api-service (feature/auth) — 2h 10m\n Events: 3x code_commit, 2x test_run, dependency_install\n\nTuesday 2026-05-19:\n Project: api-service (feature/auth) — 1h 30m\n Events: 2x code_commit, test_run, build\n\nWednesday 2026-05-20:\n Project: dashboard (main) — 3h 00m\n Events: 4x code_commit, 2x build, test_run\n\nThursday 2026-05-21:\n Project: api-service (feature/auth) — 1h 00m\n Events: code_commit {\"message\":\"feat: merge auth\"}, branch_switch\n\nFriday 2026-05-22:\n Project: dashboard (main) — 2h 00m\n Events: 3x code_commit, build\n\nOUTPUT:\n## Week of 18 May — 9h 40m across 2 projects\n\n**api-service** (Mon–Thu): Built and shipped the auth feature — JWT setup, token validation fixes, and final merge.\n**dashboard** (Wed, Fri): Active development across 7 commits with builds passing.\n\nNow summarise the following week. Output ONLY the summary — a one-line header then one bullet per active project. Maximum 4 bullets.`\n\nconst DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']\n\nexport function buildWeeklyMessage(payload: WeekSummaryPayload): string {\n const lines: string[] = [`Week: ${payload.weekStart} to ${payload.weekEnd}`, '']\n\n for (const { date, sessions } of payload.days) {\n const dayName = DAY_NAMES[new Date(date + 'T00:00:00').getDay()]\n lines.push(`${dayName} ${date}:`)\n\n for (const session of sessions) {\n const project = session.project ?? 'unknown'\n const branch = session.branch ? ` (${session.branch})` : ''\n lines.push(` Project: ${project}${branch} — ${formatDuration(session.durationMinutes)}`)\n\n for (const event of session.events) {\n if (event.category === 'note') {\n lines.push(` NOTE: ${event.metadata.text as string}`)\n }\n }\n\n const excluded = buildExcludedSet()\n const counts = new Map<string, number>()\n for (const event of session.events) {\n if (excluded.has(event.category)) continue\n const failed = event.exitCode !== null && event.exitCode !== 0 ? ' [failed]' : ''\n let key: string\n if (event.hint) {\n key = `other [${event.hint}]${failed}`\n } else {\n const meta = Object.keys(event.metadata).length > 0 ? ` ${JSON.stringify(event.metadata)}` : ''\n key = `${event.category}${meta}${failed}`\n }\n counts.set(key, (counts.get(key) ?? 0) + 1)\n }\n const eventLine = [...counts.entries()].map(([key, count]) => `${count > 1 ? `${count}x ` : ''}${key}`).join(', ')\n lines.push(` Events: ${eventLine}`)\n }\n\n lines.push('')\n }\n\n return lines.join('\\n')\n}\n","const DEFAULT_TIMEOUT_MS = 30_000\n\nexport async function fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs = DEFAULT_TIMEOUT_MS\n): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n return await fetch(url, { ...init, signal: controller.signal })\n } catch (err) {\n if ((err as Error).name === 'AbortError') {\n throw new Error(`Request timed out after ${timeoutMs / 1000}s`)\n }\n throw err\n } finally {\n clearTimeout(timer)\n }\n}\n","import type { AIProvider, DaySummaryPayload, WeekSummaryPayload } from '../types'\nimport { getSystemPrompt, buildUserMessage, WEEKLY_SYSTEM_PROMPT, buildWeeklyMessage } from '../prompt'\nimport { fetchWithTimeout } from '../fetch'\nimport type { ProviderConfig } from './config'\n\nexport class GenericProvider implements AIProvider {\n constructor(\n private config: ProviderConfig,\n private model: string,\n private apiKey: string,\n private baseUrl: string,\n private includeCategories: string[] = []\n ) {}\n\n private async call(system: string, userMsg: string, maxTokens: number): Promise<string> {\n const response = await fetchWithTimeout(this.config.chatUrl(this.baseUrl), {\n method: 'POST',\n headers: this.config.headers(this.apiKey),\n body: JSON.stringify(this.config.buildChatBody(this.model, system, userMsg, maxTokens)),\n })\n if (!response.ok) {\n throw new Error(this.config.chatError(response.status, await response.text()))\n }\n return this.config.parseText(await response.json())\n }\n\n async summarize(payload: DaySummaryPayload): Promise<string> {\n return this.call(getSystemPrompt(), buildUserMessage(payload, this.includeCategories), this.config.dailyTokens)\n }\n\n async summarizeWeek(payload: WeekSummaryPayload): Promise<string> {\n return this.call(WEEKLY_SYSTEM_PROMPT, buildWeeklyMessage(payload), this.config.weeklyTokens)\n }\n\n async validate(): Promise<void> {\n const isPost = this.config.validateMethod === 'POST'\n const response = await fetchWithTimeout(this.config.validateUrl(this.baseUrl), {\n method: this.config.validateMethod,\n headers: isPost ? this.config.headers(this.apiKey) : undefined,\n body:\n isPost && this.config.buildValidateBody ? JSON.stringify(this.config.buildValidateBody(this.model)) : undefined,\n })\n if (!response.ok) {\n throw new Error(this.config.validateError(response.status, await response.text(), this.baseUrl))\n }\n }\n}\n","export interface ProviderConfig {\n defaultModel: string\n defaultBaseUrl: string\n dailyTokens: number\n weeklyTokens: number\n chatUrl: (baseUrl: string) => string\n validateUrl: (baseUrl: string) => string\n validateMethod: 'GET' | 'POST'\n headers: (apiKey: string) => Record<string, string>\n buildChatBody: (model: string, system: string, userMsg: string, maxTokens: number) => object\n buildValidateBody?: (model: string) => object\n parseText: (json: unknown) => string\n chatError: (status: number, body: string) => string\n validateError: (status: number, body: string, baseUrl: string) => string\n}\n\nexport const PROVIDER_CONFIGS: Record<string, ProviderConfig> = {\n anthropic: {\n defaultModel: 'claude-haiku-4-5-20251001',\n defaultBaseUrl: 'https://api.anthropic.com/v1',\n dailyTokens: 1024,\n weeklyTokens: 1024,\n chatUrl: (baseUrl) => `${baseUrl}/messages`,\n validateUrl: (baseUrl) => `${baseUrl}/messages`,\n validateMethod: 'POST',\n headers: (apiKey) => ({\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n }),\n buildChatBody: (model, system, userMsg, maxTokens) => ({\n model,\n max_tokens: maxTokens,\n system,\n messages: [{ role: 'user', content: userMsg }],\n }),\n buildValidateBody: (model) => ({\n model,\n max_tokens: 1,\n messages: [{ role: 'user', content: '.' }],\n }),\n parseText: (json) => {\n const data = json as { content: Array<{ type: string; text: string }> }\n return data.content.find((b) => b.type === 'text')?.text ?? ''\n },\n chatError: (status, body) => `Anthropic API error ${status}: ${body}`,\n validateError: (status, body) => `Anthropic API error ${status}: ${body}`,\n },\n\n openai: {\n defaultModel: 'gpt-4o-mini',\n defaultBaseUrl: 'https://api.openai.com/v1',\n dailyTokens: 1024,\n weeklyTokens: 1024,\n chatUrl: (baseUrl) => `${baseUrl}/chat/completions`,\n validateUrl: (baseUrl) => `${baseUrl}/chat/completions`,\n validateMethod: 'POST',\n headers: (apiKey) => ({\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n }),\n buildChatBody: (model, system, userMsg, maxTokens) => ({\n model,\n messages: [\n { role: 'system', content: system },\n { role: 'user', content: userMsg },\n ],\n max_tokens: maxTokens,\n }),\n buildValidateBody: (model) => ({\n model,\n messages: [{ role: 'user', content: '.' }],\n max_tokens: 1,\n }),\n parseText: (json) => {\n const data = json as { choices: Array<{ message: { content: string } }> }\n return data.choices[0]?.message?.content ?? ''\n },\n chatError: (status, body) => `OpenAI API error ${status}: ${body}`,\n validateError: (status, body) => `OpenAI API error ${status}: ${body}`,\n },\n\n ollama: {\n defaultModel: 'llama3',\n defaultBaseUrl: 'http://localhost:11434',\n dailyTokens: 300,\n weeklyTokens: 400,\n chatUrl: (baseUrl) => `${baseUrl}/api/chat`,\n validateUrl: (baseUrl) => `${baseUrl}/api/tags`,\n validateMethod: 'GET',\n headers: () => ({ 'Content-Type': 'application/json' }),\n buildChatBody: (model, system, userMsg, maxTokens) => ({\n model,\n stream: false,\n messages: [\n { role: 'system', content: system },\n { role: 'user', content: userMsg },\n ],\n options: { num_predict: maxTokens, temperature: 0.3 },\n }),\n parseText: (json) => {\n return (json as { message: { content: string } }).message?.content ?? ''\n },\n chatError: (status, body) => `Ollama error ${status}: ${body}. Is Ollama running? Try: ollama serve`,\n validateError: (_status, _body, baseUrl) =>\n `Ollama is not reachable at ${baseUrl}. Is it running? Try: ollama serve`,\n },\n}\n","import type { AIProvider } from './types'\nimport type { WorkscribeConfig } from '../config'\nimport { GenericProvider } from './providers'\nimport { PROVIDER_CONFIGS } from './providers/config'\n\nexport function getProvider(config: WorkscribeConfig): AIProvider {\n const { provider, apiKey = '', model, baseUrl } = config.ai\n\n if (!provider) {\n throw new Error(\n 'No AI provider configured.\\nRun: workscribe config set ai.provider <anthropic|openai|ollama|openai-compatible>'\n )\n }\n\n const configKey = provider === 'openai-compatible' ? 'openai' : provider\n const providerConfig = PROVIDER_CONFIGS[configKey]\n\n if (!providerConfig) {\n throw new Error(\n `Unknown provider: \"${provider}\"\\nSupported providers: anthropic, openai, ollama, openai-compatible`\n )\n }\n\n if (provider !== 'ollama' && !apiKey) {\n throw new Error(`${provider} requires an API key.\\nRun: workscribe config set ai.apiKey <your-key>`)\n }\n\n if (provider === 'openai-compatible' && !baseUrl) {\n throw new Error('openai-compatible requires a base URL.\\nRun: workscribe config set ai.baseUrl <url>')\n }\n\n return new GenericProvider(\n providerConfig,\n model || providerConfig.defaultModel,\n apiKey,\n baseUrl || providerConfig.defaultBaseUrl,\n config.summary?.includeCategories ?? []\n )\n}\n","import fs from 'fs'\nimport path from 'path'\nimport { log } from '../utils/logger'\n\nconst HOOK_START = '# workscribe:hook:start'\nconst HOOK_END = '# workscribe:hook:end'\nconst HOOK_PREAMBLE = '# Workscribe — developer work journal'\n\nexport function getInstalledHookBlock(rcFile: string): string | null {\n if (!fs.existsSync(rcFile)) return null\n const content = fs.readFileSync(rcFile, 'utf-8')\n const startIdx = content.indexOf(HOOK_START)\n const endIdx = content.indexOf(HOOK_END)\n if (startIdx === -1 || endIdx === -1) return null\n return content.slice(startIdx, endIdx + HOOK_END.length)\n}\n\nexport function isHookInstalled(rcFile: string): boolean {\n return getInstalledHookBlock(rcFile) !== null\n}\n\nexport function isHookOutdated(rcFile: string, hookContent: string): boolean {\n const installed = getInstalledHookBlock(rcFile)\n if (!installed) return false\n return installed.trim() !== hookContent.trim()\n}\n\nexport function installHook(rcFile: string, hookContent: string): void {\n const backup = `${rcFile}.workscribe-backup-${Date.now()}`\n fs.copyFileSync(rcFile, backup)\n log.info(`Backed up ${rcFile} → ${path.basename(backup)}`)\n fs.appendFileSync(rcFile, `\\n${hookContent}\\n`)\n}\n\nexport function updateHook(rcFile: string, hookContent: string): void {\n const backup = `${rcFile}.workscribe-backup-${Date.now()}`\n fs.copyFileSync(rcFile, backup)\n log.info(`Backed up ${rcFile} → ${path.basename(backup)}`)\n const content = fs.readFileSync(rcFile, 'utf-8')\n const startIdx = content.indexOf(HOOK_START)\n const endIdx = content.indexOf(HOOK_END) + HOOK_END.length\n fs.writeFileSync(rcFile, content.slice(0, startIdx) + hookContent + content.slice(endIdx))\n}\n\nexport function removeHook(rcFile: string): void {\n const backup = `${rcFile}.workscribe-backup-${Date.now()}`\n fs.copyFileSync(rcFile, backup)\n log.info(`Backed up ${rcFile} → ${path.basename(backup)}`)\n const content = fs.readFileSync(rcFile, 'utf-8')\n const startIdx = content.indexOf(HOOK_START)\n const endIdx = content.indexOf(HOOK_END) + HOOK_END.length\n // Also remove the preamble comment lines that installHook writes before HOOK_START\n const preambleIdx = content.lastIndexOf(HOOK_PREAMBLE, startIdx)\n const blockStart = preambleIdx !== -1 ? preambleIdx : startIdx\n const before = content.slice(0, blockStart).replace(/\\n+$/, '\\n')\n const after = content.slice(endIdx).replace(/^\\n/, '')\n fs.writeFileSync(rcFile, before + after)\n}\n","import fs from 'fs'\nimport path from 'path'\nimport os from 'os'\nimport type { AIHookIntegration } from './types'\nimport { isCommandInstalled } from './utils'\n\nconst CLAUDE_SETTINGS_PATH = path.join(os.homedir(), '.claude', 'settings.json')\n\nfunction readSettings(): Record<string, unknown> {\n if (!fs.existsSync(CLAUDE_SETTINGS_PATH)) return {}\n try {\n return JSON.parse(fs.readFileSync(CLAUDE_SETTINGS_PATH, 'utf-8')) as Record<string, unknown>\n } catch {\n return {}\n }\n}\n\nexport const claudeCodeIntegration: AIHookIntegration = {\n displayName: 'Claude Code',\n\n isInstalled() {\n return isCommandInstalled('claude')\n },\n\n isHookInstalled() {\n const settings = readSettings()\n const postToolUse = ((settings.hooks as Record<string, unknown>)?.PostToolUse ?? []) as unknown[]\n return postToolUse.some((entry) => {\n const hooks = ((entry as Record<string, unknown>).hooks ?? []) as unknown[]\n return hooks.some((hookItem) => {\n const hook = hookItem as Record<string, unknown>\n return typeof hook.command === 'string' && hook.command.includes('workscribe _hook')\n })\n })\n },\n\n install() {\n const settings = readSettings()\n const existingHooks = (settings.hooks ?? {}) as Record<string, unknown>\n const existingPostToolUse = (existingHooks.PostToolUse ?? []) as unknown[]\n settings.hooks = {\n ...existingHooks,\n PostToolUse: [\n ...existingPostToolUse,\n {\n matcher: 'Bash',\n hooks: [{ type: 'command', command: 'workscribe _hook --source claude-code', async: true }],\n },\n ],\n }\n fs.mkdirSync(path.dirname(CLAUDE_SETTINGS_PATH), { recursive: true })\n fs.writeFileSync(CLAUDE_SETTINGS_PATH, JSON.stringify(settings, null, 2))\n },\n}\n","import { execSync } from 'child_process'\n\n/** Returns true if the given CLI command is available on PATH */\nexport function isCommandInstalled(cmd: string): boolean {\n try {\n execSync(`which ${cmd}`, { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n","import type { AIHookIntegration } from './types'\nimport { claudeCodeIntegration } from './claude-code'\n\n/**\n * Registry of AI tool hook integrations, keyed by the \"hook\" field in src/config/ai-tools.json.\n * Adding support for a new tool = add a new entry here and a corresponding integration file.\n */\nexport const AI_HOOK_INTEGRATIONS: Record<string, AIHookIntegration> = {\n 'claude-code': claudeCodeIntegration,\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport chalk from 'chalk'\nimport { getEventCount, getLastEvent, getRecentOtherRate } from '../db'\nimport { readConfig } from '../config'\nimport { log } from '../utils/logger'\nimport { formatDate, todayDate } from '../utils/format'\nimport { getEventsForDate } from '../db'\nimport { PAUSE_FLAG_PATH } from '../utils/paths'\n\nexport function registerStatus(program: Command): void {\n program\n .command('status')\n .description('Show capture status and event counts')\n .action(() => {\n const config = readConfig()\n const total = getEventCount()\n const todayEvents = getEventsForDate(todayDate())\n const last = getLastEvent()\n const isPaused = fs.existsSync(PAUSE_FLAG_PATH)\n\n log.plain('')\n log.plain(chalk.bold(' Workscribe Status'))\n log.plain('')\n\n if (isPaused) {\n log.plain(` Capture ${chalk.yellow('paused')} ${chalk.dim('(run: workscribe resume)')}`)\n } else {\n log.plain(` Capture ${chalk.green('active')}`)\n }\n\n log.plain(` Events today ${chalk.cyan(String(todayEvents.length))}`)\n log.plain(` Events total ${chalk.cyan(String(total))}`)\n\n if (last) {\n log.plain(` Last event ${formatDate(last.captured_at)} ${chalk.dim(last.command.slice(0, 60))}`)\n }\n\n log.plain('')\n log.plain(\n ` AI provider ${config.ai.provider ? chalk.cyan(config.ai.provider) : chalk.yellow('not configured')}`\n )\n if (config.ai.model) log.plain(` Model ${chalk.dim(config.ai.model)}`)\n\n const activeProfiles = config.capture.profiles\n log.plain(\n ` Profiles ${activeProfiles.length > 0 ? chalk.cyan(activeProfiles.join(', ')) : chalk.dim('none')}`\n )\n\n const { total: weekTotal, otherCount } = getRecentOtherRate(7)\n if (weekTotal > 0) {\n const otherPct = Math.round((otherCount / weekTotal) * 100)\n if (otherPct >= 25) {\n log.plain('')\n log.plain(\n ` ${chalk.yellow('⚠')} ${otherCount} of ${weekTotal} events (${otherPct}%) are uncategorised this week.`\n )\n log.plain(\n chalk.dim(\n ' Run workscribe profile detect — scan current directory for matching profiles\\n' +\n ' Run workscribe profile suggest — analyse your command history'\n )\n )\n }\n }\n\n log.plain('')\n })\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport { getEventsForDate } from '../db'\nimport { log } from '../utils/logger'\nimport { todayDate, parseDate, formatDate } from '../utils/format'\nimport { loadAIToolRegistry } from '../config/registry'\n\nconst CATEGORY_COLORS: Record<string, (s: string) => string> = {\n shipping: chalk.green,\n versioning: chalk.blue,\n building: chalk.cyan,\n running: chalk.white,\n testing: chalk.magenta,\n linting: chalk.yellow,\n dependencies: chalk.yellow,\n infrastructure: chalk.red,\n releasing: chalk.bold.green,\n database: chalk.bold.blue,\n files: chalk.dim.yellow,\n exploring: chalk.dim.cyan,\n ai_session: chalk.bold.magenta,\n other: chalk.gray,\n}\n\nconst AI_TOOL_DISPLAY_NAMES: Record<string, string> = Object.fromEntries(\n loadAIToolRegistry().map((entry) => [entry.tool, entry.displayName])\n)\n\nexport function registerEvents(program: Command): void {\n program\n .command('events')\n .description('List captured events')\n .option('--date <YYYY-MM-DD>', 'date to list events for (default: today)')\n .option('--limit <n>', 'max events to show', parseInt)\n .action((opts) => {\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n }\n\n const events = getEventsForDate(date)\n const limit = opts.limit ?? events.length\n\n if (events.length === 0) {\n log.plain(`No events captured for ${date}`)\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(` Events for ${date} (${events.length} total)`))\n log.plain('')\n\n for (const event of events.slice(0, limit)) {\n const colorFn = CATEGORY_COLORS[event.category] ?? chalk.gray\n const time = formatDate(event.captured_at)\n const category = colorFn(event.category.padEnd(20))\n const repo = event.repo_name ? chalk.dim(` [${event.repo_name}]`) : ''\n const exitBadge = event.exit_code && event.exit_code !== 0 ? chalk.red(` ✗${event.exit_code}`) : ''\n\n let cmdDisplay: string\n if (event.category === 'ai_session') {\n let meta: Record<string, unknown> = {}\n try {\n meta = event.metadata ? (JSON.parse(event.metadata) as Record<string, unknown>) : {}\n } catch {\n /* ignore */\n }\n const toolKey = typeof meta.tool === 'string' ? meta.tool : ''\n const toolName = AI_TOOL_DISPLAY_NAMES[toolKey] ?? toolKey\n cmdDisplay = chalk.white(toolName.padEnd(20)) + chalk.magenta(' ✦')\n } else {\n cmdDisplay = chalk.dim(event.command.slice(0, 55))\n }\n\n log.plain(` ${chalk.dim(time)} ${category} ${cmdDisplay}${repo}${exitBadge}`)\n }\n\n if (limit < events.length) {\n log.plain('')\n log.plain(chalk.dim(` … and ${events.length - limit} more (remove --limit to see all)`))\n }\n\n log.plain('')\n })\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport { getOrBuildSessions } from '../sessions/detector'\nimport { log } from '../utils/logger'\nimport { todayDate, parseDate, formatDate, formatDuration } from '../utils/format'\n\nexport function registerSessions(program: Command): void {\n program\n .command('sessions')\n .description('List detected work sessions')\n .option('--date <YYYY-MM-DD>', 'date to show sessions for (default: today)')\n .action((opts) => {\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (error) {\n log.error((error as Error).message)\n process.exit(1)\n }\n }\n\n const sessions = getOrBuildSessions(date)\n\n if (sessions.length === 0) {\n log.plain(`No sessions detected for ${date}`)\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(` Sessions for ${date} (${sessions.length} session${sessions.length > 1 ? 's' : ''})`))\n log.plain('')\n\n for (const session of sessions) {\n const start = formatDate(session.startedAt)\n const end = formatDate(session.endedAt)\n const duration = formatDuration(session.durationMinutes)\n const repo = session.repoName ? chalk.cyan(session.repoName) : chalk.gray('no repo')\n log.plain(\n ` ${chalk.dim(start)} – ${chalk.dim(end)} ${repo} ${chalk.dim(duration)} ${chalk.dim(session.eventCount + ' events')}`\n )\n\n for (const event of session.events) {\n if (event.category === 'note') {\n let text = ''\n try {\n text = (JSON.parse(event.metadata ?? '{}') as { text?: string }).text ?? ''\n } catch {\n /* ignore malformed metadata */\n }\n if (text) log.plain(` ${chalk.yellow('note')} ${chalk.dim(text)}`)\n }\n }\n }\n\n log.plain('')\n })\n}\n","import type { EventRow } from '../db/types'\n\n/**\n * Split a sorted list of events into groups separated by idle gaps.\n */\nexport function splitByIdleGap(events: EventRow[], idleMs: number): EventRow[][] {\n if (events.length === 0) return []\n const groups: EventRow[][] = [[events[0]]]\n\n for (let i = 1; i < events.length; i++) {\n const prev = new Date(events[i - 1].captured_at).getTime()\n const curr = new Date(events[i].captured_at).getTime()\n if (curr - prev >= idleMs) {\n groups.push([events[i]])\n } else {\n groups[groups.length - 1].push(events[i])\n }\n }\n\n return groups\n}\n\n/**\n * Split a list of events into groups by consecutive repo_name.\n * A repo change mid-stream creates a new group.\n */\nexport function splitByRepo(events: EventRow[]): EventRow[][] {\n if (events.length === 0) return []\n const groups: EventRow[][] = [[events[0]]]\n\n for (let i = 1; i < events.length; i++) {\n const prevRepo = events[i - 1].repo_name\n const currRepo = events[i].repo_name\n if (currRepo !== prevRepo) {\n groups.push([events[i]])\n } else {\n groups[groups.length - 1].push(events[i])\n }\n }\n\n return groups\n}\n\nexport function minutesBetween(start: string, end: string): number {\n return (new Date(end).getTime() - new Date(start).getTime()) / 60000\n}\n","import type { EventRow } from '../db/types'\nimport {\n insertSession,\n insertSessionEvent,\n clearSessionsForDate,\n getSessionsForDate,\n getEventsForDate,\n getEventsBySessionId,\n} from '../db'\nimport { readConfig } from '../config'\nimport { splitByIdleGap, splitByRepo, minutesBetween } from './grouper'\n\nexport interface Session {\n id: number\n date: string\n startedAt: string\n endedAt: string\n repoName: string | null\n durationMinutes: number\n eventCount: number\n summary: string | null\n events: EventRow[]\n}\n\nexport function getOrBuildSessions(date: string): Session[] {\n // Check if sessions already exist for this date\n const existing = getSessionsForDate(date)\n const events = getEventsForDate(date)\n\n if (events.length === 0) return []\n\n // If sessions exist and event count matches, use cached\n const cachedEventCount = existing.reduce((sum, sessionRow) => sum + sessionRow.event_count, 0)\n if (existing.length > 0 && cachedEventCount === events.length) {\n return existing.map((sessionRow) => ({\n id: sessionRow.id,\n date: sessionRow.date,\n startedAt: sessionRow.started_at,\n endedAt: sessionRow.ended_at,\n repoName: sessionRow.repo_name,\n durationMinutes: minutesBetween(sessionRow.started_at, sessionRow.ended_at),\n eventCount: sessionRow.event_count,\n summary: sessionRow.summary,\n events: getEventsBySessionId(sessionRow.id),\n }))\n }\n\n // Preserve any cached summaries before clearing — keyed by repo+start time\n // so they can be restored to matching sessions after rebuild\n const savedSummaries = new Map<string, string>()\n for (const s of existing) {\n if (s.summary) savedSummaries.set(`${s.repo_name}|${s.started_at}`, s.summary)\n }\n\n // Rebuild sessions\n clearSessionsForDate(date)\n return buildSessions(date, events, savedSummaries)\n}\n\nfunction buildSessions(date: string, events: EventRow[], savedSummaries: Map<string, string> = new Map()): Session[] {\n const config = readConfig()\n const idleMs = config.session.idleTimeout * 60 * 1000\n\n const sessions: Session[] = []\n const timeGroups = splitByIdleGap(events, idleMs)\n\n for (const group of timeGroups) {\n if (group.length === 0) continue\n\n const repoGroups = splitByRepo(group)\n\n for (const repoGroup of repoGroups) {\n if (repoGroup.length === 0) continue\n\n const first = repoGroup[0]\n const last = repoGroup[repoGroup.length - 1]\n const repoName = last.repo_name ?? first.repo_name ?? null\n\n // Restore a previously generated summary if the session boundaries match\n const summary = savedSummaries.get(`${repoName}|${first.captured_at}`) ?? null\n\n const sessionId = insertSession({\n date,\n started_at: first.captured_at,\n ended_at: last.captured_at,\n repo_name: repoName,\n event_count: repoGroup.length,\n summary,\n })\n\n for (const event of repoGroup) {\n insertSessionEvent(sessionId, event.id)\n }\n\n sessions.push({\n id: sessionId,\n date,\n startedAt: first.captured_at,\n endedAt: last.captured_at,\n repoName,\n durationMinutes: minutesBetween(first.captured_at, last.captured_at),\n eventCount: repoGroup.length,\n summary,\n events: repoGroup,\n })\n }\n }\n\n return sessions\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { getOrBuildSessions } from '../sessions/detector'\nimport { getProvider } from '../ai/router'\nimport { readConfig } from '../config'\nimport { updateSessionSummary } from '../db'\nimport { log } from '../utils/logger'\nimport {\n todayDate,\n parseDate,\n formatDate,\n formatDuration,\n startOfWeek,\n eachDayOfRange,\n isoWeekKey,\n} from '../utils/format'\nimport { postToWebhook } from '../integrations/webhook'\nimport { formatForSlack, isSlackWebhookUrl } from '../integrations/slack'\nimport { WEEKLY_CACHE_DIR } from '../utils/paths'\nimport type { DaySummaryPayload, SessionPayload, EventPayload, WeekSummaryPayload } from '../ai/types'\nimport type { EventRow } from '../db'\nimport { buildExcludedSet, countExcludedEvents } from '../ai/prompt'\n\ninterface SessionSummaryJson {\n project: string | null\n branch: string | null\n durationMinutes: number\n bullets: string[]\n}\n\n/** Parse AI bullet output into a clean string array. Handles both - and • prefixes. */\nexport function parseBullets(text: string): string[] {\n return text\n .split('\\n')\n .map((line) => line.replace(/^[•\\-]\\s*/, '').trim())\n .filter(Boolean)\n}\n\nfunction eventRowToPayload(row: EventRow): EventPayload {\n let metadata: Record<string, unknown> = {}\n try {\n if (row.metadata) metadata = JSON.parse(row.metadata)\n } catch {\n /* ignore */\n }\n const payload: EventPayload = {\n category: row.category,\n metadata,\n exitCode: row.exit_code,\n durationMs: row.duration_ms,\n }\n if (row.category === 'other' && typeof metadata.hint === 'string') {\n payload.hint = metadata.hint\n const { hint: _hint, tool: _tool, ...rest } = metadata\n payload.metadata = rest\n }\n return payload\n}\n\nfunction sessionToPayload(s: ReturnType<typeof getOrBuildSessions>[number], date: string): SessionPayload {\n return {\n date,\n project: s.repoName,\n branch: s.events[0]?.branch ?? null,\n startTime: formatDate(s.startedAt),\n endTime: formatDate(s.endedAt),\n durationMinutes: s.durationMinutes,\n events: s.events.map(eventRowToPayload),\n }\n}\n\nasync function handleWebhook(\n opts: { slack?: boolean; webhook?: string },\n config: ReturnType<typeof readConfig>,\n summary: string\n): Promise<void> {\n const webhookUrl = opts.webhook ?? (opts.slack ? config.integrations?.slackWebhook : undefined)\n\n if (webhookUrl) {\n try {\n log.info('Posting to webhook…')\n const username = os.userInfo().username\n const body = isSlackWebhookUrl(webhookUrl) ? formatForSlack(summary, username) : summary\n await postToWebhook(webhookUrl, body)\n log.success('Posted.')\n } catch (error) {\n log.error(`Webhook failed: ${(error as Error).message}`)\n }\n } else if (opts.slack && !config.integrations?.slackWebhook) {\n log.warn('--slack requires integrations.slackWebhook to be set in config')\n }\n}\n\nexport function registerSummary(program: Command): void {\n program\n .command('summary')\n .description('Generate an AI work summary')\n .option('--date <YYYY-MM-DD>', 'date to summarize (default: today)')\n .option('--week', 'summarize the current week')\n .option('--fresh', 'bypass cache and regenerate')\n .option('--verbose', 'show all captured events including those not sent to AI')\n .option('--slack', 'post summary to Slack webhook from config')\n .option('--webhook <url>', 'post summary to a custom webhook URL')\n .action(async (opts) => {\n const config = readConfig()\n let provider\n try {\n provider = getProvider(config)\n } catch (error) {\n log.error((error as Error).message)\n process.exit(1)\n }\n\n // ── Weekly branch ────────────────────────────────────────────────────────\n if (opts.week) {\n const today = todayDate()\n const weekStart = startOfWeek(today)\n const days = eachDayOfRange(weekStart, today)\n\n const weeklyDays: WeekSummaryPayload['days'] = []\n for (const day of days) {\n const sessions = getOrBuildSessions(day)\n if (sessions.length > 0) {\n weeklyDays.push({ date: day, sessions: sessions.map((session) => sessionToPayload(session, day)) })\n }\n }\n\n if (weeklyDays.length === 0) {\n log.plain('No activity captured this week.')\n return\n }\n\n const cacheKey = isoWeekKey(today)\n const cacheFile = path.join(WEEKLY_CACHE_DIR, `${cacheKey}.md`)\n\n if (!opts.fresh && fs.existsSync(cacheFile)) {\n const cached = fs.readFileSync(cacheFile, 'utf-8')\n log.plain('')\n log.plain(cached)\n log.plain('')\n log.plain(chalk.dim(' (cached — use --fresh to regenerate)'))\n await handleWebhook(opts, config, cached)\n return\n }\n\n const payload: WeekSummaryPayload = { weekStart, weekEnd: today, days: weeklyDays }\n\n log.plain('')\n log.info(`Generating weekly summary via ${chalk.cyan(config.ai.provider)}…`)\n\n try {\n const summary = provider.summarizeWeek\n ? await provider.summarizeWeek(payload)\n : await provider.summarize({ date: today, sessions: weeklyDays.flatMap((day) => day.sessions) })\n\n log.plain('')\n log.plain(summary)\n log.plain('')\n\n fs.mkdirSync(WEEKLY_CACHE_DIR, { recursive: true })\n fs.writeFileSync(cacheFile, summary, { encoding: 'utf-8', mode: 0o600 })\n\n await handleWebhook(opts, config, summary)\n } catch (error) {\n log.error(`Weekly summary failed [${config.ai.provider}]: ${(error as Error).message}`)\n process.exit(1)\n }\n return\n }\n\n // ── Daily branch ─────────────────────────────────────────────────────────\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (error) {\n log.error((error as Error).message)\n process.exit(1)\n }\n }\n\n const sessions = getOrBuildSessions(date)\n\n if (sessions.length === 0) {\n log.plain(`No activity captured for ${date}`)\n return\n }\n\n const jsonMode = config.summary?.format === 'json'\n\n if (!opts.fresh) {\n const allCached = sessions.every((session) => session.summary)\n if (allCached) {\n const fullSummary = sessions.map((session) => session.summary!).join('\\n\\n')\n log.plain('')\n if (jsonMode) {\n const jsonOut: SessionSummaryJson[] = sessions.map((session) => ({\n project: session.repoName,\n branch: session.events[0]?.branch ?? null,\n durationMinutes: session.durationMinutes,\n bullets: parseBullets(session.summary!.replace(/^## .+\\n/, '')),\n }))\n log.plain(JSON.stringify({ date, sessions: jsonOut }, null, 2))\n } else {\n log.plain(fullSummary)\n }\n log.plain('')\n log.plain(chalk.dim(' (cached — use --fresh to regenerate)'))\n await handleWebhook(opts, config, fullSummary)\n return\n }\n }\n\n const excluded = buildExcludedSet(config.summary?.includeCategories ?? [])\n const allSessionPayloads = sessions.map((session) => sessionToPayload(session, date))\n\n if (opts.verbose) {\n log.plain('')\n log.plain(chalk.bold(' Captured events (--verbose):'))\n for (const sessionPayload of allSessionPayloads) {\n const branch = sessionPayload.branch ? ` (${sessionPayload.branch})` : ''\n log.plain(\n chalk.dim(\n `\\n ${sessionPayload.project ?? 'unknown'}${branch} — ${formatDuration(sessionPayload.durationMinutes)}`\n )\n )\n for (const event of sessionPayload.events) {\n const tag = excluded.has(event.category)\n ? chalk.dim(` [excluded] ${event.category}`)\n : ` ${event.category}`\n const hint = event.hint ? chalk.dim(` [${event.hint}]`) : ''\n const meta = Object.keys(event.metadata).length > 0 ? chalk.dim(` ${JSON.stringify(event.metadata)}`) : ''\n log.plain(` ${tag}${hint}${meta}`)\n }\n }\n log.plain('')\n }\n\n log.plain('')\n log.info(`Generating summary via ${chalk.cyan(config.ai.provider)}…`)\n\n const allSummaries: string[] = []\n const jsonSessions: SessionSummaryJson[] = []\n\n for (let index = 0; index < sessions.length; index++) {\n const session = sessions[index]\n const sessionPayload: DaySummaryPayload = { date, sessions: [allSessionPayloads[index]] }\n try {\n const bullets = await provider.summarize(sessionPayload)\n const project = session.repoName ?? 'unknown'\n const branch = session.events[0]?.branch ? ` (${session.events[0].branch})` : ''\n const duration = formatDuration(session.durationMinutes)\n const heading = `## ${project}${branch} — ${duration}`\n const summary = `${heading}\\n${bullets.trim()}`\n allSummaries.push(summary)\n updateSessionSummary(session.id, summary)\n if (jsonMode) {\n jsonSessions.push({\n project: session.repoName,\n branch: session.events[0]?.branch ?? null,\n durationMinutes: session.durationMinutes,\n bullets: parseBullets(bullets),\n })\n }\n } catch (error) {\n log.error(`Summary failed [${config.ai.provider}]: ${(error as Error).message}`)\n process.exit(1)\n }\n }\n\n const fullSummary = allSummaries.join('\\n\\n')\n log.plain('')\n if (jsonMode) {\n log.plain(JSON.stringify({ date, sessions: jsonSessions }, null, 2))\n } else {\n log.plain(fullSummary)\n }\n log.plain('')\n\n const excludedCounts = countExcludedEvents(allSessionPayloads, excluded)\n if (excludedCounts.size > 0) {\n const total = [...excludedCounts.values()].reduce((sum, count) => sum + count, 0)\n const breakdown = [...excludedCounts.entries()].map(([category, count]) => `${category} ×${count}`).join(', ')\n log.plain(chalk.dim(` ℹ ${total} event${total === 1 ? '' : 's'} not included in summary (${breakdown})`))\n log.plain(chalk.dim(' Use --verbose to inspect · workscribe config set summary.includeCategories to opt in'))\n log.plain('')\n }\n\n await handleWebhook(opts, config, fullSummary)\n })\n}\n","import { fetchWithTimeout } from '../ai/fetch'\n\nexport async function postToWebhook(url: string, text: string): Promise<void> {\n const response = await fetchWithTimeout(\n url,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ text }),\n },\n 10_000\n )\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Webhook POST failed ${response.status}: ${body}`)\n }\n}\n","/**\n * Converts workscribe markdown summary output to Slack mrkdwn format.\n *\n * Rules:\n * ## heading → *heading* (bold)\n * - bullet → • bullet\n *\n * An optional username is prepended as a dim header line so recipients\n * can tell who sent the summary in shared channels.\n */\nexport function formatForSlack(markdown: string, username?: string): string {\n const body = markdown.replace(/^## (.+)$/gm, '*$1*').replace(/^- /gm, '• ')\n return username ? `_${username}_\\n${body}` : body\n}\n\nexport function isSlackWebhookUrl(url: string): boolean {\n return url.startsWith('https://hooks.slack.com/')\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport path from 'path'\nimport { getOrBuildSessions } from '../sessions/detector'\nimport { getProvider } from '../ai/router'\nimport { readConfig } from '../config'\nimport { log } from '../utils/logger'\nimport { todayDate, parseDate, formatDate } from '../utils/format'\nimport { EXPORTS_DIR } from '../utils/paths'\nimport type { DaySummaryPayload, SessionPayload, EventPayload } from '../ai/types'\nimport type { EventRow } from '../db'\n\nfunction eventRowToPayload(row: EventRow): EventPayload {\n let metadata: Record<string, unknown> = {}\n try {\n if (row.metadata) metadata = JSON.parse(row.metadata)\n } catch {\n /* ignore */\n }\n const payload: EventPayload = {\n category: row.category,\n metadata,\n exitCode: row.exit_code,\n durationMs: row.duration_ms,\n }\n if (row.category === 'other' && typeof metadata.hint === 'string') {\n payload.hint = metadata.hint\n const { hint: _h, tool: _t, ...rest } = metadata\n payload.metadata = rest\n }\n return payload\n}\n\nexport function registerExport(program: Command): void {\n program\n .command('export')\n .description('Export work summary as a markdown file')\n .option('--date <YYYY-MM-DD>', 'date to export (default: today)')\n .option('--output <path>', 'output file path (default: ~/.workscribe/exports/)')\n .action(async (opts) => {\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n }\n\n const sessions = getOrBuildSessions(date)\n if (sessions.length === 0) {\n log.plain(`No activity captured for ${date}`)\n return\n }\n\n const config = readConfig()\n let provider\n try {\n provider = getProvider(config)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n\n const sessionPayloads: SessionPayload[] = sessions.map((session) => ({\n date,\n project: session.repoName,\n branch: session.events[0]?.branch ?? null,\n startTime: formatDate(session.startedAt),\n endTime: formatDate(session.endedAt),\n durationMinutes: session.durationMinutes,\n events: session.events.map(eventRowToPayload),\n }))\n\n const payload: DaySummaryPayload = { date, sessions: sessionPayloads }\n\n log.info(`Generating summary via ${config.ai.provider}…`)\n const summary = await provider.summarize(payload)\n\n const outputPath = opts.output ?? path.join(EXPORTS_DIR, `workscribe-${date}.md`)\n\n if (!fs.existsSync(EXPORTS_DIR)) fs.mkdirSync(EXPORTS_DIR, { recursive: true, mode: 0o700 })\n\n fs.writeFileSync(outputPath, `# Work Summary — ${date}\\n\\n${summary}\\n`, { encoding: 'utf-8', mode: 0o600 })\n log.success(`Saved: ${outputPath}`)\n })\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport { readConfig, writeConfig, getConfigValue, setConfigValue } from '../config'\nimport { log } from '../utils/logger'\n\nexport function registerConfig(program: Command): void {\n const configCmd = program\n .command('config')\n .description('View or update Workscribe configuration')\n .action(() => {\n const config = readConfig()\n log.plain('')\n log.plain(chalk.bold(' Workscribe Config'))\n log.plain('')\n printConfig(config, ' ')\n log.plain('')\n })\n\n configCmd\n .command('set <key> <value>')\n .description('Set a config value (e.g. workscribe config set ai.provider anthropic)')\n .action((key: string, value: string) => {\n const config = readConfig()\n const updated = setConfigValue(config, key, value)\n writeConfig(updated)\n const isSensitive =\n key === 'ai.apiKey' ||\n key.toLowerCase().includes('key') ||\n key.toLowerCase().includes('secret') ||\n key.toLowerCase().includes('token')\n const displayValue = isSensitive ? '[set]' : chalk.yellow(value)\n log.success(`Set ${chalk.cyan(key)} = ${displayValue}`)\n })\n\n configCmd\n .command('get <key>')\n .description('Get a config value')\n .action((key: string) => {\n const config = readConfig()\n const value = getConfigValue(config, key)\n if (value === undefined) {\n log.warn(`Key not found: ${key}`)\n } else {\n const lastSegment = key.split('.').pop() ?? ''\n if (SENSITIVE_KEYS.has(lastSegment) && typeof value === 'string' && value.length > 0) {\n log.plain(`${value.slice(0, 4)}${'*'.repeat(8)} (${value.length} chars)`)\n } else {\n log.plain(String(value))\n }\n }\n })\n}\n\nconst SENSITIVE_KEYS = new Set([\n 'apiKey',\n 'api_key',\n 'secret',\n 'token',\n 'password',\n 'passwd',\n 'webhook',\n 'slackWebhook',\n])\n\nfunction maskValue(key: string, value: unknown): string {\n if (SENSITIVE_KEYS.has(key) && typeof value === 'string' && value.length > 0) {\n return chalk.dim(`${value.slice(0, 4)}${'*'.repeat(8)} (${value.length} chars)`)\n }\n if (Array.isArray(value)) return `[${(value as unknown[]).join(', ')}]`\n return String(value) || chalk.dim('(not set)')\n}\n\nfunction printConfig(obj: unknown, indent: string): void {\n if (typeof obj !== 'object' || obj === null) return\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n log.plain(`${indent}${chalk.bold(key)}:`)\n printConfig(value, indent + ' ')\n } else {\n log.plain(`${indent}${chalk.dim(key)}: ${chalk.yellow(maskValue(key, value))}`)\n }\n }\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport { PAUSE_FLAG_PATH } from '../utils/paths'\nimport { log } from '../utils/logger'\n\nexport function registerPause(program: Command): void {\n program\n .command('pause')\n .description('Pause capture temporarily')\n .action(() => {\n if (fs.existsSync(PAUSE_FLAG_PATH)) {\n log.info('Capture is already paused. Run workscribe resume to restart.')\n return\n }\n fs.writeFileSync(PAUSE_FLAG_PATH, '', { mode: 0o600 })\n log.success('Capture paused. Run workscribe resume to restart.')\n })\n\n program\n .command('resume')\n .description('Resume capture after a pause')\n .action(() => {\n if (!fs.existsSync(PAUSE_FLAG_PATH)) {\n log.info('Capture is not paused.')\n return\n }\n fs.rmSync(PAUSE_FLAG_PATH)\n log.success('Capture resumed.')\n })\n}\n","import { Command } from 'commander'\nimport { getLastEventIds, getEventsByIds, deleteEventsByIds } from '../db'\nimport { log } from '../utils/logger'\n\nexport function registerUndo(program: Command): void {\n program\n .command('undo')\n .description('Remove the last N captured events')\n .option('-n, --count <number>', 'number of events to remove', '1')\n .option('--dry-run', 'preview what would be deleted without deleting')\n .action((opts) => {\n const count = parseInt(opts.count, 10)\n if (isNaN(count) || count < 1) {\n log.error('--count must be a positive integer')\n process.exit(1)\n }\n\n const ids = getLastEventIds(count)\n if (ids.length === 0) {\n log.plain('No events to undo.')\n return\n }\n\n const events = getEventsByIds(ids)\n log.plain('')\n log.plain(`Events to remove (${events.length}):`)\n for (const e of events) {\n log.plain(` ${e.captured_at} ${e.category} ${e.command}`)\n }\n log.plain('')\n\n if (opts.dryRun) {\n log.plain('Dry run — nothing deleted.')\n return\n }\n\n deleteEventsByIds(ids)\n log.success(`Removed ${ids.length} event${ids.length > 1 ? 's' : ''}.`)\n })\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport prompts from 'prompts'\nimport { getEventsForDate, deleteEventsForDate } from '../db'\nimport { log } from '../utils/logger'\nimport { todayDate, parseDate } from '../utils/format'\n\nexport function registerClear(program: Command): void {\n program\n .command('clear')\n .description('Delete all captured events for a date')\n .option('--date <YYYY-MM-DD>', 'date to clear (default: today)')\n .option('--dry-run', 'preview what would be deleted without deleting')\n .option('--yes', 'skip confirmation prompt')\n .action(async (opts) => {\n let date = todayDate()\n if (opts.date) {\n try {\n date = parseDate(opts.date)\n } catch (e) {\n log.error((e as Error).message)\n process.exit(1)\n }\n }\n\n const events = getEventsForDate(date)\n\n if (events.length === 0) {\n log.plain(`No events found for ${date}.`)\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(` Events for ${date} (${events.length} total)`))\n log.plain('')\n\n // Show a compact summary by category\n const counts = new Map<string, number>()\n for (const e of events) counts.set(e.category, (counts.get(e.category) ?? 0) + 1)\n for (const [cat, n] of counts) {\n log.plain(` ${chalk.dim(String(n).padStart(4))} ${cat}`)\n }\n log.plain('')\n\n if (opts.dryRun) {\n log.plain(chalk.dim(' Dry run — nothing deleted.'))\n log.plain('')\n return\n }\n\n if (!opts.yes) {\n const { confirm } = await prompts({\n type: 'confirm',\n name: 'confirm',\n message: `Delete all ${events.length} events for ${date}?`,\n initial: false,\n })\n if (!confirm) {\n log.plain('Cancelled.')\n return\n }\n }\n\n const deleted = deleteEventsForDate(date)\n log.success(`Cleared ${deleted} event${deleted !== 1 ? 's' : ''} for ${date}.`)\n })\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport path from 'path'\nimport os from 'os'\nimport prompts from 'prompts'\nimport chalk from 'chalk'\nimport { WORKSCRIBE_DIR } from '../utils/paths'\nimport { isHookInstalled, removeHook } from '../capture/shell-hook'\nimport { log } from '../utils/logger'\n\nfunction detectShellRcFiles(): { name: string; rcFile: string }[] {\n const candidates = [\n { name: 'zsh', rcFile: path.join(os.homedir(), '.zshrc') },\n { name: 'bash', rcFile: path.join(os.homedir(), '.bashrc') },\n { name: 'bash', rcFile: path.join(os.homedir(), '.bash_profile') },\n ]\n return candidates.filter((candidate) => fs.existsSync(candidate.rcFile) && isHookInstalled(candidate.rcFile))\n}\n\nexport function registerUninstall(program: Command): void {\n program\n .command('uninstall')\n .description('Remove shell hooks and optionally delete all Workscribe data')\n .option('--hooks-only', 'remove shell hooks only, skip data deletion prompt (used by npm preuninstall)')\n .action(async (opts) => {\n log.plain(chalk.bold('\\n Workscribe — Uninstall\\n'))\n\n // 1. Remove shell hooks from any rc files that have them\n const hooked = detectShellRcFiles()\n if (hooked.length === 0) {\n log.info('No shell hooks found')\n } else {\n for (const { name, rcFile } of hooked) {\n removeHook(rcFile)\n log.success(`Shell hook removed from ${rcFile}`)\n log.plain(` ${chalk.dim(`Run: source ${rcFile}`)} (or restart your terminal to take effect)`)\n log.plain(\n ` ${chalk.dim(`${name === 'zsh' ? 'unfunction' : 'unset -f'} _workscribe_preexec _workscribe_precmd`)}`\n )\n }\n }\n\n if (opts.hooksOnly) return\n\n // 2. Optionally delete ~/.workscribe/ data\n if (fs.existsSync(WORKSCRIBE_DIR)) {\n log.plain('')\n const { deleteData } = await prompts({\n type: 'confirm',\n name: 'deleteData',\n message: `Delete all Workscribe data in ${WORKSCRIBE_DIR}? (database, config, exports)`,\n initial: false,\n })\n\n if (deleteData) {\n fs.rmSync(WORKSCRIBE_DIR, { recursive: true, force: true })\n log.success(`Deleted ${WORKSCRIBE_DIR}`)\n } else {\n log.info(`Data kept at ${WORKSCRIBE_DIR}`)\n }\n }\n\n log.plain('')\n log.plain(` ${chalk.dim('npm uninstall -g @workscribe/cli')} — remove the CLI itself`)\n log.plain('')\n })\n}\n","import { Command } from 'commander'\nimport fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport { readConfig, writeConfig } from '../config'\nimport { PROFILES_DIR } from '../utils/paths'\nimport { getCachedProfiles, detectProfilesForDirectory } from '../profiles/loader'\nimport { installProfile, cacheManifest, readCachedManifest } from '../profiles/fetcher'\nimport { getOtherEventToolCounts } from '../db'\nimport { log } from '../utils/logger'\n\nconst MIN_SUGGEST_COUNT = 5\n\nexport function registerProfile(program: Command): void {\n const profile = program.command('profile').description('Manage stack profiles for better command tracking')\n\n // ─── list ─────────────────────────────────────────────────────────────────\n profile\n .command('list')\n .description('List available profiles from the registry')\n .action(async () => {\n const config = readConfig()\n const activeNames = new Set(config.capture.profiles)\n\n let manifest = readCachedManifest()\n let offline = false\n\n if (!manifest) {\n try {\n manifest = await cacheManifest()\n } catch {\n offline = true\n manifest = getCachedProfiles().map((p) => ({\n name: p.name,\n displayName: p.displayName,\n tags: [],\n description: '',\n keywords: [],\n detect: p.detect,\n }))\n }\n } else {\n // Refresh in background — best effort, don't block output\n cacheManifest().catch(() => undefined)\n }\n\n if (offline) {\n log.warn('Registry unreachable — showing installed profiles only')\n }\n\n if (manifest.length === 0) {\n log.plain('No profiles available. Check your connection and try again.')\n return\n }\n\n // Group by tag\n const grouped = new Map<string, typeof manifest>()\n for (const entry of manifest) {\n const tag = entry.tags[0] ?? 'other'\n if (!grouped.has(tag)) grouped.set(tag, [])\n grouped.get(tag)!.push(entry)\n }\n\n log.plain('')\n for (const [tag, entries] of grouped) {\n log.plain(chalk.bold(` ${tag.charAt(0).toUpperCase() + tag.slice(1)} profiles`))\n log.plain(chalk.dim(' ' + '─'.repeat(60)))\n for (const entry of entries) {\n const badge = activeNames.has(entry.name) ? chalk.green(' [active]') : ''\n const installed = fs.existsSync(path.join(PROFILES_DIR, `${entry.name}.json`)) ? chalk.dim(' installed') : ''\n log.plain(` ${chalk.cyan(entry.name.padEnd(18))} ${entry.displayName.padEnd(28)}${badge}${installed}`)\n if (entry.description) log.plain(` ${chalk.dim(' '.repeat(18) + entry.description)}`)\n }\n log.plain('')\n }\n })\n\n // ─── add ──────────────────────────────────────────────────────────────────\n profile\n .command('add <names...>')\n .description('Install one or more profiles from the registry')\n .action(async (names: string[]) => {\n const config = readConfig()\n const activeNames = new Set(config.capture.profiles)\n\n for (const name of names) {\n if (activeNames.has(name)) {\n log.info(`Profile \"${name}\" is already active`)\n continue\n }\n try {\n log.plain(`Fetching ${chalk.cyan(name)}…`)\n await installProfile(name)\n activeNames.add(name)\n log.success(`Profile \"${name}\" installed`)\n } catch (err) {\n log.error(`Failed to install \"${name}\": ${(err as Error).message}`)\n }\n }\n\n config.capture.profiles = [...activeNames]\n writeConfig(config)\n })\n\n // ─── remove ───────────────────────────────────────────────────────────────\n profile\n .command('remove <names...>')\n .description('Uninstall one or more profiles')\n .action((names: string[]) => {\n const config = readConfig()\n const activeNames = new Set(config.capture.profiles)\n\n for (const name of names) {\n if (!activeNames.has(name)) {\n log.warn(`Profile \"${name}\" is not active`)\n continue\n }\n activeNames.delete(name)\n const cachePath = path.join(PROFILES_DIR, `${name}.json`)\n if (fs.existsSync(cachePath)) fs.unlinkSync(cachePath)\n log.success(`Profile \"${name}\" removed`)\n }\n\n config.capture.profiles = [...activeNames]\n writeConfig(config)\n })\n\n // ─── update ───────────────────────────────────────────────────────────────\n profile\n .command('update [name]')\n .description('Re-fetch installed profiles from the registry')\n .action(async (name?: string) => {\n const config = readConfig()\n const toUpdate = name ? [name] : config.capture.profiles\n\n if (toUpdate.length === 0) {\n log.plain('No profiles installed. Run workscribe profile add <name> first.')\n return\n }\n\n for (const profileName of toUpdate) {\n try {\n log.plain(`Updating ${chalk.cyan(profileName)}…`)\n await installProfile(profileName)\n log.success(`${profileName} updated`)\n } catch (err) {\n log.error(`Failed to update \"${profileName}\": ${(err as Error).message}`)\n }\n }\n })\n\n // ─── detect ───────────────────────────────────────────────────────────────\n profile\n .command('detect')\n .description('Scan the current directory and suggest matching profiles')\n .action(() => {\n const cwd = process.cwd()\n const matches = detectProfilesForDirectory(cwd)\n\n if (matches.length === 0) {\n const cached = readCachedManifest()\n if (!cached) {\n log.plain('No manifest cached. Run workscribe profile list to fetch it first.')\n } else {\n log.plain(`No profiles detected for ${chalk.dim(cwd)}`)\n log.plain(chalk.dim('Run workscribe profile list to browse available profiles.'))\n }\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(' Profiles detected for this directory:'))\n log.plain('')\n for (const entry of matches) {\n const files = entry.detect?.files?.join(', ') ?? ''\n log.plain(` ${chalk.cyan(entry.name.padEnd(18))} ${entry.displayName} ${chalk.dim('(' + files + ')')}`)\n }\n log.plain('')\n log.plain(` Run: ${chalk.cyan('workscribe profile add ' + matches.map((e) => e.name).join(' '))}`)\n log.plain('')\n })\n\n // ─── suggest ──────────────────────────────────────────────────────────────\n profile\n .command('suggest')\n .description('Analyse recent unclassified commands and suggest profiles')\n .option('--days <n>', 'number of days to analyse', '30')\n .action((opts) => {\n const days = Math.max(1, parseInt(opts.days as string, 10) || 30)\n const toolCounts = getOtherEventToolCounts(days)\n\n if (toolCounts.length === 0) {\n log.plain('No unclassified commands found in the last ' + days + ' days.')\n return\n }\n\n const manifest = readCachedManifest()\n if (!manifest) {\n log.plain('No manifest cached. Run workscribe profile list first.')\n return\n }\n\n const config = readConfig()\n const activeNames = new Set(config.capture.profiles)\n\n // Match tool counts against manifest keywords\n const suggestions: { entry: (typeof manifest)[number]; count: number }[] = []\n for (const entry of manifest) {\n if (activeNames.has(entry.name)) continue\n const matchedCount = toolCounts\n .filter((tc) => entry.keywords.some((kw) => tc.tool.toLowerCase().includes(kw.toLowerCase())))\n .reduce((sum, tc) => sum + tc.count, 0)\n if (matchedCount >= MIN_SUGGEST_COUNT) {\n suggestions.push({ entry, count: matchedCount })\n }\n }\n\n suggestions.sort((a, b) => b.count - a.count)\n\n if (suggestions.length === 0) {\n log.plain('No profile matches found. Your commands are well covered.')\n return\n }\n\n log.plain('')\n log.plain(chalk.bold(` Analysed last ${days} days of unclassified commands:`))\n log.plain('')\n for (const { entry, count } of suggestions) {\n log.plain(\n ` ${chalk.cyan(entry.name.padEnd(18))} ${String(count).padStart(4)} commands → ${entry.displayName}`\n )\n }\n log.plain('')\n log.plain(` Run: ${chalk.cyan('workscribe profile add ' + suggestions.map((s) => s.entry.name).join(' '))}`)\n log.plain('')\n })\n}\n","import { Command } from 'commander'\nimport { insertEvent } from '../db'\nimport { getGitContext } from '../capture/git'\nimport { log } from '../utils/logger'\n\nexport function registerNote(program: Command): void {\n program\n .command('note <text>')\n .description('Attach a free-text annotation to the current session')\n .action((text: string) => {\n const { repoName, branch } = getGitContext(process.cwd())\n insertEvent({\n captured_at: new Date().toISOString(),\n command: 'workscribe note',\n cwd: process.cwd(),\n exit_code: null,\n duration_ms: null,\n repo_name: repoName,\n branch,\n category: 'note',\n metadata: JSON.stringify({ text }),\n })\n log.success(`Note saved${repoName ? ` to ${repoName}` : ''}`)\n })\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport fs from 'fs'\nimport path from 'path'\nimport os from 'os'\nimport { getOrBuildSessions } from '../sessions/detector'\nimport { getProvider } from '../ai/router'\nimport { readConfig } from '../config'\nimport { log } from '../utils/logger'\nimport { todayDate, startOfWeek, eachDayOfRange, isoWeekKey, formatDate } from '../utils/format'\nimport { postToWebhook } from '../integrations/webhook'\nimport { formatForSlack, isSlackWebhookUrl } from '../integrations/slack'\nimport { WEEKLY_CACHE_DIR } from '../utils/paths'\nimport type { WeekSummaryPayload, SessionPayload, EventPayload } from '../ai/types'\nimport type { EventRow } from '../db'\n\nfunction eventRowToPayload(row: EventRow): EventPayload {\n let metadata: Record<string, unknown> = {}\n try {\n if (row.metadata) metadata = JSON.parse(row.metadata)\n } catch {\n /* ignore */\n }\n const payload: EventPayload = {\n category: row.category,\n metadata,\n exitCode: row.exit_code,\n durationMs: row.duration_ms,\n }\n if (row.category === 'other' && typeof metadata.hint === 'string') {\n payload.hint = metadata.hint\n const { hint: _hint, tool: _tool, ...rest } = metadata\n payload.metadata = rest\n }\n return payload\n}\n\nfunction sessionToPayload(session: ReturnType<typeof getOrBuildSessions>[number], date: string): SessionPayload {\n return {\n date,\n project: session.repoName,\n branch: session.events[0]?.branch ?? null,\n startTime: formatDate(session.startedAt),\n endTime: formatDate(session.endedAt),\n durationMinutes: session.durationMinutes,\n events: session.events.map(eventRowToPayload),\n }\n}\n\nasync function postSummary(\n opts: { slack?: boolean; webhook?: string },\n config: ReturnType<typeof readConfig>,\n summary: string\n): Promise<void> {\n const webhookUrl = opts.webhook ?? (opts.slack ? config.integrations?.slackWebhook : undefined)\n if (!webhookUrl) {\n if (opts.slack) log.warn('--slack requires integrations.slackWebhook to be set in config')\n return\n }\n try {\n log.info('Posting to webhook…')\n const username = os.userInfo().username\n const body = isSlackWebhookUrl(webhookUrl) ? formatForSlack(summary, username) : summary\n await postToWebhook(webhookUrl, body)\n log.success('Posted.')\n } catch (error) {\n log.error(`Webhook failed: ${(error as Error).message}`)\n }\n}\n\nexport function registerWeek(program: Command): void {\n program\n .command('week')\n .description('Generate an AI weekly digest (Mon–today)')\n .option('--fresh', 'bypass cache and regenerate')\n .option('--slack', 'post to Slack webhook from config')\n .option('--webhook <url>', 'post to a custom webhook URL')\n .action(async (opts) => {\n const config = readConfig()\n let provider\n try {\n provider = getProvider(config)\n } catch (error) {\n log.error((error as Error).message)\n process.exit(1)\n }\n\n const today = todayDate()\n const weekStart = startOfWeek(today)\n const days = eachDayOfRange(weekStart, today)\n\n const weeklyDays: WeekSummaryPayload['days'] = []\n for (const day of days) {\n const sessions = getOrBuildSessions(day)\n if (sessions.length > 0) {\n weeklyDays.push({ date: day, sessions: sessions.map((session) => sessionToPayload(session, day)) })\n }\n }\n\n if (weeklyDays.length === 0) {\n log.plain('No activity captured this week.')\n return\n }\n\n const cacheKey = isoWeekKey(today)\n const cacheFile = path.join(WEEKLY_CACHE_DIR, `${cacheKey}.md`)\n\n if (!opts.fresh && fs.existsSync(cacheFile)) {\n const cached = fs.readFileSync(cacheFile, 'utf-8')\n log.plain('')\n log.plain(cached)\n log.plain('')\n log.plain(chalk.dim(' (cached — use --fresh to regenerate)'))\n await postSummary(opts, config, cached)\n return\n }\n\n const payload: WeekSummaryPayload = { weekStart, weekEnd: today, days: weeklyDays }\n\n log.plain('')\n log.info(`Generating weekly digest via ${chalk.cyan(config.ai.provider)}…`)\n\n try {\n const summary = provider.summarizeWeek\n ? await provider.summarizeWeek(payload)\n : await provider.summarize({ date: today, sessions: weeklyDays.flatMap((day) => day.sessions) })\n\n log.plain('')\n log.plain(summary)\n log.plain('')\n\n fs.mkdirSync(WEEKLY_CACHE_DIR, { recursive: true })\n fs.writeFileSync(cacheFile, summary, { encoding: 'utf-8', mode: 0o600 })\n\n await postSummary(opts, config, summary)\n } catch (error) {\n log.error(`Weekly digest failed [${config.ai.provider}]: ${(error as Error).message}`)\n process.exit(1)\n }\n })\n}\n"],"mappings":"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","names":["import_fs","path","os","fs","migration","import_path","import_fs","fs","path","import_child_process","import_fs","import_path","path","fs","import_fs","import_os","import_path","import_fs","chalk","fs","path","os","fs","import_fs","import_path","import_fs","fs","import_fs","import_path","path","fs","path","fs","fs","path","fs","program","program","import_fs","import_path","import_os","import_chalk","import_fs","import_path","fs","path","import_fs","import_path","import_os","import_child_process","path","os","fs","path","os","chalk","program","fs","prompts","import_fs","import_chalk","program","fs","chalk","import_chalk","chalk","program","import_chalk","program","chalk","import_chalk","import_fs","import_os","import_path","os","program","sessions","path","fs","chalk","fullSummary","import_fs","import_path","eventRowToPayload","program","path","fs","import_chalk","program","chalk","import_fs","program","fs","program","import_chalk","import_prompts","program","chalk","prompts","import_fs","import_path","import_os","import_prompts","import_chalk","path","os","fs","program","chalk","prompts","import_fs","import_path","import_chalk","program","chalk","fs","path","program","import_chalk","import_fs","import_path","import_os","eventRowToPayload","sessionToPayload","os","program","path","fs","chalk"]}