@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,296 +1,296 @@
|
|
|
1
|
-
import argparse
|
|
2
|
-
import os
|
|
3
|
-
import re
|
|
4
|
-
import subprocess
|
|
5
|
-
import tempfile
|
|
6
|
-
import xml.etree.ElementTree as ET
|
|
7
|
-
from os import makedirs, replace
|
|
8
|
-
from os.path import abspath, basename, exists, expanduser, join, splitext
|
|
9
|
-
from shutil import which
|
|
10
|
-
import sys
|
|
11
|
-
from typing import Sequence, cast
|
|
12
|
-
from zipfile import ZipFile
|
|
13
|
-
|
|
14
|
-
from pdf2image import convert_from_path, pdfinfo_from_path
|
|
15
|
-
|
|
16
|
-
TWIPS_PER_INCH: int = 1440
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def ensure_system_tools() -> None:
|
|
20
|
-
missing: list[str] = []
|
|
21
|
-
for tool in ("soffice", "pdftoppm"):
|
|
22
|
-
if which(tool) is None:
|
|
23
|
-
missing.append(tool)
|
|
24
|
-
if missing:
|
|
25
|
-
tools = ", ".join(missing)
|
|
26
|
-
raise RuntimeError(
|
|
27
|
-
f"Missing required system tool(s): {tools}. Install LibreOffice and Poppler, then retry."
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def calc_dpi_via_ooxml_docx(input_path: str, max_w_px: int, max_h_px: int) -> int:
|
|
32
|
-
"""Calculate DPI from OOXML `word/document.xml` page size (w:pgSz in twips).
|
|
33
|
-
|
|
34
|
-
DOCX stores page dimensions in section properties as twips (1/1440 inch).
|
|
35
|
-
We read the first encountered section's page size and compute an isotropic DPI
|
|
36
|
-
that fits within the target max pixel dimensions.
|
|
37
|
-
"""
|
|
38
|
-
with ZipFile(input_path, "r") as zf:
|
|
39
|
-
xml = zf.read("word/document.xml")
|
|
40
|
-
root = ET.fromstring(xml)
|
|
41
|
-
ns = {"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}
|
|
42
|
-
|
|
43
|
-
# Common placements: w:body/w:sectPr or w:body/w:p/w:pPr/w:sectPr
|
|
44
|
-
sect_pr = root.find(".//w:sectPr", ns)
|
|
45
|
-
if sect_pr is None:
|
|
46
|
-
raise RuntimeError("Section properties not found in document.xml")
|
|
47
|
-
pg_sz = sect_pr.find("w:pgSz", ns)
|
|
48
|
-
if pg_sz is None:
|
|
49
|
-
raise RuntimeError("Page size not found in section properties")
|
|
50
|
-
|
|
51
|
-
# Values are in twips
|
|
52
|
-
w_twips_str = pg_sz.get(
|
|
53
|
-
"{http://schemas.openxmlformats.org/wordprocessingml/2006/main}w"
|
|
54
|
-
) or pg_sz.get("w")
|
|
55
|
-
h_twips_str = pg_sz.get(
|
|
56
|
-
"{http://schemas.openxmlformats.org/wordprocessingml/2006/main}h"
|
|
57
|
-
) or pg_sz.get("h")
|
|
58
|
-
|
|
59
|
-
if not w_twips_str or not h_twips_str:
|
|
60
|
-
raise RuntimeError("Page size attributes missing in pgSz")
|
|
61
|
-
|
|
62
|
-
width_in = int(w_twips_str) / TWIPS_PER_INCH
|
|
63
|
-
height_in = int(h_twips_str) / TWIPS_PER_INCH
|
|
64
|
-
if width_in <= 0 or height_in <= 0:
|
|
65
|
-
raise RuntimeError("Invalid page size values in document.xml")
|
|
66
|
-
return round(min(max_w_px / width_in, max_h_px / height_in))
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def calc_dpi_via_pdf(input_path: str, max_w_px: int, max_h_px: int) -> int:
|
|
70
|
-
"""Convert input to PDF and compute DPI from its page size."""
|
|
71
|
-
with tempfile.TemporaryDirectory(prefix="soffice_profile_") as user_profile:
|
|
72
|
-
with tempfile.TemporaryDirectory(prefix="soffice_convert_") as convert_tmp_dir:
|
|
73
|
-
stem = splitext(basename(input_path))[0]
|
|
74
|
-
pdf_path = convert_to_pdf(input_path, user_profile, convert_tmp_dir, stem)
|
|
75
|
-
if not (pdf_path and exists(pdf_path)):
|
|
76
|
-
raise RuntimeError("Failed to convert input to PDF for DPI computation.")
|
|
77
|
-
|
|
78
|
-
info = pdfinfo_from_path(pdf_path)
|
|
79
|
-
size_val = info.get("Page size")
|
|
80
|
-
if not size_val:
|
|
81
|
-
for k, v in info.items():
|
|
82
|
-
if isinstance(v, str) and "size" in k.lower() and "pts" in v:
|
|
83
|
-
size_val = v
|
|
84
|
-
break
|
|
85
|
-
if not isinstance(size_val, str):
|
|
86
|
-
raise RuntimeError("Failed to read PDF page size for DPI computation.")
|
|
87
|
-
|
|
88
|
-
m = re.search(r"(\d+)\s*x\s*(\d+)\s*pts", size_val)
|
|
89
|
-
if not m:
|
|
90
|
-
raise RuntimeError("Unrecognized PDF page size format.")
|
|
91
|
-
width_pts = int(m.group(1))
|
|
92
|
-
height_pts = int(m.group(2))
|
|
93
|
-
width_in = width_pts / 72.0
|
|
94
|
-
height_in = height_pts / 72.0
|
|
95
|
-
if width_in <= 0 or height_in <= 0:
|
|
96
|
-
raise RuntimeError("Invalid PDF page size values.")
|
|
97
|
-
return round(min(max_w_px / width_in, max_h_px / height_in))
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def run_cmd_no_check(cmd: list[str]) -> None:
|
|
101
|
-
subprocess.run(
|
|
102
|
-
cmd,
|
|
103
|
-
check=False,
|
|
104
|
-
stdout=subprocess.DEVNULL,
|
|
105
|
-
stderr=subprocess.DEVNULL,
|
|
106
|
-
env=os.environ.copy(),
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def convert_to_pdf(
|
|
111
|
-
doc_path: str,
|
|
112
|
-
user_profile: str,
|
|
113
|
-
convert_tmp_dir: str,
|
|
114
|
-
stem: str,
|
|
115
|
-
) -> str:
|
|
116
|
-
# Try direct DOC(X) -> PDF
|
|
117
|
-
cmd_pdf = [
|
|
118
|
-
"soffice",
|
|
119
|
-
"-env:UserInstallation=file://" + user_profile,
|
|
120
|
-
"--invisible",
|
|
121
|
-
"--headless",
|
|
122
|
-
"--norestore",
|
|
123
|
-
"--convert-to",
|
|
124
|
-
"pdf",
|
|
125
|
-
"--outdir",
|
|
126
|
-
convert_tmp_dir,
|
|
127
|
-
doc_path,
|
|
128
|
-
]
|
|
129
|
-
run_cmd_no_check(cmd_pdf)
|
|
130
|
-
|
|
131
|
-
pdf_path = join(convert_tmp_dir, f"{stem}.pdf")
|
|
132
|
-
if exists(pdf_path):
|
|
133
|
-
return pdf_path
|
|
134
|
-
|
|
135
|
-
# Fallback: DOCX -> ODT, then ODT -> PDF
|
|
136
|
-
cmd_odt = [
|
|
137
|
-
"soffice",
|
|
138
|
-
"-env:UserInstallation=file://" + user_profile,
|
|
139
|
-
"--invisible",
|
|
140
|
-
"--headless",
|
|
141
|
-
"--norestore",
|
|
142
|
-
"--convert-to",
|
|
143
|
-
"odt",
|
|
144
|
-
"--outdir",
|
|
145
|
-
convert_tmp_dir,
|
|
146
|
-
doc_path,
|
|
147
|
-
]
|
|
148
|
-
run_cmd_no_check(cmd_odt)
|
|
149
|
-
|
|
150
|
-
odt_path = join(convert_tmp_dir, f"{stem}.odt")
|
|
151
|
-
|
|
152
|
-
if exists(odt_path):
|
|
153
|
-
cmd_odt_pdf = [
|
|
154
|
-
"soffice",
|
|
155
|
-
"-env:UserInstallation=file://" + user_profile,
|
|
156
|
-
"--invisible",
|
|
157
|
-
"--headless",
|
|
158
|
-
"--norestore",
|
|
159
|
-
"--convert-to",
|
|
160
|
-
"pdf",
|
|
161
|
-
"--outdir",
|
|
162
|
-
convert_tmp_dir,
|
|
163
|
-
odt_path,
|
|
164
|
-
]
|
|
165
|
-
run_cmd_no_check(cmd_odt_pdf)
|
|
166
|
-
if exists(pdf_path):
|
|
167
|
-
return pdf_path
|
|
168
|
-
|
|
169
|
-
return ""
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
def rasterize(
|
|
173
|
-
doc_path: str,
|
|
174
|
-
out_dir: str,
|
|
175
|
-
dpi: int,
|
|
176
|
-
) -> Sequence[str]:
|
|
177
|
-
"""Rasterise DOCX (or similar) to images placed in out_dir and return their paths.
|
|
178
|
-
|
|
179
|
-
Images are named as page-<N>.<ext> with pages starting at 1.
|
|
180
|
-
"""
|
|
181
|
-
makedirs(out_dir, exist_ok=True)
|
|
182
|
-
doc_path = abspath(doc_path)
|
|
183
|
-
stem = splitext(basename(doc_path))[0]
|
|
184
|
-
|
|
185
|
-
# Use a unique user profile to avoid LibreOffice profile lock when running concurrently
|
|
186
|
-
with tempfile.TemporaryDirectory(prefix="soffice_profile_") as user_profile:
|
|
187
|
-
# Write conversion outputs into a temp directory to avoid any IO oddities
|
|
188
|
-
with tempfile.TemporaryDirectory(prefix="soffice_convert_") as convert_tmp_dir:
|
|
189
|
-
pdf_path = convert_to_pdf(
|
|
190
|
-
doc_path,
|
|
191
|
-
user_profile,
|
|
192
|
-
convert_tmp_dir,
|
|
193
|
-
stem,
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
if not pdf_path or not exists(pdf_path):
|
|
197
|
-
raise RuntimeError(
|
|
198
|
-
"Failed to produce PDF for rasterization (direct and ODT fallback)."
|
|
199
|
-
)
|
|
200
|
-
paths_raw = cast(
|
|
201
|
-
list[str],
|
|
202
|
-
convert_from_path(
|
|
203
|
-
pdf_path,
|
|
204
|
-
dpi=dpi,
|
|
205
|
-
fmt="png",
|
|
206
|
-
thread_count=8,
|
|
207
|
-
output_folder=out_dir,
|
|
208
|
-
paths_only=True,
|
|
209
|
-
output_file="page",
|
|
210
|
-
),
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
# Rename convert_from_path's output format f'page{thread_id:04d}-{page_num:02d}.<ext>' to 'page-<num>.<ext>'
|
|
214
|
-
pages: list[tuple[int, str]] = []
|
|
215
|
-
for src_path in paths_raw:
|
|
216
|
-
base = splitext(basename(src_path))[0]
|
|
217
|
-
page_num_str = base.split("-")[-1]
|
|
218
|
-
page_num = int(page_num_str)
|
|
219
|
-
dst_path = join(out_dir, f"page-{page_num}.png")
|
|
220
|
-
replace(src_path, dst_path)
|
|
221
|
-
pages.append((page_num, dst_path))
|
|
222
|
-
pages.sort(key=lambda t: t[0])
|
|
223
|
-
final_paths = [path for _, path in pages]
|
|
224
|
-
return final_paths
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
def main() -> None:
|
|
228
|
-
parser = argparse.ArgumentParser(description="Render DOCX-like file to PNG images.")
|
|
229
|
-
parser.add_argument(
|
|
230
|
-
"input_path",
|
|
231
|
-
type=str,
|
|
232
|
-
help="Path to the input DOCX file (or compatible).",
|
|
233
|
-
)
|
|
234
|
-
parser.add_argument(
|
|
235
|
-
"--output_dir",
|
|
236
|
-
type=str,
|
|
237
|
-
default=None,
|
|
238
|
-
help=(
|
|
239
|
-
"Output directory for the rendered images. "
|
|
240
|
-
"Defaults to a folder next to the input named after the input file (without extension)."
|
|
241
|
-
),
|
|
242
|
-
)
|
|
243
|
-
parser.add_argument(
|
|
244
|
-
"--width",
|
|
245
|
-
type=int,
|
|
246
|
-
default=1600,
|
|
247
|
-
help=(
|
|
248
|
-
"Approximate maximum width in pixels after isotropic scaling (default 1600). "
|
|
249
|
-
"The actual value may exceed slightly."
|
|
250
|
-
),
|
|
251
|
-
)
|
|
252
|
-
parser.add_argument(
|
|
253
|
-
"--height",
|
|
254
|
-
type=int,
|
|
255
|
-
default=2000,
|
|
256
|
-
help=(
|
|
257
|
-
"Approximate maximum height in pixels after isotropic scaling (default 2000). "
|
|
258
|
-
"The actual value may exceed slightly."
|
|
259
|
-
),
|
|
260
|
-
)
|
|
261
|
-
parser.add_argument(
|
|
262
|
-
"--dpi",
|
|
263
|
-
type=int,
|
|
264
|
-
default=None,
|
|
265
|
-
help=("Override computed DPI. If provided, skips DOCX/PDF-based DPI calculation."),
|
|
266
|
-
)
|
|
267
|
-
args = parser.parse_args()
|
|
268
|
-
|
|
269
|
-
try:
|
|
270
|
-
ensure_system_tools()
|
|
271
|
-
|
|
272
|
-
input_path = abspath(expanduser(args.input_path))
|
|
273
|
-
out_dir = (
|
|
274
|
-
abspath(expanduser(args.output_dir)) if args.output_dir else splitext(input_path)[0]
|
|
275
|
-
)
|
|
276
|
-
|
|
277
|
-
if args.dpi is not None:
|
|
278
|
-
dpi = int(args.dpi)
|
|
279
|
-
else:
|
|
280
|
-
try:
|
|
281
|
-
if input_path.lower().endswith((".docx", ".docm", ".dotx", ".dotm")):
|
|
282
|
-
dpi = calc_dpi_via_ooxml_docx(input_path, args.width, args.height)
|
|
283
|
-
else:
|
|
284
|
-
raise RuntimeError("Skip OOXML DPI; not a DOCX container")
|
|
285
|
-
except Exception:
|
|
286
|
-
dpi = calc_dpi_via_pdf(input_path, args.width, args.height)
|
|
287
|
-
|
|
288
|
-
rasterize(input_path, out_dir, dpi)
|
|
289
|
-
print("Pages rendered to " + out_dir)
|
|
290
|
-
except RuntimeError as exc:
|
|
291
|
-
print(f"Error: {exc}", file=sys.stderr)
|
|
292
|
-
raise SystemExit(1)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if __name__ == "__main__":
|
|
296
|
-
main()
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
import subprocess
|
|
5
|
+
import tempfile
|
|
6
|
+
import xml.etree.ElementTree as ET
|
|
7
|
+
from os import makedirs, replace
|
|
8
|
+
from os.path import abspath, basename, exists, expanduser, join, splitext
|
|
9
|
+
from shutil import which
|
|
10
|
+
import sys
|
|
11
|
+
from typing import Sequence, cast
|
|
12
|
+
from zipfile import ZipFile
|
|
13
|
+
|
|
14
|
+
from pdf2image import convert_from_path, pdfinfo_from_path
|
|
15
|
+
|
|
16
|
+
TWIPS_PER_INCH: int = 1440
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def ensure_system_tools() -> None:
|
|
20
|
+
missing: list[str] = []
|
|
21
|
+
for tool in ("soffice", "pdftoppm"):
|
|
22
|
+
if which(tool) is None:
|
|
23
|
+
missing.append(tool)
|
|
24
|
+
if missing:
|
|
25
|
+
tools = ", ".join(missing)
|
|
26
|
+
raise RuntimeError(
|
|
27
|
+
f"Missing required system tool(s): {tools}. Install LibreOffice and Poppler, then retry."
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def calc_dpi_via_ooxml_docx(input_path: str, max_w_px: int, max_h_px: int) -> int:
|
|
32
|
+
"""Calculate DPI from OOXML `word/document.xml` page size (w:pgSz in twips).
|
|
33
|
+
|
|
34
|
+
DOCX stores page dimensions in section properties as twips (1/1440 inch).
|
|
35
|
+
We read the first encountered section's page size and compute an isotropic DPI
|
|
36
|
+
that fits within the target max pixel dimensions.
|
|
37
|
+
"""
|
|
38
|
+
with ZipFile(input_path, "r") as zf:
|
|
39
|
+
xml = zf.read("word/document.xml")
|
|
40
|
+
root = ET.fromstring(xml)
|
|
41
|
+
ns = {"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}
|
|
42
|
+
|
|
43
|
+
# Common placements: w:body/w:sectPr or w:body/w:p/w:pPr/w:sectPr
|
|
44
|
+
sect_pr = root.find(".//w:sectPr", ns)
|
|
45
|
+
if sect_pr is None:
|
|
46
|
+
raise RuntimeError("Section properties not found in document.xml")
|
|
47
|
+
pg_sz = sect_pr.find("w:pgSz", ns)
|
|
48
|
+
if pg_sz is None:
|
|
49
|
+
raise RuntimeError("Page size not found in section properties")
|
|
50
|
+
|
|
51
|
+
# Values are in twips
|
|
52
|
+
w_twips_str = pg_sz.get(
|
|
53
|
+
"{http://schemas.openxmlformats.org/wordprocessingml/2006/main}w"
|
|
54
|
+
) or pg_sz.get("w")
|
|
55
|
+
h_twips_str = pg_sz.get(
|
|
56
|
+
"{http://schemas.openxmlformats.org/wordprocessingml/2006/main}h"
|
|
57
|
+
) or pg_sz.get("h")
|
|
58
|
+
|
|
59
|
+
if not w_twips_str or not h_twips_str:
|
|
60
|
+
raise RuntimeError("Page size attributes missing in pgSz")
|
|
61
|
+
|
|
62
|
+
width_in = int(w_twips_str) / TWIPS_PER_INCH
|
|
63
|
+
height_in = int(h_twips_str) / TWIPS_PER_INCH
|
|
64
|
+
if width_in <= 0 or height_in <= 0:
|
|
65
|
+
raise RuntimeError("Invalid page size values in document.xml")
|
|
66
|
+
return round(min(max_w_px / width_in, max_h_px / height_in))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def calc_dpi_via_pdf(input_path: str, max_w_px: int, max_h_px: int) -> int:
|
|
70
|
+
"""Convert input to PDF and compute DPI from its page size."""
|
|
71
|
+
with tempfile.TemporaryDirectory(prefix="soffice_profile_") as user_profile:
|
|
72
|
+
with tempfile.TemporaryDirectory(prefix="soffice_convert_") as convert_tmp_dir:
|
|
73
|
+
stem = splitext(basename(input_path))[0]
|
|
74
|
+
pdf_path = convert_to_pdf(input_path, user_profile, convert_tmp_dir, stem)
|
|
75
|
+
if not (pdf_path and exists(pdf_path)):
|
|
76
|
+
raise RuntimeError("Failed to convert input to PDF for DPI computation.")
|
|
77
|
+
|
|
78
|
+
info = pdfinfo_from_path(pdf_path)
|
|
79
|
+
size_val = info.get("Page size")
|
|
80
|
+
if not size_val:
|
|
81
|
+
for k, v in info.items():
|
|
82
|
+
if isinstance(v, str) and "size" in k.lower() and "pts" in v:
|
|
83
|
+
size_val = v
|
|
84
|
+
break
|
|
85
|
+
if not isinstance(size_val, str):
|
|
86
|
+
raise RuntimeError("Failed to read PDF page size for DPI computation.")
|
|
87
|
+
|
|
88
|
+
m = re.search(r"(\d+)\s*x\s*(\d+)\s*pts", size_val)
|
|
89
|
+
if not m:
|
|
90
|
+
raise RuntimeError("Unrecognized PDF page size format.")
|
|
91
|
+
width_pts = int(m.group(1))
|
|
92
|
+
height_pts = int(m.group(2))
|
|
93
|
+
width_in = width_pts / 72.0
|
|
94
|
+
height_in = height_pts / 72.0
|
|
95
|
+
if width_in <= 0 or height_in <= 0:
|
|
96
|
+
raise RuntimeError("Invalid PDF page size values.")
|
|
97
|
+
return round(min(max_w_px / width_in, max_h_px / height_in))
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def run_cmd_no_check(cmd: list[str]) -> None:
|
|
101
|
+
subprocess.run(
|
|
102
|
+
cmd,
|
|
103
|
+
check=False,
|
|
104
|
+
stdout=subprocess.DEVNULL,
|
|
105
|
+
stderr=subprocess.DEVNULL,
|
|
106
|
+
env=os.environ.copy(),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def convert_to_pdf(
|
|
111
|
+
doc_path: str,
|
|
112
|
+
user_profile: str,
|
|
113
|
+
convert_tmp_dir: str,
|
|
114
|
+
stem: str,
|
|
115
|
+
) -> str:
|
|
116
|
+
# Try direct DOC(X) -> PDF
|
|
117
|
+
cmd_pdf = [
|
|
118
|
+
"soffice",
|
|
119
|
+
"-env:UserInstallation=file://" + user_profile,
|
|
120
|
+
"--invisible",
|
|
121
|
+
"--headless",
|
|
122
|
+
"--norestore",
|
|
123
|
+
"--convert-to",
|
|
124
|
+
"pdf",
|
|
125
|
+
"--outdir",
|
|
126
|
+
convert_tmp_dir,
|
|
127
|
+
doc_path,
|
|
128
|
+
]
|
|
129
|
+
run_cmd_no_check(cmd_pdf)
|
|
130
|
+
|
|
131
|
+
pdf_path = join(convert_tmp_dir, f"{stem}.pdf")
|
|
132
|
+
if exists(pdf_path):
|
|
133
|
+
return pdf_path
|
|
134
|
+
|
|
135
|
+
# Fallback: DOCX -> ODT, then ODT -> PDF
|
|
136
|
+
cmd_odt = [
|
|
137
|
+
"soffice",
|
|
138
|
+
"-env:UserInstallation=file://" + user_profile,
|
|
139
|
+
"--invisible",
|
|
140
|
+
"--headless",
|
|
141
|
+
"--norestore",
|
|
142
|
+
"--convert-to",
|
|
143
|
+
"odt",
|
|
144
|
+
"--outdir",
|
|
145
|
+
convert_tmp_dir,
|
|
146
|
+
doc_path,
|
|
147
|
+
]
|
|
148
|
+
run_cmd_no_check(cmd_odt)
|
|
149
|
+
|
|
150
|
+
odt_path = join(convert_tmp_dir, f"{stem}.odt")
|
|
151
|
+
|
|
152
|
+
if exists(odt_path):
|
|
153
|
+
cmd_odt_pdf = [
|
|
154
|
+
"soffice",
|
|
155
|
+
"-env:UserInstallation=file://" + user_profile,
|
|
156
|
+
"--invisible",
|
|
157
|
+
"--headless",
|
|
158
|
+
"--norestore",
|
|
159
|
+
"--convert-to",
|
|
160
|
+
"pdf",
|
|
161
|
+
"--outdir",
|
|
162
|
+
convert_tmp_dir,
|
|
163
|
+
odt_path,
|
|
164
|
+
]
|
|
165
|
+
run_cmd_no_check(cmd_odt_pdf)
|
|
166
|
+
if exists(pdf_path):
|
|
167
|
+
return pdf_path
|
|
168
|
+
|
|
169
|
+
return ""
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def rasterize(
|
|
173
|
+
doc_path: str,
|
|
174
|
+
out_dir: str,
|
|
175
|
+
dpi: int,
|
|
176
|
+
) -> Sequence[str]:
|
|
177
|
+
"""Rasterise DOCX (or similar) to images placed in out_dir and return their paths.
|
|
178
|
+
|
|
179
|
+
Images are named as page-<N>.<ext> with pages starting at 1.
|
|
180
|
+
"""
|
|
181
|
+
makedirs(out_dir, exist_ok=True)
|
|
182
|
+
doc_path = abspath(doc_path)
|
|
183
|
+
stem = splitext(basename(doc_path))[0]
|
|
184
|
+
|
|
185
|
+
# Use a unique user profile to avoid LibreOffice profile lock when running concurrently
|
|
186
|
+
with tempfile.TemporaryDirectory(prefix="soffice_profile_") as user_profile:
|
|
187
|
+
# Write conversion outputs into a temp directory to avoid any IO oddities
|
|
188
|
+
with tempfile.TemporaryDirectory(prefix="soffice_convert_") as convert_tmp_dir:
|
|
189
|
+
pdf_path = convert_to_pdf(
|
|
190
|
+
doc_path,
|
|
191
|
+
user_profile,
|
|
192
|
+
convert_tmp_dir,
|
|
193
|
+
stem,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
if not pdf_path or not exists(pdf_path):
|
|
197
|
+
raise RuntimeError(
|
|
198
|
+
"Failed to produce PDF for rasterization (direct and ODT fallback)."
|
|
199
|
+
)
|
|
200
|
+
paths_raw = cast(
|
|
201
|
+
list[str],
|
|
202
|
+
convert_from_path(
|
|
203
|
+
pdf_path,
|
|
204
|
+
dpi=dpi,
|
|
205
|
+
fmt="png",
|
|
206
|
+
thread_count=8,
|
|
207
|
+
output_folder=out_dir,
|
|
208
|
+
paths_only=True,
|
|
209
|
+
output_file="page",
|
|
210
|
+
),
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
# Rename convert_from_path's output format f'page{thread_id:04d}-{page_num:02d}.<ext>' to 'page-<num>.<ext>'
|
|
214
|
+
pages: list[tuple[int, str]] = []
|
|
215
|
+
for src_path in paths_raw:
|
|
216
|
+
base = splitext(basename(src_path))[0]
|
|
217
|
+
page_num_str = base.split("-")[-1]
|
|
218
|
+
page_num = int(page_num_str)
|
|
219
|
+
dst_path = join(out_dir, f"page-{page_num}.png")
|
|
220
|
+
replace(src_path, dst_path)
|
|
221
|
+
pages.append((page_num, dst_path))
|
|
222
|
+
pages.sort(key=lambda t: t[0])
|
|
223
|
+
final_paths = [path for _, path in pages]
|
|
224
|
+
return final_paths
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def main() -> None:
|
|
228
|
+
parser = argparse.ArgumentParser(description="Render DOCX-like file to PNG images.")
|
|
229
|
+
parser.add_argument(
|
|
230
|
+
"input_path",
|
|
231
|
+
type=str,
|
|
232
|
+
help="Path to the input DOCX file (or compatible).",
|
|
233
|
+
)
|
|
234
|
+
parser.add_argument(
|
|
235
|
+
"--output_dir",
|
|
236
|
+
type=str,
|
|
237
|
+
default=None,
|
|
238
|
+
help=(
|
|
239
|
+
"Output directory for the rendered images. "
|
|
240
|
+
"Defaults to a folder next to the input named after the input file (without extension)."
|
|
241
|
+
),
|
|
242
|
+
)
|
|
243
|
+
parser.add_argument(
|
|
244
|
+
"--width",
|
|
245
|
+
type=int,
|
|
246
|
+
default=1600,
|
|
247
|
+
help=(
|
|
248
|
+
"Approximate maximum width in pixels after isotropic scaling (default 1600). "
|
|
249
|
+
"The actual value may exceed slightly."
|
|
250
|
+
),
|
|
251
|
+
)
|
|
252
|
+
parser.add_argument(
|
|
253
|
+
"--height",
|
|
254
|
+
type=int,
|
|
255
|
+
default=2000,
|
|
256
|
+
help=(
|
|
257
|
+
"Approximate maximum height in pixels after isotropic scaling (default 2000). "
|
|
258
|
+
"The actual value may exceed slightly."
|
|
259
|
+
),
|
|
260
|
+
)
|
|
261
|
+
parser.add_argument(
|
|
262
|
+
"--dpi",
|
|
263
|
+
type=int,
|
|
264
|
+
default=None,
|
|
265
|
+
help=("Override computed DPI. If provided, skips DOCX/PDF-based DPI calculation."),
|
|
266
|
+
)
|
|
267
|
+
args = parser.parse_args()
|
|
268
|
+
|
|
269
|
+
try:
|
|
270
|
+
ensure_system_tools()
|
|
271
|
+
|
|
272
|
+
input_path = abspath(expanduser(args.input_path))
|
|
273
|
+
out_dir = (
|
|
274
|
+
abspath(expanduser(args.output_dir)) if args.output_dir else splitext(input_path)[0]
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
if args.dpi is not None:
|
|
278
|
+
dpi = int(args.dpi)
|
|
279
|
+
else:
|
|
280
|
+
try:
|
|
281
|
+
if input_path.lower().endswith((".docx", ".docm", ".dotx", ".dotm")):
|
|
282
|
+
dpi = calc_dpi_via_ooxml_docx(input_path, args.width, args.height)
|
|
283
|
+
else:
|
|
284
|
+
raise RuntimeError("Skip OOXML DPI; not a DOCX container")
|
|
285
|
+
except Exception:
|
|
286
|
+
dpi = calc_dpi_via_pdf(input_path, args.width, args.height)
|
|
287
|
+
|
|
288
|
+
rasterize(input_path, out_dir, dpi)
|
|
289
|
+
print("Pages rendered to " + out_dir)
|
|
290
|
+
except RuntimeError as exc:
|
|
291
|
+
print(f"Error: {exc}", file=sys.stderr)
|
|
292
|
+
raise SystemExit(1)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
if __name__ == "__main__":
|
|
296
|
+
main()
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
© 2025 Anthropic, PBC. All rights reserved.
|
|
2
|
-
|
|
3
|
-
LICENSE: Use of these materials (including all code, prompts, assets, files,
|
|
4
|
-
and other components of this Skill) is governed by your agreement with
|
|
5
|
-
Anthropic regarding use of Anthropic's services. If no separate agreement
|
|
6
|
-
exists, use is governed by Anthropic's Consumer Terms of Service or
|
|
7
|
-
Commercial Terms of Service, as applicable:
|
|
8
|
-
https://www.anthropic.com/legal/consumer-terms
|
|
9
|
-
https://www.anthropic.com/legal/commercial-terms
|
|
10
|
-
Your applicable agreement is referred to as the "Agreement." "Services" are
|
|
11
|
-
as defined in the Agreement.
|
|
12
|
-
|
|
13
|
-
ADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the
|
|
14
|
-
contrary, users may not:
|
|
15
|
-
|
|
16
|
-
- Extract these materials from the Services or retain copies of these
|
|
17
|
-
materials outside the Services
|
|
18
|
-
- Reproduce or copy these materials, except for temporary copies created
|
|
19
|
-
automatically during authorized use of the Services
|
|
20
|
-
- Create derivative works based on these materials
|
|
21
|
-
- Distribute, sublicense, or transfer these materials to any third party
|
|
22
|
-
- Make, offer to sell, sell, or import any inventions embodied in these
|
|
23
|
-
materials
|
|
24
|
-
- Reverse engineer, decompile, or disassemble these materials
|
|
25
|
-
|
|
26
|
-
The receipt, viewing, or possession of these materials does not convey or
|
|
27
|
-
imply any license or right beyond those expressly granted above.
|
|
28
|
-
|
|
29
|
-
Anthropic retains all right, title, and interest in these materials,
|
|
30
|
-
including all copyrights, patents, and other intellectual property rights.
|
|
1
|
+
© 2025 Anthropic, PBC. All rights reserved.
|
|
2
|
+
|
|
3
|
+
LICENSE: Use of these materials (including all code, prompts, assets, files,
|
|
4
|
+
and other components of this Skill) is governed by your agreement with
|
|
5
|
+
Anthropic regarding use of Anthropic's services. If no separate agreement
|
|
6
|
+
exists, use is governed by Anthropic's Consumer Terms of Service or
|
|
7
|
+
Commercial Terms of Service, as applicable:
|
|
8
|
+
https://www.anthropic.com/legal/consumer-terms
|
|
9
|
+
https://www.anthropic.com/legal/commercial-terms
|
|
10
|
+
Your applicable agreement is referred to as the "Agreement." "Services" are
|
|
11
|
+
as defined in the Agreement.
|
|
12
|
+
|
|
13
|
+
ADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the
|
|
14
|
+
contrary, users may not:
|
|
15
|
+
|
|
16
|
+
- Extract these materials from the Services or retain copies of these
|
|
17
|
+
materials outside the Services
|
|
18
|
+
- Reproduce or copy these materials, except for temporary copies created
|
|
19
|
+
automatically during authorized use of the Services
|
|
20
|
+
- Create derivative works based on these materials
|
|
21
|
+
- Distribute, sublicense, or transfer these materials to any third party
|
|
22
|
+
- Make, offer to sell, sell, or import any inventions embodied in these
|
|
23
|
+
materials
|
|
24
|
+
- Reverse engineer, decompile, or disassemble these materials
|
|
25
|
+
|
|
26
|
+
The receipt, viewing, or possession of these materials does not convey or
|
|
27
|
+
imply any license or right beyond those expressly granted above.
|
|
28
|
+
|
|
29
|
+
Anthropic retains all right, title, and interest in these materials,
|
|
30
|
+
including all copyrights, patents, and other intellectual property rights.
|