@agentikos/omega-os 0.19.10 → 0.19.12

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.
@@ -232,6 +232,38 @@ ask() {
232
232
  # UX — banner, preflight card, profile picker, step progress, post-install
233
233
  # ─────────────────────────────────────────────────────────────────────────────
234
234
 
235
+ # NEWT_COLORS — whiptail palette in Claude theme. Without this, whiptail
236
+ # defaults to the loud blue Windows-95 look. NEWT only knows 16 named
237
+ # colors, so we map the Claude warm-light theme to the closest pairs:
238
+ # brown ≈ #D97757 (Claude orange — used for accents)
239
+ # lightgray ≈ off-white body text
240
+ # black = backdrop (matches dark terminals)
241
+ # This is exported into install.sh's env AND wired into the user's
242
+ # shellrc by path_setup_user_rc so `omega` (the menu) also picks it up.
243
+ export NEWT_COLORS='
244
+ root=lightgray,black
245
+ window=lightgray,black
246
+ shadow=black,black
247
+ title=brown,black
248
+ border=brown,black
249
+ textbox=lightgray,black
250
+ listbox=lightgray,black
251
+ sellistbox=black,brown
252
+ actsellistbox=white,brown
253
+ button=black,brown
254
+ actbutton=white,brown
255
+ compactbutton=brown,black
256
+ checkbox=brown,black
257
+ actcheckbox=white,brown
258
+ entry=lightgray,black
259
+ disentry=gray,black
260
+ label=brown,black
261
+ helpline=brown,black
262
+ roottext=brown,black
263
+ emptyscale=black,gray
264
+ fullscale=brown,brown
265
+ '
266
+
235
267
  if [ -t 1 ]; then
236
268
  C_BOLD=$'\033[1m'
237
269
  # Claude Code light theme — derived from tweakcn.com/r/themes/claude.json.
@@ -447,12 +479,17 @@ path_setup_user_rc() {
447
479
  return 0
448
480
  fi
449
481
  mkdir -p "$(dirname "$rc")"
482
+ # Build the NEWT_COLORS one-liner so the user's interactive `omega`
483
+ # menu uses the Claude theme too (orange accents, no Win-95 blue).
484
+ local newt_oneline
485
+ newt_oneline="$(printf '%s' "$NEWT_COLORS" | tr '\n' ':' | sed 's/^://;s/:$//')"
450
486
  if [ "$(basename "$rc")" = "config.fish" ]; then
451
487
  {
452
488
  echo ""
453
489
  echo "$marker"
454
490
  echo "set -gx OMEGA_HOME \"$OMEGA_HOME\""
455
491
  echo "set -gx PATH \"\$OMEGA_HOME/Agentik_Tools/bin\" \$PATH"
492
+ echo "set -gx NEWT_COLORS '$newt_oneline'"
456
493
  echo "$close"
457
494
  } >> "$rc"
458
495
  else
@@ -461,6 +498,7 @@ path_setup_user_rc() {
461
498
  echo "$marker"
462
499
  echo "export OMEGA_HOME=\"$OMEGA_HOME\""
463
500
  echo "export PATH=\"\$OMEGA_HOME/Agentik_Tools/bin:\$PATH\""
501
+ echo "export NEWT_COLORS='$newt_oneline'"
464
502
  echo "$close"
465
503
  } >> "$rc"
466
504
  fi
@@ -478,7 +516,12 @@ post_install_card() {
478
516
  | python3 -c 'import sys,json
479
517
  try: d=json.load(sys.stdin); print(d.get("readiness","unknown"))
480
518
  except Exception: print("unknown")' 2>/dev/null)" || readiness="unknown"
481
- case "${readiness,,}" in
519
+ # macOS ships Bash 3.2 (Apple won't update due to GPLv3) — no
520
+ # ${var,,} support. Use `tr` for the lowercase normalize so the
521
+ # installer works on Mac out of the box.
522
+ local readiness_lc
523
+ readiness_lc="$(printf '%s' "$readiness" | tr '[:upper:]' '[:lower:]')"
524
+ case "$readiness_lc" in
482
525
  ready) verdict_text="READY" ; verdict_color="$C_GREEN" ;;
483
526
  partial) verdict_text="PARTIAL" ; verdict_color="$C_YELLOW" ;;
484
527
  not-ready|not_ready) verdict_text="NOT READY"; verdict_color="$C_RED" ;;
@@ -67,31 +67,50 @@ step_system_deps() {
67
67
  fi
68
68
  local uv_bin="$(command -v uv || echo "$HOME/.local/bin/uv")"
69
69
 
70
- # 2. Try uv first (works on Tahoe + any PEP-668 Python).
70
+ # 2. Try, in order of robustness:
71
+ # a) uv venv with Astral-MANAGED Python 3.13 — bypasses any
72
+ # broken system Python (e.g. brew Python 3.14 on macOS Tahoe
73
+ # which has a libexpat ABI mismatch breaking pyexpat,
74
+ # ensurepip, pip, and stdlib `python3 -m venv` all at once).
75
+ # b) uv venv with system python3 + --seed (uv-managed pip)
76
+ # c) stdlib `python3 -m venv --without-pip` — skip broken
77
+ # ensurepip; uv handles package install separately.
78
+ # d) stdlib `python3 -m venv` — original path (works on any
79
+ # healthy Python).
80
+ local _venv_method=""
71
81
  if [ -x "$uv_bin" ] && "$uv_bin" venv "$installer_venv" \
72
- --python python3 --quiet 2>>"$LOG_FILE"; then
73
- ok " installer venv created via uv"
82
+ --python 3.13 --quiet 2>>"$LOG_FILE"; then
83
+ _venv_method="uv + Astral-managed Python 3.13"
84
+ elif [ -x "$uv_bin" ] && "$uv_bin" venv "$installer_venv" \
85
+ --python python3 --seed --quiet 2>>"$LOG_FILE"; then
86
+ _venv_method="uv + system python3 + seed"
87
+ elif python3 -m venv "$installer_venv" --without-pip 2>>"$LOG_FILE"; then
88
+ _venv_method="python3 -m venv --without-pip"
74
89
  elif python3 -m venv "$installer_venv" 2>>"$LOG_FILE"; then
75
- ok " installer venv created via python3 -m venv"
90
+ _venv_method="python3 -m venv"
76
91
  else
77
- err "venv creation failed by both uv AND python3 -m venv — see $LOG_FILE"
92
+ err "venv creation failed across all paths — see $LOG_FILE"
78
93
  err "diagnose:"
79
- err " $uv_bin venv $installer_venv --python python3"
80
- err " python3 -m venv $installer_venv"
94
+ err " $uv_bin venv $installer_venv --python 3.13"
95
+ err " python3 -m venv $installer_venv --without-pip"
81
96
  return 1
82
97
  fi
98
+ ok " installer venv created via $_venv_method"
83
99
  fi
84
100
 
85
- # 3. Install pyyaml into the venv. Two methods, uv first.
101
+ # 3. Install pyyaml into the venv via uv (doesn't need pip inside the
102
+ # venv — uv handles it). Falls back to venv pip only if uv is
103
+ # unavailable AND the venv has its own pip.
86
104
  local uv_bin="$(command -v uv || echo "$HOME/.local/bin/uv")"
87
105
  if [ -x "$uv_bin" ] && "$uv_bin" pip install --quiet \
88
106
  --python "$installer_venv/bin/python3" pyyaml 2>>"$LOG_FILE"; then
89
107
  ok " pyyaml installed via uv pip"
90
- elif "$installer_venv/bin/pip" install --quiet pyyaml 2>>"$LOG_FILE"; then
108
+ elif [ -x "$installer_venv/bin/pip" ] && \
109
+ "$installer_venv/bin/pip" install --quiet pyyaml 2>>"$LOG_FILE"; then
91
110
  ok " pyyaml installed via venv pip"
92
111
  else
93
- err "pyyaml install failed in venv — see $LOG_FILE"
94
- err "diagnose: $installer_venv/bin/pip install pyyaml"
112
+ err "pyyaml install failed inside venv — see $LOG_FILE"
113
+ err "diagnose: $uv_bin pip install --python $installer_venv/bin/python3 pyyaml"
95
114
  return 1
96
115
  fi
97
116
  ok "installer venv ready: $installer_venv"
@@ -429,7 +448,12 @@ PY
429
448
  step_mcp() {
430
449
  local catalog="$OMEGA_HOME/Agentik_SSOT/mcp/mcp-catalog.yaml"
431
450
  [ -f "$catalog" ] || { err "MCP catalog missing: $catalog"; return 1; }
432
- info "MCP catalog present ($(grep -c '^- id:' "$catalog" 2>/dev/null || echo '?') entries)"
451
+ # grep -c exits 1 when count is 0, which made the old `|| echo '?'`
452
+ # fire AND grep's "0" stayed printed → "0\n? entries" splatter.
453
+ local _mcp_count
454
+ _mcp_count="$(grep -c '^- id:' "$catalog" 2>/dev/null || true)"
455
+ _mcp_count="$(printf '%s' "$_mcp_count" | tr -d '\n ' )"
456
+ info "MCP catalog present (${_mcp_count:-?} entries)"
433
457
 
434
458
  # Collect the selection into newline-separated $selected.
435
459
  local selected=""
@@ -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.10"
191
+ __version__ = "0.19.12"
192
192
 
193
193
  __all__ = [
194
194
  "__version__",
@@ -275,14 +275,21 @@ def cmd_doctor(args: argparse.Namespace) -> int:
275
275
  section("llm clis")
276
276
  import shutil as _shu
277
277
  import subprocess as _sup
278
- _cli_specs = [
278
+ # CLI specs split into REQUIRED (Claude Code is the only one we hard-
279
+ # require — everything else is genuinely optional). Optional CLIs that
280
+ # aren't installed are reported as ``info``, NOT ``warn``, so they no
281
+ # longer drag a clean install down to PARTIAL when the user opted out.
282
+ _required_clis = [
279
283
  ("claude_code", "claude", ["claude", "--version"]),
284
+ ]
285
+ _optional_clis = [
280
286
  ("gemini_cli", "gemini", ["gemini", "--version"]),
281
287
  ("codex", "codex", ["codex", "--version"]),
282
288
  ("aider", "aider", ["aider", "--version"]),
283
289
  ]
284
290
  any_cli = False
285
- for cli_id, bin_name, ver_cmd in _cli_specs:
291
+ for cli_id, bin_name, ver_cmd in _required_clis + _optional_clis:
292
+ is_optional = (cli_id, bin_name, ver_cmd) in _optional_clis
286
293
  if _shu.which(bin_name):
287
294
  any_cli = True
288
295
  try:
@@ -293,16 +300,21 @@ def cmd_doctor(args: argparse.Namespace) -> int:
293
300
  v = "(version check failed)"
294
301
  line("ok", f"{cli_id:<14} {v}")
295
302
  else:
296
- line("warn", f"{cli_id:<14} (not on PATH)")
297
- # GLM SDK is a Python import, not a binary
303
+ line("info" if is_optional else "warn",
304
+ f"{cli_id:<14} (not on PATH{', optional' if is_optional else ''})")
305
+ # GLM SDK is a Python import — also OPTIONAL (only used when the user
306
+ # opts into a GLM provider; flagging it as warn every install is wrong).
298
307
  try:
299
308
  import importlib
300
309
  importlib.import_module("zhipuai")
301
310
  line("ok", "glm_sdk (zhipuai Python SDK importable)")
302
311
  any_cli = True
303
312
  except ImportError:
304
- line("warn", "glm_sdk (not installed — `uv tool install zhipuai`)")
313
+ line("info", "glm_sdk (not installed, optional — "
314
+ "`uv tool install zhipuai`)")
305
315
  if not any_cli:
316
+ # Only flag PARTIAL when literally ZERO LLM CLI is present — at
317
+ # that point the system has no model to talk to.
306
318
  line("warn", "no LLM CLI installed — `omega upgrade` or re-run "
307
319
  "install.sh with the llm_clis: block")
308
320
 
@@ -324,12 +336,29 @@ def cmd_doctor(args: argparse.Namespace) -> int:
324
336
  line("ok" if dm == "bypassPermissions" else "warn",
325
337
  f"permissions.defaultMode: {dm or 'default'}")
326
338
  stop_hooks = (data.get("hooks") or {}).get("Stop") or []
339
+ # Accept the gate as wired if EITHER the `tag` is still ours
340
+ # OR ANY Stop hook commands `omega audit gate` (Claude Code
341
+ # may strip the custom `tag` field on its own rewrites of the
342
+ # settings file — content match is more resilient).
343
+ def _is_gate(entry: dict) -> bool:
344
+ if entry.get("tag") == "omega-audit-gate":
345
+ return True
346
+ for h in (entry.get("hooks") or []):
347
+ if not isinstance(h, dict):
348
+ continue
349
+ cmd = h.get("command", "")
350
+ args = h.get("args") or []
351
+ if cmd.endswith("/omega") and "gate" in args:
352
+ return True
353
+ return False
327
354
  has_gate = any(
328
- isinstance(e, dict) and e.get("tag") == "omega-audit-gate"
329
- for e in stop_hooks
355
+ isinstance(e, dict) and _is_gate(e) for e in stop_hooks
330
356
  )
331
- line("ok" if has_gate else "warn",
332
- f"Stop-hook audit gate: {'wired' if has_gate else 'not wired'}")
357
+ # Demoted to "info" when missing the gate is an
358
+ # opt-in safety net, not a hard requirement. Doctor no
359
+ # longer drops to PARTIAL just because the hook isn't there.
360
+ line("ok" if has_gate else "info",
361
+ f"Stop-hook audit gate: {'wired' if has_gate else 'not wired (optional)'}")
333
362
  except Exception as exc: # noqa: BLE001
334
363
  line("warn", f"settings.json unreadable: {exc}")
335
364
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "omega-engine"
3
- version = "0.19.10"
3
+ version = "0.19.12"
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"
@@ -319,7 +319,10 @@ class TestDoctorJSON(unittest.TestCase):
319
319
  self.assertIn("section", r)
320
320
  self.assertIn("status", r)
321
321
  self.assertIn("msg", r)
322
- self.assertIn(r["status"], {"ok", "warn", "FAIL"})
322
+ # "info" added in v0.19.12 for genuinely optional checks
323
+ # that should not drag READY → PARTIAL (e.g. optional
324
+ # LLM CLIs the user did not opt into).
325
+ self.assertIn(r["status"], {"ok", "warn", "FAIL", "info"})
323
326
 
324
327
 
325
328
  class TestInstallerWiring(unittest.TestCase):
@@ -1 +1 @@
1
- 0.19.10
1
+ 0.19.12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentikos/omega-os",
3
- "version": "0.19.10",
3
+ "version": "0.19.12",
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"