@calcit/procs 0.12.34 → 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 (38) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/README.md +53 -48
  3. package/{rfc → RFCs}/03-05-function-schema-dual-track-rfc.md +11 -12
  4. package/RFCs/05-12-program-diff-rfc.md +204 -0
  5. package/RFCs/05-31-generic-where-bounds-mfs.md +124 -0
  6. package/{rfc → RFCs}/README.md +1 -0
  7. package/build.rs +74 -1
  8. package/editing-history/2026-0223-2321-ns-imports-code-fixes.md +1 -1
  9. package/editing-history/2026-0227-1958-tree-rewrite-command-and-reference-model.md +1 -1
  10. package/editing-history/2026-0304-1548-impl-new-dot-method-input-and-doc-hints.md +2 -2
  11. package/editing-history/2026-0306-1552-core-schema-and-hintfn-migration.md +1 -1
  12. package/editing-history/2026-0307-1302-calcit-agent-docs-update.md +1 -1
  13. package/editing-history/2026-0320-1229-query-window-3-with-parent-preview.md +7 -7
  14. package/editing-history/2026-0323-1137-command-echo-tool-output-cleanup.md +2 -2
  15. package/editing-history/2026-0410-0011-snapshot-empty-version-pipe-marker.md +1 -1
  16. package/editing-history/2026-0526-0957-match-docs-check-md.md +24 -0
  17. package/editing-history/2026-0601-0003-update-callback-field-specialization.md +19 -0
  18. package/editing-history/2026-0601-0005-release-0.12.36.md +16 -0
  19. package/editing-history/202604182041-cr-wasm-split-and-runtime-stability.md +1 -1
  20. package/editing-history/202605210055-tree-show-cr-config-and-edit-cleanup.md +81 -0
  21. package/editing-history/202605312052-macro-schema-roundtrip-and-weak-types.md +6 -0
  22. package/editing-history/202605312059-ci-docs-test-and-fn-helper-tightening.md +3 -0
  23. package/editing-history/202605312105-map-generic-weak-types-followup.md +5 -0
  24. package/lib/package.json +3 -3
  25. package/package.json +3 -3
  26. /package/{rfc → RFCs}/02-04-runtime-traits-plan.md +0 -0
  27. /package/{rfc → RFCs}/02-14-project-modernization-roadmap.md +0 -0
  28. /package/{rfc → RFCs}/02-17-register-platform-api-rfc.md +0 -0
  29. /package/{rfc → RFCs}/02-18-language-theory-evolution-plan.md +0 -0
  30. /package/{rfc → RFCs}/02-23-optional-record-macro-plan.md +0 -0
  31. /package/{rfc → RFCs}/03-16-runtime-boundary-refactor-plan.md +0 -0
  32. /package/{rfc → RFCs}/03-18-query-def-tree-show-chunked-display-plan.md +0 -0
  33. /package/{rfc → RFCs}/04-13-call-arg-literal-rewrite-rfc.md +0 -0
  34. /package/{rfc → RFCs}/04-13-type-slot-mechanism-rfc.md +0 -0
  35. /package/{rfc → RFCs}/04-15-match-syntax-rfc.md +0 -0
  36. /package/{rfc → RFCs}/04-15-type-directed-optimization-catalog.md +0 -0
  37. /package/{rfc → RFCs}/04-15-wasm-compilation-feasibility.md +0 -0
  38. /package/{rfc → RFCs}/04-16-wasm-data-structures.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,23 +60,24 @@ cr eval 'range 100'
54
60
  cr eval 'thread-first 100 range (map $ \ * % %)'
55
61
  ```
56
62
 
57
- Run with a [compact.cirru](https://github.com/calcit-lang/lilac/blob/main/compact.cirru):
63
+ Run with a runtime snapshot such as `calcit.cirru` (legacy filename: `compact.cirru`):
58
64
 
59
65
  ```bash
60
- cr compact.cirru # run once (default)
66
+ cr calcit.cirru # run once (default)
67
+ cr compact.cirru # legacy filename still works
61
68
 
62
- cr # by default, it picks `compact.cirru`
69
+ cr # by default, it picks `calcit.cirru`, then falls back to `compact.cirru`
63
70
 
64
71
  cr -w # watch mode (explicit flag required)
65
72
  ```
66
73
 
67
- By default Calcit reads `:init-fn` and `:reload-fn` inside `compact.cirru` configs. 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:
68
75
 
69
76
  ```bash
