@agentikos/omega-os 0.19.31 → 0.19.33
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/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__/paperclip_bridge.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 +187 -0
- package/omega/Agentik_Engine/omega_engine/paperclip_bridge.py +510 -0
- package/omega/Agentik_Engine/omega_engine/tmux.py +11 -3
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +9 -2
- package/omega/Agentik_SSOT/clis/clis-catalog.yaml +15 -5
- package/omega/Agentik_SSOT/docs/FEATURE-MATRIX.md +193 -0
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2606,6 +2606,88 @@ def cmd_tmux(args: argparse.Namespace) -> int:
|
|
|
2606
2606
|
print(f"no such session: {args.name}")
|
|
2607
2607
|
return 1
|
|
2608
2608
|
|
|
2609
|
+
if sub == "switcher":
|
|
2610
|
+
# v0.19.32 — fzf-based tmux session picker.
|
|
2611
|
+
# Bound to Option+/ in the pro tmux config. Lists ALL live
|
|
2612
|
+
# tmux sessions (Omega, AISB-chat, Hermes-chat, per-project
|
|
2613
|
+
# oracles, workers, ...) with metadata, lets the user pick
|
|
2614
|
+
# one, and switches the client to it.
|
|
2615
|
+
import shlex, shutil, subprocess
|
|
2616
|
+
from omega_engine import __version__
|
|
2617
|
+
if not shutil.which("fzf"):
|
|
2618
|
+
print(" fzf not on PATH — install `brew install fzf` "
|
|
2619
|
+
"or `apt install fzf`")
|
|
2620
|
+
return 2
|
|
2621
|
+
sessions = tmux.list_sessions(home)
|
|
2622
|
+
if not sessions:
|
|
2623
|
+
print(" no tmux sessions yet — type `omega` to spawn the master")
|
|
2624
|
+
return 0
|
|
2625
|
+
sessions.sort(key=lambda s: -int(s.created))
|
|
2626
|
+
|
|
2627
|
+
def _age(ts: int) -> str:
|
|
2628
|
+
import time as _t
|
|
2629
|
+
delta = max(0, int(_t.time()) - int(ts))
|
|
2630
|
+
if delta < 60: return "now"
|
|
2631
|
+
if delta < 3600: return f"{delta // 60}m"
|
|
2632
|
+
if delta < 86400: return f"{delta // 3600}h"
|
|
2633
|
+
return f"{delta // 86400}d"
|
|
2634
|
+
|
|
2635
|
+
ORANGE = "\033[38;2;217;119;87m"
|
|
2636
|
+
MUTED = "\033[38;2;136;131;122m"
|
|
2637
|
+
BOLD = "\033[1m"
|
|
2638
|
+
DIM = "\033[2m"
|
|
2639
|
+
RST = "\033[0m"
|
|
2640
|
+
|
|
2641
|
+
lines = []
|
|
2642
|
+
keys = []
|
|
2643
|
+
for s in sessions:
|
|
2644
|
+
mark = f"{ORANGE}▶{RST}" if s.attached else " "
|
|
2645
|
+
project = f"[{s.project}]" if s.project else ""
|
|
2646
|
+
line = (
|
|
2647
|
+
f" {mark} {BOLD}{s.name:<32}{RST} "
|
|
2648
|
+
f"{DIM}{s.category:<10}{RST} "
|
|
2649
|
+
f"{MUTED}{s.windows}w {_age(s.created):<5}{RST} "
|
|
2650
|
+
f"{DIM}{project}{RST}"
|
|
2651
|
+
)
|
|
2652
|
+
lines.append(line)
|
|
2653
|
+
keys.append(s.name)
|
|
2654
|
+
|
|
2655
|
+
header = (
|
|
2656
|
+
f"{ORANGE}{BOLD}Ω Sessions{RST} "
|
|
2657
|
+
f"{MUTED}• ↑↓ navigate • ↵ switch-client • Esc cancel{RST}"
|
|
2658
|
+
)
|
|
2659
|
+
try:
|
|
2660
|
+
proc = subprocess.run(
|
|
2661
|
+
["fzf", "--ansi", "--no-multi",
|
|
2662
|
+
"--prompt=session › ",
|
|
2663
|
+
f"--header={header}",
|
|
2664
|
+
"--header-first",
|
|
2665
|
+
"--layout=reverse",
|
|
2666
|
+
"--height=60%",
|
|
2667
|
+
"--border=rounded",
|
|
2668
|
+
"--padding=1,2",
|
|
2669
|
+
"--info=hidden",
|
|
2670
|
+
"--pointer=▶",
|
|
2671
|
+
"--color="
|
|
2672
|
+
"bg:#FAFAF7,fg:#3D3929,"
|
|
2673
|
+
"bg+:#E5E2DD,fg+:#D97757,"
|
|
2674
|
+
"hl:#D97757,hl+:#D97757,"
|
|
2675
|
+
"prompt:#D97757,pointer:#D97757,"
|
|
2676
|
+
"header:#88837A,border:#A8A29E,info:#88837A,"
|
|
2677
|
+
"gutter:#FAFAF7"],
|
|
2678
|
+
input="\n".join(lines), capture_output=True, text=True,
|
|
2679
|
+
)
|
|
2680
|
+
except (KeyboardInterrupt, subprocess.SubprocessError):
|
|
2681
|
+
return 0
|
|
2682
|
+
if proc.returncode != 0:
|
|
2683
|
+
return 0
|
|
2684
|
+
pick = proc.stdout.rstrip("\n")
|
|
2685
|
+
for line, name in zip(lines, keys):
|
|
2686
|
+
if line == pick:
|
|
2687
|
+
subprocess.run(["tmux", "switch-client", "-t", name])
|
|
2688
|
+
return 0
|
|
2689
|
+
return 0
|
|
2690
|
+
|
|
2609
2691
|
if sub == "spawn":
|
|
2610
2692
|
kind = args.kind
|
|
2611
2693
|
name = args.name
|
|
@@ -3089,6 +3171,78 @@ def _set_active_provider(provider_id: str) -> None:
|
|
|
3089
3171
|
p.write_text(provider_id.strip() + "\n")
|
|
3090
3172
|
|
|
3091
3173
|
|
|
3174
|
+
def cmd_paperclip(args: argparse.Namespace) -> int:
|
|
3175
|
+
"""`omega paperclip {status,register,sync,start,heartbeat}` — bridge to
|
|
3176
|
+
paperclipai/paperclip (governance layer L0).
|
|
3177
|
+
|
|
3178
|
+
Lets the Paperclip web dashboard see OmegaOS's 14 agents (Hermès + 13
|
|
3179
|
+
AISB suite), every Genesis project as a workspace, and heartbeats
|
|
3180
|
+
from running tmux sessions. Paperclip stays a parallel system — we
|
|
3181
|
+
don't host Paperclip's server; we just write its config files +
|
|
3182
|
+
drop heartbeats it picks up.
|
|
3183
|
+
"""
|
|
3184
|
+
from omega_engine import paperclip_bridge as PB
|
|
3185
|
+
sub = getattr(args, "paperclip_cmd", None) or "status"
|
|
3186
|
+
|
|
3187
|
+
if sub == "status":
|
|
3188
|
+
st = PB.status()
|
|
3189
|
+
print(f" paperclip installed: {'✓' if st.paperclip_installed else '—'}")
|
|
3190
|
+
print(f" paperclip_home: {st.paperclip_home}")
|
|
3191
|
+
print(f" omegaos company: {'✓' if st.company_registered else '—'} "
|
|
3192
|
+
f"{st.company_dir}")
|
|
3193
|
+
print(f" agents registered: {st.agents_registered} / 14")
|
|
3194
|
+
print(f" workspaces: {st.workspaces_registered}")
|
|
3195
|
+
print(f" heartbeats pending: {st.heartbeats_pending}")
|
|
3196
|
+
print(f" bridge_version: {st.bridge_version}")
|
|
3197
|
+
print(f" omega_version: {st.omega_version}")
|
|
3198
|
+
if st.drift:
|
|
3199
|
+
print(f" {st.drift = !r} — run `omega paperclip register` to refresh")
|
|
3200
|
+
if not st.paperclip_installed:
|
|
3201
|
+
print()
|
|
3202
|
+
print(" paperclip not installed — opt-in CLI:")
|
|
3203
|
+
print(" omega tool install paperclipai")
|
|
3204
|
+
print(" omega paperclip register # register OmegaOS company")
|
|
3205
|
+
print(" omega paperclip start # spin up the web dashboard")
|
|
3206
|
+
return 0
|
|
3207
|
+
|
|
3208
|
+
if sub == "register":
|
|
3209
|
+
summary = PB.register(dry_run=getattr(args, "dry_run", False))
|
|
3210
|
+
for k, v in summary.items():
|
|
3211
|
+
print(f" {k}: {v}")
|
|
3212
|
+
return 0
|
|
3213
|
+
|
|
3214
|
+
if sub == "start":
|
|
3215
|
+
bind = getattr(args, "bind", None) or "loopback"
|
|
3216
|
+
try:
|
|
3217
|
+
pid = PB.start_server(bind=bind, detach=True)
|
|
3218
|
+
print(f" paperclip launched (pid {pid}, bind={bind})")
|
|
3219
|
+
print(" default URL: http://localhost:8080 — check Paperclip output")
|
|
3220
|
+
return 0
|
|
3221
|
+
except RuntimeError as exc:
|
|
3222
|
+
print(f" start failed: {exc}")
|
|
3223
|
+
return 2
|
|
3224
|
+
|
|
3225
|
+
if sub == "heartbeat":
|
|
3226
|
+
# Drop a heartbeat from the current shell — used by `dispatch-to-
|
|
3227
|
+
# session.sh` style scripts so Paperclip sees workers come up + report.
|
|
3228
|
+
from omega_engine import paperclip_bridge as PB2
|
|
3229
|
+
hb = PB2.Heartbeat(
|
|
3230
|
+
agent_id=getattr(args, "agent_id", "unknown"),
|
|
3231
|
+
project=getattr(args, "project", ""),
|
|
3232
|
+
session=getattr(args, "session", os.environ.get("TMUX_PANE", "")),
|
|
3233
|
+
status=getattr(args, "status", "alive"),
|
|
3234
|
+
summary=getattr(args, "summary", ""),
|
|
3235
|
+
cost_so_far_usd=float(getattr(args, "cost", 0.0)),
|
|
3236
|
+
omega_home=os.environ.get("OMEGA_HOME", str(Path.home() / "Omega")),
|
|
3237
|
+
)
|
|
3238
|
+
ok = PB2.send_heartbeat(hb)
|
|
3239
|
+
print(f" heartbeat: {'✓' if ok else '✗'} {hb.agent_id} → {hb.status}")
|
|
3240
|
+
return 0 if ok else 1
|
|
3241
|
+
|
|
3242
|
+
print(f"unknown paperclip subcommand: {sub}")
|
|
3243
|
+
return 2
|
|
3244
|
+
|
|
3245
|
+
|
|
3092
3246
|
def cmd_scrape(args: argparse.Namespace) -> int:
|
|
3093
3247
|
"""`omega scrape <url> [--engine cloak|scrapling] [--out file]` — scraper.
|
|
3094
3248
|
|
|
@@ -4371,6 +4525,36 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
4371
4525
|
help="provider id (omit to print current + available)")
|
|
4372
4526
|
p_sw.set_defaults(fn=cmd_switch)
|
|
4373
4527
|
|
|
4528
|
+
# `omega paperclip` — governance bridge to paperclipai/paperclip (L0).
|
|
4529
|
+
p_pc = sub.add_parser(
|
|
4530
|
+
"paperclip",
|
|
4531
|
+
help="bridge to Paperclip governance layer (register OmegaOS as "
|
|
4532
|
+
"a Paperclip company, sync projects, send heartbeats)",
|
|
4533
|
+
)
|
|
4534
|
+
p_pc.set_defaults(fn=cmd_paperclip)
|
|
4535
|
+
pc_sub = p_pc.add_subparsers(dest="paperclip_cmd")
|
|
4536
|
+
pc_sub.add_parser("status", help="show bridge health + counts")
|
|
4537
|
+
p_pcr = pc_sub.add_parser("register",
|
|
4538
|
+
help="write Paperclip company.json + agents/<id>.json + workspaces/")
|
|
4539
|
+
p_pcr.add_argument("--dry-run", action="store_true")
|
|
4540
|
+
p_pcs = pc_sub.add_parser("start",
|
|
4541
|
+
help="launch the Paperclip web dashboard (npx onboard)")
|
|
4542
|
+
p_pcs.add_argument("--bind", choices=["loopback", "lan", "tailnet"],
|
|
4543
|
+
default="loopback")
|
|
4544
|
+
p_pch = pc_sub.add_parser("heartbeat",
|
|
4545
|
+
help="send a heartbeat from a tmux session (script callable)")
|
|
4546
|
+
p_pch.add_argument("--agent-id", required=True,
|
|
4547
|
+
help="hermes / niobe / oracle / construct / …")
|
|
4548
|
+
p_pch.add_argument("--project", default="",
|
|
4549
|
+
help="project slug if applicable")
|
|
4550
|
+
p_pch.add_argument("--session", default="",
|
|
4551
|
+
help="tmux session name (defaults to $TMUX_PANE)")
|
|
4552
|
+
p_pch.add_argument("--status", default="alive",
|
|
4553
|
+
choices=["alive", "working", "done_clean", "failed"])
|
|
4554
|
+
p_pch.add_argument("--summary", default="")
|
|
4555
|
+
p_pch.add_argument("--cost", default="0",
|
|
4556
|
+
help="cost so far in USD (float)")
|
|
4557
|
+
|
|
4374
4558
|
# `omega scrape <url>` — official OmegaOS web scraper (CloakBrowser
|
|
4375
4559
|
# default, Scrapling optional). Both engines pre-installed at step 40
|
|
4376
4560
|
# when their catalog entry is `recommended: true`.
|
|
@@ -4510,6 +4694,9 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
4510
4694
|
p_tcl.add_argument("--yes", action="store_true",
|
|
4511
4695
|
help="apply (default is dry-run)")
|
|
4512
4696
|
tx_sub.add_parser("menu", help="interactive whiptail picker (use under tmux for prefix+Z)")
|
|
4697
|
+
tx_sub.add_parser("switcher",
|
|
4698
|
+
help="fzf session switcher — list all live tmux sessions and "
|
|
4699
|
+
"switch-client to one (bound to Option+/ in the pro config)")
|
|
4513
4700
|
p_tcfg = tx_sub.add_parser("config",
|
|
4514
4701
|
help="write the recommended tmux.conf to Agentik_Tools/")
|
|
4515
4702
|
p_tcfg.add_argument("--profile", choices=["minimal", "pro"],
|
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
"""Paperclip ↔ OmegaOS bridge (v0.19.33).
|
|
2
|
+
|
|
3
|
+
Registers the OmegaOS agent hierarchy (Hermès + 13 AISB suite) as
|
|
4
|
+
Paperclip agents, mirrors Genesis projects into Paperclip workspaces,
|
|
5
|
+
and sends heartbeats from our tmux sessions into Paperclip's wakeup
|
|
6
|
+
queue. After registration, the Paperclip web dashboard surfaces every
|
|
7
|
+
OmegaOS agent / project / mission with its full org-chart + budget +
|
|
8
|
+
audit trail.
|
|
9
|
+
|
|
10
|
+
Layered model after this bridge lands:
|
|
11
|
+
|
|
12
|
+
Layer 0 — PAPERCLIP governance + org-chart + budgets + UI
|
|
13
|
+
(https://paperclip.dev)
|
|
14
|
+
Layer 1 — HUMAN Telegram / TUI / CLI
|
|
15
|
+
Layer 2 — HERMÈS meta-companion (Anthropic API, own bot)
|
|
16
|
+
Layer 3 — AISB (intake) Telegram-first classifier → oracle dispatch
|
|
17
|
+
Layer 4 — ORACLE per-project planner (Claude Max OAuth)
|
|
18
|
+
Layer 5 — WORKERS executors (one per subtask, .done.json)
|
|
19
|
+
|
|
20
|
+
Paperclip surfaces L1–L5 in its dashboard. Hermès still operates on its
|
|
21
|
+
own Anthropic budget; AISB/Oracle/Workers stay on Max OAuth. Paperclip
|
|
22
|
+
sees BOTH credential domains via its "agent bring own runtime" model.
|
|
23
|
+
"""
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import json
|
|
27
|
+
import os
|
|
28
|
+
import shutil
|
|
29
|
+
import subprocess
|
|
30
|
+
import time
|
|
31
|
+
from dataclasses import asdict, dataclass, field
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
from typing import Any
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# ---------------------------------------------------------------------------
|
|
37
|
+
# The OmegaOS canonical agent hierarchy
|
|
38
|
+
# ---------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
# Hermès sits ABOVE AISB in the OmegaOS architecture but reports to no-one
|
|
41
|
+
# inside Paperclip's org chart — it's the "COO" of the company.
|
|
42
|
+
HERMES_AGENT = {
|
|
43
|
+
"id": "hermes",
|
|
44
|
+
"title": "Hermès — Meta-Companion / COO",
|
|
45
|
+
"role": "meta",
|
|
46
|
+
"runtime": "anthropic-api",
|
|
47
|
+
"vault_secret": "ANTHROPIC_API_KEY_HERMES",
|
|
48
|
+
"model_provider": "anthropic",
|
|
49
|
+
"default_model": "claude-opus-4-7",
|
|
50
|
+
"reports_to": None,
|
|
51
|
+
"description": (
|
|
52
|
+
"L2 autonomous companion. Reads Omega state, proposes missions, "
|
|
53
|
+
"dispatches them DOWN into AISB. Runs on its own paid Anthropic "
|
|
54
|
+
"budget — never drains Claude Max."
|
|
55
|
+
),
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# The 13-agent AISB suite — pulled from the canonical
|
|
60
|
+
# bootstrap/templates/aisb/ tree. Each Paperclip agent maps 1:1 with one
|
|
61
|
+
# .md persona file in that tree.
|
|
62
|
+
AISB_AGENTS: list[dict[str, Any]] = [
|
|
63
|
+
{
|
|
64
|
+
"id": "niobe",
|
|
65
|
+
"title": "Niobe — AISB matriarch / intake",
|
|
66
|
+
"role": "intake",
|
|
67
|
+
"reports_to": "hermes",
|
|
68
|
+
"description": (
|
|
69
|
+
"Telegram-first classifier. Reads every inbound message, "
|
|
70
|
+
"decides Simple/Medium/Complex/Epic, dispatches to an oracle "
|
|
71
|
+
"with a structured brief."
|
|
72
|
+
),
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"id": "oracle",
|
|
76
|
+
"title": "Oracle — per-project planner",
|
|
77
|
+
"role": "planner",
|
|
78
|
+
"reports_to": "niobe",
|
|
79
|
+
"description": (
|
|
80
|
+
"Owns project context. Reads the brief + project CLAUDE.md, "
|
|
81
|
+
"decomposes into worker subtasks with verify_cmd, dispatches "
|
|
82
|
+
"and verifies completion."
|
|
83
|
+
),
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"id": "keymaker",
|
|
87
|
+
"title": "Keymaker — system planner / DAG",
|
|
88
|
+
"role": "system-planner",
|
|
89
|
+
"reports_to": "niobe",
|
|
90
|
+
"description": (
|
|
91
|
+
"Cross-project planning. Builds dependency DAGs for multi-"
|
|
92
|
+
"project missions (Genesis features, refonte programs)."
|
|
93
|
+
),
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"id": "construct",
|
|
97
|
+
"title": "Construct — worker executor",
|
|
98
|
+
"role": "worker",
|
|
99
|
+
"reports_to": "oracle",
|
|
100
|
+
"description": (
|
|
101
|
+
"Short-lived. Receives PLAN + FILES IN SCOPE + DONE CRITERIA + "
|
|
102
|
+
"VERIFY COMMAND. Executes step-by-step. Writes .done.json."
|
|
103
|
+
),
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": "seraph",
|
|
107
|
+
"title": "Seraph — quality gate / mission auditor",
|
|
108
|
+
"role": "auditor",
|
|
109
|
+
"reports_to": "niobe",
|
|
110
|
+
"description": (
|
|
111
|
+
"Runs 1–3 Quality Arsenal audits at close-gate. Requires "
|
|
112
|
+
"≥85/100 to approve. Falsifies before approving."
|
|
113
|
+
),
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"id": "smith",
|
|
117
|
+
"title": "Smith — learning + reflection",
|
|
118
|
+
"role": "educator",
|
|
119
|
+
"reports_to": "niobe",
|
|
120
|
+
"description": (
|
|
121
|
+
"Writes lessons (approved missions) + mistakes (rejected ≥2 "
|
|
122
|
+
"retries) to SQLite FTS5 memory. Next workers boot with the "
|
|
123
|
+
"5 most-recent lessons for the project."
|
|
124
|
+
),
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": "link",
|
|
128
|
+
"title": "Link — secure delivery / IO",
|
|
129
|
+
"role": "io",
|
|
130
|
+
"reports_to": "niobe",
|
|
131
|
+
"description": (
|
|
132
|
+
"Handles all outbound (Telegram, email, webhooks) + signed "
|
|
133
|
+
"inbound. HMAC verification, replay window enforcement."
|
|
134
|
+
),
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"id": "merovingian",
|
|
138
|
+
"title": "Merovingian — librarian / RAG",
|
|
139
|
+
"role": "librarian",
|
|
140
|
+
"reports_to": "niobe",
|
|
141
|
+
"description": (
|
|
142
|
+
"Owns the RAG corpus (hybrid + graph + agentic). Surfaces "
|
|
143
|
+
"context to other agents on demand."
|
|
144
|
+
),
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"id": "morpheus",
|
|
148
|
+
"title": "Morpheus — executor coordinator",
|
|
149
|
+
"role": "coordinator",
|
|
150
|
+
"reports_to": "oracle",
|
|
151
|
+
"description": (
|
|
152
|
+
"Orchestrates parallel workers. Dispatches multi-worker waves, "
|
|
153
|
+
"handles concurrency + dependencies + retry."
|
|
154
|
+
),
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "architect",
|
|
158
|
+
"title": "Architect — system design / refactor",
|
|
159
|
+
"role": "architect",
|
|
160
|
+
"reports_to": "oracle",
|
|
161
|
+
"description": (
|
|
162
|
+
"Reads the codebase, finds entities, proposes refactors. "
|
|
163
|
+
"Owns architectural decisions, never executes them directly."
|
|
164
|
+
),
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"id": "neo",
|
|
168
|
+
"title": "Neo — uptime + recovery",
|
|
169
|
+
"role": "ops",
|
|
170
|
+
"reports_to": "niobe",
|
|
171
|
+
"description": (
|
|
172
|
+
"Monitors sessions, resource usage, alert thresholds. "
|
|
173
|
+
"Triggers /resurrect on stall. Never decides — just notifies."
|
|
174
|
+
),
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"id": "pythia",
|
|
178
|
+
"title": "Pythia — watcher / proposals (read-only)",
|
|
179
|
+
"role": "watcher",
|
|
180
|
+
"reports_to": "niobe",
|
|
181
|
+
"description": (
|
|
182
|
+
"Weekly read-only scan of platform docs + GitHub. Produces "
|
|
183
|
+
"gap-analysis proposals. Reports to Architect for triage. "
|
|
184
|
+
"NEVER touches billing/auth scopes."
|
|
185
|
+
),
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"id": "zion",
|
|
189
|
+
"title": "Zion — dashboard / metrics",
|
|
190
|
+
"role": "metrics",
|
|
191
|
+
"reports_to": "niobe",
|
|
192
|
+
"description": (
|
|
193
|
+
"Weekly dashboard generator. Pulls .done.json + audit history "
|
|
194
|
+
"+ session metrics. Produces formatted reports."
|
|
195
|
+
),
|
|
196
|
+
},
|
|
197
|
+
]
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def all_agents() -> list[dict[str, Any]]:
|
|
201
|
+
"""Return Hermès + the 13 AISB suite — 14 agents total."""
|
|
202
|
+
return [HERMES_AGENT] + AISB_AGENTS
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
# ---------------------------------------------------------------------------
|
|
206
|
+
# Paperclip filesystem layout (canonical paths under PAPERCLIP_HOME)
|
|
207
|
+
# ---------------------------------------------------------------------------
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def paperclip_home() -> Path:
|
|
211
|
+
"""Where Paperclip stores its agent configs + DB + secrets.
|
|
212
|
+
|
|
213
|
+
Resolution order:
|
|
214
|
+
1. ``PAPERCLIP_HOME`` env var (operator override)
|
|
215
|
+
2. ``~/.paperclip`` (typical Mac/Linux)
|
|
216
|
+
3. ``$XDG_DATA_HOME/paperclip`` (XDG-conformant Linux)
|
|
217
|
+
"""
|
|
218
|
+
env = os.environ.get("PAPERCLIP_HOME")
|
|
219
|
+
if env:
|
|
220
|
+
return Path(env).expanduser()
|
|
221
|
+
home = Path.home() / ".paperclip"
|
|
222
|
+
return home
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def omegaos_company_dir(home: Path | None = None) -> Path:
|
|
226
|
+
"""Where OmegaOS's company config lives under PAPERCLIP_HOME."""
|
|
227
|
+
base = home or paperclip_home()
|
|
228
|
+
return base / "companies" / "omegaos"
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# ---------------------------------------------------------------------------
|
|
232
|
+
# Heartbeat sender
|
|
233
|
+
# ---------------------------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
@dataclass
|
|
237
|
+
class Heartbeat:
|
|
238
|
+
"""One heartbeat — sent from an OmegaOS tmux session to Paperclip."""
|
|
239
|
+
|
|
240
|
+
agent_id: str # "construct" / "oracle" / "hermes" / …
|
|
241
|
+
project: str # OmegaOS slug
|
|
242
|
+
session: str # tmux session name
|
|
243
|
+
status: str # "alive" | "working" | "done_clean" | "failed"
|
|
244
|
+
summary: str = "" # 1-line description of current work
|
|
245
|
+
timestamp: float = field(default_factory=time.time)
|
|
246
|
+
cost_so_far_usd: float = 0.0
|
|
247
|
+
omega_home: str = ""
|
|
248
|
+
|
|
249
|
+
def to_dict(self) -> dict[str, Any]:
|
|
250
|
+
return asdict(self)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def send_heartbeat(
|
|
254
|
+
hb: Heartbeat,
|
|
255
|
+
*,
|
|
256
|
+
paperclip_url: str = "",
|
|
257
|
+
paperclip_dir: Path | None = None,
|
|
258
|
+
) -> bool:
|
|
259
|
+
"""Send one heartbeat to Paperclip.
|
|
260
|
+
|
|
261
|
+
Two transport modes:
|
|
262
|
+
1. HTTP POST to ``paperclip_url + /api/heartbeat`` when configured
|
|
263
|
+
2. Filesystem drop into
|
|
264
|
+
``$PAPERCLIP_HOME/companies/omegaos/heartbeats/<agent>-<ts>.json``
|
|
265
|
+
when there's no live Paperclip server (offline-friendly).
|
|
266
|
+
|
|
267
|
+
Returns True when the heartbeat was accepted/recorded.
|
|
268
|
+
"""
|
|
269
|
+
payload = hb.to_dict()
|
|
270
|
+
if paperclip_url:
|
|
271
|
+
try:
|
|
272
|
+
import urllib.request as _urllib
|
|
273
|
+
import urllib.error as _ue
|
|
274
|
+
req = _urllib.Request(
|
|
275
|
+
f"{paperclip_url.rstrip('/')}/api/heartbeat",
|
|
276
|
+
data=json.dumps(payload).encode(),
|
|
277
|
+
headers={"Content-Type": "application/json"},
|
|
278
|
+
method="POST",
|
|
279
|
+
)
|
|
280
|
+
with _urllib.urlopen(req, timeout=5): # noqa: S310
|
|
281
|
+
return True
|
|
282
|
+
except _ue.URLError:
|
|
283
|
+
pass
|
|
284
|
+
except Exception: # noqa: BLE001
|
|
285
|
+
pass
|
|
286
|
+
# Filesystem fallback — Paperclip will pick these up on next boot.
|
|
287
|
+
target_dir = (paperclip_dir or omegaos_company_dir()) / "heartbeats"
|
|
288
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
289
|
+
fname = f"{hb.agent_id}-{int(hb.timestamp)}-{os.getpid()}.json"
|
|
290
|
+
(target_dir / fname).write_text(json.dumps(payload, indent=2))
|
|
291
|
+
return True
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
# ---------------------------------------------------------------------------
|
|
295
|
+
# Registration — write Paperclip's agent + company config from OmegaOS
|
|
296
|
+
# ---------------------------------------------------------------------------
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def register(*,
|
|
300
|
+
omega_home: Path | str | None = None,
|
|
301
|
+
paperclip_dir: Path | None = None,
|
|
302
|
+
dry_run: bool = False) -> dict[str, Any]:
|
|
303
|
+
"""Idempotently write Paperclip's `companies/omegaos/` tree from
|
|
304
|
+
the OmegaOS state.
|
|
305
|
+
|
|
306
|
+
Writes:
|
|
307
|
+
$PAPERCLIP_HOME/companies/omegaos/company.json ← top-level config
|
|
308
|
+
$PAPERCLIP_HOME/companies/omegaos/agents/<id>.json ← per-agent (14 files)
|
|
309
|
+
$PAPERCLIP_HOME/companies/omegaos/workspaces/<slug>.json ← per-project
|
|
310
|
+
$PAPERCLIP_HOME/companies/omegaos/.bridge-version ← versioning marker
|
|
311
|
+
|
|
312
|
+
Returns a summary dict for the caller (and the omega CLI).
|
|
313
|
+
"""
|
|
314
|
+
home = Path(omega_home) if omega_home else Path(
|
|
315
|
+
os.environ.get("OMEGA_HOME", str(Path.home() / "Omega"))
|
|
316
|
+
)
|
|
317
|
+
pdir = paperclip_dir or omegaos_company_dir()
|
|
318
|
+
summary = {
|
|
319
|
+
"company": "omegaos",
|
|
320
|
+
"paperclip_home": str(pdir.parent.parent),
|
|
321
|
+
"company_dir": str(pdir),
|
|
322
|
+
"agents_written": 0,
|
|
323
|
+
"workspaces_written": 0,
|
|
324
|
+
"dry_run": dry_run,
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
agents = all_agents()
|
|
328
|
+
workspaces = _discover_projects(home)
|
|
329
|
+
|
|
330
|
+
if not dry_run:
|
|
331
|
+
pdir.mkdir(parents=True, exist_ok=True)
|
|
332
|
+
(pdir / "agents").mkdir(exist_ok=True)
|
|
333
|
+
(pdir / "workspaces").mkdir(exist_ok=True)
|
|
334
|
+
(pdir / "heartbeats").mkdir(exist_ok=True)
|
|
335
|
+
|
|
336
|
+
# company.json — the master config
|
|
337
|
+
company = {
|
|
338
|
+
"id": "omegaos",
|
|
339
|
+
"name": "Omega OS",
|
|
340
|
+
"tagline": (
|
|
341
|
+
"Verified-completion agentic operating system. "
|
|
342
|
+
"Hermès above, AISB intake, Oracle plans, Workers execute."
|
|
343
|
+
),
|
|
344
|
+
"homepage": "https://github.com/agentik-os/OmegaOS",
|
|
345
|
+
"credential_domains": [
|
|
346
|
+
{
|
|
347
|
+
"id": "claude-max-oauth",
|
|
348
|
+
"label": "Claude Max OAuth (AISB+Oracle+Workers)",
|
|
349
|
+
"source": "~/.claude/.credentials.json",
|
|
350
|
+
"cost_per_call": 0.0,
|
|
351
|
+
"notes": "OAuth token for Claude Code Max — covered by sub",
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
"id": "anthropic-api-hermes",
|
|
355
|
+
"label": "Anthropic API (Hermès only)",
|
|
356
|
+
"vault_ref": "ANTHROPIC_API_KEY_HERMES",
|
|
357
|
+
"notes": "Hermès's own paid budget, isolated from Max",
|
|
358
|
+
},
|
|
359
|
+
],
|
|
360
|
+
"verified_completion": {
|
|
361
|
+
"signal": ".done.json",
|
|
362
|
+
"status_values": ["done_clean", "pending", "failed"],
|
|
363
|
+
"audit_gate": "Seraph runs 1-3 Quality Arsenal audits ≥85/100",
|
|
364
|
+
},
|
|
365
|
+
"agent_count": len(agents),
|
|
366
|
+
"workspace_count": len(workspaces),
|
|
367
|
+
"bridge_version": _bridge_version(),
|
|
368
|
+
"registered_at": time.time(),
|
|
369
|
+
}
|
|
370
|
+
(pdir / "company.json").write_text(json.dumps(company, indent=2) + "\n")
|
|
371
|
+
|
|
372
|
+
# Per-agent files
|
|
373
|
+
for agent in agents:
|
|
374
|
+
(pdir / "agents" / f"{agent['id']}.json").write_text(
|
|
375
|
+
json.dumps(agent, indent=2) + "\n"
|
|
376
|
+
)
|
|
377
|
+
summary["agents_written"] += 1
|
|
378
|
+
|
|
379
|
+
# Per-workspace (project) files
|
|
380
|
+
for ws in workspaces:
|
|
381
|
+
(pdir / "workspaces" / f"{ws['slug']}.json").write_text(
|
|
382
|
+
json.dumps(ws, indent=2) + "\n"
|
|
383
|
+
)
|
|
384
|
+
summary["workspaces_written"] += 1
|
|
385
|
+
|
|
386
|
+
# Bridge version marker
|
|
387
|
+
(pdir / ".bridge-version").write_text(_bridge_version() + "\n")
|
|
388
|
+
else:
|
|
389
|
+
summary["agents_written"] = len(agents)
|
|
390
|
+
summary["workspaces_written"] = len(workspaces)
|
|
391
|
+
|
|
392
|
+
return summary
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def _bridge_version() -> str:
|
|
396
|
+
"""Pin to the OmegaOS engine version that wrote the bridge config."""
|
|
397
|
+
try:
|
|
398
|
+
from omega_engine import __version__
|
|
399
|
+
return __version__
|
|
400
|
+
except ImportError:
|
|
401
|
+
return "unknown"
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
def _discover_projects(omega_home: Path) -> list[dict[str, Any]]:
|
|
405
|
+
"""Walk Agentik_Coding/projects/<slug>/ and return Paperclip-shape
|
|
406
|
+
workspace dicts."""
|
|
407
|
+
projects_root = omega_home / "Agentik_Coding" / "projects"
|
|
408
|
+
out: list[dict[str, Any]] = []
|
|
409
|
+
if not projects_root.is_dir():
|
|
410
|
+
return out
|
|
411
|
+
for entry in sorted(projects_root.iterdir()):
|
|
412
|
+
if not entry.is_dir():
|
|
413
|
+
continue
|
|
414
|
+
slug = entry.name
|
|
415
|
+
project_yaml = entry / "PROJECT.yaml"
|
|
416
|
+
meta: dict[str, Any] = {"slug": slug, "path": str(entry)}
|
|
417
|
+
if project_yaml.exists():
|
|
418
|
+
try:
|
|
419
|
+
import yaml as _yaml
|
|
420
|
+
meta.update(_yaml.safe_load(project_yaml.read_text()) or {})
|
|
421
|
+
except Exception: # noqa: BLE001
|
|
422
|
+
pass
|
|
423
|
+
# Paperclip "workspace" shape
|
|
424
|
+
out.append({
|
|
425
|
+
"id": slug,
|
|
426
|
+
"slug": slug,
|
|
427
|
+
"title": meta.get("title") or slug,
|
|
428
|
+
"phase": meta.get("phase") or "unknown",
|
|
429
|
+
"stack": meta.get("stack") or {},
|
|
430
|
+
"path": str(entry),
|
|
431
|
+
"registered_at": time.time(),
|
|
432
|
+
})
|
|
433
|
+
return out
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
# ---------------------------------------------------------------------------
|
|
437
|
+
# Status — does Paperclip know about OmegaOS, and how fresh?
|
|
438
|
+
# ---------------------------------------------------------------------------
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
@dataclass
|
|
442
|
+
class BridgeStatus:
|
|
443
|
+
paperclip_installed: bool
|
|
444
|
+
paperclip_home: str
|
|
445
|
+
company_dir: str
|
|
446
|
+
company_registered: bool
|
|
447
|
+
bridge_version: str
|
|
448
|
+
omega_version: str
|
|
449
|
+
agents_registered: int
|
|
450
|
+
workspaces_registered: int
|
|
451
|
+
heartbeats_pending: int
|
|
452
|
+
drift: bool # bridge_version != omega_version
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def status() -> BridgeStatus:
|
|
456
|
+
"""Return current bridge state — used by `omega paperclip status` +
|
|
457
|
+
`omega doctor`."""
|
|
458
|
+
pdir = omegaos_company_dir()
|
|
459
|
+
binary_present = bool(shutil.which("paperclip"))
|
|
460
|
+
bridge_v = ""
|
|
461
|
+
omega_v = _bridge_version()
|
|
462
|
+
company_present = (pdir / "company.json").exists()
|
|
463
|
+
agents_n = len(list((pdir / "agents").glob("*.json"))) if pdir.exists() else 0
|
|
464
|
+
workspaces_n = (
|
|
465
|
+
len(list((pdir / "workspaces").glob("*.json"))) if pdir.exists() else 0
|
|
466
|
+
)
|
|
467
|
+
heartbeats_n = (
|
|
468
|
+
len(list((pdir / "heartbeats").glob("*.json"))) if pdir.exists() else 0
|
|
469
|
+
)
|
|
470
|
+
if (pdir / ".bridge-version").exists():
|
|
471
|
+
bridge_v = (pdir / ".bridge-version").read_text().strip()
|
|
472
|
+
return BridgeStatus(
|
|
473
|
+
paperclip_installed=binary_present,
|
|
474
|
+
paperclip_home=str(paperclip_home()),
|
|
475
|
+
company_dir=str(pdir),
|
|
476
|
+
company_registered=company_present,
|
|
477
|
+
bridge_version=bridge_v or "(not yet registered)",
|
|
478
|
+
omega_version=omega_v,
|
|
479
|
+
agents_registered=agents_n,
|
|
480
|
+
workspaces_registered=workspaces_n,
|
|
481
|
+
heartbeats_pending=heartbeats_n,
|
|
482
|
+
drift=bool(bridge_v) and bridge_v != omega_v,
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
# ---------------------------------------------------------------------------
|
|
487
|
+
# Paperclip server lifecycle (start/stop the npx onboard process)
|
|
488
|
+
# ---------------------------------------------------------------------------
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
def start_server(bind: str = "loopback", *, detach: bool = True) -> int:
|
|
492
|
+
"""Launch the Paperclip onboard server.
|
|
493
|
+
|
|
494
|
+
bind ∈ {"loopback", "lan", "tailnet"}.
|
|
495
|
+
Returns the PID (or 0 if synchronous run requested via detach=False).
|
|
496
|
+
"""
|
|
497
|
+
if not shutil.which("npx"):
|
|
498
|
+
raise RuntimeError("npx not on PATH — install Node 20+")
|
|
499
|
+
args = ["npx", "-y", "paperclipai", "onboard", "--yes"]
|
|
500
|
+
if bind == "lan":
|
|
501
|
+
args += ["--bind", "lan"]
|
|
502
|
+
elif bind == "tailnet":
|
|
503
|
+
args += ["--bind", "tailnet"]
|
|
504
|
+
if detach:
|
|
505
|
+
proc = subprocess.Popen( # noqa: S603
|
|
506
|
+
args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
|
507
|
+
start_new_session=True,
|
|
508
|
+
)
|
|
509
|
+
return proc.pid
|
|
510
|
+
return subprocess.call(args)
|
|
@@ -572,9 +572,10 @@ bind-key Z display-popup -E -w 80% -h 80% "omega tmux menu"
|
|
|
572
572
|
# Prefix+S — native session list (tmux's built-in choose-tree)
|
|
573
573
|
bind-key S choose-tree -Zs
|
|
574
574
|
|
|
575
|
-
#
|
|
575
|
+
# Option+/ → session switcher (fzf popup, pick any live tmux session)
|
|
576
|
+
# Option+z → Omega action menu (spawn Omega if missing + switch-client)
|
|
576
577
|
# macOS Option key → enable "Use Option as Meta" in your terminal.
|
|
577
|
-
bind-key -n M-/
|
|
578
|
+
bind-key -n M-/ display-popup -E -h 80% -w 90% "omega tmux switcher"
|
|
578
579
|
bind-key -n M-z run-shell -b "tmux has-session -t Omega 2>/dev/null || tmux new-session -d -s Omega -n menu -c $HOME 'omega menu-tui'; tmux switch-client -t Omega"
|
|
579
580
|
|
|
580
581
|
# ════════════════════════════════════════════════════════════════════
|
|
@@ -686,7 +687,14 @@ bind-key r source-file ~/.tmux.conf \\; display-message "tmux.conf reloaded"
|
|
|
686
687
|
# IMPORTANT — for Option key to work on macOS terminals, enable
|
|
687
688
|
# "Use Option as Meta key" (iTerm2: Profile → Keys → Left/Right Option
|
|
688
689
|
# Key → Esc+). Otherwise the binding stays inactive.
|
|
689
|
-
|
|
690
|
+
# ────────────────────────────────────────────────────────────────────
|
|
691
|
+
# Option+/ → SESSION SWITCHER (fzf — pick any live tmux session)
|
|
692
|
+
# Option+z → OMEGA ACTION MENU (the v0.19.30 fzf menu of actions)
|
|
693
|
+
# ────────────────────────────────────────────────────────────────────
|
|
694
|
+
# popup -E runs the command in a tmux popup overlay (modal). The popup
|
|
695
|
+
# closes when the command exits, returning the user to their previous
|
|
696
|
+
# pane. -h 80% / -w 90% sizes the popup.
|
|
697
|
+
bind-key -n M-/ display-popup -E -h 80% -w 90% "omega tmux switcher"
|
|
690
698
|
bind-key -n M-z run-shell -b "tmux has-session -t Omega 2>/dev/null || tmux new-session -d -s Omega -n menu -c $HOME 'omega menu-tui'; tmux switch-client -t Omega"
|
|
691
699
|
|
|
692
700
|
# ════════════════════════════════════════════════════════════════════
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.19.
|
|
1
|
+
0.19.33
|
|
@@ -53,11 +53,18 @@ catalog:
|
|
|
53
53
|
|
|
54
54
|
- id: claude-mem
|
|
55
55
|
name: claude-mem
|
|
56
|
-
description:
|
|
56
|
+
description: |
|
|
57
|
+
Long-term memory + observation system across sessions.
|
|
58
|
+
KNOWN ISSUE (2026-05-25): claude-mem 13.3.0 ships a stop-hook
|
|
59
|
+
worker-service.cjs that imports `zod/v3` (doesn't exist in zod 4+).
|
|
60
|
+
Under Bun the hook crashes with "Cannot find module 'zod/v3'". The
|
|
61
|
+
plugin still installs — only the stop hook breaks.
|
|
62
|
+
Marked opt-in until upstream fixes. Install manually with:
|
|
63
|
+
claude plugin install claude-mem@thedotmack
|
|
57
64
|
category: memory
|
|
58
65
|
marketplace: thedotmack
|
|
59
66
|
scope: user
|
|
60
|
-
recommended:
|
|
67
|
+
recommended: false
|
|
61
68
|
|
|
62
69
|
- id: frontend-design
|
|
63
70
|
name: frontend-design
|
|
@@ -76,11 +76,21 @@ native:
|
|
|
76
76
|
|
|
77
77
|
- id: paperclipai
|
|
78
78
|
name: Paperclip (orchestration UI — agent teams, org charts, governance)
|
|
79
|
-
# Node.js + React app from paperclipai/paperclip.
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
79
|
+
# Node.js + React app from paperclipai/paperclip.
|
|
80
|
+
#
|
|
81
|
+
# STATUS (v0.19.32) — honest disclosure:
|
|
82
|
+
# - The binary installs cleanly (`npx -y paperclipai onboard --yes`).
|
|
83
|
+
# - There is NO native OmegaOS↔Paperclip bridge yet. Paperclip's
|
|
84
|
+
# own docs list Claude Code, Codex, Cursor, OpenClaw — Hermès is
|
|
85
|
+
# NOT in their supported-agents list, and OmegaOS isn't either.
|
|
86
|
+
# - To make Paperclip "understand" our agents I'd need to:
|
|
87
|
+
# a) Write a Paperclip agent profile pointing at omega's
|
|
88
|
+
# claude/hermes subprocess invocations
|
|
89
|
+
# b) Add a heartbeat sender from our tmux sessions
|
|
90
|
+
# c) Map Paperclip's org-chart concepts to our 4-level model
|
|
91
|
+
# That's real work, scheduled for v0.20.x — not done yet.
|
|
92
|
+
# For now: install it if you want the standalone Paperclip UI, but
|
|
93
|
+
# treat it as a parallel system, not an OmegaOS bridge.
|
|
84
94
|
install: { npm_global: "paperclipai" }
|
|
85
95
|
binary: paperclip
|
|
86
96
|
secrets: []
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# OmegaOS × Paperclip Feature Matrix (v0.19.33)
|
|
2
|
+
|
|
3
|
+
> Cross-reference between OmegaOS (engine + AISB suite + tooling) and
|
|
4
|
+
> Paperclip (governance + org-chart + UI). Identifies what each system
|
|
5
|
+
> uniquely brings, where they overlap, and what the bridge fills in.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Paperclip — feature inventory
|
|
10
|
+
|
|
11
|
+
| # | Feature | What it does | Maps to OmegaOS as |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| 1 | **Org chart & agents** | Roles, titles, reporting lines, JDs | OmegaOS hierarchy (Hermès / AISB suite) registered as Paperclip agents via `omega paperclip register` |
|
|
14
|
+
| 2 | **Issue-based tasks** | Atomic checkout, dependencies, comments, audit logs | OmegaOS missions (`omega run`) + `.done.json` events |
|
|
15
|
+
| 3 | **Heartbeat execution** | Scheduled wakeups, budget checks, secret injection | `omega paperclip heartbeat --agent-id <…>` from tmux sessions |
|
|
16
|
+
| 4 | **Goal alignment** | Task → project → company → mission | OmegaOS Genesis project YAML carries `purpose` field |
|
|
17
|
+
| 5 | **Budget & cost** | Token/USD per agent/provider/model, hard stops | Per-LLM-provider tracking (claude_code = $0 OAuth; hermes = paid Anthropic; OpenRouter = OpenRouter API) |
|
|
18
|
+
| 6 | **Governance / approvals** | Board review, pause/terminate, config versioning | Maps to Stop-hook audit gate (Seraph ≥85/100 score) |
|
|
19
|
+
| 7 | **Workspaces** | Project workspaces, git worktrees, dev servers | OmegaOS `Agentik_Coding/projects/<slug>/` per-project isolation |
|
|
20
|
+
| 8 | **Routines / schedules** | Cron, webhook, API triggers | OmegaOS autonomous charters in `Agentik_Orchestration/autonomous/` |
|
|
21
|
+
| 9 | **Plugin system** | Instance-wide extensibility | OmegaOS skill catalog (`Agentik_SSOT/skills/`) |
|
|
22
|
+
| 10 | **Secrets storage** | Encrypted local + provider-backed | OmegaOS age vault (`omega vault`) |
|
|
23
|
+
| 11 | **Activity events** | Durable audit log | OmegaOS `Agentik_Runtime/eventlog/omega.db` |
|
|
24
|
+
| 12 | **Company portability** | Export/import org with secret scrubbing | OmegaOS Genesis pipeline + manifest YAML |
|
|
25
|
+
| 13 | **Multi-company support** | One deployment, many tenants | Multi-project under one `~/Omega` |
|
|
26
|
+
| 14 | **Mobile-ready management** | Browser UI for phones | OmegaOS Telegram bot (less rich but works) |
|
|
27
|
+
| 15 | **Web dashboard (React)** | Visual governance UI | Not in OmegaOS — fixed by registering OmegaOS as a Paperclip company |
|
|
28
|
+
| 16 | **PostgreSQL backend** | Production DB | OmegaOS uses SQLite WAL per project (simpler but smaller scale) |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 2. OmegaOS — feature inventory
|
|
33
|
+
|
|
34
|
+
| # | Feature | What it does | Maps to Paperclip as |
|
|
35
|
+
|---|---|---|---|
|
|
36
|
+
| 1 | **AISB suite (13 agents)** | Niobe/Oracle/Construct/Seraph/Smith/… | 13 agent rows in Paperclip's org chart |
|
|
37
|
+
| 2 | **Hermès L2** | Meta-companion on Anthropic API | Top-of-chart "COO" agent in Paperclip (own credential domain) |
|
|
38
|
+
| 3 | **Genesis project pipeline** | vision→market→branding→PRD→features→plan | Workspace template in Paperclip |
|
|
39
|
+
| 4 | **Verified completion (`.done.json`)** | Worker status signal | Issue completion event with payload |
|
|
40
|
+
| 5 | **17 Quality Arsenal audits** | Forensic Gestalt-Popper audits | Approval workflow stages |
|
|
41
|
+
| 6 | **Plan v7 FSM-enforced executor** | Multi-day autonomous loop | Routines with state machine |
|
|
42
|
+
| 7 | **Claude Code Max OAuth** | Free-with-sub credential | Provider config (credential domain 1) |
|
|
43
|
+
| 8 | **Hermès Anthropic API key** | Isolated paid budget | Provider config (credential domain 2) |
|
|
44
|
+
| 9 | **13 LLM CLIs + hot-swap** | Claude/Gemini/Codex/OpenCode/Qwen/… | Agent runtime flexibility (each agent picks its CLI) |
|
|
45
|
+
| 10 | **16 provider configs** | Anthropic/OpenAI/Google/GLM/DeepSeek/Qwen/Ollama/LM Studio/OpenRouter/Bedrock/Mistral/xAI/Vercel Gateway/Copilot | Multi-provider routing |
|
|
46
|
+
| 11 | **Persona system** | 1 canonical → 10 LLM filenames | Agent prompt portability |
|
|
47
|
+
| 12 | **CloakBrowser scraper** | Stealth web scraping | Available to all Paperclip agents via `omega scrape` |
|
|
48
|
+
| 13 | **Scrapling scraper** | Fast HTTP-first scraping | Same |
|
|
49
|
+
| 14 | **Printing Press CLIs** | Agent-native CLIs (Stripe, Linear, …) | Same — available to all agents |
|
|
50
|
+
| 15 | **Tmux session orchestration** | Persistent sessions for oracles/workers | Workspace runtime backing |
|
|
51
|
+
| 16 | **`omega` TUI** | fzf arrow menu + slash REPL | Terminal-side control surface |
|
|
52
|
+
| 17 | **Telegram bot (AISB)** | Intake + dispatch | Mobile management surface |
|
|
53
|
+
| 18 | **age-encrypted vault** | Secrets storage | Maps to Paperclip's secrets store |
|
|
54
|
+
| 19 | **Autonomous charters** | Cron-driven agent triggers | Paperclip routines |
|
|
55
|
+
| 20 | **Event-sourced FSM** | Per-task state machine | Issue lifecycle in Paperclip |
|
|
56
|
+
| 21 | **`omega switch`** | Hot-swap LLM provider | Per-agent runtime change |
|
|
57
|
+
| 22 | **`omega scrape`** | Unified scraper interface | Tool surface for all agents |
|
|
58
|
+
| 23 | **`omega doctor`** | 30+ health checks | Paperclip dashboard's health view |
|
|
59
|
+
| 24 | **599 pytest tests** | Engine correctness | (Paperclip has its own test suite) |
|
|
60
|
+
| 25 | **Distributable via npm** | `npx @agentikos/omega-os@latest` | Single npm package, multi-platform |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 3. Merger — the bridge fills these gaps
|
|
65
|
+
|
|
66
|
+
What OmegaOS WAS MISSING and Paperclip provides:
|
|
67
|
+
|
|
68
|
+
| OmegaOS gap | Paperclip fills it |
|
|
69
|
+
|---|---|
|
|
70
|
+
| No visual dashboard | Paperclip's React UI surfaces all 14 agents + projects + missions |
|
|
71
|
+
| Per-agent budget enforcement | Paperclip's budget engine (we report; Paperclip enforces) |
|
|
72
|
+
| Cross-LLM cost transparency | Paperclip's per-provider token tracking |
|
|
73
|
+
| Board-level approvals (beyond audit gate) | Paperclip's approval workflows |
|
|
74
|
+
| Company portability with secret scrubbing | Paperclip's export/import |
|
|
75
|
+
|
|
76
|
+
What Paperclip WAS MISSING and OmegaOS provides:
|
|
77
|
+
|
|
78
|
+
| Paperclip gap | OmegaOS fills it |
|
|
79
|
+
|---|---|
|
|
80
|
+
| 13 AISB agent personas | Paperclip company "omegaos" auto-registers them via bridge |
|
|
81
|
+
| Hermès L2 meta-companion | New agent role in Paperclip's chart |
|
|
82
|
+
| Verified-completion contract | OmegaOS's `.done.json` → Paperclip issue close event |
|
|
83
|
+
| Quality Arsenal audits (17 forensic) | Available to all Paperclip agents via `omega audit <id>` |
|
|
84
|
+
| Stealth scraping (CloakBrowser + Scrapling) | Available via `omega scrape <url>` |
|
|
85
|
+
| Hot-swap LLM mid-flight | `omega switch` from any Paperclip agent's runtime |
|
|
86
|
+
| Genesis project pipeline | Stack-aware workspace bootstrap |
|
|
87
|
+
| Age-encrypted vault | More secure than Paperclip's bare encrypted-local |
|
|
88
|
+
| 21-step installer with plan mode | One-line distribution beyond Paperclip's `npx onboard` |
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 4. Bridge layer (v0.19.33 ship)
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
96
|
+
│ PAPERCLIP — L0 governance (React UI, web dashboard) │
|
|
97
|
+
│ $PAPERCLIP_HOME/companies/omegaos/ │
|
|
98
|
+
│ ├── company.json ← OmegaOS company config │
|
|
99
|
+
│ ├── agents/<id>.json ← 14 agent profiles │
|
|
100
|
+
│ ├── workspaces/<slug>.json ← per-Genesis-project workspace │
|
|
101
|
+
│ └── heartbeats/*.json ← live status from tmux sessions │
|
|
102
|
+
└────────────────────────────────┬─────────────────────────────────┘
|
|
103
|
+
│
|
|
104
|
+
OmegaOS engine writes here via:
|
|
105
|
+
`omega paperclip register`
|
|
106
|
+
`omega paperclip sync`
|
|
107
|
+
`omega paperclip heartbeat`
|
|
108
|
+
│
|
|
109
|
+
┌────────────────────────────────▼─────────────────────────────────┐
|
|
110
|
+
│ OMEGAOS — L1-L5 execution │
|
|
111
|
+
│ Hermès (L2) → AISB (L3) → Oracle (L4) → Workers (L5) │
|
|
112
|
+
│ Engine: ~/Omega/Agentik_Engine/omega_engine/ │
|
|
113
|
+
│ State: ~/Omega/Agentik_Runtime/ │
|
|
114
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## 5. Bridge commands (v0.19.33)
|
|
118
|
+
|
|
119
|
+
| Command | Effect |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `omega paperclip status` | Show bridge health (agents/workspaces/heartbeats count, version drift) |
|
|
122
|
+
| `omega paperclip register` | Write Paperclip company config (idempotent) |
|
|
123
|
+
| `omega paperclip register --dry-run` | Preview without writing |
|
|
124
|
+
| `omega paperclip start [--bind loopback\|lan\|tailnet]` | Launch Paperclip server via `npx onboard` |
|
|
125
|
+
| `omega paperclip heartbeat --agent-id <id> --status <s>` | Send heartbeat from any tmux session |
|
|
126
|
+
|
|
127
|
+
## 6. Features added to OmegaOS in v0.19.33
|
|
128
|
+
|
|
129
|
+
1. `omega_engine.paperclip_bridge` module (this file).
|
|
130
|
+
2. `omega paperclip` CLI subcommand (4 verbs).
|
|
131
|
+
3. Per-agent profiles for the 13 AISB suite + Hermès, ready to be
|
|
132
|
+
written into Paperclip's `companies/omegaos/agents/` directory.
|
|
133
|
+
4. Workspace discovery — reads `Agentik_Coding/projects/<slug>/PROJECT.yaml`,
|
|
134
|
+
maps each to a Paperclip workspace.
|
|
135
|
+
|
|
136
|
+
## 7. Features still to add (v0.19.34+)
|
|
137
|
+
|
|
138
|
+
1. **Heartbeat sender wired into spawn**: `tmux.spawn_worker()` and
|
|
139
|
+
`tmux.spawn_oracle()` should auto-call `omega paperclip heartbeat
|
|
140
|
+
--agent-id <id> --status alive` on spawn + on exit.
|
|
141
|
+
2. **Per-agent budget enforcement in OmegaOS** mirroring Paperclip's
|
|
142
|
+
limits — read the budget config back from Paperclip and refuse new
|
|
143
|
+
missions when over budget.
|
|
144
|
+
3. **Genesis stack option: "paperclip-managed"** — generates a
|
|
145
|
+
Paperclip company.json at project creation time alongside PROJECT.yaml.
|
|
146
|
+
4. **`omega paperclip import <export.tar.gz>`** — adopt an OmegaOS
|
|
147
|
+
project from a Paperclip company export.
|
|
148
|
+
5. **Heartbeat HTTP transport** — currently writes JSON to disk
|
|
149
|
+
(filesystem fallback). Add live POST to a running Paperclip server
|
|
150
|
+
when the URL is set.
|
|
151
|
+
6. **AISB suite registration depth**: per-agent skills/tools mapping
|
|
152
|
+
so Paperclip's dashboard shows which Quality Arsenal audits Seraph
|
|
153
|
+
owns, which providers Hermès uses, etc.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 8. AISB rules enforced across both systems
|
|
158
|
+
|
|
159
|
+
These are non-negotiable contracts that both OmegaOS code AND
|
|
160
|
+
Paperclip config must respect:
|
|
161
|
+
|
|
162
|
+
1. **14 agents total** (Hermès + 13 AISB suite). The bridge writes
|
|
163
|
+
exactly 14 agent profiles — no more, no less.
|
|
164
|
+
2. **Reporting lines fixed**:
|
|
165
|
+
- Hermès reports to nobody (top)
|
|
166
|
+
- Niobe reports to Hermès (intake matriarch)
|
|
167
|
+
- Oracle/Keymaker/Seraph/Smith/Link/Merovingian/Neo/Pythia/Zion
|
|
168
|
+
report to Niobe (specialists)
|
|
169
|
+
- Construct/Morpheus/Architect report to Oracle (per-project execution)
|
|
170
|
+
3. **Credential domain isolation**:
|
|
171
|
+
- Claude Max OAuth → AISB+Oracle+Workers only (L3-L5)
|
|
172
|
+
- Anthropic API → Hermès only (L2)
|
|
173
|
+
- Paperclip never sees the live tokens, only credential domain refs
|
|
174
|
+
4. **Verified completion contract**:
|
|
175
|
+
- Every Worker writes `.done.json` with `status ∈ {done_clean, pending, failed}`
|
|
176
|
+
- Oracle waits for ALL its workers' `.done.json` before its own
|
|
177
|
+
- Seraph runs 1-3 Quality Arsenal audits with score ≥85/100 to approve
|
|
178
|
+
- Paperclip's issue close event mirrors this state
|
|
179
|
+
5. **Plans are first-class**:
|
|
180
|
+
- Oracle writes `plan.md` in `/project/<slug>/` before dispatching
|
|
181
|
+
- Workers receive PLAN + FILES IN SCOPE + DONE CRITERIA + VERIFY COMMAND
|
|
182
|
+
- Plan deviation = audit gate FAIL
|
|
183
|
+
|
|
184
|
+
These rules are baked into:
|
|
185
|
+
- `omega_engine.envelope` (mission envelope builder)
|
|
186
|
+
- `omega_engine.audit_arsenal` (audit gate)
|
|
187
|
+
- `omega_engine.paperclip_bridge.AISB_AGENTS` (this file's catalog)
|
|
188
|
+
- `Agentik_SSOT/agents/aisb/CLAUDE.md` (master prompt)
|
|
189
|
+
- `Agentik_SSOT/personas/OMEGAOS-CONTEXT.md` (per-LLM context)
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
*Audit produit pour v0.19.33 — 2026-05-25.*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentikos/omega-os",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.33",
|
|
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"
|