@elevasis/core 0.1.0 → 0.2.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 (34) hide show
  1. package/dist/index.js +195 -3
  2. package/dist/organization-model/index.js +195 -3
  3. package/package.json +1 -1
  4. package/src/__tests__/template-foundations-compatibility.test.ts +95 -14
  5. package/src/auth/multi-tenancy/types.ts +2 -1
  6. package/src/execution/engine/__tests__/fixtures/test-agents.ts +4 -4
  7. package/src/execution/engine/index.ts +5 -19
  8. package/src/execution/engine/tools/platform/index.ts +9 -33
  9. package/src/execution/engine/tools/registry.ts +109 -2
  10. package/src/execution/engine/tools/tool-maps.ts +88 -0
  11. package/src/organization-model/README.md +19 -4
  12. package/src/organization-model/__tests__/graph.test.ts +612 -0
  13. package/src/organization-model/__tests__/resolve.test.ts +208 -0
  14. package/src/organization-model/defaults.ts +1 -1
  15. package/src/organization-model/organization-graph.mdx +262 -0
  16. package/src/organization-model/organization-model.mdx +257 -0
  17. package/src/organization-model/resolve.ts +26 -2
  18. package/src/organization-model/schema.ts +203 -1
  19. package/src/platform/constants/versions.ts +1 -1
  20. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +24 -0
  21. package/src/platform/registry/__tests__/resource-registry.test.ts +63 -0
  22. package/src/platform/registry/resource-registry.ts +98 -10
  23. package/src/projects/api-schemas.ts +2 -1
  24. package/src/reference/_generated/contracts.md +1044 -0
  25. package/src/reference/glossary.md +88 -0
  26. package/src/server.ts +2 -3
  27. package/src/execution/engine/tools/platform/resource-invocation/__tests__/edge-cases.test.ts +0 -507
  28. package/src/execution/engine/tools/platform/resource-invocation/__tests__/resource-invocation-service.test.ts +0 -500
  29. package/src/execution/engine/tools/platform/resource-invocation/__tests__/tool.test.ts +0 -555
  30. package/src/execution/engine/tools/platform/resource-invocation/dynamic-tool.ts +0 -94
  31. package/src/execution/engine/tools/platform/resource-invocation/index.ts +0 -14
  32. package/src/execution/engine/tools/platform/resource-invocation/resource-invocation-service.ts +0 -147
  33. package/src/execution/engine/tools/platform/resource-invocation/tool.ts +0 -115
  34. package/src/execution/engine/tools/platform/resource-invocation/types.ts +0 -31
@@ -1,25 +1,20 @@
1
1
  /**
2
2
  * Platform Tools
3
- * Factory functions for creating tools that interact with internal platform services
3
+ * Factory functions for creating tools that interact with internal platform services.
4
+ * Retained compatibility surface; deployed SDK workers use platform.call() -> dispatcher.
4
5
  *
5
6
  * Platform tools enable agents to:
6
- * - Request human approval (command queue)
7
- * - Schedule future execution (task scheduler)
8
- * - Send platform notifications (notifications service)
9
7
  * - Invoke other resources - agents and workflows (resource invocation)
8
+ * - Send platform emails
9
+ * - Manage acquisition data
10
+ * - Store files
11
+ * - Render PDFs
12
+ * - Manage schedules
10
13
  *
11
- * Usage:
12
- * import { createApprovalTool, createSchedulerTool, createNotificationTool } from '@repo/core/execution-engine/tools/platform'
14
+ * Resource invocation service and supporting types remain exported here for internal wiring.
13
15
  */
14
16
 
