gitmaps 1.1.0 → 1.1.2
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/README.md +267 -118
- package/app/[...slug]/page.client.tsx +1 -0
- package/app/[...slug]/page.tsx +6 -0
- package/app/analytics.db +0 -0
- package/app/api/analytics/route.ts +64 -0
- package/app/api/auth/positions/route.ts +95 -33
- package/app/api/build-info/route.ts +19 -0
- package/app/api/chat/route.ts +13 -2
- package/app/api/og-image/route.ts +14 -0
- package/app/api/repo/file-content/route.ts +73 -20
- package/app/api/repo/load/route.test.ts +62 -0
- package/app/api/repo/load/route.ts +41 -1
- package/app/api/repo/pdf-thumb/route.ts +127 -0
- package/app/api/repo/resolve-slug/route.ts +51 -0
- package/app/api/repo/tree/route.ts +188 -104
- package/app/api/version/route.ts +26 -0
- package/app/globals.css +5706 -4938
- package/app/layout.tsx +1279 -490
- package/app/lib/auto-arrange.test.ts +158 -0
- package/app/lib/auto-arrange.ts +147 -0
- package/app/lib/canvas-export.ts +358 -358
- package/app/lib/canvas.ts +625 -564
- package/app/lib/cards.tsx +1361 -916
- package/app/lib/chat.tsx +65 -9
- package/app/lib/code-editor.ts +86 -2
- package/app/lib/context.test.ts +32 -0
- package/app/lib/context.ts +19 -3
- package/app/lib/cursor-sharing.ts +34 -0
- package/app/lib/events.tsx +71 -93
- package/app/lib/export-canvas.ts +287 -0
- package/app/lib/file-card-plugin.ts +148 -148
- package/app/lib/file-modal.tsx +49 -0
- package/app/lib/file-preview.ts +486 -427
- package/app/lib/github-import.test.ts +424 -0
- package/app/lib/initial-route-hydration.test.ts +283 -0
- package/app/lib/initial-route-hydration.ts +202 -0
- package/app/lib/landing-reset.test.ts +99 -0
- package/app/lib/landing-reset.ts +106 -0
- package/app/lib/landing-shell.test.ts +75 -0
- package/app/lib/large-repo-optimization.ts +37 -0
- package/app/lib/layout-snapshots.ts +320 -0
- package/app/lib/loading.test.ts +69 -0
- package/app/lib/loading.tsx +160 -45
- package/app/lib/mount-cleanup.test.ts +52 -0
- package/app/lib/mount-cleanup.ts +34 -0
- package/app/lib/mount-init.test.ts +123 -0
- package/app/lib/mount-init.ts +107 -0
- package/app/lib/mount-lifecycle.test.ts +39 -0
- package/app/lib/mount-lifecycle.ts +12 -0
- package/app/lib/mount-route-wiring.test.ts +87 -0
- package/app/lib/mount-route-wiring.ts +84 -0
- package/app/lib/multi-repo.ts +14 -0
- package/app/lib/onboarding-tutorial.ts +278 -0
- package/app/lib/positions.ts +190 -121
- package/app/lib/recent-commits.test.ts +947 -0
- package/app/lib/recent-commits.ts +227 -0
- package/app/lib/repo-handoff.test.ts +23 -0
- package/app/lib/repo-handoff.ts +16 -0
- package/app/lib/repo-progressive.ts +119 -0
- package/app/lib/repo-select.test.ts +61 -0
- package/app/lib/repo-select.ts +74 -0
- package/app/lib/repo.tsx +1383 -987
- package/app/lib/role.ts +228 -0
- package/app/lib/route-catchall.test.ts +27 -0
- package/app/lib/route-repo-entry.test.ts +95 -0
- package/app/lib/route-repo-entry.ts +36 -0
- package/app/lib/router-contract.test.ts +22 -0
- package/app/lib/router-contract.ts +19 -0
- package/app/lib/shared-layout.test.ts +86 -0
- package/app/lib/shared-layout.ts +82 -0
- package/app/lib/status-bar.test.ts +118 -0
- package/app/lib/status-bar.ts +365 -128
- package/app/lib/sync-controls.test.ts +43 -0
- package/app/lib/sync-controls.tsx +303 -0
- package/app/lib/test-dom.ts +145 -0
- package/app/lib/test-fixtures/router-contract/[...slug]/page.tsx +3 -0
- package/app/lib/test-fixtures/router-contract/api/health/route.ts +3 -0
- package/app/lib/test-fixtures/router-contract/api/version/route.ts +3 -0
- package/app/lib/test-fixtures/router-contract/galaxy-canvas/page.tsx +3 -0
- package/app/lib/test-fixtures/router-contract/page.tsx +3 -0
- package/app/lib/transclusion-smoke.test.ts +163 -0
- package/app/lib/tutorial.ts +301 -0
- package/app/lib/version.ts +93 -0
- package/app/lib/viewport-culling.ts +740 -735
- package/app/lib/virtual-files.ts +456 -0
- package/app/lib/webgl-text.ts +189 -0
- package/app/lib/{galaxydraw-bridge.ts → xydraw-bridge.ts} +485 -482
- package/app/lib/{galaxydraw.test.ts → xydraw.test.ts} +228 -229
- package/app/og-image.png +0 -0
- package/app/page.client.tsx +70 -269
- package/app/page.tsx +15 -16
- package/app/state/machine.js +13 -0
- package/package.json +84 -75
- package/server.ts +10 -0
- package/app/[owner]/[repo]/page.tsx +0 -6
- package/app/[slug]/page.tsx +0 -6
- package/packages/galaxydraw/README.md +0 -296
- package/packages/galaxydraw/banner.png +0 -0
- package/packages/galaxydraw/demo/build-static.ts +0 -100
- package/packages/galaxydraw/demo/client.ts +0 -154
- package/packages/galaxydraw/demo/dist/client.js +0 -8
- package/packages/galaxydraw/demo/index.html +0 -256
- package/packages/galaxydraw/demo/server.ts +0 -96
- package/packages/galaxydraw/dist/index.js +0 -984
- package/packages/galaxydraw/dist/index.js.map +0 -16
- package/packages/galaxydraw/node_modules/.bin/tsc.bunx +0 -0
- package/packages/galaxydraw/node_modules/.bin/tsc.exe +0 -0
- package/packages/galaxydraw/node_modules/.bin/tsserver.bunx +0 -0
- package/packages/galaxydraw/node_modules/.bin/tsserver.exe +0 -0
- package/packages/galaxydraw/package.json +0 -49
- package/packages/galaxydraw/perf.test.ts +0 -284
- package/packages/galaxydraw/src/core/cards.ts +0 -435
- package/packages/galaxydraw/src/core/engine.ts +0 -339
- package/packages/galaxydraw/src/core/events.ts +0 -81
- package/packages/galaxydraw/src/core/layout.ts +0 -136
- package/packages/galaxydraw/src/core/minimap.ts +0 -216
- package/packages/galaxydraw/src/core/state.ts +0 -177
- package/packages/galaxydraw/src/core/viewport.ts +0 -106
- package/packages/galaxydraw/src/galaxydraw.css +0 -166
- package/packages/galaxydraw/src/index.ts +0 -40
- package/packages/galaxydraw/tsconfig.json +0 -30
package/app/page.client.tsx
CHANGED
|
@@ -1,269 +1,70 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
/**
|
|
3
|
-
* page.client.tsx — Slim orchestrator
|
|
4
|
-
*
|
|
5
|
-
* Creates the XState actor, initialises all sub-modules, and returns a
|
|
6
|
-
* cleanup function.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
initCommandPalette(ctx);
|
|
72
|
-
initShortcutsPanel();
|
|
73
|
-
initStatusBar(ctx);
|
|
74
|
-
await loadSavedPositions(ctx); // initial load (may be empty if no repo yet)
|
|
75
|
-
if (disposed) return; // bail if cleaned up during await
|
|
76
|
-
loadHiddenFiles(ctx);
|
|
77
|
-
updateHiddenUI(ctx);
|
|
78
|
-
loadConnections(ctx);
|
|
79
|
-
if (disposed) return; // bail if cleaned up during await
|
|
80
|
-
|
|
81
|
-
// Init auth UI
|
|
82
|
-
setupAuth();
|
|
83
|
-
|
|
84
|
-
// ── Shared Layout Decoder ──────────────────────────────────────────
|
|
85
|
-
const applySharedLayout = async (ctx: CanvasContext) => {
|
|
86
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
87
|
-
const sharedLayout = urlParams.get('layout');
|
|
88
|
-
if (!sharedLayout) return;
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
const parsed = JSON.parse(atob(sharedLayout));
|
|
92
|
-
if (parsed.positions) {
|
|
93
|
-
ctx.positions = new Map(Object.entries(parsed.positions));
|
|
94
|
-
const { savePosition } = await import('./lib/positions');
|
|
95
|
-
// Quick dummy save to trigger debounced persistence
|
|
96
|
-
savePosition(ctx, '_share_', '_trigger_', 0, 0);
|
|
97
|
-
}
|
|
98
|
-
if (parsed.hiddenFiles) {
|
|
99
|
-
ctx.hiddenFiles = new Set(parsed.hiddenFiles);
|
|
100
|
-
const { saveHiddenFiles } = await import('./lib/hidden-files');
|
|
101
|
-
saveHiddenFiles(ctx);
|
|
102
|
-
updateHiddenUI(ctx);
|
|
103
|
-
}
|
|
104
|
-
if (parsed.zoom !== undefined) ctx.actor.send({ type: 'SET_ZOOM', zoom: parsed.zoom });
|
|
105
|
-
if (parsed.offsetX !== undefined) ctx.actor.send({ type: 'SET_OFFSET', x: parsed.offsetX, y: parsed.offsetY });
|
|
106
|
-
if (parsed.cardSizes) {
|
|
107
|
-
for (const [path, size] of Object.entries(parsed.cardSizes)) {
|
|
108
|
-
ctx.actor.send({ type: 'RESIZE_CARD', path, width: (size as any).width, height: (size as any).height });
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const cleanUrl = new URL(window.location.href);
|
|
113
|
-
cleanUrl.searchParams.delete('layout');
|
|
114
|
-
window.history.replaceState({}, '', cleanUrl.toString());
|
|
115
|
-
const { showToast } = await import('./lib/utils');
|
|
116
|
-
showToast('Shared layout applied!', 'success');
|
|
117
|
-
} catch (e) {
|
|
118
|
-
console.error('Failed to decode shared layout', e);
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
// Check URL path for repo slug (e.g. /starwar or /galaxy-canvas/starwar)
|
|
123
|
-
// Fallback: also check hash for legacy URLs (e.g. #starwar)
|
|
124
|
-
const rawPath = decodeURIComponent(window.location.pathname.replace(/^\//, ''));
|
|
125
|
-
// Strip the route-name prefix if we're served at /galaxy-canvas
|
|
126
|
-
const pathSlug = rawPath.replace(/^galaxy-canvas\/?/, '');
|
|
127
|
-
const hashSlug = decodeURIComponent(window.location.hash.replace('#', ''));
|
|
128
|
-
const urlSlug = pathSlug || hashSlug;
|
|
129
|
-
|
|
130
|
-
if (urlSlug) {
|
|
131
|
-
// Migrate legacy hash URL to path URL
|
|
132
|
-
if (hashSlug && !pathSlug) {
|
|
133
|
-
history.replaceState(null, '', '/' + encodeURIComponent(hashSlug));
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Detect GitHub owner/repo pattern (exactly one /, no \ or : which indicate local paths)
|
|
137
|
-
const isGitHubSlug = /^[a-zA-Z0-9._-]+\/[a-zA-Z0-9._-]+$/.test(urlSlug)
|
|
138
|
-
&& !urlSlug.includes('\\') && !urlSlug.includes(':');
|
|
139
|
-
|
|
140
|
-
let resolvedPath: string;
|
|
141
|
-
|
|
142
|
-
if (isGitHubSlug) {
|
|
143
|
-
// Check if we already have a localStorage mapping for this GitHub slug
|
|
144
|
-
const cached = localStorage.getItem(`gitcanvas:slug:${urlSlug}`);
|
|
145
|
-
if (cached) {
|
|
146
|
-
resolvedPath = cached;
|
|
147
|
-
} else {
|
|
148
|
-
// Clone from GitHub and use the local clone path
|
|
149
|
-
const landing = document.getElementById('landingOverlay');
|
|
150
|
-
if (landing) landing.style.display = 'none';
|
|
151
|
-
|
|
152
|
-
// Show loading state
|
|
153
|
-
const loadingEl = document.getElementById('loadingProgress');
|
|
154
|
-
if (loadingEl) {
|
|
155
|
-
loadingEl.style.display = 'flex';
|
|
156
|
-
const msgEl = loadingEl.querySelector('.loading-message');
|
|
157
|
-
if (msgEl) msgEl.textContent = `Cloning ${urlSlug} from GitHub...`;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
try {
|
|
161
|
-
const cloneRes = await fetch('/api/repo/clone', {
|
|
162
|
-
method: 'POST',
|
|
163
|
-
headers: { 'Content-Type': 'application/json' },
|
|
164
|
-
body: JSON.stringify({ url: `https://github.com/${urlSlug}.git` }),
|
|
165
|
-
});
|
|
166
|
-
if (!cloneRes.ok) {
|
|
167
|
-
const err = await cloneRes.json().catch(() => ({ error: 'Clone failed' }));
|
|
168
|
-
throw new Error(err.error || 'Clone failed');
|
|
169
|
-
}
|
|
170
|
-
const cloneData = await cloneRes.json();
|
|
171
|
-
resolvedPath = cloneData.path;
|
|
172
|
-
|
|
173
|
-
// Store slug→path mapping so future visits are instant
|
|
174
|
-
localStorage.setItem(`gitcanvas:slug:${urlSlug}`, resolvedPath);
|
|
175
|
-
} catch (err: any) {
|
|
176
|
-
console.error(`[gitmaps] Failed to clone ${urlSlug}:`, err);
|
|
177
|
-
const { showToast } = await import('./lib/utils');
|
|
178
|
-
showToast(`Failed to clone ${urlSlug}: ${err.message}`, 'error');
|
|
179
|
-
// Fall through — show landing
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
} else {
|
|
184
|
-
// Resolve slug to full path (check localStorage mapping)
|
|
185
|
-
resolvedPath = localStorage.getItem(`gitcanvas:slug:${urlSlug}`) || urlSlug;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Hide landing immediately since we have a repo
|
|
189
|
-
const landing = document.getElementById('landingOverlay');
|
|
190
|
-
if (landing) landing.style.display = 'none';
|
|
191
|
-
|
|
192
|
-
const sel = document.getElementById('repoSelect') as HTMLSelectElement;
|
|
193
|
-
if (sel) sel.value = resolvedPath;
|
|
194
|
-
|
|
195
|
-
// Init layers based on repo
|
|
196
|
-
ctx.actor.send({ type: 'LOAD_REPO', path: resolvedPath });
|
|
197
|
-
ctx.snap().context.repoPath = resolvedPath;
|
|
198
|
-
await loadSavedPositions(ctx); // reload positions for this repo
|
|
199
|
-
if (disposed) return;
|
|
200
|
-
await applySharedLayout(ctx);
|
|
201
|
-
initLayers(ctx);
|
|
202
|
-
renderLayersUI(ctx);
|
|
203
|
-
restoreViewport(ctx);
|
|
204
|
-
updateCanvasTransform(ctx);
|
|
205
|
-
updateZoomUI(ctx);
|
|
206
|
-
|
|
207
|
-
if (!disposed) {
|
|
208
|
-
loadRepository(ctx, resolvedPath);
|
|
209
|
-
updateFavoriteStar(resolvedPath);
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
const saved = localStorage.getItem('gitcanvas:lastRepo');
|
|
213
|
-
if (saved) {
|
|
214
|
-
const sel2 = document.getElementById('repoSelect') as HTMLSelectElement;
|
|
215
|
-
if (sel2) sel2.value = saved;
|
|
216
|
-
|
|
217
|
-
// Set URL path to friendly slug instead of full path
|
|
218
|
-
const savedSlug = saved.replace(/\\/g, '/').split('/').filter(Boolean).pop() || saved;
|
|
219
|
-
history.replaceState(null, '', '/' + encodeURIComponent(savedSlug));
|
|
220
|
-
// Store slug→path mapping
|
|
221
|
-
localStorage.setItem(`gitcanvas:slug:${savedSlug}`, saved);
|
|
222
|
-
|
|
223
|
-
ctx.actor.send({ type: 'LOAD_REPO', path: saved });
|
|
224
|
-
ctx.snap().context.repoPath = saved;
|
|
225
|
-
await loadSavedPositions(ctx);
|
|
226
|
-
if (disposed) return;
|
|
227
|
-
await applySharedLayout(ctx);
|
|
228
|
-
initLayers(ctx);
|
|
229
|
-
renderLayersUI(ctx);
|
|
230
|
-
restoreViewport(ctx);
|
|
231
|
-
updateCanvasTransform(ctx);
|
|
232
|
-
updateZoomUI(ctx);
|
|
233
|
-
|
|
234
|
-
// Actually load the repo data
|
|
235
|
-
if (!disposed) {
|
|
236
|
-
loadRepository(ctx, saved);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Listen for popstate (back/forward navigation with path-based routing)
|
|
242
|
-
window.addEventListener('popstate', () => {
|
|
243
|
-
if (disposed) return;
|
|
244
|
-
const slug = decodeURIComponent(window.location.pathname.replace(/^\//, ''));
|
|
245
|
-
const resolvedPath = localStorage.getItem(`gitcanvas:slug:${slug}`) || slug;
|
|
246
|
-
if (resolvedPath && resolvedPath !== ctx.snap().context.repoPath) {
|
|
247
|
-
const sel3 = document.getElementById('repoSelect') as HTMLSelectElement;
|
|
248
|
-
if (sel3) sel3.value = resolvedPath;
|
|
249
|
-
loadRepository(ctx, resolvedPath);
|
|
250
|
-
updateFavoriteStar(resolvedPath);
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// ─── Boot ────────────────────────────────────────────
|
|
257
|
-
init();
|
|
258
|
-
|
|
259
|
-
// ─── Cleanup ─────────────────────────────────────────
|
|
260
|
-
const cleanup = () => {
|
|
261
|
-
disposed = true;
|
|
262
|
-
(window as any).__gitcanvas_cleanup__ = null;
|
|
263
|
-
try { actor.stop(); } catch (_) { }
|
|
264
|
-
if (ctx.canvasViewport) destroyFilePreview(ctx.canvasViewport);
|
|
265
|
-
clearCanvas(ctx);
|
|
266
|
-
};
|
|
267
|
-
(window as any).__gitcanvas_cleanup__ = cleanup;
|
|
268
|
-
return cleanup;
|
|
269
|
-
}
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* page.client.tsx — Slim orchestrator
|
|
4
|
+
*
|
|
5
|
+
* Creates the XState actor, initialises all sub-modules, and returns a
|
|
6
|
+
* cleanup function. All heavy logic lives in `./lib/*` helpers.
|
|
7
|
+
*/
|
|
8
|
+
import { measure } from 'measure-fn';
|
|
9
|
+
import { createActor } from 'xstate';
|
|
10
|
+
import { canvasMachine } from './state/machine.js';
|
|
11
|
+
import { createCanvasContext } from './lib/context';
|
|
12
|
+
import { registerCanvasMount } from './lib/mount-lifecycle';
|
|
13
|
+
import { applySharedLayout } from './lib/shared-layout';
|
|
14
|
+
import { ensureSvgOverlay, initializeMountUi } from './lib/mount-init';
|
|
15
|
+
import { showLandingPlaceholder as showLandingReset } from './lib/landing-reset';
|
|
16
|
+
import { wireMountRoutes } from './lib/mount-route-wiring';
|
|
17
|
+
import { cleanupMount } from './lib/mount-cleanup';
|
|
18
|
+
|
|
19
|
+
export default function mount(): () => void {
|
|
20
|
+
if ((window as any).__gitcanvas_cleanup__) {
|
|
21
|
+
try {
|
|
22
|
+
(window as any).__gitcanvas_cleanup__();
|
|
23
|
+
} catch {}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const actor = createActor(canvasMachine);
|
|
27
|
+
const ctx = createCanvasContext(actor);
|
|
28
|
+
let disposed = false;
|
|
29
|
+
|
|
30
|
+
function showLandingPlaceholder() {
|
|
31
|
+
showLandingReset(ctx);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function init() {
|
|
35
|
+
return measure('app:init', async () => {
|
|
36
|
+
ctx.canvas = document.getElementById('canvasContent');
|
|
37
|
+
ctx.canvasViewport = document.getElementById('canvasViewport');
|
|
38
|
+
|
|
39
|
+
ensureSvgOverlay(ctx);
|
|
40
|
+
|
|
41
|
+
await initializeMountUi(ctx, actor, {
|
|
42
|
+
isDisposed: () => disposed,
|
|
43
|
+
});
|
|
44
|
+
if (disposed) return;
|
|
45
|
+
|
|
46
|
+
await wireMountRoutes(ctx, {
|
|
47
|
+
isDisposed: () => disposed,
|
|
48
|
+
showLandingPlaceholder,
|
|
49
|
+
updateFavoriteStar: async (path: string) => {
|
|
50
|
+
const mod = await import('./lib/user');
|
|
51
|
+
mod.updateFavoriteStar(path);
|
|
52
|
+
},
|
|
53
|
+
applySharedLayout: () => applySharedLayout(ctx),
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
init();
|
|
59
|
+
|
|
60
|
+
const cleanup = () => {
|
|
61
|
+
void cleanupMount(ctx, actor, {
|
|
62
|
+
markDisposed: () => {
|
|
63
|
+
disposed = true;
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
registerCanvasMount(ctx, cleanup);
|
|
69
|
+
return cleanup;
|
|
70
|
+
}
|
package/app/page.tsx
CHANGED
|
@@ -99,7 +99,7 @@ export default function Page() {
|
|
|
99
99
|
<div className="landing-hero">
|
|
100
100
|
<div className="landing-badge">
|
|
101
101
|
<span className="badge-dot"></span>
|
|
102
|
-
|
|
102
|
+
The Intertwingled Paradigm · $GM Protocol
|
|
103
103
|
</div>
|
|
104
104
|
|
|
105
105
|
<div className="landing-icon">
|
|
@@ -144,17 +144,16 @@ export default function Page() {
|
|
|
144
144
|
<span className="title-maps">Maps</span>
|
|
145
145
|
</h1>
|
|
146
146
|
<p className="landing-subtitle">
|
|
147
|
-
Transcend the file tree. See your codebase in
|
|
148
|
-
<span className="subtitle-accent">
|
|
149
|
-
<span className="subtitle-accent">review AI-generated code spatially instead of one-file-at-a-time.</span>
|
|
147
|
+
Transcend the 1D file tree. See your codebase in five dimensions.<br />
|
|
148
|
+
<span className="subtitle-accent">Spatial Web3 Canvas mapped by Agentic AI Swarms and Gravity Tokenomics.</span>
|
|
150
149
|
</p>
|
|
151
150
|
|
|
152
151
|
{/* Key features inline */}
|
|
153
|
-
<div className="landing-features">
|
|
154
|
-
<div className="feature-pill"><span className="feature-icon">📐</span> Spatial
|
|
155
|
-
<div className="feature-pill"><span className="feature-icon"
|
|
156
|
-
<div className="feature-pill"><span className="feature-icon"
|
|
157
|
-
<div className="feature-pill"><span className="feature-icon"
|
|
152
|
+
<div className="landing-features" style={{ gridTemplateColumns: 'repeat(4, auto)' }}>
|
|
153
|
+
<div className="feature-pill"><span className="feature-icon">📐</span> Spatial Canvas</div>
|
|
154
|
+
<div className="feature-pill"><span className="feature-icon">🤖</span> AI Swarms</div>
|
|
155
|
+
<div className="feature-pill"><span className="feature-icon">💸</span> Minute-by-Minute Yields</div>
|
|
156
|
+
<div className="feature-pill"><span className="feature-icon">⚖️</span> $GM Gravity Score</div>
|
|
158
157
|
</div>
|
|
159
158
|
</div>
|
|
160
159
|
|
|
@@ -201,23 +200,23 @@ export default function Page() {
|
|
|
201
200
|
{/* Stats Row */}
|
|
202
201
|
<div className="landing-stats">
|
|
203
202
|
<div className="landing-stat">
|
|
204
|
-
<span className="stat-num">
|
|
205
|
-
<span className="stat-desc">
|
|
203
|
+
<span className="stat-num">5D</span>
|
|
204
|
+
<span className="stat-desc">Knowledge Graph</span>
|
|
206
205
|
</div>
|
|
207
206
|
<div className="stat-divider"></div>
|
|
208
207
|
<div className="landing-stat">
|
|
209
|
-
<span className="stat-num"
|
|
210
|
-
<span className="stat-desc">
|
|
208
|
+
<span className="stat-num">$GM</span>
|
|
209
|
+
<span className="stat-desc">Gravity Weights</span>
|
|
211
210
|
</div>
|
|
212
211
|
<div className="stat-divider"></div>
|
|
213
212
|
<div className="landing-stat">
|
|
214
213
|
<span className="stat-num">0ms</span>
|
|
215
|
-
<span className="stat-desc">
|
|
214
|
+
<span className="stat-desc">DOM Culling</span>
|
|
216
215
|
</div>
|
|
217
216
|
<div className="stat-divider"></div>
|
|
218
217
|
<div className="landing-stat">
|
|
219
|
-
<span className="stat-num">
|
|
220
|
-
<span className="stat-desc">
|
|
218
|
+
<span className="stat-num">Web3</span>
|
|
219
|
+
<span className="stat-desc">Spatial Economy</span>
|
|
221
220
|
</div>
|
|
222
221
|
</div>
|
|
223
222
|
</div>
|
package/app/state/machine.js
CHANGED
|
@@ -192,5 +192,18 @@ export const canvasMachine = createMachine({
|
|
|
192
192
|
})
|
|
193
193
|
}),
|
|
194
194
|
},
|
|
195
|
+
RESET_APP_STATE: {
|
|
196
|
+
actions: assign({
|
|
197
|
+
repoPath: '',
|
|
198
|
+
commits: [],
|
|
199
|
+
currentCommitHash: null,
|
|
200
|
+
commitFiles: [],
|
|
201
|
+
allFiles: [],
|
|
202
|
+
selectedCards: [],
|
|
203
|
+
connections: [],
|
|
204
|
+
pendingConnection: null,
|
|
205
|
+
error: null,
|
|
206
|
+
}),
|
|
207
|
+
},
|
|
195
208
|
},
|
|
196
209
|
});
|
package/package.json
CHANGED
|
@@ -1,75 +1,84 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "gitmaps",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"bin": {
|
|
6
|
-
"gitmaps": "cli.ts"
|
|
7
|
-
},
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "https://github.com/7flash/gitmaps"
|
|
11
|
-
},
|
|
12
|
-
"homepage": "https://gitmaps.xyz",
|
|
13
|
-
"workspaces": [
|
|
14
|
-
"packages/*"
|
|
15
|
-
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"dev": "bun run server.ts",
|
|
18
|
-
"start": "bun run server.ts",
|
|
19
|
-
"test": "bun test app/lib/
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"@codemirror/
|
|
53
|
-
"@codemirror/
|
|
54
|
-
"@codemirror/lang-
|
|
55
|
-
"@codemirror/
|
|
56
|
-
"@codemirror/
|
|
57
|
-
"@codemirror/
|
|
58
|
-
"@codemirror/
|
|
59
|
-
"@codemirror/
|
|
60
|
-
"@
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "gitmaps",
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"gitmaps": "cli.ts"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/7flash/gitmaps"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://gitmaps.xyz",
|
|
13
|
+
"workspaces": [
|
|
14
|
+
"packages/*"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"dev": "bun run server.ts",
|
|
18
|
+
"start": "bun run server.ts",
|
|
19
|
+
"test": "bun test app/api/repo/load/route.test.ts app/lib/route-catchall.test.ts app/lib/status-bar.test.ts app/lib/xydraw.test.ts app/lib/transclusion-smoke.test.ts app/lib/repo-select.test.ts packages/galaxydraw/perf.test.ts",
|
|
20
|
+
"smoke:browser": "bun scripts/browser-smoke-local.ts",
|
|
21
|
+
"smoke:browser-tools": "bash scripts/browser-smoke-local.sh",
|
|
22
|
+
"smoke:browser-tools:load": "bash scripts/browser-repo-load-smoke.sh",
|
|
23
|
+
"smoke:browser-tools:guard": "bash scripts/browser-smoke-guard.sh",
|
|
24
|
+
"smoke:browser-tools:self-check": "bash scripts/browser-smoke-self-check.sh",
|
|
25
|
+
"smoke:browser-tools:check": "bash scripts/browser-smoke-check.sh",
|
|
26
|
+
"prepublishOnly": "echo 'Publishing gitmaps to npm'"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"git",
|
|
30
|
+
"canvas",
|
|
31
|
+
"visualization",
|
|
32
|
+
"code-review",
|
|
33
|
+
"spatial",
|
|
34
|
+
"infinite-canvas",
|
|
35
|
+
"diff",
|
|
36
|
+
"repository",
|
|
37
|
+
"minimap",
|
|
38
|
+
"codemirror"
|
|
39
|
+
],
|
|
40
|
+
"author": "mements",
|
|
41
|
+
"license": "ISC",
|
|
42
|
+
"description": "Spatial code explorer — see every file at once on an infinite canvas with diffs, layers, and time-travel",
|
|
43
|
+
"files": [
|
|
44
|
+
"cli.ts",
|
|
45
|
+
"server.ts",
|
|
46
|
+
"app/",
|
|
47
|
+
"packages/xydraw/",
|
|
48
|
+
"README.md",
|
|
49
|
+
"banner.png"
|
|
50
|
+
],
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@codemirror/autocomplete": "^6.20.1",
|
|
53
|
+
"@codemirror/commands": "^6.10.2",
|
|
54
|
+
"@codemirror/lang-css": "^6.3.1",
|
|
55
|
+
"@codemirror/lang-html": "^6.4.11",
|
|
56
|
+
"@codemirror/lang-javascript": "^6.2.5",
|
|
57
|
+
"@codemirror/lang-json": "^6.0.2",
|
|
58
|
+
"@codemirror/lang-markdown": "^6.5.0",
|
|
59
|
+
"@codemirror/lang-python": "^6.2.1",
|
|
60
|
+
"@codemirror/lang-yaml": "^6.1.2",
|
|
61
|
+
"@codemirror/language": "^6.12.2",
|
|
62
|
+
"@codemirror/lint": "^6.9.5",
|
|
63
|
+
"@codemirror/search": "^6.6.0",
|
|
64
|
+
"@codemirror/state": "^6.5.4",
|
|
65
|
+
"@codemirror/view": "^6.39.16",
|
|
66
|
+
"@lezer/highlight": "^1.2.3",
|
|
67
|
+
"xydraw": "0.2.0",
|
|
68
|
+
"jsx-ai": "0.1.2",
|
|
69
|
+
"measure-fn": "3.10.1",
|
|
70
|
+
"melina": "link:../melina.js",
|
|
71
|
+
"pixi.js": "^8.17.0",
|
|
72
|
+
"simple-git": "^3.30.0",
|
|
73
|
+
"sqlite-zod-orm": "^3.26.0",
|
|
74
|
+
"xstate": "^5.26.0"
|
|
75
|
+
},
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"@types/bun": "^1.3.10",
|
|
78
|
+
"happy-dom": "^20.8.4",
|
|
79
|
+
"puppeteer": "^24.39.1"
|
|
80
|
+
},
|
|
81
|
+
"overrides": {
|
|
82
|
+
"measure-fn": "3.10.1"
|
|
83
|
+
}
|
|
84
|
+
}
|
package/server.ts
CHANGED
|
@@ -39,6 +39,16 @@ const websocket = {
|
|
|
39
39
|
viewportY: data.viewportY,
|
|
40
40
|
zoom: data.zoom,
|
|
41
41
|
}));
|
|
42
|
+
} else if (data.type === 'editor_sync') {
|
|
43
|
+
ws.publish('cursors', JSON.stringify({
|
|
44
|
+
type: 'editor_sync',
|
|
45
|
+
peerId: ws.data.peerId,
|
|
46
|
+
color: ws.data.color,
|
|
47
|
+
name: data.name || ws.data.peerId,
|
|
48
|
+
file: data.file,
|
|
49
|
+
selections: data.selections,
|
|
50
|
+
typing: data.typing
|
|
51
|
+
}));
|
|
42
52
|
} else if (data.type === 'leave') {
|
|
43
53
|
ws.publish('cursors', JSON.stringify({
|
|
44
54
|
type: 'leave',
|