moonscratch 0.1.1 → 0.1.2

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 (149) hide show
  1. package/dist/chunk-DQk6qfdC.mjs +18 -0
  2. package/dist/index.d.mts +1173 -0
  3. package/dist/index.mjs +27135 -0
  4. package/package.json +6 -1
  5. package/.agents/skills/moonbit-agent-guide/LICENSE +0 -202
  6. package/.agents/skills/moonbit-agent-guide/SKILL.mbt.md +0 -1126
  7. package/.agents/skills/moonbit-agent-guide/SKILL.md +0 -1126
  8. package/.agents/skills/moonbit-agent-guide/ide.md +0 -116
  9. package/.agents/skills/moonbit-agent-guide/references/advanced-moonbit-build.md +0 -106
  10. package/.agents/skills/moonbit-agent-guide/references/moonbit-language-fundamentals.mbt.md +0 -422
  11. package/.agents/skills/moonbit-agent-guide/references/moonbit-language-fundamentals.md +0 -422
  12. package/.agents/skills/moonbit-practice/SKILL.md +0 -258
  13. package/.agents/skills/moonbit-practice/assets/ci.yaml +0 -25
  14. package/.agents/skills/moonbit-practice/reference/agents.md +0 -1469
  15. package/.agents/skills/moonbit-practice/reference/configuration.md +0 -228
  16. package/.agents/skills/moonbit-practice/reference/ffi.md +0 -229
  17. package/.agents/skills/moonbit-practice/reference/ide.md +0 -189
  18. package/.agents/skills/moonbit-practice/reference/performance.md +0 -217
  19. package/.agents/skills/moonbit-practice/reference/refactor.md +0 -154
  20. package/.agents/skills/moonbit-practice/reference/stdlib.md +0 -351
  21. package/.agents/skills/moonbit-practice/reference/testing.md +0 -228
  22. package/.agents/skills/moonbit-refactoring/LICENSE +0 -21
  23. package/.agents/skills/moonbit-refactoring/SKILL.md +0 -323
  24. package/.githooks/README.md +0 -23
  25. package/.githooks/pre-commit +0 -3
  26. package/.github/workflows/copilot-setup-steps.yml +0 -40
  27. package/AGENTS.md +0 -91
  28. package/PLAN.md +0 -64
  29. package/TODO.md +0 -120
  30. package/benchmarks/calc.bench.ts +0 -144
  31. package/benchmarks/draw.bench.ts +0 -215
  32. package/benchmarks/load.bench.ts +0 -28
  33. package/benchmarks/render.bench.ts +0 -53
  34. package/benchmarks/run.bench.ts +0 -8
  35. package/benchmarks/types.d.ts +0 -15
  36. package/docs/scratch-vm-specs/eventloop.md +0 -103
  37. package/docs/scratch-vm-specs/moonscratch-time-separation.md +0 -50
  38. package/index.html +0 -91
  39. package/js/AGENTS.md +0 -5
  40. package/js/a.ts +0 -52
  41. package/js/assets/AGENTS.md +0 -5
  42. package/js/assets/base64.test.ts +0 -14
  43. package/js/assets/base64.ts +0 -21
  44. package/js/assets/build-asset.test.ts +0 -26
  45. package/js/assets/build-asset.ts +0 -28
  46. package/js/assets/create.test.ts +0 -142
  47. package/js/assets/create.ts +0 -122
  48. package/js/assets/index.test.ts +0 -15
  49. package/js/assets/index.ts +0 -2
  50. package/js/assets/types.ts +0 -26
  51. package/js/assets/validation.test.ts +0 -34
  52. package/js/assets/validation.ts +0 -25
  53. package/js/assets.test.ts +0 -14
  54. package/js/assets.ts +0 -1
  55. package/js/index.test.ts +0 -26
  56. package/js/index.ts +0 -3
  57. package/js/render/index.test.ts +0 -65
  58. package/js/render/index.ts +0 -13
  59. package/js/render/sharp.ts +0 -87
  60. package/js/render/svg.ts +0 -68
  61. package/js/render/types.ts +0 -35
  62. package/js/render/utils.ts +0 -108
  63. package/js/render/webgl.ts +0 -274
  64. package/js/sharp-optional.d.ts +0 -16
  65. package/js/test/helpers.ts +0 -116
  66. package/js/test/hikkaku-sample.test.ts +0 -37
  67. package/js/test/rubik-components.input-motion.test.ts +0 -60
  68. package/js/test/rubik-components.lists.test.ts +0 -49
  69. package/js/test/rubik-components.operators.test.ts +0 -104
  70. package/js/test/rubik-components.pen.test.ts +0 -112
  71. package/js/test/rubik-components.procedures-loops.test.ts +0 -72
  72. package/js/test/rubik-components.variables-branches.test.ts +0 -57
  73. package/js/test/rubik-components.visibility-entry.test.ts +0 -31
  74. package/js/test/test-projects.ts +0 -598
  75. package/js/test/variable.ts +0 -200
  76. package/js/test/warp.test.ts +0 -59
  77. package/js/vm/AGENTS.md +0 -6
  78. package/js/vm/README.md +0 -183
  79. package/js/vm/bindings.test.ts +0 -13
  80. package/js/vm/bindings.ts +0 -5
  81. package/js/vm/compare-operators.test.ts +0 -145
  82. package/js/vm/constants.test.ts +0 -11
  83. package/js/vm/constants.ts +0 -4
  84. package/js/vm/effect-guards.test.ts +0 -68
  85. package/js/vm/effect-guards.ts +0 -44
  86. package/js/vm/factory.test.ts +0 -486
  87. package/js/vm/factory.ts +0 -615
  88. package/js/vm/headless-vm.test.ts +0 -131
  89. package/js/vm/headless-vm.ts +0 -342
  90. package/js/vm/index.test.ts +0 -28
  91. package/js/vm/index.ts +0 -5
  92. package/js/vm/internal-types.ts +0 -32
  93. package/js/vm/json.test.ts +0 -40
  94. package/js/vm/json.ts +0 -273
  95. package/js/vm/normalize.test.ts +0 -48
  96. package/js/vm/normalize.ts +0 -65
  97. package/js/vm/options.test.ts +0 -30
  98. package/js/vm/options.ts +0 -55
  99. package/js/vm/pen-transparency.test.ts +0 -115
  100. package/js/vm/program-wasm.ts +0 -322
  101. package/js/vm/scheduler-render.test.ts +0 -401
  102. package/js/vm/scratch-assets.test.ts +0 -136
  103. package/js/vm/scratch-assets.ts +0 -202
  104. package/js/vm/types.ts +0 -358
  105. package/js/vm/value-guards.test.ts +0 -25
  106. package/js/vm/value-guards.ts +0 -18
  107. package/moon.mod.json +0 -10
  108. package/scripts/preinstall.ts +0 -4
  109. package/src/AGENTS.md +0 -6
  110. package/src/api.mbt +0 -161
  111. package/src/api_aot_commands.mbt +0 -184
  112. package/src/api_effects_json.mbt +0 -72
  113. package/src/api_options.mbt +0 -60
  114. package/src/api_program_wasm.mbt +0 -1647
  115. package/src/api_program_wat.mbt +0 -2206
  116. package/src/api_snapshot_json.mbt +0 -44
  117. package/src/cmd/AGENTS.md +0 -5
  118. package/src/cmd/main/AGENTS.md +0 -5
  119. package/src/cmd/main/main.mbt +0 -29
  120. package/src/cmd/main/moon.pkg +0 -7
  121. package/src/cmd/main/pkg.generated.mbti +0 -13
  122. package/src/json_helpers.mbt +0 -176
  123. package/src/moon.pkg +0 -65
  124. package/src/moonscratch.mbt +0 -3
  125. package/src/moonscratch_wbtest.mbt +0 -40
  126. package/src/parser_sb3.mbt +0 -890
  127. package/src/pkg.generated.mbti +0 -479
  128. package/src/runtime_eval.mbt +0 -2844
  129. package/src/runtime_exec.mbt +0 -3850
  130. package/src/runtime_render.mbt +0 -2550
  131. package/src/runtime_state.mbt +0 -870
  132. package/src/test/AGENTS.md +0 -3
  133. package/src/test/projects/AGENTS.md +0 -6
  134. package/src/test/projects/moon.pkg +0 -4
  135. package/src/test/projects/moonscratch_compat_test.mbt +0 -642
  136. package/src/test/projects/moonscratch_core_test.mbt +0 -1332
  137. package/src/test/projects/moonscratch_runtime_test.mbt +0 -1087
  138. package/src/test/projects/pkg.generated.mbti +0 -13
  139. package/src/test/projects/test_support.mbt +0 -35
  140. package/src/types_effects.mbt +0 -20
  141. package/src/types_error.mbt +0 -4
  142. package/src/types_options.mbt +0 -31
  143. package/src/types_runtime_structs.mbt +0 -254
  144. package/src/types_vm.mbt +0 -109
  145. package/tsconfig.json +0 -29
  146. package/viewer/index.ts +0 -399
  147. package/viewer/vite.d.ts +0 -1
  148. package/viewer/worker.ts +0 -161
  149. package/vite.config.ts +0 -61
