@phuc1403/musketeer 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +2 -2
  2. package/manifest.json +12 -3
  3. package/package.json +1 -1
  4. package/src/provisioner/detect.js +17 -2
  5. package/src/resolver.js +8 -3
  6. package/src/schema.js +1 -0
  7. package/src/settings-merger.js +0 -0
  8. package/template/.claude/hooks/inject-naming-rule-into-subagents.cjs +44 -0
  9. package/template/.claude/rules/csharp-identifier-naming.md +77 -0
  10. package/template/.claude/skills/code-review/SKILL.md +4 -1
  11. package/template/.claude/skills/code-review/references/naming-rule-review.md +41 -0
  12. package/template/.claude/skills/logical-components/SKILL.md +23 -18
  13. package/template/.claude/skills/logical-components/references/component-classifier-prompt.md +1 -1
  14. package/template/.claude/skills/logical-components/references/responsibility-agent-prompt.md +1 -1
  15. package/template/.claude/skills/logical-components/scripts/Directory.Build.rsp +1 -0
  16. package/template/.claude/skills/logical-components/scripts/Directory.Build.targets +6 -0
  17. package/template/.claude/skills/logical-components/scripts/LogicalComponents/BatchPlanning.cs +2 -1
  18. package/template/.claude/skills/logical-components/scripts/LogicalComponents/BatchesCommand.cs +9 -1
  19. package/template/.claude/skills/logical-components/scripts/LogicalComponents/CandidatesCommand.cs +39 -11
  20. package/template/.claude/skills/logical-components/scripts/LogicalComponents/CitableSource.cs +19 -4
  21. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ClassifyBatchesCommand.cs +25 -4
  22. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ClassifyMergeCommand.cs +43 -11
  23. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ComponentDiscovery.cs +20 -6
  24. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ComponentRule.cs +57 -14
  25. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ComponentsFile.cs +20 -2
  26. package/template/.claude/skills/logical-components/scripts/LogicalComponents/CouplingResolver.cs +70 -15
  27. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ExtractCommand.cs +28 -13
  28. package/template/.claude/skills/logical-components/scripts/LogicalComponents/MarkdownCodeSpans.cs +72 -0
  29. package/template/.claude/skills/logical-components/scripts/LogicalComponents/MarkdownRenderer.cs +11 -6
  30. package/template/.claude/skills/logical-components/scripts/LogicalComponents/MemberUseResolution.cs +91 -22
  31. package/template/.claude/skills/logical-components/scripts/LogicalComponents/MemberUses.cs +85 -9
  32. package/template/.claude/skills/logical-components/scripts/LogicalComponents/PlainText.cs +55 -0
  33. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ProjectFilters.cs +3 -2
  34. package/template/.claude/skills/logical-components/scripts/LogicalComponents/PruneCommand.cs +36 -4
  35. package/template/.claude/skills/logical-components/scripts/LogicalComponents/RenderCommand.cs +75 -14
  36. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ResponsibilityValidation.cs +45 -26
  37. package/template/.claude/skills/logical-components/scripts/LogicalComponents/SeamDispatch.cs +56 -0
  38. package/template/.claude/skills/logical-components/scripts/LogicalComponents/SourceCodeLines.cs +79 -0
  39. package/template/.claude/skills/logical-components/scripts/LogicalComponents/TypeMap.cs +31 -0
  40. package/template/.claude/skills/logical-components/scripts/LogicalComponents/WorkspaceLoader.cs +86 -16
  41. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/BatchPlanningTests.cs +8 -0
  42. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/BatchesCommandTests.cs +37 -0
  43. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/CandidatesCommandTests.cs +25 -0
  44. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/ClassifyCommandsTests.cs +73 -0
  45. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/ComponentDiscoveryTests.cs +63 -0
  46. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/CouplingAppExtractionTests.cs +188 -0
  47. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/CouplingAppWorkspace.cs +30 -0
  48. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/CouplingExtractionTests.cs +1 -1
  49. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/FixturePaths.cs +4 -0
  50. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/MarkdownRendererTests.cs +45 -2
  51. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/ProjectFiltersTests.cs +4 -0
  52. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/PruneCommandTests.cs +30 -0
  53. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/RenderCommandTests.cs +66 -3
  54. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/RenderTestData.cs +19 -13
  55. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/ResponsibilityValidationTests.cs +89 -1
  56. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/WorkspaceLoaderTests.cs +181 -2
  57. package/template/.claude/skills/logical-components/scripts/NuGet.config +17 -0
  58. package/template/.claude/skills/logical-components/scripts/fixtures/CompositionRootApp/CompositionRootApp.slnx +5 -0
  59. package/template/.claude/skills/logical-components/scripts/fixtures/CompositionRootApp/src/Root.Application/HostBuilderExtensions.cs +15 -0
  60. package/template/.claude/skills/logical-components/scripts/fixtures/CompositionRootApp/src/Root.Application/HostBuilderShims.cs +25 -0
  61. package/template/.claude/skills/logical-components/scripts/fixtures/CompositionRootApp/src/Root.Application/NativeInterop.cs +17 -0
  62. package/template/.claude/skills/logical-components/scripts/fixtures/CompositionRootApp/src/Root.Application/Root.Application.csproj +7 -0
  63. package/template/.claude/skills/logical-components/scripts/fixtures/CompositionRootApp/src/Root.Application/RootAutofacModule.cs +11 -0
  64. package/template/.claude/skills/logical-components/scripts/fixtures/CompositionRootApp/src/Root.Application/RootGreeter.cs +7 -0
  65. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/logical-components.json +48 -0
  66. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/AbstractMemberCases.cs +27 -0
  67. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/AttributeCases.cs +23 -0
  68. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/CouplingApp.Application.csproj +7 -0
  69. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/GenericBaseCases.cs +14 -0
  70. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/GenericSeamBindingCases.cs +59 -0
  71. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/ImplicitCallCases.cs +230 -0
  72. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/PartialInheritCases.First.cs +11 -0
  73. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/PartialInheritCases.Second.cs +14 -0
  74. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/StackOverflowCases.cs +14 -0
  75. package/template/.claude/skills/logical-components/scripts/fixtures/CouplingApp/src/CouplingApp.Application/ViaDisambiguationCases.cs +36 -0
  76. package/template/.claude/skills/logical-components/scripts/fixtures/MultiTargetApp/MultiTargetApp.slnx +1 -0
  77. package/template/.claude/skills/logical-components/scripts/fixtures/MultiTargetApp/src/Multi.Infrastructure/Multi.Infrastructure.csproj +12 -0
  78. package/template/.claude/skills/logical-components/scripts/fixtures/MultiTargetApp/src/Multi.Infrastructure/SchedulingClient.cs +12 -0
  79. package/template/.claude/skills/logical-components/scripts/fixtures/ObjOutputApp/ObjOutputApp.slnx +5 -0
  80. package/template/.claude/skills/logical-components/scripts/fixtures/ObjOutputApp/src/Obj.Application/Greeting.cs +7 -0
  81. package/template/.claude/skills/logical-components/scripts/fixtures/ObjOutputApp/src/Obj.Application/Obj.Application.csproj +14 -0
  82. package/template/.claude/skills/logical-components/scripts/fixtures/RenderGolden/components.json +5 -1
