thinkwork-cli 0.12.15 → 0.12.17

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 (152) hide show
  1. package/dist/{api-client-4VT3FWOH.js → api-client-JUBCQQDF.js} +1 -1
  2. package/dist/{chunk-H7AB42ES.js → chunk-STY44FQO.js} +13 -0
  3. package/dist/cli.js +1107 -10225
  4. package/dist/commands/enterprise/templates/deploy-repo/docs/runbook.md +3 -8
  5. package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +1 -184
  6. package/dist/drizzle/0050_brain_v0_entity_subtype.sql +2 -2
  7. package/dist/drizzle/0051_brain_v0_tenant_entity_pages.sql +6 -6
  8. package/dist/drizzle/0052_brain_v0_external_refs.sql +2 -2
  9. package/dist/drizzle/0053_brain_v0_unresolved_mentions_subtype.sql +2 -2
  10. package/dist/drizzle/0145_knowledge_graph_thread_ingest.sql +14 -14
  11. package/dist/drizzle/0146_knowledge_graph_source_scope.sql +1 -1
  12. package/dist/drizzle/0157_knowledge_graph_observations_source.sql +2 -2
  13. package/dist/drizzle/0158_wiki_tenant_scope.sql +1 -1
  14. package/dist/drizzle/0165_plugin_premium_entitlements.sql +2 -2
  15. package/dist/drizzle/{0166_company_brain_substrate_contract.sql → 0166_brain_substrate_contract.sql} +9 -9
  16. package/dist/drizzle/{0167_company_brain_artifact_manifest_runtime.sql → 0167_brain_artifact_manifest_runtime.sql} +5 -5
  17. package/dist/drizzle/0168_eval_skill_gate.sql +1 -1
  18. package/dist/drizzle/0183_okf_artifact_manifests.sql +1 -1
  19. package/dist/drizzle/0197_rcm_context_columns.sql +28 -0
  20. package/dist/drizzle/0200_eval_results_execution_tier.sql +40 -0
  21. package/dist/drizzle/0201_brain_dream_runs.sql +72 -0
  22. package/dist/drizzle/0202_backfill_thread_participants_from_senders.sql +110 -0
  23. package/dist/drizzle/0203_threads_mode_override.sql +61 -0
  24. package/dist/drizzle/0204_thread_turns_triggering_message_id.sql +48 -0
  25. package/dist/drizzle/0205_routines_git_python.sql +185 -0
  26. package/dist/drizzle/0206_agent_loop_versions_routine_actions.sql +40 -0
  27. package/dist/drizzle/0207_tenant_credentials_github_repo_kind.sql +52 -0
  28. package/dist/drizzle/0208_knowledge_graph_neutral_identifiers.sql +253 -0
  29. package/dist/drizzle/0209_living_artifacts_schema.sql +109 -0
  30. package/dist/drizzle/0210_think137_automations_additive_schema.sql +113 -0
  31. package/dist/drizzle/0211_backfill_agent_loop_versions_target_spec.sql +120 -0
  32. package/dist/drizzle/0212_fold_webhooks_into_automations.sql +312 -0
  33. package/dist/drizzle/0213_agent_loop_versions_judge_evidence_nullable.sql +63 -0
  34. package/dist/drizzle/0214_think137_drop_judge_evidence_roi.sql +99 -0
  35. package/dist/drizzle/0215_agent_loop_versions_goal_worker_policy_nullable.sql +70 -0
  36. package/dist/drizzle/0216_drop_agent_loop_versions_goal_worker_policy.sql +81 -0
  37. package/dist/drizzle/0217_agents_capability_folder_dispatch.sql +12 -0
  38. package/dist/drizzle/0218_document_plates.sql +30 -0
  39. package/dist/drizzle/0219_document_section_waivers.sql +29 -0
  40. package/dist/drizzle/0220_artifacts_created_by_user.sql +21 -0
  41. package/dist/drizzle/0221_artifact_shares.sql +29 -0
  42. package/dist/drizzle/0221_workflow_interpreter_thin_slice.sql +71 -0
  43. package/dist/drizzle/0222_compliance_drainer_select_audit_events.sql +21 -0
  44. package/dist/drizzle/0223_document_conformance_reports.sql +38 -0
  45. package/dist/drizzle/0224_artifact_refresh_state.sql +11 -0
  46. package/dist/drizzle/0225_think216_agent_loop_convergence.sql +21 -0
  47. package/dist/drizzle/0226_drop_n8n_agent_step_runs.sql +6 -0
  48. package/dist/drizzle/0227_analyst_reader_role.sql +1055 -0
  49. package/dist/drizzle/0228_tenant_credentials_rds_iam_kind.sql +62 -0
  50. package/dist/drizzle/0229_analyst_reader_rds_iam_grant.sql +79 -0
  51. package/dist/drizzle/0230_analyst_rls.sql +1613 -0
  52. package/dist/drizzle/0231_cost_events_cache_write_enforcement_exempt.sql +11 -0
  53. package/dist/plugins/catalog/package.json +0 -1
  54. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +0 -1
  55. package/dist/plugins/catalog/src/__tests__/catalog.test.ts +16 -8
  56. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +56 -0
  57. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +0 -2
  58. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -5
  59. package/dist/plugins/catalog/src/contracts.ts +112 -0
  60. package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -6
  61. package/dist/plugins/n8n/README.md +4 -36
  62. package/dist/plugins/n8n/src/deployment/managed-app.ts +0 -17
  63. package/dist/plugins/n8n/src/manifest.ts +0 -5
  64. package/dist/plugins/n8n/terraform/n8n/main.tf +0 -26
  65. package/dist/plugins/n8n/terraform/n8n/outputs.tf +0 -5
  66. package/dist/plugins/n8n/terraform/n8n/variables.tf +0 -6
  67. package/dist/plugins/n8n/test/manifest.test.ts +0 -1
  68. package/dist/plugins/twenty/package.json +5 -0
  69. package/dist/plugins/twenty/scripts/lib/__tests__/load-records.test.ts +232 -0
  70. package/dist/plugins/twenty/scripts/lib/__tests__/mappers.test.ts +489 -0
  71. package/dist/plugins/twenty/scripts/lib/__tests__/members-ensure.test.ts +199 -0
  72. package/dist/plugins/twenty/scripts/lib/__tests__/provision-members-db.test.ts +43 -0
  73. package/dist/plugins/twenty/scripts/lib/__tests__/schema-ensure.test.ts +230 -0
  74. package/dist/plugins/twenty/scripts/lib/__tests__/twenty-client.test.ts +207 -0
  75. package/dist/plugins/twenty/scripts/lib/lastmile-reader.ts +282 -0
  76. package/dist/plugins/twenty/scripts/lib/load-attachments.ts +220 -0
  77. package/dist/plugins/twenty/scripts/lib/load-records.ts +680 -0
  78. package/dist/plugins/twenty/scripts/lib/mappers.ts +559 -0
  79. package/dist/plugins/twenty/scripts/lib/members-ensure.ts +381 -0
  80. package/dist/plugins/twenty/scripts/lib/provision-members-db.ts +191 -0
  81. package/dist/plugins/twenty/scripts/lib/schema-ensure.ts +425 -0
  82. package/dist/plugins/twenty/scripts/lib/twenty-client.ts +246 -0
  83. package/dist/plugins/twenty/scripts/migrate-lastmile.ts +610 -0
  84. package/dist/plugins/twenty/scripts/provision-twenty-members.ts +214 -0
  85. package/dist/plugins/twenty/src/manifest.ts +99 -0
  86. package/dist/plugins/twenty/terraform/twenty/README.md +1 -1
  87. package/dist/plugins/twenty/test/manifest.test.ts +12 -2
  88. package/dist/terraform/examples/greenfield/main.tf +90 -380
  89. package/dist/terraform/examples/greenfield/terraform.tfvars.example +0 -1
  90. package/dist/terraform/modules/app/agentcore-pi/README.md +1 -3
  91. package/dist/terraform/modules/app/agentcore-pi/main.tf +36 -32
  92. package/dist/terraform/modules/app/agentcore-pi/variables.tf +23 -15
  93. package/dist/terraform/modules/app/agentcore-runtime/main.tf +3 -3
  94. package/dist/terraform/modules/app/customer-domain/main.tf +16 -2
  95. package/dist/terraform/modules/app/deployment-control-plane/main.tf +5 -0
  96. package/dist/terraform/modules/app/deployment-control-plane/runner.py +85 -207
  97. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +56 -2
  98. package/dist/terraform/modules/app/hindsight-memory/main.tf +52 -4
  99. package/dist/terraform/modules/app/lambda-api/eval-fanout.tf +7 -0
  100. package/dist/terraform/modules/app/lambda-api/handlers.tf +493 -89
  101. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +215 -96
  102. package/dist/terraform/modules/app/lambda-api/main.tf +24 -5
  103. package/dist/terraform/modules/app/lambda-api/outputs.tf +19 -11
  104. package/dist/terraform/modules/app/lambda-api/variables.tf +94 -67
  105. package/dist/terraform/modules/app/ses-email/main.tf +14 -2
  106. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/main.tf +493 -0
  107. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/outputs.tf +34 -0
  108. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/variables.tf +32 -0
  109. package/dist/terraform/modules/data/aurora-postgres/main.tf +55 -0
  110. package/dist/terraform/modules/data/aurora-postgres/outputs.tf +15 -0
  111. package/dist/terraform/modules/data/s3-buckets/main.tf +26 -0
  112. package/dist/terraform/modules/thinkwork/README.md +0 -1
  113. package/dist/terraform/modules/thinkwork/main.tf +167 -446
  114. package/dist/terraform/modules/thinkwork/outputs.tf +2 -142
  115. package/dist/terraform/modules/thinkwork/variables.tf +55 -309
  116. package/dist/terraform/schema.graphql +4 -0
  117. package/dist/workspace-defaults/files/AGENTS.md +45 -31
  118. package/dist/workspace-defaults/files/CONTEXT.md +48 -4
  119. package/dist/workspace-defaults/files/GUARDRAILS.md +18 -0
  120. package/dist/workspace-defaults/files/MEMORY_GUIDE.md +32 -4
  121. package/dist/workspace-defaults/files/SPACE.md +34 -19
  122. package/dist/workspace-defaults/files/TOOLS.md +30 -0
  123. package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +154 -0
  124. package/dist/workspace-defaults/files/skills/document-composer/references/authoring-rules.md +101 -0
  125. package/package.json +2 -1
  126. package/dist/plugins/company-brain/README.md +0 -37
  127. package/dist/plugins/company-brain/package.json +0 -33
  128. package/dist/plugins/company-brain/runtime/cognee/Dockerfile +0 -11
  129. package/dist/plugins/company-brain/smoke/cognee-managed-app-smoke.mjs +0 -458
  130. package/dist/plugins/company-brain/smoke/cognee-memory-cutover-smoke.mjs +0 -539
  131. package/dist/plugins/company-brain/smoke/company-brain-context-engine-smoke.mjs +0 -312
  132. package/dist/plugins/company-brain/smoke/company-brain-operations-smoke.mjs +0 -449
  133. package/dist/plugins/company-brain/smoke/company-brain-plugin-smoke.mjs +0 -655
  134. package/dist/plugins/company-brain/smoke/hindsight-memory-isolation-smoke.mjs +0 -474
  135. package/dist/plugins/company-brain/src/api/cognee-client.ts +0 -896
  136. package/dist/plugins/company-brain/src/api/cognee-cluster-identity.ts +0 -49
  137. package/dist/plugins/company-brain/src/api/cognee-memory-scope.ts +0 -84
  138. package/dist/plugins/company-brain/src/api/context-engine-provider.ts +0 -888
  139. package/dist/plugins/company-brain/src/api/migration.ts +0 -665
  140. package/dist/plugins/company-brain/src/deployment/cognee-managed-app.ts +0 -396
  141. package/dist/plugins/company-brain/src/index.ts +0 -62
  142. package/dist/plugins/company-brain/src/manifest.ts +0 -112
  143. package/dist/plugins/company-brain/terraform/cognee/README.md +0 -263
  144. package/dist/plugins/company-brain/terraform/cognee/main.tf +0 -766
  145. package/dist/plugins/company-brain/terraform/cognee/outputs.tf +0 -144
  146. package/dist/plugins/company-brain/terraform/cognee/variables.tf +0 -402
  147. package/dist/plugins/company-brain/test/api/cognee-client.test.ts +0 -562
  148. package/dist/plugins/company-brain/test/api/cognee-memory-scope.test.ts +0 -74
  149. package/dist/plugins/company-brain/test/api/context-engine-provider.test.ts +0 -447
  150. package/dist/plugins/company-brain/test/api/migration.test.ts +0 -465
  151. package/dist/plugins/company-brain/test/manifest.test.ts +0 -95
  152. package/dist/plugins/company-brain/tsconfig.json +0 -8