@@ -1,228 +0,0 @@
1
- ---
2
- title: 'MoonBit Testing Reference'
3
- ---
4
-
5
- # MoonBit Testing Reference
6
-
7
- ## Doc Tests
8
-
9
- Doc tests can be written in `.mbt.md` files or inline docstrings.
10
-
11
- ### Code Block Types
12
-
13
- | Block | Behavior |
14
- | ---------------- | ------------------------------------ |
15
- | ` ```mbt check ` | Type-checked by LSP and `moon check` |
16
- | ` ```mbt test ` | Executed as `test {...}` block |
17
- | ` ```moonbit ` | Display only (not executed) |
18
-
19
- ### Inline Docstring Example
20
-
21
- ````moonbit
22
- ///|
23
- /// Get the largest element of a non-empty `Array`.
24
- ///
25
- /// # Example
26
- /// ```mbt test
27
- /// test {
28
- /// inspect(sum_array([1, 2, 3, 4, 5, 6]), content="21")
29
- /// }
30
- /// ```
31
- ///
32
- /// # Panics
33
- /// Panics if the `xs` is empty.
34
- pub fn sum_array(xs : Array[Int]) -> Int {
35
- xs.fold(init=0, fn(a, b) { a + b })
36
- }
37
- ````
38
-
39
- ### README.mbt.md
40
-
41
- Create `README.mbt.md` in your package directory with tested code examples:
42
-
43
- ````markdown
44
- # My Package
45
-
46
- ## Usage
47
-
48
- ```mbt test
49
- test {
50
- inspect(@mypackage.hello(), content="Hello, World!")
51
- }
52
- ```
53
- ````
54
-
55
- Symlink to `README.md` for GitHub compatibility:
56
-
57
- ```bash
58
- ln -s README.mbt.md README.md
59
- ```
60
-
61
- ## Snapshot Tests
62
-
63
- Use `inspect()` for snapshot testing. Run `moon test -u` to auto-update.
64
-
65
- ```moonbit
66
- test "snapshot" {
67
- inspect([1, 2, 3], content="") // Empty initially
68
- }
69
- ```
70
-
71
- After `moon test -u`:
72
-
73
- ```moonbit
74
- test "snapshot" {
75
- inspect([1, 2, 3], content="[1, 2, 3]")
76
- }
77
- ```
78
-
79
- ### inspect vs @json.inspect
80
-
81
- - `inspect()` - Uses `Show` trait, good for simple values
82
- - `@json.inspect()` - Uses `ToJson` trait, better for complex nested structures
83
-
84
- ```moonbit
85
- test "complex structure" {
86
- let data = { "name": "Alice", "scores": [90, 85, 92] }
87
- @json.inspect(data, content={"name":"Alice","scores":[90,85,92]})
88
- }
89
- ```
90
-
91
- ## Benchmarks with moon bench
92
-
93
- ### Basic Benchmark
94
-
95
- ```moonbit
96
- ///|
97
- bench "array_sum" {
98
- let arr = Array::make(1000, 1)
99
- arr.fold(init=0, fn(a, b) { a + b })
100
- }
101
-
102
- ///|
103
- bench "array_sum_iter" {
104
- let arr = Array::make(1000, 1)
105
- let mut sum = 0
106
- for v in arr {
107
- sum = sum + v
108
- }
109
- sum
110
- }
111
- ```
112
-
113
- ### Running Benchmarks
114
-
115
- ```bash
116
- moon bench # Run all benchmarks
117
- moon bench --target js # JS backend
118
- moon bench --target wasm-gc # Wasm backend
119
- ```
120
-
121
- ### Benchmark Best Practices
122
-
123
- 1. **Isolate the operation**: Only measure the code you want to benchmark
124
- 2. **Use realistic data sizes**: Small inputs may not reveal performance issues
125
- 3. **Compare alternatives**: Benchmark multiple approaches side by side
126
- 4. **Consider different backends**: Performance varies between JS, Wasm, and Native
127
-
128
- ## QuickCheck (Property-Based Testing)
129
-
130
- QuickCheck generates random test inputs automatically.
131
-
132
- ### Setup
133
-
134
- Add to `moon.pkg.json`:
135
-
136
- ```json
137
- {
138
- "test-import": ["moonbitlang/quickcheck"]
139
- }
140
- ```
141
-
142
- ### Basic Usage
143
-
144
- ```moonbit
145
- ///|
146
- test "reverse twice is identity" {
147
- @quickcheck.check(fn(arr : Array[Int]) {
148
- arr.rev().rev() == arr
149
- })
150
- }
151
-
152
- ///|
153
- test "sort is idempotent" {
154
- @quickcheck.check(fn(arr : Array[Int]) {
155
- let sorted = arr.copy()
156
- sorted.sort()
157
- let sorted_again = sorted.copy()
158
- sorted_again.sort()
159
- sorted == sorted_again
160
- })
161
- }
162
- ```
163
-
164
- ### Custom Generators
165
-
166
- ```moonbit
167
- ///|
168
- test "custom generator" {
169
- // Generate positive integers only
170
- @quickcheck.check(fn(n : Int) {
171
- let positive = n.abs() + 1
172
- positive > 0
173
- })
174
- }
175
- ```
176
-
177
- ### Shrinking
178
-
179
- QuickCheck automatically shrinks failing inputs to find minimal counterexamples:
180
-
181
- ```moonbit
182
- ///|
183
- test "finds minimal counterexample" {
184
- // If this fails, QuickCheck will find the smallest failing input
185
- @quickcheck.check(fn(arr : Array[Int]) {
186
- arr.length() < 100 // Will fail and shrink to length=100
187
- })
188
- }
189
- ```
190
-
191
- ## Test Organization
192
-
193
- ### File Naming
194
-
195
- - `*_test.mbt` - Black-box tests (only public API)
196
- - `*_wbtest.mbt` - White-box tests (can access private members)
197
- - `*.mbt.md` - Documentation with tested examples
198
-
199
- ### Test Filtering
200
-
201
- ```bash
202
- moon test --filter "Array::*" # Run tests matching pattern
203
- moon test src/parser_test.mbt # Run specific file
204
- moon test -v # Verbose output
205
- ```
206
-
207
- ### Panic Tests
208
-
209
- Name tests with `panic` prefix:
210
-
211
- ```moonbit
212
- ///|
213
- test "panic on empty array" {
214
- ignore(@mypackage.head([])) // Should panic
215
- }
216
- ```
217
-
218
- ### Error Tests
219
-
220
- Use `try?` to convert errors to `Result`:
221
-
222
- ```moonbit
223
- ///|
224
- test "parse error" {
225
- let result = try? parse("invalid")
226
- inspect(result, content="Err(ParseError::InvalidInput)")
227
- }
228
- ```
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 bobzhang
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,323 +0,0 @@
1
- ---
2
- name: moonbit-refactoring
3
- description: 'Refactor MoonBit code to be idiomatic: shrink public APIs, convert functions to methods, use pattern matching with views, add loop invariants, and ensure test coverage without regressions. Use when updating MoonBit packages or refactoring MoonBit APIs, modules, or tests.'
4
- ---
5
-
6
- # MoonBit Refactoring Skill
7
-
8
- ## Intent
9
-
10
- - Preserve behavior and public contracts unless explicitly changed.
11
- - Minimize the public API to what callers require.
12
- - Prefer declarative style and pattern matching over incidental mutation.
13
- - Use view types (ArrayView/StringView/BytesView) to avoid copies.
14
- - Add tests and docs alongside refactors.
15
-
16
- ## Workflow
17
-
18
- **Start broad, then refine locally:**
19
-
20
- 1. **Architecture first**: Review package structure, dependencies, and API boundaries.
21
- 2. **Inventory** public APIs and call sites (`moon doc`, `moon ide find-references`).
22
- 3. **Pick one refactor theme** (API minimization, package splits, pattern matching, loop style).
23
- 4. **Apply the smallest safe change**.
24
- 5. **Update docs/tests** in the same patch.
25
- 6. **Run `moon check`, then `moon test`**.
26
- 7. **Use coverage** to target missing branches.
27
-
28
- Avoid local cleanups (renaming, pattern matching) until the high-level structure is sound.
29
-
30
- ## Improve Package Architecture
31
-
32
- - Keep packages focused: aim for <10k lines per package.
33
- - Keep files manageable: aim for <2k lines per file.
34
- - Keep functions focused: aim for <200 lines per function.
35
-
36
- ### Splitting Files
37
-
38
- Treat files in MoonBit as organizational units; move code freely within a package as long as each file stays focused on one concept.
39
-
40
- ### Splitting Packages
41
-
42
- When spinning off package `A` into `A` and `B`:
43
-
44
- 1. Create the new package and re-export temporarily:
45
-
46
- ```mbt
47
- // In package B
48
- using @A { ... } // re-export A's APIs
49
- ```
50
-
51
- Ensure `moon check` passes before proceeding.
52
-
53
- 2. Find and update all call sites:
54
-
55
- ```bash
56
- moon ide find-references <symbol>
57
- ```
58
-
59
- Replace bare `f` with `@B.f`.
60
-
61
- 3. Remove the `use` statement once all call sites are updated.
62
-
63
- 4. Audit and remove newly-unused `pub` APIs from both packages.
64
-
65
- ### Guidelines
66
-
67
- - Prefer acyclic dependencies: lower-level packages should not import higher-level ones.
68
- - Only expose what downstream packages actually need.
69
- - Consider an `internal/` package for helpers that shouldn't leak.
70
-
71
- ## Minimize Public API and Modularize
72
-
73
- - Remove `pub` from helpers; keep only required exports.
74
- - Move helpers into `internal/` packages to block external imports.
75
- - Split large files by feature; files do not define modules in MoonBit.
76
-
77
- ## Local refactoring
78
-
79
- ### Convert Free Functions to Methods + Chaining
80
-
81
- - Move behavior onto the owning type for discoverability.
82
- - Use `..` for fluent, mutating chains when it reads clearly.
83
-
84
- Example:
85
-
86
- ```mbt nocheck
87
- // Before
88
- fn reader_next(r : Reader) -> Char? { ... }
89
- let ch = reader_next(r)
90
-
91
- // After
92
- #as_free_fn(reader_next, deprecated="Use Reader::next instead")
93
- fn Reader::next(self : Reader) -> Char? { ... }
94
- let ch = r.next()
95
- ```
96
-
97
- To make the transition smooth, place `#as_free_fn(old_name, ...)` on the method; it emits a deprecated free function
98
- `old_name` that forwards to the method.
99
- Then you can check call sites and update them gradually by looking at warnings.
100
- Example (chaining):
101
-
102
- ```mbt nocheck
103
- buf..write_string("#\\")..write_char(ch)
104
- ```
105
-
106
- ### Prefer Explicit Qualification
107
-
108
- - Use `@pkg.fn` instead of `using` when clarity matters.
109
- - Keep call sites explicit during wide refactors.
110
-
111
- Example:
112
-
113
- ```mbt nocheck
114
- let n = @parser.parse_number(token)
115
- ```
116
-
117
- ### Simplify Enum Constructors When Type Is Known
118
-
119
- When the expected type is known from context, you can omit the full package path for enum constructors:
120
-
121
- - **Pattern matching**: Annotate the matched value; constructors need no path.
122
- - **Nested constructors**: Only the outermost needs the full path.
123
- - **Return values**: The return type provides context for constructors in the body.
124
- - **Collections**: Type-annotate the collection; elements inherit the type.
125
-
126
- Examples:
127
-
128
- ```mbt
129
- // Pattern matching - annotate the value being matched
130
- let tree : @pkga.Tree = ...
131
- match tree {
132
- Leaf(x) => x
133
- Node(left~, x, right~) => left.sum() + x + right.sum()
134
- }
135
-
136
- // Nested constructors - only outer needs full path
137
- let x = @pkga.Tree::Node(left=Leaf(1), x=2, right=Leaf(3))
138
-
139
- // Return type provides context
140
- fn make_tree() -> @pkga.Tree {
141
- Node(left=Leaf(1), x=2, right=Leaf(3))
142
- }
143
-
144
- // Collections - type annotation on the array
145
- let trees : Array[@pkga.Tree] = [Leaf(1), Node(left=Leaf(2), x=3, right=Leaf(4))]
146
- ```
147
-
148
- ### Pattern Matching and Views
149
-
150
- - Pattern match arrays directly; the compiler inserts ArrayView implicitly.
151
- - Use `..` in the middle to match prefix and suffix at once.
152
- - Pattern match strings directly; avoid converting to `Array[Char]`.
153
- - `String`/`StringView` indexing yields `UInt16` code units. Use `for ch in s` for Unicode-aware iteration.
154
-
155
- #### we prefer pattern matching over small functions
156
-
157
- For example,
158
-
159
- ```mbt
160
- match gen_results.get(0) {
161
- Some(value) => Iter::singleton(value)
162
- None => Iter::empty()
163
- }
164
- ```
165
-
166
- We can pattern match directly, it is more efficient and as readable:
167
-
168
- ```mbt
169
- match gen_results {
170
- [value, ..] => Iter::singleton(value)
171
- [] => Iter::empty()
172
- }
173
- ```
174
-
175
- MoonBit pattern matching is pretty expressive, here are some more examples:
176
-
177
- ```mbt
178
- match items {
179
- [] => ()
180
- [head, ..tail] => handle(head, tail)
181
- [..prefix, mid, ..suffix] => handle_mid(prefix, mid, suffix)
182
- }
183
- ```
184
-
185
- ```mbt
186
- match s {
187
- "" => ()
188
- [.."let", ..rest] => handle_let(rest)
189
- _ => ()
190
- }
191
- ```
192
-
193
- #### Char literal matching
194
-
195
- Use char literal overloading for `Char`, `UInt16`, and `Int`; the examples below rely on it. This is handy when matching `String` indexing results (`UInt16`) against a char range.
196
-
197
- ```mbt
198
- test {
199
- let a_int : Int = 'b'
200
- if (a_int is 'a'..<'z') { () } else { () }
201
- let a_u16 : UInt16 = 'b'
202
- if (a_u16 is 'a'..<'z') { () } else { () }
203
- let a_char : Char = 'b'
204
- if (a_char is 'a'..<'z') { () } else { () }
205
- }
206
- ```
207
-
208
- #### Use Nested Patterns and `is`
209
-
210
- - Use `is` patterns inside `if`/`guard` to keep branches concise.
211
-
212
- Example:
213
-
214
- ```mbt
215
- match token {
216
- Some(Ident([.."@", ..rest])) if process(rest) is Some(x) => handle_at(rest)
217
- Some(Ident(name)) => handle_ident(name)
218
- None => ()
219
- }
220
- ```
221
-
222
- #### Prefer Range Loops for Simple Indexing
223
-
224
- - Use `for i in start..<end { ... }`, `for i in start..<=end { ... }`, `for i in large>..small`, or `for i in large>=..small` for simple index loops.
225
- - Keep functional-state `for` loops for algorithms that update state.
226
-
227
- Example:
228
-
229
- ```mbt
230
- // Before
231
- for i = 0; i < len; {
232
- items.push(fill)
233
- continue i + 1
234
- }
235
-
236
- // After
237
- for i in 0..<len {
238
- items.push(fill)
239
- }
240
- ```
241
-
242
- ## Loop Specs (Dafny-Style Comments)
243
-
244
- - Add specs for functional-state loops.
245
- - Skip invariants for simple `for x in xs` loops.
246
- - Add TODO when a decreases clause is unclear (possible bug).
247
-
248
- Example:
249
-
250
- ```mbt
251
- for i = 0, acc = 0; i < xs.length(); {
252
- acc = acc + xs[i]
253
- i = i + 1
254
- } else { acc }
255
- where {
256
- invariant: 0 <= i <= xs.length(),
257
- reasoning: (
258
- #| ... rigorous explanation ...
259
- #| ...
260
- )
261
- }
262
- ```
263
-
264
- ### Tests and Docs
265
-
266
- - Prefer black-box tests in `*_test.mbt` or `*.mbt.md`.
267
- - Add docstring tests with `mbt check` for public APIs.
268
-
269
- Example:
270
-
271
- ````mbt
272
- ///|
273
- /// Return the last element of a non-empty array.
274
- ///
275
- /// # Example
276
- /// ```mbt check
277
- /// test {
278
- /// inspect(last([1, 2, 3]), content="3")
279
- /// }
280
- /// ```
281
- pub fn last(xs : Array[Int]) -> Int { ... }
282
- ````
283
-
284
- ## Coverage-Driven Refactors
285
-
286
- - Use coverage to target missing branches through public APIs.
287
- - Prefer small, focused tests over white-box checks.
288
-
289
- Commands:
290
-
291
- ```bash
292
- moon coverage analyze -- -f summary
293
- moon coverage analyze -- -f caret -F path/to/file.mbt
294
- ```
295
-
296
- ## Moon IDE Commands
297
-
298
- ```bash
299
- moon doc "<query>"
300
- moon ide outline <dir|file>
301
- moon ide find-references <symbol>
302
- moon ide peek-def <symbol>
303
- moon ide rename <symbol> -new-name <new_name>
304
- moon check
305
- moon test
306
- moon info
307
- ```
308
-
309
- Use these commands for reliable refactoring.
310
-
311
- Example: spinning off `package_b` from `package_a`.
312
-
313
- Temporary import in `package_b`:
314
-
315
- ```mbt
316
- using @package_a { a, type B }
317
- ```
318
-
319
- Steps:
320
-
321
- 1. Use `moon ide find-references <symbol>` to find all call sites of `a` and `B`.
322
- 2. Replace them with `@package_a.a` and `@package_a.B`.
323
- 3. Remove the `using` statement and run `moon check`.
@@ -1,23 +0,0 @@
1
- # Git Hooks
2
-
3
- ## Pre-commit Hook
4
-
5
- This pre-commit hook performs automatic checks before finalizing your commit.
6
-
7
- ### Usage Instructions
8
-
9
- To use this pre-commit hook:
10
-
11
- 1. Make the hook executable if it isn't already:
12
-
13
- ```bash
14
- chmod +x .githooks/pre-commit
15
- ```
16
-
17
- 2. Configure Git to use the hooks in the .githooks directory:
18
-
19
- ```bash
20
- git config core.hooksPath .githooks
21
- ```
22
-
23
- 3. The hook will automatically run when you execute `git commit`
@@ -1,3 +0,0 @@
1
- #!/bin/sh
2
-
3
- moon check
@@ -1,40 +0,0 @@
1
- # Reference: https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/customize-the-agent-environment
2
- name: 'Copilot Setup Steps'
3
-
4
- # Automatically run the setup steps when they are changed to allow for easy validation, and
5
- # allow manual testing through the repository's "Actions" tab
6
- on:
7
- workflow_dispatch:
8
- push:
9
- paths:
10
- - .github/workflows/copilot-setup-steps.yml
11
- pull_request:
12
- paths:
13
- - .github/workflows/copilot-setup-steps.yml
14
-
15
- jobs:
16
- # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
17
- copilot-setup-steps:
18
- runs-on: ubuntu-latest
19
-
20
- # Set the permissions to the lowest permissions possible needed for your steps.
21
- # Copilot will be given its own token for its operations.
22
- permissions:
23
- # If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete.
24
- contents: read
25
-
26
- # You can define any steps you want, and they will run before the agent starts.
27
- # If you do not check out your code, Copilot will do this for you.
28
- steps:
29
- - name: Checkout code
30
- uses: actions/checkout@v5
31
-
32
- - name: Set up MoonBit
33
- run: |
34
- curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash
35
- echo "$HOME/.moon/bin" >> $GITHUB_PATH
36
-
37
- - name: Update MoonBit dependencies
38
- run: |
39
- moon version --all
40
- moon update