gitmaps 1.0.0 → 1.1.1
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 +265 -122
- package/app/[...slug]/page.client.tsx +1 -0
- package/app/[...slug]/page.tsx +6 -0
- package/app/[owner]/[repo]/page.client.tsx +5 -0
- package/app/[slug]/page.client.tsx +5 -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/manifest.json/route.ts +20 -0
- package/app/api/og-image/route.ts +14 -0
- package/app/api/pwa-icon/route.ts +14 -0
- package/app/api/repo/clone-stream/route.ts +20 -12
- package/app/api/repo/file-content/route.ts +73 -20
- package/app/api/repo/imports/route.ts +21 -3
- package/app/api/repo/list/route.ts +30 -0
- 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/repo/upload/route.ts +6 -9
- package/app/api/sw.js/route.ts +70 -0
- package/app/api/version/route.ts +26 -0
- package/app/galaxy-canvas/page.client.tsx +2 -0
- package/app/galaxy-canvas/page.tsx +5 -0
- package/app/globals.css +5844 -4694
- package/app/icon.png +0 -0
- package/app/layout.tsx +1284 -467
- 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-text.ts +4 -72
- package/app/lib/canvas.ts +625 -564
- package/app/lib/card-arrangement.ts +21 -7
- package/app/lib/card-context-menu.tsx +2 -2
- package/app/lib/card-groups.ts +9 -2
- package/app/lib/cards.tsx +1361 -914
- package/app/lib/chat.tsx +65 -9
- package/app/lib/code-editor.ts +86 -2
- package/app/lib/connections.tsx +34 -43
- 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 +76 -73
- package/app/lib/export-canvas.ts +287 -0
- package/app/lib/file-card-plugin.ts +148 -134
- package/app/lib/file-modal.tsx +49 -0
- package/app/lib/file-preview.ts +486 -400
- package/app/lib/github-import.test.ts +424 -0
- package/app/lib/global-search.ts +48 -27
- 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/layers.tsx +17 -18
- 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/perf-overlay.ts +78 -0
- package/app/lib/positions.ts +191 -122
- package/app/lib/recent-commits.test.ts +869 -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 -977
- 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/shortcuts-panel.ts +2 -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 -728
- 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 -477
- package/app/lib/{galaxydraw.test.ts → xydraw.test.ts} +228 -229
- package/app/og-image.png +0 -0
- package/app/page.client.tsx +70 -215
- package/app/page.tsx +27 -92
- package/app/state/machine.js +13 -0
- package/banner.png +0 -0
- package/package.json +17 -8
- package/server.ts +11 -1
- package/app/api/connections/route.ts +0 -72
- package/app/api/positions/route.ts +0 -80
- package/app/api/repo/browse/route.ts +0 -55
- package/app/lib/pr-review.ts +0 -374
- 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,215 +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
|
-
await 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 hash for repo slug (or legacy full path)
|
|
123
|
-
const hashValue = decodeURIComponent(window.location.hash.replace('#', ''));
|
|
124
|
-
if (hashValue) {
|
|
125
|
-
// Resolve slug to full path (check localStorage mapping)
|
|
126
|
-
const resolvedPath = localStorage.getItem(`gitcanvas:slug:${hashValue}`) || hashValue;
|
|
127
|
-
|
|
128
|
-
// Hide landing immediately since we have a repo
|
|
129
|
-
const landing = document.getElementById('landingOverlay');
|
|
130
|
-
if (landing) landing.style.display = 'none';
|
|
131
|
-
|
|
132
|
-
const sel = document.getElementById('repoSelect') as HTMLSelectElement;
|
|
133
|
-
if (sel) sel.value = resolvedPath;
|
|
134
|
-
|
|
135
|
-
// Init layers based on repo
|
|
136
|
-
ctx.actor.send({ type: 'LOAD_REPO', path: resolvedPath });
|
|
137
|
-
ctx.snap().context.repoPath = resolvedPath;
|
|
138
|
-
await loadSavedPositions(ctx); // reload positions for this repo
|
|
139
|
-
if (disposed) return;
|
|
140
|
-
await applySharedLayout(ctx);
|
|
141
|
-
initLayers(ctx);
|
|
142
|
-
renderLayersUI(ctx);
|
|
143
|
-
restoreViewport(ctx);
|
|
144
|
-
updateCanvasTransform(ctx);
|
|
145
|
-
updateZoomUI(ctx);
|
|
146
|
-
|
|
147
|
-
if (!disposed) {
|
|
148
|
-
import('./lib/pr-review').then(({ initReviewStore }) => {
|
|
149
|
-
initReviewStore(hashValue);
|
|
150
|
-
});
|
|
151
|
-
loadRepository(ctx, resolvedPath);
|
|
152
|
-
updateFavoriteStar(resolvedPath);
|
|
153
|
-
}
|
|
154
|
-
} else {
|
|
155
|
-
const saved = localStorage.getItem('gitcanvas:lastRepo');
|
|
156
|
-
if (saved) {
|
|
157
|
-
const sel2 = document.getElementById('repoSelect') as HTMLSelectElement;
|
|
158
|
-
if (sel2) sel2.value = saved;
|
|
159
|
-
|
|
160
|
-
// Set URL hash to friendly slug instead of full path
|
|
161
|
-
const savedSlug = saved.replace(/\\/g, '/').split('/').filter(Boolean).pop() || saved;
|
|
162
|
-
history.replaceState(null, '', '#' + encodeURIComponent(savedSlug));
|
|
163
|
-
// Store slug→path mapping
|
|
164
|
-
localStorage.setItem(`gitcanvas:slug:${savedSlug}`, saved);
|
|
165
|
-
|
|
166
|
-
ctx.actor.send({ type: 'LOAD_REPO', path: saved });
|
|
167
|
-
ctx.snap().context.repoPath = saved;
|
|
168
|
-
await loadSavedPositions(ctx);
|
|
169
|
-
if (disposed) return;
|
|
170
|
-
await applySharedLayout(ctx);
|
|
171
|
-
initLayers(ctx);
|
|
172
|
-
renderLayersUI(ctx);
|
|
173
|
-
restoreViewport(ctx);
|
|
174
|
-
updateCanvasTransform(ctx);
|
|
175
|
-
updateZoomUI(ctx);
|
|
176
|
-
|
|
177
|
-
// Actually load the repo data
|
|
178
|
-
if (!disposed) {
|
|
179
|
-
import('./lib/pr-review').then(({ initReviewStore }) => {
|
|
180
|
-
initReviewStore(savedSlug);
|
|
181
|
-
});
|
|
182
|
-
loadRepository(ctx, saved);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Listen for hash changes
|
|
188
|
-
window.addEventListener('hashchange', () => {
|
|
189
|
-
if (disposed) return;
|
|
190
|
-
const hashSlug = decodeURIComponent(window.location.hash.replace('#', ''));
|
|
191
|
-
const resolvedPath = localStorage.getItem(`gitcanvas:slug:${hashSlug}`) || hashSlug;
|
|
192
|
-
if (resolvedPath && resolvedPath !== ctx.snap().context.repoPath) {
|
|
193
|
-
const sel3 = document.getElementById('repoSelect') as HTMLSelectElement;
|
|
194
|
-
if (sel3) sel3.value = resolvedPath;
|
|
195
|
-
loadRepository(ctx, resolvedPath);
|
|
196
|
-
updateFavoriteStar(resolvedPath);
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// ─── Boot ────────────────────────────────────────────
|
|
203
|
-
init();
|
|
204
|
-
|
|
205
|
-
// ─── Cleanup ─────────────────────────────────────────
|
|
206
|
-
const cleanup = () => {
|
|
207
|
-
disposed = true;
|
|
208
|
-
(window as any).__gitcanvas_cleanup__ = null;
|
|
209
|
-
try { actor.stop(); } catch (_) { }
|
|
210
|
-
if (ctx.canvasViewport) destroyFilePreview(ctx.canvasViewport);
|
|
211
|
-
clearCanvas(ctx);
|
|
212
|
-
};
|
|
213
|
-
(window as any).__gitcanvas_cleanup__ = cleanup;
|
|
214
|
-
return cleanup;
|
|
215
|
-
}
|
|
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
|
@@ -51,10 +51,7 @@ async function getFeaturedRepos() {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export default function Page() {
|
|
54
|
-
// Use fallback values synchronously — Melina does NOT support async page components.
|
|
55
|
-
// The GitHub star counts are fetched client-side or pre-cached.
|
|
56
54
|
const featuredRepos = _cachedRepos || FEATURED_REPOS_FALLBACK;
|
|
57
|
-
// Trigger async cache fill for next render
|
|
58
55
|
getFeaturedRepos().catch(() => { });
|
|
59
56
|
|
|
60
57
|
const langColors: Record<string, string> = {
|
|
@@ -98,48 +95,36 @@ export default function Page() {
|
|
|
98
95
|
<div className="landing-mesh"></div>
|
|
99
96
|
|
|
100
97
|
<div className="landing-content">
|
|
101
|
-
{/* Hero Section */}
|
|
98
|
+
{/* Hero Section — integrates the pitch message */}
|
|
102
99
|
<div className="landing-hero">
|
|
103
100
|
<div className="landing-badge">
|
|
104
101
|
<span className="badge-dot"></span>
|
|
105
|
-
|
|
102
|
+
The Intertwingled Paradigm · $GM Protocol
|
|
106
103
|
</div>
|
|
107
104
|
|
|
108
105
|
<div className="landing-icon">
|
|
109
106
|
<svg viewBox="0 0 140 140" width="100" height="100" fill="none">
|
|
110
|
-
{/* Outer ring with dash animation */}
|
|
111
107
|
<circle cx="70" cy="70" r="64" stroke="url(#lgHero)" strokeWidth="1.5" opacity="0.2" strokeDasharray="6 8" className="ring-outer" />
|
|
112
108
|
<circle cx="70" cy="70" r="48" stroke="url(#lgHero)" strokeWidth="1.2" opacity="0.15" strokeDasharray="4 6" className="ring-mid" />
|
|
113
109
|
<circle cx="70" cy="70" r="30" stroke="url(#lgHero)" strokeWidth="1" opacity="0.1" />
|
|
114
|
-
|
|
115
|
-
{/* Center glow core */}
|
|
116
110
|
<circle cx="70" cy="70" r="8" fill="url(#lgHero)" opacity="0.9" className="core-glow" />
|
|
117
111
|
<circle cx="70" cy="70" r="4" fill="#fff" opacity="0.8" />
|
|
118
|
-
|
|
119
|
-
{/* Orbiting nodes with connection lines */}
|
|
120
112
|
<g className="orbit-group">
|
|
121
113
|
<line x1="70" y1="6" x2="70" y2="62" stroke="#a78bfa" strokeWidth="0.6" opacity="0.2" />
|
|
122
114
|
<circle cx="70" cy="6" r="5" fill="#a78bfa" opacity="0.85" className="node-orbit n1" />
|
|
123
115
|
<circle cx="70" cy="6" r="2" fill="#fff" opacity="0.6" />
|
|
124
|
-
|
|
125
116
|
<line x1="126" y1="46" x2="76" y2="68" stroke="#60a5fa" strokeWidth="0.6" opacity="0.2" />
|
|
126
117
|
<circle cx="126" cy="46" r="4.5" fill="#60a5fa" opacity="0.8" className="node-orbit n2" />
|
|
127
118
|
<circle cx="126" cy="46" r="1.8" fill="#fff" opacity="0.5" />
|
|
128
|
-
|
|
129
119
|
<line x1="112" y1="110" x2="74" y2="74" stroke="#34d399" strokeWidth="0.6" opacity="0.18" />
|
|
130
120
|
<circle cx="112" cy="110" r="4" fill="#34d399" opacity="0.75" className="node-orbit n3" />
|
|
131
|
-
|
|
132
121
|
<line x1="28" y1="110" x2="66" y2="74" stroke="#f472b6" strokeWidth="0.6" opacity="0.18" />
|
|
133
122
|
<circle cx="28" cy="110" r="4" fill="#f472b6" opacity="0.65" className="node-orbit n4" />
|
|
134
|
-
|
|
135
123
|
<line x1="14" y1="46" x2="64" y2="68" stroke="#fbbf24" strokeWidth="0.6" opacity="0.2" />
|
|
136
124
|
<circle cx="14" cy="46" r="3.5" fill="#fbbf24" opacity="0.7" className="node-orbit n5" />
|
|
137
|
-
|
|
138
|
-
{/* Extra subtle node */}
|
|
139
125
|
<circle cx="98" cy="20" r="2.5" fill="#818cf8" opacity="0.4" className="node-orbit n6" />
|
|
140
126
|
<circle cx="42" cy="20" r="2" fill="#c084fc" opacity="0.35" />
|
|
141
127
|
</g>
|
|
142
|
-
|
|
143
128
|
<defs>
|
|
144
129
|
<linearGradient id="lgHero" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
145
130
|
<stop offset="0%" stopColor="#a78bfa" />
|
|
@@ -159,89 +144,34 @@ export default function Page() {
|
|
|
159
144
|
<span className="title-maps">Maps</span>
|
|
160
145
|
</h1>
|
|
161
146
|
<p className="landing-subtitle">
|
|
162
|
-
See your codebase in
|
|
163
|
-
<span className="subtitle-accent">
|
|
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>
|
|
164
149
|
</p>
|
|
165
|
-
</div>
|
|
166
150
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
<div className="feature-
|
|
171
|
-
<div className="feature-icon
|
|
172
|
-
|
|
173
|
-
<rect x="3" y="3" width="7" height="7" rx="1" />
|
|
174
|
-
<rect x="14" y="3" width="7" height="7" rx="1" />
|
|
175
|
-
<rect x="3" y="14" width="7" height="7" rx="1" />
|
|
176
|
-
<rect x="14" y="14" width="7" height="7" rx="1" />
|
|
177
|
-
</svg>
|
|
178
|
-
</div>
|
|
179
|
-
<h3>Spatial Code Review</h3>
|
|
180
|
-
<p>Every file becomes a card on an infinite 2D canvas. Arrange, group, and navigate them spatially — not as a flat list.</p>
|
|
181
|
-
</div>
|
|
182
|
-
|
|
183
|
-
<div className="feature-card fc-2">
|
|
184
|
-
<div className="feature-glow"></div>
|
|
185
|
-
<div className="feature-icon-wrap">
|
|
186
|
-
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
|
187
|
-
<circle cx="6" cy="6" r="3" />
|
|
188
|
-
<circle cx="18" cy="18" r="3" />
|
|
189
|
-
<path d="M8.59 13.51l6.83 6.83" />
|
|
190
|
-
<line x1="21" y1="3" x2="14" y2="10" />
|
|
191
|
-
<polyline points="21 10 21 3 14 3" />
|
|
192
|
-
</svg>
|
|
193
|
-
</div>
|
|
194
|
-
<h3>Interwingled Files</h3>
|
|
195
|
-
<p>Draw connections between related lines across files. See how <code>auth.ts:42</code> relates to <code>middleware.ts:15</code> — visually.</p>
|
|
196
|
-
</div>
|
|
197
|
-
|
|
198
|
-
<div className="feature-card fc-3">
|
|
199
|
-
<div className="feature-glow"></div>
|
|
200
|
-
<div className="feature-icon-wrap">
|
|
201
|
-
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
|
202
|
-
<polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2" />
|
|
203
|
-
<line x1="12" y1="22" x2="12" y2="15.5" />
|
|
204
|
-
<polyline points="22 8.5 12 15.5 2 8.5" />
|
|
205
|
-
<polyline points="2 15.5 12 8.5 22 15.5" />
|
|
206
|
-
<line x1="12" y1="2" x2="12" y2="8.5" />
|
|
207
|
-
</svg>
|
|
208
|
-
</div>
|
|
209
|
-
<h3>Layers of Focus</h3>
|
|
210
|
-
<p>Create layers to isolate subsets of files. "Auth layer" shows only auth-related changes. Switch context without losing position.</p>
|
|
211
|
-
</div>
|
|
212
|
-
|
|
213
|
-
<div className="feature-card fc-4">
|
|
214
|
-
<div className="feature-glow"></div>
|
|
215
|
-
<div className="feature-icon-wrap">
|
|
216
|
-
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
|
217
|
-
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
|
|
218
|
-
<polyline points="7.5 4.21 12 6.81 16.5 4.21" />
|
|
219
|
-
<polyline points="7.5 19.79 7.5 14.6 3 12" />
|
|
220
|
-
<polyline points="21 12 16.5 14.6 16.5 19.79" />
|
|
221
|
-
<polyline points="3.27 6.96 12 12.01 20.73 6.96" />
|
|
222
|
-
<line x1="12" y1="22.08" x2="12" y2="12" />
|
|
223
|
-
</svg>
|
|
224
|
-
</div>
|
|
225
|
-
<h3>Clone & Explore</h3>
|
|
226
|
-
<p>Paste any GitHub URL and explore it instantly. Real-time clone progress, smart caching, and full commit timeline navigation.</p>
|
|
151
|
+
{/* Key features inline */}
|
|
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>
|
|
227
157
|
</div>
|
|
228
158
|
</div>
|
|
229
159
|
|
|
230
|
-
{/* Featured Repos —
|
|
160
|
+
{/* Featured Repos — Open in browser */}
|
|
231
161
|
<div className="landing-repos">
|
|
232
162
|
<div className="repos-header">
|
|
233
163
|
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
234
164
|
<path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" />
|
|
235
165
|
<path d="M9 18c-4.51 2-5-2-7-2" />
|
|
236
166
|
</svg>
|
|
237
|
-
<span>Explore popular repositories</span>
|
|
167
|
+
<span>Explore popular repositories — click to open instantly</span>
|
|
238
168
|
</div>
|
|
239
169
|
<div className="repos-grid">
|
|
240
170
|
{featuredRepos.map((repo) => (
|
|
241
|
-
<
|
|
171
|
+
<a
|
|
242
172
|
key={repo.name}
|
|
243
173
|
className="repo-card-btn"
|
|
244
|
-
|
|
174
|
+
href={`/${repo.name}`}
|
|
245
175
|
id={`landing-repo-${repo.name.replace('/', '-')}`}
|
|
246
176
|
>
|
|
247
177
|
<div className="repo-card-name">{repo.name.split('/')[1]}</div>
|
|
@@ -253,7 +183,7 @@ export default function Page() {
|
|
|
253
183
|
</span>
|
|
254
184
|
<span className="repo-card-stars">★ {repo.stars}</span>
|
|
255
185
|
</div>
|
|
256
|
-
</
|
|
186
|
+
</a>
|
|
257
187
|
))}
|
|
258
188
|
</div>
|
|
259
189
|
</div>
|
|
@@ -262,26 +192,31 @@ export default function Page() {
|
|
|
262
192
|
<div className="landing-cta">
|
|
263
193
|
<div className="cta-arrows">
|
|
264
194
|
<span className="cta-arrow a1">←</span>
|
|
265
|
-
<span className="cta-text">Select a
|
|
195
|
+
<span className="cta-text">Select a repo from the sidebar, or click a card above</span>
|
|
266
196
|
</div>
|
|
267
|
-
<div className="cta-or">
|
|
197
|
+
<div className="cta-or">Import any GitHub repo with the sidebar button</div>
|
|
268
198
|
</div>
|
|
269
199
|
|
|
270
200
|
{/* Stats Row */}
|
|
271
201
|
<div className="landing-stats">
|
|
272
202
|
<div className="landing-stat">
|
|
273
|
-
<span className="stat-num"
|
|
274
|
-
<span className="stat-desc">
|
|
203
|
+
<span className="stat-num">5D</span>
|
|
204
|
+
<span className="stat-desc">Knowledge Graph</span>
|
|
205
|
+
</div>
|
|
206
|
+
<div className="stat-divider"></div>
|
|
207
|
+
<div className="landing-stat">
|
|
208
|
+
<span className="stat-num">$GM</span>
|
|
209
|
+
<span className="stat-desc">Gravity Weights</span>
|
|
275
210
|
</div>
|
|
276
211
|
<div className="stat-divider"></div>
|
|
277
212
|
<div className="landing-stat">
|
|
278
213
|
<span className="stat-num">0ms</span>
|
|
279
|
-
<span className="stat-desc">
|
|
214
|
+
<span className="stat-desc">DOM Culling</span>
|
|
280
215
|
</div>
|
|
281
216
|
<div className="stat-divider"></div>
|
|
282
217
|
<div className="landing-stat">
|
|
283
|
-
<span className="stat-num">
|
|
284
|
-
<span className="stat-desc">
|
|
218
|
+
<span className="stat-num">Web3</span>
|
|
219
|
+
<span className="stat-desc">Spatial Economy</span>
|
|
285
220
|
</div>
|
|
286
221
|
</div>
|
|
287
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/banner.png
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gitmaps",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"gitmaps": "cli.ts"
|
|
7
7
|
},
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/7flash/
|
|
10
|
+
"url": "https://github.com/7flash/gitmaps"
|
|
11
11
|
},
|
|
12
12
|
"homepage": "https://gitmaps.xyz",
|
|
13
13
|
"workspaces": [
|
|
@@ -16,7 +16,13 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"dev": "bun run server.ts",
|
|
18
18
|
"start": "bun run server.ts",
|
|
19
|
-
"test": "bun test app/lib/
|
|
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",
|
|
20
26
|
"prepublishOnly": "echo 'Publishing gitmaps to npm'"
|
|
21
27
|
},
|
|
22
28
|
"keywords": [
|
|
@@ -38,7 +44,7 @@
|
|
|
38
44
|
"cli.ts",
|
|
39
45
|
"server.ts",
|
|
40
46
|
"app/",
|
|
41
|
-
"packages/
|
|
47
|
+
"packages/xydraw/",
|
|
42
48
|
"README.md",
|
|
43
49
|
"banner.png"
|
|
44
50
|
],
|
|
@@ -58,18 +64,21 @@
|
|
|
58
64
|
"@codemirror/state": "^6.5.4",
|
|
59
65
|
"@codemirror/view": "^6.39.16",
|
|
60
66
|
"@lezer/highlight": "^1.2.3",
|
|
61
|
-
"
|
|
67
|
+
"xydraw": "0.2.0",
|
|
62
68
|
"jsx-ai": "0.1.2",
|
|
63
69
|
"measure-fn": "3.10.1",
|
|
64
|
-
"melina": "
|
|
70
|
+
"melina": "link:../melina.js",
|
|
71
|
+
"pixi.js": "^8.17.0",
|
|
65
72
|
"simple-git": "^3.30.0",
|
|
66
73
|
"sqlite-zod-orm": "^3.26.0",
|
|
67
74
|
"xstate": "^5.26.0"
|
|
68
75
|
},
|
|
69
76
|
"devDependencies": {
|
|
70
|
-
"@types/bun": "^1.3.10"
|
|
77
|
+
"@types/bun": "^1.3.10",
|
|
78
|
+
"happy-dom": "^20.8.4",
|
|
79
|
+
"puppeteer": "^24.39.1"
|
|
71
80
|
},
|
|
72
81
|
"overrides": {
|
|
73
82
|
"measure-fn": "3.10.1"
|
|
74
83
|
}
|
|
75
|
-
}
|
|
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',
|
|
@@ -59,4 +69,4 @@ const websocket = {
|
|
|
59
69
|
serve(createAppRouter({
|
|
60
70
|
appDir,
|
|
61
71
|
globalCss: path.join(appDir, 'globals.css'),
|
|
62
|
-
}), { port: parseInt(process.env.BUN_PORT || "
|
|
72
|
+
}), { port: parseInt(process.env.PORT || process.env.BUN_PORT || "3335"), websocket });
|