@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.
- package/dist/client/bootstrap.mjs +1 -1
- package/dist/client/{chunk-25PXC4HP.mjs → chunk-5DTAUY3E.mjs} +1586 -464
- package/dist/client/chunk-J7X3XTAI.mjs +53 -0
- package/dist/client/css/activity-bar.css +21 -3
- package/dist/client/css/layout.css +126 -5
- package/dist/client/css/tutorial.css +327 -0
- package/dist/client/index.html +6 -0
- package/dist/client/index.mjs +22 -45
- package/dist/client/privacy.html +22 -22
- package/dist/client/script.mjs +1 -1
- package/dist/client/style.css +1 -0
- package/dist/server/server.mjs +3 -3
- package/package.json +6 -6
- package/src/client/AUTO-GENERATED-version.mts +1 -1
- package/src/client/cosmos/seed-cosmos-workspace.mts +20 -6
- package/src/client/css/activity-bar.css +21 -3
- package/src/client/css/layout.css +126 -5
- package/src/client/css/tutorial.css +327 -0
- package/src/client/dev-tools/vcs-workspace.mts +4 -4
- package/src/client/index.html +6 -0
- package/src/client/privacy.html +22 -22
- package/src/client/style.css +1 -0
- package/src/client/ui/component/changes/changes.css +413 -0
- package/src/client/ui/component/changes/changes.html +37 -0
- package/src/client/ui/component/changes/changes.mts +766 -0
- package/src/client/ui/component/changes/index.mts +9 -0
- package/src/client/ui/component/chat-view/chat-view.html +6 -58
- package/src/client/ui/component/chat-view/chat-view.mts +13 -26
- package/src/client/ui/component/clone/clone.mts +67 -39
- package/src/client/ui/component/code-editor/code-editor.css +91 -9
- package/src/client/ui/component/code-editor/code-editor.html +58 -45
- package/src/client/ui/component/code-editor/code-editor.mts +265 -49
- package/src/client/ui/component/cosmos-navigator/cosmos-navigator.css +1 -1
- package/src/client/ui/component/cosmos-navigator/cosmos-navigator.html +5 -10
- package/src/client/ui/component/cosmos-navigator/cosmos-navigator.mts +328 -64
- package/src/client/ui/component/file-explorer/file-explorer.css +475 -11
- package/src/client/ui/component/file-explorer/file-explorer.html +45 -65
- package/src/client/ui/component/file-explorer/file-explorer.mts +1164 -98
- package/src/client/ui/component/nested-chat/chat/chat.mts +5 -90
- package/src/client/ui/component/nested-chat/nested-chat.mts +10 -8
- package/src/client/ui/component/timeline/timeline.css +16 -1
- package/src/client/ui/component/timeline/timeline.mts +37 -93
- package/src/client/ui/component/tutorial/index.mts +9 -0
- package/src/client/ui/component/tutorial/scripts/pitch-tour-script.mts +265 -0
- package/src/client/ui/component/tutorial/tutorial-controller.mts +622 -0
- package/src/client/ui/component/tutorial/tutorial-types.mts +45 -0
- package/src/client/ui/component/tutorial/tutorial.css +260 -0
- package/src/client/ui/router/space-gib-router-helpers.mts +33 -233
- package/src/client/ui/router/space-gib-router-helpers.respec.mts +298 -122
- package/src/client/ui/router/space-gib-router-service.mts +28 -151
- package/src/client/ui/router/space-gib-router-types.mts +32 -76
- package/src/client/ui/shell/cosmic-big-bang.mts +12 -3
- package/src/client/ui/shell/space-gib-shell-service.mts +715 -143
- package/dist/client/chunk-RXWLL2AI.mjs +0 -30
|
@@ -31,6 +31,10 @@ import {
|
|
|
31
31
|
registerFileExplorerComponent, FILE_EXPLORER_COMPONENT_NAME,
|
|
32
32
|
FileExplorerComponentInstance,
|
|
33
33
|
} from "../component/file-explorer/index.mjs";
|
|
34
|
+
import {
|
|
35
|
+
registerChangesComponent, CHANGES_COMPONENT_NAME,
|
|
36
|
+
ChangesComponentInstance,
|
|
37
|
+
} from "../component/changes/index.mjs";
|
|
34
38
|
import {
|
|
35
39
|
registerTimelineComponent, TIMELINE_COMPONENT_NAME,
|
|
36
40
|
TimelineComponentInstance, TimelineItem,
|
|
@@ -49,6 +53,10 @@ import {
|
|
|
49
53
|
import {
|
|
50
54
|
registerPitchComponent, PITCH_COMPONENT_NAME, PitchComponentInstance,
|
|
51
55
|
} from "../component/pitch/index.mjs";
|
|
56
|
+
import {
|
|
57
|
+
getTutorialController,
|
|
58
|
+
PITCH_TOUR_SCRIPT,
|
|
59
|
+
} from "../component/tutorial/index.mjs";
|
|
52
60
|
import {
|
|
53
61
|
registerCodeEditorComponent, CODE_EDITOR_COMPONENT_NAME,
|
|
54
62
|
CodeEditorComponentInstance,
|
|
@@ -69,20 +77,137 @@ import {
|
|
|
69
77
|
getSpaceGibRouterSvc,
|
|
70
78
|
SpaceGibRouteInfo,
|
|
71
79
|
SpaceGibTenant,
|
|
80
|
+
GalaxyRouteInfo,
|
|
72
81
|
RawAddrRouteInfo,
|
|
73
82
|
RawTjpRouteInfo,
|
|
74
83
|
} from "../router/index.mjs";
|
|
84
|
+
import { GalaxyPolicy } from "@ibgib/core-gib/dist/cosmology/galaxy/galaxy-types.mjs";
|
|
75
85
|
import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs";
|
|
76
|
-
import { prewarmPlaygroundMetaspace } from "../../cosmos/seed-cosmos-workspace.mjs";
|
|
86
|
+
import { getPlaygroundMetaspaceAndSpace, prewarmPlaygroundMetaspace } from "../../cosmos/seed-cosmos-workspace.mjs";
|
|
87
|
+
import {
|
|
88
|
+
getBranchAndRootItemInfosAndIbGibsAndSpaceFromGalaxyIbGib,
|
|
89
|
+
getFileItemFromPath,
|
|
90
|
+
getFileContent,
|
|
91
|
+
} from "@ibgib/core-gib/dist/cosmology/branching/item/item-helpers.mjs";
|
|
92
|
+
import { GalaxyIbGib_V1 } from "@ibgib/core-gib/dist/cosmology/galaxy/galaxy-types.mjs";
|
|
93
|
+
import { B2tFSGalaxyIbGib_V1 } from "@ibgib/core-gib/dist/cosmology/branching/repo/b2tfs-repo-types.mjs";
|
|
94
|
+
import { getIbGibFromSpace } from "@ibgib/core-gib/dist/common/other/ibgib-helper.mjs";
|
|
95
|
+
import {
|
|
96
|
+
executeVcsBranch,
|
|
97
|
+
executeVcsCheckout,
|
|
98
|
+
} from "@ibgib/core-gib/dist/cosmology/branching/commands/index.mjs";
|
|
99
|
+
import { validateBranchName } from "@ibgib/core-gib/dist/cosmology/branching/branch/branch-helpers.mjs";
|
|
100
|
+
|
|
101
|
+
export interface PanelLoadContext {
|
|
102
|
+
route: GalaxyRouteInfo;
|
|
103
|
+
cosmosName: string;
|
|
104
|
+
galaxyName: string;
|
|
105
|
+
discriminator?: string;
|
|
106
|
+
policy: GalaxyPolicy;
|
|
107
|
+
cosmosInfo?: CosmosInfo;
|
|
108
|
+
shell: SpaceGibShellService;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type PanelName = 'LeftPanel' | 'CenterPanel' | 'RightPanel';
|
|
112
|
+
|
|
113
|
+
export type PanelLoaderFn = (route: GalaxyRouteInfo, context: PanelLoadContext) => Promise<void>;
|
|
77
114
|
|
|
115
|
+
export type PanelLoaderMap = {
|
|
116
|
+
[K in PanelName as `loadRouteFor${K}`]: PanelLoaderFn;
|
|
117
|
+
};
|
|
78
118
|
|
|
79
119
|
export class SpaceGibShellService {
|
|
80
120
|
private lc: string = `[SpaceGibShellService]`;
|
|
81
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Default convention panel loaders for Branching Galaxies (Class I Substrate / Code).
|
|
124
|
+
*/
|
|
125
|
+
protected branchingPanelLoaders: PanelLoaderMap = {
|
|
126
|
+
loadRouteForLeftPanel: async (route, context) => {
|
|
127
|
+
this.expandActivityBar();
|
|
128
|
+
this.expandLeftPanel();
|
|
129
|
+
this.setActiveActivityBarButton('space', route.galaxy);
|
|
130
|
+
this.showLeftPanelView('code', route.galaxy);
|
|
131
|
+
if (this.fileExplorerInstance) {
|
|
132
|
+
this.fileExplorerInstance.setGalaxyAndBranch(route.galaxy, route.branch || 'main');
|
|
133
|
+
if (route.filePath) {
|
|
134
|
+
this.fileExplorerInstance.selectFile(route.filePath);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (this.changesInstance) {
|
|
138
|
+
this.changesInstance.setGalaxyAndBranch(route.galaxy, route.branch || 'main', { preserveChanges: true });
|
|
139
|
+
}
|
|
140
|
+
if (this.codeEditorInstance) {
|
|
141
|
+
this.codeEditorInstance.setGalaxyAndBranch(route.galaxy, route.branch || 'main');
|
|
142
|
+
}
|
|
143
|
+
if (this.timelineInstance) {
|
|
144
|
+
this.timelineInstance.setBranch(route.branch || 'main');
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
loadRouteForCenterPanel: async (route, context) => {
|
|
148
|
+
this.switchToReposMode({ skipNavigate: true });
|
|
149
|
+
await this.showCode(route.filePath, route.branch, route.galaxy);
|
|
150
|
+
},
|
|
151
|
+
loadRouteForRightPanel: async (route, context) => {
|
|
152
|
+
if (route.query?.inspect) {
|
|
153
|
+
this.expandRightPanel();
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Default convention panel loaders for Linear Galaxies (Class IV Discourse / Notes).
|
|
160
|
+
*/
|
|
161
|
+
protected linearPanelLoaders: PanelLoaderMap = {
|
|
162
|
+
loadRouteForLeftPanel: async (route, context) => {
|
|
163
|
+
this.expandActivityBar();
|
|
164
|
+
this.expandLeftPanel();
|
|
165
|
+
this.setActiveActivityBarButton('space', route.galaxy);
|
|
166
|
+
this.showLeftPanelView('text', route.galaxy);
|
|
167
|
+
},
|
|
168
|
+
loadRouteForCenterPanel: async (route, context) => {
|
|
169
|
+
this.switchToNotesMode(route.topicTjp || route.galaxy, { skipNavigate: true, galaxyId: route.galaxy });
|
|
170
|
+
await this.showNotes(route.topicTjp || route.galaxy, {
|
|
171
|
+
trail: route.trail,
|
|
172
|
+
trailMode: route.trailMode,
|
|
173
|
+
query: route.query,
|
|
174
|
+
});
|
|
175
|
+
},
|
|
176
|
+
loadRouteForRightPanel: async (route, context) => {
|
|
177
|
+
if (route.query?.inspect) {
|
|
178
|
+
this.expandRightPanel();
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Registry of convention panel loaders keyed by topology or discriminator.
|
|
185
|
+
*/
|
|
186
|
+
protected panelLoaderRegistry: Record<string, PanelLoaderMap> = {
|
|
187
|
+
branching: this.branchingPanelLoaders,
|
|
188
|
+
linear: this.linearPanelLoaders,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
public registerPanelLoaders(key: string, loaders: PanelLoaderMap): void {
|
|
192
|
+
this.panelLoaderRegistry[key] = loaders;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
public async loadRouteForPanels(route: GalaxyRouteInfo, context: PanelLoadContext): Promise<void> {
|
|
196
|
+
const loaders =
|
|
197
|
+
(context.discriminator ? this.panelLoaderRegistry[context.discriminator] : undefined) ||
|
|
198
|
+
this.panelLoaderRegistry[context.policy.topology] ||
|
|
199
|
+
this.branchingPanelLoaders;
|
|
200
|
+
|
|
201
|
+
await loaders.loadRouteForLeftPanel(route, context);
|
|
202
|
+
await loaders.loadRouteForCenterPanel(route, context);
|
|
203
|
+
await loaders.loadRouteForRightPanel(route, context);
|
|
204
|
+
}
|
|
205
|
+
|
|
82
206
|
public initialized: Promise<void>;
|
|
83
207
|
private isApplyingRoute: boolean = false;
|
|
84
208
|
private cosmosNavigatorInstance?: CosmosNavigatorComponentInstance;
|
|
85
209
|
private fileExplorerInstance?: FileExplorerComponentInstance;
|
|
210
|
+
private changesInstance?: ChangesComponentInstance;
|
|
86
211
|
private timelineInstance?: TimelineComponentInstance;
|
|
87
212
|
private timelineItemDetailsInstance?: TimelineItemDetailsComponentInstance;
|
|
88
213
|
private chatViewInstance?: ChatViewComponentInstance;
|
|
@@ -92,6 +217,13 @@ export class SpaceGibShellService {
|
|
|
92
217
|
private notesExplorerInstance?: NotesExplorerComponentInstance;
|
|
93
218
|
private notesInspectorInstance?: NotesInspectorComponentInstance;
|
|
94
219
|
|
|
220
|
+
public getCosmosNavigator(): CosmosNavigatorComponentInstance | undefined {
|
|
221
|
+
return this.cosmosNavigatorInstance;
|
|
222
|
+
}
|
|
223
|
+
public getFileExplorer(): FileExplorerComponentInstance | undefined {
|
|
224
|
+
return this.fileExplorerInstance;
|
|
225
|
+
}
|
|
226
|
+
|
|
95
227
|
// Panel States
|
|
96
228
|
private leftPanelState: PanelState = 'collapsed';
|
|
97
229
|
private rightPanelState: PanelState = 'collapsed';
|
|
@@ -100,6 +232,8 @@ export class SpaceGibShellService {
|
|
|
100
232
|
private isResizingLeft = false;
|
|
101
233
|
private isResizingRight = false;
|
|
102
234
|
private isResizingFooter = false;
|
|
235
|
+
private isResizingExplorerChanges = false;
|
|
236
|
+
private isResizingChangesTimeline = false;
|
|
103
237
|
|
|
104
238
|
// Playground Banner State
|
|
105
239
|
private hasBigBangExploded = false;
|
|
@@ -114,6 +248,7 @@ export class SpaceGibShellService {
|
|
|
114
248
|
await this.registerComponents();
|
|
115
249
|
await this.initCosmosNavigator();
|
|
116
250
|
await this.initFileExplorer();
|
|
251
|
+
await this.initChanges();
|
|
117
252
|
await this.initTimeline();
|
|
118
253
|
await this.initChatView();
|
|
119
254
|
await this.initCodeEditor();
|
|
@@ -175,6 +310,44 @@ export class SpaceGibShellService {
|
|
|
175
310
|
footerResizer.addEventListener('mousedown', () => this.isResizingFooter = true);
|
|
176
311
|
}
|
|
177
312
|
|
|
313
|
+
// Accordion Horizontal Resizers (Left Panel)
|
|
314
|
+
const resizerExplorerChanges = document.getElementById('resizer-explorer-changes');
|
|
315
|
+
if (resizerExplorerChanges) {
|
|
316
|
+
resizerExplorerChanges.addEventListener('mousedown', (e) => {
|
|
317
|
+
e.preventDefault();
|
|
318
|
+
this.isResizingExplorerChanges = true;
|
|
319
|
+
resizerExplorerChanges.classList.add('active');
|
|
320
|
+
});
|
|
321
|
+
resizerExplorerChanges.addEventListener('dblclick', () => {
|
|
322
|
+
const explorerEl = document.getElementById('code-file-explorer-container');
|
|
323
|
+
if (explorerEl) {
|
|
324
|
+
explorerEl.style.flex = '';
|
|
325
|
+
explorerEl.style.height = '';
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const resizerChangesTimeline = document.getElementById('resizer-changes-timeline');
|
|
331
|
+
if (resizerChangesTimeline) {
|
|
332
|
+
resizerChangesTimeline.addEventListener('mousedown', (e) => {
|
|
333
|
+
e.preventDefault();
|
|
334
|
+
this.isResizingChangesTimeline = true;
|
|
335
|
+
resizerChangesTimeline.classList.add('active');
|
|
336
|
+
});
|
|
337
|
+
resizerChangesTimeline.addEventListener('dblclick', () => {
|
|
338
|
+
const changesEl = document.getElementById('code-changes-container');
|
|
339
|
+
const timelineEl = document.getElementById('code-timeline-container');
|
|
340
|
+
if (changesEl) {
|
|
341
|
+
changesEl.style.flex = '';
|
|
342
|
+
changesEl.style.height = '';
|
|
343
|
+
}
|
|
344
|
+
if (timelineEl) {
|
|
345
|
+
timelineEl.style.flex = '';
|
|
346
|
+
timelineEl.style.height = '';
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
178
351
|
// Window mouse events for dragging
|
|
179
352
|
window.addEventListener('mousemove', (e) => this.handleMouseMove(e));
|
|
180
353
|
window.addEventListener('mouseup', () => this.handleMouseUp());
|
|
@@ -437,7 +610,7 @@ export class SpaceGibShellService {
|
|
|
437
610
|
}
|
|
438
611
|
|
|
439
612
|
private handleMouseMove(e: MouseEvent) {
|
|
440
|
-
if (!this.isResizingLeft && !this.isResizingRight && !this.isResizingFooter) return;
|
|
613
|
+
if (!this.isResizingLeft && !this.isResizingRight && !this.isResizingFooter && !this.isResizingExplorerChanges && !this.isResizingChangesTimeline) return;
|
|
441
614
|
|
|
442
615
|
// Prevent text selection while dragging
|
|
443
616
|
e.preventDefault();
|
|
@@ -459,12 +632,40 @@ export class SpaceGibShellService {
|
|
|
459
632
|
let newHeight = Math.max(24, Math.min(window.innerHeight - e.clientY, 400));
|
|
460
633
|
document.documentElement.style.setProperty('--footer-panel-height', `${newHeight}px`);
|
|
461
634
|
}
|
|
635
|
+
|
|
636
|
+
if (this.isResizingExplorerChanges) {
|
|
637
|
+
const explorerEl = document.getElementById('code-file-explorer-container');
|
|
638
|
+
if (explorerEl) {
|
|
639
|
+
const rect = explorerEl.getBoundingClientRect();
|
|
640
|
+
const parentHeight = explorerEl.parentElement?.clientHeight || 600;
|
|
641
|
+
const maxExplorerHeight = parentHeight - 75;
|
|
642
|
+
const newHeight = Math.max(76, Math.min(e.clientY - rect.top, maxExplorerHeight));
|
|
643
|
+
explorerEl.style.flex = 'none';
|
|
644
|
+
explorerEl.style.height = `${newHeight}px`;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
if (this.isResizingChangesTimeline) {
|
|
649
|
+
const changesEl = document.getElementById('code-changes-container');
|
|
650
|
+
if (changesEl) {
|
|
651
|
+
const rect = changesEl.getBoundingClientRect();
|
|
652
|
+
const parentHeight = changesEl.parentElement?.clientHeight || 600;
|
|
653
|
+
const maxChangesHeight = parentHeight - (changesEl.offsetTop || 0) - 35;
|
|
654
|
+
const newHeight = Math.max(35, Math.min(e.clientY - rect.top, maxChangesHeight));
|
|
655
|
+
changesEl.style.flex = 'none';
|
|
656
|
+
changesEl.style.height = `${newHeight}px`;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
462
659
|
}
|
|
463
660
|
|
|
464
661
|
private handleMouseUp() {
|
|
465
662
|
this.isResizingLeft = false;
|
|
466
663
|
this.isResizingRight = false;
|
|
467
664
|
this.isResizingFooter = false;
|
|
665
|
+
this.isResizingExplorerChanges = false;
|
|
666
|
+
this.isResizingChangesTimeline = false;
|
|
667
|
+
document.getElementById('resizer-explorer-changes')?.classList.remove('active');
|
|
668
|
+
document.getElementById('resizer-changes-timeline')?.classList.remove('active');
|
|
468
669
|
}
|
|
469
670
|
|
|
470
671
|
private updateCssVariables() {
|
|
@@ -479,6 +680,7 @@ export class SpaceGibShellService {
|
|
|
479
680
|
await registerAdminReviewComponent();
|
|
480
681
|
await registerCosmosNavigatorComponent();
|
|
481
682
|
await registerFileExplorerComponent();
|
|
683
|
+
await registerChangesComponent();
|
|
482
684
|
await registerTimelineComponent();
|
|
483
685
|
await registerTimelineItemDetailsComponent();
|
|
484
686
|
await registerChatViewComponent();
|
|
@@ -560,6 +762,27 @@ export class SpaceGibShellService {
|
|
|
560
762
|
}
|
|
561
763
|
}
|
|
562
764
|
|
|
765
|
+
public show404(message: string): void {
|
|
766
|
+
const centerPanel = document.getElementById(ID_CENTER_PANEL_CONTENT);
|
|
767
|
+
if (centerPanel) {
|
|
768
|
+
centerPanel.innerHTML = `
|
|
769
|
+
<div class="cosmos-not-found-view" style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; color: #94a3b8; text-align: center; padding: 2rem; font-family: sans-serif;">
|
|
770
|
+
<div style="font-size: 3.5rem; margin-bottom: 1rem;">🌌 404</div>
|
|
771
|
+
<h2 style="font-size: 1.5rem; color: #fff; margin-bottom: 0.5rem; font-weight: 600;">Cosmos Not Found</h2>
|
|
772
|
+
<p style="margin-bottom: 1.5rem; max-width: 420px; font-size: 0.95rem; line-height: 1.5;">${message}</p>
|
|
773
|
+
<button id="btn-404-return" type="button" style="padding: 10px 22px; border-radius: 8px; background: rgba(124, 92, 252, 0.2); border: 1px solid rgba(124, 92, 252, 0.4); color: #c4b5fd; cursor: pointer; font-weight: 500; font-size: 0.95rem; transition: background 0.2s;">
|
|
774
|
+
Return to Polycosmos
|
|
775
|
+
</button>
|
|
776
|
+
</div>
|
|
777
|
+
`;
|
|
778
|
+
const returnBtn = document.getElementById('btn-404-return');
|
|
779
|
+
returnBtn?.addEventListener('click', () => {
|
|
780
|
+
getSpaceGibRouterSvc().navigate({ kind: 'polycosmos' });
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
this.collapsePanels();
|
|
784
|
+
}
|
|
785
|
+
|
|
563
786
|
private async initFileExplorer(): Promise<void> {
|
|
564
787
|
const lc = `${this.lc}[${this.initFileExplorer.name}]`;
|
|
565
788
|
try {
|
|
@@ -594,49 +817,91 @@ export class SpaceGibShellService {
|
|
|
594
817
|
|
|
595
818
|
private bindFileExplorerEvents(): void {
|
|
596
819
|
window.addEventListener('space-gib-file-selected', (e: any) => {
|
|
597
|
-
const { branch, path, filename } = e.detail || {};
|
|
598
|
-
console.log(`${this.lc} File selected: ${path || filename} on worktree branch ${branch}`);
|
|
599
|
-
const fullFile = path || filename
|
|
820
|
+
const { branch, path, filename, galaxy } = e.detail || {};
|
|
821
|
+
console.log(`${this.lc} File selected: ${path || filename} on worktree branch ${branch} in galaxy ${galaxy}`);
|
|
822
|
+
const fullFile = path || filename;
|
|
823
|
+
if (!fullFile) {
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
600
826
|
const branchName = branch || 'main';
|
|
601
|
-
const
|
|
827
|
+
const galaxyName = galaxy || 'code-1';
|
|
828
|
+
const tipAddr = 'tip';
|
|
829
|
+
|
|
602
830
|
this.chatViewInstance?.setTargetFile(fullFile, `${branchName} @ ${tipAddr}`);
|
|
603
831
|
this.nestedChatInstance?.activateIbGib({ addr: `file ${fullFile}^${tipAddr}` });
|
|
604
832
|
|
|
605
|
-
|
|
606
|
-
if (fullFile === 'src/helper.ts') {
|
|
607
|
-
mockContent = `/**\n * @module my-app/helper\n * Utility functions for space-gib in-memory VCS.\n */\n\nexport function add(a: number, b: number): number {\n return a + b;\n}\n\nexport function multiply(a: number, b: number): number {\n return a * b;\n}\n`;
|
|
608
|
-
} else if (fullFile === 'README.md') {
|
|
609
|
-
mockContent = `# my-app\n\nDecentralized version-controlled application running on **space-gib**.\n\n- Zero SaaS lock-in\n- Inverted soft rel8ns for living companion discussions\n- Merkle DAG branch worktrees\n`;
|
|
610
|
-
} else if (fullFile === 'tsconfig.json') {
|
|
611
|
-
mockContent = `{\n "compilerOptions": {\n "target": "ES2022",\n "module": "NodeNext",\n "strict": true,\n "esModuleInterop": true\n }\n}\n`;
|
|
612
|
-
}
|
|
833
|
+
this.showCode(fullFile, branchName, galaxyName);
|
|
613
834
|
|
|
614
|
-
this.
|
|
615
|
-
|
|
616
|
-
|
|
835
|
+
const activeCosmos = this.cosmosNavigatorInstance?.getActiveCosmos();
|
|
836
|
+
if (activeCosmos) {
|
|
837
|
+
const tenant = this.getActiveTenant();
|
|
838
|
+
getSpaceGibRouterSvc().navigate({
|
|
839
|
+
kind: 'galaxy',
|
|
840
|
+
cosmos: activeCosmos.id || activeCosmos.name,
|
|
841
|
+
galaxy: galaxyName,
|
|
842
|
+
topology: 'branching',
|
|
843
|
+
discriminator: 'code',
|
|
617
844
|
branch: branchName,
|
|
618
|
-
|
|
619
|
-
|
|
845
|
+
filePath: fullFile,
|
|
846
|
+
...(tenant ? { tenant } : {}),
|
|
620
847
|
});
|
|
621
|
-
}
|
|
848
|
+
}
|
|
849
|
+
});
|
|
622
850
|
|
|
623
|
-
|
|
624
|
-
|
|
851
|
+
window.addEventListener('space-gib-branch-switched', async (e: any) => {
|
|
852
|
+
const { galaxy, branch } = e.detail || {};
|
|
853
|
+
const targetGalaxy = galaxy || this.fileExplorerInstance?.getGalaxyName() || 'code-1';
|
|
854
|
+
const targetBranch = branch || 'main';
|
|
855
|
+
|
|
856
|
+
console.log(`${this.lc} Branch switched: [${targetGalaxy}] -> [${targetBranch}]`);
|
|
857
|
+
|
|
858
|
+
// 1. Update File Explorer, Changes, Timeline, Code Editor
|
|
859
|
+
this.fileExplorerInstance?.setGalaxyAndBranch(targetGalaxy, targetBranch);
|
|
860
|
+
this.changesInstance?.setGalaxyAndBranch(targetGalaxy, targetBranch, { preserveChanges: true });
|
|
861
|
+
this.codeEditorInstance?.setGalaxyAndBranch(targetGalaxy, targetBranch);
|
|
862
|
+
this.timelineInstance?.setBranch(targetBranch);
|
|
625
863
|
|
|
864
|
+
// 2. Refresh active file under new branch context
|
|
865
|
+
const activePath = this.fileExplorerInstance?.getSelectedFilePath() || this.codeEditorInstance?.getFilepath();
|
|
866
|
+
if (activePath) {
|
|
867
|
+
await this.showCode(activePath, targetBranch, targetGalaxy);
|
|
868
|
+
} else {
|
|
869
|
+
await this.showCode(undefined, targetBranch, targetGalaxy);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// 3. Update router navigation
|
|
626
873
|
const activeCosmos = this.cosmosNavigatorInstance?.getActiveCosmos();
|
|
627
874
|
if (activeCosmos) {
|
|
628
|
-
const tenant = this.getActiveTenant();
|
|
875
|
+
const tenant = this.getActiveTenant(activeCosmos);
|
|
629
876
|
getSpaceGibRouterSvc().navigate({
|
|
630
|
-
kind: '
|
|
877
|
+
kind: 'galaxy',
|
|
631
878
|
cosmos: activeCosmos.id || activeCosmos.name,
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
879
|
+
galaxy: targetGalaxy,
|
|
880
|
+
topology: 'branching',
|
|
881
|
+
discriminator: 'code',
|
|
882
|
+
branch: targetBranch,
|
|
883
|
+
...(activePath ? { filePath: activePath } : {}),
|
|
635
884
|
...(tenant ? { tenant } : {}),
|
|
636
885
|
});
|
|
637
886
|
}
|
|
638
887
|
});
|
|
639
888
|
|
|
889
|
+
window.addEventListener('space-gib-view-mode-changed', (e: any) => {
|
|
890
|
+
const { mode } = e.detail || {};
|
|
891
|
+
if (mode) {
|
|
892
|
+
this.changesInstance?.setViewMode(mode);
|
|
893
|
+
}
|
|
894
|
+
});
|
|
895
|
+
|
|
896
|
+
window.addEventListener('space-gib-accordion-toggled', () => {
|
|
897
|
+
const explorerEl = document.getElementById('code-file-explorer-container');
|
|
898
|
+
const changesEl = document.getElementById('code-changes-container');
|
|
899
|
+
const timelineEl = document.getElementById('code-timeline-container');
|
|
900
|
+
if (explorerEl) { explorerEl.style.flex = ''; explorerEl.style.height = ''; }
|
|
901
|
+
if (changesEl) { changesEl.style.flex = ''; changesEl.style.height = ''; }
|
|
902
|
+
if (timelineEl) { timelineEl.style.flex = ''; timelineEl.style.height = ''; }
|
|
903
|
+
});
|
|
904
|
+
|
|
640
905
|
window.addEventListener('space-gib-new-file-requested', (e: any) => {
|
|
641
906
|
const { branch } = e.detail || {};
|
|
642
907
|
const filename = prompt(`Create new file on branch [${branch || 'main'}]:`, 'untitled.ts');
|
|
@@ -654,6 +919,117 @@ export class SpaceGibShellService {
|
|
|
654
919
|
});
|
|
655
920
|
}
|
|
656
921
|
|
|
922
|
+
private async initChanges(): Promise<void> {
|
|
923
|
+
const lc = `${this.lc}[${this.initChanges.name}]`;
|
|
924
|
+
try {
|
|
925
|
+
const container = document.getElementById('code-changes-container');
|
|
926
|
+
if (!container) {
|
|
927
|
+
console.warn(`${lc} code-changes-container element not found.`);
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
const componentSvc = await getComponentSvc();
|
|
932
|
+
this.changesInstance = await componentSvc.getComponentInstance({
|
|
933
|
+
path: CHANGES_COMPONENT_NAME,
|
|
934
|
+
ibGibAddr: ROOT_ADDR,
|
|
935
|
+
useRegExpPrefilter: true,
|
|
936
|
+
}) as ChangesComponentInstance;
|
|
937
|
+
|
|
938
|
+
if (!this.changesInstance) {
|
|
939
|
+
throw new Error(`Failed to instantiate ${CHANGES_COMPONENT_NAME}`);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
await componentSvc.inject({
|
|
943
|
+
parentEl: container,
|
|
944
|
+
componentToInject: this.changesInstance,
|
|
945
|
+
});
|
|
946
|
+
|
|
947
|
+
if (this.fileExplorerInstance) {
|
|
948
|
+
this.changesInstance.setViewMode(this.fileExplorerInstance.getViewMode());
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
this.bindChangesEvents();
|
|
952
|
+
|
|
953
|
+
} catch (error) {
|
|
954
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
private bindChangesEvents(): void {
|
|
959
|
+
window.addEventListener('space-gib-commit-created', (e: any) => {
|
|
960
|
+
const { branch, message, tipAddr, shortHash } = e.detail || {};
|
|
961
|
+
console.log(`${this.lc} Commit created: [${shortHash}] "${message}" on branch [${branch}]`);
|
|
962
|
+
|
|
963
|
+
// 1. Clear status badges in file explorer for this branch
|
|
964
|
+
this.fileExplorerInstance?.clearAllStatusBadges(branch);
|
|
965
|
+
this.fileExplorerInstance?.updateDirtyBadges();
|
|
966
|
+
|
|
967
|
+
// 2. Add snapshot to timeline
|
|
968
|
+
this.timelineInstance?.addSnapshot({
|
|
969
|
+
hash: tipAddr,
|
|
970
|
+
shortHash: shortHash || (tipAddr ? tipAddr.slice(-8) : 'unknown'),
|
|
971
|
+
message: message || 'Update',
|
|
972
|
+
author: 'You',
|
|
973
|
+
timestamp: 'Just now',
|
|
974
|
+
branch: branch || 'main',
|
|
975
|
+
isTip: true,
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
// 3. Update breadcrumb tip and mark committed in code editor
|
|
979
|
+
if (this.codeEditorInstance) {
|
|
980
|
+
if (shortHash) {
|
|
981
|
+
this.codeEditorInstance.setTipAddr(shortHash);
|
|
982
|
+
}
|
|
983
|
+
const activePath = this.codeEditorInstance.getFilepath();
|
|
984
|
+
if (activePath) {
|
|
985
|
+
this.codeEditorInstance.markAsCommitted(shortHash || tipAddr);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
window.addEventListener('space-gib-file-created', (e: any) => {
|
|
991
|
+
const { path, content, galaxy, branch } = e.detail || {};
|
|
992
|
+
if (galaxy || branch) {
|
|
993
|
+
const g = galaxy || this.changesInstance?.getGalaxyName() || 'code-1';
|
|
994
|
+
const b = branch || this.changesInstance?.getBranchName() || 'main';
|
|
995
|
+
this.changesInstance?.setGalaxyAndBranch(g, b, { preserveChanges: true });
|
|
996
|
+
this.codeEditorInstance?.setGalaxyAndBranch(g, b);
|
|
997
|
+
}
|
|
998
|
+
if (path) {
|
|
999
|
+
this.changesInstance?.recordChange({
|
|
1000
|
+
path,
|
|
1001
|
+
status: 'untracked',
|
|
1002
|
+
content: content ?? '',
|
|
1003
|
+
});
|
|
1004
|
+
this.fileExplorerInstance?.updateDirtyBadges();
|
|
1005
|
+
}
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
window.addEventListener('space-gib-change-discarded', (e: any) => {
|
|
1009
|
+
const { path, originalContent, branch, galaxy } = e.detail || {};
|
|
1010
|
+
if (path) {
|
|
1011
|
+
const b = branch || this.fileExplorerInstance?.getBranchName() || 'main';
|
|
1012
|
+
const g = galaxy || this.fileExplorerInstance?.getGalaxyName() || 'code-1';
|
|
1013
|
+
if (this.fileExplorerInstance?.isUntracked(path, b, g)) {
|
|
1014
|
+
this.fileExplorerInstance.removeFile(path, b, g);
|
|
1015
|
+
if (this.codeEditorInstance && this.codeEditorInstance.getFilepath() === path) {
|
|
1016
|
+
this.codeEditorInstance.clearFile({ repo: g, branch: b });
|
|
1017
|
+
}
|
|
1018
|
+
} else {
|
|
1019
|
+
this.fileExplorerInstance?.setFileStatus(path, undefined, b, g);
|
|
1020
|
+
if (this.codeEditorInstance && this.codeEditorInstance.getFilepath() === path) {
|
|
1021
|
+
if (originalContent !== undefined) {
|
|
1022
|
+
this.codeEditorInstance.setContent(originalContent);
|
|
1023
|
+
} else {
|
|
1024
|
+
this.showCode(path, b, g);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
this.fileExplorerInstance?.updateDirtyBadges();
|
|
1029
|
+
}
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
|
|
657
1033
|
private async initTimeline(): Promise<void> {
|
|
658
1034
|
const lc = `${this.lc}[${this.initTimeline.name}]`;
|
|
659
1035
|
try {
|
|
@@ -781,7 +1157,7 @@ export class SpaceGibShellService {
|
|
|
781
1157
|
}
|
|
782
1158
|
}
|
|
783
1159
|
|
|
784
|
-
public async showCode(filePath?: string, branch?: string): Promise<void> {
|
|
1160
|
+
public async showCode(filePath?: string, branch?: string, galaxy?: string): Promise<void> {
|
|
785
1161
|
const lc = `${this.lc}[${this.showCode.name}]`;
|
|
786
1162
|
try {
|
|
787
1163
|
const centerPanel = document.getElementById(ID_CENTER_PANEL_CONTENT);
|
|
@@ -790,6 +1166,10 @@ export class SpaceGibShellService {
|
|
|
790
1166
|
return;
|
|
791
1167
|
}
|
|
792
1168
|
|
|
1169
|
+
const currentRoute = getSpaceGibRouterSvc().getCurrentRoute();
|
|
1170
|
+
const targetGalaxy = galaxy || (currentRoute && 'galaxy' in currentRoute ? (currentRoute as any).galaxy : undefined) || this.fileExplorerInstance?.getGalaxyName() || this.changesInstance?.getGalaxyName() || 'code-1';
|
|
1171
|
+
const targetBranch = branch || (currentRoute && 'branch' in currentRoute ? (currentRoute as any).branch : undefined) || this.fileExplorerInstance?.getBranchName() || this.changesInstance?.getBranchName() || 'main';
|
|
1172
|
+
|
|
793
1173
|
if (!this.codeEditorInstance) {
|
|
794
1174
|
const componentSvc = await getComponentSvc();
|
|
795
1175
|
this.codeEditorInstance = await componentSvc.getComponentInstance({
|
|
@@ -806,25 +1186,81 @@ export class SpaceGibShellService {
|
|
|
806
1186
|
componentToInject: this.codeEditorInstance,
|
|
807
1187
|
});
|
|
808
1188
|
|
|
1189
|
+
this.codeEditorInstance.setGalaxyAndBranch(targetGalaxy, targetBranch);
|
|
1190
|
+
|
|
809
1191
|
if (filePath) {
|
|
810
|
-
let
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
1192
|
+
let casContent: string | undefined = undefined;
|
|
1193
|
+
let tipAddr: string = 'tip';
|
|
1194
|
+
|
|
1195
|
+
try {
|
|
1196
|
+
const { metaspace, space } = await getPlaygroundMetaspaceAndSpace();
|
|
1197
|
+
const router = getSpaceGibRouterSvc();
|
|
1198
|
+
let galaxyIbGib: B2tFSGalaxyIbGib_V1 | undefined;
|
|
1199
|
+
for (const manifest of router.cosmosManifestCache?.values() || []) {
|
|
1200
|
+
const entry = manifest.data?.galaxies?.[targetGalaxy];
|
|
1201
|
+
if (entry?.galaxyAddr) {
|
|
1202
|
+
galaxyIbGib = await getIbGibFromSpace<B2tFSGalaxyIbGib_V1>({ addr: entry.galaxyAddr, space });
|
|
1203
|
+
if (galaxyIbGib) break;
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
if (galaxyIbGib) {
|
|
1207
|
+
const branchAndRoot = await getBranchAndRootItemInfosAndIbGibsAndSpaceFromGalaxyIbGib({
|
|
1208
|
+
galaxyIbGib,
|
|
1209
|
+
branchName: targetBranch,
|
|
1210
|
+
metaspace,
|
|
1211
|
+
});
|
|
1212
|
+
tipAddr = branchAndRoot.branchIbGib.gib || 'tip';
|
|
1213
|
+
const rootItem = branchAndRoot.rootItemIbGib_latest || branchAndRoot.rootItemIbGib;
|
|
1214
|
+
const fileItem = await getFileItemFromPath({
|
|
1215
|
+
branchSpace: branchAndRoot.branchSpace,
|
|
1216
|
+
rootItem,
|
|
1217
|
+
filePath,
|
|
1218
|
+
});
|
|
1219
|
+
if (fileItem) {
|
|
1220
|
+
casContent = await getFileContent({ branchSpace: branchAndRoot.branchSpace, fileItem });
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
} catch (readErr) {
|
|
1224
|
+
console.warn(`${lc} Error reading file [${filePath}] from branch space: ${extractErrorMsg(readErr)}`);
|
|
817
1225
|
}
|
|
818
1226
|
|
|
1227
|
+
const workingChange = this.changesInstance?.getChange(filePath, targetBranch);
|
|
1228
|
+
const isUntrackedInExplorer = this.fileExplorerInstance?.isUntracked(filePath, targetBranch, targetGalaxy);
|
|
1229
|
+
const fileExistsInCas = casContent !== undefined;
|
|
1230
|
+
const hasWorkingTreeChange = workingChange !== undefined;
|
|
1231
|
+
|
|
1232
|
+
// If file doesn't exist in CAS, and is neither in working tree nor marked untracked in explorer, clear editor
|
|
1233
|
+
if (!fileExistsInCas && !hasWorkingTreeChange && !isUntrackedInExplorer) {
|
|
1234
|
+
this.codeEditorInstance.clearFile({
|
|
1235
|
+
repo: targetGalaxy,
|
|
1236
|
+
branch: targetBranch,
|
|
1237
|
+
});
|
|
1238
|
+
this.fileExplorerInstance?.selectFile('');
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
const isUntracked = !fileExistsInCas;
|
|
1243
|
+
const content = workingChange?.content ?? casContent ?? '';
|
|
1244
|
+
|
|
819
1245
|
this.codeEditorInstance.loadFile({
|
|
820
1246
|
filepath: filePath,
|
|
821
|
-
|
|
822
|
-
|
|
1247
|
+
repo: targetGalaxy,
|
|
1248
|
+
branch: targetBranch,
|
|
1249
|
+
tipAddr,
|
|
823
1250
|
content,
|
|
1251
|
+
originalContent: casContent,
|
|
1252
|
+
isUntracked,
|
|
1253
|
+
});
|
|
1254
|
+
} else {
|
|
1255
|
+
this.codeEditorInstance.clearFile({
|
|
1256
|
+
repo: targetGalaxy,
|
|
1257
|
+
branch: targetBranch,
|
|
824
1258
|
});
|
|
825
1259
|
}
|
|
826
1260
|
}
|
|
827
1261
|
|
|
1262
|
+
this.changesInstance?.setGalaxyAndBranch(targetGalaxy, targetBranch, { preserveChanges: true });
|
|
1263
|
+
|
|
828
1264
|
const codeChatContainer = document.getElementById('code-chat-view-container');
|
|
829
1265
|
const notesInspectorContainer = document.getElementById('notes-inspector-container');
|
|
830
1266
|
if (notesInspectorContainer) { notesInspectorContainer.style.display = 'none'; }
|
|
@@ -1004,8 +1440,25 @@ export class SpaceGibShellService {
|
|
|
1004
1440
|
|
|
1005
1441
|
private bindCodeEditorEvents(): void {
|
|
1006
1442
|
window.addEventListener('space-gib-code-changed', (e: any) => {
|
|
1007
|
-
const { filepath, lineCount } = e.detail || {};
|
|
1008
|
-
|
|
1443
|
+
const { filepath, content, lineCount, isReverted, isUntracked: isUntrackedProp, branch, repo } = e.detail || {};
|
|
1444
|
+
const targetBranch = branch || this.changesInstance?.getBranchName() || 'main';
|
|
1445
|
+
const targetGalaxy = repo || this.changesInstance?.getGalaxyName() || 'code-1';
|
|
1446
|
+
console.log(`${this.lc} Code changed in ${filepath} on branch [${targetBranch}] (${lineCount} lines, isReverted=${isReverted})`);
|
|
1447
|
+
if (filepath) {
|
|
1448
|
+
if (isReverted) {
|
|
1449
|
+
this.changesInstance?.removeChange(filepath, targetBranch);
|
|
1450
|
+
this.fileExplorerInstance?.setFileStatus(filepath, undefined, targetBranch, targetGalaxy);
|
|
1451
|
+
} else {
|
|
1452
|
+
const isUntracked = Boolean(isUntrackedProp || this.changesInstance?.isUntracked(filepath, targetBranch) || this.fileExplorerInstance?.isUntracked(filepath, targetBranch, targetGalaxy));
|
|
1453
|
+
const status = isUntracked ? 'untracked' : 'modified';
|
|
1454
|
+
this.changesInstance?.recordChange({
|
|
1455
|
+
path: filepath,
|
|
1456
|
+
status,
|
|
1457
|
+
content: content ?? '',
|
|
1458
|
+
}, targetBranch);
|
|
1459
|
+
this.fileExplorerInstance?.setFileStatus(filepath, status, targetBranch, targetGalaxy);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1009
1462
|
});
|
|
1010
1463
|
|
|
1011
1464
|
window.addEventListener('space-gib-code-copied', (e: any) => {
|
|
@@ -1055,38 +1508,30 @@ export class SpaceGibShellService {
|
|
|
1055
1508
|
}
|
|
1056
1509
|
|
|
1057
1510
|
public async showPitch(): Promise<void> {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
const centerPanel = document.getElementById(ID_CENTER_PANEL_CONTENT);
|
|
1061
|
-
if (!centerPanel) {
|
|
1062
|
-
console.warn(`${lc} ${ID_CENTER_PANEL_CONTENT} element not found.`);
|
|
1063
|
-
return;
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
if (!this.pitchInstance) {
|
|
1067
|
-
const componentSvc = await getComponentSvc();
|
|
1068
|
-
this.pitchInstance = await componentSvc.getComponentInstance({
|
|
1069
|
-
path: PITCH_COMPONENT_NAME,
|
|
1070
|
-
ibGibAddr: ROOT_ADDR,
|
|
1071
|
-
useRegExpPrefilter: true,
|
|
1072
|
-
}) as PitchComponentInstance;
|
|
1073
|
-
}
|
|
1511
|
+
await this.startPitchTour();
|
|
1512
|
+
}
|
|
1074
1513
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1514
|
+
public async startPitchTour(): Promise<void> {
|
|
1515
|
+
const lc = `${this.lc}[${this.startPitchTour.name}]`;
|
|
1516
|
+
console.log(`${lc} startPitchTour triggered.`);
|
|
1517
|
+
try {
|
|
1518
|
+
const tutorial = getTutorialController();
|
|
1519
|
+
console.log(`${lc} tutorialController isActive = ${tutorial.isActive}`);
|
|
1520
|
+
if (tutorial.isActive) {
|
|
1521
|
+
await tutorial.next();
|
|
1522
|
+
} else {
|
|
1523
|
+
await tutorial.start(PITCH_TOUR_SCRIPT, this);
|
|
1081
1524
|
}
|
|
1082
|
-
|
|
1083
|
-
this.collapsePanels();
|
|
1084
1525
|
} catch (error) {
|
|
1085
1526
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1086
1527
|
}
|
|
1087
1528
|
}
|
|
1088
1529
|
|
|
1089
1530
|
public closePitch(): void {
|
|
1531
|
+
const tutorial = getTutorialController();
|
|
1532
|
+
if (tutorial.isActive) {
|
|
1533
|
+
tutorial.stop();
|
|
1534
|
+
}
|
|
1090
1535
|
this.showCosmos();
|
|
1091
1536
|
}
|
|
1092
1537
|
|
|
@@ -1165,8 +1610,7 @@ export class SpaceGibShellService {
|
|
|
1165
1610
|
if (activitySpaces) {
|
|
1166
1611
|
let matched = false;
|
|
1167
1612
|
activitySpaces.querySelectorAll('.activity-bar-btn').forEach(b => {
|
|
1168
|
-
const isMatch = b.getAttribute('data-space-id') === spaceId
|
|
1169
|
-
b.getAttribute('data-space-type') === spaceId;
|
|
1613
|
+
const isMatch = b.getAttribute('data-space-id') === spaceId;
|
|
1170
1614
|
b.classList.toggle('active', isMatch);
|
|
1171
1615
|
if (isMatch) matched = true;
|
|
1172
1616
|
});
|
|
@@ -1269,10 +1713,33 @@ export class SpaceGibShellService {
|
|
|
1269
1713
|
}
|
|
1270
1714
|
if (space.type === 'code') {
|
|
1271
1715
|
this.showLeftPanelView('code', space.name);
|
|
1272
|
-
this.switchToReposMode();
|
|
1716
|
+
this.switchToReposMode({ skipNavigate: true, galaxyId: space.name });
|
|
1717
|
+
if (!this.isApplyingRoute && cosmos?.name) {
|
|
1718
|
+
const tenant = this.getActiveTenant(cosmos.name);
|
|
1719
|
+
getSpaceGibRouterSvc().navigate({
|
|
1720
|
+
kind: 'galaxy',
|
|
1721
|
+
...(tenant ? { tenant } : {}),
|
|
1722
|
+
cosmos: cosmos.name,
|
|
1723
|
+
galaxy: space.name,
|
|
1724
|
+
topology: 'branching',
|
|
1725
|
+
discriminator: 'code',
|
|
1726
|
+
branch: 'main',
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1273
1729
|
} else if (space.type === 'text') {
|
|
1274
1730
|
this.showLeftPanelView('text', space.name);
|
|
1275
|
-
this.switchToNotesMode(space.name);
|
|
1731
|
+
this.switchToNotesMode(space.name, { skipNavigate: true, galaxyId: space.name });
|
|
1732
|
+
if (!this.isApplyingRoute && cosmos?.name) {
|
|
1733
|
+
const tenant = this.getActiveTenant(cosmos.name);
|
|
1734
|
+
getSpaceGibRouterSvc().navigate({
|
|
1735
|
+
kind: 'galaxy',
|
|
1736
|
+
...(tenant ? { tenant } : {}),
|
|
1737
|
+
cosmos: cosmos.name,
|
|
1738
|
+
galaxy: space.name,
|
|
1739
|
+
topology: 'linear',
|
|
1740
|
+
discriminator: 'notes',
|
|
1741
|
+
});
|
|
1742
|
+
}
|
|
1276
1743
|
}
|
|
1277
1744
|
}
|
|
1278
1745
|
});
|
|
@@ -1304,6 +1771,7 @@ export class SpaceGibShellService {
|
|
|
1304
1771
|
const btnHeaderClone = document.getElementById('btn-header-clone');
|
|
1305
1772
|
|
|
1306
1773
|
btnHeaderPitch?.addEventListener('click', () => {
|
|
1774
|
+
console.log(`[SpaceGibShellService] #btn-header-pitch clicked! Triggering showPitch()...`);
|
|
1307
1775
|
this.showPitch();
|
|
1308
1776
|
});
|
|
1309
1777
|
|
|
@@ -1315,12 +1783,100 @@ export class SpaceGibShellService {
|
|
|
1315
1783
|
this.openCloneModal(e.detail);
|
|
1316
1784
|
});
|
|
1317
1785
|
|
|
1318
|
-
window.addEventListener('space-gib-branch-requested', (e: any) => {
|
|
1786
|
+
window.addEventListener('space-gib-branch-requested', async (e: any) => {
|
|
1319
1787
|
const { galaxyName, sourceBranch, newBranchName, scope, itemPath } = e.detail || {};
|
|
1320
|
-
const
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1788
|
+
const cleanGalaxy = galaxyName || 'code-1';
|
|
1789
|
+
const cleanSourceBranch = sourceBranch || 'main';
|
|
1790
|
+
const cleanNewBranch = newBranchName?.trim();
|
|
1791
|
+
if (!cleanNewBranch) return;
|
|
1792
|
+
|
|
1793
|
+
const validation = validateBranchName(cleanNewBranch);
|
|
1794
|
+
if (!validation.isValid) {
|
|
1795
|
+
alert(`Invalid branch name: ${validation.error}`);
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
const lc = `${this.lc}[space-gib-branch-requested]`;
|
|
1800
|
+
try {
|
|
1801
|
+
const { metaspace, space } = await getPlaygroundMetaspaceAndSpace();
|
|
1802
|
+
const router = getSpaceGibRouterSvc();
|
|
1803
|
+
|
|
1804
|
+
// 1. Resolve GalaxyIbGib
|
|
1805
|
+
let galaxyIbGib: B2tFSGalaxyIbGib_V1 | undefined;
|
|
1806
|
+
for (const manifest of router.cosmosManifestCache?.values() || []) {
|
|
1807
|
+
const entry = manifest.data?.galaxies?.[cleanGalaxy];
|
|
1808
|
+
if (entry?.galaxyAddr) {
|
|
1809
|
+
galaxyIbGib = await getIbGibFromSpace<B2tFSGalaxyIbGib_V1>({ addr: entry.galaxyAddr, space });
|
|
1810
|
+
if (galaxyIbGib) break;
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
if (!galaxyIbGib) {
|
|
1815
|
+
throw new Error(`Galaxy [${cleanGalaxy}] not found in cosmos manifest.`);
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
// 2. Resolve source branch space
|
|
1819
|
+
const branchAndRoot = await getBranchAndRootItemInfosAndIbGibsAndSpaceFromGalaxyIbGib({
|
|
1820
|
+
galaxyIbGib,
|
|
1821
|
+
branchName: cleanSourceBranch,
|
|
1822
|
+
metaspace,
|
|
1823
|
+
});
|
|
1824
|
+
|
|
1825
|
+
const activeBranchSpace = branchAndRoot.branchSpace;
|
|
1826
|
+
|
|
1827
|
+
// 3. Execute isomorphic VCS branch creation
|
|
1828
|
+
const branchRes = await executeVcsBranch({
|
|
1829
|
+
metaspace,
|
|
1830
|
+
localSpace: space,
|
|
1831
|
+
sourceBranchSpace: activeBranchSpace,
|
|
1832
|
+
galaxyIbGib,
|
|
1833
|
+
branchName: cleanNewBranch,
|
|
1834
|
+
sourceBranchName: cleanSourceBranch,
|
|
1835
|
+
itemPath: scope === 'item' ? itemPath : undefined,
|
|
1836
|
+
});
|
|
1837
|
+
|
|
1838
|
+
const finalGalaxy = branchRes.updatedGalaxy || galaxyIbGib;
|
|
1839
|
+
const finalGalaxyAddr = getIbGibAddr({ ibGib: finalGalaxy });
|
|
1840
|
+
|
|
1841
|
+
// 4. Update router cosmos manifest cache with updated galaxy address
|
|
1842
|
+
for (const manifest of router.cosmosManifestCache?.values() || []) {
|
|
1843
|
+
if (manifest.data?.galaxies?.[cleanGalaxy]) {
|
|
1844
|
+
manifest.data.galaxies[cleanGalaxy].galaxyAddr = finalGalaxyAddr;
|
|
1845
|
+
break;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
// 5. Broadcast new galaxy IbGib to metaspace subscribers
|
|
1850
|
+
await (metaspace as any).registerNewIbGib?.({ ibGib: finalGalaxy, space });
|
|
1851
|
+
|
|
1852
|
+
// 6. Update Changes, File Explorer & Code Editor
|
|
1853
|
+
this.changesInstance?.setGalaxyAndBranch(cleanGalaxy, cleanNewBranch);
|
|
1854
|
+
this.fileExplorerInstance?.setGalaxyAndBranch(cleanGalaxy, cleanNewBranch);
|
|
1855
|
+
this.codeEditorInstance?.setGalaxyAndBranch(cleanGalaxy, cleanNewBranch);
|
|
1856
|
+
this.timelineInstance?.setBranch(cleanNewBranch);
|
|
1857
|
+
|
|
1858
|
+
// 8. Navigate router to new branch
|
|
1859
|
+
const activeCosmos = this.cosmosNavigatorInstance?.getActiveCosmos();
|
|
1860
|
+
const activePath = this.codeEditorInstance?.getFilepath();
|
|
1861
|
+
if (activeCosmos) {
|
|
1862
|
+
const tenant = this.getActiveTenant(activeCosmos);
|
|
1863
|
+
router.navigate({
|
|
1864
|
+
kind: 'galaxy',
|
|
1865
|
+
cosmos: activeCosmos.id || activeCosmos.name,
|
|
1866
|
+
galaxy: cleanGalaxy,
|
|
1867
|
+
topology: 'branching',
|
|
1868
|
+
discriminator: 'code',
|
|
1869
|
+
branch: cleanNewBranch,
|
|
1870
|
+
...(activePath ? { filePath: activePath } : {}),
|
|
1871
|
+
...(tenant ? { tenant } : {}),
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
console.log(`${lc} Successfully diverged to new branch [${cleanNewBranch}] from ${scope === 'item' ? `item [${itemPath}]` : `worktree [${cleanSourceBranch}]`} in galaxy [${cleanGalaxy}]`);
|
|
1876
|
+
} catch (err) {
|
|
1877
|
+
console.error(`${lc} Failed to branch: ${extractErrorMsg(err)}`);
|
|
1878
|
+
alert(`Failed to create branch: ${extractErrorMsg(err)}`);
|
|
1879
|
+
}
|
|
1324
1880
|
});
|
|
1325
1881
|
|
|
1326
1882
|
btnFooterAgent?.addEventListener('click', () => {
|
|
@@ -1413,9 +1969,9 @@ export class SpaceGibShellService {
|
|
|
1413
1969
|
|
|
1414
1970
|
btnSideNewCosmos?.addEventListener('click', () => {
|
|
1415
1971
|
this.switchToSpacesMode();
|
|
1416
|
-
this.cosmosNavigatorInstance?.triggerBigBangSequence(() => {
|
|
1972
|
+
this.cosmosNavigatorInstance?.triggerBigBangSequence(async () => {
|
|
1417
1973
|
const nextIdx = (this.cosmosNavigatorInstance?.getCosmoses().length || 0) + 1;
|
|
1418
|
-
const newCosmos = this.cosmosNavigatorInstance?.createCosmos(`
|
|
1974
|
+
const newCosmos = await this.cosmosNavigatorInstance?.createCosmos(`cosmos-${nextIdx}`);
|
|
1419
1975
|
if (newCosmos) {
|
|
1420
1976
|
this.cosmosNavigatorInstance?.selectCosmos(newCosmos.id);
|
|
1421
1977
|
}
|
|
@@ -1461,13 +2017,14 @@ export class SpaceGibShellService {
|
|
|
1461
2017
|
spacesList.querySelectorAll('.cosmos-space-item').forEach(el => {
|
|
1462
2018
|
el.addEventListener('click', () => {
|
|
1463
2019
|
const type = el.getAttribute('data-space-type');
|
|
2020
|
+
const spaceId = el.getAttribute('data-space-id') || '';
|
|
1464
2021
|
const name = el.querySelector('.space-item-name')?.textContent || '';
|
|
1465
2022
|
if (type === 'code') {
|
|
1466
2023
|
this.showLeftPanelView('code', name);
|
|
1467
|
-
this.switchToReposMode();
|
|
2024
|
+
this.switchToReposMode({ galaxyId: spaceId });
|
|
1468
2025
|
} else {
|
|
1469
2026
|
this.showLeftPanelView('text', name);
|
|
1470
|
-
this.switchToNotesMode(name);
|
|
2027
|
+
this.switchToNotesMode(name, { galaxyId: spaceId });
|
|
1471
2028
|
}
|
|
1472
2029
|
});
|
|
1473
2030
|
});
|
|
@@ -1492,10 +2049,10 @@ export class SpaceGibShellService {
|
|
|
1492
2049
|
|
|
1493
2050
|
if (type === 'code') {
|
|
1494
2051
|
this.showLeftPanelView('code', title);
|
|
1495
|
-
this.switchToReposMode();
|
|
2052
|
+
this.switchToReposMode({ galaxyId: spaceId });
|
|
1496
2053
|
} else {
|
|
1497
2054
|
this.showLeftPanelView('text', title);
|
|
1498
|
-
this.switchToNotesMode(title);
|
|
2055
|
+
this.switchToNotesMode(title, { galaxyId: spaceId });
|
|
1499
2056
|
}
|
|
1500
2057
|
});
|
|
1501
2058
|
});
|
|
@@ -1603,12 +2160,12 @@ export class SpaceGibShellService {
|
|
|
1603
2160
|
});
|
|
1604
2161
|
|
|
1605
2162
|
const btnNew = menu.querySelector('#btn-header-menu-new-cosmos');
|
|
1606
|
-
btnNew?.addEventListener('click', () => {
|
|
2163
|
+
btnNew?.addEventListener('click', async () => {
|
|
1607
2164
|
menu.classList.add('hidden');
|
|
1608
2165
|
this.switchToSpacesMode();
|
|
1609
2166
|
this.cosmosNavigatorInstance?.triggerBigBangExplosion();
|
|
1610
2167
|
const nextIdx = cosmoses.length + 1;
|
|
1611
|
-
const newC = this.cosmosNavigatorInstance?.createCosmos(`
|
|
2168
|
+
const newC = await this.cosmosNavigatorInstance?.createCosmos(`cosmos-${nextIdx}`);
|
|
1612
2169
|
if (newC) {
|
|
1613
2170
|
setTimeout(() => {
|
|
1614
2171
|
this.cosmosNavigatorInstance?.selectCosmos(newC.id);
|
|
@@ -1623,17 +2180,25 @@ export class SpaceGibShellService {
|
|
|
1623
2180
|
const viewCode = document.getElementById('left-panel-code-view');
|
|
1624
2181
|
const viewText = document.getElementById('left-panel-text-view');
|
|
1625
2182
|
|
|
1626
|
-
if (viewPoly) {
|
|
1627
|
-
|
|
2183
|
+
if (viewPoly) {
|
|
2184
|
+
viewPoly.style.display = viewName === 'polycosmos' ? 'flex' : 'none';
|
|
2185
|
+
viewPoly.style.flexDirection = 'column';
|
|
2186
|
+
}
|
|
2187
|
+
if (viewCosmos) {
|
|
2188
|
+
viewCosmos.style.display = viewName === 'cosmos' ? 'flex' : 'none';
|
|
2189
|
+
viewCosmos.style.flexDirection = 'column';
|
|
2190
|
+
}
|
|
1628
2191
|
if (viewCode) {
|
|
1629
|
-
viewCode.style.display = viewName === 'code' ? '
|
|
2192
|
+
viewCode.style.display = viewName === 'code' ? 'flex' : 'none';
|
|
2193
|
+
viewCode.style.flexDirection = 'column';
|
|
1630
2194
|
if (title) {
|
|
1631
2195
|
const titleEl = document.getElementById('left-code-space-title');
|
|
1632
2196
|
if (titleEl) { titleEl.textContent = title; }
|
|
1633
2197
|
}
|
|
1634
2198
|
}
|
|
1635
2199
|
if (viewText) {
|
|
1636
|
-
viewText.style.display = viewName === 'text' ? '
|
|
2200
|
+
viewText.style.display = viewName === 'text' ? 'flex' : 'none';
|
|
2201
|
+
viewText.style.flexDirection = 'column';
|
|
1637
2202
|
if (viewName === 'text') {
|
|
1638
2203
|
this.initNotesExplorer(title);
|
|
1639
2204
|
}
|
|
@@ -1668,7 +2233,7 @@ export class SpaceGibShellService {
|
|
|
1668
2233
|
this.setMode('spaces');
|
|
1669
2234
|
}
|
|
1670
2235
|
|
|
1671
|
-
private switchToReposMode(opts?: { skipNavigate?: boolean }): void {
|
|
2236
|
+
private switchToReposMode(opts?: { skipNavigate?: boolean; galaxyId?: string }): void {
|
|
1672
2237
|
this.setMode('repos');
|
|
1673
2238
|
this.expandRightPanel();
|
|
1674
2239
|
if (!opts?.skipNavigate && !this.isApplyingRoute) {
|
|
@@ -1676,9 +2241,11 @@ export class SpaceGibShellService {
|
|
|
1676
2241
|
if (activeCosmos) {
|
|
1677
2242
|
const tenant = this.getActiveTenant(activeCosmos);
|
|
1678
2243
|
getSpaceGibRouterSvc().navigate({
|
|
1679
|
-
kind: '
|
|
2244
|
+
kind: 'galaxy',
|
|
1680
2245
|
cosmos: activeCosmos.id || activeCosmos.name,
|
|
1681
|
-
|
|
2246
|
+
galaxy: opts?.galaxyId || 'code-1',
|
|
2247
|
+
topology: 'branching',
|
|
2248
|
+
discriminator: 'code',
|
|
1682
2249
|
branch: 'main',
|
|
1683
2250
|
...(tenant ? { tenant } : {}),
|
|
1684
2251
|
});
|
|
@@ -1694,10 +2261,12 @@ export class SpaceGibShellService {
|
|
|
1694
2261
|
if (activeCosmos) {
|
|
1695
2262
|
const tenant = this.getActiveTenant(activeCosmos);
|
|
1696
2263
|
getSpaceGibRouterSvc().navigate({
|
|
1697
|
-
kind: '
|
|
2264
|
+
kind: 'galaxy',
|
|
1698
2265
|
cosmos: activeCosmos.id || activeCosmos.name,
|
|
1699
|
-
|
|
1700
|
-
|
|
2266
|
+
galaxy: opts?.galaxyId || 'notes-1',
|
|
2267
|
+
topology: 'linear',
|
|
2268
|
+
discriminator: 'notes',
|
|
2269
|
+
...(title ? { topicTjp: title, trail: [title], trailMode: 'tjp' } : {}),
|
|
1701
2270
|
...(tenant ? { tenant } : {}),
|
|
1702
2271
|
});
|
|
1703
2272
|
}
|
|
@@ -1745,12 +2314,17 @@ export class SpaceGibShellService {
|
|
|
1745
2314
|
try {
|
|
1746
2315
|
if (route.kind !== 'polycosmos') {
|
|
1747
2316
|
this.hasBigBangExploded = true;
|
|
2317
|
+
if (this.cosmosNavigatorInstance) {
|
|
2318
|
+
this.cosmosNavigatorInstance.hasBigBangExploded = true;
|
|
2319
|
+
}
|
|
1748
2320
|
this.revealChrome();
|
|
1749
2321
|
}
|
|
1750
2322
|
|
|
1751
2323
|
// If the route omitted a tenant specifier but the user is authenticated (or in playground),
|
|
1752
2324
|
// canonicalize the URL in the address bar so copying and sharing is always fully qualified.
|
|
1753
|
-
|
|
2325
|
+
// Exception: For bare landing ('polycosmos'), do not attach tenant or redirect to /@playground/polycosmos
|
|
2326
|
+
// so the URL remains bare (e.g. https://local.ibgib.space) to keep full focus on Big Bang.
|
|
2327
|
+
if (route.kind !== 'admin-review' && route.kind !== 'polycosmos' && !route.tenant) {
|
|
1754
2328
|
const cosmosName = 'cosmos' in route ? route.cosmos : undefined;
|
|
1755
2329
|
const activeTenant = this.getActiveTenant(cosmosName);
|
|
1756
2330
|
if (activeTenant) {
|
|
@@ -1767,7 +2341,11 @@ export class SpaceGibShellService {
|
|
|
1767
2341
|
}
|
|
1768
2342
|
case 'cosmos': {
|
|
1769
2343
|
if (this.cosmosNavigatorInstance) {
|
|
1770
|
-
const cosmos = await this.cosmosNavigatorInstance.
|
|
2344
|
+
const cosmos = await this.cosmosNavigatorInstance.findCosmos(route.cosmos);
|
|
2345
|
+
if (!cosmos) {
|
|
2346
|
+
this.show404(`Cosmos "${route.cosmos}" not found.`);
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
1771
2349
|
this.cosmosNavigatorInstance.selectCosmos(cosmos.id);
|
|
1772
2350
|
this.updateActiveCosmosDisplay(cosmos);
|
|
1773
2351
|
}
|
|
@@ -1776,60 +2354,46 @@ export class SpaceGibShellService {
|
|
|
1776
2354
|
await this.showCosmos();
|
|
1777
2355
|
break;
|
|
1778
2356
|
}
|
|
1779
|
-
case '
|
|
2357
|
+
case 'galaxy': {
|
|
2358
|
+
let cosmosInfo: CosmosInfo | undefined;
|
|
1780
2359
|
if (this.cosmosNavigatorInstance) {
|
|
1781
|
-
|
|
1782
|
-
if (!
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
type: 'code',
|
|
1786
|
-
name: 'Code Space 1',
|
|
1787
|
-
shortLabel: 'Code 1',
|
|
1788
|
-
icon: '</>',
|
|
1789
|
-
});
|
|
2360
|
+
cosmosInfo = await this.cosmosNavigatorInstance.findCosmos(route.cosmos);
|
|
2361
|
+
if (!cosmosInfo) {
|
|
2362
|
+
this.show404(`Cosmos "${route.cosmos}" not found.`);
|
|
2363
|
+
return;
|
|
1790
2364
|
}
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
if (route.branch && this.fileExplorerInstance) {
|
|
1800
|
-
this.fileExplorerInstance.setBranch(route.branch);
|
|
1801
|
-
}
|
|
1802
|
-
if (route.filePath && this.fileExplorerInstance) {
|
|
1803
|
-
this.fileExplorerInstance.selectFile(route.filePath);
|
|
1804
|
-
}
|
|
1805
|
-
await this.showCode(route.filePath, route.branch);
|
|
1806
|
-
break;
|
|
1807
|
-
}
|
|
1808
|
-
case 'notes-galaxy': {
|
|
1809
|
-
if (this.cosmosNavigatorInstance) {
|
|
1810
|
-
const cosmos = await this.cosmosNavigatorInstance.ensureCosmos(route.cosmos);
|
|
1811
|
-
if (!cosmos.spaces.some(s => s.type === 'text' || s.id === route.galaxyId)) {
|
|
1812
|
-
cosmos.spaces.push({
|
|
1813
|
-
id: route.galaxyId || 'notes-1',
|
|
1814
|
-
type: 'text',
|
|
1815
|
-
name: 'Text Space 1',
|
|
1816
|
-
shortLabel: 'Text 1',
|
|
1817
|
-
icon: '📝',
|
|
2365
|
+
const spaceType = route.topology === 'branching' ? 'code' : 'text';
|
|
2366
|
+
if (!cosmosInfo.spaces.some(s => s.id === route.galaxy)) {
|
|
2367
|
+
cosmosInfo.spaces.push({
|
|
2368
|
+
id: route.galaxy,
|
|
2369
|
+
type: spaceType,
|
|
2370
|
+
name: route.galaxy,
|
|
2371
|
+
shortLabel: route.galaxy,
|
|
2372
|
+
icon: route.topology === 'branching' ? '</>' : '📝',
|
|
1818
2373
|
});
|
|
1819
2374
|
}
|
|
1820
|
-
this.cosmosNavigatorInstance.selectCosmos(
|
|
1821
|
-
this.updateActiveCosmosDisplay(
|
|
2375
|
+
this.cosmosNavigatorInstance.selectCosmos(cosmosInfo.id);
|
|
2376
|
+
this.updateActiveCosmosDisplay(cosmosInfo, route.galaxy || spaceType);
|
|
1822
2377
|
}
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
2378
|
+
|
|
2379
|
+
const policy: GalaxyPolicy = {
|
|
2380
|
+
topology: route.topology,
|
|
2381
|
+
role: route.topology === 'branching' ? 'intrinsic' : 'extrinsic',
|
|
2382
|
+
storageMode: 'text',
|
|
2383
|
+
defaultBranch: 'main',
|
|
2384
|
+
};
|
|
2385
|
+
|
|
2386
|
+
const context: PanelLoadContext = {
|
|
2387
|
+
route,
|
|
2388
|
+
cosmosName: route.cosmos,
|
|
2389
|
+
galaxyName: route.galaxy,
|
|
2390
|
+
discriminator: route.discriminator,
|
|
2391
|
+
policy,
|
|
2392
|
+
cosmosInfo,
|
|
2393
|
+
shell: this,
|
|
2394
|
+
};
|
|
2395
|
+
|
|
2396
|
+
await this.loadRouteForPanels(route, context);
|
|
1833
2397
|
break;
|
|
1834
2398
|
}
|
|
1835
2399
|
case 'raw-addr': {
|
|
@@ -1858,7 +2422,11 @@ export class SpaceGibShellService {
|
|
|
1858
2422
|
try {
|
|
1859
2423
|
console.log(`${lc} Resolving raw snapshot route: cosmos=${route.cosmos}, spaceId=${route.spaceId}, addr=${route.ibGibAddr}`);
|
|
1860
2424
|
if (this.cosmosNavigatorInstance) {
|
|
1861
|
-
const cosmos = await this.cosmosNavigatorInstance.
|
|
2425
|
+
const cosmos = await this.cosmosNavigatorInstance.findCosmos(route.cosmos);
|
|
2426
|
+
if (!cosmos) {
|
|
2427
|
+
this.show404(`Cosmos "${route.cosmos}" not found.`);
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
1862
2430
|
this.cosmosNavigatorInstance.selectCosmos(cosmos.id);
|
|
1863
2431
|
this.updateActiveCosmosDisplay(cosmos);
|
|
1864
2432
|
}
|
|
@@ -1899,7 +2467,11 @@ export class SpaceGibShellService {
|
|
|
1899
2467
|
try {
|
|
1900
2468
|
console.log(`${lc} Resolving living tip route: cosmos=${route.cosmos}, spaceId=${route.spaceId}, tjp=${route.tjpAddr}`);
|
|
1901
2469
|
if (this.cosmosNavigatorInstance) {
|
|
1902
|
-
const cosmos = await this.cosmosNavigatorInstance.
|
|
2470
|
+
const cosmos = await this.cosmosNavigatorInstance.findCosmos(route.cosmos);
|
|
2471
|
+
if (!cosmos) {
|
|
2472
|
+
this.show404(`Cosmos "${route.cosmos}" not found.`);
|
|
2473
|
+
return;
|
|
2474
|
+
}
|
|
1903
2475
|
this.cosmosNavigatorInstance.selectCosmos(cosmos.id);
|
|
1904
2476
|
this.updateActiveCosmosDisplay(cosmos);
|
|
1905
2477
|
}
|