@chrisdudek/yg 4.2.0 → 5.0.0-alpha.2

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 (46) hide show
  1. package/README.md +4 -2
  2. package/dist/ast.d.ts +51 -0
  3. package/dist/ast.js +279 -0
  4. package/dist/bin.js +17543 -6420
  5. package/dist/grammars/tree-sitter-c.node-types.json +4615 -0
  6. package/dist/grammars/tree-sitter-c.wasm +0 -0
  7. package/dist/grammars/tree-sitter-c_sharp.node-types.json +7233 -0
  8. package/dist/grammars/tree-sitter-c_sharp.wasm +0 -0
  9. package/dist/grammars/tree-sitter-cpp.node-types.json +7997 -0
  10. package/dist/grammars/tree-sitter-cpp.wasm +0 -0
  11. package/dist/grammars/tree-sitter-go.node-types.json +2995 -0
  12. package/dist/grammars/tree-sitter-go.wasm +0 -0
  13. package/dist/grammars/tree-sitter-java.node-types.json +4586 -0
  14. package/dist/grammars/tree-sitter-java.wasm +0 -0
  15. package/dist/grammars/tree-sitter-javascript.node-types.json +3622 -0
  16. package/dist/grammars/tree-sitter-javascript.wasm +0 -0
  17. package/dist/grammars/tree-sitter-json.node-types.json +183 -0
  18. package/dist/grammars/tree-sitter-json.wasm +0 -0
  19. package/dist/grammars/tree-sitter-kotlin.node-types.json +3091 -0
  20. package/dist/grammars/tree-sitter-kotlin.wasm +0 -0
  21. package/dist/grammars/tree-sitter-php_only.node-types.json +6077 -0
  22. package/dist/grammars/tree-sitter-php_only.wasm +0 -0
  23. package/dist/grammars/tree-sitter-python.node-types.json +3746 -0
  24. package/dist/grammars/tree-sitter-python.wasm +0 -0
  25. package/dist/grammars/tree-sitter-ruby.node-types.json +4108 -0
  26. package/dist/grammars/tree-sitter-ruby.wasm +0 -0
  27. package/dist/grammars/tree-sitter-rust.node-types.json +5554 -0
  28. package/dist/grammars/tree-sitter-rust.wasm +0 -0
  29. package/dist/grammars/tree-sitter-toml.node-types.json +356 -0
  30. package/dist/grammars/tree-sitter-toml.wasm +0 -0
  31. package/dist/grammars/tree-sitter-tsx.node-types.json +6288 -0
  32. package/dist/grammars/tree-sitter-tsx.wasm +0 -0
  33. package/dist/grammars/tree-sitter-typescript.node-types.json +6038 -0
  34. package/dist/grammars/tree-sitter-typescript.wasm +0 -0
  35. package/dist/grammars/tree-sitter-yaml.node-types.json +552 -0
  36. package/dist/grammars/tree-sitter-yaml.wasm +0 -0
  37. package/dist/loader-hook-impl.d.ts +9 -0
  38. package/dist/loader-hook-impl.js +16 -0
  39. package/dist/structure.d.ts +414 -0
  40. package/dist/structure.js +1261 -0
  41. package/graph-schemas/yg-architecture.yaml +39 -6
  42. package/graph-schemas/yg-aspect.yaml +88 -3
  43. package/graph-schemas/yg-config.yaml +28 -12
  44. package/graph-schemas/yg-flow.yaml +5 -3
  45. package/graph-schemas/yg-node.yaml +19 -5
  46. package/package.json +56 -19
@@ -9,16 +9,49 @@
9
9
 
10
10
  node_types:
11
11
  <type-id>:
