thinkwork-cli 0.12.11 → 0.12.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/README.md +42 -38
  2. package/dist/{api-client-ASJWIG3Z.js → api-client-4VT3FWOH.js} +1 -1
  3. package/dist/{chunk-JEHV35EU.js → chunk-H7AB42ES.js} +340 -30
  4. package/dist/cli.js +22157 -9229
  5. package/dist/commands/enterprise/templates/deploy-repo/.github/workflows/deploy.yml +17 -6
  6. package/dist/commands/enterprise/templates/deploy-repo/docs/runbook.md +81 -9
  7. package/dist/commands/enterprise/templates/deploy-repo/scripts/apply-release.mjs +183 -21
  8. package/dist/commands/enterprise/templates/deploy-repo/scripts/smoke.mjs +1 -2
  9. package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +286 -0
  10. package/dist/drizzle/0000_petite_marvel_apes.sql +1188 -0
  11. package/dist/drizzle/0001_milky_surge.sql +103 -0
  12. package/dist/drizzle/0002_aberrant_mattie_franklin.sql +41 -0
  13. package/dist/drizzle/0003_exotic_ogun.sql +3 -0
  14. package/dist/drizzle/0004_glamorous_magneto.sql +2 -0
  15. package/dist/drizzle/0005_ancient_nocturne.sql +2 -0
  16. package/dist/drizzle/0006_new_colonel_america.sql +2 -0
  17. package/dist/drizzle/0007_unique_external_task_id.sql +31 -0
  18. package/dist/drizzle/0008_external_task_id_column.sql +43 -0
  19. package/dist/drizzle/0009_evaluations.sql +64 -0
  20. package/dist/drizzle/0010_eval_agent_template.sql +2 -0
  21. package/dist/drizzle/0011_eval_run_template.sql +2 -0
  22. package/dist/drizzle/0012_eval_seed_unique.sql +16 -0
  23. package/dist/drizzle/0013_motionless_white_queen.sql +140 -0
  24. package/dist/drizzle/0014_wiki_aggregation.sql +11 -0
  25. package/dist/drizzle/0015_pg_trgm_alias_title_indexes.sql +9 -0
  26. package/dist/drizzle/0016_wiki_schema_drops.sql +24 -0
  27. package/dist/drizzle/0017_wiki_places.sql +46 -0
  28. package/dist/drizzle/0018_agent_workspace_overlay.sql +26 -0
  29. package/dist/drizzle/0018_cool_firebird.sql +24 -0
  30. package/dist/drizzle/0018_skill_runs.sql +84 -0
  31. package/dist/drizzle/0019_condemned_dragon_man.sql +95 -0
  32. package/dist/drizzle/0019_webhook_skill_runs.sql +58 -0
  33. package/dist/drizzle/0020_crazy_the_anarchist.sql +9 -0
  34. package/dist/drizzle/0020_mutation_idempotency.sql +64 -0
  35. package/dist/drizzle/0021_crm_work_links.sql +76 -0
  36. package/dist/drizzle/0021_skill_runs_completion_hmac.sql +33 -0
  37. package/dist/drizzle/0022_add_billing_tables.sql +70 -0
  38. package/dist/drizzle/0022_seed_thinkwork_admin_permissions.sql +160 -0
  39. package/dist/drizzle/0022_stripe_billing_indexes.sql +48 -0
  40. package/dist/drizzle/0023_tenants_deactivation.sql +27 -0
  41. package/dist/drizzle/0024_tenant_mcp_admin_keys.sql +63 -0
  42. package/dist/drizzle/0025_v1_agent_architecture.sql +182 -0
  43. package/dist/drizzle/0026_thread_turns_add_kind.sql +28 -0
  44. package/dist/drizzle/0027_capability_catalog_and_manifests.sql +219 -0
  45. package/dist/drizzle/0028_aws_s3_extension.sql +26 -0
  46. package/dist/drizzle/0029_collapse_execution_types.sql +42 -0
  47. package/dist/drizzle/0030_retire_composition_primitives.sql +48 -0
  48. package/dist/drizzle/0031_thread_cleanup_drops.sql +131 -0
  49. package/dist/drizzle/0032_add_browser_automation_template_config.sql +24 -0
  50. package/dist/drizzle/0033_agent_operation_leases.sql +32 -0
  51. package/dist/drizzle/0034_agent_workspace_events.sql +116 -0
  52. package/dist/drizzle/0035_workspace_review_decisions.sql +19 -0
  53. package/dist/drizzle/0036_user_scoped_memory_wiki.sql +152 -0
  54. package/dist/drizzle/0037_user_profile_operating_model.sql +34 -0
  55. package/dist/drizzle/0042_agent_runtime_selector.sql +41 -0
  56. package/dist/drizzle/0043_wiki_search_tsv_tokenization.sql +48 -0
  57. package/dist/drizzle/0044_add_web_search_template_config.sql +7 -0
  58. package/dist/drizzle/0045_add_send_email_template_config.sql +7 -0
  59. package/dist/drizzle/0046_tenant_mcp_context_tools.sql +26 -0
  60. package/dist/drizzle/0047_add_context_engine_template_config.sql +7 -0
  61. package/dist/drizzle/0048_tenant_context_provider_settings.sql +22 -0
  62. package/dist/drizzle/0050_brain_v0_entity_subtype.sql +29 -0
  63. package/dist/drizzle/0051_brain_v0_tenant_entity_pages.sql +170 -0
  64. package/dist/drizzle/0052_brain_v0_external_refs.sql +41 -0
  65. package/dist/drizzle/0053_brain_v0_unresolved_mentions_subtype.sql +48 -0
  66. package/dist/drizzle/0054_wiki_compile_jobs_input.sql +28 -0
  67. package/dist/drizzle/0055_routines_stepfunctions_substrate.sql +202 -0
  68. package/dist/drizzle/0056_routine_step_events_dedup_idx.sql +25 -0
  69. package/dist/drizzle/0057_archive_legacy_python_routines.sql +36 -0
  70. package/dist/drizzle/0058_routines_visibility_and_owning_agent.sql +61 -0
  71. package/dist/drizzle/0061_routine_execution_asl_version_id.sql +29 -0
  72. package/dist/drizzle/0062_migrate_pi_to_flue.sql +110 -0
  73. package/dist/drizzle/0063_threads_session_data.sql +23 -0
  74. package/dist/drizzle/0064_tenant_credentials.sql +65 -0
  75. package/dist/drizzle/0067_thinkwork_computers_phase_one.sql +174 -0
  76. package/dist/drizzle/0068_drop_system_workflows_and_activation.sql +115 -0
  77. package/dist/drizzle/0069_compliance_schema.sql +364 -0
  78. package/dist/drizzle/0070_compliance_aurora_roles.sql +171 -0
  79. package/dist/drizzle/0072_threads_computer_ownership.sql +24 -0
  80. package/dist/drizzle/0073_compliance_tenant_anchor_state.sql +105 -0
  81. package/dist/drizzle/0074_compliance_event_hash_index.sql +49 -0
  82. package/dist/drizzle/0075_scheduled_jobs_computer_ownership.sql +27 -0
  83. package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +69 -0
  84. package/dist/drizzle/0077_computers_primary_agent_id.sql +38 -0
  85. package/dist/drizzle/0078_tenant_customize_catalog.sql +46 -0
  86. package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +53 -0
  87. package/dist/drizzle/0081_routines_catalog_slug.sql +42 -0
  88. package/dist/drizzle/0082_messages_parts_jsonb.sql +52 -0
  89. package/dist/drizzle/0083_computer_runbooks.sql +103 -0
  90. package/dist/drizzle/0084_artifacts_favorited_at.sql +32 -0
  91. package/dist/drizzle/0085_seed_thinkwork_computer_default_template.sql +46 -0
  92. package/dist/drizzle/0086_update_default_template_models.sql +19 -0
  93. package/dist/drizzle/0087_retire_oss_connectors.sql +77 -0
  94. package/dist/drizzle/0088_compliance_event_types_finance_pilot.sql +37 -0
  95. package/dist/drizzle/0089_remove_maniflow_eval_seeds.sql +81 -0
  96. package/dist/drizzle/0089_wiki_schema_extraction.sql +315 -0
  97. package/dist/drizzle/0090_brain_schema_extraction.sql +274 -0
  98. package/dist/drizzle/0091_drop_wiki_brain_compat_views.sql +118 -0
  99. package/dist/drizzle/0092_finish_oss_connector_retirement.sql +97 -0
  100. package/dist/drizzle/0093_eval_runs_scheduled_job_id.sql +23 -0
  101. package/dist/drizzle/0094_slack_workspace_app.sql +140 -0
  102. package/dist/drizzle/0095_eval_runs_computer_id.sql +22 -0
  103. package/dist/drizzle/0096_true_redteam_eval_seed_cleanup.sql +67 -0
  104. package/dist/drizzle/0097_shared_computers.sql +191 -0
  105. package/dist/drizzle/0098_business_ontology.sql +587 -0
  106. package/dist/drizzle/0099_thread_idle_learning.sql +145 -0
  107. package/dist/drizzle/0100_ontology_gated_brain_dynamic_subtypes.sql +7 -0
  108. package/dist/drizzle/0101_ontology_gated_unresolved_mentions_dynamic_subtypes.sql +7 -0
  109. package/dist/drizzle/0102_wiki_brain_owner_repair.sql +87 -0
  110. package/dist/drizzle/0103_brain_section_source_trigger_repair.sql +75 -0
  111. package/dist/drizzle/0104_expand_seed_ontology_for_user_memory.sql +166 -0
  112. package/dist/drizzle/0105_spaces_domain.sql +349 -0
  113. package/dist/drizzle/0106_expand_seed_ontology_for_triples.sql +173 -0
  114. package/dist/drizzle/0106_space_threads_participants.sql +197 -0
  115. package/dist/drizzle/0107_linked_task_mirror.sql +245 -0
  116. package/dist/drizzle/0108_message_mentions.sql +95 -0
  117. package/dist/drizzle/0109_space_owned_threads.sql +217 -0
  118. package/dist/drizzle/0110_thread_participant_read_state.sql +21 -0
  119. package/dist/drizzle/0111_agents_tenant_name_unique.sql +38 -0
  120. package/dist/drizzle/0112_recast_spaces_as_contextual_workrooms.sql +138 -0
  121. package/dist/drizzle/0113_agents_own_runtime_fields.sql +48 -0
  122. package/dist/drizzle/0114_migrate_templates_to_agents_and_spaces.sql +361 -0
  123. package/dist/drizzle/0115_remove_computer_eval_template_dependencies.sql +69 -0
  124. package/dist/drizzle/0116_backfill_thread_participants_access.sql +126 -0
  125. package/dist/drizzle/0117_space_access_mode.sql +40 -0
  126. package/dist/drizzle/0118_normalize_tenant_member_principal_type.sql +41 -0
  127. package/dist/drizzle/0119_space_knowledge_bases.sql +126 -0
  128. package/dist/drizzle/0120_space_automations.sql +58 -0
  129. package/dist/drizzle/0121_drop_computer_runbooks.sql +26 -0
  130. package/dist/drizzle/0122_space_email_triggers.sql +24 -0
  131. package/dist/drizzle/0123_single_platform_agent_and_overrides.sql +58 -0
  132. package/dist/drizzle/0124_thread_turns_finalized_at.sql +17 -0
  133. package/dist/drizzle/0125_drop_space_agent_assignments.sql +42 -0
  134. package/dist/drizzle/0126_migrate_flue_to_pi.sql +42 -0
  135. package/dist/drizzle/0127_runtime_type_observability.sql +28 -0
  136. package/dist/drizzle/0128_drop_eval_test_cases_agent_id.sql +37 -0
  137. package/dist/drizzle/0129_drop_code_factory_tables.sql +43 -0
  138. package/dist/drizzle/0129_eval_results_system_prompt.sql +30 -0
  139. package/dist/drizzle/0130_drop_teams_and_team_id_columns.sql +54 -0
  140. package/dist/drizzle/0131_drop_skill_catalog_and_tenant_skills.sql +33 -0
  141. package/dist/drizzle/0132_drop_computer_tables.sql +31 -0
  142. package/dist/drizzle/0133_drop_seed_view_tombstones.sql +79 -0
  143. package/dist/drizzle/0133_thread_turns_system_prompt.sql +22 -0
  144. package/dist/drizzle/0134_drop_dead_agent_runtime_tables.sql +53 -0
  145. package/dist/drizzle/0135_native_checklist_linked_tasks.sql +48 -0
  146. package/dist/drizzle/0136_goal_ledger.sql +55 -0
  147. package/dist/drizzle/0136_space_email_trigger_status.sql +66 -0
  148. package/dist/drizzle/0137_thread_participant_pins.sql +25 -0
  149. package/dist/drizzle/0138_users_cognito_sub.sql +30 -0
  150. package/dist/drizzle/0139_mobile_turn_client_id.sql +23 -0
  151. package/dist/drizzle/0140_workspace_folder_names.sql +36 -0
  152. package/dist/drizzle/0141_eval_runs_desktop_pi_provenance.sql +31 -0
  153. package/dist/drizzle/0142_pi_only_agent_runtime.sql +61 -0
  154. package/dist/drizzle/0143_add_web_extract_builtin_config.sql +28 -0
  155. package/dist/drizzle/0144_skill_catalog_index.sql +40 -0
  156. package/dist/drizzle/0145_knowledge_graph_thread_ingest.sql +512 -0
  157. package/dist/drizzle/0146_knowledge_graph_source_scope.sql +413 -0
  158. package/dist/drizzle/0147_knowledge_graph_scope_trigger_qualification.sql +211 -0
  159. package/dist/drizzle/0148_user_cost_attribution.sql +171 -0
  160. package/dist/drizzle/0149_managed_mcp_servers.sql +64 -0
  161. package/dist/drizzle/0149_user_model_approvals.sql +89 -0
  162. package/dist/drizzle/0150_bootstrap_first_admin_claim.sql +11 -0
  163. package/dist/drizzle/0151_managed_deployments.sql +91 -0
  164. package/dist/drizzle/0152_agent_profiles.sql +81 -0
  165. package/dist/drizzle/0153_message_mentions_agent_profile.sql +9 -0
  166. package/dist/drizzle/0154_customer_deployment_sessions.sql +61 -0
  167. package/dist/drizzle/0155_tenant_model_catalog.sql +152 -0
  168. package/dist/drizzle/0156_bootstrap_credential_leases.sql +52 -0
  169. package/dist/drizzle/0157_knowledge_graph_observations_source.sql +79 -0
  170. package/dist/drizzle/0158_pending_user_questions.sql +80 -0
  171. package/dist/drizzle/0158_wiki_tenant_scope.sql +38 -0
  172. package/dist/drizzle/0159_agent_profiles_space_local.sql +49 -0
  173. package/dist/drizzle/0159_application_plugins.sql +193 -0
  174. package/dist/drizzle/0159_eval_scoring_version.sql +46 -0
  175. package/dist/drizzle/0160_compliance_event_types_plugins.sql +37 -0
  176. package/dist/drizzle/0160_eval_datasets.sql +75 -0
  177. package/dist/drizzle/0160_eval_results_thread_turn.sql +35 -0
  178. package/dist/drizzle/0161_eval_run_pinning.sql +54 -0
  179. package/dist/drizzle/0161_tenant_mcp_servers_plugin_source.sql +62 -0
  180. package/dist/drizzle/0162_eval_result_override.sql +49 -0
  181. package/dist/drizzle/0163_eval_replay_tool_allowlist.sql +50 -0
  182. package/dist/drizzle/0164_eval_replay_tool_override_mode.sql +52 -0
  183. package/dist/drizzle/0165_plugin_premium_entitlements.sql +153 -0
  184. package/dist/drizzle/0166_company_brain_substrate_contract.sql +386 -0
  185. package/dist/drizzle/0167_company_brain_artifact_manifest_runtime.sql +85 -0
  186. package/dist/drizzle/0168_eval_skill_gate.sql +44 -0
  187. package/dist/drizzle/0169_release_update_jobs.sql +67 -0
  188. package/dist/drizzle/0170_email_channel_plugin.sql +291 -0
  189. package/dist/drizzle/0171_linked_task_external_providers.sql +30 -0
  190. package/dist/drizzle/0172_email_channel_sendgrid_provider.sql +8 -0
  191. package/dist/drizzle/0173_auth_provider_resources.sql +83 -0
  192. package/dist/drizzle/0174_workos_auth_bridges.sql +37 -0
  193. package/dist/drizzle/0175_workos_auth_sessions.sql +38 -0
  194. package/dist/drizzle/0176_n8n_agent_step_runs.sql +107 -0
  195. package/dist/drizzle/0177_workflow_control_plane.sql +281 -0
  196. package/dist/drizzle/0178_workflow_backfill_existing_routines.sql +525 -0
  197. package/dist/drizzle/0179_tenant_goal_budget_settings.sql +21 -0
  198. package/dist/drizzle/0180_skill_drafts.sql +89 -0
  199. package/dist/drizzle/0181_skill_draft_publish_status.sql +21 -0
  200. package/dist/drizzle/0182_agent_loops.sql +260 -0
  201. package/dist/drizzle/0183_okf_artifact_manifests.sql +52 -0
  202. package/dist/drizzle/0184_skill_catalog_trust_cache.sql +35 -0
  203. package/dist/drizzle/0185_agent_loop_space.sql +16 -0
  204. package/dist/drizzle/0186_tenant_mcp_runtime_metadata.sql +10 -0
  205. package/dist/drizzle/0187_native_work_items.sql +220 -0
  206. package/dist/drizzle/0188_company_etl_plugin_rename.sql +99 -0
  207. package/dist/drizzle/0189_trace_cost_substrate.sql +247 -0
  208. package/dist/drizzle/0190_billing_export_reconciliation.sql +101 -0
  209. package/dist/drizzle/0191_open_engine_work_item_queue.sql +66 -0
  210. package/dist/drizzle/0192_work_item_labels.sql +44 -0
  211. package/dist/drizzle/0193_work_item_documents.sql +31 -0
  212. package/dist/drizzle/0194_memory_retain_attempts.sql +103 -0
  213. package/dist/drizzle/0194_work_item_comments.sql +35 -0
  214. package/dist/drizzle/0195_plugin_app_overlays.sql +45 -0
  215. package/dist/drizzle/0196_pi_extensions.sql +118 -0
  216. package/dist/drizzle/0197_eval_profiles.sql +150 -0
  217. package/dist/drizzle/0198_eval_runs_unstable.sql +27 -0
  218. package/dist/drizzle/0199_eval_runs_cost_partial.sql +27 -0
  219. package/dist/drizzle/meta/_journal.json +160 -0
  220. package/dist/plugins/README.md +162 -0
  221. package/dist/plugins/catalog/package.json +40 -0
  222. package/dist/plugins/catalog/scripts/build-catalog.ts +120 -0
  223. package/dist/plugins/catalog/scripts/generate-plugin-registry.ts +144 -0
  224. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +86 -0
  225. package/dist/plugins/catalog/src/__tests__/catalog.test.ts +308 -0
  226. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +861 -0
  227. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +124 -0
  228. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +120 -0
  229. package/dist/plugins/catalog/src/catalog.ts +434 -0
  230. package/dist/plugins/catalog/src/contracts.ts +1498 -0
  231. package/dist/plugins/catalog/src/index.ts +4 -0
  232. package/dist/plugins/catalog/src/plugin-package.ts +171 -0
  233. package/dist/plugins/catalog/src/registry/generated-first-party.ts +76 -0
  234. package/dist/plugins/catalog/src/registry/index.ts +1 -0
  235. package/dist/plugins/catalog/tsconfig.json +8 -0
  236. package/dist/plugins/company-brain/README.md +37 -0
  237. package/dist/plugins/company-brain/package.json +33 -0
  238. package/dist/plugins/company-brain/runtime/cognee/Dockerfile +11 -0
  239. package/dist/plugins/company-brain/smoke/cognee-managed-app-smoke.mjs +458 -0
  240. package/dist/plugins/company-brain/smoke/cognee-memory-cutover-smoke.mjs +539 -0
  241. package/dist/plugins/company-brain/smoke/company-brain-context-engine-smoke.mjs +312 -0
  242. package/dist/plugins/company-brain/smoke/company-brain-operations-smoke.mjs +449 -0
  243. package/dist/plugins/company-brain/smoke/company-brain-plugin-smoke.mjs +655 -0
  244. package/dist/plugins/company-brain/smoke/hindsight-memory-isolation-smoke.mjs +474 -0
  245. package/dist/plugins/company-brain/src/api/cognee-client.ts +896 -0
  246. package/dist/plugins/company-brain/src/api/cognee-cluster-identity.ts +49 -0
  247. package/dist/plugins/company-brain/src/api/cognee-memory-scope.ts +84 -0
  248. package/dist/plugins/company-brain/src/api/context-engine-provider.ts +888 -0
  249. package/dist/plugins/company-brain/src/api/migration.ts +665 -0
  250. package/dist/plugins/company-brain/src/deployment/cognee-managed-app.ts +396 -0
  251. package/dist/plugins/company-brain/src/index.ts +62 -0
  252. package/dist/plugins/company-brain/src/manifest.ts +112 -0
  253. package/dist/plugins/company-brain/terraform/cognee/README.md +263 -0
  254. package/dist/plugins/company-brain/terraform/cognee/main.tf +766 -0
  255. package/dist/plugins/company-brain/terraform/cognee/outputs.tf +144 -0
  256. package/dist/plugins/company-brain/terraform/cognee/variables.tf +402 -0
  257. package/dist/plugins/company-brain/test/api/cognee-client.test.ts +562 -0
  258. package/dist/plugins/company-brain/test/api/cognee-memory-scope.test.ts +74 -0
  259. package/dist/plugins/company-brain/test/api/context-engine-provider.test.ts +447 -0
  260. package/dist/plugins/company-brain/test/api/migration.test.ts +465 -0
  261. package/dist/plugins/company-brain/test/manifest.test.ts +95 -0
  262. package/dist/plugins/company-brain/tsconfig.json +8 -0
  263. package/dist/plugins/company-data/README.md +49 -0
  264. package/dist/plugins/company-data/package.json +21 -0
  265. package/dist/plugins/company-data/src/index.ts +30 -0
  266. package/dist/plugins/company-data/src/manifest.ts +26 -0
  267. package/dist/plugins/company-data/test/manifest.test.ts +116 -0
  268. package/dist/plugins/company-data/tsconfig.json +8 -0
  269. package/dist/plugins/company-etl/README.md +46 -0
  270. package/dist/plugins/company-etl/package.json +21 -0
  271. package/dist/plugins/company-etl/src/index.ts +29 -0
  272. package/dist/plugins/company-etl/src/manifest.ts +26 -0
  273. package/dist/plugins/company-etl/test/manifest.test.ts +108 -0
  274. package/dist/plugins/company-etl/tsconfig.json +8 -0
  275. package/dist/plugins/email-channel/README.md +41 -0
  276. package/dist/plugins/email-channel/package.json +22 -0
  277. package/dist/plugins/email-channel/src/index.ts +36 -0
  278. package/dist/plugins/email-channel/src/manifest.ts +44 -0
  279. package/dist/plugins/email-channel/src/provider-contract.ts +36 -0
  280. package/dist/plugins/email-channel/test/manifest.test.ts +119 -0
  281. package/dist/plugins/email-channel/tsconfig.json +8 -0
  282. package/dist/plugins/lastmile/README.md +50 -0
  283. package/dist/plugins/lastmile/package.json +23 -0
  284. package/dist/plugins/lastmile/smoke/lastmile-plugin-smoke.mjs +661 -0
  285. package/dist/plugins/lastmile/src/api/tasks-adapter.ts +572 -0
  286. package/dist/plugins/lastmile/src/discovery.fixture.ts +64 -0
  287. package/dist/plugins/lastmile/src/index.ts +46 -0
  288. package/dist/plugins/lastmile/src/manifest.ts +139 -0
  289. package/dist/plugins/lastmile/test/api/tasks-adapter.test.ts +266 -0
  290. package/dist/plugins/lastmile/test/discovery.test.ts +88 -0
  291. package/dist/plugins/lastmile/tsconfig.json +8 -0
  292. package/dist/plugins/n8n/README.md +201 -0
  293. package/dist/plugins/n8n/n8n-app/README.md +33 -0
  294. package/dist/plugins/n8n/n8n-app/package.json +23 -0
  295. package/dist/plugins/n8n/n8n-app/src/application-config.ts +45 -0
  296. package/dist/plugins/n8n/n8n-app/src/front-components/thinkwork-workflows.front-component.tsx +970 -0
  297. package/dist/plugins/n8n/n8n-app/src/lib/n8n-app-data.ts +190 -0
  298. package/dist/plugins/n8n/n8n-app/src/vite-env.d.ts +7 -0
  299. package/dist/plugins/n8n/n8n-app/tsconfig.json +15 -0
  300. package/dist/plugins/n8n/package.json +35 -0
  301. package/dist/plugins/n8n/runtime/Dockerfile +18 -0
  302. package/dist/plugins/n8n/runtime/n8n-task-runners.json +14 -0
  303. package/dist/plugins/n8n/runtime/n8n-task-runners.json.template +14 -0
  304. package/dist/plugins/n8n/runtime/package-lock.json +13 -0
  305. package/dist/plugins/n8n/runtime/package.json +7 -0
  306. package/dist/plugins/n8n/scripts/sync-thinkwork-app.mjs +268 -0
  307. package/dist/plugins/n8n/smoke/README.md +95 -0
  308. package/dist/plugins/n8n/smoke/n8n-agent-step-bridge-smoke.mjs +866 -0
  309. package/dist/plugins/n8n/smoke/n8n-integrated-app-smoke.mjs +262 -0
  310. package/dist/plugins/n8n/smoke/n8n-managed-app-smoke.mjs +409 -0
  311. package/dist/plugins/n8n/smoke/n8n-mcp-smoke.mjs +624 -0
  312. package/dist/plugins/n8n/src/deployment/image-build.ts +172 -0
  313. package/dist/plugins/n8n/src/deployment/managed-app.ts +429 -0
  314. package/dist/plugins/n8n/src/index.ts +79 -0
  315. package/dist/plugins/n8n/src/manifest.ts +403 -0
  316. package/dist/plugins/n8n/src/package-config.ts +186 -0
  317. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/SKILL.md +76 -0
  318. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/mcp-tooling.md +40 -0
  319. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/validation-and-handoff.md +40 -0
  320. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/workflow-authoring.md +45 -0
  321. package/dist/plugins/n8n/terraform/n8n/README.md +113 -0
  322. package/dist/plugins/n8n/terraform/n8n/main.tf +918 -0
  323. package/dist/plugins/n8n/terraform/n8n/outputs.tf +124 -0
  324. package/dist/plugins/n8n/terraform/n8n/scripts/sync-database.py +250 -0
  325. package/dist/plugins/n8n/terraform/n8n/scripts/test_sync_database.py +55 -0
  326. package/dist/plugins/n8n/terraform/n8n/variables.tf +354 -0
  327. package/dist/plugins/n8n/test/image-build.test.ts +118 -0
  328. package/dist/plugins/n8n/test/integrated-app-contract.test.ts +353 -0
  329. package/dist/plugins/n8n/test/manifest.test.ts +278 -0
  330. package/dist/plugins/n8n/test/package-config.test.ts +57 -0
  331. package/dist/plugins/n8n/tsconfig.json +8 -0
  332. package/dist/plugins/sendgrid/README.md +30 -0
  333. package/dist/plugins/sendgrid/package.json +22 -0
  334. package/dist/plugins/sendgrid/src/index.ts +36 -0
  335. package/dist/plugins/sendgrid/src/manifest.ts +37 -0
  336. package/dist/plugins/sendgrid/src/provider-contract.ts +14 -0
  337. package/dist/plugins/sendgrid/test/manifest.test.ts +80 -0
  338. package/dist/plugins/sendgrid/tsconfig.json +8 -0
  339. package/dist/plugins/twenty/README.md +78 -0
  340. package/dist/plugins/twenty/package.json +27 -0
  341. package/dist/plugins/twenty/scripts/__tests__/sync-thinkwork-app.test.mjs +67 -0
  342. package/dist/plugins/twenty/scripts/sync-thinkwork-app.mjs +185 -0
  343. package/dist/plugins/twenty/scripts/wire-thinkwork-workflow.mjs +658 -0
  344. package/dist/plugins/twenty/smoke/twenty-managed-app-smoke.mjs +359 -0
  345. package/dist/plugins/twenty/smoke/twenty-mcp-oauth-smoke.mjs +574 -0
  346. package/dist/plugins/twenty/src/api/cutover.ts +209 -0
  347. package/dist/plugins/twenty/src/deployment/managed-app.ts +253 -0
  348. package/dist/plugins/twenty/src/index.ts +55 -0
  349. package/dist/plugins/twenty/src/manifest.ts +259 -0
  350. package/dist/plugins/twenty/terraform/twenty/README.md +97 -0
  351. package/dist/plugins/twenty/terraform/twenty/main.tf +829 -0
  352. package/dist/plugins/twenty/terraform/twenty/outputs.tf +79 -0
  353. package/dist/plugins/twenty/terraform/twenty/variables.tf +268 -0
  354. package/dist/plugins/twenty/test/api/cutover.test.ts +183 -0
  355. package/dist/plugins/twenty/test/manifest.test.ts +463 -0
  356. package/dist/plugins/twenty/tsconfig.json +9 -0
  357. package/dist/plugins/twenty/twenty-app/.nvmrc +1 -0
  358. package/dist/plugins/twenty/twenty-app/README.md +148 -0
  359. package/dist/plugins/twenty/twenty-app/package.json +30 -0
  360. package/dist/plugins/twenty/twenty-app/src/application-config.ts +44 -0
  361. package/dist/plugins/twenty/twenty-app/src/constants/universal-identifiers.ts +18 -0
  362. package/dist/plugins/twenty/twenty-app/src/default-role.ts +24 -0
  363. package/dist/plugins/twenty/twenty-app/src/front-components/thinkwork-settings.front-component.tsx +299 -0
  364. package/dist/plugins/twenty/twenty-app/src/logic-functions/thinkwork-webhook.logic-function.ts +354 -0
  365. package/dist/plugins/twenty/twenty-app/tsconfig.json +14 -0
  366. package/dist/plugins/twenty/twenty-app/yarn.lock +4144 -0
  367. package/dist/plugins/workos-auth/package.json +22 -0
  368. package/dist/plugins/workos-auth/src/index.ts +30 -0
  369. package/dist/plugins/workos-auth/src/manifest.ts +40 -0
  370. package/dist/plugins/workos-auth/src/provider-contract.ts +39 -0
  371. package/dist/plugins/workos-auth/test/manifest.test.ts +94 -0
  372. package/dist/plugins/workos-auth/tsconfig.json +8 -0
  373. package/dist/scripts/bootstrap-workspace.sh +162 -0
  374. package/dist/scripts/post-deploy.sh +290 -0
  375. package/dist/terraform/examples/greenfield/main.tf +903 -75
  376. package/dist/terraform/examples/greenfield/terraform.tfvars.example +67 -8
  377. package/dist/terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base +2 -2
  378. package/dist/terraform/modules/app/agentcore-code-interpreter/README.md +8 -9
  379. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/sitecustomize.py +227 -0
  380. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/test_sitecustomize.py +277 -0
  381. package/dist/terraform/modules/app/agentcore-memory/README.md +6 -6
  382. package/dist/terraform/modules/app/agentcore-memory/main.tf +1 -1
  383. package/dist/terraform/modules/app/agentcore-memory/scripts/create_or_find_memory.sh +40 -9
  384. package/dist/terraform/modules/app/agentcore-pi/README.md +61 -0
  385. package/dist/terraform/modules/app/agentcore-pi/main.tf +453 -0
  386. package/dist/terraform/modules/app/agentcore-pi/outputs.tf +38 -0
  387. package/dist/terraform/modules/app/agentcore-pi/variables.tf +145 -0
  388. package/dist/terraform/modules/app/agentcore-platform/main.tf +83 -0
  389. package/dist/terraform/modules/app/agentcore-runtime/main.tf +9 -11
  390. package/dist/terraform/modules/app/appsync-subscriptions/main.tf +5 -1
  391. package/dist/terraform/modules/app/customer-domain/main.tf +483 -0
  392. package/dist/terraform/modules/app/deployment-control-plane/README.md +47 -0
  393. package/dist/terraform/modules/app/deployment-control-plane/buildspec.yml +24 -0
  394. package/dist/terraform/modules/app/deployment-control-plane/main.tf +614 -0
  395. package/dist/terraform/modules/app/deployment-control-plane/outputs.tf +54 -0
  396. package/dist/terraform/modules/app/deployment-control-plane/runner.py +4720 -0
  397. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +3026 -0
  398. package/dist/terraform/modules/app/deployment-control-plane/variables.tf +96 -0
  399. package/dist/terraform/modules/app/hindsight-memory/README.md +25 -23
  400. package/dist/terraform/modules/app/hindsight-memory/main.tf +26 -2
  401. package/dist/terraform/modules/app/lambda-api/eval-fanout.tf +17 -50
  402. package/dist/terraform/modules/app/lambda-api/handlers.tf +1290 -679
  403. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +933 -0
  404. package/dist/terraform/modules/app/lambda-api/main.tf +14 -527
  405. package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +3 -19
  406. package/dist/terraform/modules/app/lambda-api/outputs.tf +50 -6
  407. package/dist/terraform/modules/app/lambda-api/runtime-config.tf +163 -0
  408. package/dist/terraform/modules/app/lambda-api/slack-app-secrets.tf +3 -1
  409. package/dist/terraform/modules/app/lambda-api/stripe-secrets.tf +3 -1
  410. package/dist/terraform/modules/app/lambda-api/variables.tf +240 -53
  411. package/dist/terraform/modules/app/lambda-api/workspace-events.tf +2 -25
  412. package/dist/terraform/modules/app/ses-email/main.tf +143 -30
  413. package/dist/terraform/modules/app/static-site/main.tf +4 -3
  414. package/dist/terraform/modules/app/www-dns/main.tf +45 -5
  415. package/dist/terraform/modules/app/www-dns/outputs.tf +10 -0
  416. package/dist/terraform/modules/app/www-dns/variables.tf +24 -0
  417. package/dist/terraform/modules/data/aurora-postgres/main.tf +15 -1
  418. package/dist/terraform/modules/data/compliance-exports-bucket/main.tf +1 -1
  419. package/dist/terraform/modules/data/compliance-exports-bucket/variables.tf +6 -0
  420. package/dist/terraform/modules/foundation/cognito/main.tf +167 -11
  421. package/dist/terraform/modules/foundation/cognito/outputs.tf +5 -0
  422. package/dist/terraform/modules/foundation/cognito/variables.tf +110 -0
  423. package/dist/terraform/modules/foundation/vpc/main.tf +45 -3
  424. package/dist/terraform/modules/foundation/vpc/outputs.tf +20 -0
  425. package/dist/terraform/modules/foundation/vpc/variables.tf +18 -0
  426. package/dist/terraform/modules/thinkwork/README.md +71 -0
  427. package/dist/terraform/modules/thinkwork/main.tf +1325 -174
  428. package/dist/terraform/modules/thinkwork/outputs.tf +457 -24
  429. package/dist/terraform/modules/thinkwork/variables.tf +1169 -93
  430. package/dist/terraform/schema.graphql +82 -9
  431. package/dist/workspace-defaults/files/AGENTS.md +344 -0
  432. package/dist/workspace-defaults/files/CONTEXT.md +8 -0
  433. package/dist/workspace-defaults/files/GUARDRAILS.md +51 -0
  434. package/dist/workspace-defaults/files/MEMORY_GUIDE.md +65 -0
  435. package/dist/workspace-defaults/files/ROUTER.md +24 -0
  436. package/dist/workspace-defaults/files/SPACE.md +62 -0
  437. package/dist/workspace-defaults/files/TOOLS.md +65 -0
  438. package/dist/workspace-defaults/files/USER.md +40 -0
  439. package/dist/workspace-defaults/files/mcp.json +3 -0
  440. package/dist/workspace-defaults/files/memory/contacts.md +13 -0
  441. package/dist/workspace-defaults/files/memory/lessons.md +13 -0
  442. package/dist/workspace-defaults/files/memory/preferences.md +12 -0
  443. package/dist/workspace-defaults/files/skills/.gitkeep +1 -0
  444. package/dist/workspace-defaults/files/skills/artifact-builder/SKILL.md +79 -0
  445. package/dist/workspace-defaults/files/skills/artifact-builder/references/crm-dashboard.md +166 -0
  446. package/dist/workspace-defaults/files/skills/automation-loop-designer/SKILL.md +120 -0
  447. package/dist/workspace-defaults/files/skills/skill-creator/LICENSE.txt +202 -0
  448. package/dist/workspace-defaults/files/skills/skill-creator/SKILL.md +485 -0
  449. package/dist/workspace-defaults/files/skills/skill-creator/UPSTREAM.json +124 -0
  450. package/dist/workspace-defaults/files/skills/skill-creator/agents/analyzer.md +274 -0
  451. package/dist/workspace-defaults/files/skills/skill-creator/agents/comparator.md +202 -0
  452. package/dist/workspace-defaults/files/skills/skill-creator/agents/grader.md +223 -0
  453. package/dist/workspace-defaults/files/skills/skill-creator/assets/eval_review.html +146 -0
  454. package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  455. package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  456. package/dist/workspace-defaults/files/skills/skill-creator/references/schemas.md +430 -0
  457. package/dist/workspace-defaults/files/skills/skill-creator/scripts/__init__.py +0 -0
  458. package/dist/workspace-defaults/files/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  459. package/dist/workspace-defaults/files/skills/skill-creator/scripts/generate_report.py +326 -0
  460. package/dist/workspace-defaults/files/skills/skill-creator/scripts/improve_description.py +247 -0
  461. package/dist/workspace-defaults/files/skills/skill-creator/scripts/package_skill.py +136 -0
  462. package/dist/workspace-defaults/files/skills/skill-creator/scripts/quick_validate.py +103 -0
  463. package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_eval.py +310 -0
  464. package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_loop.py +328 -0
  465. package/dist/workspace-defaults/files/skills/skill-creator/scripts/utils.py +47 -0
  466. package/package.json +1 -1
  467. package/dist/terraform/modules/app/agentcore-flue/README.md +0 -58
  468. package/dist/terraform/modules/app/agentcore-flue/main.tf +0 -323
  469. package/dist/terraform/modules/app/agentcore-flue/outputs.tf +0 -23
  470. package/dist/terraform/modules/app/agentcore-flue/variables.tf +0 -97
  471. package/dist/terraform/modules/app/computer-runtime/README.md +0 -15
  472. package/dist/terraform/modules/app/computer-runtime/main.tf +0 -406
  473. package/dist/terraform/modules/app/computer-runtime/outputs.tf +0 -75
  474. package/dist/terraform/modules/app/computer-runtime/variables.tf +0 -66
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * n8n integrated app smoke.
4
+ *
5
+ * Dry-run is the default. Set SMOKE_ENABLE_N8N_INTEGRATED_APP=1 after the n8n
6
+ * plugin is installed and deployed through ThinkWork to verify the user-facing
7
+ * app path, workflow rows, execution rows, and optional bridge-linked evidence.
8
+ */
9
+
10
+ import fs from "node:fs";
11
+ import path from "node:path";
12
+ import process from "node:process";
13
+ import { attachSmokeEvidence } from "../../../scripts/smoke/deployment-evidence.mjs";
14
+
15
+ const LIVE_ENABLED = process.env.SMOKE_ENABLE_N8N_INTEGRATED_APP === "1";
16
+
17
+ const env = {
18
+ ...loadEnvFile(),
19
+ ...process.env,
20
+ };
21
+
22
+ const thinkworkUrl = first(
23
+ env.SMOKE_THINKWORK_URL,
24
+ env.THINKWORK_PUBLIC_URL,
25
+ env.THINKWORK_WEB_URL,
26
+ );
27
+ const graphqlUrl = first(
28
+ env.SMOKE_GRAPHQL_HTTP_URL,
29
+ env.GRAPHQL_HTTP_URL,
30
+ env.API_GRAPHQL_URL,
31
+ thinkworkUrl ? new URL("/graphql", thinkworkUrl).toString() : null,
32
+ );
33
+ const installId = first(env.SMOKE_N8N_INSTALL_ID, env.N8N_PLUGIN_INSTALL_ID);
34
+ const requiredBridgeThreadId = first(env.SMOKE_N8N_BRIDGE_THREAD_ID);
35
+
36
+ if (!LIVE_ENABLED) {
37
+ console.log(
38
+ JSON.stringify(
39
+ await attachSmokeEvidence(
40
+ "n8n-integrated-app",
41
+ {
42
+ ok: true,
43
+ skippedLive: true,
44
+ reason:
45
+ "set SMOKE_ENABLE_N8N_INTEGRATED_APP=1 to run the deployed n8n integrated app smoke",
46
+ dryRun: {
47
+ route: "/apps/n8n/workflows",
48
+ requiredWhenRunning: [
49
+ "n8n plugin installed through Settings -> Plugins",
50
+ "managed n8n app deployed and ready",
51
+ "tenant n8n-api credential configured server-side",
52
+ "operator GraphQL auth for installedPluginApps and n8nAppData",
53
+ ],
54
+ optionalInputs: [
55
+ "SMOKE_N8N_INSTALL_ID to pin the app data query",
56
+ "SMOKE_N8N_BRIDGE_THREAD_ID to require bridge-linked execution evidence",
57
+ ],
58
+ verifies: [
59
+ "installedPluginApps returns n8n-workflow-operations at /apps/n8n/workflows",
60
+ "n8nAppData returns workflow table readiness and rows",
61
+ "n8nAppData returns bounded execution table readiness and rows",
62
+ "bridge-linked execution evidence is present when requested",
63
+ "smoke output contains counts and readiness only, not raw execution payloads or credentials",
64
+ ],
65
+ },
66
+ },
67
+ env,
68
+ ),
69
+ null,
70
+ 2,
71
+ ),
72
+ );
73
+ process.exit(0);
74
+ }
75
+
76
+ try {
77
+ const result = await runLiveSmoke();
78
+ console.log(
79
+ JSON.stringify(
80
+ await attachSmokeEvidence(
81
+ "n8n-integrated-app",
82
+ { ok: true, ...result },
83
+ env,
84
+ ),
85
+ null,
86
+ 2,
87
+ ),
88
+ );
89
+ } catch (error) {
90
+ fail(error instanceof Error ? error.message : String(error));
91
+ }
92
+
93
+ async function runLiveSmoke() {
94
+ if (!graphqlUrl) {
95
+ throw new Error(
96
+ "Set SMOKE_GRAPHQL_HTTP_URL, GRAPHQL_HTTP_URL, API_GRAPHQL_URL, or SMOKE_THINKWORK_URL.",
97
+ );
98
+ }
99
+ const headers = authHeaders();
100
+ if (Object.keys(headers).length === 0) {
101
+ throw new Error(
102
+ "Set SMOKE_COGNITO_ID_TOKEN, COGNITO_ID_TOKEN, API_AUTH_SECRET, THINKWORK_API_SECRET, GRAPHQL_API_KEY, or VITE_GRAPHQL_API_KEY.",
103
+ );
104
+ }
105
+
106
+ const apps = await gql(
107
+ `query N8nIntegratedAppInstalledApps {
108
+ installedPluginApps {
109
+ pluginInstallId
110
+ pluginKey
111
+ appKey
112
+ routeSegment
113
+ readiness { state message nextAction }
114
+ }
115
+ }`,
116
+ {},
117
+ headers,
118
+ );
119
+ const app = apps.installedPluginApps.find(
120
+ (candidate) =>
121
+ candidate.pluginKey === "n8n" &&
122
+ candidate.appKey === "n8n-workflow-operations" &&
123
+ candidate.routeSegment === "workflows",
124
+ );
125
+ if (!app) {
126
+ throw new Error("n8n Workflows app is not available to this account.");
127
+ }
128
+
129
+ const targetInstallId = installId || app.pluginInstallId;
130
+ if (!targetInstallId) {
131
+ throw new Error("n8n app did not include a pluginInstallId.");
132
+ }
133
+
134
+ const data = await gql(
135
+ `query N8nIntegratedAppData($installId: ID!, $executionLimit: Int) {
136
+ n8nAppData(installId: $installId, executionLimit: $executionLimit) {
137
+ workflowReadinessState
138
+ executionReadinessState
139
+ nativeBaseUrl
140
+ workflows {
141
+ externalWorkflowId
142
+ name
143
+ readinessState
144
+ nativeWorkflowUrl
145
+ warnings
146
+ }
147
+ executions {
148
+ externalExecutionId
149
+ externalWorkflowId
150
+ status
151
+ nativeExecutionUrl
152
+ warnings
153
+ bridgeRuns { id threadId status resumeStatus }
154
+ }
155
+ }
156
+ }`,
157
+ { installId: targetInstallId, executionLimit: 25 },
158
+ headers,
159
+ );
160
+ const appData = data.n8nAppData;
161
+ const bridgeLinkedExecutions = appData.executions.filter(
162
+ (execution) => execution.bridgeRuns.length > 0,
163
+ );
164
+
165
+ if (requiredBridgeThreadId) {
166
+ const matched = bridgeLinkedExecutions.some((execution) =>
167
+ execution.bridgeRuns.some(
168
+ (run) => run.threadId === requiredBridgeThreadId,
169
+ ),
170
+ );
171
+ if (!matched) {
172
+ throw new Error(
173
+ "No bridge-linked execution matched SMOKE_N8N_BRIDGE_THREAD_ID.",
174
+ );
175
+ }
176
+ }
177
+
178
+ return {
179
+ route: "/apps/n8n/workflows",
180
+ installedApp: {
181
+ pluginInstallId: app.pluginInstallId,
182
+ readiness: app.readiness,
183
+ },
184
+ appData: {
185
+ nativeBaseUrl: appData.nativeBaseUrl,
186
+ workflowReadinessState: appData.workflowReadinessState,
187
+ executionReadinessState: appData.executionReadinessState,
188
+ workflowCount: appData.workflows.length,
189
+ executionCount: appData.executions.length,
190
+ bridgeLinkedExecutionCount: bridgeLinkedExecutions.length,
191
+ sampleWorkflowIds: appData.workflows
192
+ .slice(0, 3)
193
+ .map((workflow) => workflow.externalWorkflowId),
194
+ sampleExecutionIds: appData.executions
195
+ .slice(0, 3)
196
+ .map((execution) => execution.externalExecutionId),
197
+ },
198
+ };
199
+ }
200
+
201
+ async function gql(query, variables, headers) {
202
+ const response = await fetch(graphqlUrl, {
203
+ method: "POST",
204
+ headers: {
205
+ accept: "application/json",
206
+ "content-type": "application/json",
207
+ ...headers,
208
+ },
209
+ body: JSON.stringify({ query, variables }),
210
+ });
211
+ const payload = await response.json().catch(() => ({}));
212
+ if (!response.ok || payload.errors?.length) {
213
+ throw new Error(
214
+ `GraphQL request failed: HTTP ${response.status} ${redact(
215
+ JSON.stringify(payload.errors ?? payload).slice(0, 500),
216
+ )}`,
217
+ );
218
+ }
219
+ return payload.data;
220
+ }
221
+
222
+ function authHeaders() {
223
+ const idToken = first(env.SMOKE_COGNITO_ID_TOKEN, env.COGNITO_ID_TOKEN);
224
+ if (idToken) return { authorization: `Bearer ${idToken}` };
225
+ const authSecret = first(env.API_AUTH_SECRET, env.THINKWORK_API_SECRET);
226
+ if (authSecret) return { "x-api-secret": authSecret };
227
+ const apiKey = first(env.VITE_GRAPHQL_API_KEY, env.GRAPHQL_API_KEY);
228
+ if (apiKey) return { "x-api-key": apiKey };
229
+ return {};
230
+ }
231
+
232
+ function loadEnvFile() {
233
+ const envPath = process.env.SMOKE_ENV_FILE || ".env";
234
+ const resolved = path.resolve(envPath);
235
+ if (!fs.existsSync(resolved)) return {};
236
+ const values = {};
237
+ for (const line of fs.readFileSync(resolved, "utf8").split(/\r?\n/)) {
238
+ const trimmed = line.trim();
239
+ if (!trimmed || trimmed.startsWith("#") || !trimmed.includes("=")) {
240
+ continue;
241
+ }
242
+ const [key, ...rest] = trimmed.split("=");
243
+ values[key] = rest.join("=").replace(/^['"]|['"]$/g, "");
244
+ }
245
+ return values;
246
+ }
247
+
248
+ function first(...values) {
249
+ return values.find((value) => value !== undefined && value !== "") ?? null;
250
+ }
251
+
252
+ function fail(message) {
253
+ console.error(redact(message));
254
+ process.exit(1);
255
+ }
256
+
257
+ function redact(value) {
258
+ return value
259
+ .replace(/Bearer\s+[A-Za-z0-9._~+/=-]+/g, "Bearer [redacted]")
260
+ .replace(/(api[_-]?key|token|secret|credential)["=: ]+[^",\s]+/gi, "$1=[redacted]")
261
+ .replace(/https?:\/\/[^"\s]+\/webhook\/[^"\s]+/gi, "[redacted-webhook-url]");
262
+ }
@@ -0,0 +1,409 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Smoke test the n8n managed application deployment.
4
+ *
5
+ * Dry-run is the default. Set SMOKE_ENABLE_N8N_MANAGED_APP=1 after installing
6
+ * and deploying the n8n plugin through ThinkWork to read deployment status,
7
+ * inspect generated evidence, and probe the public n8n health path.
8
+ *
9
+ * Optional live env:
10
+ * SMOKE_TERRAFORM_DIR=terraform/examples/greenfield
11
+ * SMOKE_N8N_URL=https://n8n.example.com
12
+ * SMOKE_N8N_HEALTH_PATH=/healthz
13
+ * SMOKE_TENANT_ID=<tenant-id>
14
+ * VITE_GRAPHQL_HTTP_URL, GRAPHQL_HTTP_URL, or API_GRAPHQL_URL
15
+ * API_AUTH_SECRET, THINKWORK_API_SECRET, VITE_GRAPHQL_API_KEY, or GRAPHQL_API_KEY
16
+ */
17
+
18
+ import { execFileSync } from "node:child_process";
19
+ import fs from "node:fs";
20
+ import path from "node:path";
21
+ import process from "node:process";
22
+ import { attachSmokeEvidence } from "../../../scripts/smoke/deployment-evidence.mjs";
23
+
24
+ const LIVE_ENABLED = process.env.SMOKE_ENABLE_N8N_MANAGED_APP === "1";
25
+ const TIMEOUT_MS = Number(process.env.SMOKE_TIMEOUT_MS || 15_000);
26
+
27
+ const env = {
28
+ ...loadEnvFile(),
29
+ ...process.env,
30
+ };
31
+
32
+ const terraformDir = env.SMOKE_TERRAFORM_DIR || "terraform/examples/greenfield";
33
+ const healthPath = env.SMOKE_N8N_HEALTH_PATH || "/healthz";
34
+ const apiUrl = first(
35
+ env.VITE_GRAPHQL_HTTP_URL,
36
+ env.GRAPHQL_HTTP_URL,
37
+ env.API_GRAPHQL_URL,
38
+ );
39
+ const apiSecret = first(env.API_AUTH_SECRET, env.THINKWORK_API_SECRET);
40
+ const apiKey = first(
41
+ env.VITE_GRAPHQL_API_KEY,
42
+ env.APPSYNC_API_KEY,
43
+ env.GRAPHQL_API_KEY,
44
+ );
45
+ const tenantId = first(env.SMOKE_TENANT_ID, env.TENANT_ID);
46
+
47
+ if (!LIVE_ENABLED) {
48
+ console.log(
49
+ JSON.stringify(
50
+ await attachSmokeEvidence(
51
+ "n8n-managed-app",
52
+ {
53
+ ok: true,
54
+ skippedLive: true,
55
+ reason:
56
+ "set SMOKE_ENABLE_N8N_MANAGED_APP=1 to run the deployed n8n managed-app smoke",
57
+ dryRun: {
58
+ terraformDir,
59
+ healthPath,
60
+ requiredWhenRunning: [
61
+ "n8n plugin installed and deployed through ThinkWork Settings -> Plugins",
62
+ "Terraform outputs in SMOKE_TERRAFORM_DIR or SMOKE_N8N_URL",
63
+ "n8n provisioned/runtime deployment status",
64
+ ],
65
+ optionalGraphqlEnv: [
66
+ "SMOKE_TENANT_ID",
67
+ "VITE_GRAPHQL_HTTP_URL or GRAPHQL_HTTP_URL or API_GRAPHQL_URL",
68
+ "API_AUTH_SECRET or THINKWORK_API_SECRET or VITE_GRAPHQL_API_KEY or GRAPHQL_API_KEY",
69
+ ],
70
+ verifies: [
71
+ "n8n_provisioned false skips cleanly",
72
+ "n8n_runtime_enabled true requires HTTPS n8n_url",
73
+ "public n8n health path responds successfully",
74
+ "main and worker service evidence is present",
75
+ "database, queue, storage, image digest, and service credential evidence is present",
76
+ "package configuration digest is recorded when custom packages are configured",
77
+ ],
78
+ },
79
+ },
80
+ env,
81
+ ),
82
+ null,
83
+ 2,
84
+ ),
85
+ );
86
+ process.exit(0);
87
+ }
88
+
89
+ try {
90
+ const result = await runLiveSmoke();
91
+ console.log(
92
+ JSON.stringify(
93
+ await attachSmokeEvidence(
94
+ "n8n-managed-app",
95
+ { ok: true, ...result },
96
+ env,
97
+ ),
98
+ null,
99
+ 2,
100
+ ),
101
+ );
102
+ } catch (error) {
103
+ fail(error instanceof Error ? error.message : String(error));
104
+ }
105
+
106
+ async function runLiveSmoke() {
107
+ const terraform = readTerraformOutputs(terraformDir);
108
+ const graphql = await readGraphqlStatus().catch((error) => ({
109
+ error: error instanceof Error ? error.message : String(error),
110
+ }));
111
+ const status = resolveStatus({ terraform, graphql });
112
+
113
+ if (!status.provisioned) {
114
+ return {
115
+ skippedLive: true,
116
+ reason: "n8n is not provisioned for this stage.",
117
+ terraform,
118
+ graphql,
119
+ };
120
+ }
121
+
122
+ if (!status.runtimeEnabled) {
123
+ return {
124
+ skippedLive: true,
125
+ reason: "n8n is provisioned but runtime is parked.",
126
+ status,
127
+ terraform,
128
+ graphql,
129
+ };
130
+ }
131
+
132
+ if (!status.url) {
133
+ throw new Error("n8n runtime is enabled but no public URL was resolved.");
134
+ }
135
+ if (!status.url.startsWith("https://")) {
136
+ throw new Error(`n8n URL must be HTTPS, got ${status.url}.`);
137
+ }
138
+
139
+ validateRuntimeEvidence(status.evidence, status.source);
140
+ const publicHealth = await probeHealth(status.url);
141
+
142
+ if (!publicHealth.healthy) {
143
+ throw new Error(
144
+ `n8n health probe failed: HTTP ${publicHealth.statusCode ?? "none"} ${publicHealth.message}`,
145
+ );
146
+ }
147
+
148
+ return {
149
+ status,
150
+ publicHealth,
151
+ terraform,
152
+ graphql,
153
+ };
154
+ }
155
+
156
+ function resolveStatus({ terraform, graphql }) {
157
+ const app = graphql?.deploymentStatus?.managedApplications?.find(
158
+ (entry) => entry.key === "n8n",
159
+ );
160
+ const source = app ? "graphql" : terraform.available ? "terraform" : "env";
161
+ const evidence = {
162
+ mainServiceName: first(
163
+ terraform.n8n_main_service_name,
164
+ app?.serviceNames?.[0],
165
+ ),
166
+ workerServiceName: first(
167
+ terraform.n8n_worker_service_name,
168
+ app?.serviceNames?.[1],
169
+ ),
170
+ mainLogGroupName: terraform.n8n_main_log_group_name,
171
+ workerLogGroupName: terraform.n8n_worker_log_group_name,
172
+ databaseName: first(terraform.n8n_database_name, app?.databaseName),
173
+ databaseSecretArn: terraform.n8n_database_secret_arn,
174
+ valkeyEndpoint: terraform.n8n_valkey_endpoint,
175
+ storageBucketName: first(
176
+ terraform.n8n_storage_bucket_name,
177
+ app?.storageBucketName,
178
+ ),
179
+ storagePrefix: terraform.n8n_storage_prefix,
180
+ imageDigest: terraform.n8n_image_digest,
181
+ packageConfigDigest: terraform.n8n_package_config_digest,
182
+ serviceCredentialSecretArn: terraform.n8n_service_credential_secret_arn,
183
+ };
184
+
185
+ return {
186
+ provisioned: bool(
187
+ firstDefined(
188
+ app?.provisioned,
189
+ terraform.n8n_provisioned,
190
+ !!env.SMOKE_N8N_URL,
191
+ ),
192
+ ),
193
+ runtimeEnabled: bool(
194
+ firstDefined(
195
+ app?.runtimeEnabled,
196
+ terraform.n8n_runtime_enabled,
197
+ !!env.SMOKE_N8N_URL,
198
+ ),
199
+ ),
200
+ url: first(env.SMOKE_N8N_URL, app?.url, terraform.n8n_url),
201
+ source,
202
+ status: app?.status ?? null,
203
+ message: app?.message ?? null,
204
+ evidence,
205
+ };
206
+ }
207
+
208
+ function validateRuntimeEvidence(evidence, source) {
209
+ if (env.SMOKE_N8N_ALLOW_URL_ONLY === "1") {
210
+ return;
211
+ }
212
+ const required = [
213
+ "mainServiceName",
214
+ "workerServiceName",
215
+ "databaseName",
216
+ "valkeyEndpoint",
217
+ "storageBucketName",
218
+ "imageDigest",
219
+ "serviceCredentialSecretArn",
220
+ ];
221
+ const missing = required.filter((key) => !evidence[key]);
222
+ if (missing.length > 0) {
223
+ throw new Error(
224
+ `n8n live smoke requires managed-app evidence from Terraform or GraphQL; missing ${missing.join(", ")} from ${source}. Set SMOKE_N8N_ALLOW_URL_ONLY=1 only for endpoint-only diagnostics.`,
225
+ );
226
+ }
227
+ }
228
+
229
+ async function probeHealth(baseUrl) {
230
+ const endpoint = new URL(healthPath, baseUrl).toString();
231
+ const started = Date.now();
232
+ const response = await fetchWithTimeout(endpoint, {
233
+ headers: { accept: "text/html,application/json,*/*" },
234
+ });
235
+ const body = await response.text().catch(() => "");
236
+ return {
237
+ endpoint,
238
+ healthy: response.ok,
239
+ statusCode: response.status,
240
+ latencyMs: Date.now() - started,
241
+ message: body.slice(0, 300),
242
+ };
243
+ }
244
+
245
+ function readTerraformOutputs(dir) {
246
+ const resolved = path.resolve(dir);
247
+ if (!fs.existsSync(resolved)) {
248
+ return { available: false, reason: `Terraform dir not found: ${dir}` };
249
+ }
250
+
251
+ try {
252
+ const raw = execFileSync(
253
+ "terraform",
254
+ ["-chdir=" + resolved, "output", "-json"],
255
+ {
256
+ encoding: "utf8",
257
+ stdio: ["ignore", "pipe", "pipe"],
258
+ },
259
+ );
260
+ const parsed = JSON.parse(raw);
261
+ return {
262
+ available: true,
263
+ n8n_provisioned: outputValue(parsed.n8n_provisioned),
264
+ n8n_runtime_enabled: outputValue(parsed.n8n_runtime_enabled),
265
+ n8n_url: outputValue(parsed.n8n_url),
266
+ n8n_alb_arn: outputValue(parsed.n8n_alb_arn),
267
+ n8n_target_group_arn: outputValue(parsed.n8n_target_group_arn),
268
+ n8n_cluster_arn: outputValue(parsed.n8n_cluster_arn),
269
+ n8n_main_service_name: outputValue(parsed.n8n_main_service_name),
270
+ n8n_worker_service_name: outputValue(parsed.n8n_worker_service_name),
271
+ n8n_main_log_group_name: outputValue(parsed.n8n_main_log_group_name),
272
+ n8n_worker_log_group_name: outputValue(parsed.n8n_worker_log_group_name),
273
+ n8n_database_name: outputValue(parsed.n8n_database_name),
274
+ n8n_database_secret_arn: outputValue(parsed.n8n_database_secret_arn),
275
+ n8n_valkey_endpoint: outputValue(parsed.n8n_valkey_endpoint),
276
+ n8n_storage_bucket_name: outputValue(parsed.n8n_storage_bucket_name),
277
+ n8n_storage_prefix: outputValue(parsed.n8n_storage_prefix),
278
+ n8n_image_digest: outputValue(parsed.n8n_image_digest),
279
+ n8n_package_config_digest: outputValue(parsed.n8n_package_config_digest),
280
+ n8n_service_credential_secret_arn: outputValue(
281
+ parsed.n8n_service_credential_secret_arn,
282
+ ),
283
+ };
284
+ } catch (error) {
285
+ return {
286
+ available: false,
287
+ reason: error instanceof Error ? error.message : String(error),
288
+ };
289
+ }
290
+ }
291
+
292
+ async function readGraphqlStatus() {
293
+ if (!apiUrl || !tenantId || (!apiSecret && !apiKey)) {
294
+ return {
295
+ skipped: true,
296
+ reason:
297
+ "set API URL, tenant id, and API_AUTH_SECRET/THINKWORK_API_SECRET or GraphQL API key to compare GraphQL deployment status",
298
+ };
299
+ }
300
+ const data = await gql(
301
+ `query N8nManagedAppSmoke {
302
+ deploymentStatus {
303
+ managedApplications {
304
+ key
305
+ provisioned
306
+ runtimeEnabled
307
+ url
308
+ status
309
+ message
310
+ serviceNames
311
+ storageBucketName
312
+ databaseName
313
+ }
314
+ }
315
+ }`,
316
+ {},
317
+ );
318
+ return { deploymentStatus: data.deploymentStatus };
319
+ }
320
+
321
+ async function gql(query, variables) {
322
+ const headers = {
323
+ "content-type": "application/json",
324
+ "x-tenant-id": tenantId,
325
+ };
326
+ if (apiSecret) headers.authorization = `Bearer ${apiSecret}`;
327
+ if (apiKey) headers["x-api-key"] = apiKey;
328
+
329
+ const response = await fetchWithTimeout(apiUrl, {
330
+ method: "POST",
331
+ headers,
332
+ body: JSON.stringify({ query, variables }),
333
+ });
334
+ const text = await response.text();
335
+ if (!response.ok) {
336
+ throw new Error(`GraphQL HTTP ${response.status}: ${text.slice(0, 500)}`);
337
+ }
338
+ const body = JSON.parse(text);
339
+ if (body.errors?.length) {
340
+ throw new Error(`GraphQL errors: ${JSON.stringify(body.errors)}`);
341
+ }
342
+ return body.data;
343
+ }
344
+
345
+ async function fetchWithTimeout(url, options = {}) {
346
+ const controller = new AbortController();
347
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
348
+ try {
349
+ return await fetch(url, { ...options, signal: controller.signal });
350
+ } finally {
351
+ clearTimeout(timer);
352
+ }
353
+ }
354
+
355
+ function fail(message) {
356
+ console.error(JSON.stringify({ ok: false, error: message }, null, 2));
357
+ process.exit(1);
358
+ }
359
+
360
+ function outputValue(output) {
361
+ return output && typeof output === "object" && "value" in output
362
+ ? output.value
363
+ : undefined;
364
+ }
365
+
366
+ function bool(value) {
367
+ if (typeof value === "boolean") return value;
368
+ if (typeof value === "string") return value.toLowerCase() === "true";
369
+ return Boolean(value);
370
+ }
371
+
372
+ function firstDefined(...values) {
373
+ return values.find((value) => value !== undefined && value !== null);
374
+ }
375
+
376
+ function first(...values) {
377
+ return (
378
+ values.find((value) => typeof value === "string" && value.trim())?.trim() ??
379
+ null
380
+ );
381
+ }
382
+
383
+ function loadEnvFile() {
384
+ const explicit = process.env.COMPUTER_ENV_FILE;
385
+ if (explicit === "none") return {};
386
+ const candidates = [explicit, "apps/web/.env", ".env"].filter(Boolean);
387
+
388
+ for (const candidate of candidates) {
389
+ const resolved = path.resolve(candidate);
390
+ if (!fs.existsSync(resolved)) continue;
391
+ return Object.fromEntries(
392
+ fs
393
+ .readFileSync(resolved, "utf8")
394
+ .split(/\r?\n/)
395
+ .map((line) => line.trim())
396
+ .filter((line) => line && !line.startsWith("#") && line.includes("="))
397
+ .map((line) => {
398
+ const index = line.indexOf("=");
399
+ const key = line.slice(0, index).trim();
400
+ const value = line
401
+ .slice(index + 1)
402
+ .trim()
403
+ .replace(/^['"]|['"]$/g, "");
404
+ return [key, value];
405
+ }),
406
+ );
407
+ }
408
+ return {};
409
+ }