@ibgib/space-gib 0.0.34 → 0.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/client/bootstrap.mjs +1 -1
  2. package/dist/client/{chunk-25PXC4HP.mjs → chunk-5DTAUY3E.mjs} +1586 -464
  3. package/dist/client/chunk-J7X3XTAI.mjs +53 -0
  4. package/dist/client/css/activity-bar.css +21 -3
  5. package/dist/client/css/layout.css +126 -5
  6. package/dist/client/css/tutorial.css +327 -0
  7. package/dist/client/index.html +6 -0
  8. package/dist/client/index.mjs +22 -45
  9. package/dist/client/privacy.html +22 -22
  10. package/dist/client/script.mjs +1 -1
  11. package/dist/client/style.css +1 -0
  12. package/dist/server/server.mjs +3 -3
  13. package/package.json +6 -6
  14. package/src/client/AUTO-GENERATED-version.mts +1 -1
  15. package/src/client/cosmos/seed-cosmos-workspace.mts +20 -6
  16. package/src/client/css/activity-bar.css +21 -3
  17. package/src/client/css/layout.css +126 -5
  18. package/src/client/css/tutorial.css +327 -0
  19. package/src/client/dev-tools/vcs-workspace.mts +4 -4
  20. package/src/client/index.html +6 -0
  21. package/src/client/privacy.html +22 -22
  22. package/src/client/style.css +1 -0
  23. package/src/client/ui/component/changes/changes.css +413 -0
  24. package/src/client/ui/component/changes/changes.html +37 -0
  25. package/src/client/ui/component/changes/changes.mts +766 -0
  26. package/src/client/ui/component/changes/index.mts +9 -0
  27. package/src/client/ui/component/chat-view/chat-view.html +6 -58
  28. package/src/client/ui/component/chat-view/chat-view.mts +13 -26
  29. package/src/client/ui/component/clone/clone.mts +67 -39
  30. package/src/client/ui/component/code-editor/code-editor.css +91 -9
  31. package/src/client/ui/component/code-editor/code-editor.html +58 -45
  32. package/src/client/ui/component/code-editor/code-editor.mts +265 -49
  33. package/src/client/ui/component/cosmos-navigator/cosmos-navigator.css +1 -1
  34. package/src/client/ui/component/cosmos-navigator/cosmos-navigator.html +5 -10
  35. package/src/client/ui/component/cosmos-navigator/cosmos-navigator.mts +328 -64
  36. package/src/client/ui/component/file-explorer/file-explorer.css +475 -11
  37. package/src/client/ui/component/file-explorer/file-explorer.html +45 -65
  38. package/src/client/ui/component/file-explorer/file-explorer.mts +1164 -98
  39. package/src/client/ui/component/nested-chat/chat/chat.mts +5 -90
  40. package/src/client/ui/component/nested-chat/nested-chat.mts +10 -8
  41. package/src/client/ui/component/timeline/timeline.css +16 -1
  42. package/src/client/ui/component/timeline/timeline.mts +37 -93
  43. package/src/client/ui/component/tutorial/index.mts +9 -0
  44. package/src/client/ui/component/tutorial/scripts/pitch-tour-script.mts +265 -0
  45. package/src/client/ui/component/tutorial/tutorial-controller.mts +622 -0
  46. package/src/client/ui/component/tutorial/tutorial-types.mts +45 -0
  47. package/src/client/ui/component/tutorial/tutorial.css +260 -0
  48. package/src/client/ui/router/space-gib-router-helpers.mts +33 -233
  49. package/src/client/ui/router/space-gib-router-helpers.respec.mts +298 -122
  50. package/src/client/ui/router/space-gib-router-service.mts +28 -151
  51. package/src/client/ui/router/space-gib-router-types.mts +32 -76
  52. package/src/client/ui/shell/cosmic-big-bang.mts +12 -3
  53. package/src/client/ui/shell/space-gib-shell-service.mts +715 -143
  54. package/dist/client/chunk-RXWLL2AI.mjs +0 -30
@@ -166,106 +166,21 @@ export class ChatComponentInstance
166
166
  const { ib } = getIbAndGib({ ibGibAddr: addr });
167
167
 
168
168
  if (addr === ROOT_ADDR || ib === 'root' || ib.includes('space-gib')) {
169
- this.el.contextTitleEl.textContent = 'Thread: src/index.ts';
169
+ this.el.contextTitleEl.textContent = 'Thread: Workspace';
170
170
  } else if (ib.startsWith('comment')) {
171
171
  const pieces = ib.split(' ');
172
172
  const preview = pieces.length > 1 ? pieces.slice(1).join(' ') : 'Comment Thread';
173
173
  this.el.contextTitleEl.textContent = `Thread: "${preview.slice(0, 24)}..."`;
174
+ } else if (ib.startsWith('file ')) {
175
+ const file = ib.replace('file ', '');
176
+ this.el.contextTitleEl.textContent = `Thread: ${file}`;
174
177
  } else {
175
178
  this.el.contextTitleEl.textContent = `Thread: ${ib.slice(0, 20)}`;
176
179
  }
