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.
- package/README.md +167 -0
- package/app/api/auth/favorites/route.ts +56 -0
- package/app/api/auth/github/callback/route.ts +103 -0
- package/app/api/auth/github/route.ts +32 -0
- package/app/api/auth/me/route.ts +52 -0
- package/app/api/auth/positions/route.ts +50 -0
- package/app/api/chat/route.ts +101 -0
- package/app/api/connections/route.ts +72 -0
- package/app/api/github/repos/route.ts +111 -0
- package/app/api/positions/route.ts +80 -0
- package/app/api/repo/branch-diff/route.ts +201 -0
- package/app/api/repo/branches/route.ts +53 -0
- package/app/api/repo/browse/route.ts +55 -0
- package/app/api/repo/clone/route.ts +78 -0
- package/app/api/repo/clone-stream/route.ts +131 -0
- package/app/api/repo/file-content/route.ts +28 -0
- package/app/api/repo/file-delete/route.ts +62 -0
- package/app/api/repo/file-history/route.ts +45 -0
- package/app/api/repo/file-rename/route.ts +83 -0
- package/app/api/repo/file-save/route.ts +45 -0
- package/app/api/repo/files/route.ts +169 -0
- package/app/api/repo/git-blame/route.ts +86 -0
- package/app/api/repo/git-commit/route.ts +40 -0
- package/app/api/repo/git-heatmap/route.ts +55 -0
- package/app/api/repo/imports/route.ts +154 -0
- package/app/api/repo/load/route.ts +56 -0
- package/app/api/repo/mode/route.ts +14 -0
- package/app/api/repo/search/route.ts +127 -0
- package/app/api/repo/tree/route.ts +104 -0
- package/app/api/repo/upload/route.ts +53 -0
- package/app/api/repo/validate-path.ts +53 -0
- package/app/canvas_users.db +0 -0
- package/app/canvas_users.db-shm +0 -0
- package/app/canvas_users.db-wal +0 -0
- package/app/globals.css +7899 -0
- package/app/layout.tsx +493 -0
- package/app/lib/auth.ts +193 -0
- package/app/lib/auto-save.ts +137 -0
- package/app/lib/branch-compare.ts +443 -0
- package/app/lib/breadcrumbs.ts +170 -0
- package/app/lib/canvas-export.ts +358 -0
- package/app/lib/canvas-text.ts +912 -0
- package/app/lib/canvas.ts +564 -0
- package/app/lib/card-arrangement.ts +188 -0
- package/app/lib/card-context-menu.tsx +453 -0
- package/app/lib/card-diff-markers.ts +270 -0
- package/app/lib/card-expand.ts +189 -0
- package/app/lib/card-groups.ts +246 -0
- package/app/lib/cards.tsx +914 -0
- package/app/lib/chat.tsx +308 -0
- package/app/lib/code-editor.ts +508 -0
- package/app/lib/command-palette.ts +262 -0
- package/app/lib/connections.tsx +1037 -0
- package/app/lib/context.ts +94 -0
- package/app/lib/cursor-sharing.ts +281 -0
- package/app/lib/dependency-graph.ts +438 -0
- package/app/lib/events.tsx +1747 -0
- package/app/lib/file-card-plugin.ts +134 -0
- package/app/lib/file-modal.tsx +849 -0
- package/app/lib/file-preview.ts +400 -0
- package/app/lib/file-tabs.ts +318 -0
- package/app/lib/galaxydraw-bridge.ts +477 -0
- package/app/lib/galaxydraw.test.ts +229 -0
- package/app/lib/global-search.ts +264 -0
- package/app/lib/goto-definition.ts +224 -0
- package/app/lib/heatmap.ts +178 -0
- package/app/lib/hidden-files.tsx +222 -0
- package/app/lib/layers.ts +0 -0
- package/app/lib/layers.tsx +365 -0
- package/app/lib/loading.tsx +45 -0
- package/app/lib/multi-repo.ts +286 -0
- package/app/lib/new-file-dialog.tsx +230 -0
- package/app/lib/onboarding.tsx +213 -0
- package/app/lib/perf-overlay.ts +360 -0
- package/app/lib/positions.ts +176 -0
- package/app/lib/pr-review.ts +374 -0
- package/app/lib/production-mode.ts +47 -0
- package/app/lib/repo.tsx +977 -0
- package/app/lib/settings-modal.tsx +374 -0
- package/app/lib/settings.ts +97 -0
- package/app/lib/shortcuts-panel.ts +141 -0
- package/app/lib/status-bar.ts +128 -0
- package/app/lib/symbol-outline.ts +212 -0
- package/app/lib/syntax.ts +177 -0
- package/app/lib/tab-diff.ts +238 -0
- package/app/lib/user.tsx +133 -0
- package/app/lib/utils.ts +78 -0
- package/app/lib/viewport-culling.ts +728 -0
- package/app/page.client.tsx +215 -0
- package/app/page.tsx +291 -0
- package/app/state/machine.js +196 -0
- package/app/styles/main.css +2168 -0
- package/banner.png +0 -0
- package/cli.ts +44 -0
- package/package.json +75 -0
- package/packages/galaxydraw/README.md +296 -0
- package/packages/galaxydraw/banner.png +0 -0
- package/packages/galaxydraw/demo/build-static.ts +100 -0
- package/packages/galaxydraw/demo/client.ts +154 -0
- package/packages/galaxydraw/demo/dist/client.js +8 -0
- package/packages/galaxydraw/demo/index.html +256 -0
- package/packages/galaxydraw/demo/server.ts +96 -0
- package/packages/galaxydraw/dist/index.js +984 -0
- package/packages/galaxydraw/dist/index.js.map +16 -0
- 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 +49 -0
- package/packages/galaxydraw/perf.test.ts +284 -0
- package/packages/galaxydraw/src/core/cards.ts +435 -0
- package/packages/galaxydraw/src/core/engine.ts +339 -0
- package/packages/galaxydraw/src/core/events.ts +81 -0
- package/packages/galaxydraw/src/core/layout.ts +136 -0
- package/packages/galaxydraw/src/core/minimap.ts +216 -0
- package/packages/galaxydraw/src/core/state.ts +177 -0
- package/packages/galaxydraw/src/core/viewport.ts +106 -0
- package/packages/galaxydraw/src/galaxydraw.css +166 -0
- package/packages/galaxydraw/src/index.ts +40 -0
- package/packages/galaxydraw/tsconfig.json +30 -0
- package/server.ts +62 -0
package/app/layout.tsx
ADDED
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Root Layout — JSX server component
|
|
3
|
+
*
|
|
4
|
+
* Returns proper JSX elements. The `children` prop is the page content as JSX.
|
|
5
|
+
* All interactivity is in page.client.tsx.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export default function RootLayout({ children }: { children: any }) {
|
|
9
|
+
return (
|
|
10
|
+
<html lang="en">
|
|
11
|
+
<head>
|
|
12
|
+
<meta charSet="UTF-8" />
|
|
13
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
|
14
|
+
<meta name="description" content="GitMaps - See your codebase in a new dimension. Spatial code explorer." />
|
|
15
|
+
<title>GitMaps — Spatial Code Explorer</title>
|
|
16
|
+
<link rel="icon" href="data:," />
|
|
17
|
+
<link
|
|
18
|
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
|
|
19
|
+
rel="stylesheet"
|
|
20
|
+
/>
|
|
21
|
+
</head>
|
|
22
|
+
<body>
|
|
23
|
+
<div id="app">
|
|
24
|
+
<nav className="sidebar">
|
|
25
|
+
<div className="sidebar-header">
|
|
26
|
+
<div className="logo">
|
|
27
|
+
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="2">
|
|
28
|
+
<circle cx="12" cy="12" r="3" />
|
|
29
|
+
<circle cx="12" cy="4" r="1.5" />
|
|
30
|
+
<circle cx="12" cy="20" r="1.5" />
|
|
31
|
+
<circle cx="4" cy="8" r="1.5" />
|
|
32
|
+
<circle cx="20" cy="8" r="1.5" />
|
|
33
|
+
<circle cx="4" cy="16" r="1.5" />
|
|
34
|
+
<circle cx="20" cy="16" r="1.5" />
|
|
35
|
+
<path d="M12 7v2M12 15v2M8.5 9.5l-2.5-1M15.5 9.5l2.5-1M8.5 14.5l-2.5 1M15.5 14.5l2.5 1" />
|
|
36
|
+
</svg>
|
|
37
|
+
<span>GitMaps</span>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div className="repo-selector">
|
|
42
|
+
<select id="repoSelect" className="repo-dropdown">
|
|
43
|
+
<option value="">Select a repository...</option>
|
|
44
|
+
</select>
|
|
45
|
+
<input type="text" id="repoPath" style={{ display: 'none' }} />
|
|
46
|
+
<input type="file" id="folderPickerInput" style={{ display: 'none' }} />
|
|
47
|
+
<div className="clone-status" id="cloneStatus" style={{ display: 'none' }}></div>
|
|
48
|
+
|
|
49
|
+
<button id="githubImportBtn" className="github-import-btn" title="Import from GitHub">
|
|
50
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
|
|
51
|
+
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" />
|
|
52
|
+
</svg>
|
|
53
|
+
Import from GitHub
|
|
54
|
+
</button>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div id="repoTabs" style={{ display: 'none', gap: '6px', padding: '0 12px 8px', flexWrap: 'wrap' }}></div>
|
|
58
|
+
|
|
59
|
+
<div className="commit-timeline" id="commitTimeline">
|
|
60
|
+
<div className="section-header">
|
|
61
|
+
<span className="section-title">History</span>
|
|
62
|
+
<span className="badge" id="commitCount">0</span>
|
|
63
|
+
</div>
|
|
64
|
+
<div className="timeline-container" id="timelineContainer">
|
|
65
|
+
<div className="empty-state">
|
|
66
|
+
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.5" opacity="0.3">
|
|
67
|
+
<circle cx="12" cy="12" r="10" />
|
|
68
|
+
<path d="M12 6v6l4 2" />
|
|
69
|
+
</svg>
|
|
70
|
+
<p>Load a repository</p>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<div className="sidebar-bottom">
|
|
76
|
+
<div className="canvas-controls">
|
|
77
|
+
<div className="control-row">
|
|
78
|
+
<button id="resetView" className="btn-ghost" title="Reset View">
|
|
79
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
80
|
+
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" />
|
|
81
|
+
<path d="M3 3v5h5" />
|
|
82
|
+
</svg>
|
|
83
|
+
</button>
|
|
84
|
+
<button id="fitAll" className="btn-ghost" title="Fit All">
|
|
85
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
86
|
+
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" />
|
|
87
|
+
</svg>
|
|
88
|
+
</button>
|
|
89
|
+
<div className="zoom-inline">
|
|
90
|
+
<input type="range" id="zoomSlider" min="0.1" max="3" step="0.1" defaultValue="1" />
|
|
91
|
+
<span id="zoomValue">100%</span>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div className="hotkey-toggle-wrapper">
|
|
97
|
+
<button id="hotkeyToggle" className="btn-ghost hotkey-toggle" title="Keyboard shortcuts">
|
|
98
|
+
<span>?</span>
|
|
99
|
+
</button>
|
|
100
|
+
<div className="hotkey-popup" id="hotkeyPopup">
|
|
101
|
+
<div className="hotkey-popup-title">Keyboard Shortcuts</div>
|
|
102
|
+
<div className="hotkey-grid">
|
|
103
|
+
<div className="hk"><kbd>Scroll</kbd> Zoom</div>
|
|
104
|
+
<div className="hk"><kbd>Space+Drag</kbd> Pan</div>
|
|
105
|
+
<div className="hk"><kbd>Click</kbd> Select</div>
|
|
106
|
+
<div className="hk"><kbd>Shift+Click</kbd> Multi-select</div>
|
|
107
|
+
<div className="hk"><kbd>Drag canvas</kbd> Rect select</div>
|
|
108
|
+
<div className="hk"><kbd>Drag card</kbd> Move</div>
|
|
109
|
+
<div className="hk"><kbd>Del</kbd> Hide file</div>
|
|
110
|
+
<div className="hk"><kbd>H</kbd> Arrange row</div>
|
|
111
|
+
<div className="hk"><kbd>V</kbd> Arrange column</div>
|
|
112
|
+
<div className="hk"><kbd>G</kbd> Arrange grid</div>
|
|
113
|
+
<div className="hk"><kbd>W</kbd> Fit to screen</div>
|
|
114
|
+
<div className="hk"><kbd>Ctrl+F</kbd> Search across files</div>
|
|
115
|
+
<div className="hk"><kbd>Ctrl+O</kbd> Find file</div>
|
|
116
|
+
<div className="hk"><kbd>Ctrl +/-</kbd> Text zoom</div>
|
|
117
|
+
<div className="hk"><kbd>Dbl-click</kbd> Open editor</div>
|
|
118
|
+
<div className="hk"><kbd>Alt+Click</kbd> Connect lines</div>
|
|
119
|
+
<div className="hk"><kbd>Arrow keys</kbd> Prev/next commit</div>
|
|
120
|
+
<div className="hk"><kbd>Ctrl+N</kbd> New file</div>
|
|
121
|
+
<div className="hk"><kbd>Ctrl+S</kbd> Save (in editor)</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</nav>
|
|
127
|
+
|
|
128
|
+
<main className="canvas-area">
|
|
129
|
+
<div className="canvas-header">
|
|
130
|
+
<div className="header-left">
|
|
131
|
+
<div className="current-commit" id="currentCommitInfo">
|
|
132
|
+
<span className="commit-hash-label">No commit selected</span>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
<div className="header-right">
|
|
136
|
+
<div className="arrange-toolbar" id="arrangeToolbar" style={{ display: 'none' }}>
|
|
137
|
+
<span className="arrange-label">Arrange:</span>
|
|
138
|
+
<button id="arrangeRow" className="btn-ghost btn-xs" title="Arrange in row (H)">
|
|
139
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
140
|
+
<rect x="2" y="7" width="5" height="10" rx="1" />
|
|
141
|
+
<rect x="9.5" y="7" width="5" height="10" rx="1" />
|
|
142
|
+
<rect x="17" y="7" width="5" height="10" rx="1" />
|
|
143
|
+
</svg>
|
|
144
|
+
</button>
|
|
145
|
+
<button id="arrangeCol" className="btn-ghost btn-xs" title="Arrange in column (V)">
|
|
146
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
147
|
+
<rect x="4" y="2" width="16" height="5" rx="1" />
|
|
148
|
+
<rect x="4" y="9.5" width="16" height="5" rx="1" />
|
|
149
|
+
<rect x="4" y="17" width="16" height="5" rx="1" />
|
|
150
|
+
</svg>
|
|
151
|
+
</button>
|
|
152
|
+
<button id="arrangeGrid" className="btn-ghost btn-xs" title="Arrange in grid (G)">
|
|
153
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
154
|
+
<rect x="3" y="3" width="7" height="7" rx="1" />
|
|
155
|
+
<rect x="14" y="3" width="7" height="7" rx="1" />
|
|
156
|
+
<rect x="3" y="14" width="7" height="7" rx="1" />
|
|
157
|
+
<rect x="14" y="14" width="7" height="7" rx="1" />
|
|
158
|
+
</svg>
|
|
159
|
+
</button>
|
|
160
|
+
<div style={{ width: 1, height: 16, background: 'var(--border)', margin: '0 4px' }}></div>
|
|
161
|
+
<button id="arrangeFit" className="btn-ghost btn-xs" title="Reset Size (W)">
|
|
162
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
163
|
+
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" />
|
|
164
|
+
</svg>
|
|
165
|
+
</button>
|
|
166
|
+
<button id="arrangeAI" className="btn-ghost btn-xs" title="Explain with AI...">
|
|
167
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
|
|
168
|
+
<path d="M11 2h2v4h-2zm0 16h2v4h-2zm11-7v2h-4v-2zm-16 0v2H2v-2zm12.3-5.3l1.4 1.4-2.8 2.8-1.4-1.4zm-9.8 9.8l1.4 1.4-2.8 2.8-1.4-1.4z" />
|
|
169
|
+
</svg>
|
|
170
|
+
</button>
|
|
171
|
+
</div>
|
|
172
|
+
<button id="toggleChangedFiles" className="btn-ghost btn-sm" title="Show changed files">
|
|
173
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
174
|
+
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" />
|
|
175
|
+
<polyline points="14 2 14 8 20 8" />
|
|
176
|
+
</svg>
|
|
177
|
+
<span id="fileCount">0</span>
|
|
178
|
+
</button>
|
|
179
|
+
<button id="showHidden" className="btn-ghost btn-sm" title="Show hidden files" style={{ display: 'none' }}>
|
|
180
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
181
|
+
<path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94" />
|
|
182
|
+
<path d="M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19" />
|
|
183
|
+
<line x1="1" y1="1" x2="23" y2="23" />
|
|
184
|
+
</svg>
|
|
185
|
+
<span id="hiddenCount">0</span>
|
|
186
|
+
</button>
|
|
187
|
+
<button id="toggleConnections" className="btn-ghost btn-sm" title="Toggle connection lines">
|
|
188
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
189
|
+
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
|
|
190
|
+
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
|
|
191
|
+
</svg>
|
|
192
|
+
</button>
|
|
193
|
+
<button id="dep-graph-btn" className="btn-ghost btn-sm" title="Toggle dependency graph (Ctrl+G)">
|
|
194
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
195
|
+
<circle cx="5" cy="5" r="2.5" /><circle cx="19" cy="5" r="2.5" />
|
|
196
|
+
<circle cx="12" cy="19" r="2.5" /><line x1="7" y1="6" x2="17" y2="6" />
|
|
197
|
+
<line x1="6" y1="7" x2="11" y2="17" /><line x1="18" y1="7" x2="13" y2="17" />
|
|
198
|
+
</svg>
|
|
199
|
+
</button>
|
|
200
|
+
<button id="toggleCanvasText" className="btn-ghost btn-sm" title="Toggle text rendering mode (DOM vs WebGL/Canvas)">
|
|
201
|
+
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
202
|
+
<polyline points="4 7 4 4 20 4 20 7" />
|
|
203
|
+
<line x1="9" y1="20" x2="15" y2="20" />
|
|
204
|
+
<line x1="12" y1="4" x2="12" y2="20" />
|
|
205
|
+
</svg>
|
|
206
|
+
</button>
|
|
207
|
+
<button id="autoDetectImports" className="btn-ghost btn-sm" title="Auto-detect import connections">
|
|
208
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
209
|
+
<path d="M9 3H5a2 2 0 00-2 2v4m6-6h10a2 2 0 012 2v4M9 3v18m0 0h10a2 2 0 002-2v-4M9 21H5a2 2 0 01-2-2v-4" />
|
|
210
|
+
<path d="M14 9l2 2-2 2" />
|
|
211
|
+
</svg>
|
|
212
|
+
</button>
|
|
213
|
+
<button id="shareLayout" className="btn-ghost btn-sm" title="Share Layout (Copy URL)">
|
|
214
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
215
|
+
<circle cx="18" cy="5" r="3" />
|
|
216
|
+
<circle cx="6" cy="12" r="3" />
|
|
217
|
+
<circle cx="18" cy="19" r="3" />
|
|
218
|
+
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49" />
|
|
219
|
+
<line x1="15.41" y1="6.51" x2="8.59" y2="10.49" />
|
|
220
|
+
</svg>
|
|
221
|
+
</button>
|
|
222
|
+
<button id="helpOnboarding" className="btn-ghost btn-sm" title="Replay Tutorial (?)">
|
|
223
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
224
|
+
<circle cx="12" cy="12" r="10" />
|
|
225
|
+
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" />
|
|
226
|
+
<line x1="12" y1="17" x2="12.01" y2="17" />
|
|
227
|
+
</svg>
|
|
228
|
+
</button>
|
|
229
|
+
<button id="toggleControlMode" className="btn-ghost btn-sm" title="Toggle control mode: Simple (drag=pan) / Advanced (space+drag=pan)">
|
|
230
|
+
<svg id="controlModeIcon" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
231
|
+
{/* Default: Advanced (crosshair) — gets swapped by JS */}
|
|
232
|
+
<circle cx="12" cy="12" r="10" />
|
|
233
|
+
<line x1="12" y1="2" x2="12" y2="6" />
|
|
234
|
+
<line x1="12" y1="18" x2="12" y2="22" />
|
|
235
|
+
<line x1="2" y1="12" x2="6" y2="12" />
|
|
236
|
+
<line x1="18" y1="12" x2="22" y2="12" />
|
|
237
|
+
</svg>
|
|
238
|
+
</button>
|
|
239
|
+
<button id="openGlobalSearch" className="btn-ghost btn-sm" title="Search Files (Ctrl+F)">
|
|
240
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
241
|
+
<circle cx="11" cy="11" r="8" /><line x1="21" y1="21" x2="16.65" y2="16.65" />
|
|
242
|
+
</svg>
|
|
243
|
+
</button>
|
|
244
|
+
<button id="openBranchCompare" className="btn-ghost btn-sm" title="Compare Branches">
|
|
245
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
246
|
+
<circle cx="18" cy="18" r="3" /><circle cx="6" cy="6" r="3" />
|
|
247
|
+
<path d="M13 6h3a2 2 0 0 1 2 2v7" />
|
|
248
|
+
<path d="M6 9v12" />
|
|
249
|
+
</svg>
|
|
250
|
+
</button>
|
|
251
|
+
<button id="openSettings" className="btn-ghost btn-sm" title="Settings">
|
|
252
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
253
|
+
<circle cx="12" cy="12" r="3" />
|
|
254
|
+
<path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z" />
|
|
255
|
+
</svg>
|
|
256
|
+
</button>
|
|
257
|
+
<button id="toggleCanvasChat" className="btn-ghost btn-sm ai-chat-btn" title="AI Chat">
|
|
258
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
259
|
+
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" />
|
|
260
|
+
</svg>
|
|
261
|
+
AI
|
|
262
|
+
</button>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
{children}
|
|
267
|
+
|
|
268
|
+
{/* Changed Files Panel */}
|
|
269
|
+
<div className="changed-files-panel" id="changedFilesPanel" style={{ display: 'none' }}>
|
|
270
|
+
<div className="panel-header">
|
|
271
|
+
<span className="panel-title">Changed Files</span>
|
|
272
|
+
<button id="closeChangedFiles" className="btn-ghost btn-xs" title="Close">
|
|
273
|
+
<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="2.5">
|
|
274
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
275
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
276
|
+
</svg>
|
|
277
|
+
</button>
|
|
278
|
+
</div>
|
|
279
|
+
<div className="changed-files-list" id="changedFilesList"></div>
|
|
280
|
+
</div>
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
<div className="minimap-container">
|
|
285
|
+
<div className="minimap" id="minimap">
|
|
286
|
+
<div className="minimap-viewport" id="minimapViewport"></div>
|
|
287
|
+
</div>
|
|
288
|
+
<button id="expandMinimap" className="btn-ghost btn-xs minimap-expand" title="Expand minimap">
|
|
289
|
+
<svg viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" strokeWidth="2">
|
|
290
|
+
<polyline points="15 3 21 3 21 9" />
|
|
291
|
+
<polyline points="9 21 3 21 3 15" />
|
|
292
|
+
<line x1="21" y1="3" x2="14" y2="10" />
|
|
293
|
+
<line x1="3" y1="21" x2="10" y2="14" />
|
|
294
|
+
</svg>
|
|
295
|
+
</button>
|
|
296
|
+
</div>
|
|
297
|
+
|
|
298
|
+
{/* Sticky Zoom Controls — floating pill, bottom-right */}
|
|
299
|
+
<div id="stickyZoomControls" className="sticky-zoom-pill">
|
|
300
|
+
<button id="stickyZoomOut" className="sz-btn" title="Zoom out">
|
|
301
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2.5">
|
|
302
|
+
<line x1="5" y1="12" x2="19" y2="12" />
|
|
303
|
+
</svg>
|
|
304
|
+
</button>
|
|
305
|
+
<input type="range" id="stickyZoomSlider" className="sz-slider" min="0.1" max="3" step="0.05" defaultValue="1" />
|
|
306
|
+
<button id="stickyZoomIn" className="sz-btn" title="Zoom in">
|
|
307
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2.5">
|
|
308
|
+
<line x1="12" y1="5" x2="12" y2="19" />
|
|
309
|
+
<line x1="5" y1="12" x2="19" y2="12" />
|
|
310
|
+
</svg>
|
|
311
|
+
</button>
|
|
312
|
+
<span id="stickyZoomValue" className="sz-value">100%</span>
|
|
313
|
+
<div className="sz-divider" />
|
|
314
|
+
<button id="stickyFitAll" className="sz-btn sz-fit" title="Fit all cards">
|
|
315
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
316
|
+
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" />
|
|
317
|
+
</svg>
|
|
318
|
+
</button>
|
|
319
|
+
</div>
|
|
320
|
+
|
|
321
|
+
{/* Bottom Layers Bar */}
|
|
322
|
+
<div id="layersBarContainer"></div>
|
|
323
|
+
</main>
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
{/* File Preview Modal */}
|
|
327
|
+
<div className="file-preview-modal" id="filePreviewModal">
|
|
328
|
+
<div className="modal-backdrop"></div>
|
|
329
|
+
<div className="modal-content">
|
|
330
|
+
<div className="modal-header">
|
|
331
|
+
<div className="modal-header-left">
|
|
332
|
+
<span className="file-path" id="previewFilePath"></span>
|
|
333
|
+
<span className="modal-line-count" id="previewLineCount"></span>
|
|
334
|
+
<span className="modal-file-status" id="previewFileStatus"></span>
|
|
335
|
+
</div>
|
|
336
|
+
<div className="modal-header-right">
|
|
337
|
+
<div className="modal-diff-nav" id="modalDiffNav" style={{ display: 'none', marginRight: '16px', gap: '4px', alignItems: 'center' }}>
|
|
338
|
+
<button className="btn-ghost btn-xs" id="diffNavPrev" title="Previous changed file (k)">
|
|
339
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2.5"><polyline points="15 18 9 12 15 6"></polyline></svg>
|
|
340
|
+
</button>
|
|
341
|
+
<button className="btn-ghost btn-xs" id="diffNavNext" title="Next changed file (j)">
|
|
342
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2.5"><polyline points="9 18 15 12 9 6"></polyline></svg>
|
|
343
|
+
</button>
|
|
344
|
+
</div>
|
|
345
|
+
<div className="modal-view-tabs" id="modalViewTabs">
|
|
346
|
+
<button className="modal-tab active" data-view="edit">
|
|
347
|
+
<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="2">
|
|
348
|
+
<path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7" />
|
|
349
|
+
<path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z" />
|
|
350
|
+
</svg>
|
|
351
|
+
Edit
|
|
352
|
+
</button>
|
|
353
|
+
<button className="modal-tab" data-view="diff">
|
|
354
|
+
<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="2">
|
|
355
|
+
<path d="M12 3v18M3 12h18" />
|
|
356
|
+
</svg>
|
|
357
|
+
Diff
|
|
358
|
+
</button>
|
|
359
|
+
</div>
|
|
360
|
+
<span className="modal-save-status" id="modalSaveStatus" style={{ display: 'none' }}></span>
|
|
361
|
+
<button className="btn-ghost btn-xs modal-outline-toggle" id="outlineToggle" title="Toggle symbol outline (Ctrl+Shift+O)">
|
|
362
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
363
|
+
<line x1="8" y1="6" x2="21" y2="6" /><line x1="8" y1="12" x2="21" y2="12" /><line x1="8" y1="18" x2="21" y2="18" />
|
|
364
|
+
<line x1="3" y1="6" x2="3.01" y2="6" /><line x1="3" y1="12" x2="3.01" y2="12" /><line x1="3" y1="18" x2="3.01" y2="18" />
|
|
365
|
+
</svg>
|
|
366
|
+
</button>
|
|
367
|
+
<button className="modal-close" id="closePreview">×</button>
|
|
368
|
+
</div>
|
|
369
|
+
</div>
|
|
370
|
+
<div className="modal-body-wrapper">
|
|
371
|
+
<pre className="modal-body" id="modalBodyPre"><code id="previewContent"></code></pre>
|
|
372
|
+
<div className="modal-outline-panel" id="modalOutlinePanel" style={{ display: 'none' }}></div>
|
|
373
|
+
</div>
|
|
374
|
+
<div className="modal-blame-container" id="modalBlameContainer" style={{ display: 'none' }}></div>
|
|
375
|
+
<div className="modal-chat-container" id="modalChatContainer" style={{ display: 'none' }}></div>
|
|
376
|
+
<div className="modal-edit-container" id="modalEditContainer" style={{ display: 'none' }}>
|
|
377
|
+
<textarea id="modalEditTextarea" className="modal-edit-textarea" spellCheck={false} autoComplete="off"></textarea>
|
|
378
|
+
<div className="modal-edit-toolbar" id="modalEditToolbar">
|
|
379
|
+
<span className="edit-line-info" id="editLineInfo">Line 1, Col 1</span>
|
|
380
|
+
<div className="edit-toolbar-right">
|
|
381
|
+
<div className="edit-commit-section" id="editCommitSection" style={{ display: 'none' }}>
|
|
382
|
+
<input
|
|
383
|
+
type="text"
|
|
384
|
+
id="editCommitMsg"
|
|
385
|
+
className="edit-commit-input"
|
|
386
|
+
placeholder="Commit message..."
|
|
387
|
+
spellCheck={false}
|
|
388
|
+
autoComplete="off"
|
|
389
|
+
/>
|
|
390
|
+
<button className="btn-ghost btn-sm edit-commit-btn" id="editCommitBtn" title="Commit this file">
|
|
391
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
392
|
+
<circle cx="12" cy="12" r="4" />
|
|
393
|
+
<line x1="1.05" y1="12" x2="7" y2="12" />
|
|
394
|
+
<line x1="17.01" y1="12" x2="22.96" y2="12" />
|
|
395
|
+
</svg>
|
|
396
|
+
Commit
|
|
397
|
+
</button>
|
|
398
|
+
<button className="btn-ghost btn-xs edit-commit-cancel" id="editCommitCancel" title="Cancel">
|
|
399
|
+
<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="2.5">
|
|
400
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
401
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
402
|
+
</svg>
|
|
403
|
+
</button>
|
|
404
|
+
</div>
|
|
405
|
+
<button className="btn-ghost btn-sm edit-save-btn" id="editSaveBtn" title="Save (Ctrl+S)">
|
|
406
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
407
|
+
<path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z" />
|
|
408
|
+
<polyline points="17 21 17 13 7 13 7 21" />
|
|
409
|
+
<polyline points="7 3 7 8 15 8" />
|
|
410
|
+
</svg>
|
|
411
|
+
Save
|
|
412
|
+
</button>
|
|
413
|
+
</div>
|
|
414
|
+
</div>
|
|
415
|
+
</div>
|
|
416
|
+
</div>
|
|
417
|
+
</div>
|
|
418
|
+
|
|
419
|
+
{/* GitHub Import Modal */}
|
|
420
|
+
<div className="github-modal" id="githubModal">
|
|
421
|
+
<div className="github-modal-backdrop"></div>
|
|
422
|
+
<div className="github-modal-content">
|
|
423
|
+
<div className="github-modal-header">
|
|
424
|
+
<div className="github-modal-title">
|
|
425
|
+
<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor" style={{ opacity: 0.7 }}>
|
|
426
|
+
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" />
|
|
427
|
+
</svg>
|
|
428
|
+
<span>Import from GitHub</span>
|
|
429
|
+
</div>
|
|
430
|
+
<button className="github-modal-close" id="githubModalClose">×</button>
|
|
431
|
+
</div>
|
|
432
|
+
<div className="github-search-row">
|
|
433
|
+
<input
|
|
434
|
+
type="text"
|
|
435
|
+
id="githubUserInput"
|
|
436
|
+
className="github-user-input"
|
|
437
|
+
placeholder="Username, org, or paste a GitHub URL..."
|
|
438
|
+
spellCheck={false}
|
|
439
|
+
autoComplete="off"
|
|
440
|
+
/>
|
|
441
|
+
<select id="githubSortSelect" className="github-sort-select">
|
|
442
|
+
<option value="updated">Recently Updated</option>
|
|
443
|
+
<option value="stars">Most Stars</option>
|
|
444
|
+
<option value="name">Name A→Z</option>
|
|
445
|
+
</select>
|
|
446
|
+
<button id="githubSearchBtn" className="github-search-btn">
|
|
447
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2.5">
|
|
448
|
+
<circle cx="11" cy="11" r="8" />
|
|
449
|
+
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
|
450
|
+
</svg>
|
|
451
|
+
Search
|
|
452
|
+
</button>
|
|
453
|
+
</div>
|
|
454
|
+
<div className="github-url-clone-row" id="githubUrlCloneRow" style={{ display: 'none' }}>
|
|
455
|
+
<div className="github-url-detected">
|
|
456
|
+
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2">
|
|
457
|
+
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
|
|
458
|
+
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
|
|
459
|
+
</svg>
|
|
460
|
+
<span id="githubDetectedUrl">URL detected</span>
|
|
461
|
+
</div>
|
|
462
|
+
<button id="githubUrlCloneBtn" className="github-clone-btn github-url-clone-btn">Clone & Open</button>
|
|
463
|
+
</div>
|
|
464
|
+
<div className="github-filter-row" id="githubFilterRow" style={{ display: 'none' }}>
|
|
465
|
+
<input
|
|
466
|
+
type="text"
|
|
467
|
+
id="githubRepoFilter"
|
|
468
|
+
className="github-repo-filter"
|
|
469
|
+
placeholder="Filter repos by name..."
|
|
470
|
+
spellCheck={false}
|
|
471
|
+
autoComplete="off"
|
|
472
|
+
/>
|
|
473
|
+
</div>
|
|
474
|
+
<div className="github-profile" id="githubProfile" style={{ display: 'none' }}></div>
|
|
475
|
+
<div className="github-repos-grid" id="githubReposGrid">
|
|
476
|
+
<div className="github-empty-state">
|
|
477
|
+
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="currentColor" strokeWidth="1" opacity="0.2">
|
|
478
|
+
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" />
|
|
479
|
+
</svg>
|
|
480
|
+
<p>Enter a GitHub username to browse their repositories</p>
|
|
481
|
+
</div>
|
|
482
|
+
</div>
|
|
483
|
+
<div className="github-pagination" id="githubPagination" style={{ display: 'none' }}>
|
|
484
|
+
<button id="githubPrevPage" className="github-page-btn" disabled>← Previous</button>
|
|
485
|
+
<span id="githubPageInfo" className="github-page-info">Page 1</span>
|
|
486
|
+
<button id="githubNextPage" className="github-page-btn">Next →</button>
|
|
487
|
+
</div>
|
|
488
|
+
</div>
|
|
489
|
+
</div>
|
|
490
|
+
</body >
|
|
491
|
+
</html >
|
|
492
|
+
);
|
|
493
|
+
}
|