Skip to content

more milestone work#3

Merged
xen0n merged 21 commits intomainfrom
sync/roadmap-update
Mar 11, 2026
Merged

more milestone work#3
xen0n merged 21 commits intomainfrom
sync/roadmap-update

Conversation

@xen0n
Copy link
Contributor

@xen0n xen0n commented Mar 10, 2026

This PR adds three new language supports to liyi tree_path:

Changes

M7.2 Bash ✅

  • tree-sitter-bash v0.25.1
  • Simple function_definition nodes
  • Extensions: .sh, .bash

M7.1 Ruby ✅

  • tree-sitter-ruby v0.23.1
  • Methods, classes, modules, singleton methods
  • Custom name extraction for singleton methods (def self.foo)
  • Extensions: .rb, .rake, .gemspec

M7.4 Zig ✅

  • tree-sitter-zig v1.1.2
  • Functions, struct-as-namespace pattern, tests
  • Custom name extraction for struct declarations (const Name = struct { ... })
  • Handles Zig-specific patterns like test name { ... }
  • Extension: .zig

Test Results

All 168 unit tests pass, plus 20 golden tests and 4 property tests.

Roadmap Impact

This implements M7.1, M7.2, and M7.4 from the 0.1.x roadmap. M7.3 Dart is the remaining language in M7.

@xen0n xen0n marked this pull request as ready for review March 11, 2026 05:34
@xen0n xen0n force-pushed the sync/roadmap-update branch 8 times, most recently from 48ba5b3 to 825d0b3 Compare March 11, 2026 17:40
xen0n added 21 commits March 12, 2026 01:54
Add tree-sitter-bash grammar (v0.25.1) and LanguageConfig for Bash.
Bash has simple function_definition nodes with no nesting complexity.

- Extensions: .sh, .bash
- Kind: fn -> function_definition
- No custom name extraction needed
- body_fields: ["body"]

Original prompt:

> Implement bash, ruby, and zig, one by one, then push to the currently empty PR.

AI-assisted-by: Kimi K2.5 (OpenClaw)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Add tree-sitter-ruby grammar (v0.23.1) and LanguageConfig for Ruby.

- Extensions: .rb, .rake, .gemspec
- Kinds: fn -> method, class -> class, module -> module,
  singleton_method -> singleton_method
- Custom name extraction for singleton methods (def self.foo)
  to encode receiver type: "self.method_name" or "ClassName.method_name"
- body_fields: ["body", "statements"]

Original prompt:

> Implement bash, ruby, and zig, one by one, then push to the currently empty PR.

AI-assisted-by: Kimi K2.5 (OpenClaw)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Add tree-sitter-zig grammar (v1.1.2) and LanguageConfig for Zig.

- Extension: .zig
- Kinds:
  - fn -> function_declaration
  - struct -> variable_declaration (for const Name = struct { ... })
  - test -> test_declaration
- Custom name extraction:
  - function_declaration: finds identifier child node
  - variable_declaration: detects const + struct_declaration pattern,
    extracts identifier for struct-as-namespace
  - test_declaration: extracts string literal content
- body_fields: ["block", "struct_declaration"]
  (struct_declaration contains struct body for method lookup)

Original prompt:

> Implement bash, ruby, and zig, one by one, then push to the currently empty PR.

AI-assisted-by: Kimi K2.5 (OpenClaw)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Add nom parser combinator library for implementing the formal
tree_path grammar specification (v0.2).

This enables unambiguous parsing of names containing spaces,
:: delimiters, or special characters.

Original prompt:

> You seem to have added support for Zig test cases which made spaces
> inside tree paths possible. I suggest parsing the tree path with nom
> so we can have unambiguous string escaping. What's your opinion?

AI-assisted-by: Kimi K2.5 (OpenClaw)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Implement formal tree_path parser using nom 8 with support for:

- Simple identifiers: fn::add, class::MyClass
- Quoted strings for names with spaces: test::"add function"
- Escaped quotes and backslashes: test::"with \"quote\""
- Names containing :: delimiters: fn::"foo::bar"
- Injection marker syntax (M9 prep): //bash

The parser uses heuristics to distinguish Kind vs Name segments
(common kind list: fn, class, struct, enum, trait, impl, mod,
const, type, test, namespace, interface, protocol).

Includes full roundtrip property tests and serialization that
automatically quotes names when needed.

Original prompt:

> You seem to have added support for Zig test cases which made spaces
> inside tree paths possible. I suggest parsing the tree path with nom
> so we can have unambiguous string escaping. What's your opinion?

AI-assisted-by: Kimi K2.5 (OpenClaw)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Mark M7.1 Ruby, M7.2 Bash, and M7.4 Zig as complete.

