ai-qakit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +240 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +208 -0
- package/dist/commands/clean.d.ts +10 -0
- package/dist/commands/clean.js +53 -0
- package/dist/commands/init.d.ts +20 -0
- package/dist/commands/init.js +195 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/utils/file-operations.d.ts +18 -0
- package/dist/utils/file-operations.js +79 -0
- package/dist/utils/git.d.ts +4 -0
- package/dist/utils/git.js +27 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/logger.d.ts +22 -0
- package/dist/utils/logger.js +23 -0
- package/dist/utils/manifest.d.ts +37 -0
- package/dist/utils/manifest.js +120 -0
- package/dist/utils/package.d.ts +19 -0
- package/dist/utils/package.js +47 -0
- package/package.json +61 -0
- package/templates/.antigravity/agents/qa-agents.yaml +50 -0
- package/templates/.antigravity/prompts/qa-prompts.md +56 -0
- package/templates/.claude/.scoutignore +33 -0
- package/templates/.claude/CHANGELOG.md +587 -0
- package/templates/.claude/CLAUDE.md +335 -0
- package/templates/.claude/README.md +428 -0
- package/templates/.claude/TROUBLESHOOTING.md +789 -0
- package/templates/.claude/agents/accessibility-tester.md +29 -0
- package/templates/.claude/agents/api-tester.md +29 -0
- package/templates/.claude/agents/automation-engineer.md +30 -0
- package/templates/.claude/agents/brainstormer.md +123 -0
- package/templates/.claude/agents/bug-hunter.md +30 -0
- package/templates/.claude/agents/claude-optimizer.md +221 -0
- package/templates/.claude/agents/code-reviewer.md +176 -0
- package/templates/.claude/agents/code-simplifier.md +103 -0
- package/templates/.claude/agents/coder.md +163 -0
- package/templates/.claude/agents/context-manager.md +110 -0
- package/templates/.claude/agents/cunningham.md +134 -0
- package/templates/.claude/agents/database-admin.md +112 -0
- package/templates/.claude/agents/debugger.md +156 -0
- package/templates/.claude/agents/docs-manager.md +181 -0
- package/templates/.claude/agents/e2e-tester.md +30 -0
- package/templates/.claude/agents/performance-engineer.md +48 -0
- package/templates/.claude/agents/performance-tester.md +29 -0
- package/templates/.claude/agents/planner.md +72 -0
- package/templates/.claude/agents/project-manager.md +152 -0
- package/templates/.claude/agents/qa-scout.md +29 -0
- package/templates/.claude/agents/quality-engineer.md +48 -0
- package/templates/.claude/agents/readme-writer.md +67 -0
- package/templates/.claude/agents/researcher.md +57 -0
- package/templates/.claude/agents/scout.md +125 -0
- package/templates/.claude/agents/security-agent.md +564 -0
- package/templates/.claude/agents/security-tester.md +29 -0
- package/templates/.claude/agents/storage-path-convention.md +102 -0
- package/templates/.claude/agents/tattletale-reporter.md +77 -0
- package/templates/.claude/agents/test-architect.md +32 -0
- package/templates/.claude/agents/test-reviewer.md +29 -0
- package/templates/.claude/agents/tester.md +286 -0
- package/templates/.claude/agents/typescript-pro.md +280 -0
- package/templates/.claude/agents/ui-ux-designer.md +256 -0
- package/templates/.claude/commands/devkit/analyze.md +92 -0
- package/templates/.claude/commands/devkit/ask.md +269 -0
- package/templates/.claude/commands/devkit/backend/create-api.md +220 -0
- package/templates/.claude/commands/devkit/backend/create-migration.md +130 -0
- package/templates/.claude/commands/devkit/backend/create-schema.md +158 -0
- package/templates/.claude/commands/devkit/backend/design-graphql-api.md +302 -0
- package/templates/.claude/commands/devkit/backend/design-rest-api.md +192 -0
- package/templates/.claude/commands/devkit/config/bootstrap.md +137 -0
- package/templates/.claude/commands/devkit/config/init-backend.md +233 -0
- package/templates/.claude/commands/devkit/config/init-frontend.md +911 -0
- package/templates/.claude/commands/devkit/create-test.md +165 -0
- package/templates/.claude/commands/devkit/debug.md +481 -0
- package/templates/.claude/commands/devkit/docs/capture-knowledge.md +424 -0
- package/templates/.claude/commands/devkit/docs/init.md +203 -0
- package/templates/.claude/commands/devkit/docs/summarize.md +33 -0
- package/templates/.claude/commands/devkit/docs/update.md +207 -0
- package/templates/.claude/commands/devkit/fix/fast.md +22 -0
- package/templates/.claude/commands/devkit/fix/hard.md +44 -0
- package/templates/.claude/commands/devkit/fix.md +16 -0
- package/templates/.claude/commands/devkit/frontend/create-api-integration.md +507 -0
- package/templates/.claude/commands/devkit/frontend/create-component.md +461 -0
- package/templates/.claude/commands/devkit/frontend/create-form.md +804 -0
- package/templates/.claude/commands/devkit/frontend/create-page.md +484 -0
- package/templates/.claude/commands/devkit/frontend/create-storybook.md +899 -0
- package/templates/.claude/commands/devkit/frontend/create-table.md +1035 -0
- package/templates/.claude/commands/devkit/help.md +148 -0
- package/templates/.claude/commands/devkit/refactor.md +510 -0
- package/templates/.claude/commands/devkit/research.md +394 -0
- package/templates/.claude/commands/devkit/review/code.md +349 -0
- package/templates/.claude/commands/devkit/review/codebase.md +51 -0
- package/templates/.claude/commands/devkit/scout.md +312 -0
- package/templates/.claude/commands/devkit/skill/add.md +29 -0
- package/templates/.claude/commands/devkit/skill/create.md +22 -0
- package/templates/.claude/commands/devkit/skill/optimize.md +34 -0
- package/templates/.claude/commands/devkit/solve.md +364 -0
- package/templates/.claude/commands/devkit/spec/brainstorm.md +309 -0
- package/templates/.claude/commands/devkit/spec/capture-requirement.md +202 -0
- package/templates/.claude/commands/devkit/spec/cook.md +157 -0
- package/templates/.claude/commands/devkit/spec/deep-capture-requirement.md +393 -0
- package/templates/.claude/commands/devkit/spec/implement.md +350 -0
- package/templates/.claude/commands/devkit/spec/plan.md +269 -0
- package/templates/.claude/commands/devkit/spec/task.md +156 -0
- package/templates/.claude/commands/devkit/spec/test.md +259 -0
- package/templates/.claude/commands/devkit/spec/update-plan.md +263 -0
- package/templates/.claude/commands/devkit/spec/update-requirement.md +239 -0
- package/templates/.claude/commands/devkit/spec-lite/do.md +280 -0
- package/templates/.claude/commands/devkit/spec-lite/plan.md +236 -0
- package/templates/.claude/commands/devkit/spec-lite/task.md +141 -0
- package/templates/.claude/commands/devkit/spec-lite/test.md +171 -0
- package/templates/.claude/commands/devkit/spec-lite/update-plan.md +154 -0
- package/templates/.claude/commands/qakit/a11y/audit.md +38 -0
- package/templates/.claude/commands/qakit/a11y/fix.md +22 -0
- package/templates/.claude/commands/qakit/analyze/full.md +459 -0
- package/templates/.claude/commands/qakit/analyze/quick.md +84 -0
- package/templates/.claude/commands/qakit/api/analyze.md +34 -0
- package/templates/.claude/commands/qakit/api/contract.md +22 -0
- package/templates/.claude/commands/qakit/api/generate.md +20 -0
- package/templates/.claude/commands/qakit/api/run.md +16 -0
- package/templates/.claude/commands/qakit/ask.md +57 -0
- package/templates/.claude/commands/qakit/automation/fix-flaky.md +233 -0
- package/templates/.claude/commands/qakit/automation/health-check.md +192 -0
- package/templates/.claude/commands/qakit/automation/maintenance.md +311 -0
- package/templates/.claude/commands/qakit/automation/scaffold-playwright.md +689 -0
- package/templates/.claude/commands/qakit/automation/scaffold-webdriverio.md +802 -0
- package/templates/.claude/commands/qakit/automation/scaffold.md +447 -0
- package/templates/.claude/commands/qakit/automation/update-deps.md +219 -0
- package/templates/.claude/commands/qakit/bug/investigate.md +96 -0
- package/templates/.claude/commands/qakit/bug/report.md +147 -0
- package/templates/.claude/commands/qakit/bug/reproduce.md +101 -0
- package/templates/.claude/commands/qakit/bug/triage.md +101 -0
- package/templates/.claude/commands/qakit/bug/verify.md +106 -0
- package/templates/.claude/commands/qakit/config/init-qa.md +107 -0
- package/templates/.claude/commands/qakit/confluence/fetch.md +192 -0
- package/templates/.claude/commands/qakit/confluence/search.md +201 -0
- package/templates/.claude/commands/qakit/docs/capture-test-knowledge.md +451 -0
- package/templates/.claude/commands/qakit/docs/update-changelog.md +207 -0
- package/templates/.claude/commands/qakit/docs/update-readme.md +296 -0
- package/templates/.claude/commands/qakit/e2e/generate.md +18 -0
- package/templates/.claude/commands/qakit/e2e/page-object.md +37 -0
- package/templates/.claude/commands/qakit/e2e/run.md +17 -0
- package/templates/.claude/commands/qakit/e2e/scenario.md +20 -0
- package/templates/.claude/commands/qakit/feature/create.md +178 -0
- package/templates/.claude/commands/qakit/feature/enrich-api.md +352 -0
- package/templates/.claude/commands/qakit/feature/enrich-tests.md +243 -0
- package/templates/.claude/commands/qakit/feature/enrich-ui.md +217 -0
- package/templates/.claude/commands/qakit/feature/enrich.md +246 -0
- package/templates/.claude/commands/qakit/feature/from-jira.md +184 -0
- package/templates/.claude/commands/qakit/feature/update.md +136 -0
- package/templates/.claude/commands/qakit/help.md +98 -0
- package/templates/.claude/commands/qakit/jira/analyze.md +329 -0
- package/templates/.claude/commands/qakit/jira/create-tests.md +319 -0
- package/templates/.claude/commands/qakit/kb/add-design.md +258 -0
- package/templates/.claude/commands/qakit/kb/capture.md +325 -0
- package/templates/.claude/commands/qakit/kb/clean.md +157 -0
- package/templates/.claude/commands/qakit/kb/dedupe.md +281 -0
- package/templates/.claude/commands/qakit/kb/init.md +234 -0
- package/templates/.claude/commands/qakit/kb/link.md +124 -0
- package/templates/.claude/commands/qakit/kb/list.md +185 -0
- package/templates/.claude/commands/qakit/kb/resolve.md +234 -0
- package/templates/.claude/commands/qakit/kb/search.md +202 -0
- package/templates/.claude/commands/qakit/kb/sync-confluence.md +474 -0
- package/templates/.claude/commands/qakit/metrics/coverage.md +46 -0
- package/templates/.claude/commands/qakit/metrics/dashboard.md +62 -0
- package/templates/.claude/commands/qakit/metrics/trends.md +42 -0
- package/templates/.claude/commands/qakit/perf/analyze.md +31 -0
- package/templates/.claude/commands/qakit/perf/plan.md +18 -0
- package/templates/.claude/commands/qakit/perf/run.md +17 -0
- package/templates/.claude/commands/qakit/perf/script.md +38 -0
- package/templates/.claude/commands/qakit/rca/analyze.md +166 -0
- package/templates/.claude/commands/qakit/regression/analyze.md +36 -0
- package/templates/.claude/commands/qakit/regression/report.md +30 -0
- package/templates/.claude/commands/qakit/regression/run.md +17 -0
- package/templates/.claude/commands/qakit/regression/select.md +34 -0
- package/templates/.claude/commands/qakit/research/deep.md +328 -0
- package/templates/.claude/commands/qakit/review/coverage.md +116 -0
- package/templates/.claude/commands/qakit/review/quality-gate.md +126 -0
- package/templates/.claude/commands/qakit/review/test-code.md +320 -0
- package/templates/.claude/commands/qakit/review/test-review.md +109 -0
- package/templates/.claude/commands/qakit/scout.md +195 -0
- package/templates/.claude/commands/qakit/setup/confluence.md +140 -0
- package/templates/.claude/commands/qakit/setup/jira.md +154 -0
- package/templates/.claude/commands/qakit/spec/analyze.md +46 -0
- package/templates/.claude/commands/qakit/spec/cook.md +344 -0
- package/templates/.claude/commands/qakit/spec/execute.md +38 -0
- package/templates/.claude/commands/qakit/spec/plan.md +46 -0
- package/templates/.claude/commands/qakit/spec/report.md +40 -0
- package/templates/.claude/commands/qakit/spec/task.md +40 -0
- package/templates/.claude/commands/qakit/test/create-test-case.md +151 -0
- package/templates/.claude/commands/qakit/test/create-test-suite.md +84 -0
- package/templates/.claude/commands/qakit/test/generate-api-tests.md +82 -0
- package/templates/.claude/commands/qakit/test/generate-data.md +114 -0
- package/templates/.claude/commands/qakit/test/generate-e2e.md +99 -0
- package/templates/.claude/commands/qakit/test/generate-ui-tests.md +97 -0
- package/templates/.claude/commands/qakit/testmo/report.md +22 -0
- package/templates/.claude/commands/qakit/testmo/sync.md +31 -0
- package/templates/.claude/doc-templates/bug-report-template.md +247 -0
- package/templates/.claude/doc-templates/code-standards.md +486 -0
- package/templates/.claude/doc-templates/codebase-summary.md +426 -0
- package/templates/.claude/doc-templates/development-rules.md +553 -0
- package/templates/.claude/doc-templates/feature-spec-template.md +167 -0
- package/templates/.claude/doc-templates/performance-report-template.md +49 -0
- package/templates/.claude/doc-templates/project-overview-pdr.md +494 -0
- package/templates/.claude/doc-templates/quality-report-template.md +44 -0
- package/templates/.claude/doc-templates/regression-report-template.md +41 -0
- package/templates/.claude/doc-templates/system-architecture.md +615 -0
- package/templates/.claude/doc-templates/technical-documents.md +127 -0
- package/templates/.claude/doc-templates/test-case-template.md +198 -0
- package/templates/.claude/doc-templates/test-plan-template.md +366 -0
- package/templates/.claude/doc-templates/test-summary-report.md +401 -0
- package/templates/.claude/hooks/dev-rules-reminder.cjs +101 -0
- package/templates/.claude/hooks/dev-rules-reminder.js +96 -0
- package/templates/.claude/hooks/executable_force-agent-skills-eval.sh +38 -0
- package/templates/.claude/hooks/scout-block/scout-block.ps1 +92 -0
- package/templates/.claude/hooks/scout-block/scout-block.sh +119 -0
- package/templates/.claude/hooks/scout-block.cjs +100 -0
- package/templates/.claude/hooks/scout-block.js +104 -0
- package/templates/.claude/repomix.config.json +34 -0
- package/templates/.claude/rules/01-core-principles.md +81 -0
- package/templates/.claude/rules/02-naming-and-constants.md +115 -0
- package/templates/.claude/rules/03-function-design.md +167 -0
- package/templates/.claude/rules/04-error-handling.md +83 -0
- package/templates/.claude/rules/05-testing.md +86 -0
- package/templates/.claude/rules/06-code-quality.md +107 -0
- package/templates/.claude/rules/07-architecture.md +105 -0
- package/templates/.claude/rules/08-performance-security.md +93 -0
- package/templates/.claude/rules/index.md +77 -0
- package/templates/.claude/scripts/README.md +153 -0
- package/templates/.claude/scripts/commands_data.yaml +336 -0
- package/templates/.claude/scripts/generate_catalogs.py +163 -0
- package/templates/.claude/scripts/helper.py +723 -0
- package/templates/.claude/scripts/scan_commands.py +101 -0
- package/templates/.claude/scripts/scan_skills.py +187 -0
- package/templates/.claude/scripts/skills_data.yaml +348 -0
- package/templates/.claude/settings.json +54 -0
- package/templates/.claude/settings.local.README.md +650 -0
- package/templates/.claude/settings.local.json +41 -0
- package/templates/.claude/setup/dependencies/setup-claude-mem.ps1 +534 -0
- package/templates/.claude/setup/dependencies/setup-claude-mem.sh +477 -0
- package/templates/.claude/setup/dependencies/setup-mcp-servers.ps1 +562 -0
- package/templates/.claude/setup/dependencies/setup-mcp-servers.sh +511 -0
- package/templates/.claude/setup/jira-env.example.sh +22 -0
- package/templates/.claude/setup/setup.ps1 +240 -0
- package/templates/.claude/setup/setup.sh +222 -0
- package/templates/.claude/skills/accessibility-testing/SKILL.md +34 -0
- package/templates/.claude/skills/aesthetic/SKILL.md +121 -0
- package/templates/.claude/skills/aesthetic/assets/design-guideline-template.md +163 -0
- package/templates/.claude/skills/aesthetic/assets/design-story-template.md +135 -0
- package/templates/.claude/skills/aesthetic/references/design-principles.md +62 -0
- package/templates/.claude/skills/aesthetic/references/design-resources.md +75 -0
- package/templates/.claude/skills/aesthetic/references/micro-interactions.md +53 -0
- package/templates/.claude/skills/aesthetic/references/storytelling-design.md +50 -0
- package/templates/.claude/skills/aesthetic/skill-creator/LICENSE.txt +202 -0
- package/templates/.claude/skills/aesthetic/skill-creator/SKILL.md +266 -0
- package/templates/.claude/skills/aesthetic/skill-creator/scripts/init_skill.py +303 -0
- package/templates/.claude/skills/aesthetic/skill-creator/scripts/package_skill.py +110 -0
- package/templates/.claude/skills/aesthetic/skill-creator/scripts/quick_validate.py +65 -0
- package/templates/.claude/skills/agent_skills_spec.md +51 -0
- package/templates/.claude/skills/ai-multimodal/.env.example +185 -0
- package/templates/.claude/skills/ai-multimodal/SKILL.md +69 -0
- package/templates/.claude/skills/ai-multimodal/references/audio-processing.md +386 -0
- package/templates/.claude/skills/ai-multimodal/references/image-generation.md +722 -0
- package/templates/.claude/skills/ai-multimodal/references/video-analysis.md +515 -0
- package/templates/.claude/skills/ai-multimodal/references/video-generation.md +457 -0
- package/templates/.claude/skills/ai-multimodal/references/vision-understanding.md +492 -0
- package/templates/.claude/skills/ai-multimodal/scripts/check_setup.py +299 -0
- package/templates/.claude/skills/ai-multimodal/scripts/document_converter.py +395 -0
- package/templates/.claude/skills/ai-multimodal/scripts/gemini_batch_process.py +1067 -0
- package/templates/.claude/skills/ai-multimodal/scripts/media_optimizer.py +506 -0
- package/templates/.claude/skills/ai-multimodal/scripts/requirements.txt +26 -0
- package/templates/.claude/skills/ai-multimodal/scripts/tests/requirements.txt +20 -0
- package/templates/.claude/skills/ai-multimodal/scripts/tests/test_document_converter.py +74 -0
- package/templates/.claude/skills/ai-multimodal/scripts/tests/test_gemini_batch_process.py +362 -0
- package/templates/.claude/skills/ai-multimodal/scripts/tests/test_media_optimizer.py +373 -0
- package/templates/.claude/skills/api-design-principles/SKILL.md +527 -0
- package/templates/.claude/skills/api-design-principles/assets/api-design-checklist.md +136 -0
- package/templates/.claude/skills/api-design-principles/assets/rest-api-template.py +165 -0
- package/templates/.claude/skills/api-design-principles/references/graphql-schema-design.md +566 -0
- package/templates/.claude/skills/api-design-principles/references/rest-best-practices.md +385 -0
- package/templates/.claude/skills/api-testing/SKILL.md +24 -0
- package/templates/.claude/skills/backend-development/SKILL.md +95 -0
- package/templates/.claude/skills/backend-development/references/backend-api-design.md +495 -0
- package/templates/.claude/skills/backend-development/references/backend-architecture.md +454 -0
- package/templates/.claude/skills/backend-development/references/backend-code-quality.md +659 -0
- package/templates/.claude/skills/backend-development/references/backend-debugging.md +904 -0
- package/templates/.claude/skills/backend-development/references/backend-devops.md +494 -0
- package/templates/.claude/skills/backend-development/references/backend-mindset.md +387 -0
- package/templates/.claude/skills/backend-development/references/backend-performance.md +397 -0
- package/templates/.claude/skills/backend-development/references/backend-security.md +290 -0
- package/templates/.claude/skills/backend-development/references/backend-technologies.md +256 -0
- package/templates/.claude/skills/backend-development/references/backend-testing.md +429 -0
- package/templates/.claude/skills/bug-investigation/SKILL.md +24 -0
- package/templates/.claude/skills/chrome-devtools/SKILL.md +472 -0
- package/templates/.claude/skills/chrome-devtools/references/cdp-domains.md +694 -0
- package/templates/.claude/skills/chrome-devtools/references/performance-guide.md +940 -0
- package/templates/.claude/skills/chrome-devtools/references/puppeteer-reference.md +953 -0
- package/templates/.claude/skills/chrome-devtools/scripts/README.md +228 -0
- package/templates/.claude/skills/chrome-devtools/scripts/__tests__/selector.test.js +210 -0
- package/templates/.claude/skills/chrome-devtools/scripts/aria-snapshot.js +362 -0
- package/templates/.claude/skills/chrome-devtools/scripts/click.js +83 -0
- package/templates/.claude/skills/chrome-devtools/scripts/console.js +79 -0
- package/templates/.claude/skills/chrome-devtools/scripts/evaluate.js +53 -0
- package/templates/.claude/skills/chrome-devtools/scripts/fill.js +76 -0
- package/templates/.claude/skills/chrome-devtools/scripts/install-deps.sh +181 -0
- package/templates/.claude/skills/chrome-devtools/scripts/install.sh +83 -0
- package/templates/.claude/skills/chrome-devtools/scripts/lib/browser.js +217 -0
- package/templates/.claude/skills/chrome-devtools/scripts/lib/selector.js +178 -0
- package/templates/.claude/skills/chrome-devtools/scripts/navigate.js +54 -0
- package/templates/.claude/skills/chrome-devtools/scripts/network.js +106 -0
- package/templates/.claude/skills/chrome-devtools/scripts/package.json +16 -0
- package/templates/.claude/skills/chrome-devtools/scripts/performance.js +149 -0
- package/templates/.claude/skills/chrome-devtools/scripts/screenshot.js +194 -0
- package/templates/.claude/skills/chrome-devtools/scripts/select-ref.js +131 -0
- package/templates/.claude/skills/chrome-devtools/scripts/snapshot.js +135 -0
- package/templates/.claude/skills/claude-code-analyzer/SKILL.md +299 -0
- package/templates/.claude/skills/claude-code-analyzer/references/best-practices.md +290 -0
- package/templates/.claude/skills/claude-code-analyzer/scripts/analyze-claude-md.sh +239 -0
- package/templates/.claude/skills/claude-code-analyzer/scripts/analyze.sh +274 -0
- package/templates/.claude/skills/claude-code-analyzer/scripts/fetch-features.sh +69 -0
- package/templates/.claude/skills/claude-code-analyzer/scripts/github-discovery.sh +178 -0
- package/templates/.claude/skills/code-review/SKILL.md +155 -0
- package/templates/.claude/skills/code-review/references/code-review-reception.md +209 -0
- package/templates/.claude/skills/code-review/references/human-code-review-practices.md +370 -0
- package/templates/.claude/skills/code-review/references/requesting-code-review.md +105 -0
- package/templates/.claude/skills/code-review/references/verification-before-completion.md +139 -0
- package/templates/.claude/skills/command-development/README.md +272 -0
- package/templates/.claude/skills/command-development/SKILL.md +834 -0
- package/templates/.claude/skills/command-development/examples/plugin-commands.md +557 -0
- package/templates/.claude/skills/command-development/examples/simple-commands.md +504 -0
- package/templates/.claude/skills/command-development/references/advanced-workflows.md +722 -0
- package/templates/.claude/skills/command-development/references/documentation-patterns.md +739 -0
- package/templates/.claude/skills/command-development/references/frontmatter-reference.md +463 -0
- package/templates/.claude/skills/command-development/references/interactive-commands.md +920 -0
- package/templates/.claude/skills/command-development/references/marketplace-considerations.md +904 -0
- package/templates/.claude/skills/command-development/references/plugin-features-reference.md +609 -0
- package/templates/.claude/skills/command-development/references/testing-strategies.md +702 -0
- package/templates/.claude/skills/confluence-integration/confluence-integration.md +260 -0
- package/templates/.claude/skills/databases/SKILL.md +232 -0
- package/templates/.claude/skills/databases/references/mongodb-aggregation.md +447 -0
- package/templates/.claude/skills/databases/references/mongodb-atlas.md +465 -0
- package/templates/.claude/skills/databases/references/mongodb-crud.md +408 -0
- package/templates/.claude/skills/databases/references/mongodb-indexing.md +442 -0
- package/templates/.claude/skills/databases/references/postgresql-administration.md +594 -0
- package/templates/.claude/skills/databases/references/postgresql-performance.md +527 -0
- package/templates/.claude/skills/databases/references/postgresql-psql-cli.md +467 -0
- package/templates/.claude/skills/databases/references/postgresql-queries.md +475 -0
- package/templates/.claude/skills/databases/scripts/db_backup.py +502 -0
- package/templates/.claude/skills/databases/scripts/db_migrate.py +414 -0
- package/templates/.claude/skills/databases/scripts/db_performance_check.py +444 -0
- package/templates/.claude/skills/databases/scripts/dot_coverage +0 -0
- package/templates/.claude/skills/databases/scripts/requirements.txt +20 -0
- package/templates/.claude/skills/databases/scripts/tests/coverage-db.json +1 -0
- package/templates/.claude/skills/databases/scripts/tests/requirements.txt +4 -0
- package/templates/.claude/skills/databases/scripts/tests/test_db_backup.py +340 -0
- package/templates/.claude/skills/databases/scripts/tests/test_db_migrate.py +277 -0
- package/templates/.claude/skills/databases/scripts/tests/test_db_performance_check.py +370 -0
- package/templates/.claude/skills/debugging/SKILL.md +84 -0
- package/templates/.claude/skills/debugging/references/defense-in-depth.md +124 -0
- package/templates/.claude/skills/debugging/references/root-cause-tracing.md +122 -0
- package/templates/.claude/skills/debugging/references/systematic-debugging.md +102 -0
- package/templates/.claude/skills/debugging/references/verification.md +123 -0
- package/templates/.claude/skills/debugging/scripts/find-polluter.sh +63 -0
- package/templates/.claude/skills/debugging/scripts/find-polluter.test.md +102 -0
- package/templates/.claude/skills/docs-discovery/COMPARISON.md +313 -0
- package/templates/.claude/skills/docs-discovery/README.md +53 -0
- package/templates/.claude/skills/docs-discovery/REFACTORING_SUMMARY.md +144 -0
- package/templates/.claude/skills/docs-discovery/SKILL.md +64 -0
- package/templates/.claude/skills/docs-discovery/archive/dot_env.example +15 -0
- package/templates/.claude/skills/docs-discovery/archive/package.json +24 -0
- package/templates/.claude/skills/docs-discovery/archive/references/advanced.md +79 -0
- package/templates/.claude/skills/docs-discovery/archive/references/context7-patterns.md +68 -0
- package/templates/.claude/skills/docs-discovery/archive/references/errors.md +68 -0
- package/templates/.claude/skills/docs-discovery/archive/scripts/analyze-llms-txt.js +211 -0
- package/templates/.claude/skills/docs-discovery/archive/scripts/detect-topic.js +172 -0
- package/templates/.claude/skills/docs-discovery/archive/scripts/fetch-docs.js +213 -0
- package/templates/.claude/skills/docs-discovery/archive/scripts/tests/run-tests.js +72 -0
- package/templates/.claude/skills/docs-discovery/archive/scripts/tests/test-analyze-llms.js +119 -0
- package/templates/.claude/skills/docs-discovery/archive/scripts/tests/test-detect-topic.js +112 -0
- package/templates/.claude/skills/docs-discovery/archive/scripts/tests/test-fetch-docs.js +84 -0
- package/templates/.claude/skills/docs-discovery/archive/scripts/utils/env-loader.js +94 -0
- package/templates/.claude/skills/docs-discovery/archive/workflows/library-search.md +87 -0
- package/templates/.claude/skills/docs-discovery/archive/workflows/repo-analysis.md +91 -0
- package/templates/.claude/skills/docs-discovery/archive/workflows/topic-search.md +77 -0
- package/templates/.claude/skills/docs-seeker/.env.example +15 -0
- package/templates/.claude/skills/docs-seeker/SKILL.md +97 -0
- package/templates/.claude/skills/docs-seeker/package.json +24 -0
- package/templates/.claude/skills/docs-seeker/references/advanced.md +79 -0
- package/templates/.claude/skills/docs-seeker/references/context7-patterns.md +68 -0
- package/templates/.claude/skills/docs-seeker/references/errors.md +68 -0
- package/templates/.claude/skills/docs-seeker/scripts/analyze-llms-txt.js +211 -0
- package/templates/.claude/skills/docs-seeker/scripts/detect-topic.js +172 -0
- package/templates/.claude/skills/docs-seeker/scripts/fetch-docs.js +213 -0
- package/templates/.claude/skills/docs-seeker/scripts/tests/run-tests.js +72 -0
- package/templates/.claude/skills/docs-seeker/scripts/tests/test-analyze-llms.js +119 -0
- package/templates/.claude/skills/docs-seeker/scripts/tests/test-detect-topic.js +112 -0
- package/templates/.claude/skills/docs-seeker/scripts/tests/test-fetch-docs.js +84 -0
- package/templates/.claude/skills/docs-seeker/scripts/utils/env-loader.js +94 -0
- package/templates/.claude/skills/docs-seeker/workflows/library-search.md +87 -0
- package/templates/.claude/skills/docs-seeker/workflows/repo-analysis.md +91 -0
- package/templates/.claude/skills/docs-seeker/workflows/topic-search.md +77 -0
- package/templates/.claude/skills/document-skills/docx/LICENSE.txt +30 -0
- package/templates/.claude/skills/document-skills/docx/SKILL.md +197 -0
- package/templates/.claude/skills/document-skills/docx/docx-js.md +350 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/scripts/pack.py +159 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/scripts/unpack.py +29 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/scripts/validate.py +69 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/scripts/validation/base.py +951 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/scripts/validation/docx.py +274 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/templates/.claude/skills/document-skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/templates/.claude/skills/document-skills/docx/ooxml.md +610 -0
- package/templates/.claude/skills/document-skills/docx/scripts/__init__.py +1 -0
- package/templates/.claude/skills/document-skills/docx/scripts/document.py +1276 -0
- package/templates/.claude/skills/document-skills/docx/scripts/templates/comments.xml +3 -0
- package/templates/.claude/skills/document-skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/templates/.claude/skills/document-skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/templates/.claude/skills/document-skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/templates/.claude/skills/document-skills/docx/scripts/templates/people.xml +3 -0
- package/templates/.claude/skills/document-skills/docx/scripts/utilities.py +374 -0
- package/templates/.claude/skills/document-skills/pdf/LICENSE.txt +30 -0
- package/templates/.claude/skills/document-skills/pdf/SKILL.md +294 -0
- package/templates/.claude/skills/document-skills/pdf/forms.md +205 -0
- package/templates/.claude/skills/document-skills/pdf/reference.md +612 -0
- package/templates/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes.py +70 -0
- package/templates/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/templates/.claude/skills/document-skills/pdf/scripts/check_fillable_fields.py +12 -0
- package/templates/.claude/skills/document-skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/templates/.claude/skills/document-skills/pdf/scripts/create_validation_image.py +41 -0
- package/templates/.claude/skills/document-skills/pdf/scripts/extract_form_field_info.py +152 -0
- package/templates/.claude/skills/document-skills/pdf/scripts/fill_fillable_fields.py +114 -0
- package/templates/.claude/skills/document-skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/templates/.claude/skills/document-skills/pptx/LICENSE.txt +30 -0
- package/templates/.claude/skills/document-skills/pptx/SKILL.md +484 -0
- package/templates/.claude/skills/document-skills/pptx/html2pptx.md +625 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/scripts/pack.py +159 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/scripts/unpack.py +29 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/scripts/validate.py +69 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/scripts/validation/base.py +951 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/templates/.claude/skills/document-skills/pptx/ooxml.md +427 -0
- package/templates/.claude/skills/document-skills/pptx/scripts/html2pptx.js +979 -0
- package/templates/.claude/skills/document-skills/pptx/scripts/inventory.py +1020 -0
- package/templates/.claude/skills/document-skills/pptx/scripts/rearrange.py +231 -0
- package/templates/.claude/skills/document-skills/pptx/scripts/replace.py +385 -0
- package/templates/.claude/skills/document-skills/pptx/scripts/thumbnail.py +450 -0
- package/templates/.claude/skills/document-skills/xlsx/LICENSE.txt +30 -0
- package/templates/.claude/skills/document-skills/xlsx/SKILL.md +289 -0
- package/templates/.claude/skills/document-skills/xlsx/recalc.py +178 -0
- package/templates/.claude/skills/frontend-development/SKILL.md +208 -0
- package/templates/.claude/skills/frontend-development/references/accessibility.md +720 -0
- package/templates/.claude/skills/frontend-development/references/data-fetching.md +412 -0
- package/templates/.claude/skills/frontend-development/references/forms.md +809 -0
- package/templates/.claude/skills/frontend-development/references/fsd-architecture.md +442 -0
- package/templates/.claude/skills/frontend-development/references/graphql-apollo.md +731 -0
- package/templates/.claude/skills/frontend-development/references/performance.md +417 -0
- package/templates/.claude/skills/frontend-development/references/react-patterns.md +451 -0
- package/templates/.claude/skills/frontend-development/references/routing.md +436 -0
- package/templates/.claude/skills/frontend-development/references/state-management.md +510 -0
- package/templates/.claude/skills/frontend-development/references/tailwind-css.md +397 -0
- package/templates/.claude/skills/frontend-development/references/testing.md +630 -0
- package/templates/.claude/skills/frontend-development/references/typescript-standards.md +363 -0
- package/templates/.claude/skills/frontend-development/references/ui-libraries.md +586 -0
- package/templates/.claude/skills/infra-engineer/SKILL.md +642 -0
- package/templates/.claude/skills/infra-engineer/dot_env.example +76 -0
- package/templates/.claude/skills/infra-engineer/references/aws-overview.md +171 -0
- package/templates/.claude/skills/infra-engineer/references/browser-rendering.md +305 -0
- package/templates/.claude/skills/infra-engineer/references/cicd-github-actions.md +439 -0
- package/templates/.claude/skills/infra-engineer/references/cloudflare-d1-kv.md +123 -0
- package/templates/.claude/skills/infra-engineer/references/cloudflare-platform.md +271 -0
- package/templates/.claude/skills/infra-engineer/references/cloudflare-r2-storage.md +280 -0
- package/templates/.claude/skills/infra-engineer/references/cloudflare-workers-advanced.md +312 -0
- package/templates/.claude/skills/infra-engineer/references/cloudflare-workers-apis.md +309 -0
- package/templates/.claude/skills/infra-engineer/references/cloudflare-workers-basics.md +418 -0
- package/templates/.claude/skills/infra-engineer/references/devsecops-basics.md +361 -0
- package/templates/.claude/skills/infra-engineer/references/docker-basics.md +297 -0
- package/templates/.claude/skills/infra-engineer/references/docker-compose.md +292 -0
- package/templates/.claude/skills/infra-engineer/references/finops-basics.md +278 -0
- package/templates/.claude/skills/infra-engineer/references/gcloud-platform.md +297 -0
- package/templates/.claude/skills/infra-engineer/references/gcloud-services.md +304 -0
- package/templates/.claude/skills/infra-engineer/references/kubernetes-basics.md +295 -0
- package/templates/.claude/skills/infra-engineer/scripts/cloudflare_deploy.py +269 -0
- package/templates/.claude/skills/infra-engineer/scripts/docker_optimize.py +320 -0
- package/templates/.claude/skills/infra-engineer/scripts/requirements.txt +20 -0
- package/templates/.claude/skills/infra-engineer/scripts/tests/requirements.txt +3 -0
- package/templates/.claude/skills/infra-engineer/scripts/tests/test_cloudflare_deploy.py +285 -0
- package/templates/.claude/skills/infra-engineer/scripts/tests/test_docker_optimize.py +436 -0
- package/templates/.claude/skills/javascript-pro/SKILL.md +96 -0
- package/templates/.claude/skills/javascript-pro/references/async-patterns.md +96 -0
- package/templates/.claude/skills/javascript-pro/references/best-practices.md +98 -0
- package/templates/.claude/skills/javascript-pro/references/design-patterns.md +100 -0
- package/templates/.claude/skills/javascript-pro/references/error-handling.md +100 -0
- package/templates/.claude/skills/javascript-pro/references/functional-patterns.md +93 -0
- package/templates/.claude/skills/javascript-pro/references/modern-syntax.md +100 -0
- package/templates/.claude/skills/javascript-pro/references/performance.md +98 -0
- package/templates/.claude/skills/jira-integration/adf-parser.md +338 -0
- package/templates/.claude/skills/jira-integration/jira-integration.md +353 -0
- package/templates/.claude/skills/knowledge-base/knowledge-base.md +212 -0
- package/templates/.claude/skills/mobile-development/SKILL.md +212 -0
- package/templates/.claude/skills/mobile-development/references/mobile-android.md +604 -0
- package/templates/.claude/skills/mobile-development/references/mobile-best-practices.md +545 -0
- package/templates/.claude/skills/mobile-development/references/mobile-debugging.md +1089 -0
- package/templates/.claude/skills/mobile-development/references/mobile-frameworks.md +465 -0
- package/templates/.claude/skills/mobile-development/references/mobile-ios.md +496 -0
- package/templates/.claude/skills/mobile-development/references/mobile-mindset.md +544 -0
- package/templates/.claude/skills/mobile-testing/SKILL.md +24 -0
- package/templates/.claude/skills/performance-testing/SKILL.md +30 -0
- package/templates/.claude/skills/planning/SKILL.md +143 -0
- package/templates/.claude/skills/planning/references/codebase-understanding.md +62 -0
- package/templates/.claude/skills/planning/references/output-standards.md +87 -0
- package/templates/.claude/skills/planning/references/plan-organization.md +137 -0
- package/templates/.claude/skills/planning/references/research-phase.md +47 -0
- package/templates/.claude/skills/planning/references/solution-design.md +63 -0
- package/templates/.claude/skills/playwright/SKILL.md +303 -0
- package/templates/.claude/skills/playwright/examples/auth.fixture.ts +172 -0
- package/templates/.claude/skills/playwright/examples/login.page.ts +232 -0
- package/templates/.claude/skills/playwright/references/config.md +391 -0
- package/templates/.claude/skills/problem-solving/SKILL.md +96 -0
- package/templates/.claude/skills/problem-solving/references/attribution.md +69 -0
- package/templates/.claude/skills/problem-solving/references/collision-zone-thinking.md +79 -0
- package/templates/.claude/skills/problem-solving/references/inversion-exercise.md +91 -0
- package/templates/.claude/skills/problem-solving/references/meta-pattern-recognition.md +87 -0
- package/templates/.claude/skills/problem-solving/references/scale-game.md +95 -0
- package/templates/.claude/skills/problem-solving/references/simplification-cascades.md +80 -0
- package/templates/.claude/skills/problem-solving/references/when-stuck.md +72 -0
- package/templates/.claude/skills/prompt-enhancer/SKILL.md +380 -0
- package/templates/.claude/skills/python-pro/SKILL.md +59 -0
- package/templates/.claude/skills/python-pro/references/async-patterns.md +96 -0
- package/templates/.claude/skills/python-pro/references/error-handling.md +84 -0
- package/templates/.claude/skills/python-pro/references/performance.md +71 -0
- package/templates/.claude/skills/python-pro/references/project-setup.md +78 -0
- package/templates/.claude/skills/python-pro/references/security.md +73 -0
- package/templates/.claude/skills/python-pro/references/testing.md +90 -0
- package/templates/.claude/skills/python-pro/references/type-system.md +88 -0
- package/templates/.claude/skills/qa-standards/SKILL.md +176 -0
- package/templates/.claude/skills/qa-standards/references/naming-conventions.md +262 -0
- package/templates/.claude/skills/quality-metrics/SKILL.md +27 -0
- package/templates/.claude/skills/repomix/SKILL.md +247 -0
- package/templates/.claude/skills/repomix/references/configuration.md +211 -0
- package/templates/.claude/skills/repomix/references/usage-patterns.md +232 -0
- package/templates/.claude/skills/repomix/scripts/README.md +179 -0
- package/templates/.claude/skills/repomix/scripts/repomix_batch.py +455 -0
- package/templates/.claude/skills/repomix/scripts/repos.example.json +15 -0
- package/templates/.claude/skills/repomix/scripts/requirements.txt +15 -0
- package/templates/.claude/skills/repomix/scripts/tests/test_repomix_batch.py +531 -0
- package/templates/.claude/skills/research/SKILL.md +168 -0
- package/templates/.claude/skills/sequential-thinking/.env.example +8 -0
- package/templates/.claude/skills/sequential-thinking/README.md +183 -0
- package/templates/.claude/skills/sequential-thinking/SKILL.md +94 -0
- package/templates/.claude/skills/sequential-thinking/package.json +31 -0
- package/templates/.claude/skills/sequential-thinking/references/advanced-strategies.md +79 -0
- package/templates/.claude/skills/sequential-thinking/references/advanced-techniques.md +76 -0
- package/templates/.claude/skills/sequential-thinking/references/core-patterns.md +95 -0
- package/templates/.claude/skills/sequential-thinking/references/examples-api.md +88 -0
- package/templates/.claude/skills/sequential-thinking/references/examples-architecture.md +94 -0
- package/templates/.claude/skills/sequential-thinking/references/examples-debug.md +90 -0
- package/templates/.claude/skills/sequential-thinking/scripts/format-thought.js +159 -0
- package/templates/.claude/skills/sequential-thinking/scripts/process-thought.js +236 -0
- package/templates/.claude/skills/sequential-thinking/tests/format-thought.test.js +133 -0
- package/templates/.claude/skills/sequential-thinking/tests/process-thought.test.js +215 -0
- package/templates/.claude/skills/test-automation/SKILL.md +93 -0
- package/templates/.claude/skills/test-automation/examples/page-object.ts +44 -0
- package/templates/.claude/skills/test-automation/references/frameworks.md +96 -0
- package/templates/.claude/skills/test-data-management/SKILL.md +24 -0
- package/templates/.claude/skills/test-design/SKILL.md +25 -0
- package/templates/.claude/skills/typescript-pro/SKILL.md +84 -0
- package/templates/.claude/skills/typescript-pro/references/advanced-patterns.md +100 -0
- package/templates/.claude/skills/typescript-pro/references/best-practices.md +96 -0
- package/templates/.claude/skills/typescript-pro/references/conditional-types.md +85 -0
- package/templates/.claude/skills/typescript-pro/references/generics.md +97 -0
- package/templates/.claude/skills/typescript-pro/references/mapped-types.md +99 -0
- package/templates/.claude/skills/typescript-pro/references/template-literals.md +85 -0
- package/templates/.claude/skills/typescript-pro/references/type-inference.md +94 -0
- package/templates/.claude/skills/typescript-pro/references/utility-types.md +96 -0
- package/templates/.claude/skills/ui-testing/SKILL.md +24 -0
- package/templates/.claude/skills/ui-ux-pro-max/SKILL.md +229 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/templates/.claude/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/templates/.claude/skills/ui-ux-pro-max/scripts/core.py +236 -0
- package/templates/.claude/skills/ui-ux-pro-max/scripts/search.py +61 -0
- package/templates/.claude/skills/webdriverio/SKILL.md +433 -0
- package/templates/.claude/skills/webdriverio/examples/mobile.page.ts +369 -0
- package/templates/.claude/skills/webdriverio/references/capabilities.md +377 -0
- package/templates/.claude/statusline.cjs +105 -0
- package/templates/.claude/statusline.ps1 +187 -0
- package/templates/.claude/statusline.sh +161 -0
- package/templates/.claude/workflows/api-testing-workflow.md +36 -0
- package/templates/.claude/workflows/bug-investigation-workflow.md +42 -0
- package/templates/.claude/workflows/development-rules.md +366 -0
- package/templates/.claude/workflows/documentation-management.md +128 -0
- package/templates/.claude/workflows/e2e-testing-workflow.md +36 -0
- package/templates/.claude/workflows/orchestration-protocol.md +16 -0
- package/templates/.claude/workflows/performance-testing-workflow.md +42 -0
- package/templates/.claude/workflows/primary-workflow.md +45 -0
- package/templates/.claude/workflows/qa-primary-workflow.md +48 -0
- package/templates/.claude/workflows/qa-rules.md +42 -0
- package/templates/.claude/workflows/regression-testing-workflow.md +36 -0
- package/templates/.claude/workflows/test-driven-qa-workflow.md +37 -0
- package/templates/.codex/config.toml.template +29 -0
- package/templates/.codex/prompts/qa-commands.md +32 -0
- package/templates/.codex/prompts/test-generation.md +29 -0
- package/templates/.cursor/CHANGELOG.md +540 -0
- package/templates/.cursor/README.md +261 -0
- package/templates/.cursor/commands/devkit/ask.md +71 -0
- package/templates/.cursor/commands/devkit/backend/create-api.md +207 -0
- package/templates/.cursor/commands/devkit/backend/create-migration.md +169 -0
- package/templates/.cursor/commands/devkit/backend/create-schema.md +183 -0
- package/templates/.cursor/commands/devkit/backend/design-graphql-api.md +287 -0
- package/templates/.cursor/commands/devkit/backend/design-rest-api.md +219 -0
- package/templates/.cursor/commands/devkit/config/init-backend.md +219 -0
- package/templates/.cursor/commands/devkit/config/init-frontend.md +114 -0
- package/templates/.cursor/commands/devkit/create-api-integration.md +196 -0
- package/templates/.cursor/commands/devkit/create-component.md +104 -0
- package/templates/.cursor/commands/devkit/create-form.md +189 -0
- package/templates/.cursor/commands/devkit/create-page.md +111 -0
- package/templates/.cursor/commands/devkit/create-storybook.md +235 -0
- package/templates/.cursor/commands/devkit/create-table.md +251 -0
- package/templates/.cursor/commands/devkit/create-test.md +174 -0
- package/templates/.cursor/commands/devkit/debug.md +192 -0
- package/templates/.cursor/commands/devkit/docs/capture-knowledge.md +252 -0
- package/templates/.cursor/commands/devkit/docs/init.md +153 -0
- package/templates/.cursor/commands/devkit/docs/summarize.md +82 -0
- package/templates/.cursor/commands/devkit/docs/update.md +174 -0
- package/templates/.cursor/commands/devkit/fix.md +24 -0
- package/templates/.cursor/commands/devkit/help.md +148 -0
- package/templates/.cursor/commands/devkit/refactor.md +476 -0
- package/templates/.cursor/commands/devkit/research.md +135 -0
- package/templates/.cursor/commands/devkit/review/code.md +297 -0
- package/templates/.cursor/commands/devkit/review/codebase.md +37 -0
- package/templates/.cursor/commands/devkit/scout.md +103 -0
- package/templates/.cursor/commands/devkit/solve.md +355 -0
- package/templates/.cursor/commands/devkit/spec/brainstorm.md +184 -0
- package/templates/.cursor/commands/devkit/spec/capture-requirement.md +164 -0
- package/templates/.cursor/commands/devkit/spec/cook.md +101 -0
- package/templates/.cursor/commands/devkit/spec/deep-capture-requirement.md +149 -0
- package/templates/.cursor/commands/devkit/spec/implement.md +354 -0
- package/templates/.cursor/commands/devkit/spec/plan.md +317 -0
- package/templates/.cursor/commands/devkit/spec/task.md +150 -0
- package/templates/.cursor/commands/devkit/spec/test.md +203 -0
- package/templates/.cursor/commands/devkit/spec/update-plan.md +234 -0
- package/templates/.cursor/commands/devkit/spec/update-requirement.md +222 -0
- package/templates/.cursor/commands/devkit/spec-lite/do.md +154 -0
- package/templates/.cursor/commands/devkit/spec-lite/plan.md +197 -0
- package/templates/.cursor/commands/devkit/spec-lite/task.md +138 -0
- package/templates/.cursor/commands/devkit/spec-lite/test.md +129 -0
- package/templates/.cursor/commands/devkit/spec-lite/update-plan.md +133 -0
- package/templates/.cursor/commands/devkit/ui-ux-pro-max.md +226 -0
- package/templates/.cursor/doc-templates/code-standards.md +486 -0
- package/templates/.cursor/doc-templates/codebase-summary.md +426 -0
- package/templates/.cursor/doc-templates/development-rules.md +553 -0
- package/templates/.cursor/doc-templates/project-overview-pdr.md +494 -0
- package/templates/.cursor/doc-templates/system-architecture.md +615 -0
- package/templates/.cursor/doc-templates/technical-documents.md +127 -0
- package/templates/.cursor/repomix.config.json +34 -0
- package/templates/.cursor/rules/backend-development/backend-development.mdc +94 -0
- package/templates/.cursor/rules/backend-development/references/backend-api-design.md +495 -0
- package/templates/.cursor/rules/backend-development/references/backend-architecture.md +454 -0
- package/templates/.cursor/rules/backend-development/references/backend-code-quality.md +659 -0
- package/templates/.cursor/rules/backend-development/references/backend-debugging.md +904 -0
- package/templates/.cursor/rules/backend-development/references/backend-devops.md +494 -0
- package/templates/.cursor/rules/backend-development/references/backend-mindset.md +387 -0
- package/templates/.cursor/rules/backend-development/references/backend-performance.md +397 -0
- package/templates/.cursor/rules/backend-development/references/backend-security.md +290 -0
- package/templates/.cursor/rules/backend-development/references/backend-technologies.md +256 -0
- package/templates/.cursor/rules/backend-development/references/backend-testing.md +429 -0
- package/templates/.cursor/rules/brainstormer.mdc +147 -0
- package/templates/.cursor/rules/code-optimizer.mdc +132 -0
- package/templates/.cursor/rules/code-review/code-revew.mdc +144 -0
- package/templates/.cursor/rules/code-review/references/code-review-reception.md +209 -0
- package/templates/.cursor/rules/code-review/references/requesting-code-review.md +105 -0
- package/templates/.cursor/rules/code-review/references/verification-before-completion.md +139 -0
- package/templates/.cursor/rules/code-reviewer.mdc +85 -0
- package/templates/.cursor/rules/code-simplifier.mdc +121 -0
- package/templates/.cursor/rules/coder.mdc +86 -0
- package/templates/.cursor/rules/community-rules.mdc +38 -0
- package/templates/.cursor/rules/cunningham.mdc +114 -0
- package/templates/.cursor/rules/debugger.mdc +108 -0
- package/templates/.cursor/rules/development-rules.mdc +208 -0
- package/templates/.cursor/rules/docs-manager.mdc +121 -0
- package/templates/.cursor/rules/docs-seeker/docs-seeker.mdc +57 -0
- package/templates/.cursor/rules/docs-seeker/references/advanced.md +80 -0
- package/templates/.cursor/rules/docs-seeker/references/context7-patterns.md +69 -0
- package/templates/.cursor/rules/docs-seeker/references/errors.md +69 -0
- package/templates/.cursor/rules/docs-seeker/scripts/analyze-llms-txt.js +211 -0
- package/templates/.cursor/rules/docs-seeker/scripts/detect-topic.js +172 -0
- package/templates/.cursor/rules/docs-seeker/scripts/fetch-docs.js +213 -0
- package/templates/.cursor/rules/docs-seeker/scripts/tests/run-tests.js +72 -0
- package/templates/.cursor/rules/docs-seeker/scripts/tests/test-analyze-llms.js +119 -0
- package/templates/.cursor/rules/docs-seeker/scripts/tests/test-detect-topic.js +112 -0
- package/templates/.cursor/rules/docs-seeker/scripts/tests/test-fetch-docs.js +84 -0
- package/templates/.cursor/rules/docs-seeker/scripts/utils/env-loader.js +94 -0
- package/templates/.cursor/rules/docs-seeker/workflows/library-search.md +88 -0
- package/templates/.cursor/rules/docs-seeker/workflows/repo-analysis.md +92 -0
- package/templates/.cursor/rules/docs-seeker/workflows/topic-search.md +78 -0
- package/templates/.cursor/rules/frontend-development/frontend-development.mdc +131 -0
- package/templates/.cursor/rules/frontend-development/references/accessibility.md +719 -0
- package/templates/.cursor/rules/frontend-development/references/data-fetching.md +412 -0
- package/templates/.cursor/rules/frontend-development/references/forms.md +808 -0
- package/templates/.cursor/rules/frontend-development/references/fsd-architecture.md +442 -0
- package/templates/.cursor/rules/frontend-development/references/graphql-apollo.md +730 -0
- package/templates/.cursor/rules/frontend-development/references/performance.md +417 -0
- package/templates/.cursor/rules/frontend-development/references/react-patterns.md +451 -0
- package/templates/.cursor/rules/frontend-development/references/routing.md +436 -0
- package/templates/.cursor/rules/frontend-development/references/state-management.md +511 -0
- package/templates/.cursor/rules/frontend-development/references/tailwind-css.md +398 -0
- package/templates/.cursor/rules/frontend-development/references/testing.md +629 -0
- package/templates/.cursor/rules/frontend-development/references/typescript-standards.md +364 -0
- package/templates/.cursor/rules/frontend-development/references/ui-libraries.md +587 -0
- package/templates/.cursor/rules/javascript-pro/javascript-pro.mdc +98 -0
- package/templates/.cursor/rules/javascript-pro/references/async-patterns.md +96 -0
- package/templates/.cursor/rules/javascript-pro/references/best-practices.md +98 -0
- package/templates/.cursor/rules/javascript-pro/references/design-patterns.md +100 -0
- package/templates/.cursor/rules/javascript-pro/references/error-handling.md +100 -0
- package/templates/.cursor/rules/javascript-pro/references/functional-patterns.md +93 -0
- package/templates/.cursor/rules/javascript-pro/references/modern-syntax.md +100 -0
- package/templates/.cursor/rules/javascript-pro/references/performance.md +98 -0
- package/templates/.cursor/rules/planner.mdc +87 -0
- package/templates/.cursor/rules/problem-solving/problem-solving.mdc +96 -0
- package/templates/.cursor/rules/problem-solving/references/attribution.md +69 -0
- package/templates/.cursor/rules/problem-solving/references/collision-zone-thinking.md +79 -0
- package/templates/.cursor/rules/problem-solving/references/inversion-exercise.md +91 -0
- package/templates/.cursor/rules/problem-solving/references/meta-pattern-recognition.md +87 -0
- package/templates/.cursor/rules/problem-solving/references/scale-game.md +95 -0
- package/templates/.cursor/rules/problem-solving/references/simplification-cascades.md +80 -0
- package/templates/.cursor/rules/problem-solving/references/when-stuck.md +72 -0
- package/templates/.cursor/rules/project-manager.mdc +116 -0
- package/templates/.cursor/rules/project-profile.mdc +54 -0
- package/templates/.cursor/rules/python-pro/python-pro.mdc +83 -0
- package/templates/.cursor/rules/python-pro/references/async-patterns.md +96 -0
- package/templates/.cursor/rules/python-pro/references/error-handling.md +84 -0
- package/templates/.cursor/rules/python-pro/references/performance.md +71 -0
- package/templates/.cursor/rules/python-pro/references/project-setup.md +78 -0
- package/templates/.cursor/rules/python-pro/references/security.md +73 -0
- package/templates/.cursor/rules/python-pro/references/testing.md +90 -0
- package/templates/.cursor/rules/python-pro/references/type-system.md +88 -0
- package/templates/.cursor/rules/qa-api-testing.mdc +25 -0
- package/templates/.cursor/rules/qa-automation.mdc +28 -0
- package/templates/.cursor/rules/qa-testing.mdc +28 -0
- package/templates/.cursor/rules/repomix/references/configuration.md +211 -0
- package/templates/.cursor/rules/repomix/references/usage-patterns.md +232 -0
- package/templates/.cursor/rules/repomix/repomix.mdc +248 -0
- package/templates/.cursor/rules/repomix/scripts/README.md +179 -0
- package/templates/.cursor/rules/repomix/scripts/repomix_batch.py +455 -0
- package/templates/.cursor/rules/repomix/scripts/repos.example.json +15 -0
- package/templates/.cursor/rules/repomix/scripts/requirements.txt +15 -0
- package/templates/.cursor/rules/repomix/scripts/tests/test_repomix_batch.py +531 -0
- package/templates/.cursor/rules/research/research.mdc +111 -0
- package/templates/.cursor/rules/researcher.mdc +54 -0
- package/templates/.cursor/rules/scout.mdc +105 -0
- package/templates/.cursor/rules/security-agent.mdc +122 -0
- package/templates/.cursor/rules/security.mdc +90 -0
- package/templates/.cursor/rules/sequential-thinking/references/advanced-strategies.md +80 -0
- package/templates/.cursor/rules/sequential-thinking/references/advanced-techniques.md +77 -0
- package/templates/.cursor/rules/sequential-thinking/references/core-patterns.md +96 -0
- package/templates/.cursor/rules/sequential-thinking/references/examples-api.md +89 -0
- package/templates/.cursor/rules/sequential-thinking/references/examples-architecture.md +95 -0
- package/templates/.cursor/rules/sequential-thinking/references/examples-debug.md +91 -0
- package/templates/.cursor/rules/sequential-thinking/scripts/format-thought.js +159 -0
- package/templates/.cursor/rules/sequential-thinking/scripts/process-thought.js +236 -0
- package/templates/.cursor/rules/sequential-thinking/sequential-thinking.mdc +86 -0
- package/templates/.cursor/rules/tattletale-reporter.mdc +64 -0
- package/templates/.cursor/rules/tester.mdc +221 -0
- package/templates/.cursor/rules/testing.mdc +215 -0
- package/templates/.cursor/rules/typescript-pro/references/advanced-patterns.md +100 -0
- package/templates/.cursor/rules/typescript-pro/references/best-practices.md +96 -0
- package/templates/.cursor/rules/typescript-pro/references/conditional-types.md +85 -0
- package/templates/.cursor/rules/typescript-pro/references/generics.md +97 -0
- package/templates/.cursor/rules/typescript-pro/references/mapped-types.md +99 -0
- package/templates/.cursor/rules/typescript-pro/references/template-literals.md +85 -0
- package/templates/.cursor/rules/typescript-pro/references/type-inference.md +94 -0
- package/templates/.cursor/rules/typescript-pro/references/utility-types.md +96 -0
- package/templates/.cursor/rules/typescript-pro/typescript-pro.mdc +101 -0
- package/templates/.cursor/rules/typescript-pro.mdc +129 -0
- package/templates/.cursor/rules/ui-ux-designer.mdc +117 -0
- package/templates/.cursor/scripts/helper.py +723 -0
- package/templates/.cursor/settings.json +5 -0
- package/templates/.kiro/steering/qa-standards.md +84 -0
- package/templates/.kiro/steering/test-patterns.md +62 -0
- package/templates/.kiro/steering/tool-integration.md +73 -0
|
@@ -0,0 +1,951 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base validator with common validation logic for document files.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import lxml.etree
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BaseSchemaValidator:
|
|
12
|
+
"""Base validator with common validation logic for document files."""
|
|
13
|
+
|
|
14
|
+
# Elements whose 'id' attributes must be unique within their file
|
|
15
|
+
# Format: element_name -> (attribute_name, scope)
|
|
16
|
+
# scope can be 'file' (unique within file) or 'global' (unique across all files)
|
|
17
|
+
UNIQUE_ID_REQUIREMENTS = {
|
|
18
|
+
# Word elements
|
|
19
|
+
"comment": ("id", "file"), # Comment IDs in comments.xml
|
|
20
|
+
"commentrangestart": ("id", "file"), # Must match comment IDs
|
|
21
|
+
"commentrangeend": ("id", "file"), # Must match comment IDs
|
|
22
|
+
"bookmarkstart": ("id", "file"), # Bookmark start IDs
|
|
23
|
+
"bookmarkend": ("id", "file"), # Bookmark end IDs
|
|
24
|
+
# Note: ins and del (track changes) can share IDs when part of same revision
|
|
25
|
+
# PowerPoint elements
|
|
26
|
+
"sldid": ("id", "file"), # Slide IDs in presentation.xml
|
|
27
|
+
"sldmasterid": ("id", "global"), # Slide master IDs must be globally unique
|
|
28
|
+
"sldlayoutid": ("id", "global"), # Slide layout IDs must be globally unique
|
|
29
|
+
"cm": ("authorid", "file"), # Comment author IDs
|
|
30
|
+
# Excel elements
|
|
31
|
+
"sheet": ("sheetid", "file"), # Sheet IDs in workbook.xml
|
|
32
|
+
"definedname": ("id", "file"), # Named range IDs
|
|
33
|
+
# Drawing/Shape elements (all formats)
|
|
34
|
+
"cxnsp": ("id", "file"), # Connection shape IDs
|
|
35
|
+
"sp": ("id", "file"), # Shape IDs
|
|
36
|
+
"pic": ("id", "file"), # Picture IDs
|
|
37
|
+
"grpsp": ("id", "file"), # Group shape IDs
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Mapping of element names to expected relationship types
|
|
41
|
+
# Subclasses should override this with format-specific mappings
|
|
42
|
+
ELEMENT_RELATIONSHIP_TYPES = {}
|
|
43
|
+
|
|
44
|
+
# Unified schema mappings for all Office document types
|
|
45
|
+
SCHEMA_MAPPINGS = {
|
|
46
|
+
# Document type specific schemas
|
|
47
|
+
"word": "ISO-IEC29500-4_2016/wml.xsd", # Word documents
|
|
48
|
+
"ppt": "ISO-IEC29500-4_2016/pml.xsd", # PowerPoint presentations
|
|
49
|
+
"xl": "ISO-IEC29500-4_2016/sml.xsd", # Excel spreadsheets
|
|
50
|
+
# Common file types
|
|
51
|
+
"[Content_Types].xml": "ecma/fouth-edition/opc-contentTypes.xsd",
|
|
52
|
+
"app.xml": "ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd",
|
|
53
|
+
"core.xml": "ecma/fouth-edition/opc-coreProperties.xsd",
|
|
54
|
+
"custom.xml": "ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd",
|
|
55
|
+
".rels": "ecma/fouth-edition/opc-relationships.xsd",
|
|
56
|
+
# Word-specific files
|
|
57
|
+
"people.xml": "microsoft/wml-2012.xsd",
|
|
58
|
+
"commentsIds.xml": "microsoft/wml-cid-2016.xsd",
|
|
59
|
+
"commentsExtensible.xml": "microsoft/wml-cex-2018.xsd",
|
|
60
|
+
"commentsExtended.xml": "microsoft/wml-2012.xsd",
|
|
61
|
+
# Chart files (common across document types)
|
|
62
|
+
"chart": "ISO-IEC29500-4_2016/dml-chart.xsd",
|
|
63
|
+
# Theme files (common across document types)
|
|
64
|
+
"theme": "ISO-IEC29500-4_2016/dml-main.xsd",
|
|
65
|
+
# Drawing and media files
|
|
66
|
+
"drawing": "ISO-IEC29500-4_2016/dml-main.xsd",
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Unified namespace constants
|
|
70
|
+
MC_NAMESPACE = "http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
71
|
+
XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace"
|
|
72
|
+
|
|
73
|
+
# Common OOXML namespaces used across validators
|
|
74
|
+
PACKAGE_RELATIONSHIPS_NAMESPACE = (
|
|
75
|
+
"http://schemas.openxmlformats.org/package/2006/relationships"
|
|
76
|
+
)
|
|
77
|
+
OFFICE_RELATIONSHIPS_NAMESPACE = (
|
|
78
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
79
|
+
)
|
|
80
|
+
CONTENT_TYPES_NAMESPACE = (
|
|
81
|
+
"http://schemas.openxmlformats.org/package/2006/content-types"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Folders where we should clean ignorable namespaces
|
|
85
|
+
MAIN_CONTENT_FOLDERS = {"word", "ppt", "xl"}
|
|
86
|
+
|
|
87
|
+
# All allowed OOXML namespaces (superset of all document types)
|
|
88
|
+
OOXML_NAMESPACES = {
|
|
89
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/math",
|
|
90
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
|
91
|
+
"http://schemas.openxmlformats.org/schemaLibrary/2006/main",
|
|
92
|
+
"http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
93
|
+
"http://schemas.openxmlformats.org/drawingml/2006/chart",
|
|
94
|
+
"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing",
|
|
95
|
+
"http://schemas.openxmlformats.org/drawingml/2006/diagram",
|
|
96
|
+
"http://schemas.openxmlformats.org/drawingml/2006/picture",
|
|
97
|
+
"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
|
|
98
|
+
"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
|
|
99
|
+
"http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
|
100
|
+
"http://schemas.openxmlformats.org/presentationml/2006/main",
|
|
101
|
+
"http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
|
102
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes",
|
|
103
|
+
"http://www.w3.org/XML/1998/namespace",
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
def __init__(self, unpacked_dir, original_file, verbose=False):
|
|
107
|
+
self.unpacked_dir = Path(unpacked_dir).resolve()
|
|
108
|
+
self.original_file = Path(original_file)
|
|
109
|
+
self.verbose = verbose
|
|
110
|
+
|
|
111
|
+
# Set schemas directory
|
|
112
|
+
self.schemas_dir = Path(__file__).parent.parent.parent / "schemas"
|
|
113
|
+
|
|
114
|
+
# Get all XML and .rels files
|
|
115
|
+
patterns = ["*.xml", "*.rels"]
|
|
116
|
+
self.xml_files = [
|
|
117
|
+
f for pattern in patterns for f in self.unpacked_dir.rglob(pattern)
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
if not self.xml_files:
|
|
121
|
+
print(f"Warning: No XML files found in {self.unpacked_dir}")
|
|
122
|
+
|
|
123
|
+
def validate(self):
|
|
124
|
+
"""Run all validation checks and return True if all pass."""
|
|
125
|
+
raise NotImplementedError("Subclasses must implement the validate method")
|
|
126
|
+
|
|
127
|
+
def validate_xml(self):
|
|
128
|
+
"""Validate that all XML files are well-formed."""
|
|
129
|
+
errors = []
|
|
130
|
+
|
|
131
|
+
for xml_file in self.xml_files:
|
|
132
|
+
try:
|
|
133
|
+
# Try to parse the XML file
|
|
134
|
+
lxml.etree.parse(str(xml_file))
|
|
135
|
+
except lxml.etree.XMLSyntaxError as e:
|
|
136
|
+
errors.append(
|
|
137
|
+
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
|
138
|
+
f"Line {e.lineno}: {e.msg}"
|
|
139
|
+
)
|
|
140
|
+
except Exception as e:
|
|
141
|
+
errors.append(
|
|
142
|
+
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
|
143
|
+
f"Unexpected error: {str(e)}"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
if errors:
|
|
147
|
+
print(f"FAILED - Found {len(errors)} XML violations:")
|
|
148
|
+
for error in errors:
|
|
149
|
+
print(error)
|
|
150
|
+
return False
|
|
151
|
+
else:
|
|
152
|
+
if self.verbose:
|
|
153
|
+
print("PASSED - All XML files are well-formed")
|
|
154
|
+
return True
|
|
155
|
+
|
|
156
|
+
def validate_namespaces(self):
|
|
157
|
+
"""Validate that namespace prefixes in Ignorable attributes are declared."""
|
|
158
|
+
errors = []
|
|
159
|
+
|
|
160
|
+
for xml_file in self.xml_files:
|
|
161
|
+
try:
|
|
162
|
+
root = lxml.etree.parse(str(xml_file)).getroot()
|
|
163
|
+
declared = set(root.nsmap.keys()) - {None} # Exclude default namespace
|
|
164
|
+
|
|
165
|
+
for attr_val in [
|
|
166
|
+
v for k, v in root.attrib.items() if k.endswith("Ignorable")
|
|
167
|
+
]:
|
|
168
|
+
undeclared = set(attr_val.split()) - declared
|
|
169
|
+
errors.extend(
|
|
170
|
+
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
|
171
|
+
f"Namespace '{ns}' in Ignorable but not declared"
|
|
172
|
+
for ns in undeclared
|
|
173
|
+
)
|
|
174
|
+
except lxml.etree.XMLSyntaxError:
|
|
175
|
+
continue
|
|
176
|
+
|
|
177
|
+
if errors:
|
|
178
|
+
print(f"FAILED - {len(errors)} namespace issues:")
|
|
179
|
+
for error in errors:
|
|
180
|
+
print(error)
|
|
181
|
+
return False
|
|
182
|
+
if self.verbose:
|
|
183
|
+
print("PASSED - All namespace prefixes properly declared")
|
|
184
|
+
return True
|
|
185
|
+
|
|
186
|
+
def validate_unique_ids(self):
|
|
187
|
+
"""Validate that specific IDs are unique according to OOXML requirements."""
|
|
188
|
+
errors = []
|
|
189
|
+
global_ids = {} # Track globally unique IDs across all files
|
|
190
|
+
|
|
191
|
+
for xml_file in self.xml_files:
|
|
192
|
+
try:
|
|
193
|
+
root = lxml.etree.parse(str(xml_file)).getroot()
|
|
194
|
+
file_ids = {} # Track IDs that must be unique within this file
|
|
195
|
+
|
|
196
|
+
# Remove all mc:AlternateContent elements from the tree
|
|
197
|
+
mc_elements = root.xpath(
|
|
198
|
+
".//mc:AlternateContent", namespaces={"mc": self.MC_NAMESPACE}
|
|
199
|
+
)
|
|
200
|
+
for elem in mc_elements:
|
|
201
|
+
elem.getparent().remove(elem)
|
|
202
|
+
|
|
203
|
+
# Now check IDs in the cleaned tree
|
|
204
|
+
for elem in root.iter():
|
|
205
|
+
# Get the element name without namespace
|
|
206
|
+
tag = (
|
|
207
|
+
elem.tag.split("}")[-1].lower()
|
|
208
|
+
if "}" in elem.tag
|
|
209
|
+
else elem.tag.lower()
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
# Check if this element type has ID uniqueness requirements
|
|
213
|
+
if tag in self.UNIQUE_ID_REQUIREMENTS:
|
|
214
|
+
attr_name, scope = self.UNIQUE_ID_REQUIREMENTS[tag]
|
|
215
|
+
|
|
216
|
+
# Look for the specified attribute
|
|
217
|
+
id_value = None
|
|
218
|
+
for attr, value in elem.attrib.items():
|
|
219
|
+
attr_local = (
|
|
220
|
+
attr.split("}")[-1].lower()
|
|
221
|
+
if "}" in attr
|
|
222
|
+
else attr.lower()
|
|
223
|
+
)
|
|
224
|
+
if attr_local == attr_name:
|
|
225
|
+
id_value = value
|
|
226
|
+
break
|
|
227
|
+
|
|
228
|
+
if id_value is not None:
|
|
229
|
+
if scope == "global":
|
|
230
|
+
# Check global uniqueness
|
|
231
|
+
if id_value in global_ids:
|
|
232
|
+
prev_file, prev_line, prev_tag = global_ids[
|
|
233
|
+
id_value
|
|
234
|
+
]
|
|
235
|
+
errors.append(
|
|
236
|
+
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
|
237
|
+
f"Line {elem.sourceline}: Global ID '{id_value}' in <{tag}> "
|
|
238
|
+
f"already used in {prev_file} at line {prev_line} in <{prev_tag}>"
|
|
239
|
+
)
|
|
240
|
+
else:
|
|
241
|
+
global_ids[id_value] = (
|
|
242
|
+
xml_file.relative_to(self.unpacked_dir),
|
|
243
|
+
elem.sourceline,
|
|
244
|
+
tag,
|
|
245
|
+
)
|
|
246
|
+
elif scope == "file":
|
|
247
|
+
# Check file-level uniqueness
|
|
248
|
+
key = (tag, attr_name)
|
|
249
|
+
if key not in file_ids:
|
|
250
|
+
file_ids[key] = {}
|
|
251
|
+
|
|
252
|
+
if id_value in file_ids[key]:
|
|
253
|
+
prev_line = file_ids[key][id_value]
|
|
254
|
+
errors.append(
|
|
255
|
+
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
|
256
|
+
f"Line {elem.sourceline}: Duplicate {attr_name}='{id_value}' in <{tag}> "
|
|
257
|
+
f"(first occurrence at line {prev_line})"
|
|
258
|
+
)
|
|
259
|
+
else:
|
|
260
|
+
file_ids[key][id_value] = elem.sourceline
|
|
261
|
+
|
|
262
|
+
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
|
263
|
+
errors.append(
|
|
264
|
+
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
if errors:
|
|
268
|
+
print(f"FAILED - Found {len(errors)} ID uniqueness violations:")
|
|
269
|
+
for error in errors:
|
|
270
|
+
print(error)
|
|
271
|
+
return False
|
|
272
|
+
else:
|
|
273
|
+
if self.verbose:
|
|
274
|
+
print("PASSED - All required IDs are unique")
|
|
275
|
+
return True
|
|
276
|
+
|
|
277
|
+
def validate_file_references(self):
|
|
278
|
+
"""
|
|
279
|
+
Validate that all .rels files properly reference files and that all files are referenced.
|
|
280
|
+
"""
|
|
281
|
+
errors = []
|
|
282
|
+
|
|
283
|
+
# Find all .rels files
|
|
284
|
+
rels_files = list(self.unpacked_dir.rglob("*.rels"))
|
|
285
|
+
|
|
286
|
+
if not rels_files:
|
|
287
|
+
if self.verbose:
|
|
288
|
+
print("PASSED - No .rels files found")
|
|
289
|
+
return True
|
|
290
|
+
|
|
291
|
+
# Get all files in the unpacked directory (excluding reference files)
|
|
292
|
+
all_files = []
|
|
293
|
+
for file_path in self.unpacked_dir.rglob("*"):
|
|
294
|
+
if (
|
|
295
|
+
file_path.is_file()
|
|
296
|
+
and file_path.name != "[Content_Types].xml"
|
|
297
|
+
and not file_path.name.endswith(".rels")
|
|
298
|
+
): # This file is not referenced by .rels
|
|
299
|
+
all_files.append(file_path.resolve())
|
|
300
|
+
|
|
301
|
+
# Track all files that are referenced by any .rels file
|
|
302
|
+
all_referenced_files = set()
|
|
303
|
+
|
|
304
|
+
if self.verbose:
|
|
305
|
+
print(
|
|
306
|
+
f"Found {len(rels_files)} .rels files and {len(all_files)} target files"
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
# Check each .rels file
|
|
310
|
+
for rels_file in rels_files:
|
|
311
|
+
try:
|
|
312
|
+
# Parse relationships file
|
|
313
|
+
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
|
314
|
+
|
|
315
|
+
# Get the directory where this .rels file is located
|
|
316
|
+
rels_dir = rels_file.parent
|
|
317
|
+
|
|
318
|
+
# Find all relationships and their targets
|
|
319
|
+
referenced_files = set()
|
|
320
|
+
broken_refs = []
|
|
321
|
+
|
|
322
|
+
for rel in rels_root.findall(
|
|
323
|
+
".//ns:Relationship",
|
|
324
|
+
namespaces={"ns": self.PACKAGE_RELATIONSHIPS_NAMESPACE},
|
|
325
|
+
):
|
|
326
|
+
target = rel.get("Target")
|
|
327
|
+
if target and not target.startswith(
|
|
328
|
+
("http", "mailto:")
|
|
329
|
+
): # Skip external URLs
|
|
330
|
+
# Resolve the target path relative to the .rels file location
|
|
331
|
+
if rels_file.name == ".rels":
|
|
332
|
+
# Root .rels file - targets are relative to unpacked_dir
|
|
333
|
+
target_path = self.unpacked_dir / target
|
|
334
|
+
else:
|
|
335
|
+
# Other .rels files - targets are relative to their parent's parent
|
|
336
|
+
# e.g., word/_rels/document.xml.rels -> targets relative to word/
|
|
337
|
+
base_dir = rels_dir.parent
|
|
338
|
+
target_path = base_dir / target
|
|
339
|
+
|
|
340
|
+
# Normalize the path and check if it exists
|
|
341
|
+
try:
|
|
342
|
+
target_path = target_path.resolve()
|
|
343
|
+
if target_path.exists() and target_path.is_file():
|
|
344
|
+
referenced_files.add(target_path)
|
|
345
|
+
all_referenced_files.add(target_path)
|
|
346
|
+
else:
|
|
347
|
+
broken_refs.append((target, rel.sourceline))
|
|
348
|
+
except (OSError, ValueError):
|
|
349
|
+
broken_refs.append((target, rel.sourceline))
|
|
350
|
+
|
|
351
|
+
# Report broken references
|
|
352
|
+
if broken_refs:
|
|
353
|
+
rel_path = rels_file.relative_to(self.unpacked_dir)
|
|
354
|
+
for broken_ref, line_num in broken_refs:
|
|
355
|
+
errors.append(
|
|
356
|
+
f" {rel_path}: Line {line_num}: Broken reference to {broken_ref}"
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
except Exception as e:
|
|
360
|
+
rel_path = rels_file.relative_to(self.unpacked_dir)
|
|
361
|
+
errors.append(f" Error parsing {rel_path}: {e}")
|
|
362
|
+
|
|
363
|
+
# Check for unreferenced files (files that exist but are not referenced anywhere)
|
|
364
|
+
unreferenced_files = set(all_files) - all_referenced_files
|
|
365
|
+
|
|
366
|
+
if unreferenced_files:
|
|
367
|
+
for unref_file in sorted(unreferenced_files):
|
|
368
|
+
unref_rel_path = unref_file.relative_to(self.unpacked_dir)
|
|
369
|
+
errors.append(f" Unreferenced file: {unref_rel_path}")
|
|
370
|
+
|
|
371
|
+
if errors:
|
|
372
|
+
print(f"FAILED - Found {len(errors)} relationship validation errors:")
|
|
373
|
+
for error in errors:
|
|
374
|
+
print(error)
|
|
375
|
+
print(
|
|
376
|
+
"CRITICAL: These errors will cause the document to appear corrupt. "
|
|
377
|
+
+ "Broken references MUST be fixed, "
|
|
378
|
+
+ "and unreferenced files MUST be referenced or removed."
|
|
379
|
+
)
|
|
380
|
+
return False
|
|
381
|
+
else:
|
|
382
|
+
if self.verbose:
|
|
383
|
+
print(
|
|
384
|
+
"PASSED - All references are valid and all files are properly referenced"
|
|
385
|
+
)
|
|
386
|
+
return True
|
|
387
|
+
|
|
388
|
+
def validate_all_relationship_ids(self):
|
|
389
|
+
"""
|
|
390
|
+
Validate that all r:id attributes in XML files reference existing IDs
|
|
391
|
+
in their corresponding .rels files, and optionally validate relationship types.
|
|
392
|
+
"""
|
|
393
|
+
import lxml.etree
|
|
394
|
+
|
|
395
|
+
errors = []
|
|
396
|
+
|
|
397
|
+
# Process each XML file that might contain r:id references
|
|
398
|
+
for xml_file in self.xml_files:
|
|
399
|
+
# Skip .rels files themselves
|
|
400
|
+
if xml_file.suffix == ".rels":
|
|
401
|
+
continue
|
|
402
|
+
|
|
403
|
+
# Determine the corresponding .rels file
|
|
404
|
+
# For dir/file.xml, it's dir/_rels/file.xml.rels
|
|
405
|
+
rels_dir = xml_file.parent / "_rels"
|
|
406
|
+
rels_file = rels_dir / f"{xml_file.name}.rels"
|
|
407
|
+
|
|
408
|
+
# Skip if there's no corresponding .rels file (that's okay)
|
|
409
|
+
if not rels_file.exists():
|
|
410
|
+
continue
|
|
411
|
+
|
|
412
|
+
try:
|
|
413
|
+
# Parse the .rels file to get valid relationship IDs and their types
|
|
414
|
+
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
|
415
|
+
rid_to_type = {}
|
|
416
|
+
|
|
417
|
+
for rel in rels_root.findall(
|
|
418
|
+
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
|
419
|
+
):
|
|
420
|
+
rid = rel.get("Id")
|
|
421
|
+
rel_type = rel.get("Type", "")
|
|
422
|
+
if rid:
|
|
423
|
+
# Check for duplicate rIds
|
|
424
|
+
if rid in rid_to_type:
|
|
425
|
+
rels_rel_path = rels_file.relative_to(self.unpacked_dir)
|
|
426
|
+
errors.append(
|
|
427
|
+
f" {rels_rel_path}: Line {rel.sourceline}: "
|
|
428
|
+
f"Duplicate relationship ID '{rid}' (IDs must be unique)"
|
|
429
|
+
)
|
|
430
|
+
# Extract just the type name from the full URL
|
|
431
|
+
type_name = (
|
|
432
|
+
rel_type.split("/")[-1] if "/" in rel_type else rel_type
|
|
433
|
+
)
|
|
434
|
+
rid_to_type[rid] = type_name
|
|
435
|
+
|
|
436
|
+
# Parse the XML file to find all r:id references
|
|
437
|
+
xml_root = lxml.etree.parse(str(xml_file)).getroot()
|
|
438
|
+
|
|
439
|
+
# Find all elements with r:id attributes
|
|
440
|
+
for elem in xml_root.iter():
|
|
441
|
+
# Check for r:id attribute (relationship ID)
|
|
442
|
+
rid_attr = elem.get(f"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id")
|
|
443
|
+
if rid_attr:
|
|
444
|
+
xml_rel_path = xml_file.relative_to(self.unpacked_dir)
|
|
445
|
+
elem_name = (
|
|
446
|
+
elem.tag.split("}")[-1] if "}" in elem.tag else elem.tag
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
# Check if the ID exists
|
|
450
|
+
if rid_attr not in rid_to_type:
|
|
451
|
+
errors.append(
|
|
452
|
+
f" {xml_rel_path}: Line {elem.sourceline}: "
|
|
453
|
+
f"<{elem_name}> references non-existent relationship '{rid_attr}' "
|
|
454
|
+
f"(valid IDs: {', '.join(sorted(rid_to_type.keys())[:5])}{'...' if len(rid_to_type) > 5 else ''})"
|
|
455
|
+
)
|
|
456
|
+
# Check if we have type expectations for this element
|
|
457
|
+
elif self.ELEMENT_RELATIONSHIP_TYPES:
|
|
458
|
+
expected_type = self._get_expected_relationship_type(
|
|
459
|
+
elem_name
|
|
460
|
+
)
|
|
461
|
+
if expected_type:
|
|
462
|
+
actual_type = rid_to_type[rid_attr]
|
|
463
|
+
# Check if the actual type matches or contains the expected type
|
|
464
|
+
if expected_type not in actual_type.lower():
|
|
465
|
+
errors.append(
|
|
466
|
+
f" {xml_rel_path}: Line {elem.sourceline}: "
|
|
467
|
+
f"<{elem_name}> references '{rid_attr}' which points to '{actual_type}' "
|
|
468
|
+
f"but should point to a '{expected_type}' relationship"
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
except Exception as e:
|
|
472
|
+
xml_rel_path = xml_file.relative_to(self.unpacked_dir)
|
|
473
|
+
errors.append(f" Error processing {xml_rel_path}: {e}")
|
|
474
|
+
|
|
475
|
+
if errors:
|
|
476
|
+
print(f"FAILED - Found {len(errors)} relationship ID reference errors:")
|
|
477
|
+
for error in errors:
|
|
478
|
+
print(error)
|
|
479
|
+
print("\nThese ID mismatches will cause the document to appear corrupt!")
|
|
480
|
+
return False
|
|
481
|
+
else:
|
|
482
|
+
if self.verbose:
|
|
483
|
+
print("PASSED - All relationship ID references are valid")
|
|
484
|
+
return True
|
|
485
|
+
|
|
486
|
+
def _get_expected_relationship_type(self, element_name):
|
|
487
|
+
"""
|
|
488
|
+
Get the expected relationship type for an element.
|
|
489
|
+
First checks the explicit mapping, then tries pattern detection.
|
|
490
|
+
"""
|
|
491
|
+
# Normalize element name to lowercase
|
|
492
|
+
elem_lower = element_name.lower()
|
|
493
|
+
|
|
494
|
+
# Check explicit mapping first
|
|
495
|
+
if elem_lower in self.ELEMENT_RELATIONSHIP_TYPES:
|
|
496
|
+
return self.ELEMENT_RELATIONSHIP_TYPES[elem_lower]
|
|
497
|
+
|
|
498
|
+
# Try pattern detection for common patterns
|
|
499
|
+
# Pattern 1: Elements ending in "Id" often expect a relationship of the prefix type
|
|
500
|
+
if elem_lower.endswith("id") and len(elem_lower) > 2:
|
|
501
|
+
# e.g., "sldId" -> "sld", "sldMasterId" -> "sldMaster"
|
|
502
|
+
prefix = elem_lower[:-2] # Remove "id"
|
|
503
|
+
# Check if this might be a compound like "sldMasterId"
|
|
504
|
+
if prefix.endswith("master"):
|
|
505
|
+
return prefix.lower()
|
|
506
|
+
elif prefix.endswith("layout"):
|
|
507
|
+
return prefix.lower()
|
|
508
|
+
else:
|
|
509
|
+
# Simple case like "sldId" -> "slide"
|
|
510
|
+
# Common transformations
|
|
511
|
+
if prefix == "sld":
|
|
512
|
+
return "slide"
|
|
513
|
+
return prefix.lower()
|
|
514
|
+
|
|
515
|
+
# Pattern 2: Elements ending in "Reference" expect a relationship of the prefix type
|
|
516
|
+
if elem_lower.endswith("reference") and len(elem_lower) > 9:
|
|
517
|
+
prefix = elem_lower[:-9] # Remove "reference"
|
|
518
|
+
return prefix.lower()
|
|
519
|
+
|
|
520
|
+
return None
|
|
521
|
+
|
|
522
|
+
def validate_content_types(self):
|
|
523
|
+
"""Validate that all content files are properly declared in [Content_Types].xml."""
|
|
524
|
+
errors = []
|
|
525
|
+
|
|
526
|
+
# Find [Content_Types].xml file
|
|
527
|
+
content_types_file = self.unpacked_dir / "[Content_Types].xml"
|
|
528
|
+
if not content_types_file.exists():
|
|
529
|
+
print("FAILED - [Content_Types].xml file not found")
|
|
530
|
+
return False
|
|
531
|
+
|
|
532
|
+
try:
|
|
533
|
+
# Parse and get all declared parts and extensions
|
|
534
|
+
root = lxml.etree.parse(str(content_types_file)).getroot()
|
|
535
|
+
declared_parts = set()
|
|
536
|
+
declared_extensions = set()
|
|
537
|
+
|
|
538
|
+
# Get Override declarations (specific files)
|
|
539
|
+
for override in root.findall(
|
|
540
|
+
f".//{{{self.CONTENT_TYPES_NAMESPACE}}}Override"
|
|
541
|
+
):
|
|
542
|
+
part_name = override.get("PartName")
|
|
543
|
+
if part_name is not None:
|
|
544
|
+
declared_parts.add(part_name.lstrip("/"))
|
|
545
|
+
|
|
546
|
+
# Get Default declarations (by extension)
|
|
547
|
+
for default in root.findall(
|
|
548
|
+
f".//{{{self.CONTENT_TYPES_NAMESPACE}}}Default"
|
|
549
|
+
):
|
|
550
|
+
extension = default.get("Extension")
|
|
551
|
+
if extension is not None:
|
|
552
|
+
declared_extensions.add(extension.lower())
|
|
553
|
+
|
|
554
|
+
# Root elements that require content type declaration
|
|
555
|
+
declarable_roots = {
|
|
556
|
+
"sld",
|
|
557
|
+
"sldLayout",
|
|
558
|
+
"sldMaster",
|
|
559
|
+
"presentation", # PowerPoint
|
|
560
|
+
"document", # Word
|
|
561
|
+
"workbook",
|
|
562
|
+
"worksheet", # Excel
|
|
563
|
+
"theme", # Common
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
# Common media file extensions that should be declared
|
|
567
|
+
media_extensions = {
|
|
568
|
+
"png": "image/png",
|
|
569
|
+
"jpg": "image/jpeg",
|
|
570
|
+
"jpeg": "image/jpeg",
|
|
571
|
+
"gif": "image/gif",
|
|
572
|
+
"bmp": "image/bmp",
|
|
573
|
+
"tiff": "image/tiff",
|
|
574
|
+
"wmf": "image/x-wmf",
|
|
575
|
+
"emf": "image/x-emf",
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
# Get all files in the unpacked directory
|
|
579
|
+
all_files = list(self.unpacked_dir.rglob("*"))
|
|
580
|
+
all_files = [f for f in all_files if f.is_file()]
|
|
581
|
+
|
|
582
|
+
# Check all XML files for Override declarations
|
|
583
|
+
for xml_file in self.xml_files:
|
|
584
|
+
path_str = str(xml_file.relative_to(self.unpacked_dir)).replace(
|
|
585
|
+
"\\", "/"
|
|
586
|
+
)
|
|
587
|
+
|
|
588
|
+
# Skip non-content files
|
|
589
|
+
if any(
|
|
590
|
+
skip in path_str
|
|
591
|
+
for skip in [".rels", "[Content_Types]", "docProps/", "_rels/"]
|
|
592
|
+
):
|
|
593
|
+
continue
|
|
594
|
+
|
|
595
|
+
try:
|
|
596
|
+
root_tag = lxml.etree.parse(str(xml_file)).getroot().tag
|
|
597
|
+
root_name = root_tag.split("}")[-1] if "}" in root_tag else root_tag
|
|
598
|
+
|
|
599
|
+
if root_name in declarable_roots and path_str not in declared_parts:
|
|
600
|
+
errors.append(
|
|
601
|
+
f" {path_str}: File with <{root_name}> root not declared in [Content_Types].xml"
|
|
602
|
+
)
|
|
603
|
+
|
|
604
|
+
except Exception:
|
|
605
|
+
continue # Skip unparseable files
|
|
606
|
+
|
|
607
|
+
# Check all non-XML files for Default extension declarations
|
|
608
|
+
for file_path in all_files:
|
|
609
|
+
# Skip XML files and metadata files (already checked above)
|
|
610
|
+
if file_path.suffix.lower() in {".xml", ".rels"}:
|
|
611
|
+
continue
|
|
612
|
+
if file_path.name == "[Content_Types].xml":
|
|
613
|
+
continue
|
|
614
|
+
if "_rels" in file_path.parts or "docProps" in file_path.parts:
|
|
615
|
+
continue
|
|
616
|
+
|
|
617
|
+
extension = file_path.suffix.lstrip(".").lower()
|
|
618
|
+
if extension and extension not in declared_extensions:
|
|
619
|
+
# Check if it's a known media extension that should be declared
|
|
620
|
+
if extension in media_extensions:
|
|
621
|
+
relative_path = file_path.relative_to(self.unpacked_dir)
|
|
622
|
+
errors.append(
|
|
623
|
+
f' {relative_path}: File with extension \'{extension}\' not declared in [Content_Types].xml - should add: <Default Extension="{extension}" ContentType="{media_extensions[extension]}"/>'
|
|
624
|
+
)
|
|
625
|
+
|
|
626
|
+
except Exception as e:
|
|
627
|
+
errors.append(f" Error parsing [Content_Types].xml: {e}")
|
|
628
|
+
|
|
629
|
+
if errors:
|
|
630
|
+
print(f"FAILED - Found {len(errors)} content type declaration errors:")
|
|
631
|
+
for error in errors:
|
|
632
|
+
print(error)
|
|
633
|
+
return False
|
|
634
|
+
else:
|
|
635
|
+
if self.verbose:
|
|
636
|
+
print(
|
|
637
|
+
"PASSED - All content files are properly declared in [Content_Types].xml"
|
|
638
|
+
)
|
|
639
|
+
return True
|
|
640
|
+
|
|
641
|
+
def validate_file_against_xsd(self, xml_file, verbose=False):
|
|
642
|
+
"""Validate a single XML file against XSD schema, comparing with original.
|
|
643
|
+
|
|
644
|
+
Args:
|
|
645
|
+
xml_file: Path to XML file to validate
|
|
646
|
+
verbose: Enable verbose output
|
|
647
|
+
|
|
648
|
+
Returns:
|
|
649
|
+
tuple: (is_valid, new_errors_set) where is_valid is True/False/None (skipped)
|
|
650
|
+
"""
|
|
651
|
+
# Resolve both paths to handle symlinks
|
|
652
|
+
xml_file = Path(xml_file).resolve()
|
|
653
|
+
unpacked_dir = self.unpacked_dir.resolve()
|
|
654
|
+
|
|
655
|
+
# Validate current file
|
|
656
|
+
is_valid, current_errors = self._validate_single_file_xsd(
|
|
657
|
+
xml_file, unpacked_dir
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
if is_valid is None:
|
|
661
|
+
return None, set() # Skipped
|
|
662
|
+
elif is_valid:
|
|
663
|
+
return True, set() # Valid, no errors
|
|
664
|
+
|
|
665
|
+
# Get errors from original file for this specific file
|
|
666
|
+
original_errors = self._get_original_file_errors(xml_file)
|
|
667
|
+
|
|
668
|
+
# Compare with original (both are guaranteed to be sets here)
|
|
669
|
+
assert current_errors is not None
|
|
670
|
+
new_errors = current_errors - original_errors
|
|
671
|
+
|
|
672
|
+
if new_errors:
|
|
673
|
+
if verbose:
|
|
674
|
+
relative_path = xml_file.relative_to(unpacked_dir)
|
|
675
|
+
print(f"FAILED - {relative_path}: {len(new_errors)} new error(s)")
|
|
676
|
+
for error in list(new_errors)[:3]:
|
|
677
|
+
truncated = error[:250] + "..." if len(error) > 250 else error
|
|
678
|
+
print(f" - {truncated}")
|
|
679
|
+
return False, new_errors
|
|
680
|
+
else:
|
|
681
|
+
# All errors existed in original
|
|
682
|
+
if verbose:
|
|
683
|
+
print(
|
|
684
|
+
f"PASSED - No new errors (original had {len(current_errors)} errors)"
|
|
685
|
+
)
|
|
686
|
+
return True, set()
|
|
687
|
+
|
|
688
|
+
def validate_against_xsd(self):
|
|
689
|
+
"""Validate XML files against XSD schemas, showing only new errors compared to original."""
|
|
690
|
+
new_errors = []
|
|
691
|
+
original_error_count = 0
|
|
692
|
+
valid_count = 0
|
|
693
|
+
skipped_count = 0
|
|
694
|
+
|
|
695
|
+
for xml_file in self.xml_files:
|
|
696
|
+
relative_path = str(xml_file.relative_to(self.unpacked_dir))
|
|
697
|
+
is_valid, new_file_errors = self.validate_file_against_xsd(
|
|
698
|
+
xml_file, verbose=False
|
|
699
|
+
)
|
|
700
|
+
|
|
701
|
+
if is_valid is None:
|
|
702
|
+
skipped_count += 1
|
|
703
|
+
continue
|
|
704
|
+
elif is_valid and not new_file_errors:
|
|
705
|
+
valid_count += 1
|
|
706
|
+
continue
|
|
707
|
+
elif is_valid:
|
|
708
|
+
# Had errors but all existed in original
|
|
709
|
+
original_error_count += 1
|
|
710
|
+
valid_count += 1
|
|
711
|
+
continue
|
|
712
|
+
|
|
713
|
+
# Has new errors
|
|
714
|
+
new_errors.append(f" {relative_path}: {len(new_file_errors)} new error(s)")
|
|
715
|
+
for error in list(new_file_errors)[:3]: # Show first 3 errors
|
|
716
|
+
new_errors.append(
|
|
717
|
+
f" - {error[:250]}..." if len(error) > 250 else f" - {error}"
|
|
718
|
+
)
|
|
719
|
+
|
|
720
|
+
# Print summary
|
|
721
|
+
if self.verbose:
|
|
722
|
+
print(f"Validated {len(self.xml_files)} files:")
|
|
723
|
+
print(f" - Valid: {valid_count}")
|
|
724
|
+
print(f" - Skipped (no schema): {skipped_count}")
|
|
725
|
+
if original_error_count:
|
|
726
|
+
print(f" - With original errors (ignored): {original_error_count}")
|
|
727
|
+
print(
|
|
728
|
+
f" - With NEW errors: {len(new_errors) > 0 and len([e for e in new_errors if not e.startswith(' ')]) or 0}"
|
|
729
|
+
)
|
|
730
|
+
|
|
731
|
+
if new_errors:
|
|
732
|
+
print("\nFAILED - Found NEW validation errors:")
|
|
733
|
+
for error in new_errors:
|
|
734
|
+
print(error)
|
|
735
|
+
return False
|
|
736
|
+
else:
|
|
737
|
+
if self.verbose:
|
|
738
|
+
print("\nPASSED - No new XSD validation errors introduced")
|
|
739
|
+
return True
|
|
740
|
+
|
|
741
|
+
def _get_schema_path(self, xml_file):
|
|
742
|
+
"""Determine the appropriate schema path for an XML file."""
|
|
743
|
+
# Check exact filename match
|
|
744
|
+
if xml_file.name in self.SCHEMA_MAPPINGS:
|
|
745
|
+
return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.name]
|
|
746
|
+
|
|
747
|
+
# Check .rels files
|
|
748
|
+
if xml_file.suffix == ".rels":
|
|
749
|
+
return self.schemas_dir / self.SCHEMA_MAPPINGS[".rels"]
|
|
750
|
+
|
|
751
|
+
# Check chart files
|
|
752
|
+
if "charts/" in str(xml_file) and xml_file.name.startswith("chart"):
|
|
753
|
+
return self.schemas_dir / self.SCHEMA_MAPPINGS["chart"]
|
|
754
|
+
|
|
755
|
+
# Check theme files
|
|
756
|
+
if "theme/" in str(xml_file) and xml_file.name.startswith("theme"):
|
|
757
|
+
return self.schemas_dir / self.SCHEMA_MAPPINGS["theme"]
|
|
758
|
+
|
|
759
|
+
# Check if file is in a main content folder and use appropriate schema
|
|
760
|
+
if xml_file.parent.name in self.MAIN_CONTENT_FOLDERS:
|
|
761
|
+
return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.parent.name]
|
|
762
|
+
|
|
763
|
+
return None
|
|
764
|
+
|
|
765
|
+
def _clean_ignorable_namespaces(self, xml_doc):
|
|
766
|
+
"""Remove attributes and elements not in allowed namespaces."""
|
|
767
|
+
# Create a clean copy
|
|
768
|
+
xml_string = lxml.etree.tostring(xml_doc, encoding="unicode")
|
|
769
|
+
xml_copy = lxml.etree.fromstring(xml_string)
|
|
770
|
+
|
|
771
|
+
# Remove attributes not in allowed namespaces
|
|
772
|
+
for elem in xml_copy.iter():
|
|
773
|
+
attrs_to_remove = []
|
|
774
|
+
|
|
775
|
+
for attr in elem.attrib:
|
|
776
|
+
# Check if attribute is from a namespace other than allowed ones
|
|
777
|
+
if "{" in attr:
|
|
778
|
+
ns = attr.split("}")[0][1:]
|
|
779
|
+
if ns not in self.OOXML_NAMESPACES:
|
|
780
|
+
attrs_to_remove.append(attr)
|
|
781
|
+
|
|
782
|
+
# Remove collected attributes
|
|
783
|
+
for attr in attrs_to_remove:
|
|
784
|
+
del elem.attrib[attr]
|
|
785
|
+
|
|
786
|
+
# Remove elements not in allowed namespaces
|
|
787
|
+
self._remove_ignorable_elements(xml_copy)
|
|
788
|
+
|
|
789
|
+
return lxml.etree.ElementTree(xml_copy)
|
|
790
|
+
|
|
791
|
+
def _remove_ignorable_elements(self, root):
|
|
792
|
+
"""Recursively remove all elements not in allowed namespaces."""
|
|
793
|
+
elements_to_remove = []
|
|
794
|
+
|
|
795
|
+
# Find elements to remove
|
|
796
|
+
for elem in list(root):
|
|
797
|
+
# Skip non-element nodes (comments, processing instructions, etc.)
|
|
798
|
+
if not hasattr(elem, "tag") or callable(elem.tag):
|
|
799
|
+
continue
|
|
800
|
+
|
|
801
|
+
tag_str = str(elem.tag)
|
|
802
|
+
if tag_str.startswith("{"):
|
|
803
|
+
ns = tag_str.split("}")[0][1:]
|
|
804
|
+
if ns not in self.OOXML_NAMESPACES:
|
|
805
|
+
elements_to_remove.append(elem)
|
|
806
|
+
continue
|
|
807
|
+
|
|
808
|
+
# Recursively clean child elements
|
|
809
|
+
self._remove_ignorable_elements(elem)
|
|
810
|
+
|
|
811
|
+
# Remove collected elements
|
|
812
|
+
for elem in elements_to_remove:
|
|
813
|
+
root.remove(elem)
|
|
814
|
+
|
|
815
|
+
def _preprocess_for_mc_ignorable(self, xml_doc):
|
|
816
|
+
"""Preprocess XML to handle mc:Ignorable attribute properly."""
|
|
817
|
+
# Remove mc:Ignorable attributes before validation
|
|
818
|
+
root = xml_doc.getroot()
|
|
819
|
+
|
|
820
|
+
# Remove mc:Ignorable attribute from root
|
|
821
|
+
if f"{{{self.MC_NAMESPACE}}}Ignorable" in root.attrib:
|
|
822
|
+
del root.attrib[f"{{{self.MC_NAMESPACE}}}Ignorable"]
|
|
823
|
+
|
|
824
|
+
return xml_doc
|
|
825
|
+
|
|
826
|
+
def _validate_single_file_xsd(self, xml_file, base_path):
|
|
827
|
+
"""Validate a single XML file against XSD schema. Returns (is_valid, errors_set)."""
|
|
828
|
+
schema_path = self._get_schema_path(xml_file)
|
|
829
|
+
if not schema_path:
|
|
830
|
+
return None, None # Skip file
|
|
831
|
+
|
|
832
|
+
try:
|
|
833
|
+
# Load schema
|
|
834
|
+
with open(schema_path, "rb") as xsd_file:
|
|
835
|
+
parser = lxml.etree.XMLParser()
|
|
836
|
+
xsd_doc = lxml.etree.parse(
|
|
837
|
+
xsd_file, parser=parser, base_url=str(schema_path)
|
|
838
|
+
)
|
|
839
|
+
schema = lxml.etree.XMLSchema(xsd_doc)
|
|
840
|
+
|
|
841
|
+
# Load and preprocess XML
|
|
842
|
+
with open(xml_file, "r") as f:
|
|
843
|
+
xml_doc = lxml.etree.parse(f)
|
|
844
|
+
|
|
845
|
+
xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)
|
|
846
|
+
xml_doc = self._preprocess_for_mc_ignorable(xml_doc)
|
|
847
|
+
|
|
848
|
+
# Clean ignorable namespaces if needed
|
|
849
|
+
relative_path = xml_file.relative_to(base_path)
|
|
850
|
+
if (
|
|
851
|
+
relative_path.parts
|
|
852
|
+
and relative_path.parts[0] in self.MAIN_CONTENT_FOLDERS
|
|
853
|
+
):
|
|
854
|
+
xml_doc = self._clean_ignorable_namespaces(xml_doc)
|
|
855
|
+
|
|
856
|
+
# Validate
|
|
857
|
+
if schema.validate(xml_doc):
|
|
858
|
+
return True, set()
|
|
859
|
+
else:
|
|
860
|
+
errors = set()
|
|
861
|
+
for error in schema.error_log:
|
|
862
|
+
# Store normalized error message (without line numbers for comparison)
|
|
863
|
+
errors.add(error.message)
|
|
864
|
+
return False, errors
|
|
865
|
+
|
|
866
|
+
except Exception as e:
|
|
867
|
+
return False, {str(e)}
|
|
868
|
+
|
|
869
|
+
def _get_original_file_errors(self, xml_file):
|
|
870
|
+
"""Get XSD validation errors from a single file in the original document.
|
|
871
|
+
|
|
872
|
+
Args:
|
|
873
|
+
xml_file: Path to the XML file in unpacked_dir to check
|
|
874
|
+
|
|
875
|
+
Returns:
|
|
876
|
+
set: Set of error messages from the original file
|
|
877
|
+
"""
|
|
878
|
+
import tempfile
|
|
879
|
+
import zipfile
|
|
880
|
+
|
|
881
|
+
# Resolve both paths to handle symlinks (e.g., /var vs /private/var on macOS)
|
|
882
|
+
xml_file = Path(xml_file).resolve()
|
|
883
|
+
unpacked_dir = self.unpacked_dir.resolve()
|
|
884
|
+
relative_path = xml_file.relative_to(unpacked_dir)
|
|
885
|
+
|
|
886
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
887
|
+
temp_path = Path(temp_dir)
|
|
888
|
+
|
|
889
|
+
# Extract original file
|
|
890
|
+
with zipfile.ZipFile(self.original_file, "r") as zip_ref:
|
|
891
|
+
zip_ref.extractall(temp_path)
|
|
892
|
+
|
|
893
|
+
# Find corresponding file in original
|
|
894
|
+
original_xml_file = temp_path / relative_path
|
|
895
|
+
|
|
896
|
+
if not original_xml_file.exists():
|
|
897
|
+
# File didn't exist in original, so no original errors
|
|
898
|
+
return set()
|
|
899
|
+
|
|
900
|
+
# Validate the specific file in original
|
|
901
|
+
is_valid, errors = self._validate_single_file_xsd(
|
|
902
|
+
original_xml_file, temp_path
|
|
903
|
+
)
|
|
904
|
+
return errors if errors else set()
|
|
905
|
+
|
|
906
|
+
def _remove_template_tags_from_text_nodes(self, xml_doc):
|
|
907
|
+
"""Remove template tags from XML text nodes and collect warnings.
|
|
908
|
+
|
|
909
|
+
Template tags follow the pattern {{ ... }} and are used as placeholders
|
|
910
|
+
for content replacement. They should be removed from text content before
|
|
911
|
+
XSD validation while preserving XML structure.
|
|
912
|
+
|
|
913
|
+
Returns:
|
|
914
|
+
tuple: (cleaned_xml_doc, warnings_list)
|
|
915
|
+
"""
|
|
916
|
+
warnings = []
|
|
917
|
+
template_pattern = re.compile(r"\{\{[^}]*\}\}")
|
|
918
|
+
|
|
919
|
+
# Create a copy of the document to avoid modifying the original
|
|
920
|
+
xml_string = lxml.etree.tostring(xml_doc, encoding="unicode")
|
|
921
|
+
xml_copy = lxml.etree.fromstring(xml_string)
|
|
922
|
+
|
|
923
|
+
def process_text_content(text, content_type):
|
|
924
|
+
if not text:
|
|
925
|
+
return text
|
|
926
|
+
matches = list(template_pattern.finditer(text))
|
|
927
|
+
if matches:
|
|
928
|
+
for match in matches:
|
|
929
|
+
warnings.append(
|
|
930
|
+
f"Found template tag in {content_type}: {match.group()}"
|
|
931
|
+
)
|
|
932
|
+
return template_pattern.sub("", text)
|
|
933
|
+
return text
|
|
934
|
+
|
|
935
|
+
# Process all text nodes in the document
|
|
936
|
+
for elem in xml_copy.iter():
|
|
937
|
+
# Skip processing if this is a w:t element
|
|
938
|
+
if not hasattr(elem, "tag") or callable(elem.tag):
|
|
939
|
+
continue
|
|
940
|
+
tag_str = str(elem.tag)
|
|
941
|
+
if tag_str.endswith("}t") or tag_str == "t":
|
|
942
|
+
continue
|
|
943
|
+
|
|
944
|
+
elem.text = process_text_content(elem.text, "text content")
|
|
945
|
+
elem.tail = process_text_content(elem.tail, "tail content")
|
|
946
|
+
|
|
947
|
+
return lxml.etree.ElementTree(xml_copy), warnings
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
if __name__ == "__main__":
|
|
951
|
+
raise RuntimeError("This module should not be run directly.")
|