@calcit/procs 0.12.35 → 0.12.36

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 (29) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/README.md +44 -40
  3. package/{rfc → RFCs}/03-05-function-schema-dual-track-rfc.md +11 -12
  4. package/RFCs/05-31-generic-where-bounds-mfs.md +124 -0
  5. package/{rfc → RFCs}/README.md +1 -0
  6. package/build.rs +74 -1
  7. package/editing-history/2026-0526-0957-match-docs-check-md.md +24 -0
  8. package/editing-history/2026-0601-0003-update-callback-field-specialization.md +19 -0
  9. package/editing-history/2026-0601-0005-release-0.12.36.md +16 -0
  10. package/editing-history/202605210055-tree-show-cr-config-and-edit-cleanup.md +81 -0
  11. package/editing-history/202605312052-macro-schema-roundtrip-and-weak-types.md +6 -0
  12. package/editing-history/202605312059-ci-docs-test-and-fn-helper-tightening.md +3 -0
  13. package/editing-history/202605312105-map-generic-weak-types-followup.md +5 -0
  14. package/lib/package.json +1 -1
  15. package/package.json +1 -1
  16. /package/{rfc → RFCs}/02-04-runtime-traits-plan.md +0 -0
  17. /package/{rfc → RFCs}/02-14-project-modernization-roadmap.md +0 -0
  18. /package/{rfc → RFCs}/02-17-register-platform-api-rfc.md +0 -0
  19. /package/{rfc → RFCs}/02-18-language-theory-evolution-plan.md +0 -0
  20. /package/{rfc → RFCs}/02-23-optional-record-macro-plan.md +0 -0
  21. /package/{rfc → RFCs}/03-16-runtime-boundary-refactor-plan.md +0 -0
  22. /package/{rfc → RFCs}/03-18-query-def-tree-show-chunked-display-plan.md +0 -0
  23. /package/{rfc → RFCs}/04-13-call-arg-literal-rewrite-rfc.md +0 -0
  24. /package/{rfc → RFCs}/04-13-type-slot-mechanism-rfc.md +0 -0
  25. /package/{rfc → RFCs}/04-15-match-syntax-rfc.md +0 -0
  26. /package/{rfc → RFCs}/04-15-type-directed-optimization-catalog.md +0 -0
  27. /package/{rfc → RFCs}/04-15-wasm-compilation-feasibility.md +0 -0
  28. /package/{rfc → RFCs}/04-16-wasm-data-structures.md +0 -0
  29. /package/{rfcs → RFCs}/05-12-program-diff-rfc.md +0 -0
Binary file
package/README.md CHANGED
@@ -12,11 +12,17 @@ Core design:
12
12
 
13
13
  - Interpreter runs on Rust, extensible with Rust FFI
14
14
  - Persistent Data Structure
15
- - Structural Editor(with indentation-based syntax as a fallback)
15
+ - Indentation-based Cirru syntax, friendly to plain text editing
16
16
  - Lisp macros, functional style
17
17
  - Compiles to JavaScript in ES Modules, JavaScript Interop
18
18
  - Hot code swapping friendly
19
19
 
20
+ Current direction:
21
+
22
+ - `calcit.cirru` is the primary source snapshot; legacy `compact.cirru` is still compatible
23
+ - CLI-first development with `cr` and `caps`, designed to work well with AI agents in terminal workflows
24
+ - Better CLI editing and validation for CI, docs lookup, module management, and incremental updates
25
+
20
26
  ### Install ![GitHub Release](https://img.shields.io/github/v/release/calcit-lang/calcit)
21
27
 
22
28
  Build and install with Rust:
@@ -29,12 +35,12 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
29
35
  cargo install calcit
30
36
  ```
31
37
 
32
- 4 binaries are installed:
38
+ Installed binaries:
33
39
 
34
40
  - `calcit`, the runtime and js compiler
35
41
  - `cr-wasm`, standalone WASM codegen tool
36
42
  - `caps`, for downloading dependencies declared in `deps.cirru`
37
- - `bundle_calcit`, bundle code if you don't want to use Calcit Editor
43
+ - `bundle_calcit`, bundle code for distribution
38
44
 
39
45
  When installing from source, explicitly include both runners:
40
46
 
@@ -44,9 +50,9 @@ cargo install --path . --bin cr --bin cr-wasm --bin caps --bin bundle_calcit
44
50
 
45
51
  To use Calcit in GitHub Actions, try [setup-cr](https://github.com/calcit-lang/setup-cr).
46
52
 
47
- ### Usage
53
+ ### Quick Start
48
54
 
49
- Snippets evaluating:
55
+ Evaluate snippets:
50
56
 
51
57
  ```bash
52
58
  cr eval 'range 100'
@@ -54,7 +60,7 @@ cr eval 'range 100'
54
60
  cr eval 'thread-first 100 range (map $ \ * % %)'
55
61
  ```
56
62
 
57
- Run with a runtime snapshot such as [calcit.cirru](https://github.com/calcit-lang/lilac/blob/main/compact.cirru) (legacy filename: `compact.cirru`):
63
+ Run with a runtime snapshot such as `calcit.cirru` (legacy filename: `compact.cirru`):
58
64
 
59
65
  ```bash
60
66
  cr calcit.cirru # run once (default)
@@ -65,13 +71,13 @@ cr # by default, it picks `calcit.cirru`, then falls back to `compact.cirru`
65
71
  cr -w # watch mode (explicit flag required)
66
72
  ```
67
73
 
68
- By default Calcit reads `:init-fn` and `:reload-fn` inside `calcit.cirru` configs (falling back to `compact.cirru`). You may also specify functions,
74
+ By default Calcit reads `:init-fn` and `:reload-fn` from `calcit.cirru` configs (falling back to `compact.cirru`). You may also specify functions:
69
75
 
70
76
  ```bash
71
77
  cr --init-fn='app.main/main!' --reload-fn='app.main/reload!'
72
78
  ```
73
79
 
74
- and even configure `:entries` in `calcit.cirru`:
80
+ You may also configure `:entries` in `calcit.cirru`:
75
81
 
76
82
  ```bash
77
83
  cr --entry server
@@ -79,7 +85,7 @@ cr --entry server
79
85
 
80
86
  ### JavaScript codegen
81
87
 
82
- It compiles to JavaScript and runs in consistet semantics. However it might require a lot of JavaScript interop.
88
+ Calcit compiles to JavaScript with consistent semantics. In browser or Node projects, JavaScript interop is still expected.
83
89
 
84
90
  ```bash
85
91
  cr js # compile to js, also picks `calcit.cirru` by default
@@ -93,40 +99,28 @@ import { main_$x_, reload_$x_ } from "./js-out/app.main.mjs";
93
99
  main_$x_(); // which corresponds to `main!` function in calcit
94
100
  ```
95
101
 
96
- ### Calcit Editor & Bundler
97
-
98
- Install [Calcit Editor](https://github.com/calcit-lang/editor) and run `ct` to launch editor server,
99
- which writes `calcit.cirru` and `.compact-inc.cirru` on saving. Legacy `compact.cirru` remains compatible. Try launching example by cloning [Calcit Workflow](https://github.com/calcit-lang/calcit-workflow).
100
-
101
- Read more in [Minimal Calcit](https://github.com/calcit-lang/minimal-calcit/blob/main/README.md) to learn how to code Calcit with a plain text editor.
102
-
103
- Read more in [Respo Calcit Workflow](https://github.com/calcit-lang/respo-calcit-workflow) to learn to create an MVC webpage with [Respo](http://respo-mvc.org/).
104
-
105
- ### MCP (Model Context Protocol) Support
106
-
107
- Calcit provides MCP server functionality for integration with AI assistants and development tools. The MCP server offers tools for:
102
+ ### CLI and Agent Workflow
108
103
 
109
- - **Code Management**: Read, write, and modify Calcit namespaces and definitions
110
- - **Project Operations**: Manage modules, dependencies, and configurations
111
- - **Calcit Runner**: Start/stop background runner processes with incremental updates
112
- - **Documentation**: Query API docs, reference materials, and dependency documentation
104
+ The recommended workflow is plain text editing plus CLI validation, often driven by an AI agent in terminal.
113
105
 
114
- #### Incremental File Processing
106
+ Common commands:
115
107
 
116
- When using the Calcit Runner through MCP:
117
-
118
- 1. **Start Runner**: Use `start_calcit_runner` to launch the background process. This automatically:
119
- - Creates a `.calcit-tmp/` directory
120
- - Copies the current runtime snapshot (`calcit.cirru`, or legacy `compact.cirru`) as a temporary baseline
108
+ ```bash
109
+ cr docs agents --full # read the current agent workflow guide
110
+ cr query search 'foo' # locate code by symbol or string
111
+ cr edit ... # structured edits for defs, imports, config, modules
112
+ cr js # compile once
113
+ cr js -w # watch mode
114
+ caps # install/update dependencies from deps.cirru
115
+ ```
121
116
 
122
- 2. **Generate Incremental Updates**: After making changes to your code, use `generate_calcit_incremental` to:
123
- - Compare current runtime snapshot with the temporary baseline
124
- - Generate a `.compact-inc.cirru` file with only the changes
125
- - Apply incremental updates to the running process
117
+ Calcit Editor is no longer the recommended path for everyday development. If you still need the older editor workflow, see [Calcit Editor](https://github.com/calcit-lang/editor).
126
118
 
127
- 3. **Check Results**: After generating the incremental file, always check the runner logs using `grab_calcit_runner_logs` to verify that updates were applied successfully.
119
+ Related examples and workflows:
128
120
 
129
- This workflow enables efficient hot-reloading during development without restarting the entire application.
121
+ - [Minimal Calcit](https://github.com/calcit-lang/minimal-calcit/blob/main/README.md)
122
+ - [Respo Calcit Workflow](https://github.com/calcit-lang/respo-calcit-workflow)
123
+ - [setup-cr](https://github.com/calcit-lang/setup-cr) for GitHub Actions
130
124
 
131
125
  ### Modules
132
126
 
@@ -142,7 +136,7 @@ This workflow enables efficient hot-reloading during development without restart
142
136
 
143
137
  Run `caps` to download. Sources are downloaded into `~/.config/calcit/modules/`. If a module contains `build.sh`, it will be executed mostly for compiling Rust dylibs.
144
138
 
145
- `:calcit-version` helps in check version, and provides hints in [CI](https://github.com/calcit-lang/setup-cr) environment.
139
+ `:calcit-version` helps with version checks and provides hints in [CI](https://github.com/calcit-lang/setup-cr).
146
140
 
147
141
  To load modules, use `:modules` configuration and the runtime snapshot file `calcit.cirru` (legacy: `compact.cirru`):
148
142
 
@@ -154,11 +148,11 @@ To load modules, use `:modules` configuration and the runtime snapshot file `cal
154
148
  Paths defined in `:modules` field are just loaded as files from `~/.config/calcit/modules/`,
155
149
  i.e. `~/.config/calcit/modules/memof/calcit.cirru`.
156
150
 
157
- Modules that ends with `/`s are automatically suffixed `calcit.cirru`, and still fall back to `compact.cirru` for compatibility.
151
+ Modules ending with `/` are automatically suffixed with `calcit.cirru`, and still fall back to `compact.cirru` for compatibility.
158
152
 
159
153
  ### Development
160
154
 
161
- I use these commands to run local examples:
155
+ Local validation commands:
162
156
 
163
157
  ```bash
164
158
  # run tests in Rust
@@ -175,6 +169,16 @@ cr calcit.cirru ir # compiles intermediate representation into program-ir.cirru
175
169
  cr-wasm calcit/test-wasm.cirru # compile standalone wasm target to js-out/program.wasm
176
170
  ```
177
171
 
172
+ For repository development, the usual validation flow is:
173
+
174
+ ```bash
175
+ cargo fmt
176
+ cargo clippy -- -D warnings
177
+ yarn compile
178
+ cargo test
179
+ yarn check-all
180
+ ```
181
+
178
182
  - [Cirru Parser](https://github.com/Cirru/parser.rs) for indentation-based syntax parsing.
179
183
  - [Cirru EDN](https://github.com/Cirru/cirru-edn.rs) for runtime snapshot file parsing (`calcit.cirru` / legacy `compact.cirru`).
180
184
  - [Ternary Tree](https://github.com/calcit-lang/ternary-tree.rs) for immutable list data structure.
@@ -28,8 +28,8 @@
28
28
  :args $ [] 'T :number
29
29
  :rest :number
30
30
  :return $ :: :tuple :ok 'U
31
- :where $ []
32
- :: 'Eq 'T
31
+ :where $ {}
32
+ 'T Eq
33
33
  ```
34
34
 
35
35
  说明:
@@ -83,20 +83,19 @@
83
83
 
84
84
  ## `:where` 约束
85
85
 
86
- 约束统一放在 `:where`,每条约束是一条 tuple:
86
+ 约束统一放在 `:where` map,key 是泛型变量,value 是单个 trait 或 trait 列表:
87
87
 
88
88
  ```cirru
89
- []
90
- :: 'Eq 'T
91
- :: 'Show 'T
92
- :: 'Ord 'U
89
+ {}
90
+ 'T $ [] Eq Show
91
+ 'U Ord
93
92
  ```
94
93
 
95
94
  约定:
96
95
 
97
- - 同一变量多条约束表示“且”;
98
- - 顺序不影响语义;
99
- - 若当前没有约束,直接写 `:where $ []`。
96
+ - 同一变量多个约束放在同一个 value 列表里,表示“且”;
97
+ - map 项顺序不影响语义;
98
+ - 若当前没有约束,直接省略 `:where`,或写空 map `:where $ {}`。
100
99
 
101
100
  ## parse 校验示例
102
101
 
@@ -105,13 +104,13 @@
105
104
  主示例:
106
105
 
107
106
  ```bash
108
- cr demos/calcit.cirru cirru parse-edn "(:: :fn ({} (:generics ([] 'T 'U)) (:args ([] 'T :number)) (:rest :number) (:return (:: :tuple :ok 'U)) (:where ([] (:: 'Eq 'T)))))"
107
+ cr demos/calcit.cirru cirru parse-edn "(:: :fn ({} (:generics ([] 'T 'U)) (:where ({} ('T Eq))) (:args ([] 'T :number)) (:rest :number) (:return (:: :tuple :ok 'U))))"
109
108
  ```
110
109
 
111
110
  运行时数据验证:
112
111
 
113
112
  ```bash
114
- cr demos/calcit.cirru eval "let ((schema (:: :fn ({} (:generics ([] 'T 'U)) (:args ([] 'T :number)) (:rest :number) (:return (:: :tuple :ok 'U)) (:where ([] (:: 'Eq 'T))))))) (println schema) (println (type-of schema)) , schema"
113
+ cr demos/calcit.cirru eval "let ((schema (:: :fn ({} (:generics ([] 'T 'U)) (:where ({} ('T Eq))) (:args ([] 'T :number)) (:rest :number) (:return (:: :tuple :ok 'U)))))) (println schema) (println (type-of schema)) , schema"
115
114
  ```
116
115
 
117
116
  ## 顶层定义与局部定义的分工
@@ -0,0 +1,124 @@
1
+ # 泛型 `:where` 约束 MFS
2
+
3
+ 日期:2026-05-31
4
+
5
+ 状态:Draft
6
+
7
+ ## 目标
8
+
9
+ 在现有函数 schema 泛型链路上,增加最小可用的 trait 约束能力:
10
+
11
+ - schema / `hint-fn` 可以声明 `:where`;
12
+ - 调用点在泛型变量完成绑定后,检查绑定结果是否满足 trait 约束;
13
+ - 先走主链路,不引入完整 trait solver,不处理复杂的 transitive requires 推导。
14
+
15
+ ## 当前实现边界
16
+
17
+ 本轮只覆盖:
18
+
19
+ - `CalcitFnTypeAnnotation` 的 `:where` 解析与序列化;
20
+ - 顶层 `:schema` 注入 `hint-fn` 后,用户函数调用的 `:where` 检查;
21
+ - 局部函数 / 期望函数类型场景的 `:where` 检查;
22
+ - trait 约束当前以 preprocess warning 形式暴露。
23
+
24
+ 本轮不覆盖:
25
+
26
+ - trait `requires` 的递归满足性;
27
+ - 约束失败直接升级为 hard error;
28
+ - 基于 `:where` 的代码生成优化;
29
+ - 复杂多态分派或 impl 搜索策略调整。
30
+
31
+ ## Canonical Cirru EDN 形态
32
+
33
+ ### 顶层 wrapped schema
34
+
35
+ `CodeEntry.:schema` 在 snapshot / Cirru EDN 里的推荐形态:
36
+
37
+ ```cirru
38
+ %{} :CodeEntry
39
+ :doc |demo
40
+ :code $ quote
41
+ defn show-it (x)
42
+ .show x
43
+ :examples $ []
44
+ :schema $ :: :fn
45
+ {}
46
+ :generics $ [] 'T
47
+ :where $ {}
48
+ 'T Show
49
+ :args $ [] 'T
50
+ :return :string
51
+ ```
52
+
53
+ ### 多 trait 约束
54
+
55
+ 单个类型变量绑定多个 trait 时,值是一个列表:
56
+
57
+ ```cirru
58
+ :: :fn $ {}
59
+ :generics $ [] 'T 'U
60
+ :where $ {}
61
+ 'T $ [] Show Eq
62
+ 'U Ord
63
+ :args $ [] 'T 'U
64
+ :return 'T
65
+ ```
66
+
67
+ ### 一行 Cirru EDN 示例
68
+
69
+ ```cirru
70
+ (:: :fn ({} (:generics ([] 'T 'U)) (:where ({} ('T ([] Show Eq)) ('U Ord))) (:args ([] 'T 'U)) (:return 'T)))
71
+ ```
72
+
73
+ ## 约束格式结论
74
+
75
+ `:`where` 当前使用 map,而不是 list-of-tuples。这一点刻意对齐 Rust `where` 的分离式设计:泛型名字继续放在 `:generics`,trait 约束单独放在 `:where`,避免把“变量声明”和“约束条件”混在同一个位置里。
76
+
77
+ - key: 泛型变量,例如 `'T`
78
+ - value: 单个 trait,或 `[]` 列表中的多个 trait
79
+
80
+ 也就是:
81
+
82
+ ```cirru
83
+ :where $ {}
84
+ 'T Show
85
+ 'U $ [] Eq Ord
86
+ ```
87
+
88
+ 不要写成旧草案里的 tuple 形式。`:: 'Show 'T` / `:: 'Eq 'U` 这类写法已经废弃,不应再出现在任何新文档、示例或测试输入里。
89
+
90
+ 后者不要再作为新文档示例。
91
+
92
+ 在概念上可以把它理解成 Rust 里的:
93
+
94
+ - `fn f<T, U>(...) where T: Show + Eq, U: Ord`
95
+ - 在 Calcit 中对应为 `:generics $ [] 'T 'U` 与 `:where $ {} 'T $ [] Show Eq 'U Ord`
96
+
97
+ ## 与 EDN / 内部表示的关系
98
+
99
+ - Cirru 文本里写 `'T`;
100
+ - 进入 EDN 后,它仍然是 symbol,只是内部不会把前导 `'` 作为名字的一部分存储;
101
+ - trait 名称在 schema 里直接写定义名,例如 `Show`、`Eq`,不加 `:` 前缀。
102
+
103
+ ## 主链路开发步骤
104
+
105
+ 1. 文档先固定 canonical `:where` 形态,避免继续沿用旧 tuple 草案。
106
+ 2. schema parse / serialize 支持 `:where`。
107
+ 3. 用户函数与局部函数调用,在泛型绑定后做 trait 约束检查。
108
+ 4. 增加 parse / roundtrip / warning 级别测试。
109
+ 5. 视结果决定是否把 warning 升级成 error,并是否纳入 trait `requires`。
110
+
111
+ ## 当前测试最小集
112
+
113
+ 至少保留以下方向:
114
+
115
+ - `hint-fn` 里的 `:where` 能被提取;
116
+ - 顶层 schema roundtrip 后 `:where` 不丢失;
117
+ - 满足 trait 约束时无 warning;
118
+ - 不满足 trait 约束时出现明确 warning。
119
+
120
+ ## 下一步
121
+
122
+ - 先把 `03-05-function-schema-dual-track-rfc.md` 中旧的 `:where` tuple 示例替换掉;
123
+ - 再补 schema roundtrip 测试,确保文档与实际输出一致;
124
+ - 之后再决定是否把约束失败升级为 `E_GENERIC_WHERE_BOUND_MISMATCH`。
@@ -26,6 +26,7 @@
26
26
  | `04-15-type-directed-optimization-catalog.md` | Active | 基于 `&record:nth` 经验,系统梳理 Record/Tuple/Scope 等类型导向优化机会。 |
27
27
  | `04-15-wasm-compilation-feasibility.md` | Active | WASM 编译三条路径(解释器→WASM / AOT 子集 / WASM GC)的可行性评估。 |
28
28
  | `04-16-wasm-data-structures.md` | Active | WASM codegen 中 Tag/Record/Tuple 等数据结构的内存布局与编译策略。 |
29
+ | `05-31-generic-where-bounds-mfs.md` | Active | 函数 schema 泛型 `:where` 约束的最小功能规格,先作为主链路开发基线。 |
29
30
 
30
31
  ## 已执行的清理
31
32
 
package/build.rs CHANGED
@@ -1,4 +1,4 @@
1
- use cirru_edn::{Edn, EdnRecordView, from_edn};
1
+ use cirru_edn::{Edn, EdnMapView, EdnRecordView, from_edn};
2
2
  use cirru_parser::Cirru;
3
3
  use serde::{Deserialize, Serialize};
4
4
  use std::collections::HashMap;
@@ -102,6 +102,56 @@ fn map_key_path_segment(key: &Edn) -> String {
102
102
  }
103
103
  }
104
104
 
105
+ fn canonical_schema_field_name(text: &str) -> Option<&'static str> {
106
+ match text.trim_start_matches(':') {
107
+ "kind" => Some("kind"),
108
+ "args" => Some("args"),
109
+ "return" => Some("return"),
110
+ "rest" => Some("rest"),
111
+ "generics" => Some("generics"),
112
+ "where" => Some("where"),
113
+ _ => None,
114
+ }
115
+ }
116
+
117
+ fn canonical_schema_kind_name(text: &str) -> Option<&'static str> {
118
+ match text.trim_start_matches(':') {
119
+ "fn" => Some("fn"),
120
+ "macro" => Some("macro"),
121
+ _ => None,
122
+ }
123
+ }
124
+
125
+ fn normalize_schema_map(map: &EdnMapView) -> Edn {
126
+ let mut normalized = EdnMapView::default();
127
+
128
+ for (key, value) in &map.0 {
129
+ let normalized_key = match key {
130
+ Edn::Tag(tag) => Edn::tag(tag.ref_str()),
131
+ Edn::Str(text) => canonical_schema_field_name(text.as_ref())
132
+ .map(Edn::tag)
133
+ .unwrap_or_else(|| key.clone()),
134
+ Edn::Symbol(text) => canonical_schema_field_name(text.as_ref())
135
+ .map(Edn::tag)
136
+ .unwrap_or_else(|| key.clone()),
137
+ _ => key.clone(),
138
+ };
139
+
140
+ let normalized_value = match (&normalized_key, value) {
141
+ (Edn::Tag(tag), Edn::Str(text)) | (Edn::Tag(tag), Edn::Symbol(text)) if tag.ref_str() == "kind" => {
142
+ canonical_schema_kind_name(text.as_ref())
143
+ .map(Edn::tag)
144
+ .unwrap_or_else(|| value.clone())
145
+ }
146
+ _ => value.clone(),
147
+ };
148
+
149
+ normalized.insert(normalized_key, normalized_value);
150
+ }
151
+
152
+ Edn::Map(normalized)
153
+ }
154
+
105
155
  /// Convert a schema Edn value (either old Quote-wrapped or new direct map) into Edn map form.
106
156
  fn parse_schema_from_edn(value: &Edn, owner: &str) -> Result<Edn, String> {
107
157
  // Simple scalar schemas (e.g. :dynamic, :nil) are valid as-is — skip Cirru path
@@ -110,6 +160,29 @@ fn parse_schema_from_edn(value: &Edn, owner: &str) -> Result<Edn, String> {
110
160
  validate_schema_edn_no_legacy_quotes(value, owner)?;
111
161
  return Ok(value.clone());
112
162
  }
163
+ Edn::Map(map) => {
164
+ let normalized = normalize_schema_map(map);
165
+ validate_schema_edn_no_legacy_quotes(&normalized, owner)?;
166
+ return Ok(normalized);
167
+ }
168
+ Edn::Tuple(view)
169
+ if matches!(view.tag.as_ref(), Edn::Tag(tag) if matches!(tag.ref_str(), "fn" | "macro"))
170
+ && matches!(view.extra.first(), Some(Edn::Map(_))) =>
171
+ {
172
+ let Some(Edn::Map(map)) = view.extra.first() else {
173
+ unreachable!();
174
+ };
175
+ let mut normalized = match normalize_schema_map(map) {
176
+ Edn::Map(map) => map,
177
+ _ => unreachable!(),
178
+ };
179
+ if normalized.tag_get("kind").is_none() && matches!(view.tag.as_ref(), Edn::Tag(tag) if tag.ref_str() == "macro") {
180
+ normalized.insert_key("kind", Edn::tag("macro"));
181
+ }
182
+ let normalized = Edn::Map(normalized);
183
+ validate_schema_edn_no_legacy_quotes(&normalized, owner)?;
184
+ return Ok(normalized);
185
+ }
113
186
  _ => {}
114
187
  }
115
188
  // Old format: Edn::Quote wrapping Cirru — convert to direct map Edn
@@ -0,0 +1,24 @@
1
+ # 2026-05-26 match 文档与 check-md 校验
2
+
3
+ ## 修改内容
4
+
5
+ - 将 `match` 的文档说明统一为同时适用于 enum tuple 和 plain tuple,不再把 `tag-match` 描述成 plain tuple 的唯一入口。
6
+ - 更新 `features/enums.md`、`features/tuples.md`、`features/common-patterns.md`、`features.md`、`quick-reference.md`、`run/agent-advanced.md` 中的推荐表述与示例。
7
+ - 为 `agent-advanced.md` 里无法独立运行的 DOM / 事件示意片段补上 `cirru.no-check`,使 `cr docs check-md` 只校验可执行代码块。
8
+
9
+ ## 验证
10
+
11
+ - `cargo run --bin cr -- eval $'match (:: :point 10 20)\n (:point x y) (+ x y)\n _ 0'`
12
+ - `cargo run --bin cr -- docs check-md docs/features.md`
13
+ - `cargo run --bin cr -- docs check-md docs/features/common-patterns.md`
14
+ - `cargo run --bin cr -- docs check-md docs/features/enums.md`
15
+ - `cargo run --bin cr -- docs check-md docs/features/error-handling.md`
16
+ - `cargo run --bin cr -- docs check-md docs/features/traits.md`
17
+ - `cargo run --bin cr -- docs check-md docs/features/tuples.md`
18
+ - `cargo run --bin cr -- docs check-md docs/quick-reference.md`
19
+ - `cargo run --bin cr -- docs check-md docs/run/agent-advanced.md`
20
+
21
+ ## 知识点
22
+
23
+ - 原生 `match` 可以直接匹配 plain tuple;它不只适用于带 `defenum` 类型信息的 tuple。
24
+ - 文档里的示意片段如果依赖 DOM helper、事件桥接函数或其他未加载上下文,应优先标记为 `cirru.no-check`,否则会被 `check-md` 的 `eval` 阻断。
@@ -0,0 +1,19 @@
1
+ # 2026-06-01 00:03 update callback field specialization
2
+
3
+ ## Summary
4
+
5
+ - specialized `calcit.core/update` call checking so the 3rd callback arg can inherit a known record/struct field type instead of always staying at generic `fn('T) -> 'T`
6
+ - fixed record field inference to resolve `TypeRef`-based struct annotations, not only direct `Record`/`Struct` annotations
7
+ - aligned native `not` proc signature with calcit-core semantics by accepting dynamic input and returning `:bool`
8
+
9
+ ## Why
10
+
11
+ - `respo` used precise type refs like `'respo.app.schema/Task`, but `infer_record_field_type` only looked through direct `Record`/`Struct` annotations, so `update task :done? not` could not see the field type
12
+ - even after specializing `update`, Rust-side proc metadata still described `not` as `fn(:bool?) -> :bool`, which was stricter and inconsistent with the core schema/docs path
13
+
14
+ ## Validation
15
+
16
+ - `cargo test specialize_update_uses_record_field_type_for_callback`
17
+ - `cargo run --manifest-path /Users/chenyong/repo/calcit-lang/calcit/Cargo.toml --bin cr -- js` from `respo`
18
+ - `yarn try-rs`
19
+ - `cargo test`
@@ -0,0 +1,16 @@
1
+ # 2026-06-01 00:05 release 0.12.36
2
+
3
+ ## Summary
4
+
5
+ - bumped crate and npm package version from `0.12.35` to `0.12.36`
6
+ - kept `ts-src/package.json` aligned with the root npm package metadata
7
+ - prepared the workspace for a release lockfile refresh and tag creation
8
+
9
+ ## Why
10
+
11
+ - this release publishes the `update` callback specialization and `not` proc typing fix after the PR checks passed
12
+ - keeping repeated package metadata in sync avoids mismatched npm publish/version outputs during future packaging steps
13
+
14
+ ## Validation
15
+
16
+ - `cargo update --workspace`
@@ -0,0 +1,81 @@
1
+ # 202605210055 — tree show 可选路径 + cr config 顶级命令 + cr edit 清理
2
+
3
+ ## 修改概要
4
+
5
+ ### 1. `cr tree show` — `-p` 参数改为可选,缺失时警告而非报错
6
+
7
+ **动机**: Agent 调用 `cr tree show ns/def` 时若忘记 `-p`,原来直接报错导致 token 浪费。
8
+
9
+ **变更文件**:
10
+
11
+ - `src/cli_args.rs`: `TreeShowCommand.path` 类型从 `String` → `Option<String>`,doc 注释更新
12
+ - `src/bin/cli_handlers/tree.rs`: `handle_show` 中对 `None` 输出黄色 `[Warn]`,默认使用空路径(root)
13
+ - `src/bin/cli_handlers/command_echo.rs`: `push_tree` Show 分支改用 `opt "path"` 宏处理 Option 类型
14
+
15
+ **效果**:
16
+
17
+ ```
18
+ $ cr calcit.cirru tree show "ns/def"
19
+ [Warn] No path (-p) specified; showing from root. Use -p '0' to start from a child node.
20
+ Type: list (4 items)
21
+ ...
22
+ ```
23
+
24
+ ---
25
+
26
+ ### 2. `cr config` — 顶级配置管理命令
27
+
28
+ **动机**: `cr query config`、`cr query modules`、`cr edit config`、`cr edit add-module`、`cr edit rm-module` 分散在不同子命令下,操作配置需要记忆多个入口。新增统一入口 `cr config`。
29
+
30
+ **新命令**:
31
+ | 命令 | 等价旧命令 |
32
+ |---|---|
33
+ | `cr config show` | `cr query config` |
34
+ | `cr config modules` | `cr query modules` |
35
+ | `cr config version [value]` | `cr edit config version ...` |
36
+ | `cr config set <key> <value>` | `cr edit config <key> <value>` |
37
+ | `cr config add-module <path>` | `cr edit add-module <path>` |
38
+ | `cr config rm-module <path>` | `cr edit rm-module <path>` |
39
+
40
+ `cr config version` 可独立使用(无参数显示当前版本,传 `patch/minor/major` 递增,传 semver 直接设置)。
41
+
42
+ **变更文件**:
43
+
44
+ - `src/cli_args.rs`: 添加 `CalcitCommand::Config`、`ConfigCommand`、`ConfigSubcommand`(含 `ConfigVersionCommand`)及各子命令 struct
45
+ - `src/bin/cli_handlers/config.rs`: 新建,实现 `handle_config_command` 及各子命令处理函数(含 `handle_version`)
46
+ - `src/bin/cli_handlers/edit.rs`: `parse_semver_value`、`bump_semver_value` 改为 `pub(crate)`
47
+ - `src/bin/cli_handlers/mod.rs`: 注册 `mod config` 并 re-export `handle_config_command`
48
+ - `src/bin/cli_handlers/command_echo.rs`: 添加 `config_name`、`push_config`,并在 `should_echo_command` / `render_command_echo` 中处理 `Config` 变体
49
+ - `src/bin/cr.rs`: 添加 `CalcitCommand::Config` 分支
50
+
51
+ ---
52
+
53
+ ### 3. `cr edit` 清理 — 移除已迁移至 `cr config` 的子命令
54
+
55
+ **动机**: `cr edit add-module`、`cr edit rm-module`、`cr edit config` 与新增的 `cr config` 重复,保持单一职责。
56
+
57
+ **删除内容**:
58
+
59
+ - `EditSubcommand::AddModule / RmModule / Config` 及对应 struct(`cli_args.rs`)
60
+ - `handle_add_module / handle_rm_module / handle_config` 函数体(`edit.rs`)
61
+ - `command_echo.rs` 中 `edit_name` 和 `push_edit` 两处 match 的三个变体
62
+
63
+ **保留**(被 `config.rs` 和单元测试引用):
64
+
65
+ - `pub(crate) fn parse_semver_value` — semver 字符串解析
66
+ - `pub(crate) fn bump_semver_value` — patch/minor/major 递增
67
+
68
+ **文档更新**:
69
+
70
+ - `docs/run/agent-advanced.md` "模块和配置" 章节、快速参考示例 → 全部改为 `cr config` 命令
71
+ - `docs/CalcitAgent.md` 第 9 节"cr 能力地图" → 新增"配置管理"条目
72
+
73
+ ---
74
+
75
+ ## 知识点
76
+
77
+ - `argh` 中将 `#[argh(option)]` 字段类型改为 `Option<T>` 可使该选项变为可选
78
+ - `pub(crate)` 可在同一 crate 内跨模块共享;被其他模块引用时,不能因删除调用方而一并删除
79
+ - 新增顶级命令时需同步更新 `command_echo.rs` 的三处:`should_echo_command`、`render_command_echo`(名称映射和 token push)
80
+ - 移除 enum 变体时,需同时检查 `command_echo.rs` 的两处 match(`edit_name` 和 `push_edit`)
81
+ - 单元测试也会引用函数,删除前要 grep `tests` 模块确认
@@ -0,0 +1,6 @@
1
+ - refined weak-types reporting in `cr analyze weak-types` to classify schema/code hits with detail paths
2
+ - tightened builtin proc signatures for list/map/set/buf-list helpers toward generic compound types
3
+ - kept `field-match` / `record-match` macro schema inputs precise in `calcit-core` while preserving round-trip behavior
4
+ - fixed macro schema serialization to keep non-dynamic returns like `:record` instead of dropping them during snapshot save/load
5
+ - aligned bare marker tag parsing for `:record` and related special tags with schema normalization behavior
6
+ - updated docs and parser tests to current wrapped schema / guidebook-loading behavior
@@ -0,0 +1,3 @@
1
+ - fixed docs query test to be stable both with and without ~/.config/calcit/docs configured, matching CI runner behavior
2
+ - tightened calcit.core fn helper schemas for &fn:apply / &fn:bind / &fn:map to reduce nested schema-dynamic usage
3
+ - validated with focused docs test, full cargo test, runtime cr calcit/test.cirru, weak-types analyze, and yarn check-all
@@ -0,0 +1,5 @@
1
+ - tightened multiple calcit.core snapshot schemas that safely remove weak composite internals without narrowing runtime behavior: typed path lists for `assoc-in`/`get-in`/`dissoc-in`/`update-in`/`contains-in?`, typed collection helpers like `apply`, `join-str`, `foldr-shortcut`, and explicit output map generics for `map-kv` and `pairs-map`
2
+ - corrected one weak-types false lead by changing `keys` from returning `:list` to `:set`, matching runtime/tests and moving that hit out of the list family
3
+ - extended `cr analyze weak-types` to classify nested schema-dynamic shapes/families, include per-definition summaries, split family/shape counts by `arg`/`return` position, and show per-definition `shape@position` contributors for the remaining hotspots
4
+ - confirmed the current lower-bound weak hits under the existing type system: `&record:to-map` for heterogeneous record values; `&tuple:params`, `&cirru-quote:to-list`, `parse-cirru-list`, `&format-ternary-tree`, `&list:flatten`, `format-cirru`, and `format-cirru-one-liner` for mixed list payloads that cannot be soundly collapsed to `list<'T>`
5
+ - verified the final baseline at schema-dynamic=290 with `cargo test --bin cr analyze_weak_types -- --nocapture`, repeated `cargo run --bin cr -- calcit/test.cirru analyze weak-types --ns calcit.core --only schema-dynamic`, and runtime suite checks via `cargo run --bin cr -- calcit/test.cirru`
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.12.35",
3
+ "version": "0.12.36",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.7.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.12.35",
3
+ "version": "0.12.36",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.7.0",
File without changes
File without changes
File without changes
File without changes
File without changes