177
180
  }
178
181
 
179
182
  private loadInitialMessages(): void {
180
- const addr = this.ibGibAddr ?? ROOT_ADDR;
181
- const { ib } = getIbAndGib({ ibGibAddr: addr });
182
-
183
- if (ib.includes('boundary') || ib.includes('try/catch') || ib.includes('boot')) {
184
- // Nested replies for the error boundary comment thread
185
- this.messages = [
186
- {
187
- id: 'submsg-1',
188
- addr: 'comment boundary-rationale^gib_b1',
189
- author: 'Charlie',
190
- avatar: '👩‍🔬',
191
- role: 'Peer',
192
- timestamp: '3m ago',
193
- text: 'Wrapping boot() in a top-level error boundary prevents uncaught rejections from freezing the virtual canvas.',
194
- replyCount: 1,
195
- },
196
- {
197
- id: 'submsg-2',
198
- addr: 'comment boundary-event^gib_b2',
199
- author: 'Bob',
200
- avatar: '👨‍🚀',
201
- role: 'Peer',
202
- timestamp: '1m ago',
203
- text: 'Agreed! Let us also dispatch an EVENT_IBGIB_UI_MESSAGE so the status bar shows the error banner.',
204
- replyCount: 0,
205
- }
206
- ];
207
- } else if (ib.includes('rationale') || ib.includes('index.ts') || ib.includes('indexeddb')) {
208
- // Nested replies for the architectural rationale comment thread
209
- this.messages = [
210
- {
211
- id: 'submsg-3',
212
- addr: 'comment offline-merkle^gib_a1',
213
- author: 'Bob',
214
- avatar: '👨‍🚀',
215
- role: 'Peer',
216
- timestamp: '5m ago',
217
- text: 'The local IndexedDB space works completely offline without network roundtrips.',
218
- replyCount: 0,
219
- },
220
- {
221
- id: 'submsg-4',
222
- addr: 'comment sync-keystone^gib_a2',
223
- author: 'Alice',
224
- avatar: '👩‍💻',
225
- role: 'Keystone',
226
- timestamp: '2m ago',
227
- text: 'Exactly! Remote peer hubs synchronize automatically via WebSockets whenever connectivity is detected.',
228
- replyCount: 0,
229
- }
230
- ];
231
- } else {
232
- // Default file / root comments
233
- this.messages = [
234
- {
235
- id: 'msg-1',
236
- addr: 'comment index-arch-rationale^gib_1',
237
- author: 'Alice',
238
- avatar: '👩‍💻',
239
- role: 'Keystone',
240
- timestamp: '10m ago',
241
- anchor: 'src/index.ts#L1-18',
242
- text: 'Architectural Rationale: This entrypoint initializes the virtual repository workspace within the browser’s local IndexedDB metaspace.',
243
- replyCount: 2,
244
- },
245
- {
246
- id: 'msg-2',
247
- addr: 'comment index-try-catch^gib_2',
248
- author: 'Bob',
249
- avatar: '👨‍🚀',
250
- role: 'Peer',
251
- timestamp: '6m ago',
252
- anchor: 'src/index.ts#L36-42',
253
- text: 'Looks super clean! Should we add an async try/catch boundary around boot() as well?',
254
- replyCount: 2,
255
- },
256
- {
257
- id: 'msg-3',
258
- addr: 'comment index-agent-analysis^gib_3',
259
- author: 'Agent',
260
- avatar: '🤖',
261
- role: 'Agent',
262
- timestamp: '4m ago',
263
- anchor: 'src/index.ts#L43-50',
264
- text: 'Static analysis confirms that initOrchestration provides a root failure boundary.',
265
- replyCount: 0,
266
- }
267
- ];
268
- }
183
+ this.messages = [];
269
184
  }
270
185
 
