thinkwork-cli 0.12.12 → 0.12.15

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 (474) hide show
  1. package/README.md +42 -38
  2. package/dist/{api-client-ASJWIG3Z.js → api-client-4VT3FWOH.js} +1 -1
  3. package/dist/{chunk-JEHV35EU.js → chunk-H7AB42ES.js} +340 -30
  4. package/dist/cli.js +22123 -9219
  5. package/dist/commands/enterprise/templates/deploy-repo/.github/workflows/deploy.yml +17 -6
  6. package/dist/commands/enterprise/templates/deploy-repo/docs/runbook.md +81 -9
  7. package/dist/commands/enterprise/templates/deploy-repo/scripts/apply-release.mjs +183 -21
  8. package/dist/commands/enterprise/templates/deploy-repo/scripts/smoke.mjs +1 -2
  9. package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +286 -0
  10. package/dist/drizzle/0000_petite_marvel_apes.sql +1188 -0
  11. package/dist/drizzle/0001_milky_surge.sql +103 -0
  12. package/dist/drizzle/0002_aberrant_mattie_franklin.sql +41 -0
  13. package/dist/drizzle/0003_exotic_ogun.sql +3 -0
  14. package/dist/drizzle/0004_glamorous_magneto.sql +2 -0
  15. package/dist/drizzle/0005_ancient_nocturne.sql +2 -0
  16. package/dist/drizzle/0006_new_colonel_america.sql +2 -0
  17. package/dist/drizzle/0007_unique_external_task_id.sql +31 -0
  18. package/dist/drizzle/0008_external_task_id_column.sql +43 -0
  19. package/dist/drizzle/0009_evaluations.sql +64 -0
  20. package/dist/drizzle/0010_eval_agent_template.sql +2 -0
  21. package/dist/drizzle/0011_eval_run_template.sql +2 -0
  22. package/dist/drizzle/0012_eval_seed_unique.sql +16 -0
  23. package/dist/drizzle/0013_motionless_white_queen.sql +140 -0
  24. package/dist/drizzle/0014_wiki_aggregation.sql +11 -0
  25. package/dist/drizzle/0015_pg_trgm_alias_title_indexes.sql +9 -0
  26. package/dist/drizzle/0016_wiki_schema_drops.sql +24 -0
  27. package/dist/drizzle/0017_wiki_places.sql +46 -0
  28. package/dist/drizzle/0018_agent_workspace_overlay.sql +26 -0
  29. package/dist/drizzle/0018_cool_firebird.sql +24 -0
  30. package/dist/drizzle/0018_skill_runs.sql +84 -0
  31. package/dist/drizzle/0019_condemned_dragon_man.sql +95 -0
  32. package/dist/drizzle/0019_webhook_skill_runs.sql +58 -0
  33. package/dist/drizzle/0020_crazy_the_anarchist.sql +9 -0
  34. package/dist/drizzle/0020_mutation_idempotency.sql +64 -0
  35. package/dist/drizzle/0021_crm_work_links.sql +76 -0
  36. package/dist/drizzle/0021_skill_runs_completion_hmac.sql +33 -0
  37. package/dist/drizzle/0022_add_billing_tables.sql +70 -0
  38. package/dist/drizzle/0022_seed_thinkwork_admin_permissions.sql +160 -0
  39. package/dist/drizzle/0022_stripe_billing_indexes.sql +48 -0
  40. package/dist/drizzle/0023_tenants_deactivation.sql +27 -0
  41. package/dist/drizzle/0024_tenant_mcp_admin_keys.sql +63 -0
  42. package/dist/drizzle/0025_v1_agent_architecture.sql +182 -0
  43. package/dist/drizzle/0026_thread_turns_add_kind.sql +28 -0
  44. package/dist/drizzle/0027_capability_catalog_and_manifests.sql +219 -0
  45. package/dist/drizzle/0028_aws_s3_extension.sql +26 -0
  46. package/dist/drizzle/0029_collapse_execution_types.sql +42 -0
  47. package/dist/drizzle/0030_retire_composition_primitives.sql +48 -0
  48. package/dist/drizzle/0031_thread_cleanup_drops.sql +131 -0
  49. package/dist/drizzle/0032_add_browser_automation_template_config.sql +24 -0
  50. package/dist/drizzle/0033_agent_operation_leases.sql +32 -0
  51. package/dist/drizzle/0034_agent_workspace_events.sql +116 -0
  52. package/dist/drizzle/0035_workspace_review_decisions.sql +19 -0
  53. package/dist/drizzle/0036_user_scoped_memory_wiki.sql +152 -0
  54. package/dist/drizzle/0037_user_profile_operating_model.sql +34 -0
  55. package/dist/drizzle/0042_agent_runtime_selector.sql +41 -0
  56. package/dist/drizzle/0043_wiki_search_tsv_tokenization.sql +48 -0
  57. package/dist/drizzle/0044_add_web_search_template_config.sql +7 -0
  58. package/dist/drizzle/0045_add_send_email_template_config.sql +7 -0
  59. package/dist/drizzle/0046_tenant_mcp_context_tools.sql +26 -0
  60. package/dist/drizzle/0047_add_context_engine_template_config.sql +7 -0
  61. package/dist/drizzle/0048_tenant_context_provider_settings.sql +22 -0
  62. package/dist/drizzle/0050_brain_v0_entity_subtype.sql +29 -0
  63. package/dist/drizzle/0051_brain_v0_tenant_entity_pages.sql +170 -0
  64. package/dist/drizzle/0052_brain_v0_external_refs.sql +41 -0
  65. package/dist/drizzle/0053_brain_v0_unresolved_mentions_subtype.sql +48 -0
  66. package/dist/drizzle/0054_wiki_compile_jobs_input.sql +28 -0
  67. package/dist/drizzle/0055_routines_stepfunctions_substrate.sql +202 -0
  68. package/dist/drizzle/0056_routine_step_events_dedup_idx.sql +25 -0
  69. package/dist/drizzle/0057_archive_legacy_python_routines.sql +36 -0
  70. package/dist/drizzle/0058_routines_visibility_and_owning_agent.sql +61 -0
  71. package/dist/drizzle/0061_routine_execution_asl_version_id.sql +29 -0
  72. package/dist/drizzle/0062_migrate_pi_to_flue.sql +110 -0
  73. package/dist/drizzle/0063_threads_session_data.sql +23 -0
  74. package/dist/drizzle/0064_tenant_credentials.sql +65 -0
  75. package/dist/drizzle/0067_thinkwork_computers_phase_one.sql +174 -0
  76. package/dist/drizzle/0068_drop_system_workflows_and_activation.sql +115 -0
  77. package/dist/drizzle/0069_compliance_schema.sql +364 -0
  78. package/dist/drizzle/0070_compliance_aurora_roles.sql +171 -0
  79. package/dist/drizzle/0072_threads_computer_ownership.sql +24 -0
  80. package/dist/drizzle/0073_compliance_tenant_anchor_state.sql +105 -0
  81. package/dist/drizzle/0074_compliance_event_hash_index.sql +49 -0
  82. package/dist/drizzle/0075_scheduled_jobs_computer_ownership.sql +27 -0
  83. package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +69 -0
  84. package/dist/drizzle/0077_computers_primary_agent_id.sql +38 -0
  85. package/dist/drizzle/0078_tenant_customize_catalog.sql +46 -0
  86. package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +53 -0
  87. package/dist/drizzle/0081_routines_catalog_slug.sql +42 -0
  88. package/dist/drizzle/0082_messages_parts_jsonb.sql +52 -0
  89. package/dist/drizzle/0083_computer_runbooks.sql +103 -0
  90. package/dist/drizzle/0084_artifacts_favorited_at.sql +32 -0
  91. package/dist/drizzle/0085_seed_thinkwork_computer_default_template.sql +46 -0
  92. package/dist/drizzle/0086_update_default_template_models.sql +19 -0
  93. package/dist/drizzle/0087_retire_oss_connectors.sql +77 -0
  94. package/dist/drizzle/0088_compliance_event_types_finance_pilot.sql +37 -0
  95. package/dist/drizzle/0089_remove_maniflow_eval_seeds.sql +81 -0
  96. package/dist/drizzle/0089_wiki_schema_extraction.sql +315 -0
  97. package/dist/drizzle/0090_brain_schema_extraction.sql +274 -0
  98. package/dist/drizzle/0091_drop_wiki_brain_compat_views.sql +118 -0
  99. package/dist/drizzle/0092_finish_oss_connector_retirement.sql +97 -0
  100. package/dist/drizzle/0093_eval_runs_scheduled_job_id.sql +23 -0
  101. package/dist/drizzle/0094_slack_workspace_app.sql +140 -0
  102. package/dist/drizzle/0095_eval_runs_computer_id.sql +22 -0
  103. package/dist/drizzle/0096_true_redteam_eval_seed_cleanup.sql +67 -0
  104. package/dist/drizzle/0097_shared_computers.sql +191 -0
  105. package/dist/drizzle/0098_business_ontology.sql +587 -0
  106. package/dist/drizzle/0099_thread_idle_learning.sql +145 -0
  107. package/dist/drizzle/0100_ontology_gated_brain_dynamic_subtypes.sql +7 -0
  108. package/dist/drizzle/0101_ontology_gated_unresolved_mentions_dynamic_subtypes.sql +7 -0
  109. package/dist/drizzle/0102_wiki_brain_owner_repair.sql +87 -0
  110. package/dist/drizzle/0103_brain_section_source_trigger_repair.sql +75 -0
  111. package/dist/drizzle/0104_expand_seed_ontology_for_user_memory.sql +166 -0
  112. package/dist/drizzle/0105_spaces_domain.sql +349 -0
  113. package/dist/drizzle/0106_expand_seed_ontology_for_triples.sql +173 -0
  114. package/dist/drizzle/0106_space_threads_participants.sql +197 -0
  115. package/dist/drizzle/0107_linked_task_mirror.sql +245 -0
  116. package/dist/drizzle/0108_message_mentions.sql +95 -0
  117. package/dist/drizzle/0109_space_owned_threads.sql +217 -0
  118. package/dist/drizzle/0110_thread_participant_read_state.sql +21 -0
  119. package/dist/drizzle/0111_agents_tenant_name_unique.sql +38 -0
  120. package/dist/drizzle/0112_recast_spaces_as_contextual_workrooms.sql +138 -0
  121. package/dist/drizzle/0113_agents_own_runtime_fields.sql +48 -0
  122. package/dist/drizzle/0114_migrate_templates_to_agents_and_spaces.sql +361 -0
  123. package/dist/drizzle/0115_remove_computer_eval_template_dependencies.sql +69 -0
  124. package/dist/drizzle/0116_backfill_thread_participants_access.sql +126 -0
  125. package/dist/drizzle/0117_space_access_mode.sql +40 -0
  126. package/dist/drizzle/0118_normalize_tenant_member_principal_type.sql +41 -0
  127. package/dist/drizzle/0119_space_knowledge_bases.sql +126 -0
  128. package/dist/drizzle/0120_space_automations.sql +58 -0
  129. package/dist/drizzle/0121_drop_computer_runbooks.sql +26 -0
  130. package/dist/drizzle/0122_space_email_triggers.sql +24 -0
  131. package/dist/drizzle/0123_single_platform_agent_and_overrides.sql +58 -0
  132. package/dist/drizzle/0124_thread_turns_finalized_at.sql +17 -0
  133. package/dist/drizzle/0125_drop_space_agent_assignments.sql +42 -0
  134. package/dist/drizzle/0126_migrate_flue_to_pi.sql +42 -0
  135. package/dist/drizzle/0127_runtime_type_observability.sql +28 -0
  136. package/dist/drizzle/0128_drop_eval_test_cases_agent_id.sql +37 -0
  137. package/dist/drizzle/0129_drop_code_factory_tables.sql +43 -0
  138. package/dist/drizzle/0129_eval_results_system_prompt.sql +30 -0
  139. package/dist/drizzle/0130_drop_teams_and_team_id_columns.sql +54 -0
  140. package/dist/drizzle/0131_drop_skill_catalog_and_tenant_skills.sql +33 -0
  141. package/dist/drizzle/0132_drop_computer_tables.sql +31 -0
  142. package/dist/drizzle/0133_drop_seed_view_tombstones.sql +79 -0
  143. package/dist/drizzle/0133_thread_turns_system_prompt.sql +22 -0
  144. package/dist/drizzle/0134_drop_dead_agent_runtime_tables.sql +53 -0
  145. package/dist/drizzle/0135_native_checklist_linked_tasks.sql +48 -0
  146. package/dist/drizzle/0136_goal_ledger.sql +55 -0
  147. package/dist/drizzle/0136_space_email_trigger_status.sql +66 -0
  148. package/dist/drizzle/0137_thread_participant_pins.sql +25 -0
  149. package/dist/drizzle/0138_users_cognito_sub.sql +30 -0
  150. package/dist/drizzle/0139_mobile_turn_client_id.sql +23 -0
  151. package/dist/drizzle/0140_workspace_folder_names.sql +36 -0
  152. package/dist/drizzle/0141_eval_runs_desktop_pi_provenance.sql +31 -0
  153. package/dist/drizzle/0142_pi_only_agent_runtime.sql +61 -0
  154. package/dist/drizzle/0143_add_web_extract_builtin_config.sql +28 -0
  155. package/dist/drizzle/0144_skill_catalog_index.sql +40 -0
  156. package/dist/drizzle/0145_knowledge_graph_thread_ingest.sql +512 -0
  157. package/dist/drizzle/0146_knowledge_graph_source_scope.sql +413 -0
  158. package/dist/drizzle/0147_knowledge_graph_scope_trigger_qualification.sql +211 -0
  159. package/dist/drizzle/0148_user_cost_attribution.sql +171 -0
  160. package/dist/drizzle/0149_managed_mcp_servers.sql +64 -0
  161. package/dist/drizzle/0149_user_model_approvals.sql +89 -0
  162. package/dist/drizzle/0150_bootstrap_first_admin_claim.sql +11 -0
  163. package/dist/drizzle/0151_managed_deployments.sql +91 -0
  164. package/dist/drizzle/0152_agent_profiles.sql +81 -0
  165. package/dist/drizzle/0153_message_mentions_agent_profile.sql +9 -0
  166. package/dist/drizzle/0154_customer_deployment_sessions.sql +61 -0
  167. package/dist/drizzle/0155_tenant_model_catalog.sql +152 -0
  168. package/dist/drizzle/0156_bootstrap_credential_leases.sql +52 -0
  169. package/dist/drizzle/0157_knowledge_graph_observations_source.sql +79 -0
  170. package/dist/drizzle/0158_pending_user_questions.sql +80 -0
  171. package/dist/drizzle/0158_wiki_tenant_scope.sql +38 -0
  172. package/dist/drizzle/0159_agent_profiles_space_local.sql +49 -0
  173. package/dist/drizzle/0159_application_plugins.sql +193 -0
  174. package/dist/drizzle/0159_eval_scoring_version.sql +46 -0
  175. package/dist/drizzle/0160_compliance_event_types_plugins.sql +37 -0
  176. package/dist/drizzle/0160_eval_datasets.sql +75 -0
  177. package/dist/drizzle/0160_eval_results_thread_turn.sql +35 -0
  178. package/dist/drizzle/0161_eval_run_pinning.sql +54 -0
  179. package/dist/drizzle/0161_tenant_mcp_servers_plugin_source.sql +62 -0
  180. package/dist/drizzle/0162_eval_result_override.sql +49 -0
  181. package/dist/drizzle/0163_eval_replay_tool_allowlist.sql +50 -0
  182. package/dist/drizzle/0164_eval_replay_tool_override_mode.sql +52 -0
  183. package/dist/drizzle/0165_plugin_premium_entitlements.sql +153 -0
  184. package/dist/drizzle/0166_company_brain_substrate_contract.sql +386 -0
  185. package/dist/drizzle/0167_company_brain_artifact_manifest_runtime.sql +85 -0
  186. package/dist/drizzle/0168_eval_skill_gate.sql +44 -0
  187. package/dist/drizzle/0169_release_update_jobs.sql +67 -0
  188. package/dist/drizzle/0170_email_channel_plugin.sql +291 -0
  189. package/dist/drizzle/0171_linked_task_external_providers.sql +30 -0
  190. package/dist/drizzle/0172_email_channel_sendgrid_provider.sql +8 -0
  191. package/dist/drizzle/0173_auth_provider_resources.sql +83 -0
  192. package/dist/drizzle/0174_workos_auth_bridges.sql +37 -0
  193. package/dist/drizzle/0175_workos_auth_sessions.sql +38 -0
  194. package/dist/drizzle/0176_n8n_agent_step_runs.sql +107 -0
  195. package/dist/drizzle/0177_workflow_control_plane.sql +281 -0
  196. package/dist/drizzle/0178_workflow_backfill_existing_routines.sql +525 -0
  197. package/dist/drizzle/0179_tenant_goal_budget_settings.sql +21 -0
  198. package/dist/drizzle/0180_skill_drafts.sql +89 -0
  199. package/dist/drizzle/0181_skill_draft_publish_status.sql +21 -0
  200. package/dist/drizzle/0182_agent_loops.sql +260 -0
  201. package/dist/drizzle/0183_okf_artifact_manifests.sql +52 -0
  202. package/dist/drizzle/0184_skill_catalog_trust_cache.sql +35 -0
  203. package/dist/drizzle/0185_agent_loop_space.sql +16 -0
  204. package/dist/drizzle/0186_tenant_mcp_runtime_metadata.sql +10 -0
  205. package/dist/drizzle/0187_native_work_items.sql +220 -0
  206. package/dist/drizzle/0188_company_etl_plugin_rename.sql +99 -0
  207. package/dist/drizzle/0189_trace_cost_substrate.sql +247 -0
  208. package/dist/drizzle/0190_billing_export_reconciliation.sql +101 -0
  209. package/dist/drizzle/0191_open_engine_work_item_queue.sql +66 -0
  210. package/dist/drizzle/0192_work_item_labels.sql +44 -0
  211. package/dist/drizzle/0193_work_item_documents.sql +31 -0
  212. package/dist/drizzle/0194_memory_retain_attempts.sql +103 -0
  213. package/dist/drizzle/0194_work_item_comments.sql +35 -0
  214. package/dist/drizzle/0195_plugin_app_overlays.sql +45 -0
  215. package/dist/drizzle/0196_pi_extensions.sql +118 -0
  216. package/dist/drizzle/0197_eval_profiles.sql +150 -0
  217. package/dist/drizzle/0198_eval_runs_unstable.sql +27 -0
  218. package/dist/drizzle/0199_eval_runs_cost_partial.sql +27 -0
  219. package/dist/drizzle/meta/_journal.json +160 -0
  220. package/dist/plugins/README.md +162 -0
  221. package/dist/plugins/catalog/package.json +40 -0
  222. package/dist/plugins/catalog/scripts/build-catalog.ts +120 -0
  223. package/dist/plugins/catalog/scripts/generate-plugin-registry.ts +144 -0
  224. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +86 -0
  225. package/dist/plugins/catalog/src/__tests__/catalog.test.ts +308 -0
  226. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +861 -0
  227. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +124 -0
  228. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +120 -0
  229. package/dist/plugins/catalog/src/catalog.ts +434 -0
  230. package/dist/plugins/catalog/src/contracts.ts +1498 -0
  231. package/dist/plugins/catalog/src/index.ts +4 -0
  232. package/dist/plugins/catalog/src/plugin-package.ts +171 -0
  233. package/dist/plugins/catalog/src/registry/generated-first-party.ts +76 -0
  234. package/dist/plugins/catalog/src/registry/index.ts +1 -0
  235. package/dist/plugins/catalog/tsconfig.json +8 -0
  236. package/dist/plugins/company-brain/README.md +37 -0
  237. package/dist/plugins/company-brain/package.json +33 -0
  238. package/dist/plugins/company-brain/runtime/cognee/Dockerfile +11 -0
  239. package/dist/plugins/company-brain/smoke/cognee-managed-app-smoke.mjs +458 -0
  240. package/dist/plugins/company-brain/smoke/cognee-memory-cutover-smoke.mjs +539 -0
  241. package/dist/plugins/company-brain/smoke/company-brain-context-engine-smoke.mjs +312 -0
  242. package/dist/plugins/company-brain/smoke/company-brain-operations-smoke.mjs +449 -0
  243. package/dist/plugins/company-brain/smoke/company-brain-plugin-smoke.mjs +655 -0
  244. package/dist/plugins/company-brain/smoke/hindsight-memory-isolation-smoke.mjs +474 -0
  245. package/dist/plugins/company-brain/src/api/cognee-client.ts +896 -0
  246. package/dist/plugins/company-brain/src/api/cognee-cluster-identity.ts +49 -0
  247. package/dist/plugins/company-brain/src/api/cognee-memory-scope.ts +84 -0
  248. package/dist/plugins/company-brain/src/api/context-engine-provider.ts +888 -0
  249. package/dist/plugins/company-brain/src/api/migration.ts +665 -0
  250. package/dist/plugins/company-brain/src/deployment/cognee-managed-app.ts +396 -0
  251. package/dist/plugins/company-brain/src/index.ts +62 -0
  252. package/dist/plugins/company-brain/src/manifest.ts +112 -0
  253. package/dist/plugins/company-brain/terraform/cognee/README.md +263 -0
  254. package/dist/plugins/company-brain/terraform/cognee/main.tf +766 -0
  255. package/dist/plugins/company-brain/terraform/cognee/outputs.tf +144 -0
  256. package/dist/plugins/company-brain/terraform/cognee/variables.tf +402 -0
  257. package/dist/plugins/company-brain/test/api/cognee-client.test.ts +562 -0
  258. package/dist/plugins/company-brain/test/api/cognee-memory-scope.test.ts +74 -0
  259. package/dist/plugins/company-brain/test/api/context-engine-provider.test.ts +447 -0
  260. package/dist/plugins/company-brain/test/api/migration.test.ts +465 -0
  261. package/dist/plugins/company-brain/test/manifest.test.ts +95 -0
  262. package/dist/plugins/company-brain/tsconfig.json +8 -0
  263. package/dist/plugins/company-data/README.md +49 -0
  264. package/dist/plugins/company-data/package.json +21 -0
  265. package/dist/plugins/company-data/src/index.ts +30 -0
  266. package/dist/plugins/company-data/src/manifest.ts +26 -0
  267. package/dist/plugins/company-data/test/manifest.test.ts +116 -0
  268. package/dist/plugins/company-data/tsconfig.json +8 -0
  269. package/dist/plugins/company-etl/README.md +46 -0
  270. package/dist/plugins/company-etl/package.json +21 -0
  271. package/dist/plugins/company-etl/src/index.ts +29 -0
  272. package/dist/plugins/company-etl/src/manifest.ts +26 -0
  273. package/dist/plugins/company-etl/test/manifest.test.ts +108 -0
  274. package/dist/plugins/company-etl/tsconfig.json +8 -0
  275. package/dist/plugins/email-channel/README.md +41 -0
  276. package/dist/plugins/email-channel/package.json +22 -0
  277. package/dist/plugins/email-channel/src/index.ts +36 -0
  278. package/dist/plugins/email-channel/src/manifest.ts +44 -0
  279. package/dist/plugins/email-channel/src/provider-contract.ts +36 -0
  280. package/dist/plugins/email-channel/test/manifest.test.ts +119 -0
  281. package/dist/plugins/email-channel/tsconfig.json +8 -0
  282. package/dist/plugins/lastmile/README.md +50 -0
  283. package/dist/plugins/lastmile/package.json +23 -0
  284. package/dist/plugins/lastmile/smoke/lastmile-plugin-smoke.mjs +661 -0
  285. package/dist/plugins/lastmile/src/api/tasks-adapter.ts +572 -0
  286. package/dist/plugins/lastmile/src/discovery.fixture.ts +64 -0
  287. package/dist/plugins/lastmile/src/index.ts +46 -0
  288. package/dist/plugins/lastmile/src/manifest.ts +139 -0
  289. package/dist/plugins/lastmile/test/api/tasks-adapter.test.ts +266 -0
  290. package/dist/plugins/lastmile/test/discovery.test.ts +88 -0
  291. package/dist/plugins/lastmile/tsconfig.json +8 -0
  292. package/dist/plugins/n8n/README.md +201 -0
  293. package/dist/plugins/n8n/n8n-app/README.md +33 -0
  294. package/dist/plugins/n8n/n8n-app/package.json +23 -0
  295. package/dist/plugins/n8n/n8n-app/src/application-config.ts +45 -0
  296. package/dist/plugins/n8n/n8n-app/src/front-components/thinkwork-workflows.front-component.tsx +970 -0
  297. package/dist/plugins/n8n/n8n-app/src/lib/n8n-app-data.ts +190 -0
  298. package/dist/plugins/n8n/n8n-app/src/vite-env.d.ts +7 -0
  299. package/dist/plugins/n8n/n8n-app/tsconfig.json +15 -0
  300. package/dist/plugins/n8n/package.json +35 -0
  301. package/dist/plugins/n8n/runtime/Dockerfile +18 -0
  302. package/dist/plugins/n8n/runtime/n8n-task-runners.json +14 -0
  303. package/dist/plugins/n8n/runtime/n8n-task-runners.json.template +14 -0
  304. package/dist/plugins/n8n/runtime/package-lock.json +13 -0
  305. package/dist/plugins/n8n/runtime/package.json +7 -0
  306. package/dist/plugins/n8n/scripts/sync-thinkwork-app.mjs +268 -0
  307. package/dist/plugins/n8n/smoke/README.md +95 -0
  308. package/dist/plugins/n8n/smoke/n8n-agent-step-bridge-smoke.mjs +866 -0
  309. package/dist/plugins/n8n/smoke/n8n-integrated-app-smoke.mjs +262 -0
  310. package/dist/plugins/n8n/smoke/n8n-managed-app-smoke.mjs +409 -0
  311. package/dist/plugins/n8n/smoke/n8n-mcp-smoke.mjs +624 -0
  312. package/dist/plugins/n8n/src/deployment/image-build.ts +172 -0
  313. package/dist/plugins/n8n/src/deployment/managed-app.ts +429 -0
  314. package/dist/plugins/n8n/src/index.ts +79 -0
  315. package/dist/plugins/n8n/src/manifest.ts +403 -0
  316. package/dist/plugins/n8n/src/package-config.ts +186 -0
  317. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/SKILL.md +76 -0
  318. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/mcp-tooling.md +40 -0
  319. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/validation-and-handoff.md +40 -0
  320. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/workflow-authoring.md +45 -0
  321. package/dist/plugins/n8n/terraform/n8n/README.md +113 -0
  322. package/dist/plugins/n8n/terraform/n8n/main.tf +918 -0
  323. package/dist/plugins/n8n/terraform/n8n/outputs.tf +124 -0
  324. package/dist/plugins/n8n/terraform/n8n/scripts/sync-database.py +250 -0
  325. package/dist/plugins/n8n/terraform/n8n/scripts/test_sync_database.py +55 -0
  326. package/dist/plugins/n8n/terraform/n8n/variables.tf +354 -0
  327. package/dist/plugins/n8n/test/image-build.test.ts +118 -0
  328. package/dist/plugins/n8n/test/integrated-app-contract.test.ts +353 -0
  329. package/dist/plugins/n8n/test/manifest.test.ts +278 -0
  330. package/dist/plugins/n8n/test/package-config.test.ts +57 -0
  331. package/dist/plugins/n8n/tsconfig.json +8 -0
  332. package/dist/plugins/sendgrid/README.md +30 -0
  333. package/dist/plugins/sendgrid/package.json +22 -0
  334. package/dist/plugins/sendgrid/src/index.ts +36 -0
  335. package/dist/plugins/sendgrid/src/manifest.ts +37 -0
  336. package/dist/plugins/sendgrid/src/provider-contract.ts +14 -0
  337. package/dist/plugins/sendgrid/test/manifest.test.ts +80 -0
  338. package/dist/plugins/sendgrid/tsconfig.json +8 -0
  339. package/dist/plugins/twenty/README.md +78 -0
  340. package/dist/plugins/twenty/package.json +27 -0
  341. package/dist/plugins/twenty/scripts/__tests__/sync-thinkwork-app.test.mjs +67 -0
  342. package/dist/plugins/twenty/scripts/sync-thinkwork-app.mjs +185 -0
  343. package/dist/plugins/twenty/scripts/wire-thinkwork-workflow.mjs +658 -0
  344. package/dist/plugins/twenty/smoke/twenty-managed-app-smoke.mjs +359 -0
  345. package/dist/plugins/twenty/smoke/twenty-mcp-oauth-smoke.mjs +574 -0
  346. package/dist/plugins/twenty/src/api/cutover.ts +209 -0
  347. package/dist/plugins/twenty/src/deployment/managed-app.ts +253 -0
  348. package/dist/plugins/twenty/src/index.ts +55 -0
  349. package/dist/plugins/twenty/src/manifest.ts +259 -0
  350. package/dist/plugins/twenty/terraform/twenty/README.md +97 -0
  351. package/dist/plugins/twenty/terraform/twenty/main.tf +829 -0
  352. package/dist/plugins/twenty/terraform/twenty/outputs.tf +79 -0
  353. package/dist/plugins/twenty/terraform/twenty/variables.tf +268 -0
  354. package/dist/plugins/twenty/test/api/cutover.test.ts +183 -0
  355. package/dist/plugins/twenty/test/manifest.test.ts +463 -0
  356. package/dist/plugins/twenty/tsconfig.json +9 -0
  357. package/dist/plugins/twenty/twenty-app/.nvmrc +1 -0
  358. package/dist/plugins/twenty/twenty-app/README.md +148 -0
  359. package/dist/plugins/twenty/twenty-app/package.json +30 -0
  360. package/dist/plugins/twenty/twenty-app/src/application-config.ts +44 -0
  361. package/dist/plugins/twenty/twenty-app/src/constants/universal-identifiers.ts +18 -0
  362. package/dist/plugins/twenty/twenty-app/src/default-role.ts +24 -0
  363. package/dist/plugins/twenty/twenty-app/src/front-components/thinkwork-settings.front-component.tsx +299 -0
  364. package/dist/plugins/twenty/twenty-app/src/logic-functions/thinkwork-webhook.logic-function.ts +354 -0
  365. package/dist/plugins/twenty/twenty-app/tsconfig.json +14 -0
  366. package/dist/plugins/twenty/twenty-app/yarn.lock +4144 -0
  367. package/dist/plugins/workos-auth/package.json +22 -0
  368. package/dist/plugins/workos-auth/src/index.ts +30 -0
  369. package/dist/plugins/workos-auth/src/manifest.ts +40 -0
  370. package/dist/plugins/workos-auth/src/provider-contract.ts +39 -0
  371. package/dist/plugins/workos-auth/test/manifest.test.ts +94 -0
  372. package/dist/plugins/workos-auth/tsconfig.json +8 -0
  373. package/dist/scripts/bootstrap-workspace.sh +162 -0
  374. package/dist/scripts/post-deploy.sh +290 -0
  375. package/dist/terraform/examples/greenfield/main.tf +903 -75
  376. package/dist/terraform/examples/greenfield/terraform.tfvars.example +67 -8
  377. package/dist/terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base +2 -2
  378. package/dist/terraform/modules/app/agentcore-code-interpreter/README.md +8 -9
  379. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/sitecustomize.py +227 -0
  380. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/test_sitecustomize.py +277 -0
  381. package/dist/terraform/modules/app/agentcore-memory/README.md +6 -6
  382. package/dist/terraform/modules/app/agentcore-memory/main.tf +1 -1
  383. package/dist/terraform/modules/app/agentcore-memory/scripts/create_or_find_memory.sh +40 -9
  384. package/dist/terraform/modules/app/agentcore-pi/README.md +61 -0
  385. package/dist/terraform/modules/app/agentcore-pi/main.tf +453 -0
  386. package/dist/terraform/modules/app/agentcore-pi/outputs.tf +38 -0
  387. package/dist/terraform/modules/app/agentcore-pi/variables.tf +145 -0
  388. package/dist/terraform/modules/app/agentcore-platform/main.tf +83 -0
  389. package/dist/terraform/modules/app/agentcore-runtime/main.tf +9 -11
  390. package/dist/terraform/modules/app/appsync-subscriptions/main.tf +5 -1
  391. package/dist/terraform/modules/app/customer-domain/main.tf +483 -0
  392. package/dist/terraform/modules/app/deployment-control-plane/README.md +47 -0
  393. package/dist/terraform/modules/app/deployment-control-plane/buildspec.yml +24 -0
  394. package/dist/terraform/modules/app/deployment-control-plane/main.tf +614 -0
  395. package/dist/terraform/modules/app/deployment-control-plane/outputs.tf +54 -0
  396. package/dist/terraform/modules/app/deployment-control-plane/runner.py +4720 -0
  397. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +3026 -0
  398. package/dist/terraform/modules/app/deployment-control-plane/variables.tf +96 -0
  399. package/dist/terraform/modules/app/hindsight-memory/README.md +25 -23
  400. package/dist/terraform/modules/app/hindsight-memory/main.tf +26 -2
  401. package/dist/terraform/modules/app/lambda-api/eval-fanout.tf +17 -50
  402. package/dist/terraform/modules/app/lambda-api/handlers.tf +1290 -679
  403. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +933 -0
  404. package/dist/terraform/modules/app/lambda-api/main.tf +14 -527
  405. package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +3 -19
  406. package/dist/terraform/modules/app/lambda-api/outputs.tf +50 -6
  407. package/dist/terraform/modules/app/lambda-api/runtime-config.tf +163 -0
  408. package/dist/terraform/modules/app/lambda-api/slack-app-secrets.tf +3 -1
  409. package/dist/terraform/modules/app/lambda-api/stripe-secrets.tf +3 -1
  410. package/dist/terraform/modules/app/lambda-api/variables.tf +240 -53
  411. package/dist/terraform/modules/app/lambda-api/workspace-events.tf +2 -25
  412. package/dist/terraform/modules/app/ses-email/main.tf +143 -30
  413. package/dist/terraform/modules/app/static-site/main.tf +4 -3
  414. package/dist/terraform/modules/app/www-dns/main.tf +45 -5
  415. package/dist/terraform/modules/app/www-dns/outputs.tf +10 -0
  416. package/dist/terraform/modules/app/www-dns/variables.tf +24 -0
  417. package/dist/terraform/modules/data/aurora-postgres/main.tf +15 -1
  418. package/dist/terraform/modules/data/compliance-exports-bucket/main.tf +1 -1
  419. package/dist/terraform/modules/data/compliance-exports-bucket/variables.tf +6 -0
  420. package/dist/terraform/modules/foundation/cognito/main.tf +167 -11
  421. package/dist/terraform/modules/foundation/cognito/outputs.tf +5 -0
  422. package/dist/terraform/modules/foundation/cognito/variables.tf +110 -0
  423. package/dist/terraform/modules/foundation/vpc/main.tf +45 -3
  424. package/dist/terraform/modules/foundation/vpc/outputs.tf +20 -0
  425. package/dist/terraform/modules/foundation/vpc/variables.tf +18 -0
  426. package/dist/terraform/modules/thinkwork/README.md +71 -0
  427. package/dist/terraform/modules/thinkwork/main.tf +1325 -174
  428. package/dist/terraform/modules/thinkwork/outputs.tf +457 -24
  429. package/dist/terraform/modules/thinkwork/variables.tf +1169 -93
  430. package/dist/terraform/schema.graphql +82 -9
  431. package/dist/workspace-defaults/files/AGENTS.md +344 -0
  432. package/dist/workspace-defaults/files/CONTEXT.md +8 -0
  433. package/dist/workspace-defaults/files/GUARDRAILS.md +51 -0
  434. package/dist/workspace-defaults/files/MEMORY_GUIDE.md +65 -0
  435. package/dist/workspace-defaults/files/ROUTER.md +24 -0
  436. package/dist/workspace-defaults/files/SPACE.md +62 -0
  437. package/dist/workspace-defaults/files/TOOLS.md +65 -0
  438. package/dist/workspace-defaults/files/USER.md +40 -0
  439. package/dist/workspace-defaults/files/mcp.json +3 -0
  440. package/dist/workspace-defaults/files/memory/contacts.md +13 -0
  441. package/dist/workspace-defaults/files/memory/lessons.md +13 -0
  442. package/dist/workspace-defaults/files/memory/preferences.md +12 -0
  443. package/dist/workspace-defaults/files/skills/.gitkeep +1 -0
  444. package/dist/workspace-defaults/files/skills/artifact-builder/SKILL.md +79 -0
  445. package/dist/workspace-defaults/files/skills/artifact-builder/references/crm-dashboard.md +166 -0
  446. package/dist/workspace-defaults/files/skills/automation-loop-designer/SKILL.md +120 -0
  447. package/dist/workspace-defaults/files/skills/skill-creator/LICENSE.txt +202 -0
  448. package/dist/workspace-defaults/files/skills/skill-creator/SKILL.md +485 -0
  449. package/dist/workspace-defaults/files/skills/skill-creator/UPSTREAM.json +124 -0
  450. package/dist/workspace-defaults/files/skills/skill-creator/agents/analyzer.md +274 -0
  451. package/dist/workspace-defaults/files/skills/skill-creator/agents/comparator.md +202 -0
  452. package/dist/workspace-defaults/files/skills/skill-creator/agents/grader.md +223 -0
  453. package/dist/workspace-defaults/files/skills/skill-creator/assets/eval_review.html +146 -0
  454. package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  455. package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  456. package/dist/workspace-defaults/files/skills/skill-creator/references/schemas.md +430 -0
  457. package/dist/workspace-defaults/files/skills/skill-creator/scripts/__init__.py +0 -0
  458. package/dist/workspace-defaults/files/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  459. package/dist/workspace-defaults/files/skills/skill-creator/scripts/generate_report.py +326 -0
  460. package/dist/workspace-defaults/files/skills/skill-creator/scripts/improve_description.py +247 -0
  461. package/dist/workspace-defaults/files/skills/skill-creator/scripts/package_skill.py +136 -0
  462. package/dist/workspace-defaults/files/skills/skill-creator/scripts/quick_validate.py +103 -0
  463. package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_eval.py +310 -0
  464. package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_loop.py +328 -0
  465. package/dist/workspace-defaults/files/skills/skill-creator/scripts/utils.py +47 -0
  466. package/package.json +1 -1
  467. package/dist/terraform/modules/app/agentcore-flue/README.md +0 -58
  468. package/dist/terraform/modules/app/agentcore-flue/main.tf +0 -323
  469. package/dist/terraform/modules/app/agentcore-flue/outputs.tf +0 -23
  470. package/dist/terraform/modules/app/agentcore-flue/variables.tf +0 -97
  471. package/dist/terraform/modules/app/computer-runtime/README.md +0 -15
  472. package/dist/terraform/modules/app/computer-runtime/main.tf +0 -406
  473. package/dist/terraform/modules/app/computer-runtime/outputs.tf +0 -75
  474. package/dist/terraform/modules/app/computer-runtime/variables.tf +0 -66
