@ngockhoale/ukit 2.1.5 → 2.2.2

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 (41) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +7 -4
  3. package/manifests/platform.full.yaml +121 -24
  4. package/package.json +4 -3
  5. package/src/cli/adapters.js +47 -21
  6. package/src/cli/index.js +2 -2
  7. package/src/core/applyPlan.js +5 -2
  8. package/src/core/ensureGitignore.js +2 -0
  9. package/src/core/runInstallPipeline.js +19 -0
  10. package/src/core/runtimeConfig.js +6 -1
  11. package/src/core/status.js +3 -1
  12. package/src/core/uninstall.js +16 -0
  13. package/src/index/routeCatalog.js +1 -1
  14. package/src/manifest/selectItems.js +11 -5
  15. package/templates/.claude/commands/ukit/handoff-clear.md +1 -1
  16. package/templates/.claude/commands/ukit/handoff-create.md +10 -8
  17. package/templates/.claude/commands/ukit/handoff-fullstack.md +22 -18
  18. package/templates/.claude/commands/ukit/handoff-implement.md +6 -4
  19. package/templates/.claude/commands/ukit/handoff-review.md +5 -3
  20. package/templates/.claude/commands/ukit/handoff-status.md +1 -1
  21. package/templates/.claude/ukit/index/route-catalog.mjs +1 -1
  22. package/templates/.claude/ukit/index/unic-gateway.mjs +43 -7
  23. package/templates/.codex/README.md +1 -1
  24. package/templates/.gitignore +2 -0
  25. package/templates/.omp/AGENTS.md +9 -0
  26. package/templates/.omp/README.md +96 -0
  27. package/templates/.omp/RULES.md +62 -0
  28. package/templates/.omp/agents/bug-debugger.md +85 -0
  29. package/templates/.omp/agents/code-reviewer.md +197 -0
  30. package/templates/.omp/agents/feature-implementer.md +123 -0
  31. package/templates/.omp/agents/handoff-planner.md +210 -0
  32. package/templates/.omp/agents/ukit-small-task-maintainer.md +72 -0
  33. package/templates/.omp/agents/ukit-vision-analyst.md +100 -0
  34. package/templates/.omp/config.yml +90 -0
  35. package/templates/.omp/hooks/pre/ukit-bridge.js +368 -0
  36. package/templates/AGENTS.md +132 -64
  37. package/templates/CLAUDE.md +59 -21
  38. package/templates/docs/PROJECT.md +1 -1
  39. package/templates/ukit/storage/config.json +10 -0
  40. package/templates/adapter-presets/antigravity/README.md +0 -22
  41. package/templates/adapter-presets/antigravity/rules.md +0 -49
package/CHANGELOG.md CHANGED
@@ -2,6 +2,66 @@
2
2
 
3
3
  All notable changes to UKit are documented here.
4
4
 
