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
@@ -0,0 +1,79 @@
1
+ output "twenty_url" {
2
+ description = "Public Twenty CRM URL"
3
+ value = var.public_url
4
+ }
5
+
6
+ output "twenty_alb_dns_name" {
7
+ description = "Public ALB DNS name for Twenty"
8
+ value = aws_lb.twenty.dns_name
9
+ }
10
+
11
+ output "twenty_alb_arn" {
12
+ description = "Public ALB ARN for Twenty"
13
+ value = aws_lb.twenty.arn
14
+ }
15
+
16
+ output "twenty_target_group_arn" {
17
+ description = "Target group ARN for the Twenty server"
18
+ value = aws_lb_target_group.twenty.arn
19
+ }
20
+
21
+ output "twenty_cluster_arn" {
22
+ description = "ECS cluster ARN for Twenty"
23
+ value = aws_ecs_cluster.main.arn
24
+ }
25
+
26
+ output "twenty_server_service_name" {
27
+ description = "ECS service name for the Twenty server"
28
+ value = aws_ecs_service.server.name
29
+ }
30
+
31
+ output "twenty_worker_service_name" {
32
+ description = "ECS service name for the Twenty worker"
33
+ value = aws_ecs_service.worker.name
34
+ }
35
+
36
+ output "twenty_server_log_group_name" {
37
+ description = "CloudWatch log group for the Twenty server"
38
+ value = aws_cloudwatch_log_group.server.name
39
+ }
40
+
41
+ output "twenty_worker_log_group_name" {
42
+ description = "CloudWatch log group for the Twenty worker"
43
+ value = aws_cloudwatch_log_group.worker.name
44
+ }
45
+
46
+ output "twenty_security_group_id" {
47
+ description = "Security group ID for the Twenty ECS tasks"
48
+ value = aws_security_group.twenty.id
49
+ }
50
+
51
+ output "twenty_storage_file_system_id" {
52
+ description = "EFS file system ID backing Twenty local storage"
53
+ value = aws_efs_file_system.twenty.id
54
+ }
55
+
56
+ output "twenty_cache_replication_group_id" {
57
+ description = "ElastiCache replication group ID for Twenty"
58
+ value = aws_elasticache_replication_group.twenty.id
59
+ }
60
+
61
+ output "twenty_cache_endpoint" {
62
+ description = "ElastiCache primary endpoint for Twenty"
63
+ value = aws_elasticache_replication_group.twenty.primary_endpoint_address
64
+ }
65
+
66
+ output "twenty_runtime_enabled" {
67
+ description = "Whether the Twenty server and worker are configured to run"
68
+ value = var.runtime_enabled
69
+ }
70
+
71
+ output "twenty_db_url_secret_arn" {
72
+ description = "Secrets Manager ARN used for the Twenty PG_DATABASE_URL"
73
+ value = local.effective_db_url_secret_arn
74
+ }
75
+
76
+ output "twenty_encryption_key_secret_arn" {
77
+ description = "Secrets Manager ARN used for the Twenty ENCRYPTION_KEY"
78
+ value = local.effective_encryption_key_secret_arn
79
+ }
@@ -0,0 +1,268 @@
1
+ variable "stage" {
2
+ description = "Deployment stage (e.g. dev, prod)"
3
+ type = string
4
+ }
5
+
6
+ variable "vpc_id" {
7
+ description = "VPC ID for Twenty CRM networking"
8
+ type = string
9
+ }
10
+
11
+ variable "subnet_ids" {
12
+ description = "Public subnet IDs for the Twenty ECS tasks and public ALB. Public subnets provide outbound egress in phase 1."
13
+ type = list(string)
14
+
15
+ validation {
16
+ condition = length(var.subnet_ids) > 0
17
+ error_message = "subnet_ids must include at least one public subnet for the Twenty ALB and ECS tasks."
18
+ }
19
+ }
20
+
21
+ variable "cache_subnet_ids" {
22
+ description = "Private subnet IDs for the ElastiCache subnet group. Leave empty to reuse subnet_ids in isolated test fixtures only."
23
+ type = list(string)
24
+ default = []
25
+ }
26
+
27
+ variable "storage_subnet_ids" {
28
+ description = "Subnet IDs for EFS mount targets. Leave empty to reuse subnet_ids."
29
+ type = list(string)
30
+ default = []
31
+ }
32
+
33
+ variable "db_security_group_id" {
34
+ description = "Security group ID for the shared PostgreSQL database instance"
35
+ type = string
36
+ }
37
+
38
+ variable "db_port" {
39
+ description = "PostgreSQL port for Twenty's dedicated database"
40
+ type = number
41
+ default = 5432
42
+ }
43
+
44
+ variable "public_url" {
45
+ description = "Public HTTPS URL for Twenty, for example https://crm.example.com"
46
+ type = string
47
+
48
+ validation {
49
+ condition = can(regex("^https://[^/]+$", var.public_url))
50
+ error_message = "public_url must be an HTTPS origin without a path, for example https://crm.example.com."
51
+ }
52
+ }
53
+
54
+ variable "certificate_arn" {
55
+ description = "ACM certificate ARN used by the public HTTPS ALB listener"
56
+ type = string
57
+
58
+ validation {
59
+ condition = can(regex("^arn:aws(-[a-z]+)?:acm:[^:]+:[0-9]{12}:certificate/.+", var.certificate_arn))
60
+ error_message = "certificate_arn must be an ACM certificate ARN."
61
+ }
62
+ }
63
+
64
+ variable "image_uri" {
65
+ description = "Twenty CRM container image URI pinned to a reviewed immutable digest."
66
+ type = string
67
+
68
+ validation {
69
+ condition = can(regex("@sha256:[0-9a-f]{64}$", var.image_uri))
70
+ error_message = "image_uri must be pinned to an immutable sha256 image digest."
71
+ }
72
+ }
73
+
74
+ variable "runtime_enabled" {
75
+ description = "Whether the Twenty server and worker should run. Set false to park runtime while retaining data resources."
76
+ type = bool
77
+ default = true
78
+ }
79
+
80
+ variable "server_desired_count" {
81
+ description = "Desired Twenty server task count when runtime_enabled is true"
82
+ type = number
83
+ default = 1
84
+ }
85
+
86
+ variable "worker_desired_count" {
87
+ description = "Desired Twenty worker task count when runtime_enabled is true"
88
+ type = number
89
+ default = 1
90
+ }
91
+
92
+ variable "cpu" {
93
+ description = "Fargate task CPU units for each Twenty task"
94
+ type = number
95
+ default = 1024
96
+ }
97
+
98
+ variable "memory" {
99
+ description = "Fargate task memory in MB for each Twenty task"
100
+ type = number
101
+ default = 2048
102
+ }
103
+
104
+ variable "cpu_architecture" {
105
+ description = "Fargate CPU architecture for Twenty tasks"
106
+ type = string
107
+ default = "X86_64"
108
+
109
+ validation {
110
+ condition = contains(["X86_64", "ARM64"], var.cpu_architecture)
111
+ error_message = "cpu_architecture must be X86_64 or ARM64."
112
+ }
113
+ }
114
+
115
+ variable "container_port" {
116
+ description = "Twenty server container port"
117
+ type = number
118
+ default = 3000
119
+ }
120
+
121
+ variable "health_check_path" {
122
+ description = "HTTP path used by ALB and container health checks"
123
+ type = string
124
+ default = "/healthz"
125
+ }
126
+
127
+ variable "health_check_grace_period_seconds" {
128
+ description = "Seconds ECS ignores failing load balancer health checks while Twenty starts"
129
+ type = number
130
+ default = 300
131
+ }
132
+
133
+ variable "wait_for_steady_state" {
134
+ description = "Whether Terraform waits for the Twenty ECS services to reach steady state"
135
+ type = bool
136
+ default = true
137
+ }
138
+
139
+ variable "log_retention_days" {
140
+ description = "CloudWatch log retention for Twenty services"
141
+ type = number
142
+ default = 14
143
+ }
144
+
145
+ variable "db_url_secret_arn" {
146
+ description = "Secrets Manager ARN containing a JSON PG_DATABASE_URL field for Twenty's dedicated database."
147
+ type = string
148
+ default = ""
149
+ }
150
+
151
+ variable "encryption_key_secret_arn" {
152
+ description = "Secrets Manager ARN containing a JSON ENCRYPTION_KEY field for Twenty."
153
+ type = string
154
+ default = ""
155
+ }
156
+
157
+ variable "fallback_encryption_key_secret_arn" {
158
+ description = "Optional Secrets Manager ARN containing a JSON FALLBACK_ENCRYPTION_KEY field during key rotation."
159
+ type = string
160
+ default = ""
161
+ }
162
+
163
+ variable "app_secret_arn" {
164
+ description = "Optional Secrets Manager ARN containing a JSON APP_SECRET field for legacy Twenty compatibility."
165
+ type = string
166
+ default = ""
167
+ }
168
+
169
+ variable "create_secret_placeholders" {
170
+ description = "Create operator-owned Secrets Manager placeholder containers for missing Twenty secrets. Secret values are placeholders and ignored after creation so rotation survives Terraform applies."
171
+ type = bool
172
+ default = false
173
+ }
174
+
175
+ variable "kms_key_arns" {
176
+ description = "Optional KMS key ARNs needed to decrypt injected secrets"
177
+ type = list(string)
178
+ default = []
179
+ }
180
+
181
+ variable "email_from_address" {
182
+ description = "Verified SES sender address for Twenty app emails. Leave empty to skip SMTP configuration."
183
+ type = string
184
+ default = ""
185
+ }
186
+
187
+ variable "email_from_name" {
188
+ description = "Display name for Twenty app email From headers."
189
+ type = string
190
+ default = "ThinkWork CRM"
191
+ }
192
+
193
+ variable "email_smtp_host" {
194
+ description = "SES SMTP host for Twenty app emails. Leave empty to use email-smtp.<region>.amazonaws.com."
195
+ type = string
196
+ default = ""
197
+ }
198
+
199
+ variable "email_smtp_port" {
200
+ description = "SES SMTP port for Twenty app emails."
201
+ type = number
202
+ default = 587
203
+ }
204
+
205
+ variable "email_smtp_no_tls" {
206
+ description = "Set true to disable TLS for Twenty SMTP. SES should use TLS."
207
+ type = bool
208
+ default = false
209
+ }
210
+
211
+ variable "cache_engine" {
212
+ description = "ElastiCache engine. Prefer valkey; redis is available as a compatibility fallback."
213
+ type = string
214
+ default = "valkey"
215
+
216
+ validation {
217
+ condition = contains(["valkey", "redis"], var.cache_engine)
218
+ error_message = "cache_engine must be valkey or redis."
219
+ }
220
+ }
221
+
222
+ variable "cache_engine_version" {
223
+ description = "ElastiCache engine version for the selected cache engine"
224
+ type = string
225
+ default = "8.0"
226
+ }
227
+
228
+ variable "cache_parameter_group_family" {
229
+ description = "ElastiCache parameter group family matching cache_engine/cache_engine_version"
230
+ type = string
231
+ default = "valkey8"
232
+ }
233
+
234
+ variable "cache_node_type" {
235
+ description = "ElastiCache node type for the Twenty queue/cache"
236
+ type = string
237
+ default = "cache.t4g.micro"
238
+ }
239
+
240
+ variable "cache_port" {
241
+ description = "ElastiCache Redis-compatible port"
242
+ type = number
243
+ default = 6379
244
+ }
245
+
246
+ variable "cache_num_cache_clusters" {
247
+ description = "Number of cache nodes in the replication group. Use 1 for the smallest v1 deployment."
248
+ type = number
249
+ default = 1
250
+ }
251
+
252
+ variable "cache_transit_encryption_enabled" {
253
+ description = "Enable in-transit encryption for the Twenty cache"
254
+ type = bool
255
+ default = true
256
+ }
257
+
258
+ variable "allowed_public_cidr_blocks" {
259
+ description = "CIDR blocks allowed to reach the public Twenty HTTPS ALB."
260
+ type = list(string)
261
+ default = ["0.0.0.0/0"]
262
+ }
263
+
264
+ variable "enable_http_redirect" {
265
+ description = "Whether the public ALB should redirect HTTP requests to HTTPS"
266
+ type = bool
267
+ default = true
268
+ }
@@ -0,0 +1,183 @@
1
+ /**
2
+ * U10 Twenty cutover tests — fake deps, no DB. Covers adoption, the
3
+ * plugin-row-already-exists dedupe branch, token invalidation, the
4
+ * missing-install precondition, and idempotent re-runs.
5
+ */
6
+
7
+ import { describe, expect, it, vi } from "vitest";
8
+
9
+ import {
10
+ cutoverTwentyPluginForTenant,
11
+ TWENTY_PLUGIN_MCP_SLUG,
12
+ type TwentyCutoverAuditInput,
13
+ type TwentyCutoverDeps,
14
+ } from "../../src/api/cutover.js";
15
+
16
+ interface FakeState {
17
+ install: { id: string } | null;
18
+ legacy: { id: string; url: string } | null;
19
+ pluginRow: { id: string; url: string } | null;
20
+ tokenCount: number;
21
+ }
22
+
23
+ function fakeDeps(state: FakeState) {
24
+ const calls = {
25
+ invalidatedServerIds: [] as string[],
26
+ adopted: [] as Array<Record<string, unknown>>,
27
+ removed: [] as Array<Record<string, unknown>>,
28
+ audits: [] as TwentyCutoverAuditInput[],
29
+ };
30
+ const deps: TwentyCutoverDeps = {
31
+ getTwentyInstall: vi.fn(async () => state.install),
32
+ getLegacyManagedRow: vi.fn(async () => state.legacy),
33
+ getPluginRow: vi.fn(async () => state.pluginRow),
34
+ invalidateUserTokens: vi.fn(async (serverId: string) => {
35
+ calls.invalidatedServerIds.push(serverId);
36
+ const count = state.tokenCount;
37
+ state.tokenCount = 0;
38
+ return count;
39
+ }),
40
+ adoptLegacyRow: vi.fn(async (args) => {
41
+ calls.adopted.push(args as unknown as Record<string, unknown>);
42
+ calls.audits.push(args.audit);
43
+ // Adoption flips the legacy row into the plugin row.
44
+ state.pluginRow = state.legacy;
45
+ state.legacy = null;
46
+ }),
47
+ removeLegacyRow: vi.fn(async (args) => {
48
+ calls.removed.push(args as unknown as Record<string, unknown>);
49
+ calls.audits.push(args.audit);
50
+ state.legacy = null;
51
+ }),
52
+ };
53
+ return { deps, calls };
54
+ }
55
+
56
+ const actor = {
57
+ tenantId: "tenant-1",
58
+ actorId: "user-1",
59
+ actorType: "user" as const,
60
+ };
61
+
62
+ describe("cutoverTwentyPluginForTenant", () => {
63
+ it("requires the twenty plugin install to exist", async () => {
64
+ const { deps } = fakeDeps({
65
+ install: null,
66
+ legacy: { id: "legacy-1", url: "https://crm.example.com/mcp" },
67
+ pluginRow: null,
68
+ tokenCount: 2,
69
+ });
70
+ await expect(cutoverTwentyPluginForTenant(actor, deps)).rejects.toThrow(
71
+ /Install the twenty plugin/,
72
+ );
73
+ });
74
+
75
+ it("adopts the legacy managed row: tokens invalidated, ownership + component pointer updated, audit emitted", async () => {
76
+ const { deps, calls } = fakeDeps({
77
+ install: { id: "install-1" },
78
+ legacy: { id: "legacy-1", url: "https://crm.example.com/mcp" },
79
+ pluginRow: null,
80
+ tokenCount: 3,
81
+ });
82
+
83
+ const result = await cutoverTwentyPluginForTenant(actor, deps);
84
+
85
+ expect(result).toMatchObject({
86
+ adopted: true,
87
+ mcpServerId: "legacy-1",
88
+ invalidatedUserTokenCount: 3,
89
+ });
90
+ expect(calls.invalidatedServerIds).toEqual(["legacy-1"]);
91
+ expect(calls.adopted).toHaveLength(1);
92
+ expect(calls.adopted[0]).toMatchObject({
93
+ tenantId: "tenant-1",
94
+ installId: "install-1",
95
+ serverId: "legacy-1",
96
+ serverUrl: "https://crm.example.com/mcp",
97
+ });
98
+ expect(calls.removed).toHaveLength(0);
99
+ expect(calls.audits[0]).toMatchObject({
100
+ eventType: "plugin.cutover",
101
+ actorId: "user-1",
102
+ actorType: "user",
103
+ resourceId: "install-1",
104
+ payload: {
105
+ pluginKey: "twenty",
106
+ mcpServerId: "legacy-1",
107
+ mode: "adopted",
108
+ invalidatedUserTokenCount: 3,
109
+ },
110
+ });
111
+ });
112
+
113
+ it("removes the redundant legacy row when the plugin handler already provisioned its own", async () => {
114
+ const { deps, calls } = fakeDeps({
115
+ install: { id: "install-1" },
116
+ legacy: { id: "legacy-1", url: "https://crm.example.com/mcp" },
117
+ pluginRow: { id: "plugin-1", url: "https://crm.example.com/mcp" },
118
+ tokenCount: 1,
119
+ });
120
+
121
+ const result = await cutoverTwentyPluginForTenant(actor, deps);
122
+
123
+ expect(result).toMatchObject({
124
+ adopted: true,
125
+ mcpServerId: "plugin-1",
126
+ invalidatedUserTokenCount: 1,
127
+ });
128
+ // Tokens invalidated on the LEGACY row (the one users connected to).
129
+ expect(calls.invalidatedServerIds).toEqual(["legacy-1"]);
130
+ expect(calls.adopted).toHaveLength(0);
131
+ expect(calls.removed[0]).toMatchObject({ serverId: "legacy-1" });
132
+ expect(calls.audits[0]).toMatchObject({
133
+ payload: { mode: "legacy_row_removed", mcpServerId: "plugin-1" },
134
+ });
135
+ });
136
+
137
+ it("is idempotent: a re-run after adoption reports a no-op and touches nothing", async () => {
138
+ const state: FakeState = {
139
+ install: { id: "install-1" },
140
+ legacy: { id: "legacy-1", url: "https://crm.example.com/mcp" },
141
+ pluginRow: null,
142
+ tokenCount: 2,
143
+ };
144
+ const { deps, calls } = fakeDeps(state);
145
+
146
+ const first = await cutoverTwentyPluginForTenant(actor, deps);
147
+ expect(first.adopted).toBe(true);
148
+
149
+ const second = await cutoverTwentyPluginForTenant(actor, deps);
150
+ expect(second).toMatchObject({
151
+ adopted: false,
152
+ mcpServerId: "legacy-1",
153
+ invalidatedUserTokenCount: 0,
154
+ });
155
+ expect(second.message).toMatch(/idempotent re-run/);
156
+ // No second invalidation, adoption, removal, or audit.
157
+ expect(calls.invalidatedServerIds).toEqual(["legacy-1"]);
158
+ expect(calls.adopted).toHaveLength(1);
159
+ expect(calls.removed).toHaveLength(0);
160
+ expect(calls.audits).toHaveLength(1);
161
+ });
162
+
163
+ it("reports a no-op when no managed Twenty MCP row ever existed", async () => {
164
+ const { deps, calls } = fakeDeps({
165
+ install: { id: "install-1" },
166
+ legacy: null,
167
+ pluginRow: null,
168
+ tokenCount: 0,
169
+ });
170
+
171
+ const result = await cutoverTwentyPluginForTenant(actor, deps);
172
+ expect(result).toMatchObject({
173
+ adopted: false,
174
+ mcpServerId: null,
175
+ invalidatedUserTokenCount: 0,
176
+ });
177
+ expect(calls.audits).toHaveLength(0);
178
+ });
179
+
180
+ it("adopts under the plugin handler's canonical slug so re-provision converges", () => {
181
+ expect(TWENTY_PLUGIN_MCP_SLUG).toBe("twenty--crm");
182
+ });
183
+ });