@calcit/procs 0.11.8 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/.gitattributes +1 -1
  2. package/.yarn/install-state.gz +0 -0
  3. package/build.rs +229 -11
  4. package/editing-history/2026-0305-0042-type-inference-argtypes-and-core-hints.md +54 -0
  5. package/editing-history/2026-0305-0115-calcit-core-generic-refinements.md +57 -0
  6. package/editing-history/2026-0305-1930-schema-migration-cr-edit.md +30 -0
  7. package/editing-history/2026-0305-1939-query-schema-adaptation.md +42 -0
  8. package/editing-history/2026-0306-0120-schema-hint-migration-batch.md +38 -0
  9. package/editing-history/2026-0306-1416-core-macro-schema-migration.md +20 -0
  10. package/editing-history/2026-0306-1552-core-schema-and-hintfn-migration.md +63 -0
  11. package/editing-history/2026-0306-1936-schema-normalization-and-preprocess-preload.md +12 -0
  12. package/editing-history/2026-0307-0142-unit-type-and-builtin-schemas.md +82 -0
  13. package/editing-history/2026-0307-1302-calcit-agent-docs-update.md +32 -0
  14. package/editing-history/2026-0307-1652-decouple-snapshot-schema-to-calcit-type.md +112 -0
  15. package/editing-history/2026-0307-1821-snapshot-schema-validation.md +6 -0
  16. package/editing-history/2026-0307-1959-schema-def-kind-arity-validation.md +96 -0
  17. package/editing-history/2026-0307-migrate-hint-fn-to-schema.md +29 -0
  18. package/editing-history/2026-0307-remove-enum-prototype-field.md +43 -0
  19. package/editing-history/2026-0307-schema-args-type-enforcement.md +66 -0
  20. package/editing-history/2026-0308-0031-schema-generics-quote-normalization.md +35 -0
  21. package/editing-history/2026-0308-1905-schema-typeref-and-assert-migration.md +34 -0
  22. package/editing-history/2026-0308-2033-schema-wrapper-migration.md +45 -0
  23. package/editing-history/2026-0308-2315-late-schema-cleanup-and-warning-compat.md +27 -0
  24. package/lib/package.json +2 -2
  25. package/package.json +2 -2
package/.gitattributes CHANGED
@@ -3,4 +3,4 @@ calcit.cirru -diff linguist-generated
3
3
  yarn.lock -diff linguist-generated
4
4
  Cargo.lock -diff linguist-generated
5
5
  lib -diff linguist-generated
