@synap-core/workspace-templates 0.7.2 → 0.7.4

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 (44) hide show
  1. package/dist/index.d.ts +207 -8
  2. package/dist/index.js +2122 -1427
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/src/agent-fleet.yaml +666 -108
  6. package/src/blockchain-ecosystem.yaml +1 -0
  7. package/src/brand-library.yaml +127 -12
  8. package/src/builder.yaml +116 -12
  9. package/src/business-developer.yaml +102 -18
  10. package/src/catalog.ts +13 -3
  11. package/src/communication.yaml +23 -453
  12. package/src/composition-graph.test.ts +26 -0
  13. package/src/content-os.yaml +103 -10
  14. package/src/content-studio.yaml +1 -0
  15. package/src/crm.yaml +12 -0
  16. package/src/define.ts +8 -8
  17. package/src/dev-dashboard.yaml +43 -9
  18. package/src/domains.test.ts +117 -0
  19. package/src/domains.ts +102 -0
  20. package/src/ecosystem.yaml +21 -4
  21. package/src/enterprise-os.yaml +5 -0
  22. package/src/finance.yaml +46 -5
  23. package/src/foundation.yaml +13 -1
  24. package/src/grants.yaml +1 -0
  25. package/src/hr.yaml +61 -8
  26. package/src/index.ts +29 -0
  27. package/src/internal-runbook.yaml +36 -5
  28. package/src/legal.yaml +97 -12
  29. package/src/life-os.yaml +188 -27
  30. package/src/marketing.yaml +15 -2
  31. package/src/meetings-knowledge.yaml +7 -1
  32. package/src/operations.yaml +351 -0
  33. package/src/outreach-comms.yaml +6 -1
  34. package/src/project-management.yaml +840 -111
  35. package/src/research-base.yaml +516 -0
  36. package/src/research-decision.yaml +158 -0
  37. package/src/shared-role-ssot.test.ts +268 -0
  38. package/src/social.yaml +105 -37
  39. package/src/templates.ts +4573 -4302
  40. package/src/the-arch.yaml +11 -0
  41. package/src/types.ts +9 -0
  42. package/src/validate.test.ts +81 -0
  43. package/src/validate.ts +561 -0
  44. package/src/personal.yaml +0 -177
@@ -8,6 +8,7 @@
8
8
 
9
9
  meta:
10
10
  slug: communication
11
+ domain: content
11
12
  name: Communication
12
13
  description: "Owns brand identity, voice, and narrative/positioning — the on-brand source of truth every downstream domain (Content, Marketing, Social) reads from so everything ships on-brand and on-message."
13
14
  icon: messages-square
@@ -15,469 +16,32 @@ meta:
15
16
  tags: [communication, brand, narrative, voice, positioning]
16
17
  isPublic: true
17
18
 
19
+ # Compose onto Brand Library — the canonical brand SSOT owns the brand-* profiles
20
+ # (identity, colors, fonts, assets, voice guide, rules, templates, components).
21
+ # This overlay adds the STRATEGIC MESSAGING layer (positioning, narrative,
22
+ # audience, differentiator) on top, so there is ONE brand vocabulary, not two.
23
+ dependencies:
24
+ - slug: brand-library
25
+ kind: workspace
26
+ relation: compose
27
+ reason: "Layers positioning, narrative, and audience onto your Brand Library."
28
+
18
29
  workspace:
19
- name: Communication
20
- description: "Owns brand identity, voice, and narrative/positioning — the on-brand source of truth every downstream domain reads from."
21
- subtype: communication
22
- visibility: pod_visible
30
+ # Composes onto Brand Library: name + subtype MATCH the base (overlay contract),
31
+ # visibility OMITTED (the additive reconcile would clobber the base's).
32
+ name: Brand Library
33
+ description: "The strategic messaging layer — positioning, narrative, audience, and differentiators — layered onto your Brand Library."
34
+ subtype: brand-library
23
35
  capabilities:
24
- - brand.library
25
- - brand.identity
26
36
  - brand.voice
27
- - brand.assets
28
- - brand.templates
29
- - brand.components
30
37
  - narrative.positioning
