@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,62 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
const STALE_THRESHOLD_MS = 30_000;
|
|
5
|
+
const RETRY_INTERVAL_MS = 500;
|
|
6
|
+
const MAX_RETRIES = 60;
|
|
7
|
+
function getChaoskbDir(baseDir) {
|
|
8
|
+
return baseDir ?? path.join(os.homedir(), '.chaoskb');
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Acquire an exclusive file lock for bootstrap.
|
|
12
|
+
* Uses O_CREAT | O_EXCL for atomic creation.
|
|
13
|
+
* Returns a release function.
|
|
14
|
+
*/
|
|
15
|
+
export async function acquireBootstrapLock(baseDir) {
|
|
16
|
+
const chaoskbDir = getChaoskbDir(baseDir);
|
|
17
|
+
const lockPath = path.join(chaoskbDir, '.bootstrap.lock');
|
|
18
|
+
// Ensure the directory exists before trying to create the lock file
|
|
19
|
+
if (!fs.existsSync(chaoskbDir)) {
|
|
20
|
+
fs.mkdirSync(chaoskbDir, { recursive: true, mode: 0o700 });
|
|
21
|
+
}
|
|
22
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
23
|
+
try {
|
|
24
|
+
const fd = fs.openSync(lockPath, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY);
|
|
25
|
+
// Write PID and timestamp for stale lock detection
|
|
26
|
+
fs.writeSync(fd, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
|
|
27
|
+
fs.closeSync(fd);
|
|
28
|
+
return () => {
|
|
29
|
+
try {
|
|
30
|
+
fs.unlinkSync(lockPath);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Lock file may have already been removed
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err.code !== 'EEXIST') {
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
// Lock file exists — check if it's stale
|
|
42
|
+
try {
|
|
43
|
+
const stat = fs.statSync(lockPath);
|
|
44
|
+
const ageMs = Date.now() - stat.mtimeMs;
|
|
45
|
+
if (ageMs > STALE_THRESHOLD_MS) {
|
|
46
|
+
// Stale lock — remove and retry
|
|
47
|
+
fs.unlinkSync(lockPath);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Lock file disappeared between checks — retry
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
// Lock is held and not stale — wait and retry
|
|
56
|
+
await new Promise((resolve) => setTimeout(resolve, RETRY_INTERVAL_MS));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
throw new Error('Timed out waiting for bootstrap lock. If ChaosKB is not running elsewhere, ' +
|
|
60
|
+
`delete ${lockPath} and try again.`);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=bootstrap-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-lock.js","sourceRoot":"","sources":["../../cli/bootstrap-lock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,SAAS,aAAa,CAAC,OAAgB;IACrC,OAAO,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAgB;IACzD,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IAE1D,oEAAoE;IACpE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACrG,mDAAmD;YACnD,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;YAC9E,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YAEjB,OAAO,GAAG,EAAE;gBACV,IAAI,CAAC;oBACH,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;gBAC1B,CAAC;gBAAC,MAAM,CAAC;oBACP,0CAA0C;gBAC5C,CAAC;YACH,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,MAAM,GAAG,CAAC;YACZ,CAAC;YAED,yCAAyC;YACzC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;gBACxC,IAAI,KAAK,GAAG,kBAAkB,EAAE,CAAC;oBAC/B,gCAAgC;oBAChC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;oBACxB,SAAS;gBACX,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,+CAA+C;gBAC/C,SAAS;YACX,CAAC;YAED,8CAA8C;YAC9C,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,6EAA6E;QAC7E,UAAU,QAAQ,iBAAiB,CACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const CHAOSKB_DIR: string;
|
|
2
|
+
export declare const FILE_KEY_PATH: string;
|
|
3
|
+
export interface BootstrapOptions {
|
|
4
|
+
/** Override the base directory (default: ~/.chaoskb). For testing. */
|
|
5
|
+
baseDir?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Auto-bootstrap ChaosKB on first launch.
|
|
9
|
+
*
|
|
10
|
+
* Creates ~/.chaoskb/, generates a master key, stores it in the OS keyring,
|
|
11
|
+
* initializes the database, and writes config.json — all with standard
|
|
12
|
+
* security tier and no interactive prompts.
|
|
13
|
+
*
|
|
14
|
+
* Idempotent: no-ops if config.json already exists.
|
|
15
|
+
* Concurrency-safe: uses file-based locking to prevent races.
|
|
16
|
+
*/
|
|
17
|
+
export declare function bootstrap(options?: BootstrapOptions): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Retry sync registration on subsequent launches when syncPending is true.
|
|
20
|
+
* Called from the MCP server startup path.
|
|
21
|
+
*/
|
|
22
|
+
export declare function retrySyncRegistration(configPath: string): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../cli/bootstrap.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,WAAW,QAAsC,CAAC;AAC/D,eAAO,MAAM,aAAa,QAAuC,CAAC;AAElE,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsGzE;AA8WD;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB7E"}
|
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
import { acquireBootstrapLock } from './bootstrap-lock.js';
|
|
5
|
+
export const CHAOSKB_DIR = path.join(os.homedir(), '.chaoskb');
|
|
6
|
+
export const FILE_KEY_PATH = path.join(CHAOSKB_DIR, 'master.key');
|
|
7
|
+
function resolveDir(baseDir) {
|
|
8
|
+
return baseDir ?? CHAOSKB_DIR;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Auto-bootstrap ChaosKB on first launch.
|
|
12
|
+
*
|
|
13
|
+
* Creates ~/.chaoskb/, generates a master key, stores it in the OS keyring,
|
|
14
|
+
* initializes the database, and writes config.json — all with standard
|
|
15
|
+
* security tier and no interactive prompts.
|
|
16
|
+
*
|
|
17
|
+
* Idempotent: no-ops if config.json already exists.
|
|
18
|
+
* Concurrency-safe: uses file-based locking to prevent races.
|
|
19
|
+
*/
|
|
20
|
+
export async function bootstrap(options) {
|
|
21
|
+
const chaoskbDir = resolveDir(options?.baseDir);
|
|
22
|
+
const configPath = path.join(chaoskbDir, 'config.json');
|
|
23
|
+
const modelsDir = path.join(chaoskbDir, 'models');
|
|
24
|
+
const fileKeyPath = path.join(chaoskbDir, 'master.key');
|
|
25
|
+
// Fast path: already configured
|
|
26
|
+
if (fs.existsSync(configPath)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const releaseLock = await acquireBootstrapLock(chaoskbDir);
|
|
30
|
+
try {
|
|
31
|
+
// Double-check after acquiring lock — another process may have completed bootstrap
|
|
32
|
+
if (fs.existsSync(configPath)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// 1. Create directory structure
|
|
36
|
+
if (!fs.existsSync(chaoskbDir)) {
|
|
37
|
+
fs.mkdirSync(chaoskbDir, { recursive: true, mode: 0o700 });
|
|
38
|
+
}
|
|
39
|
+
fs.chmodSync(chaoskbDir, 0o700);
|
|
40
|
+
if (!fs.existsSync(modelsDir)) {
|
|
41
|
+
fs.mkdirSync(modelsDir, { recursive: true, mode: 0o700 });
|
|
42
|
+
}
|
|
43
|
+
// 2. Generate master key
|
|
44
|
+
const { EncryptionService } = await import('../crypto/encryption-service.js');
|
|
45
|
+
const encryption = new EncryptionService();
|
|
46
|
+
const masterKey = encryption.generateMasterKey();
|
|
47
|
+
// 3. Store master key
|
|
48
|
+
try {
|
|
49
|
+
await storeKeyInKeyring(masterKey);
|
|
50
|
+
}
|
|
51
|
+
catch (keyringError) {
|
|
52
|
+
// Keyring failed — check for file-based fallback
|
|
53
|
+
if (process.env.CHAOSKB_KEY_STORAGE === 'file') {
|
|
54
|
+
process.stderr.write('\n⚠ OS keyring unavailable. Storing key in ' + fileKeyPath + ' (file-based).\n' +
|
|
55
|
+
' This is less secure than the OS keyring. The key file is readable by any process running as your user.\n\n');
|
|
56
|
+
fs.writeFileSync(fileKeyPath, masterKey.buffer.toString('hex'), { mode: 0o600 });
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
masterKey.dispose();
|
|
60
|
+
throw new Error(`Failed to store master key in OS keyring: ${keyringError instanceof Error ? keyringError.message : String(keyringError)}\n\n` +
|
|
61
|
+
' To fix this, either:\n' +
|
|
62
|
+
' • Install/configure your OS keyring service (macOS Keychain, Linux Secret Service, Windows Credential Manager)\n' +
|
|
63
|
+
' • Set CHAOSKB_KEY_STORAGE=file to use file-based key storage (less secure)\n');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Copy master key bytes before disposing (needed for sync registration)
|
|
67
|
+
const masterKeyBytes = Buffer.from(masterKey.buffer);
|
|
68
|
+
masterKey.dispose();
|
|
69
|
+
// 4. Initialize database
|
|
70
|
+
const { DatabaseManager } = await import('../storage/database-manager.js');
|
|
71
|
+
const dbManager = new DatabaseManager(chaoskbDir);
|
|
72
|
+
const db = dbManager.getPersonalDb();
|
|
73
|
+
db.close();
|
|
74
|
+
dbManager.closeAll();
|
|
75
|
+
// 5. Detect SSH key for zero-config sync
|
|
76
|
+
const sshResult = await detectSSHKey();
|
|
77
|
+
// 6. Register with sync server (non-blocking)
|
|
78
|
+
const syncResult = await attemptSyncRegistration(sshResult, masterKeyBytes);
|
|
79
|
+
// Zero the copy
|
|
80
|
+
masterKeyBytes.fill(0);
|
|
81
|
+
// 7. Write config
|
|
82
|
+
const config = {
|
|
83
|
+
securityTier: 'standard',
|
|
84
|
+
projects: [],
|
|
85
|
+
syncEnabled: syncResult.enabled,
|
|
86
|
+
syncPending: syncResult.pending,
|
|
87
|
+
...(syncResult.endpoint && { endpoint: syncResult.endpoint }),
|
|
88
|
+
...(sshResult.fingerprint && { sshKeyFingerprint: sshResult.fingerprint }),
|
|
89
|
+
...(sshResult.keyPath && { sshKeyPath: sshResult.keyPath }),
|
|
90
|
+
};
|
|
91
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
92
|
+
// 8. Log sync status
|
|
93
|
+
if (syncResult.enabled) {
|
|
94
|
+
process.stderr.write('Sync enabled. Your knowledge base will sync automatically.\n');
|
|
95
|
+
}
|
|
96
|
+
else if (syncResult.pending) {
|
|
97
|
+
process.stderr.write('Sync server unreachable. Will retry on next launch.\n');
|
|
98
|
+
}
|
|
99
|
+
else if (!sshResult.publicKey) {
|
|
100
|
+
process.stderr.write('\nNo SSH key found. Using a generated key stored in your OS keyring.\n' +
|
|
101
|
+
'Multi-device sync requires an SSH key — run ssh-keygen to create one,\n' +
|
|
102
|
+
'then: chaoskb-mcp config rotate-key\n\n');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
releaseLock();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Detect the user's SSH key for zero-config sync.
|
|
111
|
+
*
|
|
112
|
+
* Priority: ssh-agent (Ed25519 > RSA) → filesystem (id_ed25519 > id_rsa)
|
|
113
|
+
* If no SSH key found, returns source: 'none'.
|
|
114
|
+
*/
|
|
115
|
+
async function detectSSHKey() {
|
|
116
|
+
// Respect opt-out
|
|
117
|
+
if (process.env.CHAOSKB_SYNC === 'off') {
|
|
118
|
+
return { publicKey: null, fingerprint: null, keyPath: null, source: 'none' };
|
|
119
|
+
}
|
|
120
|
+
// Try ssh-agent first
|
|
121
|
+
if (process.env.SSH_AUTH_SOCK) {
|
|
122
|
+
try {
|
|
123
|
+
const { listSSHAgentKeys } = await import('../crypto/ssh-agent.js');
|
|
124
|
+
const keys = await listSSHAgentKeys();
|
|
125
|
+
// Prefer Ed25519 over RSA
|
|
126
|
+
const ed25519 = keys.find((k) => k.type === 'ed25519');
|
|
127
|
+
const rsa = keys.find((k) => k.type === 'rsa');
|
|
128
|
+
const picked = ed25519 ?? rsa;
|
|
129
|
+
if (picked) {
|
|
130
|
+
return {
|
|
131
|
+
publicKey: `ssh-${picked.type === 'ed25519' ? 'ed25519' : 'rsa'} ${Buffer.from(picked.publicKeyBytes).toString('base64')}`,
|
|
132
|
+
fingerprint: picked.fingerprint,
|
|
133
|
+
keyPath: null,
|
|
134
|
+
source: 'agent',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Agent not available or failed — fall through to filesystem
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Try filesystem
|
|
143
|
+
const sshDir = path.join(os.homedir(), '.ssh');
|
|
144
|
+
const candidates = [
|
|
145
|
+
{ file: 'id_ed25519.pub', keyFile: 'id_ed25519' },
|
|
146
|
+
{ file: 'id_rsa.pub', keyFile: 'id_rsa' },
|
|
147
|
+
];
|
|
148
|
+
for (const { file, keyFile } of candidates) {
|
|
149
|
+
const pubKeyPath = path.join(sshDir, file);
|
|
150
|
+
if (fs.existsSync(pubKeyPath)) {
|
|
151
|
+
try {
|
|
152
|
+
const content = fs.readFileSync(pubKeyPath, 'utf-8').trim();
|
|
153
|
+
const { parseSSHPublicKey } = await import('../crypto/ssh-keys.js');
|
|
154
|
+
const parsed = parseSSHPublicKey(content);
|
|
155
|
+
return {
|
|
156
|
+
publicKey: content,
|
|
157
|
+
fingerprint: parsed.fingerprint,
|
|
158
|
+
keyPath: path.join(sshDir, keyFile),
|
|
159
|
+
source: 'file',
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// Malformed key file — skip
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// No SSH key found — try generating a fallback key in keyring
|
|
169
|
+
try {
|
|
170
|
+
const fallback = await generateFallbackKey();
|
|
171
|
+
if (fallback)
|
|
172
|
+
return fallback;
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Keyring unavailable — continue without sync
|
|
176
|
+
}
|
|
177
|
+
return { publicKey: null, fingerprint: null, keyPath: null, source: 'none' };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Generate a fallback Ed25519 key pair and store it in the OS keyring.
|
|
181
|
+
* Never written to disk. Returns null if keyring is unavailable.
|
|
182
|
+
*/
|
|
183
|
+
async function generateFallbackKey() {
|
|
184
|
+
const sodium = (await import('sodium-native')).default;
|
|
185
|
+
const { KeyringService } = await import('../crypto/keyring.js');
|
|
186
|
+
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES);
|
|
187
|
+
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES);
|
|
188
|
+
sodium.crypto_sign_keypair(pk, sk);
|
|
189
|
+
try {
|
|
190
|
+
// Store secret key in keyring only (never on disk)
|
|
191
|
+
const keyring = new KeyringService();
|
|
192
|
+
const { SecureBuffer } = await import('../crypto/secure-buffer.js');
|
|
193
|
+
await keyring.store('chaoskb', 'identity-secret', SecureBuffer.from(sk));
|
|
194
|
+
await keyring.store('chaoskb', 'identity-public', SecureBuffer.from(pk));
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
sk.fill(0);
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
// Build the SSH public key line
|
|
201
|
+
const { createHash } = await import('node:crypto');
|
|
202
|
+
const typeStr = Buffer.from('ssh-ed25519');
|
|
203
|
+
const keyBlob = Buffer.concat([
|
|
204
|
+
uint32BE(typeStr.length), typeStr,
|
|
205
|
+
uint32BE(pk.length), pk,
|
|
206
|
+
]);
|
|
207
|
+
const base64Blob = keyBlob.toString('base64');
|
|
208
|
+
const fingerprint = 'SHA256:' + createHash('sha256').update(keyBlob).digest('base64').replace(/=+$/, '');
|
|
209
|
+
sk.fill(0);
|
|
210
|
+
return {
|
|
211
|
+
publicKey: `ssh-ed25519 ${base64Blob}`,
|
|
212
|
+
fingerprint,
|
|
213
|
+
keyPath: null,
|
|
214
|
+
source: 'none', // still 'none' — it's a generated key, not a user's SSH key
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function uint32BE(n) {
|
|
218
|
+
const buf = Buffer.alloc(4);
|
|
219
|
+
buf.writeUInt32BE(n);
|
|
220
|
+
return buf;
|
|
221
|
+
}
|
|
222
|
+
const DEFAULT_SYNC_ENDPOINT = 'https://sync.chaoskb.com';
|
|
223
|
+
/**
|
|
224
|
+
* Attempt to register with the sync server during bootstrap.
|
|
225
|
+
*
|
|
226
|
+
* Non-blocking: if the server is unreachable, returns pending=true
|
|
227
|
+
* and the next launch will retry.
|
|
228
|
+
*/
|
|
229
|
+
async function attemptSyncRegistration(ssh, masterKeyBuffer) {
|
|
230
|
+
if (process.env.CHAOSKB_SYNC === 'off' || !ssh.publicKey) {
|
|
231
|
+
return { enabled: false, pending: false, endpoint: null };
|
|
232
|
+
}
|
|
233
|
+
const endpoint = process.env.CHAOSKB_SYNC_ENDPOINT ?? DEFAULT_SYNC_ENDPOINT;
|
|
234
|
+
try {
|
|
235
|
+
const response = await fetchWithTimeout(`${endpoint}/v1/auth/register`, {
|
|
236
|
+
method: 'POST',
|
|
237
|
+
headers: { 'Content-Type': 'application/json' },
|
|
238
|
+
body: JSON.stringify({ publicKey: ssh.publicKey }),
|
|
239
|
+
});
|
|
240
|
+
if (!response.ok) {
|
|
241
|
+
const body = await response.json().catch(() => ({}));
|
|
242
|
+
const status = body.status;
|
|
243
|
+
if (status === 'link_required') {
|
|
244
|
+
process.stderr.write('This SSH key is not recognized. To link it to an existing account,\n' +
|
|
245
|
+
'run "chaoskb-mcp devices add" on a device that already has access.\n');
|
|
246
|
+
return { enabled: false, pending: false, endpoint };
|
|
247
|
+
}
|
|
248
|
+
// Other server errors — mark as pending for retry
|
|
249
|
+
return { enabled: false, pending: true, endpoint };
|
|
250
|
+
}
|
|
251
|
+
const regResult = await response.json();
|
|
252
|
+
// Existing account — download and unwrap master key (new-device restore)
|
|
253
|
+
if (regResult.status === 'existing') {
|
|
254
|
+
await restoreMasterKey(endpoint, ssh);
|
|
255
|
+
return { enabled: true, pending: false, endpoint };
|
|
256
|
+
}
|
|
257
|
+
// New account — wrap master key and upload
|
|
258
|
+
if (masterKeyBuffer.length > 0) {
|
|
259
|
+
await uploadWrappedMasterKey(endpoint, ssh, masterKeyBuffer);
|
|
260
|
+
}
|
|
261
|
+
return { enabled: true, pending: false, endpoint };
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// Network error — mark as pending for retry
|
|
265
|
+
return { enabled: false, pending: true, endpoint };
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Fetch with a 10-second timeout.
|
|
270
|
+
*/
|
|
271
|
+
async function fetchWithTimeout(url, init) {
|
|
272
|
+
const controller = new AbortController();
|
|
273
|
+
const timeoutId = setTimeout(() => controller.abort(), 10_000);
|
|
274
|
+
try {
|
|
275
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
clearTimeout(timeoutId);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Wrap the master key with the SSH public key and upload to the sync server.
|
|
283
|
+
* The wrapped blob is signed with the SSH private key for integrity verification.
|
|
284
|
+
*/
|
|
285
|
+
async function uploadWrappedMasterKey(endpoint, ssh, masterKeyBuffer) {
|
|
286
|
+
if (!ssh.publicKey)
|
|
287
|
+
return;
|
|
288
|
+
const { parseSSHPublicKey } = await import('../crypto/ssh-keys.js');
|
|
289
|
+
const { wrapMasterKey } = await import('../crypto/tiers/standard.js');
|
|
290
|
+
const { SecureBuffer } = await import('../crypto/secure-buffer.js');
|
|
291
|
+
const keyInfo = parseSSHPublicKey(ssh.publicKey);
|
|
292
|
+
const secureMasterKey = SecureBuffer.from(masterKeyBuffer);
|
|
293
|
+
try {
|
|
294
|
+
const wrappedBlob = wrapMasterKey(secureMasterKey, keyInfo);
|
|
295
|
+
// Sign the wrapped blob for integrity verification
|
|
296
|
+
const { SSHSigner } = await import('../sync/ssh-signer.js');
|
|
297
|
+
const signer = new SSHSigner(ssh.keyPath ?? undefined);
|
|
298
|
+
const { authorization, timestamp, sequence, publicKey } = await signer.signRequest('PUT', '/v1/wrapped-key', 1, wrappedBlob);
|
|
299
|
+
await fetchWithTimeout(`${endpoint}/v1/wrapped-key`, {
|
|
300
|
+
method: 'PUT',
|
|
301
|
+
headers: {
|
|
302
|
+
'Content-Type': 'application/octet-stream',
|
|
303
|
+
Authorization: authorization,
|
|
304
|
+
'X-ChaosKB-Timestamp': timestamp,
|
|
305
|
+
'X-ChaosKB-Sequence': String(sequence),
|
|
306
|
+
'X-ChaosKB-PublicKey': publicKey,
|
|
307
|
+
},
|
|
308
|
+
body: wrappedBlob,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
finally {
|
|
312
|
+
secureMasterKey.dispose();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Restore the master key on a new device.
|
|
317
|
+
*
|
|
318
|
+
* Downloads the wrapped master key blob from the server,
|
|
319
|
+
* verifies the signature, unwraps with the SSH private key,
|
|
320
|
+
* and stores in the OS keyring.
|
|
321
|
+
*/
|
|
322
|
+
async function restoreMasterKey(endpoint, ssh) {
|
|
323
|
+
if (!ssh.publicKey)
|
|
324
|
+
return;
|
|
325
|
+
const { SSHSigner } = await import('../sync/ssh-signer.js');
|
|
326
|
+
const signer = new SSHSigner(ssh.keyPath ?? undefined);
|
|
327
|
+
const { authorization, timestamp, sequence, publicKey } = await signer.signRequest('GET', '/v1/wrapped-key', 1);
|
|
328
|
+
const response = await fetchWithTimeout(`${endpoint}/v1/wrapped-key`, {
|
|
329
|
+
method: 'GET',
|
|
330
|
+
headers: {
|
|
331
|
+
Authorization: authorization,
|
|
332
|
+
'X-ChaosKB-Timestamp': timestamp,
|
|
333
|
+
'X-ChaosKB-Sequence': String(sequence),
|
|
334
|
+
'X-ChaosKB-PublicKey': publicKey,
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
if (!response.ok) {
|
|
338
|
+
throw new Error(`Failed to download wrapped key: ${response.status}`);
|
|
339
|
+
}
|
|
340
|
+
const wrappedBlob = new Uint8Array(await response.arrayBuffer());
|
|
341
|
+
// Unwrap with SSH private key
|
|
342
|
+
const { parseSSHPublicKey } = await import('../crypto/ssh-keys.js');
|
|
343
|
+
const keyInfo = parseSSHPublicKey(ssh.publicKey);
|
|
344
|
+
if (keyInfo.type === 'ed25519') {
|
|
345
|
+
const { unwrapMasterKeyEd25519 } = await import('../crypto/tiers/standard.js');
|
|
346
|
+
// Read the private key to get the secret key bytes for unwrapping
|
|
347
|
+
// For Ed25519 unwrap, we need the raw secret key — ssh-agent can sign
|
|
348
|
+
// but can't expose the raw key for crypto_box_seal_open.
|
|
349
|
+
// Fall back to key file for unwrapping.
|
|
350
|
+
if (ssh.keyPath) {
|
|
351
|
+
const keyData = fs.readFileSync(ssh.keyPath, 'utf-8');
|
|
352
|
+
const { createPrivateKey } = await import('node:crypto');
|
|
353
|
+
const keyObj = createPrivateKey({ key: keyData, format: 'pem' });
|
|
354
|
+
const exported = keyObj.export({ type: 'pkcs8', format: 'der' });
|
|
355
|
+
// Ed25519 PKCS8 DER: last 32 bytes are the private key, preceded by 2-byte wrapper
|
|
356
|
+
// The actual key bytes are at offset 16 (after DER headers), 32 bytes of seed + 32 bytes of public
|
|
357
|
+
const derBuf = Buffer.from(exported);
|
|
358
|
+
// Extract the 32-byte seed from the PKCS8 structure
|
|
359
|
+
// PKCS8 for Ed25519: 30 2e 02 01 00 30 05 06 03 2b 65 70 04 22 04 20 [32 bytes seed]
|
|
360
|
+
const seedOffset = derBuf.indexOf(Buffer.from([0x04, 0x20]), 12);
|
|
361
|
+
if (seedOffset === -1) {
|
|
362
|
+
throw new Error('Could not extract Ed25519 seed from private key');
|
|
363
|
+
}
|
|
364
|
+
const seed = derBuf.subarray(seedOffset + 2, seedOffset + 34);
|
|
365
|
+
// Generate the full 64-byte secret key from the seed
|
|
366
|
+
const sodium = (await import('sodium-native')).default;
|
|
367
|
+
const fullSk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES);
|
|
368
|
+
const fullPk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES);
|
|
369
|
+
sodium.crypto_sign_seed_keypair(fullPk, fullSk, seed);
|
|
370
|
+
const masterKey = unwrapMasterKeyEd25519(wrappedBlob, fullSk, fullPk);
|
|
371
|
+
// Store in keyring
|
|
372
|
+
await storeKeyInKeyring(masterKey);
|
|
373
|
+
masterKey.dispose();
|
|
374
|
+
// Zero sensitive buffers
|
|
375
|
+
fullSk.fill(0);
|
|
376
|
+
seed.fill(0);
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
// Key is in agent only — can't extract raw key for crypto_box_seal_open
|
|
380
|
+
// This is a known limitation: agent-only keys can sign but can't unwrap sealed boxes
|
|
381
|
+
throw new Error('Cannot restore master key: SSH key is in agent only (no key file).\n' +
|
|
382
|
+
'crypto_box_seal_open requires the raw private key. Ensure the key file is available at ~/.ssh/id_ed25519');
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
// RSA unwrap
|
|
387
|
+
const { unwrapMasterKeyRSA } = await import('../crypto/tiers/standard.js');
|
|
388
|
+
const { createPrivateKey } = await import('node:crypto');
|
|
389
|
+
if (!ssh.keyPath) {
|
|
390
|
+
throw new Error('Cannot restore master key: no RSA key file path');
|
|
391
|
+
}
|
|
392
|
+
const keyData = fs.readFileSync(ssh.keyPath, 'utf-8');
|
|
393
|
+
const rsaPrivKey = createPrivateKey({ key: keyData, format: 'pem' });
|
|
394
|
+
const masterKey = unwrapMasterKeyRSA(wrappedBlob, rsaPrivKey);
|
|
395
|
+
await storeKeyInKeyring(masterKey);
|
|
396
|
+
masterKey.dispose();
|
|
397
|
+
}
|
|
398
|
+
process.stderr.write('Master key restored from sync server. Your knowledge base will sync shortly.\n');
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Retry sync registration on subsequent launches when syncPending is true.
|
|
402
|
+
* Called from the MCP server startup path.
|
|
403
|
+
*/
|
|
404
|
+
export async function retrySyncRegistration(configPath) {
|
|
405
|
+
try {
|
|
406
|
+
const configData = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
407
|
+
if (!configData.syncPending)
|
|
408
|
+
return;
|
|
409
|
+
const sshResult = await detectSSHKey();
|
|
410
|
+
if (!sshResult.publicKey)
|
|
411
|
+
return;
|
|
412
|
+
const syncResult = await attemptSyncRegistration(sshResult, Buffer.alloc(0));
|
|
413
|
+
if (syncResult.enabled || !syncResult.pending) {
|
|
414
|
+
// Either succeeded or permanently failed — clear pending
|
|
415
|
+
configData.syncEnabled = syncResult.enabled;
|
|
416
|
+
configData.syncPending = false;
|
|
417
|
+
if (syncResult.endpoint)
|
|
418
|
+
configData.endpoint = syncResult.endpoint;
|
|
419
|
+
if (sshResult.fingerprint)
|
|
420
|
+
configData.sshKeyFingerprint = sshResult.fingerprint;
|
|
421
|
+
fs.writeFileSync(configPath, JSON.stringify(configData, null, 2), { mode: 0o600 });
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
catch {
|
|
425
|
+
// Retry failed silently — will try again next launch
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
async function storeKeyInKeyring(masterKey) {
|
|
429
|
+
// macOS: warn about potential keychain access dialog
|
|
430
|
+
if (process.platform === 'darwin') {
|
|
431
|
+
process.stderr.write('Storing encryption key in macOS Keychain.\n' +
|
|
432
|
+
'You may see a system dialog asking to allow keychain access — this is expected.\n');
|
|
433
|
+
}
|
|
434
|
+
const { KeyringService } = await import('../crypto/keyring.js');
|
|
435
|
+
const keyring = new KeyringService();
|
|
436
|
+
await keyring.store('chaoskb', 'master-key', masterKey);
|
|
437
|
+
}
|
|
438
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../cli/bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade security tier.
|
|
3
|
+
*
|
|
4
|
+
* Standard → Maximum: re-wrap master key under Argon2id-derived key from passphrase.
|
|
5
|
+
* Enhanced → Maximum: same as above, with note that mnemonic is invalidated.
|
|
6
|
+
*
|
|
7
|
+
* Note: The Enhanced tier (BIP39 mnemonic) is deprecated. New upgrades only
|
|
8
|
+
* support "maximum". Existing Enhanced-tier users can still upgrade to Maximum.
|
|
9
|
+
*/
|
|
10
|
+
export declare function upgradeTierCommand(tier: string, options?: {
|
|
11
|
+
dryRun?: boolean;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../cli/commands/config.ts"],"names":[],"mappings":"AAqBA;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsEpG"}
|