@girardmedia/bootspring 2.2.0 → 2.3.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 (50) hide show
  1. package/README.md +2 -2
  2. package/bin/bootspring.js +35 -96
  3. package/claude-commands/agent.md +34 -0
  4. package/claude-commands/bs.md +31 -0
  5. package/claude-commands/build.md +25 -0
  6. package/claude-commands/skill.md +31 -0
  7. package/claude-commands/todo.md +25 -0
  8. package/dist/cli/index.cjs +17808 -0
  9. package/dist/core/index.d.ts +5814 -0
  10. package/dist/core.js +5780 -0
  11. package/dist/mcp/index.d.ts +1 -0
  12. package/dist/mcp-server.js +2299 -0
  13. package/generators/api-docs.js +2 -2
  14. package/generators/decisions.js +3 -3
  15. package/generators/health.js +16 -16
  16. package/generators/sprint.js +2 -2
  17. package/package.json +27 -59
  18. package/core/api-client.d.ts +0 -69
  19. package/core/api-client.js +0 -1482
  20. package/core/auth.d.ts +0 -98
  21. package/core/auth.js +0 -737
  22. package/core/build-orchestrator.js +0 -508
  23. package/core/build-state.js +0 -612
  24. package/core/config.d.ts +0 -106
  25. package/core/config.js +0 -1328
  26. package/core/context-loader.js +0 -580
  27. package/core/context.d.ts +0 -61
  28. package/core/context.js +0 -327
  29. package/core/entitlements.d.ts +0 -70
  30. package/core/entitlements.js +0 -322
  31. package/core/index.d.ts +0 -53
  32. package/core/index.js +0 -62
  33. package/core/mcp-config.js +0 -115
  34. package/core/policies.d.ts +0 -43
  35. package/core/policies.js +0 -113
  36. package/core/policy-matrix.js +0 -303
  37. package/core/project-activity.js +0 -175
  38. package/core/redaction.d.ts +0 -5
  39. package/core/redaction.js +0 -63
  40. package/core/self-update.js +0 -259
  41. package/core/session.js +0 -353
  42. package/core/task-extractor.js +0 -1098
  43. package/core/telemetry.d.ts +0 -55
  44. package/core/telemetry.js +0 -617
  45. package/core/tier-enforcement.js +0 -928
  46. package/core/utils.d.ts +0 -90
  47. package/core/utils.js +0 -455
  48. package/core/validation.js +0 -572
  49. package/mcp/server.d.ts +0 -57
  50. package/mcp/server.js +0 -264
@@ -60,7 +60,7 @@ class ApiDocsGenerator {
60
60
  if (fs.existsSync(this.apiDataPath)) {
61
61
  return JSON.parse(fs.readFileSync(this.apiDataPath, 'utf-8'));
62
62
  }
63
- } catch (err) {
63
+ } catch (_err) {
64
64
  // Return default
65
65
  }
66
66
 
@@ -102,7 +102,7 @@ class ApiDocsGenerator {
102
102
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
103
103
  return pkg.name || 'API';
104
104
  }
105
- } catch (err) {
105
+ } catch (_err) {
106
106
  // Default
107
107
  }
108
108
  return 'API';
@@ -64,7 +64,7 @@ class DecisionsGenerator {
64
64
  if (fs.existsSync(this.decisionsPath)) {
65
65
  return JSON.parse(fs.readFileSync(this.decisionsPath, 'utf-8'));
66
66
  }
67
- } catch (err) {
67
+ } catch (_err) {
68
68
  // Return default
69
69
  }
70
70
 
@@ -103,7 +103,7 @@ class DecisionsGenerator {
103
103
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
104
104
  return pkg.name || 'Project';
105
105
  }
106
- } catch (err) {
106
+ } catch (_err) {
107
107
  // Default
108
108
  }
109
109
  return 'Project';
@@ -582,7 +582,7 @@ ${decision.links.map(l => `- [${l.title || l.url}](${l.url})`).join('\n')}
582
582
  });
