@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,679 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone (non-workspace) package files — view / cell / skill / workflow.
|
|
3
|
+
* ================================================================
|
|
4
|
+
* `market-authoring.ts`'s scaffold/publish loop is WorkspaceYaml-shaped (a
|
|
5
|
+
* `meta` + `workspace` envelope validated by `validateTemplate`). A lone view,
|
|
6
|
+
* cell, or skill has no such envelope — it IS its content. This file is the
|
|
7
|
+
* PURE half (no network, no `process.exit`) for that shape: parse a standalone
|
|
8
|
+
* package file, run the minimal structural check the CP's own
|
|
9
|
+
* `packageDefinitionSchema` needs (see synap-control-plane-api/src/routes/
|
|
10
|
+
* packages.ts), and hand back a definition `publishPackage` can post.
|
|
11
|
+
*
|
|
12
|
+
* File shape (explicit — no `_meta`/`meta` ambiguity, unlike the workspace
|
|
13
|
+
* envelope):
|
|
14
|
+
* {
|
|
15
|
+
* "category": "cell" | "view",
|
|
16
|
+
* "slug": "my-cell",
|
|
17
|
+
* "displayName": "My Cell",
|
|
18
|
+
* "description": "...", // optional
|
|
19
|
+
* "tags": ["..."], // optional
|
|
20
|
+
* "definition": { "cells": [...] } | { "views": [...] }
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* A `cells[]` entry may carry `codeFile` (a path to the cell's ESM entry
|
|
24
|
+
* source, resolved relative to the package file) INSTEAD of an inline `code`
|
|
25
|
+
* string — the indirection an author needs to publish from a real source file
|
|
26
|
+
* rather than hand-pasting a minified bundle into JSON. `codeFile` is CLI-only:
|
|
27
|
+
* the CP's `packageDefinitionSchema.cells[]` has no such slot (only `code`,
|
|
28
|
+
* required), so `resolveCellCodeFiles` bundles it (via `cell.ts`'s
|
|
29
|
+
* `buildCellFromSource` — the SAME esbuild path `cell build` uses) and inlines
|
|
30
|
+
* the result into `code` before the definition ever reaches `publishPackage`.
|
|
31
|
+
*
|
|
32
|
+
* ✅ RESOLVED 2026-09-04 — this block used to claim that
|
|
33
|
+
* `packageDefinitionSchema` requires `definition.profiles` to be non-empty
|
|
34
|
+
* UNCONDITIONALLY, so a profile-less view/cell/skill package would 400 against
|
|
35
|
+
* `POST /api/packages`. That is NO LONGER TRUE and had become a load-bearing
|
|
36
|
+
* lie: the rule moved to a category-gated `superRefine` on the OUTER schema
|
|
37
|
+
* (`synap-control-plane-api/src/routes/packages.ts:859-872` — only that schema
|
|
38
|
+
* can see the sibling `category`), and it now fires for `category === "workspace"`
|
|
39
|
+
* ONLY. Every other kind may publish with `profiles: []`.
|
|
40
|
+
*
|
|
41
|
+
* Left as a tombstone rather than deleted because the stale claim outlived its
|
|
42
|
+
* fix and was still being cited as fact months later.
|
|
43
|
+
*
|
|
44
|
+
* ✅ RESOLVED 2026-10-06 — "skill" NOW HAS A PAYLOAD SLOT. This block used to
|
|
45
|
+
* warn that `packageDefinitionSchema` carried no top-level slot for a standalone
|
|
46
|
+
* skill, so one had nowhere to land and `validateStandalonePackage` reported it
|
|
47
|
+
* rather than inventing a shape. Both halves are now false: the CP grew a
|
|
48
|
+
* SINGULAR `skill:` slot (`synap-control-plane-api/src/routes/packages.ts`,
|
|
49
|
+
* beside `capability:`) whose field names mirror the pod's own create door, and
|
|
50
|
+
* the pod grew an applier + resolver entry so a `skill` dependency installs
|
|
51
|
+
* itself. Note the shape is `skill`, NOT `skills` — the plural is the workspace
|
|
52
|
+
* template's DECLARED-skills array, an unrelated lane that already existed.
|
|
53
|
+
*
|
|
54
|
+
* Left as a tombstone, like the block above: the stale claim was load-bearing
|
|
55
|
+
* (it is why `skill` was refused at scaffold) and would otherwise be cited again.
|
|
56
|
+
*/
|
|
57
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
58
|
+
import { resolve as resolvePath } from "node:path";
|
|
59
|
+
import { parse as parseYaml } from "yaml";
|
|
60
|
+
import { validateFlowDefinition } from "@synap-core/workspace-templates";
|
|
61
|
+
import { CONTENT_KINDS, parseContentKind, buildCellFromSource, } from "../commands/cell.js";
|
|
62
|
+
/**
|
|
63
|
+
* The non-workspace package types this file knows how to shape. Mirrors the
|
|
64
|
+
* live subset of the CP's `PACKAGE_TYPES` SSOT (db/schema/packages.ts) —
|
|
65
|
+
* "workspace" has its own authoring loop (`template-file.ts`).
|
|
66
|
+
*
|
|
67
|
+
* `workflow` (the CP's rename of the old "automation" + "playbook") IS a lone
|
|
68
|
+
* file: its payload is `definition.automations[]` — a triggered/sequenced run,
|
|
69
|
+
* exactly the shape `POST /api/packages`' `packageDefinitionSchema.automations`
|
|
70
|
+
* validates (`routes/packages.ts`). The `category` posted upstream must be a
|
|
71
|
+
* live `PACKAGE_TYPES` value, so we use "workflow" verbatim (never the retired
|
|
72
|
+
* "automation" alias, which the publish enum rejects).
|
|
73
|
+
*
|
|
74
|
+
* `capability` used to be excluded here with the comment "authored/seeded
|
|
75
|
+
* elsewhere, not as a lone file here". That was a statement about how WE happen
|
|
76
|
+
* to author them, not about what the CP accepts — and it left the most complex
|
|
77
|
+
* kind we have with no CLI door at all. The server half already exists, all of
|
|
78
|
+
* it, and NO CP migration is involved:
|
|
79
|
+
* • `capability` is a live `PACKAGE_TYPES` value (db/schema/packages.ts);
|
|
80
|
+
* • `packageDefinitionSchema` declares `capability: z.record(z.unknown())`
|
|
81
|
+
* (routes/packages.ts:824-832);
|
|
82
|
+
* • `publish-package-core.ts` stores a non-workspace definition AS-IS and
|
|
83
|
+
* hashes it into `definition.capability.contentHash`;
|
|
84
|
+
* • `GET /api/marketplace/capabilities` unwraps `definition.capability` into
|
|
85
|
+
* the card the pod's catalog sync caches (marketplace-apps.ts:398-410);
|
|
86
|
+
* • `market.install` resolves `kind: "capability"` BY KEY, cache row or not
|
|
87
|
+
* (marketplace-install.ts:263).
|
|
88
|
+
* So the whole loop — scaffold → validate → publish → install — closes.
|
|
89
|
+
*
|
|
90
|
+
* `skill` is a full member as of 2026-10-06: it has a CP payload slot, a
|
|
91
|
+
* scaffold arm, a validator arm, and a pod applier, so it scaffolds, validates,
|
|
92
|
+
* publishes and installs like the rest. (The old note here claimed it needed a
|
|
93
|
+
* CHECK-constraint migration "mirrored across ~24 files in 6 repos" — that was
|
|
94
|
+
* never true for `skill`: the category was ALREADY in `PACKAGE_TYPES` and in
|
|
95
|
+
* migration 0049's CHECK. What was missing was only the payload slot.)
|
|
96
|
+
*/
|
|
97
|
+
export const STANDALONE_KINDS = [
|
|
98
|
+
"view",
|
|
99
|
+
"cell",
|
|
100
|
+
"skill",
|
|
101
|
+
"workflow",
|
|
102
|
+
"capability",
|
|
103
|
+
];
|
|
104
|
+
/**
|
|
105
|
+
* True when a parsed JSON/YAML top-level object declares a standalone
|
|
106
|
+
* (non-workspace) `category`. A `WorkspaceYaml` file never carries a
|
|
107
|
+
* top-level `category` key (it uses `meta`/`workspace`), so this is a safe,
|
|
108
|
+
* non-overlapping discriminator `marketPublish` can branch on.
|
|
109
|
+
*/
|
|
110
|
+
export function isStandalonePackageFile(parsed) {
|
|
111
|
+
return (!!parsed &&
|
|
112
|
+
typeof parsed === "object" &&
|
|
113
|
+
typeof parsed.category === "string" &&
|
|
114
|
+
STANDALONE_KINDS.includes(parsed.category));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Read + parse a standalone package file (JSON or YAML — the same
|
|
118
|
+
* JSON-superset parser `parseTemplateFile` uses). Throws a friendly Error,
|
|
119
|
+
* never `process.exit`.
|
|
120
|
+
*/
|
|
121
|
+
export function parseStandalonePackageFile(filePath) {
|
|
122
|
+
let raw;
|
|
123
|
+
try {
|
|
124
|
+
raw = readFileSync(filePath, "utf-8");
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
throw new Error(`Cannot read package file: ${filePath}`);
|
|
128
|
+
}
|
|
129
|
+
let parsed;
|
|
130
|
+
try {
|
|
131
|
+
parsed = parseYaml(raw);
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
throw new Error(`Package file is not valid YAML/JSON: ${e.message}`);
|
|
135
|
+
}
|
|
136
|
+
if (!isStandalonePackageFile(parsed)) {
|
|
137
|
+
throw new Error(`Not a standalone package file (expected a top-level "category" of ${STANDALONE_KINDS.join("/")}).`);
|
|
138
|
+
}
|
|
139
|
+
const p = parsed;
|
|
140
|
+
if (!p.slug || typeof p.slug !== "string")
|
|
141
|
+
throw new Error(`Package file has no "slug".`);
|
|
142
|
+
if (!p.displayName || typeof p.displayName !== "string")
|
|
143
|
+
throw new Error(`Package file has no "displayName".`);
|
|
144
|
+
if (!p.definition || typeof p.definition !== "object")
|
|
145
|
+
throw new Error(`Package file has no "definition" object.`);
|
|
146
|
+
return {
|
|
147
|
+
category: p.category,
|
|
148
|
+
slug: p.slug,
|
|
149
|
+
displayName: p.displayName,
|
|
150
|
+
description: typeof p.description === "string" ? p.description : undefined,
|
|
151
|
+
tags: Array.isArray(p.tags) ? p.tags : undefined,
|
|
152
|
+
definition: p.definition,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Minimal structural check BEFORE any network call — mirrors the fast
|
|
157
|
+
* author-feedback `marketValidate` gives workspace templates, scaled to what
|
|
158
|
+
* a standalone package actually needs: the `definition` must carry the array
|
|
159
|
+
* the CP's `packageDefinitionSchema` reads for that category. Returns an
|
|
160
|
+
* empty array when clean.
|
|
161
|
+
*/
|
|
162
|
+
export function validateStandalonePackage(pkg, opts = {}) {
|
|
163
|
+
const errors = [];
|
|
164
|
+
if (pkg.category === "cell") {
|
|
165
|
+
const cells = pkg.definition.cells;
|
|
166
|
+
if (!Array.isArray(cells) || cells.length === 0) {
|
|
167
|
+
errors.push(`category "cell" requires a non-empty definition.cells[] array.`);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
cells.forEach((raw, i) => {
|
|
171
|
+
const c = (raw && typeof raw === "object" ? raw : {});
|
|
172
|
+
const label = typeof c.key === "string" && c.key.trim()
|
|
173
|
+
? `cells[${i}] ("${c.key}")`
|
|
174
|
+
: `cells[${i}]`;
|
|
175
|
+
const hasCode = typeof c.code === "string" && c.code.trim().length > 0;
|
|
176
|
+
const hasCodeFile = typeof c.codeFile === "string" && c.codeFile.trim().length > 0;
|
|
177
|
+
if (!hasCode && !hasCodeFile) {
|
|
178
|
+
errors.push(`${label}: needs "code" (inline ESM source) or "codeFile" (a path to a source/bundle file, resolved and inlined at publish time).`);
|
|
179
|
+
}
|
|
180
|
+
if (hasCodeFile && opts.baseDir) {
|
|
181
|
+
const abs = resolvePath(opts.baseDir, c.codeFile);
|
|
182
|
+
if (!existsSync(abs)) {
|
|
183
|
+
errors.push(`${label}: codeFile "${c.codeFile}" not found (resolved to ${abs}).`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Both of these are `.optional()` on the CP's `packageDefinitionSchema`
|
|
187
|
+
// (routes/packages.ts), so an omitted or mistyped value is stripped
|
|
188
|
+
// SILENTLY — not rejected — and the cell arrives at the pod as the
|
|
189
|
+
// inert "widget" default with no view-renderer affinity: placeable,
|
|
190
|
+
// permanently unpickable, and nothing downstream ever reports it (see
|
|
191
|
+
// `cell.ts`'s SELECTABILITY note, and `kind-package-scaffold-usable
|
|
192
|
+
// .test.ts`, which is exactly why the scaffold always sets both).
|
|
193
|
+
if (typeof c.contentKind !== "string" || !parseContentKind(c.contentKind)) {
|
|
194
|
+
errors.push(`${label}: "contentKind" must be one of: ${CONTENT_KINDS.join(", ")} (got ${JSON.stringify(c.contentKind)}).`);
|
|
195
|
+
}
|
|
196
|
+
// `viewTypes` is OPTIONAL, and deliberately so: it is view-renderer
|
|
197
|
+
// affinity, a DIFFERENT axis from `contentKind`'s renderer slot. An
|
|
198
|
+
// `entity-detail` cell is a profile renderer and has no business
|
|
199
|
+
// declaring view types — the scaffold says so in its own comment
|
|
200
|
+
// ("remove if this cell is not a view renderer").
|
|
201
|
+
//
|
|
202
|
+
// ── VALIDATOR vs DOOR: a DELIBERATE asymmetry, do not "fix" it ──
|
|
203
|
+
// This validator requires `contentKind` UNCONDITIONALLY. The install
|
|
204
|
+
// door does NOT: `resolveCellContentKind` infers "collection" from a
|
|
205
|
+
// non-empty `viewTypes` when `contentKind` is absent.
|
|
206
|
+
//
|
|
207
|
+
// That is strict-in / permissive-out, on purpose:
|
|
208
|
+
// • AUTHORING (here) is the last cheap moment to catch a mistake. An
|
|
209
|
+
// omitted `contentKind` silently defaults the stored column to
|
|
210
|
+
// "widget" — placeable, but never offered in the renderer slot the
|
|
211
|
+
// cell was built for. Failing at `market validate` costs the author
|
|
212
|
+
// seconds; discovering it after publish costs a republish.
|
|
213
|
+
// • INSTALL (the door) must keep already-published packages working,
|
|
214
|
+
// including ones authored before this rule existed. Rejecting them
|
|
215
|
+
// there would break installs for cells nobody can now re-publish.
|
|
216
|
+
//
|
|
217
|
+
// So a package can be door-valid and validator-invalid, and that is the
|
|
218
|
+
// correct direction. Loosening this check to "match the door" would
|
|
219
|
+
// reintroduce the silent-widget trap for every new cell.
|
|
220
|
+
// Requiring it here would be worse than not checking: an author would
|
|
221
|
+
// add a meaningless `["list"]` to get past the validator, and that
|
|
222
|
+
// MANUFACTURES a false affinity — the cell then gets offered as a list
|
|
223
|
+
// renderer it was never built to be. That is the unpickability bug
|
|
224
|
+
// inverted, so we validate SHAPE when present and require presence only
|
|
225
|
+
// where absence is genuinely fatal.
|
|
226
|
+
if (c.viewTypes !== undefined) {
|
|
227
|
+
if (!Array.isArray(c.viewTypes) ||
|
|
228
|
+
c.viewTypes.length === 0 ||
|
|
229
|
+
!c.viewTypes.every((v) => typeof v === "string" && v.trim().length > 0)) {
|
|
230
|
+
errors.push(`${label}: "viewTypes", when present, must be a non-empty array of view-type strings (e.g. ["list","table"]). Omit it entirely if this cell is not a view renderer.`);
|
|
231
|
+
}
|
|
232
|
+
else if (typeof c.contentKind === "string" &&
|
|
233
|
+
parseContentKind(c.contentKind) &&
|
|
234
|
+
c.contentKind !== "collection") {
|
|
235
|
+
// Match the door: `defineCell` rejects this same pair. `contentKind`
|
|
236
|
+
// is the renderer SLOT, `viewTypes` is view-renderer AFFINITY — a
|
|
237
|
+
// DIFFERENT axis, and a non-collection slot can never be selected by
|
|
238
|
+
// view-type affinity, so declaring both is a contradiction the
|
|
239
|
+
// author must resolve, not one this validator should coerce away
|
|
240
|
+
// (silently forcing "collection" would hand them a cell they never
|
|
241
|
+
// chose to be a view renderer). `contentKind` ABSENT is NOT this case
|
|
242
|
+
// — that is inference from silence (the door's own
|
|
243
|
+
// `resolveCellContentKind` infers "collection"), not a
|
|
244
|
+
// contradiction, and is how older cell packages install correctly.
|
|
245
|
+
errors.push(`${label}: "viewTypes" is set (${JSON.stringify(c.viewTypes)}) but "contentKind" is "${c.contentKind}", not "collection" — view-type affinity only applies to a collection renderer. Drop "viewTypes", or set "contentKind": "collection".`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else if (c.contentKind === "collection") {
|
|
249
|
+
// The one case where absence IS fatal: a `collection` cell exists to
|
|
250
|
+
// render a view, so with no affinity the render chokepoint can never
|
|
251
|
+
// select it — installed and permanently unpickable.
|
|
252
|
+
errors.push(`${label}: a "collection" cell must declare "viewTypes" (e.g. ["list","table"]) — without an affinity it can never be selected as a view renderer.`);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else if (pkg.category === "view") {
|
|
258
|
+
const views = pkg.definition.views;
|
|
259
|
+
if (!Array.isArray(views) || views.length === 0) {
|
|
260
|
+
errors.push(`category "view" requires a non-empty definition.views[] array.`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else if (pkg.category === "workflow") {
|
|
264
|
+
const automations = pkg.definition.automations;
|
|
265
|
+
if (!Array.isArray(automations) || automations.length === 0) {
|
|
266
|
+
errors.push(`category "workflow" requires a non-empty definition.automations[] array.`);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
errors.push(...validateWorkflowFlows(automations));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else if (pkg.category === "capability") {
|
|
273
|
+
// `packageDefinitionSchema.capability` is `z.record(z.unknown())` — the CP
|
|
274
|
+
// catalogs a capability, it never validates or executes the inner skill
|
|
275
|
+
// code. So say plainly what this check IS: presence and the two fields the
|
|
276
|
+
// catalog's own reader dereferences, not correctness. Claiming more than
|
|
277
|
+
// the check performs is the failure this file already carries a tombstone
|
|
278
|
+
// for.
|
|
279
|
+
// The envelope is REQUIRED here (a publish must fill the slot the CP serves),
|
|
280
|
+
// so this reads `definition.capability` itself — never `unwrapPackage`,
|
|
281
|
+
// which lets a legacy flat definition through.
|
|
282
|
+
const cap = pkg.definition.capability;
|
|
283
|
+
if (!cap || typeof cap !== "object" || Array.isArray(cap)) {
|
|
284
|
+
errors.push(`category "capability" requires a definition.capability object (the CapabilityDefinition itself — key/name/tools/skills). The CP unwraps exactly this key at GET /api/marketplace/capabilities.`);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
const c = cap;
|
|
288
|
+
// `tools` and `skills` are non-optional on `CapabilityDefinition`
|
|
289
|
+
// (synap-backend/packages/playbooks/src/index.ts:839). An empty `tools`
|
|
290
|
+
// is legitimate (research-methods.capability.json ships `tools: []`);
|
|
291
|
+
// an empty `skills` is a capability that grants nothing — installed,
|
|
292
|
+
// no error, and it does nothing. That is the shape this check exists
|
|
293
|
+
// to catch, and it is the same "installed but inert" class as an
|
|
294
|
+
// automation published with no `status`.
|
|
295
|
+
if (typeof c.key !== "string" || !c.key.trim())
|
|
296
|
+
errors.push(`definition.capability.key must be a non-empty string.`);
|
|
297
|
+
if (typeof c.name !== "string" || !c.name.trim())
|
|
298
|
+
errors.push(`definition.capability.name must be a non-empty string.`);
|
|
299
|
+
if (!Array.isArray(c.tools))
|
|
300
|
+
errors.push(`definition.capability.tools must be an array (use [] for a pure know-how capability).`);
|
|
301
|
+
if (!Array.isArray(c.skills) || c.skills.length === 0)
|
|
302
|
+
errors.push(`definition.capability.skills must be a non-empty array — a capability with no skills installs successfully and grants nothing.`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else if (pkg.category === "skill") {
|
|
306
|
+
// `packageDefinitionSchema.skill` is the standalone-skill slot (SINGULAR —
|
|
307
|
+
// `skills[]`, plural, is a workspace template's DECLARED-skills refs, an
|
|
308
|
+
// unrelated shape three lines away in the same file). What this checks is
|
|
309
|
+
// presence plus the one rule the POD enforces — a skill needs documentation
|
|
310
|
+
// or code — so the loop fails at AUTHORING time instead of at install time
|
|
311
|
+
// (where a bodiless skill is refused by `skillsRouter.create`).
|
|
312
|
+
const raw = pkg.definition.skill; // envelope required — see the capability arm
|
|
313
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
314
|
+
errors.push(`category "skill" requires a definition.skill object — ONE skill ({ slug, name, kind, body | code }).`);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
const s = raw;
|
|
318
|
+
const body = typeof s.body === "string" ? s.body.trim() : "";
|
|
319
|
+
const code = typeof s.code === "string" ? s.code.trim() : "";
|
|
320
|
+
if (!body && !code && s.providerSpec == null) {
|
|
321
|
+
errors.push(`definition.skill needs documentation or code — the pod refuses a skill with neither, so this would publish and then fail to install.`);
|
|
322
|
+
}
|
|
323
|
+
const name = typeof s.name === "string" ? s.name : s.displayName;
|
|
324
|
+
if (typeof name !== "string" || !name.trim())
|
|
325
|
+
errors.push(`definition.skill.name must be a non-empty string.`);
|
|
326
|
+
if (typeof s.slug === "string" && s.slug.startsWith("system/")) {
|
|
327
|
+
errors.push(`definition.skill.slug cannot start with "system/" — that namespace is reserved for seeded skills.`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return errors;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Inline every cell's `codeFile` into `code` — the field the CP schema
|
|
335
|
+
* actually validates (`cells[].code: z.string().min(1)`, no `codeFile` slot).
|
|
336
|
+
* A no-op for anything but a `cell` package, and for a cell entry that has no
|
|
337
|
+
* `codeFile` (plain inline `code` is untouched).
|
|
338
|
+
*
|
|
339
|
+
* `codeFile` is bundled through the SAME esbuild path `cell build` uses
|
|
340
|
+
* (`buildCellFromSource`), so publishing from source needs no separate manual
|
|
341
|
+
* build step. `bundleDeps` defaults to `true` here — see `market-authoring.ts`
|
|
342
|
+
* `marketPublishStandalone` for why the DEFAULT flips only on this door.
|
|
343
|
+
* Author-declared `deps` on the cell entry win over the derived map, mirroring
|
|
344
|
+
* `cell build --deps`'s own override semantics.
|
|
345
|
+
*
|
|
346
|
+
* A cell declaring `rendererType: "mcp-app"` is built `--self-contained`
|
|
347
|
+
* instead, whatever `bundleDeps` says: its `code` is the complete HTML document
|
|
348
|
+
* a foreign MCP-Apps host loads verbatim (React, CSS and brand fonts inlined),
|
|
349
|
+
* and its `deps` is `{}` — that host's CSP admits no esm.sh, so an author
|
|
350
|
+
* `deps` on such a cell is refused rather than shipped inert.
|
|
351
|
+
*/
|
|
352
|
+
export async function resolveCellCodeFiles(pkg, baseDir, opts = {}) {
|
|
353
|
+
if (pkg.category !== "cell" || !Array.isArray(pkg.definition.cells)) {
|
|
354
|
+
return { definition: pkg.definition, errors: [] };
|
|
355
|
+
}
|
|
356
|
+
const bundleDeps = opts.bundleDeps ?? true;
|
|
357
|
+
const errors = [];
|
|
358
|
+
const resolved = [];
|
|
359
|
+
for (let i = 0; i < pkg.definition.cells.length; i++) {
|
|
360
|
+
const raw = pkg.definition.cells[i];
|
|
361
|
+
const c = (raw && typeof raw === "object" ? raw : {});
|
|
362
|
+
if (typeof c.codeFile !== "string" || !c.codeFile.trim()) {
|
|
363
|
+
resolved.push(raw);
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
const label = typeof c.key === "string" && c.key.trim()
|
|
367
|
+
? `cells[${i}] ("${c.key}")`
|
|
368
|
+
: `cells[${i}]`;
|
|
369
|
+
const entry = resolvePath(baseDir, c.codeFile);
|
|
370
|
+
if (!existsSync(entry)) {
|
|
371
|
+
errors.push(`${label}: codeFile "${c.codeFile}" not found (resolved to ${entry}).`);
|
|
372
|
+
resolved.push(raw);
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
const selfContained = c.rendererType === "mcp-app";
|
|
376
|
+
if (selfContained &&
|
|
377
|
+
c.deps &&
|
|
378
|
+
typeof c.deps === "object" &&
|
|
379
|
+
Object.keys(c.deps).length > 0) {
|
|
380
|
+
errors.push(`${label}: an "mcp-app" cell is one self-contained HTML document — remove "deps" (every import is bundled in; nothing resolves via esm.sh).`);
|
|
381
|
+
resolved.push(raw);
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
try {
|
|
385
|
+
const built = await buildCellFromSource(entry, selfContained ? { selfContained: true } : { bundleDeps });
|
|
386
|
+
const { codeFile: _codeFile, ...rest } = c;
|
|
387
|
+
resolved.push({
|
|
388
|
+
...rest,
|
|
389
|
+
code: built.code,
|
|
390
|
+
deps: { ...built.deps, ...(c.deps ?? {}) },
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
catch (e) {
|
|
394
|
+
errors.push(`${label}: failed to bundle codeFile "${c.codeFile}" — ${e.message}`);
|
|
395
|
+
resolved.push(raw);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return { definition: { ...pkg.definition, cells: resolved }, errors };
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Run the SAME node-contract validator the workspace lane runs, on a standalone
|
|
402
|
+
* workflow package's flows.
|
|
403
|
+
*
|
|
404
|
+
* `validateStandalonePackage` used to check only that `automations[]` was
|
|
405
|
+
* non-empty. A semantically broken flow — an unknown `node.type`, an edge to a
|
|
406
|
+
* nonexistent node, a cycle, a `capability` node with no `verbId`, a typo'd
|
|
407
|
+
* `channelType` — therefore validated GREEN and died at runtime, silently: the
|
|
408
|
+
* automation installs and simply never fires. `validateTemplate` has closed
|
|
409
|
+
* exactly this gap for WORKSPACE templates since
|
|
410
|
+
* `@synap-core/workspace-templates` validate.ts:655-669; the standalone lane
|
|
411
|
+
* never got the same treatment, and `market scaffold --kind workflow` has now
|
|
412
|
+
* made standalone workflows a first-class authoring path. This is that wiring —
|
|
413
|
+
* the validator already exists, it is pure and synchronous, and it is exported
|
|
414
|
+
* from the package the CLI already depends on.
|
|
415
|
+
*
|
|
416
|
+
* `flow ?? flowDefinition` mirrors validate.ts's own read: the WorkspaceYaml
|
|
417
|
+
* lane names it `flow`, the CP publish schema and the scaffold name it
|
|
418
|
+
* `flowDefinition`. Catalog-existence checks are resolver-gated and skipped —
|
|
419
|
+
* there is no catalog at author time — so only the structural and per-node
|
|
420
|
+
* contract checks run, which is exactly what the workspace lane does.
|
|
421
|
+
*
|
|
422
|
+
* An automation with NO flow at all is left alone here: `validateFlowDefinition`
|
|
423
|
+
* would reject `undefined` as "not an object", but a flowless automation is a
|
|
424
|
+
* different (and legitimate) shape, not a broken flow.
|
|
425
|
+
*/
|
|
426
|
+
function validateWorkflowFlows(automations) {
|
|
427
|
+
const errors = [];
|
|
428
|
+
automations.forEach((raw, i) => {
|
|
429
|
+
const a = (raw ?? {});
|
|
430
|
+
const label = typeof a.name === "string" && a.name.trim()
|
|
431
|
+
? `automation "${a.name}"`
|
|
432
|
+
: `automations[${i}]`;
|
|
433
|
+
const flow = a.flow ?? a.flowDefinition;
|
|
434
|
+
if (flow == null)
|
|
435
|
+
return;
|
|
436
|
+
for (const e of validateFlowDefinition(flow).errors) {
|
|
437
|
+
const where = e.nodeId
|
|
438
|
+
? `${label}.flow.node "${e.nodeId}"`
|
|
439
|
+
: e.edgeId
|
|
440
|
+
? `${label}.flow.edge "${e.edgeId}"`
|
|
441
|
+
: `${label}.flow`;
|
|
442
|
+
errors.push(`${where}: ${e.message}`);
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
return errors;
|
|
446
|
+
}
|
|
447
|
+
// ─── scaffold ────────────────────────────────────────────────────────────────
|
|
448
|
+
/**
|
|
449
|
+
* The kinds `market scaffold --kind <k>` can write. This is the SSOT for that
|
|
450
|
+
* flag's accepted values AND for its help string (`src/index.ts`) — the two had
|
|
451
|
+
* drifted: the help advertised `skill` (which scaffold refuses) and hid
|
|
452
|
+
* `workflow` (which `validateStandalonePackage` has always accepted), so the
|
|
453
|
+
* documented loop offered a dead option and concealed a working one.
|
|
454
|
+
*
|
|
455
|
+
* `skill` joined this list when the CP grew its standalone `skill` payload slot
|
|
456
|
+
* and the pod grew an applier for it — before that, scaffold refused it because
|
|
457
|
+
* there was no publishable shape to write. The barrier is gone; the refusal
|
|
458
|
+
* went with it. (`SCAFFOLDABLE_KINDS` is still what the help string is built
|
|
459
|
+
* from, so the two cannot drift again — see `scaffold-kind-help-parity.test.ts`.)
|
|
460
|
+
*/
|
|
461
|
+
export const SCAFFOLDABLE_KINDS = [
|
|
462
|
+
"cell",
|
|
463
|
+
"view",
|
|
464
|
+
"workflow",
|
|
465
|
+
"capability",
|
|
466
|
+
"skill",
|
|
467
|
+
];
|
|
468
|
+
/**
|
|
469
|
+
* Build the minimal standalone-package JSON `market scaffold --kind
|
|
470
|
+
* cell|view|workflow|capability` writes — the smallest file that passes
|
|
471
|
+
* {@link validateStandalonePackage}, for the author to edit in place.
|
|
472
|
+
*
|
|
473
|
+
* The bar is USABLE, not merely valid. Every arm below has at least one field
|
|
474
|
+
* whose OMISSION is not neutral — the cell's `contentKind`/`viewTypes`, the
|
|
475
|
+
* workflow's `status`/`triggerType`/two-node flow — because the appliers
|
|
476
|
+
* default a missing value to something inert and report success. A scaffold
|
|
477
|
+
* that writes a file which installs and then does nothing is the same defect
|
|
478
|
+
* as a validator that passes a flow which never fires.
|
|
479
|
+
*/
|
|
480
|
+
export function scaffoldStandalonePackageJson(kind, slug) {
|
|
481
|
+
const displayName = slug
|
|
482
|
+
.split(/[-_]/)
|
|
483
|
+
.filter(Boolean)
|
|
484
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
485
|
+
.join(" ") || slug;
|
|
486
|
+
const definition = scaffoldDefinition(kind, slug, displayName);
|
|
487
|
+
return JSON.stringify({
|
|
488
|
+
category: kind,
|
|
489
|
+
slug,
|
|
490
|
+
displayName,
|
|
491
|
+
// No kind noun here on purpose. `cell` and `workflow` are MACHINE tokens
|
|
492
|
+
// the product's vocabulary renders as "card" and "automation"
|
|
493
|
+
// (`KIND_HEADINGS`, commands/market.ts, pinned by
|
|
494
|
+
// test/kind-heading-vocabulary-parity.test.ts) — echoing the raw token
|
|
495
|
+
// into an author-visible, publishable description would fork that table.
|
|
496
|
+
description: `What ${displayName} does — replace this before publishing.`,
|
|
497
|
+
definition,
|
|
498
|
+
}, null, 2) + "\n";
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* The payload for one scaffolded kind.
|
|
502
|
+
*
|
|
503
|
+
* A `switch` rather than the nested ternary chain this used to be: at four
|
|
504
|
+
* arms and ~130 lines the chain had already drifted — its last arm was
|
|
505
|
+
* indented as if it belonged to the arm above it — and no reader could tell
|
|
506
|
+
* which comment documented which kind. The switch also makes exhaustiveness
|
|
507
|
+
* over {@link ScaffoldableKind} checkable, which a ternary chain cannot give:
|
|
508
|
+
* adding a kind to `SCAFFOLDABLE_KINDS` without adding an arm here is now a
|
|
509
|
+
* typecheck failure at the `never` assignment below, not a silent fallthrough
|
|
510
|
+
* into the workflow shape.
|
|
511
|
+
*/
|
|
512
|
+
function scaffoldDefinition(kind, slug, displayName) {
|
|
513
|
+
switch (kind) {
|
|
514
|
+
case "cell":
|
|
515
|
+
return {
|
|
516
|
+
cells: [
|
|
517
|
+
{
|
|
518
|
+
key: slug,
|
|
519
|
+
name: displayName,
|
|
520
|
+
code: "export default function Cell() { return null; }",
|
|
521
|
+
// WHAT this cell renders + which profile assignment it fills.
|
|
522
|
+
// SSOT: `CONTENT_KINDS` in
|
|
523
|
+
// synap-backend/packages/database/src/schema/widget-definitions.ts
|
|
524
|
+
// — the five legal values are "entity-detail", "entity-card",
|
|
525
|
+
// "entity-profile", "collection", "widget". Omitting this field
|
|
526
|
+
// is NOT neutral: the CP schema strips an undeclared
|
|
527
|
+
// `contentKind`, so the cell installs silently as the
|
|
528
|
+
// content-agnostic "widget" default and can never be picked as
|
|
529
|
+
// a renderer for the kind it was actually built for.
|
|
530
|
+
contentKind: "widget",
|
|
531
|
+
// View-type affinity when this cell acts as a view renderer
|
|
532
|
+
// (e.g. ["list", "table"]). Without this slot the cell has no
|
|
533
|
+
// affinity and the render chokepoint can never select it —
|
|
534
|
+
// installed but permanently unpickable. Edit to match the view
|
|
535
|
+
// type(s) this cell renders, or remove if this cell is not a
|
|
536
|
+
// view renderer.
|
|
537
|
+
viewTypes: ["list"],
|
|
538
|
+
},
|
|
539
|
+
],
|
|
540
|
+
};
|
|
541
|
+
case "view":
|
|
542
|
+
return {
|
|
543
|
+
views: [
|
|
544
|
+
{
|
|
545
|
+
slug,
|
|
546
|
+
displayName,
|
|
547
|
+
type: "list",
|
|
548
|
+
},
|
|
549
|
+
],
|
|
550
|
+
};
|
|
551
|
+
case "capability":
|
|
552
|
+
return {
|
|
553
|
+
capability: {
|
|
554
|
+
key: slug,
|
|
555
|
+
name: displayName,
|
|
556
|
+
description: `What ${displayName} does — replace this before publishing.`,
|
|
557
|
+
// No params and no vault: the smallest capability that is
|
|
558
|
+
// immediately usable is pure know-how, needing no credential
|
|
559
|
+
// and no connection step. Add `params`/`vault` when a tool
|
|
560
|
+
// actually needs a secret — the applier stores it
|
|
561
|
+
// server-encrypted and remaps the ref at install.
|
|
562
|
+
params: [],
|
|
563
|
+
vault: [],
|
|
564
|
+
// `tools` and `skills` are REQUIRED on `CapabilityDefinition`
|
|
565
|
+
// (synap-backend/packages/playbooks/src/index.ts:845-846).
|
|
566
|
+
// `tools: []` is legitimate and shipped in production —
|
|
567
|
+
// research-methods.capability.json is exactly this shape.
|
|
568
|
+
tools: [],
|
|
569
|
+
skills: [
|
|
570
|
+
{
|
|
571
|
+
name: `${slug.replace(/-/g, "_")}_method`,
|
|
572
|
+
// `instruction` = a prompt/doc skill injected into the
|
|
573
|
+
// agent's turn. No sandboxed code, no connector call, so
|
|
574
|
+
// it works on a fresh pod with no credentials — unlike
|
|
575
|
+
// `code`, which needs a tool to call.
|
|
576
|
+
kind: "instruction",
|
|
577
|
+
scope: "pod",
|
|
578
|
+
description: `When and how an agent should use ${displayName}.`,
|
|
579
|
+
// A real instruction, not a placeholder: an empty `code`
|
|
580
|
+
// installs a skill that teaches the agent nothing, which
|
|
581
|
+
// is this scaffold's version of an inert automation.
|
|
582
|
+
code: `# ${displayName}\n\nDescribe HOW the agent should do this — the judgement, not the mechanics.\n\n## When to use\n- Replace with the situations that should trigger this skill.\n\n## How to do it\n1. Replace with the actual method.\n\n## Hard rules\n- Replace with what the agent must never do here.\n`,
|
|
583
|
+
},
|
|
584
|
+
],
|
|
585
|
+
},
|
|
586
|
+
};
|
|
587
|
+
case "workflow":
|
|
588
|
+
return {
|
|
589
|
+
automations: [
|
|
590
|
+
{
|
|
591
|
+
// `slug` (not `key`): both are accepted by the CP's publish
|
|
592
|
+
// schema, which resolves `slug ?? key` — but three flagship
|
|
593
|
+
// templates once 400'd on `automations.0.slug: Required`, so
|
|
594
|
+
// the scaffold writes the field the schema names first.
|
|
595
|
+
slug,
|
|
596
|
+
name: displayName,
|
|
597
|
+
// A `manual` trigger is the only one that is inert until the
|
|
598
|
+
// author asks for it: a scaffolded `cron`/`event` automation
|
|
599
|
+
// would start firing the moment it is installed.
|
|
600
|
+
triggerType: "manual",
|
|
601
|
+
triggerConfig: {},
|
|
602
|
+
// NOT neutral, and the same trap as the cell's `contentKind`:
|
|
603
|
+
// the CP's `automations[]` transform defaults a missing status
|
|
604
|
+
// to "draft", so an automation that omits it installs INERT —
|
|
605
|
+
// no error, no signal, never runs.
|
|
606
|
+
status: "active",
|
|
607
|
+
// A real two-node flow, not `{nodes: [], edges: []}`: an empty
|
|
608
|
+
// flow is structurally valid and does nothing, which is the
|
|
609
|
+
// "installed but does nothing" shape this scaffold exists to
|
|
610
|
+
// avoid. Node types come from `FLOW_NODE_TYPES` and the output
|
|
611
|
+
// type from `FLOW_OUTPUT_TYPES`
|
|
612
|
+
// (@synap-core/workspace-templates `validate-flow.ts`).
|
|
613
|
+
flowDefinition: {
|
|
614
|
+
nodes: [
|
|
615
|
+
{
|
|
616
|
+
id: "trigger",
|
|
617
|
+
type: "trigger",
|
|
618
|
+
position: { x: 0, y: 0 },
|
|
619
|
+
data: {
|
|
620
|
+
label: displayName,
|
|
621
|
+
triggerType: "manual",
|
|
622
|
+
config: {},
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
id: "notify",
|
|
627
|
+
type: "output",
|
|
628
|
+
position: { x: 260, y: 0 },
|
|
629
|
+
data: {
|
|
630
|
+
label: "Notify",
|
|
631
|
+
outputType: "notification",
|
|
632
|
+
// `body` is required by the executor — a notification
|
|
633
|
+
// output with no body is SKIPPED at runtime.
|
|
634
|
+
config: {
|
|
635
|
+
title: displayName,
|
|
636
|
+
body: `${displayName} ran.`,
|
|
637
|
+
},
|
|
638
|
+
},
|
|
639
|
+
},
|
|
640
|
+
],
|
|
641
|
+
edges: [
|
|
642
|
+
{ id: "trigger-notify", source: "trigger", target: "notify" },
|
|
643
|
+
],
|
|
644
|
+
},
|
|
645
|
+
},
|
|
646
|
+
],
|
|
647
|
+
};
|
|
648
|
+
case "skill":
|
|
649
|
+
return {
|
|
650
|
+
skill: {
|
|
651
|
+
// The pod-side `load_skill` ref. Bare — `system/` is reserved for
|
|
652
|
+
// seeded skills and both the CP slot and the pod's create door refuse
|
|
653
|
+
// it. Defaults to the package slug so a scaffolded file links as soon
|
|
654
|
+
// as a space declares it.
|
|
655
|
+
slug,
|
|
656
|
+
name: displayName,
|
|
657
|
+
// `instruction` = a prompt/doc skill the agent reads. No sandboxed
|
|
658
|
+
// code and no connector, so it is usable on a fresh pod with no
|
|
659
|
+
// credentials — the smallest working skill. Use `code` when the skill
|
|
660
|
+
// must actually run something.
|
|
661
|
+
kind: "instruction",
|
|
662
|
+
// Pod-wide: any space may then declare it in its own `skills:` block.
|
|
663
|
+
scope: "pod",
|
|
664
|
+
description: `What ${displayName} teaches — replace this before publishing.`,
|
|
665
|
+
// The body is what the pod REQUIRES (documentation or code); an empty
|
|
666
|
+
// one publishes and then fails to install, which is the shape this
|
|
667
|
+
// scaffold exists to avoid.
|
|
668
|
+
body: `## ${displayName}\n\n` +
|
|
669
|
+
`Describe the process an agent should follow, the rules it must not break, ` +
|
|
670
|
+
`and the DO NOTs — this is the instruction a space applies when it declares this skill.\n`,
|
|
671
|
+
},
|
|
672
|
+
};
|
|
673
|
+
default: {
|
|
674
|
+
const unhandled = kind;
|
|
675
|
+
throw new Error(`scaffoldStandalonePackageJson: no scaffold for kind ${String(unhandled)}`);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
//# sourceMappingURL=kind-package.js.map
|