@agentikos/omega-os 0.19.42 → 0.19.43

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.
Files changed (42) hide show
  1. package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
  2. package/bootstrap/lib/common.sh +6 -0
  3. package/bootstrap/lib/llm-clis.py +6 -0
  4. package/bootstrap/lib/manifest-helpers.py +110 -0
  5. package/bootstrap/lib/steps.sh +230 -26
  6. package/bootstrap/templates/aisb/CLAUDE.md +13 -0
  7. package/install.sh +8 -2
  8. package/omega/Agentik_Engine/omega_engine/__init__.py +1 -1
  9. package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
  10. package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
  11. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
  12. package/omega/Agentik_Engine/omega_engine/__pycache__/paperclip_bridge.cpython-313.pyc +0 -0
  13. package/omega/Agentik_Engine/omega_engine/__pycache__/personas.cpython-313.pyc +0 -0
  14. package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
  15. package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
  16. package/omega/Agentik_Engine/omega_engine/__pycache__/tui.cpython-313.pyc +0 -0
  17. package/omega/Agentik_Engine/omega_engine/cli.py +44 -7
  18. package/omega/Agentik_Engine/omega_engine/hermes.py +43 -1
  19. package/omega/Agentik_Engine/omega_engine/paperclip_bridge.py +22 -0
  20. package/omega/Agentik_Engine/omega_engine/personas.py +11 -3
  21. package/omega/Agentik_Engine/omega_engine/provider.py +18 -3
  22. package/omega/Agentik_Engine/omega_engine/tmux.py +41 -21
  23. package/omega/Agentik_Engine/omega_engine/tui.py +8 -7
  24. package/omega/Agentik_Engine/pyproject.toml +1 -1
  25. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps_v0_19_43.cpython-313-pytest-8.4.2.pyc +0 -0
  26. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps_v0_19_43.cpython-313.pyc +0 -0
  27. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
  28. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
  29. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_palette.cpython-313-pytest-8.4.2.pyc +0 -0
  30. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_palette.cpython-313.pyc +0 -0
  31. package/omega/Agentik_Engine/tests/__pycache__/test_v19_43_fixes.cpython-313-pytest-8.4.2.pyc +0 -0
  32. package/omega/Agentik_Engine/tests/__pycache__/test_v19_43_fixes.cpython-313.pyc +0 -0
  33. package/omega/Agentik_Engine/tests/test_install_steps_v0_19_43.py +242 -0
  34. package/omega/Agentik_Engine/tests/test_installer_wiring.py +128 -1
  35. package/omega/Agentik_Engine/tests/test_tmux_palette.py +51 -0
  36. package/omega/Agentik_Engine/tests/test_v19_43_fixes.py +265 -0
  37. package/omega/Agentik_SSOT/VERSION +1 -1
  38. package/omega/Agentik_SSOT/docs/AUDIT-V0.19.43.md +92 -0
  39. package/omega/Agentik_SSOT/rules/audit-gates.md +2 -2
  40. package/omega/Agentik_SSOT/rules/constitution.md +18 -0
  41. package/omega/Agentik_SSOT/rules/three-laws.md +2 -0
  42. package/package.json +1 -1
@@ -271,6 +271,31 @@ def cmd_doctor(args: argparse.Namespace) -> int:
271
271
  except Exception as exc: # noqa: BLE001
272
272
  line("warn", f"provider auth check failed: {exc}")
273
273
 
274
+ # v0.19.43 — Hermès budget-isolation check. Hermès SHOULD use its own
275
+ # paid Anthropic key (ANTHROPIC_API_KEY_HERMES) so its calls don't
276
+ # share the AISB Max OAuth pool. See omega_engine/hermes.py::build_env
277
+ # for the 3-tier fallback. When path (3) — Max OAuth — is the live
278
+ # path, surface it here so the operator knows isolation is OFF.
279
+ try:
280
+ from omega_engine.vault import vault_read as _vread
281
+ _hermes_vault_key = (_vread(home, "ANTHROPIC_API_KEY_HERMES") or "").strip()
282
+ _hermes_env_key = (_os.environ.get("ANTHROPIC_API_KEY") or "").strip()
283
+ if _hermes_vault_key:
284
+ line("ok", "Hermès budget isolation: vault key present "
285
+ "(ANTHROPIC_API_KEY_HERMES)")
286
+ elif _hermes_env_key:
287
+ line("warn", "Hermès budget isolation: shell env key only "
288
+ "(ANTHROPIC_API_KEY) — works but couples Hermès to "
289
+ "whatever the env points at. Consider wiring the "
290
+ "vault key for permanent isolation.")
291
+ else:
292
+ line("warn", "Hermès budget isolation OFF — no vault key, no env "
293
+ "key. Hermès will fall back to Max OAuth (charges "
294
+ "your Max sub). Wire with: "
295
+ "`omega vault write ANTHROPIC_API_KEY_HERMES sk-ant-...`")
296
+ except Exception as exc: # noqa: BLE001
297
+ line("warn", f"Hermès isolation check failed: {exc}")
298
+
274
299
  # 6c1. LLM CLIs installed on the host