5
+ ## 2.2.2 - 2026-08-22
6
+
7
+ Running Claude Code and omp side by side exposed that they were not, in fact, running the same UKit. `CLAUDE.md` and `AGENTS.md` are hand-maintained forks of one instruction set read by different harnesses, and `AGENTS.md` had fallen three minor versions behind — so omp was never told the model-tier table existed. This wave re-unifies them and adds a test that makes the drift impossible to repeat.
8
+
9
+ It also settles the three `TODO(verify)` items 2.2.1 shipped with. Those were plan-time guesses about omp's API, unresolvable at the time because omp was not installed on any machine that could answer them. omp v17.4.2 is now installed and was inspected directly — and two of the three guesses were wrong, in the quiet way where nothing errors and the feature simply never engages.
10
+
11
+ ### Fixed
12
+
13
+ - **Auto-compact was never actually configured on omp.** `.omp/config.yml` set `compact.autoCompactWindow: 180000`, a key omp does not have — `omp config get compact.autoCompactWindow` answers "Unknown setting", so the value was inert and omp stayed on its own default. The real key is `compaction.thresholdTokens` ("Fixed token limit for context maintenance; overrides percentage if set", omp's default `-1`). Verified end-to-end against a scratch project: the nested form now reads back as `180000`, which is below `compact.hardCapTokens` (220000) as intended, so auto-compact fires before `context-hardcap-gate.sh` starts blocking tool calls.
14
+ - **Post-compact hooks never ran on omp.** The bridge assumed omp re-emitted `session_start` after a compaction, the way Claude Code's matcher-less `SessionStart` hook fires with `source: "compact"`. It does not — it has a dedicated event instead (`session_before_compact` → `session.compacting` → `session_compact`, the last firing once compaction settles). So on omp the entire post-compact chain was lost: the run cursor stayed un-surfaced, compact pressure was never reset, and a mid-cycle handoff silently failed to resume after a compaction. `ukit-bridge.js` now maps `session_compact` onto the same script chain, keeping `hook_event_name: 'SessionStart'` in the payload so the scripts stay shared with Claude Code rather than forked.
15
+ - **Two UNIC gateway probes could never have fired.** `unic-gateway.mjs` probed an `OMP_BASE_URL` env var and a `baseUrl` key in `.omp/config.yml`. Neither exists: omp's anthropic provider reads `ANTHROPIC_BASE_URL` (falling back to `https://api.anthropic.com`), and its settings schema declares no `baseUrl` at any level. Both probes are removed rather than left returning a permanent `false` — a probe that can never fire is worse than no probe, because it reads as coverage. Detection is unchanged in behaviour and now literally matches what the docs already claimed: routing is decided only by `ANTHROPIC_BASE_URL`, on omp for the same reason as on Claude Code.
16
+ - **omp behaved as if UKit only had one model, because it was never told otherwise.** `templates/AGENTS.md` — the context doc omp, Codex and OpenCode read — was missing the entire `3-Tier Model Routing` block, plus `Post-Edit Sidecar Review` and `Skill Quality`, and still announced itself as `UKit v1.5.1`. `.omp/config.yml` declared `modelRoles` for all four lanes, but nothing in omp's context ever said *when* to use a tier, so everything ran inline on the session model.
17
+ - **Five section pairs had been renamed apart** — `Core Rule`/`Core UKit Rule`, `Fast Classification`/`Fast Task Classification`, `Internal Helper Policy`/`Internal Helper Routing`, `Selective Subagent Policy`/`Subagent Policy`, `Project Snapshot`/`Environment Snapshot`. This is what let the drift hide: once the headings differ, no diff lines up and the gap is invisible. Headings are now shared, and the two docs carry byte-identical bodies for every shared section.
18
+ - **Every session opened by being told to resume a finished cycle.** `docs/AI_HANDOFF/RUN.md` was left at `Phase: R4` after 2.2.1 shipped, so `handoff-resume.sh` — which runs in the `session_start` chain of *both* Claude Code and the omp bridge — fired a "CONTINUATION — resume immediately" banner at the start of every new, unrelated session. The cursor now reads `Phase: done`.
19
+ - **`/ukit:*` commands re-pasted the user's whole problem statement up to seven times per file.** Only one `$ARGUMENTS` site per command is a real interpolation (the `## Problem / feature` body); the other six were *references* that expanded to the entire paragraph again mid-sentence. They now say "the **Problem / feature** section above".
20
+ - **Eight fallback lines told the model to do something only a human can do.** `> Other tools without subagent support: manually switch to the strong model` reads, to a running model, as an instruction to itself — which it cannot follow, so it improvises. Each is now explicitly addressed: `> **For the human operator, on a tool with no agent support (Codex, OpenCode) — not an instruction to the model:**`.
21
+
22
+ ### Added
23
+
24
+ - **`### How a tier is actually bound`** in both context docs. The main session model never changes mid-turn; a tier only takes effect when work is handed to an agent whose own definition binds that model. The section carries a harness table (Claude Code `.claude/agents/*.md` + `subagent_type`, omp `.omp/agents/*.md` + `task-agent`) and states the consequence plainly: doing everything inline is exactly what makes UKit behave as if it had one model.
25
+ - **`tests/consistency/contextDocsParity.test.js`** (29 tests) — every `## ` section must exist in both `templates/CLAUDE.md` and `templates/AGENTS.md` with byte-identical bodies, unless allowlisted with a stated reason (currently one entry: `Session Start — OpenCode`, which exists because OpenCode does not auto-load `.claude/skills/`). Also asserts neither doc hardcodes a version, and that both manifest items declare the same variable set.
26
+ - **`.omp/RULES.md` grew from 4 rules to 7**, targeting direct chat specifically — direct chat is steered only by static context, so what is missing there is simply never applied. New: `Classify first, then act` (Trivial / Simple / Non-trivial lanes, decided *before* the first tool call), `Auto-activate skills`, and `Delegate to bind a model tier`. It stays short on purpose: it is re-attached near every turn.
27
+ - **The three `/ukit:*` sites that named only Claude Code now name omp too** — `handoff-fullstack.md`'s Model Split note, and the small-task-maintainer lines in `handoff-clear.md` and `handoff-status.md`.
28
+
29
+ ### Changed
30
+
31
+ - **Four more expired one-shot guards re-anchored, same class as the two below.** `ompDocsSync` cases 3 and 6 validated "the top CHANGELOG entry" — true on the day 2.2.1 shipped, false at the next release; they now find the omp entry by version. `ompContextLayer` case 10 guarded the compact key with a `TODO(verify)` marker instead of a value, and now asserts the verified key plus its provenance. `tests/handoff/cycle4/unic-gateway.test.mjs` case 13b had never actually run (it took its skip branch because the file it checked did not exist yet) and was matching a key spelling — `@vision:` — that belongs to the agent side, not the config side.
32
+ - **`tests/consistency/ompCommandParity.test.js` cases 4 and 5 no longer diff against `git show HEAD:`.** They were scope guards for one in-flight cycle ("TASK-005 must not modify these"), and that premise expired when the cycle shipped: against a committed baseline they pass vacuously, and against a dirty tree they block every later legitimate edit instead — which is exactly what they did. Both are re-expressed as the durable properties they stood in for (no `subagent_type` site in the two non-delegation commands; pinned per-file `Do NOT` and tier-justification-clause counts). No protection was dropped, only re-anchored.
33
+
34
+ ## 2.2.1 - 2026-08-22
35
+
36
+ UKit gains a fourth runtime and loses one. omp (Oh My Pi) reaches full parity with the Claude Code workspace — same agents, same skills, same hooks, same `/ukit:*` commands — and the Antigravity adapter, unused and unmaintained, is gone. The parity is deliberate rather than incidental: the port reuses the existing `.claude/` assets wherever omp's discovery can already reach them, so there is one source of truth per capability, not two that drift.
37
+
38
+ ### Added
39
+
40
+ - **omp (Oh My Pi) adapter — `ukit install --tools=omp`** (alias `--tools=oh-my-pi`). Installs 11 files: `.omp/AGENTS.md` (a thin `@../AGENTS.md` import rather than a copy, so the shared instructions have exactly one home), `.omp/RULES.md` (sticky hard rules), `.omp/config.yml`, `.omp/README.md`, `.omp/hooks/pre/ukit-bridge.js`, and the six agents under `.omp/agents/`. **No symlinks are created.** omp's discovery providers already rank its `claude` provider above nothing at all for skills and commands, so `.claude/skills/` and `.claude/commands/` are read directly — an `.omp/skills` symlink would shadow the canonical tree for no benefit. `.omp/agents/` must be real files because omp explicitly skips `.claude/agents/*.md`.
41
+ - **All six shared agents ported to omp's task-agent contract**: `bug-debugger`, `code-reviewer`, `feature-implementer`, `handoff-planner`, `ukit-small-task-maintainer`, `ukit-vision-analyst`. The differences between each agent's Claude Code and omp form — and why each one is or is not a faithful port — are recorded in [`docs/research/2026-08-22_omp-agent-parity.md`](docs/research/2026-08-22_omp-agent-parity.md).
42
+ - **UNIC model names survive the port.** `.omp/config.yml` ships `modelRoles` with all four lanes intact: `lite: unic-lite`, `code: unic-code`, `smart: unic-smart`, `vision: unic-vision`. The vision lane stays a capability lane, not a fourth cost tier.
43
+ - **Hook bridge — one source of truth, two runtimes.** `.omp/hooks/pre/ukit-bridge.js` is an omp hook factory (`export default function hook(pi)`) that translates omp's events into the Claude Code hook JSON shape and then executes the **existing** `.claude/hooks/*.sh` scripts. The 20 shell hooks are not duplicated, forked, or rewritten for omp; a fix to one fixes both runtimes.
44
+ - **Auto-compact parity.** `compact.agentContext.targets` gains an `omp` entry using `mode: 'precompact-reinject'` — the same strategy as `claude`, not Codex's `soft-handoff`. omp exposes real pre-compaction hook events, so there is nothing to work around with a state file.
45
+ - **`agent-code-reviewer` manifest item.** `templates/.claude/agents/code-reviewer.md` had shipped as a template with no manifest item since it was introduced, and `autoDiscoverTemplates: false` meant it was therefore **silently never installed** — UKit was installing five of its six Claude agents. Both the handoff Phase 4 reviewer and the Post-Edit Sidecar Review added in 2.1.5 instruct the model to spawn an agent that was not present in any installed project. Found by the omp parity work, because the new adapter would otherwise have shipped a strictly better agent set than the one it was porting from.
46
+
47
+ ### Changed
48
+
49
+ - **`/ukit:*` commands are phrased for whichever runtime is reading them.** The command bodies no longer assume Claude Code's spawn mechanics; each names its model tier and its delegation step in runtime-neutral terms, so the same file drives the same pipeline under Claude Code and under omp.
50
+ - **`ukit status` reports `Oh My Pi (omp)`** and checks `.omp/config.yml`; the Antigravity row is gone.
51
+ - **`.omp/` is TCC-protected** (`applyPlan.js`) and **git-ignored** by the managed `.gitignore` block, alongside `.claude/` and `.codex/`.
52
+
53
+ ### Removed
54
+
55
+ - **The Antigravity adapter.** `templates/.antigravity/`, `templates/adapter-presets/antigravity/`, the five `multi-antigravity-*` manifest items, its entry in `src/cli/adapters.js`, and every user-facing mention — in `README.md`, `QUICK_START.md`, `docs/PROJECT.md`, and in the installed workspace itself: `AGENTS.md`, `.codex/README.md` and the four `/ukit:handoff-*` command files all named Antigravity as a tool you could use. `--tools=antigravity` now fails fast with `Antigravity has been removed as a UKit adapter.` plus the list of adapters that do exist, rather than silently installing nothing.
56
+ - **Legacy cleanup is retained, not removed.** `ukit uninstall` still cleans `.antigravity/`, and `.antigravity/` keeps its TCC protection, because a stale pre-2.2.0 install still has the directory. Install-time pruning now covers it too: `.antigravity/` joined `AUTO_PRUNE_OBSOLETE_PREFIXES`, so a re-install removes the stale symlinks a pre-2.2.0 install left behind. Without it those links would dangle forever — pruning is the only pass that ever revisits them, and removing the adapter took them out of the manifest that uninstall reads. Only paths UKit itself recorded in `install.json` are considered, and a path the user has replaced with a real directory is skipped with a warning instead of being silently left behind.
57
+
58
+ ### Fixed
59
+
60
+ - **Deselecting omp no longer orphans its agents.** `OPTIONAL_ADAPTERS`' `managedPaths` listed `.omp/agents` as a single entry, copying the shape of Codex's `.codex/agents`. Codex's is a symlink; omp's is a real directory of six real files. `removeFileOrLinkOnly` refuses real directories, so re-running `ukit install` without `omp` and confirming removal deleted nothing — while the metadata pass still dropped all six from `install.json`, leaving them on disk and untracked forever. The six paths are now listed individually, matching `uninstall.js`'s own list. Full `ukit uninstall` was never affected.
61
+ - **The `--tools=antigravity` regression test was passing vacuously.** It asserted on a directory the install pipeline had never been pointed at, so the "no partial write" half would have held even if the error path did write. It now runs the real `bin/ukit`, and checks the exit code, the stderr text, the absence of a stack frame, and that not even the always-on `.claude/` adapter was written.
62
+
63
+ **Known gap:** omp was not installed on the machine this release was built on. Every omp assertion in the test suite is against the generated `.omp/` tree and the bridge module's shape — the packed-tarball test confirms `templates/.omp/**` actually publishes, but nothing here observes omp's runtime behaviour. The three open verification items (does omp emit `session_start` on a post-compact continuation; omp's real base-URL key; omp's real auto-compact-window key) are recorded in `docs/AI_HANDOFF/tasks/TASK-008.md`.
64
+
5
65
  ## 2.1.5 - 2026-08-19
6
66
 
7
67
  `local-build` was the one execution contract in the daily (non-handoff) flow that let the executor claim done off write evidence alone — and it is also the busiest lane a weaker `unic-code` backend hits. This closes that gap and adds a non-blocking second opinion, without adding wait time to the main task.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # UKit
2
2
 
3
- UKit installs a project-local AI workspace (`.claude/`, adapters, docs, and index helpers) so your team can work with Claude Code, Antigravity, OpenAI Codex, and OpenCode from the same repo setup.
3
+ UKit installs a project-local AI workspace (`.claude/`, adapters, docs, and index helpers) so your team can work with Claude Code, OpenAI Codex, OpenCode, and omp (Oh My Pi) from the same repo setup.
4
4
 
5
5
  ## Highest-Priority Team Rule
6
6
 
@@ -57,10 +57,13 @@ If maintainers roll out a newer CLI build, the in-project workflow still stays t
57
57
  - `AGENTS.md` — shared instructions for AGENTS-compatible tools
58
58
 
59
59
  **Adapters**
60
- - `.antigravity/skills/` → symlink to `.claude/skills/`
61
- - `.antigravity/rules/` — Antigravity rules
62
60
  - `.codex/settings.json` + `.codex/settings.local.json` — Codex config
63
61
  - `opencode.json` — OpenCode project config with UKit-safe guardrails
62
+ - `.omp/AGENTS.md` — thin `@../AGENTS.md` import so omp reads the shared instructions
63
+ - `.omp/RULES.md` — sticky hard rules for omp sessions
64
+ - `.omp/config.yml` — omp model roles, tool approval, and bash patterns
65
+ - `.omp/agents/` — the six shared agents in omp's task-agent format
66
+ - `.omp/hooks/pre/ukit-bridge.js` — bridges omp events onto the existing `.claude/hooks/*.sh`
64
67
 
65
68
  **Project support files**
66
69
  - `.claude/ukit/.ukit/` — installer manifests, metadata, backups
@@ -192,8 +195,8 @@ For deeper index development, repo-level scripts are available:
192
195
  | Tool | Instructions | Skills | Config |
193
196
  |------|-------------|--------|--------|
194
197
  | Claude Code | `CLAUDE.md` | `.claude/skills/` (canonical) | `.claude/settings.json` |
195
- | Antigravity | `AGENTS.md` | `.antigravity/skills/` (symlink) | `.antigravity/rules/`, `.antigravity/README.md` |
196
198
  | OpenAI Codex | `AGENTS.md` | `.claude/skills/` (referenced) | `.codex/settings.json`, `.codex/settings.local.json`, `.codex/README.md` |
197
199
  | OpenCode | `AGENTS.md` | `.claude/skills/` (native Claude-compatible support) | `opencode.json` |
200
+ | omp (Oh My Pi) | `.omp/AGENTS.md` (imports `AGENTS.md`) | `.claude/skills/` (read via omp's claude provider — no symlink) | `.omp/config.yml`, `.omp/RULES.md`, `.omp/README.md` |
198
201
 
199
202
  All supported tools share the same SKILL.md ecosystem so the workspace is authored once and reused everywhere.
@@ -110,13 +110,21 @@ items:
110
110
  - docs-project
111
111
  - docs-memory
112
112
  mergeStrategy: overwrite_with_backup
113
+ # Same set as root-claude-md: AGENTS.md is the same body with a different H1 plus one
114
+ # OpenCode-only section, so it interpolates the same variables. Kept in sync by
115
+ # tests/consistency/contextDocsParity.test.js.
113
116
  variables:
114
117
  - project.name
118
+ - project.root
115
119
  - project.stack
116
120
  - stack.frontend
117
121
  - stack.backendApi
118
122
  - stack.postgres
119
123
  - runtime.packageManager
124
+ - runtime.os
125
+ - runtime.nodeVersion
126
+ - providers.unic
127
+ - ukit.version
120
128
  enabledByDefault: true
121
129
  packs:
122
130
  - core
@@ -830,6 +838,20 @@ items:
830
838
  packs:
831
839
  - core
832
840
 
841
+ # The .omp/ mirror of this agent has always been installed; the .claude/ original was
842
+ # shipped as a template with no manifest item, so autoDiscoverTemplates:false meant it
843
+ # was silently never installed. Both handoff Phase 4 and the sidecar diff review need it.
844
+ - id: agent-code-reviewer
845
+ type: agent
846
+ sourceTemplate: .claude/agents/code-reviewer.md
847
+ targetPath: .claude/agents/code-reviewer.md
848
+ requires: []
849
+ mergeStrategy: overwrite_with_backup
850
+ variables: []
851
+ enabledByDefault: true
852
+ packs:
853
+ - core
854
+
833
855
  - id: agent-ukit-small-task-maintainer
834
856
  type: agent
835
857
  sourceTemplate: .claude/agents/ukit-small-task-maintainer.md
@@ -1517,62 +1539,137 @@ items:
1517
1539
 
1518
1540
  # ═══════════════════════════════════════════════════════════════
1519
1541
  # Multi-tool Adapters
1520
- # Symlink .claude/skills/ into Antigravity discovery paths.
1521
1542
  # Config files generated from templates.
1522
1543
  # ═══════════════════════════════════════════════════════════════
1523
1544
 
1524
- # --- Google Antigravity ---
1545
+ # --- omp (Oh My Pi) ---
1546
+ # No `type: link` items on purpose (PLAN.md §3 D10): omp's `claude` discovery provider
1547
+ # already reads `.claude/skills` and `.claude/commands`, so a native-priority duplicate
1548
+ # under `.omp/` would buy nothing. `.omp/agents/` must be real files because omp skips
1549
+ # `.claude/agents/*.md` outright (TASK_AGENT_CONFIG_SOURCE = ".omp").
1550
+ # `autoDiscoverTemplates: false` means a template file without an item here is silently
1551
+ # never installed — every file under `templates/.omp/` needs exactly one entry below.
1525
1552
 
1526
- - id: multi-antigravity-skills-link
1527
- type: link
1528
- sourceTemplate: .claude/skills
1529
- targetPath: .antigravity/skills
1553
+ - id: multi-omp-agents-md
1554
+ type: config
1555
+ sourceTemplate: .omp/AGENTS.md
1556
+ targetPath: .omp/AGENTS.md
1530
1557
  requires: []
1558
+ mergeStrategy: overwrite_with_backup
1559
+ variables: []
1531
1560
  enabledByDefault: true
1532
1561
  packs:
1533
1562
  - core
1534
1563
 
1535
- - id: multi-antigravity-ukit-link
1536
- type: link
1537
- sourceTemplate: .claude/ukit
1538
- targetPath: .antigravity/ukit
1564
+ - id: multi-omp-rules
1565
+ type: config
1566
+ sourceTemplate: .omp/RULES.md
1567
+ targetPath: .omp/RULES.md
1539
1568
  requires: []
1569
+ mergeStrategy: overwrite_with_backup
1570
+ variables: []
1540
1571
  enabledByDefault: true
1541
1572
  packs:
1542
1573
  - core
1543
1574
 
1544
- - id: multi-antigravity-agents-link
1545
- type: link
1546
- sourceTemplate: .claude/agents
1547
- targetPath: .antigravity/agents
1575
+ - id: multi-omp-config
1576
+ type: config
1577
+ sourceTemplate: .omp/config.yml
1578
+ targetPath: .omp/config.yml
1548
1579
  requires: []
1580
+ mergeStrategy: overwrite_with_backup
1581
+ variables: []
1549
1582
  enabledByDefault: true
1550
1583
  packs:
1551
1584
  - core
1552
1585
 
1553
- - id: multi-antigravity-rules
1586
+ - id: multi-omp-readme
1554
1587
  type: config
1555
- sourceTemplate: adapter-presets/antigravity/rules.md
1556
- targetPath: .antigravity/rules/rules.md
1588
+ sourceTemplate: .omp/README.md
1589
+ targetPath: .omp/README.md
1557
1590
  requires: []
1558
1591
  mergeStrategy: overwrite_with_backup
1559
1592
  variables:
1560
1593
  - project.name
1594
+ - project.stack
1561
1595
  - runtime.packageManager
1562
1596
  enabledByDefault: true
1563
1597
  packs:
1564
1598
  - core
1565
1599
 
1566
- - id: multi-antigravity-readme
1600
+ - id: multi-omp-hook-bridge
1567
1601
  type: config
1568
- sourceTemplate: adapter-presets/antigravity/README.md
1569
- targetPath: .antigravity/README.md
1602
+ sourceTemplate: .omp/hooks/pre/ukit-bridge.js
1603
+ targetPath: .omp/hooks/pre/ukit-bridge.js
1570
1604
  requires: []
1571
1605
  mergeStrategy: overwrite_with_backup
1572
- variables:
1573
- - project.name
1574
- - project.stack
1575
- - runtime.packageManager
1606
+ variables: []
1607
+ enabledByDefault: true
1608
+ packs:
1609
+ - core
1610
+
1611
+ - id: multi-omp-agent-bug-debugger
1612
+ type: config
1613
+ sourceTemplate: .omp/agents/bug-debugger.md
1614
+ targetPath: .omp/agents/bug-debugger.md
1615
+ requires: []
1616
+ mergeStrategy: overwrite_with_backup
1617
+ variables: []
1618
+ enabledByDefault: true
1619
+ packs:
1620
+ - core
1621
+
1622
+ - id: multi-omp-agent-code-reviewer
1623
+ type: config
1624
+ sourceTemplate: .omp/agents/code-reviewer.md
1625
+ targetPath: .omp/agents/code-reviewer.md
1626
+ requires: []
1627
+ mergeStrategy: overwrite_with_backup
1628
+ variables: []
1629
+ enabledByDefault: true
1630
+ packs:
1631
+ - core
1632
+
1633
+ - id: multi-omp-agent-feature-implementer
1634
+ type: config
1635
+ sourceTemplate: .omp/agents/feature-implementer.md
1636
+ targetPath: .omp/agents/feature-implementer.md
1637
+ requires: []
1638
+ mergeStrategy: overwrite_with_backup
1639
+ variables: []
1640
+ enabledByDefault: true
1641
+ packs:
1642
+ - core
1643
+
1644
+ - id: multi-omp-agent-handoff-planner
1645
+ type: config
1646
+ sourceTemplate: .omp/agents/handoff-planner.md
1647
+ targetPath: .omp/agents/handoff-planner.md
1648
+ requires: []
1649
+ mergeStrategy: overwrite_with_backup
1650
+ variables: []
1651
+ enabledByDefault: true
1652
+ packs:
1653
+ - core
1654
+
1655
+ - id: multi-omp-agent-ukit-small-task-maintainer
1656
+ type: config
1657
+ sourceTemplate: .omp/agents/ukit-small-task-maintainer.md
1658
+ targetPath: .omp/agents/ukit-small-task-maintainer.md
1659
+ requires: []
1660
+ mergeStrategy: overwrite_with_backup
1661
+ variables: []
1662
+ enabledByDefault: true
1663
+ packs:
1664
+ - core
1665
+
1666
+ - id: multi-omp-agent-ukit-vision-analyst
1667
+ type: config
1668
+ sourceTemplate: .omp/agents/ukit-vision-analyst.md
1669
+ targetPath: .omp/agents/ukit-vision-analyst.md
1670
+ requires: []
1671
+ mergeStrategy: overwrite_with_backup
1672
+ variables: []
1576
1673
  enabledByDefault: true
1577
1674
  packs:
1578
1675
  - core
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "@ngockhoale/ukit",
3
- "version": "2.1.5",
4
- "description": "Install/update an index-first AI workspace for Claude Code, Antigravity, OpenAI Codex, and OpenCode.",
3
+ "version": "2.2.2",
4
+ "description": "Install/update an index-first AI workspace for Claude Code, OpenAI Codex, OpenCode, and omp (Oh My Pi).",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "keywords": [
8
8
  "ukit",
9
9
  "claude",
10
10
  "codex",
11
- "antigravity",
12
11
  "claude-code",
13
12
  "opencode",
13
+ "omp",
14
+ "oh-my-pi",
14
15
  "skills",
15
16
  "agents",
16
17
  "ai",
@@ -1,22 +1,4 @@
1
1
  export const OPTIONAL_ADAPTERS = [
2
- {
3
- key: 'antigravity',
4
- label: 'Antigravity',
5
- itemIds: [
6
- 'multi-antigravity-skills-link',
7
- 'multi-antigravity-ukit-link',
8
- 'multi-antigravity-rules',
9
- 'multi-antigravity-readme',
10
- 'multi-antigravity-agents-link',
11
- ],
12
- managedPaths: [
13
- '.antigravity/skills',
14
- '.antigravity/ukit',
15
- '.antigravity/rules/rules.md',
16
- '.antigravity/README.md',
17
- '.antigravity/agents',
18
- ],
19
- },
20
2
  {
21
3
  key: 'codex',
22
4
  label: 'OpenAI Codex',
@@ -47,6 +29,42 @@ export const OPTIONAL_ADAPTERS = [
47
29
  'opencode.json',
48
30
  ],
49
31
  },
32
+ {
33
+ key: 'omp',
34
+ label: 'Oh My Pi (omp)',
35
+ itemIds: [
36
+ 'multi-omp-agents-md',
37
+ 'multi-omp-rules',
38
+ 'multi-omp-config',
39
+ 'multi-omp-readme',
40
+ 'multi-omp-hook-bridge',
41
+ 'multi-omp-agent-bug-debugger',
42
+ 'multi-omp-agent-code-reviewer',
43
+ 'multi-omp-agent-feature-implementer',
44
+ 'multi-omp-agent-handoff-planner',
45
+ 'multi-omp-agent-ukit-small-task-maintainer',
46
+ 'multi-omp-agent-ukit-vision-analyst',
47
+ ],
48
+ managedPaths: [
49
+ '.omp/AGENTS.md',
50
+ '.omp/RULES.md',
51
+ '.omp/config.yml',
52
+ '.omp/README.md',
53
+ '.omp/hooks/pre/ukit-bridge.js',
54
+ // Listed file-by-file, unlike Codex's single '.codex/agents' entry. Codex's is a
55
+ // symlink; omp's is a real directory of real files (manifest: omp skips .claude/agents,
56
+ // so these must be real). Deselect calls removeFileOrLinkOnly, which refuses real
57
+ // directories — a single '.omp/agents' entry would drop all six from install.json
58
+ // while leaving them on disk, orphaned and no longer tracked. Keep in sync with
59
+ // buildFallbackPaths in src/core/uninstall.js.
60
+ '.omp/agents/bug-debugger.md',
61
+ '.omp/agents/code-reviewer.md',
62
+ '.omp/agents/feature-implementer.md',
63
+ '.omp/agents/handoff-planner.md',
64
+ '.omp/agents/ukit-small-task-maintainer.md',
65
+ '.omp/agents/ukit-vision-analyst.md',
66
+ ],
67
+ },
50
68
  ];
51
69
 
52
70
  export const ADAPTER_BY_KEY = new Map(OPTIONAL_ADAPTERS.map((adapter) => [adapter.key, adapter]));
@@ -55,14 +73,15 @@ export const DEFAULT_OPTIONAL_TOOL_KEYS = OPTIONAL_ADAPTERS.map((adapter) => ada
55
73
  export const TOOL_ALIASES = new Map([
56
74
  ['claude', 'claude'],
57
75
  ['claude-code', 'claude'],
58
- ['antigravity', 'antigravity'],
59
76
  ['codex', 'codex'],
60
77
  ['openai-codex', 'codex'],
61
78
  ['opencode', 'opencode'],
62
79
  ['open-code', 'opencode'],
80
+ ['omp', 'omp'],
81
+ ['oh-my-pi', 'omp'],
63
82
  ]);
64
83
 
65
- export const TOOLS_FLAG_HELP = 'all|none|claude,antigravity,codex,opencode';
84
+ export const TOOLS_FLAG_HELP = 'all|none|claude,codex,opencode,omp';
66
85
 
67
86
  export function parseToolsArg(argv = []) {
68
87
  let toolsArg = null;
@@ -111,7 +130,14 @@ export function resolveOptionalToolKeys(toolsArg) {
111
130
  const token = rawToken.trim();
112
131
  if (!token) continue;
113
132
 
114
- const normalizedTool = TOOL_ALIASES.get(token.toLowerCase()) ?? null;
133
+ const normalizedToken = token.toLowerCase();
134
+ if (normalizedToken === 'antigravity' || normalizedToken === 'google-antigravity') {
135
+ throw new Error(
136
+ `Antigravity has been removed as a UKit adapter. Allowed: ${TOOLS_FLAG_HELP}`,
137
+ );
138
+ }
139
+
140
+ const normalizedTool = TOOL_ALIASES.get(normalizedToken) ?? null;
115
141
  if (!normalizedTool) {
116
142
  throw new Error(`Unknown tool '${token}'. Allowed: ${TOOLS_FLAG_HELP}`);
117
143
  }
package/src/cli/index.js CHANGED
@@ -96,8 +96,8 @@ export async function runCli({ argv, packageRoot, projectRoot, packageVersion })
96
96
  console.log('');
97
97
  console.log('Options (install / diff):');
98
98
  console.log(' --tools=<list> Comma-separated adapters to enable (default: all)');
99
- console.log(' Values: claude, antigravity, codex, opencode');
100
- console.log(' Example: ukit install --tools=claude,codex,opencode');
99
+ console.log(' Values: claude, codex, opencode, omp');
100
+ console.log(' Example: ukit install --tools=claude,codex,opencode,omp');
101
101
  console.log(' Use --tools=none to disable all optional adapters');
102
102
  console.log(' --with-codegraph Enable CodeGraph MCP integration in CLAUDE.md');
103
103
  console.log(' Adds routing rules that prefer codegraph_* tools for');
@@ -2,9 +2,12 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { writeFileAtomic, copyFileSafe, createDirectoryLink, removeLinkOnly } from './fileOps.js';
4
4
 
5
- const TCC_PROTECTED_PREFIXES = ['.codex/', '.antigravity/'];
5
+ // legacy: '.antigravity/' stays TCC-protected — Antigravity adapter removed in v2.2.0, but a
6
+ // stale install may still have the dir and must not lose TCC protection.
7
+ const TCC_PROTECTED_PREFIXES = ['.codex/', '.antigravity/', '.omp/'];
6
8
 
7
- function isTccProtectedPath(filePath) {
9
+ // Exported for tests: the prefix boundary is security-relevant and worth asserting directly.
10
+ export function isTccProtectedPath(filePath) {
8
11
  const normalized = filePath.replace(/\\/g, '/');
9
12
  return TCC_PROTECTED_PREFIXES.some((prefix) => {
10
13
  const idx = normalized.indexOf(`/${prefix}`);
@@ -4,9 +4,11 @@ import { writeFileAtomic } from './fileOps.js';
4
4
 
5
5
  const UKIT_ENTRIES = [
6
6
  '.cache/',
7
+ // legacy: Antigravity adapter removed in v2.2.0; leftovers must stay ignored
7
8
  '.antigravity/',
8
9
  '.claude/',
9
10
  '.codex/',
11
+ '.omp/',
10
12
  '.ukit/',
11
13
  'opencode.json',
12
14
  'AGENTS.md',
@@ -16,6 +16,10 @@ import { cleanupEmptyParents, readJsonIfExists, removeFileOrLinkOnly, resolvePro
16
16
 
17
17
  const AUTO_PRUNE_OBSOLETE_PREFIXES = [
18
18
  '.claude/skills/',
19
+ // The Antigravity adapter was removed in v2.2.0. Without this, a pre-2.2.0 install
20
+ // leaves its .antigravity/ links dangling forever, since nothing else ever revisits
21
+ // them. Only paths UKit itself recorded in install.json are considered here.
22
+ '.antigravity/',
19
23
  ];
20
24
 
21
25
  const AUTO_PRUNE_OBSOLETE_PATHS = new Set([
@@ -219,6 +223,21 @@ async function pruneObsoleteManagedPaths({
219
223
  if (removed) {
220
224
  removedCount += 1;
221
225
  await cleanupEmptyParents(absolutePath, projectRoot);
226
+ continue;
227
+ }
228
+
229
+ // removeFileOrLinkOnly refuses real directories. A path recorded as managed that is
230
+ // now a real directory means the user replaced it — say so instead of silently
231
+ // leaving it behind, matching the link-update warning in applyPlan.js.
232
+ try {
233
+ const stat = await fs.lstat(absolutePath);
234
+ if (stat.isDirectory() && !stat.isSymbolicLink()) {
235
+ console.warn(
236
+ `[UKit] Warning: skipping obsolete path ${absolutePath} — exists as a real directory (possible user content). Remove it manually if intended.`,
237
+ );
238
+ }
239
+ } catch {
240
+ // Already gone — nothing to prune and nothing to warn about.
222
241
  }
223
242
  }
224
243
 
@@ -6,7 +6,9 @@ import { buildRuntimePaths } from './runtimePaths.js';
6
6
  const require = createRequire(import.meta.url);
7
7
  const { version: PACKAGE_VERSION } = require('../../package.json');
8
8
 
9
- const VALID_AGENTS = new Set(['claude-code', 'codex', 'antigravity', 'opencode']);
9
+ // legacy: 'antigravity' stays valid — Antigravity adapter removed in v2.2.0, but an existing
10
+ // config.json naming it must not become invalid.
11
+ const VALID_AGENTS = new Set(['claude-code', 'codex', 'antigravity', 'opencode', 'omp']);
10
12
 
11
13
  const BLOCKED_MERGE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
12
14
 
@@ -79,6 +81,9 @@ export function buildDefaultRuntimeConfig(overrides = {}) {
79
81
  targets: {
80
82
  claude: { autoCompact: true, mode: 'precompact-reinject', preserveExistingHooks: true },
81
83
  opencode: { autoCompact: true, mode: 'native-auto-prune', preserveExistingCompaction: true },
84
+ // 'precompact-reinject' like claude, NOT codex's 'soft-handoff': omp exposes real
85
+ // pre-compaction hook events, so there is nothing to work around with a state file.
86
+ omp: { autoCompact: true, mode: 'precompact-reinject', preserveExistingHooks: true },
82
87
  codex: {
83
88
  autoCompact: true,
84
89
  mode: 'soft-handoff',
@@ -11,8 +11,10 @@ import { detectProjectContext } from '../context/detectProjectContext.js';
11
11
  function formatPrimaryAgent(agentKey) {
12
12
  if (agentKey === 'claude-code') return 'Claude Code';
13
13
  if (agentKey === 'codex') return 'OpenAI Codex';
14
+ // legacy: Antigravity adapter removed in this release; existing config.json may still name it
14
15
  if (agentKey === 'antigravity') return 'Antigravity';
15
16
  if (agentKey === 'opencode') return 'OpenCode';
17
+ if (agentKey === 'omp') return 'Oh My Pi (omp)';
16
18
  return agentKey || 'Unknown';
17
19
  }
18
20
 
@@ -20,9 +22,9 @@ async function detectAdapterLabels(projectRoot, primaryAgent) {
20
22
  const labels = [formatPrimaryAgent(primaryAgent)];
21
23
 
22
24
  const checks = [
23
- { label: 'Antigravity', path: '.antigravity/README.md' },
24
25
  { label: 'OpenAI Codex', path: '.codex/settings.json' },
25
26
  { label: 'OpenCode', path: 'opencode.json' },
27
+ { label: 'Oh My Pi (omp)', path: '.omp/config.yml' },
26
28
  ];
27
29
 
28
30
  for (const check of checks) {
@@ -24,8 +24,10 @@ const ALLOWED_UNINSTALL_PREFIXES = [
24
24
  'AGENTS.md',
25
25
  'docs/',
26
26
  '.claude/',
27
+ // legacy: Antigravity adapter removed in v2.2.0; still cleaned up on repos that installed it
27
28
  '.antigravity/',
28
29
  '.codex/',
30
+ '.omp/',
29
31
  '.ukit/',
30
32
  'opencode.json',
31
33
  ];
@@ -77,14 +79,28 @@ function buildFallbackPaths(projectRoot) {
77
79
  path.join(projectRoot, '.claude', 'ukit', '.env.example'),
78
80
  path.join(projectRoot, '.claude', 'ukit', 'permission-usage.json'),
79
81
  path.join(projectRoot, '.claude', 'ukit', 'permission-audit.log'),
82
+ // legacy: Antigravity adapter removed in v2.2.0; still cleaned up on repos that installed it
80
83
  path.join(projectRoot, '.antigravity', 'rules', 'rules.md'),
81
84
  path.join(projectRoot, '.antigravity', 'README.md'),
82
85
  path.join(projectRoot, '.codex', 'README.md'),
83
86
  path.join(projectRoot, 'opencode.json'),
87
+ // omp adapter — 11 managed files, no symlinks (the adapter creates none)
88
+ path.join(projectRoot, '.omp', 'AGENTS.md'),
89
+ path.join(projectRoot, '.omp', 'RULES.md'),
90
+ path.join(projectRoot, '.omp', 'config.yml'),
91
+ path.join(projectRoot, '.omp', 'README.md'),
92
+ path.join(projectRoot, '.omp', 'hooks', 'pre', 'ukit-bridge.js'),
93
+ path.join(projectRoot, '.omp', 'agents', 'bug-debugger.md'),
94
+ path.join(projectRoot, '.omp', 'agents', 'code-reviewer.md'),
95
+ path.join(projectRoot, '.omp', 'agents', 'feature-implementer.md'),
96
+ path.join(projectRoot, '.omp', 'agents', 'handoff-planner.md'),
97
+ path.join(projectRoot, '.omp', 'agents', 'ukit-small-task-maintainer.md'),
98
+ path.join(projectRoot, '.omp', 'agents', 'ukit-vision-analyst.md'),
84
99
  path.join(projectRoot, '.ukit'),
85
100
  stateDir,
86
101
  ],
87
102
  linkPaths: [
103
+ // legacy: Antigravity adapter removed in v2.2.0; still cleaned up on repos that installed it
88
104
  path.join(projectRoot, '.antigravity', 'skills'),
89
105
  path.join(projectRoot, '.antigravity', 'ukit'),
90
106
  path.join(projectRoot, '.codex', 'skills'),
@@ -256,7 +256,7 @@ export const ROUTE_CATALOG = [
256
256
  signals: [
257
257
  { type: 'prompt', regex: /\b(stale|refresh|cleanup|reinstall|maintenance|workspace drift|index freshness|out of date)\b/i, score: 4 },
258
258
  { type: 'command', regex: /\bukit install\b|\brefresh-index\.mjs\b|\bbuild-index\.mjs\b/i, score: 3 },
259
- { type: 'file', regex: /\.claude\/|\.codex\/|\.antigravity\//i, score: 1 },
259
+ { type: 'file', regex: /\.claude\/|\.codex\/|\.antigravity\/|\.omp\//i, score: 1 },
260
260
  ],
261
261
  },
262
262
  {
@@ -1,9 +1,4 @@
1
1
  export const OPTIONAL_ADAPTER_ITEM_IDS = new Set([
2
- 'multi-antigravity-skills-link',
3
- 'multi-antigravity-ukit-link',
4
- 'multi-antigravity-rules',
5
- 'multi-antigravity-readme',
6
- 'multi-antigravity-agents-link',
7
2
  'multi-codex-skills-link',
8
3
  'multi-codex-ukit-link',
9
4
  'multi-codex-readme',
@@ -11,6 +6,17 @@ export const OPTIONAL_ADAPTER_ITEM_IDS = new Set([
11
6
  'multi-codex-settings-local',
12
7
  'multi-codex-agents-link',
13
8
  'multi-opencode-config',
9
+ 'multi-omp-agents-md',
10
+ 'multi-omp-rules',
11
+ 'multi-omp-config',
12
+ 'multi-omp-readme',
13
+ 'multi-omp-hook-bridge',
14
+ 'multi-omp-agent-bug-debugger',
15
+ 'multi-omp-agent-code-reviewer',
16
+ 'multi-omp-agent-feature-implementer',
17
+ 'multi-omp-agent-handoff-planner',
18
+ 'multi-omp-agent-ukit-small-task-maintainer',
19
+ 'multi-omp-agent-ukit-vision-analyst',
14
20
  ]);
15
21
 
16
22
  function resolveItemOrder(items) {
@@ -57,7 +57,7 @@ Cleared: X worktrees removed, Y branches deleted, staged changes unstaged.
57
57
  Handoff docs reset. Ready for new cycle.
58
58
  ```
59
59
 
60
- > Claude Code: spawn `ukit-small-task-maintainer` (haiku).
60
+ > Claude Code: spawn `ukit-small-task-maintainer` (haiku). omp: the `task` tool with `agent: "ukit-small-task-maintainer"`.
61
61
  > Other tools: lite model, follow steps 1–5.
62
62
 
63
63
  **Next:** `/ukit:handoff-create <new problem description>`