@synap-core/cli 1.10.0 → 1.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -198
- package/dist/build-info.json +6 -0
- package/dist/commands/agent-run.js +3 -2
- package/dist/commands/agent-run.js.map +1 -1
- package/dist/commands/agents.d.ts +33 -17
- package/dist/commands/agents.js +203 -237
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/app.d.ts +143 -0
- package/dist/commands/app.js +523 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/automate.d.ts +21 -0
- package/dist/commands/automate.js +42 -0
- package/dist/commands/automate.js.map +1 -0
- package/dist/commands/automation-schema.test.d.ts +16 -0
- package/dist/commands/automation-schema.test.js +77 -0
- package/dist/commands/automation-schema.test.js.map +1 -0
- package/dist/commands/automation.d.ts +12 -0
- package/dist/commands/automation.js +80 -35
- package/dist/commands/automation.js.map +1 -1
- package/dist/commands/bridge-setup.d.ts +14 -1
- package/dist/commands/bridge-setup.js +392 -128
- package/dist/commands/bridge-setup.js.map +1 -1
- package/dist/commands/cap-connections.d.ts +4 -4
- package/dist/commands/cap-connections.js +14 -14
- package/dist/commands/cap-connections.js.map +1 -1
- package/dist/commands/capability.d.ts +2 -0
- package/dist/commands/capability.js +297 -176
- package/dist/commands/capability.js.map +1 -1
- package/dist/commands/catalog.d.ts +275 -0
- package/dist/commands/catalog.js +481 -0
- package/dist/commands/catalog.js.map +1 -0
- package/dist/commands/cell.d.ts +155 -8
- package/dist/commands/cell.js +416 -40
- package/dist/commands/cell.js.map +1 -1
- package/dist/commands/centrality.js +3 -14
- package/dist/commands/centrality.js.map +1 -1
- package/dist/commands/connect.d.ts +38 -13
- package/dist/commands/connect.js +68 -167
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connections.d.ts +3 -2
- package/dist/commands/connections.js +95 -25
- package/dist/commands/connections.js.map +1 -1
- package/dist/commands/context.js +9 -2
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/data-extra.d.ts +34 -0
- package/dist/commands/data-extra.js +198 -25
- package/dist/commands/data-extra.js.map +1 -1
- package/dist/commands/data.d.ts +120 -2
- package/dist/commands/data.js +307 -24
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +66 -4
- package/dist/commands/diagnose.js +329 -29
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/digest.js +2 -1
- package/dist/commands/digest.js.map +1 -1
- package/dist/commands/doc.d.ts +25 -4
- package/dist/commands/doc.js +100 -18
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/doctor.d.ts +130 -0
- package/dist/commands/doctor.js +814 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/events.js +3 -1
- package/dist/commands/events.js.map +1 -1
- package/dist/commands/explain.js +5 -5
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/graph.js +5 -3
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/import.d.ts +368 -13
- package/dist/commands/import.js +1096 -55
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts +20 -9
- package/dist/commands/init.js +433 -973
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.d.ts +1 -0
- package/dist/commands/keys.js +15 -2
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/knowledge.d.ts +28 -6
- package/dist/commands/knowledge.js +358 -73
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/launch.js +2 -2
- package/dist/commands/launch.js.map +1 -1
- package/dist/commands/lens.d.ts +37 -1
- package/dist/commands/lens.js +193 -72
- package/dist/commands/lens.js.map +1 -1
- package/dist/commands/market-authoring.d.ts +72 -0
- package/dist/commands/market-authoring.js +566 -0
- package/dist/commands/market-authoring.js.map +1 -0
- package/dist/commands/market-official.d.ts +58 -0
- package/dist/commands/market-official.js +84 -0
- package/dist/commands/market-official.js.map +1 -0
- package/dist/commands/market.d.ts +419 -20
- package/dist/commands/market.js +2124 -193
- package/dist/commands/market.js.map +1 -1
- package/dist/commands/mcp.d.ts +70 -13
- package/dist/commands/mcp.js +308 -40
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/open.d.ts +39 -9
- package/dist/commands/open.js +80 -25
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/playbook.d.ts +42 -0
- package/dist/commands/playbook.js +162 -0
- package/dist/commands/playbook.js.map +1 -0
- package/dist/commands/pod.js +1 -1
- package/dist/commands/pod.js.map +1 -1
- package/dist/commands/pods.d.ts +19 -0
- package/dist/commands/pods.js +220 -85
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.d.ts +62 -0
- package/dist/commands/proposals-actions.js +146 -8
- package/dist/commands/proposals-actions.js.map +1 -1
- package/dist/commands/proposals-await.d.ts +68 -0
- package/dist/commands/proposals-await.js +248 -0
- package/dist/commands/proposals-await.js.map +1 -0
- package/dist/commands/proton-setup.d.ts +73 -0
- package/dist/commands/proton-setup.js +577 -0
- package/dist/commands/proton-setup.js.map +1 -0
- package/dist/commands/providers.d.ts +23 -0
- package/dist/commands/providers.js +126 -1
- package/dist/commands/providers.js.map +1 -1
- package/dist/commands/raycast.js +6 -2
- package/dist/commands/raycast.js.map +1 -1
- package/dist/commands/rule.d.ts +150 -0
- package/dist/commands/rule.js +447 -0
- package/dist/commands/rule.js.map +1 -0
- package/dist/commands/session-wait.d.ts +111 -0
- package/dist/commands/session-wait.js +209 -0
- package/dist/commands/session-wait.js.map +1 -0
- package/dist/commands/sessions.d.ts +52 -0
- package/dist/commands/sessions.js +479 -58
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/skill-manage.d.ts +21 -0
- package/dist/commands/skill-manage.js +136 -19
- package/dist/commands/skill-manage.js.map +1 -1
- package/dist/commands/skills.js +19 -1
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +1 -4
- package/dist/commands/status.js +5 -34
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/statusline.backoff.test.d.ts +13 -0
- package/dist/commands/statusline.backoff.test.js +100 -0
- package/dist/commands/statusline.backoff.test.js.map +1 -0
- package/dist/commands/statusline.js +16 -9
- package/dist/commands/statusline.js.map +1 -1
- package/dist/commands/sync-status.d.ts +12 -0
- package/dist/commands/sync-status.js +125 -0
- package/dist/commands/sync-status.js.map +1 -0
- package/dist/commands/templates-retire.d.ts +34 -0
- package/dist/commands/templates-retire.js +192 -0
- package/dist/commands/templates-retire.js.map +1 -0
- package/dist/commands/tools.js +6 -21
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/tracks.d.ts +51 -0
- package/dist/commands/tracks.js +291 -0
- package/dist/commands/tracks.js.map +1 -0
- package/dist/commands/update.d.ts +3 -11
- package/dist/commands/update.js +5 -134
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upload.d.ts +68 -0
- package/dist/commands/upload.js +257 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/commands/vendor.d.ts +28 -0
- package/dist/commands/vendor.js +110 -0
- package/dist/commands/vendor.js.map +1 -0
- package/dist/commands/versions.js +6 -0
- package/dist/commands/versions.js.map +1 -1
- package/dist/commands/view.js +10 -5
- package/dist/commands/view.js.map +1 -1
- package/dist/commands/whoami.d.ts +23 -3
- package/dist/commands/whoami.js +169 -23
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/worker.d.ts +122 -0
- package/dist/commands/worker.js +435 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/commands/worker.test.d.ts +1 -0
- package/dist/commands/worker.test.js +116 -0
- package/dist/commands/worker.test.js.map +1 -0
- package/dist/commands/workspace-ops.d.ts +35 -0
- package/dist/commands/workspace-ops.js +153 -0
- package/dist/commands/workspace-ops.js.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1009 -171
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-connections.d.ts +31 -0
- package/dist/lib/agent-connections.js +33 -0
- package/dist/lib/agent-connections.js.map +1 -0
- package/dist/lib/agent-detect.d.ts +27 -0
- package/dist/lib/agent-detect.js +71 -0
- package/dist/lib/agent-detect.js.map +1 -0
- package/dist/lib/agent-door.d.ts +138 -0
- package/dist/lib/agent-door.js +426 -0
- package/dist/lib/agent-door.js.map +1 -0
- package/dist/lib/agents-config.d.ts +2 -0
- package/dist/lib/agents-config.js +4 -9
- package/dist/lib/agents-config.js.map +1 -1
- package/dist/lib/approval-poll.d.ts +31 -2
- package/dist/lib/approval-poll.js +20 -7
- package/dist/lib/approval-poll.js.map +1 -1
- package/dist/lib/atomic-file.d.ts +48 -0
- package/dist/lib/atomic-file.js +129 -0
- package/dist/lib/atomic-file.js.map +1 -0
- package/dist/lib/auth.d.ts +14 -9
- package/dist/lib/auth.js +44 -61
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/batch-approval.d.ts +85 -0
- package/dist/lib/batch-approval.js +170 -0
- package/dist/lib/batch-approval.js.map +1 -0
- package/dist/lib/capture-lane.d.ts +6 -5
- package/dist/lib/capture-lane.js +11 -8
- package/dist/lib/capture-lane.js.map +1 -1
- package/dist/lib/capture-structure.d.ts +342 -0
- package/dist/lib/capture-structure.js +295 -0
- package/dist/lib/capture-structure.js.map +1 -0
- package/dist/lib/catalog-templates.d.ts +59 -0
- package/dist/lib/catalog-templates.js +126 -0
- package/dist/lib/catalog-templates.js.map +1 -0
- package/dist/lib/cli-build.d.ts +19 -0
- package/dist/lib/cli-build.js +37 -0
- package/dist/lib/cli-build.js.map +1 -0
- package/dist/lib/conversation-headers.d.ts +18 -0
- package/dist/lib/conversation-headers.js +32 -0
- package/dist/lib/conversation-headers.js.map +1 -0
- package/dist/lib/cp-packages.d.ts +216 -4
- package/dist/lib/cp-packages.js +414 -11
- package/dist/lib/cp-packages.js.map +1 -1
- package/dist/lib/credential-class.d.ts +117 -0
- package/dist/lib/credential-class.js +116 -0
- package/dist/lib/credential-class.js.map +1 -0
- package/dist/lib/describe-lens.d.ts +35 -0
- package/dist/lib/describe-lens.js +40 -0
- package/dist/lib/describe-lens.js.map +1 -1
- package/dist/lib/device-connect.d.ts +125 -0
- package/dist/lib/device-connect.js +256 -0
- package/dist/lib/device-connect.js.map +1 -0
- package/dist/lib/directory-lens.d.ts +99 -0
- package/dist/lib/directory-lens.js +187 -0
- package/dist/lib/directory-lens.js.map +1 -0
- package/dist/lib/exporter-coverage.d.ts +71 -0
- package/dist/lib/exporter-coverage.js +97 -0
- package/dist/lib/exporter-coverage.js.map +1 -0
- package/dist/lib/hub-client.d.ts +43 -9
- package/dist/lib/hub-client.js +429 -65
- 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/init-connect.d.ts +41 -0
- package/dist/lib/init-connect.js +75 -0
- package/dist/lib/init-connect.js.map +1 -0
- package/dist/lib/init-exit.d.ts +24 -0
- package/dist/lib/init-exit.js +41 -0
- package/dist/lib/init-exit.js.map +1 -0
- package/dist/lib/init-flow.d.ts +25 -0
- package/dist/lib/init-flow.js +40 -0
- package/dist/lib/init-flow.js.map +1 -0
- package/dist/lib/init-handoff.d.ts +16 -0
- package/dist/lib/init-handoff.js +19 -0
- package/dist/lib/init-handoff.js.map +1 -0
- package/dist/lib/init-output.d.ts +18 -0
- package/dist/lib/init-output.js +43 -0
- package/dist/lib/init-output.js.map +1 -0
- package/dist/lib/init-pod.d.ts +45 -0
- package/dist/lib/init-pod.js +36 -0
- package/dist/lib/init-pod.js.map +1 -0
- package/dist/lib/installed.d.ts +210 -11
- package/dist/lib/installed.js +234 -36
- package/dist/lib/installed.js.map +1 -1
- package/dist/lib/key-approval.d.ts +57 -0
- package/dist/lib/key-approval.js +117 -0
- package/dist/lib/key-approval.js.map +1 -0
- package/dist/lib/key-diagnosis.d.ts +56 -0
- package/dist/lib/key-diagnosis.js +227 -0
- package/dist/lib/key-diagnosis.js.map +1 -0
- package/dist/lib/key-doctor.d.ts +136 -0
- package/dist/lib/key-doctor.js +286 -0
- package/dist/lib/key-doctor.js.map +1 -0
- package/dist/lib/key-locations.d.ts +120 -0
- package/dist/lib/key-locations.js +326 -0
- package/dist/lib/key-locations.js.map +1 -0
- package/dist/lib/key-source.d.ts +66 -0
- package/dist/lib/key-source.js +106 -0
- package/dist/lib/key-source.js.map +1 -0
- package/dist/lib/key-state.d.ts +70 -0
- package/dist/lib/key-state.js +115 -0
- package/dist/lib/key-state.js.map +1 -0
- package/dist/lib/kind-package.d.ts +181 -0
- package/dist/lib/kind-package.js +679 -0
- package/dist/lib/kind-package.js.map +1 -0
- package/dist/lib/knowledge-title.d.ts +24 -0
- package/dist/lib/knowledge-title.js +46 -0
- package/dist/lib/knowledge-title.js.map +1 -0
- package/dist/lib/knowledge-title.test.d.ts +1 -0
- package/dist/lib/knowledge-title.test.js +34 -0
- package/dist/lib/knowledge-title.test.js.map +1 -0
- package/dist/lib/machine-instance.d.ts +64 -0
- package/dist/lib/machine-instance.js +142 -0
- package/dist/lib/machine-instance.js.map +1 -0
- package/dist/lib/mcp-bridge.d.ts +42 -0
- package/dist/lib/mcp-bridge.js +147 -0
- package/dist/lib/mcp-bridge.js.map +1 -0
- package/dist/lib/mcp-bridge.test.d.ts +1 -0
- package/dist/lib/mcp-bridge.test.js +90 -0
- package/dist/lib/mcp-bridge.test.js.map +1 -0
- package/dist/lib/mcp-call.d.ts +30 -0
- package/dist/lib/mcp-call.js +107 -0
- package/dist/lib/mcp-call.js.map +1 -0
- package/dist/lib/mcp-snippets.d.ts +53 -0
- package/dist/lib/mcp-snippets.js +82 -0
- package/dist/lib/mcp-snippets.js.map +1 -0
- package/dist/lib/next-steps.d.ts +8 -0
- package/dist/lib/next-steps.js +31 -1
- package/dist/lib/next-steps.js.map +1 -1
- package/dist/lib/package-wire.d.ts +179 -0
- package/dist/lib/package-wire.js +68 -0
- package/dist/lib/package-wire.js.map +1 -0
- package/dist/lib/pair-link.d.ts +38 -0
- package/dist/lib/pair-link.js +68 -0
- package/dist/lib/pair-link.js.map +1 -0
- package/dist/lib/pod-wide.d.ts +40 -0
- package/dist/lib/pod-wide.js +46 -0
- package/dist/lib/pod-wide.js.map +1 -0
- package/dist/lib/pod.d.ts +119 -115
- package/dist/lib/pod.js +206 -412
- package/dist/lib/pod.js.map +1 -1
- package/dist/lib/project-ref.d.ts +9 -3
- package/dist/lib/project-ref.js +10 -4
- package/dist/lib/project-ref.js.map +1 -1
- package/dist/lib/review-credential.d.ts +119 -0
- package/dist/lib/review-credential.js +147 -0
- package/dist/lib/review-credential.js.map +1 -0
- package/dist/lib/safe-open.d.ts +49 -0
- package/dist/lib/safe-open.js +119 -0
- package/dist/lib/safe-open.js.map +1 -0
- package/dist/lib/session-lens.d.ts +40 -1
- package/dist/lib/session-lens.js +54 -4
- package/dist/lib/session-lens.js.map +1 -1
- package/dist/lib/superwhisper-import.d.ts +8 -0
- package/dist/lib/superwhisper-import.js +14 -7
- package/dist/lib/superwhisper-import.js.map +1 -1
- package/dist/lib/superwhisper-title.test.d.ts +1 -0
- package/dist/lib/superwhisper-title.test.js +18 -0
- package/dist/lib/superwhisper-title.test.js.map +1 -0
- package/dist/lib/targets.d.ts +134 -10
- package/dist/lib/targets.js +962 -258
- package/dist/lib/targets.js.map +1 -1
- package/dist/lib/template-file.d.ts +78 -0
- package/dist/lib/template-file.js +140 -0
- package/dist/lib/template-file.js.map +1 -0
- package/dist/lib/template-lifecycle.d.ts +217 -0
- package/dist/lib/template-lifecycle.js +433 -0
- package/dist/lib/template-lifecycle.js.map +1 -0
- package/dist/lib/template-steps.d.ts +88 -0
- package/dist/lib/template-steps.js +118 -0
- package/dist/lib/template-steps.js.map +1 -0
- package/dist/lib/time-ago.d.ts +2 -0
- package/dist/lib/time-ago.js +15 -0
- package/dist/lib/time-ago.js.map +1 -0
- package/dist/utils/logger.js +5 -2
- package/dist/utils/logger.js.map +1 -1
- package/package.json +25 -18
- package/skills/README.md +12 -10
- package/skills/agent-os/SKILL.md +220 -99
- package/skills/manifest.json +2 -2
- package/skills/onboard/SKILL.md +61 -25
- package/skills/synap/README.md +5 -8
- package/skills/synap/SKILL.md +1185 -301
- package/skills/synap/_order.txt +7 -0
- package/skills/synap/_skill.yaml +1 -1
- package/skills/synap/automations.md +15 -0
- package/skills/synap/capture.md +54 -151
- package/skills/synap/cli-operations.md +24 -18
- package/skills/synap/common-mistakes.md +1 -0
- package/skills/synap/concepts.md +28 -0
- package/skills/synap/content-os.md +92 -0
- package/skills/synap/creative-loop.md +15 -10
- package/skills/synap/crm.md +21 -52
- package/skills/synap/digesting-a-channel.md +25 -0
- package/skills/synap/document-embeds.md +141 -47
- package/skills/synap/escalation-ladder.md +20 -10
- package/skills/synap/focus-sessions.md +47 -21
- package/skills/synap/from-intent.md +142 -0
- package/skills/synap/governance-rules.md +4 -4
- package/skills/synap/governance.md +10 -7
- package/skills/synap/hand-off.md +33 -0
- package/skills/synap/inline-patterns.md +15 -7
- package/skills/synap/lenses.md +33 -15
- package/skills/synap/linking.md +41 -40
- package/skills/synap/mcp-remote-servers.md +64 -0
- package/skills/synap/mental-model.md +24 -22
- package/skills/synap/multi-entity-capture.md +6 -4
- package/skills/synap/operating-mode-rules.md +1 -1
- package/skills/synap/processes.md +118 -0
- package/skills/synap/quick-reference.md +5 -1
- package/skills/synap/reading.md +3 -1
- package/skills/synap/reflexes.md +12 -42
- package/skills/synap/viewframe-cells.md +38 -5
- package/skills/synap/work-flow.md +1 -1
- package/skills/synap/work-model.md +96 -0
- package/skills/synap/worked-examples.md +21 -1
- package/skills/synap/workspace-design.md +14 -10
- package/skills/synap/writes.md +165 -35
- package/skills/synap/writing-titles.md +63 -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-design/SKILL.md +474 -0
- package/skills/synap-design/_order.txt +4 -0
- package/skills/synap-design/_skill.yaml +21 -0
- package/skills/synap-design/loop.md +134 -0
- package/skills/synap-design/overview.md +44 -0
- package/skills/synap-design/principles.md +130 -0
- package/skills/synap-design/system.md +133 -0
- package/skills/synap-market/SKILL.md +625 -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 +212 -0
- package/skills/synap-market/discover-and-fetch.md +59 -0
- package/skills/synap-market/governance-and-catalog.md +63 -0
- package/skills/synap-market/install.md +133 -0
- package/skills/synap-market/overview.md +119 -0
- package/skills/synap-schema/SKILL.md +172 -10
- package/skills/synap-schema/_order.txt +2 -0
- package/skills/synap-schema/_skill.yaml +4 -2
- package/skills/synap-schema/common-mistakes.md +4 -2
- package/skills/synap-schema/discover-profiles.md +1 -1
- package/skills/synap-schema/entity-scope.md +15 -3
- package/skills/synap-schema/extend-first.md +29 -0
- package/skills/synap-schema/extend-vs-create.md +1 -1
- package/skills/synap-schema/intent-vocabulary-ssot.md +111 -0
- package/skills/synap-schema/property-types.md +1 -1
- package/skills/synap-schema/relations.md +1 -1
- package/skills/synap-ui/SKILL.md +19 -12
- package/skills/synap-ui/_skill.yaml +1 -1
- package/skills/synap-ui/ai-companion.md +1 -1
- package/skills/synap-ui/arranging-bento.md +2 -0
- package/skills/synap-ui/bento-layouts.md +10 -10
- package/skills/synap-ui/bento-recipes.md +313 -543
- package/skills/synap-ui/four-builds.md +5 -0
- package/skills/synap-ui/view-types.md +2 -2
- package/skills/synap-ui/widget-catalog.md +22 -278
- package/templates/automations/bookmark-enrichment.automation.json +290 -13
- package/templates/automations/url-bookmark-capture.automation.json +73 -11
- package/templates/skills/authoring-playbooks/SKILL.md +6 -3
- package/templates/skills/authoring-playbooks/reference/stages-contract.md +15 -0
- package/templates/skills/authoring-playbooks/reference/worked-example.md +3 -0
- package/dist/commands/infra.d.ts +0 -21
- package/dist/commands/infra.js +0 -262
- package/dist/commands/infra.js.map +0 -1
- package/dist/lib/browser-auth.d.ts +0 -35
- package/dist/lib/browser-auth.js +0 -170
- package/dist/lib/browser-auth.js.map +0 -1
- package/dist/lib/openclaw.d.ts +0 -32
- package/dist/lib/openclaw.js +0 -164
- package/dist/lib/openclaw.js.map +0 -1
- package/dist/lib/seed.d.ts +0 -13
- package/dist/lib/seed.js +0 -135
- package/dist/lib/seed.js.map +0 -1
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: synap-app
|
|
3
|
+
description: >
|
|
4
|
+
Use this skill when the user wants to BUILD THEIR OWN APP on top of Synap — a
|
|
5
|
+
personal project or a product — using Synap as the backend (auth, typed data
|
|
6
|
+
API, realtime). Two paths: add the SDK (@synap-core/sdk) to an existing app,
|
|
7
|
+
or scaffold the opinionated Next.js + HeroUI base app (npx create-synap-app).
|
|
8
|
+
Triggers: "build an app on Synap", "use Synap as my backend", "scaffold a
|
|
9
|
+
Synap project", "add the Synap SDK", "connect my app to my pod",
|
|
10
|
+
"npx create-synap-app". NOT the `synap` skill (capture/recall in a pod) nor
|
|
11
|
+
`synap-ui` (views inside the pod's own UI) — this is about writing app CODE.
|
|
12
|
+
metadata:
|
|
13
|
+
synap:
|
|
14
|
+
requires:
|
|
15
|
+
env: []
|
|
16
|
+
optional_env: [SYNAP_POD_URL, SYNAP_WORKSPACE_ID]
|
|
17
|
+
primaryEnv: null
|
|
18
|
+
homepage: https://synap.live
|
|
19
|
+
capabilities: [sdk, scaffold, auth, realtime]
|
|
20
|
+
os: [macos, linux, windows]
|
|
21
|
+
userInvocable: true
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Building an app on Synap
|
|
25
|
+
|
|
26
|
+
Synap is a sovereign data pod with a complete, typed API. You build an app on it
|
|
27
|
+
the same way you'd build on any backend — except the backend is the user's own
|
|
28
|
+
pod, and **every write is governed** (see `governance.md`).
|
|
29
|
+
|
|
30
|
+
## Decide the path first
|
|
31
|
+
|
|
32
|
+
| The user has… | Do this | Read |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| an existing app (any framework) | add the SDK | `using-the-sdk.md`, `install-commands.md` |
|
|
35
|
+
| nothing yet, wants a full app fast | scaffold the base app | `creating-the-base-app.md`, `install-commands.md` |
|
|
36
|
+
| a server / script / CLI (no browser) | SDK with a session token or API key | `using-the-sdk.md` |
|
|
37
|
+
|
|
38
|
+
Both paths use the same underlying packages; only the amount of scaffolding differs.
|
|
39
|
+
|
|
40
|
+
## The packages (all published under `@synap-core/*`)
|
|
41
|
+
|
|
42
|
+
- `@synap-core/sdk` — typed tRPC client. `createSynapClient({ podUrl, ... })`. **The one you almost always want.**
|
|
43
|
+
- `@synap-core/react` — React/TanStack-Query bindings (`SynapProvider`, hooks).
|
|
44
|
+
- `@synap-core/sdk-realtime` — Socket.IO presence/live-updates (`createRealtimeClient`).
|
|
45
|
+
- `@synap-core/auth` — sign-in orchestration (Synap Cloud + pod handshake), framework-agnostic.
|
|
46
|
+
- `@synap-core/auth-bootstrap` — zero-dep server helpers (`setupAgent`, `handshake`) for machine clients.
|
|
47
|
+
|
|
48
|
+
Pin `@^1.0.0` on `sdk`/`react` so you never resolve an old, abandoned `0.x`.
|
|
49
|
+
|
|
50
|
+
## The three rules that trip people up
|
|
51
|
+
|
|
52
|
+
1. **A write can come back `"proposed"` — that is SUCCESS, not an error.** It means
|
|
53
|
+
the change is queued for the pod owner's review (like a PR). Surface the review,
|
|
54
|
+
don't retry. Full contract: `governance.md`.
|
|
55
|
+
2. **The pod URL has no `/trpc` suffix and no trailing slash.** The SDK appends `/trpc`.
|
|
56
|
+
3. **Non-browser clients (server/CLI/mobile) authenticate with a token or API key**,
|
|
57
|
+
never a cookie. Browser apps use the Synap Cloud sign-in flow (`@synap-core/auth`).
|
|
58
|
+
|
|
59
|
+
## Get a pod to build against
|
|
60
|
+
|
|
61
|
+
- **Self-host (free):** `git clone` the backend, `docker compose up -d` (run its
|
|
62
|
+
`install.sh` to generate secrets). Pod answers on `:4000`.
|
|
63
|
+
- **Managed (paid):** sign up at synap.live and provision a pod.
|
|
64
|
+
|
|
65
|
+
You can develop the base app with **no pod at all** using its mock mode
|
|
66
|
+
(`NEXT_PUBLIC_BASE_MOCK_MODE=true`).
|
|
67
|
+
|
|
68
|
+
## Honest scope
|
|
69
|
+
|
|
70
|
+
Building on the user's OWN pod is fully supported today. Building a **multi-tenant
|
|
71
|
+
commercial app** where *other* people connect *their* pods is **not yet supported**
|
|
72
|
+
— per-app data scoping is still being built. If the user asks for that, say so;
|
|
73
|
+
don't architect around a capability that isn't there.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
# Install & scaffold commands
|
|
78
|
+
|
|
79
|
+
## Scaffold a full app (recommended for a fresh start)
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx create-synap-app my-app
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Creates a Next.js + HeroUI project from the base template, with the SDK, auth,
|
|
86
|
+
app shell, command palette, realtime, and mock mode pre-wired. It also drops an
|
|
87
|
+
`AGENTS.md` into the project so your AI coding tool knows how to work with it.
|
|
88
|
+
|
|
89
|
+
## Add the SDK to an existing app
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# npm
|
|
93
|
+
npm install @synap-core/sdk@^1.0.0
|
|
94
|
+
|
|
95
|
+
# with React bindings
|
|
96
|
+
npm install @synap-core/sdk@^1.0.0 @synap-core/react@^1.0.0
|
|
97
|
+
|
|
98
|
+
# realtime
|
|
99
|
+
npm install @synap-core/sdk-realtime
|
|
100
|
+
|
|
101
|
+
# auth (browser sign-in) or auth-bootstrap (server credential bootstrap)
|
|
102
|
+
npm install @synap-core/auth # or @synap-core/auth-bootstrap
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Pin `@^1.0.0` on `sdk`/`react`. **Do not** install unpinned `@synap-core/sdk` —
|
|
106
|
+
older `0.x` versions on the registry are a different, abandoned package.
|
|
107
|
+
|
|
108
|
+
## Get this knowledge into your AI coding tool
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# add the app-creation skill (this skill) to a connected AI tool
|
|
112
|
+
synap skills get synap-app
|
|
113
|
+
|
|
114
|
+
# or wire a tool end-to-end (skills + MCP), any target
|
|
115
|
+
synap connect --target=cursor # or claude, …
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Alternatively, the scaffolded project ships an `AGENTS.md` at its root — most AI
|
|
119
|
+
coding tools read it automatically, so a freshly-scaffolded app teaches the AI
|
|
120
|
+
how to build on it with zero extra setup.
|
|
121
|
+
|
|
122
|
+
## Verify an install actually works
|
|
123
|
+
|
|
124
|
+
Publishing bugs have shipped uninstallable Synap packages before. After adding a
|
|
125
|
+
package, confirm it resolves in a clean directory:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
mkdir /tmp/synap-check && cd /tmp/synap-check && npm init -y
|
|
129
|
+
npm install @synap-core/sdk@^1.0.0
|
|
130
|
+
node -e "console.log(typeof require('@synap-core/sdk').createSynapClient)" # → function
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
# Using the SDK
|
|
136
|
+
|
|
137
|
+
## Vanilla / TypeScript / server / CLI — `@synap-core/sdk`
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import { createSynapClient } from "@synap-core/sdk";
|
|
141
|
+
|
|
142
|
+
const synap = createSynapClient({
|
|
143
|
+
podUrl: "https://pod.example.com", // NO trailing slash, NO /trpc suffix
|
|
144
|
+
apiKey: process.env.SYNAP_API_KEY, // or sessionToken (see auth below)
|
|
145
|
+
workspaceId: process.env.SYNAP_WORKSPACE_ID ?? "",
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// It's a typed tRPC client — full autocomplete over every router.
|
|
149
|
+
const me = await synap.users.me.query();
|
|
150
|
+
const entities = await synap.entities.list.query({ /* filter */ });
|
|
151
|
+
const result = await synap.entities.create.mutate({ /* ... */ });
|
|
152
|
+
// result may be { status: "proposed", ... } — that is success. See governance.md.
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Auth modes (pick ONE)
|
|
156
|
+
- **`apiKey`** — a Bearer key generated in the workspace's developer settings.
|
|
157
|
+
Best for servers, scripts, CLIs.
|
|
158
|
+
- **`sessionToken`** — an Ory Kratos session token, sent as `X-Session-Token`.
|
|
159
|
+
Best for non-browser clients that completed a sign-in.
|
|
160
|
+
- **cookie fallback** — omit both; the client uses the ambient Kratos cookie.
|
|
161
|
+
Browser, same-origin only.
|
|
162
|
+
|
|
163
|
+
For machine clients that need to bootstrap a credential, use
|
|
164
|
+
`@synap-core/auth-bootstrap` (`setupAgent(provisioningToken)` → API key,
|
|
165
|
+
`handshake(jwt)` → session token). Zero-dependency, safe in edge/serverless.
|
|
166
|
+
|
|
167
|
+
## React — `@synap-core/react`
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
import { SynapProvider, useSynapContext } from "@synap-core/react";
|
|
171
|
+
|
|
172
|
+
function App() {
|
|
173
|
+
return (
|
|
174
|
+
<SynapProvider podUrl={podUrl} sessionToken={token} workspaceId={ws}>
|
|
175
|
+
<Dashboard />
|
|
176
|
+
</SynapProvider>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`SynapProvider` honours every `createSynapClient` option, incl. `sessionToken`
|
|
182
|
+
and `onAuthError` (a 401 handler). `react` is a peer of your app's React — it
|
|
183
|
+
does not bundle its own.
|
|
184
|
+
|
|
185
|
+
## Realtime — `@synap-core/sdk-realtime`
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { createRealtimeClient } from "@synap-core/sdk-realtime";
|
|
189
|
+
|
|
190
|
+
const rt = createRealtimeClient({ podUrl, sessionToken });
|
|
191
|
+
const stop = rt.onInvalidate((target) => {
|
|
192
|
+
// e.g. refetch the affected query
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Websocket-only transport (credentials never ride a long-poll URL) and it refuses
|
|
197
|
+
to send credentials over non-TLS unless you explicitly pass `allowInsecure`.
|
|
198
|
+
|
|
199
|
+
## Two transports, on purpose
|
|
200
|
+
- `@synap-core/sdk` (tRPC) — for apps. Typed, hooks, realtime.
|
|
201
|
+
- `@synap-core/hub-rest-client` (REST, zero-dep) — for agents/CLIs/scripts. Carries
|
|
202
|
+
agent verbs the tRPC surface has no first-class path for (`ask`, `orient`,
|
|
203
|
+
`discover`). Use it when you want a dependency-free REST client, not a full app.
|
|
204
|
+
|
|
205
|
+
## Keep types fresh
|
|
206
|
+
The SDK is typed by `@synap-core/api-types`, generated from the pod's live router.
|
|
207
|
+
If the pod adds a procedure and you don't see it, bump `@synap-core/api-types`.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
# Creating the base app
|
|
212
|
+
|
|
213
|
+
The base app is an opinionated, batteries-included starter: **Next.js 16 (App
|
|
214
|
+
Router) + React 19 + HeroUI + Tailwind**, with auth (incl. TOTP), an app shell
|
|
215
|
+
(tabs + slide-in right panel), a Cmd+K command palette, a realtime bridge, and a
|
|
216
|
+
mock mode — all pre-wired. You add your screens; the plumbing is done.
|
|
217
|
+
|
|
218
|
+
## Scaffold it
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
npx create-synap-app my-app
|
|
222
|
+
cd my-app
|
|
223
|
+
cp .env.example .env.local # fill in your pod / control-plane URLs
|
|
224
|
+
pnpm dev # http://localhost:3010
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Develop with **no pod** by setting `NEXT_PUBLIC_BASE_MOCK_MODE=true`.
|
|
228
|
+
|
|
229
|
+
## What's where
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
app/
|
|
233
|
+
layout.tsx Root layout → ClientProviders (client-only, see below)
|
|
234
|
+
ClientProviders Loads the provider tree with { ssr: false } (REQUIRED — see rule 1)
|
|
235
|
+
providers.tsx The real provider stack (auth, tRPC, realtime, palette)
|
|
236
|
+
(app)/home Your home screen — replace this
|
|
237
|
+
login/ onboarding First-run + auth screens
|
|
238
|
+
lib/
|
|
239
|
+
registerAll.ts Boot hook — registers cells/views (override in your app)
|
|
240
|
+
auth.ts mockMode Session + mock helpers
|
|
241
|
+
components/layout/
|
|
242
|
+
AppShell Root layout primitive — pass your sidebar as `leftNav`
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Four rules that keep the build green (all Next 16 / Turbopack specifics)
|
|
246
|
+
|
|
247
|
+
1. **The provider tree must load client-only.** `app/ClientProviders.tsx` does
|
|
248
|
+
`dynamic(() => import("./providers"), { ssr: false })`. base's provider tree
|
|
249
|
+
pulls a dep that touches `window` at module scope, which crashes a server
|
|
250
|
+
render. base is a client app shell — there is nothing to server-render — so
|
|
251
|
+
this is correct, not a hack. Keep it.
|
|
252
|
+
2. **`config.matcher` in `middleware.ts` must be an inline literal**, not a value
|
|
253
|
+
read from a helper — Next's static analyzer can't parse an expression there.
|
|
254
|
+
3. **In `globals.css`, `@import` must come before the `@tailwind` directives.**
|
|
255
|
+
Turbopack enforces the CSS spec strictly.
|
|
256
|
+
4. **Build with Turbopack (the default) — do NOT pass `--webpack`.** In Next 16
|
|
257
|
+
the legacy `--webpack` flag silently produces nothing (exit 0, no output). If
|
|
258
|
+
you add a webpack alias, port it to `turbopack.resolveAlias` in `next.config.ts`.
|
|
259
|
+
|
|
260
|
+
## Deriving your own app
|
|
261
|
+
|
|
262
|
+
1. Rename the namespaced storage keys (`base:session`, `base-workspace`, …) so
|
|
263
|
+
two Synap apps don't share state in one browser. The README lists every key.
|
|
264
|
+
2. Replace `app/(app)/home/page.tsx` with your dashboard.
|
|
265
|
+
3. Pass your sidebar: `<AppShell leftNav={<MySidebar />}>`.
|
|
266
|
+
4. Register app-specific Cmd+K commands with `useRegisterCommand([...])`.
|
|
267
|
+
5. Register only the cells you need in `lib/registerAll.ts` (a lean template
|
|
268
|
+
registers fewer than the full set).
|
|
269
|
+
|
|
270
|
+
## Auth flow (already wired)
|
|
271
|
+
|
|
272
|
+
`/login` → Synap Cloud sign-in (email + password or magic link) → optional TOTP →
|
|
273
|
+
pod picker → handshake → session stored → `/home`. Self-hosted pods fall back to
|
|
274
|
+
the pod's own Kratos at `/login?mode=kratos`. You don't build this; you theme it.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
# Governance — `"proposed"` is success, not an error
|
|
279
|
+
|
|
280
|
+
This is the single most important thing to get right when writing code that
|
|
281
|
+
mutates a Synap pod.
|
|
282
|
+
|
|
283
|
+
## The contract
|
|
284
|
+
|
|
285
|
+
Every mutation (`entities.create`, `entities.update`, `relations.create`, …)
|
|
286
|
+
resolves to one of three outcomes, decided **by the pod**, not by your app:
|
|
287
|
+
|
|
288
|
+
| Outcome | Meaning | What your code should do |
|
|
289
|
+
|---|---|---|
|
|
290
|
+
| `approved` | applied immediately | proceed |
|
|
291
|
+
| `proposed` | queued for the pod owner's review (like a PR) | **surface the review — do NOT treat as failure, do NOT retry** |
|
|
292
|
+
| `denied` | the principal may not do this | show why; do not retry blindly |
|
|
293
|
+
|
|
294
|
+
## Why it matters for your code
|
|
295
|
+
|
|
296
|
+
- **Never treat `proposed` as an error.** It is the normal, healthy path for any
|
|
297
|
+
write that governance decides a human should see first. Retrying a `proposed`
|
|
298
|
+
write creates duplicates.
|
|
299
|
+
- **Never `try/catch` a `proposed` as if it threw.** It's a successful response
|
|
300
|
+
with a status, not an exception.
|
|
301
|
+
- **Surface the review link/id** so the user can approve it. An unreviewed
|
|
302
|
+
proposal is not yet in the graph — it won't show up in reads until approved.
|
|
303
|
+
|
|
304
|
+
## Pattern
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
const res = await synap.entities.create.mutate(input);
|
|
308
|
+
switch (res.status) {
|
|
309
|
+
case "approved": /* it's live */ break;
|
|
310
|
+
case "proposed": /* tell the user: "queued for review" + show res.proposalId */ break;
|
|
311
|
+
case "denied": /* show res.reason; don't retry */ break;
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Idempotency
|
|
316
|
+
|
|
317
|
+
If you must retry a create after a network error, pass an idempotency key where
|
|
318
|
+
the API accepts one — a `proposed` write that you retry without one will
|
|
319
|
+
duplicate on approval. When unsure, read back before re-creating.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: synap-app
|
|
2
|
+
description: >
|
|
3
|
+
Use this skill when the user wants to BUILD THEIR OWN APP on top of Synap — a
|
|
4
|
+
personal project or a product — using Synap as the backend (auth, typed data
|
|
5
|
+
API, realtime). Two paths: add the SDK (@synap-core/sdk) to an existing app,
|
|
6
|
+
or scaffold the opinionated Next.js + HeroUI base app (npx create-synap-app).
|
|
7
|
+
Triggers: "build an app on Synap", "use Synap as my backend", "scaffold a
|
|
8
|
+
Synap project", "add the Synap SDK", "connect my app to my pod",
|
|
9
|
+
"npx create-synap-app". NOT the `synap` skill (capture/recall in a pod) nor
|
|
10
|
+
`synap-ui` (views inside the pod's own UI) — this is about writing app CODE.
|
|
11
|
+
metadata:
|
|
12
|
+
synap:
|
|
13
|
+
requires:
|
|
14
|
+
env: []
|
|
15
|
+
optional_env: [SYNAP_POD_URL, SYNAP_WORKSPACE_ID]
|
|
16
|
+
primaryEnv: null
|
|
17
|
+
homepage: https://synap.live
|
|
18
|
+
capabilities: [sdk, scaffold, auth, realtime]
|
|
19
|
+
os: [macos, linux, windows]
|
|
20
|
+
userInvocable: true
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Creating the base app
|
|
2
|
+
|
|
3
|
+
The base app is an opinionated, batteries-included starter: **Next.js 16 (App
|
|
4
|
+
Router) + React 19 + HeroUI + Tailwind**, with auth (incl. TOTP), an app shell
|
|
5
|
+
(tabs + slide-in right panel), a Cmd+K command palette, a realtime bridge, and a
|
|
6
|
+
mock mode — all pre-wired. You add your screens; the plumbing is done.
|
|
7
|
+
|
|
8
|
+
## Scaffold it
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx create-synap-app my-app
|
|
12
|
+
cd my-app
|
|
13
|
+
cp .env.example .env.local # fill in your pod / control-plane URLs
|
|
14
|
+
pnpm dev # http://localhost:3010
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Develop with **no pod** by setting `NEXT_PUBLIC_BASE_MOCK_MODE=true`.
|
|
18
|
+
|
|
19
|
+
## What's where
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
app/
|
|
23
|
+
layout.tsx Root layout → ClientProviders (client-only, see below)
|
|
24
|
+
ClientProviders Loads the provider tree with { ssr: false } (REQUIRED — see rule 1)
|
|
25
|
+
providers.tsx The real provider stack (auth, tRPC, realtime, palette)
|
|
26
|
+
(app)/home Your home screen — replace this
|
|
27
|
+
login/ onboarding First-run + auth screens
|
|
28
|
+
lib/
|
|
29
|
+
registerAll.ts Boot hook — registers cells/views (override in your app)
|
|
30
|
+
auth.ts mockMode Session + mock helpers
|
|
31
|
+
components/layout/
|
|
32
|
+
AppShell Root layout primitive — pass your sidebar as `leftNav`
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Four rules that keep the build green (all Next 16 / Turbopack specifics)
|
|
36
|
+
|
|
37
|
+
1. **The provider tree must load client-only.** `app/ClientProviders.tsx` does
|
|
38
|
+
`dynamic(() => import("./providers"), { ssr: false })`. base's provider tree
|
|
39
|
+
pulls a dep that touches `window` at module scope, which crashes a server
|
|
40
|
+
render. base is a client app shell — there is nothing to server-render — so
|
|
41
|
+
this is correct, not a hack. Keep it.
|
|
42
|
+
2. **`config.matcher` in `middleware.ts` must be an inline literal**, not a value
|
|
43
|
+
read from a helper — Next's static analyzer can't parse an expression there.
|
|
44
|
+
3. **In `globals.css`, `@import` must come before the `@tailwind` directives.**
|
|
45
|
+
Turbopack enforces the CSS spec strictly.
|
|
46
|
+
4. **Build with Turbopack (the default) — do NOT pass `--webpack`.** In Next 16
|
|
47
|
+
the legacy `--webpack` flag silently produces nothing (exit 0, no output). If
|
|
48
|
+
you add a webpack alias, port it to `turbopack.resolveAlias` in `next.config.ts`.
|
|
49
|
+
|
|
50
|
+
## Deriving your own app
|
|
51
|
+
|
|
52
|
+
1. Rename the namespaced storage keys (`base:session`, `base-workspace`, …) so
|
|
53
|
+
two Synap apps don't share state in one browser. The README lists every key.
|
|
54
|
+
2. Replace `app/(app)/home/page.tsx` with your dashboard.
|
|
55
|
+
3. Pass your sidebar: `<AppShell leftNav={<MySidebar />}>`.
|
|
56
|
+
4. Register app-specific Cmd+K commands with `useRegisterCommand([...])`.
|
|
57
|
+
5. Register only the cells you need in `lib/registerAll.ts` (a lean template
|
|
58
|
+
registers fewer than the full set).
|
|
59
|
+
|
|
60
|
+
## Auth flow (already wired)
|
|
61
|
+
|
|
62
|
+
`/login` → Synap Cloud sign-in (email + password or magic link) → optional TOTP →
|
|
63
|
+
pod picker → handshake → session stored → `/home`. Self-hosted pods fall back to
|
|
64
|
+
the pod's own Kratos at `/login?mode=kratos`. You don't build this; you theme it.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Governance — `"proposed"` is success, not an error
|
|
2
|
+
|
|
3
|
+
This is the single most important thing to get right when writing code that
|
|
4
|
+
mutates a Synap pod.
|
|
5
|
+
|
|
6
|
+
## The contract
|
|
7
|
+
|
|
8
|
+
Every mutation (`entities.create`, `entities.update`, `relations.create`, …)
|
|
9
|
+
resolves to one of three outcomes, decided **by the pod**, not by your app:
|
|
10
|
+
|
|
11
|
+
| Outcome | Meaning | What your code should do |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| `approved` | applied immediately | proceed |
|
|
14
|
+
| `proposed` | queued for the pod owner's review (like a PR) | **surface the review — do NOT treat as failure, do NOT retry** |
|
|
15
|
+
| `denied` | the principal may not do this | show why; do not retry blindly |
|
|
16
|
+
|
|
17
|
+
## Why it matters for your code
|
|
18
|
+
|
|
19
|
+
- **Never treat `proposed` as an error.** It is the normal, healthy path for any
|
|
20
|
+
write that governance decides a human should see first. Retrying a `proposed`
|
|
21
|
+
write creates duplicates.
|
|
22
|
+
- **Never `try/catch` a `proposed` as if it threw.** It's a successful response
|
|
23
|
+
with a status, not an exception.
|
|
24
|
+
- **Surface the review link/id** so the user can approve it. An unreviewed
|
|
25
|
+
proposal is not yet in the graph — it won't show up in reads until approved.
|
|
26
|
+
|
|
27
|
+
## Pattern
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
const res = await synap.entities.create.mutate(input);
|
|
31
|
+
switch (res.status) {
|
|
32
|
+
case "approved": /* it's live */ break;
|
|
33
|
+
case "proposed": /* tell the user: "queued for review" + show res.proposalId */ break;
|
|
34
|
+
case "denied": /* show res.reason; don't retry */ break;
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Idempotency
|
|
39
|
+
|
|
40
|
+
If you must retry a create after a network error, pass an idempotency key where
|
|
41
|
+
the API accepts one — a `proposed` write that you retry without one will
|
|
42
|
+
duplicate on approval. When unsure, read back before re-creating.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Install & scaffold commands
|
|
2
|
+
|
|
3
|
+
## Scaffold a full app (recommended for a fresh start)
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx create-synap-app my-app
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Creates a Next.js + HeroUI project from the base template, with the SDK, auth,
|
|
10
|
+
app shell, command palette, realtime, and mock mode pre-wired. It also drops an
|
|
11
|
+
`AGENTS.md` into the project so your AI coding tool knows how to work with it.
|
|
12
|
+
|
|
13
|
+
## Add the SDK to an existing app
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# npm
|
|
17
|
+
npm install @synap-core/sdk@^1.0.0
|
|
18
|
+
|
|
19
|
+
# with React bindings
|
|
20
|
+
npm install @synap-core/sdk@^1.0.0 @synap-core/react@^1.0.0
|
|
21
|
+
|
|
22
|
+
# realtime
|
|
23
|
+
npm install @synap-core/sdk-realtime
|
|
24
|
+
|
|
25
|
+
# auth (browser sign-in) or auth-bootstrap (server credential bootstrap)
|
|
26
|
+
npm install @synap-core/auth # or @synap-core/auth-bootstrap
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Pin `@^1.0.0` on `sdk`/`react`. **Do not** install unpinned `@synap-core/sdk` —
|
|
30
|
+
older `0.x` versions on the registry are a different, abandoned package.
|
|
31
|
+
|
|
32
|
+
## Get this knowledge into your AI coding tool
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# add the app-creation skill (this skill) to a connected AI tool
|
|
36
|
+
synap skills get synap-app
|
|
37
|
+
|
|
38
|
+
# or wire a tool end-to-end (skills + MCP), any target
|
|
39
|
+
synap connect --target=cursor # or claude, …
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Alternatively, the scaffolded project ships an `AGENTS.md` at its root — most AI
|
|
43
|
+
coding tools read it automatically, so a freshly-scaffolded app teaches the AI
|
|
44
|
+
how to build on it with zero extra setup.
|
|
45
|
+
|
|
46
|
+
## Verify an install actually works
|
|
47
|
+
|
|
48
|
+
Publishing bugs have shipped uninstallable Synap packages before. After adding a
|
|
49
|
+
package, confirm it resolves in a clean directory:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
mkdir /tmp/synap-check && cd /tmp/synap-check && npm init -y
|
|
53
|
+
npm install @synap-core/sdk@^1.0.0
|
|
54
|
+
node -e "console.log(typeof require('@synap-core/sdk').createSynapClient)" # → function
|
|
55
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Building an app on Synap
|
|
2
|
+
|
|
3
|
+
Synap is a sovereign data pod with a complete, typed API. You build an app on it
|
|
4
|
+
the same way you'd build on any backend — except the backend is the user's own
|
|
5
|
+
pod, and **every write is governed** (see `governance.md`).
|
|
6
|
+
|
|
7
|
+
## Decide the path first
|
|
8
|
+
|
|
9
|
+
| The user has… | Do this | Read |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| an existing app (any framework) | add the SDK | `using-the-sdk.md`, `install-commands.md` |
|
|
12
|
+
| nothing yet, wants a full app fast | scaffold the base app | `creating-the-base-app.md`, `install-commands.md` |
|
|
13
|
+
| a server / script / CLI (no browser) | SDK with a session token or API key | `using-the-sdk.md` |
|
|
14
|
+
|
|
15
|
+
Both paths use the same underlying packages; only the amount of scaffolding differs.
|
|
16
|
+
|
|
17
|
+
## The packages (all published under `@synap-core/*`)
|
|
18
|
+
|
|
19
|
+
- `@synap-core/sdk` — typed tRPC client. `createSynapClient({ podUrl, ... })`. **The one you almost always want.**
|
|
20
|
+
- `@synap-core/react` — React/TanStack-Query bindings (`SynapProvider`, hooks).
|
|
21
|
+
- `@synap-core/sdk-realtime` — Socket.IO presence/live-updates (`createRealtimeClient`).
|
|
22
|
+
- `@synap-core/auth` — sign-in orchestration (Synap Cloud + pod handshake), framework-agnostic.
|
|
23
|
+
- `@synap-core/auth-bootstrap` — zero-dep server helpers (`setupAgent`, `handshake`) for machine clients.
|
|
24
|
+
|
|
25
|
+
Pin `@^1.0.0` on `sdk`/`react` so you never resolve an old, abandoned `0.x`.
|
|
26
|
+
|
|
27
|
+
## The three rules that trip people up
|
|
28
|
+
|
|
29
|
+
1. **A write can come back `"proposed"` — that is SUCCESS, not an error.** It means
|
|
30
|
+
the change is queued for the pod owner's review (like a PR). Surface the review,
|
|
31
|
+
don't retry. Full contract: `governance.md`.
|
|
32
|
+
2. **The pod URL has no `/trpc` suffix and no trailing slash.** The SDK appends `/trpc`.
|
|
33
|
+
3. **Non-browser clients (server/CLI/mobile) authenticate with a token or API key**,
|
|
34
|
+
never a cookie. Browser apps use the Synap Cloud sign-in flow (`@synap-core/auth`).
|
|
35
|
+
|
|
36
|
+
## Get a pod to build against
|
|
37
|
+
|
|
38
|
+
- **Self-host (free):** `git clone` the backend, `docker compose up -d` (run its
|
|
39
|
+
`install.sh` to generate secrets). Pod answers on `:4000`.
|
|
40
|
+
- **Managed (paid):** sign up at synap.live and provision a pod.
|
|
41
|
+
|
|
42
|
+
You can develop the base app with **no pod at all** using its mock mode
|
|
43
|
+
(`NEXT_PUBLIC_BASE_MOCK_MODE=true`).
|
|
44
|
+
|
|
45
|
+
## Honest scope
|
|
46
|
+
|
|
47
|
+
Building on the user's OWN pod is fully supported today. Building a **multi-tenant
|
|
48
|
+
commercial app** where *other* people connect *their* pods is **not yet supported**
|
|
49
|
+
— per-app data scoping is still being built. If the user asks for that, say so;
|
|
50
|
+
don't architect around a capability that isn't there.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Using the SDK
|
|
2
|
+
|
|
3
|
+
## Vanilla / TypeScript / server / CLI — `@synap-core/sdk`
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { createSynapClient } from "@synap-core/sdk";
|
|
7
|
+
|
|
8
|
+
const synap = createSynapClient({
|
|
9
|
+
podUrl: "https://pod.example.com", // NO trailing slash, NO /trpc suffix
|
|
10
|
+
apiKey: process.env.SYNAP_API_KEY, // or sessionToken (see auth below)
|
|
11
|
+
workspaceId: process.env.SYNAP_WORKSPACE_ID ?? "",
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// It's a typed tRPC client — full autocomplete over every router.
|
|
15
|
+
const me = await synap.users.me.query();
|
|
16
|
+
const entities = await synap.entities.list.query({ /* filter */ });
|
|
17
|
+
const result = await synap.entities.create.mutate({ /* ... */ });
|
|
18
|
+
// result may be { status: "proposed", ... } — that is success. See governance.md.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Auth modes (pick ONE)
|
|
22
|
+
- **`apiKey`** — a Bearer key generated in the workspace's developer settings.
|
|
23
|
+
Best for servers, scripts, CLIs.
|
|
24
|
+
- **`sessionToken`** — an Ory Kratos session token, sent as `X-Session-Token`.
|
|
25
|
+
Best for non-browser clients that completed a sign-in.
|
|
26
|
+
- **cookie fallback** — omit both; the client uses the ambient Kratos cookie.
|
|
27
|
+
Browser, same-origin only.
|
|
28
|
+
|
|
29
|
+
For machine clients that need to bootstrap a credential, use
|
|
30
|
+
`@synap-core/auth-bootstrap` (`setupAgent(provisioningToken)` → API key,
|
|
31
|
+
`handshake(jwt)` → session token). Zero-dependency, safe in edge/serverless.
|
|
32
|
+
|
|
33
|
+
## React — `@synap-core/react`
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { SynapProvider, useSynapContext } from "@synap-core/react";
|
|
37
|
+
|
|
38
|
+
function App() {
|
|
39
|
+
return (
|
|
40
|
+
<SynapProvider podUrl={podUrl} sessionToken={token} workspaceId={ws}>
|
|
41
|
+
<Dashboard />
|
|
42
|
+
</SynapProvider>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`SynapProvider` honours every `createSynapClient` option, incl. `sessionToken`
|
|
48
|
+
and `onAuthError` (a 401 handler). `react` is a peer of your app's React — it
|
|
49
|
+
does not bundle its own.
|
|
50
|
+
|
|
51
|
+
## Realtime — `@synap-core/sdk-realtime`
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { createRealtimeClient } from "@synap-core/sdk-realtime";
|
|
55
|
+
|
|
56
|
+
const rt = createRealtimeClient({ podUrl, sessionToken });
|
|
57
|
+
const stop = rt.onInvalidate((target) => {
|
|
58
|
+
// e.g. refetch the affected query
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Websocket-only transport (credentials never ride a long-poll URL) and it refuses
|
|
63
|
+
to send credentials over non-TLS unless you explicitly pass `allowInsecure`.
|
|
64
|
+
|
|
65
|
+
## Two transports, on purpose
|
|
66
|
+
- `@synap-core/sdk` (tRPC) — for apps. Typed, hooks, realtime.
|
|
67
|
+
- `@synap-core/hub-rest-client` (REST, zero-dep) — for agents/CLIs/scripts. Carries
|
|
68
|
+
agent verbs the tRPC surface has no first-class path for (`ask`, `orient`,
|
|
69
|
+
`discover`). Use it when you want a dependency-free REST client, not a full app.
|
|
70
|
+
|
|
71
|
+
## Keep types fresh
|
|
72
|
+
The SDK is typed by `@synap-core/api-types`, generated from the pod's live router.
|
|
73
|
+
If the pod adds a procedure and you don't see it, bump `@synap-core/api-types`.
|