thinkwork-cli 0.13.1 → 1.0.0

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 (262) hide show
  1. package/README.md +3 -14
  2. package/dist/{api-client-4DZ266J5.js → api-client-4P4JZOBX.js} +3 -1
  3. package/dist/bowser-6Z6JFAIR.js +2822 -0
  4. package/dist/{chunk-Y2WHJECR.js → chunk-4OMDWYZQ.js} +5 -44
  5. package/dist/chunk-AD2NIWB5.js +6516 -0
  6. package/dist/chunk-DV3MRBR5.js +43 -0
  7. package/dist/chunk-EI5ZX7CN.js +522 -0
  8. package/dist/chunk-EUJ7X6YD.js +126 -0
  9. package/dist/chunk-GG5WKBOX.js +436 -0
  10. package/dist/chunk-I64EZSU5.js +358 -0
  11. package/dist/chunk-KMIJ5KGT.js +128 -0
  12. package/dist/chunk-MWQ7RO76.js +137 -0
  13. package/dist/chunk-OCPHU34C.js +996 -0
  14. package/dist/chunk-OLUQ4U2Z.js +1728 -0
  15. package/dist/chunk-XYM7PE2A.js +2264 -0
  16. package/dist/chunk-YQCYD6NE.js +3299 -0
  17. package/dist/cli.js +49156 -31257
  18. package/dist/commands/enterprise/templates/deploy-repo/scripts/apply-release.mjs +0 -1
  19. package/dist/commands/enterprise/templates/deploy-repo/scripts/smoke.mjs +0 -1
  20. package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +0 -14
  21. package/dist/dist-es-2OTNTL4N.js +315 -0
  22. package/dist/dist-es-2XVAH4BQ.js +14726 -0
  23. package/dist/dist-es-3DPDUJAH.js +2000 -0
  24. package/dist/dist-es-BNZTBBVC.js +176 -0
  25. package/dist/dist-es-CD2RBDAC.js +88 -0
  26. package/dist/dist-es-I4FW57PS.js +88 -0
  27. package/dist/dist-es-KL7Y5NB2.js +377 -0
  28. package/dist/dist-es-KVFWJNDY.js +318 -0
  29. package/dist/dist-es-PS73DWNL.js +70 -0
  30. package/dist/dist-es-S3NZQFGT.js +170 -0
  31. package/dist/dist-es-SGCA4P32.js +48 -0
  32. package/dist/dist-es-WBM6J4RA.js +70 -0
  33. package/dist/dist-es-ZGVADYIF.js +485 -0
  34. package/dist/dist-es-ZKC2QKD2.js +377 -0
  35. package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +2 -1
  36. package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +1 -0
  37. package/dist/drizzle/0090_brain_schema_extraction.sql +10 -0
  38. package/dist/drizzle/0132_drop_computer_tables.sql +3 -0
  39. package/dist/drizzle/0160_compliance_event_types_plugins.sql +2 -0
  40. package/dist/drizzle/0214_think137_drop_judge_evidence_roi.sql +1 -0
  41. package/dist/drizzle/0216_drop_agent_loop_versions_goal_worker_policy.sql +1 -0
  42. package/dist/drizzle/0227_analyst_reader_role.sql +17 -20
  43. package/dist/drizzle/0230_analyst_rls.sql +28 -36
  44. package/dist/drizzle/0250_kg_schema_extraction.sql +27 -0
  45. package/dist/drizzle/0251_brain_stragglers.sql +21 -0
  46. package/dist/drizzle/0253_drop_brain_substrate.sql +2 -0
  47. package/dist/drizzle/0257_agents_runtime_allow_harness.sql +24 -0
  48. package/dist/drizzle/0261_native_auth_control_plane.sql +332 -0
  49. package/dist/drizzle/0262_auth_subscription_tickets.sql +59 -0
  50. package/dist/drizzle/0263_agentcore_runtime_identifier.sql +69 -0
  51. package/dist/drizzle/0263_drop_workos_auth_runtime.sql +236 -0
  52. package/dist/drizzle/0264_auth_enrollment_attempt_limits.sql +15 -0
  53. package/dist/drizzle/0265_eval_runs_requester_identity.sql +28 -0
  54. package/dist/drizzle/0265_require_fully_valid_auth_publication.sql +27 -0
  55. package/dist/drizzle/0266_auth_identity_recovery_grants.sql +9 -0
  56. package/dist/drizzle/0266_eval_profiles_runtime_type.sql +12 -0
  57. package/dist/drizzle/0267_ontology_candidate_rejections.sql +53 -0
  58. package/dist/drizzle/0268_identity_crosswalk_routing.sql +182 -0
  59. package/dist/drizzle/0269_ontology_system_map.sql +31 -0
  60. package/dist/drizzle/0270_tool_execution_ledger.sql +115 -0
  61. package/dist/drizzle/0271_ontology_twin_declarations.sql +47 -0
  62. package/dist/drizzle/0272_identity_graph_projection_cursor.sql +23 -0
  63. package/dist/drizzle/0273_twin_materialization_suggestions.sql +29 -0
  64. package/dist/drizzle/0274_tenant_mcp_twin_keys.sql +59 -0
  65. package/dist/drizzle/0275_identity_bulk_rebuild_fence.sql +30 -0
  66. package/dist/drizzle/0276_tool_execution_ledger_allow_cascade_delete.sql +18 -0
  67. package/dist/drizzle/0277_knowledge_base_sources.sql +107 -0
  68. package/dist/drizzle/0278_kb_page_transcription.sql +55 -0
  69. package/dist/drizzle/0279_mcp_servers_off_plugin_provenance.sql +93 -0
  70. package/dist/drizzle/0280_work_item_external_refs_drop_plane_provider.sql +46 -0
  71. package/dist/drizzle/0281_tenant_mcp_twin_keys_expiry_suffix.sql +9 -0
  72. package/dist/drizzle/0282_tenant_mcp_twin_keys_grants.sql +24 -0
  73. package/dist/drizzle/0283_agents_agentcore_runtime_dispatch.sql +13 -0
  74. package/dist/drizzle/0284_user_brain_claims.sql +69 -0
  75. package/dist/drizzle/0285_tenant_mcp_twin_keys_trusted_subsystem.sql +30 -0
  76. package/dist/drizzle/0286_brain_analytics_key.sql +26 -0
  77. package/dist/drizzle/0287_brain_subject.sql +25 -0
  78. package/dist/drizzle/0288_multi_lane_identities.sql +25 -0
  79. package/dist/event-streams-7JNLJEEL.js +894 -0
  80. package/dist/event-streams-KDF5RWR6.js +1515 -0
  81. package/dist/loadSso-ETCXTR4I.js +576 -0
  82. package/dist/loadSso-UBD7KUHE.js +583 -0
  83. package/dist/plugins/README.md +2 -2
  84. package/dist/plugins/catalog/package.json +1 -5
  85. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +6 -4
  86. package/dist/plugins/catalog/src/__tests__/catalog.test.ts +21 -21
  87. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +102 -94
  88. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +7 -8
  89. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -20
  90. package/dist/plugins/catalog/src/contracts.ts +17 -179
  91. package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -24
  92. package/dist/plugins/n8n/test/integrated-app-contract.test.ts +1 -1
  93. package/dist/plugins/twenty/package.json +2 -1
  94. package/dist/plugins/twenty/scripts/LAMBDA_DEPLOY.md +114 -0
  95. package/dist/plugins/twenty/scripts/build-lambda.sh +29 -0
  96. package/dist/plugins/twenty/scripts/configure-product-views.ts +195 -0
  97. package/dist/plugins/twenty/scripts/lambda-handler.ts +49 -0
  98. package/dist/plugins/twenty/scripts/lib/__tests__/load-attachments.test.ts +38 -0
  99. package/dist/plugins/twenty/scripts/lib/__tests__/load-records.test.ts +145 -2
  100. package/dist/plugins/twenty/scripts/lib/__tests__/mappers.test.ts +397 -151
  101. package/dist/plugins/twenty/scripts/lib/__tests__/members-ensure.test.ts +28 -129
  102. package/dist/plugins/twenty/scripts/lib/__tests__/provision-members-db.test.ts +10 -0
  103. package/dist/plugins/twenty/scripts/lib/__tests__/schema-ensure.test.ts +13 -8
  104. package/dist/plugins/twenty/scripts/lib/lastmile-reader.ts +222 -2
  105. package/dist/plugins/twenty/scripts/lib/load-attachments.ts +29 -0
  106. package/dist/plugins/twenty/scripts/lib/load-records.ts +160 -43
  107. package/dist/plugins/twenty/scripts/lib/mappers.ts +368 -152
  108. package/dist/plugins/twenty/scripts/lib/members-ensure.ts +43 -268
  109. package/dist/plugins/twenty/scripts/lib/provision-members-db.ts +57 -0
  110. package/dist/plugins/twenty/scripts/lib/schema-ensure.ts +136 -31
  111. package/dist/plugins/twenty/scripts/migrate-lastmile.ts +254 -152
  112. package/dist/plugins/twenty/scripts/provision-twenty-members.ts +44 -1
  113. package/dist/plugins/twenty/scripts/purge-lastmile-import.ts +178 -0
  114. package/dist/plugins/twenty/scripts/restructure-products.ts +312 -0
  115. package/dist/plugins/twenty/scripts/retag-stage-values.ts +362 -0
  116. package/dist/plugins/twenty/test/manifest.test.ts +2 -4
  117. package/dist/scripts/post-deploy.sh +79 -1
  118. package/dist/signin-5QZNRSOO.js +821 -0
  119. package/dist/sso-oidc-XK673P54.js +837 -0
  120. package/dist/sts-OXI2UALF.js +1113 -0
  121. package/dist/sts-SQW4NBK3.js +1117 -0
  122. package/dist/terraform/examples/greenfield/main.tf +391 -176
  123. package/dist/terraform/examples/greenfield/terraform.tfvars.example +26 -8
  124. package/dist/terraform/modules/app/agentcore-admin/main.tf +47 -0
  125. package/dist/terraform/modules/app/agentcore-code-interpreter/README.md +39 -47
  126. package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +13 -66
  127. package/dist/terraform/modules/app/agentcore-identity/main.tf +253 -0
  128. package/dist/terraform/modules/app/agentcore-identity/outputs.tf +51 -0
  129. package/dist/terraform/modules/app/agentcore-identity/scripts/bootstrap_twenty_oauth_client.sh +239 -0
  130. package/dist/terraform/modules/app/agentcore-identity/scripts/delete_identity.sh +22 -0
  131. package/dist/terraform/modules/app/agentcore-identity/scripts/delete_twenty_identity.sh +16 -0
  132. package/dist/terraform/modules/app/agentcore-identity/scripts/delete_workload_identity.sh +19 -0
  133. package/dist/terraform/modules/app/agentcore-identity/scripts/ensure_workload_identity.sh +29 -0
  134. package/dist/terraform/modules/app/agentcore-identity/scripts/read_identity.sh +55 -0
  135. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_identity.sh +73 -0
  136. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_identity.sh +45 -0
  137. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_provider.mjs +123 -0
  138. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/after.tf +15 -0
  139. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/before.tf +7 -0
  140. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/identity-after.tf +8 -0
  141. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/identity-before.tf +9 -0
  142. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/thinkwork-after.tf +3 -0
  143. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/thinkwork-before.tf +3 -0
  144. package/dist/terraform/modules/app/agentcore-identity/variables.tf +60 -0
  145. package/dist/terraform/modules/app/agentcore-memory/README.md +46 -9
  146. package/dist/terraform/modules/app/agentcore-memory/main.tf +27 -10
  147. package/dist/terraform/modules/app/agentcore-memory/scripts/create_or_find_memory.sh +156 -24
  148. package/dist/terraform/modules/app/agentcore-pi/README.md +1 -3
  149. package/dist/terraform/modules/app/agentcore-pi/main.tf +42 -52
  150. package/dist/terraform/modules/app/agentcore-pi/outputs.tf +3 -3
  151. package/dist/terraform/modules/app/agentcore-pi/scripts/reconcile_pi_runtime.mjs +175 -0
  152. package/dist/terraform/modules/app/agentcore-pi/variables.tf +35 -28
  153. package/dist/terraform/modules/app/agentcore-platform/main.tf +68 -0
  154. package/dist/terraform/modules/app/agentcore-runtime/main.tf +4 -20
  155. package/dist/terraform/modules/app/appsync-subscriptions/main.tf +127 -21
  156. package/dist/terraform/modules/app/appsync-subscriptions/outputs.tf +0 -6
  157. package/dist/terraform/modules/app/appsync-subscriptions/variables.tf +5 -0
  158. package/dist/terraform/modules/app/capability-broker/main.tf +2 -2
  159. package/dist/terraform/modules/app/capability-broker/variables.tf +11 -0
  160. package/dist/terraform/modules/app/deployment-control-plane/README.md +264 -0
  161. package/dist/terraform/modules/app/deployment-control-plane/buildspec.yml +4 -1
  162. package/dist/terraform/modules/app/deployment-control-plane/main.tf +94 -0
  163. package/dist/terraform/modules/app/deployment-control-plane/outputs.tf +5 -0
  164. package/dist/terraform/modules/app/deployment-control-plane/runner.py +3689 -233
  165. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +2579 -140
  166. package/dist/terraform/modules/app/deployment-control-plane/variables.tf +33 -0
  167. package/dist/terraform/modules/app/lambda-api/auth-state.tf +72 -0
  168. package/dist/terraform/modules/app/lambda-api/chat-latency-observability.tf +466 -0
  169. package/dist/terraform/modules/app/lambda-api/dispatch-dlq.tf +55 -0
  170. package/dist/terraform/modules/app/lambda-api/handlers.tf +531 -619
  171. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +350 -241
  172. package/dist/terraform/modules/app/lambda-api/main.tf +75 -13
  173. package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +3 -28
  174. package/dist/terraform/modules/app/lambda-api/oauth-secrets.tf +1 -2
  175. package/dist/terraform/modules/app/lambda-api/outputs.tf +17 -10
  176. package/dist/terraform/modules/app/lambda-api/runtime-config.tf +3 -21
  177. package/dist/terraform/modules/app/lambda-api/turn-assertion.tf +45 -0
  178. package/dist/terraform/modules/app/lambda-api/variables.tf +307 -121
  179. package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/README.md +1 -1
  180. package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/main.tf +18 -18
  181. package/dist/terraform/modules/app/sandbox-log-scrubber/README.md +11 -10
  182. package/dist/terraform/modules/app/sandbox-log-scrubber/main.tf +5 -5
  183. package/dist/terraform/modules/app/static-site/main.tf +1 -1
  184. package/dist/terraform/modules/app/www-dns/main.tf +9 -27
  185. package/dist/terraform/modules/app/www-dns/variables.tf +4 -10
  186. package/dist/terraform/modules/data/aurora-postgres/README.md +34 -0
  187. package/dist/terraform/modules/data/aurora-postgres/alarms.tf +82 -0
  188. package/dist/terraform/modules/data/aurora-postgres/main.tf +27 -57
  189. package/dist/terraform/modules/data/aurora-postgres/outputs.tf +0 -9
  190. package/dist/terraform/modules/data/aurora-postgres/variables.tf +41 -0
  191. package/dist/terraform/modules/data/s3-buckets/main.tf +5 -6
  192. package/dist/terraform/modules/foundation/cognito/main.tf +367 -72
  193. package/dist/terraform/modules/foundation/cognito/outputs.tf +47 -0
  194. package/dist/terraform/modules/foundation/cognito/variables.tf +131 -9
  195. package/dist/terraform/modules/thinkwork/README.md +5 -1
  196. package/dist/terraform/modules/thinkwork/main.tf +459 -234
  197. package/dist/terraform/modules/thinkwork/outputs.tf +44 -62
  198. package/dist/terraform/modules/thinkwork/variables.tf +353 -89
  199. package/dist/terraform/schema.graphql +69 -36
  200. package/dist/workspace-defaults/files/INSTRUCTIONS.md +9 -11
  201. package/dist/workspace-defaults/files/MEMORY_GUIDE.md +38 -35
  202. package/dist/workspace-defaults/files/ROUTER.md +1 -1
  203. package/dist/workspace-defaults/files/TOOLS.md +9 -39
  204. package/dist/workspace-defaults/files/USER.md +1 -0
  205. package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +6 -3
  206. package/dist/workspace-defaults/files/catalog-skills/brain-brief-builder/SKILL.md +165 -0
  207. package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/SKILL.md +75 -0
  208. package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/mcp-tooling.md +40 -0
  209. package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/validation-and-handoff.md +40 -0
  210. package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/workflow-authoring.md +46 -0
  211. package/dist/workspace-defaults/files/skills/artifact-builder/references/crm-dashboard.md +1 -1
  212. package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +22 -3
  213. package/package.json +3 -2
  214. package/dist/drizzle/0261_thread_turns_origin_turn_index.sql +0 -11
  215. package/dist/plugins/company-data/README.md +0 -49
  216. package/dist/plugins/company-data/package.json +0 -21
  217. package/dist/plugins/company-data/src/index.ts +0 -30
  218. package/dist/plugins/company-data/src/manifest.ts +0 -26
  219. package/dist/plugins/company-data/test/manifest.test.ts +0 -116
  220. package/dist/plugins/company-data/tsconfig.json +0 -8
  221. package/dist/plugins/company-etl/README.md +0 -46
  222. package/dist/plugins/company-etl/package.json +0 -21
  223. package/dist/plugins/company-etl/src/index.ts +0 -29
  224. package/dist/plugins/company-etl/src/manifest.ts +0 -26
  225. package/dist/plugins/company-etl/test/manifest.test.ts +0 -108
  226. package/dist/plugins/company-etl/tsconfig.json +0 -8
  227. package/dist/plugins/lastmile/README.md +0 -50
  228. package/dist/plugins/lastmile/package.json +0 -23
  229. package/dist/plugins/lastmile/smoke/lastmile-plugin-smoke.mjs +0 -661
  230. package/dist/plugins/lastmile/src/api/tasks-adapter.ts +0 -572
  231. package/dist/plugins/lastmile/src/discovery.fixture.ts +0 -64
  232. package/dist/plugins/lastmile/src/index.ts +0 -46
  233. package/dist/plugins/lastmile/src/manifest.ts +0 -139
  234. package/dist/plugins/lastmile/test/api/tasks-adapter.test.ts +0 -266
  235. package/dist/plugins/lastmile/test/discovery.test.ts +0 -88
  236. package/dist/plugins/lastmile/tsconfig.json +0 -8
  237. package/dist/plugins/n8n/smoke/n8n-managed-app-smoke.mjs +0 -409
  238. package/dist/plugins/twenty/smoke/twenty-managed-app-smoke.mjs +0 -359
  239. package/dist/plugins/workos-auth/package.json +0 -22
  240. package/dist/plugins/workos-auth/src/index.ts +0 -30
  241. package/dist/plugins/workos-auth/src/manifest.ts +0 -40
  242. package/dist/plugins/workos-auth/src/provider-contract.ts +0 -39
  243. package/dist/plugins/workos-auth/test/manifest.test.ts +0 -94
  244. package/dist/plugins/workos-auth/tsconfig.json +0 -8
  245. package/dist/terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base +0 -61
  246. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/sitecustomize.py +0 -227
  247. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/test_sitecustomize.py +0 -277
  248. package/dist/terraform/modules/app/agentcore-code-interpreter/scripts/build_and_push_sandbox_base.sh +0 -70
  249. package/dist/terraform/modules/app/agentcore-harness/main.tf +0 -101
  250. package/dist/terraform/modules/app/agentcore-harness/outputs.tf +0 -9
  251. package/dist/terraform/modules/app/agentcore-harness/variables.tf +0 -25
  252. package/dist/terraform/modules/app/hindsight-memory/README.md +0 -89
  253. package/dist/terraform/modules/app/hindsight-memory/main.tf +0 -411
  254. package/dist/terraform/modules/data/bedrock-knowledge-base/main.tf +0 -102
  255. /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/outputs.tf +0 -0
  256. /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/scripts/sync-database.py +0 -0
  257. /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/scripts/test_sync_database.py +0 -0
  258. /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/variables.tf +0 -0
  259. /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/README.md +0 -0
  260. /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/main.tf +0 -0
  261. /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/outputs.tf +0 -0
  262. /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/variables.tf +0 -0
