1.1.0 — restructure agent types: driver registry, plugin opt-in, hermes (beta)#181
Merged
Conversation
Discover agent types from types/<name>/type.conf manifests instead of hardcoded case arms across whoami/join/spawn/delivery, so adding a type is a manifest + template (cf. the 8-file OpenCode addition #136). Detection (detect=/detect_proc=), the join whitelist, spawn (direct-CLI cli= and Node-launcher spawn=), and delivery hooks routing (hooks_file=) all read the registry. Manifests are read-only key=value DATA, never sourced. External add-on types plug in via a spawn= Node launcher (universal --name/--team/--project/--initial-input flags) and aliases= (a type owns another's spawn name), needing no built-in edits. The six built-in types are converted with zero behavior change; full suite 296 -> 312. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… only Agent types are selected explicitly: 'spawn codex' is plain codex, 'spawn codex-app-server' is the add-on — no automatic alias hijacks a built-in's spawn name. Removes agmsg_type_alias_for, spawn.sh's reverse-alias resolution, the aliases= manifest key (schema + node-launcher docs), and the alias fixture/test. The node-launcher (spawn=) plug point for external add-ons stays. Full suite 311/311; built-in behavior unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Group the codex-only scripts (codex-bridge.js, codex-bridge-launcher.sh, codex-monitor.sh, codex-shim.sh, codex-shim-install.sh, watch-once.sh) under scripts/codex/ so scripts/ top holds the externally-invoked command surface plus cross-cutting helpers, not a per-agent subsystem. Path follow-through: moved scripts resolve SKILL_DIR as ../.. and reference top-level siblings (delivery.sh, identities.sh, inbox.sh, send.sh, lib/) via ../; codex-internal siblings stay SCRIPT_DIR-relative. External callers updated (session-start.sh, delivery.sh), install.sh chmods scripts/codex/, tests and docs point at the new paths. No behavior change.
…rop hook.sh - scripts/internal/init-db.sh: DB schema init is a pure internal helper (callers: send.sh, install.sh). Not baked into any hook config, so it is safe to move. - scripts/windows/dispatch.sh: the command dispatcher is used only by the Windows launcher (agmsg.ps1); co-locate it. dispatch resolves top-level commands via ..; agmsg.ps1 now finds it beside itself (PSScriptRoot). - remove scripts/hook.sh: a long-deprecated alias for 'delivery.sh set turn|off' that only printed a deprecation notice and was never invoked by any runtime/hook. Drops tests/test_hook.bats, the hook.sh blocks in test_delivery.bats, and the README/design/SKILL mentions. check-inbox.sh deliberately stays at scripts/ top: delivery.sh bakes its absolute path into the Stop hook in users' settings, so moving it would break turn-mode delivery on upgrade until 'delivery.sh set' is re-run (same class as session-start/session-end).
…_env setup_test_env ran scripts/init-db.sh (now scripts/internal/init-db.sh), so every test using it failed at setup. Point it at the new path and chmod scripts/codex/ so the relocated codex scripts stay executable in the test skill dir.
Move the SQLite/JSON read-modify-write helpers (sql_readfile_path, strip_agmsg_event_file, windows_wrap, add_event_entry_file, prune_empty_hooks_file) out of delivery.sh into a dedicated lib module. Pure code move — no behavior change. delivery.sh sources it after SKILL_NAME is set, matching the existing lib convention. delivery.sh: 754 -> 588 lines.
delivery.sh is now a template: the default agmsg_delivery_apply_default writes the
JSON event-hooks (claude-code, codex), and a type may override it by shipping
types/<name>/_delivery.sh that defines agmsg_delivery_apply. apply_settings()
sources the plug when present, else calls the default — so adding a type's delivery
behavior is dropping one file, no edits to delivery.sh.
- scripts/lib/delivery-rulefile.sh: shared rule-file behavior (markdown rules
file). gemini/antigravity delegate to it in a one-line _delivery.sh.
- types/opencode/_delivery.sh, types/copilot/_delivery.sh: bespoke (turn|off only;
copilot writes JSON) — behavior preserved from the old apply_settings_*.
- removes apply_settings_{gemini,copilot,opencode} and the type dispatch from
delivery.sh.
test_delivery.bats: 87/87 (behavior unchanged).
…op_output= The codex|copilot JSON status (continue:true) on empty checks (cooldown / no new messages) was a hardcoded type list. Read it from the type manifest instead: stop_output=json emits the JSON status object, otherwise stay silent (claude-code). codex and copilot set stop_output=json. No behavior change (test_delivery 87/87, incl. the cooldown-status assertion).
# Conflicts: # scripts/codex/codex-bridge.js # scripts/delivery.sh # scripts/spawn.sh
Apply the delivery.sh Template Method pattern to session-start.sh: it now defines a default no-op agmsg_session_start and, when types/<type>/_session-start.sh exists, sources it (in the script's context) and calls the override. The codex-only bridge block — thread-id resolution, app-server discovery, and the bridge/request-file launch — moves verbatim into types/codex/_session-start.sh. Behaviour is unchanged; the codex tests (session-start + bridge) stay green.
… smoke smoke_windows_powershell.ps1 ran scripts/init-db.sh (now scripts/internal/) so the Windows-tests CI leg failed with exit 127. Point it at the new path. Also fix the docs/design.md script-table entry.
Completes the template co-location whose file moves landed in c14d1f3: the manifest template= key (previously dead) is now the source of truth. - lib/type-registry.sh: add agmsg_type_template_path, resolving template= relative to the type dir (rejects absolute/traversal like resolve_hooks_file) - type.conf x6: template=cmd.<type>.md -> template=template.md - install.sh: source the type registry; route every SKILL.md / slash-command generation through the resolver instead of hardcoded templates/ paths; drop the write-only $SKILL_DIR/templates/ ship (no runtime consumer) — templates now travel inside types/ via the existing cp -R, as unsubstituted source data - test_type_registry.bats: expect template.md; cover the new resolver No behavior change. Full bats suite (353) green incl. an end-to-end install smoke.
…solve The PowerShell smoke hand-stages the skill dir by copying scripts/ only, but join.sh (and other commands) validate the agent type through the type registry, which resolves types/<name>/type.conf relative to the skill dir. Without types/, 'join … codex' fails with 'Unknown agent type' (exit 1). This was latent until the init-db path fix let the smoke reach the join step; copy types/ alongside scripts/ to mirror what install.sh ships. Reproduced on macOS: no types/ -> exit 1, types/ present -> exit 0.
do_set no longer branches on codex/claude-code. The per-type onboarding (codex shim install + node preflight + restart guidance; claude-code's Monitor directive) and teardown (codex bridge stop; default watcher kill) are now agmsg_delivery_on_enable / agmsg_delivery_on_disable hooks in types/<name>/_delivery.sh, called generically by do_set. delivery.sh is now type-agnostic for the set/off paths. - types/codex/_delivery.sh: on_enable (shim+guidance), on_disable (stop bridge) - types/claude-code/_delivery.sh: on_enable (Monitor directive) - delivery.sh: default no-op on_enable / watcher-kill on_disable; do_set calls hooks test_delivery.bats 87/87 (behavior unchanged). The codex 'both'-mode guard stays in do_set (a small validation, not a side effect).
do_status no longer branches on the rule-file type list. agmsg_delivery_status (default: derive mode from json-hooks + print entry detail) is overridden by rule-file types to report mode from the rule file's presence. delivery.sh is now type-agnostic for apply / on_enable / on_disable / status; only the codex 'both' guard names a type. - delivery.sh: agmsg_delivery_status_default + dispatch in do_status - delivery-rulefile.sh: rulefile_status (present=turn, absent=off) - gemini/antigravity/opencode/copilot _delivery.sh: agmsg_delivery_status delegation test_delivery.bats 87/87 (behavior unchanged).
B-final shape: scripts/ holds the type-independent engine; types/<name>/ holds everything for that type. Move the six codex runtime files (codex-bridge.js, codex-bridge-launcher.sh, codex-monitor.sh, codex-shim.sh, codex-shim-install.sh, watch-once.sh) from scripts/codex/ into types/codex/, where the manifest, template, and delivery/session-start plugs already live. Depth is unchanged (both are two levels under the skill root), so SKILL_DIR= ../.. and all codex-to-codex sibling refs are untouched. Only references that reach UP into the shared engine gain one level: $SCRIPT_DIR/../<x> -> $SCRIPT_DIR/../../scripts/<x> (lib/*, identities.sh, delivery.sh). codex-bridge.js computes SKILL_DIR/SCRIPTS_DIR absolutely, so it needs no path change (comments only). Callers follow the files: _delivery.sh / _session-start.sh, install.sh's chmod, the test harness (new TYPES var, $TYPES/codex paths), and the docs. Also fixes a latent bug the earlier scripts/codex move (#23f1b8f) left behind: codex-bridge-launcher.sh and codex-monitor.sh sourced $SCRIPT_DIR/lib/hash.sh (a path that never existed under scripts/codex/) — that move fixed node.sh's '../' but missed hash.sh, so both scripts would fail at the agmsg_sha1 call. Corrected to ../../scripts/lib/hash.sh alongside the other engine refs. Full bats suite green except a pre-existing, environment-flaky watch test (closed-consumer SIGPIPE timing) that fails identically on the unchanged base.
The commandWindows wrapping in hooks-json.sh keyed off a hardcoded "codex" type name, violating that layer's stated type-agnostic boundary. Resolve the wrap decision in delivery.sh (the layer that knows agent types) from a new hook_windows_wrap=yes manifest key and pass a plain flag down. hooks-json.sh now references no type name.
# Conflicts: # tests/test_codex_bridge.bats
…fest Mode acceptance was scattered: a hardcoded codex 'both' guard in delivery.sh plus per-type monitor/both rejection branches duplicated in the opencode and copilot plugs. Declare each type's accepted modes once via the delivery_modes= manifest key and gate them centrally in do_set — a typo still gets the generic "Unknown mode" error; an unsupported real mode gets "not supported for <type>". The codex 'both' guard and the opencode/copilot rejection arms are now redundant and removed (rejection happens before any file is touched, preserving the don't-wipe-turn guarantee). The Windows dispatcher keeps an explicit codex monitor/both guard: the codex bridge is unsupported on Windows (#182, tests skip_on_windows), and delivery_modes is a global fact that can't express a platform exception.
The Quick Start opened with the curl one-liner and git clone; npx agmsg is the lowest-friction way to get the skill installed (it runs the same setup.sh bootstrapper, no clone). Lead with it and point readers who want to inspect the code, track main, or pick a custom command name to the Install section.
Per the driver-interface spec (docs/spec/driver-interface.md §1.1, bundled drivers live at scripts/drivers/<axis>/), move the agent-type tree from the repo root into scripts/drivers/types/. Agent types contain executable runtime (_delivery.sh, codex's bridge/launcher/shim), so they belong under scripts/, not at the top level. - git mv types/ -> scripts/drivers/types/ - type-registry in-tree search dir: <root>/types -> <root>/scripts/drivers/types - codex runtime upward refs reshift for the +2 depth: $SCRIPT_DIR/../.. (SKILL_DIR) -> ../../../.., and ../../scripts/ -> ../../../; codex-bridge.js resolves SKILL_DIR four levels up - install.sh: the single recursive scripts/ copy now carries the type tree, so the separate types/ copy is dropped; codex chmod path follows - tests: test_helper TYPES var + codex chmod; the scripts/ copy already brings the tree, so the separate types/ stage is dropped (bats + powershell smoke) - docs/comments/user-facing strings updated to the new path Discovery of EXTERNAL add-on dirs is unchanged here (still the legacy ~/.config/agmsg path); the plugins/AGMSG_PLUGIN_DIRS redesign + opt-in gating follow in the next commit.
This was referenced Jun 21, 2026
Introduce driver-registry.sh: the axis-generic search bases + trust policy shared by all driver axes (types now; storage/delivery later). Discovery order is scripts/drivers (built-in) -> <install_dir>/plugins -> $AGMSG_PLUGIN_DIRS, with later bases overriding earlier ones among eligible candidates. External drivers are shell code run with the user's privileges, so they are NEVER loaded unless explicitly opted into. A built-in is always trusted; anything under plugins/ or AGMSG_PLUGIN_DIRS is ignored — with a clear stderr warning — until 'agmsg plugin trust <axis>/<name>'. Trust is path-pinned (the db/trusted-plugins allowlist records axis/name -> abs path), so swapping a directory under a trusted name does not silently activate new code. - type-registry.sh becomes the types-axis facade over driver-registry; the AGMSG_TYPES_ROOT override and the ~/.config/agmsg/types external path are removed (root is always resolved from the lib's own location) - plugin.sh: 'agmsg plugin list|trust <ref>|untrust <ref>' (ref is axis/name or an unambiguous bare name); wired into the Windows dispatcher - docs: ADR 0002 records the discovery + opt-in decision (supersedes ADR 0001's deferred-loader note and ~/.agents/agmsg/plugins path); spec + agent-types updated - tests: test_plugin_registry.bats locks ignored-until-trusted, later-wins override, path-pinned trust, the warning, and the CLI
The top half still described the pre-1.1.0 layout: types/ at the repo root, templates/ for command templates, and apply_settings_* per-type code in delivery.sh. Update to scripts/drivers/types/<name>/, the type-dir-relative template= file, and the _delivery.sh Template Method plug. Add the delivery_modes / stop_output / hook_windows_wrap manifest keys to the table and the codex worked example.
…n dir Document the external-driver plugin system the way codex-monitor-beta is documented — a brief README section pointing to a dedicated doc: - docs/plugins.md: discovery order, the opt-in trust model (path-pinned, ignored-until-trusted), the 'agmsg plugin' CLI, and how to author a types plugin - README: a concise Plugins section + AGMSG_PLUGIN_DIRS in the env-var table; also refresh the Architecture tree (scripts/drivers/types, plugins/; drop the stale templates/) and fix a leftover types/codex path - plugins/: the default external drop-in dir, shipped with a README (and a .gitignore so locally-dropped test plugins/opt-ins stay untracked); install.sh now creates <skill>/plugins/ and ships the README
Integrates @Fewmanism's Hermes support (#118) and spawn profile (#119), adapted to the 1.1.0 driver layout (scripts/drivers/types/<name>/) instead of the old hardcoded per-type branches and templates/ dir. - scripts/drivers/types/hermes/{type.conf,template.md,_delivery.sh}: a manual- only type (delivery_modes=off — no automatic delivery hook). The _delivery.sh plug makes apply/status/teardown no-ops so 'set off' writes nothing and never disturbs another type's watcher; cli=hermes + spawnable=yes make 'spawn hermes' work through the generic data-driven path. - delivery.sh: gate the in-session stop directive on the type actually having an automatic mode (data-driven via delivery_modes), so a manual-only type emits no AGMSG-DIRECTIVE on 'set off'. No per-type branch. - install.sh: ship the Hermes skill to ~/.hermes/skills/<name>/ and accept --agent-type hermes for the shared SKILL.md, both via agmsg_type_template_path. - tests: hermes delivery (5) + install (5) + join, and the registry invariants (now 7 built-ins; spawnable set gains hermes; no-branch guard covers hermes). Deferred: #119's --hermes-profile spawn flag. It is inherently hermes-specific and the 1.1.0 layout forbids per-type branches in spawn.sh; it needs a generic spawn-profile mechanism (manifest key or spawn plug), tracked as a follow-up. Generic 'spawn hermes <name>' (default Hermes profile, actas via boot prompt) works today. Co-authored-by: Fewmanism <lgndscntn@googlemail.com>
The ~/.agents/bin/codex shim bakes in the absolute path to codex-shim.sh at generation time. install.sh --update copies the relocated script (scripts/drivers/types/codex/) but did not re-run codex-shim-install.sh, so a shim generated before the types/ -> scripts/drivers/types/ move kept execing its old, now-missing path — breaking Codex monitor for users upgrading from 1.0.x. (Found in review by aggie-co1.) Both install paths now re-run codex-shim-install.sh when an agmsg shim is already present (status reports 'installed'). install is idempotent and overwrites only an agmsg shim — a user's own codex binary fails is_agmsg_shim and is left untouched; when no shim exists the refresh is a no-op, so --update never opts a user into the shim. Covered by two install.bats cases (re-point on update; no shim created when none existed).
Feature the seven supported agent runtimes (Claude Code, Codex, Gemini, GitHub Copilot, Antigravity, OpenCode, Hermes) as a white-on-black logo strip under the intro. Source marks live in docs/logos/; the composited strip is docs/logos/supported-agents.png.
This was referenced Jun 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1.1.0 — restructure agent types
The release that makes "a type = a directory" real and purges hardcoded
type names from the shared engine. Adding or overriding an agent runtime is now
data (a manifest) plus optional behavior plugs — no edits across the engine
scripts.
Highlights
delivery.shdefines the default behavior;each type's optional
scripts/drivers/types/<name>/_delivery.shoverrides anyof
apply/on_enable/on_disable/status. The gnarly JSON/SQLite hooklayer is extracted to
scripts/lib/hooks-json.sh.delivery_modes,stop_output,and
hook_windows_wrapkeys move the last per-typecasearms (codexbothguard, opencode/copilot mode rejection, codex Windows hook-wrap, stop output
protocol) into data. A regression test asserts no per-type branch remains in
the shared scripts.
types/→scripts/drivers/types/. Agent types now live underscripts/drivers/<axis>/per the driver spec; the codex runtime is folded inalongside its manifest.
driver-registry.shprovides the shared discovery bases (
scripts/drivers→<install>/plugins→$AGMSG_PLUGIN_DIRS) and trust policy. External drivers are shell code, sothey are never loaded until opted into (
agmsg plugin trust <axis>/<name>);trust is path-pinned. New
agmsg plugin list|trust|untrustCLI.hermestype (manual-only delivery), shippedas beta for community verification. Adapted from feat: add Hermes Agent support #118/Follow-up to #118: support Hermes profiles in spawn #119 — thanks @Fewmanism.
docs/plugins.md,refreshed
docs/agent-types.md, README Plugins section + npx-first Quick Start.install.sh --updatenow re-points an existing Codexmonitor shim to the relocated path, so users upgrading from 1.0.x keep working
monitor mode.
Deferred (follow-ups)
resolve-project.shPID-detection binaries → data (1.1.x; low ROI / sensitive path).--hermes-profile(Follow-up to #118: support Hermes profiles in spawn #119) → a generic spawn-profile mechanism, to keep spawn.sh branch-free.grok-buildtype → community contribution (issue to follow).Testing
Required CI green on ubuntu / macos / windows-tests. The
full (experimental)leg is non-required and times out by design (#125).