@vodailoc/kilo-kit-mcp 1.1.0 → 1.2.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/.mcp/kilo-kit.codex-windows.toml +5 -0
- package/LICENSE +190 -190
- package/QUICKSTART.md +265 -255
- package/README.md +321 -267
- package/mcp/README.md +64 -12
- package/mcp/dist/formatters.js +142 -1
- package/mcp/dist/orchestration-audit.js +20 -0
- package/mcp/dist/orchestration-memory.js +258 -0
- package/mcp/dist/orchestration-types.js +1 -0
- package/mcp/dist/orchestrator.js +222 -0
- package/mcp/dist/question-templates.js +249 -0
- package/mcp/dist/route-analytics.js +149 -0
- package/mcp/dist/router.js +75 -82
- package/mcp/dist/routing-policy-data.js +241 -0
- package/mcp/dist/routing-policy.js +145 -0
- package/mcp/dist/server.js +93 -4
- package/mcp/dist/smoke-env.js +18 -0
- package/mcp/dist/smoke.js +68 -1
- package/mcp/package.json +1 -2
- package/package.json +3 -2
- package/skills/README.md +647 -647
- package/skills/SKILLS_INDEX.md +139 -139
- package/skills/ai-media/ai-multimodal/.env.example +97 -97
- package/skills/ai-media/ai-multimodal/SKILL.md +357 -357
- package/skills/ai-media/ai-multimodal/references/audio-processing.md +373 -373
- package/skills/ai-media/ai-multimodal/references/image-generation.md +558 -558
- package/skills/ai-media/ai-multimodal/references/video-analysis.md +502 -502
- package/skills/ai-media/ai-multimodal/references/vision-understanding.md +483 -483
- package/skills/ai-media/ai-multimodal/scripts/document_converter.py +395 -395
- package/skills/ai-media/ai-multimodal/scripts/gemini_batch_process.py +480 -480
- package/skills/ai-media/ai-multimodal/scripts/media_optimizer.py +506 -506
- package/skills/ai-media/ai-multimodal/scripts/requirements.txt +26 -26
- package/skills/ai-media/ai-multimodal/scripts/tests/requirements.txt +20 -20
- package/skills/ai-media/ai-multimodal/scripts/tests/test_document_converter.py +299 -299
- package/skills/ai-media/ai-multimodal/scripts/tests/test_gemini_batch_process.py +362 -362
- package/skills/ai-media/ai-multimodal/scripts/tests/test_media_optimizer.py +373 -373
- package/skills/ai-media/media-processing/SKILL.md +358 -358
- package/skills/ai-media/media-processing/references/ffmpeg-encoding.md +358 -358
- package/skills/ai-media/media-processing/references/ffmpeg-filters.md +503 -503
- package/skills/ai-media/media-processing/references/ffmpeg-streaming.md +403 -403
- package/skills/ai-media/media-processing/references/format-compatibility.md +375 -375
- package/skills/ai-media/media-processing/references/imagemagick-batch.md +612 -612
- package/skills/ai-media/media-processing/references/imagemagick-editing.md +623 -623
- package/skills/ai-media/media-processing/scripts/batch_resize.py +342 -342
- package/skills/ai-media/media-processing/scripts/media_convert.py +311 -311
- package/skills/ai-media/media-processing/scripts/requirements.txt +24 -24
- package/skills/ai-media/media-processing/scripts/tests/requirements.txt +2 -2
- package/skills/ai-media/media-processing/scripts/tests/test_batch_resize.py +372 -372
- package/skills/ai-media/media-processing/scripts/tests/test_media_convert.py +259 -259
- package/skills/ai-media/media-processing/scripts/tests/test_video_optimize.py +397 -397
- package/skills/ai-media/media-processing/scripts/video_optimize.py +414 -414
- package/skills/ai-media/screenshot/LICENSE.txt +201 -201
- package/skills/ai-media/screenshot/SKILL.md +267 -267
- package/skills/ai-media/screenshot/agents/openai.yaml +6 -6
- package/skills/ai-media/screenshot/assets/screenshot-small.svg +5 -5
- package/skills/ai-media/screenshot/scripts/ensure_macos_permissions.sh +54 -54
- package/skills/ai-media/screenshot/scripts/macos_display_info.swift +22 -22
- package/skills/ai-media/screenshot/scripts/macos_permissions.swift +40 -40
- package/skills/ai-media/screenshot/scripts/macos_window_info.swift +126 -126
- package/skills/ai-media/screenshot/scripts/take_screenshot.ps1 +163 -163
- package/skills/ai-media/screenshot/scripts/take_screenshot.py +585 -585
- package/skills/ai-media/sora/LICENSE.txt +201 -201
- package/skills/ai-media/sora/SKILL.md +153 -153
- package/skills/ai-media/sora/agents/openai.yaml +6 -6
- package/skills/ai-media/sora/assets/sora-small.svg +4 -4
- package/skills/ai-media/sora/references/cinematic-shots.md +53 -53
- package/skills/ai-media/sora/references/cli.md +248 -248
- package/skills/ai-media/sora/references/codex-network.md +28 -28
- package/skills/ai-media/sora/references/prompting.md +137 -137
- package/skills/ai-media/sora/references/sample-prompts.md +95 -95
- package/skills/ai-media/sora/references/social-ads.md +42 -42
- package/skills/ai-media/sora/references/troubleshooting.md +58 -58
- package/skills/ai-media/sora/references/video-api.md +45 -45
- package/skills/ai-media/sora/scripts/sora.py +970 -970
- package/skills/design/aesthetic/SKILL.md +121 -121
- package/skills/design/aesthetic/assets/design-guideline-template.md +163 -163
- package/skills/design/aesthetic/assets/design-story-template.md +135 -135
- package/skills/design/aesthetic/references/design-principles.md +62 -62
- package/skills/design/aesthetic/references/design-resources.md +75 -75
- package/skills/design/aesthetic/references/micro-interactions.md +53 -53
- package/skills/design/aesthetic/references/storytelling-design.md +50 -50
- package/skills/design/figma/LICENSE.txt +202 -202
- package/skills/design/figma/SKILL.md +42 -42
- package/skills/design/figma/agents/openai.yaml +14 -14
- package/skills/design/figma/assets/figma-small.svg +3 -3
- package/skills/design/figma/assets/icon.svg +28 -28
- package/skills/design/figma/references/figma-mcp-config.md +35 -35
- package/skills/design/figma/references/figma-tools-and-prompts.md +34 -34
- package/skills/design/figma-implement-design/LICENSE.txt +202 -202
- package/skills/design/figma-implement-design/SKILL.md +264 -264
- package/skills/design/figma-implement-design/agents/openai.yaml +14 -14
- package/skills/design/figma-implement-design/assets/figma-small.svg +3 -3
- package/skills/design/figma-implement-design/assets/icon.svg +28 -28
- package/skills/design/frontend-design/SKILL.md +41 -41
- package/skills/design/frontend-design/references/animejs.md +395 -395
- package/skills/design/ui-styling/LICENSE.txt +201 -201
- package/skills/design/ui-styling/SKILL.md +321 -321
- package/skills/design/ui-styling/canvas-fonts/ArsenalSC-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/BigShoulders-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/Boldonse-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/BricolageGrotesque-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/CrimsonPro-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/DMMono-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/EricaOne-OFL.txt +94 -94
- package/skills/design/ui-styling/canvas-fonts/GeistMono-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/Gloock-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/IBMPlexMono-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/InstrumentSans-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/Italiana-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/JetBrainsMono-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/Jura-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/LibreBaskerville-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/Lora-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/NationalPark-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/Outfit-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/PixelifySans-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/PoiretOne-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/RedHatMono-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/Silkscreen-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/SmoochSans-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/Tektur-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/WorkSans-OFL.txt +93 -93
- package/skills/design/ui-styling/canvas-fonts/YoungSerif-OFL.txt +93 -93
- package/skills/design/ui-styling/references/canvas-design-system.md +320 -320
- package/skills/design/ui-styling/references/shadcn-accessibility.md +471 -471
- package/skills/design/ui-styling/references/shadcn-components.md +424 -424
- package/skills/design/ui-styling/references/shadcn-theming.md +373 -373
- package/skills/design/ui-styling/references/tailwind-customization.md +483 -483
- package/skills/design/ui-styling/references/tailwind-responsive.md +382 -382
- package/skills/design/ui-styling/references/tailwind-utilities.md +455 -455
- package/skills/design/ui-styling/scripts/requirements.txt +17 -17
- package/skills/design/ui-styling/scripts/shadcn_add.py +292 -292
- package/skills/design/ui-styling/scripts/tailwind_config_gen.py +456 -456
- package/skills/design/ui-styling/scripts/tests/requirements.txt +3 -3
- package/skills/design/ui-styling/scripts/tests/test_shadcn_add.py +266 -266
- package/skills/design/ui-styling/scripts/tests/test_tailwind_config_gen.py +336 -336
- package/skills/engineering/aspnet-core/LICENSE.txt +201 -201
- package/skills/engineering/aspnet-core/SKILL.md +61 -61
- package/skills/engineering/aspnet-core/agents/openai.yaml +5 -5
- package/skills/engineering/aspnet-core/references/_sections.md +40 -40
- package/skills/engineering/aspnet-core/references/apis-minimal-and-controllers.md +81 -81
- package/skills/engineering/aspnet-core/references/data-state-and-services.md +69 -69
- package/skills/engineering/aspnet-core/references/program-and-pipeline.md +103 -103
- package/skills/engineering/aspnet-core/references/realtime-grpc-and-background-work.md +58 -58
- package/skills/engineering/aspnet-core/references/security-and-identity.md +75 -75
- package/skills/engineering/aspnet-core/references/source-map.md +43 -43
- package/skills/engineering/aspnet-core/references/stack-selection.md +63 -63
- package/skills/engineering/aspnet-core/references/testing-performance-and-operations.md +92 -92
- package/skills/engineering/aspnet-core/references/ui-blazor.md +53 -53
- package/skills/engineering/aspnet-core/references/ui-mvc.md +56 -56
- package/skills/engineering/aspnet-core/references/ui-razor-pages.md +55 -55
- package/skills/engineering/aspnet-core/references/versioning-and-upgrades.md +51 -51
- package/skills/engineering/backend-development/SKILL.md +95 -95
- package/skills/engineering/backend-development/references/backend-api-design.md +495 -495
- package/skills/engineering/backend-development/references/backend-architecture.md +454 -454
- package/skills/engineering/backend-development/references/backend-authentication.md +338 -338
- package/skills/engineering/backend-development/references/backend-code-quality.md +659 -659
- package/skills/engineering/backend-development/references/backend-debugging.md +904 -904
- package/skills/engineering/backend-development/references/backend-devops.md +494 -494
- package/skills/engineering/backend-development/references/backend-mindset.md +387 -387
- package/skills/engineering/backend-development/references/backend-performance.md +397 -397
- package/skills/engineering/backend-development/references/backend-security.md +290 -290
- package/skills/engineering/backend-development/references/backend-technologies.md +256 -256
- package/skills/engineering/backend-development/references/backend-testing.md +429 -429
- package/skills/engineering/better-auth/SKILL.md +204 -204
- package/skills/engineering/better-auth/references/advanced-features.md +553 -553
- package/skills/engineering/better-auth/references/database-integration.md +577 -577
- package/skills/engineering/better-auth/references/email-password-auth.md +416 -416
- package/skills/engineering/better-auth/references/oauth-providers.md +430 -430
- package/skills/engineering/better-auth/scripts/better_auth_init.py +521 -521
- package/skills/engineering/better-auth/scripts/requirements.txt +15 -15
- package/skills/engineering/better-auth/scripts/tests/test_better_auth_init.py +421 -421
- package/skills/engineering/code-review/SKILL.md +140 -140
- package/skills/engineering/code-review/references/code-review-reception.md +208 -208
- package/skills/engineering/code-review/references/requesting-code-review.md +104 -104
- package/skills/engineering/code-review/references/verification-before-completion.md +138 -138
- package/skills/engineering/context-engineering/SKILL.md +86 -86
- package/skills/engineering/context-engineering/references/context-compression.md +84 -84
- package/skills/engineering/context-engineering/references/context-degradation.md +93 -93
- package/skills/engineering/context-engineering/references/context-fundamentals.md +75 -75
- package/skills/engineering/context-engineering/references/context-optimization.md +82 -82
- package/skills/engineering/context-engineering/references/evaluation.md +89 -89
- package/skills/engineering/context-engineering/references/memory-systems.md +88 -88
- package/skills/engineering/context-engineering/references/multi-agent-patterns.md +90 -90
- package/skills/engineering/context-engineering/references/project-development.md +97 -97
- package/skills/engineering/context-engineering/references/tool-design.md +86 -86
- package/skills/engineering/context-engineering/scripts/compression_evaluator.py +329 -329
- package/skills/engineering/context-engineering/scripts/context_analyzer.py +294 -294
- package/skills/engineering/databases/SKILL.md +232 -232
- package/skills/engineering/databases/references/mongodb-aggregation.md +447 -447
- package/skills/engineering/databases/references/mongodb-atlas.md +465 -465
- package/skills/engineering/databases/references/mongodb-crud.md +408 -408
- package/skills/engineering/databases/references/mongodb-indexing.md +442 -442
- package/skills/engineering/databases/references/postgresql-administration.md +594 -594
- package/skills/engineering/databases/references/postgresql-performance.md +527 -527
- package/skills/engineering/databases/references/postgresql-psql-cli.md +467 -467
- package/skills/engineering/databases/references/postgresql-queries.md +475 -475
- package/skills/engineering/databases/scripts/db_backup.py +502 -502
- package/skills/engineering/databases/scripts/db_migrate.py +414 -414
- package/skills/engineering/databases/scripts/db_performance_check.py +444 -444
- package/skills/engineering/databases/scripts/requirements.txt +20 -20
- package/skills/engineering/databases/scripts/tests/requirements.txt +4 -4
- package/skills/engineering/databases/scripts/tests/test_db_backup.py +340 -340
- package/skills/engineering/databases/scripts/tests/test_db_migrate.py +277 -277
- package/skills/engineering/databases/scripts/tests/test_db_performance_check.py +370 -370
- package/skills/engineering/diagnose/SKILL.md +117 -117
- package/skills/engineering/diagnose/scripts/hitl-loop.template.sh +41 -41
- package/skills/engineering/docs-seeker/SKILL.md +207 -207
- package/skills/engineering/docs-seeker/WORKFLOWS.md +505 -505
- package/skills/engineering/docs-seeker/references/best-practices.md +632 -632
- package/skills/engineering/docs-seeker/references/documentation-sources.md +461 -461
- package/skills/engineering/docs-seeker/references/error-handling.md +621 -621
- package/skills/engineering/docs-seeker/references/limitations.md +821 -821
- package/skills/engineering/docs-seeker/references/performance.md +574 -574
- package/skills/engineering/docs-seeker/references/tool-selection.md +262 -262
- package/skills/engineering/frontend-development/SKILL.md +398 -398
- package/skills/engineering/frontend-development/resources/common-patterns.md +330 -330
- package/skills/engineering/frontend-development/resources/complete-examples.md +871 -871
- package/skills/engineering/frontend-development/resources/component-patterns.md +501 -501
- package/skills/engineering/frontend-development/resources/data-fetching.md +766 -766
- package/skills/engineering/frontend-development/resources/file-organization.md +501 -501
- package/skills/engineering/frontend-development/resources/loading-and-error-states.md +500 -500
- package/skills/engineering/frontend-development/resources/performance.md +405 -405
- package/skills/engineering/frontend-development/resources/routing-guide.md +363 -363
- package/skills/engineering/frontend-development/resources/styling-guide.md +427 -427
- package/skills/engineering/frontend-development/resources/typescript-standards.md +417 -417
- package/skills/engineering/improve-codebase-architecture/DEEPENING.md +37 -37
- package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -44
- package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +53 -53
- package/skills/engineering/improve-codebase-architecture/SKILL.md +71 -71
- package/skills/engineering/openai-docs/LICENSE.txt +201 -201
- package/skills/engineering/openai-docs/SKILL.md +69 -69
- package/skills/engineering/openai-docs/agents/openai.yaml +14 -14
- package/skills/engineering/openai-docs/assets/openai-small.svg +3 -3
- package/skills/engineering/openai-docs/references/gpt-5p4-prompting-guide.md +433 -433
- package/skills/engineering/openai-docs/references/latest-model.md +35 -35
- package/skills/engineering/openai-docs/references/upgrading-to-gpt-5p4.md +164 -164
- package/skills/engineering/playwright/LICENSE.txt +201 -201
- package/skills/engineering/playwright/NOTICE.txt +14 -14
- package/skills/engineering/playwright/SKILL.md +147 -147
- package/skills/engineering/playwright/agents/openai.yaml +6 -6
- package/skills/engineering/playwright/assets/playwright-small.svg +3 -3
- package/skills/engineering/playwright/references/cli.md +116 -116
- package/skills/engineering/playwright/references/workflows.md +95 -95
- package/skills/engineering/playwright/scripts/playwright_cli.sh +25 -25
- package/skills/engineering/playwright-interactive/LICENSE.txt +201 -201
- package/skills/engineering/playwright-interactive/NOTICE.txt +13 -13
- package/skills/engineering/playwright-interactive/SKILL.md +689 -689
- package/skills/engineering/playwright-interactive/agents/openai.yaml +6 -6
- package/skills/engineering/playwright-interactive/assets/playwright-small.svg +3 -3
- package/skills/engineering/render-deploy/LICENSE.txt +201 -201
- package/skills/engineering/render-deploy/SKILL.md +479 -479
- package/skills/engineering/render-deploy/agents/openai.yaml +14 -14
- package/skills/engineering/render-deploy/assets/docker.yaml +62 -62
- package/skills/engineering/render-deploy/assets/go-api.yaml +35 -35
- package/skills/engineering/render-deploy/assets/nextjs-postgres.yaml +35 -35
- package/skills/engineering/render-deploy/assets/node-express.yaml +25 -25
- package/skills/engineering/render-deploy/assets/python-django.yaml +89 -89
- package/skills/engineering/render-deploy/assets/render-small.svg +3 -3
- package/skills/engineering/render-deploy/assets/static-site.yaml +54 -54
- package/skills/engineering/render-deploy/references/blueprint-spec.md +718 -718
- package/skills/engineering/render-deploy/references/codebase-analysis.md +49 -49
- package/skills/engineering/render-deploy/references/configuration-guide.md +603 -603
- package/skills/engineering/render-deploy/references/deployment-details.md +224 -224
- package/skills/engineering/render-deploy/references/direct-creation.md +113 -113
- package/skills/engineering/render-deploy/references/error-patterns.md +13 -13
- package/skills/engineering/render-deploy/references/post-deploy-checks.md +36 -36
- package/skills/engineering/render-deploy/references/runtimes.md +473 -473
- package/skills/engineering/render-deploy/references/service-types.md +450 -450
- package/skills/engineering/render-deploy/references/troubleshooting-basics.md +36 -36
- package/skills/engineering/repomix/SKILL.md +215 -215
- package/skills/engineering/repomix/references/configuration.md +211 -211
- package/skills/engineering/repomix/references/usage-patterns.md +232 -232
- package/skills/engineering/repomix/scripts/README.md +179 -179
- package/skills/engineering/repomix/scripts/repomix_batch.py +455 -455
- package/skills/engineering/repomix/scripts/repos.example.json +15 -15
- package/skills/engineering/repomix/scripts/requirements.txt +15 -15
- package/skills/engineering/repomix/scripts/tests/test_repomix_batch.py +531 -531
- package/skills/engineering/setup-matt-pocock-skills/SKILL.md +121 -121
- package/skills/engineering/setup-matt-pocock-skills/domain.md +51 -51
- package/skills/engineering/setup-matt-pocock-skills/issue-tracker-github.md +22 -22
- package/skills/engineering/setup-matt-pocock-skills/issue-tracker-gitlab.md +23 -23
- package/skills/engineering/setup-matt-pocock-skills/issue-tracker-local.md +19 -19
- package/skills/engineering/setup-matt-pocock-skills/triage-labels.md +15 -15
- package/skills/engineering/shopify/README.md +66 -66
- package/skills/engineering/shopify/SKILL.md +319 -319
- package/skills/engineering/shopify/references/app-development.md +470 -470
- package/skills/engineering/shopify/references/extensions.md +493 -493
- package/skills/engineering/shopify/references/themes.md +498 -498
- package/skills/engineering/shopify/scripts/requirements.txt +19 -19
- package/skills/engineering/shopify/scripts/shopify_init.py +423 -423
- package/skills/engineering/shopify/scripts/tests/test_shopify_init.py +385 -385
- package/skills/engineering/tdd/SKILL.md +109 -109
- package/skills/engineering/tdd/deep-modules.md +33 -33
- package/skills/engineering/tdd/interface-design.md +31 -31
- package/skills/engineering/tdd/mocking.md +59 -59
- package/skills/engineering/tdd/refactoring.md +10 -10
- package/skills/engineering/tdd/tests.md +61 -61
- package/skills/engineering/to-issues/SKILL.md +81 -81
- package/skills/engineering/to-prd/SKILL.md +74 -74
- package/skills/engineering/triage/AGENT-BRIEF.md +168 -168
- package/skills/engineering/triage/OUT-OF-SCOPE.md +101 -101
- package/skills/engineering/triage/SKILL.md +103 -103
- package/skills/engineering/web-frameworks/SKILL.md +324 -324
- package/skills/engineering/web-frameworks/references/nextjs-app-router.md +465 -465
- package/skills/engineering/web-frameworks/references/nextjs-data-fetching.md +459 -459
- package/skills/engineering/web-frameworks/references/nextjs-optimization.md +511 -511
- package/skills/engineering/web-frameworks/references/nextjs-server-components.md +495 -495
- package/skills/engineering/web-frameworks/references/remix-icon-integration.md +603 -603
- package/skills/engineering/web-frameworks/references/turborepo-caching.md +551 -551
- package/skills/engineering/web-frameworks/references/turborepo-pipelines.md +517 -517
- package/skills/engineering/web-frameworks/references/turborepo-setup.md +542 -542
- package/skills/engineering/web-frameworks/scripts/nextjs_init.py +547 -547
- package/skills/engineering/web-frameworks/scripts/requirements.txt +16 -16
- package/skills/engineering/web-frameworks/scripts/tests/requirements.txt +3 -3
- package/skills/engineering/web-frameworks/scripts/tests/test_nextjs_init.py +319 -319
- package/skills/engineering/web-frameworks/scripts/tests/test_turborepo_migrate.py +374 -374
- package/skills/engineering/web-frameworks/scripts/turborepo_migrate.py +394 -394
- package/skills/engineering/write-a-skill/SKILL.md +117 -117
- package/skills/kilo-kit/SKILL.md +346 -346
- package/skills/kilo-kit/_template/SKILL.md +185 -185
- package/skills/kilo-kit/debugging/root-cause/SKILL.md +360 -360
- package/skills/kilo-kit/debugging/systematic/SKILL.md +339 -339
- package/skills/kilo-kit/debugging/verification/SKILL.md +424 -424
- package/skills/kilo-kit/development/backend/SKILL.md +540 -540
- package/skills/kilo-kit/development/security/SKILL.md +529 -529
- package/skills/kilo-kit/quality/code-review/SKILL.md +297 -297
- package/skills/kilo-kit/quality/testing/SKILL.md +540 -540
- package/skills/kilo-kit/references/output-formats.md +204 -204
- package/skills/kilo-kit/references/patterns.md +156 -156
- package/skills/kilo-kit/references/performance-benchmarks.md +90 -90
- package/skills/operations/chrome-devtools/SKILL.md +392 -392
- package/skills/operations/chrome-devtools/references/cdp-domains.md +694 -694
- package/skills/operations/chrome-devtools/references/performance-guide.md +940 -940
- package/skills/operations/chrome-devtools/references/puppeteer-reference.md +953 -953
- package/skills/operations/chrome-devtools/scripts/PERSISTENT-BROWSER.md +107 -107
- package/skills/operations/chrome-devtools/scripts/README.md +213 -213
- package/skills/operations/chrome-devtools/scripts/__tests__/selector.test.js +210 -210
- package/skills/operations/chrome-devtools/scripts/click.js +79 -79
- package/skills/operations/chrome-devtools/scripts/close-persistent.js +36 -36
- package/skills/operations/chrome-devtools/scripts/console.js +75 -75
- package/skills/operations/chrome-devtools/scripts/evaluate.js +49 -49
- package/skills/operations/chrome-devtools/scripts/fill.js +72 -72
- package/skills/operations/chrome-devtools/scripts/install-deps.sh +181 -181
- package/skills/operations/chrome-devtools/scripts/install.sh +83 -83
- package/skills/operations/chrome-devtools/scripts/launch-persistent.js +71 -71
- package/skills/operations/chrome-devtools/scripts/lib/browser.js +144 -144
- package/skills/operations/chrome-devtools/scripts/lib/selector.js +178 -178
- package/skills/operations/chrome-devtools/scripts/navigate.js +46 -46
- package/skills/operations/chrome-devtools/scripts/network.js +102 -102
- package/skills/operations/chrome-devtools/scripts/package-lock.json +1206 -1206
- package/skills/operations/chrome-devtools/scripts/package.json +15 -15
- package/skills/operations/chrome-devtools/scripts/performance.js +145 -145
- package/skills/operations/chrome-devtools/scripts/screenshot.js +180 -180
- package/skills/operations/chrome-devtools/scripts/snapshot.js +131 -131
- package/skills/operations/devops/.env.example +76 -76
- package/skills/operations/devops/SKILL.md +285 -285
- package/skills/operations/devops/references/browser-rendering.md +305 -305
- package/skills/operations/devops/references/cloudflare-d1-kv.md +123 -123
- package/skills/operations/devops/references/cloudflare-platform.md +271 -271
- package/skills/operations/devops/references/cloudflare-r2-storage.md +280 -280
- package/skills/operations/devops/references/cloudflare-workers-advanced.md +312 -312
- package/skills/operations/devops/references/cloudflare-workers-apis.md +309 -309
- package/skills/operations/devops/references/cloudflare-workers-basics.md +418 -418
- package/skills/operations/devops/references/docker-basics.md +297 -297
- package/skills/operations/devops/references/docker-compose.md +292 -292
- package/skills/operations/devops/references/gcloud-platform.md +297 -297
- package/skills/operations/devops/references/gcloud-services.md +304 -304
- package/skills/operations/devops/scripts/cloudflare_deploy.py +269 -269
- package/skills/operations/devops/scripts/docker_optimize.py +320 -320
- package/skills/operations/devops/scripts/requirements.txt +20 -20
- package/skills/operations/devops/scripts/tests/requirements.txt +3 -3
- package/skills/operations/devops/scripts/tests/test_cloudflare_deploy.py +285 -285
- package/skills/operations/devops/scripts/tests/test_docker_optimize.py +436 -436
- package/skills/operations/mcp-builder/LICENSE.txt +201 -201
- package/skills/operations/mcp-builder/SKILL.md +328 -328
- package/skills/operations/mcp-builder/reference/evaluation.md +601 -601
- package/skills/operations/mcp-builder/reference/mcp_best_practices.md +915 -915
- package/skills/operations/mcp-builder/reference/node_mcp_server.md +915 -915
- package/skills/operations/mcp-builder/reference/python_mcp_server.md +751 -751
- package/skills/operations/mcp-builder/scripts/connections.py +151 -151
- package/skills/operations/mcp-builder/scripts/evaluation.py +373 -373
- package/skills/operations/mcp-builder/scripts/example_evaluation.xml +22 -22
- package/skills/operations/mcp-builder/scripts/requirements.txt +2 -2
- package/skills/operations/mcp-management/README.md +219 -219
- package/skills/operations/mcp-management/SKILL.md +175 -175
- package/skills/operations/mcp-management/assets/tools.json +3043 -3043
- package/skills/operations/mcp-management/references/configuration.md +114 -114
- package/skills/operations/mcp-management/references/gemini-cli-integration.md +201 -201
- package/skills/operations/mcp-management/references/mcp-protocol.md +116 -116
- package/skills/operations/mcp-management/scripts/.env.example +10 -10
- package/skills/operations/mcp-management/scripts/cli.ts +155 -155
- package/skills/operations/mcp-management/scripts/dist/analyze-tools.js +70 -70
- package/skills/operations/mcp-management/scripts/dist/cli.js +131 -131
- package/skills/operations/mcp-management/scripts/dist/mcp-client.js +115 -115
- package/skills/operations/mcp-management/scripts/mcp-client.ts +163 -163
- package/skills/operations/mcp-management/scripts/package.json +18 -18
- package/skills/operations/mcp-management/scripts/tsconfig.json +15 -15
- package/skills/problem-solving/collision-zone-thinking/SKILL.md +62 -62
- package/skills/problem-solving/defense-in-depth/SKILL.md +130 -130
- package/skills/problem-solving/inversion-exercise/SKILL.md +58 -58
- package/skills/problem-solving/meta-pattern-recognition/SKILL.md +54 -54
- package/skills/problem-solving/root-cause-tracing/SKILL.md +177 -177
- package/skills/problem-solving/root-cause-tracing/find-polluter.sh +63 -63
- package/skills/problem-solving/scale-game/SKILL.md +63 -63
- package/skills/problem-solving/sequential-thinking/README.md +118 -118
- package/skills/problem-solving/sequential-thinking/SKILL.md +93 -93
- package/skills/problem-solving/sequential-thinking/references/advanced.md +122 -122
- package/skills/problem-solving/sequential-thinking/references/examples.md +274 -274
- package/skills/problem-solving/simplification-cascades/SKILL.md +76 -76
- package/skills/problem-solving/when-stuck/SKILL.md +88 -88
- package/skills/productivity/caveman/SKILL.md +49 -49
- package/skills/productivity/grill-me/SKILL.md +10 -10
- package/skills/productivity/grill-with-docs/ADR-FORMAT.md +47 -47
- package/skills/productivity/grill-with-docs/CONTEXT-FORMAT.md +77 -77
- package/skills/productivity/grill-with-docs/SKILL.md +88 -88
- package/skills/productivity/writing-skills/graphviz-conventions.dot +171 -171
- package/skills/productivity/zoom-out/SKILL.md +7 -7
- package/skills/writing-docs/doc/LICENSE.txt +201 -201
- package/skills/writing-docs/doc/SKILL.md +80 -80
- package/skills/writing-docs/doc/agents/openai.yaml +6 -6
- package/skills/writing-docs/doc/assets/doc-small.svg +3 -3
- package/skills/writing-docs/doc/scripts/render_docx.py +296 -296
- package/skills/writing-docs/docx/LICENSE.txt +30 -30
- package/skills/writing-docs/docx/SKILL.md +196 -196
- package/skills/writing-docs/docx/docx-js.md +349 -349
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -1499
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -146
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -1085
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -11
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -3081
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -23
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -185
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -287
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -1676
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -28
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -144
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -174
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -25
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -18
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -59
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -56
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -195
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -582
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -25
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -4439
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -570
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -509
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -12
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -108
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -96
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -3646
- package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -116
- package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -42
- package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -50
- package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -49
- package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -33
- package/skills/writing-docs/docx/ooxml/schemas/mce/mc.xsd +75 -75
- package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -560
- package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -67
- package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -14
- package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -20
- package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -13
- package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -4
- package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -8
- package/skills/writing-docs/docx/ooxml/scripts/pack.py +159 -159
- package/skills/writing-docs/docx/ooxml/scripts/unpack.py +29 -29
- package/skills/writing-docs/docx/ooxml/scripts/validate.py +69 -69
- package/skills/writing-docs/docx/ooxml/scripts/validation/__init__.py +15 -15
- package/skills/writing-docs/docx/ooxml/scripts/validation/base.py +951 -951
- package/skills/writing-docs/docx/ooxml/scripts/validation/docx.py +274 -274
- package/skills/writing-docs/docx/ooxml/scripts/validation/pptx.py +315 -315
- package/skills/writing-docs/docx/ooxml/scripts/validation/redlining.py +279 -279
- package/skills/writing-docs/docx/ooxml.md +609 -609
- package/skills/writing-docs/docx/scripts/__init__.py +1 -1
- package/skills/writing-docs/docx/scripts/document.py +1276 -1276
- package/skills/writing-docs/docx/scripts/templates/comments.xml +2 -2
- package/skills/writing-docs/docx/scripts/templates/commentsExtended.xml +2 -2
- package/skills/writing-docs/docx/scripts/templates/commentsExtensible.xml +2 -2
- package/skills/writing-docs/docx/scripts/templates/commentsIds.xml +2 -2
- package/skills/writing-docs/docx/scripts/templates/people.xml +2 -2
- package/skills/writing-docs/docx/scripts/utilities.py +374 -374
- package/skills/writing-docs/mermaidjs-v11/SKILL.md +115 -115
- package/skills/writing-docs/mermaidjs-v11/references/cli-usage.md +228 -228
- package/skills/writing-docs/mermaidjs-v11/references/configuration.md +232 -232
- package/skills/writing-docs/mermaidjs-v11/references/diagram-types.md +315 -315
- package/skills/writing-docs/mermaidjs-v11/references/examples.md +344 -344
- package/skills/writing-docs/mermaidjs-v11/references/integration.md +310 -310
- package/skills/writing-docs/pdf/LICENSE.txt +30 -30
- package/skills/writing-docs/pdf/SKILL.md +294 -294
- package/skills/writing-docs/pdf/forms.md +205 -205
- package/skills/writing-docs/pdf/reference.md +611 -611
- package/skills/writing-docs/pdf/scripts/check_bounding_boxes.py +70 -70
- package/skills/writing-docs/pdf/scripts/check_bounding_boxes_test.py +226 -226
- package/skills/writing-docs/pdf/scripts/check_fillable_fields.py +12 -12
- package/skills/writing-docs/pdf/scripts/convert_pdf_to_images.py +35 -35
- package/skills/writing-docs/pdf/scripts/create_validation_image.py +41 -41
- package/skills/writing-docs/pdf/scripts/extract_form_field_info.py +152 -152
- package/skills/writing-docs/pdf/scripts/fill_fillable_fields.py +114 -114
- package/skills/writing-docs/pdf/scripts/fill_pdf_form_with_annotations.py +107 -107
- package/skills/writing-docs/pptx/LICENSE.txt +30 -30
- package/skills/writing-docs/pptx/SKILL.md +483 -483
- package/skills/writing-docs/pptx/html2pptx.md +624 -624
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -1499
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -146
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -1085
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -11
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -3081
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -23
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -185
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -287
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -1676
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -28
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -144
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -174
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -25
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -18
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -59
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -56
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -195
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -582
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -25
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -4439
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -570
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -509
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -12
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -108
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -96
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -3646
- package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -116
- package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -42
- package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -50
- package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -49
- package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -33
- package/skills/writing-docs/pptx/ooxml/schemas/mce/mc.xsd +75 -75
- package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -560
- package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -67
- package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -14
- package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -20
- package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -13
- package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -4
- package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -8
- package/skills/writing-docs/pptx/ooxml/scripts/pack.py +159 -159
- package/skills/writing-docs/pptx/ooxml/scripts/unpack.py +29 -29
- package/skills/writing-docs/pptx/ooxml/scripts/validate.py +69 -69
- package/skills/writing-docs/pptx/ooxml/scripts/validation/__init__.py +15 -15
- package/skills/writing-docs/pptx/ooxml/scripts/validation/base.py +951 -951
- package/skills/writing-docs/pptx/ooxml/scripts/validation/docx.py +274 -274
- package/skills/writing-docs/pptx/ooxml/scripts/validation/pptx.py +315 -315
- package/skills/writing-docs/pptx/ooxml/scripts/validation/redlining.py +279 -279
- package/skills/writing-docs/pptx/ooxml.md +426 -426
- package/skills/writing-docs/pptx/scripts/html2pptx.js +978 -978
- package/skills/writing-docs/pptx/scripts/inventory.py +1020 -1020
- package/skills/writing-docs/pptx/scripts/rearrange.py +231 -231
- package/skills/writing-docs/pptx/scripts/replace.py +385 -385
- package/skills/writing-docs/pptx/scripts/thumbnail.py +450 -450
- package/skills/writing-docs/slides/LICENSE.txt +201 -201
- package/skills/writing-docs/slides/SKILL.md +71 -71
- package/skills/writing-docs/slides/agents/openai.yaml +6 -6
- package/skills/writing-docs/slides/assets/pptxgenjs_helpers/code.js +104 -104
- package/skills/writing-docs/slides/assets/pptxgenjs_helpers/image.js +333 -333
- package/skills/writing-docs/slides/assets/pptxgenjs_helpers/index.js +33 -33
- package/skills/writing-docs/slides/assets/pptxgenjs_helpers/latex.js +51 -51
- package/skills/writing-docs/slides/assets/pptxgenjs_helpers/layout.js +643 -643
- package/skills/writing-docs/slides/assets/pptxgenjs_helpers/layout_builders.js +358 -358
- package/skills/writing-docs/slides/assets/pptxgenjs_helpers/svg.js +36 -36
- package/skills/writing-docs/slides/assets/pptxgenjs_helpers/text.js +789 -789
- package/skills/writing-docs/slides/assets/pptxgenjs_helpers/util.js +24 -24
- package/skills/writing-docs/slides/assets/slides-small.svg +3 -3
- package/skills/writing-docs/slides/references/pptxgenjs-helpers.md +61 -61
- package/skills/writing-docs/slides/scripts/create_montage.py +300 -300
- package/skills/writing-docs/slides/scripts/detect_font.py +873 -873
- package/skills/writing-docs/slides/scripts/ensure_raster_image.py +202 -202
- package/skills/writing-docs/slides/scripts/render_slides.py +273 -273
- package/skills/writing-docs/slides/scripts/slides_test.py +201 -201
- package/skills/writing-docs/template-skill/SKILL.md +26 -26
- package/skills/writing-docs/xlsx/LICENSE.txt +30 -30
- package/skills/writing-docs/xlsx/SKILL.md +288 -288
- package/skills/writing-docs/xlsx/recalc.py +177 -177
- package/src/core/KILO_MASTER.md +448 -448
- package/src/tools/validate-skill.js +421 -421
|
@@ -1,315 +1,315 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Validator for PowerPoint presentation XML files against XSD schemas.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import re
|
|
6
|
-
|
|
7
|
-
from .base import BaseSchemaValidator
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class PPTXSchemaValidator(BaseSchemaValidator):
|
|
11
|
-
"""Validator for PowerPoint presentation XML files against XSD schemas."""
|
|
12
|
-
|
|
13
|
-
# PowerPoint presentation namespace
|
|
14
|
-
PRESENTATIONML_NAMESPACE = (
|
|
15
|
-
"http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
# PowerPoint-specific element to relationship type mappings
|
|
19
|
-
ELEMENT_RELATIONSHIP_TYPES = {
|
|
20
|
-
"sldid": "slide",
|
|
21
|
-
"sldmasterid": "slidemaster",
|
|
22
|
-
"notesmasterid": "notesmaster",
|
|
23
|
-
"sldlayoutid": "slidelayout",
|
|
24
|
-
"themeid": "theme",
|
|
25
|
-
"tablestyleid": "tablestyles",
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
def validate(self):
|
|
29
|
-
"""Run all validation checks and return True if all pass."""
|
|
30
|
-
# Test 0: XML well-formedness
|
|
31
|
-
if not self.validate_xml():
|
|
32
|
-
return False
|
|
33
|
-
|
|
34
|
-
# Test 1: Namespace declarations
|
|
35
|
-
all_valid = True
|
|
36
|
-
if not self.validate_namespaces():
|
|
37
|
-
all_valid = False
|
|
38
|
-
|
|
39
|
-
# Test 2: Unique IDs
|
|
40
|
-
if not self.validate_unique_ids():
|
|
41
|
-
all_valid = False
|
|
42
|
-
|
|
43
|
-
# Test 3: UUID ID validation
|
|
44
|
-
if not self.validate_uuid_ids():
|
|
45
|
-
all_valid = False
|
|
46
|
-
|
|
47
|
-
# Test 4: Relationship and file reference validation
|
|
48
|
-
if not self.validate_file_references():
|
|
49
|
-
all_valid = False
|
|
50
|
-
|
|
51
|
-
# Test 5: Slide layout ID validation
|
|
52
|
-
if not self.validate_slide_layout_ids():
|
|
53
|
-
all_valid = False
|
|
54
|
-
|
|
55
|
-
# Test 6: Content type declarations
|
|
56
|
-
if not self.validate_content_types():
|
|
57
|
-
all_valid = False
|
|
58
|
-
|
|
59
|
-
# Test 7: XSD schema validation
|
|
60
|
-
if not self.validate_against_xsd():
|
|
61
|
-
all_valid = False
|
|
62
|
-
|
|
63
|
-
# Test 8: Notes slide reference validation
|
|
64
|
-
if not self.validate_notes_slide_references():
|
|
65
|
-
all_valid = False
|
|
66
|
-
|
|
67
|
-
# Test 9: Relationship ID reference validation
|
|
68
|
-
if not self.validate_all_relationship_ids():
|
|
69
|
-
all_valid = False
|
|
70
|
-
|
|
71
|
-
# Test 10: Duplicate slide layout references validation
|
|
72
|
-
if not self.validate_no_duplicate_slide_layouts():
|
|
73
|
-
all_valid = False
|
|
74
|
-
|
|
75
|
-
return all_valid
|
|
76
|
-
|
|
77
|
-
def validate_uuid_ids(self):
|
|
78
|
-
"""Validate that ID attributes that look like UUIDs contain only hex values."""
|
|
79
|
-
import lxml.etree
|
|
80
|
-
|
|
81
|
-
errors = []
|
|
82
|
-
# UUID pattern: 8-4-4-4-12 hex digits with optional braces/hyphens
|
|
83
|
-
uuid_pattern = re.compile(
|
|
84
|
-
r"^[\{\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\}\)]?$"
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
for xml_file in self.xml_files:
|
|
88
|
-
try:
|
|
89
|
-
root = lxml.etree.parse(str(xml_file)).getroot()
|
|
90
|
-
|
|
91
|
-
# Check all elements for ID attributes
|
|
92
|
-
for elem in root.iter():
|
|
93
|
-
for attr, value in elem.attrib.items():
|
|
94
|
-
# Check if this is an ID attribute
|
|
95
|
-
attr_name = attr.split("}")[-1].lower()
|
|
96
|
-
if attr_name == "id" or attr_name.endswith("id"):
|
|
97
|
-
# Check if value looks like a UUID (has the right length and pattern structure)
|
|
98
|
-
if self._looks_like_uuid(value):
|
|
99
|
-
# Validate that it contains only hex characters in the right positions
|
|
100
|
-
if not uuid_pattern.match(value):
|
|
101
|
-
errors.append(
|
|
102
|
-
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
|
103
|
-
f"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters"
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
|
107
|
-
errors.append(
|
|
108
|
-
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
if errors:
|
|
112
|
-
print(f"FAILED - Found {len(errors)} UUID ID validation errors:")
|
|
113
|
-
for error in errors:
|
|
114
|
-
print(error)
|
|
115
|
-
return False
|
|
116
|
-
else:
|
|
117
|
-
if self.verbose:
|
|
118
|
-
print("PASSED - All UUID-like IDs contain valid hex values")
|
|
119
|
-
return True
|
|
120
|
-
|
|
121
|
-
def _looks_like_uuid(self, value):
|
|
122
|
-
"""Check if a value has the general structure of a UUID."""
|
|
123
|
-
# Remove common UUID delimiters
|
|
124
|
-
clean_value = value.strip("{}()").replace("-", "")
|
|
125
|
-
# Check if it's 32 hex-like characters (could include invalid hex chars)
|
|
126
|
-
return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)
|
|
127
|
-
|
|
128
|
-
def validate_slide_layout_ids(self):
|
|
129
|
-
"""Validate that sldLayoutId elements in slide masters reference valid slide layouts."""
|
|
130
|
-
import lxml.etree
|
|
131
|
-
|
|
132
|
-
errors = []
|
|
133
|
-
|
|
134
|
-
# Find all slide master files
|
|
135
|
-
slide_masters = list(self.unpacked_dir.glob("ppt/slideMasters/*.xml"))
|
|
136
|
-
|
|
137
|
-
if not slide_masters:
|
|
138
|
-
if self.verbose:
|
|
139
|
-
print("PASSED - No slide masters found")
|
|
140
|
-
return True
|
|
141
|
-
|
|
142
|
-
for slide_master in slide_masters:
|
|
143
|
-
try:
|
|
144
|
-
# Parse the slide master file
|
|
145
|
-
root = lxml.etree.parse(str(slide_master)).getroot()
|
|
146
|
-
|
|
147
|
-
# Find the corresponding _rels file for this slide master
|
|
148
|
-
rels_file = slide_master.parent / "_rels" / f"{slide_master.name}.rels"
|
|
149
|
-
|
|
150
|
-
if not rels_file.exists():
|
|
151
|
-
errors.append(
|
|
152
|
-
f" {slide_master.relative_to(self.unpacked_dir)}: "
|
|
153
|
-
f"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}"
|
|
154
|
-
)
|
|
155
|
-
continue
|
|
156
|
-
|
|
157
|
-
# Parse the relationships file
|
|
158
|
-
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
|
159
|
-
|
|
160
|
-
# Build a set of valid relationship IDs that point to slide layouts
|
|
161
|
-
valid_layout_rids = set()
|
|
162
|
-
for rel in rels_root.findall(
|
|
163
|
-
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
|
164
|
-
):
|
|
165
|
-
rel_type = rel.get("Type", "")
|
|
166
|
-
if "slideLayout" in rel_type:
|
|
167
|
-
valid_layout_rids.add(rel.get("Id"))
|
|
168
|
-
|
|
169
|
-
# Find all sldLayoutId elements in the slide master
|
|
170
|
-
for sld_layout_id in root.findall(
|
|
171
|
-
f".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId"
|
|
172
|
-
):
|
|
173
|
-
r_id = sld_layout_id.get(
|
|
174
|
-
f"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id"
|
|
175
|
-
)
|
|
176
|
-
layout_id = sld_layout_id.get("id")
|
|
177
|
-
|
|
178
|
-
if r_id and r_id not in valid_layout_rids:
|
|
179
|
-
errors.append(
|
|
180
|
-
f" {slide_master.relative_to(self.unpacked_dir)}: "
|
|
181
|
-
f"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' "
|
|
182
|
-
f"references r:id='{r_id}' which is not found in slide layout relationships"
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
|
186
|
-
errors.append(
|
|
187
|
-
f" {slide_master.relative_to(self.unpacked_dir)}: Error: {e}"
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
if errors:
|
|
191
|
-
print(f"FAILED - Found {len(errors)} slide layout ID validation errors:")
|
|
192
|
-
for error in errors:
|
|
193
|
-
print(error)
|
|
194
|
-
print(
|
|
195
|
-
"Remove invalid references or add missing slide layouts to the relationships file."
|
|
196
|
-
)
|
|
197
|
-
return False
|
|
198
|
-
else:
|
|
199
|
-
if self.verbose:
|
|
200
|
-
print("PASSED - All slide layout IDs reference valid slide layouts")
|
|
201
|
-
return True
|
|
202
|
-
|
|
203
|
-
def validate_no_duplicate_slide_layouts(self):
|
|
204
|
-
"""Validate that each slide has exactly one slideLayout reference."""
|
|
205
|
-
import lxml.etree
|
|
206
|
-
|
|
207
|
-
errors = []
|
|
208
|
-
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
|
|
209
|
-
|
|
210
|
-
for rels_file in slide_rels_files:
|
|
211
|
-
try:
|
|
212
|
-
root = lxml.etree.parse(str(rels_file)).getroot()
|
|
213
|
-
|
|
214
|
-
# Find all slideLayout relationships
|
|
215
|
-
layout_rels = [
|
|
216
|
-
rel
|
|
217
|
-
for rel in root.findall(
|
|
218
|
-
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
|
219
|
-
)
|
|
220
|
-
if "slideLayout" in rel.get("Type", "")
|
|
221
|
-
]
|
|
222
|
-
|
|
223
|
-
if len(layout_rels) > 1:
|
|
224
|
-
errors.append(
|
|
225
|
-
f" {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references"
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
except Exception as e:
|
|
229
|
-
errors.append(
|
|
230
|
-
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
if errors:
|
|
234
|
-
print("FAILED - Found slides with duplicate slideLayout references:")
|
|
235
|
-
for error in errors:
|
|
236
|
-
print(error)
|
|
237
|
-
return False
|
|
238
|
-
else:
|
|
239
|
-
if self.verbose:
|
|
240
|
-
print("PASSED - All slides have exactly one slideLayout reference")
|
|
241
|
-
return True
|
|
242
|
-
|
|
243
|
-
def validate_notes_slide_references(self):
|
|
244
|
-
"""Validate that each notesSlide file is referenced by only one slide."""
|
|
245
|
-
import lxml.etree
|
|
246
|
-
|
|
247
|
-
errors = []
|
|
248
|
-
notes_slide_references = {} # Track which slides reference each notesSlide
|
|
249
|
-
|
|
250
|
-
# Find all slide relationship files
|
|
251
|
-
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
|
|
252
|
-
|
|
253
|
-
if not slide_rels_files:
|
|
254
|
-
if self.verbose:
|
|
255
|
-
print("PASSED - No slide relationship files found")
|
|
256
|
-
return True
|
|
257
|
-
|
|
258
|
-
for rels_file in slide_rels_files:
|
|
259
|
-
try:
|
|
260
|
-
# Parse the relationships file
|
|
261
|
-
root = lxml.etree.parse(str(rels_file)).getroot()
|
|
262
|
-
|
|
263
|
-
# Find all notesSlide relationships
|
|
264
|
-
for rel in root.findall(
|
|
265
|
-
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
|
266
|
-
):
|
|
267
|
-
rel_type = rel.get("Type", "")
|
|
268
|
-
if "notesSlide" in rel_type:
|
|
269
|
-
target = rel.get("Target", "")
|
|
270
|
-
if target:
|
|
271
|
-
# Normalize the target path to handle relative paths
|
|
272
|
-
normalized_target = target.replace("../", "")
|
|
273
|
-
|
|
274
|
-
# Track which slide references this notesSlide
|
|
275
|
-
slide_name = rels_file.stem.replace(
|
|
276
|
-
".xml", ""
|
|
277
|
-
) # e.g., "slide1"
|
|
278
|
-
|
|
279
|
-
if normalized_target not in notes_slide_references:
|
|
280
|
-
notes_slide_references[normalized_target] = []
|
|
281
|
-
notes_slide_references[normalized_target].append(
|
|
282
|
-
(slide_name, rels_file)
|
|
283
|
-
)
|
|
284
|
-
|
|
285
|
-
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
|
286
|
-
errors.append(
|
|
287
|
-
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
|
288
|
-
)
|
|
289
|
-
|
|
290
|
-
# Check for duplicate references
|
|
291
|
-
for target, references in notes_slide_references.items():
|
|
292
|
-
if len(references) > 1:
|
|
293
|
-
slide_names = [ref[0] for ref in references]
|
|
294
|
-
errors.append(
|
|
295
|
-
f" Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}"
|
|
296
|
-
)
|
|
297
|
-
for slide_name, rels_file in references:
|
|
298
|
-
errors.append(f" - {rels_file.relative_to(self.unpacked_dir)}")
|
|
299
|
-
|
|
300
|
-
if errors:
|
|
301
|
-
print(
|
|
302
|
-
f"FAILED - Found {len([e for e in errors if not e.startswith(' ')])} notes slide reference validation errors:"
|
|
303
|
-
)
|
|
304
|
-
for error in errors:
|
|
305
|
-
print(error)
|
|
306
|
-
print("Each slide may optionally have its own slide file.")
|
|
307
|
-
return False
|
|
308
|
-
else:
|
|
309
|
-
if self.verbose:
|
|
310
|
-
print("PASSED - All notes slide references are unique")
|
|
311
|
-
return True
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if __name__ == "__main__":
|
|
315
|
-
raise RuntimeError("This module should not be run directly.")
|
|
1
|
+
"""
|
|
2
|
+
Validator for PowerPoint presentation XML files against XSD schemas.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
from .base import BaseSchemaValidator
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PPTXSchemaValidator(BaseSchemaValidator):
|
|
11
|
+
"""Validator for PowerPoint presentation XML files against XSD schemas."""
|
|
12
|
+
|
|
13
|
+
# PowerPoint presentation namespace
|
|
14
|
+
PRESENTATIONML_NAMESPACE = (
|
|
15
|
+
"http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# PowerPoint-specific element to relationship type mappings
|
|
19
|
+
ELEMENT_RELATIONSHIP_TYPES = {
|
|
20
|
+
"sldid": "slide",
|
|
21
|
+
"sldmasterid": "slidemaster",
|
|
22
|
+
"notesmasterid": "notesmaster",
|
|
23
|
+
"sldlayoutid": "slidelayout",
|
|
24
|
+
"themeid": "theme",
|
|
25
|
+
"tablestyleid": "tablestyles",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
def validate(self):
|
|
29
|
+
"""Run all validation checks and return True if all pass."""
|
|
30
|
+
# Test 0: XML well-formedness
|
|
31
|
+
if not self.validate_xml():
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
# Test 1: Namespace declarations
|
|
35
|
+
all_valid = True
|
|
36
|
+
if not self.validate_namespaces():
|
|
37
|
+
all_valid = False
|
|
38
|
+
|
|
39
|
+
# Test 2: Unique IDs
|
|
40
|
+
if not self.validate_unique_ids():
|
|
41
|
+
all_valid = False
|
|
42
|
+
|
|
43
|
+
# Test 3: UUID ID validation
|
|
44
|
+
if not self.validate_uuid_ids():
|
|
45
|
+
all_valid = False
|
|
46
|
+
|
|
47
|
+
# Test 4: Relationship and file reference validation
|
|
48
|
+
if not self.validate_file_references():
|
|
49
|
+
all_valid = False
|
|
50
|
+
|
|
51
|
+
# Test 5: Slide layout ID validation
|
|
52
|
+
if not self.validate_slide_layout_ids():
|
|
53
|
+
all_valid = False
|
|
54
|
+
|
|
55
|
+
# Test 6: Content type declarations
|
|
56
|
+
if not self.validate_content_types():
|
|
57
|
+
all_valid = False
|
|
58
|
+
|
|
59
|
+
# Test 7: XSD schema validation
|
|
60
|
+
if not self.validate_against_xsd():
|
|
61
|
+
all_valid = False
|
|
62
|
+
|
|
63
|
+
# Test 8: Notes slide reference validation
|
|
64
|
+
if not self.validate_notes_slide_references():
|
|
65
|
+
all_valid = False
|
|
66
|
+
|
|
67
|
+
# Test 9: Relationship ID reference validation
|
|
68
|
+
if not self.validate_all_relationship_ids():
|
|
69
|
+
all_valid = False
|
|
70
|
+
|
|
71
|
+
# Test 10: Duplicate slide layout references validation
|
|
72
|
+
if not self.validate_no_duplicate_slide_layouts():
|
|
73
|
+
all_valid = False
|
|
74
|
+
|
|
75
|
+
return all_valid
|
|
76
|
+
|
|
77
|
+
def validate_uuid_ids(self):
|
|
78
|
+
"""Validate that ID attributes that look like UUIDs contain only hex values."""
|
|
79
|
+
import lxml.etree
|
|
80
|
+
|
|
81
|
+
errors = []
|
|
82
|
+
# UUID pattern: 8-4-4-4-12 hex digits with optional braces/hyphens
|
|
83
|
+
uuid_pattern = re.compile(
|
|
84
|
+
r"^[\{\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\}\)]?$"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
for xml_file in self.xml_files:
|
|
88
|
+
try:
|
|
89
|
+
root = lxml.etree.parse(str(xml_file)).getroot()
|
|
90
|
+
|
|
91
|
+
# Check all elements for ID attributes
|
|
92
|
+
for elem in root.iter():
|
|
93
|
+
for attr, value in elem.attrib.items():
|
|
94
|
+
# Check if this is an ID attribute
|
|
95
|
+
attr_name = attr.split("}")[-1].lower()
|
|
96
|
+
if attr_name == "id" or attr_name.endswith("id"):
|
|
97
|
+
# Check if value looks like a UUID (has the right length and pattern structure)
|
|
98
|
+
if self._looks_like_uuid(value):
|
|
99
|
+
# Validate that it contains only hex characters in the right positions
|
|
100
|
+
if not uuid_pattern.match(value):
|
|
101
|
+
errors.append(
|
|
102
|
+
f" {xml_file.relative_to(self.unpacked_dir)}: "
|
|
103
|
+
f"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters"
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
|
107
|
+
errors.append(
|
|
108
|
+
f" {xml_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if errors:
|
|
112
|
+
print(f"FAILED - Found {len(errors)} UUID ID validation errors:")
|
|
113
|
+
for error in errors:
|
|
114
|
+
print(error)
|
|
115
|
+
return False
|
|
116
|
+
else:
|
|
117
|
+
if self.verbose:
|
|
118
|
+
print("PASSED - All UUID-like IDs contain valid hex values")
|
|
119
|
+
return True
|
|
120
|
+
|
|
121
|
+
def _looks_like_uuid(self, value):
|
|
122
|
+
"""Check if a value has the general structure of a UUID."""
|
|
123
|
+
# Remove common UUID delimiters
|
|
124
|
+
clean_value = value.strip("{}()").replace("-", "")
|
|
125
|
+
# Check if it's 32 hex-like characters (could include invalid hex chars)
|
|
126
|
+
return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)
|
|
127
|
+
|
|
128
|
+
def validate_slide_layout_ids(self):
|
|
129
|
+
"""Validate that sldLayoutId elements in slide masters reference valid slide layouts."""
|
|
130
|
+
import lxml.etree
|
|
131
|
+
|
|
132
|
+
errors = []
|
|
133
|
+
|
|
134
|
+
# Find all slide master files
|
|
135
|
+
slide_masters = list(self.unpacked_dir.glob("ppt/slideMasters/*.xml"))
|
|
136
|
+
|
|
137
|
+
if not slide_masters:
|
|
138
|
+
if self.verbose:
|
|
139
|
+
print("PASSED - No slide masters found")
|
|
140
|
+
return True
|
|
141
|
+
|
|
142
|
+
for slide_master in slide_masters:
|
|
143
|
+
try:
|
|
144
|
+
# Parse the slide master file
|
|
145
|
+
root = lxml.etree.parse(str(slide_master)).getroot()
|
|
146
|
+
|
|
147
|
+
# Find the corresponding _rels file for this slide master
|
|
148
|
+
rels_file = slide_master.parent / "_rels" / f"{slide_master.name}.rels"
|
|
149
|
+
|
|
150
|
+
if not rels_file.exists():
|
|
151
|
+
errors.append(
|
|
152
|
+
f" {slide_master.relative_to(self.unpacked_dir)}: "
|
|
153
|
+
f"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}"
|
|
154
|
+
)
|
|
155
|
+
continue
|
|
156
|
+
|
|
157
|
+
# Parse the relationships file
|
|
158
|
+
rels_root = lxml.etree.parse(str(rels_file)).getroot()
|
|
159
|
+
|
|
160
|
+
# Build a set of valid relationship IDs that point to slide layouts
|
|
161
|
+
valid_layout_rids = set()
|
|
162
|
+
for rel in rels_root.findall(
|
|
163
|
+
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
|
164
|
+
):
|
|
165
|
+
rel_type = rel.get("Type", "")
|
|
166
|
+
if "slideLayout" in rel_type:
|
|
167
|
+
valid_layout_rids.add(rel.get("Id"))
|
|
168
|
+
|
|
169
|
+
# Find all sldLayoutId elements in the slide master
|
|
170
|
+
for sld_layout_id in root.findall(
|
|
171
|
+
f".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId"
|
|
172
|
+
):
|
|
173
|
+
r_id = sld_layout_id.get(
|
|
174
|
+
f"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id"
|
|
175
|
+
)
|
|
176
|
+
layout_id = sld_layout_id.get("id")
|
|
177
|
+
|
|
178
|
+
if r_id and r_id not in valid_layout_rids:
|
|
179
|
+
errors.append(
|
|
180
|
+
f" {slide_master.relative_to(self.unpacked_dir)}: "
|
|
181
|
+
f"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' "
|
|
182
|
+
f"references r:id='{r_id}' which is not found in slide layout relationships"
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
|
186
|
+
errors.append(
|
|
187
|
+
f" {slide_master.relative_to(self.unpacked_dir)}: Error: {e}"
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
if errors:
|
|
191
|
+
print(f"FAILED - Found {len(errors)} slide layout ID validation errors:")
|
|
192
|
+
for error in errors:
|
|
193
|
+
print(error)
|
|
194
|
+
print(
|
|
195
|
+
"Remove invalid references or add missing slide layouts to the relationships file."
|
|
196
|
+
)
|
|
197
|
+
return False
|
|
198
|
+
else:
|
|
199
|
+
if self.verbose:
|
|
200
|
+
print("PASSED - All slide layout IDs reference valid slide layouts")
|
|
201
|
+
return True
|
|
202
|
+
|
|
203
|
+
def validate_no_duplicate_slide_layouts(self):
|
|
204
|
+
"""Validate that each slide has exactly one slideLayout reference."""
|
|
205
|
+
import lxml.etree
|
|
206
|
+
|
|
207
|
+
errors = []
|
|
208
|
+
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
|
|
209
|
+
|
|
210
|
+
for rels_file in slide_rels_files:
|
|
211
|
+
try:
|
|
212
|
+
root = lxml.etree.parse(str(rels_file)).getroot()
|
|
213
|
+
|
|
214
|
+
# Find all slideLayout relationships
|
|
215
|
+
layout_rels = [
|
|
216
|
+
rel
|
|
217
|
+
for rel in root.findall(
|
|
218
|
+
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
|
219
|
+
)
|
|
220
|
+
if "slideLayout" in rel.get("Type", "")
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
if len(layout_rels) > 1:
|
|
224
|
+
errors.append(
|
|
225
|
+
f" {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references"
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
except Exception as e:
|
|
229
|
+
errors.append(
|
|
230
|
+
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
if errors:
|
|
234
|
+
print("FAILED - Found slides with duplicate slideLayout references:")
|
|
235
|
+
for error in errors:
|
|
236
|
+
print(error)
|
|
237
|
+
return False
|
|
238
|
+
else:
|
|
239
|
+
if self.verbose:
|
|
240
|
+
print("PASSED - All slides have exactly one slideLayout reference")
|
|
241
|
+
return True
|
|
242
|
+
|
|
243
|
+
def validate_notes_slide_references(self):
|
|
244
|
+
"""Validate that each notesSlide file is referenced by only one slide."""
|
|
245
|
+
import lxml.etree
|
|
246
|
+
|
|
247
|
+
errors = []
|
|
248
|
+
notes_slide_references = {} # Track which slides reference each notesSlide
|
|
249
|
+
|
|
250
|
+
# Find all slide relationship files
|
|
251
|
+
slide_rels_files = list(self.unpacked_dir.glob("ppt/slides/_rels/*.xml.rels"))
|
|
252
|
+
|
|
253
|
+
if not slide_rels_files:
|
|
254
|
+
if self.verbose:
|
|
255
|
+
print("PASSED - No slide relationship files found")
|
|
256
|
+
return True
|
|
257
|
+
|
|
258
|
+
for rels_file in slide_rels_files:
|
|
259
|
+
try:
|
|
260
|
+
# Parse the relationships file
|
|
261
|
+
root = lxml.etree.parse(str(rels_file)).getroot()
|
|
262
|
+
|
|
263
|
+
# Find all notesSlide relationships
|
|
264
|
+
for rel in root.findall(
|
|
265
|
+
f".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship"
|
|
266
|
+
):
|
|
267
|
+
rel_type = rel.get("Type", "")
|
|
268
|
+
if "notesSlide" in rel_type:
|
|
269
|
+
target = rel.get("Target", "")
|
|
270
|
+
if target:
|
|
271
|
+
# Normalize the target path to handle relative paths
|
|
272
|
+
normalized_target = target.replace("../", "")
|
|
273
|
+
|
|
274
|
+
# Track which slide references this notesSlide
|
|
275
|
+
slide_name = rels_file.stem.replace(
|
|
276
|
+
".xml", ""
|
|
277
|
+
) # e.g., "slide1"
|
|
278
|
+
|
|
279
|
+
if normalized_target not in notes_slide_references:
|
|
280
|
+
notes_slide_references[normalized_target] = []
|
|
281
|
+
notes_slide_references[normalized_target].append(
|
|
282
|
+
(slide_name, rels_file)
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
except (lxml.etree.XMLSyntaxError, Exception) as e:
|
|
286
|
+
errors.append(
|
|
287
|
+
f" {rels_file.relative_to(self.unpacked_dir)}: Error: {e}"
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
# Check for duplicate references
|
|
291
|
+
for target, references in notes_slide_references.items():
|
|
292
|
+
if len(references) > 1:
|
|
293
|
+
slide_names = [ref[0] for ref in references]
|
|
294
|
+
errors.append(
|
|
295
|
+
f" Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}"
|
|
296
|
+
)
|
|
297
|
+
for slide_name, rels_file in references:
|
|
298
|
+
errors.append(f" - {rels_file.relative_to(self.unpacked_dir)}")
|
|
299
|
+
|
|
300
|
+
if errors:
|
|
301
|
+
print(
|
|
302
|
+
f"FAILED - Found {len([e for e in errors if not e.startswith(' ')])} notes slide reference validation errors:"
|
|
303
|
+
)
|
|
304
|
+
for error in errors:
|
|
305
|
+
print(error)
|
|
306
|
+
print("Each slide may optionally have its own slide file.")
|
|
307
|
+
return False
|
|
308
|
+
else:
|
|
309
|
+
if self.verbose:
|
|
310
|
+
print("PASSED - All notes slide references are unique")
|
|
311
|
+
return True
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
if __name__ == "__main__":
|
|
315
|
+
raise RuntimeError("This module should not be run directly.")
|