@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.
- package/bin/bootspring.js +5 -0
- package/cli/org.js +474 -0
- package/cli/preseed/index.js +16 -0
- package/cli/preseed/interactive.js +143 -0
- package/cli/preseed/templates.js +227 -0
- package/cli/preseed.js +9 -301
- package/cli/seed/builders/ai-context-builder.js +85 -0
- package/cli/seed/builders/index.js +13 -0
- package/cli/seed/builders/seed-builder.js +272 -0
- package/cli/seed/extractors/content-extractors.js +383 -0
- package/cli/seed/extractors/index.js +47 -0
- package/cli/seed/extractors/metadata-extractors.js +167 -0
- package/cli/seed/extractors/section-extractor.js +54 -0
- package/cli/seed/extractors/stack-extractors.js +228 -0
- package/cli/seed/index.js +18 -0
- package/cli/seed/utils/folder-structure.js +84 -0
- package/cli/seed/utils/index.js +11 -0
- package/cli/seed.js +23 -1074
- package/core/api-client.js +77 -0
- package/core/entitlements.js +36 -0
- package/core/organizations.js +223 -0
- package/core/policies.js +51 -6
- package/core/policy-matrix.js +303 -0
- package/core/project-context.js +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +3220 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/context-McpJQa_2.d.ts +5710 -0
- package/dist/core/index.d.ts +635 -0
- package/dist/core/index.js +2593 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index-QqbeEiDm.d.ts +857 -0
- package/dist/index-UiYCgwiH.d.ts +174 -0
- package/dist/index.d.ts +453 -0
- package/dist/index.js +44228 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +41173 -0
- package/dist/mcp/index.js.map +1 -0
- package/generators/index.ts +82 -0
- package/intelligence/orchestrator/config/failure-signatures.js +48 -0
- package/intelligence/orchestrator/config/index.js +23 -0
- package/intelligence/orchestrator/config/pack-lifecycle.js +262 -0
- package/intelligence/orchestrator/config/phases.js +111 -0
- package/intelligence/orchestrator/config/remediation.js +150 -0
- package/intelligence/orchestrator/config/workflows.js +168 -0
- package/intelligence/orchestrator/core/index.js +16 -0
- package/intelligence/orchestrator/core/state-manager.js +88 -0
- package/intelligence/orchestrator/core/telemetry.js +24 -0
- package/intelligence/orchestrator/index.js +17 -0
- package/intelligence/orchestrator.js +17 -512
- package/mcp/contracts/mcp-contract.v1.json +1 -1
- package/package.json +16 -3
- package/src/cli/agent.ts +703 -0
- package/src/cli/analyze.ts +640 -0
- package/src/cli/audit.ts +707 -0
- package/src/cli/auth.ts +930 -0
- package/src/cli/billing.ts +364 -0
- package/src/cli/build.ts +1089 -0
- package/src/cli/business.ts +508 -0
- package/src/cli/checkpoint-utils.ts +236 -0
- package/src/cli/checkpoint.ts +757 -0
- package/src/cli/cloud-sync.ts +534 -0
- package/src/cli/content.ts +273 -0
- package/src/cli/context.ts +667 -0
- package/src/cli/dashboard.ts +133 -0
- package/src/cli/deploy.ts +704 -0
- package/src/cli/doctor.ts +480 -0
- package/src/cli/fundraise.ts +494 -0
- package/src/cli/generate.ts +346 -0
- package/src/cli/github-cmd.ts +566 -0
- package/src/cli/health.ts +599 -0
- package/src/cli/index.ts +113 -0
- package/src/cli/init.ts +838 -0
- package/src/cli/legal.ts +495 -0
- package/src/cli/log.ts +316 -0
- package/src/cli/loop.ts +1660 -0
- package/src/cli/manager.ts +878 -0
- package/src/cli/mcp.ts +275 -0
- package/src/cli/memory.ts +346 -0
- package/src/cli/metrics.ts +590 -0
- package/src/cli/monitor.ts +960 -0
- package/src/cli/mvp.ts +662 -0
- package/src/cli/onboard.ts +663 -0
- package/src/cli/orchestrator.ts +622 -0
- package/src/cli/plugin.ts +483 -0
- package/src/cli/prd.ts +671 -0
- package/src/cli/preseed-start.ts +1633 -0
- package/src/cli/preseed.ts +2434 -0
- package/src/cli/project.ts +526 -0
- package/src/cli/quality.ts +885 -0
- package/src/cli/security.ts +1079 -0
- package/src/cli/seed.ts +1224 -0
- package/src/cli/skill.ts +537 -0
- package/src/cli/suggest.ts +1225 -0
- package/src/cli/switch.ts +518 -0
- package/src/cli/task.ts +780 -0
- package/src/cli/telemetry.ts +172 -0
- package/src/cli/todo.ts +627 -0
- package/src/cli/types.ts +15 -0
- package/src/cli/update.ts +334 -0
- package/src/cli/visualize.ts +609 -0
- package/src/cli/watch.ts +895 -0
- package/src/cli/workspace.ts +709 -0
- package/src/core/action-recorder.ts +673 -0
- package/src/core/analyze-workflow.ts +1453 -0
- package/src/core/api-client.ts +1120 -0
- package/src/core/audit-workflow.ts +1681 -0
- package/src/core/auth.ts +471 -0
- package/src/core/build-orchestrator.ts +509 -0
- package/src/core/build-state.ts +621 -0
- package/src/core/checkpoint-engine.ts +482 -0
- package/src/core/config.ts +1285 -0
- package/src/core/context-loader.ts +694 -0
- package/src/core/context.ts +410 -0
- package/src/core/deploy-workflow.ts +1085 -0
- package/src/core/entitlements.ts +322 -0
- package/src/core/github-sync.ts +720 -0
- package/src/core/index.ts +981 -0
- package/src/core/ingest.ts +1186 -0
- package/src/core/metrics-engine.ts +886 -0
- package/src/core/mvp.ts +847 -0
- package/src/core/onboard-workflow.ts +1293 -0
- package/src/core/policies.ts +81 -0
- package/src/core/preseed-workflow.ts +1163 -0
- package/src/core/preseed.ts +1826 -0
- package/src/core/project-context.ts +380 -0
- package/src/core/project-state.ts +699 -0
- package/src/core/r2-sync.ts +691 -0
- package/src/core/scaffold.ts +1715 -0
- package/src/core/session.ts +286 -0
- package/src/core/task-extractor.ts +799 -0
- package/src/core/telemetry.ts +371 -0
- package/src/core/tier-enforcement.ts +737 -0
- package/src/core/utils.ts +437 -0
- package/src/index.ts +29 -0
- package/src/intelligence/agent-collab.ts +2376 -0
- package/src/intelligence/auto-suggest.ts +713 -0
- package/src/intelligence/content-gen.ts +1351 -0
- package/src/intelligence/cross-project.ts +1692 -0
- package/src/intelligence/git-memory.ts +529 -0
- package/src/intelligence/index.ts +318 -0
- package/src/intelligence/orchestrator.ts +534 -0
- package/src/intelligence/prd.ts +466 -0
- package/src/intelligence/recommendations.ts +982 -0
- package/src/intelligence/workflow-composer.ts +1472 -0
- package/src/mcp/capabilities.ts +233 -0
- package/src/mcp/index.ts +37 -0
- package/src/mcp/registry.ts +1268 -0
- package/src/mcp/response-formatter.ts +797 -0
- package/src/mcp/server.ts +240 -0
- package/src/types/agent.ts +69 -0
- package/src/types/config.ts +86 -0
- package/src/types/context.ts +77 -0
- package/src/types/index.ts +53 -0
- package/src/types/mcp.ts +91 -0
- package/src/types/skills.ts +47 -0
- package/src/types/workflow.ts +155 -0
- package/generators/index.js +0 -18
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootspring GitHub Command
|
|
3
|
+
* Manage GitHub integration
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* connect [--url] Connect to a GitHub repository
|
|
7
|
+
* sync Sync latest commits, PRs, and stats
|
|
8
|
+
* status Show connection status and recent activity
|
|
9
|
+
* disconnect Remove GitHub connection
|
|
10
|
+
* activity Show recent repository activity
|
|
11
|
+
*
|
|
12
|
+
* @package bootspring
|
|
13
|
+
* @command github
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// Type interfaces for JS modules
|
|
17
|
+
interface Colors {
|
|
18
|
+
reset: string;
|
|
19
|
+
bold: string;
|
|
20
|
+
dim: string;
|
|
21
|
+
cyan: string;
|
|
22
|
+
green: string;
|
|
23
|
+
yellow: string;
|
|
24
|
+
red: string;
|
|
25
|
+
magenta: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface PrintModule {
|
|
29
|
+
error(msg: string): void;
|
|
30
|
+
dim(msg: string): void;
|
|
31
|
+
warning(msg: string): void;
|
|
32
|
+
success(msg: string): void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface Spinner {
|
|
36
|
+
start(): Spinner;
|
|
37
|
+
stop(): void;
|
|
38
|
+
succeed(text: string): void;
|
|
39
|
+
fail(text: string): void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface ParsedArgs {
|
|
43
|
+
_: string[];
|
|
44
|
+
url?: string | undefined;
|
|
45
|
+
json?: boolean | undefined;
|
|
46
|
+
limit?: string | undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface UtilsModule {
|
|
50
|
+
COLORS: Colors;
|
|
51
|
+
print: PrintModule;
|
|
52
|
+
createSpinner(text: string): Spinner;
|
|
53
|
+
parseArgs(args: string[]): ParsedArgs;
|
|
54
|
+
formatRelativeTime(date: Date): string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface ConfigModule {
|
|
58
|
+
load(): LoadedConfig;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface LoadedConfig {
|
|
62
|
+
_projectRoot: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface GitHubStats {
|
|
66
|
+
totalCommits: number | string;
|
|
67
|
+
openPRs: number;
|
|
68
|
+
closedPRs?: number | undefined;
|
|
69
|
+
contributors: number | string;
|
|
70
|
+
lastCommit?: string | undefined;
|
|
71
|
+
lastCommitSha?: string | undefined;
|
|
72
|
+
lastCommitMessage?: string | undefined;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
interface ConnectResult {
|
|
76
|
+
success: boolean;
|
|
77
|
+
error?: string | undefined;
|
|
78
|
+
owner?: string | undefined;
|
|
79
|
+
repo?: string | undefined;
|
|
80
|
+
url?: string | undefined;
|
|
81
|
+
defaultBranch?: string | undefined;
|
|
82
|
+
isPrivate?: boolean | undefined;
|
|
83
|
+
description?: string | undefined;
|
|
84
|
+
stats?: GitHubStats | undefined;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface SyncResult {
|
|
88
|
+
success: boolean;
|
|
89
|
+
error?: string | undefined;
|
|
90
|
+
stats: GitHubStats;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface DisconnectResult {
|
|
94
|
+
success: boolean;
|
|
95
|
+
error?: string | undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface DetectedRepo {
|
|
99
|
+
owner: string;
|
|
100
|
+
repo: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface GitHubStatus {
|
|
104
|
+
ghInstalled: boolean;
|
|
105
|
+
ghAuthenticated: boolean;
|
|
106
|
+
connected: boolean;
|
|
107
|
+
owner?: string | undefined;
|
|
108
|
+
repo?: string | undefined;
|
|
109
|
+
repositoryUrl?: string | undefined;
|
|
110
|
+
defaultBranch?: string | undefined;
|
|
111
|
+
lastSync?: string | undefined;
|
|
112
|
+
stats?: GitHubStats | undefined;
|
|
113
|
+
detected?: DetectedRepo | undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
interface ActivityItem {
|
|
117
|
+
type: 'commit' | 'pr';
|
|
118
|
+
date: string;
|
|
119
|
+
sha?: string | undefined;
|
|
120
|
+
message?: string | undefined;
|
|
121
|
+
author?: string | undefined;
|
|
122
|
+
number?: number | undefined;
|
|
123
|
+
title?: string | undefined;
|
|
124
|
+
state?: string | undefined;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
interface GitHubSyncModule {
|
|
128
|
+
isGhInstalled(): boolean;
|
|
129
|
+
isGhAuthenticated(): boolean;
|
|
130
|
+
connectRepository(projectRoot: string, options: { url?: string | null | undefined }): ConnectResult;
|
|
131
|
+
syncGitHubData(projectRoot: string): SyncResult;
|
|
132
|
+
getStatus(projectRoot: string): GitHubStatus;
|
|
133
|
+
disconnectRepository(projectRoot: string): DisconnectResult;
|
|
134
|
+
getRecentActivity(owner: string, repo: string, limit: number): ActivityItem[];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
interface TelemetryModule {
|
|
138
|
+
emitEvent(event: string, data: Record<string, unknown>, options: { projectRoot: string }): void;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const config = require('../core/config') as ConfigModule;
|
|
142
|
+
const utils = require('../core/utils') as UtilsModule;
|
|
143
|
+
const githubSync = require('../core/github-sync') as GitHubSyncModule;
|
|
144
|
+
const telemetry = require('../core/telemetry') as TelemetryModule;
|
|
145
|
+
|
|
146
|
+
// ============================================================================
|
|
147
|
+
// Command Handlers
|
|
148
|
+
// ============================================================================
|
|
149
|
+
|
|
150
|
+
interface ConnectOptions {
|
|
151
|
+
url?: string | null | undefined;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Connect to a GitHub repository
|
|
156
|
+
*/
|
|
157
|
+
function handleConnect(projectRoot: string, options: ConnectOptions = {}): void {
|
|
158
|
+
console.log(`
|
|
159
|
+
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ GitHub Connection${utils.COLORS.reset}
|
|
160
|
+
`);
|
|
161
|
+
|
|
162
|
+
// Check gh CLI
|
|
163
|
+
if (!githubSync.isGhInstalled()) {
|
|
164
|
+
utils.print.error('GitHub CLI (gh) is not installed.');
|
|
165
|
+
console.log(`
|
|
166
|
+
${utils.COLORS.bold}To install gh CLI:${utils.COLORS.reset}
|
|
167
|
+
macOS: brew install gh
|
|
168
|
+
Windows: winget install GitHub.cli
|
|
169
|
+
Linux: See https://cli.github.com/
|
|
170
|
+
|
|
171
|
+
${utils.COLORS.dim}Or visit: https://cli.github.com/${utils.COLORS.reset}
|
|
172
|
+
`);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!githubSync.isGhAuthenticated()) {
|
|
177
|
+
utils.print.error('GitHub CLI is not authenticated.');
|
|
178
|
+
console.log(`
|
|
179
|
+
${utils.COLORS.bold}To authenticate:${utils.COLORS.reset}
|
|
180
|
+
gh auth login
|
|
181
|
+
|
|
182
|
+
${utils.COLORS.dim}Follow the prompts to authenticate with GitHub.${utils.COLORS.reset}
|
|
183
|
+
`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Try to connect
|
|
188
|
+
const spinner = utils.createSpinner('Connecting to GitHub...');
|
|
189
|
+
spinner.start();
|
|
190
|
+
|
|
191
|
+
const result = githubSync.connectRepository(projectRoot, {
|
|
192
|
+
url: options.url
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
if (!result.success) {
|
|
196
|
+
spinner.fail(`Connection failed: ${result.error}`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
spinner.succeed('Connected to GitHub!');
|
|
201
|
+
|
|
202
|
+
console.log(`
|
|
203
|
+
${utils.COLORS.bold}Repository:${utils.COLORS.reset} ${result.owner}/${result.repo}
|
|
204
|
+
${utils.COLORS.bold}URL:${utils.COLORS.reset} ${result.url}
|
|
205
|
+
${utils.COLORS.bold}Branch:${utils.COLORS.reset} ${result.defaultBranch}
|
|
206
|
+
${result.isPrivate ? `${utils.COLORS.dim}(Private repository)${utils.COLORS.reset}` : ''}
|
|
207
|
+
${result.description ? `${utils.COLORS.dim}${result.description}${utils.COLORS.reset}` : ''}
|
|
208
|
+
`);
|
|
209
|
+
|
|
210
|
+
if (result.stats) {
|
|
211
|
+
console.log(`${utils.COLORS.bold}Statistics:${utils.COLORS.reset}`);
|
|
212
|
+
console.log(` Commits: ${result.stats.totalCommits || 'N/A'}`);
|
|
213
|
+
console.log(` Open PRs: ${result.stats.openPRs || 0}`);
|
|
214
|
+
console.log(` Contributors: ${result.stats.contributors || 'N/A'}`);
|
|
215
|
+
|
|
216
|
+
if (result.stats.lastCommitMessage) {
|
|
217
|
+
console.log(`\n${utils.COLORS.bold}Latest Commit:${utils.COLORS.reset}`);
|
|
218
|
+
console.log(` ${utils.COLORS.dim}${result.stats.lastCommitSha}${utils.COLORS.reset} ${result.stats.lastCommitMessage}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
console.log();
|
|
223
|
+
|
|
224
|
+
// Emit telemetry
|
|
225
|
+
telemetry.emitEvent('github:connect', {
|
|
226
|
+
owner: result.owner,
|
|
227
|
+
repo: result.repo,
|
|
228
|
+
isPrivate: result.isPrivate
|
|
229
|
+
}, { projectRoot });
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
interface SyncOptions {
|
|
233
|
+
json?: boolean | undefined;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Sync GitHub data
|
|
238
|
+
*/
|
|
239
|
+
function handleSync(projectRoot: string, options: SyncOptions = {}): void {
|
|
240
|
+
const status = githubSync.getStatus(projectRoot);
|
|
241
|
+
|
|
242
|
+
if (!status.connected) {
|
|
243
|
+
utils.print.error('GitHub not connected.');
|
|
244
|
+
utils.print.dim('Run: bootspring github connect');
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const spinner = utils.createSpinner(`Syncing ${status.owner}/${status.repo}...`);
|
|
249
|
+
spinner.start();
|
|
250
|
+
|
|
251
|
+
const result = githubSync.syncGitHubData(projectRoot);
|
|
252
|
+
|
|
253
|
+
if (!result.success) {
|
|
254
|
+
spinner.fail(`Sync failed: ${result.error}`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
spinner.succeed('Synced GitHub data!');
|
|
259
|
+
|
|
260
|
+
if (options.json) {
|
|
261
|
+
console.log(JSON.stringify(result.stats, null, 2));
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
console.log(`
|
|
266
|
+
${utils.COLORS.bold}Statistics:${utils.COLORS.reset}
|
|
267
|
+
Commits: ${result.stats.totalCommits}
|
|
268
|
+
Open PRs: ${result.stats.openPRs}
|
|
269
|
+
Closed PRs: ${result.stats.closedPRs}
|
|
270
|
+
Contributors: ${result.stats.contributors}
|
|
271
|
+
`);
|
|
272
|
+
|
|
273
|
+
if (result.stats.lastCommitMessage) {
|
|
274
|
+
console.log(`${utils.COLORS.bold}Latest Commit:${utils.COLORS.reset}`);
|
|
275
|
+
console.log(` ${utils.COLORS.dim}${result.stats.lastCommitSha}${utils.COLORS.reset} ${result.stats.lastCommitMessage}`);
|
|
276
|
+
if (result.stats.lastCommit) {
|
|
277
|
+
const date = new Date(result.stats.lastCommit);
|
|
278
|
+
console.log(` ${utils.COLORS.dim}${utils.formatRelativeTime(date)}${utils.COLORS.reset}`);
|
|
279
|
+
}
|
|
280
|
+
console.log();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Emit telemetry
|
|
284
|
+
telemetry.emitEvent('github:sync', {
|
|
285
|
+
owner: status.owner,
|
|
286
|
+
repo: status.repo,
|
|
287
|
+
stats: result.stats
|
|
288
|
+
}, { projectRoot });
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
interface StatusOptions {
|
|
292
|
+
json?: boolean | undefined;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Show GitHub status
|
|
297
|
+
*/
|
|
298
|
+
function handleStatus(projectRoot: string, options: StatusOptions = {}): void {
|
|
299
|
+
const status = githubSync.getStatus(projectRoot);
|
|
300
|
+
|
|
301
|
+
// JSON output
|
|
302
|
+
if (options.json) {
|
|
303
|
+
console.log(JSON.stringify(status, null, 2));
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
console.log(`
|
|
308
|
+
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ GitHub Status${utils.COLORS.reset}
|
|
309
|
+
`);
|
|
310
|
+
|
|
311
|
+
// CLI status
|
|
312
|
+
console.log(`${utils.COLORS.bold}GitHub CLI:${utils.COLORS.reset}`);
|
|
313
|
+
console.log(` ${status.ghInstalled ? `${utils.COLORS.green}✓${utils.COLORS.reset}` : `${utils.COLORS.red}✗${utils.COLORS.reset}`} Installed`);
|
|
314
|
+
console.log(` ${status.ghAuthenticated ? `${utils.COLORS.green}✓${utils.COLORS.reset}` : `${utils.COLORS.red}✗${utils.COLORS.reset}`} Authenticated`);
|
|
315
|
+
console.log();
|
|
316
|
+
|
|
317
|
+
if (!status.connected) {
|
|
318
|
+
console.log(`${utils.COLORS.bold}Connection:${utils.COLORS.reset} ${utils.COLORS.dim}Not connected${utils.COLORS.reset}`);
|
|
319
|
+
|
|
320
|
+
if (status.detected) {
|
|
321
|
+
console.log(`\n${utils.COLORS.bold}Detected Repository:${utils.COLORS.reset}`);
|
|
322
|
+
console.log(` ${status.detected.owner}/${status.detected.repo}`);
|
|
323
|
+
console.log(`\n${utils.COLORS.bold}To connect:${utils.COLORS.reset}`);
|
|
324
|
+
console.log(' bootspring github connect');
|
|
325
|
+
} else {
|
|
326
|
+
console.log(`\n${utils.COLORS.bold}To connect:${utils.COLORS.reset}`);
|
|
327
|
+
console.log(' bootspring github connect --url https://github.com/owner/repo');
|
|
328
|
+
}
|
|
329
|
+
console.log();
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Connected status
|
|
334
|
+
console.log(`${utils.COLORS.bold}Connection:${utils.COLORS.reset} ${utils.COLORS.green}✓ Connected${utils.COLORS.reset}`);
|
|
335
|
+
console.log(`${utils.COLORS.bold}Repository:${utils.COLORS.reset} ${status.owner}/${status.repo}`);
|
|
336
|
+
console.log(`${utils.COLORS.bold}URL:${utils.COLORS.reset} ${status.repositoryUrl}`);
|
|
337
|
+
console.log(`${utils.COLORS.bold}Branch:${utils.COLORS.reset} ${status.defaultBranch}`);
|
|
338
|
+
|
|
339
|
+
if (status.lastSync) {
|
|
340
|
+
const syncDate = new Date(status.lastSync);
|
|
341
|
+
console.log(`${utils.COLORS.bold}Last Sync:${utils.COLORS.reset} ${utils.formatRelativeTime(syncDate)}`);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
console.log();
|
|
345
|
+
|
|
346
|
+
// Statistics
|
|
347
|
+
if (status.stats) {
|
|
348
|
+
console.log(`${utils.COLORS.bold}Statistics:${utils.COLORS.reset}`);
|
|
349
|
+
console.log(` Commits: ${status.stats.totalCommits}`);
|
|
350
|
+
console.log(` Open PRs: ${status.stats.openPRs}`);
|
|
351
|
+
console.log(` Closed PRs: ${status.stats.closedPRs}`);
|
|
352
|
+
console.log(` Contributors: ${status.stats.contributors}`);
|
|
353
|
+
console.log();
|
|
354
|
+
|
|
355
|
+
if (status.stats.lastCommitMessage) {
|
|
356
|
+
console.log(`${utils.COLORS.bold}Latest Commit:${utils.COLORS.reset}`);
|
|
357
|
+
console.log(` ${utils.COLORS.dim}${status.stats.lastCommitSha}${utils.COLORS.reset} ${status.stats.lastCommitMessage}`);
|
|
358
|
+
if (status.stats.lastCommit) {
|
|
359
|
+
const date = new Date(status.stats.lastCommit);
|
|
360
|
+
console.log(` ${utils.COLORS.dim}${utils.formatRelativeTime(date)}${utils.COLORS.reset}`);
|
|
361
|
+
}
|
|
362
|
+
console.log();
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
console.log(`${utils.COLORS.bold}Commands:${utils.COLORS.reset}`);
|
|
367
|
+
console.log(' bootspring github sync Refresh data');
|
|
368
|
+
console.log(' bootspring github activity View recent activity');
|
|
369
|
+
console.log(' bootspring github disconnect Remove connection');
|
|
370
|
+
console.log();
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Disconnect from GitHub
|
|
375
|
+
*/
|
|
376
|
+
function handleDisconnect(projectRoot: string): void {
|
|
377
|
+
const status = githubSync.getStatus(projectRoot);
|
|
378
|
+
|
|
379
|
+
if (!status.connected) {
|
|
380
|
+
utils.print.warning('GitHub is not connected.');
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const result = githubSync.disconnectRepository(projectRoot);
|
|
385
|
+
|
|
386
|
+
if (result.success) {
|
|
387
|
+
utils.print.success(`Disconnected from ${status.owner}/${status.repo}`);
|
|
388
|
+
|
|
389
|
+
// Emit telemetry
|
|
390
|
+
telemetry.emitEvent('github:disconnect', {
|
|
391
|
+
owner: status.owner,
|
|
392
|
+
repo: status.repo
|
|
393
|
+
}, { projectRoot });
|
|
394
|
+
} else {
|
|
395
|
+
utils.print.error(`Failed to disconnect: ${result.error}`);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
interface ActivityOptions {
|
|
400
|
+
limit?: number | undefined;
|
|
401
|
+
json?: boolean | undefined;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Show recent activity
|
|
406
|
+
*/
|
|
407
|
+
function handleActivity(projectRoot: string, options: ActivityOptions = {}): void {
|
|
408
|
+
const status = githubSync.getStatus(projectRoot);
|
|
409
|
+
|
|
410
|
+
if (!status.connected) {
|
|
411
|
+
utils.print.error('GitHub not connected.');
|
|
412
|
+
utils.print.dim('Run: bootspring github connect');
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const limit = options.limit || 10;
|
|
417
|
+
|
|
418
|
+
const spinner = utils.createSpinner('Fetching recent activity...');
|
|
419
|
+
spinner.start();
|
|
420
|
+
|
|
421
|
+
const owner = status.owner || '';
|
|
422
|
+
const repo = status.repo || '';
|
|
423
|
+
const activity = githubSync.getRecentActivity(owner, repo, limit);
|
|
424
|
+
|
|
425
|
+
spinner.stop();
|
|
426
|
+
|
|
427
|
+
if (!activity || activity.length === 0) {
|
|
428
|
+
utils.print.warning('No recent activity found.');
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// JSON output
|
|
433
|
+
if (options.json) {
|
|
434
|
+
console.log(JSON.stringify(activity, null, 2));
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
console.log(`
|
|
439
|
+
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Recent Activity${utils.COLORS.reset}
|
|
440
|
+
${utils.COLORS.dim}${status.owner}/${status.repo}${utils.COLORS.reset}
|
|
441
|
+
`);
|
|
442
|
+
|
|
443
|
+
for (const item of activity) {
|
|
444
|
+
const date = new Date(item.date);
|
|
445
|
+
const relativeTime = utils.formatRelativeTime(date);
|
|
446
|
+
|
|
447
|
+
if (item.type === 'commit') {
|
|
448
|
+
console.log(` ${utils.COLORS.cyan}●${utils.COLORS.reset} ${utils.COLORS.dim}${item.sha}${utils.COLORS.reset} ${item.message}`);
|
|
449
|
+
console.log(` ${utils.COLORS.dim}${item.author} · ${relativeTime}${utils.COLORS.reset}`);
|
|
450
|
+
} else if (item.type === 'pr') {
|
|
451
|
+
const stateIcon = item.state === 'open'
|
|
452
|
+
? `${utils.COLORS.green}○${utils.COLORS.reset}`
|
|
453
|
+
: `${utils.COLORS.magenta}●${utils.COLORS.reset}`;
|
|
454
|
+
console.log(` ${stateIcon} PR #${item.number}: ${item.title}`);
|
|
455
|
+
console.log(` ${utils.COLORS.dim}${item.author} · ${item.state} · ${relativeTime}${utils.COLORS.reset}`);
|
|
456
|
+
}
|
|
457
|
+
console.log();
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Show help
|
|
463
|
+
*/
|
|
464
|
+
function showHelp(): void {
|
|
465
|
+
console.log(`
|
|
466
|
+
${utils.COLORS.cyan}${utils.COLORS.bold}⚡ Bootspring GitHub${utils.COLORS.reset}
|
|
467
|
+
${utils.COLORS.dim}Manage GitHub integration${utils.COLORS.reset}
|
|
468
|
+
|
|
469
|
+
${utils.COLORS.bold}Usage:${utils.COLORS.reset}
|
|
470
|
+
bootspring github [command] [options]
|
|
471
|
+
|
|
472
|
+
${utils.COLORS.bold}Commands:${utils.COLORS.reset}
|
|
473
|
+
connect Connect to a GitHub repository
|
|
474
|
+
sync Sync latest commits, PRs, and stats
|
|
475
|
+
status Show connection status (default)
|
|
476
|
+
activity Show recent repository activity
|
|
477
|
+
disconnect Remove GitHub connection
|
|
478
|
+
|
|
479
|
+
${utils.COLORS.bold}Options:${utils.COLORS.reset}
|
|
480
|
+
--url=<url> Specify repository URL for connect
|
|
481
|
+
--json Output as JSON
|
|
482
|
+
--limit=<n> Limit results for activity
|
|
483
|
+
|
|
484
|
+
${utils.COLORS.bold}Examples:${utils.COLORS.reset}
|
|
485
|
+
bootspring github connect # Auto-detect from git
|
|
486
|
+
bootspring github connect --url https://github.com/user/repo
|
|
487
|
+
bootspring github sync # Refresh data
|
|
488
|
+
bootspring github activity --limit=5 # Recent activity
|
|
489
|
+
|
|
490
|
+
${utils.COLORS.bold}Requirements:${utils.COLORS.reset}
|
|
491
|
+
- GitHub CLI (gh) must be installed: https://cli.github.com/
|
|
492
|
+
- Must be authenticated: gh auth login
|
|
493
|
+
`);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// ============================================================================
|
|
497
|
+
// Main Runner
|
|
498
|
+
// ============================================================================
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Run github command
|
|
502
|
+
*/
|
|
503
|
+
export async function run(args: string[]): Promise<void> {
|
|
504
|
+
const cfg = config.load();
|
|
505
|
+
const projectRoot = cfg._projectRoot;
|
|
506
|
+
|
|
507
|
+
// Parse arguments
|
|
508
|
+
const parsed = utils.parseArgs(args);
|
|
509
|
+
const subcommand = parsed._[0] || 'status';
|
|
510
|
+
const options = {
|
|
511
|
+
url: parsed.url || null,
|
|
512
|
+
json: parsed.json || false,
|
|
513
|
+
limit: parseInt(parsed.limit || '10', 10) || 10
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
switch (subcommand) {
|
|
517
|
+
case 'connect':
|
|
518
|
+
case 'c':
|
|
519
|
+
handleConnect(projectRoot, options);
|
|
520
|
+
break;
|
|
521
|
+
|
|
522
|
+
case 'sync':
|
|
523
|
+
case 's':
|
|
524
|
+
handleSync(projectRoot, options);
|
|
525
|
+
break;
|
|
526
|
+
|
|
527
|
+
case 'status':
|
|
528
|
+
case 'st':
|
|
529
|
+
handleStatus(projectRoot, options);
|
|
530
|
+
break;
|
|
531
|
+
|
|
532
|
+
case 'disconnect':
|
|
533
|
+
case 'd':
|
|
534
|
+
case 'remove':
|
|
535
|
+
handleDisconnect(projectRoot);
|
|
536
|
+
break;
|
|
537
|
+
|
|
538
|
+
case 'activity':
|
|
539
|
+
case 'log':
|
|
540
|
+
case 'a':
|
|
541
|
+
handleActivity(projectRoot, options);
|
|
542
|
+
break;
|
|
543
|
+
|
|
544
|
+
case 'help':
|
|
545
|
+
case '-h':
|
|
546
|
+
case '--help':
|
|
547
|
+
showHelp();
|
|
548
|
+
break;
|
|
549
|
+
|
|
550
|
+
default:
|
|
551
|
+
utils.print.error(`Unknown subcommand: ${subcommand}`);
|
|
552
|
+
showHelp();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// ============================================================================
|
|
557
|
+
// Exports
|
|
558
|
+
// ============================================================================
|
|
559
|
+
|
|
560
|
+
export {
|
|
561
|
+
handleConnect,
|
|
562
|
+
handleSync,
|
|
563
|
+
handleStatus,
|
|
564
|
+
handleDisconnect,
|
|
565
|
+
handleActivity
|
|
566
|
+
};
|