@polderlabs/bizar-omp 0.4.1 → 0.4.2

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # BizarHarness OMP
2
2
 
3
- Release `0.4.1` is the current release target; it will be published on [npm](https://www.npmjs.com/package/@polderlabs/bizar-omp) and available as a [GitHub release](https://github.com/PolderLabsVOF/BizarHarness-OMP/releases/tag/v0.4.1) after the final release gate.
3
+ Release `0.4.2` is the current release target; it will be published on [npm](https://www.npmjs.com/package/@polderlabs/bizar-omp) and available as a [GitHub release](https://github.com/PolderLabsVOF/BizarHarness-OMP/releases/tag/v0.4.2) after the final release gate.
4
4
 
5
5
  BizarHarness OMP is a ground-up, native [oh-my-pi](https://github.com/can1357/oh-my-pi) extension for engineering workflows. It owns workflow intent, acceptance contracts, evidence freshness, and integration admission. OMP owns sessions, models, credentials, tools, workers, isolation, and conversation state.
6
6
 
@@ -19,6 +19,14 @@ omp
19
19
 
20
20
  This loads the extension, eight Bizar specialist agents, the default `bizar-omp` orientation skill plus specialized skills, rules, prompts, and the native model-role command. The main OMP session is the Bizar Orchestrator by default. Bizar also enables OMP's native Advisor and configures a visible `bizar_advisor` role for passive independent review. The skill explains Bizar's ownership boundaries, workflow/evidence tools, model-role command, and `omp` versus `omb` launcher contract. On session start, Bizar applies its autonomous OMP preset, enables background task execution, and enables steerable Collab. The ordinary `omp` command remains untouched; use `omb` when you want a durable tmux-backed host.
21
21
 
22
+ OMP's plugin manager owns the extension and all OMP-discoverable assets. It cannot place npm executables into your shell `PATH`, so `omb` and `bizar-omp` need the explicit all-in-one setup fallback:
23
+
24
+ ```sh
25
+ npx --yes @polderlabs/bizar-omp@0.4.2 setup
26
+ ```
27
+
28
+ `setup` installs the exact package version globally for both commands, installs that same version through `omp plugin install`, applies the autonomous settings with a recoverable receipt, and leaves credentials and explicit user policies intact. If you only need the OMP extension, `omp plugin install @polderlabs/bizar-omp` remains the primary path.
29
+
22
30
  The companion CLI is optional for diagnostics and repair:
23
31
 
24
32
  ```sh
@@ -27,11 +35,11 @@ bizar-omp install-doctor
27
35
  omb
28
36
  ```
29
37
 
30
- `bizar-omp install` remains available when a host-level repair is needed. The plugin path is the normal path and applies the same autonomous settings from the loaded extension. Worker patches are retained for explicit parent integration rather than automatically applied. Credentials, selected providers/models, explicit deny/prompt policies, and project overrides are preserved.
38
+ `bizar-omp install` remains available when a host-level repair is needed; `bizar-omp setup` is the one-command fallback when you need both the plugin and shell commands. The plugin path is the normal path and applies the same autonomous settings from the loaded extension. Worker patches are retained for explicit parent integration rather than automatically applied. Credentials, selected providers/models, explicit deny/prompt policies, and project overrides are preserved.
31
39
 
32
40
  Use only in trusted projects. OMP extensions and shell commands are not an OS security sandbox. Review changes with `bizar-omp install --dry-run`; isolate configuration with `bizar-omp install --profile bizar`, then launch `omp --profile bizar`. A new profile needs its own OMP login/model configuration.
33
41
 
34
- Restart OMP after plugin installation. `bizar-omp uninstall` removes the plugin link created by the CLI installer and restores settings it changed, preserving later user edits. Add the same `--profile` for profile-scoped commands. The global package install supplies the optional `omb` shell command; the plugin itself is still installed and updated through `omp plugin install`.
42
+ Restart OMP after plugin installation. `bizar-omp uninstall` removes the plugin installation created by the CLI installer and restores settings it changed, preserving later user edits. Add the same `--profile` for profile-scoped commands. The global package install supplies the `omb` and `bizar-omp` shell commands; the plugin itself is still installed and updated through `omp plugin install`.
35
43
 
36
44
  ## Development
37
45
 
@@ -85,9 +93,9 @@ Use the cross-project session switcher to see every Bizar-owned host, attach to
85
93
  omb agents
86
94
  ```
87
95
 
88
- The hub is intentionally small and keyboard-first: use Up/Down (or `j`/`k`) to select, Enter to attach, `n` to choose a project directory, task, and session name, `r` to refresh, and `q` to leave the hub. Sessions are identified by their project path and session id, so several sessions in one project remain independent. The hub only reads and controls tmux sessions created by Bizar; unrelated tmux sessions are not displayed or changed.
96
+ The hub is a full-screen Ink TUI with a workspace rail, grouped live-session list, selected-session inspector, status counts, and modal Settings, Help, and Delete views. It remains keyboard-first: use Up/Down (or `j`/`k`) to select, Enter to attach, `n` to choose a project directory, task, and session name, `e` to rename, `d` to delete after confirmation, `s` to open Settings, `r` to refresh, `?` for help, and `q` to leave the hub. Settings persist the latest-session reconnect preference, mouse scrolling, and whether stopped sessions are shown. Each Bizar host gets an isolated native OMP session journal, so the hub shows OMP's configured or auto-generated session title. Before OMP has generated a title, it derives a stable label from the first task; the project/id remains visible as secondary identity. Sessions are identified by their project path and Bizar session id, so several sessions in one project remain independent. The hub only reads and controls tmux sessions created by Bizar; unrelated tmux sessions are not displayed or changed.
89
97
 
90
- Run the objective in that host, then detach with `Ctrl-d` or the standard tmux sequence `Ctrl-b d`. `omb` scopes the `Ctrl-d` binding to its own session, so it disconnects the client instead of sending OMP's exit/EOF key to the host. If the host pane is already dead, the next `omb` detects it, respawns the host, and reconnects to the same project session. Closing the terminal window or detaching does not stop the tmux host. Bizar automatically enables `collab.autoStart=control` so the host is discoverable and steerable. Later, discover and reconnect to the live host:
98
+ Run the objective in that host, then use `Ctrl-d` or `Ctrl-c` to leave the client and return to the Bizar agents hub. Both keys are private to the Bizar tmux client, so they detach the view without sending EOF or interrupt input into OMP; the host and background work continue. The standard tmux sequence `Ctrl-b d` remains available too. Mouse scrolling is enabled by default and can be changed from Settings. If the host pane is already dead, the next `omb` detects it, respawns the host, and reconnects to the same project session. Closing the terminal window or detaching does not stop the tmux host. Bizar automatically enables `collab.autoStart=control` so the host is discoverable and steerable. Later, discover and reconnect to the live host:
91
99
 
92
100
  ```sh
93
101
  omp collab list
@@ -0,0 +1,22 @@
1
+ import { type OmbSessionInfo } from "../omp/omb-sessions.js";
2
+ import type { OmbSettings } from "../omp/omb-settings.js";
3
+ export type AgentsHubAction = {
4
+ type: "quit";
5
+ } | {
6
+ type: "attach";
7
+ session: OmbSessionInfo;
8
+ } | {
9
+ type: "new";
10
+ selected?: OmbSessionInfo;
11
+ } | {
12
+ type: "rename";
13
+ session: OmbSessionInfo;
14
+ } | {
15
+ type: "delete";
16
+ session: OmbSessionInfo;
17
+ } | {
18
+ type: "settings";
19
+ settings: OmbSettings;
20
+ };
21
+ export declare function runInkAgentsHub(cwd: string, env: NodeJS.ProcessEnv, sessions: OmbSessionInfo[], settings: OmbSettings): Promise<AgentsHubAction>;
22
+ //# sourceMappingURL=agents-ink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-ink.d.ts","sourceRoot":"","sources":["../../src/cli/agents-ink.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA0C,KAAK,cAAc,EAAwB,MAAM,wBAAwB,CAAC;AAC3H,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAE,CAAC;AA6ThD,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAOtJ"}
@@ -0,0 +1,177 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from "react";
3
+ import { Box, Text, useApp, useInput, useWindowSize, render } from "ink";
4
+ import { listOmbSessions, ombSessionDisplayName } from "../omp/omb-sessions.js";
5
+ const statusLabel = (state) => state === "attached" ? "CONNECTED" : state === "detached" ? "DISCONNECTED" : "STOPPED";
6
+ const statusColor = (state) => state === "attached" ? "green" : state === "detached" ? "yellow" : "gray";
7
+ const statusMark = (state) => state === "attached" ? "●" : state === "detached" ? "◌" : "○";
8
+ const short = (value, width) => value.length <= width ? value : width <= 1 ? value.slice(0, width) : `${value.slice(0, width - 1)}…`;
9
+ function age(session) {
10
+ const timestamp = session.lastAttachedAt ?? session.createdAt;
11
+ if (!timestamp)
12
+ return "age unknown";
13
+ const seconds = Math.max(0, Math.floor(Date.now() / 1000) - timestamp);
14
+ if (seconds < 60)
15
+ return "just now";
16
+ if (seconds < 3600)
17
+ return `${Math.floor(seconds / 60)}m ago`;
18
+ if (seconds < 86400)
19
+ return `${Math.floor(seconds / 3600)}h ago`;
20
+ return `${Math.floor(seconds / 86400)}d ago`;
21
+ }
22
+ function projectCounts(sessions) {
23
+ const counts = new Map();
24
+ for (const session of sessions)
25
+ counts.set(session.project, (counts.get(session.project) ?? 0) + 1);
26
+ return [...counts.entries()].sort(([a], [b]) => a.localeCompare(b));
27
+ }
28
+ function visibleSessions(allSessions, settings) {
29
+ return settings.showStoppedSessions ? allSessions : allSessions.filter(session => session.state !== "dead");
30
+ }
31
+ function Header({ cwd, sessions }) {
32
+ const connected = sessions.filter(session => session.state === "attached").length;
33
+ const disconnected = sessions.filter(session => session.state === "detached").length;
34
+ const stopped = sessions.filter(session => session.state === "dead").length;
35
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "cyan", children: "\u25C6 BIZAR / AGENTS HUB" }), _jsx(Text, { dimColor: true, children: short(cwd, 44) })] }), _jsxs(Box, { marginTop: 1, gap: 2, children: [_jsxs(Text, { color: "green", children: ["\u25CF ", connected, " connected"] }), _jsxs(Text, { color: "yellow", children: ["\u25CC ", disconnected, " disconnected"] }), _jsxs(Text, { color: "gray", children: ["\u25CB ", stopped, " stopped"] })] })] }));
36
+ }
37
+ function WorkspaceRail({ sessions, selected }) {
38
+ const projects = projectCounts(sessions);
39
+ return (_jsxs(Box, { width: "28%", minWidth: 24, flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "WORKSPACES" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "white", bold: true, children: ["\u203A ALL SESSIONS ", _jsx(Text, { dimColor: true, children: sessions.length })] }), projects.length === 0 ? _jsx(Text, { dimColor: true, children: " No active projects" }) : projects.map(([project, count]) => (_jsxs(Text, { color: selected?.project === project ? "cyan" : undefined, children: [selected?.project === project ? " › " : " ", short(project, 18), " ", _jsx(Text, { dimColor: true, children: count })] }, project)))] }), _jsxs(Box, { marginTop: 2, flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, color: "yellow", children: "LIVE VIEW" }), _jsx(Text, { dimColor: true, children: "Updates every few seconds." }), _jsx(Text, { dimColor: true, children: "Only bizar-* sessions" }), _jsx(Text, { dimColor: true, children: "are shown or changed." })] })] }));
40
+ }
41
+ function SessionRow({ session, selected, width }) {
42
+ const color = statusColor(session.state);
43
+ const displayName = ombSessionDisplayName(session);
44
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, backgroundColor: selected ? "blue" : undefined, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Text, { color: selected ? "white" : color, bold: selected, children: [selected ? "›" : " ", " ", statusMark(session.state), " ", short(displayName, Math.max(18, width - 28))] }), _jsx(Text, { color: selected ? "white" : color, dimColor: !selected, children: statusLabel(session.state) })] }), _jsxs(Box, { paddingLeft: 4, justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: short(`${session.project}/${session.id} · ${session.cwd}`, Math.max(20, width - 20)) }), _jsx(Text, { dimColor: true, children: age(session) })] })] }));
45
+ }
46
+ function SessionList({ sessions, selected, rows, width }) {
47
+ const visibleCount = Math.max(4, rows - 7);
48
+ const start = Math.max(0, Math.min(Math.max(0, sessions.length - visibleCount), selected - Math.floor(visibleCount / 2)));
49
+ const visible = sessions.slice(start, start + visibleCount);
50
+ let previous;
51
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "cyan", children: "SESSIONS" }), _jsx(Text, { dimColor: true, children: sessions.length ? `${start + 1}-${Math.min(start + visibleCount, sessions.length)} of ${sessions.length}` : "empty" })] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: visible.length === 0 ? (_jsxs(Box, { flexDirection: "column", paddingY: 2, children: [_jsx(Text, { color: "yellow", children: "No Bizar sessions are running." }), _jsx(Text, { dimColor: true, children: "Press n to dispatch a new agent session." })] })) : visible.map((session, offset) => {
52
+ const index = start + offset;
53
+ const heading = session.state !== previous;
54
+ previous = session.state;
55
+ return (_jsxs(Box, { flexDirection: "column", children: [heading && _jsxs(Text, { color: statusColor(session.state), bold: true, children: [statusMark(session.state), " ", statusLabel(session.state)] }), _jsx(SessionRow, { session: session, selected: index === selected, width: width })] }, session.name));
56
+ }) })] }));
57
+ }
58
+ function Inspector({ session }) {
59
+ return (_jsxs(Box, { width: "29%", minWidth: 25, flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "SELECTED SESSION" }), !session ? _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Select a session to inspect it." }) }) : (_jsxs(Box, { marginTop: 1, flexDirection: "column", gap: 1, children: [_jsxs(Text, { bold: true, color: statusColor(session.state), children: [statusMark(session.state), " ", statusLabel(session.state)] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "NAME" }), _jsx(Text, { children: ombSessionDisplayName(session) }), _jsx(Text, { dimColor: true, children: session.nativeName ? "OMP session title" : "Generated from task or project" })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "PROJECT" }), _jsx(Text, { children: short(session.cwd, 30) })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "COMMAND" }), _jsx(Text, { children: short(session.command || "omp", 30) })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "LAST ACTIVITY" }), _jsx(Text, { children: age(session) })] })] }))] }));
60
+ }
61
+ function Footer() {
62
+ return (_jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, justifyContent: "space-between", children: [_jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "Enter" }), " attach ", _jsx(Text, { color: "cyan", children: "n" }), " new ", _jsx(Text, { color: "cyan", children: "e" }), " rename ", _jsx(Text, { color: "cyan", children: "d" }), " delete"] }), _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "s" }), " settings ", _jsx(Text, { color: "cyan", children: "r" }), " refresh ", _jsx(Text, { color: "cyan", children: "?" }), " help ", _jsx(Text, { color: "cyan", children: "q" }), " quit"] })] }));
63
+ }
64
+ function Modal({ title, children, width, columns }) {
65
+ return (_jsxs(Box, { position: "absolute", top: 2, left: Math.max(0, Math.floor((columns - width) / 2)), width: width, flexDirection: "column", borderStyle: "double", borderColor: "cyan", backgroundColor: "black", paddingX: 2, paddingY: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: title }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: children })] }));
66
+ }
67
+ function SettingsModal({ settings, selected, columns, onToggle, onSave, onClose }) {
68
+ const options = [
69
+ ["Attach plain omb to latest live session", settings.autoAttachLatest],
70
+ ["Enable mouse scrolling in OMB sessions", settings.mouseScrolling],
71
+ ["Show stopped sessions in this view", settings.showStoppedSessions],
72
+ ];
73
+ return (_jsxs(Modal, { title: "OMB SETTINGS", width: Math.min(70, Math.max(46, columns - 6)), columns: columns, children: [options.map(([label, enabled], index) => (_jsxs(Text, { color: index === selected ? "white" : undefined, backgroundColor: index === selected ? "blue" : undefined, children: [index === selected ? "›" : " ", " [", enabled ? "on " : "off", "] ", label] }, label))), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "Up/Down select Space/Enter toggle s save Esc cancel" }), _jsx(Text, { color: "yellow", children: selected === 1 ? "Mouse mode applies to existing OMB sessions when saved." : "" }), _jsx(Text, { children: selected >= 0 ? "" : "" }), _jsx(SettingsKeyHandler, { onToggle: onToggle, onSave: onSave, onClose: onClose })] }));
74
+ }
75
+ function SettingsKeyHandler({ onToggle, onSave, onClose }) {
76
+ useInput((input, key) => {
77
+ if (key.upArrow || key.downArrow)
78
+ return;
79
+ if (key.escape)
80
+ onClose();
81
+ else if (input === " " || key.return)
82
+ onToggle();
83
+ else if (input === "s")
84
+ onSave();
85
+ });
86
+ return null;
87
+ }
88
+ function HelpModal({ columns, onClose }) {
89
+ useInput((input, key) => { if (key.escape || key.return || input === "q")
90
+ onClose(); });
91
+ return (_jsxs(Modal, { title: "OMB AGENTS SHORTCUTS", width: Math.min(64, Math.max(42, columns - 6)), columns: columns, children: [_jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "Enter" }), " attach to the selected session"] }), _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "n" }), " create a new session"] }), _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "e" }), " rename the selected session"] }), _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "d" }), " delete after confirmation"] }), _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "s" }), " open launcher settings"] }), _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "r" }), " refresh the session list"] }), _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "q / Esc" }), " leave this view"] }), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "Only tmux sessions with the bizar- prefix are managed." }), _jsx(Text, { dimColor: true, children: "Press Enter or Esc to return." })] }));
92
+ }
93
+ function DeleteModal({ session, columns, onConfirm, onClose }) {
94
+ useInput((input, key) => {
95
+ if (input.toLowerCase() === "y")
96
+ onConfirm();
97
+ else if (key.escape || key.return || input.length > 0)
98
+ onClose();
99
+ });
100
+ return (_jsxs(Modal, { title: "DELETE SESSION?", width: Math.min(64, Math.max(42, columns - 6)), columns: columns, children: [_jsxs(Text, { bold: true, children: [session.project, "/", session.id] }), _jsx(Text, { dimColor: true, children: short(session.cwd, 54) }), _jsx(Text, { children: " " }), _jsx(Text, { color: "yellow", children: "This stops OMP and removes the tmux session." }), _jsxs(Text, { children: ["Press ", _jsx(Text, { color: "red", bold: true, children: "y" }), " to delete, any other key to cancel."] })] }));
101
+ }
102
+ function AgentsApp({ cwd, env, sessions: initialSessions, settings: initialSettings, onAction }) {
103
+ const { columns, rows } = useWindowSize();
104
+ const [allSessions, setAllSessions] = useState(initialSessions);
105
+ const [settings, setSettings] = useState(initialSettings);
106
+ const [selected, setSelected] = useState(0);
107
+ const [overlay, setOverlay] = useState();
108
+ const [overlaySelected, setOverlaySelected] = useState(0);
109
+ const [draftSettings, setDraftSettings] = useState(initialSettings);
110
+ const { exit } = useApp();
111
+ const sessions = useMemo(() => visibleSessions(allSessions, settings), [allSessions, settings]);
112
+ const selectedSession = sessions[selected];
113
+ const refresh = async () => setAllSessions(await listOmbSessions(cwd, env));
114
+ useEffect(() => {
115
+ const timer = setInterval(() => { void refresh(); }, 3000);
116
+ return () => clearInterval(timer);
117
+ }, [cwd, env]);
118
+ useEffect(() => { setSelected(value => Math.min(value, Math.max(0, sessions.length - 1))); }, [sessions.length]);
119
+ const finish = (action) => { onAction(action); exit(); };
120
+ useInput((input, key) => {
121
+ if (overlay)
122
+ return;
123
+ if (key.ctrl && input === "c") {
124
+ finish({ type: "quit" });
125
+ return;
126
+ }
127
+ if (key.escape || input === "q") {
128
+ finish({ type: "quit" });
129
+ return;
130
+ }
131
+ if (key.upArrow || input === "k")
132
+ setSelected(value => Math.max(0, value - 1));
133
+ else if (key.downArrow || input === "j")
134
+ setSelected(value => Math.min(Math.max(0, sessions.length - 1), value + 1));
135
+ else if (key.return && selectedSession)
136
+ finish({ type: "attach", session: selectedSession });
137
+ else if (input === "n")
138
+ finish({ type: "new", selected: selectedSession });
139
+ else if (input === "e" && selectedSession)
140
+ finish({ type: "rename", session: selectedSession });
141
+ else if (input === "d" && selectedSession) {
142
+ setOverlay("delete");
143
+ }
144
+ else if (input === "r") {
145
+ void refresh();
146
+ }
147
+ else if (input === "?")
148
+ setOverlay("help");
149
+ else if (input === "s") {
150
+ setDraftSettings(settings);
151
+ setOverlaySelected(0);
152
+ setOverlay("settings");
153
+ }
154
+ });
155
+ return (_jsxs(Box, { flexDirection: "column", width: "100%", minHeight: Math.max(12, rows - 1), paddingX: 1, children: [_jsx(Header, { cwd: cwd, sessions: sessions }), _jsxs(Box, { flexGrow: 1, marginTop: 1, gap: 1, children: [_jsx(WorkspaceRail, { sessions: sessions, selected: selectedSession }), _jsx(SessionList, { sessions: sessions, selected: selected, rows: rows, width: Math.max(34, Math.floor(columns * 0.42)) }), _jsx(Inspector, { session: selectedSession })] }), _jsx(Footer, {}), overlay === "help" && _jsx(HelpModal, { columns: columns, onClose: () => setOverlay(undefined) }), overlay === "delete" && selectedSession && _jsx(DeleteModal, { session: selectedSession, columns: columns, onConfirm: () => finish({ type: "delete", session: selectedSession }), onClose: () => setOverlay(undefined) }), overlay === "settings" && (_jsx(SettingsModal, { settings: draftSettings, selected: overlaySelected, columns: columns, onToggle: () => {
156
+ const field = overlaySelected === 0 ? "autoAttachLatest" : overlaySelected === 1 ? "mouseScrolling" : "showStoppedSessions";
157
+ setDraftSettings(value => ({ ...value, [field]: !value[field] }));
158
+ }, onSave: () => finish({ type: "settings", settings: draftSettings }), onClose: () => setOverlay(undefined) })), overlay === "settings" && _jsx(SettingsNavigation, { selected: overlaySelected, onChange: setOverlaySelected })] }));
159
+ }
160
+ function SettingsNavigation({ selected, onChange }) {
161
+ useInput((_input, key) => {
162
+ if (key.upArrow)
163
+ onChange(Math.max(0, selected - 1));
164
+ else if (key.downArrow)
165
+ onChange(Math.min(2, selected + 1));
166
+ });
167
+ return null;
168
+ }
169
+ export async function runInkAgentsHub(cwd, env, sessions, settings) {
170
+ let action = { type: "quit" };
171
+ const app = render(_jsx(AgentsApp, { cwd: cwd, env: env, sessions: sessions, settings: settings, onAction: value => { action = value; } }), {
172
+ alternateScreen: true,
173
+ });
174
+ await app.waitUntilExit();
175
+ return action;
176
+ }
177
+ //# sourceMappingURL=agents-ink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-ink.js","sourceRoot":"","sources":["../../src/cli/agents-ink.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,14 @@
1
1
  #!/usr/bin/env node