583
583
  }
584
584
  }
585
- } catch (err) {
585
+ } catch (_err) {
586
586
  // Decision intelligence not available
587
587
  }
588
588
 
@@ -52,7 +52,7 @@ class HealthGenerator {
52
52
  if (fs.existsSync(this.healthDataPath)) {
53
53
  return JSON.parse(fs.readFileSync(this.healthDataPath, 'utf-8'));
54
54
  }
55
- } catch (err) {
55
+ } catch (_err) {
56
56
  // Return default
57
57
  }
58
58
 
@@ -89,7 +89,7 @@ class HealthGenerator {
89
89
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
90
90
  return pkg.name || 'Project';
91
91
  }
92
- } catch (err) {
92
+ } catch (_err) {
93
93
  // Default
94
94
  }
95
95
  return 'Project';
@@ -144,7 +144,7 @@ class HealthGenerator {
144
144
  metrics.linting.warnings = results.reduce((sum, r) => sum + r.warningCount, 0);
145
145
  metrics.linting.passed = metrics.linting.errors === 0;
146
146
  metrics.filesAnalyzed = results.length;
147
- } catch (err) {
147
+ } catch (_err) {
148
148
  // ESLint failed or not configured
149
149
  }
150
150
  }
@@ -156,7 +156,7 @@ class HealthGenerator {
156
156
  try {
157
157
  const tsConfigContent = JSON.parse(fs.readFileSync(tsConfig, 'utf-8'));
158
158
  metrics.typescript.strict = tsConfigContent.compilerOptions?.strict === true;
159
- } catch (err) {
159
+ } catch (_err) {
160
160
  // Ignore
161
161
  }
162
162
 
@@ -168,7 +168,7 @@ class HealthGenerator {
168
168
  });
169
169
  const errorCount = (output.match(/error TS\d+:/g) || []).length;
170
170
  metrics.typescript.errors = errorCount;
171
- } catch (err) {
171
+ } catch (_err) {
172
172
  // TypeScript check failed
173
173
  }
174
174
  }
@@ -189,7 +189,7 @@ class HealthGenerator {
189
189
  }
190
190
 
191
191
  metrics.score = Math.max(0, Math.min(100, Math.round(score)));
192
- } catch (err) {
192
+ } catch (_err) {
193
193
  metrics.score = 50; // Default if analysis fails
194
194
  }
195
195
 
@@ -240,7 +240,7 @@ class HealthGenerator {
240
240
  functions: coverage.total.functions?.pct || 0
241
241
  };
242
242
  }
243
- } catch (err) {
243
+ } catch (_err) {
244
244
  // Ignore
245
245
  }
246
246
  }
@@ -266,7 +266,7 @@ class HealthGenerator {
266
266
  // No tests
267
267
  metrics.score = 0;
268
268
  }
269
- } catch (err) {
269
+ } catch (_err) {
270
270
  metrics.score = 0;
271
271
  }
272
272
 
@@ -310,7 +310,7 @@ class HealthGenerator {
310
310
  wanted: outdated[name].wanted,
311
311
  latest: outdated[name].latest
312
312
  }));
313
- } catch (err) {
313
+ } catch (_err) {
314
314
  // npm outdated failed
315
315
  }
316
316
 
@@ -325,7 +325,7 @@ class HealthGenerator {
325
325
  if (audit.metadata?.vulnerabilities) {
326
326
  metrics.vulnerabilities = audit.metadata.vulnerabilities;
327
327
  }
328
- } catch (err) {
328
+ } catch (_err) {
329
329
  // npm audit failed
330
330
  }
331
331
  }
@@ -343,7 +343,7 @@ class HealthGenerator {
343
343
  score -= Math.min(15, metrics.outdated.length * 0.5);
344
344
 
345
345
  metrics.score = Math.max(0, Math.min(100, Math.round(score)));
346
- } catch (err) {
346
+ } catch (_err) {
347
347
  metrics.score = 50;
348
348
  }