12
- description: <string> # required — what this type is for, when to use it
12
+ description: <string> # required — what this type is for, when to use it.
13
+ # Validator emits description-missing if absent.
14
+
15
+ when: <file-predicate> # optional — per-file classification.
16
+ # Types WITH `when` are file-classifying: every file in
17
+ # a node's mapping must satisfy the predicate (forward
18
+ # check). Types WITHOUT `when` are organizational:
19
+ # parent-only nodes — any mapping fires
20
+ # type-without-when-with-mapping.
21
+ #
22
+ # Grammar:
23
+ # path: <glob> — minimatch glob on repo-relative POSIX path
24
+ # content: <regex> — JavaScript regex against file content
25
+ # path + content combined — implicit all_of of both atoms
26
+ # all_of: [<predicate>, ...] — every child must satisfy
27
+ # any_of: [<predicate>, ...] — at least one child must satisfy
28
+ # not: <predicate> — single child negation
29
+ #
30
+ # See: yg knowledge read working-with-architecture
31
+
32
+ enforce: strict # optional — bidirectional enforcement.
33
+ # Requires `when`. Every repo file matching the type's
34
+ # `when` MUST belong to exactly one node of this type
35
+ # (backward scan). A matching file owned by no such node
36
+ # emits type-strict-orphan; one owned by a node of a
37
+ # different type emits type-strict-misplaced.
38
+ # Use only for types where missing the type means missing
39
+ # a critical aspect (security, audit, regulatory).
40
+
41
+ log_required: <boolean> # optional — default true. Set false for infrastructure
42
+ # or utility types where an approval log adds no value
43
+ # (e.g. config, types, constants).
13
44
 
14
45
  aspects: # optional — aspects automatically applied to every
15
46
  # node of this type (channel 3). Two forms per entry:
16
- - simple-aspect # bare string — unconditional
17
- - id: conditional-aspect # object form — with per-site applicability filter
18
- when: <predicate> # see graph-schemas/yg-aspect.yaml for grammar
47
+ - <aspect-id> # bare string — unconditional
48
+ - id: <aspect-id> # object form — with per-site applicability filter
49
+ status: enforced # optional explicit status override (channel 3).
50
+ # Must satisfy bump rule (bump up OK, downgrade is validator error).
51
+ when: <aspect-predicate> # optional — see schemas/yg-aspect.yaml for grammar
19
52
  # These also cascade to children (channel 4).
20
53
 
21
- parents: [<type-id>] # optional — allowed parent node types in the hierarchy.
54
+ parents: [<type-id>, ...] # optional — allowed parent node types in the hierarchy.
22
55
 
23
56
  relations: # optional — allowed relation targets by relation type.
24
- <relation-type>: [<type-id>] # calls | uses | extends | implements | emits | listens
57
+ <relation-type>: [<type-id>, ...] # calls | uses | extends | implements | emits | listens
@@ -1,6 +1,7 @@
1
1
  # yg-aspect.yaml — Schema for cross-cutting aspects
2
2
  # Each aspect is a directory under .yggdrasil/aspects/ containing this file
3
- # plus any number of .md content files.
3
+ # plus any number of .md content files (for LLM aspects) or a check.mjs
4
+ # (for deterministic aspects).
4
5
  #
5
6
  # Aspect identifier = relative path from aspects/ to the directory
6
7
  # (e.g. observability/logging). Aspects can be organized in nested
@@ -11,14 +12,75 @@
11
12
  # They should state WHAT must be satisfied and WHY.
12
13
 
13
14
  name: CrossCuttingRequirementName # required — display name
14
- description: "Short description" # optional but recommended — shown in yg aspects output
15
- # and context packages, helps agents discover relevant aspects
15
+ description: "Short description" # required — shown in yg aspects output and context packages.
16
+ # Validator emits description-missing if absent.
17
+
18
+ # reviewer: # OPTIONAL — reviewer kind is inferred from rule-file presence:
19
+ #
20
+ # content.md present → llm
21
+ # check.mjs present → deterministic
22
+ # neither + implies declared → aggregate
23
+ #
24
+ # The reviewer: block is only required when you need to declare
25
+ # reviewer.tier: for an LLM aspect. When present, an explicit
26
+ # reviewer.type must agree with the inferred kind (validator
27
+ # error otherwise).
28
+ #
29
+ # Three kinds:
30
+ # llm — aspect ships content.md; an LLM reads it and
31
+ # judges the code against the rule.
32
+ # deterministic — aspect ships check.mjs; the runner executes it
33
+ # locally with graph-aware ctx (files, fs, graph,
34
+ # parsers). Language-agnostic. No LLM call, zero
35
+ # token cost.
36
+ # aggregate — aspect ships neither rule source but declares
37
+ # implies:. A named bundle — expands its implied
38
+ # aspects onto every node where effective. Has no
39
+ # own reviewer and produces no own verdict. An
40
+ # aspect with neither rule source and no implies:
41
+ # is rejected (aspect-empty).
42
+ # type: llm # optional; must be 'llm', 'deterministic', or 'aggregate' if set.
43
+ # tier: deep # optional, only when type: llm (or inferred llm).
44
+ # If omitted, the aspect uses reviewer.default from yg-config.yaml.
45
+ # If present, must reference a key under reviewer.tiers in the config.
46
+ # Forbidden when type is 'deterministic' or 'aggregate'.
47
+
48
+ status: enforced # optional — aspect-level default. enum: draft | advisory | enforced.
49
+ # Absent → 'enforced'.
50
+ # draft = reviewer skipped, no verdict, no baseline, no drift.
51
+ # advisory = reviewer runs; refused → warning (no block).
52
+ # enforced = reviewer runs; refused → error (blocks check).
53
+ # This is only the aspect-level default. The effective status on a
54
+ # node is max() across cascading channels 1–6; channel 7 (implies)
55
+ # carries status_inherit instead. Downgrade attempts are validator
56
+ # errors. Advisory and enforced verdicts are recorded in the
57
+ # baseline; draft aspects get no verdict.
16
58
 
