@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,460 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @kb-labs/adapters-analytics-sqlite
|
|
3
|
+
* SQLite analytics adapter for KB Labs platform.
|
|
4
|
+
*
|
|
5
|
+
* Uses better-sqlite3 with WAL mode for concurrent reads/writes from multiple processes.
|
|
6
|
+
* Implements IAnalytics with SQL-native time-series aggregation:
|
|
7
|
+
* - strftime() for groupBy (hour/day/week/month)
|
|
8
|
+
* - json_extract() for breakdownBy (dot-notation paths)
|
|
9
|
+
* - Dynamic SELECT for metrics filtering
|
|
10
|
+
* - Full EventsQuery support via SQL WHERE clauses
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import Database from 'better-sqlite3';
|
|
14
|
+
import { join, isAbsolute, dirname } from 'node:path';
|
|
15
|
+
import { mkdirSync } from 'node:fs';
|
|
16
|
+
import type {
|
|
17
|
+
IAnalytics,
|
|
18
|
+
IDisposable,
|
|
19
|
+
AnalyticsContext,
|
|
20
|
+
AnalyticsEvent,
|
|
21
|
+
EventsQuery,
|
|
22
|
+
StatsQuery,
|
|
23
|
+
EventsResponse,
|
|
24
|
+
EventsStats,
|
|
25
|
+
BufferStatus,
|
|
26
|
+
DlqStatus,
|
|
27
|
+
DailyStats,
|
|
28
|
+
} from '@kb-labs/core-platform/adapters';
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
// ─── DDL ──────────────────────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
const CREATE_EVENTS_TABLE = `
|
|
34
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
schema TEXT NOT NULL DEFAULT 'kb.v1',
|
|
37
|
+
type TEXT NOT NULL,
|
|
38
|
+
ts TEXT NOT NULL,
|
|
39
|
+
ingest_ts TEXT,
|
|
40
|
+
run_id TEXT,
|
|
41
|
+
product TEXT,
|
|
42
|
+
version TEXT,
|
|
43
|
+
actor_type TEXT,
|
|
44
|
+
actor_id TEXT,
|
|
45
|
+
actor_name TEXT,
|
|
46
|
+
ctx TEXT,
|
|
47
|
+
payload TEXT
|
|
48
|
+
)
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
const CREATE_INDEXES = [
|
|
52
|
+
`CREATE INDEX IF NOT EXISTS events_ts_idx ON events (ts)`,
|
|
53
|
+
`CREATE INDEX IF NOT EXISTS events_type_idx ON events (type)`,
|
|
54
|
+
`CREATE INDEX IF NOT EXISTS events_product_idx ON events (product)`,
|
|
55
|
+
`CREATE INDEX IF NOT EXISTS events_type_ts_idx ON events (type, ts)`,
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
// ─── groupBy mappings ─────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
const GROUP_BY_FORMAT: Record<string, string> = {
|
|
61
|
+
hour: '%Y-%m-%dT%H:00',
|
|
62
|
+
day: '%Y-%m-%d',
|
|
63
|
+
week: '%Y-W%W',
|
|
64
|
+
month: '%Y-%m',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// ─── dot-path to SQLite json_extract ─────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
function dotPathToSQL(path: string): string {
|
|
70
|
+
// "payload.model" → json_extract(payload, '$.model')
|
|
71
|
+
// "payload.nested.key" → json_extract(payload, '$.nested.key')
|
|
72
|
+
const parts = path.split('.');
|
|
73
|
+
const column = parts[0] ?? 'payload';
|
|
74
|
+
const rest = parts.slice(1).join('.');
|
|
75
|
+
if (!rest) {return column;}
|
|
76
|
+
return `json_extract(${column}, '$.${rest}')`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ─── metrics helpers ──────────────────────────────────────────────────────────
|
|
80
|
+
|
|
81
|
+
const KNOWN_METRICS: Record<string, string> = {
|
|
82
|
+
totalTokens: `SUM(CAST(json_extract(payload, '$.totalTokens') AS REAL)) as totalTokens`,
|
|
83
|
+
promptTokens: `SUM(CAST(json_extract(payload, '$.promptTokens') AS REAL)) as promptTokens`,
|
|
84
|
+
completionTokens: `SUM(CAST(json_extract(payload, '$.completionTokens') AS REAL)) as completionTokens`,
|
|
85
|
+
estimatedCost: `SUM(CAST(json_extract(payload, '$.estimatedCost') AS REAL)) as estimatedCost`,
|
|
86
|
+
durationMs: `AVG(CAST(json_extract(payload, '$.durationMs') AS REAL)) as durationMs`,
|
|
87
|
+
textLength: `SUM(CAST(json_extract(payload, '$.textLength') AS REAL)) as textLength`,
|
|
88
|
+
vectorCount: `SUM(CAST(json_extract(payload, '$.vectorCount') AS REAL)) as vectorCount`,
|
|
89
|
+
resultsCount: `AVG(CAST(json_extract(payload, '$.resultsCount') AS REAL)) as resultsCount`,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
function buildMetricsSelect(metrics: string[]): string[] {
|
|
93
|
+
return metrics.map((m) => KNOWN_METRICS[m] ?? `SUM(CAST(json_extract(payload, '$.${m}') AS REAL)) as ${m}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function getDefaultMetrics(typeFilter?: string | string[]): string[] {
|
|
97
|
+
const types = Array.isArray(typeFilter) ? typeFilter : typeFilter ? [typeFilter] : [];
|
|
98
|
+
if (types.some((t) => t.startsWith('llm.'))) {
|
|
99
|
+
return ['totalTokens', 'promptTokens', 'completionTokens', 'estimatedCost', 'durationMs'];
|
|
100
|
+
}
|
|
101
|
+
if (types.some((t) => t.startsWith('embeddings.'))) {
|
|
102
|
+
return ['textLength', 'estimatedCost', 'durationMs'];
|
|
103
|
+
}
|
|
104
|
+
if (types.some((t) => t.startsWith('vectorstore.'))) {
|
|
105
|
+
return ['resultsCount', 'durationMs', 'vectorCount'];
|
|
106
|
+
}
|
|
107
|
+
return ['durationMs'];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ─── Options ──────────────────────────────────────────────────────────────────
|
|
111
|
+
|
|
112
|
+
export interface SQLiteAnalyticsOptions {
|
|
113
|
+
/** Path to the SQLite database file. Default: .kb/analytics/analytics.sqlite */
|
|
114
|
+
dbPath?: string;
|
|
115
|
+
/** Alias for dbPath — accepted for config compatibility with kb.config.json */
|
|
116
|
+
filename?: string;
|
|
117
|
+
/** Analytics context for event enrichment */
|
|
118
|
+
context?: AnalyticsContext;
|
|
119
|
+
/** Workspace context injected by core-runtime (provides cwd for relative path resolution) */
|
|
120
|
+
workspace?: { cwd: string };
|
|
121
|
+
/** Analytics context injected by core-runtime (for auto-enrichment) */
|
|
122
|
+
analytics?: AnalyticsContext;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ─── Adapter ──────────────────────────────────────────────────────────────────
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* SQLite-based analytics adapter.
|
|
129
|
+
* Uses WAL mode — supports concurrent reads/writes from multiple processes.
|
|
130
|
+
*/
|
|
131
|
+
export class SQLiteAnalytics implements IAnalytics, IDisposable {
|
|
132
|
+
|
|
133
|
+
private readonly dbPath: string;
|
|
134
|
+
private context: AnalyticsContext;
|
|
135
|
+
private db: Database.Database;
|
|
136
|
+
|
|
137
|
+
constructor(options: SQLiteAnalyticsOptions = {}) {
|
|
138
|
+
const cwd = options.workspace?.cwd ?? process.cwd();
|
|
139
|
+
const rawPath = options.dbPath ?? options.filename ?? '.kb/analytics/analytics.sqlite';
|
|
140
|
+
this.dbPath = isAbsolute(rawPath) ? rawPath : join(cwd, rawPath);
|
|
141
|
+
|
|
142
|
+
this.context = options.context ?? options.analytics ?? {
|
|
143
|
+
source: { product: 'unknown', version: '0.0.0' },
|
|
144
|
+
runId: `run-${Date.now()}`,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Ensure directory exists
|
|
148
|
+
mkdirSync(dirname(this.dbPath), { recursive: true });
|
|
149
|
+
|
|
150
|
+
// Open database — better-sqlite3 is synchronous
|
|
151
|
+
this.db = new Database(this.dbPath);
|
|
152
|
+
|
|
153
|
+
// WAL mode: multiple readers + one writer, no exclusive lock
|
|
154
|
+
this.db.pragma('journal_mode = WAL');
|
|
155
|
+
this.db.pragma('busy_timeout = 5000');
|
|
156
|
+
this.db.pragma('synchronous = NORMAL');
|
|
157
|
+
|
|
158
|
+
// Setup schema
|
|
159
|
+
this.db.exec(CREATE_EVENTS_TABLE);
|
|
160
|
+
for (const idx of CREATE_INDEXES) {
|
|
161
|
+
this.db.exec(idx);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Ensure clean shutdown — checkpoint WAL and close connection.
|
|
165
|
+
// Without this, process.exit() leaves WAL in inconsistent state
|
|
166
|
+
// causing "database disk image is malformed" for other processes.
|
|
167
|
+
this._onExit = () => this.close();
|
|
168
|
+
process.on('exit', this._onExit);
|
|
169
|
+
process.on('SIGINT', this._onExit);
|
|
170
|
+
process.on('SIGTERM', this._onExit);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private _onExit: () => void;
|
|
174
|
+
private _closed = false;
|
|
175
|
+
|
|
176
|
+
/** Checkpoint WAL and close the database connection cleanly. */
|
|
177
|
+
close(): void {
|
|
178
|
+
if (this._closed) {return;}
|
|
179
|
+
this._closed = true;
|
|
180
|
+
try {
|
|
181
|
+
this.db.pragma('wal_checkpoint(TRUNCATE)');
|
|
182
|
+
this.db.close();
|
|
183
|
+
} catch {
|
|
184
|
+
// Already closed or corrupted — nothing we can do
|
|
185
|
+
}
|
|
186
|
+
process.removeListener('exit', this._onExit);
|
|
187
|
+
process.removeListener('SIGINT', this._onExit);
|
|
188
|
+
process.removeListener('SIGTERM', this._onExit);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Implements IDisposable — delegates to close().
|
|
193
|
+
*
|
|
194
|
+
* close() already provides the complete, correct shutdown sequence:
|
|
195
|
+
* 1. Idempotency guard (this._closed)
|
|
196
|
+
* 2. WAL TRUNCATE checkpoint (flush frames → main DB file, empty WAL)
|
|
197
|
+
* 3. Connection close (this.db.close())
|
|
198
|
+
* 4. Process listener deregistration (exit, SIGINT, SIGTERM)
|
|
199
|
+
*
|
|
200
|
+
* PlatformContainer.shutdown() checks for close() first (container.ts line 830),
|
|
201
|
+
* so the container will call close() on this adapter. dispose() is provided so
|
|
202
|
+
* that isDisposable() returns true and this adapter is typed as IDisposable for
|
|
203
|
+
* observability logging in service-bootstrap's onBeforeShutdown hook.
|
|
204
|
+
*/
|
|
205
|
+
dispose(): void {
|
|
206
|
+
this.close();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
// ─── Write ────────────────────────────────────────────────────────────────
|
|
211
|
+
|
|
212
|
+
async track(event: string, properties?: Record<string, unknown>): Promise<void> {
|
|
213
|
+
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
214
|
+
const now = new Date().toISOString();
|
|
215
|
+
|
|
216
|
+
const stmt = this.db.prepare(`
|
|
217
|
+
INSERT OR IGNORE INTO events
|
|
218
|
+
(id, schema, type, ts, ingest_ts, run_id, product, version, actor_type, actor_id, actor_name, ctx, payload)
|
|
219
|
+
VALUES
|
|
220
|
+
(?, 'kb.v1', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
221
|
+
`);
|
|
222
|
+
|
|
223
|
+
stmt.run(
|
|
224
|
+
id,
|
|
225
|
+
event,
|
|
226
|
+
now,
|
|
227
|
+
now,
|
|
228
|
+
this.context.runId ?? null,
|
|
229
|
+
this.context.source.product,
|
|
230
|
+
this.context.source.version,
|
|
231
|
+
this.context.actor?.type ?? null,
|
|
232
|
+
this.context.actor?.id ?? null,
|
|
233
|
+
this.context.actor?.name ?? null,
|
|
234
|
+
this.context.ctx ? JSON.stringify(this.context.ctx) : null,
|
|
235
|
+
properties ? JSON.stringify(properties) : null,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async identify(userId: string, traits?: Record<string, unknown>): Promise<void> {
|
|
240
|
+
await this.track('identity', { userId, ...traits });
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async flush(): Promise<void> {
|
|
244
|
+
// SQLite writes synchronously — nothing to flush
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ─── Source attribution ───────────────────────────────────────────────────
|
|
248
|
+
|
|
249
|
+
getSource(): { product: string; version: string } | undefined {
|
|
250
|
+
return this.context.source;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
setSource(source: { product: string; version: string }): void {
|
|
254
|
+
this.context = { ...this.context, source };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ─── Read: Events ─────────────────────────────────────────────────────────
|
|
258
|
+
|
|
259
|
+
async getEvents(query?: EventsQuery): Promise<EventsResponse> {
|
|
260
|
+
const { where, params } = buildWhereClause(query);
|
|
261
|
+
const limit = query?.limit ?? 100;
|
|
262
|
+
const offset = query?.offset ?? 0;
|
|
263
|
+
const whereClause = where ? ` WHERE ${where}` : '';
|
|
264
|
+
|
|
265
|
+
const countRow = this.db.prepare(`SELECT COUNT(*) as total FROM events${whereClause}`).get(...params) as { total: number };
|
|
266
|
+
const total = countRow.total;
|
|
267
|
+
|
|
268
|
+
const rows = this.db.prepare(
|
|
269
|
+
`SELECT * FROM events${whereClause} ORDER BY ts DESC LIMIT ? OFFSET ?`
|
|
270
|
+
).all(...params, limit, offset) as Record<string, unknown>[];
|
|
271
|
+
|
|
272
|
+
const events: AnalyticsEvent[] = rows.map(rowToEvent);
|
|
273
|
+
return { events, total, hasMore: offset + events.length < total };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ─── Read: Stats ──────────────────────────────────────────────────────────
|
|
277
|
+
|
|
278
|
+
async getStats(): Promise<EventsStats> {
|
|
279
|
+
const totalRow = this.db.prepare(
|
|
280
|
+
`SELECT COUNT(*) as total, MIN(ts) as minTs, MAX(ts) as maxTs FROM events`
|
|
281
|
+
).get() as { total: number; minTs: string; maxTs: string };
|
|
282
|
+
|
|
283
|
+
const totalEvents = totalRow.total;
|
|
284
|
+
const from = totalRow.minTs ?? new Date().toISOString();
|
|
285
|
+
const to = totalRow.maxTs ?? new Date().toISOString();
|
|
286
|
+
|
|
287
|
+
const byType: Record<string, number> = {};
|
|
288
|
+
for (const r of this.db.prepare(`SELECT type, COUNT(*) as cnt FROM events GROUP BY type`).all() as { type: string; cnt: number }[]) {
|
|
289
|
+
byType[r.type] = r.cnt;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const bySource: Record<string, number> = {};
|
|
293
|
+
for (const r of this.db.prepare(
|
|
294
|
+
`SELECT COALESCE(product, 'unknown') as product, COUNT(*) as cnt FROM events GROUP BY product`
|
|
295
|
+
).all() as { product: string; cnt: number }[]) {
|
|
296
|
+
bySource[r.product] = r.cnt;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const byActor: Record<string, number> = {};
|
|
300
|
+
for (const r of this.db.prepare(
|
|
301
|
+
`SELECT COALESCE(actor_id, 'unknown') as actor, COUNT(*) as cnt FROM events GROUP BY actor`
|
|
302
|
+
).all() as { actor: string; cnt: number }[]) {
|
|
303
|
+
byActor[r.actor] = r.cnt;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return { totalEvents, byType, bySource, byActor, timeRange: { from, to } };
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// ─── Read: Time-series ────────────────────────────────────────────────────
|
|
310
|
+
|
|
311
|
+
async getDailyStats(query?: StatsQuery): Promise<DailyStats[]> {
|
|
312
|
+
const groupBy = query?.groupBy ?? 'day';
|
|
313
|
+
const fmtStr = GROUP_BY_FORMAT[groupBy] ?? '%Y-%m-%d';
|
|
314
|
+
|
|
315
|
+
const breakdownBy = query?.breakdownBy;
|
|
316
|
+
const breakdownSQL = breakdownBy ? dotPathToSQL(breakdownBy) : null;
|
|
317
|
+
|
|
318
|
+
const metricsFilter = query?.metrics ?? getDefaultMetrics(query?.type);
|
|
319
|
+
const metricsSelect = buildMetricsSelect(metricsFilter);
|
|
320
|
+
|
|
321
|
+
const { where, params } = buildWhereClause(query);
|
|
322
|
+
const whereClause = where ? `WHERE ${where}` : '';
|
|
323
|
+
|
|
324
|
+
const selectParts = [
|
|
325
|
+
`strftime('${fmtStr}', ts) as date`,
|
|
326
|
+
`COUNT(*) as count`,
|
|
327
|
+
...metricsSelect,
|
|
328
|
+
...(breakdownSQL ? [`${breakdownSQL} as breakdown`] : []),
|
|
329
|
+
];
|
|
330
|
+
|
|
331
|
+
const groupByParts = [`strftime('${fmtStr}', ts)`];
|
|
332
|
+
if (breakdownSQL) {groupByParts.push(breakdownSQL);}
|
|
333
|
+
|
|
334
|
+
const sql = `
|
|
335
|
+
SELECT ${selectParts.join(', ')}
|
|
336
|
+
FROM events
|
|
337
|
+
${whereClause}
|
|
338
|
+
GROUP BY ${groupByParts.join(', ')}
|
|
339
|
+
ORDER BY strftime('${fmtStr}', ts) ASC${breakdownSQL ? ', breakdown ASC NULLS LAST' : ''}
|
|
340
|
+
`;
|
|
341
|
+
|
|
342
|
+
const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];
|
|
343
|
+
|
|
344
|
+
return rows.map((r): DailyStats => {
|
|
345
|
+
const metrics: Record<string, number> = {};
|
|
346
|
+
for (const m of metricsFilter) {
|
|
347
|
+
const v = r[m];
|
|
348
|
+
if (v !== null && v !== undefined) {
|
|
349
|
+
metrics[m] = Number(v);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const stat: DailyStats = {
|
|
354
|
+
date: String(r['date']),
|
|
355
|
+
count: Number(r['count']),
|
|
356
|
+
};
|
|
357
|
+
if (Object.keys(metrics).length > 0) {stat.metrics = metrics;}
|
|
358
|
+
if (breakdownSQL && r['breakdown'] !== null && r['breakdown'] !== undefined) {
|
|
359
|
+
stat.breakdown = String(r['breakdown']);
|
|
360
|
+
}
|
|
361
|
+
return stat;
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// ─── Read: Buffer / DLQ ───────────────────────────────────────────────────
|
|
366
|
+
|
|
367
|
+
async getBufferStatus(): Promise<BufferStatus | null> {
|
|
368
|
+
const row = this.db.prepare(
|
|
369
|
+
`SELECT COUNT(*) as segments, MIN(ts) as oldest, MAX(ts) as newest FROM events`
|
|
370
|
+
).get() as { segments: number; oldest: string | null; newest: string | null };
|
|
371
|
+
|
|
372
|
+
return {
|
|
373
|
+
segments: row.segments,
|
|
374
|
+
totalSizeBytes: 0,
|
|
375
|
+
oldestEventTs: row.oldest,
|
|
376
|
+
newestEventTs: row.newest,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
async getDlqStatus(): Promise<DlqStatus | null> {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// ─── SQL helpers ──────────────────────────────────────────────────────────────
|
|
386
|
+
|
|
387
|
+
function buildWhereClause(query?: EventsQuery): { where: string; params: unknown[] } {
|
|
388
|
+
if (!query) {return { where: '', params: [] };}
|
|
389
|
+
|
|
390
|
+
const clauses: string[] = [];
|
|
391
|
+
const params: unknown[] = [];
|
|
392
|
+
|
|
393
|
+
if (query.type) {
|
|
394
|
+
const types = Array.isArray(query.type) ? query.type : [query.type];
|
|
395
|
+
if (types.length === 1) {
|
|
396
|
+
clauses.push(`type = ?`);
|
|
397
|
+
params.push(types[0]);
|
|
398
|
+
} else {
|
|
399
|
+
clauses.push(`type IN (${types.map(() => '?').join(', ')})`);
|
|
400
|
+
params.push(...types);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (query.source) {
|
|
405
|
+
clauses.push(`product = ?`);
|
|
406
|
+
params.push(query.source);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (query.actor) {
|
|
410
|
+
clauses.push(`actor_id = ?`);
|
|
411
|
+
params.push(query.actor);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if (query.from) {
|
|
415
|
+
clauses.push(`ts >= ?`);
|
|
416
|
+
params.push(query.from);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (query.to) {
|
|
420
|
+
clauses.push(`ts <= ?`);
|
|
421
|
+
params.push(query.to);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return { where: clauses.join(' AND '), params };
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function rowToEvent(r: Record<string, unknown>): AnalyticsEvent {
|
|
428
|
+
return {
|
|
429
|
+
id: String(r['id']),
|
|
430
|
+
schema: 'kb.v1',
|
|
431
|
+
type: String(r['type']),
|
|
432
|
+
ts: String(r['ts']),
|
|
433
|
+
ingestTs: String(r['ingest_ts'] ?? r['ts']),
|
|
434
|
+
source: {
|
|
435
|
+
product: String(r['product'] ?? ''),
|
|
436
|
+
version: String(r['version'] ?? ''),
|
|
437
|
+
},
|
|
438
|
+
runId: String(r['run_id'] ?? ''),
|
|
439
|
+
actor: r['actor_type']
|
|
440
|
+
? {
|
|
441
|
+
type: r['actor_type'] as 'user' | 'agent' | 'ci',
|
|
442
|
+
id: r['actor_id'] ? String(r['actor_id']) : undefined,
|
|
443
|
+
name: r['actor_name'] ? String(r['actor_name']) : undefined,
|
|
444
|
+
}
|
|
445
|
+
: undefined,
|
|
446
|
+
ctx: r['ctx'] ? (JSON.parse(String(r['ctx'])) as Record<string, string | number | boolean | null>) : undefined,
|
|
447
|
+
payload: r['payload'] ? JSON.parse(String(r['payload'])) : undefined,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export { manifest } from './manifest.js';
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Factory function required by core-runtime adapter discovery.
|
|
455
|
+
*/
|
|
456
|
+
export function createAdapter(options?: SQLiteAnalyticsOptions): IAnalytics {
|
|
457
|
+
return new SQLiteAnalytics(options);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
export default createAdapter;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @kb-labs/adapters-analytics-sqlite/manifest
|
|
3
|
+
* Adapter manifest for SQLite analytics adapter.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { AdapterManifest } from '@kb-labs/core-platform';
|
|
7
|
+
|
|
8
|
+
export const manifest: AdapterManifest = {
|
|
9
|
+
manifestVersion: '1.0.0',
|
|
10
|
+
id: 'analytics-sqlite',
|
|
11
|
+
name: 'SQLite Analytics',
|
|
12
|
+
version: '0.1.0',
|
|
13
|
+
description: 'SQLite-based analytics adapter — concurrent writes, WAL mode, SQL analytics, no lock issues',
|
|
14
|
+
author: 'KB Labs Team',
|
|
15
|
+
license: 'KBPL-1.1',
|
|
16
|
+
type: 'core',
|
|
17
|
+
implements: 'IAnalytics',
|
|
18
|
+
contexts: ['workspace', 'analytics'],
|
|
19
|
+
capabilities: {
|
|
20
|
+
search: true,
|
|
21
|
+
custom: {
|
|
22
|
+
offline: true,
|
|
23
|
+
stats: true,
|
|
24
|
+
sql: true,
|
|
25
|
+
groupBy: true,
|
|
26
|
+
breakdownBy: true,
|
|
27
|
+
concurrent: true,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
configSchema: {
|
|
31
|
+
dbPath: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
default: '.kb/analytics/analytics.sqlite',
|
|
34
|
+
description: 'Path to the SQLite database file (relative to workspace root)',
|
|
35
|
+
},
|
|
36
|
+
filename: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
description: 'Alias for dbPath — accepted for config compatibility',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# @kb-labs/adapters-environment-docker
|
|
2
|
+
|
|
3
|
+
Docker-based implementation of `IEnvironmentProvider` for KB Labs full-cycle runs.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Create long-lived environments with `docker run -d`
|
|
8
|
+
- Query environment status via `docker inspect`
|
|
9
|
+
- Idempotent destroy via `docker rm -f`
|
|
10
|
+
- Lease renewal contract for orchestrator integration
|
|
11
|
+
|
|
12
|
+
## Example config
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"adapters": {
|
|
17
|
+
"environment": "@kb-labs/adapters-environment-docker"
|
|
18
|
+
},
|
|
19
|
+
"adapterOptions": {
|
|
20
|
+
"environment": {
|
|
21
|
+
"defaultImage": "node:20-alpine",
|
|
22
|
+
"defaultTtlMs": 3600000,
|
|
23
|
+
"mountWorkspace": true,
|
|
24
|
+
"workspaceMountPath": "/workspace"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kb-labs/adapters-environment-docker",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Docker adapter implementing IEnvironmentProvider",
|
|
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
|
+
"optionalDependencies": {
|
|
33
|
+
"@kb-labs/gateway-auth": "workspace:*"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@kb-labs/core-platform": "link:../../../../platform/kb-labs-core/packages/core-platform",
|
|
37
|
+
"@types/node": "^24.3.3",
|
|
38
|
+
"eslint": "^9",
|
|
39
|
+
"tsup": "^8.5.0",
|
|
40
|
+
"typescript": "^5.6.3",
|
|
41
|
+
"vitest": "^3.2.4",
|
|
42
|
+
"@kb-labs/devkit": "link:../../../kb-labs-devkit",
|
|
43
|
+
"rimraf": "^6.0.1"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20.0.0",
|
|
47
|
+
"pnpm": ">=9.0.0"
|
|
48
|
+
}
|
|
49
|
+
}
|