349
349
 
@@ -391,7 +391,7 @@ class HealthGenerator {
391
391
  metrics.secretsExposed += realMatches.length;
392
392
  }
393
393
  }
394
- } catch (err) {
394
+ } catch (_err) {
395
395
  // Skip file
396
396
  }
397
397
  }
@@ -447,7 +447,7 @@ class HealthGenerator {
447
447
  }
448
448
 
449
449
  metrics.score = Math.max(0, Math.min(100, Math.round(score)));
450
- } catch (err) {
450
+ } catch (_err) {
451
451
  metrics.score = 50;
452
452
  }
453
453
 
@@ -482,7 +482,7 @@ class HealthGenerator {
482
482
  const size = this.getDirectorySize(buildPath);
483
483
  metrics.bundleSize = size;
484
484
  break;
485
- } catch (err) {
485
+ } catch (_err) {
486
486
  // Ignore
487
487
  }
488
488
  }
@@ -513,7 +513,7 @@ class HealthGenerator {
513
513
  }
514
514
 
515
515
  metrics.score = Math.min(100, metrics.score);
516
- } catch (err) {
516
+ } catch (_err) {
517
517
  // Keep default score
518
518
  }
519
519
 
@@ -844,7 +844,7 @@ Functions: ${this.generateProgressBar(coverage.functions)} ${coverage.functions
844
844
  }
845
845
  }
846
846
  }
847
- } catch (err) {
847
+ } catch (_err) {
848
848
  // Skip inaccessible directories
849
849
  }
850
850
  };
@@ -70,7 +70,7 @@ class SprintGenerator {
70
70
  if (fs.existsSync(this.sprintDataPath)) {
71
71
  return JSON.parse(fs.readFileSync(this.sprintDataPath, 'utf-8'));
72
72
  }
73
- } catch (err) {
73
+ } catch (_err) {
74
74
  // Return default
75
75
  }
76
76
 
@@ -126,7 +126,7 @@ class SprintGenerator {
126
126
  const history = JSON.parse(fs.readFileSync(historyPath, 'utf-8'));
127
127
  return (history.sprints?.length || 0) + 1;
128
128
  }
129
- } catch (err) {
129
+ } catch (_err) {
130
130
  // Return default
131
131
  }
132
132
  return 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@girardmedia/bootspring",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Thin client for Bootspring cloud MCP, hosted agents, and paywalled workflow intelligence",
5
5
  "keywords": [
6
6
  "ai",
@@ -17,80 +17,44 @@
17
17
  "license": "SEE LICENSE IN LICENSE",
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "https://github.com/bootspring/bootspring.git"
20
+ "url": "git+https://github.com/Girard-Media/bootspring.git"
21
21
  },
22
22
  "homepage": "https://bootspring.com",
23
23
  "bugs": {
24
- "url": "https://github.com/bootspring/bootspring/issues"
24
+ "url": "https://github.com/Girard-Media/bootspring/issues"
25
25
  },
26
26
  "bin": {
27
- "bootspring": "./bin/bootspring.js"
27
+ "bootspring": "bin/bootspring.js"
28
28
  },
29
- "main": "./core/index.js",
30
- "types": "./core/index.d.ts",
29
+ "main": "./dist/core.js",
30
+ "types": "./dist/core/index.d.ts",
31
31
  "exports": {
32
32
  ".": {
33
- "types": "./core/index.d.ts",
34
- "default": "./core/index.js"
33
+ "types": "./dist/core/index.d.ts",
34
+ "default": "./dist/core.js"
35
35
  },
36
36
  "./mcp": {
37
- "types": "./mcp/server.d.ts",
38
- "default": "./mcp/server.js"
39
- },
40
- "./auth": {
41
- "types": "./core/auth.d.ts",
42
- "default": "./core/auth.js"
43
- },
44
- "./api": {
45
- "types": "./core/api-client.d.ts",
46
- "default": "./core/api-client.js"
37
+ "types": "./dist/mcp/index.d.ts",
38
+ "default": "./dist/mcp-server.js"
47
39
  }
48
40
  },
