@ibgib/space-gib 0.0.32 → 0.0.34

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 (112) hide show
  1. package/dist/client/bootstrap.mjs +24 -51
  2. package/dist/client/chunk-25PXC4HP.mjs +9914 -0
  3. package/dist/client/chunk-RXWLL2AI.mjs +30 -0
  4. package/dist/client/css/activity-bar.css +417 -0
  5. package/dist/client/css/base.css +167 -0
  6. package/dist/client/css/components.css +218 -0
  7. package/dist/client/css/cosmic.css +557 -0
  8. package/dist/client/css/dev-tools.css +163 -0
  9. package/dist/client/css/landing.css +184 -0
  10. package/dist/client/css/layout.css +896 -0
  11. package/dist/client/css/onboarding.css +181 -0
  12. package/dist/client/css/repos.css +740 -0
  13. package/dist/client/css/variables.css +64 -0
  14. package/dist/client/index.html +202 -31
  15. package/dist/client/index.mjs +31 -31
  16. package/dist/client/script.mjs +1 -1
  17. package/dist/client/style.css +11 -1056
  18. package/dist/respec-gib.node.mjs +5 -0
  19. package/dist/server/server.mjs +6879 -3109
  20. package/package.json +6 -6
  21. package/src/client/AUTO-GENERATED-version.mts +1 -1
  22. package/src/client/cosmos/seed-cosmos-workspace.mts +69 -0
  23. package/src/client/css/activity-bar.css +417 -0
  24. package/src/client/css/base.css +167 -0
  25. package/src/client/css/components.css +218 -0
  26. package/src/client/css/cosmic.css +557 -0
  27. package/src/client/css/dev-tools.css +163 -0
  28. package/src/client/css/landing.css +184 -0
  29. package/src/client/css/layout.css +896 -0
  30. package/src/client/css/onboarding.css +181 -0
  31. package/src/client/css/repos.css +740 -0
  32. package/src/client/css/variables.css +64 -0
  33. package/src/client/dev-tools/vcs-workspace.mts +3 -3
  34. package/src/client/index.html +202 -31
  35. package/src/client/style.css +11 -1056
  36. package/src/client/ui/component/chat-view/IMPLEMENTATION.md +48 -0
  37. package/src/client/ui/component/chat-view/chat-view.css +381 -0
  38. package/src/client/ui/component/chat-view/chat-view.html +104 -0
  39. package/src/client/ui/component/chat-view/chat-view.mts +277 -0
  40. package/src/client/ui/component/chat-view/index.mts +9 -0
  41. package/src/client/ui/component/clone/IMPLEMENTATION.md +68 -0
  42. package/src/client/ui/component/clone/clone-constants.mts +16 -0
  43. package/src/client/ui/component/clone/clone-types.mts +60 -0
  44. package/src/client/ui/component/clone/clone.css +383 -0
  45. package/src/client/ui/component/clone/clone.html +89 -0
  46. package/src/client/ui/component/clone/clone.mts +620 -0
  47. package/src/client/ui/component/clone/index.mts +11 -0
  48. package/src/client/ui/component/code-editor/IMPLEMENTATION.md +89 -0
  49. package/src/client/ui/component/code-editor/code-editor.css +275 -0
  50. package/src/client/ui/component/code-editor/code-editor.html +54 -0
  51. package/src/client/ui/component/code-editor/code-editor.mts +427 -0
  52. package/src/client/ui/component/code-editor/index.mts +9 -0
  53. package/src/client/ui/component/cosmos-navigator/IMPLEMENTATION.md +31 -0
  54. package/src/client/ui/component/cosmos-navigator/cosmos-navigator.css +864 -0
  55. package/src/client/ui/component/cosmos-navigator/cosmos-navigator.html +97 -0
  56. package/src/client/ui/component/cosmos-navigator/cosmos-navigator.mts +1084 -0
  57. package/src/client/ui/component/cosmos-navigator/index.mts +18 -0
  58. package/src/client/ui/component/file-explorer/IMPLEMENTATION.md +42 -0
  59. package/src/client/ui/component/file-explorer/file-explorer.css +256 -0
  60. package/src/client/ui/component/file-explorer/file-explorer.html +75 -0
  61. package/src/client/ui/component/file-explorer/file-explorer.mts +346 -0
  62. package/src/client/ui/component/file-explorer/index.mts +9 -0
  63. package/src/client/ui/component/nested-chat/IMPLEMENTATION.md +18 -0
  64. package/src/client/ui/component/nested-chat/chat/IMPLEMENTATION.md +14 -0
  65. package/src/client/ui/component/nested-chat/chat/chat-constants.mts +14 -0
  66. package/src/client/ui/component/nested-chat/chat/chat-helpers.mts +66 -0
  67. package/src/client/ui/component/nested-chat/chat/chat.css +654 -0
  68. package/src/client/ui/component/nested-chat/chat/chat.html +90 -0
  69. package/src/client/ui/component/nested-chat/chat/chat.mts +646 -0
  70. package/src/client/ui/component/nested-chat/chat/index.mts +7 -0
  71. package/src/client/ui/component/nested-chat/index.mts +14 -0
  72. package/src/client/ui/component/nested-chat/nested-chat-constants.mts +12 -0
  73. package/src/client/ui/component/nested-chat/nested-chat-types.mts +53 -0
  74. package/src/client/ui/component/nested-chat/nested-chat.css +142 -0
  75. package/src/client/ui/component/nested-chat/nested-chat.html +11 -0
  76. package/src/client/ui/component/nested-chat/nested-chat.mts +393 -0
  77. package/src/client/ui/component/notes-explorer/index.mts +9 -0
  78. package/src/client/ui/component/notes-explorer/notes-explorer.css +313 -0
  79. package/src/client/ui/component/notes-explorer/notes-explorer.html +136 -0
  80. package/src/client/ui/component/notes-explorer/notes-explorer.mts +240 -0
  81. package/src/client/ui/component/notes-inspector/index.mts +9 -0
  82. package/src/client/ui/component/notes-inspector/notes-inspector.css +244 -0
  83. package/src/client/ui/component/notes-inspector/notes-inspector.html +97 -0
  84. package/src/client/ui/component/notes-inspector/notes-inspector.mts +152 -0
  85. package/src/client/ui/component/pitch/IMPLEMENTATION.md +48 -0
  86. package/src/client/ui/component/pitch/index.mts +9 -0
  87. package/src/client/ui/component/pitch/pitch.css +295 -0
  88. package/src/client/ui/component/pitch/pitch.html +97 -0
  89. package/src/client/ui/component/pitch/pitch.mts +135 -0
  90. package/src/client/ui/component/timeline/IMPLEMENTATION.md +33 -0
  91. package/src/client/ui/component/timeline/index.mts +9 -0
  92. package/src/client/ui/component/timeline/timeline.css +264 -0
  93. package/src/client/ui/component/timeline/timeline.html +23 -0
  94. package/src/client/ui/component/timeline/timeline.mts +317 -0
  95. package/src/client/ui/component/timeline-item-details/IMPLEMENTATION.md +28 -0
  96. package/src/client/ui/component/timeline-item-details/index.mts +9 -0
  97. package/src/client/ui/component/timeline-item-details/timeline-item-details.css +286 -0
  98. package/src/client/ui/component/timeline-item-details/timeline-item-details.html +64 -0
  99. package/src/client/ui/component/timeline-item-details/timeline-item-details.mts +194 -0
  100. package/src/client/ui/router/index.mts +3 -0
  101. package/src/client/ui/router/space-gib-router-helpers.mts +272 -0
  102. package/src/client/ui/router/space-gib-router-helpers.respec.mts +353 -0
  103. package/src/client/ui/router/space-gib-router-service.mts +186 -0
  104. package/src/client/ui/router/space-gib-router-types.mts +93 -0
  105. package/src/client/ui/shell/cosmic-big-bang.mts +844 -0
  106. package/src/client/ui/shell/space-gib-shell-constants.mts +7 -0
  107. package/src/client/ui/shell/space-gib-shell-service.mts +1728 -31
  108. package/src/server/server.mts +20 -1
  109. package/tsconfig.test.json +5 -1
  110. package/dist/client/chunk-AX6BROMT.mjs +0 -1
  111. package/dist/client/chunk-CIQUGV7U.mjs +0 -25
  112. package/dist/client/chunk-YPCHYDKL.mjs +0 -3102
