@skillfm/local 2.6.4 → 2.7.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.
Files changed (290) hide show
  1. package/README.md +50 -1
  2. package/dist/_signers/aliyun-v3.d.ts +21 -0
  3. package/dist/_signers/aliyun-v3.d.ts.map +1 -0
  4. package/dist/_signers/aliyun-v3.js +47 -0
  5. package/dist/_signers/aliyun-v3.js.map +1 -0
  6. package/dist/_signers/canonical.d.ts +29 -0
  7. package/dist/_signers/canonical.d.ts.map +1 -0
  8. package/dist/_signers/canonical.js +59 -0
  9. package/dist/_signers/canonical.js.map +1 -0
  10. package/dist/_signers/index.d.ts +9 -0
  11. package/dist/_signers/index.d.ts.map +1 -0
  12. package/dist/_signers/index.js +6 -0
  13. package/dist/_signers/index.js.map +1 -0
  14. package/dist/_signers/tencent-tc3.d.ts +21 -0
  15. package/dist/_signers/tencent-tc3.d.ts.map +1 -0
  16. package/dist/_signers/tencent-tc3.js +48 -0
  17. package/dist/_signers/tencent-tc3.js.map +1 -0
  18. package/dist/_signers/volc-v4.d.ts +18 -0
  19. package/dist/_signers/volc-v4.d.ts.map +1 -0
  20. package/dist/_signers/volc-v4.js +43 -0
  21. package/dist/_signers/volc-v4.js.map +1 -0
  22. package/dist/asset-connectors/aliyun-ecs.d.ts +18 -0
  23. package/dist/asset-connectors/aliyun-ecs.d.ts.map +1 -0
  24. package/dist/asset-connectors/aliyun-ecs.js +99 -0
  25. package/dist/asset-connectors/aliyun-ecs.js.map +1 -0
  26. package/dist/asset-connectors/base.d.ts +15 -0
  27. package/dist/asset-connectors/base.d.ts.map +1 -0
  28. package/dist/asset-connectors/base.js +19 -0
  29. package/dist/asset-connectors/base.js.map +1 -0
  30. package/dist/asset-connectors/cloudflare.d.ts +18 -0
  31. package/dist/asset-connectors/cloudflare.d.ts.map +1 -0
  32. package/dist/asset-connectors/cloudflare.js +94 -0
  33. package/dist/asset-connectors/cloudflare.js.map +1 -0
  34. package/dist/asset-connectors/digitalocean.d.ts +18 -0
  35. package/dist/asset-connectors/digitalocean.d.ts.map +1 -0
  36. package/dist/asset-connectors/digitalocean.js +79 -0
  37. package/dist/asset-connectors/digitalocean.js.map +1 -0
  38. package/dist/asset-connectors/godaddy.d.ts +18 -0
  39. package/dist/asset-connectors/godaddy.d.ts.map +1 -0
  40. package/dist/asset-connectors/godaddy.js +62 -0
  41. package/dist/asset-connectors/godaddy.js.map +1 -0
  42. package/dist/asset-connectors/hetzner.d.ts +18 -0
  43. package/dist/asset-connectors/hetzner.d.ts.map +1 -0
  44. package/dist/asset-connectors/hetzner.js +52 -0
  45. package/dist/asset-connectors/hetzner.js.map +1 -0
  46. package/dist/asset-connectors/index.d.ts +18 -0
  47. package/dist/asset-connectors/index.d.ts.map +1 -0
  48. package/dist/asset-connectors/index.js +52 -0
  49. package/dist/asset-connectors/index.js.map +1 -0
  50. package/dist/asset-connectors/namecheap.d.ts +34 -0
  51. package/dist/asset-connectors/namecheap.d.ts.map +1 -0
  52. package/dist/asset-connectors/namecheap.js +178 -0
  53. package/dist/asset-connectors/namecheap.js.map +1 -0
  54. package/dist/asset-connectors/ssl-labs.d.ts +22 -0
  55. package/dist/asset-connectors/ssl-labs.d.ts.map +1 -0
  56. package/dist/asset-connectors/ssl-labs.js +79 -0
  57. package/dist/asset-connectors/ssl-labs.js.map +1 -0
  58. package/dist/asset-connectors/tencent-cvm.d.ts +18 -0
  59. package/dist/asset-connectors/tencent-cvm.d.ts.map +1 -0
  60. package/dist/asset-connectors/tencent-cvm.js +145 -0
  61. package/dist/asset-connectors/tencent-cvm.js.map +1 -0
  62. package/dist/asset-connectors/types.d.ts +45 -0
  63. package/dist/asset-connectors/types.d.ts.map +1 -0
  64. package/dist/asset-connectors/types.js +26 -0
  65. package/dist/asset-connectors/types.js.map +1 -0
  66. package/dist/asset-connectors/vultr.d.ts +18 -0
  67. package/dist/asset-connectors/vultr.d.ts.map +1 -0
  68. package/dist/asset-connectors/vultr.js +73 -0
  69. package/dist/asset-connectors/vultr.js.map +1 -0
  70. package/dist/connectors/anthropic.d.ts +10 -0
  71. package/dist/connectors/anthropic.d.ts.map +1 -0
  72. package/dist/connectors/anthropic.js +103 -0
  73. package/dist/connectors/anthropic.js.map +1 -0
  74. package/dist/connectors/base.d.ts +11 -0
  75. package/dist/connectors/base.d.ts.map +1 -0
  76. package/dist/connectors/base.js +19 -0
  77. package/dist/connectors/base.js.map +1 -0
  78. package/dist/connectors/deepseek.d.ts +14 -0
  79. package/dist/connectors/deepseek.d.ts.map +1 -0
  80. package/dist/connectors/deepseek.js +77 -0
  81. package/dist/connectors/deepseek.js.map +1 -0
  82. package/dist/connectors/doubao.d.ts +10 -0
  83. package/dist/connectors/doubao.d.ts.map +1 -0
  84. package/dist/connectors/doubao.js +64 -0
  85. package/dist/connectors/doubao.js.map +1 -0
  86. package/dist/connectors/index.d.ts +14 -0
  87. package/dist/connectors/index.d.ts.map +1 -0
  88. package/dist/connectors/index.js +42 -0
  89. package/dist/connectors/index.js.map +1 -0
  90. package/dist/connectors/kimi.d.ts +10 -0
  91. package/dist/connectors/kimi.d.ts.map +1 -0
  92. package/dist/connectors/kimi.js +67 -0
  93. package/dist/connectors/kimi.js.map +1 -0
  94. package/dist/connectors/openai.d.ts +10 -0
  95. package/dist/connectors/openai.d.ts.map +1 -0
  96. package/dist/connectors/openai.js +101 -0
  97. package/dist/connectors/openai.js.map +1 -0
  98. package/dist/connectors/qwen.d.ts +10 -0
  99. package/dist/connectors/qwen.d.ts.map +1 -0
  100. package/dist/connectors/qwen.js +66 -0
  101. package/dist/connectors/qwen.js.map +1 -0
  102. package/dist/connectors/types.d.ts +47 -0
  103. package/dist/connectors/types.d.ts.map +1 -0
  104. package/dist/connectors/types.js +24 -0
  105. package/dist/connectors/types.js.map +1 -0
  106. package/dist/guard/bin.js +0 -0
  107. package/dist/index.js +50 -1
  108. package/dist/index.js.map +1 -1
  109. package/dist/mcp/_vendored-contracts/beacon-mcp-tools-v1.d.ts +373 -0
  110. package/dist/mcp/_vendored-contracts/beacon-mcp-tools-v1.d.ts.map +1 -0
  111. package/dist/mcp/_vendored-contracts/beacon-mcp-tools-v1.js +128 -0
  112. package/dist/mcp/_vendored-contracts/beacon-mcp-tools-v1.js.map +1 -0
  113. package/dist/mcp/brain-client.d.ts +96 -0
  114. package/dist/mcp/brain-client.d.ts.map +1 -0
  115. package/dist/mcp/brain-client.js +214 -0
  116. package/dist/mcp/brain-client.js.map +1 -0
  117. package/dist/mcp/cache.d.ts +55 -0
  118. package/dist/mcp/cache.d.ts.map +1 -0
  119. package/dist/mcp/cache.js +109 -0
  120. package/dist/mcp/cache.js.map +1 -0
  121. package/dist/mcp/config.d.ts +29 -0
  122. package/dist/mcp/config.d.ts.map +1 -0
  123. package/dist/mcp/config.js +69 -0
  124. package/dist/mcp/config.js.map +1 -0
  125. package/dist/mcp/decision-engine.d.ts +54 -0
  126. package/dist/mcp/decision-engine.d.ts.map +1 -0
  127. package/dist/mcp/decision-engine.js +107 -0
  128. package/dist/mcp/decision-engine.js.map +1 -0
  129. package/dist/mcp/errors.d.ts +66 -0
  130. package/dist/mcp/errors.d.ts.map +1 -0
  131. package/dist/mcp/errors.js +127 -0
  132. package/dist/mcp/errors.js.map +1 -0
  133. package/dist/mcp/index.d.ts +40 -0
  134. package/dist/mcp/index.d.ts.map +1 -0
  135. package/dist/mcp/index.js +98 -0
  136. package/dist/mcp/index.js.map +1 -0
  137. package/dist/mcp/tools/_placeholder.d.ts +24 -0
  138. package/dist/mcp/tools/_placeholder.d.ts.map +1 -0
  139. package/dist/mcp/tools/_placeholder.js +29 -0
  140. package/dist/mcp/tools/_placeholder.js.map +1 -0
  141. package/dist/mcp/tools/avatar-market.d.ts +22 -0
  142. package/dist/mcp/tools/avatar-market.d.ts.map +1 -0
  143. package/dist/mcp/tools/avatar-market.js +33 -0
  144. package/dist/mcp/tools/avatar-market.js.map +1 -0
  145. package/dist/mcp/tools/check-expiry.d.ts +23 -0
  146. package/dist/mcp/tools/check-expiry.d.ts.map +1 -0
  147. package/dist/mcp/tools/check-expiry.js +29 -0
  148. package/dist/mcp/tools/check-expiry.js.map +1 -0
  149. package/dist/mcp/tools/check-usage.d.ts +25 -0
  150. package/dist/mcp/tools/check-usage.d.ts.map +1 -0
  151. package/dist/mcp/tools/check-usage.js +33 -0
  152. package/dist/mcp/tools/check-usage.js.map +1 -0
  153. package/dist/mcp/tools/get-monthly-picks.d.ts +25 -0
  154. package/dist/mcp/tools/get-monthly-picks.d.ts.map +1 -0
  155. package/dist/mcp/tools/get-monthly-picks.js +35 -0
  156. package/dist/mcp/tools/get-monthly-picks.js.map +1 -0
  157. package/dist/mcp/tools/index.d.ts +41 -0
  158. package/dist/mcp/tools/index.d.ts.map +1 -0
  159. package/dist/mcp/tools/index.js +139 -0
  160. package/dist/mcp/tools/index.js.map +1 -0
  161. package/dist/mcp/tools/memory-recent.d.ts +17 -0
  162. package/dist/mcp/tools/memory-recent.d.ts.map +1 -0
  163. package/dist/mcp/tools/memory-recent.js +46 -0
  164. package/dist/mcp/tools/memory-recent.js.map +1 -0
  165. package/dist/mcp/tools/memory-save.d.ts +15 -0
  166. package/dist/mcp/tools/memory-save.d.ts.map +1 -0
  167. package/dist/mcp/tools/memory-save.js +53 -0
  168. package/dist/mcp/tools/memory-save.js.map +1 -0
  169. package/dist/mcp/tools/memory-search.d.ts +24 -0
  170. package/dist/mcp/tools/memory-search.d.ts.map +1 -0
  171. package/dist/mcp/tools/memory-search.js +64 -0
  172. package/dist/mcp/tools/memory-search.js.map +1 -0
  173. package/dist/mcp/tools/record-acceptance.d.ts +22 -0
  174. package/dist/mcp/tools/record-acceptance.d.ts.map +1 -0
  175. package/dist/mcp/tools/record-acceptance.js +33 -0
  176. package/dist/mcp/tools/record-acceptance.js.map +1 -0
  177. package/dist/mcp/tools/record-rejection.d.ts +23 -0
  178. package/dist/mcp/tools/record-rejection.d.ts.map +1 -0
  179. package/dist/mcp/tools/record-rejection.js +34 -0
  180. package/dist/mcp/tools/record-rejection.js.map +1 -0
  181. package/dist/mcp/tools/suggest-route.d.ts +26 -0
  182. package/dist/mcp/tools/suggest-route.d.ts.map +1 -0
  183. package/dist/mcp/tools/suggest-route.js +56 -0
  184. package/dist/mcp/tools/suggest-route.js.map +1 -0
  185. package/dist/mcp/tools/user-preferences.d.ts +22 -0
  186. package/dist/mcp/tools/user-preferences.d.ts.map +1 -0
  187. package/dist/mcp/tools/user-preferences.js +63 -0
  188. package/dist/mcp/tools/user-preferences.js.map +1 -0
  189. package/dist/mcp-stdio/bin.js +0 -0
  190. package/dist/memory/index.d.ts +5 -0
  191. package/dist/memory/index.d.ts.map +1 -0
  192. package/dist/memory/index.js +4 -0
  193. package/dist/memory/index.js.map +1 -0
  194. package/dist/memory/mem0-client.d.ts +32 -0
  195. package/dist/memory/mem0-client.d.ts.map +1 -0
  196. package/dist/memory/mem0-client.js +161 -0
  197. package/dist/memory/mem0-client.js.map +1 -0
  198. package/dist/memory/types.d.ts +47 -0
  199. package/dist/memory/types.d.ts.map +1 -0
  200. package/dist/memory/types.js +20 -0
  201. package/dist/memory/types.js.map +1 -0
  202. package/dist/router/catalog.d.ts +4 -0
  203. package/dist/router/catalog.d.ts.map +1 -0
  204. package/dist/router/catalog.js +103 -0
  205. package/dist/router/catalog.js.map +1 -0
  206. package/dist/router/classifier.d.ts +5 -0
  207. package/dist/router/classifier.d.ts.map +1 -0
  208. package/dist/router/classifier.js +43 -0
  209. package/dist/router/classifier.js.map +1 -0
  210. package/dist/router/index.d.ts +7 -0
  211. package/dist/router/index.d.ts.map +1 -0
  212. package/dist/router/index.js +6 -0
  213. package/dist/router/index.js.map +1 -0
  214. package/dist/router/litellm-config.d.ts +34 -0
  215. package/dist/router/litellm-config.d.ts.map +1 -0
  216. package/dist/router/litellm-config.js +78 -0
  217. package/dist/router/litellm-config.js.map +1 -0
  218. package/dist/router/route.d.ts +3 -0
  219. package/dist/router/route.d.ts.map +1 -0
  220. package/dist/router/route.js +63 -0
  221. package/dist/router/route.js.map +1 -0
  222. package/dist/router/types.d.ts +36 -0
  223. package/dist/router/types.d.ts.map +1 -0
  224. package/dist/router/types.js +7 -0
  225. package/dist/router/types.js.map +1 -0
  226. package/dist/saas-connectors/base.d.ts +16 -0
  227. package/dist/saas-connectors/base.d.ts.map +1 -0
  228. package/dist/saas-connectors/base.js +16 -0
  229. package/dist/saas-connectors/base.js.map +1 -0
  230. package/dist/saas-connectors/brave.d.ts +19 -0
  231. package/dist/saas-connectors/brave.d.ts.map +1 -0
  232. package/dist/saas-connectors/brave.js +50 -0
  233. package/dist/saas-connectors/brave.js.map +1 -0
  234. package/dist/saas-connectors/fal.d.ts +15 -0
  235. package/dist/saas-connectors/fal.d.ts.map +1 -0
  236. package/dist/saas-connectors/fal.js +35 -0
  237. package/dist/saas-connectors/fal.js.map +1 -0
  238. package/dist/saas-connectors/index.d.ts +11 -0
  239. package/dist/saas-connectors/index.d.ts.map +1 -0
  240. package/dist/saas-connectors/index.js +32 -0
  241. package/dist/saas-connectors/index.js.map +1 -0
  242. package/dist/saas-connectors/replicate.d.ts +19 -0
  243. package/dist/saas-connectors/replicate.d.ts.map +1 -0
  244. package/dist/saas-connectors/replicate.js +43 -0
  245. package/dist/saas-connectors/replicate.js.map +1 -0
  246. package/dist/saas-connectors/serper.d.ts +19 -0
  247. package/dist/saas-connectors/serper.d.ts.map +1 -0
  248. package/dist/saas-connectors/serper.js +47 -0
  249. package/dist/saas-connectors/serper.js.map +1 -0
  250. package/dist/saas-connectors/types.d.ts +31 -0
  251. package/dist/saas-connectors/types.d.ts.map +1 -0
  252. package/dist/saas-connectors/types.js +6 -0
  253. package/dist/saas-connectors/types.js.map +1 -0
  254. package/dist/scheduler/index.d.ts +4 -0
  255. package/dist/scheduler/index.d.ts.map +1 -0
  256. package/dist/scheduler/index.js +4 -0
  257. package/dist/scheduler/index.js.map +1 -0
  258. package/dist/scheduler/poll.d.ts +4 -0
  259. package/dist/scheduler/poll.d.ts.map +1 -0
  260. package/dist/scheduler/poll.js +170 -0
  261. package/dist/scheduler/poll.js.map +1 -0
  262. package/dist/scheduler/scheduler.d.ts +18 -0
  263. package/dist/scheduler/scheduler.d.ts.map +1 -0
  264. package/dist/scheduler/scheduler.js +67 -0
  265. package/dist/scheduler/scheduler.js.map +1 -0
  266. package/dist/scheduler/types.d.ts +49 -0
  267. package/dist/scheduler/types.d.ts.map +1 -0
  268. package/dist/scheduler/types.js +14 -0
  269. package/dist/scheduler/types.js.map +1 -0
  270. package/dist/vault/cli.d.ts +2 -0
  271. package/dist/vault/cli.d.ts.map +1 -0
  272. package/dist/vault/cli.js +170 -0
  273. package/dist/vault/cli.js.map +1 -0
  274. package/dist/vault/crypto.d.ts +9 -0
  275. package/dist/vault/crypto.d.ts.map +1 -0
  276. package/dist/vault/crypto.js +54 -0
  277. package/dist/vault/crypto.js.map +1 -0
  278. package/dist/vault/index.d.ts +6 -0
  279. package/dist/vault/index.d.ts.map +1 -0
  280. package/dist/vault/index.js +5 -0
  281. package/dist/vault/index.js.map +1 -0
  282. package/dist/vault/types.d.ts +28 -0
  283. package/dist/vault/types.d.ts.map +1 -0
  284. package/dist/vault/types.js +22 -0
  285. package/dist/vault/types.js.map +1 -0
  286. package/dist/vault/vault.d.ts +34 -0
  287. package/dist/vault/vault.d.ts.map +1 -0
  288. package/dist/vault/vault.js +149 -0
  289. package/dist/vault/vault.js.map +1 -0
  290. package/package.json +17 -5
