@synap-core/workspace-templates 0.12.0 → 0.23.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 (245) hide show
  1. package/README.md +483 -0
  2. package/automations/bookmark-enrichment.automation.json +321 -0
  3. package/automations/github-pr-events.automation.json +505 -0
  4. package/automations/mail-feed.automation.json +86 -0
  5. package/automations/ship-a-change-checks-green.automation.json +106 -0
  6. package/automations/ship-a-change-checks-red.automation.json +106 -0
  7. package/automations/ship-a-change-deployed.automation.json +56 -0
  8. package/automations/ship-a-change-pr-merged.automation.json +110 -0
  9. package/automations/ship-a-change-pr-opened.automation.json +104 -0
  10. package/automations/url-bookmark-capture.automation.json +132 -0
  11. package/capabilities/agency-skills.capability.json +157 -0
  12. package/capabilities/apify.capability.json +265 -0
  13. package/capabilities/apollo.capability.json +120 -0
  14. package/capabilities/arch-backend.capability.json +97 -0
  15. package/capabilities/arch-client-intelligence.capability.json +401 -0
  16. package/capabilities/backblaze-b2.capability.json +205 -0
  17. package/capabilities/cal-com.capability.json +266 -0
  18. package/capabilities/canva.capability.json +274 -0
  19. package/capabilities/claude-code-routines.capability.json +172 -0
  20. package/capabilities/claude-managed-agents.capability.json +215 -0
  21. package/capabilities/client-comms-report.capability.json +246 -0
  22. package/capabilities/content-idea-to-production.capability.json +29 -0
  23. package/capabilities/datagouv.capability.json +315 -0
  24. package/capabilities/discord-bot.capability.json +157 -0
  25. package/capabilities/dropbox.capability.json +281 -0
  26. package/capabilities/exa.capability.json +109 -0
  27. package/capabilities/fal-ai.capability.json +83 -0
  28. package/capabilities/fal-media-lab.capability.json +158 -0
  29. package/capabilities/fireflies.capability.json +191 -0
  30. package/capabilities/freellmapi.capability.json +114 -0
  31. package/capabilities/generic-apikey.capability.json +92 -0
  32. package/capabilities/github-merge.capability.json +99 -0
  33. package/capabilities/github-read.capability.json +325 -0
  34. package/capabilities/governance-tighten-recommender.capability.json +81 -0
  35. package/capabilities/jev.capability.json +226 -0
  36. package/capabilities/lead-conversion-enrollment.capability.json +246 -0
  37. package/capabilities/mail-feed.capability.json +277 -0
  38. package/capabilities/mailgun.capability.json +52 -0
  39. package/capabilities/nango-google.capability.json +639 -0
  40. package/capabilities/notion.capability.json +417 -0
  41. package/capabilities/omniroute.capability.json +137 -0
  42. package/capabilities/posthog-analytics.capability.json +258 -0
  43. package/capabilities/postiz.capability.json +467 -0
  44. package/capabilities/proactive-digest.capability.json +190 -0
  45. package/capabilities/proton.capability.json +288 -0
  46. package/capabilities/replicate-rvm.capability.json +97 -0
  47. package/capabilities/research-methods.capability.json +57 -0
  48. package/capabilities/shopify.capability.json +395 -0
  49. package/capabilities/slack.capability.json +369 -0
  50. package/capabilities/stripe.capability.json +420 -0
  51. package/capabilities/telegram-bridge.capability.json +56 -0
  52. package/capabilities/treg.capability.json +102 -0
  53. package/capabilities/unipile-linkedin.capability.json +471 -0
  54. package/capabilities/vercel.capability.json +424 -0
  55. package/dist/define-CPS0n8BV.d.ts +1331 -0
  56. package/dist/index.d.ts +174 -900
  57. package/dist/index.js +26148 -23931
  58. package/dist/index.js.map +1 -1
  59. package/dist/wire.d.ts +222 -0
  60. package/dist/wire.js +77 -0
  61. package/dist/wire.js.map +1 -0
  62. package/package.json +27 -4
  63. package/packs/bookmark-views-pack.json +33 -0
  64. package/packs/crm-pack.json +76 -0
  65. package/packs/customer-profile.json +28 -0
  66. package/packs/deep-research.playbook.json +30 -0
  67. package/packs/event-views-pack.json +33 -0
  68. package/packs/habit-profile.json +27 -0
  69. package/packs/hr-pack.json +54 -0
  70. package/packs/invoice-profile.json +28 -0
  71. package/packs/knowledge-base-pack.json +56 -0
  72. package/packs/meeting-profile.json +29 -0
  73. package/packs/product-profile.json +30 -0
  74. package/packs/project-management-pack.json +49 -0
  75. package/packs/recipe-profile.json +29 -0
  76. package/packs/task-views-pack.json +39 -0
  77. package/retired.yaml +136 -0
  78. package/skills/app-factory-build-slice/SKILL.md +70 -0
  79. package/skills/app-factory-build-slice.catalog.json +17 -0
  80. package/skills/app-factory-design-canvas/SKILL.md +96 -0
  81. package/skills/app-factory-design-canvas.catalog.json +17 -0
  82. package/skills/app-factory-design-review/SKILL.md +99 -0
  83. package/skills/app-factory-design-review.catalog.json +18 -0
  84. package/skills/app-factory-research/SKILL.md +123 -0
  85. package/skills/app-factory-research.catalog.json +17 -0
  86. package/skills/bookmark-enrichment/SKILL.md +40 -0
  87. package/skills/carousel-format/carousel-format.skill.json +18 -0
  88. package/skills/collage-broll/collage-broll.skill.json +20 -0
  89. package/skills/content-taste/content-taste.skill.json +18 -0
  90. package/skills/creative-director/creative-director.skill.json +18 -0
  91. package/skills/design-critique/SKILL.md +135 -0
  92. package/skills/design-critique.catalog.json +12 -0
  93. package/skills/designing-with-real-components/SKILL.md +140 -0
  94. package/skills/designing-with-real-components.catalog.json +12 -0
  95. package/skills/edit-loop/edit-loop.skill.json +25 -0
  96. package/skills/facecam-edit/facecam-edit.skill.json +24 -0
  97. package/skills/mapping-the-server/SKILL.md +54 -0
  98. package/skills/math-explainer-manimgx/math-explainer-manimgx.skill.json +20 -0
  99. package/skills/motion-quality-gates/motion-quality-gates.skill.json +20 -0
  100. package/skills/open-design-edit/open-design-edit.skill.json +24 -0
  101. package/skills/reading-client-progress/SKILL.md +65 -0
  102. package/skills/routing-to-channels/SKILL.md +54 -0
  103. package/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
  104. package/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
  105. package/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
  106. package/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
  107. package/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
  108. package/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
  109. package/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
  110. package/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
  111. package/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
  112. package/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
  113. package/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
  114. package/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
  115. package/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
  116. package/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
  117. package/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
  118. package/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
  119. package/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
  120. package/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
  121. package/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
  122. package/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
  123. package/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
  124. package/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
  125. package/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
  126. package/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
  127. package/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
  128. package/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
  129. package/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
  130. package/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
  131. package/skills/video-direction/video-direction.skill.json +20 -0
  132. package/skills/video-style-vocabulary/video-style-vocabulary.skill.json +20 -0
  133. package/skills/video-toolbox/video-toolbox.skill.json +20 -0
  134. package/src/__fixtures__/lifecycle-presets.flat-before.json +205 -0
  135. package/src/agency-os.yaml +122 -0
  136. package/src/agent-os-skill-slugs.test.ts +65 -0
  137. package/src/apify-social-reader.test.ts +317 -0
  138. package/src/base.yaml +85 -39
  139. package/src/blockchain-ecosystem.yaml +1 -0
  140. package/src/brand-library.yaml +525 -14
  141. package/src/builder-dev-fold.template.test.ts +113 -0
  142. package/src/builder.yaml +779 -91
  143. package/src/business-model-catalog-description.test.ts +47 -0
  144. package/src/business-model-grp.template.test.ts +214 -0
  145. package/src/business-model.yaml +296 -49
  146. package/src/catalog-safety.test.ts +198 -0
  147. package/src/catalog.template-items.test.ts +75 -0
  148. package/src/catalog.ts +66 -2
  149. package/src/concept-guard.test.ts +28 -8
  150. package/src/concept-guard.ts +2 -2
  151. package/src/content-creation.template.test.ts +52 -0
  152. package/src/content-creation.yaml +192 -0
  153. package/src/content-os.edit-loop.template.test.ts +210 -0
  154. package/src/content-os.publish-due-posts.template.test.ts +261 -0
  155. package/src/content-os.template.test.ts +322 -0
  156. package/src/content-os.video-takes.template.test.ts +338 -0
  157. package/src/content-os.work-a-take.template.test.ts +125 -0
  158. package/src/content-os.yaml +1830 -39
  159. package/src/content-studio-retired.template.test.ts +82 -0
  160. package/src/corpus-flow-validity.test.ts +4 -5
  161. package/src/crm-absorbs-outreach.template.test.ts +117 -0
  162. package/src/crm-build-plan.template.test.ts +128 -0
  163. package/src/crm-lists.template.test.ts +96 -0
  164. package/src/crm-messages-cadence.template.test.ts +164 -0
  165. package/src/crm-one-send-door.template.test.ts +65 -0
  166. package/src/crm.yaml +1456 -181
  167. package/src/decisions-wave.template.test.ts +186 -0
  168. package/src/define.ts +130 -17
  169. package/src/design-to-implementation.template.test.ts +94 -0
  170. package/src/domain-template-type.test.ts +75 -0
  171. package/src/ecosystem.yaml +27 -66
  172. package/src/enterprise-os.yaml +10 -134
  173. package/src/facecam-edit.audio-studio.test.ts +188 -0
  174. package/src/fal-generate-image.test.ts +200 -0
  175. package/src/fal-media-lab-pod-files.test.ts +180 -0
  176. package/src/finance.yaml +254 -1
  177. package/src/foundation.yaml +78 -38
  178. package/src/frame-host-modules.d.mts +6 -0
  179. package/src/frame-host-modules.mjs +58 -0
  180. package/src/generate.mjs +9 -3
  181. package/src/github-merge.test.ts +210 -0
  182. package/src/grants.yaml +46 -17
  183. package/src/hr.yaml +39 -6
  184. package/src/index.ts +36 -1
  185. package/src/intent.test.ts +161 -0
  186. package/src/internal-runbook.yaml +19 -1
  187. package/src/jev.test.ts +356 -0
  188. package/src/legal.yaml +33 -1
  189. package/src/life-os.yaml +51 -240
  190. package/src/lifecycle-coverage.test.ts +124 -0
  191. package/src/lifecycle-declarations.test.ts +252 -0
  192. package/src/lifecycle-presets.test.ts +468 -0
  193. package/src/lifecycle-presets.ts +494 -0
  194. package/src/lifecycle-stuck.test.ts +46 -0
  195. package/src/lifecycle-waits.parity.test.ts +319 -0
  196. package/src/marketing.yaml +108 -4
  197. package/src/meetings-knowledge.yaml +18 -0
  198. package/src/networking.yaml +23 -2
  199. package/src/operations.yaml +304 -4
  200. package/src/pipeline-views.template.test.ts +88 -0
  201. package/src/playbook-goal-placeholders.test.ts +57 -0
  202. package/src/postiz-contract.test.ts +134 -0
  203. package/src/presentation-declarations.test.ts +174 -0
  204. package/src/process-contract.validate.test.ts +352 -0
  205. package/src/project-management.yaml +39 -740
  206. package/src/publish-body.d.mts +29 -0
  207. package/src/publish-body.mjs +74 -0
  208. package/src/publish-body.test.ts +74 -0
  209. package/src/publish-official-lib.test.ts +176 -0
  210. package/src/replicate-rvm.test.ts +504 -0
  211. package/src/research-base.yaml +119 -20
  212. package/src/research-decision.yaml +60 -3
  213. package/src/reserved-profile-slugs.test.ts +83 -0
  214. package/src/retired-goal-kinds.test.ts +58 -0
  215. package/src/role-reference-and-step-domain.test.ts +192 -0
  216. package/src/seed-obligation.test.ts +1 -6
  217. package/src/send-message-maps.test.ts +227 -0
  218. package/src/shared-role-ssot.test.ts +40 -2
  219. package/src/ship-a-change.template.test.ts +177 -0
  220. package/src/skills.test.ts +170 -0
  221. package/src/social.yaml +85 -27
  222. package/src/space-packages.freshness.test.ts +97 -0
  223. package/src/space-packages.generated.ts +40 -0
  224. package/src/space-packages.test.ts +125 -0
  225. package/src/space-packages.ts +73 -0
  226. package/src/start.test.ts +188 -0
  227. package/src/task-intents.test.ts +293 -0
  228. package/src/templates.ts +20851 -21496
  229. package/src/types.ts +443 -60
  230. package/src/unipile-publish-post.test.ts +162 -0
  231. package/src/validate-flow.drift.test.ts +2 -3
  232. package/src/validate-flow.ts +22 -2
  233. package/src/validate-onboarding.test.ts +59 -0
  234. package/src/validate.test.ts +71 -4
  235. package/src/validate.ts +1335 -7
  236. package/src/wire-core.ts +231 -0
  237. package/src/wire.test.ts +159 -0
  238. package/src/wire.ts +107 -0
  239. package/src/agent-fleet.yaml +0 -1645
  240. package/src/business-developer.template.test.ts +0 -351
  241. package/src/business-developer.yaml +0 -860
  242. package/src/content-studio.yaml +0 -361
  243. package/src/dev-dashboard.yaml +0 -990
  244. package/src/outreach-comms.yaml +0 -486
  245. package/src/the-arch.yaml +0 -201
