@synap-core/workspace-templates 0.8.0 → 0.9.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/index.d.ts +38 -1
- package/dist/index.js +635 -27
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/builder.yaml +1 -1
- package/src/business-developer.template.test.ts +2 -0
- package/src/business-developer.yaml +84 -0
- package/src/communication.yaml +28 -1
- package/src/content-os.yaml +487 -31
- package/src/crm.yaml +46 -0
- package/src/foundation.yaml +93 -0
- package/src/internal-runbook.yaml +1 -1
- package/src/project-management.yaml +1 -1
- package/src/templates.ts +635 -27
- package/src/types.ts +38 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synap-core/workspace-templates",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"packageManager": "pnpm@9.15.4",
|
|
6
6
|
"description": "Canonical workspace definitions — YAML source + typed exports for browser, backend, CLI, and marketplace",
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"type-check": "tsc --noEmit",
|
|
20
|
-
"build:yaml": "node build.mjs",
|
|
20
|
+
"build:yaml": "node --experimental-strip-types build.mjs",
|
|
21
21
|
"check:converters": "node scripts/check-converters.mjs",
|
|
22
22
|
"check:concepts": "node scripts/check-concepts.mjs",
|
|
23
|
-
"build": "node build.mjs && tsup && node scripts/check-converters.mjs && node scripts/check-concepts.mjs",
|
|
23
|
+
"build": "node --experimental-strip-types build.mjs && tsup && node scripts/check-converters.mjs && node scripts/check-concepts.mjs",
|
|
24
24
|
"provision": "node scripts/provision.mjs",
|
|
25
25
|
"eval": "node scripts/eval-standard.mjs",
|
|
26
|
-
"prepublishOnly": "node build.mjs && tsup && node scripts/check-converters.mjs && node scripts/check-concepts.mjs"
|
|
26
|
+
"prepublishOnly": "node --experimental-strip-types build.mjs && tsup && node scripts/check-converters.mjs && node scripts/check-concepts.mjs"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"zod": "^3.0.0",
|
package/src/builder.yaml
CHANGED
|
@@ -1290,7 +1290,7 @@ views:
|
|
|
1290
1290
|
scopeProfileSlug: devplane_deployment
|
|
1291
1291
|
startField: deployedAt
|
|
1292
1292
|
config:
|
|
1293
|
-
dateField: deployedAt
|
|
1293
|
+
dateField: properties.deployedAt
|
|
1294
1294
|
colorBy: deployStatus
|
|
1295
1295
|
description: "Deployment events on a calendar so release cadence is visible at a glance."
|
|
1296
1296
|
- name: Packages
|
|
@@ -130,6 +130,8 @@ describe("Business Developer workspace overlay", () => {
|
|
|
130
130
|
})),
|
|
131
131
|
).toEqual([
|
|
132
132
|
{ sourceProfileSlug: "deal", targetProfileSlug: "crm-commission-entitlement", type: "crm_commission_for_deal" },
|
|
133
|
+
{ sourceProfileSlug: "person", targetProfileSlug: "campaign", type: "member_of" },
|
|
134
|
+
{ sourceProfileSlug: "company", targetProfileSlug: "campaign", type: "member_of" },
|
|
133
135
|
]);
|
|
134
136
|
});
|
|
135
137
|
|
|
@@ -280,6 +280,79 @@ profiles:
|
|
|
280
280
|
valueType: string
|
|
281
281
|
inputType: textarea
|
|
282
282
|
|
|
283
|
+
# ── Campaign (reused kind — SSOT is marketing.yaml) ───────────────────────
|
|
284
|
+
# NOT a new kind and NOT a CRM fork of one: this RE-DECLARES the
|
|
285
|
+
# marketing-campaign template's `campaign` so the CRM can attach people and
|
|
286
|
+
# companies to the campaigns that sourced them (`member_of`, below). Keeping
|
|
287
|
+
# `semanticSlug: marketing.campaign` is what makes it the SAME concept rather
|
|
288
|
+
# than a third one — the concept guard only errors when two DIFFERENT slugs
|
|
289
|
+
# claim one semanticSlug. `content-os.yaml` re-declares it exactly this way;
|
|
290
|
+
# this follows that precedent.
|
|
291
|
+
#
|
|
292
|
+
# It must live in THIS file, not in `crm.yaml` or `marketing.yaml`:
|
|
293
|
+
# `toWorkspaceDefinition` does NOT flatten dependencies, so only
|
|
294
|
+
# business-developer's OWN profiles/entityLinks reach an existing CRM
|
|
295
|
+
# workspace through `reconcileFromDefinition`. It is also what lets the
|
|
296
|
+
# `member_of` links below resolve — an entityLink endpoint must be an own
|
|
297
|
+
# profile, a SYSTEM_PROFILE, or dependency vocab, and `campaign` is none of
|
|
298
|
+
# the latter two.
|
|
299
|
+
#
|
|
300
|
+
# Scope is OMITTED (= workspace) to MATCH marketing's own declaration: the
|
|
301
|
+
# promotion to pod-wide is the resolver's job (resolve-profile-for-apply.ts
|
|
302
|
+
# same-actor workspace→shared branch), not ours to assert. Body kept verbatim
|
|
303
|
+
# so no property drift.
|
|
304
|
+
- slug: campaign
|
|
305
|
+
displayName: Campaign
|
|
306
|
+
icon: megaphone
|
|
307
|
+
color: pink
|
|
308
|
+
description: "A marketing campaign — email, social, event, content, or partnership"
|
|
309
|
+
semanticSlug: marketing.campaign
|
|
310
|
+
properties:
|
|
311
|
+
- slug: campaign-status
|
|
312
|
+
label: Status
|
|
313
|
+
valueType: string
|
|
314
|
+
inputType: select
|
|
315
|
+
enumValues: [planning, active, paused, completed, cancelled]
|
|
316
|
+
constraints: { defaultValue: planning }
|
|
317
|
+
- slug: campaign-channel
|
|
318
|
+
label: Channel
|
|
319
|
+
valueType: string
|
|
320
|
+
inputType: select
|
|
321
|
+
enumValues:
|
|
322
|
+
[email, social, event, content, partnership, paid, organic, other]
|
|
323
|
+
- slug: campaign-goal
|
|
324
|
+
label: Goal
|
|
325
|
+
valueType: string
|
|
326
|
+
inputType: textarea
|
|
327
|
+
- slug: campaign-target-audience
|
|
328
|
+
label: Target Audience
|
|
329
|
+
valueType: string
|
|
330
|
+
inputType: textarea
|
|
331
|
+
- slug: campaign-start-date
|
|
332
|
+
label: Start Date
|
|
333
|
+
valueType: date
|
|
334
|
+
inputType: date
|
|
335
|
+
- slug: campaign-end-date
|
|
336
|
+
label: End Date
|
|
337
|
+
valueType: date
|
|
338
|
+
inputType: date
|
|
339
|
+
- slug: campaign-budget
|
|
340
|
+
label: Budget
|
|
341
|
+
valueType: number
|
|
342
|
+
inputType: number
|
|
343
|
+
- slug: campaign-lead-count
|
|
344
|
+
label: Lead Count
|
|
345
|
+
valueType: number
|
|
346
|
+
inputType: number
|
|
347
|
+
- slug: campaign-conversion-rate
|
|
348
|
+
label: Conversion Rate (%)
|
|
349
|
+
valueType: number
|
|
350
|
+
inputType: number
|
|
351
|
+
- slug: campaign-notes
|
|
352
|
+
label: Notes
|
|
353
|
+
valueType: string
|
|
354
|
+
inputType: textarea
|
|
355
|
+
|
|
283
356
|
entityLinks:
|
|
284
357
|
# The existing generic `linked_to_deal` relation remains the deal ↔
|
|
285
358
|
# counterparty connection. This overlay adds only the new auditable
|
|
@@ -288,6 +361,17 @@ entityLinks:
|
|
|
288
361
|
targetProfileSlug: crm-commission-entitlement
|
|
289
362
|
type: crm_commission_for_deal
|
|
290
363
|
label: Commission entitlement
|
|
364
|
+
# Campaign membership — the sourcing edge between a counterparty and the
|
|
365
|
+
# campaign it came from. Same predicate for both endpoint kinds, mirroring
|
|
366
|
+
# CRM's own `linked_to_deal` person/company pair.
|
|
367
|
+
- sourceProfileSlug: person
|
|
368
|
+
targetProfileSlug: campaign
|
|
369
|
+
type: member_of
|
|
370
|
+
label: Member of
|
|
371
|
+
- sourceProfileSlug: company
|
|
372
|
+
targetProfileSlug: campaign
|
|
373
|
+
type: member_of
|
|
374
|
+
label: Member of
|
|
291
375
|
|
|
292
376
|
# These are guided, proposal-first sessions — not background automations. They
|
|
293
377
|
# never create a deal merely because a lead exists, and never convert a lead to
|
package/src/communication.yaml
CHANGED
|
@@ -20,11 +20,22 @@ meta:
|
|
|
20
20
|
# (identity, colors, fonts, assets, voice guide, rules, templates, components).
|
|
21
21
|
# This overlay adds the STRATEGIC MESSAGING layer (positioning, narrative,
|
|
22
22
|
# audience, differentiator) on top, so there is ONE brand vocabulary, not two.
|
|
23
|
+
#
|
|
24
|
+
# `require: foundation` alongside the `compose` is legal: the resolver caps
|
|
25
|
+
# COMPOSE deps at one per template (assertSingleComposeDep) and iterates the rest
|
|
26
|
+
# by relation — it does not cap the dependency list. It is also necessary: the
|
|
27
|
+
# four messaging kinds below are foundation's, not brand-library's, and a
|
|
28
|
+
# `scope: shared` reuse only dedups to the SSOT row if the owner is guaranteed to
|
|
29
|
+
# install first, which is exactly what a `require` buys (deps-first ordering).
|
|
23
30
|
dependencies:
|
|
24
31
|
- slug: brand-library
|
|
25
32
|
kind: workspace
|
|
26
33
|
relation: compose
|
|
27
34
|
reason: "Layers positioning, narrative, and audience onto your Brand Library."
|
|
35
|
+
- slug: foundation
|
|
36
|
+
kind: workspace
|
|
37
|
+
relation: require
|
|
38
|
+
reason: "Owns the pod-wide positioning, narrative, audience, and differentiator vocabulary this workspace layers onto the brand."
|
|
28
39
|
|
|
29
40
|
workspace:
|
|
30
41
|
# Composes onto Brand Library: name + subtype MATCH the base (overlay contract),
|
|
@@ -40,13 +51,26 @@ workspace:
|
|
|
40
51
|
|
|
41
52
|
profiles:
|
|
42
53
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
43
|
-
#
|
|
54
|
+
# MESSAGING KINDS — verbatim from foundation.yaml (NOT brand-library)
|
|
55
|
+
#
|
|
56
|
+
# This block long carried a comment claiming these came from brand-library.
|
|
57
|
+
# They do not: brand-library declares none of them; `positioning`, `narrative`,
|
|
58
|
+
# `audience`, and `differentiator` are foundation's (foundation.yaml:138, :157,
|
|
59
|
+
# :89, :174). The wrong attribution had a real cost — with no `require:
|
|
60
|
+
# foundation` and no `scope: shared`, these four re-declarations minted a
|
|
61
|
+
# SECOND set of rows and the pod ended up with two positionings that could
|
|
62
|
+
# disagree. Both halves of the fix are now in place: the `require` above makes
|
|
63
|
+
# foundation install first (so its body is the SSOT base), and `scope: shared`
|
|
64
|
+
# makes provisioning dedup to that ONE pod-wide row and grant this workspace
|
|
65
|
+
# access instead of forking. Bodies stay verbatim so there is no property drift
|
|
66
|
+
# on the shared row.
|
|
44
67
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
45
68
|
- slug: positioning
|
|
46
69
|
displayName: Positioning
|
|
47
70
|
icon: crosshair
|
|
48
71
|
color: cyan
|
|
49
72
|
description: "Market category, who we stand against, and why we win."
|
|
73
|
+
scope: shared
|
|
50
74
|
properties:
|
|
51
75
|
- slug: category
|
|
52
76
|
label: Category
|
|
@@ -66,6 +90,7 @@ profiles:
|
|
|
66
90
|
icon: book-open
|
|
67
91
|
color: amber
|
|
68
92
|
description: "The origin -> insight -> mission story arc."
|
|
93
|
+
scope: shared
|
|
69
94
|
properties:
|
|
70
95
|
- slug: arc
|
|
71
96
|
label: Story arc
|
|
@@ -83,6 +108,7 @@ profiles:
|
|
|
83
108
|
icon: users
|
|
84
109
|
color: blue
|
|
85
110
|
description: "An ideal customer profile — who we are built for."
|
|
111
|
+
scope: shared
|
|
86
112
|
properties:
|
|
87
113
|
- slug: segment
|
|
88
114
|
label: Segment
|
|
@@ -106,6 +132,7 @@ profiles:
|
|
|
106
132
|
icon: sparkles
|
|
107
133
|
color: green
|
|
108
134
|
description: "One thing only we do, believe, or refuse."
|
|
135
|
+
scope: shared
|
|
109
136
|
properties:
|
|
110
137
|
- slug: statement
|
|
111
138
|
label: Statement
|