@kb-labs/adapters 0.5.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.
Files changed (276) hide show
  1. package/.cursorrules +32 -0
  2. package/.github/workflows/ci.yml +13 -0
  3. package/.github/workflows/deploy.yml +28 -0
  4. package/.github/workflows/docker-build.yml +25 -0
  5. package/.github/workflows/drift-check.yml +10 -0
  6. package/.github/workflows/profiles-validate.yml +16 -0
  7. package/.github/workflows/release.yml +8 -0
  8. package/.kb/devkit/agents/devkit-maintainer/context.globs +15 -0
  9. package/.kb/devkit/agents/devkit-maintainer/permissions.yml +17 -0
  10. package/.kb/devkit/agents/devkit-maintainer/prompt.md +28 -0
  11. package/.kb/devkit/agents/devkit-maintainer/runbook.md +31 -0
  12. package/.kb/devkit/agents/docs-crafter/prompt.md +24 -0
  13. package/.kb/devkit/agents/docs-crafter/runbook.md +18 -0
  14. package/.kb/devkit/agents/release-manager/context.globs +7 -0
  15. package/.kb/devkit/agents/release-manager/prompt.md +27 -0
  16. package/.kb/devkit/agents/release-manager/runbook.md +17 -0
  17. package/.kb/devkit/agents/test-generator/context.globs +7 -0
  18. package/.kb/devkit/agents/test-generator/prompt.md +27 -0
  19. package/.kb/devkit/agents/test-generator/runbook.md +18 -0
  20. package/CONTRIBUTING.md +90 -0
  21. package/IMPLEMENTATION_COMPLETE.md +416 -0
  22. package/LICENSE +186 -0
  23. package/README-TEMPLATE.md +179 -0
  24. package/README.md +306 -0
  25. package/docs/DOCUMENTATION.md +74 -0
  26. package/docs/adr/0000-template.md +49 -0
  27. package/docs/adr/0001-architecture-and-repository-layout.md +33 -0
  28. package/docs/adr/0002-plugins-and-extensibility.md +46 -0
  29. package/docs/adr/0003-package-and-module-boundaries.md +37 -0
  30. package/docs/adr/0004-versioning-and-release-policy.md +38 -0
  31. package/docs/adr/0005-use-devkit-for-shared-tooling.md +48 -0
  32. package/docs/adr/0006-adopt-devkit-sync.md +47 -0
  33. package/docs/adr/0007-drift-kit-check.md +72 -0
  34. package/docs/adr/0008-devkit-sync-wrapper-strategy.md +67 -0
  35. package/docs/naming-convention.md +272 -0
  36. package/eslint.config.js +27 -0
  37. package/kb-labs.config.json +5 -0
  38. package/package.json +84 -0
  39. package/package.json.bin +25 -0
  40. package/package.json.lib +30 -0
  41. package/packages/adapters-analytics-duckdb/package.json +54 -0
  42. package/packages/adapters-analytics-duckdb/scripts/migrate-from-jsonl.mjs +253 -0
  43. package/packages/adapters-analytics-duckdb/src/index.ts +380 -0
  44. package/packages/adapters-analytics-duckdb/src/manifest.ts +36 -0
  45. package/packages/adapters-analytics-duckdb/src/schema.ts +161 -0
  46. package/packages/adapters-analytics-duckdb/tsconfig.build.json +15 -0
  47. package/packages/adapters-analytics-duckdb/tsconfig.json +9 -0
  48. package/packages/adapters-analytics-duckdb/tsup.config.ts +9 -0
  49. package/packages/adapters-analytics-file/README.md +32 -0
  50. package/packages/adapters-analytics-file/eslint.config.js +27 -0
  51. package/packages/adapters-analytics-file/package.json +50 -0
  52. package/packages/adapters-analytics-file/src/__tests__/daily-stats.spec.ts +287 -0
  53. package/packages/adapters-analytics-file/src/__tests__/scoped-analytics.test.ts +233 -0
  54. package/packages/adapters-analytics-file/src/index.test.ts +214 -0
  55. package/packages/adapters-analytics-file/src/index.ts +830 -0
  56. package/packages/adapters-analytics-file/src/manifest.ts +45 -0
  57. package/packages/adapters-analytics-file/tsconfig.build.json +15 -0
  58. package/packages/adapters-analytics-file/tsconfig.json +9 -0
  59. package/packages/adapters-analytics-file/tsup.config.ts +9 -0
  60. package/packages/adapters-analytics-sqlite/package.json +55 -0
  61. package/packages/adapters-analytics-sqlite/scripts/migrate-from-jsonl.mjs +194 -0
  62. package/packages/adapters-analytics-sqlite/src/index.ts +460 -0
  63. package/packages/adapters-analytics-sqlite/src/manifest.ts +41 -0
  64. package/packages/adapters-analytics-sqlite/tsconfig.build.json +15 -0
  65. package/packages/adapters-analytics-sqlite/tsconfig.json +9 -0
  66. package/packages/adapters-analytics-sqlite/tsup.config.ts +9 -0
  67. package/packages/adapters-environment-docker/README.md +28 -0
  68. package/packages/adapters-environment-docker/eslint.config.js +5 -0
  69. package/packages/adapters-environment-docker/package.json +49 -0
  70. package/packages/adapters-environment-docker/src/index.test.ts +138 -0
  71. package/packages/adapters-environment-docker/src/index.ts +439 -0
  72. package/packages/adapters-environment-docker/src/manifest.ts +65 -0
  73. package/packages/adapters-environment-docker/tsconfig.build.json +15 -0
  74. package/packages/adapters-environment-docker/tsconfig.json +16 -0
  75. package/packages/adapters-environment-docker/tsup.config.ts +9 -0
  76. package/packages/adapters-eventbus-cache/README.md +242 -0
  77. package/packages/adapters-eventbus-cache/eslint.config.js +27 -0
  78. package/packages/adapters-eventbus-cache/package.json +46 -0
  79. package/packages/adapters-eventbus-cache/src/index.test.ts +235 -0
  80. package/packages/adapters-eventbus-cache/src/index.ts +215 -0
  81. package/packages/adapters-eventbus-cache/src/manifest.ts +50 -0
  82. package/packages/adapters-eventbus-cache/src/types.ts +58 -0
  83. package/packages/adapters-eventbus-cache/tsconfig.build.json +15 -0
  84. package/packages/adapters-eventbus-cache/tsconfig.json +9 -0
  85. package/packages/adapters-eventbus-cache/tsup.config.ts +9 -0
  86. package/packages/adapters-fs/README.md +171 -0
  87. package/packages/adapters-fs/allowed.txt +1 -0
  88. package/packages/adapters-fs/conflict.txt +1 -0
  89. package/packages/adapters-fs/dest.txt +1 -0
  90. package/packages/adapters-fs/eslint.config.js +27 -0
  91. package/packages/adapters-fs/exists.txt +1 -0
  92. package/packages/adapters-fs/not-allowed.txt +1 -0
  93. package/packages/adapters-fs/other.txt +1 -0
  94. package/packages/adapters-fs/package.json +55 -0
  95. package/packages/adapters-fs/public/file1.txt +1 -0
  96. package/packages/adapters-fs/public/file2.txt +1 -0
  97. package/packages/adapters-fs/secret.txt +1 -0
  98. package/packages/adapters-fs/secrets/key.txt +1 -0
  99. package/packages/adapters-fs/src/index.test.ts +243 -0
  100. package/packages/adapters-fs/src/index.ts +258 -0
  101. package/packages/adapters-fs/src/manifest.ts +35 -0
  102. package/packages/adapters-fs/src/secure-storage.test.ts +380 -0
  103. package/packages/adapters-fs/src/secure-storage.ts +268 -0
  104. package/packages/adapters-fs/test.json +1 -0
  105. package/packages/adapters-fs/test.txt +1 -0
  106. package/packages/adapters-fs/test.xyz +1 -0
  107. package/packages/adapters-fs/test1.txt +1 -0
  108. package/packages/adapters-fs/test2.txt +1 -0
  109. package/packages/adapters-fs/tsconfig.build.json +15 -0
  110. package/packages/adapters-fs/tsconfig.json +9 -0
  111. package/packages/adapters-fs/tsup.config.ts +8 -0
  112. package/packages/adapters-fs/vitest.config.ts +19 -0
  113. package/packages/adapters-log-ringbuffer/README.md +228 -0
  114. package/packages/adapters-log-ringbuffer/eslint.config.js +27 -0
  115. package/packages/adapters-log-ringbuffer/package.json +47 -0
  116. package/packages/adapters-log-ringbuffer/src/__tests__/ring-buffer.test.ts +450 -0
  117. package/packages/adapters-log-ringbuffer/src/index.ts +212 -0
  118. package/packages/adapters-log-ringbuffer/src/manifest.ts +30 -0
  119. package/packages/adapters-log-ringbuffer/tsconfig.build.json +15 -0
  120. package/packages/adapters-log-ringbuffer/tsconfig.json +9 -0
  121. package/packages/adapters-log-ringbuffer/tsup.config.ts +9 -0
  122. package/packages/adapters-log-ringbuffer/vitest.config.ts +14 -0
  123. package/packages/adapters-log-sqlite/README.md +396 -0
  124. package/packages/adapters-log-sqlite/eslint.config.js +27 -0
  125. package/packages/adapters-log-sqlite/package.json +49 -0
  126. package/packages/adapters-log-sqlite/src/__tests__/log-persistence.test.ts +718 -0
  127. package/packages/adapters-log-sqlite/src/index.ts +1068 -0
  128. package/packages/adapters-log-sqlite/src/manifest.ts +36 -0
  129. package/packages/adapters-log-sqlite/src/schema.sql +46 -0
  130. package/packages/adapters-log-sqlite/tsconfig.build.json +15 -0
  131. package/packages/adapters-log-sqlite/tsconfig.json +9 -0
  132. package/packages/adapters-log-sqlite/tsup.config.ts +9 -0
  133. package/packages/adapters-log-sqlite/vitest.config.ts +15 -0
  134. package/packages/adapters-mongodb/README.md +147 -0
  135. package/packages/adapters-mongodb/eslint.config.js +27 -0
  136. package/packages/adapters-mongodb/package.json +53 -0
  137. package/packages/adapters-mongodb/src/index.ts +428 -0
  138. package/packages/adapters-mongodb/src/manifest.ts +45 -0
  139. package/packages/adapters-mongodb/src/secure-document.ts +231 -0
  140. package/packages/adapters-mongodb/tsconfig.build.json +15 -0
  141. package/packages/adapters-mongodb/tsconfig.json +9 -0
  142. package/packages/adapters-mongodb/tsup.config.ts +8 -0
  143. package/packages/adapters-openai/README.md +151 -0
  144. package/packages/adapters-openai/embeddings.ts +37 -0
  145. package/packages/adapters-openai/eslint.config.js +26 -0
  146. package/packages/adapters-openai/index.ts +22 -0
  147. package/packages/adapters-openai/package.json +57 -0
  148. package/packages/adapters-openai/src/embeddings-manifest.ts +45 -0
  149. package/packages/adapters-openai/src/embeddings.ts +104 -0
  150. package/packages/adapters-openai/src/index.ts +13 -0
  151. package/packages/adapters-openai/src/llm.ts +304 -0
  152. package/packages/adapters-openai/src/manifest.ts +47 -0
  153. package/packages/adapters-openai/tsconfig.build.json +15 -0
  154. package/packages/adapters-openai/tsconfig.json +9 -0
  155. package/packages/adapters-openai/tsup.config.ts +8 -0
  156. package/packages/adapters-pino/README.md +152 -0
  157. package/packages/adapters-pino/eslint.config.js +27 -0
  158. package/packages/adapters-pino/package.json +49 -0
  159. package/packages/adapters-pino/src/index.test.ts +44 -0
  160. package/packages/adapters-pino/src/index.ts +322 -0
  161. package/packages/adapters-pino/src/log-ring-buffer.ts +142 -0
  162. package/packages/adapters-pino/src/manifest.ts +49 -0
  163. package/packages/adapters-pino/tsconfig.build.json +15 -0
  164. package/packages/adapters-pino/tsconfig.json +9 -0
  165. package/packages/adapters-pino/tsup.config.ts +9 -0
  166. package/packages/adapters-pino-http/README.md +141 -0
  167. package/packages/adapters-pino-http/eslint.config.js +27 -0
  168. package/packages/adapters-pino-http/package.json +46 -0
  169. package/packages/adapters-pino-http/src/index.ts +229 -0
  170. package/packages/adapters-pino-http/tsconfig.build.json +15 -0
  171. package/packages/adapters-pino-http/tsconfig.json +9 -0
  172. package/packages/adapters-pino-http/tsup.config.ts +9 -0
  173. package/packages/adapters-qdrant/README.md +166 -0
  174. package/packages/adapters-qdrant/eslint.config.js +27 -0
  175. package/packages/adapters-qdrant/package.json +49 -0
  176. package/packages/adapters-qdrant/src/index.ts +490 -0
  177. package/packages/adapters-qdrant/src/manifest.ts +54 -0
  178. package/packages/adapters-qdrant/src/retry.ts +204 -0
  179. package/packages/adapters-qdrant/tsconfig.build.json +15 -0
  180. package/packages/adapters-qdrant/tsconfig.json +9 -0
  181. package/packages/adapters-qdrant/tsup.config.ts +9 -0
  182. package/packages/adapters-redis/README.md +159 -0
  183. package/packages/adapters-redis/eslint.config.js +27 -0
  184. package/packages/adapters-redis/package.json +49 -0
  185. package/packages/adapters-redis/src/index.ts +164 -0
  186. package/packages/adapters-redis/src/manifest.ts +49 -0
  187. package/packages/adapters-redis/tsconfig.build.json +15 -0
  188. package/packages/adapters-redis/tsconfig.json +9 -0
  189. package/packages/adapters-redis/tsup.config.ts +9 -0
  190. package/packages/adapters-snapshot-localfs/README.md +10 -0
  191. package/packages/adapters-snapshot-localfs/eslint.config.js +2 -0
  192. package/packages/adapters-snapshot-localfs/package.json +46 -0
  193. package/packages/adapters-snapshot-localfs/src/index.test.ts +40 -0
  194. package/packages/adapters-snapshot-localfs/src/index.ts +292 -0
  195. package/packages/adapters-snapshot-localfs/src/manifest.ts +32 -0
  196. package/packages/adapters-snapshot-localfs/tsconfig.build.json +15 -0
  197. package/packages/adapters-snapshot-localfs/tsconfig.json +16 -0
  198. package/packages/adapters-snapshot-localfs/tsup.config.ts +11 -0
  199. package/packages/adapters-sqlite/README.md +163 -0
  200. package/packages/adapters-sqlite/eslint.config.js +27 -0
  201. package/packages/adapters-sqlite/package.json +54 -0
  202. package/packages/adapters-sqlite/src/index.test.ts +245 -0
  203. package/packages/adapters-sqlite/src/index.ts +382 -0
  204. package/packages/adapters-sqlite/src/manifest.ts +47 -0
  205. package/packages/adapters-sqlite/src/secure-sql.test.ts +290 -0
  206. package/packages/adapters-sqlite/src/secure-sql.ts +281 -0
  207. package/packages/adapters-sqlite/tsconfig.build.json +15 -0
  208. package/packages/adapters-sqlite/tsconfig.json +9 -0
  209. package/packages/adapters-sqlite/tsup.config.ts +8 -0
  210. package/packages/adapters-sqlite/vitest.config.ts +19 -0
  211. package/packages/adapters-transport/README.md +170 -0
  212. package/packages/adapters-transport/eslint.config.js +27 -0
  213. package/packages/adapters-transport/package.json +49 -0
  214. package/packages/adapters-transport/src/__tests__/unix-socket-server.test.ts +550 -0
  215. package/packages/adapters-transport/src/index.ts +101 -0
  216. package/packages/adapters-transport/src/ipc-transport.ts +228 -0
  217. package/packages/adapters-transport/src/transport.ts +224 -0
  218. package/packages/adapters-transport/src/types.ts +92 -0
  219. package/packages/adapters-transport/src/unix-socket-server.ts +193 -0
  220. package/packages/adapters-transport/src/unix-socket-transport.ts +280 -0
  221. package/packages/adapters-transport/tsconfig.build.json +15 -0
  222. package/packages/adapters-transport/tsconfig.json +9 -0
  223. package/packages/adapters-transport/tsup.config.ts +9 -0
  224. package/packages/adapters-vibeproxy/README.md +159 -0
  225. package/packages/adapters-vibeproxy/eslint.config.js +27 -0
  226. package/packages/adapters-vibeproxy/package.json +51 -0
  227. package/packages/adapters-vibeproxy/src/index.ts +13 -0
  228. package/packages/adapters-vibeproxy/src/llm.ts +437 -0
  229. package/packages/adapters-vibeproxy/src/manifest.ts +51 -0
  230. package/packages/adapters-vibeproxy/tsconfig.build.json +15 -0
  231. package/packages/adapters-vibeproxy/tsconfig.json +9 -0
  232. package/packages/adapters-vibeproxy/tsup.config.ts +8 -0
  233. package/packages/adapters-workspace-agent/package.json +46 -0
  234. package/packages/adapters-workspace-agent/src/__tests__/adapter.test.ts +212 -0
  235. package/packages/adapters-workspace-agent/src/index.ts +220 -0
  236. package/packages/adapters-workspace-agent/src/manifest.ts +36 -0
  237. package/packages/adapters-workspace-agent/tsconfig.build.json +15 -0
  238. package/packages/adapters-workspace-agent/tsconfig.json +16 -0
  239. package/packages/adapters-workspace-agent/tsup.config.ts +11 -0
  240. package/packages/adapters-workspace-localfs/README.md +9 -0
  241. package/packages/adapters-workspace-localfs/eslint.config.js +2 -0
  242. package/packages/adapters-workspace-localfs/package.json +46 -0
  243. package/packages/adapters-workspace-localfs/src/index.test.ts +27 -0
  244. package/packages/adapters-workspace-localfs/src/index.ts +172 -0
  245. package/packages/adapters-workspace-localfs/src/manifest.ts +32 -0
  246. package/packages/adapters-workspace-localfs/tsconfig.build.json +15 -0
  247. package/packages/adapters-workspace-localfs/tsconfig.json +16 -0
  248. package/packages/adapters-workspace-localfs/tsup.config.ts +11 -0
  249. package/packages/adapters-workspace-worktree/README.md +9 -0
  250. package/packages/adapters-workspace-worktree/eslint.config.js +2 -0
  251. package/packages/adapters-workspace-worktree/package.json +46 -0
  252. package/packages/adapters-workspace-worktree/src/index.test.ts +38 -0
  253. package/packages/adapters-workspace-worktree/src/index.ts +245 -0
  254. package/packages/adapters-workspace-worktree/src/manifest.ts +38 -0
  255. package/packages/adapters-workspace-worktree/tsconfig.build.json +15 -0
  256. package/packages/adapters-workspace-worktree/tsconfig.json +16 -0
  257. package/packages/adapters-workspace-worktree/tsup.config.ts +11 -0
  258. package/pnpm-workspace.yaml +2800 -0
  259. package/prettierrc.json +1 -0
  260. package/scripts/devkit-sync.mjs +37 -0
  261. package/scripts/hooks/post-push +9 -0
  262. package/scripts/hooks/pre-commit +9 -0
  263. package/scripts/hooks/pre-push +9 -0
  264. package/test-integration.ts +242 -0
  265. package/test.txt +1 -0
  266. package/tsconfig.base.json +6 -0
  267. package/tsconfig.build.json +15 -0
  268. package/tsconfig.json +9 -0
  269. package/tsconfig.paths.json +26 -0
  270. package/tsconfig.tools.json +17 -0
  271. package/tsup.config.bin.ts +34 -0
  272. package/tsup.config.cli.ts +41 -0
  273. package/tsup.config.dual.ts +46 -0
  274. package/tsup.config.ts +36 -0
  275. package/tsup.external.json +103 -0
  276. package/vitest.config.ts +2 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * @module @kb-labs/adapters-transport