6
- editing-history -diff linguist-generated
6
+ editing-history/* -diff linguist-generated
Binary file
package/build.rs CHANGED
@@ -1,4 +1,4 @@
1
- use cirru_edn::{Edn, from_edn};
1
+ use cirru_edn::{Edn, EdnRecordView, from_edn};
2
2
  use cirru_parser::Cirru;
3
3
  use serde::{Deserialize, Serialize};
4
4
  use std::collections::HashMap;
@@ -24,6 +24,8 @@ pub struct CodeEntry {
24
24
  #[serde(default)]
25
25
  pub examples: Vec<Cirru>,
26
26
  pub code: Cirru,
27
+ #[serde(default)]
28
+ pub schema: Option<Edn>,
27
29
  }
28
30
 
29
31
  #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
@@ -41,34 +43,250 @@ pub struct Snapshot {
41
43
  pub files: HashMap<String, FileInSnapShot>,
42
44
  }
43
45
 
46
+ fn format_edn_preview(value: &Edn) -> String {
47
+ let raw = cirru_edn::format(value, true).unwrap_or_else(|_| format!("{value:?}"));
48
+ const LIMIT: usize = 220;
49
+ if raw.chars().count() > LIMIT {
50
+ let truncated = raw.chars().take(LIMIT).collect::<String>();
51
+ format!("{truncated}…")
52
+ } else {
53
+ raw
54
+ }
55
+ }
56
+
57
+ fn truncate_preview(raw: &str, limit: usize) -> String {
58
+ if raw.chars().count() > limit {
59
+ let truncated = raw.chars().take(limit).collect::<String>();
60
+ format!("{truncated}…")
61
+ } else {
62
+ raw.to_owned()
63
+ }
64
+ }
65
+
66
+ fn truncate_edn_error_nodes(message: &str) -> String {
67
+ const NODE_LIMIT: usize = 200;
68
+
69
+ message
70
+ .lines()
71
+ .map(|line| {
72
+ if let Some((prefix, preview)) = line.split_once("Node: ") {
73
+ format!("{prefix}Node: {}", truncate_preview(preview, NODE_LIMIT))
74
+ } else {
75
+ line.to_owned()
76
+ }
77
+ })
78
+ .collect::<Vec<_>>()
79
+ .join("\n")
80
+ }
81
+
82
+ fn format_edn_error<E: std::fmt::Display>(error: E) -> String {
83
+ truncate_edn_error_nodes(&error.to_string())
84
+ }
85
+
86
+ fn schema_path_label(path: &[String]) -> String {
87
+ if path.is_empty() { "<root>".to_owned() } else { path.join("") }
88
+ }
89
+
90
+ fn map_key_path_segment(key: &Edn) -> String {
91
+ match key {
92
+ Edn::Tag(tag) => format!(".{}", tag.ref_str()),
93
+ Edn::Str(text) => format!(".{text}"),
94
+ Edn::Symbol(text) => format!(".{text}"),
95
+ _ => ".<key>".to_owned(),
96
+ }
97
+ }
98
+
99
+ /// Convert a schema Edn value (either old Quote-wrapped or new direct map) into Edn map form.
100
+ fn parse_schema_from_edn(value: &Edn, owner: &str) -> Result<Edn, String> {
101
+ // Old format: Edn::Quote wrapping Cirru — convert to direct map Edn
102
+ if let Ok(cirru) = from_edn::<Cirru>(value.clone()) {
103
+ let text = cirru_parser::format(&[cirru], true.into())
104
+ .map_err(|e| format!("{owner}: failed to format quoted schema before validation: {}", format_edn_error(e)))?;
105
+ let parsed = cirru_edn::parse(&text).map_err(|e| {
106
+ format!(
107
+ "{owner}: failed to parse quoted schema after formatting: {}; schema={}",
108
+ format_edn_error(e),
109
+ truncate_preview(&text, 200)
110
+ )
111
+ })?;
112
+ validate_schema_edn_no_legacy_quotes(&parsed, owner)?;
113
+ return Ok(parsed);
114
+ }
115
+ // New format: already a direct Edn map
116
+ validate_schema_edn_no_legacy_quotes(value, owner)?;
117
+ Ok(value.clone())
118
+ }
119
+
120
+ fn validate_schema_edn_no_legacy_quotes(value: &Edn, owner: &str) -> Result<(), String> {
121
+ fn walk(value: &Edn, owner: &str, path: &mut Vec<String>) -> Result<(), String> {
122
+ match value {
123
+ Edn::Symbol(s) => {
124
+ if s.starts_with('\'') {
125
+ let inner = s.trim_start_matches('\'');
126
+ return Err(format!(
127
+ "{owner}: invalid schema generic symbol `{s}` at {}. Use source syntax like `'{inner}`, but store it as plain EDN symbol `{inner}`.",
128
+ schema_path_label(path)
129
+ ));
130
+ }
131
+ Ok(())
132
+ }
133
+ Edn::List(xs) => {
134
+ for (idx, item) in xs.0.iter().enumerate() {
135
+ path.push(format!("[{idx}]"));
136
+ walk(item, owner, path)?;
137
+ path.pop();
138
+ }
139
+ Ok(())
140
+ }
141
+ Edn::Map(map) => {
142
+ for (k, v) in &map.0 {
143
+ path.push(map_key_path_segment(k));
144
+ walk(v, owner, path)?;
145
+ path.pop();
146
+ }
147
+ Ok(())
148
+ }
149
+ Edn::Tuple(view) => {
150
+ path.push(".tag".to_owned());
151
+ walk(view.tag.as_ref(), owner, path)?;
152
+ path.pop();
153
+ for (idx, item) in view.extra.iter().enumerate() {
154
+ path.push(format!("[{idx}]"));
155
+ walk(item, owner, path)?;
156
+ path.pop();
157
+ }
158
+ Ok(())
159
+ }
160
+ Edn::Set(set) => {
161
+ for (idx, item) in set.0.iter().enumerate() {
162
+ path.push(format!("[#{idx}]"));
163
+ walk(item, owner, path)?;
164
+ path.pop();
165
+ }
166
+ Ok(())
167
+ }
168
+ Edn::Record(_) => Ok(()),
169
+ _ => Ok(()),
170
+ }
171
+ }
172
+
173
+ let mut path = vec![];
174
+ walk(value, owner, &mut path)
175
+ }
176
+
177
+ fn parse_code_entry(edn: Edn, owner: &str) -> Result<CodeEntry, String> {
178
+ let record: EdnRecordView = match edn {
179
+ Edn::Record(r) => r,
180
+ other => return Err(format!("{owner}: expected CodeEntry record, got {}", format_edn_preview(&other))),
181
+ };
182
+ let mut doc = String::new();
183
+ let mut examples: Vec<Cirru> = vec![];
184
+ let mut code: Option<Cirru> = None;
185
+ let mut schema: Option<Edn> = None;
186
+ for (key, value) in &record.pairs {
187
+ match key.arc_str().as_ref() {
188
+ "doc" => doc = from_edn(value.clone()).map_err(|e| format!("{owner}: invalid `:doc`: {e}"))?,
189
+ "examples" => examples = from_edn(value.clone()).map_err(|e| format!("{owner}: invalid `:examples`: {e}"))?,
190
+ "code" => code = Some(from_edn(value.clone()).map_err(|e| format!("{owner}: invalid `:code`: {e}"))?),
191
+ "schema" => {
192
+ if !matches!(value, Edn::Nil) {
193
+ schema = Some(parse_schema_from_edn(value, owner).map_err(|e| format!("{owner}: invalid `:schema`: {e}"))?);
194
+ }
195
+ }
196
+ _ => {}
197
+ }
198
+ }
199
+ Ok(CodeEntry {
200
+ doc,
201
+ examples,
202
+ code: code.ok_or_else(|| format!("{owner}: missing `:code` field in CodeEntry"))?,
203
+ schema,
204
+ })
205
+ }
206
+
207
+ fn parse_file_in_snapshot(edn: Edn, file_name: &str) -> Result<FileInSnapShot, String> {
208
+ let record: EdnRecordView = match edn {
209
+ Edn::Record(r) => r,
210
+ other => {
211
+ return Err(format!(
212
+ "{file_name}: expected FileEntry record, got {}",
213
+ format_edn_preview(&other)
214
+ ));
215
+ }
216
+ };
217
+ let mut ns: Option<CodeEntry> = None;
218
+ let mut defs: HashMap<String, CodeEntry> = HashMap::new();
219
+ for (key, value) in &record.pairs {
220
+ match key.arc_str().as_ref() {
221
+ "ns" => ns = Some(parse_code_entry(value.clone(), &format!("{file_name}/:ns"))?),
222
+ "defs" => {
223
+ let map = match value {
224
+ Edn::Map(m) => m,
225
+ other => return Err(format!("{file_name}: expected `:defs` map, got {}", format_edn_preview(other))),
226
+ };
227
+ for (def_key, def_value) in &map.0 {
228
+ let name: String = from_edn(def_key.clone()).map_err(|e| format!("{file_name}: invalid def key: {e}"))?;
229
+ let owner = format!("{file_name}/{name}");
230
+ defs.insert(name, parse_code_entry(def_value.clone(), &owner)?);
231
+ }
232
+ }
233
+ _ => {}
234
+ }
235
+ }
236
+ Ok(FileInSnapShot {
237
+ ns: ns.ok_or_else(|| format!("{file_name}: missing `:ns` field in FileEntry"))?,
238
+ defs,
239
+ })
240
+ }
241
+
242
+ fn parse_files(edn: Edn) -> Result<HashMap<String, FileInSnapShot>, String> {
243
+ match edn {
244
+ Edn::Map(map) => {
245
+ let mut result = HashMap::with_capacity(map.0.len());
246
+ for (key, value) in map.0 {
247
+ let name: String = from_edn(key).map_err(|e| format!("invalid file key: {e}"))?;
248
+ result.insert(name.clone(), parse_file_in_snapshot(value, &name)?);
249
+ }
250
+ Ok(result)
251
+ }
252
+ other => Err(format!("snapshot `:files` must be a map, got {}", format_edn_preview(&other))),
253
+ }
254
+ }
255
+
44
256
  fn main() {
45
257
  println!("cargo:rerun-if-changed=src/cirru/calcit-core.cirru");
46
258
 
47
259
  let out_dir = env::var_os("OUT_DIR").unwrap();
48
260
  let dest_path = Path::new(&out_dir).join("calcit-core.rmp");
49
261
 
50
- let core_content = fs::read_to_string("src/cirru/calcit-core.cirru").expect("read core");
51
- let core_data = cirru_edn::parse(&core_content).expect("parse core");
262
+ let core_content =
263
+ fs::read_to_string("src/cirru/calcit-core.cirru").unwrap_or_else(|e| panic!("failed to read src/cirru/calcit-core.cirru: {e}"));
264
+ let core_data = cirru_edn::parse(&core_content)
265
+ .unwrap_or_else(|e| panic!("failed to parse src/cirru/calcit-core.cirru as Cirru EDN: {}", format_edn_error(e)));
52
266
 
53
267
  // Minimal logic to convert Edn to Snapshot as in src/snapshot.rs
54
- let data = core_data.view_map().expect("map");
55
- let pkg: String = from_edn(data.get_or_nil("package")).expect("pkg");
268
+ let data = core_data
269
+ .view_map()
270
+ .unwrap_or_else(|e| panic!("calcit-core snapshot root must be a map: {e}"));
271
+ let pkg: String = from_edn(data.get_or_nil("package")).unwrap_or_else(|e| panic!("failed to parse calcit-core `:package`: {e}"));
56
272
  let about = match data.get_or_nil("about") {
57
273
  Edn::Nil => None,
58
- value => Some(from_edn::<String>(value).expect("about")),
274
+ value => Some(from_edn::<String>(value).unwrap_or_else(|e| panic!("failed to parse calcit-core `:about`: {e}"))),
59
275
  };
60
276
 
61
- let files: HashMap<String, FileInSnapShot> = from_edn(data.get_or_nil("files")).expect("files");
277
+ let files = parse_files(data.get_or_nil("files")).unwrap_or_else(|e| panic!("failed to parse calcit-core `:files`: {e}"));
62
278
 
63
279
  let snapshot = Snapshot {
64
280
  package: pkg,
65
281
  about,
66
- configs: from_edn(data.get_or_nil("configs")).expect("configs"),
67
- entries: from_edn(data.get_or_nil("entries")).expect("entries"),
282
+ configs: from_edn(data.get_or_nil("configs")).unwrap_or_else(|e| panic!("failed to parse calcit-core `:configs`: {e}")),
283
+ entries: from_edn(data.get_or_nil("entries")).unwrap_or_else(|e| panic!("failed to parse calcit-core `:entries`: {e}")),
68
284
  files,
69
285
  };
70
286
 
71
287
  let mut buf = Vec::new();
72
- snapshot.serialize(&mut rmp_serde::Serializer::new(&mut buf)).expect("serialize");
73
- fs::write(dest_path, buf).expect("write");
288
+ snapshot
289
+ .serialize(&mut rmp_serde::Serializer::new(&mut buf))
290
+ .unwrap_or_else(|e| panic!("failed to serialize embedded calcit-core snapshot: {e}"));
291
+ fs::write(dest_path, buf).unwrap_or_else(|e| panic!("failed to write embedded calcit-core snapshot: {e}"));
74
292
  }
@@ -0,0 +1,54 @@
1
+ # 2026-03-05 类型推断增强记录
2
+
3
+ ## 本次目标
4
+
5
+ - 在 upstream 重置后,重新加强类型推断能力,并保证 debug/release/全量检查都稳定通过。
6
+
7
+ ## 关键改动
8
+
9
+ ### 1) 预处理阶段 Proc 返回类型传播增强
10
+
11
+ 在 `src/runner/preprocess.rs` 的 `infer_type_from_expr` 中补齐多类内建过程返回类型推断:
12
+
13
+ - List 保型:`sort`、`&list:concat`、`&list:assoc`、`&list:assoc-before`、`&list:assoc-after`、`&list:dissoc`。
14
+ - 固定返回:`range -> list<number>`,`split/split-lines -> list<string>`,`&map:to-list -> list`。
15
+ - Map 保型:`&map:assoc`、`&map:dissoc`、`&merge`、`&merge-non-nil`、`&map:diff-new`。
16
+ - Set 保型:`&include`、`&exclude`、`&difference`、`&union`、`&set:intersection`。
17
+
18
+ ### 2) defn 参数类型提示传播修复(避免栈溢出)
19
+
20
+ 在 `src/builtins/syntax.rs` 中增强 `defn` 的 `arg_types` 回退策略:
21
+
22
+ - 第一层:沿用原逻辑,从 body 中 `assert-type` 模式提取。
23
+ - 第二层:当全是 Dynamic 时,从参数列表 Local 的 `type_info` 读取。
24
+ - 第三层:当仍全是 Dynamic 时,从**预处理后 body 顶层 Local**提取(`assert-type` 被预处理成 typed local 的场景)。
25
+ - 为避免核心加载路径栈压力,`calcit.core` 命名空间跳过该额外回退扫描。
26
+
27
+ ### 3) calcit-core 类型提示细化
28
+
29
+ 在 `src/cirru/calcit-core.cirru` 为以下列表保型函数补充泛型提示:
30
+
31
+ - `distinct`
32
+ - `drop`
33
+ - `repeat`
34
+ - `reverse`
35
+ - `take`
36
+ - `take-last`
37
+
38
+ 统一使用 `hint-fn (generics 'T) $ return-type (:: :list 'T)`,并将输入列表参数改为 `assert-type ... (:: :list 'T)`。
39
+
40
+ ### 4) 测试用例一致性调整
41
+
42
+ `calcit/test-types.cirru` 中 `test-arg-type-hints` 示例从故意错误参数改为合法参数,避免新检查路径把 warning 升级为阻断导致全量检查失败。
43
+
44
+ ## 过程中的关键排障结论
45
+
46
+ - 多次尝试在 `preprocess_defn` 内直接重建/替换参数 AST 或引入额外全局缓存时,容易触发主流程栈溢出。
47
+ - 最终采用“最小干预 + 避开 core 热路径回退扫描”的方式稳定通过。
48
+
49
+ ## 验证结果
50
+
51
+ - `cargo test` 通过。
52
+ - `yarn check-all` 通过(`EXIT:0`)。
53
+ - `cargo build --release` + `./target/release/cr calcit/test.cirru -1` 通过。
54
+ - `./target/debug/cr calcit/test.cirru -1` 通过。
@@ -0,0 +1,57 @@
1
+ # 2026-03-05 calict.core 泛型签名细化
2
+
3
+ ## 目标
4
+
5
+ 在不改变运行时语义的前提下,继续收紧 `calcit-core.cirru` 中 `defn` 的类型签名,让类型推断更稳定、错误提示更精确。
6
+
7
+ ## 主要改动
8
+
9
+ 本次聚焦于“保型列表函数”“可选返回值函数”“函数组合器”“map 回调函数形状”四类。
10
+
11
+ ### 一、列表保型与可选返回
12
+
13
+ - `distinct`, `drop`, `repeat`, `reverse`, `take`, `take-last`
14
+ - 统一到 `hint-fn (generics 'T) $ return-type (:: :list 'T)`。
15
+ - `&list:find-last`
16
+ - 改为 `(:: :optional 'T)`。
17
+ - `&list:find-last-index`, `&list:last-index-of`, `index-of`
18
+ - 改为 `(:: :optional :number)`。
19
+ - `&list:max`, `&list:min`
20
+ - 改为 `(:: :optional 'T)`。
21
+
22
+ ### 二、列表/映射映射函数泛型化
23
+
24
+ - `&list:map`
25
+ - 从宽泛 `:list/:fn` 收紧到 `('T -> 'U)`,返回 `(:: :list 'U)`。
26
+ - `map`
27
+ - 回调从 `('T -> 'T)` 扩展为 `('T -> 'U)`,与 map 语义一致。
28
+ - `map-indexed`
29
+ - 返回类型显式为 `(:: :list 'U)`,回调签名改为 `(:number 'T) -> 'U`。
30
+
31
+ ### 三、拼接与组合函数
32
+
33
+ - `concat`, `conj`, `interleave`, `join`
34
+ - 输入与输出统一到同一元素类型 `'T` 的列表。
35
+ - `&list:apply`
36
+ - 收紧为 `xs: list<T>, fs: list<(T -> U)>`,返回 `list<U>`。
37
+
38
+ ### 四、函数组合器与 map helper
39
+
40
+ - `&fn:apply`, `&fn:bind`, `&fn:map`
41
+ - 增加 `('A 'B 'C)` 级别泛型,表达组合器的真实输入输出关系。
42
+ - `&map:map-list`
43
+ - 返回改为 `(:: :list 'U)`,并补充 `f/acc/pair` 类型约束。
44
+ - `&list:map-pair`
45
+ - 返回改为 `(:: :list 'U)`,`f` 改为 `('K 'V) -> 'U`。
46
+ - `&map:filter`, `&map:filter-kv`, `&map:map`
47
+ - 回调签名改为带输入/输出形状的泛型函数类型,减少 `:fn` 过宽带来的误判。
48
+
49
+ ## 验证
50
+
51
+ 日志均写入仓库内 `js-out/`:
52
+
53
+ - `yarn check-all > js-out/check-all.log`,`EXIT:0`
54
+ - `cargo build --release > js-out/release-build.log`
55
+ - `./target/release/cr calcit/test.cirru -1 > js-out/release-run.log`,`EXIT:0`
56
+
57
+ 结论:本次改动仅增强静态类型信息,未改变运行行为,且全量检查通过。
@@ -0,0 +1,30 @@
1
+ # 2026-03-05 19:30 schema 迁移记录
2
+
3
+ ## 本次改动
4
+
5
+ - 持续使用 `cr edit schema` 迁移 `src/cirru/calcit-core.cirru` 中 `defn` 的 `:schema`。
6
+ - 统一命令形式为:
7
+ - entry 使用 `src/cirru/calcit-core.cirru`
8
+ - target 使用 `namespace/definition`
9
+ - schema 使用 pair map 语法:`{} (:kind :fn) (:args ...) (:return ...)`
10
+ - 对包含 `?` 的函数名(如 `set?`)在 shell 中使用引号,避免 zsh 通配展开。
11
+
12
+ ## 迁移经验
13
+
14
+ - `cr -- calcit/test.cirru edit schema calcit.core/...` 会触发“只允许 app 包编辑”,改用 core 源文件作为 entry 可编辑 core namespace。
15
+ - schema map 在 `-e` 中不能写成 `:args ... :return ...` 平铺键值,必须写成 `(:args ...)`、`(:return ...)` 的 pair。
16
+ - 批量链式命令中若某个目标失败,会中断后续目标;迁移后需要用搜索确认实际落盘范围。
17
+
18
+ ## 本轮补充的 schema(代表性)
19
+
20
+ - `section-by`, `select-keys`, `set?`, `slice`, `some-in?`, `some?`
21
+ - `str`, `str-spaced`, `string?`, `strip-prefix`, `strip-suffix`
22
+ - `struct?`, `symbol?`, `syntax?`, `tag?`, `tagging-edn`
23
+ - `take`, `take-last`, `thread-step?`, `tuple?`, `turn-str`
24
+ - `union`, `unselect-keys`, `update`, `update-in`
25
+ - `option:map`, `optionally`, `pairs-map`, `range-bothway`, `result:map`, `vals`, `zipmap`
26
+ - `calcit.internal/normalize-trait-type`
27
+
28
+ ## 验证
29
+
30
+ - 运行通过:`cargo test && yarn check-all`。
@@ -0,0 +1,42 @@
1
+ # 2026-03-05 19:39 query schema 适配
2
+
3
+ ## 改动概要
4
+
5
+ - 针对 `cr query` 工具链补充 schema 感知与展示,修改文件:
6
+ - `src/bin/cli_handlers/query.rs`
7
+
8
+ ## 具体更新
9
+
10
+ - `query defs <ns>`
11
+ - 对带 schema 的定义添加 `[schema]` 提示,便于快速识别迁移覆盖率。
12
+
13
+ - `query def <ns/def>`
14
+ - 新增 `Schema` 区块输出(无 schema 时显示 `(none)`)。
15
+ - `--json` 输出从仅 code 扩展为完整 `CodeEntry` 结构:
16
+ - `doc`
17
+ - `examples`
18
+ - `code`
19
+ - `schema`
20
+
21
+ - `query peek <ns/def>`
22
+ - 新增 schema 预览(one-liner,超长截断)。
23
+
24
+ - `query find <symbol>`
25
+ - 引用搜索范围从 `code` 扩展到 `schema`。
26
+ - 输出中标注命中来源 `[code]` / `[schema]`。
27
+
28
+ - `query usages <ns/def>`
29
+ - 用法搜索范围从 `code` 扩展到 `schema`。
30
+ - 输出中标注命中来源 `[code]` / `[schema]`。
31
+
32
+ ## 兼容性说明
33
+
34
+ - 未新增 CLI 参数,保持原命令兼容;schema 能力默认生效。
35
+ - 仅增强查询展示与搜索语义,不影响运行时求值逻辑。
36
+
37
+ ## 验证
38
+
39
+ - 已执行并通过:
40
+ - `cargo fmt`
41
+ - `cargo test`
42
+ - `yarn check-all`
@@ -0,0 +1,38 @@
1
+ # 2026-03-06 01:20 Schema Hint Migration Batch
2
+
3
+ ## 概要
4
+
5
+ 本次集中推进 `hint-fn` 新 schema map 语法迁移,覆盖 core 与测试快照中的多批函数/示例;并持续以 `cargo run --bin cr -- calcit/test.cirru -1` 与 `yarn check-all` 做回归验证。
6
+
7
+ ## 关键变更点
8
+
9
+ - 在 `src/cirru/calcit-core.cirru` 中将大量旧写法 `hint-fn $ return-type ...` 迁移为:
10
+ - `hint-fn $ {}`
11
+ - `:args` / `:rest` / `:return` / `:generics` 等字段显式表达
12
+ - 对已由 `:args`/`:rest` 覆盖的参数类型,移除冗余 `assert-type`(保持必要运行时校验逻辑不变)。
13
+ - 同步修正若干 schema 与实现不一致处(例如部分参数应为 `:number`/`:fn` 的场景)。
14
+ - 完成多处嵌套局部函数(如 `%map`、`%map-indexed`、`%pairs-map`、`%select-keys`、`%repeat` 等)的 hint 迁移。
15
+ - 继续保持 `calcit/*.cirru` 测试快照侧的新语法一致性。
16
+
17
+ ## 工具与流程
18
+
19
+ - 使用新增命令 `cr edit format` 对变更的 snapshot 文件做规范化重写:
20
+ - `src/cirru/calcit-core.cirru`
21
+ - `calcit/test-generics.cirru`
22
+ - `calcit/test-js.cirru`
23
+ - `calcit/test-types-inference.cirru`
24
+ - `calcit/test-types.cirru`
25
+ - 使用 `cargo fmt` 统一 Rust 代码格式。
26
+
27
+ ## 验证
28
+
29
+ - 多轮执行并通过:
30
+ - `cargo run --bin cr -- calcit/test.cirru -1`
31
+ - `yarn check-all`
32
+ - 迁移过程中持续统计 `src/cirru/calcit-core.cirru` 内剩余旧模式数量,确认总体下降趋势。
33
+
34
+ ## 经验
35
+
36
+ - 在 schema-first 迁移中,优先迁移“签名简单、类型清晰”的函数可快速稳定推进。
37
+ - 对复杂逻辑函数保留运行时断言,但避免与 `:args` 重复声明同一层参数类型。
38
+ - 每批次后立即执行 targeted + full 验证,能快速定位回归并降低累计风险。
@@ -0,0 +1,20 @@
1
+ ## 概要
2
+
3
+ 本次提交继续推进 schema-first 迁移,聚焦 `src/cirru/calcit-core.cirru`,为核心宏入口补齐显式 `:schema`,在不改变运行逻辑的前提下提升静态信息覆盖率与一致性。
4
+
5
+ ## 关键改动
6
+
7
+ - 补齐高频线程/控制宏 schema:`->`、`->>`、`<-`、`if-not`、`thread-as`、`thread-first`、`thread-last`、`;nil`、`:`。
8
+ - 补齐构造/模式宏 schema:`list-match`、`record-match`、`record-with`、`tag-match`、`field-match`、`{}`。
9
+ - 补齐内部宏入口 schema:`&case`、`&list-match-internal`、`&record-match-internal`、`&field-match-internal`。
10
+ - 补齐工具/调试宏 schema:`[,]`、`[][]`、`\`、`\.`、`call-w-log`、`call-wo-log`、`js-object`、`w-log`、`w-js-log`、`with-cpu-time`、`with-gensyms`、`wo-log`、`wo-js-log`、`noted`。
11
+
12
+ ## 结果
13
+
14
+ - `calcit-core` 中 `defmacro` 对应的 `:schema nil` 已清空。
15
+ - 每批改动后均执行 `edit format` 与 `yarn check-all`,回归通过。
16
+
17
+ ## 经验
18
+
19
+ - 采用“按语义分组小批次补齐 + 每批全量回归”策略,可在大文件中稳定推进迁移并快速定位异常。
20
+ - 对宏统一使用 `:kind :macro` 与 `:args/:rest/:return` 结构,能减少后续工具链处理分支。
@@ -0,0 +1,63 @@
1
+ # 2026-03-06 15:52 core schema + hint-fn 迁移批次
2
+
3
+ ## 背景
4
+
5
+ 本批次延续 schema-first 迁移:
6
+
7
+ - 在 `src/cirru/calcit-core.cirru` 继续将 runtime 内建的 `:schema nil` 改为显式 schema。
8
+ - 在 `calcit/` 测试目录中,将旧式 `hint-fn` 参数写法迁移为新写法。
9
+
10
+ ## 主要改动
11
+
12
+ ### 1) Core runtime schema 补齐(无行为改动)
13
+
14
+ 在 `src/cirru/calcit-core.cirru` 增补了多批低风险条目的 schema,覆盖例如:
15
+
16
+ - 数学/比较/位运算:`cos`/`sin`/`sqrt`/`round`/`round?`/`floor`/`ceil`、`bit-*` 系列等
17
+ - 字符串/解析/格式化:`split`/`split-lines`/`trim`/`parse-cirru*`/`format-cirru*`
18
+ - IO 与环境:`read-file`/`write-file`/`get-env`/`generate-id!`
19
+ - 运行时工具:`atom`/`add-watch`/`remove-watch`/`type-of`/`turn-*`/`fold*`/`range`/`recur`/`raise`/`quit!`
20
+
21
+ 原则:仅补 schema,不改运行时逻辑。
22
+
23
+ ### 2) 旧式 hint-fn 参数写法迁移
24
+
25
+ 在 `calcit/test-types-inference.cirru` 中,将旧写法:
26
+
27
+ - `:args $ [] :number`
28
+
29
+ 迁移为新写法:
30
+
31
+ - `:args $ [] (:: 'x :number)`
32
+
33
+ 并复查 `calcit/**` 下同模式,不再命中。
34
+
35
+ ## 验证
36
+
37
+ 每批次均执行:
38
+
39
+ - `cargo run --bin cr -- demos/compact.cirru edit format`
40
+ - `yarn check-all`
41
+
42
+ 结果均通过(尾部稳定为 `... and 24 files not changed.`)。
43
+
44
+ ## 备注
45
+
46
+ - 当前提交聚合了本轮连续小批次迁移结果,便于后续按文件/功能继续清理剩余 `:schema nil`。
47
+
48
+ ## 增补(同批次续改)
49
+
50
+ ### 3) 移除 legacy hint-fn clause 兼容(改为直接报错)
51
+
52
+ 在 `src/runner/preprocess.rs` 中将旧语法兼容从 warning 升级为 hard error:
53
+
54
+ - 不再接受 `hint-fn` 内 legacy clauses:`return-type` / `generics` / `type-vars`
55
+ - 统一在 `preprocess_hint_fn` 阶段报 `Syntax` 错误,提示迁移到 schema map 形式
56
+ - 删除旧的 `warn_on_legacy_hint_fn_syntax` 路径并同步测试
57
+
58
+ ### 4) 文档更新(docs + guidebook)
59
+
60
+ 同步更新示例与说明,避免继续传播旧写法:
61
+
62
+ - `docs/CalcitAgent.md`:补充“legacy clause 会直接报错”,并将 `:args` 示例改为命名参数条目
63
+ - `guidebook/docs/cirru-syntax.md`、`guidebook/docs/features/static-analysis.md`、`guidebook/docs/features/records.md`:统一 `hint-fn` 示例为 schema-map + `(:: 'arg <type>)` 形式
@@ -0,0 +1,12 @@
1
+ # 本次修改记录
2
+
3
+ - 统一 schema 风格:清理 `:args` / `:rest` 中参数名,保留类型表达式,降低重复声明。
4
+ - 预处理前置 schema:在 `preprocess_defn` 中优先注入 schema hint,再进行类型与返回值检查。
5
+ - 程序装载增强:`program` 层为定义缓存并暴露 schema 查询能力。
6
+ - 快照规范化:`snapshot` 序列化时统一去除 schema 的 `:name` 字段与命名参数注解。
7
+ - 文档同步:更新 Agent 文档中 `hint-fn` / schema 写法示例到当前风格。
8
+
9
+ ## 验证
10
+
11
+ - `cargo test` 通过。
12
+ - `yarn check-all` 通过。
@@ -0,0 +1,82 @@
1
+ # 2026-0307-0142 `:unit` 类型 + 内建函数 schema 批量补全
2
+
3
+ ## 改动概要
4
+
5
+ ### 1. Rust 类型系统: `CalcitTypeAnnotation::Nil` (`:unit`)
6
+
7
+ 在 `src/calcit/type_annotation.rs` 中添加新的 `Nil` variant, 对应 Cirru 关键字 `:unit`。
8
+
9
+ **使用场景**: 副作用函数 (side-effectful functions), 明确标注返回 `nil` 的情况, 区别于 `:dynamic` (未知类型)。
10
+
11
+ **涉及改动点**:
12
+
13
+ - `CalcitTypeAnnotation` enum: 新增 `Nil` variant
14
+ - `builtin_type_from_tag_name`: `"unit" | "nil" => Self::Nil`
15
+ - `builtin_tag_name`: `Self::Nil => Some("unit")`
16
+ - `variant_order`: `Self::Nil => 27`
17
+ - `matches_with_bindings`: `(Self::Nil, Self::Nil) => true`
18
+ - `Hash impl`: `Self::Nil => "nil".hash(state)`
19
+ - `value_matches_type_annotation`: `CalcitTypeAnnotation::Nil => matches!(value, Calcit::Nil)`
20
+ - `gen_ir.rs`: `CalcitTypeAnnotation::Nil => type_tag_map("unit")`
21
+
22
+ ### 2. 副作用函数 `:return :unit` schema
23
+
24
+ 在 `src/cirru/calcit-core.cirru` 中为以下函数补充 `:return :unit` schema:
25
+
26
+ | 函数名 | schema 要点 |
27
+ | -------------- | ------------------------------------------------------- |
28
+ | `each` | `:args ([] :dynamic :fn) :return :unit` |
29
+ | `write-file` | `:args ([] :string :string) :return :unit` |
30
+ | `quit!` | `:args ([] (:: :optional :number)) :return :unit` |
31
+ | `add-watch` | `:args ([] :ref :dynamic :fn) :return :unit` |
32
+ | `remove-watch` | `:args ([] :ref :dynamic) :return :unit` |
33
+ | `reset!` | `:generics 'T :args ([] (:: :ref 'T) 'T) :return :unit` |
34
+
35
+ **注意事项**: 在 `:: :fn ('T) :unit` 中, `'T` 出现在 `('T)` 列表的算子位置会触发 EDN 解析错误 (`invalid operator for edn: 'T`)。对 `each` 的解决方案是简化成 `:fn`, 避免在 fn 参数类型中使用泛型变量作为算子。
36
+
37
+ ### 3. 内建函数 schema 批量补全 (54 条)
38
+
39
+ 对 `calcit-core.cirru` 中原本 `:schema nil` 的内建 primitive 函数批量补充类型:
40
+
41
+ **`&list:*` (16 条)**: `assoc`, `assoc-after`, `assoc-before`, `concat`, `contains?`, `count`, `dissoc`, `distinct`, `empty?`, `first`, `includes?`, `nth`, `rest`, `reverse`, `slice`, `to-set`
42
+
43
+ **`&map:*` (12 条)**: `assoc`, `common-keys`, `contains?`, `count`, `destruct`, `diff-keys`, `diff-new`, `dissoc`, `empty?`, `get`, `includes?`, `to-list`
44
+
45
+ **`&str:*` (15 条)**: `compare`, `concat`, `contains?`, `count`, `empty?`, `escape`, `find-index`, `first`, `includes?`, `nth`, `pad-left`, `pad-right`, `replace`, `rest`, `slice`
46
+
47
+ **集合操作 (10 条)**: `&difference`, `&exclude`, `&include`, `&set:count`, `&set:destruct`, `&set:empty?`, `&set:includes?`, `&set:intersection`, `&set:to-list`, `&union`
48
+
49
+ **泛型模式** (使用 `'T` 非算子位置):
50
+
51
+ ```cirru
52
+ {} (:kind :fn)
53
+ :generics $ [] 'T
54
+ :args $ [] (:: :list 'T) :number 'T
55
+ :return $ :: :list 'T
56
+ ```
57
+
58
+ ### 4. Clippy & 代码质量修复
59
+
60
+ - `emit_js.rs`: 消除冗余闭包 `xs.iter().skip(1).any(schema_marks_async)`
61
+ - `query.rs`: 添加复杂类型别名 `type RefResults = ...`
62
+
63
+ ## 技术知识点
64
+
65
+ ### `'T` 在 schema 文件中的限制
66
+
67
+ - **可用位置**: `:generics $ [] 'T`, `(:: :list 'T)` 的末尾参数, `[] :arg1 'T`
68
+ - **不可用位置**: `('T)` 即 `'T` 作为列表算子 (head), 例如 `(:: :fn ('T) :unit)` 中的 `('T)`
69
+ - **根本原因**: schema 验证通过 `cirru_edn::parse` 进行, EDN 解析器要求列表头部必须是合法算子
70
+
71
+ ### `:unit` vs `:dynamic`
72
+
73
+ - `:unit` — 明确标注 "此函数返回 nil, 且是预期行为" (副作用函数)
74
+ - `:dynamic` — 未知/任意类型 (默认回退)
75
+
76
+ ## 验证结果
77
+
78
+ ```
79
+ cargo clippy -- -D warnings → ✓ 0 warnings
80
+ cargo test → ✓ 17/17 passed
81
+ yarn check-all → ✓ took 571ms, all passed
82
+ ```
@@ -0,0 +1,32 @@
1
+ # 2026-03-07 CalcitAgent.md 文档更新
2
+
3
+ ## 修改内容
4
+
5
+ ### 1. 新增 `--no-tips` 全局标志文档
6
+
7
+ 在「主要运行命令」小节中,`cr js --check-only` 之后新增:
8
+
9
+ ```
10
+ - `cr --no-tips <subcommand> ...` - 隐藏所有编辑/查询命令输出的 "Tips:" 提示行(适合脚本/Agent 使用)
11
+ - 示例:`cr --no-tips demos/compact.cirru query def calcit.core/foldl`
12
+ ```
13
+
14
+ **背景**:`aa21b3a` 提交新增了 `--no-tips` 全局开关(`TIPS_SUPPRESSED: AtomicBool`,通过 `suppress_tips()` 设置),文档中缺少记录。
15
+
16
+ ### 2. 新增 HOF 高阶函数回调类型检查说明
17
+
18
+ 在「类型标注与检查 → 3. 支持的类型标签」之后,`约定:动态类型标注…` 注释的下方新增章节:
19
+
20
+ **高阶函数(HOF)回调类型检查:**
21
+ `foldl`、`sort`、`filter`、`find`、`find-index`、`filter-not`、`mapcat`、`group-by` 等内置 HOF 的回调参数已强制要求 `:fn` 类型,传入非函数值时预处理阶段会触发类型警告。附正/误示例。
22
+
23
+ **背景**:`aa21b3a` 提交修复了以下两条路径的类型检查:
24
+
25
+ - Cirru `defn` schema (`calcit-core.cirru`):`filter-not`/`find`/`find-index`/`foldl`/`foldl'`/`foldl-compare`/`mapcat`/`group-by`/`sort` 的回调参数由 `:dynamic` 改为 `:fn`(部分带泛型注解)
26
+ - `ProcTypeSignature` (`proc_name.rs`):`Foldl`/`Sort`/`FoldlShortcut`/`FoldrShortcut` 的回调参数 `dynamic` → `some_fn()`/`optional_fn()`
27
+
28
+ ## 知识点
29
+
30
+ - **文档中不需要描述 `ProTypeSignature` 实现细节**,面向 Agent 只需说明行为:哪些 HOF 要求 `:fn` 参数。
31
+ - **`--no-tips` 定位**:全局开关,放在 subcommand 前;所有 `Tips::print()` 调用均受其控制。
32
+ - CalcitAgent.md 未发现旧 `-s/--stdin` 残留,无需清理。
@@ -0,0 +1,112 @@
1
+ # 2026-0307-1652 — 解耦 snapshot::CodeEntry.schema 为 Arc<CalcitTypeAnnotation>
2
+
3
+ ## 核心改动
4
+
5
+ 将整个项目中 `snapshot::CodeEntry.schema` 和 `program::ProgramDefEntry.schema` 的类型,从 `Option<Edn>` / `Option<Arc<CalcitFnTypeAnnotation>>` 统一迁移为 `Arc<CalcitTypeAnnotation>`。
6
+
7
+ 同时打破了 `type_annotation.rs → program → snapshot → calcit` 的循环依赖。
8
+
9
+ ---
10
+
11
+ ## 循环依赖的解法
12
+
13
+ **原依赖链(错误):**
14
+
15
+ ```
16
+ snapshot → calcit::type_annotation → program → snapshot ❌
17
+ ```
18
+
19
+ **修复方案:** 在 `type_annotation.rs` 中用 `OnceLock<fn>` 注册 program 级别的 lookup 函数,由 `program.rs` 在 `extract_program_data` 时调用 `register_program_lookups` 完成注册:
20
+
21
+ ```rust
22
+ type LookupFn = fn(&str, &str) -> Option<Calcit>;
23
+ static LOOKUP_EVALED_DEF: OnceLock<LookupFn> = OnceLock::new();
24
+ static LOOKUP_DEF_CODE: OnceLock<LookupFn> = OnceLock::new();
25
+
26
+ pub fn register_program_lookups(evaled: LookupFn, code: LookupFn) {
27
+ let _ = LOOKUP_EVALED_DEF.set(evaled);
28
+ let _ = LOOKUP_DEF_CODE.set(code);
29
+ }
30
+ ```
31
+
32
+ ---
33
+
34
+ ## 修改文件列表
35
+
36
+ ### `src/calcit/type_annotation.rs`
37
+
38
+ - 移除 `use crate::program;` 导入
39
+ - 新增 OnceLock 静态注册机制及 `register_program_lookups` 公开函数
40
+ - 将 6 处 `program::lookup_*` 调用替换为本地 `lookup_evaled_def` / `lookup_def_code_registered`
41
+ - 新增 `CalcitTypeAnnotation::to_type_edn(&self) -> Edn` 序列化方法
42
+ - 新增 `calcit_type_to_edn(form: &Calcit) -> Edn` 私有辅助函数(Custom 类型回退)
43
+ - 新增 `CalcitFnTypeAnnotation::to_schema_edn(&self) -> Edn`(输出完整 schema map)
44
+ - 新增 `CalcitFnTypeAnnotation::to_schema_calcit(&self) -> Calcit`(用于 hint-fn 注入)
45
+ - 修复 `Self::Struct/Enum` 序列化:使用 `Edn::Tag` 而非 `Edn::Symbol`(类型不同)
46
+
47
+ ### `src/calcit.rs`
48
+
49
+ - 在 `pub use type_annotation::` 中新增 `register_program_lookups`
50
+
51
+ ### `src/program.rs`
52
+
53
+ - `ProgramDefEntry.schema: Arc<CalcitTypeAnnotation>`(取代旧 `Option<Arc<CalcitFnTypeAnnotation>>`)
54
+ - `extract_program_data` 首行调用 `calcit::register_program_lookups(...)`
55
+ - `lookup_def_schema` 返回类型改为 `Arc<CalcitTypeAnnotation>`(不再返回 Option,缺省返回 `DYNAMIC_TYPE`)
56
+ - `apply_code_changes` 中 `schema: DYNAMIC_TYPE.clone()` 取代 `None`
57
+
58
+ ### `src/snapshot.rs`
59
+
60
+ - 移除 `CalcitFnTypeAnnotation` 从导入(已无直接使用)
61
+ - 新增 `mod schema_serde`:将 `Arc<CalcitTypeAnnotation>` 序列化为 `Option<Edn>` 保持二进制 RMP 兼容
62
+ - `CodeEntry.schema: Arc<CalcitTypeAnnotation>`,带 `#[serde(default, with = "schema_serde")]`
63
+ - `TryFrom<Edn>` / `From` trait 实现全部更新,使用 `parse_fn_schema_from_edn` + `DYNAMIC_TYPE`
64
+ - 测试用例中 `schema: Some(Edn)` 改为通过 `parse_fn_schema_from_edn` 构造 `Arc<CalcitTypeAnnotation>`
65
+
66
+ ### `src/detailed_snapshot.rs`
67
+
68
+ - 同 `snapshot.rs` 模式:新增 `mod schema_serde`,字段类型改为 `Arc<CalcitTypeAnnotation>`
69
+ - `From<CodeEntry>` / `From<DetailedCodeEntry>` 均直接 clone Arc
70
+
71
+ ### `src/runner/preprocess.rs`
72
+
73
+ - hint-fn 注入改为先匹配 `CalcitTypeAnnotation::Fn(fn_annot)`,再调用 `fn_annot.to_schema_calcit()`
74
+
75
+ ### `src/bin/cli_handlers/edit.rs`
76
+
77
+ - schema 清空时:`schema = DYNAMIC_TYPE.clone()`
78
+ - schema 写入时:通过 `parse_fn_schema_from_edn` 解析后包装为 `Arc<CalcitTypeAnnotation::Fn(...)>`
79
+
80
+ ### `src/bin/cli_handlers/query.rs`
81
+
82
+ - 4 处 `entry.schema.is_some()` / `if let Some(schema_edn)` 全部改为 `CalcitTypeAnnotation::Fn(fn_annot)` 匹配
83
+ - 序列化时通过 `fn_annot.to_schema_edn()` 转回 Edn 后再调用 `schema_edn_to_cirru`
84
+
85
+ ### `src/bin/cr.rs`
86
+
87
+ - 新增 `CalcitTypeAnnotation` 到 `use calcit::{calcit::{...}}` 导入
88
+ - 原 `schema: None` 改为 `calcit::calcit::DYNAMIC_TYPE.clone()`
89
+ - `if let Some(schema_edn)` 改为 `if let CalcitTypeAnnotation::Fn(fn_annot)`
90
+
91
+ ### `src/bin/cr_sync.rs`
92
+
93
+ - `schema: None` 改为 `calcit::calcit::DYNAMIC_TYPE.clone()`
94
+
95
+ ---
96
+
97
+ ## 关键设计决策
98
+
99
+ 1. **`Arc<CalcitTypeAnnotation>` 永不为 None**:缺省值统一为 `DYNAMIC_TYPE`(全局 `LazyLock<Arc<CalcitTypeAnnotation>>` 单例),避免到处 `Option` 处理。
100
+
101
+ 2. **二进制兼容**:`schema_serde` 模块确保 `Dynamic` → 序列化为 `None`,`Fn(...)` → 序列化为完整 Edn map,与旧 `Option<Edn>` 格式一一对应。
102
+
103
+ 3. **`Edn::Tag` 用于类型名称**:`Struct`/`Enum` 类型序列化时用 `Edn::Tag(name)` 而非 `Edn::Symbol(name)`,因为 `EdnTag` 不能直接构造 `Edn::Symbol(Arc<str>)`。
104
+
105
+ ---
106
+
107
+ ## 验证结果
108
+
109
+ - `cargo build` ✅
110
+ - `cargo clippy -- -D warnings` ✅
111
+ - `cargo test` ✅(17 passed)
112
+ - `yarn check-all` ✅(515ms)
@@ -0,0 +1,6 @@
1
+ # 2026-0307-1821 Snapshot and Schema Serialization Refinement
2
+
3
+ - Verified Rust core changes using `yarn try-rs`, `cargo test`, and `yarn check-all`.
4
+ - Ensured `Snapshot` and `CodeEntry` serialization/deserialization remains consistent with the new direct map EDN format for schemas.
5
+ - Confirmed unit tests for `CodeEntry` with examples and schema validation are passing.
6
+ - Validated that `calcit-core.cirru` example parsing works as expected.
@@ -0,0 +1,96 @@
1
+ # Schema vs Definition Kind/Arity Validation
2
+
3
+ ## Summary
4
+
5
+ Added structural validation that compares a definition's code form against its schema declaration. This catch mismatches between declared schema metadata (`:kind`, arg count, rest param) and the actual `defn`/`defmacro` code at analysis time.
6
+
7
+ ## Key Changes
8
+
9
+ ### `src/calcit/type_annotation.rs`
10
+
11
+ 1. **Added `SchemaKind` enum** (`pub enum SchemaKind { Fn, Macro }`) — distinguishes `:kind :fn` from `:kind :macro` schemas.
12
+
13
+ 2. **Extended `CalcitFnTypeAnnotation`** with two new fields:
14
+ - `pub fn_kind: SchemaKind` — schema's declared kind (fn/macro).
15
+ - `pub rest_type: Option<Arc<CalcitTypeAnnotation>>` — schema's `:rest` type, if present.
16
+
17
+ 3. **`parse_fn_schema_from_edn`** — now reads `:kind :macro` → `SchemaKind::Macro` and `:rest` → `rest_type` from the EDN map.
18
+
19
+ 4. **`to_schema_edn`** — now serializes `fn_kind` (`fn`/`macro`) and `rest_type` (`:rest` key in the output map). Previously always emitted `:kind :fn` and omitted `:rest`.
20
+
21
+ 5. **All `CalcitFnTypeAnnotation` construction sites** updated to add `fn_kind: SchemaKind::Fn, rest_type: None` defaults (7 total).
22
+
23
+ 6. **`substitute_type_vars`** also propagates `fn_kind` and substitutes `rest_type`.
24
+
25
+ ### `src/calcit.rs`
26
+
27
+ - `SchemaKind` added to the `pub use type_annotation::{ ... }` re-export.
28
+
29
+ ### `src/bin/cr.rs`
30
+
31
+ 1. **`SchemaKind` imported** in the `use calcit::calcit::{...}` block.
32
+
33
+ 2. **`TypeCoverageRow` struct** gained `schema_issues: Vec<String>` field — carries kind/arity mismatch warnings per definition.
34
+
35
+ 3. **`validate_def_vs_schema(ns, def_name, code, schema) -> Vec<String>`** — new function:
36
+ - `&runtime-inplementation` leaf → skip (builtin proc/syntax).
37
+ - Schema not `CalcitTypeAnnotation::Fn` → skip.
38
+ - Code head not `defn`/`defmacro` → skip.
39
+ - Schema `:kind :fn` + code `defmacro` → error.
40
+ - Schema `:kind :macro` + code `defn` → error.
41
+ - Required arg count mismatch → error.
42
+ - `has_rest` mismatch (schema `:rest` vs code `&`) → error.
43
+
44
+ 4. **`analyze_param_arity(args: Option<&Cirru>) -> (usize, bool)`** — helper that counts required params and detects the `&` rest marker in a `defn`/`defmacro` args list.
45
+
46
+ 5. **`analyze_code_entry`** calls `validate_def_vs_schema` to populate `schema_issues` on each `TypeCoverageRow`.
47
+
48
+ 6. **`run_check_types` output loop** prints a `schema-issues:` section for rows with non-empty issues.
49
+
50
+ 7. **10 new unit tests** covering:
51
+ - `&runtime-inplementation` skip
52
+ - Correct defn/macro → no issues
53
+ - Kind mismatch (`:fn` vs `defmacro`, `:macro` vs `defn`)
54
+ - Arity mismatch
55
+ - Rest param mismatch
56
+ - `analyze_param_arity` basics
57
+ 8. **`CR_DEBUG_SCHEMA` debug flag** — when `CR_DEBUG_SCHEMA=1`, prints per-entry schema kind debug info to stderr during `analyze check-types`.
58
+
59
+ ### `src/runner/preprocess.rs`
60
+
61
+ 1. **Runtime/preprocess enforcement added** — schema-vs-definition structural checks now run while preprocessing `defn`/`defmacro`, not only in `analyze check-types`.
62
+ 2. **`validate_def_schema_during_preprocess(...)`** — mirrors the `check-types` validation for `:kind`, required arity, and `:rest`, and raises a hard `[Type Error]` during normal execution paths such as `yarn try-rs`.
63
+ 3. **Schema hints preserved** — preprocess still injects `hint-fn`, but now only after the definition passes structural schema validation.
64
+ 4. **2 new preprocess tests** covering arity mismatch and `:kind` mismatch at preprocess time.
65
+
66
+ ### `calcit/test-hygienic.cirru`
67
+
68
+ - Updated existing test fixture schemas so they match actual code:
69
+ - `add-11` / `add-11-safe`: `:kind :macro`
70
+ - `add-2`: arg schema corrected from 2 params to 1
71
+
72
+ ### `src/snapshot.rs`
73
+
74
+ - **`test_macro_schema_round_trip`** — verifies `schema_cirru_to_edn` + `parse_fn_schema_from_edn` + `normalize_schema_edn` preserve `SchemaKind::Macro` end-to-end.
75
+ - **`test_macro_schema_full_file_round_trip`** — verifies full `CodeEntry` serialize (`From<&CodeEntry> for Edn`) → `cirru_edn::format` → `cirru_edn::parse` → `TryFrom<Edn> for CodeEntry` round-trip preserves `fn_kind: Macro`.
76
+
77
+ ## Validation Rule Summary
78
+
79
+ | Schema `:kind` | Code form | Result |
80
+ | -------------- | ------------------------- | --------------- |
81
+ | `:fn` | `defn` | ✓ ok |
82
+ | `:fn` | `defmacro` | ✗ kind mismatch |
83
+ | `:macro` | `defmacro` | ✓ ok |
84
+ | `:macro` | `defn` | ✗ kind mismatch |
85
+ | any | `&runtime-inplementation` | ✓ skip |
86
+
87
+ Arg count and rest param are checked independently of kind.
88
+
89
+ ## Notes
90
+
91
+ - **`calcit.core` schemas require binary rebuild**: Schema edits to `src/cirru/calcit-core.cirru` do not take effect at runtime until the binary is rebuilt, because the core namespace is always loaded from the embedded `include_bytes!` snapshot produced by `build.rs`. Schema validation is most useful for user-defined namespaces.
92
+ - **Normal execution now checks schemas too**: before this follow-up, schema-vs-def mismatches were only reported by `analyze check-types`; now they fail fast during normal preprocess/runtime startup as well.
93
+
94
+ ## Test Results
95
+
96
+ All 125 tests pass (99 library + 26 binary), including 2 new snapshot round-trip tests and 2 new preprocess validation tests.
@@ -0,0 +1,29 @@
1
+ # 2026-03-07 migrate hint-fn to schema for top-level defs
2
+
3
+ ## 背景
4
+
5
+ `calcit-core.cirru` 中大量顶层函数在函数体内以 `hint-fn $ {} (:return ...)` 的方式标注返回类型。这是旧写法,新写法是在 `:schema` 字段中声明 `{} (:kind :fn) (:return ...)` 等结构。
6
+
7
+ ## 本次操作
8
+
9
+ - 将所有顶层定义(`defn`/`defmacro`)的 `hint-fn` 从函数体 `[3,0]` 位置删除,改为 `edit schema` 写入 `:schema` 字段
10
+ - 共处理 100+ 个函数,包含 `calcit.core` 和 `calcit.internal` 两个 namespace
11
+ - 对带泛型的函数(`&list:filter`、`&list:map`、`&fn:bind` 等)补充了 `:generics` 字段
12
+
13
+ ## 保留 hint-fn 的情况
14
+
15
+ 内层/局部函数没有 schema 位置,仍然保留 hint-fn,例如:
16
+
17
+ - `{,}` 内的 `&{,}` 局部函数
18
+ - `map` 内的 `%map`
19
+ - `join` 内的 `%join` / `%join-str`
20
+ - `select-keys` 内的 `%select-keys`
21
+ - `&map:filter` 等内部 defn
22
+
23
+ ## 修复的 bug
24
+
25
+ - `parse_target` 在 `query.rs` / `edit.rs` 中使用 `rsplit_once('/')` 导致函数名含 `/`(如 `/`、`/=`)无法识别,改为 `split_once('/')` 修复
26
+
27
+ ## 验证
28
+
29
+ `yarn try-rs` 全程通过,最终耗时约 350ms。
@@ -0,0 +1,43 @@
1
+ # 2026-0307 移除 CalcitEnum 的 prototype 字段
2
+
3
+ ## 背景
4
+
5
+ 老版本的 `CalcitEnum` 使用 `prototype: Arc<CalcitRecord>` 存储枚举定义(字段=variant tag,值=payload 类型列表),因为当时 enum 借助 record 的数据结构来定义。现在 enum 已有独立的定义语法(`defenum`),prototype 字段冗余,予以移除。
6
+
7
+ ## 主要变更
8
+
9
+ ### `src/calcit/sum_type.rs`
10
+
11
+ - `CalcitEnum` 结构体:`prototype: Arc<CalcitRecord>` → `name: EdnTag`
12
+ - `from_record` / `from_arc`:提取 name,不再存储整个 record
13
+ - 删除 `prototype()` 方法,新增 `name()` 返回 `&EdnTag`
14
+ - 新增 `to_record_prototype() -> CalcitRecord`:根据 `name + variants` 按需重建 `CalcitRecord`,供 `preprocess.rs` 向后兼容使用
15
+
16
+ ### `src/calcit.rs`
17
+
18
+ - `Hash` 实现:改为对 variant tag + payload type 逐项哈希
19
+ - `PartialEq` 实现:`a.prototype() == b.prototype()` → `a.name() == b.name() && a.variants() == b.variants()`
20
+
21
+ ### `src/calcit/compare.rs`
22
+
23
+ - `compare_calcit_enum_values`:不再对比 prototype record,改为先比较 name,再逐 variant 比较 tag 和 payload types(深度比较),确保 `Ord::cmp == Equal` ⟺ `PartialEq::eq == true`
24
+
25
+ ### `src/data.rs`
26
+
27
+ - `Enum(enum_def)` 序列化分支:通过 `enum_def.name()` 和 `enum_def.variants()` 直接读取,不再依赖 prototype record
28
+
29
+ ### `src/runner/preprocess.rs`
30
+
31
+ - `resolve_record_value` 中所有 `Calcit::Enum(enum_def)` 分支:`enum_def.prototype().to_owned()` → `enum_def.to_record_prototype()`
32
+
33
+ ## 验证结果
34
+
35
+ - `cargo build` ✅(无警告)
36
+ - `cargo test` ✅(94 + 17 = 111 通过,0 失败)
37
+ - `cargo clippy -- -D warnings` ✅(无警告)
38
+ - `yarn check-all` ✅(exit 0)
39
+
40
+ ## 踩坑与注意
41
+
42
+ - `compare_calcit_enum_values` 最初只比 tag 未比 payload types,导致 `cmp_equal_matches_eq_for_complex_named_variants` 失败。修复时需对每个 variant 的 payload types 也做深度比较。
43
+ - `to_record_prototype()` 是按需重建而非缓存,性能上无问题(仅在类型检查预处理阶段调用)。
@@ -0,0 +1,66 @@
1
+ # 2026-03-07 schema.args 类型检查接通与 fn 类型注解修复
2
+
3
+ ## 背景
4
+
5
+ 上一次 session(commit a008f8b)为 calcit-core 的 54+ 函数添加了 `:schema` 中的 `:args` 字段。但发现这些 schema
6
+ 并未实际触发调用现场的类型检查——`CalcitFn.arg_types` 只从函数体的 `assert-type` 扫描,从未读取 schema `:args`。
7
+
8
+ ## 根因分析
9
+
10
+ 类型检查数据流:
11
+
12
+ ```
13
+ calcit-core.cirru :schema :args
14
+ → preprocess.rs 注入为 (HintFn schema_value) 进 defn 体
15
+ → syntax.rs defn 调用 detect_arg_type_hints → collect_arg_type_hints_from_body
16
+ → 只扫描 assert-type/assert-traits,忽略 HintFn!
17
+ → CalcitFn.arg_types 对 schema-only 函数全为 Dynamic
18
+ → check_user_fn_arg_types 提前返回,无任何检查
19
+ ```
20
+
21
+ ## 修复内容
22
+
23
+ ### 1. 接通 schema.args → CalcitFn.arg_types(`syntax.rs` + `type_annotation.rs`)
24
+
25
+ - 新增 `CalcitTypeAnnotation::extract_arg_types_from_hint_form(form, params)` 方法
26
+ - 新增 `parse_schema_args_types` 和 `is_args_list_head` 辅助方法
27
+ - `syntax.rs:defn` 中优先从 hint-fn(schema 注入)提取 arg_types,再回退到 assert-type 扫描
28
+
29
+ ### 2. fn 类型注解解析修复(`type_annotation.rs`)
30
+
31
+ 发现 `(:: :fn ([] 'T 'U) (:: 'T 'U) 'T)` 格式的 fn 类型注解被错误解析,因为 `[]` 头部(list constructor proc)
32
+ 出现在 args 列表中被当作普通类型处理:
33
+
34
+ - **三处** `parse_type_annotation_form` `:fn` 分支:args_form 为 List 时跳过 `[]` 头部
35
+ - **`parse_generics_list`**:跳过 `[]` 头部,使 `([] 'T 'U)` 作为合法 generics 列表(`'T 'U` 不能作 Cirru EDN operator)
36
+ - **`matches_signature`**:移除 generics 数量检查,改用 `matches_with_bindings` 解析 TypeVar 绑定(使具体函数类型能匹配泛型签名)
37
+ - **`matches_with_bindings`**:`Tag` 可满足 `DynFn`/`Fn` 约束(Calcit 中 `:tag` 作为 map key accessor 可调用)
38
+
39
+ ### 3. method 调用类型检查修复(`preprocess.rs`)
40
+
41
+ 方法调用的 arg 类型检查循环中缺少对 `Variadic` 的处理,导致 `.union s1 s2` 误报。修复为与 `check_user_fn_arg_types` 一致的 Variadic 处理。
42
+
43
+ ### 4. calcit-core.cirru schema 修正
44
+
45
+ | 函数 | 修正内容 |
46
+ | --------------- | --------------------------------------------------------------------------------- |
47
+ | `every?` | `:args $ (:: :list :dynamic)` → `:dynamic`(接受 set) |
48
+ | `keys` | `:args $ :map` → `:dynamic`(接受 record) |
49
+ | `merge` | `:args $ :map` + `:rest $ :map` → `:dynamic`(接受 record) |
50
+ | `merge-non-nil` | 同上 |
51
+ | `reduce` | fn-arg 格式 `([] 'T 'U)(:: 'T 'U)` → `([] 'T 'U)([] 'T 'U)`(正确 generics+args) |
52
+ | `map` | fn-arg 格式 `([] 'T 'U)(:: 'T)` → `([] 'T 'U)([] 'T)`(正确 generics+1-arg) |
53
+
54
+ ## 验证
55
+
56
+ - `each ([] 1 2 3) 42` → 正确警告(42 不是 :fn)
57
+ - `reduce ([] 1 2 3) 0 &+` → 无误报(&+ 满足 fn(T,U)->T)
58
+ - `cargo test`:92 passed, 0 failed(之前 1 个失败的 test_examples_field_parsing 也通过了)
59
+ - `yarn check-all`:全量集成测试通过,0 warnings
60
+
61
+ ## 关键知识点
62
+
63
+ - `([] 'T 'U)` 是合法 Cirru EDN(`[]` 是合法 operator),`('T 'U)` 不合法(`'T` 不能作 operator)
64
+ - fn 类型 generics 列表格式:`([] 'T 'U)` 跳过 `[]` 头后得到 `[T, U]`
65
+ - fn 类型 args 列表格式:`([] :number :number)` 跳过 `[]` 头后得到 `[:number, :number]`
66
+ - `matches_signature` 不应检查 generics 数量——调用方传入的具体函数不声明 generics,但 TypeVar 绑定会在 args 匹配时解析
@@ -0,0 +1,35 @@
1
+ # Schema Generics Quote Normalization
2
+
3
+ ## Summary
4
+
5
+ Tightened schema loading so legacy generic symbols stored with embedded leading quotes now fail immediately, then normalized existing `calcit-core.cirru` schema generics from `''T`-style output to the correct `'T` source syntax.
6
+
7
+ ## Key Changes
8
+
9
+ - `src/calcit/type_annotation.rs`
10
+ - Stopped serializing schema generics as `Edn::Symbol("'T")`.
11
+ - Now writes plain EDN symbols like `Edn::Symbol("T")`, which format back to source as `'T`.
12
+ - Keeps compatibility when parsing previously saved legacy symbols, but normalizes them to plain names.
13
+
14
+ - `src/snapshot.rs`
15
+ - Added load-time rejection for legacy schema generic symbols carrying embedded leading quotes.
16
+ - Normalized schema EDN → Cirru conversion to go through format+parse so quoted symbols render correctly.
17
+ - Added regression tests for:
18
+ - single-quote round-trip,
19
+ - rejecting legacy quoted EDN symbols on load,
20
+ - rejecting `''T` on schema writes.
21
+
22
+ - `build.rs`
23
+ - Added the same legacy-generic rejection during build-time loading of `src/cirru/calcit-core.cirru`, so bad schema data fails `yarn check-all` immediately.
24
+
25
+ - `src/cirru/calcit-core.cirru`
26
+ - Replaced all legacy schema generic forms like `''T`, `''A`, `''K` with correct single-quoted forms.
27
+
28
+ - `docs/CalcitAgent.md`
29
+ - Updated schema/type-annotation guidance to reflect schema-first top-level typing and correct generic syntax examples.
30
+
31
+ ## Validation
32
+
33
+ - `cargo fmt`
34
+ - `cargo test schema_ -- --nocapture`
35
+ - `yarn check-all`
@@ -0,0 +1,34 @@
1
+ # 本次修改记录
2
+
3
+ ## 主题
4
+
5
+ - 完善 schema 类型系统:区分泛型变量与命名类型引用,支持 `'Result` 一类类型引用在 schema 中稳定往返。
6
+ - 继续推进 schema-first 迁移:清理 `calcit-core` 与若干测试文件中的 `assert-type`,将约束收敛到 `:schema` 与局部 `hint-fn`。
7
+ - 强化诊断:改进运行时参数个数错误与构建期 schema 解析报错,方便定位问题。
8
+
9
+ ## 主要改动
10
+
11
+ ### 1) Rust 侧类型系统收紧
12
+
13
+ - 在 `src/calcit/type_annotation.rs` 中新增命名类型引用分支,并让解析、匹配、显示、序列化都感知泛型作用域。
14
+ - `src/builtins/syntax.rs` 与 `src/builtins/records.rs` 改为按泛型上下文解析 schema,避免把命名类型误判成 type var。
15
+ - `src/codegen/gen_ir.rs`、`src/snapshot.rs` 同步适配新 schema 结构与 round-trip 测试。
16
+
17
+ ### 2) schema / hint-fn 迁移
18
+
19
+ - `src/cirru/calcit-core.cirru` 中移除剩余 `assert-type` 调用点,改为顶层 `:schema` 或局部 `hint-fn`。
20
+ - `calcit/test.cirru`、`calcit/debug/check-args.cirru`、`calcit/test-fn.cirru`、`calcit/test-types.cirru` 改用更精细的函数签名与局部约束。
21
+ - 修正函数类型直写 schema 的参数形式,统一使用 `([] ...)` 表达参数列表。
22
+
23
+ ### 3) 错误信息增强
24
+
25
+ - `src/runner.rs` 在参数个数不匹配时生成结构化报错,而不是直接触发内部 panic。
26
+ - `build.rs` 对 schema EDN 解析错误增加截断与整理,避免输出过长、难以定位。
27
+
28
+ ## 验证
29
+
30
+ - `cargo fmt` 通过。
31
+ - `cargo clippy -- -D warnings` 通过。
32
+ - `yarn compile` 通过。
33
+ - `cargo test` 通过。
34
+ - `yarn check-all` 通过。
@@ -0,0 +1,45 @@
1
+ # 2026-03-08 schema wrapper migration
2
+
3
+ ## Summary
4
+
5
+ - 统一函数 schema 的 snapshot 输出格式,顶层改为 wrapped `:: :fn` / `:: :macro` 形式。
6
+ - 修复 schema round-trip 中的类型信息丢失,确保嵌套函数类型与 `:rest` 在格式化后保持稳定。
7
+ - 将 macro schema 的顶层格式统一迁移到 `:: :macro`,并让 formatter 在处理 `defmacro` 条目时自动纠正旧的 `fn` 标记。
8
+ - 移除 legacy quote-wrapped schema normalization 与 legacy positional `fn` type annotation fallback,收紧到当前 schema-map 形式。
9
+ - 更新 `deftrait` 文档与相关说明,避免继续传播旧写法。
10
+
11
+ ## Main changes
12
+
13
+ ### 1) 顶层 schema 输出统一
14
+
15
+ - 在 `src/calcit/type_annotation.rs` 中补充顶层 wrapped schema 的解析与序列化逻辑。
16
+ - 在 `src/snapshot.rs` 中让 `CodeEntry.schema` 写回 snapshot 时统一输出为 `:schema $ :: :fn ...` 或 `:schema $ :: :macro ...`。
17
+ - 对 plain fn schema 去掉 wrapped payload 内冗余的 `:kind :fn`,但保留宏函数所需的 `:kind :macro`。
18
+
19
+ ### 2) macro schema 迁移与规范化
20
+
21
+ - 扩展 parser / normalize 逻辑,使其同时接受 wrapped `fn` 与 wrapped `macro`。
22
+ - 对 macro schema,序列化时省略冗余的 `:kind :macro` 与 `:return`,仅保留 `:args` 与可选 `:rest`。
23
+ - 在 snapshot 读写路径中,根据代码头是否为 `defmacro` 自动纠正 schema kind。
24
+
25
+ ### 3) legacy fn syntax 收紧
26
+
27
+ - 移除 legacy quote-wrapped schema normalization。
28
+ - 拒绝 legacy quoted generic symbols。
29
+ - 移除 legacy positional `fn` type annotation parsing fallback。
30
+ - 迁移剩余 core trait 与测试注解到 schema-map `:: :fn {}` 形式。
31
+
32
+ ### 4) round-trip 与批量格式化
33
+
34
+ - 修复 EDN 到 Calcit 的转换路径,补上 `Edn::Map` 的处理,避免嵌套 `fn` schema 的 hashmap payload 被吞掉后退化成 `:dynamic`。
35
+ - 调整 schema 校验与 normalize 逻辑,使 wrapped 顶层 fn schema 与旧格式都能稳定读写。
36
+ - 重新格式化了 `src/cirru/calcit-core.cirru`、`calcit/util.cirru`、`calcit/test-hygienic.cirru` 等兼容 snapshot 文件。
37
+
38
+ ## Validation
39
+
40
+ - `cargo fmt`
41
+ - `cargo clippy -- -D warnings`
42
+ - `yarn compile`
43
+ - `cargo test -q`
44
+ - `cargo build -q`
45
+ - `yarn check-all`
@@ -0,0 +1,27 @@
1
+ # 2026-03-08 late schema cleanup and warning compatibility
2
+
3
+ ## Summary
4
+
5
+ - made snapshot schema loading strict for non-nil schemas, so malformed schema data no longer silently degrades to dynamic
6
+ - normalized loaded schema maps so legacy string keys and string `:kind` values are converted into canonical tag-based schema maps
7
+ - restored generic type variables in `src/cirru/calcit-core.cirru` where a previous migration had incorrectly replaced them with `:symbol`
8
+ - cleaned the remaining mistaken `:symbol` placeholders in core collection schemas, keeping only the intentional `symbol?` runtime type check
9
+ - fixed `calcit/test-generics.cirru` after a schema-formatting edit moved `assert-type id ...` into the `let` binding section
10
+ - kept `ns/def` warning location reporting for embedded core snapshot loading
11
+ - stopped legacy fn-schema warnings from firing on malformed nested `:: :fn` schema payloads parsed from `calcit-core.cirru`
12
+ - used a conservative fallback to `DynFn` for malformed nested payloads, avoiding false-positive callback type warnings without re-editing Cirru syntax
13
+
14
+ ## Notes
15
+
16
+ - `yarn check-all` passed after the generic-schema restoration and remaining `:symbol` cleanup passes
17
+ - the `test-generics` fix resolves the runtime error `expected binding of a pair`
18
+ - nested function schema payloads coming from Cirru snapshot EDN may currently collapse into malformed map payloads like `(:: :fn ({} (nil ...)))` or `(:: :fn ({}))`
19
+ - those malformed payloads are lossy, so partially reconstructing arg/return types can introduce new static-analysis warnings
20
+ - decoding the embedded binary core snapshot with per-entry owners is necessary to preserve precise warning locations such as `calcit.core/foo`
21
+
22
+ ## Validation
23
+
24
+ - `cargo test -q malformed_nested_fn_schema`
25
+ - `cargo build -q`
26
+ - `target/debug/cr calcit/test.cirru -1`
27
+ - `yarn check-all`
package/lib/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.11.8",
3
+ "version": "0.12.0",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.0.9",
7
7
  "typescript": "^5.9.3"
8
8
  },
9
9
  "scripts": {
10
- "compile": "rm -rfv lib/* && tsc",
10
+ "compile": "rm -rf lib && tsc",
11
11
  "procs-link": "ln -sfn ../../ node_modules/@calcit/procs",
12
12
  "cp-mac": "cargo build --release && rm -rfv builds/* && node scripts/cp-version.js && scp builds/* rsync-user@calcit-lang.org:/web-assets/repo/calcit-lang/binaries/macos/",
13
13
  "eval": "cargo run --bin cr -- eval",
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.11.8",
3
+ "version": "0.12.0",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.0.9",
7
7
  "typescript": "^5.9.3"
8
8
  },
9
9
  "scripts": {
10
- "compile": "rm -rfv lib/* && tsc",
10
+ "compile": "rm -rf lib && tsc",
11
11
  "procs-link": "ln -sfn ../../ node_modules/@calcit/procs",
12
12
  "cp-mac": "cargo build --release && rm -rfv builds/* && node scripts/cp-version.js && scp builds/* rsync-user@calcit-lang.org:/web-assets/repo/calcit-lang/binaries/macos/",
13
13
  "eval": "cargo run --bin cr -- eval",