49
41
  "files": [
50
42
  "bin/bootspring.js",
51
- "monorepo/apps/cli/dist/",
52
- "core/api-client.d.ts",
53
- "core/api-client.js",
54
- "core/auth.d.ts",
55
- "core/auth.js",
56
- "core/build-orchestrator.js",
57
- "core/build-state.js",
58
- "core/config.d.ts",
59
- "core/config.js",
60
- "core/context-loader.js",
61
- "core/context.d.ts",
62
- "core/context.js",
63
- "core/entitlements.d.ts",
64
- "core/entitlements.js",
65
- "core/index.d.ts",
66
- "core/index.js",
67
- "core/mcp-config.js",
68
- "core/policies.d.ts",
69
- "core/policies.js",
70
- "core/policy-matrix.js",
71
- "core/project-activity.js",
72
- "core/redaction.d.ts",
73
- "core/redaction.js",
74
- "core/self-update.js",
75
- "core/session.js",
76
- "core/task-extractor.js",
77
- "core/telemetry.d.ts",
78
- "core/telemetry.js",
79
- "core/tier-enforcement.js",
80
- "core/utils.d.ts",
81
- "core/utils.js",
82
- "core/validation.js",
83
- "mcp/server.d.ts",
84
- "mcp/server.js",
43
+ "dist/cli/index.cjs",
44
+ "dist/core.js",
45
+ "dist/mcp-server.js",
46
+ "dist/core/index.d.ts",
47
+ "dist/mcp/index.d.ts",
85
48
  "generators/",
86
- "generators/templates/build-planning.template.js",
49
+ "claude-commands/",
87
50
  "scripts/postinstall.js"
88
51
  ],
89
52
  "scripts": {
90
53
  "postinstall": "node scripts/postinstall.js",
91
54
  "start": "node bin/bootspring.js",
92
55
  "dashboard": "node bin/bootspring.js dashboard",
93
- "mcp": "node mcp/server.js",
56
+ "mcp": "node dist/mcp-server.js",
57
+ "pretest": "npm run build",
94
58
  "test": "vitest run",
95
59
  "test:launch-smoke": "vitest run __tests__/unit/cli-first-run-smoke.test.js __tests__/unit/health-fresh-start.test.ts __tests__/unit/session-project-scope.test.ts __tests__/unit/auth-cli-mixed-states.test.ts __tests__/unit/api-client-project-auth-fallback.test.js __tests__/unit/cli-help-surface.test.js __tests__/unit/cli-command-manifest.test.js",
96
60
  "test:seed-ingestion": "vitest run __tests__/unit/seed-ingestion-regression.test.js",
@@ -100,12 +64,14 @@
100
64
  "lint:fix": "eslint . --fix",
101
65
  "typecheck": "tsc --noEmit",
102
66
  "typecheck:active": "tsc --noEmit -p tsconfig.active.json",
103
- "build": "tsup",
67
+ "build": "tsup && npm run build:cli",
68
+ "build:cli": "cd monorepo && pnpm build --filter @bootspring/cli && cd .. && mkdir -p dist/cli && cp monorepo/apps/cli/dist/index.cjs dist/cli/index.cjs",
104
69
  "build:watch": "tsup --watch",
105
70
  "dev": "tsx watch src/index.ts",
106
71
  "verify:lint-budget": "node scripts/check-lint-budgets.js",
107
72
  "verify:release-gates": "node scripts/release-gate-check.js",
108
73
  "verify:shared-contracts": "node scripts/verify-shared-contracts.js",
74
+ "verify:thin-client-contract": "node scripts/verify-thin-client-contract.js",
109
75
  "build:mcp-contract": "node scripts/export-mcp-contract.js",
110
76
  "verify:mcp-contract": "node scripts/export-mcp-contract.js --check",
111
77
  "planning:sync": "node scripts/sync-planning-queue.js",
@@ -114,26 +80,28 @@
114
80
  "verify:package": "node scripts/check-package-boundaries.js",
115
81
  "db:sync": "node shared/db/sync.js",
116
82
  "db:sync:check": "node shared/db/sync.js --check",
117
- "prepublishOnly": "npm test && npm run lint --if-present && npm run verify:package && npm run verify:mcp-contract"
83
+ "prepublishOnly": "npm run build && npm test && npm run lint --if-present && npm run verify:package && npm run verify:mcp-contract"
118
84
  },