3
+ * Unix Socket server for handling adapter calls from child processes.
4
+ *
5
+ * This server runs in the parent process and handles incoming adapter
6
+ * method calls from child processes connected via Unix sockets.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { UnixSocketServer } from '@kb-labs/adapters-transport';
11
+ * import { usePlatform } from '@kb-labs/core-runtime';
12
+ *
13
+ * const server = new UnixSocketServer({ socketPath: '/tmp/kb-ipc.sock' });
14
+ *
15
+ * server.onCall(async (call) => {
16
+ * const platform = usePlatform();
17
+ * const adapter = platform.getAdapter(call.adapter);
18
+ * const result = await adapter[call.method](...call.args);
19
+ * return { requestId: call.requestId, result };
20
+ * });
21
+ *
22
+ * await server.start();
23
+ * ```
24
+ */
25
+
26
+ import * as net from "net";
27
+ import * as fs from "fs";
28
+ import type { AdapterCall, AdapterResponse } from "./types.js";
29
+
30
+ export interface UnixSocketServerConfig {
31
+ /** Path to Unix socket file (default: /tmp/kb-ipc.sock) */
32
+ socketPath?: string;
33
+ }
34
+
35
+ /**
36
+ * Unix Socket server for parent process.
37
+ *
38
+ * Listens for adapter calls from child processes and executes them
39
+ * on the real adapters in the parent process.
40
+ */
41
+ export class UnixSocketServer {
42
+ private server: net.Server | null = null;
43
+ private clients = new Set<net.Socket>();
44
+ private callHandler?: (call: AdapterCall) => Promise<AdapterResponse>;
45
+ private socketPath: string;
46
+
47
+ constructor(private config: UnixSocketServerConfig = {}) {
48
+ this.socketPath = config.socketPath ?? "/tmp/kb-ipc.sock";
49
+ }
50
+
51
+ /**
52
+ * Register handler for incoming adapter calls.
53
+ *
54
+ * @param handler - Async function that executes adapter call and returns response
55
+ */
56
+ onCall(handler: (call: AdapterCall) => Promise<AdapterResponse>): void {
57
+ this.callHandler = handler;
58
+ }
59
+
60
+ /**
61
+ * Start listening for connections.
62
+ */
63
+ async start(): Promise<void> {
64
+ // Remove existing socket file if exists
65
+ if (fs.existsSync(this.socketPath)) {
66
+ fs.unlinkSync(this.socketPath);
67
+ }
68
+
69
+ return new Promise((resolve, reject) => {
70
+ this.server = net.createServer((socket) => {
71
+ this.handleClient(socket);
72
+ });
73
+
74
+ this.server.on("error", (error) => {
75
+ reject(error);
76
+ });
77
+
78
+ this.server.listen(this.socketPath, () => {
79
+ // Set socket permissions (readable/writable by all)
80
+ fs.chmodSync(this.socketPath, 0o666);
81
+ resolve();
82
+ });
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Handle new client connection.
88
+ */
89
+ private handleClient(socket: net.Socket): void {
90
+ this.clients.add(socket);
91
+
92
+ let buffer = "";
93
+
94
+ socket.on("data", (data) => {
95
+ buffer += data.toString("utf8");
96
+
97
+ // Process all complete messages (newline-delimited)
98
+ let newlineIndex: number;
99
+ while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
100
+ const line = buffer.slice(0, newlineIndex);
101
+ buffer = buffer.slice(newlineIndex + 1);
102
+
103
+ if (line.trim().length === 0) {
104
+ continue;
105
+ }
106
+
107
+ try {
108
+ const call = JSON.parse(line) as AdapterCall;
109
+ this.handleCall(socket, call);
110
+ } catch (error) {
111
+ console.error("[UnixSocketServer] Failed to parse message:", error);
112
+ }
113
+ }
114
+ });
115
+
116
+ socket.on("close", () => {
117
+ this.clients.delete(socket);
118
+ });
119
+
120
+ socket.on("error", (error) => {
121
+ console.error("[UnixSocketServer] Client socket error:", error);
122
+ this.clients.delete(socket);
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Handle adapter call from client.
128
+ */
129
+ private async handleCall(
130
+ socket: net.Socket,
131
+ call: AdapterCall,
132
+ ): Promise<void> {
133
+ if (!this.callHandler) {
134
+ console.error("[UnixSocketServer] No call handler registered");
135
+ return;
136
+ }
137
+
138
+ try {
139
+ const response = await this.callHandler(call);
140
+ const message = JSON.stringify(response) + "\n";
141
+ socket.write(message, "utf8");
142
+ } catch (error) {
143
+ // Send error response
144
+ const errorResponse: AdapterResponse = {
145
+ type: "adapter:response",
146
+ requestId: call.requestId,
147
+ error: {
148
+ __type: "Error",
149
+ name: error instanceof Error ? error.name : "Error",
150
+ message: error instanceof Error ? error.message : String(error),
151
+ stack: error instanceof Error ? error.stack : undefined,
152
+ },
153
+ };
154
+ const message = JSON.stringify(errorResponse) + "\n";
155
+ socket.write(message, "utf8");
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Stop server and close all connections.
161
+ */
162
+ async close(): Promise<void> {
163
+ // Close all client connections
164
+ for (const client of this.clients) {
165
+ client.destroy();
166
+ }
167
+ this.clients.clear();
168
+
169
+ // Close server
170
+ if (this.server) {
171
+ await new Promise<void>((resolve) => {
172
+ this.server!.close(() => {
173
+ resolve();
174
+ });
175
+ });
176
+ this.server = null;
177
+ }
178
+
179
+ // Remove socket file
180
+ if (fs.existsSync(this.socketPath)) {
181
+ fs.unlinkSync(this.socketPath);
182
+ }
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Create UnixSocketServer.
188
+ */
189
+ export function createUnixSocketServer(
190
+ config?: UnixSocketServerConfig,
191
+ ): UnixSocketServer {
192
+ return new UnixSocketServer(config);
193
+ }
@@ -0,0 +1,280 @@
1
+ /**
2
+ * @module @kb-labs/adapters-transport
3
+ * Unix Domain Socket transport for high-throughput IPC.
4
+ *
5
+ * Unix sockets provide 100-1000x better performance than process.send()
6
+ * for large messages (>16KB), making them ideal for bulk operations like
7
+ * VectorStore upsert with thousands of vectors.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { UnixSocketTransport } from '@kb-labs/adapters-transport';
12
+ *
13
+ * // In child process
14
+ * const transport = new UnixSocketTransport({ socketPath: '/tmp/kb-ipc.sock' });
15
+ * const response = await transport.send(call);
16
+ * await transport.close();
17
+ * ```
18
+ */
19
+
20
+ import * as net from "net";
21
+ import type { AdapterCall, AdapterResponse } from "./types.js";
22
+ import { isAdapterResponse } from "./types.js";
23
+ import {
24
+ type ITransport,
25
+ type TransportConfig,
26
+ type PendingRequest,
27
+ TransportError,
28
+ TimeoutError,
29
+ } from "./transport.js";
30
+
31
+ /**
32
+ * Configuration for Unix Socket transport.
33
+ */
34
+ export interface UnixSocketConfig extends TransportConfig {
35
+ /** Path to Unix socket file (default: /tmp/kb-ipc.sock) */
36
+ socketPath?: string;
37
+ /** Reconnect on disconnect (default: true) */
38
+ autoReconnect?: boolean;
39
+ /** Max reconnect attempts (default: 3) */
40
+ maxReconnectAttempts?: number;
41
+ }
42
+
43
+ /**
44
+ * Unix Domain Socket transport for high-performance IPC.
45
+ *
46
+ * Features:
47
+ * - 100-1000x faster than process.send() for large messages
48
+ * - No backpressure issues (TCP flow control handles it)
49
+ * - Auto-reconnect on connection loss
50
+ * - Message framing with newline delimiter
51
+ *
52
+ * Performance:
53
+ * - process.send(): ~16KB buffer, 250-300s for 40MB
54
+ * - Unix socket: ~1-2 GB/s throughput, <1s for 40MB
55
+ */
56
+ export class UnixSocketTransport implements ITransport {
57
+ private socket: net.Socket | null = null;
58
+ private pending = new Map<string, PendingRequest>();
59
+ private closed = false;
60
+ private connecting = false;
61
+ private buffer = "";
62
+ private reconnectAttempts = 0;
63
+
64
+ constructor(private config: UnixSocketConfig = {}) {}
65
+
66
+ /**
67
+ * Connect to Unix socket server.
68
+ * Called lazily on first send() or explicitly.
69
+ */
70
+ async connect(): Promise<void> {
71
+ if (this.socket && !this.socket.destroyed) {
72
+ return; // Already connected
73
+ }
74
+
75
+ if (this.connecting) {
76
+ // Wait for existing connection attempt
77
+ await new Promise((resolve) => {
78
+ setTimeout(resolve, 100);
79
+ });
80
+ return this.connect();
81
+ }
82
+
83
+ this.connecting = true;
84
+
85
+ return new Promise((resolve, reject) => {
86
+ const socketPath = this.config.socketPath ?? "/tmp/kb-ipc.sock";
87
+
88
+ this.socket = net.connect(socketPath);
89
+
90
+ this.socket.on("connect", () => {
91
+ this.connecting = false;
92
+ this.reconnectAttempts = 0;
93
+ resolve();
94
+ });
95
+
96
+ this.socket.on("error", (error) => {
97
+ this.connecting = false;
98
+
99
+ // Try reconnect if enabled
100
+ const maxAttempts = this.config.maxReconnectAttempts ?? 3;
101
+ if (
102
+ this.config.autoReconnect !== false &&
103
+ this.reconnectAttempts < maxAttempts
104
+ ) {
105
+ this.reconnectAttempts++;
106
+ setTimeout(() => this.connect(), 1000 * this.reconnectAttempts);
107
+ return;
108
+ }
109
+
110
+ reject(
111
+ new TransportError(
112
+ `Unix socket connection failed: ${error.message}`,
113
+ error,
114
+ ),
115
+ );
116
+ });
117
+
118
+ this.socket.on("data", (data) => {
119
+ this.handleData(data);
120
+ });
121
+
122
+ this.socket.on("close", () => {
123
+ if (!this.closed && this.config.autoReconnect !== false) {
124
+ // Unexpected close, try reconnect
125
+ setTimeout(() => this.connect(), 1000);
126
+ }
127
+ });
128
+ });
129
+ }
130
+
131
+ async send(call: AdapterCall): Promise<AdapterResponse> {
132
+ if (this.closed) {
133
+ throw new TransportError("Transport is closed");
134
+ }
135
+
136
+ // Ensure connected
137
+ await this.connect();
138
+
139
+ if (!this.socket || this.socket.destroyed) {
140
+ throw new TransportError("Socket not available");
141
+ }
142
+
143
+ // Determine timeout
144
+ const timeout = call.timeout ?? this.config.timeout ?? 30000;
145
+
146
+ return new Promise((resolve, reject) => {
147
+ // Create timeout timer
148
+ const timer = setTimeout(() => {
149
+ this.pending.delete(call.requestId);
150
+ reject(
151
+ new TimeoutError(
152
+ `Adapter call timed out after ${timeout}ms`,
153
+ timeout,
154
+ ),
155
+ );
156
+ }, timeout);
157
+
158
+ // Store pending request
159
+ this.pending.set(call.requestId, { resolve, reject, timer });
160
+
161
+ // Send via Unix socket (newline-delimited JSON)
162
+ const message = JSON.stringify(call) + "\n";
163
+
164
+ const written = this.socket!.write(message, "utf8", (error) => {
165
+ if (error) {
166
+ const pending = this.pending.get(call.requestId);
167
+ if (pending) {
168
+ clearTimeout(pending.timer);
169
+ this.pending.delete(call.requestId);
170
+ reject(
171
+ new TransportError(
172
+ `Failed to write to socket: ${error.message}`,
173
+ error,
174
+ ),
175
+ );
176
+ }
177
+ }
178
+ });
179
+
180
+ // Unix sockets handle backpressure via TCP flow control
181
+ // If write() returns false, 'drain' event will fire when ready
182
+ if (!written) {
183
+ this.socket!.once("drain", () => {
184
+ // Socket ready for more data (TCP handled backpressure)
185
+ });
186
+ }
187
+ });
188
+ }
189
+
190
+ /**
191
+ * Handle incoming data from Unix socket.
192
+ * Messages are newline-delimited JSON.
193
+ */
194
+ private handleData(data: Buffer): void {
195
+ this.buffer += data.toString("utf8");
196
+
197
+ // Process all complete messages (newline-delimited)
198
+ let newlineIndex: number;
199
+ while ((newlineIndex = this.buffer.indexOf("\n")) !== -1) {
200
+ const line = this.buffer.slice(0, newlineIndex);
201
+ this.buffer = this.buffer.slice(newlineIndex + 1);
202
+
203
+ if (line.trim().length === 0) {
204
+ continue;
205
+ }
206
+
207
+ try {
208
+ const msg = JSON.parse(line);
209
+ this.handleMessage(msg);
210
+ } catch (error) {
211
+ console.error("[UnixSocketTransport] Failed to parse message:", error);
212
+ }
213
+ }
214
+ }
215
+
216
+ private handleMessage(msg: unknown): void {
217
+ // Ignore non-response messages
218
+ if (!isAdapterResponse(msg)) {
219
+ return;
220
+ }
221
+
222
+ // Find pending request
223
+ const pending = this.pending.get(msg.requestId);
224
+ if (!pending) {
225
+ // Response for unknown request (may have timed out)
226
+ return;
227
+ }
228
+
229
+ // Clear timeout and remove from pending
230
+ clearTimeout(pending.timer);
231
+ this.pending.delete(msg.requestId);
232
+
233
+ // Resolve with response
234
+ pending.resolve(msg);
235
+ }
236
+
237
+ async close(): Promise<void> {
238
+ if (this.closed) {
239
+ return;
240
+ }
241
+
242
+ this.closed = true;
243
+
244
+ // Close socket
245
+ if (this.socket) {
246
+ this.socket.destroy();
247
+ this.socket = null;
248
+ }
249
+
250
+ // Reject all pending requests
251
+ for (const [_requestId, pending] of this.pending) {
252
+ clearTimeout(pending.timer);
253
+ pending.reject(new TransportError("Transport closed"));
254
+ }
255
+ this.pending.clear();
256
+ }
257
+
258
+ isClosed(): boolean {
259
+ return this.closed;
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Create UnixSocketTransport with configuration.
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * import { createUnixSocketTransport } from '@kb-labs/adapters-transport';
269
+ *
270
+ * const transport = createUnixSocketTransport({
271
+ * socketPath: '/tmp/kb-ipc.sock',
272
+ * timeout: 60000,
273
+ * });
274
+ * ```
275
+ */
276
+ export function createUnixSocketTransport(
277
+ config?: UnixSocketConfig,
278
+ ): UnixSocketTransport {
279
+ return new UnixSocketTransport(config);
280
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "baseUrl": ".",
6
+ "paths": {}
7
+ },
8
+ "include": [
9
+ "src/**/*"
10
+ ],
11
+ "exclude": [
12
+ "dist",
13
+ "node_modules"
14
+ ]
15
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "extends": "@kb-labs/devkit/tsconfig/node.json",
4
+ "compilerOptions": {
5
+ "rootDir": "src",
6
+ "outDir": "dist"
7
+ },
8
+ "include": ["src"]
9
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'tsup';
2
+ import nodePreset from '@kb-labs/devkit/tsup/node';
3
+
4
+ export default defineConfig({
5
+ ...nodePreset,
6
+ tsconfig: 'tsconfig.build.json',
7
+ entry: ['src/index.ts', 'src/manifest.ts'],
8
+ dts: true,
9
+ });
@@ -0,0 +1,159 @@
1
+ # @kb-labs/adapters-vibeproxy
2
+
3
+ > Part of [KB Labs](https://github.com/KirillBaranov/kb-labs) ecosystem. Works exclusively within KB Labs platform.
4
+
5
+ VibeProxy local adapter supporting multiple LLM providers (Claude, GPT, etc.) through a unified interface.
6
+
7
+ ## Overview
8
+
9
+ | Property | Value |
10
+ |----------|-------|
11
+ | **Implements** | `ILLM` |
12
+ | **Type** | `core` |
13
+ | **Requires** | None |
14
+ | **Category** | AI |
15
+
16
+ ## Features
17
+
18
+ - **Multi-Provider** - Claude, GPT, Gemini, and more via single interface
19
+ - **Local Proxy** - Route through local VibeProxy server
20
+ - **Function Calling** - Native tool support for all providers
21
+ - **Model Switching** - Change provider by just changing model name
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pnpm add @kb-labs/adapters-vibeproxy
27
+ ```
28
+
29
+ ## Configuration
30
+
31
+ Add to your `kb.config.json`:
32
+
33
+ ```json
34
+ {
35
+ "platform": {
36
+ "adapters": {
37
+ "llm": "@kb-labs/adapters-vibeproxy"
38
+ },
39
+ "adapterOptions": {
40
+ "llm": {
41
+ "baseURL": "http://localhost:8317",
42
+ "apiKey": "any-string",
43
+ "model": "claude-sonnet-4-20250514",
44
+ "timeout": 120000
45
+ }
46
+ }
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### Options
52
+
53
+ | Option | Type | Default | Description |
54
+ |--------|------|---------|-------------|
55
+ | `baseURL` | `string` | `"http://localhost:8317"` | VibeProxy server URL |
56
+ | `apiKey` | `string` | `"any-string"` | API key (any string works for local) |
57
+ | `model` | `string` | `"claude-sonnet-4-20250514"` | Model to use |
58
+ | `timeout` | `number` | `120000` | Request timeout in ms |
59
+
60
+ ## Usage
61
+
62
+ ### Via Platform (Recommended)
63
+
64
+ ```typescript
65
+ import { usePlatform } from '@kb-labs/sdk';
66
+
67
+ const platform = usePlatform();
68
+
69
+ // Chat with Claude
70
+ const response = await platform.llm.chat([
71
+ { role: 'user', content: 'Hello!' }
72
+ ]);
73
+
74
+ // Switch to GPT by changing model
75
+ const gptResponse = await platform.llm.chat(
76
+ [{ role: 'user', content: 'Hello!' }],
77
+ { model: 'gpt-4-turbo' }
78
+ );
79
+
80
+ // Function calling
81
+ const result = await platform.llm.chatWithTools(
82
+ [{ role: 'user', content: 'What time is it?' }],
83
+ [{ name: 'getTime', parameters: { ... } }]
84
+ );
85
+ ```
86
+
87
+ ### Standalone (Testing/Development)
88
+
89
+ ```typescript
90
+ import { createAdapter } from '@kb-labs/adapters-vibeproxy';
91
+
92
+ const llm = createAdapter({
93
+ baseURL: 'http://localhost:8317',
94
+ model: 'claude-sonnet-4-20250514'
95
+ });
96
+
97
+ const response = await llm.chat([
98
+ { role: 'user', content: 'Hello!' }
99
+ ]);
100
+ ```
101
+
102
+ ## Adapter Manifest
103
+
104
+ ```typescript
105
+ {
106
+ id: 'vibeproxy-llm',
107
+ name: 'VibeProxy LLM',
108
+ version: '0.1.0',
109
+ implements: 'ILLM',
110
+ capabilities: {
111
+ streaming: false, // TODO: implement SSE streaming
112
+ custom: {
113
+ functionCalling: true,
114
+ multiProvider: true,
115
+ },
116
+ },
117
+ }
118
+ ```
119
+
120
+ ## Supported Models
121
+
122
+ | Provider | Model Examples |
123
+ |----------|---------------|
124
+ | **Anthropic** | `claude-sonnet-4-20250514`, `claude-3-opus-*` |
125
+ | **OpenAI** | `gpt-4-turbo`, `gpt-3.5-turbo` |
126
+ | **Google** | `gemini-pro`, `gemini-ultra` |
127
+
128
+ ## FAQ
129
+
130
+ <details>
131
+ <summary><strong>Q: How do I start VibeProxy locally?</strong></summary>
132
+
133
+ See VibeProxy documentation for setup instructions. Default port is 8317.
134
+ </details>
135
+
136
+ <details>
137
+ <summary><strong>Q: Why use VibeProxy instead of direct API?</strong></summary>
138
+
139
+ - Single interface for multiple providers
140
+ - Local caching and rate limiting
141
+ - Request logging and analytics
142
+ - Cost tracking across providers
143
+ </details>
144
+
145
+ <details>
146
+ <summary><strong>Q: Is streaming supported?</strong></summary>
147
+
148
+ Not yet. Streaming (SSE) is planned for a future release.
149
+ </details>
150
+
151
+ ## Related Adapters
152
+
153
+ | Adapter | Use Case |
154
+ |---------|----------|
155
+ | `@kb-labs/adapters-openai` | Direct OpenAI API access |
156
+
157
+ ## License
158
+
159
+ [KB Public License v1.1](../../LICENSE) - KB Labs Team
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Standard ESLint configuration template
3
+ *
4
+ * This is the canonical template for all @kb-labs packages.
5
+ * DO NOT modify this file locally - it is synced from @kb-labs/devkit
6
+ *
7
+ * Customization guidelines:
8
+ * - DevKit preset already includes all standard ignores
9
+ * - Only add project-specific ignores if absolutely necessary
10
+ * - Document why custom ignores are needed
11
+ *
12
+ * @see https://github.com/kb-labs/devkit#eslint-configuration
13
+ */
14
+ import nodePreset from '@kb-labs/devkit/eslint/node.js';
15
+
16
+ export default [
17
+ ...nodePreset,
18
+
19
+ // OPTIONAL: Add project-specific ignores only if needed
20
+ // DevKit preset already ignores: dist/, coverage/, node_modules/, *.d.ts, scripts/, etc.
21
+ // {
22
+ // ignores: [
23
+ // // Add ONLY project-specific patterns here
24
+ // // Example: '**/*.generated.ts',
25
+ // ]
26
+ // }
27
+ ];