@synap-core/cli 1.11.0 → 1.13.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/LICENSE +21 -0
- package/README.md +40 -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 +32 -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 +524 -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 +116 -66
- package/dist/commands/automation.js.map +1 -1
- package/dist/commands/box.d.ts +42 -0
- package/dist/commands/box.js +89 -0
- package/dist/commands/box.js.map +1 -0
- package/dist/commands/bridge-setup.d.ts +14 -1
- package/dist/commands/bridge-setup.js +395 -129
- 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 +3 -1
- package/dist/commands/capability.js +249 -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 +1 -13
- package/dist/commands/centrality.js.map +1 -1
- package/dist/commands/close-questions.d.ts +27 -0
- package/dist/commands/close-questions.js +49 -0
- package/dist/commands/close-questions.js.map +1 -0
- package/dist/commands/close-questions.test.d.ts +1 -0
- package/dist/commands/close-questions.test.js +52 -0
- package/dist/commands/close-questions.test.js.map +1 -0
- package/dist/commands/connect.d.ts +36 -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 +79 -44
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/data-extra.d.ts +34 -0
- package/dist/commands/data-extra.js +203 -25
- package/dist/commands/data-extra.js.map +1 -1
- package/dist/commands/data.d.ts +120 -2
- package/dist/commands/data.js +295 -21
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +66 -4
- package/dist/commands/diagnose.js +285 -28
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/doc.d.ts +11 -4
- package/dist/commands/doc.js +39 -14
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/doctor.d.ts +133 -3
- package/dist/commands/doctor.js +761 -41
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain.js +5 -5
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/hooks.d.ts +19 -0
- package/dist/commands/hooks.js +70 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/import.d.ts +393 -13
- package/dist/commands/import.js +1150 -54
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts +34 -9
- package/dist/commands/init.js +481 -981
- 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 +22 -6
- package/dist/commands/knowledge.js +121 -57
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/lens.d.ts +37 -1
- package/dist/commands/lens.js +194 -72
- package/dist/commands/lens.js.map +1 -1
- package/dist/commands/market-authoring.d.ts +29 -2
- package/dist/commands/market-authoring.js +348 -7
- package/dist/commands/market-authoring.js.map +1 -1
- 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 +400 -16
- package/dist/commands/market.js +1802 -146
- package/dist/commands/market.js.map +1 -1
- package/dist/commands/mcp.d.ts +60 -25
- package/dist/commands/mcp.js +251 -64
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/observe.category.test.d.ts +1 -0
- package/dist/commands/observe.category.test.js +59 -0
- package/dist/commands/observe.category.test.js.map +1 -0
- package/dist/commands/observe.d.ts +3 -0
- package/dist/commands/observe.js +7 -5
- package/dist/commands/observe.js.map +1 -1
- package/dist/commands/observe.title.test.d.ts +1 -0
- package/dist/commands/observe.title.test.js +37 -0
- package/dist/commands/observe.title.test.js.map +1 -0
- 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 +171 -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 +11 -1
- package/dist/commands/pods.js +129 -131
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.d.ts +62 -0
- package/dist/commands/proposals-actions.js +143 -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 +579 -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-feed-wait.d.ts +48 -0
- package/dist/commands/session-feed-wait.js +261 -0
- package/dist/commands/session-feed-wait.js.map +1 -0
- package/dist/commands/session-post.d.ts +40 -0
- package/dist/commands/session-post.js +96 -0
- package/dist/commands/session-post.js.map +1 -0
- package/dist/commands/session-wait.d.ts +116 -0
- package/dist/commands/session-wait.js +224 -0
- package/dist/commands/session-wait.js.map +1 -0
- package/dist/commands/sessions.d.ts +54 -0
- package/dist/commands/sessions.js +501 -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-commands.d.ts +2 -0
- package/dist/commands/skills-commands.js +9 -1
- package/dist/commands/skills-commands.js.map +1 -1
- package/dist/commands/skills-commands.test.d.ts +1 -0
- package/dist/commands/skills-commands.test.js +57 -0
- package/dist/commands/skills-commands.test.js.map +1 -0
- package/dist/commands/skills.js +16 -0
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +1 -4
- package/dist/commands/status.js +6 -35
- 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 +112 -0
- package/dist/commands/tracks.js +543 -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 +41 -3
- package/dist/commands/upload.js +120 -18
- package/dist/commands/upload.js.map +1 -1
- 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 +30 -3
- package/dist/commands/whoami.js +186 -23
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/worker-accounts.d.ts +149 -0
- package/dist/commands/worker-accounts.js +339 -0
- package/dist/commands/worker-accounts.js.map +1 -0
- package/dist/commands/worker-accounts.test.d.ts +1 -0
- package/dist/commands/worker-accounts.test.js +224 -0
- package/dist/commands/worker-accounts.test.js.map +1 -0
- package/dist/commands/worker.d.ts +331 -0
- package/dist/commands/worker.js +1067 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/commands/worker.test.d.ts +1 -0
- package/dist/commands/worker.test.js +427 -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 +1043 -186
- 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 +136 -0
- package/dist/lib/agent-door.js +429 -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 +17 -11
- package/dist/lib/auth.js +47 -64
- 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/box/egress.d.ts +82 -0
- package/dist/lib/box/egress.js +264 -0
- package/dist/lib/box/egress.js.map +1 -0
- package/dist/lib/box/evidence.d.ts +86 -0
- package/dist/lib/box/evidence.js +121 -0
- package/dist/lib/box/evidence.js.map +1 -0
- package/dist/lib/box/job-server.d.ts +72 -0
- package/dist/lib/box/job-server.js +246 -0
- package/dist/lib/box/job-server.js.map +1 -0
- package/dist/lib/box/provisioner.d.ts +83 -0
- package/dist/lib/box/provisioner.js +312 -0
- package/dist/lib/box/provisioner.js.map +1 -0
- package/dist/lib/box/proxmox.d.ts +112 -0
- package/dist/lib/box/proxmox.js +211 -0
- package/dist/lib/box/proxmox.js.map +1 -0
- package/dist/lib/box/wire.d.ts +98 -0
- package/dist/lib/box/wire.js +70 -0
- package/dist/lib/box/wire.js.map +1 -0
- package/dist/lib/capture-lane.d.ts +6 -5
- package/dist/lib/capture-lane.js +6 -5
- package/dist/lib/capture-lane.js.map +1 -1
- package/dist/lib/capture-structure.d.ts +230 -11
- package/dist/lib/capture-structure.js +251 -13
- package/dist/lib/capture-structure.js.map +1 -1
- 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/client-header.test.d.ts +1 -0
- package/dist/lib/client-header.test.js +85 -0
- package/dist/lib/client-header.test.js.map +1 -0
- package/dist/lib/conversation-headers.d.ts +33 -0
- package/dist/lib/conversation-headers.js +69 -0
- package/dist/lib/conversation-headers.js.map +1 -0
- package/dist/lib/cp-packages.d.ts +167 -11
- package/dist/lib/cp-packages.js +253 -21
- package/dist/lib/cp-packages.js.map +1 -1
- package/dist/lib/credential-class.d.ts +144 -0
- package/dist/lib/credential-class.js +138 -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/goal-words.d.ts +38 -0
- package/dist/lib/goal-words.js +112 -0
- package/dist/lib/goal-words.js.map +1 -0
- package/dist/lib/hub-client.d.ts +57 -15
- package/dist/lib/hub-client.js +396 -82
- package/dist/lib/hub-client.js.map +1 -1
- 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 +24 -0
- package/dist/lib/init-handoff.js +26 -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 +68 -0
- package/dist/lib/key-source.js +109 -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 +25 -0
- package/dist/lib/knowledge-title.js +47 -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 +49 -0
- package/dist/lib/mcp-bridge.js +180 -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 +118 -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/openclaw.js +3 -2
- package/dist/lib/openclaw.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-moved.d.ts +70 -0
- package/dist/lib/pod-moved.js +146 -0
- package/dist/lib/pod-moved.js.map +1 -0
- package/dist/lib/pod-reach.d.ts +39 -0
- package/dist/lib/pod-reach.js +117 -0
- package/dist/lib/pod-reach.js.map +1 -0
- package/dist/lib/pod-reach.test.d.ts +1 -0
- package/dist/lib/pod-reach.test.js +67 -0
- package/dist/lib/pod-reach.test.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 +74 -112
- package/dist/lib/pod.js +146 -415
- 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/register-claude-code-mcp.test.d.ts +1 -0
- package/dist/lib/register-claude-code-mcp.test.js +78 -0
- package/dist/lib/register-claude-code-mcp.test.js.map +1 -0
- package/dist/lib/review-credential.d.ts +119 -0
- package/dist/lib/review-credential.js +149 -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-feed.d.ts +185 -0
- package/dist/lib/session-feed.js +257 -0
- package/dist/lib/session-feed.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 +152 -10
- package/dist/lib/targets.js +974 -325
- package/dist/lib/targets.js.map +1 -1
- package/dist/lib/template-file.d.ts +4 -0
- package/dist/lib/template-file.js.map +1 -1
- 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/lib/wake-hook-settings.d.ts +57 -0
- package/dist/lib/wake-hook-settings.js +153 -0
- package/dist/lib/wake-hook-settings.js.map +1 -0
- package/dist/lib/wake-state.d.ts +65 -0
- package/dist/lib/wake-state.js +122 -0
- package/dist/lib/wake-state.js.map +1 -0
- package/dist/utils/logger.js +5 -2
- package/dist/utils/logger.js.map +1 -1
- package/package.json +26 -17
- package/skills/README.md +13 -11
- package/skills/agent-os/SKILL.md +214 -99
- package/skills/manifest.json +1 -1
- package/skills/onboard/SKILL.md +55 -26
- package/skills/synap/README.md +5 -8
- package/skills/synap/SKILL.md +1149 -289
- 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 +5 -0
- package/skills/synap/cli-operations.md +24 -18
- package/skills/synap/code-skills.md +70 -0
- package/skills/synap/concepts.md +36 -0
- package/skills/synap/content-os.md +10 -1
- package/skills/synap/creative-loop.md +15 -10
- package/skills/synap/crm.md +21 -52
- package/skills/synap/document-embeds.md +143 -47
- package/skills/synap/escalation-ladder.md +20 -10
- package/skills/synap/focus-sessions.md +56 -21
- package/skills/synap/from-intent.md +158 -0
- package/skills/synap/governance-rules.md +5 -5
- 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 +34 -16
- package/skills/synap/linking.md +42 -41
- package/skills/synap/mcp-remote-servers.md +64 -0
- package/skills/synap/mental-model.md +17 -15
- package/skills/synap/operating-mode-rules.md +2 -2
- package/skills/synap/processes.md +118 -0
- package/skills/synap/quick-reference.md +7 -2
- 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 +110 -0
- package/skills/synap/worked-examples.md +4 -5
- package/skills/synap/workspace-design.md +15 -11
- package/skills/synap/writes.md +105 -25
- package/skills/synap/writing-titles.md +63 -0
- package/skills/synap-app/SKILL.md +149 -67
- package/skills/synap-app/_skill.yaml +1 -1
- package/skills/synap-app/creating-the-base-app.md +12 -7
- package/skills/synap-app/governance.md +27 -16
- package/skills/synap-app/install-commands.md +18 -9
- package/skills/synap-app/overview.md +16 -9
- package/skills/synap-app/using-the-sdk.md +75 -25
- 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 +306 -16
- package/skills/synap-market/_skill.yaml +1 -1
- package/skills/synap-market/author-and-publish.md +145 -8
- package/skills/synap-market/governance-and-catalog.md +7 -0
- package/skills/synap-market/install.md +79 -1
- package/skills/synap-market/overview.md +74 -6
- 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/box/runner.py +206 -0
- 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/node_modules/@synap/hub-rest-client/dist/index.cjs +0 -1261
- package/node_modules/@synap/hub-rest-client/dist/index.d.cts +0 -1647
- package/node_modules/@synap/hub-rest-client/dist/index.d.ts +0 -1647
- package/node_modules/@synap/hub-rest-client/dist/index.js +0 -1231
- package/node_modules/@synap/hub-rest-client/package.json +0 -45
- package/node_modules/@synap/hub-rest-client/src/client.ts +0 -1631
- package/node_modules/@synap/hub-rest-client/src/errors.ts +0 -30
- package/node_modules/@synap/hub-rest-client/src/index.ts +0 -153
- package/node_modules/@synap/hub-rest-client/src/setup.ts +0 -133
- package/node_modules/@synap/hub-rest-client/src/types.ts +0 -1299
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
## From intent — conductor for a new area of work
|
|
2
|
+
|
|
3
|
+
Use this when the user states an **intent** to start or track something that may need structure (a project, domains, kinds, roles, deals-shaped things) — not when they only want to capture a fact into types that already exist (`synap` skill).
|
|
4
|
+
|
|
5
|
+
This skill does **not** provision Company OS. That is `system/agent-os/skill` (install **domains** from templates). This skill decides **what the graph should be**, asks until that is clear, then loads the specialist skill for each write.
|
|
6
|
+
|
|
7
|
+
Load: `system/synap/from-intent`.
|
|
8
|
+
|
|
9
|
+
### Classify first: which layer is this?
|
|
10
|
+
|
|
11
|
+
Before the first write, name the layer in one word, then take its door. Most requests are not a new area at all, and the wrong layer is how a view gets faked as a note or a capability as a view. On a key that lists the starter tools only, `synap_load_skill` the group in brackets first.
|
|
12
|
+
|
|
13
|
+
| Layer | The user wants… | Door |
|
|
14
|
+
| -------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
15
|
+
| **data** | a thing remembered: a company, a note, a decision, a link between two | `synap_capture` for messy input; `synap_create_entity` (`tools:data`) when the kind and fields are known. Never a note standing in for a view or a session. |
|
|
16
|
+
| **view** | to SEE existing things: a list, a grouping, a board, a dashboard | `synap_list_views` first, so you do not duplicate one; then `synap_create_view` (`tools:build`). Never copy records into a new space to show them. |
|
|
17
|
+
| **capability** | access beyond the graph: connect Gmail, send mail, search the live web | §2b: `synap_list_capabilities`, then run it or file its install. Never build a view to stand in for a capability. |
|
|
18
|
+
| **session** | "I'm starting work on X": one bounded piece of work | `synap_start_session` with a one-line goal. Not a task. |
|
|
19
|
+
| **goal** | a goal inside a project: "launch the new site" (a _track_) | §2c: `synap_list_tracks`, else `synap_start_track` (both on every key). Not a project, not a pack, not a playbook. |
|
|
20
|
+
| **rule** | a standing intent: "always…", "from now on…", "every Monday…" | `synap_create_rule` (`tools:governance`) with the user's own words as `intent`; a trigger→steps reaction is `synap_create_automation` (`tools:capabilities`). |
|
|
21
|
+
| **structure** | a new area of work that needs kinds, spaces or a project | the rest of this skill, from §0. |
|
|
22
|
+
|
|
23
|
+
Two layers in one ask ("connect Gmail AND show my mail as a list"): name both and do two steps, capability first. Never fold a capability install into a view.
|
|
24
|
+
|
|
25
|
+
### 0. Orient first (firewall)
|
|
26
|
+
|
|
27
|
+
Before proposing structure:
|
|
28
|
+
|
|
29
|
+
1. `synap_orient` — pending review first; projects; workspaces.
|
|
30
|
+
2. `synap_list_profiles` — kinds **and** roles (`profileKind`, `applicableKinds`, `parentProfileId`, `entityScope`).
|
|
31
|
+
3. `synap_ask` — does this intent already live as a project or a cluster of entities?
|
|
32
|
+
|
|
33
|
+
If a close project exists, **reuse it**. Do not mint a twin. Name-match is enough: if orient already lists a project whose description is this company or this commitment, that **is** the project. Ask "reuse «Launch The Architech»?" — do not invent «Architech Business Model» next to it: a business-model method on that project is a **goal** on it (`synap_list_tracks` / `synap_start_track`), not a twin project.
|
|
34
|
+
|
|
35
|
+
**Pending review first.** If `startHere.pendingReview.count > 0`, offer to walk the queue before any new structure. Unreviewed work looks missing and gets duplicated.
|
|
36
|
+
|
|
37
|
+
4. `synap_start_session` — **name the unit of work before you build it.** Title + goal, nothing else; the session is the room the rest of this happens in, not a form to fill. Every write you make afterwards is attributed to it automatically, so the user can open ONE object and see the whole arc instead of loose proposals with no shared story. Reuse an open session that already covers this intent (`synap_list_sessions`) rather than starting a second one. If the intent is a single fact with no structure behind it, skip the session and use the `synap` skill instead — this whole conductor is the wrong door for that.
|
|
38
|
+
|
|
39
|
+
**Propose its `criteria` — do not grade yourself without them.** Two to five binary, observable statements the person can validate or rewrite ("`list_profiles` returns the `grp-run` kind"), not "the pack is good". They may equally be written by the person; what is not allowed is neither. A session with no criteria leaves you nothing to report against but your own opinion, which is how "85% complete" gets said about work nobody can check. Criteria are declarable at `synap_start_session` (as `outcomes` with `kind: 'fact'`, or the older `criteria`) and upserted later with `synap_update_session` — a session created inside a plan carries `expectedOutputs`, not criteria, so set them on the session once it exists.
|
|
40
|
+
|
|
41
|
+
**A discovered prerequisite is a blocking child, not a paragraph in the same session.** When the goal cannot be finished until infrastructure exists, start that infrastructure as its own session: `parentSessionId` of the goal session, plus `suspendedIntent` — one line naming what the goal was about to do. That pair links the child (`spawned_from`) and blocks the parent (`blocked_by` the child). Work the child. Do not keep building the parent goal beside it. The parent stays open and waits; when the child is validated and closed, the parent unblocks and `suspendedIntent` is what you resume. A child that is only a slice of the same goal passes `parentSessionId` alone and does not block the parent.
|
|
42
|
+
|
|
43
|
+
### 1. Ask before you build (required)
|
|
44
|
+
|
|
45
|
+
Do not install templates, define kinds, or create a project until you can answer these. Ask only what is still unknown — one short pass, not a wizard. Never a 7-step implementation plan in the first reply. What each word means (project, goal, step, template, pack, role): `concepts`.
|
|
46
|
+
|
|
47
|
+
| Question | You are distinguishing |
|
|
48
|
+
| ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
|
|
49
|
+
| What is the **commitment** (the thing we are driving toward over weeks)? | **Project** (optional; gravity). Not a folder. |
|
|
50
|
+
| Which **lasting goals** will it pursue (grow the newsletter, win ten clients…)? | **Goals** — `synap_start_track`, no template; methods are playbooks sessions follow. |
|
|
51
|
+
| Which **new kinds of things** must be recorded that no workspace owns yet? | **Workspaces** (domains). Four-test + template-first. Missing domain → load `agent-os`. |
|
|
52
|
+
| What is the **thing** vs a **hat** vs a **relationship-with-a-life** vs a **stage**? | Kind vs **facet on any kind** vs deal-pattern kind vs status/view. |
|
|
53
|
+
| What already exists that we can **extend**? | `extend-first` — never a twin slug. |
|
|
54
|
+
|
|
55
|
+
**One space per domain:** A space is a domain, installed once (Content, Brand, CRM…). A project is a filter across spaces. To make something “for project X”: file it into X inside the domain's space (`file_into_project`), and link X to the space (`project_use_workspace`). Never create a space named after a project, a brand or a client.
|
|
56
|
+
|
|
57
|
+
Hats are **not** limited to people and companies. A role is a hat on **whatever kind** `applicableKinds` lists (`item`, `task`, `deal`, …). “This item is an X” is a facet, not a new kind, until X has its own independent life.
|
|
58
|
+
|
|
59
|
+
### 2. Propose a MINIMAL graph — one question — ONE next write
|
|
60
|
+
|
|
61
|
+
After orient, your first user-facing message is:
|
|
62
|
+
|
|
63
|
+
1. **Reuse or not** — name the existing project(s) that already match. If none, say you would create one (human / capture-plan / ≥5 evidence). Stop if they must choose.
|
|
64
|
+
2. **What already covers the intent** — existing workspaces (do not onboard an **empty** domain unless this session's goal needs data there _now_). Existing kinds/roles (extend-first).
|
|
65
|
+
3. **Exactly one next write** you want confirmed. Examples of ONE: reuse+pin project lens; install one overlay template; widen one role; **or one connected PLAN** (below). Not: project + template + onboard Finance + declare all edges + playbook filed as five separate proposals.
|
|
66
|
+
|
|
67
|
+
Then **wait**. After that write lands (`proposed` is success), the _next_ turn may offer the next one move.
|
|
68
|
+
|
|
69
|
+
#### ONE write may be a whole connected PLAN
|
|
70
|
+
|
|
71
|
+
`synap_capture` accepts `projects[]` / `sessions[]` / `documents[]` / `links[]` / `entities[]` / `relations[]` — and `skills[]` / `automations[]` / `rules[]` — in a **single call** that files **ONE proposal**. Steps reference each other by `ref`; ids exist only after approval. A plan carrying a session or project applies **all-or-none**, compensated if any step fails.
|
|
72
|
+
|
|
73
|
+
This is the difference between a reviewer seeing one graph and deciding once, and seeing fourteen cards with no visible relationship. **Prefer the plan whenever the structure is connected.** It is not a 7-step sequence — it is one decision about one shape.
|
|
74
|
+
|
|
75
|
+
**The trigger is countable, so count.** The moment you are about to make a second `create_*` call for objects that reference each other — a kind and the playbook that uses it, a project and its sessions, a skill and the automation that calls it — stop: that is ONE plan, not N proposals. This is the check that was missing when an agent filed fourteen.
|
|
76
|
+
|
|
77
|
+
**Name what the work will produce.** Each `sessions[]` step takes `expectedOutputs` — the documents, entities and decisions this session owes. List them at plan time: the plan's own object list IS the expected outputs, so "done" is derivable from slots the person can see rather than announced as a percentage. Every slot filled means the work is finished **pending the person's review** — never silently closed.
|
|
78
|
+
|
|
79
|
+
It also resolves ordering that separate proposals cannot: an `automations[]` step whose flow names a skill created by a `skills[]` step in the SAME call resolves, because the skill is materialized before the automation is validated. Filed separately, the second proposal fails — the first has not been approved yet.
|
|
80
|
+
|
|
81
|
+
Refs, not ids. To change a pending plan, **revise it** (full updated operations, re-validated). Never file a second proposal pointing at items still pending in the first.
|
|
82
|
+
|
|
83
|
+
**Budget is per proposal, not per object.** An agent has a cap on how many proposals may sit pending at once. Fourteen objects as fourteen proposals can exhaust it and get the next write refused; the same fourteen as one plan costs one slot. If a write is ever refused for the cap, that refusal carries a link to raise it — follow the link, do not retry the write. Retrying is worse than waiting: a refused write that you re-send through another door is how the same playbook ends up in the pod twice.
|
|
84
|
+
|
|
85
|
+
Do **not** declare every provides/consumes/trigger edge in the opening. Edges are a later turn, and only for the pair this work actually reads.
|
|
86
|
+
|
|
87
|
+
Do **not** invent CLI (`synap create project --evidenceEntityIds`, `synap marketplace install`, `synap declare workspace source`). Use the MCP/Hub tools this door actually exposes.
|
|
88
|
+
|
|
89
|
+
Empty workspace ≠ broken. An empty Finance is fine until this intent needs a revenue number.
|
|
90
|
+
|
|
91
|
+
### 2b. When the work needs a CAPABILITY (a verb an automation calls)
|
|
92
|
+
|
|
93
|
+
A plan creates instruction skills, automations and rules. **A plan never installs a capability.** Installing one fetches a template from the Control Plane mid-apply, writes secrets and vault grants, and has no undo path — none of which belongs inside an all-or-none batch. Capability access is its own decision, on purpose.
|
|
94
|
+
|
|
95
|
+
Walk this ladder instead. Every rung is a door that exists; do not invent one.
|
|
96
|
+
|
|
97
|
+
| Situation | Do this |
|
|
98
|
+
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
99
|
+
| Not sure the verb exists | `synap_list_capabilities` (a `query` reaches the folded builtin verbs too) |
|
|
100
|
+
| Verb exists but is **not enabled** | **Just run it** — `synap_run_capability`. The refusal files ONE enable request covering your whole pack and hands it back as `enableProposal`, and tells you the action did NOT run. There is no enable tool to call. |
|
|
101
|
+
| Verb is not installed | `market.search` to find it, then `market.install` — both builtin verbs through `synap_run_capability`. For an agent this ALWAYS files a `capability.install` proposal; that is success, not refusal. |
|
|
102
|
+
| The tool does not exist at Synap at all | `tool.request` (builtin verb) — records a `tool_request` so the gap is visible instead of silently blocking you |
|
|
103
|
+
| Authoring a reusable PACK | Declare the need as a package dependency (`relation: "require"`) rather than installing inside the pack |
|
|
104
|
+
|
|
105
|
+
**Author the automation LAST.** An automation whose `capability` node names a verb that is not in the catalog is rejected at author time (`capability_unknown_verbId`) — the write never lands, so there is nothing half-built to clean up. Get the verb enabled or installed first, then file the plan that uses it.
|
|
106
|
+
|
|
107
|
+
A skill your plan creates IS resolvable in the same batch: the automation door looks a verb up by **skill name**, and skills materialize before automations. That is why a fact + a behaviour can ride in one proposal.
|
|
108
|
+
|
|
109
|
+
### 2c. A goal inside a project → a GOAL (a track)
|
|
110
|
+
|
|
111
|
+
A **goal** is a _track_ in every tool and field name (`synap_start_track`, `trackId`) — say "goal" to the person, never "track". It lives inside ONE project ("Launch the new site", "Win the first ten clients"); a project runs several. A goal that FINISHES holds an `endState` (what done looks like, a short paragraph in the person's words) and **2 to 5 `criteria`** — binary checks, each with how it is checked: measured (evidence a run posts), judged by a person, handed over, or decided by an outside party. A goal kept open as long as it matters ("keep the newsletter growing") has no criteria: it steers by a `direction` (one line) and, only if the person names a number, a `kpi` `{ label, unit?, target }`. Propose its `workKind` (project, operation, investigation…) and `uncertainty`; the person confirms them. Its judge (the owner unless someone else is named, `synap_set_track_participant`) accepts what runs claim and closes it with a verdict — hitting a number never closes it. Work in it is ordinary sessions filed into it. Definitions: `concepts`.
|
|
112
|
+
|
|
113
|
+
**Asked to pursue a goal in a project** ("launch the new site in Synap"): `synap_list_tracks` for the project (already running? resume it) → none? Propose the end state and 2–5 criteria in one line each and let the person correct them, then `synap_start_track` with `projectId`, `name`, `endState`, `criteria` (and `workKind`, `uncertainty`) — no method needed. Leave criteria out only when the person describes something to keep doing, not something to finish. Then work: `synap_start_session` with `trackId`, one session per sitting, carrying the criteria it works on (same `key`), as many as it takes.
|
|
114
|
+
|
|
115
|
+
| The user needs… | Do this |
|
|
116
|
+
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
117
|
+
| a **goal** in an existing project | `synap_list_tracks` (already running?) → `synap_start_track` (`name`, `endState`, 2–5 `criteria`; lasting: `direction`, optional `kpi`) |
|
|
118
|
+
| one piece of work toward it | a **session** born in the goal: `synap_start_session` (or `synap_run_playbook` for a session template) with `trackId` |
|
|
119
|
+
| a repeatable way to do that work | a session template (`synap_create_playbook`, default scope) run with `trackId` — not a goal method |
|
|
120
|
+
| new **kinds of things** no workspace owns | a workspace (four-test, `workspace-design`) — never to represent a goal |
|
|
121
|
+
| a new long-lived commitment with its own gravity | a project — never a twin project for a goal of an existing one |
|
|
122
|
+
|
|
123
|
+
**A goal steers; its sessions verify.** A session that passes a criterion CLAIMS it; the judge accepts or sends it back — never accept your own claim. Report a lasting goal's number with `synap_update_track` `kpi: { current }`: a STATED value, stamped with when and by whom — never invent a measurement. Reaching the target nudges the person to re-aim it or close the goal; never change the target or close the goal yourself. While a goal is active, its agent may work in the spaces its project links (`synap_project_use_workspace`); pausing it suspends that, closing or dropping it ends it. Pause, resume, close (`completed` + a `verdict`) or drop (`archived`, with a `verdict` saying why) it with `synap_set_track_status`; your close is a proposal the person approves. Goal writes are governed: `proposed` is success. Installing a pack onto a project does **not** start goals — start each one.
|
|
124
|
+
|
|
125
|
+
**Legacy: goals with steps.** A goal started from a goal template (`scope: "project"`, `playbookId` on `synap_start_track`) has re-enterable stages. Work a stage with `synap_start_stage_session` (`trackId`, optional `stageKey`); never `synap_advance_track` without the user — advancing returns an `offer` (show it, start it only on a yes). Do not create new goal templates; a new goal needs none.
|
|
126
|
+
|
|
127
|
+
### 3. Which skill to load next
|
|
128
|
+
|
|
129
|
+
| Need | Skill |
|
|
130
|
+
| -------------------------------------------- | ---------------------------------------------------------- |
|
|
131
|
+
| Schema: facet, overlay, child kind, new kind | `system/synap-schema/extend-first` then `extend-vs-create` |
|
|
132
|
+
| Missing operational domain | `system/agent-os/skill` |
|
|
133
|
+
| Views / cards once the model exists | `system/synap-ui/skill` |
|
|
134
|
+
| What a word means (the one glossary) | `system/synap/concepts` |
|
|
135
|
+
| Lenses, gravity, sessions | `system/synap/lenses` |
|
|
136
|
+
| Four-test for a workspace | `system/synap/workspace-design` |
|
|
137
|
+
| Index of everything | `catalog` |
|
|
138
|
+
|
|
139
|
+
### Firewalls (never)
|
|
140
|
+
|
|
141
|
+
- Twin **project**: orient already has this company/commitment under another name.
|
|
142
|
+
- Twin kind/role whose **slug or display name** matches `list_profiles`.
|
|
143
|
+
- A 7-step "right sequence" in the first confirm. One structural move per turn.
|
|
144
|
+
- **Splitting one coherent structure into N proposals.** If the objects reference each other, they are ONE plan through `synap_capture`, not one `create_*` call each. N cards the reviewer must mentally re-join is the failure this conductor exists to prevent.
|
|
145
|
+
- Building structure with no session open. The unit of work is named first (§0.4) or the work arrives as orphan proposals.
|
|
146
|
+
- Grading yourself. "85% complete" against no criteria and no declared outputs is an opinion, not a status — propose criteria (§0.4) and expected outputs (§2) so the person can check the claim.
|
|
147
|
+
- Onboard or fill an empty workspace "because it is empty."
|
|
148
|
+
- Invent a workspace that fails the four-test.
|
|
149
|
+
- Nested or twin projects, or a workspace, to represent a **goal or method** of an existing project. A lasting goal is a goal (`synap_start_track`); a repeatable method is a playbook a session or worker follows; one bounded piece of work is a session (`trackId`).
|
|
150
|
+
- Invent CLI flags or tools this door does not list.
|
|
151
|
+
- A second entity for a hat (`kind_mismatch` → **widen** the role’s `applicableKinds`, then `attach_facet`).
|
|
152
|
+
- Company/person-only facets. If the hat belongs on `item` (or any kind), the role’s `applicableKinds` must include that kind.
|
|
153
|
+
- CRM `deal` (pre-sale pipeline) as a generic price timeline. A commercial snapshot with its own life uses the **deal precedent** (own kind), not a twin `deal` slug and not JSON on the thing.
|
|
154
|
+
- Encoding the pattern only as Knowledge and expecting every MCP agent to find it. Skills + this conductor are the all-pods path.
|
|
155
|
+
|
|
156
|
+
### After it works
|
|
157
|
+
|
|
158
|
+
Offer L4, one at a time: session → work template; cell → renderer; **project → pack** (a `suite`) (`synap_export_project_pack` / CLI `--from-project`). Export returns a thin suite **plus** full constituent workspace packages — publish constituents first, then the suite (CLI does both). Install with `projectName` (human) or `projectId` (agent) to mint/reuse a named engagement and stamp uses-edges. Optional `projectSurface` lands in `projects.settings.layout` (engagement UI). Not live entity rows. Never crystallize a guess. No `app` package type.
|
|
@@ -36,29 +36,29 @@ Changed: [field] [old value] → [new value]
|
|
|
36
36
|
|
|
37
37
|
```
|
|
38
38
|
Context: User asked to track the Acme deal they mentioned in today's call.
|
|
39
|
-
Intent: Creates a deal entity for Acme at
|
|
39
|
+
Intent: Creates a deal entity for Acme at draft stage linked to Alice Johnson.
|
|
40
40
|
Links: ent_person_alice_johnson, ent_company_acme
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
**Example (update):**
|
|
44
44
|
|
|
45
45
|
```
|
|
46
|
-
Context: User confirmed the Acme
|
|
46
|
+
Context: User confirmed the Acme proposal went out.
|
|
47
47
|
Intent: Advances the deal through the pipeline so it appears in the proposal view.
|
|
48
48
|
Links: ent_deal_acme, ent_person_alice_johnson
|
|
49
|
-
Changed:
|
|
49
|
+
Changed: commercialStage draft → proposed
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
Rules:
|
|
53
53
|
|
|
54
54
|
- One sentence per field. No padding.
|
|
55
55
|
- `Links` must reference real entity IDs or slugs visible in the current context — not descriptions like "the related project".
|
|
56
|
-
-
|
|
56
|
+
- The pod's own governance sentence (for example "This agent asks before every change.") is never acceptable as a `reasoning` value. It says why a person must review, not why you made the change. Write it and the proposal is meaningless to the reviewer.
|
|
57
57
|
|
|
58
58
|
Example response to the user:
|
|
59
59
|
|
|
60
60
|
> I queued **Delete task "Q2 plan review"** for your review. Destructive actions need your approval. Open it: synap://open/proposal/prp_abc
|
|
61
61
|
|
|
62
|
-
Auto-approved by default (for agent API keys): `entity.create`, `entity.update`, `document.create`, `relation.create`, `view.create`, `
|
|
62
|
+
Auto-approved by default (for agent API keys): `entity.create`, `entity.update`, `document.create`, `relation.create`, `view.create`, `channel.create`, `memory.*`, all reads. META-MODEL writes (`profile.*`, `property_def.*` — new kinds, roles and fields) always propose: they are pod-wide and have no inert state to land in. Destructive actions (`delete`, `archive`, `purge`) always propose in agent-owned workspaces.
|
|
63
63
|
|
|
64
64
|
For the full whitelist, agent-user semantics, and workspace overrides, read **`governance.md`**.
|
|
@@ -60,18 +60,20 @@ Agents can perform these actions directly without a proposal:
|
|
|
60
60
|
- `document.create`
|
|
61
61
|
- `memory.store` (always auto-approved, never proposed)
|
|
62
62
|
- `view.create`
|
|
63
|
-
- `profile.create`, `profile.update`
|
|
64
|
-
- `property_def.create`, `property_def.update`
|
|
65
63
|
- `channel.create`
|
|
66
64
|
- `bento.arrange`
|
|
67
|
-
- `filesystem.write_workspace` (
|
|
65
|
+
- `filesystem.write_workspace` (agent sandbox only)
|
|
68
66
|
|
|
69
67
|
**Proposal-gated** (always require approval when done by agents):
|
|
70
68
|
|
|
71
69
|
- `entity.delete`, `entity.archive`, `entity.purge`
|
|
72
70
|
- `view.update`, `view.delete`
|
|
73
|
-
- `profile.delete`
|
|
74
|
-
- `
|
|
71
|
+
- `profile.create`, `profile.update`, `profile.delete` — META-MODEL. A kind/role
|
|
72
|
+
is pod-wide (`entityScope` defaults to `'pod'`), so it changes what the pod IS
|
|
73
|
+
in every workspace. Unlike `automation.create` (auto-approved but landing
|
|
74
|
+
INERT as a draft), profiles have no inert state, so they propose.
|
|
75
|
+
- `property_def.create`, `property_def.update`, `property_def.delete` — a base
|
|
76
|
+
property def (`workspace_id` NULL) extends a shared kind for every workspace.
|
|
75
77
|
- `workspace.create`, `workspace.update`, `workspace.delete`
|
|
76
78
|
|
|
77
79
|
## Destructive action override
|
|
@@ -108,7 +110,7 @@ You do not poll or wait. The user's experience is asynchronous.
|
|
|
108
110
|
|
|
109
111
|
An agent user is a pod-wide user with `agentMetadata.writesRequireProposal` set. Created by `POST /api/hub/setup/agent`. Each agent user has:
|
|
110
112
|
|
|
111
|
-
- `agentType`: a free-form string (`"claude-code"`, `"
|
|
113
|
+
- `agentType`: a free-form string (`"claude-code"`, `"codex"`, `"raycast"`, `"custom"`)
|
|
112
114
|
- `agentMetadata`: arbitrary JSON for config
|
|
113
115
|
- Hub API keys scoped to `hub-protocol.read` + `hub-protocol.write` + `mcp.*`
|
|
114
116
|
|
|
@@ -184,7 +186,8 @@ GET /api/hub/workspaces/{workspaceId}/governance
|
|
|
184
186
|
effective: {
|
|
185
187
|
autoApproveFor: [ // the actual whitelist at this workspace
|
|
186
188
|
"entity.create", "entity.update", "relation.create", "document.create",
|
|
187
|
-
"view.create", "profile.create
|
|
189
|
+
"view.create", "memory.*", … // NOT profile.create / property_def.create —
|
|
190
|
+
// meta-model writes propose (see "Proposal-gated" above)
|
|
188
191
|
],
|
|
189
192
|
governanceMode: "default" | "agent-owned",
|
|
190
193
|
proposalApprovalPolicy: "owner_and_admins" | "any_editor" | "admins_only",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## Hand work to an agent on the person's computer
|
|
2
|
+
|
|
3
|
+
The person says "start this on my devbox", "have my Mac's Claude Code do it", "give this session to Codex". You find the agent, hand it the work through a session, follow the session's room, and report back. You never run their machine yourself: an agent they connected there (`synap worker`, Claude Code, Codex) picks the work up.
|
|
4
|
+
|
|
5
|
+
**1. Find it — `synap_list_agents`.** One read: `computers[]` (the person's own) and `agents[]`, each with `computer`, `canTakeYourWork` (else `whyNot`), `live`, `paused`, `lastSeenAt`, and `handOff`: what YOUR hand-off would do right now (`direct`, `asks_you`, `blocked` + `handOffReason`). Ready agents come first.
|
|
6
|
+
|
|
7
|
+
- **Match the person's words against computer names first** ("my devbox" → the computer named `devbox`, any case), **then agent names and types** ("Codex", "claude-code"). Take the agents on that computer that can take the work.
|
|
8
|
+
- **Two or more fit → ask the person** which one, by name ("Claude Code on devbox, or Codex on devbox?"). Never pick for them.
|
|
9
|
+
- **None fits → say so.** "I see no agent on a computer called devbox" plus what you do see. Never hand it to a different machine silently.
|
|
10
|
+
- **`paused: true` → say it is paused** and that a person must resume it (Settings › Agents). Do not hand it off.
|
|
11
|
+
- **`live: false` → say when it was last seen** (`lastSeenAt`) and that it picks the work up the next time it checks in. Hand off only if the person still wants it.
|
|
12
|
+
- **`canTakeYourWork: false`** — `whyNot` says why: `not_owned` (another person's agent: it would never see this work), `wrong_reach` (the pod's own agent: it answers in rooms, it never picks work up), `paused`.
|
|
13
|
+
|
|
14
|
+
**2. Hand it — through a session.** The session's roster is how work reaches an agent.
|
|
15
|
+
|
|
16
|
+
- New work: `synap_start_session` with a `title`, a one-sentence `goal`, 2–5 `criteria` the person can check, and `agentIds: [agentUserId]`.
|
|
17
|
+
- Work in flight ("this session"): `synap_update_session` with `addAgentId: agentUserId`.
|
|
18
|
+
- Read the reply. `handOffs[].status` (start) or `handOff.status` (update): `granted` = on the roster now; `proposed` = waiting for the person's approval; `denied` = say the `reason` as given.
|
|
19
|
+
- **`asks_you` / `proposed`: the person approves the hand-off first.** Tell them plainly: "approve the hand-off on your phone", with the `reviewUrl` from the reply. It is success, do not retry. Then wait: `synap_get_session` until the agent is on its roster (or `synap_wait_for_answer` if you also asked them something), and go on to step 3.
|
|
20
|
+
- **`blocked` / `denied`: say why, in the reason's words.** Never retry it as is. One case the list cannot predict: your own proposal limit ("Agent proposal limit reached") — the reply carries a link to raise it; pass that to the person.
|
|
21
|
+
|
|
22
|
+
**3. Follow the room.** Everything the agent says lands in the session's room (`session.channelId`). Read it with `synap_get_thread_context { threadId: channelId }`; read the session's outcomes with `synap_get_session`. A `synap worker` on that computer follows this protocol:
|
|
23
|
+
|
|
24
|
+
- It checks for handed sessions about every 30 seconds and starts ONE run of Claude Code per session, in its working folder.
|
|
25
|
+
- It **claims** the session in the room in one line: picked up, and what it will do first.
|
|
26
|
+
- It works on a branch (`devbox/<session>-<slug>`, in a git worktree). It never pushes to main and never deploys.
|
|
27
|
+
- It **asks** with a room message starting `QUESTION:`. Kind `update` = you, the orchestrating AI, can answer; kind `question` = a decision only the person can make (the person is notified). It waits up to 30 minutes, reading the room every minute, and takes the FIRST reply posted after its question. No reply: it states its assumption and continues, or stops and says what is blocked.
|
|
28
|
+
- It **reports** in the room (what changed, branch, commit, files) and records deliverables against the session's outcomes. It does not close the session; the owner does.
|
|
29
|
+
- **Any room message posted after its run ended, by anyone but the agent, wakes it again** in the same conversation (up to 20 times). That is how an answer reaches it after it stopped. So post in the room only what you want it to act on.
|
|
30
|
+
|
|
31
|
+
Answer a `QUESTION:` of kind `update` yourself with `synap_post_message` to the room. Leave kind `question` to the person, or ask them and relay their answer.
|
|
32
|
+
|
|
33
|
+
**4. Report back.** Tell the person, in a few lines: which agent on which computer took it, whether it is on the roster or waiting for their approval, what the agent reported (result, branch, commit), and anything it asked that only they can answer. Point them at the session to review and close it.
|
|
@@ -8,6 +8,7 @@ When the user is interacting with Synap's AI Companion (the in-browser chat pane
|
|
|
8
8
|
| ---------------------------- | --------------------------- | --------------------------------- |
|
|
9
9
|
| `[[entity:UUID\|Name]]` | Purple entity chip | Opens entity detail in side panel |
|
|
10
10
|
| `[[view:UUID\|Name]]` | Blue view chip | Opens view |
|
|
11
|
+
| `[[view:UUID]]` | View chip, named for you | Same; the label is optional |
|
|
11
12
|
| `[[open:side\|view:UUID]]` | Amber "Open in side" button | Opens view in side panel |
|
|
12
13
|
| `[[open:main\|view:UUID]]` | Amber "Open" button | Opens view in main panel |
|
|
13
14
|
| `[[open:side\|entity:UUID]]` | Amber "Open in side" button | Opens entity in side panel |
|
|
@@ -16,10 +17,11 @@ When the user is interacting with Synap's AI Companion (the in-browser chat pane
|
|
|
16
17
|
|
|
17
18
|
### Rules
|
|
18
19
|
|
|
20
|
+
- **The label is optional.** `[[kind:UUID]]` is valid: in a document the chip shows the object's current name; in chat, where nothing looks it up, it reads as its kind ("View"). So in a chat reply, write the name you know: `[[view:UUID|Active Tasks]]`. A chip never shows the raw id.
|
|
19
21
|
- **Always use real IDs.** Never hallucinate UUIDs. Only emit patterns for entities/views you just created or retrieved via Hub Protocol.
|
|
20
22
|
- **Emit after creation.** When you create a view or entity, immediately reference it: `"Created your pipeline → [[view:abc123|Active Tasks]]"`
|
|
21
23
|
- **Prefer side panel.** Use `[[open:side|view:UUID]]` so the user keeps their current context.
|
|
22
|
-
- **
|
|
24
|
+
- **Companion replies and documents.** In a document, `[[entity:…|…]]` / `[[view:…|…]]` render as chips and the editor keeps them (`document-embeds.md`); the `[[open:…]]` / `[[run:…]]` commands are chat-only. Other channels and memory ignore them.
|
|
23
25
|
- **Combine with prose.** Don't lead with a chip — embed it naturally: `"Here are your open deals → [[view:xyz|Deals Pipeline]] · [[open:side|view:xyz]]"`
|
|
24
26
|
|
|
25
27
|
### Proposals
|
|
@@ -28,11 +30,17 @@ There is no `[[open:…|proposal:…]]` chip — `open`'s `resourceType` only ac
|
|
|
28
30
|
`entity`, `view`, `doc`, `cell`, `channel`. A proposal is not one of those, so
|
|
29
31
|
never invent that form.
|
|
30
32
|
|
|
31
|
-
When a write returns `status: "proposed"
|
|
32
|
-
`reviewUrl`
|
|
33
|
-
|
|
33
|
+
When a write returns `status: "proposed"` (or any per-op outcome carrying a
|
|
34
|
+
`reviewUrl` — `writeReceipt.reviewUrl`, `perm.reviewUrl`, a capability run's
|
|
35
|
+
`kind: "proposed"`), the response also carries that `reviewUrl` (a real,
|
|
36
|
+
resolvable `${PUBLIC_URL}/open/<id>` link — never invented). **Surfacing it is
|
|
37
|
+
MANDATORY, not optional:** every reply that reports a proposed write MUST
|
|
38
|
+
include the link as a plain markdown link, plus one sentence explaining why it
|
|
39
|
+
was proposed instead of auto-applied:
|
|
34
40
|
|
|
35
|
-
> Queued the task deletion for your review — destructive actions always need approval: [Review proposal](https://pod.example.com/
|
|
41
|
+
> Queued the task deletion for your review — destructive actions always need approval: [Review proposal](https://pod.example.com/open/prp_abc)
|
|
36
42
|
|
|
37
|
-
|
|
38
|
-
user to
|
|
43
|
+
A reply that only says "I've proposed that for review" with no link is
|
|
44
|
+
incomplete — the user has no way to act on it. `"proposed"` is normal, not an
|
|
45
|
+
error — don't apologize for it or wait for the user to approve before
|
|
46
|
+
continuing the conversation.
|
package/skills/synap/lenses.md
CHANGED
|
@@ -2,18 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
You don't work "inside a workspace" the way you'd work inside a folder. You operate **across the whole pod**, and you **focus** through up to three composable lenses. **Lenses narrow; they never silo.** Omitting them is legal and common — that's pod-wide.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
|
|
7
|
-
| **Project** | a **company or initiative** — the thing that ties the work together (Synap, a client, a launch). The lens you usually _organize by_. | `synap project use <id>` / `clear` |
|
|
8
|
-
| **Workspace** | an **operational domain** — where data lives (Foundation, CRM, Marketing, Finance, Builder). How the work is separated; the default home for writes. | `synap use <name-or-id>` |
|
|
9
|
-
| **Session** | the **work room** for the current goal (holds goal, deliverables, progress) | `synap session start --goal "…"` / `attach <id>` |
|
|
5
|
+
Tool names below are stems; your door may prefix them.
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
What each word means (workspace, project, goal, step, work): `concepts` — the one glossary. This file is only about scoping.
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
| Lens | Scopes | Set it (MCP / CLI) |
|
|
10
|
+
| ------------- | ---------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
11
|
+
| **Workspace** | a domain; a thing lives in exactly ONE; default write home | `set_workspace_focus` / `synap use <name-or-id>` |
|
|
12
|
+
| **Project** | a commitment across workspaces; a thing can be in several | `set_project_focus` or `projectId` / `synap project use <id>` |
|
|
13
|
+
| **Session** | the work room for the current goal; pass its id on writes | `start_session` / `synap session start --goal "…"` / `attach <id>` |
|
|
14
|
+
|
|
15
|
+
**The project rule (one rule, every door):** a project is set ONLY when the user names it — declare it with `set_project_focus`, or pass `projectId` on the write. Filing into a project shares entities and documents with its members (a session is shared only through its room, never by filing), so never infer one from content, and never let a session decide it: a write without a `sessionId` is grouped into YOUR session — the one you started, else one opened for you, never another client's — and that door-picked session never sets the project. When nobody named a project, leave it unset. Guessing a workspace is merely untidy; guessing a project is not.
|
|
16
|
+
|
|
17
|
+
**One space per domain — the lens rule (every door):** A space is a domain, installed once (Content, Brand, CRM…). A project is a filter across spaces. To make something “for project X”: file it into X inside the domain's space (`file_into_project`), and link X to the space (`project_use_workspace`). Never create a space named after a project, a brand or a client. A second space from a template whose domain already has a live space is refused for an agent (`status: "exists"` + the space to use); a person may still create one, with the same note.
|
|
18
|
+
|
|
19
|
+
**Reads:** pod-wide by default; find by name, id or role, and pass `workspaceId` / `projectId` only to narrow a list.
|
|
20
|
+
|
|
21
|
+
**Writes:** name the kind (profile slug) and, when known, the roles as facets. Omit `workspaceId` unless you are deliberately pinning a domain — the server places the write from installed profile metadata. Never invent a workspace name. Focus sticks for the session; an explicit `workspaceId` / `projectId` on one call overrides it for that call.
|
|
22
|
+
|
|
23
|
+
**Empty domains:** a workspace holding 0 entities is a scaffold — prefer an active one unless the user names it (`orient` lists active domains; `detail:'full'` shows every one).
|
|
24
|
+
|
|
25
|
+
**Where the kinds are:** `orient` names the kinds in use, most-used first; the profile-listing tool lists every kind and role. A kind's property schema (fields, enums, required): over MCP, `get_entity` on any existing entity of that kind returns it as `effectiveProperties`; over HTTP, `GET /api/hub/discover?profileSlugs=<slug>`; CLI `synap discover`. A write that breaks the schema is rejected with the valid fields quoted.
|
|
26
|
+
|
|
27
|
+
**The space brief — what a space is FOR, and what it KNOWS.** PIN a space and the pod hands you its **brief**: `purpose` + `persona` (what it is for), `keyKinds` (the kinds it holds), `rules`, `playbooks`, `anchors`, and — the one that changes how you work — **`skills`**: the agent know-how the space ACTIVATES, each `{ slug, mode, when? }`. Reach it by passing a `workspaceId` to `orient` (an unpinned orient carries NO brief — it is space-scoped), or by `set_workspace_focus`; its reply carries the same brief. **Read the mode:** `mode: 'always'` is in effect for every task in this space — `load_skill` its slug before you work; `mode: 'on-demand'` means load it when the task matches its `when`. A space's skills are the pod telling you _this domain has a way of doing things_ — honour them rather than improvising. Pin the space the moment you are about to work in one.
|
|
28
|
+
|
|
29
|
+
**How they compose** (definitions: `concepts`):
|
|
30
|
+
|
|
31
|
+
- A **project spans workspaces** and a **workspace spans projects**.
|
|
32
|
+
- **Membership is per-entity, filed on write.** An entity belongs to a project because it was written **under that project lens** (`belongs_to_project`) — that is the data ACL/filing edge. Separately, provisioning with a `projectId` also stamps **`project --uses--> workspace`**: an INDEX of domains the engagement runs through. That index is **not** an ACL and does **not** replace entity filing — set the project lens before writing work so entities compose into the project from any workspace.
|
|
33
|
+
- A lasting goal inside a project is a **goal** (a _track_ in every tool and field name — say "goal" to the person), never a child project or a workspace; a bounded piece of work is a **session** (`trackId` when it belongs to a goal). There are no nested projects.
|
|
17
34
|
|
|
18
35
|
- **The connection is pod-wide by design.** Your MCP/CLI link is _not_ welded to a workspace — reads default pod-wide, writes default to a sensible workspace. Pass a lens to narrow a single call; the lens is a focus, not a fence.
|
|
19
36
|
- **These are per-Claude-session.** Two concurrent Claude sessions can sit on different projects/workspaces/sessions without colliding. `synap use` here rebinds **this** session only.
|
|
@@ -24,15 +41,16 @@ You don't work "inside a workspace" the way you'd work inside a folder. You oper
|
|
|
24
41
|
**Before the FIRST write of a new unit of work**, check your lens and orient if you're unsure:
|
|
25
42
|
|
|
26
43
|
1. `synap lens` — am I scoped where this work belongs?
|
|
27
|
-
2. If unsure what exists → `synap orient` — it returns
|
|
28
|
-
3. **Connect or create:** if the right project / workspace / session doesn't exist yet, create it. A **session is the normal per-task move**. Creating a **workspace (a new operational domain) is a deliberate, expected move as the work grows** — not something to avoid. A **project, though, is a COMMITMENT WITH GRAVITY**: search existing projects first (`synap orient`) and prefer **linking into an existing one** via `belongs_to_project`. Only create a new project for a real initiative that ties work together — never for a task, plan, repo, or theme (those are entities), and **never for the pod owner's own company** (the company _is_ the pod, not a project inside it). An agent-created project must cite **≥5 existing entities** as evidence or the backend rejects it, and near-duplicate
|
|
44
|
+
2. If unsure what exists → `synap orient` — it returns the **briefing**: pending review, open sessions, the kinds in use, then the projects and workspaces (names + ids), without a data dump. Never guess IDs. Drill into a workspace's profiles or a project's contents only when you actually need them.
|
|
45
|
+
3. **Connect or create:** if the right project / workspace / session doesn't exist yet, create it. A **session is the normal per-task move**. Creating a **workspace (a new operational domain) is a deliberate, expected move as the work grows** — not something to avoid. A **project, though, is a COMMITMENT WITH GRAVITY**: search existing projects first (`synap orient`) and prefer **linking into an existing one** via `belongs_to_project`. Only create a new project for a real initiative that ties work together — never for a task, plan, repo, or theme (those are entities), and **never for the pod owner's own company** (the company _is_ the pod, not a project inside it). An agent-created project must cite **≥5 existing entities** as evidence or the backend rejects it, and a near-duplicate name is filed for the person to review, showing the existing project.
|
|
29
46
|
|
|
30
47
|
**Don't re-orient mid-flow.** Once you've oriented and you're in a run of related writes, keep going — re-check only when you **start a new piece of work** or switch domains. The reflex guards the _start_ of work, not every call.
|
|
31
48
|
|
|
32
|
-
### Notice a missing domain — and offer it
|
|
49
|
+
### Notice a missing method or domain — and offer it
|
|
33
50
|
|
|
34
|
-
|
|
51
|
+
A project sometimes clearly needs something it lacks. Tell the two apart first:
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
- **A lasting goal is missing** (the talk keeps returning to a goal — growing the newsletter, landing clients… — and `list_tracks` shows none for it) → offer a **goal**: _"This project has no goal for the newsletter yet — want me to start one?"_ Then `start_track` with a `name` and `direction`; no method needed.
|
|
54
|
+
- **A domain is missing** (new kinds of things must be recorded that no workspace owns — e.g. you are logging deals and there is no CRM) → offer a **workspace**, provisioned with the project lens active (see the `agent-os` skill). Never a workspace to stand for a method.
|
|
37
55
|
|
|
38
|
-
|
|
56
|
+
Say it **once, at the end, in one line**. **Offer, don't auto-build.** One nudge per response, only when the gap is real — never a checklist of everything the project "could" have. **If the user has already declined it (this session or before), drop it — don't re-offer.**
|
package/skills/synap/linking.md
CHANGED
|
@@ -8,17 +8,14 @@ When a profile property has `valueType: "entity_id"`, setting it on entity creat
|
|
|
8
8
|
|
|
9
9
|
Known system-profile auto-syncs:
|
|
10
10
|
|
|
11
|
-
| Profile
|
|
12
|
-
|
|
|
13
|
-
| task
|
|
14
|
-
| task
|
|
15
|
-
| contact
|
|
16
|
-
| deal
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
| anchor | `channelId` | (channel) | `anchored_in` |
|
|
20
|
-
|
|
21
|
-
Custom profiles: if you created a property with `valueType: "entity_id"`, the auto-sync kicks in, but the relation type defaults to `related_to` unless the profile defines a `relationDefinition`. When precision matters, create the relation explicitly (Way 2) with a specific `type`.
|
|
11
|
+
| Profile | Property | Target profile | Auto-relation type |
|
|
12
|
+
| ------- | ----------- | -------------- | -------------------- |
|
|
13
|
+
| task | `projectId` | project | `belongs_to_project` |
|
|
14
|
+
| task | `assignee` | person | `assigned_to` |
|
|
15
|
+
| contact | `companyId` | company | `works_at` |
|
|
16
|
+
| deal | `contactId` | contact | `deal_for` |
|
|
17
|
+
|
|
18
|
+
Custom profiles: an `entity_id` property does NOT create an edge on its own. Auto-sync writes a relation only when the property def is mapped to a relation def (its `relationDefId`), and the edge then takes THAT def's slug. An unmapped `entity_id` property stores the id and creates no relation at all — there is no default or fallback type. When you need the edge, create it explicitly (Way 2) with an existing relation-def slug; `synap_list_profiles` returns them under `relationTypes`.
|
|
22
19
|
|
|
23
20
|
**Do not trust this table to stay current.** Always verify with `GET /api/hub/profiles` — the returned profile includes `properties[].valueType` and `properties[].targetProfileSlug`. Any property with `valueType: "entity_id"` is an auto-sync candidate.
|
|
24
21
|
|
|
@@ -68,37 +65,40 @@ POST /api/hub/relations
|
|
|
68
65
|
}
|
|
69
66
|
```
|
|
70
67
|
|
|
71
|
-
##
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
| Type
|
|
76
|
-
|
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
|
|
90
|
-
|
|
68
|
+
## Relation types — use the pod's, never invent one
|
|
69
|
+
|
|
70
|
+
A relation's `type` must be the slug of a relation definition the pod has. `synap_list_profiles` returns them under `relationTypes` (custom ones a workspace added included) — read it before linking. The defaults every pod ships:
|
|
71
|
+
|
|
72
|
+
| Type | Direction | When |
|
|
73
|
+
| ------------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
74
|
+
| `relates_to` | bidirectional | Generic association, when no stronger type fits |
|
|
75
|
+
| `references` | source → target | A task references a document, a note cites an article |
|
|
76
|
+
| `mentions` | source → target | One entity is mentioned within another's content |
|
|
77
|
+
| `links_to` | source → target | A hyperlink or explicit pointer |
|
|
78
|
+
| `parent_of` | source → target | Entity hierarchy (a kind instance of another). Not nested projects — those do not exist. A goal in a project is a track; a unit of work is a session. |
|
|
79
|
+
| `belongs_to_project` | source → target | An entity filed into a project (prefer the `projectId` property — Way 1) |
|
|
80
|
+
| `assigned_to` | source → target | A task/project assigned to a person |
|
|
81
|
+
| `created_by` | source → target | A note/document authored or created by a person |
|
|
82
|
+
| `blocks` / `depends_on` | source → target | A DEPENDENCY: the source blocks / waits on the target. Dependencies are becoming ONE `blocked_by` edge across kinds (session · entity · track); these two slugs are its entity-side names |
|
|
83
|
+
| `tagged_with` | source → target | Categorization by a tag entity |
|
|
84
|
+
| `attended_by` | source → target | An event's participant |
|
|
85
|
+
| `works_at` · `works_on` · `affiliated_with` | source → target | A person and an organization / a project they contribute to / an affiliation |
|
|
86
|
+
| `knows` · `met_at` · `discussed_with` | person → target | People who know each other / where they met / who they talked with |
|
|
87
|
+
| `deal_for` | source → target | A sales deal for a contact |
|
|
88
|
+
| `has_skill` | source → target | A person's skill |
|
|
89
|
+
|
|
90
|
+
**No fitting type? Do not invent one.** A slug that is not a relation definition is refused or lands as a link nobody can read. Use `relates_to` plus a more specific property or document, or — if the relationship recurs and deserves a name — propose a new relation definition (it is a schema change, reviewed like one).
|
|
91
91
|
|
|
92
92
|
## Decision table
|
|
93
93
|
|
|
94
|
-
| Situation | Use
|
|
95
|
-
| ------------------------------------------------------ |
|
|
96
|
-
| Profile has matching `valueType: "entity_id"` property | Way 1 — set the property
|
|
97
|
-
| Linking two already-existing entities | Way 2 — create a relation
|
|
98
|
-
| Custom connection, no matching property | Way 2
|
|
99
|
-
| Unsure whether a property exists | `GET /profiles` first
|
|
100
|
-
| Linking a document to
|
|
101
|
-
| Multi-party link (entity A ↔ entity B ↔ entity C) | Two relations, both Way 2
|
|
94
|
+
| Situation | Use |
|
|
95
|
+
| ------------------------------------------------------ | ------------------------- |
|
|
96
|
+
| Profile has matching `valueType: "entity_id"` property | Way 1 — set the property |
|
|
97
|
+
| Linking two already-existing entities | Way 2 — create a relation |
|
|
98
|
+
| Custom connection, no matching property | Way 2 |
|
|
99
|
+
| Unsure whether a property exists | `GET /profiles` first |
|
|
100
|
+
| Linking a document to the entity it is about | Way 2 — `references` |
|
|
101
|
+
| Multi-party link (entity A ↔ entity B ↔ entity C) | Two relations, both Way 2 |
|
|
102
102
|
|
|
103
103
|
## Reading the graph
|
|
104
104
|
|
|
@@ -122,8 +122,9 @@ GET /api/hub/graph/traverse?entityId={id}&maxDepth=2
|
|
|
122
122
|
|
|
123
123
|
## Common mistakes
|
|
124
124
|
|
|
125
|
-
- **Spinning up a new project instead of linking into an existing one.** A project is a **commitment with gravity**, not a folder for a task, plan, repo, or theme (those are entities). Before `create_project`, search existing projects and file the entity into one via `belongs_to_project` (Way 1 `projectId`, or Way 2 relation).
|
|
125
|
+
- **Spinning up a new project instead of linking into an existing one.** A project is a **commitment with gravity**, not a folder for a task, plan, repo, or theme (those are entities). Before `create_project`, search existing projects and file the entity into one via `belongs_to_project` (Way 1 `projectId`, or Way 2 relation). A near-duplicate project name is filed for review with the existing project shown to the person, and an agent-created project also requires **≥5 existing entities** as evidence.
|
|
126
126
|
- **Creating an orphan, then forgetting to link it.** Every `POST /entities` should include properties that link, OR be immediately followed by a `POST /relations`. Never close the operation with a disconnected node.
|
|
127
127
|
- **Double-linking.** If you set `properties.projectId` AND also `POST /relations` with type `belongs_to_project`, the auto-sync already did it. Don't duplicate.
|
|
128
|
-
- **Using `
|
|
128
|
+
- **Using `relates_to` when a specific type fits.** `relates_to` is the fallback. `created_by`, `depends_on`, `references` carry more meaning to both the user and downstream views.
|
|
129
|
+
- **Inventing a relation type.** `child_of`, `belongs_to`, `authored_by`, `part_of`, `works_with` are NOT relation types here — use `parent_of` (from the parent), `belongs_to_project`, `created_by`, `parent_of` / `relates_to`, `knows`. Check `relationTypes` first.
|
|
129
130
|
- **Inverting direction.** Source is "the thing doing the action or owning the relationship." `task depends_on task` means the source is blocked by the target. Check twice.
|