2
+ import { type OmbSettings } from "../omp/omb-settings.js";
2
3
  import { type OmbSessionInfo } from "../omp/omb-sessions.js";
3
- export declare function renderAgentsHub(sessions: OmbSessionInfo[], selected: number): string;
4
- /** Run the small, keyboard-first cross-project session switcher. */
4
+ interface HubRenderOptions {
5
+ currentCwd?: string;
6
+ maxVisible?: number;
7
+ notice?: string;
8
+ }
9
+ export declare function renderAgentsHub(sessions: OmbSessionInfo[], selected: number, options?: HubRenderOptions): string;
10
+ export declare function renderSettingsOverlay(settings: OmbSettings, selected: number): string;
11
+ /** Run the keyboard-first cross-project session manager. */
5
12
  export declare function runAgentsHub(cwd?: string, _args?: string[], env?: NodeJS.ProcessEnv): Promise<number>;
13
+ export {};
6
14
  //# sourceMappingURL=agents.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/cli/agents.ts"],"names":[],"mappings":";AAQA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAW9E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAsBpF;AAiED,oEAAoE;AACpE,wBAAsB,YAAY,CAChC,GAAG,SAAgB,EACnB,KAAK,GAAE,MAAM,EAAO,EACpB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,MAAM,CAAC,CAkCjB"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/cli/agents.ts"],"names":[],"mappings":";AAeA,OAAO,EAAoC,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAA0C,KAAK,cAAc,EAAwB,MAAM,wBAAwB,CAAC;AAG3H,UAAU,gBAAgB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAiDD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EAAE,EAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,MAAM,CAoCR;AAiBD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYrF;AA0DD,4DAA4D;AAC5D,wBAAsB,YAAY,CAChC,GAAG,SAAgB,EACnB,KAAK,GAAE,MAAM,EAAO,EACpB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,MAAM,CAAC,CAsBjB"}
