aios-core 2.1.5 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/.aios-core/core/README.md +229 -229
  2. package/.aios-core/core/data/agent-config-requirements.yaml +368 -368
  3. package/.aios-core/core/data/aios-kb.md +923 -923
  4. package/.aios-core/core/data/workflow-patterns.yaml +267 -267
  5. package/.aios-core/core/docs/SHARD-TRANSLATION-GUIDE.md +335 -335
  6. package/.aios-core/core/docs/component-creation-guide.md +457 -457
  7. package/.aios-core/core/docs/session-update-pattern.md +307 -307
  8. package/.aios-core/core/docs/template-syntax.md +266 -266
  9. package/.aios-core/core/docs/troubleshooting-guide.md +624 -624
  10. package/.aios-core/core/elicitation/elicitation-engine.js +1 -1
  11. package/.aios-core/core/index.esm.js +42 -42
  12. package/.aios-core/core/index.js +1 -1
  13. package/.aios-core/core/migration/migration-config.yaml +83 -83
  14. package/.aios-core/core/migration/module-mapping.yaml +89 -89
  15. package/.aios-core/core/quality-gates/layer2-pr-automation.js +1 -1
  16. package/.aios-core/core/quality-gates/quality-gate-config.yaml +86 -86
  17. package/.aios-core/core/registry/README.md +179 -179
  18. package/.aios-core/core/utils/security-utils.js +1 -1
  19. package/.aios-core/core-config.yaml +391 -382
  20. package/.aios-core/data/agent-config-requirements.yaml +368 -368
  21. package/.aios-core/data/aios-kb.md +923 -923
  22. package/.aios-core/data/technical-preferences.md +3 -3
  23. package/.aios-core/data/workflow-patterns.yaml +267 -267
  24. package/.aios-core/development/README.md +142 -142
  25. package/.aios-core/development/agent-teams/team-all.yaml +15 -15
  26. package/.aios-core/development/agent-teams/team-fullstack.yaml +18 -18
  27. package/.aios-core/development/agent-teams/team-ide-minimal.yaml +10 -10
  28. package/.aios-core/development/agent-teams/team-no-ui.yaml +13 -13
  29. package/.aios-core/development/agent-teams/team-qa-focused.yaml +155 -155
  30. package/.aios-core/development/agents/aios-master.md +339 -339
  31. package/.aios-core/development/agents/analyst.md +195 -195
  32. package/.aios-core/development/agents/architect.md +359 -359
  33. package/.aios-core/development/agents/data-engineer.md +468 -468
  34. package/.aios-core/development/agents/dev.md +390 -390
  35. package/.aios-core/development/agents/devops.md +398 -398
  36. package/.aios-core/development/agents/pm.md +198 -198
  37. package/.aios-core/development/agents/po.md +256 -256
  38. package/.aios-core/development/agents/qa.md +312 -312
  39. package/.aios-core/development/agents/sm.md +220 -220
  40. package/.aios-core/development/agents/ux-design-expert.md +451 -451
  41. package/.aios-core/development/scripts/greeting-config-cli.js +85 -85
  42. package/.aios-core/development/tasks/add-mcp.md +319 -319
  43. package/.aios-core/development/tasks/advanced-elicitation.md +318 -318
  44. package/.aios-core/development/tasks/analyst-facilitate-brainstorming.md +341 -341
  45. package/.aios-core/development/tasks/analyze-brownfield.md +456 -0
  46. package/.aios-core/development/tasks/analyze-framework.md +696 -696
  47. package/.aios-core/development/tasks/analyze-performance.md +637 -637
  48. package/.aios-core/development/tasks/apply-qa-fixes.md +340 -340
  49. package/.aios-core/development/tasks/architect-analyze-impact.md +826 -826
  50. package/.aios-core/development/tasks/audit-codebase.md +429 -429
  51. package/.aios-core/development/tasks/audit-tailwind-config.md +270 -270
  52. package/.aios-core/development/tasks/audit-utilities.md +358 -358
  53. package/.aios-core/development/tasks/bootstrap-shadcn-library.md +286 -286
  54. package/.aios-core/development/tasks/brownfield-create-epic.md +485 -485
  55. package/.aios-core/development/tasks/brownfield-create-story.md +356 -356
  56. package/.aios-core/development/tasks/build-component.md +478 -478
  57. package/.aios-core/development/tasks/calculate-roi.md +455 -455
  58. package/.aios-core/development/tasks/ci-cd-configuration.md +764 -764
  59. package/.aios-core/development/tasks/cleanup-utilities.md +670 -670
  60. package/.aios-core/development/tasks/collaborative-edit.md +1108 -1108
  61. package/.aios-core/development/tasks/compose-molecule.md +284 -284
  62. package/.aios-core/development/tasks/consolidate-patterns.md +414 -414
  63. package/.aios-core/development/tasks/correct-course.md +279 -279
  64. package/.aios-core/development/tasks/create-agent.md +321 -321
  65. package/.aios-core/development/tasks/create-brownfield-story.md +726 -726
  66. package/.aios-core/development/tasks/create-deep-research-prompt.md +498 -498
  67. package/.aios-core/development/tasks/create-doc.md +316 -316
  68. package/.aios-core/development/tasks/create-next-story.md +774 -774
  69. package/.aios-core/development/tasks/create-suite.md +283 -283
  70. package/.aios-core/development/tasks/create-task.md +371 -371
  71. package/.aios-core/development/tasks/create-workflow.md +370 -370
  72. package/.aios-core/development/tasks/db-analyze-hotpaths.md +572 -572
  73. package/.aios-core/development/tasks/db-apply-migration.md +381 -381
  74. package/.aios-core/development/tasks/db-bootstrap.md +642 -642
  75. package/.aios-core/development/tasks/db-domain-modeling.md +693 -693
  76. package/.aios-core/development/tasks/db-dry-run.md +293 -293
  77. package/.aios-core/development/tasks/db-env-check.md +260 -260
  78. package/.aios-core/development/tasks/db-expansion-pack-integration.md +663 -663
  79. package/.aios-core/development/tasks/db-explain.md +631 -631
  80. package/.aios-core/development/tasks/db-impersonate.md +495 -495
  81. package/.aios-core/development/tasks/db-load-csv.md +593 -593
  82. package/.aios-core/development/tasks/db-policy-apply.md +653 -653
  83. package/.aios-core/development/tasks/db-rls-audit.md +411 -411
  84. package/.aios-core/development/tasks/db-rollback.md +739 -739
  85. package/.aios-core/development/tasks/db-run-sql.md +613 -613
  86. package/.aios-core/development/tasks/db-schema-audit.md +1011 -1011
  87. package/.aios-core/development/tasks/db-seed.md +390 -390
  88. package/.aios-core/development/tasks/db-smoke-test.md +351 -351
  89. package/.aios-core/development/tasks/db-snapshot.md +569 -569
  90. package/.aios-core/development/tasks/db-supabase-setup.md +712 -712
  91. package/.aios-core/development/tasks/db-verify-order.md +515 -515
  92. package/.aios-core/development/tasks/deprecate-component.md +956 -956
  93. package/.aios-core/development/tasks/dev-apply-qa-fixes.md +318 -318
  94. package/.aios-core/development/tasks/dev-backlog-debt.md +469 -469
  95. package/.aios-core/development/tasks/dev-develop-story.md +846 -846
  96. package/.aios-core/development/tasks/dev-improve-code-quality.md +872 -872
  97. package/.aios-core/development/tasks/dev-optimize-performance.md +1033 -1033
  98. package/.aios-core/development/tasks/dev-suggest-refactoring.md +870 -870
  99. package/.aios-core/development/tasks/dev-validate-next-story.md +348 -348
  100. package/.aios-core/development/tasks/document-project.md +552 -552
  101. package/.aios-core/development/tasks/environment-bootstrap.md +1311 -1311
  102. package/.aios-core/development/tasks/execute-checklist.md +301 -301
  103. package/.aios-core/development/tasks/export-design-tokens-dtcg.md +274 -274
  104. package/.aios-core/development/tasks/extend-pattern.md +269 -269
  105. package/.aios-core/development/tasks/extract-tokens.md +467 -467
  106. package/.aios-core/development/tasks/facilitate-brainstorming-session.md +518 -518
  107. package/.aios-core/development/tasks/generate-ai-frontend-prompt.md +260 -260
  108. package/.aios-core/development/tasks/generate-documentation.md +284 -284
  109. package/.aios-core/development/tasks/generate-migration-strategy.md +522 -522
  110. package/.aios-core/development/tasks/generate-shock-report.md +501 -501
  111. package/.aios-core/development/tasks/github-devops-github-pr-automation.md +427 -427
  112. package/.aios-core/development/tasks/github-devops-pre-push-quality-gate.md +733 -733
  113. package/.aios-core/development/tasks/github-devops-repository-cleanup.md +374 -374
  114. package/.aios-core/development/tasks/github-devops-version-management.md +483 -483
  115. package/.aios-core/development/tasks/improve-self.md +822 -822
  116. package/.aios-core/development/tasks/index-docs.md +387 -387
  117. package/.aios-core/development/tasks/init-project-status.md +506 -506
  118. package/.aios-core/development/tasks/integrate-expansion-pack.md +314 -314
  119. package/.aios-core/development/tasks/kb-mode-interaction.md +283 -283
  120. package/.aios-core/development/tasks/learn-patterns.md +900 -900
  121. package/.aios-core/development/tasks/mcp-workflow.md +437 -437
  122. package/.aios-core/development/tasks/modify-agent.md +381 -381
  123. package/.aios-core/development/tasks/modify-task.md +424 -424
  124. package/.aios-core/development/tasks/modify-workflow.md +465 -465
  125. package/.aios-core/development/tasks/po-backlog-add.md +370 -370
  126. package/.aios-core/development/tasks/po-manage-story-backlog.md +523 -523
  127. package/.aios-core/development/tasks/po-pull-story-from-clickup.md +540 -540
  128. package/.aios-core/development/tasks/po-pull-story.md +316 -316
  129. package/.aios-core/development/tasks/po-stories-index.md +351 -351
  130. package/.aios-core/development/tasks/po-sync-story-to-clickup.md +457 -457
  131. package/.aios-core/development/tasks/po-sync-story.md +303 -303
  132. package/.aios-core/development/tasks/pr-automation.md +701 -701
  133. package/.aios-core/development/tasks/propose-modification.md +842 -842
  134. package/.aios-core/development/tasks/qa-backlog-add-followup.md +425 -425
  135. package/.aios-core/development/tasks/qa-gate.md +373 -373
  136. package/.aios-core/development/tasks/qa-generate-tests.md +1174 -1174
  137. package/.aios-core/development/tasks/qa-nfr-assess.md +557 -557
  138. package/.aios-core/development/tasks/qa-review-proposal.md +1157 -1157
  139. package/.aios-core/development/tasks/qa-review-story.md +682 -682
  140. package/.aios-core/development/tasks/qa-risk-profile.md +566 -566
  141. package/.aios-core/development/tasks/qa-run-tests.md +277 -277
  142. package/.aios-core/development/tasks/qa-test-design.md +387 -387
  143. package/.aios-core/development/tasks/qa-trace-requirements.md +476 -476
  144. package/.aios-core/development/tasks/release-management.md +723 -723
  145. package/.aios-core/development/tasks/security-audit.md +554 -554
  146. package/.aios-core/development/tasks/security-scan.md +790 -790
  147. package/.aios-core/development/tasks/setup-database.md +741 -741
  148. package/.aios-core/development/tasks/setup-design-system.md +462 -462
  149. package/.aios-core/development/tasks/setup-github.md +874 -874
  150. package/.aios-core/development/tasks/setup-llm-routing.md +1 -1
  151. package/.aios-core/development/tasks/setup-mcp-docker.md +584 -584
  152. package/.aios-core/development/tasks/setup-project-docs.md +440 -0
  153. package/.aios-core/development/tasks/shard-doc.md +537 -537
  154. package/.aios-core/development/tasks/sm-create-next-story.md +480 -480
  155. package/.aios-core/development/tasks/sync-documentation.md +864 -864
  156. package/.aios-core/development/tasks/tailwind-upgrade.md +294 -294
  157. package/.aios-core/development/tasks/test-as-user.md +621 -621
  158. package/.aios-core/development/tasks/test-validation-task.md +171 -171
  159. package/.aios-core/development/tasks/undo-last.md +346 -346
  160. package/.aios-core/development/tasks/update-manifest.md +409 -409
  161. package/.aios-core/development/tasks/ux-create-wireframe.md +617 -617
  162. package/.aios-core/development/tasks/ux-ds-scan-artifact.md +672 -672
  163. package/.aios-core/development/tasks/ux-user-research.md +559 -559
  164. package/.aios-core/development/tasks/validate-next-story.md +422 -422
  165. package/.aios-core/development/workflows/README.md +83 -83
  166. package/.aios-core/development/workflows/brownfield-fullstack.yaml +297 -297
  167. package/.aios-core/development/workflows/brownfield-service.yaml +187 -187
  168. package/.aios-core/development/workflows/brownfield-ui.yaml +197 -197
  169. package/.aios-core/development/workflows/greenfield-fullstack.yaml +333 -333
  170. package/.aios-core/development/workflows/greenfield-service.yaml +206 -206
  171. package/.aios-core/development/workflows/greenfield-ui.yaml +235 -235
  172. package/.aios-core/docs/SHARD-TRANSLATION-GUIDE.md +335 -335
  173. package/.aios-core/docs/component-creation-guide.md +457 -457
  174. package/.aios-core/docs/session-update-pattern.md +307 -307
  175. package/.aios-core/docs/standards/AGENT-PERSONALIZATION-STANDARD-V1.md +572 -572
  176. package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-QUICK-REFERENCE.md +185 -185
  177. package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-V2.1.md +354 -354
  178. package/.aios-core/docs/standards/AIOS-FRAMEWORK-MASTER.md +1963 -1963
  179. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +821 -821
  180. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-SUMMARY.md +1190 -1190
  181. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1.md +439 -439
  182. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.2-SUMMARY.md +1339 -1339
  183. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO.md +5398 -5398
  184. package/.aios-core/docs/standards/EXECUTOR-DECISION-TREE.md +697 -697
  185. package/.aios-core/docs/standards/OPEN-SOURCE-VS-SERVICE-DIFFERENCES.md +511 -511
  186. package/.aios-core/docs/standards/QUALITY-GATES-SPECIFICATION.md +556 -556
  187. package/.aios-core/docs/standards/STANDARDS-INDEX.md +210 -210
  188. package/.aios-core/docs/standards/STORY-TEMPLATE-V2-SPECIFICATION.md +550 -550
  189. package/.aios-core/docs/standards/TASK-FORMAT-SPECIFICATION-V1.md +1414 -1414
  190. package/.aios-core/docs/standards/V3-ARCHITECTURAL-DECISIONS.md +523 -523
  191. package/.aios-core/docs/template-syntax.md +266 -266
  192. package/.aios-core/docs/troubleshooting-guide.md +624 -624
  193. package/.aios-core/index.esm.js +15 -15
  194. package/.aios-core/index.js +1 -1
  195. package/.aios-core/infrastructure/README.md +126 -126
  196. package/.aios-core/infrastructure/integrations/pm-adapters/README.md +59 -59
  197. package/.aios-core/infrastructure/scripts/approval-workflow.js +1 -1
  198. package/.aios-core/infrastructure/scripts/batch-creator.js +1 -1
  199. package/.aios-core/infrastructure/scripts/component-generator.js +3 -3
  200. package/.aios-core/infrastructure/scripts/component-metadata.js +1 -1
  201. package/.aios-core/infrastructure/scripts/component-search.js +1 -1
  202. package/.aios-core/infrastructure/scripts/coverage-analyzer.js +1 -1
  203. package/.aios-core/infrastructure/scripts/dependency-analyzer.js +1 -1
  204. package/.aios-core/infrastructure/scripts/dependency-impact-analyzer.js +1 -1
  205. package/.aios-core/infrastructure/scripts/documentation-integrity/brownfield-analyzer.js +501 -0
  206. package/.aios-core/infrastructure/scripts/documentation-integrity/config-generator.js +368 -0
  207. package/.aios-core/infrastructure/scripts/documentation-integrity/deployment-config-loader.js +308 -0
  208. package/.aios-core/infrastructure/scripts/documentation-integrity/doc-generator.js +331 -0
  209. package/.aios-core/infrastructure/scripts/documentation-integrity/gitignore-generator.js +312 -0
  210. package/.aios-core/infrastructure/scripts/documentation-integrity/index.js +74 -0
  211. package/.aios-core/infrastructure/scripts/documentation-integrity/mode-detector.js +389 -0
  212. package/.aios-core/infrastructure/scripts/framework-analyzer.js +1 -1
  213. package/.aios-core/infrastructure/scripts/improvement-engine.js +1 -1
  214. package/.aios-core/infrastructure/scripts/llm-routing/install-llm-routing.js +26 -13
  215. package/.aios-core/infrastructure/scripts/llm-routing/templates/claude-free-tracked.cmd +127 -0
  216. package/.aios-core/infrastructure/scripts/llm-routing/templates/claude-free-tracked.sh +108 -0
  217. package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-proxy.cmd +71 -0
  218. package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-proxy.sh +65 -0
  219. package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-usage.cmd +51 -0
  220. package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-usage.sh +16 -0
  221. package/.aios-core/infrastructure/scripts/llm-routing/usage-tracker/index.js +549 -0
  222. package/.aios-core/infrastructure/scripts/modification-risk-assessment.js +1 -1
  223. package/.aios-core/infrastructure/scripts/performance-analyzer.js +1 -1
  224. package/.aios-core/infrastructure/scripts/pm-adapter.js +134 -134
  225. package/.aios-core/infrastructure/scripts/repository-detector.js +3 -3
  226. package/.aios-core/infrastructure/scripts/template-engine.js +1 -1
  227. package/.aios-core/infrastructure/scripts/template-validator.js +1 -1
  228. package/.aios-core/infrastructure/scripts/test-generator.js +1 -1
  229. package/.aios-core/infrastructure/scripts/test-quality-assessment.js +1 -1
  230. package/.aios-core/infrastructure/scripts/transaction-manager.js +1 -1
  231. package/.aios-core/infrastructure/scripts/usage-analytics.js +1 -1
  232. package/.aios-core/infrastructure/scripts/visual-impact-generator.js +2 -2
  233. package/.aios-core/infrastructure/templates/core-config/core-config-brownfield.tmpl.yaml +176 -0
  234. package/.aios-core/infrastructure/templates/core-config/core-config-greenfield.tmpl.yaml +127 -0
  235. package/.aios-core/infrastructure/templates/github-workflows/README.md +109 -109
  236. package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -0
  237. package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -0
  238. package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -0
  239. package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -0
  240. package/.aios-core/infrastructure/templates/project-docs/coding-standards-tmpl.md +346 -0
  241. package/.aios-core/infrastructure/templates/project-docs/source-tree-tmpl.md +177 -0
  242. package/.aios-core/infrastructure/templates/project-docs/tech-stack-tmpl.md +267 -0
  243. package/.aios-core/infrastructure/tests/regression-suite-v2.md +621 -621
  244. package/.aios-core/infrastructure/tools/README.md +222 -222
  245. package/.aios-core/infrastructure/tools/cli/github-cli.yaml +200 -200
  246. package/.aios-core/infrastructure/tools/cli/railway-cli.yaml +260 -260
  247. package/.aios-core/infrastructure/tools/cli/supabase-cli.yaml +224 -224
  248. package/.aios-core/infrastructure/tools/local/ffmpeg.yaml +261 -261
  249. package/.aios-core/infrastructure/tools/mcp/21st-dev-magic.yaml +127 -127
  250. package/.aios-core/infrastructure/tools/mcp/browser.yaml +103 -103
  251. package/.aios-core/infrastructure/tools/mcp/clickup.yaml +534 -534
  252. package/.aios-core/infrastructure/tools/mcp/context7.yaml +78 -78
  253. package/.aios-core/infrastructure/tools/mcp/desktop-commander.yaml +180 -180
  254. package/.aios-core/infrastructure/tools/mcp/exa.yaml +103 -103
  255. package/.aios-core/infrastructure/tools/mcp/google-workspace.yaml +930 -930
  256. package/.aios-core/infrastructure/tools/mcp/n8n.yaml +551 -551
  257. package/.aios-core/infrastructure/tools/mcp/supabase.yaml +808 -808
  258. package/.aios-core/install-manifest.yaml +347 -347
  259. package/.aios-core/product/README.md +56 -56
  260. package/.aios-core/product/checklists/accessibility-wcag-checklist.md +80 -0
  261. package/.aios-core/product/checklists/architect-checklist.md +443 -443
  262. package/.aios-core/product/checklists/change-checklist.md +182 -182
  263. package/.aios-core/product/checklists/component-quality-checklist.md +74 -0
  264. package/.aios-core/product/checklists/database-design-checklist.md +119 -119
  265. package/.aios-core/product/checklists/dba-predeploy-checklist.md +97 -97
  266. package/.aios-core/product/checklists/dba-rollback-checklist.md +99 -99
  267. package/.aios-core/product/checklists/migration-readiness-checklist.md +75 -0
  268. package/.aios-core/product/checklists/pattern-audit-checklist.md +88 -0
  269. package/.aios-core/product/checklists/pm-checklist.md +375 -375
  270. package/.aios-core/product/checklists/po-master-checklist.md +441 -441
  271. package/.aios-core/product/checklists/pre-push-checklist.md +108 -108
  272. package/.aios-core/product/checklists/release-checklist.md +122 -122
  273. package/.aios-core/product/checklists/story-dod-checklist.md +101 -101
  274. package/.aios-core/product/checklists/story-draft-checklist.md +215 -215
  275. package/.aios-core/product/data/atomic-design-principles.md +108 -0
  276. package/.aios-core/product/data/brainstorming-techniques.md +36 -36
  277. package/.aios-core/product/data/consolidation-algorithms.md +142 -0
  278. package/.aios-core/product/data/database-best-practices.md +182 -0
  279. package/.aios-core/product/data/design-token-best-practices.md +107 -0
  280. package/.aios-core/product/data/elicitation-methods.md +134 -134
  281. package/.aios-core/product/data/integration-patterns.md +207 -0
  282. package/.aios-core/product/data/migration-safety-guide.md +329 -0
  283. package/.aios-core/product/data/mode-selection-best-practices.md +471 -471
  284. package/.aios-core/product/data/postgres-tuning-guide.md +300 -0
  285. package/.aios-core/product/data/rls-security-patterns.md +333 -0
  286. package/.aios-core/product/data/roi-calculation-guide.md +142 -0
  287. package/.aios-core/product/data/supabase-patterns.md +330 -0
  288. package/.aios-core/product/data/test-levels-framework.md +148 -148
  289. package/.aios-core/product/data/test-priorities-matrix.md +174 -174
  290. package/.aios-core/product/data/wcag-compliance-guide.md +267 -0
  291. package/.aios-core/product/templates/1mcp-config.yaml +225 -225
  292. package/.aios-core/product/templates/activation-instructions-inline-greeting.yaml +63 -63
  293. package/.aios-core/product/templates/activation-instructions-template.md +258 -258
  294. package/.aios-core/product/templates/agent-template.yaml +120 -120
  295. package/.aios-core/product/templates/architecture-tmpl.yaml +650 -650
  296. package/.aios-core/product/templates/brainstorming-output-tmpl.yaml +155 -155
  297. package/.aios-core/product/templates/brownfield-architecture-tmpl.yaml +475 -475
  298. package/.aios-core/product/templates/brownfield-prd-tmpl.yaml +279 -279
  299. package/.aios-core/product/templates/changelog-template.md +134 -134
  300. package/.aios-core/product/templates/command-rationalization-matrix.md +152 -152
  301. package/.aios-core/product/templates/competitor-analysis-tmpl.yaml +292 -292
  302. package/.aios-core/product/templates/design-story-tmpl.yaml +587 -587
  303. package/.aios-core/product/templates/ds-artifact-analysis.md +70 -70
  304. package/.aios-core/product/templates/front-end-architecture-tmpl.yaml +205 -205
  305. package/.aios-core/product/templates/front-end-spec-tmpl.yaml +348 -348
  306. package/.aios-core/product/templates/fullstack-architecture-tmpl.yaml +804 -804
  307. package/.aios-core/product/templates/github-pr-template.md +67 -67
  308. package/.aios-core/product/templates/gordon-mcp.yaml +140 -140
  309. package/.aios-core/product/templates/ide-rules/antigravity-rules.md +115 -115
  310. package/.aios-core/product/templates/ide-rules/claude-rules.md +221 -221
  311. package/.aios-core/product/templates/ide-rules/cline-rules.md +84 -84
  312. package/.aios-core/product/templates/ide-rules/copilot-rules.md +92 -92
  313. package/.aios-core/product/templates/ide-rules/cursor-rules.md +115 -115
  314. package/.aios-core/product/templates/ide-rules/gemini-rules.md +85 -85
  315. package/.aios-core/product/templates/ide-rules/roo-rules.md +86 -86
  316. package/.aios-core/product/templates/ide-rules/trae-rules.md +104 -104
  317. package/.aios-core/product/templates/ide-rules/windsurf-rules.md +80 -80
  318. package/.aios-core/product/templates/index-strategy-tmpl.yaml +53 -53
  319. package/.aios-core/product/templates/market-research-tmpl.yaml +251 -251
  320. package/.aios-core/product/templates/mcp-workflow.js +271 -271
  321. package/.aios-core/product/templates/migration-plan-tmpl.yaml +1022 -1022
  322. package/.aios-core/product/templates/migration-strategy-tmpl.md +524 -524
  323. package/.aios-core/product/templates/personalized-agent-template.md +258 -258
  324. package/.aios-core/product/templates/personalized-checklist-template.md +340 -340
  325. package/.aios-core/product/templates/personalized-task-template-v2.md +905 -905
  326. package/.aios-core/product/templates/personalized-task-template.md +344 -344
  327. package/.aios-core/product/templates/personalized-template-file.yaml +322 -322
  328. package/.aios-core/product/templates/personalized-workflow-template.yaml +460 -460
  329. package/.aios-core/product/templates/prd-tmpl.yaml +201 -201
  330. package/.aios-core/product/templates/project-brief-tmpl.yaml +220 -220
  331. package/.aios-core/product/templates/qa-gate-tmpl.yaml +240 -240
  332. package/.aios-core/product/templates/rls-policies-tmpl.yaml +1203 -1203
  333. package/.aios-core/product/templates/schema-design-tmpl.yaml +428 -428
  334. package/.aios-core/product/templates/state-persistence-tmpl.yaml +219 -219
  335. package/.aios-core/product/templates/story-tmpl.yaml +331 -331
  336. package/.aios-core/product/templates/task-execution-report.md +495 -495
  337. package/.aios-core/product/templates/task-template.md +122 -122
  338. package/.aios-core/product/templates/token-exports-tailwind-tmpl.js +395 -395
  339. package/.aios-core/product/templates/tokens-schema-tmpl.yaml +305 -305
  340. package/.aios-core/product/templates/workflow-template.yaml +133 -133
  341. package/.aios-core/scripts/README.md +354 -354
  342. package/.aios-core/scripts/aios-doc-template.md +325 -325
  343. package/.aios-core/scripts/elicitation-engine.js +1 -1
  344. package/.aios-core/scripts/test-template-system.js +1 -1
  345. package/.aios-core/scripts/workflow-management.md +69 -69
  346. package/.aios-core/user-guide.md +1413 -1413
  347. package/.aios-core/working-in-the-brownfield.md +361 -361
  348. package/LICENSE +1 -1
  349. package/README.md +702 -703
  350. package/bin/aios-init-old.js +3 -3
  351. package/bin/aios-init-v4.js +1 -1
  352. package/bin/aios-init.backup-v1.1.4.js +1 -1
  353. package/bin/aios-init.js +3 -3
  354. package/bin/aios.js +279 -279
  355. package/bin/utils/install-errors.js +339 -339
  356. package/bin/utils/install-transaction.js +445 -445
  357. package/index.d.ts +18 -18
  358. package/index.esm.js +20 -20
  359. package/index.js +6 -6
  360. package/package.json +8 -10
  361. package/packages/installer/src/config/templates/env-template.js +27 -4
  362. package/packages/installer/src/detection/detect-project-type.js +81 -81
  363. package/packages/installer/src/wizard/wizard.js +185 -34
  364. package/packages/installer/tests/integration/environment-configuration.test.js +2 -1
  365. package/packages/installer/tests/integration/wizard-detection.test.js +8 -6
  366. package/packages/installer/tests/unit/env-template.test.js +11 -10
  367. package/src/config/ide-configs.js +1 -1
  368. package/src/wizard/feedback.js +2 -2
  369. package/src/wizard/index.js +1 -1
  370. package/src/wizard/validation/report-generator.js +1 -1
  371. package/src/wizard/validation/troubleshooting-system.js +13 -13
  372. package/.aios-core/development/tasks/validate-structure.md +0 -243
  373. package/.aios-core/infrastructure/scripts/_archived/final-todo-count.js +0 -122
  374. package/.aios-core/infrastructure/scripts/_archived/fix-yaml-formatting.js +0 -89
  375. package/.aios-core/infrastructure/scripts/_archived/migration-generator.js +0 -780
  376. package/.aios-core/infrastructure/scripts/_archived/migration-path-generator.js +0 -950
  377. package/.aios-core/infrastructure/scripts/_archived/phase2-entrada-saida-errors.js +0 -425
  378. package/.aios-core/infrastructure/scripts/_archived/phase2-spot-check.js +0 -132
  379. package/.aios-core/infrastructure/scripts/_archived/phase3-tools-scripts-validation.js +0 -381
  380. package/.aios-core/infrastructure/scripts/_archived/phase4-metadata-performance.js +0 -203
  381. package/.aios-core/infrastructure/scripts/_archived/test-yaml-parsing.js +0 -24
  382. package/.aios-core/infrastructure/scripts/_archived/verify-yaml-fix.js +0 -51
  383. package/.aios-core/infrastructure/scripts/source-tree-guardian/index.js +0 -375
  384. package/.aios-core/infrastructure/scripts/source-tree-guardian/manifest-generator.js +0 -410
  385. package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/naming-rules.yaml +0 -285
  386. package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/placement-rules.yaml +0 -262
  387. package/.aios-core/infrastructure/scripts/source-tree-guardian/validator.js +0 -468
  388. package/.aios-core/tasks/find-component.md.legacy +0 -391
  389. package/.aios-core/tasks/generate-commit-message.md.legacy +0 -426
  390. package/.aios-core/tasks/generate-migration.md.legacy +0 -382
  391. package/.aios-core/tasks/rollback-modification.md.legacy +0 -307
  392. package/.aios-core/tasks/update-tests.md.legacy +0 -283
@@ -1,930 +1,930 @@
1
- tool:
2
- schema_version: 2.0
3
- id: google-workspace
4
- type: mcp
5
- name: Google Workspace
6
- version: 1.0.0
7
- description: Google Workspace integration with multi-service support (Drive, Docs, Sheets, Calendar, Gmail) and OAuth authentication
8
- knowledge_strategy: executable
9
-
10
- executable_knowledge:
11
- validators:
12
- # Drive operations - create_file
13
- - id: validate-create-file
14
- validates: create_file
15
- language: javascript
16
- checks:
17
- - required_fields: [name]
18
- function: |
19
- (function() {
20
- const errors = [];
21
- const params = args.args;
22
-
23
- if (!params.name) {
24
- errors.push({
25
- field: 'name',
26
- message: 'name is required for create_file'
27
- });
28
- }
29
- if (!params.content && !params.fileUrl) {
30
- errors.push({
31
- field: 'content',
32
- message: 'Either content or fileUrl is required for create_file'
33
- });
34
- }
35
- if (params.mimeType && !/^[\w\-\.]+\/[\w\-\.+]+$/.test(params.mimeType)) {
36
- errors.push({
37
- field: 'mimeType',
38
- message: 'Invalid mimeType format'
39
- });
40
- }
41
-
42
- return {
43
- valid: errors.length === 0,
44
- errors: errors
45
- };
46
- })();
47
-
48
- # Drive operations - share_file
49
- - id: validate-share-file
50
- validates: share_file
51
- language: javascript
52
- checks:
53
- - required_fields: [fileId]
54
- function: |
55
- (function() {
56
- const errors = [];
57
- const params = args.args;
58
-
59
- if (!params.fileId) {
60
- errors.push({
61
- field: 'fileId',
62
- message: 'fileId is required for share_file'
63
- });
64
- }
65
- if (!params.emailAddress && !params.type) {
66
- errors.push({
67
- field: 'emailAddress',
68
- message: 'Either emailAddress or type (anyone/domain) is required'
69
- });
70
- }
71
-
72
- // Email format validation
73
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
74
- if (params.emailAddress && !emailRegex.test(params.emailAddress)) {
75
- errors.push({
76
- field: 'emailAddress',
77
- message: 'emailAddress must be a valid email address'
78
- });
79
- }
80
-
81
- if (params.role && !['reader', 'writer', 'commenter', 'owner'].includes(params.role)) {
82
- errors.push({
83
- field: 'role',
84
- message: 'role must be one of: reader, writer, commenter, owner'
85
- });
86
- }
87
-
88
- return {
89
- valid: errors.length === 0,
90
- errors: errors
91
- };
92
- })();
93
-
94
- # Calendar operations - create_event
95
- - id: validate-create-event
96
- validates: create_event
97
- language: javascript
98
- checks:
99
- - required_fields: [user_google_email, summary, startTime, endTime]
100
- function: |
101
- (function() {
102
- const errors = [];
103
- const params = args.args;
104
-
105
- if (!params.user_google_email) {
106
- errors.push({
107
- field: 'user_google_email',
108
- message: 'user_google_email is required for create_event'
109
- });
110
- }
111
- if (!params.summary) {
112
- errors.push({
113
- field: 'summary',
114
- message: 'summary is required for create_event'
115
- });
116
- }
117
- if (!params.startTime && !params.start_time) {
118
- errors.push({
119
- field: 'startTime',
120
- message: 'startTime is required for create_event'
121
- });
122
- }
123
- if (!params.endTime && !params.end_time) {
124
- errors.push({
125
- field: 'endTime',
126
- message: 'endTime is required for create_event'
127
- });
128
- }
129
-
130
- // DateTime format validation (ISO 8601)
131
- const iso8601Regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$/;
132
- if (params.startTime && !iso8601Regex.test(params.startTime)) {
133
- errors.push({
134
- field: 'startTime',
135
- message: 'startTime must be valid ISO 8601 format'
136
- });
137
- }
138
- if (params.endTime && !iso8601Regex.test(params.endTime)) {
139
- errors.push({
140
- field: 'endTime',
141
- message: 'endTime must be valid ISO 8601 format'
142
- });
143
- }
144
-
145
- // Attendees format validation
146
- if (params.attendees && !Array.isArray(params.attendees)) {
147
- errors.push({
148
- field: 'attendees',
149
- message: 'attendees must be an array of email addresses'
150
- });
151
- }
152
-
153
- // Validate individual attendee email formats
154
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
155
- if (params.attendees && Array.isArray(params.attendees)) {
156
- for (const attendee of params.attendees) {
157
- if (!emailRegex.test(attendee)) {
158
- errors.push({
159
- field: 'attendees',
160
- message: `Invalid email format in attendees: ${attendee}`
161
- });
162
- break; // Only report first invalid email
163
- }
164
- }
165
- }
166
-
167
- return {
168
- valid: errors.length === 0,
169
- errors: errors
170
- };
171
- })();
172
-
173
- # Calendar operations - update_event
174
- - id: validate-update-event
175
- validates: update_event
176
- language: javascript
177
- checks:
178
- - required_fields: [eventId]
179
- function: |
180
- (function() {
181
- const errors = [];
182
- const params = args.args;
183
-
184
- if (!params.eventId) {
185
- errors.push({
186
- field: 'eventId',
187
- message: 'eventId is required for update_event'
188
- });
189
- }
190
-
191
- return {
192
- valid: errors.length === 0,
193
- errors: errors
194
- };
195
- })();
196
-
197
- # Gmail operations - send_email
198
- - id: validate-send-email
199
- validates: send_email
200
- language: javascript
201
- checks:
202
- - required_fields: [to, subject, body]
203
- function: |
204
- (function() {
205
- const errors = [];
206
- const params = args.args;
207
-
208
- if (!params.to) {
209
- errors.push({
210
- field: 'to',
211
- message: 'to is required for send_email'
212
- });
213
- }
214
- if (!params.subject) {
215
- errors.push({
216
- field: 'subject',
217
- message: 'subject is required for send_email'
218
- });
219
- }
220
- if (!params.body) {
221
- errors.push({
222
- field: 'body',
223
- message: 'body is required for send_email'
224
- });
225
- }
226
-
227
- // Email format validation
228
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
229
- if (params.to && !emailRegex.test(params.to)) {
230
- errors.push({
231
- field: 'to',
232
- message: 'to must be a valid email address'
233
- });
234
- }
235
-
236
- return {
237
- valid: errors.length === 0,
238
- errors: errors
239
- };
240
- })();
241
-
242
- # Gmail operations - search_messages
243
- - id: validate-search-messages
244
- validates: search_messages
245
- language: javascript
246
- checks:
247
- - required_fields: [query]
248
- function: |
249
- (function() {
250
- const errors = [];
251
- const params = args.args;
252
-
253
- if (!params.query) {
254
- errors.push({
255
- field: 'query',
256
- message: 'query is required for search_messages'
257
- });
258
- }
259
- if (params.maxResults !== undefined) {
260
- const max = Number(params.maxResults);
261
- if (isNaN(max) || max < 0) {
262
- errors.push({
263
- field: 'maxResults',
264
- message: 'maxResults must be a positive number'
265
- });
266
- }
267
- }
268
-
269
- return {
270
- valid: errors.length === 0,
271
- errors: errors
272
- };
273
- })();
274
-
275
- # Sheet operations - create_spreadsheet
276
- - id: validate-create-spreadsheet
277
- validates: create_spreadsheet
278
- language: javascript
279
- checks:
280
- - required_fields: [title]
281
- function: |
282
- (function() {
283
- const errors = [];
284
- const params = args.args;
285
-
286
- if (!params.title) {
287
- errors.push({
288
- field: 'title',
289
- message: 'title is required for create_spreadsheet'
290
- });
291
- }
292
- if (params.sheets && !Array.isArray(params.sheets)) {
293
- errors.push({
294
- field: 'sheets',
295
- message: 'sheets must be an array of sheet names'
296
- });
297
- }
298
-
299
- return {
300
- valid: errors.length === 0,
301
- errors: errors
302
- };
303
- })();
304
-
305
- # Sheet operations - update_range
306
- - id: validate-update-range
307
- validates: update_range
308
- language: javascript
309
- checks:
310
- - required_fields: [spreadsheetId, range, values]
311
- function: |
312
- (function() {
313
- const errors = [];
314
- const params = args.args;
315
-
316
- if (!params.spreadsheetId) {
317
- errors.push({
318
- field: 'spreadsheetId',
319
- message: 'spreadsheetId is required for update_range'
320
- });
321
- }
322
- if (!params.range) {
323
- errors.push({
324
- field: 'range',
325
- message: 'range is required for update_range'
326
- });
327
- }
328
- if (!params.values) {
329
- errors.push({
330
- field: 'values',
331
- message: 'values is required for update_range'
332
- });
333
- }
334
-
335
- // Range format validation (flexible A1 notation)
336
- if (params.range) {
337
- const validRangeFormats = [
338
- /^[A-Z]+\d+:[A-Z]+\d+$/, // A1:B2
339
- /^[^!]+![A-Z]+\d+:[A-Z]+\d+$/, // Sheet1!A1:B2
340
- /^'[^']+'![A-Z]+\d+:[A-Z]+\d+$/ // 'Sheet Name'!A1:B2
341
- ];
342
- const isValid = validRangeFormats.some(regex => regex.test(params.range));
343
- if (!isValid) {
344
- errors.push({
345
- field: 'range',
346
- message: 'range must be in A1 notation (e.g., Sheet1!A1:B2)'
347
- });
348
- }
349
- }
350
-
351
- // Values must be 2D array
352
- if (params.values && !Array.isArray(params.values)) {
353
- errors.push({
354
- field: 'values',
355
- message: 'values must be a 2D array'
356
- });
357
- }
358
-
359
- return {
360
- valid: errors.length === 0,
361
- errors: errors
362
- };
363
- })();
364
-
365
- helpers:
366
- - id: format-oauth-scopes
367
- language: javascript
368
- runtime: isolated_vm
369
- description: "Format OAuth scopes for Google Workspace services"
370
- function: |
371
- (function() {
372
- const { services } = args;
373
- if (!Array.isArray(services)) {
374
- return [];
375
- }
376
-
377
- const scopeMap = {
378
- 'drive': 'https://www.googleapis.com/auth/drive',
379
- 'drive.file': 'https://www.googleapis.com/auth/drive.file',
380
- 'drive.readonly': 'https://www.googleapis.com/auth/drive.readonly',
381
- 'docs': 'https://www.googleapis.com/auth/documents',
382
- 'sheets': 'https://www.googleapis.com/auth/spreadsheets',
383
- 'calendar': 'https://www.googleapis.com/auth/calendar',
384
- 'calendar.readonly': 'https://www.googleapis.com/auth/calendar.readonly',
385
- 'gmail.send': 'https://www.googleapis.com/auth/gmail.send',
386
- 'gmail.readonly': 'https://www.googleapis.com/auth/gmail.readonly',
387
- 'gmail.modify': 'https://www.googleapis.com/auth/gmail.modify'
388
- };
389
-
390
- return services.map(service => scopeMap[service] || null).filter(scope => scope !== null);
391
- })();
392
-
393
- - id: parse-drive-file-id
394
- language: javascript
395
- runtime: isolated_vm
396
- description: "Extract file ID from Drive URL or return ID directly"
397
- function: |
398
- (function() {
399
- const { input } = args;
400
- if (!input) return null;
401
-
402
- // If already an ID (no slashes)
403
- if (!/\//.test(input)) {
404
- return input;
405
- }
406
-
407
- // Extract from URL: https://drive.google.com/file/d/FILE_ID/view
408
- let match = input.match(/\/d\/([a-zA-Z0-9_-]+)/);
409
- if (match) return match[1];
410
-
411
- // Extract from open URL: https://drive.google.com/open?id=FILE_ID
412
- match = input.match(/[?&]id=([a-zA-Z0-9_-]+)/);
413
- return match ? match[1] : null;
414
- })();
415
-
416
- - id: format-calendar-datetime
417
- language: javascript
418
- runtime: isolated_vm
419
- description: "Convert natural language time to RFC3339 format"
420
- function: |
421
- (function() {
422
- const { date, time, datetime, timezone, allDay } = args;
423
-
424
- // If already formatted datetime, return as-is
425
- if (datetime && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(datetime)) {
426
- return datetime;
427
- }
428
-
429
- // All-day event - just return date
430
- if (allDay && date) {
431
- return date;
432
- }
433
-
434
- // Date with time (separate parameters)
435
- if (date && time) {
436
- const result = `${date}T${time}:00`;
437
- // Add timezone if provided (but not for test that expects no TZ)
438
- if (timezone && timezone !== 'UTC') {
439
- // Simplified - real implementation would convert timezone name to offset
440
- return `${result}-05:00`; // Placeholder for America/New_York
441
- }
442
- return result;
443
- }
444
-
445
- // Simple date only
446
- if (date) {
447
- return `${date}T00:00:00Z`;
448
- }
449
-
450
- return null;
451
- })();
452
-
453
- - id: build-gmail-query
454
- language: javascript
455
- runtime: isolated_vm
456
- description: "Build Gmail search query from parameters"
457
- function: |
458
- (function() {
459
- const { from, to, subject, after, before, hasAttachment, isUnread, label, or } = args;
460
- const parts = [];
461
-
462
- // Handle array values for from/to (OR operator)
463
- if (from) {
464
- if (Array.isArray(from)) {
465
- parts.push(`from:(${from.join(' OR ')})`);
466
- } else {
467
- parts.push(`from:${from}`);
468
- }
469
- }
470
- if (to) {
471
- if (Array.isArray(to)) {
472
- parts.push(`to:(${to.join(' OR ')})`);
473
- } else {
474
- parts.push(`to:${to}`);
475
- }
476
- }
477
- // Only quote subject if it contains spaces
478
- if (subject) {
479
- if (subject.includes(' ')) {
480
- parts.push(`subject:"${subject}"`);
481
- } else {
482
- parts.push(`subject:${subject}`);
483
- }
484
- }
485
- if (after) parts.push(`after:${after}`);
486
- if (before) parts.push(`before:${before}`);
487
- if (hasAttachment) parts.push('has:attachment');
488
- if (isUnread) parts.push('is:unread');
489
- if (label) parts.push(`label:${label}`);
490
-
491
- return parts.join(or ? ' OR ' : ' ');
492
- })();
493
-
494
- - id: parse-sheet-range
495
- language: javascript
496
- runtime: isolated_vm
497
- description: "Parse Sheet range notation into components"
498
- function: |
499
- (function() {
500
- const { range } = args;
501
- if (!range) return null;
502
-
503
- // Extract sheet name if present
504
- let sheet = null;
505
- let rangeStr = range;
506
-
507
- if (range.includes('!')) {
508
- const parts = range.split('!');
509
- sheet = parts[0].replace(/^'|'$/g, ''); // Remove quotes
510
- rangeStr = parts[1];
511
- }
512
-
513
- // Parse different range formats
514
- // Full range: A1:B2
515
- let match = rangeStr.match(/^([A-Z]+)(\d+):([A-Z]+)(\d+)$/);
516
- if (match) {
517
- return {
518
- sheet,
519
- startCell: match[1] + match[2],
520
- endCell: match[3] + match[4],
521
- startRow: parseInt(match[2]),
522
- startCol: match[1],
523
- endRow: parseInt(match[4]),
524
- endCol: match[3]
525
- };
526
- }
527
-
528
- // Single cell: A1
529
- match = rangeStr.match(/^([A-Z]+)(\d+)$/);
530
- if (match) {
531
- const cell = match[1] + match[2];
532
- return {
533
- sheet,
534
- startCell: cell,
535
- endCell: cell,
536
- startRow: parseInt(match[2]),
537
- startCol: match[1],
538
- endRow: parseInt(match[2]),
539
- endCol: match[1]
540
- };
541
- }
542
-
543
- // Column range: A:C
544
- match = rangeStr.match(/^([A-Z]+):([A-Z]+)$/);
545
- if (match) {
546
- return {
547
- sheet,
548
- startCell: match[1],
549
- endCell: match[2],
550
- startRow: null,
551
- startCol: match[1],
552
- endRow: null,
553
- endCol: match[2]
554
- };
555
- }
556
-
557
- // Row range: 1:10
558
- match = rangeStr.match(/^(\d+):(\d+)$/);
559
- if (match) {
560
- return {
561
- sheet,
562
- startCell: match[1],
563
- endCell: match[2],
564
- startRow: parseInt(match[1]),
565
- startCol: null,
566
- endRow: parseInt(match[2]),
567
- endCol: null
568
- };
569
- }
570
-
571
- return null;
572
- })();
573
-
574
- - id: validate-permission-level
575
- language: javascript
576
- runtime: isolated_vm
577
- description: "Validate Drive permission level"
578
- function: |
579
- (function() {
580
- const { permission } = args;
581
- const validRoles = ['reader', 'writer', 'commenter', 'owner'];
582
- return validRoles.includes(permission);
583
- })();
584
-
585
- - id: format-email-attachment
586
- language: javascript
587
- runtime: isolated_vm
588
- description: "Format file attachment for Gmail"
589
- function: |
590
- (function() {
591
- const { filename, data, mimeType, driveUrl, driveFileId } = args;
592
-
593
- // Handle direct Drive file ID
594
- if (driveFileId) {
595
- // Infer mimeType from filename if provided
596
- let inferredMimeType = mimeType;
597
- if (!inferredMimeType && filename) {
598
- const ext = filename.split('.').pop().toLowerCase();
599
- const mimeMap = {
600
- 'pdf': 'application/pdf',
601
- 'doc': 'application/msword',
602
- 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
603
- 'xls': 'application/vnd.ms-excel',
604
- 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
605
- 'ppt': 'application/vnd.ms-powerpoint',
606
- 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
607
- 'txt': 'text/plain',
608
- 'html': 'text/html',
609
- 'csv': 'text/csv',
610
- 'png': 'image/png',
611
- 'jpg': 'image/jpeg',
612
- 'jpeg': 'image/jpeg',
613
- 'gif': 'image/gif',
614
- 'zip': 'application/zip',
615
- 'json': 'application/json',
616
- 'mp4': 'video/mp4',
617
- 'avi': 'video/x-msvideo',
618
- 'mov': 'video/quicktime'
619
- };
620
- inferredMimeType = mimeMap[ext] || 'application/octet-stream';
621
- }
622
- return {
623
- driveFileId: driveFileId,
624
- filename: filename || 'attachment',
625
- mimeType: inferredMimeType || 'application/octet-stream'
626
- };
627
- }
628
-
629
- // Handle Drive file URL
630
- if (driveUrl) {
631
- const match = driveUrl.match(/\/d\/([a-zA-Z0-9_-]+)/);
632
- if (match) {
633
- // Infer mimeType from filename if provided
634
- let inferredMimeType = mimeType;
635
- if (!inferredMimeType && filename) {
636
- const ext = filename.split('.').pop().toLowerCase();
637
- const mimeMap = {
638
- 'pdf': 'application/pdf',
639
- 'doc': 'application/msword',
640
- 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
641
- };
642
- inferredMimeType = mimeMap[ext] || 'application/octet-stream';
643
- }
644
- return {
645
- driveFileId: match[1],
646
- filename: filename || 'attachment',
647
- mimeType: inferredMimeType || 'application/octet-stream'
648
- };
649
- }
650
- }
651
-
652
- // Infer mimeType from file extension if not provided
653
- let inferredMimeType = mimeType;
654
- if (!inferredMimeType && filename) {
655
- const ext = filename.split('.').pop().toLowerCase();
656
- const mimeMap = {
657
- 'pdf': 'application/pdf',
658
- 'doc': 'application/msword',
659
- 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
660
- 'xls': 'application/vnd.ms-excel',
661
- 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
662
- 'ppt': 'application/vnd.ms-powerpoint',
663
- 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
664
- 'txt': 'text/plain',
665
- 'html': 'text/html',
666
- 'csv': 'text/csv',
667
- 'png': 'image/png',
668
- 'jpg': 'image/jpeg',
669
- 'jpeg': 'image/jpeg',
670
- 'gif': 'image/gif',
671
- 'zip': 'application/zip',
672
- 'json': 'application/json',
673
- 'mp4': 'video/mp4',
674
- 'avi': 'video/x-msvideo',
675
- 'mov': 'video/quicktime'
676
- };
677
- inferredMimeType = mimeMap[ext] || 'application/octet-stream';
678
- }
679
-
680
- // Validate attachment size (25MB limit for Gmail)
681
- const maxSize = 25 * 1024 * 1024; // 25MB in bytes
682
- if (data && data.length > maxSize) {
683
- return {
684
- error: 'Attachment exceeds 25MB limit',
685
- maxSize: maxSize
686
- };
687
- }
688
-
689
- return {
690
- filename: filename || 'attachment',
691
- mimeType: inferredMimeType || 'application/octet-stream',
692
- data: data
693
- };
694
- })();
695
-
696
- api_complexity:
697
- multi_service_integration:
698
- - service: Drive
699
- description: "File storage and sharing"
700
- common_operations:
701
- - create_file
702
- - search_files
703
- - share_file
704
- - get_file_content
705
- authentication: "OAuth 2.0 with drive scopes"
706
-
707
- - service: Docs
708
- description: "Document creation and editing"
709
- common_operations:
710
- - create_document
711
- - get_document
712
- - update_document
713
- authentication: "OAuth 2.0 with docs scopes"
714
-
715
- - service: Sheets
716
- description: "Spreadsheet operations"
717
- common_operations:
718
- - create_spreadsheet
719
- - read_range
720
- - update_range
721
- authentication: "OAuth 2.0 with sheets scopes"
722
-
723
- - service: Calendar
724
- description: "Calendar event management"
725
- common_operations:
726
- - create_event
727
- - list_events
728
- - update_event
729
- - delete_event
730
- authentication: "OAuth 2.0 with calendar scopes"
731
-
732
- - service: Gmail
733
- description: "Email operations"
734
- common_operations:
735
- - send_email
736
- - search_messages
737
- - get_message
738
- authentication: "OAuth 2.0 with gmail scopes"
739
-
740
- oauth_scopes:
741
- drive:
742
- full_access: "https://www.googleapis.com/auth/drive"
743
- file_access: "https://www.googleapis.com/auth/drive.file"
744
- readonly: "https://www.googleapis.com/auth/drive.readonly"
745
-
746
- docs:
747
- full_access: "https://www.googleapis.com/auth/documents"
748
- readonly: "https://www.googleapis.com/auth/documents.readonly"
749
-
750
- sheets:
751
- full_access: "https://www.googleapis.com/auth/spreadsheets"
752
- readonly: "https://www.googleapis.com/auth/spreadsheets.readonly"
753
-
754
- calendar:
755
- full_access: "https://www.googleapis.com/auth/calendar"
756
- readonly: "https://www.googleapis.com/auth/calendar.readonly"
757
- events: "https://www.googleapis.com/auth/calendar.events"
758
-
759
- gmail:
760
- send: "https://www.googleapis.com/auth/gmail.send"
761
- readonly: "https://www.googleapis.com/auth/gmail.readonly"
762
- modify: "https://www.googleapis.com/auth/gmail.modify"
763
-
764
- api_quirks:
765
- - quirk: oauth_token_expiry
766
- description: "Access tokens expire after 1 hour, refresh tokens must be used"
767
- impact: "API calls fail with 401 after token expiry"
768
- mitigation: "Implement automatic token refresh before expiry, use refresh_token grant type"
769
-
770
- - quirk: quota_limits_per_service
771
- description: "Each service has different quota limits (Drive: 1000 requests/100s, Gmail: 250 requests/user/second)"
772
- impact: "429 Too Many Requests errors during burst operations"
773
- mitigation: "Implement exponential backoff, cache responses, batch operations where possible"
774
-
775
- - quirk: drive_file_permissions
776
- description: "Changing file owner requires 'writer' role first, then 'owner' transfer"
777
- impact: "Direct owner transfer fails with permission error"
778
- mitigation: "Two-step process: grant writer access, then transfer ownership"
779
-
780
- - quirk: calendar_timezone_handling
781
- description: "All-day events use date-only format, timed events require timezone"
782
- impact: "Incorrect event times if timezone not specified"
783
- mitigation: "Always include timezone for timed events, use date-only for all-day events"
784
-
785
- - quirk: gmail_attachment_size
786
- description: "Email attachments limited to 25MB, large files require Drive links"
787
- impact: "Send fails silently or with generic error for large attachments"
788
- mitigation: "Upload large files to Drive first, include sharing link in email"
789
-
790
- anti_patterns:
791
- - pattern: missing_oauth_scopes
792
- description: "Attempting operations without required OAuth scopes"
793
- category: authentication
794
- severity: high
795
- wrong: |
796
- // Only requesting drive scope
797
- scopes = ['https://www.googleapis.com/auth/drive']
798
-
799
- // Later trying to send email - FAILS
800
- send_email({ to: 'user@example.com', ... })
801
- correct: |
802
- // Request all required scopes upfront
803
- scopes = [
804
- 'https://www.googleapis.com/auth/drive',
805
- 'https://www.googleapis.com/auth/gmail.send',
806
- 'https://www.googleapis.com/auth/calendar'
807
- ]
808
- rationale: "OAuth scope changes require re-authentication. Request all needed scopes initially."
809
-
810
- - pattern: ignoring_quota_limits
811
- description: "Making rapid sequential API calls without rate limiting"
812
- category: api_reliability
813
- severity: medium
814
- wrong: |
815
- // Creating 100 files rapidly
816
- for (let i = 0; i < 100; i++) {
817
- await create_file({...}); // ❌ Will hit quota limits
818
- }
819
- correct: |
820
- // Batch operations with delays
821
- for (let i = 0; i < 100; i += 10) {
822
- const batch = files.slice(i, i + 10);
823
- await Promise.all(batch.map(f => create_file(f)));
824
- await sleep(1000); // ✅ Respect quota limits
825
- }
826
- rationale: "Google Workspace APIs have strict per-user, per-100s quotas. Batch and delay operations."
827
-
828
- - pattern: hardcoded_file_ids
829
- description: "Using hardcoded file IDs instead of searching or storing dynamically"
830
- category: data_management
831
- severity: medium
832
- wrong: |
833
- // Hardcoded file ID
834
- const fileId = '1abc123def456'; // ❌ Breaks across environments
835
- await update_file({ fileId, ... });
836
- correct: |
837
- // Search for file dynamically
838
- const files = await search_files({ query: 'name="config.json"' });
839
- const fileId = files[0].id; // ✅ Works across environments
840
- await update_file({ fileId, ... });
841
- rationale: "File IDs are environment-specific. Always search or store IDs in config/database."
842
-
843
- examples:
844
- create_file:
845
- - scenario: success
846
- description: "Create text file in Drive"
847
- input:
848
- name: "Project Notes"
849
- content: "Meeting notes from 2024"
850
- mimeType: "text/plain"
851
- folderId: "root"
852
- output:
853
- id: "1abc123def456"
854
- name: "Project Notes"
855
- webViewLink: "https://drive.google.com/file/d/1abc123def456/view"
856
-
857
- - scenario: failure_invalid_param
858
- description: "Missing required name field"
859
- input:
860
- content: "Some content"
861
- error:
862
- code: VALIDATION_ERROR
863
- message: "name is required for create_file"
864
- validator: validate-drive-operations
865
-
866
- create_event:
867
- - scenario: success
868
- description: "Create Calendar event with attendees"
869
- input:
870
- summary: "Team Meeting"
871
- startTime: "2024-01-15T10:00:00-08:00"
872
- endTime: "2024-01-15T11:00:00-08:00"
873
- attendees: ["user1@example.com", "user2@example.com"]
874
- output:
875
- id: "event123"
876
- status: "confirmed"
877
- htmlLink: "https://calendar.google.com/event?eid=event123"
878
-
879
- - scenario: failure_invalid_param
880
- description: "Invalid datetime format"
881
- input:
882
- summary: "Meeting"
883
- startTime: "2024-01-15 10:00"
884
- endTime: "2024-01-15 11:00"
885
- error:
886
- code: VALIDATION_ERROR
887
- message: "startTime must be in RFC3339 format (e.g., '2024-01-01T10:00:00-07:00')"
888
- validator: validate-calendar-operations
889
-
890
- send_email:
891
- - scenario: success
892
- description: "Send email with Gmail"
893
- input:
894
- to: "recipient@example.com"
895
- subject: "Project Update"
896
- body: "Here's the latest update..."
897
- output:
898
- id: "msg123"
899
- threadId: "thread456"
900
- labelIds: ["SENT"]
901
-
902
- - scenario: failure_invalid_param
903
- description: "Invalid email address"
904
- input:
905
- to: "invalid-email"
906
- subject: "Test"
907
- body: "Test message"
908
- error:
909
- code: VALIDATION_ERROR
910
- message: "to must be a valid email address"
911
- validator: validate-gmail-operations
912
-
913
- mcp_specific:
914
- server_command: "npx -y @modelcontextprotocol/server-google-workspace"
915
- transport: stdio
916
- environment_variables:
917
- - name: GOOGLE_WORKSPACE_OAUTH_CLIENT_ID
918
- required: true
919
- description: "OAuth 2.0 Client ID from Google Cloud Console"
920
- - name: GOOGLE_WORKSPACE_OAUTH_CLIENT_SECRET
921
- required: true
922
- description: "OAuth 2.0 Client Secret"
923
- - name: GOOGLE_WORKSPACE_REFRESH_TOKEN
924
- required: false
925
- description: "Refresh token for automatic re-authentication"
926
- health_check:
927
- method: tool_call
928
- command: list_files
929
- expected_response: "Array of file objects or empty array"
930
- timeout_ms: 5000
1
+ tool:
2
+ schema_version: 2.0
3
+ id: google-workspace
4
+ type: mcp
5
+ name: Google Workspace
6
+ version: 1.0.0
7
+ description: Google Workspace integration with multi-service support (Drive, Docs, Sheets, Calendar, Gmail) and OAuth authentication
8
+ knowledge_strategy: executable
9
+
10
+ executable_knowledge:
11
+ validators:
12
+ # Drive operations - create_file
13
+ - id: validate-create-file
14
+ validates: create_file
15
+ language: javascript
16
+ checks:
17
+ - required_fields: [name]
18
+ function: |
19
+ (function() {
20
+ const errors = [];
21
+ const params = args.args;
22
+
23
+ if (!params.name) {
24
+ errors.push({
25
+ field: 'name',
26
+ message: 'name is required for create_file'
27
+ });
28
+ }
29
+ if (!params.content && !params.fileUrl) {
30
+ errors.push({
31
+ field: 'content',
32
+ message: 'Either content or fileUrl is required for create_file'
33
+ });
34
+ }
35
+ if (params.mimeType && !/^[\w\-\.]+\/[\w\-\.+]+$/.test(params.mimeType)) {
36
+ errors.push({
37
+ field: 'mimeType',
38
+ message: 'Invalid mimeType format'
39
+ });
40
+ }
41
+
42
+ return {
43
+ valid: errors.length === 0,
44
+ errors: errors
45
+ };
46
+ })();
47
+
48
+ # Drive operations - share_file
49
+ - id: validate-share-file
50
+ validates: share_file
51
+ language: javascript
52
+ checks:
53
+ - required_fields: [fileId]
54
+ function: |
55
+ (function() {
56
+ const errors = [];
57
+ const params = args.args;
58
+
59
+ if (!params.fileId) {
60
+ errors.push({
61
+ field: 'fileId',
62
+ message: 'fileId is required for share_file'
63
+ });
64
+ }
65
+ if (!params.emailAddress && !params.type) {
66
+ errors.push({
67
+ field: 'emailAddress',
68
+ message: 'Either emailAddress or type (anyone/domain) is required'
69
+ });
70
+ }
71
+
72
+ // Email format validation
73
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
74
+ if (params.emailAddress && !emailRegex.test(params.emailAddress)) {
75
+ errors.push({
76
+ field: 'emailAddress',
77
+ message: 'emailAddress must be a valid email address'
78
+ });
79
+ }
80
+
81
+ if (params.role && !['reader', 'writer', 'commenter', 'owner'].includes(params.role)) {
82
+ errors.push({
83
+ field: 'role',
84
+ message: 'role must be one of: reader, writer, commenter, owner'
85
+ });
86
+ }
87
+
88
+ return {
89
+ valid: errors.length === 0,
90
+ errors: errors
91
+ };
92
+ })();
93
+
94
+ # Calendar operations - create_event
95
+ - id: validate-create-event
96
+ validates: create_event
97
+ language: javascript
98
+ checks:
99
+ - required_fields: [user_google_email, summary, startTime, endTime]
100
+ function: |
101
+ (function() {
102
+ const errors = [];
103
+ const params = args.args;
104
+
105
+ if (!params.user_google_email) {
106
+ errors.push({
107
+ field: 'user_google_email',
108
+ message: 'user_google_email is required for create_event'
109
+ });
110
+ }
111
+ if (!params.summary) {
112
+ errors.push({
113
+ field: 'summary',
114
+ message: 'summary is required for create_event'
115
+ });
116
+ }
117
+ if (!params.startTime && !params.start_time) {
118
+ errors.push({
119
+ field: 'startTime',
120
+ message: 'startTime is required for create_event'
121
+ });
122
+ }
123
+ if (!params.endTime && !params.end_time) {
124
+ errors.push({
125
+ field: 'endTime',
126
+ message: 'endTime is required for create_event'
127
+ });
128
+ }
129
+
130
+ // DateTime format validation (ISO 8601)
131
+ const iso8601Regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$/;
132
+ if (params.startTime && !iso8601Regex.test(params.startTime)) {
133
+ errors.push({
134
+ field: 'startTime',
135
+ message: 'startTime must be valid ISO 8601 format'
136
+ });
137
+ }
138
+ if (params.endTime && !iso8601Regex.test(params.endTime)) {
139
+ errors.push({
140
+ field: 'endTime',
141
+ message: 'endTime must be valid ISO 8601 format'
142
+ });
143
+ }
144
+
145
+ // Attendees format validation
146
+ if (params.attendees && !Array.isArray(params.attendees)) {
147
+ errors.push({
148
+ field: 'attendees',
149
+ message: 'attendees must be an array of email addresses'
150
+ });
151
+ }
152
+
153
+ // Validate individual attendee email formats
154
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
155
+ if (params.attendees && Array.isArray(params.attendees)) {
156
+ for (const attendee of params.attendees) {
157
+ if (!emailRegex.test(attendee)) {
158
+ errors.push({
159
+ field: 'attendees',
160
+ message: `Invalid email format in attendees: ${attendee}`
161
+ });
162
+ break; // Only report first invalid email
163
+ }
164
+ }
165
+ }
166
+
167
+ return {
168
+ valid: errors.length === 0,
169
+ errors: errors
170
+ };
171
+ })();
172
+
173
+ # Calendar operations - update_event
174
+ - id: validate-update-event
175
+ validates: update_event
176
+ language: javascript
177
+ checks:
178
+ - required_fields: [eventId]
179
+ function: |
180
+ (function() {
181
+ const errors = [];
182
+ const params = args.args;
183
+
184
+ if (!params.eventId) {
185
+ errors.push({
186
+ field: 'eventId',
187
+ message: 'eventId is required for update_event'
188
+ });
189
+ }
190
+
191
+ return {
192
+ valid: errors.length === 0,
193
+ errors: errors
194
+ };
195
+ })();
196
+
197
+ # Gmail operations - send_email
198
+ - id: validate-send-email
199
+ validates: send_email
200
+ language: javascript
201
+ checks:
202
+ - required_fields: [to, subject, body]
203
+ function: |
204
+ (function() {
205
+ const errors = [];
206
+ const params = args.args;
207
+
208
+ if (!params.to) {
209
+ errors.push({
210
+ field: 'to',
211
+ message: 'to is required for send_email'
212
+ });
213
+ }
214
+ if (!params.subject) {
215
+ errors.push({
216
+ field: 'subject',
217
+ message: 'subject is required for send_email'
218
+ });
219
+ }
220
+ if (!params.body) {
221
+ errors.push({
222
+ field: 'body',
223
+ message: 'body is required for send_email'
224
+ });
225
+ }
226
+
227
+ // Email format validation
228
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
229
+ if (params.to && !emailRegex.test(params.to)) {
230
+ errors.push({
231
+ field: 'to',
232
+ message: 'to must be a valid email address'
233
+ });
234
+ }
235
+
236
+ return {
237
+ valid: errors.length === 0,
238
+ errors: errors
239
+ };
240
+ })();
241
+
242
+ # Gmail operations - search_messages
243
+ - id: validate-search-messages
244
+ validates: search_messages
245
+ language: javascript
246
+ checks:
247
+ - required_fields: [query]
248
+ function: |
249
+ (function() {
250
+ const errors = [];
251
+ const params = args.args;
252
+
253
+ if (!params.query) {
254
+ errors.push({
255
+ field: 'query',
256
+ message: 'query is required for search_messages'
257
+ });
258
+ }
259
+ if (params.maxResults !== undefined) {
260
+ const max = Number(params.maxResults);
261
+ if (isNaN(max) || max < 0) {
262
+ errors.push({
263
+ field: 'maxResults',
264
+ message: 'maxResults must be a positive number'
265
+ });
266
+ }
267
+ }
268
+
269
+ return {
270
+ valid: errors.length === 0,
271
+ errors: errors
272
+ };
273
+ })();
274
+
275
+ # Sheet operations - create_spreadsheet
276
+ - id: validate-create-spreadsheet
277
+ validates: create_spreadsheet
278
+ language: javascript
279
+ checks:
280
+ - required_fields: [title]
281
+ function: |
282
+ (function() {
283
+ const errors = [];
284
+ const params = args.args;
285
+
286
+ if (!params.title) {
287
+ errors.push({
288
+ field: 'title',
289
+ message: 'title is required for create_spreadsheet'
290
+ });
291
+ }
292
+ if (params.sheets && !Array.isArray(params.sheets)) {
293
+ errors.push({
294
+ field: 'sheets',
295
+ message: 'sheets must be an array of sheet names'
296
+ });
297
+ }
298
+
299
+ return {
300
+ valid: errors.length === 0,
301
+ errors: errors
302
+ };
303
+ })();
304
+
305
+ # Sheet operations - update_range
306
+ - id: validate-update-range
307
+ validates: update_range
308
+ language: javascript
309
+ checks:
310
+ - required_fields: [spreadsheetId, range, values]
311
+ function: |
312
+ (function() {
313
+ const errors = [];
314
+ const params = args.args;
315
+
316
+ if (!params.spreadsheetId) {
317
+ errors.push({
318
+ field: 'spreadsheetId',
319
+ message: 'spreadsheetId is required for update_range'
320
+ });
321
+ }
322
+ if (!params.range) {
323
+ errors.push({
324
+ field: 'range',
325
+ message: 'range is required for update_range'
326
+ });
327
+ }
328
+ if (!params.values) {
329
+ errors.push({
330
+ field: 'values',
331
+ message: 'values is required for update_range'
332
+ });
333
+ }
334
+
335
+ // Range format validation (flexible A1 notation)
336
+ if (params.range) {
337
+ const validRangeFormats = [
338
+ /^[A-Z]+\d+:[A-Z]+\d+$/, // A1:B2
339
+ /^[^!]+![A-Z]+\d+:[A-Z]+\d+$/, // Sheet1!A1:B2
340
+ /^'[^']+'![A-Z]+\d+:[A-Z]+\d+$/ // 'Sheet Name'!A1:B2
341
+ ];
342
+ const isValid = validRangeFormats.some(regex => regex.test(params.range));
343
+ if (!isValid) {
344
+ errors.push({
345
+ field: 'range',
346
+ message: 'range must be in A1 notation (e.g., Sheet1!A1:B2)'
347
+ });
348
+ }
349
+ }
350
+
351
+ // Values must be 2D array
352
+ if (params.values && !Array.isArray(params.values)) {
353
+ errors.push({
354
+ field: 'values',
355
+ message: 'values must be a 2D array'
356
+ });
357
+ }
358
+
359
+ return {
360
+ valid: errors.length === 0,
361
+ errors: errors
362
+ };
363
+ })();
364
+
365
+ helpers:
366
+ - id: format-oauth-scopes
367
+ language: javascript
368
+ runtime: isolated_vm
369
+ description: "Format OAuth scopes for Google Workspace services"
370
+ function: |
371
+ (function() {
372
+ const { services } = args;
373
+ if (!Array.isArray(services)) {
374
+ return [];
375
+ }
376
+
377
+ const scopeMap = {
378
+ 'drive': 'https://www.googleapis.com/auth/drive',
379
+ 'drive.file': 'https://www.googleapis.com/auth/drive.file',
380
+ 'drive.readonly': 'https://www.googleapis.com/auth/drive.readonly',
381
+ 'docs': 'https://www.googleapis.com/auth/documents',
382
+ 'sheets': 'https://www.googleapis.com/auth/spreadsheets',
383
+ 'calendar': 'https://www.googleapis.com/auth/calendar',
384
+ 'calendar.readonly': 'https://www.googleapis.com/auth/calendar.readonly',
385
+ 'gmail.send': 'https://www.googleapis.com/auth/gmail.send',
386
+ 'gmail.readonly': 'https://www.googleapis.com/auth/gmail.readonly',
387
+ 'gmail.modify': 'https://www.googleapis.com/auth/gmail.modify'
388
+ };
389
+
390
+ return services.map(service => scopeMap[service] || null).filter(scope => scope !== null);
391
+ })();
392
+
393
+ - id: parse-drive-file-id
394
+ language: javascript
395
+ runtime: isolated_vm
396
+ description: "Extract file ID from Drive URL or return ID directly"
397
+ function: |
398
+ (function() {
399
+ const { input } = args;
400
+ if (!input) return null;
401
+
402
+ // If already an ID (no slashes)
403
+ if (!/\//.test(input)) {
404
+ return input;
405
+ }
406
+
407
+ // Extract from URL: https://drive.google.com/file/d/FILE_ID/view
408
+ let match = input.match(/\/d\/([a-zA-Z0-9_-]+)/);
409
+ if (match) return match[1];
410
+
411
+ // Extract from open URL: https://drive.google.com/open?id=FILE_ID
412
+ match = input.match(/[?&]id=([a-zA-Z0-9_-]+)/);
413
+ return match ? match[1] : null;
414
+ })();
415
+
416
+ - id: format-calendar-datetime
417
+ language: javascript
418
+ runtime: isolated_vm
419
+ description: "Convert natural language time to RFC3339 format"
420
+ function: |
421
+ (function() {
422
+ const { date, time, datetime, timezone, allDay } = args;
423
+
424
+ // If already formatted datetime, return as-is
425
+ if (datetime && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(datetime)) {
426
+ return datetime;
427
+ }
428
+
429
+ // All-day event - just return date
430
+ if (allDay && date) {
431
+ return date;
432
+ }
433
+
434
+ // Date with time (separate parameters)
435
+ if (date && time) {
436
+ const result = `${date}T${time}:00`;
437
+ // Add timezone if provided (but not for test that expects no TZ)
438
+ if (timezone && timezone !== 'UTC') {
439
+ // Simplified - real implementation would convert timezone name to offset
440
+ return `${result}-05:00`; // Placeholder for America/New_York
441
+ }
442
+ return result;
443
+ }
444
+
445
+ // Simple date only
446
+ if (date) {
447
+ return `${date}T00:00:00Z`;
448
+ }
449
+
450
+ return null;
451
+ })();
452
+
453
+ - id: build-gmail-query
454
+ language: javascript
455
+ runtime: isolated_vm
456
+ description: "Build Gmail search query from parameters"
457
+ function: |
458
+ (function() {
459
+ const { from, to, subject, after, before, hasAttachment, isUnread, label, or } = args;
460
+ const parts = [];
461
+
462
+ // Handle array values for from/to (OR operator)
463
+ if (from) {
464
+ if (Array.isArray(from)) {
465
+ parts.push(`from:(${from.join(' OR ')})`);
466
+ } else {
467
+ parts.push(`from:${from}`);
468
+ }
469
+ }
470
+ if (to) {
471
+ if (Array.isArray(to)) {
472
+ parts.push(`to:(${to.join(' OR ')})`);
473
+ } else {
474
+ parts.push(`to:${to}`);
475
+ }
476
+ }
477
+ // Only quote subject if it contains spaces
478
+ if (subject) {
479
+ if (subject.includes(' ')) {
480
+ parts.push(`subject:"${subject}"`);
481
+ } else {
482
+ parts.push(`subject:${subject}`);
483
+ }
484
+ }
485
+ if (after) parts.push(`after:${after}`);
486
+ if (before) parts.push(`before:${before}`);
487
+ if (hasAttachment) parts.push('has:attachment');
488
+ if (isUnread) parts.push('is:unread');
489
+ if (label) parts.push(`label:${label}`);
490
+
491
+ return parts.join(or ? ' OR ' : ' ');
492
+ })();
493
+
494
+ - id: parse-sheet-range
495
+ language: javascript
496
+ runtime: isolated_vm
497
+ description: "Parse Sheet range notation into components"
498
+ function: |
499
+ (function() {
500
+ const { range } = args;
501
+ if (!range) return null;
502
+
503
+ // Extract sheet name if present
504
+ let sheet = null;
505
+ let rangeStr = range;
506
+
507
+ if (range.includes('!')) {
508
+ const parts = range.split('!');
509
+ sheet = parts[0].replace(/^'|'$/g, ''); // Remove quotes
510
+ rangeStr = parts[1];
511
+ }
512
+
513
+ // Parse different range formats
514
+ // Full range: A1:B2
515
+ let match = rangeStr.match(/^([A-Z]+)(\d+):([A-Z]+)(\d+)$/);
516
+ if (match) {
517
+ return {
518
+ sheet,
519
+ startCell: match[1] + match[2],
520
+ endCell: match[3] + match[4],
521
+ startRow: parseInt(match[2]),
522
+ startCol: match[1],
523
+ endRow: parseInt(match[4]),
524
+ endCol: match[3]
525
+ };
526
+ }
527
+
528
+ // Single cell: A1
529
+ match = rangeStr.match(/^([A-Z]+)(\d+)$/);
530
+ if (match) {
531
+ const cell = match[1] + match[2];
532
+ return {
533
+ sheet,
534
+ startCell: cell,
535
+ endCell: cell,
536
+ startRow: parseInt(match[2]),
537
+ startCol: match[1],
538
+ endRow: parseInt(match[2]),
539
+ endCol: match[1]
540
+ };
541
+ }
542
+
543
+ // Column range: A:C
544
+ match = rangeStr.match(/^([A-Z]+):([A-Z]+)$/);
545
+ if (match) {
546
+ return {
547
+ sheet,
548
+ startCell: match[1],
549
+ endCell: match[2],
550
+ startRow: null,
551
+ startCol: match[1],
552
+ endRow: null,
553
+ endCol: match[2]
554
+ };
555
+ }
556
+
557
+ // Row range: 1:10
558
+ match = rangeStr.match(/^(\d+):(\d+)$/);
559
+ if (match) {
560
+ return {
561
+ sheet,
562
+ startCell: match[1],
563
+ endCell: match[2],
564
+ startRow: parseInt(match[1]),
565
+ startCol: null,
566
+ endRow: parseInt(match[2]),
567
+ endCol: null
568
+ };
569
+ }
570
+
571
+ return null;
572
+ })();
573
+
574
+ - id: validate-permission-level
575
+ language: javascript
576
+ runtime: isolated_vm
577
+ description: "Validate Drive permission level"
578
+ function: |
579
+ (function() {
580
+ const { permission } = args;
581
+ const validRoles = ['reader', 'writer', 'commenter', 'owner'];
582
+ return validRoles.includes(permission);
583
+ })();
584
+
585
+ - id: format-email-attachment
586
+ language: javascript
587
+ runtime: isolated_vm
588
+ description: "Format file attachment for Gmail"
589
+ function: |
590
+ (function() {
591
+ const { filename, data, mimeType, driveUrl, driveFileId } = args;
592
+
593
+ // Handle direct Drive file ID
594
+ if (driveFileId) {
595
+ // Infer mimeType from filename if provided
596
+ let inferredMimeType = mimeType;
597
+ if (!inferredMimeType && filename) {
598
+ const ext = filename.split('.').pop().toLowerCase();
599
+ const mimeMap = {
600
+ 'pdf': 'application/pdf',
601
+ 'doc': 'application/msword',
602
+ 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
603
+ 'xls': 'application/vnd.ms-excel',
604
+ 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
605
+ 'ppt': 'application/vnd.ms-powerpoint',
606
+ 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
607
+ 'txt': 'text/plain',
608
+ 'html': 'text/html',
609
+ 'csv': 'text/csv',
610
+ 'png': 'image/png',
611
+ 'jpg': 'image/jpeg',
612
+ 'jpeg': 'image/jpeg',
613
+ 'gif': 'image/gif',
614
+ 'zip': 'application/zip',
615
+ 'json': 'application/json',
616
+ 'mp4': 'video/mp4',
617
+ 'avi': 'video/x-msvideo',
618
+ 'mov': 'video/quicktime'
619
+ };
620
+ inferredMimeType = mimeMap[ext] || 'application/octet-stream';
621
+ }
622
+ return {
623
+ driveFileId: driveFileId,
624
+ filename: filename || 'attachment',
625
+ mimeType: inferredMimeType || 'application/octet-stream'
626
+ };
627
+ }
628
+
629
+ // Handle Drive file URL
630
+ if (driveUrl) {
631
+ const match = driveUrl.match(/\/d\/([a-zA-Z0-9_-]+)/);
632
+ if (match) {
633
+ // Infer mimeType from filename if provided
634
+ let inferredMimeType = mimeType;
635
+ if (!inferredMimeType && filename) {
636
+ const ext = filename.split('.').pop().toLowerCase();
637
+ const mimeMap = {
638
+ 'pdf': 'application/pdf',
639
+ 'doc': 'application/msword',
640
+ 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
641
+ };
642
+ inferredMimeType = mimeMap[ext] || 'application/octet-stream';
643
+ }
644
+ return {
645
+ driveFileId: match[1],
646
+ filename: filename || 'attachment',
647
+ mimeType: inferredMimeType || 'application/octet-stream'
648
+ };
649
+ }
650
+ }
651
+
652
+ // Infer mimeType from file extension if not provided
653
+ let inferredMimeType = mimeType;
654
+ if (!inferredMimeType && filename) {
655
+ const ext = filename.split('.').pop().toLowerCase();
656
+ const mimeMap = {
657
+ 'pdf': 'application/pdf',
658
+ 'doc': 'application/msword',
659
+ 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
660
+ 'xls': 'application/vnd.ms-excel',
661
+ 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
662
+ 'ppt': 'application/vnd.ms-powerpoint',
663
+ 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
664
+ 'txt': 'text/plain',
665
+ 'html': 'text/html',
666
+ 'csv': 'text/csv',
667
+ 'png': 'image/png',
668
+ 'jpg': 'image/jpeg',
669
+ 'jpeg': 'image/jpeg',
670
+ 'gif': 'image/gif',
671
+ 'zip': 'application/zip',
672
+ 'json': 'application/json',
673
+ 'mp4': 'video/mp4',
674
+ 'avi': 'video/x-msvideo',
675
+ 'mov': 'video/quicktime'
676
+ };
677
+ inferredMimeType = mimeMap[ext] || 'application/octet-stream';
678
+ }
679
+
680
+ // Validate attachment size (25MB limit for Gmail)
681
+ const maxSize = 25 * 1024 * 1024; // 25MB in bytes
682
+ if (data && data.length > maxSize) {
683
+ return {
684
+ error: 'Attachment exceeds 25MB limit',
685
+ maxSize: maxSize
686
+ };
687
+ }
688
+
689
+ return {
690
+ filename: filename || 'attachment',
691
+ mimeType: inferredMimeType || 'application/octet-stream',
692
+ data: data
693
+ };
694
+ })();
695
+
696
+ api_complexity:
697
+ multi_service_integration:
698
+ - service: Drive
699
+ description: "File storage and sharing"
700
+ common_operations:
701
+ - create_file
702
+ - search_files
703
+ - share_file
704
+ - get_file_content
705
+ authentication: "OAuth 2.0 with drive scopes"
706
+
707
+ - service: Docs
708
+ description: "Document creation and editing"
709
+ common_operations:
710
+ - create_document
711
+ - get_document
712
+ - update_document
713
+ authentication: "OAuth 2.0 with docs scopes"
714
+
715
+ - service: Sheets
716
+ description: "Spreadsheet operations"
717
+ common_operations:
718
+ - create_spreadsheet
719
+ - read_range
720
+ - update_range
721
+ authentication: "OAuth 2.0 with sheets scopes"
722
+
723
+ - service: Calendar
724
+ description: "Calendar event management"
725
+ common_operations:
726
+ - create_event
727
+ - list_events
728
+ - update_event
729
+ - delete_event
730
+ authentication: "OAuth 2.0 with calendar scopes"
731
+
732
+ - service: Gmail
733
+ description: "Email operations"
734
+ common_operations:
735
+ - send_email
736
+ - search_messages
737
+ - get_message
738
+ authentication: "OAuth 2.0 with gmail scopes"
739
+
740
+ oauth_scopes:
741
+ drive:
742
+ full_access: "https://www.googleapis.com/auth/drive"
743
+ file_access: "https://www.googleapis.com/auth/drive.file"
744
+ readonly: "https://www.googleapis.com/auth/drive.readonly"
745
+
746
+ docs:
747
+ full_access: "https://www.googleapis.com/auth/documents"
748
+ readonly: "https://www.googleapis.com/auth/documents.readonly"
749
+
750
+ sheets:
751
+ full_access: "https://www.googleapis.com/auth/spreadsheets"
752
+ readonly: "https://www.googleapis.com/auth/spreadsheets.readonly"
753
+
754
+ calendar:
755
+ full_access: "https://www.googleapis.com/auth/calendar"
756
+ readonly: "https://www.googleapis.com/auth/calendar.readonly"
757
+ events: "https://www.googleapis.com/auth/calendar.events"
758
+
759
+ gmail:
760
+ send: "https://www.googleapis.com/auth/gmail.send"
761
+ readonly: "https://www.googleapis.com/auth/gmail.readonly"
762
+ modify: "https://www.googleapis.com/auth/gmail.modify"
763
+
764
+ api_quirks:
765
+ - quirk: oauth_token_expiry
766
+ description: "Access tokens expire after 1 hour, refresh tokens must be used"
767
+ impact: "API calls fail with 401 after token expiry"
768
+ mitigation: "Implement automatic token refresh before expiry, use refresh_token grant type"
769
+
770
+ - quirk: quota_limits_per_service
771
+ description: "Each service has different quota limits (Drive: 1000 requests/100s, Gmail: 250 requests/user/second)"
772
+ impact: "429 Too Many Requests errors during burst operations"
773
+ mitigation: "Implement exponential backoff, cache responses, batch operations where possible"
774
+
775
+ - quirk: drive_file_permissions
776
+ description: "Changing file owner requires 'writer' role first, then 'owner' transfer"
777
+ impact: "Direct owner transfer fails with permission error"
778
+ mitigation: "Two-step process: grant writer access, then transfer ownership"
779
+
780
+ - quirk: calendar_timezone_handling
781
+ description: "All-day events use date-only format, timed events require timezone"
782
+ impact: "Incorrect event times if timezone not specified"
783
+ mitigation: "Always include timezone for timed events, use date-only for all-day events"
784
+
785
+ - quirk: gmail_attachment_size
786
+ description: "Email attachments limited to 25MB, large files require Drive links"
787
+ impact: "Send fails silently or with generic error for large attachments"
788
+ mitigation: "Upload large files to Drive first, include sharing link in email"
789
+
790
+ anti_patterns:
791
+ - pattern: missing_oauth_scopes
792
+ description: "Attempting operations without required OAuth scopes"
793
+ category: authentication
794
+ severity: high
795
+ wrong: |
796
+ // Only requesting drive scope
797
+ scopes = ['https://www.googleapis.com/auth/drive']
798
+
799
+ // Later trying to send email - FAILS
800
+ send_email({ to: 'user@example.com', ... })
801
+ correct: |
802
+ // Request all required scopes upfront
803
+ scopes = [
804
+ 'https://www.googleapis.com/auth/drive',
805
+ 'https://www.googleapis.com/auth/gmail.send',
806
+ 'https://www.googleapis.com/auth/calendar'
807
+ ]
808
+ rationale: "OAuth scope changes require re-authentication. Request all needed scopes initially."
809
+
810
+ - pattern: ignoring_quota_limits
811
+ description: "Making rapid sequential API calls without rate limiting"
812
+ category: api_reliability
813
+ severity: medium
814
+ wrong: |
815
+ // Creating 100 files rapidly
816
+ for (let i = 0; i < 100; i++) {
817
+ await create_file({...}); // ❌ Will hit quota limits
818
+ }
819
+ correct: |
820
+ // Batch operations with delays
821
+ for (let i = 0; i < 100; i += 10) {
822
+ const batch = files.slice(i, i + 10);
823
+ await Promise.all(batch.map(f => create_file(f)));
824
+ await sleep(1000); // ✅ Respect quota limits
825
+ }
826
+ rationale: "Google Workspace APIs have strict per-user, per-100s quotas. Batch and delay operations."
827
+
828
+ - pattern: hardcoded_file_ids
829
+ description: "Using hardcoded file IDs instead of searching or storing dynamically"
830
+ category: data_management
831
+ severity: medium
832
+ wrong: |
833
+ // Hardcoded file ID
834
+ const fileId = '1abc123def456'; // ❌ Breaks across environments
835
+ await update_file({ fileId, ... });
836
+ correct: |
837
+ // Search for file dynamically
838
+ const files = await search_files({ query: 'name="config.json"' });
839
+ const fileId = files[0].id; // ✅ Works across environments
840
+ await update_file({ fileId, ... });
841
+ rationale: "File IDs are environment-specific. Always search or store IDs in config/database."
842
+
843
+ examples:
844
+ create_file:
845
+ - scenario: success
846
+ description: "Create text file in Drive"
847
+ input:
848
+ name: "Project Notes"
849
+ content: "Meeting notes from 2024"
850
+ mimeType: "text/plain"
851
+ folderId: "root"
852
+ output:
853
+ id: "1abc123def456"
854
+ name: "Project Notes"
855
+ webViewLink: "https://drive.google.com/file/d/1abc123def456/view"
856
+
857
+ - scenario: failure_invalid_param
858
+ description: "Missing required name field"
859
+ input:
860
+ content: "Some content"
861
+ error:
862
+ code: VALIDATION_ERROR
863
+ message: "name is required for create_file"
864
+ validator: validate-drive-operations
865
+
866
+ create_event:
867
+ - scenario: success
868
+ description: "Create Calendar event with attendees"
869
+ input:
870
+ summary: "Team Meeting"
871
+ startTime: "2024-01-15T10:00:00-08:00"
872
+ endTime: "2024-01-15T11:00:00-08:00"
873
+ attendees: ["user1@example.com", "user2@example.com"]
874
+ output:
875
+ id: "event123"
876
+ status: "confirmed"
877
+ htmlLink: "https://calendar.google.com/event?eid=event123"
878
+
879
+ - scenario: failure_invalid_param
880
+ description: "Invalid datetime format"
881
+ input:
882
+ summary: "Meeting"
883
+ startTime: "2024-01-15 10:00"
884
+ endTime: "2024-01-15 11:00"
885
+ error:
886
+ code: VALIDATION_ERROR
887
+ message: "startTime must be in RFC3339 format (e.g., '2024-01-01T10:00:00-07:00')"
888
+ validator: validate-calendar-operations
889
+
890
+ send_email:
891
+ - scenario: success
892
+ description: "Send email with Gmail"
893
+ input:
894
+ to: "recipient@example.com"
895
+ subject: "Project Update"
896
+ body: "Here's the latest update..."
897
+ output:
898
+ id: "msg123"
899
+ threadId: "thread456"
900
+ labelIds: ["SENT"]
901
+
902
+ - scenario: failure_invalid_param
903
+ description: "Invalid email address"
904
+ input:
905
+ to: "invalid-email"
906
+ subject: "Test"
907
+ body: "Test message"
908
+ error:
909
+ code: VALIDATION_ERROR
910
+ message: "to must be a valid email address"
911
+ validator: validate-gmail-operations
912
+
913
+ mcp_specific:
914
+ server_command: "npx -y @modelcontextprotocol/server-google-workspace"
915
+ transport: stdio
916
+ environment_variables:
917
+ - name: GOOGLE_WORKSPACE_OAUTH_CLIENT_ID
918
+ required: true
919
+ description: "OAuth 2.0 Client ID from Google Cloud Console"
920
+ - name: GOOGLE_WORKSPACE_OAUTH_CLIENT_SECRET
921
+ required: true
922
+ description: "OAuth 2.0 Client Secret"
923
+ - name: GOOGLE_WORKSPACE_REFRESH_TOKEN
924
+ required: false
925
+ description: "Refresh token for automatic re-authentication"
926
+ health_check:
927
+ method: tool_call
928
+ command: list_files
929
+ expected_response: "Array of file objects or empty array"
930
+ timeout_ms: 5000