thinkwork-cli 0.12.12 → 0.12.16

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 (475) hide show
  1. package/README.md +42 -38
  2. package/dist/{api-client-ASJWIG3Z.js → api-client-JUBCQQDF.js} +1 -1
  3. package/dist/{chunk-JEHV35EU.js → chunk-STY44FQO.js} +353 -30
  4. package/dist/cli.js +23823 -10151
  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/0197_rcm_context_columns.sql +28 -0
  218. package/dist/drizzle/0198_eval_runs_unstable.sql +27 -0
  219. package/dist/drizzle/0199_eval_runs_cost_partial.sql +27 -0
  220. package/dist/drizzle/meta/_journal.json +160 -0
  221. package/dist/plugins/README.md +162 -0
  222. package/dist/plugins/catalog/package.json +40 -0
  223. package/dist/plugins/catalog/scripts/build-catalog.ts +120 -0
  224. package/dist/plugins/catalog/scripts/generate-plugin-registry.ts +144 -0
  225. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +86 -0
  226. package/dist/plugins/catalog/src/__tests__/catalog.test.ts +308 -0
  227. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +861 -0
  228. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +124 -0
  229. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +120 -0
  230. package/dist/plugins/catalog/src/catalog.ts +434 -0
  231. package/dist/plugins/catalog/src/contracts.ts +1498 -0
  232. package/dist/plugins/catalog/src/index.ts +4 -0
  233. package/dist/plugins/catalog/src/plugin-package.ts +171 -0
  234. package/dist/plugins/catalog/src/registry/generated-first-party.ts +76 -0
  235. package/dist/plugins/catalog/src/registry/index.ts +1 -0
  236. package/dist/plugins/catalog/tsconfig.json +8 -0
  237. package/dist/plugins/company-brain/README.md +37 -0
  238. package/dist/plugins/company-brain/package.json +33 -0
  239. package/dist/plugins/company-brain/runtime/cognee/Dockerfile +11 -0
  240. package/dist/plugins/company-brain/smoke/cognee-managed-app-smoke.mjs +458 -0
  241. package/dist/plugins/company-brain/smoke/cognee-memory-cutover-smoke.mjs +539 -0
  242. package/dist/plugins/company-brain/smoke/company-brain-context-engine-smoke.mjs +312 -0
  243. package/dist/plugins/company-brain/smoke/company-brain-operations-smoke.mjs +449 -0
  244. package/dist/plugins/company-brain/smoke/company-brain-plugin-smoke.mjs +655 -0
  245. package/dist/plugins/company-brain/smoke/hindsight-memory-isolation-smoke.mjs +474 -0
  246. package/dist/plugins/company-brain/src/api/cognee-client.ts +896 -0
  247. package/dist/plugins/company-brain/src/api/cognee-cluster-identity.ts +49 -0
  248. package/dist/plugins/company-brain/src/api/cognee-memory-scope.ts +84 -0
  249. package/dist/plugins/company-brain/src/api/context-engine-provider.ts +888 -0
  250. package/dist/plugins/company-brain/src/api/migration.ts +665 -0
  251. package/dist/plugins/company-brain/src/deployment/cognee-managed-app.ts +396 -0
  252. package/dist/plugins/company-brain/src/index.ts +62 -0
  253. package/dist/plugins/company-brain/src/manifest.ts +112 -0
  254. package/dist/plugins/company-brain/terraform/cognee/README.md +263 -0
  255. package/dist/plugins/company-brain/terraform/cognee/main.tf +766 -0
  256. package/dist/plugins/company-brain/terraform/cognee/outputs.tf +144 -0
  257. package/dist/plugins/company-brain/terraform/cognee/variables.tf +402 -0
  258. package/dist/plugins/company-brain/test/api/cognee-client.test.ts +562 -0
  259. package/dist/plugins/company-brain/test/api/cognee-memory-scope.test.ts +74 -0
  260. package/dist/plugins/company-brain/test/api/context-engine-provider.test.ts +447 -0
  261. package/dist/plugins/company-brain/test/api/migration.test.ts +465 -0
  262. package/dist/plugins/company-brain/test/manifest.test.ts +95 -0
  263. package/dist/plugins/company-brain/tsconfig.json +8 -0
  264. package/dist/plugins/company-data/README.md +49 -0
  265. package/dist/plugins/company-data/package.json +21 -0
  266. package/dist/plugins/company-data/src/index.ts +30 -0
  267. package/dist/plugins/company-data/src/manifest.ts +26 -0
  268. package/dist/plugins/company-data/test/manifest.test.ts +116 -0
  269. package/dist/plugins/company-data/tsconfig.json +8 -0
  270. package/dist/plugins/company-etl/README.md +46 -0
  271. package/dist/plugins/company-etl/package.json +21 -0
  272. package/dist/plugins/company-etl/src/index.ts +29 -0
  273. package/dist/plugins/company-etl/src/manifest.ts +26 -0
  274. package/dist/plugins/company-etl/test/manifest.test.ts +108 -0
  275. package/dist/plugins/company-etl/tsconfig.json +8 -0
  276. package/dist/plugins/email-channel/README.md +41 -0
  277. package/dist/plugins/email-channel/package.json +22 -0
  278. package/dist/plugins/email-channel/src/index.ts +36 -0
  279. package/dist/plugins/email-channel/src/manifest.ts +44 -0
  280. package/dist/plugins/email-channel/src/provider-contract.ts +36 -0
  281. package/dist/plugins/email-channel/test/manifest.test.ts +119 -0
  282. package/dist/plugins/email-channel/tsconfig.json +8 -0
  283. package/dist/plugins/lastmile/README.md +50 -0
  284. package/dist/plugins/lastmile/package.json +23 -0
  285. package/dist/plugins/lastmile/smoke/lastmile-plugin-smoke.mjs +661 -0
  286. package/dist/plugins/lastmile/src/api/tasks-adapter.ts +572 -0
  287. package/dist/plugins/lastmile/src/discovery.fixture.ts +64 -0
  288. package/dist/plugins/lastmile/src/index.ts +46 -0
  289. package/dist/plugins/lastmile/src/manifest.ts +139 -0
  290. package/dist/plugins/lastmile/test/api/tasks-adapter.test.ts +266 -0
  291. package/dist/plugins/lastmile/test/discovery.test.ts +88 -0
  292. package/dist/plugins/lastmile/tsconfig.json +8 -0
  293. package/dist/plugins/n8n/README.md +201 -0
  294. package/dist/plugins/n8n/n8n-app/README.md +33 -0
  295. package/dist/plugins/n8n/n8n-app/package.json +23 -0
  296. package/dist/plugins/n8n/n8n-app/src/application-config.ts +45 -0
  297. package/dist/plugins/n8n/n8n-app/src/front-components/thinkwork-workflows.front-component.tsx +970 -0
  298. package/dist/plugins/n8n/n8n-app/src/lib/n8n-app-data.ts +190 -0
  299. package/dist/plugins/n8n/n8n-app/src/vite-env.d.ts +7 -0
  300. package/dist/plugins/n8n/n8n-app/tsconfig.json +15 -0
  301. package/dist/plugins/n8n/package.json +35 -0
  302. package/dist/plugins/n8n/runtime/Dockerfile +18 -0
  303. package/dist/plugins/n8n/runtime/n8n-task-runners.json +14 -0
  304. package/dist/plugins/n8n/runtime/n8n-task-runners.json.template +14 -0
  305. package/dist/plugins/n8n/runtime/package-lock.json +13 -0
  306. package/dist/plugins/n8n/runtime/package.json +7 -0
  307. package/dist/plugins/n8n/scripts/sync-thinkwork-app.mjs +268 -0
  308. package/dist/plugins/n8n/smoke/README.md +95 -0
  309. package/dist/plugins/n8n/smoke/n8n-agent-step-bridge-smoke.mjs +866 -0
  310. package/dist/plugins/n8n/smoke/n8n-integrated-app-smoke.mjs +262 -0
  311. package/dist/plugins/n8n/smoke/n8n-managed-app-smoke.mjs +409 -0
  312. package/dist/plugins/n8n/smoke/n8n-mcp-smoke.mjs +624 -0
  313. package/dist/plugins/n8n/src/deployment/image-build.ts +172 -0
  314. package/dist/plugins/n8n/src/deployment/managed-app.ts +429 -0
  315. package/dist/plugins/n8n/src/index.ts +79 -0
  316. package/dist/plugins/n8n/src/manifest.ts +403 -0
  317. package/dist/plugins/n8n/src/package-config.ts +186 -0
  318. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/SKILL.md +76 -0
  319. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/mcp-tooling.md +40 -0
  320. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/validation-and-handoff.md +40 -0
  321. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/workflow-authoring.md +45 -0
  322. package/dist/plugins/n8n/terraform/n8n/README.md +113 -0
  323. package/dist/plugins/n8n/terraform/n8n/main.tf +918 -0
  324. package/dist/plugins/n8n/terraform/n8n/outputs.tf +124 -0
  325. package/dist/plugins/n8n/terraform/n8n/scripts/sync-database.py +250 -0
  326. package/dist/plugins/n8n/terraform/n8n/scripts/test_sync_database.py +55 -0
  327. package/dist/plugins/n8n/terraform/n8n/variables.tf +354 -0
  328. package/dist/plugins/n8n/test/image-build.test.ts +118 -0
  329. package/dist/plugins/n8n/test/integrated-app-contract.test.ts +353 -0
  330. package/dist/plugins/n8n/test/manifest.test.ts +278 -0
  331. package/dist/plugins/n8n/test/package-config.test.ts +57 -0
  332. package/dist/plugins/n8n/tsconfig.json +8 -0
  333. package/dist/plugins/sendgrid/README.md +30 -0
  334. package/dist/plugins/sendgrid/package.json +22 -0
  335. package/dist/plugins/sendgrid/src/index.ts +36 -0
  336. package/dist/plugins/sendgrid/src/manifest.ts +37 -0
  337. package/dist/plugins/sendgrid/src/provider-contract.ts +14 -0
  338. package/dist/plugins/sendgrid/test/manifest.test.ts +80 -0
  339. package/dist/plugins/sendgrid/tsconfig.json +8 -0
  340. package/dist/plugins/twenty/README.md +78 -0
  341. package/dist/plugins/twenty/package.json +27 -0
  342. package/dist/plugins/twenty/scripts/__tests__/sync-thinkwork-app.test.mjs +67 -0
  343. package/dist/plugins/twenty/scripts/sync-thinkwork-app.mjs +185 -0
  344. package/dist/plugins/twenty/scripts/wire-thinkwork-workflow.mjs +658 -0
  345. package/dist/plugins/twenty/smoke/twenty-managed-app-smoke.mjs +359 -0
  346. package/dist/plugins/twenty/smoke/twenty-mcp-oauth-smoke.mjs +574 -0
  347. package/dist/plugins/twenty/src/api/cutover.ts +209 -0
  348. package/dist/plugins/twenty/src/deployment/managed-app.ts +253 -0
  349. package/dist/plugins/twenty/src/index.ts +55 -0
  350. package/dist/plugins/twenty/src/manifest.ts +259 -0
  351. package/dist/plugins/twenty/terraform/twenty/README.md +97 -0
  352. package/dist/plugins/twenty/terraform/twenty/main.tf +829 -0
  353. package/dist/plugins/twenty/terraform/twenty/outputs.tf +79 -0
  354. package/dist/plugins/twenty/terraform/twenty/variables.tf +268 -0
  355. package/dist/plugins/twenty/test/api/cutover.test.ts +183 -0
  356. package/dist/plugins/twenty/test/manifest.test.ts +463 -0
  357. package/dist/plugins/twenty/tsconfig.json +9 -0
  358. package/dist/plugins/twenty/twenty-app/.nvmrc +1 -0
  359. package/dist/plugins/twenty/twenty-app/README.md +148 -0
  360. package/dist/plugins/twenty/twenty-app/package.json +30 -0
  361. package/dist/plugins/twenty/twenty-app/src/application-config.ts +44 -0
  362. package/dist/plugins/twenty/twenty-app/src/constants/universal-identifiers.ts +18 -0
  363. package/dist/plugins/twenty/twenty-app/src/default-role.ts +24 -0
  364. package/dist/plugins/twenty/twenty-app/src/front-components/thinkwork-settings.front-component.tsx +299 -0
  365. package/dist/plugins/twenty/twenty-app/src/logic-functions/thinkwork-webhook.logic-function.ts +354 -0
  366. package/dist/plugins/twenty/twenty-app/tsconfig.json +14 -0
  367. package/dist/plugins/twenty/twenty-app/yarn.lock +4144 -0
  368. package/dist/plugins/workos-auth/package.json +22 -0
  369. package/dist/plugins/workos-auth/src/index.ts +30 -0
  370. package/dist/plugins/workos-auth/src/manifest.ts +40 -0
  371. package/dist/plugins/workos-auth/src/provider-contract.ts +39 -0
  372. package/dist/plugins/workos-auth/test/manifest.test.ts +94 -0
  373. package/dist/plugins/workos-auth/tsconfig.json +8 -0
  374. package/dist/scripts/bootstrap-workspace.sh +162 -0
  375. package/dist/scripts/post-deploy.sh +290 -0
  376. package/dist/terraform/examples/greenfield/main.tf +903 -75
  377. package/dist/terraform/examples/greenfield/terraform.tfvars.example +67 -8
  378. package/dist/terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base +2 -2
  379. package/dist/terraform/modules/app/agentcore-code-interpreter/README.md +8 -9
  380. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/sitecustomize.py +227 -0
  381. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/test_sitecustomize.py +277 -0
  382. package/dist/terraform/modules/app/agentcore-memory/README.md +6 -6
  383. package/dist/terraform/modules/app/agentcore-memory/main.tf +1 -1
  384. package/dist/terraform/modules/app/agentcore-memory/scripts/create_or_find_memory.sh +40 -9
  385. package/dist/terraform/modules/app/agentcore-pi/README.md +61 -0
  386. package/dist/terraform/modules/app/agentcore-pi/main.tf +466 -0
  387. package/dist/terraform/modules/app/agentcore-pi/outputs.tf +38 -0
  388. package/dist/terraform/modules/app/agentcore-pi/variables.tf +145 -0
  389. package/dist/terraform/modules/app/agentcore-platform/main.tf +83 -0
  390. package/dist/terraform/modules/app/agentcore-runtime/main.tf +9 -11
  391. package/dist/terraform/modules/app/appsync-subscriptions/main.tf +5 -1
  392. package/dist/terraform/modules/app/customer-domain/main.tf +483 -0
  393. package/dist/terraform/modules/app/deployment-control-plane/README.md +47 -0
  394. package/dist/terraform/modules/app/deployment-control-plane/buildspec.yml +24 -0
  395. package/dist/terraform/modules/app/deployment-control-plane/main.tf +614 -0
  396. package/dist/terraform/modules/app/deployment-control-plane/outputs.tf +54 -0
  397. package/dist/terraform/modules/app/deployment-control-plane/runner.py +4720 -0
  398. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +3026 -0
  399. package/dist/terraform/modules/app/deployment-control-plane/variables.tf +96 -0
  400. package/dist/terraform/modules/app/hindsight-memory/README.md +25 -23
  401. package/dist/terraform/modules/app/hindsight-memory/main.tf +26 -2
  402. package/dist/terraform/modules/app/lambda-api/eval-fanout.tf +17 -50
  403. package/dist/terraform/modules/app/lambda-api/handlers.tf +1290 -679
  404. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +933 -0
  405. package/dist/terraform/modules/app/lambda-api/main.tf +14 -527
  406. package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +3 -19
  407. package/dist/terraform/modules/app/lambda-api/outputs.tf +50 -6
  408. package/dist/terraform/modules/app/lambda-api/runtime-config.tf +163 -0
  409. package/dist/terraform/modules/app/lambda-api/slack-app-secrets.tf +3 -1
  410. package/dist/terraform/modules/app/lambda-api/stripe-secrets.tf +3 -1
  411. package/dist/terraform/modules/app/lambda-api/variables.tf +240 -53
  412. package/dist/terraform/modules/app/lambda-api/workspace-events.tf +2 -25
  413. package/dist/terraform/modules/app/ses-email/main.tf +143 -30
  414. package/dist/terraform/modules/app/static-site/main.tf +4 -3
  415. package/dist/terraform/modules/app/www-dns/main.tf +45 -5
  416. package/dist/terraform/modules/app/www-dns/outputs.tf +10 -0
  417. package/dist/terraform/modules/app/www-dns/variables.tf +24 -0
  418. package/dist/terraform/modules/data/aurora-postgres/main.tf +15 -1
  419. package/dist/terraform/modules/data/compliance-exports-bucket/main.tf +1 -1
  420. package/dist/terraform/modules/data/compliance-exports-bucket/variables.tf +6 -0
  421. package/dist/terraform/modules/foundation/cognito/main.tf +167 -11
  422. package/dist/terraform/modules/foundation/cognito/outputs.tf +5 -0
  423. package/dist/terraform/modules/foundation/cognito/variables.tf +110 -0
  424. package/dist/terraform/modules/foundation/vpc/main.tf +45 -3
  425. package/dist/terraform/modules/foundation/vpc/outputs.tf +20 -0
  426. package/dist/terraform/modules/foundation/vpc/variables.tf +18 -0
  427. package/dist/terraform/modules/thinkwork/README.md +71 -0
  428. package/dist/terraform/modules/thinkwork/main.tf +1325 -174
  429. package/dist/terraform/modules/thinkwork/outputs.tf +457 -24
  430. package/dist/terraform/modules/thinkwork/variables.tf +1169 -93
  431. package/dist/terraform/schema.graphql +82 -9
  432. package/dist/workspace-defaults/files/AGENTS.md +344 -0
  433. package/dist/workspace-defaults/files/CONTEXT.md +8 -0
  434. package/dist/workspace-defaults/files/GUARDRAILS.md +51 -0
  435. package/dist/workspace-defaults/files/MEMORY_GUIDE.md +65 -0
  436. package/dist/workspace-defaults/files/ROUTER.md +24 -0
  437. package/dist/workspace-defaults/files/SPACE.md +62 -0
  438. package/dist/workspace-defaults/files/TOOLS.md +65 -0
  439. package/dist/workspace-defaults/files/USER.md +40 -0
  440. package/dist/workspace-defaults/files/mcp.json +3 -0
  441. package/dist/workspace-defaults/files/memory/contacts.md +13 -0
  442. package/dist/workspace-defaults/files/memory/lessons.md +13 -0
  443. package/dist/workspace-defaults/files/memory/preferences.md +12 -0
  444. package/dist/workspace-defaults/files/skills/.gitkeep +1 -0
  445. package/dist/workspace-defaults/files/skills/artifact-builder/SKILL.md +79 -0
  446. package/dist/workspace-defaults/files/skills/artifact-builder/references/crm-dashboard.md +166 -0
  447. package/dist/workspace-defaults/files/skills/automation-loop-designer/SKILL.md +120 -0
  448. package/dist/workspace-defaults/files/skills/skill-creator/LICENSE.txt +202 -0
  449. package/dist/workspace-defaults/files/skills/skill-creator/SKILL.md +485 -0
  450. package/dist/workspace-defaults/files/skills/skill-creator/UPSTREAM.json +124 -0
  451. package/dist/workspace-defaults/files/skills/skill-creator/agents/analyzer.md +274 -0
  452. package/dist/workspace-defaults/files/skills/skill-creator/agents/comparator.md +202 -0
  453. package/dist/workspace-defaults/files/skills/skill-creator/agents/grader.md +223 -0
  454. package/dist/workspace-defaults/files/skills/skill-creator/assets/eval_review.html +146 -0
  455. package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  456. package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  457. package/dist/workspace-defaults/files/skills/skill-creator/references/schemas.md +430 -0
  458. package/dist/workspace-defaults/files/skills/skill-creator/scripts/__init__.py +0 -0
  459. package/dist/workspace-defaults/files/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  460. package/dist/workspace-defaults/files/skills/skill-creator/scripts/generate_report.py +326 -0
  461. package/dist/workspace-defaults/files/skills/skill-creator/scripts/improve_description.py +247 -0
  462. package/dist/workspace-defaults/files/skills/skill-creator/scripts/package_skill.py +136 -0
  463. package/dist/workspace-defaults/files/skills/skill-creator/scripts/quick_validate.py +103 -0
  464. package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_eval.py +310 -0
  465. package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_loop.py +328 -0
  466. package/dist/workspace-defaults/files/skills/skill-creator/scripts/utils.py +47 -0
  467. package/package.json +2 -1
  468. package/dist/terraform/modules/app/agentcore-flue/README.md +0 -58
  469. package/dist/terraform/modules/app/agentcore-flue/main.tf +0 -323
  470. package/dist/terraform/modules/app/agentcore-flue/outputs.tf +0 -23
  471. package/dist/terraform/modules/app/agentcore-flue/variables.tf +0 -97
  472. package/dist/terraform/modules/app/computer-runtime/README.md +0 -15
  473. package/dist/terraform/modules/app/computer-runtime/main.tf +0 -406
  474. package/dist/terraform/modules/app/computer-runtime/outputs.tf +0 -75
  475. package/dist/terraform/modules/app/computer-runtime/variables.tf +0 -66
