feat(6.8): role-template management UI — versioning, full + augmented types#39
Merged
fstamatelopoulos merged 8 commits intomainfrom May 9, 2026
Merged
Conversation
…uction
New top-level "Agents" tab in the web UI for editing the instruction
templates each agent role reads. Each role gets:
- A bundled cf² default (always selectable, read-only, never deletable).
- Any number of saved versions stored under
`~/.cfcf/templates-managed/<name>/{manifest.json, v_<id>.md}`.
- A "Promote to production" action that writes the selected version's
content to `~/.cfcf/templates/<name>` — the existing user-global
override path that `getTemplate()` already reads. Reverting to default
deletes the override file so cf² falls back to the embedded template.
No runtime changes to agent spawning.
Decoupled from the prior "blocked on 6.11/ADLC" framing: the user's
vision (edit + version + promote) operates at per-role-template
granularity — whatever role abstraction ADLC eventually settles on
can layer on top of this without rework.
**Shipped (round 1)**
- `packages/core/src/role-templates.ts` — versioning manager.
list / get / save / update / delete / promote, manifest self-heal
on corruption, orphan detection, automatic revert when deleting the
promoted version, automatic override-file refresh when editing it.
Bundled defaults sourced via a new `getEmbeddedTemplate(name)`
exported from `templates.ts`.
- HTTP routes at `/api/role-templates/*` with uniform error envelope.
- Web UI: new `/agents` route (Header link between Memory and Settings),
tab strip across managed roles, version selector, monospace textarea
editor, action buttons (Edit / Save as new version / Save changes /
Promote / Revert / Delete), inline help block. Deep-linkable via
`/agents?template=<name>`.
**Managed templates (round 1)**: cfcf-architect-instructions.md,
cfcf-judge-instructions.md, cfcf-documenter-instructions.md,
cfcf-reflection-instructions.md, process.md.
**Out of scope (deferred follow-ups)**: dev-role custom-directions
block (Tier-2 from the original 6.8 design — needs the sentinel-merge
insertion-point design first), Product Architect / Help Assistant
system-prompt management (their prompts are programmatically assembled),
per-project override management UI, diff viewer, search-within-content.
**Tests**: 30 unit tests in `role-templates.test.ts` (every flow +
manifest corruption recovery + cross-template isolation), 15 endpoint
tests in `routes/role-templates.test.ts`, 3 new route-parser tests for
the new `/agents` + `?template=` routes. All 834 core+cli+web tests
pass; clean typecheck; web build clean.
Pre-existing `app.test.ts` config-merge failure on main is unrelated
(verified earlier in this iter).
**Design doc**: `docs/design/role-template-management.md`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…indicator Two small follow-ups on top of 7c67f82: 1. The page only honoured `initialTemplate` on first mount; subsequent hash changes (browser back/forward through `?template=...`) were silently ignored. Added an effect that syncs activeName when the prop changes (and the requested template exists in the loaded summary list). 2. When in edit mode with local changes, the page heading now shows a yellow "• unsaved changes" indicator. Doesn't replace the button-disabled-state cue; just adds a visual signal so the user doesn't lose track of dirty state when scrolled away from the action buttons. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brief mention of all five top-level web tabs in the Server / web UI concept block. Adds discoverability for the new Agents tab without expanding into a full guide section (the inline help on the page itself covers the mechanics). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…d version The previous readOnly gate was `!isEditing || selectionIsDefault` — so clicking Edit on the bundled-default tab left the textarea read-only and the user couldn't type at all. The intent was "we never overwrite the bundled-default file on disk" but the user still needs to TYPE in the editor to draft a new version that gets saved via "Save as new version". The save action is what's gated by selection-is-default (no "Save changes" button on default — only "Save as new version"); typing should always work in edit mode. Updated the inline help below the editor to reframe accordingly: "You're editing a copy of the bundled default. Click Save as new version to fork your changes into a new version (the cf²-shipped default itself stays untouched and remains available in the dropdown)." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a second customisation mode alongside round-1's full-template
editing. Each saved version now has a type:
- type="full": body REPLACES the bundled default at promote time.
Maximum flexibility (delete sections, restructure);
doesn't auto-pick-up cf² upgrades. UI shows a
"Forked from cf² vX.Y.Z" badge so the user knows
their version may be drifting.
- type="augmented": body is APPENDED to the live bundled default at
promote time AND every server boot. The bundled
default is read live (never duplicated on disk),
so when cf² ships a new default, the user's
extension automatically rides along on the new
version. THIS is the upgrade-friendly mode.
Composition lives in `composeForOverride(name, type, body)`:
- "full" → body verbatim
- "augmented" → getEmbeddedTemplate(name) + AUGMENTATION_SEPARATOR + body
Boot-time auto-recompose: every cfcf server start runs
`refreshAugmentedOverrides()` which, for every managed template whose
promoted version is augmented, re-writes the override file IF the
on-disk content differs from the live composition. Cheap idempotent
pass, single log line on change. Full versions are explicitly NOT
touched (frozen by design — auto-merging would be wrong).
UI changes:
- New "Augment" button next to "Edit" in the action row. Augment
always creates a new augmented version on top of the bundled
default (regardless of which version is currently selected).
- Split editor view for augmented versions: bundled default
rendered read-only at the top (~25vh, smaller for visual emphasis
on the extension) + extension textarea below (~30vh) with a
placeholder showing example custom directions. Editing toggles
only the extension.
- Forked-from-cf²-vX.Y.Z hint below the selector for full versions.
- Version dropdown suffixes each entry with its type.
- "Creating new <type> version" indicator in the heading during
create flows.
Also addresses the round-1 polish requests:
- Status messages moved above the version-selector row.
- Directional words removed from messages ("click Promote" not
"click Promote below").
- Editor textarea is now editable on the bundled-default tab in
edit mode (was read-only in round 1; the user couldn't type to
draft a fork).
Back-compat: round-1 manifests without a `type` field are read as
type="full" automatically. Existing tests pass unchanged.
API extension: POST /api/role-templates/:name/versions accepts an
optional `type` field defaulting to "full". Invalid values return 400.
Tests:
- 41 unit tests in role-templates.test.ts (was 30) — augmented
composition, boot refresh idempotency, full-versions-untouched,
back-compat with round-1 manifests.
- 17 endpoint tests (was 15) — type validation in POST /versions.
- 845 total core+cli+web pass.
Pre-existing app.test.ts config-merge failure on main is unrelated.
Design doc + plan + CHANGELOG updated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…match agent execution flow The user spotted that the tab labelled "Workspace Process" is functionally the **dev agent's** primary instruction template — the file's content literally opens with "You are a dev agent working on a cfcf-managed workspace. This document defines how you operate within each iteration." The historical name `process.md` predates the explicit per-role instruction files (cfcf-architect-instructions.md, etc.) so it never got renamed to `cfcf-dev-instructions.md`. The display name in the Agents tab should reflect the role, not the historical filename. The inline "Template file: process.md" hint on the page still surfaces the real filename for users who grep the override directory. Also reorders the tabs to match the natural agent execution sequence within an iteration loop: Solution Architect → Developer → Judge → Reflection → Documenter (Architect runs pre-loop and on refine_plan / NEEDS_REFINEMENT; dev does the work; judge assesses; reflection optionally analyses across iterations; documenter runs post-SUCCESS. Reading top-to- bottom in the UI now mirrors the firing order.) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e" claims + document new features A documentation audit pass over all user-facing docs to align with recent changes (items 6.30, 6.31, 6.33, 6.8 rounds 1+2). Stale "manually-invoked SA via cfcf review = interactive" framing removed from: - README.md (top-level policy heads-up) - docs/guides/installing.md (Claude Code install recommendation) - docs/guides/cli-usage.md (cfcf init warnings section) - docs/guides/workflow.md (adapter-choice block) - docs/guides/troubleshooting.md (harness-policy warning entry) Reality (verified in code 6.30): ALL architect spawns are headless `claude -p` regardless of how they're invoked. `cfcf review` is just a polling client to a server-side background spawn — there's no `stdio: "inherit"` anywhere in the architect path. Only PA + HA truly take over the user's shell. All five surfaces now reflect this. Also fixed: - docs/guides/installing.md: dropped "auto-architect" qualifier from the unattended-roles enumeration; architect is always unattended. New feature documentation: - docs/api/server-api.md: added `GET /api/agents/models`, `POST /api/agents/refresh-ollama-models` (item 6.33), and the full `/api/role-templates/*` surface (item 6.8). - docs/guides/cli-usage.md: added `cfcf server reap` section (item 6.31, v0.21.0); ollama-models auto-refresh + button reference (item 6.33); five-tab web UI navigation overview (Workspaces / Memory / Agents / Settings / Help) including a brief description of the new Agents tab and its full+augmented version types. - docs/guides/manual.md: expanded Agents-tab bullet to mention round-2 full vs augmented version types + execution-order tab layout. - docs/README.md: refreshed the directory map with the design docs + guides that have been added since the last update (role-template-management.md, anthropic-policy.md, etc.). - CLAUDE.md: added bullets for role-template management (item 6.8), orphan reaper (item 6.31), ollama auto-refresh (item 6.33), and the architect-always-unattended classification (item 6.30). File structure section now lists role-templates.ts, orphan-reaper.ts, ollama-detection.ts, AgentTemplatesPage, and the cfcf server reap CLI verb. Plan + decisions-log + design + research files left unchanged — those are historical and shouldn't be retroactively edited. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… panel (25vh) The single-textarea FullEditor was 60vh tall while the augmented-mode "cf² standard template (read-only)" panel was 25vh. Switching between the two views (e.g. Default tab → an augmented-version tab) felt jarring because the bundled-default content rendered at noticeably different heights. Aligned FullEditor to 25vh as well. The textarea keeps `resize: vertical` so users editing a long full version can drag it taller — just lowers the floor height from 60vh to 25vh for consistency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Adds a top-level "Agents" tab to the web UI for managing each agent role's instruction template. Per-role versioning + promote-to-production with two complementary modes:
full— body replaces the bundled cf² default. Maximum flexibility (delete sections, restructure); doesn't auto-pick-up cf² upgrades. UI shows a "Forked from cf² vX.Y.Z" badge so users know their version may be drifting.augmented— body is appended to the live bundled default at promote time and every server boot. The bundled default is read live (never duplicated on disk), so when cf² ships a new template, the user's extension automatically rides along on the new version. Upgrade-friendly by default.Hooks into the existing user-global override path (
~/.cfcf/templates/<name>— whatgetTemplate()already reads) so the runtime is unchanged. Promote writes the (composed-for-augmented) content there; revert-to-default deletes it.What's new
Core (
packages/core/src/role-templates.ts)listManagedTemplates,getManagedTemplate,getVersionContent,saveVersion,updateVersion,deleteVersion,promoteVersion,findOrphanedVersions,refreshAugmentedOverrides.~/.cfcf/templates-managed/<name>/{manifest.json, v_<id>.md}. Manifest self-heals on corruption; missing version files fall back gracefully.typefield) read back astype: "full"automatically — no migration needed.getEmbeddedTemplate(name)newly exported fromtemplates.tsfor read-only access to the bundled default.Server
/api/role-templates/*endpoints (list / get / per-version content / create / update / delete / promote) with uniform{ error: string }envelope.refreshAugmentedOverrides()called fromstart.tsafter the orphan reaper). Cheap idempotent pass — only writes when on-disk content actually differs from live composition. Single log line on change. Full versions are not touched (frozen by design).Web UI
/agentsroute (Header link between Memory and Settings). Optional?template=<name>query for deep-linking.•marker.Edit(full-edit mode) /Augment(augmented-edit mode) /Promote/Revert to default/Delete version.resize: verticalhandle.<label> — <type> (<date>) — promotedfor each entry. Bundled default always selectable, never deletable.Naming + ordering polish (informed by user feedback)
process.mdtab from "Workspace Process" to "Developer" — the file's content literally opens with "You are a dev agent…", so it functionally serves as the dev role's primary instruction template even though the historical filename predates the per-role-instructions convention.Documentation
docs/design/role-template-management.md.cfcf reviewis interactive" claims removed (verified in code: SA is headless on all paths). New endpoints documented indocs/api/server-api.md.CLAUDE.mdgains bullets for role-template management, orphan reaper, ollama auto-refresh, and the architect-always-unattended classification.Test plan
bun run typecheck— cleanbun test packages/core packages/cli packages/web— 845/845 pass (41 unit tests inrole-templates.test.ts, 17 endpoint tests, 3 route-parser tests)cd packages/web && bun run build— clean~/.cfcf/templates/<name>contains the body verbatim<bundled default> + separator + <extension>[server] Re-composed N augmented role-template override(s)…log line + override file is back to<fresh bundled> + <extension>Notes
context-assembler.generateInstructionContent(), not file-loaded — needs a different sentinel-merge insertion-point design); Product Architect / Help Assistant system-prompt management (their prompts are programmatically assembled); per-project (workspace-local) override management UI; diff viewer between versions.app.test.tsconfig-merge failure onmainis unrelated to this PR (verified earlier in iter-6 viagit stash && bun test).mainhistory clean if you'd prefer; happy either way.