@agentikos/omega-os 0.19.28 → 0.19.30
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/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/__pycache__/tui.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/cli.py +21 -13
- package/omega/Agentik_Engine/omega_engine/tui.py +301 -13
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2855,19 +2855,23 @@ def cmd_menu(_args: argparse.Namespace) -> int:
|
|
|
2855
2855
|
return 0
|
|
2856
2856
|
|
|
2857
2857
|
|
|
2858
|
-
def cmd_menu_tui(
|
|
2859
|
-
"""`omega menu-tui` —
|
|
2858
|
+
def cmd_menu_tui(args: argparse.Namespace) -> int:
|
|
2859
|
+
"""`omega menu-tui` — fzf arrow-key menu (default) / REPL / Textual.
|
|
2860
2860
|
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2861
|
+
v0.19.30 default = fzf arrow-key menu. Arrow keys + search-as-you-type
|
|
2862
|
+
+ mouse + Enter, with clean grouped layout (CHAT / PROJECTS / AUDITS
|
|
2863
|
+
/ INFRASTRUCTURE / HEALTH / SCRAPE / EXIT). Color-themed to Claude
|
|
2864
|
+
(orange #D97757 accents on dark backdrop).
|
|
2865
2865
|
|
|
2866
|
-
|
|
2867
|
-
|
|
2866
|
+
Flags:
|
|
2867
|
+
--repl → plain slash REPL (input() loop, type /commands)
|
|
2868
|
+
--textual → Textual app (opt-in, may break under tmux send-keys)
|
|
2868
2869
|
"""
|
|
2869
2870
|
from omega_engine.tui import run_tui
|
|
2870
|
-
return run_tui(
|
|
2871
|
+
return run_tui(
|
|
2872
|
+
prefer_textual=getattr(args, "textual", False),
|
|
2873
|
+
force_repl=getattr(args, "repl", False),
|
|
2874
|
+
)
|
|
2871
2875
|
|
|
2872
2876
|
|
|
2873
2877
|
def _legacy_fzf_menu(_args: argparse.Namespace) -> int:
|
|
@@ -4343,10 +4347,14 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
4343
4347
|
sub.add_parser("menu",
|
|
4344
4348
|
help="open the interactive whiptail menu (legacy)"
|
|
4345
4349
|
).set_defaults(fn=cmd_menu_whiptail)
|
|
4346
|
-
sub.add_parser("menu-tui",
|
|
4347
|
-
help="
|
|
4348
|
-
"
|
|
4349
|
-
|
|
4350
|
+
p_mt = sub.add_parser("menu-tui",
|
|
4351
|
+
help="fzf arrow-key menu (default), --repl for slash REPL, "
|
|
4352
|
+
"--textual for the Textual app")
|
|
4353
|
+
p_mt.add_argument("--textual", action="store_true",
|
|
4354
|
+
help="try the Textual app (fragile under tmux)")
|
|
4355
|
+
p_mt.add_argument("--repl", action="store_true",
|
|
4356
|
+
help="force slash REPL instead of the arrow menu")
|
|
4357
|
+
p_mt.set_defaults(fn=cmd_menu_tui)
|
|
4350
4358
|
sub.add_parser("menu-fzf",
|
|
4351
4359
|
help="legacy v0.19.26 fzf menu fallback"
|
|
4352
4360
|
).set_defaults(fn=_legacy_fzf_menu)
|
|
@@ -409,17 +409,242 @@ if TEXTUAL_AVAILABLE:
|
|
|
409
409
|
_switch_client(res.session_jump)
|
|
410
410
|
|
|
411
411
|
|
|
412
|
-
def
|
|
413
|
-
"""
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
412
|
+
def _arrow_menu() -> int:
|
|
413
|
+
"""v0.19.30 — fzf-driven arrow-key menu (the default `omega` UX).
|
|
414
|
+
|
|
415
|
+
Clean grouped layout, arrow-key navigation, search-as-you-type,
|
|
416
|
+
Enter to pick, Esc to refresh. After each action runs INLINE in
|
|
417
|
+
the same pane, "press Enter to return" then re-render the menu.
|
|
418
|
+
|
|
419
|
+
Why fzf and not Textual? Textual's focus model is fragile under
|
|
420
|
+
tmux + send-keys (v0.19.27 bug). fzf has been arrow-key + mouse
|
|
421
|
+
capable since 2014; it's lightweight, single-binary, and behaves
|
|
422
|
+
consistently in every terminal.
|
|
423
|
+
|
|
424
|
+
Why fzf and not whiptail? whiptail is fine but visually 1995. fzf
|
|
425
|
+
gives us a Linear-style search filter and clean ANSI color groups.
|
|
426
|
+
"""
|
|
427
|
+
import os
|
|
428
|
+
import shlex
|
|
429
|
+
import shutil
|
|
430
|
+
import subprocess
|
|
431
|
+
from pathlib import Path
|
|
432
|
+
from omega_engine import __version__
|
|
433
|
+
from omega_engine import tmux
|
|
434
|
+
|
|
435
|
+
if not shutil.which("fzf"):
|
|
436
|
+
print(" fzf not on PATH — falling back to slash REPL.")
|
|
437
|
+
print(" install: brew install fzf (or apt install fzf)")
|
|
438
|
+
return _plain_repl()
|
|
439
|
+
|
|
440
|
+
HOME = Path(os.environ.get("OMEGA_HOME", str(Path.home() / "Omega")))
|
|
441
|
+
OMEGA_BIN = str(HOME / "Agentik_Tools" / "bin" / "omega")
|
|
442
|
+
|
|
443
|
+
# ANSI escapes — used via fzf --ansi.
|
|
444
|
+
ORANGE = "\033[38;2;217;119;87m"
|
|
445
|
+
MUTED = "\033[38;2;136;131;122m"
|
|
446
|
+
BOLD = "\033[1m"
|
|
447
|
+
DIM = "\033[2m"
|
|
448
|
+
RST = "\033[0m"
|
|
449
|
+
|
|
450
|
+
def _label(name: str, hint: str = "") -> str:
|
|
451
|
+
"""Two-column label: name on the left, hint dimmed on the right."""
|
|
452
|
+
if hint:
|
|
453
|
+
return f" {name:<36}{DIM}{hint}{RST}"
|
|
454
|
+
return f" {name}"
|
|
455
|
+
|
|
456
|
+
def _section(name: str) -> str:
|
|
457
|
+
return f"{ORANGE}{BOLD}── {name} ──{RST}"
|
|
458
|
+
|
|
459
|
+
def _build_items() -> list[tuple[str, str]]:
|
|
460
|
+
"""Return (display, action_key) — section headers have key '__sep__'."""
|
|
461
|
+
provider = _active_provider()
|
|
462
|
+
sessions = tmux.list_sessions(HOME)
|
|
463
|
+
return [
|
|
464
|
+
(_section("CHAT"), "__sep__"),
|
|
465
|
+
(_label("AISB master chat", "→ claude (Max OAuth)"), "open:aisb"),
|
|
466
|
+
(_label("Hermès companion", "→ claude (Anthropic API)"), "open:hermes"),
|
|
467
|
+
(_label("Switch LLM", f"current: {provider}"), "switch:provider"),
|
|
468
|
+
("", "__sep__"),
|
|
469
|
+
(_section("PROJECTS"), "__sep__"),
|
|
470
|
+
(_label("New project", "Genesis pipeline"), "genesis:new"),
|
|
471
|
+
(_label("Open project shell"), "project:open"),
|
|
472
|
+
("", "__sep__"),
|
|
473
|
+
(_section("AUDITS & MISSIONS"), "__sep__"),
|
|
474
|
+
(_label("Run a mission", "verified completion"), "run:mission"),
|
|
475
|
+
(_label("Quality Arsenal", "17 forensic audits"), "audit:menu"),
|
|
476
|
+
("", "__sep__"),
|
|
477
|
+
(_section("INFRASTRUCTURE"), "__sep__"),
|
|
478
|
+
(_label("Sessions", f"{len(sessions)} active"), "sessions:list"),
|
|
479
|
+
(_label("Accounts", "Claude Max pool"), "accounts:menu"),
|
|
480
|
+
(_label("Vault", "encrypted secrets"), "vault:menu"),
|
|
481
|
+
("", "__sep__"),
|
|
482
|
+
(_section("HEALTH"), "__sep__"),
|
|
483
|
+
(_label("omega doctor", "full health check"), "cmd:doctor"),
|
|
484
|
+
(_label("omega status", "task state"), "cmd:status"),
|
|
485
|
+
("", "__sep__"),
|
|
486
|
+
(_section("SCRAPE"), "__sep__"),
|
|
487
|
+
(_label("Stealth scrape", "CloakBrowser"), "scrape:cloak"),
|
|
488
|
+
(_label("Fast scrape", "Scrapling"), "scrape:scrapling"),
|
|
489
|
+
("", "__sep__"),
|
|
490
|
+
(_section("EXIT"), "__sep__"),
|
|
491
|
+
(_label("Detach", "session keeps running"), "detach"),
|
|
492
|
+
(_label("Quit Omega", "kills the tmux session"), "quit:kill"),
|
|
493
|
+
]
|
|
494
|
+
|
|
495
|
+
def _run_inline(cmd_argv, *, shell: bool = False) -> None:
|
|
496
|
+
os.system("clear")
|
|
497
|
+
header = " ".join(cmd_argv) if isinstance(cmd_argv, list) else cmd_argv
|
|
498
|
+
print(f" {ORANGE}{BOLD}Ω ›{RST} {header}")
|
|
499
|
+
print(f" {MUTED}{'─' * 60}{RST}")
|
|
500
|
+
if shell:
|
|
501
|
+
subprocess.run(cmd_argv, shell=True)
|
|
502
|
+
else:
|
|
503
|
+
subprocess.run(cmd_argv)
|
|
417
504
|
print()
|
|
418
|
-
print("
|
|
505
|
+
print(f" {MUTED}{'─' * 60}{RST}")
|
|
506
|
+
try:
|
|
507
|
+
input(f" {DIM}press Enter to return to Omega menu… {RST}")
|
|
508
|
+
except (EOFError, KeyboardInterrupt):
|
|
509
|
+
pass
|
|
510
|
+
|
|
511
|
+
def _prompt(label: str) -> str:
|
|
512
|
+
try:
|
|
513
|
+
return input(f" {ORANGE}{label}:{RST} ").strip()
|
|
514
|
+
except (EOFError, KeyboardInterrupt):
|
|
515
|
+
return ""
|
|
516
|
+
|
|
517
|
+
while True:
|
|
518
|
+
items = _build_items()
|
|
519
|
+
lines = [disp for disp, _ in items]
|
|
520
|
+
header = (
|
|
521
|
+
f"{ORANGE}{BOLD}Ω Omega OS v{__version__}{RST} "
|
|
522
|
+
f"{MUTED}• ↑↓ navigate • ↵ pick • / search • Esc refresh{RST}"
|
|
523
|
+
)
|
|
524
|
+
try:
|
|
525
|
+
proc = subprocess.run(
|
|
526
|
+
["fzf",
|
|
527
|
+
"--ansi",
|
|
528
|
+
"--prompt=Ω › ",
|
|
529
|
+
f"--header={header}",
|
|
530
|
+
"--header-first",
|
|
531
|
+
"--layout=reverse",
|
|
532
|
+
"--height=100%",
|
|
533
|
+
"--border=rounded",
|
|
534
|
+
"--padding=1,2",
|
|
535
|
+
"--no-multi",
|
|
536
|
+
"--info=hidden",
|
|
537
|
+
"--pointer=▶",
|
|
538
|
+
"--marker=●",
|
|
539
|
+
"--color=bg+:#1a1a2e,fg+:#D97757,hl+:#D97757,"
|
|
540
|
+
"hl:#D97757,prompt:#D97757,pointer:#D97757,"
|
|
541
|
+
"header:#88837A,border:#A8A29E,info:#88837A"],
|
|
542
|
+
input="\n".join(lines), capture_output=True, text=True,
|
|
543
|
+
)
|
|
544
|
+
except (KeyboardInterrupt, subprocess.SubprocessError):
|
|
545
|
+
return 0
|
|
546
|
+
if proc.returncode != 0:
|
|
547
|
+
# Esc → refresh.
|
|
548
|
+
continue
|
|
549
|
+
pick = proc.stdout.rstrip("\n")
|
|
550
|
+
action = None
|
|
551
|
+
for disp, key in items:
|
|
552
|
+
if disp == pick and key != "__sep__":
|
|
553
|
+
action = key
|
|
554
|
+
break
|
|
555
|
+
if action is None:
|
|
556
|
+
continue
|
|
557
|
+
|
|
558
|
+
# === Dispatch ===
|
|
559
|
+
if action == "detach":
|
|
560
|
+
subprocess.run(["tmux", "detach-client"])
|
|
561
|
+
return 0
|
|
562
|
+
if action == "quit:kill":
|
|
563
|
+
subprocess.run(["tmux", "kill-session", "-t", "Omega"])
|
|
564
|
+
return 0
|
|
565
|
+
if action == "open:aisb":
|
|
566
|
+
tmux.spawn_aisb_chat(HOME, force_replace=False)
|
|
567
|
+
subprocess.run(["tmux", "switch-client", "-t", "AISB-chat"])
|
|
568
|
+
continue
|
|
569
|
+
if action == "open:hermes":
|
|
570
|
+
tmux.spawn_hermes_chat(HOME, force_replace=False)
|
|
571
|
+
subprocess.run(["tmux", "switch-client", "-t", "Hermes-chat"])
|
|
572
|
+
continue
|
|
573
|
+
if action == "switch:provider":
|
|
574
|
+
_run_inline([OMEGA_BIN, "switch"]); continue
|
|
575
|
+
if action == "genesis:new":
|
|
576
|
+
slug = _prompt("project slug (a-z0-9_-)")
|
|
577
|
+
if slug:
|
|
578
|
+
_run_inline([OMEGA_BIN, "genesis", "new", slug])
|
|
579
|
+
continue
|
|
580
|
+
if action == "project:open":
|
|
581
|
+
_run_inline("ls -la ~/Omega/Agentik_Coding/projects/ 2>/dev/null "
|
|
582
|
+
"&& echo && echo '(cd into one to start working)'",
|
|
583
|
+
shell=True)
|
|
584
|
+
continue
|
|
585
|
+
if action == "run:mission":
|
|
586
|
+
intent = _prompt("mission intent")
|
|
587
|
+
if intent:
|
|
588
|
+
_run_inline([OMEGA_BIN, "run", intent])
|
|
589
|
+
continue
|
|
590
|
+
if action == "audit:menu":
|
|
591
|
+
_run_inline(
|
|
592
|
+
"echo ' Quality Arsenal — 17 forensic audits:' && "
|
|
593
|
+
"echo ' /codeaudit /uiuxaudit /flowaudit /debugaudit' && "
|
|
594
|
+
"echo ' /featureaudit /perfaudit /secaudit /a11yaudit' && "
|
|
595
|
+
"echo ' /seoaudit /dataaudit /apiaudit /copyaudit' && "
|
|
596
|
+
"echo ' /dxaudit /motionaudit /automationaudit' && "
|
|
597
|
+
"echo ' /logicaudit /retentionaudit /refontaudit' && "
|
|
598
|
+
"echo && echo ' invoke from any claude session, or:' && "
|
|
599
|
+
f"echo ' {OMEGA_BIN} audit <id>'",
|
|
600
|
+
shell=True)
|
|
601
|
+
continue
|
|
602
|
+
if action == "sessions:list":
|
|
603
|
+
_run_inline("tmux ls", shell=True); continue
|
|
604
|
+
if action == "accounts:menu":
|
|
605
|
+
_run_inline([OMEGA_BIN, "account", "list"]); continue
|
|
606
|
+
if action == "vault:menu":
|
|
607
|
+
_run_inline([OMEGA_BIN, "vault", "status"]); continue
|
|
608
|
+
if action == "cmd:doctor":
|
|
609
|
+
_run_inline([OMEGA_BIN, "doctor"]); continue
|
|
610
|
+
if action == "cmd:status":
|
|
611
|
+
_run_inline([OMEGA_BIN, "status"]); continue
|
|
612
|
+
if action == "scrape:cloak":
|
|
613
|
+
url = _prompt("URL")
|
|
614
|
+
if url:
|
|
615
|
+
_run_inline([OMEGA_BIN, "scrape", url])
|
|
616
|
+
continue
|
|
617
|
+
if action == "scrape:scrapling":
|
|
618
|
+
url = _prompt("URL")
|
|
619
|
+
if url:
|
|
620
|
+
_run_inline([OMEGA_BIN, "scrape", url, "--engine", "scrapling"])
|
|
621
|
+
continue
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
def run_tui(prefer_textual: bool = False,
|
|
625
|
+
force_repl: bool = False) -> int:
|
|
626
|
+
"""Entry point — `omega menu-tui` calls this.
|
|
627
|
+
|
|
628
|
+
v0.19.30 — default is the arrow-key fzf menu (clean grouped layout,
|
|
629
|
+
arrow keys + search-as-you-type + mouse, color theme matched to
|
|
630
|
+
Claude). Falls back to plain slash REPL if fzf is missing.
|
|
631
|
+
|
|
632
|
+
Modes:
|
|
633
|
+
- default → `_arrow_menu()` (fzf, arrow keys + search)
|
|
634
|
+
- `--repl` → `_plain_repl()` (input() loop, slash commands)
|
|
635
|
+
- `--textual` → Textual TUI (opt-in, may break under tmux)
|
|
636
|
+
"""
|
|
637
|
+
if prefer_textual and TEXTUAL_AVAILABLE:
|
|
638
|
+
try:
|
|
639
|
+
app = OmegaTUI()
|
|
640
|
+
app.run()
|
|
641
|
+
return 0
|
|
642
|
+
except Exception as exc: # noqa: BLE001
|
|
643
|
+
print(f" Textual TUI failed: {exc}")
|
|
644
|
+
print(" Falling back to arrow-key menu.")
|
|
645
|
+
if force_repl:
|
|
419
646
|
return _plain_repl()
|
|
420
|
-
|
|
421
|
-
app.run()
|
|
422
|
-
return 0
|
|
647
|
+
return _arrow_menu()
|
|
423
648
|
|
|
424
649
|
|
|
425
650
|
# ---------------------------------------------------------------------------
|
|
@@ -428,15 +653,73 @@ def run_tui() -> int:
|
|
|
428
653
|
|
|
429
654
|
|
|
430
655
|
def _plain_repl() -> int:
|
|
431
|
-
"""Slash-command REPL
|
|
656
|
+
"""Slash-command REPL — the v0.19.29 default for `omega menu-tui`.
|
|
657
|
+
|
|
658
|
+
Rock-solid input via Python's stdlib `input()` — works in any
|
|
659
|
+
terminal, any tmux setup, any TERM value. Same slash command set
|
|
660
|
+
as the Textual app. readline gives history (↑/↓), basic line
|
|
661
|
+
editing, Ctrl-r reverse search.
|
|
662
|
+
"""
|
|
663
|
+
import os
|
|
432
664
|
from omega_engine import __version__
|
|
433
|
-
|
|
434
|
-
|
|
665
|
+
|
|
666
|
+
# readline gives line editing + history. Persist history under $OMEGA_HOME.
|
|
667
|
+
try:
|
|
668
|
+
import readline
|
|
669
|
+
hist_path = os.path.join(
|
|
670
|
+
os.environ.get("OMEGA_HOME", os.path.expanduser("~/Omega")),
|
|
671
|
+
"Agentik_Extra", "var", "omega-repl-history",
|
|
672
|
+
)
|
|
673
|
+
try:
|
|
674
|
+
os.makedirs(os.path.dirname(hist_path), exist_ok=True)
|
|
675
|
+
if os.path.exists(hist_path):
|
|
676
|
+
readline.read_history_file(hist_path)
|
|
677
|
+
except OSError:
|
|
678
|
+
hist_path = None
|
|
679
|
+
readline.set_history_length(500)
|
|
680
|
+
# Tab-completion over known slash commands.
|
|
681
|
+
_COMMANDS = [
|
|
682
|
+
"/help", "/aisb", "/hermes", "/switch", "/mission", "/audit",
|
|
683
|
+
"/genesis", "/scrape", "/sessions", "/accounts", "/vault",
|
|
684
|
+
"/doctor", "/status", "/detach", "/quit",
|
|
685
|
+
]
|
|
686
|
+
def _completer(text: str, state: int) -> str | None:
|
|
687
|
+
matches = [c for c in _COMMANDS if c.startswith(text)]
|
|
688
|
+
return matches[state] if state < len(matches) else None
|
|
689
|
+
readline.set_completer(_completer)
|
|
690
|
+
readline.parse_and_bind("tab: complete")
|
|
691
|
+
except ImportError:
|
|
692
|
+
hist_path = None
|
|
693
|
+
|
|
694
|
+
# Banner — boxed, orange Ω like Hermès's launch screen.
|
|
695
|
+
print()
|
|
696
|
+
print(" ┌─────────────────────────────────────────────────────────┐")
|
|
697
|
+
print(f" │ \033[38;2;217;119;87m\033[1mΩ\033[0m \033[1mOmega OS\033[0m v{__version__:<10} │")
|
|
698
|
+
print( " │ type \033[1m/help\033[0m for slash commands • \033[1m/quit\033[0m to exit │")
|
|
699
|
+
print( " ├─────────────────────────────────────────────────────────┤")
|
|
700
|
+
print( " │ quick start: │")
|
|
701
|
+
print( " │ \033[1m/aisb\033[0m chat with AISB (Max OAuth) │")
|
|
702
|
+
print( " │ \033[1m/hermes\033[0m chat with Hermès (Anthropic API) │")
|
|
703
|
+
print( " │ \033[1m/switch\033[0m see + hot-swap LLM provider │")
|
|
704
|
+
print( " │ \033[1m/mission \"...\"\033[0m run verified-completion mission │")
|
|
705
|
+
print( " │ \033[1m/scrape <url>\033[0m stealth scrape (CloakBrowser) │")
|
|
706
|
+
print( " │ \033[1m/audit <id>\033[0m run a Quality Arsenal audit │")
|
|
707
|
+
print( " │ \033[1m/doctor\033[0m full health check │")
|
|
708
|
+
print( " └─────────────────────────────────────────────────────────┘")
|
|
709
|
+
print()
|
|
710
|
+
print(" TAB completes slash commands • ↑/↓ for history\n")
|
|
711
|
+
|
|
712
|
+
PROMPT = " \033[38;2;217;119;87mΩ\033[0m › "
|
|
435
713
|
while True:
|
|
436
714
|
try:
|
|
437
|
-
line = input(
|
|
715
|
+
line = input(PROMPT).strip()
|
|
438
716
|
except (EOFError, KeyboardInterrupt):
|
|
439
717
|
print()
|
|
718
|
+
if hist_path:
|
|
719
|
+
try:
|
|
720
|
+
readline.write_history_file(hist_path)
|
|
721
|
+
except OSError:
|
|
722
|
+
pass
|
|
440
723
|
return 0
|
|
441
724
|
if not line:
|
|
442
725
|
continue
|
|
@@ -455,3 +738,8 @@ def _plain_repl() -> int:
|
|
|
455
738
|
print()
|
|
456
739
|
if res.session_jump:
|
|
457
740
|
_switch_client(res.session_jump)
|
|
741
|
+
if hist_path:
|
|
742
|
+
try:
|
|
743
|
+
readline.write_history_file(hist_path)
|
|
744
|
+
except OSError:
|
|
745
|
+
pass
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.19.
|
|
1
|
+
0.19.30
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentikos/omega-os",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.30",
|
|
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"
|