omnius 1.0.601 → 1.0.603
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 +782 -186
- 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
|
}
|
|
@@ -709767,6 +709817,12 @@ var init_status_bar = __esm({
|
|
|
709767
709817
|
_toolCallBreakdown = [];
|
|
709768
709818
|
_compactionCount = 0;
|
|
709769
709819
|
_sessionStartAt = 0;
|
|
709820
|
+
/** Whether the uptime timer is currently paused (task complete) */
|
|
709821
|
+
_timerPaused = false;
|
|
709822
|
+
/** Timestamp when timer was paused */
|
|
709823
|
+
_pausedAt = 0;
|
|
709824
|
+
/** Total accumulated paused time in milliseconds */
|
|
709825
|
+
_accumulatedPausedMs = 0;
|
|
709770
709826
|
_gpuName = "";
|
|
709771
709827
|
_vramTotal = 0;
|
|
709772
709828
|
_vramUsed = 0;
|
|
@@ -711128,6 +711184,31 @@ var init_status_bar = __esm({
|
|
|
711128
711184
|
recordSpeedTaskEnd() {
|
|
711129
711185
|
this._speedTracker.taskEnd();
|
|
711130
711186
|
}
|
|
711187
|
+
/** Pause the uptime timer (called when task completes) */
|
|
711188
|
+
pauseUptimeTimer() {
|
|
711189
|
+
if (!this._timerPaused && this._sessionStartAt > 0) {
|
|
711190
|
+
this._timerPaused = true;
|
|
711191
|
+
this._pausedAt = Date.now();
|
|
711192
|
+
if (this.active) this.renderFooterPreserveCursor();
|
|
711193
|
+
}
|
|
711194
|
+
}
|
|
711195
|
+
/** Resume the uptime timer (called when next query begins) */
|
|
711196
|
+
resumeUptimeTimer() {
|
|
711197
|
+
if (this._timerPaused) {
|
|
711198
|
+
const now2 = Date.now();
|
|
711199
|
+
this._accumulatedPausedMs += now2 - this._pausedAt;
|
|
711200
|
+
this._timerPaused = false;
|
|
711201
|
+
this._pausedAt = 0;
|
|
711202
|
+
if (this.active) this.renderFooterPreserveCursor();
|
|
711203
|
+
}
|
|
711204
|
+
}
|
|
711205
|
+
/** Reset the uptime timer completely (for new session) */
|
|
711206
|
+
resetUptimeTimer() {
|
|
711207
|
+
this._sessionStartAt = 0;
|
|
711208
|
+
this._timerPaused = false;
|
|
711209
|
+
this._pausedAt = 0;
|
|
711210
|
+
this._accumulatedPausedMs = 0;
|
|
711211
|
+
}
|
|
711131
711212
|
/** SNR (Signal-to-Noise Ratio) from context quality evaluation */
|
|
711132
711213
|
_snr = null;
|
|
711133
711214
|
/** Update the SNR gauge with a new evaluation result */
|
|
@@ -713734,7 +713815,10 @@ ${CONTENT_BG_SEQ}`);
|
|
|
713734
713815
|
const m2 = this.metrics;
|
|
713735
713816
|
const termWidth = getTermWidth();
|
|
713736
713817
|
const uptime2 = this.formatUptime();
|
|
713737
|
-
const
|
|
713818
|
+
const isPaused = this._timerPaused;
|
|
713819
|
+
const circleChar = isPaused ? "●" : "◖";
|
|
713820
|
+
const circleColor = isPaused ? 120 : 183;
|
|
713821
|
+
const uptimeStr = `\x1B[38;5;${circleColor}m${circleChar} ${uptime2}\x1B[0m`;
|
|
713738
713822
|
const ctxUsed = m2.estimatedContextTokens;
|
|
713739
713823
|
const ctxTotal = this.reportedContextTotal(
|
|
713740
713824
|
m2.contextWindowSize,
|
|
@@ -713831,7 +713915,12 @@ ${CONTENT_BG_SEQ}`);
|
|
|
713831
713915
|
}
|
|
713832
713916
|
formatUptime() {
|
|
713833
713917
|
if (this._sessionStartAt <= 0) return "0s";
|
|
713834
|
-
|
|
713918
|
+
let ms;
|
|
713919
|
+
if (this._timerPaused) {
|
|
713920
|
+
ms = this._pausedAt - this._sessionStartAt - this._accumulatedPausedMs;
|
|
713921
|
+
} else {
|
|
713922
|
+
ms = Date.now() - this._sessionStartAt - this._accumulatedPausedMs;
|
|
713923
|
+
}
|
|
713835
713924
|
const totalSec = Math.floor(ms / 1e3);
|
|
713836
713925
|
const h = Math.floor(totalSec / 3600);
|
|
713837
713926
|
const m2 = Math.floor(totalSec % 3600 / 60);
|
|
@@ -792889,6 +792978,17 @@ var init_routes_v1 = __esm({
|
|
|
792889
792978
|
});
|
|
792890
792979
|
|
|
792891
792980
|
// packages/cli/src/api/web-ui.ts
|
|
792981
|
+
function renderRouteHeading(options2) {
|
|
792982
|
+
const signals = options2.signals.map((signal) => `<span class="route-heading__signal">${signal}</span>`).join("");
|
|
792983
|
+
return `<header class="route-heading" data-route-heading="${options2.page}">
|
|
792984
|
+
<div class="route-heading__copy">
|
|
792985
|
+
<span class="route-heading__eyebrow">${options2.eyebrow}</span>
|
|
792986
|
+
<h1 class="route-heading__title">${options2.title}</h1>
|
|
792987
|
+
<p class="route-heading__description">${options2.description}</p>
|
|
792988
|
+
</div>
|
|
792989
|
+
<div class="route-heading__signals" aria-label="Visible operational areas">${signals}</div>
|
|
792990
|
+
</header>`;
|
|
792991
|
+
}
|
|
792892
792992
|
function getWebUI() {
|
|
792893
792993
|
return `<!DOCTYPE html>
|
|
792894
792994
|
<html lang="en">
|
|
@@ -794986,6 +795086,303 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
794986
795086
|
}
|
|
794987
795087
|
*::-webkit-scrollbar-thumb:hover { background: var(--nclp-yellow); }
|
|
794988
795088
|
|
|
795089
|
+
/* Shared route composition. This carries the useful six-track command-center
|
|
795090
|
+
* grammar from the Voryn persona/call-tree surfaces while keeping Omnius's
|
|
795091
|
+
* existing NOCLIP palette, compact density, and 3px geometry authoritative. */
|
|
795092
|
+
[data-route-page] {
|
|
795093
|
+
min-width: 0;
|
|
795094
|
+
background: var(--nclp-bg-main) !important;
|
|
795095
|
+
}
|
|
795096
|
+
|
|
795097
|
+
.omnius-route-shell {
|
|
795098
|
+
padding: 12px 16px !important;
|
|
795099
|
+
}
|
|
795100
|
+
|
|
795101
|
+
.route-heading {
|
|
795102
|
+
display: grid;
|
|
795103
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
795104
|
+
align-items: end;
|
|
795105
|
+
gap: 12px;
|
|
795106
|
+
margin-bottom: 12px;
|
|
795107
|
+
padding-bottom: 10px;
|
|
795108
|
+
border-bottom: 1px solid var(--nclp-line);
|
|
795109
|
+
min-width: 0;
|
|
795110
|
+
}
|
|
795111
|
+
|
|
795112
|
+
.route-heading__copy { min-width: 0; }
|
|
795113
|
+
.route-heading__eyebrow {
|
|
795114
|
+
display: block;
|
|
795115
|
+
margin-bottom: 3px;
|
|
795116
|
+
color: var(--nclp-yellow);
|
|
795117
|
+
font-size: 9px;
|
|
795118
|
+
font-weight: 800;
|
|
795119
|
+
letter-spacing: 0.14em;
|
|
795120
|
+
text-transform: uppercase;
|
|
795121
|
+
}
|
|
795122
|
+
.route-heading__title {
|
|
795123
|
+
margin: 0 !important;
|
|
795124
|
+
color: var(--nclp-text) !important;
|
|
795125
|
+
font-size: 15px !important;
|
|
795126
|
+
letter-spacing: 0.02em !important;
|
|
795127
|
+
text-transform: none !important;
|
|
795128
|
+
}
|
|
795129
|
+
.route-heading__description {
|
|
795130
|
+
max-width: 760px;
|
|
795131
|
+
margin: 4px 0 0;
|
|
795132
|
+
color: var(--nclp-muted);
|
|
795133
|
+
font-size: 11px;
|
|
795134
|
+
line-height: 1.45;
|
|
795135
|
+
}
|
|
795136
|
+
.route-heading__signals {
|
|
795137
|
+
display: flex;
|
|
795138
|
+
flex-wrap: wrap;
|
|
795139
|
+
justify-content: flex-end;
|
|
795140
|
+
gap: 5px;
|
|
795141
|
+
}
|
|
795142
|
+
.route-heading__signal,
|
|
795143
|
+
.observability-chip {
|
|
795144
|
+
border: 1px solid var(--nclp-line);
|
|
795145
|
+
border-radius: var(--radius-sm);
|
|
795146
|
+
background: var(--nclp-bg-secondary);
|
|
795147
|
+
color: var(--nclp-muted);
|
|
795148
|
+
padding: 3px 6px;
|
|
795149
|
+
font-size: 9px;
|
|
795150
|
+
font-weight: 700;
|
|
795151
|
+
letter-spacing: 0.06em;
|
|
795152
|
+
text-transform: uppercase;
|
|
795153
|
+
white-space: nowrap;
|
|
795154
|
+
}
|
|
795155
|
+
|
|
795156
|
+
.observability-grid {
|
|
795157
|
+
display: grid;
|
|
795158
|
+
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
795159
|
+
gap: 12px;
|
|
795160
|
+
min-width: 0;
|
|
795161
|
+
align-items: start;
|
|
795162
|
+
}
|
|
795163
|
+
.observability-card {
|
|
795164
|
+
position: relative;
|
|
795165
|
+
min-width: 0;
|
|
795166
|
+
overflow: hidden;
|
|
795167
|
+
border: 1px solid var(--nclp-line);
|
|
795168
|
+
border-radius: var(--radius-lg);
|
|
795169
|
+
background: var(--nclp-card);
|
|
795170
|
+
box-shadow: var(--nclp-shadow);
|
|
795171
|
+
}
|
|
795172
|
+
.observability-card::before {
|
|
795173
|
+
content: "";
|
|
795174
|
+
position: absolute;
|
|
795175
|
+
z-index: 2;
|
|
795176
|
+
top: 0;
|
|
795177
|
+
left: 0;
|
|
795178
|
+
width: 38px;
|
|
795179
|
+
height: 2px;
|
|
795180
|
+
background: var(--nclp-yellow);
|
|
795181
|
+
pointer-events: none;
|
|
795182
|
+
}
|
|
795183
|
+
.observability-card__header {
|
|
795184
|
+
display: grid;
|
|
795185
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
795186
|
+
align-items: center;
|
|
795187
|
+
gap: 10px;
|
|
795188
|
+
min-width: 0;
|
|
795189
|
+
padding: 10px 12px 8px;
|
|
795190
|
+
border-bottom: 1px solid var(--nclp-line);
|
|
795191
|
+
}
|
|
795192
|
+
.observability-card__title {
|
|
795193
|
+
min-width: 0;
|
|
795194
|
+
margin: 0 !important;
|
|
795195
|
+
color: var(--nclp-text) !important;
|
|
795196
|
+
font-size: 10px !important;
|
|
795197
|
+
letter-spacing: 0.1em !important;
|
|
795198
|
+
text-transform: uppercase !important;
|
|
795199
|
+
}
|
|
795200
|
+
.observability-card__meta {
|
|
795201
|
+
overflow: hidden;
|
|
795202
|
+
color: var(--nclp-quiet);
|
|
795203
|
+
font-size: 9px;
|
|
795204
|
+
text-overflow: ellipsis;
|
|
795205
|
+
white-space: nowrap;
|
|
795206
|
+
}
|
|
795207
|
+
.observability-card__body {
|
|
795208
|
+
min-width: 0;
|
|
795209
|
+
padding: 11px 12px 12px;
|
|
795210
|
+
}
|
|
795211
|
+
.observability-card__body--flush { padding: 0; }
|
|
795212
|
+
.observability-span-2 { grid-column: span 2; }
|
|
795213
|
+
.observability-span-3 { grid-column: span 3; }
|
|
795214
|
+
.observability-span-4 { grid-column: span 4; }
|
|
795215
|
+
.observability-span-6 { grid-column: 1 / -1; }
|
|
795216
|
+
|
|
795217
|
+
.observability-facts {
|
|
795218
|
+
display: grid;
|
|
795219
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
795220
|
+
gap: 7px;
|
|
795221
|
+
min-width: 0;
|
|
795222
|
+
}
|
|
795223
|
+
.observability-facts > * {
|
|
795224
|
+
min-width: 0;
|
|
795225
|
+
margin: 0 !important;
|
|
795226
|
+
}
|
|
795227
|
+
.observability-stack {
|
|
795228
|
+
display: grid;
|
|
795229
|
+
gap: 7px;
|
|
795230
|
+
min-width: 0;
|
|
795231
|
+
}
|
|
795232
|
+
.observability-actions {
|
|
795233
|
+
display: flex;
|
|
795234
|
+
flex-wrap: wrap;
|
|
795235
|
+
align-items: center;
|
|
795236
|
+
gap: 7px;
|
|
795237
|
+
}
|
|
795238
|
+
.observability-actions > :is(input, select, textarea) { min-width: 0; }
|
|
795239
|
+
.observability-table-scroll { overflow-x: auto; overscroll-behavior-inline: contain; }
|
|
795240
|
+
|
|
795241
|
+
.route-workspace {
|
|
795242
|
+
display: flex;
|
|
795243
|
+
flex: 1;
|
|
795244
|
+
min-width: 0;
|
|
795245
|
+
min-height: 0;
|
|
795246
|
+
overflow: hidden;
|
|
795247
|
+
}
|
|
795248
|
+
.route-workspace__main {
|
|
795249
|
+
display: flex;
|
|
795250
|
+
flex: 1;
|
|
795251
|
+
flex-direction: column;
|
|
795252
|
+
min-width: 0;
|
|
795253
|
+
min-height: 0;
|
|
795254
|
+
overflow: hidden;
|
|
795255
|
+
}
|
|
795256
|
+
.route-scroll-region {
|
|
795257
|
+
min-width: 0;
|
|
795258
|
+
min-height: 0;
|
|
795259
|
+
overflow: auto;
|
|
795260
|
+
}
|
|
795261
|
+
.agent-command-body { padding: 11px 12px 12px; }
|
|
795262
|
+
.agent-command-body #agent-params { margin: 0; border: 0; background: transparent; }
|
|
795263
|
+
.agent-task-input { min-height: 120px !important; margin: 0 !important; }
|
|
795264
|
+
.agent-events-surface { min-height: 180px; }
|
|
795265
|
+
|
|
795266
|
+
.workspace-switcher { position: relative; flex: 1; min-width: 0; }
|
|
795267
|
+
.workspace-switcher__trigger {
|
|
795268
|
+
display: grid !important;
|
|
795269
|
+
grid-template-columns: 9px minmax(0, 1fr) 12px;
|
|
795270
|
+
align-items: center;
|
|
795271
|
+
gap: 8px;
|
|
795272
|
+
width: 100%;
|
|
795273
|
+
min-width: 0;
|
|
795274
|
+
padding: 5px 7px !important;
|
|
795275
|
+
text-align: left;
|
|
795276
|
+
}
|
|
795277
|
+
#sidebar-brand {
|
|
795278
|
+
overflow: hidden;
|
|
795279
|
+
color: var(--nclp-text) !important;
|
|
795280
|
+
font-size: 11px !important;
|
|
795281
|
+
letter-spacing: 0.01em !important;
|
|
795282
|
+
text-overflow: ellipsis;
|
|
795283
|
+
text-transform: none !important;
|
|
795284
|
+
white-space: nowrap;
|
|
795285
|
+
}
|
|
795286
|
+
.workspace-switcher__chevron { color: var(--nclp-quiet); transition: transform 0.14s ease; }
|
|
795287
|
+
.workspace-switcher__trigger[aria-expanded="true"] .workspace-switcher__chevron { transform: rotate(180deg); }
|
|
795288
|
+
.workspace-picker {
|
|
795289
|
+
position: absolute;
|
|
795290
|
+
z-index: 80;
|
|
795291
|
+
top: calc(100% + 6px);
|
|
795292
|
+
left: 0;
|
|
795293
|
+
width: min(420px, calc(100vw - 24px));
|
|
795294
|
+
max-height: min(520px, 72vh);
|
|
795295
|
+
overflow: hidden;
|
|
795296
|
+
border: 1px solid var(--nclp-line-strong);
|
|
795297
|
+
border-radius: var(--radius-lg);
|
|
795298
|
+
background: var(--nclp-card);
|
|
795299
|
+
box-shadow: 0 22px 56px rgba(0, 0, 0, 0.48);
|
|
795300
|
+
}
|
|
795301
|
+
.workspace-picker__header { padding: 10px; border-bottom: 1px solid var(--nclp-line); }
|
|
795302
|
+
.workspace-picker__header input { width: 100%; padding: 7px 9px; }
|
|
795303
|
+
.workspace-picker__list {
|
|
795304
|
+
display: grid;
|
|
795305
|
+
gap: 3px;
|
|
795306
|
+
max-height: 42vh;
|
|
795307
|
+
overflow-y: auto;
|
|
795308
|
+
padding: 6px;
|
|
795309
|
+
overscroll-behavior: contain;
|
|
795310
|
+
}
|
|
795311
|
+
.workspace-picker__option {
|
|
795312
|
+
display: grid !important;
|
|
795313
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
795314
|
+
align-items: center;
|
|
795315
|
+
gap: 10px;
|
|
795316
|
+
width: 100%;
|
|
795317
|
+
padding: 8px 9px !important;
|
|
795318
|
+
text-align: left;
|
|
795319
|
+
text-transform: none !important;
|
|
795320
|
+
}
|
|
795321
|
+
.workspace-picker__option[aria-selected="true"] {
|
|
795322
|
+
border-color: var(--nclp-yellow) !important;
|
|
795323
|
+
background: var(--nclp-amber-soft) !important;
|
|
795324
|
+
}
|
|
795325
|
+
.workspace-picker__option.is-keyboard-active {
|
|
795326
|
+
border-color: var(--nclp-yellow) !important;
|
|
795327
|
+
color: var(--nclp-yellow) !important;
|
|
795328
|
+
}
|
|
795329
|
+
.workspace-picker__name,
|
|
795330
|
+
.workspace-picker__path { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
795331
|
+
.workspace-picker__name { color: var(--nclp-text); font-size: 11px; font-weight: 700; }
|
|
795332
|
+
.workspace-picker__path { margin-top: 2px; color: var(--nclp-quiet); font-size: 9px; font-weight: 500; }
|
|
795333
|
+
.workspace-picker__check { color: var(--nclp-yellow); }
|
|
795334
|
+
.workspace-picker__empty { padding: 18px 10px; color: var(--nclp-quiet); font-size: 10px; text-align: center; }
|
|
795335
|
+
.workspace-picker__footer { display: flex; justify-content: flex-end; padding: 7px 9px; border-top: 1px solid var(--nclp-line); }
|
|
795336
|
+
#omnius-sidebar[data-collapsed="true"] .workspace-switcher { display: none; }
|
|
795337
|
+
|
|
795338
|
+
/* Generate keeps its purpose-built rails, but uses the same six-track span
|
|
795339
|
+
* proportions as the overview grids: 1/6 controls, 3/6 work, 2/6 signal. */
|
|
795340
|
+
.hud-workbench[data-layout="generate-workbench"] {
|
|
795341
|
+
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
795342
|
+
}
|
|
795343
|
+
.hud-workbench[data-layout="generate-workbench"] > #gen-mode-rail { grid-column: span 1; }
|
|
795344
|
+
.hud-workbench[data-layout="generate-workbench"] > main { grid-column: span 3; min-width: 0; }
|
|
795345
|
+
.hud-workbench[data-layout="generate-workbench"] > .hud-side-output { grid-column: span 2; min-width: 0; }
|
|
795346
|
+
|
|
795347
|
+
@media (max-width: 1180px) {
|
|
795348
|
+
.hud-workbench[data-layout="generate-workbench"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
795349
|
+
.hud-workbench[data-layout="generate-workbench"] > #gen-mode-rail,
|
|
795350
|
+
.hud-workbench[data-layout="generate-workbench"] > main { grid-column: span 1; }
|
|
795351
|
+
.hud-workbench[data-layout="generate-workbench"] > .hud-side-output { grid-column: 1 / -1; }
|
|
795352
|
+
}
|
|
795353
|
+
|
|
795354
|
+
@media (max-width: 820px) {
|
|
795355
|
+
.hud-workbench[data-layout="generate-workbench"] { grid-template-columns: minmax(0, 1fr); }
|
|
795356
|
+
.hud-workbench[data-layout="generate-workbench"] > #gen-mode-rail,
|
|
795357
|
+
.hud-workbench[data-layout="generate-workbench"] > main,
|
|
795358
|
+
.hud-workbench[data-layout="generate-workbench"] > .hud-side-output { grid-column: 1; }
|
|
795359
|
+
}
|
|
795360
|
+
|
|
795361
|
+
@media (max-width: 920px) {
|
|
795362
|
+
.observability-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
795363
|
+
.observability-span-2,
|
|
795364
|
+
.observability-span-3 { grid-column: span 1; }
|
|
795365
|
+
.observability-span-4,
|
|
795366
|
+
.observability-span-6 { grid-column: 1 / -1; }
|
|
795367
|
+
.observability-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
795368
|
+
}
|
|
795369
|
+
|
|
795370
|
+
@media (max-width: 760px) {
|
|
795371
|
+
.omnius-route-shell { padding: 10px !important; }
|
|
795372
|
+
.route-heading { grid-template-columns: 1fr; align-items: start; }
|
|
795373
|
+
.route-heading__signals { justify-content: flex-start; }
|
|
795374
|
+
.observability-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
|
|
795375
|
+
.observability-span-2,
|
|
795376
|
+
.observability-span-3,
|
|
795377
|
+
.observability-span-4,
|
|
795378
|
+
.observability-span-6 { grid-column: 1; }
|
|
795379
|
+
.observability-facts { grid-template-columns: minmax(0, 1fr); }
|
|
795380
|
+
.observability-card__header { grid-template-columns: minmax(0, 1fr); }
|
|
795381
|
+
.observability-card__meta { white-space: normal; }
|
|
795382
|
+
.observability-actions > :is(button, input, select) { max-width: 100%; }
|
|
795383
|
+
.workspace-picker { position: fixed; top: 54px; right: 12px; left: 12px; width: auto; }
|
|
795384
|
+
}
|
|
795385
|
+
|
|
794989
795386
|
@media (prefers-reduced-motion: reduce) {
|
|
794990
795387
|
*, *::before, *::after {
|
|
794991
795388
|
animation-duration: 0.01ms !important;
|
|
@@ -795014,8 +795411,22 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795014
795411
|
<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
795412
|
<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
795413
|
</button>
|
|
795017
|
-
<
|
|
795018
|
-
|
|
795414
|
+
<div class="workspace-switcher">
|
|
795415
|
+
<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">
|
|
795416
|
+
<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>
|
|
795417
|
+
<span id="sidebar-brand">No project</span>
|
|
795418
|
+
<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>
|
|
795419
|
+
</button>
|
|
795420
|
+
<section id="workspace-picker" class="workspace-picker" role="dialog" aria-label="Select workspace" style="display:none">
|
|
795421
|
+
<div class="workspace-picker__header">
|
|
795422
|
+
<input id="workspace-picker-search" type="search" placeholder="Filter workspaces..." autocomplete="off" aria-label="Filter workspaces" oninput="filterWorkspacePicker(this.value)" onkeydown="handleWorkspacePickerKeys(event)">
|
|
795423
|
+
</div>
|
|
795424
|
+
<div id="workspace-picker-list" class="workspace-picker__list" role="listbox" aria-label="Available workspaces"></div>
|
|
795425
|
+
<div class="workspace-picker__footer">
|
|
795426
|
+
<button type="button" onclick="closeWorkspacePicker(); switchTab('projects')">Manage workspaces</button>
|
|
795427
|
+
</div>
|
|
795428
|
+
</section>
|
|
795429
|
+
</div>
|
|
795019
795430
|
</div>
|
|
795020
795431
|
|
|
795021
795432
|
<!-- New chat button -->
|
|
@@ -795051,35 +795462,35 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795051
795462
|
|
|
795052
795463
|
<!-- Section nav (the legacy tabs migrated into the sidebar footer) -->
|
|
795053
795464
|
<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"
|
|
795465
|
+
<button class="sb-nav" data-tab="chat" data-route="/chat" aria-controls="chat-container" aria-current="page" onclick="switchTab('chat')" title="Chat">
|
|
795055
795466
|
<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
795467
|
<span class="sb-label">Chat</span>
|
|
795057
795468
|
</button>
|
|
795058
|
-
<button class="sb-nav" data-tab="agent"
|
|
795469
|
+
<button class="sb-nav" data-tab="agent" data-route="/agent" aria-controls="agent-panel" onclick="switchTab('agent')" title="Agent">
|
|
795059
795470
|
<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
795471
|
<span class="sb-label">Agent</span>
|
|
795061
795472
|
</button>
|
|
795062
|
-
<button class="sb-nav" data-tab="voice"
|
|
795473
|
+
<button class="sb-nav" data-tab="voice" data-route="/voice" aria-controls="voice-panel" onclick="switchTab('voice')" title="Voice">
|
|
795063
795474
|
<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
795475
|
<span class="sb-label">Voice</span>
|
|
795065
795476
|
</button>
|
|
795066
|
-
<button class="sb-nav" data-tab="generate" onclick="switchTab('generate')" title="Generate media">
|
|
795477
|
+
<button class="sb-nav" data-tab="generate" data-route="/generate" aria-controls="generate-panel" onclick="switchTab('generate')" title="Generate media">
|
|
795067
795478
|
<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
795479
|
<span class="sb-label">Generate</span>
|
|
795069
795480
|
</button>
|
|
795070
|
-
<button class="sb-nav" data-tab="projects" onclick="switchTab('projects')" title="Projects">
|
|
795481
|
+
<button class="sb-nav" data-tab="projects" data-route="/projects" aria-controls="projects-panel" onclick="switchTab('projects')" title="Projects">
|
|
795071
795482
|
<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
795483
|
<span class="sb-label">Projects</span>
|
|
795073
795484
|
</button>
|
|
795074
|
-
<button class="sb-nav" data-tab="jobs"
|
|
795485
|
+
<button class="sb-nav" data-tab="jobs" data-route="/dashboard" aria-controls="jobs-panel" onclick="switchTab('jobs')" title="Dashboard">
|
|
795075
795486
|
<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
795487
|
<span class="sb-label">Dashboard</span>
|
|
795077
795488
|
</button>
|
|
795078
|
-
<button class="sb-nav" data-tab="activity" onclick="switchTab('activity')" title="Activity">
|
|
795489
|
+
<button class="sb-nav" data-tab="activity" data-route="/activity" aria-controls="activity-panel" onclick="switchTab('activity')" title="Activity">
|
|
795079
795490
|
<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
795491
|
<span class="sb-label">Activity</span>
|
|
795081
795492
|
</button>
|
|
795082
|
-
<button class="sb-nav" data-tab="config"
|
|
795493
|
+
<button class="sb-nav" data-tab="config" data-route="/settings" aria-controls="config-panel" onclick="switchTab('config')" title="Settings">
|
|
795083
795494
|
<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
795495
|
<span class="sb-label">Settings</span>
|
|
795085
795496
|
</button>
|
|
@@ -795105,8 +795516,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795105
795516
|
<div id="omnius-main" style="flex:1;display:flex;flex-direction:column;min-width:0;overflow:hidden;background:var(--color-bg)">
|
|
795106
795517
|
|
|
795107
795518
|
<div id="header">
|
|
795108
|
-
<span class="
|
|
795109
|
-
<span class="status" id="status">connecting...</span>
|
|
795519
|
+
<span class="status" id="status" aria-live="polite" style="display:none">connecting...</span>
|
|
795110
795520
|
<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
795521
|
<select id="model-select"><option>loading...</option></select>
|
|
795112
795522
|
<button class="key-btn" id="files-btn" onclick="toggleFilesForActiveTab()" title="Toggle workspace sidebar (chat or agent depending on active tab)">files</button>
|
|
@@ -795148,7 +795558,9 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795148
795558
|
<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
795559
|
</div>
|
|
795150
795560
|
</div>
|
|
795151
|
-
<div id="chat-container" style="display:flex;flex:1;overflow:hidden">
|
|
795561
|
+
<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">
|
|
795562
|
+
${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"] })}
|
|
795563
|
+
<div class="route-workspace" data-layout="chat-split">
|
|
795152
795564
|
<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
795565
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
|
795154
795566
|
<span style="color:var(--color-brand);font-size:0.7rem;font-weight:bold">Workspace</span>
|
|
@@ -795158,7 +795570,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795158
795570
|
<div id="workspace-tree" style="color:var(--color-fg)"></div>
|
|
795159
795571
|
</div>
|
|
795160
795572
|
<!-- Vertical column: session topbar + checklist + conversation -->
|
|
795161
|
-
<div
|
|
795573
|
+
<div class="route-workspace__main">
|
|
795162
795574
|
<!-- WO-TASK-02 — Chat session topbar (separate storage from agent runs) -->
|
|
795163
795575
|
<div class="session-topbar" id="chat-session-topbar">
|
|
795164
795576
|
<span class="topbar-label">chat session</span>
|
|
@@ -795175,8 +795587,10 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795175
795587
|
</div>
|
|
795176
795588
|
<div id="conversation" style="flex:1;overflow-y:auto;padding:12px 16px;display:flex;flex-direction:column;gap:4px;min-height:0"></div>
|
|
795177
795589
|
</div>
|
|
795590
|
+
</div>
|
|
795178
795591
|
</div>
|
|
795179
|
-
<div id="agent-panel" style="display:none;flex:1;overflow:hidden;flex-direction:column">
|
|
795592
|
+
<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">
|
|
795593
|
+
${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
795594
|
<!-- WO-TASK-02 — Agent run topbar (separate storage from chat sessions) -->
|
|
795181
795595
|
<div class="session-topbar" id="agent-session-topbar">
|
|
795182
795596
|
<span class="topbar-label">agent run</span>
|
|
@@ -795188,7 +795602,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795188
795602
|
<button onclick="refreshAgentRunSelect()" title="Refresh the run list">⟳</button>
|
|
795189
795603
|
</div>
|
|
795190
795604
|
<!-- Body row: agent workspace sidebar (isolated from chat) | scrollable form -->
|
|
795191
|
-
<div
|
|
795605
|
+
<div class="route-workspace" data-layout="agent-form">
|
|
795192
795606
|
<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
795607
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
|
795194
795608
|
<span style="color:var(--color-brand);font-size:0.7rem;font-weight:bold">Agent Workspace</span>
|
|
@@ -795197,10 +795611,12 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795197
795611
|
<div id="agent-workspace-cwd" style="color:var(--color-fg-faint);font-size:0.6rem;margin-bottom:8px;word-break:break-all"></div>
|
|
795198
795612
|
<div id="agent-workspace-tree" style="color:var(--color-fg)"></div>
|
|
795199
795613
|
</div>
|
|
795200
|
-
<div style="flex:1;
|
|
795614
|
+
<div class="route-scroll-region" style="flex:1;padding:0 0 4px;">
|
|
795615
|
+
<div class="observability-grid">
|
|
795201
795616
|
<!-- Parameter form: all the dials for POST /v1/run -->
|
|
795202
|
-
<
|
|
795203
|
-
<
|
|
795617
|
+
<section class="observability-card observability-span-4" data-module="agent-parameters">
|
|
795618
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Run configuration</h2><span class="observability-card__meta">POST /v1/run</span></header>
|
|
795619
|
+
<div id="agent-params" class="observability-card__body agent-command-body" style="font-size:0.68rem">
|
|
795204
795620
|
<div style="display:grid;grid-template-columns:120px 1fr;gap:6px 12px;align-items:center">
|
|
795205
795621
|
<label style="color:var(--color-fg-muted)">Working dir</label>
|
|
795206
795622
|
<div style="display:flex;gap:4px;align-items:center">
|
|
@@ -795231,36 +795647,75 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795231
795647
|
<label style="color:var(--color-fg-muted)">Isolate workspace</label>
|
|
795232
795648
|
<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
795649
|
</div>
|
|
795234
|
-
|
|
795650
|
+
</div>
|
|
795651
|
+
</section>
|
|
795235
795652
|
|
|
795236
|
-
<
|
|
795237
|
-
|
|
795653
|
+
<section class="observability-card observability-span-2" data-module="agent-task-contract">
|
|
795654
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Task contract</h2><span class="observability-card__meta">persona + controls</span></header>
|
|
795655
|
+
<div class="observability-card__body observability-stack">
|
|
795656
|
+
<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>
|
|
795657
|
+
<div class="observability-actions">
|
|
795238
795658
|
<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
795659
|
<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
795660
|
<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
795661
|
</div>
|
|
795242
|
-
|
|
795662
|
+
</div>
|
|
795663
|
+
</section>
|
|
795664
|
+
|
|
795665
|
+
<section class="observability-card observability-span-6" data-module="agent-event-stream">
|
|
795666
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Event stream</h2><span class="observability-card__meta">tools · stdout · completion</span></header>
|
|
795667
|
+
<div id="agent-events" class="observability-card__body agent-events-surface" style="font-size:0.78rem;line-height:1.5"></div>
|
|
795668
|
+
</section>
|
|
795669
|
+
</div>
|
|
795243
795670
|
</div><!-- /scrollable agent body -->
|
|
795244
795671
|
</div><!-- /agent body row (sidebar | form) -->
|
|
795245
795672
|
</div>
|
|
795246
|
-
<div id="jobs-panel" style="display:none;flex:1;overflow-y:auto
|
|
795247
|
-
|
|
795248
|
-
<div
|
|
795249
|
-
|
|
795250
|
-
|
|
795251
|
-
|
|
795252
|
-
|
|
795253
|
-
|
|
795673
|
+
<div id="jobs-panel" class="omnius-route-shell" data-route-page="dashboard" data-route-tab="jobs" style="display:none;flex:1;overflow-y:auto">
|
|
795674
|
+
${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"] })}
|
|
795675
|
+
<div class="observability-grid" data-layout="dashboard-metrics">
|
|
795676
|
+
<section class="observability-card observability-span-6" data-module="runtime-health">
|
|
795677
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Runtime health</h2><span class="observability-card__meta">live daemon telemetry</span></header>
|
|
795678
|
+
<div id="dashboard-health" class="observability-card__body observability-facts"></div>
|
|
795679
|
+
</section>
|
|
795680
|
+
<section class="observability-card observability-span-2" data-module="active-processes">
|
|
795681
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Active processes</h2><span class="observability-card__meta">agent runs</span></header>
|
|
795682
|
+
<div id="dashboard-daemons" class="observability-card__body"></div>
|
|
795683
|
+
</section>
|
|
795684
|
+
<section class="observability-card observability-span-4" data-module="scheduled-tasks">
|
|
795685
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Scheduled tasks</h2><span class="observability-card__meta">automation control</span></header>
|
|
795686
|
+
<div id="dashboard-scheduled" class="observability-card__body"></div>
|
|
795687
|
+
</section>
|
|
795688
|
+
<section class="observability-card observability-span-3" data-module="services">
|
|
795689
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Services</h2><span class="observability-card__meta">systemd --user</span></header>
|
|
795690
|
+
<div id="dashboard-services" class="observability-card__body"></div>
|
|
795691
|
+
</section>
|
|
795692
|
+
<section class="observability-card observability-span-3" data-module="token-usage">
|
|
795693
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Token usage</h2><span class="observability-card__meta">persistent by provider</span></header>
|
|
795694
|
+
<div id="dashboard-usage" class="observability-card__body"></div>
|
|
795695
|
+
</section>
|
|
795696
|
+
<section class="observability-card observability-span-6" data-module="job-history">
|
|
795697
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Job history</h2><span class="observability-card__meta">latest 20 runs</span></header>
|
|
795698
|
+
<div class="observability-card__body observability-table-scroll"><div id="jobs-list" style="font-size:0.78rem"></div></div>
|
|
795699
|
+
</section>
|
|
795700
|
+
</div>
|
|
795254
795701
|
</div>
|
|
795255
|
-
<div id="config-panel" style="display:none;flex:1;overflow-y:auto
|
|
795256
|
-
|
|
795257
|
-
<div
|
|
795258
|
-
<
|
|
795259
|
-
|
|
795702
|
+
<div id="config-panel" class="omnius-route-shell" data-route-page="settings" data-route-tab="config" style="display:none;flex:1;overflow-y:auto">
|
|
795703
|
+
${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"] })}
|
|
795704
|
+
<div class="observability-grid" data-layout="config-form">
|
|
795705
|
+
<section class="observability-card observability-span-2" data-module="server-configuration">
|
|
795706
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Server configuration</h2><span class="observability-card__meta">read only</span></header>
|
|
795707
|
+
<div id="config-content" class="observability-card__body" style="font-size:0.78rem"></div>
|
|
795708
|
+
</section>
|
|
795709
|
+
<section class="observability-card observability-span-4" data-module="active-model">
|
|
795710
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Model</h2><span class="observability-card__meta">active inference target</span></header>
|
|
795711
|
+
<div class="observability-card__body observability-actions">
|
|
795260
795712
|
<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
795713
|
<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
|
-
|
|
795714
|
+
</div>
|
|
795715
|
+
</section>
|
|
795716
|
+
<section class="observability-card observability-span-6" data-module="inference-provider">
|
|
795717
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Inference provider</h2><span class="observability-card__meta">connection + authentication</span></header>
|
|
795718
|
+
<div class="observability-card__body">
|
|
795264
795719
|
<div id="config-endpoint" style="font-size:0.78rem;color:var(--color-fg-muted);margin-bottom:8px"></div>
|
|
795265
795720
|
<div id="config-recent-providers-section" style="display:none;margin-bottom:12px">
|
|
795266
795721
|
<div style="font-size:0.66rem;color:var(--color-fg-muted);margin-bottom:6px;font-weight:500">Previously connected</div>
|
|
@@ -795276,48 +795731,71 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795276
795731
|
</select>
|
|
795277
795732
|
<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
795733
|
</form>
|
|
795279
|
-
|
|
795280
|
-
|
|
795281
|
-
<
|
|
795282
|
-
|
|
795734
|
+
</div>
|
|
795735
|
+
</section>
|
|
795736
|
+
<section class="observability-card observability-span-3" data-module="agent-profiles">
|
|
795737
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Profiles</h2><span class="observability-card__meta">agent personas</span></header>
|
|
795738
|
+
<div id="config-profiles" class="observability-card__body" style="font-size:0.78rem"></div>
|
|
795739
|
+
</section>
|
|
795740
|
+
<section class="observability-card observability-span-3" data-module="conversation-export">
|
|
795741
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Export conversation</h2><span class="observability-card__meta">portable session record</span></header>
|
|
795742
|
+
<div class="observability-card__body observability-actions">
|
|
795283
795743
|
<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
795744
|
<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
795745
|
</div>
|
|
795746
|
+
</section>
|
|
795747
|
+
</div>
|
|
795286
795748
|
</div>
|
|
795287
|
-
<div id="activity-panel" style="display:none;flex:1;overflow-y:auto
|
|
795288
|
-
|
|
795289
|
-
<div
|
|
795749
|
+
<div id="activity-panel" class="omnius-route-shell" data-route-page="activity" data-route-tab="activity" style="display:none;flex:1;overflow-y:auto">
|
|
795750
|
+
${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"] })}
|
|
795751
|
+
<div class="observability-grid" data-layout="activity-ledger">
|
|
795752
|
+
<section class="observability-card observability-span-6" data-module="audit-log">
|
|
795753
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Audit log</h2><span class="observability-card__meta">latest 50 records</span></header>
|
|
795754
|
+
<div id="activity-feed" class="observability-card__body" style="font-size:0.72rem"></div>
|
|
795755
|
+
</section>
|
|
795756
|
+
</div>
|
|
795290
795757
|
</div>
|
|
795291
|
-
<div id="projects-panel" style="display:none;flex:1;overflow-y:auto
|
|
795292
|
-
|
|
795293
|
-
|
|
795294
|
-
|
|
795758
|
+
<div id="projects-panel" class="omnius-route-shell" data-route-page="projects" data-route-tab="projects" style="display:none;flex:1;overflow-y:auto">
|
|
795759
|
+
${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"] })}
|
|
795760
|
+
<div class="observability-grid" data-layout="project-toolbar">
|
|
795761
|
+
<section class="observability-card observability-span-6" data-module="workspace-tools">
|
|
795762
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Workspace tools</h2><span class="observability-card__meta">filter · scan · register</span></header>
|
|
795763
|
+
<div class="observability-card__body observability-actions">
|
|
795295
795764
|
<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
795765
|
<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
795766
|
<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
795767
|
</div>
|
|
795299
|
-
</
|
|
795300
|
-
<
|
|
795301
|
-
|
|
795768
|
+
</section>
|
|
795769
|
+
<section class="observability-card observability-span-2" data-module="current-workspace">
|
|
795770
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Current workspace</h2><span class="observability-card__meta">active context</span></header>
|
|
795771
|
+
<div id="projects-current" class="observability-card__body" style="font-size:0.72rem;color:var(--color-fg)">
|
|
795302
795772
|
<span style="color:var(--color-fg-subtle)">current:</span> <span id="projects-current-name" style="color:var(--color-brand)">(none)</span>
|
|
795303
795773
|
<span id="projects-current-root" style="color:var(--color-fg-subtle);margin-left:8px"></span>
|
|
795304
795774
|
</div>
|
|
795305
|
-
|
|
795306
|
-
<
|
|
795307
|
-
<
|
|
795775
|
+
</section>
|
|
795776
|
+
<section class="observability-card observability-span-4" data-module="workspace-registry">
|
|
795777
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Registered workspaces</h2><span class="observability-card__meta">select to activate</span></header>
|
|
795778
|
+
<div id="projects-list" class="observability-card__body" style="font-size:0.72rem"></div>
|
|
795779
|
+
</section>
|
|
795780
|
+
<section id="add-project-form" class="observability-card observability-span-6" data-module="register-workspace" style="display:none">
|
|
795781
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Add project</h2><span class="observability-card__meta">absolute filesystem path</span></header>
|
|
795782
|
+
<div class="observability-card__body">
|
|
795308
795783
|
<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
|
|
795784
|
+
<div class="observability-actions">
|
|
795310
795785
|
<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
795786
|
<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
795787
|
</div>
|
|
795788
|
+
</div>
|
|
795789
|
+
</section>
|
|
795313
795790
|
</div>
|
|
795314
795791
|
</div>
|
|
795315
795792
|
|
|
795316
795793
|
<!-- Generate tab — global media generation (image/video/audio/music) backed by
|
|
795317
795794
|
the unified ~/.omnius model store. Loads models from /v1/media/models,
|
|
795318
795795
|
generates via /v1/media/<kind>, and browses the global gallery. -->
|
|
795319
|
-
<div id="generate-panel" style="display:none;flex:1;overflow-y:auto
|
|
795320
|
-
|
|
795796
|
+
<div id="generate-panel" class="omnius-route-shell" data-route-page="generate" data-route-tab="generate" style="display:none;flex:1;overflow-y:auto">
|
|
795797
|
+
${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"] })}
|
|
795798
|
+
<div class="hud-workbench" data-layout="generate-workbench">
|
|
795321
795799
|
<aside class="hud-panel hud-panel--slant hud-rail" id="gen-mode-rail">
|
|
795322
795800
|
<div class="hud-panel__chrome" aria-hidden="true"></div>
|
|
795323
795801
|
<header class="hud-panel__header">
|
|
@@ -795486,9 +795964,12 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795486
795964
|
</div>
|
|
795487
795965
|
|
|
795488
795966
|
<!-- 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
|
-
|
|
795967
|
+
<div id="voice-panel" class="omnius-route-shell" data-route-page="voice" data-route-tab="voice" style="display:none;flex:1;overflow-y:auto">
|
|
795968
|
+
${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"] })}
|
|
795969
|
+
<div class="observability-grid" data-layout="voice-controls">
|
|
795970
|
+
<section class="observability-card observability-span-4" data-module="voice-session">
|
|
795971
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Voice session</h2><span class="observability-card__meta">mic ↔ ASR ↔ agent ↔ TTS</span></header>
|
|
795972
|
+
<div class="observability-card__body">
|
|
795492
795973
|
<div style="font-size:0.65rem;color:var(--color-fg-subtle);margin-bottom:8px">
|
|
795493
795974
|
Live mic ↔ ASR ↔ agent ↔ TTS over WebSocket. Audio routes over the same origin
|
|
795494
795975
|
as this page — works on localhost or over a forwarded public IP. Mic permission
|
|
@@ -795500,26 +795981,29 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795500
795981
|
<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
795982
|
</div>
|
|
795502
795983
|
<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
|
-
|
|
795984
|
+
</div>
|
|
795985
|
+
</section>
|
|
795504
795986
|
|
|
795505
|
-
<
|
|
795506
|
-
<
|
|
795507
|
-
<div
|
|
795987
|
+
<section class="observability-card observability-span-2" data-module="voice-model">
|
|
795988
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Voice model</h2><span class="observability-card__meta">active engine</span></header>
|
|
795989
|
+
<div class="observability-card__body observability-actions">
|
|
795508
795990
|
<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
795991
|
<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
795992
|
</div>
|
|
795511
|
-
</
|
|
795993
|
+
</section>
|
|
795512
795994
|
|
|
795513
|
-
<
|
|
795514
|
-
<
|
|
795515
|
-
|
|
795995
|
+
<section id="voice-model-options-panel" class="observability-card observability-span-3" data-module="voice-model-options">
|
|
795996
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Model options</h2><span class="observability-card__meta">engine capabilities</span></header>
|
|
795997
|
+
<div id="voice-model-options-content" class="observability-card__body" style="font-size:0.7rem;color:var(--color-fg-muted)"></div>
|
|
795998
|
+
</section>
|
|
795516
795999
|
|
|
795517
|
-
<
|
|
795518
|
-
<
|
|
795519
|
-
<div
|
|
796000
|
+
<section class="observability-card observability-span-3" data-module="voice-tts-test">
|
|
796001
|
+
<header class="observability-card__header"><h2 class="observability-card__title">Speech test</h2><span class="observability-card__meta">test active TTS</span></header>
|
|
796002
|
+
<div class="observability-card__body observability-actions">
|
|
795520
796003
|
<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
796004
|
<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
796005
|
</div>
|
|
796006
|
+
</section>
|
|
795523
796007
|
</div>
|
|
795524
796008
|
</div>
|
|
795525
796009
|
|
|
@@ -795592,7 +796076,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795592
796076
|
the mic button on the input row. The panel hits /v1/voice/start
|
|
795593
796077
|
to warm the engines on first open, /v1/voice/tts to synthesize
|
|
795594
796078
|
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">
|
|
796079
|
+
<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
796080
|
<div style="display:flex;gap:6px;align-items:center;margin-bottom:6px">
|
|
795597
796081
|
<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
796082
|
<button type="button" onclick="warmVoice()" style="font-size:0.74rem">warm</button>
|
|
@@ -795614,7 +796098,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795614
796098
|
<div id="input-row">
|
|
795615
796099
|
<span id="system-prompt-toggle" onclick="toggleSystemPrompt()" style="display:none">sys</span>
|
|
795616
796100
|
<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>
|
|
796101
|
+
<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
796102
|
<button id="send-btn" onclick="sendMessage()">send</button>
|
|
795619
796103
|
<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
796104
|
<!-- WO-CHAT-CHECKIN — teal accent button that takes the place of stop
|
|
@@ -795753,6 +796237,7 @@ html { scrollbar-color: var(--nclp-line-strong) var(--nclp-bg-main); }
|
|
|
795753
796237
|
</div>
|
|
795754
796238
|
|
|
795755
796239
|
<script>
|
|
796240
|
+
const webUiRouteSpecs = ${JSON.stringify(WEB_UI_ROUTE_SPECS)};
|
|
795756
796241
|
// ════════════════════════════════════════════════════════════════════
|
|
795757
796242
|
// Store layer — Svelte-writable shape, vanilla JS.
|
|
795758
796243
|
// ════════════════════════════════════════════════════════════════════
|
|
@@ -796013,18 +796498,8 @@ const $activeTab = writable('chat');
|
|
|
796013
796498
|
|
|
796014
796499
|
function parseInitialGuiRoute() {
|
|
796015
796500
|
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;
|
|
796501
|
+
const matched = webUiRouteSpecs.find(route => route.path === path || route.aliases.includes(path));
|
|
796502
|
+
const tab = matched?.tab || null;
|
|
796028
796503
|
let chatSession = null;
|
|
796029
796504
|
if (tab === 'chat') {
|
|
796030
796505
|
const qs = location.search.replace(/^\\?/, '').trim();
|
|
@@ -796223,36 +796698,18 @@ function _projectDisplayName(proj) {
|
|
|
796223
796698
|
if (!proj) return 'No project';
|
|
796224
796699
|
return proj.name || _projectPathLeaf(proj.root) || proj.root || 'Project';
|
|
796225
796700
|
}
|
|
796226
|
-
function _endpointDisplayName(endpoint) {
|
|
796227
|
-
if (!endpoint) return '';
|
|
796228
|
-
try { return new URL(endpoint).host || endpoint; } catch { return String(endpoint); }
|
|
796229
|
-
}
|
|
796230
796701
|
function renderProjectChrome() {
|
|
796231
796702
|
const proj = $currentProject.get ? $currentProject.get() : null;
|
|
796232
|
-
const cfg = $config.get ? ($config.get() || {}) : {};
|
|
796233
796703
|
const root = proj?.root || '';
|
|
796234
796704
|
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
796705
|
const brand = document.getElementById('sidebar-brand');
|
|
796241
796706
|
if (brand) {
|
|
796242
796707
|
brand.textContent = name;
|
|
796243
796708
|
brand.title = root || name;
|
|
796244
796709
|
}
|
|
796245
796710
|
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');
|
|
796711
|
+
statusEl.textContent = String(_connectionState || 'connecting');
|
|
796712
|
+
statusEl.title = root || name;
|
|
796256
796713
|
statusEl.className = /connected|ready|online/i.test(_connectionState || '') ? 'status live' : 'status';
|
|
796257
796714
|
}
|
|
796258
796715
|
try { _syncSidebarStatus(); } catch {}
|
|
@@ -796261,6 +796718,171 @@ function setConnectionState(state) {
|
|
|
796261
796718
|
_connectionState = state || 'connecting';
|
|
796262
796719
|
renderProjectChrome();
|
|
796263
796720
|
}
|
|
796721
|
+
|
|
796722
|
+
// Accessible workspace switcher based on the compact search/listbox pattern
|
|
796723
|
+
// used by Voryn. Project state still flows through Omnius's central store.
|
|
796724
|
+
let workspacePickerProjects = [];
|
|
796725
|
+
let workspacePickerIndex = -1;
|
|
796726
|
+
function workspacePickerElements() {
|
|
796727
|
+
return {
|
|
796728
|
+
trigger: document.getElementById('workspace-switcher-trigger'),
|
|
796729
|
+
picker: document.getElementById('workspace-picker'),
|
|
796730
|
+
search: document.getElementById('workspace-picker-search'),
|
|
796731
|
+
list: document.getElementById('workspace-picker-list'),
|
|
796732
|
+
};
|
|
796733
|
+
}
|
|
796734
|
+
function isWorkspacePickerOpen() {
|
|
796735
|
+
const { picker } = workspacePickerElements();
|
|
796736
|
+
return !!picker && picker.style.display !== 'none';
|
|
796737
|
+
}
|
|
796738
|
+
async function openWorkspacePicker() {
|
|
796739
|
+
const { trigger, picker, search } = workspacePickerElements();
|
|
796740
|
+
if (!trigger || !picker || !search) return;
|
|
796741
|
+
picker.style.display = 'block';
|
|
796742
|
+
trigger.setAttribute('aria-expanded', 'true');
|
|
796743
|
+
workspacePickerIndex = -1;
|
|
796744
|
+
await loadWorkspacePicker();
|
|
796745
|
+
requestAnimationFrame(() => { try { search.focus(); search.select(); } catch {} });
|
|
796746
|
+
}
|
|
796747
|
+
function closeWorkspacePicker(restoreFocus) {
|
|
796748
|
+
const { trigger, picker, search } = workspacePickerElements();
|
|
796749
|
+
if (!trigger || !picker) return;
|
|
796750
|
+
picker.style.display = 'none';
|
|
796751
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
796752
|
+
workspacePickerIndex = -1;
|
|
796753
|
+
if (search) search.value = '';
|
|
796754
|
+
if (restoreFocus) { try { trigger.focus(); } catch {} }
|
|
796755
|
+
}
|
|
796756
|
+
function toggleWorkspacePicker(event) {
|
|
796757
|
+
if (event) event.stopPropagation();
|
|
796758
|
+
if (isWorkspacePickerOpen()) closeWorkspacePicker(false);
|
|
796759
|
+
else openWorkspacePicker();
|
|
796760
|
+
}
|
|
796761
|
+
function workspaceAgo(ts) {
|
|
796762
|
+
if (!ts) return '';
|
|
796763
|
+
const seconds = Math.max(0, Math.floor((Date.now() - Number(ts)) / 1000));
|
|
796764
|
+
if (seconds < 60) return seconds + 's';
|
|
796765
|
+
if (seconds < 3600) return Math.floor(seconds / 60) + 'm';
|
|
796766
|
+
if (seconds < 86400) return Math.floor(seconds / 3600) + 'h';
|
|
796767
|
+
return Math.floor(seconds / 86400) + 'd';
|
|
796768
|
+
}
|
|
796769
|
+
function renderWorkspacePicker(query) {
|
|
796770
|
+
const { list } = workspacePickerElements();
|
|
796771
|
+
if (!list) return;
|
|
796772
|
+
const currentRoot = $currentProject.get?.()?.root || '';
|
|
796773
|
+
const needle = String(query || '').trim().toLowerCase();
|
|
796774
|
+
const matches = workspacePickerProjects.filter(project => {
|
|
796775
|
+
const haystack = (_projectDisplayName(project) + ' ' + (project.root || '')).toLowerCase();
|
|
796776
|
+
return !needle || haystack.includes(needle);
|
|
796777
|
+
});
|
|
796778
|
+
list.replaceChildren();
|
|
796779
|
+
if (!matches.length) {
|
|
796780
|
+
const empty = document.createElement('div');
|
|
796781
|
+
empty.className = 'workspace-picker__empty';
|
|
796782
|
+
empty.textContent = needle ? 'No matching workspaces' : 'No registered workspaces';
|
|
796783
|
+
list.appendChild(empty);
|
|
796784
|
+
return;
|
|
796785
|
+
}
|
|
796786
|
+
for (const project of matches) {
|
|
796787
|
+
const active = project.root === currentRoot;
|
|
796788
|
+
const option = document.createElement('button');
|
|
796789
|
+
option.type = 'button';
|
|
796790
|
+
option.className = 'workspace-picker__option';
|
|
796791
|
+
option.setAttribute('role', 'option');
|
|
796792
|
+
option.setAttribute('aria-selected', active ? 'true' : 'false');
|
|
796793
|
+
option.dataset.root = project.root || '';
|
|
796794
|
+
const copy = document.createElement('span');
|
|
796795
|
+
copy.style.minWidth = '0';
|
|
796796
|
+
const name = document.createElement('span');
|
|
796797
|
+
name.className = 'workspace-picker__name';
|
|
796798
|
+
name.textContent = _projectDisplayName(project);
|
|
796799
|
+
const path = document.createElement('span');
|
|
796800
|
+
path.className = 'workspace-picker__path';
|
|
796801
|
+
const age = workspaceAgo(project.lastSeen);
|
|
796802
|
+
path.textContent = (project.root || '') + (age ? ' · seen ' + age + ' ago' : '');
|
|
796803
|
+
const mark = document.createElement('span');
|
|
796804
|
+
mark.className = 'workspace-picker__check';
|
|
796805
|
+
mark.textContent = active ? 'active' : 'switch';
|
|
796806
|
+
copy.append(name, path);
|
|
796807
|
+
option.append(copy, mark);
|
|
796808
|
+
option.addEventListener('click', () => switchProjectRoot(project.root, option));
|
|
796809
|
+
list.appendChild(option);
|
|
796810
|
+
}
|
|
796811
|
+
}
|
|
796812
|
+
async function loadWorkspacePicker() {
|
|
796813
|
+
const { list, search } = workspacePickerElements();
|
|
796814
|
+
if (!list) return;
|
|
796815
|
+
list.innerHTML = '<div class="workspace-picker__empty">Loading workspaces...</div>';
|
|
796816
|
+
try {
|
|
796817
|
+
const response = await fetch('/v1/projects', { headers: headers() });
|
|
796818
|
+
if (!response.ok) throw new Error('HTTP ' + response.status);
|
|
796819
|
+
const data = await response.json();
|
|
796820
|
+
workspacePickerProjects = Array.isArray(data.projects) ? data.projects : [];
|
|
796821
|
+
const current = data.current && typeof data.current.root === 'string' ? data.current : null;
|
|
796822
|
+
if ($currentProject.get?.()?.root !== current?.root) $currentProject.set(current);
|
|
796823
|
+
renderWorkspacePicker(search?.value || '');
|
|
796824
|
+
} catch (error) {
|
|
796825
|
+
list.innerHTML = '<div class="workspace-picker__empty">Unable to load workspaces</div>';
|
|
796826
|
+
}
|
|
796827
|
+
}
|
|
796828
|
+
function filterWorkspacePicker(value) {
|
|
796829
|
+
workspacePickerIndex = -1;
|
|
796830
|
+
renderWorkspacePicker(value);
|
|
796831
|
+
}
|
|
796832
|
+
function handleWorkspacePickerKeys(event) {
|
|
796833
|
+
const { list } = workspacePickerElements();
|
|
796834
|
+
if (!list) return;
|
|
796835
|
+
const options = Array.from(list.querySelectorAll('.workspace-picker__option'));
|
|
796836
|
+
if (event.key === 'Escape') {
|
|
796837
|
+
event.preventDefault();
|
|
796838
|
+
closeWorkspacePicker(true);
|
|
796839
|
+
return;
|
|
796840
|
+
}
|
|
796841
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
796842
|
+
event.preventDefault();
|
|
796843
|
+
const delta = event.key === 'ArrowDown' ? 1 : -1;
|
|
796844
|
+
workspacePickerIndex = Math.max(0, Math.min(options.length - 1, workspacePickerIndex + delta));
|
|
796845
|
+
options.forEach((option, index) => option.classList.toggle('is-keyboard-active', index === workspacePickerIndex));
|
|
796846
|
+
options[workspacePickerIndex]?.scrollIntoView({ block: 'nearest' });
|
|
796847
|
+
return;
|
|
796848
|
+
}
|
|
796849
|
+
if (event.key === 'Enter' && options.length) {
|
|
796850
|
+
event.preventDefault();
|
|
796851
|
+
options[Math.max(0, workspacePickerIndex)]?.click();
|
|
796852
|
+
}
|
|
796853
|
+
}
|
|
796854
|
+
async function switchProjectRoot(root, pendingElement) {
|
|
796855
|
+
if (!root) return false;
|
|
796856
|
+
if (pendingElement) pendingElement.disabled = true;
|
|
796857
|
+
try {
|
|
796858
|
+
const response = await fetch('/v1/projects/switch', {
|
|
796859
|
+
method: 'POST',
|
|
796860
|
+
headers: { 'Content-Type': 'application/json', ...headers() },
|
|
796861
|
+
body: JSON.stringify({ root }),
|
|
796862
|
+
});
|
|
796863
|
+
if (!response.ok) {
|
|
796864
|
+
const error = await response.json().catch(() => ({ message: 'HTTP ' + response.status }));
|
|
796865
|
+
throw new Error(error.message || error.error || 'unknown error');
|
|
796866
|
+
}
|
|
796867
|
+
closeWorkspacePicker(true);
|
|
796868
|
+
await loadProjects();
|
|
796869
|
+
return true;
|
|
796870
|
+
} catch (error) {
|
|
796871
|
+
alert('Switch failed: ' + (error && error.message ? error.message : String(error)));
|
|
796872
|
+
if (pendingElement) pendingElement.disabled = false;
|
|
796873
|
+
return false;
|
|
796874
|
+
}
|
|
796875
|
+
}
|
|
796876
|
+
document.addEventListener('pointerdown', (event) => {
|
|
796877
|
+
if (isWorkspacePickerOpen() && !event.target.closest('.workspace-switcher')) closeWorkspacePicker(false);
|
|
796878
|
+
});
|
|
796879
|
+
document.addEventListener('keydown', (event) => {
|
|
796880
|
+
if (event.key === 'Escape' && isWorkspacePickerOpen()) closeWorkspacePicker(true);
|
|
796881
|
+
});
|
|
796882
|
+
window.toggleWorkspacePicker = toggleWorkspacePicker;
|
|
796883
|
+
window.closeWorkspacePicker = closeWorkspacePicker;
|
|
796884
|
+
window.filterWorkspacePicker = filterWorkspacePicker;
|
|
796885
|
+
window.handleWorkspacePickerKeys = handleWorkspacePickerKeys;
|
|
796264
796886
|
let streaming = false;
|
|
796265
796887
|
let messages = [];
|
|
796266
796888
|
let chatAbortController = null; // for stop button
|
|
@@ -797985,7 +798607,7 @@ async function _refreshVoiceState() {
|
|
|
797985
798607
|
}
|
|
797986
798608
|
|
|
797987
798609
|
function toggleVoicePanel() {
|
|
797988
|
-
const p = document.getElementById('voice-panel');
|
|
798610
|
+
const p = document.getElementById('voice-mini-panel');
|
|
797989
798611
|
if (!p) return;
|
|
797990
798612
|
if (p.style.display === 'none') {
|
|
797991
798613
|
p.style.display = 'block';
|
|
@@ -797995,7 +798617,7 @@ function toggleVoicePanel() {
|
|
|
797995
798617
|
}
|
|
797996
798618
|
}
|
|
797997
798619
|
function closeVoicePanel() {
|
|
797998
|
-
const p = document.getElementById('voice-panel');
|
|
798620
|
+
const p = document.getElementById('voice-mini-panel');
|
|
797999
798621
|
if (p) p.style.display = 'none';
|
|
798000
798622
|
}
|
|
798001
798623
|
window.toggleVoicePanel = toggleVoicePanel;
|
|
@@ -798275,36 +798897,14 @@ window.closeRemoteConnection = closeRemoteConnection;
|
|
|
798275
798897
|
})();
|
|
798276
798898
|
|
|
798277
798899
|
// Tab switching + browser route sync
|
|
798278
|
-
const allPanels =
|
|
798900
|
+
const allPanels = webUiRouteSpecs.map(route => route.panelId);
|
|
798279
798901
|
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';
|
|
798902
|
+
return webUiRouteSpecs.find(route => route.tab === tab)?.path || '/chat';
|
|
798291
798903
|
}
|
|
798292
798904
|
function tabForRoutePath(pathname) {
|
|
798293
798905
|
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';
|
|
798906
|
+
const matched = webUiRouteSpecs.find(route => route.path === path || route.aliases.includes(path));
|
|
798907
|
+
return matched?.tab || 'chat';
|
|
798308
798908
|
}
|
|
798309
798909
|
function chatSessionFromRouteSearch(search) {
|
|
798310
798910
|
const qs = String(search || '').replace(/^\\?/, '').trim();
|
|
@@ -798326,13 +798926,19 @@ function syncRouteForTab(tab, replace) {
|
|
|
798326
798926
|
}
|
|
798327
798927
|
function switchTab(tab, opts) {
|
|
798328
798928
|
opts = opts || {};
|
|
798329
|
-
const
|
|
798330
|
-
allPanels.forEach(id => {
|
|
798331
|
-
|
|
798929
|
+
const route = webUiRouteSpecs.find(candidate => candidate.tab === tab) || webUiRouteSpecs[0];
|
|
798930
|
+
allPanels.forEach(id => {
|
|
798931
|
+
const el = document.getElementById(id);
|
|
798932
|
+
if (!el) return;
|
|
798933
|
+
el.style.display = 'none';
|
|
798934
|
+
el.setAttribute('aria-hidden', 'true');
|
|
798935
|
+
});
|
|
798936
|
+
const panel = document.getElementById(route.panelId);
|
|
798332
798937
|
if (panel) {
|
|
798333
798938
|
// chat AND agent are flex containers (vertical column with sidebar/topbar);
|
|
798334
798939
|
// other panels are simple block scrollers.
|
|
798335
798940
|
panel.style.display = (tab === 'chat' || tab === 'agent') ? 'flex' : 'block';
|
|
798941
|
+
panel.setAttribute('aria-hidden', 'false');
|
|
798336
798942
|
}
|
|
798337
798943
|
document.getElementById('footer').style.display = tab === 'chat' ? 'flex' : 'none';
|
|
798338
798944
|
document.querySelectorAll('.tab').forEach(t => { t.style.borderBottomColor = 'transparent'; t.style.color = 'var(--color-fg-faint)'; });
|
|
@@ -798340,7 +798946,10 @@ function switchTab(tab, opts) {
|
|
|
798340
798946
|
if (active) { active.style.borderBottomColor = 'var(--color-brand)'; active.style.color = 'var(--color-brand)'; }
|
|
798341
798947
|
// OWUI-2: mirror active state on the sidebar nav
|
|
798342
798948
|
document.querySelectorAll('#omnius-sidebar .sb-nav').forEach(b => {
|
|
798343
|
-
|
|
798949
|
+
const isActive = b.getAttribute('data-tab') === tab;
|
|
798950
|
+
b.classList.toggle('active', isActive);
|
|
798951
|
+
if (isActive) b.setAttribute('aria-current', 'page');
|
|
798952
|
+
else b.removeAttribute('aria-current');
|
|
798344
798953
|
});
|
|
798345
798954
|
if ($activeTab.get && $activeTab.get() !== tab) $activeTab.set(tab);
|
|
798346
798955
|
if (!opts.fromRoute) syncRouteForTab(tab, !!opts.replaceRoute);
|
|
@@ -798363,6 +798972,9 @@ function switchTab(tab, opts) {
|
|
|
798363
798972
|
}
|
|
798364
798973
|
}
|
|
798365
798974
|
window.switchTab = switchTab;
|
|
798975
|
+
// Route activation must not depend on a registered/current project. Apply it
|
|
798976
|
+
// immediately, then project preference hydration may fill route-local state.
|
|
798977
|
+
if (initialGuiRoute.tab) switchTab(initialGuiRoute.tab, { fromRoute: true });
|
|
798366
798978
|
|
|
798367
798979
|
// ════════════════════════════════════════════════════════════
|
|
798368
798980
|
// Generate tab — global media generation (image/video/audio/music)
|
|
@@ -798979,27 +799591,8 @@ async function loadProjects() {
|
|
|
798979
799591
|
const root = decodeURIComponent(el.getAttribute('data-root') || '');
|
|
798980
799592
|
if (!root) return;
|
|
798981
799593
|
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
|
-
}
|
|
799594
|
+
const switched = await switchProjectRoot(root, el);
|
|
799595
|
+
if (!switched) el.style.opacity = '1';
|
|
799003
799596
|
});
|
|
799004
799597
|
});
|
|
799005
799598
|
} catch (e) {
|
|
@@ -799363,8 +799956,7 @@ async function loadDaemons() {
|
|
|
799363
799956
|
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
799957
|
return;
|
|
799365
799958
|
}
|
|
799366
|
-
el.innerHTML =
|
|
799367
|
-
d.runs.map(j =>
|
|
799959
|
+
el.innerHTML = d.runs.map(j =>
|
|
799368
799960
|
'<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
799961
|
'<span style="color:var(--color-brand)">' + (j.id||'').slice(0,12) + '</span> ' +
|
|
799370
799962
|
'<span style="color:var(--color-success)">running</span> ' +
|
|
@@ -799401,7 +799993,7 @@ async function loadScheduled() {
|
|
|
799401
799993
|
+ '</div>';
|
|
799402
799994
|
return row;
|
|
799403
799995
|
}).join('');
|
|
799404
|
-
el.innerHTML =
|
|
799996
|
+
el.innerHTML = rows
|
|
799405
799997
|
+ '<div style="margin-top:6px;display:flex;gap:8px">'
|
|
799406
799998
|
+ '<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
799999
|
+ '<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 +800155,7 @@ async function loadServices() {
|
|
|
799563
800155
|
+ '<div style="margin-top:4px;display:flex;gap:8px">' + stopBtn + disBtn + '</div>'
|
|
799564
800156
|
+ '</div>';
|
|
799565
800157
|
}).join('');
|
|
799566
|
-
el.innerHTML =
|
|
800158
|
+
el.innerHTML = rows;
|
|
799567
800159
|
} catch {}
|
|
799568
800160
|
}
|
|
799569
800161
|
|
|
@@ -799752,7 +800344,6 @@ async function loadDashboard() {
|
|
|
799752
800344
|
const totalIn = d.persistent?.totalIn || d.totalTokensIn || 0;
|
|
799753
800345
|
const totalOut = d.persistent?.totalOut || d.totalTokensOut || 0;
|
|
799754
800346
|
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
800347
|
'<div style="display:flex;gap:12px;flex-wrap:wrap;margin-bottom:8px">' +
|
|
799757
800348
|
'<div style="background:var(--color-bg-elevated);border:1px solid var(--color-bg-input);border-radius:3px;padding:8px 12px;flex:1">' +
|
|
799758
800349
|
'<div style="color:var(--color-fg-faint);font-size:0.6rem">TOTAL IN</div>' +
|
|
@@ -802718,6 +803309,7 @@ function toggleSidebar() {
|
|
|
802718
803309
|
const sb = document.getElementById('omnius-sidebar');
|
|
802719
803310
|
if (!sb) return;
|
|
802720
803311
|
const next = sb.getAttribute('data-collapsed') !== 'true';
|
|
803312
|
+
if (next) closeWorkspacePicker(false);
|
|
802721
803313
|
sb.setAttribute('data-collapsed', String(next));
|
|
802722
803314
|
_setLS(SIDEBAR_KEYS.collapsed, next ? '1' : '0');
|
|
802723
803315
|
}
|
|
@@ -804159,8 +804751,22 @@ input.focus();
|
|
|
804159
804751
|
</body>
|
|
804160
804752
|
</html>`;
|
|
804161
804753
|
}
|
|
804754
|
+
var WEB_UI_ROUTE_SPECS, WEB_UI_ROUTE_PATHS;
|
|
804162
804755
|
var init_web_ui = __esm({
|
|
804163
804756
|
"packages/cli/src/api/web-ui.ts"() {
|
|
804757
|
+
WEB_UI_ROUTE_SPECS = Object.freeze([
|
|
804758
|
+
{ tab: "chat", page: "chat", path: "/chat", aliases: ["/"], panelId: "chat-container" },
|
|
804759
|
+
{ tab: "agent", page: "agent", path: "/agent", aliases: [], panelId: "agent-panel" },
|
|
804760
|
+
{ tab: "voice", page: "voice", path: "/voice", aliases: [], panelId: "voice-panel" },
|
|
804761
|
+
{ tab: "generate", page: "generate", path: "/generate", aliases: [], panelId: "generate-panel" },
|
|
804762
|
+
{ tab: "projects", page: "projects", path: "/projects", aliases: [], panelId: "projects-panel" },
|
|
804763
|
+
{ tab: "jobs", page: "dashboard", path: "/dashboard", aliases: ["/jobs"], panelId: "jobs-panel" },
|
|
804764
|
+
{ tab: "activity", page: "activity", path: "/activity", aliases: [], panelId: "activity-panel" },
|
|
804765
|
+
{ tab: "config", page: "settings", path: "/settings", aliases: ["/config"], panelId: "config-panel" }
|
|
804766
|
+
]);
|
|
804767
|
+
WEB_UI_ROUTE_PATHS = Object.freeze(
|
|
804768
|
+
WEB_UI_ROUTE_SPECS.flatMap((route) => [route.path, ...route.aliases])
|
|
804769
|
+
);
|
|
804164
804770
|
}
|
|
804165
804771
|
});
|
|
804166
804772
|
|
|
@@ -811485,19 +812091,7 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
|
|
|
811485
812091
|
res.end(svg);
|
|
811486
812092
|
return;
|
|
811487
812093
|
}
|
|
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
|
-
]);
|
|
812094
|
+
const guiRoutes = new Set(WEB_UI_ROUTE_PATHS);
|
|
811501
812095
|
if (guiRoutes.has(pathname) && method === "GET" && req3.headers.accept?.includes("text/html")) {
|
|
811502
812096
|
const htmlHeaders = {
|
|
811503
812097
|
"Content-Type": "text/html; charset=utf-8",
|
|
@@ -827364,6 +827958,7 @@ ${taskInput}`;
|
|
|
827364
827958
|
}
|
|
827365
827959
|
try {
|
|
827366
827960
|
statusBar.setProcessing(true);
|
|
827961
|
+
statusBar.resumeUptimeTimer();
|
|
827367
827962
|
statusBar.recordSpeedTaskStart();
|
|
827368
827963
|
const task = startTask(
|
|
827369
827964
|
taskInput,
|
|
@@ -827446,6 +828041,7 @@ ${taskInput}`;
|
|
|
827446
828041
|
} finally {
|
|
827447
828042
|
statusBar.setProcessing(false);
|
|
827448
828043
|
statusBar.recordSpeedTaskEnd();
|
|
828044
|
+
statusBar.pauseUptimeTimer();
|
|
827449
828045
|
try {
|
|
827450
828046
|
const memSnippets = gatherMemorySnippets(repoRoot);
|
|
827451
828047
|
if (memSnippets.length > 0 && lastSubmittedPrompt) {
|