@skillfm/local 2.6.4 → 2.7.1
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/README.md +50 -1
- package/dist/_signers/aliyun-v3.d.ts +21 -0
- package/dist/_signers/aliyun-v3.d.ts.map +1 -0
- package/dist/_signers/aliyun-v3.js +47 -0
- package/dist/_signers/aliyun-v3.js.map +1 -0
- package/dist/_signers/canonical.d.ts +29 -0
- package/dist/_signers/canonical.d.ts.map +1 -0
- package/dist/_signers/canonical.js +59 -0
- package/dist/_signers/canonical.js.map +1 -0
- package/dist/_signers/index.d.ts +9 -0
- package/dist/_signers/index.d.ts.map +1 -0
- package/dist/_signers/index.js +6 -0
- package/dist/_signers/index.js.map +1 -0
- package/dist/_signers/tencent-tc3.d.ts +21 -0
- package/dist/_signers/tencent-tc3.d.ts.map +1 -0
- package/dist/_signers/tencent-tc3.js +48 -0
- package/dist/_signers/tencent-tc3.js.map +1 -0
- package/dist/_signers/volc-v4.d.ts +18 -0
- package/dist/_signers/volc-v4.d.ts.map +1 -0
- package/dist/_signers/volc-v4.js +43 -0
- package/dist/_signers/volc-v4.js.map +1 -0
- package/dist/agent-hints.d.ts.map +1 -1
- package/dist/agent-hints.js +28 -13
- package/dist/agent-hints.js.map +1 -1
- package/dist/asset-connectors/aliyun-ecs.d.ts +18 -0
- package/dist/asset-connectors/aliyun-ecs.d.ts.map +1 -0
- package/dist/asset-connectors/aliyun-ecs.js +99 -0
- package/dist/asset-connectors/aliyun-ecs.js.map +1 -0
- package/dist/asset-connectors/base.d.ts +15 -0
- package/dist/asset-connectors/base.d.ts.map +1 -0
- package/dist/asset-connectors/base.js +19 -0
- package/dist/asset-connectors/base.js.map +1 -0
- package/dist/asset-connectors/cloudflare.d.ts +18 -0
- package/dist/asset-connectors/cloudflare.d.ts.map +1 -0
- package/dist/asset-connectors/cloudflare.js +94 -0
- package/dist/asset-connectors/cloudflare.js.map +1 -0
- package/dist/asset-connectors/digitalocean.d.ts +18 -0
- package/dist/asset-connectors/digitalocean.d.ts.map +1 -0
- package/dist/asset-connectors/digitalocean.js +79 -0
- package/dist/asset-connectors/digitalocean.js.map +1 -0
- package/dist/asset-connectors/godaddy.d.ts +18 -0
- package/dist/asset-connectors/godaddy.d.ts.map +1 -0
- package/dist/asset-connectors/godaddy.js +62 -0
- package/dist/asset-connectors/godaddy.js.map +1 -0
- package/dist/asset-connectors/hetzner.d.ts +18 -0
- package/dist/asset-connectors/hetzner.d.ts.map +1 -0
- package/dist/asset-connectors/hetzner.js +52 -0
- package/dist/asset-connectors/hetzner.js.map +1 -0
- package/dist/asset-connectors/index.d.ts +18 -0
- package/dist/asset-connectors/index.d.ts.map +1 -0
- package/dist/asset-connectors/index.js +52 -0
- package/dist/asset-connectors/index.js.map +1 -0
- package/dist/asset-connectors/namecheap.d.ts +34 -0
- package/dist/asset-connectors/namecheap.d.ts.map +1 -0
- package/dist/asset-connectors/namecheap.js +178 -0
- package/dist/asset-connectors/namecheap.js.map +1 -0
- package/dist/asset-connectors/ssl-labs.d.ts +22 -0
- package/dist/asset-connectors/ssl-labs.d.ts.map +1 -0
- package/dist/asset-connectors/ssl-labs.js +79 -0
- package/dist/asset-connectors/ssl-labs.js.map +1 -0
- package/dist/asset-connectors/tencent-cvm.d.ts +18 -0
- package/dist/asset-connectors/tencent-cvm.d.ts.map +1 -0
- package/dist/asset-connectors/tencent-cvm.js +145 -0
- package/dist/asset-connectors/tencent-cvm.js.map +1 -0
- package/dist/asset-connectors/types.d.ts +45 -0
- package/dist/asset-connectors/types.d.ts.map +1 -0
- package/dist/asset-connectors/types.js +26 -0
- package/dist/asset-connectors/types.js.map +1 -0
- package/dist/asset-connectors/vultr.d.ts +18 -0
- package/dist/asset-connectors/vultr.d.ts.map +1 -0
- package/dist/asset-connectors/vultr.js +73 -0
- package/dist/asset-connectors/vultr.js.map +1 -0
- package/dist/connectors/anthropic.d.ts +10 -0
- package/dist/connectors/anthropic.d.ts.map +1 -0
- package/dist/connectors/anthropic.js +103 -0
- package/dist/connectors/anthropic.js.map +1 -0
- package/dist/connectors/base.d.ts +11 -0
- package/dist/connectors/base.d.ts.map +1 -0
- package/dist/connectors/base.js +19 -0
- package/dist/connectors/base.js.map +1 -0
- package/dist/connectors/deepseek.d.ts +14 -0
- package/dist/connectors/deepseek.d.ts.map +1 -0
- package/dist/connectors/deepseek.js +77 -0
- package/dist/connectors/deepseek.js.map +1 -0
- package/dist/connectors/doubao.d.ts +10 -0
- package/dist/connectors/doubao.d.ts.map +1 -0
- package/dist/connectors/doubao.js +64 -0
- package/dist/connectors/doubao.js.map +1 -0
- package/dist/connectors/index.d.ts +14 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +42 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/kimi.d.ts +10 -0
- package/dist/connectors/kimi.d.ts.map +1 -0
- package/dist/connectors/kimi.js +67 -0
- package/dist/connectors/kimi.js.map +1 -0
- package/dist/connectors/openai.d.ts +10 -0
- package/dist/connectors/openai.d.ts.map +1 -0
- package/dist/connectors/openai.js +101 -0
- package/dist/connectors/openai.js.map +1 -0
- package/dist/connectors/qwen.d.ts +10 -0
- package/dist/connectors/qwen.d.ts.map +1 -0
- package/dist/connectors/qwen.js +66 -0
- package/dist/connectors/qwen.js.map +1 -0
- package/dist/connectors/types.d.ts +47 -0
- package/dist/connectors/types.d.ts.map +1 -0
- package/dist/connectors/types.js +24 -0
- package/dist/connectors/types.js.map +1 -0
- package/dist/guard/bin.js +0 -0
- package/dist/index.js +83 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/_vendored-contracts/beacon-mcp-tools-v1.d.ts +373 -0
- package/dist/mcp/_vendored-contracts/beacon-mcp-tools-v1.d.ts.map +1 -0
- package/dist/mcp/_vendored-contracts/beacon-mcp-tools-v1.js +130 -0
- package/dist/mcp/_vendored-contracts/beacon-mcp-tools-v1.js.map +1 -0
- package/dist/mcp/brain-client.d.ts +96 -0
- package/dist/mcp/brain-client.d.ts.map +1 -0
- package/dist/mcp/brain-client.js +214 -0
- package/dist/mcp/brain-client.js.map +1 -0
- package/dist/mcp/cache.d.ts +55 -0
- package/dist/mcp/cache.d.ts.map +1 -0
- package/dist/mcp/cache.js +109 -0
- package/dist/mcp/cache.js.map +1 -0
- package/dist/mcp/config.d.ts +29 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +69 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/decision-engine.d.ts +54 -0
- package/dist/mcp/decision-engine.d.ts.map +1 -0
- package/dist/mcp/decision-engine.js +107 -0
- package/dist/mcp/decision-engine.js.map +1 -0
- package/dist/mcp/errors.d.ts +66 -0
- package/dist/mcp/errors.d.ts.map +1 -0
- package/dist/mcp/errors.js +127 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/index.d.ts +40 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +104 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tools/_placeholder.d.ts +24 -0
- package/dist/mcp/tools/_placeholder.d.ts.map +1 -0
- package/dist/mcp/tools/_placeholder.js +29 -0
- package/dist/mcp/tools/_placeholder.js.map +1 -0
- package/dist/mcp/tools/avatar-market.d.ts +22 -0
- package/dist/mcp/tools/avatar-market.d.ts.map +1 -0
- package/dist/mcp/tools/avatar-market.js +33 -0
- package/dist/mcp/tools/avatar-market.js.map +1 -0
- package/dist/mcp/tools/check-expiry.d.ts +23 -0
- package/dist/mcp/tools/check-expiry.d.ts.map +1 -0
- package/dist/mcp/tools/check-expiry.js +29 -0
- package/dist/mcp/tools/check-expiry.js.map +1 -0
- package/dist/mcp/tools/check-usage.d.ts +25 -0
- package/dist/mcp/tools/check-usage.d.ts.map +1 -0
- package/dist/mcp/tools/check-usage.js +33 -0
- package/dist/mcp/tools/check-usage.js.map +1 -0
- package/dist/mcp/tools/credential-tools.d.ts +37 -0
- package/dist/mcp/tools/credential-tools.d.ts.map +1 -0
- package/dist/mcp/tools/credential-tools.js +109 -0
- package/dist/mcp/tools/credential-tools.js.map +1 -0
- package/dist/mcp/tools/get-monthly-picks.d.ts +25 -0
- package/dist/mcp/tools/get-monthly-picks.d.ts.map +1 -0
- package/dist/mcp/tools/get-monthly-picks.js +35 -0
- package/dist/mcp/tools/get-monthly-picks.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +44 -0
- package/dist/mcp/tools/index.d.ts.map +1 -0
- package/dist/mcp/tools/index.js +188 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/memory-recent.d.ts +17 -0
- package/dist/mcp/tools/memory-recent.d.ts.map +1 -0
- package/dist/mcp/tools/memory-recent.js +46 -0
- package/dist/mcp/tools/memory-recent.js.map +1 -0
- package/dist/mcp/tools/memory-save.d.ts +15 -0
- package/dist/mcp/tools/memory-save.d.ts.map +1 -0
- package/dist/mcp/tools/memory-save.js +53 -0
- package/dist/mcp/tools/memory-save.js.map +1 -0
- package/dist/mcp/tools/memory-search.d.ts +24 -0
- package/dist/mcp/tools/memory-search.d.ts.map +1 -0
- package/dist/mcp/tools/memory-search.js +64 -0
- package/dist/mcp/tools/memory-search.js.map +1 -0
- package/dist/mcp/tools/record-acceptance.d.ts +22 -0
- package/dist/mcp/tools/record-acceptance.d.ts.map +1 -0
- package/dist/mcp/tools/record-acceptance.js +33 -0
- package/dist/mcp/tools/record-acceptance.js.map +1 -0
- package/dist/mcp/tools/record-rejection.d.ts +23 -0
- package/dist/mcp/tools/record-rejection.d.ts.map +1 -0
- package/dist/mcp/tools/record-rejection.js +34 -0
- package/dist/mcp/tools/record-rejection.js.map +1 -0
- package/dist/mcp/tools/suggest-route.d.ts +26 -0
- package/dist/mcp/tools/suggest-route.d.ts.map +1 -0
- package/dist/mcp/tools/suggest-route.js +56 -0
- package/dist/mcp/tools/suggest-route.js.map +1 -0
- package/dist/mcp/tools/user-preferences.d.ts +22 -0
- package/dist/mcp/tools/user-preferences.d.ts.map +1 -0
- package/dist/mcp/tools/user-preferences.js +63 -0
- package/dist/mcp/tools/user-preferences.js.map +1 -0
- package/dist/mcp-stdio/bin.js +0 -0
- package/dist/memory/index.d.ts +5 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +4 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/mem0-client.d.ts +32 -0
- package/dist/memory/mem0-client.d.ts.map +1 -0
- package/dist/memory/mem0-client.js +161 -0
- package/dist/memory/mem0-client.js.map +1 -0
- package/dist/memory/types.d.ts +47 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +20 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/router/catalog.d.ts +4 -0
- package/dist/router/catalog.d.ts.map +1 -0
- package/dist/router/catalog.js +103 -0
- package/dist/router/catalog.js.map +1 -0
- package/dist/router/classifier.d.ts +5 -0
- package/dist/router/classifier.d.ts.map +1 -0
- package/dist/router/classifier.js +43 -0
- package/dist/router/classifier.js.map +1 -0
- package/dist/router/index.d.ts +7 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +6 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/litellm-config.d.ts +34 -0
- package/dist/router/litellm-config.d.ts.map +1 -0
- package/dist/router/litellm-config.js +78 -0
- package/dist/router/litellm-config.js.map +1 -0
- package/dist/router/route.d.ts +3 -0
- package/dist/router/route.d.ts.map +1 -0
- package/dist/router/route.js +63 -0
- package/dist/router/route.js.map +1 -0
- package/dist/router/types.d.ts +36 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +7 -0
- package/dist/router/types.js.map +1 -0
- package/dist/saas-connectors/base.d.ts +16 -0
- package/dist/saas-connectors/base.d.ts.map +1 -0
- package/dist/saas-connectors/base.js +16 -0
- package/dist/saas-connectors/base.js.map +1 -0
- package/dist/saas-connectors/brave.d.ts +19 -0
- package/dist/saas-connectors/brave.d.ts.map +1 -0
- package/dist/saas-connectors/brave.js +50 -0
- package/dist/saas-connectors/brave.js.map +1 -0
- package/dist/saas-connectors/fal.d.ts +15 -0
- package/dist/saas-connectors/fal.d.ts.map +1 -0
- package/dist/saas-connectors/fal.js +35 -0
- package/dist/saas-connectors/fal.js.map +1 -0
- package/dist/saas-connectors/index.d.ts +11 -0
- package/dist/saas-connectors/index.d.ts.map +1 -0
- package/dist/saas-connectors/index.js +32 -0
- package/dist/saas-connectors/index.js.map +1 -0
- package/dist/saas-connectors/replicate.d.ts +19 -0
- package/dist/saas-connectors/replicate.d.ts.map +1 -0
- package/dist/saas-connectors/replicate.js +43 -0
- package/dist/saas-connectors/replicate.js.map +1 -0
- package/dist/saas-connectors/serper.d.ts +19 -0
- package/dist/saas-connectors/serper.d.ts.map +1 -0
- package/dist/saas-connectors/serper.js +47 -0
- package/dist/saas-connectors/serper.js.map +1 -0
- package/dist/saas-connectors/types.d.ts +31 -0
- package/dist/saas-connectors/types.d.ts.map +1 -0
- package/dist/saas-connectors/types.js +6 -0
- package/dist/saas-connectors/types.js.map +1 -0
- package/dist/scheduler/brain-push-client.d.ts +13 -0
- package/dist/scheduler/brain-push-client.d.ts.map +1 -0
- package/dist/scheduler/brain-push-client.js +46 -0
- package/dist/scheduler/brain-push-client.js.map +1 -0
- package/dist/scheduler/index.d.ts +6 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +5 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/poll.d.ts +4 -0
- package/dist/scheduler/poll.d.ts.map +1 -0
- package/dist/scheduler/poll.js +170 -0
- package/dist/scheduler/poll.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +18 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -0
- package/dist/scheduler/scheduler.js +67 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/scheduler/types.d.ts +49 -0
- package/dist/scheduler/types.d.ts.map +1 -0
- package/dist/scheduler/types.js +14 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/vault/cli.d.ts +2 -0
- package/dist/vault/cli.d.ts.map +1 -0
- package/dist/vault/cli.js +170 -0
- package/dist/vault/cli.js.map +1 -0
- package/dist/vault/crypto.d.ts +9 -0
- package/dist/vault/crypto.d.ts.map +1 -0
- package/dist/vault/crypto.js +54 -0
- package/dist/vault/crypto.js.map +1 -0
- package/dist/vault/index.d.ts +6 -0
- package/dist/vault/index.d.ts.map +1 -0
- package/dist/vault/index.js +5 -0
- package/dist/vault/index.js.map +1 -0
- package/dist/vault/types.d.ts +28 -0
- package/dist/vault/types.d.ts.map +1 -0
- package/dist/vault/types.js +22 -0
- package/dist/vault/types.js.map +1 -0
- package/dist/vault/vault.d.ts +34 -0
- package/dist/vault/vault.d.ts.map +1 -0
- package/dist/vault/vault.js +149 -0
- package/dist/vault/vault.js.map +1 -0
- package/package.json +17 -5
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/vault/cli.ts
|
|
2
|
+
//
|
|
3
|
+
// Vault subcommand CLI (Day 5 B1)
|
|
4
|
+
// 入口: `npx -y @skillfm/local vault <action> [args]`
|
|
5
|
+
// 用法:
|
|
6
|
+
// skillfm-local vault put <provider> [key] # key 省略则 stdin 读 (避免 shell history 留 key)
|
|
7
|
+
// skillfm-local vault get <provider> # 显示 fingerprint, 不显示 key 全文
|
|
8
|
+
// skillfm-local vault list
|
|
9
|
+
// skillfm-local vault delete <provider>
|
|
10
|
+
// skillfm-local vault rotate
|
|
11
|
+
// skillfm-local vault health
|
|
12
|
+
import * as readline from 'node:readline';
|
|
13
|
+
import { Vault } from './vault.js';
|
|
14
|
+
import { maskKey } from '../connectors/types.js';
|
|
15
|
+
async function readStdinHidden(prompt) {
|
|
16
|
+
// 简易 hidden input — 关闭 echo
|
|
17
|
+
process.stdout.write(prompt);
|
|
18
|
+
const stdin = process.stdin;
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
if (!stdin.isTTY) {
|
|
21
|
+
// 非 TTY (e.g. piped input) — 直接 readline 不 hide
|
|
22
|
+
const rl = readline.createInterface({ input: stdin, output: process.stderr });
|
|
23
|
+
rl.question('', (answer) => {
|
|
24
|
+
rl.close();
|
|
25
|
+
resolve(answer.trim());
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
stdin.setRawMode?.(true);
|
|
30
|
+
stdin.resume();
|
|
31
|
+
stdin.setEncoding('utf8');
|
|
32
|
+
let buf = '';
|
|
33
|
+
const onData = (ch) => {
|
|
34
|
+
const c = ch.toString();
|
|
35
|
+
if (c === '\n' || c === '\r' || c === '') {
|
|
36
|
+
stdin.setRawMode?.(false);
|
|
37
|
+
stdin.pause();
|
|
38
|
+
stdin.removeListener('data', onData);
|
|
39
|
+
process.stdout.write('\n');
|
|
40
|
+
resolve(buf.trim());
|
|
41
|
+
}
|
|
42
|
+
else if (c === '') {
|
|
43
|
+
// Ctrl+C
|
|
44
|
+
stdin.setRawMode?.(false);
|
|
45
|
+
process.exit(130);
|
|
46
|
+
}
|
|
47
|
+
else if (c === '' || c === '\b') {
|
|
48
|
+
// Backspace
|
|
49
|
+
if (buf.length > 0) {
|
|
50
|
+
buf = buf.slice(0, -1);
|
|
51
|
+
process.stdout.write('\b \b');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
buf += c;
|
|
56
|
+
process.stdout.write('*');
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
stdin.on('data', onData);
|
|
60
|
+
stdin.on('error', reject);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const VALID_PROVIDERS = new Set([
|
|
64
|
+
// LLM
|
|
65
|
+
'anthropic', 'openai', 'deepseek', 'kimi', 'qwen', 'doubao',
|
|
66
|
+
// Asset (域名 / SSL / VPS)
|
|
67
|
+
'cloudflare', 'godaddy', 'namecheap', 'ssl_labs', 'ssl_labs_domains',
|
|
68
|
+
'hetzner', 'digitalocean', 'vultr', 'aliyun_ecs', 'tencent_cvm',
|
|
69
|
+
// SaaS
|
|
70
|
+
'brave_search', 'serper', 'replicate', 'fal',
|
|
71
|
+
]);
|
|
72
|
+
function validateProvider(p) {
|
|
73
|
+
if (!VALID_PROVIDERS.has(p)) {
|
|
74
|
+
console.error(`[vault] unknown provider "${p}". Valid: ${[...VALID_PROVIDERS].join(', ')}`);
|
|
75
|
+
process.exit(2);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export async function cmdVault() {
|
|
79
|
+
const action = process.argv[3];
|
|
80
|
+
const args = process.argv.slice(4);
|
|
81
|
+
if (!action) {
|
|
82
|
+
console.error('Usage: skillfm-local vault <put|get|list|delete|rotate|health> [args]');
|
|
83
|
+
process.exit(2);
|
|
84
|
+
}
|
|
85
|
+
const v = new Vault();
|
|
86
|
+
switch (action) {
|
|
87
|
+
case 'put': {
|
|
88
|
+
const provider = args[0];
|
|
89
|
+
if (!provider) {
|
|
90
|
+
console.error('Usage: skillfm-local vault put <provider> [key]');
|
|
91
|
+
process.exit(2);
|
|
92
|
+
}
|
|
93
|
+
validateProvider(provider);
|
|
94
|
+
let key = args[1];
|
|
95
|
+
if (!key) {
|
|
96
|
+
// 不在命令行传 key (避免 shell history 留痕), 走 hidden stdin
|
|
97
|
+
key = await readStdinHidden(`[vault] enter ${provider} key (input hidden): `);
|
|
98
|
+
}
|
|
99
|
+
if (!key || key.length < 8) {
|
|
100
|
+
console.error('[vault] key 太短 (≥8 chars)');
|
|
101
|
+
process.exit(2);
|
|
102
|
+
}
|
|
103
|
+
await v.put(provider, key);
|
|
104
|
+
console.log(`[vault] ✓ saved ${provider} (${maskKey(key)})`);
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
case 'get': {
|
|
108
|
+
const provider = args[0];
|
|
109
|
+
if (!provider) {
|
|
110
|
+
console.error('Usage: skillfm-local vault get <provider>');
|
|
111
|
+
process.exit(2);
|
|
112
|
+
}
|
|
113
|
+
const k = await v.get(provider);
|
|
114
|
+
if (!k) {
|
|
115
|
+
console.error(`[vault] no key for ${provider}`);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
console.log(`[vault] ${provider}: ${maskKey(k)}`);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
case 'list': {
|
|
122
|
+
const providers = await v.list();
|
|
123
|
+
if (providers.length === 0) {
|
|
124
|
+
console.log('[vault] (empty)');
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
console.log('[vault] saved providers:');
|
|
128
|
+
for (const p of providers)
|
|
129
|
+
console.log(` - ${p}`);
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
case 'delete': {
|
|
134
|
+
const provider = args[0];
|
|
135
|
+
if (!provider) {
|
|
136
|
+
console.error('Usage: skillfm-local vault delete <provider>');
|
|
137
|
+
process.exit(2);
|
|
138
|
+
}
|
|
139
|
+
const did = await v.delete(provider);
|
|
140
|
+
if (did)
|
|
141
|
+
console.log(`[vault] ✓ deleted ${provider}`);
|
|
142
|
+
else {
|
|
143
|
+
console.error(`[vault] ${provider} not found`);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case 'rotate': {
|
|
149
|
+
await v.rotate();
|
|
150
|
+
console.log('[vault] ✓ master key rotated, all entries re-encrypted');
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case 'health': {
|
|
154
|
+
const h = await v.health();
|
|
155
|
+
if (h.ok) {
|
|
156
|
+
console.log(`[vault] ✓ healthy (${h.entry_count} entries)`);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
console.error(`[vault] ✗ unhealthy: ${h.error}`);
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
default:
|
|
165
|
+
console.error(`[vault] unknown action: ${action}`);
|
|
166
|
+
console.error('Valid: put | get | list | delete | rotate | health');
|
|
167
|
+
process.exit(2);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/vault/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface EncryptResult {
|
|
2
|
+
iv_b64: string;
|
|
3
|
+
auth_tag_b64: string;
|
|
4
|
+
ciphertext_b64: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function generateMasterKey(): Buffer;
|
|
7
|
+
export declare function encrypt(plaintext: string, key: Buffer): EncryptResult;
|
|
8
|
+
export declare function decrypt(blob: EncryptResult, key: Buffer): string;
|
|
9
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/vault/crypto.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,CAgBrE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAqBhE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/vault/crypto.ts
|
|
2
|
+
//
|
|
3
|
+
// AES-256-GCM 加密原语
|
|
4
|
+
// IV 12 bytes (GCM 推荐) / Auth tag 16 bytes / Key 32 bytes
|
|
5
|
+
import { randomBytes, createCipheriv, createDecipheriv } from 'node:crypto';
|
|
6
|
+
import { VaultError, VAULT_ERROR_CODES } from './types.js';
|
|
7
|
+
const ALGO = 'aes-256-gcm';
|
|
8
|
+
const KEY_BYTES = 32;
|
|
9
|
+
const IV_BYTES = 12;
|
|
10
|
+
const TAG_BYTES = 16;
|
|
11
|
+
export function generateMasterKey() {
|
|
12
|
+
return randomBytes(KEY_BYTES);
|
|
13
|
+
}
|
|
14
|
+
export function encrypt(plaintext, key) {
|
|
15
|
+
if (key.length !== KEY_BYTES) {
|
|
16
|
+
throw new VaultError(VAULT_ERROR_CODES.MASTER_KEY_INVALID, `master key must be ${KEY_BYTES} bytes, got ${key.length}`);
|
|
17
|
+
}
|
|
18
|
+
const iv = randomBytes(IV_BYTES);
|
|
19
|
+
const cipher = createCipheriv(ALGO, key, iv);
|
|
20
|
+
const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
21
|
+
const tag = cipher.getAuthTag();
|
|
22
|
+
if (tag.length !== TAG_BYTES) {
|
|
23
|
+
throw new VaultError(VAULT_ERROR_CODES.DECRYPT_FAILED, `unexpected auth tag length ${tag.length}`);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
iv_b64: iv.toString('base64'),
|
|
27
|
+
auth_tag_b64: tag.toString('base64'),
|
|
28
|
+
ciphertext_b64: encrypted.toString('base64'),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function decrypt(blob, key) {
|
|
32
|
+
if (key.length !== KEY_BYTES) {
|
|
33
|
+
throw new VaultError(VAULT_ERROR_CODES.MASTER_KEY_INVALID, `master key must be ${KEY_BYTES} bytes`);
|
|
34
|
+
}
|
|
35
|
+
const iv = Buffer.from(blob.iv_b64, 'base64');
|
|
36
|
+
const tag = Buffer.from(blob.auth_tag_b64, 'base64');
|
|
37
|
+
const cipher_buf = Buffer.from(blob.ciphertext_b64, 'base64');
|
|
38
|
+
if (iv.length !== IV_BYTES) {
|
|
39
|
+
throw new VaultError(VAULT_ERROR_CODES.VAULT_FILE_CORRUPTED, `iv length ${iv.length} != ${IV_BYTES}`);
|
|
40
|
+
}
|
|
41
|
+
if (tag.length !== TAG_BYTES) {
|
|
42
|
+
throw new VaultError(VAULT_ERROR_CODES.VAULT_FILE_CORRUPTED, `tag length ${tag.length} != ${TAG_BYTES}`);
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const decipher = createDecipheriv(ALGO, key, iv);
|
|
46
|
+
decipher.setAuthTag(tag);
|
|
47
|
+
const decrypted = Buffer.concat([decipher.update(cipher_buf), decipher.final()]);
|
|
48
|
+
return decrypted.toString('utf8');
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
throw new VaultError(VAULT_ERROR_CODES.DECRYPT_FAILED, `AES-GCM auth failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/vault/crypto.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { VaultConfig } from './vault.js';
|
|
2
|
+
export { Vault } from './vault.js';
|
|
3
|
+
export type { VaultEntries, VaultFileV1, VaultProviderId } from './types.js';
|
|
4
|
+
export { VaultError, VAULT_ERROR_CODES } from './types.js';
|
|
5
|
+
export { encrypt, decrypt, generateMasterKey } from './crypto.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vault/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vault/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AAGvC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type VaultProviderId = string;
|
|
2
|
+
export interface VaultFileV1 {
|
|
3
|
+
version: 1;
|
|
4
|
+
/** 12 bytes IV, base64 */
|
|
5
|
+
iv: string;
|
|
6
|
+
/** 16 bytes auth tag, base64 */
|
|
7
|
+
auth_tag: string;
|
|
8
|
+
/** AES-256-GCM ciphertext, base64 */
|
|
9
|
+
ciphertext: string;
|
|
10
|
+
created_at: string;
|
|
11
|
+
updated_at: string;
|
|
12
|
+
}
|
|
13
|
+
export interface VaultEntries {
|
|
14
|
+
[provider: string]: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class VaultError extends Error {
|
|
17
|
+
code: string;
|
|
18
|
+
constructor(code: string, message: string);
|
|
19
|
+
}
|
|
20
|
+
export declare const VAULT_ERROR_CODES: {
|
|
21
|
+
readonly MASTER_KEY_NOT_FOUND: "VAULT_MASTER_KEY_NOT_FOUND";
|
|
22
|
+
readonly MASTER_KEY_INVALID: "VAULT_MASTER_KEY_INVALID";
|
|
23
|
+
readonly VAULT_FILE_CORRUPTED: "VAULT_FILE_CORRUPTED";
|
|
24
|
+
readonly DECRYPT_FAILED: "VAULT_DECRYPT_FAILED";
|
|
25
|
+
readonly PROVIDER_NOT_FOUND: "VAULT_PROVIDER_NOT_FOUND";
|
|
26
|
+
readonly IO_ERROR: "VAULT_IO_ERROR";
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vault/types.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AAErC,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,CAAC,CAAC;IACX,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,qBAAa,UAAW,SAAQ,KAAK;IAChB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIjD;AAED,eAAO,MAAM,iBAAiB;;;;;;;CAOpB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/vault/types.ts
|
|
2
|
+
//
|
|
3
|
+
// 凭证保险柜 — Day 3 D3-B1
|
|
4
|
+
// AES-256-GCM 加密用户 BYOK key, master key 存节点本地 (~/.skillfm/vault.key chmod 0600)
|
|
5
|
+
// 替代 Day 1+2 connector in-memory 处理 — Day 3 之后所有 connector 从 vault.get() 取 key
|
|
6
|
+
export class VaultError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
constructor(code, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.name = 'VaultError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export const VAULT_ERROR_CODES = {
|
|
15
|
+
MASTER_KEY_NOT_FOUND: 'VAULT_MASTER_KEY_NOT_FOUND',
|
|
16
|
+
MASTER_KEY_INVALID: 'VAULT_MASTER_KEY_INVALID',
|
|
17
|
+
VAULT_FILE_CORRUPTED: 'VAULT_FILE_CORRUPTED',
|
|
18
|
+
DECRYPT_FAILED: 'VAULT_DECRYPT_FAILED',
|
|
19
|
+
PROVIDER_NOT_FOUND: 'VAULT_PROVIDER_NOT_FOUND',
|
|
20
|
+
IO_ERROR: 'VAULT_IO_ERROR',
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/vault/types.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,sBAAsB;AACtB,gFAAgF;AAChF,+EAA+E;AAoB/E,MAAM,OAAO,UAAW,SAAQ,KAAK;IAChB;IAAnB,YAAmB,IAAY,EAAE,OAAe;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QADE,SAAI,GAAJ,IAAI,CAAQ;QAE7B,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,oBAAoB,EAAE,4BAA4B;IAClD,kBAAkB,EAAE,0BAA0B;IAC9C,oBAAoB,EAAE,sBAAsB;IAC5C,cAAc,EAAE,sBAAsB;IACtC,kBAAkB,EAAE,0BAA0B;IAC9C,QAAQ,EAAE,gBAAgB;CAClB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { VaultProviderId } from './types.js';
|
|
2
|
+
export interface VaultConfig {
|
|
3
|
+
/** master key 文件 (default: ~/.skillfm/vault.key) */
|
|
4
|
+
master_key_path?: string;
|
|
5
|
+
/** vault 加密文件 (default: ~/.skillfm/vault.enc) */
|
|
6
|
+
vault_path?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class Vault {
|
|
9
|
+
private master_key_path;
|
|
10
|
+
private vault_path;
|
|
11
|
+
private _master_key;
|
|
12
|
+
private _entries;
|
|
13
|
+
constructor(cfg?: VaultConfig);
|
|
14
|
+
/** 初始化: 加载 master key (没有则生成) + 加载 vault entries (没有则空) */
|
|
15
|
+
init(): Promise<void>;
|
|
16
|
+
put(provider: VaultProviderId, key: string): Promise<void>;
|
|
17
|
+
get(provider: VaultProviderId): Promise<string | null>;
|
|
18
|
+
list(): Promise<VaultProviderId[]>;
|
|
19
|
+
delete(provider: VaultProviderId): Promise<boolean>;
|
|
20
|
+
/** 轮换 master key — 重生成 master key + 重加密所有 entries */
|
|
21
|
+
rotate(): Promise<void>;
|
|
22
|
+
/** 验证 vault 是否健康 (能解密) */
|
|
23
|
+
health(): Promise<{
|
|
24
|
+
ok: boolean;
|
|
25
|
+
entry_count: number;
|
|
26
|
+
error?: string;
|
|
27
|
+
}>;
|
|
28
|
+
private ensureDir;
|
|
29
|
+
private ensureInitialized;
|
|
30
|
+
private loadOrCreateMasterKey;
|
|
31
|
+
private loadEntries;
|
|
32
|
+
private saveEntries;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=vault.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../src/vault/vault.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAA6B,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7E,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,qBAAa,KAAK;IAChB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAA6B;gBAEjC,GAAG,CAAC,EAAE,WAAW;IAK7B,2DAA2D;IACrD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1D,GAAG,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKtD,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAKlC,MAAM,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAUzD,qDAAqD;IAC/C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7B,0BAA0B;IACpB,MAAM,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;YAe/D,SAAS;YAST,iBAAiB;YAMjB,qBAAqB;YAkBrB,WAAW;YAwBX,WAAW;CAsB1B"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/vault/vault.ts
|
|
2
|
+
//
|
|
3
|
+
// Vault 主 API — put / get / list / delete / rotate
|
|
4
|
+
// 文件持久化: master key (~/.skillfm/vault.key chmod 0600) + vault.enc (加密 JSON)
|
|
5
|
+
// 异步 (非阻塞 IO)
|
|
6
|
+
import { promises as fs } from 'node:fs';
|
|
7
|
+
import { homedir } from 'node:os';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { encrypt, decrypt, generateMasterKey } from './crypto.js';
|
|
10
|
+
import { VaultError, VAULT_ERROR_CODES } from './types.js';
|
|
11
|
+
const DEFAULT_DIR = path.join(homedir(), '.skillfm');
|
|
12
|
+
const DEFAULT_MASTER_KEY = path.join(DEFAULT_DIR, 'vault.key');
|
|
13
|
+
const DEFAULT_VAULT = path.join(DEFAULT_DIR, 'vault.enc');
|
|
14
|
+
export class Vault {
|
|
15
|
+
master_key_path;
|
|
16
|
+
vault_path;
|
|
17
|
+
_master_key = null;
|
|
18
|
+
_entries = null;
|
|
19
|
+
constructor(cfg) {
|
|
20
|
+
this.master_key_path = cfg?.master_key_path ?? DEFAULT_MASTER_KEY;
|
|
21
|
+
this.vault_path = cfg?.vault_path ?? DEFAULT_VAULT;
|
|
22
|
+
}
|
|
23
|
+
/** 初始化: 加载 master key (没有则生成) + 加载 vault entries (没有则空) */
|
|
24
|
+
async init() {
|
|
25
|
+
await this.ensureDir();
|
|
26
|
+
this._master_key = await this.loadOrCreateMasterKey();
|
|
27
|
+
this._entries = await this.loadEntries();
|
|
28
|
+
}
|
|
29
|
+
async put(provider, key) {
|
|
30
|
+
await this.ensureInitialized();
|
|
31
|
+
this._entries[provider] = key;
|
|
32
|
+
await this.saveEntries();
|
|
33
|
+
}
|
|
34
|
+
async get(provider) {
|
|
35
|
+
await this.ensureInitialized();
|
|
36
|
+
return this._entries[provider] ?? null;
|
|
37
|
+
}
|
|
38
|
+
async list() {
|
|
39
|
+
await this.ensureInitialized();
|
|
40
|
+
return Object.keys(this._entries).sort();
|
|
41
|
+
}
|
|
42
|
+
async delete(provider) {
|
|
43
|
+
await this.ensureInitialized();
|
|
44
|
+
if (provider in this._entries) {
|
|
45
|
+
delete this._entries[provider];
|
|
46
|
+
await this.saveEntries();
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
/** 轮换 master key — 重生成 master key + 重加密所有 entries */
|
|
52
|
+
async rotate() {
|
|
53
|
+
await this.ensureInitialized();
|
|
54
|
+
const new_key = generateMasterKey();
|
|
55
|
+
await fs.writeFile(this.master_key_path, new_key, { mode: 0o600 });
|
|
56
|
+
this._master_key = new_key;
|
|
57
|
+
await this.saveEntries();
|
|
58
|
+
}
|
|
59
|
+
/** 验证 vault 是否健康 (能解密) */
|
|
60
|
+
async health() {
|
|
61
|
+
try {
|
|
62
|
+
await this.ensureInitialized();
|
|
63
|
+
return { ok: true, entry_count: Object.keys(this._entries).length };
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
return {
|
|
67
|
+
ok: false,
|
|
68
|
+
entry_count: 0,
|
|
69
|
+
error: e instanceof Error ? e.message : String(e),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ────────────────────────── private ──────────────────────────
|
|
74
|
+
async ensureDir() {
|
|
75
|
+
const dir = path.dirname(this.master_key_path);
|
|
76
|
+
try {
|
|
77
|
+
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
throw new VaultError(VAULT_ERROR_CODES.IO_ERROR, `mkdir ${dir}: ${e instanceof Error ? e.message : e}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async ensureInitialized() {
|
|
84
|
+
if (!this._master_key || !this._entries) {
|
|
85
|
+
await this.init();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async loadOrCreateMasterKey() {
|
|
89
|
+
try {
|
|
90
|
+
const buf = await fs.readFile(this.master_key_path);
|
|
91
|
+
if (buf.length !== 32) {
|
|
92
|
+
throw new VaultError(VAULT_ERROR_CODES.MASTER_KEY_INVALID, `master key length ${buf.length} != 32`);
|
|
93
|
+
}
|
|
94
|
+
return buf;
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
// 不存在 → 生成新的
|
|
98
|
+
if (e.code === 'ENOENT') {
|
|
99
|
+
const new_key = generateMasterKey();
|
|
100
|
+
await fs.writeFile(this.master_key_path, new_key, { mode: 0o600 });
|
|
101
|
+
return new_key;
|
|
102
|
+
}
|
|
103
|
+
throw e;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async loadEntries() {
|
|
107
|
+
try {
|
|
108
|
+
const raw = await fs.readFile(this.vault_path, 'utf8');
|
|
109
|
+
const file = JSON.parse(raw);
|
|
110
|
+
if (file.version !== 1) {
|
|
111
|
+
throw new VaultError(VAULT_ERROR_CODES.VAULT_FILE_CORRUPTED, `unsupported version ${file.version}`);
|
|
112
|
+
}
|
|
113
|
+
const plain = decrypt({ iv_b64: file.iv, auth_tag_b64: file.auth_tag, ciphertext_b64: file.ciphertext }, this._master_key);
|
|
114
|
+
return JSON.parse(plain);
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
if (e.code === 'ENOENT') {
|
|
118
|
+
return {}; // 第一次, 空 vault
|
|
119
|
+
}
|
|
120
|
+
if (e instanceof VaultError)
|
|
121
|
+
throw e;
|
|
122
|
+
throw new VaultError(VAULT_ERROR_CODES.VAULT_FILE_CORRUPTED, `load vault: ${e instanceof Error ? e.message : e}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async saveEntries() {
|
|
126
|
+
const plain = JSON.stringify(this._entries);
|
|
127
|
+
const enc = encrypt(plain, this._master_key);
|
|
128
|
+
const now = new Date().toISOString();
|
|
129
|
+
let created_at = now;
|
|
130
|
+
try {
|
|
131
|
+
const existing = await fs.readFile(this.vault_path, 'utf8');
|
|
132
|
+
const f = JSON.parse(existing);
|
|
133
|
+
created_at = f.created_at ?? now;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
/* 第一次写, created_at = now */
|
|
137
|
+
}
|
|
138
|
+
const file = {
|
|
139
|
+
version: 1,
|
|
140
|
+
iv: enc.iv_b64,
|
|
141
|
+
auth_tag: enc.auth_tag_b64,
|
|
142
|
+
ciphertext: enc.ciphertext_b64,
|
|
143
|
+
created_at,
|
|
144
|
+
updated_at: now,
|
|
145
|
+
};
|
|
146
|
+
await fs.writeFile(this.vault_path, JSON.stringify(file, null, 2), { mode: 0o600 });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/vault/vault.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillfm/local",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "SkillFM local
|
|
3
|
+
"version": "2.7.1",
|
|
4
|
+
"description": "SkillFM local — single npm package for the SkillFM platform on user nodes. Subcommand router exposes (1) Beacon MCP stdio server (cost-optimizer for any agent; merged in from @skillfm/beacon-mcp on 2026-05-01), (2) skill runtime (BYOK Playwright / brain reverse-tunnel), (3) sidecar HTTP proxy + OAuth 2.1 device-flow activation. Writes ~/.skillfm/local.json for service discovery.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -10,9 +10,17 @@
|
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"import": "./dist/index.js"
|
|
12
12
|
},
|
|
13
|
+
"./mcp": {
|
|
14
|
+
"types": "./dist/mcp/index.d.ts",
|
|
15
|
+
"import": "./dist/mcp/index.js"
|
|
16
|
+
},
|
|
13
17
|
"./mcp-stdio": {
|
|
14
18
|
"types": "./dist/mcp-stdio/server.d.ts",
|
|
15
19
|
"import": "./dist/mcp-stdio/server.js"
|
|
20
|
+
},
|
|
21
|
+
"./connectors": {
|
|
22
|
+
"types": "./dist/connectors/index.d.ts",
|
|
23
|
+
"import": "./dist/connectors/index.js"
|
|
16
24
|
}
|
|
17
25
|
},
|
|
18
26
|
"files": [
|
|
@@ -31,19 +39,23 @@
|
|
|
31
39
|
"localhost",
|
|
32
40
|
"agent-native",
|
|
33
41
|
"mcp",
|
|
42
|
+
"model-context-protocol",
|
|
43
|
+
"beacon",
|
|
44
|
+
"cost-optimizer",
|
|
45
|
+
"byok",
|
|
34
46
|
"bootstrap"
|
|
35
47
|
],
|
|
36
48
|
"scripts": {
|
|
37
49
|
"build": "tsc",
|
|
38
|
-
"vendor:contracts": "node scripts/inline-contracts.ts",
|
|
50
|
+
"vendor:contracts": "node scripts/inline-contracts.ts && tsx scripts/inline-mcp-contracts.ts",
|
|
39
51
|
"prebuild": "npm run vendor:contracts",
|
|
40
52
|
"dev": "tsx src/index.ts",
|
|
41
53
|
"typecheck": "tsc --noEmit",
|
|
42
54
|
"start": "node dist/index.js start",
|
|
43
55
|
"prepublishOnly": "npm run build && bash scripts/verify-no-bare-workspace-imports.sh dist",
|
|
44
|
-
"test": "tsx --test src/harness/detector.test.ts src/harness/priming.test.ts src/harness/writers.test.ts src/guard/state.test.ts src/soul.test.ts src/soul-security.test.ts src/harness/kernels/registry.test.ts src/harness/kernels/deny-pipeline.test.ts src/mcp-output/builder.test.ts src/mcp-output/deny-review.test.ts src/mcp-output/integration.test.ts src/skill-md/template.test.ts src/skill-md/writer.test.ts src/mcp-stdio/smoke.test.ts src/mcp-stdio/render-flow.contract.test.ts src/mcp-stdio/render-aha.test.ts src/mcp-stdio/sse-progress-client.test.ts src/mcp-stdio/parse-tolerant-json.test.ts src/self-upgrade.test.ts src/skill-tunnel/local-bridge.test.ts src/skill-tunnel/client.test.ts src/skill-runner/discovery.test.ts src/skill-installer/index.test.ts src/_dist-no-external-contracts.test.ts",
|
|
56
|
+
"test": "tsx --test src/harness/detector.test.ts src/harness/priming.test.ts src/harness/writers.test.ts src/guard/state.test.ts src/soul.test.ts src/soul-security.test.ts src/harness/kernels/registry.test.ts src/harness/kernels/deny-pipeline.test.ts src/mcp-output/builder.test.ts src/mcp-output/deny-review.test.ts src/mcp-output/integration.test.ts src/skill-md/template.test.ts src/skill-md/writer.test.ts src/mcp-stdio/smoke.test.ts src/mcp-stdio/render-flow.contract.test.ts src/mcp-stdio/render-aha.test.ts src/mcp-stdio/sse-progress-client.test.ts src/mcp-stdio/parse-tolerant-json.test.ts src/self-upgrade.test.ts src/skill-tunnel/local-bridge.test.ts src/skill-tunnel/client.test.ts src/skill-runner/discovery.test.ts src/skill-installer/index.test.ts src/_dist-no-external-contracts.test.ts src/mcp/server-boot.test.ts src/connectors/connectors.test.ts src/asset-connectors/asset-connectors.test.ts src/saas-connectors/saas-connectors.test.ts src/router/router.test.ts src/vault/vault.test.ts src/scheduler/scheduler.test.ts src/_signers/signers.test.ts src/memory/memory.test.ts src/mcp/tools/memory-tools.test.ts",
|
|
45
57
|
"test:acceptance": "npm run build && bash scripts/acceptance-matrix.sh",
|
|
46
|
-
"postpublish": "curl -sS -m 10 -X PUT 'https://registry.npmmirror.com/-/package/@skillfm/local/syncs?sync_upstream=true' > /dev/null && echo '
|
|
58
|
+
"postpublish": "curl -sS -m 10 -X PUT 'https://registry.npmmirror.com/-/package/@skillfm/local/syncs?sync_upstream=true' > /dev/null && echo '✓ npmmirror sync triggered' || echo '⚠ npmmirror sync failed (非阻塞,可手动触发)'"
|
|
47
59
|
},
|
|
48
60
|
"dependencies": {
|
|
49
61
|
"@modelcontextprotocol/sdk": "^1.0.0",
|