@synap-core/cli 1.6.1 → 1.7.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.
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Hub Protocol REST API error class.
3
+ * Thrown when the server returns a non-2xx response.
4
+ */
5
+ export class HubApiError extends Error {
6
+ constructor(
7
+ message: string,
8
+ public readonly statusCode: number,
9
+ public readonly body?: unknown
10
+ ) {
11
+ super(message);
12
+ this.name = "HubApiError";
13
+ }
14
+
15
+ get isUnauthorized(): boolean {
16
+ return this.statusCode === 401;
17
+ }
18
+
19
+ get isForbidden(): boolean {
20
+ return this.statusCode === 403;
21
+ }
22
+
23
+ get isNotFound(): boolean {
24
+ return this.statusCode === 404;
25
+ }
26
+
27
+ get isServerError(): boolean {
28
+ return this.statusCode >= 500;
29
+ }
30
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @synap/hub-rest-client
3
+ *
4
+ * Zero-dependency TypeScript client for the Synap Hub Protocol REST API.
5
+ *
6
+ * Works in Node.js >= 18, browsers, Deno, Bun, and Raycast extensions.
7
+ *
8
+ * @example Basic usage
9
+ * ```ts
10
+ * import { HubRestClient } from "@synap/hub-rest-client";
11
+ *
12
+ * const client = new HubRestClient({
13
+ * podUrl: "https://my-pod.synap.live",
14
+ * apiKey: process.env.SYNAP_HUB_API_KEY!,
15
+ * });
16
+ *
17
+ * const entities = await client.searchEntities("meeting notes");
18
+ * const task = await client.createEntity({ profileSlug: "task", title: "Fix bug" });
19
+ * ```
20
+ *
21
+ * @example Setup flow (new agent)
22
+ * ```ts
23
+ * import { setupAgent, checkPodHealth } from "@synap/hub-rest-client";
24
+ *
25
+ * const status = await checkPodHealth("https://my-pod.synap.live");
26
+ * if (status.healthy) {
27
+ * const { hubApiKey, workspaceId } = await setupAgent(
28
+ * "https://my-pod.synap.live",
29
+ * process.env.PROVISIONING_TOKEN!,
30
+ * "my-agent"
31
+ * );
32
+ * }
33
+ * ```
34
+ */
35
+
36
+ // Client
37
+ export { HubRestClient } from "./client.js";
38
+ export type { HubRestClientConfig } from "./client.js";
39
+
40
+ // Errors
41
+ export { HubApiError } from "./errors.js";
42
+
43
+ // Setup utilities
44
+ export { checkPodHealth, setupAgent } from "./setup.js";
45
+
46
+ // Types
47
+ export type {
48
+ // Core entity types
49
+ HubEntity,
50
+ HubDocument,
51
+ HubChannel,
52
+ HubWorkspace,
53
+ HubWorkspacesListResponse,
54
+ HubUser,
55
+ HubMemoryResult,
56
+ HubListResponse,
57
+ HubSingleResponse,
58
+ // Relations & Graph
59
+ HubRelation,
60
+ HubGraphNode,
61
+ HubGraphEdge,
62
+ HubGraphResult,
63
+ HubConnection,
64
+ HubConnectionsResult,
65
+ // Profiles & Schema
66
+ HubProfile,
67
+ HubPropertyDef,
68
+ HubDiscoverResult,
69
+ HubDiscoverProfile,
70
+ HubDiscoverProperty,
71
+ // Threads & Channels
72
+ HubThread,
73
+ HubMessage,
74
+ HubThreadContext,
75
+ // Proposals
76
+ HubProposal,
77
+ // Views
78
+ HubView,
79
+ // Search
80
+ HubSearchResult,
81
+ // Commands & Agents
82
+ HubCommand,
83
+ HubAgentUser,
84
+ // User Context
85
+ HubUserContext,
86
+ // Governance
87
+ HubGovernanceResult,
88
+ // Input types — Entity
89
+ CreateEntityInput,
90
+ UpdateEntityInput,
91
+ // Input types — Documents
92
+ CreateDocumentInput,
93
+ // Input types — Memory
94
+ StoreMemoryInput,
95
+ // Input types — Channels
96
+ SendToChannelInput,
97
+ // Input types — Relations, Threads, Views, Commands
98
+ CreateRelationInput,
99
+ CreateThreadInput,
100
+ CreateViewInput,
101
+ ExecuteCommandInput,
102
+ // Setup
103
+ AgentSetupResult,
104
+ PodStatus,
105
+ // Capture pipeline
106
+ CaptureProposal,
107
+ CaptureRelation,
108
+ CaptureStructureResponse,
109
+ CaptureExecuteInput,
110
+ CaptureExecuteResponse,
111
+ } from "./types.js";
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Pod setup and health utilities.
3
+ *
4
+ * These functions are the canonical implementations shared between
5
+ * the Synap CLI and the Raycast extension. They use the native fetch API
6
+ * and have zero Node.js-specific dependencies.
7
+ */
8
+
9
+ import { HubApiError } from "./errors.js";
10
+ import type { AgentSetupResult, PodStatus } from "./types.js";
11
+
12
+ function normalizeUrl(url: string): string {
13
+ return url.replace(/\/$/, "");
14
+ }
15
+
16
+ /**
17
+ * Check whether a Synap pod is healthy.
18
+ * Hits `GET {podUrl}/health` with a 5s timeout.
19
+ */
20
+ export async function checkPodHealth(podUrl: string): Promise<PodStatus> {
21
+ const url = normalizeUrl(podUrl);
22
+ const status: PodStatus = { url, healthy: false };
23
+
24
+ try {
25
+ const res = await fetch(`${url}/health`, {
26
+ signal: AbortSignal.timeout(5000),
27
+ });
28
+ if (res.ok) {
29
+ status.healthy = true;
30
+ const data = (await res.json()) as Record<string, unknown>;
31
+ status.version = data.version as string | undefined;
32
+ }
33
+ } catch {
34
+ // pod unreachable or timed out
35
+ }
36
+
37
+ return status;
38
+ }
39
+
40
+ /**
41
+ * Create an agent user + Hub Protocol API key on the pod.
42
+ *
43
+ * Auth: `Authorization: Bearer <provisioningToken>`
44
+ * The provisioning token is either:
45
+ * - The pod's `PROVISIONING_TOKEN` env var (self-hosted path)
46
+ * - A CP-signed `agent_setup` JWT (managed pod path)
47
+ *
48
+ * Endpoint: `POST {podUrl}/api/hub/setup/agent`
49
+ */
50
+ export async function setupAgent(
51
+ podUrl: string,
52
+ provisioningToken: string,
53
+ agentType = "openclaw"
54
+ ): Promise<AgentSetupResult> {
55
+ const url = normalizeUrl(podUrl);
56
+
57
+ const res = await fetch(`${url}/api/hub/setup/agent`, {
58
+ method: "POST",
59
+ headers: {
60
+ "Content-Type": "application/json",
61
+ Authorization: `Bearer ${provisioningToken}`,
62
+ },
63
+ body: JSON.stringify({ agentType }),
64
+ signal: AbortSignal.timeout(15_000),
65
+ });
66
+
67
+ if (!res.ok) {
68
+ const body = await res.json().catch(() => ({}));
69
+ throw new HubApiError(
70
+ `Agent setup failed (HTTP ${res.status})`,
71
+ res.status,
72
+ body
73
+ );
74
+ }
75
+
76
+ return res.json() as Promise<AgentSetupResult>;
77
+ }