@synap-core/workspace-templates 0.12.0 → 0.24.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/README.md +509 -0
- package/automations/bookmark-enrichment.automation.json +321 -0
- package/automations/github-pr-events.automation.json +505 -0
- package/automations/mail-feed.automation.json +86 -0
- package/automations/ship-a-change-checks-green.automation.json +106 -0
- package/automations/ship-a-change-checks-red.automation.json +106 -0
- package/automations/ship-a-change-deployed.automation.json +56 -0
- package/automations/ship-a-change-pr-merged.automation.json +110 -0
- package/automations/ship-a-change-pr-opened.automation.json +104 -0
- package/automations/url-bookmark-capture.automation.json +132 -0
- package/capabilities/agency-skills.capability.json +157 -0
- package/capabilities/apify.capability.json +265 -0
- package/capabilities/apollo.capability.json +120 -0
- package/capabilities/arch-backend.capability.json +97 -0
- package/capabilities/arch-client-intelligence.capability.json +401 -0
- package/capabilities/backblaze-b2.capability.json +205 -0
- package/capabilities/cal-com.capability.json +266 -0
- package/capabilities/canva.capability.json +274 -0
- package/capabilities/claude-code-routines.capability.json +172 -0
- package/capabilities/claude-managed-agents.capability.json +215 -0
- package/capabilities/client-comms-report.capability.json +246 -0
- package/capabilities/content-idea-to-production.capability.json +29 -0
- package/capabilities/datagouv.capability.json +315 -0
- package/capabilities/discord-bot.capability.json +157 -0
- package/capabilities/dropbox.capability.json +281 -0
- package/capabilities/exa.capability.json +109 -0
- package/capabilities/fal-ai.capability.json +83 -0
- package/capabilities/fal-media-lab.capability.json +158 -0
- package/capabilities/fireflies.capability.json +191 -0
- package/capabilities/freellmapi.capability.json +114 -0
- package/capabilities/generic-apikey.capability.json +92 -0
- package/capabilities/github-merge.capability.json +99 -0
- package/capabilities/github-read.capability.json +325 -0
- package/capabilities/governance-tighten-recommender.capability.json +81 -0
- package/capabilities/jev.capability.json +226 -0
- package/capabilities/lead-conversion-enrollment.capability.json +246 -0
- package/capabilities/mail-feed.capability.json +277 -0
- package/capabilities/mailgun.capability.json +52 -0
- package/capabilities/nango-google.capability.json +639 -0
- package/capabilities/notion.capability.json +417 -0
- package/capabilities/omniroute.capability.json +137 -0
- package/capabilities/posthog-analytics.capability.json +258 -0
- package/capabilities/postiz.capability.json +467 -0
- package/capabilities/proactive-digest.capability.json +190 -0
- package/capabilities/proton.capability.json +288 -0
- package/capabilities/replicate-rvm.capability.json +97 -0
- package/capabilities/research-methods.capability.json +57 -0
- package/capabilities/shopify.capability.json +395 -0
- package/capabilities/slack.capability.json +369 -0
- package/capabilities/stripe.capability.json +1496 -0
- package/capabilities/telegram-bridge.capability.json +56 -0
- package/capabilities/treg.capability.json +102 -0
- package/capabilities/unipile-linkedin.capability.json +494 -0
- package/capabilities/vercel.capability.json +424 -0
- package/dist/define-DqoItRiR.d.ts +1370 -0
- package/dist/index.d.ts +174 -900
- package/dist/index.js +26447 -24075
- package/dist/index.js.map +1 -1
- package/dist/wire.d.ts +222 -0
- package/dist/wire.js +77 -0
- package/dist/wire.js.map +1 -0
- package/package.json +27 -4
- package/retired.yaml +136 -0
- package/skills/app-factory-build-slice/SKILL.md +70 -0
- package/skills/app-factory-build-slice.catalog.json +17 -0
- package/skills/app-factory-design-canvas/SKILL.md +96 -0
- package/skills/app-factory-design-canvas.catalog.json +17 -0
- package/skills/app-factory-design-review/SKILL.md +105 -0
- package/skills/app-factory-design-review.catalog.json +18 -0
- package/skills/app-factory-research/SKILL.md +123 -0
- package/skills/app-factory-research.catalog.json +17 -0
- package/skills/bookmark-enrichment/SKILL.md +40 -0
- package/skills/carousel-format/carousel-format.skill.json +18 -0
- package/skills/collage-broll/collage-broll.skill.json +20 -0
- package/skills/content-taste/content-taste.skill.json +18 -0
- package/skills/creative-director/creative-director.skill.json +18 -0
- package/skills/design-critique/SKILL.md +138 -0
- package/skills/design-critique.catalog.json +12 -0
- package/skills/designing-with-real-components/SKILL.md +140 -0
- package/skills/designing-with-real-components.catalog.json +12 -0
- package/skills/edit-loop/edit-loop.skill.json +25 -0
- package/skills/facecam-edit/facecam-edit.skill.json +24 -0
- package/skills/mapping-the-server/SKILL.md +54 -0
- package/skills/math-explainer-manimgx/math-explainer-manimgx.skill.json +20 -0
- package/skills/motion-quality-gates/motion-quality-gates.skill.json +20 -0
- package/skills/open-design-edit/open-design-edit.skill.json +24 -0
- package/skills/reading-client-progress/SKILL.md +65 -0
- package/skills/routing-to-channels/SKILL.md +54 -0
- package/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
- package/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
- package/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
- package/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
- package/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
- package/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
- package/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
- package/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
- package/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
- package/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
- package/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
- package/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
- package/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
- package/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
- package/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
- package/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
- package/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
- package/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
- package/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
- package/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
- package/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
- package/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
- package/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
- package/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
- package/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
- package/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
- package/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
- package/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
- package/skills/video-direction/video-direction.skill.json +20 -0
- package/skills/video-style-vocabulary/video-style-vocabulary.skill.json +20 -0
- package/skills/video-toolbox/video-toolbox.skill.json +20 -0
- package/src/__fixtures__/lifecycle-presets.flat-before.json +205 -0
- package/src/agency-os.yaml +122 -0
- package/src/agent-os-skill-slugs.test.ts +65 -0
- package/src/apify-social-reader.test.ts +317 -0
- package/src/base.yaml +85 -39
- package/src/blockchain-ecosystem.yaml +1 -0
- package/src/brand-library.yaml +525 -14
- package/src/builder-dev-fold.template.test.ts +113 -0
- package/src/builder.yaml +779 -91
- package/src/business-model-catalog-description.test.ts +47 -0
- package/src/business-model-grp.template.test.ts +214 -0
- package/src/business-model.yaml +296 -49
- package/src/catalog-safety.test.ts +198 -0
- package/src/catalog.template-items.test.ts +75 -0
- package/src/catalog.ts +66 -2
- package/src/concept-guard.test.ts +28 -8
- package/src/concept-guard.ts +2 -2
- package/src/content-creation.template.test.ts +52 -0
- package/src/content-creation.yaml +192 -0
- package/src/content-os.edit-loop.template.test.ts +210 -0
- package/src/content-os.publish-due-posts.template.test.ts +261 -0
- package/src/content-os.template.test.ts +349 -0
- package/src/content-os.video-takes.template.test.ts +338 -0
- package/src/content-os.work-a-take.template.test.ts +125 -0
- package/src/content-os.yaml +1873 -39
- package/src/content-studio-retired.template.test.ts +82 -0
- package/src/corpus-flow-validity.test.ts +4 -5
- package/src/crm-absorbs-outreach.template.test.ts +117 -0
- package/src/crm-build-plan.template.test.ts +128 -0
- package/src/crm-lists.template.test.ts +96 -0
- package/src/crm-messages-cadence.template.test.ts +246 -0
- package/src/crm-one-send-door.template.test.ts +65 -0
- package/src/crm.yaml +1563 -181
- package/src/decisions-wave.template.test.ts +186 -0
- package/src/define.ts +146 -17
- package/src/design-to-implementation.template.test.ts +94 -0
- package/src/domain-template-type.test.ts +75 -0
- package/src/ecosystem.yaml +27 -66
- package/src/enterprise-os.yaml +10 -134
- package/src/facecam-edit.audio-studio.test.ts +188 -0
- package/src/fal-generate-image.test.ts +200 -0
- package/src/fal-media-lab-pod-files.test.ts +180 -0
- package/src/finance.yaml +254 -1
- package/src/foundation.yaml +78 -38
- package/src/frame-host-modules.d.mts +6 -0
- package/src/frame-host-modules.mjs +58 -0
- package/src/generate.mjs +9 -3
- package/src/github-merge.test.ts +210 -0
- package/src/grants.yaml +46 -17
- package/src/hr.yaml +39 -6
- package/src/index.ts +36 -1
- package/src/intent.test.ts +161 -0
- package/src/internal-runbook.yaml +19 -1
- package/src/jev.test.ts +356 -0
- package/src/legal.yaml +33 -1
- package/src/life-os.yaml +51 -240
- package/src/lifecycle-coverage.test.ts +124 -0
- package/src/lifecycle-declarations.test.ts +252 -0
- package/src/lifecycle-presets.test.ts +468 -0
- package/src/lifecycle-presets.ts +494 -0
- package/src/lifecycle-stuck.test.ts +46 -0
- package/src/lifecycle-waits.parity.test.ts +319 -0
- package/src/marketing.yaml +108 -4
- package/src/meetings-knowledge.yaml +18 -0
- package/src/networking.yaml +23 -2
- package/src/operations.yaml +304 -4
- package/src/pipeline-views.template.test.ts +88 -0
- package/src/playbook-goal-placeholders.test.ts +57 -0
- package/src/postiz-contract.test.ts +134 -0
- package/src/presentation-declarations.test.ts +174 -0
- package/src/process-contract.validate.test.ts +352 -0
- package/src/project-management.yaml +39 -740
- package/src/publish-body.d.mts +29 -0
- package/src/publish-body.mjs +74 -0
- package/src/publish-body.test.ts +74 -0
- package/src/publish-official-lib.test.ts +176 -0
- package/src/replicate-rvm.test.ts +504 -0
- package/src/research-base.yaml +119 -20
- package/src/research-decision.yaml +60 -3
- package/src/reserved-profile-slugs.test.ts +81 -0
- package/src/retired-goal-kinds.test.ts +52 -0
- package/src/role-reference-and-step-domain.test.ts +192 -0
- package/src/seed-obligation.test.ts +1 -6
- package/src/send-message-maps.test.ts +227 -0
- package/src/shared-role-ssot.test.ts +40 -2
- package/src/ship-a-change.template.test.ts +177 -0
- package/src/skills.test.ts +170 -0
- package/src/social.yaml +85 -27
- package/src/space-packages.freshness.test.ts +97 -0
- package/src/space-packages.generated.ts +40 -0
- package/src/space-packages.test.ts +125 -0
- package/src/space-packages.ts +73 -0
- package/src/start.test.ts +188 -0
- package/src/stripe-capability.test.ts +192 -0
- package/src/task-intents.test.ts +293 -0
- package/src/template-documents.test.ts +158 -0
- package/src/templates.ts +20907 -21464
- package/src/types.ts +475 -61
- package/src/unipile-linkedin-find-profile.test.ts +183 -0
- package/src/unipile-publish-post.test.ts +162 -0
- package/src/validate-flow.drift.test.ts +2 -3
- package/src/validate-flow.ts +22 -2
- package/src/validate-onboarding.test.ts +59 -0
- package/src/validate.test.ts +71 -4
- package/src/validate.ts +1416 -7
- package/src/wire-core.ts +231 -0
- package/src/wire.test.ts +159 -0
- package/src/wire.ts +107 -0
- package/views/bookmark-views-pack.view.json +39 -0
- package/views/event-views-pack.view.json +45 -0
- package/views/task-views-pack.view.json +53 -0
- package/src/agent-fleet.yaml +0 -1645
- package/src/business-developer.template.test.ts +0 -351
- package/src/business-developer.yaml +0 -860
- package/src/content-studio.yaml +0 -361
- package/src/dev-dashboard.yaml +0 -990
- package/src/outreach-comms.yaml +0 -486
- package/src/the-arch.yaml +0 -201
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: app-factory-design-canvas
|
|
3
|
+
description: Draw a new app on the design canvas with the Website Factory design kit — every page and every state, desktop and phone, in the real shadcn components from day one, with the person's real data as the sample world and one writer. Use in the Design stage of "Build an app (App Factory)", or when asked to design, mock up or draw an app's screens before building it.
|
|
4
|
+
metadata:
|
|
5
|
+
synap_native: true
|
|
6
|
+
auto_load: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# App Factory: design canvas
|
|
10
|
+
|
|
11
|
+
The canvas is where the person says yes before any code. It must show the app as it will be built: the real
|
|
12
|
+
components at their real sizes, every state, the phone, and the person's own data. Read the plan (Research output) and
|
|
13
|
+
the decisions first; draw nothing the data contract cannot fill.
|
|
14
|
+
|
|
15
|
+
## Where the boards live
|
|
16
|
+
|
|
17
|
+
1. Create the app's repo from the Website Factory now, not at build time: `pnpm create-site <dir> --name "<Name>"
|
|
18
|
+
--path <path>` in the template (a private repo `Synap-core/site-<slug>`). If the path's bundle is not available
|
|
19
|
+
yet (`pod-app` exits "bundle not available"), create it from `static`, and keep the gap in the register. Its
|
|
20
|
+
`design-kit/` is the kit; read `design-kit/README.md` fully.
|
|
21
|
+
2. Work on a branch `design` in that repo and commit `design-kit/src` AND `design-kit/out` after every round. A design
|
|
22
|
+
that lives only in a scratch folder is lost at the next reboot (it happened).
|
|
23
|
+
3. Publish `design-kit/out` (every `*.dc.html` + `canvas.json`) as the app's design canvas and put its link in the plan.
|
|
24
|
+
|
|
25
|
+
## Set the look once
|
|
26
|
+
|
|
27
|
+
Fill `design-kit/tokens.css`: the shadcn token values (background, foreground, card, primary, muted, border, input,
|
|
28
|
+
ring, destructive, radius), the state-mark extras the app uses, the fonts (`@font`), and site macros for the app's
|
|
29
|
+
vocabulary (`@macro status:draft = [[lc:active:Draft]]`, one per lifecycle option, named exactly as the pod's lifecycle).
|
|
30
|
+
Reserve each brand colour for ONE meaning and write the meaning beside it (Content Studio: red only for recording and
|
|
31
|
+
"today", yellow only for the person's own words). Never introduce a colour on a board: `design:check` refuses it.
|
|
32
|
+
|
|
33
|
+
## What to draw
|
|
34
|
+
|
|
35
|
+
- **The shell:** `src/Sidebar.dc.html` (256, the registry sidebar: groups, 32 px rows, counts as quiet grey stock or
|
|
36
|
+
a badge for a queue) and, if the app is used on a phone, `src/TabBar.dc.html` (at most five tabs; a centre `+` only
|
|
37
|
+
for capture).
|
|
38
|
+
- **One board per page** in the plan's pages table, at 1280, with `expand: fill`. Each page has ONE primary (button
|
|
39
|
+
`lg`), a header with a trail only when a parent exists, and every named thing as a link to its own board.
|
|
40
|
+
- **The phone**, 390 x 844, for every page the person uses on the phone: tab bar on every phone board, thumb buttons,
|
|
41
|
+
sheets as drawers (top radius 14, handle), root `width: 100%; max-width: 390px`, no horizontal overflow.
|
|
42
|
+
- **Every state**, per page (on its own "every state" board or beside the page):
|
|
43
|
+
loading (skeleton in the shape of the rows) · empty, with its answer named: omit (render nothing), invite (an action
|
|
44
|
+
that fills it), explain (why, and the escape), reassure ("all clear") · failed, with retry inside, never drawn as
|
|
45
|
+
empty · partly failed (the section, not the page) · gone / no access · offline · long content and many items (a cap
|
|
46
|
+
and "Show all N") · first run · an action in flight, done with undo, failed · the bridge state when a change waits as
|
|
47
|
+
a proposal in the pod (`[[pending]]`).
|
|
48
|
+
- **The app islands:** the service or pod down, access ended, not signed in / consent, the person's first run. An
|
|
49
|
+
island has no sidebar, one sentence, one way forward, and says what is safe.
|
|
50
|
+
- **The flow:** one canvas page that lays the boards out in the order a person lives them (e.g. a week), with row
|
|
51
|
+
titles in `canvas.json` notes.
|
|
52
|
+
- **The kit page:** the vocabulary sheet (`Vocabulary.dc.html`), the sidebar and the tab bar, so reviewers measure
|
|
53
|
+
against one sheet.
|
|
54
|
+
|
|
55
|
+
## The sample world
|
|
56
|
+
|
|
57
|
+
Use the real rows the research chose: same names, ids, dates and counts on every board. Draw "as of" a real day and
|
|
58
|
+
label any future-state board ("Thursday, after Monday's interview"). The person's own words are verbatim, wrapped in
|
|
59
|
+
`<mark>`; if a board needs words they have not written, it shows the empty state instead. No lorem, no invented
|
|
60
|
+
companies or people (`design:check` catches the obvious ones; the rest is on you).
|
|
61
|
+
|
|
62
|
+
## Fidelity (the numbers the review checks)
|
|
63
|
+
|
|
64
|
+
From the template's components (shadcn base-nova), as `vocab.css` draws them: button default 32 (px 10, radius 10,
|
|
65
|
+
14·500, gap 6, icon 16), `lg` 36 = the page primary, sm 28, xs 24; a larger "do it now" button only if the decisions
|
|
66
|
+
added it as a cva size first (Content Studio: one `xl` 48 for Home's single action and the phone thumb buttons). Badge
|
|
67
|
+
20 pill 12·500. Toggle 32, pressed = muted fill. Tabs 32 with a 3 px inset, active = background + shadow-sm; line tabs
|
|
68
|
+
with a 2 px indicator. Card radius 14, padding 16 (12 small), title 16·500. Item rows px 12 py 10, radius 10, title
|
|
69
|
+
14·500, description 14 muted clamped to 2 lines. Input 32, textarea min 64. Kbd 20 muted, no border. Progress 4.
|
|
70
|
+
Sidebar 256, rows 32, group label 12·500 at 70 %. Empty: padding 24, gap 16, media tile 32. Type: display 60 / 36 /
|
|
71
|
+
28 / 24 / 18 only, body 16 and 14, small 12, nothing else; weight 500 for UI, 600 section headings, 700 display;
|
|
72
|
+
spacing on the 4 px grid. Text contrast at least 4.5:1 (muted ink on a tinted ground fails first). No shadows in flow,
|
|
73
|
+
no gradients, no left accent stripes; state is a mark (glyph + one word), never a sentence.
|
|
74
|
+
|
|
75
|
+
Below 768 the sidebar becomes an offcanvas sheet with a top-bar trigger, a calendar becomes an agenda, list + detail
|
|
76
|
+
becomes list then push: draw one board at 768 or annotate. Dark mode is drawn or explicitly out of v1 (then no theme
|
|
77
|
+
toggle on any board).
|
|
78
|
+
|
|
79
|
+
## One writer, and the gates
|
|
80
|
+
|
|
81
|
+
You are the one writer: reviewers report, you apply. After every round:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pnpm design:build && pnpm design:check # lint + stale check, must be 0 problems
|
|
85
|
+
pnpm design:preview # overflow + axe per board (run heavy previews on the devbox)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Quote both outputs, commit `src/` + `out/`, republish the canvas, and list every board added or changed with its
|
|
89
|
+
title. Then hand off to `app-factory-design-review`.
|
|
90
|
+
|
|
91
|
+
## Output
|
|
92
|
+
|
|
93
|
+
The canvas link; the board list (file · title · page · states covered); a short design brief document in the pod (the
|
|
94
|
+
look decisions with each colour's one meaning, the fidelity numbers used, the sample world, open questions for the
|
|
95
|
+
person). Done when every page in the plan has its desktop board, its states and (if used on a phone) its phone
|
|
96
|
+
board, `design:check` is clean, and `design:preview` shows no overflow and no serious or critical axe issue.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "app-factory-design-canvas",
|
|
6
|
+
"name": "App Factory: design canvas",
|
|
7
|
+
"description": "Draw a new app on the design canvas with the Website Factory design kit: every page and state, desktop and phone, in the real shadcn components from day one, the person's real data as the sample world, one writer.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"skill",
|
|
10
|
+
"app-factory",
|
|
11
|
+
"design",
|
|
12
|
+
"builder"
|
|
13
|
+
],
|
|
14
|
+
"isPublic": true
|
|
15
|
+
},
|
|
16
|
+
"dependencies": []
|
|
17
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: app-factory-design-review
|
|
3
|
+
description: Review an app's design canvas with three independent, read-only lenses run in parallel — UX surface and consolidation; component fidelity, contrast and responsive; the data contract per element — then consolidate their findings as ONE writer into a brief with must-fix, boards to add, founder questions with recommended defaults, and apply it. Use in the Review and Consolidate stages of "Build an app (App Factory)", or when asked to review or critique app boards before the person approves them.
|
|
4
|
+
metadata:
|
|
5
|
+
synap_native: true
|
|
6
|
+
auto_load: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# App Factory: design review
|
|
10
|
+
|
|
11
|
+
Three lenses look at the same boards for different defects, and none of them edits. One writer then turns their
|
|
12
|
+
reports into one brief and applies it. This is how Content Studio's second round worked (2026-10-20): the UX lens found
|
|
13
|
+
the approval tray, the open loops and the dead doors; the fidelity lens re-measured every component against shadcn;
|
|
14
|
+
the data lens found fields with no data behind them and an approve button the app's key could never press.
|
|
15
|
+
|
|
16
|
+
Inputs: the design folder (`design-kit/src` + `out` of the app's repo, or the published canvas), the plan document id,
|
|
17
|
+
the data contract and identity table from research, and today's sample world. Run the three lenses as parallel
|
|
18
|
+
subagents with read-only tools. Each returns findings in this shape:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
[severity] board · element — what is wrong (evidence: measured value, quote, id or file:line) → the fix
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`severity` = `blocker` (cannot approve the design with it) · `major` · `minor`. A finding without evidence is
|
|
25
|
+
dropped. A lens never rewrites a board, never answers a founder decision itself: it lists the question.
|
|
26
|
+
|
|
27
|
+
## Lens 1 — UX surface and consolidation
|
|
28
|
+
|
|
29
|
+
Prompt (fill the braces):
|
|
30
|
+
|
|
31
|
+
> You review the design boards in {design folder} for the app described in plan document {plan doc id}. Read-only:
|
|
32
|
+
> never edit a file. Read the plan's problem, goal and pages, then every board. Report, with board and element:
|
|
33
|
+
> (1) every page with more than one primary action, or none; (2) every named thing (a count, a chip, a row, a
|
|
34
|
+
> provenance line) that is not a link to its own board — dead doors and scroll-to-anchor "navigation"; (3) state said
|
|
35
|
+
> in a sentence where a mark (glyph + one word) would do, and two marks for the same state on different boards;
|
|
36
|
+
> (4) the same value spelled or counted differently across boards (a lifecycle option, a format, a count: name the one
|
|
37
|
+
> source it should come from); (5) open loops the person owes that are not visible where they start their day; (6)
|
|
38
|
+
> every empty section and which of the four answers it gives (omit / invite / explain / reassure) and whether that is
|
|
39
|
+
> right; (7) copy that promises what the system cannot do, or asks the person to decide something an agent should
|
|
40
|
+
> propose; (8) more than one entry point for the same job, and duplicated sections; (9) approval and other commitment
|
|
41
|
+
> flows: one queue, batch, undo, and every way back (all approved, partly, cancelled, closed with no action); (10) the
|
|
42
|
+
> phone: navigation, thumb reach, what is missing that the person needs on the phone; (11) boards that must exist and
|
|
43
|
+
> do not (a state, a detail page a door points to, a first run, an island), split P0 (needed to approve) and P1;
|
|
44
|
+
> (12) the sample world: dates, names and counts that disagree between boards, and any words attributed to the person
|
|
45
|
+
> that are not verbatim from the plan's real data; (13) every filter drawn as a row of chips instead of one chip
|
|
46
|
+
> showing its value that opens a menu, and every page whose filters, tabs and search take more than one row; (14)
|
|
47
|
+
> every panel that shows all its options at once instead of the current choice and one door, every later step drawn
|
|
48
|
+
> before the earlier one is made, every option that cannot apply to this object, and every default pre-selected
|
|
49
|
+
> without a declared one; (15) anything that contradicts the object's status (a made thing offering to be made, a
|
|
50
|
+
> done step offered again, a primary that is not the next move for the status). End with the three changes that
|
|
51
|
+
> would most improve the design.
|
|
52
|
+
|
|
53
|
+
## Lens 2 — component fidelity, contrast and responsive
|
|
54
|
+
|
|
55
|
+
Prompt:
|
|
56
|
+
|
|
57
|
+
> You measure the design boards in {design folder} against the components they claim to be. Read-only. Sources of
|
|
58
|
+
> truth: the app repo's `components/ui/*.tsx` and `design-kit/vocab.css` (sizes cited inside it), the shadcn base-nova
|
|
59
|
+
> registry for components not installed yet, and `design-kit/tokens.css`. For every board report: (1) any element
|
|
60
|
+
> whose height, padding, radius, gap, font size or weight differs from its component (quote measured vs source, e.g.
|
|
61
|
+
> "button 40 px, button.tsx default h-8 = 32"); (2) hand-made pieces where a component exists (a row that should be
|
|
62
|
+
> an Item, a chip that should be a Badge or Toggle); (3) type outside the scale (display 60/36/28/24/18, body 16/14,
|
|
63
|
+
> small 12) and spacing off the 4 px grid; (4) colours used outside their one declared meaning, raw colours, gradients,
|
|
64
|
+
> shadows on in-flow surfaces, left accent stripes; (5) contrast: run `pnpm design:preview` (axe) where you can, and
|
|
65
|
+
> check by hand muted text on tinted grounds, coloured text at 12 px, text on brand fills — give the pair and the
|
|
66
|
+
> ratio; (6) responsive: what happens below 768 for every desktop board (sidebar sheet, agenda, list then push), phone
|
|
67
|
+
> boards that overflow 390 or use a fixed width, sheets and dialogs wider than their max; (7) dark mode: drawn
|
|
68
|
+
> consistently, or a theme toggle that should be removed. End with the token mapping you would put in `app/brand.css`.
|
|
69
|
+
|
|
70
|
+
## Lens 3 — data contract per element
|
|
71
|
+
|
|
72
|
+
Prompt:
|
|
73
|
+
|
|
74
|
+
> You check that every element on the design boards in {design folder} can be filled by real data and that every
|
|
75
|
+
> action can be done by the credential that would do it. Read-only. Read plan document {plan doc id} (its data contract
|
|
76
|
+
> and identity table) and read the pod live where needed (list_profiles, get_entities, counts; quote ids). For every
|
|
77
|
+
> element that shows data report: the kind and field it reads, a live example, the live count, and the read door;
|
|
78
|
+
> flag (1) elements with no field or no data behind them; (2) values on the boards that differ from the live data
|
|
79
|
+
> (counts, names, dates, statuses), and invented content, above all words attributed to the person; (3) lifecycle
|
|
80
|
+
> options or statuses that do not exist on the kind; (4) states the app cannot detect (no signal tells "late",
|
|
81
|
+
> "uploaded", "transcribed"); (5) actions the app's credential cannot do today (an app key is an agent: it proposes,
|
|
82
|
+
> it never approves, it cannot answer a session ask; quote the code or the refusal) and whether the board draws the
|
|
83
|
+
> bridge honestly; (6) read budgets: requests per page against the rate limit. Every gap gets a proposed id, an owner
|
|
84
|
+
> (platform, factory, catalog, the person) and the slice it blocks.
|
|
85
|
+
|
|
86
|
+
## Consolidate (one writer)
|
|
87
|
+
|
|
88
|
+
1. Merge the three reports. Deduplicate (the same root cause seen by two lenses is one item). Re-check any surprising
|
|
89
|
+
claim yourself before keeping it.
|
|
90
|
+
2. Classify each item: **must-fix** (apply), **justified-keep** (say why it stays — necessary is not slop), **founder
|
|
91
|
+
decision** (only the person can say), **gap** (into the plan's register with an owner).
|
|
92
|
+
3. Turn the founder decisions into 2 to 4 multiple-choice questions, each with a recommended default and the cost of
|
|
93
|
+
each option. Ask them in one message (the Decisions or Design-approval gate), never one by one.
|
|
94
|
+
4. Write the **redesign brief** as a pod document, in this order: founder decisions (binding once answered) · must-fix
|
|
95
|
+
across boards · boards to add (P0, P1) · fidelity (the measured numbers and token mapping) · real data (the one
|
|
96
|
+
sample world) · process notes. Content Studio's brief is the reference shape.
|
|
97
|
+
5. Apply it yourself, as the only writer: edit `design-kit/src`, `pnpm design:build && pnpm design:check`, `pnpm
|
|
98
|
+
design:preview`, commit `src` + `out`, republish the canvas, and list every board changed or added.
|
|
99
|
+
|
|
100
|
+
## Verify pass
|
|
101
|
+
|
|
102
|
+
Before asking the person to approve: re-run `design:check` and `design:preview` and quote them; grep the boards for
|
|
103
|
+
every must-fix you claim done (the old string gone, the new one present); confirm every P0 board exists on the canvas;
|
|
104
|
+
confirm no lens finding was silently dropped (each is applied, kept with a reason, a question, or a gap). Then the
|
|
105
|
+
person approves the design on the canvas; nothing is built from boards they have not approved.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "app-factory-design-review",
|
|
6
|
+
"name": "App Factory: design review",
|
|
7
|
+
"description": "Review an app's design canvas with three read-only lenses in parallel (UX surface, component fidelity and contrast, data contract per element), then consolidate as one writer into a brief with must-fix items, boards to add and the person's questions with recommended defaults.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"skill",
|
|
10
|
+
"app-factory",
|
|
11
|
+
"design",
|
|
12
|
+
"review",
|
|
13
|
+
"builder"
|
|
14
|
+
],
|
|
15
|
+
"isPublic": true
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: app-factory-research
|
|
3
|
+
description: Research a new app before anything is drawn — intake in the person's words, a name-collision check, a data contract per screen with live counts, an identity and permission check (who writes, who approves, can the app's credential do it), platform gaps with owners, and the real sample data the boards will use. Use in the Research stage of "Build an app (App Factory)", or whenever someone says "let's build app X" and nothing is designed yet.
|
|
4
|
+
metadata:
|
|
5
|
+
synap_native: true
|
|
6
|
+
auto_load: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# App Factory: research
|
|
10
|
+
|
|
11
|
+
Research decides what can be drawn. On Content Studio (2026-10-20) the biggest rework came from learning AFTER the
|
|
12
|
+
first canvas that an app key is an agent (it cannot act as the person, approve, or answer an ask) and that several drawn
|
|
13
|
+
fields had no data behind them. So the order is fixed: **intake → name → data contract → identity and permission →
|
|
14
|
+
platform gaps → sample world**, and only then decisions and design.
|
|
15
|
+
|
|
16
|
+
Everything you claim here is either a live read (quote the id and the value) or a code read (quote `file:line`). A
|
|
17
|
+
claim with neither is a guess: write it as an open question, never as a fact.
|
|
18
|
+
|
|
19
|
+
## 1. Intake (the person's words first)
|
|
20
|
+
|
|
21
|
+
1. Recall before asking: `synap_ask` about the subject, `synap_orient` for spaces and projects, `synap_list_playbooks`
|
|
22
|
+
for an existing process. Read the person's brief, their notes and any earlier plan.
|
|
23
|
+
2. Write, in their words (quote them): **the problem**, **the goal**, **the measure of success** (theirs, not yours),
|
|
24
|
+
and **not in v1**. A problem stated as a feature list is not a problem yet: ask what is hard today.
|
|
25
|
+
3. Pick the **path** with three questions (Website Factory AGENTS.md "Data: pick the path first"):
|
|
26
|
+
do people sign in with their OWN pod (pod-app)? does it show data from ONE pod (showcase) or none (static)? is
|
|
27
|
+
everything it shows public? A private app over the owner's pod is none of the three public paths: say so, it decides
|
|
28
|
+
identity (section 4).
|
|
29
|
+
4. Collect what is still unknown as candidate decisions: each one a multiple-choice question with a recommended
|
|
30
|
+
default and the reason for the default. Do not send them yet: the Decisions stage sends 2 to 4 of them, batched.
|
|
31
|
+
|
|
32
|
+
## 2. Name collision check
|
|
33
|
+
|
|
34
|
+
Search before the name sticks. A name that already means something else costs a rename across URLs, app ids and copy.
|
|
35
|
+
|
|
36
|
+
- the pod: `synap_ask "<name>"`, `synap_find` on apps (`devplane_app`) and spaces;
|
|
37
|
+
- the catalog: `meta.name` / `meta.slug` in `synap-app/packages/workspace-templates/src/*.yaml`, capability keys;
|
|
38
|
+
- deprecated and live surfaces: `DEPRECATED_SURFACES` in `@synap-core/types/surfaces`, the browser app manifest
|
|
39
|
+
(`browser/electron/renderer/src/apps/manifest.ts`), relay routes;
|
|
40
|
+
- repos and hosts: `gh repo list Synap-core`, the `*.synap.live` hosts you know of.
|
|
41
|
+
|
|
42
|
+
Content Studio: "Studio" was already the deprecated studio.synap.live app (and still the target of a claim link), so
|
|
43
|
+
the name became "Content Studio", never "Studio". Record the result as a decision with its evidence.
|
|
44
|
+
|
|
45
|
+
## 3. Data contract per screen
|
|
46
|
+
|
|
47
|
+
For every screen the app will have, list every element that shows or changes data:
|
|
48
|
+
|
|
49
|
+
| Screen | Element | Kind / role | Field (property slug) or relation | Live example (id: value) | Live count | Read door | Gap |
|
|
50
|
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
51
|
+
| Home | the one next action | `post` | `post-status`, `publish-date` | 32c69c61: In Draft, 6 Oct | 4 late + 1 today | `GET /api/hub/entities?profileSlug=post&workspaceId=…` | — |
|
|
52
|
+
|
|
53
|
+
Rules:
|
|
54
|
+
|
|
55
|
+
- Read it live: `synap_list_profiles` (fields, lifecycle options, which property is the lifecycle), `synap_get_entities`
|
|
56
|
+
/ `synap_find` (rows), counts by status. Quote ids.
|
|
57
|
+
- A field nobody populates is a gap, not a drawing. A convention (e.g. the person's words stored after "Original:" in
|
|
58
|
+
`content`) is verified on real rows and noted; an undeclared property is a catalog gap.
|
|
59
|
+
- Exclude test and demo rows from counts, and list them (they pollute every number on the canvas).
|
|
60
|
+
- Name the one space (and project) the app reads; always pass `workspaceId` in the read door.
|
|
61
|
+
- A lifecycle is read from the kind's profile; the boards use its real option names, never new ones.
|
|
62
|
+
- Counts that must agree across screens come from ONE derivation: write it once here (e.g. "late = publish-date <
|
|
63
|
+
today and not Published; due today is not late").
|
|
64
|
+
|
|
65
|
+
## 4. Identity and permission check
|
|
66
|
+
|
|
67
|
+
For every action in the app, who does it and can the credential do it TODAY:
|
|
68
|
+
|
|
69
|
+
| Action | Actor (person / agent / app) | Credential | Today: writes · proposes · refused | Evidence | Target |
|
|
70
|
+
| --- | --- | --- | --- | --- | --- |
|
|
71
|
+
| approve a draft | the person | app key | refused (agents never approve) | `governance…` file:line | person sign-in |
|
|
72
|
+
|
|
73
|
+
What has been true on Synap pods (re-verify, do not trust this list):
|
|
74
|
+
|
|
75
|
+
- An app key or OAuth key minted for an app is **agent-attributed**: its writes become proposals by the app's agent,
|
|
76
|
+
it can never approve, and it cannot answer a session ask ("only the person can answer").
|
|
77
|
+
- A key pinned to workspaces gets grants per workspace (`entity.<kind>.read|create|update|delete`, the kind a row IS
|
|
78
|
+
(`entity.person.read`), never a role it wears (`lead`: a role is read with `facetSlug` under its kind's permission),
|
|
79
|
+
`proposal.read`, `session.read`, `document.read`, `relation.read`); reading ONE proposal or session by id can be
|
|
80
|
+
refused while the list works; file URLs may need a person's session.
|
|
81
|
+
- `@synap-core/sdk` is the tRPC client and throws on hub keys; a server reading `/api/hub/*` uses
|
|
82
|
+
`@synap-core/hub-rest-client`. The Website Factory's `synap:check` bans app keys and that client in PUBLIC site
|
|
83
|
+
code: a private owner-run app needs the factory's pod-app path (or a documented exemption) — a gap, never a
|
|
84
|
+
hand-edit of the check.
|
|
85
|
+
- Hub rate limits apply per key (500 requests / 15 min was measured): budget requests per page.
|
|
86
|
+
|
|
87
|
+
Verify each row by reading the backend (`synap-backend/packages/api/src/routers/hub-protocol/rest/`, the governance
|
|
88
|
+
resolver, the session-ask door) or with a live read-only call. The target column says what the action SHOULD be
|
|
89
|
+
(e.g. "the person's own click writes as them; agent work stays a proposal") so design can draw both the target and
|
|
90
|
+
the bridge.
|
|
91
|
+
|
|
92
|
+
## 5. Platform gaps, each with an owner
|
|
93
|
+
|
|
94
|
+
One register for the app: `id · what is missing · evidence · blocks which slice · owner · bridge until fixed`.
|
|
95
|
+
Owners are named: platform backend, the Website Factory, the catalog, the person (a decision or a cleanup only they can
|
|
96
|
+
approve). A gap found by one app is a shared platform feature for every next app (person sign-in for apps, a hub file
|
|
97
|
+
URL door, a hub transcribe door, an ids filter on proposals): write it so the next app can find it. A bridge is labelled
|
|
98
|
+
in the UI and the code (`// STUB(<gap id>)`), never silent.
|
|
99
|
+
|
|
100
|
+
## 6. Sample world (real data for the boards)
|
|
101
|
+
|
|
102
|
+
Pick the records the boards will draw, once, so every board tells the same story:
|
|
103
|
+
|
|
104
|
+
- today's date and the week (boards are drawn "as of" it; future-state boards are labelled, e.g. "after Monday's
|
|
105
|
+
interview");
|
|
106
|
+
- the real rows with their ids, names, statuses and dates, and the counts from section 3;
|
|
107
|
+
- the person's own words, verbatim, each with its source id. Never invent a quote, a note or an idea they did not
|
|
108
|
+
write: two invented quotes were caught at the last edit on Content Studio;
|
|
109
|
+
- the states the data really has (late items, an empty bank, a missing pillar shown as "unknown pillar").
|
|
110
|
+
|
|
111
|
+
## Output
|
|
112
|
+
|
|
113
|
+
1. A **plan document** in the pod (`synap_create_document`, the app's space), sections: 0 how to use this document
|
|
114
|
+
(any AI) · 1 problem and goal (their words) · 2 decisions (locked, and pending with defaults) · 3 facts verified
|
|
115
|
+
(claim · evidence) · 4 the flow the app makes visible · 5 pages (route · page template · shows · one primary) ·
|
|
116
|
+
6 components (only existing ones) · 7 slices (entry · steps · done when) · 8 gaps register · 9 ids. Link it to the
|
|
117
|
+
app (`devplane_app`) and the session.
|
|
118
|
+
2. The **data contract** and **identity table** (in the plan or as their own documents).
|
|
119
|
+
3. The **candidate decisions** for the Decisions stage, each multiple-choice with a recommended default.
|
|
120
|
+
|
|
121
|
+
Done when: every screen has its contract rows with live examples; every action has an identity row with evidence;
|
|
122
|
+
every gap has an id and an owner; the sample world is chosen from real rows; nothing in the plan is unverified without
|
|
123
|
+
saying so.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "app-factory-research",
|
|
6
|
+
"name": "App Factory: research",
|
|
7
|
+
"description": "Before anything is drawn for a new app: intake in the person's words, a name-collision check, a data contract per screen with live counts, who writes and who approves (can the app's credential do it), platform gaps with owners, and the real sample data the boards will use.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"skill",
|
|
10
|
+
"app-factory",
|
|
11
|
+
"research",
|
|
12
|
+
"builder"
|
|
13
|
+
],
|
|
14
|
+
"isPublic": true
|
|
15
|
+
},
|
|
16
|
+
"dependencies": []
|
|
17
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bookmark-enrichment
|
|
3
|
+
description: Enriches a bookmark entity from the page it points to — reads the URL, extracts title + description, classifies it, and links it into the CRM graph. Runs automatically when a bookmark is created.
|
|
4
|
+
metadata:
|
|
5
|
+
synap_native: true
|
|
6
|
+
auto_load: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are a bookmark enrichment agent. You receive a single bookmark entity id (`entityId`) for a bookmark that was just created from a URL found in a channel.
|
|
10
|
+
|
|
11
|
+
Do this:
|
|
12
|
+
|
|
13
|
+
1. **Read the bookmark** to get its `url` property.
|
|
14
|
+
2. **Read the page** with the `web.read` verb (`{ url }`) — the pod's one reader door; never fetch it any other way. It returns the page's `title`, `author`, `siteName` and `text` (use the first ~500 words). If it comes back `blocked` or `failed`, keep the bookmark's own title and leave it minimally enriched.
|
|
15
|
+
3. **Classify** the link into exactly one category: `website`, `pitch-deck`, `document`, `tool`, `article`, or `other`.
|
|
16
|
+
4. **Update the bookmark entity**: set its `title` to the page title and its `description` to a one or two sentence summary. Store the category in a `category` property.
|
|
17
|
+
5. **Promote when it's more than a bookmark**:
|
|
18
|
+
- If the URL is the **company website** of the client this bookmark is linked to, update that company entity's `website` property.
|
|
19
|
+
- If it is a **pitch deck** or a substantial **document**, create a `document` entity for it and link it to the client.
|
|
20
|
+
|
|
21
|
+
Be precise and quiet: enrich the bookmark, link what should be linked, and stop. Do not create duplicates — check the linked client + company first. Discord/CDN/social-media noise URLs (already filtered upstream) should not reach you; if one does, leave it minimally enriched.
|
|
22
|
+
|
|
23
|
+
## Surface + pin (significant links only)
|
|
24
|
+
|
|
25
|
+
Only do this section if the bookmark's `category` is `pitch-deck`, `document`, or `website`. Skip for `tool`, `article`, or `other` — keep the channel signal-high.
|
|
26
|
+
|
|
27
|
+
The bookmark carries `sourceChannelId` (the Discord channel the URL was posted in) and `sourceMessageId` (the message that contained the URL).
|
|
28
|
+
|
|
29
|
+
**Firewall rule (non-negotiable): NEVER post or pin in a `client-comms` channel.** Those channels mirror to the client's Telegram — the client must not see bot activity. All bot feedback goes to the client's `team` channel only.
|
|
30
|
+
|
|
31
|
+
Steps:
|
|
32
|
+
1. Look up the client entity linked to this bookmark. List its channels and identify:
|
|
33
|
+
- the `team` channel (`branchPurpose = 'team'`, internal)
|
|
34
|
+
- the `client-comms` channel (`branchPurpose = 'client-comms'`, mirrored to Telegram)
|
|
35
|
+
2. Determine where the source message came from by matching `sourceChannelId`:
|
|
36
|
+
- **Source is `client-comms`**: do NOT post or pin there. Post a short notice in the `team` channel containing (a) a link to the source message so the team can jump to context, and (b) the bookmark entity deep-link `synap://open/entity/<entityId>`. Pinning is optional in this case.
|
|
37
|
+
- **Source is the `team` channel**: it's internal — pin the source message via `pin_channel_message(sourceChannelId, sourceMessageId)` and reply in-place with the entity deep-link `synap://open/entity/<entityId>`.
|
|
38
|
+
3. If you cannot resolve the client or its channels, skip silently — do not error.
|
|
39
|
+
|
|
40
|
+
Entity deep-link format: `synap://open/entity/<entityId>` (opens the bookmark in the Synap browser app).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "carousel-format",
|
|
6
|
+
"name": "Carousel format",
|
|
7
|
+
"description": "Best-practice module for brand carousels, LinkedIn PDFs and image posts: 4:5, a hook slide, one idea per slide, tight text, real screenshots, a Link slide with the brand mark, accessible, mapped onto Story · Example · Lesson · Link, and built as a layered composition saved on the post."
|
|
8
|
+
},
|
|
9
|
+
"spec": {
|
|
10
|
+
"slug": "carousel-format",
|
|
11
|
+
"name": "Carousel format",
|
|
12
|
+
"kind": "instruction",
|
|
13
|
+
"scope": "pod",
|
|
14
|
+
"description": "Best-practice module for brand carousels, LinkedIn PDFs and image posts: 4:5, a hook slide, one idea per slide, tight text, real screenshots, a Link slide with the brand mark, accessible, mapped onto Story · Example · Lesson · Link, and built as a layered composition saved on the post.",
|
|
15
|
+
"body": "## Carousel format — how a brand carousel is built\n\nLoad this module when the post's format is a carousel. It sits under the approved carousel `content-guideline` and `brand-template`: when they say something more specific, they win.\n\n### Canvas\n\n- 4:5, 1080 × 1350 px.\n- One grid and one set of margins for every slide, taken from the template's `template-slots`. Never move the margins slide to slide.\n\n### Slides\n\n- **Slide 1 = the hook.** One claim. Headline ≤ 8 words. No logo wall, no \"a thread:\" opener.\n- **One idea per slide.**\n- **≤ ~30 words per slide.** Cut, don't shrink the type.\n- **A progression cue** on every slide but the last (counter, arrow, or a line that runs across slides).\n- **Product claims show real screenshots.** Never a fake or mocked UI. No real screen → say so and ask for one.\n- **Last slide = Link.** One call to action, one place to go, the brand mark.\n\n### Story · Example · Lesson · Link on ~7 slides\n\n| Slide | Beat | Content |\n| ----- | ------- | ------------------------------------------------ |\n| 1 | Hook | The claim, ≤ 8 words |\n| 2 | Story | The moment the reader recognises |\n| 3 | Story | What went wrong, or what was at stake |\n| 4 | Example | One concrete case — a real screen or a number |\n| 5 | Example | What changed |\n| 6 | Lesson | The principle, in one line |\n| 7 | Link | CTA + brand mark |\n\nOther goals use their frame (approved `content-guideline` type frame, or the defaults in `creative-director`) on the same skeleton: hook first, link last.\n\n### Build it: the layered composition\n\nA carousel, a LinkedIn PDF (the same slides, exported as one PDF) and an image post (one slide) are built as a **layered composition** saved on the post in the pod. No local engine: the person finishes it in Content Studio's Layers tab, in any browser. The run follows the `edit-loop` skill (passes `structure`, `visual`, `polish`; an image `visual`, `polish`): read it first. Decks, PDF documents and presentations are not built here (`open-design-edit`).\n\n**Before the first layer.**\n1. The creative-director readiness check passed on APPROVED rows, and the slide outline (one sentence per slide, in the frame for the post's goal; hot-take = Claim · Tension · Reason · Invitation) is approved on the post. Name the story object that recurs across slides, and mark each slide *their world* (the problem), *after the turn*, or *proof* (the product).\n2. Read the brand's assets from the pod: `brand-asset` rows (logos, marks, product diagrams, base scenes, forms), approved only, and the brand kit's tokens (`GET /api/hub/brand/kit`). Reuse before you generate.\n\n**The composition** (pod spec 578e0974; the same JSON as the approved Carousel 01 v5 and 02 v2):\n- ONE `content-composition` per post (`render-engine` layered, `aspect-ratio` 4:5, `composition-template` the brand-template used), made_for the post. Its body is a document holding a short note and exactly ONE ```json block: `{ \"name\", \"size\": { \"w\": 1080, \"h\": 1350 }, \"slides\": [{ \"n\", \"ground\": \"paper\" | \"ink\", \"sentence\", \"layers\": [...] }] }`. Create it once (`synap_capture`: the entity, its body, a `made_for` relation to the post); a second pass edits it, never a second composition.\n- A layer: `{ \"id\" (unique on its slide, kept forever), \"type\": \"rect\" | \"image\" | \"asset\" | \"text\" | \"chip\", \"x\", \"y\", \"w\", \"h\", \"z\", \"rot\"?, \"opacity\"?, \"role\", \"tells\" }`; image and asset layers carry `file` (a pod `file` entity id); text layers `html` (plain words, `<br>`, `<i>` for the accent) with a preset (`t-display`, `t-title`, `t-body`, `t-mono`, `t-hand`); rect layers a plain `fill`. Fields you do not know are kept as they came.\n- Every image or asset layer says what it `tells` the reader and its `role`: ground, emotion, meaning, proof, voice, chrome, sentence.\n- Type: a headline 96 px or more (104 by default), body 36 px or more (40 by default). Shorten the copy rather than shrink the type; no dead band between text and picture.\n\n**Pictures.**\n- Base scenes (emotion slides only) through the pod's fal action (`fal_generate_image`, `fal-ai/nano-banana`, one image per call). A person comes from the approved character sheet (`fal-ai/nano-banana/edit`, the sheet's public `asset-url` in `imageUrls`). Prompt: the style, the recurring character, an empty top ~30% for the headline, **blank surfaces** where a logo or label will go, then exclusions (no text, no logos, no arrows or lines, no glow). Look at every result; expect 2-4 tries. Store each kept scene in the pod and use its file id.\n- Logos and labels are their own asset layers on those blank surfaces, never asked of the generator. Product proof is a precise diagram or a real screenshot, never a mocked UI.\n\n**Saving a pass (the composition door).**\n1. Read the composition's document (`synap_get_document`): keep its `revision` and a copy of its JSON (`~/synap-work/<run session id>/versions/r<revision>.json`). That is your version before the pass (edit-loop §4.1).\n2. Edit only what the pass, or the Rework note, touches: slide by slide, layer by layer, by id.\n3. Write it with `synap_update_document`, `baseRevision` = that revision, one `replace_text` op whose `old` is the current JSON block's content and `new` the edited JSON. A \"changed after you read it\" refusal means the person saved meanwhile: read again, diff, redo your change on top of theirs. A `proposed` reply is success: the pass waits for its approval.\n4. Read it back once applied and keep that revision as your last version.\n5. **Use my edit**: diff your last version against the current JSON, slide by slide (slide `n`, then layer `id`: added, removed, moved, resized, turned, rewritten, file swapped). That diff IS the pass; change nothing of it.\n\n**Preview and files** (all of them, or the slides do not show in Content Studio):\n- Render every slide at 1080 × 1350 (PNG) and, for a LinkedIn PDF, the whole set as one PDF, with a headless browser drawing the composition as the Layers tab does (until Content Studio files its own export, the content factory's `compose.html` on the person's Mac; render online, the fonts load from Google Fonts). Check each slide at full size yourself first.\n- Upload each to the pod: titles `Carousel NN vX — slide n/N` (the PDF `Carousel NN vX — PDF`); rename the previous version's slide files out of that pattern (`… (replaced by vX)`), or both versions show. Move uploads into the Content OS space.\n- Links: the post `references` each slide; a LinkedIn twin post `references` the PDF; the composition `made_for` the post. The captions go in the post's `content` property.\n- The pass's preview (`layer-<pass>`'s `ref`) is the slide set's sheet, or the image itself for one slide.\n\nAgents never publish: the post stays in draft or Review, and the person posts.\n\n### Accessibility\n\n- Text contrast ≥ 4.5:1 against its background (WCAG AA). Check light text on photos.\n- Alt text for every slide: what it says and shows, in one or two sentences.\n\n### Caption\n\n- The first line repeats the hook.\n- Then two or three lines of context, then the same CTA as the last slide.\n\n### Slots\n\nFill every `required` slot in `template-slots`. Fill `recommended` slots when approved material exists. List any slot left empty when you hand the script back.\n"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "collage-broll",
|
|
6
|
+
"name": "Collage b-roll",
|
|
7
|
+
"description": "Turns a ~5 s narration line into an assembling paper-collage b-roll clip through three approval gates (metaphor, still, first/last-frame video on fal.ai) with QA and pod save. Use when a voiceover needs a visual metaphor clip.",
|
|
8
|
+
"tags": ["skill", "content", "video"],
|
|
9
|
+
"isPublic": true
|
|
10
|
+
},
|
|
11
|
+
"spec": {
|
|
12
|
+
"slug": "collage-broll",
|
|
13
|
+
"name": "Collage b-roll",
|
|
14
|
+
"kind": "instruction",
|
|
15
|
+
"scope": "pod",
|
|
16
|
+
"description": "Turns a ~5 s narration line into an assembling paper-collage b-roll clip through three approval gates (metaphor, still, first/last-frame video on fal.ai) with QA and pod save. Use when a voiceover needs a visual metaphor clip.",
|
|
17
|
+
"body": "# Collage b-roll\n\nTurn one line of narration (about 5 s) into a short clip of an editorial paper collage assembling itself from an empty colour field: black-and-white halftone photo cut-outs, coloured cardstock accents, crisp edges, cream keylines, soft paper shadows. It carries one idea, never the words.\n\n## Why three gates\n\nVideo generation is the expensive, slow step, and a wrong metaphor or a flawed still poisons it. So the work stops twice for the user: once on the idea (cheap text), once on the still (one image), and only then spends on video. Never skip a gate, never merge two.\n\n**Partial approval.** Gates apply per item. If the user approves items 1, 2 and 4, only those advance; 3 and 5 stay at their current gate for revision. Never generate video for an item whose still was not approved.\n\n## 0. Recall\n\n`synap_ask` for: the brand kit (palette, which overrides the colour table below), existing approved collage stills or clips for the same idea (`content-asset`), and the content piece this b-roll serves. Reuse before generating.\n\n## Gate 1: metaphor cards (text only)\n\nCompress the line into one sharp visual idea. No images, no video calls.\n\nFor each line, deliver a card:\n- **Meaning**: what the viewer must understand.\n- **Mood**: calm, surprise, urgency, relief, absurd, ironic.\n- **Visual proposition**: one sentence describing the image.\n- **Key objects**: 3-6 (more weakens the idea and destabilises assembly).\n- **Colour**: background field + 1-2 accent colours.\n- **Assembly order**: which pieces arrive first to last.\n\nNever put the narration text in the picture. For a batch, make the metaphors read as a sequence (problem, then resolution). Then stop and wait for \"approved\" or per-item notes.\n\n## Gate 2: stills + contact sheet\n\nOnly for approved metaphors. Write a visual spec, then the still prompt.\n\n**Visual spec (JSON):**\n`script_meaning`, `visual_metaphor`, `style_signature` (\"flat bold colour field, black-and-white halftone cut-outs with coloured cardstock accents, crisp cut edges, cream keylines, soft paper shadows, editorial paper collage\"), `aspect_ratio` (default 9:16), `color_field` {`background_hex`, `accent_colors`, `paper_grain`}, `elements[]` {`what`, `role`, `motion`, `placement`}, `composition` {`layout`, `negative_space`, `final_frame`}, `motion_plan` (\"structure first, subject or cards second, action and result last\"), `avoid` (\"typography, readable letters, numerals, logos, watermark, UI, subtitles, glossy 3D, photoreal environment\").\n\n**Colour by meaning** (default; the brand palette from the pod overrides it). Keep one design language per batch but vary the field by meaning; do not default everything to blue.\n\n| Field | Meaning |\n|---|---|\n| Burnt orange / red | time spent, labour, urgency |\n| Mustard yellow | tools, warning, lost know-how |\n| Deep green | understanding, taste, reset |\n| Deep purple | rules, consolidation, long-term memory |\n| Teal | judgement, collaboration, automation |\n\nAccent paper must serve hierarchy, not decoration. Do not use the brand's AI-provenance colour unless the b-roll is about AI work.\n\n**Still prompt template** (English):\n```\nAsset: final still frame for a 9:16 image-to-video b-roll clip.\nRequest: a finished editorial paper-collage image expressing [visual proposition].\nBackdrop: perfectly flat [colour] paper field [hex] with subtle uncoated paper fibre.\nStyle: premium editorial stop-motion paper collage; black-and-white halftone photographic cut-outs mixed with selective [accent] coloured cardstock.\nComposition: vertical 9:16 locked poster frame; subject within the middle 70 percent; generous clean colour-field negative space; 3-6 large separable paper groups for a later assemble-from-empty animation.\nMaterials: visible halftone dots, crisp machine-cut edges, thin warm-cream keylines, soft low-opacity drop shadows.\nConstraint: [the relationship that must read at a glance].\nAvoid: typography, readable letters, numerals, logos, watermark, UI, subtitles, glossy 3D, photoreal environment, clutter.\n```\nGenerate through a fal.ai image model (the one the team has standardised on; confirm its endpoint and input schema before calling). Keep the original file.\n\n**Still QA:** metaphor reads at a glance; subject is concentrated; no fake letters, logos, watermark or UI; enough empty field to assemble from; 3-6 clear groups, not confetti; batch is consistent in texture, varied in colour.\n\nBuild a numbered contact sheet of the stills, show it, and stop. On regeneration, write `still-contact-sheet-v2.jpg` (v3, v4...) and keep the old sheet for comparison.\n\n## Gate 3: video from first and last frame\n\nOnly for approved stills. Do not ask which model again; use the team default.\n\n1. **Frames.** Last frame = the approved still, normalised:\n `ffmpeg -y -i last-original.png -vf \"scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920\" last.png`\n First frame = an empty field of the same colour:\n `ffmpeg -y -f lavfi -i color=c=0x<HEX>:s=1080x1920 -frames:v 1 first.png`\n Keep one base object in the first frame only if the user asks.\n2. **Endpoint** (fal.ai, verified first/last-frame): `fal-ai/veo3.1/first-last-frame-to-video` (`first_frame_url`, `last_frame_url`), `fal-ai/kling-video/v2.1/pro/image-to-video` (`tail_image_url` for the last frame), or `fal-ai/kling-video/o3/standard/image-to-video` (`end_image_url`). Upload frames to get URLs; target 5 s, 9:16.\n3. **Motion prompt:**\n```\nPaper-collage stop-motion assembly. The first frame is the exact empty [colour] paper field; the last frame is the exact completed composition. One continuous locked-off vertical shot. Assemble piece by piece with crisp stop-motion timing: [3-6 elements in order: structure, subject or cards, connectors, action, result; how each slides in and snaps into place]. End by holding the supplied completed composition. Preserve framing, [hex] field, cardstock accents, paper grain, halftone dots, cream keylines, crisp edges, soft shadows. Restrained tactile 2D paper craft only. No cuts, no camera move, no zoom, no morphing, no new objects, no text, no letters, no numbers, no logos, no UI, no sound.\n```\n4. **Strip audio** regardless of the prompt: `ffmpeg -y -i clip.mp4 -map 0:v:0 -c:v copy -an clip-noaudio.mp4`. Deliver the silent version.\n5. Run a batch in parallel (about 3 at a time); rerun only the failed item, never the ones that passed.\n\n## Video QA\n\nLook at the assembly, not just the end.\n- **1 fps contact sheet:** `ffmpeg -y -i clip-noaudio.mp4 -vf \"fps=1,scale=270:480,tile=5x1\" -frames:v 1 sheet.jpg`.\n- **First frame** is near-empty field (a sliver of paper at an edge is acceptable).\n- **Middle** shows pieces arriving one by one; a global fade-in fails.\n- No cuts, zoom, 3D look or drift to a photoreal scene; no fake letters, logos, UI.\n- **End frame** side by side with the approved still. Small pose or detail drift that keeps the meaning passes; do not rerun for it.\n- Spec: duration, aspect, zero audio streams (`ffprobe`).\n\n**Fix rules:**\n- Fake letters or logos: go back and regenerate the still. Never patch them in the video prompt.\n- Weak assembly: fewer elements, and an explicit \"slides in, snaps into place\" order.\n- End frame drifts: insist the last frame is exact and the clip ends by holding it.\n- Need a strictly empty start or exact layer control: build that part in HyperFrames instead.\n\nRecord per-item QA verdicts, including flawed passes and why.\n\n## Handoff\n\n- Place the silent clip as a media layer in the HyperFrames composition, timed to its narration line.\n- Captions, labels and any type live in HyperFrames, never inside the generated clip.\n- Save every approved still and clip to the pod as `content-asset` (`synap_store_file`), with its metaphor card, visual spec, prompts and endpoint in the record, linked to the content piece, so it is found and reused instead of regenerated.\n\n## The same method for any generated b-roll\n\nThe three gates are not specific to paper collage. For any generated style (ink, isometric, clay, archival photo), keep: idea on text first; one approved still that fixes framing, palette and forbidden content; video only from approved stills with explicit first and last frames; QA on the process and the end frame; fix defects at the stage that caused them; save everything to the pod. Only the style signature, the colour rules and the prompt templates change.\n\n## Sources\n\nAdapted from gbro-collage-broll SKILL.md and evals (MIT, © 2026 狗哥笔记); translated and generalised.\n"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": []
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "content-taste",
|
|
6
|
+
"name": "Content taste",
|
|
7
|
+
"description": "Study references the brand admires, distil them into content guidelines (base, format, frame per goal), and build the kit — assets, templates with slots, token additions. Every output is a draft the person approves."
|
|
8
|
+
},
|
|
9
|
+
"spec": {
|
|
10
|
+
"slug": "content-taste",
|
|
11
|
+
"name": "Content taste",
|
|
12
|
+
"kind": "instruction",
|
|
13
|
+
"scope": "pod",
|
|
14
|
+
"description": "Study references the brand admires, distil them into content guidelines (base, format, frame per goal), and build the kit — assets, templates with slots, token additions. Every output is a draft the person approves.",
|
|
15
|
+
"body": "## Content taste — turn inspiration into guidelines and a kit\n\nYou build the brand's taste: what it admires, the rules it draws from that, and the kit it makes with. Three movements. Each produces DRAFTS. The person approves; you never approve your own work.\n\nThe brand is the project (Synap first). File everything into that project, in the Brand space.\n\n### 1. STUDY a reference\n\nThe person shares a link, a post, an image or a page they like.\n\n1. **Read it.** Reading stores nothing; it gives you the page to study.\n - Any link → `synap_run_capability` with `verbId: web.read`, `parameters: { url }`. The pod reads it with its free built-in reader and answers `{ read, offers }`: `read.status` is `ok`, `partial`, `blocked` or `failed`, with the text, author and pictures when it got them.\n - A `blocked` read says why and the next step; follow it. The pod never fetches Instagram or TikTok itself (`needs_reader`): a reader the person installed may, after a tap of theirs. Ask them to open the post in their Library and tap Read, or attach a screenshot. Never run a billed reader (`capture_social_post` or any `offers` entry with `billing: account`) in bulk or in a loop: each run is billed to the person's account. Name one with `reader` only for the single post the person pointed at.\n - To KEEP the reference, `synap_capture` the link; the person keeps posts in their Library. The `brand-reference` row below carries the URL either way.\n2. **Find or create the `brand-reference`.** Search first by `reference-url`; update the existing row rather than create a twin. New row: `reference-status` = draft, `reference-url` = the source URL, `reference-kind`.\n3. **Analyse it.** Write `reference-takeaways`, one short line per axis:\n - layout and grid\n - elements (photos, screenshots, shapes, icons)\n - type (sizes, weights, pairing)\n - colour use\n - density (words per slide or frame)\n - voice\n - hook\n - pacing\n - CTA\n4. Write `reference-avoid` (what not to take), `reference-formats` (carousel, deck, video-motion, video-face, image, text) and `reference-style`.\n5. Move `reference-status` draft → studied (`update_entity` with `expectedStatus: draft`). Ask the person to approve it.\n\n**Never copy the work.** Extract principles: \"one claim per slide, big type, real screenshot\" — never \"use their layout with our logo\".\n\n### 2. DISTIL guidelines\n\nStart when at least 3 references are approved, or when the person asks.\n\nDraft `content-guideline` entities, `guideline-status` = draft:\n\n- **One base** (`guideline-type` = base, `guideline-format` = any) — what holds for every piece.\n- **One per format used** (`guideline-type` = format, `guideline-format` = carousel, deck, video-motion, …).\n- **Frames per goal** (`guideline-type` = frame, `guideline-goal` = sell, hot-take, tutorial, product-demo, announcement, proof, behind-the-scenes, community) — the narrative order for that goal.\n\nEach guideline: a one-paragraph `guideline-summary`; the full rules in the entity's document, as short testable lines (\"headline ≤ 8 words\"), never adjectives. Link it `derived_from` every reference it draws on.\n\nOne guideline per scope: one base, one per format, one per goal. Find the existing one before you write.\n\n**A new reference never edits an approved guideline in place.** Draft a revision as a new `content-guideline` (draft), linked `derived_from` the new reference, and say what changed. The person approves it; then the old one moves to deprecated.\n\n### 3. BUILD THE KIT\n\nFrom the approved guidelines and the brand kit (`GET /api/hub/brand/kit`), draft:\n\n- **`brand-asset`** — backgrounds, textures, images (`synap_run_capability` with `verbId: fal_generate_image`, prompt in the order subject → composition → palette → texture → production → exclusions, exclusions from `reference-avoid`), and short clips. `asset-status` = draft.\n- **`brand-template`** per format, `template-status` = draft. It carries the recipe (structure, count, type scale, colour use, motion) and `template-slots`: a JSON array of `{ slot, component, need: required|recommended|optional, where }`. Example slot: `{ \"slot\": \"hook\", \"component\": \"headline\", \"need\": \"required\", \"where\": \"slide 1, top third\" }`.\n- **Token additions** — sizes, spacing, motion timings. Add them to the existing `brand-token-set` as a proposal that references its tokens. Never invent a parallel palette or type scale.\n\n### Guardrails\n\n- **Rights.** Inspiration is not copying. Store the source URL on every reference. Never reuse someone else's image, footage or copy as a brand asset.\n- **Approved only feeds generation.** Draft and studied rows are candidates. Say so when you show them.\n- **One guideline per scope.** No twins.\n- **Status moves through one door:** `update_entity` with `expectedStatus`. A conflict → re-read. `proposed` → success, keep going.\n- **Capture lessons.** When the person rejects or corrects a draft, capture why (`capture`, type lesson) so the next draft starts from it.\n"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "creative-director",
|
|
6
|
+
"name": "Creative director",
|
|
7
|
+
"description": "Check the brand is ready, pick the goal's frame, the template, the references and the assets, get the written version approved, then hand off to the one Produce Content playbook."
|
|
8
|
+
},
|
|
9
|
+
"spec": {
|
|
10
|
+
"slug": "creative-director",
|
|
11
|
+
"name": "Creative director",
|
|
12
|
+
"kind": "instruction",
|
|
13
|
+
"scope": "pod",
|
|
14
|
+
"description": "Check the brand is ready, pick the goal's frame, the template, the references and the assets, get the written version approved, then hand off to the one Produce Content playbook.",
|
|
15
|
+
"body": "## Creative director — route any content ask to the brand's approved material\n\nThe user should never have to specify fonts, palette, references or the tool chain. They say \"make a carousel about X\" or \"turn this voice note into a reel\"; you find what the pod already validated and route the ask. You are the creative director: you check the brand is ready, pick the frame, the template, the references and the assets, get the written version approved, then hand the work to the one Produce Content playbook.\n\n### 0. Readiness check — before anything else\n\nThe brand is the project (Synap first). Read the Brand space brief: its definition of \"ready for content\" is the checklist. For the target brand, confirm each piece exists and is APPROVED:\n\n1. A brand identity, filed into the project.\n2. A voice guide.\n3. Brand rules (at least the mandatory ones).\n4. At least 3 approved `brand-reference` rows.\n5. An approved `content-guideline` with `guideline-type` = base.\n6. An approved `content-guideline` with `guideline-type` = format for this post's format.\n7. At least one approved `brand-template` for this format.\n8. The frame for the post's goal: an approved `content-guideline` with `guideline-type` = frame and `guideline-goal` = the post's `post-goal` (or the default frame below).\n\nA piece is missing → name it in one line and fix the gap first. Never silently generate generic content.\n\n- Identity, voice guide or rules missing → load the `onboard` skill for the Brand space.\n- References, guidelines or templates missing → load `content-taste` (study → distil → build the kit).\n\nA draft may stand in only when the person says so. Then say which drafts you used.\n\n### 1. Read before you make anything\n\n1. **Brand kit** — `GET /api/hub/brand/kit` (voice, tokens, approved assets). Never re-derive the brand from a website capture.\n2. **Brand Library entities** — `list_entities` on `brand-template`, `content-guideline`, `brand-reference` and `brand-asset` (logos, photos, loops, music).\n3. **Keep only APPROVED rows.** `template-status`, `guideline-status`, `reference-status` and `asset-status` must be `approved`. A `draft` (or a `studied` reference) is a candidate the user has not validated — it never feeds generation. If you used one because the person allowed it, say so.\n4. **Match the style.** Each row carries a Style field (`template-style`, `reference-style`, `asset-style`: on-white, on-dark, organic, editorial, technical, generative, cinematic, playful, bold). Use the style the user named; otherwise the style of the approved template for that format; otherwise ask once.\n\n### 2. Pick the goal and its frame\n\nEvery post has a goal (`post-goal`): sell, hot-take, tutorial, product-demo, announcement, proof, behind-the-scenes, community. Not set → ask once, or infer it and say so.\n\nThe goal picks the narrative frame. Use the approved frame guideline for that goal. None approved → use the default:\n\n| Goal | Frame |\n| ------------ | --------------------------------------- |\n| sell | Story · Example · Lesson · Link |\n| hot-take | Claim · Tension · Reason · Invitation |\n| tutorial | Promise · Steps · Result · Next |\n| product-demo | Problem · Real screen · Outcome · Try it |\n\nThe `sell` frame, one line each:\n\n- **Story** — a real moment the reader recognises.\n- **Example** — one concrete case that shows it working.\n- **Lesson** — the principle the reader keeps.\n- **Link** — the one next step, and where to take it.\n\nOther goals with no approved frame → propose one as a draft `content-guideline` (type frame) through `content-taste`, and use it only if the person agrees.\n\n### 3. Route the ask\n\n| The user brings… | Format | Route inside Produce Content |\n| --------------------------------------- | ------------------ | ----------------------------------------------------------------------------------- |\n| An idea or a post to explain | carousel / image | VISUAL — approved carousel template → a layered composition on the post |\n| A topic to present (lead, event, talk) | deck / document | VISUAL — approved deck template → Open Design on the person's Mac |\n| A script or a written idea | video | VIDEO · FROM SCRATCH — script → storyboard → frames → HyperFrames |\n| An existing voice-over, talk or podcast | video | VIDEO · FROM A VOICE — transcribe, cut on its beats, build frames under it |\n| Existing footage (+ a voice) | video | VIDEO · RE-EDIT — cut, caption, add approved music and motion |\n| Words only | text / thread | TEXT — hook + CTA in the brand voice |\n\nThere is ONE playbook for every format — never author a sibling \"Produce video\" playbook. Start it on the post (`subjectProfile: post`) with the `format` param, and let its goal branch.\n\n**Format modules.** Load the module for the format before you write: `carousel-format` (carousel, LinkedIn PDF, image), `open-design-edit` (deck, PDF document). Then build pass by pass with `edit-loop`.\n\n### 4. Script gate — the written version comes first\n\nBefore any generation, write the piece in words:\n\n- carousel → a slide outline (one line per slide, mapped to the frame);\n- deck → a deck outline;\n- video → a script plus a storyboard (one line per shot);\n- text → the full text draft.\n\nAttach it to the post as a document and move the post Briefed → Scripted. Then stop. Generation starts only after the person approves the written version — the draft stage is human-gated. Changes requested → revise the script, stay in Scripted.\n\n**Status moves go through one door:** `update_entity` on `post-status` with `expectedStatus` set to the status you read. A conflict means someone moved it — re-read, then decide. A `proposed` result is success; keep going, never retry.\n\n### 5. Compose from the template\n\nA `brand-template` is the reusable answer to \"what does a Synap carousel look like\". It carries the recipe: structure, slide count, type scale, colour use, motion rules, the references it leans on and what it must avoid. It also carries `template-slots`: the slots the layout needs (slot, component, need required|recommended|optional, where). Fill every required slot; fill recommended slots when you have approved material; name any slot you left empty. Follow the template literally; deviate only when the user asks to explore.\n\nFor generative or image-model work, phrase prompts in the order subject → composition → palette → texture → production → exclusions, and take the exclusions from the references' avoid lines (`reference-avoid`).\n\n### 6. When the library is thin\n\n- **No approved template for the format** → with the person's go-ahead, produce the piece once from the kit, then propose the template as a `brand-template` with status `draft` so the user can validate it. Do once, then crystallize.\n- **The user shares a link, repo or image they like** → store it as a `brand-reference`, status `draft`, with the source URL and its Style. Load `content-taste` to study it. It joins generation only once the user approves it.\n- **A needed asset is missing** (logo variant, music bed, footage) → name the gap and ask, or draft it through `content-taste`; never invent a brand asset and pass it off as approved.\n\n### 7. Hand-off rules\n\nNothing publishes itself. Agents never publish. Move the post to Review with the output attached and a proposed publish date; the human approves on the preview. Never claim a draft reference, guideline, template or asset was \"the brand\" — cite which approved rows you used.\n"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|