gitmaps 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 (121) hide show
  1. package/README.md +167 -0
  2. package/app/api/auth/favorites/route.ts +56 -0
  3. package/app/api/auth/github/callback/route.ts +103 -0
  4. package/app/api/auth/github/route.ts +32 -0
  5. package/app/api/auth/me/route.ts +52 -0
  6. package/app/api/auth/positions/route.ts +50 -0
  7. package/app/api/chat/route.ts +101 -0
  8. package/app/api/connections/route.ts +72 -0
  9. package/app/api/github/repos/route.ts +111 -0
  10. package/app/api/positions/route.ts +80 -0
  11. package/app/api/repo/branch-diff/route.ts +201 -0
  12. package/app/api/repo/branches/route.ts +53 -0
  13. package/app/api/repo/browse/route.ts +55 -0
  14. package/app/api/repo/clone/route.ts +78 -0
  15. package/app/api/repo/clone-stream/route.ts +131 -0
  16. package/app/api/repo/file-content/route.ts +28 -0
  17. package/app/api/repo/file-delete/route.ts +62 -0
  18. package/app/api/repo/file-history/route.ts +45 -0
  19. package/app/api/repo/file-rename/route.ts +83 -0
  20. package/app/api/repo/file-save/route.ts +45 -0
  21. package/app/api/repo/files/route.ts +169 -0
  22. package/app/api/repo/git-blame/route.ts +86 -0
  23. package/app/api/repo/git-commit/route.ts +40 -0
  24. package/app/api/repo/git-heatmap/route.ts +55 -0
  25. package/app/api/repo/imports/route.ts +154 -0
  26. package/app/api/repo/load/route.ts +56 -0
  27. package/app/api/repo/mode/route.ts +14 -0
  28. package/app/api/repo/search/route.ts +127 -0
  29. package/app/api/repo/tree/route.ts +104 -0
  30. package/app/api/repo/upload/route.ts +53 -0
  31. package/app/api/repo/validate-path.ts +53 -0
  32. package/app/canvas_users.db +0 -0
  33. package/app/canvas_users.db-shm +0 -0
  34. package/app/canvas_users.db-wal +0 -0
  35. package/app/globals.css +7899 -0
  36. package/app/layout.tsx +493 -0
  37. package/app/lib/auth.ts +193 -0
  38. package/app/lib/auto-save.ts +137 -0
  39. package/app/lib/branch-compare.ts +443 -0
  40. package/app/lib/breadcrumbs.ts +170 -0
  41. package/app/lib/canvas-export.ts +358 -0
  42. package/app/lib/canvas-text.ts +912 -0
  43. package/app/lib/canvas.ts +564 -0
  44. package/app/lib/card-arrangement.ts +188 -0
  45. package/app/lib/card-context-menu.tsx +453 -0
  46. package/app/lib/card-diff-markers.ts +270 -0
  47. package/app/lib/card-expand.ts +189 -0
  48. package/app/lib/card-groups.ts +246 -0
  49. package/app/lib/cards.tsx +914 -0
  50. package/app/lib/chat.tsx +308 -0
  51. package/app/lib/code-editor.ts +508 -0
  52. package/app/lib/command-palette.ts +262 -0
  53. package/app/lib/connections.tsx +1037 -0
  54. package/app/lib/context.ts +94 -0
  55. package/app/lib/cursor-sharing.ts +281 -0
  56. package/app/lib/dependency-graph.ts +438 -0
  57. package/app/lib/events.tsx +1747 -0
  58. package/app/lib/file-card-plugin.ts +134 -0
  59. package/app/lib/file-modal.tsx +849 -0
  60. package/app/lib/file-preview.ts +400 -0
  61. package/app/lib/file-tabs.ts +318 -0
  62. package/app/lib/galaxydraw-bridge.ts +477 -0
  63. package/app/lib/galaxydraw.test.ts +229 -0
  64. package/app/lib/global-search.ts +264 -0
  65. package/app/lib/goto-definition.ts +224 -0
  66. package/app/lib/heatmap.ts +178 -0
  67. package/app/lib/hidden-files.tsx +222 -0
  68. package/app/lib/layers.ts +0 -0
  69. package/app/lib/layers.tsx +365 -0
  70. package/app/lib/loading.tsx +45 -0
  71. package/app/lib/multi-repo.ts +286 -0
  72. package/app/lib/new-file-dialog.tsx +230 -0
  73. package/app/lib/onboarding.tsx +213 -0
  74. package/app/lib/perf-overlay.ts +360 -0
  75. package/app/lib/positions.ts +176 -0
  76. package/app/lib/pr-review.ts +374 -0
  77. package/app/lib/production-mode.ts +47 -0
  78. package/app/lib/repo.tsx +977 -0
  79. package/app/lib/settings-modal.tsx +374 -0
  80. package/app/lib/settings.ts +97 -0
  81. package/app/lib/shortcuts-panel.ts +141 -0
  82. package/app/lib/status-bar.ts +128 -0
  83. package/app/lib/symbol-outline.ts +212 -0
  84. package/app/lib/syntax.ts +177 -0
  85. package/app/lib/tab-diff.ts +238 -0
  86. package/app/lib/user.tsx +133 -0
  87. package/app/lib/utils.ts +78 -0
  88. package/app/lib/viewport-culling.ts +728 -0
  89. package/app/page.client.tsx +215 -0
  90. package/app/page.tsx +291 -0
  91. package/app/state/machine.js +196 -0
  92. package/app/styles/main.css +2168 -0
  93. package/banner.png +0 -0
  94. package/cli.ts +44 -0
  95. package/package.json +75 -0
  96. package/packages/galaxydraw/README.md +296 -0
  97. package/packages/galaxydraw/banner.png +0 -0
  98. package/packages/galaxydraw/demo/build-static.ts +100 -0
  99. package/packages/galaxydraw/demo/client.ts +154 -0
  100. package/packages/galaxydraw/demo/dist/client.js +8 -0
  101. package/packages/galaxydraw/demo/index.html +256 -0
  102. package/packages/galaxydraw/demo/server.ts +96 -0
  103. package/packages/galaxydraw/dist/index.js +984 -0
  104. package/packages/galaxydraw/dist/index.js.map +16 -0
  105. package/packages/galaxydraw/node_modules/.bin/tsc.bunx +0 -0
  106. package/packages/galaxydraw/node_modules/.bin/tsc.exe +0 -0
  107. package/packages/galaxydraw/node_modules/.bin/tsserver.bunx +0 -0
  108. package/packages/galaxydraw/node_modules/.bin/tsserver.exe +0 -0
  109. package/packages/galaxydraw/package.json +49 -0
  110. package/packages/galaxydraw/perf.test.ts +284 -0
  111. package/packages/galaxydraw/src/core/cards.ts +435 -0
  112. package/packages/galaxydraw/src/core/engine.ts +339 -0
  113. package/packages/galaxydraw/src/core/events.ts +81 -0
  114. package/packages/galaxydraw/src/core/layout.ts +136 -0
  115. package/packages/galaxydraw/src/core/minimap.ts +216 -0
  116. package/packages/galaxydraw/src/core/state.ts +177 -0
  117. package/packages/galaxydraw/src/core/viewport.ts +106 -0
  118. package/packages/galaxydraw/src/galaxydraw.css +166 -0
  119. package/packages/galaxydraw/src/index.ts +40 -0
  120. package/packages/galaxydraw/tsconfig.json +30 -0
  121. package/server.ts +62 -0
