@agentikos/omega-os 0.19.21 → 0.19.22
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/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
- package/bootstrap/lib/llm-clis.py +32 -0
- 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__/personas.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/cli.py +85 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/stack.py +57 -0
- package/omega/Agentik_Engine/omega_engine/personas.py +197 -0
- package/omega/Agentik_Engine/omega_engine/tmux.py +48 -18
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +8 -0
- package/package.json +1 -1
|
Binary file
|
|
@@ -99,6 +99,38 @@ _CATALOG: list[CliSpec] = [
|
|
|
99
99
|
install_cmd=[], # filled at runtime
|
|
100
100
|
description="Community aider-chat (`aider`)",
|
|
101
101
|
),
|
|
102
|
+
# v0.19.22 — extended provider matrix per the user's "install them all,
|
|
103
|
+
# let me hot-swap" spec.
|
|
104
|
+
CliSpec(
|
|
105
|
+
id="opencode", label="OpenCode (community multi-LLM)",
|
|
106
|
+
bin_name="opencode",
|
|
107
|
+
install_cmd=["npm", "install", "-g", "opencode-ai"],
|
|
108
|
+
description="OpenCode — terminal AI coding with provider switching",
|
|
109
|
+
),
|
|
110
|
+
CliSpec(
|
|
111
|
+
id="openrouter_cli", label="OpenRouter via OpenCode",
|
|
112
|
+
bin_name="opencode", # opencode supports openrouter as a provider
|
|
113
|
+
install_cmd=[], # piggy-backs on opencode install
|
|
114
|
+
description="OpenRouter (300+ models) via OpenCode provider",
|
|
115
|
+
),
|
|
116
|
+
CliSpec(
|
|
117
|
+
id="deepseek", label="DeepSeek (via OpenCode)",
|
|
118
|
+
bin_name="opencode",
|
|
119
|
+
install_cmd=[],
|
|
120
|
+
description="DeepSeek V3 / R1 via OpenCode provider",
|
|
121
|
+
),
|
|
122
|
+
CliSpec(
|
|
123
|
+
id="qwen_code", label="Qwen Code (Alibaba CLI)",
|
|
124
|
+
bin_name="qwen",
|
|
125
|
+
install_cmd=["npm", "install", "-g", "@qwen-code/qwen-code"],
|
|
126
|
+
description="Alibaba's Qwen Coder CLI (`qwen`)",
|
|
127
|
+
),
|
|
128
|
+
CliSpec(
|
|
129
|
+
id="continue_dev", label="Continue.dev (terminal)",
|
|
130
|
+
bin_name="cn",
|
|
131
|
+
install_cmd=["npm", "install", "-g", "@continuedev/cli"],
|
|
132
|
+
description="Continue.dev CLI — multi-provider with config.json",
|
|
133
|
+
),
|
|
102
134
|
]
|
|
103
135
|
|
|
104
136
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2941,6 +2941,80 @@ def cmd_menu_whiptail(_args: argparse.Namespace) -> int:
|
|
|
2941
2941
|
return run_menu()
|
|
2942
2942
|
|
|
2943
2943
|
|
|
2944
|
+
# Default LLM provider for chat sessions — recorded in a tiny state file
|
|
2945
|
+
# so spawn_*_chat picks the right one. Hot-swap via `omega switch <id>`.
|
|
2946
|
+
_PROVIDER_MARKER = "active-llm-provider"
|
|
2947
|
+
|
|
2948
|
+
|
|
2949
|
+
def _provider_state_path() -> "Path":
|
|
2950
|
+
from pathlib import Path
|
|
2951
|
+
home = _omega_home()
|
|
2952
|
+
return home / "Agentik_Extra" / "var" / _PROVIDER_MARKER
|
|
2953
|
+
|
|
2954
|
+
|
|
2955
|
+
def _active_provider() -> str:
|
|
2956
|
+
p = _provider_state_path()
|
|
2957
|
+
if p.exists():
|
|
2958
|
+
return p.read_text().strip() or "claude_code"
|
|
2959
|
+
return "claude_code"
|
|
2960
|
+
|
|
2961
|
+
|
|
2962
|
+
def _set_active_provider(provider_id: str) -> None:
|
|
2963
|
+
p = _provider_state_path()
|
|
2964
|
+
p.parent.mkdir(parents=True, exist_ok=True)
|
|
2965
|
+
p.write_text(provider_id.strip() + "\n")
|
|
2966
|
+
|
|
2967
|
+
|
|
2968
|
+
def cmd_switch(args: argparse.Namespace) -> int:
|
|
2969
|
+
"""`omega switch <provider>` — hot-swap the LLM provider for new chats.
|
|
2970
|
+
|
|
2971
|
+
Existing tmux sessions keep their current provider; only the NEXT
|
|
2972
|
+
chat session spawned (via `omega`, `omega aisb`, `omega hermes`) uses
|
|
2973
|
+
the new one. Per-LLM persona files are already in place in every
|
|
2974
|
+
context dir (write_all_personas runs at install + on every spawn),
|
|
2975
|
+
so switching is just changing which `cli` the tmux session launches.
|
|
2976
|
+
|
|
2977
|
+
Supported provider ids (must match the LLM CLI catalog in
|
|
2978
|
+
`bootstrap/lib/llm-clis.py` + `omega_engine.personas`):
|
|
2979
|
+
|
|
2980
|
+
claude_code, gemini_cli, codex, opencode, openrouter_cli,
|
|
2981
|
+
deepseek, qwen_code, continue_dev, aider
|
|
2982
|
+
"""
|
|
2983
|
+
import shutil
|
|
2984
|
+
valid = {
|
|
2985
|
+
"claude_code": "claude",
|
|
2986
|
+
"gemini_cli": "gemini",
|
|
2987
|
+
"codex": "codex",
|
|
2988
|
+
"opencode": "opencode",
|
|
2989
|
+
"openrouter_cli": "opencode",
|
|
2990
|
+
"deepseek": "opencode",
|
|
2991
|
+
"qwen_code": "qwen",
|
|
2992
|
+
"continue_dev": "cn",
|
|
2993
|
+
"aider": "aider",
|
|
2994
|
+
}
|
|
2995
|
+
if not getattr(args, "provider", None):
|
|
2996
|
+
print(f" active provider: {_active_provider()}")
|
|
2997
|
+
print(f" available:")
|
|
2998
|
+
for pid, bin_name in valid.items():
|
|
2999
|
+
mark = "✓" if shutil.which(bin_name) else "—"
|
|
3000
|
+
active = " (active)" if pid == _active_provider() else ""
|
|
3001
|
+
print(f" {mark} {pid:<16} ({bin_name}){active}")
|
|
3002
|
+
return 0
|
|
3003
|
+
target = args.provider
|
|
3004
|
+
if target not in valid:
|
|
3005
|
+
print(f" unknown provider: {target!r}")
|
|
3006
|
+
print(f" valid: {', '.join(valid)}")
|
|
3007
|
+
return 2
|
|
3008
|
+
if not shutil.which(valid[target]):
|
|
3009
|
+
print(f" provider {target!r} not installed — `omega upgrade` "
|
|
3010
|
+
f"or re-run install.sh with the llm_clis: block")
|
|
3011
|
+
return 2
|
|
3012
|
+
_set_active_provider(target)
|
|
3013
|
+
print(f" active provider set to: {target}")
|
|
3014
|
+
print(f" next `omega` / `omega aisb` / `omega hermes` will launch with `{valid[target]}`")
|
|
3015
|
+
return 0
|
|
3016
|
+
|
|
3017
|
+
|
|
2944
3018
|
def cmd_hermes_desktop(args: argparse.Namespace) -> int:
|
|
2945
3019
|
"""`omega hermes-desktop {install,serve,profile,status}` — expose this
|
|
2946
3020
|
VPS as a remote backend for the Hermes Desktop Electron app."""
|
|
@@ -4024,6 +4098,17 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
4024
4098
|
help="open the interactive whiptail menu (the old `omega` behaviour)"
|
|
4025
4099
|
).set_defaults(fn=cmd_menu_whiptail)
|
|
4026
4100
|
sub.add_parser("version", help="print the engine version").set_defaults(fn=cmd_version)
|
|
4101
|
+
|
|
4102
|
+
# `omega switch <provider>` — hot-swap the LLM CLI used for new chats.
|
|
4103
|
+
p_sw = sub.add_parser(
|
|
4104
|
+
"switch",
|
|
4105
|
+
help="switch the default LLM provider for new chat sessions "
|
|
4106
|
+
"(claude_code / gemini_cli / codex / opencode / qwen_code / "
|
|
4107
|
+
"continue_dev / aider)",
|
|
4108
|
+
)
|
|
4109
|
+
p_sw.add_argument("provider", nargs="?", default=None,
|
|
4110
|
+
help="provider id (omit to print current + available)")
|
|
4111
|
+
p_sw.set_defaults(fn=cmd_switch)
|
|
4027
4112
|
p_doc = sub.add_parser("doctor", help="validate the deployment")
|
|
4028
4113
|
p_doc.add_argument("--json", action="store_true",
|
|
4029
4114
|
help="emit a single JSON object instead of pretty text")
|
|
Binary file
|
|
@@ -176,6 +176,61 @@ def _backend_supabase_stack() -> Stack:
|
|
|
176
176
|
)
|
|
177
177
|
|
|
178
178
|
|
|
179
|
+
def _convex_selfhosted_stack() -> Stack:
|
|
180
|
+
"""Self-hosted Convex backend running on the operator's VPS.
|
|
181
|
+
|
|
182
|
+
Convex went open-source in 2024 — you can run the full backend
|
|
183
|
+
locally or on a VPS instead of paying the Convex Cloud. This stack
|
|
184
|
+
pre-wires that path: Next.js + Vercel frontend, Convex self-hosted
|
|
185
|
+
on the operator's VPS, Stripe payments, Clerk auth, shadcn UI.
|
|
186
|
+
"""
|
|
187
|
+
return Stack(
|
|
188
|
+
id="convex-selfhosted",
|
|
189
|
+
title="Convex self-hosted (VPS) + Next.js + Vercel + Stripe + Clerk",
|
|
190
|
+
config=StackConfig(
|
|
191
|
+
type="web",
|
|
192
|
+
frontend="nextjs",
|
|
193
|
+
backend="convex", # but with extras=["selfhosted"]
|
|
194
|
+
deploy="vercel",
|
|
195
|
+
payments="stripe",
|
|
196
|
+
ui_kit="shadcn",
|
|
197
|
+
auth="clerk",
|
|
198
|
+
extras=["convex-selfhosted", "vps-backend"],
|
|
199
|
+
),
|
|
200
|
+
why="When the operator wants Convex's real-time + typed model "
|
|
201
|
+
"without Convex Cloud lock-in. Backend runs on their VPS via "
|
|
202
|
+
"the open-source Convex docker image. Same DX, zero per-call "
|
|
203
|
+
"cost, full data sovereignty.",
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _sqlite_local_stack() -> Stack:
|
|
208
|
+
"""Local SQLite-only stack — the simplest possible.
|
|
209
|
+
|
|
210
|
+
For tools, internal apps, single-user dashboards. No backend
|
|
211
|
+
process needed, no auth surface, no per-call cost. Drizzle ORM
|
|
212
|
+
over better-sqlite3 gives a typed query layer.
|
|
213
|
+
"""
|
|
214
|
+
return Stack(
|
|
215
|
+
id="sqlite-local",
|
|
216
|
+
title="Local SQLite (Next.js + Drizzle + Vercel — single-user)",
|
|
217
|
+
config=StackConfig(
|
|
218
|
+
type="web",
|
|
219
|
+
frontend="nextjs",
|
|
220
|
+
backend="postgres+drizzle", # drizzle works with sqlite too
|
|
221
|
+
deploy="vercel",
|
|
222
|
+
payments="none",
|
|
223
|
+
ui_kit="shadcn",
|
|
224
|
+
auth="none",
|
|
225
|
+
extras=["sqlite-local", "drizzle-sqlite"],
|
|
226
|
+
),
|
|
227
|
+
why="Single-user / internal-tool stack. SQLite file in the project "
|
|
228
|
+
"dir, Drizzle for typed queries, no auth, no payments. Ship "
|
|
229
|
+
"in 20 minutes. Upgrade to a real backend later when the "
|
|
230
|
+
"scale calls for it.",
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
|
|
179
234
|
def _claude_dashboard_stack() -> Stack:
|
|
180
235
|
"""The Claude Code-grade premium dashboard stack.
|
|
181
236
|
|
|
@@ -213,6 +268,8 @@ CANONICAL_STACKS: dict[str, Stack] = {
|
|
|
213
268
|
_desktop_tauri_stack(),
|
|
214
269
|
_backend_supabase_stack(),
|
|
215
270
|
_claude_dashboard_stack(),
|
|
271
|
+
_convex_selfhosted_stack(),
|
|
272
|
+
_sqlite_local_stack(),
|
|
216
273
|
)
|
|
217
274
|
}
|
|
218
275
|
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""Multi-LLM persona writer — one canonical OmegaOS context, N output files.
|
|
2
|
+
|
|
3
|
+
Every LLM CLI we install (Claude Code, Gemini CLI, OpenAI Codex, OpenCode,
|
|
4
|
+
Continue.dev, Qwen, Aider…) reads a different filename for its project
|
|
5
|
+
context (CLAUDE.md, GEMINI.md, AGENTS.md, .opencode/CONTEXT.md, etc.).
|
|
6
|
+
Without a canonical source, the operator has to copy the same content
|
|
7
|
+
into N files manually and they drift.
|
|
8
|
+
|
|
9
|
+
This module:
|
|
10
|
+
|
|
11
|
+
1. Defines the canonical OmegaOS context at one path
|
|
12
|
+
(``$OMEGA_HOME/Agentik_SSOT/personas/OMEGAOS-CONTEXT.md``).
|
|
13
|
+
2. Exports ``write_all_personas(home, chat_context_dir)`` which mirrors
|
|
14
|
+
that one canonical file into every LLM's expected filename inside the
|
|
15
|
+
project dir, so when the user runs `claude`, `gemini`, `codex`,
|
|
16
|
+
etc. in that dir they ALL load the same OmegaOS persona.
|
|
17
|
+
3. Idempotent — re-running diff-checks before write.
|
|
18
|
+
|
|
19
|
+
Used by:
|
|
20
|
+
* step_clis post-install pass — seeds the canonical context.
|
|
21
|
+
* tmux.spawn_*_chat — ensures the chat context dir has every persona
|
|
22
|
+
file before launching whichever CLI the user picked.
|
|
23
|
+
* `omega switch <provider>` — re-renders the active context's
|
|
24
|
+
persona pointer.
|
|
25
|
+
"""
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import shutil
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# The single source of truth. Every per-LLM persona file is a symlink or
|
|
33
|
+
# mirror of this.
|
|
34
|
+
CANONICAL_FILENAME = "OMEGAOS-CONTEXT.md"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Map: LLM id → list of persona filenames it reads (relative to a project dir).
|
|
38
|
+
# Sources:
|
|
39
|
+
# - Anthropic Claude Code → CLAUDE.md (project root or ~/.claude/CLAUDE.md)
|
|
40
|
+
# - Google Gemini CLI → GEMINI.md (project root or ~/.gemini/GEMINI.md)
|
|
41
|
+
# - OpenAI Codex CLI → AGENTS.md (project root)
|
|
42
|
+
# - OpenCode → .opencode/CONTEXT.md
|
|
43
|
+
# - Continue.dev → .continue/CONTEXT.md
|
|
44
|
+
# - Qwen Code → QWEN.md
|
|
45
|
+
# - Aider → .aider.conf.yml (config, not full context)
|
|
46
|
+
# + CONVENTIONS.md (Aider's persona convention)
|
|
47
|
+
_LLM_PERSONA_PATHS: dict[str, list[str]] = {
|
|
48
|
+
"claude_code": ["CLAUDE.md"],
|
|
49
|
+
"gemini_cli": ["GEMINI.md"],
|
|
50
|
+
"codex": ["AGENTS.md"],
|
|
51
|
+
"opencode": [".opencode/CONTEXT.md"],
|
|
52
|
+
"openrouter_cli": [".opencode/CONTEXT.md"],
|
|
53
|
+
"deepseek": [".opencode/CONTEXT.md"],
|
|
54
|
+
"qwen_code": ["QWEN.md"],
|
|
55
|
+
"continue_dev": [".continue/CONTEXT.md"],
|
|
56
|
+
"aider": ["CONVENTIONS.md"],
|
|
57
|
+
"hermes": ["HERMES.md"],
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
_DEFAULT_CONTEXT_TEMPLATE = """\
|
|
62
|
+
# OmegaOS — Working Context
|
|
63
|
+
|
|
64
|
+
> *You are running inside an OmegaOS-managed Claude/Gemini/Codex/OpenCode
|
|
65
|
+
> session. This file is auto-generated by `omega_engine.personas` and
|
|
66
|
+
> mirrored from `$OMEGA_HOME/Agentik_SSOT/personas/OMEGAOS-CONTEXT.md`.
|
|
67
|
+
> Edits to per-LLM files (CLAUDE.md, GEMINI.md, …) are lost on next sync —
|
|
68
|
+
> edit the canonical file instead.*
|
|
69
|
+
|
|
70
|
+
## What OmegaOS is
|
|
71
|
+
|
|
72
|
+
OmegaOS is a 5-layer agentic operating system:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
Layer 1 Human (Telegram, CLI, web)
|
|
76
|
+
Layer 2 Hermès — meta-companion (Anthropic API, separate budget)
|
|
77
|
+
Layer 3 AISB — OmegaOS intake / orchestrator (Claude Max OAuth)
|
|
78
|
+
Layer 4 Oracle — planner / dispatcher (per-project tmux session)
|
|
79
|
+
Layer 5 Workers — executors (one per subtask, .done.json verified)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
You sit at L4 or L5 depending on context.
|
|
83
|
+
|
|
84
|
+
## The Three Laws (override everything)
|
|
85
|
+
|
|
86
|
+
1. **Code lies. Comments lie. Only runtime tells the truth.**
|
|
87
|
+
Observe before concluding. Before the 3rd code change on the same
|
|
88
|
+
bug, live runtime evidence is MANDATORY.
|
|
89
|
+
2. **Researcher, not sycophant.** Challenge flawed premises. Think
|
|
90
|
+
before coding. Iterate with evidence. Root causes over symptoms.
|
|
91
|
+
3. **Autonomous execution.** When dispatched, never wait. Decide →
|
|
92
|
+
execute → report. The only legal stop is `.done.json` with status
|
|
93
|
+
`done_clean | pending | failed`.
|
|
94
|
+
|
|
95
|
+
## OmegaOS structure (where things live)
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
$OMEGA_HOME = ~/Omega
|
|
99
|
+
├── Agentik_Engine/ ← Python engine (omega CLI)
|
|
100
|
+
├── Agentik_SSOT/ ← source of truth
|
|
101
|
+
│ ├── skills/ ← 17 audits + orchestrators + /newcmd
|
|
102
|
+
│ ├── agents/aisb/ ← 13 AISB persona files
|
|
103
|
+
│ ├── personas/OMEGAOS-CONTEXT.md ← THIS FILE
|
|
104
|
+
│ ├── docs/LAYERS.md ← formal L1-L5 architecture
|
|
105
|
+
│ └── clis/clis-catalog.yaml ← CLI catalog
|
|
106
|
+
├── Agentik_Orchestration/ ← topology YAMLs
|
|
107
|
+
├── Agentik_Coding/projects/<slug>/ ← per-project root (strict isolation)
|
|
108
|
+
├── Agentik_Runtime/ ← event log, RAG, locks, sessions
|
|
109
|
+
├── Agentik_Tools/bin/omega ← the CLI you can shell out to
|
|
110
|
+
└── Agentik_Extra/etc/secrets/ ← age-encrypted vault
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## What you can do (shell out via Bash)
|
|
114
|
+
|
|
115
|
+
| Action | Command |
|
|
116
|
+
|---|---|
|
|
117
|
+
| Mission with verified completion | `omega run "<intent>"` |
|
|
118
|
+
| New project (Genesis pipeline) | `omega genesis new <slug>` |
|
|
119
|
+
| Audit code/UI/flow/security/… | `omega audit <id>` (or the `/codeaudit` skill) |
|
|
120
|
+
| Switch LLM provider for this session | `omega switch <provider>` |
|
|
121
|
+
| Vault secrets | `omega vault read/write <REF>` |
|
|
122
|
+
| Status / health | `omega doctor` / `omega status` |
|
|
123
|
+
| Session manager (tmux) | `omega` (no args) |
|
|
124
|
+
|
|
125
|
+
## Quality Arsenal (17 forensic audits)
|
|
126
|
+
|
|
127
|
+
`/codeaudit /flowaudit /uiuxaudit /debugaudit /featureaudit /perfaudit
|
|
128
|
+
/secaudit /a11yaudit /seoaudit /dataaudit /apiaudit /copyaudit /dxaudit
|
|
129
|
+
/motionaudit /automationaudit /logicaudit /retentionaudit`
|
|
130
|
+
|
|
131
|
+
Each: Gestalt clarity gate, Popper falsification, hinge point 10x
|
|
132
|
+
scrutiny, auto-fix, auto-re-audit, scored /100.
|
|
133
|
+
|
|
134
|
+
## When something doesn't fit OmegaOS
|
|
135
|
+
|
|
136
|
+
Push back. Don't quietly invent. State the premise, decide, execute.
|
|
137
|
+
If the user's request would violate one of the Three Laws or the
|
|
138
|
+
verified-completion contract, call it out — they want a researcher,
|
|
139
|
+
not a yes-engine.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def canonical_path(omega_home: Path) -> Path:
|
|
144
|
+
"""Where the single source of truth lives."""
|
|
145
|
+
return omega_home / "Agentik_SSOT" / "personas" / CANONICAL_FILENAME
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def ensure_canonical(omega_home: Path) -> Path:
|
|
149
|
+
"""Create the canonical OmegaOS context file if absent. Returns its
|
|
150
|
+
path. Operators are free to edit this file — it's the SSOT."""
|
|
151
|
+
path = canonical_path(omega_home)
|
|
152
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
153
|
+
if not path.exists():
|
|
154
|
+
path.write_text(_DEFAULT_CONTEXT_TEMPLATE)
|
|
155
|
+
return path
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def write_all_personas(
|
|
159
|
+
omega_home: Path | str,
|
|
160
|
+
chat_context_dir: Path | str,
|
|
161
|
+
*,
|
|
162
|
+
llm_ids: list[str] | None = None,
|
|
163
|
+
) -> dict[str, str]:
|
|
164
|
+
"""Mirror the canonical context into every LLM's expected filename
|
|
165
|
+
inside ``chat_context_dir``.
|
|
166
|
+
|
|
167
|
+
Returns ``{llm_id: relative_path}`` for what was written. Files
|
|
168
|
+
that already match (content equality) are skipped silently —
|
|
169
|
+
idempotent.
|
|
170
|
+
|
|
171
|
+
When ``llm_ids`` is None we write for every LLM in
|
|
172
|
+
``_LLM_PERSONA_PATHS`` (cheap insurance against the user later
|
|
173
|
+
swapping providers).
|
|
174
|
+
"""
|
|
175
|
+
home = Path(omega_home)
|
|
176
|
+
ctx_dir = Path(chat_context_dir)
|
|
177
|
+
ctx_dir.mkdir(parents=True, exist_ok=True)
|
|
178
|
+
|
|
179
|
+
src = ensure_canonical(home)
|
|
180
|
+
content = src.read_text()
|
|
181
|
+
|
|
182
|
+
targets = list(llm_ids) if llm_ids else list(_LLM_PERSONA_PATHS)
|
|
183
|
+
written: dict[str, str] = {}
|
|
184
|
+
for llm in targets:
|
|
185
|
+
for rel in _LLM_PERSONA_PATHS.get(llm, []):
|
|
186
|
+
dest = ctx_dir / rel
|
|
187
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
188
|
+
if dest.exists() and dest.read_text() == content:
|
|
189
|
+
continue
|
|
190
|
+
dest.write_text(content)
|
|
191
|
+
written[llm] = rel
|
|
192
|
+
return written
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def supported_llm_ids() -> list[str]:
|
|
196
|
+
"""The LLM ids personas can be written for."""
|
|
197
|
+
return list(_LLM_PERSONA_PATHS)
|
|
@@ -233,29 +233,59 @@ def spawn_worker(project: str, task: str, *,
|
|
|
233
233
|
|
|
234
234
|
def _ensure_chat_context_dir(home: Path, label: str,
|
|
235
235
|
persona_md_path: Path) -> Path:
|
|
236
|
-
"""Create (idempotent) a
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
the
|
|
236
|
+
"""Create (idempotent) a multi-LLM project dir for an OmegaOS chat
|
|
237
|
+
session.
|
|
238
|
+
|
|
239
|
+
v0.19.22 — drops persona files for EVERY supported LLM (CLAUDE.md,
|
|
240
|
+
GEMINI.md, AGENTS.md, QWEN.md, .opencode/CONTEXT.md, etc.) sourced
|
|
241
|
+
from the canonical ``Agentik_SSOT/personas/OMEGAOS-CONTEXT.md``.
|
|
242
|
+
User can `claude` here, OR `gemini`, OR `codex`, OR `opencode`, OR
|
|
243
|
+
`qwen`, OR `aider` — they all see the SAME OmegaOS context. Hot-swap
|
|
244
|
+
works because every CLI's file is already in place.
|
|
245
|
+
|
|
246
|
+
The ``persona_md_path`` argument is now used only as a hint: if a
|
|
247
|
+
role-specific persona file exists at that path (e.g. the AISB v7.0
|
|
248
|
+
master prompt), we PREPEND it to the canonical context so AISB-chat
|
|
249
|
+
gets both the role identity AND the OmegaOS background, while
|
|
250
|
+
Hermes-chat gets just the canonical context.
|
|
242
251
|
"""
|
|
243
252
|
ctx_dir = home / "Agentik_Coding" / "chat-contexts" / label
|
|
244
253
|
ctx_dir.mkdir(parents=True, exist_ok=True)
|
|
245
|
-
|
|
246
|
-
if
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
254
|
+
|
|
255
|
+
# Build the merged context: role-specific persona (if any) + canonical.
|
|
256
|
+
from omega_engine.personas import (
|
|
257
|
+
canonical_path, ensure_canonical, write_all_personas,
|
|
258
|
+
)
|
|
259
|
+
ensure_canonical(home)
|
|
260
|
+
canonical_text = canonical_path(home).read_text()
|
|
261
|
+
if persona_md_path.is_file() and persona_md_path.name not in (
|
|
262
|
+
"OMEGAOS-CONTEXT.md",
|
|
263
|
+
):
|
|
264
|
+
role_text = persona_md_path.read_text()
|
|
265
|
+
merged = f"{role_text}\n\n---\n\n{canonical_text}"
|
|
266
|
+
# Write merged to the canonical filename in ctx_dir, then mirror
|
|
267
|
+
# to every LLM's expected filename via personas.write_all.
|
|
268
|
+
merged_file = ctx_dir / "OMEGAOS-CONTEXT.md"
|
|
269
|
+
merged_file.write_text(merged)
|
|
270
|
+
# personas.write_all reads from the canonical — temporarily point
|
|
271
|
+
# to the merged version by writing per-LLM files directly.
|
|
272
|
+
for llm_id in [
|
|
273
|
+
"claude_code", "gemini_cli", "codex", "opencode",
|
|
274
|
+
"qwen_code", "continue_dev", "aider", "hermes",
|
|
275
|
+
]:
|
|
276
|
+
from omega_engine.personas import _LLM_PERSONA_PATHS # noqa: WPS437
|
|
277
|
+
for rel in _LLM_PERSONA_PATHS.get(llm_id, []):
|
|
278
|
+
dest = ctx_dir / rel
|
|
279
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
280
|
+
if not dest.exists() or dest.read_text() != merged:
|
|
281
|
+
dest.write_text(merged)
|
|
282
|
+
else:
|
|
283
|
+
write_all_personas(home, ctx_dir)
|
|
284
|
+
|
|
285
|
+
# `.gitignore` so the transient dir doesn't get committed.
|
|
256
286
|
gi = ctx_dir / ".gitignore"
|
|
257
287
|
if not gi.exists():
|
|
258
|
-
gi.write_text("*\n!.gitignore\n
|
|
288
|
+
gi.write_text("*\n!.gitignore\n!*.md\n!.opencode/\n!.continue/\n")
|
|
259
289
|
return ctx_dir
|
|
260
290
|
|
|
261
291
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.19.
|
|
1
|
+
0.19.22
|
|
@@ -131,3 +131,11 @@ catalog:
|
|
|
131
131
|
marketplace: claude-plugins-official
|
|
132
132
|
scope: user
|
|
133
133
|
recommended: false
|
|
134
|
+
|
|
135
|
+
- id: superpowers
|
|
136
|
+
name: superpowers
|
|
137
|
+
description: "obra/superpowers — agentic framework with subagent-driven dev, TDD, planning, brainstorm, code review enforced"
|
|
138
|
+
category: workflow
|
|
139
|
+
marketplace: claude-plugins-official
|
|
140
|
+
scope: user
|
|
141
|
+
recommended: true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentikos/omega-os",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.22",
|
|
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"
|