@elevasis/sdk 1.10.0 → 1.12.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 (40) hide show
  1. package/dist/cli.cjs +52 -149
  2. package/dist/index.d.ts +468 -198
  3. package/dist/index.js +225 -147
  4. package/dist/test-utils/index.d.ts +272 -99
  5. package/dist/test-utils/index.js +4756 -125
  6. package/dist/types/worker/adapters/llm.d.ts +1 -1
  7. package/dist/worker/index.js +14 -6
  8. package/package.json +2 -2
  9. package/reference/claude-config/rules/agent-start-here.md +14 -14
  10. package/reference/claude-config/skills/configure/SKILL.md +3 -3
  11. package/reference/claude-config/skills/setup/SKILL.md +6 -6
  12. package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +55 -0
  13. package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +101 -0
  14. package/reference/cli.mdx +57 -0
  15. package/reference/deployment/provided-features.mdx +40 -267
  16. package/reference/examples/organization-model.ts +99 -564
  17. package/reference/packages/core/src/organization-model/README.md +102 -97
  18. package/reference/resources/types.mdx +72 -163
  19. package/reference/scaffold/core/organization-graph.mdx +92 -272
  20. package/reference/scaffold/core/organization-model.mdx +155 -320
  21. package/reference/scaffold/index.mdx +3 -0
  22. package/reference/scaffold/operations/propagation-pipeline.md +4 -1
  23. package/reference/scaffold/operations/scaffold-maintenance.md +3 -0
  24. package/reference/scaffold/operations/workflow-recipes.md +13 -10
  25. package/reference/scaffold/recipes/add-a-feature.md +105 -158
  26. package/reference/scaffold/recipes/add-a-resource.md +88 -158
  27. package/reference/scaffold/recipes/customize-organization-model.md +144 -400
  28. package/reference/scaffold/recipes/extend-a-base-entity.md +11 -8
  29. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +117 -158
  30. package/reference/scaffold/recipes/index.md +3 -0
  31. package/reference/scaffold/reference/contracts.md +107 -435
  32. package/reference/scaffold/reference/feature-registry.md +11 -8
  33. package/reference/scaffold/reference/glossary.md +74 -105
  34. package/reference/scaffold/ui/composition-extensibility.mdx +3 -0
  35. package/reference/scaffold/ui/customization.md +3 -0
  36. package/reference/scaffold/ui/feature-flags-and-gating.md +29 -231
  37. package/reference/scaffold/ui/feature-shell.mdx +53 -219
  38. package/reference/scaffold/ui/recipes.md +65 -397
  39. package/reference/claude-config/logs/pre-edit-vibe-gate.log +0 -40
  40. package/reference/claude-config/logs/scaffold-registry-reminder.log +0 -38
@@ -4,7 +4,7 @@
4
4
  * Typed wrapper over platform.call() for LLM generation.
5
5
  * Singleton export -- no credential needed (platform tool).
6
6
  *
7
- * Types are shared with the server-side LLM engine via @repo/core/execution.
7
+ * Types are shared with the server-side LLM engine and inlined for SDK consumers.
8
8
  */
9
9
  import type { LLMGenerateRequest, LLMGenerateResponse, LLMModel } from '../../types/index.js';
10
10
  type LLMProvider = 'openai' | 'anthropic' | 'openrouter' | 'google';
@@ -1,4 +1,4 @@
1
- import { parentPort } from 'worker_threads';
1
+ import { workerData, parentPort } from 'worker_threads';
2
2
  import { z, ZodError } from 'zod';
3
3
 
