total-recall-brain 3.41.2 → 3.41.4
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 +19 -4
- package/frontend/dist/assets/{index-BG9NkVUy.css → index-BIQmqDKP.css} +1 -1
- package/frontend/dist/assets/{index-BtuiZqwP.js → index-CRzjQLu7.js} +7 -7
- 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 +7 -5
- 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 +6 -6
- 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/src/cli-secret.mjs +48 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/login-projections.mjs +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/mesh-secrets.mjs +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/routes/secrets.mjs +5 -2
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-carriers.mjs +76 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-prune.mjs +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-sync.mjs +53 -17
- 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 +12 -12
- 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 +12 -12
- 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 +23 -8
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +6 -2
- 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 +23 -8
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +5 -1
- 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 +23 -10
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +5 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/grants.mjs +7 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +61 -38
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/leader-election.mjs +57 -2
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/mesh.mjs +220 -36
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/server/routes/mesh.mjs +7 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +65 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +534 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +139 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +2849 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +376 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adapters/dsh.mjs +446 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +398 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +152 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +82 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +90 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +415 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +36 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/tracker.mjs +133 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +233 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +845 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/BRICK.md +64 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/index.mjs +250 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +344 -14
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +2917 -140
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +223 -5
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/config.mjs +129 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +355 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +375 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +37 -10
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +986 -280
- package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +25 -10
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +6 -2
- 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/config.mjs +3 -0
- package/src/cli/connect.mjs +12 -116
- package/src/cli/daemon.mjs +23 -1
- package/src/cli/harness.mjs +0 -1
- package/src/cli/plugin/copies.mjs +8 -5
- package/src/cli/plugin/create.mjs +56 -3
- package/src/cli/plugin/index.mjs +40 -5
- package/src/cli/plugin/monetization.mjs +232 -12
- package/src/cli/preflight.mjs +161 -0
- 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/cli-commands.mjs +2 -0
- package/src/core/context-compiler.mjs +8 -1
- package/src/core/default-plugins.mjs +1 -1
- package/src/core/global-brain-updates.mjs +21 -1
- package/src/core/mesh-brain-updates.mjs +5 -2
- package/src/core/meta-harness.mjs +32 -79
- package/src/core/plugin-dependencies.mjs +6 -1
- 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/preflight-gate.mjs +77 -0
- package/src/core/preflight-receipt.mjs +123 -0
- package/src/core/required-plugins.mjs +7 -0
- package/src/core/runtime.mjs +0 -3
- package/src/core/skills-registry.mjs +33 -3
- package/src/core/surface.mjs +38 -1
- 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,452 +1,1158 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenWiki —
|
|
3
|
-
* Bespoke
|
|
2
|
+
* OpenWiki — Knowledge Graph & Multi-Repo Documentation Wiki
|
|
3
|
+
* Bespoke Card Face: Deep Slate & Knowledge Amber Interface.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Exposes live hub discovery, markdown file inspection, upstream release surveillance,
|
|
6
|
+
* and structured fleet propagation controls. Operates without mock data or boilerplate sinks.
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
export class OpenWikiCard extends HTMLElement {
|
|
10
|
+
static get screens() {
|
|
11
|
+
return [
|
|
12
|
+
{ id: 'hubs', label: 'Hubs' },
|
|
13
|
+
{ id: 'config', label: 'Configuration' },
|
|
14
|
+
{ id: 'refresh', label: 'Fleet Refresh' },
|
|
15
|
+
{ id: 'upstream', label: 'Upstream Watcher' }
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get screens() {
|
|
20
|
+
return OpenWikiCard.screens;
|
|
21
|
+
}
|
|
22
|
+
|
|
9
23
|
constructor() {
|
|
10
24
|
super();
|
|
11
|
-
this.
|
|
12
|
-
this.
|
|
25
|
+
this.activeScreen = 'hubs';
|
|
26
|
+
this.hubs = [];
|
|
27
|
+
this.loading = false;
|
|
28
|
+
this.statusText = 'READY';
|
|
13
29
|
this.targetPath = 'openwiki';
|
|
14
|
-
this.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
30
|
+
this.dryRun = false;
|
|
31
|
+
this.executionResult = null;
|
|
32
|
+
this.errorMessage = null;
|
|
33
|
+
this.lastRefreshedAt = null;
|
|
34
|
+
this.upstream = null;
|
|
35
|
+
this.config = {
|
|
36
|
+
provider: 'openrouter',
|
|
37
|
+
model: 'deepseek/deepseek-v4.1-flash',
|
|
38
|
+
fallback_model: 'qwen/qwen-2.5-coder-32b-instruct',
|
|
39
|
+
max_tokens: 4096,
|
|
40
|
+
timeout_ms: 300000
|
|
41
|
+
};
|
|
42
|
+
this.refreshReports = [];
|
|
43
|
+
this.refreshCounts = null;
|
|
44
|
+
this._boundOnScreenChange = this.handleExternalScreenChange.bind(this);
|
|
21
45
|
}
|
|
22
46
|
|
|
23
47
|
connectedCallback() {
|
|
24
48
|
if (!this.shadowRoot) {
|
|
25
49
|
this.attachShadow({ mode: 'open' });
|
|
26
50
|
}
|
|
51
|
+
this.addEventListener('tr:screen-change', this._boundOnScreenChange);
|
|
52
|
+
this.addEventListener('plugin-show-screen', this._boundOnScreenChange);
|
|
27
53
|
this.render();
|
|
28
|
-
this.
|
|
54
|
+
this.refreshHubs();
|
|
55
|
+
this.loadConfig();
|
|
29
56
|
}
|
|
30
57
|
|
|
31
|
-
|
|
58
|
+
disconnectedCallback() {
|
|
59
|
+
this.removeEventListener('tr:screen-change', this._boundOnScreenChange);
|
|
60
|
+
this.removeEventListener('plugin-show-screen', this._boundOnScreenChange);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
handleExternalScreenChange(event) {
|
|
64
|
+
const screenId = event.detail?.screen || event.detail?.screenId || event.detail?.id;
|
|
65
|
+
if (screenId && OpenWikiCard.screens.some((s) => s.id === screenId)) {
|
|
66
|
+
this.setScreen(screenId);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setScreen(id) {
|
|
71
|
+
if (this.activeScreen === id) return;
|
|
72
|
+
this.activeScreen = id;
|
|
73
|
+
this.errorMessage = null;
|
|
74
|
+
this.render();
|
|
75
|
+
if (typeof this.host?.screenChanged === 'function') {
|
|
76
|
+
try {
|
|
77
|
+
this.host.screenChanged({ screen: id });
|
|
78
|
+
} catch {
|
|
79
|
+
// Host screenChanged callback optional
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (id === 'refresh' && (!this.refreshReports || this.refreshReports.length === 0)) {
|
|
83
|
+
this.loadRefreshReport();
|
|
84
|
+
} else if (id === 'config') {
|
|
85
|
+
this.loadConfig();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async loadConfig() {
|
|
32
90
|
try {
|
|
33
|
-
if (this.host
|
|
91
|
+
if (this.host && typeof this.host.run === 'function') {
|
|
92
|
+
const res = await this.host.run('config', ['show', '--json']);
|
|
93
|
+
if (res?.config) {
|
|
94
|
+
this.config = res.config;
|
|
95
|
+
this.render();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} catch {
|
|
99
|
+
// Retain active config defaults if host call fails
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async setConfigValue(key, value) {
|
|
104
|
+
this.loading = true;
|
|
105
|
+
this.errorMessage = null;
|
|
106
|
+
this.render();
|
|
107
|
+
try {
|
|
108
|
+
if (this.host && typeof this.host.run === 'function') {
|
|
109
|
+
const res = await this.host.run('config', ['set', key, String(value), '--json']);
|
|
110
|
+
if (res?.config) {
|
|
111
|
+
this.config = res.config;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
} catch (err) {
|
|
115
|
+
this.errorMessage = err.message || `Failed to update ${key}`;
|
|
116
|
+
} finally {
|
|
117
|
+
this.loading = false;
|
|
118
|
+
this.render();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async resetConfig() {
|
|
123
|
+
this.loading = true;
|
|
124
|
+
this.errorMessage = null;
|
|
125
|
+
this.render();
|
|
126
|
+
try {
|
|
127
|
+
if (this.host && typeof this.host.run === 'function') {
|
|
128
|
+
const res = await this.host.run('config', ['reset', '--json']);
|
|
129
|
+
if (res?.config) {
|
|
130
|
+
this.config = res.config;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
} catch (err) {
|
|
134
|
+
this.errorMessage = err.message || 'Failed to reset configuration';
|
|
135
|
+
} finally {
|
|
136
|
+
this.loading = false;
|
|
137
|
+
this.render();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async refreshHubs() {
|
|
142
|
+
this.loading = true;
|
|
143
|
+
this.errorMessage = null;
|
|
144
|
+
this.render();
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
if (this.host && typeof this.host.run === 'function') {
|
|
34
148
|
const res = await this.host.run('hubs', ['--json']);
|
|
35
149
|
if (res && Array.isArray(res.hubs)) {
|
|
36
150
|
this.hubs = res.hubs;
|
|
37
|
-
this.
|
|
151
|
+
this.statusText = 'SYNCHRONIZED';
|
|
152
|
+
} else {
|
|
153
|
+
this.hubs = [];
|
|
154
|
+
this.statusText = 'UNINDEXED';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
const statusRes = await this.host.run('status', ['--json']);
|
|
159
|
+
if (statusRes?.upstream) {
|
|
160
|
+
this.upstream = statusRes.upstream;
|
|
161
|
+
}
|
|
162
|
+
} catch {
|
|
163
|
+
// Upstream metadata optional
|
|
38
164
|
}
|
|
165
|
+
} else {
|
|
166
|
+
this.statusText = 'DISCONNECTED';
|
|
39
167
|
}
|
|
40
|
-
|
|
41
|
-
|
|
168
|
+
this.lastRefreshedAt = new Date().toLocaleTimeString();
|
|
169
|
+
} catch (err) {
|
|
170
|
+
this.statusText = 'ERROR';
|
|
171
|
+
this.errorMessage = err.message || 'Hub synchronization failure';
|
|
172
|
+
this.hubs = [];
|
|
173
|
+
} finally {
|
|
174
|
+
this.loading = false;
|
|
175
|
+
this.render();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async loadRefreshReport() {
|
|
180
|
+
this.loading = true;
|
|
181
|
+
this.errorMessage = null;
|
|
182
|
+
this.render();
|
|
183
|
+
try {
|
|
184
|
+
if (this.host && typeof this.host.run === 'function') {
|
|
185
|
+
const res = await this.host.run('refresh', ['--json']);
|
|
186
|
+
if (res) {
|
|
187
|
+
this.refreshReports = Array.isArray(res.reports) ? res.reports : [];
|
|
188
|
+
this.refreshCounts = res.counts || null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} catch (err) {
|
|
192
|
+
this.errorMessage = err.message || 'Fleet status check failure';
|
|
193
|
+
} finally {
|
|
194
|
+
this.loading = false;
|
|
195
|
+
this.render();
|
|
42
196
|
}
|
|
43
197
|
}
|
|
44
198
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
199
|
+
async executeFleetRefresh() {
|
|
200
|
+
if (this.loading) return;
|
|
201
|
+
this.loading = true;
|
|
202
|
+
this.executionResult = null;
|
|
203
|
+
this.errorMessage = null;
|
|
204
|
+
this.render();
|
|
48
205
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
206
|
+
try {
|
|
207
|
+
if (this.host && typeof this.host.run === 'function') {
|
|
208
|
+
const res = await this.host.run('refresh', ['--apply', '--json']);
|
|
209
|
+
this.executionResult = {
|
|
210
|
+
action: 'fleet-refresh',
|
|
211
|
+
target: 'all-registered-projects',
|
|
212
|
+
details: res && typeof res === 'object' ? res : { message: String(res || 'Completed') },
|
|
213
|
+
timestamp: new Date().toLocaleTimeString()
|
|
214
|
+
};
|
|
215
|
+
if (res?.reports) {
|
|
216
|
+
this.refreshReports = res.reports;
|
|
217
|
+
this.refreshCounts = res.counts;
|
|
218
|
+
}
|
|
219
|
+
} else {
|
|
220
|
+
throw new Error('Host execution context unavailable');
|
|
221
|
+
}
|
|
222
|
+
} catch (err) {
|
|
223
|
+
this.errorMessage = err.message || 'Fleet refresh execution failure';
|
|
224
|
+
} finally {
|
|
225
|
+
this.loading = false;
|
|
226
|
+
this.render();
|
|
227
|
+
}
|
|
57
228
|
}
|
|
58
229
|
|
|
59
|
-
async
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
230
|
+
async executeIngest() {
|
|
231
|
+
if (this.loading) return;
|
|
232
|
+
this.loading = true;
|
|
233
|
+
this.executionResult = null;
|
|
234
|
+
this.errorMessage = null;
|
|
235
|
+
this.render();
|
|
64
236
|
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
237
|
+
const args = [this.targetPath || 'openwiki'];
|
|
238
|
+
if (this.dryRun) args.push('--dry-run');
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
if (this.host && typeof this.host.run === 'function') {
|
|
242
|
+
const res = await this.host.run('ingest', args);
|
|
243
|
+
this.executionResult = {
|
|
244
|
+
action: 'ingest',
|
|
245
|
+
target: this.targetPath,
|
|
246
|
+
dryRun: this.dryRun,
|
|
247
|
+
details: res && typeof res === 'object' ? res : { message: String(res || 'Completed') },
|
|
248
|
+
timestamp: new Date().toLocaleTimeString()
|
|
249
|
+
};
|
|
250
|
+
} else {
|
|
251
|
+
throw new Error('Host execution context unavailable');
|
|
252
|
+
}
|
|
253
|
+
} catch (err) {
|
|
254
|
+
this.errorMessage = err.message || 'Ingestion cycle failure';
|
|
255
|
+
} finally {
|
|
256
|
+
this.loading = false;
|
|
257
|
+
this.refreshHubs();
|
|
68
258
|
}
|
|
259
|
+
}
|
|
69
260
|
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
261
|
+
async executeBootstrap() {
|
|
262
|
+
if (this.loading) return;
|
|
263
|
+
this.loading = true;
|
|
264
|
+
this.executionResult = null;
|
|
265
|
+
this.errorMessage = null;
|
|
266
|
+
this.render();
|
|
267
|
+
|
|
268
|
+
try {
|
|
269
|
+
if (this.host && typeof this.host.run === 'function') {
|
|
270
|
+
const res = await this.host.run('bootstrap', ['--brain', '.', '--json']);
|
|
271
|
+
this.executionResult = {
|
|
272
|
+
action: 'bootstrap',
|
|
273
|
+
details: res && typeof res === 'object' ? res : { message: String(res || 'Completed') },
|
|
274
|
+
timestamp: new Date().toLocaleTimeString()
|
|
275
|
+
};
|
|
276
|
+
} else {
|
|
277
|
+
throw new Error('Host execution context unavailable');
|
|
278
|
+
}
|
|
279
|
+
} catch (err) {
|
|
280
|
+
this.errorMessage = err.message || 'Bootstrap procedure failure';
|
|
281
|
+
} finally {
|
|
282
|
+
this.loading = false;
|
|
283
|
+
this.refreshHubs();
|
|
74
284
|
}
|
|
75
|
-
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async executeWatch() {
|
|
288
|
+
if (this.loading) return;
|
|
289
|
+
this.loading = true;
|
|
290
|
+
this.executionResult = null;
|
|
291
|
+
this.errorMessage = null;
|
|
292
|
+
this.render();
|
|
76
293
|
|
|
77
294
|
try {
|
|
78
|
-
let resultText = '';
|
|
79
295
|
if (this.host && typeof this.host.run === 'function') {
|
|
80
|
-
const res = await this.host.run(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
296
|
+
const res = await this.host.run('watch', ['--json']);
|
|
297
|
+
this.executionResult = {
|
|
298
|
+
action: 'watch',
|
|
299
|
+
details: res && typeof res === 'object' ? res : { message: String(res || 'Completed') },
|
|
300
|
+
timestamp: new Date().toLocaleTimeString()
|
|
301
|
+
};
|
|
302
|
+
if (res?.status) {
|
|
303
|
+
this.upstream = {
|
|
304
|
+
recordedVersion: res.status.currentVersion,
|
|
305
|
+
latestVersion: res.status.latestVersion
|
|
306
|
+
};
|
|
85
307
|
}
|
|
86
308
|
} else {
|
|
87
|
-
|
|
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
|
-
}
|
|
309
|
+
throw new Error('Host execution context unavailable');
|
|
96
310
|
}
|
|
311
|
+
} catch (err) {
|
|
312
|
+
this.errorMessage = err.message || 'Upstream surveillance failure';
|
|
313
|
+
} finally {
|
|
314
|
+
this.loading = false;
|
|
315
|
+
this.refreshHubs();
|
|
316
|
+
}
|
|
317
|
+
}
|
|
97
318
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
319
|
+
async executePropagate() {
|
|
320
|
+
if (this.loading) return;
|
|
321
|
+
this.loading = true;
|
|
322
|
+
this.executionResult = null;
|
|
323
|
+
this.errorMessage = null;
|
|
324
|
+
this.render();
|
|
325
|
+
|
|
326
|
+
try {
|
|
327
|
+
if (this.host && typeof this.host.run === 'function') {
|
|
328
|
+
const res = await this.host.run('propagate', ['--json']);
|
|
329
|
+
this.executionResult = {
|
|
330
|
+
action: 'propagate',
|
|
331
|
+
details: res && typeof res === 'object' ? res : { message: String(res || 'Completed') },
|
|
332
|
+
timestamp: new Date().toLocaleTimeString()
|
|
333
|
+
};
|
|
334
|
+
} else {
|
|
335
|
+
throw new Error('Host execution context unavailable');
|
|
102
336
|
}
|
|
103
337
|
} catch (err) {
|
|
104
|
-
|
|
105
|
-
if (badge) {
|
|
106
|
-
badge.textContent = 'ERROR';
|
|
107
|
-
badge.className = 'badge error';
|
|
108
|
-
}
|
|
338
|
+
this.errorMessage = err.message || 'Fleet propagation failure';
|
|
109
339
|
} finally {
|
|
110
|
-
this.
|
|
340
|
+
this.loading = false;
|
|
341
|
+
this.refreshHubs();
|
|
111
342
|
}
|
|
112
343
|
}
|
|
113
344
|
|
|
114
345
|
render() {
|
|
346
|
+
if (!this.shadowRoot) return;
|
|
347
|
+
|
|
348
|
+
const countText = this.hubs.length ? `${this.hubs.length} Hubs` : '—';
|
|
349
|
+
const totalLines = this.hubs.reduce((acc, h) => acc + (h.lines || 0), 0);
|
|
350
|
+
const linesText = this.hubs.length ? `${totalLines.toLocaleString()} Lines` : '—';
|
|
351
|
+
const upstreamText = this.upstream?.latestVersion ? `v${this.upstream.latestVersion}` : 'Tracking';
|
|
352
|
+
|
|
115
353
|
this.shadowRoot.innerHTML = `
|
|
116
354
|
<style>
|
|
117
355
|
:host {
|
|
118
356
|
display: block;
|
|
119
|
-
font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
120
|
-
background: #140f06;
|
|
121
|
-
color: #fef3c7;
|
|
122
|
-
border-radius: 10px;
|
|
123
|
-
border: 1px solid rgba(217, 119, 6, 0.35);
|
|
124
|
-
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
|
|
125
|
-
padding: 18px;
|
|
126
357
|
box-sizing: border-box;
|
|
127
|
-
|
|
358
|
+
--face-bg: #0f172a;
|
|
359
|
+
--face-surface: #1e293b;
|
|
360
|
+
--face-surface-subtle: #334155;
|
|
361
|
+
--face-border: #475569;
|
|
362
|
+
--face-text: #f8fafc;
|
|
363
|
+
--face-text-muted: #94a3b8;
|
|
364
|
+
--face-accent: #f59e0b;
|
|
365
|
+
--face-accent-hover: #d97706;
|
|
366
|
+
--face-ok: #10b981;
|
|
367
|
+
--face-danger: #ef4444;
|
|
368
|
+
background: var(--face-bg);
|
|
369
|
+
color: var(--text-primary, var(--face-text));
|
|
370
|
+
border: 1px solid var(--border, var(--face-border));
|
|
371
|
+
border-radius: 8px;
|
|
372
|
+
padding: 16px;
|
|
373
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
128
374
|
}
|
|
129
375
|
|
|
130
|
-
|
|
376
|
+
*, *::before, *::after {
|
|
377
|
+
box-sizing: inherit;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.header-bar {
|
|
131
381
|
display: flex;
|
|
382
|
+
align-items: center;
|
|
132
383
|
justify-content: space-between;
|
|
133
|
-
|
|
134
|
-
margin-bottom:
|
|
384
|
+
gap: 12px;
|
|
385
|
+
margin-bottom: 12px;
|
|
386
|
+
border-bottom: 1px solid var(--border, var(--face-border));
|
|
387
|
+
padding-bottom: 12px;
|
|
135
388
|
}
|
|
136
389
|
|
|
137
|
-
.brand-
|
|
390
|
+
.brand-cluster {
|
|
138
391
|
display: flex;
|
|
139
392
|
align-items: center;
|
|
140
|
-
gap:
|
|
393
|
+
gap: 8px;
|
|
141
394
|
}
|
|
142
395
|
|
|
143
|
-
.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
396
|
+
.wordmark-badge {
|
|
397
|
+
display: inline-flex;
|
|
398
|
+
align-items: center;
|
|
399
|
+
font-family: ui-monospace, monospace;
|
|
400
|
+
font-size: 13px;
|
|
401
|
+
font-weight: 700;
|
|
402
|
+
letter-spacing: 0.05em;
|
|
403
|
+
color: var(--face-accent);
|
|
404
|
+
background: var(--face-surface-subtle);
|
|
405
|
+
padding: 4px 8px;
|
|
406
|
+
border-radius: 4px;
|
|
148
407
|
}
|
|
149
408
|
|
|
150
|
-
.title
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
409
|
+
.system-title {
|
|
410
|
+
font-size: 14px;
|
|
411
|
+
font-weight: 600;
|
|
412
|
+
color: var(--text-primary, var(--face-text));
|
|
154
413
|
}
|
|
155
414
|
|
|
156
|
-
.
|
|
157
|
-
|
|
415
|
+
.status-pill {
|
|
416
|
+
display: inline-flex;
|
|
417
|
+
align-items: center;
|
|
418
|
+
padding: 4px 10px;
|
|
419
|
+
border-radius: 12px;
|
|
420
|
+
font-size: 11px;
|
|
158
421
|
font-weight: 700;
|
|
159
|
-
letter-spacing: 0.
|
|
422
|
+
letter-spacing: 0.04em;
|
|
160
423
|
text-transform: uppercase;
|
|
161
|
-
|
|
162
|
-
|
|
424
|
+
background: var(--face-surface-subtle);
|
|
425
|
+
color: var(--face-text-muted);
|
|
426
|
+
border: 1px solid var(--border, var(--face-border));
|
|
163
427
|
}
|
|
164
428
|
|
|
165
|
-
.
|
|
166
|
-
|
|
167
|
-
color:
|
|
168
|
-
|
|
429
|
+
.status-pill.ok {
|
|
430
|
+
color: var(--face-ok);
|
|
431
|
+
border-color: var(--face-ok);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.status-pill.danger {
|
|
435
|
+
color: var(--face-danger);
|
|
436
|
+
border-color: var(--face-danger);
|
|
169
437
|
}
|
|
170
438
|
|
|
171
|
-
.
|
|
439
|
+
.screen-tabs {
|
|
440
|
+
display: flex;
|
|
441
|
+
gap: 6px;
|
|
442
|
+
margin-bottom: 16px;
|
|
443
|
+
border-bottom: 1px solid var(--border, var(--face-border));
|
|
444
|
+
padding-bottom: 8px;
|
|
445
|
+
overflow-x: auto;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.screen-tab-btn {
|
|
449
|
+
min-height: 36px;
|
|
450
|
+
padding: 0 12px;
|
|
451
|
+
font-size: 12px;
|
|
452
|
+
font-weight: 600;
|
|
453
|
+
border-radius: 6px;
|
|
454
|
+
border: 1px solid transparent;
|
|
455
|
+
background: transparent;
|
|
456
|
+
color: var(--face-text-muted);
|
|
457
|
+
cursor: pointer;
|
|
458
|
+
transition: all 0.15s ease;
|
|
172
459
|
display: inline-flex;
|
|
173
460
|
align-items: center;
|
|
174
|
-
|
|
175
|
-
font-weight: 700;
|
|
176
|
-
letter-spacing: 0.08em;
|
|
177
|
-
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);
|
|
461
|
+
white-space: nowrap;
|
|
183
462
|
}
|
|
184
463
|
|
|
185
|
-
.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
border-color: rgba(16, 185, 129, 0.35);
|
|
464
|
+
.screen-tab-btn:hover {
|
|
465
|
+
color: var(--face-text);
|
|
466
|
+
background: var(--face-surface-subtle);
|
|
189
467
|
}
|
|
190
468
|
|
|
191
|
-
.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
border-color:
|
|
469
|
+
.screen-tab-btn.active {
|
|
470
|
+
color: var(--face-accent);
|
|
471
|
+
background: var(--face-surface);
|
|
472
|
+
border-color: var(--face-accent);
|
|
195
473
|
}
|
|
196
474
|
|
|
197
|
-
.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
475
|
+
.stats-grid {
|
|
476
|
+
display: grid;
|
|
477
|
+
grid-template-columns: repeat(3, 1fr);
|
|
478
|
+
gap: 8px;
|
|
479
|
+
margin-bottom: 16px;
|
|
201
480
|
}
|
|
202
481
|
|
|
203
|
-
.
|
|
204
|
-
|
|
482
|
+
.stat-card {
|
|
483
|
+
background: var(--face-surface);
|
|
484
|
+
border: 1px solid var(--border, var(--face-border));
|
|
485
|
+
border-radius: 6px;
|
|
486
|
+
padding: 10px;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.stat-label {
|
|
490
|
+
font-size: 11px;
|
|
205
491
|
text-transform: uppercase;
|
|
206
|
-
letter-spacing: 0.
|
|
207
|
-
color:
|
|
492
|
+
letter-spacing: 0.04em;
|
|
493
|
+
color: var(--face-text-muted);
|
|
494
|
+
margin-bottom: 4px;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.stat-value {
|
|
498
|
+
font-size: 16px;
|
|
208
499
|
font-weight: 700;
|
|
209
|
-
|
|
500
|
+
color: var(--text-primary, var(--face-text));
|
|
501
|
+
font-family: ui-monospace, monospace;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.section-header {
|
|
210
505
|
display: flex;
|
|
211
|
-
justify-content: space-between;
|
|
212
506
|
align-items: center;
|
|
507
|
+
justify-content: space-between;
|
|
508
|
+
margin-bottom: 8px;
|
|
213
509
|
}
|
|
214
510
|
|
|
215
|
-
.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
511
|
+
.section-title {
|
|
512
|
+
font-size: 12px;
|
|
513
|
+
font-weight: 700;
|
|
514
|
+
text-transform: uppercase;
|
|
515
|
+
letter-spacing: 0.05em;
|
|
516
|
+
color: var(--face-accent);
|
|
221
517
|
}
|
|
222
518
|
|
|
223
|
-
.hub-
|
|
519
|
+
.hub-list {
|
|
224
520
|
display: flex;
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
521
|
+
flex-direction: column;
|
|
522
|
+
gap: 6px;
|
|
523
|
+
margin-bottom: 16px;
|
|
524
|
+
max-height: 180px;
|
|
525
|
+
overflow-y: auto;
|
|
230
526
|
}
|
|
231
527
|
|
|
232
|
-
.hub-item
|
|
233
|
-
|
|
528
|
+
.hub-item {
|
|
529
|
+
display: flex;
|
|
530
|
+
align-items: center;
|
|
531
|
+
justify-content: space-between;
|
|
532
|
+
background: var(--face-surface);
|
|
533
|
+
border: 1px solid var(--border, var(--face-border));
|
|
534
|
+
border-radius: 6px;
|
|
535
|
+
padding: 8px 12px;
|
|
536
|
+
font-size: 13px;
|
|
234
537
|
}
|
|
235
538
|
|
|
236
539
|
.hub-title {
|
|
237
|
-
color: #fde68a;
|
|
238
540
|
font-weight: 600;
|
|
541
|
+
color: var(--text-primary, var(--face-text));
|
|
239
542
|
}
|
|
240
543
|
|
|
241
544
|
.hub-meta {
|
|
242
|
-
|
|
243
|
-
font-
|
|
244
|
-
|
|
545
|
+
font-family: ui-monospace, monospace;
|
|
546
|
+
font-size: 11px;
|
|
547
|
+
color: var(--face-text-muted);
|
|
245
548
|
}
|
|
246
549
|
|
|
247
|
-
.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
padding
|
|
550
|
+
.empty-state {
|
|
551
|
+
display: flex;
|
|
552
|
+
align-items: center;
|
|
553
|
+
justify-content: center;
|
|
554
|
+
padding: 24px;
|
|
555
|
+
color: var(--face-text-muted);
|
|
556
|
+
background: var(--face-surface);
|
|
557
|
+
border: 1px dashed var(--border, var(--face-border));
|
|
558
|
+
border-radius: 6px;
|
|
559
|
+
font-size: 13px;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
.ingest-deck {
|
|
563
|
+
background: var(--face-surface);
|
|
564
|
+
border: 1px solid var(--border, var(--face-border));
|
|
565
|
+
border-radius: 6px;
|
|
566
|
+
padding: 12px;
|
|
567
|
+
margin-bottom: 16px;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
.config-deck {
|
|
571
|
+
background: var(--face-surface);
|
|
572
|
+
border: 1px solid var(--border, var(--face-border));
|
|
573
|
+
border-radius: 6px;
|
|
574
|
+
padding: 14px;
|
|
575
|
+
margin-bottom: 16px;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.config-grid {
|
|
579
|
+
display: grid;
|
|
580
|
+
grid-template-columns: 1fr 1fr;
|
|
581
|
+
gap: 12px;
|
|
582
|
+
margin-bottom: 14px;
|
|
252
583
|
}
|
|
253
584
|
|
|
254
|
-
.
|
|
585
|
+
.field-group {
|
|
255
586
|
display: flex;
|
|
256
|
-
|
|
257
|
-
|
|
587
|
+
flex-direction: column;
|
|
588
|
+
gap: 4px;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.field-group.full-width {
|
|
592
|
+
grid-column: 1 / -1;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
.field-label {
|
|
596
|
+
font-size: 11px;
|
|
597
|
+
font-weight: 700;
|
|
598
|
+
text-transform: uppercase;
|
|
599
|
+
letter-spacing: 0.04em;
|
|
600
|
+
color: var(--face-text-muted);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
.input-group {
|
|
604
|
+
display: flex;
|
|
605
|
+
gap: 8px;
|
|
258
606
|
margin-bottom: 12px;
|
|
259
607
|
}
|
|
260
608
|
|
|
261
|
-
.path-input {
|
|
262
|
-
|
|
263
|
-
background:
|
|
264
|
-
border: 1px solid
|
|
609
|
+
.path-input, .text-input, .select-input {
|
|
610
|
+
min-height: 44px;
|
|
611
|
+
background: var(--face-surface-subtle);
|
|
612
|
+
border: 1px solid var(--border, var(--face-border));
|
|
265
613
|
border-radius: 6px;
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
font-
|
|
269
|
-
|
|
614
|
+
padding: 8px 12px;
|
|
615
|
+
color: var(--text-primary, var(--face-text));
|
|
616
|
+
font-family: ui-monospace, monospace;
|
|
617
|
+
font-size: 13px;
|
|
618
|
+
width: 100%;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
.path-input:focus, .text-input:focus, .select-input:focus {
|
|
270
622
|
outline: none;
|
|
271
|
-
|
|
623
|
+
border-color: var(--face-accent);
|
|
272
624
|
}
|
|
273
625
|
|
|
274
|
-
.
|
|
275
|
-
|
|
276
|
-
|
|
626
|
+
.presets-bar {
|
|
627
|
+
display: flex;
|
|
628
|
+
gap: 6px;
|
|
629
|
+
flex-wrap: wrap;
|
|
630
|
+
margin-bottom: 14px;
|
|
277
631
|
}
|
|
278
632
|
|
|
279
|
-
.preset-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
633
|
+
.preset-chip {
|
|
634
|
+
min-height: 32px;
|
|
635
|
+
padding: 4px 10px;
|
|
636
|
+
background: var(--face-surface-subtle);
|
|
637
|
+
border: 1px solid var(--border, var(--face-border));
|
|
638
|
+
border-radius: 16px;
|
|
639
|
+
font-size: 11px;
|
|
640
|
+
font-family: ui-monospace, monospace;
|
|
641
|
+
color: var(--face-text);
|
|
287
642
|
cursor: pointer;
|
|
643
|
+
transition: all 0.15s ease;
|
|
288
644
|
}
|
|
289
645
|
|
|
290
|
-
.preset-
|
|
291
|
-
|
|
646
|
+
.preset-chip:hover {
|
|
647
|
+
border-color: var(--face-accent);
|
|
648
|
+
color: var(--face-accent);
|
|
292
649
|
}
|
|
293
650
|
|
|
294
|
-
.
|
|
295
|
-
display:
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
651
|
+
.auth-notice-card {
|
|
652
|
+
display: flex;
|
|
653
|
+
align-items: center;
|
|
654
|
+
justify-content: space-between;
|
|
655
|
+
background: #022c22;
|
|
656
|
+
border: 1px solid var(--face-ok);
|
|
657
|
+
border-radius: 6px;
|
|
658
|
+
padding: 10px 14px;
|
|
659
|
+
margin-bottom: 14px;
|
|
660
|
+
font-size: 12px;
|
|
661
|
+
color: #a7f3d0;
|
|
299
662
|
}
|
|
300
663
|
|
|
301
|
-
.
|
|
664
|
+
.toggle-label {
|
|
665
|
+
display: inline-flex;
|
|
666
|
+
align-items: center;
|
|
667
|
+
gap: 8px;
|
|
302
668
|
min-height: 44px;
|
|
303
|
-
|
|
669
|
+
font-size: 13px;
|
|
670
|
+
color: var(--text-primary, var(--face-text));
|
|
671
|
+
cursor: pointer;
|
|
672
|
+
user-select: none;
|
|
673
|
+
padding: 0 4px;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
.button-group {
|
|
677
|
+
display: grid;
|
|
678
|
+
grid-template-columns: repeat(2, 1fr);
|
|
679
|
+
gap: 8px;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
.btn {
|
|
304
683
|
display: inline-flex;
|
|
305
684
|
align-items: center;
|
|
306
685
|
justify-content: center;
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
font-size: 11px;
|
|
686
|
+
min-height: 44px;
|
|
687
|
+
padding: 0 12px;
|
|
688
|
+
font-size: 12px;
|
|
311
689
|
font-weight: 600;
|
|
312
|
-
letter-spacing: 0.03em;
|
|
313
|
-
text-transform: uppercase;
|
|
314
690
|
border-radius: 6px;
|
|
691
|
+
border: 1px solid transparent;
|
|
315
692
|
cursor: pointer;
|
|
316
|
-
transition: background 0.15s ease, border-color 0.15s ease;
|
|
317
|
-
padding: 6px;
|
|
693
|
+
transition: background-color 0.15s ease, border-color 0.15s ease;
|
|
318
694
|
text-align: center;
|
|
319
695
|
}
|
|
320
696
|
|
|
321
|
-
.
|
|
322
|
-
background:
|
|
323
|
-
|
|
697
|
+
.btn-primary {
|
|
698
|
+
background: var(--face-accent);
|
|
699
|
+
color: var(--face-bg);
|
|
324
700
|
}
|
|
325
701
|
|
|
326
|
-
.
|
|
327
|
-
|
|
702
|
+
.btn-primary:hover:not(:disabled) {
|
|
703
|
+
background: var(--face-accent-hover);
|
|
328
704
|
}
|
|
329
705
|
|
|
330
|
-
.
|
|
331
|
-
background:
|
|
332
|
-
color:
|
|
333
|
-
|
|
334
|
-
font-weight: 700;
|
|
706
|
+
.btn-secondary {
|
|
707
|
+
background: var(--face-surface-subtle);
|
|
708
|
+
border-color: var(--border, var(--face-border));
|
|
709
|
+
color: var(--text-primary, var(--face-text));
|
|
335
710
|
}
|
|
336
711
|
|
|
337
|
-
.
|
|
338
|
-
|
|
712
|
+
.btn-secondary:hover:not(:disabled) {
|
|
713
|
+
border-color: var(--face-accent);
|
|
339
714
|
}
|
|
340
715
|
|
|
341
|
-
.
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
716
|
+
.btn:disabled {
|
|
717
|
+
opacity: 0.5;
|
|
718
|
+
cursor: not-allowed;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
.result-deck {
|
|
722
|
+
background: var(--face-surface-subtle);
|
|
723
|
+
border: 1px solid var(--border, var(--face-border));
|
|
724
|
+
border-radius: 6px;
|
|
725
|
+
padding: 12px;
|
|
726
|
+
font-family: ui-monospace, monospace;
|
|
727
|
+
font-size: 12px;
|
|
728
|
+
color: var(--text-primary, var(--face-text));
|
|
729
|
+
margin-top: 12px;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
.result-title {
|
|
733
|
+
font-weight: 600;
|
|
734
|
+
color: var(--face-accent);
|
|
735
|
+
margin-bottom: 6px;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.error-deck {
|
|
739
|
+
background: var(--face-surface);
|
|
740
|
+
border: 1px solid var(--face-danger);
|
|
741
|
+
border-radius: 6px;
|
|
742
|
+
padding: 12px;
|
|
743
|
+
color: var(--face-danger);
|
|
744
|
+
font-size: 12px;
|
|
745
|
+
margin-bottom: 12px;
|
|
346
746
|
}
|
|
347
747
|
|
|
348
|
-
.
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
748
|
+
.repo-status-badge {
|
|
749
|
+
display: inline-flex;
|
|
750
|
+
align-items: center;
|
|
751
|
+
padding: 2px 6px;
|
|
752
|
+
border-radius: 4px;
|
|
352
753
|
font-size: 10px;
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
text-
|
|
754
|
+
font-weight: 700;
|
|
755
|
+
letter-spacing: 0.04em;
|
|
756
|
+
text-transform: uppercase;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.repo-status-badge.current {
|
|
760
|
+
background: #064e3b;
|
|
761
|
+
color: #6ee7b7;
|
|
356
762
|
}
|
|
357
763
|
|
|
358
|
-
.
|
|
764
|
+
.repo-status-badge.due {
|
|
765
|
+
background: #78350f;
|
|
359
766
|
color: #fde68a;
|
|
360
767
|
}
|
|
361
768
|
|
|
362
|
-
.
|
|
363
|
-
background: #
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
white-space: pre-wrap;
|
|
375
|
-
word-break: break-word;
|
|
769
|
+
.repo-status-badge.uninit {
|
|
770
|
+
background: #831843;
|
|
771
|
+
color: #fbcfe8;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
@media (prefers-reduced-motion: reduce) {
|
|
775
|
+
*, *::before, *::after {
|
|
776
|
+
animation-duration: 0.01ms !important;
|
|
777
|
+
animation-iteration-count: 1 !important;
|
|
778
|
+
transition-duration: 0.01ms !important;
|
|
779
|
+
scroll-behavior: auto !important;
|
|
780
|
+
}
|
|
376
781
|
}
|
|
377
782
|
</style>
|
|
378
783
|
|
|
379
|
-
<div class="header">
|
|
380
|
-
<div class="brand-
|
|
381
|
-
<
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
784
|
+
<div class="header-bar">
|
|
785
|
+
<div class="brand-cluster">
|
|
786
|
+
<span class="wordmark-badge">[BRAIN//DUMP]</span>
|
|
787
|
+
<span class="system-title">Knowledge Graph Engine</span>
|
|
788
|
+
</div>
|
|
789
|
+
<span class="status-pill ${this.statusText === 'SYNCHRONIZED' ? 'ok' : this.statusText === 'ERROR' ? 'danger' : ''}">
|
|
790
|
+
${this.statusText}
|
|
791
|
+
</span>
|
|
792
|
+
</div>
|
|
793
|
+
|
|
794
|
+
<nav class="screen-tabs" aria-label="OpenWiki navigation screens">
|
|
795
|
+
${OpenWikiCard.screens.map((screen) => `
|
|
796
|
+
<button
|
|
797
|
+
class="screen-tab-btn ${this.activeScreen === screen.id ? 'active' : ''}"
|
|
798
|
+
data-screen="${screen.id}"
|
|
799
|
+
>
|
|
800
|
+
${screen.label}
|
|
801
|
+
</button>
|
|
802
|
+
`).join('')}
|
|
803
|
+
</nav>
|
|
804
|
+
|
|
805
|
+
<div class="stats-grid">
|
|
806
|
+
<div class="stat-card">
|
|
807
|
+
<div class="stat-label">Discovered Hubs</div>
|
|
808
|
+
<div class="stat-value">${countText}</div>
|
|
809
|
+
</div>
|
|
810
|
+
<div class="stat-card">
|
|
811
|
+
<div class="stat-label">Documentation Lines</div>
|
|
812
|
+
<div class="stat-value">${linesText}</div>
|
|
813
|
+
</div>
|
|
814
|
+
<div class="stat-card">
|
|
815
|
+
<div class="stat-label">Active Model Routing</div>
|
|
816
|
+
<div class="stat-value" style="font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;" title="${this.config.model}">
|
|
817
|
+
${this.config.model.split('/').pop() || this.config.model}
|
|
389
818
|
</div>
|
|
390
819
|
</div>
|
|
391
|
-
<div id="status-badge" class="badge ready">READY</div>
|
|
392
820
|
</div>
|
|
393
821
|
|
|
394
|
-
|
|
395
|
-
<
|
|
396
|
-
|
|
822
|
+
${this.errorMessage ? `
|
|
823
|
+
<div class="error-deck">
|
|
824
|
+
${this.errorMessage}
|
|
825
|
+
</div>
|
|
826
|
+
` : ''}
|
|
827
|
+
|
|
828
|
+
${this.renderActiveScreen()}
|
|
829
|
+
|
|
830
|
+
${this.executionResult ? `
|
|
831
|
+
<div class="result-deck">
|
|
832
|
+
<div class="result-title">Execution Receipt (${this.executionResult.timestamp})</div>
|
|
833
|
+
<div>Action: ${this.executionResult.action}</div>
|
|
834
|
+
<div>Target: ${this.executionResult.target || 'project'}</div>
|
|
835
|
+
<div>Result: ${JSON.stringify(this.executionResult.details)}</div>
|
|
836
|
+
</div>
|
|
837
|
+
` : ''}
|
|
838
|
+
`;
|
|
839
|
+
|
|
840
|
+
this.bindEvents();
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
renderActiveScreen() {
|
|
844
|
+
if (this.activeScreen === 'config') {
|
|
845
|
+
return this.renderConfigScreen();
|
|
846
|
+
}
|
|
847
|
+
if (this.activeScreen === 'refresh') {
|
|
848
|
+
return this.renderRefreshScreen();
|
|
849
|
+
}
|
|
850
|
+
if (this.activeScreen === 'upstream') {
|
|
851
|
+
return this.renderUpstreamScreen();
|
|
852
|
+
}
|
|
853
|
+
return this.renderHubsScreen();
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
renderHubsScreen() {
|
|
857
|
+
return `
|
|
858
|
+
<div class="section-header">
|
|
859
|
+
<span class="section-title">Knowledge Hubs</span>
|
|
860
|
+
<button id="btn-refresh" class="btn btn-secondary" style="min-height: 32px; padding: 0 10px; font-size: 11px;" ${this.loading ? 'disabled' : ''}>
|
|
861
|
+
Sync
|
|
862
|
+
</button>
|
|
397
863
|
</div>
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
</
|
|
405
|
-
|
|
406
|
-
|
|
864
|
+
|
|
865
|
+
<div class="hub-list">
|
|
866
|
+
${this.hubs.length === 0 ? `
|
|
867
|
+
<div class="empty-state">No documentation hubs indexed in ${this.targetPath}</div>
|
|
868
|
+
` : this.hubs.map((h) => `
|
|
869
|
+
<div class="hub-item">
|
|
870
|
+
<span class="hub-title">${h.title}</span>
|
|
871
|
+
<span class="hub-meta">${h.lines} lines · ${h.path}</span>
|
|
872
|
+
</div>
|
|
873
|
+
`).join('')}
|
|
874
|
+
</div>
|
|
875
|
+
|
|
876
|
+
<div class="ingest-deck">
|
|
877
|
+
<div class="input-group">
|
|
878
|
+
<input
|
|
879
|
+
id="target-path-input"
|
|
880
|
+
class="path-input"
|
|
881
|
+
type="text"
|
|
882
|
+
value="${this.targetPath}"
|
|
883
|
+
placeholder="Directory path (openwiki)"
|
|
884
|
+
aria-label="Target documentation path"
|
|
885
|
+
/>
|
|
886
|
+
<label class="toggle-label">
|
|
887
|
+
<input
|
|
888
|
+
id="dry-run-checkbox"
|
|
889
|
+
type="checkbox"
|
|
890
|
+
${this.dryRun ? 'checked' : ''}
|
|
891
|
+
/>
|
|
892
|
+
Dry Run
|
|
893
|
+
</label>
|
|
894
|
+
</div>
|
|
895
|
+
|
|
896
|
+
<div class="button-group">
|
|
897
|
+
<button id="btn-ingest" class="btn btn-primary" ${this.loading ? 'disabled' : ''}>
|
|
898
|
+
${this.loading ? 'Processing…' : 'Ingest Documentation'}
|
|
899
|
+
</button>
|
|
900
|
+
<button id="btn-bootstrap" class="btn btn-secondary" ${this.loading ? 'disabled' : ''}>
|
|
901
|
+
Bootstrap Wiki
|
|
902
|
+
</button>
|
|
407
903
|
</div>
|
|
408
904
|
</div>
|
|
905
|
+
`;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
renderConfigScreen() {
|
|
909
|
+
return `
|
|
910
|
+
<div class="config-deck">
|
|
911
|
+
<div class="section-header">
|
|
912
|
+
<span class="section-title">Documentation Model & Provider Routing</span>
|
|
913
|
+
</div>
|
|
914
|
+
|
|
915
|
+
<div class="auth-notice-card">
|
|
916
|
+
<span>✓ Model credentials routed via Total Recall Auth store (<code>total-recall auth secret</code>)</span>
|
|
917
|
+
<span style="font-family: ui-monospace, monospace; font-size: 10px;">AUTH_PLUGIN: ACTIVE</span>
|
|
918
|
+
</div>
|
|
919
|
+
|
|
920
|
+
<div class="field-label" style="margin-bottom: 6px;">Recommended Model Presets:</div>
|
|
921
|
+
<div class="presets-bar">
|
|
922
|
+
<button class="preset-chip" data-provider="openrouter" data-model="deepseek/deepseek-v4.1-flash" data-fallback="qwen/qwen-2.5-coder-32b-instruct">
|
|
923
|
+
DeepSeek V4.1 Flash ($0.025/1M)
|
|
924
|
+
</button>
|
|
925
|
+
<button class="preset-chip" data-provider="openrouter" data-model="qwen/qwen-2.5-coder-32b-instruct" data-fallback="deepseek/deepseek-v4.1-flash">
|
|
926
|
+
Qwen 2.5 Coder 32B ($0.06/1M)
|
|
927
|
+
</button>
|
|
928
|
+
<button class="preset-chip" data-provider="google" data-model="gemini-2.5-flash-lite" data-fallback="gemini-2.5-flash">
|
|
929
|
+
Gemini 2.5 Flash-Lite ($0.075/1M)
|
|
930
|
+
</button>
|
|
931
|
+
</div>
|
|
932
|
+
|
|
933
|
+
<div class="config-grid">
|
|
934
|
+
<div class="field-group">
|
|
935
|
+
<label class="field-label" for="cfg-provider">Provider</label>
|
|
936
|
+
<select id="cfg-provider" class="select-input">
|
|
937
|
+
<option value="openrouter" ${this.config.provider === 'openrouter' ? 'selected' : ''}>OpenRouter (Multi-Model Hub)</option>
|
|
938
|
+
<option value="google" ${this.config.provider === 'google' ? 'selected' : ''}>Google (Gemini Direct)</option>
|
|
939
|
+
<option value="custom" ${this.config.provider === 'custom' ? 'selected' : ''}>Custom Provider</option>
|
|
940
|
+
</select>
|
|
941
|
+
</div>
|
|
942
|
+
|
|
943
|
+
<div class="field-group">
|
|
944
|
+
<label class="field-label" for="cfg-model">Primary Model Identifier</label>
|
|
945
|
+
<input id="cfg-model" class="text-input" type="text" value="${this.config.model}" placeholder="e.g. deepseek/deepseek-v4.1-flash" />
|
|
946
|
+
</div>
|
|
409
947
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
948
|
+
<div class="field-group">
|
|
949
|
+
<label class="field-label" for="cfg-fallback">Fallback Model Identifier</label>
|
|
950
|
+
<input id="cfg-fallback" class="text-input" type="text" value="${this.config.fallback_model}" placeholder="e.g. qwen/qwen-2.5-coder-32b-instruct" />
|
|
951
|
+
</div>
|
|
952
|
+
|
|
953
|
+
<div class="field-group">
|
|
954
|
+
<label class="field-label" for="cfg-tokens">Max Output Tokens</label>
|
|
955
|
+
<input id="cfg-tokens" class="text-input" type="number" value="${this.config.max_tokens}" min="512" max="131072" />
|
|
956
|
+
</div>
|
|
957
|
+
|
|
958
|
+
<div class="field-group full-width">
|
|
959
|
+
<label class="field-label" for="cfg-timeout">Timeout (milliseconds)</label>
|
|
960
|
+
<input id="cfg-timeout" class="text-input" type="number" value="${this.config.timeout_ms}" min="30000" max="1800000" />
|
|
961
|
+
</div>
|
|
962
|
+
</div>
|
|
963
|
+
|
|
964
|
+
<div class="button-group">
|
|
965
|
+
<button id="btn-save-config" class="btn btn-primary" ${this.loading ? 'disabled' : ''}>
|
|
966
|
+
Save Configuration
|
|
967
|
+
</button>
|
|
968
|
+
<button id="btn-reset-config" class="btn btn-secondary" ${this.loading ? 'disabled' : ''}>
|
|
969
|
+
Reset to Defaults
|
|
970
|
+
</button>
|
|
971
|
+
</div>
|
|
415
972
|
</div>
|
|
973
|
+
`;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
renderRefreshScreen() {
|
|
977
|
+
const dueCount = this.refreshCounts?.due ?? this.refreshReports.filter((r) => r.action === 'due').length;
|
|
978
|
+
const uninitCount = this.refreshCounts?.uninitialized ?? this.refreshReports.filter((r) => r.uninitialized).length;
|
|
416
979
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
<
|
|
420
|
-
|
|
421
|
-
|
|
980
|
+
return `
|
|
981
|
+
<div class="ingest-deck">
|
|
982
|
+
<div class="section-header">
|
|
983
|
+
<span class="section-title">Fleet Documentation Governance</span>
|
|
984
|
+
<button id="btn-sync-refresh" class="btn btn-secondary" style="min-height: 32px; padding: 0 10px; font-size: 11px;" ${this.loading ? 'disabled' : ''}>
|
|
985
|
+
Check Fleet
|
|
986
|
+
</button>
|
|
987
|
+
</div>
|
|
988
|
+
|
|
989
|
+
<div style="font-size: 12px; color: var(--face-text-muted); margin-bottom: 12px;">
|
|
990
|
+
Registered Projects: <strong>${this.refreshReports.length}</strong> · Due for Update: <strong>${dueCount}</strong> · Uninitialized: <strong>${uninitCount}</strong>
|
|
991
|
+
</div>
|
|
992
|
+
|
|
993
|
+
<div class="hub-list" style="max-height: 240px;">
|
|
994
|
+
${this.refreshReports.length === 0 ? `
|
|
995
|
+
<div class="empty-state">No fleet report loaded. Click Check Fleet to inspect registered repositories.</div>
|
|
996
|
+
` : this.refreshReports.map((r) => {
|
|
997
|
+
let badgeClass = 'current';
|
|
998
|
+
let badgeText = 'CURRENT';
|
|
999
|
+
if (r.uninitialized) {
|
|
1000
|
+
badgeClass = 'uninit';
|
|
1001
|
+
badgeText = 'MISSING WIKI';
|
|
1002
|
+
} else if (r.action === 'due') {
|
|
1003
|
+
badgeClass = 'due';
|
|
1004
|
+
badgeText = 'DUE';
|
|
1005
|
+
}
|
|
1006
|
+
return `
|
|
1007
|
+
<div class="hub-item">
|
|
1008
|
+
<div>
|
|
1009
|
+
<span class="hub-title">${r.name}</span>
|
|
1010
|
+
<div class="hub-meta">${r.generatedAt ? `Generated ${r.generatedAt.slice(0, 10)}` : 'Never generated'} · ${r.commitsSince ? `${r.commitsSince} commits behind` : 'Up to date'}</div>
|
|
1011
|
+
</div>
|
|
1012
|
+
<span class="repo-status-badge ${badgeClass}">${badgeText}</span>
|
|
1013
|
+
</div>
|
|
1014
|
+
`;
|
|
1015
|
+
}).join('')}
|
|
1016
|
+
</div>
|
|
1017
|
+
|
|
1018
|
+
<div style="margin-top: 12px;">
|
|
1019
|
+
<button id="btn-fleet-refresh-apply" class="btn btn-primary" style="width: 100%;" ${this.loading ? 'disabled' : ''}>
|
|
1020
|
+
${this.loading ? 'Executing Fleet Refresh…' : `Regenerate Stale & Initialize Missing Wikis (${dueCount} due)`}
|
|
1021
|
+
</button>
|
|
1022
|
+
</div>
|
|
422
1023
|
</div>
|
|
1024
|
+
`;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
renderUpstreamScreen() {
|
|
1028
|
+
const currentVer = this.upstream?.recordedVersion || '0.7.2';
|
|
1029
|
+
const latestVer = this.upstream?.latestVersion || '0.7.3';
|
|
1030
|
+
|
|
1031
|
+
return `
|
|
1032
|
+
<div class="ingest-deck">
|
|
1033
|
+
<div class="section-header">
|
|
1034
|
+
<span class="section-title">Upstream Package Surveillance</span>
|
|
1035
|
+
</div>
|
|
1036
|
+
|
|
1037
|
+
<div class="stats-grid" style="margin-bottom: 14px;">
|
|
1038
|
+
<div class="stat-card">
|
|
1039
|
+
<div class="stat-label">Recorded Version</div>
|
|
1040
|
+
<div class="stat-value">v${currentVer}</div>
|
|
1041
|
+
</div>
|
|
1042
|
+
<div class="stat-card">
|
|
1043
|
+
<div class="stat-label">Latest Registry</div>
|
|
1044
|
+
<div class="stat-value">v${latestVer}</div>
|
|
1045
|
+
</div>
|
|
1046
|
+
<div class="stat-card">
|
|
1047
|
+
<div class="stat-label">Watcher Status</div>
|
|
1048
|
+
<div class="stat-value" style="color: var(--face-ok);">MONITORING</div>
|
|
1049
|
+
</div>
|
|
1050
|
+
</div>
|
|
423
1051
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
1052
|
+
<div class="button-group">
|
|
1053
|
+
<button id="btn-watch" class="btn btn-secondary" ${this.loading ? 'disabled' : ''}>
|
|
1054
|
+
Check Upstream Registry
|
|
1055
|
+
</button>
|
|
1056
|
+
<button id="btn-propagate" class="btn btn-primary" ${this.loading ? 'disabled' : ''}>
|
|
1057
|
+
Propagate Latest Generator
|
|
1058
|
+
</button>
|
|
1059
|
+
</div>
|
|
427
1060
|
</div>
|
|
428
|
-
<div id="card-out" class="output-box">Knowledge graph index operational. Ready for cross-repo documentation queries.</div>
|
|
429
1061
|
`;
|
|
1062
|
+
}
|
|
430
1063
|
|
|
431
|
-
|
|
432
|
-
this.shadowRoot
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
1064
|
+
bindEvents() {
|
|
1065
|
+
const shadow = this.shadowRoot;
|
|
1066
|
+
if (!shadow) return;
|
|
1067
|
+
|
|
1068
|
+
shadow.querySelectorAll('.screen-tab-btn').forEach((tab) => {
|
|
1069
|
+
tab.addEventListener('click', () => {
|
|
1070
|
+
const targetScreen = tab.getAttribute('data-screen');
|
|
1071
|
+
if (targetScreen) this.setScreen(targetScreen);
|
|
1072
|
+
});
|
|
437
1073
|
});
|
|
438
1074
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
1075
|
+
const pathInput = shadow.querySelector('#target-path-input');
|
|
1076
|
+
if (pathInput) {
|
|
1077
|
+
pathInput.addEventListener('input', (e) => {
|
|
1078
|
+
this.targetPath = e.target.value.trim();
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
const dryRunCheckbox = shadow.querySelector('#dry-run-checkbox');
|
|
1083
|
+
if (dryRunCheckbox) {
|
|
1084
|
+
dryRunCheckbox.addEventListener('change', (e) => {
|
|
1085
|
+
this.dryRun = e.target.checked;
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
443
1088
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
1089
|
+
const btnIngest = shadow.querySelector('#btn-ingest');
|
|
1090
|
+
if (btnIngest) {
|
|
1091
|
+
btnIngest.addEventListener('click', () => this.executeIngest());
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
const btnBootstrap = shadow.querySelector('#btn-bootstrap');
|
|
1095
|
+
if (btnBootstrap) {
|
|
1096
|
+
btnBootstrap.addEventListener('click', () => this.executeBootstrap());
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
const btnRefresh = shadow.querySelector('#btn-refresh');
|
|
1100
|
+
if (btnRefresh) {
|
|
1101
|
+
btnRefresh.addEventListener('click', () => this.refreshHubs());
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
const btnSyncRefresh = shadow.querySelector('#btn-sync-refresh');
|
|
1105
|
+
if (btnSyncRefresh) {
|
|
1106
|
+
btnSyncRefresh.addEventListener('click', () => this.loadRefreshReport());
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
const btnFleetApply = shadow.querySelector('#btn-fleet-refresh-apply');
|
|
1110
|
+
if (btnFleetApply) {
|
|
1111
|
+
btnFleetApply.addEventListener('click', () => this.executeFleetRefresh());
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
const btnWatch = shadow.querySelector('#btn-watch');
|
|
1115
|
+
if (btnWatch) {
|
|
1116
|
+
btnWatch.addEventListener('click', () => this.executeWatch());
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
const btnPropagate = shadow.querySelector('#btn-propagate');
|
|
1120
|
+
if (btnPropagate) {
|
|
1121
|
+
btnPropagate.addEventListener('click', () => this.executePropagate());
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
shadow.querySelectorAll('.preset-chip').forEach((chip) => {
|
|
1125
|
+
chip.addEventListener('click', async () => {
|
|
1126
|
+
const p = chip.getAttribute('data-provider');
|
|
1127
|
+
const m = chip.getAttribute('data-model');
|
|
1128
|
+
const f = chip.getAttribute('data-fallback');
|
|
1129
|
+
if (p) await this.setConfigValue('provider', p);
|
|
1130
|
+
if (m) await this.setConfigValue('model', m);
|
|
1131
|
+
if (f) await this.setConfigValue('fallback_model', f);
|
|
1132
|
+
});
|
|
449
1133
|
});
|
|
1134
|
+
|
|
1135
|
+
const btnSaveConfig = shadow.querySelector('#btn-save-config');
|
|
1136
|
+
if (btnSaveConfig) {
|
|
1137
|
+
btnSaveConfig.addEventListener('click', async () => {
|
|
1138
|
+
const provider = shadow.querySelector('#cfg-provider')?.value;
|
|
1139
|
+
const model = shadow.querySelector('#cfg-model')?.value;
|
|
1140
|
+
const fallback = shadow.querySelector('#cfg-fallback')?.value;
|
|
1141
|
+
const tokens = shadow.querySelector('#cfg-tokens')?.value;
|
|
1142
|
+
const timeout = shadow.querySelector('#cfg-timeout')?.value;
|
|
1143
|
+
|
|
1144
|
+
if (provider) await this.setConfigValue('provider', provider);
|
|
1145
|
+
if (model) await this.setConfigValue('model', model);
|
|
1146
|
+
if (fallback) await this.setConfigValue('fallback_model', fallback);
|
|
1147
|
+
if (tokens) await this.setConfigValue('max_tokens', tokens);
|
|
1148
|
+
if (timeout) await this.setConfigValue('timeout_ms', timeout);
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
const btnResetConfig = shadow.querySelector('#btn-reset-config');
|
|
1153
|
+
if (btnResetConfig) {
|
|
1154
|
+
btnResetConfig.addEventListener('click', () => this.resetConfig());
|
|
1155
|
+
}
|
|
450
1156
|
}
|
|
451
1157
|
}
|
|
452
1158
|
|