119
85
  "devDependencies": {
120
86
  "@eslint/js": "^9.39.2",
121
87
  "@swc/core": "^1.15.13",
122
88
  "@types/node": "^25.3.1",
89
+ "@typescript-eslint/eslint-plugin": "^8.57.0",
90
+ "@typescript-eslint/parser": "^8.57.0",
123
91
  "@vitest/coverage-v8": "^4.0.18",
124
92
  "eslint": "^9.39.2",
125
93
  "globals": "^17.3.0",
126
94
  "tsup": "^8.5.1",
127
95
  "tsx": "^4.21.0",
128
96
  "typescript": "^5.9.3",
129
- "vitest": "^4.0.18",
130
- "zod": "^4.3.6"
97
+ "vitest": "^4.0.18"
131
98
  },
132
99
  "dependencies": {
133
100
  "@modelcontextprotocol/sdk": "^1.0.0",
134
101
  "jsonwebtoken": "^9.0.3",
135
102
  "ws": "^8.18.0",
136
- "yaml": "^2.8.0"
103
+ "yaml": "^2.8.0",
104
+ "zod": "^4.3.6"
137
105
  },
138
106
  "engines": {
139
107
  "node": ">=18.0.0"
@@ -1,69 +0,0 @@
1
- /**
2
- * Bootspring API Client Types
3
- * @module core/api-client
4
- */
5
-
6
- export interface RequestOptions {
7
- method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
8
- body?: unknown;
9
- headers?: Record<string, string>;
10
- cache?: boolean;
11
- cacheTTL?: number;
12
- }
13
-
14
- export interface ApiResponse<T = unknown> {
15
- data?: T;
16
- error?: string;
17
- status: number;
18
- }
19
-
20
- /** API base URL */
21
- export const API_BASE: string;
22
-
23
- /** API version */
24
- export const API_VERSION: string;
25
-
26
- /**
27
- * Make an API request
28
- * @param endpoint - API endpoint (without base URL)
29
- * @param options - Request options
30
- * @returns API response
31
- */
32
- export function request<T = unknown>(
33
- endpoint: string,
34
- options?: RequestOptions
35
- ): Promise<ApiResponse<T>>;
36
-
37
- /** Clear API response cache */
38
- export function clearCache(): void;
39
-
40
- /**
41
- * Check API health
42
- * @returns Health check result
43
- */
44
- export function healthCheck(): Promise<{ ok: boolean; latency?: number }>;
45
-
46
- /**
47
- * Decorator to require authentication for API calls
48
- * @param fn - Function to wrap
49
- * @returns Wrapped function that checks auth first
50
- */
51
- export function requireAuth<T extends (...args: unknown[]) => unknown>(fn: T): T;
52
-
53
- // API endpoints
54
- export namespace api {
55
- /** Get current user profile */
56
- function getProfile(): Promise<ApiResponse>;
57
-
58
- /** Get user entitlements */
59
- function getEntitlements(): Promise<ApiResponse>;
60
-
61
- /** Verify license key */
62
- function verifyLicense(key: string): Promise<ApiResponse>;
63
-
64
- /** Get available skills */
65
- function getSkills(): Promise<ApiResponse>;
66
-
67
- /** Get available workflows */
68
- function getWorkflows(): Promise<ApiResponse>;
69
- }