@@ -48,6 +48,13 @@ provider "aws" {
48
48
  region = var.region
49
49
  }
50
50
 
51
+ # us-east-1 alias required by the thinkwork module's customer-domain wiring
52
+ # (CloudFront ACM certs must live in us-east-1 regardless of stack region).
53
+ provider "aws" {
54
+ alias = "us_east_1"
55
+ region = "us-east-1"
56
+ }
57
+
51
58
  # Cloudflare provider reads its token from the CLOUDFLARE_API_TOKEN env var.
52
59
  # Never commit the token to tfvars or source control.
53
60
  provider "cloudflare" {}
@@ -68,6 +75,12 @@ variable "account_id" {
68
75
  type = string
69
76
  }
70
77
 
78
+ variable "plugin_catalog_github_token_secret_arn" {
79
+ description = "Optional Secrets Manager ARN/name containing a GitHub token for API plugin catalog release-asset fetches. Empty uses unauthenticated GitHub requests."
80
+ type = string
81
+ default = ""
82
+ }
83
+
71
84
  variable "db_password" {
72
85
  description = "Master password for the Aurora cluster"
73
86
  type = string
@@ -81,11 +94,431 @@ variable "database_engine" {
81
94
  }
82
95
 
83
96
  variable "enable_hindsight" {
84
- description = "Optional Hindsight add-on alongside the always-on managed memory (ECS+ALB for semantic + graph retrieval)"
97
+ description = "Enable Hindsight canonical user and Space memory. Full ThinkWork installs default this on; set false only for explicit low-cost/development AgentCore-only deployments."
98
+ type = bool
99
+ default = true
100
+ }
101
+
102
+ variable "memory_engine" {
103
+ description = "Active long-term memory engine. Empty selects Hindsight when enable_hindsight = true. Use 'agentcore' only for explicit low-cost/development managed-memory deployments; 'cognee' is legacy diagnostic compatibility, not the supported user/Space memory path."
104
+ type = string
105
+ default = ""
106
+ }
107
+
108
+ variable "enable_cognee" {
109
+ description = "Enable Cognee as optional ThinkWork Brain ontology/knowledge-graph infrastructure. Disabled by default."
110
+ type = bool
111
+ default = false
112
+ }
113
+
114
+ variable "cognee_image_uri" {
115
+ description = "Cognee container image URI pinned to an immutable sha256 digest. Required when enable_cognee = true."
116
+ type = string
117
+ default = ""
118
+ }
119
+
120
+ variable "cognee_db_username" {
121
+ description = "Dedicated PostgreSQL username for Cognee metadata storage."
122
+ type = string
123
+ default = "thinkwork_cognee"
124
+ }
125
+
126
+ variable "cognee_db_name" {
127
+ description = "Dedicated PostgreSQL database name for Cognee metadata storage."
128
+ type = string
129
+ default = "thinkwork_cognee"
130
+ }
131
+
132
+ variable "cognee_db_password_secret_arn" {
133
+ description = "Secrets Manager ARN containing a JSON password field for the dedicated Cognee PostgreSQL user. Required when enable_cognee = true."
134
+ type = string
135
+ default = ""
136
+ }
137
+
138
+ variable "cognee_allowed_internal_cidr_blocks" {
139
+ description = "CIDR blocks allowed to reach the internal Cognee ALB."
140
+ type = list(string)
141
+ default = []
142
+ }
143
+
144
+ variable "cognee_allowed_internal_security_group_ids" {
145
+ description = "Security group IDs allowed to reach the internal Cognee ALB."
146
+ type = list(string)
147
+ default = []
148
+ }
149
+
150
+ variable "cognee_backend_mode" {
151
+ description = "Cognee backend mode. dogfood uses EFS-backed local stores; remote requires graph/vector URLs."
152
+ type = string
153
+ default = "dogfood"
154
+ }
155
+
156
+ variable "cognee_desired_count" {
157
+ description = "Desired Cognee task count. Dogfood mode must stay at 1."
158
+ type = number
159
+ default = 1
160
+ }
161
+
162
+ variable "cognee_brain_tenant_id" {
163
+ description = "Tenant ID for a tenant-scoped Company Brain substrate instance. Empty preserves legacy stage-wide Cognee names."
164
+ type = string
165
+ default = ""
166
+ }
167
+
168
+ variable "cognee_brain_instance_key" {
169
+ description = "Stable tenant-scoped Brain instance key used to derive resource names."
170
+ type = string
171
+ default = ""
172
+ }
173
+
174
+ variable "cognee_brain_storage_tier" {
175
+ description = "Company Brain storage tier: default or production."
176
+ type = string
177
+ default = "default"
178
+ }
179
+
180
+ variable "cognee_brain_s3_artifact_root" {
181
+ description = "Canonical Company Brain S3 root URI for source artifacts."
182
+ type = string
183
+ default = ""
184
+ }
185
+
186
+ variable "cognee_brain_s3_manifest_root" {
187
+ description = "Canonical Company Brain S3 root URI for ingestion manifests."
188
+ type = string
189
+ default = ""
190
+ }
191
+
192
+ variable "cognee_brain_s3_vault_projection_root" {
193
+ description = "Canonical Company Brain S3 root URI for vault/materialized projections."
194
+ type = string
195
+ default = ""
196
+ }
197
+
198
+ variable "cognee_brain_artifacts_bucket_arn" {
199
+ description = "Optional canonical Company Brain artifacts bucket ARN for scoped task-role access."
200
+ type = string
201
+ default = ""
202
+ }
203
+
204
+ variable "cognee_brain_artifacts_prefixes" {
205
+ description = "Tenant/stage prefixes inside cognee_brain_artifacts_bucket_arn the Brain task may access."
206
+ type = list(string)
207
+ default = []
208
+ }
209
+
210
+ variable "cognee_private_substrate_mode" {
211
+ description = "Whether the Company Brain substrate is private/internal-only."
212
+ type = bool
213
+ default = true
214
+ }
215
+
216
+ variable "cognee_require_authentication" {
217
+ description = "Passed to Cognee REQUIRE_AUTHENTICATION."
218
+ type = bool
219
+ default = false
220
+ }
221
+
222
+ variable "cognee_enable_backend_access_control" {
223
+ description = "Passed to Cognee ENABLE_BACKEND_ACCESS_CONTROL."
85
224
  type = bool
86
225
  default = false
87
226
  }
88
227
 
228
+ variable "cognee_cors_allowed_origins" {
229
+ description = "Passed to Cognee CORS_ALLOWED_ORIGINS."
230
+ type = string
231
+ default = ""
232
+ }
233
+
234
+ variable "cognee_llm_provider" {
235
+ description = "Cognee LLM provider."
236
+ type = string
237
+ default = "bedrock"
238
+ }
239
+
240
+ variable "cognee_llm_model" {
241
+ description = "Cognee LLM model. Must handle tool-use structured extraction reliably — nova-lite repeatedly produced invalid ToolUse sequences on observation documents, and Haiku is rate-limited on this account. Kimi K2.5 is ON_DEMAND (no inference profile needed)."
242
+ type = string
243
+ default = "bedrock/moonshotai.kimi-k2.5"
244
+ }
245
+
246
+ variable "cognee_llm_api_key_secret_arn" {
247
+ description = "Optional Secrets Manager ARN for non-Bedrock Cognee LLM provider API key."
248
+ type = string
249
+ default = ""
250
+ }
251
+
252
+ variable "cognee_embedding_provider" {
253
+ description = "Cognee embedding provider."
254
+ type = string
255
+ default = "bedrock"
256
+ }
257
+
258
+ variable "cognee_embedding_model" {
259
+ description = "Cognee embedding model."
260
+ type = string
261
+ default = "amazon.titan-embed-text-v2:0"
262
+ }
263
+
264
+ variable "cognee_embedding_dimensions" {
265
+ description = "Cognee embedding dimensions."
266
+ type = number
267
+ default = 1024
268
+ }
269
+
270
+ variable "cognee_embedding_api_key_secret_arn" {
271
+ description = "Optional Secrets Manager ARN for non-Bedrock Cognee embedding provider API key."
272
+ type = string
273
+ default = ""
274
+ }
275
+
276
+ variable "cognee_vector_db_provider" {
277
+ description = "Cognee vector store provider."
278
+ type = string
279
+ default = "lancedb"
280
+ }
281
+
282
+ variable "cognee_vector_db_url" {
283
+ description = "Cognee vector store URL. Empty uses the dogfood local default."
284
+ type = string
285
+ default = ""
286
+ }
287
+
288
+ variable "cognee_vector_db_key_secret_arn" {
289
+ description = "Optional Secrets Manager ARN for remote Cognee vector store credentials."
290
+ type = string
291
+ default = ""
292
+ }
293
+
294
+ variable "cognee_graph_database_provider" {
295
+ description = "Cognee graph store provider."
296
+ type = string
297
+ default = "kuzu"
298
+ }
299
+
300
+ variable "cognee_graph_database_url" {
301
+ description = "Cognee graph store URL. Empty uses the dogfood local default."
302
+ type = string
303
+ default = ""
304
+ }
305
+
306
+ variable "cognee_graph_database_username" {
307
+ description = "Optional Cognee graph store username."
308
+ type = string
309
+ default = ""
310
+ }
311
+
312
+ variable "cognee_graph_database_password_secret_arn" {
313
+ description = "Optional Secrets Manager ARN for remote Cognee graph store password."
314
+ type = string
315
+ default = ""
316
+ }
317
+
318
+ variable "cognee_neptune_graph_id" {
319
+ description = "Neptune Analytics graph ID used by the production Brain tier."
320
+ type = string
321
+ default = ""
322
+ }
323
+
324
+ variable "cognee_neptune_graph_arn" {
325
+ description = "Optional Neptune Analytics graph ARN for scoped task-role access."
326
+ type = string
327
+ default = ""
328
+ }
329
+
330
+ variable "cognee_neptune_endpoint" {
331
+ description = "Neptune Analytics endpoint used by the production Brain tier."
332
+ type = string
333
+ default = ""
334
+ }
335
+
336
+ variable "cognee_production_posture" {
337
+ description = "Operator evidence string for production-tier approval/readiness posture."
338
+ type = string
339
+ default = ""
340
+ }
341
+
342
+ variable "cognee_bedrock_model_resource_arns" {
343
+ description = "Explicit Bedrock model ARNs Cognee may invoke when a Bedrock provider is selected."
344
+ type = list(string)
345
+ default = []
346
+ }
347
+
348
+ variable "cognee_kms_key_arns" {
349
+ description = "Optional KMS key ARNs needed to decrypt Cognee-injected secrets."
350
+ type = list(string)
351
+ default = []
352
+ }
353
+
354
+ variable "twenty_provisioned" {
355
+ description = "Provision the retained Twenty CRM managed-app substrate. Runtime can be parked independently with twenty_runtime_enabled."
356
+ type = bool
357
+ default = false
358
+ }
359
+
360
+ variable "twenty_runtime_enabled" {
361
+ description = "Run Twenty CRM server/worker tasks when the retained substrate is provisioned."
362
+ type = bool
363
+ default = false
364
+ }
365
+
366
+ variable "twenty_image_uri" {
367
+ description = "Twenty CRM container image URI pinned to an immutable sha256 digest. Required when twenty_provisioned = true."
368
+ type = string
369
+ default = ""
370
+ }
371
+
372
+ variable "twenty_db_username" {
373
+ description = "Dedicated PostgreSQL username for Twenty CRM."
374
+ type = string
375
+ default = "thinkwork_twenty"
376
+ }
377
+
378
+ variable "twenty_db_name" {
379
+ description = "Dedicated PostgreSQL database name for Twenty CRM."
380
+ type = string
381
+ default = "thinkwork_twenty"
382
+ }
383
+
384
+ variable "twenty_db_url_secret_arn" {
385
+ description = "Secrets Manager ARN containing a JSON PG_DATABASE_URL field for the dedicated Twenty database. Required when twenty_provisioned = true."
386
+ type = string
387
+ default = ""
388
+ }
389
+
390
+ variable "twenty_encryption_key_secret_arn" {
391
+ description = "Secrets Manager ARN containing a JSON ENCRYPTION_KEY field for Twenty. Required when twenty_provisioned = true."
392
+ type = string
393
+ default = ""
394
+ }
395
+
396
+ variable "twenty_email_from_address" {
397
+ description = "Verified SES sender address for Twenty app emails. Leave empty to derive noreply@ses_inbound_domain."
398
+ type = string
399
+ default = ""
400
+ }
401
+
402
+ variable "twenty_email_from_name" {
403
+ description = "Display name for Twenty app email From headers."
404
+ type = string
405
+ default = "ThinkWork CRM"
406
+ }
407
+
408
+ variable "twenty_public_url" {
409
+ description = "Public HTTPS URL for Twenty CRM. Leave empty to derive https://crm.<www_domain>."
410
+ type = string
411
+ default = ""
412
+ }
413
+
414
+ variable "twenty_certificate_arn" {
415
+ description = "ACM certificate ARN for the Twenty public ALB. Leave empty to create a dedicated crm.<www_domain> certificate when Twenty is provisioned."
416
+ type = string
417
+ default = ""
418
+ }
419
+
420
+ variable "n8n_provisioned" {
421
+ description = "Provision the retained n8n managed-app substrate. Runtime can be parked independently with n8n_runtime_enabled."
422
+ type = bool
423
+ default = false
424
+ }
425
+
426
+ variable "n8n_runtime_enabled" {
427
+ description = "Run n8n main/worker tasks when the retained substrate is provisioned."
428
+ type = bool
429
+ default = false
430
+ }
431
+
432
+ variable "n8n_image_uri" {
433
+ description = "Thin ThinkWork n8n wrapper image URI pinned to an immutable sha256 digest. Required when n8n_provisioned = true."
434
+ type = string
435
+ default = ""
436
+ }
437
+
438
+ variable "n8n_database_admin_secret_arn" {
439
+ description = "Secrets Manager ARN for an admin database credential allowed to create/drop the dedicated n8n database and role."
440
+ type = string
441
+ default = ""
442
+ }
443
+
444
+ variable "n8n_database_url_secret_arn" {
445
+ description = "Secrets Manager ARN containing n8n's least-privilege database secret."
446
+ type = string
447
+ default = ""
448
+ }
449
+
450
+ variable "n8n_database_username" {
451
+ description = "Dedicated PostgreSQL username for n8n."
452
+ type = string
453
+ default = "thinkwork_n8n"
454
+ }
455
+
456
+ variable "n8n_database_name" {
457
+ description = "Dedicated PostgreSQL database name for n8n."
458
+ type = string
459
+ default = "thinkwork_n8n"
460
+ }
461
+
462
+ variable "n8n_encryption_key_secret_arn" {
463
+ description = "Secrets Manager ARN containing N8N_ENCRYPTION_KEY."
464
+ type = string
465
+ default = ""
466
+ }
467
+
468
+ variable "n8n_operator_secret_arn" {
469
+ description = "Secrets Manager ARN containing the shared native n8n operator account credential."
470
+ type = string
471
+ default = ""
472
+ }
473
+
474
+ variable "n8n_service_credential_secret_arn" {
475
+ description = "Secrets Manager ARN containing the tenant service credential used by the native n8n MCP integration."
476
+ type = string
477
+ default = ""
478
+ }
479
+
480
+ variable "n8n_agent_step_bridge_credential_secret_arn" {
481
+ description = "Secrets Manager ARN containing the inbound credential used by n8n workflows to call the ThinkWork agent-step bridge."
482
+ type = string
483
+ default = ""
484
+ }
485
+
486
+ variable "n8n_storage_bucket_name" {
487
+ description = "S3 bucket name used for n8n managed artifacts and optional storage mode objects."
488
+ type = string
489
+ default = ""
490
+ }
491
+
492
+ variable "n8n_public_url" {
493
+ description = "Public HTTPS URL for n8n. Leave empty to derive https://n8n.<www_domain>."
494
+ type = string
495
+ default = ""
496
+ }
497
+
498
+ variable "n8n_domain" {
499
+ description = "Public DNS name for n8n. Leave empty to derive n8n.<www_domain>."
500
+ type = string
501
+ default = ""
502
+ }
503
+
504
+ variable "n8n_certificate_arn" {
505
+ description = "ACM certificate ARN for the n8n public ALB. Leave empty to create a dedicated n8n.<www_domain> certificate when n8n is provisioned."
506
+ type = string
507
+ default = ""
508
+ }
509
+
510
+ variable "n8n_container_port" {
511
+ description = "n8n HTTP listener/container port exposed through the public ALB."
512
+ type = number
513
+ default = 5678
514
+ }
515
+
516
+ variable "n8n_cache_engine" {
517
+ description = "ElastiCache engine for n8n. Prefer valkey; redis is available as a compatibility fallback."
518
+ type = string
519
+ default = "valkey"
520
+ }
521
+
89
522
  variable "google_oauth_client_id" {
90
523
  description = "Google OAuth client ID (optional — leave empty to skip Google login)"
91
524
  type = string
@@ -105,6 +538,12 @@ variable "pre_signup_lambda_zip" {
105
538
  default = ""
106
539
  }
107
540
 
541
+ variable "cognito_custom_auth_lambda_zip" {
542
+ description = "Path to the Cognito custom-auth challenge Lambda zip"
543
+ type = string
544
+ default = ""
545
+ }
546
+
108
547
  variable "lambda_zips_dir" {
109
548
  description = "Local directory containing Lambda zip artifacts (from pnpm build:lambdas)"
110
549
  type = string
@@ -142,6 +581,12 @@ variable "api_auth_secret" {
142
581
  default = ""
143
582
  }
144
583
 
584
+ variable "platform_operator_emails" {
585
+ description = "Comma-separated email allowlist for operator-gated GraphQL mutations."
586
+ type = string
587
+ default = ""
588
+ }
589
+
145
590
  variable "www_domain" {
146
591
  description = "Public website apex domain (e.g. thinkwork.ai). Leave empty to skip the custom domain and DNS wiring."
147
592
  type = string
@@ -154,12 +599,24 @@ variable "cloudflare_zone_id" {
154
599
  default = ""
155
600
  }
156
601
 
602
+ variable "ses_parent_domain" {
603
+ description = "Parent domain for tenant-scoped Space email addresses (e.g. thinkwork.ai). Leave empty to skip SES inbound resources."
604
+ type = string
605
+ default = ""
606
+ }
607
+
157
608
  variable "ses_inbound_domain" {
158
- description = "Subdomain for agent email (e.g. agents.thinkwork.ai). Terraform creates a delegated Route53 hosted zone, SES domain identity + DKIM, MX record, and receipt rule. Leave empty to skip SES inbound resources."
609
+ description = "Legacy delegated subdomain for agent email (e.g. agents.thinkwork.ai). Keep configured until legacy-address retirement notices are no longer needed."
159
610
  type = string
160
611
  default = ""
161
612
  }
162
613
 
614
+ variable "tenant_slugs" {
615
+ description = "Tenant slugs to provision as SES receiving subdomains under ses_parent_domain. Each slug creates <slug>.<ses_parent_domain>."
616
+ type = set(string)
617
+ default = []
618
+ }
619
+
163
620
  variable "stripe_price_ids_json" {
164
621
  description = "JSON object mapping internal plan names to Stripe price IDs for this stage, e.g. {\"starter\":\"price_...\",\"team\":\"price_...\"}. Non-secret; per-stage. Exposed to Lambdas as STRIPE_PRICE_IDS_JSON env var. The secret keys themselves live in AWS Secrets Manager at thinkwork/<stage>/stripe/api-credentials — never in tfvars."
165
622
  type = string
@@ -249,10 +706,10 @@ variable "google_places_api_key" {
249
706
 
250
707
  variable "mapbox_public_token" {
251
708
  description = <<-EOT
252
- Mapbox public pk.* token consumed by apps/computer's MapView primitive
709
+ Mapbox public pk.* token consumed by the apps/web MapView primitive
253
710
  (in @thinkwork/computer-stdlib) for inline map tile rendering inside
254
- generated applets. Flows through to scripts/build-computer.sh →
255
- apps/computer/.env.production as VITE_MAPBOX_PUBLIC_TOKEN.
711
+ generated applets. Flows through to scripts/build-web.sh →
712
+ apps/web/.env.production as VITE_MAPBOX_PUBLIC_TOKEN.
256
713
 
257
714
  Mapbox tokens are designed to ship in public bundles; URL allowlist
258
715
  on the Mapbox dashboard is the security boundary. Restrict the token
@@ -267,21 +724,6 @@ variable "mapbox_public_token" {
267
724
  sensitive = true
268
725
  }
269
726
 
270
- variable "nova_act_api_key" {
271
- description = <<-EOT
272
- Nova Act API key used by the Strands Browser Automation tool. When empty,
273
- Terraform creates /thinkwork/<stage>/agentcore/nova-act-api-key with a
274
- placeholder value; populate or rotate the real key with:
275
- aws ssm put-parameter --overwrite --name /thinkwork/<stage>/agentcore/nova-act-api-key --type SecureString --value <KEY>
276
-
277
- The parameter's value has lifecycle.ignore_changes set, so operator
278
- rotation sticks across applies.
279
- EOT
280
- type = string
281
- default = ""
282
- sensitive = true
283
- }
284
-
285
727
  variable "wiki_deterministic_linking_enabled" {
286
728
  description = <<-EOT
287
729
  Feature flag for deterministic compile-time link emission:
@@ -303,6 +745,12 @@ variable "agentcore_code_interpreter_id" {
303
745
  default = ""
304
746
  }
305
747
 
748
+ variable "agentcore_memory_id" {
749
+ description = "Optional pre-existing AgentCore Memory resource ID. When set, skips memory auto-provisioning and reuses this ID."
750
+ type = string
751
+ default = ""
752
+ }
753
+
306
754
  variable "mcp_custom_domain" {
307
755
  description = <<-EOT
308
756
  MCP custom domain (e.g. "mcp.thinkwork.ai"). Empty disables the
@@ -328,14 +776,38 @@ variable "mcp_custom_domain_ready" {
328
776
  default = false
329
777
  }
330
778
 
779
+ variable "customer_domain" {
780
+ description = "Customer domain for this deployment (e.g. tei.thinkwork.ai), claimed via the shared namespace claim tool. Leave empty to skip all customer-domain resources."
781
+ type = string
782
+ default = ""
783
+ }
784
+
785
+ variable "customer_domain_delegated" {
786
+ description = "Set true once the apex zone's NS records point at the customer zone (claim tool phase two). Gates the ACM certificate, the web alias records, and the customer-domain Cognito callback entries. Requires customer_domain."
787
+ type = bool
788
+ default = false
789
+ }
790
+
791
+ variable "customer_domain_legacy_retired" {
792
+ description = "Set true to remove the legacy (non-customer-domain) end-user app URLs from the Cognito callback/logout lists after the dual-domain cutover window closes. Requires customer_domain_delegated."
793
+ type = bool
794
+ default = false
795
+ }
796
+
331
797
  locals {
332
798
  www_dns_enabled = var.www_domain != "" && var.cloudflare_zone_id != ""
333
799
  docs_domain = var.www_domain != "" ? "docs.${var.www_domain}" : ""
334
- admin_domain = var.www_domain != "" ? "admin.${var.www_domain}" : ""
335
800
  app_domain = var.www_domain != "" ? "app.${var.www_domain}" : ""
336
801
  computer_domain = var.www_domain != "" ? "computer.${var.www_domain}" : ""
337
802
  sandbox_domain = var.www_domain != "" ? "sandbox.${var.www_domain}" : ""
338
803
  api_domain = var.www_domain != "" ? "api.${var.www_domain}" : ""
804
+ crm_domain = var.www_domain != "" ? "crm.${var.www_domain}" : ""
805
+ n8n_domain = var.n8n_domain != "" ? var.n8n_domain : (var.www_domain != "" ? "n8n.${var.www_domain}" : "")
806
+ twenty_url = var.twenty_public_url != "" ? var.twenty_public_url : (local.crm_domain != "" ? "https://${local.crm_domain}" : "")
807
+ n8n_url = var.n8n_public_url != "" ? var.n8n_public_url : (local.n8n_domain != "" ? "https://${local.n8n_domain}" : "")
808
+
809
+ twenty_managed_certificate_enabled = local.www_dns_enabled && var.twenty_provisioned && var.twenty_certificate_arn == "" && local.crm_domain != ""
810
+ n8n_managed_certificate_enabled = local.www_dns_enabled && var.n8n_provisioned && var.n8n_certificate_arn == "" && local.n8n_domain != ""
339
811
  }
340
812
 
341
813
  resource "aws_acm_certificate" "computer_sandbox" {
@@ -384,40 +856,203 @@ resource "aws_acm_certificate_validation" "computer_sandbox" {
384
856
  ]
385
857
  }
386
858
 
859
+ resource "aws_acm_certificate" "twenty" {
860
+ count = local.twenty_managed_certificate_enabled ? 1 : 0
861
+
862
+ domain_name = local.crm_domain
863
+ validation_method = "DNS"
864
+
865
+ lifecycle {
866
+ create_before_destroy = true
867
+ }
868
+
869
+ tags = {
870
+ Name = "thinkwork-${var.stage}-twenty"
871
+ }
872
+ }
873
+
874
+ resource "cloudflare_record" "twenty_acm_validation" {
875
+ for_each = {
876
+ for dvo in flatten([
877
+ for cert in aws_acm_certificate.twenty : tolist(cert.domain_validation_options)
878
+ ]) : dvo.domain_name => {
879
+ name = dvo.resource_record_name
880
+ value = dvo.resource_record_value
881
+ type = dvo.resource_record_type
882
+ }
883
+ }
884
+
885
+ zone_id = var.cloudflare_zone_id
886
+ name = trimsuffix(each.value.name, ".")
887
+ content = trimsuffix(each.value.value, ".")
888
+ type = each.value.type
889
+ ttl = 60
890
+ proxied = false
891
+ comment = "ACM DNS validation for ${each.key}"
892
+
893
+ allow_overwrite = true
894
+ }
895
+
896
+ resource "aws_acm_certificate_validation" "twenty" {
897
+ count = local.twenty_managed_certificate_enabled ? 1 : 0
898
+
899
+ certificate_arn = aws_acm_certificate.twenty[0].arn
900
+ validation_record_fqdns = [
901
+ for record in cloudflare_record.twenty_acm_validation : record.hostname
902
+ ]
903
+ }
904
+
905
+ resource "aws_acm_certificate" "n8n" {
906
+ count = local.n8n_managed_certificate_enabled ? 1 : 0
907
+
908
+ domain_name = local.n8n_domain
909
+ validation_method = "DNS"
910
+
911
+ lifecycle {
912
+ create_before_destroy = true
913
+ }
914
+
915
+ tags = {
916
+ Name = "thinkwork-${var.stage}-n8n"
917
+ }
918
+ }
919
+
920
+ resource "cloudflare_record" "n8n_acm_validation" {
921
+ for_each = local.n8n_managed_certificate_enabled ? toset([local.n8n_domain]) : toset([])
922
+
923
+ zone_id = var.cloudflare_zone_id
924
+ name = trimsuffix(tolist(aws_acm_certificate.n8n[0].domain_validation_options)[0].resource_record_name, ".")
925
+ content = trimsuffix(tolist(aws_acm_certificate.n8n[0].domain_validation_options)[0].resource_record_value, ".")
926
+ type = tolist(aws_acm_certificate.n8n[0].domain_validation_options)[0].resource_record_type
927
+ ttl = 60
928
+ proxied = false
929
+ comment = "ACM DNS validation for ${each.key}"
930
+
931
+ allow_overwrite = true
932
+ }
933
+
934
+ resource "aws_acm_certificate_validation" "n8n" {
935
+ count = local.n8n_managed_certificate_enabled ? 1 : 0
936
+
937
+ certificate_arn = aws_acm_certificate.n8n[0].arn
938
+ validation_record_fqdns = [
939
+ for record in cloudflare_record.n8n_acm_validation : record.hostname
940
+ ]
941
+ }
942
+
943
+ moved {
944
+ from = module.www_dns[0].cloudflare_record.acm_validation["crm.thinkwork.ai"]
945
+ to = cloudflare_record.twenty_acm_validation["crm.thinkwork.ai"]
946
+ }
947
+
387
948
  module "thinkwork" {
388
949
  source = "../../modules/thinkwork"
389
950
 
951
+ providers = {
952
+ aws.us_east_1 = aws.us_east_1
953
+ }
954
+
390
955
  stage = var.stage
391
956
  region = var.region
392
957
  account_id = var.account_id
393
958
 
394
- db_password = var.db_password
395
- database_engine = var.database_engine
396
- enable_hindsight = var.enable_hindsight
397
- google_oauth_client_id = var.google_oauth_client_id
398
- google_oauth_client_secret = var.google_oauth_client_secret
399
- pre_signup_lambda_zip = var.pre_signup_lambda_zip
400
- lambda_zips_dir = var.lambda_zips_dir
401
- lambda_artifact_bucket = var.lambda_artifact_bucket
402
- lambda_artifact_prefix = var.lambda_artifact_prefix
403
- require_lambda_artifacts = var.require_lambda_artifacts
404
- enable_workspace_orchestration = var.enable_workspace_orchestration
405
- api_auth_secret = var.api_auth_secret
959
+ plugin_catalog_github_token_secret_arn = var.plugin_catalog_github_token_secret_arn
960
+
961
+ db_password = var.db_password
962
+ database_engine = var.database_engine
963
+ enable_hindsight = var.enable_hindsight
964
+ memory_engine = var.memory_engine
965
+ enable_cognee = var.enable_cognee
966
+ cognee_image_uri = var.cognee_image_uri
967
+ cognee_db_username = var.cognee_db_username
968
+ cognee_db_name = var.cognee_db_name
969
+ cognee_db_password_secret_arn = var.cognee_db_password_secret_arn
970
+ cognee_allowed_internal_cidr_blocks = var.cognee_allowed_internal_cidr_blocks
971
+ cognee_allowed_internal_security_group_ids = var.cognee_allowed_internal_security_group_ids
972
+ cognee_backend_mode = var.cognee_backend_mode
973
+ cognee_desired_count = var.cognee_desired_count
974
+ cognee_brain_tenant_id = var.cognee_brain_tenant_id
975
+ cognee_brain_instance_key = var.cognee_brain_instance_key
976
+ cognee_brain_storage_tier = var.cognee_brain_storage_tier
977
+ cognee_brain_s3_artifact_root = var.cognee_brain_s3_artifact_root
978
+ cognee_brain_s3_manifest_root = var.cognee_brain_s3_manifest_root
979
+ cognee_brain_s3_vault_projection_root = var.cognee_brain_s3_vault_projection_root
980
+ cognee_brain_artifacts_bucket_arn = var.cognee_brain_artifacts_bucket_arn
981
+ cognee_brain_artifacts_prefixes = var.cognee_brain_artifacts_prefixes
982
+ cognee_private_substrate_mode = var.cognee_private_substrate_mode
983
+ cognee_require_authentication = var.cognee_require_authentication
984
+ cognee_enable_backend_access_control = var.cognee_enable_backend_access_control
985
+ cognee_cors_allowed_origins = var.cognee_cors_allowed_origins
986
+ cognee_llm_provider = var.cognee_llm_provider
987
+ cognee_llm_model = var.cognee_llm_model
988
+ cognee_llm_api_key_secret_arn = var.cognee_llm_api_key_secret_arn
989
+ cognee_embedding_provider = var.cognee_embedding_provider
990
+ cognee_embedding_model = var.cognee_embedding_model
991
+ cognee_embedding_dimensions = var.cognee_embedding_dimensions
992
+ cognee_embedding_api_key_secret_arn = var.cognee_embedding_api_key_secret_arn
993
+ cognee_vector_db_provider = var.cognee_vector_db_provider
994
+ cognee_vector_db_url = var.cognee_vector_db_url
995
+ cognee_vector_db_key_secret_arn = var.cognee_vector_db_key_secret_arn
996
+ cognee_graph_database_provider = var.cognee_graph_database_provider
997
+ cognee_graph_database_url = var.cognee_graph_database_url
998
+ cognee_graph_database_username = var.cognee_graph_database_username
999
+ cognee_graph_database_password_secret_arn = var.cognee_graph_database_password_secret_arn
1000
+ cognee_neptune_graph_id = var.cognee_neptune_graph_id
1001
+ cognee_neptune_graph_arn = var.cognee_neptune_graph_arn
1002
+ cognee_neptune_endpoint = var.cognee_neptune_endpoint
1003
+ cognee_production_posture = var.cognee_production_posture
1004
+ cognee_bedrock_model_resource_arns = var.cognee_bedrock_model_resource_arns
1005
+ cognee_kms_key_arns = var.cognee_kms_key_arns
1006
+ twenty_provisioned = var.twenty_provisioned
1007
+ twenty_runtime_enabled = var.twenty_runtime_enabled
1008
+ twenty_image_uri = var.twenty_image_uri
1009
+ twenty_db_username = var.twenty_db_username
1010
+ twenty_db_name = var.twenty_db_name
1011
+ twenty_db_url_secret_arn = var.twenty_db_url_secret_arn
1012
+ twenty_encryption_key_secret_arn = var.twenty_encryption_key_secret_arn
1013
+ twenty_email_from_address = var.twenty_email_from_address
1014
+ twenty_email_from_name = var.twenty_email_from_name
1015
+ twenty_public_url = local.twenty_url
1016
+ twenty_certificate_arn = var.twenty_certificate_arn != "" ? var.twenty_certificate_arn : (local.twenty_managed_certificate_enabled ? aws_acm_certificate_validation.twenty[0].certificate_arn : "")
1017
+ n8n_provisioned = var.n8n_provisioned
1018
+ n8n_runtime_enabled = var.n8n_runtime_enabled
1019
+ n8n_image_uri = var.n8n_image_uri
1020
+ n8n_database_admin_secret_arn = var.n8n_database_admin_secret_arn
1021
+ n8n_database_url_secret_arn = var.n8n_database_url_secret_arn
1022
+ n8n_database_username = var.n8n_database_username
1023
+ n8n_database_name = var.n8n_database_name
1024
+ n8n_encryption_key_secret_arn = var.n8n_encryption_key_secret_arn
1025
+ n8n_operator_secret_arn = var.n8n_operator_secret_arn
1026
+ n8n_service_credential_secret_arn = var.n8n_service_credential_secret_arn
1027
+ n8n_agent_step_bridge_credential_secret_arn = var.n8n_agent_step_bridge_credential_secret_arn
1028
+ n8n_storage_bucket_name = var.n8n_storage_bucket_name
1029
+ n8n_container_port = var.n8n_container_port
1030
+ n8n_cache_engine = var.n8n_cache_engine
1031
+ n8n_domain = local.n8n_domain
1032
+ n8n_public_url = local.n8n_url
1033
+ n8n_certificate_arn = var.n8n_certificate_arn != "" ? var.n8n_certificate_arn : (local.n8n_managed_certificate_enabled ? aws_acm_certificate_validation.n8n[0].certificate_arn : "")
1034
+ google_oauth_client_id = var.google_oauth_client_id
1035
+ google_oauth_client_secret = var.google_oauth_client_secret
1036
+ pre_signup_lambda_zip = var.pre_signup_lambda_zip
1037
+ cognito_custom_auth_lambda_zip = var.cognito_custom_auth_lambda_zip
1038
+ lambda_zips_dir = var.lambda_zips_dir
1039
+ lambda_artifact_bucket = var.lambda_artifact_bucket
1040
+ lambda_artifact_prefix = var.lambda_artifact_prefix
1041
+ require_lambda_artifacts = var.require_lambda_artifacts
1042
+ enable_workspace_orchestration = var.enable_workspace_orchestration
1043
+ api_auth_secret = var.api_auth_secret
1044
+ platform_operator_emails = var.platform_operator_emails
406
1045
 
407
1046
  # Public website custom domain (optional — wired only when www_domain is set)
408
1047
  www_domain = var.www_domain
409
1048
  www_certificate_arn = local.www_dns_enabled ? module.www_dns[0].certificate_arn : ""
410
1049
 
411
1050
  # Docs site custom domain (derived from www_domain — docs.<apex>). The
412
- # same ACM cert covers apex + www + docs + admin so every distribution
1051
+ # same ACM cert covers apex + www + docs + app/computer so every distribution
413
1052
  # shares it.
414
1053
  docs_domain = local.www_dns_enabled ? local.docs_domain : ""
415
1054
  docs_certificate_arn = local.www_dns_enabled ? module.www_dns[0].certificate_arn : ""
416
1055
 
417
- # Admin SPA custom domain (derived from www_domain — admin.<apex>).
418
- admin_domain = local.www_dns_enabled ? local.admin_domain : ""
419
- admin_certificate_arn = local.www_dns_enabled ? module.www_dns[0].certificate_arn : ""
420
-
421
1056
  # End-user app custom domain (derived from www_domain — app.<apex>).
422
1057
  # Same ACM cert covers it via the include_app SAN gate on www_dns.
423
1058
  app_domain = local.www_dns_enabled ? local.app_domain : ""
@@ -431,13 +1066,15 @@ module "thinkwork" {
431
1066
 
432
1067
  # Computer iframe sandbox (derived from www_domain — sandbox.<apex>).
433
1068
  # Uses its own ACM certificate so sandbox bootstrap/rotation cannot replace
434
- # the shared apex/www/docs/admin/computer/api certificate.
1069
+ # the shared apex/www/docs/app/computer/api certificate.
435
1070
  computer_sandbox_domain = local.www_dns_enabled ? local.sandbox_domain : ""
436
1071
  computer_sandbox_certificate_arn = local.www_dns_enabled ? aws_acm_certificate_validation.computer_sandbox[0].certificate_arn : ""
437
- computer_sandbox_allowed_parent_origins = local.www_dns_enabled ? "https://${local.app_domain},https://${local.admin_domain}" : ""
1072
+ computer_sandbox_allowed_parent_origins = local.www_dns_enabled ? "https://${local.app_domain}" : ""
438
1073
 
439
- # SES inbound email subdomain (delegated Route53 subzone).
1074
+ # SES inbound email subdomains (delegated Route53 subzones).
440
1075
  ses_inbound_domain = var.ses_inbound_domain
1076
+ ses_parent_domain = var.ses_parent_domain
1077
+ ses_tenant_slugs = var.tenant_slugs
441
1078
 
442
1079
  # Wiki compile Lambda config. Pinned so unrelated terraform applies
443
1080
  # don't wipe the Bedrock model or the aggregation flag back to
@@ -451,11 +1088,11 @@ module "thinkwork" {
451
1088
  requester_memory_dreaming_enabled = var.requester_memory_dreaming_enabled
452
1089
  requester_memory_dreaming_schedule_expression = var.requester_memory_dreaming_schedule_expression
453
1090
  requester_memory_dreaming_model_id = var.requester_memory_dreaming_model_id
454
- nova_act_api_key = var.nova_act_api_key
455
1091
  agentcore_code_interpreter_id = var.agentcore_code_interpreter_id
1092
+ agentcore_memory_id = var.agentcore_memory_id
456
1093
 
457
- # Mapbox public token for apps/computer MapView primitive. Flows through
458
- # to scripts/build-computer.sh → VITE_MAPBOX_PUBLIC_TOKEN.
1094
+ # Mapbox public token for apps/web MapView primitive. Flows through
1095
+ # to scripts/build-web.sh → VITE_MAPBOX_PUBLIC_TOKEN.
459
1096
  mapbox_public_token = var.mapbox_public_token
460
1097
 
461
1098
  # Stripe billing — internal-plan → price-id map (per-stage, non-secret).
@@ -469,6 +1106,11 @@ module "thinkwork" {
469
1106
  mcp_custom_domain = var.mcp_custom_domain
470
1107
  mcp_custom_domain_ready = var.mcp_custom_domain_ready
471
1108
 
1109
+ # Customer-namespace domain (optional — two-apply flow; see README).
1110
+ customer_domain = var.customer_domain
1111
+ customer_domain_delegated = var.customer_domain_delegated
1112
+ customer_domain_legacy_retired = var.customer_domain_legacy_retired
1113
+
472
1114
  # Greenfield: create everything (all defaults are true)
473
1115
  }
474
1116
 
@@ -492,12 +1134,8 @@ module "www_dns" {
492
1134
  include_docs = true
493
1135
  docs_cloudfront_domain_name = module.thinkwork.docs_distribution_domain
494
1136
 
495
- # Admin: same cycle-avoidance pattern.
496
- include_admin = true
497
- admin_cloudfront_domain_name = module.thinkwork.admin_distribution_domain
498
-
499
- # End-user app: canonical app.<apex> host. The underlying source package is
500
- # still apps/computer for compatibility.
1137
+ # End-user app: canonical app.<apex> host. The compatibility output names
1138
+ # still use computer_* while the source path is apps/web.
501
1139
  include_app = true
502
1140
  app_cloudfront_domain_name = module.thinkwork.app_distribution_domain
503
1141
 
@@ -515,22 +1153,52 @@ module "www_dns" {
515
1153
  include_api = true
516
1154
  api_gateway_id = module.thinkwork.api_id
517
1155
  api_gateway_stage_name = "$default"
1156
+
1157
+ # Twenty CRM custom domain (crm.<apex>). CRM uses its own ACM certificate;
1158
+ # this module owns only the public CNAME to the ALB.
1159
+ include_crm = var.twenty_provisioned
1160
+ crm_alb_dns_name = module.thinkwork.twenty_alb_dns_name != null ? module.thinkwork.twenty_alb_dns_name : ""
1161
+
1162
+ # n8n custom domain (n8n.<apex>). n8n uses its own ACM certificate; this
1163
+ # module owns only the public CNAME to the ALB.
1164
+ include_n8n = var.n8n_provisioned
1165
+ n8n_alb_dns_name = module.thinkwork.n8n_alb_dns_name != null ? module.thinkwork.n8n_alb_dns_name : ""
1166
+
518
1167
  }
519
1168
 
520
1169
  ################################################################################
521
1170
  # SES Inbound DNS Delegation
522
1171
  #
523
- # The ses-email module creates a Route53 hosted zone for var.ses_inbound_domain
524
- # (e.g. agents.thinkwork.ai). For the subzone to resolve, the parent zone
525
- # (thinkwork.ai at Cloudflare) must carry NS records pointing at the 4 AWS name
526
- # servers. New Route53 zones always return exactly 4 name servers, so we can
527
- # hardcode count = 4 without hitting "count value is not known" at plan time.
1172
+ # The ses-email module keeps the legacy Route53 hosted zone for
1173
+ # var.ses_inbound_domain (e.g. agents.thinkwork.ai) and creates one Route53
1174
+ # hosted zone for each tenant subdomain (e.g. dev.thinkwork.ai). For those
1175
+ # subzones to resolve, the parent zone (thinkwork.ai at Cloudflare) must carry
1176
+ # NS records pointing each subdomain at its 4 AWS name servers. New Route53
1177
+ # zones always return exactly 4 name servers, so we can hardcode range(4)
1178
+ # without hitting "for_each value is not known" at plan time.
528
1179
  #
529
- # Without this delegation, terraform creates the Route53 zone and the MX/DKIM
530
- # records inside it, but the outside world asks Cloudflare for agents.thinkwork.ai
531
- # and gets NXDOMAIN because Cloudflare doesn't know to delegate.
1180
+ # Without this delegation, terraform creates the Route53 zones and the MX/DKIM
1181
+ # records inside them, but the outside world asks Cloudflare for
1182
+ # <tenant>.thinkwork.ai and gets NXDOMAIN because Cloudflare doesn't know to
1183
+ # delegate.
532
1184
  ################################################################################
533
1185
 
1186
+ resource "cloudflare_record" "tenant_email_ns" {
1187
+ for_each = var.ses_parent_domain != "" && var.cloudflare_zone_id != "" ? {
1188
+ for pair in setproduct(sort(tolist(var.tenant_slugs)), range(4)) : "${pair[0]}-${pair[1]}" => {
1189
+ slug = pair[0]
1190
+ index = pair[1]
1191
+ }
1192
+ } : {}
1193
+
1194
+ zone_id = var.cloudflare_zone_id
1195
+ name = "${each.value.slug}.${var.ses_parent_domain}"
1196
+ content = module.thinkwork.ses_tenant_name_servers[each.value.slug][each.value.index]
1197
+ type = "NS"
1198
+ ttl = 300
1199
+ proxied = false
1200
+ }
1201
+
534
1202
  resource "cloudflare_record" "agents_ns" {
535
1203
  count = var.ses_inbound_domain != "" && var.cloudflare_zone_id != "" ? 4 : 0
536
1204
 
@@ -578,7 +1246,7 @@ output "appsync_api_key" {
578
1246
  }
579
1247
 
580
1248
  output "mapbox_public_token" {
581
- description = "Mapbox public token used by apps/computer MapView. Read by scripts/build-computer.sh to inline VITE_MAPBOX_PUBLIC_TOKEN at build time; empty string lets MapView fall back to OpenStreetMap tiles."
1249
+ description = "Mapbox public token used by apps/web MapView. Read by scripts/build-web.sh to inline VITE_MAPBOX_PUBLIC_TOKEN at build time; empty string lets MapView fall back to OpenStreetMap tiles."
582
1250
  value = module.thinkwork.mapbox_public_token
583
1251
  sensitive = true
584
1252
  }
@@ -629,7 +1297,7 @@ output "database_name" {
629
1297
  }
630
1298
 
631
1299
  output "hindsight_enabled" {
632
- description = "Whether the Hindsight add-on is enabled"
1300
+ description = "Whether Hindsight canonical memory is enabled"
633
1301
  value = module.thinkwork.hindsight_enabled
634
1302
  }
635
1303
 
@@ -638,24 +1306,144 @@ output "hindsight_endpoint" {
638
1306
  value = module.thinkwork.hindsight_endpoint
639
1307
  }
640
1308
 
641
- output "agentcore_memory_id" {
642
- description = "AgentCore Memory resource ID used for automatic retention"
643
- value = module.thinkwork.agentcore_memory_id
1309
+ output "cognee_enabled" {
1310
+ description = "Whether the Cognee ontology/KG add-on is enabled"
1311
+ value = module.thinkwork.cognee_enabled
644
1312
  }
645
1313
 
646
- output "admin_url" {
647
- description = "Admin app URL"
648
- value = local.www_dns_enabled ? "https://${local.admin_domain}" : "https://${module.thinkwork.admin_distribution_domain}"
1314
+ output "cognee_endpoint" {
1315
+ description = "Internal Cognee API endpoint (null when enable_cognee = false)"
1316
+ value = module.thinkwork.cognee_endpoint
1317
+ }
1318
+
1319
+ output "cognee_log_group_name" {
1320
+ description = "CloudWatch log group for Cognee (null when enable_cognee = false)"
1321
+ value = module.thinkwork.cognee_log_group_name
1322
+ }
1323
+
1324
+ output "cognee_brain_storage_tier" {
1325
+ description = "Company Brain storage tier (null when enable_cognee = false)"
1326
+ value = module.thinkwork.cognee_brain_storage_tier
1327
+ }
1328
+
1329
+ output "cognee_brain_instance_key" {
1330
+ description = "Tenant-scoped Company Brain instance key (null for legacy stage-wide instances)"
1331
+ value = module.thinkwork.cognee_brain_instance_key
1332
+ }
1333
+
1334
+ output "cognee_s3_artifact_root" {
1335
+ description = "Canonical Company Brain S3 source artifact root"
1336
+ value = module.thinkwork.cognee_s3_artifact_root
1337
+ }
1338
+
1339
+ output "cognee_neptune_graph_id" {
1340
+ description = "Neptune Analytics graph ID for production Company Brain"
1341
+ value = module.thinkwork.cognee_neptune_graph_id
1342
+ }
1343
+
1344
+ output "twenty_provisioned" {
1345
+ description = "Whether the Twenty CRM retained managed-app substrate is provisioned"
1346
+ value = module.thinkwork.twenty_provisioned
1347
+ }
1348
+
1349
+ output "twenty_runtime_enabled" {
1350
+ description = "Whether the Twenty CRM server/worker runtime is enabled"
1351
+ value = module.thinkwork.twenty_runtime_enabled
649
1352
  }
650
1353
 
651
- output "admin_distribution_id" {
652
- description = "CloudFront distribution ID for admin (for cache invalidation)"
653
- value = module.thinkwork.admin_distribution_id
1354
+ output "twenty_url" {
1355
+ description = "Public Twenty CRM URL (null when twenty_provisioned = false)"
1356
+ value = module.thinkwork.twenty_url
654
1357
  }
655
1358
 
656
- output "admin_bucket_name" {
657
- description = "S3 bucket for admin app assets"
658
- value = module.thinkwork.admin_bucket_name
1359
+ output "twenty_cluster_arn" {
1360
+ description = "ECS cluster ARN for Twenty CRM (null when twenty_provisioned = false)"
1361
+ value = module.thinkwork.twenty_cluster_arn
1362
+ }
1363
+
1364
+ output "twenty_server_service_name" {
1365
+ description = "ECS service name for the Twenty server (null when twenty_provisioned = false)"
1366
+ value = module.thinkwork.twenty_server_service_name
1367
+ }
1368
+
1369
+ output "twenty_worker_service_name" {
1370
+ description = "ECS service name for the Twenty worker (null when twenty_provisioned = false)"
1371
+ value = module.thinkwork.twenty_worker_service_name
1372
+ }
1373
+
1374
+ output "twenty_server_log_group_name" {
1375
+ description = "CloudWatch log group for the Twenty server (null when twenty_provisioned = false)"
1376
+ value = module.thinkwork.twenty_server_log_group_name
1377
+ }
1378
+
1379
+ output "twenty_worker_log_group_name" {
1380
+ description = "CloudWatch log group for the Twenty worker (null when twenty_provisioned = false)"
1381
+ value = module.thinkwork.twenty_worker_log_group_name
1382
+ }
1383
+
1384
+ output "twenty_cache_endpoint" {
1385
+ description = "ElastiCache primary endpoint for Twenty CRM (null when twenty_provisioned = false)"
1386
+ value = module.thinkwork.twenty_cache_endpoint
1387
+ }
1388
+
1389
+ output "n8n_provisioned" {
1390
+ description = "Whether the n8n retained managed-app substrate is provisioned"
1391
+ value = module.thinkwork.n8n_provisioned
1392
+ }
1393
+
1394
+ output "n8n_runtime_enabled" {
1395
+ description = "Whether n8n ECS services are enabled"
1396
+ value = module.thinkwork.n8n_runtime_enabled
1397
+ }
1398
+
1399
+ output "n8n_url" {
1400
+ description = "Public n8n URL (null when n8n_provisioned = false)"
1401
+ value = module.thinkwork.n8n_url
1402
+ }
1403
+
1404
+ output "n8n_cluster_arn" {
1405
+ description = "ECS cluster ARN for n8n (null when n8n_provisioned = false)"
1406
+ value = module.thinkwork.n8n_cluster_arn
1407
+ }
1408
+
1409
+ output "n8n_main_service_name" {
1410
+ description = "ECS service name for n8n main (null when n8n_provisioned = false)"
1411
+ value = module.thinkwork.n8n_main_service_name
1412
+ }
1413
+
1414
+ output "n8n_worker_service_name" {
1415
+ description = "ECS service name for n8n worker (null when n8n_provisioned = false)"
1416
+ value = module.thinkwork.n8n_worker_service_name
1417
+ }
1418
+
1419
+ output "n8n_valkey_endpoint" {
1420
+ description = "ElastiCache primary endpoint for n8n queue mode (null when n8n_provisioned = false)"
1421
+ value = module.thinkwork.n8n_valkey_endpoint
1422
+ }
1423
+
1424
+ output "n8n_storage_bucket_name" {
1425
+ description = "S3 bucket name used for n8n managed artifacts (null when n8n_provisioned = false)"
1426
+ value = module.thinkwork.n8n_storage_bucket_name
1427
+ }
1428
+
1429
+ output "n8n_service_credential_secret_arn" {
1430
+ description = "Secrets Manager ARN used for the n8n MCP tenant service credential (null when n8n_provisioned = false)"
1431
+ value = module.thinkwork.n8n_service_credential_secret_arn
1432
+ }
1433
+
1434
+ output "n8n_agent_step_bridge_credential_secret_arn" {
1435
+ description = "Secrets Manager ARN used for the inbound n8n agent-step bridge credential (null when n8n_provisioned = false)"
1436
+ value = module.thinkwork.n8n_agent_step_bridge_credential_secret_arn
1437
+ }
1438
+
1439
+ output "agentcore_memory_id" {
1440
+ description = "AgentCore Memory resource ID used for automatic retention"
1441
+ value = module.thinkwork.agentcore_memory_id
1442
+ }
1443
+
1444
+ output "admin_url" {
1445
+ description = "Deprecated compatibility alias for app_url"
1446
+ value = local.www_dns_enabled ? "https://${local.app_domain}" : "https://${module.thinkwork.app_distribution_domain}"
659
1447
  }
660
1448
 
661
1449
  output "app_url" {
@@ -673,6 +1461,31 @@ output "app_bucket_name" {
673
1461
  value = module.thinkwork.app_bucket_name
674
1462
  }
675
1463
 
1464
+ output "deployment_state_machine_arn" {
1465
+ description = "Deployment orchestration Step Functions state machine ARN."
1466
+ value = module.thinkwork.deployment_state_machine_arn
1467
+ }
1468
+
1469
+ output "deployment_state_machine_name" {
1470
+ description = "Deployment orchestration Step Functions state machine name."
1471
+ value = module.thinkwork.deployment_state_machine_name
1472
+ }
1473
+
1474
+ output "deployment_runner_project_name" {
1475
+ description = "CodeBuild project name for the deployment runner."
1476
+ value = module.thinkwork.deployment_runner_project_name
1477
+ }
1478
+
1479
+ output "deployment_runner_project_arn" {
1480
+ description = "CodeBuild project ARN for the deployment runner."
1481
+ value = module.thinkwork.deployment_runner_project_arn
1482
+ }
1483
+
1484
+ output "deployment_evidence_bucket_name" {
1485
+ description = "S3 bucket for deployment evidence artifacts."
1486
+ value = module.thinkwork.deployment_evidence_bucket_name
1487
+ }
1488
+
676
1489
  output "computer_url" {
677
1490
  description = "Deprecated alias for app_url"
678
1491
  value = local.www_dns_enabled ? "https://${local.app_domain}" : "https://${module.thinkwork.app_distribution_domain}"
@@ -743,18 +1556,28 @@ output "www_bucket_name" {
743
1556
  value = module.thinkwork.www_bucket_name
744
1557
  }
745
1558
 
1559
+ output "ses_inbound_zone_ids" {
1560
+ description = "Route53 hosted zone IDs for tenant email subdomains, keyed by tenant slug"
1561
+ value = module.thinkwork.ses_inbound_zone_ids
1562
+ }
1563
+
746
1564
  output "ses_inbound_zone_id" {
747
- description = "Route53 hosted zone ID for the email subdomain (null when ses_inbound_domain is not set)"
1565
+ description = "Route53 hosted zone ID for the legacy email subdomain (null when ses_inbound_domain is not set)"
748
1566
  value = module.thinkwork.ses_inbound_zone_id
749
1567
  }
750
1568
 
1569
+ output "ses_tenant_name_servers" {
1570
+ description = "Name servers for delegated tenant email subzones, keyed by tenant slug. Published to Cloudflare when cloudflare_zone_id is set."
1571
+ value = module.thinkwork.ses_tenant_name_servers
1572
+ }
1573
+
751
1574
  output "ses_inbound_name_servers" {
752
- description = "Name servers for the delegated email subzone. Paste these as NS records at the registrar that hosts the parent domain (Google Domains for thinkwork.ai) before SES can verify."
1575
+ description = "Name servers for the legacy delegated email subzone."
753
1576
  value = module.thinkwork.ses_inbound_name_servers
754
1577
  }
755
1578
 
756
1579
  output "ses_inbound_mx_target" {
757
- description = "MX target host for the email subdomain. Already written into the subzone by Terraform — informational."
1580
+ description = "MX target host for tenant email subdomains. Already written into each subzone by Terraform — informational."
758
1581
  value = module.thinkwork.ses_inbound_mx_target
759
1582
  }
760
1583
 
@@ -778,3 +1601,8 @@ output "mcp_custom_domain_target" {
778
1601
  description = "Regional target for the final mcp CNAME — only populated on the second apply after mcp_custom_domain_ready=true. { target_domain_name, hosted_zone_id } or null."
779
1602
  value = module.thinkwork.mcp_custom_domain_target
780
1603
  }
1604
+
1605
+ output "customer_domain_name_servers" {
1606
+ description = "The four Route53 name servers for the customer-domain zone — publish these via the claim tool's `claim --set-targets` to delegate (empty when no customer domain is configured)."
1607
+ value = module.thinkwork.customer_domain_name_servers
1608
+ }