@privateconnect/sdk 0.7.5 → 0.8.6

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.
Files changed (4) hide show
  1. package/README.md +192 -174
  2. package/dist/index.d.ts +204 -19
  3. package/dist/index.js +349 -20
  4. package/package.json +10 -6
package/README.md CHANGED
@@ -1,174 +1,192 @@
1
- # Private Connect SDK
2
-
3
- TypeScript SDK for Private Connect - programmatic access to services and agent orchestration.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @privateconnect/sdk
9
- # or
10
- pnpm add @privateconnect/sdk
11
- ```
12
-
13
- ## Quick Start
14
-
15
- ```typescript
16
- import { PrivateConnect, connect } from '@privateconnect/sdk';
17
-
18
- // Quick connect to a service
19
- const db = await connect('postgres-prod');
20
- console.log(db.connectionString); // postgres://localhost:5432/...
21
-
22
- // Or use the full client
23
- const pc = new PrivateConnect({
24
- apiKey: process.env.PRIVATECONNECT_API_KEY
25
- });
26
-
27
- // List available services
28
- const services = await pc.services.list();
29
-
30
- // Connect to a specific service
31
- const redis = await pc.connect('redis-cache');
32
- console.log(redis.connectionString); // redis://localhost:6379
33
- ```
34
-
35
- ## Agent Orchestration
36
-
37
- The SDK enables multi-agent orchestration - coordinating work across agents running on different machines.
38
-
39
- ### List Agents
40
-
41
- ```typescript
42
- // Get all agents in your workspace
43
- const agents = await pc.agents.list();
44
-
45
- // Get only online agents
46
- const online = await pc.agents.list({ onlineOnly: true });
47
-
48
- // Find agents with specific capabilities
49
- const gpuAgents = await pc.agents.findByCapability('gpu');
50
- ```
51
-
52
- ### Register Capabilities
53
-
54
- Tell other agents what you can do:
55
-
56
- ```typescript
57
- await pc.agents.registerCapabilities([
58
- { name: 'database', metadata: { type: 'postgres', version: '15' } },
59
- { name: 'gpu', metadata: { model: 'A100', memory: '80GB' } },
60
- ]);
61
- ```
62
-
63
- ### Agent Messaging
64
-
65
- Coordinate with other agents:
66
-
67
- ```typescript
68
- // Send a message to a specific agent
69
- await pc.agents.sendMessage(targetAgentId, {
70
- action: 'run-migration',
71
- database: 'users',
72
- });
73
-
74
- // Broadcast to all agents
75
- await pc.agents.broadcast({
76
- type: 'deployment-starting',
77
- service: 'api',
78
- });
79
-
80
- // Get your messages
81
- const messages = await pc.agents.getMessages({ unreadOnly: true });
82
- for (const msg of messages) {
83
- console.log(`From ${msg.from.name}: ${JSON.stringify(msg.payload)}`);
84
- }
85
- ```
86
-
87
- ### Orchestration Sessions
88
-
89
- Create ephemeral sessions for coordinated workflows:
90
-
91
- ```typescript
92
- // Create a session
93
- const session = await pc.sessions.create('deploy-v2.1', {
94
- ttlMinutes: 30,
95
- metadata: { version: '2.1.0' },
96
- });
97
-
98
- // ... coordinate agents ...
99
-
100
- // End the session
101
- await pc.sessions.end(session.id);
102
- ```
103
-
104
- ## Connection Strings
105
-
106
- Get properly formatted connection strings for common services:
107
-
108
- ```typescript
109
- const db = await pc.connect('postgres-prod');
110
- // db.connectionString = 'postgres://localhost:5432/postgres'
111
- // db.envVar = 'DATABASE_URL'
112
-
113
- const cache = await pc.connect('redis-cache');
114
- // cache.connectionString = 'redis://localhost:6379'
115
- // cache.envVar = 'REDIS_URL'
116
-
117
- const api = await pc.connect('internal-api');
118
- // api.connectionString = 'http://localhost:8080'
119
- // api.envVar = 'API_URL'
120
- ```
121
-
122
- ## Environment Variables
123
-
124
- The SDK can read configuration from environment variables:
125
-
126
- ```bash
127
- export PRIVATECONNECT_API_KEY=your-api-key
128
- ```
129
-
130
- ```typescript
131
- // API key automatically read from env
132
- const connection = await connect('my-service');
133
- ```
134
-
135
- ## API Reference
136
-
137
- ### `PrivateConnect`
138
-
139
- Main client class.
140
-
141
- ```typescript
142
- const pc = new PrivateConnect({
143
- apiKey: string, // Required: Your API key
144
- hubUrl?: string, // Optional: Hub URL (default: https://api.privateconnect.co)
145
- agentId?: string, // Optional: Agent ID (auto-detected)
146
- });
147
- ```
148
-
149
- ### `pc.services`
150
-
151
- - `list()` - List all services
152
- - `get(name)` - Get a service by name
153
- - `getConnection(name)` - Get connection details for a service
154
-
155
- ### `pc.agents`
156
-
157
- - `list(options?)` - List all agents
158
- - `findByCapability(capability)` - Find agents by capability
159
- - `registerCapabilities(capabilities)` - Register this agent's capabilities
160
- - `sendMessage(toAgentId, payload, options?)` - Send a message
161
- - `broadcast(payload, options?)` - Broadcast to all agents
162
- - `getMessages(options?)` - Get received messages
163
- - `markRead(messageIds)` - Mark messages as read
164
-
165
- ### `pc.sessions`
166
-
167
- - `create(name, options?)` - Create an orchestration session
168
- - `end(sessionId)` - End a session
169
- - `getActive()` - Get active sessions
170
-
171
- ## License
172
-
173
- [FSL-1.1-MIT](LICENSE)
174
-
1
+ # Private Connect SDK
2
+
3
+ Define your connections in `pconnect.yml`. Access them from anywhere your app, CI, an AI agent.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @privateconnect/sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ **1. Create `pconnect.yml` in your project root:**
14
+
15
+ ```yaml
16
+ resources:
17
+ staging-db:
18
+ type: postgres
19
+ host: internal-db
20
+ port: 5432
21
+ access:
22
+ mode: tcp
23
+ redis-cache:
24
+ type: redis
25
+ host: redis.internal
26
+ port: 6379
27
+ access:
28
+ mode: tcp
29
+ ```
30
+
31
+ **2. Use it in your code:**
32
+
33
+ ```typescript
34
+ import { PrivateConnect } from '@privateconnect/sdk';
35
+
36
+ const pc = PrivateConnect.fromManifest();
37
+
38
+ const db = pc.resource('staging-db');
39
+ console.log(db.connectionString); // postgres://internal-db:5432
40
+ console.log(db.envVar); // DATABASE_URL
41
+
42
+ const cache = pc.resource('redis-cache');
43
+ console.log(cache.connectionString); // redis://redis.internal:6379
44
+ ```
45
+
46
+ **3. Run `connect dev` to make it live:**
47
+
48
+ ```bash
49
+ connect dev
50
+ # → Provisions tunnels for every resource in pconnect.yml
51
+ # → Your app's connection strings now resolve to live services
52
+ ```
53
+
54
+ That's it. Your app declares what it connects to. `connect dev` makes it work. An AI agent (or a teammate) can modify `pconnect.yml` to change the topology — without touching application code.
55
+
56
+ ## Why This Matters
57
+
58
+ The `pconnect.yml` file is a diffable, reviewable, mergeable description of your project's connectivity. When an AI modifies it — adding a read replica, changing a TTL, switching an access mode — that's a PR you can review and merge. The SDK reads the manifest; the agent provisions it.
59
+
60
+ ## Manifest API
61
+
62
+ ### `PrivateConnect.fromManifest(path?, config?)`
63
+
64
+ Load a manifest and return a configured client. Auto-discovers `pconnect.yml` in the current directory (or parents) if no path is given.
65
+
66
+ ```typescript
67
+ // Auto-discover
68
+ const pc = PrivateConnect.fromManifest();
69
+
70
+ // Explicit path
71
+ const pc = PrivateConnect.fromManifest('./infra/pconnect.yml');
72
+
73
+ // With hub API access (for grants, orchestration, etc.)
74
+ const pc = PrivateConnect.fromManifest('./pconnect.yml', {
75
+ apiKey: process.env.PRIVATECONNECT_API_KEY,
76
+ });
77
+ ```
78
+
79
+ ### `pc.resource(name)`
80
+
81
+ Get a resource by name. Returns its resolved type, host, port, connection string, and suggested environment variable.
82
+
83
+ ```typescript
84
+ const db = pc.resource('staging-db');
85
+ // {
86
+ // name: 'staging-db',
87
+ // type: 'postgres',
88
+ // host: 'internal-db',
89
+ // port: 5432,
90
+ // connectionString: 'postgres://internal-db:5432',
91
+ // envVar: 'DATABASE_URL',
92
+ // accessMode: 'tcp',
93
+ // via: 'direct'
94
+ // }
95
+ ```
96
+
97
+ ### `pc.resources()`
98
+
99
+ List all resources declared in the manifest.
100
+
101
+ ```typescript
102
+ const all = pc.resources();
103
+ all.forEach(r => console.log(`${r.name}: ${r.connectionString}`));
104
+ ```
105
+
106
+ ### `pc.envBlock()`
107
+
108
+ Generate a `.env`-compatible block for all resources.
109
+
110
+ ```typescript
111
+ console.log(pc.envBlock());
112
+ // DATABASE_URL=postgres://internal-db:5432
113
+ // REDIS_URL=redis://redis.internal:6379
114
+ // API_URL=http://payments.service.internal:3000
115
+ ```
116
+
117
+ ## Hub API
118
+
119
+ When you pass an API key, you also get access to the hub APIs for grants, agents, and services.
120
+
121
+ ### Grants
122
+
123
+ Grant an AI agent temporary, scoped access to a private resource.
124
+
125
+ ```typescript
126
+ const pc = PrivateConnect.fromManifest('./pconnect.yml', {
127
+ apiKey: process.env.PRIVATECONNECT_API_KEY,
128
+ });
129
+
130
+ const grant = await pc.grants.create({
131
+ agentLabel: 'claude',
132
+ resourceType: 'db',
133
+ resourceName: 'postgres',
134
+ ttl: '5m',
135
+ });
136
+ console.log(grant.token); // gnt_...
137
+ ```
138
+
139
+ ### Agent Orchestration
140
+
141
+ Coordinate agents across machines.
142
+
143
+ ```typescript
144
+ const agents = await pc.agents.list({ onlineOnly: true });
145
+ const gpuAgents = await pc.agents.findByCapability('gpu');
146
+
147
+ await pc.agents.sendMessage(gpuAgents[0].id, {
148
+ action: 'run-training',
149
+ dataset: 'v2',
150
+ });
151
+ ```
152
+
153
+ ### Services
154
+
155
+ Query hub-registered services directly.
156
+
157
+ ```typescript
158
+ const services = await pc.services.list();
159
+ const conn = await pc.connect('prod-db');
160
+ console.log(conn.connectionString);
161
+ ```
162
+
163
+ ## Manifest Format
164
+
165
+ The `pconnect.yml` file supports the following resource types:
166
+
167
+ | Type | Default Port | Connection String | Env Var |
168
+ |------|-------------|-------------------|---------|
169
+ | `postgres` | 5432 | `postgres://host:port` | `DATABASE_URL` |
170
+ | `mysql` | 3306 | `mysql://host:port` | `DATABASE_URL` |
171
+ | `redis` | 6379 | `redis://host:port` | `REDIS_URL` |
172
+ | `http` | 80 | `http://host:port` | `API_URL` |
173
+ | `generic-tcp` | — | `tcp://host:port` | `<NAME>_URL` |
174
+
175
+ Access modes:
176
+ - `tcp` — direct TCP tunnel (databases, Redis, generic)
177
+ - `http` — HTTP-level proxying
178
+
179
+ Transport:
180
+ - `direct` (default) — connect directly to the target
181
+ - `hub` — route through the Private Connect hub when the target isn't directly reachable
182
+
183
+ ## Environment Variables
184
+
185
+ | Variable | Purpose |
186
+ |----------|---------|
187
+ | `PRIVATECONNECT_API_KEY` | API key for hub access (grants, orchestration) |
188
+ | `CONNECT_HUB_URL` | Hub URL (default: `https://api.privateconnect.co`) |
189
+
190
+ ## License
191
+
192
+ [FSL-1.1-MIT](LICENSE)
package/dist/index.d.ts CHANGED
@@ -1,34 +1,35 @@
1
1
  /**
2
2
  * Private Connect SDK
3
3
  *
4
- * Programmatic access to Private Connect services, grants, and agent orchestration.
4
+ * Define your connections in pconnect.yml. Access them from anywhere.
5
5
  *
6
6
  * @example
7
7
  * ```typescript
8
8
  * import { PrivateConnect } from '@privateconnect/sdk';
9
9
  *
10
- * const pc = new PrivateConnect({ apiKey: 'your-api-key' });
10
+ * // Load your project's connection manifest
11
+ * const pc = PrivateConnect.fromManifest();
11
12
  *
12
- * // Connect to a service (assumes tunnel is already open)
13
- * const db = await pc.connect('postgres-prod');
14
- * console.log(db.connectionString); // postgres://localhost:5432/...
13
+ * // Get a resource declared in pconnect.yml
14
+ * const db = pc.resource('staging-db');
15
+ * console.log(db.connectionString); // postgres://internal-db:5432
16
+ * console.log(db.envVar); // DATABASE_URL
15
17
  *
16
- * // Grant an AI agent temporary access
17
- * const grant = await pc.grants.create({
18
+ * // With an API key, you also get hub API access
19
+ * const pc2 = PrivateConnect.fromManifest('./pconnect.yml', {
20
+ * apiKey: process.env.PRIVATECONNECT_API_KEY,
21
+ * });
22
+ * const grant = await pc2.grants.create({
18
23
  * agentLabel: 'claude',
19
24
  * resourceType: 'db',
20
25
  * resourceName: 'postgres',
21
26
  * ttl: '5m',
22
27
  * });
23
- * console.log(grant.token); // gnt_...
24
- *
25
- * // List all agents
26
- * const agents = await pc.agents.list();
27
28
  * ```
28
29
  */
