mindcontext-cli 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/init.ts","../src/lib/config.ts","../src/lib/machine-id.ts","../src/lib/git-ops.ts","../src/commands/connect.ts","../src/parsers/openspec.ts","../src/lib/templates.ts","../src/commands/sync.ts","../src/lib/update-file.ts","../src/commands/pull.ts","../src/commands/context.ts","../src/commands/progress.ts","../src/commands/config.ts","../src/commands/cleanup.ts","../src/commands/reset.ts","../src/commands/migrate.ts","../src/cli.ts"],"sourcesContent":["import { existsSync, mkdirSync } from 'fs';\nimport { createInterface } from 'readline';\nimport {\n getMindcontextDir,\n getRepoDir,\n isInitialized,\n createDefaultConfig,\n writeConfig,\n readConfig,\n} from '../lib/config.js';\nimport { cloneRepo } from '../lib/git-ops.js';\n\n/**\n * Prompt user for input.\n */\nasync function prompt(question: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise(resolve => {\n rl.question(question, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Initialize mindcontext.\n */\nexport async function init(options: { quiet?: boolean } = {}): Promise<void> {\n const mindcontextDir = getMindcontextDir();\n const repoDir = getRepoDir();\n\n // Check if already initialized\n if (isInitialized()) {\n const config = readConfig();\n if (!options.quiet) {\n console.log('MindContext is already initialized.');\n console.log(` Directory: ${mindcontextDir}`);\n console.log(` Dashboard: ${config?.dashboard_url || 'Not configured'}`);\n console.log(` Projects: ${Object.keys(config?.projects || {}).length}`);\n console.log('');\n console.log('Run \"mc reset\" to start fresh.');\n }\n return;\n }\n\n if (!options.quiet) {\n console.log('Initializing MindContext...\\n');\n }\n\n // Create directory\n if (!existsSync(mindcontextDir)) {\n mkdirSync(mindcontextDir, { recursive: true });\n }\n\n // Get dashboard repo URL\n let dashboardRepo = '';\n if (!options.quiet) {\n console.log('Enter your dashboard repository URL.');\n console.log('(Create one from https://github.com/tmsjngx0/mindcontext-template)\\n');\n dashboardRepo = await prompt('Dashboard repo URL (git@github.com:user/repo.git): ');\n }\n\n if (!dashboardRepo) {\n if (!options.quiet) {\n console.log('\\nNo dashboard URL provided. You can configure it later with:');\n console.log(' mc config --dashboard-repo <url>');\n }\n // Create config without dashboard\n const config = createDefaultConfig();\n writeConfig(config);\n if (!options.quiet) {\n console.log(`\\nCreated: ${mindcontextDir}/config.json`);\n }\n return;\n }\n\n // Clone the repo\n if (!options.quiet) {\n console.log(`\\nCloning dashboard repository...`);\n }\n\n try {\n cloneRepo(dashboardRepo, repoDir);\n } catch (error) {\n console.error('Failed to clone repository:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n\n // Extract dashboard URL from repo URL\n let dashboardUrl = '';\n const match = dashboardRepo.match(/github\\.com[:/]([^/]+)\\/([^/.]+)/);\n if (match) {\n dashboardUrl = `https://${match[1]}.github.io/${match[2]}`;\n }\n\n // Create config\n const config = createDefaultConfig();\n config.dashboard_repo = dashboardRepo;\n config.dashboard_url = dashboardUrl;\n writeConfig(config);\n\n if (!options.quiet) {\n console.log('\\n✓ MindContext initialized!');\n console.log(` Directory: ${mindcontextDir}`);\n console.log(` Dashboard: ${dashboardUrl}`);\n console.log('');\n console.log('Next steps:');\n console.log(' cd <your-project>');\n console.log(' mc connect');\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { getMachineId } from './machine-id.js';\n\nconst MINDCONTEXT_DIR = join(homedir(), '.mindcontext');\nconst CONFIG_FILE = join(MINDCONTEXT_DIR, 'config.json');\nconst REPO_DIR = join(MINDCONTEXT_DIR, 'repo');\nconst PENDING_FILE = join(MINDCONTEXT_DIR, 'pending.json');\n\nexport interface ProjectConfig {\n path: string;\n openspec: boolean;\n category: string;\n}\n\nexport interface Config {\n version: string;\n dashboard_repo: string;\n dashboard_url: string;\n projects: Record<string, ProjectConfig>;\n machine: {\n name: string;\n id: string;\n };\n}\n\nexport interface PendingPush {\n timestamp: string;\n message: string;\n}\n\n/**\n * Get the mindcontext directory path.\n */\nexport function getMindcontextDir(): string {\n return MINDCONTEXT_DIR;\n}\n\n/**\n * Get the repo directory path.\n */\nexport function getRepoDir(): string {\n return REPO_DIR;\n}\n\n/**\n * Check if mindcontext is initialized.\n */\nexport function isInitialized(): boolean {\n return existsSync(CONFIG_FILE) && existsSync(REPO_DIR);\n}\n\n/**\n * Create default config structure.\n */\nexport function createDefaultConfig(): Config {\n const machine = getMachineId();\n return {\n version: '1.0',\n dashboard_repo: '',\n dashboard_url: '',\n projects: {},\n machine,\n };\n}\n\n/**\n * Read the config file.\n */\nexport function readConfig(): Config | null {\n if (!existsSync(CONFIG_FILE)) {\n return null;\n }\n try {\n const content = readFileSync(CONFIG_FILE, 'utf8');\n return JSON.parse(content) as Config;\n } catch {\n return null;\n }\n}\n\n/**\n * Write the config file.\n */\nexport function writeConfig(config: Config): void {\n if (!existsSync(MINDCONTEXT_DIR)) {\n mkdirSync(MINDCONTEXT_DIR, { recursive: true });\n }\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));\n}\n\n/**\n * Read pending pushes.\n */\nexport function readPending(): PendingPush[] {\n if (!existsSync(PENDING_FILE)) {\n return [];\n }\n try {\n const content = readFileSync(PENDING_FILE, 'utf8');\n return JSON.parse(content) as PendingPush[];\n } catch {\n return [];\n }\n}\n\n/**\n * Write pending pushes.\n */\nexport function writePending(pending: PendingPush[]): void {\n writeFileSync(PENDING_FILE, JSON.stringify(pending, null, 2));\n}\n\n/**\n * Add a pending push.\n */\nexport function addPending(message: string): void {\n const pending = readPending();\n pending.push({\n timestamp: new Date().toISOString(),\n message,\n });\n writePending(pending);\n}\n\n/**\n * Clear pending pushes.\n */\nexport function clearPending(): void {\n if (existsSync(PENDING_FILE)) {\n writeFileSync(PENDING_FILE, '[]');\n }\n}\n\n/**\n * Get project directory in repo.\n */\nexport function getProjectDir(projectName: string): string {\n return join(REPO_DIR, 'projects', projectName, 'updates');\n}\n\n/**\n * Ensure project directory exists.\n */\nexport function ensureProjectDir(projectName: string): void {\n const dir = getProjectDir(projectName);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n","import { createHash } from 'crypto';\nimport { hostname, userInfo } from 'os';\nimport { execSync } from 'child_process';\n\n/**\n * Generate a unique machine identifier based on hostname, username, and git email.\n * Used to create unique filenames for update files.\n */\nexport function getMachineId(): { name: string; id: string } {\n const host = hostname();\n const user = userInfo().username;\n\n // Try to get git email for additional uniqueness\n let gitEmail = '';\n try {\n gitEmail = execSync('git config user.email', { encoding: 'utf8' }).trim();\n } catch {\n // Git not configured, use empty string\n }\n\n // Create hash for ID\n const hash = createHash('sha256')\n .update(`${host}-${user}-${gitEmail}`)\n .digest('hex')\n .substring(0, 8);\n\n // Create readable name\n const name = `${user}-${host}`.toLowerCase().replace(/[^a-z0-9-]/g, '-');\n\n return { name, id: hash };\n}\n\n/**\n * Generate a timestamp string safe for filenames.\n * Format: YYYY-MM-DDTHH-MM-SS (uses dashes instead of colons)\n */\nexport function getTimestamp(): string {\n const now = new Date();\n return now.toISOString().replace(/:/g, '-').replace(/\\.\\d{3}Z$/, '');\n}\n\n/**\n * Generate a unique update filename.\n * Format: {timestamp}_{machine-name}_{machine-id}.json\n */\nexport function generateUpdateFilename(): string {\n const { name, id } = getMachineId();\n const timestamp = getTimestamp();\n return `${timestamp}_${name}_${id}.json`;\n}\n","import { execSync, ExecSyncOptionsWithStringEncoding } from 'child_process';\nimport { existsSync } from 'fs';\nimport { getRepoDir, addPending, readPending, clearPending } from './config.js';\n\nconst execOptions: ExecSyncOptionsWithStringEncoding = {\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'pipe'],\n};\n\n/**\n * Check if we have network connectivity to GitHub.\n */\nexport function isOnline(): boolean {\n try {\n execSync('git ls-remote --exit-code origin HEAD', {\n ...execOptions,\n cwd: getRepoDir(),\n timeout: 5000,\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Clone the dashboard repository.\n */\nexport function cloneRepo(repoUrl: string, targetDir: string): void {\n execSync(`git clone \"${repoUrl}\" \"${targetDir}\"`, execOptions);\n}\n\n/**\n * Pull latest changes from remote.\n */\nexport function pull(): { success: boolean; message: string } {\n const repoDir = getRepoDir();\n if (!existsSync(repoDir)) {\n return { success: false, message: 'Repository not initialized' };\n }\n\n try {\n const output = execSync('git pull --rebase origin main', {\n ...execOptions,\n cwd: repoDir,\n });\n return { success: true, message: output.trim() };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Pull failed';\n return { success: false, message };\n }\n}\n\n/**\n * Stage all changes.\n */\nexport function stageAll(): void {\n const repoDir = getRepoDir();\n execSync('git add -A', { ...execOptions, cwd: repoDir });\n}\n\n/**\n * Create a commit.\n */\nexport function commit(message: string): { success: boolean; message: string } {\n const repoDir = getRepoDir();\n try {\n // Check if there are changes to commit\n const status = execSync('git status --porcelain', {\n ...execOptions,\n cwd: repoDir,\n });\n if (!status.trim()) {\n return { success: true, message: 'Nothing to commit' };\n }\n\n stageAll();\n execSync(`git commit -m \"${message.replace(/\"/g, '\\\\\"')}\"`, {\n ...execOptions,\n cwd: repoDir,\n });\n return { success: true, message: 'Committed' };\n } catch (error) {\n const msg = error instanceof Error ? error.message : 'Commit failed';\n return { success: false, message: msg };\n }\n}\n\n/**\n * Push changes to remote.\n */\nexport function push(): { success: boolean; message: string } {\n const repoDir = getRepoDir();\n try {\n execSync('git push origin main', {\n ...execOptions,\n cwd: repoDir,\n timeout: 30000,\n });\n return { success: true, message: 'Pushed to remote' };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Push failed';\n return { success: false, message };\n }\n}\n\n/**\n * Sync: commit and push (with offline support).\n */\nexport function sync(commitMessage: string): {\n committed: boolean;\n pushed: boolean;\n message: string;\n} {\n // First, try to push any pending commits\n const pending = readPending();\n if (pending.length > 0) {\n const pushResult = push();\n if (pushResult.success) {\n clearPending();\n }\n }\n\n // Commit changes\n const commitResult = commit(commitMessage);\n if (!commitResult.success) {\n return {\n committed: false,\n pushed: false,\n message: commitResult.message,\n };\n }\n\n if (commitResult.message === 'Nothing to commit') {\n return {\n committed: false,\n pushed: false,\n message: 'No changes to sync',\n };\n }\n\n // Try to push\n const pushResult = push();\n if (!pushResult.success) {\n // Save for later\n addPending(commitMessage);\n return {\n committed: true,\n pushed: false,\n message: 'Committed locally. Push pending (offline)',\n };\n }\n\n return {\n committed: true,\n pushed: true,\n message: 'Synced successfully',\n };\n}\n\n/**\n * Get current branch name.\n */\nexport function getCurrentBranch(): string {\n const repoDir = getRepoDir();\n try {\n return execSync('git branch --show-current', {\n ...execOptions,\n cwd: repoDir,\n }).trim();\n } catch {\n return 'main';\n }\n}\n\n/**\n * Get recent commits from a project directory.\n * Returns commit messages (not from mindcontext repo, but from the user's project).\n */\nexport function getRecentCommits(projectPath: string, limit = 5): string[] {\n try {\n const output = execSync(\n `git log --oneline -${limit} --format=\"%s\"`,\n { ...execOptions, cwd: projectPath }\n );\n return output\n .trim()\n .split('\\n')\n .filter(line => line.length > 0);\n } catch {\n return [];\n }\n}\n","import { basename, resolve, join } from 'path';\nimport { existsSync, mkdirSync, writeFileSync } from 'fs';\nimport { isInitialized, readConfig, writeConfig, ensureProjectDir } from '../lib/config.js';\nimport { hasOpenSpec } from '../parsers/openspec.js';\nimport { COMMAND_TEMPLATES, HOOK_TEMPLATES } from '../lib/templates.js';\n\nexport interface ConnectOptions {\n category?: string;\n name?: string;\n quiet?: boolean;\n withHooks?: boolean;\n}\n\n/**\n * Connect current project to mindcontext.\n */\nexport async function connect(options: ConnectOptions = {}): Promise<void> {\n // Check if initialized\n if (!isInitialized()) {\n console.error('MindContext is not initialized. Run \"mc init\" first.');\n process.exit(1);\n }\n\n const config = readConfig();\n if (!config) {\n console.error('Failed to read config.');\n process.exit(1);\n }\n\n // Get project path and name\n const projectPath = resolve(process.cwd());\n const projectName = options.name || basename(projectPath);\n\n // Check if already connected\n if (config.projects[projectName]) {\n if (!options.quiet) {\n console.log(`Project \"${projectName}\" is already connected.`);\n console.log(` Path: ${config.projects[projectName].path}`);\n console.log(` Category: ${config.projects[projectName].category}`);\n console.log(` OpenSpec: ${config.projects[projectName].openspec ? 'Yes' : 'No'}`);\n }\n return;\n }\n\n // Detect OpenSpec\n const openspec = hasOpenSpec(projectPath);\n\n // Add project to config\n config.projects[projectName] = {\n path: projectPath,\n openspec,\n category: options.category || 'default',\n };\n writeConfig(config);\n\n // Create project directory in repo\n ensureProjectDir(projectName);\n\n // Generate .claude/commands/mc/ templates\n const claudeDir = join(projectPath, '.claude');\n const commandsDir = join(claudeDir, 'commands', 'mc');\n\n if (!existsSync(commandsDir)) {\n mkdirSync(commandsDir, { recursive: true });\n\n // Write command templates\n for (const [filename, content] of Object.entries(COMMAND_TEMPLATES)) {\n writeFileSync(join(commandsDir, filename), content);\n }\n\n if (!options.quiet) {\n console.log(`✓ Created .claude/commands/mc/`);\n }\n }\n\n // Optionally generate hooks\n if (options.withHooks) {\n const hooksDir = join(claudeDir, 'hooks');\n if (!existsSync(hooksDir)) {\n mkdirSync(hooksDir, { recursive: true });\n\n for (const [filename, content] of Object.entries(HOOK_TEMPLATES)) {\n writeFileSync(join(hooksDir, filename), content);\n }\n\n if (!options.quiet) {\n console.log(`✓ Created .claude/hooks/`);\n }\n }\n }\n\n if (!options.quiet) {\n console.log(`✓ Connected \"${projectName}\"`);\n console.log(` Path: ${projectPath}`);\n console.log(` Category: ${options.category || 'default'}`);\n console.log(` OpenSpec: ${openspec ? 'Detected' : 'Not found'}`);\n console.log('');\n console.log('Next: Run \"mc sync\" to create your first update.');\n }\n}\n","import { existsSync, readdirSync, readFileSync } from 'fs';\nimport { join, basename } from 'path';\n\nexport interface OpenSpecChange {\n id: string;\n tasksTotal: number;\n tasksComplete: number;\n status: 'proposed' | 'in_progress' | 'review' | 'done';\n}\n\nexport interface OpenSpecResult {\n found: boolean;\n changes: OpenSpecChange[];\n activeChange: OpenSpecChange | null;\n}\n\n/**\n * Check if a directory has OpenSpec structure.\n */\nexport function hasOpenSpec(projectPath: string): boolean {\n const openspecDir = join(projectPath, 'openspec');\n return existsSync(openspecDir) && existsSync(join(openspecDir, 'changes'));\n}\n\n/**\n * Parse tasks.md to count completed vs total tasks.\n */\nfunction parseTasksFile(filepath: string): { total: number; complete: number } {\n if (!existsSync(filepath)) {\n return { total: 0, complete: 0 };\n }\n\n const content = readFileSync(filepath, 'utf8');\n const lines = content.split('\\n');\n\n let total = 0;\n let complete = 0;\n\n for (const line of lines) {\n // Match markdown checkbox: - [ ] or - [x]\n if (/^\\s*-\\s*\\[\\s*\\]\\s/.test(line)) {\n total++;\n } else if (/^\\s*-\\s*\\[x\\]\\s/i.test(line)) {\n total++;\n complete++;\n }\n }\n\n return { total, complete };\n}\n\n/**\n * Determine change status based on tasks.\n */\nfunction determineStatus(tasksTotal: number, tasksComplete: number): OpenSpecChange['status'] {\n if (tasksTotal === 0) {\n return 'proposed';\n }\n if (tasksComplete === 0) {\n return 'proposed';\n }\n if (tasksComplete === tasksTotal) {\n return 'done';\n }\n // Check if any task is in review (you could expand this)\n return 'in_progress';\n}\n\n/**\n * Parse a single change directory.\n */\nfunction parseChange(changePath: string): OpenSpecChange | null {\n const id = basename(changePath);\n\n // Skip archive directory\n if (id === 'archive') {\n return null;\n }\n\n const tasksFile = join(changePath, 'tasks.md');\n const { total, complete } = parseTasksFile(tasksFile);\n\n return {\n id,\n tasksTotal: total,\n tasksComplete: complete,\n status: determineStatus(total, complete),\n };\n}\n\n/**\n * Parse all OpenSpec changes in a project.\n */\nexport function parseOpenSpec(projectPath: string): OpenSpecResult {\n if (!hasOpenSpec(projectPath)) {\n return { found: false, changes: [], activeChange: null };\n }\n\n const changesDir = join(projectPath, 'openspec', 'changes');\n const entries = readdirSync(changesDir, { withFileTypes: true });\n const changes: OpenSpecChange[] = [];\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const change = parseChange(join(changesDir, entry.name));\n if (change) {\n changes.push(change);\n }\n }\n }\n\n // Find active change (in_progress or proposed with tasks)\n let activeChange: OpenSpecChange | null = null;\n\n // Priority: in_progress > review > proposed with tasks\n for (const change of changes) {\n if (change.status === 'in_progress') {\n activeChange = change;\n break;\n }\n }\n\n if (!activeChange) {\n for (const change of changes) {\n if (change.status === 'review') {\n activeChange = change;\n break;\n }\n }\n }\n\n if (!activeChange) {\n for (const change of changes) {\n if (change.status === 'proposed' && change.tasksTotal > 0) {\n activeChange = change;\n break;\n }\n }\n }\n\n return { found: true, changes, activeChange };\n}\n\n/**\n * Get progress data from OpenSpec.\n */\nexport function getOpenSpecProgress(projectPath: string): {\n source: 'openspec' | 'manual';\n change?: string;\n tasks_done: number;\n tasks_total: number;\n} {\n const result = parseOpenSpec(projectPath);\n\n if (!result.found || !result.activeChange) {\n return {\n source: 'manual',\n tasks_done: 0,\n tasks_total: 0,\n };\n }\n\n return {\n source: 'openspec',\n change: result.activeChange.id,\n tasks_done: result.activeChange.tasksComplete,\n tasks_total: result.activeChange.tasksTotal,\n };\n}\n","/**\n * Templates for .claude/ generation.\n * Embedded in code for easy npm distribution.\n */\n\nexport const COMMAND_TEMPLATES = {\n 'prime.md': `---\ndescription: Load context and show what to work on\n---\n\n# Prime Context\n\nLoad project context at the start of your session.\n\n## Step 1: Get Current Context\n\n\\`\\`\\`bash\nmc context --json\n\\`\\`\\`\n\n## Step 2: Load Last Session Notes\n\nFrom the context output, identify:\n- **Last session summary** - What was accomplished\n- **Next tasks** - What was planned for this session\n- **Current change** - The OpenSpec change being worked on\n- **Progress** - Tasks completed vs total\n\n## Step 3: Show Context Summary\n\nDisplay to the user:\n\n\\`\\`\\`\nSESSION CONTEXT LOADED\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nProject: [project name]\nChange: [current openspec change]\nProgress: [tasks_done]/[tasks_total] ([percentage]%)\n\nLast Session:\n- [notes from last update]\n\nPlanned for This Session:\n- [next tasks from last update]\n\\`\\`\\`\n\n## Step 4: Suggest Next Action\n\nBased on context, suggest what to work on next.\n`,\n\n 'update.md': `---\ndescription: Save session context and sync progress\n---\n\n# Update Context\n\nSave your session progress with auto-generated context.\n\n## Step 1: Generate Session Summary\n\nFrom your conversation context, summarize what was accomplished:\n- Recent code changes and commits\n- Tasks completed\n- Features implemented or bugs fixed\n\nCreate 3-5 concise bullet points.\n\n## Step 2: Generate Next Tasks\n\nFrom OpenSpec and conversation context, identify what should be done next:\n- Remaining tasks from current OpenSpec change\n- Blockers or pending items mentioned\n\nCreate 2-4 actionable next task items.\n\n## Step 3: Run mc sync\n\n\\`\\`\\`bash\nmc sync --notes \"First accomplishment\nSecond accomplishment\" --next \"Next task 1\nNext task 2\"\n\\`\\`\\`\n\nUse multiline strings - each line becomes one item.\n\n## Step 4: Show Confirmation\n\n\\`\\`\\`\nPROGRESS SYNCED\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nSession Summary:\n- [generated notes]\n\nNext Session:\n- [generated next tasks]\n\\`\\`\\`\n`,\n\n 'progress.md': `---\ndescription: Show progress\n---\n\nRun \\`mc progress\\` to see current progress in the terminal.\n\nOptions:\n- \\`--web\\` - Open the web dashboard in your browser\n\nThis aggregates all update files to show:\n- Current change and task completion\n- Recent activity across machines\n- Team member status (if collaborative)\n`,\n\n 'context.md': `---\ndescription: Output current context\n---\n\nRun \\`mc context\\` to output the current project context.\n\nOptions:\n- \\`--json\\` - Output as JSON (for integration with other tools)\n\nThis shows:\n- Project connection status\n- Current OpenSpec change and progress\n- Last update details\n- Team activity summary\n`,\n};\n\nexport const HOOK_TEMPLATES = {\n 'session-end.js': `const { execSync } = require('child_process');\n\nmodule.exports = async function() {\n try {\n execSync('mc sync --quiet', {\n stdio: 'inherit',\n timeout: 10000\n });\n } catch (e) {\n // Sync failed silently - don't block session end\n }\n};\n`,\n};\n","import { basename, resolve } from 'path';\nimport { isInitialized, readConfig } from '../lib/config.js';\nimport { sync as gitSync, getRecentCommits } from '../lib/git-ops.js';\nimport { createUpdateFile, ContextData } from '../lib/update-file.js';\nimport { getOpenSpecProgress } from '../parsers/openspec.js';\n\nexport interface SyncOptions {\n quiet?: boolean;\n dryRun?: boolean;\n notes?: string[];\n next?: string[];\n status?: ContextData['status'];\n}\n\n/**\n * Sync progress for current project.\n */\nexport async function sync(options: SyncOptions = {}): Promise<void> {\n // Check if initialized\n if (!isInitialized()) {\n if (!options.quiet) {\n console.error('MindContext is not initialized. Run \"mc init\" first.');\n }\n process.exit(1);\n }\n\n const config = readConfig();\n if (!config) {\n if (!options.quiet) {\n console.error('Failed to read config.');\n }\n process.exit(1);\n }\n\n // Get current project\n const projectPath = resolve(process.cwd());\n const projectName = basename(projectPath);\n\n // Check if project is connected\n const project = config.projects[projectName];\n if (!project) {\n if (!options.quiet) {\n console.error(`Project \"${projectName}\" is not connected.`);\n console.error('Run \"mc connect\" first.');\n }\n process.exit(1);\n }\n\n // Get progress from OpenSpec\n const progress = getOpenSpecProgress(projectPath);\n\n // Build context\n const context: ContextData = {\n current_task: progress.change ? `Working on ${progress.change}` : undefined,\n status: options.status || (progress.tasks_done > 0 ? 'in_progress' : 'idle'),\n notes: options.notes || [],\n next: options.next || [],\n };\n\n if (!options.quiet) {\n console.log(`Syncing \"${projectName}\"...`);\n if (progress.source === 'openspec') {\n console.log(` Change: ${progress.change}`);\n console.log(` Progress: ${progress.tasks_done}/${progress.tasks_total}`);\n }\n }\n\n // Get recent commits from project\n const recentCommits = getRecentCommits(projectPath, 5);\n\n if (options.dryRun) {\n if (!options.quiet) {\n console.log('\\n[Dry run] Would create update file:');\n console.log(JSON.stringify({ progress, context, recent_commits: recentCommits }, null, 2));\n }\n return;\n }\n\n // Create update file\n const filepath = createUpdateFile(projectName, progress, context, recentCommits);\n\n if (!options.quiet) {\n console.log(` Created: ${filepath}`);\n }\n\n // Git sync\n const commitMessage = `chore(progress): sync ${config.machine.name}`;\n const result = gitSync(commitMessage);\n\n if (!options.quiet) {\n if (result.committed && result.pushed) {\n console.log('✓ Synced successfully');\n } else if (result.committed) {\n console.log('✓ Committed locally (push pending)');\n console.log(' Run \"mc push\" when online to push changes.');\n } else {\n console.log(` ${result.message}`);\n }\n }\n}\n","import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { generateUpdateFilename as genFilename, getMachineId } from './machine-id.js';\nimport { getProjectDir, ensureProjectDir } from './config.js';\n\n// Re-export for use by other modules\nexport { genFilename as generateUpdateFilename };\n\nexport interface ProgressData {\n source: 'openspec' | 'manual';\n change?: string;\n tasks_done: number;\n tasks_total: number;\n}\n\nexport interface ContextData {\n current_task?: string;\n status: 'idle' | 'in_progress' | 'blocked' | 'review';\n notes: string[];\n next: string[];\n}\n\nexport interface UpdateFile {\n version: string;\n timestamp: string;\n machine: string;\n machine_id: string;\n project: string;\n progress: ProgressData;\n context: ContextData;\n recent_commits?: string[];\n}\n\n/**\n * Create an update file with progress and context data.\n */\nexport function createUpdateFile(\n projectName: string,\n progress: ProgressData,\n context: ContextData,\n recentCommits?: string[]\n): string {\n const { name, id } = getMachineId();\n const filename = genFilename();\n const filepath = join(getProjectDir(projectName), filename);\n\n const update: UpdateFile = {\n version: '1.0',\n timestamp: new Date().toISOString(),\n machine: name,\n machine_id: id,\n project: projectName,\n progress,\n context,\n recent_commits: recentCommits,\n };\n\n ensureProjectDir(projectName);\n writeFileSync(filepath, JSON.stringify(update, null, 2));\n\n return filepath;\n}\n\n/**\n * Read all update files for a project.\n */\nexport function readUpdateFiles(projectName: string): UpdateFile[] {\n const dir = getProjectDir(projectName);\n if (!existsSync(dir)) {\n return [];\n }\n\n const files = readdirSync(dir).filter(f => f.endsWith('.json'));\n const updates: UpdateFile[] = [];\n\n for (const file of files) {\n try {\n const content = readFileSync(join(dir, file), 'utf8');\n updates.push(JSON.parse(content) as UpdateFile);\n } catch {\n // Skip invalid files\n }\n }\n\n // Sort by timestamp descending (newest first)\n return updates.sort((a, b) =>\n new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n}\n\n/**\n * Get the latest update for a project.\n */\nexport function getLatestUpdate(projectName: string): UpdateFile | null {\n const updates = readUpdateFiles(projectName);\n return updates[0] || null;\n}\n\n/**\n * Get the latest update for each machine for a project.\n */\nexport function getLatestByMachine(projectName: string): Map<string, UpdateFile> {\n const updates = readUpdateFiles(projectName);\n const byMachine = new Map<string, UpdateFile>();\n\n for (const update of updates) {\n if (!byMachine.has(update.machine_id)) {\n byMachine.set(update.machine_id, update);\n }\n }\n\n return byMachine;\n}\n\n/**\n * Get recent updates across all machines.\n */\nexport function getRecentUpdates(projectName: string, limit = 10): UpdateFile[] {\n const updates = readUpdateFiles(projectName);\n return updates.slice(0, limit);\n}\n","import { isInitialized } from '../lib/config.js';\nimport { pull as gitPull } from '../lib/git-ops.js';\n\nexport interface PullOptions {\n quiet?: boolean;\n}\n\n/**\n * Pull latest updates from remote.\n */\nexport async function pull(options: PullOptions = {}): Promise<void> {\n // Check if initialized\n if (!isInitialized()) {\n if (!options.quiet) {\n console.error('MindContext is not initialized. Run \"mc init\" first.');\n }\n process.exit(1);\n }\n\n if (!options.quiet) {\n console.log('Pulling latest updates...');\n }\n\n const result = gitPull();\n\n if (!options.quiet) {\n if (result.success) {\n console.log('✓ Updated');\n if (result.message && result.message !== 'Already up to date.') {\n console.log(` ${result.message}`);\n }\n } else {\n console.error('✗ Failed to pull');\n console.error(` ${result.message}`);\n }\n }\n}\n","import { basename, resolve } from 'path';\nimport { isInitialized, readConfig } from '../lib/config.js';\nimport { getLatestByMachine, getLatestUpdate, UpdateFile } from '../lib/update-file.js';\nimport { getOpenSpecProgress, parseOpenSpec } from '../parsers/openspec.js';\n\nexport interface ContextOptions {\n json?: boolean;\n quiet?: boolean;\n}\n\nexport interface ContextOutput {\n project: string;\n connected: boolean;\n progress: {\n source: 'openspec' | 'manual';\n change?: string;\n tasks_done: number;\n tasks_total: number;\n percentage: number;\n };\n lastUpdate?: {\n timestamp: string;\n machine: string;\n status: string;\n notes: string[];\n next: string[];\n };\n team: Array<{\n machine: string;\n timestamp: string;\n status: string;\n }>;\n}\n\n/**\n * Output current context for mindcontext-core integration.\n */\nexport async function context(options: ContextOptions = {}): Promise<void> {\n const projectPath = resolve(process.cwd());\n const projectName = basename(projectPath);\n\n // Check if initialized\n const initialized = isInitialized();\n const config = initialized ? readConfig() : null;\n const project = config?.projects[projectName];\n\n // Get progress from OpenSpec\n const progress = getOpenSpecProgress(projectPath);\n const percentage =\n progress.tasks_total > 0\n ? Math.round((progress.tasks_done / progress.tasks_total) * 100)\n : 0;\n\n // Build context output\n const output: ContextOutput = {\n project: projectName,\n connected: !!project,\n progress: {\n ...progress,\n percentage,\n },\n team: [],\n };\n\n // Get updates if connected\n if (project) {\n const latestUpdate = getLatestUpdate(projectName);\n if (latestUpdate) {\n output.lastUpdate = {\n timestamp: latestUpdate.timestamp,\n machine: latestUpdate.machine,\n status: latestUpdate.context.status,\n notes: latestUpdate.context.notes,\n next: latestUpdate.context.next,\n };\n }\n\n // Get team status\n const byMachine = getLatestByMachine(projectName);\n for (const [_machineId, update] of byMachine) {\n output.team.push({\n machine: update.machine,\n timestamp: update.timestamp,\n status: update.context.status,\n });\n }\n }\n\n if (options.json) {\n console.log(JSON.stringify(output, null, 2));\n return;\n }\n\n // Human-readable output\n if (!options.quiet) {\n console.log(`Project: ${projectName}`);\n console.log(`Connected: ${output.connected ? 'Yes' : 'No'}`);\n console.log('');\n\n if (progress.source === 'openspec' && progress.change) {\n console.log(`Change: ${progress.change}`);\n console.log(`Progress: ${progress.tasks_done}/${progress.tasks_total} (${percentage}%)`);\n } else {\n console.log('Progress: No active change');\n }\n\n if (output.lastUpdate) {\n console.log('');\n console.log(`Last Update: ${output.lastUpdate.timestamp}`);\n console.log(` Machine: ${output.lastUpdate.machine}`);\n console.log(` Status: ${output.lastUpdate.status}`);\n if (output.lastUpdate.notes.length > 0) {\n console.log(` Notes: ${output.lastUpdate.notes.join(', ')}`);\n }\n if (output.lastUpdate.next.length > 0) {\n console.log(` Next: ${output.lastUpdate.next.join(', ')}`);\n }\n }\n\n if (output.team.length > 1) {\n console.log('');\n console.log('Team Activity:');\n for (const member of output.team) {\n console.log(` ${member.machine}: ${member.status} (${member.timestamp})`);\n }\n }\n }\n}\n","import { execSync } from 'child_process';\nimport { basename, resolve } from 'path';\nimport { isInitialized, readConfig } from '../lib/config.js';\nimport { getLatestUpdate, getRecentUpdates } from '../lib/update-file.js';\nimport { getOpenSpecProgress } from '../parsers/openspec.js';\n\nexport interface ProgressOptions {\n web?: boolean;\n quiet?: boolean;\n}\n\n/**\n * Display progress or open dashboard.\n */\nexport async function progress(options: ProgressOptions = {}): Promise<void> {\n // Check if initialized\n if (!isInitialized()) {\n if (!options.quiet) {\n console.error('MindContext is not initialized. Run \"mc init\" first.');\n }\n process.exit(1);\n }\n\n const config = readConfig();\n if (!config) {\n if (!options.quiet) {\n console.error('Failed to read config.');\n }\n process.exit(1);\n }\n\n // Open web dashboard\n if (options.web) {\n if (!config.dashboard_url) {\n if (!options.quiet) {\n console.error('No dashboard URL configured.');\n console.error('Configure with: mc config --dashboard-url <url>');\n }\n process.exit(1);\n }\n\n if (!options.quiet) {\n console.log(`Opening: ${config.dashboard_url}`);\n }\n\n // Open in browser\n try {\n const platform = process.platform;\n if (platform === 'darwin') {\n execSync(`open \"${config.dashboard_url}\"`);\n } else if (platform === 'win32') {\n execSync(`start \"${config.dashboard_url}\"`);\n } else {\n execSync(`xdg-open \"${config.dashboard_url}\"`);\n }\n } catch {\n if (!options.quiet) {\n console.log(`Please open: ${config.dashboard_url}`);\n }\n }\n return;\n }\n\n // CLI progress view\n const projectPath = resolve(process.cwd());\n const projectName = basename(projectPath);\n const project = config.projects[projectName];\n\n if (!project) {\n // Show all projects\n console.log('MindContext Progress\\n');\n console.log('Projects:');\n\n for (const [name, proj] of Object.entries(config.projects)) {\n const openspecProgress = getOpenSpecProgress(proj.path);\n const percentage =\n openspecProgress.tasks_total > 0\n ? Math.round((openspecProgress.tasks_done / openspecProgress.tasks_total) * 100)\n : 0;\n\n const bar = generateProgressBar(percentage);\n console.log(` ${name}`);\n console.log(` ${bar} ${percentage}%`);\n if (openspecProgress.change) {\n console.log(` Current: ${openspecProgress.change}`);\n }\n }\n\n if (Object.keys(config.projects).length === 0) {\n console.log(' (No projects connected)');\n console.log('');\n console.log('Run \"mc connect\" in a project directory to connect it.');\n }\n\n if (config.dashboard_url) {\n console.log('');\n console.log(`Dashboard: ${config.dashboard_url}`);\n console.log('Run \"mc progress --web\" to open in browser.');\n }\n return;\n }\n\n // Show current project progress\n const openspecProgress = getOpenSpecProgress(projectPath);\n const percentage =\n openspecProgress.tasks_total > 0\n ? Math.round((openspecProgress.tasks_done / openspecProgress.tasks_total) * 100)\n : 0;\n\n console.log(`${projectName}\\n`);\n\n if (openspecProgress.source === 'openspec' && openspecProgress.change) {\n console.log(`Change: ${openspecProgress.change}`);\n console.log(`Progress: ${openspecProgress.tasks_done}/${openspecProgress.tasks_total}`);\n console.log(generateProgressBar(percentage, 30) + ` ${percentage}%`);\n } else {\n console.log('No active OpenSpec change.');\n }\n\n // Show recent updates\n const recentUpdates = getRecentUpdates(projectName, 5);\n if (recentUpdates.length > 0) {\n console.log('\\nRecent Activity:');\n for (const update of recentUpdates) {\n const date = new Date(update.timestamp).toLocaleDateString();\n const time = new Date(update.timestamp).toLocaleTimeString();\n console.log(` ${date} ${time} - ${update.machine}`);\n if (update.context.notes.length > 0) {\n console.log(` Notes: ${update.context.notes.join(', ')}`);\n }\n }\n }\n}\n\n/**\n * Generate a text-based progress bar.\n */\nfunction generateProgressBar(percentage: number, width = 20): string {\n const filled = Math.round((percentage / 100) * width);\n const empty = width - filled;\n return '█'.repeat(filled) + '░'.repeat(empty);\n}\n","import {\n isInitialized,\n readConfig,\n writeConfig,\n type Config,\n} from '../lib/config.js';\n\nexport interface ConfigOptions {\n show?: boolean;\n get?: string;\n dashboardRepo?: string;\n dashboardUrl?: string;\n quiet?: boolean;\n}\n\n/**\n * Config command - view and update mindcontext configuration.\n *\n * Usage:\n * mc config Show current config\n * mc config --get <key> Get specific config value\n * mc config --dashboard-repo <url> Set dashboard repository URL\n * mc config --dashboard-url <url> Set dashboard web URL\n */\nexport async function config(options: ConfigOptions): Promise<unknown> {\n // Check initialization\n if (!isInitialized()) {\n throw new Error('Mindcontext not initialized. Run \"mc init\" first.');\n }\n\n const currentConfig = readConfig();\n if (!currentConfig) {\n throw new Error('Failed to read config file.');\n }\n\n // Get specific key\n if (options.get) {\n const key = options.get as keyof Config;\n const value = currentConfig[key];\n if (!options.quiet) {\n if (typeof value === 'object') {\n console.log(JSON.stringify(value, null, 2));\n } else {\n console.log(value);\n }\n }\n return value;\n }\n\n // Set values\n let updated = false;\n\n if (options.dashboardRepo !== undefined) {\n currentConfig.dashboard_repo = options.dashboardRepo;\n updated = true;\n }\n\n if (options.dashboardUrl !== undefined) {\n currentConfig.dashboard_url = options.dashboardUrl;\n updated = true;\n }\n\n if (updated) {\n writeConfig(currentConfig);\n if (!options.quiet) {\n console.log('✓ Config updated');\n }\n return currentConfig;\n }\n\n // Show current config (default behavior)\n if (!options.quiet) {\n console.log('Mindcontext Configuration:\\n');\n console.log(` Dashboard Repo: ${currentConfig.dashboard_repo || '(not set)'}`);\n console.log(` Dashboard URL: ${currentConfig.dashboard_url || '(not set)'}`);\n console.log(` Machine: ${currentConfig.machine.name} (${currentConfig.machine.id})`);\n console.log(` Projects: ${Object.keys(currentConfig.projects).length} registered`);\n }\n\n return currentConfig;\n}\n","import { readdirSync, statSync, unlinkSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport {\n isInitialized,\n readConfig,\n getRepoDir,\n} from '../lib/config.js';\n\nexport interface CleanupOptions {\n olderThan?: number; // days\n dryRun?: boolean;\n quiet?: boolean;\n}\n\nexport interface CleanupResult {\n deleted: number;\n wouldDelete?: number;\n}\n\nconst DEFAULT_OLDER_THAN_DAYS = 30;\n\n/**\n * Cleanup command - remove old update files.\n *\n * Usage:\n * mc cleanup Remove files older than 30 days\n * mc cleanup --older-than 7 Remove files older than 7 days\n * mc cleanup --dry-run Preview what would be deleted\n */\nexport async function cleanup(options: CleanupOptions): Promise<CleanupResult> {\n // Check initialization\n if (!isInitialized()) {\n throw new Error('Mindcontext not initialized. Run \"mc init\" first.');\n }\n\n const config = readConfig();\n if (!config) {\n throw new Error('Failed to read config file.');\n }\n\n const olderThanDays = options.olderThan ?? DEFAULT_OLDER_THAN_DAYS;\n const cutoffTime = Date.now() - olderThanDays * 24 * 60 * 60 * 1000;\n const repoDir = getRepoDir();\n\n let deleted = 0;\n let wouldDelete = 0;\n\n // Process each registered project\n for (const projectName of Object.keys(config.projects)) {\n const updatesDir = join(repoDir, 'projects', projectName, 'updates');\n\n if (!existsSync(updatesDir)) {\n continue;\n }\n\n const files = readdirSync(updatesDir);\n\n for (const file of files) {\n if (!file.endsWith('.json')) {\n continue;\n }\n\n const filePath = join(updatesDir, file);\n const stats = statSync(filePath);\n const fileAge = stats.mtime.getTime();\n\n if (fileAge < cutoffTime) {\n if (options.dryRun) {\n wouldDelete++;\n if (!options.quiet) {\n console.log(`Would delete: ${projectName}/${file}`);\n }\n } else {\n unlinkSync(filePath);\n deleted++;\n if (!options.quiet) {\n console.log(`Deleted: ${projectName}/${file}`);\n }\n }\n }\n }\n }\n\n if (!options.quiet) {\n if (options.dryRun) {\n console.log(`\\n${wouldDelete} file(s) would be deleted.`);\n } else {\n console.log(`\\n✓ Cleaned up ${deleted} file(s).`);\n }\n }\n\n return { deleted, wouldDelete };\n}\n","import { existsSync, rmSync } from 'fs';\nimport { getMindcontextDir } from '../lib/config.js';\n\nexport interface ResetOptions {\n force?: boolean;\n dryRun?: boolean;\n quiet?: boolean;\n}\n\nexport interface ResetResult {\n success: boolean;\n removed: boolean;\n wouldRemove?: boolean;\n}\n\n/**\n * Reset command - remove ~/.mindcontext/ and start fresh.\n *\n * Usage:\n * mc reset Show what would be removed\n * mc reset --force Actually remove everything\n * mc reset --dry-run Preview removal without deleting\n */\nexport async function reset(options: ResetOptions): Promise<ResetResult> {\n const mindcontextDir = getMindcontextDir();\n\n // Check if there's anything to remove\n if (!existsSync(mindcontextDir)) {\n if (!options.quiet) {\n console.log('Nothing to remove. Mindcontext directory does not exist.');\n }\n return { success: true, removed: false };\n }\n\n // Dry-run mode\n if (options.dryRun) {\n if (!options.quiet) {\n console.log(`Would remove: ${mindcontextDir}`);\n console.log('\\nThis will delete:');\n console.log(' - config.json (global configuration)');\n console.log(' - repo/ (dashboard repository clone)');\n console.log(' - All cached data and pending pushes');\n console.log('\\nRun with --force to actually remove.');\n }\n return { success: true, removed: false, wouldRemove: true };\n }\n\n // Require --force flag\n if (!options.force) {\n if (!options.quiet) {\n console.log('Reset requires --force flag to confirm.');\n console.log(`\\nThis will remove: ${mindcontextDir}`);\n console.log('\\nRun: mc reset --force');\n console.log('Or preview with: mc reset --dry-run');\n }\n return { success: false, removed: false };\n }\n\n // Actually remove\n try {\n rmSync(mindcontextDir, { recursive: true, force: true });\n if (!options.quiet) {\n console.log(`✓ Removed ${mindcontextDir}`);\n console.log('\\nRun \"mc init\" to set up mindcontext again.');\n }\n return { success: true, removed: true };\n } catch (error) {\n if (!options.quiet) {\n console.error(`Failed to remove: ${error instanceof Error ? error.message : error}`);\n }\n return { success: false, removed: false };\n }\n}\n","import { existsSync, readdirSync, readFileSync, writeFileSync, statSync } from 'fs';\nimport { join, relative } from 'path';\nimport {\n isInitialized,\n readConfig,\n ensureProjectDir,\n getProjectDir,\n} from '../lib/config.js';\nimport { generateUpdateFilename } from '../lib/machine-id.js';\n\nexport interface MigrationSources {\n hasProjectDir: boolean;\n hasFocusJson: boolean;\n projectFiles: string[];\n focusJsonPath?: string;\n}\n\nexport interface MigrateOptions {\n projectPath: string;\n dryRun?: boolean;\n quiet?: boolean;\n skipProjectDir?: boolean;\n skipFocusJson?: boolean;\n autoConfirm?: boolean;\n}\n\nexport interface MigrateResult {\n sources: MigrationSources;\n migrated: boolean;\n focusMigrated: boolean;\n projectDirMigrated: boolean;\n}\n\n/**\n * Recursively list all files in a directory.\n */\nfunction listFilesRecursively(dir: string, baseDir: string = dir): string[] {\n const files: string[] = [];\n\n if (!existsSync(dir)) {\n return files;\n }\n\n const entries = readdirSync(dir);\n for (const entry of entries) {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n\n if (stat.isDirectory()) {\n files.push(...listFilesRecursively(fullPath, baseDir));\n } else {\n files.push(relative(baseDir, fullPath));\n }\n }\n\n return files;\n}\n\n/**\n * Detect migration sources in a project directory.\n */\nexport function detectMigrationSources(projectPath: string): MigrationSources {\n const projectDir = join(projectPath, '.project');\n const focusJsonPath = join(projectPath, '.claude', 'focus.json');\n\n const hasProjectDir = existsSync(projectDir);\n const hasFocusJson = existsSync(focusJsonPath);\n\n const projectFiles = hasProjectDir ? listFilesRecursively(projectDir) : [];\n\n return {\n hasProjectDir,\n hasFocusJson,\n projectFiles,\n focusJsonPath: hasFocusJson ? focusJsonPath : undefined,\n };\n}\n\n/**\n * Convert focus.json to update file format.\n */\nexport function convertFocusToUpdate(\n focusJson: Record<string, unknown>,\n projectName: string,\n machine: { name: string; id: string }\n): Record<string, unknown> {\n const timestamp = (focusJson.timestamp as string) || new Date().toISOString();\n\n return {\n version: '1.0',\n timestamp,\n machine: machine.name,\n machine_id: machine.id,\n project: projectName,\n progress: {\n source: 'migration',\n change: 'migrated-from-focus',\n tasks_done: 0,\n tasks_total: 0,\n },\n context: {\n current_task: (focusJson.current_focus as string) || '',\n status: 'migrated',\n notes: focusJson.session_summary ? [focusJson.session_summary as string] : [],\n next: (focusJson.next_session_tasks as string[]) || [],\n },\n };\n}\n\n/**\n * Migrate command - convert .project/ and focus.json to mindcontext format.\n *\n * Usage:\n * mc migrate Interactive migration\n * mc migrate --dry-run Preview what would be migrated\n * mc migrate --auto-confirm Non-interactive (use defaults)\n */\nexport async function migrate(options: MigrateOptions): Promise<MigrateResult> {\n // Check initialization\n if (!isInitialized()) {\n throw new Error('Mindcontext not initialized. Run \"mc init\" first.');\n }\n\n const config = readConfig();\n if (!config) {\n throw new Error('Failed to read config file.');\n }\n\n // Detect sources\n const sources = detectMigrationSources(options.projectPath);\n\n // Nothing to migrate\n if (!sources.hasProjectDir && !sources.hasFocusJson) {\n if (!options.quiet) {\n console.log('Nothing to migrate.');\n console.log(' - No .project/ directory found');\n console.log(' - No .claude/focus.json found');\n }\n return {\n sources,\n migrated: false,\n focusMigrated: false,\n projectDirMigrated: false,\n };\n }\n\n // Report what was found\n if (!options.quiet) {\n console.log('Migration sources detected:\\n');\n\n if (sources.hasProjectDir) {\n console.log(' .project/ directory:');\n for (const file of sources.projectFiles) {\n console.log(` - ${file}`);\n }\n }\n\n if (sources.hasFocusJson) {\n console.log(' .claude/focus.json: Found');\n }\n\n console.log('');\n }\n\n // Dry-run mode\n if (options.dryRun) {\n if (!options.quiet) {\n console.log('Dry-run mode - no changes made.');\n\n if (sources.hasFocusJson) {\n console.log('\\nWould migrate focus.json to update file.');\n }\n\n if (sources.hasProjectDir) {\n console.log('\\nWould prompt for .project/ file destinations.');\n }\n }\n return {\n sources,\n migrated: false,\n focusMigrated: false,\n projectDirMigrated: false,\n };\n }\n\n let focusMigrated = false;\n let projectDirMigrated = false;\n\n // Migrate focus.json\n if (sources.hasFocusJson && !options.skipFocusJson) {\n if (!options.quiet) {\n console.log('Migrating focus.json...');\n }\n\n try {\n // Find project name from path\n const projectName = Object.keys(config.projects).find(\n (name) => config.projects[name].path === options.projectPath\n ) || 'unknown-project';\n\n // Read focus.json\n const focusContent = readFileSync(sources.focusJsonPath!, 'utf8');\n const focusJson = JSON.parse(focusContent);\n\n // Convert to update format\n const update = convertFocusToUpdate(focusJson, projectName, config.machine);\n\n // Ensure project directory exists\n ensureProjectDir(projectName);\n\n // Write update file\n const filename = generateUpdateFilename();\n const updatesDir = getProjectDir(projectName);\n const updatePath = join(updatesDir, filename);\n\n writeFileSync(updatePath, JSON.stringify(update, null, 2));\n\n if (!options.quiet) {\n console.log(` ✓ Created update file: ${filename}`);\n }\n\n focusMigrated = true;\n } catch (error) {\n if (!options.quiet) {\n console.error(` ✗ Failed to migrate focus.json: ${error instanceof Error ? error.message : error}`);\n }\n }\n }\n\n // Note: .project/ migration requires interactive prompts\n // For now, we only support focus.json migration in non-interactive mode\n if (sources.hasProjectDir && !options.skipProjectDir) {\n if (options.autoConfirm) {\n if (!options.quiet) {\n console.log('\\n.project/ migration requires interactive mode.');\n console.log('Run without --auto-confirm to migrate .project/ files.');\n }\n } else if (!options.quiet) {\n console.log('\\n.project/ migration: Interactive prompts not yet implemented.');\n console.log('Files remain in .project/ - manual migration recommended.');\n }\n }\n\n const migrated = focusMigrated || projectDirMigrated;\n\n if (!options.quiet && migrated) {\n console.log('\\n✓ Migration complete.');\n }\n\n return {\n sources,\n migrated,\n focusMigrated,\n projectDirMigrated,\n };\n}\n","import { init } from './commands/init.js';\nimport { connect } from './commands/connect.js';\nimport { sync } from './commands/sync.js';\nimport { pull } from './commands/pull.js';\nimport { context } from './commands/context.js';\nimport { progress } from './commands/progress.js';\nimport { config } from './commands/config.js';\nimport { cleanup } from './commands/cleanup.js';\nimport { reset } from './commands/reset.js';\nimport { migrate } from './commands/migrate.js';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\n// Parse flags\nconst flags: Record<string, boolean | string> = {};\nconst positional: string[] = [];\n\nfor (let i = 1; i < args.length; i++) {\n const arg = args[i];\n if (arg.startsWith('--')) {\n const eqIndex = arg.indexOf('=');\n if (eqIndex > -1) {\n // --key=value format\n const key = arg.slice(2, eqIndex);\n const value = arg.slice(eqIndex + 1);\n flags[key] = value;\n } else {\n // --key value or --flag format\n const key = arg.slice(2);\n const nextArg = args[i + 1];\n if (nextArg && !nextArg.startsWith('-')) {\n flags[key] = nextArg;\n i++; // Skip next arg since we consumed it\n } else {\n flags[key] = true;\n }\n }\n } else if (arg.startsWith('-')) {\n flags[arg.slice(1)] = true;\n } else {\n positional.push(arg);\n }\n}\n\nasync function main() {\n try {\n switch (command) {\n case 'init':\n await init({ quiet: !!flags.quiet || !!flags.q });\n break;\n\n case 'connect':\n await connect({\n category: flags.category as string | undefined,\n name: positional[0],\n quiet: !!flags.quiet || !!flags.q,\n withHooks: !!flags['with-hooks'],\n });\n break;\n\n case 'sync':\n await sync({\n quiet: !!flags.quiet || !!flags.q,\n dryRun: !!flags['dry-run'],\n notes: flags.notes ? String(flags.notes).split('\\n').filter(Boolean) : undefined,\n next: flags.next ? String(flags.next).split('\\n').filter(Boolean) : undefined,\n });\n break;\n\n case 'pull':\n await pull({ quiet: !!flags.quiet || !!flags.q });\n break;\n\n case 'context':\n await context({\n json: !!flags.json,\n quiet: !!flags.quiet || !!flags.q,\n });\n break;\n\n case 'progress':\n await progress({\n web: !!flags.web,\n quiet: !!flags.quiet || !!flags.q,\n });\n break;\n\n case 'config':\n await config({\n show: !flags['dashboard-repo'] && !flags['dashboard-url'] && !flags.get,\n get: flags.get as string | undefined,\n dashboardRepo: flags['dashboard-repo'] as string | undefined,\n dashboardUrl: flags['dashboard-url'] as string | undefined,\n quiet: !!flags.quiet || !!flags.q,\n });\n break;\n\n case 'cleanup':\n await cleanup({\n olderThan: flags['older-than'] ? parseInt(flags['older-than'] as string, 10) : undefined,\n dryRun: !!flags['dry-run'],\n quiet: !!flags.quiet || !!flags.q,\n });\n break;\n\n case 'reset':\n await reset({\n force: !!flags.force,\n dryRun: !!flags['dry-run'],\n quiet: !!flags.quiet || !!flags.q,\n });\n break;\n\n case 'migrate':\n await migrate({\n projectPath: process.cwd(),\n dryRun: !!flags['dry-run'],\n quiet: !!flags.quiet || !!flags.q,\n skipProjectDir: !!flags['skip-project'],\n skipFocusJson: !!flags['skip-focus'],\n autoConfirm: !!flags.yes || !!flags.y,\n });\n break;\n\n case 'help':\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n break;\n\n case 'version':\n case '--version':\n case '-v':\n console.log('mindcontext v0.1.0');\n break;\n\n default:\n console.error(`Unknown command: ${command}`);\n console.error('Run \"mc help\" for available commands.');\n process.exit(1);\n }\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n\nfunction printHelp() {\n console.log(`\nmindcontext - Git-based project progress tracker\n\nUSAGE:\n mc <command> [options]\n\nCOMMANDS:\n init Initialize mindcontext (~/.mindcontext/)\n connect Connect current project to mindcontext\n sync Create progress update and push\n pull Pull latest updates from remote\n context Output current context (for integration)\n progress Show progress (or --web to open dashboard)\n config View or update configuration\n cleanup Remove old update files\n reset Remove ~/.mindcontext/ and start fresh\n migrate Migrate from .project/ and focus.json\n help Show this help message\n\nOPTIONS:\n --quiet, -q Suppress output\n --json Output as JSON (context command)\n --web Open web dashboard (progress command)\n --category Set project category (connect command)\n --with-hooks Generate session-end hook (connect command)\n --dry-run Show what would be done (sync command)\n --dashboard-repo Set dashboard git repository (config command)\n --dashboard-url Set dashboard web URL (config command)\n --get <key> Get specific config value (config command)\n --older-than <d> Days threshold for cleanup (default: 30)\n --force Confirm destructive action (reset command)\n --yes, -y Auto-confirm prompts (migrate command)\n --skip-project Skip .project/ migration\n --skip-focus Skip focus.json migration\n\nEXAMPLES:\n # First-time setup\n mc init\n\n # Connect a project\n cd my-project\n mc connect --category work\n\n # Daily usage\n mc sync # Push progress update\n mc progress # View progress in terminal\n mc progress --web # Open dashboard in browser\n mc pull # Get team updates\n\nDOCUMENTATION:\n https://github.com/tmsjngx0/mindcontext\n`);\n}\n\nmain();\n"],"mappings":"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","names":["existsSync","mkdirSync","config","execSync","existsSync","execSync","existsSync","pushResult","execSync","resolve","config","existsSync","mkdirSync","basename","join","existsSync","mkdirSync","writeFileSync","existsSync","readFileSync","join","config","basename","join","existsSync","mkdirSync","writeFileSync","basename","resolve","existsSync","readdirSync","readFileSync","writeFileSync","join","progress","context","join","writeFileSync","existsSync","readdirSync","readFileSync","sync","config","resolve","basename","progress","context","pull","basename","resolve","resolve","basename","config","progress","execSync","basename","resolve","config","execSync","resolve","basename","openspecProgress","percentage","readdirSync","existsSync","join","config","join","existsSync","readdirSync","existsSync","existsSync","existsSync","readdirSync","readFileSync","writeFileSync","statSync","join","existsSync","readdirSync","join","statSync","config","readFileSync","writeFileSync","sync","pull"]}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Initialize mindcontext.
3
+ */
4
+ declare function init(options?: {
5
+ quiet?: boolean;
6
+ }): Promise<void>;
7
+
8
+ interface ConnectOptions {
9
+ category?: string;
10
+ name?: string;
11
+ quiet?: boolean;
12
+ withHooks?: boolean;
13
+ }
14
+ /**
15
+ * Connect current project to mindcontext.
16
+ */
17
+ declare function connect(options?: ConnectOptions): Promise<void>;
18
+
19
+ /**
20
+ * Generate a unique machine identifier based on hostname, username, and git email.
21
+ * Used to create unique filenames for update files.
22
+ */
23
+ declare function getMachineId(): {
24
+ name: string;
25
+ id: string;
26
+ };
27
+ /**
28
+ * Generate a timestamp string safe for filenames.
29
+ * Format: YYYY-MM-DDTHH-MM-SS (uses dashes instead of colons)
30
+ */
31
+ declare function getTimestamp(): string;
32
+ /**
33
+ * Generate a unique update filename.
34
+ * Format: {timestamp}_{machine-name}_{machine-id}.json
35
+ */
36
+ declare function generateUpdateFilename(): string;
37
+
38
+ interface ProgressData {
39
+ source: 'openspec' | 'manual';
40
+ change?: string;
41
+ tasks_done: number;
42
+ tasks_total: number;
43
+ }
44
+ interface ContextData {
45
+ current_task?: string;
46
+ status: 'idle' | 'in_progress' | 'blocked' | 'review';
47
+ notes: string[];
48
+ next: string[];
49
+ }
50
+ interface UpdateFile {
51
+ version: string;
52
+ timestamp: string;
53
+ machine: string;
54
+ machine_id: string;
55
+ project: string;
56
+ progress: ProgressData;
57
+ context: ContextData;
58
+ recent_commits?: string[];
59
+ }
60
+ /**
61
+ * Create an update file with progress and context data.
62
+ */
63
+ declare function createUpdateFile(projectName: string, progress: ProgressData, context: ContextData, recentCommits?: string[]): string;
64
+ /**
65
+ * Read all update files for a project.
66
+ */
67
+ declare function readUpdateFiles(projectName: string): UpdateFile[];
68
+ /**
69
+ * Get the latest update for a project.
70
+ */
71
+ declare function getLatestUpdate(projectName: string): UpdateFile | null;
72
+ /**
73
+ * Get the latest update for each machine for a project.
74
+ */
75
+ declare function getLatestByMachine(projectName: string): Map<string, UpdateFile>;
76
+
77
+ interface SyncOptions {
78
+ quiet?: boolean;
79
+ dryRun?: boolean;
80
+ notes?: string[];
81
+ next?: string[];
82
+ status?: ContextData['status'];
83
+ }
84
+ /**
85
+ * Sync progress for current project.
86
+ */
87
+ declare function sync(options?: SyncOptions): Promise<void>;
88
+
89
+ interface PullOptions {
90
+ quiet?: boolean;
91
+ }
92
+ /**
93
+ * Pull latest updates from remote.
94
+ */
95
+ declare function pull(options?: PullOptions): Promise<void>;
96
+
97
+ interface ContextOptions {
98
+ json?: boolean;
99
+ quiet?: boolean;
100
+ }
101
+ /**
102
+ * Output current context for mindcontext-core integration.
103
+ */
104
+ declare function context(options?: ContextOptions): Promise<void>;
105
+
106
+ interface ProgressOptions {
107
+ web?: boolean;
108
+ quiet?: boolean;
109
+ }
110
+ /**
111
+ * Display progress or open dashboard.
112
+ */
113
+ declare function progress(options?: ProgressOptions): Promise<void>;
114
+
115
+ interface ProjectConfig {
116
+ path: string;
117
+ openspec: boolean;
118
+ category: string;
119
+ }
120
+ interface Config {
121
+ version: string;
122
+ dashboard_repo: string;
123
+ dashboard_url: string;
124
+ projects: Record<string, ProjectConfig>;
125
+ machine: {
126
+ name: string;
127
+ id: string;
128
+ };
129
+ }
130
+ /**
131
+ * Get the mindcontext directory path.
132
+ */
133
+ declare function getMindcontextDir(): string;
134
+ /**
135
+ * Get the repo directory path.
136
+ */
137
+ declare function getRepoDir(): string;
138
+ /**
139
+ * Check if mindcontext is initialized.
140
+ */
141
+ declare function isInitialized(): boolean;
142
+ /**
143
+ * Read the config file.
144
+ */
145
+ declare function readConfig(): Config | null;
146
+ /**
147
+ * Write the config file.
148
+ */
149
+ declare function writeConfig(config: Config): void;
150
+
151
+ interface OpenSpecChange {
152
+ id: string;
153
+ tasksTotal: number;
154
+ tasksComplete: number;
155
+ status: 'proposed' | 'in_progress' | 'review' | 'done';
156
+ }
157
+ interface OpenSpecResult {
158
+ found: boolean;
159
+ changes: OpenSpecChange[];
160
+ activeChange: OpenSpecChange | null;
161
+ }
162
+ /**
163
+ * Check if a directory has OpenSpec structure.
164
+ */
165
+ declare function hasOpenSpec(projectPath: string): boolean;
166
+ /**
167
+ * Parse all OpenSpec changes in a project.
168
+ */
169
+ declare function parseOpenSpec(projectPath: string): OpenSpecResult;
170
+ /**
171
+ * Get progress data from OpenSpec.
172
+ */
173
+ declare function getOpenSpecProgress(projectPath: string): {
174
+ source: 'openspec' | 'manual';
175
+ change?: string;
176
+ tasks_done: number;
177
+ tasks_total: number;
178
+ };
179
+
180
+ export { type Config, type ContextData, type OpenSpecChange, type OpenSpecResult, type ProgressData, type ProjectConfig, type UpdateFile, connect, context, createUpdateFile, generateUpdateFilename, getLatestByMachine, getLatestUpdate, getMachineId, getMindcontextDir, getOpenSpecProgress, getRepoDir, getTimestamp, hasOpenSpec, init, isInitialized, parseOpenSpec, progress, pull, readConfig, readUpdateFiles, sync, writeConfig };