@synap-core/cli 1.8.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/agent-chat.d.ts +47 -0
- package/dist/commands/agent-chat.js +250 -0
- package/dist/commands/agent-chat.js.map +1 -0
- package/dist/commands/agent-run.js +3 -4
- package/dist/commands/agent-run.js.map +1 -1
- package/dist/commands/agents.js +85 -46
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/automation.js +2 -1
- package/dist/commands/automation.js.map +1 -1
- package/dist/commands/bridge-setup.d.ts +66 -0
- package/dist/commands/bridge-setup.js +1112 -0
- package/dist/commands/bridge-setup.js.map +1 -0
- package/dist/commands/cap-connections.d.ts +28 -0
- package/dist/commands/cap-connections.js +224 -0
- package/dist/commands/cap-connections.js.map +1 -0
- package/dist/commands/capability.d.ts +89 -0
- package/dist/commands/capability.js +1594 -0
- package/dist/commands/capability.js.map +1 -0
- package/dist/commands/centrality.d.ts +20 -0
- package/dist/commands/centrality.js +95 -0
- package/dist/commands/centrality.js.map +1 -0
- package/dist/commands/connect.d.ts +2 -0
- package/dist/commands/connect.js +16 -35
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/context.js +6 -7
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/data-extra.d.ts +1 -0
- package/dist/commands/data-extra.js +41 -14
- package/dist/commands/data-extra.js.map +1 -1
- package/dist/commands/data.d.ts +4 -4
- package/dist/commands/data.js +254 -187
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +20 -0
- package/dist/commands/diagnose.js +186 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/digest.d.ts +17 -0
- package/dist/commands/digest.js +122 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/discover.d.ts +2 -0
- package/dist/commands/discover.js +25 -8
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/doc.d.ts +14 -0
- package/dist/commands/doc.js +61 -4
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/doctor.d.ts +21 -0
- package/dist/commands/doctor.js +189 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/events.js +5 -2
- package/dist/commands/events.js.map +1 -1
- package/dist/commands/explain.d.ts +1 -1
- package/dist/commands/explain.js +18 -15
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/facet.d.ts +29 -0
- package/dist/commands/facet.js +113 -0
- package/dist/commands/facet.js.map +1 -0
- package/dist/commands/graph.js +7 -4
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/import.d.ts +38 -0
- package/dist/commands/import.js +471 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.js +35 -16
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.js +3 -4
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/knowledge.d.ts +8 -0
- package/dist/commands/knowledge.js +308 -33
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/launch.d.ts +50 -0
- package/dist/commands/launch.js +790 -0
- package/dist/commands/launch.js.map +1 -0
- package/dist/commands/lens.d.ts +45 -0
- package/dist/commands/lens.js +386 -0
- package/dist/commands/lens.js.map +1 -0
- package/dist/commands/market-authoring.d.ts +45 -0
- package/dist/commands/market-authoring.js +225 -0
- package/dist/commands/market-authoring.js.map +1 -0
- package/dist/commands/market.d.ts +224 -0
- package/dist/commands/market.js +1643 -0
- package/dist/commands/market.js.map +1 -0
- package/dist/commands/mcp.d.ts +64 -0
- package/dist/commands/mcp.js +265 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/observe.js +14 -11
- package/dist/commands/observe.js.map +1 -1
- package/dist/commands/open.d.ts +21 -4
- package/dist/commands/open.js +45 -4
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/pod.d.ts +100 -0
- package/dist/commands/pod.js +359 -0
- package/dist/commands/pod.js.map +1 -0
- package/dist/commands/pods.d.ts +15 -0
- package/dist/commands/pods.js +233 -17
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.js +43 -3
- package/dist/commands/proposals-actions.js.map +1 -1
- package/dist/commands/purge.d.ts +23 -0
- package/dist/commands/purge.js +148 -0
- package/dist/commands/purge.js.map +1 -0
- package/dist/commands/raycast.d.ts +15 -0
- package/dist/commands/raycast.js +153 -0
- package/dist/commands/raycast.js.map +1 -0
- package/dist/commands/sessions.js +47 -22
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/skill-manage.d.ts +21 -0
- package/dist/commands/skill-manage.js +195 -0
- package/dist/commands/skill-manage.js.map +1 -0
- package/dist/commands/skills-commands.js +2 -1
- package/dist/commands/skills-commands.js.map +1 -1
- package/dist/commands/skills.js +7 -4
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +3 -1
- package/dist/commands/status.js +166 -14
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/statusline.d.ts +24 -0
- package/dist/commands/statusline.js +450 -0
- package/dist/commands/statusline.js.map +1 -0
- package/dist/commands/subscribe.js +2 -2
- package/dist/commands/subscribe.js.map +1 -1
- package/dist/commands/template.d.ts +42 -0
- package/dist/commands/template.js +191 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/tools.d.ts +30 -0
- package/dist/commands/tools.js +315 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commands/upload.d.ts +30 -0
- package/dist/commands/upload.js +155 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/commands/versions.d.ts +27 -0
- package/dist/commands/versions.js +277 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/commands/view.js +3 -2
- package/dist/commands/view.js.map +1 -1
- package/dist/commands/whoami.d.ts +21 -0
- package/dist/commands/whoami.js +129 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.js +894 -60
- package/dist/index.js.map +1 -1
- package/dist/lib/approval-poll.d.ts +42 -0
- package/dist/lib/approval-poll.js +52 -0
- package/dist/lib/approval-poll.js.map +1 -0
- package/dist/lib/auth.d.ts +29 -6
- package/dist/lib/auth.js +105 -94
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/bundle-version.d.ts +11 -0
- package/dist/lib/bundle-version.js +33 -0
- package/dist/lib/bundle-version.js.map +1 -0
- package/dist/lib/capture-lane.d.ts +30 -12
- package/dist/lib/capture-lane.js +73 -14
- package/dist/lib/capture-lane.js.map +1 -1
- package/dist/lib/capture-structure.d.ts +123 -0
- package/dist/lib/capture-structure.js +57 -0
- package/dist/lib/capture-structure.js.map +1 -0
- package/dist/lib/cp-packages.d.ts +177 -0
- package/dist/lib/cp-packages.js +389 -0
- package/dist/lib/cp-packages.js.map +1 -0
- package/dist/lib/describe-lens.d.ts +46 -0
- package/dist/lib/describe-lens.js +33 -0
- package/dist/lib/describe-lens.js.map +1 -0
- package/dist/lib/hub-client.d.ts +91 -1
- package/dist/lib/hub-client.js +565 -22
- package/dist/lib/hub-client.js.map +1 -1
- package/dist/lib/id.d.ts +23 -0
- package/dist/lib/id.js +35 -0
- package/dist/lib/id.js.map +1 -0
- package/dist/lib/installed.d.ts +51 -0
- package/dist/lib/installed.js +70 -0
- package/dist/lib/installed.js.map +1 -0
- package/dist/lib/next-steps.d.ts +61 -0
- package/dist/lib/next-steps.js +146 -0
- package/dist/lib/next-steps.js.map +1 -0
- package/dist/lib/pod.d.ts +144 -22
- package/dist/lib/pod.js +302 -64
- package/dist/lib/pod.js.map +1 -1
- package/dist/lib/project-ref.d.ts +95 -0
- package/dist/lib/project-ref.js +144 -0
- package/dist/lib/project-ref.js.map +1 -0
- package/dist/lib/project.d.ts +35 -0
- package/dist/lib/project.js +39 -0
- package/dist/lib/project.js.map +1 -0
- package/dist/lib/session-lens.d.ts +33 -0
- package/dist/lib/session-lens.js +76 -0
- package/dist/lib/session-lens.js.map +1 -0
- package/dist/lib/skill-import.d.ts +40 -0
- package/dist/lib/skill-import.js +203 -0
- package/dist/lib/skill-import.js.map +1 -0
- package/dist/lib/skills-installer.d.ts +17 -6
- package/dist/lib/skills-installer.js +133 -19
- package/dist/lib/skills-installer.js.map +1 -1
- package/dist/lib/suite.d.ts +28 -0
- package/dist/lib/suite.js +29 -0
- package/dist/lib/suite.js.map +1 -0
- package/dist/lib/superwhisper-import.d.ts +40 -0
- package/dist/lib/superwhisper-import.js +389 -0
- package/dist/lib/superwhisper-import.js.map +1 -0
- package/dist/lib/targets.d.ts +49 -1
- package/dist/lib/targets.js +420 -288
- package/dist/lib/targets.js.map +1 -1
- package/dist/lib/template-file.d.ts +74 -0
- package/dist/lib/template-file.js +140 -0
- package/dist/lib/template-file.js.map +1 -0
- package/dist/lib/unwrapList.d.ts +1 -0
- package/dist/lib/unwrapList.js +20 -0
- package/dist/lib/unwrapList.js.map +1 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +10 -2
- package/dist/utils/logger.js.map +1 -1
- package/node_modules/@synap/hub-rest-client/dist/index.cjs +414 -34
- package/node_modules/@synap/hub-rest-client/dist/index.d.cts +762 -22
- package/node_modules/@synap/hub-rest-client/dist/index.d.ts +762 -22
- package/node_modules/@synap/hub-rest-client/dist/index.js +414 -34
- package/node_modules/@synap/hub-rest-client/package.json +1 -1
- package/node_modules/@synap/hub-rest-client/src/client.ts +525 -37
- package/node_modules/@synap/hub-rest-client/src/index.ts +42 -0
- package/node_modules/@synap/hub-rest-client/src/setup.ts +57 -1
- package/node_modules/@synap/hub-rest-client/src/types.ts +697 -37
- package/package.json +11 -5
- package/skills/agent-os/SKILL.md +218 -0
- package/skills/manifest.json +5 -0
- package/skills/onboard/SKILL.md +193 -0
- package/skills/synap/SKILL.md +1284 -58
- package/skills/synap/_order.txt +37 -0
- package/skills/synap/_skill.yaml +24 -0
- package/skills/synap/authentication.md +10 -0
- package/skills/synap/automations.md +264 -0
- package/skills/synap/capabilities.md +107 -0
- package/skills/synap/capture.md +50 -142
- package/skills/synap/cli-operations.md +107 -0
- package/skills/synap/common-mistakes.md +13 -0
- package/skills/synap/content-os.md +83 -0
- package/skills/synap/creative-loop.md +43 -0
- package/skills/synap/crm.md +117 -0
- package/skills/synap/diagnostics.md +35 -0
- package/skills/synap/digesting-a-channel.md +63 -0
- package/skills/synap/document-embeds.md +123 -0
- package/skills/synap/escalation-ladder.md +71 -0
- package/skills/synap/focus-sessions.md +47 -0
- package/skills/synap/governance-rules.md +64 -0
- package/skills/synap/governance.md +6 -6
- package/skills/synap/graph-gardening.md +21 -0
- package/skills/synap/inline-patterns.md +38 -0
- package/skills/synap/lenses.md +38 -0
- package/skills/synap/linking-principle.md +39 -0
- package/skills/synap/linking.md +1 -0
- package/skills/synap/mental-model.md +45 -0
- package/skills/synap/more.md +7 -0
- package/skills/synap/multi-entity-capture.md +12 -0
- package/skills/synap/next-action.md +37 -0
- package/skills/synap/north-star.md +17 -0
- package/skills/synap/operating-mode-rules.md +45 -0
- package/skills/synap/operating-mode.md +9 -0
- package/skills/synap/quick-reference.md +67 -0
- package/skills/synap/reading.md +43 -0
- package/skills/synap/recap.md +21 -0
- package/skills/synap/reflexes.md +46 -0
- package/skills/synap/response-style.md +21 -0
- package/skills/synap/scope.md +13 -0
- package/skills/synap/showing.md +17 -0
- package/skills/synap/user-model.md +25 -0
- package/skills/synap/viewframe-cells.md +290 -0
- package/skills/synap/work-flow.md +113 -0
- package/skills/synap/worked-examples.md +74 -0
- package/skills/synap/workspace-design.md +45 -0
- package/skills/synap/workspace-edges.md +49 -0
- package/skills/synap/writes.md +213 -0
- package/skills/synap-app/SKILL.md +319 -0
- package/skills/synap-app/_order.txt +5 -0
- package/skills/synap-app/_skill.yaml +20 -0
- package/skills/synap-app/creating-the-base-app.md +64 -0
- package/skills/synap-app/governance.md +42 -0
- package/skills/synap-app/install-commands.md +55 -0
- package/skills/synap-app/overview.md +50 -0
- package/skills/synap-app/using-the-sdk.md +73 -0
- package/skills/synap-market/SKILL.md +335 -0
- package/skills/synap-market/_order.txt +5 -0
- package/skills/synap-market/_skill.yaml +24 -0
- package/skills/synap-market/author-and-publish.md +75 -0
- package/skills/synap-market/discover-and-fetch.md +59 -0
- package/skills/synap-market/governance-and-catalog.md +56 -0
- package/skills/synap-market/install.md +55 -0
- package/skills/synap-market/overview.md +51 -0
- package/skills/synap-schema/SKILL.md +97 -6
- package/skills/synap-schema/_order.txt +13 -0
- package/skills/synap-schema/_skill.yaml +22 -0
- package/skills/synap-schema/before-you-touch.md +14 -0
- package/skills/synap-schema/common-mistakes.md +9 -0
- package/skills/synap-schema/creating-profiles.md +17 -0
- package/skills/synap-schema/discover-profiles.md +24 -0
- package/skills/synap-schema/entity-scope.md +8 -0
- package/skills/synap-schema/extend-vs-create.md +31 -0
- package/skills/synap-schema/more.md +6 -0
- package/skills/synap-schema/overlay-properties.md +22 -0
- package/skills/synap-schema/profiles.md +3 -0
- package/skills/synap-schema/property-defs.md +29 -0
- package/skills/synap-schema/read-before-write.md +50 -0
- package/skills/synap-schema/relations.md +18 -0
- package/skills/synap-schema/worked-example.md +30 -0
- package/skills/synap-ui/SKILL.md +26 -2
- package/skills/synap-ui/_order.txt +13 -0
- package/skills/synap-ui/_skill.yaml +23 -0
- package/skills/synap-ui/ai-companion.md +27 -0
- package/skills/synap-ui/arranging-bento.md +8 -0
- package/skills/synap-ui/before-you-build.md +20 -0
- package/skills/synap-ui/bento-layouts.md +35 -0
- package/skills/synap-ui/common-mistakes.md +10 -0
- package/skills/synap-ui/creating-views.md +26 -0
- package/skills/synap-ui/four-builds.md +24 -0
- package/skills/synap-ui/more.md +7 -0
- package/skills/synap-ui/proposing-vs-extending.md +11 -0
- package/skills/synap-ui/view-list.md +24 -0
- package/skills/synap-ui/views.md +3 -0
- package/skills/synap-ui/worked-example.md +18 -0
- package/skills/synap-ui/workspaces.md +47 -0
- package/templates/automations/bookmark-enrichment.automation.json +44 -0
- package/templates/automations/mail-feed.automation.json +86 -0
- package/templates/automations/url-bookmark-capture.automation.json +70 -0
- package/templates/skills/README.md +21 -0
- package/templates/skills/authoring-automations/SKILL.md +95 -0
- package/templates/skills/authoring-automations/reference/node-matrix.md +49 -0
- package/templates/skills/authoring-capabilities/SKILL.md +93 -0
- package/templates/skills/authoring-capabilities/reference/template-anatomy.md +70 -0
- package/templates/skills/authoring-playbooks/SKILL.md +102 -0
- package/templates/skills/authoring-playbooks/reference/stages-contract.md +35 -0
- package/templates/skills/authoring-playbooks/reference/worked-example.md +64 -0
- package/templates/skills/bookmark-enrichment/SKILL.md +40 -0
- package/templates/skills/coordinating-agents/SKILL.md +32 -0
- package/templates/skills/coordinating-branches/SKILL.md +27 -0
- package/templates/skills/mapping-the-server/SKILL.md +54 -0
- package/templates/skills/reading-client-progress/SKILL.md +65 -0
- package/templates/skills/routing-to-channels/SKILL.md +54 -0
- package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
- package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
- package/templates/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
- package/templates/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
- package/templates/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
- package/templates/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
- package/templates/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
- package/dist/commands/connectors.d.ts +0 -31
- package/dist/commands/connectors.js +0 -276
- package/dist/commands/connectors.js.map +0 -1
- package/dist/commands/finish.d.ts +0 -25
- package/dist/commands/finish.js +0 -274
- package/dist/commands/finish.js.map +0 -1
- package/dist/commands/openclaw.d.ts +0 -40
- package/dist/commands/openclaw.js +0 -1148
- package/dist/commands/openclaw.js.map +0 -1
- package/dist/commands/security-audit.d.ts +0 -12
- package/dist/commands/security-audit.js +0 -100
- package/dist/commands/security-audit.js.map +0 -1
- package/dist/lib/hardening.d.ts +0 -18
- package/dist/lib/hardening.js +0 -214
- package/dist/lib/hardening.js.map +0 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
## Worked examples
|
|
2
|
+
|
|
3
|
+
### Example 1 — "Remind me to send the proposal to Acme on Friday"
|
|
4
|
+
|
|
5
|
+
1. Search for the Acme entity: `GET /entities?q=Acme&profileSlug=company` → got `ent_acme`
|
|
6
|
+
2. Search for an existing task: `GET /entities?q=proposal&profileSlug=task&workspaceId=…` → none
|
|
7
|
+
3. Create the task with links:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
POST /api/hub/entities
|
|
11
|
+
{ "userId": "{userId}", "workspaceId": "{wsId}",
|
|
12
|
+
"profileSlug": "task",
|
|
13
|
+
"title": "Send proposal to Acme",
|
|
14
|
+
"properties": {
|
|
15
|
+
"status": "todo", "priority": "high",
|
|
16
|
+
"dueDate": "2026-04-24"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
4. Link to Acme (Acme is not an entity_id property on task — use Way 2):
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
POST /api/hub/relations
|
|
25
|
+
{ "userId": "{userId}",
|
|
26
|
+
"sourceEntityId": "ent_new_task",
|
|
27
|
+
"targetEntityId": "ent_acme",
|
|
28
|
+
"type": "related_to" }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
5. Confirm: "Task created and linked to Acme, due Friday."
|
|
32
|
+
|
|
33
|
+
### Example 2 — "Who's Sarah at Acme?"
|
|
34
|
+
|
|
35
|
+
1. Search person: `GET /entities?q=Sarah&profileSlug=person` → `ent_sarah`
|
|
36
|
+
2. Pull her connections: `GET /entities/ent_sarah/connections` → company=Acme, 3 recent emails, 1 meeting
|
|
37
|
+
3. Answer from the returned data, not from your own context.
|
|
38
|
+
|
|
39
|
+
### Example 3 — "Save this article for later: https://…"
|
|
40
|
+
|
|
41
|
+
1. Search for existing bookmark: `GET /entities?q=<url>&profileSlug=article` → none
|
|
42
|
+
2. Create an article entity:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
POST /api/hub/entities
|
|
46
|
+
{ "userId": "{userId}", "workspaceId": "{wsId}",
|
|
47
|
+
"profileSlug": "article",
|
|
48
|
+
"title": "<page title>",
|
|
49
|
+
"properties": { "url": "<url>", "domain": "<host>" }
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
3. If the user said why ("interesting for the onboarding project"), also create a relation to that project — never drop the reason as a plain comment, turn it into a link.
|
|
54
|
+
|
|
55
|
+
### Example 4 — "Write up a strategic plan for the Q3 launch"
|
|
56
|
+
|
|
57
|
+
You are authoring this text yourself — it is not a file you have. Don't create
|
|
58
|
+
a `file`/`document`-kind entity and stuff the Markdown into it.
|
|
59
|
+
|
|
60
|
+
1. Search for an existing plan: `GET /entities?q=Q3 launch&profileSlug=knowledge&workspaceId=…` → none
|
|
61
|
+
2. Create a CONTENT-kind entity carrying the plan as `content` (the doc auto-materializes):
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
POST /api/hub/entities
|
|
65
|
+
{ "userId": "{userId}", "workspaceId": "{wsId}",
|
|
66
|
+
"profileSlug": "knowledge",
|
|
67
|
+
"title": "Q3 launch strategic plan",
|
|
68
|
+
"properties": { "ek_type": "reference" },
|
|
69
|
+
"content": "# Q3 Launch Plan\n\n## Goals\n…\n\n## Timeline\n…"
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
3. Link it to the relevant project: `POST /api/hub/relations` `{ sourceEntityId: "ent_new_plan", targetEntityId: "ent_project_q3", type: "related_to" }`.
|
|
74
|
+
4. Confirm: "Plan captured and linked to Q3 launch." No upload, no `file` entity, no separate `synap_create_document` call.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
## Workspace design — is this concern a WORKSPACE, or something smaller?
|
|
2
|
+
|
|
3
|
+
Before you create a workspace, run the decision rule. A workspace (an operational **domain**) is the heaviest structure in the pod — it owns kinds, confers roles, carries its own team and automations. Most new concerns are NOT domains; they are a **hat**, an **initiative**, or a **stage**. Creating a workspace for one of those is the anti-pattern that fragments the graph. Decide first, then create.
|
|
4
|
+
|
|
5
|
+
## The decision rule — a concern earns a workspace ONLY if ALL FOUR hold
|
|
6
|
+
|
|
7
|
+
1. **Owns kinds** — it is source-of-truth for a noun nothing else owns (CRM owns `person`/`company`; Operations owns `engagement`/`deliverable`). If it only _reads_ or _annotates_ another domain's kinds, it is not a domain.
|
|
8
|
+
2. **Own team** — a distinct set of operators/collaborators works it (separation of _who_, not just _what_).
|
|
9
|
+
3. **Native automations/tools** — it runs behavior its neighbors don't (its own capabilities, playbooks, triggers).
|
|
10
|
+
4. **Stable** — it persists across clients and campaigns. If it is per-client or per-campaign, it is time-bound, not a domain.
|
|
11
|
+
|
|
12
|
+
**All four, or it is not a workspace.** Then fork it to the right lighter structure:
|
|
13
|
+
|
|
14
|
+
| If the concern is… | It is a… | Substrate | Example |
|
|
15
|
+
| ----------------------------------------------------------- | -------------- | -------------------------------------- | ------------------------------------------- |
|
|
16
|
+
| a **role/hat** an existing entity wears in a domain | **Facet** | `attach_facet` (`profileKind: "role"`) | `client`, `sponsor`, `prospect`, `investor` |
|
|
17
|
+
| a **cross-cutting, time-bound initiative** spanning domains | **Project** | `create_project` (a lens) | a campaign, an engagement, a launch |
|
|
18
|
+
| a **stage/filter WITHIN a domain** | **State/View** | a `status` property def + a view | pipeline stage, "active"/"archived" |
|
|
19
|
+
|
|
20
|
+
## The decision procedure (follow in order)
|
|
21
|
+
|
|
22
|
+
1. **Name the source-of-truth noun.** What kind would this workspace _own_ that no existing workspace owns? Run `list_profiles` — if the noun already lives in another domain, you have a facet or a project, not a domain. STOP.
|
|
23
|
+
2. **Test all four conditions.** Owns kinds AND own team AND native automations AND stable. Any one fails → fork below.
|
|
24
|
+
3. **If it's a hat** (a status/role on an entity that already exists elsewhere) → resolve the entity, `attach_facet`. Never a workspace, never a second entity.
|
|
25
|
+
4. **If it's time-bound work across domains** → `create_project` and set it as the lens; the work files into it from whatever workspace holds the data. **A project is a COMMITMENT WITH GRAVITY** — a real initiative that ties work together (a campaign, an engagement, a client, a launch). Tasks, plans, repos, themes, and topics are **entities**, never projects. Before you create one: (a) **search existing projects first** (`synap orient` / `GET /api/hub/projects`) and prefer **linking into an existing project** via `belongs_to_project` — near-duplicate names are rejected with the existing candidates; (b) an agent-created project must cite **≥5 existing entities** that would belong to it as `evidenceEntityIds` — the backend rejects a project with no gravity and tells you to store it as an entity or reuse an existing project instead; (c) **never create a project for the pod owner's own company** — the company _is_ the pod, not a project inside it.
|
|
26
|
+
5. **If it's a stage inside a domain** → add a `status` property def (`create_property_def`) and a view; don't split the stage into its own space.
|
|
27
|
+
6. **Only if all four held** → **template first** (escalation ladder L3):
|
|
28
|
+
`market.search({query, kind: "template"})` and propose install of a matching
|
|
29
|
+
template before freehand `create_workspace`. Freehand create is last resort
|
|
30
|
+
and always proposed — a deliberate move, offer it to the user (see
|
|
31
|
+
`lenses.md`). Then declare how it lives in the graph (see `workspace-edges.md`).
|
|
32
|
+
|
|
33
|
+
## The CRM corollary — the load-bearing example
|
|
34
|
+
|
|
35
|
+
Operational state — **prospect → client → delivered** — is a **FLOW across domains**, expressed as **facets + a triggered project**, NEVER as workspaces and NEVER by bolting delivery onto the identity domain.
|
|
36
|
+
|
|
37
|
+
- CRM = **who** (owns `person`/`company`, confers the `lead`/`client` facets).
|
|
38
|
+
- Operations = **what we do for them** (owns `engagement`/`contract`/`deliverable`).
|
|
39
|
+
- The bridge: attaching the `client` facet in CRM **triggers** an engagement project in Operations (see the _triggers_ edge in `workspace-edges.md`).
|
|
40
|
+
|
|
41
|
+
Bolting delivery-ops onto CRM was the anti-pattern: it made one workspace own two unrelated source-of-truth concerns and blurred _who_ the entity is with _what work_ is happening. Split by ownership; bridge by facet + trigger.
|
|
42
|
+
|
|
43
|
+
## Why this matters
|
|
44
|
+
|
|
45
|
+
A workspace is a boundary; a facet/project/state is a connection. Boundaries fragment the graph — they should be rare and earned. When you catch yourself about to create a workspace, check the four conditions: nine times out of ten the honest answer is a facet on an entity that already exists, a project that spans what's already there, or a status field on a kind you already own.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
## Workspace edges — how a domain LIVES IN THE GRAPH
|
|
2
|
+
|
|
3
|
+
A workspace is never an island. Before you create one (or reason about an existing one), map its **edges**: what it consumes, what it provides, what it triggers, what subject it shares, what spans it. Domains are wired together by a small, fixed taxonomy — and each edge type maps to a specific substrate. Knowing the taxonomy is what lets you reason about a new domain's _position_ instead of dropping it in disconnected.
|
|
4
|
+
|
|
5
|
+
> The two graphs are orthogonal. This is the **data-flow graph** (what reads/writes/triggers what) — the one we model. The **org graph** (who owns/operates a domain) is workspace membership only. "Comms contains Marketing" is org; the _data_ edge is "Marketing **consumes** Comms' brand." Keep them separate so a team reorg never rewires the data graph.
|
|
6
|
+
|
|
7
|
+
## The four edge types (and their substrate)
|
|
8
|
+
|
|
9
|
+
| Edge | Meaning | Direction | Substrate | Example |
|
|
10
|
+
| ----------------------- | ------------------------------------------------ | --------- | ------------------------------------------------------------- | ----------------------------------------------------- |
|
|
11
|
+
| **Provides / Consumes** | a domain _reads_ another's data (read redirect) | A ← B | `defaultSources` / `sourceRoles` on the consuming workspace | Content **consumes** Comms' voice/ICP |
|
|
12
|
+
| **Triggers** | an event in A causes _work written_ into B | A ⇒ B | automation + `resolveWorkspacePlacement` (run-in-A → write-B) | a `client` facet in CRM ⇒ an engagement in Operations |
|
|
13
|
+
| **Shares subject** | the same atom wears a different facet per domain | A ⟷ B | `entity_facets` (one entity, per-domain roles) | one company is `lead` in CRM, `client` in Ops |
|
|
14
|
+
| **Spans** | a time-bound initiative crosses domains | A—B—C | `projects` (a cross-cutting lens) | one campaign spans Marketing + Content + Social |
|
|
15
|
+
|
|
16
|
+
Read the whole graph as: **Provides/Consumes** = the read wiring · **Triggers** = the write/event wiring · **Shares subject** = shared identity · **Spans** = shared initiative.
|
|
17
|
+
|
|
18
|
+
## Reason about position BEFORE you create
|
|
19
|
+
|
|
20
|
+
When `workspace-design.md`'s rule says "yes, this is a domain," don't stop at creating it — place it in the graph:
|
|
21
|
+
|
|
22
|
+
1. **What does it consume?** Which existing domains' data does it read? Those become its `defaultSources` (provides/consumes edges).
|
|
23
|
+
2. **What does it provide?** Which domains will read _its_ output? (Declared on the consumer's side, but know the answer.)
|
|
24
|
+
3. **What does it trigger — and what triggers it?** Which facet/event in a neighbor should spin up work here, or here into a neighbor? That's the automation + placement wiring (Wave 2 processor behavior).
|
|
25
|
+
4. **What subject does it share?** Which atoms already exist elsewhere that this domain will confer a new facet on? (Resolve identity first, `attach_facet` — never a duplicate.)
|
|
26
|
+
5. **What projects span it?** Which cross-cutting initiatives will pull its data alongside other domains'?
|
|
27
|
+
|
|
28
|
+
A domain that consumes nothing and provides nothing is a smell — re-check the decision rule; it may be a facet or a project after all.
|
|
29
|
+
|
|
30
|
+
## Declaring provides/consumes on an existing workspace
|
|
31
|
+
|
|
32
|
+
Edges used to be settable only at template-authoring time or through the tRPC UI. The agnostic door for setting them on a live workspace is the governed MCP tool **`synap_declare_workspace_source`** (Hub REST: `PATCH /workspaces/:id/source-edges`): it merges `defaultSources` / `sourceRoles` on an existing workspace so the generic edge-resolver can redirect its reads to the providing domain, and it materializes the `feeds` link the placement ladder reads.
|
|
33
|
+
|
|
34
|
+
- Use it when a domain should start reading another's data (e.g. point Marketing at Comms for brand/ICP).
|
|
35
|
+
- It is a **governed write** — a `{ status: "proposed", proposalId }` response is NORMAL, not an error. Because declaring an edge rewires where the pod's cross-workspace reads land, it goes through review: when you (an agent) call it, it is **proposed for a human to approve**, and the edge only goes live on approval (the `workspace/declare_source` proposal executor then runs the same merge). Tell the user it's **proposed for review** and share the review link — don't claim the edge is already live. (An operator calling it directly with their own authority applies immediately and gets `{ status: "updated" }`.)
|
|
36
|
+
- Setting the edge is what makes cross-workspace reads resolve generically, instead of each domain re-deriving its sources by hand.
|
|
37
|
+
|
|
38
|
+
## The reference wiring (worked example)
|
|
39
|
+
|
|
40
|
+
The 6-domain reference enterprise, read as edges:
|
|
41
|
+
|
|
42
|
+
- **Communication** owns voice/narrative/ICP/assets — _provides_ → Marketing, Content.
|
|
43
|
+
- **Content** owns asset/carousel/video — _consumes_ Comms; _provides_ → Social, Marketing.
|
|
44
|
+
- **Marketing** owns campaign/funnel — _consumes_ Comms + Content; _provides_ brief → Social; ⇒ _triggers_ leads → CRM.
|
|
45
|
+
- **Social** owns channel/post/schedule — _consumes_ Content + Marketing; _provides_ signals → Marketing/CRM.
|
|
46
|
+
- **CRM** owns person/company, confers `lead`/`client` — _consumes_ Social signals; `client` facet ⇒ _triggers_ → Operations.
|
|
47
|
+
- **Operations** owns engagement/contract/deliverable — _consumes_ CRM; delivery proof ⇒ _feeds_ → Content/Marketing.
|
|
48
|
+
|
|
49
|
+
Every arrow above is one of the four edge types. That is the whole model: name the arrows, pick the substrate, wire it — then the domain is a citizen of the graph, not an island.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
## Core writes
|
|
2
|
+
|
|
3
|
+
**Two write doors, one gradient.** `create_entity` is for exactly ONE
|
|
4
|
+
fully-structured, typed entity you already have. For anything unstructured,
|
|
5
|
+
several entities, or a graph — or **when in doubt** — use the capture door
|
|
6
|
+
(`synap_capture`, see `capture.md`): precision comes from sending more structure
|
|
7
|
+
in the SAME call, never from picking a different tool or a second commit step.
|
|
8
|
+
|
|
9
|
+
### Create an entity (one exact typed entity)
|
|
10
|
+
|
|
11
|
+
Before this call, use `/discover?userId=…&profileSlugs=<kind>` to read the
|
|
12
|
+
real fields, required/default values, constraints and reference targets. Omit
|
|
13
|
+
`workspaceId` for the pod/base schema and normal profile placement; pass it
|
|
14
|
+
only when the user or routing decision explicitly selected that workspace.
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
POST /api/hub/entities
|
|
18
|
+
{
|
|
19
|
+
"userId": "{userId}",
|
|
20
|
+
"profileSlug": "task", // from /discover — never guess
|
|
21
|
+
"title": "Weekly team sync",
|
|
22
|
+
"description": "Recurring planning sync",
|
|
23
|
+
"properties": { "status": "todo", "dueDate": "2026-07-21" },
|
|
24
|
+
"content": "# Agenda\n- Priorities\n- Risks",
|
|
25
|
+
"projectId": "{existingProjectId}",
|
|
26
|
+
"source": "agent"
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The response has legacy `status`/`id` fields plus `writeReceipt`:
|
|
31
|
+
`pending`/`proposed` means a proposal exists and no entity is live yet;
|
|
32
|
+
`applied` means the reported direct write completed; `partial` means a follow-up
|
|
33
|
+
(for example a facet) failed after the entity applied. **A `proposed`/`pending`
|
|
34
|
+
receipt is a governed success, not an error** — surface its `reviewUrl`, never
|
|
35
|
+
claim completion, and only enrich again when the receipt identifies a real
|
|
36
|
+
missing fact.
|
|
37
|
+
|
|
38
|
+
For several entities, creation-time roles/facets, or relations that need one
|
|
39
|
+
review, send the whole graph through the capture door (`synap_capture` with
|
|
40
|
+
`entities[]` + `relations[]`) instead of sequencing independent creates. It is
|
|
41
|
+
ONE governed call: policy auto-applies when every op is safe, otherwise the
|
|
42
|
+
whole graph is proposed (atomic). There is no separate commit step.
|
|
43
|
+
|
|
44
|
+
**Name-refs, not UUIDs.** Reference an existing project by name — the server
|
|
45
|
+
resolves it against the caller's own projects (exact match files there; no match
|
|
46
|
+
proposes, never mis-files). Never ask the user for a UUID.
|
|
47
|
+
|
|
48
|
+
**Dedup is advisory across kinds.** Strong signals (`email`/`phone`/`website` —
|
|
49
|
+
not a bare `url`) dedup within a kind; a same-title hit in a _different_ kind
|
|
50
|
+
comes back as an advisory candidate, never an auto-merge. "No exact match" is not
|
|
51
|
+
"safe to create" when advisory candidates are returned — review them first.
|
|
52
|
+
|
|
53
|
+
### Update an entity
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
PATCH /api/hub/entities/{entityId}
|
|
57
|
+
{ "userId": "{userId}", "title": "…", "properties": { "status": "done" } }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Properties are deep-merged — send only the keys you want to change.** An update with `{ "status": "done" }` leaves all other properties untouched. You never need to re-send the full properties object.
|
|
61
|
+
|
|
62
|
+
### Authored text is content, not a `file`
|
|
63
|
+
|
|
64
|
+
Something **you** author — a pitch deck, a strategic plan, a note body — is
|
|
65
|
+
**never** a `file`- or `document`-kind entity. Create it as the right CONTENT
|
|
66
|
+
kind (`note`, `knowledge`, or a fitting domain kind) with `content` set to the
|
|
67
|
+
Markdown body; Synap **auto-materializes** that `content` into a real
|
|
68
|
+
versioned document behind the scenes (`entities WHERE documentId = ?`) — no
|
|
69
|
+
upload step needed. `file` is reserved for real uploaded bytes you actually
|
|
70
|
+
have (the upload door / `synap upload`) — an agent has no filesystem, so it
|
|
71
|
+
rarely touches `file` at all. Reach for `synap_create_document` /
|
|
72
|
+
`POST /api/hub/documents` directly only for a standalone rich document that
|
|
73
|
+
isn't itself a title-worthy entity (see below) — never as a substitute for an
|
|
74
|
+
entity's `content`.
|
|
75
|
+
|
|
76
|
+
### "I want to add a real FILE" — the decision tree
|
|
77
|
+
|
|
78
|
+
You CAN store content you **hold** — you send it inline. Pick by what you have:
|
|
79
|
+
|
|
80
|
+
| You have… | Do this | Result |
|
|
81
|
+
| ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
|
82
|
+
| **Content in hand** — a report/CSV/image/PDF/etc. you generated or received (text or bytes) | **`synap_store_file`** (`content` for text, `contentBase64` for binary) + `mimeType`/`filename` | a `file` entity, content stored **as-is, never read** (≤10MB inline) |
|
|
83
|
+
| Text you're **authoring as a note/idea** (not "a file") — a plan, a thought | `synap_create_entity` with `content` (a content kind) | body auto-becomes a document — NOT a `file` |
|
|
84
|
+
| Only a **URL/link** (no bytes) — a Google Doc, a PDF url, an article | `synap_create_document` with **`url`**, or attach via `entityId` | an external **reference** document (no bytes) |
|
|
85
|
+
| A **large file on a local disk** you don't hold in context | the CLI `synap upload <path>` (streams it) — an agent can't send bytes it doesn't have | a `file` entity backed by stored bytes |
|
|
86
|
+
| Only a file's **name**, nothing else | you **cannot** invent it — ask the human/client to provide the content or a link | — |
|
|
87
|
+
|
|
88
|
+
**Store ≠ analyze.** `synap_store_file` / `synap_create_document` store content
|
|
89
|
+
**deterministically — the file is NEVER read by an LLM.** Only fetch a document
|
|
90
|
+
and reason over it when the user explicitly says "read/analyze this file."
|
|
91
|
+
|
|
92
|
+
**Do NOT over-structure a file request.** "Store this file" / "how do I add this
|
|
93
|
+
file" is ONE intent → at most one stored file (plus, only if asked, a linking
|
|
94
|
+
relation). Never inflate it into a task + note + placeholder-file scaffold, and
|
|
95
|
+
never dump the request text into a note and call it done.
|
|
96
|
+
|
|
97
|
+
### Create a document (attach to an entity)
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
POST /api/hub/documents
|
|
101
|
+
{
|
|
102
|
+
"userId": "{userId}",
|
|
103
|
+
"workspaceId": "{workspaceId}",
|
|
104
|
+
"title": "Meeting notes — 2026-04-20",
|
|
105
|
+
"content": "# Attendees\n- …\n\n# Decisions\n- …",
|
|
106
|
+
"type": "markdown", // "markdown" | "html" | "text" | "code"
|
|
107
|
+
"entityId": "ent_event_..." // attach to an entity for context
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`type: "html"` stores self-contained HTML. The browser renders it via the `html-doc` cell in a sandboxed iframe. Use for AI-generated reports, rich visualisations, custom charts, or anything beyond markdown.
|
|
112
|
+
|
|
113
|
+
**Full HTML cell workflow** (AI → visible custom UI in any bento):
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
// 1. Create the HTML document
|
|
117
|
+
POST /api/hub/documents
|
|
118
|
+
{ "userId": "{userId}", "workspaceId": "{workspaceId}",
|
|
119
|
+
"title": "Q2 Revenue Report", "type": "html",
|
|
120
|
+
"content": "<!DOCTYPE html><html>…</html>",
|
|
121
|
+
"entityId": "ent_project_..." }
|
|
122
|
+
// → { "document": { "id": "doc_abc" }, ... }
|
|
123
|
+
|
|
124
|
+
// 2. Place the html-doc cell in any bento view
|
|
125
|
+
POST /api/hub/views/{bentoViewId}/arrange
|
|
126
|
+
{ "userId": "{userId}", "workspaceId": "{workspaceId}",
|
|
127
|
+
"widgets": [
|
|
128
|
+
{ "id": "b1", "kind": "html-doc", "config": { "documentId": "doc_abc" },
|
|
129
|
+
"layout": { "x": 0, "y": 0, "w": 8, "h": 6 } }
|
|
130
|
+
] }
|
|
131
|
+
|
|
132
|
+
// 3. Update the HTML (cell auto-refreshes)
|
|
133
|
+
PATCH /api/hub/documents/doc_abc
|
|
134
|
+
{ "userId": "{userId}", "content": "<!DOCTYPE html>…updated…</html>" }
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The iframe uses `sandbox="allow-scripts"` — scripts run but have no same-origin access to the parent app. The HTML is fully isolated.
|
|
138
|
+
|
|
139
|
+
### Update a document (title and/or content)
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
PATCH /api/hub/documents/{documentId}
|
|
143
|
+
{
|
|
144
|
+
"userId": "{userId}",
|
|
145
|
+
"title": "Updated title", // optional
|
|
146
|
+
"content": "# Full replacement\n…" // full string — not a diff
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Content is a **full replacement**, not a patch. Fetch the current content first if you want to append: `GET /api/hub/documents/{id}?userId={userId}` → `.content`, append, then PATCH.
|
|
151
|
+
|
|
152
|
+
The reverse lookup is `entities WHERE documentId = ?`. Always attach the document to a meaningful entity (the meeting event, the project, the person) — a floating document is another orphan.
|
|
153
|
+
|
|
154
|
+
### Remember a fact about the user — use sparingly
|
|
155
|
+
|
|
156
|
+
A fact _about the user_ goes through `remember_fact` (CLI: `synap capture --type
|
|
157
|
+
observation`). It writes a governed `user_observation` — not an ungoverned
|
|
158
|
+
throwaway row: a fact the user explicitly stated auto-approves; a fact you
|
|
159
|
+
inferred returns `proposed` (normal — surface the review link). Because it's a
|
|
160
|
+
real entity it's addressable, linkable and revertible.
|
|
161
|
+
|
|
162
|
+
**Use it only for loose, unstructured, hard-to-title facts about the user** — a
|
|
163
|
+
stated preference, a throwaway detail. Everything with a title-worthy noun or
|
|
164
|
+
something to link to is an ENTITY through the capture door, not an observation.
|
|
165
|
+
|
|
166
|
+
**The test:** if the user later asked "show me all X," could a loose observation
|
|
167
|
+
answer? It can only keyword-match — it has no structure. So:
|
|
168
|
+
|
|
169
|
+
| Input | Use |
|
|
170
|
+
| ------------------------------------------------------- | --------------------------------------------------------------- |
|
|
171
|
+
| "User prefers async communication" | observation — it's a preference |
|
|
172
|
+
| "Garage code is 4321" | observation — throwaway fact |
|
|
173
|
+
| "Should we use LangGraph or CrewAI for Eve?" | **entity `question`** — substantive inquiry, start of flow |
|
|
174
|
+
| "Here's what I found comparing LangGraph and CrewAI…" | **entity `research`** — investigation with sources + conclusion |
|
|
175
|
+
| "We decided to use LangGraph over OpenClaude's native…" | **entity `decision`** — has title, rationale, project |
|
|
176
|
+
| "Key insight: tasks need better retry logic" | **entity `note` with tag "insight"** + link to project |
|
|
177
|
+
| "John is now head of engineering at Acme" | **update `contact` entity** — that's a property change |
|
|
178
|
+
| "Launch date moved to May 15" | **update `project` entity** — change the startDate |
|
|
179
|
+
| "Action item from meeting: ship MVP by Friday" | **entity `task`** linked to the `event` (meeting) |
|
|
180
|
+
| "Agreed with Sarah: we'll split backend & frontend" | **entity `decision`** linked to Sarah + the project |
|
|
181
|
+
|
|
182
|
+
**Rule of thumb:** if it has a title-worthy noun OR context to link to (a project, a person, a meeting) OR a lifecycle (status/supersession) — it's an entity through the capture door, not an observation. A user observation is the fallback, not the default.
|
|
183
|
+
|
|
184
|
+
**For decisions specifically** — use the `decision` system profile:
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
POST /api/hub/entities
|
|
188
|
+
{
|
|
189
|
+
"userId": "{userId}",
|
|
190
|
+
"profileSlug": "decision",
|
|
191
|
+
"title": "Use LangGraph orchestrator over OpenClaude native",
|
|
192
|
+
"properties": {
|
|
193
|
+
"decisionStatus": "accepted",
|
|
194
|
+
"decidedAt": "2026-04-20",
|
|
195
|
+
"summary": "Dedicated orchestrator service; OpenClaude CLI as UX",
|
|
196
|
+
"rationale": "Separates the Orchestration Brain (LangGraph) from the UX (OpenClaude CLI).",
|
|
197
|
+
"alternatives": "Standardize entirely on OpenClaude's multi-agent logic.",
|
|
198
|
+
"projectId": "ent_project_eve"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
This creates a first-class decision entity linked to Project Eve. It shows up in traversals, can be superseded later (`supersededBy: newDecisionId`), and survives governance. Memory can't do any of that.
|
|
204
|
+
|
|
205
|
+
### Post to the user's personal channel
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
GET /api/hub/channels/personal?userId={userId}&workspaceId={workspaceId}
|
|
209
|
+
→ { id, name, … } (get-or-create, needs hub-protocol.write scope)
|
|
210
|
+
|
|
211
|
+
POST /api/hub/threads/{threadId}/messages
|
|
212
|
+
{ "userId": "{userId}", "role": "user", "content": "…" }
|
|
213
|
+
```
|