@synap-core/workspace-templates 0.7.1 → 0.7.2
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 +60 -1
- package/dist/index.js +234 -28
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/src/business-developer.yaml +8 -0
- package/src/catalog.test.ts +2 -2
- package/src/composition-graph.test.ts +2 -2
- package/src/concept-guard.test.ts +176 -0
- package/src/concept-guard.ts +219 -0
- package/src/ecosystem.yaml +4 -1
- package/src/generate.d.mts +15 -0
- package/src/generate.mjs +86 -0
- package/src/index.ts +11 -0
- package/src/meetings-knowledge.yaml +136 -22
- package/src/outreach-comms.yaml +5 -2
- package/src/templates-freshness.test.ts +55 -0
- package/src/templates.ts +126 -28
|
@@ -25,26 +25,92 @@ workspace:
|
|
|
25
25
|
meetings: provider
|
|
26
26
|
|
|
27
27
|
profiles:
|
|
28
|
-
# ──
|
|
28
|
+
# ── Reused pod-wide kinds ────────────────────────────────────────────────
|
|
29
|
+
# Declared minimally because the workspace-definition validator resolves view
|
|
30
|
+
# scopes and entityLink endpoints ONLY against the slugs declared here — a
|
|
31
|
+
# referenced-but-undeclared slug throws at install time, it does not fall
|
|
32
|
+
# through to the pod-wide kind. Kept light on purpose: these kinds are owned
|
|
33
|
+
# pod-wide (identity + full schema live there), this is just the local grant.
|
|
34
|
+
- slug: person
|
|
35
|
+
displayName: Person
|
|
36
|
+
icon: user
|
|
37
|
+
color: amber
|
|
38
|
+
description: A meeting attendee.
|
|
39
|
+
properties:
|
|
40
|
+
- slug: email
|
|
41
|
+
label: Email
|
|
42
|
+
valueType: string
|
|
43
|
+
inputType: email
|
|
44
|
+
|
|
45
|
+
- slug: task
|
|
46
|
+
displayName: Task
|
|
47
|
+
icon: check-square
|
|
48
|
+
color: blue
|
|
49
|
+
description: An action item that came out of a meeting.
|
|
50
|
+
properties:
|
|
51
|
+
# NOTE: the pod-wide `task` already ships `status` and `dueDate`, and the
|
|
52
|
+
# applier SKIPS properties that already exist — so these are not what makes
|
|
53
|
+
# the kanban work. They are restated only so the SLUG is declarable here
|
|
54
|
+
# (the validator resolves view scopes against this template's `profiles`).
|
|
55
|
+
# The enum mirrors the live pod-wide one exactly; diverging would be
|
|
56
|
+
# misleading since the declaration is skipped and the real lanes win.
|
|
57
|
+
- slug: status
|
|
58
|
+
label: Status
|
|
59
|
+
valueType: string
|
|
60
|
+
inputType: select
|
|
61
|
+
enumValues: [todo, in-progress, done, cancelled]
|
|
62
|
+
constraints: { defaultValue: todo }
|
|
63
|
+
- slug: dueDate
|
|
64
|
+
label: Due
|
|
65
|
+
valueType: date
|
|
66
|
+
inputType: date
|
|
67
|
+
|
|
68
|
+
- slug: note
|
|
69
|
+
displayName: Note
|
|
70
|
+
icon: file-text
|
|
71
|
+
color: violet
|
|
72
|
+
description: A note or summary captured from a meeting.
|
|
73
|
+
properties:
|
|
74
|
+
- slug: content
|
|
75
|
+
label: Content
|
|
76
|
+
valueType: string
|
|
77
|
+
inputType: textarea
|
|
78
|
+
|
|
79
|
+
# ── Event (reused pod-wide kind — the meeting's IDENTITY) ────────────────
|
|
80
|
+
# The pod already seeds `event`, and the live Google Calendar sync writes
|
|
81
|
+
# `entities.type = "event"`. A parallel `meeting` KIND would therefore sit
|
|
82
|
+
# empty beside a synced calendar AND mint a second entity for the same
|
|
83
|
+
# real-world meeting. Identity lives here; the meeting-ness is a role below.
|
|
84
|
+
- slug: event
|
|
85
|
+
displayName: Event
|
|
86
|
+
icon: calendar
|
|
87
|
+
color: sky
|
|
88
|
+
description: A calendar event — the thing a meeting actually is.
|
|
89
|
+
properties:
|
|
90
|
+
- slug: startDate
|
|
91
|
+
label: Start
|
|
92
|
+
valueType: date
|
|
93
|
+
inputType: date
|
|
94
|
+
|
|
95
|
+
# ── Meeting (a ROLE the event plays — NOT a second entity) ───────────────
|
|
96
|
+
# Kind-vs-Facets rule: a role an entity PLAYS is a facet attached to the real
|
|
97
|
+
# thing, never its own kind. Date/attendees/location come from the `event`;
|
|
98
|
+
# only these four are genuinely new. The import playbook ATTACHES this role to
|
|
99
|
+
# the already-synced event rather than creating a duplicate.
|
|
29
100
|
- slug: meeting
|
|
30
101
|
displayName: Meeting
|
|
31
102
|
icon: video
|
|
32
103
|
color: violet
|
|
33
|
-
|
|
104
|
+
scope: shared
|
|
105
|
+
profileKind: role
|
|
106
|
+
applicableKinds: [event]
|
|
107
|
+
description: The meeting hat an event wears — platform, transcript, and what came out of it.
|
|
34
108
|
properties:
|
|
35
|
-
- slug: meetingDate
|
|
36
|
-
label: Date
|
|
37
|
-
valueType: date
|
|
38
|
-
inputType: date
|
|
39
109
|
- slug: platform
|
|
40
110
|
label: Platform
|
|
41
111
|
valueType: string
|
|
42
112
|
inputType: select
|
|
43
113
|
enumValues: [zoom, google-meet, teams, in-person, other]
|
|
44
|
-
- slug: attendees
|
|
45
|
-
label: Attendees
|
|
46
|
-
valueType: array
|
|
47
|
-
inputType: text
|
|
48
114
|
- slug: status
|
|
49
115
|
label: Status
|
|
50
116
|
valueType: string
|
|
@@ -67,13 +133,37 @@ views:
|
|
|
67
133
|
scopeProfileSlug: meeting
|
|
68
134
|
description: Every meeting, its platform, and whether it's been processed.
|
|
69
135
|
config:
|
|
70
|
-
columns: [title,
|
|
136
|
+
columns: [title, startDate, platform, status]
|
|
137
|
+
# The workspace's daily question: which meetings happened but haven't been
|
|
138
|
+
# imported+summarized yet. This is the one action the workspace exists to
|
|
139
|
+
# prompt, so it is the landing view — not the full table.
|
|
140
|
+
- name: Needs Processing
|
|
141
|
+
slug: meetings-unprocessed
|
|
142
|
+
type: list
|
|
143
|
+
scopeProfileSlug: meeting
|
|
144
|
+
description: Meetings that happened but haven't been imported and summarized yet.
|
|
145
|
+
config:
|
|
146
|
+
filterBy: { field: status, operator: is, value: completed }
|
|
71
147
|
defaultView: true
|
|
148
|
+
# Summaries the playbook writes land here — without a view they're invisible.
|
|
149
|
+
- name: Meeting Notes
|
|
150
|
+
slug: meeting-notes
|
|
151
|
+
type: list
|
|
152
|
+
scopeProfileSlug: note
|
|
153
|
+
description: Summaries and notes produced from meetings.
|
|
72
154
|
- name: Meetings Calendar
|
|
73
155
|
slug: meetings-calendar
|
|
74
156
|
type: calendar
|
|
75
157
|
scopeProfileSlug: meeting
|
|
76
158
|
description: Meetings on a calendar, keyed on their date.
|
|
159
|
+
# The date comes from the underlying `event` (startDate), not the meeting
|
|
160
|
+
# role. NOTE the `properties.` prefix is REQUIRED: the calendar resolves
|
|
161
|
+
# dateField with a dotted-path walker against the entity, so a bare
|
|
162
|
+
# `startDate` reads `entity.startDate` (undefined) and only renders at all
|
|
163
|
+
# by falling through the hardcoded dueDate→startDate→startTime chain.
|
|
164
|
+
config:
|
|
165
|
+
dateField: properties.startDate
|
|
166
|
+
colorBy: status
|
|
77
167
|
- name: Action Items
|
|
78
168
|
slug: meeting-action-items
|
|
79
169
|
type: kanban
|
|
@@ -152,20 +242,41 @@ onboarding:
|
|
|
152
242
|
Recurring meetings (standups, 1:1s) get skipped because they feel
|
|
153
243
|
routine — but their action items are exactly what falls through the
|
|
154
244
|
cracks. Don't let "it's just a standup" excuse skipping capture.
|
|
245
|
+
- >
|
|
246
|
+
"Attendees" as a list of names is not attendee capture — it's a string.
|
|
247
|
+
If the summary says "Sarah will send the deck" and Sarah isn't a tracked
|
|
248
|
+
person linked to that task, the next meeting with Sarah starts from zero
|
|
249
|
+
again. Resolve every attendee to a real person, or say out loud that
|
|
250
|
+
you're choosing not to.
|
|
251
|
+
- >
|
|
252
|
+
A summary nobody re-reads is theatre. The test for a good meeting note is
|
|
253
|
+
whether someone who missed the call could act from it alone — if it needs
|
|
254
|
+
the transcript to make sense, it isn't a summary yet.
|
|
155
255
|
bar: >
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
256
|
+
The PIPE is live, not the rows: transcript source and calendar connected,
|
|
257
|
+
the Import & Summarize playbook run once end-to-end on a real recent
|
|
258
|
+
meeting, and the output inspected together — a note a human would actually
|
|
259
|
+
keep, tasks that are genuinely actionable, and attendees resolved to
|
|
260
|
+
tracked people rather than name strings. If the first import produces vague
|
|
261
|
+
tasks ("follow up"), fix the extraction bar now, not after fifty meetings.
|
|
159
262
|
collect:
|
|
263
|
+
# Deliberately NOT a backfill. The import playbook fills date, summary,
|
|
264
|
+
# attendees and action items — asking the human to type them here would
|
|
265
|
+
# invert the product's whole loop (capture → AI structures it). The only
|
|
266
|
+
# thing the agent can't infer is which meetings deserve the pipe.
|
|
160
267
|
- profileSlug: meeting
|
|
161
|
-
what:
|
|
268
|
+
what: >
|
|
269
|
+
Which recurring meetings are worth importing every time — the standing
|
|
270
|
+
1:1s, the weekly ops call. A watchlist, not a backlog.
|
|
162
271
|
cardinality: few
|
|
163
|
-
keyFields: [
|
|
272
|
+
keyFields: [platform]
|
|
164
273
|
openingQuestions:
|
|
165
|
-
- "
|
|
166
|
-
- "
|
|
167
|
-
- "
|
|
168
|
-
doneWhen:
|
|
274
|
+
- "Name a meeting from last week whose outcome you can't remember. What did that cost you?"
|
|
275
|
+
- "When a meeting produces an action item, where does it go today — and does it survive the week?"
|
|
276
|
+
- "Which recurring meeting would you cancel if you could see its action-item completion rate?"
|
|
277
|
+
doneWhen: >
|
|
278
|
+
Transcript source connected and one real meeting imported end-to-end —
|
|
279
|
+
summary note, at least one action item, and attendees resolved to people.
|
|
169
280
|
|
|
170
281
|
app:
|
|
171
282
|
kind: stored
|
|
@@ -174,7 +285,7 @@ app:
|
|
|
174
285
|
layout:
|
|
175
286
|
defaultView: Meetings
|
|
176
287
|
defaultApp: null
|
|
177
|
-
pinnedApps: [dashboard, data]
|
|
288
|
+
pinnedApps: [dashboard, data, chat]
|
|
178
289
|
sidebarItems:
|
|
179
290
|
- kind: view
|
|
180
291
|
viewName: Meetings
|
|
@@ -194,7 +305,10 @@ layout:
|
|
|
194
305
|
icon: database
|
|
195
306
|
|
|
196
307
|
bento:
|
|
197
|
-
|
|
308
|
+
# Distinct from the "Meetings" table it embeds — the bento is created as its
|
|
309
|
+
# OWN view row, so reusing an embedded view's name puts two identically-named
|
|
310
|
+
# views in the switcher and makes layout.defaultView ambiguous.
|
|
311
|
+
viewName: Meetings Home
|
|
198
312
|
blocks:
|
|
199
313
|
- kind: view
|
|
200
314
|
viewName: Meetings
|
package/src/outreach-comms.yaml
CHANGED
|
@@ -256,7 +256,7 @@ app:
|
|
|
256
256
|
layout:
|
|
257
257
|
defaultView: Campaigns
|
|
258
258
|
defaultApp: null
|
|
259
|
-
pinnedApps: [dashboard, data]
|
|
259
|
+
pinnedApps: [dashboard, data, chat]
|
|
260
260
|
sidebarItems:
|
|
261
261
|
- kind: view
|
|
262
262
|
viewName: Campaigns
|
|
@@ -272,7 +272,10 @@ layout:
|
|
|
272
272
|
icon: database
|
|
273
273
|
|
|
274
274
|
bento:
|
|
275
|
-
|
|
275
|
+
# Distinct from the "Campaigns" table it embeds — see meetings-knowledge:
|
|
276
|
+
# the bento becomes its own view row, so a shared name collides in the
|
|
277
|
+
# switcher and makes layout.defaultView ambiguous.
|
|
278
|
+
viewName: Outreach Home
|
|
276
279
|
blocks:
|
|
277
280
|
- kind: view
|
|
278
281
|
viewName: Campaigns
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FRESHNESS GATE for the generated-and-committed `src/templates.ts`.
|
|
3
|
+
*
|
|
4
|
+
* WHY (read before deleting):
|
|
5
|
+
* `src/templates.ts` is generated from `src/*.yaml` by `build.mjs` and is
|
|
6
|
+
* COMMITTED to git. Every other check in this package — `concept-guard`,
|
|
7
|
+
* `catalog`, `composition-graph`, the backend's shared-role tripwire — reads
|
|
8
|
+
* that committed snapshot, NOT the YAML. Root `pnpm test` does not regenerate
|
|
9
|
+
* it. So before this test, an author could edit a template YAML, run
|
|
10
|
+
* `pnpm test`, and get a green guard against vocabulary that no longer exists
|
|
11
|
+
* on disk. A guard that can pass against a stale artifact is not a guard.
|
|
12
|
+
*
|
|
13
|
+
* This test closes that hole in the cheapest possible place: the existing
|
|
14
|
+
* `pnpm test` CI step. It re-renders the corpus IN MEMORY with the SAME
|
|
15
|
+
* function `build.mjs` uses (`src/generate.mjs`) and asserts the committed file
|
|
16
|
+
* matches byte-for-byte. No build dependency, no extra CI step, ~tens of ms.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { readFileSync } from "node:fs";
|
|
20
|
+
import { describe, expect, it } from "vitest";
|
|
21
|
+
import {
|
|
22
|
+
readYamlTemplates,
|
|
23
|
+
renderTemplatesModule,
|
|
24
|
+
TEMPLATES_FILE,
|
|
25
|
+
} from "./generate.mjs";
|
|
26
|
+
|
|
27
|
+
describe("templates.ts freshness", () => {
|
|
28
|
+
it("matches what build.mjs would generate from src/*.yaml", () => {
|
|
29
|
+
const expected = renderTemplatesModule(readYamlTemplates());
|
|
30
|
+
const actual = readFileSync(TEMPLATES_FILE, "utf-8");
|
|
31
|
+
|
|
32
|
+
if (actual !== expected) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
[
|
|
35
|
+
"",
|
|
36
|
+
"❌ src/templates.ts is STALE — it no longer matches src/*.yaml.",
|
|
37
|
+
"",
|
|
38
|
+
" Every template check (concept-guard, catalog, composition-graph, and",
|
|
39
|
+
" synap-backend's shared-role tripwire) reads this generated file, so a",
|
|
40
|
+
" stale snapshot makes them all green against vocabulary that is not on",
|
|
41
|
+
" disk anymore.",
|
|
42
|
+
"",
|
|
43
|
+
" FIX — regenerate and commit the result:",
|
|
44
|
+
" cd synap-app/packages/workspace-templates && pnpm build:yaml",
|
|
45
|
+
"",
|
|
46
|
+
" (`pnpm build` also regenerates, and additionally runs tsup + the",
|
|
47
|
+
" converter/concept guards.)",
|
|
48
|
+
"",
|
|
49
|
+
].join("\n"),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
expect(actual).toBe(expected);
|
|
54
|
+
});
|
|
55
|
+
});
|
package/src/templates.ts
CHANGED
|
@@ -6790,6 +6790,7 @@ const DATA = {
|
|
|
6790
6790
|
"description": "A person or company actively being qualified or contacted by this CRM workspace.",
|
|
6791
6791
|
"scope": "WORKSPACE",
|
|
6792
6792
|
"profileKind": "role",
|
|
6793
|
+
"semanticSlug": "crm.lead",
|
|
6793
6794
|
"applicableKinds": [
|
|
6794
6795
|
"person",
|
|
6795
6796
|
"company"
|
|
@@ -6897,6 +6898,7 @@ const DATA = {
|
|
|
6897
6898
|
"description": "A CRM lead converted by a won commercial proposal and ready for handoff.",
|
|
6898
6899
|
"scope": "WORKSPACE",
|
|
6899
6900
|
"profileKind": "role",
|
|
6901
|
+
"semanticSlug": "crm.client",
|
|
6900
6902
|
"applicableKinds": [
|
|
6901
6903
|
"person",
|
|
6902
6904
|
"company"
|
|
@@ -13243,7 +13245,7 @@ const DATA = {
|
|
|
13243
13245
|
]
|
|
13244
13246
|
},
|
|
13245
13247
|
"bento": {
|
|
13246
|
-
"viewName": "Ecosystem
|
|
13248
|
+
"viewName": "Ecosystem Home",
|
|
13247
13249
|
"blocks": [
|
|
13248
13250
|
{
|
|
13249
13251
|
"kind": "view",
|
|
@@ -22472,18 +22474,92 @@ const DATA = {
|
|
|
22472
22474
|
},
|
|
22473
22475
|
"profiles": [
|
|
22474
22476
|
{
|
|
22475
|
-
"slug": "
|
|
22476
|
-
"displayName": "
|
|
22477
|
-
"icon": "
|
|
22477
|
+
"slug": "person",
|
|
22478
|
+
"displayName": "Person",
|
|
22479
|
+
"icon": "user",
|
|
22480
|
+
"color": "amber",
|
|
22481
|
+
"description": "A meeting attendee.",
|
|
22482
|
+
"properties": [
|
|
22483
|
+
{
|
|
22484
|
+
"slug": "email",
|
|
22485
|
+
"label": "Email",
|
|
22486
|
+
"valueType": "string",
|
|
22487
|
+
"inputType": "email"
|
|
22488
|
+
}
|
|
22489
|
+
]
|
|
22490
|
+
},
|
|
22491
|
+
{
|
|
22492
|
+
"slug": "task",
|
|
22493
|
+
"displayName": "Task",
|
|
22494
|
+
"icon": "check-square",
|
|
22495
|
+
"color": "blue",
|
|
22496
|
+
"description": "An action item that came out of a meeting.",
|
|
22497
|
+
"properties": [
|
|
22498
|
+
{
|
|
22499
|
+
"slug": "status",
|
|
22500
|
+
"label": "Status",
|
|
22501
|
+
"valueType": "string",
|
|
22502
|
+
"inputType": "select",
|
|
22503
|
+
"enumValues": [
|
|
22504
|
+
"todo",
|
|
22505
|
+
"in-progress",
|
|
22506
|
+
"done",
|
|
22507
|
+
"cancelled"
|
|
22508
|
+
],
|
|
22509
|
+
"constraints": {
|
|
22510
|
+
"defaultValue": "todo"
|
|
22511
|
+
}
|
|
22512
|
+
},
|
|
22513
|
+
{
|
|
22514
|
+
"slug": "dueDate",
|
|
22515
|
+
"label": "Due",
|
|
22516
|
+
"valueType": "date",
|
|
22517
|
+
"inputType": "date"
|
|
22518
|
+
}
|
|
22519
|
+
]
|
|
22520
|
+
},
|
|
22521
|
+
{
|
|
22522
|
+
"slug": "note",
|
|
22523
|
+
"displayName": "Note",
|
|
22524
|
+
"icon": "file-text",
|
|
22478
22525
|
"color": "violet",
|
|
22479
|
-
"description": "A
|
|
22526
|
+
"description": "A note or summary captured from a meeting.",
|
|
22480
22527
|
"properties": [
|
|
22481
22528
|
{
|
|
22482
|
-
"slug": "
|
|
22483
|
-
"label": "
|
|
22529
|
+
"slug": "content",
|
|
22530
|
+
"label": "Content",
|
|
22531
|
+
"valueType": "string",
|
|
22532
|
+
"inputType": "textarea"
|
|
22533
|
+
}
|
|
22534
|
+
]
|
|
22535
|
+
},
|
|
22536
|
+
{
|
|
22537
|
+
"slug": "event",
|
|
22538
|
+
"displayName": "Event",
|
|
22539
|
+
"icon": "calendar",
|
|
22540
|
+
"color": "sky",
|
|
22541
|
+
"description": "A calendar event — the thing a meeting actually is.",
|
|
22542
|
+
"properties": [
|
|
22543
|
+
{
|
|
22544
|
+
"slug": "startDate",
|
|
22545
|
+
"label": "Start",
|
|
22484
22546
|
"valueType": "date",
|
|
22485
22547
|
"inputType": "date"
|
|
22486
|
-
}
|
|
22548
|
+
}
|
|
22549
|
+
]
|
|
22550
|
+
},
|
|
22551
|
+
{
|
|
22552
|
+
"slug": "meeting",
|
|
22553
|
+
"displayName": "Meeting",
|
|
22554
|
+
"icon": "video",
|
|
22555
|
+
"color": "violet",
|
|
22556
|
+
"scope": "shared",
|
|
22557
|
+
"profileKind": "role",
|
|
22558
|
+
"applicableKinds": [
|
|
22559
|
+
"event"
|
|
22560
|
+
],
|
|
22561
|
+
"description": "The meeting hat an event wears — platform, transcript, and what came out of it.",
|
|
22562
|
+
"properties": [
|
|
22487
22563
|
{
|
|
22488
22564
|
"slug": "platform",
|
|
22489
22565
|
"label": "Platform",
|
|
@@ -22497,12 +22573,6 @@ const DATA = {
|
|
|
22497
22573
|
"other"
|
|
22498
22574
|
]
|
|
22499
22575
|
},
|
|
22500
|
-
{
|
|
22501
|
-
"slug": "attendees",
|
|
22502
|
-
"label": "Attendees",
|
|
22503
|
-
"valueType": "array",
|
|
22504
|
-
"inputType": "text"
|
|
22505
|
-
},
|
|
22506
22576
|
{
|
|
22507
22577
|
"slug": "status",
|
|
22508
22578
|
"label": "Status",
|
|
@@ -22542,19 +22612,44 @@ const DATA = {
|
|
|
22542
22612
|
"config": {
|
|
22543
22613
|
"columns": [
|
|
22544
22614
|
"title",
|
|
22545
|
-
"
|
|
22615
|
+
"startDate",
|
|
22546
22616
|
"platform",
|
|
22547
22617
|
"status"
|
|
22548
22618
|
]
|
|
22619
|
+
}
|
|
22620
|
+
},
|
|
22621
|
+
{
|
|
22622
|
+
"name": "Needs Processing",
|
|
22623
|
+
"slug": "meetings-unprocessed",
|
|
22624
|
+
"type": "list",
|
|
22625
|
+
"scopeProfileSlug": "meeting",
|
|
22626
|
+
"description": "Meetings that happened but haven't been imported and summarized yet.",
|
|
22627
|
+
"config": {
|
|
22628
|
+
"filterBy": {
|
|
22629
|
+
"field": "status",
|
|
22630
|
+
"operator": "is",
|
|
22631
|
+
"value": "completed"
|
|
22632
|
+
}
|
|
22549
22633
|
},
|
|
22550
22634
|
"defaultView": true
|
|
22551
22635
|
},
|
|
22636
|
+
{
|
|
22637
|
+
"name": "Meeting Notes",
|
|
22638
|
+
"slug": "meeting-notes",
|
|
22639
|
+
"type": "list",
|
|
22640
|
+
"scopeProfileSlug": "note",
|
|
22641
|
+
"description": "Summaries and notes produced from meetings."
|
|
22642
|
+
},
|
|
22552
22643
|
{
|
|
22553
22644
|
"name": "Meetings Calendar",
|
|
22554
22645
|
"slug": "meetings-calendar",
|
|
22555
22646
|
"type": "calendar",
|
|
22556
22647
|
"scopeProfileSlug": "meeting",
|
|
22557
|
-
"description": "Meetings on a calendar, keyed on their date."
|
|
22648
|
+
"description": "Meetings on a calendar, keyed on their date.",
|
|
22649
|
+
"config": {
|
|
22650
|
+
"dateField": "properties.startDate",
|
|
22651
|
+
"colorBy": "status"
|
|
22652
|
+
}
|
|
22558
22653
|
},
|
|
22559
22654
|
{
|
|
22560
22655
|
"name": "Action Items",
|
|
@@ -22637,27 +22732,28 @@ const DATA = {
|
|
|
22637
22732
|
"Attendees are people, not names in a transcript — capture them as tracked contacts so the next meeting with them has history.\n"
|
|
22638
22733
|
],
|
|
22639
22734
|
"blindSpots": [
|
|
22640
|
-
"Recurring meetings (standups, 1:1s) get skipped because they feel routine — but their action items are exactly what falls through the cracks. Don't let \"it's just a standup\" excuse skipping capture.\n"
|
|
22735
|
+
"Recurring meetings (standups, 1:1s) get skipped because they feel routine — but their action items are exactly what falls through the cracks. Don't let \"it's just a standup\" excuse skipping capture.\n",
|
|
22736
|
+
"\"Attendees\" as a list of names is not attendee capture — it's a string. If the summary says \"Sarah will send the deck\" and Sarah isn't a tracked person linked to that task, the next meeting with Sarah starts from zero again. Resolve every attendee to a real person, or say out loud that you're choosing not to.\n",
|
|
22737
|
+
"A summary nobody re-reads is theatre. The test for a good meeting note is whether someone who missed the call could act from it alone — if it needs the transcript to make sense, it isn't a summary yet.\n"
|
|
22641
22738
|
],
|
|
22642
|
-
"bar": "
|
|
22739
|
+
"bar": "The PIPE is live, not the rows: transcript source and calendar connected, the Import & Summarize playbook run once end-to-end on a real recent meeting, and the output inspected together — a note a human would actually keep, tasks that are genuinely actionable, and attendees resolved to tracked people rather than name strings. If the first import produces vague tasks (\"follow up\"), fix the extraction bar now, not after fifty meetings.\n"
|
|
22643
22740
|
},
|
|
22644
22741
|
"collect": [
|
|
22645
22742
|
{
|
|
22646
22743
|
"profileSlug": "meeting",
|
|
22647
|
-
"what": "
|
|
22744
|
+
"what": "Which recurring meetings are worth importing every time — the standing 1:1s, the weekly ops call. A watchlist, not a backlog.\n",
|
|
22648
22745
|
"cardinality": "few",
|
|
22649
22746
|
"keyFields": [
|
|
22650
|
-
"meetingDate",
|
|
22651
22747
|
"platform"
|
|
22652
22748
|
]
|
|
22653
22749
|
}
|
|
22654
22750
|
],
|
|
22655
22751
|
"openingQuestions": [
|
|
22656
|
-
"
|
|
22657
|
-
"
|
|
22658
|
-
"
|
|
22752
|
+
"Name a meeting from last week whose outcome you can't remember. What did that cost you?",
|
|
22753
|
+
"When a meeting produces an action item, where does it go today — and does it survive the week?",
|
|
22754
|
+
"Which recurring meeting would you cancel if you could see its action-item completion rate?"
|
|
22659
22755
|
],
|
|
22660
|
-
"doneWhen": "
|
|
22756
|
+
"doneWhen": "Transcript source connected and one real meeting imported end-to-end — summary note, at least one action item, and attendees resolved to people.\n"
|
|
22661
22757
|
},
|
|
22662
22758
|
"app": {
|
|
22663
22759
|
"kind": "stored",
|
|
@@ -22668,7 +22764,8 @@ const DATA = {
|
|
|
22668
22764
|
"defaultApp": null,
|
|
22669
22765
|
"pinnedApps": [
|
|
22670
22766
|
"dashboard",
|
|
22671
|
-
"data"
|
|
22767
|
+
"data",
|
|
22768
|
+
"chat"
|
|
22672
22769
|
],
|
|
22673
22770
|
"sidebarItems": [
|
|
22674
22771
|
{
|
|
@@ -22698,7 +22795,7 @@ const DATA = {
|
|
|
22698
22795
|
]
|
|
22699
22796
|
},
|
|
22700
22797
|
"bento": {
|
|
22701
|
-
"viewName": "Meetings",
|
|
22798
|
+
"viewName": "Meetings Home",
|
|
22702
22799
|
"blocks": [
|
|
22703
22800
|
{
|
|
22704
22801
|
"kind": "view",
|
|
@@ -23421,7 +23518,8 @@ const DATA = {
|
|
|
23421
23518
|
"defaultApp": null,
|
|
23422
23519
|
"pinnedApps": [
|
|
23423
23520
|
"dashboard",
|
|
23424
|
-
"data"
|
|
23521
|
+
"data",
|
|
23522
|
+
"chat"
|
|
23425
23523
|
],
|
|
23426
23524
|
"sidebarItems": [
|
|
23427
23525
|
{
|
|
@@ -23445,7 +23543,7 @@ const DATA = {
|
|
|
23445
23543
|
]
|
|
23446
23544
|
},
|
|
23447
23545
|
"bento": {
|
|
23448
|
-
"viewName": "
|
|
23546
|
+
"viewName": "Outreach Home",
|
|
23449
23547
|
"blocks": [
|
|
23450
23548
|
{
|
|
23451
23549
|
"kind": "view",
|