@@ -0,0 +1,27 @@
1
+ namespace CouplingApp.Application;
2
+
3
+ public abstract class PartlyImplemented
4
+ {
5
+ // Not virtual: this body runs for every subclass (or none), so it is coupling even with no subclass in the repo.
6
+ public void Ready() => ReadyTarget.Touch();
7
+
8
+ // Virtual with zero implementations in the repo: nothing to walk, but the tool should say so instead of staying
9
+ // silent.
10
+ public abstract void Missing();
11
+ }
12
+
13
+ public sealed class ReadyTarget
14
+ {
15
+ public static void Touch()
16
+ {
17
+ }
18
+ }
19
+
20
+ public sealed class PartlyImplementedUsing
21
+ {
22
+ public void Run(PartlyImplemented value)
23
+ {
24
+ value.Ready();
25
+ value.Missing();
26
+ }
27
+ }
@@ -0,0 +1,23 @@
1
+ namespace CouplingApp.Application;
2
+
3
+ // An attribute's constructor must not be treated as coupling: applying an attribute is metadata the compiler reads,
4
+ // not code the annotated member runs.
5
+ public sealed class AuditedAttribute : Attribute
6
+ {
7
+ public AuditedAttribute() => AttributeTarget.Touch();
8
+ }
9
+
10
+ public sealed class AttributeTarget
11
+ {
12
+ public static void Touch()
13
+ {
14
+ }
15
+ }
16
+
17
+ [Audited]
18
+ public sealed class AttributedRunning
19
+ {
20
+ public void Run()
21
+ {
22
+ }
23
+ }
@@ -0,0 +1,7 @@
1
+ <Project Sdk="Microsoft.NET.Sdk">
2
+ <PropertyGroup>
3
+ <TargetFramework>net10.0</TargetFramework>
4
+ <Nullable>enable</Nullable>
5
+ <ImplicitUsings>enable</ImplicitUsings>
6
+ </PropertyGroup>
7
+ </Project>
@@ -0,0 +1,14 @@
1
+ namespace CouplingApp.Application;
2
+
3
+ // A generic abstract base: its own type parameter must bind to what each concrete subclass supplies (however many
4
+ // levels up the walk gathers this base's own code as the subclass's behaviour), or a seam it calls looks unbound and
5
+ // matches every construction. Uses IHandler<T>/PingHandling/PongHandling from GenericSeamBindingCases.cs.
6
+ public abstract class HandlerBase<T>(IHandler<T> inner)
7
+ {
8
+ protected void Run(T command) => inner.Handle(command);
9
+ }
10
+
11
+ public sealed class PingRunning(IHandler<Ping> handler) : HandlerBase<Ping>(handler)
12
+ {
13
+ public void Execute(Ping ping) => Run(ping);
14
+ }
@@ -0,0 +1,59 @@
1
+ namespace CouplingApp.Application;
2
+
3
+ public sealed record Ping(int Value);
4
+
5
+ public sealed record Pong(int Value);
6
+
7
+ public interface IHandler<T>
8
+ {
9
+ void Handle(T command);
10
+ }
11
+
12
+ public sealed class PingHandling : IHandler<Ping>
13
+ {
14
+ public void Handle(Ping command)
15
+ {
16
+ }
17
+ }
18
+
19
+ public sealed class PongHandling : IHandler<Pong>
20
+ {
21
+ public void Handle(Pong command)
22
+ {
23
+ }
24
+ }
25
+
26
+ // A generic method declared on a seam: walking the implementation must bind the method's own type parameter to what
27
+ // this use supplied, or the seam it calls in turn looks unbound and matches every construction.
28
+ public interface IDispatch
29
+ {
30
+ void Send<T>(T command);
31
+ }
32
+
33
+ public sealed class Dispatch(IEnumerable<object> handlers) : IDispatch
34
+ {
35
+ public void Send<T>(T command)
36
+ {
37
+ foreach (var handler in handlers.OfType<IHandler<T>>())
38
+ {
39
+ handler.Handle(command);
40
+ }
41
+ }
42
+ }
43
+
44
+ public sealed class GenericMethodDispatching(IDispatch dispatch)
45
+ {
46
+ public void Run() => dispatch.Send(new Ping(1));
47
+ }
48
+
49
+ // An open-generic decorator wrapping the same generic seam it implements: T must stay bound to the seam's own
50
+ // construction at the use, or the decorator's own call looks unbound and matches every construction it wraps.
51
+ public sealed class Decorator<T>(IHandler<T> inner) : IHandler<T>
52
+ {
53
+ public void Handle(T command) => inner.Handle(command);
54
+ }
55
+
56
+ public sealed class DecoratedDispatching(IHandler<Ping> handler)
57
+ {
58
+ public void Run(Ping ping) => handler.Handle(ping);
59
+ }
@@ -0,0 +1,230 @@
1
+ using System.Collections;
2
+ using System.Runtime.CompilerServices;
3
+
4
+ namespace CouplingApp.Application;
5
+
6
+ // A collection initializer's elements run the type's Add method.
7
+ public sealed class Bag : IEnumerable<int>
8
+ {
9
+ private readonly List<int> _items = [];
10
+
11
+ public void Add(int item)
12
+ {
13
+ AddTarget.Touch();
14
+ _items.Add(item);
15
+ }
16
+
17
+ public IEnumerator<int> GetEnumerator() => _items.GetEnumerator();
18
+
19
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
20
+ }
21
+
22
+ public sealed class AddTarget
23
+ {
24
+ public static void Touch()
25
+ {
26
+ }
27
+ }
28
+
29
+ public sealed class CollectionInitializerRunning
30
+ {
31
+ public Bag Make() => new() { 1, 2 };
32
+ }
33
+
34
+ // A deconstruction, by assignment or by a foreach variable, runs the target's Deconstruct method.
35
+ public sealed class Point(int x, int y)
36
+ {
37
+ public void Deconstruct(out int deconstructedX, out int deconstructedY)
38
+ {
39
+ DeconstructTarget.Touch();
40
+ deconstructedX = x;
41
+ deconstructedY = y;
42
+ }
43
+ }
44
+
45
+ public sealed class DeconstructTarget
46
+ {
47
+ public static void Touch()
48
+ {
49
+ }
50
+ }
51
+
52
+ public sealed class DeconstructAssigning
53
+ {
54
+ public void Run()
55
+ {
56
+ int x, y;
57
+ (x, y) = new Point(1, 2);
58
+ }
59
+ }
60
+
61
+ public sealed class PointSequence
62
+ {
63
+ public IEnumerator<Point> GetEnumerator() => new List<Point> { new(1, 2) }.GetEnumerator();
64
+ }
65
+
66
+ public sealed class ForeachDeconstructing
67
+ {
68
+ public int Sum()
69
+ {
70
+ var sum = 0;
71
+ foreach (var (a, b) in new PointSequence())
72
+ {
73
+ sum += a + b;
74
+ }
75
+
76
+ return sum;
77
+ }
78
+ }
79
+
80
+ // A static constructor runs once, lazily, before the type's first static member use or instantiation.
81
+ public sealed class StaticSeed
82
+ {
83
+ public static readonly int Value;
84
+
85
+ static StaticSeed() => StaticCtorTarget.Touch();
86
+ }
87
+
88
+ public sealed class StaticCtorTarget
89
+ {
90
+ public static void Touch()
91
+ {
92
+ }
93
+ }
94
+
95
+ public sealed class StaticSeedReading
96
+ {
97
+ public int Read() => StaticSeed.Value;
98
+ }
99
+
100
+ // await runs GetAwaiter, IsCompleted's getter and GetResult on a custom (non-framework) awaitable.
101
+ public sealed class CustomAwaiter(int value) : INotifyCompletion
102
+ {
103
+ public bool IsCompleted
104
+ {
105
+ get
106
+ {
107
+ IsCompletedTarget.Touch();
108
+ return true;
109
+ }
110
+ }
111
+
112
+ public int GetResult()
113
+ {
114
+ GetResultTarget.Touch();
115
+ return value;
116
+ }
117
+
118
+ public void OnCompleted(Action continuation) => continuation();
119
+ }
120
+
121
+ public sealed class CustomAwaitable(int value)
122
+ {
123
+ public CustomAwaiter GetAwaiter()
124
+ {
125
+ GetAwaiterTarget.Touch();
126
+ return new CustomAwaiter(value);
127
+ }
128
+ }
129
+
130
+ public sealed class GetAwaiterTarget
131
+ {
132
+ public static void Touch()
133
+ {
134
+ }
135
+ }
136
+
137
+ public sealed class IsCompletedTarget
138
+ {
139
+ public static void Touch()
140
+ {
141
+ }
142
+ }
143
+
144
+ public sealed class GetResultTarget
145
+ {
146
+ public static void Touch()
147
+ {
148
+ }
149
+ }
150
+
151
+ public sealed class Awaiting
152
+ {
153
+ public async Task<int> RunAsync() => await new CustomAwaitable(1);
154
+ }
155
+
156
+ // A foreach over a hand-written (non-iterator) enumerator runs its own MoveNext and Current, not just GetEnumerator.
157
+ public sealed class NumberEnumerator
158
+ {
159
+ private int _current;
160
+
161
+ public int Current
162
+ {
163
+ get
164
+ {
165
+ CurrentTarget.Touch();
166
+ return _current;
167
+ }
168
+ }
169
+
170
+ public bool MoveNext()
171
+ {
172
+ MoveNextTarget.Touch();
173
+ if (_current >= 2)
174
+ {
175
+ return false;
176
+ }
177
+
178
+ _current++;
179
+ return true;
180
+ }
181
+ }
182
+
183
+ public sealed class NumberSequence
184
+ {
185
+ public NumberEnumerator GetEnumerator() => new();
186
+ }
187
+
188
+ public sealed class CurrentTarget
189
+ {
190
+ public static void Touch()
191
+ {
192
+ }
193
+ }
194
+
195
+ public sealed class MoveNextTarget
196
+ {
197
+ public static void Touch()
198
+ {
199
+ }
200
+ }
201
+
202
+ public sealed class CustomForEaching
203
+ {
204
+ public int Sum()
205
+ {
206
+ var sum = 0;
207
+ foreach (var n in new NumberSequence())
208
+ {
209
+ sum += n;
210
+ }
211
+
212
+ return sum;
213
+ }
214
+ }
215
+
216
+ // A conditional-access indexer (x?[i]) runs the indexer's getter same as x[i] does.
217
+ public sealed class Grid
218
+ {
219
+ public int this[int index] => IndexerTarget.Touch();
220
+ }
221
+
222
+ public sealed class IndexerTarget
223
+ {
224
+ public static int Touch() => 1;
225
+ }
226
+
227
+ public sealed class ConditionalIndexing
228
+ {
229
+ public int? Read(Grid? grid) => grid?[0];
230
+ }
@@ -0,0 +1,11 @@
1
+ namespace CouplingApp.Application;
2
+
3
+ // This partial fragment has a base list too, but it names only an interface, never PartialBase: the inherits
4
+ // citation must not land here just because it is the first declaration with any base list at all.
5
+ public interface IMarker
6
+ {
7
+ }
8
+
9
+ public sealed partial class PartialInheriting : IMarker
10
+ {
11
+ }
@@ -0,0 +1,14 @@
1
+ namespace CouplingApp.Application;
2
+
3
+ public class PartialBase
4
+ {
5
+ public void Ping()
6
+ {
7
+ }
8
+ }
9
+
10
+ // The inherits edge must cite this base list, the one that actually names PartialBase.
11
+ public sealed partial class PartialInheriting : PartialBase
12
+ {
13
+ public void Act() => Ping();
14
+ }
@@ -0,0 +1,14 @@
1
+ namespace CouplingApp.Application;
2
+
3
+ // A generic helper that instantiates itself one level deeper at every recursive call (Nest<T> calling Nest<List<T>>):
4
+ // the (member, bindings) pair walked never repeats, so the cycle guard alone can't stop it. Without a depth bound the
5
+ // walk would recurse until the process stack overflows.
6
+ public static class Nest<T>
7
+ {
8
+ public static int Go(int n) => n <= 0 ? 0 : Nest<List<T>>.Go(n - 1);
9
+ }
10
+
11
+ public sealed class NestRunning
12
+ {
13
+ public int Run() => Nest<int>.Go(3);
14
+ }
@@ -0,0 +1,36 @@
1
+ namespace CouplingApp.Application.Left
2
+ {
3
+ // Two unrelated types named Builder, in different namespaces, on the same coupling path: via must tell them apart
4
+ // instead of both showing as the bare, indistinguishable "Builder".
5
+ public sealed class Builder
6
+ {
7
+ public string Make() => new CouplingApp.Application.Right.Builder().Build();
8
+ }
9
+ }
10
+
11
+ namespace CouplingApp.Application.Right
12
+ {
13
+ public sealed class Builder
14
+ {
15
+ public string Build()
16
+ {
17
+ CouplingApp.Application.ViaTarget.Touch();
18
+ return "built";
19
+ }
20
+ }
21
+ }
22
+
23
+ namespace CouplingApp.Application
24
+ {
25
+ public sealed class ViaTarget
26
+ {
27
+ public static void Touch()
28
+ {
29
+ }
30
+ }
31
+
32
+ public sealed class ViaDisambiguating
33
+ {
34
+ public string Run() => new Left.Builder().Make();
35
+ }
36
+ }
@@ -1,6 +1,7 @@
1
1
  <Solution>