@@ -1,15 +1,19 @@
1
1
  ################################################################################
2
2
  # SES Email — App Module
3
3
  #
4
- # Wires up inbound and outbound email for a delegated subdomain
5
- # (e.g. agents.thinkwork.ai). The module:
4
+ # Wires up inbound and outbound email for a legacy delegated subdomain
5
+ # (e.g. agents.thinkwork.ai) plus delegated tenant subdomains
6
+ # (e.g. acme.thinkwork.ai). The module:
6
7
  #
7
- # 1. Creates a Route53 hosted zone for the subdomain (Option A — delegated
8
- # subzone). The operator pastes the output name servers at whatever hosts
9
- # the parent domain (Google, Squarespace, Cloudflare, etc.).
10
- # 2. Creates the SES domain identity + DKIM tokens.
11
- # 3. Writes the SES verification TXT, DKIM CNAMEs, and an MX record into the
12
- # new subzone.
8
+ # 1. Keeps the legacy Route53 hosted zone for agents.thinkwork.ai when
9
+ # configured, and creates one Route53 hosted zone per tenant subdomain
10
+ # (Option A delegated subzones). The operator publishes each output
11
+ # name-server set at whatever hosts the parent domain (Cloudflare, Google,
12
+ # etc.).
13
+ # 2. Creates SES domain identities + DKIM token sets for the configured
14
+ # legacy domain and each tenant subdomain.
15
+ # 3. Writes SES verification TXT, DKIM CNAME, and MX records into the matching
16
+ # subzone.
13
17
  # 4. Creates an SES receipt rule set that stores inbound mail in S3 at
