@agentikos/omega-os 0.19.16 → 0.19.18

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.
@@ -365,49 +365,74 @@ step_engine() {
365
365
 
366
366
  # --- 36 -----------------------------------------------------------------------
367
367
  #
368
- # step_tmux_config — install the "pro" tmux profile and wire ~/.tmux.conf.
368
+ # step_tmux_config — install the canonical `tmux-claude` setup.
369
369
  #
370
- # Writes two files:
371
- # 1. $OMEGA_HOME/Agentik_Tools/tmux.conf (bundled, single source of truth)
372
- # 2. ~/.tmux.conf (the user's live config)
370
+ # The canonical OmegaVPS tmux UX lives at github.com/agentik-os/tmux-claude:
371
+ # session manager popup (Ctrl+l, Ctrl+b z, Option+z), per-session metrics
372
+ # (RAM/age/git/Claude/AISB progress), project auto-discovery, dev-server
373
+ # port management, mobile-friendly scroll, theme-neutral status bar.
373
374
  #
374
- # (2) gets a timestamped .bak.<ts> sibling whenever the existing content
375
- # differs re-runs that produce identical content are silent no-ops, so the
376
- # step is fully idempotent without leaving piles of backups behind.
375
+ # We run the upstream installer (curl|bash). It writes ~/.tmux.conf plus
376
+ # ~/.tmux/scripts/ and ~/.config/tmux-claude/. Idempotent re-running is a
377
+ # safe no-op once the marker file is present.
377
378
  #
378
- # Why "pro" by default: Termius paste-fix, session-kill forensics log, smart
379
- # scroll in alt-screen panes (Claude Code TUI), extended keys, OSC 52
380
- # clipboard. This matches the live OmegaVPS UX the operator already uses.
379
+ # Fallback: when curl is unavailable or the network is down, we drop our
380
+ # bundled "pro" config so the user still has a sane tmux conf.
381
381
  step_tmux_config() {
382
382
  if ! have tmux; then
383
383
  err "tmux not installed — step_system_deps should have caught this"
384
384
  return 1
385
385
  fi
386
+ local marker="$HOME/.tmux/scripts/session-manager.sh"
387
+ local installer_url="https://raw.githubusercontent.com/agentik-os/tmux-claude/main/install.sh"
388
+
389
+ if [ -f "$marker" ]; then
390
+ info "tmux-claude already installed at $marker — skipping"
391
+ elif have curl; then
392
+ info "installing canonical tmux-claude setup (agentik-os/tmux-claude)…"
393
+ # We pipe through `bash -s -- --no-prompt` so the install doesn't ask
394
+ # for confirmation. If the upstream installer doesn't support that
395
+ # flag it just ignores it.
396
+ if curl -fsSL "$installer_url" 2>>"$LOG_FILE" \
397
+ | bash -s -- --no-prompt >>"$LOG_FILE" 2>&1; then
398
+ ok "tmux-claude installed (~/.tmux/scripts/, ~/.tmux.conf)"
399
+ else
400
+ err "tmux-claude install failed — falling back to bundled pro profile"
401
+ _tmux_fallback_pro_config
402
+ fi
403
+ else
404
+ info "curl missing — falling back to bundled pro profile"
405
+ _tmux_fallback_pro_config
406
+ fi
407
+
408
+ # Always also drop the bundled config under $OMEGA_HOME so `omega tmux
409
+ # install --profile pro` later remains a working manual recovery path.
410
+ PYTHONPATH="$OMEGA_HOME/Agentik_Engine" python3 - <<PY 2>>"$LOG_FILE"
411
+ import os
412
+ os.environ["OMEGA_HOME"] = "$OMEGA_HOME"
413
+ from omega_engine.tmux import write_default_config
414
+ bundled = write_default_config(profile="pro")
415
+ print(f" bundled fallback config also at: {bundled}")
416
+ PY
417
+ return 0
418
+ }
419
+
420
+ _tmux_fallback_pro_config() {
386
421
  PYTHONPATH="$OMEGA_HOME/Agentik_Engine" python3 - <<PY 2>>"$LOG_FILE"
387
422
  import os
388
423
  os.environ["OMEGA_HOME"] = "$OMEGA_HOME"
389
424
  from pathlib import Path
390
425
  from omega_engine.tmux import write_default_config, install_into_home_tmux_conf
391
-
392
- # 1. Always write the bundled "pro" config — single source of truth.
393
426
  bundled = write_default_config(profile="pro")
394
- print(f" tmux bundled config: {bundled} (pro profile)")
395
-
396
- # 2. Skip ~/.tmux.conf rewrite when it already matches the bundled content
397
- # (otherwise re-runs spam timestamped backups for no reason).
398
427
  home_conf = Path.home() / ".tmux.conf"
399
428
  bundled_content = Path(bundled).read_text()
400
429
  existing = home_conf.read_text() if home_conf.exists() else ""
401
- if existing == bundled_content:
402
- print(f" ~/.tmux.conf already matches pro profile — nothing to do")
403
- else:
430
+ if existing != bundled_content:
404
431
  res = install_into_home_tmux_conf(profile="pro", backup=True)
405
432
  if res["backup_path"]:
406
433
  print(f" backed up previous ~/.tmux.conf -> {res['backup_path']}")
407
434
  print(f" wrote pro profile to {res['written']}")
408
- print(f" reload in-session: tmux source-file ~/.tmux.conf")
409
435
  PY
410
- return $?
411
436
  }
412
437
 
413
438
  # --- 37 -----------------------------------------------------------------------
@@ -188,7 +188,7 @@ from omega_engine.genesis import (
188
188
  )
189
189
  from omega_engine import plan as plan_v7
190
190
 
191
- __version__ = "0.19.16"
191
+ __version__ = "0.19.18"
192
192
 
193
193
  __all__ = [
194
194
  "__version__",
@@ -231,33 +231,99 @@ def spawn_worker(project: str, task: str, *,
231
231
  return name
232
232
 
233
233
 
234
+ def _ensure_chat_context_dir(home: Path, label: str,
235
+ persona_md_path: Path) -> Path:
236
+ """Create (idempotent) a dedicated Claude Code project dir for an
237
+ OmegaOS chat session.
238
+
239
+ Drops ``CLAUDE.md`` (the persona) so Claude Code auto-loads it as
240
+ project context when the user runs `claude` in this dir. Returns
241
+ the path.
242
+ """
243
+ ctx_dir = home / "Agentik_Coding" / "chat-contexts" / label
244
+ ctx_dir.mkdir(parents=True, exist_ok=True)
245
+ target = ctx_dir / "CLAUDE.md"
246
+ if persona_md_path.is_file():
247
+ # Mirror the upstream persona file so refreshes propagate.
248
+ target.write_text(persona_md_path.read_text())
249
+ elif not target.exists():
250
+ target.write_text(
251
+ f"# {label} chat context\n\n"
252
+ f"(no persona file found — using default Claude Code behaviour)\n"
253
+ )
254
+ # Also drop a .gitignore so this transient dir never gets committed
255
+ # by accident if the user `git init`s it.
256
+ gi = ctx_dir / ".gitignore"
257
+ if not gi.exists():
258
+ gi.write_text("*\n!.gitignore\n!CLAUDE.md\n")
259
+ return ctx_dir
260
+
261
+
234
262
  def spawn_aisb_chat(omega_home: str | Path | None = None) -> str:
235
- """Spawn the AISB master chat tmux session.
263
+ """Spawn the AISB master chat tmux session — REAL Claude Code TUI.
264
+
265
+ v0.19.18 — instead of running our Python REPL (`omega aisb chat-loop`),
266
+ we now run the canonical `claude` CLI inside a dedicated project dir
267
+ seeded with the AISB master persona (``Agentik_SSOT/agents/aisb/CLAUDE.md``).
268
+ User sees the SAME interactive Claude Code TUI they get with bare
269
+ `claude`, but pre-loaded with AISB's identity, the L3 orchestrator
270
+ role, and full OmegaOS context.
236
271
 
237
- Runs ``omega aisb chat-loop`` inside REPL conversation with the
238
- AISB master agent on Claude Max OAuth. This is what bare `omega`
239
- attaches to (v0.19.15+).
272
+ Auth: Claude Max OAuth (inherited from the user's shell env, no env
273
+ override needed `claude` reads `~/.claude/.credentials.json`).
274
+
275
+ cwd=$HOME is the legacy crash fix (spawn() default would inherit
276
+ the npm/_npx cache dir which can disappear); the `claude` process
277
+ itself runs with cwd = the context dir we just created.
240
278
  """
241
279
  name = "AISB-chat"
242
280
  home = Path(omega_home or os.environ.get("OMEGA_HOME")
243
281
  or Path.home() / "Omega")
244
- omega_bin = home / "Agentik_Tools" / "bin" / "omega"
245
- spawn(name, command=f"{omega_bin} aisb chat-loop")
282
+ persona = home / "Agentik_SSOT" / "agents" / "aisb" / "CLAUDE.md"
283
+ ctx_dir = _ensure_chat_context_dir(home, "aisb-master", persona)
284
+ spawn(name, command=f"cd {ctx_dir} && exec claude",
285
+ cwd=str(Path.home()))
246
286
  return name
247
287
 
248
288
 
249
289
  def spawn_hermes_chat(omega_home: str | Path | None = None) -> str:
250
- """Spawn the Hermès meta-companion chat tmux session.
251
-
252
- Runs ``omega hermes chat-loop`` — REPL conversation with Hermès on
253
- Anthropic API (separate budget from AISB's Max OAuth). This is what
254
- `omega hermes` attaches to (v0.19.15+).
290
+ """Spawn the Hermès chat tmux session — REAL Claude Code TUI, but on
291
+ Anthropic API (Hermès's own paid key, budget-isolated from Max OAuth).
292
+
293
+ Mirrors ``spawn_aisb_chat`` for the L2 companion: drops a Hermès
294
+ persona ``CLAUDE.md`` into a dedicated context dir, then runs
295
+ `claude` there with ``ANTHROPIC_API_KEY`` exported from the vault.
296
+ Setting the env var makes Claude Code use the API key instead of
297
+ the Max OAuth — same TUI, different billing surface.
255
298
  """
256
299
  name = "Hermes-chat"
257
300
  home = Path(omega_home or os.environ.get("OMEGA_HOME")
258
301
  or Path.home() / "Omega")
259
- omega_bin = home / "Agentik_Tools" / "bin" / "omega"
260
- spawn(name, command=f"{omega_bin} hermes chat-loop")
302
+ persona = home / "Agentik_SSOT" / "docs" / "LAYERS.md" # Hermès reads architecture as persona
303
+ ctx_dir = _ensure_chat_context_dir(home, "hermes", persona)
304
+ # Resolve Anthropic key from vault → fallback to existing env.
305
+ try:
306
+ from omega_engine.vault import vault_read
307
+ api_key = (vault_read(home, "ANTHROPIC_API_KEY_HERMES") or "").strip()
308
+ except Exception: # noqa: BLE001
309
+ api_key = ""
310
+ if not api_key:
311
+ api_key = (os.environ.get("ANTHROPIC_API_KEY") or "").strip()
312
+ # If no key, fall back to Max OAuth (Hermès will share AISB's
313
+ # billing — not ideal but better than failing). Surface a marker
314
+ # file in the context dir so the user sees the warning on first launch.
315
+ if not api_key:
316
+ (ctx_dir / "NO_ANTHROPIC_KEY.md").write_text(
317
+ "# Hermès — no Anthropic API key wired\n\n"
318
+ "Set `ANTHROPIC_API_KEY_HERMES` in the vault to use Hermès's\n"
319
+ "own paid Anthropic budget instead of the AISB Max OAuth.\n\n"
320
+ " omega vault write ANTHROPIC_API_KEY_HERMES sk-ant-...\n"
321
+ )
322
+ cmd = f"cd {ctx_dir} && exec claude"
323
+ else:
324
+ cmd = (f"cd {ctx_dir} && "
325
+ f"ANTHROPIC_API_KEY={api_key} exec claude")
326
+ spawn(name, command=cmd, cwd=str(Path.home()))
261
327
  return name
262
328
 
263
329
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "omega-engine"
3
- version = "0.19.16"
3
+ version = "0.19.18"
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"
@@ -1 +1 @@
1
- 0.19.16
1
+ 0.19.18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentikos/omega-os",
3
- "version": "0.19.16",
3
+ "version": "0.19.18",
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"