@synap-core/cli 1.8.0 → 1.11.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.js +3 -4
- package/dist/commands/agent-run.js.map +1 -1
- package/dist/commands/agents.js +85 -46
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/automation.js +2 -1
- package/dist/commands/automation.js.map +1 -1
- 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 +1594 -0
- package/dist/commands/capability.js.map +1 -0
- package/dist/commands/centrality.d.ts +20 -0
- package/dist/commands/centrality.js +95 -0
- package/dist/commands/centrality.js.map +1 -0
- package/dist/commands/connect.d.ts +2 -0
- package/dist/commands/connect.js +16 -35
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/context.js +6 -7
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/data-extra.d.ts +1 -0
- package/dist/commands/data-extra.js +41 -14
- package/dist/commands/data-extra.js.map +1 -1
- package/dist/commands/data.d.ts +4 -4
- package/dist/commands/data.js +254 -187
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +20 -0
- package/dist/commands/diagnose.js +186 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/digest.d.ts +17 -0
- package/dist/commands/digest.js +122 -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 +14 -0
- package/dist/commands/doc.js +61 -4
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/doctor.d.ts +21 -0
- package/dist/commands/doctor.js +189 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/events.js +5 -2
- package/dist/commands/events.js.map +1 -1
- package/dist/commands/explain.d.ts +1 -1
- package/dist/commands/explain.js +18 -15
- package/dist/commands/explain.js.map +1 -1
- 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.js +7 -4
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/import.d.ts +38 -0
- package/dist/commands/import.js +471 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.js +35 -16
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.js +3 -4
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/knowledge.d.ts +8 -0
- package/dist/commands/knowledge.js +308 -33
- 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-authoring.d.ts +45 -0
- package/dist/commands/market-authoring.js +225 -0
- package/dist/commands/market-authoring.js.map +1 -0
- package/dist/commands/market.d.ts +224 -0
- package/dist/commands/market.js +1643 -0
- package/dist/commands/market.js.map +1 -0
- package/dist/commands/mcp.d.ts +64 -0
- package/dist/commands/mcp.js +265 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/observe.js +14 -11
- package/dist/commands/observe.js.map +1 -1
- package/dist/commands/open.d.ts +21 -4
- package/dist/commands/open.js +45 -4
- package/dist/commands/open.js.map +1 -1
- 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 +15 -0
- package/dist/commands/pods.js +233 -17
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.js +43 -3
- package/dist/commands/proposals-actions.js.map +1 -1
- 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.js +47 -22
- package/dist/commands/sessions.js.map +1 -1
- 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.js +2 -1
- package/dist/commands/skills-commands.js.map +1 -1
- package/dist/commands/skills.js +7 -4
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +3 -1
- package/dist/commands/status.js +166 -14
- 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.js +2 -2
- package/dist/commands/subscribe.js.map +1 -1
- package/dist/commands/template.d.ts +42 -0
- package/dist/commands/template.js +191 -0
- package/dist/commands/template.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/upload.d.ts +30 -0
- package/dist/commands/upload.js +155 -0
- package/dist/commands/upload.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.js +3 -2
- package/dist/commands/view.js.map +1 -1
- 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.js +894 -60
- package/dist/index.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 +30 -12
- package/dist/lib/capture-lane.js +73 -14
- package/dist/lib/capture-lane.js.map +1 -1
- package/dist/lib/capture-structure.d.ts +123 -0
- package/dist/lib/capture-structure.js +57 -0
- package/dist/lib/capture-structure.js.map +1 -0
- package/dist/lib/cp-packages.d.ts +177 -0
- package/dist/lib/cp-packages.js +389 -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 +91 -1
- package/dist/lib/hub-client.js +565 -22
- 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/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 +144 -22
- package/dist/lib/pod.js +302 -64
- 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 +17 -6
- package/dist/lib/skills-installer.js +133 -19
- 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 +49 -1
- package/dist/lib/targets.js +420 -288
- package/dist/lib/targets.js.map +1 -1
- package/dist/lib/template-file.d.ts +74 -0
- package/dist/lib/template-file.js +140 -0
- package/dist/lib/template-file.js.map +1 -0
- 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/node_modules/@synap/hub-rest-client/dist/index.cjs +414 -34
- package/node_modules/@synap/hub-rest-client/dist/index.d.cts +762 -22
- package/node_modules/@synap/hub-rest-client/dist/index.d.ts +762 -22
- package/node_modules/@synap/hub-rest-client/dist/index.js +414 -34
- package/node_modules/@synap/hub-rest-client/package.json +1 -1
- package/node_modules/@synap/hub-rest-client/src/client.ts +525 -37
- package/node_modules/@synap/hub-rest-client/src/index.ts +42 -0
- package/node_modules/@synap/hub-rest-client/src/setup.ts +57 -1
- package/node_modules/@synap/hub-rest-client/src/types.ts +697 -37
- package/package.json +11 -5
- package/skills/agent-os/SKILL.md +218 -0
- package/skills/manifest.json +5 -0
- package/skills/onboard/SKILL.md +193 -0
- package/skills/synap/SKILL.md +1284 -58
- 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 +50 -142
- package/skills/synap/cli-operations.md +107 -0
- package/skills/synap/common-mistakes.md +13 -0
- package/skills/synap/content-os.md +83 -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 +63 -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 +12 -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 +74 -0
- package/skills/synap/workspace-design.md +45 -0
- package/skills/synap/workspace-edges.md +49 -0
- package/skills/synap/writes.md +213 -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-market/SKILL.md +335 -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 +75 -0
- package/skills/synap-market/discover-and-fetch.md +59 -0
- package/skills/synap-market/governance-and-catalog.md +56 -0
- package/skills/synap-market/install.md +55 -0
- package/skills/synap-market/overview.md +51 -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 +26 -2
- 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/connectors.d.ts +0 -31
- package/dist/commands/connectors.js +0 -276
- package/dist/commands/connectors.js.map +0 -1
- 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
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project-ref resolution — the ONE door (P4-lite W3).
|
|
3
|
+
*
|
|
4
|
+
* A project ref can name a project on ANY pod the user can see, resolved via
|
|
5
|
+
* the Control Plane directory (`GET /projects/resolve?ref=`). Every command
|
|
6
|
+
* that accepts a project ref parses + resolves it HERE — no second ref parser
|
|
7
|
+
* anywhere.
|
|
8
|
+
*
|
|
9
|
+
* Ref forms (ratified):
|
|
10
|
+
* - uuid → local: today's behavior, pinned against the active pod
|
|
11
|
+
* - `<pod-subdomain>/<slug>` → canonical cross-pod form (e.g. perso/synap)
|
|
12
|
+
* - bare `<slug>` → resolved when unique across visible pods; 300-ambiguous otherwise
|
|
13
|
+
*
|
|
14
|
+
* The directory is an ACCELERATOR, not a dependency: CP unreachable, not
|
|
15
|
+
* logged in, or 404 all degrade to a graceful message — the uuid path never
|
|
16
|
+
* touches the CP and keeps working.
|
|
17
|
+
*/
|
|
18
|
+
export type ParsedProjectRef = {
|
|
19
|
+
kind: "uuid";
|
|
20
|
+
id: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: "fq";
|
|
23
|
+
pod: string;
|
|
24
|
+
slug: string;
|
|
25
|
+
} | {
|
|
26
|
+
kind: "slug";
|
|
27
|
+
slug: string;
|
|
28
|
+
} | {
|
|
29
|
+
kind: "invalid";
|
|
30
|
+
reason: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function parseProjectRef(raw: string): ParsedProjectRef;
|
|
33
|
+
/** One resolved project, as the CP directory returns it (200). */
|
|
34
|
+
export interface CpProjectResolution {
|
|
35
|
+
projectId: string;
|
|
36
|
+
/** Nullable in the CP mirror (pre-slug rows); render with a fallback. */
|
|
37
|
+
slug: string | null;
|
|
38
|
+
name: string;
|
|
39
|
+
podId: string;
|
|
40
|
+
podUrl: string;
|
|
41
|
+
grant?: unknown;
|
|
42
|
+
}
|
|
43
|
+
/** A 300-ambiguous candidate — same shape, rendered as `pod/slug` hints. */
|
|
44
|
+
export type CpProjectCandidate = Partial<CpProjectResolution>;
|
|
45
|
+
export type ProjectRefResolution =
|
|
46
|
+
/** uuid ref — no CP involved; caller keeps today's active-pod behavior. */
|
|
47
|
+
{
|
|
48
|
+
kind: "local";
|
|
49
|
+
projectId: string;
|
|
50
|
+
} | {
|
|
51
|
+
kind: "resolved";
|
|
52
|
+
project: CpProjectResolution;
|
|
53
|
+
refPod?: string;
|
|
54
|
+
} | {
|
|
55
|
+
kind: "ambiguous";
|
|
56
|
+
candidates: CpProjectCandidate[];
|
|
57
|
+
} | {
|
|
58
|
+
kind: "not-found";
|
|
59
|
+
ref: string;
|
|
60
|
+
} | {
|
|
61
|
+
kind: "not-active";
|
|
62
|
+
ref: string;
|
|
63
|
+
status: string;
|
|
64
|
+
} | {
|
|
65
|
+
kind: "not-logged-in";
|
|
66
|
+
} | {
|
|
67
|
+
kind: "cp-error";
|
|
68
|
+
message: string;
|
|
69
|
+
} | {
|
|
70
|
+
kind: "invalid";
|
|
71
|
+
reason: string;
|
|
72
|
+
};
|
|
73
|
+
/** Injectable seams for tests — production callers pass nothing. */
|
|
74
|
+
export interface ResolveDeps {
|
|
75
|
+
fetchImpl?: typeof fetch;
|
|
76
|
+
getToken?: () => {
|
|
77
|
+
token: string;
|
|
78
|
+
} | null;
|
|
79
|
+
cpUrl?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Resolve a project ref. uuid short-circuits to `local` (today's behavior);
|
|
83
|
+
* everything else goes through the CP directory with the CLI's CP credentials.
|
|
84
|
+
*/
|
|
85
|
+
export declare function resolveProjectRef(raw: string, deps?: ResolveDeps): Promise<ProjectRefResolution>;
|
|
86
|
+
/** True when two pod URLs name the same origin (scheme+host+port). */
|
|
87
|
+
export declare function samePodOrigin(a: string | undefined, b: string | undefined): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Session-lens guard: the per-Claude-session lens has NO pod field, so a
|
|
90
|
+
* `--session` pin can only target a project on the ACTIVE pod. Returns the
|
|
91
|
+
* refusal message for a cross-pod ref, or null when the pin is allowed.
|
|
92
|
+
*/
|
|
93
|
+
export declare function sessionScopeRefusal(project: CpProjectResolution, activePodUrl: string | undefined): string | null;
|
|
94
|
+
/** `pod/slug` label for a candidate row, degrading to whatever fields exist. */
|
|
95
|
+
export declare function candidateLabel(c: CpProjectCandidate): string;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project-ref resolution — the ONE door (P4-lite W3).
|
|
3
|
+
*
|
|
4
|
+
* A project ref can name a project on ANY pod the user can see, resolved via
|
|
5
|
+
* the Control Plane directory (`GET /projects/resolve?ref=`). Every command
|
|
6
|
+
* that accepts a project ref parses + resolves it HERE — no second ref parser
|
|
7
|
+
* anywhere.
|
|
8
|
+
*
|
|
9
|
+
* Ref forms (ratified):
|
|
10
|
+
* - uuid → local: today's behavior, pinned against the active pod
|
|
11
|
+
* - `<pod-subdomain>/<slug>` → canonical cross-pod form (e.g. perso/synap)
|
|
12
|
+
* - bare `<slug>` → resolved when unique across visible pods; 300-ambiguous otherwise
|
|
13
|
+
*
|
|
14
|
+
* The directory is an ACCELERATOR, not a dependency: CP unreachable, not
|
|
15
|
+
* logged in, or 404 all degrade to a graceful message — the uuid path never
|
|
16
|
+
* touches the CP and keeps working.
|
|
17
|
+
*/
|
|
18
|
+
import { getStoredToken, getCpUrl } from "./auth.js";
|
|
19
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
20
|
+
/** Pod subdomains and project slugs: alphanum with internal `-`/`_`/`.`. */
|
|
21
|
+
const PART_RE = /^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/i;
|
|
22
|
+
export function parseProjectRef(raw) {
|
|
23
|
+
const ref = raw.trim();
|
|
24
|
+
if (!ref)
|
|
25
|
+
return { kind: "invalid", reason: "empty project ref" };
|
|
26
|
+
if (UUID_RE.test(ref))
|
|
27
|
+
return { kind: "uuid", id: ref.toLowerCase() };
|
|
28
|
+
const parts = ref.split("/");
|
|
29
|
+
if (parts.length === 2) {
|
|
30
|
+
const [pod, slug] = parts;
|
|
31
|
+
if (!PART_RE.test(pod) || !PART_RE.test(slug)) {
|
|
32
|
+
return {
|
|
33
|
+
kind: "invalid",
|
|
34
|
+
reason: `"${ref}" is not a valid <pod>/<slug> ref (letters, digits, - _ . only)`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return { kind: "fq", pod: pod.toLowerCase(), slug: slug.toLowerCase() };
|
|
38
|
+
}
|
|
39
|
+
if (parts.length > 2) {
|
|
40
|
+
return { kind: "invalid", reason: `"${ref}" has too many '/' — use <pod-subdomain>/<slug>` };
|
|
41
|
+
}
|
|
42
|
+
if (!PART_RE.test(ref)) {
|
|
43
|
+
return {
|
|
44
|
+
kind: "invalid",
|
|
45
|
+
reason: `"${ref}" is not a project uuid, slug, or <pod>/<slug> ref`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return { kind: "slug", slug: ref.toLowerCase() };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Resolve a project ref. uuid short-circuits to `local` (today's behavior);
|
|
52
|
+
* everything else goes through the CP directory with the CLI's CP credentials.
|
|
53
|
+
*/
|
|
54
|
+
export async function resolveProjectRef(raw, deps = {}) {
|
|
55
|
+
const parsed = parseProjectRef(raw);
|
|
56
|
+
if (parsed.kind === "invalid")
|
|
57
|
+
return { kind: "invalid", reason: parsed.reason };
|
|
58
|
+
if (parsed.kind === "uuid")
|
|
59
|
+
return { kind: "local", projectId: parsed.id };
|
|
60
|
+
const creds = (deps.getToken ?? getStoredToken)();
|
|
61
|
+
if (!creds?.token)
|
|
62
|
+
return { kind: "not-logged-in" };
|
|
63
|
+
const cpUrl = deps.cpUrl ?? getCpUrl();
|
|
64
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
65
|
+
const ref = parsed.kind === "fq" ? `${parsed.pod}/${parsed.slug}` : parsed.slug;
|
|
66
|
+
let res;
|
|
67
|
+
try {
|
|
68
|
+
res = await fetchImpl(`${cpUrl}/projects/resolve?ref=${encodeURIComponent(ref)}`, {
|
|
69
|
+
headers: { Authorization: `Bearer ${creds.token}` },
|
|
70
|
+
signal: AbortSignal.timeout(10_000),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
75
|
+
return {
|
|
76
|
+
kind: "cp-error",
|
|
77
|
+
message: `could not reach the project directory at ${cpUrl} (${detail})`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (res.status === 300) {
|
|
81
|
+
const body = (await res.json().catch(() => null));
|
|
82
|
+
return { kind: "ambiguous", candidates: body?.candidates ?? [] };
|
|
83
|
+
}
|
|
84
|
+
if (res.status === 404) {
|
|
85
|
+
// The CP distinguishes "exists but archived/completed" from truly absent.
|
|
86
|
+
const body = (await res.json().catch(() => null));
|
|
87
|
+
if (body?.status)
|
|
88
|
+
return { kind: "not-active", ref, status: body.status };
|
|
89
|
+
return { kind: "not-found", ref };
|
|
90
|
+
}
|
|
91
|
+
if (res.status === 401 || res.status === 403)
|
|
92
|
+
return { kind: "not-logged-in" };
|
|
93
|
+
if (!res.ok) {
|
|
94
|
+
return { kind: "cp-error", message: `the project directory returned HTTP ${res.status}` };
|
|
95
|
+
}
|
|
96
|
+
const body = (await res.json().catch(() => null));
|
|
97
|
+
if (!body?.projectId || !body?.podUrl) {
|
|
98
|
+
return { kind: "cp-error", message: "the project directory returned an incomplete resolution" };
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
kind: "resolved",
|
|
102
|
+
project: body,
|
|
103
|
+
refPod: parsed.kind === "fq" ? parsed.pod : undefined,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// ─── Helpers shared by callers ────────────────────────────────────────────────
|
|
107
|
+
/** True when two pod URLs name the same origin (scheme+host+port). */
|
|
108
|
+
export function samePodOrigin(a, b) {
|
|
109
|
+
if (!a || !b)
|
|
110
|
+
return false;
|
|
111
|
+
try {
|
|
112
|
+
return new URL(a).origin === new URL(b).origin;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return a === b;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Session-lens guard: the per-Claude-session lens has NO pod field, so a
|
|
120
|
+
* `--session` pin can only target a project on the ACTIVE pod. Returns the
|
|
121
|
+
* refusal message for a cross-pod ref, or null when the pin is allowed.
|
|
122
|
+
*/
|
|
123
|
+
export function sessionScopeRefusal(project, activePodUrl) {
|
|
124
|
+
if (samePodOrigin(activePodUrl, project.podUrl))
|
|
125
|
+
return null;
|
|
126
|
+
return (`--session scopes only this Claude session, and the session lens has no pod field — ` +
|
|
127
|
+
`it cannot bind a project on another pod (${project.podUrl}). ` +
|
|
128
|
+
`Re-run without --session to switch the active pod, or pick a project on the active pod.`);
|
|
129
|
+
}
|
|
130
|
+
/** `pod/slug` label for a candidate row, degrading to whatever fields exist. */
|
|
131
|
+
export function candidateLabel(c) {
|
|
132
|
+
// The CP emits podUrl (never a subdomain field); derive the label from it.
|
|
133
|
+
let pod;
|
|
134
|
+
if (c.podUrl) {
|
|
135
|
+
try {
|
|
136
|
+
pod = new URL(c.podUrl).hostname;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
pod = c.podUrl;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return `${pod ?? "?"}/${c.slug ?? c.projectId ?? "?"}`;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=project-ref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-ref.js","sourceRoot":"","sources":["../../src/lib/project-ref.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project doors shared by `synap launch` and `synap market install`.
|
|
3
|
+
*
|
|
4
|
+
* The project is the cross-cutting lens both commands link installs to: launch
|
|
5
|
+
* stands up a NEW company under a project, market install ADDS a package into an
|
|
6
|
+
* existing (or the active) project. Both need the same two primitives — list the
|
|
7
|
+
* pod's projects, and create one — so they live here instead of being duplicated.
|
|
8
|
+
* The INTERACTIVE picking differs per command (launch weaves it into its guided
|
|
9
|
+
* flow; market offers a standalone "Add to which project?" with a pod-wide
|
|
10
|
+
* escape), so that stays in each command; only the data doors are shared.
|
|
11
|
+
*/
|
|
12
|
+
import { type HubConfig } from "./hub-client.js";
|
|
13
|
+
export interface ProjectRef {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The pod's existing projects (`GET /projects`), normalized to `{id, name}`.
|
|
19
|
+
* Best-effort: an unreachable/erroring pod yields `[]` rather than throwing, so
|
|
20
|
+
* callers degrade to create-new / pod-wide instead of failing.
|
|
21
|
+
*/
|
|
22
|
+
export declare function fetchProjects(cfg: HubConfig): Promise<ProjectRef[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Create a project (`POST /projects`). Governance may answer with a proposal
|
|
25
|
+
* instead of creating directly — the caller distinguishes `id` (live) from
|
|
26
|
+
* `proposalId` (queued for review) and messages accordingly.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createProject(cfg: HubConfig, input: {
|
|
29
|
+
name: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
id?: string;
|
|
33
|
+
proposalId?: string;
|
|
34
|
+
status?: string;
|
|
35
|
+
}>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project doors shared by `synap launch` and `synap market install`.
|
|
3
|
+
*
|
|
4
|
+
* The project is the cross-cutting lens both commands link installs to: launch
|
|
5
|
+
* stands up a NEW company under a project, market install ADDS a package into an
|
|
6
|
+
* existing (or the active) project. Both need the same two primitives — list the
|
|
7
|
+
* pod's projects, and create one — so they live here instead of being duplicated.
|
|
8
|
+
* The INTERACTIVE picking differs per command (launch weaves it into its guided
|
|
9
|
+
* flow; market offers a standalone "Add to which project?" with a pod-wide
|
|
10
|
+
* escape), so that stays in each command; only the data doors are shared.
|
|
11
|
+
*/
|
|
12
|
+
import { hubGet, hubPost } from "./hub-client.js";
|
|
13
|
+
import { unwrapList } from "./unwrapList.js";
|
|
14
|
+
/**
|
|
15
|
+
* The pod's existing projects (`GET /projects`), normalized to `{id, name}`.
|
|
16
|
+
* Best-effort: an unreachable/erroring pod yields `[]` rather than throwing, so
|
|
17
|
+
* callers degrade to create-new / pod-wide instead of failing.
|
|
18
|
+
*/
|
|
19
|
+
export async function fetchProjects(cfg) {
|
|
20
|
+
try {
|
|
21
|
+
const res = (await hubGet("/projects", {}, cfg));
|
|
22
|
+
const list = unwrapList(res, ["projects"]);
|
|
23
|
+
return list
|
|
24
|
+
.filter((p) => p.id)
|
|
25
|
+
.map((p) => ({ id: String(p.id), name: String(p.name ?? p.id) }));
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a project (`POST /projects`). Governance may answer with a proposal
|
|
33
|
+
* instead of creating directly — the caller distinguishes `id` (live) from
|
|
34
|
+
* `proposalId` (queued for review) and messages accordingly.
|
|
35
|
+
*/
|
|
36
|
+
export async function createProject(cfg, input) {
|
|
37
|
+
return (await hubPost("/projects", { name: input.name, description: input.description || undefined, status: "active" }, cfg));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/lib/project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAkB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAO7C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAc;IAChD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,CAAY,CAAC;QAC5D,MAAM,IAAI,GAAG,UAAU,CAA0B,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QACpE,OAAO,IAAI;aACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACnB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAc,EACd,KAA6C;IAE7C,OAAO,CAAC,MAAM,OAAO,CACnB,WAAW,EACX,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,EACnF,GAAG,CACJ,CAA0D,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-Claude-session lens registry.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code assigns each session (each tab / instance) a stable
|
|
5
|
+
* `CLAUDE_CODE_SESSION_ID` — present BOTH in the bash env of the agent's
|
|
6
|
+
* commands AND in the JSON the statusline receives on stdin. That shared id
|
|
7
|
+
* lets us bind a per-session "lens" (which workspace / project / focus session
|
|
8
|
+
* this session is working through) without any backend change: the pod stays
|
|
9
|
+
* agnostic, the CLI layers session-scoped state on top.
|
|
10
|
+
*
|
|
11
|
+
* This is what makes concurrent Claude Code sessions independent — tab A on
|
|
12
|
+
* workspace Builder + session X, tab B on workspace Marketing + session Y —
|
|
13
|
+
* instead of all sharing one global `~/.synap/config.json` workspace.
|
|
14
|
+
*
|
|
15
|
+
* Registry: ~/.synap/lenses/<session_id>.json
|
|
16
|
+
* Resolution precedence (highest first): explicit flag > session lens >
|
|
17
|
+
* env SYNAP_WORKSPACE_ID > global config activeWorkspaceId.
|
|
18
|
+
*/
|
|
19
|
+
export interface SessionLens {
|
|
20
|
+
workspaceId?: string;
|
|
21
|
+
projectId?: string;
|
|
22
|
+
focusSessionId?: string;
|
|
23
|
+
updatedAt?: number;
|
|
24
|
+
}
|
|
25
|
+
/** The current Claude Code session id, if we're running inside one. */
|
|
26
|
+
export declare function getClaudeSessionId(): string | undefined;
|
|
27
|
+
export declare function readLens(sessionId: string): SessionLens | null;
|
|
28
|
+
/** Merge-write the lens for a session (creates the registry dir on demand). */
|
|
29
|
+
export declare function writeLens(sessionId: string, patch: Partial<SessionLens>): SessionLens;
|
|
30
|
+
/** Clear one field (or the whole lens) for a session. */
|
|
31
|
+
export declare function clearLensField(sessionId: string, field?: keyof SessionLens): void;
|
|
32
|
+
/** The active session's lens, or null if not in a Claude session / none set. */
|
|
33
|
+
export declare function resolveActiveLens(): SessionLens | null;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-Claude-session lens registry.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code assigns each session (each tab / instance) a stable
|
|
5
|
+
* `CLAUDE_CODE_SESSION_ID` — present BOTH in the bash env of the agent's
|
|
6
|
+
* commands AND in the JSON the statusline receives on stdin. That shared id
|
|
7
|
+
* lets us bind a per-session "lens" (which workspace / project / focus session
|
|
8
|
+
* this session is working through) without any backend change: the pod stays
|
|
9
|
+
* agnostic, the CLI layers session-scoped state on top.
|
|
10
|
+
*
|
|
11
|
+
* This is what makes concurrent Claude Code sessions independent — tab A on
|
|
12
|
+
* workspace Builder + session X, tab B on workspace Marketing + session Y —
|
|
13
|
+
* instead of all sharing one global `~/.synap/config.json` workspace.
|
|
14
|
+
*
|
|
15
|
+
* Registry: ~/.synap/lenses/<session_id>.json
|
|
16
|
+
* Resolution precedence (highest first): explicit flag > session lens >
|
|
17
|
+
* env SYNAP_WORKSPACE_ID > global config activeWorkspaceId.
|
|
18
|
+
*/
|
|
19
|
+
import fs from "node:fs";
|
|
20
|
+
import os from "node:os";
|
|
21
|
+
import path from "node:path";
|
|
22
|
+
const LENS_DIR = path.join(os.homedir(), ".synap", "lenses");
|
|
23
|
+
/** The current Claude Code session id, if we're running inside one. */
|
|
24
|
+
export function getClaudeSessionId() {
|
|
25
|
+
// Set in the bash env of the agent's commands. The statusline gets the same
|
|
26
|
+
// id from stdin and forwards it via SYNAP_LENS_SESSION when it spawns the
|
|
27
|
+
// detached refresh (which has no Claude env of its own).
|
|
28
|
+
return process.env.SYNAP_LENS_SESSION || process.env.CLAUDE_CODE_SESSION_ID || undefined;
|
|
29
|
+
}
|
|
30
|
+
function lensPath(sessionId) {
|
|
31
|
+
// session ids are UUIDs — safe as filenames, but sanitize defensively.
|
|
32
|
+
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
33
|
+
return path.join(LENS_DIR, `${safe}.json`);
|
|
34
|
+
}
|
|
35
|
+
export function readLens(sessionId) {
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(fs.readFileSync(lensPath(sessionId), "utf-8"));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Merge-write the lens for a session (creates the registry dir on demand). */
|
|
44
|
+
export function writeLens(sessionId, patch) {
|
|
45
|
+
const prev = readLens(sessionId) ?? {};
|
|
46
|
+
const next = { ...prev, ...patch, updatedAt: Date.now() };
|
|
47
|
+
try {
|
|
48
|
+
fs.mkdirSync(LENS_DIR, { recursive: true, mode: 0o700 });
|
|
49
|
+
fs.writeFileSync(lensPath(sessionId), JSON.stringify(next, null, 2), { mode: 0o600 });
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
/* best-effort */
|
|
53
|
+
}
|
|
54
|
+
return next;
|
|
55
|
+
}
|
|
56
|
+
/** Clear one field (or the whole lens) for a session. */
|
|
57
|
+
export function clearLensField(sessionId, field) {
|
|
58
|
+
const prev = readLens(sessionId);
|
|
59
|
+
if (!prev)
|
|
60
|
+
return;
|
|
61
|
+
if (!field) {
|
|
62
|
+
try {
|
|
63
|
+
fs.unlinkSync(lensPath(sessionId));
|
|
64
|
+
}
|
|
65
|
+
catch { }
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
delete prev[field];
|
|
69
|
+
writeLens(sessionId, prev);
|
|
70
|
+
}
|
|
71
|
+
/** The active session's lens, or null if not in a Claude session / none set. */
|
|
72
|
+
export function resolveActiveLens() {
|
|
73
|
+
const id = getClaudeSessionId();
|
|
74
|
+
return id ? readLens(id) : null;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=session-lens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-lens.js","sourceRoot":"","sources":["../../src/lib/session-lens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAS7D,uEAAuE;AACvE,MAAM,UAAU,kBAAkB;IAChC,4EAA4E;IAC5E,0EAA0E;IAC1E,yDAAyD;IACzD,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,SAAS,CAAC;AAC3F,CAAC;AAED,SAAS,QAAQ,CAAC,SAAiB;IACjC,uEAAuE;IACvE,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,SAAiB;IACxC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAgB,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,SAAS,CAAC,SAAiB,EAAE,KAA2B;IACtE,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IACvC,MAAM,IAAI,GAAgB,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACvE,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,KAAyB;IACzE,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CAAC;YAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACpD,OAAO;IACT,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,iBAAiB;IAC/B,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAChC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill import — read standard SKILL.md skill directories and push them to the pod.
|
|
3
|
+
*
|
|
4
|
+
* Follows the Agent Skills open standard (agentskills.io): a skill is a DIRECTORY
|
|
5
|
+
* with a `SKILL.md` at its root (YAML frontmatter + markdown body) and optional
|
|
6
|
+
* nested files/subdirs for reference docs, examples, templates, and code. Every
|
|
7
|
+
* non-SKILL.md file becomes a linked document (the agent reads them on demand via
|
|
8
|
+
* get_document). This is the same format Claude Code, Codex, Gemini CLI, Copilot
|
|
9
|
+
* and others use.
|
|
10
|
+
*
|
|
11
|
+
* The pod stores them via POST /agent-skills/import: the SKILL.md body becomes
|
|
12
|
+
* the instruction skill, every other file becomes a linked document.
|
|
13
|
+
*/
|
|
14
|
+
import { type HubConfig } from "./hub-client.js";
|
|
15
|
+
export interface ParsedSkill {
|
|
16
|
+
slug: string;
|
|
17
|
+
name: string;
|
|
18
|
+
description: string;
|
|
19
|
+
body: string;
|
|
20
|
+
/** auto_load=true → always-loaded core DNA; false → on-demand (catalog + load_skill). */
|
|
21
|
+
autoLoad: boolean;
|
|
22
|
+
documents: Array<{
|
|
23
|
+
title: string;
|
|
24
|
+
content: string;
|
|
25
|
+
type: string;
|
|
26
|
+
language?: string;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
/** Parse a single SKILL.md skill directory into an import payload. */
|
|
30
|
+
export declare function parseSkillDir(dir: string): ParsedSkill | null;
|
|
31
|
+
/** Find every skill directory (one containing SKILL.md) under a root, one level deep. */
|
|
32
|
+
export declare function discoverSkillDirs(root: string): string[];
|
|
33
|
+
export interface ImportResult {
|
|
34
|
+
slug: string;
|
|
35
|
+
status: "imported" | "exists" | "error";
|
|
36
|
+
docs: number;
|
|
37
|
+
error?: string;
|
|
38
|
+
}
|
|
39
|
+
/** Import a parsed skill into the pod via POST /agent-skills/import. */
|
|
40
|
+
export declare function importSkill(parsed: ParsedSkill, userId: string, cfg: HubConfig): Promise<ImportResult>;
|