Compare commits

...

8 Commits

Author SHA1 Message Date
Michael Pursifull 1ac25c2a7a
feat: promote extensionless unresolved paths from silent skip to [UNRESOLVED]
Paths without file extensions that don't exist as files or directories
are now flagged as [UNRESOLVED] — a distinct tag from [BROKEN] (which
means a file with a known extension wasn't found). Both count toward
the broken reference total and appear in CI annotations.

This catches real bugs like wrong directory names in installed_path
metadata and dead invoke-workflow references to removed workflows.
Extensionless paths that DO exist as directories are still [OK-DIR].
2026-02-07 14:17:35 -06:00
Michael Pursifull 3f5d059c42
refactor: collect-then-print to eliminate confusing !VERBOSE pattern
Replace the split header-printing logic (print early in verbose mode,
print late in non-verbose mode with a !VERBOSE guard) with a simpler
collect-then-print approach. Refs are now classified into ok[] and
broken[] arrays first, then printed in a single location with one
straightforward if/else if decision.

Addresses alexeyv's review feedback about the counterintuitive
"if not verbose, log" pattern.
2026-02-07 14:09:28 -06:00
Michael Pursifull c7cdaa77cb
fix: address review feedback on CSV validator extension
- Surface CSV parse errors visibly instead of silently swallowing
  (no Layer 2c schema validator exists yet to catch these)
- Add explanatory comments for the !VERBOSE logging pattern
  (non-verbose prints file headers only when issues found)
- Add verbose-mode diagnostics for extensionless path handling
  ([SKIP] when nothing exists, [OK-DIR] for valid directories)
2026-02-07 13:59:41 -06:00
Michael Pursifull e2acf1eb3d
Merge branch 'main' into feat/csv-file-ref-validation 2026-02-07 10:56:55 -06:00
Alex Verkhovsky ecf7fbcb2c
docs: add description front matter to documentation pages (#1566) 2026-02-07 10:43:16 -06:00
Alex Verkhovsky cb73c05cf6
fix: use pull_request_target for CodeRabbit review trigger (#1583)
The workflow was failing with 403 "Resource not accessible by integration"
on fork PRs because pull_request events get read-only GITHUB_TOKEN
permissions for cross-repository PRs. Switching to pull_request_target
runs the workflow in the base repo context, granting write permissions
needed to post the @coderabbitai review comment.

This is safe because the workflow only posts a comment and does not
check out or execute any code from the PR branch.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 10:27:57 -06:00
Alex Verkhovsky 045b1fe148
chore: sync package-lock.json after archiver removal (#1580)
Removes leftover archiver dependencies from the lock file
following #1577.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 10:18:16 -06:00
Alex Verkhovsky 4c36c94c2d
chore: configure dual-mode AI code review (#1511)
Add Augment Code Review (audit mode) and CodeRabbit (adversarial mode):

Augment (.augment/code_review_guidelines.yaml):
- Workflow structure and step validation rules
- Agent definition validation
- Path placeholder enforcement
- JIT loading and HALT requirements

CodeRabbit (.coderabbit.yaml):
- Raven-style adversarial reviewer persona
- Finds logical contradictions and missing implementations
- No rule anchoring - reasons freely

Supporting changes:
- .gitignore: exclude .augment/ from ignore
- eslint.config.mjs: ignore .augment/ directory

fix: clarify .augment gitignore pattern and eslint comment

Add documentation comment to .gitignore explaining the .augment/*
exception pattern, and replace misleading eslint comment about
"underscores per their spec" with accurate description of vendor
config directory exclusion.

Addresses CodeRabbit findings F10 and F11 from PR #1511 review.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

fix: remove redundant eslint ignore patterns

The broader glob patterns (dir/**) already match all files recursively,
making the more specific sub-patterns (dir/**/*.js, dir/**/*.md, etc.)
completely redundant. Similarly, _bmad*/** already covers _bmad/**.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

fix: synchronize ignore baselines across CodeRabbit and Augment configs

Expand path exclusions in both PR review tools to a shared baseline:
- Mutual config exclusions (each tool ignores its own and others configs)
- Build output, vendored/generated files, package metadata, binary/media
- Test fixtures, non-project dirs, AI assistant dirs, build temp
- Generated reports

CodeRabbit goes from 1 exclusion to 32; Augment from 12 to 32.
ESLint already had comprehensive ignores and is unchanged.

Addresses CodeRabbit findings F2 and F4 from PR #1511 review.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

fix: correct project name in Augment review guidelines

fix: remove instruction that explicitly encourages false positives
2026-02-07 09:17:41 -06:00
16 changed files with 401 additions and 509 deletions

View File

@ -0,0 +1,271 @@
# Augment Code Review Guidelines for BMAD-METHOD
# https://docs.augmentcode.com/codereview/overview
# Focus: Workflow validation and quality
file_paths_to_ignore:
# --- Shared baseline: tool configs ---
- ".coderabbit.yaml"
- ".augment/**"
- "eslint.config.mjs"
# --- Shared baseline: build output ---
- "dist/**"
- "build/**"
- "coverage/**"
# --- Shared baseline: vendored/generated ---
- "node_modules/**"
- "**/*.min.js"
- "**/*.generated.*"
- "**/*.bundle.md"
# --- Shared baseline: package metadata ---
- "package-lock.json"
# --- Shared baseline: binary/media ---
- "*.png"
- "*.jpg"
- "*.svg"
# --- Shared baseline: test fixtures ---
- "test/fixtures/**"
- "test/template-test-generator/**"
- "tools/template-test-generator/test-scenarios/**"
# --- Shared baseline: non-project dirs ---
- "_bmad*/**"
- "website/**"
- "z*/**"
- "sample-project/**"
- "test-project-install/**"
# --- Shared baseline: AI assistant dirs ---
- ".claude/**"
- ".codex/**"
- ".agent/**"
- ".agentvibes/**"
- ".kiro/**"
- ".roo/**"
- ".github/chatmodes/**"
# --- Shared baseline: build temp ---
- ".bundler-temp/**"
# --- Shared baseline: generated reports ---
- "**/validation-report-*.md"
- "CHANGELOG.md"
areas:
# ============================================
# WORKFLOW STRUCTURE RULES
# ============================================
workflow_structure:
description: "Workflow folder organization and required components"
globs:
- "src/**/workflows/**"
rules:
- id: "workflow_entry_point_required"
description: "Every workflow folder must have workflow.yaml, workflow.md, or workflow.xml as entry point"
severity: "high"
- id: "sharded_workflow_steps_folder"
description: "Sharded workflows (using workflow.md) must have steps/ folder with numbered files (step-01-*.md, step-02-*.md)"
severity: "high"
- id: "standard_workflow_instructions"
description: "Standard workflows using workflow.yaml must include instructions.md for execution guidance"
severity: "medium"
- id: "workflow_step_limit"
description: "Workflows should have 5-10 steps maximum to prevent context loss in LLM execution"
severity: "medium"
# ============================================
# WORKFLOW ENTRY FILE RULES
# ============================================
workflow_definitions:
description: "Workflow entry files (workflow.yaml, workflow.md, workflow.xml)"
globs:
- "src/**/workflows/**/workflow.yaml"
- "src/**/workflows/**/workflow.md"
- "src/**/workflows/**/workflow.xml"
rules:
- id: "workflow_name_required"
description: "Workflow entry files must define 'name' field in frontmatter or root element"
severity: "high"
- id: "workflow_description_required"
description: "Workflow entry files must include 'description' explaining the workflow's purpose"
severity: "high"
- id: "workflow_config_source"
description: "Workflows should reference config_source for variable resolution (e.g., {project-root}/_bmad/module/config.yaml)"
severity: "medium"
- id: "workflow_installed_path"
description: "Workflows should define installed_path for relative file references within the workflow"
severity: "medium"
- id: "valid_step_references"
description: "Step file references in workflow entry must point to existing files"
severity: "high"
# ============================================
# SHARDED WORKFLOW STEP RULES
# ============================================
workflow_steps:
description: "Individual step files in sharded workflows"
globs:
- "src/**/workflows/**/steps/step-*.md"
rules:
- id: "step_goal_required"
description: "Each step must clearly state its goal (## STEP GOAL, ## YOUR TASK, or step n='X' goal='...')"
severity: "high"
- id: "step_mandatory_rules"
description: "Step files should include MANDATORY EXECUTION RULES section with universal agent behavior rules"
severity: "medium"
- id: "step_context_boundaries"
description: "Step files should define CONTEXT BOUNDARIES explaining available context and limits"
severity: "medium"
- id: "step_success_metrics"
description: "Step files should include SUCCESS METRICS section with ✅ checkmarks for validation criteria"
severity: "medium"
- id: "step_failure_modes"
description: "Step files should include FAILURE MODES section with ❌ marks for anti-patterns to avoid"
severity: "medium"
- id: "step_next_step_reference"
description: "Step files should reference the next step file path for sequential execution"
severity: "medium"
- id: "step_no_forward_loading"
description: "Steps must NOT load future step files until current step completes - just-in-time loading only"
severity: "high"
- id: "valid_file_references"
description: "File path references using {variable}/filename.md must point to existing files"
severity: "high"
- id: "step_naming"
description: "Step files must be named step-NN-description.md (e.g., step-01-init.md, step-02-context.md)"
severity: "medium"
- id: "halt_before_menu"
description: "Steps presenting user menus ([C] Continue, [a] Advanced, etc.) must HALT and wait for response"
severity: "high"
# ============================================
# XML WORKFLOW/TASK RULES
# ============================================
xml_workflows:
description: "XML-based workflows and tasks"
globs:
- "src/**/workflows/**/*.xml"
- "src/**/tasks/**/*.xml"
rules:
- id: "xml_task_id_required"
description: "XML tasks must have unique 'id' attribute on root task element"
severity: "high"
- id: "xml_llm_instructions"
description: "XML workflows should include <llm> section with critical execution instructions for the agent"
severity: "medium"
- id: "xml_step_numbering"
description: "XML steps should use n='X' attribute for sequential numbering"
severity: "medium"
- id: "xml_action_tags"
description: "Use <action> for required actions, <ask> for user input (must HALT), <goto> for jumps, <check if='...'> for conditionals"
severity: "medium"
- id: "xml_ask_must_halt"
description: "<ask> tags require agent to HALT and wait for user response before continuing"
severity: "high"
# ============================================
# WORKFLOW CONTENT QUALITY
# ============================================
workflow_content:
description: "Content quality and consistency rules for all workflow files"
globs:
- "src/**/workflows/**/*.md"
- "src/**/workflows/**/*.yaml"
rules:
- id: "communication_language_variable"
description: "Workflows should use {communication_language} variable for agent output language consistency"
severity: "low"
- id: "path_placeholders_required"
description: "Use path placeholders (e.g. {project-root}, {installed_path}, {output_folder}) instead of hardcoded paths"
severity: "medium"
- id: "no_time_estimates"
description: "Workflows should NOT include time estimates - AI development speed varies significantly"
severity: "low"
- id: "facilitator_not_generator"
description: "Workflow agents should act as facilitators (guide user input) not content generators (create without input)"
severity: "medium"
- id: "no_skip_optimization"
description: "Workflows must execute steps sequentially - no skipping or 'optimizing' step order"
severity: "high"
# ============================================
# AGENT DEFINITIONS
# ============================================
agent_definitions:
description: "Agent YAML configuration files"
globs:
- "src/**/*.agent.yaml"
rules:
- id: "agent_metadata_required"
description: "Agent files must have metadata section with id, name, title, icon, and module"
severity: "high"
- id: "agent_persona_required"
description: "Agent files must define persona with role, identity, communication_style, and principles"
severity: "high"
- id: "agent_menu_valid_workflows"
description: "Menu triggers must reference valid workflow paths that exist"
severity: "high"
# ============================================
# TEMPLATES
# ============================================
templates:
description: "Template files for workflow outputs"
globs:
- "src/**/template*.md"
- "src/**/templates/**/*.md"
rules:
- id: "placeholder_syntax"
description: "Use {variable_name} or {{variable_name}} syntax consistently for placeholders"
severity: "medium"
- id: "template_sections_marked"
description: "Template sections that need generation should be clearly marked (e.g., <!-- GENERATE: section_name -->)"
severity: "low"
# ============================================
# DOCUMENTATION
# ============================================
documentation:
description: "Documentation files"
globs:
- "docs/**/*.md"
- "README.md"
- "CONTRIBUTING.md"
rules:
- id: "valid_internal_links"
description: "Internal markdown links must point to existing files"
severity: "medium"
# ============================================
# BUILD TOOLS
# ============================================
build_tools:
description: "Build scripts and tooling"
globs:
- "tools/**"
rules:
- id: "script_error_handling"
description: "Scripts should handle errors gracefully with proper exit codes"
severity: "medium"

View File

@ -17,21 +17,66 @@ reviews:
base_branches: base_branches:
- main - main
path_filters: path_filters:
# --- Shared baseline: tool configs ---
- "!.coderabbit.yaml"
- "!.augment/**"
- "!eslint.config.mjs"
# --- Shared baseline: build output ---
- "!dist/**"
- "!build/**"
- "!coverage/**"
# --- Shared baseline: vendored/generated ---
- "!**/node_modules/**" - "!**/node_modules/**"
- "!**/*.min.js"
- "!**/*.generated.*"
- "!**/*.bundle.md"
# --- Shared baseline: package metadata ---
- "!package-lock.json"
# --- Shared baseline: binary/media ---
- "!*.png"
- "!*.jpg"
- "!*.svg"
# --- Shared baseline: test fixtures ---
- "!test/fixtures/**"
- "!test/template-test-generator/**"
- "!tools/template-test-generator/test-scenarios/**"
# --- Shared baseline: non-project dirs ---
- "!_bmad*/**"
- "!website/**"
- "!z*/**"
- "!sample-project/**"
- "!test-project-install/**"
# --- Shared baseline: AI assistant dirs ---
- "!.claude/**"
- "!.codex/**"
- "!.agent/**"
- "!.agentvibes/**"
- "!.kiro/**"
- "!.roo/**"
- "!.github/chatmodes/**"
# --- Shared baseline: build temp ---
- "!.bundler-temp/**"
# --- Shared baseline: generated reports ---
- "!**/validation-report-*.md"
- "!CHANGELOG.md"
path_instructions: path_instructions:
- path: "**/*" - path: "**/*"
instructions: | instructions: |
Focus on inconsistencies, contradictions, edge cases and serious issues. You are a cynical, jaded reviewer with zero patience for sloppy work.
Avoid commenting on minor issues such as linting, formatting and style issues. This PR was submitted by a clueless weasel and you expect to find problems.
When providing code suggestions, use GitHub's suggestion format: Be skeptical of everything.
```suggestion Look for what's missing, not just what's wrong.
<code changes> Use a precise, professional tone — no profanity or personal attacks.
```
- path: "**/*.js" Review with extreme skepticism — assume problems exist.
instructions: | Find at least 10 issues to fix or improve.
CLI tooling code. Check for: missing error handling on fs operations,
path.join vs string concatenation, proper cleanup in error paths. Do NOT:
Flag any process.exit() without error message. - Comment on formatting, linting, or style
- Give "looks good" passes
- Anchor on any specific ruleset — reason freely
If you find zero issues, re-analyze — this is suspicious.
chat: chat:
auto_reply: true # Response to mentions in comments, a la @coderabbit review auto_reply: true # Response to mentions in comments, a la @coderabbit review
issue_enrichment: issue_enrichment:

View File

@ -1,7 +1,7 @@
name: Trigger CodeRabbit on Ready for Review name: Trigger CodeRabbit on Ready for Review
on: on:
pull_request: pull_request_target:
types: [ready_for_review] types: [ready_for_review]
jobs: jobs:

4
.gitignore vendored
View File

@ -42,7 +42,9 @@ z*/
_bmad _bmad
_bmad-output _bmad-output
.clinerules .clinerules
.augment # .augment/ is gitignored except tracked config files — add exceptions explicitly
.augment/*
!.augment/code_review_guidelines.yaml
.crush .crush
.cursor .cursor
.iflow .iflow

View File

@ -1,5 +1,6 @@
--- ---
title: "Documentation Style Guide" title: "Documentation Style Guide"
description: Project-specific documentation conventions based on Google style and Diataxis structure
--- ---
This project adheres to the [Google Developer Documentation Style Guide](https://developers.google.com/style) and uses [Diataxis](https://diataxis.fr/) to structure content. Only project-specific conventions follow. This project adheres to the [Google Developer Documentation Style Guide](https://developers.google.com/style) and uses [Diataxis](https://diataxis.fr/) to structure content. Only project-specific conventions follow.

View File

@ -1,5 +1,6 @@
--- ---
title: "Game Types Reference" title: "Game Types Reference"
description: 24 game type templates with genre-specific GDD sections for BMGD
draft: true draft: true
--- ---

View File

@ -1,5 +1,6 @@
--- ---
title: "Quick Flow Workflows" title: "Quick Flow Workflows"
description: Create tech specs and execute implementations with BMGD Quick Flow
draft: true draft: true
--- ---

View File

@ -1,5 +1,6 @@
--- ---
title: "BMad Method Customization Guide" title: "BMad Method Customization Guide"
description: Customize agents, workflows, and modules while preserving update compatibility
--- ---
The ability to customize the BMad Method and its core to your needs, while still being able to get updates and enhancements is a critical idea within the BMad Ecosystem. The ability to customize the BMad Method and its core to your needs, while still being able to get updates and enhancements is a critical idea within the BMad Ecosystem.

View File

@ -1,5 +1,6 @@
--- ---
title: "Document Sharding Guide" title: "Document Sharding Guide"
description: Split large markdown files into smaller organized files for better context management
--- ---
Use the `shard-doc` tool if you need to split large markdown files into smaller, organized files for better context management. Use the `shard-doc` tool if you need to split large markdown files into smaller, organized files for better context management.

View File

@ -1,5 +1,6 @@
--- ---
title: Welcome to the BMad Method title: Welcome to the BMad Method
description: AI-driven development framework with specialized agents, guided workflows, and intelligent planning
--- ---
The BMad Method (**B**reakthrough **M**ethod of **A**gile AI **D**riven Development) is an AI-driven development framework that helps you build software through the whole process from ideation and planning all the way through agentic implementation. It provides specialized AI agents, guided workflows, and intelligent planning that adapts to your project's complexity, whether you're fixing a bug or building an enterprise platform. The BMad Method (**B**reakthrough **M**ethod of **A**gile AI **D**riven Development) is an AI-driven development framework that helps you build software through the whole process from ideation and planning all the way through agentic implementation. It provides specialized AI agents, guided workflows, and intelligent planning that adapts to your project's complexity, whether you're fixing a bug or building an enterprise platform.

View File

@ -1,5 +1,6 @@
--- ---
title: Agents title: Agents
description: Default BMM agents with their menu triggers and primary workflows
--- ---
This page lists the default BMM (Agile suite) agents that install with BMAD Method, along with their menu triggers and primary workflows. This page lists the default BMM (Agile suite) agents that install with BMAD Method, along with their menu triggers and primary workflows.

View File

@ -1,5 +1,6 @@
--- ---
title: Official Modules title: Official Modules
description: Add-on modules for building custom agents, creative intelligence, game development, and testing
--- ---
BMad extends through official modules that you select during installation. These add-on modules provide specialized agents, workflows, and tasks for specific domains beyond the built-in core and BMM (Agile suite). BMad extends through official modules that you select during installation. These add-on modules provide specialized agents, workflows, and tasks for specific domains beyond the built-in core and BMM (Agile suite).

View File

@ -1,5 +1,6 @@
--- ---
title: Testing Options title: Testing Options
description: Built-in QA agent and the standalone Test Architect module for advanced testing
--- ---
# Testing Options # Testing Options

View File

@ -12,11 +12,7 @@ export default [
'coverage/**', 'coverage/**',
'**/*.min.js', '**/*.min.js',
'test/template-test-generator/**', 'test/template-test-generator/**',
'test/template-test-generator/**/*.js',
'test/template-test-generator/**/*.md',
'test/fixtures/**', 'test/fixtures/**',
'test/fixtures/**/*.yaml',
'_bmad/**',
'_bmad*/**', '_bmad*/**',
// Build output // Build output
'build/**', 'build/**',
@ -36,6 +32,10 @@ export default [
'tools/template-test-generator/test-scenarios/**', 'tools/template-test-generator/test-scenarios/**',
'src/modules/*/sub-modules/**', 'src/modules/*/sub-modules/**',
'.bundler-temp/**', '.bundler-temp/**',
// Augment vendor config — not project code, naming conventions
// are dictated by Augment and can't be changed, so exclude
// the entire directory from linting
'.augment/**',
], ],
}, },

474
package-lock.json generated
View File

@ -37,7 +37,6 @@
"@astrojs/sitemap": "^3.6.0", "@astrojs/sitemap": "^3.6.0",
"@astrojs/starlight": "^0.37.5", "@astrojs/starlight": "^0.37.5",
"@eslint/js": "^9.33.0", "@eslint/js": "^9.33.0",
"archiver": "^7.0.1",
"astro": "^5.16.0", "astro": "^5.16.0",
"c8": "^10.1.3", "c8": "^10.1.3",
"eslint": "^9.33.0", "eslint": "^9.33.0",
@ -2030,9 +2029,9 @@
} }
}, },
"node_modules/@isaacs/brace-expansion": { "node_modules/@isaacs/brace-expansion": {
"version": "5.0.0", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz",
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@isaacs/balanced-match": "^4.0.1" "@isaacs/balanced-match": "^4.0.1"
@ -3950,19 +3949,6 @@
"win32" "win32"
] ]
}, },
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"dev": true,
"license": "MIT",
"dependencies": {
"event-target-shim": "^5.0.0"
},
"engines": {
"node": ">=6.5"
}
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.15.0", "version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
@ -4095,131 +4081,6 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/archiver": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz",
"integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"archiver-utils": "^5.0.2",
"async": "^3.2.4",
"buffer-crc32": "^1.0.0",
"readable-stream": "^4.0.0",
"readdir-glob": "^1.1.2",
"tar-stream": "^3.0.0",
"zip-stream": "^6.0.1"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/archiver-utils": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz",
"integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==",
"dev": true,
"license": "MIT",
"dependencies": {
"glob": "^10.0.0",
"graceful-fs": "^4.2.0",
"is-stream": "^2.0.1",
"lazystream": "^1.0.0",
"lodash": "^4.17.15",
"normalize-path": "^3.0.0",
"readable-stream": "^4.0.0"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/archiver-utils/node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/archiver-utils/node_modules/glob": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/archiver-utils/node_modules/jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
},
"optionalDependencies": {
"@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/archiver-utils/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
"license": "ISC"
},
"node_modules/archiver-utils/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/archiver-utils/node_modules/path-scurry": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
"node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/arg": { "node_modules/arg": {
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
@ -4964,21 +4825,6 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/b4a": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz",
"integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==",
"dev": true,
"license": "Apache-2.0",
"peerDependencies": {
"react-native-b4a": "*"
},
"peerDependenciesMeta": {
"react-native-b4a": {
"optional": true
}
}
},
"node_modules/babel-jest": { "node_modules/babel-jest": {
"version": "30.2.0", "version": "30.2.0",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz",
@ -5132,21 +4978,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/bare-events": {
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz",
"integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==",
"dev": true,
"license": "Apache-2.0",
"peerDependencies": {
"bare-abort-controller": "*"
},
"peerDependenciesMeta": {
"bare-abort-controller": {
"optional": true
}
}
},
"node_modules/base-64": { "node_modules/base-64": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz",
@ -5356,16 +5187,6 @@
"ieee754": "^1.1.13" "ieee754": "^1.1.13"
} }
}, },
"node_modules/buffer-crc32": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz",
"integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/buffer-from": { "node_modules/buffer-from": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@ -5864,23 +5685,6 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/compress-commons": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz",
"integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"crc-32": "^1.2.0",
"crc32-stream": "^6.0.0",
"is-stream": "^2.0.1",
"normalize-path": "^3.0.0",
"readable-stream": "^4.0.0"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -5937,40 +5741,6 @@
"url": "https://opencollective.com/core-js" "url": "https://opencollective.com/core-js"
} }
}, },
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"dev": true,
"license": "MIT"
},
"node_modules/crc-32": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"crc32": "bin/crc32.njs"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/crc32-stream": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz",
"integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==",
"dev": true,
"license": "MIT",
"dependencies": {
"crc-32": "^1.2.0",
"readable-stream": "^4.0.0"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.6", "version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@ -7090,16 +6860,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/eventemitter3": { "node_modules/eventemitter3": {
"version": "5.0.4", "version": "5.0.4",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
@ -7107,26 +6867,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.x"
}
},
"node_modules/events-universal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",
"integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"bare-events": "^2.7.0"
}
},
"node_modules/execa": { "node_modules/execa": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@ -7212,13 +6952,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/fast-fifo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
"integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-glob": { "node_modules/fast-glob": {
"version": "3.3.3", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
@ -8545,13 +8278,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"dev": true,
"license": "MIT"
},
"node_modules/isexe": { "node_modules/isexe": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -9628,52 +9354,6 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/lazystream": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
"integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
"dev": true,
"license": "MIT",
"dependencies": {
"readable-stream": "^2.0.5"
},
"engines": {
"node": ">= 0.6.3"
}
},
"node_modules/lazystream/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dev": true,
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/lazystream/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true,
"license": "MIT"
},
"node_modules/lazystream/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/leven": { "node_modules/leven": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@ -9830,13 +9510,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/lodash": {
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
"dev": true,
"license": "MIT"
},
"node_modules/lodash.iteratee": { "node_modules/lodash.iteratee": {
"version": "4.7.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.iteratee/-/lodash.iteratee-4.7.0.tgz", "resolved": "https://registry.npmjs.org/lodash.iteratee/-/lodash.iteratee-4.7.0.tgz",
@ -12328,23 +12001,6 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true,
"license": "MIT"
},
"node_modules/prompts": { "node_modules/prompts": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@ -12442,81 +12098,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/readable-stream": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
"dev": true,
"license": "MIT",
"dependencies": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
"events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/readable-stream/node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/readdir-glob": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz",
"integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"minimatch": "^5.1.0"
}
},
"node_modules/readdir-glob/node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/readdir-glob/node_modules/minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/readdirp": { "node_modules/readdirp": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
@ -13517,18 +13098,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/streamx": {
"version": "2.23.0",
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz",
"integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==",
"dev": true,
"license": "MIT",
"dependencies": {
"events-universal": "^1.0.0",
"fast-fifo": "^1.3.2",
"text-decoder": "^1.1.0"
}
},
"node_modules/string_decoder": { "node_modules/string_decoder": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@ -13870,18 +13439,6 @@
"url": "https://opencollective.com/webpack" "url": "https://opencollective.com/webpack"
} }
}, },
"node_modules/tar-stream": {
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
"integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"b4a": "^1.6.4",
"fast-fifo": "^1.2.0",
"streamx": "^2.15.0"
}
},
"node_modules/test-exclude": { "node_modules/test-exclude": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz",
@ -13984,16 +13541,6 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/text-decoder": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
"integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"b4a": "^1.6.4"
}
},
"node_modules/tiny-inflate": { "node_modules/tiny-inflate": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
@ -15144,21 +14691,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/zip-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz",
"integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==",
"dev": true,
"license": "MIT",
"dependencies": {
"archiver-utils": "^5.0.0",
"compress-commons": "^6.0.2",
"readable-stream": "^4.0.0"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/zod": { "node_modules/zod": {
"version": "3.25.76", "version": "3.25.76",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",

View File

@ -303,8 +303,15 @@ function extractCsvRefs(filePath, content) {
skip_empty_lines: true, skip_empty_lines: true,
relax_column_count: true, relax_column_count: true,
}); });
} catch { } catch (error) {
return refs; // Skip unparseable CSV // No CSV schema validator exists yet (planned as Layer 2c) — surface parse errors visibly.
// YAML equivalent (line ~198) defers to validate-agent-schema.js; CSV has no such fallback.
const rel = path.relative(PROJECT_ROOT, filePath);
console.error(` [CSV-PARSE-ERROR] ${rel}: ${error.message}`);
if (process.env.GITHUB_ACTIONS) {
console.log(`::warning file=${rel},line=1::${escapeAnnotation(`CSV parse error: ${error.message}`)}`);
}
return refs;
} }
// Only process if workflow-file column exists // Only process if workflow-file column exists
@ -418,31 +425,39 @@ if (require.main === module) {
refs = extractMarkdownRefs(filePath, content); refs = extractMarkdownRefs(filePath, content);
} }
// Resolve and check // Resolve and classify all refs before printing anything.
// This avoids the confusing pattern of printing headers at two different
// times depending on verbosity — collect first, then print once.
const broken = []; const broken = [];
const ok = [];
if (VERBOSE && refs.length > 0) {
console.log(`\n${relativePath}`);
}
for (const ref of refs) { for (const ref of refs) {
totalRefs++; totalRefs++;
const resolved = resolveRef(ref); const resolved = resolveRef(ref);
if (resolved && !fs.existsSync(resolved)) { if (resolved && !fs.existsSync(resolved)) {
// For paths without extensions, also check if it's a directory // Extensionless paths may be directory references or partial templates.
// If the path has no extension, check whether it exists as a directory.
// Flag it if nothing exists at all — likely a real broken reference.
const hasExt = path.extname(resolved) !== ''; const hasExt = path.extname(resolved) !== '';
if (!hasExt) { if (!hasExt) {
// Could be a directory reference — skip if not clearly a file if (fs.existsSync(resolved)) {
ok.push({ ref, tag: 'OK-DIR' });
} else {
// No extension and nothing exists — not a file, not a directory.
// Flag as UNRESOLVED (distinct from BROKEN which means "file with extension not found").
broken.push({ ref, resolved: path.relative(PROJECT_ROOT, resolved), kind: 'unresolved' });
brokenRefs++;
}
continue; continue;
} }
broken.push({ ref, resolved: path.relative(PROJECT_ROOT, resolved) }); broken.push({ ref, resolved: path.relative(PROJECT_ROOT, resolved), kind: 'broken' });
brokenRefs++; brokenRefs++;
continue; continue;
} }
if (VERBOSE && resolved) { if (resolved) {
console.log(` [OK] ${ref.raw}`); ok.push({ ref, tag: 'OK' });
} }
} }
@ -450,21 +465,33 @@ if (require.main === module) {
const leaks = checkAbsolutePathLeaks(filePath, content); const leaks = checkAbsolutePathLeaks(filePath, content);
totalLeaks += leaks.length; totalLeaks += leaks.length;
// Report issues for this file // Print results — file header appears once, in one place
if (broken.length > 0 || leaks.length > 0) { const hasFileIssues = broken.length > 0 || leaks.length > 0;
if (hasFileIssues) {
filesWithIssues++; filesWithIssues++;
if (!VERBOSE) { console.log(`\n${relativePath}`);
console.log(`\n${relativePath}`);
if (VERBOSE) {
for (const { ref, tag, note } of ok) {
const suffix = note ? ` (${note})` : '';
console.log(` [${tag}] ${ref.raw}${suffix}`);
}
} }
for (const { ref, resolved } of broken) { for (const { ref, resolved, kind } of broken) {
const location = ref.line ? `line ${ref.line}` : ref.key ? `key: ${ref.key}` : ''; const location = ref.line ? `line ${ref.line}` : ref.key ? `key: ${ref.key}` : '';
console.log(` [BROKEN] ${ref.raw}${location ? ` (${location})` : ''}`); const tag = kind === 'unresolved' ? 'UNRESOLVED' : 'BROKEN';
console.log(` Target not found: ${resolved}`); const detail = kind === 'unresolved' ? 'Not found as file or directory' : 'Target not found';
allIssues.push({ file: relativePath, line: ref.line || 1, ref: ref.raw, issue: 'broken ref' }); const issueType = kind === 'unresolved' ? 'unresolved path' : 'broken ref';
console.log(` [${tag}] ${ref.raw}${location ? ` (${location})` : ''}`);
console.log(` ${detail}: ${resolved}`);
allIssues.push({ file: relativePath, line: ref.line || 1, ref: ref.raw, issue: issueType });
if (process.env.GITHUB_ACTIONS) { if (process.env.GITHUB_ACTIONS) {
const line = ref.line || 1; const line = ref.line || 1;
console.log(`::warning file=${relativePath},line=${line}::${escapeAnnotation(`Broken reference: ${ref.raw}${resolved}`)}`); console.log(
`::warning file=${relativePath},line=${line}::${escapeAnnotation(`${tag === 'UNRESOLVED' ? 'Unresolved path' : 'Broken reference'}: ${ref.raw}${resolved}`)}`,
);
} }
} }
@ -475,6 +502,12 @@ if (require.main === module) {
console.log(`::warning file=${relativePath},line=${leak.line}::${escapeAnnotation(`Absolute path leak: ${leak.content}`)}`); console.log(`::warning file=${relativePath},line=${leak.line}::${escapeAnnotation(`Absolute path leak: ${leak.content}`)}`);
} }
} }
} else if (VERBOSE && refs.length > 0) {
console.log(`\n${relativePath}`);
for (const { ref, tag, note } of ok) {
const suffix = note ? ` (${note})` : '';
console.log(` [${tag}] ${ref.raw}${suffix}`);
}
} }
} }