@switchbot/openapi-cli 3.2.1 → 3.3.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 (332) hide show
  1. package/README.md +3 -1
  2. package/dist/index.js +57419 -170
  3. package/package.json +9 -5
  4. package/dist/api/client.d.ts +0 -31
  5. package/dist/api/client.js +0 -236
  6. package/dist/api/client.js.map +0 -1
  7. package/dist/auth.d.ts +0 -1
  8. package/dist/auth.js +0 -21
  9. package/dist/auth.js.map +0 -1
  10. package/dist/commands/agent-bootstrap.d.ts +0 -10
  11. package/dist/commands/agent-bootstrap.js +0 -200
  12. package/dist/commands/agent-bootstrap.js.map +0 -1
  13. package/dist/commands/auth.d.ts +0 -18
  14. package/dist/commands/auth.js +0 -355
  15. package/dist/commands/auth.js.map +0 -1
  16. package/dist/commands/batch.d.ts +0 -2
  17. package/dist/commands/batch.js +0 -414
  18. package/dist/commands/batch.js.map +0 -1
  19. package/dist/commands/cache.d.ts +0 -2
  20. package/dist/commands/cache.js +0 -127
  21. package/dist/commands/cache.js.map +0 -1
  22. package/dist/commands/capabilities.d.ts +0 -31
  23. package/dist/commands/capabilities.js +0 -383
  24. package/dist/commands/capabilities.js.map +0 -1
  25. package/dist/commands/catalog.d.ts +0 -2
  26. package/dist/commands/catalog.js +0 -360
  27. package/dist/commands/catalog.js.map +0 -1
  28. package/dist/commands/completion.d.ts +0 -2
  29. package/dist/commands/completion.js +0 -386
  30. package/dist/commands/completion.js.map +0 -1
  31. package/dist/commands/config.d.ts +0 -21
  32. package/dist/commands/config.js +0 -377
  33. package/dist/commands/config.js.map +0 -1
  34. package/dist/commands/daemon.d.ts +0 -2
  35. package/dist/commands/daemon.js +0 -411
  36. package/dist/commands/daemon.js.map +0 -1
  37. package/dist/commands/device-meta.d.ts +0 -2
  38. package/dist/commands/device-meta.js +0 -160
  39. package/dist/commands/device-meta.js.map +0 -1
  40. package/dist/commands/devices.d.ts +0 -2
  41. package/dist/commands/devices.js +0 -949
  42. package/dist/commands/devices.js.map +0 -1
  43. package/dist/commands/doctor.d.ts +0 -3
  44. package/dist/commands/doctor.js +0 -1016
  45. package/dist/commands/doctor.js.map +0 -1
  46. package/dist/commands/events.d.ts +0 -31
  47. package/dist/commands/events.js +0 -564
  48. package/dist/commands/events.js.map +0 -1
  49. package/dist/commands/expand.d.ts +0 -2
  50. package/dist/commands/expand.js +0 -131
  51. package/dist/commands/expand.js.map +0 -1
  52. package/dist/commands/explain.d.ts +0 -2
  53. package/dist/commands/explain.js +0 -140
  54. package/dist/commands/explain.js.map +0 -1
  55. package/dist/commands/health.d.ts +0 -8
  56. package/dist/commands/health.js +0 -114
  57. package/dist/commands/health.js.map +0 -1
  58. package/dist/commands/history.d.ts +0 -2
  59. package/dist/commands/history.js +0 -321
  60. package/dist/commands/history.js.map +0 -1
  61. package/dist/commands/identity.d.ts +0 -45
  62. package/dist/commands/identity.js +0 -60
  63. package/dist/commands/identity.js.map +0 -1
  64. package/dist/commands/install.d.ts +0 -20
  65. package/dist/commands/install.js +0 -247
  66. package/dist/commands/install.js.map +0 -1
  67. package/dist/commands/mcp.d.ts +0 -14
  68. package/dist/commands/mcp.js +0 -2018
  69. package/dist/commands/mcp.js.map +0 -1
  70. package/dist/commands/plan.d.ts +0 -51
  71. package/dist/commands/plan.js +0 -654
  72. package/dist/commands/plan.js.map +0 -1
  73. package/dist/commands/policy.d.ts +0 -24
  74. package/dist/commands/policy.js +0 -587
  75. package/dist/commands/policy.js.map +0 -1
  76. package/dist/commands/quota.d.ts +0 -2
  77. package/dist/commands/quota.js +0 -79
  78. package/dist/commands/quota.js.map +0 -1
  79. package/dist/commands/rules.d.ts +0 -2
  80. package/dist/commands/rules.js +0 -876
  81. package/dist/commands/rules.js.map +0 -1
  82. package/dist/commands/scenes.d.ts +0 -2
  83. package/dist/commands/scenes.js +0 -265
  84. package/dist/commands/scenes.js.map +0 -1
  85. package/dist/commands/schema.d.ts +0 -2
  86. package/dist/commands/schema.js +0 -185
  87. package/dist/commands/schema.js.map +0 -1
  88. package/dist/commands/status-sync.d.ts +0 -2
  89. package/dist/commands/status-sync.js +0 -132
  90. package/dist/commands/status-sync.js.map +0 -1
  91. package/dist/commands/uninstall.d.ts +0 -20
  92. package/dist/commands/uninstall.js +0 -238
  93. package/dist/commands/uninstall.js.map +0 -1
  94. package/dist/commands/upgrade-check.d.ts +0 -2
  95. package/dist/commands/upgrade-check.js +0 -107
  96. package/dist/commands/upgrade-check.js.map +0 -1
  97. package/dist/commands/watch.d.ts +0 -2
  98. package/dist/commands/watch.js +0 -195
  99. package/dist/commands/watch.js.map +0 -1
  100. package/dist/commands/webhook.d.ts +0 -2
  101. package/dist/commands/webhook.js +0 -183
  102. package/dist/commands/webhook.js.map +0 -1
  103. package/dist/config.d.ts +0 -57
  104. package/dist/config.js +0 -259
  105. package/dist/config.js.map +0 -1
  106. package/dist/credentials/backends/file.d.ts +0 -18
  107. package/dist/credentials/backends/file.js +0 -102
  108. package/dist/credentials/backends/file.js.map +0 -1
  109. package/dist/credentials/backends/linux.d.ts +0 -16
  110. package/dist/credentials/backends/linux.js +0 -130
  111. package/dist/credentials/backends/linux.js.map +0 -1
  112. package/dist/credentials/backends/macos.d.ts +0 -18
  113. package/dist/credentials/backends/macos.js +0 -130
  114. package/dist/credentials/backends/macos.js.map +0 -1
  115. package/dist/credentials/backends/windows.d.ts +0 -23
  116. package/dist/credentials/backends/windows.js +0 -216
  117. package/dist/credentials/backends/windows.js.map +0 -1
  118. package/dist/credentials/keychain.d.ts +0 -83
  119. package/dist/credentials/keychain.js +0 -89
  120. package/dist/credentials/keychain.js.map +0 -1
  121. package/dist/credentials/prime.d.ts +0 -32
  122. package/dist/credentials/prime.js +0 -53
  123. package/dist/credentials/prime.js.map +0 -1
  124. package/dist/devices/cache.d.ts +0 -79
  125. package/dist/devices/cache.js +0 -294
  126. package/dist/devices/cache.js.map +0 -1
  127. package/dist/devices/catalog.d.ts +0 -138
  128. package/dist/devices/catalog.js +0 -768
  129. package/dist/devices/catalog.js.map +0 -1
  130. package/dist/devices/device-meta.d.ts +0 -15
  131. package/dist/devices/device-meta.js +0 -57
  132. package/dist/devices/device-meta.js.map +0 -1
  133. package/dist/devices/history-agg.d.ts +0 -37
  134. package/dist/devices/history-agg.js +0 -139
  135. package/dist/devices/history-agg.js.map +0 -1
  136. package/dist/devices/history-query.d.ts +0 -45
  137. package/dist/devices/history-query.js +0 -182
  138. package/dist/devices/history-query.js.map +0 -1
  139. package/dist/devices/param-validator.d.ts +0 -40
  140. package/dist/devices/param-validator.js +0 -434
  141. package/dist/devices/param-validator.js.map +0 -1
  142. package/dist/devices/resources.d.ts +0 -74
  143. package/dist/devices/resources.js +0 -271
  144. package/dist/devices/resources.js.map +0 -1
  145. package/dist/index.d.ts +0 -1
  146. package/dist/index.js.map +0 -1
  147. package/dist/install/default-steps.d.ts +0 -66
  148. package/dist/install/default-steps.js +0 -258
  149. package/dist/install/default-steps.js.map +0 -1
  150. package/dist/install/preflight.d.ts +0 -60
  151. package/dist/install/preflight.js +0 -213
  152. package/dist/install/preflight.js.map +0 -1
  153. package/dist/install/steps.d.ts +0 -61
  154. package/dist/install/steps.js +0 -68
  155. package/dist/install/steps.js.map +0 -1
  156. package/dist/lib/command-keywords.d.ts +0 -5
  157. package/dist/lib/command-keywords.js +0 -18
  158. package/dist/lib/command-keywords.js.map +0 -1
  159. package/dist/lib/daemon-state.d.ts +0 -24
  160. package/dist/lib/daemon-state.js +0 -47
  161. package/dist/lib/daemon-state.js.map +0 -1
  162. package/dist/lib/destructive-mode.d.ts +0 -2
  163. package/dist/lib/destructive-mode.js +0 -13
  164. package/dist/lib/destructive-mode.js.map +0 -1
  165. package/dist/lib/devices.d.ts +0 -151
  166. package/dist/lib/devices.js +0 -383
  167. package/dist/lib/devices.js.map +0 -1
  168. package/dist/lib/idempotency.d.ts +0 -46
  169. package/dist/lib/idempotency.js +0 -107
  170. package/dist/lib/idempotency.js.map +0 -1
  171. package/dist/lib/plan-store.d.ts +0 -19
  172. package/dist/lib/plan-store.js +0 -69
  173. package/dist/lib/plan-store.js.map +0 -1
  174. package/dist/lib/request-context.d.ts +0 -7
  175. package/dist/lib/request-context.js +0 -13
  176. package/dist/lib/request-context.js.map +0 -1
  177. package/dist/lib/scenes.d.ts +0 -7
  178. package/dist/lib/scenes.js +0 -11
  179. package/dist/lib/scenes.js.map +0 -1
  180. package/dist/logger.d.ts +0 -4
  181. package/dist/logger.js +0 -17
  182. package/dist/logger.js.map +0 -1
  183. package/dist/mcp/device-history.d.ts +0 -36
  184. package/dist/mcp/device-history.js +0 -146
  185. package/dist/mcp/device-history.js.map +0 -1
  186. package/dist/mcp/events-subscription.d.ts +0 -45
  187. package/dist/mcp/events-subscription.js +0 -214
  188. package/dist/mcp/events-subscription.js.map +0 -1
  189. package/dist/mqtt/client.d.ts +0 -25
  190. package/dist/mqtt/client.js +0 -181
  191. package/dist/mqtt/client.js.map +0 -1
  192. package/dist/mqtt/credential.d.ts +0 -16
  193. package/dist/mqtt/credential.js +0 -31
  194. package/dist/mqtt/credential.js.map +0 -1
  195. package/dist/policy/add-rule.d.ts +0 -21
  196. package/dist/policy/add-rule.js +0 -125
  197. package/dist/policy/add-rule.js.map +0 -1
  198. package/dist/policy/diff.d.ts +0 -21
  199. package/dist/policy/diff.js +0 -92
  200. package/dist/policy/diff.js.map +0 -1
  201. package/dist/policy/format.d.ts +0 -6
  202. package/dist/policy/format.js +0 -58
  203. package/dist/policy/format.js.map +0 -1
  204. package/dist/policy/load.d.ts +0 -32
  205. package/dist/policy/load.js +0 -62
  206. package/dist/policy/load.js.map +0 -1
  207. package/dist/policy/migrate.d.ts +0 -21
  208. package/dist/policy/migrate.js +0 -68
  209. package/dist/policy/migrate.js.map +0 -1
  210. package/dist/policy/schema.d.ts +0 -5
  211. package/dist/policy/schema.js +0 -19
  212. package/dist/policy/schema.js.map +0 -1
  213. package/dist/policy/validate.d.ts +0 -19
  214. package/dist/policy/validate.js +0 -263
  215. package/dist/policy/validate.js.map +0 -1
  216. package/dist/rules/action.d.ts +0 -65
  217. package/dist/rules/action.js +0 -217
  218. package/dist/rules/action.js.map +0 -1
  219. package/dist/rules/audit-query.d.ts +0 -51
  220. package/dist/rules/audit-query.js +0 -90
  221. package/dist/rules/audit-query.js.map +0 -1
  222. package/dist/rules/conflict-analyzer.d.ts +0 -57
  223. package/dist/rules/conflict-analyzer.js +0 -215
  224. package/dist/rules/conflict-analyzer.js.map +0 -1
  225. package/dist/rules/cron-scheduler.d.ts +0 -62
  226. package/dist/rules/cron-scheduler.js +0 -187
  227. package/dist/rules/cron-scheduler.js.map +0 -1
  228. package/dist/rules/destructive.d.ts +0 -20
  229. package/dist/rules/destructive.js +0 -53
  230. package/dist/rules/destructive.js.map +0 -1
  231. package/dist/rules/engine.d.ts +0 -193
  232. package/dist/rules/engine.js +0 -758
  233. package/dist/rules/engine.js.map +0 -1
  234. package/dist/rules/matcher.d.ts +0 -56
  235. package/dist/rules/matcher.js +0 -231
  236. package/dist/rules/matcher.js.map +0 -1
  237. package/dist/rules/pid-file.d.ts +0 -43
  238. package/dist/rules/pid-file.js +0 -96
  239. package/dist/rules/pid-file.js.map +0 -1
  240. package/dist/rules/quiet-hours.d.ts +0 -26
  241. package/dist/rules/quiet-hours.js +0 -46
  242. package/dist/rules/quiet-hours.js.map +0 -1
  243. package/dist/rules/suggest.d.ts +0 -20
  244. package/dist/rules/suggest.js +0 -96
  245. package/dist/rules/suggest.js.map +0 -1
  246. package/dist/rules/throttle.d.ts +0 -61
  247. package/dist/rules/throttle.js +0 -117
  248. package/dist/rules/throttle.js.map +0 -1
  249. package/dist/rules/types.d.ts +0 -117
  250. package/dist/rules/types.js +0 -35
  251. package/dist/rules/types.js.map +0 -1
  252. package/dist/rules/webhook-listener.d.ts +0 -63
  253. package/dist/rules/webhook-listener.js +0 -224
  254. package/dist/rules/webhook-listener.js.map +0 -1
  255. package/dist/rules/webhook-token.d.ts +0 -50
  256. package/dist/rules/webhook-token.js +0 -91
  257. package/dist/rules/webhook-token.js.map +0 -1
  258. package/dist/schema/field-aliases.d.ts +0 -34
  259. package/dist/schema/field-aliases.js +0 -132
  260. package/dist/schema/field-aliases.js.map +0 -1
  261. package/dist/sinks/dispatcher.d.ts +0 -7
  262. package/dist/sinks/dispatcher.js +0 -13
  263. package/dist/sinks/dispatcher.js.map +0 -1
  264. package/dist/sinks/file.d.ts +0 -6
  265. package/dist/sinks/file.js +0 -20
  266. package/dist/sinks/file.js.map +0 -1
  267. package/dist/sinks/format.d.ts +0 -20
  268. package/dist/sinks/format.js +0 -57
  269. package/dist/sinks/format.js.map +0 -1
  270. package/dist/sinks/homeassistant.d.ts +0 -18
  271. package/dist/sinks/homeassistant.js +0 -45
  272. package/dist/sinks/homeassistant.js.map +0 -1
  273. package/dist/sinks/openclaw.d.ts +0 -13
  274. package/dist/sinks/openclaw.js +0 -34
  275. package/dist/sinks/openclaw.js.map +0 -1
  276. package/dist/sinks/stdout.d.ts +0 -4
  277. package/dist/sinks/stdout.js +0 -6
  278. package/dist/sinks/stdout.js.map +0 -1
  279. package/dist/sinks/telegram.d.ts +0 -11
  280. package/dist/sinks/telegram.js +0 -29
  281. package/dist/sinks/telegram.js.map +0 -1
  282. package/dist/sinks/types.d.ts +0 -13
  283. package/dist/sinks/types.js +0 -2
  284. package/dist/sinks/types.js.map +0 -1
  285. package/dist/sinks/webhook.d.ts +0 -6
  286. package/dist/sinks/webhook.js +0 -23
  287. package/dist/sinks/webhook.js.map +0 -1
  288. package/dist/status-sync/manager.d.ts +0 -48
  289. package/dist/status-sync/manager.js +0 -269
  290. package/dist/status-sync/manager.js.map +0 -1
  291. package/dist/utils/arg-parsers.d.ts +0 -16
  292. package/dist/utils/arg-parsers.js +0 -67
  293. package/dist/utils/arg-parsers.js.map +0 -1
  294. package/dist/utils/audit.d.ts +0 -69
  295. package/dist/utils/audit.js +0 -122
  296. package/dist/utils/audit.js.map +0 -1
  297. package/dist/utils/filter.d.ts +0 -81
  298. package/dist/utils/filter.js +0 -190
  299. package/dist/utils/filter.js.map +0 -1
  300. package/dist/utils/flags.d.ts +0 -72
  301. package/dist/utils/flags.js +0 -187
  302. package/dist/utils/flags.js.map +0 -1
  303. package/dist/utils/format.d.ts +0 -9
  304. package/dist/utils/format.js +0 -118
  305. package/dist/utils/format.js.map +0 -1
  306. package/dist/utils/health.d.ts +0 -48
  307. package/dist/utils/health.js +0 -102
  308. package/dist/utils/health.js.map +0 -1
  309. package/dist/utils/help-json.d.ts +0 -39
  310. package/dist/utils/help-json.js +0 -55
  311. package/dist/utils/help-json.js.map +0 -1
  312. package/dist/utils/name-resolver.d.ts +0 -26
  313. package/dist/utils/name-resolver.js +0 -138
  314. package/dist/utils/name-resolver.js.map +0 -1
  315. package/dist/utils/output.d.ts +0 -73
  316. package/dist/utils/output.js +0 -405
  317. package/dist/utils/output.js.map +0 -1
  318. package/dist/utils/quota.d.ts +0 -61
  319. package/dist/utils/quota.js +0 -228
  320. package/dist/utils/quota.js.map +0 -1
  321. package/dist/utils/redact.d.ts +0 -23
  322. package/dist/utils/redact.js +0 -69
  323. package/dist/utils/redact.js.map +0 -1
  324. package/dist/utils/retry.d.ts +0 -72
  325. package/dist/utils/retry.js +0 -141
  326. package/dist/utils/retry.js.map +0 -1
  327. package/dist/utils/string.d.ts +0 -2
  328. package/dist/utils/string.js +0 -23
  329. package/dist/utils/string.js.map +0 -1
  330. package/dist/version.d.ts +0 -2
  331. package/dist/version.js +0 -5
  332. package/dist/version.js.map +0 -1
