Commit cb2e1d3
authored
refactor(bridges): collapse chat bridges into auto-discovered bridges/*.sh files (#77)
* refactor(bridges): collapse chat bridges into auto-discovered bridges/*.sh files
Closes #76.
Per-bridge logic was scattered across 4 files in 11 case statements
totaling ~2,500 LOC: lib/chat-bridge.sh (install dispatcher),
lib/chat-bridges.sh (registry + templates), upgrade.sh (per-bridge
sync/systemd/launchd update), lib/summary.sh (per-bridge restart/verify
hints). Adding a new bridge meant editing 3+ files and threading a new
arm through every case. The runtimes/ layer already solved this same
shape via runtimes/<name>.sh auto-discovery; bridges now adopt the
same pattern.
New layout:
bridges/
├── _dispatch.sh — auto-discover, bridge_load, bridge_call,
│ bridge_has_hook, install_chat_bridge,
│ BRIDGE_DETECTION_ORDER + shared helpers
│ (_resolve_node_bin_dir, _compose_path_value,
│ _merge_systemd_env_lines, _smart_update_systemd_unit,
│ _ensure_systemd_path_contains, _plist_string_after_key)
├── kimaki.sh — install + sync_config + render_systemd/launchd
├── kimaki/ — kimaki-private assets (plugins, post-upgrade.sh,
│ skills-kill-list.txt) — moved from repo root
├── cc-connect.sh
└── telegram.sh
Hook contract every bridge implements (see bridges/_dispatch.sh
docblock for the full list): bridge_install, bridge_systemd_units,
bridge_launchd_labels, bridge_binaries, bridge_display_name,
bridge_display_title, bridge_render_systemd, bridge_render_launchd,
bridge_sync_config, bridge_update_systemd, bridge_restart_cmd,
bridge_verify_cmd, bridge_logs_cmd, bridge_start_hint, bridge_stop_hint,
bridge_is_ready. Optional: bridge_update_launchd, bridge_vps_setup_block,
bridge_launchd_setup_block, bridge_vps_start_preamble,
bridge_verify_extra. Optional hooks are gated through bridge_has_hook
so a bridge omits any prose block it doesn't need (cc-connect has no
setup blocks because it has no token).
Dispatch model:
* bridge_load <name> sources bridges/<name>.sh into the current
shell. Used after CHAT_BRIDGE is decided so
install/sync hooks can mutate parent globals
(KIMAKI_BIN, RESOLVED_KIMAKI_PLUGINS_DIR,
UPDATED_ITEMS) the same way the legacy code
did.
* bridge_call <n> <hook> sources <n> in a SUBSHELL and invokes hook.
Used for registry walks (detection,
multi-bridge metadata queries) where parent
state must not be clobbered.
Detection priority is preserved via BRIDGE_DETECTION_ORDER constant
in _dispatch.sh (kimaki > cc-connect > telegram), then alphabetical
filesystem order for any future bridges added without updating the
constant. Hosts that somehow have multiple bridges installed see the
same tie-break behaviour as before.
Consumers all simplified:
* setup.sh sources bridges/_dispatch.sh and calls install_chat_bridge.
No more 'lib chat-bridge' source line.
* upgrade.sh phase 2 / phase 5 / phase 5a became 4-line wrappers that
call bridge_sync_config / bridge_update_systemd / bridge_update_launchd
on the loaded bridge. The 215-LOC _sync_kimaki_config body and the
three _update_*_systemd functions moved into bridges/<name>.sh as
bridge_sync_config / bridge_update_systemd. _smart_update_systemd_unit
and friends moved to bridges/_dispatch.sh as shared helpers.
* lib/summary.sh _print_*_setup_block case statements became
bridge_<setup_block> hook calls; _print_launchd_run_block no longer
takes a bridge arg (uses the loaded bridge's metadata directly).
* upgrade.sh's _print_verify_block kimaki special case became an
optional bridge_verify_extra hook.
* runtimes/opencode.sh kimaki plugin paths repointed to
$SCRIPT_DIR/bridges/kimaki/plugins/.
Tests:
* tests/bridge-render.sh rewritten as a golden-file regression suite.
Renders every (bridge × unit / launchd-label) combo through the new
bridge_render_* hooks and diffs against committed fixtures under
tests/__snapshots__/bridges/. Pre-refactor it diffed legacy install
function output against the new generators in lib/chat-bridges.sh;
both files are gone, so the test is now snapshot-based with a
--update flag for refreshing fixtures intentionally. The committed
snapshots were captured by running the legacy bridge_render_*
generators with deterministic env values, so this PR is provably
byte-equivalent to main.
* tests/path-helpers.sh source path updated (lib/chat-bridges.sh →
bridges/_dispatch.sh). 11/11 assertions pass.
* tests/post-upgrade-restore.sh path updated for the moved
kimaki/post-upgrade.sh.
Live-verified on intelligence-chubes4: ./upgrade.sh --dry-run --local
output is byte-identical to main modulo timestamps and script paths.
The 8 rendered template snapshots are byte-identical to legacy output.
Net delta: ~1594 LOC deleted across the four legacy files; ~1830 LOC
added across the four new bridges/ files. Roughly LOC-neutral but the
shape is dramatically different — adding a new bridge is now 'drop a
file in bridges/' (the promise the README already made for runtimes,
now actually delivered for bridges).
The kimaki-only --kimaki-only upgrade flag and --no-chat setup flag
are unchanged; the README and skills/upgrade-wp-coding-agents/SKILL.md
references to file paths got updated for the move.
## AI assistance
- **AI assistance:** Yes
- **Tool(s):** Claude Code (Sonnet 4.5)
- **Used for:** Drafted the bridges/_dispatch.sh dispatcher, mechanically
moved per-bridge functions out of lib/chat-bridge.sh / lib/chat-bridges.sh
/ upgrade.sh / lib/summary.sh into bridges/<name>.sh, rewrote
tests/bridge-render.sh as a snapshot harness, and live-verified the
byte-equivalence diff against main on intelligence-chubes4. Chris
reviewed the dispatch model + hook contract and ran the smoke tests.
* docs(upgrade): repoint stale _sync_kimaki_config comment at bridge_sync_config
* fix(tests): sanitize PATH + KIMAKI_BIN in bridge-render harness
The committed kimaki-systemd / kimaki-launchd snapshots were generated on
my dev machine, where `command -v node` and the kimaki shim at
/Users/chubes/.kimaki/bin/kimaki are reachable. `_resolve_node_bin_dir`
correctly followed both, baking /Users/chubes/.kimaki/bin into the
rendered Environment=PATH= line. CI runners (clean Linux, no kimaki shim,
no node on PATH) rendered without that segment and failed the diff.
Two-part fix:
1. tests/bridge-render.sh now exports PATH=/usr/bin:/bin at the top of
the env-mock block, so `command -v node` and the shim-parsing fallback
both miss on every machine. Snapshots become reproducible.
2. The two kimaki snapshots refreshed to drop the dev-machine path
segment. Diff is purely the removal of /Users/chubes/.kimaki/bin
from the PATH= line — no template logic changed.
CI red on PR #77, fixed here.1 parent 9126474 commit cb2e1d3
27 files changed
Lines changed: 2210 additions & 1781 deletions
File tree
- bridges
- kimaki
- plugins
- lib
- runtimes
- skills/upgrade-wp-coding-agents
- tests
- __snapshots__/bridges
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
256 | 256 | | |
257 | 257 | | |
258 | 258 | | |
259 | | - | |
| 259 | + | |
260 | 260 | | |
261 | 261 | | |
262 | | - | |
| 262 | + | |
263 | 263 | | |
264 | 264 | | |
265 | 265 | | |
| |||
0 commit comments