Merge
dotagents._merge
Managed-block merge for init's AGENTS.md/CLAUDE.md (D-init-merge).
init must never clobber a user-customized AGENTS.md. Content owned by dotagents
is delimited by literal marker lines and treated as a block within the file:
create if missing, prepend if present-without-markers, refresh-in-place if the
markers are already there. Detection is by marker presence only, never by prose
matching, so it survives user reformatting.
BEGIN_MARKER = '<!-- dotagents:begin -->'
module-attribute
END_MARKER = '<!-- dotagents:end -->'
module-attribute
merge_block(target, block_source_text, *, force=False, dry_run=False, backup_root=None, begin_marker=BEGIN_MARKER, end_marker=END_MARKER, append=False)
Merge block_source_text (a fully marker-wrapped skeleton file's
contents) into target, returning the branch taken:
"created" / "block-inserted" / "block-refreshed" / "replaced (--force, backed up)".
Never overwrites content outside the markers unless force is True (then
the whole file is replaced, after being backed up to backup_root if the
target pre-exists).
begin_marker/end_marker default to the Markdown/HTML comment pair; pass a
different pair for other comment syntaxes (e.g. #-prefixed markers for TOML).
append puts the block at the END of an existing file rather than the start.
Required for TOML: a [table] header captures every key line that follows it,
so prepending a table would silently swallow the user's existing top-level keys
into our table.
Source code in src/dotagents/_merge.py
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | |
merge_claude_md(target, block_source_text, *, force=False, dry_run=False, backup_root=None)
Same managed-block rule, but for the CLAUDE.md one-liner: if the file
already contains an @AGENTS.md reference (any form), leave it untouched
(branch "skipped (present)") instead of requiring exact marker match --
a bare @AGENTS.md file written by hand still counts as "present".
Source code in src/dotagents/_merge.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | |
timestamped_backup_root(dest)
Source code in src/dotagents/_merge.py
121 122 | |