omnius 1.0.872 → 1.0.873
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 +2 -2
- package/dist/tui/native/worker.js +92 -13
- package/docs/DISCOVERY.json +32 -0
- package/docs/DISCOVERY.md +1 -0
- package/docs/reference/session-controls.md +11 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/dist/index.js
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 37773730 bytes
|
|
4
|
+
sha256: f762c00e6a2c7407ca37ff6c15bacffd0028cd2c2927dd91fd7db512549090c8
|
|
@@ -2055,7 +2055,7 @@ var NativeModalView = class {
|
|
|
2055
2055
|
return consume();
|
|
2056
2056
|
}
|
|
2057
2057
|
if (key.name === "tab") {
|
|
2058
|
-
if (this.spec.deferSelection || this.spec.captureKeys) this.emitAction(key.shift ? "shift-tab" : "tab");
|
|
2058
|
+
if (!this.spec.nativeTabNavigation && (this.spec.deferSelection || this.spec.captureKeys)) this.emitAction(key.shift ? "shift-tab" : "tab");
|
|
2059
2059
|
else this.nextControl(key.shift ? -1 : 1);
|
|
2060
2060
|
return consume();
|
|
2061
2061
|
}
|
|
@@ -5956,12 +5956,16 @@ var NativeTabStrip = class extends BoxRenderable9 {
|
|
|
5956
5956
|
const signature = JSON.stringify([items, activeId, busy]);
|
|
5957
5957
|
if (signature === this.signature) return;
|
|
5958
5958
|
this.signature = signature;
|
|
5959
|
+
const previousFocus = this.renderer.currentFocusedRenderable;
|
|
5960
|
+
const ownedFocus = Boolean(previousFocus) && [...this.buttons.values()].some((entry) => previousFocus === entry.button || previousFocus === entry.close);
|
|
5959
5961
|
const ids = new Set(items.map((item) => item.id));
|
|
5960
5962
|
for (const [id, entry] of this.buttons) if (!ids.has(id)) {
|
|
5961
5963
|
entry.button.destroy();
|
|
5964
|
+
entry.close?.destroy();
|
|
5962
5965
|
this.buttons.delete(id);
|
|
5963
5966
|
}
|
|
5964
|
-
|
|
5967
|
+
const controls = [];
|
|
5968
|
+
for (const action of items) {
|
|
5965
5969
|
let entry = this.buttons.get(action.id);
|
|
5966
5970
|
if (!entry) {
|
|
5967
5971
|
const button = new TextRenderable8(this.renderer, {
|
|
@@ -5991,35 +5995,73 @@ var NativeTabStrip = class extends BoxRenderable9 {
|
|
|
5991
5995
|
this.reveal = button.id;
|
|
5992
5996
|
});
|
|
5993
5997
|
button.on("blurred", () => this.style(entry));
|
|
5998
|
+
if (this.options.close) {
|
|
5999
|
+
const close2 = new TextRenderable8(this.renderer, {
|
|
6000
|
+
id: `${this.options.prefix}-close:${action.id}`,
|
|
6001
|
+
content: "×",
|
|
6002
|
+
width: 1,
|
|
6003
|
+
height: 1,
|
|
6004
|
+
flexShrink: 0,
|
|
6005
|
+
wrapMode: "none",
|
|
6006
|
+
selectable: false,
|
|
6007
|
+
fg: this.colors.foreground,
|
|
6008
|
+
bg: this.colors.background,
|
|
6009
|
+
onMouseDown: (event) => {
|
|
6010
|
+
if (event.button === 0 && !entry.blocked) {
|
|
6011
|
+
close2.focus();
|
|
6012
|
+
this.options.close(entry.action.id);
|
|
6013
|
+
}
|
|
6014
|
+
event.preventDefault();
|
|
6015
|
+
event.stopPropagation();
|
|
6016
|
+
},
|
|
6017
|
+
onKeyDown: (key) => this.handleKey(entry, key, true)
|
|
6018
|
+
});
|
|
6019
|
+
entry.close = close2;
|
|
6020
|
+
close2.on("focused", () => {
|
|
6021
|
+
this.style(entry);
|
|
6022
|
+
this.scroll.scrollChildIntoView(close2.id);
|
|
6023
|
+
this.reveal = close2.id;
|
|
6024
|
+
});
|
|
6025
|
+
close2.on("blurred", () => this.style(entry));
|
|
6026
|
+
}
|
|
5994
6027
|
}
|
|
5995
6028
|
entry.action = action;
|
|
5996
6029
|
entry.active = action.id === activeId;
|
|
5997
6030
|
entry.blocked = busy || Boolean(action.disabled);
|
|
5998
6031
|
entry.button.focusable = entry.active || !entry.blocked;
|
|
6032
|
+
if (entry.close) entry.close.focusable = !entry.blocked;
|
|
5999
6033
|
const label2 = plainText(action.label);
|
|
6000
6034
|
const content = ` ${label2} `;
|
|
6001
6035
|
if (entry.button.plainText !== content) entry.button.content = content;
|
|
6002
6036
|
this.style(entry);
|
|
6003
|
-
|
|
6037
|
+
controls.push(entry.button);
|
|
6038
|
+
if (entry.close) controls.push(entry.close);
|
|
6004
6039
|
}
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
if (
|
|
6040
|
+
for (const [index, control] of controls.entries()) if (this.scroll.getChildren()[index] !== control) this.scroll.add(control, index);
|
|
6041
|
+
this.naturalWidth = controls.reduce((width, control) => width + terminalCellWidth(control.plainText), 0) + Math.max(0, controls.length - 1);
|
|
6042
|
+
if (ownedFocus && (!previousFocus || previousFocus.isDestroyed || !previousFocus.focusable))
|
|
6043
|
+
(this.buttons.get(activeId)?.button ?? controls.find((control) => control.focusable))?.focus();
|
|
6008
6044
|
if (activeId !== this.activeId) this.reveal = `${this.options.prefix}:${activeId}`;
|
|
6009
6045
|
this.activeId = activeId;
|
|
6010
6046
|
this.renderer.requestRender();
|
|
6011
6047
|
}
|
|
6012
6048
|
style(entry) {
|
|
6013
6049
|
entry.button.attributes = (entry.active ? TextAttributes9.BOLD | TextAttributes9.UNDERLINE : entry.blocked ? TextAttributes9.DIM : 0) | (entry.button.focused ? TextAttributes9.INVERSE : 0);
|
|
6050
|
+
if (entry.close) entry.close.attributes = (entry.blocked || !entry.close.focused ? TextAttributes9.DIM : 0) | (entry.close.focused ? TextAttributes9.INVERSE : 0);
|
|
6014
6051
|
}
|
|
6015
|
-
handleKey(entry, key) {
|
|
6052
|
+
handleKey(entry, key, close2 = false) {
|
|
6016
6053
|
if (key.eventType === "release") return;
|
|
6017
6054
|
if (key.name === "return" || key.sequence === " ") {
|
|
6018
|
-
if (!entry.blocked)
|
|
6055
|
+
if (!entry.blocked) {
|
|
6056
|
+
if (close2) this.options.close?.(entry.action.id);
|
|
6057
|
+
else this.options.activate(entry.action.id);
|
|
6058
|
+
}
|
|
6059
|
+
} else if (this.options.close && (key.name === "delete" || key.ctrl && key.name.toLowerCase() === "w")) {
|
|
6060
|
+
if (!entry.blocked) this.options.close(entry.action.id);
|
|
6019
6061
|
} else if (["left", "right", "home", "end"].includes(key.name)) {
|
|
6020
|
-
const targets = this.scroll.getChildren().filter((button) => button.focusable);
|
|
6062
|
+
const targets = this.scroll.getChildren().filter((button) => button.focusable && button.id.startsWith(`${this.options.prefix}:`));
|
|
6021
6063
|
const index = targets.indexOf(entry.button);
|
|
6022
|
-
const next = key.name === "home" ? 0 : key.name === "end" ? targets.length - 1 : (index + (key.name === "left" ? -1 : 1) + targets.length) % targets.length;
|
|
6064
|
+
const next = key.name === "home" ? 0 : key.name === "end" ? targets.length - 1 : (index + (key.name === "left" ? close2 ? 0 : -1 : 1) + targets.length) % targets.length;
|
|
6023
6065
|
targets[next]?.focus();
|
|
6024
6066
|
} else return;
|
|
6025
6067
|
key.preventDefault();
|
|
@@ -6044,9 +6086,13 @@ var NativeTabStrip = class extends BoxRenderable9 {
|
|
|
6044
6086
|
};
|
|
6045
6087
|
applyTheme(colors) {
|
|
6046
6088
|
this.colors = colors;
|
|
6047
|
-
for (const { button } of this.buttons.values()) {
|
|
6089
|
+
for (const { button, close: close2 } of this.buttons.values()) {
|
|
6048
6090
|
button.fg = colors.foreground;
|
|
6049
6091
|
button.bg = colors.background;
|
|
6092
|
+
if (close2) {
|
|
6093
|
+
close2.fg = colors.foreground;
|
|
6094
|
+
close2.bg = colors.background;
|
|
6095
|
+
}
|
|
6050
6096
|
}
|
|
6051
6097
|
styleNativeScrollbars(this.scroll, colors);
|
|
6052
6098
|
styleNativeSlider(this.rail, colors);
|
|
@@ -6196,7 +6242,8 @@ var NativeFrontend = class {
|
|
|
6196
6242
|
id: "omnius-session-tabs",
|
|
6197
6243
|
prefix: "session",
|
|
6198
6244
|
colors,
|
|
6199
|
-
activate: (id) => this.emitAction("session", id)
|
|
6245
|
+
activate: (id) => this.emitAction("session", id),
|
|
6246
|
+
close: (id) => this.emitAction("session-close", id)
|
|
6200
6247
|
});
|
|
6201
6248
|
this.sessionRow.add(this.sessions);
|
|
6202
6249
|
this.newSession = new TextRenderable9(renderer2, {
|
|
@@ -6228,6 +6275,35 @@ var NativeFrontend = class {
|
|
|
6228
6275
|
this.newSession.on("focused", styleNew);
|
|
6229
6276
|
this.newSession.on("blurred", styleNew);
|
|
6230
6277
|
this.sessionRow.add(this.newSession);
|
|
6278
|
+
this.sessionPicker = new TextRenderable9(renderer2, {
|
|
6279
|
+
id: "omnius-session-picker",
|
|
6280
|
+
content: "SESSIONS",
|
|
6281
|
+
width: 8,
|
|
6282
|
+
height: 1,
|
|
6283
|
+
flexShrink: 0,
|
|
6284
|
+
selectable: false,
|
|
6285
|
+
fg: colors.foreground,
|
|
6286
|
+
bg: colors.background,
|
|
6287
|
+
onMouseDown: (event) => {
|
|
6288
|
+
if (event.button === 0 && !this.state?.sessions?.busy) this.emitAction("session-picker");
|
|
6289
|
+
event.preventDefault();
|
|
6290
|
+
event.stopPropagation();
|
|
6291
|
+
},
|
|
6292
|
+
onKeyDown: (key) => {
|
|
6293
|
+
if (key.eventType !== "release" && (key.name === "return" || key.sequence === " ")) {
|
|
6294
|
+
if (!this.state?.sessions?.busy) this.emitAction("session-picker");
|
|
6295
|
+
key.preventDefault();
|
|
6296
|
+
key.stopPropagation();
|
|
6297
|
+
}
|
|
6298
|
+
}
|
|
6299
|
+
});
|
|
6300
|
+
this.sessionPicker.focusable = true;
|
|
6301
|
+
const stylePicker = () => {
|
|
6302
|
+
this.sessionPicker.attributes = (this.state?.sessions?.busy ? TextAttributes10.DIM : 0) | (this.sessionPicker.focused ? TextAttributes10.INVERSE : 0);
|
|
6303
|
+
};
|
|
6304
|
+
this.sessionPicker.on("focused", stylePicker);
|
|
6305
|
+
this.sessionPicker.on("blurred", stylePicker);
|
|
6306
|
+
this.sessionRow.add(this.sessionPicker);
|
|
6231
6307
|
this.routeWarning = new TextRenderable9(renderer2, { id: "omnius-route-warning", content: "", width: "100%", wrapMode: "word", fg: colors.warning, attributes: TextAttributes10.BOLD | TextAttributes10.UNDERLINE, visible: false, flexShrink: 0 });
|
|
6232
6308
|
this.root.add(this.routeWarning);
|
|
6233
6309
|
this.taskPane = new BoxRenderable10(renderer2, { id: "omnius-tasks", width: "100%", flexDirection: "column", maxHeight: 6, flexShrink: 0, overflow: "hidden", visible: false });
|
|
@@ -6519,6 +6595,7 @@ var NativeFrontend = class {
|
|
|
6519
6595
|
sessionRow;
|
|
6520
6596
|
sessions;
|
|
6521
6597
|
newSession;
|
|
6598
|
+
sessionPicker;
|
|
6522
6599
|
taskPane;
|
|
6523
6600
|
taskStrip;
|
|
6524
6601
|
tasks;
|
|
@@ -6617,8 +6694,10 @@ var NativeFrontend = class {
|
|
|
6617
6694
|
this.sessionRow.visible = Boolean(state.sessions);
|
|
6618
6695
|
this.sessions.update(state.sessions?.items ?? [], state.sessions?.activeId ?? "", state.sessions?.busy);
|
|
6619
6696
|
this.newSession.focusable = !state.sessions?.busy;
|
|
6620
|
-
|
|
6697
|
+
this.sessionPicker.focusable = !state.sessions?.busy;
|
|
6698
|
+
if (state.sessions?.busy && (this.newSession.focused || this.sessionPicker.focused)) this.getRenderable(`session:${state.sessions.activeId}`)?.focus();
|
|
6621
6699
|
this.newSession.attributes = state.sessions?.busy ? TextAttributes10.DIM : this.newSession.focused ? TextAttributes10.INVERSE : 0;
|
|
6700
|
+
this.sessionPicker.attributes = state.sessions?.busy ? TextAttributes10.DIM : this.sessionPicker.focused ? TextAttributes10.INVERSE : 0;
|
|
6622
6701
|
this.tasks.replace(state.taskNotes ? [] : state.tasks);
|
|
6623
6702
|
this.taskPane.visible = !state.taskNotes && state.tasks.length > 0;
|
|
6624
6703
|
this.taskStrip.update(state.taskNotes);
|
package/docs/DISCOVERY.json
CHANGED
|
@@ -32538,6 +32538,38 @@
|
|
|
32538
32538
|
}
|
|
32539
32539
|
]
|
|
32540
32540
|
},
|
|
32541
|
+
{
|
|
32542
|
+
"id": "guide.reference-session-controls",
|
|
32543
|
+
"kind": "guide",
|
|
32544
|
+
"title": "Terminal session controls",
|
|
32545
|
+
"summary": "The header shows open sessions. Each tab has a separate × control. Closing a tab preserves its saved conversation and draft; closing the active tab selects a neighbour, or creates a new session when it was the last tab. Active work must finish or stop first. Failed transitions keep the original tab.",
|
|
32546
|
+
"keywords": [
|
|
32547
|
+
"reference",
|
|
32548
|
+
"session",
|
|
32549
|
+
"controls",
|
|
32550
|
+
"md"
|
|
32551
|
+
],
|
|
32552
|
+
"maturity": "stable",
|
|
32553
|
+
"audiences": [
|
|
32554
|
+
"user",
|
|
32555
|
+
"integrator",
|
|
32556
|
+
"coding-agent"
|
|
32557
|
+
],
|
|
32558
|
+
"layer": "documentation",
|
|
32559
|
+
"interfaces": [
|
|
32560
|
+
{
|
|
32561
|
+
"type": "file",
|
|
32562
|
+
"target": "docs/reference/session-controls.md"
|
|
32563
|
+
}
|
|
32564
|
+
],
|
|
32565
|
+
"references": [
|
|
32566
|
+
{
|
|
32567
|
+
"type": "documentation",
|
|
32568
|
+
"target": "docs/reference/session-controls.md",
|
|
32569
|
+
"relation": "canonical-artifact"
|
|
32570
|
+
}
|
|
32571
|
+
]
|
|
32572
|
+
},
|
|
32541
32573
|
{
|
|
32542
32574
|
"id": "guide.reference-slash-commands",
|
|
32543
32575
|
"kind": "guide",
|
package/docs/DISCOVERY.md
CHANGED
|
@@ -499,6 +499,7 @@ Daemon equivalents are `GET /v1/discovery/bootstrap`, `GET /v1/discovery?q=<inte
|
|
|
499
499
|
| `guide.reference-configuration` | Configuration Reference | Configuration is layered from environment, global user settings, project settings, and active TUI state. |
|
|
500
500
|
| `guide.reference-omni-analysis` | Omni media analysis | Omnius uses an explicitly configured Omni adapter for genuine audio and video comprehension. A model name containing -omni does not add audio/video execution to stock Ollama: the adapter must decode the media and run the corresponding model/projector weights. An unavailable runtime is an unavailable capability, never a reason to substitute synthetic observat |
|
|
501
501
|
| `guide.reference-rest-api` | REST API Reference | This is the maintained human inventory for the supported Omnius daemon API. The machine contract is generated by packages/cli/src/api/openapi.ts and served at /openapi.json; every operation in that contract must appear here. The root README links to this inventory and stays focused on the system overview. Browser HTML routes and implementation-only compatibi |
|
|
502
|
+
| `guide.reference-session-controls` | Terminal session controls | The header shows open sessions. Each tab has a separate × control. Closing a tab preserves its saved conversation and draft; closing the active tab selects a neighbour, or creates a new session when it was the last tab. Active work must finish or stop first. Failed transitions keep the original tab. |
|
|
502
503
|
| `guide.reference-slash-commands` | Slash Commands | This file is generated from packages/cli/src/tui/command-registry.ts. |
|
|
503
504
|
| `guide.reference-task-observability` | Tasks, notes and scoped work | The native terminal's details rail includes TASKS / NOTES. It presents the active session's checklist as a hierarchy, public operational notes, and recorded runner activity. It remains available during transcript scrollback. When viewing an agent tab, the session label identifies which session owns the displayed checklist. |
|
|
504
505
|
| `guide.reference-work-queue` | Mid-task intake and work queue | The native terminal's WORK / QUEUE section tracks user requests. TASKS / NOTES tracks the implementation steps, notes and observed execution layers within a task. Adding a request does not create a fake todo or replace the active objective. |
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Terminal session controls
|
|
2
|
+
|
|
3
|
+
The header shows open sessions. Each tab has a separate × control. Closing a tab preserves its saved conversation and draft; closing the active tab selects a neighbour, or creates a new session when it was the last tab. Active work must finish or stop first. Failed transitions keep the original tab.
|
|
4
|
+
|
|
5
|
+
**SESSIONS**, beside **+ NEW**, opens the saved-session catalog for the current project directory. Type to filter, use arrows to select, and press Enter to resume the original conversation. Tab and Shift+Tab traverse the filter and footer actions. Escape or an outside click closes the picker. `/sessions` and `/session` open the same picker in the native terminal.
|
|
6
|
+
|
|
7
|
+
The catalog includes saved sessions beyond the visible tab strip, including closed tabs and unsent drafts. Resuming restores the saved document and session identity through the existing session owner. It does not append a replay or request a generated summary.
|
|
8
|
+
|
|
9
|
+
**DELETE** requires a second confirmation and is available for inactive saved conversations. It removes the saved transcript, interface draft, catalog entries and current context projection. Generated media, shared model weights and operational audit records remain. Active work, pending delivery, update handoffs and concurrent writers can block removal; a failed or partial removal is reported in the modal. Close other terminal instances before deleting history they could save again.
|
|
10
|
+
|
|
11
|
+
The controls use the terminal palette and existing native modal dimming, corner animation and focus restoration. The right-side actions stay pinned while the tab strip scrolls within the remaining width.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.873",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.873",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED