@hai.ai/jacs 0.6.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/simple.d.ts ADDED
@@ -0,0 +1,573 @@
1
+ /**
2
+ * JACS Simplified API for TypeScript/JavaScript
3
+ *
4
+ * A streamlined interface for the most common JACS operations:
5
+ * - load(): Load an existing agent from config
6
+ * - verifySelf(): Verify the loaded agent's integrity
7
+ * - signMessage(): Sign a message or data
8
+ * - verify(): Verify any signed document
9
+ * - signFile(): Sign a file with optional embedding
10
+ * - updateAgent(): Update the agent document with new data
11
+ * - updateDocument(): Update an existing document with new data
12
+ * - createAgreement(): Create a multi-party agreement
13
+ * - signAgreement(): Sign an existing agreement
14
+ * - checkAgreement(): Check agreement status
15
+ * - trustAgent(): Add an agent to the local trust store
16
+ * - listTrustedAgents(): List all trusted agent IDs
17
+ * - untrustAgent(): Remove an agent from the trust store
18
+ * - isTrusted(): Check if an agent is trusted
19
+ * - getTrustedAgent(): Get a trusted agent's JSON
20
+ * - audit(): Run a read-only security audit and health checks
21
+ *
22
+ * Also re-exports for advanced usage:
23
+ * - JacsAgent: Class for direct agent control
24
+ * - hashString: Standalone SHA-256 hashing
25
+ * - verifyString: Verify with external public key
26
+ * - createConfig: Create agent configuration
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import * as jacs from '@hai.ai/jacs/simple';
31
+ *
32
+ * // Load agent
33
+ * const agent = jacs.load('./jacs.config.json');
34
+ *
35
+ * // Sign a message
36
+ * const signed = jacs.signMessage({ action: 'approve', amount: 100 });
37
+ *
38
+ * // Verify it
39
+ * const result = jacs.verify(signed.raw);
40
+ * console.log(`Valid: ${result.valid}`);
41
+ *
42
+ * // Use standalone hash function
43
+ * const hash = jacs.hashString('data to hash');
44
+ * ```
45
+ */
46
+ import { JacsAgent, hashString, verifyString, createConfig } from './index';
47
+ /**
48
+ * Re-export utilities and classes for advanced use cases.
49
+ * Use these when you need functionality beyond the simplified API.
50
+ */
51
+ export { JacsAgent, hashString, verifyString, createConfig };
52
+ /**
53
+ * Information about a created or loaded agent.
54
+ */
55
+ export interface AgentInfo {
56
+ /** Unique identifier for the agent (UUID). */
57
+ agentId: string;
58
+ /** Human-readable name of the agent. */
59
+ name: string;
60
+ /** Path to the public key file. */
61
+ publicKeyPath: string;
62
+ /** Path to the configuration file. */
63
+ configPath: string;
64
+ }
65
+ /**
66
+ * A signed JACS document.
67
+ */
68
+ export interface SignedDocument {
69
+ /** The full JSON string of the signed JACS document. */
70
+ raw: string;
71
+ /** Unique identifier for this document (UUID). */
72
+ documentId: string;
73
+ /** ID of the agent that signed this document. */
74
+ agentId: string;
75
+ /** ISO 8601 timestamp of when the document was signed. */
76
+ timestamp: string;
77
+ }
78
+ /**
79
+ * Result of verifying a signed document.
80
+ */
81
+ export interface VerificationResult {
82
+ /** Whether the signature is valid. */
83
+ valid: boolean;
84
+ /** The original data that was signed. */
85
+ data?: any;
86
+ /** ID of the agent that signed the document. */
87
+ signerId: string;
88
+ /** Name of the signer (if available in trust store). */
89
+ signerName?: string;
90
+ /** ISO 8601 timestamp of when the document was signed. */
91
+ timestamp: string;
92
+ /** Any file attachments included in the document. */
93
+ attachments: Attachment[];
94
+ /** Error messages if verification failed. */
95
+ errors: string[];
96
+ }
97
+ /**
98
+ * A file attachment in a signed document.
99
+ */
100
+ export interface Attachment {
101
+ /** Original filename. */
102
+ filename: string;
103
+ /** MIME type of the file. */
104
+ mimeType: string;
105
+ /** File content (decoded if it was embedded). */
106
+ content?: Buffer;
107
+ /** SHA-256 hash of the original file. */
108
+ hash: string;
109
+ /** Whether the file was embedded (true) or referenced (false). */
110
+ embedded: boolean;
111
+ }
112
+ /**
113
+ * Options for HAI registration.
114
+ */
115
+ export interface HaiRegistrationOptions {
116
+ /** API key (or set HAI_API_KEY env). */
117
+ apiKey?: string;
118
+ /** HAI base URL (default "https://hai.ai"). */
119
+ haiUrl?: string;
120
+ /** If true, dry-run without sending. */
121
+ preview?: boolean;
122
+ }
123
+ /**
124
+ * Result of registering an agent with HAI.
125
+ */
126
+ export interface HaiRegistrationResult {
127
+ agentId: string;
128
+ jacsId: string;
129
+ dnsVerified: boolean;
130
+ signatures: string[];
131
+ }
132
+ /**
133
+ * Options for creating a new JACS agent.
134
+ */
135
+ export interface CreateAgentOptions {
136
+ /** Human-readable name for the agent. */
137
+ name: string;
138
+ /** Password for encrypting the private key. Falls back to JACS_PRIVATE_KEY_PASSWORD if omitted. */
139
+ password?: string;
140
+ /** Signing algorithm: "pq2025" (default), "ring-Ed25519", or "RSA-PSS". "pq-dilithium" is deprecated. */
141
+ algorithm?: string;
142
+ /** Directory for agent data (default: "./jacs_data"). */
143
+ dataDirectory?: string;
144
+ /** Directory for cryptographic keys (default: "./jacs_keys"). */
145
+ keyDirectory?: string;
146
+ /** Path to write the config file (default: "./jacs.config.json"). */
147
+ configPath?: string;
148
+ /** Agent type: "ai" (default), "human", or "hybrid". */
149
+ agentType?: string;
150
+ /** Description of the agent's purpose. */
151
+ description?: string;
152
+ /** Domain for DNS-based agent discovery. */
153
+ domain?: string;
154
+ /** Default storage backend: "fs" (default). */
155
+ defaultStorage?: string;
156
+ }
157
+ /**
158
+ * Creates a new JACS agent with cryptographic keys.
159
+ *
160
+ * This is a fully programmatic API that does not require interactive input.
161
+ * The password must be provided directly or via the JACS_PRIVATE_KEY_PASSWORD
162
+ * environment variable.
163
+ *
164
+ * @param options - Agent creation options
165
+ * @returns AgentInfo containing the agent ID, name, and file paths
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * const agent = jacs.create({
170
+ * name: 'my-agent',
171
+ * password: process.env.JACS_PRIVATE_KEY_PASSWORD,
172
+ * algorithm: 'pq2025',
173
+ * });
174
+ * console.log(`Created: ${agent.agentId}`);
175
+ * ```
176
+ */
177
+ export declare function create(options: CreateAgentOptions): AgentInfo;
178
+ /**
179
+ * Loads an existing agent from a configuration file.
180
+ *
181
+ * @param configPath - Path to jacs.config.json (default: "./jacs.config.json")
182
+ * @returns AgentInfo with the loaded agent's details
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * const agent = jacs.load('./jacs.config.json');
187
+ * console.log(`Loaded: ${agent.agentId}`);
188
+ * ```
189
+ */
190
+ export declare function load(configPath?: string): AgentInfo;
191
+ /**
192
+ * Verifies the currently loaded agent's integrity.
193
+ *
194
+ * @returns VerificationResult indicating if the agent is valid
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * const result = jacs.verifySelf();
199
+ * if (result.valid) {
200
+ * console.log('Agent integrity verified');
201
+ * }
202
+ * ```
203
+ */
204
+ export declare function verifySelf(): VerificationResult;
205
+ /**
206
+ * Signs arbitrary data as a JACS message.
207
+ *
208
+ * @param data - The data to sign (object, string, or any JSON-serializable value)
209
+ * @returns SignedDocument containing the full signed document
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * const signed = jacs.signMessage({ action: 'approve', amount: 100 });
214
+ * console.log(`Document ID: ${signed.documentId}`);
215
+ * ```
216
+ */
217
+ export declare function signMessage(data: any): SignedDocument;
218
+ /**
219
+ * Updates the agent document with new data and re-signs it.
220
+ *
221
+ * This function expects a complete agent document (not partial updates).
222
+ * Use exportAgent() to get the current document, modify it, then pass it here.
223
+ * The function will create a new version, re-sign, and re-hash the document.
224
+ *
225
+ * @param newAgentData - Complete agent document as JSON string or object
226
+ * @returns The updated and re-signed agent document as a JSON string
227
+ *
228
+ * @example
229
+ * ```typescript
230
+ * // Get current agent, modify, and update
231
+ * const agentDoc = JSON.parse(jacs.exportAgent());
232
+ * agentDoc.jacsAgentType = 'updated-service';
233
+ * const updated = jacs.updateAgent(agentDoc);
234
+ * console.log('Agent updated with new version');
235
+ * ```
236
+ */
237
+ export declare function updateAgent(newAgentData: any): string;
238
+ /**
239
+ * Updates an existing document with new data and re-signs it.
240
+ *
241
+ * Use signMessage() to create a document first, then use this to update it.
242
+ * The function will create a new version, re-sign, and re-hash the document.
243
+ *
244
+ * @param documentId - The document ID (jacsId) to update
245
+ * @param newDocumentData - The updated document as JSON string or object
246
+ * @param attachments - Optional array of file paths to attach
247
+ * @param embed - If true, embed attachment contents
248
+ * @returns SignedDocument with the updated document
249
+ *
250
+ * @example
251
+ * ```typescript
252
+ * // Create a document first
253
+ * const signed = jacs.signMessage({ status: 'pending' });
254
+ *
255
+ * // Later, update it
256
+ * const doc = JSON.parse(signed.raw);
257
+ * doc.content.status = 'approved';
258
+ * const updated = jacs.updateDocument(signed.documentId, doc);
259
+ * console.log('Document updated with new version');
260
+ * ```
261
+ */
262
+ export declare function updateDocument(documentId: string, newDocumentData: any, attachments?: string[], embed?: boolean): SignedDocument;
263
+ /**
264
+ * Signs a file with optional content embedding.
265
+ *
266
+ * @param filePath - Path to the file to sign
267
+ * @param embed - If true, embed file content in the document
268
+ * @returns SignedDocument with file attachment
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * const signed = jacs.signFile('contract.pdf', true);
273
+ * console.log(`Signed: ${signed.attachments[0].filename}`);
274
+ * ```
275
+ */
276
+ export declare function signFile(filePath: string, embed?: boolean): SignedDocument;
277
+ /**
278
+ * Verifies a signed document and extracts its content.
279
+ *
280
+ * @param signedDocument - The JSON string of the signed document
281
+ * @returns VerificationResult with the verification status and extracted content
282
+ *
283
+ * @example
284
+ * ```typescript
285
+ * const result = jacs.verify(signedJson);
286
+ * if (result.valid) {
287
+ * console.log(`Signed by: ${result.signerId}`);
288
+ * }
289
+ * ```
290
+ */
291
+ export declare function verify(signedDocument: string): VerificationResult;
292
+ /**
293
+ * Verify a signed JACS document without loading an agent.
294
+ * Uses caller-supplied key resolution and directories; does not use global agent state.
295
+ *
296
+ * @param signedDocument - Full signed JACS document JSON string
297
+ * @param options - Optional keyResolution, dataDirectory, keyDirectory
298
+ * @returns VerificationResult with valid and signerId
299
+ *
300
+ * @example
301
+ * ```typescript
302
+ * const result = jacs.verifyStandalone(signedJson, { keyResolution: 'local', keyDirectory: './keys' });
303
+ * if (result.valid) console.log(`Signed by: ${result.signerId}`);
304
+ * ```
305
+ */
306
+ export declare function verifyStandalone(signedDocument: string, options?: {
307
+ keyResolution?: string;
308
+ dataDirectory?: string;
309
+ keyDirectory?: string;
310
+ }): VerificationResult;
311
+ /**
312
+ * Verifies a document by its storage ID.
313
+ *
314
+ * Use this when you have a document ID (e.g., "uuid:version") rather than
315
+ * the full JSON string. The document will be loaded from storage and verified.
316
+ *
317
+ * @param documentId - The document ID in "uuid:version" format
318
+ * @returns VerificationResult with the verification status
319
+ *
320
+ * @example
321
+ * ```typescript
322
+ * const result = jacs.verifyById('550e8400-e29b-41d4-a716-446655440000:1');
323
+ * if (result.valid) {
324
+ * console.log('Document verified');
325
+ * }
326
+ * ```
327
+ */
328
+ export declare function verifyById(documentId: string): VerificationResult;
329
+ /**
330
+ * Re-encrypt the agent's private key with a new password.
331
+ *
332
+ * @param oldPassword - The current password for the private key
333
+ * @param newPassword - The new password to encrypt with (must meet password requirements)
334
+ *
335
+ * @example
336
+ * ```typescript
337
+ * jacs.reencryptKey('old-password-123!', 'new-Str0ng-P@ss!');
338
+ * console.log('Key re-encrypted successfully');
339
+ * ```
340
+ */
341
+ export declare function reencryptKey(oldPassword: string, newPassword: string): void;
342
+ /**
343
+ * Get the loaded agent's public key in PEM format.
344
+ *
345
+ * @returns The public key as a PEM-encoded string
346
+ *
347
+ * @example
348
+ * ```typescript
349
+ * const pem = jacs.getPublicKey();
350
+ * console.log(pem); // Share with others for verification
351
+ * ```
352
+ */
353
+ export declare function getPublicKey(): string;
354
+ /**
355
+ * Export the agent document for sharing.
356
+ *
357
+ * @returns The agent JSON document as a string
358
+ *
359
+ * @example
360
+ * ```typescript
361
+ * const agentDoc = jacs.exportAgent();
362
+ * // Send to another party for trust establishment
363
+ * ```
364
+ */
365
+ export declare function exportAgent(): string;
366
+ /**
367
+ * Get information about the currently loaded agent.
368
+ *
369
+ * @returns AgentInfo if an agent is loaded, null otherwise
370
+ */
371
+ export declare function getAgentInfo(): AgentInfo | null;
372
+ /**
373
+ * Check if an agent is currently loaded.
374
+ *
375
+ * @returns true if an agent is loaded, false otherwise
376
+ */
377
+ export declare function isLoaded(): boolean;
378
+ /**
379
+ * Returns the DNS TXT record line for the loaded agent (for DNS-based discovery).
380
+ * Format: _v1.agent.jacs.{domain}. TTL IN TXT "v=hai.ai; jacs_agent_id=...; alg=SHA-256; enc=base64; jac_public_key_hash=..."
381
+ */
382
+ export declare function getDnsRecord(domain: string, ttl?: number): string;
383
+ /**
384
+ * Returns the well-known JSON object for the loaded agent (e.g. for /.well-known/jacs-pubkey.json).
385
+ * Keys: publicKey, publicKeyHash, algorithm, agentId.
386
+ */
387
+ export declare function getWellKnownJson(): {
388
+ publicKey: string;
389
+ publicKeyHash: string;
390
+ algorithm: string;
391
+ agentId: string;
392
+ };
393
+ /**
394
+ * Register the loaded agent with HAI.ai.
395
+ * Requires a loaded agent (uses exportAgent() for the payload).
396
+ * Calls POST {haiUrl}/api/v1/agents/register with Bearer token and agent JSON.
397
+ *
398
+ * @param options - apiKey (or HAI_API_KEY env), haiUrl (default "https://hai.ai"), preview
399
+ * @returns HaiRegistrationResult with agentId, jacsId, dnsVerified, signatures
400
+ */
401
+ export declare function registerWithHai(options?: HaiRegistrationOptions): Promise<HaiRegistrationResult>;
402
+ /**
403
+ * Status of a multi-party agreement.
404
+ */
405
+ export interface AgreementStatus {
406
+ /** Whether all required parties have signed. */
407
+ complete: boolean;
408
+ /** List of signers and their status. */
409
+ signers: Array<{
410
+ agentId: string;
411
+ signed: boolean;
412
+ signedAt?: string;
413
+ }>;
414
+ /** List of agent IDs that haven't signed yet. */
415
+ pending: string[];
416
+ }
417
+ /**
418
+ * Creates a multi-party agreement that requires signatures from multiple agents.
419
+ *
420
+ * @param document - The document to create an agreement on (object or JSON string)
421
+ * @param agentIds - List of agent IDs required to sign
422
+ * @param question - Optional question or purpose of the agreement
423
+ * @param context - Optional additional context for signers
424
+ * @param fieldName - Optional custom field name for the agreement (default: "jacsAgreement")
425
+ * @returns SignedDocument containing the agreement document
426
+ *
427
+ * @example
428
+ * ```typescript
429
+ * const agreement = jacs.createAgreement(
430
+ * { proposal: 'Merge codebase' },
431
+ * ['agent-1-uuid', 'agent-2-uuid'],
432
+ * 'Do you approve this merge?',
433
+ * 'This will combine repositories A and B'
434
+ * );
435
+ * ```
436
+ */
437
+ export declare function createAgreement(document: any, agentIds: string[], question?: string, context?: string, fieldName?: string): SignedDocument;
438
+ /**
439
+ * Signs an existing multi-party agreement.
440
+ *
441
+ * @param document - The agreement document to sign (object or JSON string)
442
+ * @param fieldName - Optional custom field name for the agreement (default: "jacsAgreement")
443
+ * @returns SignedDocument with this agent's signature added
444
+ *
445
+ * @example
446
+ * ```typescript
447
+ * // Receive agreement from another party
448
+ * const signedByMe = jacs.signAgreement(agreementDoc);
449
+ * // Send back to coordinator or next signer
450
+ * ```
451
+ */
452
+ export declare function signAgreement(document: any, fieldName?: string): SignedDocument;
453
+ /**
454
+ * Checks the status of a multi-party agreement.
455
+ *
456
+ * @param document - The agreement document to check (object or JSON string)
457
+ * @param fieldName - Optional custom field name for the agreement (default: "jacsAgreement")
458
+ * @returns AgreementStatus with completion status and signer details
459
+ *
460
+ * @example
461
+ * ```typescript
462
+ * const status = jacs.checkAgreement(agreementDoc);
463
+ * if (status.complete) {
464
+ * console.log('All parties have signed!');
465
+ * } else {
466
+ * console.log(`Waiting for: ${status.pending.join(', ')}`);
467
+ * }
468
+ * ```
469
+ */
470
+ export declare function checkAgreement(document: any, fieldName?: string): AgreementStatus;
471
+ /**
472
+ * Add an agent to the local trust store.
473
+ *
474
+ * The trust store is a local list of agents you trust. When verifying
475
+ * documents from known agents, the trust store provides signer names
476
+ * and allows quick lookups.
477
+ *
478
+ * @param agentJson - The agent's JSON document (from their exportAgent())
479
+ * @returns The trusted agent's ID
480
+ *
481
+ * @example
482
+ * ```typescript
483
+ * const trustedId = jacs.trustAgent(partnerAgentJson);
484
+ * console.log(`Trusted agent: ${trustedId}`);
485
+ * ```
486
+ */
487
+ export declare function trustAgent(agentJson: string): string;
488
+ /**
489
+ * List all trusted agent IDs in the local trust store.
490
+ *
491
+ * @returns Array of trusted agent UUIDs
492
+ *
493
+ * @example
494
+ * ```typescript
495
+ * const trustedIds = jacs.listTrustedAgents();
496
+ * console.log(`${trustedIds.length} trusted agents`);
497
+ * ```
498
+ */
499
+ export declare function listTrustedAgents(): string[];
500
+ /**
501
+ * Remove an agent from the local trust store.
502
+ *
503
+ * @param agentId - The agent UUID to remove
504
+ *
505
+ * @example
506
+ * ```typescript
507
+ * jacs.untrustAgent('550e8400-e29b-41d4-a716-446655440000');
508
+ * ```
509
+ */
510
+ export declare function untrustAgent(agentId: string): void;
511
+ /**
512
+ * Check if an agent is in the local trust store.
513
+ *
514
+ * @param agentId - The agent UUID to check
515
+ * @returns true if the agent is trusted
516
+ *
517
+ * @example
518
+ * ```typescript
519
+ * if (jacs.isTrusted(signerId)) {
520
+ * console.log('Signer is in our trust store');
521
+ * }
522
+ * ```
523
+ */
524
+ export declare function isTrusted(agentId: string): boolean;
525
+ /**
526
+ * Get a trusted agent's full JSON document from the trust store.
527
+ *
528
+ * @param agentId - The agent UUID to retrieve
529
+ * @returns The agent's JSON document as a string
530
+ *
531
+ * @example
532
+ * ```typescript
533
+ * const agentDoc = JSON.parse(jacs.getTrustedAgent(agentId));
534
+ * console.log(`Agent name: ${agentDoc.jacsAgentName}`);
535
+ * ```
536
+ */
537
+ export declare function getTrustedAgent(agentId: string): string;
538
+ /**
539
+ * Options for the security audit.
540
+ */
541
+ export interface AuditOptions {
542
+ /** Optional path to jacs config file. */
543
+ configPath?: string;
544
+ /** Optional number of recent documents to re-verify. */
545
+ recentN?: number;
546
+ }
547
+ /**
548
+ * Run a read-only security audit and health checks.
549
+ * Returns an object with risks, health_checks, summary, and related fields.
550
+ *
551
+ * @param options - Optional config path and recent document count
552
+ * @returns Audit result object (risks, health_checks, summary, overall_status)
553
+ *
554
+ * @example
555
+ * ```typescript
556
+ * const result = jacs.audit();
557
+ * console.log(`Risks: ${result.risks.length}, Status: ${result.overall_status}`);
558
+ * ```
559
+ */
560
+ export declare function audit(options?: AuditOptions): Record<string, unknown>;
561
+ /** Max length for a full verify URL (scheme + host + path + ?s=...). */
562
+ export declare const MAX_VERIFY_URL_LEN = 2048;
563
+ /** Max UTF-8 byte length of a document that fits in a verify link. */
564
+ export declare const MAX_VERIFY_DOCUMENT_BYTES = 1515;
565
+ /**
566
+ * Build a verification URL for a signed JACS document (e.g. https://hai.ai/jacs/verify?s=...).
567
+ * Uses URL-safe base64. Throws if the URL would exceed MAX_VERIFY_URL_LEN.
568
+ *
569
+ * @param document - Full signed JACS document string (JSON)
570
+ * @param baseUrl - Base URL of the verifier (no trailing slash). Default "https://hai.ai"
571
+ * @returns Full URL: {baseUrl}/jacs/verify?s={base64url(document)}
572
+ */
573
+ export declare function generateVerifyLink(document: string, baseUrl?: string): string;