31
- # Communication CONSUMES brand and PROVIDES narrative.
32
- #
33
- # `brand: provider` here was a LIVE bug, not dead metadata. brand-library.yaml
34
- # also declares `brand: provider`, and the IS reads this to pick which
35
- # workspace supplies brand for EVERY agent's system prompt
36
- # (`resolveWorkspaceForCapability` in agents/utils/context-manager.ts): it
37
- # filters candidates by the `brand.library` capability, then takes the FIRST
38
- # workspace whose sourceRoles.brand is a provider. With both installed, "first"
39
- # is whatever order listWorkspaces returned — an arbitrary, non-deterministic
40
- # brand voice across turns. brand-library is the canonical brand source (this
41
- # file's brand profiles are, by its own admission below, verbatim from it);
42
- # Communication is the narrative/voice layer that reads from it.
43
- #
44
- # Every other domain in this template set has exactly ONE provider and names
45
- # its consumers (content-studio: `brand: consumer`; marketing: `brand: consumer`).
46
- # `brand` was the only domain with two. This restores that invariant.
47
- #
48
- # Expressed as a source ROLE, not `defaultSources.brand`, because a
49
- # TemplateDefaultSource requires a concrete `workspaceId` (types.ts) that does
50
- # not exist until provisioning — a template cannot know it. finance.yaml makes
51
- # the same call for `strategy` and says so. `defaultSources` remains the
52
- # correct RUNTIME override (`synap_declare_workspace_source`).
53
- #
54
- # The `brand.library` capability above is deliberately KEPT: it is what the
55
- # resolver filters candidates on, and it makes this workspace a graceful
56
- # fallback (step 3) when brand-library is not installed — in which case the
57
- # local brand profiles below are exactly what the agent should read.
58
38
  sourceRoles:
59
- brand: consumer
60
39
  narrative: provider
61
40
 
62
41
  profiles:
63
42
  # ═══════════════════════════════════════════════════════════════════════════
64
43
  # BRAND KINDS — verbatim from brand-library.yaml
65
44
  # ═══════════════════════════════════════════════════════════════════════════
