@vanshbhardwaj/worklog 1.0.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.
Files changed (68) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  3. package/.github/PULL_REQUEST_TEMPLATE.md +19 -0
  4. package/.github/workflows/release.yml +63 -0
  5. package/.github/workflows/validate.yml +103 -0
  6. package/.prettierrc +8 -0
  7. package/ARCHITECTURE.md +82 -0
  8. package/CODE_OF_CONDUCT.md +65 -0
  9. package/CONTRIBUTING.md +74 -0
  10. package/INSTALLATION.md +98 -0
  11. package/LICENSE +21 -0
  12. package/README.md +246 -0
  13. package/SECURITY.md +18 -0
  14. package/benchmarks/benchmark.ts +149 -0
  15. package/benchmarks/vitest.bench.config.ts +9 -0
  16. package/dist/database/migrations/001_initial.sql +60 -0
  17. package/dist/database/migrations/002_relational_tables.sql +22 -0
  18. package/dist/index.cjs +31007 -0
  19. package/dist/index.cjs.map +1 -0
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.js +1873 -0
  22. package/dist/index.js.map +1 -0
  23. package/eslint.config.js +38 -0
  24. package/package.json +49 -0
  25. package/pnpm-workspace.yaml +6 -0
  26. package/scripts/build-bin.js +75 -0
  27. package/sea-config.json +5 -0
  28. package/src/cli/commands/add.ts +176 -0
  29. package/src/cli/commands/continue.ts +80 -0
  30. package/src/cli/commands/dashboard.ts +30 -0
  31. package/src/cli/commands/export.ts +72 -0
  32. package/src/cli/commands/init.ts +52 -0
  33. package/src/cli/commands/list.ts +33 -0
  34. package/src/cli/commands/search.ts +33 -0
  35. package/src/cli/commands/show.ts +42 -0
  36. package/src/cli/commands/stats.ts +23 -0
  37. package/src/cli/commands/today.ts +27 -0
  38. package/src/cli/commands/week.ts +93 -0
  39. package/src/cli/index.ts +294 -0
  40. package/src/cli/ui.ts +323 -0
  41. package/src/core/config.ts +69 -0
  42. package/src/core/discovery.ts +38 -0
  43. package/src/core/logger.ts +53 -0
  44. package/src/database/connection.ts +95 -0
  45. package/src/database/migration-data.ts +71 -0
  46. package/src/database/migrations/001_initial.sql +60 -0
  47. package/src/database/migrations/002_relational_tables.sql +22 -0
  48. package/src/database/migrations.ts +65 -0
  49. package/src/errors/index.ts +51 -0
  50. package/src/exporters/csv.ts +59 -0
  51. package/src/exporters/json.ts +8 -0
  52. package/src/exporters/markdown.ts +71 -0
  53. package/src/models/work-unit.ts +38 -0
  54. package/src/repositories/work-unit.ts +466 -0
  55. package/src/services/work-unit.ts +131 -0
  56. package/src/tests/cli/__snapshots__/cli-productivity.test.ts.snap +37 -0
  57. package/src/tests/cli/__snapshots__/cli.test.ts.snap +20 -0
  58. package/src/tests/cli/cli-productivity.test.ts +167 -0
  59. package/src/tests/cli/cli.test.ts +171 -0
  60. package/src/tests/core/config.test.ts +53 -0
  61. package/src/tests/core/discovery.test.ts +46 -0
  62. package/src/tests/database/migrations.test.ts +75 -0
  63. package/src/tests/repositories/work-unit.test.ts +243 -0
  64. package/src/tests/services/work-unit.test.ts +87 -0
  65. package/src/validators/work-unit.ts +63 -0
  66. package/tsconfig.json +16 -0
  67. package/tsup.config.ts +50 -0
  68. package/vitest.config.ts +8 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../node_modules/.pnpm/tsup@8.3.5_postcss@8.5.23_supports-color@7.2.0_typescript@5.7.2/node_modules/tsup/assets/esm_shims.js","../src/cli/index.ts","../src/core/discovery.ts","../src/errors/index.ts","../src/core/logger.ts","../src/database/connection.ts","../src/database/migration-data.ts","../src/database/migrations.ts","../src/repositories/work-unit.ts","../src/validators/work-unit.ts","../src/services/work-unit.ts","../src/cli/commands/init.ts","../src/core/config.ts","../src/cli/commands/add.ts","../src/cli/ui.ts","../src/cli/commands/list.ts","../src/cli/commands/show.ts","../src/cli/commands/search.ts","../src/cli/commands/today.ts","../src/cli/commands/week.ts","../src/cli/commands/dashboard.ts","../src/cli/commands/continue.ts","../src/cli/commands/stats.ts","../src/cli/commands/export.ts","../src/exporters/markdown.ts","../src/exporters/csv.ts","../src/exporters/json.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport { fileURLToPath } from 'url'\nimport path from 'path'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport pc from 'picocolors';\nimport { getWorkspaceRoot } from '../core/discovery.js';\nimport { initLogger, logger } from '../core/logger.js';\nimport { connectDatabase, closeDatabase } from '../database/connection.js';\nimport { runMigrations } from '../database/migrations.js';\nimport { WorkUnitRepository } from '../repositories/work-unit.js';\nimport { WorkUnitService } from '../services/work-unit.js';\nimport { initCommand } from './commands/init.js';\nimport { addCommand } from './commands/add.js';\nimport { listCommand } from './commands/list.js';\nimport { showCommand } from './commands/show.js';\nimport { searchCommand } from './commands/search.js';\nimport { todayCommand } from './commands/today.js';\nimport { weekCommand } from './commands/week.js';\nimport { dashboardCommand } from './commands/dashboard.js';\nimport { continueCommand } from './commands/continue.js';\nimport { statsCommand } from './commands/stats.js';\nimport { exportCommand } from './commands/export.js';\nimport { WorkLogDomainError } from '../errors/index.js';\n\nconst program = new Command();\n\nprogram\n .name('worklog')\n .description('WorkLog - Engineering Context Manager')\n .version('0.1.0')\n .option('--verbose', 'enable verbose debug logging')\n .option('--json', 'output in machine-readable JSON format');\n\n// Helper to bootstrap database & service\nfunction bootstrap(): WorkUnitService {\n const root = getWorkspaceRoot();\n initLogger(root);\n const db = connectDatabase(root);\n runMigrations(db);\n const repo = new WorkUnitRepository(db);\n return new WorkUnitService(repo);\n}\n\n// Global error handler\nfunction handleError(error: any) {\n const isVerbose = program.opts().verbose;\n const isJson = program.opts().json;\n\n // Database errors represent unexpected system errors rather than user input issues, so they exit with 2\n const isUserError = error instanceof WorkLogDomainError && error.code !== 'DATABASE_ERROR';\n\n if (isUserError) {\n logger.error({ error, code: error.code }, 'Domain error occurred');\n if (isJson) {\n console.error(JSON.stringify({ success: false, code: error.code, error: error.message }));\n } else {\n console.error(pc.red(`Error: ${error.message}`));\n if (error.actionRequired) {\n console.error(pc.yellow(`Action required: ${error.actionRequired}`));\n }\n }\n process.exit(1);\n } else {\n logger.error({ error }, 'Unexpected system error');\n if (isJson) {\n console.error(\n JSON.stringify({ success: false, code: 'INTERNAL_ERROR', error: error.message }),\n );\n } else {\n console.error(pc.red(`Unexpected Error: ${error.message}`));\n if (isVerbose) {\n console.error(pc.gray(error.stack || ''));\n } else {\n console.error(pc.yellow('Run with --verbose to view stack traces.'));\n }\n }\n process.exit(2);\n }\n}\n\n// Commands definition\nprogram\n .command('init')\n .alias('i')\n .description('Initialize a new WorkLog repository')\n .option('--name <name>', 'override default project name')\n .action((options) => {\n try {\n const json = program.opts().json || options.json;\n initCommand({ ...options, json });\n } catch (error: any) {\n handleError(error);\n }\n });\n\nprogram\n .command('add')\n .alias('a')\n .description('Create a new Work Unit')\n .option('-t, --title <title>', 'title of the work unit')\n .option(\n '--type <type>',\n 'type of the work unit (Feature, Bug, Spike, Refactor, Improvement, Research, Decision, Blocker, Review, Idea)',\n )\n .option(\n '--status <status>',\n 'status of the work unit (Planned, In Progress, Blocked, Completed, Cancelled)',\n )\n .option('--priority <priority>', 'priority of the work unit (Low, Medium, High)')\n .option('--module <module>', 'associated component or code module')\n .option('--tags <tags>', 'comma-separated tags list')\n .option('-d, --description <desc>', 'detailed description')\n .option('-n, --next <next>', 'next step/action')\n .option('--notes <notes>', 'implementation notes')\n .action(async (options) => {\n try {\n const service = bootstrap();\n const json = program.opts().json || options.json;\n await addCommand(service, { ...options, json });\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\nprogram\n .command('list')\n .alias('ls')\n .description('List recent Work Units')\n .option('-l, --limit <limit>', 'limit output count', '20')\n .option('-s, --status <status>', 'filter by status')\n .option('-t, --type <type>', 'filter by type')\n .action((options) => {\n try {\n const service = bootstrap();\n const json = program.opts().json || options.json;\n listCommand(service, { ...options, json });\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\nprogram\n .command('show <id>')\n .alias('sh')\n .description('Show details for a specific Work Unit')\n .action((id, options) => {\n try {\n const service = bootstrap();\n const json = program.opts().json || options.json;\n showCommand(service, id, { ...options, json });\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\nprogram\n .command('search [query]')\n .alias('s')\n .description('Search Work Units by keyword and category filters')\n .option('--tag <tag>', 'filter search results by tag')\n .option('--module <module>', 'filter search results by module')\n .option('--status <status>', 'filter search results by status')\n .option('--type <type>', 'filter search results by type')\n .action((query, options) => {\n try {\n const service = bootstrap();\n const json = program.opts().json || options.json;\n searchCommand(service, query, { ...options, json });\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\nprogram\n .command('today')\n .alias('t')\n .description('Show work units updated today')\n .action((options) => {\n try {\n const service = bootstrap();\n const json = program.opts().json || options.json;\n todayCommand(service, { ...options, json });\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\nprogram\n .command('week')\n .alias('w')\n .description('Show weekly engineering summary')\n .action((options) => {\n try {\n const service = bootstrap();\n const json = program.opts().json || options.json;\n weekCommand(service, { ...options, json });\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\nprogram\n .command('dashboard')\n .alias('db')\n .description('Show clean project dashboard overview')\n .action((options) => {\n try {\n const service = bootstrap();\n const json = program.opts().json || options.json;\n dashboardCommand(service, { ...options, json });\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\nprogram\n .command('continue')\n .alias('co')\n .description('Resume work on the most recent unfinished task')\n .action(async (options) => {\n try {\n const service = bootstrap();\n const json = program.opts().json || options.json;\n await continueCommand(service, { ...options, json });\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\nprogram\n .command('stats')\n .alias('st')\n .description('Show total stats and category distributions')\n .action((options) => {\n try {\n const service = bootstrap();\n const json = program.opts().json || options.json;\n statsCommand(service, { ...options, json });\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\nprogram\n .command('export')\n .alias('ex')\n .description('Export Work Units to Markdown, CSV, or JSON')\n .option('-f, --format <format>', 'export format (markdown, csv, json)', 'markdown')\n .option('-o, --output <file>', 'write output directly to a file')\n .option('--id <id>', 'export a single work unit by its ID')\n .action((options) => {\n try {\n const service = bootstrap();\n exportCommand(service, options);\n } catch (error: any) {\n handleError(error);\n } finally {\n closeDatabase();\n }\n });\n\n// Handle invalid / unknown command routing\nprogram.on('command:*', () => {\n const isJson = program.opts().json;\n const command = program.args.join(' ');\n\n if (isJson) {\n console.error(\n JSON.stringify({ success: false, code: 'UNKNOWN_COMMAND', error: `Unknown command: ${command}` }),\n );\n } else {\n console.error(pc.red(`Error: Unknown command: ${command}`));\n console.error(`Run 'worklog --help' for a list of available commands.`);\n }\n process.exit(1);\n});\n\nprogram.parse(process.argv);\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { NotInitializedError } from '../errors/index.js';\n\n/**\n * Searches upward from the starting directory to find the `.worklog` directory.\n * Returns the absolute path of the directory containing `.worklog`.\n * Returns null if not found.\n */\nexport function findWorkspaceRoot(startDir: string = process.cwd()): string | null {\n let current = path.resolve(startDir);\n const rootPath = path.parse(current).root;\n\n while (true) {\n const candidate = path.join(current, '.worklog');\n if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {\n return current;\n }\n\n if (current === rootPath) {\n break;\n }\n current = path.dirname(current);\n }\n\n return null;\n}\n\n/**\n * Finds the workspace root or throws a NotInitializedError.\n */\nexport function getWorkspaceRoot(startDir: string = process.cwd()): string {\n const root = findWorkspaceRoot(startDir);\n if (!root) {\n throw new NotInitializedError();\n }\n return root;\n}\n","export class WorkLogDomainError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly actionRequired?: string,\n ) {\n super(message);\n this.name = this.constructor.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class NotInitializedError extends WorkLogDomainError {\n constructor() {\n super(\n 'Not a WorkLog repository (or any of the parent directories): .worklog',\n 'NOT_INITIALIZED',\n \"Run 'worklog init' or 'worklog a' to initialize a new repository.\",\n );\n }\n}\n\nexport class DatabaseError extends WorkLogDomainError {\n constructor(message: string, details?: string) {\n super(\n `Database error: ${message}${details ? ` (${details})` : ''}`,\n 'DATABASE_ERROR',\n 'Please check your database integrity or log files.',\n );\n }\n}\n\nexport class ValidationError extends WorkLogDomainError {\n constructor(message: string) {\n super(\n `Validation error: ${message}`,\n 'VALIDATION_ERROR',\n 'Please provide valid inputs conforming to the schema.',\n );\n }\n}\n\nexport class ConfigError extends WorkLogDomainError {\n constructor(message: string) {\n super(\n `Configuration error: ${message}`,\n 'CONFIG_ERROR',\n 'Please check if .worklog/config.json is well-formed.',\n );\n }\n}\n","import pino from 'pino';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nlet loggerInstance: pino.Logger | null = null;\n\n/**\n * Returns the current logger instance or a silent fallback if not initialized.\n */\nexport function getLogger(): pino.Logger {\n if (loggerInstance) {\n return loggerInstance;\n }\n\n // Silent fallback before repository discovery\n loggerInstance = pino({\n level: 'silent',\n });\n return loggerInstance;\n}\n\n/**\n * Initializes the logger to write to the `.worklog/worklog.log` file in the workspace.\n */\nexport function initLogger(workspaceRoot: string): pino.Logger {\n const logDir = path.join(workspaceRoot, '.worklog');\n if (!fs.existsSync(logDir)) {\n fs.mkdirSync(logDir, { recursive: true });\n }\n\n const logFile = path.join(logDir, 'worklog.log');\n\n loggerInstance = pino(\n {\n level: process.env.WORKLOG_LOG_LEVEL || 'info',\n base: undefined, // remove pid/hostname for clean local logs\n timestamp: () => `,\"time\":\"${new Date().toISOString()}\"`,\n },\n pino.destination({\n dest: logFile,\n sync: true, // synchronous write to guarantee flush before CLI exit\n }),\n );\n\n return loggerInstance;\n}\n\nexport const logger = {\n info: (obj: any, msg?: string, ...args: any[]) => getLogger().info(obj, msg, ...args),\n error: (obj: any, msg?: string, ...args: any[]) => getLogger().error(obj, msg, ...args),\n debug: (obj: any, msg?: string, ...args: any[]) => getLogger().debug(obj, msg, ...args),\n warn: (obj: any, msg?: string, ...args: any[]) => getLogger().warn(obj, msg, ...args),\n};\n","import { createRequire } from 'module';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { DatabaseError } from '../errors/index.js';\nimport { logger } from '../core/logger.js';\nimport type DatabaseType from 'better-sqlite3';\n\n// Construct dynamic disk require to bypass Node SEA embedded require constraints\nlet DatabaseConstructor: any;\ntry {\n const contextPath =\n typeof import.meta !== 'undefined' && import.meta.url\n ? import.meta.url\n : typeof __filename !== 'undefined'\n ? __filename\n : process.cwd() + '/package.json';\n\n const requireFromDisk = createRequire(contextPath);\n DatabaseConstructor = requireFromDisk('better-sqlite3');\n} catch {\n try {\n // Fallback: resolve from the current working directory\n const requireFromDisk = createRequire(process.cwd() + '/package.json');\n DatabaseConstructor = requireFromDisk('better-sqlite3');\n } catch {\n // Fallback: resolve from the directory of the executable\n const execDir = path.dirname(process.execPath);\n const requireFromDisk = createRequire(execDir + '/package.json');\n DatabaseConstructor = requireFromDisk('better-sqlite3');\n }\n}\n\nlet dbInstance: DatabaseType.Database | null = null;\n\n/**\n * Connects to the SQLite database located at `<workspaceRoot>/.worklog/worklog.db`.\n * Optimizes SQLite performance parameters for local CLI use.\n */\nexport function connectDatabase(workspaceRoot: string): DatabaseType.Database {\n if (dbInstance) {\n return dbInstance;\n }\n\n const dbDir = path.join(workspaceRoot, '.worklog');\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n\n const dbPath = path.join(dbDir, 'worklog.db');\n\n try {\n const db = new DatabaseConstructor(dbPath);\n\n // Performance optimizations for local development CLI\n db.pragma('foreign_keys = ON');\n db.pragma('journal_mode = WAL');\n db.pragma('synchronous = NORMAL');\n db.pragma('temp_store = MEMORY');\n\n dbInstance = db;\n logger.debug({ dbPath }, 'Connected to SQLite database successfully');\n return db;\n } catch (error: any) {\n logger.error({ error, dbPath }, 'Failed to connect to SQLite database');\n throw new DatabaseError('Failed to connect to database', error.message);\n }\n}\n\n/**\n * Returns the currently active database instance.\n * Throws if the database has not been initialized.\n */\nexport function getDatabase(): DatabaseType.Database {\n const db = dbInstance;\n if (!db) {\n throw new DatabaseError('Database is not initialized. Call connectDatabase first.');\n }\n return db;\n}\n\n/**\n * Closes the database connection cleanly.\n */\nexport function closeDatabase(): void {\n if (dbInstance) {\n try {\n dbInstance.close();\n logger.debug('Database connection closed');\n } catch (error: any) {\n logger.error({ error }, 'Error closing database connection');\n } finally {\n dbInstance = null;\n }\n }\n}\n","export const MIGRATIONS: Record<string, string> = {\n '001_initial.sql': `\nCREATE TABLE IF NOT EXISTS work_units (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n title TEXT NOT NULL,\n type TEXT NOT NULL,\n status TEXT NOT NULL,\n priority TEXT,\n module TEXT,\n description TEXT,\n next_step TEXT,\n decision TEXT,\n blocker TEXT,\n notes TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\n-- Full Text Search Index Table\nCREATE VIRTUAL TABLE IF NOT EXISTS work_units_fts USING fts5(\n title,\n description,\n decision,\n blocker,\n notes,\n content=work_units,\n content_rowid=id\n);\n\n-- Auto-sync Insert Trigger\nCREATE TRIGGER IF NOT EXISTS work_units_ai AFTER INSERT ON work_units BEGIN\n INSERT INTO work_units_fts(rowid, title, description, decision, blocker, notes)\n VALUES (new.id, new.title, new.description, new.decision, new.blocker, new.notes);\nEND;\n\n-- Auto-sync Delete Trigger\nCREATE TRIGGER IF NOT EXISTS work_units_ad AFTER DELETE ON work_units BEGIN\n INSERT INTO work_units_fts(work_units_fts, rowid, title, description, decision, blocker, notes)\n VALUES('delete', old.id, old.title, old.description, old.decision, old.blocker, old.notes);\nEND;\n\n-- Auto-sync Update Trigger\nCREATE TRIGGER IF NOT EXISTS work_units_au AFTER UPDATE ON work_units BEGIN\n INSERT INTO work_units_fts(work_units_fts, rowid, title, description, decision, blocker, notes)\n VALUES('delete', old.id, old.title, old.description, old.decision, old.blocker, old.notes);\n INSERT INTO work_units_fts(rowid, title, description, decision, blocker, notes)\n VALUES (new.id, new.title, new.description, new.decision, new.blocker, new.notes);\nEND;\n `,\n '002_relational_tables.sql': `\n-- Junction table for tags\nCREATE TABLE IF NOT EXISTS work_unit_tags (\n work_unit_id INTEGER NOT NULL,\n tag TEXT NOT NULL,\n PRIMARY KEY (work_unit_id, tag),\n FOREIGN KEY (work_unit_id) REFERENCES work_units(id) ON DELETE CASCADE\n);\n\n-- Index for tag filtering performance\nCREATE INDEX IF NOT EXISTS idx_work_unit_tags_tag ON work_unit_tags(tag);\n\n-- Junction table for bidirectional relation mapping\nCREATE TABLE IF NOT EXISTS work_unit_relations (\n work_unit_id INTEGER NOT NULL,\n related_work_unit_id INTEGER NOT NULL,\n PRIMARY KEY (work_unit_id, related_work_unit_id),\n FOREIGN KEY (work_unit_id) REFERENCES work_units(id) ON DELETE CASCADE,\n FOREIGN KEY (related_work_unit_id) REFERENCES work_units(id) ON DELETE CASCADE\n);\n `,\n};\n","import Database from 'better-sqlite3';\nimport { logger } from '../core/logger.js';\nimport { DatabaseError } from '../errors/index.js';\nimport { MIGRATIONS } from './migration-data.js';\n\n/**\n * Runs all pending migrations sequentially within a database transaction.\n */\nexport function runMigrations(db: Database.Database): void {\n logger.debug('Starting database migrations run');\n\n // Step 1: Ensure the schema_migrations table exists\n db.exec(`\n CREATE TABLE IF NOT EXISTS schema_migrations (\n version TEXT PRIMARY KEY,\n applied_at TEXT NOT NULL\n );\n `);\n\n // Step 2: Get sorted migration keys\n const files = Object.keys(MIGRATIONS).sort();\n\n if (files.length === 0) {\n logger.debug('No migration definitions found');\n return;\n }\n\n // Step 3: Get already applied migrations\n const stmt = db.prepare('SELECT version FROM schema_migrations');\n const applied: string[] = stmt.all().map((row: any) => row.version);\n\n // Step 4: Apply outstanding migrations in order\n for (const file of files) {\n if (applied.includes(file)) {\n logger.debug({ migration: file }, 'Migration already applied, skipping');\n continue;\n }\n\n logger.info({ migration: file }, `Applying database migration: ${file}`);\n const sql = MIGRATIONS[file];\n\n // Run migrations inside a transaction\n const runMigrationTx = db.transaction(() => {\n db.exec(sql);\n const insertStmt = db.prepare(\n 'INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)',\n );\n insertStmt.run(file, new Date().toISOString());\n });\n\n try {\n runMigrationTx();\n logger.info({ migration: file }, `Migration ${file} applied successfully`);\n } catch (error: any) {\n logger.error({ error, migration: file }, `Failed to apply migration: ${file}`);\n throw new DatabaseError(`Failed to apply migration ${file}`, error.message);\n }\n }\n\n logger.debug('Database migrations completed');\n}\nexport function getMigrationsDir(): string {\n // Provided for backward compatibility in tests\n return '';\n}\n","import Database from 'better-sqlite3';\nimport { WorkUnit, WorkUnitType, WorkUnitStatus, WorkUnitPriority } from '../models/work-unit.js';\nimport { DatabaseError } from '../errors/index.js';\nimport { logger } from '../core/logger.js';\n\nexport interface SearchFilters {\n tag?: string;\n module?: string;\n status?: string;\n type?: string;\n}\n\nexport interface WorkUnitStats {\n totalCount: number;\n typeDistribution: { type: string; count: number }[];\n statusDistribution: { status: string; count: number }[];\n moduleDistribution: { module: string; count: number }[];\n dailyActivity: { day: string; count: number }[];\n}\n\nexport class WorkUnitRepository {\n constructor(private db: Database.Database) {}\n\n /**\n * Creates a new WorkUnit in the database.\n * Inserts relations into work_unit_tags and work_unit_relations under a transaction.\n */\n create(workUnitData: Omit<WorkUnit, 'id'>): WorkUnit {\n const createTx = this.db.transaction(() => {\n // 1. Insert into main work_units table\n const insertUnit = this.db.prepare(`\n INSERT INTO work_units (\n title, type, status, priority, module, description, next_step, decision, blocker, notes, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const result = insertUnit.run(\n workUnitData.title,\n workUnitData.type,\n workUnitData.status,\n workUnitData.priority,\n workUnitData.module,\n workUnitData.description,\n workUnitData.nextStep,\n workUnitData.decision,\n workUnitData.blocker,\n workUnitData.notes,\n workUnitData.createdAt,\n workUnitData.updatedAt,\n );\n\n const workUnitId = Number(result.lastInsertRowid);\n\n // 2. Insert tags\n if (workUnitData.tags && workUnitData.tags.length > 0) {\n const insertTag = this.db.prepare(`\n INSERT INTO work_unit_tags (work_unit_id, tag) VALUES (?, ?)\n `);\n for (const tag of workUnitData.tags) {\n insertTag.run(workUnitId, tag);\n }\n }\n\n // 3. Insert relations\n if (workUnitData.relatedWorkUnits && workUnitData.relatedWorkUnits.length > 0) {\n const insertRelation = this.db.prepare(`\n INSERT INTO work_unit_relations (work_unit_id, related_work_unit_id) VALUES (?, ?)\n `);\n const checkStmt = this.db.prepare('SELECT 1 FROM work_units WHERE id = ?');\n for (const relId of workUnitData.relatedWorkUnits) {\n if (!checkStmt.get(relId)) {\n throw new DatabaseError(`Related work unit with ID ${relId} does not exist.`);\n }\n insertRelation.run(workUnitId, relId);\n }\n }\n\n return workUnitId;\n });\n\n try {\n const id = createTx();\n return this.findById(id)!;\n } catch (error: any) {\n if (error instanceof DatabaseError) throw error;\n throw new DatabaseError('Failed to create work unit', error.message);\n }\n }\n\n /**\n * Fetches a WorkUnit by ID and joins related tags and relations.\n */\n findById(id: number): WorkUnit | null {\n try {\n // 1. Fetch main record\n const selectUnit = this.db.prepare(`\n SELECT * FROM work_units WHERE id = ?\n `);\n const row = selectUnit.get(id) as any;\n if (!row) {\n return null;\n }\n\n // 2. Fetch tags\n const selectTags = this.db.prepare(`\n SELECT tag FROM work_unit_tags WHERE work_unit_id = ? ORDER BY tag ASC\n `);\n const tags = selectTags.all(id).map((r: any) => r.tag);\n\n // 3. Fetch relations\n const selectRelations = this.db.prepare(`\n SELECT related_work_unit_id FROM work_unit_relations WHERE work_unit_id = ? ORDER BY related_work_unit_id ASC\n `);\n const related = selectRelations.all(id).map((r: any) => Number(r.related_work_unit_id));\n\n // 4. Map DB row to Domain Model\n return {\n id: Number(row.id),\n title: row.title,\n type: row.type as WorkUnitType,\n status: row.status as WorkUnitStatus,\n priority: row.priority as WorkUnitPriority | null,\n module: row.module,\n description: row.description,\n nextStep: row.next_step,\n decision: row.decision,\n blocker: row.blocker,\n tags,\n relatedWorkUnits: related,\n notes: row.notes,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n } catch (error: any) {\n throw new DatabaseError(`Failed to find work unit by ID ${id}`, error.message);\n }\n }\n\n /**\n * Updates an existing WorkUnit.\n * Handles differential updates for fields, tags, and relations.\n */\n update(\n id: number,\n workUnitData: Partial<Omit<WorkUnit, 'id' | 'createdAt'>> & { updatedAt: string },\n ): WorkUnit {\n const updateTx = this.db.transaction(() => {\n // 1. Check if exists\n const existing = this.findById(id);\n if (!existing) {\n throw new DatabaseError(`Work unit with ID ${id} not found.`);\n }\n\n // 2. Build SET clause dynamically\n const updates: string[] = [];\n const values: any[] = [];\n\n const fieldsMap: { [key: string]: string } = {\n title: 'title',\n type: 'type',\n status: 'status',\n priority: 'priority',\n module: 'module',\n description: 'description',\n nextStep: 'next_step',\n decision: 'decision',\n blocker: 'blocker',\n notes: 'notes',\n updatedAt: 'updated_at',\n };\n\n for (const [key, dbCol] of Object.entries(fieldsMap)) {\n if (key in workUnitData) {\n updates.push(`${dbCol} = ?`);\n values.push((workUnitData as any)[key]);\n }\n }\n\n if (updates.length > 0) {\n values.push(id);\n const updateStmt = this.db.prepare(`\n UPDATE work_units SET ${updates.join(', ')} WHERE id = ?\n `);\n updateStmt.run(...values);\n }\n\n // 3. Update tags if provided\n if (workUnitData.tags !== undefined) {\n const deleteTags = this.db.prepare('DELETE FROM work_unit_tags WHERE work_unit_id = ?');\n deleteTags.run(id);\n\n if (workUnitData.tags.length > 0) {\n const insertTag = this.db.prepare(\n 'INSERT INTO work_unit_tags (work_unit_id, tag) VALUES (?, ?)',\n );\n for (const tag of workUnitData.tags) {\n insertTag.run(id, tag);\n }\n }\n }\n\n // 4. Update relations if provided\n if (workUnitData.relatedWorkUnits !== undefined) {\n const deleteRelations = this.db.prepare(\n 'DELETE FROM work_unit_relations WHERE work_unit_id = ?',\n );\n deleteRelations.run(id);\n\n if (workUnitData.relatedWorkUnits.length > 0) {\n const insertRelation = this.db.prepare(\n 'INSERT INTO work_unit_relations (work_unit_id, related_work_unit_id) VALUES (?, ?)',\n );\n const checkStmt = this.db.prepare('SELECT 1 FROM work_units WHERE id = ?');\n for (const relId of workUnitData.relatedWorkUnits) {\n if (!checkStmt.get(relId)) {\n throw new DatabaseError(`Related work unit with ID ${relId} does not exist.`);\n }\n insertRelation.run(id, relId);\n }\n }\n }\n });\n\n try {\n updateTx();\n return this.findById(id)!;\n } catch (error: any) {\n if (error instanceof DatabaseError) throw error;\n throw new DatabaseError(`Failed to update work unit by ID ${id}`, error.message);\n }\n }\n\n /**\n * Deletes a WorkUnit. Returns true if changes were made.\n */\n delete(id: number): boolean {\n try {\n const deleteStmt = this.db.prepare('DELETE FROM work_units WHERE id = ?');\n const info = deleteStmt.run(id);\n return info.changes > 0;\n } catch (error: any) {\n throw new DatabaseError(`Failed to delete work unit by ID ${id}`, error.message);\n }\n }\n\n /**\n * Finds the most recent work units, ordered by creation date descending.\n */\n findRecent(limit: number = 10): WorkUnit[] {\n try {\n const selectIds = this.db.prepare(`\n SELECT id FROM work_units ORDER BY created_at DESC LIMIT ?\n `);\n const rows = selectIds.all(limit);\n return rows.map((row: any) => this.findById(row.id) as WorkUnit);\n } catch (error: any) {\n throw new DatabaseError('Failed to fetch recent work units', error.message);\n }\n }\n\n /**\n * Finds work units matching a specific status.\n */\n findByStatus(status: WorkUnitStatus): WorkUnit[] {\n try {\n const selectIds = this.db.prepare(`\n SELECT id FROM work_units WHERE status = ? ORDER BY created_at DESC\n `);\n const rows = selectIds.all(status);\n return rows.map((row: any) => this.findById(row.id) as WorkUnit);\n } catch (error: any) {\n throw new DatabaseError(`Failed to fetch work units by status: ${status}`, error.message);\n }\n }\n\n /**\n * Finds work units matching a specific type.\n */\n findByType(type: WorkUnitType): WorkUnit[] {\n try {\n const selectIds = this.db.prepare(`\n SELECT id FROM work_units WHERE type = ? ORDER BY created_at DESC\n `);\n const rows = selectIds.all(type);\n return rows.map((row: any) => this.findById(row.id) as WorkUnit);\n } catch (error: any) {\n throw new DatabaseError(`Failed to fetch work units by type: ${type}`, error.message);\n }\n }\n\n /**\n * Finds all unfinished work units (Planned, In Progress, Blocked) ordered by updatedAt descending.\n */\n findUnfinished(): WorkUnit[] {\n try {\n const selectIds = this.db.prepare(`\n SELECT id FROM work_units\n WHERE status IN ('Planned', 'In Progress', 'Blocked')\n ORDER BY updated_at DESC\n `);\n const rows = selectIds.all();\n return rows.map((row: any) => this.findById(row.id) as WorkUnit);\n } catch (error: any) {\n throw new DatabaseError('Failed to fetch unfinished work units', error.message);\n }\n }\n\n /**\n * Finds work units created or updated since an ISO timestamp.\n */\n findCreatedOrUpdatedAfter(isoString: string): WorkUnit[] {\n try {\n const selectIds = this.db.prepare(`\n SELECT id FROM work_units\n WHERE created_at >= ? OR updated_at >= ?\n ORDER BY created_at DESC\n `);\n const rows = selectIds.all(isoString, isoString);\n return rows.map((row: any) => this.findById(row.id) as WorkUnit);\n } catch (error: any) {\n throw new DatabaseError(\n `Failed to fetch work units updated after ${isoString}`,\n error.message,\n );\n }\n }\n\n /**\n * Runs analytical SQL queries to fetch count aggregates.\n */\n getStats(sinceIsoString: string): WorkUnitStats {\n try {\n // 1. Total Count\n const totalCount = (\n this.db.prepare('SELECT COUNT(*) as count FROM work_units').get() as any\n ).count;\n\n // 2. Type Distribution\n const typeRows = this.db\n .prepare(\n 'SELECT type, COUNT(*) as count FROM work_units GROUP BY type ORDER BY count DESC',\n )\n .all() as any[];\n const typeDistribution = typeRows.map((r) => ({ type: r.type, count: r.count }));\n\n // 3. Status Distribution\n const statusRows = this.db\n .prepare(\n 'SELECT status, COUNT(*) as count FROM work_units GROUP BY status ORDER BY count DESC',\n )\n .all() as any[];\n const statusDistribution = statusRows.map((r) => ({ status: r.status, count: r.count }));\n\n // 4. Module Distribution\n const moduleRows = this.db\n .prepare(`\n SELECT module, COUNT(*) as count FROM work_units\n WHERE module IS NOT NULL AND module != ''\n GROUP BY module ORDER BY count DESC\n `)\n .all() as any[];\n const moduleDistribution = moduleRows.map((r) => ({ module: r.module, count: r.count }));\n\n // 5. Daily activity: Group by Date parsed from ISO string\n const dailyRows = this.db\n .prepare(`\n SELECT date(created_at) as day, COUNT(*) as count FROM work_units\n WHERE created_at >= ?\n GROUP BY day ORDER BY day ASC\n `)\n .all(sinceIsoString) as any[];\n const dailyActivity = dailyRows.map((r) => ({ day: r.day, count: r.count }));\n\n return {\n totalCount,\n typeDistribution,\n statusDistribution,\n moduleDistribution,\n dailyActivity,\n };\n } catch (error: any) {\n throw new DatabaseError('Failed to fetch aggregate statistics', error.message);\n }\n }\n\n /**\n * Case-insensitive, structured multi-criteria search combining FTS5 and standard filters.\n */\n search(query: string, filters: SearchFilters = {}): WorkUnit[] {\n try {\n let ids: number[] = [];\n const hasQuery = query.trim().length > 0;\n\n if (hasQuery) {\n const trimmed = query.trim();\n // FTS5 MATCH format\n const ftsQuery = `\"${trimmed}\" OR ${trimmed}*`;\n try {\n const stmt = this.db.prepare(`\n SELECT rowid as id FROM work_units_fts WHERE work_units_fts MATCH ?\n `);\n ids = stmt.all(ftsQuery).map((r: any) => Number(r.id));\n } catch (ftsError: any) {\n logger.warn({ ftsError, query }, 'FTS MATCH failed; using fallback LIKE list');\n // If FTS fails (due to query syntax), do a fallback retrieve of all IDs containing query in LIKE\n const fallbackStmt = this.db.prepare(`\n SELECT id FROM work_units\n WHERE title LIKE ? OR description LIKE ? OR notes LIKE ? OR decision LIKE ? OR blocker LIKE ?\n `);\n const likeParam = `%${trimmed}%`;\n ids = fallbackStmt\n .all(likeParam, likeParam, likeParam, likeParam, likeParam)\n .map((r: any) => Number(r.id));\n }\n\n if (ids.length === 0) {\n return []; // no text matches, exit early\n }\n }\n\n // Build conditional SQL query\n const clauses: string[] = [];\n const params: any[] = [];\n\n if (hasQuery) {\n // Chunk ID binds if too large, but for standard search length we place binds directly\n clauses.push(`id IN (${ids.map(() => '?').join(',')})`);\n params.push(...ids);\n }\n\n if (filters.module) {\n clauses.push('LOWER(module) = LOWER(?)');\n params.push(filters.module);\n }\n\n if (filters.status) {\n clauses.push('LOWER(status) = LOWER(?)');\n params.push(filters.status);\n }\n\n if (filters.type) {\n clauses.push('LOWER(type) = LOWER(?)');\n params.push(filters.type);\n }\n\n if (filters.tag) {\n clauses.push(`id IN (\n SELECT work_unit_id FROM work_unit_tags WHERE LOWER(tag) = LOWER(?)\n )`);\n params.push(filters.tag);\n }\n\n const whereClause = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';\n const sql = `\n SELECT id FROM work_units\n ${whereClause}\n ORDER BY created_at DESC\n `;\n\n const rows = this.db.prepare(sql).all(...params);\n return rows.map((row: any) => this.findById(row.id) as WorkUnit);\n } catch (error: any) {\n throw new DatabaseError(`Search operation failed: ${error.message}`);\n }\n }\n}\n","import { z } from 'zod';\n\nconst WorkUnitTypeSchema = z.enum([\n 'Feature',\n 'Bug',\n 'Spike',\n 'Refactor',\n 'Improvement',\n 'Research',\n 'Decision',\n 'Blocker',\n 'Review',\n 'Idea',\n]);\n\nconst WorkUnitStatusSchema = z.enum([\n 'Planned',\n 'In Progress',\n 'Blocked',\n 'Completed',\n 'Cancelled',\n]);\n\nconst WorkUnitPrioritySchema = z.enum(['Low', 'Medium', 'High']);\n\nexport const CreateWorkUnitSchema = z.object({\n title: z\n .string()\n .trim()\n .min(1, 'Title cannot be empty')\n .max(200, 'Title cannot exceed 200 characters'),\n type: WorkUnitTypeSchema,\n status: WorkUnitStatusSchema.default('Planned'),\n priority: WorkUnitPrioritySchema.nullable().optional().default(null),\n module: z\n .string()\n .trim()\n .max(100, 'Module cannot exceed 100 characters')\n .nullable()\n .optional()\n .default(null),\n description: z.string().trim().nullable().optional().default(null),\n nextStep: z.string().trim().nullable().optional().default(null),\n decision: z.string().trim().nullable().optional().default(null),\n blocker: z.string().trim().nullable().optional().default(null),\n tags: z\n .array(\n z\n .string()\n .trim()\n .min(1, 'Tag cannot be empty')\n .max(50, 'Tag cannot exceed 50 characters'),\n )\n .optional()\n .default([]),\n relatedWorkUnits: z.array(z.number().int().positive()).optional().default([]),\n notes: z.string().trim().nullable().optional().default(null),\n});\n\nexport const UpdateWorkUnitSchema = CreateWorkUnitSchema.partial();\n\nexport type CreateWorkUnitInput = z.infer<typeof CreateWorkUnitSchema>;\nexport type UpdateWorkUnitInput = z.infer<typeof UpdateWorkUnitSchema>;\n","import { SearchFilters, WorkUnitRepository, WorkUnitStats } from '../repositories/work-unit.js';\nimport {\n CreateWorkUnitSchema,\n UpdateWorkUnitSchema,\n} from '../validators/work-unit.js';\nimport { WorkUnit, WorkUnitType, WorkUnitStatus } from '../models/work-unit.js';\nimport { ValidationError } from '../errors/index.js';\n\nexport class WorkUnitService {\n constructor(private repo: WorkUnitRepository) {}\n\n /**\n * Validates creation input at the service boundary, assigns initial timestamps, and persists to database.\n */\n createWorkUnit(input: unknown): WorkUnit {\n const result = CreateWorkUnitSchema.safeParse(input);\n if (!result.success) {\n const errorMsg = result.error.issues\n .map((issue) => `${issue.path.join('.')}: ${issue.message}`)\n .join(', ');\n throw new ValidationError(errorMsg);\n }\n\n const validated = result.data;\n const now = new Date().toISOString();\n\n const workUnitData: Omit<WorkUnit, 'id'> = {\n ...validated,\n createdAt: now,\n updatedAt: now,\n };\n\n return this.repo.create(workUnitData);\n }\n\n /**\n * Validates update input, updates timestamp, and runs repository update statement.\n */\n updateWorkUnit(id: number, input: unknown): WorkUnit {\n if (!id || id <= 0 || !Number.isInteger(id)) {\n throw new ValidationError('A valid positive integer ID is required.');\n }\n\n const result = UpdateWorkUnitSchema.safeParse(input);\n if (!result.success) {\n const errorMsg = result.error.issues\n .map((issue) => `${issue.path.join('.')}: ${issue.message}`)\n .join(', ');\n throw new ValidationError(errorMsg);\n }\n\n const validated = result.data;\n const now = new Date().toISOString();\n\n const workUnitData: Partial<Omit<WorkUnit, 'id' | 'createdAt'>> & { updatedAt: string } = {\n ...validated,\n updatedAt: now,\n };\n\n return this.repo.update(id, workUnitData);\n }\n\n /**\n * Fetches a WorkUnit by its ID. Throws on negative/decimal values.\n */\n getWorkUnit(id: number): WorkUnit | null {\n if (!id || id <= 0 || !Number.isInteger(id)) {\n throw new ValidationError('A valid positive integer ID is required.');\n }\n return this.repo.findById(id);\n }\n\n /**\n * Deletes a WorkUnit by ID. Returns true if deleted.\n */\n deleteWorkUnit(id: number): boolean {\n if (!id || id <= 0 || !Number.isInteger(id)) {\n throw new ValidationError('A valid positive integer ID is required.');\n }\n return this.repo.delete(id);\n }\n\n /**\n * Retrieves recent WorkUnits.\n */\n getRecentWorkUnits(limit?: number): WorkUnit[] {\n return this.repo.findRecent(limit);\n }\n\n /**\n * Retrieves WorkUnits filtered by Status.\n */\n getWorkUnitsByStatus(status: WorkUnitStatus): WorkUnit[] {\n return this.repo.findByStatus(status);\n }\n\n /**\n * Retrieves WorkUnits filtered by Type.\n */\n getWorkUnitsByType(type: WorkUnitType): WorkUnit[] {\n return this.repo.findByType(type);\n }\n\n /**\n * Retrieves all unfinished Work Units (Planned, In Progress, Blocked) sorted by updatedAt descending.\n */\n getUnfinishedWorkUnits(): WorkUnit[] {\n return this.repo.findUnfinished();\n }\n\n /**\n * Retrieves Work Units created or updated since an ISO timestamp.\n */\n getCreatedOrUpdatedAfter(isoString: string): WorkUnit[] {\n return this.repo.findCreatedOrUpdatedAfter(isoString);\n }\n\n /**\n * Retrieves SQLite aggregated statistics.\n */\n getStats(sinceIsoString: string): WorkUnitStats {\n return this.repo.getStats(sinceIsoString);\n }\n\n /**\n * Searches WorkUnits by text query and structured filters.\n */\n searchWorkUnits(query: string, filters: SearchFilters = {}): WorkUnit[] {\n return this.repo.search(query, filters);\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport pc from 'picocolors';\nimport { initConfig } from '../../core/config.js';\nimport { connectDatabase } from '../../database/connection.js';\nimport { runMigrations } from '../../database/migrations.js';\nimport { initLogger } from '../../core/logger.js';\n\ninterface InitOptions {\n name?: string;\n json?: boolean;\n}\n\n/**\n * Initializes a new WorkLog repository in the current working directory.\n */\nexport function initCommand(options: InitOptions): void {\n const targetDir = process.cwd();\n const dotWorklog = path.join(targetDir, '.worklog');\n\n const exists = fs.existsSync(dotWorklog) && fs.statSync(dotWorklog).isDirectory();\n\n if (!fs.existsSync(dotWorklog)) {\n fs.mkdirSync(dotWorklog, { recursive: true });\n }\n\n // 1. Initialize configuration\n const config = initConfig(targetDir, options.name);\n\n // 2. Initialize logger\n initLogger(targetDir);\n\n // 3. Connect database & run migrations\n const db = connectDatabase(targetDir);\n runMigrations(db);\n\n if (options.json) {\n console.log(\n JSON.stringify({\n success: true,\n message: exists\n ? 'Reinitialized existing WorkLog repository'\n : 'Initialized empty WorkLog repository',\n projectName: config.projectName,\n path: dotWorklog,\n }),\n );\n } else {\n const verb = exists ? 'Reinitialized existing' : 'Initialized empty';\n console.log(pc.green(`${verb} WorkLog repository in ${dotWorklog}/`));\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { z } from 'zod';\nimport { ConfigError } from '../errors/index.js';\n\nexport const ConfigSchema = z.object({\n projectName: z.string(),\n createdAt: z.string(),\n schemaVersion: z.number().default(1),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nconst DEFAULT_CONFIG_FILENAME = 'config.json';\n\n/**\n * Loads and validates the configuration file from a workspace root.\n */\nexport function loadConfig(workspaceRoot: string): Config {\n const configPath = path.join(workspaceRoot, '.worklog', DEFAULT_CONFIG_FILENAME);\n if (!fs.existsSync(configPath)) {\n throw new ConfigError(`Config file not found at ${configPath}.`);\n }\n\n try {\n const raw = fs.readFileSync(configPath, 'utf8');\n const parsed = JSON.parse(raw);\n return ConfigSchema.parse(parsed);\n } catch (error: any) {\n if (error instanceof z.ZodError) {\n throw new ConfigError(\n `Invalid config format: ${error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ')}`,\n );\n }\n throw new ConfigError(`Failed to read config file: ${error.message}`);\n }\n}\n\n/**\n * Saves and validates a configuration object to a workspace root.\n */\nexport function saveConfig(workspaceRoot: string, config: Config): void {\n const dotWorklog = path.join(workspaceRoot, '.worklog');\n if (!fs.existsSync(dotWorklog)) {\n fs.mkdirSync(dotWorklog, { recursive: true });\n }\n\n const configPath = path.join(dotWorklog, DEFAULT_CONFIG_FILENAME);\n try {\n const validated = ConfigSchema.parse(config);\n fs.writeFileSync(configPath, JSON.stringify(validated, null, 2), 'utf8');\n } catch (error: any) {\n throw new ConfigError(`Failed to save config: ${error.message}`);\n }\n}\n\n/**\n * Initializes a new configuration object in the workspace root.\n */\nexport function initConfig(workspaceRoot: string, projectName?: string): Config {\n const pName = projectName || path.basename(path.resolve(workspaceRoot));\n const newConfig: Config = {\n projectName: pName,\n createdAt: new Date().toISOString(),\n schemaVersion: 1,\n };\n saveConfig(workspaceRoot, newConfig);\n return newConfig;\n}\n","import prompts from 'prompts';\nimport pc from 'picocolors';\nimport { WorkUnitService } from '../../services/work-unit.js';\n\ninterface AddOptions {\n title?: string;\n type?: string;\n status?: string;\n priority?: string;\n module?: string;\n tags?: string;\n description?: string;\n next?: string;\n notes?: string;\n json?: boolean;\n}\n\nfunction capitalize(val: string): string {\n if (!val) return val;\n return val.charAt(0).toUpperCase() + val.slice(1).toLowerCase();\n}\n\nfunction parseStatus(val: string): string {\n if (!val) return val;\n const lower = val.toLowerCase();\n if (lower === 'in-progress' || lower === 'inprogress' || lower === 'in_progress') {\n return 'In Progress';\n }\n return capitalize(val);\n}\n\n/**\n * Creates a new Work Unit. If the title is omitted, starts interactive prompting.\n */\nexport async function addCommand(service: WorkUnitService, options: AddOptions): Promise<void> {\n let inputData: any;\n\n if (!options.title) {\n // Check if stdin is a TTY before starting prompts\n if (!process.stdin.isTTY) {\n if (options.json) {\n console.error(\n JSON.stringify({\n success: false,\n error: 'Title is required in non-interactive mode.',\n }),\n );\n } else {\n console.error(pc.red('Error: Title is required in non-interactive mode.'));\n }\n process.exit(1);\n }\n\n // Interactive Mode\n const responses = await prompts(\n [\n {\n type: 'text',\n name: 'title',\n message: 'Title:',\n validate: (val) => (val.trim().length > 0 ? true : 'Title is required'),\n },\n {\n type: 'select',\n name: 'type',\n message: 'Type:',\n choices: [\n { title: 'Feature', value: 'Feature' },\n { title: 'Bug', value: 'Bug' },\n { title: 'Spike', value: 'Spike' },\n { title: 'Refactor', value: 'Refactor' },\n { title: 'Improvement', value: 'Improvement' },\n { title: 'Research', value: 'Research' },\n { title: 'Decision', value: 'Decision' },\n { title: 'Blocker', value: 'Blocker' },\n { title: 'Review', value: 'Review' },\n { title: 'Idea', value: 'Idea' },\n ],\n initial: 0,\n },\n {\n type: 'select',\n name: 'status',\n message: 'Status:',\n choices: [\n { title: 'Planned', value: 'Planned' },\n { title: 'In Progress', value: 'In Progress' },\n { title: 'Blocked', value: 'Blocked' },\n { title: 'Completed', value: 'Completed' },\n { title: 'Cancelled', value: 'Cancelled' },\n ],\n initial: 0,\n },\n {\n type: 'text',\n name: 'description',\n message: 'Description (optional):',\n format: (val) => val.trim() || null,\n },\n {\n type: 'text',\n name: 'module',\n message: 'Module (optional):',\n format: (val) => val.trim() || null,\n },\n {\n type: 'text',\n name: 'tags',\n message: 'Tags (comma-separated, optional):',\n format: (val) => val.trim() || null,\n },\n {\n type: 'text',\n name: 'nextStep',\n message: 'Next Step (optional):',\n format: (val) => val.trim() || null,\n },\n ],\n {\n onCancel: () => {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'Cancelled by user' }));\n } else {\n console.log(pc.yellow('\\nCancelled.'));\n }\n process.exit(1);\n },\n },\n );\n\n const parsedTags = responses.tags\n ? responses.tags\n .split(',')\n .map((t: string) => t.trim())\n .filter(Boolean)\n : [];\n\n inputData = {\n title: responses.title,\n type: responses.type,\n status: responses.status,\n description: responses.description,\n module: responses.module,\n tags: parsedTags,\n nextStep: responses.nextStep,\n };\n } else {\n // Non-Interactive Mode\n const parsedTags = options.tags\n ? options.tags\n .split(',')\n .map((t: string) => t.trim())\n .filter(Boolean)\n : [];\n\n inputData = {\n title: options.title,\n type: options.type ? capitalize(options.type) : 'Feature',\n status: options.status ? parseStatus(options.status) : 'Planned',\n priority: options.priority ? capitalize(options.priority) : null,\n module: options.module || null,\n tags: parsedTags,\n description: options.description || null,\n nextStep: options.next || null,\n notes: options.notes || null,\n };\n }\n\n const created = service.createWorkUnit(inputData);\n\n if (options.json) {\n console.log(JSON.stringify(created));\n } else {\n console.log(pc.green(`Created work unit #${created.id}: ${created.title}`));\n }\n}\n","import pc from 'picocolors';\nimport Table from 'cli-table3';\nimport { WorkUnit, WorkUnitStatus, WorkUnitType, WorkUnitPriority } from '../models/work-unit.js';\nimport { WorkUnitStats } from '../repositories/work-unit.js';\n\n/**\n * Returns the width of the terminal, defaulting to 80 columns.\n */\nexport function getTerminalWidth(): number {\n return process.stdout.columns || 80;\n}\n\n/**\n * Truncates text and removes newlines, appending an ellipsis if exceeded.\n */\nexport function truncateText(text: string | null | undefined, maxLength: number): string {\n if (!text) return '';\n const clean = text.replace(/\\r?\\n|\\r/g, ' ').trim();\n if (clean.length <= maxLength) return clean;\n return clean.substring(0, maxLength - 3) + '...';\n}\n\n/**\n * Maps a WorkUnitStatus to a colored terminal string.\n */\nexport function colorStatus(status: WorkUnitStatus): string {\n switch (status) {\n case 'Planned':\n return pc.gray('Planned');\n case 'In Progress':\n return pc.blue('In Progress');\n case 'Blocked':\n return pc.red('Blocked');\n case 'Completed':\n return pc.green('Completed');\n case 'Cancelled':\n return pc.strikethrough(pc.gray('Cancelled'));\n default:\n return status;\n }\n}\n\n/**\n * Maps a WorkUnitType to a colored terminal string.\n */\nexport function colorType(type: WorkUnitType): string {\n switch (type) {\n case 'Feature':\n return pc.cyan('Feature');\n case 'Bug':\n return pc.red('Bug');\n case 'Spike':\n return pc.magenta('Spike');\n case 'Refactor':\n return pc.yellow('Refactor');\n case 'Improvement':\n return pc.green('Improvement');\n case 'Research':\n return pc.blue('Research');\n case 'Decision':\n return pc.cyan(pc.bold('Decision'));\n case 'Blocker':\n return pc.bgRed(pc.white('Blocker'));\n case 'Review':\n return pc.yellow('Review');\n case 'Idea':\n return pc.gray('Idea');\n default:\n return type;\n }\n}\n\n/**\n * Maps a WorkUnitPriority to a colored terminal string.\n */\nexport function colorPriority(priority: WorkUnitPriority | null): string {\n if (!priority) return pc.gray('-');\n switch (priority) {\n case 'High':\n return pc.red('High');\n case 'Medium':\n return pc.yellow('Medium');\n case 'Low':\n return pc.green('Low');\n default:\n return priority;\n }\n}\n\n/**\n * Formats a list of work units as a minimal, git-like text table.\n */\nexport function formatTable(workUnits: WorkUnit[]): string {\n if (workUnits.length === 0) {\n return 'No work units found.';\n }\n\n const table = new Table({\n head: [\n pc.bold('ID'),\n pc.bold('Title'),\n pc.bold('Type'),\n pc.bold('Status'),\n pc.bold('Module'),\n pc.bold('Priority'),\n pc.bold('Created At'),\n ],\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n middle: ' ',\n },\n style: { 'padding-left': 0, 'padding-right': 2, head: [] },\n });\n\n const width = getTerminalWidth();\n // Reserve width for: ID(5) Type(14) Status(14) Module(12) Priority(10) Date(8) + spacing(12) = 75\n const titleMaxWidth = Math.max(20, width - 75);\n\n for (const unit of workUnits) {\n const formattedDate = new Date(unit.createdAt).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n });\n\n table.push([\n pc.gray(`#${unit.id}`),\n truncateText(unit.title, titleMaxWidth),\n colorType(unit.type),\n colorStatus(unit.status),\n unit.module ? pc.yellow(unit.module) : pc.gray('-'),\n colorPriority(unit.priority),\n pc.gray(formattedDate),\n ]);\n }\n\n return table.toString();\n}\n\n/**\n * Formats a single WorkUnit as a detail card.\n */\nexport function formatWorkUnitDetail(unit: WorkUnit): string {\n const lines: string[] = [];\n\n lines.push(`${pc.bold(pc.cyan(`[#${unit.id}] ${unit.title}`))}`);\n lines.push(`${pc.gray('--------------------------------------------------')}`);\n lines.push(`${pc.bold('Type:')} ${colorType(unit.type)}`);\n lines.push(`${pc.bold('Status:')} ${colorStatus(unit.status)}`);\n\n if (unit.priority) {\n lines.push(`${pc.bold('Priority:')} ${colorPriority(unit.priority)}`);\n }\n if (unit.module) {\n lines.push(`${pc.bold('Module:')} ${pc.yellow(unit.module)}`);\n }\n\n if (unit.tags && unit.tags.length > 0) {\n lines.push(`${pc.bold('Tags:')} ${unit.tags.map((t) => pc.blue(t)).join(', ')}`);\n }\n\n if (unit.relatedWorkUnits && unit.relatedWorkUnits.length > 0) {\n lines.push(\n `${pc.bold('Related:')} ${unit.relatedWorkUnits.map((id) => pc.gray(`#${id}`)).join(', ')}`,\n );\n }\n\n lines.push(`${pc.bold('Created:')} ${new Date(unit.createdAt).toLocaleString()}`);\n lines.push(`${pc.bold('Updated:')} ${new Date(unit.updatedAt).toLocaleString()}`);\n\n if (unit.description) {\n lines.push('');\n lines.push(`${pc.bold('Description:')}`);\n lines.push(unit.description);\n }\n\n if (unit.nextStep) {\n lines.push('');\n lines.push(`${pc.bold('Next Step:')}`);\n lines.push(pc.blue(`-> ${unit.nextStep}`));\n }\n\n if (unit.decision) {\n lines.push('');\n lines.push(`${pc.bold('Decision:')}`);\n lines.push(pc.green(`✔ ${unit.decision}`));\n }\n\n if (unit.blocker) {\n lines.push('');\n lines.push(`${pc.bold('Blocker:')}`);\n lines.push(pc.red(`✖ ${unit.blocker}`));\n }\n\n if (unit.notes) {\n lines.push('');\n lines.push(`${pc.bold('Notes:')}`);\n lines.push(unit.notes);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats a dashboard overview screen showing current tasks, blocked work, and recent updates.\n */\nexport function formatDashboard(\n inProgress: WorkUnit[],\n recentlyUpdated: WorkUnit[],\n needsAttention: WorkUnit[],\n): string {\n const lines: string[] = [];\n\n lines.push(pc.bold(pc.cyan('=== WORKLOG DASHBOARD ===\\n')));\n\n lines.push(pc.bold('CURRENTLY IN PROGRESS:'));\n if (inProgress.length === 0) {\n lines.push(pc.gray(' (No tasks currently in progress)'));\n } else {\n for (const u of inProgress) {\n lines.push(\n ` ${pc.gray(`#${u.id}`)} ${pc.bold(u.title)}${u.module ? ` [${u.module}]` : ''}`,\n );\n if (u.nextStep) {\n lines.push(` ${pc.blue('->')} ${pc.gray(u.nextStep)}`);\n }\n }\n }\n lines.push('');\n\n lines.push(pc.bold('NEEDS ATTENTION:'));\n if (needsAttention.length === 0) {\n lines.push(pc.gray(' (No blocked or planned tasks requiring attention)'));\n } else {\n for (const u of needsAttention) {\n const reason =\n u.status === 'Blocked'\n ? pc.red(`[Blocked: ${u.blocker || 'Unknown'}]`)\n : pc.yellow('[Planned]');\n lines.push(` ${pc.gray(`#${u.id}`)} ${reason} ${u.title}`);\n }\n }\n lines.push('');\n\n lines.push(pc.bold('RECENTLY UPDATED:'));\n if (recentlyUpdated.length === 0) {\n lines.push(pc.gray(' (No recent updates)'));\n } else {\n for (const u of recentlyUpdated) {\n const date = new Date(u.updatedAt).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n lines.push(\n ` ${pc.gray(`#${u.id}`)} ${pc.gray(`[${date}]`)} ${u.title} (${colorStatus(u.status)})`,\n );\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats statistics insights screen using clean text bars.\n */\nexport function formatStats(stats: WorkUnitStats): string {\n const lines: string[] = [];\n\n lines.push(pc.bold(pc.cyan('=== ENGINEERING INSIGHTS ===\\n')));\n lines.push(`${pc.bold('Total Work Units:')} ${stats.totalCount}\\n`);\n\n // 1. Status Distribution\n lines.push(pc.bold('STATUS DISTRIBUTION:'));\n for (const item of stats.statusDistribution) {\n lines.push(` ${item.status.padEnd(15)} : ${item.count}`);\n }\n lines.push('');\n\n // 2. Type Distribution\n lines.push(pc.bold('TYPE DISTRIBUTION:'));\n for (const item of stats.typeDistribution) {\n lines.push(` ${item.type.padEnd(15)} : ${item.count}`);\n }\n lines.push('');\n\n // 3. Module Distribution\n lines.push(pc.bold('MODULE DISTRIBUTION:'));\n if (stats.moduleDistribution.length === 0) {\n lines.push(' No modules tracked.');\n } else {\n for (const item of stats.moduleDistribution) {\n lines.push(` ${item.module.padEnd(15)} : ${item.count}`);\n }\n }\n lines.push('');\n\n // 4. Daily Activity over past 7 days\n lines.push(pc.bold('ACTIVITY IN THE PAST 7 DAYS:'));\n if (stats.dailyActivity.length === 0) {\n lines.push(' No work logged in the past 7 days.');\n } else {\n for (const item of stats.dailyActivity) {\n const bar = '*'.repeat(item.count);\n lines.push(` ${item.day} : ${bar} (${item.count})`);\n }\n }\n\n return lines.join('\\n');\n}\n","import { WorkUnitService } from '../../services/work-unit.js';\nimport { formatTable } from '../ui.js';\n\ninterface ListOptions {\n limit?: string;\n status?: string;\n type?: string;\n json?: boolean;\n}\n\n/**\n * Lists recent Work Units with optional filters.\n */\nexport function listCommand(service: WorkUnitService, options: ListOptions): void {\n const limitVal = options.limit ? Number(options.limit) : 20;\n let units = service.getRecentWorkUnits(limitVal);\n\n if (options.status) {\n const filterStatus = options.status.toLowerCase();\n units = units.filter((u) => u.status.toLowerCase() === filterStatus);\n }\n\n if (options.type) {\n const filterType = options.type.toLowerCase();\n units = units.filter((u) => u.type.toLowerCase() === filterType);\n }\n\n if (options.json) {\n console.log(JSON.stringify(units));\n } else {\n console.log(formatTable(units));\n }\n}\n","import pc from 'picocolors';\nimport { WorkUnitService } from '../../services/work-unit.js';\nimport { formatWorkUnitDetail } from '../ui.js';\n\ninterface ShowOptions {\n json?: boolean;\n}\n\n/**\n * Displays detailed information about a single Work Unit.\n */\nexport function showCommand(\n service: WorkUnitService,\n idStr: string,\n options: ShowOptions,\n): void {\n const id = Number(idStr);\n if (isNaN(id) || !Number.isInteger(id) || id <= 0) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'A valid positive integer ID is required.' }));\n } else {\n console.error(pc.red('Error: A valid positive integer ID is required.'));\n }\n process.exit(1);\n }\n\n const unit = service.getWorkUnit(id);\n if (!unit) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: `Work unit #${id} not found.` }));\n } else {\n console.error(pc.red(`Error: Work unit #${id} not found.`));\n }\n process.exit(1);\n }\n\n if (options.json) {\n console.log(JSON.stringify(unit));\n } else {\n console.log(formatWorkUnitDetail(unit));\n }\n}\n","import { WorkUnitService } from '../../services/work-unit.js';\nimport { formatTable } from '../ui.js';\n\ninterface SearchOptions {\n tag?: string;\n module?: string;\n status?: string;\n type?: string;\n json?: boolean;\n}\n\n/**\n * Searches Work Units by text queries and/or structured category filters.\n */\nexport function searchCommand(\n service: WorkUnitService,\n query: string | undefined,\n options: SearchOptions,\n): void {\n const textQuery = query || '';\n const results = service.searchWorkUnits(textQuery, {\n tag: options.tag,\n module: options.module,\n status: options.status,\n type: options.type,\n });\n\n if (options.json) {\n console.log(JSON.stringify(results));\n } else {\n console.log(formatTable(results));\n }\n}\n","import { WorkUnitService } from '../../services/work-unit.js';\nimport { formatTable } from '../ui.js';\n\ninterface TodayOptions {\n json?: boolean;\n}\n\n/**\n * Displays work units updated or created today.\n */\nexport function todayCommand(service: WorkUnitService, options: TodayOptions): void {\n const startOfToday = new Date();\n startOfToday.setHours(0, 0, 0, 0);\n const isoString = startOfToday.toISOString();\n\n const units = service.getCreatedOrUpdatedAfter(isoString);\n\n if (options.json) {\n console.log(JSON.stringify(units));\n } else {\n if (units.length === 0) {\n console.log('No work units logged today.');\n return;\n }\n console.log(formatTable(units));\n }\n}\n","import pc from 'picocolors';\nimport { WorkUnitService } from '../../services/work-unit.js';\n\ninterface WeekOptions {\n json?: boolean;\n}\n\n/**\n * Displays a weekly engineering summary of work logged over the past 7 days.\n */\nexport function weekCommand(service: WorkUnitService, options: WeekOptions): void {\n const sevenDaysAgo = new Date();\n sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);\n sevenDaysAgo.setHours(0, 0, 0, 0);\n const isoString = sevenDaysAgo.toISOString();\n\n const units = service.getCreatedOrUpdatedAfter(isoString);\n\n if (options.json) {\n console.log(JSON.stringify(units));\n return;\n }\n\n if (units.length === 0) {\n console.log('No work units logged in the past 7 days.');\n return;\n }\n\n // Filter categories\n const completedFeatures = units.filter((u) => u.type === 'Feature' && u.status === 'Completed');\n const fixedBugs = units.filter((u) => u.type === 'Bug' && u.status === 'Completed');\n const decisions = units.filter((u) => u.type === 'Decision' || u.decision !== null);\n const blockers = units.filter((u) => u.type === 'Blocker' || u.status === 'Blocked');\n const research = units.filter((u) => u.type === 'Research' || u.type === 'Spike');\n\n console.log(pc.bold(pc.cyan('=== WEEKLY ENGINEERING SUMMARY ===\\n')));\n\n console.log(pc.bold(`Features Completed (${completedFeatures.length}):`));\n if (completedFeatures.length === 0) console.log(' None');\n for (const u of completedFeatures) {\n console.log(` - #${u.id}: ${u.title}`);\n }\n console.log('');\n\n console.log(pc.bold(`Bugs Fixed (${fixedBugs.length}):`));\n if (fixedBugs.length === 0) console.log(' None');\n for (const u of fixedBugs) {\n console.log(` - #${u.id}: ${u.title}`);\n }\n console.log('');\n\n console.log(pc.bold(`Decisions Made (${decisions.length}):`));\n if (decisions.length === 0) console.log(' None');\n for (const u of decisions) {\n console.log(` - #${u.id}: ${u.title}`);\n if (u.decision) console.log(` ✔ ${pc.green(u.decision)}`);\n }\n console.log('');\n\n console.log(pc.bold(`Blockers Encountered (${blockers.length}):`));\n if (blockers.length === 0) console.log(' None');\n for (const u of blockers) {\n console.log(` - #${u.id}: ${u.title}`);\n if (u.blocker) console.log(` ✖ ${pc.red(u.blocker)}`);\n }\n console.log('');\n\n console.log(pc.bold(`Research & Spikes (${research.length}):`));\n if (research.length === 0) console.log(' None');\n for (const u of research) {\n console.log(` - #${u.id}: ${u.title} (${u.type})`);\n }\n console.log('');\n\n // Status & Type counts\n const typeCounts: Record<string, number> = {};\n const statusCounts: Record<string, number> = {};\n for (const u of units) {\n typeCounts[u.type] = (typeCounts[u.type] || 0) + 1;\n statusCounts[u.status] = (statusCounts[u.status] || 0) + 1;\n }\n\n console.log(pc.bold('WORK UNITS BY STATUS:'));\n for (const [status, count] of Object.entries(statusCounts)) {\n console.log(` - ${status.padEnd(15)}: ${count}`);\n }\n console.log('');\n\n console.log(pc.bold('WORK UNITS BY TYPE:'));\n for (const [type, count] of Object.entries(typeCounts)) {\n console.log(` - ${type.padEnd(15)}: ${count}`);\n }\n}\n","import { WorkUnitService } from '../../services/work-unit.js';\nimport { formatDashboard } from '../ui.js';\n\ninterface DashboardOptions {\n json?: boolean;\n}\n\n/**\n * Renders the WorkLog project overview dashboard.\n */\nexport function dashboardCommand(service: WorkUnitService, options: DashboardOptions): void {\n const inProgress = service.getWorkUnitsByStatus('In Progress');\n const recentlyUpdated = service.getRecentWorkUnits(5);\n\n const blocked = service.getWorkUnitsByStatus('Blocked');\n const planned = service.getWorkUnitsByStatus('Planned');\n const needsAttention = [...blocked, ...planned].slice(0, 5); // limit to 5 to keep dashboard concise\n\n if (options.json) {\n console.log(\n JSON.stringify({\n inProgress,\n recentlyUpdated,\n needsAttention,\n }),\n );\n } else {\n console.log(formatDashboard(inProgress, recentlyUpdated, needsAttention));\n }\n}\n","import prompts from 'prompts';\nimport pc from 'picocolors';\nimport { WorkUnitService } from '../../services/work-unit.js';\n\ninterface ContinueOptions {\n json?: boolean;\n}\n\n/**\n * Resumes work on the most recent unfinished Work Unit.\n */\nexport async function continueCommand(\n service: WorkUnitService,\n options: ContinueOptions,\n): Promise<void> {\n const unfinished = service.getUnfinishedWorkUnits(); // sorted by updated_at desc\n\n if (unfinished.length === 0) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'No unfinished work units found.' }));\n } else {\n console.log(pc.yellow('No unfinished work units found.'));\n }\n return;\n }\n\n let selectedUnit = unfinished[0];\n\n if (unfinished.length > 1) {\n if (!process.stdin.isTTY) {\n // Non-interactive: auto-resume the most recently touched unit\n selectedUnit = unfinished[0];\n } else {\n const choices = unfinished.map((u) => ({\n title: `#${u.id} - ${u.title} (${u.status})`,\n value: u,\n }));\n\n const response = await prompts(\n {\n type: 'select',\n name: 'unit',\n message: 'Select an unfinished work unit to resume:',\n choices,\n initial: 0,\n },\n {\n onCancel: () => {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'Cancelled by user' }));\n } else {\n console.log(pc.yellow('\\nCancelled.'));\n }\n process.exit(1);\n },\n },\n );\n\n if (!response.unit) {\n process.exit(1);\n }\n selectedUnit = response.unit;\n }\n }\n\n // Update status to In Progress\n const updated = service.updateWorkUnit(selectedUnit.id, {\n status: 'In Progress',\n });\n\n if (options.json) {\n console.log(JSON.stringify(updated));\n } else {\n console.log(\n pc.green(\n `Resumed work unit #${updated.id}: ${updated.title} (Status updated to 'In Progress')`,\n ),\n );\n }\n}\n","import { WorkUnitService } from '../../services/work-unit.js';\nimport { formatStats } from '../ui.js';\n\ninterface StatsOptions {\n json?: boolean;\n}\n\n/**\n * Renders analytical distributions and activity stats.\n */\nexport function statsCommand(service: WorkUnitService, options: StatsOptions): void {\n const sevenDaysAgo = new Date();\n sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);\n sevenDaysAgo.setHours(0, 0, 0, 0);\n\n const stats = service.getStats(sevenDaysAgo.toISOString());\n\n if (options.json) {\n console.log(JSON.stringify(stats));\n } else {\n console.log(formatStats(stats));\n }\n}\n","import * as fs from 'fs';\nimport pc from 'picocolors';\nimport { WorkUnitService } from '../../services/work-unit.js';\nimport { exportToMarkdown } from '../../exporters/markdown.js';\nimport { exportToCSV } from '../../exporters/csv.js';\nimport { exportToJSON } from '../../exporters/json.js';\nimport { WorkUnit } from '../../models/work-unit.js';\n\ninterface ExportOptions {\n format?: string;\n output?: string;\n id?: string;\n}\n\n/**\n * Handles exporting all work units or a single work unit into Markdown, CSV, or JSON formats.\n */\nexport function exportCommand(service: WorkUnitService, options: ExportOptions): void {\n let data: WorkUnit | WorkUnit[];\n\n if (options.id) {\n const id = Number(options.id);\n if (isNaN(id) || !Number.isInteger(id) || id <= 0) {\n console.error(pc.red('Error: A valid positive integer ID is required.'));\n process.exit(1);\n }\n const unit = service.getWorkUnit(id);\n if (!unit) {\n console.error(pc.red(`Error: Work unit #${id} not found.`));\n process.exit(1);\n }\n data = unit;\n } else {\n // Retrieve all units (up to 1,000,000 limit)\n data = service.getRecentWorkUnits(1000000);\n }\n\n let formatted = '';\n const format = (options.format || 'markdown').toLowerCase();\n\n switch (format) {\n case 'markdown':\n case 'md':\n formatted = exportToMarkdown(data);\n break;\n case 'csv':\n formatted = exportToCSV(data);\n break;\n case 'json':\n formatted = exportToJSON(data);\n break;\n default:\n console.error(\n pc.red(\n `Error: Unsupported format '${options.format}'. Supported: markdown (md), csv, json.`,\n ),\n );\n process.exit(1);\n }\n\n if (options.output) {\n try {\n fs.writeFileSync(options.output, formatted, 'utf8');\n console.log(pc.green(`Exported successfully to ${options.output}`));\n } catch (error: any) {\n console.error(pc.red(`Error: Failed to write to file '${options.output}': ${error.message}`));\n process.exit(1);\n }\n } else {\n process.stdout.write(formatted);\n }\n}\n","import { WorkUnit } from '../models/work-unit.js';\n\nfunction formatSingleMarkdown(u: WorkUnit): string {\n const lines: string[] = [];\n lines.push(`# [#${u.id}] ${u.title}\\n`);\n lines.push(`- **Type:** ${u.type}`);\n lines.push(`- **Status:** ${u.status}`);\n if (u.priority) lines.push(`- **Priority:** ${u.priority}`);\n if (u.module) lines.push(`- **Module:** ${u.module}`);\n if (u.tags && u.tags.length > 0) lines.push(`- **Tags:** ${u.tags.join(', ')}`);\n lines.push(`- **Created:** ${u.createdAt}`);\n lines.push(`- **Updated:** ${u.updatedAt}`);\n lines.push('');\n\n if (u.description) {\n lines.push('## Description');\n lines.push(u.description);\n lines.push('');\n }\n if (u.nextStep) {\n lines.push(`## Next Step\\n-> ${u.nextStep}\\n`);\n }\n if (u.decision) {\n lines.push(`## Decision\\n✔ ${u.decision}\\n`);\n }\n if (u.blocker) {\n lines.push(`## Blocker\\n✖ ${u.blocker}\\n`);\n }\n if (u.notes) {\n lines.push('## Notes');\n lines.push(u.notes);\n lines.push('');\n }\n return lines.join('\\n');\n}\n\n/**\n * Converts WorkUnits to a clean Markdown string.\n */\nexport function exportToMarkdown(units: WorkUnit | WorkUnit[]): string {\n if (!units) return 'No work units found.\\n';\n\n if (!Array.isArray(units)) {\n return formatSingleMarkdown(units);\n }\n\n if (units.length === 0) {\n return 'No work units found.\\n';\n }\n\n const lines: string[] = [];\n lines.push('# WorkLog Export\\n');\n\n const statuses = ['In Progress', 'Blocked', 'Planned', 'Completed', 'Cancelled'] as const;\n for (const status of statuses) {\n const filtered = units.filter((u) => u.status === status);\n if (filtered.length === 0) continue;\n\n lines.push(`## ${status}`);\n for (const u of filtered) {\n const moduleStr = u.module ? ` [${u.module}]` : '';\n lines.push(`- **#${u.id}**: ${u.title}${moduleStr} (${u.type})`);\n if (u.nextStep) {\n lines.push(` - *Next step:* ${u.nextStep}`);\n }\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import { WorkUnit } from '../models/work-unit.js';\n\nfunction escapeCSV(val: any): string {\n if (val === null || val === undefined) return '';\n const str = String(val);\n if (str.includes(',') || str.includes('\"') || str.includes('\\n') || str.includes('\\r')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n return str;\n}\n\n/**\n * Converts WorkUnits to a standard CSV string.\n */\nexport function exportToCSV(units: WorkUnit | WorkUnit[]): string {\n const list = Array.isArray(units) ? units : [units];\n const headers = [\n 'ID',\n 'Title',\n 'Type',\n 'Status',\n 'Priority',\n 'Module',\n 'Description',\n 'Next Step',\n 'Decision',\n 'Blocker',\n 'Tags',\n 'Related Work Units',\n 'Notes',\n 'Created At',\n 'Updated At',\n ];\n\n const lines: string[] = [headers.join(',')];\n\n for (const u of list) {\n const row = [\n u.id,\n escapeCSV(u.title),\n escapeCSV(u.type),\n escapeCSV(u.status),\n escapeCSV(u.priority),\n escapeCSV(u.module),\n escapeCSV(u.description),\n escapeCSV(u.nextStep),\n escapeCSV(u.decision),\n escapeCSV(u.blocker),\n escapeCSV(u.tags.join(';')),\n escapeCSV(u.relatedWorkUnits.join(';')),\n escapeCSV(u.notes),\n escapeCSV(u.createdAt),\n escapeCSV(u.updatedAt),\n ];\n lines.push(row.join(','));\n }\n\n return lines.join('\\n') + '\\n';\n}\n","import { WorkUnit } from '../models/work-unit.js';\n\n/**\n * Converts WorkUnits to a formatted JSON string.\n */\nexport function exportToJSON(units: WorkUnit | WorkUnit[]): string {\n return JSON.stringify(units, null, 2) + '\\n';\n}\n"],"mappings":"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","names":["pc","path","fs","path","fs","fs","path","fs","path","z","z","pc","pc","pc","pc","pc","prompts","pc","fs","pc","pc","pc"]}
