@synap-core/cli 1.10.0 → 1.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -198
- package/dist/build-info.json +6 -0
- package/dist/commands/agent-run.js +3 -2
- package/dist/commands/agent-run.js.map +1 -1
- package/dist/commands/agents.d.ts +33 -17
- package/dist/commands/agents.js +203 -237
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/app.d.ts +143 -0
- package/dist/commands/app.js +523 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/automate.d.ts +21 -0
- package/dist/commands/automate.js +42 -0
- package/dist/commands/automate.js.map +1 -0
- package/dist/commands/automation-schema.test.d.ts +16 -0
- package/dist/commands/automation-schema.test.js +77 -0
- package/dist/commands/automation-schema.test.js.map +1 -0
- package/dist/commands/automation.d.ts +12 -0
- package/dist/commands/automation.js +80 -35
- package/dist/commands/automation.js.map +1 -1
- package/dist/commands/bridge-setup.d.ts +14 -1
- package/dist/commands/bridge-setup.js +392 -128
- package/dist/commands/bridge-setup.js.map +1 -1
- package/dist/commands/cap-connections.d.ts +4 -4
- package/dist/commands/cap-connections.js +14 -14
- package/dist/commands/cap-connections.js.map +1 -1
- package/dist/commands/capability.d.ts +2 -0
- package/dist/commands/capability.js +297 -176
- package/dist/commands/capability.js.map +1 -1
- package/dist/commands/catalog.d.ts +275 -0
- package/dist/commands/catalog.js +481 -0
- package/dist/commands/catalog.js.map +1 -0
- package/dist/commands/cell.d.ts +155 -8
- package/dist/commands/cell.js +416 -40
- package/dist/commands/cell.js.map +1 -1
- package/dist/commands/centrality.js +3 -14
- package/dist/commands/centrality.js.map +1 -1
- package/dist/commands/connect.d.ts +38 -13
- package/dist/commands/connect.js +68 -167
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connections.d.ts +3 -2
- package/dist/commands/connections.js +95 -25
- package/dist/commands/connections.js.map +1 -1
- package/dist/commands/context.js +9 -2
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/data-extra.d.ts +34 -0
- package/dist/commands/data-extra.js +198 -25
- package/dist/commands/data-extra.js.map +1 -1
- package/dist/commands/data.d.ts +120 -2
- package/dist/commands/data.js +307 -24
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +66 -4
- package/dist/commands/diagnose.js +329 -29
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/digest.js +2 -1
- package/dist/commands/digest.js.map +1 -1
- package/dist/commands/doc.d.ts +25 -4
- package/dist/commands/doc.js +100 -18
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/doctor.d.ts +130 -0
- package/dist/commands/doctor.js +814 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/events.js +3 -1
- package/dist/commands/events.js.map +1 -1
- package/dist/commands/explain.js +5 -5
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/graph.js +5 -3
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/import.d.ts +368 -13
- package/dist/commands/import.js +1096 -55
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts +20 -9
- package/dist/commands/init.js +433 -973
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.d.ts +1 -0
- package/dist/commands/keys.js +15 -2
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/knowledge.d.ts +28 -6
- package/dist/commands/knowledge.js +358 -73
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/launch.js +2 -2
- package/dist/commands/launch.js.map +1 -1
- package/dist/commands/lens.d.ts +37 -1
- package/dist/commands/lens.js +193 -72
- package/dist/commands/lens.js.map +1 -1
- package/dist/commands/market-authoring.d.ts +72 -0
- package/dist/commands/market-authoring.js +566 -0
- package/dist/commands/market-authoring.js.map +1 -0
- package/dist/commands/market-official.d.ts +58 -0
- package/dist/commands/market-official.js +84 -0
- package/dist/commands/market-official.js.map +1 -0
- package/dist/commands/market.d.ts +419 -20
- package/dist/commands/market.js +2124 -193
- package/dist/commands/market.js.map +1 -1
- package/dist/commands/mcp.d.ts +70 -13
- package/dist/commands/mcp.js +308 -40
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/open.d.ts +39 -9
- package/dist/commands/open.js +80 -25
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/playbook.d.ts +42 -0
- package/dist/commands/playbook.js +162 -0
- package/dist/commands/playbook.js.map +1 -0
- package/dist/commands/pod.js +1 -1
- package/dist/commands/pod.js.map +1 -1
- package/dist/commands/pods.d.ts +19 -0
- package/dist/commands/pods.js +220 -85
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.d.ts +62 -0
- package/dist/commands/proposals-actions.js +146 -8
- package/dist/commands/proposals-actions.js.map +1 -1
- package/dist/commands/proposals-await.d.ts +68 -0
- package/dist/commands/proposals-await.js +248 -0
- package/dist/commands/proposals-await.js.map +1 -0
- package/dist/commands/proton-setup.d.ts +73 -0
- package/dist/commands/proton-setup.js +577 -0
- package/dist/commands/proton-setup.js.map +1 -0
- package/dist/commands/providers.d.ts +23 -0
- package/dist/commands/providers.js +126 -1
- package/dist/commands/providers.js.map +1 -1
- package/dist/commands/raycast.js +6 -2
- package/dist/commands/raycast.js.map +1 -1
- package/dist/commands/rule.d.ts +150 -0
- package/dist/commands/rule.js +447 -0
- package/dist/commands/rule.js.map +1 -0
- package/dist/commands/session-wait.d.ts +111 -0
- package/dist/commands/session-wait.js +209 -0
- package/dist/commands/session-wait.js.map +1 -0
- package/dist/commands/sessions.d.ts +52 -0
- package/dist/commands/sessions.js +479 -58
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/skill-manage.d.ts +21 -0
- package/dist/commands/skill-manage.js +136 -19
- package/dist/commands/skill-manage.js.map +1 -1
- package/dist/commands/skills.js +19 -1
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +1 -4
- package/dist/commands/status.js +5 -34
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/statusline.backoff.test.d.ts +13 -0
- package/dist/commands/statusline.backoff.test.js +100 -0
- package/dist/commands/statusline.backoff.test.js.map +1 -0
- package/dist/commands/statusline.js +16 -9
- package/dist/commands/statusline.js.map +1 -1
- package/dist/commands/sync-status.d.ts +12 -0
- package/dist/commands/sync-status.js +125 -0
- package/dist/commands/sync-status.js.map +1 -0
- package/dist/commands/templates-retire.d.ts +34 -0
- package/dist/commands/templates-retire.js +192 -0
- package/dist/commands/templates-retire.js.map +1 -0
- package/dist/commands/tools.js +6 -21
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/tracks.d.ts +51 -0
- package/dist/commands/tracks.js +291 -0
- package/dist/commands/tracks.js.map +1 -0
- package/dist/commands/update.d.ts +3 -11
- package/dist/commands/update.js +5 -134
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upload.d.ts +68 -0
- package/dist/commands/upload.js +257 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/commands/vendor.d.ts +28 -0
- package/dist/commands/vendor.js +110 -0
- package/dist/commands/vendor.js.map +1 -0
- package/dist/commands/versions.js +6 -0
- package/dist/commands/versions.js.map +1 -1
- package/dist/commands/view.js +10 -5
- package/dist/commands/view.js.map +1 -1
- package/dist/commands/whoami.d.ts +23 -3
- package/dist/commands/whoami.js +169 -23
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/worker.d.ts +122 -0
- package/dist/commands/worker.js +435 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/commands/worker.test.d.ts +1 -0
- package/dist/commands/worker.test.js +116 -0
- package/dist/commands/worker.test.js.map +1 -0
- package/dist/commands/workspace-ops.d.ts +35 -0
- package/dist/commands/workspace-ops.js +153 -0
- package/dist/commands/workspace-ops.js.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1009 -171
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-connections.d.ts +31 -0
- package/dist/lib/agent-connections.js +33 -0
- package/dist/lib/agent-connections.js.map +1 -0
- package/dist/lib/agent-detect.d.ts +27 -0
- package/dist/lib/agent-detect.js +71 -0
- package/dist/lib/agent-detect.js.map +1 -0
- package/dist/lib/agent-door.d.ts +138 -0
- package/dist/lib/agent-door.js +426 -0
- package/dist/lib/agent-door.js.map +1 -0
- package/dist/lib/agents-config.d.ts +2 -0
- package/dist/lib/agents-config.js +4 -9
- package/dist/lib/agents-config.js.map +1 -1
- package/dist/lib/approval-poll.d.ts +31 -2
- package/dist/lib/approval-poll.js +20 -7
- package/dist/lib/approval-poll.js.map +1 -1
- package/dist/lib/atomic-file.d.ts +48 -0
- package/dist/lib/atomic-file.js +129 -0
- package/dist/lib/atomic-file.js.map +1 -0
- package/dist/lib/auth.d.ts +14 -9
- package/dist/lib/auth.js +44 -61
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/batch-approval.d.ts +85 -0
- package/dist/lib/batch-approval.js +170 -0
- package/dist/lib/batch-approval.js.map +1 -0
- package/dist/lib/capture-lane.d.ts +6 -5
- package/dist/lib/capture-lane.js +11 -8
- package/dist/lib/capture-lane.js.map +1 -1
- package/dist/lib/capture-structure.d.ts +342 -0
- package/dist/lib/capture-structure.js +295 -0
- package/dist/lib/capture-structure.js.map +1 -0
- package/dist/lib/catalog-templates.d.ts +59 -0
- package/dist/lib/catalog-templates.js +126 -0
- package/dist/lib/catalog-templates.js.map +1 -0
- package/dist/lib/cli-build.d.ts +19 -0
- package/dist/lib/cli-build.js +37 -0
- package/dist/lib/cli-build.js.map +1 -0
- package/dist/lib/conversation-headers.d.ts +18 -0
- package/dist/lib/conversation-headers.js +32 -0
- package/dist/lib/conversation-headers.js.map +1 -0
- package/dist/lib/cp-packages.d.ts +216 -4
- package/dist/lib/cp-packages.js +414 -11
- package/dist/lib/cp-packages.js.map +1 -1
- package/dist/lib/credential-class.d.ts +117 -0
- package/dist/lib/credential-class.js +116 -0
- package/dist/lib/credential-class.js.map +1 -0
- package/dist/lib/describe-lens.d.ts +35 -0
- package/dist/lib/describe-lens.js +40 -0
- package/dist/lib/describe-lens.js.map +1 -1
- package/dist/lib/device-connect.d.ts +125 -0
- package/dist/lib/device-connect.js +256 -0
- package/dist/lib/device-connect.js.map +1 -0
- package/dist/lib/directory-lens.d.ts +99 -0
- package/dist/lib/directory-lens.js +187 -0
- package/dist/lib/directory-lens.js.map +1 -0
- package/dist/lib/exporter-coverage.d.ts +71 -0
- package/dist/lib/exporter-coverage.js +97 -0
- package/dist/lib/exporter-coverage.js.map +1 -0
- package/dist/lib/hub-client.d.ts +43 -9
- package/dist/lib/hub-client.js +429 -65
- package/dist/lib/hub-client.js.map +1 -1
- package/dist/lib/id.d.ts +23 -0
- package/dist/lib/id.js +35 -0
- package/dist/lib/id.js.map +1 -0
- package/dist/lib/init-connect.d.ts +41 -0
- package/dist/lib/init-connect.js +75 -0
- package/dist/lib/init-connect.js.map +1 -0
- package/dist/lib/init-exit.d.ts +24 -0
- package/dist/lib/init-exit.js +41 -0
- package/dist/lib/init-exit.js.map +1 -0
- package/dist/lib/init-flow.d.ts +25 -0
- package/dist/lib/init-flow.js +40 -0
- package/dist/lib/init-flow.js.map +1 -0
- package/dist/lib/init-handoff.d.ts +16 -0
- package/dist/lib/init-handoff.js +19 -0
- package/dist/lib/init-handoff.js.map +1 -0
- package/dist/lib/init-output.d.ts +18 -0
- package/dist/lib/init-output.js +43 -0
- package/dist/lib/init-output.js.map +1 -0
- package/dist/lib/init-pod.d.ts +45 -0
- package/dist/lib/init-pod.js +36 -0
- package/dist/lib/init-pod.js.map +1 -0
- package/dist/lib/installed.d.ts +210 -11
- package/dist/lib/installed.js +234 -36
- package/dist/lib/installed.js.map +1 -1
- package/dist/lib/key-approval.d.ts +57 -0
- package/dist/lib/key-approval.js +117 -0
- package/dist/lib/key-approval.js.map +1 -0
- package/dist/lib/key-diagnosis.d.ts +56 -0
- package/dist/lib/key-diagnosis.js +227 -0
- package/dist/lib/key-diagnosis.js.map +1 -0
- package/dist/lib/key-doctor.d.ts +136 -0
- package/dist/lib/key-doctor.js +286 -0
- package/dist/lib/key-doctor.js.map +1 -0
- package/dist/lib/key-locations.d.ts +120 -0
- package/dist/lib/key-locations.js +326 -0
- package/dist/lib/key-locations.js.map +1 -0
- package/dist/lib/key-source.d.ts +66 -0
- package/dist/lib/key-source.js +106 -0
- package/dist/lib/key-source.js.map +1 -0
- package/dist/lib/key-state.d.ts +70 -0
- package/dist/lib/key-state.js +115 -0
- package/dist/lib/key-state.js.map +1 -0
- package/dist/lib/kind-package.d.ts +181 -0
- package/dist/lib/kind-package.js +679 -0
- package/dist/lib/kind-package.js.map +1 -0
- package/dist/lib/knowledge-title.d.ts +24 -0
- package/dist/lib/knowledge-title.js +46 -0
- package/dist/lib/knowledge-title.js.map +1 -0
- package/dist/lib/knowledge-title.test.d.ts +1 -0
- package/dist/lib/knowledge-title.test.js +34 -0
- package/dist/lib/knowledge-title.test.js.map +1 -0
- package/dist/lib/machine-instance.d.ts +64 -0
- package/dist/lib/machine-instance.js +142 -0
- package/dist/lib/machine-instance.js.map +1 -0
- package/dist/lib/mcp-bridge.d.ts +42 -0
- package/dist/lib/mcp-bridge.js +147 -0
- package/dist/lib/mcp-bridge.js.map +1 -0
- package/dist/lib/mcp-bridge.test.d.ts +1 -0
- package/dist/lib/mcp-bridge.test.js +90 -0
- package/dist/lib/mcp-bridge.test.js.map +1 -0
- package/dist/lib/mcp-call.d.ts +30 -0
- package/dist/lib/mcp-call.js +107 -0
- package/dist/lib/mcp-call.js.map +1 -0
- package/dist/lib/mcp-snippets.d.ts +53 -0
- package/dist/lib/mcp-snippets.js +82 -0
- package/dist/lib/mcp-snippets.js.map +1 -0
- package/dist/lib/next-steps.d.ts +8 -0
- package/dist/lib/next-steps.js +31 -1
- package/dist/lib/next-steps.js.map +1 -1
- package/dist/lib/package-wire.d.ts +179 -0
- package/dist/lib/package-wire.js +68 -0
- package/dist/lib/package-wire.js.map +1 -0
- package/dist/lib/pair-link.d.ts +38 -0
- package/dist/lib/pair-link.js +68 -0
- package/dist/lib/pair-link.js.map +1 -0
- package/dist/lib/pod-wide.d.ts +40 -0
- package/dist/lib/pod-wide.js +46 -0
- package/dist/lib/pod-wide.js.map +1 -0
- package/dist/lib/pod.d.ts +119 -115
- package/dist/lib/pod.js +206 -412
- package/dist/lib/pod.js.map +1 -1
- package/dist/lib/project-ref.d.ts +9 -3
- package/dist/lib/project-ref.js +10 -4
- package/dist/lib/project-ref.js.map +1 -1
- package/dist/lib/review-credential.d.ts +119 -0
- package/dist/lib/review-credential.js +147 -0
- package/dist/lib/review-credential.js.map +1 -0
- package/dist/lib/safe-open.d.ts +49 -0
- package/dist/lib/safe-open.js +119 -0
- package/dist/lib/safe-open.js.map +1 -0
- package/dist/lib/session-lens.d.ts +40 -1
- package/dist/lib/session-lens.js +54 -4
- package/dist/lib/session-lens.js.map +1 -1
- package/dist/lib/superwhisper-import.d.ts +8 -0
- package/dist/lib/superwhisper-import.js +14 -7
- package/dist/lib/superwhisper-import.js.map +1 -1
- package/dist/lib/superwhisper-title.test.d.ts +1 -0
- package/dist/lib/superwhisper-title.test.js +18 -0
- package/dist/lib/superwhisper-title.test.js.map +1 -0
- package/dist/lib/targets.d.ts +134 -10
- package/dist/lib/targets.js +962 -258
- package/dist/lib/targets.js.map +1 -1
- package/dist/lib/template-file.d.ts +78 -0
- package/dist/lib/template-file.js +140 -0
- package/dist/lib/template-file.js.map +1 -0
- package/dist/lib/template-lifecycle.d.ts +217 -0
- package/dist/lib/template-lifecycle.js +433 -0
- package/dist/lib/template-lifecycle.js.map +1 -0
- package/dist/lib/template-steps.d.ts +88 -0
- package/dist/lib/template-steps.js +118 -0
- package/dist/lib/template-steps.js.map +1 -0
- package/dist/lib/time-ago.d.ts +2 -0
- package/dist/lib/time-ago.js +15 -0
- package/dist/lib/time-ago.js.map +1 -0
- package/dist/utils/logger.js +5 -2
- package/dist/utils/logger.js.map +1 -1
- package/package.json +25 -18
- package/skills/README.md +12 -10
- package/skills/agent-os/SKILL.md +220 -99
- package/skills/manifest.json +2 -2
- package/skills/onboard/SKILL.md +61 -25
- package/skills/synap/README.md +5 -8
- package/skills/synap/SKILL.md +1185 -301
- package/skills/synap/_order.txt +7 -0
- package/skills/synap/_skill.yaml +1 -1
- package/skills/synap/automations.md +15 -0
- package/skills/synap/capture.md +54 -151
- package/skills/synap/cli-operations.md +24 -18
- package/skills/synap/common-mistakes.md +1 -0
- package/skills/synap/concepts.md +28 -0
- package/skills/synap/content-os.md +92 -0
- package/skills/synap/creative-loop.md +15 -10
- package/skills/synap/crm.md +21 -52
- package/skills/synap/digesting-a-channel.md +25 -0
- package/skills/synap/document-embeds.md +141 -47
- package/skills/synap/escalation-ladder.md +20 -10
- package/skills/synap/focus-sessions.md +47 -21
- package/skills/synap/from-intent.md +142 -0
- package/skills/synap/governance-rules.md +4 -4
- package/skills/synap/governance.md +10 -7
- package/skills/synap/hand-off.md +33 -0
- package/skills/synap/inline-patterns.md +15 -7
- package/skills/synap/lenses.md +33 -15
- package/skills/synap/linking.md +41 -40
- package/skills/synap/mcp-remote-servers.md +64 -0
- package/skills/synap/mental-model.md +24 -22
- package/skills/synap/multi-entity-capture.md +6 -4
- package/skills/synap/operating-mode-rules.md +1 -1
- package/skills/synap/processes.md +118 -0
- package/skills/synap/quick-reference.md +5 -1
- package/skills/synap/reading.md +3 -1
- package/skills/synap/reflexes.md +12 -42
- package/skills/synap/viewframe-cells.md +38 -5
- package/skills/synap/work-flow.md +1 -1
- package/skills/synap/work-model.md +96 -0
- package/skills/synap/worked-examples.md +21 -1
- package/skills/synap/workspace-design.md +14 -10
- package/skills/synap/writes.md +165 -35
- package/skills/synap/writing-titles.md +63 -0
- package/skills/synap-app/SKILL.md +319 -0
- package/skills/synap-app/_order.txt +5 -0
- package/skills/synap-app/_skill.yaml +20 -0
- package/skills/synap-app/creating-the-base-app.md +64 -0
- package/skills/synap-app/governance.md +42 -0
- package/skills/synap-app/install-commands.md +55 -0
- package/skills/synap-app/overview.md +50 -0
- package/skills/synap-app/using-the-sdk.md +73 -0
- package/skills/synap-design/SKILL.md +474 -0
- package/skills/synap-design/_order.txt +4 -0
- package/skills/synap-design/_skill.yaml +21 -0
- package/skills/synap-design/loop.md +134 -0
- package/skills/synap-design/overview.md +44 -0
- package/skills/synap-design/principles.md +130 -0
- package/skills/synap-design/system.md +133 -0
- package/skills/synap-market/SKILL.md +625 -0
- package/skills/synap-market/_order.txt +5 -0
- package/skills/synap-market/_skill.yaml +24 -0
- package/skills/synap-market/author-and-publish.md +212 -0
- package/skills/synap-market/discover-and-fetch.md +59 -0
- package/skills/synap-market/governance-and-catalog.md +63 -0
- package/skills/synap-market/install.md +133 -0
- package/skills/synap-market/overview.md +119 -0
- package/skills/synap-schema/SKILL.md +172 -10
- package/skills/synap-schema/_order.txt +2 -0
- package/skills/synap-schema/_skill.yaml +4 -2
- package/skills/synap-schema/common-mistakes.md +4 -2
- package/skills/synap-schema/discover-profiles.md +1 -1
- package/skills/synap-schema/entity-scope.md +15 -3
- package/skills/synap-schema/extend-first.md +29 -0
- package/skills/synap-schema/extend-vs-create.md +1 -1
- package/skills/synap-schema/intent-vocabulary-ssot.md +111 -0
- package/skills/synap-schema/property-types.md +1 -1
- package/skills/synap-schema/relations.md +1 -1
- package/skills/synap-ui/SKILL.md +19 -12
- package/skills/synap-ui/_skill.yaml +1 -1
- package/skills/synap-ui/ai-companion.md +1 -1
- package/skills/synap-ui/arranging-bento.md +2 -0
- package/skills/synap-ui/bento-layouts.md +10 -10
- package/skills/synap-ui/bento-recipes.md +313 -543
- package/skills/synap-ui/four-builds.md +5 -0
- package/skills/synap-ui/view-types.md +2 -2
- package/skills/synap-ui/widget-catalog.md +22 -278
- package/templates/automations/bookmark-enrichment.automation.json +290 -13
- package/templates/automations/url-bookmark-capture.automation.json +73 -11
- package/templates/skills/authoring-playbooks/SKILL.md +6 -3
- package/templates/skills/authoring-playbooks/reference/stages-contract.md +15 -0
- package/templates/skills/authoring-playbooks/reference/worked-example.md +3 -0
- package/dist/commands/infra.d.ts +0 -21
- package/dist/commands/infra.js +0 -262
- package/dist/commands/infra.js.map +0 -1
- package/dist/lib/browser-auth.d.ts +0 -35
- package/dist/lib/browser-auth.js +0 -170
- package/dist/lib/browser-auth.js.map +0 -1
- package/dist/lib/openclaw.d.ts +0 -32
- package/dist/lib/openclaw.js +0 -164
- package/dist/lib/openclaw.js.map +0 -1
- package/dist/lib/seed.d.ts +0 -13
- package/dist/lib/seed.js +0 -135
- package/dist/lib/seed.js.map +0 -1
|
@@ -12,43 +12,168 @@
|
|
|
12
12
|
* `engineering_knowledge`). A formal decision RECORD (rationale/alternatives/status
|
|
13
13
|
* lifecycle) comes from smart `capture "<text>"` or `create entity --profile=decision`.
|
|
14
14
|
*
|
|
15
|
-
* Workspace routing: --workspace
|
|
16
|
-
*
|
|
15
|
+
* Workspace routing for Work-lane knowledge: --workspace (explicit pin) >
|
|
16
|
+
* --team (first product ws, when configured) > omit workspaceId (server-derived
|
|
17
|
+
* / pod-wide preferred). Never default-pin to the active profile workspace —
|
|
18
|
+
* that commonly is Pod Admin and would dump domain knowledge into admin.
|
|
17
19
|
*/
|
|
18
20
|
import chalk from "chalk";
|
|
19
21
|
import * as readline from "node:readline/promises";
|
|
20
22
|
import { stdin as input, stdout as output } from "node:process";
|
|
21
23
|
import { log } from "../utils/logger.js";
|
|
22
|
-
import { resolveHubConfig, resolveUserId, hubPost,
|
|
24
|
+
import { resolveHubConfig, resolveUserId, hubPost, hubGet, resolveActiveSessionId, renderHubError, } from "../lib/hub-client.js";
|
|
25
|
+
import { unwrapList } from "../lib/unwrapList.js";
|
|
23
26
|
import { getAgentWorkspaceRouting } from "../lib/pod.js";
|
|
24
|
-
import {
|
|
27
|
+
import { resolvePodWide } from "../lib/pod-wide.js";
|
|
28
|
+
import { laneFromSource, resolveWorkspaceName, formatLaneLine, laneJsonFields, writeGovernance, } from "../lib/capture-lane.js";
|
|
29
|
+
import { isDegraded, degradedMessage, readCaptureExecute, formatWorkspaceRouting, formatPendingWorkspaceSwitch, headlessPlacementFields, projectRoutingHints, workspaceRoutingHints, } from "../lib/capture-structure.js";
|
|
30
|
+
import { UUID_RE } from "../lib/id.js";
|
|
31
|
+
import { chooseKnowledgeTitle } from "../lib/knowledge-title.js";
|
|
32
|
+
// ─── Client-side length guard ────────────────────────────────────────────────
|
|
33
|
+
// Captures used to die SERVER-SIDE with a raw "String length 1404 > maximum
|
|
34
|
+
// 1000" after the user had already composed + confirmed — surface the same
|
|
35
|
+
// caps client-side, BEFORE sending, so a too-long capture gets a heads-up
|
|
36
|
+
// instead of a mid-flight rejection. Not a hard block: --yes/--json paths and
|
|
37
|
+
// a declined truncation still send as-is and let the pod be the final judge
|
|
38
|
+
// (the caps below mirror the pod's contract but are not re-validated here).
|
|
39
|
+
//
|
|
40
|
+
// Mirrors:
|
|
41
|
+
// - synap-backend CaptureStructureRequestSchema.text
|
|
42
|
+
// (packages/api/src/routers/hub-protocol/rest/_codecs/misc.ts)
|
|
43
|
+
// - the `knowledge` profile's ek_claim/ek_why/ek_evidence property defs
|
|
44
|
+
// (packages/database/src/utils/ensure-system-profiles.ts)
|
|
45
|
+
const SMART_TEXT_MAX = 8000;
|
|
46
|
+
const CLAIM_MAX = 1000;
|
|
47
|
+
const WHY_MAX = 5000;
|
|
48
|
+
const EVIDENCE_MAX = 2000;
|
|
49
|
+
/**
|
|
50
|
+
* Warn when `value` exceeds `max`, and offer to truncate (interactive) or
|
|
51
|
+
* proceed as-is. Returns the value to send (possibly truncated), or
|
|
52
|
+
* `undefined` if the user aborted.
|
|
53
|
+
*
|
|
54
|
+
* Non-interactive (`--yes` / `--json`): warns to stderr and proceeds unchanged
|
|
55
|
+
* — this is a heads-up, not a client-side hard block; the pod is still free to
|
|
56
|
+
* accept a since-raised cap.
|
|
57
|
+
*/
|
|
58
|
+
async function guardLength(label, value, max, opts) {
|
|
59
|
+
if (value.length <= max)
|
|
60
|
+
return value;
|
|
61
|
+
if (opts.yes || opts.json) {
|
|
62
|
+
log.warn(`${label} is ${value.length} chars (pod limit ~${max}) — sending as-is; the pod may reject it.`);
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
log.warn(`${label} is ${value.length} chars — the pod's limit is ~${max}.`);
|
|
66
|
+
const rl = readline.createInterface({ input, output });
|
|
67
|
+
try {
|
|
68
|
+
const answer = await rl.question(chalk.bold(` Truncate to ${max} chars and continue? [Y/n/(a)bort] `));
|
|
69
|
+
const a = answer.trim().toLowerCase();
|
|
70
|
+
if (a === "n" || a === "abort" || a === "a")
|
|
71
|
+
return undefined;
|
|
72
|
+
return value.slice(0, max);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
rl.close();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
25
78
|
/**
|
|
26
79
|
* Resolve the workspace for a DOMAIN capture (the `knowledge` entity, the Work
|
|
27
|
-
* lane).
|
|
28
|
-
* a Builder lesson stays in Builder, a marketing one in marketing.
|
|
80
|
+
* lane).
|
|
29
81
|
*
|
|
30
|
-
* Priority: --workspace > --team (first product ws
|
|
82
|
+
* Priority: --workspace (explicit pin) > --team (first product ws when
|
|
83
|
+
* configured) > omit workspaceId.
|
|
31
84
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* (
|
|
36
|
-
*
|
|
85
|
+
* Default is intentional omit: sending an ambient/active workspaceId is a
|
|
86
|
+
* backend rung-1 pin. Team profiles often default active workspace to Pod Admin,
|
|
87
|
+
* which dumped domain knowledge into admin. Leaving workspaceId out lets the
|
|
88
|
+
* server place knowledge (pod-wide preferred for knowledge kinds / AI routing on
|
|
89
|
+
* smart capture).
|
|
90
|
+
*
|
|
91
|
+
* NOTE: the agent-memory ("AI-self") lane was removed — everything routes to a
|
|
92
|
+
* real lane: Work (here), Global (`--global` → knowledge_keys), or User
|
|
93
|
+
* (`record_observation` → user_observation).
|
|
37
94
|
*/
|
|
38
|
-
async function resolveKnowledgeWorkspace(opts
|
|
95
|
+
async function resolveKnowledgeWorkspace(opts) {
|
|
39
96
|
if (opts.workspace) {
|
|
40
97
|
return { workspaceId: opts.workspace, source: "explicit" };
|
|
41
98
|
}
|
|
42
99
|
if (opts.team) {
|
|
43
100
|
const routing = getAgentWorkspaceRouting();
|
|
44
101
|
const teamWs = routing?.productWorkspaceIds?.[0];
|
|
45
|
-
|
|
102
|
+
if (teamWs) {
|
|
103
|
+
return { workspaceId: teamWs, source: "team" };
|
|
104
|
+
}
|
|
105
|
+
// --team asked for a product pin but none is configured: still omit.
|
|
106
|
+
// Do not fall back to active workspace (that reintroduces the Admin dump).
|
|
107
|
+
return {
|
|
108
|
+
workspaceId: undefined,
|
|
109
|
+
source: "server-derived (no team workspace configured — pod-wide preferred for knowledge)",
|
|
110
|
+
};
|
|
46
111
|
}
|
|
47
112
|
return {
|
|
48
|
-
workspaceId:
|
|
49
|
-
source:
|
|
113
|
+
workspaceId: undefined,
|
|
114
|
+
source: "server-derived (pod-wide preferred for knowledge)",
|
|
50
115
|
};
|
|
51
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Resolve a `--project` value (id or name) to a project id on the active pod.
|
|
119
|
+
* Mirrors `synap import`'s resolveProjectArg — same shape, same "not found"
|
|
120
|
+
* wording, kept local here since neither command shares a project-resolution
|
|
121
|
+
* lib yet. Throws on no match so a typo'd project name fails loud instead of
|
|
122
|
+
* silently dropping the pin.
|
|
123
|
+
*/
|
|
124
|
+
async function resolveProjectArg(value, cfg) {
|
|
125
|
+
if (UUID_RE.test(value))
|
|
126
|
+
return value;
|
|
127
|
+
const res = (await hubGet("/projects", {}, cfg));
|
|
128
|
+
const list = unwrapList(res, ["projects"]);
|
|
129
|
+
const match = list.find((p) => String(p.name ?? "").toLowerCase() === value.toLowerCase());
|
|
130
|
+
if (!match) {
|
|
131
|
+
const names = list.map((p) => String(p.name ?? p.id)).join(", ");
|
|
132
|
+
throw new Error(`Project '${value}' not found.${names ? ` Available: ${names}` : ""}`);
|
|
133
|
+
}
|
|
134
|
+
return String(match.id);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Render the pod's project-link receipt honestly — never a bare "✓ stored"
|
|
138
|
+
* that hides a dropped project coordinate. Read DEFENSIVELY: the two write
|
|
139
|
+
* doors this command uses shape their receipt differently —
|
|
140
|
+
* - POST /capture/execute → `res.project = { projectId, rung, status }`
|
|
141
|
+
* - POST /entities → `res.writeReceipt.projectId` (present only once
|
|
142
|
+
* applied — omitted while the write is still a pending proposal)
|
|
143
|
+
* and the exact field name may still shift as the backend's receipt work
|
|
144
|
+
* lands, so this checks both shapes rather than assuming one.
|
|
145
|
+
*/
|
|
146
|
+
function renderProjectReceipt(res, requestedProjectId, isProposed) {
|
|
147
|
+
if (!requestedProjectId)
|
|
148
|
+
return;
|
|
149
|
+
const captureProject = res.project;
|
|
150
|
+
if (captureProject?.projectId) {
|
|
151
|
+
if (captureProject.status === "linked") {
|
|
152
|
+
log.dim(` → linked to project ${captureProject.projectId.slice(0, 8)}`);
|
|
153
|
+
}
|
|
154
|
+
else if (captureProject.status === "proposed") {
|
|
155
|
+
log.dim(` → project ${captureProject.projectId.slice(0, 8)} proposed (advisory — awaiting confirm, not yet linked)`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
log.dim(` → project ${captureProject.projectId.slice(0, 8)} (${captureProject.status ?? "unknown"})`);
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const writeReceipt = res.writeReceipt;
|
|
163
|
+
if (writeReceipt?.projectId) {
|
|
164
|
+
log.dim(` → linked to project ${writeReceipt.projectId.slice(0, 8)}`);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (isProposed) {
|
|
168
|
+
// The whole write is pending review — the project link rides along with
|
|
169
|
+
// it and applies on approval, not dropped.
|
|
170
|
+
log.dim(` → project ${requestedProjectId.slice(0, 8)} will link on approval (write is pending review)`);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// A project pin was sent but no receipt confirms it — say so plainly rather
|
|
174
|
+
// than letting a silent drop look like success.
|
|
175
|
+
log.dim(` → project NOT linked (pod did not confirm ${requestedProjectId.slice(0, 8)} — it may not be reachable from this workspace)`);
|
|
176
|
+
}
|
|
52
177
|
/** Slugify free text into a knowledge_keys slug fragment. */
|
|
53
178
|
function slugify(text) {
|
|
54
179
|
return text
|
|
@@ -101,12 +226,14 @@ async function captureGlobalRunbook(opts, cfg, authorUserId) {
|
|
|
101
226
|
log.dim(` key: ${key}`);
|
|
102
227
|
console.log(" " + formatLaneLine(report));
|
|
103
228
|
}
|
|
229
|
+
// ─── Smart capture mode (no --type) ──────────────────────────────────────────
|
|
230
|
+
// Structure/execute wire shapes + the degraded/execute interpreters are shared
|
|
231
|
+
// with `synap import` in lib/capture-structure.ts (ONE mirror, no drift).
|
|
104
232
|
/** Render the /capture/structure result as a compact human-readable summary. */
|
|
105
233
|
function renderStructureResult(result) {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
234
|
+
const proposals = result.proposals ?? [];
|
|
235
|
+
const relations = result.relations ?? [];
|
|
236
|
+
const followUp = result.followUp;
|
|
110
237
|
if (proposals.length === 0) {
|
|
111
238
|
log.dim("No entity proposals extracted.");
|
|
112
239
|
return;
|
|
@@ -140,11 +267,10 @@ function renderStructureResult(result) {
|
|
|
140
267
|
}
|
|
141
268
|
if (result.targetWorkspaceId || result.targetProjectId) {
|
|
142
269
|
log.blank();
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
log.dim(` → workspace: ${result.targetWorkspaceId}${conf}`);
|
|
270
|
+
const workspaceLine = formatWorkspaceRouting(result);
|
|
271
|
+
if (workspaceLine) {
|
|
272
|
+
// The pod's NAME for its pick, with its confidence once.
|
|
273
|
+
log.dim(` → workspace: ${workspaceLine}`);
|
|
148
274
|
if (result.targetWorkspaceReason) {
|
|
149
275
|
log.dim(` ${result.targetWorkspaceReason.slice(0, 90)}`);
|
|
150
276
|
}
|
|
@@ -174,35 +300,92 @@ function renderStructureResult(result) {
|
|
|
174
300
|
}
|
|
175
301
|
}
|
|
176
302
|
}
|
|
177
|
-
async function runSmartCapture(
|
|
303
|
+
async function runSmartCapture(rawText, opts) {
|
|
304
|
+
const guarded = await guardLength("Capture text", rawText, SMART_TEXT_MAX, opts);
|
|
305
|
+
if (guarded === undefined) {
|
|
306
|
+
log.dim("Aborted.");
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const text = guarded;
|
|
178
310
|
const cfg = await resolveHubConfig();
|
|
179
311
|
const userId = await resolveUserId(cfg);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
312
|
+
// Do NOT default-pin cfg.workspaceId — omit unless --workspace / --team.
|
|
313
|
+
const { workspaceId, source } = await resolveKnowledgeWorkspace(opts);
|
|
314
|
+
// Default Work-lane knowledge omits workspaceId so the pod can place it
|
|
315
|
+
// (AI routing on smart capture / pod-wide preferred for knowledge kinds).
|
|
316
|
+
if (!workspaceId && !opts.json) {
|
|
317
|
+
log.dim(` Placement: ${source} — workspaceId omitted.`);
|
|
318
|
+
log.dim(" Pin with --workspace <id> or --team (first product workspace).");
|
|
319
|
+
}
|
|
320
|
+
// Project pin: explicit --project (id or name) wins; otherwise the ambient
|
|
321
|
+
// lens (SYNAP_PROJECT_ID / the active Claude session's pinned project,
|
|
322
|
+
// already resolved into cfg.projectId by resolveHubConfig).
|
|
323
|
+
let projectId;
|
|
324
|
+
try {
|
|
325
|
+
projectId = opts.project ? await resolveProjectArg(opts.project, cfg) : cfg.projectId;
|
|
326
|
+
}
|
|
327
|
+
catch (e) {
|
|
328
|
+
console.error(chalk.red(e.message));
|
|
185
329
|
process.exit(1);
|
|
186
330
|
}
|
|
187
331
|
// 1. Structure
|
|
188
|
-
const smartSessionId = opts.session ?
|
|
189
|
-
const structureBody = {
|
|
332
|
+
const smartSessionId = opts.session ? resolveActiveSessionId(cfg.podUrl) : undefined;
|
|
333
|
+
const structureBody = {
|
|
334
|
+
userId,
|
|
335
|
+
text,
|
|
336
|
+
...(workspaceId ? { workspaceId } : {}),
|
|
337
|
+
...(smartSessionId ? { sessionId: smartSessionId } : {}),
|
|
338
|
+
};
|
|
190
339
|
const structureRes = await hubPost("/capture/structure", structureBody, cfg);
|
|
340
|
+
// Degraded: the IS structurer is down. The server returns a raw fallback-kind
|
|
341
|
+
// stand-in (`note`; `degraded: true` on the wire), but we create nothing (browser does the same via
|
|
342
|
+
// offlineFallback:false) — tell the user, don't silently downgrade the
|
|
343
|
+
// capture into an unstructured blob behind a success line.
|
|
344
|
+
if (isDegraded(structureRes)) {
|
|
345
|
+
if (opts.json) {
|
|
346
|
+
console.log(JSON.stringify({
|
|
347
|
+
degraded: true,
|
|
348
|
+
degradedReason: structureRes.degradedReason ?? null,
|
|
349
|
+
created: 0,
|
|
350
|
+
message: degradedMessage(structureRes),
|
|
351
|
+
}, null, 2));
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
log.warn(degradedMessage(structureRes));
|
|
355
|
+
}
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
191
358
|
// Explicit --workspace is a deliberate pin: send it as-is, no AI routing hints.
|
|
192
359
|
// Otherwise forward the AI's routing signal and let the backend decide
|
|
193
360
|
// (auto = AI target wins over ambient when confidence is high enough AND the
|
|
194
|
-
// user is a member).
|
|
361
|
+
// user is a member).
|
|
195
362
|
const isExplicitOverride = Boolean(opts.workspace);
|
|
363
|
+
// The AI's advice goes through the ONE structure → execute mapper
|
|
364
|
+
// (`captureExecuteRoutingHints`, mirrored in capture-structure.ts).
|
|
365
|
+
// Headless door: the structure step's PLACEMENT decides what is pinned
|
|
366
|
+
// (`headlessPlacementFields` — the ONE derivation, shared with the pod's own
|
|
367
|
+
// headless doors). A deterministic placement rides as an explicit
|
|
368
|
+
// `targetWorkspaceId`; an AI suggestion stays a proposal and is recorded as
|
|
369
|
+
// `workspaceChoice: "ignored"` — the CLI never shows it before saving.
|
|
196
370
|
const routingFields = isExplicitOverride
|
|
197
371
|
? {}
|
|
198
372
|
: {
|
|
199
373
|
workspaceRouting: "auto",
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
aiWorkspaceReason: structureRes.targetWorkspaceReason,
|
|
374
|
+
...headlessPlacementFields(structureRes),
|
|
375
|
+
...workspaceRoutingHints(structureRes),
|
|
203
376
|
};
|
|
204
|
-
|
|
205
|
-
|
|
377
|
+
// Project: the explicit pin (--project / ambient lens) is the ONE
|
|
378
|
+
// deterministic field and always wins when present. The AI's own guess is
|
|
379
|
+
// forwarded ONLY as advisory (aiProjectId) — never promoted to the
|
|
380
|
+
// deterministic `projectId` field. That promotion was a real bug here
|
|
381
|
+
// (an AI guess would auto-link and widen cross-workspace access before the
|
|
382
|
+
// user ever confirmed it); the backend's aiProjectId path records it as a
|
|
383
|
+
// suggestion instead and never auto-links it.
|
|
384
|
+
if (projectId) {
|
|
385
|
+
routingFields.projectId = projectId;
|
|
386
|
+
}
|
|
387
|
+
else if (structureRes.targetProjectId) {
|
|
388
|
+
Object.assign(routingFields, projectRoutingHints(structureRes));
|
|
206
389
|
}
|
|
207
390
|
if (opts.json) {
|
|
208
391
|
// --json without --yes: print structure result and exit
|
|
@@ -213,14 +396,19 @@ async function runSmartCapture(text, opts) {
|
|
|
213
396
|
// --json + --yes: also execute and print combined result
|
|
214
397
|
const executeRes = await hubPost("/capture/execute", {
|
|
215
398
|
userId,
|
|
216
|
-
workspaceId,
|
|
399
|
+
...(workspaceId ? { workspaceId } : {}),
|
|
217
400
|
...(smartSessionId ? { sessionId: smartSessionId } : {}),
|
|
218
401
|
...routingFields,
|
|
219
402
|
entities: structureRes.proposals,
|
|
220
403
|
relations: structureRes.relations ?? [],
|
|
221
404
|
}, cfg);
|
|
222
405
|
const report = await buildSmartLaneReport(executeRes, workspaceId, source, cfg);
|
|
223
|
-
console.log(JSON.stringify({
|
|
406
|
+
console.log(JSON.stringify({
|
|
407
|
+
structure: structureRes,
|
|
408
|
+
execute: executeRes,
|
|
409
|
+
...(projectId ? { requestedProjectId: projectId } : {}),
|
|
410
|
+
...laneJsonFields(report),
|
|
411
|
+
}, null, 2));
|
|
224
412
|
return;
|
|
225
413
|
}
|
|
226
414
|
// 2. Render proposals
|
|
@@ -248,39 +436,52 @@ async function runSmartCapture(text, opts) {
|
|
|
248
436
|
// 4. Execute
|
|
249
437
|
const executeRes = await hubPost("/capture/execute", {
|
|
250
438
|
userId,
|
|
251
|
-
workspaceId,
|
|
439
|
+
...(workspaceId ? { workspaceId } : {}),
|
|
252
440
|
...(smartSessionId ? { sessionId: smartSessionId } : {}),
|
|
253
441
|
...routingFields,
|
|
254
442
|
entities: structureRes.proposals,
|
|
255
443
|
relations: structureRes.relations ?? [],
|
|
256
444
|
}, cfg);
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (
|
|
262
|
-
log.
|
|
445
|
+
// Report what the pod ACTUALLY returned — applied vs proposed vs
|
|
446
|
+
// nothing-new — never the planned proposal count.
|
|
447
|
+
const outcome = readCaptureExecute(executeRes);
|
|
448
|
+
const report = await buildSmartLaneReport(executeRes, workspaceId, source, cfg);
|
|
449
|
+
if (outcome.proposed) {
|
|
450
|
+
log.info("Capture proposed — under review, not yet stored.");
|
|
451
|
+
if (outcome.proposalId)
|
|
452
|
+
log.dim(` proposal: ${outcome.proposalId}`);
|
|
453
|
+
if (outcome.reviewUrl)
|
|
454
|
+
log.dim(` review: ${outcome.reviewUrl}`);
|
|
263
455
|
}
|
|
264
|
-
|
|
265
|
-
|
|
456
|
+
else {
|
|
457
|
+
const n = outcome.entitiesCreated;
|
|
458
|
+
log.success(`${n} entr${n !== 1 ? "ies" : "y"} created.`);
|
|
459
|
+
if (outcome.entitiesLinked) {
|
|
460
|
+
log.dim(` ${outcome.entitiesLinked} linked to existing entit${outcome.entitiesLinked !== 1 ? "ies" : "y"}.`);
|
|
461
|
+
}
|
|
462
|
+
if (outcome.relationsCreated) {
|
|
463
|
+
log.dim(` ${outcome.relationsCreated} relation${outcome.relationsCreated !== 1 ? "s" : ""} created.`);
|
|
464
|
+
}
|
|
465
|
+
const pending = formatPendingWorkspaceSwitch(outcome);
|
|
466
|
+
if (pending)
|
|
467
|
+
log.dim(` ${pending}`);
|
|
266
468
|
}
|
|
267
|
-
const report = await buildSmartLaneReport(executeRes, workspaceId, source, cfg);
|
|
268
469
|
console.log(" " + formatLaneLine(report));
|
|
470
|
+
renderProjectReceipt(executeRes, projectId, outcome.proposed);
|
|
269
471
|
}
|
|
270
472
|
/**
|
|
271
|
-
* Build the lane report for a smart-capture execute response.
|
|
272
|
-
*
|
|
273
|
-
*
|
|
473
|
+
* Build the lane report for a smart-capture execute response. Governance
|
|
474
|
+
* (auto vs proposed) is derived by the ONE shared interpreter so this doesn't
|
|
475
|
+
* re-implement a third detector.
|
|
274
476
|
*/
|
|
275
477
|
async function buildSmartLaneReport(executeRes, workspaceId, source, cfg) {
|
|
276
|
-
const isProposed = executeRes.status === "proposed" ||
|
|
277
|
-
Boolean(executeRes.proposalId) ||
|
|
278
|
-
Number(executeRes.proposalsCreated ?? 0) > 0;
|
|
279
478
|
return {
|
|
280
479
|
lane: laneFromSource(source),
|
|
281
480
|
workspaceId,
|
|
282
|
-
workspaceName:
|
|
283
|
-
|
|
481
|
+
workspaceName: workspaceId
|
|
482
|
+
? await resolveWorkspaceName(workspaceId, cfg)
|
|
483
|
+
: "server-derived (pod-wide preferred)",
|
|
484
|
+
governance: readCaptureExecute(executeRes).proposed ? "proposed" : "auto",
|
|
284
485
|
};
|
|
285
486
|
}
|
|
286
487
|
// ─── Legacy engineering-memory capture ────────────────────────────────────────
|
|
@@ -308,67 +509,132 @@ export async function captureKnowledge(opts) {
|
|
|
308
509
|
console.error(chalk.red("Missing required option: --claim <text>"));
|
|
309
510
|
process.exit(1);
|
|
310
511
|
}
|
|
512
|
+
// Client-side length guard — catch the "String length N > maximum 1000"
|
|
513
|
+
// server rejection BEFORE it fires, with a chance to truncate/abort
|
|
514
|
+
// instead of a mid-flight failure after composing + confirming.
|
|
515
|
+
const guardedClaim = await guardLength("--claim", opts.claim, CLAIM_MAX, opts);
|
|
516
|
+
if (guardedClaim === undefined) {
|
|
517
|
+
log.dim("Aborted.");
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
opts.claim = guardedClaim;
|
|
521
|
+
if (opts.why) {
|
|
522
|
+
const guardedWhy = await guardLength("--why", opts.why, WHY_MAX, opts);
|
|
523
|
+
if (guardedWhy === undefined) {
|
|
524
|
+
log.dim("Aborted.");
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
opts.why = guardedWhy;
|
|
528
|
+
}
|
|
529
|
+
if (opts.evidence) {
|
|
530
|
+
const guardedEvidence = await guardLength("--evidence", opts.evidence, EVIDENCE_MAX, opts);
|
|
531
|
+
if (guardedEvidence === undefined) {
|
|
532
|
+
log.dim("Aborted.");
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
opts.evidence = guardedEvidence;
|
|
536
|
+
}
|
|
311
537
|
const cfg = await resolveHubConfig();
|
|
312
538
|
const userId = await resolveUserId(cfg);
|
|
313
539
|
// GLOBAL lane: pod-wide procedural runbook → knowledge_keys.
|
|
314
|
-
|
|
540
|
+
// Canonical spelling is `--pod-wide`; `--global` is the retained alias.
|
|
541
|
+
if (resolvePodWide(opts)) {
|
|
315
542
|
await captureGlobalRunbook(opts, cfg, userId);
|
|
316
543
|
return;
|
|
317
544
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
545
|
+
// Do NOT default-pin cfg.workspaceId — omit unless --workspace / --team.
|
|
546
|
+
const { workspaceId, source } = await resolveKnowledgeWorkspace(opts);
|
|
547
|
+
// Default Work-lane knowledge omits workspaceId so the pod can place it
|
|
548
|
+
// (server-derived / pod-wide preferred for knowledge kinds).
|
|
549
|
+
if (!workspaceId && !opts.json) {
|
|
550
|
+
log.dim(` Placement: ${source} — workspaceId omitted.`);
|
|
551
|
+
log.dim(" Pin with --workspace <id> or --team (first product workspace).");
|
|
552
|
+
}
|
|
553
|
+
// Project pin: explicit --project (id or name) wins; otherwise the ambient
|
|
554
|
+
// lens already resolved by resolveHubConfig (SYNAP_PROJECT_ID / the active
|
|
555
|
+
// Claude session's pinned project). Previously this coordinate was simply
|
|
556
|
+
// dropped by `capture` — --pod resolved url+key but never the project lens.
|
|
557
|
+
let projectId;
|
|
558
|
+
try {
|
|
559
|
+
projectId = opts.project ? await resolveProjectArg(opts.project, cfg) : cfg.projectId;
|
|
560
|
+
}
|
|
561
|
+
catch (e) {
|
|
562
|
+
console.error(chalk.red(e.message));
|
|
323
563
|
process.exit(1);
|
|
324
564
|
}
|
|
325
565
|
const tags = opts.tags
|
|
326
566
|
? opts.tags.split(",").map((t) => t.trim()).filter(Boolean)
|
|
327
567
|
: [];
|
|
328
|
-
|
|
568
|
+
// A title is a short NAME; the claim itself stays in `ek_claim`.
|
|
569
|
+
const chosen = chooseKnowledgeTitle(opts.claim, opts.title);
|
|
570
|
+
if (!chosen.ok) {
|
|
571
|
+
console.error(chalk.red(chosen.reason));
|
|
572
|
+
process.exit(1);
|
|
573
|
+
}
|
|
574
|
+
const title = chosen.title;
|
|
329
575
|
// Every --type entry is a typed `knowledge` entity; ek_type discriminates the
|
|
330
576
|
// kind. This is "one store, type tags" (the research-canonical pattern) — NOT a
|
|
331
577
|
// residual catch-all: each row is typed by ek_type and lives in the workspace
|
|
332
578
|
// lens that supplies its domain (so no `engineering_knowledge`). A structured
|
|
333
579
|
// decision RECORD (rationale/alternatives/status) is a different artifact, reached
|
|
334
580
|
// via smart `capture "<text>"` or `create entity --profile=decision`.
|
|
335
|
-
const sessionId = opts.session ?
|
|
581
|
+
const sessionId = opts.session ? resolveActiveSessionId(cfg.podUrl) : undefined;
|
|
336
582
|
const res = await hubPost("/entities", {
|
|
337
583
|
userId,
|
|
338
|
-
workspaceId,
|
|
584
|
+
...(workspaceId ? { workspaceId } : {}),
|
|
339
585
|
profileSlug: "knowledge",
|
|
340
586
|
title,
|
|
341
587
|
...(sessionId ? { sessionId } : {}),
|
|
588
|
+
...(projectId ? { projectId } : {}),
|
|
342
589
|
properties: {
|
|
590
|
+
knowledgeForm: opts.type === "gotcha" ? "caution" : "insight",
|
|
343
591
|
ek_type: opts.type,
|
|
344
592
|
ek_claim: opts.claim,
|
|
345
593
|
...(opts.why ? { ek_why: opts.why } : {}),
|
|
346
594
|
...(opts.evidence ? { ek_evidence: opts.evidence } : {}),
|
|
347
595
|
...(tags.length > 0 ? { ek_tags: tags } : {}),
|
|
348
596
|
},
|
|
597
|
+
...(opts.content?.trim().length ? { content: opts.content } : {}),
|
|
349
598
|
}, cfg);
|
|
350
|
-
// Governance may queue the write as a proposal rather than creating
|
|
351
|
-
|
|
599
|
+
// Governance may queue the write as a proposal rather than creating
|
|
600
|
+
// directly — read the real outcome via the ONE shared detector.
|
|
601
|
+
const isProposed = writeGovernance(res) === "proposed";
|
|
602
|
+
// The pod's title rubric verdict (absent when the title is clean).
|
|
603
|
+
const titleLint = readTitleLint(res);
|
|
352
604
|
// Declare which lane + workspace + governance this capture took, so the
|
|
353
605
|
// caller always knows where its knowledge landed.
|
|
354
606
|
const report = {
|
|
355
607
|
lane: laneFromSource(source),
|
|
356
608
|
workspaceId,
|
|
357
|
-
workspaceName:
|
|
609
|
+
workspaceName: workspaceId
|
|
610
|
+
? await resolveWorkspaceName(workspaceId, cfg)
|
|
611
|
+
: "server-derived (pod-wide preferred)",
|
|
358
612
|
governance: isProposed ? "proposed" : "auto",
|
|
359
613
|
};
|
|
360
614
|
if (opts.json) {
|
|
615
|
+
const writeReceipt = res.writeReceipt;
|
|
361
616
|
if (isProposed) {
|
|
362
617
|
console.log(JSON.stringify({
|
|
363
618
|
proposed: true,
|
|
364
619
|
proposalId: res.proposalId ?? res.id,
|
|
365
620
|
reviewUrl: res.reviewUrl ?? null,
|
|
366
621
|
message: "Write queued for approval — not yet stored.",
|
|
622
|
+
title,
|
|
623
|
+
...(titleLint.length ? { titleLint } : {}),
|
|
624
|
+
...(projectId ? { requestedProjectId: projectId } : {}),
|
|
367
625
|
...laneJsonFields(report),
|
|
368
626
|
}, null, 2));
|
|
369
627
|
}
|
|
370
628
|
else {
|
|
371
|
-
console.log(JSON.stringify({
|
|
629
|
+
console.log(JSON.stringify({
|
|
630
|
+
id: res.id,
|
|
631
|
+
stored: true,
|
|
632
|
+
title,
|
|
633
|
+
...(titleLint.length ? { titleLint } : {}),
|
|
634
|
+
workspace: source,
|
|
635
|
+
...(projectId ? { requestedProjectId: projectId, linkedProjectId: writeReceipt?.projectId ?? null } : {}),
|
|
636
|
+
...laneJsonFields(report),
|
|
637
|
+
}, null, 2));
|
|
372
638
|
}
|
|
373
639
|
return;
|
|
374
640
|
}
|
|
@@ -380,18 +646,37 @@ export async function captureKnowledge(opts) {
|
|
|
380
646
|
else
|
|
381
647
|
log.dim(` Open Synap and approve the pending proposal to persist this entry.`);
|
|
382
648
|
console.log(" " + formatLaneLine(report));
|
|
649
|
+
renderProjectReceipt(res, projectId, true);
|
|
383
650
|
}
|
|
384
651
|
else {
|
|
385
|
-
log.success(`[${opts.type}] ${
|
|
652
|
+
log.success(`[${opts.type}] ${title}`);
|
|
386
653
|
log.dim(` workspace: ${source} id: ${String(res.id ?? "")}`);
|
|
387
654
|
console.log(" " + formatLaneLine(report));
|
|
655
|
+
renderProjectReceipt(res, projectId, false);
|
|
388
656
|
}
|
|
657
|
+
renderTitleLint(titleLint);
|
|
389
658
|
}
|
|
390
659
|
catch (e) {
|
|
391
660
|
renderHubError(e);
|
|
392
661
|
process.exit(1);
|
|
393
662
|
}
|
|
394
663
|
}
|
|
664
|
+
/** `writeReceipt.titleLint` from a POST /entities response; [] when clean or absent. */
|
|
665
|
+
export function readTitleLint(res) {
|
|
666
|
+
const receipt = res.writeReceipt;
|
|
667
|
+
const raw = Array.isArray(receipt?.titleLint) ? receipt.titleLint : [];
|
|
668
|
+
return raw.filter((i) => !!i && typeof i === "object" && typeof i.message === "string");
|
|
669
|
+
}
|
|
670
|
+
/** Tell the writer what to rewrite — the title was stored as sent. */
|
|
671
|
+
function renderTitleLint(issues) {
|
|
672
|
+
const defects = issues.filter((i) => i.severity === "defect");
|
|
673
|
+
if (!defects.length)
|
|
674
|
+
return;
|
|
675
|
+
log.warn(" Title stored as sent, but it should be rewritten:");
|
|
676
|
+
for (const i of defects)
|
|
677
|
+
log.dim(` - ${i.message}`);
|
|
678
|
+
log.dim(` Rewrite it with the MCP tool synap_update_entity (title), and pass --title next time.`);
|
|
679
|
+
}
|
|
395
680
|
export async function provisionAgentWorkspace(opts) {
|
|
396
681
|
try {
|
|
397
682
|
const cfg = await resolveHubConfig();
|