omnius 1.0.601 → 1.0.602
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +739 -184
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -678990,6 +678990,7 @@ __export(tray_exports, {
|
|
|
678990
678990
|
trayRequiresRestart: () => trayRequiresRestart,
|
|
678991
678991
|
traySupport: () => traySupport,
|
|
678992
678992
|
trayUpdatePresentation: () => trayUpdatePresentation,
|
|
678993
|
+
trayVersionPresentation: () => trayVersionPresentation,
|
|
678993
678994
|
uninstallTrayAutostart: () => uninstallTrayAutostart,
|
|
678994
678995
|
verifyTrayHelper: () => verifyTrayHelper
|
|
678995
678996
|
});
|
|
@@ -679047,6 +679048,23 @@ function trayUpdatePresentation(currentVersion, latestVersion, state = null) {
|
|
|
679047
679048
|
action: "check-update"
|
|
679048
679049
|
};
|
|
679049
679050
|
}
|
|
679051
|
+
function trayVersionPresentation(health, update2) {
|
|
679052
|
+
if (health.kind === "online" && update2.targetVersion) {
|
|
679053
|
+
const current = health.version ? `v${health.version}` : "current version";
|
|
679054
|
+
const running = !update2.enabled && update2.title.startsWith("Updating ");
|
|
679055
|
+
return {
|
|
679056
|
+
title: running ? update2.title : `Omnius ${current} — update to v${update2.targetVersion} available`,
|
|
679057
|
+
tooltip: update2.tooltip,
|
|
679058
|
+
enabled: update2.enabled,
|
|
679059
|
+
action: "update-omnius"
|
|
679060
|
+
};
|
|
679061
|
+
}
|
|
679062
|
+
return {
|
|
679063
|
+
title: health.label,
|
|
679064
|
+
tooltip: health.tooltip,
|
|
679065
|
+
enabled: false
|
|
679066
|
+
};
|
|
679067
|
+
}
|
|
679050
679068
|
function uidSuffix() {
|
|
679051
679069
|
return typeof process.getuid === "function" ? String(process.getuid()) : "user";
|
|
679052
679070
|
}
|
|
@@ -679479,7 +679497,7 @@ async function loadSysTray() {
|
|
|
679479
679497
|
return constructor;
|
|
679480
679498
|
}
|
|
679481
679499
|
function menuForHealth(health, endpoint, registered, update2) {
|
|
679482
|
-
const healthItem =
|
|
679500
|
+
const healthItem = trayVersionPresentation(health, update2);
|
|
679483
679501
|
const actionItem = {
|
|
679484
679502
|
title: health.kind === "online" ? "Restart daemon" : "Start daemon",
|
|
679485
679503
|
tooltip: health.kind === "online" ? "Restart the Omnius API daemon" : "Start the Omnius API daemon",
|
|
@@ -679501,7 +679519,8 @@ function menuForHealth(health, endpoint, registered, update2) {
|
|
|
679501
679519
|
title: update2.title,
|
|
679502
679520
|
tooltip: update2.tooltip,
|
|
679503
679521
|
enabled: update2.enabled,
|
|
679504
|
-
action: update2.action
|
|
679522
|
+
action: update2.action,
|
|
679523
|
+
hidden: Boolean(update2.targetVersion)
|
|
679505
679524
|
};
|
|
679506
679525
|
return {
|
|
679507
679526
|
healthItem,
|
|
@@ -679747,8 +679766,6 @@ async function runTrayForeground(explicitEndpoint) {
|
|
|
679747
679766
|
health = next;
|
|
679748
679767
|
state = { ...state, health };
|
|
679749
679768
|
writeProcessState(paths, state);
|
|
679750
|
-
menuState.healthItem.title = health.label;
|
|
679751
|
-
menuState.healthItem.tooltip = health.tooltip;
|
|
679752
679769
|
menuState.actionItem.title = health.kind === "online" ? "Restart daemon" : "Start daemon";
|
|
679753
679770
|
menuState.actionItem.action = health.kind === "online" ? "restart-daemon" : "start-daemon";
|
|
679754
679771
|
menuState.stopItem.enabled = health.kind === "online";
|
|
@@ -679762,6 +679779,13 @@ async function runTrayForeground(explicitEndpoint) {
|
|
|
679762
679779
|
menuState.updateItem.tooltip = updateView.tooltip;
|
|
679763
679780
|
menuState.updateItem.enabled = updateView.enabled;
|
|
679764
679781
|
menuState.updateItem.action = updateView.action;
|
|
679782
|
+
menuState.updateItem.hidden = Boolean(updateView.targetVersion);
|
|
679783
|
+
const versionView = trayVersionPresentation(health, updateView);
|
|
679784
|
+
menuState.healthItem.title = versionView.title;
|
|
679785
|
+
menuState.healthItem.tooltip = versionView.tooltip;
|
|
679786
|
+
menuState.healthItem.enabled = versionView.enabled;
|
|
679787
|
+
if (versionView.action) menuState.healthItem.action = versionView.action;
|
|
679788
|
+
else delete menuState.healthItem.action;
|
|
679765
679789
|
const autostartRegistered = existsSync117(paths.autostartFile);
|
|
679766
679790
|
const autostartChanged = menuState.autostartItem.checked !== autostartRegistered;
|
|
679767
679791
|
if (autostartChanged) menuState.autostartItem.checked = autostartRegistered;
|
|
@@ -679819,14 +679843,32 @@ async function runTrayForeground(explicitEndpoint) {
|
|
|
679819
679843
|
trayWasRunning: true
|
|
679820
679844
|
});
|
|
679821
679845
|
updateView = trayUpdatePresentation(currentVersion, targetVersion, readUpdateState());
|
|
679846
|
+
if (updateView.enabled) {
|
|
679847
|
+
updateView = {
|
|
679848
|
+
title: `Updating to v${targetVersion} — starting`,
|
|
679849
|
+
tooltip: "The global npm update transaction is starting",
|
|
679850
|
+
enabled: false,
|
|
679851
|
+
targetVersion,
|
|
679852
|
+
action: "update-omnius"
|
|
679853
|
+
};
|
|
679854
|
+
}
|
|
679855
|
+
const versionView = trayVersionPresentation(health, updateView);
|
|
679856
|
+
menuState.healthItem.title = versionView.title;
|
|
679857
|
+
menuState.healthItem.tooltip = versionView.tooltip;
|
|
679858
|
+
menuState.healthItem.enabled = versionView.enabled;
|
|
679859
|
+
menuState.healthItem.action = "update-omnius";
|
|
679822
679860
|
menuState.updateItem.title = updateView.title;
|
|
679823
679861
|
menuState.updateItem.tooltip = updateView.tooltip;
|
|
679824
679862
|
menuState.updateItem.enabled = false;
|
|
679863
|
+
menuState.updateItem.hidden = true;
|
|
679825
679864
|
} catch (error) {
|
|
679826
|
-
|
|
679827
|
-
menuState.
|
|
679828
|
-
menuState.
|
|
679865
|
+
const message2 = error instanceof Error ? error.message : String(error);
|
|
679866
|
+
menuState.healthItem.title = `Update to v${targetVersion} could not start — retry`;
|
|
679867
|
+
menuState.healthItem.tooltip = message2;
|
|
679868
|
+
menuState.healthItem.enabled = true;
|
|
679869
|
+
menuState.healthItem.action = "update-omnius";
|
|
679829
679870
|
}
|
|
679871
|
+
await tray?.sendAction({ type: "update-item", item: menuState.healthItem });
|
|
679830
679872
|
await tray?.sendAction({ type: "update-item", item: menuState.updateItem });
|
|
679831
679873
|
break;
|
|
679832
679874
|
}
|
|
@@ -679843,6 +679885,14 @@ async function runTrayForeground(explicitEndpoint) {
|
|
|
679843
679885
|
menuState.updateItem.tooltip = updateView.tooltip;
|
|
679844
679886
|
menuState.updateItem.enabled = updateView.enabled;
|
|
679845
679887
|
menuState.updateItem.action = updateView.action;
|
|
679888
|
+
menuState.updateItem.hidden = Boolean(updateView.targetVersion);
|
|
679889
|
+
const versionView = trayVersionPresentation(health, updateView);
|
|
679890
|
+
menuState.healthItem.title = versionView.title;
|
|
679891
|
+
menuState.healthItem.tooltip = versionView.tooltip;
|
|
679892
|
+
menuState.healthItem.enabled = versionView.enabled;
|
|
679893
|
+
if (versionView.action) menuState.healthItem.action = versionView.action;
|
|
679894
|
+
else delete menuState.healthItem.action;
|
|
679895
|
+
await tray?.sendAction({ type: "update-item", item: menuState.healthItem });
|
|
679846
679896
|
await tray?.sendAction({ type: "update-item", item: menuState.updateItem });
|
|
679847
679897
|
break;
|
|
679848
679898
|
}
|
|
@@ -792889,6 +792939,17 @@ var init_routes_v1 = __esm({
|
|
|
792889
792939
|
});
|
|
792890
792940
|
|
|
792891
792941
|
// packages/cli/src/api/web-ui.ts
|
|
792942
|
+
function renderRouteHeading(options2) {
|
|
792943
|
+
const signals = options2.signals.map((signal) => `<span class="route-heading__signal">${signal}</span>`).join("");
|
|
792944
|
+
return `<header class="route-heading" data-route-heading="${options2.page}">
|
|
792945
|
+
<div class="route-heading__copy">
|
|
792946
|
+
<span class="route-heading__eyebrow">${options2.eyebrow}</span>
|
|
792947
|
+
<h1 class="route-heading__title">${options2.title}</h1>
|
|
792948
|
+
<p class="route-heading__description">${options2.description}</p>
|
|
792949
|
+
</div>
|
|
792950
|
+
<div class="route-heading__signals" aria-label="Visible operational areas">${signals}</div>
|
|
792951
|
+
</header>`;
|
|
792952
|
+
}
|
|
792892
792953
|
function getWebUI() {
|
|
792893
792954
|
return `<!DOCTYPE html>
|
|
792894
792955
|
<html lang="en">
|
|
@@ -794986,6 +795047,303 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
794986
795047
|
}
|
|
794987
795048
|
*::-webkit-scrollbar-thumb:hover { background: var(--nclp-yellow); }
|
|
794988
795049
|
|
|
795050
|
+
/* Shared route composition. This carries the useful six-track command-center
|
|
795051
|
+
* grammar from the Voryn persona/call-tree surfaces while keeping Omnius's
|
|
795052
|
+
* existing NOCLIP palette, compact density, and 3px geometry authoritative. */
|
|
795053
|
+
[data-route-page] {
|
|
795054
|
+
min-width: 0;
|
|
795055
|
+
background: var(--nclp-bg-main) !important;
|
|
795056
|
+
}
|
|
795057
|
+
|
|
795058
|
+
.omnius-route-shell {
|
|
795059
|
+
padding: 12px 16px !important;
|
|
795060
|
+
}
|
|
795061
|
+
|
|
795062
|
+
.route-heading {
|
|
795063
|
+
display: grid;
|
|
795064
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
795065
|
+
align-items: end;
|
|
795066
|
+
gap: 12px;
|
|
795067
|
+
margin-bottom: 12px;
|
|
795068
|
+
padding-bottom: 10px;
|
|
795069
|
+
border-bottom: 1px solid var(--nclp-line);
|
|
795070
|
+
min-width: 0;
|
|
795071
|
+
}
|
|
795072
|
+
|
|
795073
|
+
.route-heading__copy { min-width: 0; }
|
|
795074
|
+
.route-heading__eyebrow {
|
|
795075
|
+
display: block;
|
|
795076
|
+
margin-bottom: 3px;
|
|
795077
|
+
color: var(--nclp-yellow);
|
|
795078
|
+
font-size: 9px;
|
|
795079
|
+
font-weight: 800;
|
|
795080
|
+
letter-spacing: 0.14em;
|
|
795081
|
+
text-transform: uppercase;
|
|
795082
|
+
}
|
|
795083
|
+
.route-heading__title {
|
|
795084
|
+
margin: 0 !important;
|
|
795085
|
+
color: var(--nclp-text) !important;
|
|
795086
|
+
font-size: 15px !important;
|
|
795087
|
+
letter-spacing: 0.02em !important;
|
|
795088
|
+
text-transform: none !important;
|
|
795089
|
+
}
|
|
795090
|
+
.route-heading__description {
|
|
795091
|
+
max-width: 760px;
|
|
795092
|
+
margin: 4px 0 0;
|
|
795093
|
+
color: var(--nclp-muted);
|
|
795094
|
+
font-size: 11px;
|
|
795095
|
+
line-height: 1.45;
|
|
795096
|
+
}
|
|
795097
|
+
.route-heading__signals {
|
|
795098
|
+
display: flex;
|
|
795099
|
+
flex-wrap: wrap;
|
|
795100
|
+
justify-content: flex-end;
|
|
795101
|
+
gap: 5px;
|
|
795102
|
+
}
|
|
795103
|
+
.route-heading__signal,
|
|
795104
|
+
.observability-chip {
|
|
795105
|
+
border: 1px solid var(--nclp-line);
|
|
795106
|
+
border-radius: var(--radius-sm);
|
|
795107
|
+
background: var(--nclp-bg-secondary);
|
|
795108
|
+
color: var(--nclp-muted);
|
|
795109
|
+
padding: 3px 6px;
|
|
795110
|
+
font-size: 9px;
|
|
795111
|
+
font-weight: 700;
|
|
795112
|
+
letter-spacing: 0.06em;
|
|
795113
|
+
text-transform: uppercase;
|
|
795114
|
+
white-space: nowrap;
|
|
795115
|
+
}
|
|
795116
|
+
|
|
795117
|
+
.observability-grid {
|
|
795118
|
+
display: grid;
|
|
795119
|
+
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
795120
|
+
gap: 12px;
|
|
795121
|
+
min-width: 0;
|
|
795122
|
+
align-items: start;
|
|
795123
|
+
}
|
|
795124
|
+
.observability-card {
|
|
795125
|
+
position: relative;
|
|
795126
|
+
min-width: 0;
|
|
795127
|
+
overflow: hidden;
|
|
795128
|
+
border: 1px solid var(--nclp-line);
|
|
795129
|
+
border-radius: var(--radius-lg);
|
|
795130
|
+
background: var(--nclp-card);
|
|
795131
|
+
box-shadow: var(--nclp-shadow);
|
|
795132
|
+
}
|
|
795133
|
+
.observability-card::before {
|
|
795134
|
+
content: "";
|
|
795135
|
+
position: absolute;
|
|
795136
|
+
z-index: 2;
|
|
795137
|
+
top: 0;
|
|
795138
|
+
left: 0;
|
|
795139
|
+
width: 38px;
|
|
795140
|
+
height: 2px;
|
|
795141
|
+
background: var(--nclp-yellow);
|
|
795142
|
+
pointer-events: none;
|
|
795143
|
+
}
|
|
795144
|
+
.observability-card__header {
|
|
795145
|
+
display: grid;
|
|
795146
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
795147
|
+
align-items: center;
|
|
795148
|
+
gap: 10px;
|
|
795149
|
+
min-width: 0;
|
|
795150
|
+
padding: 10px 12px 8px;
|
|
795151
|
+
border-bottom: 1px solid var(--nclp-line);
|
|
795152
|
+
}
|
|
795153
|
+
.observability-card__title {
|
|
795154
|
+
min-width: 0;
|
|
795155
|
+
margin: 0 !important;
|
|
795156
|
+
color: var(--nclp-text) !important;
|
|
795157
|
+
font-size: 10px !important;
|
|
795158
|
+
letter-spacing: 0.1em !important;
|
|
795159
|
+
text-transform: uppercase !important;
|
|
795160
|
+
}
|
|
795161
|
+
.observability-card__meta {
|
|
795162
|
+
overflow: hidden;
|
|
795163
|
+
color: var(--nclp-quiet);
|
|
795164
|
+
font-size: 9px;
|
|
795165
|
+
text-overflow: ellipsis;
|
|
795166
|
+
white-space: nowrap;
|
|
795167
|
+
}
|
|
795168
|
+
.observability-card__body {
|
|
795169
|
+
min-width: 0;
|
|
795170
|
+
padding: 11px 12px 12px;
|
|
795171
|
+
}
|
|
795172
|
+
.observability-card__body--flush { padding: 0; }
|
|
795173
|
+
.observability-span-2 { grid-column: span 2; }
|
|
795174
|
+
.observability-span-3 { grid-column: span 3; }
|
|
795175
|
+
.observability-span-4 { grid-column: span 4; }
|
|
795176
|
+
.observability-span-6 { grid-column: 1 / -1; }
|
|
795177
|
+
|
|
795178
|
+
.observability-facts {
|
|
795179
|
+
display: grid;
|
|
795180
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
795181
|
+
gap: 7px;
|
|
795182
|
+
min-width: 0;
|
|
795183
|
+
}
|
|
795184
|
+
.observability-facts > * {
|
|
795185
|
+
min-width: 0;
|
|
795186
|
+
margin: 0 !important;
|
|
795187
|
+
}
|
|
795188
|
+
.observability-stack {
|
|
795189
|
+
display: grid;
|
|
795190
|
+
gap: 7px;
|
|
795191
|
+
min-width: 0;
|
|
795192
|
+
}
|
|
795193
|
+
.observability-actions {
|
|
795194
|
+
display: flex;
|
|
795195
|
+
flex-wrap: wrap;
|
|
795196
|
+
align-items: center;
|
|
795197
|
+
gap: 7px;
|
|
795198
|
+
}
|
|
795199
|
+
.observability-actions > :is(input, select, textarea) { min-width: 0; }
|
|
795200
|
+
.observability-table-scroll { overflow-x: auto; overscroll-behavior-inline: contain; }
|
|
795201
|
+
|
|
795202
|
+
.route-workspace {
|
|
795203
|
+
display: flex;
|
|
795204
|
+
flex: 1;
|
|
795205
|
+
min-width: 0;
|
|
795206
|
+
min-height: 0;
|
|
795207
|
+
overflow: hidden;
|
|
795208
|
+
}
|
|
795209
|
+
.route-workspace__main {
|
|
795210
|
+
display: flex;
|
|
795211
|
+
flex: 1;
|
|
795212
|
+
flex-direction: column;
|
|
795213
|
+
min-width: 0;
|
|
795214
|
+
min-height: 0;
|
|
795215
|
+
overflow: hidden;
|
|
795216
|
+
}
|
|
795217
|
+
.route-scroll-region {
|
|
795218
|
+
min-width: 0;
|
|
795219
|
+
min-height: 0;
|
|
795220
|
+
overflow: auto;
|
|
795221
|
+
}
|
|
795222
|
+
.agent-command-body { padding: 11px 12px 12px; }
|
|
795223
|
+
.agent-command-body #agent-params { margin: 0; border: 0; background: transparent; }
|
|
795224
|
+
.agent-task-input { min-height: 120px !important; margin: 0 !important; }
|
|
795225
|
+
.agent-events-surface { min-height: 180px; }
|
|
795226
|
+
|
|
795227
|
+
.workspace-switcher { position: relative; flex: 1; min-width: 0; }
|
|
795228
|
+
.workspace-switcher__trigger {
|
|
795229
|
+
display: grid !important;
|
|
795230
|
+
grid-template-columns: 9px minmax(0, 1fr) 12px;
|
|
795231
|
+
align-items: center;
|
|
795232
|
+
gap: 8px;
|
|
795233
|
+
width: 100%;
|
|
795234
|
+
min-width: 0;
|
|
795235
|
+
padding: 5px 7px !important;
|
|
795236
|
+
text-align: left;
|
|
795237
|
+
}
|
|
795238
|
+
#sidebar-brand {
|
|
795239
|
+
overflow: hidden;
|
|
795240
|
+
color: var(--nclp-text) !important;
|
|
795241
|
+
font-size: 11px !important;
|
|
795242
|
+
letter-spacing: 0.01em !important;
|
|
795243
|
+
text-overflow: ellipsis;
|
|
795244
|
+
text-transform: none !important;
|
|
795245
|
+
white-space: nowrap;
|
|
795246
|
+
}
|
|
795247
|
+
.workspace-switcher__chevron { color: var(--nclp-quiet); transition: transform 0.14s ease; }
|
|
795248
|
+
.workspace-switcher__trigger[aria-expanded="true"] .workspace-switcher__chevron { transform: rotate(180deg); }
|
|
795249
|
+
.workspace-picker {
|
|
795250
|
+
position: absolute;
|
|
795251
|
+
z-index: 80;
|
|
795252
|
+
top: calc(100% + 6px);
|
|
795253
|
+
left: 0;
|
|
795254
|
+
width: min(420px, calc(100vw - 24px));
|
|
795255
|
+
max-height: min(520px, 72vh);
|
|
795256
|
+
overflow: hidden;
|
|
795257
|
+
border: 1px solid var(--nclp-line-strong);
|
|
795258
|
+
border-radius: var(--radius-lg);
|
|
795259
|
+
background: var(--nclp-card);
|
|
795260
|
+
box-shadow: 0 22px 56px rgba(0, 0, 0, 0.48);
|
|
795261
|
+
}
|
|
795262
|
+
.workspace-picker__header { padding: 10px; border-bottom: 1px solid var(--nclp-line); }
|
|
795263
|
+
.workspace-picker__header input { width: 100%; padding: 7px 9px; }
|
|
795264
|
+
.workspace-picker__list {
|
|
795265
|
+
display: grid;
|
|
795266
|
+
gap: 3px;
|
|
795267
|
+
max-height: 42vh;
|
|
795268
|
+
overflow-y: auto;
|
|
795269
|
+
padding: 6px;
|
|
795270
|
+
overscroll-behavior: contain;
|
|
795271
|
+
}
|
|
795272
|
+
.workspace-picker__option {
|
|
795273
|
+
display: grid !important;
|
|
795274
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
795275
|
+
align-items: center;
|
|
795276
|
+
gap: 10px;
|
|
795277
|
+
width: 100%;
|
|
795278
|
+
padding: 8px 9px !important;
|
|
795279
|
+
text-align: left;
|
|
795280
|
+
text-transform: none !important;
|
|
795281
|
+
}
|
|
795282
|
+
.workspace-picker__option[aria-selected="true"] {
|
|
795283
|
+
border-color: var(--nclp-yellow) !important;
|
|
795284
|
+
background: var(--nclp-amber-soft) !important;
|
|
795285
|
+
}
|
|
795286
|
+
.workspace-picker__option.is-keyboard-active {
|
|
795287
|
+
border-color: var(--nclp-yellow) !important;
|
|
795288
|
+
color: var(--nclp-yellow) !important;
|
|
795289
|
+
}
|
|
795290
|
+
.workspace-picker__name,
|
|
795291
|
+
.workspace-picker__path { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
795292
|
+
.workspace-picker__name { color: var(--nclp-text); font-size: 11px; font-weight: 700; }
|
|
795293
|
+
.workspace-picker__path { margin-top: 2px; color: var(--nclp-quiet); font-size: 9px; font-weight: 500; }
|
|
795294
|
+
.workspace-picker__check { color: var(--nclp-yellow); }
|
|
795295
|
+
.workspace-picker__empty { padding: 18px 10px; color: var(--nclp-quiet); font-size: 10px; text-align: center; }
|
|
795296
|
+
.workspace-picker__footer { display: flex; justify-content: flex-end; padding: 7px 9px; border-top: 1px solid var(--nclp-line); }
|
|
795297
|
+
#omnius-sidebar[data-collapsed="true"] .workspace-switcher { display: none; }
|
|
795298
|
+
|
|
795299
|
+
/* Generate keeps its purpose-built rails, but uses the same six-track span
|
|
795300
|
+
* proportions as the overview grids: 1/6 controls, 3/6 work, 2/6 signal. */
|
|
795301
|
+
.hud-workbench[data-layout="generate-workbench"] {
|
|
795302
|
+
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
795303
|
+
}
|
|
795304
|
+
.hud-workbench[data-layout="generate-workbench"] > #gen-mode-rail { grid-column: span 1; }
|
|
795305
|
+
.hud-workbench[data-layout="generate-workbench"] > main { grid-column: span 3; min-width: 0; }
|
|
795306
|
+
.hud-workbench[data-layout="generate-workbench"] > .hud-side-output { grid-column: span 2; min-width: 0; }
|
|
795307
|
+
|
|
795308
|
+
@media (max-width: 1180px) {
|
|
795309
|
+
.hud-workbench[data-layout="generate-workbench"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
795310
|
+
.hud-workbench[data-layout="generate-workbench"] > #gen-mode-rail,
|
|
795311
|
+
.hud-workbench[data-layout="generate-workbench"] > main { grid-column: span 1; }
|
|
795312
|
+
.hud-workbench[data-layout="generate-workbench"] > .hud-side-output { grid-column: 1 / -1; }
|
|
795313
|
+
}
|
|
795314
|
+
|
|
795315
|
+
@media (max-width: 820px) {
|
|
795316
|
+
.hud-workbench[data-layout="generate-workbench"] { grid-template-columns: minmax(0, 1fr); }
|
|
795317
|
+
.hud-workbench[data-layout="generate-workbench"] > #gen-mode-rail,
|
|
795318
|
+
.hud-workbench[data-layout="generate-workbench"] > main,
|
|
795319
|
+
.hud-workbench[data-layout="generate-workbench"] > .hud-side-output { grid-column: 1; }
|
|
795320
|
+
}
|
|
795321
|
+
|
|
795322
|
+
@media (max-width: 920px) {
|
|
795323
|
+
.observability-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
795324
|
+
.observability-span-2,
|
|
795325
|
+
.observability-span-3 { grid-column: span 1; }
|
|
795326
|
+
.observability-span-4,
|
|
795327
|
+
.observability-span-6 { grid-column: 1 / -1; }
|
|
795328
|
+
.observability-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
795329
|
+
}
|
|
795330
|
+
|
|
795331
|
+
@media (max-width: 760px) {
|
|
795332
|
+
.omnius-route-shell { padding: 10px !important; }
|
|
795333
|
+
.route-heading { grid-template-columns: 1fr; align-items: start; }
|
|
795334
|
+
.route-heading__signals { justify-content: flex-start; }
|
|
795335
|
+
.observability-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
|
|
795336
|
+
.observability-span-2,
|
|
795337
|
+
.observability-span-3,
|
|
795338
|
+
.observability-span-4,
|
|
795339
|
+
.observability-span-6 { grid-column: 1; }
|
|
795340
|
+
.observability-facts { grid-template-columns: minmax(0, 1fr); }
|
|
795341
|
+
.observability-card__header { grid-template-columns: minmax(0, 1fr); }
|
|
795342
|
+
.observability-card__meta { white-space: normal; }
|
|
795343
|
+
.observability-actions > :is(button, input, select) { max-width: 100%; }
|
|
795344
|
+
.workspace-picker { position: fixed; top: 54px; right: 12px; left: 12px; width: auto; }
|
|
795345
|
+
}
|
|
795346
|
+
|
|
794989
795347
|
@media (prefers-reduced-motion: reduce) {
|
|
794990
795348
|
*, *::before, *::after {
|
|
794991
795349
|
animation-duration: 0.01ms !important;
|
|
@@ -795014,8 +795372,22 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795014
795372
|
<button id="sidebar-toggle" onclick="toggleSidebar()" title="Toggle sidebar (Cmd/Ctrl+B)" style="background:transparent;border:none;color:var(--color-fg-muted);padding:4px;border-radius:var(--radius-sm);cursor:pointer;display:flex;align-items:center;justify-content:center;width:28px;height:28px">
|
|
795015
795373
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M9 3v18"/></svg>
|
|
795016
795374
|
</button>
|
|
795017
|
-
<
|
|
795018
|
-
|
|
795375
|
+
<div class="workspace-switcher">
|
|
795376
|
+
<button id="workspace-switcher-trigger" class="workspace-switcher__trigger" type="button" aria-haspopup="dialog" aria-expanded="false" aria-controls="workspace-picker" onclick="toggleWorkspacePicker(event)" title="Switch workspace">
|
|
795377
|
+
<span id="sidebar-brand-dot" title="Connection status" style="width:9px;height:9px;border-radius:999px;background:#f59e0b;box-shadow:0 0 0 2px rgba(245,158,11,.16);flex:0 0 auto"></span>
|
|
795378
|
+
<span id="sidebar-brand">No project</span>
|
|
795379
|
+
<svg class="workspace-switcher__chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
|
|
795380
|
+
</button>
|
|
795381
|
+
<section id="workspace-picker" class="workspace-picker" role="dialog" aria-label="Select workspace" style="display:none">
|
|
795382
|
+
<div class="workspace-picker__header">
|
|
795383
|
+
<input id="workspace-picker-search" type="search" placeholder="Filter workspaces..." autocomplete="off" aria-label="Filter workspaces" oninput="filterWorkspacePicker(this.value)" onkeydown="handleWorkspacePickerKeys(event)">
|
|
795384
|
+
</div>
|
|
795385
|
+
<div id="workspace-picker-list" class="workspace-picker__list" role="listbox" aria-label="Available workspaces"></div>
|
|
795386
|
+
<div class="workspace-picker__footer">
|
|
795387
|
+
<button type="button" onclick="closeWorkspacePicker(); switchTab('projects')">Manage workspaces</button>
|
|
795388
|
+
</div>
|
|
795389
|
+
</section>
|
|
795390
|
+
</div>
|
|
795019
795391
|
</div>
|
|
795020
795392
|
|
|
795021
795393
|
<!-- New chat button -->
|
|
@@ -795051,35 +795423,35 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795051
795423
|
|
|
795052
795424
|
<!-- Section nav (the legacy tabs migrated into the sidebar footer) -->
|
|
795053
795425
|
<div id="sidebar-nav" class="sb-label" style="border-top:1px solid var(--color-border);padding:8px;display:flex;flex-direction:column;gap:2px">
|
|
795054
|
-
<button class="sb-nav" data-tab="chat"
|
|
795426
|
+
<button class="sb-nav" data-tab="chat" data-route="/chat" aria-controls="chat-container" aria-current="page" onclick="switchTab('chat')" title="Chat">
|
|
795055
795427
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
|
|
795056
795428
|
<span class="sb-label">Chat</span>
|
|
795057
795429
|
</button>
|
|
795058
|
-
<button class="sb-nav" data-tab="agent"
|
|
795430
|
+
<button class="sb-nav" data-tab="agent" data-route="/agent" aria-controls="agent-panel" onclick="switchTab('agent')" title="Agent">
|
|
795059
795431
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2 4 7v10l8 5 8-5V7l-8-5z"/><path d="M12 22V12"/><path d="m4 7 8 5 8-5"/></svg>
|
|
795060
795432
|
<span class="sb-label">Agent</span>
|
|
795061
795433
|
</button>
|
|
795062
|
-
<button class="sb-nav" data-tab="voice"
|
|
795434
|
+
<button class="sb-nav" data-tab="voice" data-route="/voice" aria-controls="voice-panel" onclick="switchTab('voice')" title="Voice">
|
|
795063
795435
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>
|
|
795064
795436
|
<span class="sb-label">Voice</span>
|
|
795065
795437
|
</button>
|
|
795066
|
-
<button class="sb-nav" data-tab="generate" onclick="switchTab('generate')" title="Generate media">
|
|
795438
|
+
<button class="sb-nav" data-tab="generate" data-route="/generate" aria-controls="generate-panel" onclick="switchTab('generate')" title="Generate media">
|
|
795067
795439
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
|
|
795068
795440
|
<span class="sb-label">Generate</span>
|
|
795069
795441
|
</button>
|
|
795070
|
-
<button class="sb-nav" data-tab="projects" onclick="switchTab('projects')" title="Projects">
|
|
795442
|
+
<button class="sb-nav" data-tab="projects" data-route="/projects" aria-controls="projects-panel" onclick="switchTab('projects')" title="Projects">
|
|
795071
795443
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
|
|
795072
795444
|
<span class="sb-label">Projects</span>
|
|
795073
795445
|
</button>
|
|
795074
|
-
<button class="sb-nav" data-tab="jobs"
|
|
795446
|
+
<button class="sb-nav" data-tab="jobs" data-route="/dashboard" aria-controls="jobs-panel" onclick="switchTab('jobs')" title="Dashboard">
|
|
795075
795447
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="9"/><rect x="14" y="3" width="7" height="5"/><rect x="14" y="12" width="7" height="9"/><rect x="3" y="16" width="7" height="5"/></svg>
|
|
795076
795448
|
<span class="sb-label">Dashboard</span>
|
|
795077
795449
|
</button>
|
|
795078
|
-
<button class="sb-nav" data-tab="activity" onclick="switchTab('activity')" title="Activity">
|
|
795450
|
+
<button class="sb-nav" data-tab="activity" data-route="/activity" aria-controls="activity-panel" onclick="switchTab('activity')" title="Activity">
|
|
795079
795451
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
|
|
795080
795452
|
<span class="sb-label">Activity</span>
|
|
795081
795453
|
</button>
|
|
795082
|
-
<button class="sb-nav" data-tab="config"
|
|
795454
|
+
<button class="sb-nav" data-tab="config" data-route="/settings" aria-controls="config-panel" onclick="switchTab('config')" title="Settings">
|
|
795083
795455
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
|
|
795084
795456
|
<span class="sb-label">Settings</span>
|
|
795085
795457
|
</button>
|
|
@@ -795105,8 +795477,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795105
795477
|
<div id="omnius-main" style="flex:1;display:flex;flex-direction:column;min-width:0;overflow:hidden;background:var(--color-bg)">
|
|
795106
795478
|
|
|
795107
795479
|
<div id="header">
|
|
795108
|
-
<span class="
|
|
795109
|
-
<span class="status" id="status">connecting...</span>
|
|
795480
|
+
<span class="status" id="status" aria-live="polite" style="display:none">connecting...</span>
|
|
795110
795481
|
<span id="update-btn" style="display:none;background:#0f3f3d;border:1px solid var(--color-brand);color:var(--color-brand);padding:2px 8px;border-radius:3px;font-family:inherit;font-size:0.6rem;cursor:pointer" onclick="doUpdate()">update</span>
|
|
795111
795482
|
<select id="model-select"><option>loading...</option></select>
|
|
795112
795483
|
<button class="key-btn" id="files-btn" onclick="toggleFilesForActiveTab()" title="Toggle workspace sidebar (chat or agent depending on active tab)">files</button>
|
|
@@ -795148,7 +795519,9 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795148
795519
|
<span id="token-counter" style="font-size:0.6rem;color:var(--color-fg-faint);display:flex;flex-flow:column;justify-content:center;padding:0 6px">0 tokens</span>
|
|
795149
795520
|
</div>
|
|
795150
795521
|
</div>
|
|
795151
|
-
<div id="chat-container" style="display:flex;flex:1;overflow:hidden">
|
|
795522
|
+
<div id="chat-container" class="omnius-route-shell" data-route-page="chat" data-route-tab="chat" style="display:flex;flex:1;overflow:hidden;flex-direction:column">
|
|
795523
|
+
${renderRouteHeading({ page: "chat", eyebrow: "Conversation", title: "Chat workspace", description: "Keep the active session, execution plan, workspace context, and conversation visible as one operational surface.", signals: ["session", "plan", "live context"] })}
|
|
795524
|
+
<div class="route-workspace" data-layout="chat-split">
|
|
795152
795525
|
<div id="workspace-sidebar" style="display:none;width:250px;background:var(--color-bg-elevated);border-right:1px solid var(--color-bg-input);overflow-y:auto;padding:8px;flex-shrink:0;font-size:0.7rem">
|
|
795153
795526
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
|
795154
795527
|
<span style="color:var(--color-brand);font-size:0.7rem;font-weight:bold">Workspace</span>
|
|
@@ -795158,7 +795531,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795158
795531
|
<div id="workspace-tree" style="color:var(--color-fg)"></div>
|
|
795159
795532
|
</div>
|
|
795160
795533
|
<!-- Vertical column: session topbar + checklist + conversation -->
|
|
795161
|
-
<div
|
|
795534
|
+
<div class="route-workspace__main">
|
|
795162
795535
|
<!-- WO-TASK-02 — Chat session topbar (separate storage from agent runs) -->
|
|
795163
795536
|
<div class="session-topbar" id="chat-session-topbar">
|
|
795164
795537
|
<span class="topbar-label">chat session</span>
|
|
@@ -795175,8 +795548,10 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795175
795548
|
</div>
|
|
795176
795549
|
<div id="conversation" style="flex:1;overflow-y:auto;padding:12px 16px;display:flex;flex-direction:column;gap:4px;min-height:0"></div>
|
|
795177
795550
|
</div>
|
|
795551
|
+
</div>
|
|
795178
795552
|
</div>
|
|
795179
|
-
<div id="agent-panel" style="display:none;flex:1;overflow:hidden;flex-direction:column">
|
|
795553
|
+
<div id="agent-panel" class="omnius-route-shell" data-route-page="agent" data-route-tab="agent" style="display:none;flex:1;overflow:hidden;flex-direction:column">
|
|
795554
|
+
${renderRouteHeading({ page: "agent", eyebrow: "Execution", title: "Agent command center", description: "Define the task contract, inspect the run configuration, and follow the event stream without losing workspace context.", signals: ["task contract", "run profile", "event stream"] })}
|
|
795180
795555
|
<!-- WO-TASK-02 — Agent run topbar (separate storage from chat sessions) -->
|
|
795181
795556
|
<div class="session-topbar" id="agent-session-topbar">
|
|
795182
795557
|
<span class="topbar-label">agent run</span>
|
|
@@ -795188,7 +795563,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795188
795563
|
<button onclick="refreshAgentRunSelect()" title="Refresh the run list">⟳</button>
|
|
795189
795564
|
</div>
|
|
795190
795565
|
<!-- Body row: agent workspace sidebar (isolated from chat) | scrollable form -->
|
|
795191
|
-
<div
|
|
795566
|
+
<div class="route-workspace" data-layout="agent-form">
|
|
795192
795567
|
<div id="agent-workspace-sidebar" style="display:none;width:250px;background:var(--color-bg-elevated);border-right:1px solid var(--color-bg-input);overflow-y:auto;padding:8px;flex-shrink:0;font-size:0.7rem">
|
|
795193
795568
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
|
795194
795569
|
<span style="color:var(--color-brand);font-size:0.7rem;font-weight:bold">Agent Workspace</span>
|
|
@@ -795197,10 +795572,12 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795197
795572
|
<div id="agent-workspace-cwd" style="color:var(--color-fg-faint);font-size:0.6rem;margin-bottom:8px;word-break:break-all"></div>
|
|
795198
795573
|
<div id="agent-workspace-tree" style="color:var(--color-fg)"></div>
|
|
795199
795574
|
</div>
|
|
795200
|
-
<div style="flex:1;
|
|
795575
|
+
<div class="route-scroll-region" style="flex:1;padding:0 0 4px;">
|
|
795576
|
+
<div class="observability-grid">
|
|
795201
795577
|
<!-- Parameter form: all the dials for POST /v1/run -->
|
|
795202
|
-
<
|
|
795203
|
-
<
|
|
795578
|
+
<section class="observability-card observability-span-4" data-module="agent-parameters">
|
|
795579
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Run configuration</h2><span class="observability-card__meta">POST /v1/run</span></header>
|
|
795580
|
+
<div id="agent-params" class="observability-card__body agent-command-body" style="font-size:0.68rem">
|
|
795204
795581
|
<div style="display:grid;grid-template-columns:120px 1fr;gap:6px 12px;align-items:center">
|
|
795205
795582
|
<label style="color:var(--color-fg-muted)">Working dir</label>
|
|
795206
795583
|
<div style="display:flex;gap:4px;align-items:center">
|
|
@@ -795231,36 +795608,75 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795231
795608
|
<label style="color:var(--color-fg-muted)">Isolate workspace</label>
|
|
795232
795609
|
<div><input type="checkbox" id="agent-isolate" style="accent-color:var(--color-brand)"> <span style="color:var(--color-fg-faint);font-size:0.6rem">fresh temp dir per run</span></div>
|
|
795233
795610
|
</div>
|
|
795234
|
-
|
|
795611
|
+
</div>
|
|
795612
|
+
</section>
|
|
795235
795613
|
|
|
795236
|
-
<
|
|
795237
|
-
|
|
795614
|
+
<section class="observability-card observability-span-2" data-module="agent-task-contract">
|
|
795615
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Task contract</h2><span class="observability-card__meta">persona + controls</span></header>
|
|
795616
|
+
<div class="observability-card__body observability-stack">
|
|
795617
|
+
<textarea id="agent-task" class="agent-task-input" placeholder="Describe the task for the agent..." style="width:100%;background:var(--color-bg-input);border:1px solid var(--color-border);border-radius:3px;padding:8px 12px;color:var(--color-fg);font-family:inherit;font-size:0.82rem;resize:vertical;outline:none"></textarea>
|
|
795618
|
+
<div class="observability-actions">
|
|
795238
795619
|
<select id="agent-profile" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:4px 8px;border-radius:3px;font-family:inherit;font-size:0.7rem"><option value="">no profile</option></select>
|
|
795239
795620
|
<button onclick="submitAgentTask()" id="agent-submit" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-brand);padding:6px 16px;border-radius:3px;font-family:inherit;font-size:0.75rem;cursor:pointer">run task</button>
|
|
795240
795621
|
<button onclick="abortAgentTask()" id="agent-abort" style="display:none;background:var(--color-bg-input);border:1px solid var(--color-error);color:var(--color-error);padding:6px 16px;border-radius:3px;font-family:inherit;font-size:0.75rem;cursor:pointer">abort</button>
|
|
795241
795622
|
</div>
|
|
795242
|
-
|
|
795623
|
+
</div>
|
|
795624
|
+
</section>
|
|
795625
|
+
|
|
795626
|
+
<section class="observability-card observability-span-6" data-module="agent-event-stream">
|
|
795627
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Event stream</h2><span class="observability-card__meta">tools · stdout · completion</span></header>
|
|
795628
|
+
<div id="agent-events" class="observability-card__body agent-events-surface" style="font-size:0.78rem;line-height:1.5"></div>
|
|
795629
|
+
</section>
|
|
795630
|
+
</div>
|
|
795243
795631
|
</div><!-- /scrollable agent body -->
|
|
795244
795632
|
</div><!-- /agent body row (sidebar | form) -->
|
|
795245
795633
|
</div>
|
|
795246
|
-
<div id="jobs-panel" style="display:none;flex:1;overflow-y:auto
|
|
795247
|
-
|
|
795248
|
-
<div
|
|
795249
|
-
|
|
795250
|
-
|
|
795251
|
-
|
|
795252
|
-
|
|
795253
|
-
|
|
795634
|
+
<div id="jobs-panel" class="omnius-route-shell" data-route-page="dashboard" data-route-tab="jobs" style="display:none;flex:1;overflow-y:auto">
|
|
795635
|
+
${renderRouteHeading({ page: "dashboard", eyebrow: "Operations", title: "System dashboard", description: "Health, active execution, scheduled automation, services, usage, and job history share one scan-friendly command grid.", signals: ["health", "daemons", "usage", "history"] })}
|
|
795636
|
+
<div class="observability-grid" data-layout="dashboard-metrics">
|
|
795637
|
+
<section class="observability-card observability-span-6" data-module="runtime-health">
|
|
795638
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Runtime health</h2><span class="observability-card__meta">live daemon telemetry</span></header>
|
|
795639
|
+
<div id="dashboard-health" class="observability-card__body observability-facts"></div>
|
|
795640
|
+
</section>
|
|
795641
|
+
<section class="observability-card observability-span-2" data-module="active-processes">
|
|
795642
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Active processes</h2><span class="observability-card__meta">agent runs</span></header>
|
|
795643
|
+
<div id="dashboard-daemons" class="observability-card__body"></div>
|
|
795644
|
+
</section>
|
|
795645
|
+
<section class="observability-card observability-span-4" data-module="scheduled-tasks">
|
|
795646
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Scheduled tasks</h2><span class="observability-card__meta">automation control</span></header>
|
|
795647
|
+
<div id="dashboard-scheduled" class="observability-card__body"></div>
|
|
795648
|
+
</section>
|
|
795649
|
+
<section class="observability-card observability-span-3" data-module="services">
|
|
795650
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Services</h2><span class="observability-card__meta">systemd --user</span></header>
|
|
795651
|
+
<div id="dashboard-services" class="observability-card__body"></div>
|
|
795652
|
+
</section>
|
|
795653
|
+
<section class="observability-card observability-span-3" data-module="token-usage">
|
|
795654
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Token usage</h2><span class="observability-card__meta">persistent by provider</span></header>
|
|
795655
|
+
<div id="dashboard-usage" class="observability-card__body"></div>
|
|
795656
|
+
</section>
|
|
795657
|
+
<section class="observability-card observability-span-6" data-module="job-history">
|
|
795658
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Job history</h2><span class="observability-card__meta">latest 20 runs</span></header>
|
|
795659
|
+
<div class="observability-card__body observability-table-scroll"><div id="jobs-list" style="font-size:0.78rem"></div></div>
|
|
795660
|
+
</section>
|
|
795661
|
+
</div>
|
|
795254
795662
|
</div>
|
|
795255
|
-
<div id="config-panel" style="display:none;flex:1;overflow-y:auto
|
|
795256
|
-
|
|
795257
|
-
<div
|
|
795258
|
-
<
|
|
795259
|
-
|
|
795663
|
+
<div id="config-panel" class="omnius-route-shell" data-route-page="settings" data-route-tab="config" style="display:none;flex:1;overflow-y:auto">
|
|
795664
|
+
${renderRouteHeading({ page: "settings", eyebrow: "Control plane", title: "Settings", description: "Inspect daemon configuration, choose models and providers, manage profiles, and export session data from one modular surface.", signals: ["runtime", "models", "providers", "profiles"] })}
|
|
795665
|
+
<div class="observability-grid" data-layout="config-form">
|
|
795666
|
+
<section class="observability-card observability-span-2" data-module="server-configuration">
|
|
795667
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Server configuration</h2><span class="observability-card__meta">read only</span></header>
|
|
795668
|
+
<div id="config-content" class="observability-card__body" style="font-size:0.78rem"></div>
|
|
795669
|
+
</section>
|
|
795670
|
+
<section class="observability-card observability-span-4" data-module="active-model">
|
|
795671
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Model</h2><span class="observability-card__meta">active inference target</span></header>
|
|
795672
|
+
<div class="observability-card__body observability-actions">
|
|
795260
795673
|
<select id="config-model-select" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:4px 8px;border-radius:3px;font-family:inherit;font-size:0.7rem;flex:1"></select>
|
|
795261
795674
|
<button onclick="switchModel()" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-brand);padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">switch</button>
|
|
795262
|
-
|
|
795263
|
-
|
|
795675
|
+
</div>
|
|
795676
|
+
</section>
|
|
795677
|
+
<section class="observability-card observability-span-6" data-module="inference-provider">
|
|
795678
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Inference provider</h2><span class="observability-card__meta">connection + authentication</span></header>
|
|
795679
|
+
<div class="observability-card__body">
|
|
795264
795680
|
<div id="config-endpoint" style="font-size:0.78rem;color:var(--color-fg-muted);margin-bottom:8px"></div>
|
|
795265
795681
|
<div id="config-recent-providers-section" style="display:none;margin-bottom:12px">
|
|
795266
795682
|
<div style="font-size:0.66rem;color:var(--color-fg-muted);margin-bottom:6px;font-weight:500">Previously connected</div>
|
|
@@ -795276,48 +795692,71 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795276
795692
|
</select>
|
|
795277
795693
|
<button type="submit" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-brand);padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">set</button>
|
|
795278
795694
|
</form>
|
|
795279
|
-
|
|
795280
|
-
|
|
795281
|
-
<
|
|
795282
|
-
|
|
795695
|
+
</div>
|
|
795696
|
+
</section>
|
|
795697
|
+
<section class="observability-card observability-span-3" data-module="agent-profiles">
|
|
795698
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Profiles</h2><span class="observability-card__meta">agent personas</span></header>
|
|
795699
|
+
<div id="config-profiles" class="observability-card__body" style="font-size:0.78rem"></div>
|
|
795700
|
+
</section>
|
|
795701
|
+
<section class="observability-card observability-span-3" data-module="conversation-export">
|
|
795702
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Export conversation</h2><span class="observability-card__meta">portable session record</span></header>
|
|
795703
|
+
<div class="observability-card__body observability-actions">
|
|
795283
795704
|
<button onclick="exportChat('md')" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-brand);padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">markdown</button>
|
|
795284
795705
|
<button onclick="exportChat('json')" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-brand);padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">JSON</button>
|
|
795285
795706
|
</div>
|
|
795707
|
+
</section>
|
|
795708
|
+
</div>
|
|
795286
795709
|
</div>
|
|
795287
|
-
<div id="activity-panel" style="display:none;flex:1;overflow-y:auto
|
|
795288
|
-
|
|
795289
|
-
<div
|
|
795710
|
+
<div id="activity-panel" class="omnius-route-shell" data-route-page="activity" data-route-tab="activity" style="display:none;flex:1;overflow-y:auto">
|
|
795711
|
+
${renderRouteHeading({ page: "activity", eyebrow: "Audit", title: "Recent activity", description: "Review request outcomes, routes, latency, and actor context as a continuous operational record.", signals: ["status", "latency", "actor"] })}
|
|
795712
|
+
<div class="observability-grid" data-layout="activity-ledger">
|
|
795713
|
+
<section class="observability-card observability-span-6" data-module="audit-log">
|
|
795714
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Audit log</h2><span class="observability-card__meta">latest 50 records</span></header>
|
|
795715
|
+
<div id="activity-feed" class="observability-card__body" style="font-size:0.72rem"></div>
|
|
795716
|
+
</section>
|
|
795717
|
+
</div>
|
|
795290
795718
|
</div>
|
|
795291
|
-
<div id="projects-panel" style="display:none;flex:1;overflow-y:auto
|
|
795292
|
-
|
|
795293
|
-
|
|
795294
|
-
|
|
795719
|
+
<div id="projects-panel" class="omnius-route-shell" data-route-page="projects" data-route-tab="projects" style="display:none;flex:1;overflow-y:auto">
|
|
795720
|
+
${renderRouteHeading({ page: "projects", eyebrow: "Workspace registry", title: "Projects", description: "Find, register, and activate workspaces while keeping the current execution context unambiguous.", signals: ["active context", "registry", "discovery"] })}
|
|
795721
|
+
<div class="observability-grid" data-layout="project-toolbar">
|
|
795722
|
+
<section class="observability-card observability-span-6" data-module="workspace-tools">
|
|
795723
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Workspace tools</h2><span class="observability-card__meta">filter · scan · register</span></header>
|
|
795724
|
+
<div class="observability-card__body observability-actions">
|
|
795295
795725
|
<input id="project-search" type="text" placeholder="Filter projects…" style="background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-fg);padding:3px 8px;border-radius:3px;font-size:0.65rem;width:140px;font-family:inherit" oninput="filterProjects()">
|
|
795296
795726
|
<button id="scan-btn" onclick="scanProjects()" style="background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-fg-subtle);padding:3px 10px;border-radius:3px;font-size:0.65rem;cursor:pointer;font-family:inherit">🔍 Scan</button>
|
|
795297
795727
|
<button id="add-project-btn" onclick="showAddProject()" style="background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-fg-subtle);padding:3px 10px;border-radius:3px;font-size:0.65rem;cursor:pointer;font-family:inherit">+ Add</button>
|
|
795298
795728
|
</div>
|
|
795299
|
-
</
|
|
795300
|
-
<
|
|
795301
|
-
|
|
795729
|
+
</section>
|
|
795730
|
+
<section class="observability-card observability-span-2" data-module="current-workspace">
|
|
795731
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Current workspace</h2><span class="observability-card__meta">active context</span></header>
|
|
795732
|
+
<div id="projects-current" class="observability-card__body" style="font-size:0.72rem;color:var(--color-fg)">
|
|
795302
795733
|
<span style="color:var(--color-fg-subtle)">current:</span> <span id="projects-current-name" style="color:var(--color-brand)">(none)</span>
|
|
795303
795734
|
<span id="projects-current-root" style="color:var(--color-fg-subtle);margin-left:8px"></span>
|
|
795304
795735
|
</div>
|
|
795305
|
-
|
|
795306
|
-
<
|
|
795307
|
-
<
|
|
795736
|
+
</section>
|
|
795737
|
+
<section class="observability-card observability-span-4" data-module="workspace-registry">
|
|
795738
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Registered workspaces</h2><span class="observability-card__meta">select to activate</span></header>
|
|
795739
|
+
<div id="projects-list" class="observability-card__body" style="font-size:0.72rem"></div>
|
|
795740
|
+
</section>
|
|
795741
|
+
<section id="add-project-form" class="observability-card observability-span-6" data-module="register-workspace" style="display:none">
|
|
795742
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Add project</h2><span class="observability-card__meta">absolute filesystem path</span></header>
|
|
795743
|
+
<div class="observability-card__body">
|
|
795308
795744
|
<input id="add-project-path" type="text" placeholder="/absolute/path/to/project" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:4px 8px;border-radius:3px;font-size:0.65rem;width:100%;margin-bottom:6px;font-family:inherit">
|
|
795309
|
-
<div
|
|
795745
|
+
<div class="observability-actions">
|
|
795310
795746
|
<button onclick="addProject()" style="background:var(--color-brand);border:none;color:var(--color-accent-fg);padding:4px 12px;border-radius:3px;font-size:0.65rem;cursor:pointer;font-family:inherit">Register</button>
|
|
795311
795747
|
<button onclick="hideAddProject()" style="background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-fg-subtle);padding:4px 12px;border-radius:3px;font-size:0.65rem;cursor:pointer;font-family:inherit">Cancel</button>
|
|
795312
795748
|
</div>
|
|
795749
|
+
</div>
|
|
795750
|
+
</section>
|
|
795313
795751
|
</div>
|
|
795314
795752
|
</div>
|
|
795315
795753
|
|
|
795316
795754
|
<!-- Generate tab — global media generation (image/video/audio/music) backed by
|
|
795317
795755
|
the unified ~/.omnius model store. Loads models from /v1/media/models,
|
|
795318
795756
|
generates via /v1/media/<kind>, and browses the global gallery. -->
|
|
795319
|
-
<div id="generate-panel" style="display:none;flex:1;overflow-y:auto
|
|
795320
|
-
|
|
795757
|
+
<div id="generate-panel" class="omnius-route-shell" data-route-page="generate" data-route-tab="generate" style="display:none;flex:1;overflow-y:auto">
|
|
795758
|
+
${renderRouteHeading({ page: "generate", eyebrow: "Media operations", title: "Generate", description: "Move between synthesis, perception, model storage, evidence output, and the media archive without leaving the workbench.", signals: ["synthesis", "analysis", "signal", "archive"] })}
|
|
795759
|
+
<div class="hud-workbench" data-layout="generate-workbench">
|
|
795321
795760
|
<aside class="hud-panel hud-panel--slant hud-rail" id="gen-mode-rail">
|
|
795322
795761
|
<div class="hud-panel__chrome" aria-hidden="true"></div>
|
|
795323
795762
|
<header class="hud-panel__header">
|
|
@@ -795486,9 +795925,12 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795486
795925
|
</div>
|
|
795487
795926
|
|
|
795488
795927
|
<!-- Voice tab — voicechat toggle + clone management. AudioWorklet drives mic capture; WebAudio handles TTS playback. -->
|
|
795489
|
-
<div id="voice-panel" style="display:none;flex:1;overflow-y:auto
|
|
795490
|
-
|
|
795491
|
-
|
|
795928
|
+
<div id="voice-panel" class="omnius-route-shell" data-route-page="voice" data-route-tab="voice" style="display:none;flex:1;overflow-y:auto">
|
|
795929
|
+
${renderRouteHeading({ page: "voice", eyebrow: "Realtime audio", title: "Voice", description: "Control the live voice session, active model, model-specific options, transcript, and speech test from one observable surface.", signals: ["session", "model", "transcript", "TTS"] })}
|
|
795930
|
+
<div class="observability-grid" data-layout="voice-controls">
|
|
795931
|
+
<section class="observability-card observability-span-4" data-module="voice-session">
|
|
795932
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Voice session</h2><span class="observability-card__meta">mic ↔ ASR ↔ agent ↔ TTS</span></header>
|
|
795933
|
+
<div class="observability-card__body">
|
|
795492
795934
|
<div style="font-size:0.65rem;color:var(--color-fg-subtle);margin-bottom:8px">
|
|
795493
795935
|
Live mic ↔ ASR ↔ agent ↔ TTS over WebSocket. Audio routes over the same origin
|
|
795494
795936
|
as this page — works on localhost or over a forwarded public IP. Mic permission
|
|
@@ -795500,26 +795942,29 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795500
795942
|
<span id="voice-mic-pill" style="display:none;background:var(--color-bg);border-left:2px solid var(--color-success);padding:4px 10px;font-size:0.6rem;color:var(--color-success)">● mic active</span>
|
|
795501
795943
|
</div>
|
|
795502
795944
|
<div id="voice-transcript-pane" style="display:none;background:var(--color-bg);border:1px solid var(--color-bg-input);border-radius:3px;padding:10px;margin-top:6px;min-height:80px;max-height:280px;overflow-y:auto;font-size:0.7rem"></div>
|
|
795503
|
-
|
|
795945
|
+
</div>
|
|
795946
|
+
</section>
|
|
795504
795947
|
|
|
795505
|
-
<
|
|
795506
|
-
<
|
|
795507
|
-
<div
|
|
795948
|
+
<section class="observability-card observability-span-2" data-module="voice-model">
|
|
795949
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Voice model</h2><span class="observability-card__meta">active engine</span></header>
|
|
795950
|
+
<div class="observability-card__body observability-actions">
|
|
795508
795951
|
<select id="voice-model-select" onchange="renderVoiceModelOptions()" style="background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-fg);padding:5px 10px;border-radius:3px;font-family:inherit;font-size:0.7rem;flex:1"></select>
|
|
795509
795952
|
<button onclick="switchVoiceModel()" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-brand);padding:5px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">switch</button>
|
|
795510
795953
|
</div>
|
|
795511
|
-
</
|
|
795954
|
+
</section>
|
|
795512
795955
|
|
|
795513
|
-
<
|
|
795514
|
-
<
|
|
795515
|
-
|
|
795956
|
+
<section id="voice-model-options-panel" class="observability-card observability-span-3" data-module="voice-model-options">
|
|
795957
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Model options</h2><span class="observability-card__meta">engine capabilities</span></header>
|
|
795958
|
+
<div id="voice-model-options-content" class="observability-card__body" style="font-size:0.7rem;color:var(--color-fg-muted)"></div>
|
|
795959
|
+
</section>
|
|
795516
795960
|
|
|
795517
|
-
<
|
|
795518
|
-
<
|
|
795519
|
-
<div
|
|
795961
|
+
<section class="observability-card observability-span-3" data-module="voice-tts-test">
|
|
795962
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Speech test</h2><span class="observability-card__meta">test active TTS</span></header>
|
|
795963
|
+
<div class="observability-card__body observability-actions">
|
|
795520
795964
|
<input type="text" id="voice-test-text" placeholder="Type and the voice model speaks it..." style="flex:1;background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-fg);padding:6px 10px;border-radius:3px;font-family:inherit;font-size:0.7rem">
|
|
795521
795965
|
<button onclick="testTTS()" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-brand);padding:5px 14px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">speak</button>
|
|
795522
795966
|
</div>
|
|
795967
|
+
</section>
|
|
795523
795968
|
</div>
|
|
795524
795969
|
</div>
|
|
795525
795970
|
|
|
@@ -795592,7 +796037,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795592
796037
|
the mic button on the input row. The panel hits /v1/voice/start
|
|
795593
796038
|
to warm the engines on first open, /v1/voice/tts to synthesize
|
|
795594
796039
|
arbitrary text, and /v1/voice/transcribe with mic blob bytes. -->
|
|
795595
|
-
<div id="voice-panel" style="display:none;padding:8px 10px;background:var(--color-bg-elevated);border-top:1px solid var(--color-border);font-size:0.78rem">
|
|
796040
|
+
<div id="voice-mini-panel" style="display:none;padding:8px 10px;background:var(--color-bg-elevated);border-top:1px solid var(--color-border);font-size:0.78rem">
|
|
795596
796041
|
<div style="display:flex;gap:6px;align-items:center;margin-bottom:6px">
|
|
795597
796042
|
<span id="voice-state-badge" style="padding:2px 8px;border-radius:10px;background:var(--color-bg-input);border:1px solid var(--color-border);font-size:0.7rem;color:var(--color-fg-muted)">idle</span>
|
|
795598
796043
|
<button type="button" onclick="warmVoice()" style="font-size:0.74rem">warm</button>
|
|
@@ -795614,7 +796059,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795614
796059
|
<div id="input-row">
|
|
795615
796060
|
<span id="system-prompt-toggle" onclick="toggleSystemPrompt()" style="display:none">sys</span>
|
|
795616
796061
|
<textarea id="input-area" placeholder="Type a message..." rows="1"></textarea>
|
|
795617
|
-
<button id="voice-toggle-btn" type="button" onclick="toggleVoicePanel()" title="open voice panel" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg-muted);padding:10px 12px;border-radius:3px;font-family:inherit;font-size:0.75rem;cursor:pointer;flex-shrink:0">🎙</button>
|
|
796062
|
+
<button id="voice-input-toggle-btn" type="button" onclick="toggleVoicePanel()" title="open voice panel" style="background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg-muted);padding:10px 12px;border-radius:3px;font-family:inherit;font-size:0.75rem;cursor:pointer;flex-shrink:0">🎙</button>
|
|
795618
796063
|
<button id="send-btn" onclick="sendMessage()">send</button>
|
|
795619
796064
|
<button id="stop-btn" onclick="stopChat()" style="display:none;background:var(--color-bg-input);border:1px solid var(--color-error);color:var(--color-error);padding:10px 16px;border-radius:3px;font-family:inherit;font-size:0.75rem;cursor:pointer;flex-shrink:0">stop</button>
|
|
795620
796065
|
<!-- WO-CHAT-CHECKIN — teal accent button that takes the place of stop
|
|
@@ -795753,6 +796198,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795753
796198
|
</div>
|
|
795754
796199
|
|
|
795755
796200
|
<script>
|
|
796201
|
+
const webUiRouteSpecs = ${JSON.stringify(WEB_UI_ROUTE_SPECS)};
|
|
795756
796202
|
// ════════════════════════════════════════════════════════════════════
|
|
795757
796203
|
// Store layer — Svelte-writable shape, vanilla JS.
|
|
795758
796204
|
// ════════════════════════════════════════════════════════════════════
|
|
@@ -796013,18 +796459,8 @@ const $activeTab = writable('chat');
|
|
|
796013
796459
|
|
|
796014
796460
|
function parseInitialGuiRoute() {
|
|
796015
796461
|
const path = (location.pathname || '/').replace(/\\/+$/, '') || '/';
|
|
796016
|
-
const
|
|
796017
|
-
|
|
796018
|
-
'/agent': 'agent',
|
|
796019
|
-
'/voice': 'voice',
|
|
796020
|
-
'/projects': 'projects',
|
|
796021
|
-
'/dashboard': 'jobs',
|
|
796022
|
-
'/jobs': 'jobs',
|
|
796023
|
-
'/activity': 'activity',
|
|
796024
|
-
'/settings': 'config',
|
|
796025
|
-
'/config': 'config',
|
|
796026
|
-
};
|
|
796027
|
-
const tab = pathToTab[path] || null;
|
|
796462
|
+
const matched = webUiRouteSpecs.find(route => route.path === path || route.aliases.includes(path));
|
|
796463
|
+
const tab = matched?.tab || null;
|
|
796028
796464
|
let chatSession = null;
|
|
796029
796465
|
if (tab === 'chat') {
|
|
796030
796466
|
const qs = location.search.replace(/^\\?/, '').trim();
|
|
@@ -796223,36 +796659,18 @@ function _projectDisplayName(proj) {
|
|
|
796223
796659
|
if (!proj) return 'No project';
|
|
796224
796660
|
return proj.name || _projectPathLeaf(proj.root) || proj.root || 'Project';
|
|
796225
796661
|
}
|
|
796226
|
-
function _endpointDisplayName(endpoint) {
|
|
796227
|
-
if (!endpoint) return '';
|
|
796228
|
-
try { return new URL(endpoint).host || endpoint; } catch { return String(endpoint); }
|
|
796229
|
-
}
|
|
796230
796662
|
function renderProjectChrome() {
|
|
796231
796663
|
const proj = $currentProject.get ? $currentProject.get() : null;
|
|
796232
|
-
const cfg = $config.get ? ($config.get() || {}) : {};
|
|
796233
796664
|
const root = proj?.root || '';
|
|
796234
796665
|
const name = _projectDisplayName(proj);
|
|
796235
|
-
const headerName = document.getElementById('header-project-name') || document.querySelector('#header .accent');
|
|
796236
|
-
if (headerName) {
|
|
796237
|
-
headerName.textContent = name;
|
|
796238
|
-
headerName.title = root || name;
|
|
796239
|
-
}
|
|
796240
796666
|
const brand = document.getElementById('sidebar-brand');
|
|
796241
796667
|
if (brand) {
|
|
796242
796668
|
brand.textContent = name;
|
|
796243
796669
|
brand.title = root || name;
|
|
796244
796670
|
}
|
|
796245
796671
|
if (statusEl) {
|
|
796246
|
-
|
|
796247
|
-
|
|
796248
|
-
const endpoint = endpointObj.url || cfg.backendUrl || '';
|
|
796249
|
-
const endpointType = endpointObj.backendType || cfg.backendType || '';
|
|
796250
|
-
const endpointLabel = endpoint ? ((endpointType ? endpointType + ' ' : '') + _endpointDisplayName(endpoint)) : '';
|
|
796251
|
-
const bits = [String(_connectionState || 'connecting')];
|
|
796252
|
-
if (selected) bits.push(selected);
|
|
796253
|
-
if (endpointLabel) bits.push(endpointLabel);
|
|
796254
|
-
statusEl.textContent = bits.join(' · ');
|
|
796255
|
-
statusEl.title = [root, endpoint].filter(Boolean).join('\\n');
|
|
796672
|
+
statusEl.textContent = String(_connectionState || 'connecting');
|
|
796673
|
+
statusEl.title = root || name;
|
|
796256
796674
|
statusEl.className = /connected|ready|online/i.test(_connectionState || '') ? 'status live' : 'status';
|
|
796257
796675
|
}
|
|
796258
796676
|
try { _syncSidebarStatus(); } catch {}
|
|
@@ -796261,6 +796679,171 @@ function setConnectionState(state) {
|
|
|
796261
796679
|
_connectionState = state || 'connecting';
|
|
796262
796680
|
renderProjectChrome();
|
|
796263
796681
|
}
|
|
796682
|
+
|
|
796683
|
+
// Accessible workspace switcher based on the compact search/listbox pattern
|
|
796684
|
+
// used by Voryn. Project state still flows through Omnius's central store.
|
|
796685
|
+
let workspacePickerProjects = [];
|
|
796686
|
+
let workspacePickerIndex = -1;
|
|
796687
|
+
function workspacePickerElements() {
|
|
796688
|
+
return {
|
|
796689
|
+
trigger: document.getElementById('workspace-switcher-trigger'),
|
|
796690
|
+
picker: document.getElementById('workspace-picker'),
|
|
796691
|
+
search: document.getElementById('workspace-picker-search'),
|
|
796692
|
+
list: document.getElementById('workspace-picker-list'),
|
|
796693
|
+
};
|
|
796694
|
+
}
|
|
796695
|
+
function isWorkspacePickerOpen() {
|
|
796696
|
+
const { picker } = workspacePickerElements();
|
|
796697
|
+
return !!picker && picker.style.display !== 'none';
|
|
796698
|
+
}
|
|
796699
|
+
async function openWorkspacePicker() {
|
|
796700
|
+
const { trigger, picker, search } = workspacePickerElements();
|
|
796701
|
+
if (!trigger || !picker || !search) return;
|
|
796702
|
+
picker.style.display = 'block';
|
|
796703
|
+
trigger.setAttribute('aria-expanded', 'true');
|
|
796704
|
+
workspacePickerIndex = -1;
|
|
796705
|
+
await loadWorkspacePicker();
|
|
796706
|
+
requestAnimationFrame(() => { try { search.focus(); search.select(); } catch {} });
|
|
796707
|
+
}
|
|
796708
|
+
function closeWorkspacePicker(restoreFocus) {
|
|
796709
|
+
const { trigger, picker, search } = workspacePickerElements();
|
|
796710
|
+
if (!trigger || !picker) return;
|
|
796711
|
+
picker.style.display = 'none';
|
|
796712
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
796713
|
+
workspacePickerIndex = -1;
|
|
796714
|
+
if (search) search.value = '';
|
|
796715
|
+
if (restoreFocus) { try { trigger.focus(); } catch {} }
|
|
796716
|
+
}
|
|
796717
|
+
function toggleWorkspacePicker(event) {
|
|
796718
|
+
if (event) event.stopPropagation();
|
|
796719
|
+
if (isWorkspacePickerOpen()) closeWorkspacePicker(false);
|
|
796720
|
+
else openWorkspacePicker();
|
|
796721
|
+
}
|
|
796722
|
+
function workspaceAgo(ts) {
|
|
796723
|
+
if (!ts) return '';
|
|
796724
|
+
const seconds = Math.max(0, Math.floor((Date.now() - Number(ts)) / 1000));
|
|
796725
|
+
if (seconds < 60) return seconds + 's';
|
|
796726
|
+
if (seconds < 3600) return Math.floor(seconds / 60) + 'm';
|
|
796727
|
+
if (seconds < 86400) return Math.floor(seconds / 3600) + 'h';
|
|
796728
|
+
return Math.floor(seconds / 86400) + 'd';
|
|
796729
|
+
}
|
|
796730
|
+
function renderWorkspacePicker(query) {
|
|
796731
|
+
const { list } = workspacePickerElements();
|
|
796732
|
+
if (!list) return;
|
|
796733
|
+
const currentRoot = $currentProject.get?.()?.root || '';
|
|
796734
|
+
const needle = String(query || '').trim().toLowerCase();
|
|
796735
|
+
const matches = workspacePickerProjects.filter(project => {
|
|
796736
|
+
const haystack = (_projectDisplayName(project) + ' ' + (project.root || '')).toLowerCase();
|
|
796737
|
+
return !needle || haystack.includes(needle);
|
|
796738
|
+
});
|
|
796739
|
+
list.replaceChildren();
|
|
796740
|
+
if (!matches.length) {
|
|
796741
|
+
const empty = document.createElement('div');
|
|
796742
|
+
empty.className = 'workspace-picker__empty';
|
|
796743
|
+
empty.textContent = needle ? 'No matching workspaces' : 'No registered workspaces';
|
|
796744
|
+
list.appendChild(empty);
|
|
796745
|
+
return;
|
|
796746
|
+
}
|
|
796747
|
+
for (const project of matches) {
|
|
796748
|
+
const active = project.root === currentRoot;
|
|
796749
|
+
const option = document.createElement('button');
|
|
796750
|
+
option.type = 'button';
|
|
796751
|
+
option.className = 'workspace-picker__option';
|
|
796752
|
+
option.setAttribute('role', 'option');
|
|
796753
|
+
option.setAttribute('aria-selected', active ? 'true' : 'false');
|
|
796754
|
+
option.dataset.root = project.root || '';
|
|
796755
|
+
const copy = document.createElement('span');
|
|
796756
|
+
copy.style.minWidth = '0';
|
|
796757
|
+
const name = document.createElement('span');
|
|
796758
|
+
name.className = 'workspace-picker__name';
|
|
796759
|
+
name.textContent = _projectDisplayName(project);
|
|
796760
|
+
const path = document.createElement('span');
|
|
796761
|
+
path.className = 'workspace-picker__path';
|
|
796762
|
+
const age = workspaceAgo(project.lastSeen);
|
|
796763
|
+
path.textContent = (project.root || '') + (age ? ' · seen ' + age + ' ago' : '');
|
|
796764
|
+
const mark = document.createElement('span');
|
|
796765
|
+
mark.className = 'workspace-picker__check';
|
|
796766
|
+
mark.textContent = active ? 'active' : 'switch';
|
|
796767
|
+
copy.append(name, path);
|
|
796768
|
+
option.append(copy, mark);
|
|
796769
|
+
option.addEventListener('click', () => switchProjectRoot(project.root, option));
|
|
796770
|
+
list.appendChild(option);
|
|
796771
|
+
}
|
|
796772
|
+
}
|
|
796773
|
+
async function loadWorkspacePicker() {
|
|
796774
|
+
const { list, search } = workspacePickerElements();
|
|
796775
|
+
if (!list) return;
|
|
796776
|
+
list.innerHTML = '<div class="workspace-picker__empty">Loading workspaces...</div>';
|
|
796777
|
+
try {
|
|
796778
|
+
const response = await fetch('/v1/projects', { headers: headers() });
|
|
796779
|
+
if (!response.ok) throw new Error('HTTP ' + response.status);
|
|
796780
|
+
const data = await response.json();
|
|
796781
|
+
workspacePickerProjects = Array.isArray(data.projects) ? data.projects : [];
|
|
796782
|
+
const current = data.current && typeof data.current.root === 'string' ? data.current : null;
|
|
796783
|
+
if ($currentProject.get?.()?.root !== current?.root) $currentProject.set(current);
|
|
796784
|
+
renderWorkspacePicker(search?.value || '');
|
|
796785
|
+
} catch (error) {
|
|
796786
|
+
list.innerHTML = '<div class="workspace-picker__empty">Unable to load workspaces</div>';
|
|
796787
|
+
}
|
|
796788
|
+
}
|
|
796789
|
+
function filterWorkspacePicker(value) {
|
|
796790
|
+
workspacePickerIndex = -1;
|
|
796791
|
+
renderWorkspacePicker(value);
|
|
796792
|
+
}
|
|
796793
|
+
function handleWorkspacePickerKeys(event) {
|
|
796794
|
+
const { list } = workspacePickerElements();
|
|
796795
|
+
if (!list) return;
|
|
796796
|
+
const options = Array.from(list.querySelectorAll('.workspace-picker__option'));
|
|
796797
|
+
if (event.key === 'Escape') {
|
|
796798
|
+
event.preventDefault();
|
|
796799
|
+
closeWorkspacePicker(true);
|
|
796800
|
+
return;
|
|
796801
|
+
}
|
|
796802
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
796803
|
+
event.preventDefault();
|
|
796804
|
+
const delta = event.key === 'ArrowDown' ? 1 : -1;
|
|
796805
|
+
workspacePickerIndex = Math.max(0, Math.min(options.length - 1, workspacePickerIndex + delta));
|
|
796806
|
+
options.forEach((option, index) => option.classList.toggle('is-keyboard-active', index === workspacePickerIndex));
|
|
796807
|
+
options[workspacePickerIndex]?.scrollIntoView({ block: 'nearest' });
|
|
796808
|
+
return;
|
|
796809
|
+
}
|
|
796810
|
+
if (event.key === 'Enter' && options.length) {
|
|
796811
|
+
event.preventDefault();
|
|
796812
|
+
options[Math.max(0, workspacePickerIndex)]?.click();
|
|
796813
|
+
}
|
|
796814
|
+
}
|
|
796815
|
+
async function switchProjectRoot(root, pendingElement) {
|
|
796816
|
+
if (!root) return false;
|
|
796817
|
+
if (pendingElement) pendingElement.disabled = true;
|
|
796818
|
+
try {
|
|
796819
|
+
const response = await fetch('/v1/projects/switch', {
|
|
796820
|
+
method: 'POST',
|
|
796821
|
+
headers: { 'Content-Type': 'application/json', ...headers() },
|
|
796822
|
+
body: JSON.stringify({ root }),
|
|
796823
|
+
});
|
|
796824
|
+
if (!response.ok) {
|
|
796825
|
+
const error = await response.json().catch(() => ({ message: 'HTTP ' + response.status }));
|
|
796826
|
+
throw new Error(error.message || error.error || 'unknown error');
|
|
796827
|
+
}
|
|
796828
|
+
closeWorkspacePicker(true);
|
|
796829
|
+
await loadProjects();
|
|
796830
|
+
return true;
|
|
796831
|
+
} catch (error) {
|
|
796832
|
+
alert('Switch failed: ' + (error && error.message ? error.message : String(error)));
|
|
796833
|
+
if (pendingElement) pendingElement.disabled = false;
|
|
796834
|
+
return false;
|
|
796835
|
+
}
|
|
796836
|
+
}
|
|
796837
|
+
document.addEventListener('pointerdown', (event) => {
|
|
796838
|
+
if (isWorkspacePickerOpen() && !event.target.closest('.workspace-switcher')) closeWorkspacePicker(false);
|
|
796839
|
+
});
|
|
796840
|
+
document.addEventListener('keydown', (event) => {
|
|
796841
|
+
if (event.key === 'Escape' && isWorkspacePickerOpen()) closeWorkspacePicker(true);
|
|
796842
|
+
});
|
|
796843
|
+
window.toggleWorkspacePicker = toggleWorkspacePicker;
|
|
796844
|
+
window.closeWorkspacePicker = closeWorkspacePicker;
|
|
796845
|
+
window.filterWorkspacePicker = filterWorkspacePicker;
|
|
796846
|
+
window.handleWorkspacePickerKeys = handleWorkspacePickerKeys;
|
|
796264
796847
|
let streaming = false;
|
|
796265
796848
|
let messages = [];
|
|
796266
796849
|
let chatAbortController = null; // for stop button
|
|
@@ -797985,7 +798568,7 @@ async function _refreshVoiceState() {
|
|
|
797985
798568
|
}
|
|
797986
798569
|
|
|
797987
798570
|
function toggleVoicePanel() {
|
|
797988
|
-
const p = document.getElementById('voice-panel');
|
|
798571
|
+
const p = document.getElementById('voice-mini-panel');
|
|
797989
798572
|
if (!p) return;
|
|
797990
798573
|
if (p.style.display === 'none') {
|
|
797991
798574
|
p.style.display = 'block';
|
|
@@ -797995,7 +798578,7 @@ function toggleVoicePanel() {
|
|
|
797995
798578
|
}
|
|
797996
798579
|
}
|
|
797997
798580
|
function closeVoicePanel() {
|
|
797998
|
-
const p = document.getElementById('voice-panel');
|
|
798581
|
+
const p = document.getElementById('voice-mini-panel');
|
|
797999
798582
|
if (p) p.style.display = 'none';
|
|
798000
798583
|
}
|
|
798001
798584
|
window.toggleVoicePanel = toggleVoicePanel;
|
|
@@ -798275,36 +798858,14 @@ window.closeRemoteConnection = closeRemoteConnection;
|
|
|
798275
798858
|
})();
|
|
798276
798859
|
|
|
798277
798860
|
// Tab switching + browser route sync
|
|
798278
|
-
const allPanels =
|
|
798861
|
+
const allPanels = webUiRouteSpecs.map(route => route.panelId);
|
|
798279
798862
|
function routePathForTab(tab) {
|
|
798280
|
-
|
|
798281
|
-
chat: '/chat',
|
|
798282
|
-
agent: '/agent',
|
|
798283
|
-
voice: '/voice',
|
|
798284
|
-
generate: '/generate',
|
|
798285
|
-
projects: '/projects',
|
|
798286
|
-
jobs: '/dashboard',
|
|
798287
|
-
activity: '/activity',
|
|
798288
|
-
config: '/settings',
|
|
798289
|
-
};
|
|
798290
|
-
return map[tab] || '/chat';
|
|
798863
|
+
return webUiRouteSpecs.find(route => route.tab === tab)?.path || '/chat';
|
|
798291
798864
|
}
|
|
798292
798865
|
function tabForRoutePath(pathname) {
|
|
798293
798866
|
const path = (pathname || '/').replace(/\\/+$/, '') || '/';
|
|
798294
|
-
const
|
|
798295
|
-
|
|
798296
|
-
'/chat': 'chat',
|
|
798297
|
-
'/agent': 'agent',
|
|
798298
|
-
'/voice': 'voice',
|
|
798299
|
-
'/generate': 'generate',
|
|
798300
|
-
'/projects': 'projects',
|
|
798301
|
-
'/dashboard': 'jobs',
|
|
798302
|
-
'/jobs': 'jobs',
|
|
798303
|
-
'/activity': 'activity',
|
|
798304
|
-
'/settings': 'config',
|
|
798305
|
-
'/config': 'config',
|
|
798306
|
-
};
|
|
798307
|
-
return map[path] || 'chat';
|
|
798867
|
+
const matched = webUiRouteSpecs.find(route => route.path === path || route.aliases.includes(path));
|
|
798868
|
+
return matched?.tab || 'chat';
|
|
798308
798869
|
}
|
|
798309
798870
|
function chatSessionFromRouteSearch(search) {
|
|
798310
798871
|
const qs = String(search || '').replace(/^\\?/, '').trim();
|
|
@@ -798326,13 +798887,19 @@ function syncRouteForTab(tab, replace) {
|
|
|
798326
798887
|
}
|
|
798327
798888
|
function switchTab(tab, opts) {
|
|
798328
798889
|
opts = opts || {};
|
|
798329
|
-
const
|
|
798330
|
-
allPanels.forEach(id => {
|
|
798331
|
-
|
|
798890
|
+
const route = webUiRouteSpecs.find(candidate => candidate.tab === tab) || webUiRouteSpecs[0];
|
|
798891
|
+
allPanels.forEach(id => {
|
|
798892
|
+
const el = document.getElementById(id);
|
|
798893
|
+
if (!el) return;
|
|
798894
|
+
el.style.display = 'none';
|
|
798895
|
+
el.setAttribute('aria-hidden', 'true');
|
|
798896
|
+
});
|
|
798897
|
+
const panel = document.getElementById(route.panelId);
|
|
798332
798898
|
if (panel) {
|
|
798333
798899
|
// chat AND agent are flex containers (vertical column with sidebar/topbar);
|
|
798334
798900
|
// other panels are simple block scrollers.
|
|
798335
798901
|
panel.style.display = (tab === 'chat' || tab === 'agent') ? 'flex' : 'block';
|
|
798902
|
+
panel.setAttribute('aria-hidden', 'false');
|
|
798336
798903
|
}
|
|
798337
798904
|
document.getElementById('footer').style.display = tab === 'chat' ? 'flex' : 'none';
|
|
798338
798905
|
document.querySelectorAll('.tab').forEach(t => { t.style.borderBottomColor = 'transparent'; t.style.color = 'var(--color-fg-faint)'; });
|
|
@@ -798340,7 +798907,10 @@ function switchTab(tab, opts) {
|
|
|
798340
798907
|
if (active) { active.style.borderBottomColor = 'var(--color-brand)'; active.style.color = 'var(--color-brand)'; }
|
|
798341
798908
|
// OWUI-2: mirror active state on the sidebar nav
|
|
798342
798909
|
document.querySelectorAll('#omnius-sidebar .sb-nav').forEach(b => {
|
|
798343
|
-
|
|
798910
|
+
const isActive = b.getAttribute('data-tab') === tab;
|
|
798911
|
+
b.classList.toggle('active', isActive);
|
|
798912
|
+
if (isActive) b.setAttribute('aria-current', 'page');
|
|
798913
|
+
else b.removeAttribute('aria-current');
|
|
798344
798914
|
});
|
|
798345
798915
|
if ($activeTab.get && $activeTab.get() !== tab) $activeTab.set(tab);
|
|
798346
798916
|
if (!opts.fromRoute) syncRouteForTab(tab, !!opts.replaceRoute);
|
|
@@ -798363,6 +798933,9 @@ function switchTab(tab, opts) {
|
|
|
798363
798933
|
}
|
|
798364
798934
|
}
|
|
798365
798935
|
window.switchTab = switchTab;
|
|
798936
|
+
// Route activation must not depend on a registered/current project. Apply it
|
|
798937
|
+
// immediately, then project preference hydration may fill route-local state.
|
|
798938
|
+
if (initialGuiRoute.tab) switchTab(initialGuiRoute.tab, { fromRoute: true });
|
|
798366
798939
|
|
|
798367
798940
|
// ════════════════════════════════════════════════════════════
|
|
798368
798941
|
// Generate tab — global media generation (image/video/audio/music)
|
|
@@ -798979,27 +799552,8 @@ async function loadProjects() {
|
|
|
798979
799552
|
const root = decodeURIComponent(el.getAttribute('data-root') || '');
|
|
798980
799553
|
if (!root) return;
|
|
798981
799554
|
el.style.opacity = '0.5';
|
|
798982
|
-
|
|
798983
|
-
|
|
798984
|
-
method: 'POST',
|
|
798985
|
-
headers: { 'Content-Type': 'application/json', ...headers() },
|
|
798986
|
-
body: JSON.stringify({ root }),
|
|
798987
|
-
});
|
|
798988
|
-
if (!r.ok) {
|
|
798989
|
-
const err = await r.json().catch(() => ({ message: 'HTTP ' + r.status }));
|
|
798990
|
-
alert('Switch failed: ' + (err.message || err.error || 'unknown'));
|
|
798991
|
-
el.style.opacity = '1';
|
|
798992
|
-
return;
|
|
798993
|
-
}
|
|
798994
|
-
// Successful switch: re-fetch /v1/projects which updates
|
|
798995
|
-
// $currentProject; the subscription cascade refreshes models,
|
|
798996
|
-
// config, sessions, agent runs, and restores the chat session
|
|
798997
|
-
// for the new project. No more brittle ad-hoc fan-out.
|
|
798998
|
-
await loadProjects();
|
|
798999
|
-
} catch (e) {
|
|
799000
|
-
alert('Switch failed: ' + (e && e.message ? e.message : String(e)));
|
|
799001
|
-
el.style.opacity = '1';
|
|
799002
|
-
}
|
|
799555
|
+
const switched = await switchProjectRoot(root, el);
|
|
799556
|
+
if (!switched) el.style.opacity = '1';
|
|
799003
799557
|
});
|
|
799004
799558
|
});
|
|
799005
799559
|
} catch (e) {
|
|
@@ -799363,8 +799917,7 @@ async function loadDaemons() {
|
|
|
799363
799917
|
el.innerHTML = '<div style="background:var(--color-bg-elevated);border:1px solid var(--color-bg-input);border-radius:3px;padding:8px 12px;color:var(--color-fg-faint);font-size:0.7rem">No active processes</div>';
|
|
799364
799918
|
return;
|
|
799365
799919
|
}
|
|
799366
|
-
el.innerHTML =
|
|
799367
|
-
d.runs.map(j =>
|
|
799920
|
+
el.innerHTML = d.runs.map(j =>
|
|
799368
799921
|
'<div style="background:var(--color-bg-elevated);border-left:2px solid var(--color-brand);padding:6px 10px;margin:4px 0;font-size:0.72rem">' +
|
|
799369
799922
|
'<span style="color:var(--color-brand)">' + (j.id||'').slice(0,12) + '</span> ' +
|
|
799370
799923
|
'<span style="color:var(--color-success)">running</span> ' +
|
|
@@ -799401,7 +799954,7 @@ async function loadScheduled() {
|
|
|
799401
799954
|
+ '</div>';
|
|
799402
799955
|
return row;
|
|
799403
799956
|
}).join('');
|
|
799404
|
-
el.innerHTML =
|
|
799957
|
+
el.innerHTML = rows
|
|
799405
799958
|
+ '<div style="margin-top:6px;display:flex;gap:8px">'
|
|
799406
799959
|
+ '<button onclick="disableAllScheduled()" title="Disable all scheduled tasks" style="background:var(--color-bg-input);border:1px solid var(--color-error);color:var(--color-error);padding:3px 8px;border-radius:3px;font-size:0.65rem;cursor:pointer">disable all</button>'
|
|
799407
799960
|
+ '<button onclick="enableAllScheduled()" title="Enable all scheduled tasks" style="background:var(--color-bg-input);border:1px solid #2a3a2a;color:var(--color-success);padding:3px 8px;border-radius:3px;font-size:0.65rem;cursor:pointer">enable all</button>'
|
|
@@ -799563,7 +800116,7 @@ async function loadServices() {
|
|
|
799563
800116
|
+ '<div style="margin-top:4px;display:flex;gap:8px">' + stopBtn + disBtn + '</div>'
|
|
799564
800117
|
+ '</div>';
|
|
799565
800118
|
}).join('');
|
|
799566
|
-
el.innerHTML =
|
|
800119
|
+
el.innerHTML = rows;
|
|
799567
800120
|
} catch {}
|
|
799568
800121
|
}
|
|
799569
800122
|
|
|
@@ -799752,7 +800305,6 @@ async function loadDashboard() {
|
|
|
799752
800305
|
const totalIn = d.persistent?.totalIn || d.totalTokensIn || 0;
|
|
799753
800306
|
const totalOut = d.persistent?.totalOut || d.totalTokensOut || 0;
|
|
799754
800307
|
document.getElementById('dashboard-usage').innerHTML =
|
|
799755
|
-
'<h3 style="color:var(--color-brand);font-size:0.7rem;margin-bottom:8px">Token Usage by Provider (persistent)</h3>' +
|
|
799756
800308
|
'<div style="display:flex;gap:12px;flex-wrap:wrap;margin-bottom:8px">' +
|
|
799757
800309
|
'<div style="background:var(--color-bg-elevated);border:1px solid var(--color-bg-input);border-radius:3px;padding:8px 12px;flex:1">' +
|
|
799758
800310
|
'<div style="color:var(--color-fg-faint);font-size:0.6rem">TOTAL IN</div>' +
|
|
@@ -802718,6 +803270,7 @@ function toggleSidebar() {
|
|
|
802718
803270
|
const sb = document.getElementById('omnius-sidebar');
|
|
802719
803271
|
if (!sb) return;
|
|
802720
803272
|
const next = sb.getAttribute('data-collapsed') !== 'true';
|
|
803273
|
+
if (next) closeWorkspacePicker(false);
|
|
802721
803274
|
sb.setAttribute('data-collapsed', String(next));
|
|
802722
803275
|
_setLS(SIDEBAR_KEYS.collapsed, next ? '1' : '0');
|
|
802723
803276
|
}
|
|
@@ -804159,8 +804712,22 @@ input.focus();
|
|
|
804159
804712
|
</body>
|
|
804160
804713
|
</html>`;
|
|
804161
804714
|
}
|
|
804715
|
+
var WEB_UI_ROUTE_SPECS, WEB_UI_ROUTE_PATHS;
|
|
804162
804716
|
var init_web_ui = __esm({
|
|
804163
804717
|
"packages/cli/src/api/web-ui.ts"() {
|
|
804718
|
+
WEB_UI_ROUTE_SPECS = Object.freeze([
|
|
804719
|
+
{ tab: "chat", page: "chat", path: "/chat", aliases: ["/"], panelId: "chat-container" },
|
|
804720
|
+
{ tab: "agent", page: "agent", path: "/agent", aliases: [], panelId: "agent-panel" },
|
|
804721
|
+
{ tab: "voice", page: "voice", path: "/voice", aliases: [], panelId: "voice-panel" },
|
|
804722
|
+
{ tab: "generate", page: "generate", path: "/generate", aliases: [], panelId: "generate-panel" },
|
|
804723
|
+
{ tab: "projects", page: "projects", path: "/projects", aliases: [], panelId: "projects-panel" },
|
|
804724
|
+
{ tab: "jobs", page: "dashboard", path: "/dashboard", aliases: ["/jobs"], panelId: "jobs-panel" },
|
|
804725
|
+
{ tab: "activity", page: "activity", path: "/activity", aliases: [], panelId: "activity-panel" },
|
|
804726
|
+
{ tab: "config", page: "settings", path: "/settings", aliases: ["/config"], panelId: "config-panel" }
|
|
804727
|
+
]);
|
|
804728
|
+
WEB_UI_ROUTE_PATHS = Object.freeze(
|
|
804729
|
+
WEB_UI_ROUTE_SPECS.flatMap((route) => [route.path, ...route.aliases])
|
|
804730
|
+
);
|
|
804164
804731
|
}
|
|
804165
804732
|
});
|
|
804166
804733
|
|
|
@@ -811485,19 +812052,7 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
|
|
|
811485
812052
|
res.end(svg);
|
|
811486
812053
|
return;
|
|
811487
812054
|
}
|
|
811488
|
-
const guiRoutes =
|
|
811489
|
-
"/",
|
|
811490
|
-
"/chat",
|
|
811491
|
-
"/agent",
|
|
811492
|
-
"/voice",
|
|
811493
|
-
"/generate",
|
|
811494
|
-
"/projects",
|
|
811495
|
-
"/dashboard",
|
|
811496
|
-
"/jobs",
|
|
811497
|
-
"/activity",
|
|
811498
|
-
"/settings",
|
|
811499
|
-
"/config"
|
|
811500
|
-
]);
|
|
812055
|
+
const guiRoutes = new Set(WEB_UI_ROUTE_PATHS);
|
|
811501
812056
|
if (guiRoutes.has(pathname) && method === "GET" && req3.headers.accept?.includes("text/html")) {
|
|
811502
812057
|
const htmlHeaders = {
|
|
811503
812058
|
"Content-Type": "text/html; charset=utf-8",
|