4
4
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
@@ -4986,14 +4986,14 @@ var acqDb = createAdapter("acqDb", [
4986
4986
  "getDealById",
4987
4987
  "getContactById",
4988
4988
  "getCompanyById",
4989
- // Deal-sync operations
4989
+ // Deal transitions
4990
4990
  "updateDiscoveryData",
4991
4991
  "updateProposalData",
4992
4992
  "markProposalSent",
4993
4993
  "markProposalReviewed",
4994
4994
  "updateCloseLostReason",
4995
4995
  "updateFees",
4996
- "syncDealStage",
4996
+ "transitionItem",
4997
4997
  "setContactNurture",
4998
4998
  "cancelSchedulesAndHitlByEmail",
4999
4999
  "cancelHitlByDealId",
@@ -5043,7 +5043,6 @@ var crm = createAdapter("crm", [
5043
5043
  "listDeals",
5044
5044
  "getDeal",
5045
5045
  "getDealByEmail",
5046
- "updateDealStage",
5047
5046
  "createDealNote",
5048
5047
  "listDealNotes",
5049
5048
  "createDealTask",
@@ -5290,7 +5289,8 @@ function startWorker(org) {
5290
5289
  status: w.config.status,
5291
5290
  description: w.config.description,
5292
5291
  version: w.config.version,
5293
- domains: w.config.domains,
5292
+ links: w.config.links,
5293
+ category: w.config.category,
5294
5294
  contract: {
5295
5295
  inputSchema: safeZodToJsonSchema(w.contract?.inputSchema),
5296
5296
  outputSchema: safeZodToJsonSchema(w.contract?.outputSchema)
@@ -5312,7 +5312,8 @@ function startWorker(org) {
5312
5312
  status: a.config.status,
5313
5313
  description: a.config.description,
5314
5314
  version: a.config.version,
5315
- domains: a.config.domains,
5315
+ links: a.config.links,
5316
+ category: a.config.category,
5316
5317
  contract: {
5317
5318
  inputSchema: safeZodToJsonSchema(a.contract?.inputSchema),
5318
5319
  outputSchema: safeZodToJsonSchema(a.contract?.outputSchema)
@@ -5434,5 +5435,12 @@ function startWorker(org) {
5434
5435
  }
5435
5436
  });
5436
5437
  }
5438
+ if (workerData != null && workerData.kind === "static") {
5439
+ const { modulePath } = workerData;
5440
+ void (async () => {
5441
+ const mod = await import(modulePath);
5442
+ startWorker(mod.default);
5443
+ })();
5444
+ }
5437
5445
 
5438
5446
  export { PlatformToolError, acqDb, approval, createAdapter, createAnymailfinderAdapter, createApifyAdapter, createAttioAdapter, createDropboxAdapter, createGmailAdapter, createGoogleSheetsAdapter, createInstantlyAdapter, createMillionVerifierAdapter, createResendAdapter, createSignatureApiAdapter, createStripeAdapter, createTombaAdapter, crm, email, executeWorkflow, execution, list, llm, notifications, pdf, platform, projects, scheduler, startWorker, storage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "1.10.0",
3
+ "version": "1.12.0",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -50,7 +50,7 @@
50
50
  "tsup": "^8.0.0",
51
51
  "typescript": "5.9.2",
52
52
  "zod": "^4.1.0",
53
- "@repo/core": "0.10.0",
53
+ "@repo/core": "0.13.0",
54
54
  "@repo/typescript-config": "0.0.0"
55
55
  },
56
56
  "scripts": {
@@ -47,7 +47,7 @@ Once project continuity is resolved (or confirmed irrelevant), the template is n
47
47
 
48
48
  - `ui/` -- React frontend app and shell composition
49
49
  - `operations/` -- Elevasis SDK resources deployed to the platform
50
- - `foundations/` -- runtime-agnostic shared contracts and organization model adaptation
50
+ - `core/` -- runtime-agnostic shared contracts and organization model adaptation
51
51
  - `.claude/` -- local agent rules, skills, and hooks
52
52
  - `client-workspace/` -- optional separate knowledge workspace for richer team knowledge management
53
53
  - `node_modules/@elevasis/sdk/reference/scaffold/` -- SDK reference scaffold: canonical recipes, UI patterns, gating model, contracts, and glossary. Entry point: `index.mdx`.
@@ -59,7 +59,7 @@ Use this order unless a more specific doc tells you otherwise:
59
59
  1. Complete the "First Action: Check Active Projects" flow above.
60
60
  2. Read `CLAUDE.md` for project rules, command surface, and navigation pointers.
61
61
  3. Read this rule and classify the task using the Task Classes below.
62
- 4. Read `identity.clientBrief` from the OrganizationModel (`operations/foundations/config/organization-model.ts`) for organization context and naming.
62
+ 4. Read `identity.clientBrief` from the OrganizationModel (`core/config/organization-model.ts`) for organization context and naming.
63
63
  5. Read the relevant structural map:
64
64
  - Glob `node_modules/@elevasis/sdk/reference/` for published package surfaces
65
65
  - Glob `operations/resources/**` for source, or run `pnpm elevasis-sdk project:list --pretty` for live DB state
@@ -90,7 +90,7 @@ Load first:
90
90
  - `node_modules/@elevasis/sdk/reference/scaffold/index.mdx` (scaffold index -- UI recipes, feature flags, customization)
91
91
  - `.claude/rules/ui.md`
92
92
  - `ui/src/routes/README.md`
93
- - `foundations/config/README.md`
93
+ - `core/config/README.md`
94
94
  - `node_modules/@elevasis/sdk/reference/scaffold/ui/recipes.md` -- specifically recipe 6 when building a "run this resource" surface
95
95
 
96
96
  Then inspect:
@@ -99,7 +99,7 @@ Then inspect:
99
99
  - `ui/src/config/*`
100
100
  - relevant `ui/src/routes/*`
101
101
  - relevant `ui/src/features/*`
102
- - `foundations/config/organization-model.ts`
102
+ - `core/config/organization-model.ts`
103
103
 
104
104
  Verify with:
105
105
 
@@ -120,8 +120,8 @@ Then inspect:
120
120
 
121
121
  - `operations/src/index.ts`
122
122
  - relevant `operations/src/<feature>/*`
123
- - `foundations/types/index.ts` -- workflow input/output Zod schemas
124
- - `foundations/types/entities.ts` -- typed entity contracts (Project, Deal, etc.) extending `@elevasis/core/entities` base types. Read this when authoring a workflow that takes or returns these entities so the input/output schemas reference the canonical entity shapes rather than redeclaring them.
123
+ - `core/types/index.ts` -- workflow input/output Zod schemas
124
+ - `core/types/entities.ts` -- typed entity contracts (Project, Deal, etc.) extending `@elevasis/core/entities` base types. Read this when authoring a workflow that takes or returns these entities so the input/output schemas reference the canonical entity shapes rather than redeclaring them.
125
125
  - `operations/elevasis.config.ts`
126
126
 
127
127
  Verify with:
@@ -136,15 +136,15 @@ Examples: rename a feature area, change quick access surfaces, map new business
136
136
  Load first:
137
137
 
138
138
  - `node_modules/@elevasis/sdk/reference/scaffold/index.mdx` (scaffold index -- contracts, gating patterns, glossary)
139
- - `foundations/config/README.md`
139
+ - `core/config/README.md`
140
140
  - `node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`
141
141
  - typed feature/surface constants from `@elevasis/core/organization-model` -- `CRM_FEATURE_ID`, `LEAD_GEN_FEATURE_ID`, `PROJECTS_FEATURE_ID`, `OPERATIONS_FEATURE_ID`, `MONITORING_FEATURE_ID`, `SETTINGS_FEATURE_ID`, `SEO_FEATURE_ID`, `CRM_PIPELINE_SURFACE_ID`, `LEAD_GEN_LISTS_SURFACE_ID`, `PROJECTS_INDEX_SURFACE_ID`, `OPERATIONS_ORGANIZATION_GRAPH_SURFACE_ID`. Use these typed constants instead of magic strings when overriding feature/surface IDs.
142
142
  - `node_modules/@elevasis/sdk/reference/scaffold/ui/feature-flags-and-gating.md`
143
143
 
144
144
  Then inspect:
145
145
 
146
- - `foundations/config/organization-model.ts`
147
- - `foundations/config/organization-model.examples.ts` -- 5 reference patterns: branding override, CRM pipeline stage customization, lead-gen lifecycle customization, resource mapping registration, custom feature declaration. Not imported anywhere -- pure reference. Start here for the override pattern when extending the org model.
146
+ - `core/config/organization-model.ts`
147
+ - `core/config/organization-model.examples.ts` -- 5 reference patterns: branding override, CRM pipeline stage customization, lead-gen lifecycle customization, resource mapping registration, custom feature declaration. Not imported anywhere -- pure reference. Start here for the override pattern when extending the org model.
148
148
  - `ui/src/routes/__root.tsx`
149
149
  - `ui/src/lib/hooks/useFeatureAccess.ts`
150
150
  - relevant nav config files
@@ -169,7 +169,7 @@ Then inspect:
169
169
  - `operations/src/index.ts`
170
170
  - resource definitions
171
171
  - related UI route and feature files
172
- - related foundations contracts
172
+ - related core contracts
173
173
 
174
174
  Verify with:
175
175
 
@@ -203,7 +203,7 @@ Verify with:
203
203
 
204
204
  Once the request is classified, determine which boundary owns the change:
205
205
 
206
- - **Foundations boundary** -- semantics, aliases, labels, shared schemas
206
+ - **Core boundary** -- semantics, aliases, labels, shared schemas
207
207
  - **UI shell boundary** -- provider composition, manifests, navigation, route ownership
208
208
  - **Operations boundary** -- deployable resource registration, workflow/agent contracts, topology
209
209
  - **Package boundary** -- public exports, shared platform behavior, reusable contracts
@@ -212,7 +212,7 @@ If a task spans boundaries, start at the semantic boundary, then move to runtime
212
212
 
213
213
  ## Main Boundaries
214
214
 
215
- ### `foundations/config/organization-model.ts`
215
+ ### `core/config/organization-model.ts`
216
216
 
217
217
  The semantic adaptation point between platform contracts and scaffold-local terminology. Start here for feature labels, legacy aliases, quick-access surfaces, and shell-facing organization semantics.
218
218
 
@@ -239,13 +239,13 @@ If a hand-authored doc conflicts with source or published package docs, trust so
239
239
  ## Common Traps
240
240
 
241
241
  - Do not assume `operations/resources/**` is exhaustive without also checking `operations/src/index.ts` directly.
242
- - Do not assume placeholder knowledge is sufficient for real client context. Read `identity.clientBrief` from the OrganizationModel (`operations/foundations/config/organization-model.ts`).
242
+ - Do not assume placeholder knowledge is sufficient for real client context. Read `identity.clientBrief` from the OrganizationModel (`core/config/organization-model.ts`).
243
243
  - Do not trust stable docs blindly when `.claude/rules/active-change-index.md` flags related in-progress architecture work.
244
244
  - Do not write `resume_context` into task-doc frontmatter. DB is canonical; write via `project:task:save` or the inline editor in Command Center.
245
245
 
246
246
  ## Operations-Only Projects
247
247
 
248
- Some projects derived from this template are operations-only. They have `operations/` (or a top-level `src/`) but NO `ui/`, NO `foundations/config/organization-model.ts`, and NO frontend. Finding none of these is not missing scaffolding -- it is by design.
248
+ Some projects derived from this template are operations-only. They have `operations/` (or a top-level `src/`) but NO `ui/`, NO `core/config/organization-model.ts`, and NO frontend. Finding none of these is not missing scaffolding -- it is by design.
249
249
 
250
250
  **What applies:** Only Task Classes 2 (Workflow / Agent / Operations Work) and 4 (Debugging / Impact Analysis) apply to operations-only projects. Task Classes 1 (UI / Shell Work), 3 (Organization Model / Feature Access Work), and 5 (Platform Extension / Package Contract Work) do not apply and can be skipped.
251
251
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: configure
3
- description: "Recurring organization model editor — layered QA flow across identity, customers, offerings, roles, goals, and techStack. Idempotent, confirm-before-overwrite. Codifies changes to foundations/config/organization-model.ts with runtime validation gate."
3
+ description: "Recurring organization model editor — layered QA flow across identity, customers, offerings, roles, goals, and techStack. Idempotent, confirm-before-overwrite. Codifies changes to core/config/organization-model.ts with runtime validation gate."
4
4
  argument-hint: "[identity|customers|offerings|roles|goals|techStack|features|labels]"
5
5
  context: fork
6
6
  allowed-tools: Read, Write, Edit, Glob, Grep, Bash
@@ -28,7 +28,7 @@ Recurring, safe-to-re-run org model editor for external projects. Reads the orga
28
28
 
29
29
  ## Goal
30
30
 
31
- Keep `foundations/config/organization-model.ts` accurate and validated. Every edit proposed by this skill ends with `resolveOrganizationModel()` + `OrganizationModelSchema.parse()` confirming the merged result is valid — and a full TypeScript type-check via `pnpm -C operations check-types` to catch static errors. If validation fails, the change is rolled back.
31
+ Keep `core/config/organization-model.ts` accurate and validated. Every edit proposed by this skill ends with `resolveOrganizationModel()` + `OrganizationModelSchema.parse()` confirming the merged result is valid — and a full TypeScript type-check via `pnpm -C operations check-types` to catch static errors. If validation fails, the change is rolled back.
32
32
 
33
33
  ---
34
34
 
@@ -37,7 +37,7 @@ Keep `foundations/config/organization-model.ts` accurate and validated. Every ed
37
37
  Before any domain flow, read the current organization model adapter:
38
38
 
39
39
  ```
40
- Read("foundations/config/organization-model.ts")
40
+ Read("core/config/organization-model.ts")
41
41
  ```
42
42
 
43
43
  This is the single source of truth. All proposals must start from what is currently in this file, not from stale context.
@@ -23,7 +23,7 @@ Before collecting any information or running any steps, determine which state th
23
23
 
24
24
  **State A — Virgin (placeholders present):** One or more of the above placeholder strings is found. Run the full bootstrap flow (Steps 1–7 below), then hand off to `/configure`.
25
25
 
26
- **State B — Already bootstrapped, org-model at defaults:** No placeholders found, but `foundations/config/organization-model.ts` contains only the default branding override (just `branding.organizationName`, `branding.productName`, `branding.shortName` — no identity, customers, offerings, roles, goals, or techStack overrides). Print:
26
+ **State B — Already bootstrapped, org-model at defaults:** No placeholders found, but `core/config/organization-model.ts` contains only the default branding override (just `branding.organizationName`, `branding.productName`, `branding.shortName` — no identity, customers, offerings, roles, goals, or techStack overrides). Print:
27
27
 
28
28
  ```
29
29
  This project is already set up. The organization model has not been configured yet.
@@ -32,7 +32,7 @@ Running /configure to set up your organization profile...
32
32
 
33
33
  Then execute `/configure` (the full layered flow) and stop.
34
34
 
35
- **State C — Fully configured:** No placeholders found AND `foundations/config/organization-model.ts` has at least one non-branding domain populated (identity, customers, offerings, roles, goals, or techStack present). Print:
35
+ **State C — Fully configured:** No placeholders found AND `core/config/organization-model.ts` has at least one non-branding domain populated (identity, customers, offerings, roles, goals, or techStack present). Print:
36
36
 
37
37
  ```
38
38
  This project is already configured. To update your organization profile, run /configure.
@@ -145,7 +145,7 @@ If the user skipped any knowledge questions, fill in what was provided and omit
145
145
 
146
146
  ### Step 5: Write Client Brief to Org Model
147
147
 
148
- **Idempotency check:** Read `foundations/config/organization-model.ts` and inspect `identity.clientBrief`. If the field is already a non-empty string, skip this step entirely — do not overwrite.
148
+ **Idempotency check:** Read `core/config/organization-model.ts` and inspect `identity.clientBrief`. If the field is already a non-empty string, skip this step entirely — do not overwrite.
149
149
 
150
150
  If the field is empty or absent, compose the client brief from the information gathered in Step 2:
151
151
 
@@ -171,12 +171,12 @@ Here's the client brief I'll write into identity.clientBrief:
171
171
  Write this? (yes/no)
172
172
  ```
173
173
 
174
- On confirmation, use the Edit tool to replace the `clientBrief: ''` value in `foundations/config/organization-model.ts` with a template literal containing the composed markdown. Use a regular string (backtick or single-quoted multi-line) — ensure the closing quote and trailing comma are correct TypeScript.
174
+ On confirmation, use the Edit tool to replace the `clientBrief: ''` value in `core/config/organization-model.ts` with a template literal containing the composed markdown. Use a regular string (backtick or single-quoted multi-line) — ensure the closing quote and trailing comma are correct TypeScript.
175
175
 
176
176
  After the edit, run:
177
177
 
178
178
  ```bash
179
- pnpm -C foundations check-types
179
+ pnpm -C core test
180
180
  ```
181
181
 
182
182
  If type-check fails, report the error and do not proceed to Step 6 until it is resolved.
@@ -258,7 +258,7 @@ Running `/setup` more than once is safe:
258
258
  - **Placeholder replacement** only runs when placeholders are detected (State A). It is skipped entirely in States B and C.
259
259
  - **CLAUDE.md knowledge sections** (`{CLIENT_CONTEXT}`, `{USER_PREFERENCES}`) are checked before writing. If already replaced, the write is skipped.
260
260
  - **`identity.clientBrief`** is only written when the field is empty. A non-empty field is never overwritten by `/setup`. The write uses a read → propose → confirm ceremony before touching the file.
261
- - **All other org-model fields** (`foundations/config/organization-model.ts`) are never written by `/setup`. All other org-model edits go through `/configure`, which has its own diff-preview and confirm ceremony.
261
+ - **All other org-model fields** (`core/config/organization-model.ts`) are never written by `/setup`. All other org-model edits go through `/configure`, which has its own diff-preview and confirm ceremony.
262
262
 
263
263
  ---
264
264
 
@@ -0,0 +1,55 @@
1
+ # Auth Role System And Settings Roles
2
+
3
+ ## Why this note exists
4
+
5
+ The Org OS default surface now includes `settings.roles` at `/settings/roles`. Template-derived projects that update to the matching `@elevasis/core` release will receive the Settings navigation entry, so the template now ships a self-view route for members to see their current role and effective permission groups.
6
+
7
+ This route depends on the published `@elevasis/ui` provider/layout/auth exports that the template already uses, plus the backend role and permission endpoints introduced by the same release train. The release train also publishes reusable role hooks and primitives for custom app code that wants the richer role-management surfaces.
8
+
9
+ ## Applies to
10
+
11
+ All template-derived projects that sync from `external/_template` and update to the auth role system release train.
12
+
13
+ This is especially relevant for projects that expose the default Settings navigation from `@elevasis/core` organization-model surfaces or run a project-local organization model derived from those defaults.
14
+
15
+ ## Required actions
16
+
17
+ 1. Pull template changes with `/git-sync` so `ui/src/routes/settings/roles.tsx` is available.
18
+ 2. Update project packages after the release train is published:
19
+
20
+ ```bash
21
+ pnpm up @elevasis/core @elevasis/ui --latest
22
+ ```
23
+
24
+ 3. Confirm the project API target is deployed to a backend version that includes the auth role endpoints used by the published UI hooks:
25
+
26
+ - `GET /permissions/catalog`
27
+ - `GET /memberships/my-permissions/:orgId`
28
+ - role-management endpoints under `/organizations/:orgId/roles`
29
+ - membership role and effective-permission endpoints under `/memberships/:membershipId`
30
+
31
+ 4. Rebuild any project-local route tree artifacts if your project does not regenerate TanStack Router routes during normal dev/build startup.
32
+
33
+ ## Verification
34
+
35
+ Run from the project root after package updates and backend deployment:
36
+
37
+ ```bash
38
+ pnpm -C ui check-types
39
+ pnpm -C ui build
40
+ ```
41
+
42
+ Then sign in to the UI, open `/settings/roles`, and verify:
43
+
44
+ - the page is protected for authenticated organization members,
45
+ - the current membership role badge is visible,
46
+ - grouped effective permissions render,
47
+ - permission descriptions load from the catalog endpoint,
48
+ - no Settings navigation item points to a missing route.
49
+
50
+ ## Not handled by /git-sync
51
+
52
+ - `/git-sync` does not publish or upgrade `@elevasis/core` or `@elevasis/ui`.
53
+ - `/git-sync` does not deploy the API/backend version that serves the role and permission endpoints.
54
+ - `/git-sync` does not reconcile project-owned organization-model overrides that intentionally remove or rename Settings surfaces.
55
+ - `/git-sync` does not validate downstream auth state, role assignments, or production API connectivity.
@@ -0,0 +1,101 @@
1
+ # CRM HITL Action Layer Cutover
2
+
3
+ ## Why this note exists
4
+
5
+ The Elevasis platform completed an atomic cutover of `acq_deals` from the legacy `cached_stage` + `proposal_status` model to the canonical `pipeline_key` / `stage_key` / `state_key` runtime fields. The release train that ships this cutover bumps `@elevasis/core`, `@elevasis/ui`, and `@elevasis/sdk` together, and rewires server-side lifecycle to flow through a single `transitionItem()` boundary in the API.
6
+
7
+ Concretely, this train introduces:
8
+
9
+ - a flat `ActivityEventSchema` discriminated union on `@elevasis/core/business/acquisition` (replaces the older `DealActivityEntry` shape; activity rows now use fields like `stageBefore`, `stageAfter`, `stateBefore`, `stateAfter`, `taskId`, `timestamp`)
10
+ - a pure `deriveActions(deal)` helper on `@elevasis/core/business/acquisition` (UI/API action derivation from current deal state)
11
+ - new typed CRM hooks on `@elevasis/ui` (`useTransitionItem`, refreshed `useSyncDealStage`, kanban + deal-drawer wiring)
12
+ - canonical `transitionItem(dealId, organizationId, pipelineKey, stageKey, stateKey?, reason?, expectedUpdatedAt?)` as the single lifecycle mutation; server-side it appends activity, supersedes open command-queue rows, and closes incompatible tasks atomically
13
+ - a `command_queue`-backed HITL transport supersession lifecycle resolved by `resolveDealCommandQueue` (called inside `transitionItem`)
14
+
15
+ Derived projects that read or write `acq_deals` directly, render the CRM kanban from `@elevasis/ui`, or import acquisition types from `@elevasis/core` will pick up these contract changes when they upgrade through this train.
16
+
17
+ ## Applies to
18
+
19
+ All template-derived projects that:
20
+
21
+ - consume `@elevasis/core/business/acquisition` types (`Deal`, `ActivityEvent`, action types) or import `deriveActions`
22
+ - render the CRM kanban / deal drawer surfaces from `@elevasis/ui`
23
+ - have a project-local `acq_deals` table that mirrors the platform schema
24
+ - author workflows under `operations/src/sales/crm/**` that call `acqDb.transitionItem(...)` (or formerly called `syncDealStage` / direct stage writes)
25
+ - read `activity_log` rows on deals and pattern-match on event shape
26
+
27
+ Operations-only projects with no CRM surface and no `acq_deals` table can ignore this train.
28
+
29
+ ## Required actions
30
+
31
+ 1. Pull template changes with `/git-sync` so the refreshed CRM hook + drawer/kanban consumers are available.
32
+
33
+ 2. After the release train is published, update package versions in the project:
34
+
35
+ ```bash
36
+ pnpm up @elevasis/core @elevasis/ui @elevasis/sdk --latest
37
+ ```
38
+
39
+ 3. If your project has a project-local `acq_deals` table, run the matching atomic cutover migration. The reference SQL lives in the monorepo at `apps/docs/content/docs/in-progress/active-development/sdk-changes/org-model/_sql/`:
40
+ - `00_preflight_org_model_cutover.sql`
41
+ - `01_cleanup_known_cutover_outliers.sql`
42
+ - `02_acq_deals_atomic_cutover.sql`
43
+ - `03_postflight_org_model_cutover.sql`
44
+
45
+ The cutover is single-shot, not dual-write. Backfill `pipeline_key` / `stage_key` from `cached_stage` and drop the legacy columns in the same transaction. There is no mid-flight rollback path; fix-forward only. Confirm prod deal volume is small enough to accept that tradeoff before applying.
46
+
47
+ 4. Replace any direct stage writes with `acqDb.transitionItem(...)`:
48
+ - workflow code that previously called `syncDealStage`, `updateDeal({ cached_stage: ... })`, or wrote `proposal_status` directly must now route through `transitionItem`
49
+ - the API server injects `organizationId` from execution context — never pass `organizationId` from worker payload
50
+ - the platform-side method appends `ActivityEventSchema`-shaped events; do NOT also write activity rows from the workflow side
51
+
52
+ 5. If you read `activity_log` and pattern-match by `type`, update consumers to the flat schema:
53
+
54
+ ```ts
55
+ // Stage change
56
+ { type: 'stage_change', timestamp, stageBefore, stageAfter, reason? }
57
+
58
+ // State change
59
+ { type: 'state_change', timestamp, stateBefore, stateAfter, reason? }
60
+
61
+ // Task created
62
+ { type: 'task_created', timestamp, taskId }
63
+
64
+ // Approval resolved (written by resolveDealCommandQueue)
65
+ { type: 'approval_resolved', timestamp, ... }
66
+ ```
67
+
68
+ The legacy `{ type, title, payload, occurredAt }` envelope is gone.
69
+
70
+ 6. If your project deploys SDK resources, redeploy `operations` after the package upgrades so workers pick up the new typed adapter surface and ToolMap entries:
71
+
72
+ ```bash
73
+ pnpm -C operations exec elevasis-sdk deploy --prod
74
+ ```
75
+
76
+ ## Verification
77
+
78
+ Run from the project root after package updates and any DB migration:
79
+
80
+ ```bash
81
+ pnpm -C ui check-types
82
+ pnpm -C ui build
83
+ pnpm -C operations check-types
84
+ pnpm -C operations exec elevasis-sdk check
85
+ ```
86
+
87
+ Then exercise the CRM surface:
88
+
89
+ - open the deal kanban — drag a deal between stages; confirm the activity log shows a flat `stage_change` event with `stageBefore` / `stageAfter`
90
+ - open a deal drawer — confirm available actions render from `deriveActions(deal)` and not from a stored `available_actions` array
91
+ - if you have a HITL approval surface, confirm that completing or superseding an approval lands an `approval_resolved` activity event before any subsequent state change
92
+
93
+ If a workflow that historically wrote stage updates throws Zod errors against `ActivityEventSchema`, it is still on the legacy envelope — fix-forward by routing it through `acqDb.transitionItem(...)`.
94
+
95
+ ## Not handled by /git-sync
96
+
97
+ - `/git-sync` does not publish or upgrade `@elevasis/core`, `@elevasis/ui`, or `@elevasis/sdk`.
98
+ - `/git-sync` does not run the project-local `acq_deals` cutover migration. The DB cutover is atomic and irreversible — only the project owner can authorize it.
99
+ - `/git-sync` does not redeploy the project's `operations` bundle to dev or prod.
100
+ - `/git-sync` does not rewrite project-owned workflow code that bypasses `transitionItem` to write stage / state directly.
101
+ - `/git-sync` does not reconcile project-owned `activity_log` consumers that still pattern-match on the legacy `DealActivityEntry` envelope.
package/reference/cli.mdx CHANGED
@@ -537,9 +537,12 @@ elevasis-sdk project:delete <id>
537
537
  elevasis-sdk project:milestone:list --project <id>
538
538
  elevasis-sdk project:milestone:create --project <id> --name "Phase 1"
539
539
  elevasis-sdk project:milestone:update <id> --status completed
540
+ elevasis-sdk project:milestone:update <id> --description "Updated scope description"
540
541
  elevasis-sdk project:milestone:delete <id>
541
542
  ```
542
543
 
544
+ `project:milestone:update` accepts `--description` to set or clear the milestone description. Passing an empty string clears the field, matching `project:task:update --description` semantics.
545
+
543
546
  ### Tasks
544
547
 
545
548
  ```bash
@@ -566,10 +569,42 @@ elevasis-sdk project:task:save <id> --current-state "Implemented the route layer
566
569
  ```bash
567
570
  elevasis-sdk project:note:list --project <id>
568
571
  elevasis-sdk project:note:create --project <id> --content "Client approved scope"
572
+ elevasis-sdk project:note:create --project <id> --type agent_learning --content "Learned X"
569
573
  elevasis-sdk project:note:update <id> --content "Updated status"
570
574
  elevasis-sdk project:note:delete <id>
571
575
  ```
572
576
 
577
+ The `--type` flag accepts: `call_note`, `status_update`, `issue`, `blocker`, `agent_learning`. The `agent_learning` type is the canonical way for agents to record durable skill observations. Accepted values are derived from `NoteTypeSchema` in `packages/core/src/projects/api-schemas.ts` -- that schema is the source of truth; the CLI help text is generated from it to prevent drift.
578
+
579
+ ### Requests
580
+
581
+ ```bash
582
+ elevasis-sdk request:submit --input-file ./tmp/request-report.json
583
+ elevasis-sdk request:submit --input '{"type":"bug","category":"sdk","severity":"high","title":"..."}'
584
+ ```
585
+
586
+ Submits a structured request report to `POST /api/external/requests`. The payload is validated against `CreateRequestInputSchema` before the network call.
587
+
588
+ **Payload enum values** (inline in `--help` output; sourced from `packages/core/src/requests/api-schemas.ts`):
589
+
590
+ | Field | Accepted values |
591
+ | ---------- | ------------------------------------------------------------------------------------- |
592
+ | `type` | Values from `RequestTypeEnum` -- see `request:submit --help` for the current list |
593
+ | `category` | Values from `RequestCategoryEnum` -- see `request:submit --help` for the current list |
594
+ | `severity` | Values from `RequestSeverityEnum` -- see `request:submit --help` for the current list |
595
+
596
+ **Flags:**
597
+
598
+ | Flag | Description |
599
+ | --------------------------- | ----------------------------------------------------------------------------- |
600
+ | `-i, --input <json>` | Request body as JSON string |
601
+ | `-f, --input-file <path>` | Read body from a JSON file; relative paths resolve against the project root |
602
+ | `--pretty` | Human-readable output instead of raw JSON |
603
+ | `--cleanup-input` | Delete the input file after success (only files under `<projectRoot>/tmp/`) |
604
+ | `--api-url <url>` | Override the API base URL |
605
+
606
+ ---
607
+
573
608
  ### Shared Flags
574
609
 
575
610
  Most `project:*` commands support:
@@ -590,6 +625,28 @@ For exact required flags and accepted enum values, see the command source under
590
625
 
591
626
  ---
592
627
 
628
+ ## elevasis-sdk ui:use-local / ui:use-published
629
+
630
+ Switch the `@elevasis/ui` dependency in an external project between a local tarball build and the published npm package.
631
+
632
+ **Synopsis:**
633
+
634
+ ```bash
635
+ elevasis-sdk ui:use-local
636
+ elevasis-sdk ui:use-published
637
+ ```
638
+
639
+ **Behavior:**
640
+
641
+ - `ui:use-local` -- builds a tarball from the local `packages/ui/` source and rewrites the project's `package.json` to point at the tarball path. Use this during active `@elevasis/ui` development to test changes without publishing.
642
+ - `ui:use-published` -- reverts `package.json` to the published `@elevasis/ui` version string and removes any local tarball reference.
643
+
644
+ Both commands install after rewriting `package.json`. The `external/_template` root scripts `ui:use-local` and `ui:use-published` are compatibility wrappers that delegate to these CLI commands.
645
+
646
+ **Implementation:** `packages/sdk/src/cli/commands/ui/ui-switcher.ts`
647
+
648
+ ---
649
+
593
650
  ## Global Flags
594
651
 
595
652
  These flags are accepted by all commands: