@synap-core/cli 1.7.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/agent-chat.d.ts +47 -0
- package/dist/commands/agent-chat.js +250 -0
- package/dist/commands/agent-chat.js.map +1 -0
- package/dist/commands/agent-run.d.ts +47 -0
- package/dist/commands/agent-run.js +301 -0
- package/dist/commands/agent-run.js.map +1 -0
- package/dist/commands/agents.js +85 -46
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/artifact.d.ts +26 -0
- package/dist/commands/artifact.js +76 -0
- package/dist/commands/artifact.js.map +1 -0
- package/dist/commands/automation.d.ts +47 -0
- package/dist/commands/automation.js +601 -0
- package/dist/commands/automation.js.map +1 -0
- package/dist/commands/bridge-setup.d.ts +66 -0
- package/dist/commands/bridge-setup.js +1112 -0
- package/dist/commands/bridge-setup.js.map +1 -0
- package/dist/commands/cap-connections.d.ts +28 -0
- package/dist/commands/cap-connections.js +224 -0
- package/dist/commands/cap-connections.js.map +1 -0
- package/dist/commands/capability.d.ts +89 -0
- package/dist/commands/capability.js +1523 -0
- package/dist/commands/capability.js.map +1 -0
- package/dist/commands/cell.d.ts +55 -0
- package/dist/commands/cell.js +277 -0
- package/dist/commands/cell.js.map +1 -0
- package/dist/commands/centrality.d.ts +20 -0
- package/dist/commands/centrality.js +94 -0
- package/dist/commands/centrality.js.map +1 -0
- package/dist/commands/connect.d.ts +2 -0
- package/dist/commands/connect.js +25 -10
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connections.js +0 -16
- package/dist/commands/connections.js.map +1 -1
- package/dist/commands/context.d.ts +22 -0
- package/dist/commands/context.js +149 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/data-extra.d.ts +14 -0
- package/dist/commands/data-extra.js +185 -0
- package/dist/commands/data-extra.js.map +1 -0
- package/dist/commands/data.d.ts +14 -10
- package/dist/commands/data.js +353 -192
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +20 -0
- package/dist/commands/diagnose.js +143 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/digest.d.ts +17 -0
- package/dist/commands/digest.js +121 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/discover.d.ts +2 -0
- package/dist/commands/discover.js +25 -8
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/doc.d.ts +39 -0
- package/dist/commands/doc.js +130 -0
- package/dist/commands/doc.js.map +1 -0
- package/dist/commands/events.d.ts +26 -0
- package/dist/commands/events.js +69 -0
- package/dist/commands/events.js.map +1 -0
- package/dist/commands/explain.d.ts +21 -0
- package/dist/commands/explain.js +251 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/facet.d.ts +29 -0
- package/dist/commands/facet.js +113 -0
- package/dist/commands/facet.js.map +1 -0
- package/dist/commands/graph.d.ts +18 -0
- package/dist/commands/graph.js +74 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/home.d.ts +12 -0
- package/dist/commands/home.js +54 -0
- package/dist/commands/home.js.map +1 -0
- package/dist/commands/import.d.ts +38 -0
- package/dist/commands/import.js +440 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.d.ts +0 -2
- package/dist/commands/init.js +97 -118
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.d.ts +9 -0
- package/dist/commands/keys.js +78 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/knowledge.d.ts +34 -18
- package/dist/commands/knowledge.js +355 -57
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/launch.d.ts +50 -0
- package/dist/commands/launch.js +790 -0
- package/dist/commands/launch.js.map +1 -0
- package/dist/commands/lens.d.ts +45 -0
- package/dist/commands/lens.js +386 -0
- package/dist/commands/lens.js.map +1 -0
- package/dist/commands/market.d.ts +209 -0
- package/dist/commands/market.js +1368 -0
- package/dist/commands/market.js.map +1 -0
- package/dist/commands/mcp.d.ts +42 -0
- package/dist/commands/mcp.js +184 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/observe.d.ts +9 -0
- package/dist/commands/observe.js +93 -0
- package/dist/commands/observe.js.map +1 -0
- package/dist/commands/open.d.ts +32 -0
- package/dist/commands/open.js +85 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/pod.d.ts +100 -0
- package/dist/commands/pod.js +359 -0
- package/dist/commands/pod.js.map +1 -0
- package/dist/commands/pods.d.ts +6 -0
- package/dist/commands/pods.js +160 -50
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.d.ts +7 -0
- package/dist/commands/proposals-actions.js +77 -0
- package/dist/commands/proposals-actions.js.map +1 -0
- package/dist/commands/providers.d.ts +38 -0
- package/dist/commands/providers.js +170 -0
- package/dist/commands/providers.js.map +1 -0
- package/dist/commands/purge.d.ts +23 -0
- package/dist/commands/purge.js +148 -0
- package/dist/commands/purge.js.map +1 -0
- package/dist/commands/raycast.d.ts +15 -0
- package/dist/commands/raycast.js +153 -0
- package/dist/commands/raycast.js.map +1 -0
- package/dist/commands/sessions.d.ts +31 -0
- package/dist/commands/sessions.js +248 -0
- package/dist/commands/sessions.js.map +1 -0
- package/dist/commands/skill-manage.d.ts +21 -0
- package/dist/commands/skill-manage.js +195 -0
- package/dist/commands/skill-manage.js.map +1 -0
- package/dist/commands/skills-commands.d.ts +26 -0
- package/dist/commands/skills-commands.js +187 -0
- package/dist/commands/skills-commands.js.map +1 -0
- package/dist/commands/skills.d.ts +26 -0
- package/dist/commands/skills.js +196 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/status.d.ts +3 -1
- package/dist/commands/status.js +231 -41
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/statusline.d.ts +24 -0
- package/dist/commands/statusline.js +450 -0
- package/dist/commands/statusline.js.map +1 -0
- package/dist/commands/subscribe.d.ts +19 -0
- package/dist/commands/subscribe.js +91 -0
- package/dist/commands/subscribe.js.map +1 -0
- package/dist/commands/tools.d.ts +30 -0
- package/dist/commands/tools.js +315 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commands/versions.d.ts +27 -0
- package/dist/commands/versions.js +277 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/commands/view.d.ts +57 -0
- package/dist/commands/view.js +195 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/commands/whoami.d.ts +21 -0
- package/dist/commands/whoami.js +129 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1524 -202
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-templates.d.ts +25 -0
- package/dist/lib/agent-templates.js +148 -0
- package/dist/lib/agent-templates.js.map +1 -0
- package/dist/lib/agents-config.d.ts +4 -1
- package/dist/lib/agents-config.js +19 -2
- package/dist/lib/agents-config.js.map +1 -1
- package/dist/lib/approval-poll.d.ts +42 -0
- package/dist/lib/approval-poll.js +52 -0
- package/dist/lib/approval-poll.js.map +1 -0
- package/dist/lib/auth.d.ts +29 -6
- package/dist/lib/auth.js +105 -94
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/bundle-version.d.ts +11 -0
- package/dist/lib/bundle-version.js +33 -0
- package/dist/lib/bundle-version.js.map +1 -0
- package/dist/lib/capture-lane.d.ts +67 -0
- package/dist/lib/capture-lane.js +136 -0
- package/dist/lib/capture-lane.js.map +1 -0
- package/dist/lib/cp-packages.d.ts +121 -0
- package/dist/lib/cp-packages.js +218 -0
- package/dist/lib/cp-packages.js.map +1 -0
- package/dist/lib/describe-lens.d.ts +46 -0
- package/dist/lib/describe-lens.js +33 -0
- package/dist/lib/describe-lens.js.map +1 -0
- package/dist/lib/hub-client.d.ts +84 -1
- package/dist/lib/hub-client.js +502 -22
- package/dist/lib/hub-client.js.map +1 -1
- package/dist/lib/installed.d.ts +51 -0
- package/dist/lib/installed.js +70 -0
- package/dist/lib/installed.js.map +1 -0
- package/dist/lib/next-steps.d.ts +61 -0
- package/dist/lib/next-steps.js +146 -0
- package/dist/lib/next-steps.js.map +1 -0
- package/dist/lib/pod.d.ts +104 -19
- package/dist/lib/pod.js +245 -57
- package/dist/lib/pod.js.map +1 -1
- package/dist/lib/project-ref.d.ts +95 -0
- package/dist/lib/project-ref.js +144 -0
- package/dist/lib/project-ref.js.map +1 -0
- package/dist/lib/project.d.ts +35 -0
- package/dist/lib/project.js +39 -0
- package/dist/lib/project.js.map +1 -0
- package/dist/lib/session-lens.d.ts +33 -0
- package/dist/lib/session-lens.js +76 -0
- package/dist/lib/session-lens.js.map +1 -0
- package/dist/lib/skill-import.d.ts +40 -0
- package/dist/lib/skill-import.js +203 -0
- package/dist/lib/skill-import.js.map +1 -0
- package/dist/lib/skills-installer.d.ts +16 -5
- package/dist/lib/skills-installer.js +132 -18
- package/dist/lib/skills-installer.js.map +1 -1
- package/dist/lib/suite.d.ts +28 -0
- package/dist/lib/suite.js +29 -0
- package/dist/lib/suite.js.map +1 -0
- package/dist/lib/superwhisper-import.d.ts +40 -0
- package/dist/lib/superwhisper-import.js +389 -0
- package/dist/lib/superwhisper-import.js.map +1 -0
- package/dist/lib/targets.d.ts +66 -2
- package/dist/lib/targets.js +914 -132
- package/dist/lib/targets.js.map +1 -1
- package/dist/lib/unwrapList.d.ts +1 -0
- package/dist/lib/unwrapList.js +20 -0
- package/dist/lib/unwrapList.js.map +1 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +10 -2
- package/dist/utils/logger.js.map +1 -1
- package/package.json +10 -4
- package/skills/agent-os/SKILL.md +212 -0
- package/skills/manifest.json +5 -0
- package/skills/onboard/SKILL.md +186 -0
- package/skills/synap/SKILL.md +1524 -104
- package/skills/synap/_order.txt +37 -0
- package/skills/synap/_skill.yaml +24 -0
- package/skills/synap/authentication.md +10 -0
- package/skills/synap/automations.md +264 -0
- package/skills/synap/capabilities.md +107 -0
- package/skills/synap/capture.md +10 -0
- package/skills/synap/cli-operations.md +107 -0
- package/skills/synap/common-mistakes.md +12 -0
- package/skills/synap/creative-loop.md +43 -0
- package/skills/synap/crm.md +117 -0
- package/skills/synap/diagnostics.md +35 -0
- package/skills/synap/digesting-a-channel.md +38 -0
- package/skills/synap/document-embeds.md +123 -0
- package/skills/synap/escalation-ladder.md +71 -0
- package/skills/synap/focus-sessions.md +47 -0
- package/skills/synap/governance-rules.md +64 -0
- package/skills/synap/governance.md +6 -6
- package/skills/synap/graph-gardening.md +21 -0
- package/skills/synap/inline-patterns.md +38 -0
- package/skills/synap/lenses.md +38 -0
- package/skills/synap/linking-principle.md +39 -0
- package/skills/synap/linking.md +1 -0
- package/skills/synap/mental-model.md +45 -0
- package/skills/synap/more.md +7 -0
- package/skills/synap/multi-entity-capture.md +10 -0
- package/skills/synap/next-action.md +37 -0
- package/skills/synap/north-star.md +17 -0
- package/skills/synap/operating-mode-rules.md +45 -0
- package/skills/synap/operating-mode.md +9 -0
- package/skills/synap/quick-reference.md +67 -0
- package/skills/synap/reading.md +43 -0
- package/skills/synap/recap.md +21 -0
- package/skills/synap/reflexes.md +46 -0
- package/skills/synap/response-style.md +21 -0
- package/skills/synap/scope.md +13 -0
- package/skills/synap/showing.md +17 -0
- package/skills/synap/user-model.md +25 -0
- package/skills/synap/viewframe-cells.md +290 -0
- package/skills/synap/work-flow.md +113 -0
- package/skills/synap/worked-examples.md +53 -0
- package/skills/synap/workspace-design.md +45 -0
- package/skills/synap/workspace-edges.md +49 -0
- package/skills/synap/writes.md +156 -0
- package/skills/synap-schema/SKILL.md +97 -6
- package/skills/synap-schema/_order.txt +13 -0
- package/skills/synap-schema/_skill.yaml +22 -0
- package/skills/synap-schema/before-you-touch.md +14 -0
- package/skills/synap-schema/common-mistakes.md +9 -0
- package/skills/synap-schema/creating-profiles.md +17 -0
- package/skills/synap-schema/discover-profiles.md +24 -0
- package/skills/synap-schema/entity-scope.md +8 -0
- package/skills/synap-schema/extend-vs-create.md +31 -0
- package/skills/synap-schema/more.md +6 -0
- package/skills/synap-schema/overlay-properties.md +22 -0
- package/skills/synap-schema/profiles.md +3 -0
- package/skills/synap-schema/property-defs.md +29 -0
- package/skills/synap-schema/read-before-write.md +50 -0
- package/skills/synap-schema/relations.md +18 -0
- package/skills/synap-schema/worked-example.md +30 -0
- package/skills/synap-ui/SKILL.md +38 -11
- package/skills/synap-ui/_order.txt +13 -0
- package/skills/synap-ui/_skill.yaml +23 -0
- package/skills/synap-ui/ai-companion.md +27 -0
- package/skills/synap-ui/arranging-bento.md +8 -0
- package/skills/synap-ui/before-you-build.md +20 -0
- package/skills/synap-ui/bento-layouts.md +35 -0
- package/skills/synap-ui/common-mistakes.md +10 -0
- package/skills/synap-ui/creating-views.md +26 -0
- package/skills/synap-ui/four-builds.md +24 -0
- package/skills/synap-ui/more.md +7 -0
- package/skills/synap-ui/proposing-vs-extending.md +11 -0
- package/skills/synap-ui/view-list.md +24 -0
- package/skills/synap-ui/views.md +3 -0
- package/skills/synap-ui/worked-example.md +18 -0
- package/skills/synap-ui/workspaces.md +47 -0
- package/templates/automations/bookmark-enrichment.automation.json +44 -0
- package/templates/automations/mail-feed.automation.json +86 -0
- package/templates/automations/url-bookmark-capture.automation.json +70 -0
- package/templates/skills/README.md +21 -0
- package/templates/skills/authoring-automations/SKILL.md +95 -0
- package/templates/skills/authoring-automations/reference/node-matrix.md +49 -0
- package/templates/skills/authoring-capabilities/SKILL.md +93 -0
- package/templates/skills/authoring-capabilities/reference/template-anatomy.md +70 -0
- package/templates/skills/authoring-playbooks/SKILL.md +102 -0
- package/templates/skills/authoring-playbooks/reference/stages-contract.md +35 -0
- package/templates/skills/authoring-playbooks/reference/worked-example.md +64 -0
- package/templates/skills/bookmark-enrichment/SKILL.md +40 -0
- package/templates/skills/coordinating-agents/SKILL.md +32 -0
- package/templates/skills/coordinating-branches/SKILL.md +27 -0
- package/templates/skills/mapping-the-server/SKILL.md +54 -0
- package/templates/skills/reading-client-progress/SKILL.md +65 -0
- package/templates/skills/routing-to-channels/SKILL.md +54 -0
- package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
- package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
- package/templates/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
- package/templates/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
- package/templates/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
- package/templates/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
- package/templates/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
- package/templates/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
- package/templates/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
- package/dist/commands/finish.d.ts +0 -25
- package/dist/commands/finish.js +0 -274
- package/dist/commands/finish.js.map +0 -1
- package/dist/commands/openclaw.d.ts +0 -40
- package/dist/commands/openclaw.js +0 -1148
- package/dist/commands/openclaw.js.map +0 -1
- package/dist/commands/security-audit.d.ts +0 -12
- package/dist/commands/security-audit.js +0 -100
- package/dist/commands/security-audit.js.map +0 -1
- package/dist/lib/hardening.d.ts +0 -18
- package/dist/lib/hardening.js +0 -214
- package/dist/lib/hardening.js.map +0 -1
- package/dist/lib/templates.d.ts +0 -11
- package/dist/lib/templates.js +0 -13
- package/dist/lib/templates.js.map +0 -1
- package/dist/templates/agent-os.json +0 -3090
- package/node_modules/@synap/hub-rest-client/dist/index.cjs +0 -881
- package/node_modules/@synap/hub-rest-client/dist/index.d.cts +0 -907
- package/node_modules/@synap/hub-rest-client/dist/index.d.ts +0 -907
- package/node_modules/@synap/hub-rest-client/dist/index.js +0 -851
- package/node_modules/@synap/hub-rest-client/package.json +0 -45
- package/node_modules/@synap/hub-rest-client/src/client.ts +0 -1143
- package/node_modules/@synap/hub-rest-client/src/errors.ts +0 -30
- package/node_modules/@synap/hub-rest-client/src/index.ts +0 -111
- package/node_modules/@synap/hub-rest-client/src/setup.ts +0 -77
- package/node_modules/@synap/hub-rest-client/src/types.ts +0 -639
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* synap keys — Manage pod API keys
|
|
3
|
+
*
|
|
4
|
+
* Subcommands: rotate
|
|
5
|
+
*/
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import ora from "ora";
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import os from "node:os";
|
|
11
|
+
import { resolveHubConfig, hubPost, HubError, renderHubError } from "../lib/hub-client.js";
|
|
12
|
+
import { log } from "../utils/logger.js";
|
|
13
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
14
|
+
const CONFIG_FILE = path.join(os.homedir(), ".synap", "config.json");
|
|
15
|
+
function updateConfigKey(newApiKey) {
|
|
16
|
+
const raw = fs.readFileSync(CONFIG_FILE, "utf-8");
|
|
17
|
+
const config = JSON.parse(raw);
|
|
18
|
+
const activePod = config.activePod;
|
|
19
|
+
const pods = config.pods;
|
|
20
|
+
if (activePod && pods && pods[activePod]) {
|
|
21
|
+
pods[activePod].hubApiKey = newApiKey;
|
|
22
|
+
config.pods = pods;
|
|
23
|
+
}
|
|
24
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
25
|
+
}
|
|
26
|
+
export async function keysRotate(opts) {
|
|
27
|
+
let cfg;
|
|
28
|
+
try {
|
|
29
|
+
cfg = await resolveHubConfig({ podUrl: opts.podUrl });
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
log.error(err.message);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const spinner = ora({ text: "Rotating CLI key…", color: "cyan" }).start();
|
|
36
|
+
let result;
|
|
37
|
+
try {
|
|
38
|
+
result = (await hubPost("/keys/rotate-cli", {}, cfg));
|
|
39
|
+
spinner.succeed(chalk.green("Key rotated"));
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
spinner.fail(chalk.red("Failed to rotate key"));
|
|
43
|
+
if (err instanceof HubError && (err.status === 401 || err.status === 403)) {
|
|
44
|
+
log.error("The current key is already invalid (401/403).");
|
|
45
|
+
log.dim("Run `synap init` to fully re-provision your credentials.");
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
renderHubError(err);
|
|
49
|
+
}
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
// Update config file and current process env
|
|
53
|
+
try {
|
|
54
|
+
updateConfigKey(result.apiKey);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
log.warn(`Key rotated but could not update config file: ${err.message}`);
|
|
58
|
+
log.dim(`Set it manually: SYNAP_HUB_API_KEY=${result.apiKey}`);
|
|
59
|
+
}
|
|
60
|
+
process.env.SYNAP_HUB_API_KEY = result.apiKey;
|
|
61
|
+
// Print scope table
|
|
62
|
+
console.log();
|
|
63
|
+
log.heading("New key details");
|
|
64
|
+
console.log();
|
|
65
|
+
console.log(` ${chalk.dim("Key ID:")} ${result.keyId}`);
|
|
66
|
+
console.log();
|
|
67
|
+
if (result.scopes && result.scopes.length > 0) {
|
|
68
|
+
console.log(` ${chalk.dim("Scopes:")}`);
|
|
69
|
+
for (const scope of result.scopes) {
|
|
70
|
+
console.log(` ${chalk.green("✓")} ${scope}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log(` ${chalk.dim("Scopes: (none returned)")}`);
|
|
75
|
+
}
|
|
76
|
+
console.log();
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,36 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* synap capture
|
|
2
|
+
* synap capture — the one canonical structured-WRITE verb.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* SMART MODE (no --type): `synap capture "free text"`
|
|
5
|
+
* → POST /capture/structure (AI pipeline: proposals + relations + followUp)
|
|
6
|
+
* → renders a proposal table, prompts y/N, then POST /capture/execute.
|
|
7
|
+
*
|
|
8
|
+
* TYPED MODE (--type): `synap capture --type gotcha --claim "…" [--why] [--evidence] [--tags]`
|
|
9
|
+
* → POST /entities as a typed `knowledge` entity; `ek_type` (gotcha|lesson|decision|
|
|
10
|
+
* reference) discriminates the kind — ONE store, type tags (the canonical pattern,
|
|
11
|
+
* NOT a residual dump). The workspace lens supplies the domain (no
|
|
12
|
+
* `engineering_knowledge`). A formal decision RECORD (rationale/alternatives/status
|
|
13
|
+
* lifecycle) comes from smart `capture "<text>"` or `create entity --profile=decision`.
|
|
14
|
+
*
|
|
15
|
+
* Workspace routing: --workspace > --team (first product ws) > memory ws (default,
|
|
16
|
+
* auto-approved, agent-private) > active ws.
|
|
7
17
|
*/
|
|
8
|
-
interface BaseOpts {
|
|
9
|
-
podUrl?: string;
|
|
10
|
-
apiKey?: string;
|
|
11
|
-
}
|
|
12
18
|
export type KnowledgeType = "gotcha" | "lesson" | "decision" | "reference";
|
|
13
19
|
export interface CaptureOpts {
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
/** Smart mode: positional free-text (no --type). When present, uses AI /capture/structure pipeline. */
|
|
21
|
+
text?: string;
|
|
22
|
+
/** Typed mode: one of gotcha|lesson|decision|reference */
|
|
23
|
+
type?: KnowledgeType;
|
|
24
|
+
claim?: string;
|
|
16
25
|
why?: string;
|
|
17
26
|
evidence?: string;
|
|
18
27
|
tags?: string;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
type?: KnowledgeType;
|
|
23
|
-
tags?: string;
|
|
24
|
-
limit?: string;
|
|
28
|
+
/** Override to first product workspace instead of the active workspace */
|
|
29
|
+
team?: boolean;
|
|
30
|
+
/** Explicit workspace override — highest priority */
|
|
25
31
|
workspace?: string;
|
|
32
|
+
/**
|
|
33
|
+
* GLOBAL lane: write a pod-wide procedural runbook to `knowledge_keys`
|
|
34
|
+
* (cross-cutting best-practice/how-to, visible in every workspace) instead of
|
|
35
|
+
* a domain `knowledge` entity in the active workspace.
|
|
36
|
+
*/
|
|
37
|
+
global?: boolean;
|
|
38
|
+
/** Optional stable key (namespace:slug) for a --global runbook; derived if absent. */
|
|
39
|
+
key?: string;
|
|
26
40
|
json?: boolean;
|
|
41
|
+
/** Skip the y/N confirmation prompt (smart mode only) */
|
|
42
|
+
yes?: boolean;
|
|
43
|
+
/** Link the captured knowledge to the active session */
|
|
44
|
+
session?: boolean;
|
|
27
45
|
}
|
|
28
46
|
export declare function captureKnowledge(opts: CaptureOpts): Promise<void>;
|
|
29
|
-
export declare function recallStructured(query: string, opts: RecallStructuredOpts): Promise<void>;
|
|
30
47
|
export declare function provisionAgentWorkspace(opts: {
|
|
31
48
|
agentUserId?: string;
|
|
32
49
|
name?: string;
|
|
33
50
|
use?: boolean;
|
|
34
51
|
json?: boolean;
|
|
35
52
|
}): Promise<void>;
|
|
36
|
-
export {};
|
|
@@ -1,33 +1,344 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* synap capture
|
|
2
|
+
* synap capture — the one canonical structured-WRITE verb.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* SMART MODE (no --type): `synap capture "free text"`
|
|
5
|
+
* → POST /capture/structure (AI pipeline: proposals + relations + followUp)
|
|
6
|
+
* → renders a proposal table, prompts y/N, then POST /capture/execute.
|
|
7
|
+
*
|
|
8
|
+
* TYPED MODE (--type): `synap capture --type gotcha --claim "…" [--why] [--evidence] [--tags]`
|
|
9
|
+
* → POST /entities as a typed `knowledge` entity; `ek_type` (gotcha|lesson|decision|
|
|
10
|
+
* reference) discriminates the kind — ONE store, type tags (the canonical pattern,
|
|
11
|
+
* NOT a residual dump). The workspace lens supplies the domain (no
|
|
12
|
+
* `engineering_knowledge`). A formal decision RECORD (rationale/alternatives/status
|
|
13
|
+
* lifecycle) comes from smart `capture "<text>"` or `create entity --profile=decision`.
|
|
14
|
+
*
|
|
15
|
+
* Workspace routing: --workspace > --team (first product ws) > memory ws (default,
|
|
16
|
+
* auto-approved, agent-private) > active ws.
|
|
7
17
|
*/
|
|
8
18
|
import chalk from "chalk";
|
|
19
|
+
import * as readline from "node:readline/promises";
|
|
20
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
9
21
|
import { log } from "../utils/logger.js";
|
|
10
|
-
import { resolveHubConfig, resolveUserId, hubPost,
|
|
22
|
+
import { resolveHubConfig, resolveUserId, hubPost, readActiveSessionId, renderHubError, } from "../lib/hub-client.js";
|
|
23
|
+
import { getAgentWorkspaceRouting } from "../lib/pod.js";
|
|
24
|
+
import { laneFromSource, resolveWorkspaceName, formatLaneLine, laneJsonFields, } from "../lib/capture-lane.js";
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the workspace for a DOMAIN capture (the `knowledge` entity, the Work
|
|
27
|
+
* lane). Knowledge is workspace-scoped, so the destination IS the separation:
|
|
28
|
+
* a Builder lesson stays in Builder, a marketing one in marketing.
|
|
29
|
+
*
|
|
30
|
+
* Priority: --workspace > --team (first product ws) > active ws.
|
|
31
|
+
*
|
|
32
|
+
* NOTE: the agent-memory ("AI-self") lane was removed — the AI no longer dumps
|
|
33
|
+
* captures into a private agent workspace. Everything it learns routes to a real
|
|
34
|
+
* lane: Work (here), Global (`--global` → knowledge_keys), or User
|
|
35
|
+
* (`record_observation` → user_observation). The per-adjunct memory workspace is
|
|
36
|
+
* being decommissioned.
|
|
37
|
+
*/
|
|
38
|
+
async function resolveKnowledgeWorkspace(opts, _cfg, activeWorkspaceId) {
|
|
39
|
+
if (opts.workspace) {
|
|
40
|
+
return { workspaceId: opts.workspace, source: "explicit" };
|
|
41
|
+
}
|
|
42
|
+
if (opts.team) {
|
|
43
|
+
const routing = getAgentWorkspaceRouting();
|
|
44
|
+
const teamWs = routing?.productWorkspaceIds?.[0];
|
|
45
|
+
return { workspaceId: teamWs ?? activeWorkspaceId, source: teamWs ? "team" : "active (no team workspace configured)" };
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
workspaceId: activeWorkspaceId,
|
|
49
|
+
source: activeWorkspaceId ? "active" : "active (run `synap use <id>` to set a workspace)",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Slugify free text into a knowledge_keys slug fragment. */
|
|
53
|
+
function slugify(text) {
|
|
54
|
+
return text
|
|
55
|
+
.toLowerCase()
|
|
56
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
57
|
+
.replace(/^-+|-+$/g, "")
|
|
58
|
+
.slice(0, 80) || "entry";
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* GLOBAL lane: write a pod-wide procedural runbook to `knowledge_keys`.
|
|
62
|
+
* Cross-cutting best-practice/how-to, addressed by a stable `namespace:slug` key
|
|
63
|
+
* and visible in every workspace (pod-wide). The kind (gotcha/lesson/decision/
|
|
64
|
+
* reference) becomes the namespace; the claim derives the slug unless --key given.
|
|
65
|
+
*/
|
|
66
|
+
async function captureGlobalRunbook(opts, cfg, authorUserId) {
|
|
67
|
+
const type = opts.type ?? "reference";
|
|
68
|
+
const claim = opts.claim ?? opts.text ?? "";
|
|
69
|
+
const key = opts.key ?? `${type}:${slugify(claim)}`;
|
|
70
|
+
const [namespace, ...slugParts] = key.split(":");
|
|
71
|
+
const slug = slugParts.join(":") || slugify(claim);
|
|
72
|
+
const valueParts = [claim];
|
|
73
|
+
if (opts.why)
|
|
74
|
+
valueParts.push(`\n**Why:** ${opts.why}`);
|
|
75
|
+
if (opts.evidence)
|
|
76
|
+
valueParts.push(`\n**Evidence:** ${opts.evidence}`);
|
|
77
|
+
if (opts.tags)
|
|
78
|
+
valueParts.push(`\n_tags: ${opts.tags}_`);
|
|
79
|
+
const res = await hubPost("/knowledge", {
|
|
80
|
+
key,
|
|
81
|
+
namespace,
|
|
82
|
+
slug,
|
|
83
|
+
value: valueParts.join("\n"),
|
|
84
|
+
author: authorUserId,
|
|
85
|
+
// workspaceId omitted → pod-wide (null). The Global lane is, by definition,
|
|
86
|
+
// cross-workspace. (Workspace-scoped knowledge_keys await a backend fix —
|
|
87
|
+
// POST /knowledge currently drops workspaceId; domain knowledge uses the
|
|
88
|
+
// `knowledge` entity instead, which IS workspace-scoped.)
|
|
89
|
+
}, cfg);
|
|
90
|
+
const report = {
|
|
91
|
+
lane: "global",
|
|
92
|
+
workspaceId: undefined,
|
|
93
|
+
workspaceName: "pod-wide",
|
|
94
|
+
governance: "auto",
|
|
95
|
+
};
|
|
96
|
+
if (opts.json) {
|
|
97
|
+
console.log(JSON.stringify({ key, id: res.id, stored: true, ...laneJsonFields(report) }, null, 2));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
log.success(`[${type}] ${claim.slice(0, 80)}`);
|
|
101
|
+
log.dim(` key: ${key}`);
|
|
102
|
+
console.log(" " + formatLaneLine(report));
|
|
103
|
+
}
|
|
104
|
+
/** Render the /capture/structure result as a compact human-readable summary. */
|
|
105
|
+
function renderStructureResult(result) {
|
|
106
|
+
const { proposals, relations, followUp, degraded } = result;
|
|
107
|
+
if (degraded) {
|
|
108
|
+
log.warn("AI structuring unavailable — degraded fallback.");
|
|
109
|
+
}
|
|
110
|
+
if (proposals.length === 0) {
|
|
111
|
+
log.dim("No entity proposals extracted.");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
log.heading("Proposed entities");
|
|
115
|
+
// Column widths
|
|
116
|
+
const typeW = Math.min(18, Math.max(6, ...proposals.map((p) => p.profileSlug.length)));
|
|
117
|
+
const titleW = Math.min(48, Math.max(10, ...proposals.map((p) => p.title.length)));
|
|
118
|
+
const header = [
|
|
119
|
+
chalk.bold("#".padEnd(3)),
|
|
120
|
+
chalk.bold("Type".padEnd(typeW)),
|
|
121
|
+
chalk.bold("Title".padEnd(titleW)),
|
|
122
|
+
].join(" ");
|
|
123
|
+
console.log(" " + header);
|
|
124
|
+
console.log(" " + chalk.dim("-".repeat(3 + 2 + typeW + 2 + titleW)));
|
|
125
|
+
for (let i = 0; i < proposals.length; i++) {
|
|
126
|
+
const p = proposals[i];
|
|
127
|
+
const row = [
|
|
128
|
+
chalk.dim(String(i + 1).padEnd(3)),
|
|
129
|
+
chalk.cyan(p.profileSlug.slice(0, typeW).padEnd(typeW)),
|
|
130
|
+
p.title.slice(0, titleW).padEnd(titleW),
|
|
131
|
+
].join(" ");
|
|
132
|
+
console.log(" " + row);
|
|
133
|
+
if (p.description) {
|
|
134
|
+
log.dim(` ${p.description.slice(0, 80)}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (relations.length > 0) {
|
|
138
|
+
log.blank();
|
|
139
|
+
log.dim(` ${relations.length} relation${relations.length !== 1 ? "s" : ""} will be created.`);
|
|
140
|
+
}
|
|
141
|
+
if (result.targetWorkspaceId || result.targetProjectId) {
|
|
142
|
+
log.blank();
|
|
143
|
+
if (result.targetWorkspaceId) {
|
|
144
|
+
const conf = typeof result.targetWorkspaceConfidence === "number"
|
|
145
|
+
? ` (${Math.round(result.targetWorkspaceConfidence * 100)}%)`
|
|
146
|
+
: "";
|
|
147
|
+
log.dim(` → workspace: ${result.targetWorkspaceId}${conf}`);
|
|
148
|
+
if (result.targetWorkspaceReason) {
|
|
149
|
+
log.dim(` ${result.targetWorkspaceReason.slice(0, 90)}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (result.targetProjectId) {
|
|
153
|
+
const conf = typeof result.targetProjectConfidence === "number"
|
|
154
|
+
? ` (${Math.round(result.targetProjectConfidence * 100)}%)`
|
|
155
|
+
: "";
|
|
156
|
+
log.dim(` → project: ${result.targetProjectId}${conf}`);
|
|
157
|
+
if (result.targetProjectReason) {
|
|
158
|
+
log.dim(` ${result.targetProjectReason.slice(0, 90)}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// followUp may be a bare string (previously dropped — the `.question` guard
|
|
163
|
+
// never matched) or a { question, suggestions[] } object (chips previously
|
|
164
|
+
// rendered as "[object Object]"). Handle both; render each chip by its label.
|
|
165
|
+
if (followUp) {
|
|
166
|
+
const question = typeof followUp === "string" ? followUp : followUp.question;
|
|
167
|
+
if (question) {
|
|
168
|
+
log.blank();
|
|
169
|
+
log.info(`Follow-up: ${question}`);
|
|
170
|
+
const chips = typeof followUp === "string" ? [] : followUp.suggestions ?? [];
|
|
171
|
+
for (const c of chips) {
|
|
172
|
+
log.dim(` · ${c.label ?? c.value}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
async function runSmartCapture(text, opts) {
|
|
178
|
+
const cfg = await resolveHubConfig();
|
|
179
|
+
const userId = await resolveUserId(cfg);
|
|
180
|
+
const { workspaceId, source } = await resolveKnowledgeWorkspace(opts, cfg, cfg.workspaceId);
|
|
181
|
+
if (!workspaceId) {
|
|
182
|
+
console.error(chalk.red("No workspace set. Run:\n" +
|
|
183
|
+
" synap connect (sets up memory + team workspace routing)\n" +
|
|
184
|
+
" synap use <workspace-id> (manual override)"));
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
// 1. Structure
|
|
188
|
+
const smartSessionId = opts.session ? readActiveSessionId() : undefined;
|
|
189
|
+
const structureBody = { userId, text, workspaceId, ...(smartSessionId ? { sessionId: smartSessionId } : {}) };
|
|
190
|
+
const structureRes = await hubPost("/capture/structure", structureBody, cfg);
|
|
191
|
+
// Explicit --workspace is a deliberate pin: send it as-is, no AI routing hints.
|
|
192
|
+
// Otherwise forward the AI's routing signal and let the backend decide
|
|
193
|
+
// (auto = AI target wins over ambient when confidence is high enough AND the
|
|
194
|
+
// user is a member). Project from structure is forwarded when present.
|
|
195
|
+
const isExplicitOverride = Boolean(opts.workspace);
|
|
196
|
+
const routingFields = isExplicitOverride
|
|
197
|
+
? {}
|
|
198
|
+
: {
|
|
199
|
+
workspaceRouting: "auto",
|
|
200
|
+
aiWorkspaceId: structureRes.targetWorkspaceId,
|
|
201
|
+
aiWorkspaceConfidence: structureRes.targetWorkspaceConfidence,
|
|
202
|
+
aiWorkspaceReason: structureRes.targetWorkspaceReason,
|
|
203
|
+
};
|
|
204
|
+
if (structureRes.targetProjectId) {
|
|
205
|
+
routingFields.projectId = structureRes.targetProjectId;
|
|
206
|
+
}
|
|
207
|
+
if (opts.json) {
|
|
208
|
+
// --json without --yes: print structure result and exit
|
|
209
|
+
if (!opts.yes) {
|
|
210
|
+
console.log(JSON.stringify(structureRes, null, 2));
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
// --json + --yes: also execute and print combined result
|
|
214
|
+
const executeRes = await hubPost("/capture/execute", {
|
|
215
|
+
userId,
|
|
216
|
+
workspaceId,
|
|
217
|
+
...(smartSessionId ? { sessionId: smartSessionId } : {}),
|
|
218
|
+
...routingFields,
|
|
219
|
+
entities: structureRes.proposals,
|
|
220
|
+
relations: structureRes.relations ?? [],
|
|
221
|
+
}, cfg);
|
|
222
|
+
const report = await buildSmartLaneReport(executeRes, workspaceId, source, cfg);
|
|
223
|
+
console.log(JSON.stringify({ structure: structureRes, execute: executeRes, ...laneJsonFields(report) }, null, 2));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
// 2. Render proposals
|
|
227
|
+
renderStructureResult(structureRes);
|
|
228
|
+
const count = structureRes.proposals?.length ?? 0;
|
|
229
|
+
if (count === 0)
|
|
230
|
+
return;
|
|
231
|
+
// 3. Confirm
|
|
232
|
+
let confirmed = opts.yes ?? false;
|
|
233
|
+
if (!confirmed) {
|
|
234
|
+
log.blank();
|
|
235
|
+
const rl = readline.createInterface({ input, output });
|
|
236
|
+
try {
|
|
237
|
+
const answer = await rl.question(chalk.bold(` Create ${count} entr${count !== 1 ? "ies" : "y"}? [y/N] `));
|
|
238
|
+
confirmed = answer.trim().toLowerCase() === "y";
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
rl.close();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (!confirmed) {
|
|
245
|
+
log.dim("Aborted.");
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
// 4. Execute
|
|
249
|
+
const executeRes = await hubPost("/capture/execute", {
|
|
250
|
+
userId,
|
|
251
|
+
workspaceId,
|
|
252
|
+
...(smartSessionId ? { sessionId: smartSessionId } : {}),
|
|
253
|
+
...routingFields,
|
|
254
|
+
entities: structureRes.proposals,
|
|
255
|
+
relations: structureRes.relations ?? [],
|
|
256
|
+
}, cfg);
|
|
257
|
+
const created = executeRes.entitiesCreated
|
|
258
|
+
?? executeRes.created
|
|
259
|
+
?? count;
|
|
260
|
+
log.success(`${created} entr${created !== 1 ? "ies" : "y"} created.`);
|
|
261
|
+
if (executeRes.relationsCreated) {
|
|
262
|
+
log.dim(` ${executeRes.relationsCreated} relation${Number(executeRes.relationsCreated) !== 1 ? "s" : ""} created.`);
|
|
263
|
+
}
|
|
264
|
+
if (executeRes.movedToWorkspace) {
|
|
265
|
+
log.dim(` → filed into workspace ${String(executeRes.movedToWorkspace)}`);
|
|
266
|
+
}
|
|
267
|
+
const report = await buildSmartLaneReport(executeRes, workspaceId, source, cfg);
|
|
268
|
+
console.log(" " + formatLaneLine(report));
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Build the lane report for a smart-capture execute response. Smart capture may
|
|
272
|
+
* land directly or be queued as proposals — detect the latter from the execute
|
|
273
|
+
* payload (proposed/proposalsCreated/status) and fall back to auto otherwise.
|
|
274
|
+
*/
|
|
275
|
+
async function buildSmartLaneReport(executeRes, workspaceId, source, cfg) {
|
|
276
|
+
const isProposed = executeRes.status === "proposed" ||
|
|
277
|
+
Boolean(executeRes.proposalId) ||
|
|
278
|
+
Number(executeRes.proposalsCreated ?? 0) > 0;
|
|
279
|
+
return {
|
|
280
|
+
lane: laneFromSource(source),
|
|
281
|
+
workspaceId,
|
|
282
|
+
workspaceName: await resolveWorkspaceName(workspaceId, cfg),
|
|
283
|
+
governance: isProposed ? "proposed" : "auto",
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
// ─── Legacy engineering-memory capture ────────────────────────────────────────
|
|
11
287
|
export async function captureKnowledge(opts) {
|
|
12
288
|
try {
|
|
289
|
+
// Mutual exclusion: smart mode (positional text) and typed mode (--type/--claim)
|
|
290
|
+
// are two distinct flows. Mixing them silently drops one — fail loud instead.
|
|
291
|
+
if (opts.text !== undefined && opts.type !== undefined) {
|
|
292
|
+
console.error(chalk.red("Cannot mix smart mode (positional text) with typed mode (--type/--claim)."));
|
|
293
|
+
console.error(chalk.dim(" Use one: `synap capture \"free text\"` OR `synap capture --type gotcha --claim \"…\"`"));
|
|
294
|
+
process.exit(1);
|
|
295
|
+
}
|
|
296
|
+
// Smart mode: positional text with no --type
|
|
297
|
+
if (opts.text !== undefined && opts.type === undefined) {
|
|
298
|
+
await runSmartCapture(opts.text, opts);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
// Legacy mode: --type is required
|
|
302
|
+
if (!opts.type) {
|
|
303
|
+
console.error(chalk.red("Missing required option: --type <gotcha|lesson|decision|reference>"));
|
|
304
|
+
console.error(chalk.dim(" Or pass free text as a positional arg for smart capture: synap capture \"your text\""));
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
if (!opts.claim) {
|
|
308
|
+
console.error(chalk.red("Missing required option: --claim <text>"));
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
13
311
|
const cfg = await resolveHubConfig();
|
|
14
312
|
const userId = await resolveUserId(cfg);
|
|
15
|
-
|
|
313
|
+
// GLOBAL lane: pod-wide procedural runbook → knowledge_keys.
|
|
314
|
+
if (opts.global) {
|
|
315
|
+
await captureGlobalRunbook(opts, cfg, userId);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const { workspaceId, source } = await resolveKnowledgeWorkspace(opts, cfg, cfg.workspaceId);
|
|
16
319
|
if (!workspaceId) {
|
|
17
320
|
console.error(chalk.red("No workspace set. Run:\n" +
|
|
18
|
-
" synap
|
|
19
|
-
" synap use <workspace-id>
|
|
321
|
+
" synap connect (sets up memory + team workspace routing)\n" +
|
|
322
|
+
" synap use <workspace-id> (manual override)"));
|
|
20
323
|
process.exit(1);
|
|
21
324
|
}
|
|
22
325
|
const tags = opts.tags
|
|
23
326
|
? opts.tags.split(",").map((t) => t.trim()).filter(Boolean)
|
|
24
327
|
: [];
|
|
25
328
|
const title = opts.claim.slice(0, 120);
|
|
329
|
+
// Every --type entry is a typed `knowledge` entity; ek_type discriminates the
|
|
330
|
+
// kind. This is "one store, type tags" (the research-canonical pattern) — NOT a
|
|
331
|
+
// residual catch-all: each row is typed by ek_type and lives in the workspace
|
|
332
|
+
// lens that supplies its domain (so no `engineering_knowledge`). A structured
|
|
333
|
+
// decision RECORD (rationale/alternatives/status) is a different artifact, reached
|
|
334
|
+
// via smart `capture "<text>"` or `create entity --profile=decision`.
|
|
335
|
+
const sessionId = opts.session ? readActiveSessionId() : undefined;
|
|
26
336
|
const res = await hubPost("/entities", {
|
|
27
337
|
userId,
|
|
28
338
|
workspaceId,
|
|
29
|
-
profileSlug: "
|
|
339
|
+
profileSlug: "knowledge",
|
|
30
340
|
title,
|
|
341
|
+
...(sessionId ? { sessionId } : {}),
|
|
31
342
|
properties: {
|
|
32
343
|
ek_type: opts.type,
|
|
33
344
|
ek_claim: opts.claim,
|
|
@@ -36,61 +347,48 @@ export async function captureKnowledge(opts) {
|
|
|
36
347
|
...(tags.length > 0 ? { ek_tags: tags } : {}),
|
|
37
348
|
},
|
|
38
349
|
}, cfg);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
console.error(chalk.red("Error: " + e.message));
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
export async function recallStructured(query, opts) {
|
|
53
|
-
try {
|
|
54
|
-
const cfg = await resolveHubConfig(opts);
|
|
55
|
-
const limit = parseInt(opts.limit ?? "10", 10);
|
|
56
|
-
const params = {
|
|
57
|
-
profileSlug: "engineering_knowledge",
|
|
58
|
-
q: query,
|
|
59
|
-
limit,
|
|
350
|
+
// Governance may queue the write as a proposal rather than creating directly
|
|
351
|
+
const isProposed = res.status === "proposed" || Boolean(res.proposalId);
|
|
352
|
+
// Declare which lane + workspace + governance this capture took, so the
|
|
353
|
+
// caller always knows where its knowledge landed.
|
|
354
|
+
const report = {
|
|
355
|
+
lane: laneFromSource(source),
|
|
356
|
+
workspaceId,
|
|
357
|
+
workspaceName: await resolveWorkspaceName(workspaceId, cfg),
|
|
358
|
+
governance: isProposed ? "proposed" : "auto",
|
|
60
359
|
};
|
|
61
|
-
const workspaceId = opts.workspace ?? cfg.workspaceId;
|
|
62
|
-
if (workspaceId)
|
|
63
|
-
params.workspaceId = workspaceId;
|
|
64
|
-
const res = await hubGet("/entities", params, cfg);
|
|
65
|
-
const entities = (res.entities ?? res.items ?? res);
|
|
66
|
-
let list = Array.isArray(entities) ? entities : [];
|
|
67
|
-
if (opts.type) {
|
|
68
|
-
list = list.filter((e) => {
|
|
69
|
-
const props = (e.properties ?? {});
|
|
70
|
-
return props.ek_type === opts.type;
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
360
|
if (opts.json) {
|
|
74
|
-
|
|
361
|
+
if (isProposed) {
|
|
362
|
+
console.log(JSON.stringify({
|
|
363
|
+
proposed: true,
|
|
364
|
+
proposalId: res.proposalId ?? res.id,
|
|
365
|
+
reviewUrl: res.reviewUrl ?? null,
|
|
366
|
+
message: "Write queued for approval — not yet stored.",
|
|
367
|
+
...laneJsonFields(report),
|
|
368
|
+
}, null, 2));
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
console.log(JSON.stringify({ id: res.id, stored: true, workspace: source, ...laneJsonFields(report) }, null, 2));
|
|
372
|
+
}
|
|
75
373
|
return;
|
|
76
374
|
}
|
|
77
|
-
if (
|
|
78
|
-
log.
|
|
79
|
-
|
|
375
|
+
if (isProposed) {
|
|
376
|
+
log.warn(`Queued for approval — not yet stored.`);
|
|
377
|
+
log.dim(` The target workspace requires human review for agent writes.`);
|
|
378
|
+
if (res.reviewUrl)
|
|
379
|
+
log.dim(` Review: ${String(res.reviewUrl)}`);
|
|
380
|
+
else
|
|
381
|
+
log.dim(` Open Synap and approve the pending proposal to persist this entry.`);
|
|
382
|
+
console.log(" " + formatLaneLine(report));
|
|
80
383
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const why = props.ek_why ? `\n why: ${props.ek_why}` : "";
|
|
86
|
-
const tags = Array.isArray(props.ek_tags) && props.ek_tags.length > 0
|
|
87
|
-
? chalk.dim(` [${props.ek_tags.join(", ")}]`)
|
|
88
|
-
: "";
|
|
89
|
-
console.log(` ${chalk.cyan(type.padEnd(10))} ${claim}${tags}${chalk.dim(why)}`);
|
|
384
|
+
else {
|
|
385
|
+
log.success(`[${opts.type}] ${opts.claim.slice(0, 80)}`);
|
|
386
|
+
log.dim(` workspace: ${source} id: ${String(res.id ?? "")}`);
|
|
387
|
+
console.log(" " + formatLaneLine(report));
|
|
90
388
|
}
|
|
91
389
|
}
|
|
92
390
|
catch (e) {
|
|
93
|
-
|
|
391
|
+
renderHubError(e);
|
|
94
392
|
process.exit(1);
|
|
95
393
|
}
|
|
96
394
|
}
|
|
@@ -120,7 +418,7 @@ export async function provisionAgentWorkspace(opts) {
|
|
|
120
418
|
}
|
|
121
419
|
}
|
|
122
420
|
catch (e) {
|
|
123
|
-
|
|
421
|
+
renderHubError(e);
|
|
124
422
|
process.exit(1);
|
|
125
423
|
}
|
|
126
424
|
}
|