specsmd 0.0.1

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 (83) hide show
  1. package/README.md +300 -0
  2. package/bin/cli.js +21 -0
  3. package/flows/aidlc/README.md +372 -0
  4. package/flows/aidlc/agents/construction-agent.md +81 -0
  5. package/flows/aidlc/agents/inception-agent.md +95 -0
  6. package/flows/aidlc/agents/master-agent.md +61 -0
  7. package/flows/aidlc/agents/operations-agent.md +89 -0
  8. package/flows/aidlc/commands/construction-agent.md +63 -0
  9. package/flows/aidlc/commands/inception-agent.md +55 -0
  10. package/flows/aidlc/commands/master-agent.md +47 -0
  11. package/flows/aidlc/commands/operations-agent.md +77 -0
  12. package/flows/aidlc/context-config.yaml +41 -0
  13. package/flows/aidlc/memory-bank.yaml +104 -0
  14. package/flows/aidlc/quick-start.md +315 -0
  15. package/flows/aidlc/skills/construction/bolt-list.md +163 -0
  16. package/flows/aidlc/skills/construction/bolt-replan.md +343 -0
  17. package/flows/aidlc/skills/construction/bolt-start.md +289 -0
  18. package/flows/aidlc/skills/construction/bolt-status.md +185 -0
  19. package/flows/aidlc/skills/construction/navigator.md +196 -0
  20. package/flows/aidlc/skills/inception/bolt-plan.md +338 -0
  21. package/flows/aidlc/skills/inception/context.md +171 -0
  22. package/flows/aidlc/skills/inception/intent-create.md +211 -0
  23. package/flows/aidlc/skills/inception/intent-list.md +124 -0
  24. package/flows/aidlc/skills/inception/navigator.md +207 -0
  25. package/flows/aidlc/skills/inception/requirements.md +227 -0
  26. package/flows/aidlc/skills/inception/review.md +248 -0
  27. package/flows/aidlc/skills/inception/story-create.md +304 -0
  28. package/flows/aidlc/skills/inception/units.md +271 -0
  29. package/flows/aidlc/skills/master/analyze-context.md +132 -0
  30. package/flows/aidlc/skills/master/answer-question.md +141 -0
  31. package/flows/aidlc/skills/master/explain-flow.md +146 -0
  32. package/flows/aidlc/skills/master/project-init.md +281 -0
  33. package/flows/aidlc/skills/master/route-request.md +126 -0
  34. package/flows/aidlc/skills/operations/build.md +237 -0
  35. package/flows/aidlc/skills/operations/deploy.md +259 -0
  36. package/flows/aidlc/skills/operations/monitor.md +265 -0
  37. package/flows/aidlc/skills/operations/navigator.md +209 -0
  38. package/flows/aidlc/skills/operations/verify.md +224 -0
  39. package/flows/aidlc/templates/construction/bolt-template.md +193 -0
  40. package/flows/aidlc/templates/construction/bolt-types/bdd-construction-bolt.md +250 -0
  41. package/flows/aidlc/templates/construction/bolt-types/ddd-construction-bolt/adr-template.md +49 -0
  42. package/flows/aidlc/templates/construction/bolt-types/ddd-construction-bolt/ddd-01-domain-model-template.md +55 -0
  43. package/flows/aidlc/templates/construction/bolt-types/ddd-construction-bolt/ddd-02-technical-design-template.md +67 -0
  44. package/flows/aidlc/templates/construction/bolt-types/ddd-construction-bolt/ddd-03-test-report-template.md +62 -0
  45. package/flows/aidlc/templates/construction/bolt-types/ddd-construction-bolt.md +528 -0
  46. package/flows/aidlc/templates/construction/bolt-types/simple-construction-bolt.md +273 -0
  47. package/flows/aidlc/templates/construction/bolt-types/spike-bolt.md +240 -0
  48. package/flows/aidlc/templates/construction/bolt-types/tdd-construction-bolt.md +259 -0
  49. package/flows/aidlc/templates/construction/construction-log-template.md +129 -0
  50. package/flows/aidlc/templates/construction/standards/coding-standards.md +29 -0
  51. package/flows/aidlc/templates/construction/standards/system-architecture.md +22 -0
  52. package/flows/aidlc/templates/construction/standards/tech-stack.md +19 -0
  53. package/flows/aidlc/templates/inception/inception-log-template.md +134 -0
  54. package/flows/aidlc/templates/inception/project/README.md +55 -0
  55. package/flows/aidlc/templates/inception/requirements-template.md +144 -0
  56. package/flows/aidlc/templates/inception/stories-template.md +38 -0
  57. package/flows/aidlc/templates/inception/story-template.md +147 -0
  58. package/flows/aidlc/templates/inception/system-context-template.md +29 -0
  59. package/flows/aidlc/templates/inception/unit-brief-template.md +177 -0
  60. package/flows/aidlc/templates/inception/units-template.md +52 -0
  61. package/flows/aidlc/templates/standards/catalog.yaml +345 -0
  62. package/flows/aidlc/templates/standards/coding-standards.guide.md +553 -0
  63. package/flows/aidlc/templates/standards/data-stack.guide.md +162 -0
  64. package/flows/aidlc/templates/standards/tech-stack.guide.md +280 -0
  65. package/lib/InstallerFactory.js +36 -0
  66. package/lib/cli-utils.js +372 -0
  67. package/lib/constants.js +31 -0
  68. package/lib/installer.js +314 -0
  69. package/lib/installers/AntigravityInstaller.js +22 -0
  70. package/lib/installers/ClaudeInstaller.js +85 -0
  71. package/lib/installers/ClineInstaller.js +21 -0
  72. package/lib/installers/CodexInstaller.js +21 -0
  73. package/lib/installers/CopilotInstaller.js +113 -0
  74. package/lib/installers/CursorInstaller.js +63 -0
  75. package/lib/installers/GeminiInstaller.js +75 -0
  76. package/lib/installers/KiroInstaller.js +22 -0
  77. package/lib/installers/OpenCodeInstaller.js +22 -0
  78. package/lib/installers/RooInstaller.js +22 -0
  79. package/lib/installers/ToolInstaller.js +73 -0
  80. package/lib/installers/WindsurfInstaller.js +76 -0
  81. package/lib/markdown-validator.ts +175 -0
  82. package/lib/yaml-validator.ts +99 -0
  83. package/package.json +65 -0