@@ -0,0 +1,286 @@
1
+ :host {
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 100%;
5
+ height: 100%;
6
+ box-sizing: border-box;
7
+ overflow: hidden;
8
+ }
9
+
10
+ .timeline-details-root {
11
+ display: flex;
12
+ flex-direction: column;
13
+ width: 100%;
14
+ height: 100%;
15
+ background: #0b0f19;
16
+ color: #f1f5f9;
17
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
18
+ box-sizing: border-box;
19
+ overflow: hidden;
20
+ }
21
+
22
+ /* Top Bar */
23
+ .details-top-bar {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 0.75rem;
27
+ padding: 0.5rem 1rem;
28
+ background: rgba(15, 23, 42, 0.95);
29
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
30
+ flex-shrink: 0;
31
+ }
32
+
33
+ .btn-back-editor {
34
+ display: inline-flex;
35
+ align-items: center;
36
+ gap: 0.4rem;
37
+ background: rgba(124, 92, 252, 0.15);
38
+ border: 1px solid rgba(124, 92, 252, 0.35);
39
+ color: #c4b5fd;
40
+ border-radius: 6px;
41
+ padding: 0.35rem 0.65rem;
42
+ font-size: 0.8rem;
43
+ font-weight: 600;
44
+ cursor: pointer;
45
+ transition: all 0.15s ease;
46
+ }
47
+
48
+ .btn-back-editor:hover {
49
+ background: rgba(124, 92, 252, 0.28);
50
+ border-color: #a78bfa;
51
+ color: #fff;
52
+ transform: translateX(-2px);
53
+ }
54
+
55
+ .breadcrumb-trail {
56
+ display: flex;
57
+ align-items: center;
58
+ gap: 0.4rem;
59
+ font-size: 0.82rem;
60
+ color: #94a3b8;
61
+ }
62
+
63
+ .trail-worktree {
64
+ font-family: ui-monospace, SFMono-Regular, monospace;
65
+ font-weight: 600;
66
+ color: #a78bfa;
67
+ background: rgba(124, 92, 252, 0.15);
68
+ padding: 1px 6px;
69
+ border-radius: 4px;
70
+ }
71
+
72
+ .trail-separator {
73
+ color: #475569;
74
+ }
75
+
76
+ .trail-hash {
77
+ font-family: ui-monospace, SFMono-Regular, monospace;
78
+ font-weight: 600;
79
+ color: #38bdf8;
80
+ background: rgba(56, 189, 248, 0.15);
81
+ padding: 1px 6px;
82
+ border-radius: 4px;
83
+ }
84
+
85
+ .top-bar-actions {
86
+ margin-left: auto;
87
+ display: flex;
88
+ gap: 0.5rem;
89
+ }
90
+
91
+ .top-action-btn {
92
+ background: rgba(255, 255, 255, 0.05);
93
+ border: 1px solid rgba(255, 255, 255, 0.1);
94
+ color: #cbd5e1;
95
+ font-size: 0.76rem;
96
+ padding: 0.3rem 0.6rem;
97
+ border-radius: 5px;
98
+ cursor: pointer;
99
+ transition: all 0.15s ease;
100
+ }
101
+
102
+ .top-action-btn:hover {
103
+ background: rgba(255, 255, 255, 0.1);
104
+ color: #fff;
105
+ }
106
+
107
+ /* Scrollable Body */
108
+ .details-body {
109
+ flex: 1;
110
+ overflow-y: auto;
111
+ padding: 1.25rem 1.5rem;
112
+ display: flex;
113
+ flex-direction: column;
114
+ gap: 1.25rem;
115
+ box-sizing: border-box;
116
+ }
117
+
118
+ /* Metadata Card */
119
+ .metadata-card {
120
+ background: rgba(15, 23, 42, 0.7);
121
+ border: 1px solid rgba(255, 255, 255, 0.08);
122
+ border-radius: 8px;
123
+ padding: 1.2rem;
124
+ display: flex;
125
+ flex-direction: column;
126
+ gap: 0.9rem;
127
+ }
128
+
129
+ .commit-message {
130
+ margin: 0;
131
+ font-size: 1.15rem;
132
+ font-weight: 600;
133
+ color: #f8fafc;
134
+ line-height: 1.35;
135
+ }
136
+
137
+ .meta-grid {
138
+ display: grid;
139
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
140
+ gap: 0.6rem 1.5rem;
141
+ }
142
+
143
+ .meta-field {
144
+ display: flex;
145
+ align-items: center;
146
+ gap: 0.5rem;
147
+ font-size: 0.82rem;
148
+ }
149
+
150
+ .field-label {
151
+ color: #64748b;
152
+ font-weight: 500;
153
+ min-width: 70px;
154
+ }
155
+
156
+ .field-value {
157
+ color: #cbd5e1;
158
+ }
159
+
160
+ .monospace-val {
161
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, monospace;
162
+ color: #38bdf8;
163
+ font-size: 0.8rem;
164
+ }
165
+
166
+ /* Changed Files */
167
+ .changed-files-section {
168
+ background: rgba(15, 23, 42, 0.7);
169
+ border: 1px solid rgba(255, 255, 255, 0.08);
170
+ border-radius: 8px;
171
+ padding: 1rem 1.2rem;
172
+ display: flex;
173
+ flex-direction: column;
174
+ gap: 0.75rem;
175
+ }
176
+
177
+ .section-header {
178
+ display: flex;
179
+ align-items: center;
180
+ gap: 0.5rem;
181
+ }
182
+
183
+ .section-title {
184
+ font-size: 0.92rem;
185
+ font-weight: 600;
186
+ color: #e2e8f0;
187
+ }
188
+
189
+ .badge-count {
190
+ font-size: 0.7rem;
191
+ background: rgba(255, 255, 255, 0.08);
192
+ color: #94a3b8;
193
+ padding: 1px 6px;
194
+ border-radius: 10px;
195
+ }
196
+
197
+ .files-list {
198
+ display: flex;
199
+ flex-direction: column;
200
+ gap: 0.4rem;
201
+ }
202
+
203
+ .file-row {
204
+ display: flex;
205
+ align-items: center;
206
+ gap: 0.6rem;
207
+ padding: 0.35rem 0.5rem;
208
+ border-radius: 5px;
209
+ background: rgba(255, 255, 255, 0.02);
210
+ font-size: 0.82rem;
211
+ font-family: ui-monospace, SFMono-Regular, monospace;
212
+ }
213
+
214
+ .file-row:hover {
215
+ background: rgba(255, 255, 255, 0.05);
216
+ }
217
+
218
+ .status-badge {
219
+ font-size: 0.68rem;
220
+ font-weight: 700;
221
+ padding: 1px 5px;
222
+ border-radius: 3px;
223
+ line-height: 1;
224
+ }
225
+
226
+ .status-M {
227
+ color: #fbbf24;
228
+ background: rgba(251, 191, 36, 0.15);
229
+ }
230
+
231
+ .status-A {
232
+ color: #34d399;
233
+ background: rgba(52, 211, 153, 0.15);
234
+ }
235
+
236
+ .status-D {
237
+ color: #f87171;
238
+ background: rgba(248, 113, 113, 0.15);
239
+ }
240
+
241
+ .file-path {
242
+ flex: 1;
243
+ color: #cbd5e1;
244
+ overflow: hidden;
245
+ text-overflow: ellipsis;
246
+ white-space: nowrap;
247
+ }
248
+
249
+ .file-stats {
250
+ font-size: 0.72rem;
251
+ display: flex;
252
+ gap: 0.4rem;
253
+ }
254
+
255
+ .stat-add {
256
+ color: #34d399;
257
+ }
258
+
259
+ .stat-del {
260
+ color: #f87171;
261
+ }
262
+
263
+ /* Diff Viewer */
264
+ .diff-viewer-section {
265
+ background: rgba(15, 23, 42, 0.7);
266
+ border: 1px solid rgba(255, 255, 255, 0.08);
267
+ border-radius: 8px;
268
+ padding: 1rem 1.2rem;
269
+ display: flex;
270
+ flex-direction: column;
271
+ gap: 0.75rem;
272
+ }
273
+
274
+ .diff-code-block {
275
+ margin: 0;
276
+ background: #050811;
277
+ border: 1px solid rgba(255, 255, 255, 0.06);
278
+ border-radius: 6px;
279
+ padding: 0.85rem 1rem;
280
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, monospace;
281
+ font-size: 0.8rem;
282
+ line-height: 1.5;
283
+ color: #cbd5e1;
284
+ overflow-x: auto;
285
+ white-space: pre-wrap;
286
+ }
@@ -0,0 +1,64 @@
1
+ <div id="timeline-details-root" class="timeline-details-root">
2
+ <!-- Details Top Bar -->
3
+ <div class="details-top-bar">
4
+ <button id="btn-back-to-editor" class="btn-back-editor" type="button">
5
+ <span class="back-icon">←</span>
6
+ <span class="back-text">Back to Editor</span>
7
+ </button>
8
+ <div class="breadcrumb-trail">
9
+ <span class="trail-worktree" id="details-branch-badge">main</span>
10
+ <span class="trail-separator">/</span>
11
+ <span class="trail-hash" id="details-top-hash">3e8f1c2</span>
12
+ </div>
13
+ <div class="top-bar-actions">
14
+ <button id="btn-copy-hash" class="top-action-btn" type="button" title="Copy Snapshot Hash">📋 Copy Hash</button>
15
+ </div>
16
+ </div>
17
+
18
+ <!-- Main Scrollable Body -->
19
+ <div class="details-body">
20
+ <!-- Metadata Card -->
21
+ <div class="metadata-card">
22
+ <div class="card-header">
23
+ <h2 id="details-message" class="commit-message">feat: implement cosmos navigation and orbital drift</h2>
24
+ </div>
25
+ <div class="meta-grid">
26
+ <div class="meta-field">
27
+ <span class="field-label">Snapshot:</span>
28
+ <span id="details-full-hash" class="field-value monospace-val">3e8f1c2a05d8f99e32b4f17c802e3b4a</span>
29
+ </div>
30
+ <div class="meta-field">
31
+ <span class="field-label">Author:</span>
32
+ <span id="details-author" class="field-value">Bill Raiford &lt;bill@ibgib.space&gt;</span>
33
+ </div>
34
+ <div class="meta-field">
35
+ <span class="field-label">Committed:</span>
36
+ <span id="details-timestamp" class="field-value">2 mins ago</span>
37
+ </div>
38
+ <div class="meta-field">
39
+ <span class="field-label">Parent:</span>
40
+ <span id="details-parent-hash" class="field-value monospace-val">a7b4d90</span>
41
+ </div>
42
+ </div>
43
+ </div>
44
+
45
+ <!-- Changed Files List -->
46
+ <div class="changed-files-section">
47
+ <div class="section-header">
48
+ <span class="section-title">Changed Files</span>
49
+ <span id="details-files-count" class="badge-count">3 files</span>
50
+ </div>
51
+ <div id="details-files-list" class="files-list">
52
+ <!-- Injected changed file items -->
53
+ </div>
54
+ </div>
55
+
56
+ <!-- Diff Viewer -->
57
+ <div class="diff-viewer-section">
58
+ <div class="section-header">
59
+ <span class="section-title">Changes Diff Preview</span>
60
+ </div>
61
+ <pre id="details-diff-preview" class="diff-code-block"><code><!-- Injected diff content --></code></pre>
62
+ </div>
63
+ </div>
64
+ </div>
@@ -0,0 +1,194 @@
1
+ import thisCss from "./timeline-item-details.css";
2
+ import thisHtml from "./timeline-item-details.html";
3
+
4
+ import { ROOT_ADDR } from "@ibgib/ts-gib/dist/V1/constants.mjs";
5
+ import { IbGibAddr } from "@ibgib/ts-gib/dist/types.mjs";
6
+ import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
7
+ import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
8
+ import {
9
+ IbGibDynamicComponentMetaBase, IbGibDynamicComponentInstanceBase,
10
+ } from "@ibgib/web-gib/dist/ui/component/ibgib-dynamic-component-bases.mjs";
11
+ import {
12
+ ElementsBase, IbGibDynamicComponentInstance,
13
+ } from "@ibgib/web-gib/dist/ui/component/component-types.mjs";
14
+ import { getComponentCtorArg } from "@ibgib/web-gib/dist/app-bootstrap/init-orchestration.mjs";
15
+ import { TimelineItem } from "../timeline/timeline.mjs";
16
+
17
+ export const TIMELINE_ITEM_DETAILS_COMPONENT_NAME = 'space-gib-timeline-item-details';
18
+
19
+ /**
20
+ * Metadata factory for space-gib-timeline-item-details Web Component.
21
+ */
22
+ export class TimelineItemDetailsComponentMeta extends IbGibDynamicComponentMetaBase {
23
+ protected lc: string = `[${TimelineItemDetailsComponentMeta.name}]`;
24
+
25
+ routeRegExp?: RegExp = new RegExp(`^${TIMELINE_ITEM_DETAILS_COMPONENT_NAME}$`);
26
+ componentName = TIMELINE_ITEM_DETAILS_COMPONENT_NAME;
27
+
28
+ constructor() {
29
+ super(getComponentCtorArg());
30
+ if (!customElements.get(this.componentName)) {
31
+ customElements.define(this.componentName, TimelineItemDetailsComponentInstance);
32
+ }
33
+ }
34
+
35
+ async createInstance({
36
+ path,
37
+ ibGibAddr
38
+ }: {
39
+ path: string;
40
+ ibGibAddr: IbGibAddr;
41
+ }): Promise<IbGibDynamicComponentInstance> {
42
+ const component = document.createElement(this.componentName) as TimelineItemDetailsComponentInstance;
43
+ await component.initialize({
44
+ ibGibAddr: ibGibAddr || ROOT_ADDR,
45
+ meta: this,
46
+ html: thisHtml,
47
+ css: [thisCss],
48
+ });
49
+ return component;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * References to DOM elements within the component's Shadow Root.
55
+ */
56
+ export interface TimelineItemDetailsElements extends ElementsBase {
57
+ rootEl: HTMLDivElement;
58
+ btnBackToEditorEl: HTMLButtonElement;
59
+ detailsBranchBadgeEl: HTMLSpanElement;
60
+ detailsTopHashEl: HTMLSpanElement;
61
+ btnCopyHashEl: HTMLButtonElement;
62
+ detailsMessageEl: HTMLHeadingElement;
63
+ detailsFullHashEl: HTMLSpanElement;
64
+ detailsAuthorEl: HTMLSpanElement;
65
+ detailsTimestampEl: HTMLSpanElement;
66
+ detailsParentHashEl: HTMLSpanElement;
67
+ detailsFilesCountEl: HTMLSpanElement;
68
+ detailsFilesListEl: HTMLDivElement;
69
+ detailsDiffPreviewEl: HTMLElement;
70
+ }
71
+
72
+ /**
73
+ * Concrete implementation of the Timeline Item Inspector Details component.
74
+ */
75
+ export class TimelineItemDetailsComponentInstance
76
+ extends IbGibDynamicComponentInstanceBase<IbGib_V1, TimelineItemDetailsElements>
77
+ implements IbGibDynamicComponentInstance<IbGib_V1, TimelineItemDetailsElements> {
78
+
79
+ protected lc: string = `[${TimelineItemDetailsComponentInstance.name}]`;
80
+
81
+ private currentItem?: TimelineItem;
82
+
83
+ get el(): TimelineItemDetailsElements {
84
+ if (!this.elements) {
85
+ throw new Error(`elements is not defined in ${this.lc}`);
86
+ }
87
+ return this.elements;
88
+ }
89
+
90
+ override async created(): Promise<void> {
91
+ const lc = `${this.lc}[${this.created.name}]`;
92
+ try {
93
+ const shadow = this.shadowRoot!;
94
+ this.elements = {
95
+ rootEl: shadow.getElementById('timeline-details-root') as HTMLDivElement,
96
+ btnBackToEditorEl: shadow.getElementById('btn-back-to-editor') as HTMLButtonElement,
97
+ detailsBranchBadgeEl: shadow.getElementById('details-branch-badge') as HTMLSpanElement,
98
+ detailsTopHashEl: shadow.getElementById('details-top-hash') as HTMLSpanElement,
99
+ btnCopyHashEl: shadow.getElementById('btn-copy-hash') as HTMLButtonElement,
100
+ detailsMessageEl: shadow.getElementById('details-message') as HTMLHeadingElement,
101
+ detailsFullHashEl: shadow.getElementById('details-full-hash') as HTMLSpanElement,
102
+ detailsAuthorEl: shadow.getElementById('details-author') as HTMLSpanElement,
103
+ detailsTimestampEl: shadow.getElementById('details-timestamp') as HTMLSpanElement,
104
+ detailsParentHashEl: shadow.getElementById('details-parent-hash') as HTMLSpanElement,
105
+ detailsFilesCountEl: shadow.getElementById('details-files-count') as HTMLSpanElement,
106
+ detailsFilesListEl: shadow.getElementById('details-files-list') as HTMLDivElement,
107
+ detailsDiffPreviewEl: shadow.getElementById('details-diff-preview') as HTMLElement,
108
+ contentEl: shadow.getElementById('timeline-details-root') as HTMLDivElement,
109
+ };
110
+
111
+ this.bindHandlers();
112
+ if (this.currentItem) {
113
+ this.renderItemDetails(this.currentItem);
114
+ }
115
+ } catch (error) {
116
+ console.error(`${lc} ${extractErrorMsg(error)}`);
117
+ }
118
+ }
119
+
120
+ private bindHandlers(): void {
121
+ this.el.btnBackToEditorEl.addEventListener('click', () => {
122
+ this.dispatchEvent(new CustomEvent('space-gib-timeline-details-closed', {
123
+ bubbles: true,
124
+ composed: true,
125
+ }));
126
+ });
127
+
128
+ this.el.btnCopyHashEl.addEventListener('click', async () => {
129
+ if (this.currentItem?.hash) {
130
+ try {
131
+ await navigator.clipboard.writeText(this.currentItem.hash);
132
+ this.el.btnCopyHashEl.textContent = '✓ Copied!';
133
+ setTimeout(() => {
134
+ this.el.btnCopyHashEl.textContent = '📋 Copy Hash';
135
+ }, 1800);
136
+ } catch {
137
+ // clipboard fallback
138
+ }
139
+ }
140
+ });
141
+ }
142
+
143
+ public setTimelineItem(item: TimelineItem): void {
144
+ this.currentItem = item;
145
+ if (this.elements) {
146
+ this.renderItemDetails(item);
147
+ }
148
+ }
149
+
150
+ private renderItemDetails(item: TimelineItem): void {
151
+ if (!this.elements) return;
152
+
153
+ this.el.detailsBranchBadgeEl.textContent = item.branch || 'main';
154
+ this.el.detailsTopHashEl.textContent = item.shortHash;
155
+ this.el.detailsMessageEl.textContent = item.message;
156
+ this.el.detailsFullHashEl.textContent = item.hash;
157
+ this.el.detailsAuthorEl.textContent = item.author;
158
+ this.el.detailsTimestampEl.textContent = item.timestamp;
159
+ this.el.detailsParentHashEl.textContent = item.parentHash || 'None (Initial)';
160
+
161
+ const files = item.changedFiles || [];
162
+ this.el.detailsFilesCountEl.textContent = `${files.length} file${files.length === 1 ? '' : 's'}`;
163
+
164
+ const filesListContainer = this.el.detailsFilesListEl;
165
+ filesListContainer.innerHTML = '';
166
+ for (const f of files) {
167
+ const row = document.createElement('div');
168
+ row.className = 'file-row';
169
+ row.innerHTML = `
170
+ <span class="status-badge status-${f.status}">${f.status}</span>
171
+ <span class="file-path">${f.path}</span>
172
+ <div class="file-stats">
173
+ <span class="stat-add">+${f.additions}</span>
174
+ <span class="stat-del">-${f.deletions}</span>
175
+ </div>
176
+ `;
177
+ filesListContainer.appendChild(row);
178
+ }
179
+
180
+ const diffEl = this.el.detailsDiffPreviewEl;
181
+ if (diffEl) {
182
+ diffEl.textContent = item.diffPreview || 'No diff available for this snapshot.';
183
+ }
184
+ }
185
+
186
+ override async disconnected(): Promise<void> {
187
+ const lc = `${this.lc}[${this.disconnected.name}]`;
188
+ try {
189
+ // cleanup if needed
190
+ } catch (error) {
191
+ console.error(`${lc} ${extractErrorMsg(error)}`);
192
+ }
193
+ }
194
+ }
@@ -0,0 +1,3 @@
1
+ export * from './space-gib-router-types.mjs';
2
+ export * from './space-gib-router-helpers.mjs';
3
+ export * from './space-gib-router-service.mjs';