17
59
  # implies: # optional — other aspects included automatically when this
18
60
  # # aspect is effective on a node. Two forms:
19
61
  # - simple-aspect-id # bare string — implied unconditionally (when outer aspect passes)
20
62
  # - id: conditional-aspect-id # object form — imply only when `when` passes on the node
21
63
  # when: <predicate> # see `when` section below for grammar
64
+ # status_inherit: strictest # optional — propagation modifier for this implies edge.
65
+ # enum: strictest | own-default.
66
+ # Absent → 'strictest' (implied aspect promotes to
67
+ # the implier's effective status if higher than the
68
+ # implied aspect's own default).
69
+ # 'own-default' anchors the implied aspect to its
70
+ # own aspect-level default (decouples from implier).
71
+ #
72
+ # ASYMMETRY NOTE: attach-site entries on channels
73
+ # 1–6 (node, ancestor, architecture type, ancestor
74
+ # type, flow, port) carry an explicit `status:`
75
+ # VALUE. Channel 7 (implies) carries a propagation
76
+ # MODIFIER (`status_inherit:`) instead. Implies is
77
+ # not a direct attach — the implied aspect's status
78
+ # is structurally derived from the implier's
79
+ # effective status on the node. The modifier
80
+ # selects how to derive; a value-overriding
81
+ # `status:` on an implies edge would couple the
82
+ # edge to a literal that becomes stale if the
83
+ # implied aspect's own default changes.
22
84
  # Chains expand recursively. Cycles are forbidden — CLI detects.
23
85
 
24
86
  # when: <predicate> # optional — applicability filter. If the predicate evaluates
@@ -53,3 +115,26 @@ description: "Short description" # optional but recommended — shown in yg as
53
115
  # any_of:
54
116
  # - relations: { calls: { target_type: service-client } }
55
117
  # - descendants: { relations: { calls: { target_type: service-client } } }
118
+
119
+ # references: # optional — supporting files for the LLM reviewer.
120
+ # Permitted on LLM aspects ONLY (forbidden on deterministic).
121
+ # Each entry is a string (shorthand) OR an object { path, description? }.
122
+ #
123
+ # Example:
124
+ # references:
125
+ # - docs/error-codes.md # shorthand
126
+ # - path: source/cli/src/errors/codes.ts
127
+ # description: "Catalogue of valid error codes; reviewer rejects unknown codes."
128
+ #
129
+ # Constraints (validated by `yg check`):
130
+ # - Path is repo-root-relative.
131
+ # - No '..' that escapes the repo root; no leading '/'; no Windows drive letter; no '~'.
132
+ # - File must exist at check time and resolve (after symlink follow) to a regular file.
133
+ # - No duplicates within one aspect.
134
+ #
135
+ # Drift semantics: changes to referenced files cascade to all nodes where this
136
+ # aspect is effective — same as changes to content.md. Run `yg impact --file <ref>`
137
+ # before editing a widely-referenced file.
138
+ #
139
+ # Size limits: per-tier caps via reviewer.tiers.<tier>.references.* in yg-config.yaml.
140
+ # Defaults: 64 KiB per file, 256 KiB total per aspect.
@@ -2,12 +2,12 @@
2
2
  # Located at .yggdrasil/yg-config.yaml — one per project.