@@ -0,0 +1,38 @@
1
+ import eslint from '@eslint/js';
2
+ import tseslint from 'typescript-eslint';
3
+
4
+ export default tseslint.config(
5
+ eslint.configs.recommended,
6
+ ...tseslint.configs.recommended,
7
+ {
8
+ languageOptions: {
9
+ parserOptions: {
10
+ project: true,
11
+ tsconfigRootDir: import.meta.dirname,
12
+ },
13
+ },
14
+ rules: {
15
+ '@typescript-eslint/no-explicit-any': 'off',
16
+ '@typescript-eslint/no-unused-vars': [
17
+ 'error',
18
+ {
19
+ argsIgnorePattern: '^_',
20
+ varsIgnorePattern: '^_',
21
+ },
22
+ ],
23
+ 'no-console': 'off',
24
+ },
25
+ },
26
+ {
27
+ ignores: [
28
+ 'dist/**',
29
+ 'node_modules/**',
30
+ 'tsup.config.ts',
31
+ 'eslint.config.js',
32
+ 'vitest.config.ts',
33
+ 'src/tests/**',
34
+ 'benchmarks/**',
35
+ 'scripts/**',
36
+ ],
37
+ }
38
+ );
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@vanshbhardwaj/worklog",
3
+ "version": "1.0.0",
4
+ "description": "Engineering Context Manager",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "worklog": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsup",
12
+ "pkg:bin": "node scripts/build-bin.js",
13
+ "benchmark": "vitest run --config benchmarks/vitest.bench.config.ts",
14
+ "test": "vitest run",
15
+ "test:watch": "vitest",
16
+ "lint": "eslint src",
17
+ "format": "prettier --write \"src/**/*.ts\""
18
+ },
19
+ "keywords": [
20
+ "worklog",
21
+ "cli",
22
+ "context-manager"
23
+ ],
24
+ "author": "Vansh Bhardwaj",
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "better-sqlite3": "13.0.1",
28
+ "cli-table3": "0.6.5",
29
+ "commander": "15.0.0",
30
+ "ora": "9.4.1",
31
+ "picocolors": "1.1.1",
32
+ "pino": "10.3.1",
33
+ "prompts": "2.4.2",
34
+ "zod": "4.4.3"
35
+ },
36
+ "devDependencies": {
37
+ "@eslint/js": "^10.0.1",
38
+ "@types/better-sqlite3": "7.6.12",
39
+ "@types/node": "22.10.2",
40
+ "@types/prompts": "2.4.9",
41
+ "eslint": "10.8.0",
42
+ "postject": "1.0.0-alpha.6",
43
+ "prettier": "3.4.2",
44
+ "tsup": "8.3.5",
45
+ "typescript": "5.7.2",
46
+ "typescript-eslint": "8.65.0",
47
+ "vitest": "2.1.8"
48
+ }
49
+ }
@@ -0,0 +1,6 @@
1
+ packages:
2
+ - '.'
3
+
4
+ allowBuilds:
5
+ better-sqlite3: true
6
+ esbuild: true
@@ -0,0 +1,75 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { execSync } from 'child_process';
4
+
5
+ const targetDir = path.resolve('bin');
6
+ const binaryName = path.join(targetDir, process.platform === 'win32' ? 'worklog.exe' : 'worklog');
7
+
8
+ async function main() {
9
+ const isMac = process.platform === 'darwin';
10
+ console.log('Starting Node SEA (Single Executable Application) compilation...');
11
+
12
+ // 1. Clean and prepare output folder
13
+ if (!fs.existsSync(targetDir)) {
14
+ fs.mkdirSync(targetDir, { recursive: true });
15
+ }
16
+ if (fs.existsSync(binaryName)) {
17
+ fs.rmSync(binaryName, { force: true });
18
+ }
19
+
20
+ // 2. Ensure dist script is built
21
+ if (!fs.existsSync(path.resolve('dist/index.cjs'))) {
22
+ console.log('Main bundle not found, compiling first...');
23
+ execSync('pnpm build', { stdio: 'inherit' });
24
+ }
25
+
26
+ // 3. Compile the SEA blob
27
+ console.log('Generating SEA blob...');
28
+ execSync('node --experimental-sea-config sea-config.json', { stdio: 'inherit' });
29
+
30
+ // 4. Copy Node.js executable
31
+ console.log(`Copying active Node.js executable from ${process.execPath}...`);
32
+ fs.copyFileSync(process.execPath, binaryName);
33
+
34
+ // 4.5 Remove existing signature on macOS to allow injection
35
+ if (isMac) {
36
+ console.log('Removing existing codesign signature from Node binary copy...');
37
+ try {
38
+ execSync(`codesign --remove-signature "${binaryName}"`, { stdio: 'inherit' });
39
+ } catch (e) {
40
+ console.warn('Warning: codesign --remove-signature failed:', e.message);
41
+ }
42
+ }
43
+
44
+ // 5. Inject SEA blob into executable copy
45
+ console.log('Injecting blob using postject...');
46
+
47
+ // Read binary to detect correct sentinel fuse string dynamically
48
+ const binaryBuffer = fs.readFileSync(binaryName);
49
+ let sentinelFuse = 'NODE_SEA_FUSE_f140de4428b4ffc1293c654d2f6d83d0';
50
+ if (binaryBuffer.includes(Buffer.from('NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2'))) {
51
+ sentinelFuse = 'NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2';
52
+ }
53
+ console.log(`Detected sentinel fuse pattern: ${sentinelFuse}`);
54
+
55
+ const machoFlag = isMac ? '--macho-segment-name NODE_SEA' : '';
56
+ const postjectCmd = `npx postject "${binaryName}" NODE_SEA_BLOB dist/sea-prep.blob --sentinel-fuse ${sentinelFuse} ${machoFlag}`;
57
+ execSync(postjectCmd, { stdio: 'inherit' });
58
+
59
+ // 6. Resign on macOS (critical for Apple Silicon validation)
60
+ if (isMac) {
61
+ console.log('Signing binary for macOS platform compatibility...');
62
+ try {
63
+ execSync(`codesign --sign - --force "${binaryName}"`, { stdio: 'inherit' });
64
+ } catch (e) {
65
+ console.warn('Warning: macOS codesign failed. Binary might require manual signature authorization.');
66
+ }
67
+ }
68
+
69
+ console.log(`Successfully built native binary: ${binaryName}`);
70
+ }
71
+
72
+ main().catch((err) => {
73
+ console.error('Binary build failed:', err);
74
+ process.exit(1);
75
+ });
@@ -0,0 +1,5 @@
1
+ {
2
+ "main": "dist/index.cjs",
3
+ "output": "dist/sea-prep.blob",
4
+ "disableSentinel": false
5
+ }