@@ -1,130 +0,0 @@
1
- /**
2
- * macOS Keychain backend.
3
- *
4
- * Wraps the built-in `security(1)` CLI so `npm install` stays free of
5
- * native compile steps. Service name is shared with the Linux and
6
- * Windows backends (`com.openclaw.switchbot`), so a user migrating a
7
- * config between machines sees the same lookup shape.
8
- *
9
- * Errors never leak credential material — `add-generic-password`
10
- * receives the password via `-w <value>` on argv, which is visible in
11
- * `ps` to the current user but not persisted anywhere, and any stderr
12
- * we surface back up is bounded to the library's own messages
13
- * (`password not found`, `could not be added`, etc.) rather than our
14
- * input values.
15
- */
16
- import { spawn } from 'node:child_process';
17
- import { accountFor, CREDENTIAL_SERVICE, KeychainError, } from '../keychain.js';
18
- function run(cmd, args, stdin) {
19
- return new Promise((resolve) => {
20
- const proc = spawn(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'] });
21
- let stdout = '';
22
- let stderr = '';
23
- proc.stdout.on('data', (buf) => {
24
- stdout += buf.toString('utf-8');
25
- });
26
- proc.stderr.on('data', (buf) => {
27
- stderr += buf.toString('utf-8');
28
- });
29
- proc.on('error', () => resolve({ code: 127, stdout, stderr }));
30
- proc.on('close', (code) => resolve({ code: code ?? 0, stdout, stderr }));
31
- if (stdin !== undefined) {
32
- proc.stdin.write(stdin);
33
- }
34
- proc.stdin.end();
35
- });
36
- }
37
- export async function macOsAvailable() {
38
- if (process.platform !== 'darwin')
39
- return false;
40
- const res = await run('which', ['security']);
41
- return res.code === 0 && res.stdout.trim().length > 0;
42
- }
43
- async function readField(profile, field) {
44
- const account = accountFor(profile, field);
45
- const res = await run('security', [
46
- 'find-generic-password',
47
- '-s', CREDENTIAL_SERVICE,
48
- '-a', account,
49
- '-w',
50
- ]);
51
- if (res.code !== 0)
52
- return null;
53
- const value = res.stdout.replace(/\n$/, '');
54
- return value.length > 0 ? value : null;
55
- }
56
- async function writeField(profile, field, value) {
57
- const account = accountFor(profile, field);
58
- const res = await run('security', [
59
- 'add-generic-password',
60
- '-U', // update if exists
61
- '-s', CREDENTIAL_SERVICE,
62
- '-a', account,
63
- '-w', value,
64
- ]);
65
- if (res.code !== 0) {
66
- throw new KeychainError('keychain', 'set', `security(1) exit ${res.code}`);
67
- }
68
- }
69
- async function deleteField(profile, field) {
70
- const account = accountFor(profile, field);
71
- const res = await run('security', [
72
- 'delete-generic-password',
73
- '-s', CREDENTIAL_SERVICE,
74
- '-a', account,
75
- ]);
76
- // exit 44 = "The specified item could not be found" — tolerate as idempotent delete.
77
- if (res.code !== 0 && res.code !== 44) {
78
- throw new KeychainError('keychain', 'delete', `security(1) exit ${res.code}`);
79
- }
80
- }
81
- async function restoreField(profile, field, value) {
82
- try {
83
- if (value === null) {
84
- await deleteField(profile, field);
85
- return;
86
- }
87
- await writeField(profile, field, value);
88
- }
89
- catch {
90
- // Best effort only. Preserve the original write failure.
91
- }
92
- }
93
- export function createMacOsBackend() {
94
- return {
95
- name: 'keychain',
96
- async get(profile) {
97
- const token = await readField(profile, 'token');
98
- const secret = await readField(profile, 'secret');
99
- if (!token || !secret)
100
- return null;
101
- return { token, secret };
102
- },
103
- async set(profile, creds) {
104
- const previousToken = await readField(profile, 'token');
105
- const previousSecret = await readField(profile, 'secret');
106
- try {
107
- await writeField(profile, 'token', creds.token);
108
- await writeField(profile, 'secret', creds.secret);
109
- }
110
- catch (err) {
111
- await restoreField(profile, 'token', previousToken);
112
- await restoreField(profile, 'secret', previousSecret);
113
- throw err;
114
- }
115
- },
116
- async delete(profile) {
117
- await deleteField(profile, 'token');
118
- await deleteField(profile, 'secret');
119
- },
120
- describe() {
121
- return {
122
- backend: 'macOS Keychain',
123
- tag: 'keychain',
124
- writable: true,
125
- notes: `Stored under service "${CREDENTIAL_SERVICE}" via security(1).`,
126
- };
127
- },
128
- };
129
- }
130
- //# sourceMappingURL=macos.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"macos.js","sourceRoot":"","sources":["../../../src/credentials/backends/macos.ts"],"names":[],"mappings":"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"}
@@ -1,23 +0,0 @@
1
- /**
2
- * Windows Credential Manager backend.
3
- *
4
- * Uses PowerShell + Win32 P/Invoke (`CredReadW` / `CredWriteW` /
5
- * `CredDeleteW`) instead of a native binding so `npm install` stays
6
- * toolchain-free on Windows runners. `cmdkey.exe` could create and
7
- * delete credentials but can't read the password back — reading is the
8
- * whole point, so PowerShell is mandatory.
9
- *
10
- * Target-name shape is `com.openclaw.switchbot:<profile>:<field>` so
11
- * `rundll32.exe keymgr.dll,KRShowKeyMgr` displays our entries in a
12
- * clear, groupable list.
13
- *
14
- * Credential values are passed to the child process via environment
15
- * variables, not argv — this keeps them out of any process listing
16
- * and out of the PowerShell command history. Env blocks on Windows
17
- * are only visible to the current user (and admins), so this is a
18
- * reasonable trade versus the alternatives (stdin requires a second
19
- * round-trip; temp files leave disk residue).
20
- */
21
- import { CredentialStore } from '../keychain.js';
22
- export declare function windowsAvailable(): Promise<boolean>;
23
- export declare function createWindowsBackend(): CredentialStore;
@@ -1,216 +0,0 @@
1
- /**
2
- * Windows Credential Manager backend.
3
- *
4
- * Uses PowerShell + Win32 P/Invoke (`CredReadW` / `CredWriteW` /
5
- * `CredDeleteW`) instead of a native binding so `npm install` stays
6
- * toolchain-free on Windows runners. `cmdkey.exe` could create and
7
- * delete credentials but can't read the password back — reading is the
8
- * whole point, so PowerShell is mandatory.
9
- *
10
- * Target-name shape is `com.openclaw.switchbot:<profile>:<field>` so
11
- * `rundll32.exe keymgr.dll,KRShowKeyMgr` displays our entries in a
12
- * clear, groupable list.
13
- *
14
- * Credential values are passed to the child process via environment
15
- * variables, not argv — this keeps them out of any process listing
16
- * and out of the PowerShell command history. Env blocks on Windows
17
- * are only visible to the current user (and admins), so this is a
18
- * reasonable trade versus the alternatives (stdin requires a second
19
- * round-trip; temp files leave disk residue).
20
- */
21
- import { spawn } from 'node:child_process';
22
- import { accountFor, CREDENTIAL_SERVICE, KeychainError, } from '../keychain.js';
23
- const PS_HEADER = `$ErrorActionPreference = 'Stop'
24
- Add-Type -MemberDefinition @'
25
- [DllImport("Advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
26
- public static extern bool CredReadW(string target, int type, int flags, out System.IntPtr credentialPtr);
27
-
28
- [DllImport("Advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
29
- public static extern bool CredWriteW(ref CREDENTIAL cred, int flags);
30
-
31
- [DllImport("Advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
32
- public static extern bool CredDeleteW(string target, int type, int flags);
33
-
34
- [DllImport("Advapi32.dll", SetLastError=true)]
35
- public static extern void CredFree(System.IntPtr buffer);
36
-
37
- [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
38
- public struct CREDENTIAL {
39
- public int Flags;
40
- public int Type;
41
- public System.IntPtr TargetName;
42
- public System.IntPtr Comment;
43
- public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
44
- public int CredentialBlobSize;
45
- public System.IntPtr CredentialBlob;
46
- public int Persist;
47
- public int AttributeCount;
48
- public System.IntPtr Attributes;
49
- public System.IntPtr TargetAlias;
50
- public System.IntPtr UserName;
51
- }
52
- '@ -Name CredApi -Namespace Win32 | Out-Null
53
- `;
54
- const PS_GET = `${PS_HEADER}
55
- $target = $env:SWITCHBOT_CRED_TARGET
56
- $ptr = [System.IntPtr]::Zero
57
- $ok = [Win32.CredApi]::CredReadW($target, 1, 0, [ref]$ptr)
58
- if (-not $ok) { exit 2 }
59
- $cred = [System.Runtime.InteropServices.Marshal]::PtrToStructure($ptr, [type][Win32.CredApi+CREDENTIAL])
60
- $bytes = New-Object byte[] $cred.CredentialBlobSize
61
- [System.Runtime.InteropServices.Marshal]::Copy($cred.CredentialBlob, $bytes, 0, $cred.CredentialBlobSize)
62
- [Win32.CredApi]::CredFree($ptr) | Out-Null
63
- $password = [System.Text.Encoding]::Unicode.GetString($bytes)
64
- [Console]::Out.Write([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($password)))
65
- `;
66
- const PS_SET = `${PS_HEADER}
67
- $target = $env:SWITCHBOT_CRED_TARGET
68
- $user = $env:SWITCHBOT_CRED_USER
69
- $value = $env:SWITCHBOT_CRED_VALUE
70
- $bytes = [System.Text.Encoding]::Unicode.GetBytes($value)
71
- $blob = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($bytes.Length)
72
- [System.Runtime.InteropServices.Marshal]::Copy($bytes, 0, $blob, $bytes.Length)
73
- $cred = New-Object Win32.CredApi+CREDENTIAL
74
- $cred.Flags = 0
75
- $cred.Type = 1
76
- $cred.TargetName = [System.Runtime.InteropServices.Marshal]::StringToCoTaskMemUni($target)
77
- $cred.UserName = [System.Runtime.InteropServices.Marshal]::StringToCoTaskMemUni($user)
78
- $cred.CredentialBlob = $blob
79
- $cred.CredentialBlobSize = $bytes.Length
80
- $cred.Persist = 2
81
- $cred.AttributeCount = 0
82
- $ok = [Win32.CredApi]::CredWriteW([ref]$cred, 0)
83
- [System.Runtime.InteropServices.Marshal]::FreeCoTaskMem($cred.TargetName)
84
- [System.Runtime.InteropServices.Marshal]::FreeCoTaskMem($cred.UserName)
85
- [System.Runtime.InteropServices.Marshal]::FreeHGlobal($blob)
86
- if (-not $ok) { exit 3 }
87
- `;
88
- const PS_DELETE = `${PS_HEADER}
89
- $target = $env:SWITCHBOT_CRED_TARGET
90
- $ok = [Win32.CredApi]::CredDeleteW($target, 1, 0)
91
- if (-not $ok) {
92
- $errno = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
93
- # 1168 = ERROR_NOT_FOUND — tolerate as idempotent delete.
94
- if ($errno -ne 1168) { exit 4 }
95
- }
96
- `;
97
- function encodePs(script) {
98
- return Buffer.from(script, 'utf16le').toString('base64');
99
- }
100
- function runPowerShell(script, env) {
101
- return new Promise((resolve) => {
102
- const proc = spawn('powershell.exe', ['-NoProfile', '-NonInteractive', '-EncodedCommand', encodePs(script)], {
103
- stdio: ['ignore', 'pipe', 'pipe'],
104
- env: { ...process.env, ...env },
105
- });
106
- let stdout = '';
107
- let stderr = '';
108
- proc.stdout.on('data', (buf) => {
109
- stdout += buf.toString('utf-8');
110
- });
111
- proc.stderr.on('data', (buf) => {
112
- stderr += buf.toString('utf-8');
113
- });
114
- proc.on('error', () => resolve({ code: 127, stdout, stderr }));
115
- proc.on('close', (code) => resolve({ code: code ?? 0, stdout, stderr }));
116
- });
117
- }
118
- function targetFor(profile, field) {
119
- return `${CREDENTIAL_SERVICE}:${accountFor(profile, field)}`;
120
- }
121
- export async function windowsAvailable() {
122
- if (process.platform !== 'win32')
123
- return false;
124
- return new Promise((resolve) => {
125
- const proc = spawn('where', ['powershell.exe'], { stdio: ['ignore', 'pipe', 'pipe'] });
126
- let ok = false;
127
- proc.stdout.on('data', (buf) => {
128
- if (buf.toString().trim().length > 0)
129
- ok = true;
130
- });
131
- proc.on('error', () => resolve(false));
132
- proc.on('close', (code) => resolve(ok && (code ?? 0) === 0));
133
- });
134
- }
135
- async function readField(profile, field) {
136
- const res = await runPowerShell(PS_GET, {
137
- SWITCHBOT_CRED_TARGET: targetFor(profile, field),
138
- });
139
- if (res.code !== 0)
140
- return null;
141
- try {
142
- const decoded = Buffer.from(res.stdout, 'base64').toString('utf-8');
143
- return decoded.length > 0 ? decoded : null;
144
- }
145
- catch {
146
- return null;
147
- }
148
- }
149
- async function writeField(profile, field, value) {
150
- const res = await runPowerShell(PS_SET, {
151
- SWITCHBOT_CRED_TARGET: targetFor(profile, field),
152
- SWITCHBOT_CRED_USER: accountFor(profile, field),
153
- SWITCHBOT_CRED_VALUE: value,
154
- });
155
- if (res.code !== 0) {
156
- throw new KeychainError('credman', 'set', `CredWrite exit ${res.code}`);
157
- }
158
- }
159
- async function deleteField(profile, field) {
160
- const res = await runPowerShell(PS_DELETE, {
161
- SWITCHBOT_CRED_TARGET: targetFor(profile, field),
162
- });
163
- if (res.code !== 0) {
164
- throw new KeychainError('credman', 'delete', `CredDelete exit ${res.code}`);
165
- }
166
- }
167
- async function restoreField(profile, field, value) {
168
- try {
169
- if (value === null) {
170
- await deleteField(profile, field);
171
- return;
172
- }
173
- await writeField(profile, field, value);
174
- }
175
- catch {
176
- // Best effort only. Preserve the original write failure.
177
- }
178
- }
179
- export function createWindowsBackend() {
180
- return {
181
- name: 'credman',
182
- async get(profile) {
183
- const token = await readField(profile, 'token');
184
- const secret = await readField(profile, 'secret');
185
- if (!token || !secret)
186
- return null;
187
- return { token, secret };
188
- },
189
- async set(profile, creds) {
190
- const previousToken = await readField(profile, 'token');
191
- const previousSecret = await readField(profile, 'secret');
192
- try {
193
- await writeField(profile, 'token', creds.token);
194
- await writeField(profile, 'secret', creds.secret);
195
- }
196
- catch (err) {
197
- await restoreField(profile, 'token', previousToken);
198
- await restoreField(profile, 'secret', previousSecret);
199
- throw err;
200
- }
201
- },
202
- async delete(profile) {
203
- await deleteField(profile, 'token');
204
- await deleteField(profile, 'secret');
205
- },
206
- describe() {
207
- return {
208
- backend: 'Credential Manager (Windows)',
209
- tag: 'credman',
210
- writable: true,
211
- notes: `Stored under target "${CREDENTIAL_SERVICE}:*" via Win32 CredRead/CredWrite.`,
212
- };
213
- },
214
- };
215
- }
216
- //# sourceMappingURL=windows.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"windows.js","sourceRoot":"","sources":["../../../src/credentials/backends/windows.ts"],"names":[],"mappings":"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"}
@@ -1,83 +0,0 @@
1
- /**
2
- * OS-keychain credential store abstraction.
3
- *
4
- * F1 scope (plan: `feat/v2.8-policy-tooling`):
5
- * - Defines the `CredentialStore` contract the rest of the CLI can
6
- * depend on (token/secret per profile, auditable describe(), best-
7
- * effort delete()).
8
- * - Ships four backends: `macos` (security(1)), `linux`
9
- * (secret-tool), `windows` (PowerShell + Win32 CredRead/CredWrite)
10
- * and `file` (the existing `~/.switchbot/config.json` shape as
11
- * last-resort fallback).
12
- * - `selectCredentialStore()` picks the OS-native backend first and
13
- * silently degrades to `file` whenever a backend is absent or
14
- * non-writable — so a fresh Linux box without libsecret installed
15
- * still Just Works.
16
- *
17
- * Out of scope here: migrating existing users off `~/.switchbot/config.json`
18
- * into the keychain. F3's `switchbot auth keychain migrate` subcommand
19
- * handles the explicit opt-in; F2 only wires the *read* path.
20
- *
21
- * Design choices:
22
- * - No native bindings. Every native backend shells out to an
23
- * OS-provided CLI / interpreter, which keeps `npm install` free of
24
- * compile steps on CI machines.
25
- * - Errors never leak credential material to logs or stderr. On any
26
- * subprocess failure backends return `null` (read) or throw a
27
- * `KeychainError` without the input token/secret in the message.
28
- * - Service / account namespacing is identical across backends
29
- * (`com.openclaw.switchbot` / `<profile>:<field>`) so a user can
30
- * move between machines and expect `switchbot auth keychain get`
31
- * to produce the same lookup shape.
32
- */
33
- export declare const CREDENTIAL_SERVICE = "com.openclaw.switchbot";
34
- export declare const CREDENTIAL_FIELDS: readonly ["token", "secret"];
35
- export type CredentialField = (typeof CREDENTIAL_FIELDS)[number];
36
- export interface CredentialBundle {
37
- token: string;
38
- secret: string;
39
- }
40
- export type CredentialBackendName = 'keychain' | 'credman' | 'secret-service' | 'file';
41
- export interface CredentialStoreDescribe {
42
- /** User-facing short name, e.g. "macOS Keychain" or "Credential Manager (Windows)". */
43
- backend: string;
44
- /** Implementation tag; what `CredentialStore.name` returns. */
45
- tag: CredentialBackendName;
46
- /** Whether `set()`/`delete()` are expected to succeed. */
47
- writable: boolean;
48
- /** Optional one-line note surfaced by doctor and `auth keychain describe`. */
49
- notes?: string;
50
- }
51
- export interface CredentialStore {
52
- readonly name: CredentialBackendName;
53
- get(profile: string): Promise<CredentialBundle | null>;
54
- set(profile: string, creds: CredentialBundle): Promise<void>;
55
- delete(profile: string): Promise<void>;
56
- describe(): CredentialStoreDescribe;
57
- }
58
- /**
59
- * Thrown when a backend cannot service a `set`/`delete` request even
60
- * though it reported itself as writable. Never includes the
61
- * credential material in the message.
62
- */
63
- export declare class KeychainError extends Error {
64
- readonly backend: CredentialBackendName;
65
- readonly operation: 'get' | 'set' | 'delete';
66
- constructor(backend: CredentialBackendName, operation: 'get' | 'set' | 'delete', message: string);
67
- }
68
- /** Encode the account string used by every native backend. Kept public
69
- * so F3's CLI can show what the underlying keychain will see. */
70
- export declare function accountFor(profile: string, field: CredentialField): string;
71
- /**
72
- * Select the best backend for the current platform. The caller does
73
- * not need to handle "no keychain available" — this function always
74
- * returns a store, falling back to the file backend if necessary.
75
- *
76
- * Detection is done eagerly at call time (cheap `which` probe) so a
77
- * long-running process reflects environment changes (e.g. user
78
- * installs secret-tool after first run). Selection does NOT mutate
79
- * any state; calling it twice returns fresh instances.
80
- */
81
- export declare function selectCredentialStore(opts?: {
82
- preferFile?: boolean;
83
- }): Promise<CredentialStore>;
@@ -1,89 +0,0 @@
1
- /**
2
- * OS-keychain credential store abstraction.
3
- *
4
- * F1 scope (plan: `feat/v2.8-policy-tooling`):
5
- * - Defines the `CredentialStore` contract the rest of the CLI can
6
- * depend on (token/secret per profile, auditable describe(), best-
7
- * effort delete()).
8
- * - Ships four backends: `macos` (security(1)), `linux`
9
- * (secret-tool), `windows` (PowerShell + Win32 CredRead/CredWrite)
10
- * and `file` (the existing `~/.switchbot/config.json` shape as
11
- * last-resort fallback).
12
- * - `selectCredentialStore()` picks the OS-native backend first and
13
- * silently degrades to `file` whenever a backend is absent or
14
- * non-writable — so a fresh Linux box without libsecret installed
15
- * still Just Works.
16
- *
17
- * Out of scope here: migrating existing users off `~/.switchbot/config.json`
18
- * into the keychain. F3's `switchbot auth keychain migrate` subcommand
19
- * handles the explicit opt-in; F2 only wires the *read* path.
20
- *
21
- * Design choices:
22
- * - No native bindings. Every native backend shells out to an
23
- * OS-provided CLI / interpreter, which keeps `npm install` free of
24
- * compile steps on CI machines.
25
- * - Errors never leak credential material to logs or stderr. On any
26
- * subprocess failure backends return `null` (read) or throw a
27
- * `KeychainError` without the input token/secret in the message.
28
- * - Service / account namespacing is identical across backends
29
- * (`com.openclaw.switchbot` / `<profile>:<field>`) so a user can
30
- * move between machines and expect `switchbot auth keychain get`
31
- * to produce the same lookup shape.
32
- */
33
- export const CREDENTIAL_SERVICE = 'com.openclaw.switchbot';
34
- export const CREDENTIAL_FIELDS = ['token', 'secret'];
35
- /**
36
- * Thrown when a backend cannot service a `set`/`delete` request even
37
- * though it reported itself as writable. Never includes the
38
- * credential material in the message.
39
- */
40
- export class KeychainError extends Error {
41
- backend;
42
- operation;
43
- constructor(backend, operation, message) {
44
- super(`[${backend}] ${operation} failed: ${message}`);
45
- this.backend = backend;
46
- this.operation = operation;
47
- this.name = 'KeychainError';
48
- }
49
- }
50
- /** Encode the account string used by every native backend. Kept public
51
- * so F3's CLI can show what the underlying keychain will see. */
52
- export function accountFor(profile, field) {
53
- return `${profile}:${field}`;
54
- }
55
- /**
56
- * Select the best backend for the current platform. The caller does
57
- * not need to handle "no keychain available" — this function always
58
- * returns a store, falling back to the file backend if necessary.
59
- *
60
- * Detection is done eagerly at call time (cheap `which` probe) so a
61
- * long-running process reflects environment changes (e.g. user
62
- * installs secret-tool after first run). Selection does NOT mutate
63
- * any state; calling it twice returns fresh instances.
64
- */
65
- export async function selectCredentialStore(opts = {}) {
66
- if (opts.preferFile) {
67
- const { createFileBackend } = await import('./backends/file.js');
68
- return createFileBackend();
69
- }
70
- const platform = process.platform;
71
- if (platform === 'darwin') {
72
- const { createMacOsBackend, macOsAvailable } = await import('./backends/macos.js');
73
- if (await macOsAvailable())
74
- return createMacOsBackend();
75
- }
76
- else if (platform === 'linux') {
77
- const { createLinuxBackend, linuxAvailable } = await import('./backends/linux.js');
78
- if (await linuxAvailable())
79
- return createLinuxBackend();
80
- }
81
- else if (platform === 'win32') {
82
- const { createWindowsBackend, windowsAvailable } = await import('./backends/windows.js');
83
- if (await windowsAvailable())
84
- return createWindowsBackend();
85
- }
86
- const { createFileBackend } = await import('./backends/file.js');
87
- return createFileBackend();
88
- }
89
- //# sourceMappingURL=keychain.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/credentials/keychain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,wBAAwB,CAAC;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAU,CAAC;AA6B9D;;;;GAIG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAEpB;IACA;IAFlB,YACkB,OAA8B,EAC9B,SAAmC,EACnD,OAAe;QAEf,KAAK,CAAC,IAAI,OAAO,KAAK,SAAS,YAAY,OAAO,EAAE,CAAC,CAAC;QAJtC,YAAO,GAAP,OAAO,CAAuB;QAC9B,cAAS,GAAT,SAAS,CAA0B;QAInD,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED;iEACiE;AACjE,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,KAAsB;IAChE,OAAO,GAAG,OAAO,IAAI,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAiC,EAAE;IAC7E,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACjE,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,kBAAkB,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACnF,IAAI,MAAM,cAAc,EAAE;YAAE,OAAO,kBAAkB,EAAE,CAAC;IAC1D,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,EAAE,kBAAkB,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACnF,IAAI,MAAM,cAAc,EAAE;YAAE,OAAO,kBAAkB,EAAE,CAAC;IAC1D,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QACzF,IAAI,MAAM,gBAAgB,EAAE;YAAE,OAAO,oBAAoB,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACjE,OAAO,iBAAiB,EAAE,CAAC;AAC7B,CAAC"}
@@ -1,32 +0,0 @@
1
- /**
2
- * Credential priming cache.
3
- *
4
- * `loadConfig()` runs synchronously, but every OS keychain backend is
5
- * async (subprocess-based). We bridge the two by priming credentials
6
- * once per command, early in the `preAction` hook, and keeping the
7
- * result in a tiny in-process cache keyed by profile name.
8
- *
9
- * After priming, sync callers can consult `getPrimedCredentials()` to
10
- * pick up keychain-stored token/secret without any await.
11
- *
12
- * This module intentionally swallows errors — a flaky keychain
13
- * probe must never block the CLI from running. When the probe fails
14
- * we behave as "nothing primed" and the existing file path is used.
15
- */
16
- import { CredentialBundle } from './keychain.js';
17
- /**
18
- * Look up the given profile in the active credential store and cache
19
- * the result. Safe to call multiple times — subsequent calls with the
20
- * same profile short-circuit against the cache. Swallows all errors.
21
- */
22
- export declare function primeCredentials(profile: string): Promise<void>;
23
- /**
24
- * Sync accessor for code paths that cannot be made async. Returns
25
- * null when the cache is empty or keyed against a different profile,
26
- * so existing file-based fallback stays the authoritative source.
27
- */
28
- export declare function getPrimedCredentials(profile: string): CredentialBundle | null;
29
- /**
30
- * Test helper. Not used by production code.
31
- */
32
- export declare function __resetPrimedCredentials(): void;
@@ -1,53 +0,0 @@
1
- /**
2
- * Credential priming cache.
3
- *
4
- * `loadConfig()` runs synchronously, but every OS keychain backend is
5
- * async (subprocess-based). We bridge the two by priming credentials
6
- * once per command, early in the `preAction` hook, and keeping the
7
- * result in a tiny in-process cache keyed by profile name.
8
- *
9
- * After priming, sync callers can consult `getPrimedCredentials()` to
10
- * pick up keychain-stored token/secret without any await.
11
- *
12
- * This module intentionally swallows errors — a flaky keychain
13
- * probe must never block the CLI from running. When the probe fails
14
- * we behave as "nothing primed" and the existing file path is used.
15
- */
16
- import { selectCredentialStore } from './keychain.js';
17
- let cache = null;
18
- /**
19
- * Look up the given profile in the active credential store and cache
20
- * the result. Safe to call multiple times — subsequent calls with the
21
- * same profile short-circuit against the cache. Swallows all errors.
22
- */
23
- export async function primeCredentials(profile) {
24
- if (cache?.profile === profile)
25
- return;
26
- try {
27
- const store = await selectCredentialStore();
28
- const creds = await store.get(profile);
29
- cache = { profile, creds };
30
- }
31
- catch {
32
- cache = { profile, creds: null };
33
- }
34
- }
35
- /**
36
- * Sync accessor for code paths that cannot be made async. Returns
37
- * null when the cache is empty or keyed against a different profile,
38
- * so existing file-based fallback stays the authoritative source.
39
- */
40
- export function getPrimedCredentials(profile) {
41
- if (!cache)
42
- return null;
43
- if (cache.profile !== profile)
44
- return null;
45
- return cache.creds;
46
- }
47
- /**
48
- * Test helper. Not used by production code.
49
- */
50
- export function __resetPrimedCredentials() {
51
- cache = null;
52
- }
53
- //# sourceMappingURL=prime.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prime.js","sourceRoot":"","sources":["../../src/credentials/prime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAoB,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAOxE,IAAI,KAAK,GAAsB,IAAI,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAe;IACpD,IAAI,KAAK,EAAE,OAAO,KAAK,OAAO;QAAE,OAAO;IACvC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,qBAAqB,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,KAAK,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC3C,OAAO,KAAK,CAAC,KAAK,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB;IACtC,KAAK,GAAG,IAAI,CAAC;AACf,CAAC"}