Repository navigation
rolebox v1.10.0
Features
-
Codex is a supported harness — rolebox now targets Codex through a generated local plugin marketplace plus a rolebox MCP server:
rolebox sync codexwrites<codexHome>/rolebox-marketplace(the marketplace manifest plusplugins/roleboxcarrying.codex-plugin/plugin.json,.mcp.jsonand askillssymlink to<codexHome>/skills), deploys installed roles to<codexHome>/rolebox, and registers one managed block in<codexHome>/config.toml, with the Codex home resolved from$CODEX_HOMEwhen set and non-blank and~/.codexotherwise. The plugin starts the rolebox MCP server (rolebox mcp, also exported asrolebox/codex), a newline-delimited JSON-RPC 2.0 stdio server exposing 15 canonical tools — hashline_read/hashline_edit, memory_write/memory_recall/memory_list, web_search/web_read/web_fetch, asset_search/asset_inspect/asset_validate, reference_search, load_role_skill, signal and interactive_terminal — with nosession_*,dispatch_*,loop_*,task_*orgraph_*tools, no role switching, TUI, hot reload, extension loader or hooks-driven activation; the generated layout, the MCP protocol surface and those non-goals are documented in docs/codex.md. -
dsh roles reload in-process, without a restart (ce96f44) —
POST /rolebox/reload(served by the dsh role-switch route, with the monitor panel's "Reload roles" control as its entry point) performs an in-process, non-destructive role reload: roles are re-discovered and re-resolved into the live containers in place and the agent catalog is re-synced, so installing or editing a role no longer needs a host restart. Because consumers capture the resolved-role snapshot by reference, the four role-snapshot tools (asset_search,asset_inspect,asset_validate,reference_search) are rebuilt as one disposable generation and the lazy skill catalog is invalidated, while discovery and resolution run against local containers and every post-swap mutation is guarded by an in-memory rollback — a failed reload leaves the previous roles, role functions and open-role registry in place, so no partially swapped state is observable.
Bug Fixes
-
Dispatch teardown always releases its resources —
DispatchManager.dispose()now runs its release tail in afinally, so a throwing state flush can no longer leave the watchdog timers running or the state lock held. Pending debounced progress writes are flushed and their timers cleared on teardown, so no write can fire after a manager is disposed. -
Dispatch health is config-aware — a stopped budget sampler now reads as a stopped pipeline only when a budget limit is actually configured, so a manager with no configured limits no longer reports unhealthy merely because its sampler was never armed, and a manager with configured limits no longer reports healthy while its sampler is dead.
-
Process-fatal events are recorded without changing host behaviour — a new observation-only reporter flushes rolebox state and writes one structured log entry on
uncaughtException/unhandledRejection. It never exits, re-throws, or alters the host's exit code, installs and removes exactly its own process listeners, and reports at most one event per process. -
Graph Engine v2 correctness fixes (7a7c67e) — Persistence DTOs are derived from the runtime types and validated per node, so a partial node state can no longer load as valid and silently disable the
max_total_*budget gates after recovery; join quorum is a discriminated union that carries its count instead of a quantity-free member each consumer read differently; a dispatch kickoff that contends for the advancing lock is deferred and replayed instead of dropped, so a graph cannot sit inexecutingwith no work in flight;on_conditionloop-backs consume a traversal, which makesmax_traversalsenforceable for that shape; and the approval payload is serialized before the node is marked complete, so an unserializable payload can no longer complete a node and strand its downstream join. The same pass stops escalate propagation from walking revise back-edges, validatespartialApprovemember lists, scopes the terminal-notification dedupe key to the engine epoch, returns approval reports instead ofvoid, and routesgraph_cancelthrough the authorityCancelScopeReportrather than matchingerrorReasontext. -
Session tool output hardened (62298b1) —
formatDateno longer throws on a non-finite or out-of-range timestamp, so one malformed session record can no longer abort a whole tool call; durations no longer render asNaNh NaNm; markdown table cells are escaped so a title containing|or a newline cannot break the table; number grouping is locale-independent; andformatDiffis a real LCS unified diff with hunk headers, context lines and a missing-newline marker instead of an index comparison that marked every line of a file as changed when a single line was inserted at the top. -
The CLI checkpoint list tolerates malformed rows (8855f9c) —
rolebox checkpoint listcoerces and validates each row as it reads the checkpoint file, tolerates a missing or unparseablecreated_atthrough the shared timestamp helper, and keeps nulls out of the sort comparator, so a single bad entry (a missing phase or a numeric task id) no longer throwsTypeErroroutside every try and reduces the command to a bare header with no rows. -
Truncation budgets display columns (9615bfb) —
truncate()sliced UTF-16 code units, so a wide or CJK title could overrun its column budget and a cut could split a surrogate pair intoU+FFFD; it now budgets display columns, which also composes with the padding helpers. Behavior change: a non-ASCII string truncates at roughly half the previous character count, because each wide character costs two columns. -
Model-alias advisories are de-duplicated per cache generation (45344c1) — Each unresolvable model is reported once per cache generation instead of once per role, so a config with N such roles no longer emits N identical four-line advisory logs on every discovery and hot reload;
initModelResolverre-arms the reports so the next load after a config edit still warns, and a non-mappingmodel_aliasesvalue is rejected instead of registering bogus numeric aliases.
Refactors
-
Harness entries consolidated under
src/entries(85b2423, 9655230, 45406e4) — The three harness entries now live insrc/entries(opencode.ts,pi.ts,dsh.ts) and publish atdist/entries/*;dist/index.js,dist/pi-extension.jsanddist/dsh-plugin.jsare still generated as re-export aliases, so existing out-of-package harness configs keep working, and the alias build unlinks stale legacy declarations so a previously built outDir cannot publish them. The opencode entry'sroleFunctionsMapre-export is restored. -
One shared text-format module (1c98377, 13db0d1) — The duplicated duration, truncation, padding, bar and byte formatters now delegate to a single pure
src/utils/text-format.ts, with documented invalid-input sentinels, surrogate-safe truncation, ANSI- and East-Asian-width-aware measurement, markdown cell escaping and locale-independent number grouping.