@@ -0,0 +1,178 @@
1
+ // sdk/skillfm-local/src/asset-connectors/namecheap.ts
2
+ //
3
+ // Namecheap connector — 域名时效真实现 (Day 4 B2)
4
+ // Doc: https://www.namecheap.com/support/api/methods/domains/get-list/
5
+ // Endpoint: GET https://api.namecheap.com/xml.response
6
+ // Auth: 4 个 query param + IP 白名单 (sandbox 不需 IP 白名单)
7
+ // ApiUser, ApiKey, UserName, ClientIp + Command=namecheap.domains.getList
8
+ //
9
+ // byok_key 格式: "ApiUser:ApiKey:UserName" (3 段 colon 分隔, 缺一不可)
10
+ // ClientIp 实时从 sidecar 公网 IP 拿 (env BEACON_PUBLIC_IP 或 ifconfig.me 拉)
11
+ import { AssetBaseConnector } from './base.js';
12
+ import { daysUntil, classifyStatus } from './types.js';
13
+ import { sanitizeError } from '../connectors/types.js';
14
+ const PROD_URL = 'https://api.namecheap.com/xml.response';
15
+ const SANDBOX_URL = 'https://api.sandbox.namecheap.com/xml.response';
16
+ function parseKey(byok_key) {
17
+ const parts = byok_key.split(':');
18
+ if (parts.length !== 3 || parts.some((p) => !p)) {
19
+ throw new Error('Namecheap byok_key 格式应为 "ApiUser:ApiKey:UserName" (3 段 colon 分隔)');
20
+ }
21
+ return { api_user: parts[0], api_key: parts[1], user_name: parts[2] };
22
+ }
23
+ async function getPublicIp() {
24
+ if (process.env.BEACON_PUBLIC_IP)
25
+ return process.env.BEACON_PUBLIC_IP;
26
+ // 兜底: 拉 ifconfig.me. Day 5+ 启动时 cache 在 ~/.skillfm/local.json
27
+ try {
28
+ const r = await fetch('https://ifconfig.me/ip', { signal: AbortSignal.timeout(5000) });
29
+ const txt = (await r.text()).trim();
30
+ if (/^\d{1,3}(\.\d{1,3}){3}$/.test(txt))
31
+ return txt;
32
+ }
33
+ catch {
34
+ /* fallthrough */
35
+ }
36
+ throw new Error('Namecheap 需要 sidecar 公网 IP. 请设 BEACON_PUBLIC_IP env, ' +
37
+ '或确保 sidecar 能访问 ifconfig.me, 然后把该 IP 加 Namecheap dashboard 白名单');
38
+ }
39
+ /**
40
+ * 简单 XML parser (够用 Namecheap GetList response schema)
41
+ * <DomainGetListResult>
42
+ * <Domain ID="123" Name="example.com" Expires="01/05/2027" IsExpired="false" AutoRenew="true" .../>
43
+ * </DomainGetListResult>
44
+ */
45
+ function parseDomains(xml) {
46
+ const results = [];
47
+ // 检 error
48
+ const errMatch = xml.match(/<Error\s+Number="(\d+)">([^<]+)<\/Error>/);
49
+ if (errMatch) {
50
+ throw new Error(`Namecheap API error ${errMatch[1]}: ${errMatch[2]}`);
51
+ }
52
+ // 抽每个 <Domain ... /> 自闭合
53
+ // 用 [^>]*? 而非 [^/>]*? 因为 attribute 值可能含 "/" (如日期 "01/15/2027")
54
+ const domainRegex = /<Domain\s+([^>]*?)\/>/g;
55
+ let m;
56
+ while ((m = domainRegex.exec(xml)) !== null) {
57
+ const attrs = m[1];
58
+ const get = (k) => {
59
+ const r = new RegExp(`${k}="([^"]*)"`);
60
+ const a = attrs.match(r);
61
+ return a ? a[1] : null;
62
+ };
63
+ const name = get('Name');
64
+ if (!name)
65
+ continue;
66
+ const expires = get('Expires'); // "MM/DD/YYYY"
67
+ let expires_iso = null;
68
+ if (expires) {
69
+ const dm = expires.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
70
+ if (dm) {
71
+ const month = dm[1].padStart(2, '0');
72
+ const day = dm[2].padStart(2, '0');
73
+ expires_iso = `${dm[3]}-${month}-${day}T00:00:00Z`;
74
+ }
75
+ }
76
+ results.push({
77
+ id: get('ID') ?? '',
78
+ name,
79
+ expires_iso,
80
+ is_expired: get('IsExpired') === 'true',
81
+ auto_renew: get('AutoRenew') === 'true',
82
+ });
83
+ }
84
+ return results;
85
+ }
86
+ export class NamecheapConnector extends AssetBaseConnector {
87
+ id = 'namecheap';
88
+ name = 'Namecheap';
89
+ is_real = true;
90
+ /** sandbox 模式 (env BEACON_NAMECHEAP_SANDBOX=1) — sandbox 不需要 IP 白名单, 用于 CI 测试 */
91
+ getEndpoint() {
92
+ return process.env.BEACON_NAMECHEAP_SANDBOX === '1' ? SANDBOX_URL : PROD_URL;
93
+ }
94
+ async fetchAssets(byok_key, opts) {
95
+ let auth;
96
+ try {
97
+ auth = parseKey(byok_key);
98
+ }
99
+ catch (e) {
100
+ throw new Error(sanitizeError(e, byok_key));
101
+ }
102
+ const client_ip = await getPublicIp();
103
+ const params = new URLSearchParams({
104
+ ApiUser: auth.api_user,
105
+ ApiKey: auth.api_key,
106
+ UserName: auth.user_name,
107
+ ClientIp: client_ip,
108
+ Command: 'namecheap.domains.getList',
109
+ PageSize: String(Math.min(opts?.limit ?? 50, 100)), // Namecheap 最大 100/page
110
+ Page: '1',
111
+ });
112
+ const r = await this.safeFetch(`${this.getEndpoint()}?${params.toString()}`, { method: 'GET' }, byok_key);
113
+ if (!r.ok) {
114
+ const text = await r.text().catch(() => '');
115
+ throw new Error(sanitizeError(`Namecheap ${r.status}: ${text}`, byok_key));
116
+ }
117
+ const xml = await r.text();
118
+ const domains = parseDomains(xml);
119
+ const assets = [];
120
+ for (const d of domains) {
121
+ const days = daysUntil(d.expires_iso);
122
+ if (opts?.expiring_within_days !== undefined && days !== null && days > opts.expiring_within_days)
123
+ continue;
124
+ assets.push({
125
+ asset_type: 'domain',
126
+ identifier: d.id || d.name,
127
+ display_name: d.name,
128
+ expires_at: d.expires_iso,
129
+ days_left: days,
130
+ provider: this.id,
131
+ status: d.is_expired ? 'expired' : classifyStatus(days),
132
+ raw: { auto_renew: d.auto_renew },
133
+ });
134
+ }
135
+ return assets;
136
+ }
137
+ async ping(byok_key) {
138
+ const fp = this.fingerprint(byok_key);
139
+ try {
140
+ const auth = parseKey(byok_key);
141
+ const client_ip = await getPublicIp();
142
+ const params = new URLSearchParams({
143
+ ApiUser: auth.api_user,
144
+ ApiKey: auth.api_key,
145
+ UserName: auth.user_name,
146
+ ClientIp: client_ip,
147
+ Command: 'namecheap.domains.getList',
148
+ PageSize: '1',
149
+ Page: '1',
150
+ });
151
+ const r = await this.safeFetch(`${this.getEndpoint()}?${params.toString()}`, { method: 'GET' }, byok_key);
152
+ if (r.ok) {
153
+ const xml = await r.text();
154
+ // 校验返回是否含 IsSuccess="true"
155
+ if (/IsSuccess="true"/.test(xml))
156
+ return { ok: true, key_fingerprint: fp };
157
+ const errMatch = xml.match(/<Error[^>]*>([^<]+)<\/Error>/);
158
+ return {
159
+ ok: false,
160
+ error: errMatch ? `Namecheap: ${errMatch[1]}` : 'Namecheap response not success',
161
+ key_fingerprint: fp,
162
+ };
163
+ }
164
+ const text = await r.text().catch(() => '');
165
+ return {
166
+ ok: false,
167
+ error: `HTTP ${r.status}: ${sanitizeError(text, byok_key)}`,
168
+ key_fingerprint: fp,
169
+ };
170
+ }
171
+ catch (e) {
172
+ return { ok: false, error: sanitizeError(e, byok_key), key_fingerprint: fp };
173
+ }
174
+ }
175
+ }
176
+ // 暴露 parseDomains 供 test 使用
177
+ export { parseDomains as _parseDomainsForTest };
178
+ //# sourceMappingURL=namecheap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namecheap.js","sourceRoot":"","sources":["../../src/asset-connectors/namecheap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { AssetBaseConnector } from './base.js';
2
+ import type { AssetExpiry, AssetProviderId, FetchAssetsOptions } from './types.js';
3
+ export declare class SSLLabsConnector extends AssetBaseConnector {
4
+ id: AssetProviderId;
5
+ name: string;
6
+ is_real: boolean;
7
+ /**
8
+ * byok_key 实际是逗号分隔的域名列表 (e.g. "skillfm.ai,api.skillfm.ai")
9
+ * SSL Labs 不需要 auth key
10
+ */
11
+ fetchAssets(byok_key: string, opts?: FetchAssetsOptions): Promise<AssetExpiry[]>;
12
+ ping(_byok_key: string): Promise<{
13
+ ok: boolean;
14
+ key_fingerprint: string;
15
+ error?: undefined;
16
+ } | {
17
+ ok: boolean;
18
+ error: string;
19
+ key_fingerprint?: undefined;
20
+ }>;
21
+ }
22
+ //# sourceMappingURL=ssl-labs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssl-labs.d.ts","sourceRoot":"","sources":["../../src/asset-connectors/ssl-labs.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAsBnF,qBAAa,gBAAiB,SAAQ,kBAAkB;IACtD,EAAE,EAAE,eAAe,CAAc;IACjC,IAAI,SAAc;IAClB,OAAO,UAAQ;IAEf;;;OAGG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAgDhF,IAAI,CAAC,SAAS,EAAE,MAAM;;;;;;;;;CAS7B"}
@@ -0,0 +1,79 @@
1
+ // sdk/skillfm-local/src/asset-connectors/ssl-labs.ts
2
+ //
3
+ // SSL Labs connector — SSL 证书强度 + 到期分析 (Day 2 真实现)
4
+ // Doc: https://github.com/ssllabs/ssllabs-scan/blob/master/ssllabs-api-docs-v3.md
5
+ // Endpoint: GET /api/v3/analyze?host=<domain>
6
+ // Auth: 无 (SSL Labs 公开 API, 但有 rate limit ~25 scans/sec/IP)
7
+ //
8
+ // 用户在 ~/.skillfm/local.json (或 dashboard) 配置要监控的域名列表,
9
+ // 此 connector 不需要 BYOK key — fetchAssets 的第一参 byok_key 实际是逗号分隔的域名列表。
10
+ import { AssetBaseConnector } from './base.js';
11
+ import { daysUntil, classifyStatus } from './types.js';
12
+ const BASE_URL = 'https://api.ssllabs.com/api/v3';
13
+ export class SSLLabsConnector extends AssetBaseConnector {
14
+ id = 'ssl_labs';
15
+ name = 'SSL Labs';
16
+ is_real = true;
17
+ /**
18
+ * byok_key 实际是逗号分隔的域名列表 (e.g. "skillfm.ai,api.skillfm.ai")
19
+ * SSL Labs 不需要 auth key
20
+ */
21
+ async fetchAssets(byok_key, opts) {
22
+ const domains = (byok_key || '').split(',').map((s) => s.trim()).filter(Boolean);
23
+ const assets = [];
24
+ for (const host of domains.slice(0, opts?.limit ?? 10)) {
25
+ try {
26
+ // fromCache=on + maxAge=24 节省真扫描
27
+ const r = await this.safeFetch(`${BASE_URL}/analyze?host=${encodeURIComponent(host)}&fromCache=on&maxAge=24`, { method: 'GET', headers: { accept: 'application/json' } }, byok_key);
28
+ if (!r.ok)
29
+ continue;
30
+ const data = (await r.json());
31
+ if (data.status !== 'READY') {
32
+ assets.push({
33
+ asset_type: 'ssl',
34
+ identifier: host,
35
+ display_name: host,
36
+ expires_at: null,
37
+ days_left: null,
38
+ provider: this.id,
39
+ status: data.status === 'IN_PROGRESS' ? 'scanning' : 'error',
40
+ });
41
+ continue;
42
+ }
43
+ const cert = data.endpoints?.[0]?.details?.cert ?? data.certs?.[0];
44
+ if (!cert)
45
+ continue;
46
+ const expires_at = new Date(cert.notAfter).toISOString();
47
+ const days = daysUntil(expires_at);
48
+ if (opts?.expiring_within_days !== undefined && days !== null && days > opts.expiring_within_days)
49
+ continue;
50
+ assets.push({
51
+ asset_type: 'ssl',
52
+ identifier: host,
53
+ display_name: host,
54
+ expires_at,
55
+ days_left: days,
56
+ provider: this.id,
57
+ status: classifyStatus(days),
58
+ raw: { sig_alg: cert.sigAlg, grade: data.endpoints?.[0]?.grade },
59
+ });
60
+ }
61
+ catch {
62
+ // 单域名扫描失败不影响其他
63
+ }
64
+ }
65
+ return assets;
66
+ }
67
+ async ping(_byok_key) {
68
+ try {
69
+ const r = await this.safeFetch(`${BASE_URL}/info`, { method: 'GET' }, '');
70
+ if (r.ok)
71
+ return { ok: true, key_fingerprint: 'no-auth' };
72
+ return { ok: false, error: `HTTP ${r.status}` };
73
+ }
74
+ catch (e) {
75
+ return { ok: false, error: e instanceof Error ? e.message : String(e) };
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=ssl-labs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssl-labs.js","sourceRoot":"","sources":["../../src/asset-connectors/ssl-labs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { AssetBaseConnector } from './base.js';
2
+ import type { AssetExpiry, AssetProviderId, FetchAssetsOptions } from './types.js';
3
+ export declare class TencentCVMConnector extends AssetBaseConnector {
4
+ id: AssetProviderId;
5
+ name: string;
6
+ is_real: boolean;
7
+ fetchAssets(byok_key: string, opts?: FetchAssetsOptions): Promise<AssetExpiry[]>;
8
+ ping(byok_key: string): Promise<{
9
+ ok: boolean;
10
+ key_fingerprint: string;
11
+ error?: undefined;
12
+ } | {
13
+ ok: boolean;
14
+ error: string;
15
+ key_fingerprint: string;
16
+ }>;
17
+ }
18
+ //# sourceMappingURL=tencent-cvm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tencent-cvm.d.ts","sourceRoot":"","sources":["../../src/asset-connectors/tencent-cvm.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAwCnF,qBAAa,mBAAoB,SAAQ,kBAAkB;IACzD,EAAE,EAAE,eAAe,CAAiB;IACpC,IAAI,SAAa;IACjB,OAAO,UAAQ;IAET,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA+FhF,IAAI,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;CAmC5B"}
@@ -0,0 +1,145 @@
1
+ // sdk/skillfm-local/src/asset-connectors/tencent-cvm.ts
2
+ //
3
+ // 腾讯云 CVM connector — Day 4 真实现 (TC3-HMAC-SHA256)
4
+ // Doc: https://cloud.tencent.com/document/api/213/15728 (CVM)
5
+ // https://cloud.tencent.com/document/api/555/30334 (DescribeAccountBalance)
6
+ // Auth: SecretId + SecretKey + 腾讯云 TC3-HMAC-SHA256
7
+ //
8
+ // byok_key 格式: "<SecretId>:<SecretKey>" (colon 分隔)
9
+ import { AssetBaseConnector } from './base.js';
10
+ import { sanitizeError } from '../connectors/types.js';
11
+ import { signTencentTC3 } from '../_signers/index.js';
12
+ const CVM_HOST = 'cvm.tencentcloudapi.com';
13
+ const BILLING_HOST = 'billing.tencentcloudapi.com';
14
+ function splitKey(byok_key) {
15
+ const idx = byok_key.indexOf(':');
16
+ if (idx <= 0 || idx === byok_key.length - 1) {
17
+ throw new Error('腾讯云 byok_key 格式应为 "<SecretId>:<SecretKey>"');
18
+ }
19
+ return { ak_id: byok_key.slice(0, idx), ak_secret: byok_key.slice(idx + 1) };
20
+ }
21
+ export class TencentCVMConnector extends AssetBaseConnector {
22
+ id = 'tencent_cvm';
23
+ name = '腾讯云 CVM';
24
+ is_real = true;
25
+ async fetchAssets(byok_key, opts) {
26
+ let ak;
27
+ try {
28
+ ak = splitKey(byok_key);
29
+ }
30
+ catch (e) {
31
+ throw new Error(sanitizeError(e, byok_key));
32
+ }
33
+ const assets = [];
34
+ // 1. 账户余额 (DescribeAccountBalance, billing service)
35
+ try {
36
+ const payload = JSON.stringify({});
37
+ const signed = signTencentTC3({
38
+ method: 'POST',
39
+ host: BILLING_HOST,
40
+ path: '/',
41
+ query: {},
42
+ headers: {},
43
+ payload,
44
+ ak_id: ak.ak_id,
45
+ ak_secret: ak.ak_secret,
46
+ service: 'billing',
47
+ action: 'DescribeAccountBalance',
48
+ version: '2018-07-09',
49
+ });
50
+ const r = await this.safeFetch(`https://${BILLING_HOST}/`, { method: 'POST', headers: signed.signed_headers_with_signature, body: payload }, byok_key);
51
+ if (r.ok) {
52
+ const d = (await r.json());
53
+ if (d.Response?.Balance !== undefined && !d.Response.Error) {
54
+ // Balance 单位 cent (分), CNY → USD ≈ /730
55
+ const balance_usd = (d.Response.Balance ?? 0) / 100 / 7.3;
56
+ assets.push({
57
+ asset_type: 'api_credit',
58
+ identifier: 'tencent-account-balance',
59
+ display_name: `腾讯云账户余额 (Uin ${d.Response.Uin ?? 'unknown'})`,
60
+ expires_at: null,
61
+ days_left: null,
62
+ provider: this.id,
63
+ balance_usd,
64
+ status: 'active',
65
+ });
66
+ }
67
+ }
68
+ }
69
+ catch {
70
+ /* tolerate */
71
+ }
72
+ // 2. CVM 实例列表
73
+ const cvmPayload = JSON.stringify({ Limit: opts?.limit ?? 50, Offset: 0 });
74
+ const signed = signTencentTC3({
75
+ method: 'POST',
76
+ host: CVM_HOST,
77
+ path: '/',
78
+ query: {},
79
+ headers: {},
80
+ payload: cvmPayload,
81
+ ak_id: ak.ak_id,
82
+ ak_secret: ak.ak_secret,
83
+ service: 'cvm',
84
+ region: 'ap-shanghai',
85
+ action: 'DescribeInstances',
86
+ version: '2017-03-12',
87
+ });
88
+ const r = await this.safeFetch(`https://${CVM_HOST}/`, { method: 'POST', headers: signed.signed_headers_with_signature, body: cvmPayload }, byok_key);
89
+ if (!r.ok) {
90
+ const text = await r.text().catch(() => '');
91
+ throw new Error(sanitizeError(`腾讯云 CVM ${r.status}: ${text}`, byok_key));
92
+ }
93
+ const data = (await r.json());
94
+ if (data.Response?.Error) {
95
+ throw new Error(sanitizeError(`腾讯云 CVM ${data.Response.Error.Code}: ${data.Response.Error.Message}`, byok_key));
96
+ }
97
+ for (const i of data.Response?.InstanceSet ?? []) {
98
+ assets.push({
99
+ asset_type: 'vps',
100
+ identifier: i.InstanceId,
101
+ display_name: i.InstanceName || i.InstanceId,
102
+ expires_at: null,
103
+ days_left: null,
104
+ provider: this.id,
105
+ status: i.InstanceState,
106
+ raw: { instance_type: i.InstanceType, zone: i.Placement?.Zone, created: i.CreatedTime },
107
+ });
108
+ }
109
+ return assets;
110
+ }
111
+ async ping(byok_key) {
112
+ const fp = this.fingerprint(byok_key);
113
+ try {
114
+ const ak = splitKey(byok_key);
115
+ // DescribeAccountBalance 是最轻量验签
116
+ const payload = JSON.stringify({});
117
+ const signed = signTencentTC3({
118
+ method: 'POST',
119
+ host: BILLING_HOST,
120
+ path: '/',
121
+ query: {},
122
+ headers: {},
123
+ payload,
124
+ ak_id: ak.ak_id,
125
+ ak_secret: ak.ak_secret,
126
+ service: 'billing',
127
+ action: 'DescribeAccountBalance',
128
+ version: '2018-07-09',
129
+ });
130
+ const r = await this.safeFetch(`https://${BILLING_HOST}/`, { method: 'POST', headers: signed.signed_headers_with_signature, body: payload }, byok_key);
131
+ if (r.ok)
132
+ return { ok: true, key_fingerprint: fp };
133
+ const text = await r.text().catch(() => '');
134
+ return {
135
+ ok: false,
136
+ error: `HTTP ${r.status}: ${sanitizeError(text, byok_key)}`,
137
+ key_fingerprint: fp,
138
+ };
139
+ }
140
+ catch (e) {
141
+ return { ok: false, error: sanitizeError(e, byok_key), key_fingerprint: fp };
142
+ }
143
+ }
144
+ }
145
+ //# sourceMappingURL=tencent-cvm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tencent-cvm.js","sourceRoot":"","sources":["../../src/asset-connectors/tencent-cvm.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,kDAAkD;AAClD,8DAA8D;AAC9D,iFAAiF;AACjF,mDAAmD;AACnD,EAAE;AACF,mDAAmD;AAEnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,QAAQ,GAAG,yBAAyB,CAAC;AAC3C,MAAM,YAAY,GAAG,6BAA6B,CAAC;AA2BnD,SAAS,QAAQ,CAAC,QAAgB;IAChC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED,MAAM,OAAO,mBAAoB,SAAQ,kBAAkB;IACzD,EAAE,GAAoB,aAAa,CAAC;IACpC,IAAI,GAAG,SAAS,CAAC;IACjB,OAAO,GAAG,IAAI,CAAC;IAEf,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,IAAyB;QAC3D,IAAI,EAAwC,CAAC;QAC7C,IAAI,CAAC;YACH,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,MAAM,GAAkB,EAAE,CAAC;QAEjC,oDAAoD;QACpD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,cAAc,CAAC;gBAC5B,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,GAAG;gBACT,KAAK,EAAE,EAAE;gBACT,OAAO,EAAE,EAAE;gBACX,OAAO;gBACP,KAAK,EAAE,EAAE,CAAC,KAAK;gBACf,SAAS,EAAE,EAAE,CAAC,SAAS;gBACvB,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,wBAAwB;gBAChC,OAAO,EAAE,YAAY;aACtB,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,SAAS,CAC5B,WAAW,YAAY,GAAG,EAC1B,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,6BAA6B,EAAE,IAAI,EAAE,OAAO,EAAE,EAChF,QAAQ,CACT,CAAC;YACF,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;gBACT,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAA0C,CAAC;gBACpE,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;oBAC3D,wCAAwC;oBACxC,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;oBAC1D,MAAM,CAAC,IAAI,CAAC;wBACV,UAAU,EAAE,YAAY;wBACxB,UAAU,EAAE,yBAAyB;wBACrC,YAAY,EAAE,gBAAgB,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,SAAS,GAAG;wBAC5D,UAAU,EAAE,IAAI;wBAChB,SAAS,EAAE,IAAI;wBACf,QAAQ,EAAE,IAAI,CAAC,EAAE;wBACjB,WAAW;wBACX,MAAM,EAAE,QAAQ;qBACjB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;QAED,cAAc;QACd,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,cAAc,CAAC;YAC5B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,GAAG;YACT,KAAK,EAAE,EAAE;YACT,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,UAAU;YACnB,KAAK,EAAE,EAAE,CAAC,KAAK;YACf,SAAS,EAAE,EAAE,CAAC,SAAS;YACvB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,mBAAmB;YAC3B,OAAO,EAAE,YAAY;SACtB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,SAAS,CAC5B,WAAW,QAAQ,GAAG,EACtB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,6BAA6B,EAAE,IAAI,EAAE,UAAU,EAAE,EACnF,QAAQ,CACT,CAAC;QACF,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAiC,CAAC;QAC9D,IAAI,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;QAClH,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,WAAW,IAAI,EAAE,EAAE,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC;gBACV,UAAU,EAAE,KAAK;gBACjB,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,UAAU;gBAC5C,UAAU,EAAE,IAAI;gBAChB,SAAS,EAAE,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,EAAE;gBACjB,MAAM,EAAE,CAAC,CAAC,aAAa;gBACvB,GAAG,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,WAAW,EAAE;aACxF,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAgB;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC9B,gCAAgC;YAChC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,cAAc,CAAC;gBAC5B,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,GAAG;gBACT,KAAK,EAAE,EAAE;gBACT,OAAO,EAAE,EAAE;gBACX,OAAO;gBACP,KAAK,EAAE,EAAE,CAAC,KAAK;gBACf,SAAS,EAAE,EAAE,CAAC,SAAS;gBACvB,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,wBAAwB;gBAChC,OAAO,EAAE,YAAY;aACtB,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,SAAS,CAC5B,WAAW,YAAY,GAAG,EAC1B,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,6BAA6B,EAAE,IAAI,EAAE,OAAO,EAAE,EAChF,QAAQ,CACT,CAAC;YACF,IAAI,CAAC,CAAC,EAAE;gBAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;YACnD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC5C,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE;gBAC3D,eAAe,EAAE,EAAE;aACpB,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;QAC/E,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,45 @@
1
+ export type AssetType = 'domain' | 'ssl' | 'vps' | 'api_credit' | 'cdn_credit';
2
+ export type AssetProviderId = 'cloudflare' | 'godaddy' | 'namecheap' | 'ssl_labs' | 'hetzner' | 'digitalocean' | 'vultr' | 'aliyun_ecs' | 'tencent_cvm';
3
+ export interface AssetExpiry {
4
+ asset_type: AssetType;
5
+ /** 资源标识 (domain name / cert fingerprint / vps id) */
6
+ identifier: string;
7
+ /** 显示名 (e.g. example.com / vps "web-prod-01") */
8
+ display_name: string;
9
+ /** ISO 8601 到期时间 (null = 不到期 / 未知) */
10
+ expires_at: string | null;
11
+ /** 距离到期天数 (负数 = 已过期, null = 未知) */
12
+ days_left: number | null;
13
+ /** 提供商 */
14
+ provider: AssetProviderId;
15
+ /** 余额 (VPS / API credit), 单位 USD */
16
+ balance_usd?: number;
17
+ /** 状态描述 (e.g. "active" / "expiring_soon" / "expired" / "renewed") */
18
+ status?: string;
19
+ /** 原始响应 (调试用, 生产可省) */
20
+ raw?: unknown;
21
+ }
22
+ export interface FetchAssetsOptions {
23
+ /** 最多返回条数 */
24
+ limit?: number;
25
+ /** 仅查询 X 天内到期的 (省 API call) */
26
+ expiring_within_days?: number;
27
+ }
28
+ export interface AssetConnector {
29
+ id: AssetProviderId;
30
+ name: string;
31
+ is_real: boolean;
32
+ /** 拉资产时效列表 — 调用瞬间 BYOK key 注入,函数 scope 结束 GC */
33
+ fetchAssets(byok_key: string, opts?: FetchAssetsOptions): Promise<AssetExpiry[]>;
34
+ /** 验 key 有效性 */
35
+ ping(byok_key: string): Promise<{
36
+ ok: boolean;
37
+ error?: string;
38
+ key_fingerprint?: string;
39
+ }>;
40
+ }
41
+ /** 计算距离到期天数 */
42
+ export declare function daysUntil(iso: string | null): number | null;
43
+ /** 状态归类 */
44
+ export declare function classifyStatus(days_left: number | null): string;
45
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/asset-connectors/types.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,YAAY,GAAG,YAAY,CAAC;AAE/E,MAAM,MAAM,eAAe,GAEvB,YAAY,GACZ,SAAS,GACT,WAAW,GACX,UAAU,GAEV,SAAS,GACT,cAAc,GACd,OAAO,GACP,YAAY,GACZ,aAAa,CAAC;AAElB,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,SAAS,CAAC;IACtB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,mCAAmC;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU;IACV,QAAQ,EAAE,eAAe,CAAC;IAC1B,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,eAAe,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACjF,gBAAgB;IAChB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5F;AAED,eAAe;AACf,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAK3D;AAED,WAAW;AACX,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAM/D"}
@@ -0,0 +1,26 @@
1
+ // sdk/skillfm-local/src/asset-connectors/types.ts
2
+ //
3
+ // 数字资产时效 connector 共享类型 (Day 2 D2-2)
4
+ // 跟 LLM connectors 区分 — 这里关注 "expiry / balance" 不是 "token usage"
5
+ /** 计算距离到期天数 */
6
+ export function daysUntil(iso) {
7
+ if (!iso)
8
+ return null;
9
+ const t = new Date(iso).getTime();
10
+ if (isNaN(t))
11
+ return null;
12
+ return Math.floor((t - Date.now()) / 86400000);
13
+ }
14
+ /** 状态归类 */
15
+ export function classifyStatus(days_left) {
16
+ if (days_left === null)
17
+ return 'unknown';
18
+ if (days_left < 0)
19
+ return 'expired';
20
+ if (days_left <= 7)
21
+ return 'expiring_soon';
22
+ if (days_left <= 30)
23
+ return 'expiring_in_month';
24
+ return 'active';
25
+ }
26
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/asset-connectors/types.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,EAAE;AACF,qCAAqC;AACrC,iEAAiE;AAsDjE,eAAe;AACf,MAAM,UAAU,SAAS,CAAC,GAAkB;IAC1C,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED,WAAW;AACX,MAAM,UAAU,cAAc,CAAC,SAAwB;IACrD,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IACzC,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACpC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,eAAe,CAAC;IAC3C,IAAI,SAAS,IAAI,EAAE;QAAE,OAAO,mBAAmB,CAAC;IAChD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { AssetBaseConnector } from './base.js';
2
+ import type { AssetExpiry, AssetProviderId, FetchAssetsOptions } from './types.js';
3
+ export declare class VultrConnector extends AssetBaseConnector {
4
+ id: AssetProviderId;
5
+ name: string;
6
+ is_real: boolean;
7
+ fetchAssets(byok_key: string, opts?: FetchAssetsOptions): Promise<AssetExpiry[]>;
8
+ ping(byok_key: string): Promise<{
9
+ ok: boolean;
10
+ key_fingerprint: string;
11
+ error?: undefined;
12
+ } | {
13
+ ok: boolean;
14
+ error: string;
15
+ key_fingerprint: string;
16
+ }>;
17
+ }
18
+ //# sourceMappingURL=vultr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vultr.d.ts","sourceRoot":"","sources":["../../src/asset-connectors/vultr.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA+BnF,qBAAa,cAAe,SAAQ,kBAAkB;IACpD,EAAE,EAAE,eAAe,CAAW;IAC9B,IAAI,SAAW;IACf,OAAO,UAAQ;IAET,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAiDhF,IAAI,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;CAe5B"}