275
300
  section("llm clis")
276
301
  import shutil as _shu
@@ -2885,8 +2910,11 @@ def cmd_aisb(args: argparse.Namespace) -> int:
2885
2910
  from omega_engine import tmux
2886
2911
  sub = getattr(args, "aisb_cmd", None) or "chat"
2887
2912
  if sub in ("chat", None):
2913
+ # v0.19.43 — AISB-chat is now a WINDOW inside the Omega master
2914
+ # session (Omega:aisb), not a standalone session. spawn_aisb_chat
2915
+ # returns "Omega:aisb" so we pass that as the switch target.
2888
2916
  return _attach_or_spawn_chat(
2889
- "AISB-chat",
2917
+ "Omega:aisb",
2890
2918
  spawn_fn=tmux.spawn_aisb_chat,
2891
2919
  label="AISB master (Claude Code on Max OAuth)",
2892
2920
  )
@@ -3175,14 +3203,14 @@ def _legacy_fzf_menu(_args: argparse.Namespace) -> int:
3175
3203
  subprocess.run(["tmux", "kill-session", "-t", "Omega"])
3176
3204
  return 0
3177
3205
 
3178
- # Chat sessions — switch tmux client to the chat session.
3206
+ # Chat sessions — windows inside Omega master (v0.19.43).
3179
3207
  if action == "open:aisb":
3180
- tmux.spawn_aisb_chat(HOME, force_replace=False)
3181
- subprocess.run(["tmux", "switch-client", "-t", "AISB-chat"])
3208
+ target = tmux.spawn_aisb_chat(HOME, force_replace=False)
3209
+ subprocess.run(["tmux", "switch-client", "-t", target])
3182
3210
  continue
3183
3211
  if action == "open:hermes":
3184
- tmux.spawn_hermes_chat(HOME, force_replace=False)
3185
- subprocess.run(["tmux", "switch-client", "-t", "Hermes-chat"])
3212
+ target = tmux.spawn_hermes_chat(HOME, force_replace=False)
3213
+ subprocess.run(["tmux", "switch-client", "-t", target])
3186
3214
  continue
3187
3215
 
3188
3216
  # Inline actions — run in the menu pane, prompt to return.
@@ -3494,6 +3522,13 @@ def cmd_switch(args: argparse.Namespace) -> int:
3494
3522
  "qwen_code": "qwen",
3495
3523
  "continue_dev": "cn",
3496
3524
  "aider": "aider",
3525
+ # v0.19.43 — providers installable via the CLI catalog that were
3526
+ # missing from `omega switch`. Each maps to its bin_name from
3527
+ # bootstrap/lib/llm-clis.py::_CATALOG.
3528
+ "glm_sdk": "zhipuai", # Python SDK — no binary, kept for completeness
3529
+ "ollama": "ollama",
3530
+ "lm_studio": "lms",
3531
+ "gh_copilot": "gh", # extension on top of gh
3497
3532
  }
3498
3533
  if not getattr(args, "provider", None):
3499
3534
  print(f" active provider: {_active_provider()}")
@@ -3598,10 +3633,12 @@ def cmd_hermes(args: argparse.Namespace) -> int:
3598
3633
 
3599
3634
  # v0.19.15 — `omega hermes` with no subcommand opens the Hermès chat
3600
3635
  # tmux session. Same UX as bare `omega` → AISB chat, but for L2.
3636
+ # v0.19.43 — Hermes-chat is now a WINDOW inside the Omega master
3637
+ # session (Omega:hermes); spawn_hermes_chat returns that ref.
3601
3638
  if sub is None or sub == "chat":
3602
3639
  from omega_engine import tmux as _tx
3603
3640
  return _attach_or_spawn_chat(
3604
- "Hermes-chat",
3641
+ "Omega:hermes",
3605
3642
  spawn_fn=_tx.spawn_hermes_chat,
3606
3643
  label="Hermès meta-companion chat",
3607
3644
  )