3
3
  # Edit this after running yg init to describe your project.
4
4
 
5
- version: "4.0.0" # managed by CLI — do not edit manually. Tracks the CLI version
5
+ version: "5.0.0" # managed by CLI — do not edit manually. Tracks the CLI version
6
6
  # that last initialized or upgraded this config.
7
7
 
8
8
  quality: # optional — quality thresholds
9
9
  max_direct_relations: 10 # maximum outgoing relations per node (warning if above)
10
- max_mapping_source_files: 10 # maximum source files per node (warning if above, for nodes with aspects)
10
+ max_node_chars: 40000 # per-node character budget — mapped source + aspect reference files (error if above; binaries skipped; opt out per-node via sizeExempt)
11
11
 
12
12
  parallel: 1 # optional — concurrency limit for batch approve (positive integer, default: 1)
13
13
 
@@ -15,13 +15,29 @@ debug: false # optional — when true, appends all command
15
15
  # Default: false (off). Log is append-only; rotate or delete manually.
16
16
 
17
17
  reviewer: # required — aspect verification during yg approve
18
- active: ollama # required when multiple providers configured
19
- consensus: 1 # positive odd integer >= 1 (3+ for majority vote)
20
- ollama: # provider-specific config
21
- model: "qwen3.5:9b" # model ID
22
- endpoint: "http://localhost:11434" # custom endpoint
23
- temperature: 0 # reduces variability keep at 0
24
- max_tokens: auto # auto = query provider, or explicit number
25
- context_length_field: "" # ollama model_info key for context window size
26
- claude-code: # alternative provider — uses claude CLI subprocess
27
- model: haiku # haiku, sonnet, or opus
18
+ default: standard # required when more than one tier is configured; optional with exactly one tier.
19
+ # Must reference one of the keys under reviewer.tiers.
20
+ tiers: # required — named tier configurations, minimum one entry.
21
+ standard: # tier name — referenced from aspects via reviewer.tier:
22
+ provider: ollama # provider id (one of: ollama, openai, anthropic, google,
23
+ # openai-compatible, claude-code, codex, gemini-cli)
24
+ consensus: 1 # positive odd integer >= 1 (3+ for majority vote). Per-tier.
25
+ config: # provider-specific settings same fields the provider accepts.
26
+ model: "qwen3.5:9b" # model id
27
+ endpoint: "http://localhost:11434" # custom endpoint (required for ollama, openai-compatible)
28
+ temperature: 0 # reduces variability — keep at 0
29
+ max_tokens: auto # auto = query provider, or explicit positive integer
30
+ context_length_field: "" # ollama: model_info key for context window size
31
+ # timeout: 300 # Per-call timeout in SECONDS (default 300). Only CLI providers.
32
+ # references: # optional — limits on aspect reference files for aspects resolving to this tier
33
+ # max_bytes_per_file: 65536 # positive integer; default 65536 (64 KiB)
34
+ # max_total_bytes_per_aspect: 262144 # positive integer; default 262144 (256 KiB)
35
+ # Add more tiers as needed (e.g. a `deep` tier with a higher-capability model for critical aspects).
36
+ # An aspect references a non-default tier via:
37
+ #
38
+ # reviewer:
39
+ # type: llm
40
+ # tier: deep
41
+ #
42
+ # Tier names match ^[a-zA-Z][a-zA-Z0-9_-]{0,62}$ and `default` is reserved.
43
+ # API keys live in yg-secrets.yaml (api_key only) — never in this file.
@@ -9,8 +9,8 @@
9
9
  # listing a parent node covers all its children.
10
10
 
11
11
  name: EndToEndProcessName # required — display name
12
- description: "What this business process does" # optional but recommended — shown in
13
- # yg flows output and context packages
12
+ description: "What this business process does" # required — shown in yg flows output and
13
+ # context packages. Validator emits description-missing if absent.
14
14
 
15
15
  nodes: # required, non-empty — participant nodes (alias: participants)
16
16
  - orders/order-service # paths relative to model/
@@ -20,4 +20,6 @@ nodes: # required, non-empty — participant nodes (alias
20
20
  aspects: # optional — aspects propagate to all flow participants (channel 5)
21
21
  - simple-aspect # bare string
