@haiai/haiai 0.1.2

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 (153) hide show
  1. package/README.md +127 -0
  2. package/bin/haiai.cjs +70 -0
  3. package/dist/cjs/a2a.js +352 -0
  4. package/dist/cjs/a2a.js.map +1 -0
  5. package/dist/cjs/agent.js +236 -0
  6. package/dist/cjs/agent.js.map +1 -0
  7. package/dist/cjs/client.js +2168 -0
  8. package/dist/cjs/client.js.map +1 -0
  9. package/dist/cjs/config.js +176 -0
  10. package/dist/cjs/config.js.map +1 -0
  11. package/dist/cjs/errors.js +102 -0
  12. package/dist/cjs/errors.js.map +1 -0
  13. package/dist/cjs/hash.js +52 -0
  14. package/dist/cjs/hash.js.map +1 -0
  15. package/dist/cjs/index.js +84 -0
  16. package/dist/cjs/index.js.map +1 -0
  17. package/dist/cjs/integrations.js +193 -0
  18. package/dist/cjs/integrations.js.map +1 -0
  19. package/dist/cjs/jacs.js +66 -0
  20. package/dist/cjs/jacs.js.map +1 -0
  21. package/dist/cjs/mime.js +100 -0
  22. package/dist/cjs/mime.js.map +1 -0
  23. package/dist/cjs/package.json +3 -0
  24. package/dist/cjs/signing.js +190 -0
  25. package/dist/cjs/signing.js.map +1 -0
  26. package/dist/cjs/sse.js +76 -0
  27. package/dist/cjs/sse.js.map +1 -0
  28. package/dist/cjs/types.js +6 -0
  29. package/dist/cjs/types.js.map +1 -0
  30. package/dist/cjs/verify.js +76 -0
  31. package/dist/cjs/verify.js.map +1 -0
  32. package/dist/cjs/ws.js +206 -0
  33. package/dist/cjs/ws.js.map +1 -0
  34. package/dist/esm/a2a.js +305 -0
  35. package/dist/esm/a2a.js.map +1 -0
  36. package/dist/esm/agent.js +231 -0
  37. package/dist/esm/agent.js.map +1 -0
  38. package/dist/esm/client.js +2131 -0
  39. package/dist/esm/client.js.map +1 -0
  40. package/dist/esm/config.js +171 -0
  41. package/dist/esm/config.js.map +1 -0
  42. package/dist/esm/errors.js +88 -0
  43. package/dist/esm/errors.js.map +1 -0
  44. package/dist/esm/hash.js +49 -0
  45. package/dist/esm/hash.js.map +1 -0
  46. package/dist/esm/index.js +27 -0
  47. package/dist/esm/index.js.map +1 -0
  48. package/dist/esm/integrations.js +147 -0
  49. package/dist/esm/integrations.js.map +1 -0
  50. package/dist/esm/jacs.js +61 -0
  51. package/dist/esm/jacs.js.map +1 -0
  52. package/dist/esm/mime.js +97 -0
  53. package/dist/esm/mime.js.map +1 -0
  54. package/dist/esm/signing.js +183 -0
  55. package/dist/esm/signing.js.map +1 -0
  56. package/dist/esm/sse.js +73 -0
  57. package/dist/esm/sse.js.map +1 -0
  58. package/dist/esm/types.js +5 -0
  59. package/dist/esm/types.js.map +1 -0
  60. package/dist/esm/verify.js +72 -0
  61. package/dist/esm/verify.js.map +1 -0
  62. package/dist/esm/ws.js +168 -0
  63. package/dist/esm/ws.js.map +1 -0
  64. package/dist/types/a2a.d.ts +52 -0
  65. package/dist/types/a2a.d.ts.map +1 -0
  66. package/dist/types/agent.d.ts +202 -0
  67. package/dist/types/agent.d.ts.map +1 -0
  68. package/dist/types/client.d.ts +486 -0
  69. package/dist/types/client.d.ts.map +1 -0
  70. package/dist/types/config.d.ts +31 -0
  71. package/dist/types/config.d.ts.map +1 -0
  72. package/dist/types/errors.d.ts +50 -0
  73. package/dist/types/errors.d.ts.map +1 -0
  74. package/dist/types/hash.d.ts +32 -0
  75. package/dist/types/hash.d.ts.map +1 -0
  76. package/dist/types/index.d.ts +22 -0
  77. package/dist/types/index.d.ts.map +1 -0
  78. package/dist/types/integrations.d.ts +25 -0
  79. package/dist/types/integrations.d.ts.map +1 -0
  80. package/dist/types/jacs.d.ts +26 -0
  81. package/dist/types/jacs.d.ts.map +1 -0
  82. package/dist/types/mime.d.ts +39 -0
  83. package/dist/types/mime.d.ts.map +1 -0
  84. package/dist/types/signing.d.ts +58 -0
  85. package/dist/types/signing.d.ts.map +1 -0
  86. package/dist/types/sse.d.ts +8 -0
  87. package/dist/types/sse.d.ts.map +1 -0
  88. package/dist/types/types.d.ts +652 -0
  89. package/dist/types/types.d.ts.map +1 -0
  90. package/dist/types/verify.d.ts +20 -0
  91. package/dist/types/verify.d.ts.map +1 -0
  92. package/dist/types/ws.d.ts +30 -0
  93. package/dist/types/ws.d.ts.map +1 -0
  94. package/examples/a2a_quickstart.ts +138 -0
  95. package/examples/hai_quickstart.ts +111 -0
  96. package/examples/mcp_quickstart.ts +53 -0
  97. package/npm/@haiai/cli-darwin-arm64/package.json +16 -0
  98. package/npm/@haiai/cli-darwin-x64/package.json +16 -0
  99. package/npm/@haiai/cli-linux-arm64/package.json +16 -0
  100. package/npm/@haiai/cli-linux-x64/package.json +16 -0
  101. package/npm/@haiai/cli-win32-x64/package.json +16 -0
  102. package/package.json +68 -0
  103. package/scripts/build-platform-packages.js +132 -0
  104. package/scripts/smoke-package.cjs +114 -0
  105. package/scripts/write-cjs-package.cjs +9 -0
  106. package/src/a2a.ts +463 -0
  107. package/src/agent.ts +302 -0
  108. package/src/client.ts +2504 -0
  109. package/src/config.ts +204 -0
  110. package/src/errors.ts +99 -0
  111. package/src/hash.ts +66 -0
  112. package/src/index.ts +163 -0
  113. package/src/integrations.ts +210 -0
  114. package/src/jacs.ts +86 -0
  115. package/src/mime.ts +131 -0
  116. package/src/signing.ts +233 -0
  117. package/src/sse.ts +86 -0
  118. package/src/types.ts +773 -0
  119. package/src/verify.ts +89 -0
  120. package/src/ws.ts +198 -0
  121. package/tests/_debug_jacs.cjs +29 -0
  122. package/tests/a2a-contract.test.ts +271 -0
  123. package/tests/a2a-fixtures.test.ts +73 -0
  124. package/tests/a2a.test.ts +379 -0
  125. package/tests/binary.test.ts +90 -0
  126. package/tests/client-api-methods.test.ts +176 -0
  127. package/tests/client-path-escaping.test.ts +80 -0
  128. package/tests/client-register.test.ts +61 -0
  129. package/tests/config.test.ts +281 -0
  130. package/tests/contract.test.ts +360 -0
  131. package/tests/cross-lang-contract.test.ts +67 -0
  132. package/tests/email-conformance.test.ts +289 -0
  133. package/tests/email-integration.test.ts +217 -0
  134. package/tests/email.test.ts +767 -0
  135. package/tests/errors.test.ts +167 -0
  136. package/tests/init-contract.test.ts +129 -0
  137. package/tests/integrations.test.ts +132 -0
  138. package/tests/jacs-passthrough.test.ts +125 -0
  139. package/tests/key-cache.test.ts +201 -0
  140. package/tests/key-integration.test.ts +119 -0
  141. package/tests/key-lookups.test.ts +187 -0
  142. package/tests/key-rotation.test.ts +362 -0
  143. package/tests/mime.test.ts +127 -0
  144. package/tests/security.test.ts +109 -0
  145. package/tests/setup.ts +60 -0
  146. package/tests/signing.test.ts +142 -0
  147. package/tests/sse.test.ts +125 -0
  148. package/tests/types.test.ts +294 -0
  149. package/tests/verify-link.test.ts +81 -0
  150. package/tests/ws.test.ts +213 -0
  151. package/tsconfig.cjs.json +11 -0
  152. package/tsconfig.json +22 -0
  153. package/vitest.config.ts +11 -0
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.JacsModuleError = void 0;
37
+ exports.langchainSignedTool = langchainSignedTool;
38
+ exports.langgraphWrapToolCall = langgraphWrapToolCall;
39
+ exports.langgraphToolNode = langgraphToolNode;
40
+ exports.createJacsLangchainTools = createJacsLangchainTools;
41
+ exports.createJacsMcpTransportProxy = createJacsMcpTransportProxy;
42
+ exports.getJacsMcpToolDefinitions = getJacsMcpToolDefinitions;
43
+ exports.registerJacsMcpTools = registerJacsMcpTools;
44
+ exports.createAgentSdkToolWrapper = createAgentSdkToolWrapper;
45
+ exports.verifyAgentSdkPayload = verifyAgentSdkPayload;
46
+ const node_util_1 = require("node:util");
47
+ class JacsModuleError extends Error {
48
+ constructor(message) {
49
+ super(message);
50
+ this.name = 'JacsModuleError';
51
+ }
52
+ }
53
+ exports.JacsModuleError = JacsModuleError;
54
+ function isMissingModuleError(error, moduleName) {
55
+ if (!error || typeof error !== 'object') {
56
+ return false;
57
+ }
58
+ const code = error.code;
59
+ if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') {
60
+ return true;
61
+ }
62
+ const message = error.message ?? '';
63
+ if (message.includes(`Cannot find package '${moduleName}'`)) {
64
+ return true;
65
+ }
66
+ if (message.includes(`Cannot find module '${moduleName}'`)) {
67
+ return true;
68
+ }
69
+ if (message.includes(`Failed to load url ${moduleName}`)) {
70
+ return true;
71
+ }
72
+ return false;
73
+ }
74
+ async function loadOptionalModule(moduleName, feature, installHint) {
75
+ try {
76
+ return await Promise.resolve(`${moduleName}`).then(s => __importStar(require(s)));
77
+ }
78
+ catch (error) {
79
+ if (isMissingModuleError(error, moduleName)) {
80
+ throw new JacsModuleError(`Optional dependency '${moduleName}' is required for ${feature}. ${installHint}`);
81
+ }
82
+ throw error;
83
+ }
84
+ }
85
+ function getRequiredFunction(moduleName, moduleObj, name) {
86
+ const value = moduleObj[name];
87
+ if (typeof value !== 'function') {
88
+ throw new JacsModuleError(`Module '${moduleName}' does not export function '${name}'. ` +
89
+ `Received: ${(0, node_util_1.inspect)(value, { depth: 1 })}`);
90
+ }
91
+ return value;
92
+ }
93
+ const LANGCHAIN_HINT = "Install with: npm install @hai.ai/jacs @langchain/core @langchain/langgraph";
94
+ const MCP_HINT = "Install with: npm install @hai.ai/jacs @modelcontextprotocol/sdk";
95
+ // ---------------------------------------------------------------------------
96
+ // LangChain / LangGraph wrappers (delegates to @hai.ai/jacs/langchain)
97
+ // ---------------------------------------------------------------------------
98
+ async function langchainSignedTool(tool, options) {
99
+ const moduleName = '@hai.ai/jacs/langchain';
100
+ const mod = await loadOptionalModule(moduleName, 'LangChain/LangGraph integration', LANGCHAIN_HINT);
101
+ return getRequiredFunction(moduleName, mod, 'signedTool')(tool, options);
102
+ }
103
+ async function langgraphWrapToolCall(options) {
104
+ const moduleName = '@hai.ai/jacs/langchain';
105
+ const mod = await loadOptionalModule(moduleName, 'LangGraph tool wrapping', LANGCHAIN_HINT);
106
+ return getRequiredFunction(moduleName, mod, 'jacsWrapToolCall')(options);
107
+ }
108
+ async function langgraphToolNode(tools, options) {
109
+ const moduleName = '@hai.ai/jacs/langchain';
110
+ const mod = await loadOptionalModule(moduleName, 'LangGraph ToolNode integration', LANGCHAIN_HINT);
111
+ return getRequiredFunction(moduleName, mod, 'jacsToolNode')(tools, options);
112
+ }
113
+ async function createJacsLangchainTools(options) {
114
+ const moduleName = '@hai.ai/jacs/langchain';
115
+ const mod = await loadOptionalModule(moduleName, 'LangChain JACS tools', LANGCHAIN_HINT);
116
+ return getRequiredFunction(moduleName, mod, 'createJacsTools')(options);
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // MCP wrappers (delegates to @hai.ai/jacs/mcp)
120
+ // ---------------------------------------------------------------------------
121
+ async function createJacsMcpTransportProxy(transport, clientOrAgent, role = 'server') {
122
+ const moduleName = '@hai.ai/jacs/mcp';
123
+ const mod = await loadOptionalModule(moduleName, 'MCP transport signing', MCP_HINT);
124
+ return getRequiredFunction(moduleName, mod, 'createJACSTransportProxy')(transport, clientOrAgent, role);
125
+ }
126
+ async function getJacsMcpToolDefinitions() {
127
+ const moduleName = '@hai.ai/jacs/mcp';
128
+ const mod = await loadOptionalModule(moduleName, 'MCP tool definitions', MCP_HINT);
129
+ return getRequiredFunction(moduleName, mod, 'getJacsMcpToolDefinitions')();
130
+ }
131
+ async function registerJacsMcpTools(server, client) {
132
+ const moduleName = '@hai.ai/jacs/mcp';
133
+ const mod = await loadOptionalModule(moduleName, 'MCP server tool registration', MCP_HINT);
134
+ getRequiredFunction(moduleName, mod, 'registerJacsTools')(server, client);
135
+ }
136
+ function normalizeSignedPayload(value) {
137
+ if (typeof value === 'string') {
138
+ return value;
139
+ }
140
+ if (value && typeof value === 'object') {
141
+ const v = value;
142
+ const direct = v.raw ?? v.raw_json ?? v.rawJson;
143
+ if (typeof direct === 'string') {
144
+ return direct;
145
+ }
146
+ }
147
+ return JSON.stringify(value);
148
+ }
149
+ function passthroughPayload(value) {
150
+ return typeof value === 'string' ? value : JSON.stringify(value);
151
+ }
152
+ function createAgentSdkToolWrapper(options) {
153
+ const strict = options.strict ?? false;
154
+ return function wrapTool(tool, toolName) {
155
+ const resolvedToolName = toolName ?? options.defaultToolName ?? tool.name ?? 'tool';
156
+ return async (...args) => {
157
+ const result = await tool(...args);
158
+ const payload = {
159
+ tool: resolvedToolName,
160
+ result,
161
+ };
162
+ try {
163
+ const signed = await options.signer.signMessage(payload);
164
+ return normalizeSignedPayload(signed);
165
+ }
166
+ catch (error) {
167
+ if (strict) {
168
+ throw error;
169
+ }
170
+ return passthroughPayload(result);
171
+ }
172
+ };
173
+ };
174
+ }
175
+ async function verifyAgentSdkPayload(signer, signedPayload, options = {}) {
176
+ const strict = options.strict ?? false;
177
+ if (typeof signer.verify !== 'function') {
178
+ if (strict) {
179
+ throw new JacsModuleError('Agent SDK verification requires signer.verify(signedPayload).');
180
+ }
181
+ return signedPayload;
182
+ }
183
+ try {
184
+ return await signer.verify(signedPayload);
185
+ }
186
+ catch (error) {
187
+ if (strict) {
188
+ throw error;
189
+ }
190
+ return signedPayload;
191
+ }
192
+ }
193
+ //# sourceMappingURL=integrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrations.js","sourceRoot":"","sources":["../../src/integrations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveJacsCliBin = resolveJacsCliBin;
4
+ exports.enforceMcpRunStdioArgs = enforceMcpRunStdioArgs;
5
+ exports.runJacsCli = runJacsCli;
6
+ const node_child_process_1 = require("node:child_process");
7
+ function resolveJacsCliBin(env = process.env) {
8
+ const candidate = (env.JACS_CLI_BIN ?? '').trim();
9
+ return candidate.length > 0 ? candidate : 'jacs';
10
+ }
11
+ /**
12
+ * Enforce local MCP execution policy when invoking `jacs mcp run`.
13
+ *
14
+ * We only allow `--bin` passthrough here and reject all forwarded runtime args
15
+ * so transport cannot be switched away from stdio.
16
+ */
17
+ function enforceMcpRunStdioArgs(args) {
18
+ if (args.length < 2 || args[0] !== 'mcp' || args[1] !== 'run') {
19
+ return args;
20
+ }
21
+ const normalized = ['mcp', 'run'];
22
+ for (let i = 2; i < args.length; i += 1) {
23
+ const arg = args[i];
24
+ if (arg === '--bin') {
25
+ const bin = args[i + 1];
26
+ if (!bin) {
27
+ throw new Error('Missing value for --bin');
28
+ }
29
+ normalized.push('--bin', bin);
30
+ i += 1;
31
+ continue;
32
+ }
33
+ if (arg.startsWith('--bin=')) {
34
+ normalized.push(arg);
35
+ continue;
36
+ }
37
+ throw new Error('`jacs mcp run` is stdio-only in haiai. ' +
38
+ 'Only optional `--bin <path>` is allowed; transport/runtime overrides are blocked.');
39
+ }
40
+ return normalized;
41
+ }
42
+ /**
43
+ * Execute a JACS CLI command from library code.
44
+ *
45
+ * Example:
46
+ * runJacsCli(["verify", "./signed.json"])
47
+ */
48
+ function runJacsCli(args, options = {}) {
49
+ const normalizedArgs = enforceMcpRunStdioArgs(args);
50
+ const binary = options.jacsBin?.trim() || resolveJacsCliBin(options.env ?? process.env);
51
+ const result = (0, node_child_process_1.spawnSync)(binary, normalizedArgs, {
52
+ cwd: options.cwd,
53
+ env: options.env,
54
+ stdio: options.stdio ?? 'pipe',
55
+ encoding: 'buffer',
56
+ });
57
+ if (result.error) {
58
+ const err = result.error;
59
+ if (err.code === 'ENOENT') {
60
+ throw new Error(`JACS CLI binary not found: ${binary}. Install jacs or set JACS_CLI_BIN.`);
61
+ }
62
+ throw new Error(`Failed to execute JACS CLI '${binary}': ${err.message}`);
63
+ }
64
+ return result;
65
+ }
66
+ //# sourceMappingURL=jacs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jacs.js","sourceRoot":"","sources":["../../src/jacs.ts"],"names":[],"mappings":";;AAaA,8CAGC;AAQD,wDA+BC;AAQD,gCAsBC;AArFD,2DAA+G;AAa/G,SAAgB,iBAAiB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACpE,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,IAAc;IACnD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;YAC7C,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC9B,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QAED,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QAED,MAAM,IAAI,KAAK,CACb,yCAAyC;YACzC,mFAAmF,CACpF,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CACxB,IAAc,EACd,UAA6B,EAAE;IAE/B,MAAM,cAAc,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,iBAAiB,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IACxF,MAAM,MAAM,GAAG,IAAA,8BAAS,EAAC,MAAM,EAAE,cAAc,EAAE;QAC/C,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM;QAC9B,QAAQ,EAAE,QAAQ;KACnB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,MAAM,CAAC,KAA8B,CAAC;QAClD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,8BAA8B,MAAM,qCAAqC,CAAC,CAAC;QAC7F,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ /**
3
+ * RFC 5322 MIME email construction.
4
+ *
5
+ * Builds standards-compliant email messages from structured fields.
6
+ * Zero external dependencies — uses only Node.js built-ins.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.buildRfc5322Email = buildRfc5322Email;
10
+ const node_crypto_1 = require("node:crypto");
11
+ /**
12
+ * Strip `\r` and `\n` from a header value to prevent CRLF injection.
13
+ */
14
+ function sanitizeHeader(value) {
15
+ return value.replace(/[\r\n"]/g, '');
16
+ }
17
+ /**
18
+ * Build an RFC 5322 email from structured fields.
19
+ *
20
+ * Produces raw bytes with CRLF line endings suitable for JACS signing
21
+ * and parseable by standard email parsers.
22
+ *
23
+ * @param opts - Email options (to, subject, body, attachments, etc.)
24
+ * @param fromEmail - The sender's email address
25
+ * @returns Buffer containing the raw RFC 5322 email
26
+ */
27
+ function buildRfc5322Email(opts, fromEmail) {
28
+ const safeTo = sanitizeHeader(opts.to);
29
+ const safeFrom = sanitizeHeader(fromEmail);
30
+ const safeSubject = sanitizeHeader(opts.subject);
31
+ const messageId = `<${(0, node_crypto_1.randomUUID)()}@hai.ai>`;
32
+ const date = new Date().toUTCString();
33
+ const attachments = opts.attachments ?? [];
34
+ if (attachments.length === 0) {
35
+ // Simple text/plain email
36
+ let email = '';
37
+ email += `From: <${safeFrom}>\r\n`;
38
+ email += `To: ${safeTo}\r\n`;
39
+ email += `Subject: ${safeSubject}\r\n`;
40
+ email += `Date: ${date}\r\n`;
41
+ email += `Message-ID: ${messageId}\r\n`;
42
+ if (opts.inReplyTo) {
43
+ const safeReply = sanitizeHeader(opts.inReplyTo);
44
+ email += `In-Reply-To: ${safeReply}\r\n`;
45
+ email += `References: ${safeReply}\r\n`;
46
+ }
47
+ email += 'MIME-Version: 1.0\r\n';
48
+ email += 'Content-Type: text/plain; charset=utf-8\r\n';
49
+ email += 'Content-Transfer-Encoding: 8bit\r\n';
50
+ email += '\r\n'; // end of headers
51
+ email += opts.body;
52
+ email += '\r\n';
53
+ return Buffer.from(email, 'utf-8');
54
+ }
55
+ else {
56
+ // multipart/mixed with text body + attachments
57
+ const boundary = `hai-boundary-${(0, node_crypto_1.randomUUID)().replace(/-/g, '')}`;
58
+ let email = '';
59
+ email += `From: <${safeFrom}>\r\n`;
60
+ email += `To: ${safeTo}\r\n`;
61
+ email += `Subject: ${safeSubject}\r\n`;
62
+ email += `Date: ${date}\r\n`;
63
+ email += `Message-ID: ${messageId}\r\n`;
64
+ if (opts.inReplyTo) {
65
+ const safeReply = sanitizeHeader(opts.inReplyTo);
66
+ email += `In-Reply-To: ${safeReply}\r\n`;
67
+ email += `References: ${safeReply}\r\n`;
68
+ }
69
+ email += 'MIME-Version: 1.0\r\n';
70
+ email += `Content-Type: multipart/mixed; boundary="${boundary}"\r\n`;
71
+ email += '\r\n'; // end of headers
72
+ // Body part
73
+ email += `--${boundary}\r\n`;
74
+ email += 'Content-Type: text/plain; charset=utf-8\r\n';
75
+ email += 'Content-Transfer-Encoding: 8bit\r\n';
76
+ email += '\r\n';
77
+ email += opts.body;
78
+ email += '\r\n';
79
+ // Attachment parts
80
+ for (const att of attachments) {
81
+ const safeFilename = sanitizeHeader(att.filename);
82
+ const safeContentType = sanitizeHeader(att.contentType);
83
+ const b64 = att.data.toString('base64');
84
+ email += `--${boundary}\r\n`;
85
+ email += `Content-Type: ${safeContentType}; name="${safeFilename}"\r\n`;
86
+ email += `Content-Disposition: attachment; filename="${safeFilename}"\r\n`;
87
+ email += 'Content-Transfer-Encoding: base64\r\n';
88
+ email += '\r\n';
89
+ // Write base64 in 76-char lines (RFC 2045)
90
+ for (let i = 0; i < b64.length; i += 76) {
91
+ email += b64.slice(i, i + 76);
92
+ email += '\r\n';
93
+ }
94
+ }
95
+ // Closing boundary
96
+ email += `--${boundary}--\r\n`;
97
+ return Buffer.from(email, 'utf-8');
98
+ }
99
+ }
100
+ //# sourceMappingURL=mime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mime.js","sourceRoot":"","sources":["../../src/mime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getServerKeys = getServerKeys;
4
+ exports.clearServerKeysCache = clearServerKeysCache;
5
+ exports.canonicalJson = canonicalJson;
6
+ exports.unwrapSignedEvent = unwrapSignedEvent;
7
+ exports.signResponse = signResponse;
8
+ const node_crypto_1 = require("node:crypto");
9
+ const jacs_1 = require("@hai.ai/jacs");
10
+ // Cache for server public keys
11
+ let serverKeysCache = {};
12
+ let cacheExpiry = 0;
13
+ /**
14
+ * Fetch the server's public signing keys from the well-known endpoint.
15
+ * Results are cached for 1 hour.
16
+ */
17
+ async function getServerKeys(baseUrl) {
18
+ if (Date.now() < cacheExpiry && Object.keys(serverKeysCache).length > 0) {
19
+ return serverKeysCache;
20
+ }
21
+ const resp = await fetch(`${baseUrl.replace(/\/+$/, '')}/.well-known/hai-keys.json`);
22
+ if (!resp.ok) {
23
+ throw new Error(`Failed to fetch server keys (${resp.status})`);
24
+ }
25
+ const data = (await resp.json());
26
+ serverKeysCache = {};
27
+ for (const key of data.keys ?? []) {
28
+ serverKeysCache[key.key_id] = key.public_key;
29
+ }
30
+ cacheExpiry = Date.now() + 3_600_000; // 1 hour
31
+ return serverKeysCache;
32
+ }
33
+ /** Reset the server keys cache (useful for testing). */
34
+ function clearServerKeysCache() {
35
+ serverKeysCache = {};
36
+ cacheExpiry = 0;
37
+ }
38
+ /**
39
+ * Produce canonical JSON per RFC 8785 (JCS).
40
+ *
41
+ * Delegates to JACS binding-core `canonicalizeJsonSync` when an agent is
42
+ * provided. Falls back to local sorted-key JSON.stringify for environments
43
+ * where the JACS native module is not loaded.
44
+ */
45
+ function canonicalJson(obj, agent) {
46
+ if (agent && 'canonicalizeJsonSync' in agent && typeof agent.canonicalizeJsonSync === 'function') {
47
+ try {
48
+ const jsonStr = canonicalJsonLocal(obj);
49
+ return agent.canonicalizeJsonSync(jsonStr);
50
+ }
51
+ catch {
52
+ // Fall through to local implementation
53
+ }
54
+ }
55
+ return canonicalJsonLocal(obj);
56
+ }
57
+ /** Local sorted-key JSON canonicalization (fallback). */
58
+ function canonicalJsonLocal(obj) {
59
+ return JSON.stringify(obj, (_key, value) => {
60
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
61
+ const sorted = {};
62
+ for (const k of Object.keys(value).sort()) {
63
+ sorted[k] = value[k];
64
+ }
65
+ return sorted;
66
+ }
67
+ return value;
68
+ });
69
+ }
70
+ /**
71
+ * Unwrap a JACS-signed event, verifying the signature via JACS if server keys
72
+ * are provided.
73
+ *
74
+ * Delegates to JACS binding-core `unwrapSignedEventSync` when the agent
75
+ * supports it. Falls back to local unwrap + verification otherwise.
76
+ *
77
+ * Supports both the canonical format (version/document_type/data/metadata/jacsSignature)
78
+ * and the legacy format (payload/metadata/signature). If the event is not a
79
+ * JacsDocument, it is returned as-is.
80
+ *
81
+ * Throws if a known key fails verification (signature mismatch).
82
+ */
83
+ function unwrapSignedEvent(eventData, serverPublicKeys, agent) {
84
+ // Try JACS binding-core delegation first
85
+ if (agent && 'unwrapSignedEventSync' in agent && typeof agent.unwrapSignedEventSync === 'function') {
86
+ try {
87
+ const eventJson = JSON.stringify(eventData);
88
+ const serverKeysJson = JSON.stringify({
89
+ keys: Object.entries(serverPublicKeys).map(([keyId, publicKey]) => ({
90
+ key_id: keyId,
91
+ public_key: publicKey,
92
+ })),
93
+ });
94
+ const resultJson = agent.unwrapSignedEventSync(eventJson, serverKeysJson);
95
+ const result = JSON.parse(resultJson);
96
+ return result.data ?? eventData;
97
+ }
98
+ catch {
99
+ // Fall through to local implementation
100
+ }
101
+ }
102
+ // Fallback: local unwrap with JACS verify for signature checks
103
+ // Canonical JacsDocument format: {version, document_type, data, metadata, jacsSignature}
104
+ if (eventData.jacsSignature && eventData.metadata && eventData.data !== undefined) {
105
+ const doc = eventData;
106
+ const agentID = doc.jacsSignature.agentID;
107
+ const publicKeyPem = serverPublicKeys[agentID];
108
+ if (publicKeyPem) {
109
+ const signedContent = canonicalJson(doc.data, agent);
110
+ let valid = false;
111
+ if (agent) {
112
+ valid = agent.verifyStringSync(signedContent, doc.jacsSignature.signature, Buffer.from(publicKeyPem, 'utf-8'), 'pem');
113
+ }
114
+ else {
115
+ const standaloneResult = (0, jacs_1.verifyDocumentStandalone)(JSON.stringify(eventData));
116
+ valid = standaloneResult.valid;
117
+ }
118
+ if (!valid) {
119
+ throw new Error(`JACS signature verification failed for agentID="${agentID}"`);
120
+ }
121
+ }
122
+ return doc.data;
123
+ }
124
+ // Legacy format: {payload, metadata, signature}
125
+ if (eventData.metadata && eventData.signature) {
126
+ const payload = eventData.payload;
127
+ const sig = eventData.signature;
128
+ const keyId = sig.key_id || '';
129
+ const publicKeyPem = serverPublicKeys[keyId];
130
+ if (publicKeyPem) {
131
+ const signedContent = canonicalJson({
132
+ metadata: eventData.metadata,
133
+ payload: eventData.payload,
134
+ }, agent);
135
+ let valid = false;
136
+ if (agent) {
137
+ valid = agent.verifyStringSync(signedContent, sig.signature || '', Buffer.from(publicKeyPem, 'utf-8'), 'pem');
138
+ }
139
+ if (!valid) {
140
+ throw new Error(`JACS signature verification failed for key_id="${keyId}"`);
141
+ }
142
+ }
143
+ return payload;
144
+ }
145
+ // Not a JacsDocument -- return unchanged
146
+ return eventData;
147
+ }
148
+ /**
149
+ * Sign a job response as a JACS document via JACS core.
150
+ *
151
+ * Delegates envelope construction to JACS binding-core when the agent
152
+ * exposes `signResponseSync`. Falls back to local construction for agents
153
+ * that only provide `signStringSync` (e.g. test mocks).
154
+ */
155
+ function signResponse(jobResponse, agent, jacsId) {
156
+ // Prefer JACS binding delegation (JACS canonicalizes internally via RFC 8785)
157
+ if ('signResponseSync' in agent && typeof agent.signResponseSync === 'function') {
158
+ const rawJson = JSON.stringify(jobResponse);
159
+ const resultJson = agent.signResponseSync(rawJson);
160
+ return { signed_document: resultJson, agent_jacs_id: jacsId };
161
+ }
162
+ // Fallback for agents without signResponseSync
163
+ const canonicalPayload = canonicalJson(jobResponse, agent);
164
+ const now = new Date().toISOString();
165
+ const documentId = (0, node_crypto_1.randomUUID)();
166
+ const hash = (0, jacs_1.hashString)(canonicalPayload);
167
+ const sortedData = JSON.parse(canonicalPayload);
168
+ const signature = agent.signStringSync(canonicalPayload);
169
+ const jacsDoc = {
170
+ version: '1.0.0',
171
+ document_type: 'job_response',
172
+ data: sortedData,
173
+ metadata: {
174
+ issuer: jacsId,
175
+ document_id: documentId,
176
+ created_at: now,
177
+ hash,
178
+ },
179
+ jacsSignature: {
180
+ agentID: jacsId,
181
+ date: now,
182
+ signature,
183
+ },
184
+ };
185
+ return {
186
+ signed_document: JSON.stringify(jacsDoc),
187
+ agent_jacs_id: jacsId,
188
+ };
189
+ }
190
+ //# sourceMappingURL=signing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/signing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSseStream = parseSseStream;
4
+ /**
5
+ * Parse an SSE stream (ReadableStream<Uint8Array>) into an async generator of HaiEvents.
6
+ *
7
+ * Implements the SSE protocol: events are delimited by blank lines,
8
+ * fields are "event:", "data:", and "id:".
9
+ */
10
+ async function* parseSseStream(body) {
11
+ const reader = body.getReader();
12
+ const decoder = new TextDecoder();
13
+ let buffer = '';
14
+ let fields = { event: '', data: '', id: undefined };
15
+ try {
16
+ while (true) {
17
+ const { done, value } = await reader.read();
18
+ if (done)
19
+ break;
20
+ buffer += decoder.decode(value, { stream: true });
21
+ const lines = buffer.split('\n');
22
+ buffer = lines.pop() ?? '';
23
+ for (const line of lines) {
24
+ if (line.startsWith('event:')) {
25
+ fields.event = line.slice(6).trim();
26
+ }
27
+ else if (line.startsWith('data:')) {
28
+ fields.data += (fields.data ? '\n' : '') + line.slice(5).trim();
29
+ }
30
+ else if (line.startsWith('id:')) {
31
+ fields.id = line.slice(3).trim();
32
+ }
33
+ else if (line === '' || line === '\r') {
34
+ // Blank line = end of event
35
+ if (fields.data) {
36
+ const event = buildEvent(fields);
37
+ if (event)
38
+ yield event;
39
+ }
40
+ fields = { event: '', data: '', id: undefined };
41
+ }
42
+ // Lines starting with ':' are comments, ignored
43
+ }
44
+ }
45
+ // Flush any remaining event
46
+ if (fields.data) {
47
+ const event = buildEvent(fields);
48
+ if (event)
49
+ yield event;
50
+ }
51
+ }
52
+ finally {
53
+ reader.releaseLock();
54
+ }
55
+ }
56
+ function buildEvent(fields) {
57
+ if (!fields.event && !fields.data)
58
+ return null;
59
+ let parsed;
60
+ try {
61
+ parsed = JSON.parse(fields.data);
62
+ }
63
+ catch {
64
+ parsed = fields.data;
65
+ }
66
+ const eventType = fields.event || (typeof parsed === 'object' && parsed !== null
67
+ ? parsed.type || 'message'
68
+ : 'message');
69
+ return {
70
+ eventType,
71
+ data: parsed,
72
+ id: fields.id,
73
+ raw: fields.data,
74
+ };
75
+ }
76
+ //# sourceMappingURL=sse.js.map