CLI Reference
Commands
axm-anvil move
Move top-level symbols (classes, functions, constants) between Python
files atomically. Wraps the MoveTool MCP tool.
axm-anvil move <from_file> <to_file> <symbols> [--dry-run] [--check] [--strict] [--path <root>] [--shared-helpers <strategy>] [--reexport] [--rename '<json>'] [--insert-after <symbol>] [--no-include-helpers] [--side-effect-decorators '<csv>']
| Argument | Description |
|---|---|
from_file |
Source Python file path |
to_file |
Target Python file path |
symbols |
Comma-separated symbol names to move |
--dry-run |
Preview the move without writing files |
--check |
Simulate the move, including import-cycle detection, without writing. Fails with ImportCycleError if the move would introduce a new cycle |
--strict |
Fail (non-zero exit) on a requested symbol that is absent from the source module instead of skipping it with a warning. Default (--no-strict) skips an absent symbol and records a warning |
--path |
Workspace root (default: .) |
--shared-helpers |
Strategy when a helper is used by both moved and remaining symbols: duplicate (default, copies the helper and emits a warning) or error (abort with SharedHelpersError) |
--reexport |
Leave callers untouched; inject from new_module import <Symbol> # re-export for backwards compat into the source module for gradual migration |
--rename |
JSON object string mapping old symbol names to new ones (e.g. '{"OldName": "NewName"}'). Renames moved definitions and rewrites all caller references to the new name. Incompatible with --reexport |
--insert-after |
Name of an existing top-level symbol in the target module; moved blocks are spliced immediately after it. Omitted (default) appends the blocks at the end of the target; naming an absent symbol appends at the end and records a warning on MovePlan.warnings. Imports and constants keep their usual end-of-file placement regardless |
--include-helpers / --no-include-helpers |
Whether to copy transitively-referenced local helpers and constants into the target. --include-helpers (default) copies private helper symbols alongside the moved symbol. --no-include-helpers leaves the moved code referencing those helpers without copying them, short-circuits the --shared-helpers classification, and records a include_helpers=False: not copied into target: <names> warning on MovePlan.warnings. Imports required by the moved code are always copied regardless |
--side-effect-decorators |
Comma-separated extra side-effect decorator dotted-names (e.g. 'mylib.register') that extend the built-in SIDE_EFFECT_DECORATORS whitelist (see Python API). When a moved symbol carries a matching decorator, a non-blocking warning is recorded on MovePlan.warnings; the move always proceeds |
MCP Tools
MoveTool
Registered as anvil_move via the axm.tools entry point. Accepts the
same fields as the CLI and returns a ToolResult with the move plan
(moved symbols, copied imports/constants, warnings).
MoveTool
Bases: AXMTool
Move top-level symbols between Python files atomically.
Registered as anvil_move via the axm.tools entry point.
Delegates to :func:axm_anvil.core.move.move_symbols and adapts
exceptions into ToolResult(success=False).
Source code in packages/axm-anvil/src/axm_anvil/tools/move.py
| Python | |
|---|---|
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | |
name
property
Return tool name for registry lookup.
execute(*, path='.', symbols='', from_file='', to_file='', dry_run=False, shared_helpers='duplicate', shared_helpers_module=None, reexport=False, rename=None, check=False, strict=False, insert_after=None, include_helpers=True, side_effect_decorators=None, **kwargs)
Move symbols (CSV) from from_file to to_file.
Parameters
path:
Workspace root used to resolve relative from_file / to_file
and to constrain caller updates.
symbols:
Comma-separated list of top-level symbol names to move. Empty
entries are ignored.
from_file:
Source Python file. Relative paths are resolved against path.
to_file:
Target Python file. Relative paths are resolved against path.
dry_run:
When True, compute the :class:MovePlan without writing.
shared_helpers:
Policy for helpers used by both moved and remaining symbols:
"duplicate", "extract", or "error".
shared_helpers_module:
Target module path used when shared_helpers="extract".
reexport:
When True, leave callers untouched and inject a re-export in
the source module. Incompatible with rename.
rename:
Optional JSON object string mapping old symbol names to new ones
(e.g. '{"OldName": "NewName"}'). Parsed to dict[str, str]
and forwarded to :func:move_symbols. Invalid JSON yields a
success=False result.
strict:
When True, a requested symbol absent from the source module
raises (surfaced as success=False) instead of being silently
skipped with a warning. When False (default) the current
skip-and-warn behaviour is preserved.
insert_after:
Optional name of a top-level symbol in the target module; moved
blocks are spliced immediately after it. When None blocks
append at the end; an absent name appends at the end with a
warning.
include_helpers:
When True (default) transitively-referenced local helpers and
constants are copied into the target. When False they are not
copied (a warning enumerates the un-copied names); imports are
still copied regardless.
side_effect_decorators:
Optional comma-separated list of extra side-effect decorator
dotted-names that extend the built-in SIDE_EFFECT_DECORATORS
whitelist. A moved symbol decorated with a matching decorator
yields a non-blocking warning on the plan.
Returns
ToolResult
success=True with a MovePlan summary on success; otherwise
success=False with a message describing the failure
(missing symbol, collision, shared helpers, validation error).
Source code in packages/axm-anvil/src/axm_anvil/tools/move.py
| Python | |
|---|---|
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | |
ExtractTool
Registered as anvil_extract via the axm.tools entry point (reachable as
axm anvil_extract on the CLI and via MCP). Extracts top-level symbols from
from_file into a new to_file (created on disk, parent directories
included), copying the same transitive dependencies (imports, local
helpers, constants) as anvil_move and rewriting every cross-file caller
(from old import X to from new import X). It is a thin specialisation of
MoveTool where the target module does not yet exist:
extracting into a pre-existing module that already defines one of the
requested symbols fails with success=False (no silent overwrite). With
dry_run=True the plan is computed without leaving any file on disk.
reexport and check are intentionally not exposed (meaningless against a
freshly created module). The returned ToolResult carries the same shape
as anvil_move (moved, dependencies_copied, callers_updated,
warnings, shared_helpers_detected, files_modified).
ExtractTool
Bases: AXMTool
Extract top-level symbols from a module into a brand-new module.
Registered as anvil_extract via the axm.tools entry point.
Delegates to :func:axm_anvil.core.extract.extract_symbols (itself a
thin adapter over the move pipeline) and adapts exceptions into
ToolResult(success=False). The result shape matches anvil_move.
Source code in packages/axm-anvil/src/axm_anvil/tools/extract.py
| Python | |
|---|---|
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
name
property
Return tool name for registry lookup.
execute(*, path='.', symbols='', from_file='', to_file='', dry_run=False, shared_helpers='duplicate', shared_helpers_module=None, rename=None, strict=False, insert_after=None, include_helpers=True, side_effect_decorators=None, **kwargs)
Extract symbols (CSV) from from_file into a new to_file.
Parameters
path:
Workspace root used to resolve relative from_file / to_file
and to constrain caller updates.
symbols:
Comma-separated list of top-level symbol names to extract. Empty
entries are ignored.
from_file:
Source Python file. Relative paths are resolved against path.
to_file:
Target Python file to create. Relative paths are resolved
against path; missing parent directories are created.
dry_run:
When True, compute the :class:MovePlan without writing (and
without leaving a scaffolded target on disk).
shared_helpers:
Policy for helpers used by both moved and remaining symbols:
"duplicate", "extract", or "error".
shared_helpers_module:
Target module path used when shared_helpers="extract".
rename:
Optional JSON object string mapping old symbol names to new ones
(e.g. '{"OldName": "NewName"}'). Invalid JSON yields a
success=False result.
strict:
When True, a requested symbol absent from the source module
raises (surfaced as success=False) instead of being skipped
with a warning.
insert_after:
Optional name of a top-level symbol in the target module after
which extracted blocks are spliced. None appends at the end.
include_helpers:
When True (default) transitively-referenced local helpers and
constants are copied into the target.
side_effect_decorators:
Optional comma-separated list of extra side-effect decorator
dotted-names extending the built-in whitelist.
Returns
ToolResult
success=True with a plan summary on success; otherwise
success=False with a message (missing symbol, collision,
shared helpers, validation error).
Source code in packages/axm-anvil/src/axm_anvil/tools/extract.py
| Python | |
|---|---|
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
RenameTool
Registered as anvil_rename via the axm.tools entry point (so it is
reachable as axm anvil_rename on the CLI and via MCP). Renames top-level
symbols in place — definition and internal usages — and rewrites every
cross-file caller (from mod import Old import alias and usages). Pass a
mono-symbol old/new pair, or a mapping JSON object (e.g.
'{"OldName": "NewName"}') for batch renames. dry_run previews the plan
without writing; strict turns an absent symbol into a success=False
result instead of a skipped-with-warning. reexport is intentionally not
exposed (incompatible with rename). The returned ToolResult carries
renamed, callers_updated, warnings, and files_modified.
RenameTool
Bases: AXMTool
Rename top-level symbols in place, rewriting cross-file callers.
Registered as anvil_rename via the axm.tools entry point.
Delegates to :func:axm_anvil.core.rename.rename_symbols and adapts
exceptions into ToolResult(success=False). Mono-symbol renames use
--old/--new; batch renames pass a --mapping JSON object
(symmetric with the rename JSON of :class:MoveTool). reexport
is not exposed (incompatible with rename, per MoveTool.execute).
Source code in packages/axm-anvil/src/axm_anvil/tools/rename.py
| Python | |
|---|---|
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |
name
property
Return tool name for registry lookup.
execute(*, path='.', file='', old='', new='', mapping=None, dry_run=False, strict=False, **kwargs)
Rename symbol(s) in file and rewrite cross-file callers.
Parameters
path:
Workspace root used to resolve a relative file and to
constrain caller discovery.
file:
Python file defining the symbols. Relative paths resolve against
path.
old / new:
Mono-symbol rename: rename old to new. Ignored when
mapping is provided.
mapping:
Optional JSON object string mapping old names to new ones
(e.g. '{"OldName": "NewName"}') for batch renames. Invalid
JSON yields a success=False result.
dry_run:
When True, compute the :class:RenamePlan without writing.
strict:
When True an absent symbol raises (surfaced as
success=False); when False (default) it is skipped with
a warning.
Returns
ToolResult
success=True with a rename summary (renamed,
callers_updated, warnings, files_modified) on
success; otherwise success=False with a failure message.
Source code in packages/axm-anvil/src/axm_anvil/tools/rename.py
Python API
The full Python API — every public function, model, and exception with its signature and docstring — is rendered from source under Python API. This section captures only the cross-cutting semantics that span several symbols.
extract_symbols — thin adapter over move_symbols for the extract
case: the target module is created rather than amended. When
target_path does not exist it is scaffolded as an empty module so the move
pipeline can fill it; a pre-existing target already defining a requested
symbol raises SymbolAlreadyExistsError (no silent overwrite). A
dry_run=True call removes any scaffolded target — and any directories it
created — before returning, leaving disk state byte-identical. All other
parameters mirror move_symbols and are forwarded verbatim; reexport and
check are not exposed.
rename_symbols — renames the top-level symbols in mapping in place
in file and rewrites every cross-file caller discovered under the
workspace root. A rename onto a name that already exists in the module is
refused with SymbolAlreadyExistsError (no duplicate definition). Caller
rewriting is pattern-based on the import statement; shadowing, alias chains,
and re-exports/star imports are deferred to a later tier (see the function
and module docstrings).
SIDE_EFFECT_DECORATORS — the default whitelist of decorator
dotted-names whose primary purpose is to register the decorated symbol with
an external registry as an import-time side effect (e.g. app.route,
pytest.fixture / bare fixture, celery.task, click.command). When a
moved FunctionDef/ClassDef carries a matching decorator — in bare
(@fixture), dotted (@pytest.fixture), or call (@app.route("/x")) form
— move_symbols records a non-blocking warning on MovePlan.warnings. The
move is never blocked. Callers extend the whitelist via the
side_effect_decorators parameter of move_symbols (or
--side-effect-decorators on the CLI).
SymbolNotFoundError — a requested name absent from the source module's
top-level symbols is skipped by default: move_symbols drops it and
records a skipped '<name>': not a top-level symbol in source entry on
MovePlan.warnings. The CLI and the anvil_move MCP tool surface that
warning and still exit successfully. Pass strict=True (or --strict) to
raise on the first absent name instead.
ImportCycleError — raised by move_symbols when the requested move
(or its caller rewrites) would introduce a new import cycle. Pre-existing
cycles are ignored. Raised when check=True or during a normal
(non-dry-run) write; a pure dry_run=True call skips the raise to preserve
the preview contract.