total-recall-brain 3.41.2 → 3.41.3
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/bin/total-recall.mjs +9 -3
- package/frontend/dist/assets/{index-BG9NkVUy.css → index-BIQmqDKP.css} +1 -1
- package/frontend/dist/assets/{index-BtuiZqwP.js → index-DFenQQEQ.js} +74 -79
- package/frontend/dist/index.html +2 -2
- package/frontend/dist/sw.js +8 -5
- package/frontend/src/api/auth.ts +0 -3
- package/frontend/src/components/plugins/PluginPanel.tsx +7 -3
- package/frontend/src/components/plugins/card/CardEngine.tsx +1 -1
- package/frontend/src/pages/LoginPage.tsx +1 -41
- package/frontend/src/pages/PluginsPage.tsx +14 -7
- package/package.json +2 -2
- package/scaffold/.agent/skills/plugin/scripts/record.mjs +6 -3
- package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +197 -31
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +8 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +56 -8
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +1068 -204
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/panel.js +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/card.js +436 -274
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +16 -2
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +461 -242
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +1 -7
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/DESIGN.md +17 -2
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +426 -300
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +350 -283
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +31 -19
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +16 -2
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +380 -298
- package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/src/scanner.mjs +17 -3
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +38 -15
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +60 -34
- package/src/cli/command.mjs +23 -18
- package/src/cli/daemon.mjs +23 -1
- package/src/cli/plugin/copies.mjs +8 -5
- package/src/cli/plugin/index.mjs +25 -2
- package/src/cli/rebuild.mjs +22 -0
- package/src/cli/reset-password.mjs +3 -2
- package/src/cli/skill.mjs +8 -2
- package/src/cli/status.mjs +25 -7
- package/src/core/automatic-brain-updates.mjs +9 -3
- package/src/core/brain-updates.mjs +63 -5
- package/src/core/global-brain-updates.mjs +21 -1
- package/src/core/mesh-brain-updates.mjs +5 -2
- package/src/core/meta-harness.mjs +16 -41
- package/src/core/plugin-runner.mjs +6 -1
- package/src/core/plugin-store.mjs +67 -1
- package/src/core/plugin-updates.mjs +1 -1
- package/src/core/portable-skills-maintenance.mjs +19 -0
- package/src/core/required-plugins.mjs +7 -0
- package/src/core/skills-registry.mjs +33 -3
- package/src/server/auth.mjs +41 -1
- package/src/server/memory-app.mjs +2 -1
- package/src/server/routes/auth.mjs +25 -1
- package/src/server/routes/plugins.mjs +17 -4
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Bespoke Web Component Card Face: Knowledge Amber & Ink Theme.
|
|
2
|
+
* Brain Dump — Multi-Repo Knowledge Graph & Documentation Console
|
|
4
3
|
*
|
|
5
|
-
*
|
|
4
|
+
* Bespoke operator interface for cross-repository documentation and knowledge graphs.
|
|
5
|
+
* Displays real-time hub trees, file metrics, structured ingestion controllers,
|
|
6
|
+
* and bootstrap verification without template wrappers or terminal dumps.
|
|
6
7
|
*/
|
|
7
8
|
|
|
9
|
+
const DASH = '\u2014';
|
|
10
|
+
|
|
11
|
+
function escapeHtml(str) {
|
|
12
|
+
if (str === null || str === undefined) return '';
|
|
13
|
+
return String(str).replace(/[&<>"']/g, c => ({
|
|
14
|
+
'&': '&',
|
|
15
|
+
'<': '<',
|
|
16
|
+
'>': '>',
|
|
17
|
+
'"': '"',
|
|
18
|
+
"'": '''
|
|
19
|
+
}[c]));
|
|
20
|
+
}
|
|
21
|
+
|
|
8
22
|
export class OpenWikiCard extends HTMLElement {
|
|
9
23
|
constructor() {
|
|
10
24
|
super();
|
|
11
|
-
this.
|
|
25
|
+
this.hubs = [];
|
|
26
|
+
this.totalLines = 0;
|
|
12
27
|
this.executing = false;
|
|
13
28
|
this.targetPath = 'openwiki';
|
|
14
|
-
this.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{ title: 'Secrets & API keys', path: 'openwiki/secrets.md', lines: 8, size_bytes: 286 },
|
|
19
|
-
{ title: 'Software Factory', path: 'openwiki/software-factory.md', lines: 36, size_bytes: 1833 }
|
|
20
|
-
];
|
|
29
|
+
this.dryRun = true;
|
|
30
|
+
this.lastResult = null;
|
|
31
|
+
this.screens = [{ id: 'knowledge', label: 'Knowledge Hubs' }];
|
|
32
|
+
this.screen = 'knowledge';
|
|
21
33
|
}
|
|
22
34
|
|
|
23
35
|
connectedCallback() {
|
|
@@ -25,428 +37,498 @@ export class OpenWikiCard extends HTMLElement {
|
|
|
25
37
|
this.attachShadow({ mode: 'open' });
|
|
26
38
|
}
|
|
27
39
|
this.render();
|
|
28
|
-
this.
|
|
40
|
+
this.refreshHubs();
|
|
29
41
|
}
|
|
30
42
|
|
|
31
|
-
async
|
|
43
|
+
async refreshHubs() {
|
|
44
|
+
if (!this.host) return;
|
|
32
45
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
46
|
+
const res = await this.host.run('status', ['--json']);
|
|
47
|
+
let parsed = [];
|
|
48
|
+
if (res && typeof res === 'object') {
|
|
49
|
+
if (Array.isArray(res.hubs)) {
|
|
50
|
+
parsed = res.hubs;
|
|
51
|
+
this.totalLines = res.total_lines || 0;
|
|
52
|
+
} else if (Array.isArray(res)) {
|
|
53
|
+
parsed = res;
|
|
54
|
+
}
|
|
55
|
+
} else if (typeof res === 'string' && res.trim().startsWith('{')) {
|
|
56
|
+
const json = JSON.parse(res);
|
|
57
|
+
parsed = Array.isArray(json.hubs) ? json.hubs : [];
|
|
58
|
+
this.totalLines = json.total_lines || 0;
|
|
39
59
|
}
|
|
60
|
+
|
|
61
|
+
this.hubs = parsed;
|
|
62
|
+
this.render();
|
|
40
63
|
} catch {
|
|
41
|
-
|
|
64
|
+
this.hubs = [];
|
|
65
|
+
this.render();
|
|
42
66
|
}
|
|
43
67
|
}
|
|
44
68
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (!container) return;
|
|
51
|
-
container.innerHTML = this.hubs.slice(0, 4).map((h) => `
|
|
52
|
-
<div class="hub-item">
|
|
53
|
-
<span class="hub-title">${h.title}</span>
|
|
54
|
-
<span class="hub-meta">${h.lines} lines · ${Math.round(h.size_bytes / 1024 * 10) / 10}KB</span>
|
|
55
|
-
</div>
|
|
56
|
-
`).join('') + (this.hubs.length > 4 ? `<div class="hub-more">+${this.hubs.length - 4} more indexed hubs</div>` : '');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async execute(action, customArgs = []) {
|
|
60
|
-
const out = this.shadowRoot.querySelector('#card-out');
|
|
61
|
-
const badge = this.shadowRoot.querySelector('#status-badge');
|
|
62
|
-
const pathInput = this.shadowRoot.querySelector('#path-input');
|
|
63
|
-
const target = pathInput ? pathInput.value.trim() : this.targetPath;
|
|
69
|
+
async runIngest() {
|
|
70
|
+
if (!this.host || this.executing) return;
|
|
71
|
+
this.executing = true;
|
|
72
|
+
this.lastResult = null;
|
|
73
|
+
this.render();
|
|
64
74
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
75
|
+
try {
|
|
76
|
+
const args = [this.targetPath || 'openwiki'];
|
|
77
|
+
if (this.dryRun) args.push('--dry-run');
|
|
78
|
+
args.push('--json');
|
|
79
|
+
|
|
80
|
+
const res = await this.host.run('ingest', args);
|
|
81
|
+
this.lastResult = {
|
|
82
|
+
ok: true,
|
|
83
|
+
message: this.dryRun ? 'Dry-run preview completed' : 'Ingestion completed successfully',
|
|
84
|
+
data: res
|
|
85
|
+
};
|
|
86
|
+
await this.refreshHubs();
|
|
87
|
+
} catch (err) {
|
|
88
|
+
this.lastResult = {
|
|
89
|
+
ok: false,
|
|
90
|
+
message: err instanceof Error ? err.message : 'Ingestion failed'
|
|
91
|
+
};
|
|
92
|
+
} finally {
|
|
93
|
+
this.executing = false;
|
|
94
|
+
this.render();
|
|
68
95
|
}
|
|
96
|
+
}
|
|
69
97
|
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
badge.textContent = 'BUSY';
|
|
73
|
-
badge.className = 'badge busy';
|
|
74
|
-
}
|
|
98
|
+
async runBootstrap() {
|
|
99
|
+
if (!this.host || this.executing) return;
|
|
75
100
|
this.executing = true;
|
|
101
|
+
this.lastResult = null;
|
|
102
|
+
this.render();
|
|
76
103
|
|
|
77
104
|
try {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
if (action === 'status') {
|
|
88
|
-
resultText = 'OpenWiki: implemented subcommands: probe, hubs, ingest';
|
|
89
|
-
} else if (action === 'hubs') {
|
|
90
|
-
resultText = `Discovered ${this.hubs.length} OpenWiki Hub(s):\n` + this.hubs.map((h) => ` - ${h.title}: ${h.path} (${h.lines} lines)`).join('\n');
|
|
91
|
-
} else if (action === 'probe') {
|
|
92
|
-
resultText = 'Health probe: HTTP 200 (14ms) from http://127.0.0.1:3000';
|
|
93
|
-
} else if (action === 'ingest') {
|
|
94
|
-
resultText = `OpenWiki Ingest: Processed ${args[0] || 'openwiki'} into knowledge graph. Ingest completed successfully.`;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (out) out.textContent = resultText.trim();
|
|
99
|
-
if (badge) {
|
|
100
|
-
badge.textContent = 'READY';
|
|
101
|
-
badge.className = 'badge ready';
|
|
102
|
-
}
|
|
105
|
+
const res = await this.host.run('bootstrap', ['--json']);
|
|
106
|
+
this.lastResult = {
|
|
107
|
+
ok: true,
|
|
108
|
+
message: 'OpenWiki skeleton bootstrapped',
|
|
109
|
+
data: res
|
|
110
|
+
};
|
|
111
|
+
await this.refreshHubs();
|
|
103
112
|
} catch (err) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
113
|
+
this.lastResult = {
|
|
114
|
+
ok: false,
|
|
115
|
+
message: err instanceof Error ? err.message : 'Bootstrap failed'
|
|
116
|
+
};
|
|
109
117
|
} finally {
|
|
110
118
|
this.executing = false;
|
|
119
|
+
this.render();
|
|
111
120
|
}
|
|
112
121
|
}
|
|
113
122
|
|
|
114
123
|
render() {
|
|
115
|
-
this.shadowRoot
|
|
124
|
+
const root = this.shadowRoot;
|
|
125
|
+
if (!root) return;
|
|
126
|
+
|
|
127
|
+
root.innerHTML = `
|
|
116
128
|
<style>
|
|
117
129
|
:host {
|
|
130
|
+
--face-bg: #0f172a;
|
|
131
|
+
--face-surface: #1e293b;
|
|
132
|
+
--face-line: #334155;
|
|
133
|
+
--face-text: #f8fafc;
|
|
134
|
+
--face-muted: #94a3b8;
|
|
135
|
+
--face-brand: #3b82f6;
|
|
136
|
+
--face-brand-hover: #60a5fa;
|
|
137
|
+
--face-accent: #facc15;
|
|
138
|
+
--face-ok: #10b981;
|
|
139
|
+
--face-warn: #f59e0b;
|
|
140
|
+
--face-danger: #ef4444;
|
|
141
|
+
--face-dark: #0f172a;
|
|
142
|
+
|
|
118
143
|
display: block;
|
|
119
|
-
font-family:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
border
|
|
123
|
-
border:
|
|
124
|
-
|
|
125
|
-
padding: 18px;
|
|
144
|
+
font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
|
|
145
|
+
color: var(--text-primary, var(--face-text));
|
|
146
|
+
background: var(--bg-secondary, var(--face-bg));
|
|
147
|
+
border: 1px solid var(--border, var(--face-line));
|
|
148
|
+
border-radius: 8px;
|
|
149
|
+
padding: 16px;
|
|
126
150
|
box-sizing: border-box;
|
|
127
151
|
overflow: hidden;
|
|
128
152
|
}
|
|
129
153
|
|
|
154
|
+
@media (prefers-reduced-motion: reduce) {
|
|
155
|
+
*, ::before, ::after {
|
|
156
|
+
animation-duration: 0.01ms !important;
|
|
157
|
+
animation-iteration-count: 1 !important;
|
|
158
|
+
transition-duration: 0.01ms !important;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Header Bar */
|
|
130
163
|
.header {
|
|
131
164
|
display: flex;
|
|
165
|
+
align-items: center;
|
|
132
166
|
justify-content: space-between;
|
|
133
|
-
|
|
134
|
-
|
|
167
|
+
flex-wrap: wrap;
|
|
168
|
+
gap: 12px;
|
|
169
|
+
padding-bottom: 14px;
|
|
170
|
+
border-bottom: 1px solid var(--border, var(--face-line));
|
|
171
|
+
margin-bottom: 16px;
|
|
135
172
|
}
|
|
136
173
|
|
|
137
|
-
.brand-
|
|
174
|
+
.brand-group {
|
|
138
175
|
display: flex;
|
|
139
176
|
align-items: center;
|
|
140
177
|
gap: 10px;
|
|
141
178
|
}
|
|
142
179
|
|
|
143
|
-
.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
180
|
+
.wordmark-badge {
|
|
181
|
+
font-family: var(--font-mono, 'JetBrains Mono', monospace);
|
|
182
|
+
font-size: 13px;
|
|
183
|
+
font-weight: 800;
|
|
184
|
+
letter-spacing: 0.05em;
|
|
185
|
+
color: var(--card-accent, var(--face-accent));
|
|
186
|
+
background: rgba(250, 204, 21, 0.12);
|
|
187
|
+
padding: 6px 10px;
|
|
188
|
+
border-radius: 6px;
|
|
189
|
+
border: 1px solid rgba(250, 204, 21, 0.3);
|
|
148
190
|
}
|
|
149
191
|
|
|
150
|
-
.title-
|
|
192
|
+
.title-meta {
|
|
151
193
|
display: flex;
|
|
152
194
|
flex-direction: column;
|
|
153
|
-
gap: 2px;
|
|
154
195
|
}
|
|
155
196
|
|
|
156
|
-
.title {
|
|
157
|
-
font-size:
|
|
197
|
+
.plugin-title {
|
|
198
|
+
font-size: 14px;
|
|
158
199
|
font-weight: 700;
|
|
159
|
-
|
|
160
|
-
text-transform: uppercase;
|
|
161
|
-
color: #fde68a;
|
|
200
|
+
color: var(--text-primary, var(--face-text));
|
|
162
201
|
margin: 0;
|
|
163
202
|
}
|
|
164
203
|
|
|
165
|
-
.subtitle {
|
|
204
|
+
.plugin-subtitle {
|
|
166
205
|
font-size: 11px;
|
|
167
|
-
color:
|
|
206
|
+
color: var(--text-secondary, var(--face-muted));
|
|
168
207
|
margin: 0;
|
|
169
208
|
}
|
|
170
209
|
|
|
171
|
-
.
|
|
172
|
-
display:
|
|
210
|
+
.hub-count-chip {
|
|
211
|
+
display: flex;
|
|
173
212
|
align-items: center;
|
|
174
|
-
|
|
213
|
+
gap: 6px;
|
|
214
|
+
font-family: var(--font-mono, 'JetBrains Mono', monospace);
|
|
215
|
+
font-size: 11px;
|
|
175
216
|
font-weight: 700;
|
|
176
|
-
|
|
217
|
+
color: var(--face-accent);
|
|
218
|
+
background: rgba(250, 204, 21, 0.12);
|
|
219
|
+
border: 1px solid rgba(250, 204, 21, 0.3);
|
|
220
|
+
padding: 5px 12px;
|
|
221
|
+
border-radius: 6px;
|
|
177
222
|
text-transform: uppercase;
|
|
178
|
-
border-radius: 4px;
|
|
179
|
-
padding: 4px 8px;
|
|
180
|
-
background: rgba(217, 119, 6, 0.15);
|
|
181
|
-
color: #fbbf24;
|
|
182
|
-
border: 1px solid rgba(217, 119, 6, 0.3);
|
|
183
223
|
}
|
|
184
224
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
225
|
+
/* Split Layout */
|
|
226
|
+
.workspace-split {
|
|
227
|
+
display: grid;
|
|
228
|
+
grid-template-columns: minmax(260px, 1.4fr) minmax(240px, 1fr);
|
|
229
|
+
gap: 14px;
|
|
230
|
+
margin-bottom: 16px;
|
|
189
231
|
}
|
|
190
232
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
233
|
+
@media (max-width: 700px) {
|
|
234
|
+
.workspace-split {
|
|
235
|
+
grid-template-columns: 1fr;
|
|
236
|
+
}
|
|
195
237
|
}
|
|
196
238
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
border-
|
|
239
|
+
/* Hub Tree Matrix */
|
|
240
|
+
.hub-panel {
|
|
241
|
+
border: 1px solid var(--border, var(--face-line));
|
|
242
|
+
border-radius: 6px;
|
|
243
|
+
background: rgba(30, 41, 59, 0.4);
|
|
244
|
+
padding: 12px;
|
|
245
|
+
display: flex;
|
|
246
|
+
flex-direction: column;
|
|
247
|
+
gap: 10px;
|
|
201
248
|
}
|
|
202
249
|
|
|
203
|
-
.
|
|
204
|
-
font-size:
|
|
205
|
-
text-transform: uppercase;
|
|
206
|
-
letter-spacing: 0.06em;
|
|
207
|
-
color: #f59e0b;
|
|
250
|
+
.panel-title {
|
|
251
|
+
font-size: 11px;
|
|
208
252
|
font-weight: 700;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
253
|
+
text-transform: uppercase;
|
|
254
|
+
letter-spacing: 0.05em;
|
|
255
|
+
color: var(--text-secondary, var(--face-muted));
|
|
256
|
+
margin: 0;
|
|
213
257
|
}
|
|
214
258
|
|
|
215
|
-
.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
259
|
+
.hub-list {
|
|
260
|
+
display: flex;
|
|
261
|
+
flex-direction: column;
|
|
262
|
+
gap: 6px;
|
|
263
|
+
max-height: 280px;
|
|
264
|
+
overflow-y: auto;
|
|
221
265
|
}
|
|
222
266
|
|
|
223
267
|
.hub-item {
|
|
268
|
+
padding: 10px 12px;
|
|
269
|
+
background: rgba(15, 23, 42, 0.6);
|
|
270
|
+
border: 1px solid var(--border, var(--face-line));
|
|
271
|
+
border-radius: 5px;
|
|
224
272
|
display: flex;
|
|
225
|
-
justify-content: space-between;
|
|
226
273
|
align-items: center;
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
font-size: 11px;
|
|
274
|
+
justify-content: space-between;
|
|
275
|
+
gap: 10px;
|
|
230
276
|
}
|
|
231
277
|
|
|
232
|
-
.hub-
|
|
233
|
-
|
|
278
|
+
.hub-main {
|
|
279
|
+
display: flex;
|
|
280
|
+
flex-direction: column;
|
|
281
|
+
gap: 2px;
|
|
234
282
|
}
|
|
235
283
|
|
|
236
284
|
.hub-title {
|
|
237
|
-
|
|
238
|
-
font-
|
|
285
|
+
font-family: var(--font-mono, 'JetBrains Mono', monospace);
|
|
286
|
+
font-size: 12px;
|
|
287
|
+
font-weight: 700;
|
|
288
|
+
color: var(--text-primary, var(--face-text));
|
|
239
289
|
}
|
|
240
290
|
|
|
241
|
-
.hub-
|
|
242
|
-
color: #d97706;
|
|
243
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
291
|
+
.hub-path {
|
|
244
292
|
font-size: 10px;
|
|
293
|
+
color: var(--text-secondary, var(--face-muted));
|
|
245
294
|
}
|
|
246
295
|
|
|
247
|
-
.hub-
|
|
296
|
+
.hub-metrics {
|
|
297
|
+
display: flex;
|
|
298
|
+
align-items: center;
|
|
299
|
+
gap: 6px;
|
|
300
|
+
font-family: var(--font-mono, 'JetBrains Mono', monospace);
|
|
248
301
|
font-size: 10px;
|
|
249
|
-
color:
|
|
250
|
-
text-align: center;
|
|
251
|
-
padding-top: 4px;
|
|
302
|
+
color: var(--face-accent);
|
|
252
303
|
}
|
|
253
304
|
|
|
254
|
-
|
|
305
|
+
/* Ingest Deck Column */
|
|
306
|
+
.ingest-deck {
|
|
255
307
|
display: flex;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
margin-bottom: 12px;
|
|
308
|
+
flex-direction: column;
|
|
309
|
+
gap: 10px;
|
|
259
310
|
}
|
|
260
311
|
|
|
261
|
-
.
|
|
262
|
-
|
|
263
|
-
background: #080602;
|
|
264
|
-
border: 1px solid rgba(217, 119, 6, 0.3);
|
|
312
|
+
.form-card {
|
|
313
|
+
border: 1px solid var(--border, var(--face-line));
|
|
265
314
|
border-radius: 6px;
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
box-sizing: border-box;
|
|
315
|
+
background: rgba(30, 41, 59, 0.4);
|
|
316
|
+
padding: 12px;
|
|
317
|
+
display: flex;
|
|
318
|
+
flex-direction: column;
|
|
319
|
+
gap: 10px;
|
|
272
320
|
}
|
|
273
321
|
|
|
274
|
-
.
|
|
275
|
-
|
|
276
|
-
|
|
322
|
+
.input-row {
|
|
323
|
+
display: flex;
|
|
324
|
+
flex-direction: column;
|
|
325
|
+
gap: 4px;
|
|
277
326
|
}
|
|
278
327
|
|
|
279
|
-
.
|
|
280
|
-
background: rgba(217, 119, 6, 0.1);
|
|
281
|
-
border: 1px solid rgba(217, 119, 6, 0.25);
|
|
282
|
-
color: #fde68a;
|
|
283
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
328
|
+
.input-label {
|
|
284
329
|
font-size: 10px;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
330
|
+
text-transform: uppercase;
|
|
331
|
+
color: var(--text-secondary, var(--face-muted));
|
|
332
|
+
letter-spacing: 0.05em;
|
|
288
333
|
}
|
|
289
334
|
|
|
290
|
-
.
|
|
291
|
-
|
|
335
|
+
.text-input {
|
|
336
|
+
min-height: 44px;
|
|
337
|
+
padding: 8px 12px;
|
|
338
|
+
font-family: var(--font-mono, 'JetBrains Mono', monospace);
|
|
339
|
+
font-size: 12px;
|
|
340
|
+
color: var(--text-primary, var(--face-text));
|
|
341
|
+
background: rgba(15, 23, 42, 0.8);
|
|
342
|
+
border: 1px solid var(--border, var(--face-line));
|
|
343
|
+
border-radius: 5px;
|
|
344
|
+
box-sizing: border-box;
|
|
345
|
+
width: 100%;
|
|
292
346
|
}
|
|
293
347
|
|
|
294
|
-
.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
gap: 6px;
|
|
298
|
-
margin-bottom: 12px;
|
|
348
|
+
.text-input:focus {
|
|
349
|
+
outline: none;
|
|
350
|
+
border-color: var(--card-accent, var(--face-brand));
|
|
299
351
|
}
|
|
300
352
|
|
|
301
|
-
.
|
|
302
|
-
|
|
303
|
-
min-width: 44px;
|
|
304
|
-
display: inline-flex;
|
|
353
|
+
.toggle-row {
|
|
354
|
+
display: flex;
|
|
305
355
|
align-items: center;
|
|
306
|
-
|
|
307
|
-
background: rgba(217, 119, 6, 0.1);
|
|
308
|
-
border: 1px solid rgba(217, 119, 6, 0.28);
|
|
309
|
-
color: #fde68a;
|
|
356
|
+
gap: 8px;
|
|
310
357
|
font-size: 11px;
|
|
311
|
-
|
|
312
|
-
letter-spacing: 0.03em;
|
|
313
|
-
text-transform: uppercase;
|
|
314
|
-
border-radius: 6px;
|
|
358
|
+
color: var(--text-secondary, var(--face-muted));
|
|
315
359
|
cursor: pointer;
|
|
316
|
-
transition: background 0.15s ease, border-color 0.15s ease;
|
|
317
|
-
padding: 6px;
|
|
318
|
-
text-align: center;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
.touch-btn:hover {
|
|
322
|
-
background: rgba(217, 119, 6, 0.22);
|
|
323
|
-
border-color: #f59e0b;
|
|
324
360
|
}
|
|
325
361
|
|
|
326
|
-
.
|
|
327
|
-
|
|
362
|
+
.toggle-check {
|
|
363
|
+
min-height: 20px;
|
|
364
|
+
min-width: 20px;
|
|
365
|
+
cursor: pointer;
|
|
328
366
|
}
|
|
329
367
|
|
|
330
|
-
.
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
368
|
+
.btn-action-primary {
|
|
369
|
+
min-height: 44px;
|
|
370
|
+
padding: 8px 16px;
|
|
371
|
+
font-family: var(--font-sans, sans-serif);
|
|
372
|
+
font-size: 12px;
|
|
334
373
|
font-weight: 700;
|
|
374
|
+
color: var(--face-dark);
|
|
375
|
+
background: var(--face-accent);
|
|
376
|
+
border: none;
|
|
377
|
+
border-radius: 5px;
|
|
378
|
+
cursor: pointer;
|
|
379
|
+
transition: background 0.15s ease;
|
|
335
380
|
}
|
|
336
381
|
|
|
337
|
-
.
|
|
338
|
-
background: #
|
|
382
|
+
.btn-action-primary:hover {
|
|
383
|
+
background: #fde047;
|
|
339
384
|
}
|
|
340
385
|
|
|
341
|
-
.
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
align-items: center;
|
|
345
|
-
margin-bottom: 4px;
|
|
386
|
+
.btn-action-primary:disabled {
|
|
387
|
+
opacity: 0.6;
|
|
388
|
+
cursor: not-allowed;
|
|
346
389
|
}
|
|
347
390
|
|
|
348
|
-
.
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
font-size:
|
|
391
|
+
.btn-action-secondary {
|
|
392
|
+
min-height: 44px;
|
|
393
|
+
padding: 8px 16px;
|
|
394
|
+
font-family: var(--font-sans, sans-serif);
|
|
395
|
+
font-size: 12px;
|
|
396
|
+
font-weight: 700;
|
|
397
|
+
color: var(--text-primary, var(--face-text));
|
|
398
|
+
background: transparent;
|
|
399
|
+
border: 1px solid var(--border, var(--face-line));
|
|
400
|
+
border-radius: 5px;
|
|
353
401
|
cursor: pointer;
|
|
354
|
-
|
|
355
|
-
text-decoration: underline;
|
|
402
|
+
transition: background 0.15s ease;
|
|
356
403
|
}
|
|
357
404
|
|
|
358
|
-
.
|
|
359
|
-
|
|
405
|
+
.btn-action-secondary:hover {
|
|
406
|
+
background: rgba(255, 255, 255, 0.05);
|
|
360
407
|
}
|
|
361
408
|
|
|
362
|
-
.
|
|
363
|
-
|
|
364
|
-
border:
|
|
365
|
-
|
|
366
|
-
padding: 8px 10px;
|
|
367
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
409
|
+
.feedback-banner {
|
|
410
|
+
padding: 8px 12px;
|
|
411
|
+
border-radius: 5px;
|
|
412
|
+
font-family: var(--font-mono, 'JetBrains Mono', monospace);
|
|
368
413
|
font-size: 11px;
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.feedback-ok {
|
|
417
|
+
background: rgba(16, 185, 129, 0.15);
|
|
418
|
+
border: 1px solid rgba(16, 185, 129, 0.4);
|
|
419
|
+
color: var(--face-ok);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.feedback-fail {
|
|
423
|
+
background: rgba(239, 68, 68, 0.15);
|
|
424
|
+
border: 1px solid rgba(239, 68, 68, 0.4);
|
|
425
|
+
color: var(--face-danger);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.empty-hubs {
|
|
429
|
+
padding: 32px 16px;
|
|
430
|
+
text-align: center;
|
|
431
|
+
font-size: 12px;
|
|
432
|
+
color: var(--text-secondary, var(--face-muted));
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* Footer Telemetry */
|
|
436
|
+
.footer-bar {
|
|
437
|
+
display: flex;
|
|
438
|
+
justify-content: space-between;
|
|
439
|
+
align-items: center;
|
|
440
|
+
padding-top: 12px;
|
|
441
|
+
margin-top: 14px;
|
|
442
|
+
border-top: 1px solid var(--border, var(--face-line));
|
|
443
|
+
font-size: 10px;
|
|
444
|
+
color: var(--text-secondary, var(--face-muted));
|
|
376
445
|
}
|
|
377
446
|
</style>
|
|
378
447
|
|
|
379
448
|
<div class="header">
|
|
380
|
-
<div class="brand-
|
|
381
|
-
<
|
|
382
|
-
|
|
383
|
-
<
|
|
384
|
-
<
|
|
385
|
-
</svg>
|
|
386
|
-
<div class="title-block">
|
|
387
|
-
<h2 class="title">OpenWiki Engine</h2>
|
|
388
|
-
<p class="subtitle">Multi-Repo Knowledge Graph & Docs</p>
|
|
449
|
+
<div class="brand-group">
|
|
450
|
+
<div class="wordmark-badge">[BRAIN//DUMP]</div>
|
|
451
|
+
<div class="title-meta">
|
|
452
|
+
<h3 class="plugin-title">OpenWiki Knowledge Graph</h3>
|
|
453
|
+
<p class="plugin-subtitle">Multi-repository documentation and knowledge ingestion engine</p>
|
|
389
454
|
</div>
|
|
390
455
|
</div>
|
|
391
|
-
<div
|
|
456
|
+
<div class="hub-count-chip">
|
|
457
|
+
${this.hubs.length > 0 ? `${this.hubs.length} Hubs Indexed` : 'No Hubs'}
|
|
458
|
+
</div>
|
|
392
459
|
</div>
|
|
393
460
|
|
|
394
|
-
<div class="
|
|
395
|
-
<
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
461
|
+
<div class="workspace-split">
|
|
462
|
+
<div class="hub-panel">
|
|
463
|
+
<h4 class="panel-title">Verified Documentation Hubs</h4>
|
|
464
|
+
<div class="hub-list">
|
|
465
|
+
${this.hubs.length > 0 ? this.hubs.map(h => `
|
|
466
|
+
<div class="hub-item">
|
|
467
|
+
<div class="hub-main">
|
|
468
|
+
<span class="hub-title">${escapeHtml(h.title || h.path)}</span>
|
|
469
|
+
<span class="hub-path">${escapeHtml(h.path)}</span>
|
|
470
|
+
</div>
|
|
471
|
+
<div class="hub-metrics">
|
|
472
|
+
<span>${h.lines !== undefined ? `${h.lines} lines` : DASH}</span>
|
|
473
|
+
</div>
|
|
474
|
+
</div>
|
|
475
|
+
`).join('') : `
|
|
476
|
+
<div class="empty-hubs">No markdown documentation hubs indexed yet. Click Bootstrap below to initialize.</div>
|
|
477
|
+
`}
|
|
478
|
+
</div>
|
|
407
479
|
</div>
|
|
408
|
-
</div>
|
|
409
480
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
481
|
+
<div class="ingest-deck">
|
|
482
|
+
<div class="form-card">
|
|
483
|
+
<h4 class="panel-title">Knowledge Ingest</h4>
|
|
484
|
+
<div class="input-row">
|
|
485
|
+
<span class="input-label">Target Hub Path</span>
|
|
486
|
+
<input class="text-input" type="text" id="input-path" placeholder="openwiki" />
|
|
487
|
+
</div>
|
|
488
|
+
<label class="toggle-row">
|
|
489
|
+
<input class="toggle-check" type="checkbox" id="check-dryrun" ${this.dryRun ? 'checked' : ''} />
|
|
490
|
+
<span>Dry Run (Preview changes without writing)</span>
|
|
491
|
+
</label>
|
|
492
|
+
<button class="btn-action-primary" type="button" id="btn-ingest" ${this.executing ? 'disabled' : ''}>
|
|
493
|
+
${this.executing ? 'Processing...' : 'Run Ingestion'}
|
|
494
|
+
</button>
|
|
495
|
+
<button class="btn-action-secondary" type="button" id="btn-bootstrap" ${this.executing ? 'disabled' : ''}>
|
|
496
|
+
Bootstrap OpenWiki Skeleton
|
|
497
|
+
</button>
|
|
498
|
+
</div>
|
|
416
499
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
500
|
+
${this.lastResult ? `
|
|
501
|
+
<div class="feedback-banner ${this.lastResult.ok ? 'feedback-ok' : 'feedback-fail'}">
|
|
502
|
+
${escapeHtml(this.lastResult.message)}
|
|
503
|
+
</div>
|
|
504
|
+
` : ''}
|
|
505
|
+
</div>
|
|
422
506
|
</div>
|
|
423
507
|
|
|
424
|
-
<div class="
|
|
425
|
-
<span
|
|
426
|
-
<
|
|
508
|
+
<div class="footer-bar">
|
|
509
|
+
<span>Engine: OpenWiki v0.1.2</span>
|
|
510
|
+
<span>Storage: Markdown + SSSS Projections</span>
|
|
427
511
|
</div>
|
|
428
|
-
<div id="card-out" class="output-box">Knowledge graph index operational. Ready for cross-repo documentation queries.</div>
|
|
429
512
|
`;
|
|
430
513
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
});
|
|
514
|
+
// Event listeners
|
|
515
|
+
const pathInput = root.querySelector('#input-path');
|
|
516
|
+
if (pathInput) {
|
|
517
|
+
pathInput.value = this.targetPath;
|
|
518
|
+
pathInput.addEventListener('input', e => {
|
|
519
|
+
this.targetPath = e.target.value;
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
const dryRunCheck = root.querySelector('#check-dryrun');
|
|
524
|
+
if (dryRunCheck) {
|
|
525
|
+
dryRunCheck.addEventListener('change', e => {
|
|
526
|
+
this.dryRun = e.target.checked;
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
root.querySelector('#btn-ingest')?.addEventListener('click', () => this.runIngest());
|
|
531
|
+
root.querySelector('#btn-bootstrap')?.addEventListener('click', () => this.runBootstrap());
|
|
450
532
|
}
|
|
451
533
|
}
|
|
452
534
|
|