66
- - slug: brand-identity
67
- displayName: Brand Identity
68
- icon: fingerprint
69
- color: amber
70
- description: "Root brand context: positioning, audience, website, voice summary, and generation intent."
71
- semanticSlug: brand.identity
72
- properties:
73
- - slug: brand-type
74
- label: Brand type
75
- valueType: string
76
- inputType: select
77
- enumValues: [product-digital, product-physical, agency, personal-brand, nonprofit, institutional, universal]
78
- constraints: { defaultValue: universal }
79
- - slug: brand-status
80
- label: Status
81
- valueType: string
82
- inputType: select
83
- enumValues: [draft, active, archived]
84
- constraints: { defaultValue: active }
85
- - slug: brand-tagline
86
- label: Tagline
87
- valueType: string
88
- inputType: text
89
- - slug: brand-website
90
- label: Website
91
- valueType: string
92
- inputType: url
93
- - slug: brand-industry
94
- label: Industry
95
- valueType: string
96
- inputType: text
97
- - slug: brand-positioning
98
- label: Positioning
99
- valueType: string
100
- inputType: textarea
101
- - slug: brand-audience-primary
102
- label: Primary audience
103
- valueType: string
104
- inputType: textarea
105
- - slug: brand-audience-secondary
106
- label: Secondary audience
107
- valueType: string
108
- inputType: textarea
109
- - slug: brand-voice-summary
110
- label: Voice summary
111
- valueType: string
112
- inputType: textarea
113
- - slug: brand-notes
114
- label: Notes
115
- valueType: string
116
- inputType: textarea
117
-
118
- - slug: brand-color
119
- displayName: Brand Color
120
- icon: swatch-book
121
- color: violet
122
- description: Approved palette entry with semantic role, usage notes, and print references.
123
- semanticSlug: brand.color
124
- properties:
125
- - slug: color-role
126
- label: Role
127
- valueType: string
128
- inputType: select
129
- enumValues: [primary, secondary, accent, background, surface, surface-elevated, text, text-muted, border, success, warning, error, info, neutral, campaign, custom]
130
- constraints: { defaultValue: custom }
131
- - slug: color-group
132
- label: Group
133
- valueType: string
134
- inputType: select
135
- enumValues: [core, extended, semantic, neutral, seasonal, campaign]
136
- constraints: { defaultValue: core }
137
- - slug: color-hex
138
- label: Hex
139
- valueType: string
140
- inputType: color
141
- - slug: color-rgb
142
- label: RGB
143
- valueType: string
144
- inputType: text
145
- - slug: color-cmyk
146
- label: CMYK
147
- valueType: string
148
- inputType: text
149
- - slug: color-pantone
150
- label: Pantone
151
- valueType: string
152
- inputType: text
153
- - slug: color-ral
154
- label: RAL
155
- valueType: string
156
- inputType: text
157
- - slug: color-token-name
158
- label: Token name
159
- valueType: string
160
- inputType: text
161
- - slug: color-usage
162
- label: Usage note
163
- valueType: string
164
- inputType: textarea
165
- - slug: color-status
166
- label: Status
167
- valueType: string
168
- inputType: select
169
- enumValues: [draft, approved, deprecated]
170
- constraints: { defaultValue: approved }
171
-
172
- - slug: brand-font
173
- displayName: Brand Typeface
174
- icon: type
175
- color: blue
176
- description: Typeface with role, family, licensing, import URL, weights, and fallback stack.
177
- semanticSlug: brand.font
178
- properties:
179
- - slug: font-role
180
- label: Role
181
- valueType: string
182
- inputType: select
183
- enumValues: [heading, body, display, mono, accent, ui, caption]
184
- constraints: { defaultValue: body }
185
- - slug: font-family
186
- label: Family
187
- valueType: string
188
- inputType: text
189
- - slug: font-foundry
190
- label: Foundry
191
- valueType: string
192
- inputType: text
193
- - slug: font-license
194
- label: License
195
- valueType: string
196
- inputType: select
197
- enumValues: [open-source, google-fonts, adobe-fonts, licensed, custom, system]
198
- constraints: { defaultValue: google-fonts }
199
- - slug: font-weights
200
- label: Weights
201
- valueType: string
202
- inputType: text
203
- - slug: font-fallback
204
- label: Fallback stack
205
- valueType: string
206
- inputType: text
207
- - slug: font-url
208
- label: Import URL
209
- valueType: string
210
- inputType: url
211
- - slug: font-document-id
212
- label: Font document ID
213
- valueType: string
214
- inputType: text
215
- - slug: font-status
216
- label: Status
217
- valueType: string
218
- inputType: select
219
- enumValues: [active, draft, deprecated]
220
- constraints: { defaultValue: active }
221
-
222
- - slug: brand-asset
223
- displayName: Brand Asset
224
- icon: image
225
- color: green
226
- description: "Document-backed or URL-backed reusable media: logos, imagery, icons, fonts, video, references, and documents."
227
- semanticSlug: brand.asset
228
- properties:
229
- - slug: asset-kind
230
- label: Kind
231
- valueType: string
232
- inputType: select
233
- enumValues: [logo, wordmark, symbol, monogram, pattern, texture, icon-set, illustration, photo, video, document, font, 3d-model, print-ready, reference, other]
234
- - slug: asset-variant
235
- label: Variant
236
- valueType: string
237
- inputType: select
238
- enumValues: [primary, secondary, horizontal, stacked, mono-dark, mono-light, white, reversed, favicon, social-avatar, og-image, other]
239
- - slug: asset-status
240
- label: Status
241
- valueType: string
242
- inputType: select
243
- enumValues: [draft, approved, deprecated]
244
- constraints: { defaultValue: approved }
245
- - slug: asset-usage
246
- label: Usage notes
247
- valueType: string
248
- inputType: textarea
249
- - slug: asset-tags
250
- label: Tags
251
- valueType: string
252
- inputType: text
253
- - slug: asset-url
254
- label: External URL
255
- valueType: string
256
- inputType: url
257
- - slug: asset-document-id
258
- label: Document ID
259
- valueType: string
260
- inputType: text
261
- - slug: asset-file-id
262
- label: Legacy file ID
263
- valueType: string
264
- inputType: text
265
- - slug: asset-alt-text
266
- label: Alt text
267
- valueType: string
268
- inputType: textarea
269
-
270
- - slug: brand-reference
271
- displayName: Brand Reference
272
- icon: bookmark
273
- color: teal
274
- description: Website, competitor, campaign, moodboard, or example used as source context for generation.
275
- semanticSlug: brand.reference
276
- properties:
277
- - slug: reference-kind
278
- label: Kind
279
- valueType: string
280
- inputType: select
281
- enumValues: [website, competitor, campaign, moodboard, copy-example, design-example, customer-example, other]
282
- - slug: reference-url
283
- label: URL
284
- valueType: string
285
- inputType: url
286
- - slug: reference-notes
287
- label: Notes
288
- valueType: string
289
- inputType: textarea
290
- - slug: reference-status
291
- label: Status
292
- valueType: string
293
- inputType: select
294
- enumValues: [draft, approved, archived]
295
- constraints: { defaultValue: approved }
296
-
297
- - slug: brand-token-set
298
- displayName: Token Set
299
- icon: code-2
300
- color: violet
301
- description: Generated or curated design tokens for color, typography, spacing, radii, and exported CSS variables.
302
- semanticSlug: brand.tokens
303
- properties:
304
- - slug: token-status
305
- label: Status
306
- valueType: string
307
- inputType: select
308
- enumValues: [draft, active, archived]
309
- constraints: { defaultValue: active }
310
- - slug: token-mode
311
- label: Mode
312
- valueType: string
313
- inputType: select
314
- enumValues: [base, light, dark, high-contrast, campaign, experimental]
315
- constraints: { defaultValue: base }
316
- - slug: token-source-ids
317
- label: Source IDs
318
- valueType: string
319
- inputType: textarea
320
- - slug: token-json
321
- label: Tokens JSON
322
- valueType: string
323
- inputType: textarea
324
- - slug: token-css
325
- label: CSS variables
326
- valueType: string
327
- inputType: textarea
328
- - slug: token-notes
329
- label: Notes
330
- valueType: string
331
- inputType: textarea
332
-
333
- - slug: brand-voice-guide
334
- displayName: Voice Guide
335
- icon: message-circle
336
- color: orange
337
- description: "Generated or curated voice guidance by context: traits, tone, vocabulary, and copy examples."
338
- semanticSlug: brand.voice
339
- properties:
340
- - slug: voice-context
341
- label: Context
342
- valueType: string
343
- inputType: select
344
- enumValues: [general, marketing, product, support, social, legal, editorial, investor]
345
- constraints: { defaultValue: general }
346
- - slug: voice-status
347
- label: Status
348
- valueType: string
349
- inputType: select
350
- enumValues: [draft, approved, deprecated]
351
- constraints: { defaultValue: approved }
352
- - slug: voice-personality-traits
353
- label: Personality
354
- valueType: string
355
- inputType: textarea
356
- - slug: voice-tone-descriptors
357
- label: Tone
358
- valueType: string
359
- inputType: text
360
- - slug: voice-vocabulary
361
- label: Vocabulary
362
- valueType: string
363
- inputType: textarea
364
- - slug: voice-example-do
365
- label: Do
366
- valueType: string
367
- inputType: textarea
368
- - slug: voice-example-dont
369
- label: Don't
370
- valueType: string
371
- inputType: textarea
372
- - slug: voice-source-ids
373
- label: Source IDs
374
- valueType: string
375
- inputType: textarea
376
-
377
- - slug: brand-rule
378
- displayName: Brand Rule
379
- icon: shield-check
380
- color: red
381
- description: Usage constraints, accessibility requirements, do/don't examples, and generation guidance.
382
- semanticSlug: brand.rule
383
- properties:
384
- - slug: rule-kind
385
- label: Kind
386
- valueType: string
387
- inputType: select
388
- enumValues: [visual, voice, legal, accessibility, sizing, clearance, color-usage, typography-usage, do, dont, generation, other]
389
- - slug: rule-subject
390
- label: Subject
391
- valueType: string
392
- inputType: select
393
- enumValues: [logo, color, typography, pattern, asset, voice, general, digital, print, packaging]
394
- - slug: rule-severity
395
- label: Severity
396
- valueType: string
397
- inputType: select
398
- enumValues: [guideline, important, mandatory]
399
- constraints: { defaultValue: important }
400
- - slug: rule-content
401
- label: Rule
402
- valueType: string
403
- inputType: textarea
404
- - slug: rule-example
405
- label: Example
406
- valueType: string
407
- inputType: textarea
408
- - slug: rule-source-ids
409
- label: Source IDs
410
- valueType: string
411
- inputType: textarea
412
-
413
- - slug: brand-template
414
- displayName: Brand Template
415
- icon: layout-template
416
- color: pink
417
- description: Reusable output template for artboards, decks, carousels, banners, documents, or generated HTML.
418
- semanticSlug: brand.template
419
- properties:
420
- - slug: template-kind
421
- label: Kind
422
- valueType: string
423
- inputType: select
424
- enumValues: [artboard, deck, carousel, banner, document, html, social, other]
425
- - slug: template-status
426
- label: Status
427
- valueType: string
428
- inputType: select
429
- enumValues: [draft, approved, deprecated]
430
- constraints: { defaultValue: approved }
431
- - slug: template-format
432
- label: Format
433
- valueType: string
434
- inputType: select
435
- enumValues: [tldraw, html, json, markdown, image, mixed]
436
- - slug: template-config
437
- label: Config JSON
438
- valueType: string
439
- inputType: textarea
440
- - slug: template-usage
441
- label: Usage notes
442
- valueType: string
443
- inputType: textarea
444
-
445
- - slug: brand-component
446
- displayName: Brand Component
447
- icon: component
448
- color: green
449
- description: "Reusable branded UI or content component: hero, CTA, card, quote, banner, section, or HTML snippet."
450
- semanticSlug: brand.component
451
- properties:
452
- - slug: component-kind
453
- label: Kind
454
- valueType: string
455
- inputType: select
456
- enumValues: [hero, card, cta, quote, banner, section, layout, html, other]
457
- - slug: component-status
458
- label: Status
459
- valueType: string
460
- inputType: select
461
- enumValues: [draft, approved, deprecated]
462
- constraints: { defaultValue: approved }
463
- - slug: component-html
464
- label: HTML
465
- valueType: string
466
- inputType: textarea
467
- - slug: component-props
468
- label: Props JSON
469
- valueType: string
470
- inputType: textarea
471
- - slug: component-usage
472
- label: Usage notes
473
- valueType: string
474
- inputType: textarea
475
-
476
- # ═══════════════════════════════════════════════════════════════════════════
477
- # NARRATIVE KINDS — verbatim from foundation.yaml
478
- # (Communication owns the narrative ARTIFACTS: positioning, story arc,
479
- # audiences, and differentiators — NOT mission/vision/values.)
480
- # ═══════════════════════════════════════════════════════════════════════════
481
45
  - slug: positioning