2
2
  <Folder Name="/src/">
3
3
  <Project Path="src/Multi.Application/Multi.Application.csproj" />
4
+ <Project Path="src/Multi.Infrastructure/Multi.Infrastructure.csproj" />
4
5
  <Project Path="src/Legacy.FSharp/Legacy.FSharp.fsproj" />
5
6
  </Folder>
6
7
  </Solution>
@@ -0,0 +1,12 @@
1
+ <Project Sdk="Microsoft.NET.Sdk">
2
+ <PropertyGroup>
3
+ <TargetFramework>net8.0</TargetFramework>
4
+ <Nullable>enable</Nullable>
5
+ <ImplicitUsings>enable</ImplicitUsings>
6
+ </PropertyGroup>
7
+ <ItemGroup>
8
+ <!-- Single-targeted, so MSBuild resolves this reference to the net8.0 copy of Multi.Application, not the
9
+ net10.0 copy the loader keeps: proves a reference to a dropped TFM copy survives KeepSourceProjects. -->
10
+ <ProjectReference Include="../Multi.Application/Multi.Application.csproj" />
11
+ </ItemGroup>
12
+ </Project>
@@ -0,0 +1,12 @@
1
+ using Multi.Application;
2
+
3
+ namespace Multi.Infrastructure;
4
+
5
+ /// <summary>
6
+ /// Targets only net8.0 and ctor-injects a type from the multi-targeted Multi.Application, whose net8.0 copy the loader
7
+ /// drops: its reference must follow the kept copy.
8
+ /// </summary>
9
+ public sealed class SchedulingClient(Scheduling scheduling)
10
+ {
11
+ public DateOnly Tomorrow(DateOnly from) => scheduling.Next(from);
12
+ }
@@ -0,0 +1,5 @@
1
+ <Solution>
2
+ <Folder Name="/src/">
3
+ <Project Path="src/Obj.Application/Obj.Application.csproj" />
4
+ </Folder>
5
+ </Solution>
@@ -0,0 +1,7 @@
1
+ namespace Obj.Application;
2
+
3
+ /// <summary>A normal, real-source candidate: contrast for GrpcStub (written under obj/ at test time).</summary>
4
+ public sealed class Greeting
5
+ {
6
+ public string For(string name) => $"Hello, {name}!";
7
+ }
@@ -0,0 +1,14 @@
1
+ <Project Sdk="Microsoft.NET.Sdk">
2
+ <PropertyGroup>
3
+ <TargetFramework>net10.0</TargetFramework>
4
+ <Nullable>enable</Nullable>
5
+ <ImplicitUsings>enable</ImplicitUsings>
6
+ </PropertyGroup>
7
+ <ItemGroup>
8
+ <!-- Simulates gRPC/NSwag output written into obj/ by a build-time code generator: an explicit Compile item
9
+ (not the SDK's default glob, which excludes obj/) pointing at a real file, not a Roslyn source generator's
10
+ virtual document. obj/ is gitignored in scripts/, so this file is not checked in; the test that loads this
11
+ fixture writes it before calling WorkspaceLoader.LoadAsync. -->
12
+ <Compile Include="obj/Generated/GrpcStub.cs" />
13
+ </ItemGroup>
14
+ </Project>
@@ -59,5 +59,9 @@
59
59
  "at": "src/App/OrderAcceptance.cs:3"
60
60
  }
61
61
  ],
62
- "warnings": []
62
+ "warnings": [],
63
+ "fileHashes": {
64
+ "src/App/OrderAcceptance.cs": "28a98da24919780874e1d25e8c2c9ef6b496cf3dfd6dc171e79dda6bfc9f062a",
65
+ "src/Infra/OrderQueue.cs": "5d0de05d2b60730ec4accce7cc93da9c025fb7961549a1ca154400a6de5d12b7"
66
+ }
63
67
  }