@girardmedia/bootspring 2.0.21 → 2.0.23

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 (159) hide show
  1. package/bin/bootspring.js +5 -0
  2. package/cli/org.js +474 -0
  3. package/cli/preseed/index.js +16 -0
  4. package/cli/preseed/interactive.js +143 -0
  5. package/cli/preseed/templates.js +227 -0
  6. package/cli/preseed.js +9 -301
  7. package/cli/seed/builders/ai-context-builder.js +85 -0
  8. package/cli/seed/builders/index.js +13 -0
  9. package/cli/seed/builders/seed-builder.js +272 -0
  10. package/cli/seed/extractors/content-extractors.js +383 -0
  11. package/cli/seed/extractors/index.js +47 -0
  12. package/cli/seed/extractors/metadata-extractors.js +167 -0
  13. package/cli/seed/extractors/section-extractor.js +54 -0
  14. package/cli/seed/extractors/stack-extractors.js +228 -0
  15. package/cli/seed/index.js +18 -0
  16. package/cli/seed/utils/folder-structure.js +84 -0
  17. package/cli/seed/utils/index.js +11 -0
  18. package/cli/seed.js +23 -1074
  19. package/core/api-client.js +77 -0
  20. package/core/entitlements.js +36 -0
  21. package/core/organizations.js +223 -0
  22. package/core/policies.js +51 -6
  23. package/core/policy-matrix.js +303 -0
  24. package/core/project-context.js +1 -0
  25. package/dist/cli/index.d.ts +3 -0
  26. package/dist/cli/index.js +3220 -0
  27. package/dist/cli/index.js.map +1 -0
  28. package/dist/context-McpJQa_2.d.ts +5710 -0
  29. package/dist/core/index.d.ts +635 -0
  30. package/dist/core/index.js +2593 -0
  31. package/dist/core/index.js.map +1 -0
  32. package/dist/index-QqbeEiDm.d.ts +857 -0
  33. package/dist/index-UiYCgwiH.d.ts +174 -0
  34. package/dist/index.d.ts +453 -0
  35. package/dist/index.js +44228 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/mcp/index.d.ts +1 -0
  38. package/dist/mcp/index.js +41173 -0
  39. package/dist/mcp/index.js.map +1 -0
  40. package/generators/index.ts +82 -0
  41. package/intelligence/orchestrator/config/failure-signatures.js +48 -0
  42. package/intelligence/orchestrator/config/index.js +23 -0
  43. package/intelligence/orchestrator/config/pack-lifecycle.js +262 -0
  44. package/intelligence/orchestrator/config/phases.js +111 -0
  45. package/intelligence/orchestrator/config/remediation.js +150 -0
  46. package/intelligence/orchestrator/config/workflows.js +168 -0
  47. package/intelligence/orchestrator/core/index.js +16 -0
  48. package/intelligence/orchestrator/core/state-manager.js +88 -0
  49. package/intelligence/orchestrator/core/telemetry.js +24 -0
  50. package/intelligence/orchestrator/index.js +17 -0
  51. package/intelligence/orchestrator.js +17 -512
  52. package/mcp/contracts/mcp-contract.v1.json +1 -1
  53. package/package.json +16 -3
  54. package/src/cli/agent.ts +703 -0
  55. package/src/cli/analyze.ts +640 -0
  56. package/src/cli/audit.ts +707 -0
  57. package/src/cli/auth.ts +930 -0
  58. package/src/cli/billing.ts +364 -0
  59. package/src/cli/build.ts +1089 -0
  60. package/src/cli/business.ts +508 -0
  61. package/src/cli/checkpoint-utils.ts +236 -0
  62. package/src/cli/checkpoint.ts +757 -0
  63. package/src/cli/cloud-sync.ts +534 -0
  64. package/src/cli/content.ts +273 -0
  65. package/src/cli/context.ts +667 -0
  66. package/src/cli/dashboard.ts +133 -0
  67. package/src/cli/deploy.ts +704 -0
  68. package/src/cli/doctor.ts +480 -0
  69. package/src/cli/fundraise.ts +494 -0
  70. package/src/cli/generate.ts +346 -0
  71. package/src/cli/github-cmd.ts +566 -0
  72. package/src/cli/health.ts +599 -0
  73. package/src/cli/index.ts +113 -0
  74. package/src/cli/init.ts +838 -0
  75. package/src/cli/legal.ts +495 -0
  76. package/src/cli/log.ts +316 -0
  77. package/src/cli/loop.ts +1660 -0
  78. package/src/cli/manager.ts +878 -0
  79. package/src/cli/mcp.ts +275 -0
  80. package/src/cli/memory.ts +346 -0
  81. package/src/cli/metrics.ts +590 -0
  82. package/src/cli/monitor.ts +960 -0
  83. package/src/cli/mvp.ts +662 -0
  84. package/src/cli/onboard.ts +663 -0
  85. package/src/cli/orchestrator.ts +622 -0
  86. package/src/cli/plugin.ts +483 -0
  87. package/src/cli/prd.ts +671 -0
  88. package/src/cli/preseed-start.ts +1633 -0
  89. package/src/cli/preseed.ts +2434 -0
  90. package/src/cli/project.ts +526 -0
  91. package/src/cli/quality.ts +885 -0
  92. package/src/cli/security.ts +1079 -0
  93. package/src/cli/seed.ts +1224 -0
  94. package/src/cli/skill.ts +537 -0
  95. package/src/cli/suggest.ts +1225 -0
  96. package/src/cli/switch.ts +518 -0
  97. package/src/cli/task.ts +780 -0
  98. package/src/cli/telemetry.ts +172 -0
  99. package/src/cli/todo.ts +627 -0
  100. package/src/cli/types.ts +15 -0
  101. package/src/cli/update.ts +334 -0
  102. package/src/cli/visualize.ts +609 -0
  103. package/src/cli/watch.ts +895 -0
  104. package/src/cli/workspace.ts +709 -0
  105. package/src/core/action-recorder.ts +673 -0
  106. package/src/core/analyze-workflow.ts +1453 -0
  107. package/src/core/api-client.ts +1120 -0
  108. package/src/core/audit-workflow.ts +1681 -0
  109. package/src/core/auth.ts +471 -0
  110. package/src/core/build-orchestrator.ts +509 -0
  111. package/src/core/build-state.ts +621 -0
  112. package/src/core/checkpoint-engine.ts +482 -0
  113. package/src/core/config.ts +1285 -0
  114. package/src/core/context-loader.ts +694 -0
  115. package/src/core/context.ts +410 -0
  116. package/src/core/deploy-workflow.ts +1085 -0
  117. package/src/core/entitlements.ts +322 -0
  118. package/src/core/github-sync.ts +720 -0
  119. package/src/core/index.ts +981 -0
  120. package/src/core/ingest.ts +1186 -0
  121. package/src/core/metrics-engine.ts +886 -0
  122. package/src/core/mvp.ts +847 -0
  123. package/src/core/onboard-workflow.ts +1293 -0
  124. package/src/core/policies.ts +81 -0
  125. package/src/core/preseed-workflow.ts +1163 -0
  126. package/src/core/preseed.ts +1826 -0
  127. package/src/core/project-context.ts +380 -0
  128. package/src/core/project-state.ts +699 -0
  129. package/src/core/r2-sync.ts +691 -0
  130. package/src/core/scaffold.ts +1715 -0
  131. package/src/core/session.ts +286 -0
  132. package/src/core/task-extractor.ts +799 -0
  133. package/src/core/telemetry.ts +371 -0
  134. package/src/core/tier-enforcement.ts +737 -0
  135. package/src/core/utils.ts +437 -0
  136. package/src/index.ts +29 -0
  137. package/src/intelligence/agent-collab.ts +2376 -0
  138. package/src/intelligence/auto-suggest.ts +713 -0
  139. package/src/intelligence/content-gen.ts +1351 -0
  140. package/src/intelligence/cross-project.ts +1692 -0
  141. package/src/intelligence/git-memory.ts +529 -0
  142. package/src/intelligence/index.ts +318 -0
  143. package/src/intelligence/orchestrator.ts +534 -0
  144. package/src/intelligence/prd.ts +466 -0
  145. package/src/intelligence/recommendations.ts +982 -0
  146. package/src/intelligence/workflow-composer.ts +1472 -0
  147. package/src/mcp/capabilities.ts +233 -0
  148. package/src/mcp/index.ts +37 -0
  149. package/src/mcp/registry.ts +1268 -0
  150. package/src/mcp/response-formatter.ts +797 -0
  151. package/src/mcp/server.ts +240 -0
  152. package/src/types/agent.ts +69 -0
  153. package/src/types/config.ts +86 -0
  154. package/src/types/context.ts +77 -0
  155. package/src/types/index.ts +53 -0
  156. package/src/types/mcp.ts +91 -0
  157. package/src/types/skills.ts +47 -0
  158. package/src/types/workflow.ts +155 -0
  159. package/generators/index.js +0 -18
