Skip to content

feat: manage CLAUDE.md/AGENTS.md as a delimited begin/end block instead of overwriting the whole file#33

Open
dehuaichendragonplus wants to merge 2 commits into
FunplayAI:mainfrom
dehuaichendragonplus:feat/projectskills-managed-block
Open

feat: manage CLAUDE.md/AGENTS.md as a delimited begin/end block instead of overwriting the whole file#33
dehuaichendragonplus wants to merge 2 commits into
FunplayAI:mainfrom
dehuaichendragonplus:feat/projectskills-managed-block

Conversation

@dehuaichendragonplus

Copy link
Copy Markdown
Contributor

Why this change is needed

Today SyncClaude / SyncCodex regenerate the entire CLAUDE.md / AGENTS.md on every sync (File.WriteAllText(path, BuildXxxContent(...))). Any content a user adds to these files — project architecture notes, coding conventions, pitfalls, other (non-Funplay) agent instructions — is silently destroyed the next time Project Skills syncs (after a package upgrade, or after toggling platforms).

Real incident that motivated this: in a production project, a hand-authored CLAUDE.md (hundreds of lines of project-specific guidance) still carried the Funplay managed marker at its top from an earlier generation. A later sync overwrote the whole file back down to Funplay's ~40 generated lines, losing everything. The single-line marker is an unreliable ownership signal — it survives a hand-rewrite of the body, so IsManagedFile reports "managed" while the body is actually the user's.

Root problem: Funplay treats these shared root files as wholly-owned, but they are shared surfaces users legitimately edit.

Change approach

Manage only a delimited block, never the whole file:

  • Reuse the existing ManagedMarker as the begin marker (so IsManagedFile and version-status detection keep working) and add an end marker <!-- /Funplay Unity MCP managed project skills -->.
  • WriteManagedBlock(path, title, block):
    • absent/empty file → create title + block
    • complete begin+end block present → replace only the block region; preserve everything before begin and after end
    • begin marker but no end (legacy whole-file marker, or an edited/corrupted block) → skip with a warning; its managed extent is unknowable, so refuse to guess and clobber
    • no begin marker → append the block below the user's existing content (touching nothing above)
  • RemoveManagedBlock (platform disabled) strips just the block; deletes the file only if nothing but a bare title/whitespace remains. Files without a block fall back to the legacy delete guard.
  • BuildClaude/CodexAgentsContent split into Build*ManagedBlock (block body only, no # CLAUDE.md title).
  • Deliberately unchanged: IsManagedFile, the version-status / Upgrade Skills detection, and cursor rules. Status detection matches markers by content (Contains/IndexOf), independent of position, so it works whether markers sit at the top of a fully-managed file or inside a block.

Benefits

  • User content in CLAUDE.md / AGENTS.md is never destroyed again — the MCP HTTP transport can fail to restart after Unity domain reload because previous listener is not fully stopped #1 safety issue with the current behavior.
  • Funplay guidance stays updatable across versions (the block is replaced in place), so Upgrade Skills still delivers new guidance without a full-file rewrite.
  • Disabling a platform cleanly removes just Funplay's block instead of deleting a file the user may have added their own content to.
  • Backward compatible: a file Funplay fully generated in the old scheme (marker at top, no end marker) is treated as legacy and skipped-with-warning rather than mis-spliced; new syncs create the delimited-block form going forward.

Test results

Verified in a Unity 6000.3.13f1 project (package compiles with zero errors), then exercised WriteManagedBlock / RemoveManagedBlock via reflection over temp files:

Scenario Result
absent file creates # CLAUDE.md + block ✔
hand-authored file (no marker) block appended, user content preserved ✔
file with block, re-sync block replaced in place (v1→v2), user content preserved, old block gone ✔
legacy begin-only marker (no end) unchanged / skipped with warning ✔
RemoveManagedBlock on block + user content block stripped, user content kept ✔
RemoveManagedBlock on block-only file file deleted ✔

Compatibility testing

  • Only affects the claude and codex guidance-file platforms. cursor rules (Funplay-namespaced files under .cursor/rules/) are unchanged; LM Studio / VS Code / Trae / Kiro don't generate a guidance file at all (SupportedPlatforms = { codex, claude, cursor }), so they're unaffected.
  • MCP client connection-config generation (FunplayMCPClientConfigPanel) is untouched.
  • Version-status / Upgrade Skills behavior is unchanged and verified (detection is position-independent, so markers inside a block are detected identically to markers at the top of a fully-managed file).

Checklist

  • Tested in a clean Unity 2022.3+ project (Unity 6000.3.13f1)
  • Verified Funplay > MCP Server opens and starts correctly
  • Did not commit local junk such as .idea/ or .DS_Store
  • Updated CHANGELOG.md

…ad of overwriting the whole file

SyncClaude/SyncCodex previously regenerated the entire CLAUDE.md/AGENTS.md, which clobbered any
hand-authored content a user added (and any content that survived from a prior version). They now
manage only the region between the managed begin marker and a new end marker
(<!-- /Funplay Unity MCP managed project skills -->), preserving everything outside it:
  - absent/empty file        -> create title + block
  - complete begin..end block -> replace just the block in place
  - no begin marker           -> append the block below the user's existing content
  - begin marker, no end      -> legacy whole-file marker (or corrupted block) of unknowable
                                 extent; skip + warn rather than clobber
Disabling a platform now strips just the block (deleting the file only if nothing but a bare title
remains) instead of deleting the whole file. BuildClaude/CodexAgentsContent are split into
Build*ManagedBlock (block body, no title). IsManagedFile and the version-status/Upgrade Skills
detection are unchanged -- they match markers by content (Contains/IndexOf), independent of
position, so they work whether markers sit at the top of a fully-managed file or inside a block.

Verified via reflection over temp files: create (title+block), append-to-hand-authored (user
content preserved + block added), in-place update (block replaced, user content kept), legacy
begin-only (skipped unchanged), block removal (block stripped, user content kept), and block-only
file (deleted).
…ithout-end marker

The disable path routed the "begin marker present, end marker missing/out-of-order" state into
DeleteManagedFile, which deletes the file whenever IsManagedFile is true (begin marker present) --
destroying hand-authored content in a file that only had a stale/legacy begin marker. Now only a
COMPLETE begin..end block is stripped; a begin-without-end (or no markers) is left untouched with a
warning, matching WriteManagedBlock's safe handling of the same state.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant