Add 5 MCP tools, refactor nav-data, fix deep path bug, fix Playwright failures
Nav refactoring: - Split nav-data.sx (32 forms) into 6 files: nav-geography, nav-language, nav-applications, nav-etc, nav-tools, nav-tree - Add Tools top-level nav category with SX Tools and Services pages - New services-tools.sx page documenting the rose-ash-services MCP server JS build fixes (fixes 5 Playwright failures): - Wire web/web-signals.sx into JS build (stores, events, resources) - Add cek-try primitive to JS platform (island hydration error handling) - Merge PRIMITIVES into getRenderEnv (island env was missing primitives) - Rename web/signals.sx → web/web-signals.sx to avoid spec/ collision New MCP tools: - sx_trace: step-through CEK evaluation showing lookups, calls, returns - sx_deps: dependency analysis — free symbols + cross-file resolution - sx_build_manifest: show build contents for JS and OCaml targets - sx_harness_eval extended: multi-file loading + setup expressions Deep path bug fix: - Native OCaml list-replace and navigate bypass CEK callback chain - Fixes sx_replace_node and sx_read_subtree corruption on paths 6+ deep Tests: 1478/1478 JS full suite, 91/91 Playwright Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -672,4 +672,81 @@
|
||||
(assert (not (nil? (get result "ok"))))
|
||||
(let ((found (find-all (get result "ok") "second")))
|
||||
(assert (>= (len found) 1))))))
|
||||
)
|
||||
|
||||
(deftest "replace-node 6-level deep preserves full tree"
|
||||
(let ((tree (sx-parse "(outer (a (b (c (d (e x y z) f g h i j k l) m n) o p) q r) s t)")))
|
||||
(let ((result (replace-node tree (list 0 1 1 1 1 1 1) "replaced")))
|
||||
(assert (not (nil? (get result "ok"))))
|
||||
(let ((new-tree (get result "ok")))
|
||||
(assert-equal "replaced" (symbol-name (navigate new-tree (list 0 1 1 1 1 1 1))))
|
||||
(assert-equal 1 (len new-tree))
|
||||
(let ((d-node (navigate new-tree (list 0 1 1 1 1))))
|
||||
(assert-equal 9 (len d-node)))
|
||||
(assert-equal "s" (symbol-name (navigate new-tree (list 0 2))))))))
|
||||
|
||||
|
||||
(deftest "collect-free-symbols: let binds exclude variables"
|
||||
(let ((tree (sx-parse "(let ((x 10)) (+ x y))")))
|
||||
(let ((syms (collect-free-symbols (first tree))))
|
||||
(assert (contains? syms "+"))
|
||||
(assert (contains? syms "y"))
|
||||
(assert (not (contains? syms "x"))))))
|
||||
|
||||
(deftest "collect-free-symbols: fn params excluded"
|
||||
(let ((tree (sx-parse "(fn (a b) (+ a b c))")))
|
||||
(let ((syms (collect-free-symbols (first tree))))
|
||||
(assert (contains? syms "+"))
|
||||
(assert (contains? syms "c"))
|
||||
(assert (not (contains? syms "a")))
|
||||
(assert (not (contains? syms "b"))))))
|
||||
|
||||
(deftest "collect-free-symbols: define name excluded"
|
||||
(let ((tree (sx-parse "(define foo (+ bar 1))")))
|
||||
(let ((syms (collect-free-symbols (first tree))))
|
||||
(assert (contains? syms "+"))
|
||||
(assert (contains? syms "bar"))
|
||||
(assert (not (contains? syms "foo"))))))
|
||||
|
||||
(deftest "collect-free-symbols: letrec bindings visible in body"
|
||||
(let ((tree (sx-parse "(letrec ((f (fn (x) (g x))) (g (fn (y) y))) (f 1))")))
|
||||
(let ((syms (collect-free-symbols (first tree))))
|
||||
(assert (not (contains? syms "f")))
|
||||
(assert (not (contains? syms "g")))
|
||||
(assert (not (contains? syms "x")))
|
||||
(assert (not (contains? syms "y"))))))
|
||||
|
||||
(deftest "collect-free-symbols: quote skipped"
|
||||
(let ((tree (sx-parse "(quote (foo bar baz))")))
|
||||
(let ((syms (collect-free-symbols (first tree))))
|
||||
(assert (empty? syms)))))
|
||||
|
||||
(deftest "collect-free-symbols: special forms not reported"
|
||||
(let ((tree (sx-parse "(if (> x 0) (+ x 1) 0)")))
|
||||
(let ((syms (collect-free-symbols (first tree))))
|
||||
(assert (not (contains? syms "if")))
|
||||
(assert (contains? syms ">"))
|
||||
(assert (contains? syms "x"))
|
||||
(assert (contains? syms "+")))))
|
||||
|
||||
(deftest "collect-free-symbols: defcomp params excluded"
|
||||
(let ((tree (sx-parse "(defcomp ~card (&key title) (div title))")))
|
||||
(let ((syms (collect-free-symbols (first tree))))
|
||||
(assert (contains? syms "div"))
|
||||
(assert (not (contains? syms "title"))))))
|
||||
|
||||
(deftest "native list-replace works at all positions"
|
||||
(assert-equal (list 99 2 3) (list-replace (list 1 2 3) 0 99))
|
||||
(assert-equal (list 1 99 3) (list-replace (list 1 2 3) 1 99))
|
||||
(assert-equal (list 1 2 99) (list-replace (list 1 2 3) 2 99)))
|
||||
|
||||
(deftest "native navigate deep path"
|
||||
(let ((tree (sx-parse "(a (b (c (d (e (f target))))))")))
|
||||
(let ((result (navigate tree (list 0 1 1 1 1 1 1))))
|
||||
(assert-equal "target" (symbol-name result)))))
|
||||
|
||||
(deftest "native navigate preserves structure"
|
||||
(let ((tree (sx-parse "(outer (inner x y z) sibling)")))
|
||||
(assert-equal "inner" (symbol-name (first (navigate tree (list 0 1)))))
|
||||
(assert-equal "sibling" (symbol-name (navigate tree (list 0 2))))))
|
||||
|
||||
)
|
||||
1318
lib/tree-tools.sx
1318
lib/tree-tools.sx
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user