@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.
- package/.cursorrules +32 -0
- package/.github/workflows/ci.yml +13 -0
- package/.github/workflows/deploy.yml +28 -0
- package/.github/workflows/docker-build.yml +25 -0
- package/.github/workflows/drift-check.yml +10 -0
- package/.github/workflows/profiles-validate.yml +16 -0
- package/.github/workflows/release.yml +8 -0
- package/.kb/devkit/agents/devkit-maintainer/context.globs +15 -0
- package/.kb/devkit/agents/devkit-maintainer/permissions.yml +17 -0
- package/.kb/devkit/agents/devkit-maintainer/prompt.md +28 -0
- package/.kb/devkit/agents/devkit-maintainer/runbook.md +31 -0
- package/.kb/devkit/agents/docs-crafter/prompt.md +24 -0
- package/.kb/devkit/agents/docs-crafter/runbook.md +18 -0
- package/.kb/devkit/agents/release-manager/context.globs +7 -0
- package/.kb/devkit/agents/release-manager/prompt.md +27 -0
- package/.kb/devkit/agents/release-manager/runbook.md +17 -0
- package/.kb/devkit/agents/test-generator/context.globs +7 -0
- package/.kb/devkit/agents/test-generator/prompt.md +27 -0
- package/.kb/devkit/agents/test-generator/runbook.md +18 -0
- package/CONTRIBUTING.md +90 -0
- package/IMPLEMENTATION_COMPLETE.md +416 -0
- package/LICENSE +186 -0
- package/README-TEMPLATE.md +179 -0
- package/README.md +306 -0
- package/docs/DOCUMENTATION.md +74 -0
- package/docs/adr/0000-template.md +49 -0
- package/docs/adr/0001-architecture-and-repository-layout.md +33 -0
- package/docs/adr/0002-plugins-and-extensibility.md +46 -0
- package/docs/adr/0003-package-and-module-boundaries.md +37 -0
- package/docs/adr/0004-versioning-and-release-policy.md +38 -0
- package/docs/adr/0005-use-devkit-for-shared-tooling.md +48 -0
- package/docs/adr/0006-adopt-devkit-sync.md +47 -0
- package/docs/adr/0007-drift-kit-check.md +72 -0
- package/docs/adr/0008-devkit-sync-wrapper-strategy.md +67 -0
- package/docs/naming-convention.md +272 -0
- package/eslint.config.js +27 -0
- package/kb-labs.config.json +5 -0
- package/package.json +84 -0
- package/package.json.bin +25 -0
- package/package.json.lib +30 -0
- package/packages/adapters-analytics-duckdb/package.json +54 -0
- package/packages/adapters-analytics-duckdb/scripts/migrate-from-jsonl.mjs +253 -0
- package/packages/adapters-analytics-duckdb/src/index.ts +380 -0
- package/packages/adapters-analytics-duckdb/src/manifest.ts +36 -0
- package/packages/adapters-analytics-duckdb/src/schema.ts +161 -0
- package/packages/adapters-analytics-duckdb/tsconfig.build.json +15 -0
- package/packages/adapters-analytics-duckdb/tsconfig.json +9 -0
- package/packages/adapters-analytics-duckdb/tsup.config.ts +9 -0
- package/packages/adapters-analytics-file/README.md +32 -0
- package/packages/adapters-analytics-file/eslint.config.js +27 -0
- package/packages/adapters-analytics-file/package.json +50 -0
- package/packages/adapters-analytics-file/src/__tests__/daily-stats.spec.ts +287 -0
- package/packages/adapters-analytics-file/src/__tests__/scoped-analytics.test.ts +233 -0
- package/packages/adapters-analytics-file/src/index.test.ts +214 -0
- package/packages/adapters-analytics-file/src/index.ts +830 -0
- package/packages/adapters-analytics-file/src/manifest.ts +45 -0
- package/packages/adapters-analytics-file/tsconfig.build.json +15 -0
- package/packages/adapters-analytics-file/tsconfig.json +9 -0
- package/packages/adapters-analytics-file/tsup.config.ts +9 -0
- package/packages/adapters-analytics-sqlite/package.json +55 -0
- package/packages/adapters-analytics-sqlite/scripts/migrate-from-jsonl.mjs +194 -0
- package/packages/adapters-analytics-sqlite/src/index.ts +460 -0
- package/packages/adapters-analytics-sqlite/src/manifest.ts +41 -0
- package/packages/adapters-analytics-sqlite/tsconfig.build.json +15 -0
- package/packages/adapters-analytics-sqlite/tsconfig.json +9 -0
- package/packages/adapters-analytics-sqlite/tsup.config.ts +9 -0
- package/packages/adapters-environment-docker/README.md +28 -0
- package/packages/adapters-environment-docker/eslint.config.js +5 -0
- package/packages/adapters-environment-docker/package.json +49 -0
- package/packages/adapters-environment-docker/src/index.test.ts +138 -0
- package/packages/adapters-environment-docker/src/index.ts +439 -0
- package/packages/adapters-environment-docker/src/manifest.ts +65 -0
- package/packages/adapters-environment-docker/tsconfig.build.json +15 -0
- package/packages/adapters-environment-docker/tsconfig.json +16 -0
- package/packages/adapters-environment-docker/tsup.config.ts +9 -0
- package/packages/adapters-eventbus-cache/README.md +242 -0
- package/packages/adapters-eventbus-cache/eslint.config.js +27 -0
- package/packages/adapters-eventbus-cache/package.json +46 -0
- package/packages/adapters-eventbus-cache/src/index.test.ts +235 -0
- package/packages/adapters-eventbus-cache/src/index.ts +215 -0
- package/packages/adapters-eventbus-cache/src/manifest.ts +50 -0
- package/packages/adapters-eventbus-cache/src/types.ts +58 -0
- package/packages/adapters-eventbus-cache/tsconfig.build.json +15 -0
- package/packages/adapters-eventbus-cache/tsconfig.json +9 -0
- package/packages/adapters-eventbus-cache/tsup.config.ts +9 -0
- package/packages/adapters-fs/README.md +171 -0
- package/packages/adapters-fs/allowed.txt +1 -0
- package/packages/adapters-fs/conflict.txt +1 -0
- package/packages/adapters-fs/dest.txt +1 -0
- package/packages/adapters-fs/eslint.config.js +27 -0
- package/packages/adapters-fs/exists.txt +1 -0
- package/packages/adapters-fs/not-allowed.txt +1 -0
- package/packages/adapters-fs/other.txt +1 -0
- package/packages/adapters-fs/package.json +55 -0
- package/packages/adapters-fs/public/file1.txt +1 -0
- package/packages/adapters-fs/public/file2.txt +1 -0
- package/packages/adapters-fs/secret.txt +1 -0
- package/packages/adapters-fs/secrets/key.txt +1 -0
- package/packages/adapters-fs/src/index.test.ts +243 -0
- package/packages/adapters-fs/src/index.ts +258 -0
- package/packages/adapters-fs/src/manifest.ts +35 -0
- package/packages/adapters-fs/src/secure-storage.test.ts +380 -0
- package/packages/adapters-fs/src/secure-storage.ts +268 -0
- package/packages/adapters-fs/test.json +1 -0
- package/packages/adapters-fs/test.txt +1 -0
- package/packages/adapters-fs/test.xyz +1 -0
- package/packages/adapters-fs/test1.txt +1 -0
- package/packages/adapters-fs/test2.txt +1 -0
- package/packages/adapters-fs/tsconfig.build.json +15 -0
- package/packages/adapters-fs/tsconfig.json +9 -0
- package/packages/adapters-fs/tsup.config.ts +8 -0
- package/packages/adapters-fs/vitest.config.ts +19 -0
- package/packages/adapters-log-ringbuffer/README.md +228 -0
- package/packages/adapters-log-ringbuffer/eslint.config.js +27 -0
- package/packages/adapters-log-ringbuffer/package.json +47 -0
- package/packages/adapters-log-ringbuffer/src/__tests__/ring-buffer.test.ts +450 -0
- package/packages/adapters-log-ringbuffer/src/index.ts +212 -0
- package/packages/adapters-log-ringbuffer/src/manifest.ts +30 -0
- package/packages/adapters-log-ringbuffer/tsconfig.build.json +15 -0
- package/packages/adapters-log-ringbuffer/tsconfig.json +9 -0
- package/packages/adapters-log-ringbuffer/tsup.config.ts +9 -0
- package/packages/adapters-log-ringbuffer/vitest.config.ts +14 -0
- package/packages/adapters-log-sqlite/README.md +396 -0
- package/packages/adapters-log-sqlite/eslint.config.js +27 -0
- package/packages/adapters-log-sqlite/package.json +49 -0
- package/packages/adapters-log-sqlite/src/__tests__/log-persistence.test.ts +718 -0
- package/packages/adapters-log-sqlite/src/index.ts +1068 -0
- package/packages/adapters-log-sqlite/src/manifest.ts +36 -0
- package/packages/adapters-log-sqlite/src/schema.sql +46 -0
- package/packages/adapters-log-sqlite/tsconfig.build.json +15 -0
- package/packages/adapters-log-sqlite/tsconfig.json +9 -0
- package/packages/adapters-log-sqlite/tsup.config.ts +9 -0
- package/packages/adapters-log-sqlite/vitest.config.ts +15 -0
- package/packages/adapters-mongodb/README.md +147 -0
- package/packages/adapters-mongodb/eslint.config.js +27 -0
- package/packages/adapters-mongodb/package.json +53 -0
- package/packages/adapters-mongodb/src/index.ts +428 -0
- package/packages/adapters-mongodb/src/manifest.ts +45 -0
- package/packages/adapters-mongodb/src/secure-document.ts +231 -0
- package/packages/adapters-mongodb/tsconfig.build.json +15 -0
- package/packages/adapters-mongodb/tsconfig.json +9 -0
- package/packages/adapters-mongodb/tsup.config.ts +8 -0
- package/packages/adapters-openai/README.md +151 -0
- package/packages/adapters-openai/embeddings.ts +37 -0
- package/packages/adapters-openai/eslint.config.js +26 -0
- package/packages/adapters-openai/index.ts +22 -0
- package/packages/adapters-openai/package.json +57 -0
- package/packages/adapters-openai/src/embeddings-manifest.ts +45 -0
- package/packages/adapters-openai/src/embeddings.ts +104 -0
- package/packages/adapters-openai/src/index.ts +13 -0
- package/packages/adapters-openai/src/llm.ts +304 -0
- package/packages/adapters-openai/src/manifest.ts +47 -0
- package/packages/adapters-openai/tsconfig.build.json +15 -0
- package/packages/adapters-openai/tsconfig.json +9 -0
- package/packages/adapters-openai/tsup.config.ts +8 -0
- package/packages/adapters-pino/README.md +152 -0
- package/packages/adapters-pino/eslint.config.js +27 -0
- package/packages/adapters-pino/package.json +49 -0
- package/packages/adapters-pino/src/index.test.ts +44 -0
- package/packages/adapters-pino/src/index.ts +322 -0
- package/packages/adapters-pino/src/log-ring-buffer.ts +142 -0
- package/packages/adapters-pino/src/manifest.ts +49 -0
- package/packages/adapters-pino/tsconfig.build.json +15 -0
- package/packages/adapters-pino/tsconfig.json +9 -0
- package/packages/adapters-pino/tsup.config.ts +9 -0
- package/packages/adapters-pino-http/README.md +141 -0
- package/packages/adapters-pino-http/eslint.config.js +27 -0
- package/packages/adapters-pino-http/package.json +46 -0
- package/packages/adapters-pino-http/src/index.ts +229 -0
- package/packages/adapters-pino-http/tsconfig.build.json +15 -0
- package/packages/adapters-pino-http/tsconfig.json +9 -0
- package/packages/adapters-pino-http/tsup.config.ts +9 -0
- package/packages/adapters-qdrant/README.md +166 -0
- package/packages/adapters-qdrant/eslint.config.js +27 -0
- package/packages/adapters-qdrant/package.json +49 -0
- package/packages/adapters-qdrant/src/index.ts +490 -0
- package/packages/adapters-qdrant/src/manifest.ts +54 -0
- package/packages/adapters-qdrant/src/retry.ts +204 -0
- package/packages/adapters-qdrant/tsconfig.build.json +15 -0
- package/packages/adapters-qdrant/tsconfig.json +9 -0
- package/packages/adapters-qdrant/tsup.config.ts +9 -0
- package/packages/adapters-redis/README.md +159 -0
- package/packages/adapters-redis/eslint.config.js +27 -0
- package/packages/adapters-redis/package.json +49 -0
- package/packages/adapters-redis/src/index.ts +164 -0
- package/packages/adapters-redis/src/manifest.ts +49 -0
- package/packages/adapters-redis/tsconfig.build.json +15 -0
- package/packages/adapters-redis/tsconfig.json +9 -0
- package/packages/adapters-redis/tsup.config.ts +9 -0
- package/packages/adapters-snapshot-localfs/README.md +10 -0
- package/packages/adapters-snapshot-localfs/eslint.config.js +2 -0
- package/packages/adapters-snapshot-localfs/package.json +46 -0
- package/packages/adapters-snapshot-localfs/src/index.test.ts +40 -0
- package/packages/adapters-snapshot-localfs/src/index.ts +292 -0
- package/packages/adapters-snapshot-localfs/src/manifest.ts +32 -0
- package/packages/adapters-snapshot-localfs/tsconfig.build.json +15 -0
- package/packages/adapters-snapshot-localfs/tsconfig.json +16 -0
- package/packages/adapters-snapshot-localfs/tsup.config.ts +11 -0
- package/packages/adapters-sqlite/README.md +163 -0
- package/packages/adapters-sqlite/eslint.config.js +27 -0
- package/packages/adapters-sqlite/package.json +54 -0
- package/packages/adapters-sqlite/src/index.test.ts +245 -0
- package/packages/adapters-sqlite/src/index.ts +382 -0
- package/packages/adapters-sqlite/src/manifest.ts +47 -0
- package/packages/adapters-sqlite/src/secure-sql.test.ts +290 -0
- package/packages/adapters-sqlite/src/secure-sql.ts +281 -0
- package/packages/adapters-sqlite/tsconfig.build.json +15 -0
- package/packages/adapters-sqlite/tsconfig.json +9 -0
- package/packages/adapters-sqlite/tsup.config.ts +8 -0
- package/packages/adapters-sqlite/vitest.config.ts +19 -0
- package/packages/adapters-transport/README.md +170 -0
- package/packages/adapters-transport/eslint.config.js +27 -0
- package/packages/adapters-transport/package.json +49 -0
- package/packages/adapters-transport/src/__tests__/unix-socket-server.test.ts +550 -0
- package/packages/adapters-transport/src/index.ts +101 -0
- package/packages/adapters-transport/src/ipc-transport.ts +228 -0
- package/packages/adapters-transport/src/transport.ts +224 -0
- package/packages/adapters-transport/src/types.ts +92 -0
- package/packages/adapters-transport/src/unix-socket-server.ts +193 -0
- package/packages/adapters-transport/src/unix-socket-transport.ts +280 -0
- package/packages/adapters-transport/tsconfig.build.json +15 -0
- package/packages/adapters-transport/tsconfig.json +9 -0
- package/packages/adapters-transport/tsup.config.ts +9 -0
- package/packages/adapters-vibeproxy/README.md +159 -0
- package/packages/adapters-vibeproxy/eslint.config.js +27 -0
- package/packages/adapters-vibeproxy/package.json +51 -0
- package/packages/adapters-vibeproxy/src/index.ts +13 -0
- package/packages/adapters-vibeproxy/src/llm.ts +437 -0
- package/packages/adapters-vibeproxy/src/manifest.ts +51 -0
- package/packages/adapters-vibeproxy/tsconfig.build.json +15 -0
- package/packages/adapters-vibeproxy/tsconfig.json +9 -0
- package/packages/adapters-vibeproxy/tsup.config.ts +8 -0
- package/packages/adapters-workspace-agent/package.json +46 -0
- package/packages/adapters-workspace-agent/src/__tests__/adapter.test.ts +212 -0
- package/packages/adapters-workspace-agent/src/index.ts +220 -0
- package/packages/adapters-workspace-agent/src/manifest.ts +36 -0
- package/packages/adapters-workspace-agent/tsconfig.build.json +15 -0
- package/packages/adapters-workspace-agent/tsconfig.json +16 -0
- package/packages/adapters-workspace-agent/tsup.config.ts +11 -0
- package/packages/adapters-workspace-localfs/README.md +9 -0
- package/packages/adapters-workspace-localfs/eslint.config.js +2 -0
- package/packages/adapters-workspace-localfs/package.json +46 -0
- package/packages/adapters-workspace-localfs/src/index.test.ts +27 -0
- package/packages/adapters-workspace-localfs/src/index.ts +172 -0
- package/packages/adapters-workspace-localfs/src/manifest.ts +32 -0
- package/packages/adapters-workspace-localfs/tsconfig.build.json +15 -0
- package/packages/adapters-workspace-localfs/tsconfig.json +16 -0
- package/packages/adapters-workspace-localfs/tsup.config.ts +11 -0
- package/packages/adapters-workspace-worktree/README.md +9 -0
- package/packages/adapters-workspace-worktree/eslint.config.js +2 -0
- package/packages/adapters-workspace-worktree/package.json +46 -0
- package/packages/adapters-workspace-worktree/src/index.test.ts +38 -0
- package/packages/adapters-workspace-worktree/src/index.ts +245 -0
- package/packages/adapters-workspace-worktree/src/manifest.ts +38 -0
- package/packages/adapters-workspace-worktree/tsconfig.build.json +15 -0
- package/packages/adapters-workspace-worktree/tsconfig.json +16 -0
- package/packages/adapters-workspace-worktree/tsup.config.ts +11 -0
- package/pnpm-workspace.yaml +2800 -0
- package/prettierrc.json +1 -0
- package/scripts/devkit-sync.mjs +37 -0
- package/scripts/hooks/post-push +9 -0
- package/scripts/hooks/pre-commit +9 -0
- package/scripts/hooks/pre-push +9 -0
- package/test-integration.ts +242 -0
- package/test.txt +1 -0
- package/tsconfig.base.json +6 -0
- package/tsconfig.build.json +15 -0
- package/tsconfig.json +9 -0
- package/tsconfig.paths.json +26 -0
- package/tsconfig.tools.json +17 -0
- package/tsup.config.bin.ts +34 -0
- package/tsup.config.cli.ts +41 -0
- package/tsup.config.dual.ts +46 -0
- package/tsup.config.ts +36 -0
- package/tsup.external.json +103 -0
- 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,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
|
+
];
|