70
77
  cr --init-fn='app.main/main!' --reload-fn='app.main/reload!'
71
78
  ```
72
79
 
73
- and even configure `:entries` in `compact.cirru`:
80
+ You may also configure `:entries` in `calcit.cirru`:
74
81
 
75
82
  ```bash
76
83
  cr --entry server
@@ -78,10 +85,10 @@ cr --entry server
78
85
 
79
86
  ### JavaScript codegen
80
87
 
81
- 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.
82
89
 
83
90
  ```bash
84
- cr js # compile to js, also picks `compact.cirru` by default
91
+ cr js # compile to js, also picks `calcit.cirru` by default
85
92
  cr js --emit-path=out/ # compile to js and save in `out/`
86
93
  ```
87
94
 
@@ -92,40 +99,28 @@ import { main_$x_, reload_$x_ } from "./js-out/app.main.mjs";
92
99
  main_$x_(); // which corresponds to `main!` function in calcit
93
100
  ```
94
101
 
95
- ### Calcit Editor & Bundler
96
-
97
- Install [Calcit Editor](https://github.com/calcit-lang/editor) and run `ct` to launch editor server,
98
- which writes `compact.cirru` and `.compact-inc.cirru` on saving. Try launching example by cloning [Calcit Workflow](https://github.com/calcit-lang/calcit-workflow).
99
-
100
- 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.
101
-
102
- 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/).
103
-
104
- ### MCP (Model Context Protocol) Support
105
-
106
- Calcit provides MCP server functionality for integration with AI assistants and development tools. The MCP server offers tools for:
102
+ ### CLI and Agent Workflow
107
103
 
108
- - **Code Management**: Read, write, and modify Calcit namespaces and definitions
109
- - **Project Operations**: Manage modules, dependencies, and configurations
110
- - **Calcit Runner**: Start/stop background runner processes with incremental updates
111
- - **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.
112
105
 
113
- #### Incremental File Processing
106
+ Common commands:
114
107
 
115
- When using the Calcit Runner through MCP:
116
-
117
- 1. **Start Runner**: Use `start_calcit_runner` to launch the background process. This automatically:
118
- - Creates a `.calcit-tmp/` directory
119
- - Copies the current `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
+ ```
120
116
 
121
- 2. **Generate Incremental Updates**: After making changes to your code, use `generate_calcit_incremental` to:
122
- - Compare current `compact.cirru` with the temporary baseline
123
- - Generate a `.compact-inc.cirru` file with only the changes
124
- - 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).
125
118
 
126
- 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:
127
120
 
128
- 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
129
124
 
130
125
  ### Modules
131
126
 
@@ -141,23 +136,23 @@ This workflow enables efficient hot-reloading during development without restart
141
136
 
142
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.
143
138
 
144
- `: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).
145
140
 
146
- To load modules, use `:modules` configuration and `compact.cirru`(which normally generated from `calcit.cirru`):
141
+ To load modules, use `:modules` configuration and the runtime snapshot file `calcit.cirru` (legacy: `compact.cirru`):
147
142
 
148
143
  ```cirru
149
144
  :configs $ {}
150
- :modules $ [] |memof/compact.cirru |lilac/
145
+ :modules $ [] |memof/calcit.cirru |lilac/
151
146
  ```
152
147
 
153
148
  Paths defined in `:modules` field are just loaded as files from `~/.config/calcit/modules/`,
154
- i.e. `~/.config/calcit/modules/memof/compact.cirru`.
149
+ i.e. `~/.config/calcit/modules/memof/calcit.cirru`.
155
150
 
156
- Modules that ends with `/`s are automatically suffixed `compact.cirru` since it's the default entry.
151
+ Modules ending with `/` are automatically suffixed with `calcit.cirru`, and still fall back to `compact.cirru` for compatibility.
157
152
 
158
153
  ### Development
159
154
 
160
- I use these commands to run local examples:
155
+ Local validation commands:
161
156
 
162
157
  ```bash
163
158
  # run tests in Rust
@@ -169,13 +164,23 @@ cargo run --bin cr -- calcit/test.cirru js && yarn try-js
169
164
  # run snippet
170
165
  cargo run --bin cr -- eval 'range 100'
171
166
 
172
- cr compact.cirru ir # compiles intermediate representation into program-ir.cirru
167
+ cr calcit.cirru ir # compiles intermediate representation into program-ir.cirru
173
168
 
174
169
  cr-wasm calcit/test-wasm.cirru # compile standalone wasm target to js-out/program.wasm
175
170
  ```
