@takuma-hirai/hirai-method 0.1.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/.claude/.stale-harness-state/last-check +0 -0
- package/.claude/CommonRules.md +121 -0
- package/.claude/agents/01-core-development/api-designer.md +237 -0
- package/.claude/agents/01-core-development/backend-developer.md +222 -0
- package/.claude/agents/01-core-development/design-bridge.md +127 -0
- package/.claude/agents/01-core-development/electron-pro.md +240 -0
- package/.claude/agents/01-core-development/frontend-developer.md +133 -0
- package/.claude/agents/01-core-development/fullstack-developer.md +235 -0
- package/.claude/agents/01-core-development/graphql-architect.md +238 -0
- package/.claude/agents/01-core-development/microservices-architect.md +239 -0
- package/.claude/agents/01-core-development/mobile-developer.md +283 -0
- package/.claude/agents/01-core-development/ui-designer.md +174 -0
- package/.claude/agents/01-core-development/websocket-engineer.md +150 -0
- package/.claude/agents/03-infrastructure/azure-infra-engineer.md +53 -0
- package/.claude/agents/03-infrastructure/cloud-architect.md +277 -0
- package/.claude/agents/03-infrastructure/database-administrator.md +287 -0
- package/.claude/agents/03-infrastructure/deployment-engineer.md +287 -0
- package/.claude/agents/03-infrastructure/devops-engineer.md +287 -0
- package/.claude/agents/03-infrastructure/devops-incident-responder.md +287 -0
- package/.claude/agents/03-infrastructure/docker-expert.md +278 -0
- package/.claude/agents/03-infrastructure/incident-responder.md +287 -0
- package/.claude/agents/03-infrastructure/kubernetes-specialist.md +287 -0
- package/.claude/agents/03-infrastructure/network-engineer.md +287 -0
- package/.claude/agents/03-infrastructure/platform-engineer.md +287 -0
- package/.claude/agents/03-infrastructure/security-engineer.md +277 -0
- package/.claude/agents/03-infrastructure/sre-engineer.md +287 -0
- package/.claude/agents/03-infrastructure/terraform-engineer.md +287 -0
- package/.claude/agents/03-infrastructure/terragrunt-expert.md +307 -0
- package/.claude/agents/03-infrastructure/windows-infra-admin.md +52 -0
- package/.claude/agents/04-quality-security/accessibility-tester.md +277 -0
- package/.claude/agents/04-quality-security/ad-security-reviewer.md +56 -0
- package/.claude/agents/04-quality-security/ai-writing-auditor.md +77 -0
- package/.claude/agents/04-quality-security/architect-reviewer.md +287 -0
- package/.claude/agents/04-quality-security/chaos-engineer.md +277 -0
- package/.claude/agents/04-quality-security/code-reviewer.md +287 -0
- package/.claude/agents/04-quality-security/compliance-auditor.md +277 -0
- package/.claude/agents/04-quality-security/debugger.md +287 -0
- package/.claude/agents/04-quality-security/error-detective.md +287 -0
- package/.claude/agents/04-quality-security/penetration-tester.md +287 -0
- package/.claude/agents/04-quality-security/performance-engineer.md +287 -0
- package/.claude/agents/04-quality-security/powershell-security-hardening.md +54 -0
- package/.claude/agents/04-quality-security/qa-expert.md +287 -0
- package/.claude/agents/04-quality-security/security-auditor.md +287 -0
- package/.claude/agents/04-quality-security/test-automator.md +287 -0
- package/.claude/agents/04-quality-security/ui-ux-tester.md +234 -0
- package/.claude/agents/06-developer-experience/build-engineer.md +286 -0
- package/.claude/agents/06-developer-experience/cli-developer.md +286 -0
- package/.claude/agents/06-developer-experience/dependency-manager.md +286 -0
- package/.claude/agents/06-developer-experience/documentation-engineer.md +276 -0
- package/.claude/agents/06-developer-experience/dx-optimizer.md +286 -0
- package/.claude/agents/06-developer-experience/git-workflow-manager.md +286 -0
- package/.claude/agents/06-developer-experience/legacy-modernizer.md +286 -0
- package/.claude/agents/06-developer-experience/mcp-developer.md +275 -0
- package/.claude/agents/06-developer-experience/powershell-module-architect.md +58 -0
- package/.claude/agents/06-developer-experience/powershell-ui-architect.md +135 -0
- package/.claude/agents/06-developer-experience/readme-generator.md +238 -0
- package/.claude/agents/06-developer-experience/refactoring-specialist.md +286 -0
- package/.claude/agents/06-developer-experience/slack-expert.md +232 -0
- package/.claude/agents/06-developer-experience/tooling-engineer.md +286 -0
- package/.claude/agents/09-meta-orchestration/agent-installer.md +97 -0
- package/.claude/agents/09-meta-orchestration/agent-organizer.md +287 -0
- package/.claude/agents/09-meta-orchestration/codebase-orchestrator.md +249 -0
- package/.claude/agents/09-meta-orchestration/context-manager.md +287 -0
- package/.claude/agents/09-meta-orchestration/error-coordinator.md +287 -0
- package/.claude/agents/09-meta-orchestration/it-ops-orchestrator.md +60 -0
- package/.claude/agents/09-meta-orchestration/knowledge-synthesizer.md +287 -0
- package/.claude/agents/09-meta-orchestration/multi-agent-coordinator.md +287 -0
- package/.claude/agents/09-meta-orchestration/performance-monitor.md +287 -0
- package/.claude/agents/09-meta-orchestration/task-distributor.md +287 -0
- package/.claude/agents/09-meta-orchestration/workflow-orchestrator.md +287 -0
- package/.claude/agents/10-research-analysis/competitive-analyst.md +287 -0
- package/.claude/agents/10-research-analysis/data-researcher.md +287 -0
- package/.claude/agents/10-research-analysis/market-researcher.md +287 -0
- package/.claude/agents/10-research-analysis/project-idea-validator.md +269 -0
- package/.claude/agents/10-research-analysis/research-analyst.md +287 -0
- package/.claude/agents/10-research-analysis/scientific-literature-researcher.md +151 -0
- package/.claude/agents/10-research-analysis/search-specialist.md +287 -0
- package/.claude/agents/10-research-analysis/trend-analyst.md +287 -0
- package/.claude/archive/README.md +47 -0
- package/.claude/archive/agents/02-language-specialists/angular-architect.md +287 -0
- package/.claude/archive/agents/02-language-specialists/cpp-pro.md +277 -0
- package/.claude/archive/agents/02-language-specialists/csharp-developer.md +287 -0
- package/.claude/archive/agents/02-language-specialists/django-developer.md +287 -0
- package/.claude/archive/agents/02-language-specialists/dotnet-core-expert.md +287 -0
- package/.claude/archive/agents/02-language-specialists/dotnet-framework-4.8-expert.md +306 -0
- package/.claude/archive/agents/02-language-specialists/elixir-expert.md +311 -0
- package/.claude/archive/agents/02-language-specialists/expo-react-native-expert.md +268 -0
- package/.claude/archive/agents/02-language-specialists/fastapi-developer.md +287 -0
- package/.claude/archive/agents/02-language-specialists/flutter-expert.md +287 -0
- package/.claude/archive/agents/02-language-specialists/golang-pro.md +277 -0
- package/.claude/archive/agents/02-language-specialists/java-architect.md +287 -0
- package/.claude/archive/agents/02-language-specialists/javascript-pro.md +277 -0
- package/.claude/archive/agents/02-language-specialists/kotlin-specialist.md +287 -0
- package/.claude/archive/agents/02-language-specialists/laravel-specialist.md +287 -0
- package/.claude/archive/agents/02-language-specialists/nextjs-developer.md +287 -0
- package/.claude/archive/agents/02-language-specialists/node-specialist.md +124 -0
- package/.claude/archive/agents/02-language-specialists/php-pro.md +287 -0
- package/.claude/archive/agents/02-language-specialists/powershell-5.1-expert.md +59 -0
- package/.claude/archive/agents/02-language-specialists/powershell-7-expert.md +57 -0
- package/.claude/archive/agents/02-language-specialists/python-pro.md +277 -0
- package/.claude/archive/agents/02-language-specialists/rails-expert.md +358 -0
- package/.claude/archive/agents/02-language-specialists/react-specialist.md +287 -0
- package/.claude/archive/agents/02-language-specialists/rust-engineer.md +287 -0
- package/.claude/archive/agents/02-language-specialists/spring-boot-engineer.md +287 -0
- package/.claude/archive/agents/02-language-specialists/sql-pro.md +287 -0
- package/.claude/archive/agents/02-language-specialists/swift-expert.md +287 -0
- package/.claude/archive/agents/02-language-specialists/symfony-specialist.md +354 -0
- package/.claude/archive/agents/02-language-specialists/typescript-pro.md +277 -0
- package/.claude/archive/agents/02-language-specialists/vue-expert.md +287 -0
- package/.claude/archive/agents/05-data-ai/ai-engineer.md +287 -0
- package/.claude/archive/agents/05-data-ai/data-analyst.md +277 -0
- package/.claude/archive/agents/05-data-ai/data-engineer.md +287 -0
- package/.claude/archive/agents/05-data-ai/data-scientist.md +287 -0
- package/.claude/archive/agents/05-data-ai/database-optimizer.md +287 -0
- package/.claude/archive/agents/05-data-ai/llm-architect.md +287 -0
- package/.claude/archive/agents/05-data-ai/machine-learning-engineer.md +277 -0
- package/.claude/archive/agents/05-data-ai/ml-engineer.md +287 -0
- package/.claude/archive/agents/05-data-ai/mlops-engineer.md +287 -0
- package/.claude/archive/agents/05-data-ai/nlp-engineer.md +287 -0
- package/.claude/archive/agents/05-data-ai/postgres-pro.md +287 -0
- package/.claude/archive/agents/05-data-ai/prompt-engineer.md +287 -0
- package/.claude/archive/agents/05-data-ai/reinforcement-learning-engineer.md +277 -0
- package/.claude/archive/agents/07-specialized-domains/api-documenter.md +277 -0
- package/.claude/archive/agents/07-specialized-domains/blockchain-developer.md +287 -0
- package/.claude/archive/agents/07-specialized-domains/embedded-systems.md +287 -0
- package/.claude/archive/agents/07-specialized-domains/fintech-engineer.md +287 -0
- package/.claude/archive/agents/07-specialized-domains/game-developer.md +287 -0
- package/.claude/archive/agents/07-specialized-domains/healthcare-admin.md +199 -0
- package/.claude/archive/agents/07-specialized-domains/iot-engineer.md +287 -0
- package/.claude/archive/agents/07-specialized-domains/m365-admin.md +48 -0
- package/.claude/archive/agents/07-specialized-domains/mobile-app-developer.md +287 -0
- package/.claude/archive/agents/07-specialized-domains/payment-integration.md +287 -0
- package/.claude/archive/agents/07-specialized-domains/quant-analyst.md +287 -0
- package/.claude/archive/agents/07-specialized-domains/risk-manager.md +287 -0
- package/.claude/archive/agents/07-specialized-domains/seo-specialist.md +184 -0
- package/.claude/archive/agents/08-business-product/business-analyst.md +287 -0
- package/.claude/archive/agents/08-business-product/content-marketer.md +287 -0
- package/.claude/archive/agents/08-business-product/customer-success-manager.md +287 -0
- package/.claude/archive/agents/08-business-product/legal-advisor.md +287 -0
- package/.claude/archive/agents/08-business-product/license-engineer.md +295 -0
- package/.claude/archive/agents/08-business-product/product-manager.md +287 -0
- package/.claude/archive/agents/08-business-product/project-manager.md +287 -0
- package/.claude/archive/agents/08-business-product/sales-engineer.md +287 -0
- package/.claude/archive/agents/08-business-product/scrum-master.md +287 -0
- package/.claude/archive/agents/08-business-product/technical-writer.md +287 -0
- package/.claude/archive/agents/08-business-product/ux-researcher.md +287 -0
- package/.claude/archive/agents/08-business-product/wordpress-master.md +316 -0
- package/.claude/archive/skills/competitive-ads-extractor/SKILL.md +293 -0
- package/.claude/archive/skills/developer-growth-analysis/SKILL.md +322 -0
- package/.claude/archive/skills/document-docx/LICENSE.txt +30 -0
- package/.claude/archive/skills/document-docx/SKILL.md +197 -0
- package/.claude/archive/skills/document-docx/docx-js.md +350 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.claude/archive/skills/document-docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.claude/archive/skills/document-docx/ooxml/scripts/pack.py +159 -0
- package/.claude/archive/skills/document-docx/ooxml/scripts/unpack.py +29 -0
- package/.claude/archive/skills/document-docx/ooxml/scripts/validate.py +69 -0
- package/.claude/archive/skills/document-docx/ooxml/scripts/validation/__init__.py +15 -0
- package/.claude/archive/skills/document-docx/ooxml/scripts/validation/base.py +951 -0
- package/.claude/archive/skills/document-docx/ooxml/scripts/validation/docx.py +274 -0
- package/.claude/archive/skills/document-docx/ooxml/scripts/validation/pptx.py +315 -0
- package/.claude/archive/skills/document-docx/ooxml/scripts/validation/redlining.py +279 -0
- package/.claude/archive/skills/document-docx/ooxml.md +610 -0
- package/.claude/archive/skills/document-docx/scripts/__init__.py +1 -0
- package/.claude/archive/skills/document-docx/scripts/document.py +1276 -0
- package/.claude/archive/skills/document-docx/scripts/templates/comments.xml +3 -0
- package/.claude/archive/skills/document-docx/scripts/templates/commentsExtended.xml +3 -0
- package/.claude/archive/skills/document-docx/scripts/templates/commentsExtensible.xml +3 -0
- package/.claude/archive/skills/document-docx/scripts/templates/commentsIds.xml +3 -0
- package/.claude/archive/skills/document-docx/scripts/templates/people.xml +3 -0
- package/.claude/archive/skills/document-docx/scripts/utilities.py +374 -0
- package/.claude/archive/skills/document-pdf/LICENSE.txt +30 -0
- package/.claude/archive/skills/document-pdf/SKILL.md +294 -0
- package/.claude/archive/skills/document-pdf/forms.md +205 -0
- package/.claude/archive/skills/document-pdf/reference.md +612 -0
- package/.claude/archive/skills/document-pdf/scripts/check_bounding_boxes.py +70 -0
- package/.claude/archive/skills/document-pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/.claude/archive/skills/document-pdf/scripts/check_fillable_fields.py +12 -0
- package/.claude/archive/skills/document-pdf/scripts/convert_pdf_to_images.py +35 -0
- package/.claude/archive/skills/document-pdf/scripts/create_validation_image.py +41 -0
- package/.claude/archive/skills/document-pdf/scripts/extract_form_field_info.py +152 -0
- package/.claude/archive/skills/document-pdf/scripts/fill_fillable_fields.py +114 -0
- package/.claude/archive/skills/document-pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/.claude/archive/skills/document-pptx/LICENSE.txt +30 -0
- package/.claude/archive/skills/document-pptx/SKILL.md +484 -0
- package/.claude/archive/skills/document-pptx/html2pptx.md +625 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.claude/archive/skills/document-pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.claude/archive/skills/document-pptx/ooxml/scripts/pack.py +159 -0
- package/.claude/archive/skills/document-pptx/ooxml/scripts/unpack.py +29 -0
- package/.claude/archive/skills/document-pptx/ooxml/scripts/validate.py +69 -0
- package/.claude/archive/skills/document-pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/.claude/archive/skills/document-pptx/ooxml/scripts/validation/base.py +951 -0
- package/.claude/archive/skills/document-pptx/ooxml/scripts/validation/docx.py +274 -0
- package/.claude/archive/skills/document-pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/.claude/archive/skills/document-pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/.claude/archive/skills/document-pptx/ooxml.md +427 -0
- package/.claude/archive/skills/document-pptx/scripts/html2pptx.js +979 -0
- package/.claude/archive/skills/document-pptx/scripts/inventory.py +1020 -0
- package/.claude/archive/skills/document-pptx/scripts/rearrange.py +231 -0
- package/.claude/archive/skills/document-pptx/scripts/replace.py +385 -0
- package/.claude/archive/skills/document-pptx/scripts/thumbnail.py +450 -0
- package/.claude/archive/skills/document-xlsx/LICENSE.txt +30 -0
- package/.claude/archive/skills/document-xlsx/SKILL.md +289 -0
- package/.claude/archive/skills/document-xlsx/recalc.py +178 -0
- package/.claude/archive/skills/image-enhancer/SKILL.md +99 -0
- package/.claude/archive/skills/meeting-insights-analyzer/SKILL.md +327 -0
- package/.claude/archive/skills/slack-gif-creator/LICENSE.txt +202 -0
- package/.claude/archive/skills/slack-gif-creator/SKILL.md +646 -0
- package/.claude/archive/skills/slack-gif-creator/core/color_palettes.py +302 -0
- package/.claude/archive/skills/slack-gif-creator/core/easing.py +230 -0
- package/.claude/archive/skills/slack-gif-creator/core/frame_composer.py +469 -0
- package/.claude/archive/skills/slack-gif-creator/core/gif_builder.py +246 -0
- package/.claude/archive/skills/slack-gif-creator/core/typography.py +357 -0
- package/.claude/archive/skills/slack-gif-creator/core/validators.py +264 -0
- package/.claude/archive/skills/slack-gif-creator/core/visual_effects.py +494 -0
- package/.claude/archive/skills/slack-gif-creator/requirements.txt +4 -0
- package/.claude/archive/skills/slack-gif-creator/templates/bounce.py +106 -0
- package/.claude/archive/skills/slack-gif-creator/templates/explode.py +331 -0
- package/.claude/archive/skills/slack-gif-creator/templates/fade.py +329 -0
- package/.claude/archive/skills/slack-gif-creator/templates/flip.py +291 -0
- package/.claude/archive/skills/slack-gif-creator/templates/kaleidoscope.py +211 -0
- package/.claude/archive/skills/slack-gif-creator/templates/morph.py +329 -0
- package/.claude/archive/skills/slack-gif-creator/templates/move.py +293 -0
- package/.claude/archive/skills/slack-gif-creator/templates/pulse.py +268 -0
- package/.claude/archive/skills/slack-gif-creator/templates/shake.py +127 -0
- package/.claude/archive/skills/slack-gif-creator/templates/slide.py +291 -0
- package/.claude/archive/skills/slack-gif-creator/templates/spin.py +269 -0
- package/.claude/archive/skills/slack-gif-creator/templates/wiggle.py +300 -0
- package/.claude/archive/skills/slack-gif-creator/templates/zoom.py +312 -0
- package/.claude/archive/skills/twitter-algorithm-optimizer/SKILL.md +327 -0
- package/.claude/archive/skills/video-downloader/SKILL.md +99 -0
- package/.claude/archive/skills/video-downloader/scripts/download_video.py +145 -0
- package/.claude/bash-whitelist-requests/2026-05-28-grep-find-rg.md +68 -0
- package/.claude/bash-whitelist-requests/2026-06-01-readonly-filters.md +76 -0
- package/.claude/bash-whitelist.txt +124 -0
- package/.claude/commands/agent-introspect.md +89 -0
- package/.claude/commands/apply-rules.md +363 -0
- package/.claude/commands/approve-design.md +219 -0
- package/.claude/commands/approve-org-money.md +267 -0
- package/.claude/commands/build.md +234 -0
- package/.claude/commands/commit.md +97 -0
- package/.claude/commands/context-fetch.md +113 -0
- package/.claude/commands/create-tool.md +496 -0
- package/.claude/commands/design-review.md +138 -0
- package/.claude/commands/design.md +807 -0
- package/.claude/commands/discharge-byproduct.md +208 -0
- package/.claude/commands/doc-review.md +165 -0
- package/.claude/commands/document-pair.md +76 -0
- package/.claude/commands/error-triage.md +435 -0
- package/.claude/commands/eval.md +70 -0
- package/.claude/commands/evolve.md +49 -0
- package/.claude/commands/finish-task.md +105 -0
- package/.claude/commands/gan-build.md +91 -0
- package/.claude/commands/gan-design.md +82 -0
- package/.claude/commands/gate-bypass.md +77 -0
- package/.claude/commands/gate-clear.md +45 -0
- package/.claude/commands/gate-status.md +46 -0
- package/.claude/commands/harness-audit.md +151 -0
- package/.claude/commands/hearing.md +138 -0
- package/.claude/commands/impact-check.md +486 -0
- package/.claude/commands/init-tasks.md +49 -0
- package/.claude/commands/instinct-export.md +47 -0
- package/.claude/commands/instinct-import.md +41 -0
- package/.claude/commands/instinct-status.md +43 -0
- package/.claude/commands/investigate.md +547 -0
- package/.claude/commands/learn.md +55 -0
- package/.claude/commands/lint-rules.md +400 -0
- package/.claude/commands/mode.md +58 -0
- package/.claude/commands/modify-feature.md +209 -0
- package/.claude/commands/module-review.md +149 -0
- package/.claude/commands/move-section.md +67 -0
- package/.claude/commands/new-draft.md +67 -0
- package/.claude/commands/new-feature.md +286 -0
- package/.claude/commands/new-task.md +156 -0
- package/.claude/commands/notification.md +107 -0
- package/.claude/commands/pm-start.md +119 -0
- package/.claude/commands/projects.md +32 -0
- package/.claude/commands/promote.md +43 -0
- package/.claude/commands/rasis-report.md +1323 -0
- package/.claude/commands/release-note.md +130 -0
- package/.claude/commands/reply-watch.md +149 -0
- package/.claude/commands/requirement.md +352 -0
- package/.claude/commands/resume-state.md +187 -0
- package/.claude/commands/reviewpr.md +118 -0
- package/.claude/commands/save-state.md +100 -0
- package/.claude/commands/sentry-pr.md +157 -0
- package/.claude/commands/start-task.md +87 -0
- package/.claude/commands/system-review.md +147 -0
- package/.claude/commands/task-bypass.md +70 -0
- package/.claude/commands/task-estimate.md +100 -0
- package/.claude/commands/template-apply.md +89 -0
- package/.claude/commands/test-design.md +116 -0
- package/.claude/commands/transfer-mismatch.md +317 -0
- package/.claude/commands/verify.md +51 -0
- package/.claude/evals/grader-loop-mode-autonomy.sh +165 -0
- package/.claude/evals/grader-system-reminder-attention.sh +99 -0
- package/.claude/evals/loop-mode-autonomy.md +121 -0
- package/.claude/evals/loop-mode-autonomy.results.template.md +133 -0
- package/.claude/evals/system-reminder-attention.md +123 -0
- package/.claude/evals/system-reminder-attention.results.template.md +93 -0
- package/.claude/evals/system-reminder-attention.runner.md +353 -0
- package/.claude/harness-config.local.yml +48 -0
- package/.claude/harness-config.yml +534 -0
- package/.claude/hooks/agent-marker-clear.sh +43 -0
- package/.claude/hooks/agent-marker-set.sh +40 -0
- package/.claude/hooks/agent-router-suggest.sh +123 -0
- package/.claude/hooks/autonomous-action-guard.sh +242 -0
- package/.claude/hooks/byproduct-discharge-guard.sh +128 -0
- package/.claude/hooks/check-md-mermaid.sh +144 -0
- package/.claude/hooks/check-required-env.sh +95 -0
- package/.claude/hooks/check-serena-mcp.sh +123 -0
- package/.claude/hooks/confidence-gate.sh +139 -0
- package/.claude/hooks/context-budget.sh +233 -0
- package/.claude/hooks/delegation-guard.sh +99 -0
- package/.claude/hooks/dispatcher-manifest.tsv +38 -0
- package/.claude/hooks/draft-flow-guard.sh +304 -0
- package/.claude/hooks/failure-loop-detect.sh +139 -0
- package/.claude/hooks/gateguard.sh +209 -0
- package/.claude/hooks/improvement-proposal.sh +112 -0
- package/.claude/hooks/init-tasks-on-start.sh +34 -0
- package/.claude/hooks/lib/bypass-logger.sh +82 -0
- package/.claude/hooks/lib/confidence-gate/bypass.sh +48 -0
- package/.claude/hooks/lib/confidence-gate/extract.sh +99 -0
- package/.claude/hooks/lib/confidence-gate/major-agent-filter.sh +59 -0
- package/.claude/hooks/lib/confidence-gate/messages.sh +53 -0
- package/.claude/hooks/lib/config-loader.sh +784 -0
- package/.claude/hooks/lib/delegation-guard/bash-whitelist.sh +323 -0
- package/.claude/hooks/lib/delegation-guard/git-deny.sh +188 -0
- package/.claude/hooks/lib/delegation-guard/protected-paths.sh +105 -0
- package/.claude/hooks/lib/delegation-guard/subagent-detect.sh +40 -0
- package/.claude/hooks/lib/dispatcher-core.sh +454 -0
- package/.claude/hooks/lib/improvement-proposal/aggregate.py +466 -0
- package/.claude/hooks/lib/improvement-proposal/cache.sh +78 -0
- package/.claude/hooks/lib/mode-loader.sh +80 -0
- package/.claude/hooks/lib/next-actions-parser.sh +153 -0
- package/.claude/hooks/lib/project-root.sh +60 -0
- package/.claude/hooks/list-md-plan-first-reminder.sh +143 -0
- package/.claude/hooks/loop-auto-progress-reminder.sh +108 -0
- package/.claude/hooks/loop-confirmation-detector.sh +241 -0
- package/.claude/hooks/mode-asana-prompt.sh +61 -0
- package/.claude/hooks/mode-enforce.sh +57 -0
- package/.claude/hooks/mode-session-start.sh +93 -0
- package/.claude/hooks/next-actions-surface.sh +136 -0
- package/.claude/hooks/notification-dispatcher.sh +9 -0
- package/.claude/hooks/notify.sh +27 -0
- package/.claude/hooks/parallel-subagent-reminder.sh +469 -0
- package/.claude/hooks/post-tool-use-dispatcher.sh +9 -0
- package/.claude/hooks/pre-tool-use-dispatcher.sh +9 -0
- package/.claude/hooks/reviewer-count-guard.sh +313 -0
- package/.claude/hooks/session-help-surface.sh +192 -0
- package/.claude/hooks/session-start-dispatcher.sh +9 -0
- package/.claude/hooks/session-start-wrapper.sh +156 -0
- package/.claude/hooks/stale-harness-detect.sh +422 -0
- package/.claude/hooks/stop-dispatcher.sh +9 -0
- package/.claude/hooks/stop.sh +25 -0
- package/.claude/hooks/subagent-stop-dispatcher.sh +9 -0
- package/.claude/hooks/task-rule-guard.sh +317 -0
- package/.claude/hooks/tests/run-tests.sh +23 -0
- package/.claude/hooks/tests/test-agent-marker-warn.sh +86 -0
- package/.claude/hooks/tests/test-check-required-env.sh +138 -0
- package/.claude/hooks/tests/test-confidence-gate.sh +170 -0
- package/.claude/hooks/tests/test-config-env-override.sh +220 -0
- package/.claude/hooks/tests/test-gate-disable.sh +118 -0
- package/.claude/hooks/tests/test-improvement-proposal.sh +284 -0
- package/.claude/hooks/tool-call-slip-detector.sh +188 -0
- package/.claude/hooks/user-prompt-submit-dispatcher.sh +9 -0
- package/.claude/hooks/why-x5-reminder.sh +45 -0
- package/.claude/hooks/why-x5-violation-detect.sh +152 -0
- package/.claude/hooks/workflow-guard.sh +263 -0
- package/.claude/mode.yml +28 -0
- package/.claude/project-rules/development-process.md +8 -0
- package/.claude/project-rules/git-workflow.md +8 -0
- package/.claude/project-rules/modes.md +8 -0
- package/.claude/project-rules/self-improvement.md +8 -0
- package/.claude/project-rules/task-management.md +8 -0
- package/.claude/project-rules/why-x5-output.md +8 -0
- package/.claude/project-rules/workflow.md +8 -0
- package/.claude/rules/development-process.md +293 -0
- package/.claude/rules/git-workflow.md +71 -0
- package/.claude/rules/modes.md +189 -0
- package/.claude/rules/self-improvement.md +76 -0
- package/.claude/rules/task-management.md +261 -0
- package/.claude/rules/why-x5-output.md +97 -0
- package/.claude/rules/workflow.md +157 -0
- package/.claude/rules-details/README.md +67 -0
- package/.claude/rules-details/development-process/confidence-gate.md +22 -0
- package/.claude/rules-details/development-process/cross-repo-write.md +35 -0
- package/.claude/rules-details/development-process/delegation-requirements.md +158 -0
- package/.claude/rules-details/development-process/harness-sync.md +21 -0
- package/.claude/rules-details/development-process/origin.md +13 -0
- package/.claude/rules-details/development-process/parallelization-origin.md +22 -0
- package/.claude/rules-details/development-process/research-reuse.md +22 -0
- package/.claude/rules-details/development-process/staging-strategy.md +47 -0
- package/.claude/rules-details/modes/artifacts.md +34 -0
- package/.claude/rules-details/modes/compliance-items.md +120 -0
- package/.claude/rules-details/modes/five-layer-enforcement.md +46 -0
- package/.claude/rules-details/modes/mode-hooks.md +51 -0
- package/.claude/rules-details/modes/origin.md +17 -0
- package/.claude/rules-details/self-improvement/l4-mechanics.md +36 -0
- package/.claude/rules-details/self-improvement/origin.md +8 -0
- package/.claude/rules-details/self-improvement/related-skills.md +35 -0
- package/.claude/rules-details/self-improvement/when-to-use-layers.md +39 -0
- package/.claude/rules-details/task-management/hook-enforcement.md +25 -0
- package/.claude/rules-details/task-management/mandatory-reading.md +20 -0
- package/.claude/rules-details/task-management/origin.md +12 -0
- package/.claude/rules-details/task-management/parking-lot.md +26 -0
- package/.claude/rules-details/task-management/plan-first.md +44 -0
- package/.claude/rules-details/task-management/six-articles.md +68 -0
- package/.claude/rules-details/task-management/task-migration.md +16 -0
- package/.claude/rules-details/task-management/ui-detection.md +11 -0
- package/.claude/rules-details/why-x5-output/examples.md +41 -0
- package/.claude/rules-details/why-x5-output/feedback-memory.md +14 -0
- package/.claude/rules-details/why-x5-output/origin.md +10 -0
- package/.claude/rules-details/why-x5-output/v1-v10-history.md +19 -0
- package/.claude/rules-details/workflow/10-stage.md +43 -0
- package/.claude/rules-details/workflow/14-stage.md +52 -0
- package/.claude/rules-details/workflow/byproduct-discharge.md +39 -0
- package/.claude/rules-details/workflow/draft-flow-guard.md +31 -0
- package/.claude/rules-details/workflow/fan-out.md +70 -0
- package/.claude/rules-details/workflow/mece-20.md +36 -0
- package/.claude/rules-details/workflow/origin.md +14 -0
- package/.claude/rules-details/workflow/refactoring.md +48 -0
- package/.claude/rules-details/workflow/related-skills.md +22 -0
- package/.claude/rules-details/workflow/reviewer-prompt.md +100 -0
- package/.claude/rules-details/workflow/session-persistence.md +46 -0
- package/.claude/rules-details/workflow/workflow-guard.md +36 -0
- package/.claude/scripts/__pycache__/harness-audit.cpython-313.pyc +0 -0
- package/.claude/scripts/agent-stocktake.py +421 -0
- package/.claude/scripts/check-md-mermaid.mjs +138 -0
- package/.claude/scripts/generate-settings.sh +0 -0
- package/.claude/scripts/harness-audit.py +1547 -0
- package/.claude/scripts/hc-config.sh +2265 -0
- package/.claude/scripts/init-tasks.sh +117 -0
- package/.claude/scripts/lib/enforcement-matrix-parse.sh +81 -0
- package/.claude/scripts/lib/hc-config-metadata.sh +190 -0
- package/.claude/scripts/lib/hc-config-web-server.js +1528 -0
- package/.claude/scripts/lib/hc-config-web-ui/app.js +1054 -0
- package/.claude/scripts/lib/hc-config-web-ui/index.html +130 -0
- package/.claude/scripts/lib/hc-config-web-ui/style.css +522 -0
- package/.claude/scripts/new-task-helper.sh +432 -0
- package/.claude/scripts/observe-repair.sh +437 -0
- package/.claude/scripts/observe-rotate.sh +311 -0
- package/.claude/scripts/statusline.sh +239 -0
- package/.claude/settings.generated.preview.json +211 -0
- package/.claude/settings.json +215 -0
- package/.claude/settings.local.example.json +20 -0
- package/.claude/settings.local.json +36 -0
- package/.claude/skills/agent-introspection-debugging/SKILL.md +123 -0
- package/.claude/skills/agent-router/README.md +137 -0
- package/.claude/skills/agent-router/SKILL.md +74 -0
- package/.claude/skills/agent-router/dispatch-table.yml +352 -0
- package/.claude/skills/agent-router/router.py +1086 -0
- package/.claude/skills/agent-router/samples/representative_prompts.txt +24 -0
- package/.claude/skills/agent-router/tests/__init__.py +0 -0
- package/.claude/skills/agent-router/tests/test_router.py +762 -0
- package/.claude/skills/artifacts-builder/LICENSE.txt +202 -0
- package/.claude/skills/artifacts-builder/SKILL.md +74 -0
- package/.claude/skills/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/.claude/skills/artifacts-builder/scripts/init-artifact.sh +322 -0
- package/.claude/skills/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/.claude/skills/brand-guidelines/LICENSE.txt +202 -0
- package/.claude/skills/brand-guidelines/SKILL.md +73 -0
- package/.claude/skills/canvas-design/LICENSE.txt +202 -0
- package/.claude/skills/canvas-design/SKILL.md +130 -0
- package/.claude/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/.claude/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/.claude/skills/changelog-generator/SKILL.md +104 -0
- package/.claude/skills/check-md-mermaid/SKILL.md +62 -0
- package/.claude/skills/connect/SKILL.md +156 -0
- package/.claude/skills/connect-apps/SKILL.md +80 -0
- package/.claude/skills/content-research-writer/SKILL.md +538 -0
- package/.claude/skills/continuous-agent-loop/SKILL.md +187 -0
- package/.claude/skills/continuous-learning-v2/SKILL.md +238 -0
- package/.claude/skills/continuous-learning-v2/config.json +35 -0
- package/.claude/skills/continuous-learning-v2/hooks/observe.sh +333 -0
- package/.claude/skills/continuous-learning-v2/instinct-cli.py +406 -0
- package/.claude/skills/domain-name-brainstormer/SKILL.md +212 -0
- package/.claude/skills/eval-harness/SKILL.md +100 -0
- package/.claude/skills/eval-harness/swe-bench/README.md +80 -0
- package/.claude/skills/eval-harness/swe-bench/config.yml +29 -0
- package/.claude/skills/eval-harness/swe-bench/docker/Dockerfile +25 -0
- package/.claude/skills/eval-harness/swe-bench/docker/docker-compose.yml +18 -0
- package/.claude/skills/eval-harness/swe-bench/results/dry-run-2026-05-04.json +137 -0
- package/.claude/skills/eval-harness/swe-bench/results/dry-run-comparison-2026-05-04.md +112 -0
- package/.claude/skills/eval-harness/swe-bench/results/dry-run-improved-2026-05-04.json +165 -0
- package/.claude/skills/eval-harness/swe-bench/results/raw/astropy__astropy-12907.patch +12 -0
- package/.claude/skills/eval-harness/swe-bench/results/raw/astropy__astropy-12907.txt +322 -0
- package/.claude/skills/eval-harness/swe-bench/results/raw/astropy__astropy-12907.whole-file.txt +322 -0
- package/.claude/skills/eval-harness/swe-bench/runner.py +845 -0
- package/.claude/skills/eval-harness/swe-bench/scoring.py +298 -0
- package/.claude/skills/eval-harness/swe-bench/tasks/fetch_tasks.py +81 -0
- package/.claude/skills/eval-harness/swe-bench/tasks/lite-50.json +702 -0
- package/.claude/skills/file-organizer/SKILL.md +433 -0
- package/.claude/skills/gan-style-harness/SKILL.md +111 -0
- package/.claude/skills/gateguard/.gateguard.yml +47 -0
- package/.claude/skills/gateguard/SKILL.md +99 -0
- package/.claude/skills/internal-comms/LICENSE.txt +202 -0
- package/.claude/skills/internal-comms/SKILL.md +32 -0
- package/.claude/skills/internal-comms/examples/3p-updates.md +47 -0
- package/.claude/skills/internal-comms/examples/company-newsletter.md +65 -0
- package/.claude/skills/internal-comms/examples/faq-answers.md +30 -0
- package/.claude/skills/internal-comms/examples/general-comms.md +16 -0
- package/.claude/skills/invoice-organizer/SKILL.md +446 -0
- package/.claude/skills/karpathy-guidelines/SKILL.md +67 -0
- package/.claude/skills/langsmith-fetch/SKILL.md +485 -0
- package/.claude/skills/lead-research-assistant/SKILL.md +199 -0
- package/.claude/skills/mcp-builder/LICENSE.txt +202 -0
- package/.claude/skills/mcp-builder/SKILL.md +328 -0
- package/.claude/skills/mcp-builder/reference/evaluation.md +602 -0
- package/.claude/skills/mcp-builder/reference/mcp_best_practices.md +915 -0
- package/.claude/skills/mcp-builder/reference/node_mcp_server.md +916 -0
- package/.claude/skills/mcp-builder/reference/python_mcp_server.md +752 -0
- package/.claude/skills/mcp-builder/scripts/connections.py +151 -0
- package/.claude/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/.claude/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/.claude/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/.claude/skills/raffle-winner-picker/SKILL.md +159 -0
- package/.claude/skills/repo-map/README.md +125 -0
- package/.claude/skills/repo-map/SKILL.md +128 -0
- package/.claude/skills/repo-map/examples/sample-output.md +1194 -0
- package/.claude/skills/repo-map/repo-map.py +715 -0
- package/.claude/skills/salesforce-e2e-testing/SKILL.md +116 -0
- package/.claude/skills/salesforce-e2e-testing/catalog-template.md +161 -0
- package/.claude/skills/salesforce-e2e-testing/methodology.md +179 -0
- package/.claude/skills/salesforce-e2e-testing/observation-rules.md +280 -0
- package/.claude/skills/salesforce-e2e-testing/pattern-taxonomy.md +392 -0
- package/.claude/skills/salesforce-e2e-testing/procedure-template.md +376 -0
- package/.claude/skills/skill-creator/LICENSE.txt +202 -0
- package/.claude/skills/skill-creator/SKILL.md +209 -0
- package/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/.claude/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/.claude/skills/skill-share/SKILL.md +80 -0
- package/.claude/skills/tailored-resume-generator/SKILL.md +345 -0
- package/.claude/skills/template-skill/SKILL.md +6 -0
- package/.claude/skills/theme-factory/LICENSE.txt +202 -0
- package/.claude/skills/theme-factory/SKILL.md +59 -0
- package/.claude/skills/theme-factory/theme-showcase.pdf +0 -0
- package/.claude/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/.claude/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/.claude/skills/theme-factory/themes/desert-rose.md +19 -0
- package/.claude/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/.claude/skills/theme-factory/themes/golden-hour.md +19 -0
- package/.claude/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/.claude/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/.claude/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/.claude/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/.claude/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/.claude/skills/verification-loop/SKILL.md +129 -0
- package/.claude/skills/webapp-testing/LICENSE.txt +202 -0
- package/.claude/skills/webapp-testing/SKILL.md +96 -0
- package/.claude/skills/webapp-testing/examples/console_logging.py +35 -0
- package/.claude/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/.claude/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/.claude/skills/webapp-testing/scripts/with_server.py +106 -0
- package/.claude/templates/docs/draft/_DRAFT_TEMPLATE.md +162 -0
- package/.claude/templates/docs/draft/_TEST_DESIGN_TEMPLATE.md +76 -0
- package/.claude/templates/docs/tasks/_TASK_TEMPLATE.md +276 -0
- package/.claude/templates/docs/tasks/list.md +80 -0
- package/.claude/templates/docs/tasks/parking-lot.md +82 -0
- package/.claude/templates/settings.user-level.json.template +306 -0
- package/.claude/tests/SMOKE-CLASSIFICATION.md +199 -0
- package/.claude/tests/action-space-count-smoke.sh +130 -0
- package/.claude/tests/agent-router-suggest-wiring-smoke.sh +188 -0
- package/.claude/tests/audit-followups-smoke.sh +158 -0
- package/.claude/tests/autonomous-action-guard-relaxation-smoke.sh +479 -0
- package/.claude/tests/autonomous-action-guard-smoke.sh +187 -0
- package/.claude/tests/check-serena-mcp-smoke.sh +156 -0
- package/.claude/tests/common-rules-import-smoke.sh +209 -0
- package/.claude/tests/confidence-gate-smoke.sh +220 -0
- package/.claude/tests/config-feature-toggles-smoke.sh +389 -0
- package/.claude/tests/context-budget-smoke.sh +222 -0
- package/.claude/tests/custom-pm-commands-smoke.sh +93 -0
- package/.claude/tests/delegation-guard-code-smoke.sh +244 -0
- package/.claude/tests/delegation-guard-deny-layers-smoke.sh +356 -0
- package/.claude/tests/delegation-guard-readonly-filter-smoke.sh +205 -0
- package/.claude/tests/delegation-guard-search-whitelist-smoke.sh +152 -0
- package/.claude/tests/delegation-guard-segment-smoke.sh +109 -0
- package/.claude/tests/dispatcher-blocker-invariance-smoke.sh +700 -0
- package/.claude/tests/dispatcher-core-smoke.sh +452 -0
- package/.claude/tests/dispatcher-merge-matrix-smoke.sh +825 -0
- package/.claude/tests/dispatcher-success-stdout-smoke.sh +290 -0
- package/.claude/tests/draft-flow-guard-approved-dir-smoke.sh +234 -0
- package/.claude/tests/draft-flow-guard-smoke.sh +194 -0
- package/.claude/tests/dual-mode-portability-smoke.sh +131 -0
- package/.claude/tests/effective-hook-matrix-smoke.sh +261 -0
- package/.claude/tests/enforcement-mismatch-smoke.sh +263 -0
- package/.claude/tests/fixtures/cascade-sample.jsonl +9 -0
- package/.claude/tests/fixtures/next-actions/case-clean.md +14 -0
- package/.claude/tests/fixtures/next-actions/case-with-red.md +16 -0
- package/.claude/tests/fixtures/next-actions/case-with-yellow-only.md +14 -0
- package/.claude/tests/fixtures/normal-broken-scatter.jsonl +5 -0
- package/.claude/tests/fixtures/task-71/blocker-baseline.tsv +24 -0
- package/.claude/tests/fixtures/task-71/settings-inventory.tsv +37 -0
- package/.claude/tests/fixtures/transcript-50pct.jsonl +2 -0
- package/.claude/tests/fixtures/transcript-60pct.jsonl +2 -0
- package/.claude/tests/fixtures/transcript-80pct.jsonl +2 -0
- package/.claude/tests/fixtures/transcript-95pct.jsonl +2 -0
- package/.claude/tests/fixtures/workflow-guard/case-2-mid.json +21 -0
- package/.claude/tests/fixtures/workflow-guard/case-3-blocked.json +33 -0
- package/.claude/tests/fixtures/workflow-guard/case-4-clean.json +27 -0
- package/.claude/tests/fixtures/workflow-guard/case-8-modify.json +23 -0
- package/.claude/tests/fixtures/workflow-guard/inputs/case-1.json +1 -0
- package/.claude/tests/fixtures/workflow-guard/inputs/case-2.json +1 -0
- package/.claude/tests/fixtures/workflow-guard/inputs/case-3.json +1 -0
- package/.claude/tests/fixtures/workflow-guard/inputs/case-4.json +1 -0
- package/.claude/tests/fixtures/workflow-guard/inputs/case-5.json +1 -0
- package/.claude/tests/fixtures/workflow-guard/inputs/case-6.json +1 -0
- package/.claude/tests/fixtures/workflow-guard/inputs/case-7.json +1 -0
- package/.claude/tests/fixtures/workflow-guard/inputs/case-8.json +1 -0
- package/.claude/tests/gateguard-smoke.sh +213 -0
- package/.claude/tests/git-deny-mainline-policy-smoke.sh +222 -0
- package/.claude/tests/harness-audit-c-batch-smoke.sh +270 -0
- package/.claude/tests/harness-audit-compare-smoke.sh +186 -0
- package/.claude/tests/harness-audit-pipeline-health-smoke.sh +326 -0
- package/.claude/tests/harness-config-local-smoke.sh +232 -0
- package/.claude/tests/hc-config-git-policy-smoke.sh +241 -0
- package/.claude/tests/hc-config-key-parity-smoke.sh +149 -0
- package/.claude/tests/hc-config-migration-smoke.sh +251 -0
- package/.claude/tests/hc-config-script-smoke.sh +1106 -0
- package/.claude/tests/hc-config-tui-smoke.sh +801 -0
- package/.claude/tests/hc-config-web-ui-smoke.sh +3224 -0
- package/.claude/tests/hook-cwd-robustness-smoke.sh +206 -0
- package/.claude/tests/hook-frequency-tweaks-smoke.sh +312 -0
- package/.claude/tests/improvement-proposal-cache-smoke.sh +238 -0
- package/.claude/tests/install-sh-overwrite-all-smoke.sh +274 -0
- package/.claude/tests/install-sh-regen-settings-smoke.sh +301 -0
- package/.claude/tests/install-sh-sync-drift-smoke.sh +285 -0
- package/.claude/tests/layer-b-context-isolation-smoke.sh +392 -0
- package/.claude/tests/list-md-plan-first-reminder-smoke.sh +313 -0
- package/.claude/tests/loop-auto-progress-smoke.sh +372 -0
- package/.claude/tests/loop-confirmation-detector-smoke.sh +674 -0
- package/.claude/tests/new-task-batch-update-smoke.sh +664 -0
- package/.claude/tests/next-actions-hooks-smoke.sh +283 -0
- package/.claude/tests/npx-cli-smoke.sh +696 -0
- package/.claude/tests/observe-flock-smoke.sh +223 -0
- package/.claude/tests/observe-jq-parse-smoke.sh +250 -0
- package/.claude/tests/observe-repair-smoke.sh +475 -0
- package/.claude/tests/observe-rotate-smoke.sh +428 -0
- package/.claude/tests/observe-subagent-stop-smoke.sh +476 -0
- package/.claude/tests/parallel-subagent-reminder-smoke.sh +918 -0
- package/.claude/tests/project-root-smoke.sh +140 -0
- package/.claude/tests/project-rules-protection-smoke.sh +199 -0
- package/.claude/tests/review-required-min-count-smoke.sh +286 -0
- package/.claude/tests/reviewer-count-guard-smoke.sh +490 -0
- package/.claude/tests/rule-architecture-smoke.sh +418 -0
- package/.claude/tests/rule-change-draft-flow-guard-smoke.sh +343 -0
- package/.claude/tests/run-all-smokes.sh +340 -0
- package/.claude/tests/session-help-surface-smoke.sh +224 -0
- package/.claude/tests/session-start-parallel-smoke.sh +165 -0
- package/.claude/tests/sessionstart-budget-smoke.sh +185 -0
- package/.claude/tests/sessionstart-footprint-smoke.sh +258 -0
- package/.claude/tests/settings-dispatcher-baseline-smoke.sh +709 -0
- package/.claude/tests/settings-generation-feature-pruning-smoke.sh +196 -0
- package/.claude/tests/stale-harness-detect-smoke.sh +974 -0
- package/.claude/tests/statusline-smoke.sh +180 -0
- package/.claude/tests/task-rule-guard-smoke.sh +656 -0
- package/.claude/tests/tool-call-slip-detector-smoke.sh +101 -0
- package/.claude/tests/wave-precheck-template-smoke.sh +159 -0
- package/.claude/tests/why-x5-violation-detect-smoke.sh +157 -0
- package/.claude/tests/workflow-guard-smoke.sh +266 -0
- package/CLAUDE.md +75 -0
- package/LICENSE +21 -0
- package/README.md +790 -0
- package/bin/cli.js +395 -0
- package/docs/INVENTORY.md +163 -0
- package/install.sh +769 -0
- package/package.json +25 -0
|
@@ -0,0 +1,1323 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rasis-report
|
|
3
|
+
description: "RASIS品質レポート生成 - Asanaインシデント管理データからR/A/S指標を自動計測しMarkdownレポートを出力"
|
|
4
|
+
category: workflow
|
|
5
|
+
complexity: enhanced
|
|
6
|
+
model: opus
|
|
7
|
+
mcp-servers: [asana]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# /rasis-report - RASIS品質レポート生成
|
|
11
|
+
|
|
12
|
+
## 概要
|
|
13
|
+
|
|
14
|
+
Asana「CRMインシデント管理」プロジェクトのタスクデータを取得し、RASIS指標(R: 信頼性、A: 可用性、S: 保守性)を自動計測してMarkdownレポートを生成するコマンド。
|
|
15
|
+
|
|
16
|
+
**実行頻度:** 週1回(QA MTG前に実行)
|
|
17
|
+
|
|
18
|
+
## 使用方法
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
# 標準実行(直近のデータで全指標を計算)
|
|
22
|
+
/rasis-report
|
|
23
|
+
|
|
24
|
+
# 引数を指定することも可能
|
|
25
|
+
/rasis-report $ARGUMENTS
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 定数定義
|
|
29
|
+
|
|
30
|
+
### Asanaプロジェクト
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
PROJECT_GID = "1210141860554779" # CRMインシデント管理
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### セクションGID分類
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
IMPACT_SECTION_GIDS(業務影響あり = A/Sで使用):
|
|
40
|
+
"1210141860554780" # 未対応 ← トリアージ前のためRASIS計算から除外
|
|
41
|
+
"1213583272288474" # 一時対応 / 復旧まで
|
|
42
|
+
"1212427130084727" # 調査中
|
|
43
|
+
"1212427130084711" # 調査済み
|
|
44
|
+
"1212442930023501" # 修正待機中
|
|
45
|
+
"1212411628435001" # 改修中
|
|
46
|
+
"1212411628434999" # 完了済み
|
|
47
|
+
"1213308608099451" # 水道自動申込
|
|
48
|
+
|
|
49
|
+
RELIABILITY_SECTION_GIDS(R(MTBF)の分母 = トリアージ済みセクションのみ):
|
|
50
|
+
"1213583272288474" # 一時対応 / 復旧まで
|
|
51
|
+
"1212427130084727" # 調査中
|
|
52
|
+
"1212427130084711" # 調査済み
|
|
53
|
+
"1212442930023501" # 修正待機中
|
|
54
|
+
"1212411628435001" # 改修中
|
|
55
|
+
"1212411628434999" # 完了済み
|
|
56
|
+
"1213308608099451" # 水道自動申込
|
|
57
|
+
|
|
58
|
+
NO_IMPACT_SECTION_GIDS(業務影響なし = R/Aから除外):
|
|
59
|
+
"1212895654036871" # 修正が必要な業務に影響のないタスク ← S分母には含む
|
|
60
|
+
"1212427130084716" # 影響のないエラー ← S分母からも除外
|
|
61
|
+
"1212427130084717" # 重複エラー ← S分母からも除外
|
|
62
|
+
"1213037757239679" # SINGLE_EMAIL_LIMIT... ← S分母からも除外
|
|
63
|
+
"1212411628435000" # 過去のエラー ← S分母からも除外
|
|
64
|
+
|
|
65
|
+
EXCLUDED_FROM_SERVICEABILITY(Sの分母から除外):
|
|
66
|
+
"1212427130084716" # 影響のないエラー
|
|
67
|
+
"1212427130084717" # 重複エラー
|
|
68
|
+
"1213037757239679" # SINGLE_EMAIL_LIMIT_EXCEEDED
|
|
69
|
+
"1212411628435000" # 過去のエラー
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### カスタムフィールドGID
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
INCIDENT_LEVEL_GID = "1212430676458427" # インシデントレベル(enum: 高/中/低)
|
|
76
|
+
HIGH_GID = "1212430676458428"
|
|
77
|
+
MEDIUM_GID = "1212430676458429"
|
|
78
|
+
LOW_GID = "1212430676458430"
|
|
79
|
+
|
|
80
|
+
TAIOU_SECTION_GID = "1213583272288474" # 一時対応 / 復旧まで(MTTR-1のセクション離脱検知対象)
|
|
81
|
+
ERROR_TYPE_GID = "1210376591796313" # エラー種別
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 目標値
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
A_TARGET = 0.99 # 99%
|
|
88
|
+
S_TARGET_HOURS = 1 # MTTR 1時間以内
|
|
89
|
+
|
|
90
|
+
MEASUREMENT_START = "2026-03-10" # 計測開始日
|
|
91
|
+
MAX_PERIOD = 365 # 最大計測日数
|
|
92
|
+
|
|
93
|
+
# 経過日数の算出ロジック:
|
|
94
|
+
# elapsed = (today - MEASUREMENT_START) の日数
|
|
95
|
+
# if elapsed > MAX_PERIOD:
|
|
96
|
+
# period = MAX_PERIOD
|
|
97
|
+
# periodStart = today - MAX_PERIOD日
|
|
98
|
+
# else:
|
|
99
|
+
# period = elapsed
|
|
100
|
+
# periodStart = MEASUREMENT_START
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## 出力
|
|
104
|
+
|
|
105
|
+
**必ずMarkdownファイルを出力すること。**
|
|
106
|
+
|
|
107
|
+
- 出力先: `doc_draft/rasis-report/rasis-report-YYYY-MM-DD.md`
|
|
108
|
+
- ディレクトリがなければ作成する
|
|
109
|
+
- 過去のレポートは上書きしない(日付付きファイル名)
|
|
110
|
+
- レポート出力後、サマリーをコンソールにも表示する
|
|
111
|
+
|
|
112
|
+
## 実行フロー
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
Step 1: Asana APIでタスク全件取得(ページネーション対応)
|
|
116
|
+
↓
|
|
117
|
+
Step 2: 各タスクのセクションGIDで分類
|
|
118
|
+
↓
|
|
119
|
+
Step 3: R(信頼性)計算 → MTBF = 経過日数 / エラー回数
|
|
120
|
+
Step 4: MTTR候補を収集 → Stories APIでMTTR取得
|
|
121
|
+
Step 5: A(可用性)・S(保守性)計算
|
|
122
|
+
↓
|
|
123
|
+
Step 6: Markdownレポート生成 → doc_draft/rasis-report/ に出力
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Step 1: タスク全件取得
|
|
127
|
+
|
|
128
|
+
Asana MCPの `asana_get_tasks` を使用してタスクを取得する。
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
呼び出し:
|
|
132
|
+
mcp__asana__asana_get_tasks({
|
|
133
|
+
project: "1210141860554779",
|
|
134
|
+
opt_fields: "name,created_at,completed,completed_at,memberships.section.gid,memberships.section.name,custom_fields.gid,custom_fields.name,custom_fields.date_value,custom_fields.enum_value.gid,custom_fields.enum_value.name",
|
|
135
|
+
limit: 100
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
ページネーション:
|
|
139
|
+
- レスポンスに `next_page.offset` がある場合、offset を指定して次ページを取得
|
|
140
|
+
- offsetがnullになるまで繰り返す
|
|
141
|
+
- 全ページの data を結合して全タスクリストを作成
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**重要:** 必ず全件取得すること。ページネーションが残っている場合は `offset` を渡して次のページを取得し続ける。
|
|
145
|
+
|
|
146
|
+
## Step 2: セクション判定
|
|
147
|
+
|
|
148
|
+
各タスクについて、CRMインシデント管理プロジェクトでのセクションを特定する。
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
function getTaskSection(task):
|
|
152
|
+
ALL_KNOWN_GIDS = IMPACT_SECTION_GIDS + NO_IMPACT_SECTION_GIDS
|
|
153
|
+
|
|
154
|
+
for membership in task.memberships:
|
|
155
|
+
if membership.section.gid in ALL_KNOWN_GIDS:
|
|
156
|
+
return membership.section // CRMインシデント管理のセクション
|
|
157
|
+
|
|
158
|
+
// フォールバック: 最初のセクション
|
|
159
|
+
return task.memberships[0].section
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Step 3: R(信頼性)計算 - MTBF
|
|
163
|
+
|
|
164
|
+
**計算式:** `R(MTBF) = 経過日数 / エラー回数`(日)
|
|
165
|
+
|
|
166
|
+
トリアージ済みの業務影響ありインシデントの発生頻度から、平均故障間隔(MTBF)を算出する。
|
|
167
|
+
**計測開始日(2026-03-10)から365日未満の場合は経過日数を使用し、365日以上経過後は直近365日間で算出する。**
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
function calcReliability(tasks, now):
|
|
171
|
+
// 期間算出
|
|
172
|
+
elapsed = (now - MEASUREMENT_START) の日数
|
|
173
|
+
if elapsed > MAX_PERIOD:
|
|
174
|
+
period = MAX_PERIOD
|
|
175
|
+
periodStart = now - MAX_PERIOD日
|
|
176
|
+
else:
|
|
177
|
+
period = elapsed
|
|
178
|
+
periodStart = MEASUREMENT_START
|
|
179
|
+
|
|
180
|
+
errorCount = 0
|
|
181
|
+
recentErrors = [] // 直近エラー一覧
|
|
182
|
+
|
|
183
|
+
for task in tasks:
|
|
184
|
+
sectionGid = getTaskSection(task).gid
|
|
185
|
+
if sectionGid NOT IN RELIABILITY_SECTION_GIDS:
|
|
186
|
+
continue // トリアージ前・業務影響なしセクションはスキップ
|
|
187
|
+
|
|
188
|
+
createdAt = parseDateTime(task.created_at)
|
|
189
|
+
if createdAt < periodStart:
|
|
190
|
+
continue // 期間より前はスキップ
|
|
191
|
+
|
|
192
|
+
errorCount += 1
|
|
193
|
+
recentErrors.append({
|
|
194
|
+
name: task.name,
|
|
195
|
+
date: toJSTDate(createdAt)
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
if errorCount == 0:
|
|
199
|
+
mtbf = null // エラーなし → MTBF算出不可(最良の状態)
|
|
200
|
+
else:
|
|
201
|
+
mtbf = period / errorCount // 日
|
|
202
|
+
|
|
203
|
+
// 出力: MTBF(日)、エラー回数、直近エラー一覧(最大5件、降順)
|
|
204
|
+
return {
|
|
205
|
+
mtbf: mtbf,
|
|
206
|
+
errorCount: errorCount,
|
|
207
|
+
recentErrors: recentErrors をソート(降順)して最大5件
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Step 4: MTTR候補の収集 + Stories API呼び出し
|
|
212
|
+
|
|
213
|
+
**計測期間内の候補を収集し、Stories APIでセクション移動履歴を取得する。**
|
|
214
|
+
|
|
215
|
+
### Step 4-1: MTTR候補タスク収集
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
function collectMttrCandidates(tasks, now):
|
|
219
|
+
// 期間算出(Step 3と同じロジック)
|
|
220
|
+
elapsed = (now - MEASUREMENT_START) の日数
|
|
221
|
+
if elapsed > MAX_PERIOD:
|
|
222
|
+
periodStart = now - MAX_PERIOD日
|
|
223
|
+
else:
|
|
224
|
+
periodStart = MEASUREMENT_START
|
|
225
|
+
TAIOU_SECTION_GID = "1213583272288474" // 一時対応 / 復旧まで
|
|
226
|
+
|
|
227
|
+
candidateTasks = []
|
|
228
|
+
for task in tasks:
|
|
229
|
+
sectionGid = getTaskSection(task).gid
|
|
230
|
+
if sectionGid NOT IN IMPACT_SECTION_GIDS:
|
|
231
|
+
continue
|
|
232
|
+
|
|
233
|
+
createdAt = parseDateTime(task.created_at)
|
|
234
|
+
if createdAt < periodStart:
|
|
235
|
+
continue
|
|
236
|
+
|
|
237
|
+
// 現在「一時対応」セクションに滞留中 → 復旧未完了のためスキップ
|
|
238
|
+
if sectionGid == TAIOU_SECTION_GID:
|
|
239
|
+
continue
|
|
240
|
+
|
|
241
|
+
candidateTasks.append(task)
|
|
242
|
+
|
|
243
|
+
return candidateTasks
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Step 4-2: Stories APIで各タスクのセクション移動履歴を取得
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
function fetchMttrData(candidateTasks):
|
|
250
|
+
// 全候補タスクのMTTRデータを取得(API呼び出しは1候補1回)
|
|
251
|
+
mttrData = [] // { gid, createdAt, mttrHours }
|
|
252
|
+
|
|
253
|
+
for task in candidateTasks:
|
|
254
|
+
stories = mcp__asana__asana_get_stories_for_task({
|
|
255
|
+
task_id: task.gid,
|
|
256
|
+
opt_fields: "resource_subtype,text,created_at"
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
// 「一時対応 / 復旧まで」から別セクションへ移動したストーリーを検索
|
|
260
|
+
recoveryAt = null
|
|
261
|
+
for story in stories.data:
|
|
262
|
+
if story.text に "一時対応" が含まれる:
|
|
263
|
+
if story.text が "from 一時対応" or "「一時対応」から" パターンにマッチ:
|
|
264
|
+
recoveryAt = parseDateTime(story.created_at)
|
|
265
|
+
break // 最初の離脱(= 暫定復旧完了)を採用
|
|
266
|
+
|
|
267
|
+
if recoveryAt == null:
|
|
268
|
+
continue
|
|
269
|
+
|
|
270
|
+
createdAt = parseDateTime(task.created_at)
|
|
271
|
+
mttrHours = (recoveryAt - createdAt) のミリ秒差 / 3,600,000
|
|
272
|
+
|
|
273
|
+
if mttrHours < 0:
|
|
274
|
+
continue
|
|
275
|
+
|
|
276
|
+
mttrData.append({
|
|
277
|
+
gid: task.gid,
|
|
278
|
+
createdAt: createdAt,
|
|
279
|
+
mttrHours: mttrHours
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
return mttrData
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Stories API呼び出しの注意
|
|
286
|
+
|
|
287
|
+
- **API呼び出し回数**: 候補タスク1件につき1回のStories API呼び出しが発生
|
|
288
|
+
- **精度向上**: Stories APIは秒単位のタイムスタンプを返すため高精度
|
|
289
|
+
|
|
290
|
+
## Step 5: A(可用性)・S(保守性)を算出
|
|
291
|
+
|
|
292
|
+
Step 4で取得した `mttrData` から A/S を算出する。
|
|
293
|
+
|
|
294
|
+
### A(可用性)計算
|
|
295
|
+
|
|
296
|
+
**計算式:** `A = (経過日数 × 24 − MTTR合計) / (経過日数 × 24) × 100%`
|
|
297
|
+
|
|
298
|
+
> **計測対象**: 業務に多大な影響を与え、即時復旧が必要なインシデントのみ復旧時間(MTTR)を計測する。
|
|
299
|
+
> 計測範囲はインシデント起票から一時対応(暫定復旧)完了までの時間。
|
|
300
|
+
> 調査依頼や特定レコードのエラーなど、即時の業務復旧を伴わないタスクは復旧時間の計測対象に含まない。
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
function calcAvailability(mttrData, period):
|
|
304
|
+
TOTAL_HOURS = period * 24 // period日分の総時間
|
|
305
|
+
|
|
306
|
+
mttrList = [d.mttrHours for d in mttrData]
|
|
307
|
+
|
|
308
|
+
sumMttr = sum(mttrList)
|
|
309
|
+
availability = (TOTAL_HOURS - sumMttr) / TOTAL_HOURS
|
|
310
|
+
|
|
311
|
+
return {
|
|
312
|
+
rate: availability,
|
|
313
|
+
sumMttrHours: sumMttr,
|
|
314
|
+
totalHours: TOTAL_HOURS,
|
|
315
|
+
count: len(mttrList),
|
|
316
|
+
mttrList: mttrList,
|
|
317
|
+
meetsTarget: availability >= A_TARGET
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### S(保守性)計算 - MTTR
|
|
322
|
+
|
|
323
|
+
**計算式:** `S(MTTR) = AVG(「一時対応」セクション離脱時刻 - created_at)`(H)
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
function calcServiceability(mttrList):
|
|
327
|
+
if mttrList が空:
|
|
328
|
+
return { avg: null, median: null, count: 0, meetsTarget: true }
|
|
329
|
+
|
|
330
|
+
avg = sum(mttrList) / len(mttrList)
|
|
331
|
+
med = median(mttrList)
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
avg: avg,
|
|
335
|
+
median: med,
|
|
336
|
+
count: len(mttrList),
|
|
337
|
+
meetsTarget: avg <= S_TARGET_HOURS
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**median計算:**
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
function median(arr):
|
|
345
|
+
sorted = arr.sort(昇順)
|
|
346
|
+
mid = floor(sorted.length / 2)
|
|
347
|
+
if sorted.length が奇数: return sorted[mid]
|
|
348
|
+
else: return (sorted[mid-1] + sorted[mid]) / 2
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## Step 6: レポート出力
|
|
352
|
+
|
|
353
|
+
### 出力先
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
doc_draft/rasis-report/rasis-report-YYYY-MM-DD.md
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### 出力フォーマット
|
|
360
|
+
|
|
361
|
+
実行日のレポートをMarkdown形式で生成する。以下のテンプレートに従うこと。
|
|
362
|
+
**集計期間は計測開始日(2026-03-10)からの経過日数(最大365日)。**
|
|
363
|
+
|
|
364
|
+
```markdown
|
|
365
|
+
# RASIS品質レポート - YYYY/MM/DD (曜日)
|
|
366
|
+
|
|
367
|
+
> 対象プロジェクト: CRMインシデント管理
|
|
368
|
+
> レポート生成日時: YYYY-MM-DD HH:MM (JST)
|
|
369
|
+
> 集計期間: YYYY-MM-DD 〜 YYYY-MM-DD(XX日間)
|
|
370
|
+
> ※計測開始日(2026-03-10)から365日未満のため、経過日数で算出(365日経過後はローリングウィンドウ)
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## サマリー
|
|
375
|
+
|
|
376
|
+
| 指標 | 値 | 目標 | 判定 |
|
|
377
|
+
| ---------------- | ------ | ------ | ------------------- |
|
|
378
|
+
| R 信頼性(MTBF) | X.XX日 | - | - |
|
|
379
|
+
| A 可用性 | XX.X% | 99% | 🟢 達成 / 🔴 未達成 |
|
|
380
|
+
| S 保守性(MTTR) | X.XH | 1H以内 | 🟢 達成 / 🔴 未達成 |
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## R 信頼性(Reliability)- MTBF
|
|
385
|
+
|
|
386
|
+
| 項目 | 値 |
|
|
387
|
+
| ---------- | ------------------------ |
|
|
388
|
+
| MTBF | X.XX日 |
|
|
389
|
+
| 計測期間 | YYYY-MM-DD 〜 YYYY-MM-DD |
|
|
390
|
+
| エラー回数 | X件 |
|
|
391
|
+
| 計算式 | 経過日数 / エラー回数 |
|
|
392
|
+
|
|
393
|
+
### 直近のインシデント(5件)
|
|
394
|
+
|
|
395
|
+
| # | タスク名 | 発生日 |
|
|
396
|
+
| --- | ---------- | ---------- |
|
|
397
|
+
| 1 | [タスク名] | YYYY-MM-DD |
|
|
398
|
+
| ... | ... | ... |
|
|
399
|
+
|
|
400
|
+
(エラーがない場合: 「計測期間内に業務影響インシデントなし(MTBF算出不可)」と表示)
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## A 可用性(Availability)
|
|
405
|
+
|
|
406
|
+
| 項目 | 値 |
|
|
407
|
+
| ------------ | ------------------------------------------ |
|
|
408
|
+
| 可用性 | XX.X% |
|
|
409
|
+
| MTTR合計 | X.XH |
|
|
410
|
+
| 総稼働時間 | XX×24H(経過日数×24H) |
|
|
411
|
+
| 対象タスク数 | X件 |
|
|
412
|
+
| 計測期間 | YYYY-MM-DD 〜 YYYY-MM-DD |
|
|
413
|
+
| 計算式 | (経過日数×24H - MTTR合計) / (経過日数×24H) |
|
|
414
|
+
| 目標達成 | 🟢 達成 / 🔴 未達成 |
|
|
415
|
+
|
|
416
|
+
> **計測対象について**
|
|
417
|
+
> 業務に多大な影響を与え、即時復旧が必要なインシデントのみ復旧時間(MTTR)を計測しています。
|
|
418
|
+
> 計測範囲はインシデント起票から一時対応(暫定復旧)完了までの時間です。
|
|
419
|
+
> 調査依頼や特定レコードのエラーなど、即時の業務復旧を伴わないタスクは復旧時間の計測対象に含まれません。
|
|
420
|
+
|
|
421
|
+
### MTTR内訳
|
|
422
|
+
|
|
423
|
+
| # | タスク名 | 起票日時 (JST) | 復旧日時 (JST) | MTTR |
|
|
424
|
+
| --- | ---------- | ---------------- | ---------------- | ----- |
|
|
425
|
+
| 1 | [タスク名] | YYYY-MM-DD HH:MM | YYYY-MM-DD HH:MM | X.XXH |
|
|
426
|
+
|
|
427
|
+
(対象タスクが0件の場合: 「計測期間内にMTTR対象タスクなし → 可用性100%」と表示)
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## S 保守性(Serviceability)- MTTR
|
|
432
|
+
|
|
433
|
+
| 項目 | 値 |
|
|
434
|
+
| ------------ | ------------------------ |
|
|
435
|
+
| MTTR 平均 | X.XH |
|
|
436
|
+
| MTTR 中央値 | X.XH |
|
|
437
|
+
| 対象タスク数 | X件 |
|
|
438
|
+
| 計測期間 | YYYY-MM-DD 〜 YYYY-MM-DD |
|
|
439
|
+
| 目標達成 | 🟢 達成 / 🔴 未達成 |
|
|
440
|
+
|
|
441
|
+
(対象タスクが0件の場合: 「計測期間内にMTTR対象タスクなし(一時対応を経由したタスクなし)」と表示)
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## セクション別タスク分布(参考)
|
|
446
|
+
|
|
447
|
+
| セクション | タスク数 | 分類 |
|
|
448
|
+
| -------------- | -------- | ---------------------- |
|
|
449
|
+
| [セクション名] | X | 業務影響あり/なし/除外 |
|
|
450
|
+
| ... | ... | ... |
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## 今週のインシデント
|
|
455
|
+
|
|
456
|
+
直近7日間に起票されたインシデント一覧を表示する。
|
|
457
|
+
|
|
458
|
+
| # | タスク名 | 起票日 | セクション | インシデントレベル |
|
|
459
|
+
| --- | -------- | ---------- | ------------ | ------------------ |
|
|
460
|
+
| 1 | [名前] | YYYY-MM-DD | [セクション] | 高/中/低/未設定 |
|
|
461
|
+
|
|
462
|
+
(0件の場合: 「直近7日間にインシデントなし」と表示)
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## 注記
|
|
467
|
+
|
|
468
|
+
- R: MTBF = 経過日数 / エラー回数(トリアージ済みの業務影響ありインシデント数)
|
|
469
|
+
- A: 可用性 = (経過日数×24H - MTTR合計) / (経過日数×24H)
|
|
470
|
+
- MTTRは業務に多大な影響を与え即時復旧が必要なインシデントのみ対象(一時対応フローを経由したタスク)
|
|
471
|
+
- 計測範囲はインシデント起票〜一時対応(暫定復旧)完了まで
|
|
472
|
+
- 調査依頼や特定レコードのエラーなど、即時の業務復旧を伴わないタスクは対象外
|
|
473
|
+
- S: MTTR = 一時対応(暫定復旧)完了時刻 - created_at の平均(時間単位)
|
|
474
|
+
- 業務影響あり判定はセクションベース(IMPACT_SECTION_GIDS)
|
|
475
|
+
- タイムゾーン: JST(UTC+9)で日付判定
|
|
476
|
+
- 計測開始日: YYYY-MM-DD(2026-03-10)。365日未満のため経過日数(XX日)で算出。365日経過後は直近365日間のローリングウィンドウに切替
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
## タイムゾーン処理
|
|
480
|
+
|
|
481
|
+
- `created_at` はISO8601形式(UTC)で返される → JST(+9時間)に変換して日付判定
|
|
482
|
+
- Stories APIの `created_at` もISO8601形式(UTC)→ JST(+9時間)に変換して計算
|
|
483
|
+
- **精度向上**: Stories APIは秒単位のタイムスタンプを返すため、旧方式(カスタムフィールドの日付のみ)より高精度
|
|
484
|
+
|
|
485
|
+
## エッジケース
|
|
486
|
+
|
|
487
|
+
| ケース | 対応 |
|
|
488
|
+
| ------------------------------- | --------------------------------------------------------------- |
|
|
489
|
+
| 計測期間内にエラー0件 | R: MTBF算出不可(最良), A=100%, S=データなし |
|
|
490
|
+
| 全タスクが除外セクション | R: MTBF算出不可, A=100%, S=データなし |
|
|
491
|
+
| 一時対応を経由せず直接完了 | A/S: MTTR対象外(セクション離脱ストーリーなし) |
|
|
492
|
+
| 「一時対応 / 復旧まで」に滞留中 | A/S: MTTR対象外(現在セクションが一時対応のためスキップ) |
|
|
493
|
+
| Stories APIレスポンスが空 | A/S: MTTR対象外として処理(一時対応を経由していない) |
|
|
494
|
+
| MTTR合計 > 総稼働時間 | A: 0%として扱う |
|
|
495
|
+
| 計測開始日から365日未満 | 経過日数で算出(注記に記載)。365日経過後はローリングウィンドウ |
|
|
496
|
+
|
|
497
|
+
## 実行時の注意
|
|
498
|
+
|
|
499
|
+
1. **全件取得を必ず行う**: ページネーションが終わるまで `offset` を渡して取得し続けること
|
|
500
|
+
2. **JST変換を忘れない**: `created_at` はUTCで返されるため、日付判定前にJST変換する
|
|
501
|
+
3. **レポートは毎回新規作成**: 日付付きファイル名で保存し、過去のレポートは上書きしない
|
|
502
|
+
4. **計算結果をコンソールにも表示**: ファイル保存前にサマリーをユーザーに表示する
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
# Appendix A: 設計書(RASIS品質指標)
|
|
509
|
+
|
|
510
|
+
> 元ファイル: `doc_draft/basic-design/RASIS品質指標/README.md`
|
|
511
|
+
|
|
512
|
+
## A-1. 背景・目的
|
|
513
|
+
|
|
514
|
+
### 背景
|
|
515
|
+
|
|
516
|
+
- インシデントMTGを「品質保証(QA)MTG」に改称し、対象範囲を拡大
|
|
517
|
+
- システム品質をRASIS(信頼性・可用性・保守性・完全性・機密性)の5軸で評価する方針を決定
|
|
518
|
+
- 日次でRASIS指標を把握し、QA MTGでの品質改善サイクルを回す必要がある
|
|
519
|
+
|
|
520
|
+
### 目的
|
|
521
|
+
|
|
522
|
+
Asana「CRMインシデント管理」プロジェクトのデータを元に、RASIS指標を自動計測し、日次でSlackに投稿する仕組みを構築する。
|
|
523
|
+
|
|
524
|
+
## A-2. フェーズ分け
|
|
525
|
+
|
|
526
|
+
| フェーズ | 期間 | 対象指標 | 状態 |
|
|
527
|
+
| ------------- | ---------------------- | ------------------------------------- | ------ |
|
|
528
|
+
| **フェーズ1** | 3月〜 運用開始 | R(信頼性), A(可用性), S(保守性) | 着手 |
|
|
529
|
+
| **フェーズ2** | 4月〜 スケジューリング | I(完全性), S(機密性) | 未着手 |
|
|
530
|
+
|
|
531
|
+
## A-3. データソース
|
|
532
|
+
|
|
533
|
+
### Asana プロジェクト
|
|
534
|
+
|
|
535
|
+
| 項目 | 内容 |
|
|
536
|
+
| --------------- | ------------------------------------------------------------------------------------- |
|
|
537
|
+
| プロジェクト名 | CRMインシデント管理 |
|
|
538
|
+
| プロジェクトGID | `1210141860554779` |
|
|
539
|
+
| 認証方式 | Personal Access Token(Script Propertiesに格納) |
|
|
540
|
+
| 取得方式 | Asana REST API(`next_page.offset` でページネーション、limit=100/リクエスト) |
|
|
541
|
+
| 取得項目 | タスク名, created_at, completed, completed_at, セクション情報, カスタムフィールド全て |
|
|
542
|
+
|
|
543
|
+
### カスタムフィールド一覧
|
|
544
|
+
|
|
545
|
+
| フィールド名 | GID | 型 | 選択肢 | RASIS用途 |
|
|
546
|
+
| ------------------ | ------------------ | ---- | ------------------------------------------ | ----------------------------------------------------------------------------------- |
|
|
547
|
+
| エラー種別 | `1210376591796313` | enum | オペレーションに影響あり / 対応不要 / 重複 | R: 業務影響の判定、S: 除外対象の判定 |
|
|
548
|
+
| インシデントレベル | `1212430676458427` | enum | 高 / 中 / 低 | A: レベル別MTTR内訳 |
|
|
549
|
+
| 対応種別 | `1210141956819951` | enum | エラー / 生産性向上 | 参考情報 |
|
|
550
|
+
| 起票種別 | `1212430676458454` | enum | ユーザー / システム | 参考情報 |
|
|
551
|
+
| 完了日 | `1212716524519634` | date | - | 参考情報(計算にはcompleted_atを使用) |
|
|
552
|
+
| 一時対応完了日時 | `1213587177650004` | date | - | ~~A: MTTR-1の終点~~ → Stories APIに移行済み(フィールドは残存するが計算には未使用) |
|
|
553
|
+
|
|
554
|
+
### タイムスタンプ
|
|
555
|
+
|
|
556
|
+
| タイムスタンプ | 取得元 | 用途 |
|
|
557
|
+
| -------------- | --------------------------- | -------------------------------------------------- |
|
|
558
|
+
| `created_at` | Asanaタスク自動記録 | インシデント起票日時(障害発生日の判定、MTTR起点) |
|
|
559
|
+
| `completed_at` | Asanaタスク完了時に自動記録 | MTTR終点、完了判定 |
|
|
560
|
+
|
|
561
|
+
## A-4. セクションベース判定
|
|
562
|
+
|
|
563
|
+
> **背景**: カスタムフィールド「エラー種別」の入力率が現状0%のため、**セクション所属**で業務影響の有無を判定する。
|
|
564
|
+
> カスタムフィールドの運用が定着した段階でフィールドベースに切替可能な設計とする。
|
|
565
|
+
|
|
566
|
+
### セクション分類マッピング
|
|
567
|
+
|
|
568
|
+
| セクション | GID | R(障害日) | A(MTTR-1) | S(分母) | 分類 |
|
|
569
|
+
| ---------------------------------- | ------------------ | ----------- | ----------- | --------- | ------------ |
|
|
570
|
+
| 未対応 | `1210141860554780` | **除外** | **除外** | **除外** | トリアージ前 |
|
|
571
|
+
| 一時対応 / 復旧まで | `1213583272288474` | カウント | 対象 | 含む | ワークフロー |
|
|
572
|
+
| 調査中 | `1212427130084727` | カウント | 対象 | 含む | ワークフロー |
|
|
573
|
+
| 調査済み | `1212427130084711` | カウント | 対象 | 含む | ワークフロー |
|
|
574
|
+
| 修正待機中 | `1212442930023501` | カウント | 対象 | 含む | ワークフロー |
|
|
575
|
+
| 改修中 | `1212411628435001` | カウント | 対象 | 含む | ワークフロー |
|
|
576
|
+
| 完了済み | `1212411628434999` | カウント | 対象 | 含む | ワークフロー |
|
|
577
|
+
| 水道自動申込 | `1213308608099451` | カウント | 対象 | 含む | 特定カテゴリ |
|
|
578
|
+
| 修正が必要な業務に影響のないタスク | `1212895654036871` | **除外** | 除外 | 含む | 低影響 |
|
|
579
|
+
| 影響のないエラー | `1212427130084716` | **除外** | 除外 | **除外** | 除外 |
|
|
580
|
+
| 重複エラー | `1212427130084717` | **除外** | 除外 | **除外** | 除外 |
|
|
581
|
+
| SINGLE_EMAIL_LIMIT_EXCEEDED | `1213037757239679` | **除外** | 除外 | **除外** | 除外 |
|
|
582
|
+
| 過去のエラー | `1212411628435000` | **除外** | 除外 | **除外** | 除外 |
|
|
583
|
+
|
|
584
|
+
### セクション判定ロジック
|
|
585
|
+
|
|
586
|
+
タスクは複数プロジェクトに所属し得るため、CRMインシデント管理プロジェクト内のセクションを特定する必要がある。
|
|
587
|
+
|
|
588
|
+
```
|
|
589
|
+
function セクション判定(task):
|
|
590
|
+
既知のセクションGID一覧 = 業務影響ありGID[] + 業務影響なしGID[]
|
|
591
|
+
|
|
592
|
+
for membership in task.memberships:
|
|
593
|
+
if membership.section.gid が 既知のセクションGID一覧 に含まれる:
|
|
594
|
+
return membership.section.gid ← CRMインシデント管理のセクション
|
|
595
|
+
|
|
596
|
+
// 該当なしの場合は最初のセクションを返す(フォールバック)
|
|
597
|
+
return task.memberships[0].section.gid
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
## A-5. Asana項目とRASIS計算式の対応
|
|
601
|
+
|
|
602
|
+
### 使用するAsana API項目一覧
|
|
603
|
+
|
|
604
|
+
| # | Asana API項目 | 型 | 説明 | 使用先 |
|
|
605
|
+
| --- | ------------------------------------- | -------- | -------------------------- | ----------------------------------------------------------- |
|
|
606
|
+
| 1 | `task.created_at` | datetime | タスク起票日時(自動記録) | R: 障害発生日の判定, A: MTTR-1起点, S: 期間フィルタ |
|
|
607
|
+
| 2 | `task.completed` | boolean | 完了済みフラグ | S: 完了カウント |
|
|
608
|
+
| 3 | `task.completed_at` | datetime | タスク完了日時(自動記録) | A: MTTR-2終点(将来レポート化時に使用) |
|
|
609
|
+
| 4 | `task.memberships[].section.gid` | string | 所属セクションのGID | R/A/S: セクション分類判定 |
|
|
610
|
+
| 5 | `task.memberships[].section.name` | string | セクション名 | レポート表示用 |
|
|
611
|
+
| 6 | `task.name` | string | タスク名 | レポート表示用 |
|
|
612
|
+
| 7 | `task.custom_fields[].enum_value.gid` | string | カスタムフィールド値 | A: インシデントレベル別MTTR(補助) |
|
|
613
|
+
| 8 | `task.custom_fields[].date_value` | date | カスタムフィールド日付値 | ~~A: MTTR-1終点~~ → Stories APIに移行(参考情報として残存) |
|
|
614
|
+
| - | `story.created_at`(Stories API) | datetime | タスク履歴のタイムスタンプ | A: MTTR-1終点(「一時対応」セクション離脱時刻) |
|
|
615
|
+
|
|
616
|
+
### 計算式とAsana項目の対応
|
|
617
|
+
|
|
618
|
+
#### R(信頼性) = `経過日数 / エラー回数`
|
|
619
|
+
|
|
620
|
+
```
|
|
621
|
+
// 期間算出: elapsed = (today - MEASUREMENT_START) の日数、period = min(elapsed, 365)
|
|
622
|
+
エラー回数 = COUNT(
|
|
623
|
+
task
|
|
624
|
+
WHERE task.memberships[].section.gid IN RELIABILITY_SECTION_GIDS // トリアージ済みのIMPACTセクション
|
|
625
|
+
AND task.created_at >= periodStart
|
|
626
|
+
)
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
#### A(可用性) - 2段階MTTR
|
|
630
|
+
|
|
631
|
+
> MTTR-1(暫定復旧)をメイン指標としてレポートに表示する。
|
|
632
|
+
> MTTR-2(完全解決)は将来のレポート拡張時に使用する。
|
|
633
|
+
|
|
634
|
+
**MTTR-1(暫定復旧時間)** = `Σ(「一時対応」セクション離脱時刻 - created_at) / 対象タスク数`
|
|
635
|
+
|
|
636
|
+
> **方式変更(2026-03)**: カスタムフィールド「暫定復旧日時」+ Asanaルール方式から、**Stories API方式**に移行。
|
|
637
|
+
> Asanaルールやカスタムフィールド設定が不要になり、秒単位の精度で計測可能。
|
|
638
|
+
|
|
639
|
+
#### S(保守性) = `完了済みタスク数 / 対象タスク数`
|
|
640
|
+
|
|
641
|
+
```
|
|
642
|
+
// 期間算出: Step 3と同じ動的期間ロジック
|
|
643
|
+
対象タスク数 = COUNT(
|
|
644
|
+
task
|
|
645
|
+
WHERE task.memberships[].section.gid NOT IN EXCLUDED_FROM_SERVICEABILITY
|
|
646
|
+
AND task.created_at >= periodStart
|
|
647
|
+
)
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
## A-6. エッジケース
|
|
651
|
+
|
|
652
|
+
| ケース | R | A(MTTR-1) | S |
|
|
653
|
+
| ------------------------------- | ------------------------------------- | ------------------------------------------------------ | -------------------------- |
|
|
654
|
+
| 期間内にタスクが0件 | 100%(障害なし) | データなし(目標達成扱い) | 100%(対応すべきものなし) |
|
|
655
|
+
| 全タスクが除外セクション | 100% | データなし | 100% |
|
|
656
|
+
| 1日に100件のインシデント | 障害日は1日としてカウント | 暫定復旧日時ありの件数が対象 | 100件が分母 |
|
|
657
|
+
| タスクが複数プロジェクトに所属 | CRMインシデント管理のセクションで判定 | 同左 | 同左 |
|
|
658
|
+
| 一時対応を経由せず直接完了 | カウント(業務影響あり) | MTTR-1対象外(Stories APIにセクション離脱記録なし) | 分母に含む |
|
|
659
|
+
| 「一時対応 / 復旧まで」に滞留中 | カウント(業務影響あり) | MTTR-1対象外(現在セクションが一時対応のためスキップ) | 分母に含む(未完了) |
|
|
660
|
+
| Stories APIレスポンスが空 | - | MTTR-1対象外(一時対応を経由していないと判定) | - |
|
|
661
|
+
|
|
662
|
+
## A-7. フェーズ2 要件(IS)- 概要のみ
|
|
663
|
+
|
|
664
|
+
> 4月に詳細を再定義。現時点では方向性のみ記載。
|
|
665
|
+
|
|
666
|
+
### I(Integrity / 完全性)
|
|
667
|
+
|
|
668
|
+
| 候補 | 概要 | データソース | 難易度 |
|
|
669
|
+
| --------------------- | ---------------------------------------------------------------------- | ------------------------------------------ | ------ |
|
|
670
|
+
| A. データ不整合検知数 | 定期バッチで参照整合性・必須項目のnull等をチェックし、不整合件数を計測 | Salesforce SOQL(バッチ実行) | 中 |
|
|
671
|
+
| B. 入力規則エラー率 | 入力規則で弾かれた操作の割合を計測 | Salesforce EventLogFile(SetupAuditTrail) | 高 |
|
|
672
|
+
| C. 手動データ修正件数 | DataLoaderやSF Inspector等での手動修正件数をAPI使用量から推定 | ApiTotalUsage CSV / EventMonitoring | 中 |
|
|
673
|
+
|
|
674
|
+
### S(Security / 機密性)
|
|
675
|
+
|
|
676
|
+
| 候補 | 概要 | データソース | 難易度 |
|
|
677
|
+
| --------------------- | ---------------------------------------- | ----------------------- | ------ |
|
|
678
|
+
| A. ログイン異常検知数 | 異常ログイン(時間外、海外IP等)の件数 | Salesforce LoginHistory | 中 |
|
|
679
|
+
| B. 権限変更監査 | プロファイル・権限セットの変更件数を追跡 | SetupAuditTrail | 中 |
|
|
680
|
+
| C. 共有ルール違反 | 参照権限のないレコードへのアクセス試行数 | EventMonitoring(有料) | 高 |
|
|
681
|
+
|
|
682
|
+
## A-8. 運用要件
|
|
683
|
+
|
|
684
|
+
### Stories API方式への移行(2026-03)
|
|
685
|
+
|
|
686
|
+
> Asanaルールやカスタムフィールド設定は**不要**。
|
|
687
|
+
> MTTR-1の計測はStories API(タスク履歴)から「一時対応 / 復旧まで」セクションの離脱時刻を直接取得する。
|
|
688
|
+
|
|
689
|
+
### ワークフロー定義
|
|
690
|
+
|
|
691
|
+
```
|
|
692
|
+
未対応 → 一時対応 / 復旧まで → 調査中 → 調査済み → 修正待機中 → 改修中 → 完了済み
|
|
693
|
+
^^^^^^^^^^^^^^^^
|
|
694
|
+
暫定復旧フェーズ 根本対応フェーズ
|
|
695
|
+
(ここを離脱すると
|
|
696
|
+
暫定復旧日時が自動セット)
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### セクション移動の運用ルール
|
|
700
|
+
|
|
701
|
+
1. 一時対応で業務復旧したら「一時対応 / 復旧まで」セクションに移動すること
|
|
702
|
+
2. 一時対応完了後、根本対応フェーズに進む際は「調査中」セクションに移動すること
|
|
703
|
+
3. インシデント対応完了時は必ず「完了済み」セクションに移動すること
|
|
704
|
+
4. 重複と判明した場合は「重複エラー」セクションに移動すること
|
|
705
|
+
5. 業務影響がないと判明した場合は「影響のないエラー」セクションに移動すること
|
|
706
|
+
|
|
707
|
+
### Slack投稿
|
|
708
|
+
|
|
709
|
+
| 項目 | 内容 |
|
|
710
|
+
| ------------ | ------------------------------------------- |
|
|
711
|
+
| 投稿方式 | Slack Incoming Webhook |
|
|
712
|
+
| フォーマット | Slack mrkdwn形式(太字、絵文字使用) |
|
|
713
|
+
| 目標達成 | 🟢(緑丸)/ 目標未達 🔴(赤丸) |
|
|
714
|
+
| 実行方式 | GAS時間主導型トリガー(毎日午前9〜10時JST) |
|
|
715
|
+
|
|
716
|
+
---
|
|
717
|
+
|
|
718
|
+
---
|
|
719
|
+
|
|
720
|
+
# Appendix B: 要件定義書
|
|
721
|
+
|
|
722
|
+
> 元ファイル: `doc_draft/requirement/RASIS品質指標/requirement.md`
|
|
723
|
+
|
|
724
|
+
## B-1. 機能要件
|
|
725
|
+
|
|
726
|
+
### FR-01: Asanaデータ取得
|
|
727
|
+
|
|
728
|
+
| 項目 | 内容 |
|
|
729
|
+
| ---------------- | ------------------------------------------------------------------- |
|
|
730
|
+
| 概要 | Asana REST APIでCRMインシデント管理プロジェクトの全タスクを取得する |
|
|
731
|
+
| データソース | Asanaプロジェクト「CRMインシデント管理」(GID: `1210141860554779`) |
|
|
732
|
+
| 認証方式 | Personal Access Token(Script Propertiesに格納) |
|
|
733
|
+
| ページネーション | Asana APIの`next_page.offset`を使い全件取得(limit=100/リクエスト) |
|
|
734
|
+
|
|
735
|
+
### FR-02: セクションベース判定
|
|
736
|
+
|
|
737
|
+
セクション分類は本コマンドの「定数定義 > セクションGID分類」を参照。
|
|
738
|
+
|
|
739
|
+
### FR-03〜05: R/A/S計算
|
|
740
|
+
|
|
741
|
+
計算ロジックは本コマンドの「Step 3〜5」を参照。
|
|
742
|
+
|
|
743
|
+
### FR-06: 今日のインシデント一覧
|
|
744
|
+
|
|
745
|
+
| 項目 | 内容 |
|
|
746
|
+
| --------- | ------------------------------------------------------ |
|
|
747
|
+
| 概要 | レポート実行日に起票されたインシデントの一覧を表示する |
|
|
748
|
+
| 表示項目 | タスク名(60文字まで), エラー種別, セクション名 |
|
|
749
|
+
| 0件の場合 | 「インシデントなし」と表示 |
|
|
750
|
+
|
|
751
|
+
### FR-07: Slack投稿
|
|
752
|
+
|
|
753
|
+
| 項目 | 内容 |
|
|
754
|
+
| ------------ | ------------------------------------ |
|
|
755
|
+
| 投稿方式 | Slack Incoming Webhook |
|
|
756
|
+
| フォーマット | Slack mrkdwn形式(太字、絵文字使用) |
|
|
757
|
+
|
|
758
|
+
### FR-08: 定期実行
|
|
759
|
+
|
|
760
|
+
| 項目 | 内容 |
|
|
761
|
+
| -------- | --------------------------- |
|
|
762
|
+
| 実行方式 | GAS時間主導型トリガー |
|
|
763
|
+
| 実行頻度 | 毎日1回(午前9時〜10時JST) |
|
|
764
|
+
|
|
765
|
+
## B-2. 非機能要件
|
|
766
|
+
|
|
767
|
+
| 項目 | 制限値 | 対応 |
|
|
768
|
+
| ------------------- | ---------------- | ------------------------------------------------ |
|
|
769
|
+
| GAS実行時間上限 | 6分 | ページネーションで全件取得しても十分に収まる想定 |
|
|
770
|
+
| Asana APIレート制限 | 150リクエスト/分 | 1回の実行で数リクエスト程度のため問題なし |
|
|
771
|
+
| Slack Webhook制限 | 1メッセージ/秒 | 1回の実行で1メッセージのため問題なし |
|
|
772
|
+
|
|
773
|
+
## B-3. エラーハンドリング
|
|
774
|
+
|
|
775
|
+
| エラー種別 | 対応 |
|
|
776
|
+
| ------------------------- | ---------------------------------------- |
|
|
777
|
+
| Asana API認証エラー | エラーメッセージをthrow(GASログに記録) |
|
|
778
|
+
| Asana APIレスポンスエラー | エラー内容をthrow |
|
|
779
|
+
| Slack Webhook URL未設定 | エラーメッセージをthrow |
|
|
780
|
+
| 対象データ0件 | 正常系として扱い「データなし」と表示 |
|
|
781
|
+
|
|
782
|
+
## B-4. セットアップ手順
|
|
783
|
+
|
|
784
|
+
1. GASエディタで新規スタンドアロンプロジェクトを作成
|
|
785
|
+
2. Appendix CのGASスクリプトの内容をペースト
|
|
786
|
+
3. Script Propertiesに `ASANA_TOKEN` と `SLACK_WEBHOOK_URL` を設定
|
|
787
|
+
4. `rasis_test()` を実行して計算結果を確認
|
|
788
|
+
5. トリガーを追加: `rasis_daily_report` → 毎日午前9〜10時
|
|
789
|
+
|
|
790
|
+
---
|
|
791
|
+
|
|
792
|
+
---
|
|
793
|
+
|
|
794
|
+
# Appendix C: GASスクリプト(参考実装)
|
|
795
|
+
|
|
796
|
+
> 元ファイル: `scripts/gas/rasis-report.gs`
|
|
797
|
+
> このスクリプトはGAS(Google Apps Script)で動作するSlack日次投稿用の参考実装。
|
|
798
|
+
> `/rasis-report` コマンド自体はAsana MCPを直接使用してMarkdownレポートを生成する。
|
|
799
|
+
|
|
800
|
+
```javascript
|
|
801
|
+
/**
|
|
802
|
+
* RASIS品質レポート - Google Apps Script
|
|
803
|
+
*
|
|
804
|
+
* Asana「CRMインシデント管理」プロジェクトからデータを取得し、
|
|
805
|
+
* R(信頼性)/A(可用性)/S(保守性)を計算してSlackに日次レポートを投稿する。
|
|
806
|
+
*
|
|
807
|
+
* 判定方式: セクションベース(カスタムフィールドは補助的に使用)
|
|
808
|
+
*
|
|
809
|
+
* セットアップ:
|
|
810
|
+
* 1. Script Properties に以下を設定:
|
|
811
|
+
* - ASANA_TOKEN: Asana Personal Access Token
|
|
812
|
+
* - SLACK_WEBHOOK_URL: Slack Incoming Webhook URL
|
|
813
|
+
* 2. トリガー設定: rasis_daily_report を毎日9:00に実行
|
|
814
|
+
*/
|
|
815
|
+
|
|
816
|
+
// ============================================================
|
|
817
|
+
// 設定値
|
|
818
|
+
// ============================================================
|
|
819
|
+
const CONFIG = {
|
|
820
|
+
PROJECT_GID: "1210141860554779",
|
|
821
|
+
|
|
822
|
+
TAIOU_SECTION_GID: "1213583272288474",
|
|
823
|
+
|
|
824
|
+
IMPACT_SECTION_GIDS: [
|
|
825
|
+
"1210141860554780", // 未対応
|
|
826
|
+
"1213583272288474", // 一時対応 / 復旧まで
|
|
827
|
+
"1212427130084727", // 調査中
|
|
828
|
+
"1212427130084711", // 調査済み
|
|
829
|
+
"1212442930023501", // 修正待機中
|
|
830
|
+
"1212411628435001", // 改修中
|
|
831
|
+
"1212411628434999", // 完了済み
|
|
832
|
+
"1213308608099451" // 水道自動申込
|
|
833
|
+
],
|
|
834
|
+
|
|
835
|
+
NO_IMPACT_SECTION_GIDS: [
|
|
836
|
+
"1212895654036871", // 修正が必要な業務に影響のないタスク
|
|
837
|
+
"1212427130084716", // 影響のないエラー
|
|
838
|
+
"1212427130084717", // 重複エラー
|
|
839
|
+
"1213037757239679", // SINGLE_EMAIL_LIMIT_EXCEEDED
|
|
840
|
+
"1212411628435000" // 過去のエラー
|
|
841
|
+
],
|
|
842
|
+
|
|
843
|
+
EXCLUDED_FROM_SERVICEABILITY: [
|
|
844
|
+
"1212427130084716", // 影響のないエラー
|
|
845
|
+
"1212427130084717", // 重複エラー
|
|
846
|
+
"1213037757239679", // SINGLE_EMAIL_LIMIT_EXCEEDED
|
|
847
|
+
"1212411628435000" // 過去のエラー
|
|
848
|
+
],
|
|
849
|
+
|
|
850
|
+
FIELD: {
|
|
851
|
+
ERROR_TYPE: "1210376591796313",
|
|
852
|
+
INCIDENT_LEVEL: "1212430676458427",
|
|
853
|
+
TASK_TYPE: "1210141956819951",
|
|
854
|
+
COMPLETION_DATE: "1212716524519634"
|
|
855
|
+
},
|
|
856
|
+
|
|
857
|
+
INCIDENT_LEVEL_VALUE: {
|
|
858
|
+
HIGH: "1212430676458428",
|
|
859
|
+
MEDIUM: "1212430676458429",
|
|
860
|
+
LOW: "1212430676458430"
|
|
861
|
+
},
|
|
862
|
+
|
|
863
|
+
RELIABILITY_DAYS: 90,
|
|
864
|
+
AVAILABILITY_DAYS: 90,
|
|
865
|
+
SERVICEABILITY_DAYS: 90,
|
|
866
|
+
TOTAL_HOURS: 90 * 24,
|
|
867
|
+
|
|
868
|
+
TARGET: {
|
|
869
|
+
AVAILABILITY: 0.99,
|
|
870
|
+
SERVICEABILITY_HOURS: 1
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
// ============================================================
|
|
875
|
+
// メイン関数
|
|
876
|
+
// ============================================================
|
|
877
|
+
|
|
878
|
+
function rasis_daily_report() {
|
|
879
|
+
const tasks = fetchAllIncidentTasks_();
|
|
880
|
+
const now = new Date();
|
|
881
|
+
const reliability = calcReliability_(tasks, now);
|
|
882
|
+
const availabilityResult = calcAvailability_(tasks, now);
|
|
883
|
+
const serviceability = calcServiceability_(availabilityResult.mttrList);
|
|
884
|
+
const todayIncidents = getTodayIncidents_(tasks, now);
|
|
885
|
+
const message = formatSlackMessage_(
|
|
886
|
+
reliability,
|
|
887
|
+
availabilityResult,
|
|
888
|
+
serviceability,
|
|
889
|
+
todayIncidents,
|
|
890
|
+
now
|
|
891
|
+
);
|
|
892
|
+
postToSlack_(message);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
function rasis_test() {
|
|
896
|
+
const tasks = fetchAllIncidentTasks_();
|
|
897
|
+
const now = new Date();
|
|
898
|
+
const reliability = calcReliability_(tasks, now);
|
|
899
|
+
const availabilityResult = calcAvailability_(tasks, now);
|
|
900
|
+
const serviceability = calcServiceability_(availabilityResult.mttrList);
|
|
901
|
+
const todayIncidents = getTodayIncidents_(tasks, now);
|
|
902
|
+
Logger.log("=== RASIS テスト結果 ===");
|
|
903
|
+
Logger.log(
|
|
904
|
+
"R(信頼性/MTBF): " +
|
|
905
|
+
(reliability.mtbf !== null
|
|
906
|
+
? reliability.mtbf.toFixed(1) + "日"
|
|
907
|
+
: "算出不可") +
|
|
908
|
+
" (エラー: " +
|
|
909
|
+
reliability.errorCount +
|
|
910
|
+
"件)"
|
|
911
|
+
);
|
|
912
|
+
Logger.log(
|
|
913
|
+
"A(可用性): " +
|
|
914
|
+
(availabilityResult.rate * 100).toFixed(1) +
|
|
915
|
+
"% (MTTR合計: " +
|
|
916
|
+
availabilityResult.sumMttrHours.toFixed(1) +
|
|
917
|
+
"H, 対象: " +
|
|
918
|
+
availabilityResult.count +
|
|
919
|
+
"件)"
|
|
920
|
+
);
|
|
921
|
+
Logger.log(
|
|
922
|
+
"S(保守性/MTTR): " +
|
|
923
|
+
(serviceability.avg !== null
|
|
924
|
+
? serviceability.avg.toFixed(1) + "H"
|
|
925
|
+
: "データなし") +
|
|
926
|
+
" (中央値: " +
|
|
927
|
+
(serviceability.median !== null
|
|
928
|
+
? serviceability.median.toFixed(1) + "H"
|
|
929
|
+
: "-") +
|
|
930
|
+
")"
|
|
931
|
+
);
|
|
932
|
+
const message = formatSlackMessage_(
|
|
933
|
+
reliability,
|
|
934
|
+
availabilityResult,
|
|
935
|
+
serviceability,
|
|
936
|
+
todayIncidents,
|
|
937
|
+
now
|
|
938
|
+
);
|
|
939
|
+
Logger.log("\n--- Slack投稿プレビュー ---");
|
|
940
|
+
Logger.log(message.text);
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// ============================================================
|
|
944
|
+
// Asana API
|
|
945
|
+
// ============================================================
|
|
946
|
+
|
|
947
|
+
function fetchAllIncidentTasks_() {
|
|
948
|
+
const token =
|
|
949
|
+
PropertiesService.getScriptProperties().getProperty("ASANA_TOKEN");
|
|
950
|
+
if (!token)
|
|
951
|
+
throw new Error("ASANA_TOKEN が Script Properties に設定されていません");
|
|
952
|
+
const optFields = [
|
|
953
|
+
"name",
|
|
954
|
+
"created_at",
|
|
955
|
+
"completed",
|
|
956
|
+
"completed_at",
|
|
957
|
+
"memberships.section.gid",
|
|
958
|
+
"memberships.section.name",
|
|
959
|
+
"custom_fields"
|
|
960
|
+
].join(",");
|
|
961
|
+
var allTasks = [],
|
|
962
|
+
offset = null;
|
|
963
|
+
do {
|
|
964
|
+
var url =
|
|
965
|
+
"https://app.asana.com/api/1.0/projects/" +
|
|
966
|
+
CONFIG.PROJECT_GID +
|
|
967
|
+
"/tasks?opt_fields=" +
|
|
968
|
+
encodeURIComponent(optFields) +
|
|
969
|
+
"&limit=100";
|
|
970
|
+
if (offset) url += "&offset=" + offset;
|
|
971
|
+
var response = UrlFetchApp.fetch(url, {
|
|
972
|
+
headers: { Authorization: "Bearer " + token },
|
|
973
|
+
muteHttpExceptions: true
|
|
974
|
+
});
|
|
975
|
+
var json = JSON.parse(response.getContentText());
|
|
976
|
+
if (json.errors)
|
|
977
|
+
throw new Error("Asana API Error: " + JSON.stringify(json.errors));
|
|
978
|
+
allTasks = allTasks.concat(json.data);
|
|
979
|
+
offset = json.next_page ? json.next_page.offset : null;
|
|
980
|
+
} while (offset);
|
|
981
|
+
return allTasks;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
function fetchStoriesForTask_(taskGid) {
|
|
985
|
+
var token =
|
|
986
|
+
PropertiesService.getScriptProperties().getProperty("ASANA_TOKEN");
|
|
987
|
+
var url =
|
|
988
|
+
"https://app.asana.com/api/1.0/tasks/" +
|
|
989
|
+
taskGid +
|
|
990
|
+
"/stories?opt_fields=" +
|
|
991
|
+
encodeURIComponent("resource_subtype,text,created_at");
|
|
992
|
+
var response = UrlFetchApp.fetch(url, {
|
|
993
|
+
headers: { Authorization: "Bearer " + token },
|
|
994
|
+
muteHttpExceptions: true
|
|
995
|
+
});
|
|
996
|
+
var json = JSON.parse(response.getContentText());
|
|
997
|
+
if (json.errors) {
|
|
998
|
+
Logger.log(
|
|
999
|
+
"Stories API Error for task " +
|
|
1000
|
+
taskGid +
|
|
1001
|
+
": " +
|
|
1002
|
+
JSON.stringify(json.errors)
|
|
1003
|
+
);
|
|
1004
|
+
return [];
|
|
1005
|
+
}
|
|
1006
|
+
return json.data || [];
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
function getRecoveryTimeFromStories_(taskGid) {
|
|
1010
|
+
var stories = fetchStoriesForTask_(taskGid);
|
|
1011
|
+
for (var i = 0; i < stories.length; i++) {
|
|
1012
|
+
var story = stories[i];
|
|
1013
|
+
if (!story.text) continue;
|
|
1014
|
+
if (
|
|
1015
|
+
story.text.indexOf("一時対応") !== -1 &&
|
|
1016
|
+
(story.text.indexOf("from") !== -1 || story.text.indexOf("から") !== -1)
|
|
1017
|
+
) {
|
|
1018
|
+
return new Date(story.created_at);
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
return null;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
// ============================================================
|
|
1025
|
+
// セクション判定
|
|
1026
|
+
// ============================================================
|
|
1027
|
+
|
|
1028
|
+
function getProjectSectionGid_(task) {
|
|
1029
|
+
if (!task.memberships) return null;
|
|
1030
|
+
var allKnown = CONFIG.IMPACT_SECTION_GIDS.concat(
|
|
1031
|
+
CONFIG.NO_IMPACT_SECTION_GIDS
|
|
1032
|
+
);
|
|
1033
|
+
for (var i = 0; i < task.memberships.length; i++) {
|
|
1034
|
+
var secGid = task.memberships[i].section
|
|
1035
|
+
? task.memberships[i].section.gid
|
|
1036
|
+
: null;
|
|
1037
|
+
if (secGid && allKnown.indexOf(secGid) !== -1) return secGid;
|
|
1038
|
+
}
|
|
1039
|
+
if (task.memberships.length > 0 && task.memberships[0].section)
|
|
1040
|
+
return task.memberships[0].section.gid;
|
|
1041
|
+
return null;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
function isInImpactSection_(task) {
|
|
1045
|
+
var secGid = getProjectSectionGid_(task);
|
|
1046
|
+
return secGid !== null && CONFIG.IMPACT_SECTION_GIDS.indexOf(secGid) !== -1;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
function isExcludedFromServiceability_(task) {
|
|
1050
|
+
var secGid = getProjectSectionGid_(task);
|
|
1051
|
+
return (
|
|
1052
|
+
secGid !== null &&
|
|
1053
|
+
CONFIG.EXCLUDED_FROM_SERVICEABILITY.indexOf(secGid) !== -1
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
function getCurrentSectionName_(task) {
|
|
1058
|
+
if (!task.memberships || task.memberships.length === 0) return "不明";
|
|
1059
|
+
var allKnown = CONFIG.IMPACT_SECTION_GIDS.concat(
|
|
1060
|
+
CONFIG.NO_IMPACT_SECTION_GIDS
|
|
1061
|
+
);
|
|
1062
|
+
for (var i = 0; i < task.memberships.length; i++) {
|
|
1063
|
+
var m = task.memberships[i];
|
|
1064
|
+
if (m.section && allKnown.indexOf(m.section.gid) !== -1)
|
|
1065
|
+
return m.section.name;
|
|
1066
|
+
}
|
|
1067
|
+
if (task.memberships[0].section) return task.memberships[0].section.name;
|
|
1068
|
+
return "不明";
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
// ============================================================
|
|
1072
|
+
// ヘルパー関数
|
|
1073
|
+
// ============================================================
|
|
1074
|
+
|
|
1075
|
+
function getCustomFieldValue_(task, fieldGid) {
|
|
1076
|
+
if (!task.custom_fields) return null;
|
|
1077
|
+
for (var i = 0; i < task.custom_fields.length; i++) {
|
|
1078
|
+
if (task.custom_fields[i].gid === fieldGid) {
|
|
1079
|
+
return task.custom_fields[i].enum_value
|
|
1080
|
+
? task.custom_fields[i].enum_value.gid
|
|
1081
|
+
: null;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
return null;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
function getIncidentLevelLabel_(task) {
|
|
1088
|
+
var val = getCustomFieldValue_(task, CONFIG.FIELD.INCIDENT_LEVEL);
|
|
1089
|
+
if (val === CONFIG.INCIDENT_LEVEL_VALUE.HIGH) return "高";
|
|
1090
|
+
if (val === CONFIG.INCIDENT_LEVEL_VALUE.MEDIUM) return "中";
|
|
1091
|
+
if (val === CONFIG.INCIDENT_LEVEL_VALUE.LOW) return "低";
|
|
1092
|
+
return "-";
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
function toJSTDateString_(date) {
|
|
1096
|
+
var jst = new Date(date.getTime() + 9 * 60 * 60 * 1000);
|
|
1097
|
+
return jst.toISOString().split("T")[0];
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
function daysAgo_(n, from) {
|
|
1101
|
+
var d = new Date(from);
|
|
1102
|
+
d.setDate(d.getDate() - n);
|
|
1103
|
+
d.setHours(0, 0, 0, 0);
|
|
1104
|
+
return d;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
function median_(arr) {
|
|
1108
|
+
if (arr.length === 0) return 0;
|
|
1109
|
+
var sorted = arr.slice().sort(function (a, b) {
|
|
1110
|
+
return a - b;
|
|
1111
|
+
});
|
|
1112
|
+
var mid = Math.floor(sorted.length / 2);
|
|
1113
|
+
return sorted.length % 2 !== 0
|
|
1114
|
+
? sorted[mid]
|
|
1115
|
+
: (sorted[mid - 1] + sorted[mid]) / 2;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
// ============================================================
|
|
1119
|
+
// RASIS計算
|
|
1120
|
+
// ============================================================
|
|
1121
|
+
|
|
1122
|
+
function calcReliability_(tasks, now) {
|
|
1123
|
+
var periodStart = daysAgo_(CONFIG.RELIABILITY_DAYS, now);
|
|
1124
|
+
var errorCount = 0,
|
|
1125
|
+
recentErrors = [];
|
|
1126
|
+
for (var i = 0; i < tasks.length; i++) {
|
|
1127
|
+
var task = tasks[i];
|
|
1128
|
+
if (!isInImpactSection_(task)) continue;
|
|
1129
|
+
var createdAt = new Date(task.created_at);
|
|
1130
|
+
if (createdAt < periodStart) continue;
|
|
1131
|
+
errorCount++;
|
|
1132
|
+
recentErrors.push({
|
|
1133
|
+
name: task.name || "(無題)",
|
|
1134
|
+
date: toJSTDateString_(createdAt)
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
recentErrors.sort(function (a, b) {
|
|
1138
|
+
return b.date.localeCompare(a.date);
|
|
1139
|
+
});
|
|
1140
|
+
return {
|
|
1141
|
+
mtbf: errorCount > 0 ? 365 / errorCount : null,
|
|
1142
|
+
errorCount: errorCount,
|
|
1143
|
+
recentErrors: recentErrors.slice(0, 5)
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
function calcAvailability_(tasks, now) {
|
|
1148
|
+
var periodStart = daysAgo_(CONFIG.AVAILABILITY_DAYS, now);
|
|
1149
|
+
var allMttr = [];
|
|
1150
|
+
for (var i = 0; i < tasks.length; i++) {
|
|
1151
|
+
var task = tasks[i];
|
|
1152
|
+
if (!isInImpactSection_(task)) continue;
|
|
1153
|
+
var createdAt = new Date(task.created_at);
|
|
1154
|
+
if (createdAt < periodStart) continue;
|
|
1155
|
+
var currentSectionGid = getProjectSectionGid_(task);
|
|
1156
|
+
if (currentSectionGid === CONFIG.TAIOU_SECTION_GID) continue;
|
|
1157
|
+
var recoveryAt = getRecoveryTimeFromStories_(task.gid);
|
|
1158
|
+
if (!recoveryAt) continue;
|
|
1159
|
+
var mttrHours = (recoveryAt - createdAt) / (1000 * 60 * 60);
|
|
1160
|
+
if (mttrHours < 0) continue;
|
|
1161
|
+
allMttr.push(mttrHours);
|
|
1162
|
+
}
|
|
1163
|
+
var sumMttr =
|
|
1164
|
+
allMttr.length > 0
|
|
1165
|
+
? allMttr.reduce(function (a, b) {
|
|
1166
|
+
return a + b;
|
|
1167
|
+
}, 0)
|
|
1168
|
+
: 0;
|
|
1169
|
+
var rate = (CONFIG.TOTAL_HOURS - sumMttr) / CONFIG.TOTAL_HOURS;
|
|
1170
|
+
if (rate < 0) rate = 0;
|
|
1171
|
+
return {
|
|
1172
|
+
rate: rate,
|
|
1173
|
+
sumMttrHours: sumMttr,
|
|
1174
|
+
count: allMttr.length,
|
|
1175
|
+
mttrList: allMttr,
|
|
1176
|
+
meetsTarget: rate >= CONFIG.TARGET.AVAILABILITY || allMttr.length === 0
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
function calcServiceability_(mttrList) {
|
|
1181
|
+
if (!mttrList || mttrList.length === 0)
|
|
1182
|
+
return { avg: null, median: null, count: 0, meetsTarget: true };
|
|
1183
|
+
var avg =
|
|
1184
|
+
mttrList.reduce(function (a, b) {
|
|
1185
|
+
return a + b;
|
|
1186
|
+
}, 0) / mttrList.length;
|
|
1187
|
+
return {
|
|
1188
|
+
avg: avg,
|
|
1189
|
+
median: median_(mttrList),
|
|
1190
|
+
count: mttrList.length,
|
|
1191
|
+
meetsTarget: avg <= CONFIG.TARGET.SERVICEABILITY_HOURS
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
function getTodayIncidents_(tasks, now) {
|
|
1196
|
+
var todayStr = toJSTDateString_(now),
|
|
1197
|
+
incidents = [];
|
|
1198
|
+
for (var i = 0; i < tasks.length; i++) {
|
|
1199
|
+
var task = tasks[i];
|
|
1200
|
+
if (toJSTDateString_(new Date(task.created_at)) !== todayStr || !task.name)
|
|
1201
|
+
continue;
|
|
1202
|
+
incidents.push({
|
|
1203
|
+
name:
|
|
1204
|
+
task.name.length > 60 ? task.name.substring(0, 60) + "..." : task.name,
|
|
1205
|
+
section: getCurrentSectionName_(task)
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
return incidents;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
// ============================================================
|
|
1212
|
+
// レポートフォーマット
|
|
1213
|
+
// ============================================================
|
|
1214
|
+
|
|
1215
|
+
function formatSlackMessage_(
|
|
1216
|
+
reliability,
|
|
1217
|
+
availability,
|
|
1218
|
+
serviceability,
|
|
1219
|
+
todayIncidents,
|
|
1220
|
+
now
|
|
1221
|
+
) {
|
|
1222
|
+
var dateStr = Utilities.formatDate(now, "Asia/Tokyo", "yyyy/MM/dd (E)");
|
|
1223
|
+
var aIcon = availability.meetsTarget
|
|
1224
|
+
? ":large_green_circle:"
|
|
1225
|
+
: ":red_circle:";
|
|
1226
|
+
var sIcon = serviceability.meetsTarget
|
|
1227
|
+
? ":large_green_circle:"
|
|
1228
|
+
: ":red_circle:";
|
|
1229
|
+
var text = "";
|
|
1230
|
+
text += ":bar_chart: *RASIS品質レポート - " + dateStr + "*\n";
|
|
1231
|
+
text += "──────────────────────────────\n\n";
|
|
1232
|
+
text += ":chart_with_upwards_trend: *R 信頼性(MTBF): ";
|
|
1233
|
+
text +=
|
|
1234
|
+
reliability.mtbf !== null
|
|
1235
|
+
? reliability.mtbf.toFixed(1) + "日*\n"
|
|
1236
|
+
: "算出不可(エラーなし)*\n";
|
|
1237
|
+
text +=
|
|
1238
|
+
" " +
|
|
1239
|
+
CONFIG.RELIABILITY_DAYS +
|
|
1240
|
+
"日間のエラー回数: " +
|
|
1241
|
+
reliability.errorCount +
|
|
1242
|
+
"件\n";
|
|
1243
|
+
if (reliability.recentErrors.length > 0) {
|
|
1244
|
+
text +=
|
|
1245
|
+
" 直近エラー: " +
|
|
1246
|
+
reliability.recentErrors
|
|
1247
|
+
.map(function (e) {
|
|
1248
|
+
return e.date;
|
|
1249
|
+
})
|
|
1250
|
+
.join(", ") +
|
|
1251
|
+
"\n";
|
|
1252
|
+
}
|
|
1253
|
+
text += "\n";
|
|
1254
|
+
text +=
|
|
1255
|
+
aIcon +
|
|
1256
|
+
" *A 可用性: " +
|
|
1257
|
+
(availability.rate * 100).toFixed(1) +
|
|
1258
|
+
"%* (目標: " +
|
|
1259
|
+
CONFIG.TARGET.AVAILABILITY * 100 +
|
|
1260
|
+
"%)\n";
|
|
1261
|
+
text +=
|
|
1262
|
+
" MTTR合計: " +
|
|
1263
|
+
availability.sumMttrHours.toFixed(1) +
|
|
1264
|
+
"H / " +
|
|
1265
|
+
CONFIG.TOTAL_HOURS +
|
|
1266
|
+
"H (対象: " +
|
|
1267
|
+
availability.count +
|
|
1268
|
+
"件)\n\n";
|
|
1269
|
+
text += sIcon + " *S 保守性(MTTR): ";
|
|
1270
|
+
text +=
|
|
1271
|
+
serviceability.avg !== null
|
|
1272
|
+
? "平均 " +
|
|
1273
|
+
serviceability.avg.toFixed(1) +
|
|
1274
|
+
"H / 中央値 " +
|
|
1275
|
+
serviceability.median.toFixed(1) +
|
|
1276
|
+
"H*"
|
|
1277
|
+
: "データなし*";
|
|
1278
|
+
text += " (目標: " + CONFIG.TARGET.SERVICEABILITY_HOURS + "H以内)\n";
|
|
1279
|
+
text += " 対象: " + serviceability.count + "件\n\n";
|
|
1280
|
+
text += "──────────────────────────────\n";
|
|
1281
|
+
text += ":pushpin: *今日のインシデント (" + todayIncidents.length + "件)*\n";
|
|
1282
|
+
if (todayIncidents.length === 0) {
|
|
1283
|
+
text += " インシデントなし :tada:\n";
|
|
1284
|
+
} else {
|
|
1285
|
+
for (var k = 0; k < todayIncidents.length; k++) {
|
|
1286
|
+
text +=
|
|
1287
|
+
" ・" +
|
|
1288
|
+
todayIncidents[k].name +
|
|
1289
|
+
" [" +
|
|
1290
|
+
todayIncidents[k].section +
|
|
1291
|
+
"]\n";
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
return { text: text };
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
// ============================================================
|
|
1298
|
+
// Slack投稿・セットアップ
|
|
1299
|
+
// ============================================================
|
|
1300
|
+
|
|
1301
|
+
function postToSlack_(message) {
|
|
1302
|
+
var webhookUrl =
|
|
1303
|
+
PropertiesService.getScriptProperties().getProperty("SLACK_WEBHOOK_URL");
|
|
1304
|
+
if (!webhookUrl)
|
|
1305
|
+
throw new Error(
|
|
1306
|
+
"SLACK_WEBHOOK_URL が Script Properties に設定されていません"
|
|
1307
|
+
);
|
|
1308
|
+
UrlFetchApp.fetch(webhookUrl, {
|
|
1309
|
+
method: "post",
|
|
1310
|
+
contentType: "application/json",
|
|
1311
|
+
payload: JSON.stringify(message),
|
|
1312
|
+
muteHttpExceptions: true
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
function setupDirect() {
|
|
1317
|
+
PropertiesService.getScriptProperties().setProperties({
|
|
1318
|
+
ASANA_TOKEN: "YOUR_ASANA_PERSONAL_ACCESS_TOKEN_HERE",
|
|
1319
|
+
SLACK_WEBHOOK_URL: "YOUR_SLACK_WEBHOOK_URL_HERE"
|
|
1320
|
+
});
|
|
1321
|
+
Logger.log("Script Properties を設定しました");
|
|
1322
|
+
}
|
|
1323
|
+
```
|