271
186
  private async initEnterBehavior(): Promise<void> {
@@ -99,7 +99,7 @@ export class NestedChatComponentInstance
99
99
 
100
100
  private ensureValidIbGibAddr(addr: string): IbGibAddr {
101
101
  if (!addr || addr === ROOT_ADDR) {
102
- return 'file src/index.ts^index_tjp';
102
+ return ROOT_ADDR;
103
103
  }
104
104
  if (!addr.includes('^')) {
105
105
  return `file ${addr}^${addr.replace(/[^a-zA-Z0-9]/g, '_')}_tjp`;
@@ -123,13 +123,15 @@ export class NestedChatComponentInstance
123
123
 
124
124
  this.bindEvents();
125
125
 
126
- // Only activate initial thread if an ibGibAddr was explicitly provided to the component
127
- if (this.ibGibAddr) {
126
+ // Only activate initial thread if an ibGibAddr was explicitly provided (not ROOT_ADDR)
127
+ if (this.ibGibAddr && this.ibGibAddr !== ROOT_ADDR) {
128
128
  const rootAddr = this.ensureValidIbGibAddr(this.ibGibAddr);
129
- setTimeout(async () => {
130
- console.log(`${lc} activating initial root thread: ${rootAddr}`);
131
- await this.activateIbGib({ addr: rootAddr });
132
- }, 0);
129
+ if (rootAddr && rootAddr !== ROOT_ADDR) {
130
+ setTimeout(async () => {
131
+ console.log(`${lc} activating initial root thread: ${rootAddr}`);
132
+ await this.activateIbGib({ addr: rootAddr });
133
+ }, 0);
134
+ }
133
135
  }
134
136
 
135
137
  } catch (error) {
@@ -350,7 +352,7 @@ export class NestedChatComponentInstance
350
352
 
351
353
  const { ib } = getIbAndGib({ ibGibAddr: addr });
352
354
  if (addr === ROOT_ADDR || ib === 'root' || ib.includes('file') || !addr.includes('comment')) {
353
- const fileTitle = ib.startsWith('file ') ? ib.replace('file ', '') : 'src/index.ts';
355
+ const fileTitle = ib.startsWith('file ') ? ib.replace('file ', '') : (ib === 'root' || addr === ROOT_ADDR ? 'Workspace' : ib);
354
356
  return {
355
357
  shortTitle: this.formatShortTitle(fileTitle),
356
358
  fullText: `Root Thread: ${fileTitle}`,
@@ -2,15 +2,25 @@
2
2
  display: flex;
3
3
  flex-direction: column;
4
4
  width: 100%;
5
+ height: 100%;
6
+ min-height: 0;
5
7
  box-sizing: border-box;
6
8
  margin: 0;
7
9
  padding: 0;
8
10
  }
9
11
 
12
+ :host([collapsed]) {
13
+ height: auto !important;
14
+ flex: 0 0 auto !important;
15
+ }
16
+
10
17
  .timeline-root {
11
18
  display: flex;
12
19
  flex-direction: column;
13
20
  width: 100%;
21
+ height: 100%;
22
+ min-height: 0;
23
+ overflow: hidden;
14
24
  user-select: none;
15
25
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
16
26
  box-sizing: border-box;
@@ -23,7 +33,7 @@
23
33
  display: flex;
24
34
  align-items: center;
25
35
  gap: 0.35rem;
26
- padding: 0.4rem 0.6rem;
36
+ padding: 0.28rem 0.5rem;
27
37
  background: rgba(255, 255, 255, 0.04);
28
38
  border: 1px solid rgba(255, 255, 255, 0.08);
29
39
  border-radius: 6px;
@@ -35,6 +45,8 @@
35
45
  outline: none;
36
46
  box-sizing: border-box;
37
47
  margin: 0;
48
+ flex: 0 0 auto !important;
49
+ flex-shrink: 0 !important;
38
50
  }
39
51
 
40
52
  .timeline-header:hover {
@@ -135,6 +147,9 @@
135
147
  .timeline-stream-container {
136
148
  display: flex;
137
149
  flex-direction: column;
150
+ flex: 1 1 0px;
151
+ min-height: 0;
152
+ overflow-y: auto;
138
153
  position: relative;
139
154
  padding: 0.35rem 0.2rem 0.5rem 0.8rem;
140
155
  box-sizing: border-box;
@@ -87,98 +87,8 @@ export class TimelineComponentInstance
87
87
 
88
88
  private branchName: string = 'main';
89
89
  private isTimelineExpanded: boolean = true;
90
- private selectedHash: string = '3e8f1c2';
91
-
92
- private snapshots: TimelineItem[] = [
93
- {
94
- hash: '3e8f1c2a05d8f99e32b4f17c802e3b4a',
95
- shortHash: '3e8f1c2',
96
- message: 'feat: implement cosmos navigation and orbital drift',
97
- author: 'Bill Raiford <bill@ibgib.space>',
98
- timestamp: '2m ago',
99
- isTip: true,
100
- branch: 'main',
101
- parentHash: 'a7b4d90',
102
- changedFiles: [
103
- { path: 'src/client/ui/component/cosmos-navigator/cosmos-navigator.mts', status: 'M', additions: 18, deletions: 4 },
104
- { path: 'src/client/ui/shell/space-gib-shell-service.mts', status: 'M', additions: 32, deletions: 6 },
105
- { path: 'src/client/css/layout.css', status: 'M', additions: 14, deletions: 2 },
106
- ],
107
- diffPreview: `@@ -848,6 +848,20 @@
108
- - this.launchProjectile({ ... });
109
- + // Make activity bar visible BEFORE zoom flight starts
110
- + window.dispatchEvent(new CustomEvent('space-gib-activity-bar-expand-requested'));
111
- + setTimeout(() => {
112
- + this.launchProjectile({ ... });
113
- + }, 180);`
114
- },
115
- {
116
- hash: 'a7b4d9089f21c4320b9e8471da329188',
117
- shortHash: 'a7b4d90',
118
- message: 'style: polish firecracker big bang compression',
119
- author: 'Bill Raiford <bill@ibgib.space>',
120
- timestamp: '1h ago',
121
- branch: 'main',
122
- parentHash: 'f2098b1',
123
- changedFiles: [
124
- { path: 'src/client/ui/component/cosmos-navigator/cosmos-navigator.css', status: 'M', additions: 24, deletions: 11 },
125
- { path: 'src/client/ui/component/cosmos-navigator/cosmos-navigator.mts', status: 'M', additions: 12, deletions: 5 },
126
- ],
127
- diffPreview: `@@ -430,8 +430,12 @@
128
- - btn.classList.add('compressing');
129
- + // Firecracker high velocity rotation
130
- + btn.classList.add('compressing');
131
- + this.triggerBigBangExplosion();`
132
- },
133
- {
134
- hash: 'f2098b191c4998721fae390c91834789',
135
- shortHash: 'f2098b1',
136
- message: 'refactor: decouple activity bar and cosmos controls',
137
- author: 'Bill Raiford <bill@ibgib.space>',
138
- timestamp: 'yesterday',
139
- branch: 'main',
140
- parentHash: 'c019a4e',
141
- changedFiles: [
142
- { path: 'src/client/ui/shell/cosmic-big-bang.mts', status: 'M', additions: 40, deletions: 52 },
143
- { path: 'src/client/ui/shell/space-gib-shell-service.mts', status: 'M', additions: 75, deletions: 18 },
144
- ],
145
- diffPreview: `@@ -120,7 +120,7 @@
146
- - public toggleActivityBar(): void {
147
- + public expandActivityBar(): void {`
148
- },
149
- {
150
- hash: 'c019a4ee899201bdcf88132582910fa2',
151
- shortHash: 'c019a4e',
152
- message: 'feat: primordial singularity and big bang stage',
153
- author: 'Bill Raiford <bill@ibgib.space>',
154
- timestamp: '3d ago',
155
- branch: 'main',
156
- parentHash: '0000000',
157
- changedFiles: [
158
- { path: 'src/client/ui/component/cosmos-navigator/cosmos-navigator.mts', status: 'A', additions: 450, deletions: 0 },
159
- { path: 'src/client/ui/component/cosmos-navigator/cosmos-navigator.html', status: 'A', additions: 95, deletions: 0 },
160
- ],
161
- diffPreview: `@@ -0,0 +1,95 @@
162
- +<div id="cosmos-nav-root" class="cosmos-nav-root">
163
- + <canvas id="bg-canvas"></canvas>
164
- +</div>`
165
- },
166
- {
167
- hash: '00000000000000000000000000000000',
168
- shortHash: '0000000',
169
- message: 'Initial commit (empty space genesis)',
170
- author: 'Bill Raiford <bill@ibgib.space>',
171
- timestamp: '5d ago',
172
- branch: 'main',
173
- changedFiles: [
174
- { path: 'package.json', status: 'A', additions: 35, deletions: 0 },
175
- { path: 'README.md', status: 'A', additions: 20, deletions: 0 },
176
- ],
177
- diffPreview: `@@ -0,0 +1,20 @@
178
- +# space-gib
179
- +Decentralized VCS and superspaces.`
180
- }
181
- ];
90
+ private selectedHash: string = '';
91
+ private snapshots: TimelineItem[] = [];
182
92
 
183
93
  get el(): TimelineElements {
184
94
  if (!this.elements) {
@@ -203,6 +113,7 @@ export class TimelineComponentInstance
203
113
  contentEl: shadow.getElementById('timeline-root') as HTMLDivElement,
204
114
  };
205
115
 
116
+ this.toggleAttribute('collapsed', !this.isTimelineExpanded);
206
117
  this.bindHandlers();
207
118
  this.renderSnapshots();
208
119
  } catch (error) {
@@ -238,6 +149,15 @@ export class TimelineComponentInstance
238
149
  if (!container) { return; }
239
150
  container.innerHTML = '';
240
151
 
152
+ if (this.snapshots.length === 0) {
153
+ container.innerHTML = `
154
+ <div class="empty-timeline-msg" style="padding: 16px 12px; font-size: 11px; color: #8a99a8; font-style: italic; text-align: center;">
155
+ No commits on branch [${this.branchName}] yet.
156
+ </div>
157
+ `;
158
+ return;
159
+ }
160
+
241
161
  for (const item of this.snapshots) {
242
162
  const row = document.createElement('div');
243
163
  row.className = `timeline-item ${item.shortHash === this.selectedHash ? 'selected' : ''} ${item.isTip ? 'is-tip' : ''}`;
@@ -268,6 +188,11 @@ export class TimelineComponentInstance
268
188
  }
269
189
  }
270
190
 
191
+ public setSnapshots(snapshots: TimelineItem[]): void {
192
+ this.snapshots = snapshots || [];
193
+ this.renderSnapshots();
194
+ }
195
+
271
196
  public selectTimelineItem(hash: string): void {
272
197
  this.selectedHash = hash;
273
198
  const shadow = this.shadowRoot;
@@ -288,8 +213,23 @@ export class TimelineComponentInstance
288
213
  }
289
214
  }
290
215
 
216
+ public addSnapshot(snapshot: TimelineItem): void {
217
+ for (const s of this.snapshots) {
218
+ s.isTip = false;
219
+ }
220
+ snapshot.isTip = true;
221
+ this.snapshots.unshift(snapshot);
222
+ this.renderSnapshots();
223
+ }
224
+
225
+ public clearSnapshots(): void {
226
+ this.snapshots = [];
227
+ this.renderSnapshots();
228
+ }
229
+
291
230
  public toggleTimelineAccordion(): void {
292
231
  this.isTimelineExpanded = !this.isTimelineExpanded;
232
+ this.toggleAttribute('collapsed', !this.isTimelineExpanded);
293
233
  const chevron = this.el.timelineHeaderEl.querySelector('.chevron-icon');
294
234
 
295
235
  if (this.isTimelineExpanded) {
@@ -301,9 +241,13 @@ export class TimelineComponentInstance
301
241
  this.el.timelineHeaderEl.classList.remove('expanded');
302
242
  this.el.timelineHeaderEl.classList.add('collapsed');
303
243
  this.el.timelineStreamContainerEl.classList.add('hidden');
304
- // if (chevron) chevron.textContent = '▶';
305
244
  if (chevron) { chevron.textContent = '▼'; }
306
245
  }
246
+ this.dispatchEvent(new CustomEvent('space-gib-accordion-toggled', {
247
+ detail: { isExpanded: this.isTimelineExpanded },
248
+ bubbles: true,
249
+ composed: true,
250
+ }));
307
251
  }
308
252
 
309
253
  override async disconnected(): Promise<void> {
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @module tutorial
3
+ *
4
+ * Space-Gib Tutorial Runner & Interactive Spotlight Tour framework.
5
+ */
6
+
7
+ export * from './tutorial-types.mjs';
8
+ export * from './tutorial-controller.mjs';
9
+ export * from './scripts/pitch-tour-script.mjs';
@@ -0,0 +1,265 @@
1
+ /**
2
+ * @module pitch-tour-script
3
+ *
4
+ * The Founder Pitch Tour script for Space-Gib.
5
+ * Walks through the full ibgib cosmology contrasting each layer against the legacy
6
+ * Git/GitHub/GitLab stack, with automated in-between mouse click animations,
7
+ * culminating in a transparent founder investment thesis.
8
+ */
9
+
10
+ import { TutorialScript } from '../tutorial-types.mjs';
11
+ import { findElementDeep } from '../tutorial-controller.mjs';
12
+
13
+ export const PITCH_TOUR_SCRIPT_ID = 'space-gib-founder-pitch-tour';
14
+
15
+ export const PITCH_TOUR_SCRIPT: TutorialScript = {
16
+ id: PITCH_TOUR_SCRIPT_ID,
17
+ title: 'The Post-Git Frontier: Founder Pitch Tour',
18
+ steps: [
19
+ // =====================================================================
20
+ // STEP 1: Introduction & The Post-Git Thesis
21
+ // =====================================================================
22
+ {
23
+ id: 'step-1-thesis',
24
+ title: 'The Post-Git Frontier: Unlocking Autonomous AI Agents',
25
+ narration: `
26
+ <p>The fundamental bottleneck for AI software engineering is <strong>not</strong> the models—it is <strong>Git</strong>.</p>
27
+ <p>Modern agent harnesses, coding assistants, and CI/CD pipelines are chained to a 2005 architecture designed for human developers emailing diff patches. When autonomous agents code concurrently, the Git stack collapses:</p>
28
+ <ul>
29
+ <li><strong>Git & Worktrees:</strong> Fragile locks, merge conflicts that stop the world, detached HEADs.</li>
30
+ <li><strong>Package Managers (npm, PyPI):</strong> External out-of-band registries vulnerable to supply chain hijacking.</li>
31
+ <li><strong>Asset Managers (Git LFS):</strong> Fragile pointer files pointing to separate, proprietary blob servers.</li>
32
+ <li><strong>External Comms (GitHub Issues, Slack, Discord):</strong> Trapped in centralized corporate silos separated from code history.</li>
33
+ </ul>
34
+ <p><strong>The Solution: A Unified Merkle Cosmology.</strong> Let us begin with the birth of our workspace.</p>
35
+ <p><em>Click [Ignite the Big Bang ➔] to witness the workspace creation.</em></p>
36
+ `,
37
+ targetElementId: undefined, // center placement
38
+ placement: 'center',
39
+ beaconLabel: 'Begin Pitch ✨',
40
+ buttonText: 'Ignite the Big Bang ➔',
41
+ action: async (ctx) => {
42
+ await ctx.shell?.showCosmos?.();
43
+ },
44
+ transitionAction: async (ctx, controller) => {
45
+ // Ensure Cosmos is showing
46
+ await ctx.shell?.showCosmos?.();
47
+ const cosmosNav = ctx.shell?.getCosmosNavigator?.();
48
+ const singularityBtn = findElementDeep('btn-singularity');
49
+
50
+ if (singularityBtn && (!cosmosNav || !cosmosNav.hasBigBangExploded)) {
51
+ // Glide virtual mouse to the Singularity button and click it
52
+ await controller.animateMouseClick(singularityBtn, { durationMs: 800 });
53
+
54
+ // Trigger the physical Big Bang sequence
55
+ await new Promise<void>((resolve) => {
56
+ if (cosmosNav?.triggerBigBangSequence) {
57
+ cosmosNav.triggerBigBangSequence(() => {
58
+ resolve();
59
+ });
60
+ } else {
61
+ singularityBtn.click();
62
+ setTimeout(resolve, 1400);
63
+ }
64
+ });
65
+ // Allow the Cosmos stage and revolving satellites to blossom
66
+ await new Promise((r) => setTimeout(r, 650));
67
+ } else {
68
+ // Already exploded, ensure Cosmos stage is visible
69
+ await ctx.shell?.showCosmos?.();
70
+ await new Promise((r) => setTimeout(r, 400));
71
+ }
72
+ },
73
+ },
74
+
75
+ // =====================================================================
76
+ // STEP 2: The Cosmos (Root Container)
77
+ // =====================================================================
78
+ {
79
+ id: 'step-2-cosmos-container',
80
+ title: '1. The Cosmos: Supercharged Monorepo Container',
81
+ narration: `
82
+ <p>Welcome to the <strong>Cosmos</strong>—the root container that replaces multi-repo sprawl and fractured monorepo tooling.</p>
83
+ <p>In traditional setups, coordinating multiple repositories, Git submodules, or Lerna/Turborepo workspaces requires fragile symlinks, separate CI configs, and constant sync friction.</p>
84
+ <p>In <code>ibgib</code>, a <strong>Cosmos</strong> is a unified, sovereign Merkle coordinate space. It hosts interconnected <strong>Galaxies</strong>—each with discrete cryptographic boundaries, bound together by inverted soft links.</p>
85
+ <p>Watch as we spawn our primary workspace: a <strong>Code Galaxy</strong>.</p>
86
+ `,
87
+ targetElementId: 'node-superspace-wrapper',
88
+ placement: 'bottom',
89
+ beaconLabel: 'Code Galaxy 🚀',
90
+ buttonText: 'Birth Code Galaxy ➔',
91
+ action: async (ctx) => {
92
+ await ctx.shell?.showCosmos?.();
93
+ },
94
+ transitionAction: async (ctx, controller) => {
95
+ const btnSatCode = findElementDeep('btn-sat-code');
96
+ const cosmosNav = ctx.shell?.getCosmosNavigator?.();
97
+
98
+ if (btnSatCode) {
99
+ // Move virtual mouse cursor to the revolving Code Galaxy satellite
100
+ await controller.animateMouseClick(btnSatCode, { durationMs: 800 });
101
+ }
102
+
103
+ // Trigger programmatic launch of the Code Galaxy projectile
104
+ if (cosmosNav?.launchCodeGalaxyProgrammatic) {
105
+ await cosmosNav.launchCodeGalaxyProgrammatic('code-1');
106
+ // Wait for the projectile to fly across the screen, dock into the activity bar, and expand panels
107
+ await new Promise((r) => setTimeout(r, 1800));
108
+ } else {
109
+ ctx.shell?.expandActivityBar?.();
110
+ ctx.shell?.expandLeftPanel?.();
111
+ ctx.shell?.showLeftPanelView?.('code', 'code-1');
112
+ await new Promise((r) => setTimeout(r, 600));
113
+ }
114
+ },
115
+ },
116
+
117
+ // =====================================================================
118
+ // STEP 3: Class I: Code Galaxy (The Git Replacement)
119
+ // =====================================================================
120
+ {
121
+ id: 'step-3-code-galaxy',
122
+ title: '2. Code Galaxy: Accretive Merkle Branches & Zero Push Rejections',
123
+ narration: `
124
+ <p>The <strong>Code Galaxy</strong> is our native replacement for a Git repository.</p>
125
+ <p>Notice the File Explorer on the left. In <code>ibgib</code>, every file, folder, and branch is an immutable, content-addressed Merkle node.</p>
126
+ <p><strong>Why this defeats Git for AI Agents:</strong></p>
127
+ <ul>
128
+ <li><strong>Accretive 3-Way Graft Merging:</strong> In Git, concurrent agent pushes fail with non-fast-forward push rejections. In <code>ibgib</code>, concurrent agent commits graft accretively without blocking repository state.</li>
129
+ <li><strong>No Detached HEADs:</strong> Timelines are monotonic and cryptographically sovereign.</li>
130
+ <li><strong>Instant Worktrees:</strong> Multiple agents can branch and execute simultaneously in-memory without cloning gigabytes of files to disk.</li>
131
+ </ul>
132
+ `,
133
+ targetElementId: 'code-file-explorer-container',
134
+ placement: 'right',
135
+ beaconLabel: 'Code Substrate 📁',
136
+ buttonText: 'Inspect In-Band Discourse ➔',
137
+ action: async (ctx) => {
138
+ ctx.shell?.expandLeftPanel?.();
139
+ ctx.shell?.showLeftPanelView?.('code', ctx.galaxyName || 'code-1');
140
+ },
141
+ transitionAction: async (ctx, controller) => {
142
+ // Select a file in the explorer and open editor & right companion panel
143
+ const files = ['README.md', 'app.ts', 'index.ts'];
144
+ for (const f of files) {
145
+ try {
146
+ ctx.shell?.fileExplorerInstance?.selectFile?.(f);
147
+ break;
148
+ } catch { /* continue */ }
149
+ }
150
+ await ctx.shell?.showCode?.();
151
+ ctx.shell?.expandRightPanel?.();
152
+ await new Promise((r) => setTimeout(r, 650));
153
+ },
154
+ },
155
+
156
+ // =====================================================================
157
+ // STEP 4: Class IV: Metatext Galaxy (In-Band Discourse)
158
+ // =====================================================================
159
+ {
160
+ id: 'step-4-metatext-galaxy',
161
+ title: '3. Metatext Galaxy: In-Band Discourse & Reviews (.ib.*.md)',
162
+ narration: `
163
+ <p>Look at the right panel. In legacy software engineering, code lives in Git, but discussions, PR reviews, bug reports, and agent rationale are locked in proprietary third-party silos: <strong>GitHub Issues, Jira, Slack, or Discord</strong>.</p>
164
+ <p>When an AI agent writes code, its reasoning and discussion are lost from the repository's cryptographic history.</p>
165
+ <p>In <code>ibgib</code>, <strong>Metatext Galaxies</strong> embed discussions, companion reviews, and prompt rationale <strong>in-band in the exact same Merkle DAG</strong> using companion files (<code>.ib.*.md</code>).</p>
166
+ <p>Code and rationale evolve together. You own your code <em>and</em> the conversation that created it.</p>
167
+ `,
168
+ targetElementId: 'right-panel',
169
+ placement: 'left',
170
+ beaconLabel: 'In-Band State 💬',
171
+ buttonText: 'Explore Package Galaxy ➔',
172
+ action: async (ctx) => {
173
+ ctx.shell?.expandRightPanel?.();
174
+ },
175
+ transitionAction: async (ctx, controller) => {
176
+ ctx.shell?.collapseRightPanel?.();
177
+ ctx.shell?.expandLeftPanel?.();
178
+ await new Promise((r) => setTimeout(r, 500));
179
+ },
180
+ },
181
+
182
+ // =====================================================================
183
+ // STEP 5: Class II: Package Galaxy (Monotonic Releases)
184
+ // =====================================================================
185
+ {
186
+ id: 'step-5-package-galaxy',
187
+ title: '4. Package Galaxy: Monotonic Append-Only Releases',
188
+ narration: `
189
+ <p>Modern software supply chains rely on centralized registries (<strong>npm, PyPI, Cargo, Crates</strong>) that are vulnerable to token theft, registry outages, and malicious typosquatting.</p>
190
+ <p>A <strong>Package Galaxy</strong> provides monotonic, append-only cryptographic release checkpoints (<code>v1.0.0</code>, <code>v1.0.1</code>).</p>
191
+ <p>Each release is an immutable Merkle root signed by the creator's cryptographic Keystone identity.</p>
192
+ <p>Downstream consumers verify and pull the exact dependency graph directly from sovereign spaces—with zero middlemen, zero spoofing, and zero central points of failure.</p>
193
+ `,
194
+ targetElementId: 'code-changes-container',
195
+ placement: 'right',
196
+ beaconLabel: 'Package Integrity 📦',
197
+ buttonText: 'Explore Asset Galaxy ➔',
198
+ action: async (ctx) => {
199
+ ctx.shell?.expandLeftPanel?.();
200
+ },
201
+ transitionAction: async (ctx, controller) => {
202
+ const btnClone = findElementDeep('btn-header-clone');
203
+ if (btnClone) {
204
+ await controller.animateMouseClick(btnClone, { durationMs: 700 });
205
+ }
206
+ await new Promise((r) => setTimeout(r, 450));
207
+ },
208
+ },
209
+
210
+ // =====================================================================
211
+ // STEP 6: Asset Galaxy (Binary Content vs Git LFS)
212
+ // =====================================================================
213
+ {
214
+ id: 'step-6-asset-galaxy',
215
+ title: '5. Asset Galaxy: Content-Addressed Binary Sovereignty',
216
+ narration: `
217
+ <p>Git was never built for binary files. <strong>Git LFS</strong> is a fragile hack: text pointers in Git that point to separate cloud servers. If the LFS server goes down or credentials expire, builds fail completely.</p>
218
+ <p>In <code>ibgib</code>, <strong>Asset Galaxies</strong> treat large binaries, AI weights, model tensors, datasets, and media as first-class, content-addressed Merkle stones.</p>
219
+ <p>Deduplication is cryptographic and native.</p>
220
+ <p>And with <strong>Zero Platform Lock-In</strong>, clicking <strong>Clone</strong> allows you to export raw files, zip archives, or Git repositories directly to disk at any time.</p>
221
+ `,
222
+ targetElementId: 'btn-header-clone',
223
+ placement: 'bottom',
224
+ beaconLabel: 'Zero Lock-In ⤓',
225
+ buttonText: 'The Founder Ask ➔',
226
+ action: async (ctx) => {
227
+ ctx.shell?.expandLeftPanel?.();
228
+ },
229
+ transitionAction: async (ctx, controller) => {
230
+ await controller.animateMouseClick(
231
+ { x: window.innerWidth / 2, y: window.innerHeight / 2 },
232
+ { durationMs: 600 }
233
+ );
234
+ await new Promise((r) => setTimeout(r, 350));
235
+ },
236
+ },
237
+
238
+ // =====================================================================
239
+ // STEP 7: The Founder Ask & Investment Realities
240
+ // =====================================================================
241
+ {
242
+ id: 'step-7-founder-ask',
243
+ title: 'The Ask: Fueling the Solo Founder Behind the Protocol',
244
+ narration: `
245
+ <p>Currently, the live monorepo source code is not served directly through this web client because we are in the process of finalizing the MVP CLI sync pipeline.</p>
246
+ <p><strong>The Reality:</strong> I am building this entire protocol as a solo founder, currently coding at <strong>50% capacity</strong> due to everyday survival stresses and single-income family debt—competing against well-funded teams with $100Ks or $1Ms in venture investment.</p>
247
+ <p>A modest seed investment ($50k–$150k) takes me to <strong>100% full-time capacity</strong> to deliver the post-git infrastructure the agentic era urgently demands.</p>
248
+ <p><strong>Founder Expectations & Terms:</strong></p>
249
+ <ul>
250
+ <li><strong>Talk is cheap:</strong> I have no budget for travel and cannot afford a laptop capable of running Zoom reliably. If an investor wants in-person meetings or video calls, please fund the travel or hardware.</li>
251
+ <li><strong>Open-Source Core:</strong> The core protocol <em>must remain open-source</em> (dogfooded in its own decentralized repository).</li>
252
+ <li><strong>The Commercial Moat:</strong> The immense business upside lies in the hosted platform, the agentic supply chain infrastructure, and the downstream multi-app cosmology (educational LMS suites, knowledge graphs, and enterprise sync).</li>
253
+ </ul>
254
+ <p><em>If you believe that AI agents will do 90% of coding going forward, invest now in the protocol built from the ground up for that future.</em></p>
255
+ <p style="margin-top:16px; padding:12px; background:rgba(255,215,0,0.1); border-radius:8px; border:1px solid rgba(255,215,0,0.35); text-align:center;">
256
+ <strong>Direct Founder Contact:</strong> <a href="mailto:bill@ibgib.space" style="color:#ffd700; text-decoration:underline; font-weight:700;">bill@ibgib.space</a>
257
+ </p>
258
+ `,
259
+ targetElementId: undefined, // center placement
260
+ placement: 'center',
261
+ beaconLabel: 'Invest in ibgib 💰',
262
+ buttonText: 'Complete Tour ✨',
263
+ },
264
+ ],
265
+ };