@@ -0,0 +1,246 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Card Groups — collapse directories into compact summary cards.
4
+ *
5
+ * Click a directory label (📁) to collapse all files in that directory
6
+ * into a single group card showing: dir name, file count, total lines,
7
+ * and a mini file list. Click again to expand back.
8
+ *
9
+ * State persisted to localStorage per repo.
10
+ */
11
+ import type { CanvasContext } from './context';
12
+
13
+ // ─── State ───────────────────────────────────────────────
14
+ const collapsedDirs = new Set<string>();
15
+ let _ctx: CanvasContext | null = null;
16
+
17
+ interface CollapsedGroup {
18
+ dir: string;
19
+ files: { path: string; name: string; lines: number; status?: string; x: number; y: number; w: number; h: number }[];
20
+ groupCard: HTMLElement;
21
+ }
22
+
23
+ const activeGroups = new Map<string, CollapsedGroup>();
24
+
25
+ // ─── Persistence ─────────────────────────────────────────
26
+ function getStorageKey(): string {
27
+ const hash = location.hash?.slice(1) || 'default';
28
+ return `gitmaps:collapsed-dirs:${hash}`;
29
+ }
30
+
31
+ function saveState() {
32
+ try {
33
+ localStorage.setItem(getStorageKey(), JSON.stringify([...collapsedDirs]));
34
+ } catch { }
35
+ }
36
+
37
+ function loadState() {
38
+ try {
39
+ const raw = localStorage.getItem(getStorageKey());
40
+ if (raw) {
41
+ const dirs = JSON.parse(raw);
42
+ collapsedDirs.clear();
43
+ for (const d of dirs) collapsedDirs.add(d);
44
+ }
45
+ } catch { }
46
+ }
47
+
48
+ // ─── Group card rendering ────────────────────────────────
49
+ function createGroupCard(dir: string, files: CollapsedGroup['files']): HTMLElement {
50
+ const card = document.createElement('div');
51
+ card.className = 'file-card group-card';
52
+ card.dataset.groupDir = dir;
53
+
54
+ // Position at the centroid of the files
55
+ let cx = 0, cy = 0;
56
+ for (const f of files) {
57
+ cx += f.x;
58
+ cy += f.y;
59
+ }
60
+ cx /= files.length;
61
+ cy /= files.length;
62
+ card.style.left = `${cx}px`;
63
+ card.style.top = `${cy}px`;
64
+ card.style.width = '320px';
65
+ card.style.maxHeight = 'none';
66
+ card.style.zIndex = '5';
67
+
68
+ const totalLines = files.reduce((s, f) => s + (f.lines || 0), 0);
69
+ const changedCount = files.filter(f => f.status && f.status !== 'unmodified').length;
70
+
71
+ const statusColors: Record<string, string> = {
72
+ added: '#22c55e', modified: '#eab308', deleted: '#ef4444',
73
+ renamed: '#60a5fa', copied: '#a78bfa'
74
+ };
75
+
76
+ const fileListHTML = files
77
+ .sort((a, b) => a.name.localeCompare(b.name))
78
+ .slice(0, 12)
79
+ .map(f => {
80
+ const dot = f.status && statusColors[f.status]
81
+ ? `<span style="color:${statusColors[f.status]}; margin-right: 4px;">●</span>`
82
+ : '';
83
+ return `<div class="group-file-row">${dot}<span class="group-file-name">${f.name}</span><span class="group-file-lines">${f.lines}L</span></div>`;
84
+ })
85
+ .join('');
86
+
87
+ const moreCount = files.length - 12;
88
+ const moreHTML = moreCount > 0
89
+ ? `<div class="group-more">+ ${moreCount} more files</div>`
90
+ : '';
91
+
92
+ card.innerHTML = `
93
+ <div class="file-card-header group-card-header">
94
+ <span class="group-icon">📁</span>
95
+ <span class="file-name">${dir.split('/').pop() || dir}</span>
96
+ <span class="group-meta">${files.length} files</span>
97
+ ${changedCount > 0 ? `<span class="group-changed">${changedCount} changed</span>` : ''}
98
+ <button class="group-expand-btn" title="Expand directory">▼</button>
99
+ </div>
100
+ <div class="group-card-body">
101
+ <div class="group-dir-path">${dir}</div>
102
+ <div class="group-stats">
103
+ <span>📄 ${files.length} files</span>
104
+ <span>📝 ${totalLines.toLocaleString()} lines</span>
105
+ ${changedCount > 0 ? `<span style="color:#eab308">✏️ ${changedCount} changed</span>` : ''}
106
+ </div>
107
+ <div class="group-file-list">
108
+ ${fileListHTML}
109
+ ${moreHTML}
110
+ </div>
111
+ </div>
112
+ `;
113
+
114
+ // Click expand button to uncollapse
115
+ card.querySelector('.group-expand-btn')?.addEventListener('click', (e) => {
116
+ e.stopPropagation();
117
+ expandDirectory(dir);
118
+ });
119
+
120
+ // Double-click to expand
121
+ card.addEventListener('dblclick', (e) => {
122
+ e.stopPropagation();
123
+ expandDirectory(dir);
124
+ });
125
+
126
+ return card;
127
+ }
128
+
129
+ // ─── Collapse a directory ────────────────────────────────
130
+ export function collapseDirectory(ctx: CanvasContext, dir: string) {
131
+ _ctx = ctx;
132
+
133
+ // Already collapsed?
134
+ if (activeGroups.has(dir)) return;
135
+
136
+ const filesToCollapse: CollapsedGroup['files'] = [];
137
+
138
+ // Find all file cards in this directory
139
+ ctx.fileCards.forEach((card, path) => {
140
+ const fileDir = path.includes('/') ? path.substring(0, path.lastIndexOf('/')) : '.';
141
+ if (fileDir === dir) {
142
+ const x = parseFloat(card.style.left) || 0;
143
+ const y = parseFloat(card.style.top) || 0;
144
+ const w = card.offsetWidth || 580;
145
+ const h = card.offsetHeight || 700;
146
+ const name = path.split('/').pop() || path;
147
+ const fileData = card.dataset;
148
+ filesToCollapse.push({
149
+ path, name,
150
+ lines: parseInt(fileData.lines || '0') || 0,
151
+ status: fileData.status || undefined,
152
+ x, y, w, h
153
+ });
154
+ }
155
+ });
156
+
157
+ // Also check deferred cards
158
+ ctx.deferredCards.forEach((entry, path) => {
159
+ const fileDir = path.includes('/') ? path.substring(0, path.lastIndexOf('/')) : '.';
160
+ if (fileDir === dir) {
161
+ const name = path.split('/').pop() || path;
162
+ filesToCollapse.push({
163
+ path, name,
164
+ lines: 0,
165
+ status: entry.isChanged ? 'modified' : undefined,
166
+ x: entry.x, y: entry.y,
167
+ w: entry.size?.width || 580,
168
+ h: entry.size?.height || 700
169
+ });
170
+ }
171
+ });
172
+
173
+ if (filesToCollapse.length === 0) return;
174
+
175
+ // Hide individual cards
176
+ for (const f of filesToCollapse) {
177
+ const card = ctx.fileCards.get(f.path);
178
+ if (card) {
179
+ card.style.display = 'none';
180
+ }
181
+ }
182
+
183
+ // Create group card
184
+ const groupCard = createGroupCard(dir, filesToCollapse);
185
+ ctx.canvas?.appendChild(groupCard);
186
+
187
+ activeGroups.set(dir, { dir, files: filesToCollapse, groupCard });
188
+ collapsedDirs.add(dir);
189
+ saveState();
190
+
191
+ console.log(`[card-groups] Collapsed ${dir} (${filesToCollapse.length} files)`);
192
+ }
193
+
194
+ // ─── Expand a directory ──────────────────────────────────
195
+ export function expandDirectory(dir: string) {
196
+ const ctx = _ctx;
197
+ if (!ctx) return;
198
+
199
+ const group = activeGroups.get(dir);
200
+ if (!group) return;
201
+
202
+ // Remove group card
203
+ group.groupCard.remove();
204
+
205
+ // Show individual cards again
206
+ for (const f of group.files) {
207
+ const card = ctx.fileCards.get(f.path);
208
+ if (card) {
209
+ card.style.display = '';
210
+ }
211
+ }
212
+
213
+ activeGroups.delete(dir);
214
+ collapsedDirs.delete(dir);
215
+ saveState();
216
+
217
+ console.log(`[card-groups] Expanded ${dir}`);
218
+ }
219
+
220
+ // ─── Toggle collapse ─────────────────────────────────────
221
+ export function toggleDirectoryCollapse(ctx: CanvasContext, dir: string) {
222
+ if (activeGroups.has(dir)) {
223
+ expandDirectory(dir);
224
+ } else {
225
+ collapseDirectory(ctx, dir);
226
+ }
227
+ }
228
+
229
+ // ─── Restore collapsed state on load ─────────────────────
230
+ export function restoreCollapsedDirs(ctx: CanvasContext) {
231
+ _ctx = ctx;
232
+ loadState();
233
+ for (const dir of collapsedDirs) {
234
+ collapseDirectory(ctx, dir);
235
+ }
236
+ }
237
+
238
+ // ─── Check if a dir is collapsed ─────────────────────────
239
+ export function isDirCollapsed(dir: string): boolean {
240
+ return collapsedDirs.has(dir);
241
+ }
242
+
243
+ // ─── Get all collapsed dirs ──────────────────────────────
244
+ export function getCollapsedDirs(): string[] {
245
+ return [...collapsedDirs];
246
+ }