refactor(prism-facet): strip content into ClawPrompts; expose registration API #4
Reference in New Issue
Block a user
Delete Branch "feat/registration-api-strip-content"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Makes PrismFacet a pure framework. All Hangman-Lab-specific content (always router, pcexec-convention prompt, fabric-chat-injector hook) moves to a new sibling plugin ClawPrompts (private, at hzhang/ClawPrompts) which registers them via the new
globalThis.__prismFacet.addRouter / addRulecross-plugin API.New core/cross-plugin-api.ts is installed at module-import time so a consumer plugin loaded before PrismFacet still finds a working API.
rule-store now tiers rules into
persistent(rules.json, mutated by the prompt-rules tool) andexternal(in-memory, registered by other plugins via the API). Persistent overrides external on conflict.Nothing in this PR is plumbed to TODO(phase-2) fabric xType DM-only narrowing yet — that work still belongs in Fabric.OpenclawPlugin first.
Strip all Hangman-Lab-specific content out of PrismFacet so it can be reused by any project. Content (always router, pcexec-convention prompt, fabric-chat-injector hook) moves to the new sibling plugin ClawPrompts. Mechanism additions: - `globalThis.__prismFacet` cross-plugin API installed at module-import time (so consumers loaded before PrismFacet can still register): .addRouter(name, resolveFn) .addRule(router, key, { file }) - core/rule-store: tier rules into `persistent` (rules.json, mutated by the prompt-rules admin tool) and `external` (in-memory, registered by other plugins via the API). Persistent overrides external on conflict. - core/router-loader: addExternalRouter() for programmatic registration into the same map the file-based loader uses. - index.ts: drops registerFabricChatInjector wiring, registerBeforePromptBuild remains. Removed (now shipped from ClawPrompts): - plugin/routers/always.ts - plugin/hooks/fabric-chat-injector.ts - plugin/prompts/pcexec-convention.md - plugin/rules.json: now `{}`; ClawPrompts registers its rule externally What still lives in PrismFacet: - before_prompt_build hook (the wiring between routers/rules and the agent's system prompt) - prompt-rules admin tool (lists + mutates persistent rules) - file-based routersDir / rulesFile scanning (kept for operator ad-hoc use; ClawPrompts uses the API instead) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Sim e2e on dind-t2 — 7 plugins listening, drain verified
Gateway start log (load order is claw-prompts first, prism-facet later):
Runtime sanity after restart confirms ClawPrompts's registrations actually landed:
Tiered view shows the rule came in via the external tier (the cross-plugin API), not persistent (rules.json) — i.e. ClawPrompts owns it, not PrismFacet.
Two fixes piggybacked in this PR after the first restart attempt surfaced bugs:
loadRoutersno longermap.clear()s blindly — that wiped externally-registered routers added before PrismFacet'sregister(). Now it only deletes file-based routers that disappeared between loads; API-registered routers (filePath sentinel<external: ...>) survive.scripts/install.mjschowns installed dir to root (same hardening Meridian + ClawPrompts have) — fixes the openclaw 2026.5 "suspicious ownership" block when source was tar-pushed from a uid-1000 host.ClawPrompts repo: https://git.hangman-lab.top/hzhang/ClawPrompts (private, initial commit on main:
2d685c6).TODO(phase-2) fabric xType DM-only narrowing — still NOT done. The fabric-chat-injector hook today fires for any fabric channel triggered turn; Fabric.OpenclawPlugin would need to expose per-channel type info via
__fabriccross-plugin API first. Tracked in the hook's comment.