22
22
  - id: conditional-aspect # object form with per-site applicability filter
23
- when: <predicate> # see graph-schemas/yg-aspect.yaml for grammar
23
+ status: enforced # optional explicit status override (channel 5).
24
+ # Must satisfy bump rule (bump up OK, downgrade is validator error).
25
+ when: <predicate> # optional — see schemas/yg-aspect.yaml for grammar
@@ -6,14 +6,16 @@
6
6
 
7
7
  name: ComponentName # required — display name
8
8
  type: service # required — must match a type defined in yg-architecture.yaml
9
- description: "What this node does" # optional but recommended — shown in context output,
10
- # helps agents understand purpose without reading code
9
+ description: "What this node does" # required — shown in context output and helps agents
10
+ # understand purpose. Validator emits description-missing if absent.
11
11
 
12
12
  aspects: # optional — aspect identifiers applied directly to this node.
13
13
  # Two forms per entry:
14
14
  - simple-aspect # bare string — always effective once attached (channel 1)
15
15
  - id: conditional-aspect # object form — attach with per-site applicability filter
16
- when: <predicate> # see graph-schemas/yg-aspect.yaml for grammar
16
+ status: enforced # optional explicit status override (channel 1).
17
+ # Must satisfy bump rule (bump up OK, downgrade is validator error).
18
+ when: <predicate> # optional — see schemas/yg-aspect.yaml for grammar
17
19
  # Aspects cascade to all child nodes.
18
20
 
19
21
  ports: # optional — named entry points with required aspects
@@ -22,16 +24,28 @@ ports: # optional — named entry points with required as
22
24
  aspects: # required — aspects consumers must satisfy (channel 6)
23
25
  - simple-aspect # bare string form
24
26
  - id: conditional-aspect
25
- when: <predicate> # object form with per-attach applicability filter
27
+ status: enforced # optional explicit status override (channel 6).
28
+ # Must satisfy bump rule (bump up OK, downgrade is validator error).
29
+ when: <predicate> # optional — object form with per-attach applicability filter
26
30
 
27
31
  relations: # optional — outgoing dependencies to other nodes
28
32
  - target: other/module-path # required — node path relative to model/
29
33
  type: calls # required — calls | uses | extends | implements | emits | listens
30
34
  consumes: [port-name] # optional — port names consumed from target
31
- # required when target declares ports — otherwise check warns
35
+ # required when target declares ports — otherwise yg check emits a
36
+ # BLOCKING ERROR (port-missing-consumes) that fails the architecture gate.
37
+ # There is no waiver; resolve by adding consumes or removing the ports.
38
+ # Naming a target that declares no ports raises consumes-without-ports.
32
39
 
33
40
  mapping: # optional — source files and directories owned by this node
34
41
  - src/modules/component/ # directory — all files inside are owned (recursive)
35
42
  - src/modules/component.ts # file — exact match
36
43
  # paths are relative to repository root
37
44
  # each source file must have exactly one owner node
45
+
46
+ sizeExempt: # optional — opt out of the per-node character budget (quality.max_node_chars)
47
+ reason: "package-lock.json is npm-generated and cannot be split" # required — non-empty justification
48
+ # Binary files (images, fonts, archives, etc.) count 0 toward the budget
49
+ # automatically — they never need sizeExempt. Use sizeExempt ONLY for a
50
+ # large unsplittable TEXT artifact (e.g. a generated lockfile), not images.
51
+ # Normal oversized nodes must be split.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chrisdudek/yg",
3
- "version": "4.2.0",
4
- "description": "Continuous architecture enforcement for AI-assisted development. Aspects, review, enforcement.",
3
+ "version": "5.0.0-alpha.2",
4
+ "description": "Architecture rules your coding agent can't ignore. Written in Markdown, verified on every change, enforced in the agent's loop — not after on a PR. Works with Claude Code, Cursor, Copilot, Codex, Cline.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "yg": "dist/bin.js"
@@ -9,6 +9,8 @@
9
9
  "files": [
10
10
  "dist/**/*.js",
11
11
  "dist/**/*.d.ts",
12
+ "dist/**/*.wasm",
13
+ "dist/**/*.node-types.json",
12
14
  "graph-schemas/"
13
15
  ],
