@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.
- package/.yarn/install-state.gz +0 -0
- package/README.md +44 -40
- package/{rfc → RFCs}/03-05-function-schema-dual-track-rfc.md +11 -12
- package/RFCs/05-31-generic-where-bounds-mfs.md +124 -0
- package/{rfc → RFCs}/README.md +1 -0
- package/build.rs +74 -1
- package/editing-history/2026-0526-0957-match-docs-check-md.md +24 -0
- package/editing-history/2026-0601-0003-update-callback-field-specialization.md +19 -0
- package/editing-history/2026-0601-0005-release-0.12.36.md +16 -0
- package/editing-history/202605210055-tree-show-cr-config-and-edit-cleanup.md +81 -0
- package/editing-history/202605312052-macro-schema-roundtrip-and-weak-types.md +6 -0
- package/editing-history/202605312059-ci-docs-test-and-fn-helper-tightening.md +3 -0
- package/editing-history/202605312105-map-generic-weak-types-followup.md +5 -0
- package/lib/package.json +1 -1
- package/package.json +1 -1
- /package/{rfc → RFCs}/02-04-runtime-traits-plan.md +0 -0
- /package/{rfc → RFCs}/02-14-project-modernization-roadmap.md +0 -0
- /package/{rfc → RFCs}/02-17-register-platform-api-rfc.md +0 -0
- /package/{rfc → RFCs}/02-18-language-theory-evolution-plan.md +0 -0
- /package/{rfc → RFCs}/02-23-optional-record-macro-plan.md +0 -0
- /package/{rfc → RFCs}/03-16-runtime-boundary-refactor-plan.md +0 -0
- /package/{rfc → RFCs}/03-18-query-def-tree-show-chunked-display-plan.md +0 -0
- /package/{rfc → RFCs}/04-13-call-arg-literal-rewrite-rfc.md +0 -0
- /package/{rfc → RFCs}/04-13-type-slot-mechanism-rfc.md +0 -0
- /package/{rfc → RFCs}/04-15-match-syntax-rfc.md +0 -0
- /package/{rfc → RFCs}/04-15-type-directed-optimization-catalog.md +0 -0
- /package/{rfc → RFCs}/04-15-wasm-compilation-feasibility.md +0 -0
- /package/{rfc → RFCs}/04-16-wasm-data-structures.md +0 -0
- /package/{rfcs → RFCs}/05-12-program-diff-rfc.md +0 -0
package/.yarn/install-state.gz
CHANGED
|
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
|
-
-
|
|
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 
|
|
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
|
-
|
|
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
|
|
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
|
-
###
|
|
53
|
+
### Quick Start
|
|
48
54
|
|
|
49
|
-
|
|
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
|
|
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`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
106
|
+
Common commands:
|
|
115
107
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
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
|
-
|
|
119
|
+
Related examples and workflows:
|
|
128
120
|
|
|
129
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
31
|
+
:where $ {}
|
|
32
|
+
'T Eq
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
说明:
|
|
@@ -83,20 +83,19 @@
|
|
|
83
83
|
|
|
84
84
|
## `:where` 约束
|
|
85
85
|
|
|
86
|
-
约束统一放在 `:where
|
|
86
|
+
约束统一放在 `:where` map,key 是泛型变量,value 是单个 trait 或 trait 列表:
|
|
87
87
|
|
|
88
88
|
```cirru
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
:: 'Ord 'U
|
|
89
|
+
{}
|
|
90
|
+
'T $ [] Eq Show
|
|
91
|
+
'U Ord
|
|
93
92
|
```
|
|
94
93
|
|
|
95
94
|
约定:
|
|
96
95
|
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
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))
|
|
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))
|
|
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`。
|
package/{rfc → RFCs}/README.md
RENAMED
|
@@ -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
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|