@@ -0,0 +1,410 @@
1
+ /**
2
+ * Bootspring Context Manager
3
+ * Handles project context for AI assistants
4
+ *
5
+ * @package bootspring
6
+ * @module core/context
7
+ */
8
+
9
+ import * as path from 'path';
10
+ import * as configModule from './config';
11
+ import * as utils from './utils';
12
+ import type { LoadedConfig, ConfigInput } from './config';
13
+
14
+ // =============================================================================
15
+ // Types
16
+ // =============================================================================
17
+
18
+ /**
19
+ * Enabled plugin info
20
+ */
21
+ export interface EnabledPlugin {
22
+ provider: string;
23
+ features: string[];
24
+ }
25
+
26
+ /**
27
+ * Enabled plugins map
28
+ */
29
+ export interface EnabledPlugins {
30
+ [name: string]: EnabledPlugin;
31
+ }
32
+
33
+ /**
34
+ * Project file structure info
35
+ */
36
+ export interface ProjectFiles {
37
+ hasPackageJson: boolean;
38
+ hasTsConfig: boolean;
39
+ hasClaudeMd: boolean;
40
+ hasBootspringConfig: boolean;
41
+ hasTodoMd: boolean;
42
+ hasGit: boolean;
43
+ hasSrcDir: boolean;
44
+ hasAppDir: boolean;
45
+ hasPagesDir: boolean;
46
+ structure: 'app-router' | 'pages-router' | 'src-based' | 'flat';
47
+ }
48
+
49
+ /**
50
+ * Git repository info
51
+ */
52
+ export interface GitInfo {
53
+ initialized: boolean;
54
+ branch?: string | undefined;
55
+ hasRemote?: boolean | undefined;
56
+ }
57
+
58
+ /**
59
+ * Project state info
60
+ */
61
+ export interface ProjectState {
62
+ phase: 'unknown' | 'uninitialized' | 'initialized' | 'active';
63
+ health: 'unknown' | 'good' | 'fair' | 'needs-attention';
64
+ todos: number;
65
+ lastGenerated: Date | null;
66
+ issues?: string[] | undefined;
67
+ }
68
+
69
+ /**
70
+ * Full project context
71
+ */
72
+ export interface ProjectContext {
73
+ project: ConfigInput['project'];
74
+ stack: ConfigInput['stack'];
75
+ plugins: EnabledPlugins;
76
+ files: ProjectFiles;
77
+ git: GitInfo;
78
+ state: ProjectState;
79
+ timestamp: string;
80
+ }
81
+
82
+ /**
83
+ * Validation check result
84
+ */
85
+ export interface ValidationCheck {
86
+ name: string;
87
+ status: 'pass' | 'fail' | 'warn';
88
+ message: string;
89
+ }
90
+
91
+ /**
92
+ * Context validation result
93
+ */
94
+ export interface ContextValidationResult {
95
+ valid: boolean;
96
+ score: number;
97
+ maxScore: number;
98
+ percentage: number;
99
+ checks: ValidationCheck[];
100
+ }
101
+
102
+ /**
103
+ * Options for get/validate functions
104
+ */
105
+ export interface ContextOptions {
106
+ config?: LoadedConfig | undefined;
107
+ }
108
+
109
+ // =============================================================================
110
+ // Functions
111
+ // =============================================================================
112
+
113
+ /**
114
+ * Get current project context
115
+ */
116
+ export function get(options: ContextOptions = {}): ProjectContext {
117
+ const cfg = options.config ?? configModule.load();
118
+ const projectRoot = cfg._projectRoot ?? process.cwd();
119
+
120
+ const context: ProjectContext = {
121
+ project: cfg.project,
122
+ stack: cfg.stack,
123
+ plugins: getEnabledPlugins(cfg),
124
+ files: getProjectFiles(projectRoot),
125
+ git: getGitInfo(projectRoot),
126
+ state: getProjectState(projectRoot, cfg),
127
+ timestamp: new Date().toISOString()
128
+ };
129
+
130
+ return context;
131
+ }
132
+
133
+ /**
134
+ * Get enabled plugins from config
135
+ */
136
+ export function getEnabledPlugins(cfg: LoadedConfig | ConfigInput): EnabledPlugins {
137
+ const enabled: EnabledPlugins = {};
138
+
139
+ const plugins = cfg.plugins ?? {};
140
+ for (const [name, plugin] of Object.entries(plugins)) {
141
+ if (plugin && plugin.enabled !== false) {
142
+ enabled[name] = {
143
+ provider: (plugin as { provider?: string }).provider ?? 'default',
144
+ features: (plugin as { features?: string[] }).features ?? []
145
+ };
146
+ }
147
+ }
148
+
149
+ return enabled;
150
+ }
151
+
152
+ /**
153
+ * Get project file structure summary
154
+ */
155
+ export function getProjectFiles(projectRoot: string): ProjectFiles {
156
+ const files: ProjectFiles = {
157
+ hasPackageJson: utils.fileExists(path.join(projectRoot, 'package.json')),
158
+ hasTsConfig: utils.fileExists(path.join(projectRoot, 'tsconfig.json')),
159
+ hasClaudeMd: utils.fileExists(path.join(projectRoot, 'CLAUDE.md')),
160
+ hasBootspringConfig: utils.fileExists(path.join(projectRoot, 'bootspring.config.js')),
161
+ hasTodoMd: utils.fileExists(path.join(projectRoot, 'todo.md')),
162
+ hasGit: utils.fileExists(path.join(projectRoot, '.git')),
163
+ hasSrcDir: utils.fileExists(path.join(projectRoot, 'src')),
164
+ hasAppDir: utils.fileExists(path.join(projectRoot, 'app')),
165
+ hasPagesDir: utils.fileExists(path.join(projectRoot, 'pages')),
166
+ structure: 'flat'
167
+ };
168
+
169
+ // Detect framework structure
170
+ if (files.hasAppDir) {
171
+ files.structure = 'app-router';
172
+ } else if (files.hasPagesDir) {
173
+ files.structure = 'pages-router';
174
+ } else if (files.hasSrcDir) {
175
+ files.structure = 'src-based';
176
+ }
177
+
178
+ return files;
179
+ }
180
+
181
+ /**
182
+ * Get git information
183
+ */
184
+ export function getGitInfo(projectRoot: string): GitInfo {
185
+ const gitDir = path.join(projectRoot, '.git');
186
+
187
+ if (!utils.fileExists(gitDir)) {
188
+ return { initialized: false };
189
+ }
190
+
191
+ const info: GitInfo = { initialized: true };
192
+
193
+ // Get current branch
194
+ const headPath = path.join(gitDir, 'HEAD');
195
+ if (utils.fileExists(headPath)) {
196
+ const head = utils.readFile(headPath);
197
+ if (head) {
198
+ const trimmedHead = head.trim();
199
+ if (trimmedHead.startsWith('ref: refs/heads/')) {
200
+ info.branch = trimmedHead.replace('ref: refs/heads/', '');
201
+ }
202
+ }
203
+ }
204
+
205
+ // Check for remote
206
+ const configPath = path.join(gitDir, 'config');
207
+ if (utils.fileExists(configPath)) {
208
+ const gitConfig = utils.readFile(configPath);
209
+ if (gitConfig) {
210
+ info.hasRemote = gitConfig.includes('[remote "origin"]');
211
+ }
212
+ }
213
+
214
+ return info;
215
+ }
216
+
217
+ /**
218
+ * Get project state
219
+ */
220
+ export function getProjectState(projectRoot: string, cfg: LoadedConfig | ConfigInput): ProjectState {
221
+ const state: ProjectState = {
222
+ phase: 'unknown',
223
+ health: 'unknown',
224
+ todos: 0,
225
+ lastGenerated: null
226
+ };
227
+
228
+ // Count todos
229
+ const todoPath = path.join(projectRoot, cfg.paths?.todo ?? 'todo.md');
230
+ if (utils.fileExists(todoPath)) {
231
+ const content = utils.readFile(todoPath);
232
+ if (content) {
233
+ const todoMatches = content.match(/- \[ \]/g);
234
+ state.todos = todoMatches ? todoMatches.length : 0;
235
+ }
236
+ }
237
+
238
+ // Check CLAUDE.md generation time
239
+ const claudePath = path.join(projectRoot, cfg.paths?.context ?? 'CLAUDE.md');
240
+ if (utils.fileExists(claudePath)) {
241
+ state.lastGenerated = utils.getFileTime(claudePath);
242
+ }
243
+
244
+ // Determine phase
245
+ const loadedCfg = cfg as LoadedConfig;
246
+ if (!loadedCfg._configPath) {
247
+ state.phase = 'uninitialized';
248
+ } else if (!state.lastGenerated) {
249
+ state.phase = 'initialized';
250
+ } else {
251
+ state.phase = 'active';
252
+ }
253
+
254
+ // Determine health
255
+ const issues: string[] = [];
256
+ if (!utils.fileExists(path.join(projectRoot, 'package.json'))) {
257
+ issues.push('missing-package-json');
258
+ }
259
+ if (!loadedCfg._configPath) {
260
+ issues.push('missing-config');
261
+ }
262
+ if (!state.lastGenerated) {
263
+ issues.push('missing-context');
264
+ }
265
+
266
+ if (issues.length === 0) {
267
+ state.health = 'good';
268
+ } else if (issues.length <= 2) {
269
+ state.health = 'fair';
270
+ } else {
271
+ state.health = 'needs-attention';
272
+ }
273
+
274
+ state.issues = issues;
275
+
276
+ return state;
277
+ }
278
+
279
+ /**
280
+ * Validate project context
281
+ */
282
+ export function validate(options: ContextOptions = {}): ContextValidationResult {
283
+ const cfg = options.config ?? configModule.load();
284
+ const projectRoot = cfg._projectRoot ?? process.cwd();
285
+
286
+ const checks: ValidationCheck[] = [];
287
+ let score = 0;
288
+ const maxScore = 10;
289
+
290
+ // Check 1: Config exists
291
+ if (cfg._configPath) {
292
+ checks.push({ name: 'Configuration', status: 'pass', message: 'bootspring.config.js found' });
293
+ score += 2;
294
+ } else {
295
+ checks.push({ name: 'Configuration', status: 'fail', message: 'bootspring.config.js missing' });
296
+ }
297
+
298
+ // Check 2: CLAUDE.md exists
299
+ const claudePath = path.join(projectRoot, cfg.paths?.context ?? 'CLAUDE.md');
300
+ if (utils.fileExists(claudePath)) {
301
+ checks.push({ name: 'AI Context', status: 'pass', message: 'CLAUDE.md exists' });
302
+ score += 2;
303
+ } else {
304
+ checks.push({ name: 'AI Context', status: 'fail', message: 'CLAUDE.md missing - run bootspring generate' });
305
+ }
306
+
307
+ // Check 3: package.json exists
308
+ if (utils.fileExists(path.join(projectRoot, 'package.json'))) {
309
+ checks.push({ name: 'Package', status: 'pass', message: 'package.json found' });
310
+ score += 1;
311
+ } else {
312
+ checks.push({ name: 'Package', status: 'warn', message: 'package.json missing' });
313
+ }
314
+
315
+ // Check 4: Git initialized
316
+ if (utils.fileExists(path.join(projectRoot, '.git'))) {
317
+ checks.push({ name: 'Git', status: 'pass', message: 'Git repository initialized' });
318
+ score += 1;
319
+ } else {
320
+ checks.push({ name: 'Git', status: 'warn', message: 'Git not initialized' });
321
+ }
322
+
323
+ // Check 5: TypeScript config (if using TS)
324
+ if (cfg.stack?.language === 'typescript') {
325
+ if (utils.fileExists(path.join(projectRoot, 'tsconfig.json'))) {
326
+ checks.push({ name: 'TypeScript', status: 'pass', message: 'tsconfig.json found' });
327
+ score += 1;
328
+ } else {
329
+ checks.push({ name: 'TypeScript', status: 'fail', message: 'tsconfig.json missing for TypeScript project' });
330
+ }
331
+ } else {
332
+ score += 1;
333
+ }
334
+
335
+ // Check 6: Config validation
336
+ const configValidation = configModule.validate(cfg);
337
+ if (configValidation.valid) {
338
+ checks.push({ name: 'Config Validation', status: 'pass', message: 'Configuration is valid' });
339
+ score += 2;
340
+ } else {
341
+ checks.push({ name: 'Config Validation', status: 'fail', message: configValidation.errors.join(', ') });
342
+ }
343
+
344
+ // Check 7: Todo file
345
+ if (utils.fileExists(path.join(projectRoot, cfg.paths?.todo ?? 'todo.md'))) {
346
+ checks.push({ name: 'Todo Tracking', status: 'pass', message: 'todo.md exists' });
347
+ score += 1;
348
+ } else {
349
+ checks.push({ name: 'Todo Tracking', status: 'fail', message: 'todo.md not found' });
350
+ }
351
+
352
+ return {
353
+ valid: score >= maxScore * 0.6,
354
+ score,
355
+ maxScore,
356
+ percentage: Math.round((score / maxScore) * 100),
357
+ checks
358
+ };
359
+ }
360
+
361
+ /**
362
+ * Generate context summary for AI
363
+ */
364
+ export function generateSummary(options: ContextOptions = {}): string {
365
+ const ctx = get(options);
366
+
367
+ const lines: string[] = [
368
+ '# Project Context',
369
+ '',
370
+ `**Project**: ${ctx.project?.name ?? 'Unknown'}`,
371
+ `**Generated**: ${ctx.timestamp}`,
372
+ '',
373
+ '## Stack',
374
+ `- Framework: ${ctx.stack?.framework ?? 'unknown'}`,
375
+ `- Language: ${ctx.stack?.language ?? 'unknown'}`,
376
+ `- Database: ${ctx.stack?.database ?? 'unknown'}`,
377
+ `- Hosting: ${ctx.stack?.hosting ?? 'unknown'}`,
378
+ ''
379
+ ];
380
+
381
+ // Plugins
382
+ const enabledPlugins = Object.keys(ctx.plugins);
383
+ if (enabledPlugins.length > 0) {
384
+ lines.push('## Enabled Plugins');
385
+ for (const [name, plugin] of Object.entries(ctx.plugins)) {
386
+ lines.push(`- **${name}**: ${plugin.provider}`);
387
+ }
388
+ lines.push('');
389
+ }
390
+
391
+ // State
392
+ lines.push('## Project State');
393
+ lines.push(`- Phase: ${ctx.state.phase}`);
394
+ lines.push(`- Health: ${ctx.state.health}`);
395
+ lines.push(`- Open Todos: ${ctx.state.todos}`);
396
+ if (ctx.state.lastGenerated) {
397
+ lines.push(`- Context Last Generated: ${utils.formatRelativeTime(ctx.state.lastGenerated)}`);
398
+ }
399
+ lines.push('');
400
+
401
+ // Git
402
+ if (ctx.git.initialized) {
403
+ lines.push('## Git');
404
+ lines.push(`- Branch: ${ctx.git.branch ?? 'unknown'}`);
405
+ lines.push(`- Remote: ${ctx.git.hasRemote ? 'configured' : 'not configured'}`);
406
+ lines.push('');
407
+ }
408
+
409
+ return lines.join('\n');
410
+ }