29
30
  export interface PrivateConnectConfig {
30
- /** API key for authentication */
31
- apiKey: string;
31
+ /** API key for authentication. Required for hub API calls; optional for manifest-only usage. */
32
+ apiKey?: string;
32
33
  /** Hub URL (default: https://api.privateconnect.co) */
33
34
  hubUrl?: string;
34
35
  /** Agent ID (auto-detected from local config if not provided) */
@@ -95,14 +96,109 @@ export interface Grant {
95
96
  export interface GrantCreateOptions {
96
97
  agentLabel: string;
97
98
  resourceType: 'db' | 'api' | 'path';
98
- resourceName: string;
99
+ resourceName?: string;
100
+ groupId?: string;
99
101
  scope?: 'read-only' | 'full';
100
102
  /** Duration string: 60s, 5m, 1h, 1d. Omit for persistent grant. */
101
103
  ttl?: string;
102
104
  }
105
+ export interface ServiceRegisterOptions {
106
+ agentId: string;
107
+ name: string;
108
+ targetHost: string;
109
+ targetPort: number;
110
+ protocol?: 'auto' | 'tcp' | 'udp' | 'http' | 'https';
111
+ isPublic?: boolean;
112
+ groupId?: string;
113
+ }
114
+ export interface ProvisionOptions {
115
+ clientType: string;
116
+ label?: string;
117
+ name?: string;
118
+ ttlSeconds?: number;
119
+ }
120
+ export interface ProvisionResult {
121
+ agentId: string;
122
+ token: string;
123
+ expiresAt: string;
124
+ workspaceId: string;
125
+ workspaceName: string;
126
+ }
127
+ export interface ShareCreateOptions {
128
+ name: string;
129
+ description?: string;
130
+ expiresIn?: '1h' | '24h' | '7d' | '30d' | 'never';
131
+ allowedPaths?: string[];
132
+ allowedMethods?: ('GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE')[];
133
+ rateLimitPerMin?: number;
134
+ }
135
+ export interface Share {
136
+ id: string;
137
+ name: string;
138
+ description?: string;
139
+ expiresAt: string | null;
140
+ revokedAt: string | null;
141
+ createdAt: string;
142
+ isActive: boolean;
143
+ shareUrl: string;
144
+ tokenPreview: string;
145
+ }
146
+ export interface ServiceGroup {
147
+ id: string;
148
+ name: string;
149
+ metadata: Record<string, unknown> | null;
150
+ createdAt: string;
151
+ services: Array<{
152
+ id: string;
153
+ name: string;
154
+ status: string;
155
+ protocol: string;
156
+ }>;
157
+ }
158
+ export interface GroupCreateOptions {
159
+ name: string;
160
+ metadata?: Record<string, unknown>;
161
+ services?: Array<{
162
+ agentId: string;
163
+ name: string;
164
+ targetHost: string;
165
+ targetPort: number;
166
+ protocol?: string;
167
+ isPublic?: boolean;
168
+ }>;
169
+ }
170
+ export declare const RESOURCE_TYPES: readonly ["postgres", "mysql", "redis", "http", "generic-tcp"];
171
+ export type ResourceType = typeof RESOURCE_TYPES[number];
172
+ export declare const ACCESS_MODES: readonly ["tcp", "http"];
173
+ export type AccessMode = typeof ACCESS_MODES[number];
174
+ export declare const TRANSPORT_MODES: readonly ["direct", "hub"];
175
+ export type TransportVia = typeof TRANSPORT_MODES[number];
176
+ export interface ManifestResourceConfig {
177
+ type: ResourceType;
178
+ host?: string;
179
+ port?: number;
180
+ targetHost?: string;
181
+ targetPort?: number;
182
+ url?: string;
183
+ access: {
184
+ mode: AccessMode;
185
+ via?: TransportVia;
186
+ };
187
+ }
188
+ export interface ManifestResource {
189
+ name: string;
190
+ type: ResourceType;
191
+ host: string;
192
+ port: number;
193
+ connectionString: string;
194
+ envVar: string;
195
+ accessMode: AccessMode;
196
+ via: TransportVia;
197
+ }
103
198
  export declare class AgentsAPI {
104
199
  private client;
105
200
  constructor(client: PrivateConnect);
201
+ provision(options: ProvisionOptions): Promise<ProvisionResult>;
106
202
  list(options?: {
107
203
  onlineOnly?: boolean;
108
204
  }): Promise<Agent[]>;
@@ -132,8 +228,13 @@ export declare class AgentsAPI {
132
228
  export declare class ServicesAPI {
133
229
  private client;
134
230
  constructor(client: PrivateConnect);
231
+ register(options: ServiceRegisterOptions): Promise<Service>;
135
232
  list(): Promise<Service[]>;
136
233
  get(name: string): Promise<Service | null>;
234
+ update(id: string, options: {
235
+ name?: string;
236
+ }): Promise<void>;
237
+ delete(id: string): Promise<void>;
137
238
  /**
138
239
  * Get connection details for a service.
139
240
  *
@@ -168,15 +269,92 @@ export declare class GrantsAPI {
168
269
  */
169
270
  validate(token: string): Promise<Grant | null>;
170
271
  }
272
+ export declare class SharesAPI {
273
+ private client;
274
+ constructor(client: PrivateConnect);
275
+ create(serviceId: string, options: ShareCreateOptions): Promise<{
276
+ id: string;
277
+ token: string;
278
+ shareUrl: string;
279
+ expiresAt: string | null;
280
+ }>;
281
+ list(serviceId: string): Promise<Share[]>;
282
+ revoke(shareId: string): Promise<void>;
283
+ }
284
+ export declare class GroupsAPI {
285
+ private client;
286
+ constructor(client: PrivateConnect);
287
+ create(options: GroupCreateOptions): Promise<ServiceGroup>;
288
+ list(): Promise<ServiceGroup[]>;
289
+ get(id: string): Promise<ServiceGroup>;
290
+ addService(groupId: string, options: Omit<ServiceRegisterOptions, 'groupId'>): Promise<Service>;
291
+ createShares(groupId: string, options: {
292
+ name: string;
293
+ description?: string;
294
+ expiresIn?: string;
295
+ }): Promise<Array<{
296
+ id: string;
297
+ token: string;
298
+ serviceName: string;
299
+ shareUrl: string;
300
+ }>>;
301
+ delete(id: string): Promise<{
302
+ deletedServices: number;
303
+ }>;
304
+ }
171
305
  export declare class PrivateConnect {
172
306
  private config;
173
- /** Agents API for discovery and orchestration */
307
+ private manifest;
308
+ private manifestPath?;
309
+ /** Agents API for discovery, orchestration, and provisioning */
174
310
  agents: AgentsAPI;
175
- /** Services API for connecting to services */
311
+ /** Services API for registering, connecting to, and managing services */
176
312
  services: ServicesAPI;
177
313
  /** Grants API for managing scoped access tokens (time-limited or persistent) */
178
314
  grants: GrantsAPI;
179
- constructor(config: PrivateConnectConfig);
315
+ /** Shares API for creating and managing service share links */
316
+ shares: SharesAPI;
317
+ /** Groups API for managing service groups (per-branch, per-project environments) */
318
+ groups: GroupsAPI;
319
+ constructor(config?: PrivateConnectConfig);
320
+ /**
321
+ * Load a pconnect.yml manifest and return a configured client.
322
+ *
323
+ * Auto-discovers pconnect.yml in the current directory (or parents) if no
324
+ * path is given. Pass a config to also enable hub API access.
325
+ *
326
+ * @example
327
+ * ```typescript
328
+ * const pc = PrivateConnect.fromManifest();
329
+ * const db = pc.resource('staging-db');
330
+ * console.log(db.connectionString); // postgres://internal-db:5432
331
+ * ```
332
+ */
333
+ static fromManifest(manifestPath?: string, config?: PrivateConnectConfig): PrivateConnect;
334
+ /**
335
+ * Get a resource declared in pconnect.yml by name.
336
+ *
337
+ * Returns its type, host, port, connection string, and suggested env var.
338
+ * When `connect dev` is running, the connection string points to a live
339
+ * local tunnel.
340
+ */
341
+ resource(name: string): ManifestResource;
342
+ /**
343
+ * List all resources declared in the loaded manifest.
344
+ */
345
+ resources(): ManifestResource[];
346
+ /**
347
+ * Generate a `.env`-compatible block for all manifest resources.
348
+ *
349
+ * @example
350
+ * ```typescript
351
+ * const pc = PrivateConnect.fromManifest();
352
+ * console.log(pc.envBlock());
353
+ * // DATABASE_URL=postgres://internal-db:5432
354
+ * // REDIS_URL=redis://redis.internal:6379
355
+ * ```
356
+ */
357
+ envBlock(): string;
180
358
  /** The resolved agent ID, or undefined if not configured. */
181
359
  get agentId(): string | undefined;
182
360
  /** The hub URL this client is connected to. */
@@ -193,11 +371,18 @@ export declare class PrivateConnect {
193
371
  * Used by APIs that require an authenticated agent identity.
194
372
  */
195
373
  requireAgentId(): string;
374
+ /** Requires an API key or throws. */
375
+ private requireApiKey;
196
376
  /** Internal fetch with API key auth. */
197
- fetch(path: string, options?: RequestInit): Promise<Response>;
377
+ fetch(urlPath: string, options?: RequestInit): Promise<Response>;
198
378
  }
199
379
  export default PrivateConnect;
200
- /** Convenience function for quick one-off connections. */
380
+ /** Convenience function for quick one-off connections via the hub API. */
201
381
  export declare function connect(serviceName: string, config?: PrivateConnectConfig & {
202
382
  grantToken?: string;
203
383
  }): Promise<Connection>;
384
+ /**
385
+ * Load pconnect.yml and get a resource by name.
386
+ * Shorthand for `PrivateConnect.fromManifest().resource(name)`.
387
+ */
388
+ export declare function fromManifest(manifestPath?: string): PrivateConnect;