[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7E6CZP9CT50K019SWMS7E3M":3,"skill-same:01M7E6CZP9CT50K019SWMS7E3M":93},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":19,"publishedAt":20,"linkOnly":21,"markdownContent":22,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":14,"repositoryHtmlUrl":28,"repositoryHomepageUrl":6,"ownerHtmlUrl":29,"ownerBlogUrl":30,"ownerDescription":31,"updatedAt":32,"install":33,"resources":46},"01M7E6CZP9CT50K019SWMS7E3M","scala-compiler-macro-refactoring",null,"Use when refactoring or reviewing Scala compiler plugins, macros\u002Finline combinators, or REPL\u002Fscript tooling where the risk is changing what is captured, when it runs, or what the compiler sees - Acyclic whole-run Scala 2\u002F3 analysis and diagnostics, sourcecode Args argument capture, Ammonite symbol-derived closure capture and static BSP script dependency propagation, and Fastparse shared-run combinator extraction. Not for effect cancellation, stream scoping, HTTP semantics, compatibility laws, or runtime hot-path cost.","w0rxbend\u002Fdot-agents","w0rxbend","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F8176996?v=4","01M7E4XY3Y871Z2NFBXF3H3T8F","Oleksandr B.","01M7E4XY51E6NSG05FXR36H9RV",0,"MIT","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: scala-compiler-macro-refactoring\ndescription: Use when refactoring or reviewing Scala compiler plugins, macros\u002Finline combinators, or REPL\u002Fscript tooling where the risk is changing what is captured, when it runs, or what the compiler sees - Acyclic whole-run Scala 2\u002F3 analysis and diagnostics, sourcecode Args argument capture, Ammonite symbol-derived closure capture and static BSP script dependency propagation, and Fastparse shared-run combinator extraction. Not for effect cancellation, stream scoping, HTTP semantics, compatibility laws, or runtime hot-path cost.\nlicense: MIT\n---\n\n# Scala compiler, macro and REPL refactoring\n\nCompiler plugins, macros, inline combinators and REPL wrappers generate or analyse code on someone else's behalf. Refactor keeping names, types and green tests can still change **what is captured** (value, command instance, dependency tree), **when or how often it runs** (per unit versus per run, eager versus deferred, re-initialized on deserialization), or **what the compiler sees** (syntactic proxy instead of symbol, inserted implicit view, type clause read as term clause).\n\n## When to Use\n\n- Changing compiler plugin's phase callbacks, shared analysis or reporter adapter, especially when porting between Scala 2 and Scala 3.\n- Changing macro or inline entrypoint capturing enclosing-scope information (parameters, owners, values).\n- Changing REPL\u002Fscript wrapper generation, used-definition tracking, serialized closure capture, or static (IDE\u002FBSP) script dependency extraction.\n- Extracting or consolidating parser\u002Fcombinator code whose children share mutable run state, or changing an implicit hook every combinator invokes.\n- Reviewing a test claiming to cover the above that may observe only names, sets or compile success.\n\n## When Not to Use\n\n- Ordinary application cycles, imports, dependency bumps, or logging of values already supplied explicitly.\n- Generic ABI\u002Fbinary-compatibility or law-backed instance questions: use `scala-library-compatibility-laws` or `scala-library-contracts`.\n- Allocation, closure or bytecode cost with unchanged semantics, or failure-label\u002Fdiagnostic-mode work with unchanged control flow: use `scala-runtime-diagnostics-hot-paths`.\n- Effect cancellation\u002Ffinalization (`scala-effect-cancellation-finalization`), stream resource scoping (`scala-stream-resource-scoping`), HTTP server semantics (`scala-http-server-semantics`).\n- General type-level design (`scala-type-system`), FP structure (`scala-functional-patterns`), or library triage (`scala-oss-library-review`, the router).\n- Do not add Cats Effect, ZIO, Ox or lazy wrapper to these synchronous compiler\u002Fmacro\u002FREPL paths. No source supports it.\n\n## Prerequisites\n\n1. Pin exact revision, Scala compiler patch versions, platform versions (JVM\u002FJS\u002FNative), build tool and launcher version, test framework and JDK. Calendar year never selects a compiler API.\n2. Read that revision's real build and CI. In every case the obvious command was wrong for at least one era (sbt versus Mill; `.\u002Fmill` versus `mill`; main-driven `test.run` versus framework selector).\n3. Find compiler-specific source roots (`src-2`, `src-3`, version-specific test roots) and code they share.\n4. Load matching case reference from routing table before proposing a patch.\n\n## Routing Table\n\n| Change touches | Load |\n| --- | --- |\n| Acyclic `RuntimePlugin`\u002F`TestPlugin`, `PluginPhase` (`src-2`\u002F`src-3`), `BasePluginPhase.runAllUnits`, `GraphAnalysis`, `reportInform`\u002F`report.echo`, `TestUtils.make`\u002F`makeFail`, `BaseCycleTests`, bootstrap self-plugin exclusions; any plugin doing whole-run work from per-unit callback | [references\u002Facyclic-whole-run-compiler-adapters.md](references\u002Facyclic-whole-run-compiler-adapters.md) |\n| sourcecode `Args`, `argsImpl`, `SourceContext.scala`, `src-2`\u002F`src-3` `Macros.scala`, `ArgsTests` via `Main`\u002F`Tests.run`; any macro reading parameter clauses, `ValDef` RHS, or enclosing owner | [references\u002Fsourcecode-args-capture-review.md](references\u002Fsourcecode-args-capture-review.md) |\n| Ammonite `CodeClassWrapper`, `Preprocessor`, `AmmonitePlugin` used-command collector (`usedEarlierDefinitions`), session\u002Fcache bridge, `SerializationTests`, `EvaluatorTests`, `DualTestRepl`; any REPL wrapper whose import rewriting changes captured object graph | [references\u002Fammonite-symbol-derived-closure-capture.md](references\u002Fammonite-symbol-derived-closure-capture.md) |\n| Ammonite import hooks (`$repo`, `Result.Repo`), `Script.Dependencies`, `noDuplicates`, `ScriptProcessor.jarDependencies`\u002F`jarPluginDependencies`, `ScriptCompiler`, BSP `scriptScalacOptions`, `AmmoniteBuildServerTests`; any static (IDE) extraction mirroring interactive interpreter | [references\u002Fammonite-static-script-dependency-propagation.md](references\u002Fammonite-static-script-dependency-propagation.md) |\n| Fastparse `ParsingRun`, `P`, sequence\u002F`.rep`\u002F`.repX` macros (`MacroRepImpls`), higher-order wrappers such as `Indexed`, `Whitespace`, cuts in reusable whitespace\u002Fcomment parsers, Scala 2 -> 3 combinator ports; any combinator library over shared mutable run | [references\u002Ffastparse-shared-run-combinator-extraction.md](references\u002Ffastparse-shared-run-combinator-extraction.md) |\n\nPinned evidence for every case lives in `references\u002Fevidence\u002F` (exact copies of original records; claim and record IDs cited in references resolve there).\n\n## Shared Model\n\nInvariants below recur across cases; each names cases demonstrating it. Applying an invariant to another library is inference unless that library's source shows same mechanism.\n\n**M1. Capture identity, not syntactic proxy.** Capture the real runtime or compiler referent.\n- sourcecode: parameter's optional `ValDef` RHS is not caller's argument. PR 126 replaces RHS\u002F`None` fallback with `Ref(vd.symbol).asExpr`.\n- Ammonite closure: `import ...cmd0.instance.a` resolves same name but captures singleton path, so deserialization reinitializes `a`. Capture command instance.\n- Acyclic: dependency edges must keep trees (positions, symbol names, supplemental lines), not only connectivity booleans.\n- All three reject string-based substitutes: `tree.toString`\u002Fregex scans (Ammonite), rebuilt initializers or re-evaluated call-site expressions (sourcecode).\n\n**M2. Derive dependencies from typed symbols, via both term and type paths.**\n- Ammonite PR 944: `Select` receiver matching missed commands needed only through types. Fix traversed `TypeTree.tpe` for `SingleType` prefixes equal to wrapper symbol. Dropping either branch breaks a different oracle.\n- sourcecode: classify term versus type clauses by compiler's real discriminator. Erased `List[ValDef]` versus `List[TypeDef]` matching does not work (PR 103 extension-method counterexample; cast still in late-2024 source).\n- Acyclic: validity, different-source-file and `unitMap.contains(symbolPath(sym))` guards precede lookup. Out-of-run symbols are not invented edges.\n\n**M3. Execution count and timing belong to right lifetime.**\n- Acyclic: whole-run analysis in per-unit callback ran once per file, duplicating diagnostics. Run once per compilation run; do not suppress a second supported run.\n- Fastparse: child parser runs once, at original position. By-name for ordinary wrappers (PR 212 `Indexed`), inspected staging for macros.\n- Ammonite closure: deserializing and invoking captured value must not rerun its initializer.\n- Ammonite static: dependency extraction must not evaluate arbitrary script bodies. Hooks go through dummy interpreter interface: architectural boundary, not sandbox.\n- sourcecode: `Args` must materialize at call site in intended owner. Extracting a helper that materializes it elsewhere changes owner.\n\n**M4. Know who owns mutable state and when it resets.**\n- Fastparse: `val` holding a `ParsingRun` is not a snapshot. Save child results to locals before a sibling overwrites `index`\u002F`isSuccess`\u002F`successValue`\u002F`cut`\u002Fdiagnostics\u002F`noDropBuffer`.\n- Acyclic: `alreadyRun` is plugin-instance state that `init` does not visibly reset. Source does not establish whether production reuses the instance.\n- Ammonite static: stateful Interpreter mutates its repositories; static `Script` metadata carries `extraRepositories`. Both consumers intentional; do not merge.\n- Ammonite closure: used-command metadata must stay tied to command being instantiated, including cache hits and session restoration.\n\n**M5. Metadata must survive every transformation to final consumer.**\n- Ammonite static: repositories pass extraction, `Dependencies.+`, `noDuplicates`, and both ordinary and plugin resolution, reaching dependent target's classpath.\n- Acyclic: supplemental dependency lines pass shared graph code to default-visible reporter (`report.echo`, not verbose-only `inform`).\n- Fastparse: diagnostic aggregates keep child provenance after extraction.\n- sourcecode: ordered outer-list grouping of term clauses survives to `Args.value`.\n\n**M6. Keep compiler-specific representation in adapters; share only matching semantics.**\n- Acyclic PR 136: share graph operations; keep bespoke tree\u002Fsymbol\u002Funit traversal and reporting per compiler.\n- sourcecode: Scala 2 uses method symbols\u002F`paramLists`, Scala 3 inspects definition trees. Common helper must not assert equivalence.\n- Ammonite: PR 944's `TypeTree`\u002F`SingleType` shapes are Scala 2 internals, not APIs to copy into Scala 3. `-Ydelambdafy=inline` stays test-local.\n- Fastparse: Scala 2 split common macros from runtime methods; Scala 3 shares one macro inspecting inline values. PR 310: compiler-internal test adapters need version-specific roots.\n\n**M7. Check what compiler inserts.**\n- Fastparse PR 272: Scala 2 applied function-typed implicit (`P[_] => P[Unit]`) as implicit view, rewriting `Fail.!` into whitespace call that overwrote the failure. Repair: dedicated trait\u002FSAM type plus regression asserting `Parsed.Failure`. Trait change was binary incompatible, timed for 3.0.0.\n- sourcecode: implicit `Args` materializes wherever compiler resolves it; that site is inspected owner.\n\n**M8. Oracle must observe the invariant and must actually run.**\n- Observe the right thing: raw diagnostic events before set canonicalization (Acyclic); full nested `(name, value)` pairs with varying values (sourcecode); sentinel plus result plus separate type-dependency evaluator transcript (Ammonite closure); dependent-target classpath plus inverse case plus hook removal (Ammonite static); value plus consumed index plus `End` (Fastparse).\n- Actually run: unasserted `make(...).exists(...)` (Acyclic 2022); names-only Scala 3 exemption (sourcecode 2022); Scala 3 `disabled` case or object-wrapper-only `DualTestRepl` run (Ammonite); `scala2_11` guard that disabled the regression (Ammonite PR 1090); main-driven assertions reachable only via `__.test.run` (sourcecode).\n- Prove discrimination with a mutation that must make test fail (remove the once-per-run gate, revert to RHS fallback, import singletons directly, drop the `TypeTree` branch, remove the repo hook, re-add the comment cut).\n\n## Workflow\n\n1. **Classify the boundary** (transferable). Locate change: compile-time analysis, compile-time code generation, generated-code runtime, or test harness. Distinguish ordinary parameter, by-name, inline receiver, quoted expression, macro surface parameter, and completed value.\n2. **Write the behavioural baseline** (transferable). For each user-observed output, record: what is captured (M1), from which symbol\u002Ftype paths (M2), when and how often it runs (M3), which state it reads\u002Fwrites and who resets it (M4), and which consumer finally reads the metadata (M5).\n3. **Draw the adapter boundary** (transferable). List compiler-specific operations versus shared semantics (M6). Refuse shared helper hiding a representation difference.\n4. **Trace every transformation to the consumer** (transferable). Follow value\u002Fmetadata through folds, merges, deduplication, caches and reporters. Preserve ordering and dedup semantics; do not swap sequences for sets.\n5. **Check compiler insertions** (transferable). Implicit views from function-typed implicits, implicit materialization site, inline expansion. Compile with conversion diagnostics when execution is authorized.\n6. **Apply the smallest change** (transferable). Keep publication\u002Ftoolchain edits separate. Route ABI consequences to compatibility guidance.\n7. **Repair the oracle with the code** (transferable). Strengthen it to observe M1-M5, confirm test is reached on each claimed compiler cell, specify a mutation that must fail (M8).\n8. **Apply the case-specific procedure** (library-specific). Load routed reference; follow its version-pinned steps, probe matrix and validation commands.\n\n## Review and Refactoring Checks\n\n| Check | Scope |\n| --- | --- |\n| Captured value is symbol\u002Finstance reference, not initializer, singleton path or text match (M1) | Transferable |\n| Dependencies include type-derived paths, not only term selections (M2) | Transferable; collector shapes are Scala 2 Ammonite-specific |\n| Term versus type clauses classified by compiler's real discriminator; empty term clauses and group order preserved (M2) | Transferable; API is compiler-version-specific |\n| Whole-run work executes once per run, keyed to real run lifetime, not reset per callback (M3, M4) | Transferable; `alreadyRun` placement is Acyclic-specific |\n| Children\u002Farguments execute at original position and count; earlier results saved before shared state is overwritten (M3, M4) | Transferable to any shared-run combinator library |\n| Deserialization does not rerun captured initializers; unused whole commands nulled, required ones kept (M1, M3) | Ammonite class-wrapper-specific; command (not field) granularity |\n| Static extraction does not evaluate script bodies; static and interactive consumers both updated (M3, M4) | Transferable pattern; `Result.Repo`\u002F`extraRepositories` Ammonite-specific |\n| Metadata survives merge\u002Fdedup and reaches every sibling consumer (ordinary and plugin resolution; reporter) (M5) | Transferable |\n| Default visibility and severity of diagnostics unchanged; no byte-identical caret demands across compilers (M5) | Transferable; `echo` versus `inform` is Scala 3 Acyclic-specific |\n| No function-typed implicit that Scala 2 can apply as view (M7) | Transferable to Scala 2 libraries |\n| Cuts\u002Fcommitment inside reusable sub-parsers checked against enclosing repetition\u002Falternative (M3) | Fastparse-specific mechanism; transferable to cut-based parsers |\n| Specialized generated paths not replaced by runtime branching on consolidation | Fastparse-specific; measure separately from correctness |\n| Oracle observes raw\u002Fcomplete payload, runs on every claimed cell, and has failing mutation (M8) | Transferable |\n| Bootstrap\u002Fself-applied plugin not pre-rejecting test resources | Acyclic-specific, revision-dependent |\n\n## Consolidated False Positives\n\n- **Acyclic:** `makeFail` asserts internally, so its call site needs no outer `assert`; `acyclic.pkg` package-internal cycles (`success\u002Fpkg\u002Finnercycle`) are deliberate; distinct cycles may legitimately yield multiple diagnostics; caret-format differences are not drift; 2024 build need not restore 2022 bootstrap exclusions; analyzer intentionally processing one unit per callback needs no whole-run guard.\n- **sourcecode:** empty `Seq()` for parameterless method is correct; names-only API need not capture values; empty `testFramework` does not disable main-driven assertions; suspicious cast justifies targeted counterexample, not claimed crash on every compiler; IO wrappers, framework migration or public `Args` flattening are not repairs; `Name`-only formatting change is out of scope unless it alters shared ownership.\n- **Ammonite closure:** nonserializable sibling in same required command can stay reachable (not a closure cleaner); intentional singleton references and object-only commands (kept for macro ownership) keep their initialization semantics; string-based source generation is not itself forbidden; disabled Scala 3 variant is coverage boundary, not proof Scala 3 closures are unserializable.\n- **Ammonite static:** stateful REPL execution is intentional; private synchronized `addRepository` helper is not API widening; generated inert imports are not the resolution effect; different classloader topology is not automatically defective, and isolated compilation does not require a classloader DAG; multi-stage scripts need their own contract.\n- **Fastparse:** macro surface parameters can be staged without looking by-name; storing immutable `Parsed` results is safe; intentional cut after unique prefix may be necessary; explicit non-implicit function parameter cannot become view; removing all cuts or retaining all input is not a bounded repair; Scala 3 quote hygiene does not authorize removing Scala 2 qualification; shared source is not inherently slower.\n- **All:** merge or approval adds no independent behavioural proof; open proposal (Fastparse #204) or author report (#323, Acyclic PR 136 experiments) is not an adopted mechanism or reproduced result.\n\n## Version Fences\n\n| Case | Pinned eras (historical, not recommendations) |\n| --- | --- |\n| Acyclic | 2022 `e090ee2b`: Scala 2.11.12\u002F2.12.8-2.12.17\u002F2.13.0-2.13.10, Mill 0.10.10, uTest 0.8.1, `(position, message, severity)` tuples. 2024 `fbb60d12`: adds Scala 3.3.0-3.5.1 via `src-3`, Mill 0.11.12, uTest 0.8.2, `(message, severity)` pairs; CI declares Java 8. JVM only. |\n| sourcecode | PR 103: Scala 3.0.0-RC1 (2021). PR 126 (2023): Scala 3.1.3, 2.11.12\u002F2.12.16\u002F2.13.8, JS 1.10.1, Native 0.4.5. Nov 2024: 2.12.16\u002F2.13.8\u002F3.3.3, JS 1.17.0, Native 0.5.0, Mill 0.12.0. |\n| Ammonite closure | PR 736 (2018): Scala 2.12.4\u002FJVM, uTest 0.6.0, sbt `ammRepl`. PR 944 `50e075dd`: Mill 0.3.3 via `mill`, Scala 2.11.12\u002FJDK 8 and 2.12.8\u002FJDK 8 or 11. 2019 isolated-loader test; 2021 Scala 3 case disabled. |\n| Ammonite static | PR 1090 `7017cb94` (June 2020): Scala 2.12.11\u002F2.13.2, BSP 2.0.0-M6, coursier-interface 0.0.21, uTest 0.7.3, Mill 0.7.0 default; CI 2.12.11 with JDK 8\u002F11, 2.13.2 with JDK 8. JVM Scala 2 only. |\n| Fastparse | 2020: Scala 2.12.10\u002F2.13.1 JVM. 2022: repetition under `src-2`. 2024: Scala 3.3.3\u002F2.13.14\u002F2.12.19, Scala.js 1.16.0, Native 0.5.1. Fastparse 1 is outside the shared-run model. Whitespace trait (PR 272) lands at 3.0.0. |\n\n## Validation\n\n- Report every proposed test as `not executed` until you run it.\n- Discover commands from target revision's build file, launcher pin (`.mill-version`, `MILL_VERSION`, wrapper script) and CI workflow. Trace from CI entry to specific test. Historical examples: Acyclic `.\u002Fmill -i -j 0 __.publishArtifacts + __.test`; sourcecode `.\u002Fmill -i '__.test.run'`; Ammonite `TRAVIS_SCALA_VERSION=2.13.2 .\u002Fmill -i unitTest` (2020) and `TRAVIS_SCALA_VERSION=2.12.8 mill -i unitTest` (PR 944); Fastparse `.\u002Fmill -i --disable-ticker __.jvm.__.publishArtifacts + __.jvm.__.compile + __.jvm.__.test` with focused selectors such as `'fastparse.jvm[3.3.3].test'`. Each is valid only for its pinned revision.\n- Run only in separately authorized, isolated, trusted checkout with matching toolchain. Never run publish\u002Frelease\u002Fsigning jobs. Static inspection, hooks, resolution and macros can execute code or touch network.\n- Confirm target test ran on each claimed compiler\u002Fplatform cell (case count, wrapper member, not a disabled variant). JVM success is not JS\u002FNative coverage.\n- Run specified mutation for each strengthened oracle, require failure, then restore.\n- Keep correctness separate from throughput or generated-code-size measurement.\n\n## Examples\n\n### Good\n\nScala 3 port of analysis plugin keeps traversal and reporting in `src-3`, shares only graph policy, gates whole-run analysis to run lifetime, and reports supplemental lines with a default-visible call. It adds a raw-event test: two-file cycle plus unrelated third file, still expecting one top-level diagnostic (Acyclic). Same discipline for a macro: reference parameter symbol, assert complete nested `(name, value)` pairs across two invocations with different values (sourcecode).\n\n### Broken and Correction\n\nCleanup makes generated wrapper \"simpler\": rewrites captured instance to direct import (Ammonite), changes by-name child to strict parameter (Fastparse `Indexed`), or reads parameter's default RHS (sourcecode). Names and types still resolve; existing name-only or success-only tests pass. Correction: restore instance\u002Fsymbol capture and deferred execution. Then add oracle observing lost property (no reinitialization sentinel plus result; nested value\u002Foffset tuple; full value pairs) and its failing mutation.\n\n### Negative\n\nDiff only bumps release number, edits `sourcecode.Name` formatting, changes an application import, or formats already-produced `Parsed.Success`. None changes capture, timing or compiler-visible structure. Decline this workflow; do not demand macro surgery, by-name parameters or new compiler tests.\n\n## Output Contract\n\nPer finding: `file:line`, severity, violated invariant (M1-M8 plus case-specific invariant), exact revision and compiler\u002Fplatform cell, evidence record or claim ID from `references\u002Fevidence\u002F` or pinned source URL, minimal correction, discriminating test with expected failure under mutation. Label each statement: historical observation, reviewer guidance, author report, new inference, or your own execution. Include tested versus untested cells, actual command and result or `not executed`, and blockers. If no defect found, list checked capture\u002Ftiming\u002Fstate\u002Fmetadata\u002Finsertion paths and those still untested.\n\n## Limitations\n\n- Five bounded historical samples (2018-2024), mostly from com-lihaoyi libraries.\n- No upstream build, test, mutation, reused-instance or cache-independence check executed during research. Structural validity of this skill is not behavioural effectiveness.\n- Unresolved in sources: Acyclic plugin-instance reuse across runs; sourcecode mixed term\u002Ftype clause classification (no compiled repair); Ammonite Scala 3 closure capture; Ammonite static semantics on Scala 3 or later BSP APIs and for multi-stage scripts.\n- Mostly JVM evidence; Scala.js\u002FNative behaviour needs separate validation. Untrusted deserialization and untrusted hook execution are out of scope.\n\n## Sources\n\n- Case procedures: five `references\u002F*.md` files in routing table.\n- Pinned evidence: [acyclic](references\u002Fevidence\u002Fscala-acyclic-whole-run-compiler-adapters.json), [sourcecode](references\u002Fevidence\u002Fscala-sourcecode-args-capture-review.json), [Ammonite closure](references\u002Fevidence\u002Fscala-ammonite-symbol-derived-closure-capture.json), [Ammonite static](references\u002Fevidence\u002Fscala-ammonite-static-script-dependency-propagation.json), [Fastparse](references\u002Fevidence\u002Fscala-fastparse-shared-run-combinator-extraction.json).\n- Key upstream discussions: [Acyclic PR 136](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002Facyclic\u002Fpull\u002F136#discussion_r1760522833), [sourcecode PR 103](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002Fsourcecode\u002Fpull\u002F103#discussion_r577846016), [Ammonite PR 736](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002FAmmonite\u002Fpull\u002F736#issuecomment-355239967), [Ammonite PR 1090](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002FAmmonite\u002Fpull\u002F1090#issuecomment-638956149), [Fastparse PR 272](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002Ffastparse\u002Fcommit\u002F22051f098d4cf3f2cb7510ba214cbf2e9b478108).\n","# Scala compiler, macro and REPL refactoring\n\nCompiler plugins, macros, inline combinators and REPL wrappers generate or analyse code on someone else's behalf. Refactor keeping names, types and green tests can still change **what is captured** (value, command instance, dependency tree), **when or how often it runs** (per unit versus per run, eager versus deferred, re-initialized on deserialization), or **what the compiler sees** (syntactic proxy instead of symbol, inserted implicit view, type clause read as term clause).\n\n## When to Use\n\n- Changing compiler plugin's phase callbacks, shared analysis or reporter adapter, especially when porting between Scala 2 and Scala 3.\n- Changing macro or inline entrypoint capturing enclosing-scope information (parameters, owners, values).\n- Changing REPL\u002Fscript wrapper generation, used-definition tracking, serialized closure capture, or static (IDE\u002FBSP) script dependency extraction.\n- Extracting or consolidating parser\u002Fcombinator code whose children share mutable run state, or changing an implicit hook every combinator invokes.\n- Reviewing a test claiming to cover the above that may observe only names, sets or compile success.\n\n## When Not to Use\n\n- Ordinary application cycles, imports, dependency bumps, or logging of values already supplied explicitly.\n- Generic ABI\u002Fbinary-compatibility or law-backed instance questions: use `scala-library-compatibility-laws` or `scala-library-contracts`.\n- Allocation, closure or bytecode cost with unchanged semantics, or failure-label\u002Fdiagnostic-mode work with unchanged control flow: use `scala-runtime-diagnostics-hot-paths`.\n- Effect cancellation\u002Ffinalization (`scala-effect-cancellation-finalization`), stream resource scoping (`scala-stream-resource-scoping`), HTTP server semantics (`scala-http-server-semantics`).\n- General type-level design (`scala-type-system`), FP structure (`scala-functional-patterns`), or library triage (`scala-oss-library-review`, the router).\n- Do not add Cats Effect, ZIO, Ox or lazy wrapper to these synchronous compiler\u002Fmacro\u002FREPL paths. No source supports it.\n\n## Prerequisites\n\n1. Pin exact revision, Scala compiler patch versions, platform versions (JVM\u002FJS\u002FNative), build tool and launcher version, test framework and JDK. Calendar year never selects a compiler API.\n2. Read that revision's real build and CI. In every case the obvious command was wrong for at least one era (sbt versus Mill; `.\u002Fmill` versus `mill`; main-driven `test.run` versus framework selector).\n3. Find compiler-specific source roots (`src-2`, `src-3`, version-specific test roots) and code they share.\n4. Load matching case reference from routing table before proposing a patch.\n\n## Routing Table\n\n| Change touches | Load |\n| --- | --- |\n| Acyclic `RuntimePlugin`\u002F`TestPlugin`, `PluginPhase` (`src-2`\u002F`src-3`), `BasePluginPhase.runAllUnits`, `GraphAnalysis`, `reportInform`\u002F`report.echo`, `TestUtils.make`\u002F`makeFail`, `BaseCycleTests`, bootstrap self-plugin exclusions; any plugin doing whole-run work from per-unit callback | [references\u002Facyclic-whole-run-compiler-adapters.md](references\u002Facyclic-whole-run-compiler-adapters.md) |\n| sourcecode `Args`, `argsImpl`, `SourceContext.scala`, `src-2`\u002F`src-3` `Macros.scala`, `ArgsTests` via `Main`\u002F`Tests.run`; any macro reading parameter clauses, `ValDef` RHS, or enclosing owner | [references\u002Fsourcecode-args-capture-review.md](references\u002Fsourcecode-args-capture-review.md) |\n| Ammonite `CodeClassWrapper`, `Preprocessor`, `AmmonitePlugin` used-command collector (`usedEarlierDefinitions`), session\u002Fcache bridge, `SerializationTests`, `EvaluatorTests`, `DualTestRepl`; any REPL wrapper whose import rewriting changes captured object graph | [references\u002Fammonite-symbol-derived-closure-capture.md](references\u002Fammonite-symbol-derived-closure-capture.md) |\n| Ammonite import hooks (`$repo`, `Result.Repo`), `Script.Dependencies`, `noDuplicates`, `ScriptProcessor.jarDependencies`\u002F`jarPluginDependencies`, `ScriptCompiler`, BSP `scriptScalacOptions`, `AmmoniteBuildServerTests`; any static (IDE) extraction mirroring interactive interpreter | [references\u002Fammonite-static-script-dependency-propagation.md](references\u002Fammonite-static-script-dependency-propagation.md) |\n| Fastparse `ParsingRun`, `P`, sequence\u002F`.rep`\u002F`.repX` macros (`MacroRepImpls`), higher-order wrappers such as `Indexed`, `Whitespace`, cuts in reusable whitespace\u002Fcomment parsers, Scala 2 -> 3 combinator ports; any combinator library over shared mutable run | [references\u002Ffastparse-shared-run-combinator-extraction.md](references\u002Ffastparse-shared-run-combinator-extraction.md) |\n\nPinned evidence for every case lives in `references\u002Fevidence\u002F` (exact copies of original records; claim and record IDs cited in references resolve there).\n\n## Shared Model\n\nInvariants below recur across cases; each names cases demonstrating it. Applying an invariant to another library is inference unless that library's source shows same mechanism.\n\n**M1. Capture identity, not syntactic proxy.** Capture the real runtime or compiler referent.\n- sourcecode: parameter's optional `ValDef` RHS is not caller's argument. PR 126 replaces RHS\u002F`None` fallback with `Ref(vd.symbol).asExpr`.\n- Ammonite closure: `import ...cmd0.instance.a` resolves same name but captures singleton path, so deserialization reinitializes `a`. Capture command instance.\n- Acyclic: dependency edges must keep trees (positions, symbol names, supplemental lines), not only connectivity booleans.\n- All three reject string-based substitutes: `tree.toString`\u002Fregex scans (Ammonite), rebuilt initializers or re-evaluated call-site expressions (sourcecode).\n\n**M2. Derive dependencies from typed symbols, via both term and type paths.**\n- Ammonite PR 944: `Select` receiver matching missed commands needed only through types. Fix traversed `TypeTree.tpe` for `SingleType` prefixes equal to wrapper symbol. Dropping either branch breaks a different oracle.\n- sourcecode: classify term versus type clauses by compiler's real discriminator. Erased `List[ValDef]` versus `List[TypeDef]` matching does not work (PR 103 extension-method counterexample; cast still in late-2024 source).\n- Acyclic: validity, different-source-file and `unitMap.contains(symbolPath(sym))` guards precede lookup. Out-of-run symbols are not invented edges.\n\n**M3. Execution count and timing belong to right lifetime.**\n- Acyclic: whole-run analysis in per-unit callback ran once per file, duplicating diagnostics. Run once per compilation run; do not suppress a second supported run.\n- Fastparse: child parser runs once, at original position. By-name for ordinary wrappers (PR 212 `Indexed`), inspected staging for macros.\n- Ammonite closure: deserializing and invoking captured value must not rerun its initializer.\n- Ammonite static: dependency extraction must not evaluate arbitrary script bodies. Hooks go through dummy interpreter interface: architectural boundary, not sandbox.\n- sourcecode: `Args` must materialize at call site in intended owner. Extracting a helper that materializes it elsewhere changes owner.\n\n**M4. Know who owns mutable state and when it resets.**\n- Fastparse: `val` holding a `ParsingRun` is not a snapshot. Save child results to locals before a sibling overwrites `index`\u002F`isSuccess`\u002F`successValue`\u002F`cut`\u002Fdiagnostics\u002F`noDropBuffer`.\n- Acyclic: `alreadyRun` is plugin-instance state that `init` does not visibly reset. Source does not establish whether production reuses the instance.\n- Ammonite static: stateful Interpreter mutates its repositories; static `Script` metadata carries `extraRepositories`. Both consumers intentional; do not merge.\n- Ammonite closure: used-command metadata must stay tied to command being instantiated, including cache hits and session restoration.\n\n**M5. Metadata must survive every transformation to final consumer.**\n- Ammonite static: repositories pass extraction, `Dependencies.+`, `noDuplicates`, and both ordinary and plugin resolution, reaching dependent target's classpath.\n- Acyclic: supplemental dependency lines pass shared graph code to default-visible reporter (`report.echo`, not verbose-only `inform`).\n- Fastparse: diagnostic aggregates keep child provenance after extraction.\n- sourcecode: ordered outer-list grouping of term clauses survives to `Args.value`.\n\n**M6. Keep compiler-specific representation in adapters; share only matching semantics.**\n- Acyclic PR 136: share graph operations; keep bespoke tree\u002Fsymbol\u002Funit traversal and reporting per compiler.\n- sourcecode: Scala 2 uses method symbols\u002F`paramLists`, Scala 3 inspects definition trees. Common helper must not assert equivalence.\n- Ammonite: PR 944's `TypeTree`\u002F`SingleType` shapes are Scala 2 internals, not APIs to copy into Scala 3. `-Ydelambdafy=inline` stays test-local.\n- Fastparse: Scala 2 split common macros from runtime methods; Scala 3 shares one macro inspecting inline values. PR 310: compiler-internal test adapters need version-specific roots.\n\n**M7. Check what compiler inserts.**\n- Fastparse PR 272: Scala 2 applied function-typed implicit (`P[_] => P[Unit]`) as implicit view, rewriting `Fail.!` into whitespace call that overwrote the failure. Repair: dedicated trait\u002FSAM type plus regression asserting `Parsed.Failure`. Trait change was binary incompatible, timed for 3.0.0.\n- sourcecode: implicit `Args` materializes wherever compiler resolves it; that site is inspected owner.\n\n**M8. Oracle must observe the invariant and must actually run.**\n- Observe the right thing: raw diagnostic events before set canonicalization (Acyclic); full nested `(name, value)` pairs with varying values (sourcecode); sentinel plus result plus separate type-dependency evaluator transcript (Ammonite closure); dependent-target classpath plus inverse case plus hook removal (Ammonite static); value plus consumed index plus `End` (Fastparse).\n- Actually run: unasserted `make(...).exists(...)` (Acyclic 2022); names-only Scala 3 exemption (sourcecode 2022); Scala 3 `disabled` case or object-wrapper-only `DualTestRepl` run (Ammonite); `scala2_11` guard that disabled the regression (Ammonite PR 1090); main-driven assertions reachable only via `__.test.run` (sourcecode).\n- Prove discrimination with a mutation that must make test fail (remove the once-per-run gate, revert to RHS fallback, import singletons directly, drop the `TypeTree` branch, remove the repo hook, re-add the comment cut).\n\n## Workflow\n\n1. **Classify the boundary** (transferable). Locate change: compile-time analysis, compile-time code generation, generated-code runtime, or test harness. Distinguish ordinary parameter, by-name, inline receiver, quoted expression, macro surface parameter, and completed value.\n2. **Write the behavioural baseline** (transferable). For each user-observed output, record: what is captured (M1), from which symbol\u002Ftype paths (M2), when and how often it runs (M3), which state it reads\u002Fwrites and who resets it (M4), and which consumer finally reads the metadata (M5).\n3. **Draw the adapter boundary** (transferable). List compiler-specific operations versus shared semantics (M6). Refuse shared helper hiding a representation difference.\n4. **Trace every transformation to the consumer** (transferable). Follow value\u002Fmetadata through folds, merges, deduplication, caches and reporters. Preserve ordering and dedup semantics; do not swap sequences for sets.\n5. **Check compiler insertions** (transferable). Implicit views from function-typed implicits, implicit materialization site, inline expansion. Compile with conversion diagnostics when execution is authorized.\n6. **Apply the smallest change** (transferable). Keep publication\u002Ftoolchain edits separate. Route ABI consequences to compatibility guidance.\n7. **Repair the oracle with the code** (transferable). Strengthen it to observe M1-M5, confirm test is reached on each claimed compiler cell, specify a mutation that must fail (M8).\n8. **Apply the case-specific procedure** (library-specific). Load routed reference; follow its version-pinned steps, probe matrix and validation commands.\n\n## Review and Refactoring Checks\n\n| Check | Scope |\n| --- | --- |\n| Captured value is symbol\u002Finstance reference, not initializer, singleton path or text match (M1) | Transferable |\n| Dependencies include type-derived paths, not only term selections (M2) | Transferable; collector shapes are Scala 2 Ammonite-specific |\n| Term versus type clauses classified by compiler's real discriminator; empty term clauses and group order preserved (M2) | Transferable; API is compiler-version-specific |\n| Whole-run work executes once per run, keyed to real run lifetime, not reset per callback (M3, M4) | Transferable; `alreadyRun` placement is Acyclic-specific |\n| Children\u002Farguments execute at original position and count; earlier results saved before shared state is overwritten (M3, M4) | Transferable to any shared-run combinator library |\n| Deserialization does not rerun captured initializers; unused whole commands nulled, required ones kept (M1, M3) | Ammonite class-wrapper-specific; command (not field) granularity |\n| Static extraction does not evaluate script bodies; static and interactive consumers both updated (M3, M4) | Transferable pattern; `Result.Repo`\u002F`extraRepositories` Ammonite-specific |\n| Metadata survives merge\u002Fdedup and reaches every sibling consumer (ordinary and plugin resolution; reporter) (M5) | Transferable |\n| Default visibility and severity of diagnostics unchanged; no byte-identical caret demands across compilers (M5) | Transferable; `echo` versus `inform` is Scala 3 Acyclic-specific |\n| No function-typed implicit that Scala 2 can apply as view (M7) | Transferable to Scala 2 libraries |\n| Cuts\u002Fcommitment inside reusable sub-parsers checked against enclosing repetition\u002Falternative (M3) | Fastparse-specific mechanism; transferable to cut-based parsers |\n| Specialized generated paths not replaced by runtime branching on consolidation | Fastparse-specific; measure separately from correctness |\n| Oracle observes raw\u002Fcomplete payload, runs on every claimed cell, and has failing mutation (M8) | Transferable |\n| Bootstrap\u002Fself-applied plugin not pre-rejecting test resources | Acyclic-specific, revision-dependent |\n\n## Consolidated False Positives\n\n- **Acyclic:** `makeFail` asserts internally, so its call site needs no outer `assert`; `acyclic.pkg` package-internal cycles (`success\u002Fpkg\u002Finnercycle`) are deliberate; distinct cycles may legitimately yield multiple diagnostics; caret-format differences are not drift; 2024 build need not restore 2022 bootstrap exclusions; analyzer intentionally processing one unit per callback needs no whole-run guard.\n- **sourcecode:** empty `Seq()` for parameterless method is correct; names-only API need not capture values; empty `testFramework` does not disable main-driven assertions; suspicious cast justifies targeted counterexample, not claimed crash on every compiler; IO wrappers, framework migration or public `Args` flattening are not repairs; `Name`-only formatting change is out of scope unless it alters shared ownership.\n- **Ammonite closure:** nonserializable sibling in same required command can stay reachable (not a closure cleaner); intentional singleton references and object-only commands (kept for macro ownership) keep their initialization semantics; string-based source generation is not itself forbidden; disabled Scala 3 variant is coverage boundary, not proof Scala 3 closures are unserializable.\n- **Ammonite static:** stateful REPL execution is intentional; private synchronized `addRepository` helper is not API widening; generated inert imports are not the resolution effect; different classloader topology is not automatically defective, and isolated compilation does not require a classloader DAG; multi-stage scripts need their own contract.\n- **Fastparse:** macro surface parameters can be staged without looking by-name; storing immutable `Parsed` results is safe; intentional cut after unique prefix may be necessary; explicit non-implicit function parameter cannot become view; removing all cuts or retaining all input is not a bounded repair; Scala 3 quote hygiene does not authorize removing Scala 2 qualification; shared source is not inherently slower.\n- **All:** merge or approval adds no independent behavioural proof; open proposal (Fastparse #204) or author report (#323, Acyclic PR 136 experiments) is not an adopted mechanism or reproduced result.\n\n## Version Fences\n\n| Case | Pinned eras (historical, not recommendations) |\n| --- | --- |\n| Acyclic | 2022 `e090ee2b`: Scala 2.11.12\u002F2.12.8-2.12.17\u002F2.13.0-2.13.10, Mill 0.10.10, uTest 0.8.1, `(position, message, severity)` tuples. 2024 `fbb60d12`: adds Scala 3.3.0-3.5.1 via `src-3`, Mill 0.11.12, uTest 0.8.2, `(message, severity)` pairs; CI declares Java 8. JVM only. |\n| sourcecode | PR 103: Scala 3.0.0-RC1 (2021). PR 126 (2023): Scala 3.1.3, 2.11.12\u002F2.12.16\u002F2.13.8, JS 1.10.1, Native 0.4.5. Nov 2024: 2.12.16\u002F2.13.8\u002F3.3.3, JS 1.17.0, Native 0.5.0, Mill 0.12.0. |\n| Ammonite closure | PR 736 (2018): Scala 2.12.4\u002FJVM, uTest 0.6.0, sbt `ammRepl`. PR 944 `50e075dd`: Mill 0.3.3 via `mill`, Scala 2.11.12\u002FJDK 8 and 2.12.8\u002FJDK 8 or 11. 2019 isolated-loader test; 2021 Scala 3 case disabled. |\n| Ammonite static | PR 1090 `7017cb94` (June 2020): Scala 2.12.11\u002F2.13.2, BSP 2.0.0-M6, coursier-interface 0.0.21, uTest 0.7.3, Mill 0.7.0 default; CI 2.12.11 with JDK 8\u002F11, 2.13.2 with JDK 8. JVM Scala 2 only. |\n| Fastparse | 2020: Scala 2.12.10\u002F2.13.1 JVM. 2022: repetition under `src-2`. 2024: Scala 3.3.3\u002F2.13.14\u002F2.12.19, Scala.js 1.16.0, Native 0.5.1. Fastparse 1 is outside the shared-run model. Whitespace trait (PR 272) lands at 3.0.0. |\n\n## Validation\n\n- Report every proposed test as `not executed` until you run it.\n- Discover commands from target revision's build file, launcher pin (`.mill-version`, `MILL_VERSION`, wrapper script) and CI workflow. Trace from CI entry to specific test. Historical examples: Acyclic `.\u002Fmill -i -j 0 __.publishArtifacts + __.test`; sourcecode `.\u002Fmill -i '__.test.run'`; Ammonite `TRAVIS_SCALA_VERSION=2.13.2 .\u002Fmill -i unitTest` (2020) and `TRAVIS_SCALA_VERSION=2.12.8 mill -i unitTest` (PR 944); Fastparse `.\u002Fmill -i --disable-ticker __.jvm.__.publishArtifacts + __.jvm.__.compile + __.jvm.__.test` with focused selectors such as `'fastparse.jvm[3.3.3].test'`. Each is valid only for its pinned revision.\n- Run only in separately authorized, isolated, trusted checkout with matching toolchain. Never run publish\u002Frelease\u002Fsigning jobs. Static inspection, hooks, resolution and macros can execute code or touch network.\n- Confirm target test ran on each claimed compiler\u002Fplatform cell (case count, wrapper member, not a disabled variant). JVM success is not JS\u002FNative coverage.\n- Run specified mutation for each strengthened oracle, require failure, then restore.\n- Keep correctness separate from throughput or generated-code-size measurement.\n\n## Examples\n\n### Good\n\nScala 3 port of analysis plugin keeps traversal and reporting in `src-3`, shares only graph policy, gates whole-run analysis to run lifetime, and reports supplemental lines with a default-visible call. It adds a raw-event test: two-file cycle plus unrelated third file, still expecting one top-level diagnostic (Acyclic). Same discipline for a macro: reference parameter symbol, assert complete nested `(name, value)` pairs across two invocations with different values (sourcecode).\n\n### Broken and Correction\n\nCleanup makes generated wrapper \"simpler\": rewrites captured instance to direct import (Ammonite), changes by-name child to strict parameter (Fastparse `Indexed`), or reads parameter's default RHS (sourcecode). Names and types still resolve; existing name-only or success-only tests pass. Correction: restore instance\u002Fsymbol capture and deferred execution. Then add oracle observing lost property (no reinitialization sentinel plus result; nested value\u002Foffset tuple; full value pairs) and its failing mutation.\n\n### Negative\n\nDiff only bumps release number, edits `sourcecode.Name` formatting, changes an application import, or formats already-produced `Parsed.Success`. None changes capture, timing or compiler-visible structure. Decline this workflow; do not demand macro surgery, by-name parameters or new compiler tests.\n\n## Output Contract\n\nPer finding: `file:line`, severity, violated invariant (M1-M8 plus case-specific invariant), exact revision and compiler\u002Fplatform cell, evidence record or claim ID from `references\u002Fevidence\u002F` or pinned source URL, minimal correction, discriminating test with expected failure under mutation. Label each statement: historical observation, reviewer guidance, author report, new inference, or your own execution. Include tested versus untested cells, actual command and result or `not executed`, and blockers. If no defect found, list checked capture\u002Ftiming\u002Fstate\u002Fmetadata\u002Finsertion paths and those still untested.\n\n## Limitations\n\n- Five bounded historical samples (2018-2024), mostly from com-lihaoyi libraries.\n- No upstream build, test, mutation, reused-instance or cache-independence check executed during research. Structural validity of this skill is not behavioural effectiveness.\n- Unresolved in sources: Acyclic plugin-instance reuse across runs; sourcecode mixed term\u002Ftype clause classification (no compiled repair); Ammonite Scala 3 closure capture; Ammonite static semantics on Scala 3 or later BSP APIs and for multi-stage scripts.\n- Mostly JVM evidence; Scala.js\u002FNative behaviour needs separate validation. Untrusted deserialization and untrusted hook execution are out of scope.\n\n## Sources\n\n- Case procedures: five `references\u002F*.md` files in routing table.\n- Pinned evidence: [acyclic](references\u002Fevidence\u002Fscala-acyclic-whole-run-compiler-adapters.json), [sourcecode](references\u002Fevidence\u002Fscala-sourcecode-args-capture-review.json), [Ammonite closure](references\u002Fevidence\u002Fscala-ammonite-symbol-derived-closure-capture.json), [Ammonite static](references\u002Fevidence\u002Fscala-ammonite-static-script-dependency-propagation.json), [Fastparse](references\u002Fevidence\u002Fscala-fastparse-shared-run-combinator-extraction.json).\n- Key upstream discussions: [Acyclic PR 136](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002Facyclic\u002Fpull\u002F136#discussion_r1760522833), [sourcecode PR 103](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002Fsourcecode\u002Fpull\u002F103#discussion_r577846016), [Ammonite PR 736](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002FAmmonite\u002Fpull\u002F736#issuecomment-355239967), [Ammonite PR 1090](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002FAmmonite\u002Fpull\u002F1090#issuecomment-638956149), [Fastparse PR 272](https:\u002F\u002Fgithub.com\u002Fcom-lihaoyi\u002Ffastparse\u002Fcommit\u002F22051f098d4cf3f2cb7510ba214cbf2e9b478108).\n",{"name":5,"license":15,"description":7},"main","101d0f67250256ca5d80dc3f95767cad7b541457","skills\u002Fscala\u002Fscala-compiler-macro-refactoring","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents","https:\u002F\u002Fgithub.com\u002Fw0rxbend","https:\u002F\u002Freadme.worxbend.com\u002F","Fluent in Backend-ese (microservices, distributed systems, you know the drill)\r\nFunctional Programming Fanatic...","2026-11-14 14:44:12",{"source":8,"skillName":5,"commands":34,"prompt":44,"zipAvailable":45},[35,38,41],{"tool":36,"command":37},"npx","npx skills add w0rxbend\u002Fdot-agents --skill scala-compiler-macro-refactoring",{"tool":39,"command":40},"bunx","bunx skills add w0rxbend\u002Fdot-agents --skill scala-compiler-macro-refactoring",{"tool":42,"command":43},"pnpm","pnpm dlx skills add w0rxbend\u002Fdot-agents --skill scala-compiler-macro-refactoring","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002FSKILL.md",true,[47,51,57,61,65,69,73,77,81,85,89],{"path":48,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":50,"sourceHtmlUrl":16},"LICENSE","许可证",1280,{"path":52,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":55,"sourceHtmlUrl":56},"references\u002Facyclic-whole-run-compiler-adapters.md","REFERENCE","参考文档",15415,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Facyclic-whole-run-compiler-adapters.md",{"path":58,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":59,"sourceHtmlUrl":60},"references\u002Fammonite-static-script-dependency-propagation.md",9126,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Fammonite-static-script-dependency-propagation.md",{"path":62,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":63,"sourceHtmlUrl":64},"references\u002Fammonite-symbol-derived-closure-capture.md",10914,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Fammonite-symbol-derived-closure-capture.md",{"path":66,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":67,"sourceHtmlUrl":68},"references\u002Fevidence\u002Fscala-acyclic-whole-run-compiler-adapters.json",25134,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Fevidence\u002Fscala-acyclic-whole-run-compiler-adapters.json",{"path":70,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":71,"sourceHtmlUrl":72},"references\u002Fevidence\u002Fscala-ammonite-static-script-dependency-propagation.json",17377,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Fevidence\u002Fscala-ammonite-static-script-dependency-propagation.json",{"path":74,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":75,"sourceHtmlUrl":76},"references\u002Fevidence\u002Fscala-ammonite-symbol-derived-closure-capture.json",22847,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Fevidence\u002Fscala-ammonite-symbol-derived-closure-capture.json",{"path":78,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":79,"sourceHtmlUrl":80},"references\u002Fevidence\u002Fscala-fastparse-shared-run-combinator-extraction.json",35096,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Fevidence\u002Fscala-fastparse-shared-run-combinator-extraction.json",{"path":82,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":83,"sourceHtmlUrl":84},"references\u002Fevidence\u002Fscala-sourcecode-args-capture-review.json",19585,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Fevidence\u002Fscala-sourcecode-args-capture-review.json",{"path":86,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":87,"sourceHtmlUrl":88},"references\u002Ffastparse-shared-run-combinator-extraction.md",15141,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Ffastparse-shared-run-combinator-extraction.md",{"path":90,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":91,"sourceHtmlUrl":92},"references\u002Fsourcecode-args-capture-review.md",12332,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-compiler-macro-refactoring\u002Freferences\u002Fsourcecode-args-capture-review.md",[94,101,108,116,123,130],{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":20},"01M7E6TS1SW1ZSXN748N0RBGHT","wiki-builder","Create and maintain a local Markdown research wiki (sources with provenance, compiled concept\u002Fsource pages, index, maintenance log) driven by a per-wiki config. Use when the user wants to start a wiki or knowledge base, ingest sources into one, or query and update it; use wiki-page-writer for a single code deep-dive page.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fwiki-builder\u002FSKILL.md",[],[],{"skillNo":102,"name":103,"nameZh":6,"description":104,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":105,"categories":106,"keywords":107,"publishedAt":20},"01M7E6S8ARS0VQR85H4FEC390B","refactoring-guru","Diagnose a named code smell and apply the smallest behavior-preserving refactoring, with verification before and after and an explicit stop condition. Use for structural refactors (extract, move, consolidate, change ownership), not for feature or bug work; for readability cleanup of recent changes use code-simplification.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Frefactoring-guru\u002FSKILL.md",[],[],{"skillNo":109,"name":110,"nameZh":6,"description":111,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":112,"sourceHtmlUrl":113,"categories":114,"keywords":115,"publishedAt":20},"01M7E6RRXCYGSHA0ZBFX3YZP7Y","legacy-seams","When changing untested legacy code, pin the observed results with characterization tests and open the smallest seam that substitutes only the blocking dependency, separate from any later logic change. Use when a clock, random source, I\u002FO, global, or hidden constructor blocks a test or a safe edit. Use test-driven-development for a new behavior or a bug, refactoring-guru for one named structural refactor after the seam exists, and code-refactoring-tech-debt to choose which legacy to replace.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Flegacy-seams\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Flegacy-seams\u002FSKILL.md",[],[],{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":122,"publishedAt":20},"01M7E6QZ11XWSNHCBGYK8HH97C","idea-refine","Refine a raw idea into a one-page brief (problem statement, recommended direction, assumptions to validate, MVP scope, not-doing list) through divergent then convergent thinking. Use when an idea is still vague or you want options and a stress test before committing; use interview-me when the goal itself is unclear and spec-driven-development once the direction is chosen.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fidea-refine\u002FSKILL.md",[],[],{"skillNo":124,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":127,"categories":128,"keywords":129,"publishedAt":20},"01M7E6N2N7BYW7BA5XGM0QD3B4","code-review-and-quality","Review rubric and approval standard for any change before merge, including code written by you, another agent, or a human: five axes (correctness, readability, architecture, security, performance), change sizing, structural remedies, severity labels, and feedback technique. Use to judge whether a change is fit to merge; use code-review to run a PR or diff review end to end.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fcode-review-and-quality\u002FSKILL.md",[],[],{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":134,"sourceHtmlUrl":135,"categories":136,"keywords":137,"publishedAt":20},"01M7E6MNCZPTRD77Z419X755HQ","code-perfection","Smell and style gate for code you write or change. Bans known code smells (long method, large class, primitive obsession, long parameter list, data clumps, duplicate code, dead code, feature envy, shotgun surgery, flag arguments, message chains) and enforces behavior-preserving structure. On Scala files, enforces worxbend style. Use while implementing, reviewing a diff for smells, or when a smell or style violation is suspected. Routine construction stays with code-complete. SOLID and DRY stay with clean-code-guard. One named structural refactor stays with refactoring-guru.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fcode-perfection\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fcode-perfection\u002FSKILL.md",[],[]]