@@ -0,0 +1,280 @@
1
+ # Tech Stack Facilitation Guide
2
+
3
+ ## Purpose
4
+
5
+ Define the technology choices that will guide code generation, architecture decisions, and ensure consistency across all AI agents working on the project.
6
+
7
+ ---
8
+
9
+ ## Facilitation Approach
10
+
11
+ You are collaborating with a peer to discover their tech stack preferences. This is a conversation, not a form to fill out.
12
+
13
+ **Adapt your style:**
14
+
15
+ - If they mention specific technologies confidently → treat them as experienced, be concise
16
+ - If they seem uncertain → provide more context, examples, and recommendations
17
+ - If they have strong preferences → respect them, ask about tradeoffs they've considered
18
+
19
+ **Your role:**
20
+
21
+ - Guide discovery, don't dictate choices
22
+ - Surface tradeoffs they may not have considered
23
+ - Ensure choices are coherent (no conflicting technologies)
24
+ - Capture rationale, not just the choice
25
+
26
+ ---
27
+
28
+ ## Discovery Areas
29
+
30
+ ### 1. Languages
31
+
32
+ **Goal**: Understand what programming language(s) they'll use.
33
+
34
+ **Open with context:**
35
+ > "Let's start with languages. This affects everything else - framework options, available libraries, team hiring, and performance characteristics."
36
+
37
+ **Explore:**
38
+
39
+ - What languages is the team already comfortable with?
40
+ - Are there languages they want to learn vs. use productively?
41
+ - Is type safety important? (catches bugs early vs. development speed)
42
+ - What's the runtime environment? (Browser, Node.js, Edge functions, Native)
43
+ - Any organizational standards or constraints?
44
+
45
+ **If they're unsure, guide by use case:**
46
+
47
+ | Use Case | Recommendation | Why |
48
+ |----------|----------------|-----|
49
+ | Web app (full-stack) | TypeScript | Type safety, React/Next.js ecosystem, great tooling |
50
+ | API service | TypeScript or Go | TS for ecosystem, Go for performance |
51
+ | ML/AI/Data | Python | Libraries (PyTorch, pandas), community |
52
+ | High-performance systems | Go or Rust | Go for simplicity, Rust for safety |
53
+ | Scripts/automation | Python or TypeScript | Readability, quick iteration |
54
+
55
+ **Common signals to listen for:**
56
+
57
+ - "We're a React shop" → TypeScript
58
+ - "We do ML/AI" → Python, possibly with TypeScript frontend
59
+ - "Performance is critical" → Go, Rust, or optimized Node.js
60
+ - "Small team, move fast" → TypeScript or Python
61
+ - "Enterprise environment" → Java/Kotlin or TypeScript
62
+
63
+ **Validate before moving on:**
64
+ > "So we're going with {language}. This means {implication}. Sound right?"
65
+
66
+ ---
67
+
68
+ ### 2. Framework
69
+
70
+ **Goal**: Understand their application framework choice.
71
+
72
+ **Context to share:**
73
+ > "Your framework shapes project structure, available patterns, and deployment options. It's one of the hardest things to change later."
74
+
75
+ **Explore:**
76
+
77
+ - What type of application? (Web app, API only, CLI, Mobile)
78
+ - Do they need server-side rendering (SSR) or static generation (SSG)?
79
+ - Is this a new project or adding to existing code?
80
+ - Where will it be deployed? (This affects framework choice)
81
+ - Any real-time requirements? (WebSockets, subscriptions)
82
+
83
+ **Guide by language and use case:**
84
+
85
+ **TypeScript - Web Applications:**
86
+
87
+ | Framework | Best For | Tradeoffs |
88
+ |-----------|----------|-----------|
89
+ | Next.js | Full-stack, SSR/SSG, Vercel deployment | Opinionated, tied to React |
90
+ | Remix | Web standards, nested routing, great DX | Smaller ecosystem |
91
+ | Astro | Content-heavy sites, partial hydration | Less suited for highly interactive apps |
92
+ | SvelteKit | Performance, smaller bundle, great DX | Smaller ecosystem than React |
93
+
94
+ **TypeScript - API Only:**
95
+
96
+ | Framework | Best For | Tradeoffs |
97
+ |-----------|----------|-----------|
98
+ | Fastify | Performance, low overhead | Less opinionated |
99
+ | NestJS | Enterprise, structured, dependency injection | More boilerplate |
100
+ | Hono | Edge functions, ultra-lightweight | Newer, smaller ecosystem |
101
+ | Express | Simple, huge middleware ecosystem | Older patterns, callback-heavy |
102
+
103
+ **Python - APIs:**
104
+
105
+ | Framework | Best For | Tradeoffs |
106
+ |-----------|----------|-----------|
107
+ | FastAPI | Modern async, auto-docs, type hints | Async complexity |
108
+ | Django | Batteries-included, ORM, admin | Heavier, monolithic |
109
+ | Flask | Minimal, flexible | Need to add everything yourself |
110
+
111
+ **Go - APIs:**
112
+
113
+ | Framework | Best For | Tradeoffs |
114
+ |-----------|----------|-----------|
115
+ | Gin | Fast, popular, good docs | |
116
+ | Echo | Similar to Gin, slightly different API | |
117
+ | Chi | Lightweight, idiomatic Go | Less batteries included |
118
+ | Standard library | Maximum control | More code to write |
119
+
120
+ **Questions to surface tradeoffs:**
121
+
122
+ - "Next.js is great but ties you to React. Is that okay?"
123
+ - "FastAPI requires understanding async Python. Is the team comfortable with that?"
124
+ - "NestJS has more structure but also more boilerplate. Do you prefer convention or flexibility?"
125
+
126
+ ---
127
+
128
+ ### 3. Authentication
129
+
130
+ **Goal**: Understand authentication needs.
131
+
132
+ **Optional - some projects don't need auth initially.**
133
+
134
+ **Explore:**
135
+
136
+ - Do they need user authentication?
137
+ - What methods? (Email/password, social login, magic links, SSO)
138
+ - Is this B2C (end users) or B2B (enterprise SSO)?
139
+ - Any compliance requirements? (MFA, audit logs)
140
+
141
+ **Options:**
142
+
143
+ | Solution | Best For | Tradeoffs |
144
+ |----------|----------|-----------|
145
+ | Supabase Auth | Supabase users, quick setup | Tied to Supabase |
146
+ | NextAuth.js | Next.js apps, flexible | Configuration complexity |
147
+ | Clerk | Quick setup, beautiful UI | Cost at scale |
148
+ | Auth0 | Enterprise, SSO | Cost, complexity |
149
+ | Lucia | Lightweight, self-hosted | More DIY |
150
+ | Custom | Full control | Security responsibility |
151
+
152
+ **If using Supabase for database:**
153
+ > "Since you're using Supabase for the database, Supabase Auth integrates seamlessly. It handles email/password, social providers, and row-level security. Worth considering unless you have specific needs."
154
+
155
+ ---
156
+
157
+ ### 4. Infrastructure & Deployment
158
+
159
+ **Goal**: Understand how they'll deploy and operate.
160
+
161
+ **Explore:**
162
+
163
+ - Where do they want to deploy? (Cloud provider preference?)
164
+ - Serverless vs. containers vs. VMs?
165
+ - Who manages infrastructure? (Solo dev, dedicated DevOps, managed service)
166
+ - Budget constraints?
167
+ - Any existing infrastructure to integrate with?
168
+
169
+ **Guide by context:**
170
+
171
+ | Context | Recommendation | Why |
172
+ |---------|----------------|-----|
173
+ | Solo dev, startup | Vercel, Railway, Render | Minimal ops, fast deployment |
174
+ | Next.js app | Vercel | Optimized for Next.js |
175
+ | Need containers | Fly.io, Railway, Render | Simple container hosting |
176
+ | Enterprise/compliance | AWS, GCP, Azure | Full control, compliance certifications |
177
+ | Cost-sensitive at scale | Fly.io, self-managed k8s | Lower costs, more ops |
178
+ | Already in AWS | AWS ecosystem | Consistency, existing knowledge |
179
+
180
+ **Serverless vs. Containers:**
181
+
182
+ - **Serverless** (Vercel, Lambda): Pay-per-use, auto-scaling, cold starts
183
+ - **Containers** (Fly.io, ECS): Predictable performance, more control
184
+ - **VMs** (EC2): Full control, predictable costs at scale
185
+
186
+ ---
187
+
188
+ ### 5. Package Manager
189
+
190
+ **Goal**: Quick decision on package management.
191
+
192
+ **For JavaScript/TypeScript:**
193
+
194
+ | Manager | Best For |
195
+ |---------|----------|
196
+ | pnpm | Monorepos, disk efficiency, speed |
197
+ | npm | Default, widest compatibility |
198
+ | yarn | Existing yarn projects |
199
+ | bun | Experimental, very fast |
200
+
201
+ **Default recommendation:** pnpm (fast, efficient, great monorepo support)
202
+
203
+ ---
204
+
205
+ ## Completing the Discovery
206
+
207
+ Once you've explored all relevant areas, summarize:
208
+
209
+ ```markdown
210
+ ## Tech Stack Summary
211
+
212
+ Based on our conversation, here's what I understand:
213
+
214
+ **Languages**: {choice}
215
+ {brief rationale}
216
+
217
+ **Framework**: {choice}
218
+ {brief rationale}
219
+
220
+ **Authentication**: {choice or "TBD"}
221
+ {brief rationale if applicable}
222
+
223
+ **Infrastructure**: {choice}
224
+ {brief rationale}
225
+
226
+ **Package Manager**: {choice}
227
+
228
+ ---
229
+
230
+ Does this capture your tech stack accurately? Any adjustments needed?
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Output Generation
236
+
237
+ After confirmation, create `standards/tech-stack.md`:
238
+
239
+ ```markdown
240
+ # Tech Stack
241
+
242
+ ## Overview
243
+ {1-2 sentence summary of the stack and why it fits the project}
244
+
245
+ ## Languages
246
+ {language(s)}
247
+
248
+ {Rationale - why this choice, what it enables}
249
+
250
+ ## Framework
251
+ {framework}
252
+
253
+ {Rationale - why this choice, deployment implications}
254
+
255
+ ## Authentication
256
+ {auth solution or "TBD"}
257
+
258
+ {Rationale if selected}
259
+
260
+ ## Infrastructure & Deployment
261
+ {infrastructure choice}
262
+
263
+ {Rationale - deployment strategy, scaling approach}
264
+
265
+ ## Package Manager
266
+ {package manager}
267
+
268
+ ## Decision Relationships
269
+ {Note any important connections between choices}
270
+ ```
271
+
272
+ ---
273
+
274
+ ## Notes for Agent
275
+
276
+ - **Don't ask all questions linearly** - adapt based on what they've already told you
277
+ - **Skip irrelevant decisions** - CLI tools don't need authentication discussion
278
+ - **Capture rationale** - "why" is as important as "what"
279
+ - **Respect existing choices** - if they say "we're using X", don't try to change their mind unless there's a real issue
280
+ - **It's okay to leave things TBD** - not every decision needs to be made upfront
@@ -0,0 +1,36 @@
1
+ const ClaudeInstaller = require('./installers/ClaudeInstaller');
2
+ const CursorInstaller = require('./installers/CursorInstaller');
3
+ const CopilotInstaller = require('./installers/CopilotInstaller');
4
+ const AntigravityInstaller = require('./installers/AntigravityInstaller');
5
+ const WindsurfInstaller = require('./installers/WindsurfInstaller');
6
+ const ClineInstaller = require('./installers/ClineInstaller');
7
+ const RooInstaller = require('./installers/RooInstaller');
8
+ const KiroInstaller = require('./installers/KiroInstaller');
9
+ const GeminiInstaller = require('./installers/GeminiInstaller');
10
+ const CodexInstaller = require('./installers/CodexInstaller');
11
+ const OpenCodeInstaller = require('./installers/OpenCodeInstaller');
12
+
13
+ class InstallerFactory {
14
+ static getInstallers() {
15
+ return [
16
+ new ClaudeInstaller(),
17
+ new CursorInstaller(),
18
+ new CopilotInstaller(),
19
+ new AntigravityInstaller(),
20
+ new WindsurfInstaller(),
21
+ new ClineInstaller(),
22
+ new RooInstaller(),
23
+ new KiroInstaller(),
24
+ new GeminiInstaller(),
25
+ new CodexInstaller(),
26
+ new OpenCodeInstaller()
27
+ ];
28
+ }
29
+
30
+ static getInstaller(key) {
31
+ const installers = this.getInstallers();
32
+ return installers.find(i => i.key === key);
33
+ }
34
+ }
35
+
36
+ module.exports = InstallerFactory;
@@ -0,0 +1,372 @@
1
+ /**
2
+ * CLI Utilities for specsmd
3
+ */
4
+
5
+ const chalk = require('chalk');
6
+ const figlet = require('figlet');
7
+ const gradient = require('gradient-string');
8
+ const path = require('path');
9
+
10
+ // Lazy load oh-my-logo (ESM module) via dynamic import
11
+ let ohMyLogo = null;
12
+ const getOhMyLogo = async () => {
13
+ if (!ohMyLogo) {
14
+ ohMyLogo = await import('oh-my-logo');
15
+ }
16
+ return ohMyLogo;
17
+ };
18
+
19
+ const { THEME_COLORS } = require('./constants');
20
+
21
+ // Theme Colors (Terracotta/Orange inspired by Claude Code)
22
+ const THEME = THEME_COLORS;
23
+
24
+ // Create gradient for logo
25
+ const logoGradient = gradient([THEME.primary, THEME.secondary]);
26
+
27
+ // Theme chalk instances
28
+ const theme = {
29
+ primary: chalk.hex(THEME.primary),
30
+ secondary: chalk.hex(THEME.secondary),
31
+ success: chalk.hex(THEME.success),
32
+ error: chalk.hex(THEME.error),
33
+ warning: chalk.hex(THEME.warning),
34
+ info: chalk.hex(THEME.info),
35
+ dim: chalk.hex(THEME.dim)
36
+ };
37
+
38
+ // Box drawing characters (Unicode)
39
+ const BOX = {
40
+ topLeft: '╭',
41
+ topRight: '╮',
42
+ bottomLeft: '╰',
43
+ bottomRight: '╯',
44
+ horizontal: '─',
45
+ vertical: '│',
46
+ heavyHorizontal: '═',
47
+ heavyVertical: '║',
48
+ heavyTopLeft: '╔',
49
+ heavyTopRight: '╗',
50
+ heavyBottomLeft: '╚',
51
+ heavyBottomRight: '╝'
52
+ };
53
+
54
+ /**
55
+ * CLIUtils -
56
+ */
57
+ const CLIUtils = {
58
+ /**
59
+ * Get package version
60
+ */
61
+ getVersion() {
62
+ try {
63
+ const packageJson = require(path.join(__dirname, '..', 'package.json'));
64
+ return packageJson.version || 'Unknown';
65
+ } catch {
66
+ return 'Unknown';
67
+ }
68
+ },
69
+
70
+ /**
71
+ * Get terminal width (capped at 80)
72
+ */
73
+ getWidth() {
74
+ return Math.min(process.stdout.columns || 80, 80);
75
+ },
76
+
77
+ /**
78
+ * Display the specs.md logo with gradient ASCII art (lowercase with shadow)
79
+ * Uses oh-my-logo for beautiful gradient rendering
80
+ * @param {boolean} clearScreen - Whether to clear screen first
81
+ */
82
+ async displayLogo(clearScreen = true) {
83
+ if (clearScreen) {
84
+ console.clear();
85
+ }
86
+
87
+ const version = this.getVersion();
88
+
89
+ console.log('');
90
+
91
+ try {
92
+ // Use oh-my-logo with custom orange palette and Standard font (lowercase)
93
+ const { render } = await getOhMyLogo();
94
+ const logo = await render('specs.md', {
95
+ palette: [THEME.primary, THEME.secondary, '#ffb380'],
96
+ font: 'Standard',
97
+ direction: 'horizontal'
98
+ });
99
+
100
+ console.log(logo);
101
+ } catch (err) {
102
+ // Fallback to figlet + gradient-string if oh-my-logo fails
103
+ const figletArt = figlet.textSync('specs.md', {
104
+ font: 'Standard',
105
+ horizontalLayout: 'default'
106
+ });
107
+ console.log(logoGradient(figletArt));
108
+ }
109
+
110
+ // Tagline with version
111
+ console.log(theme.primary(' AI-native development orchestration') + theme.primary.bold(` v${version}`) + '\n');
112
+ },
113
+
114
+ /**
115
+ * Display the specsmd logo synchronously using figlet (fallback)
116
+ * @param {boolean} clearScreen - Whether to clear screen first
117
+ */
118
+ displayLogoSync(clearScreen = true) {
119
+ if (clearScreen) {
120
+ console.clear();
121
+ }
122
+
123
+ const version = this.getVersion();
124
+
125
+ // Generate ASCII art with figlet
126
+ const figletArt = figlet.textSync('specs.md', {
127
+ font: 'Big',
128
+ horizontalLayout: 'default'
129
+ });
130
+
131
+ console.log('');
132
+ console.log(logoGradient(figletArt));
133
+
134
+ // Tagline with version
135
+ console.log(theme.primary(' AI-native development orchestration') + theme.primary.bold(` v${version}`) + '\n');
136
+ },
137
+
138
+ /**
139
+ * Display the logo using figlet (alternative style)
140
+ * @param {boolean} clearScreen - Whether to clear screen first
141
+ */
142
+ displayFigletLogo(clearScreen = true) {
143
+ if (clearScreen) {
144
+ console.clear();
145
+ }
146
+
147
+ const version = this.getVersion();
148
+ const art = figlet.textSync('specs.md', {
149
+ font: 'Big',
150
+ horizontalLayout: 'full'
151
+ });
152
+
153
+ console.log(logoGradient(art));
154
+ console.log(theme.dim(' AI-native development orchestration') + theme.primary.bold(` v${version}`) + '\n');
155
+ },
156
+
157
+ /**
158
+ * Display a section header with separator lines
159
+ * @param {string} title - Section title
160
+ * @param {string} subtitle - Optional subtitle
161
+ */
162
+ displaySection(title, subtitle = null) {
163
+ const width = this.getWidth();
164
+ const line = BOX.heavyHorizontal.repeat(width);
165
+
166
+ console.log('\n' + theme.primary(line));
167
+ console.log(theme.primary.bold(` ${title}`));
168
+ if (subtitle) {
169
+ console.log(theme.dim(` ${subtitle}`));
170
+ }
171
+ console.log(theme.primary(line) + '\n');
172
+ },
173
+
174
+ /**
175
+ * Display a header (lighter than section)
176
+ * @param {string} title - Header title
177
+ * @param {string} icon - Optional icon prefix
178
+ */
179
+ displayHeader(title, icon = '') {
180
+ const prefix = icon ? `${icon} ` : '';
181
+ console.log('\n' + theme.primary.bold(`${prefix}${title}`));
182
+ console.log(theme.dim(BOX.horizontal.repeat(title.length + prefix.length)) + '\n');
183
+ },
184
+
185
+ /**
186
+ * Display a boxed message
187
+ * @param {string} content - Box content
188
+ * @param {object} options - Box options
189
+ */
190
+ displayBox(content, options = {}) {
191
+ const {
192
+ title = null,
193
+ borderColor = 'primary',
194
+ padding = 1,
195
+ width = null
196
+ } = options;
197
+
198
+ const boxWidth = width || Math.min(this.getWidth() - 4, 76);
199
+ const innerWidth = boxWidth - 2;
200
+ const colorFn = theme[borderColor] || theme.primary;
201
+
202
+ // Top border
203
+ let topBorder;
204
+ if (title) {
205
+ const titleStr = ` ${title} `;
206
+ const remainingWidth = boxWidth - titleStr.length - 2;
207
+ const leftPad = Math.floor(remainingWidth / 2);
208
+ const rightPad = remainingWidth - leftPad;
209
+ topBorder = colorFn(BOX.topLeft + BOX.horizontal.repeat(leftPad) + titleStr + BOX.horizontal.repeat(rightPad) + BOX.topRight);
210
+ } else {
211
+ topBorder = colorFn(BOX.topLeft + BOX.horizontal.repeat(boxWidth - 2) + BOX.topRight);
212
+ }
213
+ console.log(topBorder);
214
+
215
+ // Padding top
216
+ for (let i = 0; i < padding; i++) {
217
+ console.log(colorFn(BOX.vertical) + ' '.repeat(innerWidth) + colorFn(BOX.vertical));
218
+ }
219
+
220
+ // Content lines
221
+ const lines = content.split('\n');
222
+ for (const line of lines) {
223
+ const stripped = line.replace(/\u001b\[[0-9;]*m/g, ''); // Strip ANSI codes for length calculation
224
+ const paddedLine = line + ' '.repeat(Math.max(0, innerWidth - stripped.length));
225
+ console.log(colorFn(BOX.vertical) + paddedLine.slice(0, innerWidth) + colorFn(BOX.vertical));
226
+ }
227
+
228
+ // Padding bottom
229
+ for (let i = 0; i < padding; i++) {
230
+ console.log(colorFn(BOX.vertical) + ' '.repeat(innerWidth) + colorFn(BOX.vertical));
231
+ }
232
+
233
+ // Bottom border
234
+ console.log(colorFn(BOX.bottomLeft + BOX.horizontal.repeat(boxWidth - 2) + BOX.bottomRight));
235
+ },
236
+
237
+ /**
238
+ * Display a success message in a green box
239
+ * @param {string} message - Success message
240
+ * @param {string} title - Optional title
241
+ */
242
+ displaySuccess(message, title = 'Success') {
243
+ console.log('');
244
+ this.displayBox(theme.success(message), {
245
+ title,
246
+ borderColor: 'success',
247
+ padding: 0
248
+ });
249
+ },
250
+
251
+ /**
252
+ * Display an error message in a red box
253
+ * @param {string} message - Error message
254
+ * @param {string} title - Optional title
255
+ */
256
+ displayError(message, title = 'Error') {
257
+ console.log('');
258
+ this.displayBox(theme.error(message), {
259
+ title,
260
+ borderColor: 'error',
261
+ padding: 0
262
+ });
263
+ },
264
+
265
+ /**
266
+ * Display a warning message in an amber box
267
+ * @param {string} message - Warning message
268
+ * @param {string} title - Optional title
269
+ */
270
+ displayWarning(message, title = 'Warning') {
271
+ console.log('');
272
+ this.displayBox(theme.warning(message), {
273
+ title,
274
+ borderColor: 'warning',
275
+ padding: 0
276
+ });
277
+ },
278
+
279
+ /**
280
+ * Display an info message in a blue box
281
+ * @param {string} message - Info message
282
+ * @param {string} title - Optional title
283
+ */
284
+ displayInfo(message, title = 'Info') {
285
+ console.log('');
286
+ this.displayBox(theme.info(message), {
287
+ title,
288
+ borderColor: 'info',
289
+ padding: 0
290
+ });
291
+ },
292
+
293
+ /**
294
+ * Display current step progress
295
+ * @param {number} current - Current step
296
+ * @param {number} total - Total steps
297
+ * @param {string} description - Step description
298
+ */
299
+ displayStep(current, total, description) {
300
+ const progress = theme.primary.bold(`[${current}/${total}]`);
301
+ console.log(`${progress} ${description}`);
302
+ },
303
+
304
+ /**
305
+ * Display a completion message
306
+ * @param {string} message - Completion message
307
+ */
308
+ displayComplete(message) {
309
+ this.displaySuccess(message, 'Complete');
310
+ },
311
+
312
+ /**
313
+ * Display a simple status line
314
+ * @param {string} icon - Status icon
315
+ * @param {string} message - Status message
316
+ * @param {string} color - Color name
317
+ */
318
+ displayStatus(icon, message, color = 'primary') {
319
+ const colorFn = theme[color] || theme.primary;
320
+ console.log(`${colorFn(icon)} ${message}`);
321
+ },
322
+
323
+ /**
324
+ * Display a list of items
325
+ * @param {string[]} items - List items
326
+ * @param {string} bullet - Bullet character
327
+ */
328
+ displayList(items, bullet = ' -') {
329
+ for (const item of items) {
330
+ console.log(theme.dim(bullet) + ' ' + item);
331
+ }
332
+ },
333
+
334
+ /**
335
+ * Display next steps
336
+ * @param {string[]} steps - Array of step descriptions
337
+ */
338
+ displayNextSteps(steps) {
339
+ console.log(theme.dim('\nNext steps:'));
340
+ steps.forEach((step, index) => {
341
+ console.log(theme.dim(` ${index + 1}. ${step}`));
342
+ });
343
+ console.log('');
344
+ },
345
+
346
+ /**
347
+ * Display a separator line
348
+ * @param {string} style - 'light' or 'heavy'
349
+ */
350
+ displaySeparator(style = 'light') {
351
+ const width = this.getWidth();
352
+ const char = style === 'heavy' ? BOX.heavyHorizontal : BOX.horizontal;
353
+ console.log(theme.dim(char.repeat(width)));
354
+ },
355
+
356
+ /**
357
+ * Theme colors for external use
358
+ */
359
+ theme,
360
+
361
+ /**
362
+ * Logo gradient for external use
363
+ */
364
+ logoGradient,
365
+
366
+ /**
367
+ * Box characters for external use
368
+ */
369
+ BOX
370
+ };
371
+
372
+ module.exports = CLIUtils;