@de-otio/chaoskb-client 0.2.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/dist/cli/agent-registry/config-merger.d.ts +28 -0
- package/dist/cli/agent-registry/config-merger.d.ts.map +1 -0
- package/dist/cli/agent-registry/config-merger.js +90 -0
- package/dist/cli/agent-registry/config-merger.js.map +1 -0
- package/dist/cli/agent-registry/detector.d.ts +7 -0
- package/dist/cli/agent-registry/detector.d.ts.map +1 -0
- package/dist/cli/agent-registry/detector.js +100 -0
- package/dist/cli/agent-registry/detector.js.map +1 -0
- package/dist/cli/agent-registry/index.d.ts +26 -0
- package/dist/cli/agent-registry/index.d.ts.map +1 -0
- package/dist/cli/agent-registry/index.js +77 -0
- package/dist/cli/agent-registry/index.js.map +1 -0
- package/dist/cli/agent-registry/path-validator.d.ts +11 -0
- package/dist/cli/agent-registry/path-validator.d.ts.map +1 -0
- package/dist/cli/agent-registry/path-validator.js +69 -0
- package/dist/cli/agent-registry/path-validator.js.map +1 -0
- package/dist/cli/agent-registry/registry.json +108 -0
- package/dist/cli/agent-registry/types.d.ts +29 -0
- package/dist/cli/agent-registry/types.d.ts.map +1 -0
- package/dist/cli/agent-registry/types.js +2 -0
- package/dist/cli/agent-registry/types.js.map +1 -0
- package/dist/cli/bootstrap-lock.d.ts +7 -0
- package/dist/cli/bootstrap-lock.d.ts.map +1 -0
- package/dist/cli/bootstrap-lock.js +62 -0
- package/dist/cli/bootstrap-lock.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +23 -0
- package/dist/cli/bootstrap.d.ts.map +1 -0
- package/dist/cli/bootstrap.js +438 -0
- package/dist/cli/bootstrap.js.map +1 -0
- package/dist/cli/commands/config.d.ts +13 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +244 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/devices.d.ts +21 -0
- package/dist/cli/commands/devices.d.ts.map +1 -0
- package/dist/cli/commands/devices.js +229 -0
- package/dist/cli/commands/devices.js.map +1 -0
- package/dist/cli/commands/export.d.ts +12 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +183 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/import.d.ts +26 -0
- package/dist/cli/commands/import.d.ts.map +1 -0
- package/dist/cli/commands/import.js +311 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/kb.d.ts +39 -0
- package/dist/cli/commands/kb.d.ts.map +1 -0
- package/dist/cli/commands/kb.js +138 -0
- package/dist/cli/commands/kb.js.map +1 -0
- package/dist/cli/commands/project.d.ts +6 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +115 -0
- package/dist/cli/commands/project.js.map +1 -0
- package/dist/cli/commands/projects.d.ts +33 -0
- package/dist/cli/commands/projects.d.ts.map +1 -0
- package/dist/cli/commands/projects.js +189 -0
- package/dist/cli/commands/projects.js.map +1 -0
- package/dist/cli/commands/register.d.ts +8 -0
- package/dist/cli/commands/register.d.ts.map +1 -0
- package/dist/cli/commands/register.js +146 -0
- package/dist/cli/commands/register.js.map +1 -0
- package/dist/cli/commands/rotate-key.d.ts +16 -0
- package/dist/cli/commands/rotate-key.d.ts.map +1 -0
- package/dist/cli/commands/rotate-key.js +197 -0
- package/dist/cli/commands/rotate-key.js.map +1 -0
- package/dist/cli/commands/setup-sync.d.ts +2 -0
- package/dist/cli/commands/setup-sync.d.ts.map +1 -0
- package/dist/cli/commands/setup-sync.js +165 -0
- package/dist/cli/commands/setup-sync.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +12 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +39 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/status.d.ts +5 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +96 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/uninstall.d.ts +4 -0
- package/dist/cli/commands/uninstall.d.ts.map +1 -0
- package/dist/cli/commands/uninstall.js +85 -0
- package/dist/cli/commands/uninstall.js.map +1 -0
- package/dist/cli/commands/unregister.d.ts +2 -0
- package/dist/cli/commands/unregister.d.ts.map +1 -0
- package/dist/cli/commands/unregister.js +46 -0
- package/dist/cli/commands/unregister.js.map +1 -0
- package/dist/cli/device-metadata.d.ts +15 -0
- package/dist/cli/device-metadata.d.ts.map +1 -0
- package/dist/cli/device-metadata.js +58 -0
- package/dist/cli/device-metadata.js.map +1 -0
- package/dist/cli/github.d.ts +38 -0
- package/dist/cli/github.d.ts.map +1 -0
- package/dist/cli/github.js +159 -0
- package/dist/cli/github.js.map +1 -0
- package/dist/cli/guide-hashes.json +13 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +226 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mcp-server.d.ts +205 -0
- package/dist/cli/mcp-server.d.ts.map +1 -0
- package/dist/cli/mcp-server.js +366 -0
- package/dist/cli/mcp-server.js.map +1 -0
- package/dist/cli/tools/kb-delete.d.ts +10 -0
- package/dist/cli/tools/kb-delete.d.ts.map +1 -0
- package/dist/cli/tools/kb-delete.js +28 -0
- package/dist/cli/tools/kb-delete.js.map +1 -0
- package/dist/cli/tools/kb-ingest.d.ts +13 -0
- package/dist/cli/tools/kb-ingest.d.ts.map +1 -0
- package/dist/cli/tools/kb-ingest.js +72 -0
- package/dist/cli/tools/kb-ingest.js.map +1 -0
- package/dist/cli/tools/kb-list.d.ts +20 -0
- package/dist/cli/tools/kb-list.d.ts.map +1 -0
- package/dist/cli/tools/kb-list.js +24 -0
- package/dist/cli/tools/kb-list.js.map +1 -0
- package/dist/cli/tools/kb-query-shared.d.ts +27 -0
- package/dist/cli/tools/kb-query-shared.d.ts.map +1 -0
- package/dist/cli/tools/kb-query-shared.js +28 -0
- package/dist/cli/tools/kb-query-shared.js.map +1 -0
- package/dist/cli/tools/kb-query.d.ts +20 -0
- package/dist/cli/tools/kb-query.d.ts.map +1 -0
- package/dist/cli/tools/kb-query.js +109 -0
- package/dist/cli/tools/kb-query.js.map +1 -0
- package/dist/cli/tools/kb-summary.d.ts +29 -0
- package/dist/cli/tools/kb-summary.d.ts.map +1 -0
- package/dist/cli/tools/kb-summary.js +89 -0
- package/dist/cli/tools/kb-summary.js.map +1 -0
- package/dist/cli/tools/kb-sync-status.d.ts +7 -0
- package/dist/cli/tools/kb-sync-status.d.ts.map +1 -0
- package/dist/cli/tools/kb-sync-status.js +48 -0
- package/dist/cli/tools/kb-sync-status.js.map +1 -0
- package/dist/crypto/aad.d.ts +8 -0
- package/dist/crypto/aad.d.ts.map +1 -0
- package/dist/crypto/aad.js +11 -0
- package/dist/crypto/aad.js.map +1 -0
- package/dist/crypto/aead.d.ts +21 -0
- package/dist/crypto/aead.d.ts.map +1 -0
- package/dist/crypto/aead.js +43 -0
- package/dist/crypto/aead.js.map +1 -0
- package/dist/crypto/argon2.d.ts +11 -0
- package/dist/crypto/argon2.d.ts.map +1 -0
- package/dist/crypto/argon2.js +33 -0
- package/dist/crypto/argon2.js.map +1 -0
- package/dist/crypto/blob-id.d.ts +6 -0
- package/dist/crypto/blob-id.d.ts.map +1 -0
- package/dist/crypto/blob-id.js +33 -0
- package/dist/crypto/blob-id.js.map +1 -0
- package/dist/crypto/canonical-json.d.ts +6 -0
- package/dist/crypto/canonical-json.d.ts.map +1 -0
- package/dist/crypto/canonical-json.js +88 -0
- package/dist/crypto/canonical-json.js.map +1 -0
- package/dist/crypto/commitment.d.ts +12 -0
- package/dist/crypto/commitment.d.ts.map +1 -0
- package/dist/crypto/commitment.js +37 -0
- package/dist/crypto/commitment.js.map +1 -0
- package/dist/crypto/encryption-service.d.ts +19 -0
- package/dist/crypto/encryption-service.d.ts.map +1 -0
- package/dist/crypto/encryption-service.js +38 -0
- package/dist/crypto/encryption-service.js.map +1 -0
- package/dist/crypto/envelope-cbor.d.ts +37 -0
- package/dist/crypto/envelope-cbor.d.ts.map +1 -0
- package/dist/crypto/envelope-cbor.js +124 -0
- package/dist/crypto/envelope-cbor.js.map +1 -0
- package/dist/crypto/envelope.d.ts +34 -0
- package/dist/crypto/envelope.d.ts.map +1 -0
- package/dist/crypto/envelope.js +160 -0
- package/dist/crypto/envelope.js.map +1 -0
- package/dist/crypto/hkdf.d.ts +16 -0
- package/dist/crypto/hkdf.d.ts.map +1 -0
- package/dist/crypto/hkdf.js +33 -0
- package/dist/crypto/hkdf.js.map +1 -0
- package/dist/crypto/index.d.ts +15 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +15 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/invite.d.ts +31 -0
- package/dist/crypto/invite.d.ts.map +1 -0
- package/dist/crypto/invite.js +137 -0
- package/dist/crypto/invite.js.map +1 -0
- package/dist/crypto/keyring.d.ts +37 -0
- package/dist/crypto/keyring.d.ts.map +1 -0
- package/dist/crypto/keyring.js +219 -0
- package/dist/crypto/keyring.js.map +1 -0
- package/dist/crypto/known-keys.d.ts +34 -0
- package/dist/crypto/known-keys.d.ts.map +1 -0
- package/dist/crypto/known-keys.js +106 -0
- package/dist/crypto/known-keys.js.map +1 -0
- package/dist/crypto/project-keys.d.ts +26 -0
- package/dist/crypto/project-keys.d.ts.map +1 -0
- package/dist/crypto/project-keys.js +69 -0
- package/dist/crypto/project-keys.js.map +1 -0
- package/dist/crypto/secure-buffer.d.ts +31 -0
- package/dist/crypto/secure-buffer.d.ts.map +1 -0
- package/dist/crypto/secure-buffer.js +61 -0
- package/dist/crypto/secure-buffer.js.map +1 -0
- package/dist/crypto/ssh-agent.d.ts +16 -0
- package/dist/crypto/ssh-agent.d.ts.map +1 -0
- package/dist/crypto/ssh-agent.js +225 -0
- package/dist/crypto/ssh-agent.js.map +1 -0
- package/dist/crypto/ssh-keys.d.ts +19 -0
- package/dist/crypto/ssh-keys.d.ts.map +1 -0
- package/dist/crypto/ssh-keys.js +121 -0
- package/dist/crypto/ssh-keys.js.map +1 -0
- package/dist/crypto/tiers/enhanced.d.ts +25 -0
- package/dist/crypto/tiers/enhanced.d.ts.map +1 -0
- package/dist/crypto/tiers/enhanced.js +56 -0
- package/dist/crypto/tiers/enhanced.js.map +1 -0
- package/dist/crypto/tiers/maximum.d.ts +19 -0
- package/dist/crypto/tiers/maximum.d.ts.map +1 -0
- package/dist/crypto/tiers/maximum.js +25 -0
- package/dist/crypto/tiers/maximum.js.map +1 -0
- package/dist/crypto/tiers/standard.d.ts +27 -0
- package/dist/crypto/tiers/standard.d.ts.map +1 -0
- package/dist/crypto/tiers/standard.js +147 -0
- package/dist/crypto/tiers/standard.js.map +1 -0
- package/dist/crypto/types.d.ts +169 -0
- package/dist/crypto/types.d.ts.map +1 -0
- package/dist/crypto/types.js +11 -0
- package/dist/crypto/types.js.map +1 -0
- package/dist/pipeline/chunker.d.ts +27 -0
- package/dist/pipeline/chunker.d.ts.map +1 -0
- package/dist/pipeline/chunker.js +96 -0
- package/dist/pipeline/chunker.js.map +1 -0
- package/dist/pipeline/content-pipeline.d.ts +24 -0
- package/dist/pipeline/content-pipeline.d.ts.map +1 -0
- package/dist/pipeline/content-pipeline.js +49 -0
- package/dist/pipeline/content-pipeline.js.map +1 -0
- package/dist/pipeline/embedder.d.ts +49 -0
- package/dist/pipeline/embedder.d.ts.map +1 -0
- package/dist/pipeline/embedder.js +195 -0
- package/dist/pipeline/embedder.js.map +1 -0
- package/dist/pipeline/extract.d.ts +17 -0
- package/dist/pipeline/extract.d.ts.map +1 -0
- package/dist/pipeline/extract.js +70 -0
- package/dist/pipeline/extract.js.map +1 -0
- package/dist/pipeline/fetch.d.ts +26 -0
- package/dist/pipeline/fetch.d.ts.map +1 -0
- package/dist/pipeline/fetch.js +91 -0
- package/dist/pipeline/fetch.js.map +1 -0
- package/dist/pipeline/index.d.ts +10 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +10 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/model-manager.d.ts +57 -0
- package/dist/pipeline/model-manager.d.ts.map +1 -0
- package/dist/pipeline/model-manager.js +234 -0
- package/dist/pipeline/model-manager.js.map +1 -0
- package/dist/pipeline/search.d.ts +37 -0
- package/dist/pipeline/search.d.ts.map +1 -0
- package/dist/pipeline/search.js +65 -0
- package/dist/pipeline/search.js.map +1 -0
- package/dist/pipeline/tokenizer.d.ts +29 -0
- package/dist/pipeline/tokenizer.d.ts.map +1 -0
- package/dist/pipeline/tokenizer.js +54 -0
- package/dist/pipeline/tokenizer.js.map +1 -0
- package/dist/pipeline/types.d.ts +86 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +2 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/pipeline/wordpiece-tokenizer.d.ts +60 -0
- package/dist/pipeline/wordpiece-tokenizer.d.ts.map +1 -0
- package/dist/pipeline/wordpiece-tokenizer.js +251 -0
- package/dist/pipeline/wordpiece-tokenizer.js.map +1 -0
- package/dist/storage/chunk-repo.d.ts +29 -0
- package/dist/storage/chunk-repo.d.ts.map +1 -0
- package/dist/storage/chunk-repo.js +115 -0
- package/dist/storage/chunk-repo.js.map +1 -0
- package/dist/storage/database-manager.d.ts +17 -0
- package/dist/storage/database-manager.d.ts.map +1 -0
- package/dist/storage/database-manager.js +100 -0
- package/dist/storage/database-manager.js.map +1 -0
- package/dist/storage/database.d.ts +10 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +34 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/embedding-index.d.ts +22 -0
- package/dist/storage/embedding-index.d.ts.map +1 -0
- package/dist/storage/embedding-index.js +78 -0
- package/dist/storage/embedding-index.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +10 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/kb-database.d.ts +11 -0
- package/dist/storage/kb-database.d.ts.map +1 -0
- package/dist/storage/kb-database.js +24 -0
- package/dist/storage/kb-database.js.map +1 -0
- package/dist/storage/schema.d.ts +6 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +122 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/storage/source-repo.d.ts +20 -0
- package/dist/storage/source-repo.d.ts.map +1 -0
- package/dist/storage/source-repo.js +120 -0
- package/dist/storage/source-repo.js.map +1 -0
- package/dist/storage/sync-status-repo.d.ts +15 -0
- package/dist/storage/sync-status-repo.d.ts.map +1 -0
- package/dist/storage/sync-status-repo.js +40 -0
- package/dist/storage/sync-status-repo.js.map +1 -0
- package/dist/storage/types.d.ts +139 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +9 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/sync/canary.d.ts +14 -0
- package/dist/sync/canary.d.ts.map +1 -0
- package/dist/sync/canary.js +53 -0
- package/dist/sync/canary.js.map +1 -0
- package/dist/sync/full-sync.d.ts +16 -0
- package/dist/sync/full-sync.d.ts.map +1 -0
- package/dist/sync/full-sync.js +91 -0
- package/dist/sync/full-sync.js.map +1 -0
- package/dist/sync/http-client.d.ts +28 -0
- package/dist/sync/http-client.d.ts.map +1 -0
- package/dist/sync/http-client.js +90 -0
- package/dist/sync/http-client.js.map +1 -0
- package/dist/sync/incremental-sync.d.ts +17 -0
- package/dist/sync/incremental-sync.d.ts.map +1 -0
- package/dist/sync/incremental-sync.js +155 -0
- package/dist/sync/incremental-sync.js.map +1 -0
- package/dist/sync/index.d.ts +12 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +12 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/quota.d.ts +17 -0
- package/dist/sync/quota.d.ts.map +1 -0
- package/dist/sync/quota.js +48 -0
- package/dist/sync/quota.js.map +1 -0
- package/dist/sync/sequence.d.ts +21 -0
- package/dist/sync/sequence.d.ts.map +1 -0
- package/dist/sync/sequence.js +49 -0
- package/dist/sync/sequence.js.map +1 -0
- package/dist/sync/ssh-signer.d.ts +59 -0
- package/dist/sync/ssh-signer.d.ts.map +1 -0
- package/dist/sync/ssh-signer.js +241 -0
- package/dist/sync/ssh-signer.js.map +1 -0
- package/dist/sync/sync-service.d.ts +48 -0
- package/dist/sync/sync-service.d.ts.map +1 -0
- package/dist/sync/sync-service.js +116 -0
- package/dist/sync/sync-service.js.map +1 -0
- package/dist/sync/types.d.ts +106 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/sync/types.js +2 -0
- package/dist/sync/types.js.map +1 -0
- package/dist/sync/upload-queue.d.ts +40 -0
- package/dist/sync/upload-queue.d.ts.map +1 -0
- package/dist/sync/upload-queue.js +148 -0
- package/dist/sync/upload-queue.js.map +1 -0
- package/dist/sync/verification.d.ts +17 -0
- package/dist/sync/verification.d.ts.map +1 -0
- package/dist/sync/verification.js +25 -0
- package/dist/sync/verification.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +16 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { McpDependencies } from '../mcp-server.js';
|
|
2
|
+
export interface KbQueryInput {
|
|
3
|
+
query: string;
|
|
4
|
+
limit?: number;
|
|
5
|
+
mode?: 'semantic' | 'keyword' | 'hybrid';
|
|
6
|
+
}
|
|
7
|
+
export interface KbQueryResultItem {
|
|
8
|
+
sourceId: string;
|
|
9
|
+
title: string;
|
|
10
|
+
url: string;
|
|
11
|
+
content: string;
|
|
12
|
+
score: number;
|
|
13
|
+
chunkIndex: number;
|
|
14
|
+
}
|
|
15
|
+
export interface KbQueryResult {
|
|
16
|
+
results: KbQueryResultItem[];
|
|
17
|
+
mode: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function handleKbQuery(input: KbQueryInput, deps: McpDependencies): Promise<KbQueryResult>;
|
|
20
|
+
//# sourceMappingURL=kb-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-query.d.ts","sourceRoot":"","sources":["../../../cli/tools/kb-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;CAC1C;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,aAAa,CAAC,CAcxB"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export async function handleKbQuery(input, deps) {
|
|
2
|
+
const limit = input.limit ?? 10;
|
|
3
|
+
const mode = input.mode ?? 'semantic';
|
|
4
|
+
if (mode === 'keyword') {
|
|
5
|
+
return keywordSearch(input.query, limit, deps);
|
|
6
|
+
}
|
|
7
|
+
if (mode === 'hybrid') {
|
|
8
|
+
return hybridSearch(input.query, limit, deps);
|
|
9
|
+
}
|
|
10
|
+
// Default: semantic search
|
|
11
|
+
return semanticSearch(input.query, limit, deps);
|
|
12
|
+
}
|
|
13
|
+
async function semanticSearch(query, limit, deps) {
|
|
14
|
+
const { db, pipeline } = deps;
|
|
15
|
+
// 1. Embed the query using the pipeline embedder
|
|
16
|
+
const queryEmbedding = await pipeline.embed(query);
|
|
17
|
+
// 2. Search the embedding index for top-K matches
|
|
18
|
+
const matches = db.embeddingIndex.search(queryEmbedding, limit);
|
|
19
|
+
// 3. For each match, load the chunk content and source metadata
|
|
20
|
+
const results = [];
|
|
21
|
+
for (const match of matches) {
|
|
22
|
+
const source = db.sources.getById(match.sourceId);
|
|
23
|
+
if (!source || source.deletedAt)
|
|
24
|
+
continue;
|
|
25
|
+
const chunks = db.chunks.getBySourceId(match.sourceId);
|
|
26
|
+
const chunk = chunks.find((c) => c.chunkIndex === match.chunkIndex);
|
|
27
|
+
if (!chunk)
|
|
28
|
+
continue;
|
|
29
|
+
// Update last accessed timestamp
|
|
30
|
+
db.sources.updateLastAccessed(match.sourceId);
|
|
31
|
+
results.push({
|
|
32
|
+
sourceId: match.sourceId,
|
|
33
|
+
title: source.title,
|
|
34
|
+
url: source.url,
|
|
35
|
+
content: chunk.content,
|
|
36
|
+
score: match.score,
|
|
37
|
+
chunkIndex: match.chunkIndex,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return { results, mode: 'semantic' };
|
|
41
|
+
}
|
|
42
|
+
async function keywordSearch(query, limit, deps) {
|
|
43
|
+
const { db } = deps;
|
|
44
|
+
const matches = db.chunks.searchKeyword(query, limit);
|
|
45
|
+
const results = [];
|
|
46
|
+
for (const match of matches) {
|
|
47
|
+
const source = db.sources.getById(match.sourceId);
|
|
48
|
+
if (!source || source.deletedAt)
|
|
49
|
+
continue;
|
|
50
|
+
db.sources.updateLastAccessed(match.sourceId);
|
|
51
|
+
results.push({
|
|
52
|
+
sourceId: match.sourceId,
|
|
53
|
+
title: source.title,
|
|
54
|
+
url: source.url,
|
|
55
|
+
content: match.snippet,
|
|
56
|
+
score: -match.rank, // FTS5 rank is negative (lower = better), flip for consistency
|
|
57
|
+
chunkIndex: match.chunkIndex,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return { results, mode: 'keyword' };
|
|
61
|
+
}
|
|
62
|
+
async function hybridSearch(query, limit, deps) {
|
|
63
|
+
// Run both searches with 2x limit to ensure we have enough after deduplication
|
|
64
|
+
const [semanticResults, keywordResults] = await Promise.all([
|
|
65
|
+
semanticSearch(query, limit * 2, deps),
|
|
66
|
+
keywordSearch(query, limit * 2, deps),
|
|
67
|
+
]);
|
|
68
|
+
// Normalize scores to [0, 1] range for merging
|
|
69
|
+
const semanticMax = Math.max(...semanticResults.results.map((r) => r.score), 0.001);
|
|
70
|
+
const keywordMax = Math.max(...keywordResults.results.map((r) => r.score), 0.001);
|
|
71
|
+
// Build combined score map: key = sourceId:chunkIndex
|
|
72
|
+
const combined = new Map();
|
|
73
|
+
const SEMANTIC_WEIGHT = 0.7;
|
|
74
|
+
const KEYWORD_WEIGHT = 0.3;
|
|
75
|
+
for (const r of semanticResults.results) {
|
|
76
|
+
const key = `${r.sourceId}:${r.chunkIndex}`;
|
|
77
|
+
const normScore = r.score / semanticMax;
|
|
78
|
+
combined.set(key, {
|
|
79
|
+
...r,
|
|
80
|
+
combinedScore: normScore * SEMANTIC_WEIGHT,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
for (const r of keywordResults.results) {
|
|
84
|
+
const key = `${r.sourceId}:${r.chunkIndex}`;
|
|
85
|
+
const normScore = r.score / keywordMax;
|
|
86
|
+
const existing = combined.get(key);
|
|
87
|
+
if (existing) {
|
|
88
|
+
// Boost: this chunk appeared in both searches
|
|
89
|
+
existing.combinedScore += normScore * KEYWORD_WEIGHT;
|
|
90
|
+
// Prefer semantic content over keyword snippet
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
combined.set(key, {
|
|
94
|
+
...r,
|
|
95
|
+
combinedScore: normScore * KEYWORD_WEIGHT,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Sort by combined score and take top-K
|
|
100
|
+
const sorted = [...combined.values()]
|
|
101
|
+
.sort((a, b) => b.combinedScore - a.combinedScore)
|
|
102
|
+
.slice(0, limit);
|
|
103
|
+
const results = sorted.map(({ combinedScore, ...rest }) => ({
|
|
104
|
+
...rest,
|
|
105
|
+
score: combinedScore,
|
|
106
|
+
}));
|
|
107
|
+
return { results, mode: 'hybrid' };
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=kb-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-query.js","sourceRoot":"","sources":["../../../cli/tools/kb-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { McpDependencies } from '../mcp-server.js';
|
|
2
|
+
export interface KbSummaryInput {
|
|
3
|
+
period: 'week' | 'month' | 'year' | string;
|
|
4
|
+
}
|
|
5
|
+
export interface KbSummaryArticle {
|
|
6
|
+
title: string;
|
|
7
|
+
url: string;
|
|
8
|
+
date: string;
|
|
9
|
+
chunkCount: number;
|
|
10
|
+
tags: string[];
|
|
11
|
+
preview: string;
|
|
12
|
+
}
|
|
13
|
+
export interface KbSummaryResult {
|
|
14
|
+
period: string;
|
|
15
|
+
totalArticles: number;
|
|
16
|
+
totalChunks: number;
|
|
17
|
+
articles: KbSummaryArticle[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Calculate the date range from a period specification.
|
|
21
|
+
* @returns [startDate, endDate] as ISO date strings (YYYY-MM-DD)
|
|
22
|
+
*/
|
|
23
|
+
export declare function calculateDateRange(period: string): {
|
|
24
|
+
start: string;
|
|
25
|
+
end: string;
|
|
26
|
+
label: string;
|
|
27
|
+
};
|
|
28
|
+
export declare function handleKbSummary(input: KbSummaryInput, deps: McpDependencies): Promise<KbSummaryResult>;
|
|
29
|
+
//# sourceMappingURL=kb-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-summary.d.ts","sourceRoot":"","sources":["../../../cli/tools/kb-summary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CAC5C;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAkDhG;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,eAAe,CAAC,CAgD1B"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate the date range from a period specification.
|
|
3
|
+
* @returns [startDate, endDate] as ISO date strings (YYYY-MM-DD)
|
|
4
|
+
*/
|
|
5
|
+
export function calculateDateRange(period) {
|
|
6
|
+
const now = new Date();
|
|
7
|
+
const endDate = now.toISOString().split('T')[0];
|
|
8
|
+
switch (period) {
|
|
9
|
+
case 'week': {
|
|
10
|
+
const start = new Date(now);
|
|
11
|
+
start.setDate(start.getDate() - 7);
|
|
12
|
+
return {
|
|
13
|
+
start: start.toISOString().split('T')[0],
|
|
14
|
+
end: endDate,
|
|
15
|
+
label: `${start.toISOString().split('T')[0]} to ${endDate}`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
case 'month': {
|
|
19
|
+
const start = new Date(now);
|
|
20
|
+
start.setMonth(start.getMonth() - 1);
|
|
21
|
+
return {
|
|
22
|
+
start: start.toISOString().split('T')[0],
|
|
23
|
+
end: endDate,
|
|
24
|
+
label: `${start.toISOString().split('T')[0]} to ${endDate}`,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
case 'year': {
|
|
28
|
+
const start = new Date(now);
|
|
29
|
+
start.setFullYear(start.getFullYear() - 1);
|
|
30
|
+
return {
|
|
31
|
+
start: start.toISOString().split('T')[0],
|
|
32
|
+
end: endDate,
|
|
33
|
+
label: `${start.toISOString().split('T')[0]} to ${endDate}`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
default: {
|
|
37
|
+
// Custom range: "YYYY-MM-DD:YYYY-MM-DD"
|
|
38
|
+
const parts = period.split(':');
|
|
39
|
+
if (parts.length !== 2) {
|
|
40
|
+
throw new Error(`Invalid period format: "${period}". Use "week", "month", "year", or "YYYY-MM-DD:YYYY-MM-DD".`);
|
|
41
|
+
}
|
|
42
|
+
const [start, end] = parts;
|
|
43
|
+
// Validate date format
|
|
44
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(start) || !/^\d{4}-\d{2}-\d{2}$/.test(end)) {
|
|
45
|
+
throw new Error(`Invalid date format in period: "${period}". Use "YYYY-MM-DD:YYYY-MM-DD".`);
|
|
46
|
+
}
|
|
47
|
+
return { start, end, label: `${start} to ${end}` };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export async function handleKbSummary(input, deps) {
|
|
52
|
+
const { db } = deps;
|
|
53
|
+
const range = calculateDateRange(input.period);
|
|
54
|
+
// Query sources within the date range
|
|
55
|
+
const sources = db.sources.list({
|
|
56
|
+
since: range.start,
|
|
57
|
+
includeDeleted: false,
|
|
58
|
+
}, { limit: 1000, offset: 0 });
|
|
59
|
+
// Filter by end date and collect results
|
|
60
|
+
const endDateObj = new Date(range.end + 'T23:59:59.999Z');
|
|
61
|
+
const filteredSources = sources.filter((s) => {
|
|
62
|
+
const createdAt = new Date(s.createdAt);
|
|
63
|
+
return createdAt <= endDateObj;
|
|
64
|
+
});
|
|
65
|
+
let totalChunks = 0;
|
|
66
|
+
const articles = [];
|
|
67
|
+
for (const source of filteredSources) {
|
|
68
|
+
totalChunks += source.chunkCount;
|
|
69
|
+
// Get first chunk as preview
|
|
70
|
+
const chunks = db.chunks.getBySourceId(source.id);
|
|
71
|
+
const firstChunk = chunks.find((c) => c.chunkIndex === 0);
|
|
72
|
+
const preview = firstChunk?.content ?? '';
|
|
73
|
+
articles.push({
|
|
74
|
+
title: source.title,
|
|
75
|
+
url: source.url,
|
|
76
|
+
date: source.createdAt,
|
|
77
|
+
chunkCount: source.chunkCount,
|
|
78
|
+
tags: source.tags,
|
|
79
|
+
preview,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
period: range.label,
|
|
84
|
+
totalArticles: filteredSources.length,
|
|
85
|
+
totalChunks,
|
|
86
|
+
articles,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=kb-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-summary.js","sourceRoot":"","sources":["../../../cli/tools/kb-summary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-sync-status.d.ts","sourceRoot":"","sources":["../../../cli/tools/kb-sync-status.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CA6CpD"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { CHAOSKB_DIR } from '../bootstrap.js';
|
|
4
|
+
/**
|
|
5
|
+
* MCP tool: kb_sync_status
|
|
6
|
+
*
|
|
7
|
+
* Returns the current sync status, key type, and device configuration.
|
|
8
|
+
*/
|
|
9
|
+
export async function kbSyncStatus() {
|
|
10
|
+
const configPath = path.join(CHAOSKB_DIR, 'config.json');
|
|
11
|
+
if (!fs.existsSync(configPath)) {
|
|
12
|
+
return JSON.stringify({
|
|
13
|
+
status: 'not_configured',
|
|
14
|
+
message: 'ChaosKB is not configured. Run any KB tool to auto-bootstrap.',
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
18
|
+
const result = {
|
|
19
|
+
status: config.syncEnabled ? 'active' : config.syncPending ? 'pending' : 'disabled',
|
|
20
|
+
securityTier: config.securityTier,
|
|
21
|
+
syncEnabled: config.syncEnabled ?? false,
|
|
22
|
+
};
|
|
23
|
+
if (config.endpoint) {
|
|
24
|
+
result.endpoint = config.endpoint;
|
|
25
|
+
}
|
|
26
|
+
if (config.sshKeyFingerprint) {
|
|
27
|
+
result.sshKeyFingerprint = config.sshKeyFingerprint;
|
|
28
|
+
result.keySource = config.sshKeyPath ? 'file' : 'agent_or_generated';
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
result.keySource = 'none';
|
|
32
|
+
result.message = 'No SSH key configured. Multi-device sync requires an SSH key. Run: ssh-keygen -t ed25519';
|
|
33
|
+
}
|
|
34
|
+
if (config.syncPending) {
|
|
35
|
+
result.message = 'Sync server was unreachable. Will retry on next launch.';
|
|
36
|
+
}
|
|
37
|
+
// Check if an SSH key has appeared since bootstrap (nudge)
|
|
38
|
+
if (!config.sshKeyPath && !config.sshKeyFingerprint) {
|
|
39
|
+
const sshDir = path.join(process.env.HOME ?? '', '.ssh');
|
|
40
|
+
const hasSSHKey = fs.existsSync(path.join(sshDir, 'id_ed25519.pub')) ||
|
|
41
|
+
fs.existsSync(path.join(sshDir, 'id_rsa.pub'));
|
|
42
|
+
if (hasSSHKey) {
|
|
43
|
+
result.nudge = 'SSH key detected on this system. Switch to it for multi-device sync: chaoskb-mcp config rotate-key';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return JSON.stringify(result, null, 2);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=kb-sync-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-sync-status.js","sourceRoot":"","sources":["../../../cli/tools/kb-sync-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAEzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,MAAM,EAAE,gBAAgB;YACxB,OAAO,EAAE,+DAA+D;SACzE,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAkB,CAAC;IAEjF,MAAM,MAAM,GAA4B;QACtC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;QACnF,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,KAAK;KACzC,CAAC;IAEF,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC7B,MAAM,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC;QACpD,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC;IACvE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC;QAC1B,MAAM,CAAC,OAAO,GAAG,0FAA0F,CAAC;IAC9G,CAAC;IAED,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,CAAC,OAAO,GAAG,yDAAyD,CAAC;IAC7E,CAAC;IAED,2DAA2D;IAC3D,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;YAClD,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;QACjE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,KAAK,GAAG,oGAAoG,CAAC;QACtH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Algorithm, KeyId } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Construct AAD (Associated Authenticated Data) for AEAD encryption.
|
|
4
|
+
* Per the envelope spec: AAD = UTF-8 bytes of canonicalJson({alg, id, kid, v})
|
|
5
|
+
* Keys are sorted alphabetically by RFC 8785.
|
|
6
|
+
*/
|
|
7
|
+
export declare function constructAAD(alg: Algorithm, id: string, kid: KeyId, v: number): Uint8Array;
|
|
8
|
+
//# sourceMappingURL=aad.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aad.d.ts","sourceRoot":"","sources":["../../crypto/aad.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAG1F"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { canonicalJson } from './canonical-json.js';
|
|
2
|
+
/**
|
|
3
|
+
* Construct AAD (Associated Authenticated Data) for AEAD encryption.
|
|
4
|
+
* Per the envelope spec: AAD = UTF-8 bytes of canonicalJson({alg, id, kid, v})
|
|
5
|
+
* Keys are sorted alphabetically by RFC 8785.
|
|
6
|
+
*/
|
|
7
|
+
export function constructAAD(alg, id, kid, v) {
|
|
8
|
+
const json = canonicalJson({ alg, id, kid, v });
|
|
9
|
+
return new TextEncoder().encode(json);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=aad.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aad.js","sourceRoot":"","sources":["../../crypto/aad.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,GAAc,EAAE,EAAU,EAAE,GAAU,EAAE,CAAS;IAC5E,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface AeadResult {
|
|
2
|
+
nonce: Uint8Array;
|
|
3
|
+
ciphertext: Uint8Array;
|
|
4
|
+
tag: Uint8Array;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Encrypt using XChaCha20-Poly1305.
|
|
8
|
+
* Generates a random 24-byte nonce.
|
|
9
|
+
* Returns separate nonce, ciphertext, and authentication tag.
|
|
10
|
+
*/
|
|
11
|
+
export declare function aeadEncrypt(key: Uint8Array, plaintext: Uint8Array, aad: Uint8Array): AeadResult;
|
|
12
|
+
/**
|
|
13
|
+
* Encrypt with a specified nonce (for testing only).
|
|
14
|
+
*/
|
|
15
|
+
export declare function aeadEncryptWithNonce(key: Uint8Array, nonce: Uint8Array, plaintext: Uint8Array, aad: Uint8Array): AeadResult;
|
|
16
|
+
/**
|
|
17
|
+
* Decrypt using XChaCha20-Poly1305.
|
|
18
|
+
* Throws if authentication fails.
|
|
19
|
+
*/
|
|
20
|
+
export declare function aeadDecrypt(key: Uint8Array, nonce: Uint8Array, ciphertext: Uint8Array, tag: Uint8Array, aad: Uint8Array): Uint8Array;
|
|
21
|
+
//# sourceMappingURL=aead.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aead.d.ts","sourceRoot":"","sources":["../../crypto/aead.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,UAAU,EAAE,UAAU,CAAC;IACvB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,UAAU,EACrB,GAAG,EAAE,UAAU,GACd,UAAU,CAGZ;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,UAAU,EACrB,GAAG,EAAE,UAAU,GACd,UAAU,CAaZ;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,GACd,UAAU,CAYZ"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { xchacha20poly1305 } from '@noble/ciphers/chacha.js';
|
|
3
|
+
const NONCE_LENGTH = 24;
|
|
4
|
+
const TAG_LENGTH = 16;
|
|
5
|
+
/**
|
|
6
|
+
* Encrypt using XChaCha20-Poly1305.
|
|
7
|
+
* Generates a random 24-byte nonce.
|
|
8
|
+
* Returns separate nonce, ciphertext, and authentication tag.
|
|
9
|
+
*/
|
|
10
|
+
export function aeadEncrypt(key, plaintext, aad) {
|
|
11
|
+
const nonce = new Uint8Array(randomBytes(NONCE_LENGTH));
|
|
12
|
+
return aeadEncryptWithNonce(key, nonce, plaintext, aad);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Encrypt with a specified nonce (for testing only).
|
|
16
|
+
*/
|
|
17
|
+
export function aeadEncryptWithNonce(key, nonce, plaintext, aad) {
|
|
18
|
+
if (nonce.length !== NONCE_LENGTH) {
|
|
19
|
+
throw new Error(`Nonce must be ${NONCE_LENGTH} bytes, got ${nonce.length}`);
|
|
20
|
+
}
|
|
21
|
+
const cipher = xchacha20poly1305(key, nonce, aad);
|
|
22
|
+
const sealed = cipher.encrypt(plaintext);
|
|
23
|
+
// noble/ciphers returns ciphertext || tag concatenated
|
|
24
|
+
const ciphertext = sealed.slice(0, sealed.length - TAG_LENGTH);
|
|
25
|
+
const tag = sealed.slice(sealed.length - TAG_LENGTH);
|
|
26
|
+
return { nonce, ciphertext, tag };
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Decrypt using XChaCha20-Poly1305.
|
|
30
|
+
* Throws if authentication fails.
|
|
31
|
+
*/
|
|
32
|
+
export function aeadDecrypt(key, nonce, ciphertext, tag, aad) {
|
|
33
|
+
if (nonce.length !== NONCE_LENGTH) {
|
|
34
|
+
throw new Error(`Nonce must be ${NONCE_LENGTH} bytes, got ${nonce.length}`);
|
|
35
|
+
}
|
|
36
|
+
// noble/ciphers expects ciphertext || tag concatenated
|
|
37
|
+
const sealed = new Uint8Array(ciphertext.length + tag.length);
|
|
38
|
+
sealed.set(ciphertext, 0);
|
|
39
|
+
sealed.set(tag, ciphertext.length);
|
|
40
|
+
const cipher = xchacha20poly1305(key, nonce, aad);
|
|
41
|
+
return cipher.decrypt(sealed);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=aead.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aead.js","sourceRoot":"","sources":["../../crypto/aead.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,UAAU,GAAG,EAAE,CAAC;AAQtB;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,GAAe,EACf,SAAqB,EACrB,GAAe;IAEf,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;IACxD,OAAO,oBAAoB,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAe,EACf,KAAiB,EACjB,SAAqB,EACrB,GAAe;IAEf,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,iBAAiB,YAAY,eAAe,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEzC,uDAAuD;IACvD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IAErD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;AACpC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,GAAe,EACf,KAAiB,EACjB,UAAsB,EACtB,GAAe,EACf,GAAe;IAEf,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,iBAAiB,YAAY,eAAe,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,uDAAuD;IACvD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9D,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC1B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAEnC,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ISecureBuffer } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Derive a master key from a passphrase using Argon2id.
|
|
4
|
+
* The passphrase is held in a SecureBuffer and zeroed after derivation.
|
|
5
|
+
*
|
|
6
|
+
* @param passphrase - User passphrase
|
|
7
|
+
* @param salt - 16-byte salt (CSPRNG-generated, stored on server)
|
|
8
|
+
* @returns SecureBuffer containing the 32-byte derived key
|
|
9
|
+
*/
|
|
10
|
+
export declare function deriveFromPassphrase(passphrase: string, salt: Uint8Array): ISecureBuffer;
|
|
11
|
+
//# sourceMappingURL=argon2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argon2.d.ts","sourceRoot":"","sources":["../../crypto/argon2.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAQhD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,aAAa,CAiBxF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { argon2id } from '@noble/hashes/argon2.js';
|
|
2
|
+
import { SecureBuffer } from './secure-buffer.js';
|
|
3
|
+
// Argon2id parameters per spec: t=3, m=65536 (64MB), p=1, output 32 bytes
|
|
4
|
+
const ARGON2_TIME_COST = 3;
|
|
5
|
+
const ARGON2_MEMORY_COST = 65536; // in KiB = 64 MB
|
|
6
|
+
const ARGON2_PARALLELISM = 1;
|
|
7
|
+
const ARGON2_OUTPUT_LENGTH = 32;
|
|
8
|
+
/**
|
|
9
|
+
* Derive a master key from a passphrase using Argon2id.
|
|
10
|
+
* The passphrase is held in a SecureBuffer and zeroed after derivation.
|
|
11
|
+
*
|
|
12
|
+
* @param passphrase - User passphrase
|
|
13
|
+
* @param salt - 16-byte salt (CSPRNG-generated, stored on server)
|
|
14
|
+
* @returns SecureBuffer containing the 32-byte derived key
|
|
15
|
+
*/
|
|
16
|
+
export function deriveFromPassphrase(passphrase, salt) {
|
|
17
|
+
// Convert passphrase to bytes and hold in a buffer we can zero
|
|
18
|
+
const passphraseBytes = Buffer.from(passphrase, 'utf-8');
|
|
19
|
+
try {
|
|
20
|
+
const derived = argon2id(passphraseBytes, salt, {
|
|
21
|
+
t: ARGON2_TIME_COST,
|
|
22
|
+
m: ARGON2_MEMORY_COST,
|
|
23
|
+
p: ARGON2_PARALLELISM,
|
|
24
|
+
dkLen: ARGON2_OUTPUT_LENGTH,
|
|
25
|
+
});
|
|
26
|
+
return SecureBuffer.from(Buffer.from(derived));
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
// Zero passphrase memory immediately
|
|
30
|
+
passphraseBytes.fill(0);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=argon2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argon2.js","sourceRoot":"","sources":["../../crypto/argon2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,0EAA0E;AAC1E,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,kBAAkB,GAAG,KAAK,CAAC,CAAC,iBAAiB;AACnD,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAkB,EAAE,IAAgB;IACvE,+DAA+D;IAC/D,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAEzD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,QAAQ,CAAC,eAAe,EAAE,IAAI,EAAE;YAC9C,CAAC,EAAE,gBAAgB;YACnB,CAAC,EAAE,kBAAkB;YACrB,CAAC,EAAE,kBAAkB;YACrB,KAAK,EAAE,oBAAoB;SAC5B,CAAC,CAAC;QAEH,OAAO,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,CAAC;YAAS,CAAC;QACT,qCAAqC;QACrC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blob-id.d.ts","sourceRoot":"","sources":["../../crypto/blob-id.ts"],"names":[],"mappings":"AA8BA;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAGvC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
const BASE62_ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
3
|
+
/**
|
|
4
|
+
* Encode a byte array as base62.
|
|
5
|
+
* Uses repeated division for exact encoding.
|
|
6
|
+
*/
|
|
7
|
+
function base62Encode(bytes) {
|
|
8
|
+
// Convert bytes to a BigInt
|
|
9
|
+
let num = BigInt(0);
|
|
10
|
+
for (const byte of bytes) {
|
|
11
|
+
num = (num << 8n) | BigInt(byte);
|
|
12
|
+
}
|
|
13
|
+
if (num === 0n) {
|
|
14
|
+
return BASE62_ALPHABET[0];
|
|
15
|
+
}
|
|
16
|
+
const chars = [];
|
|
17
|
+
const base = BigInt(BASE62_ALPHABET.length);
|
|
18
|
+
while (num > 0n) {
|
|
19
|
+
const remainder = Number(num % base);
|
|
20
|
+
chars.unshift(BASE62_ALPHABET[remainder]);
|
|
21
|
+
num = num / base;
|
|
22
|
+
}
|
|
23
|
+
return chars.join('');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Generate a CSPRNG blob ID.
|
|
27
|
+
* Format: b_ + base62-encoded 16 random bytes.
|
|
28
|
+
*/
|
|
29
|
+
export function generateBlobId() {
|
|
30
|
+
const bytes = randomBytes(16);
|
|
31
|
+
return 'b_' + base62Encode(bytes);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=blob-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blob-id.js","sourceRoot":"","sources":["../../crypto/blob-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,eAAe,GAAG,gEAAgE,CAAC;AAEzF;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAiB;IACrC,4BAA4B;IAC5B,IAAI,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC5C,OAAO,GAAG,GAAG,EAAE,EAAE,CAAC;QAChB,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QACrC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1C,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,OAAO,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-json.d.ts","sourceRoot":"","sources":["../../crypto/canonical-json.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAElE"}
|