@@ -262,6 +262,39 @@ def build_env(
262
262
  calls through your Max sub.
263
263
 
264
264
  Caller env wins via ``extra``.
265
+
266
+ ──────────────────────────────────────────────────────────────────
267
+ IMPORTANT — Hermès credential resolution (v0.19.43 clarification)
268
+ ──────────────────────────────────────────────────────────────────
269
+
270
+ Hermès SHOULD use ANTHROPIC_API_KEY_HERMES from the vault for budget
271
+ isolation from the AISB Max OAuth. The 3-tier fallback below is a
272
+ SAFETY NET for the edge case where the vault key is missing but the
273
+ operator still wants Hermès to work (during initial setup, debugging,
274
+ or a one-off command before they have wired the paid key).
275
+
276
+ Fallback order (first non-empty wins):
277
+
278
+ 1. ANTHROPIC_API_KEY_HERMES (vault) ← preferred, isolated budget
279
+ 2. ANTHROPIC_API_KEY (shell env) ← shared env, semi-isolated
280
+ 3. CLAUDE_CODE_OAUTH_TOKEN (Max OAuth) ← LAST RESORT, breaks isolation
281
+
282
+ Hierarchy intent:
283
+ * Path (1) is the contract Hermès was designed to honor.
284
+ * Path (2) lets a developer ``ANTHROPIC_API_KEY=sk-... omega hermes``
285
+ without writing to the vault.
286
+ * Path (3) preserves "Hermès still works on a fresh install before
287
+ the user has wired their key" — at the cost of charging the user's
288
+ Max sub for what should be a paid-API call.
289
+
290
+ ``omega doctor`` warns when Hermès would fall through to path (3) in
291
+ practice (vault empty AND ``ANTHROPIC_API_KEY`` unset). The persistent
292
+ Hermès chat (``step_hermes_session`` in bootstrap/lib/steps.sh) SKIPS
293
+ its spawn entirely on missing vault key — it does NOT fall through to
294
+ Max OAuth for 24/7 runtime use, because an always-on Max-billed Hermès
295
+ is rarely what the operator wants. Only the interactive on-demand
296
+ ``omega hermes`` path uses this fallback chain.
297
+ ──────────────────────────────────────────────────────────────────
265
298
  """
266
299
  env = {**os.environ}
267
300
  # 1. Vault first.
@@ -279,10 +312,19 @@ def build_env(
279
312
  if not key:
280
313
  key = (os.environ.get("ANTHROPIC_API_KEY") or "").strip()
281
314
  # 3. Last-resort OAuth (preserves the old behaviour without making
282
- # Hermès depend on it).
315
+ # Hermès depend on it). When this branch fires, log a warning to
316
+ # stderr so the operator knows budget isolation is OFF — Hermès is
317
+ # now sharing the Max OAuth pool with AISB+Oracle+Workers. The
318
+ # `omega doctor` `personas` / `providers` section will also surface
319
+ # this drift.
283
320
  if not key:
284
321
  try:
285
322
  env["CLAUDE_CODE_OAUTH_TOKEN"] = claude_oauth_token(creds_path)
323
+ import sys as _sys
324
+ print(" ⚠️ Hermès budget isolation OFF — falling back to "
325
+ "Max OAuth. Run `omega vault write "
326
+ "ANTHROPIC_API_KEY_HERMES sk-ant-...` to restore.",
327
+ file=_sys.stderr)
286
328
  except Exception: # noqa: BLE001
287
329
  pass
288
330
  if key:
@@ -292,6 +292,28 @@ def send_heartbeat(
292
292
  return True
293
293
 
294
294
 
295
+ def heartbeat_on_spawn(agent_id: str, project: str | None = None) -> None:
296
+ """v0.19.43 — call this from spawn_worker / spawn_oracle right after
297
+ the tmux session is created. Drops a one-shot heartbeat to Paperclip
298
+ so the dashboard's live-agent indicator wakes up immediately instead
299
+ of waiting for the agent's first explicit heartbeat call.
300
+
301
+ Never raises — if Paperclip is not installed or not running, this is
302
+ a no-op. Safe to call from any spawn path.
303
+ """
304
+ try:
305
+ hb = Heartbeat(
306
+ agent_id=agent_id,
307
+ project=project or "",
308
+ session=os.environ.get("TMUX_SESSION", ""),
309
+ status="alive",
310
+ summary="spawned",
311
+ )
312
+ send_heartbeat(hb)
313
+ except Exception:
314
+ pass # silent fallback — bridge is optional infrastructure
315
+
316
+
295
317
  # ---------------------------------------------------------------------------
296
318
  # Registration — write Paperclip's agent + company config from OmegaOS
297
319
  # ---------------------------------------------------------------------------
@@ -55,6 +55,14 @@ _LLM_PERSONA_PATHS: dict[str, list[str]] = {
55
55
  "continue_dev": [".continue/CONTEXT.md"],
56
56
  "aider": ["CONVENTIONS.md"],
57
57
  "hermes": ["HERMES.md"],
58
+ # v0.19.43 — 4 CLIs were installable but had no persona file. Without
59
+ # this mapping, write_all_personas() silently skipped them and the
60
+ # CLI would launch with no Omega context. Each maps to the closest
61
+ # convention for that CLI.
62
+ "glm_sdk": ["GLM.md"], # Zhipu GLM SDK — bespoke marker
63
+ "ollama": ["OLLAMA.md"], # Ollama local runtime
64
+ "lm_studio": ["LM_STUDIO.md"], # LM Studio local
65
+ "gh_copilot": ["CLAUDE.md"], # gh copilot piggy-backs on CLAUDE.md
58
66
  }
59
67
 
60
68
 
@@ -98,7 +106,7 @@ You sit at L4 or L5 depending on context.
98
106
  $OMEGA_HOME = ~/Omega
99
107
  ├── Agentik_Engine/ ← Python engine (omega CLI)
100
108
  ├── Agentik_SSOT/ ← source of truth
101
- │ ├── skills/ ← 17 audits + orchestrators + /newcmd
109
+ │ ├── skills/ ← 18 audits + orchestrators + /newcmd
102
110
  │ ├── agents/aisb/ ← 13 AISB persona files
103
111
  │ ├── personas/OMEGAOS-CONTEXT.md ← THIS FILE
104
112
  │ ├── docs/LAYERS.md ← formal L1-L5 architecture
@@ -122,11 +130,11 @@ $OMEGA_HOME = ~/Omega
122
130
  | Status / health | `omega doctor` / `omega status` |
123
131
  | Session manager (tmux) | `omega` (no args) |
124
132
 
125
- ## Quality Arsenal (17 forensic audits)
133
+ ## Quality Arsenal (18 forensic audits)
126
134
 
127
135
  `/codeaudit /flowaudit /uiuxaudit /debugaudit /featureaudit /perfaudit
128
136
  /secaudit /a11yaudit /seoaudit /dataaudit /apiaudit /copyaudit /dxaudit
129
- /motionaudit /automationaudit /logicaudit /retentionaudit`
137
+ /motionaudit /automationaudit /logicaudit /retentionaudit /refontaudit`
130
138
 
131
139
  Each: Gestalt clarity gate, Popper falsification, hinge point 10x
132
140
  scrutiny, auto-fix, auto-re-audit, scored /100.
@@ -440,13 +440,28 @@ class _OpenAICompatProvider:
440
440
  self._base_url = base_url or self._default_base_url
441
441
 
442
442
  def _resolve_key(self) -> str:
443
- key = self._api_key or os.environ.get(self._env_var)
444
- if not key:
443
+ # Constructor-injected key always wins.
444
+ if self._api_key:
445
+ return self._api_key
446
+ # v0.19.43 — try the encrypted vault first, then fall back to env.
447
+ # The vault is where step_providers stores api keys provided via
448
+ # the install manifest; env is the legacy / fallback path.
449
+ try:
450
+ from omega_engine.vault import vault_read
451
+ from pathlib import Path
452
+ home = Path(os.environ.get("OMEGA_HOME", str(Path.home() / "Omega")))
453
+ v = vault_read(home, self._env_var)
454
+ if v and v.strip():
455
+ return v.strip()
456
+ except Exception:
457
+ pass
458
+ key = os.environ.get(self._env_var)
459
+ if not key or not key.strip():
445
460
  raise RuntimeError(
446
461
  f"{type(self).__name__} requires an API key. "
447
462
  f"Pass api_key=... or set {self._env_var} in the environment."
448
463
  )
449
- return key
464
+ return key.strip()
450
465
 
451
466
  def _build_messages(self, req: AgentRequest) -> list[dict[str, str]]:
452
467
  prompt = req.prompt
@@ -385,30 +385,37 @@ def spawn_chat_in_omega(
385
385
 
386
386
  def spawn_aisb_chat(omega_home: str | Path | None = None,
387
387
  force_replace: bool = False) -> str:
388
- """Spawn the AISB master chat tmux session REAL Claude Code TUI.
388
+ """Spawn the AISB master chat as a WINDOW inside the Omega master session.
389
389
 
390
- v0.19.20moved from ``exec claude`` (which kills the session when
391
- claude exits) to ``spawn shell + send-keys claude``. The shell stays
392
- alive even if claude can't start (no Max OAuth wired, etc.), so the
393
- user lands inside the session and sees the actual failure instead of
394
- "ça fait rien du tout" silent attach-to-dead.
390
+ v0.19.43refactored to use the window-based pattern via
391
+ :func:`spawn_chat_in_omega` so AISB-chat lives UNDER the persistent
392
+ Omega master session (single tmux lifecycle, detach returns to the
393
+ Omega menu) instead of as a standalone tmux session. This honors the
394
+ v0.19.31+ design promise: "everything under Omega".
395
+
396
+ Returns the full tmux ref ``"Omega:aisb"`` — callers can use it
397
+ directly with ``tmux switch-client -t`` / ``tmux attach -t``.
395
398
 
396
399
  Auth: Claude Max OAuth (inherited from the user's shell env, no env
397
400
  override needed — `claude` reads `~/.claude/.credentials.json`).
398
401
 
399
- ``force_replace=True`` kills any existing AISB-chat first — used by
400
- the `omega` session manager's "+ New" action so the user gets a
401
- fresh session each time.
402
+ ``force_replace=True`` kills any existing aisb window first — used
403
+ by the menu's "+ New" action so the user gets a fresh window each
404
+ time.
402
405
  """
403
- name = "AISB-chat"
404
406
  home = Path(omega_home or os.environ.get("OMEGA_HOME")
405
407
  or Path.home() / "Omega")
408
+ # Ensure the Omega master session exists — spawn_chat_in_omega tries
409
+ # to do this too, but its fallback uses ctx_dir.parent.parent.parent
410
+ # which doesn't always resolve to OMEGA_HOME. Be explicit.
411
+ spawn_omega_master(home)
406
412
  persona = home / "Agentik_SSOT" / "agents" / "aisb" / "CLAUDE.md"
407
413
  ctx_dir = _ensure_chat_context_dir(home, "aisb-master", persona)
408
- return _spawn_with_shell_then_run(
409
- name, cwd=ctx_dir, run_command="claude",
414
+ spawn_chat_in_omega(
415
+ "aisb", ctx_dir=ctx_dir, run_command="claude",
410
416
  force_replace=force_replace,
411
417
  )
418
+ return "Omega:aisb"
412
419
 
413
420
 
414
421
  def spawn_omega_master(omega_home: str | Path | None = None) -> str:
@@ -448,19 +455,31 @@ def spawn_omega_master(omega_home: str | Path | None = None) -> str:
448
455
 
449
456
  def spawn_hermes_chat(omega_home: str | Path | None = None,
450
457
  force_replace: bool = False) -> str:
451
- """Spawn the Hermès chat tmux session REAL Claude Code TUI, but on
452
- Anthropic API (Hermès's own paid key, budget-isolated from Max OAuth).
458
+ """Spawn the Hermès chat as a WINDOW inside the Omega master session.
459
+
460
+ v0.19.43 — refactored to use the window-based pattern via
461
+ :func:`spawn_chat_in_omega` to match :func:`spawn_aisb_chat` and the
462
+ menu TUI (single tmux lifecycle, detach returns to the Omega menu).
463
+
464
+ Credential isolation is PRESERVED — Hermès reads
465
+ ``ANTHROPIC_API_KEY_HERMES`` from the vault to keep its budget
466
+ isolated from the AISB Max OAuth. If the vault key is missing we
467
+ fall back to ``ANTHROPIC_API_KEY`` in the shell env, and finally to
468
+ plain ``claude`` (Max OAuth) with a marker file dropped in the
469
+ context dir so the operator sees the message after attaching.
453
470
 
454
- Mirrors ``spawn_aisb_chat`` for the L2 companion: drops a Hermès
455
- persona ``CLAUDE.md`` into a dedicated context dir, exports
456
- ``ANTHROPIC_API_KEY`` (from vault) before launching `claude`. Same
457
- shell-stays-alive pattern.
471
+ Returns ``"Omega:hermes"`` so callers can use it with
472
+ ``tmux switch-client -t`` / ``tmux attach -t`` directly.
458
473
  """
459
- name = "Hermes-chat"
460
474
  home = Path(omega_home or os.environ.get("OMEGA_HOME")
461
475
  or Path.home() / "Omega")
476
+ # Ensure the Omega master session exists — see spawn_aisb_chat.
477
+ spawn_omega_master(home)
462
478
  persona = home / "Agentik_SSOT" / "docs" / "LAYERS.md"
463
479
  ctx_dir = _ensure_chat_context_dir(home, "hermes", persona)
480
+ # Credential isolation — vault key first, env fallback, Max OAuth
481
+ # last-resort. MUST stay in this function: the budget-isolation
482
+ # contract belongs to Hermès, not to the generic spawn helper.
464
483
  try:
465
484
  from omega_engine.vault import vault_read
466
485
  api_key = (vault_read(home, "ANTHROPIC_API_KEY_HERMES") or "").strip()
@@ -479,10 +498,11 @@ def spawn_hermes_chat(omega_home: str | Path | None = None,
479
498
  else:
480
499
  # Single-line shell statement; send-keys passes it as-is.
481
500
  run_cmd = f"ANTHROPIC_API_KEY={api_key} claude"
482
- return _spawn_with_shell_then_run(
483
- name, cwd=ctx_dir, run_command=run_cmd,
501
+ spawn_chat_in_omega(
502
+ "hermes", ctx_dir=ctx_dir, run_command=run_cmd,
484
503
  force_replace=force_replace,
485
504
  )
505
+ return "Omega:hermes"
486
506
 
487
507
 
488
508
  # ---------------------------------------------------------------------------
@@ -67,7 +67,7 @@ except ImportError:
67
67
  CATEGORIES: list[tuple[str, str]] = [
68
68
  ("chat", "Chat — AISB & Hermès"),
69
69
  ("projects", "Projects — Genesis & shells"),
70
- ("audits", "Audits — Quality Arsenal (17 forensic)"),
70
+ ("audits", "Audits — Quality Arsenal (18 forensic)"),
71
71
  ("missions", "Missions — run with verified completion"),
72
72
  ("sessions", "Sessions — live tmux sessions"),
73
73
  ("accounts", "Accounts — Claude Max + provider auth"),
@@ -135,22 +135,23 @@ def dispatch_slash(line: str) -> CommandResult:
135
135
  if cmd in ("detach", "d"):
136
136
  return CommandResult(detach=True)
137
137
 
138
- # Chat sessions
138
+ # Chat sessions — v0.19.43 are now WINDOWS inside the Omega master
139
+ # session (Omega:aisb, Omega:hermes), not standalone sessions.
139
140
  if cmd == "aisb" or (cmd == "chat" and rest and rest[0] == "aisb"):
140
141
  from omega_engine import tmux as _tx
141
- _tx.spawn_aisb_chat(Path(os.environ.get(
142
+ target = _tx.spawn_aisb_chat(Path(os.environ.get(
142
143
  "OMEGA_HOME", str(Path.home() / "Omega"))))
143
144
  return CommandResult(
144
145
  text=" AISB-chat spawned — switching client…",
145
- session_jump="AISB-chat",
146
+ session_jump=target,
146
147
  )
147
148
  if cmd == "hermes" or (cmd == "chat" and rest and rest[0] == "hermes"):
148
149
  from omega_engine import tmux as _tx
149
- _tx.spawn_hermes_chat(Path(os.environ.get(
150
+ target = _tx.spawn_hermes_chat(Path(os.environ.get(
150
151
  "OMEGA_HOME", str(Path.home() / "Omega"))))
151
152
  return CommandResult(
152
153
  text=" Hermes-chat spawned — switching client…",
153
- session_jump="Hermes-chat",
154
+ session_jump=target,
154
155
  )
155
156
 
156
157
  # Provider hot-swap
@@ -164,7 +165,7 @@ def dispatch_slash(line: str) -> CommandResult:
164
165
  if rest:
165
166
  return CommandResult(text=_run_omega("audit", *rest))
166
167
  return CommandResult(text=(
167
- " Quality Arsenal — 17 forensic audits:\n"
168
+ " Quality Arsenal — 18 forensic audits:\n"
168
169
  " /codeaudit /uiuxaudit /flowaudit /debugaudit\n"
169
170
  " /featureaudit /perfaudit /secaudit /a11yaudit\n"
170
171
  " /seoaudit /dataaudit /apiaudit /copyaudit\n"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "omega-engine"
3
- version = "0.19.42"
3
+ version = "0.19.43"
4
4
  description = "The Omega OS orchestration engine — event-sourced, verified-completion agent graphs."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"