@compilr-dev/cli 0.4.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 (152) hide show
  1. package/README.md +110 -0
  2. package/dist/agent.d.ts +62 -0
  3. package/dist/agent.js +317 -0
  4. package/dist/agents/registry.d.ts +66 -0
  5. package/dist/agents/registry.js +238 -0
  6. package/dist/agents/types.d.ts +40 -0
  7. package/dist/agents/types.js +94 -0
  8. package/dist/commands/custom-registry.d.ts +69 -0
  9. package/dist/commands/custom-registry.js +246 -0
  10. package/dist/commands/index.d.ts +7 -0
  11. package/dist/commands/index.js +7 -0
  12. package/dist/commands/types.d.ts +31 -0
  13. package/dist/commands/types.js +26 -0
  14. package/dist/commands.d.ts +63 -0
  15. package/dist/commands.js +324 -0
  16. package/dist/db/index.d.ts +42 -0
  17. package/dist/db/index.js +146 -0
  18. package/dist/db/repositories/document-repository.d.ts +63 -0
  19. package/dist/db/repositories/document-repository.js +184 -0
  20. package/dist/db/repositories/index.d.ts +9 -0
  21. package/dist/db/repositories/index.js +6 -0
  22. package/dist/db/repositories/project-repository.d.ts +132 -0
  23. package/dist/db/repositories/project-repository.js +337 -0
  24. package/dist/db/repositories/work-item-repository.d.ts +115 -0
  25. package/dist/db/repositories/work-item-repository.js +389 -0
  26. package/dist/db/schema.d.ts +83 -0
  27. package/dist/db/schema.js +143 -0
  28. package/dist/debug.d.ts +8 -0
  29. package/dist/debug.js +48 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.js +348 -0
  32. package/dist/index.old.d.ts +7 -0
  33. package/dist/index.old.js +1014 -0
  34. package/dist/repl.d.ts +121 -0
  35. package/dist/repl.js +1878 -0
  36. package/dist/settings/index.d.ts +80 -0
  37. package/dist/settings/index.js +195 -0
  38. package/dist/shared-handlers.d.ts +63 -0
  39. package/dist/shared-handlers.js +57 -0
  40. package/dist/slash-autocomplete.d.ts +41 -0
  41. package/dist/slash-autocomplete.js +638 -0
  42. package/dist/state.d.ts +75 -0
  43. package/dist/state.js +130 -0
  44. package/dist/tabbed-menu.d.ts +11 -0
  45. package/dist/tabbed-menu.js +328 -0
  46. package/dist/templates/backlog-md.d.ts +7 -0
  47. package/dist/templates/backlog-md.js +94 -0
  48. package/dist/templates/claude-md.d.ts +7 -0
  49. package/dist/templates/claude-md.js +189 -0
  50. package/dist/templates/coding-standards.d.ts +7 -0
  51. package/dist/templates/coding-standards.js +299 -0
  52. package/dist/templates/compilr-md.d.ts +7 -0
  53. package/dist/templates/compilr-md.js +189 -0
  54. package/dist/templates/config-json.d.ts +38 -0
  55. package/dist/templates/config-json.js +39 -0
  56. package/dist/templates/gitignore.d.ts +7 -0
  57. package/dist/templates/gitignore.js +85 -0
  58. package/dist/templates/index.d.ts +19 -0
  59. package/dist/templates/index.js +302 -0
  60. package/dist/templates/package-json.d.ts +7 -0
  61. package/dist/templates/package-json.js +111 -0
  62. package/dist/templates/readme-md.d.ts +7 -0
  63. package/dist/templates/readme-md.js +161 -0
  64. package/dist/templates/tsconfig.d.ts +7 -0
  65. package/dist/templates/tsconfig.js +61 -0
  66. package/dist/templates/types.d.ts +33 -0
  67. package/dist/templates/types.js +24 -0
  68. package/dist/test-autocomplete.d.ts +7 -0
  69. package/dist/test-autocomplete.js +85 -0
  70. package/dist/test-tabbed-menu.d.ts +7 -0
  71. package/dist/test-tabbed-menu.js +25 -0
  72. package/dist/themes/colors.d.ts +49 -0
  73. package/dist/themes/colors.js +135 -0
  74. package/dist/themes/index.d.ts +23 -0
  75. package/dist/themes/index.js +24 -0
  76. package/dist/themes/registry.d.ts +60 -0
  77. package/dist/themes/registry.js +195 -0
  78. package/dist/themes/types.d.ts +82 -0
  79. package/dist/themes/types.js +7 -0
  80. package/dist/tool-selector.d.ts +71 -0
  81. package/dist/tool-selector.js +184 -0
  82. package/dist/tools/ask-user-simple.d.ts +19 -0
  83. package/dist/tools/ask-user-simple.js +86 -0
  84. package/dist/tools/ask-user.d.ts +32 -0
  85. package/dist/tools/ask-user.js +113 -0
  86. package/dist/tools/backlog.d.ts +53 -0
  87. package/dist/tools/backlog.js +709 -0
  88. package/dist/tools.d.ts +15 -0
  89. package/dist/tools.js +121 -0
  90. package/dist/ui/agents-overlay.d.ts +12 -0
  91. package/dist/ui/agents-overlay.js +501 -0
  92. package/dist/ui/arch-type-overlay.d.ts +20 -0
  93. package/dist/ui/arch-type-overlay.js +229 -0
  94. package/dist/ui/ask-user-overlay.d.ts +26 -0
  95. package/dist/ui/ask-user-overlay.js +647 -0
  96. package/dist/ui/ask-user-simple-overlay.d.ts +25 -0
  97. package/dist/ui/ask-user-simple-overlay.js +242 -0
  98. package/dist/ui/backlog-overlay.d.ts +17 -0
  99. package/dist/ui/backlog-overlay.js +786 -0
  100. package/dist/ui/commands-overlay.d.ts +11 -0
  101. package/dist/ui/commands-overlay.js +410 -0
  102. package/dist/ui/config-overlay.d.ts +34 -0
  103. package/dist/ui/config-overlay.js +977 -0
  104. package/dist/ui/conversation.d.ts +82 -0
  105. package/dist/ui/conversation.js +508 -0
  106. package/dist/ui/diff.d.ts +38 -0
  107. package/dist/ui/diff.js +182 -0
  108. package/dist/ui/ephemeral.d.ts +111 -0
  109. package/dist/ui/ephemeral.js +413 -0
  110. package/dist/ui/file-autocomplete.d.ts +45 -0
  111. package/dist/ui/file-autocomplete.js +237 -0
  112. package/dist/ui/footer.d.ts +153 -0
  113. package/dist/ui/footer.js +422 -0
  114. package/dist/ui/index.d.ts +12 -0
  115. package/dist/ui/index.js +15 -0
  116. package/dist/ui/init-overlay.d.ts +24 -0
  117. package/dist/ui/init-overlay.js +525 -0
  118. package/dist/ui/input-prompt-v2.d.ts +179 -0
  119. package/dist/ui/input-prompt-v2.js +991 -0
  120. package/dist/ui/input-prompt.d.ts +97 -0
  121. package/dist/ui/input-prompt.js +800 -0
  122. package/dist/ui/iteration-limit-overlay.d.ts +21 -0
  123. package/dist/ui/iteration-limit-overlay.js +150 -0
  124. package/dist/ui/keys-overlay.d.ts +14 -0
  125. package/dist/ui/keys-overlay.js +181 -0
  126. package/dist/ui/model-warning-overlay.d.ts +30 -0
  127. package/dist/ui/model-warning-overlay.js +171 -0
  128. package/dist/ui/overlay-controller.d.ts +25 -0
  129. package/dist/ui/overlay-controller.js +35 -0
  130. package/dist/ui/overlays.d.ts +47 -0
  131. package/dist/ui/overlays.js +627 -0
  132. package/dist/ui/permission-overlay.d.ts +16 -0
  133. package/dist/ui/permission-overlay.js +494 -0
  134. package/dist/ui/terminal.d.ts +117 -0
  135. package/dist/ui/terminal.js +237 -0
  136. package/dist/ui/todo-zone.d.ts +112 -0
  137. package/dist/ui/todo-zone.js +353 -0
  138. package/dist/ui/tools-overlay.d.ts +26 -0
  139. package/dist/ui/tools-overlay.js +278 -0
  140. package/dist/ui/tutorial-overlay.d.ts +10 -0
  141. package/dist/ui/tutorial-overlay.js +936 -0
  142. package/dist/ui/types.d.ts +103 -0
  143. package/dist/ui/types.js +33 -0
  144. package/dist/utils/credentials.d.ts +55 -0
  145. package/dist/utils/credentials.js +268 -0
  146. package/dist/utils/model-tiers.d.ts +37 -0
  147. package/dist/utils/model-tiers.js +118 -0
  148. package/dist/utils/project-memory.d.ts +47 -0
  149. package/dist/utils/project-memory.js +117 -0
  150. package/dist/utils/project-status.d.ts +56 -0
  151. package/dist/utils/project-status.js +237 -0
  152. package/package.json +66 -0
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Custom Command Types
3
+ *
4
+ * Type definitions for custom slash commands.
5
+ */
6
+ /** Project-level commands directory */
7
+ export declare const PROJECT_COMMANDS_DIR = ".compilr-dev/commands";
8
+ /** User-level commands directory */
9
+ export declare const USER_COMMANDS_DIR: string;
10
+ /** Where the command is defined */
11
+ export type CommandLocation = 'project' | 'personal';
12
+ /** Custom command definition */
13
+ export interface CustomCommand {
14
+ /** Command name (from filename, e.g., "review") */
15
+ name: string;
16
+ /** Short description (from frontmatter) */
17
+ description: string;
18
+ /** The prompt template content */
19
+ prompt: string;
20
+ /** Where this command is defined */
21
+ location: CommandLocation;
22
+ /** Full path to the .md file */
23
+ filePath: string;
24
+ }
25
+ /**
26
+ * Validate command name format
27
+ * - Lowercase letters, numbers, hyphens only
28
+ * - Must start with a letter
29
+ * - 2-30 characters
30
+ */
31
+ export declare function isValidCommandName(name: string): boolean;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Custom Command Types
3
+ *
4
+ * Type definitions for custom slash commands.
5
+ */
6
+ import * as path from 'path';
7
+ import * as os from 'os';
8
+ // =============================================================================
9
+ // Directory Constants
10
+ // =============================================================================
11
+ /** Project-level commands directory */
12
+ export const PROJECT_COMMANDS_DIR = '.compilr-dev/commands';
13
+ /** User-level commands directory */
14
+ export const USER_COMMANDS_DIR = path.join(os.homedir(), '.compilr-dev', 'commands');
15
+ // =============================================================================
16
+ // Validation
17
+ // =============================================================================
18
+ /**
19
+ * Validate command name format
20
+ * - Lowercase letters, numbers, hyphens only
21
+ * - Must start with a letter
22
+ * - 2-30 characters
23
+ */
24
+ export function isValidCommandName(name) {
25
+ return /^[a-z][a-z0-9-]{1,29}$/.test(name);
26
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Slash Commands Registry
3
+ *
4
+ * Single source of truth for all slash commands.
5
+ * Used by: help menu, autocomplete dropdown, and command handler.
6
+ */
7
+ /**
8
+ * Example with optional description
9
+ */
10
+ export interface CommandExample {
11
+ /** The command to run (e.g., '/backlog') */
12
+ code: string;
13
+ /** What this example demonstrates */
14
+ description?: string;
15
+ }
16
+ export interface SlashCommand {
17
+ /** Command name without slash (e.g., 'help') */
18
+ name: string;
19
+ /** Short description for help/autocomplete */
20
+ description: string;
21
+ /** Alternative names (e.g., 'q' for 'exit') */
22
+ aliases?: string[];
23
+ /** Detailed explanation of what the command does */
24
+ details?: string;
25
+ /** Usage examples with optional descriptions */
26
+ examples?: CommandExample[];
27
+ /** UI interaction hints (keyboard shortcuts, navigation) */
28
+ interactions?: string[];
29
+ }
30
+ export declare const COMMANDS: SlashCommand[];
31
+ /**
32
+ * Get commands formatted for autocomplete dropdown
33
+ * Includes both built-in and custom commands
34
+ */
35
+ export declare function getAutocompleteCommands(): {
36
+ command: string;
37
+ description: string;
38
+ }[];
39
+ /**
40
+ * Get commands formatted for help menu
41
+ */
42
+ export declare function getHelpCommands(): {
43
+ name: string;
44
+ description: string;
45
+ }[];
46
+ /**
47
+ * Resolve command name (handles aliases)
48
+ * Returns the canonical command name or null if not found
49
+ */
50
+ export declare function resolveCommand(input: string): string | null;
51
+ /**
52
+ * Check if a command exists
53
+ */
54
+ export declare function isValidCommand(input: string): boolean;
55
+ /**
56
+ * Check if a command is a custom command (starts with the input but isn't a built-in)
57
+ * This is used to allow custom command names that aren't in the registry
58
+ */
59
+ export declare function isCustomCommand(_input: string): boolean;
60
+ /**
61
+ * Get full command details by index (for help overlay man page)
62
+ */
63
+ export declare function getCommandByIndex(index: number): SlashCommand | null;
@@ -0,0 +1,324 @@
1
+ /**
2
+ * Slash Commands Registry
3
+ *
4
+ * Single source of truth for all slash commands.
5
+ * Used by: help menu, autocomplete dropdown, and command handler.
6
+ */
7
+ import { getCustomCommandRegistry } from './commands/index.js';
8
+ // =============================================================================
9
+ // Command Registry
10
+ // =============================================================================
11
+ export const COMMANDS = [
12
+ {
13
+ name: 'agents',
14
+ description: 'Manage sub-agent configurations',
15
+ details: 'View and configure sub-agents that can be spawned for specialized tasks like code review, testing, or exploration.',
16
+ examples: [{ code: '/agents' }],
17
+ interactions: [
18
+ 'Tab to switch: built-in ↔ custom',
19
+ '↑/↓ to navigate agents',
20
+ 'Enter to select or create new',
21
+ 'Esc to close',
22
+ ],
23
+ },
24
+ {
25
+ name: 'arch',
26
+ description: 'Create architecture documentation (ADRs, diagrams, etc.)',
27
+ details: 'Guides you through creating architecture documentation. Choose from ADRs (Architecture Decision Records), system diagrams, data models, or API designs. The agent asks questions and generates properly formatted documentation.',
28
+ examples: [
29
+ { code: '/arch', description: 'Interactive type selection' },
30
+ { code: '/arch decision', description: 'Create ADR directly' },
31
+ { code: '/arch diagram', description: 'Create system diagram' },
32
+ ],
33
+ interactions: [
34
+ '↑/↓ or 1-5 to select type',
35
+ 'Enter to confirm',
36
+ 'Esc to cancel',
37
+ ],
38
+ },
39
+ {
40
+ name: 'backlog',
41
+ description: 'View and manage project backlog',
42
+ details: 'Opens an interactive overlay to browse, filter, and manage backlog items. You can add new items, change status/priority, search, and view details.',
43
+ examples: [{ code: '/backlog' }],
44
+ interactions: [
45
+ 'Tab cycles: All → Feature → Bug → Tech-Debt → Chore → Active',
46
+ '↑/↓ to navigate, ←/→ for pages',
47
+ 'Enter for details, Space to toggle status',
48
+ '/ to search, n for new item',
49
+ 'Esc to close',
50
+ ],
51
+ },
52
+ {
53
+ name: 'build',
54
+ description: 'Implement a backlog item',
55
+ details: 'Picks the highest priority backlog item (or a specific one) and guides the agent through implementing it. Includes planning, coding, testing, and committing. Auto-detects if project scaffold is needed first.',
56
+ examples: [
57
+ { code: '/build', description: 'Pick highest priority item' },
58
+ { code: '/build REQ-003', description: 'Build specific item' },
59
+ { code: '/build scaffold', description: 'Create project structure first' },
60
+ ],
61
+ },
62
+ {
63
+ name: 'clear',
64
+ description: 'Clear the screen',
65
+ details: 'Clears the terminal screen. Does not affect conversation history or context.',
66
+ examples: [{ code: '/clear' }],
67
+ },
68
+ {
69
+ name: 'commands',
70
+ description: 'Manage custom commands',
71
+ details: 'Create, edit, or delete custom slash commands. Custom commands are markdown files that expand into prompts when invoked.',
72
+ examples: [{ code: '/commands' }],
73
+ interactions: [
74
+ '↑/↓ to navigate commands',
75
+ 'Enter to select or create new',
76
+ 'Esc to close',
77
+ ],
78
+ },
79
+ {
80
+ name: 'compact',
81
+ description: 'Summarize old messages to free context',
82
+ details: 'When context is running low, use this to summarize older messages. The agent creates a summary and removes old messages to free up token space.',
83
+ examples: [{ code: '/compact' }],
84
+ },
85
+ {
86
+ name: 'config',
87
+ description: 'Open settings panel',
88
+ details: 'Opens the configuration overlay where you can change model, theme, permissions, and other settings.',
89
+ examples: [{ code: '/config' }],
90
+ interactions: [
91
+ 'Tab cycles: Status → Config → Usage',
92
+ '↑/↓ to navigate in Config tab',
93
+ 'Enter/Space to toggle or open submenu',
94
+ 'Esc to exit',
95
+ ],
96
+ },
97
+ {
98
+ name: 'context',
99
+ description: 'Show context window usage',
100
+ details: 'Displays current context window utilization including token count, percentage used, and number of messages.',
101
+ examples: [{ code: '/context' }],
102
+ },
103
+ {
104
+ name: 'design',
105
+ description: 'Design your project and populate the backlog',
106
+ details: 'Comprehensive requirements gathering workflow. The agent guides you through vision, features, and technical context phases, then creates a PRD and populates the backlog with 5-15 items. Best used after /init.',
107
+ examples: [{ code: '/design' }],
108
+ },
109
+ {
110
+ name: 'exit',
111
+ description: 'Exit the REPL',
112
+ aliases: ['quit', 'q'],
113
+ details: 'Exits the CLI. Your conversation is not saved unless you export it first.',
114
+ examples: [
115
+ { code: '/exit' },
116
+ { code: '/quit', description: 'Alias' },
117
+ { code: '/q', description: 'Short alias' },
118
+ ],
119
+ },
120
+ {
121
+ name: 'export',
122
+ description: 'Export conversation to file or clipboard',
123
+ details: 'Export the current conversation to a file or clipboard for later reference.',
124
+ examples: [{ code: '/export' }],
125
+ },
126
+ {
127
+ name: 'help',
128
+ description: 'Show this help menu',
129
+ aliases: ['?'],
130
+ details: 'Opens the help overlay with tabs for general info, commands list, and custom commands.',
131
+ examples: [
132
+ { code: '/help' },
133
+ { code: '/?', description: 'Short alias' },
134
+ ],
135
+ interactions: [
136
+ 'Tab cycles: general → commands → custom-commands',
137
+ '↑/↓ to navigate command list',
138
+ 'Enter to view command details',
139
+ 'Esc to go back or close',
140
+ ],
141
+ },
142
+ {
143
+ name: 'keys',
144
+ description: 'Manage API keys for LLM providers',
145
+ details: 'Opens an interactive overlay to view, set, and delete API keys for LLM providers (Anthropic, OpenAI, Google). Keys are encrypted and stored locally in ~/.compilr-dev/credentials.enc.',
146
+ examples: [{ code: '/keys' }],
147
+ interactions: [
148
+ '↑/↓ to navigate providers',
149
+ 'Enter to edit key',
150
+ 'd to delete stored key',
151
+ 'Esc to close',
152
+ ],
153
+ },
154
+ {
155
+ name: 'init',
156
+ description: 'Initialize a new project with structured workflow',
157
+ details: 'Interactive wizard to scaffold a new project. Asks about project name, type, tech stack, and documentation preferences. Creates project structure with COMPILR.md, backlog, and optional separate docs repo.',
158
+ examples: [{ code: '/init' }],
159
+ interactions: [
160
+ '8-step wizard (0-7)',
161
+ '↑/↓ for selection steps, type for input steps',
162
+ 'Enter to confirm, Esc to go back',
163
+ ],
164
+ },
165
+ {
166
+ name: 'model',
167
+ description: 'Show the current model',
168
+ details: 'Displays the currently active LLM model (e.g., claude-3-5-sonnet, gpt-4o).',
169
+ examples: [{ code: '/model' }],
170
+ },
171
+ {
172
+ name: 'note',
173
+ description: 'Create a session note capturing work done',
174
+ details: 'Creates a structured markdown note summarizing the current session including changes made, decisions, blockers, and next steps. Optionally provide a title.',
175
+ examples: [
176
+ { code: '/note', description: 'Auto-generated title' },
177
+ { code: '/note "Fixed auth bug"', description: 'Custom title' },
178
+ ],
179
+ },
180
+ {
181
+ name: 'plan',
182
+ description: 'Switch to Plan mode',
183
+ details: 'Enters plan mode where the agent focuses on planning and design rather than implementation. Useful for complex tasks that need thinking through first.',
184
+ examples: [{ code: '/plan' }],
185
+ },
186
+ {
187
+ name: 'prd',
188
+ description: 'Amend or enhance the Product Requirements Document',
189
+ details: 'Update or refine the PRD created during /design. The agent reads the existing PRD and guides you through updating specific sections.',
190
+ examples: [
191
+ { code: '/prd', description: 'Interactive section selection' },
192
+ { code: '/prd vision', description: 'Update vision section' },
193
+ { code: '/prd scope', description: 'Update scope section' },
194
+ ],
195
+ },
196
+ {
197
+ name: 'refine',
198
+ description: 'Refine and expand existing requirements',
199
+ details: 'Iteratively refine backlog items. Can focus on a specific item or let the agent suggest what to refine. Useful for breaking down large items or adding acceptance criteria.',
200
+ examples: [
201
+ { code: '/refine', description: 'Agent picks item to refine' },
202
+ { code: '/refine REQ-003', description: 'Refine specific item' },
203
+ ],
204
+ },
205
+ {
206
+ name: 'scaffold',
207
+ description: 'Create project foundation/structure',
208
+ details: 'Creates the base project structure (folders, config files, dependencies) based on tech stack from COMPILR.md. Use this before implementing features if starting from scratch. Alias for /build scaffold.',
209
+ examples: [{ code: '/scaffold' }],
210
+ },
211
+ {
212
+ name: 'sketch',
213
+ description: 'Quick project outline with simple questions',
214
+ details: 'Lightweight alternative to /design. Asks 6 quick questions and creates 3-8 backlog items. Good for small projects or when you want to get started quickly.',
215
+ examples: [{ code: '/sketch' }],
216
+ },
217
+ {
218
+ name: 'status',
219
+ description: 'Show version, model, mode, and context',
220
+ details: 'Displays current session status including CLI version, active model, mode, and context usage.',
221
+ examples: [{ code: '/status' }],
222
+ },
223
+ {
224
+ name: 'todos',
225
+ description: 'List current todo items',
226
+ details: 'Shows the current todo list that the agent uses to track work in progress.',
227
+ examples: [{ code: '/todos' }],
228
+ },
229
+ {
230
+ name: 'tokens',
231
+ description: 'Show session token usage',
232
+ details: 'Displays token usage statistics for the current session including input/output tokens and estimated cost.',
233
+ examples: [{ code: '/tokens' }],
234
+ },
235
+ {
236
+ name: 'tools',
237
+ description: 'List available tools',
238
+ details: 'Shows all tools available to the agent including file operations, bash, git, and custom tools.',
239
+ examples: [{ code: '/tools' }],
240
+ },
241
+ {
242
+ name: 'tutorial',
243
+ description: 'Interactive tutorial for the workflow',
244
+ details: 'Opens an interactive tutorial that guides you through the compilr.dev workflow. Choose a guided tour to learn everything step-by-step, or jump directly to specific topics like /init, /design, or /build.',
245
+ examples: [{ code: '/tutorial' }],
246
+ interactions: [
247
+ '↑/↓ to navigate options and topics',
248
+ '←/→ or Enter to navigate pages',
249
+ 'Esc to go back or exit',
250
+ ],
251
+ },
252
+ ];
253
+ // =============================================================================
254
+ // Helper Functions
255
+ // =============================================================================
256
+ /**
257
+ * Get commands formatted for autocomplete dropdown
258
+ * Includes both built-in and custom commands
259
+ */
260
+ export function getAutocompleteCommands() {
261
+ // Built-in commands
262
+ const builtIn = COMMANDS.map((cmd) => ({
263
+ command: `/${cmd.name}`,
264
+ description: cmd.description,
265
+ }));
266
+ // Custom commands
267
+ const customRegistry = getCustomCommandRegistry();
268
+ const custom = customRegistry.getAll().map((cmd) => ({
269
+ command: `/${cmd.name}`,
270
+ description: cmd.description,
271
+ }));
272
+ // Merge: built-in first, then custom
273
+ return [...builtIn, ...custom];
274
+ }
275
+ /**
276
+ * Get commands formatted for help menu
277
+ */
278
+ export function getHelpCommands() {
279
+ return COMMANDS.map((cmd) => {
280
+ const aliases = cmd.aliases?.length ? ` (also /${cmd.aliases.join(', /')})` : '';
281
+ return {
282
+ name: `/${cmd.name}`,
283
+ description: `${cmd.description}${aliases}`,
284
+ };
285
+ });
286
+ }
287
+ /**
288
+ * Resolve command name (handles aliases)
289
+ * Returns the canonical command name or null if not found
290
+ */
291
+ export function resolveCommand(input) {
292
+ const lower = input.toLowerCase();
293
+ for (const cmd of COMMANDS) {
294
+ if (cmd.name === lower)
295
+ return cmd.name;
296
+ if (cmd.aliases?.includes(lower))
297
+ return cmd.name;
298
+ }
299
+ return null;
300
+ }
301
+ /**
302
+ * Check if a command exists
303
+ */
304
+ export function isValidCommand(input) {
305
+ return resolveCommand(input) !== null;
306
+ }
307
+ /**
308
+ * Check if a command is a custom command (starts with the input but isn't a built-in)
309
+ * This is used to allow custom command names that aren't in the registry
310
+ */
311
+ export function isCustomCommand(_input) {
312
+ // Custom commands use the same format but aren't in the built-in list
313
+ // The custom command registry handles this separately
314
+ return false; // Placeholder - actual check happens in REPL
315
+ }
316
+ /**
317
+ * Get full command details by index (for help overlay man page)
318
+ */
319
+ export function getCommandByIndex(index) {
320
+ if (index < 0 || index >= COMMANDS.length) {
321
+ return null;
322
+ }
323
+ return COMMANDS[index];
324
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Database module for compilr-cli
3
+ *
4
+ * Provides SQLite database connection and initialization.
5
+ * Database location: ~/.compilr-dev/projects.db
6
+ */
7
+ import Database from 'better-sqlite3';
8
+ export * from './schema.js';
9
+ /**
10
+ * Get the database directory path
11
+ */
12
+ export declare function getDbDir(): string;
13
+ /**
14
+ * Get the database file path
15
+ */
16
+ export declare function getDbPath(): string;
17
+ /**
18
+ * Get or create the database connection
19
+ */
20
+ export declare function getDb(): Database.Database;
21
+ /**
22
+ * Close the database connection
23
+ */
24
+ export declare function closeDb(): void;
25
+ /**
26
+ * Check if the database exists
27
+ */
28
+ export declare function dbExists(): boolean;
29
+ /**
30
+ * Get database stats for debugging
31
+ */
32
+ export declare function getDbStats(): {
33
+ exists: boolean;
34
+ path: string;
35
+ size: number | null;
36
+ projectCount: number;
37
+ workItemCount: number;
38
+ };
39
+ /**
40
+ * Transaction helper for running multiple operations atomically
41
+ */
42
+ export declare function transaction<T>(fn: (db: Database.Database) => T): T;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Database module for compilr-cli
3
+ *
4
+ * Provides SQLite database connection and initialization.
5
+ * Database location: ~/.compilr-dev/projects.db
6
+ */
7
+ import Database from 'better-sqlite3';
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import * as os from 'os';
11
+ import { SCHEMA_SQL, SCHEMA_VERSION } from './schema.js';
12
+ // Re-export types
13
+ export * from './schema.js';
14
+ // Database instance (singleton)
15
+ let dbInstance = null;
16
+ /**
17
+ * Get the database directory path
18
+ */
19
+ export function getDbDir() {
20
+ return path.join(os.homedir(), '.compilr-dev');
21
+ }
22
+ /**
23
+ * Get the database file path
24
+ */
25
+ export function getDbPath() {
26
+ return path.join(getDbDir(), 'projects.db');
27
+ }
28
+ /**
29
+ * Initialize the database directory if it doesn't exist
30
+ */
31
+ function ensureDbDir() {
32
+ const dbDir = getDbDir();
33
+ if (!fs.existsSync(dbDir)) {
34
+ fs.mkdirSync(dbDir, { recursive: true });
35
+ }
36
+ }
37
+ /**
38
+ * Get or create the database connection
39
+ */
40
+ export function getDb() {
41
+ if (dbInstance) {
42
+ return dbInstance;
43
+ }
44
+ ensureDbDir();
45
+ const dbPath = getDbPath();
46
+ // Create/open database
47
+ dbInstance = new Database(dbPath);
48
+ // Enable foreign keys
49
+ dbInstance.pragma('foreign_keys = ON');
50
+ // Enable WAL mode for better concurrency
51
+ dbInstance.pragma('journal_mode = WAL');
52
+ // Initialize schema if needed
53
+ initializeSchema(dbInstance);
54
+ return dbInstance;
55
+ }
56
+ /**
57
+ * Initialize the database schema
58
+ */
59
+ function initializeSchema(db) {
60
+ // Check if schema_version table exists
61
+ const tableExists = db
62
+ .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='schema_version'`)
63
+ .get();
64
+ if (!tableExists) {
65
+ // Fresh database - create all tables
66
+ db.exec(SCHEMA_SQL);
67
+ // Record schema version
68
+ db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(SCHEMA_VERSION);
69
+ return;
70
+ }
71
+ // Check current schema version
72
+ const currentVersion = db
73
+ .prepare('SELECT MAX(version) as version FROM schema_version')
74
+ .get();
75
+ if (!currentVersion || currentVersion.version < SCHEMA_VERSION) {
76
+ // Run migrations (for future use)
77
+ runMigrations(db, currentVersion?.version ?? 0, SCHEMA_VERSION);
78
+ }
79
+ }
80
+ /**
81
+ * Run database migrations from one version to another
82
+ */
83
+ function runMigrations(db, fromVersion, toVersion) {
84
+ // Future migrations go here
85
+ // For now, just update the version
86
+ if (fromVersion < toVersion) {
87
+ db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(toVersion);
88
+ }
89
+ }
90
+ /**
91
+ * Close the database connection
92
+ */
93
+ export function closeDb() {
94
+ if (dbInstance) {
95
+ dbInstance.close();
96
+ dbInstance = null;
97
+ }
98
+ }
99
+ /**
100
+ * Check if the database exists
101
+ */
102
+ export function dbExists() {
103
+ return fs.existsSync(getDbPath());
104
+ }
105
+ /**
106
+ * Get database stats for debugging
107
+ */
108
+ export function getDbStats() {
109
+ const dbPath = getDbPath();
110
+ const exists = fs.existsSync(dbPath);
111
+ let size = null;
112
+ let projectCount = 0;
113
+ let workItemCount = 0;
114
+ if (exists) {
115
+ try {
116
+ const stats = fs.statSync(dbPath);
117
+ size = stats.size;
118
+ const db = getDb();
119
+ const projectResult = db
120
+ .prepare('SELECT COUNT(*) as count FROM projects')
121
+ .get();
122
+ const workItemResult = db
123
+ .prepare('SELECT COUNT(*) as count FROM work_items')
124
+ .get();
125
+ projectCount = projectResult.count;
126
+ workItemCount = workItemResult.count;
127
+ }
128
+ catch {
129
+ // Ignore errors, return defaults
130
+ }
131
+ }
132
+ return {
133
+ exists,
134
+ path: dbPath,
135
+ size,
136
+ projectCount,
137
+ workItemCount,
138
+ };
139
+ }
140
+ /**
141
+ * Transaction helper for running multiple operations atomically
142
+ */
143
+ export function transaction(fn) {
144
+ const db = getDb();
145
+ return db.transaction(() => fn(db))();
146
+ }