482
46
  displayName: Positioning
483
47
  icon: crosshair
@@ -630,7 +194,13 @@ onboarding:
630
194
  - profileSlug: brand-voice-guide
631
195
  what: Voice guides — tone, personality traits, vocabulary, and do/don't examples per context.
632
196
  cardinality: few
633
- keyFields: [voice-personality-traits, voice-tone-descriptors, voice-example-do, voice-example-dont]
197
+ keyFields:
198
+ [
199
+ voice-personality-traits,
200
+ voice-tone-descriptors,
201
+ voice-example-do,
202
+ voice-example-dont,
203
+ ]
634
204
  - profileSlug: brand-rule
635
205
  what: Usage and voice rules (mandatory / important / guideline).
636
206
  cardinality: several
@@ -11,6 +11,7 @@ import { test } from "vitest";
11
11
  import assert from "node:assert/strict";
12
12
  import { layerTemplateGraph, type CompositionGraph } from "./composition-graph.js";
13
13
  import type { TemplateDependency } from "./types.js";
14
+ import { readYamlTemplates } from "./generate.mjs";
14
15
 
15
16
  /** Build a small `edgesOf` from a plain adjacency map, for test fixtures. */
16
17
  function edgesFrom(map: Record<string, TemplateDependency[]>) {
@@ -120,6 +121,31 @@ test("cycle: A→B→A terminates and reports the broken edge in cycles[]", () =
120
121
  assert.equal(graph.nodes.get("A")!.layer, 0);
121
122
  });