14
18
  # `email/inbound/<sesMessageId>` and invokes the email-inbound Lambda.
15
19
  ################################################################################
@@ -30,12 +34,24 @@ variable "region" {
30
34
  default = "us-east-1"
31
35
  }
32
36
 
37
+ variable "parent_domain" {
38
+ description = "Parent domain for tenant email subdomains (e.g. thinkwork.ai). Leave empty to skip all SES resources."
39
+ type = string
40
+ default = ""
41
+ }
42
+
33
43
  variable "email_domain" {
34
- description = "Subdomain used for agent email (e.g. agents.thinkwork.ai). Leave empty to skip all SES resources."
44
+ description = "Legacy delegated subdomain used for agent email (e.g. agents.thinkwork.ai). Kept until legacy-address retirement notices are no longer needed."
35
45
  type = string
36
46
  default = ""
37
47
  }
38
48
 
49
+ variable "tenant_slugs" {
50
+ description = "Tenant slugs to provision as SES receiving subdomains under parent_domain. Each slug creates <slug>.<parent_domain>."
51
+ type = set(string)
52
+ default = []
53
+ }
54
+
39
55
  variable "inbound_bucket_name" {
40
56
  description = "S3 bucket that SES writes raw inbound .eml files into. Its policy must already allow ses.amazonaws.com PutObject."
41
57
  type = string
@@ -54,6 +70,12 @@ variable "email_inbound_fn_name" {
54
70
  default = ""
55
71
  }
56
72
 
73
+ variable "enable_email_inbound_lambda_action" {
74
+ description = "Attach the email-inbound Lambda action and invoke permission to SES receipt rules."
75
+ type = bool
76
+ default = false
77
+ }
78
+
57
79
  variable "manage_active_rule_set" {
58
80
  description = "Activate the receipt rule set. Only ONE rule set can be active per region per account, so set false in secondary stages that share an account."
59
81
  type = bool
@@ -61,19 +83,34 @@ variable "manage_active_rule_set" {
61
83
  }
62
84
 
63
85
  locals {
64
- enabled = var.email_domain != ""
86
+ tenant_slugs = toset(var.tenant_slugs)
87
+ legacy_enabled = var.email_domain != ""
88
+ tenant_enabled = var.parent_domain != "" && length(local.tenant_slugs) > 0
89
+ enabled = local.legacy_enabled || local.tenant_enabled
90
+
91
+ tenant_domains = {
92
+ for slug in local.tenant_slugs : slug => "${slug}.${var.parent_domain}"
93
+ }
94
+
95
+ tenant_dkim_records = local.tenant_enabled ? {
96
+ for pair in setproduct(sort(tolist(local.tenant_slugs)), range(3)) : "${pair[0]}-${pair[1]}" => {
97
+ slug = pair[0]
98
+ index = pair[1]
99
+ }
100
+ } : {}
101
+
65
102
  inbound_smtp = "inbound-smtp.${var.region}.amazonaws.com"
66
103
  rule_set_name = "thinkwork-${var.stage}-email-rules"
67
- has_lambda = var.email_inbound_fn_arn != ""
104
+ has_lambda = var.enable_email_inbound_lambda_action && var.email_inbound_fn_arn != "" && var.email_inbound_fn_name != ""
68
105
  has_bucket = var.inbound_bucket_name != ""
69
106
  }
70
107
 
71
108
  ################################################################################
72
- # Route53 — delegated subzone for the agent email subdomain
109
+ # Route53 — delegated subzones for legacy + tenant email subdomains
73
110
  ################################################################################
74
111
 
75
112
  resource "aws_route53_zone" "agents" {
76
- count = local.enabled ? 1 : 0
113
+ count = local.legacy_enabled ? 1 : 0
77
114
  name = var.email_domain
78
115
 
79
116
  tags = {
@@ -82,26 +119,47 @@ resource "aws_route53_zone" "agents" {
82
119
  }
83
120
  }
84
121
 
122
+ resource "aws_route53_zone" "tenant" {
123
+ for_each = local.tenant_enabled ? local.tenant_domains : {}
124
+ name = each.value
125
+
126
+ tags = {
127
+ Name = "thinkwork-${var.stage}-${each.key}-email-zone"
128
+ Stage = var.stage
129
+ TenantSlug = each.key
130
+ }
131
+ }
132
+
85
133
  ################################################################################
86
- # SES Domain Identity + DKIM
134
+ # SES Domain Identities + DKIM for legacy + tenant subdomains
87
135
  ################################################################################
88
136
 
89
137
  resource "aws_ses_domain_identity" "main" {
90
- count = local.enabled ? 1 : 0
138
+ count = local.legacy_enabled ? 1 : 0
91
139
  domain = var.email_domain
92
140
  }
93
141
 
94
142
  resource "aws_ses_domain_dkim" "main" {
95
- count = local.enabled ? 1 : 0
143
+ count = local.legacy_enabled ? 1 : 0
96
144
  domain = aws_ses_domain_identity.main[0].domain
97
145
  }
98
146
 
147
+ resource "aws_ses_domain_identity" "tenant" {
148
+ for_each = local.tenant_enabled ? local.tenant_domains : {}
149
+ domain = each.value
150
+ }
151
+
152
+ resource "aws_ses_domain_dkim" "tenant" {
153
+ for_each = local.tenant_enabled ? local.tenant_domains : {}
154
+ domain = aws_ses_domain_identity.tenant[each.key].domain
155
+ }
156
+
99
157
  ################################################################################
100
- # DNS records in the subzone — verification TXT, DKIM CNAMEs, MX
158
+ # DNS records in legacy + tenant subzones — verification TXT, DKIM CNAMEs, MX
101
159
  ################################################################################
102
160
 
103
161
  resource "aws_route53_record" "ses_verification" {
104
- count = local.enabled ? 1 : 0
162
+ count = local.legacy_enabled ? 1 : 0
105
163
  zone_id = aws_route53_zone.agents[0].zone_id
106
164
  name = "_amazonses.${var.email_domain}"
107
165
  type = "TXT"
@@ -109,8 +167,17 @@ resource "aws_route53_record" "ses_verification" {
109
167
  records = [aws_ses_domain_identity.main[0].verification_token]
110
168
  }
111
169
 
170
+ resource "aws_route53_record" "tenant_ses_verification" {
171
+ for_each = local.tenant_enabled ? local.tenant_domains : {}
172
+ zone_id = aws_route53_zone.tenant[each.key].zone_id
173
+ name = "_amazonses.${each.value}"
174
+ type = "TXT"
175
+ ttl = 600
176
+ records = [aws_ses_domain_identity.tenant[each.key].verification_token]
177
+ }
178
+
112
179
  resource "aws_route53_record" "dkim" {
113
- count = local.enabled ? 3 : 0
180
+ count = local.legacy_enabled ? 3 : 0
114
181
  zone_id = aws_route53_zone.agents[0].zone_id
115
182
  name = "${aws_ses_domain_dkim.main[0].dkim_tokens[count.index]}._domainkey.${var.email_domain}"
116
183
  type = "CNAME"
@@ -118,8 +185,17 @@ resource "aws_route53_record" "dkim" {
118
185
  records = ["${aws_ses_domain_dkim.main[0].dkim_tokens[count.index]}.dkim.amazonses.com"]
119
186
  }
120
187
 
188
+ resource "aws_route53_record" "tenant_dkim" {
189
+ for_each = local.tenant_dkim_records
190
+ zone_id = aws_route53_zone.tenant[each.value.slug].zone_id
191
+ name = "${aws_ses_domain_dkim.tenant[each.value.slug].dkim_tokens[each.value.index]}._domainkey.${local.tenant_domains[each.value.slug]}"
192
+ type = "CNAME"
193
+ ttl = 600
194
+ records = ["${aws_ses_domain_dkim.tenant[each.value.slug].dkim_tokens[each.value.index]}.dkim.amazonses.com"]
195
+ }
196
+
121
197
  resource "aws_route53_record" "mx" {
122
- count = local.enabled ? 1 : 0
198
+ count = local.legacy_enabled ? 1 : 0
123
199
  zone_id = aws_route53_zone.agents[0].zone_id
124
200
  name = var.email_domain
125
201
  type = "MX"
@@ -127,6 +203,15 @@ resource "aws_route53_record" "mx" {
127
203
  records = ["10 ${local.inbound_smtp}"]
128
204
  }
129
205
 
206
+ resource "aws_route53_record" "tenant_mx" {
207
+ for_each = local.tenant_enabled ? local.tenant_domains : {}
208
+ zone_id = aws_route53_zone.tenant[each.key].zone_id
209
+ name = each.value
210
+ type = "MX"
211
+ ttl = 600
212
+ records = ["10 ${local.inbound_smtp}"]
213
+ }
214
+
130
215
  ################################################################################
131
216
  # SES Receipt Rule Set + Rule → S3 + Lambda
132
217
  ################################################################################
@@ -154,7 +239,7 @@ resource "aws_ses_receipt_rule" "inbound" {
154
239
  count = local.enabled ? 1 : 0
155
240
  name = "thinkwork-${var.stage}-inbound-email"
156
241
  rule_set_name = aws_ses_receipt_rule_set.main[0].rule_set_name
157
- recipients = [var.email_domain]
242
+ recipients = []
158
243
  enabled = true
159
244
  scan_enabled = true
160
245
 
@@ -183,28 +268,56 @@ resource "aws_ses_receipt_rule" "inbound" {
183
268
  # Outputs
184
269
  ################################################################################
185
270
 
271
+ output "ses_domain_identity_arns" {
272
+ description = "SES domain identity ARNs by tenant slug"
273
+ value = {
274
+ for slug, identity in aws_ses_domain_identity.tenant : slug => identity.arn
275
+ }
276
+ }
277
+
186
278
  output "ses_domain_identity_arn" {
187
- description = "SES domain identity ARN"
188
- value = local.enabled ? aws_ses_domain_identity.main[0].arn : null
279
+ description = "Legacy SES domain identity ARN"
280
+ value = local.legacy_enabled ? aws_ses_domain_identity.main[0].arn : null
281
+ }
282
+
283
+ output "tenant_dkim_tokens" {
284
+ description = "DKIM tokens by tenant slug (already written as CNAMEs in each subzone)"
285
+ value = {
286
+ for slug, dkim in aws_ses_domain_dkim.tenant : slug => dkim.dkim_tokens
287
+ }
189
288
  }
190
289
 
191
290
  output "dkim_tokens" {
192
- description = "DKIM tokens (already written as CNAMEs in the subzone)"
193
- value = local.enabled ? aws_ses_domain_dkim.main[0].dkim_tokens : []
291
+ description = "Legacy DKIM tokens (already written as CNAMEs in the legacy subzone)"
292
+ value = local.legacy_enabled ? aws_ses_domain_dkim.main[0].dkim_tokens : []
293
+ }
294
+
295
+ output "zone_ids" {
296
+ description = "Route53 hosted zone IDs by tenant slug"
297
+ value = {
298
+ for slug, zone in aws_route53_zone.tenant : slug => zone.zone_id
299
+ }
194
300
  }
195
301
 
196
302
  output "zone_id" {
197
- description = "Route53 hosted zone ID for the email subdomain"
198
- value = local.enabled ? aws_route53_zone.agents[0].zone_id : null
303
+ description = "Legacy Route53 hosted zone ID"
304
+ value = local.legacy_enabled ? aws_route53_zone.agents[0].zone_id : null
305
+ }
306
+
307
+ output "tenant_name_servers" {
308
+ description = "Name servers by tenant slug. Publish each set as NS records at the parent domain host before SES can verify."
309
+ value = {
310
+ for slug, zone in aws_route53_zone.tenant : slug => zone.name_servers
311
+ }
199
312
  }
200
313
 
201
314
  output "name_servers" {
202
- description = "Name servers for the delegated email subzone. Paste these as NS records at the registrar that hosts the parent domain (e.g. Google Domains) before SES can verify."
203
- value = local.enabled ? aws_route53_zone.agents[0].name_servers : []
315
+ description = "Legacy email subzone name servers"
316
+ value = local.legacy_enabled ? aws_route53_zone.agents[0].name_servers : []
204
317
  }
205
318
 
206
319
  output "mx_target" {
207
- description = "MX target host for the email subdomain"
320
+ description = "MX target host for each tenant email subdomain"
208
321
  value = local.enabled ? local.inbound_smtp : null
209
322
  }
210
323
 
@@ -1,7 +1,7 @@
1
1
  ################################################################################
2
2
  # Static Site — App Module
3
3
  #
4
- # S3 + CloudFront distribution for static web apps (apps/admin, docs site).
4
+ # S3 + CloudFront distribution for static web apps.
5
5
  # Reusable for any static frontend that needs a CDN + custom domain.
6
6
  ################################################################################
7
7
 
@@ -55,7 +55,7 @@ variable "viewer_request_function_code" {
55
55
  # Response-headers policy (optional, plan-012 U3)
56
56
  #
57
57
  # Two opt-in forms, both backwards compatible — existing callers
58
- # (computer_site, admin_site, docs_site, www_site) leave both unset and the
58
+ # (computer_site, docs_site, www_site) leave both unset and the
59
59
  # distribution is created with no response-headers policy attached:
60
60
  #
61
61
  # - Pass `response_headers_policy_id` to attach an existing policy by id.
@@ -144,7 +144,8 @@ check "policy_inputs_are_mutually_exclusive" {
144
144
  }
145
145
 
146
146
  resource "aws_s3_bucket" "site" {
147
- bucket = local.bucket_name
147
+ bucket = local.bucket_name
148
+ force_destroy = var.stage == "dev"
148
149
 
149
150
  tags = {
150
151
  Name = "thinkwork-${var.stage}-${var.site_name}"
@@ -12,6 +12,10 @@
12
12
  # 6. Optional admin.<domain> CNAME → admin CloudFront distribution.
13
13
  # 7. Optional app.<domain> CNAME → end-user app CloudFront distribution.
14
14
  # 8. Optional computer.<domain> → app.<domain> 301 compatibility redirect.
15
+ # 9. Optional crm.<domain> CNAME → Twenty CRM public ALB. The CRM ALB uses
16
+ # its own certificate; this module only owns the public CNAME.
17
+ # 10. Optional n8n.<domain> CNAME → n8n public ALB. The n8n ALB uses its own
18
+ # certificate; this module only owns the public CNAME.
15
19
  #
16
20
  # Cloudflare records MUST be DNS-only (grey cloud). CloudFront terminates TLS
17
21
  # with the ACM cert and needs the real Host header.
@@ -39,11 +43,13 @@ locals {
39
43
  computer = "computer.${var.domain}"
40
44
  sandbox = "sandbox.${var.domain}"
41
45
  api = "api.${var.domain}"
46
+ crm = "crm.${var.domain}"
47
+ n8n = "n8n.${var.domain}"
42
48
  name_id = replace(var.domain, ".", "-")
43
49
 
44
50
  # ACM SANs: always include www, conditionally include docs, admin, computer,
45
- # and api. The Computer iframe sandbox uses its own certificate so adding or
46
- # rotating the sandbox host never forces a replacement of this shared
51
+ # and api. The Computer iframe sandbox and CRM ALB use their own certificates
52
+ # so adding or rotating those hosts never forces a replacement of this shared
47
53
  # production certificate.
48
54
  # Gated on plain bool vars (not on CloudFront/API Gateway outputs) to keep
49
55
  # the dependency graph acyclic — distributions / custom domain names
@@ -59,14 +65,16 @@ locals {
59
65
 
60
66
  # Existing CNAME records stay gated on non-empty targets because their target
61
67
  # outputs are already known in the deployed stack. Newly bootstrapped records
62
- # such as app/computer compatibility/sandbox CNAMEs must gate only on explicit
63
- # booleans so Terraform can plan the resource count before the new CloudFront
64
- # distribution exists.
68
+ # such as app/computer compatibility/sandbox/crm CNAMEs must gate only on
69
+ # explicit booleans so Terraform can plan the resource count before the new
70
+ # load balancer exists.
65
71
  create_docs_record = var.include_docs && var.docs_cloudfront_domain_name != ""
66
72
  create_admin_record = var.include_admin && var.admin_cloudfront_domain_name != ""
67
73
  create_app_record = var.include_app
68
74
  create_computer_record = var.include_computer
69
75
  create_api_record = var.include_api && var.api_gateway_id != ""
76
+ create_crm_record = var.include_crm
77
+ create_n8n_record = var.include_n8n
70
78
  }
71
79
 
72
80
  ################################################################################
@@ -373,3 +381,35 @@ resource "cloudflare_record" "api" {
373
381
  proxied = false
374
382
  comment = "thinkwork-${var.stage} api → API Gateway v2 regional domain"
375
383
  }
384
+
385
+ ################################################################################
386
+ # crm.<domain> → Twenty CRM public ALB (optional)
387
+ ################################################################################
388
+
389
+ resource "cloudflare_record" "crm" {
390
+ count = local.create_crm_record ? 1 : 0
391
+
392
+ zone_id = var.cloudflare_zone_id
393
+ name = local.crm
394
+ content = var.crm_alb_dns_name
395
+ type = "CNAME"
396
+ ttl = 300
397
+ proxied = false
398
+ comment = "thinkwork-${var.stage} crm → Twenty CRM public ALB"
399
+ }
400
+
401
+ ################################################################################
402
+ # n8n.<domain> -> n8n public ALB (optional)
403
+ ################################################################################
404
+
405
+ resource "cloudflare_record" "n8n" {
406
+ count = local.create_n8n_record ? 1 : 0
407
+
408
+ zone_id = var.cloudflare_zone_id
409
+ name = local.n8n
410
+ content = var.n8n_alb_dns_name
411
+ type = "CNAME"
412
+ ttl = 300
413
+ proxied = false
414
+ comment = "thinkwork-${var.stage} n8n -> n8n public ALB"
415
+ }
@@ -22,3 +22,13 @@ output "api_custom_domain_target" {
22
22
  description = "API Gateway regional target domain to CNAME to (useful for external DNS configuration). Empty string when include_api is false."
23
23
  value = var.include_api ? aws_apigatewayv2_domain_name.api[0].domain_name_configuration[0].target_domain_name : ""
24
24
  }
25
+
26
+ output "crm_custom_domain_name" {
27
+ description = "Custom domain name for Twenty CRM (e.g. crm.thinkwork.ai). Empty string when include_crm is false."
28
+ value = var.include_crm ? "crm.${var.domain}" : ""
29
+ }
30
+
31
+ output "n8n_custom_domain_name" {
32
+ description = "Custom domain name for n8n (e.g. n8n.thinkwork.ai). Empty string when include_n8n is false."
33
+ value = var.include_n8n ? "n8n.${var.domain}" : ""
34
+ }
@@ -84,6 +84,30 @@ variable "include_api" {
84
84
  default = false
85
85
  }
86
86
 
87
+ variable "include_crm" {
88
+ description = "When true, create a Cloudflare CNAME for the Twenty CRM public ALB. The CRM ALB uses its own certificate."
89
+ type = bool
90
+ default = false
91
+ }
92
+
93
+ variable "crm_alb_dns_name" {
94
+ description = "Public ALB DNS name for the Twenty CRM app. Used as the target for the crm.<domain> Cloudflare CNAME when include_crm is true."
95
+ type = string
96
+ default = ""
97
+ }
98
+
99
+ variable "include_n8n" {
100
+ description = "When true, create a Cloudflare CNAME for the n8n public ALB. The n8n ALB uses its own certificate."
101
+ type = bool
102
+ default = false
103
+ }
104
+
105
+ variable "n8n_alb_dns_name" {
106
+ description = "Public ALB DNS name for n8n. Used as the target for the n8n.<domain> Cloudflare CNAME when include_n8n is true."
107
+ type = string
108
+ default = ""
109
+ }
110
+
87
111
  variable "api_gateway_id" {
88
112
  description = "aws_apigatewayv2_api.id of the HTTP API to expose at api.<domain>. Required when include_api is true."
89
113
  type = string
@@ -73,7 +73,11 @@ resource "aws_security_group" "db" {
73
73
  }
74
74
 
75
75
  lifecycle {
76
- ignore_changes = [name]
76
+ # App modules grant their own task security groups database access through
77
+ # standalone aws_security_group_rule resources. Keep this shared group from
78
+ # trying to reconcile those externally managed ingress rules during targeted
79
+ # managed-app deploys.
80
+ ignore_changes = [name, ingress]
77
81
  }
78
82
  }
79
83
 
@@ -121,6 +125,12 @@ resource "aws_rds_cluster" "main" {
121
125
  tags = {
122
126
  Name = "thinkwork-${var.stage}-db"
123
127
  }
128
+
129
+ lifecycle {
130
+ # Aurora can auto-advance patch versions; never attempt to roll an
131
+ # existing cluster back to the module's default minor version.
132
+ ignore_changes = [engine_version]
133
+ }
124
134
  }
125
135
 
126
136
  resource "aws_rds_cluster_instance" "main" {
@@ -138,6 +148,10 @@ resource "aws_rds_cluster_instance" "main" {
138
148
  tags = {
139
149
  Name = "thinkwork-${var.stage}-db-1"
140
150
  }
151
+
152
+ lifecycle {
153
+ ignore_changes = [engine_version]
154
+ }
141
155
  }
142
156
 
143
157
  ################################################################################
@@ -216,7 +216,7 @@ resource "aws_iam_role_policy" "runner_s3_allow" {
216
216
  }
217
217
 
218
218
  resource "aws_iam_role_policy" "runner_secrets" {
219
- count = length(var.database_secret_arn) > 0 ? 1 : 0
219
+ count = var.enable_runner_database_secret_access ? 1 : 0
220
220
  name = "exports-runner-secrets"
221
221
  role = aws_iam_role.runner_lambda.id
222
222
 
@@ -38,6 +38,12 @@ variable "database_secret_arn" {
38
38
  default = ""
39
39
  }
40
40
 
41
+ variable "enable_runner_database_secret_access" {
42
+ description = "Grant the compliance export runner role access to database_secret_arn."
43
+ type = bool
44
+ default = false
45
+ }
46
+
41
47
  variable "expiration_days" {
42
48
  description = "Number of days an export object lives before lifecycle expiration. SOC2 walkthrough auditors typically download artifacts within hours; 7 days is the audit-window default."
43
49
  type = number