@agentimprint/sdk 0.1.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/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # @agentimprint/sdk
2
+
3
+ TypeScript SDK for [Agent Imprint](https://agentimprint.ai) — sovereign memory infrastructure for AI agents.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @agentimprint/sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { ImprintClient } from '@agentimprint/sdk';
15
+
16
+ const client = new ImprintClient({
17
+ apiKey: 'your-api-key',
18
+ baseUrl: 'https://agentimprint.ai/api/v1',
19
+ });
20
+
21
+ // Create a vault
22
+ const vault = await client.vaults.create({
23
+ name: 'my-agent-memory',
24
+ description: 'Persistent memory for my AI agent',
25
+ });
26
+
27
+ // Store a memory
28
+ await client.entries.create(vault.id, {
29
+ type: 'lesson',
30
+ content: 'User prefers concise responses over verbose explanations',
31
+ confidence: 0.9,
32
+ tags: ['preferences', 'communication'],
33
+ });
34
+
35
+ // Search memories
36
+ const results = await client.entries.search(vault.id, {
37
+ query: 'user preferences',
38
+ });
39
+ ```
40
+
41
+ ## Features
42
+
43
+ - **Vault Management** — Create, read, update encrypted memory vaults
44
+ - **Entry CRUD** — Store and retrieve memories in ImprintML format
45
+ - **Agent Identity** — Ed25519 fingerprinting and agent discovery
46
+ - **Client-Side Encryption** — AES-256-GCM with HKDF key derivation
47
+ - **Key Recovery** — Shamir secret sharing (3-of-5)
48
+ - **Merkle Integrity** — Cryptographic audit trails for all entries
49
+ - **Zero Dependencies** — Uses Web Crypto API only
50
+
51
+ ## Entry Types
52
+
53
+ ImprintML supports these memory types:
54
+
55
+ | Type | Description |
56
+ |------|-------------|
57
+ | `lesson` | Something learned from experience |
58
+ | `heuristic` | A rule of thumb or decision pattern |
59
+ | `fact` | A known piece of information |
60
+ | `preference` | A user or agent preference |
61
+ | `pattern` | A recurring behavior or sequence |
62
+ | `relationship` | A connection between entities |
63
+ | `negative` | Something to avoid |
64
+ | `procedural` | Step-by-step process knowledge |
65
+
66
+ ## Encryption
67
+
68
+ All vault contents can be encrypted client-side before transmission:
69
+
70
+ ```typescript
71
+ import { ImprintCrypto } from '@agentimprint/sdk';
72
+
73
+ const crypto = new ImprintCrypto();
74
+ const key = await crypto.generateKey();
75
+ const encrypted = await crypto.encrypt(key, 'sensitive memory data');
76
+ const decrypted = await crypto.decrypt(key, encrypted);
77
+ ```
78
+
79
+ ## Documentation
80
+
81
+ Full API docs: [agentimprint.ai/docs](https://agentimprint.ai/docs)
82
+
83
+ ## License
84
+
85
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,436 @@
1
+ 'use strict';
2
+
3
+ // src/errors.ts
4
+ var ImprintApiError = class _ImprintApiError extends Error {
5
+ constructor(message, status, body, code) {
6
+ super(message);
7
+ this.name = "ImprintApiError";
8
+ this.status = status;
9
+ this.code = code;
10
+ this.body = body;
11
+ Object.setPrototypeOf(this, _ImprintApiError.prototype);
12
+ }
13
+ };
14
+ var ImprintValidationError = class _ImprintValidationError extends ImprintApiError {
15
+ constructor(message, errors, body) {
16
+ super(message, 422, body, "VALIDATION_ERROR");
17
+ this.name = "ImprintValidationError";
18
+ this.errors = errors;
19
+ Object.setPrototypeOf(this, _ImprintValidationError.prototype);
20
+ }
21
+ };
22
+ var ImprintAuthError = class _ImprintAuthError extends ImprintApiError {
23
+ constructor(message = "Unauthorized \u2014 check your API key", body) {
24
+ super(message, 401, body, "AUTH_ERROR");
25
+ this.name = "ImprintAuthError";
26
+ Object.setPrototypeOf(this, _ImprintAuthError.prototype);
27
+ }
28
+ };
29
+ var ImprintNotFoundError = class _ImprintNotFoundError extends ImprintApiError {
30
+ constructor(message = "Resource not found", body) {
31
+ super(message, 404, body, "NOT_FOUND");
32
+ this.name = "ImprintNotFoundError";
33
+ Object.setPrototypeOf(this, _ImprintNotFoundError.prototype);
34
+ }
35
+ };
36
+
37
+ // src/http.ts
38
+ var HttpClient = class {
39
+ constructor(apiKey, baseUrl) {
40
+ this.apiKey = apiKey;
41
+ this.baseUrl = baseUrl.replace(/\/$/, "");
42
+ }
43
+ buildUrl(path, params) {
44
+ const url = new URL(`${this.baseUrl}${path}`);
45
+ if (params) {
46
+ for (const [key, value] of Object.entries(params)) {
47
+ if (value !== void 0) {
48
+ url.searchParams.set(key, String(value));
49
+ }
50
+ }
51
+ }
52
+ return url.toString();
53
+ }
54
+ async request(method, path, options = {}) {
55
+ const { body, params, requiresAuth = true } = options;
56
+ const url = this.buildUrl(path, params);
57
+ const headers = {
58
+ "Content-Type": "application/json",
59
+ Accept: "application/json"
60
+ };
61
+ if (requiresAuth) {
62
+ headers["X-API-Key"] = this.apiKey;
63
+ }
64
+ const response = await fetch(url, {
65
+ method,
66
+ headers,
67
+ body: body !== void 0 ? JSON.stringify(body) : void 0
68
+ });
69
+ let responseBody;
70
+ const contentType = response.headers.get("content-type") ?? "";
71
+ if (contentType.includes("application/json")) {
72
+ responseBody = await response.json();
73
+ } else {
74
+ responseBody = await response.text();
75
+ }
76
+ if (!response.ok) {
77
+ await this.throwError(response.status, responseBody);
78
+ }
79
+ return responseBody;
80
+ }
81
+ async throwError(status, body) {
82
+ const bodyObj = typeof body === "object" && body !== null ? body : {};
83
+ const message = typeof bodyObj["message"] === "string" ? bodyObj["message"] : `HTTP ${status}`;
84
+ switch (status) {
85
+ case 401:
86
+ throw new ImprintAuthError(message, body);
87
+ case 404:
88
+ throw new ImprintNotFoundError(message, body);
89
+ case 422: {
90
+ const errors = bodyObj["errors"] ?? {};
91
+ throw new ImprintValidationError(message, errors, body);
92
+ }
93
+ default:
94
+ throw new ImprintApiError(message, status, body);
95
+ }
96
+ }
97
+ async get(path, params, requiresAuth = true) {
98
+ return this.request("GET", path, { params, requiresAuth });
99
+ }
100
+ async post(path, body, requiresAuth = true) {
101
+ return this.request("POST", path, { body, requiresAuth });
102
+ }
103
+ async put(path, body) {
104
+ return this.request("PUT", path, { body });
105
+ }
106
+ async delete(path) {
107
+ return this.request("DELETE", path);
108
+ }
109
+ };
110
+
111
+ // src/resources/agents.ts
112
+ var AgentsResource = class {
113
+ constructor(http) {
114
+ this.http = http;
115
+ }
116
+ async create(params) {
117
+ const response = await this.http.post("/api/v1/agents", params);
118
+ return response.data;
119
+ }
120
+ async list() {
121
+ const response = await this.http.get("/api/v1/agents");
122
+ return response.data;
123
+ }
124
+ async get(uuid) {
125
+ const response = await this.http.get(`/api/v1/agents/${uuid}`);
126
+ return response.data;
127
+ }
128
+ async discover(fingerprint) {
129
+ const response = await this.http.get(
130
+ `/api/v1/agents/discover/${fingerprint}`
131
+ );
132
+ return response.data;
133
+ }
134
+ async generateKey(uuid) {
135
+ const response = await this.http.post(
136
+ `/api/v1/agents/${uuid}/keys/generate`
137
+ );
138
+ return response.data;
139
+ }
140
+ async splitKey(uuid, params) {
141
+ const response = await this.http.post(
142
+ `/api/v1/agents/${uuid}/keys/split`,
143
+ params
144
+ );
145
+ return response.data;
146
+ }
147
+ async recoverKey(uuid, shares) {
148
+ const response = await this.http.post(
149
+ `/api/v1/agents/${uuid}/keys/recover`,
150
+ { shares }
151
+ );
152
+ return response.data;
153
+ }
154
+ };
155
+
156
+ // src/resources/entries.ts
157
+ var EntriesResource = class {
158
+ constructor(http) {
159
+ this.http = http;
160
+ }
161
+ async list(vaultUuid, params) {
162
+ const response = await this.http.get(
163
+ `/api/v1/vaults/${vaultUuid}/entries`,
164
+ params
165
+ );
166
+ const pagination = response.meta?.pagination ?? {};
167
+ return { entries: response.data, pagination };
168
+ }
169
+ async create(vaultUuid, entry) {
170
+ const response = await this.http.post(
171
+ `/api/v1/vaults/${vaultUuid}/entries`,
172
+ entry
173
+ );
174
+ return response.data;
175
+ }
176
+ async createBulk(vaultUuid, entries) {
177
+ const response = await this.http.post(
178
+ `/api/v1/vaults/${vaultUuid}/entries/bulk`,
179
+ { entries }
180
+ );
181
+ return response.data;
182
+ }
183
+ async get(vaultUuid, entryUuid) {
184
+ const response = await this.http.get(
185
+ `/api/v1/vaults/${vaultUuid}/entries/${entryUuid}`
186
+ );
187
+ return response.data;
188
+ }
189
+ async update(vaultUuid, entryUuid, data) {
190
+ const response = await this.http.put(
191
+ `/api/v1/vaults/${vaultUuid}/entries/${entryUuid}`,
192
+ data
193
+ );
194
+ return response.data;
195
+ }
196
+ async delete(vaultUuid, entryUuid) {
197
+ await this.http.delete(`/api/v1/vaults/${vaultUuid}/entries/${entryUuid}`);
198
+ }
199
+ };
200
+
201
+ // src/resources/organizations.ts
202
+ var OrganizationsResource = class {
203
+ constructor(http) {
204
+ this.http = http;
205
+ }
206
+ async create(name) {
207
+ const response = await this.http.post(
208
+ "/api/v1/organizations",
209
+ { name },
210
+ false
211
+ );
212
+ return { ...response.data, apiKey: response.api_key };
213
+ }
214
+ async get(uuid) {
215
+ const response = await this.http.get(`/api/v1/organizations/${uuid}`);
216
+ return response.data;
217
+ }
218
+ };
219
+
220
+ // src/resources/vaults.ts
221
+ var VaultsResource = class {
222
+ constructor(http) {
223
+ this.http = http;
224
+ }
225
+ async create(params) {
226
+ const response = await this.http.post("/api/v1/vaults", params);
227
+ return response.data;
228
+ }
229
+ async list() {
230
+ const response = await this.http.get("/api/v1/vaults");
231
+ return response.data;
232
+ }
233
+ async get(uuid) {
234
+ const response = await this.http.get(`/api/v1/vaults/${uuid}`);
235
+ return response.data;
236
+ }
237
+ async stats(uuid) {
238
+ const response = await this.http.get(`/api/v1/vaults/${uuid}/stats`);
239
+ return response.data;
240
+ }
241
+ async export(uuid) {
242
+ const response = await this.http.get(`/api/v1/vaults/${uuid}/export`);
243
+ return response.data;
244
+ }
245
+ async import(uuid, data) {
246
+ const response = await this.http.post(
247
+ `/api/v1/vaults/${uuid}/import`,
248
+ data
249
+ );
250
+ return response.data;
251
+ }
252
+ async merkle(uuid) {
253
+ const response = await this.http.get(`/api/v1/vaults/${uuid}/merkle`);
254
+ return response.data;
255
+ }
256
+ async verify(uuid) {
257
+ const response = await this.http.post(
258
+ `/api/v1/vaults/${uuid}/verify`
259
+ );
260
+ return response.data;
261
+ }
262
+ async snapshot(uuid) {
263
+ const response = await this.http.post(
264
+ `/api/v1/vaults/${uuid}/snapshot`
265
+ );
266
+ return response.data;
267
+ }
268
+ async snapshots(uuid) {
269
+ const response = await this.http.get(`/api/v1/vaults/${uuid}/snapshots`);
270
+ return response.data;
271
+ }
272
+ };
273
+
274
+ // src/client.ts
275
+ var DEFAULT_BASE_URL = "https://api.agentimprint.io";
276
+ var ImprintClient = class {
277
+ /**
278
+ * Public discovery — check if an agent fingerprint exists (no auth required).
279
+ * Uses the unauthenticated /api/v1/discover endpoint.
280
+ */
281
+ static async probe(fingerprint, baseUrl) {
282
+ const url = (baseUrl ?? DEFAULT_BASE_URL) + "/api/v1/discover/" + encodeURIComponent(fingerprint);
283
+ const response = await fetch(url);
284
+ if (!response.ok) {
285
+ throw new Error("Discovery probe failed: " + response.status);
286
+ }
287
+ const json = await response.json();
288
+ return json.data;
289
+ }
290
+ constructor(config) {
291
+ if (!config.apiKey) {
292
+ throw new Error("ImprintClient: apiKey is required");
293
+ }
294
+ const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
295
+ this.http = new HttpClient(config.apiKey, baseUrl);
296
+ this.organizations = new OrganizationsResource(this.http);
297
+ this.agents = new AgentsResource(this.http);
298
+ this.vaults = new VaultsResource(this.http);
299
+ this.entries = new EntriesResource(this.http);
300
+ }
301
+ };
302
+
303
+ // src/fingerprint.ts
304
+ function getCrypto() {
305
+ if (typeof globalThis !== "undefined" && globalThis.crypto) {
306
+ return globalThis.crypto;
307
+ }
308
+ throw new Error("Web Crypto API not available in this environment");
309
+ }
310
+ async function sha256Hex(input) {
311
+ const data = new TextEncoder().encode(input);
312
+ const hashBuffer = await getCrypto().subtle.digest("SHA-256", data);
313
+ const hashArray = new Uint8Array(hashBuffer);
314
+ return Array.from(hashArray).map((b) => b.toString(16).padStart(2, "0")).join("");
315
+ }
316
+ async function computeFingerprint(params) {
317
+ const { model_family, core_purpose, creator_identifier } = params;
318
+ const purposeHash = await sha256Hex(core_purpose);
319
+ const combined = `${model_family}${purposeHash}${creator_identifier}`;
320
+ return sha256Hex(combined);
321
+ }
322
+
323
+ // src/crypto.ts
324
+ var ALGORITHM = "AES-GCM";
325
+ var KEY_LENGTH = 256;
326
+ var IV_LENGTH = 12;
327
+ function hexToBytes(hex) {
328
+ const bytes = new Uint8Array(hex.length / 2);
329
+ for (let i = 0; i < hex.length; i += 2) {
330
+ bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
331
+ }
332
+ return bytes;
333
+ }
334
+ function toArrayBuffer(bytes) {
335
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
336
+ }
337
+ function bytesToHex(bytes) {
338
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
339
+ }
340
+ function getCrypto2() {
341
+ if (typeof globalThis !== "undefined" && globalThis.crypto) {
342
+ return globalThis.crypto;
343
+ }
344
+ throw new Error("Web Crypto API not available in this environment");
345
+ }
346
+ async function importAesKey(keyHex, usages) {
347
+ const keyBytes = hexToBytes(keyHex);
348
+ return getCrypto2().subtle.importKey("raw", toArrayBuffer(keyBytes), { name: ALGORITHM }, false, usages);
349
+ }
350
+ async function hkdfDerive(masterKeyHex, info) {
351
+ const crypto = getCrypto2();
352
+ const masterKeyBytes = hexToBytes(masterKeyHex);
353
+ const baseKey = await crypto.subtle.importKey(
354
+ "raw",
355
+ toArrayBuffer(masterKeyBytes),
356
+ { name: "HKDF" },
357
+ false,
358
+ ["deriveKey"]
359
+ );
360
+ const infoBytes = new TextEncoder().encode(info);
361
+ const derivedKey = await crypto.subtle.deriveKey(
362
+ {
363
+ name: "HKDF",
364
+ hash: "SHA-256",
365
+ salt: new Uint8Array(32),
366
+ info: infoBytes
367
+ },
368
+ baseKey,
369
+ { name: ALGORITHM, length: KEY_LENGTH },
370
+ true,
371
+ ["encrypt", "decrypt"]
372
+ );
373
+ const exported = await crypto.subtle.exportKey("raw", derivedKey);
374
+ return bytesToHex(new Uint8Array(exported));
375
+ }
376
+ function generateKey() {
377
+ const bytes = new Uint8Array(32);
378
+ getCrypto2().getRandomValues(bytes);
379
+ return bytesToHex(bytes);
380
+ }
381
+ async function deriveVaultKey(masterKey, vaultUuid) {
382
+ return hkdfDerive(masterKey, `vault:${vaultUuid}`);
383
+ }
384
+ async function deriveEntryKey(vaultKey, entryUuid) {
385
+ return hkdfDerive(vaultKey, `entry:${entryUuid}`);
386
+ }
387
+ async function encrypt(keyHex, data) {
388
+ const crypto = getCrypto2();
389
+ const cryptoKey = await importAesKey(keyHex, ["encrypt"]);
390
+ const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
391
+ const plaintext = new TextEncoder().encode(JSON.stringify(data));
392
+ const ciphertextWithTag = await crypto.subtle.encrypt(
393
+ { name: ALGORITHM, iv: toArrayBuffer(iv) },
394
+ cryptoKey,
395
+ toArrayBuffer(plaintext)
396
+ );
397
+ const ciphertextWithTagBytes = new Uint8Array(ciphertextWithTag);
398
+ const ciphertext = ciphertextWithTagBytes.slice(0, -16);
399
+ const tag = ciphertextWithTagBytes.slice(-16);
400
+ return {
401
+ ciphertext: bytesToHex(ciphertext),
402
+ iv: bytesToHex(iv),
403
+ tag: bytesToHex(tag),
404
+ algorithm: "AES-256-GCM"
405
+ };
406
+ }
407
+ async function decrypt(keyHex, payload) {
408
+ const cryptoKey = await importAesKey(keyHex, ["decrypt"]);
409
+ const iv = hexToBytes(payload.iv);
410
+ const ciphertext = hexToBytes(payload.ciphertext);
411
+ const tag = hexToBytes(payload.tag);
412
+ const combined = new Uint8Array(ciphertext.length + tag.length);
413
+ combined.set(ciphertext);
414
+ combined.set(tag, ciphertext.length);
415
+ const plaintext = await getCrypto2().subtle.decrypt(
416
+ { name: ALGORITHM, iv: toArrayBuffer(iv) },
417
+ cryptoKey,
418
+ toArrayBuffer(combined)
419
+ );
420
+ return JSON.parse(new TextDecoder().decode(plaintext));
421
+ }
422
+
423
+ exports.DEFAULT_BASE_URL = DEFAULT_BASE_URL;
424
+ exports.ImprintApiError = ImprintApiError;
425
+ exports.ImprintAuthError = ImprintAuthError;
426
+ exports.ImprintClient = ImprintClient;
427
+ exports.ImprintNotFoundError = ImprintNotFoundError;
428
+ exports.ImprintValidationError = ImprintValidationError;
429
+ exports.computeFingerprint = computeFingerprint;
430
+ exports.decrypt = decrypt;
431
+ exports.deriveEntryKey = deriveEntryKey;
432
+ exports.deriveVaultKey = deriveVaultKey;
433
+ exports.encrypt = encrypt;
434
+ exports.generateKey = generateKey;
435
+ //# sourceMappingURL=index.cjs.map
436
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/agents.ts","../src/resources/entries.ts","../src/resources/organizations.ts","../src/resources/vaults.ts","../src/client.ts","../src/fingerprint.ts","../src/crypto.ts"],"names":["getCrypto"],"mappings":"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","file":"index.cjs","sourcesContent":["// ============================================================\n// Agent Imprint SDK — Typed Errors\n// ============================================================\n\nexport class ImprintApiError extends Error {\n public readonly status: number;\n public readonly code: string | undefined;\n public readonly body: unknown;\n\n constructor(\n message: string,\n status: number,\n body?: unknown,\n code?: string,\n ) {\n super(message);\n this.name = 'ImprintApiError';\n this.status = status;\n this.code = code;\n this.body = body;\n Object.setPrototypeOf(this, ImprintApiError.prototype);\n }\n}\n\nexport class ImprintValidationError extends ImprintApiError {\n public readonly errors: Record<string, string[]>;\n\n constructor(\n message: string,\n errors: Record<string, string[]>,\n body?: unknown,\n ) {\n super(message, 422, body, 'VALIDATION_ERROR');\n this.name = 'ImprintValidationError';\n this.errors = errors;\n Object.setPrototypeOf(this, ImprintValidationError.prototype);\n }\n}\n\nexport class ImprintAuthError extends ImprintApiError {\n constructor(message: string = 'Unauthorized — check your API key', body?: unknown) {\n super(message, 401, body, 'AUTH_ERROR');\n this.name = 'ImprintAuthError';\n Object.setPrototypeOf(this, ImprintAuthError.prototype);\n }\n}\n\nexport class ImprintNotFoundError extends ImprintApiError {\n constructor(message: string = 'Resource not found', body?: unknown) {\n super(message, 404, body, 'NOT_FOUND');\n this.name = 'ImprintNotFoundError';\n Object.setPrototypeOf(this, ImprintNotFoundError.prototype);\n }\n}\n","// ============================================================\n// Agent Imprint SDK — HTTP Transport\n// ============================================================\n\nimport {\n ImprintApiError,\n ImprintAuthError,\n ImprintNotFoundError,\n ImprintValidationError,\n} from './errors.js';\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n\n constructor(apiKey: string, baseUrl: string) {\n this.apiKey = apiKey;\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n }\n\n private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(`${this.baseUrl}${path}`);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n return url.toString();\n }\n\n private async request<T>(\n method: string,\n path: string,\n options: {\n body?: unknown;\n params?: Record<string, string | number | boolean | undefined>;\n requiresAuth?: boolean;\n } = {},\n ): Promise<T> {\n const { body, params, requiresAuth = true } = options;\n const url = this.buildUrl(path, params);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n\n if (requiresAuth) {\n headers['X-API-Key'] = this.apiKey;\n }\n\n const response = await fetch(url, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n\n let responseBody: unknown;\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n responseBody = await response.json();\n } else {\n responseBody = await response.text();\n }\n\n if (!response.ok) {\n await this.throwError(response.status, responseBody);\n }\n\n return responseBody as T;\n }\n\n private async throwError(status: number, body: unknown): Promise<never> {\n const bodyObj = typeof body === 'object' && body !== null ? body as Record<string, unknown> : {};\n const message = typeof bodyObj['message'] === 'string' ? bodyObj['message'] : `HTTP ${status}`;\n\n switch (status) {\n case 401:\n throw new ImprintAuthError(message, body);\n case 404:\n throw new ImprintNotFoundError(message, body);\n case 422: {\n const errors = (bodyObj['errors'] as Record<string, string[]>) ?? {};\n throw new ImprintValidationError(message, errors, body);\n }\n default:\n throw new ImprintApiError(message, status, body);\n }\n }\n\n async get<T>(path: string, params?: Record<string, string | number | boolean | undefined>, requiresAuth = true): Promise<T> {\n return this.request<T>('GET', path, { params, requiresAuth });\n }\n\n async post<T>(path: string, body?: unknown, requiresAuth = true): Promise<T> {\n return this.request<T>('POST', path, { body, requiresAuth });\n }\n\n async put<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PUT', path, { body });\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>('DELETE', path);\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type {\n Agent,\n CreateAgentParams,\n DiscoverResult,\n GenerateKeyResult,\n RecoverKeyResult,\n SplitKeyParams,\n SplitKeyResult,\n} from '../types.js';\n\nexport class AgentsResource {\n constructor(private readonly http: HttpClient) {}\n\n async create(params: CreateAgentParams): Promise<Agent> {\n const response = await this.http.post<{ data: Agent }>('/api/v1/agents', params);\n return response.data;\n }\n\n async list(): Promise<Agent[]> {\n const response = await this.http.get<{ data: Agent[] }>('/api/v1/agents');\n return response.data;\n }\n\n async get(uuid: string): Promise<Agent> {\n const response = await this.http.get<{ data: Agent }>(`/api/v1/agents/${uuid}`);\n return response.data;\n }\n\n async discover(fingerprint: string): Promise<DiscoverResult> {\n const response = await this.http.get<{ data: DiscoverResult }>(\n `/api/v1/agents/discover/${fingerprint}`,\n );\n return response.data;\n }\n\n async generateKey(uuid: string): Promise<GenerateKeyResult> {\n const response = await this.http.post<{ data: GenerateKeyResult }>(\n `/api/v1/agents/${uuid}/keys/generate`,\n );\n return response.data;\n }\n\n async splitKey(uuid: string, params: SplitKeyParams): Promise<SplitKeyResult> {\n const response = await this.http.post<{ data: SplitKeyResult }>(\n `/api/v1/agents/${uuid}/keys/split`,\n params,\n );\n return response.data;\n }\n\n async recoverKey(uuid: string, shares: string[]): Promise<RecoverKeyResult> {\n const response = await this.http.post<{ data: RecoverKeyResult }>(\n `/api/v1/agents/${uuid}/keys/recover`,\n { shares },\n );\n return response.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type {\n BulkResult,\n CreateEntryParams,\n Entry,\n ListEntriesParams,\n PaginatedEntries,\n UpdateEntryParams,\n} from '../types.js';\n\nexport class EntriesResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(vaultUuid: string, params?: ListEntriesParams): Promise<PaginatedEntries> {\n const response = await this.http.get<{ data: Entry[]; meta: Record<string, unknown> }>(\n `/api/v1/vaults/${vaultUuid}/entries`,\n params as Record<string, string | number | boolean | undefined>,\n );\n const pagination = (response.meta?.pagination ?? {}) as PaginatedEntries['pagination'];\n return { entries: response.data, pagination };\n }\n\n async create(vaultUuid: string, entry: CreateEntryParams): Promise<Entry> {\n const response = await this.http.post<{ data: Entry }>(\n `/api/v1/vaults/${vaultUuid}/entries`,\n entry,\n );\n return response.data;\n }\n\n async createBulk(vaultUuid: string, entries: CreateEntryParams[]): Promise<BulkResult> {\n const response = await this.http.post<{ data: BulkResult }>(\n `/api/v1/vaults/${vaultUuid}/entries/bulk`,\n { entries },\n );\n return response.data;\n }\n\n async get(vaultUuid: string, entryUuid: string): Promise<Entry> {\n const response = await this.http.get<{ data: Entry }>(\n `/api/v1/vaults/${vaultUuid}/entries/${entryUuid}`,\n );\n return response.data;\n }\n\n async update(vaultUuid: string, entryUuid: string, data: UpdateEntryParams): Promise<Entry> {\n const response = await this.http.put<{ data: Entry }>(\n `/api/v1/vaults/${vaultUuid}/entries/${entryUuid}`,\n data,\n );\n return response.data;\n }\n\n async delete(vaultUuid: string, entryUuid: string): Promise<void> {\n await this.http.delete<void>(`/api/v1/vaults/${vaultUuid}/entries/${entryUuid}`);\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { Organization, OrganizationWithKey } from '../types.js';\n\nexport class OrganizationsResource {\n constructor(private readonly http: HttpClient) {}\n\n async create(name: string): Promise<OrganizationWithKey> {\n const response = await this.http.post<{ data: Organization; api_key: string }>(\n '/api/v1/organizations',\n { name },\n false,\n );\n return { ...response.data, apiKey: response.api_key };\n }\n\n async get(uuid: string): Promise<Organization> {\n const response = await this.http.get<{ data: Organization }>(`/api/v1/organizations/${uuid}`);\n return response.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type {\n CreateVaultParams,\n ImportResult,\n MerkleInfo,\n Snapshot,\n Vault,\n VaultExport,\n VaultStats,\n VerifyResult,\n} from '../types.js';\n\nexport class VaultsResource {\n constructor(private readonly http: HttpClient) {}\n\n async create(params: CreateVaultParams): Promise<Vault> {\n const response = await this.http.post<{ data: Vault }>('/api/v1/vaults', params);\n return response.data;\n }\n\n async list(): Promise<Vault[]> {\n const response = await this.http.get<{ data: Vault[] }>('/api/v1/vaults');\n return response.data;\n }\n\n async get(uuid: string): Promise<Vault> {\n const response = await this.http.get<{ data: Vault }>(`/api/v1/vaults/${uuid}`);\n return response.data;\n }\n\n async stats(uuid: string): Promise<VaultStats> {\n const response = await this.http.get<{ data: VaultStats }>(`/api/v1/vaults/${uuid}/stats`);\n return response.data;\n }\n\n async export(uuid: string): Promise<VaultExport> {\n const response = await this.http.get<{ data: VaultExport }>(`/api/v1/vaults/${uuid}/export`);\n return response.data;\n }\n\n async import(uuid: string, data: VaultExport): Promise<ImportResult> {\n const response = await this.http.post<{ data: ImportResult }>(\n `/api/v1/vaults/${uuid}/import`,\n data,\n );\n return response.data;\n }\n\n async merkle(uuid: string): Promise<MerkleInfo> {\n const response = await this.http.get<{ data: MerkleInfo }>(`/api/v1/vaults/${uuid}/merkle`);\n return response.data;\n }\n\n async verify(uuid: string): Promise<VerifyResult> {\n const response = await this.http.post<{ data: VerifyResult }>(\n `/api/v1/vaults/${uuid}/verify`,\n );\n return response.data;\n }\n\n async snapshot(uuid: string): Promise<Snapshot> {\n const response = await this.http.post<{ data: Snapshot }>(\n `/api/v1/vaults/${uuid}/snapshot`,\n );\n return response.data;\n }\n\n async snapshots(uuid: string): Promise<Snapshot[]> {\n const response = await this.http.get<{ data: Snapshot[] }>(`/api/v1/vaults/${uuid}/snapshots`);\n return response.data;\n }\n}\n","// ============================================================\n// Agent Imprint SDK — Main Client\n// ============================================================\n\nimport { HttpClient } from './http.js';\nimport { AgentsResource } from './resources/agents.js';\nimport { EntriesResource } from './resources/entries.js';\nimport { OrganizationsResource } from './resources/organizations.js';\nimport { VaultsResource } from './resources/vaults.js';\nimport type { ImprintClientConfig } from './types.js';\n\nexport const DEFAULT_BASE_URL = 'https://api.agentimprint.io';\n\n/**\n * ImprintClient — main entry point for the Agent Imprint SDK.\n *\n * @example\n * ```ts\n * const client = new ImprintClient({ apiKey: 'your-api-key' });\n * const agents = await client.agents.list();\n * ```\n */\nexport class ImprintClient {\n public readonly organizations: OrganizationsResource;\n public readonly agents: AgentsResource;\n public readonly vaults: VaultsResource;\n public readonly entries: EntriesResource;\n\n private readonly http: HttpClient;\n\n /**\n * Public discovery — check if an agent fingerprint exists (no auth required).\n * Uses the unauthenticated /api/v1/discover endpoint.\n */\n static async probe(fingerprint: string, baseUrl?: string): Promise<{ exists: boolean }> {\n const url = (baseUrl ?? DEFAULT_BASE_URL) + '/api/v1/discover/' + encodeURIComponent(fingerprint);\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error('Discovery probe failed: ' + response.status);\n }\n const json = await response.json() as { data: { exists: boolean } };\n return json.data;\n }\n\n constructor(config: ImprintClientConfig) {\n if (!config.apiKey) {\n throw new Error('ImprintClient: apiKey is required');\n }\n\n const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;\n this.http = new HttpClient(config.apiKey, baseUrl);\n\n this.organizations = new OrganizationsResource(this.http);\n this.agents = new AgentsResource(this.http);\n this.vaults = new VaultsResource(this.http);\n this.entries = new EntriesResource(this.http);\n }\n}\n","// ============================================================\n// Agent Imprint SDK — Fingerprint Helper\n// Matches server-side algorithm:\n// sha256(model_family + sha256(core_purpose) + creator_identifier)\n// ============================================================\n\nimport type { FingerprintComponents } from './types.js';\n\nfunction getCrypto(): Crypto {\n if (typeof globalThis !== 'undefined' && globalThis.crypto) {\n return globalThis.crypto;\n }\n throw new Error('Web Crypto API not available in this environment');\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const data = new TextEncoder().encode(input);\n const hashBuffer = await getCrypto().subtle.digest('SHA-256', data);\n const hashArray = new Uint8Array(hashBuffer);\n return Array.from(hashArray)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Compute a deterministic agent fingerprint that matches the server-side algorithm.\n *\n * Algorithm: sha256(model_family + sha256(core_purpose) + creator_identifier)\n */\nexport async function computeFingerprint(params: FingerprintComponents): Promise<string> {\n const { model_family, core_purpose, creator_identifier } = params;\n const purposeHash = await sha256Hex(core_purpose);\n const combined = `${model_family}${purposeHash}${creator_identifier}`;\n return sha256Hex(combined);\n}\n","// ============================================================\n// Agent Imprint SDK — Encryption Helpers (Web Crypto API)\n// Works in Node.js 18+ (globalThis.crypto) and browsers\n// ============================================================\n\nimport type { EncryptedPayload } from './types.js';\n\nconst ALGORITHM = 'AES-GCM';\nconst KEY_LENGTH = 256;\nconst IV_LENGTH = 12; // 96-bit IV for AES-GCM\n\n// ─── Utility ───────────────────────────────────────────────\n\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);\n }\n return bytes;\n}\n\nfunction toArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nfunction getCrypto(): Crypto {\n if (typeof globalThis !== 'undefined' && globalThis.crypto) {\n return globalThis.crypto;\n }\n throw new Error('Web Crypto API not available in this environment');\n}\n\nasync function importAesKey(keyHex: string, usages: KeyUsage[]): Promise<CryptoKey> {\n const keyBytes = hexToBytes(keyHex);\n return getCrypto().subtle.importKey('raw', toArrayBuffer(keyBytes), { name: ALGORITHM }, false, usages);\n}\n\n// ─── HKDF Key Derivation ───────────────────────────────────\n\nasync function hkdfDerive(masterKeyHex: string, info: string): Promise<string> {\n const crypto = getCrypto();\n const masterKeyBytes = hexToBytes(masterKeyHex);\n\n const baseKey = await crypto.subtle.importKey(\n 'raw',\n toArrayBuffer(masterKeyBytes),\n { name: 'HKDF' },\n false,\n ['deriveKey'],\n );\n\n const infoBytes = new TextEncoder().encode(info);\n const derivedKey = await crypto.subtle.deriveKey(\n {\n name: 'HKDF',\n hash: 'SHA-256',\n salt: new Uint8Array(32),\n info: infoBytes,\n },\n baseKey,\n { name: ALGORITHM, length: KEY_LENGTH },\n true,\n ['encrypt', 'decrypt'],\n );\n\n const exported = await crypto.subtle.exportKey('raw', derivedKey);\n return bytesToHex(new Uint8Array(exported));\n}\n\n// ─── Public API ────────────────────────────────────────────\n\n/**\n * Generate a cryptographically secure random 256-bit key (64 hex chars).\n */\nexport function generateKey(): string {\n const bytes = new Uint8Array(32);\n getCrypto().getRandomValues(bytes);\n return bytesToHex(bytes);\n}\n\n/**\n * Derive a vault-specific key from a master key and vault UUID.\n */\nexport async function deriveVaultKey(masterKey: string, vaultUuid: string): Promise<string> {\n return hkdfDerive(masterKey, `vault:${vaultUuid}`);\n}\n\n/**\n * Derive an entry-specific key from a vault key and entry UUID.\n */\nexport async function deriveEntryKey(vaultKey: string, entryUuid: string): Promise<string> {\n return hkdfDerive(vaultKey, `entry:${entryUuid}`);\n}\n\n/**\n * Encrypt a JSON-serializable object with AES-256-GCM.\n * Returns an EncryptedPayload with ciphertext, iv, and tag (all hex-encoded).\n */\nexport async function encrypt(keyHex: string, data: object): Promise<EncryptedPayload> {\n const crypto = getCrypto();\n const cryptoKey = await importAesKey(keyHex, ['encrypt']);\n const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));\n const plaintext = new TextEncoder().encode(JSON.stringify(data));\n\n const ciphertextWithTag = await crypto.subtle.encrypt(\n { name: ALGORITHM, iv: toArrayBuffer(iv) },\n cryptoKey,\n toArrayBuffer(plaintext),\n );\n\n // AES-GCM appends the 16-byte auth tag at the end\n const ciphertextWithTagBytes = new Uint8Array(ciphertextWithTag);\n const ciphertext = ciphertextWithTagBytes.slice(0, -16);\n const tag = ciphertextWithTagBytes.slice(-16);\n\n return {\n ciphertext: bytesToHex(ciphertext),\n iv: bytesToHex(iv),\n tag: bytesToHex(tag),\n algorithm: 'AES-256-GCM',\n };\n}\n\n/**\n * Decrypt an EncryptedPayload back to the original object.\n */\nexport async function decrypt(keyHex: string, payload: EncryptedPayload): Promise<object> {\n const cryptoKey = await importAesKey(keyHex, ['decrypt']);\n const iv = hexToBytes(payload.iv);\n const ciphertext = hexToBytes(payload.ciphertext);\n const tag = hexToBytes(payload.tag);\n\n // Reassemble ciphertext + tag for AES-GCM\n const combined = new Uint8Array(ciphertext.length + tag.length);\n combined.set(ciphertext);\n combined.set(tag, ciphertext.length);\n\n const plaintext = await getCrypto().subtle.decrypt(\n { name: ALGORITHM, iv: toArrayBuffer(iv) },\n cryptoKey,\n toArrayBuffer(combined),\n );\n\n return JSON.parse(new TextDecoder().decode(plaintext)) as object;\n}\n"]}