Add Appendix A: tree_path Grammar Specification (v0.2) documenting
the formal grammar for unambiguous tree_path parsing using nom.

Key design decisions:
- Quoted strings for names containing spaces, ::, or special chars
- Backslash escaping inside quoted strings
- Unquoted shorthand for simple identifiers (backward compatible)
- Extension point for M9 injection syntax (//lang)

Original prompt:

> Implement bash, ruby, and zig, one by one, then push to the currently empty PR.

AI-assisted-by: Kimi K2.5 (OpenClaw)
Signed-off-by: WANG Xuerui <git@xen0n.name>
- Use inline format strings for cleaner code
- Rename to_string to serialize to avoid conflict with Display trait
- Apply cargo fmt to all modified files

AI-assisted-by: Kimi K2.5 (OpenClaw)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Move Ruby, Bash, and Zig from "Planned" to "Built-in" in the design
doc language table. Update Appendix A status from "Design" to
"Partial" and mark parser.rs implementation step as done.

Original prompt:

> I have updated the Rust toolchain, please re-check, and fix any
> inconsistencies you have surfaced and commit.

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
The design doc (M9) specifies that injection markers attach directly
to the preceding name (e.g., run//bash), not as a separate ::
delimited segment (run:://bash). Fix the parser to accept both
forms and the serializer to always emit the canonical appended form.
Update Appendix A.3 grammar to match.

Original prompt:

> Currently the tree_path injection syntax seems implemented as
> key:foo:://bash::fn::bar, a superfluous :: is before //.
> Please confirm and fix it.

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Add quoting example (Zig test name) and injection example (YAML+Bash)
to the tree_path format table. Add a short paragraph explaining
quoted names and //lang injection markers, with a forward-reference
to the roadmap appendix for the full grammar.

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
The previous reanchor computed wrong SHA-256 hashes and assigned
nonsensical anchor lines because Markdown lacks tree-sitter semantic
support, causing the span-shift heuristic to mismatch content after
a 4-line insertion. Manually recomputed all 17 requirement specs
with correct source_span, source_hash, and source_anchor values.

liyi check now reports 134 current, 0 stale.

Original prompt:

> Please fix design doc sidecar -- the reanchor did not account for
> the shifted span due to missing semantic support for Markdown,
> and calculated wrong SHA-256 hashes and several anchor lines are
> now meaningless.

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Add @liyi:end-requirement marker to pair with @liyi:requirement for
deterministic span recovery in files without tree-sitter support.

- Add EndRequirement { name, line } variant to SourceMarker enum
- Add CANON_END_REQUIREMENT constant and 6 multilingual aliases
  (Chinese 需求结束, Spanish, Japanese, French, Korean)
- Order end-requirement aliases before requirement aliases in
  ALIAS_TABLE to prevent prefix-matching collisions
- Add scan_markers match arm for CANON_END_REQUIREMENT
- Add requirement_spans() function to pair open/close markers by
  name into [start, end] span maps
- Add 5 scanner tests for end-requirement parsing and pairing

Original prompt:

> Based on your own dogfooding experience in this session, what's
> your opinion on Markdown semantic anchoring support?
>
> Agreed that we should allow deterministically tracking requirement
> blocks. We may need to define the end-of-block marker more
> "officially" than the current ad-hoc convention, such as
> @liyi:end-requirement, then make the reanchor tool recognize that.
>
> Sure, please do, but for Chinese please make it "需求结束" or
> "需求完" -- let me know your preference before going ahead.
>
> Fair point, let's go with "需求结束". Please go ahead with
> implementation.

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Use requirement_spans() from the scanner to recover deterministic
spans for @liyi:requirement blocks in check.rs and reanchor.rs.

check.rs:
- Import requirement_spans, compute marker_span_map after scanning
- In Requirement branch, apply marker-pair span before hash
  computation so marker-bounded blocks stay current automatically

reanchor.rs:
- Import requirement_spans and scan_markers
- For files without tree-sitter support, build marker_spans map
- Use marker-pair span as fallback after tree-sitter resolution
  in Requirement branch

This is the primary span recovery mechanism for Markdown and other
files where tree-sitter grammars are unavailable.

Original prompt:

> Based on your own dogfooding experience in this session, what's
> your opinion on Markdown semantic anchoring support?
>
> Agreed that we should allow deterministically tracking requirement
> blocks. We may need to define the end-of-block marker more
> "officially" than the current ad-hoc convention, such as
> @liyi:end-requirement, then make the reanchor tool recognize that.
>
> Sure, please do, but for Chinese please make it "需求结束" or
> "需求完" -- let me know your preference before going ahead.
>
> Fair point, let's go with "需求结束". Please go ahead with
> implementation.

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Update the design document to formally specify @liyi:end-requirement
as the closing marker for requirement blocks, replacing the previous
"not supported in 0.1" statement.

Spec additions:
- Full alias table (English, Chinese, Spanish, Japanese, French,
  Korean) matching the scanner implementation
- Recommendation for Markdown requirement blocks
- Code example showing paired open/close markers

Marker migration:
- Replace all 17 <!-- /requirement --> ad-hoc closing markers with
  <!-- @liyi:end-requirement <name> --> using the corresponding
  requirement name from each block's opening marker
- Reanchor sidecar to reflect updated spans and hashes

Original prompt:

> Based on your own dogfooding experience in this session, what's
> your opinion on Markdown semantic anchoring support?
>
> Agreed that we should allow deterministically tracking requirement
> blocks. We may need to define the end-of-block marker more
> "officially" than the current ad-hoc convention, such as
> @liyi:end-requirement, then make the reanchor tool recognize that.
>
> Sure, please do, but for Chinese please make it "需求结束" or
> "需求完" -- let me know your preference before going ahead.
>
> Fair point, let's go with "需求结束". Please go ahead with
> implementation.

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Signed-off-by: WANG Xuerui <git@xen0n.name>
When check --fix updates a span (via tree-sitter recovery, shift
heuristic, or filling a missing hash), also compute and update
the tree_path field from the new span. This makes check --fix
feature-complete with reanchor for tree_path maintenance.

Previously only liyi reanchor refreshed tree_path; now the standard
lint-and-fix workflow does it too, removing one reason to need a
separate reanchor subcommand.

Original prompt:

> Let's do that now, I haven't released v0.1.0 yet exactly because
> I don't feel the dogfooding experience to be smooth and pleasant
> enough. Everything can still be changed. Let's revise the docs
> and just drop "reanchor".

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Move resolve_reanchor_targets from reanchor.rs to discovery.rs as
resolve_sidecar_targets. The function resolves file/directory paths
into concrete .liyi.jsonc paths — this is sidecar discovery, not
reanchor-specific logic.

- Add resolve_sidecar_targets to discovery.rs
- Update approve.rs to import from discovery
- Keep backward-compatible alias in reanchor.rs (will be removed
  when the reanchor subcommand is dropped)

Original prompt:

> Let's do that now, I haven't released v0.1.0 yet exactly because
> I don't feel the dogfooding experience to be smooth and pleasant
> enough. Everything can still be changed. Let's revise the docs
> and just drop "reanchor".

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Drop the `liyi reanchor` subcommand. Its unique capabilities are now
covered by `liyi check --fix` (tree_path computation, span recovery)
or the new `liyi migrate` subcommand (schema version migration).

CLI changes:
- Remove Reanchor variant from Commands enum
- Add Migrate subcommand (takes files/dirs, runs schema migration)
- Remove parse_span helper (no longer needed)
- Update main.rs dispatch to use discovery::resolve_sidecar_targets

Diagnostic changes:
- Replace all "liyi reanchor <file>" fix_hints with
  "liyi check --fix" or "liyi migrate <file>" as appropriate

Original prompt:

> Let's do that now, I haven't released v0.1.0 yet exactly because
> I don't feel the dogfooding experience to be smooth and pleasant
> enough. Everything can still be changed. Let's revise the docs
> and just drop "reanchor".

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
The reanchor CLI subcommand was removed in prior commits. This
updates all documentation, schemas, AGENTS.md, READMEs, source
comments, and sidecar files to reflect the new terminology:

- "liyi reanchor" → "liyi check --fix" throughout
- "liyi reanchor --migrate" → "liyi migrate"
- Rename requirement tree-path-reanchor-behavior →
  tree-path-fix-behavior
- Rename triage action auto-reanchor → auto-fix
- Remove deleted parse_span from cli.rs sidecar
- Update intent text for affected sidecars
- Clear and recompute stale hashes via check --fix

Original prompt:

> Let's revise the docs and just drop 'reanchor'. Remember to
> commit logical changes frequently.

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Replace HashMap with BTreeMap for the `related` field in
ItemSpec so that `check --fix` and `write_sidecar` produce
stable, alphabetically sorted key order.

Original prompt:

> please make `check --fix` related edge output order
> deterministic

AI-assisted-by: Claude Opus 4.6 (GitHub Copilot)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Signed-off-by: WANG Xuerui <git@xen0n.name>
@xen0n xen0n force-pushed the sync/roadmap-update branch from 825d0b3 to cff9698 Compare March 11, 2026 17:55
@xen0n xen0n changed the title docs(roadmap): sync liyi-01x-roadmap.md with repo state more milestone work Mar 11, 2026
@xen0n xen0n merged commit cff9698 into main Mar 11, 2026
4 checks passed
@xen0n xen0n deleted the sync/roadmap-update branch March 11, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant