@nguyenphp/antigravity-marketing 1.0.16 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +187 -74
- package/bin/index.js +4 -4
- package/package.json +4 -3
- package/templates/.agent/agents/backend-specialist.md +263 -0
- package/templates/.agent/agents/database-architect.md +226 -0
- package/templates/.agent/agents/debugger.md +225 -0
- package/templates/.agent/agents/devops-engineer.md +242 -0
- package/templates/.agent/agents/documentation-writer.md +104 -0
- package/templates/.agent/agents/explorer-agent.md +73 -0
- package/templates/.agent/agents/frontend-specialist.md +527 -0
- package/templates/.agent/agents/game-developer.md +162 -0
- package/templates/.agent/agents/mobile-developer.md +377 -0
- package/templates/.agent/agents/orchestrator.md +400 -0
- package/templates/.agent/agents/penetration-tester.md +188 -0
- package/templates/.agent/agents/performance-optimizer.md +187 -0
- package/templates/.agent/agents/project-planner.md +403 -0
- package/templates/.agent/agents/security-auditor.md +170 -0
- package/templates/.agent/agents/seo-specialist.md +111 -0
- package/templates/.agent/agents/test-engineer.md +158 -0
- package/templates/.agent/rules/GEMINI.md +248 -0
- package/templates/.agent/skills/analytics-marketing/SKILL.md +172 -324
- package/templates/.agent/skills/api-patterns/SKILL.md +81 -0
- package/templates/.agent/skills/api-patterns/api-style.md +42 -0
- package/templates/.agent/skills/api-patterns/auth.md +24 -0
- package/templates/.agent/skills/api-patterns/documentation.md +26 -0
- package/templates/.agent/skills/api-patterns/graphql.md +41 -0
- package/templates/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/templates/.agent/skills/api-patterns/response.md +37 -0
- package/templates/.agent/skills/api-patterns/rest.md +40 -0
- package/templates/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/templates/.agent/skills/api-patterns/security-testing.md +122 -0
- package/templates/.agent/skills/api-patterns/trpc.md +41 -0
- package/templates/.agent/skills/api-patterns/versioning.md +22 -0
- package/templates/.agent/skills/app-builder/SKILL.md +75 -0
- package/templates/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/templates/.agent/skills/app-builder/feature-building.md +53 -0
- package/templates/.agent/skills/app-builder/project-detection.md +34 -0
- package/templates/.agent/skills/app-builder/scaffolding.md +118 -0
- package/templates/.agent/skills/app-builder/tech-stack.md +40 -0
- package/templates/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/templates/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/templates/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/templates/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/templates/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/templates/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/templates/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/templates/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/templates/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +82 -0
- package/templates/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +100 -0
- package/templates/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +106 -0
- package/templates/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +101 -0
- package/templates/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/templates/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +93 -0
- package/templates/.agent/skills/architecture/SKILL.md +55 -0
- package/templates/.agent/skills/architecture/context-discovery.md +43 -0
- package/templates/.agent/skills/architecture/examples.md +94 -0
- package/templates/.agent/skills/architecture/pattern-selection.md +68 -0
- package/templates/.agent/skills/architecture/patterns-reference.md +50 -0
- package/templates/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/templates/.agent/skills/banner-design/SKILL.md +192 -0
- package/templates/.agent/skills/banner-design/references/banner-sizes-and-styles.md +118 -0
- package/templates/.agent/skills/bash-linux/SKILL.md +199 -0
- package/templates/.agent/skills/behavioral-modes/SKILL.md +242 -0
- package/templates/.agent/skills/brainstorming/SKILL.md +163 -0
- package/templates/.agent/skills/brainstorming/dynamic-questioning.md +350 -0
- package/templates/.agent/skills/brand/SKILL.md +97 -0
- package/templates/.agent/skills/brand/references/approval-checklist.md +169 -0
- package/templates/.agent/skills/brand/references/asset-organization.md +157 -0
- package/templates/.agent/skills/brand/references/brand-guideline-template.md +140 -0
- package/templates/.agent/skills/brand/references/color-palette-management.md +186 -0
- package/templates/.agent/skills/brand/references/consistency-checklist.md +94 -0
- package/templates/.agent/skills/brand/references/logo-usage-rules.md +185 -0
- package/templates/.agent/skills/brand/references/messaging-framework.md +85 -0
- package/templates/.agent/skills/brand/references/typography-specifications.md +214 -0
- package/templates/.agent/skills/brand/references/update.md +118 -0
- package/templates/.agent/skills/brand/references/visual-identity.md +96 -0
- package/templates/.agent/skills/brand/references/voice-framework.md +88 -0
- package/templates/.agent/skills/brand/scripts/extract-colors.cjs +341 -0
- package/templates/.agent/skills/brand/scripts/inject-brand-context.cjs +349 -0
- package/templates/.agent/skills/brand/scripts/sync-brand-to-tokens.cjs +266 -0
- package/templates/.agent/skills/brand/scripts/validate-asset.cjs +387 -0
- package/templates/.agent/skills/brand/templates/brand-guidelines-starter.md +275 -0
- package/templates/.agent/skills/clean-code/SKILL.md +201 -0
- package/templates/.agent/skills/code-review-checklist/SKILL.md +109 -0
- package/templates/.agent/skills/copywriting/SKILL.md +250 -0
- package/templates/.agent/skills/database-design/SKILL.md +52 -0
- package/templates/.agent/skills/database-design/database-selection.md +43 -0
- package/templates/.agent/skills/database-design/indexing.md +39 -0
- package/templates/.agent/skills/database-design/migrations.md +48 -0
- package/templates/.agent/skills/database-design/optimization.md +36 -0
- package/templates/.agent/skills/database-design/orm-selection.md +30 -0
- package/templates/.agent/skills/database-design/schema-design.md +56 -0
- package/templates/.agent/skills/database-design/scripts/schema_validator.py +172 -0
- package/templates/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/templates/.agent/skills/docker-expert/SKILL.md +409 -0
- package/templates/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/templates/.agent/skills/frontend-design/color-system.md +311 -0
- package/templates/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/templates/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/templates/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/templates/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
- package/templates/.agent/skills/frontend-design/typography-system.md +345 -0
- package/templates/.agent/skills/frontend-design/ux-psychology.md +541 -0
- package/templates/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/templates/.agent/skills/frontend-slides/SKILL.md +92 -0
- package/templates/.agent/skills/frontend-slides/STYLE_PRESETS.md +347 -0
- package/templates/.agent/skills/frontend-slides/animation-patterns.md +110 -0
- package/templates/.agent/skills/frontend-slides/examples/n8n-jupviec-automation.html +789 -0
- package/templates/.agent/skills/frontend-slides/examples/n8n-jupviec-automation.pptx +0 -0
- package/templates/.agent/skills/frontend-slides/html-template.md +347 -0
- package/templates/.agent/skills/frontend-slides/scripts/export-pptx.py +58 -0
- package/templates/.agent/skills/frontend-slides/scripts/extract-pptx.py +96 -0
- package/templates/.agent/skills/frontend-slides/viewport-base.css +153 -0
- package/templates/.agent/skills/game-development/2d-games/SKILL.md +119 -0
- package/templates/.agent/skills/game-development/3d-games/SKILL.md +135 -0
- package/templates/.agent/skills/game-development/SKILL.md +167 -0
- package/templates/.agent/skills/game-development/game-art/SKILL.md +185 -0
- package/templates/.agent/skills/game-development/game-audio/SKILL.md +190 -0
- package/templates/.agent/skills/game-development/game-design/SKILL.md +129 -0
- package/templates/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
- package/templates/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
- package/templates/.agent/skills/game-development/pc-games/SKILL.md +144 -0
- package/templates/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
- package/templates/.agent/skills/game-development/web-games/SKILL.md +150 -0
- package/templates/.agent/skills/geo-fundamentals/SKILL.md +156 -0
- package/templates/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
- package/templates/.agent/skills/growth-engine/SKILL.md +244 -0
- package/templates/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/templates/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/templates/.agent/skills/lint-and-validate/SKILL.md +45 -0
- package/templates/.agent/skills/lint-and-validate/scripts/lint_runner.py +172 -0
- package/templates/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
- package/templates/.agent/skills/marketing-report-expert/SKILL.md +70 -0
- package/templates/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/templates/.agent/skills/minimax-docx/LICENSE +21 -0
- package/templates/.agent/skills/minimax-docx/SKILL.md +274 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/academic_styles.xml +250 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/corporate_styles.xml +284 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/default_styles.xml +449 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/aesthetic-rules.xsd +470 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/business-rules.xsd +130 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/common-types.xsd +159 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/wml-subset.xsd +589 -0
- package/templates/.agent/skills/minimax-docx/references/cjk_typography.md +357 -0
- package/templates/.agent/skills/minimax-docx/references/cjk_university_template_guide.md +184 -0
- package/templates/.agent/skills/minimax-docx/references/comments_guide.md +191 -0
- package/templates/.agent/skills/minimax-docx/references/design_good_bad_examples.md +829 -0
- package/templates/.agent/skills/minimax-docx/references/design_principles.md +819 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_element_order.md +308 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part1.md +4061 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part2.md +2820 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part3.md +3381 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_namespaces.md +82 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_units.md +72 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_a_create.md +284 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_b_edit_content.md +295 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_c_apply_template.md +456 -0
- package/templates/.agent/skills/minimax-docx/references/track_changes_guide.md +200 -0
- package/templates/.agent/skills/minimax-docx/references/troubleshooting.md +506 -0
- package/templates/.agent/skills/minimax-docx/references/typography_guide.md +294 -0
- package/templates/.agent/skills/minimax-docx/references/xsd_validation_guide.md +158 -0
- package/templates/.agent/skills/minimax-docx/scripts/doc_to_docx.sh +40 -0
- package/templates/.agent/skills/minimax-docx/scripts/docx_preview.sh +37 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj +19 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/Program.cs +18 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/AnalyzeCommand.cs +147 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ApplyTemplateCommand.cs +322 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/CreateCommand.cs +324 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/DiffCommand.cs +155 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/EditContentCommand.cs +487 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/FixOrderCommand.cs +108 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/MergeRunsCommand.cs +122 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ValidateCommand.cs +107 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/MiniMaxAIDocx.Core.csproj +15 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/CommentSynchronizer.cs +169 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/ElementOrder.cs +80 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/NamespaceConstants.cs +42 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/RunMerger.cs +81 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/StyleAnalyzer.cs +81 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/TrackChangesHelper.cs +99 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/UnitConverter.cs +23 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples.cs +1832 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch1.cs +910 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch2.cs +999 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch3.cs +1048 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch4.cs +1038 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/CharacterFormattingSamples.cs +1020 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/DocumentCreationSamples.cs +1121 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FieldAndTocSamples.cs +624 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FootnoteAndCommentSamples.cs +675 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/HeaderFooterSamples.cs +838 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ImageSamples.cs +917 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ListAndNumberingSamples.cs +826 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ParagraphFormattingSamples.cs +1199 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/StyleSystemSamples.cs +1487 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TableSamples.cs +1163 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TrackChangesSamples.cs +595 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/CjkHelper.cs +39 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/FontDefaults.cs +24 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/PageSizes.cs +20 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/BusinessRuleValidator.cs +224 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/GateCheckValidator.cs +148 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/ValidationResult.cs +23 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/XsdValidator.cs +69 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.slnx +4 -0
- package/templates/.agent/skills/minimax-docx/scripts/env_check.sh +196 -0
- package/templates/.agent/skills/minimax-docx/scripts/setup.ps1 +274 -0
- package/templates/.agent/skills/minimax-docx/scripts/setup.sh +504 -0
- package/templates/.agent/skills/minimax-multimodal-toolkit/SKILL.md +359 -0
- package/templates/.agent/skills/minimax-pdf/README.md +222 -0
- package/templates/.agent/skills/minimax-pdf/SKILL.md +201 -0
- package/templates/.agent/skills/minimax-pdf/design/design.md +381 -0
- package/templates/.agent/skills/minimax-pdf/scripts/cover.py +1579 -0
- package/templates/.agent/skills/minimax-pdf/scripts/fill_inspect.py +200 -0
- package/templates/.agent/skills/minimax-pdf/scripts/fill_write.py +242 -0
- package/templates/.agent/skills/minimax-pdf/scripts/make.sh +491 -0
- package/templates/.agent/skills/minimax-pdf/scripts/merge.py +112 -0
- package/templates/.agent/skills/minimax-pdf/scripts/palette.py +559 -0
- package/templates/.agent/skills/minimax-pdf/scripts/reformat_parse.py +374 -0
- package/templates/.agent/skills/minimax-pdf/scripts/render_body.py +1055 -0
- package/templates/.agent/skills/minimax-pdf/scripts/render_cover.cjs +111 -0
- package/templates/.agent/skills/minimax-xlsx/SKILL.md +138 -0
- package/templates/.agent/skills/minimax-xlsx/references/create.md +691 -0
- package/templates/.agent/skills/minimax-xlsx/references/edit.md +684 -0
- package/templates/.agent/skills/minimax-xlsx/references/fix.md +37 -0
- package/templates/.agent/skills/minimax-xlsx/references/format.md +768 -0
- package/templates/.agent/skills/minimax-xlsx/references/ooxml-cheatsheet.md +231 -0
- package/templates/.agent/skills/minimax-xlsx/references/read-analyze.md +97 -0
- package/templates/.agent/skills/minimax-xlsx/references/validate.md +772 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/formula_check.py +422 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/libreoffice_recalc.py +248 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/shared_strings_builder.py +163 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/style_audit.py +575 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_add_column.py +395 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_insert_row.py +274 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_pack.py +87 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_reader.py +362 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_shift_rows.py +396 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_unpack.py +130 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/[Content_Types].xml +9 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/_rels/.rels +6 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/_rels/workbook.xml.rels +19 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/sharedStrings.xml +33 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/styles.xml +160 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/workbook.xml +30 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/worksheets/sheet1.xml +70 -0
- package/templates/.agent/skills/mobile-design/SKILL.md +394 -0
- package/templates/.agent/skills/mobile-design/decision-trees.md +516 -0
- package/templates/.agent/skills/mobile-design/mobile-backend.md +491 -0
- package/templates/.agent/skills/mobile-design/mobile-color-system.md +420 -0
- package/templates/.agent/skills/mobile-design/mobile-debugging.md +122 -0
- package/templates/.agent/skills/mobile-design/mobile-design-thinking.md +357 -0
- package/templates/.agent/skills/mobile-design/mobile-navigation.md +458 -0
- package/templates/.agent/skills/mobile-design/mobile-performance.md +767 -0
- package/templates/.agent/skills/mobile-design/mobile-testing.md +356 -0
- package/templates/.agent/skills/mobile-design/mobile-typography.md +433 -0
- package/templates/.agent/skills/mobile-design/platform-android.md +666 -0
- package/templates/.agent/skills/mobile-design/platform-ios.md +561 -0
- package/templates/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
- package/templates/.agent/skills/mobile-design/touch-psychology.md +537 -0
- package/templates/.agent/skills/nestjs-expert/SKILL.md +552 -0
- package/templates/.agent/skills/nextjs-best-practices/SKILL.md +203 -0
- package/templates/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
- package/templates/.agent/skills/parallel-agents/SKILL.md +175 -0
- package/templates/.agent/skills/performance-profiling/SKILL.md +143 -0
- package/templates/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
- package/templates/.agent/skills/plan-writing/SKILL.md +152 -0
- package/templates/.agent/skills/powershell-windows/SKILL.md +167 -0
- package/templates/.agent/skills/ppc-advertising/SKILL.md +183 -475
- package/templates/.agent/skills/pptx-generator/SKILL.md +249 -0
- package/templates/.agent/skills/pptx-generator/references/design-system.md +392 -0
- package/templates/.agent/skills/pptx-generator/references/editing.md +162 -0
- package/templates/.agent/skills/pptx-generator/references/pitfalls.md +112 -0
- package/templates/.agent/skills/pptx-generator/references/pptxgenjs.md +420 -0
- package/templates/.agent/skills/pptx-generator/references/slide-types.md +413 -0
- package/templates/.agent/skills/prisma-expert/SKILL.md +355 -0
- package/templates/.agent/skills/python-patterns/SKILL.md +441 -0
- package/templates/.agent/skills/react-patterns/SKILL.md +198 -0
- package/templates/.agent/skills/red-team-tactics/SKILL.md +199 -0
- package/templates/.agent/skills/remotion-best-practices/SKILL.md +45 -111
- package/templates/.agent/skills/remotion-best-practices/rules/3d.md +4 -4
- package/templates/.agent/skills/remotion-best-practices/rules/animations.md +5 -7
- package/templates/.agent/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/templates/.agent/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/templates/.agent/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +103 -0
- package/templates/.agent/skills/remotion-best-practices/rules/assets.md +78 -0
- package/templates/.agent/skills/remotion-best-practices/rules/audio-visualization.md +198 -0
- package/templates/.agent/skills/remotion-best-practices/rules/audio.md +1 -4
- package/templates/.agent/skills/remotion-best-practices/rules/calculate-metadata.md +47 -17
- package/templates/.agent/skills/remotion-best-practices/rules/can-decode.md +75 -0
- package/templates/.agent/skills/remotion-best-practices/rules/charts.md +80 -48
- package/templates/.agent/skills/remotion-best-practices/rules/compositions.md +22 -14
- package/templates/.agent/skills/remotion-best-practices/rules/display-captions.md +79 -21
- package/templates/.agent/skills/remotion-best-practices/rules/extract-frames.md +229 -0
- package/templates/.agent/skills/remotion-best-practices/rules/ffmpeg.md +38 -0
- package/templates/.agent/skills/remotion-best-practices/rules/fonts.md +96 -54
- package/templates/.agent/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/templates/.agent/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/templates/.agent/skills/remotion-best-practices/rules/get-video-duration.md +60 -0
- package/templates/.agent/skills/remotion-best-practices/rules/gifs.md +21 -18
- package/templates/.agent/skills/remotion-best-practices/rules/images.md +6 -2
- package/templates/.agent/skills/remotion-best-practices/rules/import-srt-captions.md +69 -0
- package/templates/.agent/skills/remotion-best-practices/rules/light-leaks.md +73 -0
- package/templates/.agent/skills/remotion-best-practices/rules/lottie.md +10 -7
- package/templates/.agent/skills/remotion-best-practices/rules/maps.md +412 -0
- package/templates/.agent/skills/remotion-best-practices/rules/measuring-dom-nodes.md +34 -0
- package/templates/.agent/skills/remotion-best-practices/rules/measuring-text.md +140 -0
- package/templates/.agent/skills/remotion-best-practices/rules/parameters.md +109 -0
- package/templates/.agent/skills/remotion-best-practices/rules/sequencing.md +13 -1
- package/templates/.agent/skills/remotion-best-practices/rules/sfx.md +26 -0
- package/templates/.agent/skills/remotion-best-practices/rules/subtitles.md +36 -0
- package/templates/.agent/skills/remotion-best-practices/rules/tailwind.md +11 -0
- package/templates/.agent/skills/remotion-best-practices/rules/text-animations.md +4 -115
- package/templates/.agent/skills/remotion-best-practices/rules/timing.md +19 -19
- package/templates/.agent/skills/remotion-best-practices/rules/transcribe-captions.md +70 -0
- package/templates/.agent/skills/remotion-best-practices/rules/transitions.md +117 -42
- package/templates/.agent/skills/remotion-best-practices/rules/transparent-videos.md +106 -0
- package/templates/.agent/skills/remotion-best-practices/rules/trimming.md +51 -0
- package/templates/.agent/skills/remotion-best-practices/rules/voiceover.md +99 -0
- package/templates/.agent/skills/seo-fundamentals/SKILL.md +83 -441
- package/templates/.agent/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
- package/templates/.agent/skills/server-management/SKILL.md +161 -0
- package/templates/.agent/skills/systematic-debugging/SKILL.md +109 -0
- package/templates/.agent/skills/tdd-workflow/SKILL.md +149 -0
- package/templates/.agent/skills/testing-patterns/SKILL.md +178 -0
- package/templates/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
- package/templates/.agent/skills/tutorial-video-expert/SKILL.md +88 -0
- package/templates/.agent/skills/typescript-expert/SKILL.md +429 -0
- package/templates/.agent/skills/ui-ux-pro-max/SKILL.md +1 -1
- package/templates/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/templates/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/templates/.agent/skills/ui-ux-pro-max/scripts/core.py +257 -0
- package/templates/.agent/skills/ui-ux-pro-max/scripts/design_system.py +487 -0
- package/templates/.agent/skills/ui-ux-pro-max/scripts/search.py +76 -0
- package/templates/.agent/skills/vision-analysis/SKILL.md +174 -0
- package/templates/.agent/skills/vue-expert/SKILL.md +374 -0
- package/templates/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
- package/templates/.agent/skills/vulnerability-scanner/checklists.md +121 -0
- package/templates/.agent/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
- package/templates/.agent/skills/webapp-testing/SKILL.md +187 -0
- package/templates/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
- package/templates/.agent/workflows/analyze.md +3 -0
- package/templates/.agent/workflows/brainstorm.md +113 -0
- package/templates/.agent/workflows/brand-report.md +44 -0
- package/templates/.agent/workflows/create.md +59 -0
- package/templates/.agent/workflows/debug.md +103 -0
- package/templates/.agent/workflows/deploy.md +176 -0
- package/templates/.agent/workflows/enhance.md +63 -0
- package/templates/.agent/workflows/orchestrate.md +237 -0
- package/templates/.agent/workflows/plan.md +89 -0
- package/templates/.agent/workflows/preview.md +80 -0
- package/templates/.agent/workflows/report.md +49 -0
- package/templates/.agent/workflows/status.md +86 -0
- package/templates/.agent/workflows/test.md +144 -0
- package/templates/.agent/workflows/ui-ux-pro-max.md +231 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
using System.CommandLine;
|
|
2
|
+
using System.IO.Compression;
|
|
3
|
+
using System.Xml.Linq;
|
|
4
|
+
|
|
5
|
+
namespace MiniMaxAIDocx.Core.Commands;
|
|
6
|
+
|
|
7
|
+
public static class MergeRunsCommand
|
|
8
|
+
{
|
|
9
|
+
private static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
10
|
+
|
|
11
|
+
public static Command Create()
|
|
12
|
+
{
|
|
13
|
+
var inputOption = new Option<string>("--input") { Description = "DOCX file to optimize", Required = true };
|
|
14
|
+
var outputOption = new Option<string>("--output") { Description = "Output path (default: overwrite input)" };
|
|
15
|
+
var dryRunOption = new Option<bool>("--dry-run") { Description = "Report without modifying" };
|
|
16
|
+
|
|
17
|
+
var cmd = new Command("merge-runs", "Merge adjacent runs with identical formatting")
|
|
18
|
+
{
|
|
19
|
+
inputOption, outputOption, dryRunOption
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
cmd.SetAction((parseResult) =>
|
|
23
|
+
{
|
|
24
|
+
var input = parseResult.GetValue(inputOption)!;
|
|
25
|
+
var output = parseResult.GetValue(outputOption) ?? input;
|
|
26
|
+
var dryRun = parseResult.GetValue(dryRunOption);
|
|
27
|
+
|
|
28
|
+
if (!File.Exists(input))
|
|
29
|
+
{
|
|
30
|
+
Console.Error.WriteLine($"File not found: {input}");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var tempPath = Path.GetTempFileName();
|
|
35
|
+
File.Copy(input, tempPath, true);
|
|
36
|
+
|
|
37
|
+
using var zip = ZipFile.Open(tempPath, ZipArchiveMode.Update);
|
|
38
|
+
var entry = zip.GetEntry("word/document.xml");
|
|
39
|
+
if (entry == null)
|
|
40
|
+
{
|
|
41
|
+
Console.Error.WriteLine("Not a valid DOCX: missing word/document.xml");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
XDocument doc;
|
|
46
|
+
using (var stream = entry.Open())
|
|
47
|
+
doc = XDocument.Load(stream);
|
|
48
|
+
|
|
49
|
+
int originalCount = 0;
|
|
50
|
+
int mergedCount = 0;
|
|
51
|
+
|
|
52
|
+
foreach (var p in doc.Descendants(W + "p"))
|
|
53
|
+
{
|
|
54
|
+
var runs = p.Elements(W + "r").ToList();
|
|
55
|
+
originalCount += runs.Count;
|
|
56
|
+
|
|
57
|
+
for (int i = runs.Count - 1; i > 0; i--)
|
|
58
|
+
{
|
|
59
|
+
var current = runs[i];
|
|
60
|
+
var previous = runs[i - 1];
|
|
61
|
+
|
|
62
|
+
var curProps = current.Element(W + "rPr")?.ToString() ?? "";
|
|
63
|
+
var prevProps = previous.Element(W + "rPr")?.ToString() ?? "";
|
|
64
|
+
|
|
65
|
+
if (curProps == prevProps)
|
|
66
|
+
{
|
|
67
|
+
// Only merge if both contain only text elements
|
|
68
|
+
var curChildren = current.Elements().Where(e => e.Name != W + "rPr").ToList();
|
|
69
|
+
var prevChildren = previous.Elements().Where(e => e.Name != W + "rPr").ToList();
|
|
70
|
+
|
|
71
|
+
if (curChildren.All(e => e.Name == W + "t") && prevChildren.All(e => e.Name == W + "t"))
|
|
72
|
+
{
|
|
73
|
+
var prevText = previous.Elements(W + "t").LastOrDefault();
|
|
74
|
+
var curText = current.Elements(W + "t").FirstOrDefault();
|
|
75
|
+
|
|
76
|
+
if (prevText != null && curText != null)
|
|
77
|
+
{
|
|
78
|
+
prevText.Value += curText.Value;
|
|
79
|
+
prevText.SetAttributeValue(XNamespace.Xml + "space", "preserve");
|
|
80
|
+
|
|
81
|
+
foreach (var extra in current.Elements(W + "t").Skip(1))
|
|
82
|
+
{
|
|
83
|
+
previous.Add(new XElement(extra));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
current.Remove();
|
|
87
|
+
runs.RemoveAt(i);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
mergedCount += runs.Count;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (dryRun)
|
|
97
|
+
{
|
|
98
|
+
Console.WriteLine($"Original runs: {originalCount}");
|
|
99
|
+
Console.WriteLine($"After merge: {mergedCount}");
|
|
100
|
+
Console.WriteLine($"Reduction: {(originalCount > 0 ? (originalCount - mergedCount) * 100.0 / originalCount : 0):F1}%");
|
|
101
|
+
File.Delete(tempPath);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
entry.Delete();
|
|
106
|
+
var newEntry = zip.CreateEntry("word/document.xml", CompressionLevel.Optimal);
|
|
107
|
+
using (var stream = newEntry.Open())
|
|
108
|
+
doc.Save(stream);
|
|
109
|
+
|
|
110
|
+
zip.Dispose();
|
|
111
|
+
File.Copy(tempPath, output, true);
|
|
112
|
+
File.Delete(tempPath);
|
|
113
|
+
|
|
114
|
+
Console.WriteLine($"Original runs: {originalCount}");
|
|
115
|
+
Console.WriteLine($"After merge: {mergedCount}");
|
|
116
|
+
Console.WriteLine($"Reduction: {(originalCount > 0 ? (originalCount - mergedCount) * 100.0 / originalCount : 0):F1}%");
|
|
117
|
+
Console.WriteLine($"Written to: {output}");
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return cmd;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
using System.CommandLine;
|
|
2
|
+
using System.Text.Json;
|
|
3
|
+
using MiniMaxAIDocx.Core.Validation;
|
|
4
|
+
|
|
5
|
+
namespace MiniMaxAIDocx.Core.Commands;
|
|
6
|
+
|
|
7
|
+
public static class ValidateCommand
|
|
8
|
+
{
|
|
9
|
+
public static Command Create()
|
|
10
|
+
{
|
|
11
|
+
var inputOption = new Option<string>("--input") { Description = "DOCX file to validate", Required = true };
|
|
12
|
+
var xsdOption = new Option<string>("--xsd") { Description = "XSD schema path for XML validation" };
|
|
13
|
+
var businessOption = new Option<bool>("--business") { Description = "Run business rule validation" };
|
|
14
|
+
var gateCheckOption = new Option<string>("--gate-check") { Description = "Template DOCX for gate-check validation" };
|
|
15
|
+
var jsonOption = new Option<bool>("--json") { Description = "Output results as JSON" };
|
|
16
|
+
|
|
17
|
+
var cmd = new Command("validate", "Validate DOCX structure and content")
|
|
18
|
+
{
|
|
19
|
+
inputOption, xsdOption, businessOption, gateCheckOption, jsonOption
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
cmd.SetAction((parseResult) =>
|
|
23
|
+
{
|
|
24
|
+
var input = parseResult.GetValue(inputOption)!;
|
|
25
|
+
var xsd = parseResult.GetValue(xsdOption);
|
|
26
|
+
var business = parseResult.GetValue(businessOption);
|
|
27
|
+
var gateCheck = parseResult.GetValue(gateCheckOption);
|
|
28
|
+
var asJson = parseResult.GetValue(jsonOption);
|
|
29
|
+
|
|
30
|
+
if (!File.Exists(input))
|
|
31
|
+
{
|
|
32
|
+
Console.Error.WriteLine($"File not found: {input}");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var combinedResult = new ValidationResult();
|
|
37
|
+
GateCheckResult? gateResult = null;
|
|
38
|
+
|
|
39
|
+
if (xsd != null)
|
|
40
|
+
{
|
|
41
|
+
var xsdValidator = new XsdValidator();
|
|
42
|
+
combinedResult.Merge(xsdValidator.Validate(input, xsd));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (business)
|
|
46
|
+
{
|
|
47
|
+
var bizValidator = new BusinessRuleValidator();
|
|
48
|
+
combinedResult.Merge(bizValidator.Validate(input));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (gateCheck != null)
|
|
52
|
+
{
|
|
53
|
+
var gateValidator = new GateCheckValidator();
|
|
54
|
+
gateResult = gateValidator.Validate(input, gateCheck);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (asJson)
|
|
58
|
+
{
|
|
59
|
+
var output = new
|
|
60
|
+
{
|
|
61
|
+
isValid = combinedResult.IsValid && (gateResult?.Passed ?? true),
|
|
62
|
+
errors = combinedResult.Errors,
|
|
63
|
+
warnings = combinedResult.Warnings,
|
|
64
|
+
gateCheck = gateResult == null ? null : new
|
|
65
|
+
{
|
|
66
|
+
passed = gateResult.Passed,
|
|
67
|
+
violations = gateResult.Violations
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
Console.WriteLine(JsonSerializer.Serialize(output, new JsonSerializerOptions { WriteIndented = true }));
|
|
71
|
+
}
|
|
72
|
+
else
|
|
73
|
+
{
|
|
74
|
+
if (combinedResult.Errors.Count > 0)
|
|
75
|
+
{
|
|
76
|
+
Console.WriteLine($"ERRORS ({combinedResult.Errors.Count}):");
|
|
77
|
+
foreach (var e in combinedResult.Errors)
|
|
78
|
+
Console.WriteLine($" [{e.Severity}] {e.Message}" + (e.LineNumber > 0 ? $" (line {e.LineNumber}:{e.LinePosition})" : ""));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (combinedResult.Warnings.Count > 0)
|
|
82
|
+
{
|
|
83
|
+
Console.WriteLine($"WARNINGS ({combinedResult.Warnings.Count}):");
|
|
84
|
+
foreach (var w in combinedResult.Warnings)
|
|
85
|
+
Console.WriteLine($" [{w.Severity}] {w.Message}");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (gateResult != null)
|
|
89
|
+
{
|
|
90
|
+
Console.WriteLine(gateResult.Passed ? "GATE CHECK: PASSED" : "GATE CHECK: FAILED");
|
|
91
|
+
foreach (var v in gateResult.Violations)
|
|
92
|
+
Console.WriteLine($" - {v}");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (combinedResult.IsValid && (gateResult?.Passed ?? true))
|
|
96
|
+
Console.WriteLine("Validation: PASSED");
|
|
97
|
+
else
|
|
98
|
+
Console.WriteLine("Validation: FAILED");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!combinedResult.IsValid || gateResult is { Passed: false })
|
|
102
|
+
Environment.ExitCode = 1;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return cmd;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
|
+
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<TargetFramework>net8.0</TargetFramework>
|
|
5
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
6
|
+
<Nullable>enable</Nullable>
|
|
7
|
+
<NeutralLanguage>en</NeutralLanguage>
|
|
8
|
+
</PropertyGroup>
|
|
9
|
+
|
|
10
|
+
<ItemGroup>
|
|
11
|
+
<PackageReference Include="DocumentFormat.OpenXml" Version="3.5.1" />
|
|
12
|
+
<PackageReference Include="System.CommandLine" Version="2.0.5" />
|
|
13
|
+
</ItemGroup>
|
|
14
|
+
|
|
15
|
+
</Project>
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
using DocumentFormat.OpenXml;
|
|
2
|
+
using DocumentFormat.OpenXml.Packaging;
|
|
3
|
+
using DocumentFormat.OpenXml.Wordprocessing;
|
|
4
|
+
|
|
5
|
+
namespace MiniMaxAIDocx.Core.OpenXml;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Manages the 4-file comment system (comments.xml, commentsExtended.xml,
|
|
9
|
+
/// commentsIds.xml, commentsExtensible.xml) plus document.xml markers.
|
|
10
|
+
/// </summary>
|
|
11
|
+
public static class CommentSynchronizer
|
|
12
|
+
{
|
|
13
|
+
/// <summary>
|
|
14
|
+
/// Adds a comment to the document, updating all required parts.
|
|
15
|
+
/// </summary>
|
|
16
|
+
public static int AddComment(WordprocessingDocument doc, string text, string author, string rangeBookmark)
|
|
17
|
+
{
|
|
18
|
+
var mainPart = doc.MainDocumentPart
|
|
19
|
+
?? throw new InvalidOperationException("Document has no main part.");
|
|
20
|
+
|
|
21
|
+
int commentId = GetNextCommentId(doc);
|
|
22
|
+
|
|
23
|
+
// Ensure comments part exists
|
|
24
|
+
var commentsPart = mainPart.WordprocessingCommentsPart
|
|
25
|
+
?? mainPart.AddNewPart<WordprocessingCommentsPart>();
|
|
26
|
+
|
|
27
|
+
if (commentsPart.Comments == null)
|
|
28
|
+
commentsPart.Comments = new Comments();
|
|
29
|
+
|
|
30
|
+
// Create the comment
|
|
31
|
+
var comment = new Comment
|
|
32
|
+
{
|
|
33
|
+
Id = commentId.ToString(),
|
|
34
|
+
Author = author,
|
|
35
|
+
Date = DateTime.UtcNow,
|
|
36
|
+
Initials = author.Length > 0 ? author[..1].ToUpperInvariant() : "A"
|
|
37
|
+
};
|
|
38
|
+
comment.Append(new Paragraph(new Run(new Text(text))));
|
|
39
|
+
commentsPart.Comments.Append(comment);
|
|
40
|
+
|
|
41
|
+
// Add range markers in document body
|
|
42
|
+
var body = mainPart.Document.Body;
|
|
43
|
+
if (body != null)
|
|
44
|
+
{
|
|
45
|
+
// Find bookmark or append at end
|
|
46
|
+
var rangeStart = new CommentRangeStart { Id = commentId.ToString() };
|
|
47
|
+
var rangeEnd = new CommentRangeEnd { Id = commentId.ToString() };
|
|
48
|
+
var reference = new Run(new CommentReference { Id = commentId.ToString() });
|
|
49
|
+
|
|
50
|
+
body.Append(rangeStart);
|
|
51
|
+
body.Append(rangeEnd);
|
|
52
|
+
body.Append(new Paragraph(reference));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return commentId;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/// <summary>
|
|
59
|
+
/// Adds a reply to an existing comment.
|
|
60
|
+
/// </summary>
|
|
61
|
+
public static int AddReply(WordprocessingDocument doc, int parentCommentId, string text, string author)
|
|
62
|
+
{
|
|
63
|
+
var mainPart = doc.MainDocumentPart
|
|
64
|
+
?? throw new InvalidOperationException("Document has no main part.");
|
|
65
|
+
|
|
66
|
+
var commentsPart = mainPart.WordprocessingCommentsPart
|
|
67
|
+
?? throw new InvalidOperationException("Document has no comments part.");
|
|
68
|
+
|
|
69
|
+
int replyId = GetNextCommentId(doc);
|
|
70
|
+
|
|
71
|
+
var reply = new Comment
|
|
72
|
+
{
|
|
73
|
+
Id = replyId.ToString(),
|
|
74
|
+
Author = author,
|
|
75
|
+
Date = DateTime.UtcNow,
|
|
76
|
+
Initials = author.Length > 0 ? author[..1].ToUpperInvariant() : "A"
|
|
77
|
+
};
|
|
78
|
+
reply.Append(new Paragraph(new Run(new Text(text))));
|
|
79
|
+
commentsPart.Comments?.Append(reply);
|
|
80
|
+
|
|
81
|
+
// Link reply to parent via commentsExtended.xml
|
|
82
|
+
LinkReplyToParent(doc, replyId, parentCommentId);
|
|
83
|
+
|
|
84
|
+
return replyId;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// <summary>
|
|
88
|
+
/// Marks a comment as resolved/done by setting done="1" in commentsExtended.xml.
|
|
89
|
+
/// Uses raw XML manipulation since these extended parts lack typed SDK support.
|
|
90
|
+
/// </summary>
|
|
91
|
+
public static void ResolveComment(WordprocessingDocument doc, int commentId)
|
|
92
|
+
{
|
|
93
|
+
var mainPart = doc.MainDocumentPart;
|
|
94
|
+
if (mainPart == null) return;
|
|
95
|
+
|
|
96
|
+
// commentsExtended.xml is an untyped part — manipulate via raw XML
|
|
97
|
+
const string ceUri = "http://schemas.microsoft.com/office/word/2018/wordml/cex";
|
|
98
|
+
foreach (var part in mainPart.Parts)
|
|
99
|
+
{
|
|
100
|
+
if (part.OpenXmlPart.ContentType.Contains("commentsExtensible"))
|
|
101
|
+
{
|
|
102
|
+
using var stream = part.OpenXmlPart.GetStream(FileMode.Open, FileAccess.ReadWrite);
|
|
103
|
+
var xdoc = System.Xml.Linq.XDocument.Load(stream);
|
|
104
|
+
var ns = System.Xml.Linq.XNamespace.Get(ceUri);
|
|
105
|
+
var commentEl = xdoc.Descendants(ns + "comment")
|
|
106
|
+
.FirstOrDefault(e => e.Attribute(ns + "paraId")?.Value != null);
|
|
107
|
+
// Set done flag if element found for this comment
|
|
108
|
+
if (commentEl != null)
|
|
109
|
+
{
|
|
110
|
+
commentEl.SetAttributeValue("done", "1");
|
|
111
|
+
stream.SetLength(0);
|
|
112
|
+
xdoc.Save(stream);
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/// <summary>
|
|
120
|
+
/// Links a reply comment to its parent via commentsExtended.xml (w15:commentEx).
|
|
121
|
+
/// Uses raw XML since the extended comment parts lack typed SDK support.
|
|
122
|
+
/// </summary>
|
|
123
|
+
private static void LinkReplyToParent(WordprocessingDocument doc, int replyId, int parentCommentId)
|
|
124
|
+
{
|
|
125
|
+
var mainPart = doc.MainDocumentPart;
|
|
126
|
+
if (mainPart == null) return;
|
|
127
|
+
|
|
128
|
+
const string w15Uri = "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
129
|
+
var w15 = System.Xml.Linq.XNamespace.Get(w15Uri);
|
|
130
|
+
|
|
131
|
+
// Find or create commentsExtended part
|
|
132
|
+
foreach (var part in mainPart.Parts)
|
|
133
|
+
{
|
|
134
|
+
if (part.OpenXmlPart.ContentType.Contains("commentsExtended"))
|
|
135
|
+
{
|
|
136
|
+
using var stream = part.OpenXmlPart.GetStream(FileMode.Open, FileAccess.ReadWrite);
|
|
137
|
+
var xdoc = System.Xml.Linq.XDocument.Load(stream);
|
|
138
|
+
var root = xdoc.Root;
|
|
139
|
+
if (root == null) return;
|
|
140
|
+
|
|
141
|
+
root.Add(new System.Xml.Linq.XElement(w15 + "commentEx",
|
|
142
|
+
new System.Xml.Linq.XAttribute(w15 + "paraId", replyId.ToString("X8")),
|
|
143
|
+
new System.Xml.Linq.XAttribute(w15 + "paraIdParent", parentCommentId.ToString("X8")),
|
|
144
|
+
new System.Xml.Linq.XAttribute(w15 + "done", "0")));
|
|
145
|
+
|
|
146
|
+
stream.SetLength(0);
|
|
147
|
+
xdoc.Save(stream);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/// <summary>
|
|
154
|
+
/// Finds the maximum existing comment ID and returns the next one.
|
|
155
|
+
/// </summary>
|
|
156
|
+
public static int GetNextCommentId(WordprocessingDocument doc)
|
|
157
|
+
{
|
|
158
|
+
var commentsPart = doc.MainDocumentPart?.WordprocessingCommentsPart;
|
|
159
|
+
if (commentsPart?.Comments == null) return 1;
|
|
160
|
+
|
|
161
|
+
int maxId = 0;
|
|
162
|
+
foreach (var comment in commentsPart.Comments.Elements<Comment>())
|
|
163
|
+
{
|
|
164
|
+
if (comment.Id?.Value != null && int.TryParse(comment.Id.Value, out int id) && id > maxId)
|
|
165
|
+
maxId = id;
|
|
166
|
+
}
|
|
167
|
+
return maxId + 1;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
using System.Xml.Linq;
|
|
2
|
+
|
|
3
|
+
namespace MiniMaxAIDocx.Core.OpenXml;
|
|
4
|
+
|
|
5
|
+
/// <summary>
|
|
6
|
+
/// Defines canonical child element ordering for key OpenXML parent elements
|
|
7
|
+
/// and provides reordering utilities.
|
|
8
|
+
/// </summary>
|
|
9
|
+
public static class ElementOrder
|
|
10
|
+
{
|
|
11
|
+
private static readonly Dictionary<string, string[]> OrderMap = new()
|
|
12
|
+
{
|
|
13
|
+
["w:body"] = ["w:p", "w:tbl", "w:sdt", "w:sectPr"],
|
|
14
|
+
["w:p"] = ["w:pPr", "w:hyperlink", "w:r", "w:ins", "w:del", "w:bookmarkStart", "w:bookmarkEnd", "w:commentRangeStart", "w:commentRangeEnd", "w:fldSimple"],
|
|
15
|
+
["w:pPr"] = ["w:pStyle", "w:keepNext", "w:keepLines", "w:pageBreakBefore", "w:widowControl", "w:numPr", "w:pBdr", "w:shd", "w:tabs", "w:suppressAutoHyphens", "w:spacing", "w:ind", "w:jc", "w:rPr", "w:sectPr", "w:pPrChange"],
|
|
16
|
+
["w:r"] = ["w:rPr", "w:t", "w:br", "w:tab", "w:cr", "w:sym", "w:drawing", "w:delText", "w:fldChar", "w:instrText", "w:lastRenderedPageBreak", "w:noBreakHyphen", "w:softHyphen"],
|
|
17
|
+
["w:rPr"] = ["w:rStyle", "w:rFonts", "w:b", "w:bCs", "w:i", "w:iCs", "w:caps", "w:smallCaps", "w:strike", "w:dstrike", "w:vanish", "w:color", "w:sz", "w:szCs", "w:u", "w:shd", "w:highlight", "w:lang", "w:rPrChange"],
|
|
18
|
+
["w:tbl"] = ["w:tblPr", "w:tblGrid", "w:tr"],
|
|
19
|
+
["w:tblPr"] = ["w:tblStyle", "w:tblpPr", "w:tblOverlap", "w:tblW", "w:jc", "w:tblCellSpacing", "w:tblInd", "w:tblBorders", "w:shd", "w:tblLayout", "w:tblCellMar", "w:tblLook", "w:tblPrChange"],
|
|
20
|
+
["w:tr"] = ["w:trPr", "w:tc"],
|
|
21
|
+
["w:trPr"] = ["w:cnfStyle", "w:divId", "w:gridBefore", "w:gridAfter", "w:wBefore", "w:wAfter", "w:cantSplit", "w:trHeight", "w:tblHeader", "w:tblCellSpacing", "w:jc", "w:hidden", "w:ins", "w:del", "w:trPrChange"],
|
|
22
|
+
["w:tc"] = ["w:tcPr", "w:p", "w:tbl"],
|
|
23
|
+
["w:tcPr"] = ["w:cnfStyle", "w:tcW", "w:gridSpan", "w:hMerge", "w:vMerge", "w:tcBorders", "w:shd", "w:noWrap", "w:tcMar", "w:textDirection", "w:tcFitText", "w:vAlign", "w:hideMark", "w:headers", "w:cellIns", "w:cellDel", "w:cellMerge", "w:tcPrChange"],
|
|
24
|
+
["w:sectPr"] = ["w:headerReference", "w:footerReference", "w:type", "w:pgSz", "w:pgMar", "w:paperSrc", "w:pgBorders", "w:lnNumType", "w:pgNumType", "w:cols", "w:formProt", "w:vAlign", "w:noEndnote", "w:titlePg", "w:textDirection", "w:bidi", "w:rtlGutter", "w:docGrid"],
|
|
25
|
+
["w:hdr"] = ["w:p", "w:tbl", "w:sdt"],
|
|
26
|
+
["w:ftr"] = ["w:p", "w:tbl", "w:sdt"],
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/// <summary>
|
|
30
|
+
/// Returns the canonical child ordering for a given parent element name (e.g. "w:p").
|
|
31
|
+
/// Returns null if no ordering is defined.
|
|
32
|
+
/// </summary>
|
|
33
|
+
public static string[]? GetChildOrder(string parentElement)
|
|
34
|
+
{
|
|
35
|
+
return OrderMap.TryGetValue(parentElement, out var order) ? order : null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/// <summary>
|
|
39
|
+
/// Reorders children of the given XElement according to the canonical ordering rules.
|
|
40
|
+
/// Children not listed in the ordering are placed at the end in their original order.
|
|
41
|
+
/// </summary>
|
|
42
|
+
public static void ReorderChildren(XElement parent)
|
|
43
|
+
{
|
|
44
|
+
var qualifiedName = GetQualifiedName(parent);
|
|
45
|
+
var order = GetChildOrder(qualifiedName);
|
|
46
|
+
if (order == null) return;
|
|
47
|
+
|
|
48
|
+
var children = parent.Elements().ToList();
|
|
49
|
+
if (children.Count <= 1) return;
|
|
50
|
+
|
|
51
|
+
var orderIndex = new Dictionary<string, int>();
|
|
52
|
+
for (int i = 0; i < order.Length; i++)
|
|
53
|
+
orderIndex[order[i]] = i;
|
|
54
|
+
|
|
55
|
+
int unknownBase = order.Length;
|
|
56
|
+
int unknownCounter = 0;
|
|
57
|
+
|
|
58
|
+
var sorted = children
|
|
59
|
+
.Select(c => (Element: c, QName: GetQualifiedName(c)))
|
|
60
|
+
.OrderBy(x => orderIndex.TryGetValue(x.QName, out var idx) ? idx : unknownBase + unknownCounter++)
|
|
61
|
+
.Select(x => x.Element)
|
|
62
|
+
.ToList();
|
|
63
|
+
|
|
64
|
+
parent.RemoveNodes();
|
|
65
|
+
foreach (var child in sorted)
|
|
66
|
+
parent.Add(child);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private static string GetQualifiedName(XElement element)
|
|
70
|
+
{
|
|
71
|
+
var ns = element.Name.Namespace;
|
|
72
|
+
var local = element.Name.LocalName;
|
|
73
|
+
|
|
74
|
+
if (ns == Ns.W) return $"w:{local}";
|
|
75
|
+
if (ns == Ns.R) return $"r:{local}";
|
|
76
|
+
if (ns == Ns.MC) return $"mc:{local}";
|
|
77
|
+
|
|
78
|
+
return local;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
using System.Xml.Linq;
|
|
2
|
+
|
|
3
|
+
namespace MiniMaxAIDocx.Core.OpenXml;
|
|
4
|
+
|
|
5
|
+
/// <summary>
|
|
6
|
+
/// All OpenXML namespace URIs and common content/relationship type constants.
|
|
7
|
+
/// </summary>
|
|
8
|
+
public static class Ns
|
|
9
|
+
{
|
|
10
|
+
public static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
11
|
+
public static readonly XNamespace R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
12
|
+
public static readonly XNamespace WP = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
|
|
13
|
+
public static readonly XNamespace A = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
14
|
+
public static readonly XNamespace MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
15
|
+
public static readonly XNamespace PIC = "http://schemas.openxmlformats.org/drawingml/2006/picture";
|
|
16
|
+
public static readonly XNamespace W14 = "http://schemas.microsoft.com/office/word/2010/wordml";
|
|
17
|
+
public static readonly XNamespace W15 = "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
18
|
+
public static readonly XNamespace W16CID = "http://schemas.microsoft.com/office/word/2016/wordml/cid";
|
|
19
|
+
public static readonly XNamespace W16CEX = "http://schemas.microsoft.com/office/word/2018/wordml/cex";
|
|
20
|
+
public static readonly XNamespace WPC = "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas";
|
|
21
|
+
public static readonly XNamespace WPS = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
|
|
22
|
+
|
|
23
|
+
// Content types
|
|
24
|
+
public const string MainDocumentContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
|
|
25
|
+
public const string StylesContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml";
|
|
26
|
+
public const string HeaderContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml";
|
|
27
|
+
public const string FooterContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml";
|
|
28
|
+
public const string CommentsContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml";
|
|
29
|
+
|
|
30
|
+
// Relationship types
|
|
31
|
+
public const string DocumentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
|
|
32
|
+
public const string StylesRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
|
|
33
|
+
public const string HeaderRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header";
|
|
34
|
+
public const string FooterRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer";
|
|
35
|
+
public const string CommentsRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
|
|
36
|
+
public const string ImageRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
37
|
+
public const string HyperlinkRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
|
|
38
|
+
public const string NumberingRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering";
|
|
39
|
+
public const string FontTableRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable";
|
|
40
|
+
public const string ThemeRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
|
|
41
|
+
public const string SettingsRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings";
|
|
42
|
+
}
|
package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/RunMerger.cs
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
using System.Xml.Linq;
|
|
2
|
+
|
|
3
|
+
namespace MiniMaxAIDocx.Core.OpenXml;
|
|
4
|
+
|
|
5
|
+
/// <summary>
|
|
6
|
+
/// Result of a run merge operation.
|
|
7
|
+
/// </summary>
|
|
8
|
+
public record RunMergeResult(int OriginalRunCount, int MergedRunCount, int SizeReductionBytes);
|
|
9
|
+
|
|
10
|
+
/// <summary>
|
|
11
|
+
/// Merges adjacent w:r elements with identical w:rPr formatting to reduce document size.
|
|
12
|
+
/// </summary>
|
|
13
|
+
public static class RunMerger
|
|
14
|
+
{
|
|
15
|
+
/// <summary>
|
|
16
|
+
/// Merges adjacent runs with identical formatting in all paragraphs of the document body.
|
|
17
|
+
/// </summary>
|
|
18
|
+
public static RunMergeResult MergeRuns(XDocument document)
|
|
19
|
+
{
|
|
20
|
+
var body = document.Root?.Element(Ns.W + "body");
|
|
21
|
+
if (body == null) return new(0, 0, 0);
|
|
22
|
+
|
|
23
|
+
int originalCount = 0;
|
|
24
|
+
int removedCount = 0;
|
|
25
|
+
|
|
26
|
+
foreach (var paragraph in body.Descendants(Ns.W + "p"))
|
|
27
|
+
{
|
|
28
|
+
var runs = paragraph.Elements(Ns.W + "r").ToList();
|
|
29
|
+
originalCount += runs.Count;
|
|
30
|
+
|
|
31
|
+
for (int i = runs.Count - 1; i > 0; i--)
|
|
32
|
+
{
|
|
33
|
+
var current = runs[i];
|
|
34
|
+
var previous = runs[i - 1];
|
|
35
|
+
|
|
36
|
+
if (!AreRunPropertiesEqual(previous, current)) continue;
|
|
37
|
+
|
|
38
|
+
// Merge text content from current into previous
|
|
39
|
+
var prevText = GetOrCreateTextElement(previous);
|
|
40
|
+
var currText = current.Element(Ns.W + "t");
|
|
41
|
+
if (currText != null && prevText != null)
|
|
42
|
+
{
|
|
43
|
+
prevText.Value += currText.Value;
|
|
44
|
+
// Preserve xml:space="preserve" if either has it
|
|
45
|
+
if (currText.Attribute(XNamespace.Xml + "space")?.Value == "preserve" ||
|
|
46
|
+
prevText.Value.StartsWith(' ') || prevText.Value.EndsWith(' '))
|
|
47
|
+
{
|
|
48
|
+
prevText.SetAttributeValue(XNamespace.Xml + "space", "preserve");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
current.Remove();
|
|
53
|
+
removedCount++;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return new(originalCount, originalCount - removedCount, 0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private static bool AreRunPropertiesEqual(XElement run1, XElement run2)
|
|
61
|
+
{
|
|
62
|
+
var rPr1 = run1.Element(Ns.W + "rPr");
|
|
63
|
+
var rPr2 = run2.Element(Ns.W + "rPr");
|
|
64
|
+
|
|
65
|
+
if (rPr1 == null && rPr2 == null) return true;
|
|
66
|
+
if (rPr1 == null || rPr2 == null) return false;
|
|
67
|
+
|
|
68
|
+
return XNode.DeepEquals(rPr1, rPr2);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private static XElement? GetOrCreateTextElement(XElement run)
|
|
72
|
+
{
|
|
73
|
+
var t = run.Element(Ns.W + "t");
|
|
74
|
+
if (t == null)
|
|
75
|
+
{
|
|
76
|
+
t = new XElement(Ns.W + "t");
|
|
77
|
+
run.Add(t);
|
|
78
|
+
}
|
|
79
|
+
return t;
|
|
80
|
+
}
|
|
81
|
+
}
|