@azizbekdevuz/gitguard-cli 1.0.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 +88 -0
  2. package/dist/collectors/conflict-extractor.d.ts +7 -0
  3. package/dist/collectors/conflict-extractor.d.ts.map +1 -0
  4. package/dist/collectors/conflict-extractor.js +94 -0
  5. package/dist/collectors/conflict-extractor.js.map +1 -0
  6. package/dist/collectors/git-info.d.ts +18 -0
  7. package/dist/collectors/git-info.d.ts.map +1 -0
  8. package/dist/collectors/git-info.js +59 -0
  9. package/dist/collectors/git-info.js.map +1 -0
  10. package/dist/collectors/rebase-detector.d.ts +7 -0
  11. package/dist/collectors/rebase-detector.d.ts.map +1 -0
  12. package/dist/collectors/rebase-detector.js +57 -0
  13. package/dist/collectors/rebase-detector.js.map +1 -0
  14. package/dist/commands/send.d.ts +7 -0
  15. package/dist/commands/send.d.ts.map +1 -0
  16. package/dist/commands/send.js +169 -0
  17. package/dist/commands/send.js.map +1 -0
  18. package/dist/commands/snapshot.d.ts +7 -0
  19. package/dist/commands/snapshot.d.ts.map +1 -0
  20. package/dist/commands/snapshot.js +92 -0
  21. package/dist/commands/snapshot.js.map +1 -0
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +22 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/parsers/branch-parser.d.ts +7 -0
  27. package/dist/parsers/branch-parser.d.ts.map +1 -0
  28. package/dist/parsers/branch-parser.js +20 -0
  29. package/dist/parsers/branch-parser.js.map +1 -0
  30. package/dist/parsers/diffstat-parser.d.ts +8 -0
  31. package/dist/parsers/diffstat-parser.d.ts.map +1 -0
  32. package/dist/parsers/diffstat-parser.js +42 -0
  33. package/dist/parsers/diffstat-parser.js.map +1 -0
  34. package/dist/parsers/log-parser.d.ts +8 -0
  35. package/dist/parsers/log-parser.d.ts.map +1 -0
  36. package/dist/parsers/log-parser.js +46 -0
  37. package/dist/parsers/log-parser.js.map +1 -0
  38. package/dist/parsers/reflog-parser.d.ts +8 -0
  39. package/dist/parsers/reflog-parser.d.ts.map +1 -0
  40. package/dist/parsers/reflog-parser.js +65 -0
  41. package/dist/parsers/reflog-parser.js.map +1 -0
  42. package/dist/parsers/status-parser.d.ts +27 -0
  43. package/dist/parsers/status-parser.d.ts.map +1 -0
  44. package/dist/parsers/status-parser.js +110 -0
  45. package/dist/parsers/status-parser.js.map +1 -0
  46. package/dist/utils/exec.d.ts +14 -0
  47. package/dist/utils/exec.d.ts.map +1 -0
  48. package/dist/utils/exec.js +54 -0
  49. package/dist/utils/exec.js.map +1 -0
  50. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # GitGuard CLI