@@ -1,465 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from "vitest";
2
- import type {
3
- BrainArtifactManifestRow,
4
- BrainMigrationDeps,
5
- BrainSubstrateMigrationRow,
6
- BrainSubstrateStateRow,
7
- } from "../../src/api/migration.js";
8
- import {
9
- requestCompanyBrainProductionMigration,
10
- updateCompanyBrainMigration,
11
- } from "../../src/api/migration.js";
12
-
13
- const now = new Date("2026-06-14T12:00:00.000Z");
14
-
15
- function substrate(
16
- overrides: Partial<BrainSubstrateStateRow> = {},
17
- ): BrainSubstrateStateRow {
18
- return {
19
- id: "substrate-1",
20
- tenant_id: "tenant-1",
21
- managed_application_id: "app-1",
22
- latest_deployment_job_id: "job-1",
23
- storage_tier: "default",
24
- active_backend: "default",
25
- status: "ready",
26
- health_status: "healthy",
27
- backend_mode: "default",
28
- graph_provider: "cognee",
29
- vector_provider: "postgres",
30
- embedding_model: "amazon.titan-embed-text-v2:0",
31
- vector_dimension: 1024,
32
- cognee_version: "0.2.0",
33
- cognee_endpoint: "https://cognee.internal.example.com",
34
- s3_artifact_root: "s3://brain-artifacts/tenant-1/",
35
- s3_manifest_root: "s3://brain-manifests/tenant-1/",
36
- s3_vault_projection_root: "s3://brain-vault/tenant-1/",
37
- neptune_graph_id: null,
38
- neptune_endpoint: null,
39
- efs_file_system_id: null,
40
- production_posture: null,
41
- latest_ingest_at: null,
42
- latest_projection_at: null,
43
- ingestion_queue_depth: 0,
44
- failed_ingest_count: 0,
45
- graph_entity_count: null,
46
- graph_edge_count: null,
47
- source_artifact_count: null,
48
- vault_projection_count: null,
49
- ontology_version: null,
50
- launch_capabilities: {},
51
- optional_capabilities: {},
52
- operator_evidence: { smoke: "pass" },
53
- last_failure_message: null,
54
- last_failure_at: null,
55
- created_at: new Date("2026-06-14T11:00:00.000Z"),
56
- updated_at: new Date("2026-06-14T11:30:00.000Z"),
57
- ...overrides,
58
- };
59
- }
60
-
61
- function manifest(
62
- overrides: Partial<BrainArtifactManifestRow> = {},
63
- ): BrainArtifactManifestRow {
64
- return {
65
- id: "manifest-1",
66
- tenant_id: "tenant-1",
67
- substrate_id: "substrate-1",
68
- migration_id: null,
69
- ingest_run_id: "ingest-1",
70
- manifest_kind: "source_artifact",
71
- storage_tier: "default",
72
- source_family: "threads",
73
- source_kind: "thread",
74
- source_type: "thread",
75
- source_ids: ["thread-1"],
76
- source_id_hash: "hash-1",
77
- manifest_uri: "s3://brain-manifests/tenant-1/manifest-1.json",
78
- artifact_root_uri: "s3://brain-artifacts/tenant-1/thread-1/",
79
- vault_projection_root_uri: null,
80
- object_version_id: null,
81
- content_type: "application/json",
82
- content_encoding: null,
83
- byte_length: 512,
84
- checksum_sha256: "sha256",
85
- object_count: 3,
86
- source_count: 1,
87
- embedding_model: "amazon.titan-embed-text-v2:0",
88
- vector_dimension: 1024,
89
- ontology_version: "company-brain-v1",
90
- ontology_mechanism: "default",
91
- status: "active",
92
- metadata: {},
93
- created_at: new Date("2026-06-14T11:00:00.000Z"),
94
- updated_at: new Date("2026-06-14T11:30:00.000Z"),
95
- ...overrides,
96
- };
97
- }
98
-
99
- function migration(
100
- overrides: Partial<BrainSubstrateMigrationRow> = {},
101
- ): BrainSubstrateMigrationRow {
102
- return {
103
- id: "migration-1",
104
- tenant_id: "tenant-1",
105
- substrate_id: "substrate-1",
106
- from_storage_tier: "default",
107
- to_storage_tier: "production",
108
- phase: "validating",
109
- status: "running",
110
- requested_by_user_id: "user-1",
111
- deployment_job_id: null,
112
- embedding_model: "amazon.titan-embed-text-v2:0",
113
- vector_dimension: 1024,
114
- validation_summary: { validationPassed: false, vectorDimension: 1024 },
115
- operator_evidence: { runbook: "checked" },
116
- error_message: null,
117
- requested_at: new Date("2026-06-14T11:40:00.000Z"),
118
- started_at: new Date("2026-06-14T11:41:00.000Z"),
119
- completed_at: null,
120
- rollback_window_closes_at: null,
121
- created_at: new Date("2026-06-14T11:40:00.000Z"),
122
- updated_at: new Date("2026-06-14T11:50:00.000Z"),
123
- ...overrides,
124
- };
125
- }
126
-
127
- function deps(args: {
128
- substrate?: BrainSubstrateStateRow | null;
129
- migration?: BrainSubstrateMigrationRow | null;
130
- activeMigration?: BrainSubstrateMigrationRow | null;
131
- manifests?: BrainArtifactManifestRow[];
132
- }) {
133
- const state = {
134
- substrate: args.substrate ?? substrate(),
135
- migration: args.migration ?? migration(),
136
- };
137
- const testDeps: BrainMigrationDeps & {
138
- createdMigrations: BrainSubstrateMigrationRow[];
139
- migrationPatches: Array<Partial<BrainSubstrateMigrationRow>>;
140
- substratePatches: Array<Partial<BrainSubstrateStateRow>>;
141
- events: Array<Record<string, unknown>>;
142
- } = {
143
- createdMigrations: [],
144
- migrationPatches: [],
145
- substratePatches: [],
146
- events: [],
147
- getSubstrateState: vi.fn(async () => state.substrate),
148
- getMigration: vi.fn(async () => state.migration),
149
- getActiveMigration: vi.fn(async () => args.activeMigration ?? null),
150
- listReplayManifests: vi.fn(async () => args.manifests ?? [manifest()]),
151
- createMigration: vi.fn(async (values) => {
152
- const created = migration({
153
- ...values,
154
- id: "migration-new",
155
- phase: values.phase ?? "requested",
156
- status: values.status ?? "requested",
157
- });
158
- testDeps.createdMigrations.push(created);
159
- state.migration = created;
160
- return created;
161
- }),
162
- updateMigration: vi.fn(async ({ patch }) => {
163
- testDeps.migrationPatches.push(patch);
164
- const updated = migration({ ...state.migration, ...patch });
165
- state.migration = updated;
166
- return updated;
167
- }),
168
- updateSubstrate: vi.fn(async ({ patch }) => {
169
- testDeps.substratePatches.push(patch);
170
- if (state.substrate)
171
- state.substrate = substrate({ ...state.substrate, ...patch });
172
- }),
173
- appendEvent: vi.fn(async (event) => {
174
- testDeps.events.push(event as Record<string, unknown>);
175
- }),
176
- now: () => now,
177
- };
178
- return testDeps;
179
- }
180
-
181
- beforeEach(() => {
182
- vi.restoreAllMocks();
183
- });
184
-
185
- describe("requestCompanyBrainProductionMigration", () => {
186
- it("creates a requested migration and marks the default substrate as migrating", async () => {
187
- const testDeps = deps({});
188
-
189
- const result = await requestCompanyBrainProductionMigration(
190
- {
191
- tenantId: "tenant-1",
192
- requestedByUserId: "user-1",
193
- operatorEvidence: { ticket: "THNK-6" },
194
- },
195
- testDeps,
196
- );
197
-
198
- expect(result).toMatchObject({
199
- id: "migration-new",
200
- from_storage_tier: "default",
201
- to_storage_tier: "production",
202
- phase: "requested",
203
- status: "requested",
204
- embedding_model: "amazon.titan-embed-text-v2:0",
205
- vector_dimension: 1024,
206
- requested_by_user_id: "user-1",
207
- validation_summary: expect.objectContaining({
208
- replayManifestCount: 1,
209
- sourceCount: 1,
210
- objectCount: 3,
211
- validationPassed: false,
212
- }),
213
- });
214
- expect(testDeps.substratePatches.at(-1)).toMatchObject({
215
- status: "migrating",
216
- health_status: "degraded",
217
- operator_evidence: {
218
- smoke: "pass",
219
- latestMigrationId: "migration-new",
220
- },
221
- });
222
- expect(testDeps.events.at(-1)).toMatchObject({
223
- event_type: "brain.migration.requested",
224
- migration_id: "migration-new",
225
- });
226
- });
227
-
228
- it("requires explicit empty-source approval before migrating without replay manifests", async () => {
229
- const testDeps = deps({ manifests: [] });
230
-
231
- await expect(
232
- requestCompanyBrainProductionMigration(
233
- { tenantId: "tenant-1" },
234
- testDeps,
235
- ),
236
- ).rejects.toMatchObject({ extensions: { code: "BAD_USER_INPUT" } });
237
- expect(testDeps.createdMigrations).toHaveLength(0);
238
- expect(testDeps.substratePatches).toHaveLength(0);
239
- });
240
-
241
- it("rejects manifests whose vector dimension does not match the target", async () => {
242
- const testDeps = deps({
243
- manifests: [
244
- manifest({ id: "manifest-mismatch", vector_dimension: 1536 }),
245
- ],
246
- });
247
-
248
- await expect(
249
- requestCompanyBrainProductionMigration(
250
- { tenantId: "tenant-1", vectorDimension: 1024 },
251
- testDeps,
252
- ),
253
- ).rejects.toThrow(/vector dimension/i);
254
- expect(testDeps.createdMigrations).toHaveLength(0);
255
- });
256
-
257
- it("rejects duplicate active migrations before creating another row", async () => {
258
- const testDeps = deps({
259
- activeMigration: migration({ id: "migration-active", status: "running" }),
260
- });
261
-
262
- await expect(
263
- requestCompanyBrainProductionMigration(
264
- { tenantId: "tenant-1" },
265
- testDeps,
266
- ),
267
- ).rejects.toThrow(/already active/i);
268
- expect(testDeps.createdMigrations).toHaveLength(0);
269
- expect(testDeps.substratePatches).toHaveLength(0);
270
- });
271
-
272
- it("only allows requests from ready default substrates", async () => {
273
- const testDeps = deps({
274
- substrate: substrate({ status: "migrating" }),
275
- });
276
-
277
- await expect(
278
- requestCompanyBrainProductionMigration(
279
- { tenantId: "tenant-1" },
280
- testDeps,
281
- ),
282
- ).rejects.toThrow(/migrating/i);
283
- expect(testDeps.getActiveMigration).not.toHaveBeenCalled();
284
- expect(testDeps.createdMigrations).toHaveLength(0);
285
- });
286
- });
287
-
288
- describe("updateCompanyBrainMigration", () => {
289
- it("refuses cutover until validation evidence passes", async () => {
290
- const testDeps = deps({
291
- migration: migration({
292
- phase: "validating",
293
- validation_summary: { validationPassed: false, vectorDimension: 1024 },
294
- }),
295
- });
296
-
297
- await expect(
298
- updateCompanyBrainMigration(
299
- {
300
- tenantId: "tenant-1",
301
- migrationId: "migration-1",
302
- phase: "cutover",
303
- },
304
- testDeps,
305
- ),
306
- ).rejects.toThrow(/validationPassed/i);
307
- expect(testDeps.migrationPatches).toHaveLength(0);
308
- expect(testDeps.substratePatches).toHaveLength(0);
309
- });
310
-
311
- it("promotes the active backend to production when validation completes", async () => {
312
- const testDeps = deps({
313
- migration: migration({
314
- phase: "cutover",
315
- validation_summary: { validationPassed: true, vectorDimension: 1024 },
316
- }),
317
- });
318
-
319
- const result = await updateCompanyBrainMigration(
320
- {
321
- tenantId: "tenant-1",
322
- migrationId: "migration-1",
323
- phase: "completed",
324
- status: "completed",
325
- validationSummary: { validationPassed: true, vectorDimension: 1024 },
326
- },
327
- testDeps,
328
- );
329
-
330
- expect(result).toMatchObject({
331
- phase: "completed",
332
- status: "completed",
333
- completed_at: now,
334
- });
335
- expect(testDeps.substratePatches.at(-1)).toMatchObject({
336
- storage_tier: "production",
337
- active_backend: "production",
338
- status: "ready",
339
- health_status: "healthy",
340
- operator_evidence: {
341
- smoke: "pass",
342
- latestMigrationId: "migration-1",
343
- activeMigrationCompletedAt: now.toISOString(),
344
- },
345
- });
346
- expect(testDeps.events.at(-1)).toMatchObject({
347
- event_type: "brain.migration.completed",
348
- payload: expect.objectContaining({
349
- phase: "completed",
350
- status: "completed",
351
- }),
352
- });
353
- });
354
-
355
- it("keeps the default backend active when a migration rolls back", async () => {
356
- const testDeps = deps({
357
- migration: migration({
358
- phase: "failed",
359
- status: "failed",
360
- validation_summary: { validationPassed: true, vectorDimension: 1024 },
361
- }),
362
- });
363
-
364
- await updateCompanyBrainMigration(
365
- {
366
- tenantId: "tenant-1",
367
- migrationId: "migration-1",
368
- phase: "rolled_back",
369
- status: "rolled_back",
370
- },
371
- testDeps,
372
- );
373
-
374
- expect(testDeps.substratePatches.at(-1)).toMatchObject({
375
- storage_tier: "default",
376
- active_backend: "default",
377
- status: "ready",
378
- health_status: "healthy",
379
- });
380
- });
381
-
382
- it("rejects skipped phase transitions before cutover", async () => {
383
- const testDeps = deps({
384
- migration: migration({
385
- phase: "requested",
386
- status: "requested",
387
- validation_summary: { validationPassed: true, vectorDimension: 1024 },
388
- }),
389
- });
390
-
391
- await expect(
392
- updateCompanyBrainMigration(
393
- {
394
- tenantId: "tenant-1",
395
- migrationId: "migration-1",
396
- phase: "completed",
397
- status: "completed",
398
- validationSummary: { validationPassed: true, vectorDimension: 1024 },
399
- },
400
- testDeps,
401
- ),
402
- ).rejects.toThrow(/phase transition/i);
403
- expect(testDeps.migrationPatches).toHaveLength(0);
404
- expect(testDeps.substratePatches).toHaveLength(0);
405
- });
406
-
407
- it("rejects terminal statuses that do not match the requested phase", async () => {
408
- const testDeps = deps({
409
- migration: migration({
410
- phase: "validating",
411
- validation_summary: { validationPassed: true, vectorDimension: 1024 },
412
- }),
413
- });
414
-
415
- await expect(
416
- updateCompanyBrainMigration(
417
- {
418
- tenantId: "tenant-1",
419
- migrationId: "migration-1",
420
- phase: "validating",
421
- status: "completed",
422
- },
423
- testDeps,
424
- ),
425
- ).rejects.toThrow(/status does not match phase/i);
426
- expect(testDeps.migrationPatches).toHaveLength(0);
427
- expect(testDeps.substratePatches).toHaveLength(0);
428
- });
429
-
430
- it("redacts raw validation details from the public summary", async () => {
431
- const testDeps = deps({
432
- migration: migration({
433
- phase: "replaying",
434
- validation_summary: {
435
- sourceCount: 1,
436
- rawSourceIds: ["thread-secret"],
437
- },
438
- }),
439
- });
440
-
441
- const result = await updateCompanyBrainMigration(
442
- {
443
- tenantId: "tenant-1",
444
- migrationId: "migration-1",
445
- phase: "validating",
446
- validationSummary: {
447
- validationPassed: false,
448
- vectorDimension: 1024,
449
- rawS3Uri: "s3://private-bucket/key",
450
- },
451
- },
452
- testDeps,
453
- );
454
-
455
- expect(result.validation_summary).toEqual({
456
- sourceCount: 1,
457
- vectorDimension: 1024,
458
- validationPassed: false,
459
- });
460
- expect(JSON.stringify(result.validation_summary)).not.toContain("s3://");
461
- expect(JSON.stringify(result.validation_summary)).not.toContain(
462
- "thread-secret",
463
- );
464
- });
465
- });
@@ -1,95 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
-
3
- import {
4
- validatePluginManifest,
5
- type InfrastructureComponent,
6
- type McpServerComponent,
7
- } from "@thinkwork/plugin-catalog/contracts";
8
-
9
- import { companyBrainManifest } from "../src/manifest";
10
-
11
- const latestVersion =
12
- companyBrainManifest.versions[companyBrainManifest.versions.length - 1]!;
13
-
14
- describe("ThinkWork Brain plugin manifest", () => {
15
- it("validates as a premium infrastructure plus MCP plugin", () => {
16
- const validated = validatePluginManifest(companyBrainManifest);
17
- expect(validated.pluginKey).toBe("company-brain");
18
- expect(validated.displayName).toBe("ThinkWork Brain");
19
- expect(validated.premium).toEqual({
20
- entitlementProductKey: "company-brain",
21
- installKeyRequired: true,
22
- installKeyPrompt:
23
- "Enter the ThinkWork Brain install key provided by ThinkWork to unlock this premium plugin for your tenant.",
24
- });
25
- expect(validated.versions.map((version) => version.version)).toEqual([
26
- "0.1.0",
27
- "0.1.1",
28
- ]);
29
- expect(validated.versions[0].components).toHaveLength(1);
30
- expect(latestVersion.requiredOauthScopes).toEqual([]);
31
- expect(latestVersion.components).toHaveLength(2);
32
- expect(latestVersion.components[0].type).toBe("infrastructure");
33
- expect(latestVersion.components[1].type).toBe("mcp-server");
34
- });
35
-
36
- it("declares the internal Cognee-backed Brain substrate component", () => {
37
- const component = latestVersion.components[0] as InfrastructureComponent;
38
- expect(component).toMatchObject({
39
- type: "infrastructure",
40
- key: "brain-substrate",
41
- managedAppKey: "cognee",
42
- });
43
- expect(Object.keys(component.terraformInputs).sort()).toEqual([
44
- "bedrockModelResourceArns",
45
- "dbPasswordSecretArn",
46
- "imageUri",
47
- ]);
48
- expect(component.terraformInputs.bedrockModelResourceArns.type).toBe(
49
- "list(string)",
50
- );
51
- });
52
-
53
- it("declares ThinkWork Brain MCP as a plugin-owned direct agent surface", () => {
54
- const component = latestVersion.components[1] as McpServerComponent;
55
- expect(component).toMatchObject({
56
- type: "mcp-server",
57
- key: "brain",
58
- displayName: "ThinkWork Brain",
59
- endpointFrom: {
60
- managedApp: "cognee",
61
- configKey: "cogneeEndpoint",
62
- path: "/mcp-server/http",
63
- },
64
- auth: { mode: "none" },
65
- });
66
- const toolNotes = component.toolNotes?.join("\n") ?? "";
67
- expect(toolNotes).toMatch(/Brain substrate operations/i);
68
- expect(toolNotes).toMatch(/Hindsight-backed ThinkWork memory APIs/i);
69
- expect(toolNotes).not.toMatch(/user and Space memory provider/i);
70
- });
71
-
72
- it("does not declare Full Brain runtime, skills, or rendered UI surfaces in v1", () => {
73
- const componentTypes = latestVersion.components.map(
74
- (component) => component.type,
75
- );
76
- expect(componentTypes).toEqual(["infrastructure", "mcp-server"]);
77
- expect(latestVersion.requiredOauthScopes).toEqual([]);
78
- });
79
-
80
- it("keeps customer-facing copy on ThinkWork Brain rather than Cognee", () => {
81
- const customerFacingText = [
82
- companyBrainManifest.displayName,
83
- companyBrainManifest.description,
84
- companyBrainManifest.premium?.installKeyPrompt,
85
- ...Object.values(
86
- (latestVersion.components[0] as InfrastructureComponent)
87
- .terraformInputs,
88
- ).map((spec) => spec.description),
89
- ].join("\n");
90
-
91
- expect(customerFacingText).toContain("ThinkWork Brain");
92
- expect(customerFacingText).not.toContain("Company Brain");
93
- expect(customerFacingText).not.toMatch(/\bCognee\b/);
94
- });
95
- });
@@ -1,8 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "rootDir": "."
6
- },
7
- "include": ["./**/*.ts"]
8
- }