@@ -5,59 +5,123 @@ import { homedir } from "node:os";
5
5
  import { resolve } from "node:path";
6
6
  import { createInterface } from "node:readline/promises";
7
7
  import { stdin as input, stdout as output } from "node:process";
8
- import { attachOmbSession, launchOmb } from "../omp/tmux.js";
9
- import { listOmbSessions } from "../omp/omb-sessions.js";
8
+ import { attachOmbSession, deleteOmbSession, launchOmb, ombSessionName, renameOmbSession, setOmbSessionMouse, } from "../omp/tmux.js";
9
+ import { loadOmbSettings, saveOmbSettings } from "../omp/omb-settings.js";
10
+ import { listOmbSessions, ombSessionDisplayName } from "../omp/omb-sessions.js";
11
+ import { runInkAgentsHub } from "./agents-ink.js";
12
+ const RESET = "\u001b[0m";
13
+ const DIM = "\u001b[2m";
14
+ const BOLD = "\u001b[1m";
15
+ const REVERSE = "\u001b[7m";
10
16
  function generatedSessionId() {
11
17
  return `s-${Date.now().toString(36)}-${randomBytes(2).toString("hex")}`;
12
18
  }
13
- function sessionGroups(sessions) {
14
- const projects = new Set(sessions.map(session => session.cwd));
15
- return `${sessions.length} session${sessions.length === 1 ? "" : "s"} across ${projects.size} project${projects.size === 1 ? "" : "s"}`;
19
+ function statusLabel(state) {
20
+ return state === "attached" ? "connected" : state === "detached" ? "disconnected" : "stopped";
16
21
  }
17
- export function renderAgentsHub(sessions, selected) {
22
+ function sessionAge(session) {
23
+ const timestamp = session.lastAttachedAt ?? session.createdAt;
24
+ if (!timestamp)
25
+ return "age ?";
26
+ const seconds = Math.max(0, Math.floor(Date.now() / 1000) - timestamp);
27
+ if (seconds < 60)
28
+ return "now";
29
+ if (seconds < 3600)
30
+ return `${Math.floor(seconds / 60)}m`;
31
+ if (seconds < 86400)
32
+ return `${Math.floor(seconds / 3600)}h`;
33
+ return `${Math.floor(seconds / 86400)}d`;
34
+ }
35
+ function truncate(value, width) {
36
+ if (value.length <= width)
37
+ return value;
38
+ if (width <= 1)
39
+ return value.slice(0, width);
40
+ return `${value.slice(0, width - 1)}…`;
41
+ }
42
+ function sessionSummary(session, currentCwd, terminalWidth) {
43
+ const project = truncate(ombSessionDisplayName(session), 28).padEnd(28);
44
+ const location = session.cwd === currentCwd ? "current project" : session.cwd;
45
+ const locationWidth = Math.max(18, Math.min(44, terminalWidth - 28 - 12 - 8));
46
+ return `${project} ${statusLabel(session.state).padEnd(12)} ${truncate(location, locationWidth).padEnd(locationWidth)} ${sessionAge(session)}`;
47
+ }
48
+ function counts(sessions) {
49
+ const connected = sessions.filter(session => session.state === "attached").length;
50
+ const disconnected = sessions.filter(session => session.state === "detached").length;
51
+ const stopped = sessions.filter(session => session.state === "dead").length;
52
+ return `${sessions.length} session${sessions.length === 1 ? "" : "s"} · ${connected} connected · ${disconnected} disconnected · ${stopped} stopped`;
53
+ }
54
+ function sectionName(state) {
55
+ return state === "attached" ? "Connected" : state === "detached" ? "Disconnected" : "Stopped";
56
+ }
57
+ export function renderAgentsHub(sessions, selected, options = {}) {
58
+ const currentCwd = options.currentCwd || process.cwd();
59
+ const terminalWidth = Math.max(60, output.columns || 90);
60
+ const maxVisible = Math.max(4, options.maxVisible ?? Math.max(4, (output.rows || 24) - 10));
61
+ const start = Math.max(0, Math.min(Math.max(0, sessions.length - maxVisible), selected - Math.floor(maxVisible / 2)));
62
+ const visible = sessions.slice(start, start + maxVisible);
18
63
  const lines = [
19
- "Bizar Agents",
20
- sessionGroups(sessions),
64
+ `${BOLD}Bizar Agents${RESET}`,
65
+ counts(sessions),
66
+ `${DIM}${truncate(currentCwd, terminalWidth - 2)}${RESET}`,
21
67
  "",
22
- "Enter attach n new session r refresh q quit",
68
+ `${DIM}Enter attach n new e rename d delete s settings r refresh ? help q quit${RESET}`,
23
69
  "",
24
70
  ];
25
71
  if (sessions.length === 0) {
26
72
  lines.push("No Bizar sessions are running.", "", "Press n to dispatch a new session.");
27
- return `${lines.join("\n")}\n`;
28
73
  }
29
- for (const [index, session] of sessions.entries()) {
30
- const marker = index === selected ? ">" : " ";
31
- const status = session.state.padEnd(8);
32
- const id = session.id === "main" ? "main" : session.id;
33
- lines.push(`${marker} ${session.project}/${id} ${status} ${session.cwd}`);
74
+ else {
75
+ let previousState;
76
+ for (const [offset, session] of visible.entries()) {
77
+ const index = start + offset;
78
+ if (session.state !== previousState) {
79
+ lines.push(`${BOLD}${sectionName(session.state)}${RESET}`);
80
+ previousState = session.state;
81
+ }
82
+ const row = `${index === selected ? ">" : " "} ${sessionSummary(session, currentCwd, terminalWidth)}`;
83
+ lines.push(index === selected ? `${REVERSE}${row}${RESET}` : row);
84
+ }
85
+ if (start > 0 || start + visible.length < sessions.length) {
86
+ lines.push(`${DIM}Showing ${start + 1}-${start + visible.length} of ${sessions.length}. Use Up/Down to scroll.${RESET}`);
87
+ }
34
88
  }
35
- lines.push("", "The hub manages Bizar's durable OMP sessions; other tmux sessions are left untouched.");
89
+ if (options.notice)
90
+ lines.push("", `${options.notice}`);
91
+ lines.push("", `${DIM}Bizar owns only sessions with the bizar- prefix; unrelated tmux sessions are untouched.${RESET}`);
36
92
  return `${lines.join("\n")}\n`;
37
93
  }
38
- function keyOf(data) {
39
- const value = data.toString("utf8");
40
- if (value === "\u0003" || value === "q" || value === "\u0004")
41
- return "quit";
42
- if (value === "\r" || value === "\n")
43
- return "enter";
44
- if (value === "j" || value === "\u001b[B")
45
- return "down";
46
- if (value === "k" || value === "\u001b[A")
47
- return "up";
48
- if (value === "n")
49
- return "new";
50
- if (value === "r")
51
- return "refresh";
52
- return "other";
53
- }
54
- function nextKey() {
55
- return new Promise(resolveKey => {
56
- const onData = (data) => resolveKey(keyOf(data));
57
- input.once("data", onData);
94
+ function boxed(title, body, width = 58) {
95
+ const inner = width - 2;
96
+ const top = `┌${"".repeat(inner)}┐`;
97
+ const bottom = `└${"".repeat(inner)}┘`;
98
+ const rows = [`│ ${BOLD}${title}${RESET}${" ".repeat(Math.max(0, inner - title.length - 1))}│`];
99
+ const ansi = /\u001b\[[0-9;]*m/g;
100
+ for (const line of body) {
101
+ const visible = line.replace(ansi, "");
102
+ const clipped = truncate(visible, inner - 1);
103
+ const content = visible.length > inner - 1 ? clipped : line;
104
+ rows.push(`│ ${content}${" ".repeat(Math.max(0, inner - 1 - clipped.length))}│`);
105
+ }
106
+ return [top, ...rows, bottom].join("\n");
107
+ }
108
+ export function renderSettingsOverlay(settings, selected) {
109
+ const options = [
110
+ ["Attach plain omb to latest live session", settings.autoAttachLatest],
111
+ ["Enable mouse scrolling in OMB sessions", settings.mouseScrolling],
112
+ ["Show stopped sessions in this view", settings.showStoppedSessions],
113
+ ];
114
+ const body = options.map(([label, enabled], index) => {
115
+ const row = `${index === selected ? ">" : " "} [${enabled ? "on " : "off"}] ${label}`;
116
+ return index === selected ? `${REVERSE}${row}${RESET}` : row;
58
117
  });
118
+ body.push("", `${DIM}Up/Down select Space/Enter toggle s save Esc cancel${RESET}`);
119
+ return boxed("OMB Settings", body);
59
120
  }
60
121
  async function promptLine(prompt) {
122
+ // Ink unrefs stdin when it leaves raw mode. Re-ref it before handing the
123
+ // terminal to readline so an unanswered prompt keeps the CLI alive.
124
+ input.ref?.();
61
125
  input.setRawMode?.(false);
62
126
  input.resume();
63
127
  const readline = createInterface({ input, output });
@@ -72,12 +136,7 @@ async function promptLine(prompt) {
72
136
  function restoreTerminal() {
73
137
  input.setRawMode?.(false);
74
138
  input.pause();
75
- output.write("\u001b[?25h\u001b[0m\n");
76
- }
77
- function prepareTerminal() {
78
- output.write("\u001b[?25l");
79
- input.setRawMode?.(true);
80
- input.resume();
139
+ output.write(`${RESET}\u001b[?25h\n`);
81
140
  }
82
141
  async function dispatchSession(currentCwd, selected, env) {
83
142
  const defaultCwd = selected?.cwd && selected.cwd !== "?" ? selected.cwd : currentCwd;
@@ -90,48 +149,50 @@ async function dispatchSession(currentCwd, selected, env) {
90
149
  }
91
150
  const task = (await promptLine("Describe a task for the new session (optional): ")).trim();
92
151
  const requestedId = (await promptLine("Session name (blank=generated): ")).trim();
93
- const sessionId = requestedId || generatedSessionId();
94
152
  restoreTerminal();
95
- await launchOmb(projectCwd, task ? [task] : [], env, sessionId);
153
+ await launchOmb(projectCwd, task ? [task] : [], env, requestedId || generatedSessionId());
154
+ }
155
+ async function renameSession(session, env) {
156
+ const requestedId = (await promptLine(`New name for ${session.id} [${session.id}]: `)).trim() || session.id;
157
+ const projectCwd = session.cwd === "?" ? process.cwd() : session.cwd;
158
+ const nextName = ombSessionName(projectCwd, requestedId);
159
+ if (nextName === session.name)
160
+ return "Session name unchanged.";
161
+ const code = await renameOmbSession(session.name, nextName, projectCwd, env);
162
+ return code === 0 ? `Renamed session to ${requestedId}.` : "Could not rename that session.";
163
+ }
164
+ async function applySavedSettings(previous, next, sessions, cwd, env) {
165
+ saveOmbSettings(next, env);
166
+ if (previous.mouseScrolling !== next.mouseScrolling) {
167
+ await Promise.all(sessions.map(session => setOmbSessionMouse(session.name, next.mouseScrolling, cwd, env)));
168
+ }
96
169
  }
97
- /** Run the small, keyboard-first cross-project session switcher. */
170
+ /** Run the keyboard-first cross-project session manager. */
98
171
  export async function runAgentsHub(cwd = process.cwd(), _args = [], env = process.env) {
99
172
  if (!input.isTTY || !output.isTTY) {
100
173
  output.write("omb agents requires an interactive terminal.\n");
101
174
  return 1;
102
175
  }
103
- let sessions = await listOmbSessions(cwd, env);
104
- let selected = 0;
105
- try {
106
- while (true) {
107
- selected = Math.min(selected, Math.max(0, sessions.length - 1));
108
- output.write("\u001b[2J\u001b[H");
109
- output.write(renderAgentsHub(sessions, selected));
110
- prepareTerminal();
111
- const key = await nextKey();
112
- if (key === "quit")
113
- return 0;
114
- if (key === "up")
115
- selected = Math.max(0, selected - 1);
116
- else if (key === "down")
117
- selected = Math.min(Math.max(0, sessions.length - 1), selected + 1);
118
- else if (key === "refresh")
119
- sessions = await listOmbSessions(cwd, env);
120
- else if (key === "enter" && sessions[selected]) {
121
- const session = sessions[selected];
122
- restoreTerminal();
123
- await attachOmbSession(session.name, session.cwd === "?" ? cwd : session.cwd, env);
124
- sessions = await listOmbSessions(cwd, env);
125
- }
126
- else if (key === "new") {
127
- restoreTerminal();
128
- await dispatchSession(cwd, sessions[selected], env);
129
- sessions = await listOmbSessions(cwd, env);
130
- }
176
+ let settings = loadOmbSettings(env);
177
+ while (true) {
178
+ const allSessions = await listOmbSessions(cwd, env);
179
+ const sessions = settings.showStoppedSessions ? allSessions : allSessions.filter(session => session.state !== "dead");
180
+ const action = await runInkAgentsHub(cwd, env, sessions, settings);
181
+ if (action.type === "quit")
182
+ return 0;
183
+ if (action.type === "settings") {
184
+ await applySavedSettings(settings, action.settings, allSessions, cwd, env);
185
+ settings = action.settings;
186
+ continue;
131
187
  }
132
- }
133
- finally {
134
- restoreTerminal();
188
+ if (action.type === "attach")
189
+ await attachOmbSession(action.session.name, action.session.cwd === "?" ? cwd : action.session.cwd, env);
190
+ else if (action.type === "new")
191
+ await dispatchSession(cwd, action.selected, env);
192
+ else if (action.type === "rename")
193
+ await renameSession(action.session, env);
194
+ else if (action.type === "delete")
195
+ await deleteOmbSession(action.session.name, cwd, env);
135
196
  }
136
197
  }
137
198
  //# sourceMappingURL=agents.js.map