@@ -0,0 +1,639 @@
1
+ {
2
+ "apiVersion": "synap/v1",
3
+ "kind": "capability",
4
+ "meta": {
5
+ "slug": "nango-google",
6
+ "name": "Google Workspace",
7
+ "description": "Gmail, Calendar, Drive and Docs through one Google connection: search and send email, list and create events, search and organize Drive, read Docs and sync contacts. Sending email and creating events follow your approval rules. Connect Google in Settings → Connectors.",
8
+ "tags": [
9
+ "capability"
10
+ ],
11
+ "isPublic": true,
12
+ "syncByDefault": true
13
+ },
14
+ "spec": {
15
+ "key": "nango-google",
16
+ "name": "Nango — Google Workspace",
17
+ "description": "Google Workspace (Gmail + Calendar + Drive) through ONE Nango OAuth connection. Registers a single provider tool whose credentialRef is the stable nango://google ref (Nango holds the OAuth credential — no vault secret) and seeds eight skills across the three Google APIs. Gmail calls set Nango's Base-Url-Override to gmail.googleapis.com; Calendar/Drive use the provider-default host www.googleapis.com. Grounded in NangoConnector.proxyRequest (Connection-Id + Provider-Config-Key, optional Base-Url-Override) and external-dispatch's nango:// handler. PRECONDITION: a Nango integration with providerConfigKey 'google' (scopes for gmail.send, gmail.readonly, calendar, drive.readonly) must exist and the acting user must have connected their Google account via Settings -> Connectors; the dispatcher resolves the user's most-recent google connection automatically. Writes (gmail_send, calendar_create) are side-effecting and route through the capability-execution gate (which may auto-run or propose depending on the actor); the skills detect a proposal envelope and report 'queued for approval' rather than falsely claiming success. Reads (gmail_search, calendar_list, drive_search) return data inline. CONNECTION SYNC: tools[google].metadata.sync declares the out-of-the-box mirror (per kind: event via calendar_list, email.thread via gmail_list_threads, contact via contacts_list; first run bounded to windowDays/itemLimit and filed as ONE import proposal). contacts_list additionally needs the contacts.readonly scope on the Nango 'google' integration.",
18
+ "params": [],
19
+ "vault": [],
20
+ "tools": [
21
+ {
22
+ "name": "google",
23
+ "kind": "provider",
24
+ "description": "Google Workspace access through Nango. credentialRef nango://google resolves the user's Google connection (Connection-Id + Provider-Config-Key) and proxies the request to the relevant Google API (Gmail via Base-Url-Override, Calendar/Drive via the provider default).",
25
+ "credentialRef": "nango://google",
26
+ "executor": "is-agent",
27
+ "config": {
28
+ "providerConfigKey": "google"
29
+ },
30
+ "metadata": {
31
+ "sync": {
32
+ "enabled": true,
33
+ "kinds": {
34
+ "event": {
35
+ "enabled": true,
36
+ "windowDays": 90,
37
+ "itemLimit": 200
38
+ },
39
+ "email.thread": {
40
+ "enabled": true,
41
+ "windowDays": 90,
42
+ "itemLimit": 200
43
+ },
44
+ "contact": {
45
+ "enabled": true,
46
+ "windowDays": 90,
47
+ "itemLimit": 200
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ],
54
+ "skills": [
55
+ {
56
+ "name": "gmail_send",
57
+ "intent": "send_message",
58
+ "kind": "code",
59
+ "scope": "pod",
60
+ "description": "Sends an email via Gmail (Nango OAuth) and notes the send as a note entity (proposal-gated). Args: { to: string, subject: string, body: string }.",
61
+ "requires": [
62
+ "google"
63
+ ],
64
+ "executionMode": "async",
65
+ "timeoutSeconds": 60,
66
+ "parameters": {
67
+ "to": "string",
68
+ "subject": "string",
69
+ "body": "string"
70
+ },
71
+ "inputMap": {
72
+ "params": {
73
+ "to": "$to.email",
74
+ "subject": "$.subject",
75
+ "body": "$.text"
76
+ }
77
+ },
78
+ "code": "// Send a Gmail message through the unified Google connection (Nango OAuth).\n// callProvider('google', ...) routes by tool NAME to the nango://google\n// connection; the 5th arg baseUrlOverride points THIS call at gmail.googleapis.com\n// (Calendar/Drive use the provider default www.googleapis.com — no override).\nconst GMAIL_HOST = 'https://gmail.googleapis.com';\nconst to = String(args?.to ?? '').trim();\nconst subject = String(args?.subject ?? '').trim();\nconst bodyText = String(args?.body ?? '');\nif (!to) throw new Error('gmail_send: to is required');\nif (!subject) throw new Error('gmail_send: subject is required');\n\nconst mime = [\n 'To: ' + to,\n 'Subject: ' + subject,\n 'MIME-Version: 1.0',\n 'Content-Type: text/plain; charset=\"UTF-8\"',\n '',\n bodyText\n].join('\\r\\n');\n\nconst B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst utf8Bytes = (str) => {\n const out = [];\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n if (c < 0x80) out.push(c);\n else if (c < 0x800) { out.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f)); }\n else if (c >= 0xd800 && c <= 0xdbff) {\n const c2 = str.charCodeAt(++i);\n c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff);\n out.push(0xf0 | (c >> 18), 0x80 | ((c >> 12) & 0x3f), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f));\n } else { out.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f)); }\n }\n return out;\n};\nconst base64 = (bytes) => {\n let s = '';\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i], b1 = bytes[i + 1], b2 = bytes[i + 2];\n s += B64[b0 >> 2];\n s += B64[((b0 & 3) << 4) | ((b1 ?? 0) >> 4)];\n s += b1 === undefined ? '=' : B64[((b1 & 15) << 2) | ((b2 ?? 0) >> 6)];\n s += b2 === undefined ? '=' : B64[b2 & 63];\n }\n return s;\n};\nconst raw = base64(utf8Bytes(mime)).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n\nconst res = await callProvider('google', 'POST', '/gmail/v1/users/me/messages/send', { raw }, { baseUrlOverride: GMAIL_HOST });\n// The capability-execution gate may return a PROPOSAL envelope ({ proposed,\n// proposalId }) with NO http status instead of executing. When proposed, that\n// proposal IS the record — return early WITHOUT also filing a note (no\n// double-proposal); the send is logged on approval-replay.\nif (res?.proposed === true) {\n return { success: false, proposed: true, proposalId: res?.proposalId ?? null, to, subject };\n}\n// Executed: treat \"no status\" as NOT-sent (never optimistically claim success).\nconst ok = typeof res?.status === 'number' && res.status >= 200 && res.status < 300;\nconst messageId = res?.body?.id ?? null;\n\nawait propose.entity({\n profileSlug: 'note',\n title: 'Email ' + (ok ? 'sent' : 'attempted') + ' -> ' + to + ': ' + subject,\n properties: { action: 'gmail_send', to, subject, gmailMessageId: messageId, status: res?.status ?? null, success: ok, provenance: 'connector', provider: 'nango-google' },\n reasoning: 'Recorded the outbound email for the activity timeline.'\n});\nreturn { success: ok, proposed: false, to, subject, gmailMessageId: messageId, status: res?.status ?? null };"
79
+ },
80
+ {
81
+ "name": "gmail_search",
82
+ "intent": "search_external",
83
+ "kind": "declarative",
84
+ "scope": "pod",
85
+ "description": "Searches Gmail and returns enriched results (subject, from, date, snippet) per hit. Args: { query?: string (Gmail search syntax), maxResults?: number }.",
86
+ "requires": [
87
+ "google"
88
+ ],
89
+ "executionMode": "sync",
90
+ "timeoutSeconds": 60,
91
+ "parameters": {
92
+ "query": "string",
93
+ "maxResults": "number"
94
+ },
95
+ "providerSpec": {
96
+ "tool": "google",
97
+ "method": "GET",
98
+ "baseUrlOverride": "https://gmail.googleapis.com",
99
+ "pathTemplate": "/gmail/v1/users/me/messages",
100
+ "query": {
101
+ "maxResults": "{{maxResults}}",
102
+ "q": "{{query}}"
103
+ },
104
+ "paramMapping": {
105
+ "query": {
106
+ "default": ""
107
+ },
108
+ "maxResults": {
109
+ "default": 10,
110
+ "clampMin": 1,
111
+ "clampMax": 25
112
+ }
113
+ },
114
+ "responseShape": {
115
+ "collectionPath": "messages",
116
+ "collectionAs": "results",
117
+ "item": {
118
+ "id": "id"
119
+ },
120
+ "scalar": {
121
+ "query": "{{query}}",
122
+ "count": "@count"
123
+ }
124
+ },
125
+ "expand": {
126
+ "forEachIdFrom": "results",
127
+ "concurrency": 5,
128
+ "merge": "detail-into-list-item",
129
+ "detail": {
130
+ "method": "GET",
131
+ "baseUrlOverride": "https://gmail.googleapis.com",
132
+ "pathTemplate": "/gmail/v1/users/me/messages/{{id}}",
133
+ "query": {
134
+ "format": "metadata",
135
+ "metadataHeaders": [
136
+ "Subject",
137
+ "From",
138
+ "Date"
139
+ ]
140
+ },
141
+ "paramMapping": {
142
+ "id": {
143
+ "required": true
144
+ }
145
+ },
146
+ "responseShape": {
147
+ "headers": {
148
+ "subject": "Subject",
149
+ "from": "From",
150
+ "date": "Date"
151
+ },
152
+ "scalar": {
153
+ "snippet": "snippet"
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+ },
160
+ {
161
+ "name": "calendar_list",
162
+ "intent": "list_records",
163
+ "kind": "declarative",
164
+ "scope": "pod",
165
+ "description": "Lists Google Calendar events ordered by start time. Args: { calendarId?: string (default 'primary'), timeMin?: RFC3339, timeMax?: RFC3339, updatedMin?: RFC3339 (only events modified since), maxResults?: number, pageToken?: string (from a prior nextPageToken) }.",
166
+ "requires": [
167
+ "google"
168
+ ],
169
+ "executionMode": "sync",
170
+ "timeoutSeconds": 60,
171
+ "parameters": {
172
+ "calendarId": "string",
173
+ "timeMin": "string",
174
+ "timeMax": "string?",
175
+ "updatedMin": "string?",
176
+ "maxResults": "number",
177
+ "pageToken": "string?"
178
+ },
179
+ "providerSpec": {
180
+ "tool": "google",
181
+ "method": "GET",
182
+ "baseUrlOverride": "https://www.googleapis.com",
183
+ "pathTemplate": "/calendar/v3/calendars/{{calendarId}}/events",
184
+ "query": {
185
+ "singleEvents": "true",
186
+ "orderBy": "startTime",
187
+ "maxResults": "{{maxResults}}",
188
+ "timeMin": "{{timeMin}}",
189
+ "timeMax": "{{timeMax}}",
190
+ "updatedMin": "{{updatedMin}}",
191
+ "pageToken": "{{pageToken}}"
192
+ },
193
+ "paramMapping": {
194
+ "calendarId": {
195
+ "default": "primary",
196
+ "encode": "uri"
197
+ },
198
+ "timeMin": {
199
+ "default": "@now"
200
+ },
201
+ "maxResults": {
202
+ "default": 10,
203
+ "clampMin": 1,
204
+ "clampMax": 250
205
+ }
206
+ },
207
+ "responseShape": {
208
+ "collectionPath": "items",
209
+ "collectionAs": "events",
210
+ "item": {
211
+ "id": "id",
212
+ "status": "status",
213
+ "summary": "summary",
214
+ "start": "start",
215
+ "end": "end",
216
+ "location": "location",
217
+ "htmlLink": "htmlLink",
218
+ "hangoutLink": "hangoutLink",
219
+ "description": "description",
220
+ "attendees": "attendees",
221
+ "updated": "updated"
222
+ },
223
+ "scalar": {
224
+ "calendarId": "{{calendarId}}",
225
+ "count": "@count",
226
+ "nextPageToken": "nextPageToken"
227
+ }
228
+ }
229
+ }
230
+ },
231
+ {
232
+ "name": "gmail_list_threads",
233
+ "intent": "list_records",
234
+ "kind": "declarative",
235
+ "scope": "pod",
236
+ "description": "Lists Gmail threads matching a query, each expanded with its messages' metadata (id, internalDate, labelIds, From/To/Cc/Subject/Date headers). Args: { query?: string (Gmail search syntax, e.g. newer_than:90d), maxResults?: number, pageToken?: string (from a prior nextPageToken) }.",
237
+ "requires": [
238
+ "google"
239
+ ],
240
+ "executionMode": "sync",
241
+ "timeoutSeconds": 120,
242
+ "parameters": {
243
+ "query": "string",
244
+ "maxResults": "number",
245
+ "pageToken": "string?"
246
+ },
247
+ "providerSpec": {
248
+ "tool": "google",
249
+ "method": "GET",
250
+ "baseUrlOverride": "https://gmail.googleapis.com",
251
+ "pathTemplate": "/gmail/v1/users/me/threads",
252
+ "query": {
253
+ "maxResults": "{{maxResults}}",
254
+ "q": "{{query}}",
255
+ "pageToken": "{{pageToken}}"
256
+ },
257
+ "paramMapping": {
258
+ "query": {
259
+ "default": ""
260
+ },
261
+ "maxResults": {
262
+ "default": 25,
263
+ "clampMin": 1,
264
+ "clampMax": 100
265
+ }
266
+ },
267
+ "responseShape": {
268
+ "collectionPath": "threads",
269
+ "collectionAs": "threads",
270
+ "item": {
271
+ "id": "id",
272
+ "snippet": "snippet"
273
+ },
274
+ "scalar": {
275
+ "query": "{{query}}",
276
+ "count": "@count",
277
+ "nextPageToken": "nextPageToken"
278
+ }
279
+ },
280
+ "expand": {
281
+ "forEachIdFrom": "threads",
282
+ "concurrency": 5,
283
+ "merge": "detail-into-list-item",
284
+ "detail": {
285
+ "method": "GET",
286
+ "baseUrlOverride": "https://gmail.googleapis.com",
287
+ "pathTemplate": "/gmail/v1/users/me/threads/{{id}}",
288
+ "query": {
289
+ "format": "metadata",
290
+ "metadataHeaders": [
291
+ "From",
292
+ "To",
293
+ "Cc",
294
+ "Subject",
295
+ "Date"
296
+ ]
297
+ },
298
+ "paramMapping": {
299
+ "id": {
300
+ "required": true,
301
+ "encode": "uri"
302
+ }
303
+ },
304
+ "responseShape": {
305
+ "collectionPath": "messages",
306
+ "collectionAs": "messages",
307
+ "item": {
308
+ "id": "id",
309
+ "internalDate": "internalDate",
310
+ "labelIds": "labelIds",
311
+ "headers": "payload.headers"
312
+ }
313
+ }
314
+ }
315
+ }
316
+ }
317
+ },
318
+ {
319
+ "name": "contacts_list",
320
+ "intent": "list_records",
321
+ "kind": "declarative",
322
+ "scope": "pod",
323
+ "description": "Lists the user's Google Contacts (People API connections), most recently modified first, with names, email addresses, phone numbers and organizations. Requires the contacts.readonly scope. Args: { maxResults?: number, pageToken?: string (from a prior nextPageToken) }.",
324
+ "requires": [
325
+ "google"
326
+ ],
327
+ "executionMode": "sync",
328
+ "timeoutSeconds": 60,
329
+ "parameters": {
330
+ "maxResults": "number",
331
+ "pageToken": "string?"
332
+ },
333
+ "providerSpec": {
334
+ "tool": "google",
335
+ "method": "GET",
336
+ "baseUrlOverride": "https://people.googleapis.com",
337
+ "pathTemplate": "/v1/people/me/connections",
338
+ "query": {
339
+ "personFields": "names,emailAddresses,phoneNumbers,organizations",
340
+ "sortOrder": "LAST_MODIFIED_DESCENDING",
341
+ "pageSize": "{{maxResults}}",
342
+ "pageToken": "{{pageToken}}"
343
+ },
344
+ "paramMapping": {
345
+ "maxResults": {
346
+ "default": 100,
347
+ "clampMin": 1,
348
+ "clampMax": 1000
349
+ }
350
+ },
351
+ "responseShape": {
352
+ "collectionPath": "connections",
353
+ "collectionAs": "contacts",
354
+ "item": {
355
+ "resourceName": "resourceName",
356
+ "names": "names",
357
+ "emailAddresses": "emailAddresses",
358
+ "phoneNumbers": "phoneNumbers",
359
+ "organizations": "organizations"
360
+ },
361
+ "scalar": {
362
+ "count": "@count",
363
+ "nextPageToken": "nextPageToken"
364
+ }
365
+ }
366
+ }
367
+ },
368
+ {
369
+ "name": "calendar_create",
370
+ "intent": "schedule_event",
371
+ "kind": "code",
372
+ "scope": "pod",
373
+ "description": "Creates a Google Calendar event and notes it (proposal-gated). Args: { summary: string, start: RFC3339, end: RFC3339, description?: string, location?: string, calendarId?: string }.",
374
+ "requires": [
375
+ "google"
376
+ ],
377
+ "executionMode": "async",
378
+ "timeoutSeconds": 60,
379
+ "parameters": {
380
+ "summary": "string",
381
+ "start": "string",
382
+ "end": "string",
383
+ "description": "string?",
384
+ "location": "string?",
385
+ "calendarId": "string?"
386
+ },
387
+ "code": "// Create a Google Calendar event (side-effecting write). RFC3339 start/end.\nconst summary = String(args?.summary ?? '').trim();\nif (!summary) throw new Error('calendar_create: summary is required');\nconst start = String(args?.start ?? '').trim();\nconst end = String(args?.end ?? '').trim();\nif (!start) throw new Error('calendar_create: start is required (RFC3339, e.g. 2026-07-01T15:00:00Z)');\nif (!end) throw new Error('calendar_create: end is required (RFC3339)');\nconst calendarId = String(args?.calendarId ?? 'primary').trim() || 'primary';\nconst event = { summary, start: { dateTime: start }, end: { dateTime: end } };\nif (args?.description) event.description = String(args.description);\nif (args?.location) event.location = String(args.location);\nconst res = await callProvider('google', 'POST', '/calendar/v3/calendars/' + encodeURIComponent(calendarId) + '/events', event);\n// Proposed → the proposal is the record; return early without a duplicate note.\nif (res?.proposed === true) {\n return { success: false, proposed: true, proposalId: res?.proposalId ?? null, summary };\n}\nconst ok = typeof res?.status === 'number' && res.status >= 200 && res.status < 300;\nconst eventId = res?.body?.id ?? null;\nconst htmlLink = res?.body?.htmlLink ?? null;\nawait propose.entity({\n profileSlug: 'note',\n title: 'Calendar event ' + (ok ? 'created' : 'attempted') + ': ' + summary,\n properties: { action: 'calendar_create', summary, start, end, eventId, htmlLink, status: res?.status ?? null, success: ok, provenance: 'connector', provider: 'nango-google' },\n reasoning: 'Recorded the created calendar event for the activity timeline.'\n});\nreturn { success: ok, proposed: false, summary, eventId, htmlLink, status: res?.status ?? null };"
388
+ },
389
+ {
390
+ "name": "drive_search",
391
+ "intent": "search_external",
392
+ "kind": "declarative",
393
+ "scope": "pod",
394
+ "description": "Searches Google Drive files by name and returns id/name/mimeType/webViewLink. Args: { query?: string, maxResults?: number }.",
395
+ "requires": [
396
+ "google"
397
+ ],
398
+ "executionMode": "sync",
399
+ "timeoutSeconds": 60,
400
+ "parameters": {
401
+ "query": "string",
402
+ "maxResults": "number"
403
+ },
404
+ "providerSpec": {
405
+ "tool": "google",
406
+ "method": "GET",
407
+ "baseUrlOverride": "https://www.googleapis.com",
408
+ "pathTemplate": "/drive/v3/files",
409
+ "query": {
410
+ "pageSize": "{{maxResults}}",
411
+ "fields": "files(id,name,mimeType,webViewLink,modifiedTime)",
412
+ "q": "name contains '{{query}}'"
413
+ },
414
+ "paramMapping": {
415
+ "query": {
416
+ "default": ""
417
+ },
418
+ "maxResults": {
419
+ "default": 10,
420
+ "clampMin": 1,
421
+ "clampMax": 50
422
+ }
423
+ },
424
+ "responseShape": {
425
+ "collectionPath": "files",
426
+ "collectionAs": "files",
427
+ "item": {
428
+ "id": "id",
429
+ "name": "name",
430
+ "mimeType": "mimeType",
431
+ "webViewLink": "webViewLink",
432
+ "modifiedTime": "modifiedTime"
433
+ },
434
+ "scalar": {
435
+ "query": "{{query}}",
436
+ "count": "@count"
437
+ }
438
+ }
439
+ }
440
+ },
441
+ {
442
+ "name": "drive_list_folder",
443
+ "intent": "list_records",
444
+ "kind": "declarative",
445
+ "scope": "pod",
446
+ "description": "Lists the files directly inside a Google Drive folder (non-trashed) and returns id/name/mimeType/webViewLink. Args: { folderId: string, maxResults?: number }.",
447
+ "requires": [
448
+ "google"
449
+ ],
450
+ "executionMode": "sync",
451
+ "timeoutSeconds": 60,
452
+ "parameters": {
453
+ "folderId": "string",
454
+ "maxResults": "number"
455
+ },
456
+ "providerSpec": {
457
+ "tool": "google",
458
+ "method": "GET",
459
+ "baseUrlOverride": "https://www.googleapis.com",
460
+ "pathTemplate": "/drive/v3/files",
461
+ "query": {
462
+ "pageSize": "{{maxResults}}",
463
+ "fields": "files(id,name,mimeType,webViewLink,modifiedTime)",
464
+ "orderBy": "folder,name",
465
+ "q": "'{{folderId}}' in parents and trashed=false"
466
+ },
467
+ "paramMapping": {
468
+ "folderId": {
469
+ "required": true
470
+ },
471
+ "maxResults": {
472
+ "default": 25,
473
+ "clampMin": 1,
474
+ "clampMax": 100
475
+ }
476
+ },
477
+ "responseShape": {
478
+ "collectionPath": "files",
479
+ "collectionAs": "files",
480
+ "item": {
481
+ "id": "id",
482
+ "name": "name",
483
+ "mimeType": "mimeType",
484
+ "webViewLink": "webViewLink",
485
+ "modifiedTime": "modifiedTime"
486
+ },
487
+ "scalar": {
488
+ "folderId": "{{folderId}}",
489
+ "count": "@count"
490
+ }
491
+ }
492
+ }
493
+ },
494
+ {
495
+ "name": "drive_create_folder",
496
+ "intent": "manage_file",
497
+ "kind": "declarative",
498
+ "scope": "pod",
499
+ "description": "Creates a Google Drive folder inside a parent folder and returns id/name/webViewLink. Args: { name: string, parentId: string }.",
500
+ "requires": [
501
+ "google"
502
+ ],
503
+ "executionMode": "sync",
504
+ "timeoutSeconds": 60,
505
+ "parameters": {
506
+ "name": "string",
507
+ "parentId": "string"
508
+ },
509
+ "providerSpec": {
510
+ "tool": "google",
511
+ "method": "POST",
512
+ "baseUrlOverride": "https://www.googleapis.com",
513
+ "pathTemplate": "/drive/v3/files",
514
+ "query": {
515
+ "fields": "id,name,webViewLink",
516
+ "supportsAllDrives": "true"
517
+ },
518
+ "body": {
519
+ "name": "{{name}}",
520
+ "mimeType": "application/vnd.google-apps.folder",
521
+ "parents": [
522
+ "{{parentId}}"
523
+ ]
524
+ },
525
+ "paramMapping": {
526
+ "name": {
527
+ "required": true
528
+ },
529
+ "parentId": {
530
+ "required": true
531
+ }
532
+ },
533
+ "responseShape": {
534
+ "scalar": {
535
+ "id": "id",
536
+ "name": "name",
537
+ "webViewLink": "webViewLink"
538
+ }
539
+ }
540
+ }
541
+ },
542
+ {
543
+ "name": "drive_copy_file",
544
+ "intent": "manage_file",
545
+ "kind": "declarative",
546
+ "scope": "pod",
547
+ "description": "Copies a Google Drive file into a folder under a new name (copy + rename + file-into-folder in one call) and returns id/name/webViewLink. Args: { fileId: string, name: string, parentId: string }.",
548
+ "requires": [
549
+ "google"
550
+ ],
551
+ "executionMode": "sync",
552
+ "timeoutSeconds": 60,
553
+ "parameters": {
554
+ "fileId": "string",
555
+ "name": "string",
556
+ "parentId": "string"
557
+ },
558
+ "providerSpec": {
559
+ "tool": "google",
560
+ "method": "POST",
561
+ "baseUrlOverride": "https://www.googleapis.com",
562
+ "pathTemplate": "/drive/v3/files/{{fileId}}/copy",
563
+ "query": {
564
+ "fields": "id,name,webViewLink",
565
+ "supportsAllDrives": "true"
566
+ },
567
+ "body": {
568
+ "name": "{{name}}",
569
+ "parents": [
570
+ "{{parentId}}"
571
+ ]
572
+ },
573
+ "paramMapping": {
574
+ "fileId": {
575
+ "required": true,
576
+ "encode": "uri"
577
+ },
578
+ "name": {
579
+ "required": true
580
+ },
581
+ "parentId": {
582
+ "required": true
583
+ }
584
+ },
585
+ "responseShape": {
586
+ "scalar": {
587
+ "id": "id",
588
+ "name": "name",
589
+ "webViewLink": "webViewLink"
590
+ }
591
+ }
592
+ }
593
+ },
594
+ {
595
+ "name": "docs_get",
596
+ "intent": "fetch_record",
597
+ "kind": "declarative",
598
+ "scope": "pod",
599
+ "description": "Fetches a Google Doc by id and returns its title, documentId, and structured body content. Args: { documentId: string }.",
600
+ "requires": [
601
+ "google"
602
+ ],
603
+ "executionMode": "sync",
604
+ "timeoutSeconds": 60,
605
+ "parameters": {
606
+ "documentId": "string"
607
+ },
608
+ "providerSpec": {
609
+ "tool": "google",
610
+ "method": "GET",
611
+ "baseUrlOverride": "https://docs.googleapis.com",
612
+ "pathTemplate": "/v1/documents/{{documentId}}",
613
+ "paramMapping": {
614
+ "documentId": {
615
+ "required": true,
616
+ "encode": "uri"
617
+ }
618
+ },
619
+ "responseShape": {
620
+ "scalar": {
621
+ "documentId": "documentId",
622
+ "title": "title",
623
+ "body": "body"
624
+ }
625
+ }
626
+ }
627
+ }
628
+ ],
629
+ "provides": [
630
+ "send_message",
631
+ "search_external",
632
+ "list_records",
633
+ "schedule_event",
634
+ "manage_file",
635
+ "fetch_record"
636
+ ]
637
+ },
638
+ "dependencies": []
639
+ }