@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 +13 -5
- package/dist/cli/agents-ink.d.ts +22 -0
- package/dist/cli/agents-ink.d.ts.map +1 -0
- package/dist/cli/agents-ink.js +177 -0
- package/dist/cli/agents-ink.js.map +1 -0
- package/dist/cli/agents.d.ts +10 -2
- package/dist/cli/agents.d.ts.map +1 -1
- package/dist/cli/agents.js +137 -76
- package/dist/cli/agents.js.map +1 -1
- package/dist/cli/install.d.ts +6 -2
- package/dist/cli/install.d.ts.map +1 -1
- package/dist/cli/install.js +21 -6
- package/dist/cli/install.js.map +1 -1
- package/dist/cli/main.js +15 -4
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/omb.js +9 -1
- package/dist/cli/omb.js.map +1 -1
- package/dist/omp/omb-sessions.d.ts +12 -0
- package/dist/omp/omb-sessions.d.ts.map +1 -1
- package/dist/omp/omb-sessions.js +148 -1
- package/dist/omp/omb-sessions.js.map +1 -1
- package/dist/omp/omb-settings.d.ts +10 -0
- package/dist/omp/omb-settings.d.ts.map +1 -0
- package/dist/omp/omb-settings.js +34 -0
- package/dist/omp/omb-settings.js.map +1 -0
- package/dist/omp/tmux.d.ts +6 -0
- package/dist/omp/tmux.d.ts.map +1 -1
- package/dist/omp/tmux.js +46 -10
- package/dist/omp/tmux.js.map +1 -1
- package/docs/compatibility/baseline.json +1 -1
- package/docs/releases/0.4.2.md +9 -0
- package/docs/releases/native-stable.md +1 -1
- package/package.json +6 -1
- package/skills/bizar-omp/SKILL.md +4 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# BizarHarness OMP
|
|
2
2
|
|
|
3
|
-
Release `0.4.
|
|
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
|
|
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
|
|
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
|
|
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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"}
|
package/dist/cli/agents.d.ts
CHANGED
|
@@ -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
|
-
|
|
4
|
-
|
|
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
|
package/dist/cli/agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/cli/agents.ts"],"names":[],"mappings":";
|
|
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"}
|
package/dist/cli/agents.js
CHANGED
|
@@ -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 {
|
|
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
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
20
|
-
|
|
64
|
+
`${BOLD}Bizar Agents${RESET}`,
|
|
65
|
+
counts(sessions),
|
|
66
|
+
`${DIM}${truncate(currentCwd, terminalWidth - 2)}${RESET}`,
|
|
21
67
|
"",
|
|
22
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
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
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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(
|
|
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,
|
|
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
|
|
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
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
134
|
-
|
|
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
|