2
+
3
+ Command-line tool for capturing and analyzing Git repository state.
4
+
5
+ ## Installation & Usage
6
+
7
+ Since this is a local package (not published to npm), use one of these methods:
8
+
9
+ ### Method 1: Using pnpm (Recommended - Easiest)
10
+
11
+ From the **project root**:
12
+ ```bash
13
+ # Build the CLI first (one time)
14
+ pnpm build:cli
15
+
16
+ # Then use via pnpm (use -- to pass arguments)
17
+ pnpm --filter @gitguard/cli -- snapshot --pretty > snapshot.json
18
+ # pnpm --filter @gitguard/cli -- send
19
+ # pnpm --filter @gitguard/cli -- send --open
20
+ ```
21
+
22
+ ### Method 2: Direct Node Execution (After Building)
23
+
24
+ ```bash
25
+ # Build first (one time)
26
+ pnpm build:cli
27
+
28
+ # Run directly from project root
29
+ node apps/cli/dist/index.js snapshot --pretty > snapshot.json
30
+ # node apps/cli/dist/index.js send
31
+ # node apps/cli/dist/index.js send --open
32
+ ```
33
+
34
+ ### Method 3: Global Link (For Development)
35
+
36
+ ```bash
37
+ # From project root
38
+ pnpm build:cli
39
+ cd apps/cli
40
+ pnpm link --global
41
+
42
+ # Now you can use `gitguard` from anywhere on your system
43
+ gitguard snapshot --pretty > snapshot.json
44
+ gitguard send
45
+ gitguard send --open
46
+ ```
47
+
48
+ ### Method 4: Create an Alias (PowerShell)
49
+
50
+ Add to your PowerShell profile (`$PROFILE`):
51
+ ```powershell
52
+ function gitguard { node D:\Workplace\Web\gitguardian\apps\cli\dist\index.js $args }
53
+ ```
54
+
55
+ Then use normally:
56
+ ```bash
57
+ gitguard snapshot --pretty > snapshot.json
58
+ gitguard send
59
+ ```
60
+
61
+ ## Commands
62
+
63
+ ### `gitguard snapshot`
64
+
65
+ Generate a read-only snapshot of your repository state.
66
+
67
+ ```bash
68
+ gitguard snapshot # Output to stdout
69
+ gitguard snapshot -o snapshot.json # Save to file
70
+ gitguard snapshot --pretty # Pretty-print JSON
71
+ ```
72
+
73
+ ### `gitguard send`
74
+
75
+ Capture repository state and send to GitGuard for AI analysis.
76
+
77
+ ```bash
78
+ gitguard send # Send to default API (localhost:3000)
79
+ gitguard send -u https://api.example.com # Custom API URL
80
+ gitguard send --open # Open incident room in browser
81
+ ```
82
+
83
+ ## Requirements
84
+
85
+ - Node.js 18+
86
+ - Git repository with issues (conflicts, detached HEAD, rebase in progress)
87
+ - Build the CLI first: `pnpm build:cli` or `cd apps/cli && pnpm build`
88
+
@@ -0,0 +1,7 @@
1
+ import type { UnmergedFile } from '@gitguard/schema';
2
+ /**
3
+ * Extract conflict blocks from unmerged files.
4
+ * Scans for <<<<<<<, =======, >>>>>>> markers.
5
+ */
6
+ export declare function extractConflicts(repoRoot: string, unmergedPaths: string[]): Promise<UnmergedFile[]>;
7
+ //# sourceMappingURL=conflict-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict-extractor.d.ts","sourceRoot":"","sources":["../../src/collectors/conflict-extractor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,kBAAkB,CAAC;AAMpE;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,YAAY,EAAE,CAAC,CAkCzB"}
@@ -0,0 +1,94 @@
1
+ import { readFileSync, existsSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ const MAX_BLOCKS_PER_FILE = 3;
4
+ const CONTEXT_LINES = 10;
5
+ const MAX_BLOCK_SIZE = 2000; // characters
6
+ /**
7
+ * Extract conflict blocks from unmerged files.
8
+ * Scans for <<<<<<<, =======, >>>>>>> markers.
9
+ */
10
+ export async function extractConflicts(repoRoot, unmergedPaths) {
11
+ const results = [];
12
+ for (const filePath of unmergedPaths) {
13
+ const fullPath = resolve(repoRoot, filePath);
14
+ if (!existsSync(fullPath)) {
15
+ results.push({
16
+ path: filePath,
17
+ conflictBlocks: [],
18
+ });
19
+ continue;
20
+ }
21
+ try {
22
+ let content = readFileSync(fullPath, 'utf-8');
23
+ // Normalize line endings
24
+ content = content.replace(/\r\n/g, '\n');
25
+ const blocks = extractConflictBlocks(content);
26
+ results.push({
27
+ path: filePath,
28
+ conflictBlocks: blocks.slice(0, MAX_BLOCKS_PER_FILE),
29
+ });
30
+ }
31
+ catch {
32
+ results.push({
33
+ path: filePath,
34
+ conflictBlocks: [],
35
+ });
36
+ }
37
+ }
38
+ return results;
39
+ }
40
+ function extractConflictBlocks(content) {
41
+ const lines = content.split('\n');
42
+ const blocks = [];
43
+ let i = 0;
44
+ while (i < lines.length && blocks.length < MAX_BLOCKS_PER_FILE) {
45
+ const line = lines[i];
46
+ // Look for conflict start marker
47
+ if (line.startsWith('<<<<<<<')) {
48
+ const startLine = i;
49
+ let separatorLine = -1;
50
+ let endLine = -1;
51
+ // Find separator and end
52
+ for (let j = i + 1; j < lines.length; j++) {
53
+ if (lines[j].startsWith('=======')) {
54
+ separatorLine = j;
55
+ }
56
+ else if (lines[j].startsWith('>>>>>>>') && separatorLine !== -1) {
57
+ endLine = j;
58
+ break;
59
+ }
60
+ }
61
+ if (separatorLine !== -1 && endLine !== -1) {
62
+ // Extract ours (between <<<< and ====)
63
+ const oursLines = lines.slice(startLine + 1, separatorLine);
64
+ const oursContent = truncate(oursLines.join('\n'));
65
+ // Extract theirs (between ==== and >>>>)
66
+ const theirsLines = lines.slice(separatorLine + 1, endLine);
67
+ const theirsContent = truncate(theirsLines.join('\n'));
68
+ // Extract context (lines around the conflict)
69
+ const contextStart = Math.max(0, startLine - CONTEXT_LINES);
70
+ const contextEnd = Math.min(lines.length, endLine + CONTEXT_LINES + 1);
71
+ const contextLines = lines.slice(contextStart, contextEnd);
72
+ const context = truncate(contextLines.join('\n'));
73
+ blocks.push({
74
+ startLine: startLine + 1, // 1-indexed for display
75
+ endLine: endLine + 1,
76
+ oursContent,
77
+ theirsContent,
78
+ context,
79
+ });
80
+ i = endLine + 1;
81
+ continue;
82
+ }
83
+ }
84
+ i++;
85
+ }
86
+ return blocks;
87
+ }
88
+ function truncate(text) {
89
+ if (text.length <= MAX_BLOCK_SIZE) {
90
+ return text;
91
+ }
92
+ return text.slice(0, MAX_BLOCK_SIZE) + '\n... [truncated]';
93
+ }
94
+ //# sourceMappingURL=conflict-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict-extractor.js","sourceRoot":"","sources":["../../src/collectors/conflict-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface GitInfo {
2
+ repoRoot: string;
3
+ gitDir: string;
4
+ status: string;
5
+ branches: string;
6
+ log: string;
7
+ reflog: string;
8
+ commitGraph: string;
9
+ diffStat: string;
10
+ mergeHead: string | null;
11
+ mergeMessage: string | null;
12
+ }
13
+ /**
14
+ * Collect all git information needed for snapshot.
15
+ * Uses only git commands - no direct file system access to .git
16
+ */
17
+ export declare function collectGitInfo(): Promise<GitInfo>;
18
+ //# sourceMappingURL=git-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-info.d.ts","sourceRoot":"","sources":["../../src/collectors/git-info.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CA8DvD"}
@@ -0,0 +1,59 @@
1
+ import { execGit } from '../utils/exec.js';
2
+ /**
3
+ * Collect all git information needed for snapshot.
4
+ * Uses only git commands - no direct file system access to .git
5
+ */
6
+ export async function collectGitInfo() {
7
+ // Get repo root
8
+ const repoRootResult = execGit(['rev-parse', '--show-toplevel']);
9
+ if (!repoRootResult.success) {
10
+ throw new Error('Not a git repository (or any of the parent directories)');
11
+ }
12
+ const repoRoot = repoRootResult.stdout.trim();
13
+ // Get git directory (handles worktrees correctly)
14
+ const gitDirResult = execGit(['rev-parse', '--git-dir']);
15
+ if (!gitDirResult.success) {
16
+ throw new Error('Could not determine git directory');
17
+ }
18
+ const gitDir = gitDirResult.stdout.trim();
19
+ // Get status with porcelain v2 format
20
+ const statusResult = execGit(['status', '--porcelain=v2', '--branch']);
21
+ const status = statusResult.stdout;
22
+ // Get branches with verbose info
23
+ const branchesResult = execGit(['branch', '-vv']);
24
+ const branches = branchesResult.stdout;
25
+ // Get recent log
26
+ const logResult = execGit(['log', '--oneline', '--decorate', '-n', '30']);
27
+ const log = logResult.stdout;
28
+ // Get reflog
29
+ const reflogResult = execGit(['reflog', '-n', '30']);
30
+ const reflog = reflogResult.stdout;
31
+ // NEW: Get commit graph for visualization
32
+ const graphResult = execGit(['log', '--graph', '--oneline', '--decorate', '--all', '-n', '30']);
33
+ const commitGraph = graphResult.stdout;
34
+ // NEW: Get diff stat for file summary
35
+ const diffStatResult = execGit(['diff', '--stat', '--numstat']);
36
+ const diffStat = diffStatResult.stdout;
37
+ // NEW: Check for MERGE_HEAD (indicates we're in a merge)
38
+ const mergeHeadResult = execGit(['rev-parse', 'MERGE_HEAD']);
39
+ const mergeHead = mergeHeadResult.success ? mergeHeadResult.stdout.trim() : null;
40
+ // NEW: Get merge message if available
41
+ let mergeMessage = null;
42
+ if (mergeHead) {
43
+ const msgResult = execGit(['log', '-1', '--format=%B', 'MERGE_HEAD']);
44
+ mergeMessage = msgResult.success ? msgResult.stdout.trim() : null;
45
+ }
46
+ return {
47
+ repoRoot,
48
+ gitDir,
49
+ status,
50
+ branches,
51
+ log,
52
+ reflog,
53
+ commitGraph,
54
+ diffStat,
55
+ mergeHead,
56
+ mergeMessage,
57
+ };
58
+ }
59
+ //# sourceMappingURL=git-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-info.js","sourceRoot":"","sources":["../../src/collectors/git-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAe3C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,gBAAgB;IAChB,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAE9C,kDAAkD;IAClD,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;IACzD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAE1C,sCAAsC;IACtC,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;IAEnC,iCAAiC;IACjC,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC;IAEvC,iBAAiB;IACjB,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC;IAE7B,aAAa;IACb,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;IAEnC,0CAA0C;IAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAChG,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC;IAEvC,sCAAsC;IACtC,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC;IAEvC,yDAAyD;IACzD,MAAM,eAAe,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAEjF,sCAAsC;IACtC,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;QACtE,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,CAAC;IAED,OAAO;QACL,QAAQ;QACR,MAAM;QACN,MAAM;QACN,QAAQ;QACR,GAAG;QACH,MAAM;QACN,WAAW;QACX,QAAQ;QACR,SAAS;QACT,YAAY;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { RebaseState } from '@gitguard/schema';
2
+ /**
3
+ * Detect if a rebase is in progress and gather state info.
4
+ * Uses git rev-parse --git-path to locate rebase directories cross-platform.
5
+ */
6
+ export declare function detectRebaseState(gitDir: string): Promise<RebaseState>;
7
+ //# sourceMappingURL=rebase-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebase-detector.d.ts","sourceRoot":"","sources":["../../src/collectors/rebase-detector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAuB5E"}
@@ -0,0 +1,57 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { execGit } from '../utils/exec.js';
4
+ /**
5
+ * Detect if a rebase is in progress and gather state info.
6
+ * Uses git rev-parse --git-path to locate rebase directories cross-platform.
7
+ */
8
+ export async function detectRebaseState(gitDir) {
9
+ // Check for rebase-merge (interactive rebase)
10
+ const rebaseMergeResult = execGit(['rev-parse', '--git-path', 'rebase-merge']);
11
+ const rebaseMergePath = rebaseMergeResult.stdout.trim();
12
+ const resolvedMergePath = resolve(process.cwd(), rebaseMergePath);
13
+ if (existsSync(resolvedMergePath)) {
14
+ return parseRebaseState(resolvedMergePath, 'merge');
15
+ }
16
+ // Check for rebase-apply (regular rebase, am, etc.)
17
+ const rebaseApplyResult = execGit(['rev-parse', '--git-path', 'rebase-apply']);
18
+ const rebaseApplyPath = rebaseApplyResult.stdout.trim();
19
+ const resolvedApplyPath = resolve(process.cwd(), rebaseApplyPath);
20
+ if (existsSync(resolvedApplyPath)) {
21
+ return parseRebaseState(resolvedApplyPath, 'apply');
22
+ }
23
+ return {
24
+ inProgress: false,
25
+ type: 'none',
26
+ };
27
+ }
28
+ function parseRebaseState(rebasePath, type) {
29
+ const state = {
30
+ inProgress: true,
31
+ type,
32
+ };
33
+ // Try to read head-name (original branch)
34
+ const headNamePath = resolve(rebasePath, 'head-name');
35
+ if (existsSync(headNamePath)) {
36
+ const headName = readFileSync(headNamePath, 'utf-8').trim();
37
+ // Remove refs/heads/ prefix
38
+ state.headName = headName.replace(/^refs\/heads\//, '');
39
+ }
40
+ // Try to read onto (target commit)
41
+ const ontoPath = resolve(rebasePath, 'onto');
42
+ if (existsSync(ontoPath)) {
43
+ state.onto = readFileSync(ontoPath, 'utf-8').trim();
44
+ }
45
+ // Try to read msgnum (current step)
46
+ const msgnumPath = resolve(rebasePath, 'msgnum');
47
+ if (existsSync(msgnumPath)) {
48
+ state.currentStep = parseInt(readFileSync(msgnumPath, 'utf-8').trim(), 10);
49
+ }
50
+ // Try to read end (total steps)
51
+ const endPath = resolve(rebasePath, 'end');
52
+ if (existsSync(endPath)) {
53
+ state.totalSteps = parseInt(readFileSync(endPath, 'utf-8').trim(), 10);
54
+ }
55
+ return state;
56
+ }
57
+ //# sourceMappingURL=rebase-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebase-detector.js","sourceRoot":"","sources":["../../src/collectors/rebase-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAc;IACpD,8CAA8C;IAC9C,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;IAC/E,MAAM,eAAe,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACxD,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IAElE,IAAI,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAClC,OAAO,gBAAgB,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,oDAAoD;IACpD,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;IAC/E,MAAM,eAAe,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACxD,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IAElE,IAAI,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAClC,OAAO,gBAAgB,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,OAAO;QACL,UAAU,EAAE,KAAK;QACjB,IAAI,EAAE,MAAM;KACb,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,UAAkB,EAAE,IAAuB;IACnE,MAAM,KAAK,GAAgB;QACzB,UAAU,EAAE,IAAI;QAChB,IAAI;KACL,CAAC;IAEF,0CAA0C;IAC1C,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACtD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5D,4BAA4B;QAC5B,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,mCAAmC;IACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC7C,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,CAAC;IAED,oCAAoC;IACpC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACjD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,gCAAgC;IAChC,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,7 @@
1
+ interface SendOptions {
2
+ apiUrl?: string;
3
+ open?: boolean;
4
+ }
5
+ export declare function sendCommand(options: SendOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=send.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"AAYA,UAAU,WAAW;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAWD,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuKrE"}
@@ -0,0 +1,169 @@
1
+ import { SnapshotV1Schema } from '@gitguard/schema';
2
+ import { collectGitInfo } from '../collectors/git-info.js';
3
+ import { parseStatus } from '../parsers/status-parser.js';
4
+ import { parseBranches } from '../parsers/branch-parser.js';
5
+ import { parseLog } from '../parsers/log-parser.js';
6
+ import { parseReflog } from '../parsers/reflog-parser.js';
7
+ import { parseDiffStat } from '../parsers/diffstat-parser.js';
8
+ import { detectRebaseState } from '../collectors/rebase-detector.js';
9
+ import { extractConflicts } from '../collectors/conflict-extractor.js';
10
+ const DEFAULT_API_URL = 'http://localhost:3000';
11
+ export async function sendCommand(options) {
12
+ const apiUrl = options.apiUrl || process.env.GITGUARD_API_URL || DEFAULT_API_URL;
13
+ const requestId = `cli-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
14
+ console.error(`[CLI:SEND:${requestId}] ========================================`);
15
+ console.error(`[CLI:SEND:${requestId}] 🚀 Starting GitGuard snapshot collection`);
16
+ console.error(`[CLI:SEND:${requestId}] API URL: ${apiUrl}`);
17
+ console.error(`[CLI:SEND:${requestId}] Timestamp: ${new Date().toISOString()}`);
18
+ try {
19
+ console.error(`[CLI:SEND:${requestId}] 📥 Collecting Git repository information...`);
20
+ // Collect git information
21
+ const gitInfo = await collectGitInfo();
22
+ console.error(`[CLI:SEND:${requestId}] ✅ Git info collected`);
23
+ console.error(`[CLI:SEND:${requestId}] Repo root: ${gitInfo.repoRoot}`);
24
+ console.error(`[CLI:SEND:${requestId}] Git dir: ${gitInfo.gitDir}`);
25
+ console.error(`[CLI:SEND:${requestId}] 🔍 Parsing Git status...`);
26
+ // Parse status
27
+ const statusInfo = parseStatus(gitInfo.status);
28
+ console.error(`[CLI:SEND:${requestId}] ✅ Status parsed`);
29
+ console.error(`[CLI:SEND:${requestId}] Branch: ${statusInfo.branch}`);
30
+ console.error(`[CLI:SEND:${requestId}] Unmerged files: ${statusInfo.unmergedPaths.length}`);
31
+ console.error(`[CLI:SEND:${requestId}] Staged: ${statusInfo.stagedFiles.length}, Modified: ${statusInfo.modifiedFiles.length}`);
32
+ console.error(`[CLI:SEND:${requestId}] 🔍 Parsing branches...`);
33
+ // Parse branches
34
+ const branchInfo = parseBranches(gitInfo.branches, statusInfo.branch);
35
+ console.error(`[CLI:SEND:${requestId}] ✅ Branches parsed: ${branchInfo.head}`);
36
+ console.error(`[CLI:SEND:${requestId}] 🔍 Parsing commit logs...`);
37
+ // Parse logs
38
+ const logEntries = parseLog(gitInfo.log);
39
+ const reflogEntries = parseReflog(gitInfo.reflog);
40
+ console.error(`[CLI:SEND:${requestId}] ✅ Logs parsed: ${logEntries.length} commits, ${reflogEntries.length} reflog entries`);
41
+ console.error(`[CLI:SEND:${requestId}] 🔍 Parsing diff stats...`);
42
+ // Parse diff stats
43
+ const diffStats = parseDiffStat(gitInfo.diffStat);
44
+ console.error(`[CLI:SEND:${requestId}] ✅ Diff stats parsed: ${diffStats.length} files`);
45
+ console.error(`[CLI:SEND:${requestId}] 🔍 Detecting rebase state...`);
46
+ // Detect rebase state
47
+ const rebaseState = await detectRebaseState(gitInfo.gitDir);
48
+ console.error(`[CLI:SEND:${requestId}] ✅ Rebase state: ${rebaseState.inProgress ? 'IN PROGRESS' : 'none'}`);
49
+ console.error(`[CLI:SEND:${requestId}] 🔍 Extracting conflict details...`);
50
+ // Extract conflict details
51
+ const unmergedFiles = await extractConflicts(gitInfo.repoRoot, statusInfo.unmergedPaths.slice(0, 10) // Extract up to 10 conflict files
52
+ );
53
+ console.error(`[CLI:SEND:${requestId}] ✅ Conflicts extracted: ${unmergedFiles.length} files with conflicts`);
54
+ // Build snapshot
55
+ const snapshot = {
56
+ version: 1,
57
+ timestamp: new Date().toISOString(),
58
+ platform: process.platform,
59
+ repoRoot: gitInfo.repoRoot,
60
+ gitDir: gitInfo.gitDir,
61
+ branch: branchInfo,
62
+ isDetachedHead: statusInfo.isDetachedHead,
63
+ rebaseState,
64
+ unmergedFiles,
65
+ stagedFiles: statusInfo.stagedFiles,
66
+ modifiedFiles: statusInfo.modifiedFiles,
67
+ untrackedFiles: statusInfo.untrackedFiles,
68
+ recentLog: logEntries,
69
+ recentReflog: reflogEntries,
70
+ commitGraph: gitInfo.commitGraph || undefined,
71
+ diffStats: diffStats.length > 0 ? diffStats : undefined,
72
+ mergeHead: gitInfo.mergeHead || undefined,
73
+ mergeMessage: gitInfo.mergeMessage || undefined,
74
+ rawStatus: gitInfo.status,
75
+ rawBranches: gitInfo.branches,
76
+ };
77
+ console.error(`[CLI:SEND:${requestId}] ✅ Validating snapshot with schema...`);
78
+ // Validate with Zod
79
+ const validated = SnapshotV1Schema.parse(snapshot);
80
+ console.error(`[CLI:SEND:${requestId}] ✅ Snapshot validated`);
81
+ console.error(`[CLI:SEND:${requestId}] Snapshot size: ${JSON.stringify(validated).length} bytes`);
82
+ console.error(`[CLI:SEND:${requestId}] 📤 Uploading snapshot to GitGuard API...`);
83
+ console.error(`[CLI:SEND:${requestId}] Endpoint: ${apiUrl}/api/snapshots/ingest`);
84
+ const uploadStart = Date.now();
85
+ // Send to API
86
+ const response = await fetch(`${apiUrl}/api/snapshots/ingest`, {
87
+ method: 'POST',
88
+ headers: {
89
+ 'Content-Type': 'application/json',
90
+ },
91
+ body: JSON.stringify({ snapshot: validated }),
92
+ });
93
+ const uploadDuration = Date.now() - uploadStart;
94
+ console.error(`[CLI:SEND:${requestId}] Upload duration: ${uploadDuration}ms`);
95
+ console.error(`[CLI:SEND:${requestId}] Response status: ${response.status}`);
96
+ if (!response.ok) {
97
+ let errorMessage = `Server returned ${response.status}`;
98
+ try {
99
+ const errorData = await response.json();
100
+ if (errorData.error) {
101
+ errorMessage = errorData.error;
102
+ }
103
+ }
104
+ catch {
105
+ // Ignore JSON parse errors
106
+ }
107
+ console.error(`[CLI:SEND:${requestId}] ❌ Upload failed: ${errorMessage}`);
108
+ throw new Error(errorMessage);
109
+ }
110
+ const result = await response.json();
111
+ console.error(`[CLI:SEND:${requestId}] ✅ Upload successful`);
112
+ console.error(`[CLI:SEND:${requestId}] Session ID: ${result.sessionId}`);
113
+ console.error(`[CLI:SEND:${requestId}] Issue type: ${result.analysis.issueType}`);
114
+ // Display results
115
+ console.log('');
116
+ console.log('='.repeat(60));
117
+ console.log('');
118
+ console.log(` Issue Type: ${result.analysis.issueType.replace('_', ' ').toUpperCase()}`);
119
+ console.log(` Summary: ${result.analysis.summary}`);
120
+ console.log('');
121
+ console.log(` Incident Room: ${result.url}`);
122
+ console.log('');
123
+ console.log('='.repeat(60));
124
+ console.log('');
125
+ // Try to open in browser if requested
126
+ if (options.open) {
127
+ try {
128
+ const open = await getOpenCommand();
129
+ if (open) {
130
+ const { exec } = await import('node:child_process');
131
+ exec(`${open} "${result.url}"`);
132
+ console.error(`[CLI:SEND:${requestId}] 🌐 Opening incident room in browser...`);
133
+ }
134
+ }
135
+ catch {
136
+ // Silently fail if we can't open the browser
137
+ }
138
+ }
139
+ console.error(`[CLI:SEND:${requestId}] ✅ Command completed successfully`);
140
+ console.error(`[CLI:SEND:${requestId}] ========================================`);
141
+ }
142
+ catch (error) {
143
+ console.error(`[CLI:SEND:${requestId}] ❌ Command failed`);
144
+ if (error instanceof Error) {
145
+ console.error(`[CLI:SEND:${requestId}] Error: ${error.message}`);
146
+ if (error.message.includes('not a git repository')) {
147
+ console.error('Please run this command from within a git repository.');
148
+ }
149
+ else if (error.message.includes('fetch')) {
150
+ console.error(`Could not connect to ${apiUrl}. Is the server running?`);
151
+ }
152
+ }
153
+ console.error(`[CLI:SEND:${requestId}] ========================================`);
154
+ process.exit(1);
155
+ }
156
+ }
157
+ async function getOpenCommand() {
158
+ switch (process.platform) {
159
+ case 'darwin':
160
+ return 'open';
161
+ case 'win32':
162
+ return 'start';
163
+ case 'linux':
164
+ return 'xdg-open';
165
+ default:
166
+ return null;
167
+ }
168
+ }
169
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface SnapshotOptions {
2
+ output?: string;
3
+ pretty?: boolean;
4
+ }
5
+ export declare function snapshotCommand(options: SnapshotOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/commands/snapshot.ts"],"names":[],"mappings":"AAWA,UAAU,eAAe;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAqG7E"}