14
16
  "engines": {
@@ -24,17 +26,23 @@
24
26
  "lint": "eslint src/",
25
27
  "lint:fix": "eslint src/ --fix",
26
28
  "format": "prettier --write \"src/**/*.ts\"",
27
- "typecheck": "tsc --noEmit"
29
+ "typecheck": "tsc -p tsconfig.check.json"
28
30
  },
29
31
  "keywords": [
30
32
  "yggdrasil",
31
- "ai-agents",
32
33
  "architecture-enforcement",
33
- "code-review",
34
- "ai-governance",
34
+ "code-guardrails",
35
+ "agentic-guardrails",
36
+ "rule-engine",
37
+ "agents-md",
38
+ "claude-md",
39
+ "claude-code",
40
+ "ai-agents",
41
+ "coding-agents",
42
+ "ai-coding",
43
+ "ai-assisted-development",
35
44
  "cli",
36
- "developer-tools",
37
- "ai-coding"
45
+ "developer-tools"
38
46
  ],
39
47
  "author": "Krzysztof Dudek <me@chrisdudek.com>",
40
48
  "license": "MIT",
@@ -48,27 +56,56 @@
48
56
  "url": "git+https://github.com/krzysztofdudek/Yggdrasil.git",
49
57
  "directory": "source/cli"
50
58
  },
59
+ "exports": {
60
+ "./ast": {
61
+ "import": "./dist/ast.js",
62
+ "types": "./dist/ast.d.ts"
63
+ },
64
+ "./structure": {
65
+ "import": "./dist/structure.js",
66
+ "types": "./dist/structure.d.ts"
67
+ }
68
+ },
51
69
  "publishConfig": {
52
70
  "access": "public"
53
71
  },
54
72
  "dependencies": {
55
- "@clack/prompts": "^1.2.0",
73
+ "@clack/prompts": "^1.5.0",
56
74
  "chalk": "^5.6.2",
57
- "commander": "^14.0.3",
75
+ "commander": "^15.0.0",
58
76
  "ignore": "^7.0.5",
59
- "semver": "^7.7.4",
60
- "yaml": "^2.8.2"
77
+ "minimatch": "^10.2.5",
78
+ "minisearch": "^7.2.0",
79
+ "semver": "^7.8.1",
80
+ "smol-toml": "^1.6.1",
81
+ "web-tree-sitter": "^0.26.9",
82
+ "yaml": "^2.9.0"
61
83
  },
62
84
  "devDependencies": {
63
85
  "@eslint/js": "^10.0.1",
64
- "@types/node": "^25.3.0",
86
+ "@tree-sitter-grammars/tree-sitter-kotlin": "^1.1.0",
87
+ "@tree-sitter-grammars/tree-sitter-toml": "^0.7.0",
88
+ "@tree-sitter-grammars/tree-sitter-yaml": "^0.7.1",
89
+ "@types/node": "^25.9.1",
65
90
  "@types/semver": "^7.7.1",
66
- "@vitest/coverage-v8": "^4.0.18",
67
- "eslint": "^10.0.1",
68
- "prettier": "^3.8.1",
91
+ "@vitest/coverage-v8": "^4.1.8",
92
+ "eslint": "^10.4.1",
93
+ "prettier": "^3.8.3",
94
+ "tree-sitter-c": "^0.24.1",
95
+ "tree-sitter-c-sharp": "^0.23.5",
96
+ "tree-sitter-cpp": "^0.23.4",
97
+ "tree-sitter-go": "^0.25.0",
98
+ "tree-sitter-java": "^0.23.5",
99
+ "tree-sitter-javascript": "^0.25.0",
100
+ "tree-sitter-json": "^0.24.8",
101
+ "tree-sitter-php": "^0.24.2",
102
+ "tree-sitter-python": "^0.25.0",
103
+ "tree-sitter-ruby": "^0.23.1",
104
+ "tree-sitter-rust": "^0.24.0",
105
+ "tree-sitter-typescript": "^0.23.2",
69
106
  "tsup": "^8.5.1",
70
- "typescript": "^6.0.2",
71
- "typescript-eslint": "^8.56.0",
72
- "vitest": "^4.0.18"
107
+ "typescript": "^6.0.3",
108
+ "typescript-eslint": "^8.60.0",
109
+ "vitest": "^4.1.8"
73
110
  }
74
111
  }