@synap-core/workspace-templates 0.6.4 → 0.7.1
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 +216 -1
- package/dist/index.js +3501 -1622
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/business-developer.template.test.ts +280 -0
- package/src/business-developer.yaml +644 -0
- package/src/composition-graph.test.ts +135 -0
- package/src/composition-graph.ts +298 -0
- package/src/crm.yaml +38 -58
- package/src/define.flow-automations.test.ts +65 -0
- package/src/define.ts +95 -7
- package/src/ecosystem.yaml +24 -17
- package/src/index.ts +15 -0
- package/src/meetings-knowledge.yaml +204 -0
- package/src/outreach-comms.yaml +282 -0
- package/src/templates.ts +2999 -1288
- package/src/types.ts +106 -3
package/src/define.ts
CHANGED
|
@@ -10,9 +10,39 @@
|
|
|
10
10
|
* shape never drifts per call-site.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import type { TemplateBentoBlock, WorkspaceYaml } from "./types.js";
|
|
13
|
+
import type { TemplateAutomation, TemplateBentoBlock, WorkspaceYaml } from "./types.js";
|
|
14
14
|
import { getWorkspaceTemplate } from "./templates.js";
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* A `TemplateAutomation` as the apply door expects it: `flowDefinition`, not
|
|
18
|
+
* the authored `flow` (mirrors `PackagePostWorkspaceBody['automations'][number]`
|
|
19
|
+
* / the Hub `POST /packages/apply` `AutomationSchema`).
|
|
20
|
+
*/
|
|
21
|
+
export interface PackageAutomationWire {
|
|
22
|
+
/** Stable template identity; names may be edited without orphaning the flow. */
|
|
23
|
+
key?: string;
|
|
24
|
+
name: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
triggerType: TemplateAutomation['triggerType'];
|
|
27
|
+
triggerConfig?: Record<string, unknown>;
|
|
28
|
+
flowDefinition?: { nodes: unknown[]; edges: unknown[]; precondition?: string };
|
|
29
|
+
status?: TemplateAutomation['status'];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function toAutomationWire(
|
|
33
|
+
automations: TemplateAutomation[] | undefined,
|
|
34
|
+
): PackageAutomationWire[] | undefined {
|
|
35
|
+
return automations?.map((a) => ({
|
|
36
|
+
key: a.key,
|
|
37
|
+
name: a.name,
|
|
38
|
+
description: a.description,
|
|
39
|
+
triggerType: a.triggerType,
|
|
40
|
+
triggerConfig: a.triggerConfig,
|
|
41
|
+
flowDefinition: a.flow,
|
|
42
|
+
status: a.status,
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
|
|
16
46
|
/** A widget block as the wire expects it: `bentoLayout[]`, keyed by `widgetType`. */
|
|
17
47
|
export interface BentoWidgetBlockWire {
|
|
18
48
|
widgetType: string;
|
|
@@ -147,6 +177,21 @@ export interface WorkspaceDefinitionInput {
|
|
|
147
177
|
* tools/skills/automations silently dropped on that door.
|
|
148
178
|
*/
|
|
149
179
|
capabilities?: WorkspaceYaml['integrations'];
|
|
180
|
+
/** Playbooks normalized to the workspace-create input contract. */
|
|
181
|
+
playbooks?: Array<Record<string, unknown>>;
|
|
182
|
+
/**
|
|
183
|
+
* Entity-detail action placements — forwarded verbatim to
|
|
184
|
+
* `applyPackagePostWorkspace`, which merges them into
|
|
185
|
+
* `settings.actionPlacements`. The tRPC door (`createFromDefinition`)
|
|
186
|
+
* declares `actionPlacements` in its zod input and carries them through the
|
|
187
|
+
* shared apply door. No shape transform: the authored form IS the wire form.
|
|
188
|
+
*/
|
|
189
|
+
actionPlacements?: WorkspaceYaml['actionPlacements'];
|
|
190
|
+
/**
|
|
191
|
+
* Graph-based automations. Deliberately distinct from the legacy
|
|
192
|
+
* `automations` loop/playbook-trigger wire shape accepted by this door.
|
|
193
|
+
*/
|
|
194
|
+
flowAutomations?: PackageAutomationWire[];
|
|
150
195
|
// Workspace-level metadata (flattened from the `workspace` block)
|
|
151
196
|
workspaceSubtype?: string;
|
|
152
197
|
workspaceType?: NonNullable<WorkspaceYaml['workspace']>['workspaceType'];
|
|
@@ -177,6 +222,27 @@ export interface ToDefinitionResult {
|
|
|
177
222
|
templateId: string;
|
|
178
223
|
}
|
|
179
224
|
|
|
225
|
+
/**
|
|
226
|
+
* The workspace-create door persists a compact primitive input contract. A
|
|
227
|
+
* template's entity/choice parameter is still represented precisely by its
|
|
228
|
+
* `subjectProfile` or runtime prompt, while the persisted input value is an ID
|
|
229
|
+
* or selected value string. Keep this conversion at the shared template seam
|
|
230
|
+
* so browser creation and package application cannot silently disagree.
|
|
231
|
+
*/
|
|
232
|
+
function toWorkspacePlaybooks(playbooks: WorkspaceYaml["playbooks"]): Array<Record<string, unknown>> | undefined {
|
|
233
|
+
return playbooks?.map((playbook) => ({
|
|
234
|
+
...playbook,
|
|
235
|
+
params: playbook.params?.map((param) => ({
|
|
236
|
+
name: param.name,
|
|
237
|
+
type: param.type === "number" || param.type === "boolean" ? param.type : "string",
|
|
238
|
+
...(param.defaultValue !== undefined ? { default: param.defaultValue } : {}),
|
|
239
|
+
...(param.label
|
|
240
|
+
? { description: param.label }
|
|
241
|
+
: {}),
|
|
242
|
+
})),
|
|
243
|
+
}));
|
|
244
|
+
}
|
|
245
|
+
|
|
180
246
|
/**
|
|
181
247
|
* Resolve a template (by slug or YAML object) into the createFromDefinition
|
|
182
248
|
* payload. Pass `nameOverride` to rename the workspace at creation time.
|
|
@@ -228,6 +294,13 @@ export function toWorkspaceDefinition(
|
|
|
228
294
|
workspaceCapabilities: ws.capabilities,
|
|
229
295
|
sourceRoles: ws.sourceRoles,
|
|
230
296
|
defaultSources: ws.defaultSources,
|
|
297
|
+
// Workspace creation persists its own compact playbook parameter shape.
|
|
298
|
+
// Map authored entity/choice inputs here instead of dropping playbooks.
|
|
299
|
+
playbooks: toWorkspacePlaybooks(tpl.playbooks),
|
|
300
|
+
// Entity-detail action placements — forwarded verbatim; the apply door
|
|
301
|
+
// resolves playbook/automation refs and merges into settings.actionPlacements.
|
|
302
|
+
actionPlacements: tpl.actionPlacements,
|
|
303
|
+
flowAutomations: toAutomationWire(tpl.automations),
|
|
231
304
|
onboarding: tpl.onboarding,
|
|
232
305
|
// Template-composition dependencies — forwarded so the tRPC/UI door gets the
|
|
233
306
|
// SAME deps-first ordering the CLI/Hub door gets via `toPackageDefinition`.
|
|
@@ -281,6 +354,9 @@ type WorkspaceDefinitionForwarded =
|
|
|
281
354
|
| 'bento' // → bentoViewName + bentoLayout (widgets) + bentoViewBlocks (views)
|
|
282
355
|
| 'profileEntityBentoTemplates'
|
|
283
356
|
| 'integrations' // → capabilities (installed via shared applyPackagePostWorkspace door)
|
|
357
|
+
| 'playbooks' // → normalized compact playbook contract
|
|
358
|
+
| 'actionPlacements' // → settings.actionPlacements via applyPackagePostWorkspace
|
|
359
|
+
| 'automations' // → flowAutomations → shared applyPackagePostWorkspace door
|
|
284
360
|
| 'onboarding'
|
|
285
361
|
| 'dependencies';
|
|
286
362
|
|
|
@@ -297,12 +373,7 @@ type WorkspaceDefinitionDropped =
|
|
|
297
373
|
// The door DOES accept `extends`, but no template declares it today (0/21).
|
|
298
374
|
// Forwarding is a no-op until one does — wire it then.
|
|
299
375
|
| 'extends'
|
|
300
|
-
|
|
301
|
-
// accepts `playbooks`, but the shapes disagree: template param `type` allows
|
|
302
|
-
// 'text'|'entity'|'choice', the tRPC enum accepts only string|number|boolean
|
|
303
|
-
// (and defaultValue↔default, grants: string[]↔{kind,ref}[]). Raw forwarding =
|
|
304
|
-
// zod BAD_REQUEST. Needs a param mapper — separate wave, not a silent drop.
|
|
305
|
-
| 'playbooks';
|
|
376
|
+
;
|
|
306
377
|
|
|
307
378
|
type UnclassifiedWorkspaceDefinitionKey = Exclude<
|
|
308
379
|
keyof WorkspaceYaml,
|
|
@@ -367,6 +438,19 @@ export interface PackageDefinitionOutput {
|
|
|
367
438
|
layoutConfig?: WorkspaceYaml['layout'];
|
|
368
439
|
capabilities?: WorkspaceYaml['integrations'];
|
|
369
440
|
playbooks?: WorkspaceYaml['playbooks'];
|
|
441
|
+
/** Flow-based automations — mapped to the apply door's `flowDefinition` field. */
|
|
442
|
+
automations?: PackageAutomationWire[];
|
|
443
|
+
/**
|
|
444
|
+
* Entity-detail action placements — carried verbatim (authored form IS the
|
|
445
|
+
* wire form). NOTE: the Hub `PackageApplySchema` (synap-backend
|
|
446
|
+
* `hub-protocol/rest/packages.ts`) is a plain `z.object` and does not yet
|
|
447
|
+
* declare `actionPlacements`, so on the CLI/Hub install path this field is
|
|
448
|
+
* STRIPPED before `applyPackagePostWorkspace` sees it. The tRPC
|
|
449
|
+
* `createFromDefinition` door DOES carry it. Named follow-up: add an
|
|
450
|
+
* `ActionPlacementSchema` field to `PackageApplySchema` to close the Hub half
|
|
451
|
+
* (out of the T2 fence — flagged in the handoff).
|
|
452
|
+
*/
|
|
453
|
+
actionPlacements?: WorkspaceYaml['actionPlacements'];
|
|
370
454
|
onboarding?: WorkspaceYaml['onboarding'];
|
|
371
455
|
/** Template-composition dependencies — resolved by the apply endpoint. */
|
|
372
456
|
dependencies?: WorkspaceYaml['dependencies'];
|
|
@@ -421,6 +505,8 @@ export function toPackageDefinition(
|
|
|
421
505
|
layoutConfig: tpl.layout,
|
|
422
506
|
capabilities: tpl.integrations,
|
|
423
507
|
playbooks: tpl.playbooks,
|
|
508
|
+
automations: toAutomationWire(tpl.automations),
|
|
509
|
+
actionPlacements: tpl.actionPlacements,
|
|
424
510
|
onboarding: tpl.onboarding,
|
|
425
511
|
dependencies: tpl.dependencies,
|
|
426
512
|
};
|
|
@@ -448,6 +534,8 @@ type PackageDefinitionForwarded =
|
|
|
448
534
|
| 'layout' // → layoutConfig
|
|
449
535
|
| 'integrations' // → capabilities
|
|
450
536
|
| 'playbooks'
|
|
537
|
+
| 'automations' // → mapped to the apply door's flowDefinition wire shape
|
|
538
|
+
| 'actionPlacements' // → carried verbatim (Hub inbound schema decl is a follow-up)
|
|
451
539
|
| 'onboarding'
|
|
452
540
|
| 'dependencies';
|
|
453
541
|
|
package/src/ecosystem.yaml
CHANGED
|
@@ -381,9 +381,11 @@ playbooks:
|
|
|
381
381
|
goalTemplate: >-
|
|
382
382
|
Research this competitor ({competitor}) and compare them to us. Investigate
|
|
383
383
|
their {focus}: positioning, strengths, weaknesses, pricing, and recent
|
|
384
|
-
moves. Use
|
|
385
|
-
|
|
386
|
-
|
|
384
|
+
moves. Use web search for news and public signal, and use the Apify scraper
|
|
385
|
+
for a deep scan of their site (pricing page, changelog, careers page) when
|
|
386
|
+
a URL is known. Use the provided company context where relevant:
|
|
387
|
+
{companyContext}. Produce: {outputTypes}. Update the competitor entity with
|
|
388
|
+
what you find and make clear where we win and where we are exposed.
|
|
387
389
|
subjectProfile:
|
|
388
390
|
profileSlug: competitor
|
|
389
391
|
params:
|
|
@@ -398,8 +400,9 @@ playbooks:
|
|
|
398
400
|
# starts paid AI runs — the user turns it on when they want the watch.
|
|
399
401
|
schedule: { cron: "0 9 * * 1", enabled: false }
|
|
400
402
|
grants:
|
|
401
|
-
-
|
|
402
|
-
-
|
|
403
|
+
- exa_search
|
|
404
|
+
- apify_run_actor
|
|
405
|
+
- entity.create
|
|
403
406
|
status: active
|
|
404
407
|
|
|
405
408
|
# A radar DISCOVERY run: the self-generating half. No subjectProfile → a single
|
|
@@ -409,28 +412,32 @@ playbooks:
|
|
|
409
412
|
- name: Discover Competitors
|
|
410
413
|
description: Scan the market for competitors we don't track yet and add them to the ecosystem — the self-generating half of the radar.
|
|
411
414
|
goalTemplate: >-
|
|
412
|
-
Find companies that compete with us in {ourSpace}.
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
a competitor in our ecosystem), propose it as a
|
|
417
|
-
ALWAYS include its `website` (its canonical URL)
|
|
418
|
-
|
|
419
|
-
anything already known. Report what you added
|
|
415
|
+
Find companies that compete with us in {ourSpace}. Fan out neural web
|
|
416
|
+
searches with the exa_search skill using category "company" — cover direct
|
|
417
|
+
competitors, adjacent tools that solve the same job a different way, and
|
|
418
|
+
emerging players, not just the obvious incumbents. For each genuinely NEW
|
|
419
|
+
one (not already a competitor in our ecosystem), propose it as a
|
|
420
|
+
`competitor` entity and ALWAYS include its `website` (its canonical URL) as
|
|
421
|
+
the dedup key — never create a company whose website already matches one we
|
|
422
|
+
track. Skip anything already known. Report what you added, the search
|
|
423
|
+
angles you covered, and why each new one matters.
|
|
420
424
|
schedule: { cron: "0 9 * * 1", enabled: false }
|
|
421
425
|
params:
|
|
422
426
|
- { name: ourSpace, type: text, label: Our market / category, required: true }
|
|
423
427
|
executor: is-agent
|
|
424
428
|
grants:
|
|
425
429
|
- exa_search
|
|
426
|
-
-
|
|
430
|
+
- entity.create
|
|
427
431
|
status: active
|
|
428
432
|
|
|
429
|
-
#
|
|
430
|
-
#
|
|
431
|
-
#
|
|
433
|
+
# Exa powers the discovery radar (find companies we don't track yet); Apify
|
|
434
|
+
# powers the deep-scan half of Research Competitor (scrape a known competitor's
|
|
435
|
+
# site for pricing/changelog/careers signal). Composed pod-wide at provisioning
|
|
436
|
+
# via the existing integrations door; the user supplies each API key once on
|
|
437
|
+
# install — a missing key fails gracefully per-skill, not the whole workspace.
|
|
432
438
|
integrations:
|
|
433
439
|
- templateKey: exa
|
|
440
|
+
- templateKey: apify
|
|
434
441
|
|
|
435
442
|
onboarding:
|
|
436
443
|
goal: >
|
package/src/index.ts
CHANGED
|
@@ -44,6 +44,8 @@ export type {
|
|
|
44
44
|
TemplateOnboardingCollectTarget,
|
|
45
45
|
TemplatePlaybook,
|
|
46
46
|
TemplatePlaybookParam,
|
|
47
|
+
TemplateAutomation,
|
|
48
|
+
TemplateActionPlacement,
|
|
47
49
|
} from "./types.js";
|
|
48
50
|
|
|
49
51
|
// The dependency-kind vocabulary as a VALUE — so consumers (marketplace,
|
|
@@ -83,6 +85,19 @@ export type {
|
|
|
83
85
|
TemplateUpdateCheck,
|
|
84
86
|
} from "./catalog.js";
|
|
85
87
|
|
|
88
|
+
export {
|
|
89
|
+
layerTemplateGraph,
|
|
90
|
+
bundledEdgesOf,
|
|
91
|
+
} from "./composition-graph.js";
|
|
92
|
+
export type {
|
|
93
|
+
CompositionInstalledEntry,
|
|
94
|
+
CompositionOverlay,
|
|
95
|
+
CompositionEdge,
|
|
96
|
+
CompositionNode,
|
|
97
|
+
CompositionGraph,
|
|
98
|
+
LayerTemplateGraphInput,
|
|
99
|
+
} from "./composition-graph.js";
|
|
100
|
+
|
|
86
101
|
export {
|
|
87
102
|
toWorkspaceDefinition,
|
|
88
103
|
toPackageDefinition,
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Meetings & Knowledge workspace template
|
|
2
|
+
# A standalone capture layer for meetings: pull the transcript, summarize it,
|
|
3
|
+
# and turn it into the things that actually matter afterward — notes, tasks,
|
|
4
|
+
# and the people involved. Reuses the pod-wide person/task/note kinds so a
|
|
5
|
+
# meeting's output lands where every other workspace already looks for it.
|
|
6
|
+
|
|
7
|
+
meta:
|
|
8
|
+
slug: meetings-knowledge
|
|
9
|
+
name: Meetings & Knowledge
|
|
10
|
+
description: Import and summarize meetings — transcripts become notes, action items become tasks, and attendees become tracked people.
|
|
11
|
+
icon: video
|
|
12
|
+
color: "#8B5CF6"
|
|
13
|
+
tags: [meetings, notes, tasks, transcripts, calendar]
|
|
14
|
+
isPublic: true
|
|
15
|
+
|
|
16
|
+
workspace:
|
|
17
|
+
name: Meetings & Knowledge
|
|
18
|
+
description: Import and summarize meetings — transcripts become notes, action items become tasks, and attendees become tracked people.
|
|
19
|
+
subtype: meetings-knowledge
|
|
20
|
+
visibility: pod_visible
|
|
21
|
+
capabilities:
|
|
22
|
+
- meetings.import
|
|
23
|
+
- meetings.summaries
|
|
24
|
+
sourceRoles:
|
|
25
|
+
meetings: provider
|
|
26
|
+
|
|
27
|
+
profiles:
|
|
28
|
+
# ── Meeting (owned here) ─────────────────────────────────────────────────
|
|
29
|
+
- slug: meeting
|
|
30
|
+
displayName: Meeting
|
|
31
|
+
icon: video
|
|
32
|
+
color: violet
|
|
33
|
+
description: A meeting — its date, attendees, and what came out of it.
|
|
34
|
+
properties:
|
|
35
|
+
- slug: meetingDate
|
|
36
|
+
label: Date
|
|
37
|
+
valueType: date
|
|
38
|
+
inputType: date
|
|
39
|
+
- slug: platform
|
|
40
|
+
label: Platform
|
|
41
|
+
valueType: string
|
|
42
|
+
inputType: select
|
|
43
|
+
enumValues: [zoom, google-meet, teams, in-person, other]
|
|
44
|
+
- slug: attendees
|
|
45
|
+
label: Attendees
|
|
46
|
+
valueType: array
|
|
47
|
+
inputType: text
|
|
48
|
+
- slug: status
|
|
49
|
+
label: Status
|
|
50
|
+
valueType: string
|
|
51
|
+
inputType: select
|
|
52
|
+
enumValues: [scheduled, completed, processed]
|
|
53
|
+
constraints: { defaultValue: scheduled }
|
|
54
|
+
- slug: summary
|
|
55
|
+
label: Summary
|
|
56
|
+
valueType: string
|
|
57
|
+
inputType: textarea
|
|
58
|
+
- slug: transcriptUrl
|
|
59
|
+
label: Transcript URL
|
|
60
|
+
valueType: string
|
|
61
|
+
inputType: url
|
|
62
|
+
|
|
63
|
+
views:
|
|
64
|
+
- name: Meetings
|
|
65
|
+
slug: meetings
|
|
66
|
+
type: table
|
|
67
|
+
scopeProfileSlug: meeting
|
|
68
|
+
description: Every meeting, its platform, and whether it's been processed.
|
|
69
|
+
config:
|
|
70
|
+
columns: [title, meetingDate, platform, status]
|
|
71
|
+
defaultView: true
|
|
72
|
+
- name: Meetings Calendar
|
|
73
|
+
slug: meetings-calendar
|
|
74
|
+
type: calendar
|
|
75
|
+
scopeProfileSlug: meeting
|
|
76
|
+
description: Meetings on a calendar, keyed on their date.
|
|
77
|
+
- name: Action Items
|
|
78
|
+
slug: meeting-action-items
|
|
79
|
+
type: kanban
|
|
80
|
+
scopeProfileSlug: task
|
|
81
|
+
groupBy: status
|
|
82
|
+
description: Tasks generated from meetings, by status.
|
|
83
|
+
config:
|
|
84
|
+
groupBy: status
|
|
85
|
+
|
|
86
|
+
entityLinks:
|
|
87
|
+
- sourceProfileSlug: meeting
|
|
88
|
+
targetProfileSlug: person
|
|
89
|
+
type: attended_by
|
|
90
|
+
label: Attended by
|
|
91
|
+
- sourceProfileSlug: meeting
|
|
92
|
+
targetProfileSlug: task
|
|
93
|
+
type: generated
|
|
94
|
+
label: Generated
|
|
95
|
+
- sourceProfileSlug: meeting
|
|
96
|
+
targetProfileSlug: note
|
|
97
|
+
type: summarized_in
|
|
98
|
+
label: Summarized in
|
|
99
|
+
|
|
100
|
+
# Playbook — pulls the transcript (Fireflies) and calendar context (Google
|
|
101
|
+
# Calendar), summarizes it, and writes the follow-through: a note, tasks per
|
|
102
|
+
# action item, and any new attendees. Bound to the meeting kind so a captured
|
|
103
|
+
# meeting can offer this as a session.
|
|
104
|
+
playbooks:
|
|
105
|
+
- name: Import & Summarize Meeting
|
|
106
|
+
description: Pull a meeting's transcript, summarize it, and extract action items and attendees into tasks, notes, and people.
|
|
107
|
+
goalTemplate: >-
|
|
108
|
+
Import the meeting {meeting} — pull its transcript from Fireflies and use
|
|
109
|
+
Google Calendar for scheduling/attendee context. Produce: {outputTypes}.
|
|
110
|
+
Create a note with the summary, create a task for each action item, and
|
|
111
|
+
make sure attendees not already tracked are captured as person entities.
|
|
112
|
+
Update the meeting record's summary, transcriptUrl, and status.
|
|
113
|
+
subjectProfile:
|
|
114
|
+
profileSlug: meeting
|
|
115
|
+
params:
|
|
116
|
+
- { name: meeting, type: entity, label: Meeting, required: true }
|
|
117
|
+
- { name: outputTypes, type: text, label: Outputs, defaultValue: "a summary note, action-item tasks, and updated attendee records" }
|
|
118
|
+
executor: is-agent
|
|
119
|
+
grants:
|
|
120
|
+
- fireflies_import_last_meeting
|
|
121
|
+
- fireflies_search
|
|
122
|
+
- calendar_list
|
|
123
|
+
- entity.create
|
|
124
|
+
status: active
|
|
125
|
+
|
|
126
|
+
# Transcript import via Fireflies, calendar/attendee context via Google
|
|
127
|
+
# (nango-google). The user connects each once on install; a missing key fails
|
|
128
|
+
# gracefully per-skill.
|
|
129
|
+
integrations:
|
|
130
|
+
- templateKey: fireflies
|
|
131
|
+
- templateKey: nango-google
|
|
132
|
+
|
|
133
|
+
onboarding:
|
|
134
|
+
goal: >
|
|
135
|
+
Get recent meetings into the pod so summaries, action items, and attendees
|
|
136
|
+
are captured instead of living only in someone's memory of the call.
|
|
137
|
+
framing: |
|
|
138
|
+
THE CHIEF OF STAFF: Act as a sharp chief of staff who turns meetings into
|
|
139
|
+
follow-through. A meeting with no summary and no action items didn't
|
|
140
|
+
happen as far as the rest of the org is concerned.
|
|
141
|
+
expertise:
|
|
142
|
+
starters:
|
|
143
|
+
- >
|
|
144
|
+
Every meeting worth logging needs a "so what" — at least one action item
|
|
145
|
+
or decision. If a founder describes a meeting with no outcome, ask what
|
|
146
|
+
changed because of it.
|
|
147
|
+
- >
|
|
148
|
+
Attendees are people, not names in a transcript — capture them as
|
|
149
|
+
tracked contacts so the next meeting with them has history.
|
|
150
|
+
blindSpots:
|
|
151
|
+
- >
|
|
152
|
+
Recurring meetings (standups, 1:1s) get skipped because they feel
|
|
153
|
+
routine — but their action items are exactly what falls through the
|
|
154
|
+
cracks. Don't let "it's just a standup" excuse skipping capture.
|
|
155
|
+
bar: >
|
|
156
|
+
A handful of recent meetings are logged with a real summary and at least
|
|
157
|
+
one action item each, so the Import & Summarize playbook has something
|
|
158
|
+
concrete to run against.
|
|
159
|
+
collect:
|
|
160
|
+
- profileSlug: meeting
|
|
161
|
+
what: Recent or upcoming meetings worth tracking.
|
|
162
|
+
cardinality: few
|
|
163
|
+
keyFields: [meetingDate, platform]
|
|
164
|
+
openingQuestions:
|
|
165
|
+
- "What meetings do you want tracked — recurring ones, or just the important ones?"
|
|
166
|
+
- "Where do your meetings live — Zoom, Google Meet, somewhere else?"
|
|
167
|
+
- "Do you already record/transcribe them, or should that start now?"
|
|
168
|
+
doneWhen: A few meetings captured with a date and platform, at least one with a summary.
|
|
169
|
+
|
|
170
|
+
app:
|
|
171
|
+
kind: stored
|
|
172
|
+
cellKey: entity-detail
|
|
173
|
+
|
|
174
|
+
layout:
|
|
175
|
+
defaultView: Meetings
|
|
176
|
+
defaultApp: null
|
|
177
|
+
pinnedApps: [dashboard, data]
|
|
178
|
+
sidebarItems:
|
|
179
|
+
- kind: view
|
|
180
|
+
viewName: Meetings
|
|
181
|
+
label: Meetings
|
|
182
|
+
icon: video
|
|
183
|
+
- kind: view
|
|
184
|
+
viewName: Meetings Calendar
|
|
185
|
+
label: Calendar
|
|
186
|
+
icon: calendar
|
|
187
|
+
- kind: view
|
|
188
|
+
viewName: Action Items
|
|
189
|
+
label: Action Items
|
|
190
|
+
icon: check-square
|
|
191
|
+
- kind: app
|
|
192
|
+
appId: data
|
|
193
|
+
label: Data
|
|
194
|
+
icon: database
|
|
195
|
+
|
|
196
|
+
bento:
|
|
197
|
+
viewName: Meetings
|
|
198
|
+
blocks:
|
|
199
|
+
- kind: view
|
|
200
|
+
viewName: Meetings
|
|
201
|
+
pos: { x: 0, y: 0, w: 8, h: 5 }
|
|
202
|
+
- kind: view
|
|
203
|
+
viewName: Action Items
|
|
204
|
+
pos: { x: 8, y: 0, w: 4, h: 5 }
|