@@ -1,572 +0,0 @@
1
- export type LinkedTaskStatus =
2
- | "unknown"
3
- | "todo"
4
- | "in_progress"
5
- | "completed"
6
- | "blocked"
7
- | "cancelled"
8
- | "not_applicable";
9
-
10
- export type LinkedTaskSyncStatus = "pending" | "synced" | "warning" | "error";
11
-
12
- export type SpaceWritebackPolicy =
13
- | "disabled"
14
- | "status_only"
15
- | "status_and_comments";
16
-
17
- export type ExternalTaskWritebackAction =
18
- | "status_summary"
19
- | "human_comment"
20
- | "agent_comment";
21
-
22
- export interface SpaceWritebackPolicyConfig {
23
- allowAgentComments?: boolean;
24
- agentCommentMode?: "disabled" | "requires_confirmation" | "allowed";
25
- }
26
-
27
- export interface EvaluateExternalTaskWritebackInput {
28
- policy?: SpaceWritebackPolicy | string | null;
29
- action: ExternalTaskWritebackAction;
30
- humanConfirmed?: boolean;
31
- config?: SpaceWritebackPolicyConfig | null;
32
- }
33
-
34
- export interface ExternalTaskWritebackDecision {
35
- allowed: boolean;
36
- policy: SpaceWritebackPolicy;
37
- reason:
38
- | "allowed"
39
- | "writeback_disabled"
40
- | "comments_disabled"
41
- | "agent_comment_confirmation_required"
42
- | "agent_comments_disabled";
43
- requiresHumanConfirmation: boolean;
44
- }
45
-
46
- export interface LastMileMcpToolCall {
47
- serverName: string;
48
- toolName: string;
49
- arguments: Record<string, unknown>;
50
- }
51
-
52
- export interface LastMileMcpToolResponse {
53
- content?: unknown;
54
- structuredContent?: unknown;
55
- isError?: boolean;
56
- }
57
-
58
- export interface LastMileMcpClient {
59
- callTool(call: LastMileMcpToolCall): Promise<LastMileMcpToolResponse>;
60
- }
61
-
62
- export interface LastMileTasksAdapterOptions {
63
- client: LastMileMcpClient;
64
- serverName?: string;
65
- toolNames?: Partial<LastMileTaskToolNames>;
66
- }
67
-
68
- export interface LastMileTaskToolNames {
69
- createTask: string;
70
- readTask: string;
71
- postComment: string;
72
- }
73
-
74
- export interface LastMileTaskAssigneeInput {
75
- roleKey?: string | null;
76
- externalId?: string | null;
77
- displayName?: string | null;
78
- }
79
-
80
- export interface CreateLastMileTaskInput {
81
- tenantId: string;
82
- spaceId: string;
83
- threadId: string;
84
- checklistItemId?: string | null;
85
- idempotencyKey: string;
86
- title: string;
87
- description?: string | null;
88
- required?: boolean;
89
- assignee?: LastMileTaskAssigneeInput | null;
90
- dueAt?: string | null;
91
- metadata?: Record<string, unknown> | null;
92
- }
93
-
94
- export interface ReadLastMileTaskInput {
95
- externalTaskId: string;
96
- }
97
-
98
- export interface PostLastMileTaskCommentInput {
99
- externalTaskId: string;
100
- body: string;
101
- writeback: EvaluateExternalTaskWritebackInput;
102
- metadata?: Record<string, unknown> | null;
103
- }
104
-
105
- export interface LastMileTaskSnapshot {
106
- externalTaskId: string;
107
- externalTaskUrl: string | null;
108
- title: string | null;
109
- status: LinkedTaskStatus;
110
- blocked: boolean;
111
- syncStatus: LinkedTaskSyncStatus;
112
- assignee: {
113
- externalId: string | null;
114
- displayName: string | null;
115
- } | null;
116
- dueAt: string | null;
117
- idempotent: boolean;
118
- needsTriage: boolean;
119
- raw: unknown;
120
- }
121
-
122
- export interface LastMileCommentResult {
123
- externalTaskId: string;
124
- commentId: string | null;
125
- postedAt: string | null;
126
- raw: unknown;
127
- }
128
-
129
- export interface LastMileProviderError {
130
- code: string;
131
- message: string;
132
- retryable: boolean;
133
- status?: number;
134
- detail?: unknown;
135
- }
136
-
137
- export type LastMileAdapterResult<T> =
138
- | { ok: true; value: T }
139
- | { ok: false; providerError: LastMileProviderError };
140
-
141
- export type LastMileCommentAdapterResult =
142
- | LastMileAdapterResult<LastMileCommentResult>
143
- | {
144
- ok: false;
145
- blockedByPolicy: ReturnType<typeof evaluateExternalTaskWriteback>;
146
- };
147
-
148
- const DEFAULT_TOOL_NAMES: LastMileTaskToolNames = {
149
- createTask: "create_task",
150
- readTask: "read_task",
151
- postComment: "post_comment",
152
- };
153
-
154
- export function createLastMileTasksAdapter(
155
- options: LastMileTasksAdapterOptions,
156
- ) {
157
- const serverName = options.serverName ?? "lastmile-tasks";
158
- const toolNames = { ...DEFAULT_TOOL_NAMES, ...options.toolNames };
159
-
160
- return {
161
- async createTask(
162
- input: CreateLastMileTaskInput,
163
- ): Promise<LastMileAdapterResult<LastMileTaskSnapshot>> {
164
- const response = await callProvider(options.client, {
165
- serverName,
166
- toolName: toolNames.createTask,
167
- arguments: {
168
- tenantId: input.tenantId,
169
- spaceId: input.spaceId,
170
- threadId: input.threadId,
171
- checklistItemId: input.checklistItemId ?? null,
172
- idempotencyKey: input.idempotencyKey,
173
- title: input.title,
174
- description: input.description ?? null,
175
- required: input.required ?? true,
176
- assignee: normalizeAssigneeInput(input.assignee),
177
- dueAt: input.dueAt ?? null,
178
- metadata: input.metadata ?? {},
179
- },
180
- });
181
- if (!response.ok) return response;
182
-
183
- return toTaskSnapshotResult(response.value, {
184
- fallback: {
185
- title: input.title,
186
- needsTriage:
187
- !input.assignee?.externalId && Boolean(input.assignee?.roleKey),
188
- },
189
- });
190
- },
191
-
192
- async readTask(
193
- input: ReadLastMileTaskInput,
194
- ): Promise<LastMileAdapterResult<LastMileTaskSnapshot>> {
195
- const response = await callProvider(options.client, {
196
- serverName,
197
- toolName: toolNames.readTask,
198
- arguments: { externalTaskId: input.externalTaskId },
199
- });
200
- if (!response.ok) return response;
201
- return toTaskSnapshotResult(response.value, { fallback: {} });
202
- },
203
-
204
- async postComment(
205
- input: PostLastMileTaskCommentInput,
206
- ): Promise<LastMileCommentAdapterResult> {
207
- const decision = evaluateExternalTaskWriteback(input.writeback);
208
- if (!decision.allowed) {
209
- return { ok: false, blockedByPolicy: decision };
210
- }
211
-
212
- const response = await callProvider(options.client, {
213
- serverName,
214
- toolName: toolNames.postComment,
215
- arguments: {
216
- externalTaskId: input.externalTaskId,
217
- body: input.body,
218
- metadata: input.metadata ?? {},
219
- },
220
- });
221
- if (!response.ok) return response;
222
-
223
- const record = objectRecord(response.value);
224
- return {
225
- ok: true,
226
- value: {
227
- externalTaskId: input.externalTaskId,
228
- commentId: stringValue(record.commentId) ?? stringValue(record.id),
229
- postedAt:
230
- stringValue(record.postedAt) ?? stringValue(record.createdAt),
231
- raw: response.value,
232
- },
233
- };
234
- },
235
- };
236
- }
237
-
238
- async function callProvider(
239
- client: LastMileMcpClient,
240
- call: LastMileMcpToolCall,
241
- ): Promise<LastMileAdapterResult<unknown>> {
242
- try {
243
- const response = await client.callTool(call);
244
- if (response.isError) {
245
- return {
246
- ok: false,
247
- providerError: toProviderError(
248
- extractPayload(response),
249
- "MCP_TOOL_ERROR",
250
- ),
251
- };
252
- }
253
- return { ok: true, value: extractPayload(response) };
254
- } catch (error) {
255
- return {
256
- ok: false,
257
- providerError: toProviderError(error, "MCP_CALL_FAILED"),
258
- };
259
- }
260
- }
261
-
262
- function toTaskSnapshotResult(
263
- value: unknown,
264
- options: { fallback: { title?: string; needsTriage?: boolean } },
265
- ): LastMileAdapterResult<LastMileTaskSnapshot> {
266
- const snapshot = toTaskSnapshot(value, options.fallback);
267
- if (!snapshot.externalTaskId) {
268
- return {
269
- ok: false,
270
- providerError: {
271
- code: "PROVIDER_RESPONSE_MISSING_TASK_ID",
272
- message: "LastMile task provider response did not include a task id",
273
- retryable: false,
274
- detail: redactSecrets(value),
275
- },
276
- };
277
- }
278
- return { ok: true, value: snapshot };
279
- }
280
-
281
- function toTaskSnapshot(
282
- value: unknown,
283
- fallback: { title?: string; needsTriage?: boolean },
284
- ): LastMileTaskSnapshot {
285
- const record = objectRecord(value);
286
- const assignee = normalizeAssigneeOutput(record.assignee);
287
- const normalizedStatus = normalizeExternalTaskStatus(
288
- record.status ?? record.state ?? record.taskStatus,
289
- );
290
- const blocked =
291
- typeof record.blocked === "boolean"
292
- ? record.blocked
293
- : normalizedStatus.blocked;
294
- return {
295
- externalTaskId:
296
- stringValue(record.externalTaskId) ??
297
- stringValue(record.taskId) ??
298
- stringValue(record.id) ??
299
- "",
300
- externalTaskUrl:
301
- stringValue(record.externalTaskUrl) ??
302
- stringValue(record.url) ??
303
- stringValue(record.webUrl),
304
- title: stringValue(record.title) ?? fallback.title ?? null,
305
- status: normalizedStatus.status,
306
- blocked,
307
- syncStatus: normalizedStatus.syncStatus,
308
- assignee,
309
- dueAt: stringValue(record.dueAt) ?? stringValue(record.dueDate),
310
- idempotent: Boolean(
311
- record.idempotent ??
312
- record.duplicate ??
313
- record.existing ??
314
- record.alreadyExists,
315
- ),
316
- needsTriage: Boolean(
317
- fallback.needsTriage || record.needsTriage || !assignee,
318
- ),
319
- raw: value,
320
- };
321
- }
322
-
323
- function normalizeAssigneeInput(
324
- input: LastMileTaskAssigneeInput | null | undefined,
325
- ) {
326
- if (!input) return null;
327
- return {
328
- roleKey: input.roleKey ?? null,
329
- externalId: input.externalId ?? null,
330
- displayName: input.displayName ?? null,
331
- };
332
- }
333
-
334
- function normalizeAssigneeOutput(value: unknown) {
335
- const record = objectRecord(value);
336
- const externalId =
337
- stringValue(record.externalId) ??
338
- stringValue(record.id) ??
339
- stringValue(record.userId);
340
- const displayName =
341
- stringValue(record.displayName) ??
342
- stringValue(record.name) ??
343
- stringValue(record.email);
344
- if (!externalId && !displayName) return null;
345
- return { externalId, displayName };
346
- }
347
-
348
- function extractPayload(response: LastMileMcpToolResponse): unknown {
349
- if (response.structuredContent !== undefined) {
350
- const structured = objectRecord(response.structuredContent);
351
- return structured.task ?? structured.result ?? structured;
352
- }
353
- if (Array.isArray(response.content)) {
354
- const text = response.content
355
- .map((item) => stringValue(objectRecord(item).text) ?? "")
356
- .join("\n")
357
- .trim();
358
- if (!text) return {};
359
- try {
360
- return JSON.parse(text);
361
- } catch {
362
- return { message: text };
363
- }
364
- }
365
- return response.content ?? {};
366
- }
367
-
368
- function toProviderError(
369
- value: unknown,
370
- fallbackCode: string,
371
- ): LastMileProviderError {
372
- const record = objectRecord(value);
373
- const status = numberValue(record.status) ?? numberValue(record.statusCode);
374
- const code =
375
- stringValue(record.code) ??
376
- stringValue(record.errorCode) ??
377
- (status === 403 ? "PERMISSION_DENIED" : fallbackCode);
378
- return {
379
- code,
380
- message:
381
- stringValue(record.message) ??
382
- stringValue(record.error) ??
383
- (value instanceof Error
384
- ? value.message
385
- : "LastMile task provider failed"),
386
- retryable:
387
- typeof record.retryable === "boolean"
388
- ? record.retryable
389
- : status === undefined || status >= 500,
390
- ...(status !== undefined ? { status } : {}),
391
- detail: redactSecrets(value),
392
- };
393
- }
394
-
395
- function normalizeExternalTaskStatus(value: unknown): {
396
- status: LinkedTaskStatus;
397
- blocked: boolean;
398
- syncStatus: LinkedTaskSyncStatus;
399
- } {
400
- const normalized = normalizeStatusToken(value);
401
- if (!normalized) {
402
- return { status: "unknown", blocked: false, syncStatus: "warning" };
403
- }
404
-
405
- if (
406
- normalized === "completed" ||
407
- normalized === "complete" ||
408
- normalized === "done" ||
409
- normalized === "closed"
410
- ) {
411
- return { status: "completed", blocked: false, syncStatus: "synced" };
412
- }
413
-
414
- if (
415
- normalized === "blocked" ||
416
- normalized === "on_hold" ||
417
- normalized === "waiting" ||
418
- normalized === "stalled"
419
- ) {
420
- return { status: "blocked", blocked: true, syncStatus: "synced" };
421
- }
422
-
423
- if (
424
- normalized === "in_progress" ||
425
- normalized === "started" ||
426
- normalized === "working" ||
427
- normalized === "active"
428
- ) {
429
- return { status: "in_progress", blocked: false, syncStatus: "synced" };
430
- }
431
-
432
- if (
433
- normalized === "todo" ||
434
- normalized === "to_do" ||
435
- normalized === "open" ||
436
- normalized === "new" ||
437
- normalized === "not_started"
438
- ) {
439
- return { status: "todo", blocked: false, syncStatus: "synced" };
440
- }
441
-
442
- if (
443
- normalized === "cancelled" ||
444
- normalized === "canceled" ||
445
- normalized === "void"
446
- ) {
447
- return { status: "cancelled", blocked: false, syncStatus: "synced" };
448
- }
449
-
450
- if (
451
- normalized === "not_applicable" ||
452
- normalized === "not_applicable_not_needed" ||
453
- normalized === "n_a" ||
454
- normalized === "na"
455
- ) {
456
- return { status: "not_applicable", blocked: false, syncStatus: "synced" };
457
- }
458
-
459
- return { status: "unknown", blocked: false, syncStatus: "warning" };
460
- }
461
-
462
- function evaluateExternalTaskWriteback(
463
- input: EvaluateExternalTaskWritebackInput,
464
- ): ExternalTaskWritebackDecision {
465
- const policy = normalizeSpaceWritebackPolicy(input.policy);
466
- if (policy === "disabled") {
467
- return deny(policy, "writeback_disabled", false);
468
- }
469
-
470
- if (input.action === "status_summary") {
471
- return allow(policy);
472
- }
473
-
474
- if (policy === "status_only") {
475
- return deny(policy, "comments_disabled", false);
476
- }
477
-
478
- if (input.action === "human_comment") {
479
- return allow(policy);
480
- }
481
-
482
- const agentCommentMode =
483
- input.config?.agentCommentMode ??
484
- (input.config?.allowAgentComments ? "allowed" : "requires_confirmation");
485
- if (agentCommentMode === "disabled") {
486
- return deny(policy, "agent_comments_disabled", false);
487
- }
488
- if (agentCommentMode === "allowed" || input.humanConfirmed === true) {
489
- return allow(policy);
490
- }
491
- return deny(policy, "agent_comment_confirmation_required", true);
492
- }
493
-
494
- function normalizeSpaceWritebackPolicy(
495
- value: SpaceWritebackPolicy | string | null | undefined,
496
- ): SpaceWritebackPolicy {
497
- if (typeof value !== "string") return "disabled";
498
- const normalized = value.trim().toLowerCase();
499
- if (
500
- normalized === "disabled" ||
501
- normalized === "status_only" ||
502
- normalized === "status_and_comments"
503
- ) {
504
- return normalized;
505
- }
506
- return "disabled";
507
- }
508
-
509
- function allow(policy: SpaceWritebackPolicy): ExternalTaskWritebackDecision {
510
- return {
511
- allowed: true,
512
- policy,
513
- reason: "allowed",
514
- requiresHumanConfirmation: false,
515
- };
516
- }
517
-
518
- function deny(
519
- policy: SpaceWritebackPolicy,
520
- reason: ExternalTaskWritebackDecision["reason"],
521
- requiresHumanConfirmation: boolean,
522
- ): ExternalTaskWritebackDecision {
523
- return {
524
- allowed: false,
525
- policy,
526
- reason,
527
- requiresHumanConfirmation,
528
- };
529
- }
530
-
531
- function normalizeStatusToken(value: unknown): string | null {
532
- if (value === undefined || value === null) return null;
533
- const normalized = String(value)
534
- .trim()
535
- .toLowerCase()
536
- .replace(/[\s/-]+/g, "_");
537
- return normalized.length > 0 ? normalized : null;
538
- }
539
-
540
- function redactSecrets(value: unknown): unknown {
541
- if (Array.isArray(value)) return value.map((item) => redactSecrets(item));
542
- if (!value || typeof value !== "object") {
543
- return value instanceof Error
544
- ? { name: value.name, message: value.message }
545
- : value;
546
- }
547
- const output: Record<string, unknown> = {};
548
- for (const [key, child] of Object.entries(value as Record<string, unknown>)) {
549
- if (/token|secret|password|authorization|api[-_]?key/i.test(key)) {
550
- output[key] = "[redacted]";
551
- } else {
552
- output[key] = redactSecrets(child);
553
- }
554
- }
555
- return output;
556
- }
557
-
558
- function objectRecord(value: unknown): Record<string, unknown> {
559
- return value && typeof value === "object"
560
- ? (value as Record<string, unknown>)
561
- : {};
562
- }
563
-
564
- function stringValue(value: unknown): string | null {
565
- return typeof value === "string" && value.trim() ? value : null;
566
- }
567
-
568
- function numberValue(value: unknown): number | undefined {
569
- return typeof value === "number" && Number.isFinite(value)
570
- ? value
571
- : undefined;
572
- }
@@ -1,64 +0,0 @@
1
- /**
2
- * Recorded LastMile OAuth discovery metadata (plan 2026-06-12-001 U9).
3
- *
4
- * Captured 2026-06-12 from the live RFC 9728 protected-resource metadata
5
- * endpoints:
6
- *
7
- * https://dev-mcp.lastmile-tei.com/.well-known/oauth-protected-resource/{crm,tasks,routing}
8
- *
9
- * `lastmile-discovery.test.ts` asserts the manifest against this fixture,
10
- * and `plugins/lastmile/smoke/lastmile-plugin-smoke.mjs` re-fetches the live
11
- * endpoints to catch drift between LastMile's deployment and this
12
- * recording. If LastMile changes its auth server, resources, or scope
13
- * vocabulary, update this fixture AND the manifest together.
14
- *
15
- * NOTE: these are LastMile's DEVELOP-stage endpoints (prod is
16
- * mcp.lastmile-tei.com). Per-stage endpoint parameterization is a known
17
- * v1 gap — see the manifest header.
18
- */
19
-
20
- export interface RecordedProtectedResourceMetadata {
21
- resource: string;
22
- authorization_servers: string[];
23
- bearer_methods_supported: string[];
24
- scopes_supported: string[];
25
- resource_documentation: string;
26
- }
27
-
28
- export const LASTMILE_DISCOVERY_CAPTURED_AT = "2026-06-12";
29
-
30
- export const lastmileDiscoveryFixture: Record<
31
- "crm" | "tasks" | "routing",
32
- RecordedProtectedResourceMetadata
33
- > = {
34
- crm: {
35
- resource: "https://dev-mcp.lastmile-tei.com/crm",
36
- authorization_servers: [
37
- "https://straightforward-dragon-14-staging.authkit.app",
38
- ],
39
- bearer_methods_supported: ["header"],
40
- scopes_supported: ["openid", "email", "profile", "offline_access"],
41
- resource_documentation:
42
- "https://github.com/homecareintel/web-apps/blob/main/docs/MCP.md",
43
- },
44
- tasks: {
45
- resource: "https://dev-mcp.lastmile-tei.com/tasks",
46
- authorization_servers: [
47
- "https://straightforward-dragon-14-staging.authkit.app",
48
- ],
49
- bearer_methods_supported: ["header"],
50
- scopes_supported: ["openid", "email", "profile", "offline_access"],
51
- resource_documentation:
52
- "https://github.com/homecareintel/web-apps/blob/main/docs/MCP.md",
53
- },
54
- routing: {
55
- resource: "https://dev-mcp.lastmile-tei.com/routing",
56
- authorization_servers: [
57
- "https://straightforward-dragon-14-staging.authkit.app",
58
- ],
59
- bearer_methods_supported: ["header"],
60
- scopes_supported: ["openid", "email", "profile", "offline_access"],
61
- resource_documentation:
62
- "https://github.com/homecareintel/web-apps/blob/main/docs/MCP.md",
63
- },
64
- };
@@ -1,46 +0,0 @@
1
- import { lastmileManifest } from "./manifest";
2
-
3
- export const lastmilePluginPackage = {
4
- packageKey: "lastmile",
5
- sourceRoot: "plugins/lastmile",
6
- manifest: lastmileManifest,
7
- ownedSources: [
8
- {
9
- kind: "manifest",
10
- path: "plugins/lastmile/src/manifest.ts",
11
- description: "LastMile catalog manifest and MCP component contract.",
12
- },
13
- {
14
- kind: "api",
15
- path: "plugins/lastmile/src/api/tasks-adapter.ts",
16
- description:
17
- "LastMile task adapter that normalizes MCP task provider calls.",
18
- },
19
- {
20
- kind: "api",
21
- path: "plugins/lastmile/src/discovery.fixture.ts",
22
- description:
23
- "Recorded protected-resource discovery metadata used by package drift tests.",
24
- },
25
- {
26
- kind: "smoke",
27
- path: "plugins/lastmile/smoke",
28
- description: "LastMile live plugin smoke validation script.",
29
- },
30
- {
31
- kind: "tests",
32
- path: "plugins/lastmile/test",
33
- description: "LastMile package-local discovery and manifest drift tests.",
34
- },
35
- {
36
- kind: "docs",
37
- path: "plugins/lastmile/README.md",
38
- description: "LastMile package ownership and verification notes.",
39
- },
40
- ],
41
- compatibilityLinks: [],
42
- } as const;
43
-
44
- export { lastmileManifest };
45
- export { lastmileDiscoveryFixture } from "./discovery.fixture";
46
- export * from "./api/tasks-adapter";