@agentikos/omega-os 0.19.44 → 0.19.46
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/bootstrap/lib/steps.sh +43 -0
- package/install.sh +8 -5
- package/omega/Agentik_Engine/omega_engine/__init__.py +1 -1
- package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/cli.py +16 -84
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +63 -92
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/package.json +1 -1
package/bootstrap/lib/steps.sh
CHANGED
|
@@ -1037,7 +1037,50 @@ PY
|
|
|
1037
1037
|
# Selection comes from the manifest's `claude_plugins:` list (headless) or a
|
|
1038
1038
|
# whiptail checklist (interactive). Failures on individual plugins are
|
|
1039
1039
|
# recorded but do not abort the step — Claude plugins are nice-to-have.
|
|
1040
|
+
_disable_broken_claude_plugins() {
|
|
1041
|
+
# v0.19.46 — detect + neutralize known-broken Claude Code plugins
|
|
1042
|
+
# before any `claude` session is spawned (AISB-chat, Hermès-chat,
|
|
1043
|
+
# auto-launch menu, etc.). Without this, broken plugins fire their
|
|
1044
|
+
# SessionStart hook on every claude invocation and pollute the TUI
|
|
1045
|
+
# with ugly stack traces.
|
|
1046
|
+
#
|
|
1047
|
+
# Currently neutralized:
|
|
1048
|
+
# * thedotmack/claude-mem@13.x — imports `zod/v3` which zod 4
|
|
1049
|
+
# removed; the SessionStart hook crashes on every claude start.
|
|
1050
|
+
# Upstream issue (no fix as of 2026-05-26).
|
|
1051
|
+
local cache_dir="${HOME}/.claude/plugins/cache"
|
|
1052
|
+
[ -d "$cache_dir" ] || return 0
|
|
1053
|
+
local found=0
|
|
1054
|
+
# claude-mem: look for the broken worker-service.cjs path.
|
|
1055
|
+
local cm
|
|
1056
|
+
for cm in "$cache_dir"/thedotmack/claude-mem/*/; do
|
|
1057
|
+
[ -d "$cm" ] || continue
|
|
1058
|
+
if [ -f "$cm/scripts/worker-service.cjs" ]; then
|
|
1059
|
+
# Probe the broken `zod/v3` require — if grep finds it, plugin is
|
|
1060
|
+
# the broken upstream version.
|
|
1061
|
+
if grep -q "require.*zod/v3\|require.*['\"]zod/v3['\"]" \
|
|
1062
|
+
"$cm/scripts/worker-service.cjs" 2>/dev/null; then
|
|
1063
|
+
local disabled="${cm%/}.disabled-by-omegaos"
|
|
1064
|
+
if [ ! -d "$disabled" ]; then
|
|
1065
|
+
mv "$cm" "$disabled" 2>/dev/null \
|
|
1066
|
+
&& info " neutralized broken claude-mem at $(basename "$cm") (zod/v3 import bug)" \
|
|
1067
|
+
&& found=1
|
|
1068
|
+
fi
|
|
1069
|
+
fi
|
|
1070
|
+
fi
|
|
1071
|
+
done
|
|
1072
|
+
if [ "$found" = "1" ]; then
|
|
1073
|
+
info " → re-enable later: \`mv ${cache_dir}/thedotmack/claude-mem.*.disabled-by-omegaos ${cache_dir}/thedotmack/claude-mem/\`"
|
|
1074
|
+
fi
|
|
1075
|
+
return 0
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1040
1078
|
step_claude_plugins() {
|
|
1079
|
+
# v0.19.46 — preflight: kill any known-broken plugins so the claude
|
|
1080
|
+
# commands we spawn later (and the user's interactive `claude` runs)
|
|
1081
|
+
# don't crash on hook startup.
|
|
1082
|
+
_disable_broken_claude_plugins
|
|
1083
|
+
|
|
1041
1084
|
local catalog="$OMEGA_HOME/Agentik_SSOT/claude-plugins/claude-plugins.yaml"
|
|
1042
1085
|
if [ ! -f "$catalog" ]; then
|
|
1043
1086
|
info "no Claude plugin catalog — skipping (step 20 should have deployed it)"
|
package/install.sh
CHANGED
|
@@ -290,11 +290,14 @@ post_install_card
|
|
|
290
290
|
# * an `omega` binary exists at the canonical path
|
|
291
291
|
#
|
|
292
292
|
# Otherwise we just print the instruction so the user knows what to do.
|
|
293
|
-
if [ -t 0 ] && [ "$
|
|
294
|
-
&& [ -x "$OMEGA_HOME/Agentik_Tools/bin/omega" ]; then
|
|
293
|
+
if [ -t 0 ] && [ -x "$OMEGA_HOME/Agentik_Tools/bin/omega" ]; then
|
|
295
294
|
log ""
|
|
296
|
-
log "${
|
|
297
|
-
log "${C_DIM}::${C_RST}
|
|
295
|
+
log "${C_ORANGE}::${C_RST} ${C_BOLD}Installation complete — launching Omega menu…${C_RST}"
|
|
296
|
+
log "${C_DIM}::${C_RST} press Esc or pick ${C_BOLD}Quit${C_RST} to exit the menu"
|
|
298
297
|
log ""
|
|
299
|
-
|
|
298
|
+
# v0.19.45 — auto-launch the Omega menu RIGHT NOW so the user sees the
|
|
299
|
+
# interactive surface immediately. No "type `omega` to open" prompt —
|
|
300
|
+
# just open it. exec replaces the install process so the menu owns
|
|
301
|
+
# the terminal cleanly.
|
|
302
|
+
exec "$OMEGA_HOME/Agentik_Tools/bin/omega"
|
|
300
303
|
fi
|
|
Binary file
|
|
Binary file
|
|
@@ -2981,91 +2981,23 @@ def _session_age(unix_ts: int) -> str:
|
|
|
2981
2981
|
|
|
2982
2982
|
|
|
2983
2983
|
def cmd_menu(_args: argparse.Namespace) -> int:
|
|
2984
|
-
"""`omega` (no args) —
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
Inside the Omega session you have:
|
|
2999
|
-
* window 0 (menu) — the action picker
|
|
3000
|
-
* spawned on demand: AISB-chat, Hermes-chat, projects, scratch shells
|
|
3001
|
-
* Ctrl-b w — tmux's own window picker
|
|
3002
|
-
* Ctrl-b z — tmux-claude session manager (if installed)
|
|
3003
|
-
|
|
3004
|
-
If you're already inside tmux (e.g. iTerm tmux integration), we
|
|
3005
|
-
don't take over the current session — we tell you how to switch
|
|
3006
|
-
to the Omega session manually.
|
|
2984
|
+
"""`omega` (no args) — render the Omega menu DIRECTLY in the current
|
|
2985
|
+
terminal. No tmux switch, no session attach, no message: just the menu.
|
|
2986
|
+
|
|
2987
|
+
v0.19.45 — RADICAL simplification. Previously we tried to be clever:
|
|
2988
|
+
detect $TMUX, switch-client to the persistent Omega session, attach,
|
|
2989
|
+
etc. Result: a brittle pipeline that printed "Switch to it with: ..."
|
|
2990
|
+
when the cleverness failed, leaving the user staring at a useless
|
|
2991
|
+
message. The user (correctly) called this "insupportable".
|
|
2992
|
+
|
|
2993
|
+
New behavior: `omega` = `omega menu-tui` = fzf TUI right here, right
|
|
2994
|
+
now. Works inside tmux, outside tmux, in iTerm, in Termius, anywhere.
|
|
2995
|
+
The menu's actions (open AISB chat, etc.) still use tmux for chat
|
|
2996
|
+
persistence — but the menu itself is just a fzf prompt in your
|
|
2997
|
+
current terminal, no indirection.
|
|
3007
2998
|
"""
|
|
3008
|
-
import
|
|
3009
|
-
|
|
3010
|
-
from omega_engine import tmux
|
|
3011
|
-
|
|
3012
|
-
OMEGA_SESSION = "Omega"
|
|
3013
|
-
|
|
3014
|
-
if not shutil.which("tmux"):
|
|
3015
|
-
print(" tmux not installed — `brew install tmux` (macOS) or "
|
|
3016
|
-
"`apt-get install tmux` (Linux)")
|
|
3017
|
-
return 2
|
|
3018
|
-
|
|
3019
|
-
if os.environ.get("TMUX"):
|
|
3020
|
-
# We're already inside a tmux client. Nested `tmux attach` is
|
|
3021
|
-
# rejected by tmux, but `tmux switch-client` works fine — and is
|
|
3022
|
-
# what the user wants when they type `omega` from inside tmux.
|
|
3023
|
-
# v0.19.41 — actually DO the switch instead of just printing
|
|
3024
|
-
# instructions. Print is the v0.19.40 bug ("ça lance rien du tout").
|
|
3025
|
-
import subprocess
|
|
3026
|
-
if not tmux.is_alive(OMEGA_SESSION):
|
|
3027
|
-
tmux.spawn_omega_master(_omega_home())
|
|
3028
|
-
# Are we already INSIDE the Omega session?
|
|
3029
|
-
proc = subprocess.run(
|
|
3030
|
-
["tmux", "display-message", "-p", "#S"],
|
|
3031
|
-
capture_output=True, text=True,
|
|
3032
|
-
)
|
|
3033
|
-
current = (proc.stdout or "").strip()
|
|
3034
|
-
if current == OMEGA_SESSION:
|
|
3035
|
-
# Already in Omega — just jump to the menu window. If the
|
|
3036
|
-
# menu window was killed, recreate it.
|
|
3037
|
-
wins = subprocess.run(
|
|
3038
|
-
["tmux", "list-windows", "-t", OMEGA_SESSION, "-F", "#W"],
|
|
3039
|
-
capture_output=True, text=True,
|
|
3040
|
-
)
|
|
3041
|
-
if "menu" not in (wins.stdout or "").split():
|
|
3042
|
-
subprocess.run(
|
|
3043
|
-
["tmux", "new-window", "-t", OMEGA_SESSION, "-n",
|
|
3044
|
-
"menu", "omega menu-tui"],
|
|
3045
|
-
capture_output=True,
|
|
3046
|
-
)
|
|
3047
|
-
subprocess.run(
|
|
3048
|
-
["tmux", "select-window", "-t", f"{OMEGA_SESSION}:menu"],
|
|
3049
|
-
capture_output=True,
|
|
3050
|
-
)
|
|
3051
|
-
else:
|
|
3052
|
-
# Different session — switch the client to Omega.
|
|
3053
|
-
subprocess.run(
|
|
3054
|
-
["tmux", "switch-client", "-t", OMEGA_SESSION],
|
|
3055
|
-
capture_output=True,
|
|
3056
|
-
)
|
|
3057
|
-
return 0
|
|
3058
|
-
|
|
3059
|
-
if not tmux.is_alive(OMEGA_SESSION):
|
|
3060
|
-
tmux.spawn_omega_master(_omega_home())
|
|
3061
|
-
|
|
3062
|
-
try:
|
|
3063
|
-
os.execvp("tmux", ["tmux", "attach", "-t", OMEGA_SESSION])
|
|
3064
|
-
except FileNotFoundError:
|
|
3065
|
-
print(" tmux not on PATH")
|
|
3066
|
-
return 2
|
|
3067
|
-
return 0
|
|
3068
|
-
|
|
2999
|
+
from omega_engine.tui import run_tui
|
|
3000
|
+
return run_tui()
|
|
3069
3001
|
|
|
3070
3002
|
def cmd_menu_tui(args: argparse.Namespace) -> int:
|
|
3071
3003
|
"""`omega menu-tui` — fzf arrow-key menu (default) / REPL / Textual.
|
package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -219,98 +219,69 @@ class TestAisbChat(unittest.TestCase):
|
|
|
219
219
|
self.assertEqual(history[1].text, "ok, will look into it")
|
|
220
220
|
|
|
221
221
|
|
|
222
|
-
class
|
|
223
|
-
"""v0.19.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
f"cmd_menu must call `tmux select-window -t Omega:menu` "
|
|
286
|
-
f"when already inside Omega. Captured: {calls}")
|
|
287
|
-
switch_calls = [c for c in calls
|
|
288
|
-
if isinstance(c, list)
|
|
289
|
-
and len(c) >= 2
|
|
290
|
-
and c[:2] == ["tmux", "switch-client"]]
|
|
291
|
-
self.assertEqual(switch_calls, [],
|
|
292
|
-
f"cmd_menu must NOT switch-client when already in Omega.")
|
|
293
|
-
|
|
294
|
-
def test_cmd_menu_does_not_print_hint_when_in_tmux(self):
|
|
295
|
-
"""REGRESSION — the v0.19.40 bug: cmd_menu printed
|
|
296
|
-
'Omega session is running. Switch to it with: ...' instead of
|
|
297
|
-
actually switching."""
|
|
298
|
-
import argparse, io, sys as _sys
|
|
299
|
-
with mock.patch.dict("os.environ", {"TMUX": "/tmp/tmux-fake,1,0"}):
|
|
300
|
-
class _Proc:
|
|
301
|
-
stdout = "Other\n"; returncode = 0
|
|
302
|
-
with mock.patch("subprocess.run", return_value=_Proc()), \
|
|
303
|
-
mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
|
|
304
|
-
mock.patch("omega_engine.tmux.is_alive", return_value=True), \
|
|
305
|
-
mock.patch.object(_sys, "stdout", new_callable=io.StringIO) as captured:
|
|
306
|
-
from omega_engine.cli import cmd_menu
|
|
307
|
-
cmd_menu(argparse.Namespace())
|
|
308
|
-
out = captured.getvalue()
|
|
309
|
-
self.assertNotIn("Switch to it with", out,
|
|
310
|
-
f"v0.19.40 regression: cmd_menu printed switch instructions "
|
|
311
|
-
f"instead of switching. Output: {out!r}")
|
|
312
|
-
self.assertNotIn("tmux switch-client -t Omega", out,
|
|
313
|
-
"cmd_menu must DO the switch, not print the command")
|
|
222
|
+
class TestBareOmegaRendersMenuDirectly(unittest.TestCase):
|
|
223
|
+
"""v0.19.45 — RADICAL simplification. Previously cmd_menu tried to
|
|
224
|
+
be clever (switch-client / select-window / attach). It was brittle
|
|
225
|
+
and printed "Switch to it with..." when the cleverness failed —
|
|
226
|
+
the user (correctly) called it "insupportable" through 3+ ships.
|
|
227
|
+
|
|
228
|
+
New contract: bare `omega` = run_tui() right in the current pane.
|
|
229
|
+
No tmux switch, no session attach, no print. The fzf menu just
|
|
230
|
+
renders inline."""
|
|
231
|
+
|
|
232
|
+
def test_cmd_menu_calls_run_tui_directly(self):
|
|
233
|
+
"""The new cmd_menu must delegate to omega_engine.tui.run_tui —
|
|
234
|
+
nothing else. No tmux switch, no session attach."""
|
|
235
|
+
import argparse, inspect
|
|
236
|
+
from omega_engine.cli import cmd_menu
|
|
237
|
+
src = inspect.getsource(cmd_menu)
|
|
238
|
+
self.assertIn("from omega_engine.tui import run_tui", src,
|
|
239
|
+
"cmd_menu must import run_tui directly")
|
|
240
|
+
self.assertIn("return run_tui()", src,
|
|
241
|
+
"cmd_menu must return run_tui() — direct menu render")
|
|
242
|
+
|
|
243
|
+
def test_cmd_menu_body_only_calls_run_tui(self):
|
|
244
|
+
"""REGRESSION — the user hit this through v0.19.40, .41, .42,
|
|
245
|
+
.43, .44: cmd_menu kept printing 'Omega session is running.
|
|
246
|
+
Switch to it with: tmux switch-client -t Omega' instead of just
|
|
247
|
+
showing a menu.
|
|
248
|
+
|
|
249
|
+
v0.19.45 ENFORCES the direct-render contract. We strip the
|
|
250
|
+
docstring + comments and verify the EXECUTABLE body is exactly:
|
|
251
|
+
from omega_engine.tui import run_tui
|
|
252
|
+
return run_tui()
|
|
253
|
+
Anything else (subprocess, switch-client, execvp, print of switch
|
|
254
|
+
instructions) is a regression.
|
|
255
|
+
"""
|
|
256
|
+
import inspect, ast
|
|
257
|
+
from omega_engine.cli import cmd_menu
|
|
258
|
+
src = inspect.getsource(cmd_menu)
|
|
259
|
+
# Parse the function body and inspect the AST nodes.
|
|
260
|
+
tree = ast.parse(src.strip())
|
|
261
|
+
fn = tree.body[0]
|
|
262
|
+
# Strip leading Expr-of-string-Constant (docstring).
|
|
263
|
+
body = [n for n in fn.body
|
|
264
|
+
if not (isinstance(n, ast.Expr)
|
|
265
|
+
and isinstance(n.value, ast.Constant)
|
|
266
|
+
and isinstance(n.value.value, str))]
|
|
267
|
+
# Expected: ImportFrom omega_engine.tui import run_tui ; Return.
|
|
268
|
+
kinds = [type(n).__name__ for n in body]
|
|
269
|
+
self.assertEqual(kinds, ["ImportFrom", "Return"],
|
|
270
|
+
f"cmd_menu body must be exactly [ImportFrom, Return]. "
|
|
271
|
+
f"Got: {kinds}. v0.19.40-.44 regression — somebody re-added "
|
|
272
|
+
f"tmux switch logic.")
|
|
273
|
+
# Confirm the ImportFrom is `from omega_engine.tui import run_tui`
|
|
274
|
+
imp = body[0]
|
|
275
|
+
self.assertEqual(imp.module, "omega_engine.tui",
|
|
276
|
+
"import must be from omega_engine.tui")
|
|
277
|
+
self.assertIn("run_tui", [n.name for n in imp.names],
|
|
278
|
+
"must import run_tui")
|
|
279
|
+
# Confirm the Return calls run_tui()
|
|
280
|
+
ret = body[1]
|
|
281
|
+
self.assertIsInstance(ret.value, ast.Call,
|
|
282
|
+
"return must be a function call")
|
|
283
|
+
self.assertEqual(ret.value.func.id, "run_tui",
|
|
284
|
+
"must return run_tui()")
|
|
314
285
|
|
|
315
286
|
|
|
316
287
|
if __name__ == "__main__":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.19.
|
|
1
|
+
0.19.46
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentikos/omega-os",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.46",
|
|
4
4
|
"description": "Omega OS — installable agentic operating system with verified-completion orchestration. Event-sourced engine, 8-block rack, autonomous agents, MCP.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"omega-os": "bin/omega-os.js"
|