15
- export { createApprovalTool } from './approval'
16
- export { createSchedulerTool } from './scheduler'
17
- export { createNotificationTool } from './notification'
18
-
19
17
  export type {
20
- ApprovalToolConfig,
21
- SchedulerToolConfig,
22
- NotificationToolConfig,
23
18
  ICommandQueueService,
24
19
  ITaskSchedulerService,
25
20
  INotificationsService
@@ -32,23 +27,6 @@ export type { SendPlatformEmailInput, SendPlatformEmailOutput, PlatformEmailTool
32
27
 
33
28
  export { SendPlatformEmailInputSchema, SendPlatformEmailOutputSchema } from './email'
34
29
 
35
- // Resource Invocation (service, types, and tool factories - Wave 2a complete)
36
- export {
37
- ResourceInvocationService,
38
- createResourceInvocationService,
39
- createResourceInvocationTool,
40
- createDynamicResourceInvocationTool,
41
- dynamicResourceInvocationSchema,
42
- dynamicResourceInvocationOutputSchema
43
- } from './resource-invocation'
44
-
45
- export type {
46
- ResourceExecutionRequest,
47
- ResourceInvocationResult,
48
- ResourceInvocationToolConfig,
49
- ResourceDefinition
50
- } from './resource-invocation'
51
-
52
30
  // Acquisition Tools (Lead Database management)
53
31
  export {
54
32
  // List tools
@@ -173,9 +151,7 @@ export {
173
151
  DeleteScheduleByKeyOutputSchema
174
152
  } from './schedules'
175
153
 
176
- // HITL Cancel by Metadata Tool
177
- export { createHitlCancelByMetadataTool } from './approval'
178
-
154
+ // HITL Cancel by Metadata types and schemas
179
155
  export type { HitlCancelByMetadataInput, HitlCancelByMetadataOutput } from './approval'
180
156
 
181
157
  export { HitlCancelByMetadataInputSchema, HitlCancelByMetadataOutputSchema } from './approval'
@@ -12,9 +12,24 @@
12
12
  import type { CreateTaskParams, Task } from '../../../commands/queue/types'
13
13
  import type { CreateScheduleInput, TaskSchedule } from '../../scheduler/types'
14
14
  import type { CreateNotificationParams, Notification } from '../../../operations/notifications/types'
15
- import type { ResourceInvocationService } from './platform/resource-invocation'
16
15
  import type { ILeadService } from './lead-service-types'
17
16
  import type { ExecutionContext } from '../base/types'
17
+ import type {
18
+ ProjectRow,
19
+ ProjectWithCounts,
20
+ ProjectDetail,
21
+ MilestoneRow,
22
+ TaskRow,
23
+ NoteRow
24
+ } from '../../../business/delivery'
25
+ import type {
26
+ DealListItem,
27
+ DealDetail,
28
+ DealStage,
29
+ ListDealsQuery
30
+ } from '../../../business/acquisition'
31
+ import type { RecentActivityEntry } from '../../../business/crm/api-schemas'
32
+ import type { Database } from '../../../supabase/database.types'
18
33
 
19
34
  /**
20
35
  * Service interfaces for platform tools
@@ -127,6 +142,93 @@ export interface INotificationsService {
127
142
  create(params: CreateNotificationParams): Promise<Notification>
128
143
  }
129
144
 
145
+ export interface ICrmService {
146
+ getRecentActivity(organizationId: string, limit: number): Promise<RecentActivityEntry[]>
147
+ listDeals(organizationId: string, filters?: Partial<ListDealsQuery>): Promise<DealListItem[]>
148
+ getDeal(dealId: string, organizationId: string): Promise<DealDetail | null>
149
+ getDealByEmail(email: string, organizationId: string): Promise<DealDetail | null>
150
+ updateDealStage(dealId: string, organizationId: string, stage: DealStage): Promise<void>
151
+ createDealNote(params: import('./lead-service-types').CreateDealNoteParams): Promise<import('./lead-service-types').AcqDealNote>
152
+ listDealNotes(params: import('./lead-service-types').ListDealNotesParams): Promise<import('./lead-service-types').AcqDealNote[]>
153
+ createDealTask(params: import('./lead-service-types').CreateDealTaskParams): Promise<import('./lead-service-types').AcqDealTask>
154
+ listDealTasks(params: import('./lead-service-types').ListDealTasksParams): Promise<import('./lead-service-types').AcqDealTask[]>
155
+ listDealTasksDue(params: import('./lead-service-types').ListDealTasksDueParams): Promise<import('./lead-service-types').AcqDealTask[]>
156
+ completeDealTask(params: import('./lead-service-types').CompleteDealTaskParams): Promise<import('./lead-service-types').AcqDealTask>
157
+ recordActivity(params: import('./lead-service-types').RecordDealActivityParams): Promise<void>
158
+ deleteDeal(params: import('./lead-service-types').DeleteDealParams): Promise<void>
159
+ }
160
+
161
+ type ProjectInsert = Database['public']['Tables']['prj_projects']['Insert']
162
+ type ProjectUpdate = Database['public']['Tables']['prj_projects']['Update']
163
+ type MilestoneInsert = Database['public']['Tables']['prj_milestones']['Insert']
164
+ type MilestoneUpdate = Database['public']['Tables']['prj_milestones']['Update']
165
+ type TaskInsert = Database['public']['Tables']['prj_tasks']['Insert']
166
+ type TaskUpdate = Database['public']['Tables']['prj_tasks']['Update']
167
+ type NoteInsert = Database['public']['Tables']['prj_notes']['Insert']
168
+ type NoteUpdate = Database['public']['Tables']['prj_notes']['Update']
169
+ type TaskResumeContextRow = Pick<TaskRow, 'id' | 'resume_context' | 'updated_at'>
170
+
171
+ export interface IProjectsService {
172
+ listProjects(
173
+ organizationId: string,
174
+ filters?: {
175
+ kind?: string
176
+ status?: string
177
+ }
178
+ ): Promise<ProjectWithCounts[]>
179
+ getProject(id: string, organizationId: string): Promise<ProjectDetail | null>
180
+ createProject(input: Omit<ProjectInsert, 'organization_id'> & { organizationId: string }): Promise<ProjectRow>
181
+ updateProject(
182
+ id: string,
183
+ organizationId: string,
184
+ input: Omit<ProjectUpdate, 'organization_id'>
185
+ ): Promise<ProjectRow | null>
186
+ deleteProject(id: string, organizationId: string): Promise<boolean>
187
+ listMilestones(projectId: string, organizationId: string): Promise<MilestoneRow[]>
188
+ createMilestone(
189
+ input: Omit<MilestoneInsert, 'organization_id' | 'project_id'> & {
190
+ organizationId: string
191
+ projectId: string
192
+ }
193
+ ): Promise<MilestoneRow>
194
+ updateMilestone(
195
+ id: string,
196
+ organizationId: string,
197
+ input: Omit<MilestoneUpdate, 'organization_id'>
198
+ ): Promise<MilestoneRow | null>
199
+ deleteMilestone(id: string, organizationId: string): Promise<boolean>
200
+ listTasks(
201
+ projectId: string,
202
+ organizationId: string,
203
+ filters?: {
204
+ status?: string
205
+ milestone_id?: string
206
+ parent_task_id?: string
207
+ }
208
+ ): Promise<TaskRow[]>
209
+ getTask(id: string, organizationId: string): Promise<TaskRow | null>
210
+ createTask(input: Omit<TaskInsert, 'organization_id'> & { organizationId: string }): Promise<TaskRow>
211
+ updateTask(
212
+ id: string,
213
+ organizationId: string,
214
+ input: Omit<TaskUpdate, 'organization_id'>
215
+ ): Promise<TaskRow | null>
216
+ deleteTask(id: string, organizationId: string): Promise<boolean>
217
+ mergeTaskResumeContext(
218
+ id: string,
219
+ organizationId: string,
220
+ incoming: Record<string, unknown>
221
+ ): Promise<TaskResumeContextRow | null>
222
+ listNotes(projectId: string, organizationId: string): Promise<NoteRow[]>
223
+ createNote(input: Omit<NoteInsert, 'organization_id'> & { organizationId: string }): Promise<NoteRow>
224
+ updateNote(
225
+ id: string,
226
+ organizationId: string,
227
+ input: Omit<NoteUpdate, 'organization_id'>
228
+ ): Promise<NoteRow | null>
229
+ deleteNote(id: string, organizationId: string): Promise<boolean>
230
+ }
231
+
130
232
  // =============================================================================
131
233
  // Platform Email Service Types
132
234
  // =============================================================================
@@ -501,10 +603,11 @@ export interface ToolServices {
501
603
  commandQueueService: ICommandQueueService | null
502
604
  taskSchedulerService: ITaskSchedulerService | null
503
605
  notificationsService: INotificationsService | null
606
+ projectsService?: IProjectsService | null
607
+ crmService?: ICrmService | null
504
608
  emailService: IEmailService | null
505
609
  credentialsService: ICredentialsService | null
506
610
  integrationService: IIntegrationService | null
507
- resourceInvocationService?: ResourceInvocationService
508
611
  leadService: ILeadService | null
509
612
  storageService: IStorageService | null
510
613
  /** PDF rendering service - optional for gradual adoption */
@@ -520,6 +623,8 @@ class ToolServicesRegistry {
520
623
  commandQueueService: null,
521
624
  taskSchedulerService: null,
522
625
  notificationsService: null,
626
+ projectsService: null,
627
+ crmService: null,
523
628
  emailService: null,
524
629
  credentialsService: null,
525
630
  integrationService: null,
@@ -562,6 +667,8 @@ class ToolServicesRegistry {
562
667
  commandQueueService: null,
563
668
  taskSchedulerService: null,
564
669
  notificationsService: null,
670
+ projectsService: null,
671
+ crmService: null,
565
672
  emailService: null,
566
673
  credentialsService: null,
567
674
  integrationService: null,
@@ -260,6 +260,21 @@ import type {
260
260
  GetCompanyByIdParams
261
261
  } from './lead-service-types'
262
262
 
263
+ import type { DealListItem, DealDetail } from '../../../business/acquisition'
264
+ import { CrmSchemas } from '../../../business/crm/api-schemas'
265
+ import type { RecentActivityEntry } from '../../../business/crm/api-schemas'
266
+ import { DealSchemas } from '../../../business/acquisition'
267
+ import { ProjectSchemas } from '../../../projects/api-schemas'
268
+ import type {
269
+ ProjectRow,
270
+ MilestoneRow,
271
+ TaskRow,
272
+ NoteRow,
273
+ ProjectWithCounts,
274
+ ProjectDetail
275
+ } from '../../../business/delivery'
276
+ import type { z } from 'zod'
277
+
263
278
  // ---------------------------------------------------------------------------
264
279
  // Generic constraint types
265
280
  // ---------------------------------------------------------------------------
@@ -335,6 +350,79 @@ export type NotificationToolMap = {
335
350
  create: { params: NotificationSDKInput; result: void }
336
351
  }
337
352
 
353
+ // ---------------------------------------------------------------------------
354
+ // Projects (platform tool, 18 methods)
355
+ // ---------------------------------------------------------------------------
356
+
357
+ type ProjectsListParams = z.infer<typeof ProjectSchemas.GetProjectsQuery>
358
+ type ProjectCreateParams = z.infer<typeof ProjectSchemas.CreateProjectRequest>
359
+ type ProjectUpdateParams = z.infer<typeof ProjectSchemas.UpdateProjectRequest>
360
+ type MilestoneCreateParams =
361
+ z.infer<typeof ProjectSchemas.ProjectIdPathParams> & z.infer<typeof ProjectSchemas.CreateMilestoneRequest>
362
+ type MilestoneUpdateParams = z.infer<typeof ProjectSchemas.UpdateMilestoneRequest>
363
+ type TaskListParams = z.infer<typeof ProjectSchemas.ProjectIdPathParams> & z.infer<typeof ProjectSchemas.GetTasksQuery>
364
+ type TaskCreateParams = z.infer<typeof ProjectSchemas.CreateTaskRequest>
365
+ type TaskUpdateParams = z.infer<typeof ProjectSchemas.UpdateTaskRequest>
366
+ type TaskResumeContextParams =
367
+ z.infer<typeof ProjectSchemas.TaskIdParams> & z.infer<typeof ProjectSchemas.MergeResumeContextRequest>
368
+ type NoteListParams = z.infer<typeof ProjectSchemas.ProjectIdPathParams>
369
+ type NoteCreateParams = z.infer<typeof ProjectSchemas.CreateNoteRequest>
370
+ type NoteUpdateParams = z.infer<typeof ProjectSchemas.UpdateNoteRequest>
371
+ type TaskResumeContextResult = Pick<TaskRow, 'id' | 'resume_context' | 'updated_at'>
372
+
373
+ export type ProjectsToolMap = {
374
+ listProjects: { params: ProjectsListParams; result: ProjectWithCounts[] }
375
+ getProject: { params: z.infer<typeof ProjectSchemas.ProjectIdParams>; result: ProjectDetail }
376
+ createProject: { params: ProjectCreateParams; result: ProjectRow }
377
+ updateProject: { params: z.infer<typeof ProjectSchemas.ProjectIdParams> & ProjectUpdateParams; result: ProjectRow }
378
+ deleteProject: { params: z.infer<typeof ProjectSchemas.ProjectIdParams>; result: void }
379
+ listMilestones: { params: z.infer<typeof ProjectSchemas.ProjectIdPathParams>; result: MilestoneRow[] }
380
+ createMilestone: { params: MilestoneCreateParams; result: MilestoneRow }
381
+ updateMilestone: { params: z.infer<typeof ProjectSchemas.MilestoneIdParams> & MilestoneUpdateParams; result: MilestoneRow }
382
+ deleteMilestone: { params: z.infer<typeof ProjectSchemas.MilestoneIdParams>; result: void }
383
+ listTasks: { params: TaskListParams; result: TaskRow[] }
384
+ getTask: { params: z.infer<typeof ProjectSchemas.TaskIdParams>; result: TaskRow }
385
+ createTask: { params: TaskCreateParams; result: TaskRow }
386
+ updateTask: { params: z.infer<typeof ProjectSchemas.TaskIdParams> & TaskUpdateParams; result: TaskRow }
387
+ deleteTask: { params: z.infer<typeof ProjectSchemas.TaskIdParams>; result: void }
388
+ mergeTaskResumeContext: { params: TaskResumeContextParams; result: TaskResumeContextResult }
389
+ listNotes: { params: NoteListParams; result: NoteRow[] }
390
+ createNote: { params: NoteCreateParams; result: NoteRow }
391
+ updateNote: { params: z.infer<typeof ProjectSchemas.NoteIdParams> & NoteUpdateParams; result: NoteRow }
392
+ deleteNote: { params: z.infer<typeof ProjectSchemas.NoteIdParams>; result: void }
393
+ }
394
+
395
+ // ---------------------------------------------------------------------------
396
+ // CRM (platform tool, 13 methods)
397
+ // ---------------------------------------------------------------------------
398
+
399
+ type CrmRecentActivityParams = Partial<z.infer<typeof CrmSchemas.GetRecentActivityQuery>>
400
+ type CrmListDealsParams = Partial<z.infer<typeof DealSchemas.ListDealsQuery>>
401
+ type CrmGetDealParams = z.infer<typeof DealSchemas.DealIdParams>
402
+ type CrmUpdateDealStageParams = z.infer<typeof DealSchemas.DealIdParams> & z.infer<typeof DealSchemas.SyncDealStageRequest>
403
+ type CrmGetDealByEmailParams = { email: string }
404
+ type CrmTaskDueParams = Partial<z.infer<typeof DealSchemas.ListDealTasksDueQuery>>
405
+ type CrmDealTaskParams = Omit<CreateDealTaskParams, 'organizationId'>
406
+ type CrmDealNoteParams = Omit<CreateDealNoteParams, 'organizationId'>
407
+ type CrmRecordActivityParams = Omit<RecordDealActivityParams, 'organizationId'>
408
+ type CrmDeleteDealParams = Omit<DeleteDealParams, 'organizationId'>
409
+
410
+ export type CrmToolMap = {
411
+ getRecentActivity: { params: CrmRecentActivityParams; result: RecentActivityEntry[] }
412
+ listDeals: { params: CrmListDealsParams; result: DealListItem[] }
413
+ getDeal: { params: CrmGetDealParams; result: DealDetail | null }
414
+ getDealByEmail: { params: CrmGetDealByEmailParams; result: DealDetail | null }
415
+ updateDealStage: { params: CrmUpdateDealStageParams; result: void }
416
+ createDealNote: { params: CrmDealNoteParams; result: AcqDealNote }
417
+ listDealNotes: { params: Omit<ListDealNotesParams, 'organizationId'>; result: AcqDealNote[] }
418
+ createDealTask: { params: CrmDealTaskParams; result: AcqDealTask }
419
+ listDealTasks: { params: Omit<ListDealTasksParams, 'organizationId'>; result: AcqDealTask[] }
420
+ listDealTasksDue: { params: CrmTaskDueParams; result: AcqDealTask[] }
421
+ completeDealTask: { params: Omit<CompleteDealTaskParams, 'organizationId'>; result: AcqDealTask }
422
+ recordActivity: { params: CrmRecordActivityParams; result: void }
423
+ deleteDeal: { params: CrmDeleteDealParams; result: void }
424
+ }
425
+
338
426
  // ---------------------------------------------------------------------------
339
427
  // Stripe (integration adapter, 6 methods)
340
428
  // ---------------------------------------------------------------------------
@@ -33,7 +33,7 @@ Top-level fields:
33
33
 
34
34
  - `domains` - semantic domain entries that bind entity IDs, surface IDs, resource IDs, and capability IDs.
35
35
  - `branding` - organization branding defaults and overrides.
36
- - `features` - feature flags and labels for the shell.
36
+ - `features` - grouped shell-level feature flags and labels.
37
37
  - `navigation` - navigation model for the product shell.
38
38
  - `crm` - CRM-specific contract data.
39
39
  - `leadGen` - lead generation contract data.
@@ -51,29 +51,44 @@ The default model includes four semantic domains:
51
51
 
52
52
  ## Feature Keys
53
53
 
54
- The current feature keys are:
54
+ The current canonical feature keys are grouped shell features:
55
55
 
56
56
  - `acquisition`
57
57
  - `delivery`
58
58
  - `operations`
59
59
  - `monitoring`
60
60
  - `settings`
61
- - `seo`
62
61
  - `calibration`
62
+ - `seo`
63
63
 
64
64
  Each feature can carry an enabled flag and an optional label override.
65
65
 
66
+ This is intentionally different from the domain and surface vocabulary:
67
+
68
+ - domains and surface IDs still use IDs such as `crm`, `lead-gen`, and `projects.index`
69
+ - navigation surfaces point those routes at grouped `featureKey` values such as `acquisition` and `delivery`
70
+ - downstream apps may still carry compatibility aliases for legacy route-level keys, but the published organization-model contract does not
71
+
66
72
  ## Resolution Semantics
67
73
 
68
74
  - `defineOrganizationModel()` is a typed helper. It does not validate or merge anything by itself.
69
75
  - `resolveOrganizationModel()` deep-merges a partial override into the default model, then validates the result with `OrganizationModelSchema`.
70
76
  - Plain objects merge recursively.
71
77
  - Arrays replace the default value instead of merging element-by-element.
78
+ - If `navigation.surfaces` is replaced without also supplying `navigation.groups`, inherited default groups are dropped when they no longer point at declared surfaces.
72
79
  - Missing fields fall back to `DEFAULT_ORGANIZATION_MODEL`.
73
80
 
81
+ ## Referential Integrity
82
+
83
+ - `navigation.defaultSurfaceId` must point at a declared navigation surface.
84
+ - Every navigation group `surfaceId` must resolve to a declared surface.
85
+ - Domain, surface, and resource-mapping IDs must resolve to declared counterparts; dangling references fail validation.
86
+ - Domain-to-surface and domain/surface-to-resource links are validated in both directions so one-sided declarations fail during resolution.
87
+ - Feature-bearing surfaces validate `featureKey` against the canonical grouped feature set.
88
+
74
89
  ## Practical Guidance
75
90
 
76
91
  - Use `resolveOrganizationModel()` when you need a runtime-safe model for rendering or policy checks.
77
92
  - Use `defineOrganizationModel()` when authoring a static partial model in source.
93
+ - Treat `features.enabled` and `features.labels` as the shell-level contract; do not use `crm`, `lead-gen`, or `projects` as canonical feature keys in new organization-model authoring.
78
94
  - Keep domain IDs, surface IDs, and capability IDs stable because downstream UI and policy code depend on them.
79
-