@synap-core/workspace-templates 0.6.4 → 0.7.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.
@@ -0,0 +1,282 @@
1
+ # Outreach & Comms workspace template
2
+ # A standalone, channel-first outreach workspace: personalized LinkedIn and
3
+ # email sequences run against people and companies you already track pod-wide.
4
+ # Owns the outreach data (campaigns + individual touches) and the playbook
5
+ # that drafts and sends the next message — not a CRM, not a content calendar.
6
+ # Reuses the pod-wide `person`/`company` kinds so a contact worked here is the
7
+ # same entity a CRM or Ecosystem workspace sees, not a workspace-local twin.
8
+
9
+ meta:
10
+ slug: outreach-comms
11
+ name: Outreach & Comms
12
+ description: Personalized LinkedIn and email outreach — sequenced touches against real people and companies, drafted and sent by an agent.
13
+ icon: send
14
+ color: "#0EA5E9"
15
+ tags: [outreach, linkedin, email, comms, sequences]
16
+ isPublic: true
17
+
18
+ workspace:
19
+ name: Outreach & Comms
20
+ description: Personalized LinkedIn and email outreach — sequenced touches against real people and companies, drafted and sent by an agent.
21
+ subtype: outreach-comms
22
+ visibility: pod_visible
23
+ capabilities:
24
+ - outreach.campaigns
25
+ - outreach.touches
26
+ sourceRoles:
27
+ outreach: provider
28
+
29
+ profiles:
30
+ # ── Actors ────────────────────────────────────────────────────────────────
31
+ # The pod-wide person and company kinds — declared minimally so campaign and
32
+ # touch links resolve. Kept light on purpose: identity lives elsewhere.
33
+ - slug: person
34
+ displayName: Person
35
+ icon: user
36
+ color: amber
37
+ description: A person you are reaching out to — a prospect, partner, or contact.
38
+ properties:
39
+ - slug: email
40
+ label: Email
41
+ valueType: string
42
+ inputType: email
43
+ - slug: notes
44
+ label: Notes
45
+ valueType: string
46
+ inputType: textarea
47
+
48
+ - slug: company
49
+ displayName: Company
50
+ icon: building-2
51
+ color: "#10B981"
52
+ description: A company you are reaching out to.
53
+ properties:
54
+ - slug: website
55
+ label: Website
56
+ valueType: string
57
+ inputType: url
58
+ - slug: industry
59
+ label: Industry
60
+ valueType: string
61
+ inputType: text
62
+
63
+ # ── Outreach data (owned here) ───────────────────────────────────────────
64
+ - slug: outreach-campaign
65
+ displayName: Outreach Campaign
66
+ icon: target
67
+ color: sky
68
+ description: A sequence of personalized touches aimed at a segment — the "why we're reaching out" and the offer.
69
+ properties:
70
+ - slug: channel
71
+ label: Channel
72
+ valueType: string
73
+ inputType: select
74
+ enumValues: [linkedin, email, both]
75
+ constraints: { defaultValue: linkedin }
76
+ - slug: status
77
+ label: Status
78
+ valueType: string
79
+ inputType: select
80
+ enumValues: [draft, active, paused, completed]
81
+ constraints: { defaultValue: draft }
82
+ - slug: targetSegment
83
+ label: Target segment
84
+ valueType: string
85
+ inputType: text
86
+ placeholder: e.g. Series A-B B2B SaaS founders
87
+ - slug: valueProp
88
+ label: Value proposition
89
+ valueType: string
90
+ inputType: textarea
91
+ - slug: callToAction
92
+ label: Call to action
93
+ valueType: string
94
+ inputType: text
95
+ - slug: startDate
96
+ label: Start date
97
+ valueType: date
98
+ inputType: date
99
+ - slug: notes
100
+ label: Notes
101
+ valueType: string
102
+ inputType: textarea
103
+
104
+ - slug: outreach-touch
105
+ displayName: Outreach Touch
106
+ icon: message-circle
107
+ color: blue
108
+ description: A single message sent (or drafted) to one person as part of a campaign.
109
+ properties:
110
+ - slug: channel
111
+ label: Channel
112
+ valueType: string
113
+ inputType: select
114
+ enumValues: [linkedin, email]
115
+ - slug: touchType
116
+ label: Touch type
117
+ valueType: string
118
+ inputType: select
119
+ enumValues: [connection_request, follow_up, intro_email, reply]
120
+ - slug: status
121
+ label: Status
122
+ valueType: string
123
+ inputType: select
124
+ enumValues: [drafted, sent, opened, replied, bounced, no_response]
125
+ constraints: { defaultValue: drafted }
126
+ - slug: sentDate
127
+ label: Sent date
128
+ valueType: date
129
+ inputType: date
130
+ - slug: messageContent
131
+ label: Message content
132
+ valueType: string
133
+ inputType: textarea
134
+
135
+ views:
136
+ - name: Campaigns
137
+ slug: outreach-campaigns
138
+ type: table
139
+ scopeProfileSlug: outreach-campaign
140
+ description: Every outreach sequence, its channel, and its status.
141
+ config:
142
+ columns: [title, channel, status, targetSegment, startDate]
143
+ defaultView: true
144
+ - name: Touches
145
+ slug: outreach-touches
146
+ type: kanban
147
+ scopeProfileSlug: outreach-touch
148
+ groupBy: status
149
+ description: Individual messages, grouped by where they stand — drafted through replied.
150
+ config:
151
+ groupBy: status
152
+ cardFields: [channel, touchType, sentDate]
153
+
154
+ entityLinks:
155
+ - sourceProfileSlug: outreach-campaign
156
+ targetProfileSlug: person
157
+ type: targets
158
+ label: Targets
159
+ - sourceProfileSlug: outreach-campaign
160
+ targetProfileSlug: company
161
+ type: targets
162
+ label: Targets
163
+ - sourceProfileSlug: outreach-touch
164
+ targetProfileSlug: person
165
+ type: sent_to
166
+ label: Sent to
167
+ - sourceProfileSlug: outreach-touch
168
+ targetProfileSlug: outreach-campaign
169
+ type: part_of
170
+ label: Part of
171
+
172
+ # Playbook — drafts and sends the next personalized touch for a target, using
173
+ # whatever we already know about them so the message isn't generic. Bound to
174
+ # the campaign kind so a captured/updated campaign can offer this as a session.
175
+ playbooks:
176
+ - name: Personalized Outreach
177
+ description: Draft a personalized LinkedIn or email message to a target contact, send it, and log the touch.
178
+ goalTemplate: >-
179
+ Reach out to {target} on {channel} as part of the "{campaign}" campaign.
180
+ Research them first using what we already know (their company, role, and
181
+ any prior touches) so the message is specific, not generic. Campaign
182
+ context — value proposition and call to action: {campaignContext}. Draft
183
+ the message, send it via {channel}, then create an outreach-touch record
184
+ logging what was sent and update the target's contact record with the
185
+ outcome.
186
+ subjectProfile:
187
+ profileSlug: outreach-campaign
188
+ params:
189
+ - { name: target, type: entity, label: Target contact, required: true }
190
+ - { name: campaign, type: text, label: Campaign name, required: true }
191
+ - { name: channel, type: choice, label: Channel, defaultValue: linkedin }
192
+ - { name: campaignContext, type: text, label: Value prop + call to action }
193
+ executor: is-agent
194
+ grants:
195
+ - linkedin_send_invite
196
+ - unipile_send_message
197
+ - gmail_send
198
+ - entity.create
199
+ status: active
200
+
201
+ # LinkedIn send/search via Unipile, email send via Gmail (nango-google). The
202
+ # user connects each once on install; a missing key fails gracefully per-skill.
203
+ integrations:
204
+ - templateKey: unipile-linkedin
205
+ - templateKey: nango-google
206
+
207
+ onboarding:
208
+ goal: >
209
+ Stand up an outreach motion — who we're targeting, on which channel, with
210
+ what offer — so the agent can start drafting and sending real touches
211
+ instead of waiting for a blank campaign.
212
+ framing: |
213
+ THE OUTBOUND LEAD: Act as a sharp SDR/outbound lead. Push for a SPECIFIC
214
+ segment and a SPECIFIC offer, not "reach out to everyone about our product".
215
+ A campaign with no segment and no value prop is just a contact list.
216
+ expertise:
217
+ starters:
218
+ - >
219
+ Name the segment as a person, not a market — "Head of Growth at
220
+ seed-to-Series-A B2B SaaS", not "SaaS companies". The agent personalizes
221
+ against a person, not a category.
222
+ - >
223
+ Every campaign needs ONE call to action, stated plainly — a call, a demo,
224
+ a reply. If the founder gives a vague goal ("build awareness"), push for
225
+ the concrete next step a touch should provoke.
226
+ blindSpots:
227
+ - >
228
+ Founders default to email when LinkedIn converts better for cold B2B —
229
+ ask which channel the target segment actually lives on before defaulting.
230
+ - >
231
+ A campaign with no target contacts yet is fine to create, but flag it —
232
+ the first touch needs at least one real person or company to reach.
233
+ bar: >
234
+ At least one real campaign exists with a named segment, a stated value
235
+ prop and call to action, and — ideally — a first target contact ready for
236
+ the Personalized Outreach playbook to run against.
237
+ collect:
238
+ - profileSlug: outreach-campaign
239
+ what: The outreach sequences to run — channel, target segment, and offer.
240
+ cardinality: few
241
+ keyFields: [channel, targetSegment, valueProp, callToAction]
242
+ - profileSlug: person
243
+ what: The first contacts to target with this campaign.
244
+ cardinality: few
245
+ keyFields: [email]
246
+ openingQuestions:
247
+ - "Who are you trying to reach — what role, at what kind of company?"
248
+ - "LinkedIn, email, or both?"
249
+ - "What's the one thing you want them to do after reading your message?"
250
+ doneWhen: At least one campaign captured with a channel, segment, and value prop, plus one target contact.
251
+
252
+ app:
253
+ kind: stored
254
+ cellKey: entity-detail
255
+
256
+ layout:
257
+ defaultView: Campaigns
258
+ defaultApp: null
259
+ pinnedApps: [dashboard, data]
260
+ sidebarItems:
261
+ - kind: view
262
+ viewName: Campaigns
263
+ label: Campaigns
264
+ icon: target
265
+ - kind: view
266
+ viewName: Touches
267
+ label: Touches
268
+ icon: message-circle
269
+ - kind: app
270
+ appId: data
271
+ label: Data
272
+ icon: database
273
+
274
+ bento:
275
+ viewName: Campaigns
276
+ blocks:
277
+ - kind: view
278
+ viewName: Campaigns
279
+ pos: { x: 0, y: 0, w: 8, h: 5 }
280
+ - kind: view
281
+ viewName: Touches
282
+ pos: { x: 8, y: 0, w: 4, h: 5 }