@synap-core/workspace-templates 0.9.2 → 0.9.3
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/index.d.ts +170 -8
- package/dist/index.js +643 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/business-developer.yaml +24 -6
- package/src/content-os.yaml +19 -0
- package/src/crm.yaml +28 -2
- package/src/define.primary-surface.test.ts +183 -0
- package/src/define.ts +142 -19
- package/src/index.ts +26 -3
- package/src/marketing.yaml +19 -0
- package/src/templates.ts +126 -8
- package/src/types.ts +74 -5
- package/src/validate-flow.drift.test.ts +83 -0
- package/src/validate-flow.ts +555 -0
- package/src/validate.test.ts +121 -0
- package/src/validate.ts +133 -10
package/dist/index.d.ts
CHANGED
|
@@ -15,12 +15,55 @@ interface TemplateAppRef {
|
|
|
15
15
|
/** For kind='stored': the cell key registered in the cell registry */
|
|
16
16
|
cellKey?: string;
|
|
17
17
|
/** For kind='stored': default props passed to the cell */
|
|
18
|
-
props?: Record<string,
|
|
18
|
+
props?: Record<string, WorkspaceJsonValue>;
|
|
19
19
|
/** For kind='url': external URL to open */
|
|
20
20
|
url?: string;
|
|
21
21
|
/** Human label */
|
|
22
22
|
title?: string;
|
|
23
23
|
}
|
|
24
|
+
type WorkspaceJsonValue = string | number | boolean | null | WorkspaceJsonValue[] | {
|
|
25
|
+
[key: string]: WorkspaceJsonValue;
|
|
26
|
+
};
|
|
27
|
+
type WorkspacePrimarySurface = {
|
|
28
|
+
kind: 'app';
|
|
29
|
+
appId: string;
|
|
30
|
+
rendererType: 'native';
|
|
31
|
+
title?: string;
|
|
32
|
+
props?: Record<string, WorkspaceJsonValue>;
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'app';
|
|
35
|
+
appId: string;
|
|
36
|
+
rendererType: 'external';
|
|
37
|
+
url: string;
|
|
38
|
+
title?: string;
|
|
39
|
+
props?: Record<string, WorkspaceJsonValue>;
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'cell';
|
|
42
|
+
cellKey: string;
|
|
43
|
+
title?: string;
|
|
44
|
+
props?: Record<string, WorkspaceJsonValue>;
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'view';
|
|
47
|
+
viewId: string;
|
|
48
|
+
title?: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Authoring-time view reference. View IDs do not exist until provisioning, so
|
|
52
|
+
* templates and packages address a view by its stable authored name and/or
|
|
53
|
+
* slug. The pod resolves this to `WorkspacePrimarySurface` before persistence.
|
|
54
|
+
*/
|
|
55
|
+
type WorkspacePrimarySurfaceViewReference = {
|
|
56
|
+
kind: 'view';
|
|
57
|
+
viewName: string;
|
|
58
|
+
viewSlug?: string;
|
|
59
|
+
title?: string;
|
|
60
|
+
} | {
|
|
61
|
+
kind: 'view';
|
|
62
|
+
viewName?: string;
|
|
63
|
+
viewSlug: string;
|
|
64
|
+
title?: string;
|
|
65
|
+
};
|
|
66
|
+
type TemplatePrimarySurface = WorkspacePrimarySurface | WorkspacePrimarySurfaceViewReference;
|
|
24
67
|
interface TemplateProperty {
|
|
25
68
|
slug: string;
|
|
26
69
|
label: string;
|
|
@@ -41,8 +84,7 @@ interface TemplateProfile {
|
|
|
41
84
|
* Visibility of the profile DEFINITION — who can USE this vocabulary.
|
|
42
85
|
* `system` = pod-wide; `shared` = ONE row reachable from other workspaces via
|
|
43
86
|
* a `profile_workspace_access` grant; omit or `workspace` = this workspace
|
|
44
|
-
* only. Orthogonal to `entityScope` below — do not conflate the two axes.
|
|
45
|
-
*/
|
|
87
|
+
* only. Orthogonal to `entityScope` below — do not conflate the two axes. */
|
|
46
88
|
scope?: string;
|
|
47
89
|
/**
|
|
48
90
|
* Placement of the profile's ENTITY ROWS — where the data LANDS.
|
|
@@ -64,7 +106,7 @@ interface TemplateProfile {
|
|
|
64
106
|
/** Semantic slug for system profiles. */
|
|
65
107
|
semanticSlug?: string;
|
|
66
108
|
/** Kind vs role profile. Omit for default ('kind'). */
|
|
67
|
-
profileKind?:
|
|
109
|
+
profileKind?: 'kind' | 'role';
|
|
68
110
|
/** For profileKind='role': which base-kind profile slugs this role can attach to. */
|
|
69
111
|
applicableKinds?: string[];
|
|
70
112
|
properties: TemplateProperty[];
|
|
@@ -149,7 +191,14 @@ interface TemplateSidebarItem {
|
|
|
149
191
|
interface TemplateLayoutConfig {
|
|
150
192
|
pinnedApps?: string[];
|
|
151
193
|
defaultView?: string;
|
|
152
|
-
/**
|
|
194
|
+
/**
|
|
195
|
+
* Canonical first screen for this workspace.
|
|
196
|
+
*
|
|
197
|
+
* `undefined` means the template has no opinion during reconciliation,
|
|
198
|
+
* `null` explicitly returns the workspace to its home surface, and a
|
|
199
|
+
* descriptor replaces the current primary surface. */
|
|
200
|
+
primarySurface?: TemplatePrimarySurface | null;
|
|
201
|
+
/** Compatibility input only. New templates should use `app:` or `primarySurface`. */
|
|
153
202
|
defaultApp?: string | null;
|
|
154
203
|
theme?: string;
|
|
155
204
|
sidebarItems?: TemplateSidebarItem[];
|
|
@@ -1036,8 +1085,8 @@ declare function groupByDomain<T>(items: readonly T[], domainOf: (item: T) => st
|
|
|
1036
1085
|
* • `scripts/check-converters.mjs` — injects the real converters, exits non-zero.
|
|
1037
1086
|
* • CP / pod / CLI (from dist) — import `validateTemplate` + `SYSTEM_PROFILES`.
|
|
1038
1087
|
*
|
|
1039
|
-
*
|
|
1040
|
-
* Node's type-stripping BEFORE `tsup` builds `dist/`. A static
|
|
1088
|
+
* NO RUNTIME IMPORT THAT FAILS AT STRIP-TIME. `build.mjs` loads this file
|
|
1089
|
+
* directly under Node's type-stripping BEFORE `tsup` builds `dist/`. A static
|
|
1041
1090
|
* `import { toWorkspaceDefinition } from "./define.js"` would fail to resolve at
|
|
1042
1091
|
* that moment (define → templates.js does not exist pre-build, and Node's
|
|
1043
1092
|
* type-stripper does not remap a `.js` specifier to its `.ts` source). So the
|
|
@@ -1045,6 +1094,14 @@ declare function groupByDomain<T>(items: readonly T[], domainOf: (item: T) => st
|
|
|
1045
1094
|
* YAML/bento rules run everywhere; the converter-parity rules run wherever the
|
|
1046
1095
|
* caller can supply the compiled converters (check-converters.mjs, from dist).
|
|
1047
1096
|
* `import type` lines are fully erased by the type-stripper, so they are safe.
|
|
1097
|
+
*
|
|
1098
|
+
* THE ONE RUNTIME IMPORT: `./validate-flow.ts` (the pure automation-flow
|
|
1099
|
+
* validator). It is imported with the `.ts` extension SPECIFICALLY so it resolves
|
|
1100
|
+
* under Node's type-stripper at build.mjs time (a `.js` specifier would NOT — see
|
|
1101
|
+
* above), and it has NO generated dependency (unlike `./define.js` → templates)
|
|
1102
|
+
* so it is always present. It is DB-free (only `import type` internally), so it
|
|
1103
|
+
* needs no injection: the flow-node contract check runs for every caller
|
|
1104
|
+
* (build / check-converters / CLI / CP) automatically.
|
|
1048
1105
|
*/
|
|
1049
1106
|
|
|
1050
1107
|
interface ValidationError {
|
|
@@ -1159,6 +1216,103 @@ declare function collectBaseProfileSlugs(data: WorkspaceYaml, resolveDep: (slug:
|
|
|
1159
1216
|
*/
|
|
1160
1217
|
declare function validateTemplate(tpl: WorkspaceYaml, opts?: ValidateOptions): ValidateResult;
|
|
1161
1218
|
|
|
1219
|
+
/**
|
|
1220
|
+
* Node-contract validation for automation flow definitions.
|
|
1221
|
+
*
|
|
1222
|
+
* The persist doors and the install/apply doors validate flow SHAPE only
|
|
1223
|
+
* (`{ nodes: [], edges: [] }`). A semantically-broken flow — a `channel_message`
|
|
1224
|
+
* output with a typo'd `channelType`, a `capability` node with no `verbId`, an
|
|
1225
|
+
* edge to a nonexistent node, a cycle, an unknown `node.type` — passes the shape
|
|
1226
|
+
* check and only fails at RUNTIME (automation-executor.ts throws mid-run). For a
|
|
1227
|
+
* template automation this is worse: it validates green at author time and then
|
|
1228
|
+
* SILENTLY never fires on a live pod.
|
|
1229
|
+
*
|
|
1230
|
+
* `validateFlowDefinition` closes that gap: a PURE, synchronous, DB-free function
|
|
1231
|
+
* that rejects malformed flows with actionable per-node errors. It is called by
|
|
1232
|
+
* `validateTemplate` (this package) so `synap market validate` / the build gate /
|
|
1233
|
+
* the CP publish door all run the same contract check, and by the pod's persist
|
|
1234
|
+
* doors.
|
|
1235
|
+
*
|
|
1236
|
+
* ── SSOT-IN-WAITING — temporary duplicate ────────────────────────────────────
|
|
1237
|
+
* This is a PURE copy of synap-backend's
|
|
1238
|
+
* `packages/api/src/services/automations/validate-flow.ts` (the current runtime
|
|
1239
|
+
* SSOT, which carries the `@synap/database` COMPILE-TIME drift guard). This copy
|
|
1240
|
+
* exists so `validateTemplate` — which runs in THIS published, backend-independent
|
|
1241
|
+
* package (CLI `synap market validate` / build gate / CP publish) — can catch
|
|
1242
|
+
* broken automation flows at AUTHOR time. It is intentionally free of any
|
|
1243
|
+
* `@synap/database` import (this package depends only on zod + js-yaml), so the
|
|
1244
|
+
* compile-time drift guard cannot live here; it stays in backend.
|
|
1245
|
+
*
|
|
1246
|
+
* The two copies are kept byte-identical (logic) by `validate-flow.drift.test.ts`
|
|
1247
|
+
* in this package, which reads BOTH files and fails if they diverge.
|
|
1248
|
+
*
|
|
1249
|
+
* CUTOVER (collapse to ONE SSOT): publish `@synap-core/workspace-templates`, bump
|
|
1250
|
+
* synap-backend (`^0.7.1`) and CP (`^0.9.2`) deps to that version, then replace
|
|
1251
|
+
* backend's validate-flow.ts body with a re-export FROM HERE (keeping backend's
|
|
1252
|
+
* `AssertExact` guard binding these arrays to the `@synap/database` unions).
|
|
1253
|
+
* Until then: keep the constant arrays below identical to `@synap/database`
|
|
1254
|
+
* `schema/automations.ts`.
|
|
1255
|
+
*/
|
|
1256
|
+
/** The 21 node types — `AutomationNodeBase.type` union (schema/automations.ts). */
|
|
1257
|
+
declare const FLOW_NODE_TYPES: readonly ["trigger", "command", "condition", "delay", "output", "loop", "transform", "fetch", "query", "entity_read", "related_entities", "guard", "compute", "select", "claim", "messages_query", "switch", "skill", "capability", "sub_automation", "playbook_run"];
|
|
1258
|
+
/** The 11 output types — `OutputNodeDef.data.outputType` (schema/automations.ts). */
|
|
1259
|
+
declare const FLOW_OUTPUT_TYPES: readonly ["notification", "entity_create", "entity_update", "facet_attach", "facet_update", "facet_detach", "relation_create", "webhook", "channel_message", "session_update", "set_state"];
|
|
1260
|
+
/**
|
|
1261
|
+
* The known `config.channelType` values for a `channel_message` output. Mirrors
|
|
1262
|
+
* the executor's channel_message resolution (automation-executor.ts). The output
|
|
1263
|
+
* channel is CONTEXT-DERIVED — a channel_message is valid with `channelId`, OR
|
|
1264
|
+
* `channelEntityRef` (an entity-id expression → that entity's internal channel),
|
|
1265
|
+
* OR a `channelType` from this set, OR NOTHING (the executor defaults a targetless
|
|
1266
|
+
* channel_message to the automation's own run channel). A `channelType` that is
|
|
1267
|
+
* PRESENT but not one of these is still a typo → still an error.
|
|
1268
|
+
*/
|
|
1269
|
+
declare const CHANNEL_MESSAGE_CHANNEL_TYPES: readonly ["personal_thread", "proactive", "subjectEntity"];
|
|
1270
|
+
interface FlowValidationError {
|
|
1271
|
+
/** Node the error is about (absent for graph-level / edge-level errors). */
|
|
1272
|
+
nodeId?: string;
|
|
1273
|
+
/** Edge the error is about (for dangling-reference / bad-handle errors). */
|
|
1274
|
+
edgeId?: string;
|
|
1275
|
+
/** Stable machine code — see the `code` literals below. */
|
|
1276
|
+
code: string;
|
|
1277
|
+
/** Human-actionable message naming what is wrong and how to fix it. */
|
|
1278
|
+
message: string;
|
|
1279
|
+
}
|
|
1280
|
+
interface FlowValidationResult {
|
|
1281
|
+
valid: boolean;
|
|
1282
|
+
errors: FlowValidationError[];
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* Optional catalog resolvers. When provided, existence checks run; when omitted,
|
|
1286
|
+
* those checks are SKIPPED (structural + contract checks always run). Kept
|
|
1287
|
+
* synchronous so the whole function stays pure — the caller pre-loads whatever
|
|
1288
|
+
* it needs and passes predicates.
|
|
1289
|
+
*/
|
|
1290
|
+
interface FlowValidationResolvers {
|
|
1291
|
+
/** Does this capability verb (skill name) exist in the workspace catalog? */
|
|
1292
|
+
verbExists?: (verbId: string) => boolean;
|
|
1293
|
+
/** Does the referenced skill exist (by id OR by name)? */
|
|
1294
|
+
skillExists?: (ref: {
|
|
1295
|
+
skillId?: string;
|
|
1296
|
+
skillName?: string;
|
|
1297
|
+
}) => boolean;
|
|
1298
|
+
/** Does the referenced playbook exist? */
|
|
1299
|
+
playbookExists?: (ref: {
|
|
1300
|
+
playbookId?: string;
|
|
1301
|
+
playbookName?: string;
|
|
1302
|
+
}) => boolean;
|
|
1303
|
+
}
|
|
1304
|
+
/**
|
|
1305
|
+
* Validate an automation flow definition against the node contract.
|
|
1306
|
+
* Pure and synchronous. `resolvers` gate the catalog-existence checks only.
|
|
1307
|
+
*/
|
|
1308
|
+
declare function validateFlowDefinition(flow: unknown, resolvers?: FlowValidationResolvers): FlowValidationResult;
|
|
1309
|
+
/**
|
|
1310
|
+
* Convenience helper for the persist doors: run the validator and, if invalid,
|
|
1311
|
+
* return a single joined actionable message (else null). Keeps the door code a
|
|
1312
|
+
* one-liner and the message format consistent across create/update.
|
|
1313
|
+
*/
|
|
1314
|
+
declare function flowValidationErrorMessage(flow: unknown, resolvers?: FlowValidationResolvers): string | null;
|
|
1315
|
+
|
|
1162
1316
|
/**
|
|
1163
1317
|
* @synap-core/workspace-templates — Definition adapter
|
|
1164
1318
|
*
|
|
@@ -1207,6 +1361,14 @@ interface SplitBentoBlocks {
|
|
|
1207
1361
|
bentoLayout: BentoWidgetBlockWire[];
|
|
1208
1362
|
bentoViewBlocks: BentoViewBlockWire[];
|
|
1209
1363
|
}
|
|
1364
|
+
/**
|
|
1365
|
+
* Produce the canonical persisted layout. A template may author either the
|
|
1366
|
+
* top-level `app:` shorthand or an explicit `layout.primarySurface`, never both.
|
|
1367
|
+
* Legacy `defaultApp` is the final compatibility fallback. Keeping the property
|
|
1368
|
+
* absent preserves a live workspace value during reconciliation; an authored
|
|
1369
|
+
* null is retained as an explicit clear.
|
|
1370
|
+
*/
|
|
1371
|
+
declare function normalizeTemplateLayout(layout: TemplateLayoutConfig | undefined, app: TemplateAppRef | undefined): TemplateLayoutConfig | undefined;
|
|
1210
1372
|
declare function splitBentoBlocks(blocks: TemplateBentoBlock[] | undefined): SplitBentoBlocks;
|
|
1211
1373
|
/** The flat definition object accepted by createFromDefinition. */
|
|
1212
1374
|
interface WorkspaceDefinitionInput {
|
|
@@ -1362,4 +1524,4 @@ interface PackageDefinitionOutput {
|
|
|
1362
1524
|
*/
|
|
1363
1525
|
declare function toPackageDefinition(slugOrYaml: string | WorkspaceYaml): PackageDefinitionOutput;
|
|
1364
1526
|
|
|
1365
|
-
export { type AssembleCatalogInput, type BentoViewBlockWire, type BentoWidgetBlockWire, type BundledCatalogEntry, type BundledEntry, type CatalogEntry, type CompositionEdge, type CompositionGraph, type CompositionInstalledEntry, type CompositionNode, type CompositionOverlay, type ConceptViolation, type CpPackageRow, DECLARED_DIVERGENCES, type DomainGroup, type InstalledTemplate, type LayerTemplateGraphInput, type MergeCatalogInput, type MergeCatalogResult, OTHER_DOMAIN_ID, OTHER_DOMAIN_LABEL, PACKAGE_DEPENDENCY_KINDS, type PackageDefinitionOutput, type PackageDependencyKind, REQUIRED_META_FIELDS, REQUIRED_WORKSPACE_FIELDS, type RemoteCatalogEntry, type RemoteEntry, type RemoteSourceStatus, SYSTEM_PROFILES, type SplitBentoBlocks, TEMPLATE_DOMAINS, type TemplateActionPlacement, type TemplateAppKind, type TemplateAppRef, type TemplateAutomation, type TemplateBentoBlock, type TemplateConverters, type TemplateDefaultSource, type TemplateDependency, type TemplateDisplayTemplate, type TemplateDomain, type TemplateEntityLink, type TemplateExtendsRef, type TemplateIntegration, type TemplateLayoutConfig, type TemplateMeta, type TemplateOnboarding, type TemplateOnboardingCollectTarget, type TemplatePlaybook, type TemplatePlaybookParam, type TemplateProfile, type TemplateProfileEntityBentoTemplates, type TemplateProperty, type TemplateSeedEntity, type TemplateSidebarItem, type TemplateSidebarSurface, type TemplateSourceRole, type TemplateSuggestedRelation, type TemplateUpdateCheck, type TemplateView, type ToDefinitionResult, type ValidateOptions, type ValidateResult, type ValidationError, WORKSPACE_TEMPLATES, type WorkspaceDefinitionInput, type WorkspaceTemplateSlug, type WorkspaceYaml, assembleCatalog, bundledEdgesOf, collectBaseProfileSlugs, computeTemplateUpdates, conceptTerm, domainLabel, findConceptViolations, formatConceptViolations, getWorkspaceTemplate, groupByDomain, isHashVersion, isKnownDomain, layerTemplateGraph, listPublicTemplates, listWorkspaceTemplates, mergeCatalog, rowToRemoteEntry, splitBentoBlocks, toPackageDefinition, toWorkspaceDefinition, validateTemplate };
|
|
1527
|
+
export { type AssembleCatalogInput, type BentoViewBlockWire, type BentoWidgetBlockWire, type BundledCatalogEntry, type BundledEntry, CHANNEL_MESSAGE_CHANNEL_TYPES, type CatalogEntry, type CompositionEdge, type CompositionGraph, type CompositionInstalledEntry, type CompositionNode, type CompositionOverlay, type ConceptViolation, type CpPackageRow, DECLARED_DIVERGENCES, type DomainGroup, FLOW_NODE_TYPES, FLOW_OUTPUT_TYPES, type FlowValidationError, type FlowValidationResolvers, type FlowValidationResult, type InstalledTemplate, type LayerTemplateGraphInput, type MergeCatalogInput, type MergeCatalogResult, OTHER_DOMAIN_ID, OTHER_DOMAIN_LABEL, PACKAGE_DEPENDENCY_KINDS, type PackageDefinitionOutput, type PackageDependencyKind, REQUIRED_META_FIELDS, REQUIRED_WORKSPACE_FIELDS, type RemoteCatalogEntry, type RemoteEntry, type RemoteSourceStatus, SYSTEM_PROFILES, type SplitBentoBlocks, TEMPLATE_DOMAINS, type TemplateActionPlacement, type TemplateAppKind, type TemplateAppRef, type TemplateAutomation, type TemplateBentoBlock, type TemplateConverters, type TemplateDefaultSource, type TemplateDependency, type TemplateDisplayTemplate, type TemplateDomain, type TemplateEntityLink, type TemplateExtendsRef, type TemplateIntegration, type TemplateLayoutConfig, type TemplateMeta, type TemplateOnboarding, type TemplateOnboardingCollectTarget, type TemplatePlaybook, type TemplatePlaybookParam, type TemplatePrimarySurface, type TemplateProfile, type TemplateProfileEntityBentoTemplates, type TemplateProperty, type TemplateSeedEntity, type TemplateSidebarItem, type TemplateSidebarSurface, type TemplateSourceRole, type TemplateSuggestedRelation, type TemplateUpdateCheck, type TemplateView, type ToDefinitionResult, type ValidateOptions, type ValidateResult, type ValidationError, WORKSPACE_TEMPLATES, type WorkspaceDefinitionInput, type WorkspaceJsonValue, type WorkspacePrimarySurface, type WorkspacePrimarySurfaceViewReference, type WorkspaceTemplateSlug, type WorkspaceYaml, assembleCatalog, bundledEdgesOf, collectBaseProfileSlugs, computeTemplateUpdates, conceptTerm, domainLabel, findConceptViolations, flowValidationErrorMessage, formatConceptViolations, getWorkspaceTemplate, groupByDomain, isHashVersion, isKnownDomain, layerTemplateGraph, listPublicTemplates, listWorkspaceTemplates, mergeCatalog, normalizeTemplateLayout, rowToRemoteEntry, splitBentoBlocks, toPackageDefinition, toWorkspaceDefinition, validateFlowDefinition, validateTemplate };
|