176
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
+
177
182
  - [Cirru Parser](https://github.com/Cirru/parser.rs) for indentation-based syntax parsing.
178
- - [Cirru EDN](https://github.com/Cirru/cirru-edn.rs) for `compact.cirru` file parsing.
183
+ - [Cirru EDN](https://github.com/Cirru/cirru-edn.rs) for runtime snapshot file parsing (`calcit.cirru` / legacy `compact.cirru`).
179
184
  - [Ternary Tree](https://github.com/calcit-lang/ternary-tree.rs) for immutable list data structure.
180
185
 
181
186
  Other tools:
@@ -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/compact.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/compact.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,204 @@
1
+ # RFC: `cr analyze program-diff <GIT REF>`
2
+
3
+ 状态:Draft
4
+ 日期:2026-05-12
5
+
6
+ ---
7
+
8
+ ## 1. 概要
9
+
10
+ 新增命令:
11
+
12
+ - `cr analyze program-diff <GIT REF>`
13
+
14
+ 该命令从 Git 中读取指定版本的完整运行时快照文件(默认沿用当前 `cr` 的输入文件路径,优先 `calcit.cirru`,兼容旧文件名 `compact.cirru`),确保**历史版本**与**当前工作区版本**都能被正确解析为 Calcit snapshot,然后做**结构化 diff**。
15
+
16
+ 输出目标不是纯文本行 diff,而是面向程序结构的树形 diff:
17
+
18
+ - 顶层展示 `package/configs/entries/files` 等结构;
19
+ - 文件层展示 `ns/defs`;
20
+ - definition 层展示 `doc/schema/examples/code`;
21
+ - `code/examples/ns.code` 内部继续深入到 Cirru 表达式节点级别;
22
+ - 无变化分支允许灰色折叠;
23
+ - 变更分支默认展开;
24
+ - 增加、删除、修改分别用不同符号和颜色表示。
25
+
26
+ ## 2. 动机
27
+
28
+ 当前针对运行时快照文件的版本对比主要依赖 Git 行 diff,但它有几个明显问题:
29
+
30
+ 1. **对结构不友好**:`calcit.cirru`(兼容旧文件名 `compact.cirru`)是机器生成的 snapshot,行 diff 容易受格式、字段顺序和长表达式影响;
31
+ 2. **对表达式内部变化不友好**:definition 代码改动往往是局部子树变化,行 diff 很难快速看出 AST 层面的增删改;
32
+ 3. **对 LLM / CLI 阅读不友好**:调用 `git diff` 后很难一眼区分“只是某个 def 变了”还是“整个 namespace 被搬动了”;
33
+ 4. **缺少 parse guard**:历史版本文件如果本身损坏,应该先明确报解析失败,而不是直接进入错误 diff。
34
+
35
+ 因此需要一个基于 Calcit 自身 snapshot/Cirru 结构的 diff 命令。
36
+
37
+ ## 3. 命令定义
38
+
39
+ ```/dev/null/rfc.txt#L1-2
40
+ cr analyze program-diff <GIT REF>
41
+ ```
42
+
43
+ 语义:
44
+
45
+ - `<GIT REF>` 可以是 `HEAD~1`、tag、branch、commit SHA 等;
46
+ - 当前侧使用 `cr` 输入路径(默认优先 `calcit.cirru`,兼容旧文件名 `compact.cirru`);
47
+ - 历史侧使用 `git show <ref>:<repo-relative-input-path>` 读取文件内容;
48
+ - 两边都必须先经过:
49
+ 1. `cirru_edn::parse`
50
+ 2. `snapshot::load_snapshot_data`
51
+ - 任一侧失败都直接返回错误并停止 diff。
52
+
53
+ ## 4. 输出设计
54
+
55
+ ### 4.1 总体结构
56
+
57
+ 输出分 2 段:
58
+
59
+ 1. Summary
60
+ 2. Tree Diff
61
+
62
+ Summary 示例:
63
+
64
+ ```/dev/null/rfc.txt#L1-6
65
+ # Program Diff
66
+ - ref: HEAD~1
67
+ - file: calcit.cirru
68
+ - parsed: ok / ok
69
+ - changes: ~12 +3 -1
70
+ ```
71
+
72
+ ### 4.2 树形 diff 约定
73
+
74
+ 参考 `cr analyze call-graph` 的树形展示风格,继续使用:
75
+
76
+ - `├──`
77
+ - `└──`
78
+ - `│`
79
+
80
+ 在此基础上增加状态符号:
81
+
82
+ - `=` unchanged(灰色)
83
+ - `~` modified(黄色)
84
+ - `+` added(绿色)
85
+ - `-` removed(红色)
86
+
87
+ ### 4.3 折叠策略
88
+
89
+ - `Unchanged` 子树默认只显示一行概要,并灰色折叠;
90
+ - `Modified` / `Added` / `Removed` 子树默认展开;
91
+ - root 总是展开;
92
+ - 叶子节点直接显示 old/new 摘要。
93
+
94
+ ### 4.4 表达式内部 diff
95
+
96
+ 对于 `code/examples/ns.code` 内部的 `Cirru`:
97
+
98
+ - 叶子变更显示 old/new;
99
+ - list 节点按子节点序列做结构化比对;
100
+ - 插入/删除节点要保留索引位置和节点摘要;
101
+ - 同位置替换优先显示为 `modified`,而不是简单拆成 delete+add;
102
+ - 整棵新增/删除表达式应继续展开其子结构。
103
+
104
+ ## 5. 范围
105
+
106
+ 本次只在 `calcit` 当前仓库内实现,不先抽到 `cirru_parser`:
107
+
108
+ - 先满足 CLI 工作流;
109
+ - diff 数据结构先放在当前项目中,便于快速迭代;
110
+ - 后续如果算法稳定,再考虑抽取成 Cirru parser / edn 侧通用模块。
111
+
112
+ ## 6. 实现方案
113
+
114
+ ### 6.1 新模块
115
+
116
+ 新增库模块:
117
+
118
+ - `src/program_diff.rs`
119
+
120
+ 职责:
121
+
122
+ 1. 读取当前 snapshot 文件;
123
+ 2. 从 git ref 读取历史 snapshot 文件;
124
+ 3. 校验两边都能 parse/load;
125
+ 4. 构建结构化 diff tree;
126
+ 5. 生成适合终端的彩色树形输出。
127
+
128
+ ### 6.2 CLI 接入
129
+
130
+ - `src/cli_args.rs`
131
+ - 为 `AnalyzeSubcommand` 增加 `ProgramDiff`;
132
+ - `src/bin/cr.rs`
133
+ - 将该命令作为 standalone analyze 命令优先处理;
134
+ - `src/bin/cli_handlers/command_echo.rs`
135
+ - 增加 command echo 渲染;
136
+ - `src/bin/cli_handlers/mod.rs`
137
+ - 导出 handler。
138
+
139
+ ### 6.3 Git 文件读取
140
+
141
+ 流程:
142
+
143
+ 1. 用 `git rev-parse --show-toplevel` 找 repo root;
144
+ 2. 将当前 `input` 解析成 repo-relative path;
145
+ 3. 用 `git show <ref>:<relative-path>` 读取历史内容;
146
+ 4. 若文件不存在、ref 不存在、或命令失败,则直接返回错误。
147
+
148
+ ### 6.4 Diff 层级
149
+
150
+ 优先按 snapshot 语义层比较:
151
+
152
+ 1. `package`
153
+ 2. `about`
154
+ 3. `configs`
155
+ 4. `entries`
156
+ 5. `files`
157
+ 6. `file.ns`
158
+ 7. `file.defs`
159
+ 8. `def.doc`
160
+ 9. `def.schema`
161
+ 10. `def.examples`
162
+ 11. `def.code`
163
+ 12. `Cirru` 子树
164
+
165
+ 这样可以避免直接把整个运行时快照文件当作匿名 EDN 树来比,输出会更稳定、更可读。
166
+
167
+ ### 6.5 Cirru 序列 diff
168
+
169
+ list 内部子节点对比采用“带替换代价的序列对齐”策略:
170
+
171
+ - 完全相等 => `match`
172
+ - 不相等但对位更合理 => `replace`
173
+ - 仅旧侧存在 => `remove`
174
+ - 仅新侧存在 => `insert`
175
+
176
+ 这比单纯按索引逐位比较更适合表达式中间插入/删除节点的场景。
177
+
178
+ ## 7. 预期收益
179
+
180
+ - 更适合 review `calcit.cirru`(兼容旧文件名 `compact.cirru`)的语义变化;
181
+ - 更容易理解大型 definition 的局部 AST 改动;
182
+ - 对 agent/LLM 更友好,能直接拿到层级化变化;
183
+ - 为后续抽象成 Cirru diff 模块提供实现样本。
184
+
185
+ ## 8. 暂不处理
186
+
187
+ 本 RFC 本轮不覆盖:
188
+
189
+ - 三方 merge;
190
+ - patch 应用;
191
+ - HTML/TUI 交互界面;
192
+ - 抽取到 `cirru_parser` crate;
193
+ - 和 `cr tree show` / `cr query def` 的统一 chunk/diff UI。
194
+
195
+ ## 9. 后续可能扩展
196
+
197
+ 后续可考虑继续增加:
198
+
199
+ - `--format json`
200
+ - `--no-color`
201
+ - `--expand-all`
202
+ - `--only <path-prefix>`
203
+ - `--git-path <path>`(脱离当前 input)
204
+ - 将 Cirru diff 算法下沉到 parser 层
@@ -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
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## 背景
4
4
 
5
- 通过在 `demos/compact.cirru` 上逐一测试 `cr edit` 的 namespace 相关子命令,发现三处导致 Agent 频繁用错的根本原因。
5
+ 通过在 `demos/calcit.cirru` 上逐一测试 `cr edit` 的 namespace 相关子命令,发现三处导致 Agent 频繁用错的根本原因。
6
6
 
7
7
  ## 发现的 Bug
8
8
 
@@ -12,7 +12,7 @@
12
12
  - `tree` handler:将 `handle_structural` 更名为 `handle_rewrite`,并更新输出提示与错误信息。
13
13
  - 结构引用处理:在 `tree` 中统一使用 `parse_with_references` + `process_node_with_references`。
14
14
  - 文档更新:`docs/CalcitAgent.md` 与 `Agents.md` 全部改用 `tree rewrite` 与 `--with` 示例。
15
- - 真实命令验证(基于 `demos/compact.cirru`):
15
+ - 真实命令验证(基于 `demos/calcit.cirru`):
16
16
  - `tree replace` 可执行普通替换;
17
17
  - `tree rewrite` 无 `--with` 会按预期报错;
18
18
  - `tree rewrite` 携带 `--with` 可按预期执行。
@@ -27,7 +27,7 @@
27
27
  - `yarn compile`
28
28
  - `cargo test`
29
29
  - `yarn check-all`
30
- - `cargo run --bin cr -- demos/compact.cirru query examples 'calcit.core/&impl::new'`
31
- - `cargo run --bin cr -- demos/compact.cirru query examples 'calcit.core/&impl:get'`
30
+ - `cargo run --bin cr -- demos/calcit.cirru query examples 'calcit.core/&impl::new'`
31
+ - `cargo run --bin cr -- demos/calcit.cirru query examples 'calcit.core/&impl:get'`
32
32
 
33
33
  以上在本次改动后均通过。
@@ -36,7 +36,7 @@
36
36
 
37
37
  每批次均执行:
38
38
 
39
- - `cargo run --bin cr -- demos/compact.cirru edit format`
39
+ - `cargo run --bin cr -- demos/calcit.cirru edit format`
40
40
  - `yarn check-all`
41
41
 
42
42
  结果均通过(尾部稳定为 `... and 24 files not changed.`)。
@@ -8,7 +8,7 @@
8
8
 
9
9
  ```
10
10
  - `cr --no-tips <subcommand> ...` - 隐藏所有编辑/查询命令输出的 "Tips:" 提示行(适合脚本/Agent 使用)
11
- - 示例:`cr --no-tips demos/compact.cirru query def calcit.core/foldl`
11
+ - 示例:`cr --no-tips demos/calcit.cirru query def calcit.core/foldl`
12
12
  ```
13
13
 
14
14
  **背景**:`aa21b3a` 提交新增了 `--no-tips` 全局开关(`TIPS_SUPPRESSED: AtomicBool`,通过 `suppress_tips()` 设置),文档中缺少记录。
@@ -56,17 +56,17 @@
56
56
  ## 验证
57
57
 
58
58
  - `cargo check --bin cr` 通过。
59
- - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/compact.cirru query find --help`
59
+ - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/calcit.cirru query find --help`
60
60
  - 可见 `--detail-offset` 参数。
61
- - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/compact.cirru query search --help`
61
+ - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/calcit.cirru query search --help`
62
62
  - `--start-path` 示例为点号格式。
63
- - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/compact.cirru query search state -f respo.app.comp.todolist/comp-todolist --detail-offset 5`
63
+ - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/calcit.cirru query search state -f respo.app.comp.todolist/comp-todolist --detail-offset 5`
64
64
  - 输出降噪,路径为点号,窗口外压缩。
65
- - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/compact.cirru query search state -f respo.app.comp.todolist/comp-todolist --detail-offset 0`
65
+ - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/calcit.cirru query search state -f respo.app.comp.todolist/comp-todolist --detail-offset 0`
66
66
  - 详情窗口为 `[0, 3)`,每条命中仅展示一行(优先父节点预览)。
67
- - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/compact.cirru query search state -f respo.app.comp.todolist/comp-todolist --detail-offset 0 --exact`
67
+ - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/calcit.cirru query search state -f respo.app.comp.todolist/comp-todolist --detail-offset 0 --exact`
68
68
  - 精确命中不再把 `states` 视觉误判为 `state`;且不显示“add --exact”提示。
69
- - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/compact.cirru query search-expr state -f respo.app.comp.todolist/comp-todolist --detail-offset 0`
69
+ - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/calcit.cirru query search-expr state -f respo.app.comp.todolist/comp-todolist --detail-offset 0`
70
70
  - 输出样式一致(单行预览)。
71
- - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/compact.cirru query search-expr state -f respo.app.comp.todolist/comp-todolist --detail-offset 0 --exact`
71
+ - `cargo run --bin cr -- /Users/jon.chen/repo/respo/respo/calcit.cirru query search-expr state -f respo.app.comp.todolist/comp-todolist --detail-offset 0 --exact`
72
72
  - 结果为 `No matches found`,符合结构精确匹配预期。
@@ -62,8 +62,8 @@
62
62
  - `cargo run --bin cr -- calcit/test.cirru query find render`
63
63
  - `cargo run --bin cr -- calcit/test.cirru tree show app.main/test-json -p ''`
64
64
  - `cargo run --bin cr -- calcit/test.cirru docs search chunk -f agent-advanced.md`
65
- - `cargo run --bin cr -- demos/compact.cirru docs check-md docs/CalcitAgent.md`
66
- - `cargo run --bin cr -- /tmp/calcit-cli-demo/compact.cirru tree replace ...` 多次人工检查 replace 输出形态
65
+ - `cargo run --bin cr -- demos/calcit.cirru docs check-md docs/CalcitAgent.md`
66
+ - `cargo run --bin cr -- /tmp/calcit-cli-demo/calcit.cirru tree replace ...` 多次人工检查 replace 输出形态
67
67
 
68
68
  ## 经验
69
69
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## 背景
4
4
 
5
- PR `snapshot-format` 新增了空 `configs.version` 的回归测试,但 GitHub Actions 上加载 `compact.cirru` 时,`(:version ||)` 会解析成字符串 `"|"`,没有命中原先仅检查空白字符串的校验。
5
+ PR `snapshot-format` 新增了空 `configs.version` 的回归测试,但 GitHub Actions 上加载运行时快照文件(`calcit.cirru` / legacy `compact.cirru`)时,`(:version ||)` 会解析成字符串 `"|"`,没有命中原先仅检查空白字符串的校验。
6
6
 
7
7
  ## 知识点
8
8
 
@@ -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`
@@ -11,7 +11,7 @@
11
11
 
12
12
  ## 经验与注意事项
13
13
 
14
- - `compact.cirru` 的修改必须通过 `cr edit`/`cr tree` 完成,避免文本直接编辑破坏结构。
14
+ - 对运行时快照文件(`calcit.cirru` / legacy `compact.cirru`)的修改必须通过 `cr edit`/`cr tree` 完成,避免文本直接编辑破坏结构。
15
15
  - 在多项目联动(calcit + recollect)场景下,发布前验证至少应覆盖:
16
16
  - calcit: `yarn check-all`
17
17
  - recollect: `yarn test:cr`、`yarn test:js`、`yarn test:wasm`
@@ -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,10 +1,10 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.12.34",
3
+ "version": "0.12.36",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
- "@types/node": "^25.0.9",
7
- "typescript": "^6.0.2"
6
+ "@types/node": "^25.7.0",
7
+ "typescript": "^6.0.3"
8
8
  },
9
9
  "scripts": {
10
10
  "compile": "rm -rf lib && tsc",
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.12.34",
3
+ "version": "0.12.36",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
- "@types/node": "^25.0.9",
7
- "typescript": "^6.0.2"
6
+ "@types/node": "^25.7.0",
7
+ "typescript": "^6.0.3"
8
8
  },
9
9
  "scripts": {
10
10
  "compile": "rm -rf lib && tsc",
File without changes
File without changes
File without changes
File without changes