neuron-explorer
Steering-first neuron explorer for Qwen3.5-4B: push every MLP neuron, keep every rollout, browse the results
Move files and rename symbols with every reference updated, in one call. Your agent keeps its tokens for the actual work.
Developer toolsRust · JavaScriptGitHub @jav-edOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
AI refac: CLI tool that moves source files and updates import paths, module references, and links, designed for scripted and agent-driven workflows
Taken from the repository README
Loading the full README.
Read the full README ↗[!WARNING] Pre-alpha. refac is built for personal use and is not finished. Commands, output, and behavior change whenever I need them to, and there is no guarantee that I keep working on this repository, or that it works for you. If it inshallah turns out useful to you, go ahead, at your own risk.
A CLI tool that moves source files and updates affected import paths, module references, and links across a project, and renames symbols (variables, parameters, functions, methods, fields, types) with every reference in TypeScript/JavaScript, Kotlin, Go, Rust, Python, and Dart. Designed for scripted and agent-driven workflows where an IDE is not in the loop.
The documentation site is built from a separate repository. This repository remains the source of truth for CLI behavior and limitations.
I was building out an AI agent workflow and kept running into the same problem: when an agent needs to move a file, it does it the hard way: it reads every file that imports it, rewrites the paths manually, and hopes it got them all. That is slow, token-heavy, and fragile. A missed import means a broken build, a retry, more context burned.
Moving files and updating references is exactly what refactoring tools are built for. The agent should call the right tool, get a clean result, and move on.
refac is that tool. Three things make it agent-friendly by design:
1. Ships with a skill file, no MCP needed.
The repo includes a .agents/skills/refac-cli/ folder. Drop it into your agent setup and it loads only when relevant. The agent reads what it needs, skips the rest. No persistent context overhead, no server to run.
2. Structured output an agent can actually use.
The --json flag returns a predictable JSON object with status, operation, and operation-specific fields, so the agent can parse the result cleanly without scraping terminal output. Errors return status and a descriptive error.
3. Built-in help in three depths, for agents and humans alike. Everything is inside the binary, so it is there when this repository is not.
refac move -h # a few lines: what the command is and its flags
refac move --help # everything about one command: arguments, rules per language, output, examples
refac guide # in-depth topics across commands: languages, safety, batching, output, servers
refac guide languages # one topic (refac guide all prints every topic)
refac --help is the whole tool on one page: commands, what each language supports, how a change stays safe, what a command costs, exit codes and environment variables. refac doctor checks the language servers and prints the install steps for a missing one.
The docs in this repo are structured for agent navigation, not for sequential reading. Instead of skimming through files yourself, point your agent at the entry point and ask your question directly:
Read @Project_Manag/Docs/doc_Start.md and tell me: [your question here]
Examples:
Read @Project_Manag/Docs/doc_Start.md and tell me how to install this tool.
Read @Project_Manag/Docs/doc_Start.md and explain how Go package moves work.
Read @Project_Manag/Docs/doc_Start.md and tell me what languages are supported and what their limits are.
Read @Project_Manag/Docs/doc_Start.md and explain semantic Rust module moves.
The agent will inshallah navigate to the relevant doc, read only what it needs, and answer directly.
The skill file lives in .agents/skills/refac-cli/, the single source of truth. To wire it into your agent tool, symlink from wherever that tool expects skills rather than copying.
mkdir -p .claude
ln -s ../.agents/skills .claude/skills
Claude Code picks up skills from .claude/skills/. The symlink points back to .agents/skills/, so there is no duplication: one folder, two entry points.
The .claude/ directory is tracked in git. .claude/skills is listed in .gitignore so the symlink itself is not committed (the skills are already tracked under .agents/).
Other agent tools that support a skills or prompts directory can be wired up the same way: just symlink from their expected path into .agents/skills/.
AI and skills: the folder each tool reads (Claude Code, Codex, Gemini CLI, Cursor, VS Code with GitHub Copilot, OpenCode, Kilo Code, Roo Code) and how to fetch only the skill are on refac.javedab.com/docs/ai/skills.
| Language | Files | Directories | Logical modules | Engine |
|---|---|---|---|---|
| TypeScript / JavaScript | ✅ | ✅ | n/a | Oxc parser + TypeScript resolver via Bun; symbol rename via the TypeScript 7 native language server |
| Python | ✅ | ❌ | n/a | Rope (automatic fallback: Pyrefly); symbol rename via basedpyright |
| Rust | ✅ | ❌ | ✅ | rust-analyzer LSP + embedded HIR; symbol rename via rust-analyzer |
| Go | ✅ | ❌ | n/a | gopls (LSP), also for symbol rename |
| Dart | ✅ | ❌ | n/a | Dart analysis server (LSP), also for symbol rename |
| Markdown | ✅ | ✅ | n/a | Native (no external tooling) |
| Kotlin / Android | ✅ | ✅ | n/a | JetBrains Kotlin language server, plus refac's own Android XML layer |
Symbol rename (refac rename) is available for TypeScript / JavaScript, Kotlin, Go, Rust, Python, and Dart. Language servers are started for the command and stopped afterwards, never left running. If one is not installed, the error lists where it looked and names refac doctor <language>, which prints the install steps; refac doctor alone shows every language.
Language is detected by file extension (.ts, .tsx, .js, .jsx, .mts, .cts, .mjs, .cjs, .py, .rs, .go, .dart, .kt, .md). A directory source is routed by what it contains: TypeScript/JavaScript files, or Kotlin files anywhere below it; all other languages require individual files.
Requires Rust 1.99+ (edition 2024). The repository pins Rust 1.99.0, rustfmt, and rust-analyzer in rust-toolchain.toml. Install via rustup if needed.
git clone https://github.com/jav-ed/ai_refac.git
cd ai_refac
scripts/install.sh
scripts/install.sh builds the release binary, links it as ~/.local/bin/refac, and checks that the refac on your PATH is that build and was built from the commit that is checked out. It prints installed and current: refac 0.1.4 (55b157a, built 2026-10-09 20:09 UTC) or stops with the reason. Run it again after every pull, checkout or source change: it takes seconds when nothing changed. refac --version shows the same stamp at any time (+dirty means the sources differ from that commit). The binary is one 36 MB file in target/release; the 1.5 GB around it is build cache (compiled dependencies) that keeps repeat builds fast. Test builds add a separate cache under target/debug (see Project_Manag/Docs/Setup/resource_Use.md).
The link is what makes updates reach every folder and shell: it points ~/.local/bin/refac at target/release/refac, so an update in this checkout will inshallah reach every folder and shell with no copy step. The link stores this checkout's absolute path, so if you move, rename or delete the checkout, refac turns into command not found: run scripts/install.sh once from the new location.
By hand, the same is cargo build --release plus ln -sf "$(pwd)/target/release/refac" ~/.local/bin/refac; cargo install --path . or cp target/release/refac ~/.local/bin/refac give a fixed snapshot that does not follow rebuilds.
The TypeScript and Python helpers (scripts/) stay in the checkout: refac finds them next to the binary (target/release), or in the checkout it was built from, so keep the checkout where you built it. When it cannot find one, the error lists every place it looked.
No Rust? Each release has a Linux x86_64 archive with a SHA256SUMS file, and the binary comes with the helper scripts it needs. Unpack it, link the refac inside it, and check refac --version: the steps are in Release process and in the docs.
Platform: Linux. macOS and Windows are not targets (not needed), so nothing is tested or promised for them.
Each language backend requires its own tooling. See Prerequisites.
refac move \
--project-path /path/to/project \
--source-path src/old/module.ts \
--target-path src/new/module.ts
For move, --project-path must be the package root, the directory that contains tsconfig.json, Cargo.toml, go.mod, pyproject.toml, etc. For monorepos or workspaces, point it at the sub-package being operated on, not the workspace root.
Paths given to --source-path and --target-path can be absolute or relative to --project-path.
Set REFAC_PROJECT_PATH to avoid repeating it:
export REFAC_PROJECT_PATH=/path/to/project
refac move --source-path src/old.ts --target-path src/new.ts
Repeat the flags in matching order: the first source maps to the first target, and so on:
refac move \
--project-path /path/to/project \
--source-path src/a.ts --source-path src/b.ts \
--target-path src/x.ts --target-path src/y.ts
Mixed languages in one call work: the tool groups files by language and dispatches each batch to its correct backend. If one language's batch fails, the others still run. The response reports which succeeded and which failed.
A long list is easier to keep in a file. Write the moves once as JSON, the same shape as the list of rename --batch, and read it with --batch (--batch - reads stdin):
cat > moves.json <<'JSON'
[
{"source_path": "src/a.ts", "target_path": "src/x.ts"},
{"source_path": "src/b.ts", "target_path": "src/y.ts"}
]
JSON
refac move --project-path /path/to/project --batch moves.json --dry-run # check it
refac move --project-path /path/to/project --batch moves.json # run it
It is the same call as the flags (paths absolute or relative to --project-path, languages may mix, a folder may be an entry), so a Kotlin list pays the server start once. An entry needs exactly source_path and target_path; anything else, an empty list or a file that cannot be read is an error that names the file. --batch cannot be combined with --source-path or --target-path. refac move -h, refac guide batching and the refusal of a single Kotlin move show the same form.
Add --dry-run to any move to see what it would do without changing a file:
refac move --dry-run --project-path /path/to/project \
--source-path src/utils/format.ts --target-path src/helpers/format.ts
The report lists, per language, the paths that would move (also the files that travel with a Go package) and one // <file> (N edits) line per file that would be edited, where an edit is one rewritten import, module line, package line or link. It runs the same checks as the move and refuses what the move refuses. TypeScript, Markdown, Dart, Go, Rust, and Pyrefly are planned from the plan their tool makes before it writes; TypeScript also resolves every rewritten import against the files as they will be after the move, so a move that the real move would roll back (another module answers the new import) is refused in the dry run too. An import of an asset through an alias can only be checked by the real move; a note says how many. Python (Rope) and Kotlin cannot plan without moving, so they run the real move, with its own checks, on a throw-away copy of the project (at most 500 MiB, REFAC_DRY_RUN_COPY_MAX_MB changes it; Rope copies only .py and .pyi files) and report the difference; the original is never touched. Go and Rust moves of several packages are planned one after the other; two plans that edit the same text are refused, with the advice to move them in separate commands.
Use logical module paths, not filesystem paths, for a structural Rust move:
refac move-module \
--project-path /path/to/cargo-workspace \
crate::engine::matching \
crate::domain::matching
--project-path may be a Cargo package or workspace root. Refac resolves the source module semantically, moves its complete conventional file/mod.rs subtree, rewrites resolved references in the workspace, adjusts affected super:: paths, creates missing parent modules, and validates the result with cargo check --workspace --all-targets.
refac rename \
--project-path /path/to/package \
--file src/lib/util.ts \
--symbol total \
--new-name grandTotal
--project-path is the package root whose tsconfig.json includes every caller. Refac finds every reference with the TypeScript 7 native language server (imports, aliases, re-exports, namespace access, class members, JSX, .js files), plans all edits, proves in memory that the new name neither clashes with nor shadows another symbol, and only then writes. Use --dry-run to preview the edits. If the name refers to several symbols in the file, the command lists them; pass --line (and --column) to choose one. Strings and comments are never edited. See Symbol rename for the safety rules and limits.
refac move \
--project-path /path/to/gradle/root \
--source-path app/src/main/kotlin/com/example/ui/Home.kt \
--target-path app/src/main/kotlin/com/example/home/Home.kt
refac rename \
--project-path /path/to/gradle/root \
--file app/src/main/kotlin/com/example/util/Helper.kt \
--symbol shout --new-name yell
--project-path is the Gradle root (the folder with settings.gradle.kts). The JetBrains Kotlin language server rewrites the package line, imports, and usages, including Java callers, and renames symbols with every reference. For Android, refac adds what the server never touches: class names in the manifest, layouts, and navigation graphs, and the R / BuildConfig imports a file loses when it leaves its namespace package. A rename that would clash with or shadow another declaration is refused, and every failure restores the project. Old names in ProGuard rules, build scripts, and strings are reported, not edited. The server is installed once by you; see Kotlin server setup and Kotlin and Android.
refac rename --project-path /path/to/module --file shape/shape.go --symbol Area --new-name Surface
refac rename --project-path /path/to/crate --file src/shapes.rs --symbol area --new-name surface
refac rename --project-path /path/to/project --file shop/shapes.py --symbol area --new-name surface
refac rename --project-path /path/to/package --file lib/shapes.dart --symbol area --new-name surface
--project-path is the folder with go.mod, Cargo.toml, or pubspec.yaml (after dart pub get); for Python it is the folder basedpyright treats as the root. The same rules hold in all four: the server (gopls, rust-analyzer, basedpyright, the Dart SDK's analysis server) lists the references and proposes the edits, refac proves in memory that the renamed program still means the same (a new name that clashes with or shadows something is refused with the usages that would change), writes through an undo log, and reports where the old name is still written (untyped receivers, strings, comments, Rust macro_rules! bodies). --dry-run writes nothing; --line and --column choose one symbol when the name refers to several. Package, module, and file names are paths: use refac move or move-module. Details per language: Symbol rename.
Several renames in one call. Starting a language server costs seconds (Kotlin about 24 s), so several renames of one project go into one --batch call: the server starts once, each rename is proven and written against the files the previous one left, and the batch is all or nothing (a failing rename undoes the earlier ones). The batch is a JSON list read from a file or from stdin with -; it works for TypeScript / JavaScript, Kotlin, Go, Rust, Python, and Dart, one language and one project per batch (a batch that mixes languages is refused before anything runs, naming the entry). With --dry-run each entry is planned on the files as the ones before it would leave them, so a dry run accepts and refuses exactly what the real batch does; a Kotlin dry run of several entries runs the batch on a throw-away copy of the project.
refac rename --project-path /path/to/crate --batch - <<'JSON'
[
{"file": "src/shapes.rs", "symbol": "SCALE", "new_name": "FACTOR"},
{"file": "src/shapes.rs", "symbol": "Square", "new_name": "Cube", "line": 36},
{"file": "src/shapes.rs", "symbol": "FACTOR", "new_name": "MULTIPLIER"}
]
JSON
On the Rust fixture four renames took 18.8 s as four commands and 4.6 s as one batch. No server stays running between commands, by design: a resident server would hold hundreds of MB to a few GB of memory and would see a stale copy of every file that anything else edits.
refac doctor # every language: ready, MISSING, or BROKEN
refac doctor go # where gopls was looked for, the install command, a start check
refac move --json \
--project-path /path/to/project \
--source-path src/old.go \
--target-path pkg/new/old.go
With --json, a file move returns a single JSON object with operation-specific fields:
{
"status": "ok",
"operation": "move",
"project_path": "/path/to/project",
"source_path": ["src/old.go"],
"target_path": ["pkg/new/old.go"],
"result": "..."
}
On failure, "status" is "error" and "error" contains the descriptive failure chain. Successful move-module --json output additionally reports source_module, target_module, dry_run, compiled (the moved workspace passed cargo check), moved_paths, edited_files, edits, files (path and number of edits) and moves (from, to). move-module --dry-run plans the move, lists what it would move and edit, and writes nothing; it does not compile the result unless you add --check, which carries the move out on a throw-away copy of the workspace (without target, at most 500 MiB) and runs cargo check --workspace --all-targets there, as the real move does. The copy builds into a folder of its own, so --check takes as long as a first build. move --dry-run --json returns the same shape (dry_run, moved_paths, edited_files, edits, files, moves) plus notes, with paths relative to the project path.
0: all requested moves completed1: one or more moves failed (or all failed)These are not edge cases. Read them before deciding whether this tool is right for your situation.
TypeScript / JavaScript
--project-path at the package with the authoritative tsconfig.json; its include or files configuration must cover all local TS/JS sources. External packages in node_modules do not need to be included.Python
__init__.py re-exports. If a package re-exports a symbol and callers import via the re-export, those callers are not updated.__init__.py) may see incomplete updates.Rust
move-module for cross-directory or otherwise structural moves. Ordinary move rejects cross-directory .rs paths instead of guessing the logical module change.crate::... paths in the same crate. Workspace dependants are updated, but a source path that resolves in multiple workspace crates is rejected as ambiguous.#[path] and #[macro_use] declarations (other attributes must be conditions or lints such as #[cfg]), pub(in …) visibility that is not an absolute crate:: path, syntax errors, and complex paths it cannot preserve. It handles code behind #[cfg(test)], crate:: paths in macro arguments, short references through use, pub(super), and a module that leaves a grouped import (details and limits: Rust).#[path] or compatibility re-export shims. It validates after applying and rolls planned source changes back on failure.Go
.go file cross-directory renames the entire package. All files in the source directory move together. If pkg/ contains a.go, b.go, and c.go, asking to move pkg/a.go makes gopls move all three. Partial-package moves are not supported.go.mod at the project root for cross-directory moves.Dart
package: URI imports are only rewritten if .dart_tool/package_config.json exists at the project root. Run dart pub get to generate it. Without it, a move that would leave a package: import pointing at a file that no longer exists is refused before anything is written, and the error lists the imports.Kotlin / Android
~/.cache/refac, REFAC_KOTLIN_CACHE=off disables it), and about 1.6 GiB of memory for the server on a tiny project. Batch several moves into one call (repeat --source-path and --target-path, or list them in a file with move --batch moves.json) and several renames into one rename --batch. So a single Kotlin file moved, or a single Kotlin rename, is refused by default (dry runs included) before anything starts, and the error writes the batch command for that request and explains why Kotlin is slow and which options exist (the same text as refac guide kotlin). --allow-single lets the one change through, and it then ends with a note that says how many seconds it took and shows the batch form. REFAC_KOTLIN_BATCH_ONLY=0 turns the refusal off for the whole environment. REFAC_KOTLIN_GRADLE_IDLE_SECS=120 (1 to 3600, off by default) keeps the project's Gradle daemon up between commands, so a call right after another takes 15 s instead of 24 s, for the price of the daemon's memory. The variable is 1 (the default, also when empty or unset) or 0; any other value is an error, so a typo cannot switch the protection off.import <old package>.<name> for each top-level name the file uses and a file of the old package declares (including overloads and an expect fun with its actual, which the server leaves out in a Multiplatform build), unless the file imports that name already. The same goes for operator functions the syntax calls without writing their names (q[0] calls get, for (x in q) calls iterator, val (a, b) = q calls component1, by calls getValue), in both directions: the moved file gets the imports it lost, and the files that stay behind get the imports of the operators that moved away. An operator needs the type it is called on to be written in the file, and an operator of another Gradle module is imported only for a direct project dependency (project(":lib"), projects.lib; api chains are not followed). Operators the server rewrites as calls (a < b as a compareTo b) are put back. The notes list the files that got imports..java files, directories containing Java sources, and moves between modules or source sets are refused.Markdown
#anchors, site-root /paths, and paths with template syntax are left unchanged.href, src, poster, and srcset values are rewritten; MDX imports, wiki-links [[Page]], and paths inside other file types (SVG, CSS, JSON) are not..gitignore, .git/, and node_modules/ are not searched. Markdown files that are not valid UTF-8 are reported and left unchanged.TypeScript symbol rename
baseUrl and moduleResolution: node10 are rejected with the engine's diagnostic. File moves are not affected.--line.General
move, move-module and rename all support --dry-run. A plain move writes to disk immediately.move-module rejects existing targets during preflight.node_modules/, target/, .git/, or similar build/vendor directories when scanning for references.| Language | Required | Install |
|---|---|---|
| TypeScript / JS | bun | bun.sh |
| Python | rope importable from .venv or python3 | pip install rope |
| Python (fallback) | pyrefly (only if Rope is absent) | pip install pyrefly |
Python (rename) | basedpyright | pip install basedpyright |
| Rust | rust-analyzer for symbol rename and ordinary file renames; semantic module support is embedded | rustup component add rust-analyzer |
| Go | gopls | go install golang.org/x/tools/gopls@latest |
| Dart | Dart SDK | dart.dev/get-dart |
| Kotlin / Android | JetBrains Kotlin language server (REFAC_KOTLIN_SERVER), JDK 17+, a Gradle project; ANDROID_HOME for Android | Kotlin server setup |
| Markdown | none | n/a |
refac doctor <language> prints these steps for the machine it runs on and proves the server starts. No specific minimum version is enforced for external language tools, but use recent releases. This checkout pins rust-analyzer 1.99.0 for ordinary Rust file renames and locks the embedded rust-analyzer crates in Cargo.
The approach depends on the language:
LSP-backed file moves (Rust, Go, Dart): The tool starts a language server process, issues a rename request (textDocument/rename or workspace/willRenameFiles), applies the workspace edit the server returns, then moves the file on the filesystem. For batch operations, multiple renames are sent within a single server session with textDocument/didChange notifications between them to keep the server's view current. The tool never waits a fixed time: it sends the project's documents and waits for the server's own readiness signal (Dart $/analyzerStatus, gopls $/progress end, rust-analyzer experimental/serverStatus, pyrefly diagnostics). A server that never signals is an error after REFAC_LSP_TIMEOUT_SECS (default 300). For Dart the plan is checked before writing: if it would leave an import pointing at a missing file, nothing is changed.
Semantic Rust modules: move-module loads the Cargo workspace through embedded rust-analyzer crates, resolves the logical module and references through HIR, plans conventional module-tree edits and physical moves, then validates a fresh semantic load and the full Cargo workspace. Unsupported or ambiguous structures fail with a descriptive error rather than falling back to text-only guesses.
Shared rename engine (Go, Rust, Python, Dart, Kotlin symbol rename): rename (or rename --batch, which does this for each of its renames in one server session) starts the language server for the file's language, asks it for the references and the rename edits, shows it the renamed text in memory and asks for the references again, and writes only if the sets match (and every listed reference was edited). The server is shut down before anything is written. Python overrides are found with textDocument/implementation and renamed together; gopls is asked again when it answers under load with only part of the edits; the Dart server is made to finish analysing the changed documents first. See Engine.
TypeScript 7 native server (TypeScript / JavaScript symbol rename): rename starts tsc --lsp --stdio from the locked typescript-native dependency, asks it for the rename edits, applies them in memory only, and asks for the references of the renamed declaration to prove that no clash or shadowing changed any meaning. Files are written only after that check, with rollback on a failed write. See Symbol rename.
Oxc (TypeScript / JavaScript): A Bun helper parses configured sources with Oxc and resolves code imports with TypeScript, without a compiler Program or type checker. It plans the complete batch, edits module literals precisely, and verifies resolution after movement. Ordinary apply/verification failures roll back. Assets use Oxc Resolver; the supervisor enforces time and memory limits. See TypeScript details.
Rope (Python): The Rope refactoring library is invoked directly via Python. It performs the move and updates all import statements it can trace.
Native (Markdown): A CommonMark parser (pulldown-cmark) finds every link, image, reference definition, and the href/src/srcset values in raw HTML. The tool plans the full change (moves, then rewritten destinations written the way the author wrote them), applies it, and rolls back everything if a step fails. The same engine runs after any other backend has moved files, so a README that points at src/app.py follows the move. No external tooling required. See Markdown.
cargo test
bun install --cwd scripts --frozen-lockfile
bun run --cwd scripts test
bun run --cwd scripts typecheck
The suite covers unit tests and integration tests for all supported languages. Integration tests copy fixture projects into temp directories and run assertions on the resulting files. They live in six groups, one test program each: cargo test --test cli, moves, rename, typescript, markdown, kotlin (a part of a group with a filter, cargo test --test rename go::). A plain cargo test needs only the Rust toolchain (plus Bun for the TypeScript engine) and never skips silently: every test that needs a language server (gopls, the Dart SDK, rope, basedpyright, the Kotlin server) is #[ignore = "needs X (run refac doctor Y)"], so it shows up as ignored in the summary. With the tools installed run them with cargo test -- --ignored (or --include-ignored for everything); without the tool they fail with an explanation of what was looked for. The Kotlin group is the exception, and it is not for casual runs: a Kotlin test starts a language server (20 to 32 seconds, about 2 GB) and the whole group takes about 7 minutes. By default only the quick set runs, within 30 seconds (cargo test --test kotlin quick:: -- --ignored --test-threads=1); every other Kotlin test is blocked and fails at once with the reason unless the command says REFAC_KOTLIN_TESTS=all. Run those only when your change needs them, in a single command (REFAC_KOTLIN_TESTS=all cargo test --test kotlin -- --ignored --test-threads=1 <name> <name>; the tests share one server per fixture inside it); which tests cover which change.
Disk and memory. The repository is 3 MB; a fresh cargo test build writes 2.1 GB (target/) and peaks at 3.2 GB of RAM, because the Cargo profile drops debug information and the integration tests are grouped. Do not add a .rs file directly in tests/ (it becomes another 90 MB program); see Resource use.
Issues and pull requests are welcome. There is no formal contribution guide yet, so open an issue first if you are planning a significant change.
Hippocratic License HL3, see LICENSE.
Failed to find 'target' in Kotlin extension, then every move is refused), so for a build with a commonMain, commonTest or <target>Main source set refac starts it on a plain-JVM copy of every source set and translates paths both ways. Package lines and references to the project's own classes follow; imports of libraries the copy cannot see (Compose, Android) are kept. A file that declares expect or actual is refused before anything starts (move those by hand), and it was tested on a small fixture and by a hand-over from a Compose Multiplatform application, not on a Compose Multiplatform application of ours: compile every target afterwards. A Kotlin move changes the package line and the imports it has to change, adds the imports for names that stayed behind in the old package, and nothing else; files that .gitignore leaves out are not read. The Kotlin version of the copy comes from gradle/libs.versions.toml or the plugin line, else REFAC_KOTLIN_MIRROR_VERSION. Details: Kotlin Multiplatform.