@elevasis/sdk 1.21.0 → 1.22.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.
- package/dist/cli.cjs +951 -171
- package/dist/index.d.ts +632 -341
- package/dist/index.js +3102 -142
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +19 -1
- package/dist/test-utils/index.d.ts +313 -4
- package/dist/test-utils/index.js +3246 -281
- package/dist/worker/index.js +3041 -80
- package/package.json +3 -3
- package/reference/claude-config/hooks/post-edit-validate.mjs +98 -98
- package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +188 -188
- package/reference/claude-config/hooks/tool-failure-recovery.mjs +73 -73
- package/reference/claude-config/registries/graph-skills.json +4 -4
- package/reference/claude-config/registries/knowledge-flags.json +0 -2
- package/reference/claude-config/rules/active-change-index.md +80 -80
- package/reference/claude-config/rules/agent-start-here.md +277 -277
- package/reference/claude-config/rules/deployment.md +57 -57
- package/reference/claude-config/rules/error-handling.md +56 -56
- package/reference/claude-config/rules/execution.md +40 -40
- package/reference/claude-config/rules/frontend.md +4 -4
- package/reference/claude-config/rules/observability.md +31 -31
- package/reference/claude-config/rules/operations.md +29 -17
- package/reference/claude-config/rules/organization-model.md +110 -84
- package/reference/claude-config/rules/organization-os.md +115 -113
- package/reference/claude-config/rules/package-taxonomy.md +33 -33
- package/reference/claude-config/rules/platform.md +42 -42
- package/reference/claude-config/rules/shared-types.md +49 -46
- package/reference/claude-config/rules/task-tracking.md +47 -47
- package/reference/claude-config/rules/ui.md +200 -200
- package/reference/claude-config/rules/vibe.md +235 -235
- package/reference/claude-config/scripts/statusline-command.js +18 -18
- package/reference/claude-config/settings.json +34 -34
- package/reference/claude-config/skills/deploy/{SKILL.md → skill.md} +156 -156
- package/reference/claude-config/skills/dsp/SKILL.md +66 -66
- package/reference/claude-config/skills/elevasis/SKILL.md +235 -235
- package/reference/claude-config/skills/explore/SKILL.md +6 -6
- package/reference/claude-config/skills/git-sync/SKILL.md +126 -126
- package/reference/claude-config/skills/knowledge/SKILL.md +314 -299
- package/reference/claude-config/skills/knowledge/operations/codify-level-a.md +100 -100
- package/reference/claude-config/skills/knowledge/operations/codify-level-b.md +159 -159
- package/reference/claude-config/skills/knowledge/operations/customers.md +109 -109
- package/reference/claude-config/skills/knowledge/operations/features.md +76 -76
- package/reference/claude-config/skills/knowledge/operations/goals.md +118 -118
- package/reference/claude-config/skills/knowledge/operations/identity.md +93 -93
- package/reference/claude-config/skills/knowledge/operations/labels.md +94 -94
- package/reference/claude-config/skills/knowledge/operations/offerings.md +109 -109
- package/reference/claude-config/skills/knowledge/operations/roles.md +99 -99
- package/reference/claude-config/skills/knowledge/operations/techStack.md +30 -30
- package/reference/claude-config/skills/project/SKILL.md +1088 -1088
- package/reference/claude-config/skills/run-ui/SKILL.md +73 -73
- package/reference/claude-config/skills/save/SKILL.md +3 -3
- package/reference/claude-config/skills/setup/SKILL.md +275 -275
- package/reference/claude-config/skills/status/SKILL.md +59 -59
- package/reference/claude-config/skills/submit-request/SKILL.md +180 -180
- package/reference/claude-config/skills/sync/SKILL.md +47 -47
- package/reference/claude-config/skills/tutorial/SKILL.md +259 -259
- package/reference/claude-config/skills/tutorial/progress-template.md +74 -74
- package/reference/claude-config/skills/tutorial/technical.md +1303 -1303
- package/reference/claude-config/skills/tutorial/vibe-coder.md +890 -890
- package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +27 -27
- package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +30 -30
- package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +73 -73
- package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +86 -86
- package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +55 -55
- package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +97 -97
- package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +112 -112
- package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +93 -93
- package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +58 -58
- package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +56 -56
- package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +71 -71
- package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
- package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +59 -59
- package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +42 -42
- package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +60 -60
- package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +37 -37
- package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +34 -34
- package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +38 -38
- package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +32 -32
- package/reference/claude-config/sync-notes/2026-05-09-command-system.md +33 -33
- package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +69 -69
- package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +30 -30
- package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +42 -0
- package/reference/claude-config/sync-notes/README.md +43 -43
- package/reference/cli.mdx +808 -808
- package/reference/concepts.mdx +146 -146
- package/reference/deployment/api.mdx +297 -297
- package/reference/deployment/command-center.mdx +209 -209
- package/reference/deployment/index.mdx +195 -195
- package/reference/deployment/provided-features.mdx +107 -107
- package/reference/deployment/ui-execution.mdx +250 -250
- package/reference/examples/organization-model.ts +146 -83
- package/reference/framework/agent.mdx +156 -156
- package/reference/framework/index.mdx +195 -195
- package/reference/framework/interaction-guidance.mdx +182 -182
- package/reference/framework/memory.mdx +326 -326
- package/reference/framework/project-structure.mdx +282 -282
- package/reference/framework/tutorial-system.mdx +135 -135
- package/reference/getting-started.mdx +142 -142
- package/reference/index.mdx +106 -106
- package/reference/packages/core/src/README.md +14 -14
- package/reference/packages/core/src/business/README.md +2 -2
- package/reference/packages/core/src/knowledge/README.md +32 -32
- package/reference/packages/core/src/organization-model/README.md +149 -149
- package/reference/packages/core/src/test-utils/README.md +37 -37
- package/reference/packages/ui/src/api/README.md +18 -18
- package/reference/packages/ui/src/app/README.md +24 -24
- package/reference/packages/ui/src/auth/README.md +18 -18
- package/reference/packages/ui/src/components/README.md +24 -24
- package/reference/packages/ui/src/execution/README.md +16 -16
- package/reference/packages/ui/src/features/README.md +28 -28
- package/reference/packages/ui/src/graph/README.md +16 -16
- package/reference/packages/ui/src/hooks/README.md +23 -23
- package/reference/packages/ui/src/initialization/README.md +19 -19
- package/reference/packages/ui/src/knowledge/README.md +31 -31
- package/reference/packages/ui/src/organization/README.md +18 -18
- package/reference/packages/ui/src/profile/README.md +19 -19
- package/reference/packages/ui/src/provider/README.md +32 -32
- package/reference/packages/ui/src/router/README.md +18 -18
- package/reference/packages/ui/src/sse/README.md +13 -13
- package/reference/packages/ui/src/test-utils/README.md +7 -7
- package/reference/packages/ui/src/theme/README.md +23 -23
- package/reference/packages/ui/src/theme/presets/README.md +19 -19
- package/reference/packages/ui/src/types/README.md +16 -16
- package/reference/packages/ui/src/utils/README.md +18 -18
- package/reference/packages/ui/src/zustand/README.md +18 -18
- package/reference/platform-tools/adapters-integration.mdx +301 -301
- package/reference/platform-tools/adapters-platform.mdx +553 -553
- package/reference/platform-tools/index.mdx +217 -217
- package/reference/platform-tools/type-safety.mdx +82 -82
- package/reference/resources/index.mdx +349 -349
- package/reference/resources/patterns.mdx +449 -449
- package/reference/resources/types.mdx +116 -116
- package/reference/roadmap.mdx +165 -165
- package/reference/runtime.mdx +173 -173
- package/reference/scaffold/core/organization-graph.mdx +110 -90
- package/reference/scaffold/core/organization-model.mdx +226 -219
- package/reference/scaffold/index.mdx +67 -67
- package/reference/scaffold/operations/propagation-pipeline.md +77 -77
- package/reference/scaffold/operations/scaffold-maintenance.md +12 -12
- package/reference/scaffold/operations/workflow-recipes.md +138 -138
- package/reference/scaffold/recipes/add-a-feature.md +308 -88
- package/reference/scaffold/recipes/add-a-resource.md +134 -110
- package/reference/scaffold/recipes/customize-knowledge-browser.md +5 -5
- package/reference/scaffold/recipes/customize-organization-model.md +273 -138
- package/reference/scaffold/recipes/extend-a-base-entity.md +8 -8
- package/reference/scaffold/recipes/extend-crm.md +3 -3
- package/reference/scaffold/recipes/extend-lead-gen.md +400 -400
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +118 -118
- package/reference/scaffold/recipes/index.md +46 -46
- package/reference/scaffold/recipes/query-the-knowledge-graph.md +197 -170
- package/reference/scaffold/reference/contracts.md +2101 -2096
- package/reference/scaffold/reference/glossary.md +76 -76
- package/reference/scaffold/ui/composition-extensibility.mdx +233 -233
- package/reference/scaffold/ui/customization.md +243 -243
- package/reference/scaffold/ui/feature-flags-and-gating.md +46 -46
- package/reference/scaffold/ui/feature-shell.mdx +72 -72
- package/reference/scaffold/ui/recipes.md +221 -214
- package/reference/spine/spine-primer.md +96 -96
- package/reference/templates/index.mdx +47 -47
- package/reference/troubleshooting.mdx +223 -223
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Propagation Pipeline
|
|
3
|
-
description: Three-layer pipeline that keeps Organization OS artifacts current across the monorepo and all template-derived external projects -- source generation, registry-driven sync planning/apply, and verification.
|
|
3
|
+
description: Three-layer pipeline that keeps Organization OS artifacts current across the monorepo and all template-derived external projects -- source generation, registry-driven sync planning/apply, and verification.
|
|
4
4
|
---
|
|
5
5
|
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
6
6
|
<!-- Regenerate: pnpm scaffold:sync -->
|
|
@@ -14,18 +14,18 @@ description: Three-layer pipeline that keeps Organization OS artifacts current a
|
|
|
14
14
|
|
|
15
15
|
## Architecture
|
|
16
16
|
|
|
17
|
-
The Organization OS propagation pipeline has three layers. Each has its own scripts, triggers, and failure modes.
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
Layer 1: Source Generation (pnpm scaffold:sync)
|
|
21
|
-
Regenerates derived docs from TypeScript types and manifests
|
|
22
|
-
↓
|
|
23
|
-
Layer 2: Registry-Driven Sync Planning + Apply (/external sync)
|
|
24
|
-
Plans registry-backed writes/deletes, then applies the approved scope
|
|
25
|
-
↓
|
|
26
|
-
Layer 3: Sync Verification (pnpm sync:verify)
|
|
27
|
-
Asserts correctness across all template-derived projects after apply
|
|
28
|
-
```
|
|
17
|
+
The Organization OS propagation pipeline has three layers. Each has its own scripts, triggers, and failure modes.
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Layer 1: Source Generation (pnpm scaffold:sync)
|
|
21
|
+
Regenerates derived docs from TypeScript types and manifests
|
|
22
|
+
↓
|
|
23
|
+
Layer 2: Registry-Driven Sync Planning + Apply (/external sync)
|
|
24
|
+
Plans registry-backed writes/deletes, then applies the approved scope
|
|
25
|
+
↓
|
|
26
|
+
Layer 3: Sync Verification (pnpm sync:verify)
|
|
27
|
+
Asserts correctness across all template-derived projects after apply
|
|
28
|
+
```
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
@@ -36,7 +36,7 @@ Layer 3: Sync Verification (pnpm sync:verify)
|
|
|
36
36
|
| Script | Input | Output |
|
|
37
37
|
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
38
38
|
| `generate-scaffold-contracts.js` | `packages/core/src/organization-model/types.ts`, `packages/ui/src/features/registry/types.ts`, `packages/core/src/platform/registry/types.ts` | `packages/core/src/reference/_generated/contracts.md` |
|
|
39
|
-
| `generate-scaffold-feature-registry.js` | `packages/ui/src/features/registry/manifests.ts`, `packages/ui/src/features/*/manifest.ts` | `packages/ui/src/scaffold/_generated/feature-registry.md` |
|
|
39
|
+
| `generate-scaffold-feature-registry.js` | `packages/ui/src/features/registry/manifests.ts`, `packages/ui/src/features/*/manifest.ts` | `packages/ui/src/scaffold/_generated/feature-registry.md` |
|
|
40
40
|
| `generate-reference-artifacts.js` | SDK manifest, navigation sources | `packages/sdk/reference/_reference-manifest.json`, `_navigation.md` |
|
|
41
41
|
|
|
42
42
|
After generation, `validate-reference-artifacts.js` checks that the outputs are consistent. Exit 1 if drifted.
|
|
@@ -54,41 +54,41 @@ Drift is healed at the moment it would otherwise leak downstream. This is cheape
|
|
|
54
54
|
|
|
55
55
|
---
|
|
56
56
|
|
|
57
|
-
## Layer 2: Registry-Driven Sync Planning + Apply
|
|
58
|
-
|
|
59
|
-
`/external sync` now treats the scaffold registry as the execution contract rather than relying on tier prose alone.
|
|
60
|
-
The canonical ownership vocabulary is:
|
|
61
|
-
|
|
62
|
-
| Category | Strategy examples | Meaning |
|
|
63
|
-
| --------------- | ----------------------------------------------- | ----------------------------------------------------------------------- |
|
|
64
|
-
| `replace` | `replace-all` | Template-managed surface; copy from template baseline |
|
|
65
|
-
| `merge` | `merge-baseline`, `merge-regions` | Merge-aware surface; preserve project customizations where required |
|
|
66
|
-
| `never-touch` | `verify-only` | Project-owned surface; planner may report drift but never writes |
|
|
67
|
-
| `generated` | `generated-freshness` | Generated surface; verify/regen instead of copying |
|
|
68
|
-
|
|
69
|
-
Current command helpers:
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
pnpm sync:plan -- --all # registry-backed dry-run plan
|
|
73
|
-
pnpm sync:apply -- --all # registry-backed apply pass
|
|
74
|
-
pnpm sync:verify # post-apply verification
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
Per-project or scoped runs pass the project name and optional `--path` / `--source` filters through to the planner/apply script.
|
|
78
|
-
|
|
79
|
-
Delete behavior is explicit:
|
|
80
|
-
|
|
81
|
-
- managed deletes apply only to `replace` surfaces
|
|
82
|
-
- deletion is allowed only when the path appears in the manifest-backed tombstone list
|
|
83
|
-
- absence from the template alone is not enough to delete a downstream file
|
|
84
|
-
|
|
85
|
-
Generated surfaces are also explicit:
|
|
86
|
-
|
|
87
|
-
- they are planned as `generated`
|
|
88
|
-
- apply does not copy them as normal source files
|
|
89
|
-
- the relevant regen command must run, then `pnpm sync:verify` checks freshness
|
|
90
|
-
|
|
91
|
-
The external skill doc (`.claude/skills/external/SKILL.md`) remains the workflow authority, but it should be read as planner/apply/verify orchestration over the registry model above.
|
|
57
|
+
## Layer 2: Registry-Driven Sync Planning + Apply
|
|
58
|
+
|
|
59
|
+
`/external sync` now treats the scaffold registry as the execution contract rather than relying on tier prose alone.
|
|
60
|
+
The canonical ownership vocabulary is:
|
|
61
|
+
|
|
62
|
+
| Category | Strategy examples | Meaning |
|
|
63
|
+
| --------------- | ----------------------------------------------- | ----------------------------------------------------------------------- |
|
|
64
|
+
| `replace` | `replace-all` | Template-managed surface; copy from template baseline |
|
|
65
|
+
| `merge` | `merge-baseline`, `merge-regions` | Merge-aware surface; preserve project customizations where required |
|
|
66
|
+
| `never-touch` | `verify-only` | Project-owned surface; planner may report drift but never writes |
|
|
67
|
+
| `generated` | `generated-freshness` | Generated surface; verify/regen instead of copying |
|
|
68
|
+
|
|
69
|
+
Current command helpers:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pnpm sync:plan -- --all # registry-backed dry-run plan
|
|
73
|
+
pnpm sync:apply -- --all # registry-backed apply pass
|
|
74
|
+
pnpm sync:verify # post-apply verification
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Per-project or scoped runs pass the project name and optional `--path` / `--source` filters through to the planner/apply script.
|
|
78
|
+
|
|
79
|
+
Delete behavior is explicit:
|
|
80
|
+
|
|
81
|
+
- managed deletes apply only to `replace` surfaces
|
|
82
|
+
- deletion is allowed only when the path appears in the manifest-backed tombstone list
|
|
83
|
+
- absence from the template alone is not enough to delete a downstream file
|
|
84
|
+
|
|
85
|
+
Generated surfaces are also explicit:
|
|
86
|
+
|
|
87
|
+
- they are planned as `generated`
|
|
88
|
+
- apply does not copy them as normal source files
|
|
89
|
+
- the relevant regen command must run, then `pnpm sync:verify` checks freshness
|
|
90
|
+
|
|
91
|
+
The external skill doc (`.claude/skills/external/SKILL.md`) remains the workflow authority, but it should be read as planner/apply/verify orchestration over the registry model above.
|
|
92
92
|
|
|
93
93
|
---
|
|
94
94
|
|
|
@@ -98,18 +98,18 @@ The external skill doc (`.claude/skills/external/SKILL.md`) remains the workflow
|
|
|
98
98
|
|
|
99
99
|
### Per-Project Checks (auto-discovered)
|
|
100
100
|
|
|
101
|
-
| Category | What It Checks |
|
|
102
|
-
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
103
|
-
| `deps` | `@elevasis/ui`, `@elevasis/sdk`, `@elevasis/core` versions match template |
|
|
104
|
-
| `tier1` | registry-backed replace surfaces match template where verification still models them as exact baselines |
|
|
105
|
-
| `org-os` | Organization model exists, exports canonical symbols, imports from `@elevasis/core/organization-model`, calls `createFoundationOrganizationModel`, app-config references org model, `__root.tsx` uses `ElevasisSystemsProvider` + `canonicalOrganizationModel`, `main.tsx` uses `createElevasisApp`, all 3 CSS subpath imports present |
|
|
106
|
-
| `placeholders` | No unresolved `__PROJECT_SLUG__`, `__PROJECT_NAME__`, `__PROJECT_DESCRIPTION__` in key config files |
|
|
107
|
-
| `scripts` | `ui` and `operations` `package.json` have required npm scripts |
|
|
108
|
-
| `lib` | `ui/src/lib/`, `lib/`, `test-utils/` exist with minimum file counts |
|
|
109
|
-
| `tier3` | project-owned preservation boundaries such as `nav-items.ts` remain intact |
|
|
110
|
-
| `conflicts` | No merge conflict markers in source files |
|
|
111
|
-
| `git` | Working tree is clean |
|
|
112
|
-
| `lockfile` | `pnpm-lock.yaml` and `node_modules` exist |
|
|
101
|
+
| Category | What It Checks |
|
|
102
|
+
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
103
|
+
| `deps` | `@elevasis/ui`, `@elevasis/sdk`, `@elevasis/core` versions match template |
|
|
104
|
+
| `tier1` | registry-backed replace surfaces match template where verification still models them as exact baselines |
|
|
105
|
+
| `org-os` | Organization model exists, exports canonical symbols, imports from `@elevasis/core/organization-model`, calls `createFoundationOrganizationModel`, app-config references org model, `__root.tsx` uses `ElevasisSystemsProvider` + `canonicalOrganizationModel`, `main.tsx` uses `createElevasisApp`, all 3 CSS subpath imports present |
|
|
106
|
+
| `placeholders` | No unresolved `__PROJECT_SLUG__`, `__PROJECT_NAME__`, `__PROJECT_DESCRIPTION__` in key config files |
|
|
107
|
+
| `scripts` | `ui` and `operations` `package.json` have required npm scripts |
|
|
108
|
+
| `lib` | `ui/src/lib/`, `lib/`, `test-utils/` exist with minimum file counts |
|
|
109
|
+
| `tier3` | project-owned preservation boundaries such as `nav-items.ts` remain intact |
|
|
110
|
+
| `conflicts` | No merge conflict markers in source files |
|
|
111
|
+
| `git` | Working tree is clean |
|
|
112
|
+
| `lockfile` | `pnpm-lock.yaml` and `node_modules` exist |
|
|
113
113
|
|
|
114
114
|
### Monorepo-Level Checks
|
|
115
115
|
|
|
@@ -126,22 +126,22 @@ pnpm sync:verify --pre # Pre-sync drift report (always exit 0)
|
|
|
126
126
|
pnpm sync:verify -- ZentaraHQ # Single project
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
### Integration Points
|
|
130
|
-
|
|
131
|
-
- **`/external sync` preflight:** Runs `pnpm sync:verify --pre` before planning so current drift is visible before any writes
|
|
132
|
-
- **`/external sync` planner/apply:** `pnpm sync:plan` previews registry-backed writes/deletes, then `pnpm sync:apply` executes the approved plan
|
|
133
|
-
- **`/external sync` post-apply:** Runs `pnpm sync:verify` to assert correctness after the planner/apply pass
|
|
134
|
-
- **Automated coverage:** tests live under `scripts/external/__tests__/` including planner/apply coverage
|
|
129
|
+
### Integration Points
|
|
135
130
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
131
|
+
- **`/external sync` preflight:** Runs `pnpm sync:verify --pre` before planning so current drift is visible before any writes
|
|
132
|
+
- **`/external sync` planner/apply:** `pnpm sync:plan` previews registry-backed writes/deletes, then `pnpm sync:apply` executes the approved plan
|
|
133
|
+
- **`/external sync` post-apply:** Runs `pnpm sync:verify` to assert correctness after the planner/apply pass
|
|
134
|
+
- **Automated coverage:** tests live under `scripts/external/__tests__/` including planner/apply coverage
|
|
135
|
+
|
|
136
|
+
### Planner Interpretation Note
|
|
137
|
+
|
|
138
|
+
`pnpm sync:verify` still carries some historical `tier1` / `tier3` labels in its output, but the ownership semantics now come from the registry-backed categories used by the planner:
|
|
139
|
+
|
|
140
|
+
- `.claude/commands/**`, `hooks/**`, `rules/**`, `scripts/**`, `skills/**`, and `.claude/settings.json` are managed `replace` surfaces
|
|
141
|
+
- `nav-items.ts`, `operations/src/**`, `shared/src/**`, `CLAUDE.md`, and extension files are `never-touch`
|
|
142
|
+
- generated surfaces are verified for freshness, not copied
|
|
143
|
+
|
|
144
|
+
Treat the old tier labels as display shorthand inside the verifier, not as the canonical execution contract.
|
|
145
145
|
|
|
146
146
|
---
|
|
147
147
|
|
|
@@ -149,7 +149,7 @@ Treat the old tier labels as display shorthand inside the verifier, not as the c
|
|
|
149
149
|
|
|
150
150
|
| Gap | Priority |
|
|
151
151
|
| ------------------------------------------------------------------------- | -------- |
|
|
152
|
-
| System manifest validation (all manifests imported in `__root.tsx`) | Medium |
|
|
152
|
+
| System manifest validation (all manifests imported in `__root.tsx`) | Medium |
|
|
153
153
|
| TypeScript verification (`check-types` per project) | Medium |
|
|
154
154
|
| Template docs surface validation (`docs/index.md`, `agent-start-here.md`) | Medium |
|
|
155
155
|
| Environment variable template validation (`.env.example` completeness) | Low |
|
|
@@ -32,13 +32,13 @@ Scaffold docs are co-located with their owning package and copied into the SDK r
|
|
|
32
32
|
| Glossary | `packages/core/src/reference/glossary.md` | `scaffold/reference/glossary.md` |
|
|
33
33
|
| Contracts (auto-gen) | `packages/core/src/reference/_generated/contracts.md` | `scaffold/reference/contracts.md` |
|
|
34
34
|
| UI Recipes | `packages/ui/src/scaffold/recipes.md` | `scaffold/ui/recipes.md` |
|
|
35
|
-
| System Flags & Gating | `packages/ui/src/scaffold/feature-flags-and-gating.md` | `scaffold/ui/feature-flags-and-gating.md` |
|
|
35
|
+
| System Flags & Gating | `packages/ui/src/scaffold/feature-flags-and-gating.md` | `scaffold/ui/feature-flags-and-gating.md` |
|
|
36
36
|
| Customization | `packages/ui/src/scaffold/customization.md` | `scaffold/ui/customization.md` |
|
|
37
|
-
| System Shell | `packages/ui/src/scaffold/feature-shell.mdx` | `scaffold/ui/feature-shell.mdx` |
|
|
37
|
+
| System Shell | `packages/ui/src/scaffold/feature-shell.mdx` | `scaffold/ui/feature-shell.mdx` |
|
|
38
38
|
| Composition & Extensibility | `packages/ui/src/scaffold/composition-extensibility.mdx` | `scaffold/ui/composition-extensibility.mdx` |
|
|
39
|
-
| System Registry (auto-gen) | `packages/ui/src/scaffold/_generated/feature-registry.md` | `scaffold/reference/feature-registry.md` |
|
|
39
|
+
| System Registry (auto-gen) | `packages/ui/src/scaffold/_generated/feature-registry.md` | `scaffold/reference/feature-registry.md` |
|
|
40
40
|
| Scaffold Index | `packages/sdk/docs/scaffold/index.mdx` | `scaffold/index.mdx` |
|
|
41
|
-
| Pathway Recipes
|
|
41
|
+
| Pathway Recipes | `packages/sdk/docs/scaffold/recipes/` | `scaffold/recipes/` |
|
|
42
42
|
| Workflow Recipes | `packages/sdk/docs/scaffold/operations/workflow-recipes.md` | `scaffold/operations/workflow-recipes.md` |
|
|
43
43
|
| Propagation Pipeline | `packages/sdk/docs/scaffold/operations/propagation-pipeline.md` | `scaffold/operations/propagation-pipeline.md` |
|
|
44
44
|
| This doc | `packages/sdk/docs/scaffold/operations/scaffold-maintenance.md` | `scaffold/operations/scaffold-maintenance.md` |
|
|
@@ -53,18 +53,18 @@ Two types of docs are auto-generated from source:
|
|
|
53
53
|
|
|
54
54
|
Generated by `scripts/monorepo/generate-scaffold-contracts.js` from TypeScript source types:
|
|
55
55
|
|
|
56
|
-
- `packages/core/src/organization-model/types.ts` -- Organization Model, System Model
|
|
57
|
-
- `packages/ui/src/features/registry/types.ts` -- System Registry
|
|
56
|
+
- `packages/core/src/organization-model/types.ts` -- Organization Model, System Model
|
|
57
|
+
- `packages/ui/src/features/registry/types.ts` -- System Registry
|
|
58
58
|
- `packages/core/src/platform/registry/types.ts` -- Resource Registry, Deployment Spec
|
|
59
59
|
|
|
60
60
|
Output: `packages/core/src/reference/_generated/contracts.md`
|
|
61
61
|
|
|
62
|
-
### System Registry (`feature-registry.md`)
|
|
63
|
-
|
|
64
|
-
Generated by `scripts/monorepo/generate-scaffold-feature-registry.js` from system manifests:
|
|
65
|
-
|
|
66
|
-
- `packages/ui/src/features/*/manifest.ts` -- individual system manifests
|
|
67
|
-
- `packages/ui/src/features/registry/manifests.ts` -- `SYSTEM_MANIFESTS`
|
|
62
|
+
### System Registry (`feature-registry.md`)
|
|
63
|
+
|
|
64
|
+
Generated by `scripts/monorepo/generate-scaffold-feature-registry.js` from system manifests:
|
|
65
|
+
|
|
66
|
+
- `packages/ui/src/features/*/manifest.ts` -- individual system manifests
|
|
67
|
+
- `packages/ui/src/features/registry/manifests.ts` -- `SYSTEM_MANIFESTS`
|
|
68
68
|
|
|
69
69
|
Output: `packages/ui/src/scaffold/_generated/feature-registry.md`
|
|
70
70
|
|
|
@@ -16,29 +16,29 @@ description: Anatomy of a workflow, adapter usage, and trigger patterns -- runna
|
|
|
16
16
|
|
|
17
17
|
Every workflow is a `WorkflowDefinition` object with four top-level keys: `config`, `contract`, `steps`, and `entryPoint`. The `email-notification` workflow at `operations/src/email-notification/index.ts` is used as the running example throughout this section.
|
|
18
18
|
|
|
19
|
-
### Config
|
|
20
|
-
|
|
21
|
-
```typescript
|
|
22
|
-
import { resourceDescriptors } from '@core/config/organization-model'
|
|
23
|
-
|
|
24
|
-
config: {
|
|
25
|
-
resource: resourceDescriptors.emailNotification,
|
|
26
|
-
resourceId: resourceDescriptors.emailNotification.id,
|
|
27
|
-
name: 'Email Notification',
|
|
28
|
-
type: resourceDescriptors.emailNotification.kind,
|
|
29
|
-
description: 'Sends a notification email to a user...',
|
|
30
|
-
version: '1.0.0',
|
|
31
|
-
status: 'dev'
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
- The OM Resources descriptor owns the stable ID and kind. Runtime execution still uses that deployed `resourceId`, but workflow authoring should derive it from the descriptor.
|
|
36
|
-
- Bump `version` whenever you change `contract.inputSchema` or `contract.outputSchema`.
|
|
19
|
+
### Config
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { resourceDescriptors } from '@core/config/organization-model'
|
|
23
|
+
|
|
24
|
+
config: {
|
|
25
|
+
resource: resourceDescriptors.emailNotification,
|
|
26
|
+
resourceId: resourceDescriptors.emailNotification.id,
|
|
27
|
+
name: 'Email Notification',
|
|
28
|
+
type: resourceDescriptors.emailNotification.kind,
|
|
29
|
+
description: 'Sends a notification email to a user...',
|
|
30
|
+
version: '1.0.0',
|
|
31
|
+
status: 'dev'
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- The OM Resources descriptor owns the stable ID and kind. Runtime execution still uses that deployed `resourceId`, but workflow authoring should derive it from the descriptor.
|
|
36
|
+
- Bump `version` whenever you change `contract.inputSchema` or `contract.outputSchema`.
|
|
37
37
|
|
|
38
38
|
### Contract
|
|
39
39
|
|
|
40
40
|
```typescript
|
|
41
|
-
// core/types/index.ts -- shared with frontend
|
|
41
|
+
// core/types/index.ts -- shared with frontend
|
|
42
42
|
export const emailNotificationInputSchema = z.object({
|
|
43
43
|
recipientEmail: z.string().email(),
|
|
44
44
|
recipientName: z.string().min(1),
|
|
@@ -60,7 +60,7 @@ export type EmailNotificationOutput = z.infer<typeof emailNotificationOutputSche
|
|
|
60
60
|
|
|
61
61
|
```typescript
|
|
62
62
|
// operations/src/email-notification/index.ts
|
|
63
|
-
import { emailNotificationInputSchema, emailNotificationOutputSchema } from '@core/types'
|
|
63
|
+
import { emailNotificationInputSchema, emailNotificationOutputSchema } from '@core/types'
|
|
64
64
|
|
|
65
65
|
contract: {
|
|
66
66
|
inputSchema: emailNotificationInputSchema,
|
|
@@ -70,16 +70,16 @@ contract: {
|
|
|
70
70
|
|
|
71
71
|
**Rules:**
|
|
72
72
|
|
|
73
|
-
- Define schemas in `core/types/index.ts` -- never inline Zod schemas in workflow files.
|
|
74
|
-
- Both runtimes (frontend and platform) import from `@core/types`, keeping validation consistent.
|
|
75
|
-
- `@core/types` resolves to `core/types/index.ts` via the tsconfig path alias.
|
|
73
|
+
- Define schemas in `core/types/index.ts` -- never inline Zod schemas in workflow files.
|
|
74
|
+
- Both runtimes (frontend and platform) import from `@core/types`, keeping validation consistent.
|
|
75
|
+
- `@core/types` resolves to `core/types/index.ts` via the tsconfig path alias.
|
|
76
76
|
|
|
77
77
|
**Entity-backed workflows:** for workflows that operate on a domain entity, reference the entity contract rather than redeclaring it.
|
|
78
78
|
|
|
79
79
|
```typescript
|
|
80
|
-
// core/types/index.ts
|
|
80
|
+
// core/types/index.ts
|
|
81
81
|
import { BaseDealSchema } from '@elevasis/core/entities'
|
|
82
|
-
import { DealSchema } from '@core/types/entities' // project-local extended version
|
|
82
|
+
import { DealSchema } from '@core/types/entities' // project-local extended version
|
|
83
83
|
|
|
84
84
|
export const closeDealInputSchema = z.object({
|
|
85
85
|
deal: DealSchema,
|
|
@@ -89,7 +89,7 @@ export const closeDealInputSchema = z.object({
|
|
|
89
89
|
export type CloseDealInput = z.infer<typeof closeDealInputSchema>
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
`DealSchema` is defined in `core/types/entities.ts` by extending `BaseDealSchema` with project-specific metadata. See [../recipes/extend-a-base-entity.md](../recipes/extend-a-base-entity.md) for the pattern.
|
|
92
|
+
`DealSchema` is defined in `core/types/entities.ts` by extending `BaseDealSchema` with project-specific metadata. See [../recipes/extend-a-base-entity.md](../recipes/extend-a-base-entity.md) for the pattern.
|
|
93
93
|
|
|
94
94
|
### Steps
|
|
95
95
|
|
|
@@ -297,7 +297,7 @@ Use this pattern in React components and hooks. `apiRequest` automatically attac
|
|
|
297
297
|
// ui/src/features/notifications/hooks/useSendEmailNotification.ts
|
|
298
298
|
import { useMutation } from '@tanstack/react-query'
|
|
299
299
|
import { useApiClient } from '@/lib/hooks/useApiClient'
|
|
300
|
-
import type { EmailNotificationInput, EmailNotificationOutput } from '@core/types'
|
|
300
|
+
import type { EmailNotificationInput, EmailNotificationOutput } from '@core/types'
|
|
301
301
|
|
|
302
302
|
export function useSendEmailNotification() {
|
|
303
303
|
const { apiRequest } = useApiClient()
|
|
@@ -392,7 +392,7 @@ pnpm exec elevasis --prod exec Elevasis/email-notification --input '{...}'
|
|
|
392
392
|
|
|
393
393
|
## 4. Registry Pattern
|
|
394
394
|
|
|
395
|
-
Workflows are discovered through `operations/src/index.ts`, which exports a `DeploymentSpec` as its default export. The spec assembles deployable runtime resources; it is not a second resource identity catalog.
|
|
395
|
+
Workflows are discovered through `operations/src/index.ts`, which exports a `DeploymentSpec` as its default export. The spec assembles deployable runtime resources; it is not a second resource identity catalog.
|
|
396
396
|
|
|
397
397
|
**Pattern:** each feature group in `operations/src/` has its own exports barrel. The top-level spec spreads all groups:
|
|
398
398
|
|
|
@@ -410,17 +410,17 @@ operations/src/
|
|
|
410
410
|
Top-level registry (`operations/src/index.ts`):
|
|
411
411
|
|
|
412
412
|
```typescript
|
|
413
|
-
import type { DeploymentSpec } from '@elevasis/sdk'
|
|
414
|
-
import { resourceGovernanceModel } from '@core/config/organization-model'
|
|
415
|
-
import * as example from './example/index.js'
|
|
416
|
-
import * as emailNotification from './email-notification/exports.js'
|
|
417
|
-
|
|
418
|
-
const org: DeploymentSpec = {
|
|
419
|
-
version: '0.1.0',
|
|
420
|
-
organizationModel: resourceGovernanceModel,
|
|
421
|
-
workflows: [...example.workflows, ...emailNotification.workflows],
|
|
422
|
-
agents: [...example.agents, ...emailNotification.agents]
|
|
423
|
-
}
|
|
413
|
+
import type { DeploymentSpec } from '@elevasis/sdk'
|
|
414
|
+
import { resourceGovernanceModel } from '@core/config/organization-model'
|
|
415
|
+
import * as example from './example/index.js'
|
|
416
|
+
import * as emailNotification from './email-notification/exports.js'
|
|
417
|
+
|
|
418
|
+
const org: DeploymentSpec = {
|
|
419
|
+
version: '0.1.0',
|
|
420
|
+
organizationModel: resourceGovernanceModel,
|
|
421
|
+
workflows: [...example.workflows, ...emailNotification.workflows],
|
|
422
|
+
agents: [...example.agents, ...emailNotification.agents]
|
|
423
|
+
}
|
|
424
424
|
export default org
|
|
425
425
|
```
|
|
426
426
|
|
|
@@ -436,103 +436,103 @@ export const agents: never[] = []
|
|
|
436
436
|
|
|
437
437
|
**Adding a new workflow:**
|
|
438
438
|
|
|
439
|
-
1. Add the resource descriptor to `core/config/organization-model.ts`.
|
|
440
|
-
2. Create `operations/src/<feature>/index.ts` with the `WorkflowDefinition`, deriving `config.resourceId` and `config.type` from the descriptor.
|
|
441
|
-
3. Create `operations/src/<feature>/exports.ts` with `workflows` and `agents` arrays.
|
|
442
|
-
4. Import the group barrel in `operations/src/index.ts` and spread into `workflows`/`agents`.
|
|
443
|
-
5. Run `pnpm -C operations check` to validate descriptor/code alignment, then `pnpm -C operations deploy` to publish.
|
|
439
|
+
1. Add the resource descriptor to `core/config/organization-model.ts`.
|
|
440
|
+
2. Create `operations/src/<feature>/index.ts` with the `WorkflowDefinition`, deriving `config.resourceId` and `config.type` from the descriptor.
|
|
441
|
+
3. Create `operations/src/<feature>/exports.ts` with `workflows` and `agents` arrays.
|
|
442
|
+
4. Import the group barrel in `operations/src/index.ts` and spread into `workflows`/`agents`.
|
|
443
|
+
5. Run `pnpm -C operations check` to validate descriptor/code alignment, then `pnpm -C operations deploy` to publish.
|
|
444
444
|
|
|
445
|
-
**Note:** Use `.js` extensions in imports even though the source is TypeScript. The TypeScript compiler and esbuild bundler both require this for ESM interoperability.
|
|
446
|
-
|
|
447
|
-
---
|
|
448
|
-
|
|
449
|
-
## 5. Testing Custom Workflows And UI
|
|
450
|
-
|
|
451
|
-
Package-owned test helpers are the stable way to test custom downstream code. Do not copy template-only tests into a project unless the project owns the matching workflow, route, or component.
|
|
452
|
-
|
|
453
|
-
After the bundled package release lands, use these public subpaths:
|
|
454
|
-
|
|
455
|
-
```typescript
|
|
456
|
-
import { makeProject } from '@elevasis/core/test-utils'
|
|
457
|
-
import { renderWithProviders, mockAuthenticatedUser } from '@elevasis/ui/test-utils'
|
|
458
|
-
import { assertResourceRegistry, mockNotifications, runWorkflow } from '@elevasis/sdk/test-utils'
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
### Workflow Smoke Test
|
|
462
|
-
|
|
463
|
-
Use `runWorkflow` for project-owned workflows. This tests the workflow contract, step execution, and parsed output without deploying.
|
|
464
|
-
|
|
465
|
-
```typescript
|
|
466
|
-
import { describe, expect, it } from 'vitest'
|
|
467
|
-
import { runWorkflow, mockNotifications } from '@elevasis/sdk/test-utils'
|
|
468
|
-
import { emailNotification } from './index'
|
|
469
|
-
import type { EmailNotificationOutput } from '@core/types'
|
|
470
|
-
|
|
471
|
-
describe('emailNotification workflow', () => {
|
|
472
|
-
it('runs the notify step with a mocked notification adapter', async () => {
|
|
473
|
-
const notifications = mockNotifications({
|
|
474
|
-
create: { id: 'notification-1' }
|
|
475
|
-
})
|
|
476
|
-
|
|
477
|
-
const result = await runWorkflow<EmailNotificationOutput>(
|
|
478
|
-
emailNotification,
|
|
479
|
-
{
|
|
480
|
-
recipientEmail: 'jane@example.com',
|
|
481
|
-
recipientName: 'Jane',
|
|
482
|
-
subject: 'Action ready',
|
|
483
|
-
body: 'Your request has been processed.'
|
|
484
|
-
},
|
|
485
|
-
{ adapters: { notification: notifications } }
|
|
486
|
-
)
|
|
487
|
-
|
|
488
|
-
expect(result.output.delivered).toBe(true)
|
|
489
|
-
expect(result.stepEvents.map((event) => event.stepId)).toContain('notify')
|
|
490
|
-
})
|
|
491
|
-
})
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
### Registry Smoke Test
|
|
495
|
-
|
|
496
|
-
Use `assertResourceRegistry` for a project-owned `operations/src/index.ts` manifest. Keep assertions generic unless the project intentionally owns a fixed workflow list.
|
|
497
|
-
|
|
498
|
-
```typescript
|
|
499
|
-
import { describe, expect, it } from 'vitest'
|
|
500
|
-
import { assertResourceRegistry } from '@elevasis/sdk/test-utils'
|
|
501
|
-
import org from './index'
|
|
502
|
-
|
|
503
|
-
describe('operations registry', () => {
|
|
504
|
-
it('registers a valid operations manifest', () => {
|
|
505
|
-
const spec = assertResourceRegistry(org, { organizationName: 'Example Project' })
|
|
506
|
-
const workflows = spec.workflows ?? []
|
|
507
|
-
|
|
508
|
-
expect(workflows.length + (spec.agents?.length ?? 0)).toBeGreaterThan(0)
|
|
509
|
-
expect(new Set(workflows.map((workflow) => workflow.config.resourceId)).size).toBe(workflows.length)
|
|
510
|
-
})
|
|
511
|
-
})
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
### UI And Core Fixtures
|
|
515
|
-
|
|
516
|
-
Use `@elevasis/ui/test-utils` for route/component tests and `@elevasis/core/test-utils` for schema-compatible fixtures.
|
|
517
|
-
|
|
518
|
-
```tsx
|
|
519
|
-
import { describe, expect, it } from 'vitest'
|
|
520
|
-
import { screen } from '@testing-library/react'
|
|
521
|
-
import { makeProject } from '@elevasis/core/test-utils'
|
|
522
|
-
import { mockAuthenticatedUser, renderWithProviders } from '@elevasis/ui/test-utils'
|
|
523
|
-
import { ProjectCard } from './ProjectCard'
|
|
524
|
-
|
|
525
|
-
describe('ProjectCard', () => {
|
|
526
|
-
it('renders a project fixture for an authenticated user', () => {
|
|
527
|
-
const project = makeProject({ name: 'Website Refresh' })
|
|
528
|
-
|
|
529
|
-
renderWithProviders(<ProjectCard project={project} />, {
|
|
530
|
-
auth: mockAuthenticatedUser()
|
|
531
|
-
})
|
|
532
|
-
|
|
533
|
-
expect(screen.getByText('Website Refresh')).toBeInTheDocument()
|
|
534
|
-
})
|
|
535
|
-
})
|
|
536
|
-
```
|
|
537
|
-
|
|
538
|
-
Template tests are examples and smoke coverage. Downstream projects should keep custom tests close to the feature they validate, then consume these package helpers instead of copying scaffold internals.
|
|
445
|
+
**Note:** Use `.js` extensions in imports even though the source is TypeScript. The TypeScript compiler and esbuild bundler both require this for ESM interoperability.
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## 5. Testing Custom Workflows And UI
|
|
450
|
+
|
|
451
|
+
Package-owned test helpers are the stable way to test custom downstream code. Do not copy template-only tests into a project unless the project owns the matching workflow, route, or component.
|
|
452
|
+
|
|
453
|
+
After the bundled package release lands, use these public subpaths:
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
import { makeProject } from '@elevasis/core/test-utils'
|
|
457
|
+
import { renderWithProviders, mockAuthenticatedUser } from '@elevasis/ui/test-utils'
|
|
458
|
+
import { assertResourceRegistry, mockNotifications, runWorkflow } from '@elevasis/sdk/test-utils'
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Workflow Smoke Test
|
|
462
|
+
|
|
463
|
+
Use `runWorkflow` for project-owned workflows. This tests the workflow contract, step execution, and parsed output without deploying.
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
import { describe, expect, it } from 'vitest'
|
|
467
|
+
import { runWorkflow, mockNotifications } from '@elevasis/sdk/test-utils'
|
|
468
|
+
import { emailNotification } from './index'
|
|
469
|
+
import type { EmailNotificationOutput } from '@core/types'
|
|
470
|
+
|
|
471
|
+
describe('emailNotification workflow', () => {
|
|
472
|
+
it('runs the notify step with a mocked notification adapter', async () => {
|
|
473
|
+
const notifications = mockNotifications({
|
|
474
|
+
create: { id: 'notification-1' }
|
|
475
|
+
})
|
|
476
|
+
|
|
477
|
+
const result = await runWorkflow<EmailNotificationOutput>(
|
|
478
|
+
emailNotification,
|
|
479
|
+
{
|
|
480
|
+
recipientEmail: 'jane@example.com',
|
|
481
|
+
recipientName: 'Jane',
|
|
482
|
+
subject: 'Action ready',
|
|
483
|
+
body: 'Your request has been processed.'
|
|
484
|
+
},
|
|
485
|
+
{ adapters: { notification: notifications } }
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
expect(result.output.delivered).toBe(true)
|
|
489
|
+
expect(result.stepEvents.map((event) => event.stepId)).toContain('notify')
|
|
490
|
+
})
|
|
491
|
+
})
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Registry Smoke Test
|
|
495
|
+
|
|
496
|
+
Use `assertResourceRegistry` for a project-owned `operations/src/index.ts` manifest. Keep assertions generic unless the project intentionally owns a fixed workflow list.
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
import { describe, expect, it } from 'vitest'
|
|
500
|
+
import { assertResourceRegistry } from '@elevasis/sdk/test-utils'
|
|
501
|
+
import org from './index'
|
|
502
|
+
|
|
503
|
+
describe('operations registry', () => {
|
|
504
|
+
it('registers a valid operations manifest', () => {
|
|
505
|
+
const spec = assertResourceRegistry(org, { organizationName: 'Example Project' })
|
|
506
|
+
const workflows = spec.workflows ?? []
|
|
507
|
+
|
|
508
|
+
expect(workflows.length + (spec.agents?.length ?? 0)).toBeGreaterThan(0)
|
|
509
|
+
expect(new Set(workflows.map((workflow) => workflow.config.resourceId)).size).toBe(workflows.length)
|
|
510
|
+
})
|
|
511
|
+
})
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### UI And Core Fixtures
|
|
515
|
+
|
|
516
|
+
Use `@elevasis/ui/test-utils` for route/component tests and `@elevasis/core/test-utils` for schema-compatible fixtures.
|
|
517
|
+
|
|
518
|
+
```tsx
|
|
519
|
+
import { describe, expect, it } from 'vitest'
|
|
520
|
+
import { screen } from '@testing-library/react'
|
|
521
|
+
import { makeProject } from '@elevasis/core/test-utils'
|
|
522
|
+
import { mockAuthenticatedUser, renderWithProviders } from '@elevasis/ui/test-utils'
|
|
523
|
+
import { ProjectCard } from './ProjectCard'
|
|
524
|
+
|
|
525
|
+
describe('ProjectCard', () => {
|
|
526
|
+
it('renders a project fixture for an authenticated user', () => {
|
|
527
|
+
const project = makeProject({ name: 'Website Refresh' })
|
|
528
|
+
|
|
529
|
+
renderWithProviders(<ProjectCard project={project} />, {
|
|
530
|
+
auth: mockAuthenticatedUser()
|
|
531
|
+
})
|
|
532
|
+
|
|
533
|
+
expect(screen.getByText('Website Refresh')).toBeInTheDocument()
|
|
534
|
+
})
|
|
535
|
+
})
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
Template tests are examples and smoke coverage. Downstream projects should keep custom tests close to the feature they validate, then consume these package helpers instead of copying scaffold internals.
|