@agentikos/omega-os 0.19.11 → 0.19.13

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 (23) hide show
  1. package/bootstrap/lib/common.sh +44 -1
  2. package/bootstrap/lib/steps.sh +6 -1
  3. package/omega/Agentik_Engine/omega_engine/__init__.py +1 -1
  4. package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
  5. package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
  6. package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
  7. package/omega/Agentik_Engine/omega_engine/aisb_chat.py +43 -0
  8. package/omega/Agentik_Engine/omega_engine/cli.py +38 -9
  9. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
  10. package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +27 -14
  11. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
  12. package/omega/Agentik_Engine/omega_engine/genesis/stack.py +30 -0
  13. package/omega/Agentik_Engine/pyproject.toml +1 -1
  14. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
  15. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
  16. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
  17. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
  18. package/omega/Agentik_Engine/tests/test_install_steps.py +4 -1
  19. package/omega/Agentik_Engine/tests/test_telegram_history.py +63 -15
  20. package/omega/Agentik_SSOT/VERSION +1 -1
  21. package/omega/Agentik_SSOT/docs/references/README.md +17 -0
  22. package/omega/Agentik_SSOT/skills/desktop-architecture/SKILL.md +61 -0
  23. package/package.json +1 -1
@@ -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" ;;
@@ -448,7 +448,12 @@ PY
448
448
  step_mcp() {
449
449
  local catalog="$OMEGA_HOME/Agentik_SSOT/mcp/mcp-catalog.yaml"
450
450
  [ -f "$catalog" ] || { err "MCP catalog missing: $catalog"; return 1; }
451
- 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)"
452
457
 
453
458
  # Collect the selection into newline-separated $selected.
454
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.11"
191
+ __version__ = "0.19.13"
192
192
 
193
193
  __all__ = [
194
194
  "__version__",
@@ -60,6 +60,49 @@ def _clear_history(home: Path) -> int:
60
60
  conn.close()
61
61
 
62
62
 
63
+ def chat_once(home: Path, text: str, *,
64
+ topic_id: int = None,
65
+ record_history: bool = True) -> str:
66
+ """Run ONE conversation turn against the AISB envelope and return the
67
+ reply. Stateless from the caller's POV — history is persisted via
68
+ ``telegram_history`` keyed on ``topic_id`` (a single global default
69
+ for the tmux REPL; chat_id for Telegram DMs to keep per-user threads).
70
+
71
+ Extracted so the Telegram DM path can talk to the same agent the
72
+ tmux REPL talks to, without duplicating env+envelope+provider plumbing.
73
+ """
74
+ import time
75
+ from omega_engine.envelope import EnvelopeContext, build_envelope
76
+ from omega_engine.provider import AgentRequest
77
+ from omega_engine.router import ModelRouter
78
+ from omega_engine.telegram_history import (
79
+ build_context_prompt, record_inbound, record_outbound,
80
+ )
81
+ if topic_id is None:
82
+ topic_id = CHAT_TOPIC
83
+ if record_history:
84
+ record_inbound(home, topic_id=topic_id, text=text)
85
+ enriched = build_context_prompt(
86
+ home, topic_id=topic_id, new_intent=text, limit=10,
87
+ )
88
+ ctx = EnvelopeContext(
89
+ role="aisb",
90
+ intent=enriched,
91
+ task_id=f"chat-{int(time.time())}",
92
+ )
93
+ env = build_envelope(home, ctx)
94
+ router = ModelRouter.auto()
95
+ provider = router.resolve("aisb")
96
+ result = provider.run(AgentRequest(
97
+ role="aisb", prompt=env["user"], context={},
98
+ system=env["system"],
99
+ ))
100
+ reply = (result.text or "").strip() or "(empty reply)"
101
+ if record_history:
102
+ record_outbound(home, topic_id=topic_id, text=reply)
103
+ return reply
104
+
105
+
63
106
  def run_chat_loop() -> int:
64
107
  """Block until /quit. Returns 0 on clean exit."""
65
108
  home = _omega_home()
@@ -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
 
@@ -153,33 +153,46 @@ def _route_one(
153
153
  """
154
154
  from omega_engine import telegram_history
155
155
 
156
- # DM (no topic) — log it, refuse to start a mission. AISB DM
157
- # is NOT where the orchestration runs; it's where the operator
158
- # talks to the bot 1:1. The mission must run inside a project topic.
156
+ # DM (no topic) — route to the AISB conversational agent (same one
157
+ # the tmux REPL talks to). This used to refuse with "Missions only
158
+ # run from a project topic" which broke the most basic UX (a fresh
159
+ # install has no group topic yet, so the bot was effectively dead).
160
+ #
161
+ # Per-chat conversation history is namespaced by chat_id (encoded
162
+ # as a negative topic_id to avoid collisions with real Telegram
163
+ # forum topics, which are always positive small integers).
159
164
  if topic_id is None:
160
- # We still record DM history so the operator's question + the
161
- # bot's eventual reply (handled elsewhere) are linked.
165
+ dm_topic = -abs(int(chat_id)) if chat_id is not None else 0
162
166
  telegram_history.record_inbound(
163
- home, topic_id=0, text=text, message_id=message_id,
167
+ home, topic_id=dm_topic, text=text, message_id=message_id,
164
168
  )
165
169
  logger.info(
166
- "telegram in: DM (chat=%s) text=%r — refusing to start a "
167
- "mission from the DM; ask in a project topic instead",
170
+ "telegram in: DM (chat=%s) text=%r — routing to AISB chat",
168
171
  chat_id, text[:80],
169
172
  )
173
+ try:
174
+ from omega_engine.aisb_chat import chat_once
175
+ reply = chat_once(home, text, topic_id=dm_topic,
176
+ record_history=False)
177
+ except Exception as exc: # noqa: BLE001
178
+ logger.warning("telegram DM: chat_once failed",
179
+ exc_info=True)
180
+ reply = (
181
+ f"I hit an error talking to the AISB agent: {exc}\n"
182
+ "Check `omega doctor` for provider/account status."
183
+ )
184
+ telegram_history.record_outbound(
185
+ home, topic_id=dm_topic, text=reply,
186
+ )
170
187
  if telegram_bridge is not None and chat_id is not None:
171
188
  try:
172
189
  telegram_bridge._call("sendMessage", { # noqa: SLF001
173
190
  "chat_id": str(chat_id),
174
- "text": (
175
- "Missions only run from a project topic in the "
176
- "OmegaOS group — not the DM. Open the topic for "
177
- "the project and re-send your request there."
178
- ),
191
+ "text": reply[:3900],
179
192
  })
180
193
  except Exception: # noqa: BLE001
181
194
  logger.warning("telegram daemon: DM reply failed", exc_info=True)
182
- return "dm:refused"
195
+ return "dm:aisb-chat"
183
196
 
184
197
  # Topic message — record + route.
185
198
  telegram_history.record_inbound(
@@ -176,6 +176,35 @@ def _backend_supabase_stack() -> Stack:
176
176
  )
177
177
 
178
178
 
179
+ def _claude_dashboard_stack() -> Stack:
180
+ """The Claude Code-grade premium dashboard stack.
181
+
182
+ Picks up the architecture contract from
183
+ ``Agentik_SSOT/docs/references/CLAUDE-DESKTOP-FRONTEND-ARCHITECTURE.md``
184
+ during PRD + branding + design-system phases. Worker prompts include
185
+ the `/desktop-architecture` skill so every generated component traces
186
+ back to the same reference doc.
187
+ """
188
+ return Stack(
189
+ id="claude-dashboard",
190
+ title="Claude-grade premium dashboard (Next.js + Convex + shadcn + Motion + references doc)",
191
+ config=StackConfig(
192
+ type="web",
193
+ frontend="nextjs",
194
+ backend="convex",
195
+ deploy="vercel",
196
+ payments="stripe",
197
+ ui_kit="shadcn",
198
+ auth="clerk",
199
+ extras=["desktop-architecture-reference"],
200
+ ),
201
+ why="When the operator wants the Claude / Linear / Vercel / Stripe / "
202
+ "Elevenlabs dashboard look. Genesis phases pull from "
203
+ "Agentik_SSOT/docs/references/CLAUDE-DESKTOP-FRONTEND-ARCHITECTURE.md "
204
+ "as the single source of design truth.",
205
+ )
206
+
207
+
179
208
  CANONICAL_STACKS: dict[str, Stack] = {
180
209
  s.id: s for s in (
181
210
  default_stack(),
@@ -183,6 +212,7 @@ CANONICAL_STACKS: dict[str, Stack] = {
183
212
  _mobile_cross_stack(),
184
213
  _desktop_tauri_stack(),
185
214
  _backend_supabase_stack(),
215
+ _claude_dashboard_stack(),
186
216
  )
187
217
  }
188
218
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "omega-engine"
3
- version = "0.19.11"
3
+ version = "0.19.13"
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):
@@ -142,10 +142,15 @@ class TestTopicStats(unittest.TestCase):
142
142
  self.assertEqual(by_topic[2]["messages"], 1)
143
143
 
144
144
 
145
- class TestDaemonDMRefusal(unittest.TestCase):
146
- """The daemon must refuse to start a mission from a DM."""
147
- def test_dm_message_is_refused(self):
148
- from omega_engine.daemons.telegram import _route_one
145
+ class TestDaemonDMRoutesToAISBChat(unittest.TestCase):
146
+ """The daemon now routes DMs to the AISB conversational agent
147
+ (v0.19.13 change). Previously it refused with "project topic only",
148
+ which made the bot mute on a fresh install with no group yet."""
149
+
150
+ def test_dm_message_routes_to_aisb_chat(self):
151
+ from omega_engine.daemons import telegram as T
152
+ from omega_engine import aisb_chat
153
+ from unittest import mock
149
154
 
150
155
  class _FakeBridge:
151
156
  def __init__(self):
@@ -161,22 +166,65 @@ class TestDaemonDMRefusal(unittest.TestCase):
161
166
  with tempfile.TemporaryDirectory() as td:
162
167
  home = Path(td)
163
168
  bridge = _FakeBridge()
164
- tag = _route_one(
165
- topic_id=None, text="hi from DM",
166
- message_id=5, chat_id=12345,
167
- supervisor=_FakeSupervisor(),
168
- project_map={},
169
- home=home,
170
- telegram_bridge=bridge,
171
- )
172
- self.assertEqual(tag, "dm:refused")
173
- # We replied to the user with the redirect message.
169
+ with mock.patch.object(aisb_chat, "chat_once",
170
+ return_value="hello from AISB"):
171
+ tag = T._route_one(
172
+ topic_id=None, text="hi from DM",
173
+ message_id=5, chat_id=12345,
174
+ supervisor=_FakeSupervisor(),
175
+ project_map={},
176
+ home=home,
177
+ telegram_bridge=bridge,
178
+ )
179
+ self.assertEqual(tag, "dm:aisb-chat",
180
+ "DM must now be tagged as routed to AISB, not refused")
181
+ # We sent the AISB reply back via sendMessage.
174
182
  self.assertEqual(len(bridge.calls), 1)
175
183
  self.assertEqual(bridge.calls[0]["method"], "sendMessage")
176
184
  self.assertEqual(
177
185
  str(bridge.calls[0]["fields"]["chat_id"]), "12345",
178
186
  )
179
- self.assertIn("project topic", bridge.calls[0]["fields"]["text"])
187
+ self.assertEqual(
188
+ bridge.calls[0]["fields"]["text"], "hello from AISB",
189
+ )
190
+
191
+ def test_dm_history_is_namespaced_by_chat_id(self):
192
+ """Two DMs from different chats must NOT cross-contaminate history.
193
+ We use negative topic_ids derived from chat_id (real topics are
194
+ always positive Telegram forum thread IDs)."""
195
+ from omega_engine.daemons import telegram as T
196
+ from omega_engine import aisb_chat
197
+ from unittest import mock
198
+
199
+ class _FakeBridge:
200
+ def __init__(self): self.calls = []
201
+ def _call(self, method, fields, **_kw):
202
+ self.calls.append({"method": method, "fields": fields})
203
+ return {"message_id": 1}
204
+
205
+ class _FakeSupervisor:
206
+ def on_channel_message(self, t, x): return []
207
+
208
+ with tempfile.TemporaryDirectory() as td:
209
+ home = Path(td)
210
+ (home / "Agentik_Runtime").mkdir(parents=True)
211
+ captured: list[int] = []
212
+ def _fake_chat(home_arg, text, *, topic_id, record_history):
213
+ captured.append(topic_id)
214
+ return "ok"
215
+ with mock.patch.object(aisb_chat, "chat_once",
216
+ side_effect=_fake_chat):
217
+ T._route_one(topic_id=None, text="hi", message_id=1,
218
+ chat_id=42, supervisor=_FakeSupervisor(),
219
+ project_map={}, home=home,
220
+ telegram_bridge=_FakeBridge())
221
+ T._route_one(topic_id=None, text="hi", message_id=2,
222
+ chat_id=99, supervisor=_FakeSupervisor(),
223
+ project_map={}, home=home,
224
+ telegram_bridge=_FakeBridge())
225
+ self.assertEqual(captured, [-42, -99],
226
+ "DM history must be namespaced by chat_id "
227
+ "(encoded as negative topic_id)")
180
228
 
181
229
  def test_topic_message_records_history(self):
182
230
  from omega_engine.daemons.telegram import _route_one
@@ -1 +1 @@
1
- 0.19.11
1
+ 0.19.13
@@ -0,0 +1,17 @@
1
+ # References
2
+
3
+ Operator-curated source-of-truth documents that OmegaOS skills + Genesis
4
+ consume by name. Drop a new version of any file here and it propagates
5
+ to every project at the next `omega sync`.
6
+
7
+ ## Active references
8
+
9
+ | File | Consumed by | Topic |
10
+ |---|---|---|
11
+ | `CLAUDE-DESKTOP-FRONTEND-ARCHITECTURE.md` | `/desktop-architecture`, Genesis stack `claude-dashboard`, refonte audit | Premium desktop / dashboard UI architecture, the "Claude / Linear / Vercel / Stripe / Elevenlabs" canon |
12
+
13
+ ## Format
14
+
15
+ Plain Markdown. No frontmatter needed — these are reference docs, not
16
+ SKILL.md. Headings should be self-describing so skills can extract
17
+ sub-sections by regex if needed.
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: desktop-architecture
3
+ description: >
4
+ Reference skill — pull the canonical Claude Code-grade desktop/dashboard
5
+ architecture (`Agentik_SSOT/docs/references/CLAUDE-DESKTOP-FRONTEND-ARCHITECTURE.md`)
6
+ and apply it to a project. Triggers on "desktop architecture", "Claude
7
+ dashboard", "Claude desktop", "premium dashboard", "comme Linear / Vercel
8
+ / Stripe / Elevenlabs", "dashboard senior", "claude stack". Use whenever
9
+ the user asks for a dashboard refonte or a new project that needs the
10
+ Claude-grade desktop look.
11
+ when_to_use: >
12
+ User mentions "desktop architecture", "Claude dashboard", "Claude desktop
13
+ stack", or asks for a dashboard rebuild "comme Claude / Linear / Vercel /
14
+ Stripe / Elevenlabs". Also triggers automatically when the Genesis stack
15
+ picker selects the `claude-dashboard` preset.
16
+ allowed-tools: Read Grep Glob
17
+ ---
18
+
19
+ # /desktop-architecture — pull the canonical Claude dashboard reference
20
+
21
+ This skill loads the **Claude Desktop Frontend Architecture** reference
22
+ document from the SSOT and applies its principles to the current task.
23
+
24
+ ## What it does
25
+
26
+ 1. Reads `$OMEGA_HOME/Agentik_SSOT/docs/references/CLAUDE-DESKTOP-FRONTEND-ARCHITECTURE.md`
27
+ 2. Extracts the relevant section (components, layout, motion, palette,
28
+ typography, density, navigation, command palette, etc.)
29
+ 3. Applies it as the design contract for the requested task:
30
+ - **Refonte audit** — score the current UI against this contract
31
+ - **Genesis** — when stack = `claude-dashboard`, the PRD, branding and
32
+ design-system phases derive their tokens from this doc
33
+ - **Component builder** — when a worker generates a new dashboard
34
+ screen, it references the layout primitives from this doc first
35
+
36
+ ## Triggers (any of these in a user prompt invoke me)
37
+
38
+ - `desktop architecture`
39
+ - `Claude desktop` / `Claude dashboard` / `Claude stack`
40
+ - `premium dashboard` / `dashboard senior`
41
+ - `comme Linear` / `comme Vercel` / `comme Stripe` / `comme Elevenlabs`
42
+ - `refais le dashboard` / `redesign dashboard` (combined with project name)
43
+
44
+ ## Where it lives
45
+
46
+ The reference doc itself lives at:
47
+ `$OMEGA_HOME/Agentik_SSOT/docs/references/CLAUDE-DESKTOP-FRONTEND-ARCHITECTURE.md`
48
+
49
+ It's the single source of truth — when Gareth refreshes the document
50
+ (e.g. new components, new motion language), every project re-reads it
51
+ on next `/desktop-architecture` invocation. No fork, no drift.
52
+
53
+ ## How to refresh the reference
54
+
55
+ The operator drops a new version into the SSOT path above, then runs:
56
+
57
+ ```bash
58
+ omega sync # projects to ~/.claude/skills/<id>/
59
+ ```
60
+
61
+ Workers spawned after the sync pick up the new content automatically.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentikos/omega-os",
3
- "version": "0.19.11",
3
+ "version": "0.19.13",
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"