@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,10 @@
|
|
|
1
|
+
# @kb-labs/adapters-snapshot-localfs
|
|
2
|
+
|
|
3
|
+
Local filesystem implementation of `ISnapshotProvider`.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Capture snapshot by copying source directory into snapshot store
|
|
8
|
+
- Restore snapshot to target directory
|
|
9
|
+
- Status/delete/garbage-collect lifecycle
|
|
10
|
+
- Can resolve workspace root from workspace registry
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kb-labs/adapters-snapshot-localfs",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Local filesystem adapter implementing ISnapshotProvider",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"scripts": {
|
|
20
|
+
"clean": "rimraf dist",
|
|
21
|
+
"build": "tsup",
|
|
22
|
+
"dev": "tsup --watch",
|
|
23
|
+
"type-check": "tsc --noEmit",
|
|
24
|
+
"test": "vitest run --passWithNoTests",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"lint": "eslint src --ext .ts",
|
|
27
|
+
"lint:fix": "eslint . --fix"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"@kb-labs/core-platform": "*"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@kb-labs/core-platform": "link:../../../../platform/kb-labs-core/packages/core-platform",
|
|
34
|
+
"@types/node": "^24.3.3",
|
|
35
|
+
"eslint": "^9",
|
|
36
|
+
"tsup": "^8.5.0",
|
|
37
|
+
"typescript": "^5.6.3",
|
|
38
|
+
"vitest": "^3.2.4",
|
|
39
|
+
"@kb-labs/devkit": "link:../../../kb-labs-devkit",
|
|
40
|
+
"rimraf": "^6.0.1"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=20.0.0",
|
|
44
|
+
"pnpm": ">=9.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { mkdtemp, rm, writeFile, readFile, mkdir } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import { LocalFsSnapshotAdapter } from './index.js';
|
|
6
|
+
|
|
7
|
+
describe('LocalFsSnapshotAdapter', () => {
|
|
8
|
+
it('captures and restores workspace snapshot', async () => {
|
|
9
|
+
const tmp = await mkdtemp(path.join(os.tmpdir(), 'kb-snapshot-'));
|
|
10
|
+
try {
|
|
11
|
+
const workspaceId = 'ws_1';
|
|
12
|
+
const workspaceRoot = path.join(tmp, 'demo');
|
|
13
|
+
await mkdir(path.join(tmp, '.kb/runtime/workspace-registry'), { recursive: true });
|
|
14
|
+
await mkdir(workspaceRoot, { recursive: true });
|
|
15
|
+
await writeFile(
|
|
16
|
+
path.join(tmp, '.kb/runtime/workspace-registry', `${workspaceId}.json`),
|
|
17
|
+
JSON.stringify({ workspaceId, rootPath: workspaceRoot }, null, 2),
|
|
18
|
+
'utf8'
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const filePath = path.join(workspaceRoot, 'hello.txt');
|
|
22
|
+
await writeFile(filePath, 'v1', 'utf8');
|
|
23
|
+
|
|
24
|
+
const snapshot = new LocalFsSnapshotAdapter({ workspace: { cwd: tmp } });
|
|
25
|
+
const snap = await snapshot.capture({ workspaceId, namespace: 'demo' });
|
|
26
|
+
|
|
27
|
+
await writeFile(filePath, 'v2', 'utf8');
|
|
28
|
+
await snapshot.restore({
|
|
29
|
+
snapshotId: snap.snapshotId,
|
|
30
|
+
workspaceId,
|
|
31
|
+
overwrite: true,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const restored = await readFile(filePath, 'utf8');
|
|
35
|
+
expect(restored).toBe('v1');
|
|
36
|
+
} finally {
|
|
37
|
+
await rm(tmp, { recursive: true, force: true });
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { mkdir, readFile, rm, writeFile, access, cp, readdir, stat } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import type {
|
|
5
|
+
ISnapshotProvider,
|
|
6
|
+
CaptureSnapshotRequest,
|
|
7
|
+
SnapshotDescriptor,
|
|
8
|
+
RestoreSnapshotRequest,
|
|
9
|
+
RestoreSnapshotResult,
|
|
10
|
+
SnapshotStatusResult,
|
|
11
|
+
SnapshotGarbageCollectRequest,
|
|
12
|
+
SnapshotGarbageCollectResult,
|
|
13
|
+
SnapshotProviderCapabilities,
|
|
14
|
+
SnapshotStatus,
|
|
15
|
+
} from '@kb-labs/core-platform';
|
|
16
|
+
|
|
17
|
+
export { manifest } from './manifest.js';
|
|
18
|
+
|
|
19
|
+
interface WorkspaceContext {
|
|
20
|
+
cwd?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface LocalFsSnapshotAdapterConfig {
|
|
24
|
+
storageDir?: string;
|
|
25
|
+
workspaceRegistryDir?: string;
|
|
26
|
+
workspace?: WorkspaceContext;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface SnapshotRecord {
|
|
30
|
+
snapshotId: string;
|
|
31
|
+
status: SnapshotStatus;
|
|
32
|
+
createdAt: string;
|
|
33
|
+
updatedAt: string;
|
|
34
|
+
workspaceId?: string;
|
|
35
|
+
environmentId?: string;
|
|
36
|
+
sourcePath: string;
|
|
37
|
+
payloadPath: string;
|
|
38
|
+
namespace?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface WorkspaceRecord {
|
|
42
|
+
workspaceId: string;
|
|
43
|
+
rootPath?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class LocalFsSnapshotAdapter implements ISnapshotProvider {
|
|
47
|
+
private readonly cwd: string;
|
|
48
|
+
private readonly storageDir: string;
|
|
49
|
+
private readonly workspaceRegistryDir: string;
|
|
50
|
+
private readonly records = new Map<string, SnapshotRecord>();
|
|
51
|
+
|
|
52
|
+
constructor(private readonly config: LocalFsSnapshotAdapterConfig = {}) {
|
|
53
|
+
this.cwd = path.resolve(config.workspace?.cwd ?? process.cwd());
|
|
54
|
+
this.storageDir = path.resolve(this.cwd, config.storageDir ?? '.kb/runtime/snapshots');
|
|
55
|
+
this.workspaceRegistryDir = path.resolve(
|
|
56
|
+
this.cwd,
|
|
57
|
+
config.workspaceRegistryDir ?? '.kb/runtime/workspace-registry'
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async capture(request: CaptureSnapshotRequest): Promise<SnapshotDescriptor> {
|
|
62
|
+
const snapshotId = request.snapshotId ?? `snap_${randomUUID()}`;
|
|
63
|
+
const now = new Date().toISOString();
|
|
64
|
+
const sourcePath = await this.resolveSourcePath(request);
|
|
65
|
+
const namespace = request.namespace ?? 'default';
|
|
66
|
+
const payloadPath = path.join(this.storageDir, namespace, snapshotId);
|
|
67
|
+
|
|
68
|
+
await mkdir(path.dirname(payloadPath), { recursive: true });
|
|
69
|
+
await rm(payloadPath, { recursive: true, force: true });
|
|
70
|
+
await cp(sourcePath, payloadPath, { recursive: true, force: true });
|
|
71
|
+
|
|
72
|
+
const record: SnapshotRecord = {
|
|
73
|
+
snapshotId,
|
|
74
|
+
status: 'ready',
|
|
75
|
+
createdAt: now,
|
|
76
|
+
updatedAt: now,
|
|
77
|
+
workspaceId: request.workspaceId,
|
|
78
|
+
environmentId: request.environmentId,
|
|
79
|
+
sourcePath,
|
|
80
|
+
payloadPath,
|
|
81
|
+
namespace,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
await this.persistRecord(record);
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
snapshotId,
|
|
88
|
+
provider: 'snapshot-localfs',
|
|
89
|
+
status: 'ready',
|
|
90
|
+
createdAt: now,
|
|
91
|
+
updatedAt: now,
|
|
92
|
+
workspaceId: request.workspaceId,
|
|
93
|
+
environmentId: request.environmentId,
|
|
94
|
+
metadata: {
|
|
95
|
+
namespace,
|
|
96
|
+
payloadPath,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async restore(request: RestoreSnapshotRequest): Promise<RestoreSnapshotResult> {
|
|
102
|
+
const record = await this.getRecordOrThrow(request.snapshotId);
|
|
103
|
+
const now = new Date().toISOString();
|
|
104
|
+
|
|
105
|
+
const targetPath = request.targetPath
|
|
106
|
+
? path.resolve(this.cwd, request.targetPath)
|
|
107
|
+
: await this.resolveRestoreTargetPath(request.workspaceId, record.workspaceId);
|
|
108
|
+
|
|
109
|
+
if (!request.overwrite) {
|
|
110
|
+
try {
|
|
111
|
+
await access(targetPath);
|
|
112
|
+
throw new Error(`Restore target already exists: ${targetPath}. Use overwrite=true.`);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (error instanceof Error && error.message.startsWith('Restore target already exists')) {
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
// path missing, continue
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (request.overwrite) {
|
|
122
|
+
await rm(targetPath, { recursive: true, force: true });
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
126
|
+
await cp(record.payloadPath, targetPath, { recursive: true, force: true });
|
|
127
|
+
|
|
128
|
+
record.status = 'ready';
|
|
129
|
+
record.updatedAt = now;
|
|
130
|
+
await this.persistRecord(record);
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
snapshotId: request.snapshotId,
|
|
134
|
+
restoredAt: now,
|
|
135
|
+
workspaceId: request.workspaceId,
|
|
136
|
+
environmentId: request.environmentId,
|
|
137
|
+
targetPath,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async getStatus(snapshotId: string): Promise<SnapshotStatusResult> {
|
|
142
|
+
const record = await this.getRecordOrThrow(snapshotId);
|
|
143
|
+
return {
|
|
144
|
+
snapshotId,
|
|
145
|
+
status: record.status,
|
|
146
|
+
updatedAt: record.updatedAt,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async delete(snapshotId: string): Promise<void> {
|
|
151
|
+
const record = await this.getRecordOrThrow(snapshotId);
|
|
152
|
+
await rm(record.payloadPath, { recursive: true, force: true });
|
|
153
|
+
this.records.delete(snapshotId);
|
|
154
|
+
await rm(this.getRecordPath(snapshotId), { force: true });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async garbageCollect(
|
|
158
|
+
request: SnapshotGarbageCollectRequest = {}
|
|
159
|
+
): Promise<SnapshotGarbageCollectResult> {
|
|
160
|
+
const beforeTs = request.before ? new Date(request.before).getTime() : Number.POSITIVE_INFINITY;
|
|
161
|
+
const limit = request.limit ?? Number.POSITIVE_INFINITY;
|
|
162
|
+
const dryRun = request.dryRun ?? false;
|
|
163
|
+
let scanned = 0;
|
|
164
|
+
let deleted = 0;
|
|
165
|
+
|
|
166
|
+
for (const record of await this.loadAllRecords()) {
|
|
167
|
+
scanned += 1;
|
|
168
|
+
const createdTs = new Date(record.createdAt).getTime();
|
|
169
|
+
if (createdTs >= beforeTs) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (request.namespace && record.namespace !== request.namespace) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (deleted >= limit) {
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!dryRun) {
|
|
180
|
+
await this.delete(record.snapshotId);
|
|
181
|
+
}
|
|
182
|
+
deleted += 1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return { scanned, deleted, dryRun };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
getCapabilities(): SnapshotProviderCapabilities {
|
|
189
|
+
return {
|
|
190
|
+
supportsWorkspaceSnapshots: true,
|
|
191
|
+
supportsEnvironmentSnapshots: false,
|
|
192
|
+
supportsGarbageCollection: true,
|
|
193
|
+
supportsIncrementalSnapshots: false,
|
|
194
|
+
custom: {
|
|
195
|
+
provider: 'localfs',
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private async resolveSourcePath(request: CaptureSnapshotRequest): Promise<string> {
|
|
201
|
+
if (request.sourcePath) {
|
|
202
|
+
return path.resolve(this.cwd, request.sourcePath);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (request.workspaceId) {
|
|
206
|
+
const workspace = await this.readWorkspaceRecord(request.workspaceId);
|
|
207
|
+
if (workspace.rootPath) {
|
|
208
|
+
return workspace.rootPath;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
throw new Error('Snapshot capture requires sourcePath or resolvable workspaceId');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private async resolveRestoreTargetPath(
|
|
216
|
+
requestedWorkspaceId?: string,
|
|
217
|
+
recordWorkspaceId?: string
|
|
218
|
+
): Promise<string> {
|
|
219
|
+
const workspaceId = requestedWorkspaceId ?? recordWorkspaceId;
|
|
220
|
+
if (!workspaceId) {
|
|
221
|
+
throw new Error('Snapshot restore requires targetPath or workspaceId');
|
|
222
|
+
}
|
|
223
|
+
const workspace = await this.readWorkspaceRecord(workspaceId);
|
|
224
|
+
if (!workspace.rootPath) {
|
|
225
|
+
throw new Error(`Workspace rootPath not found for workspaceId=${workspaceId}`);
|
|
226
|
+
}
|
|
227
|
+
return workspace.rootPath;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private getRecordPath(snapshotId: string): string {
|
|
231
|
+
return path.join(this.storageDir, '.records', `${snapshotId}.json`);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
private async persistRecord(record: SnapshotRecord): Promise<void> {
|
|
235
|
+
this.records.set(record.snapshotId, record);
|
|
236
|
+
const recordPath = this.getRecordPath(record.snapshotId);
|
|
237
|
+
await mkdir(path.dirname(recordPath), { recursive: true });
|
|
238
|
+
await writeFile(recordPath, JSON.stringify(record, null, 2), 'utf8');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private async getRecordOrThrow(snapshotId: string): Promise<SnapshotRecord> {
|
|
242
|
+
const inMemory = this.records.get(snapshotId);
|
|
243
|
+
if (inMemory) {
|
|
244
|
+
return inMemory;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const recordPath = this.getRecordPath(snapshotId);
|
|
248
|
+
try {
|
|
249
|
+
const raw = await readFile(recordPath, 'utf8');
|
|
250
|
+
const parsed = JSON.parse(raw) as SnapshotRecord;
|
|
251
|
+
this.records.set(snapshotId, parsed);
|
|
252
|
+
return parsed;
|
|
253
|
+
} catch {
|
|
254
|
+
throw new Error(`Snapshot not found: ${snapshotId}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private async readWorkspaceRecord(workspaceId: string): Promise<WorkspaceRecord> {
|
|
259
|
+
const filePath = path.join(this.workspaceRegistryDir, `${workspaceId}.json`);
|
|
260
|
+
const raw = await readFile(filePath, 'utf8');
|
|
261
|
+
return JSON.parse(raw) as WorkspaceRecord;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
private async loadAllRecords(): Promise<SnapshotRecord[]> {
|
|
265
|
+
const recordsDir = path.join(this.storageDir, '.records');
|
|
266
|
+
try {
|
|
267
|
+
const entries = await readdir(recordsDir);
|
|
268
|
+
const loaded: SnapshotRecord[] = [];
|
|
269
|
+
for (const entry of entries) {
|
|
270
|
+
if (!entry.endsWith('.json')) {
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
const filePath = path.join(recordsDir, entry);
|
|
274
|
+
const fileStat = await stat(filePath);
|
|
275
|
+
if (!fileStat.isFile()) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
const raw = await readFile(filePath, 'utf8');
|
|
279
|
+
loaded.push(JSON.parse(raw) as SnapshotRecord);
|
|
280
|
+
}
|
|
281
|
+
return loaded;
|
|
282
|
+
} catch {
|
|
283
|
+
return [];
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function createAdapter(config?: LocalFsSnapshotAdapterConfig): LocalFsSnapshotAdapter {
|
|
289
|
+
return new LocalFsSnapshotAdapter(config);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export default createAdapter;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AdapterManifest } from '@kb-labs/core-platform';
|
|
2
|
+
|
|
3
|
+
export const manifest: AdapterManifest = {
|
|
4
|
+
manifestVersion: '1.0.0',
|
|
5
|
+
id: 'localfs-snapshot-provider',
|
|
6
|
+
name: 'LocalFS Snapshot Provider',
|
|
7
|
+
version: '0.1.0',
|
|
8
|
+
description: 'Snapshot provider on local filesystem',
|
|
9
|
+
author: 'KB Labs Team',
|
|
10
|
+
license: 'KBPL-1.1',
|
|
11
|
+
type: 'core',
|
|
12
|
+
implements: 'ISnapshotProvider',
|
|
13
|
+
contexts: ['workspace'],
|
|
14
|
+
capabilities: {
|
|
15
|
+
custom: {
|
|
16
|
+
provider: 'localfs',
|
|
17
|
+
workspaceRegistry: true,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
configSchema: {
|
|
21
|
+
storageDir: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
default: '.kb/runtime/snapshots',
|
|
24
|
+
description: 'Root directory where snapshots are stored',
|
|
25
|
+
},
|
|
26
|
+
workspaceRegistryDir: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
default: '.kb/runtime/workspace-registry',
|
|
29
|
+
description: 'Directory with workspace metadata for source path resolution',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"extends": "@kb-labs/devkit/tsconfig/node.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"baseUrl": ".",
|
|
6
|
+
"paths": {
|
|
7
|
+
"@kb-labs/core-platform": [
|
|
8
|
+
"../../../kb-labs-core/packages/core-platform/src/index.ts"
|
|
9
|
+
],
|
|
10
|
+
"@kb-labs/core-platform/*": [
|
|
11
|
+
"../../../kb-labs-core/packages/core-platform/src/*"
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"include": ["src"]
|
|
16
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# @kb-labs/adapters-sqlite
|
|
2
|
+
|
|
3
|
+
> Part of [KB Labs](https://github.com/KirillBaranov/kb-labs) ecosystem. Works exclusively within KB Labs platform.
|
|
4
|
+
|
|
5
|
+
Lightweight embedded SQL database adapter using better-sqlite3 with FTS, JSON, and transaction support.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
| Property | Value |
|
|
10
|
+
|----------|-------|
|
|
11
|
+
| **Implements** | `ISQLDatabase` |
|
|
12
|
+
| **Type** | `core` |
|
|
13
|
+
| **Requires** | None |
|
|
14
|
+
| **Category** | Database |
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- **Embedded Database** - No external server required
|
|
19
|
+
- **Full-Text Search** - FTS5 for fast text search
|
|
20
|
+
- **JSON Support** - Store and query JSON fields
|
|
21
|
+
- **Prepared Statements** - Optimized query execution
|
|
22
|
+
- **Transaction Support** - ACID-compliant operations
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pnpm add @kb-labs/adapters-sqlite
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Configuration
|
|
31
|
+
|
|
32
|
+
Add to your `kb.config.json`:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"platform": {
|
|
37
|
+
"adapters": {
|
|
38
|
+
"db": "@kb-labs/adapters-sqlite"
|
|
39
|
+
},
|
|
40
|
+
"adapterOptions": {
|
|
41
|
+
"db": {
|
|
42
|
+
"filename": ".kb/data/kb.db",
|
|
43
|
+
"readonly": false,
|
|
44
|
+
"timeout": 5000
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Options
|
|
52
|
+
|
|
53
|
+
| Option | Type | Default | Description |
|
|
54
|
+
|--------|------|---------|-------------|
|
|
55
|
+
| `filename` | `string` | - | Database file path (`:memory:` for in-memory) |
|
|
56
|
+
| `readonly` | `boolean` | `false` | Open in readonly mode |
|
|
57
|
+
| `timeout` | `number` | `5000` | Busy timeout in milliseconds |
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
### Via Platform (Recommended)
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { usePlatform } from '@kb-labs/sdk';
|
|
65
|
+
|
|
66
|
+
const platform = usePlatform();
|
|
67
|
+
|
|
68
|
+
// Execute query
|
|
69
|
+
const users = platform.db.query<User>('SELECT * FROM users WHERE active = ?', [true]);
|
|
70
|
+
|
|
71
|
+
// Insert
|
|
72
|
+
platform.db.run('INSERT INTO users (name, email) VALUES (?, ?)', ['John', 'john@example.com']);
|
|
73
|
+
|
|
74
|
+
// Transaction
|
|
75
|
+
platform.db.transaction(() => {
|
|
76
|
+
platform.db.run('UPDATE accounts SET balance = balance - 100 WHERE id = ?', [1]);
|
|
77
|
+
platform.db.run('UPDATE accounts SET balance = balance + 100 WHERE id = ?', [2]);
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Standalone (Testing/Development)
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { createAdapter } from '@kb-labs/adapters-sqlite';
|
|
85
|
+
|
|
86
|
+
const db = createAdapter({ filename: ':memory:' });
|
|
87
|
+
|
|
88
|
+
db.run('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)');
|
|
89
|
+
db.run('INSERT INTO users (name) VALUES (?)', ['John']);
|
|
90
|
+
|
|
91
|
+
const users = db.query('SELECT * FROM users');
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Adapter Manifest
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
{
|
|
98
|
+
id: 'sqlite-database',
|
|
99
|
+
name: 'SQLite Database',
|
|
100
|
+
version: '1.0.0',
|
|
101
|
+
implements: 'ISQLDatabase',
|
|
102
|
+
capabilities: {
|
|
103
|
+
transactions: true,
|
|
104
|
+
search: true,
|
|
105
|
+
custom: {
|
|
106
|
+
prepared: true,
|
|
107
|
+
fts: true,
|
|
108
|
+
json: true,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## FAQ
|
|
115
|
+
|
|
116
|
+
<details>
|
|
117
|
+
<summary><strong>Q: How do I use in-memory database?</strong></summary>
|
|
118
|
+
|
|
119
|
+
Set filename to `:memory:`:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"adapterOptions": {
|
|
124
|
+
"db": {
|
|
125
|
+
"filename": ":memory:"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
</details>
|
|
131
|
+
|
|
132
|
+
<details>
|
|
133
|
+
<summary><strong>Q: How do I enable WAL mode for better concurrency?</strong></summary>
|
|
134
|
+
|
|
135
|
+
Run pragma after initialization:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
db.run('PRAGMA journal_mode = WAL');
|
|
139
|
+
```
|
|
140
|
+
</details>
|
|
141
|
+
|
|
142
|
+
<details>
|
|
143
|
+
<summary><strong>Q: How do I use full-text search?</strong></summary>
|
|
144
|
+
|
|
145
|
+
Create FTS5 virtual table:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
db.run('CREATE VIRTUAL TABLE docs_fts USING fts5(content)');
|
|
149
|
+
db.run("INSERT INTO docs_fts VALUES ('hello world')");
|
|
150
|
+
const results = db.query("SELECT * FROM docs_fts WHERE docs_fts MATCH 'hello'");
|
|
151
|
+
```
|
|
152
|
+
</details>
|
|
153
|
+
|
|
154
|
+
## Related Adapters
|
|
155
|
+
|
|
156
|
+
| Adapter | Use Case |
|
|
157
|
+
|---------|----------|
|
|
158
|
+
| `@kb-labs/adapters-log-sqlite` | Log persistence using SQLite |
|
|
159
|
+
| `@kb-labs/adapters-mongodb` | Document database for complex data |
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
[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
|
+
];
|