122
123
 
124
+ // ── Corpus invariant: the SHIPPED template graph is acyclic ───────────────────
125
+ // `build.mjs` catches dangling deps at authoring time, but a `compose`/`require`
126
+ // CYCLE among real templates would sink each node to layer 0 and (at install)
127
+ // have the resolver chase its own tail. The engine already surfaces broken
128
+ // back-edges in `cycles[]` — assert the real corpus has none, reading YAML
129
+ // straight off disk (not the committed templates.ts) so a stale snapshot can't
130
+ // hide a freshly-introduced loop.
131
+ test("corpus: the shipped template dependency graph has no cycles", () => {
132
+ const templates = readYamlTemplates() as Array<{
133
+ slug: string;
134
+ data: { dependencies?: TemplateDependency[] };
135
+ }>;
136
+ const bySlug = new Map(templates.map((t) => [t.slug, t.data]));
137
+ const roots = templates.map((t) => t.slug);
138
+ const edgesOf = (slug: string): readonly TemplateDependency[] =>
139
+ bySlug.get(slug)?.dependencies ?? [];
140
+
141
+ const graph = layerTemplateGraph({ roots, edgesOf });
142
+ assert.deepEqual(
143
+ graph.cycles,
144
+ [],
145
+ `template dependency graph must be acyclic — broken back-edges: ${JSON.stringify(graph.cycles)}`,
146
+ );
147
+ });
148
+
123
149
  // ── edgesOf injection ─────────────────────────────────────────────────────────
124
150
  test("edgesOf injection: deps supplied for a slug NOT in the bundled map are still walked", () => {
125
151
  // "private-remote-pkg" does not exist in the bundled WORKSPACE_TEMPLATES map