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,139 @@
1
+ /**
2
+ * LastMile plugin manifest — v0.1.0.
3
+ *
4
+ * Endpoint/auth values were captured from LastMile's live RFC 9728
5
+ * protected-resource metadata on 2026-06-12 (plan 2026-06-12-001 U9; the
6
+ * recorded capture lives in `discovery.fixture.ts` next to this file and
7
+ * is asserted against the manifest by `lastmile-discovery.test.ts`):
8
+ *
9
+ * - One authorization server (WorkOS AuthKit staging) covers all three
10
+ * MCP servers, so a single app-level activation mints tokens for the
11
+ * whole plugin.
12
+ * - Per-server RFC 8707 resource indicators are the server base URLs.
13
+ * - The Routing server publishes protected-resource metadata and
14
+ * therefore REQUIRES OAuth, despite a stale `auth_type: 'none'`
15
+ * direct-add row that existed on dev — the manifest declares oauth.
16
+ * - Endpoint URLs intentionally match the existing manually-added dev
17
+ * `tenant_mcp_servers` rows EXACTLY, so the URL-dedupe coexistence
18
+ * path (plugin row wins over a same-URL manual row at dispatch) is
19
+ * exercised for real.
20
+ *
21
+ * KNOWN v1 GAP — per-stage endpoints: these are LastMile's DEVELOP-stage
22
+ * endpoints (`dev-mcp.lastmile-tei.com`); production is
23
+ * `mcp.lastmile-tei.com`. The manifest format has no per-stage endpoint
24
+ * parameterization yet, so a prod rollout currently requires publishing a
25
+ * new manifest version with the prod URLs. Tracked as a follow-up to plan
26
+ * 2026-06-12-001.
27
+ */
28
+
29
+ const LASTMILE_AUTH_DOMAIN =
30
+ "https://straightforward-dragon-14-staging.authkit.app";
31
+
32
+ const LASTMILE_MCP_BASE = "https://dev-mcp.lastmile-tei.com";
33
+
34
+ const CRM_BASICS_SKILL_MD = `---
35
+ name: lastmile--crm-basics
36
+ description: Look up, summarize, and update LastMile CRM records through the LastMile CRM MCP tools. Use when a request involves LastMile customers, accounts, opportunities, or account history.
37
+ ---
38
+
39
+ # LastMile CRM basics
40
+
41
+ Work LastMile CRM requests through the \`lastmile--crm\` MCP server's
42
+ tools — never guess at record contents from memory. The server covers
43
+ opportunities and accounts; list its tools first if you are unsure what
44
+ is available, since the exact tool set can change between LastMile
45
+ releases.
46
+
47
+ ## Listing and filtering opportunities
48
+
49
+ 1. Use \`opportunities_list\` to enumerate opportunities. Apply the
50
+ narrowest filter the tool's input schema supports (owner, stage,
51
+ account) rather than listing everything and filtering in prose.
52
+ 2. If a request names a specific account or customer, resolve the account
53
+ first, then scope the opportunity listing to it.
54
+ 3. When more rows match than you can usefully summarize, say so and ask
55
+ how to narrow, instead of truncating silently.
56
+
57
+ ## Updating records
58
+
59
+ 1. Read the current record first and show the user the fields you are
60
+ about to change.
61
+ 2. Apply the smallest update that satisfies the request; never bulk-edit
62
+ fields the user did not mention.
63
+ 3. After writing, re-read the record and confirm the change took effect.
64
+
65
+ ## Summarizing
66
+
67
+ When asked for an account or pipeline summary, pull the relevant records
68
+ and lead with what changed most recently. State clearly when a field is
69
+ empty or a record was not found — do not fill gaps from memory.
70
+ `;
71
+
72
+ export const lastmileManifest = {
73
+ pluginKey: "lastmile",
74
+ displayName: "LastMile",
75
+ description:
76
+ "LastMile CRM, task, and routing tools for field-service teams, with bundled skills for working customer records.",
77
+ versions: [
78
+ {
79
+ version: "0.1.0",
80
+ // scopes_supported is identical across all three servers (captured
81
+ // 2026-06-12); offline_access keeps refresh tokens flowing so an
82
+ // activation outlives the first access token.
83
+ requiredOauthScopes: ["openid", "email", "profile", "offline_access"],
84
+ components: [
85
+ {
86
+ type: "mcp-server",
87
+ key: "crm",
88
+ displayName: "LastMile CRM",
89
+ description: "Customer accounts and sales opportunities.",
90
+ endpointUrl: `${LASTMILE_MCP_BASE}/crm`,
91
+ auth: {
92
+ mode: "oauth",
93
+ authDomain: LASTMILE_AUTH_DOMAIN,
94
+ resourceIndicator: `${LASTMILE_MCP_BASE}/crm`,
95
+ },
96
+ toolNotes: [
97
+ "Opportunity and account tools, including opportunities_list for listing/filtering opportunities.",
98
+ ],
99
+ },
100
+ {
101
+ type: "mcp-server",
102
+ key: "tasks",
103
+ displayName: "LastMile Tasks",
104
+ description: "Work orders and task assignments.",
105
+ endpointUrl: `${LASTMILE_MCP_BASE}/tasks`,
106
+ auth: {
107
+ mode: "oauth",
108
+ authDomain: LASTMILE_AUTH_DOMAIN,
109
+ resourceIndicator: `${LASTMILE_MCP_BASE}/tasks`,
110
+ },
111
+ toolNotes: ["Task management tools."],
112
+ },
113
+ {
114
+ type: "mcp-server",
115
+ key: "routing",
116
+ displayName: "LastMile Routing",
117
+ description: "Route planning and technician dispatch.",
118
+ endpointUrl: `${LASTMILE_MCP_BASE}/routing`,
119
+ auth: {
120
+ mode: "oauth",
121
+ authDomain: LASTMILE_AUTH_DOMAIN,
122
+ resourceIndicator: `${LASTMILE_MCP_BASE}/routing`,
123
+ },
124
+ toolNotes: ["Route optimization tools."],
125
+ },
126
+ {
127
+ type: "skills",
128
+ key: "skills",
129
+ skills: [
130
+ {
131
+ slug: "lastmile--crm-basics",
132
+ skillMd: CRM_BASICS_SKILL_MD,
133
+ },
134
+ ],
135
+ },
136
+ ],
137
+ },
138
+ ],
139
+ };
@@ -0,0 +1,266 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+
3
+ import {
4
+ createLastMileTasksAdapter,
5
+ type LastMileMcpClient,
6
+ } from "../../src/api/tasks-adapter.js";
7
+
8
+ const baseCreateInput = {
9
+ tenantId: "tenant-1",
10
+ spaceId: "space-1",
11
+ threadId: "thread-1",
12
+ checklistItemId: "checklist-1",
13
+ idempotencyKey: "tenant-1:thread-1:checklist-1",
14
+ title: "Collect sales tax exemption",
15
+ required: true,
16
+ assignee: {
17
+ roleKey: "accounting",
18
+ externalId: "user-100",
19
+ displayName: "Accounting Owner",
20
+ },
21
+ };
22
+
23
+ describe("LastMile Tasks adapter", () => {
24
+ let client: LastMileMcpClient & {
25
+ callTool: ReturnType<typeof vi.fn>;
26
+ };
27
+
28
+ beforeEach(() => {
29
+ client = {
30
+ callTool: vi.fn(),
31
+ };
32
+ });
33
+
34
+ it("creates a task through the configured MCP tool and normalizes the response", async () => {
35
+ client.callTool.mockResolvedValueOnce({
36
+ structuredContent: {
37
+ task: {
38
+ id: "LM-100",
39
+ url: "https://tasks.example/LM-100",
40
+ title: "Collect sales tax exemption",
41
+ status: "In Progress",
42
+ assignee: { id: "user-100", name: "Accounting Owner" },
43
+ dueDate: "2026-06-01",
44
+ },
45
+ },
46
+ });
47
+ const adapter = createLastMileTasksAdapter({ client });
48
+
49
+ await expect(adapter.createTask(baseCreateInput)).resolves.toEqual({
50
+ ok: true,
51
+ value: expect.objectContaining({
52
+ externalTaskId: "LM-100",
53
+ externalTaskUrl: "https://tasks.example/LM-100",
54
+ status: "in_progress",
55
+ blocked: false,
56
+ syncStatus: "synced",
57
+ assignee: {
58
+ externalId: "user-100",
59
+ displayName: "Accounting Owner",
60
+ },
61
+ dueAt: "2026-06-01",
62
+ idempotent: false,
63
+ needsTriage: false,
64
+ }),
65
+ });
66
+ expect(client.callTool).toHaveBeenCalledWith({
67
+ serverName: "lastmile-tasks",
68
+ toolName: "create_task",
69
+ arguments: expect.objectContaining({
70
+ idempotencyKey: "tenant-1:thread-1:checklist-1",
71
+ title: "Collect sales tax exemption",
72
+ assignee: expect.objectContaining({ externalId: "user-100" }),
73
+ }),
74
+ });
75
+ });
76
+
77
+ it("treats duplicate/idempotent creates as successful existing task snapshots", async () => {
78
+ client.callTool.mockResolvedValueOnce({
79
+ structuredContent: {
80
+ result: {
81
+ taskId: "LM-100",
82
+ externalTaskUrl: "https://tasks.example/LM-100",
83
+ status: "todo",
84
+ existing: true,
85
+ },
86
+ },
87
+ });
88
+ const adapter = createLastMileTasksAdapter({ client });
89
+
90
+ const result = await adapter.createTask(baseCreateInput);
91
+
92
+ expect(result).toMatchObject({
93
+ ok: true,
94
+ value: {
95
+ externalTaskId: "LM-100",
96
+ idempotent: true,
97
+ status: "todo",
98
+ },
99
+ });
100
+ });
101
+
102
+ it("creates an unassigned task and marks triage when a role has no external owner", async () => {
103
+ client.callTool.mockResolvedValueOnce({
104
+ structuredContent: {
105
+ task: {
106
+ id: "LM-101",
107
+ status: "not started",
108
+ },
109
+ },
110
+ });
111
+ const adapter = createLastMileTasksAdapter({ client });
112
+
113
+ const result = await adapter.createTask({
114
+ ...baseCreateInput,
115
+ assignee: { roleKey: "finance", displayName: "Finance" },
116
+ });
117
+
118
+ expect(result).toMatchObject({
119
+ ok: true,
120
+ value: {
121
+ externalTaskId: "LM-101",
122
+ assignee: null,
123
+ needsTriage: true,
124
+ syncStatus: "synced",
125
+ },
126
+ });
127
+ expect(client.callTool).toHaveBeenCalledWith(
128
+ expect.objectContaining({
129
+ arguments: expect.objectContaining({
130
+ assignee: {
131
+ roleKey: "finance",
132
+ externalId: null,
133
+ displayName: "Finance",
134
+ },
135
+ }),
136
+ }),
137
+ );
138
+ });
139
+
140
+ it("preserves sanitized provider error detail for outages", async () => {
141
+ client.callTool.mockRejectedValueOnce({
142
+ status: 503,
143
+ message: "LastMile unavailable",
144
+ apiKey: "super-secret",
145
+ });
146
+ const adapter = createLastMileTasksAdapter({ client });
147
+
148
+ const result = await adapter.readTask({ externalTaskId: "LM-100" });
149
+
150
+ expect(result).toMatchObject({
151
+ ok: false,
152
+ providerError: {
153
+ code: "MCP_CALL_FAILED",
154
+ message: "LastMile unavailable",
155
+ status: 503,
156
+ retryable: true,
157
+ detail: {
158
+ status: 503,
159
+ message: "LastMile unavailable",
160
+ apiKey: "[redacted]",
161
+ },
162
+ },
163
+ });
164
+ });
165
+
166
+ it("maps provider permission denial without throwing", async () => {
167
+ client.callTool.mockResolvedValueOnce({
168
+ isError: true,
169
+ structuredContent: {
170
+ code: "FORBIDDEN",
171
+ status: 403,
172
+ message: "not allowed",
173
+ },
174
+ });
175
+ const adapter = createLastMileTasksAdapter({ client });
176
+
177
+ await expect(adapter.createTask(baseCreateInput)).resolves.toMatchObject({
178
+ ok: false,
179
+ providerError: {
180
+ code: "FORBIDDEN",
181
+ status: 403,
182
+ retryable: false,
183
+ message: "not allowed",
184
+ },
185
+ });
186
+ });
187
+
188
+ it("treats a provider response without a task id as an unhealthy sync response", async () => {
189
+ client.callTool.mockResolvedValueOnce({
190
+ structuredContent: {
191
+ task: {
192
+ title: "Collect sales tax exemption",
193
+ status: "todo",
194
+ },
195
+ },
196
+ });
197
+ const adapter = createLastMileTasksAdapter({ client });
198
+
199
+ await expect(adapter.createTask(baseCreateInput)).resolves.toMatchObject({
200
+ ok: false,
201
+ providerError: {
202
+ code: "PROVIDER_RESPONSE_MISSING_TASK_ID",
203
+ retryable: false,
204
+ message: "LastMile task provider response did not include a task id",
205
+ },
206
+ });
207
+ });
208
+
209
+ it("gates external comments through Space writeback policy before calling MCP", async () => {
210
+ const adapter = createLastMileTasksAdapter({ client });
211
+
212
+ await expect(
213
+ adapter.postComment({
214
+ externalTaskId: "LM-100",
215
+ body: "Coordinator summary",
216
+ writeback: {
217
+ policy: "status_and_comments",
218
+ action: "agent_comment",
219
+ },
220
+ }),
221
+ ).resolves.toEqual({
222
+ ok: false,
223
+ blockedByPolicy: expect.objectContaining({
224
+ reason: "agent_comment_confirmation_required",
225
+ }),
226
+ });
227
+ expect(client.callTool).not.toHaveBeenCalled();
228
+ });
229
+
230
+ it("posts confirmed comments through MCP", async () => {
231
+ client.callTool.mockResolvedValueOnce({
232
+ structuredContent: {
233
+ commentId: "comment-1",
234
+ postedAt: "2026-05-19T00:00:00Z",
235
+ },
236
+ });
237
+ const adapter = createLastMileTasksAdapter({ client });
238
+
239
+ await expect(
240
+ adapter.postComment({
241
+ externalTaskId: "LM-100",
242
+ body: "Ready for accounting review",
243
+ writeback: {
244
+ policy: "status_and_comments",
245
+ action: "agent_comment",
246
+ humanConfirmed: true,
247
+ },
248
+ }),
249
+ ).resolves.toMatchObject({
250
+ ok: true,
251
+ value: {
252
+ externalTaskId: "LM-100",
253
+ commentId: "comment-1",
254
+ },
255
+ });
256
+ expect(client.callTool).toHaveBeenCalledWith({
257
+ serverName: "lastmile-tasks",
258
+ toolName: "post_comment",
259
+ arguments: {
260
+ externalTaskId: "LM-100",
261
+ body: "Ready for accounting review",
262
+ metadata: {},
263
+ },
264
+ });
265
+ });
266
+ });
@@ -0,0 +1,88 @@
1
+ /**
2
+ * LastMile manifest ↔ recorded discovery metadata drift guard
3
+ * (plan 2026-06-12-001 U9).
4
+ *
5
+ * Asserts the published manifest against the RFC 9728 protected-resource
6
+ * metadata captured from LastMile's live develop-stage servers. The live
7
+ * half of this guard lives in `plugins/lastmile/smoke/lastmile-plugin-smoke.mjs`,
8
+ * which re-fetches the same endpoints; this test pins the manifest to the
9
+ * recorded fixture so the two can only drift apart loudly.
10
+ */
11
+
12
+ import { describe, expect, it } from "vitest";
13
+
14
+ import {
15
+ validatePluginManifest,
16
+ type McpServerComponent,
17
+ } from "@thinkwork/plugin-catalog/contracts";
18
+
19
+ import { lastmileDiscoveryFixture } from "../src/discovery.fixture";
20
+ import { lastmileManifest } from "../src/manifest";
21
+
22
+ const SERVER_KEYS = ["crm", "tasks", "routing"] as const;
23
+ const validatedLastmileManifest = validatePluginManifest(lastmileManifest);
24
+
25
+ function mcpServer(key: string): McpServerComponent {
26
+ const component = validatedLastmileManifest.versions[0].components.find(
27
+ (candidate) => candidate.type === "mcp-server" && candidate.key === key,
28
+ );
29
+ if (component?.type !== "mcp-server") {
30
+ throw new Error(`manifest is missing mcp-server component "${key}"`);
31
+ }
32
+ return component;
33
+ }
34
+
35
+ describe("lastmile manifest vs recorded discovery metadata", () => {
36
+ it("declares exactly the three discovered MCP servers", () => {
37
+ const keys = validatedLastmileManifest.versions[0].components
38
+ .filter((component) => component.type === "mcp-server")
39
+ .map((component) => component.key)
40
+ .sort();
41
+ expect(keys).toEqual([...SERVER_KEYS].sort());
42
+ });
43
+
44
+ it.each(SERVER_KEYS)(
45
+ "%s endpoint and resource indicator match the recorded resource",
46
+ (key) => {
47
+ const recorded = lastmileDiscoveryFixture[key];
48
+ const component = mcpServer(key);
49
+ expect(component.endpointUrl).toBe(recorded.resource);
50
+ if (component.auth.mode !== "oauth") {
51
+ throw new Error(`mcp-server "${key}" must declare oauth`);
52
+ }
53
+ expect(component.auth.resourceIndicator).toBe(recorded.resource);
54
+ },
55
+ );
56
+
57
+ it.each(SERVER_KEYS)(
58
+ "%s auth domain is the recorded authorization server",
59
+ (key) => {
60
+ const recorded = lastmileDiscoveryFixture[key];
61
+ const component = mcpServer(key);
62
+ if (component.auth.mode !== "oauth") {
63
+ throw new Error(`mcp-server "${key}" must declare oauth`);
64
+ }
65
+ expect(recorded.authorization_servers).toContain(
66
+ component.auth.authDomain,
67
+ );
68
+ // One AS covers the whole plugin — a single app-level activation.
69
+ expect(recorded.authorization_servers).toHaveLength(1);
70
+ },
71
+ );
72
+
73
+ it.each(SERVER_KEYS)(
74
+ "requiredOauthScopes are exactly the scopes %s supports",
75
+ (key) => {
76
+ const recorded = lastmileDiscoveryFixture[key];
77
+ expect(
78
+ [...validatedLastmileManifest.versions[0].requiredOauthScopes].sort(),
79
+ ).toEqual([...recorded.scopes_supported].sort());
80
+ },
81
+ );
82
+
83
+ it("contains no placeholder values", () => {
84
+ const serialized = JSON.stringify(lastmileManifest);
85
+ expect(serialized).not.toMatch(/\.invalid/);
86
+ expect(serialized).not.toMatch(/PLACEHOLDER/i);
87
+ });
88
+ });
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "."
6
+ },
7
+ "include": ["./**/*.ts"]
8
+ }