@caupulican/pi-adaptative 0.81.40 → 0.81.41

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 (406) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -1
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +1 -0
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +1 -0
  6. package/dist/cli/args.d.ts +2 -0
  7. package/dist/cli/args.d.ts.map +1 -1
  8. package/dist/cli/args.js +22 -1
  9. package/dist/cli/args.js.map +1 -1
  10. package/dist/core/agent-paths.d.ts +6 -0
  11. package/dist/core/agent-paths.d.ts.map +1 -1
  12. package/dist/core/agent-paths.js +12 -0
  13. package/dist/core/agent-paths.js.map +1 -1
  14. package/dist/core/agent-session-contracts.d.ts +293 -0
  15. package/dist/core/agent-session-contracts.d.ts.map +1 -0
  16. package/dist/core/agent-session-contracts.js +26 -0
  17. package/dist/core/agent-session-contracts.js.map +1 -0
  18. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  19. package/dist/core/agent-session-runtime.js +3 -0
  20. package/dist/core/agent-session-runtime.js.map +1 -1
  21. package/dist/core/agent-session.d.ts +26 -405
  22. package/dist/core/agent-session.d.ts.map +1 -1
  23. package/dist/core/agent-session.js +86 -307
  24. package/dist/core/agent-session.js.map +1 -1
  25. package/dist/core/auth-storage.d.ts.map +1 -1
  26. package/dist/core/auth-storage.js +3 -1
  27. package/dist/core/auth-storage.js.map +1 -1
  28. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  29. package/dist/core/autonomy/lane-tool-surface.js +2 -1
  30. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  31. package/dist/core/background-lane-controller.d.ts +3 -1
  32. package/dist/core/background-lane-controller.d.ts.map +1 -1
  33. package/dist/core/background-lane-controller.js +1 -0
  34. package/dist/core/background-lane-controller.js.map +1 -1
  35. package/dist/core/bedrock-sso-login.d.ts +16 -0
  36. package/dist/core/bedrock-sso-login.d.ts.map +1 -0
  37. package/dist/core/bedrock-sso-login.js +98 -0
  38. package/dist/core/bedrock-sso-login.js.map +1 -0
  39. package/dist/core/compaction-controller.d.ts.map +1 -1
  40. package/dist/core/compaction-controller.js +1 -1
  41. package/dist/core/compaction-controller.js.map +1 -1
  42. package/dist/core/compaction-support.d.ts +3 -8
  43. package/dist/core/compaction-support.d.ts.map +1 -1
  44. package/dist/core/compaction-support.js +3 -3
  45. package/dist/core/compaction-support.js.map +1 -1
  46. package/dist/core/context-pipeline.d.ts +1 -1
  47. package/dist/core/context-pipeline.d.ts.map +1 -1
  48. package/dist/core/context-pipeline.js +7 -33
  49. package/dist/core/context-pipeline.js.map +1 -1
  50. package/dist/core/cost/cost-summary.d.ts.map +1 -1
  51. package/dist/core/cost/cost-summary.js +5 -3
  52. package/dist/core/cost/cost-summary.js.map +1 -1
  53. package/dist/core/cost/daily-usage.d.ts.map +1 -1
  54. package/dist/core/cost/daily-usage.js +4 -5
  55. package/dist/core/cost/daily-usage.js.map +1 -1
  56. package/dist/core/default-tool-surface.d.ts.map +1 -1
  57. package/dist/core/default-tool-surface.js +1 -0
  58. package/dist/core/default-tool-surface.js.map +1 -1
  59. package/dist/core/extension-import-authority.d.ts +6 -0
  60. package/dist/core/extension-import-authority.d.ts.map +1 -0
  61. package/dist/core/extension-import-authority.js +10 -0
  62. package/dist/core/extension-import-authority.js.map +1 -0
  63. package/dist/core/extensions/loader.d.ts.map +1 -1
  64. package/dist/core/extensions/loader.js +2 -3
  65. package/dist/core/extensions/loader.js.map +1 -1
  66. package/dist/core/extensions/runner.d.ts +3 -0
  67. package/dist/core/extensions/runner.d.ts.map +1 -1
  68. package/dist/core/extensions/runner.js +14 -5
  69. package/dist/core/extensions/runner.js.map +1 -1
  70. package/dist/core/extensions/stale-context.d.ts +2 -0
  71. package/dist/core/extensions/stale-context.d.ts.map +1 -0
  72. package/dist/core/extensions/stale-context.js +2 -0
  73. package/dist/core/extensions/stale-context.js.map +1 -0
  74. package/dist/core/extensions/types.d.ts +8 -0
  75. package/dist/core/extensions/types.d.ts.map +1 -1
  76. package/dist/core/extensions/types.js.map +1 -1
  77. package/dist/core/foreground-recovery-controller.d.ts +1 -0
  78. package/dist/core/foreground-recovery-controller.d.ts.map +1 -1
  79. package/dist/core/foreground-recovery-controller.js +13 -13
  80. package/dist/core/foreground-recovery-controller.js.map +1 -1
  81. package/dist/core/goal-loop-controller.d.ts +14 -9
  82. package/dist/core/goal-loop-controller.d.ts.map +1 -1
  83. package/dist/core/goal-loop-controller.js +47 -75
  84. package/dist/core/goal-loop-controller.js.map +1 -1
  85. package/dist/core/goals/compact-goal-context.d.ts +11 -0
  86. package/dist/core/goals/compact-goal-context.d.ts.map +1 -0
  87. package/dist/core/goals/compact-goal-context.js +59 -0
  88. package/dist/core/goals/compact-goal-context.js.map +1 -0
  89. package/dist/core/goals/goal-acceptance.d.ts.map +1 -1
  90. package/dist/core/goals/goal-acceptance.js +2 -0
  91. package/dist/core/goals/goal-acceptance.js.map +1 -1
  92. package/dist/core/goals/goal-auto-continue-controller.d.ts +2 -1
  93. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -1
  94. package/dist/core/goals/goal-auto-continue-controller.js +5 -8
  95. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -1
  96. package/dist/core/goals/goal-continuation-controller.d.ts +2 -2
  97. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  98. package/dist/core/goals/goal-continuation-controller.js +42 -11
  99. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  100. package/dist/core/goals/goal-continuation-defaults.d.ts +4 -29
  101. package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
  102. package/dist/core/goals/goal-continuation-defaults.js +4 -32
  103. package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
  104. package/dist/core/goals/goal-continuation-prompt.d.ts +8 -18
  105. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  106. package/dist/core/goals/goal-continuation-prompt.js +9 -179
  107. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  108. package/dist/core/goals/goal-lifecycle.d.ts +35 -12
  109. package/dist/core/goals/goal-lifecycle.d.ts.map +1 -1
  110. package/dist/core/goals/goal-lifecycle.js +98 -13
  111. package/dist/core/goals/goal-lifecycle.js.map +1 -1
  112. package/dist/core/goals/goal-record.d.ts +17 -0
  113. package/dist/core/goals/goal-record.d.ts.map +1 -0
  114. package/dist/core/goals/goal-record.js +31 -0
  115. package/dist/core/goals/goal-record.js.map +1 -0
  116. package/dist/core/goals/goal-session-controller.d.ts +42 -0
  117. package/dist/core/goals/goal-session-controller.d.ts.map +1 -0
  118. package/dist/core/goals/goal-session-controller.js +128 -0
  119. package/dist/core/goals/goal-session-controller.js.map +1 -0
  120. package/dist/core/goals/goal-state.d.ts +45 -25
  121. package/dist/core/goals/goal-state.d.ts.map +1 -1
  122. package/dist/core/goals/goal-state.js +85 -15
  123. package/dist/core/goals/goal-state.js.map +1 -1
  124. package/dist/core/goals/goal-tool-core.d.ts +1 -4
  125. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  126. package/dist/core/goals/goal-tool-core.js +49 -34
  127. package/dist/core/goals/goal-tool-core.js.map +1 -1
  128. package/dist/core/goals/session-goal-state.d.ts +18 -8
  129. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  130. package/dist/core/goals/session-goal-state.js +134 -11
  131. package/dist/core/goals/session-goal-state.js.map +1 -1
  132. package/dist/core/human-input-controller.d.ts +47 -0
  133. package/dist/core/human-input-controller.d.ts.map +1 -0
  134. package/dist/core/human-input-controller.js +181 -0
  135. package/dist/core/human-input-controller.js.map +1 -0
  136. package/dist/core/local-runtime-controller.d.ts +1 -1
  137. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  138. package/dist/core/local-runtime-controller.js.map +1 -1
  139. package/dist/core/model-capability.d.ts +0 -19
  140. package/dist/core/model-capability.d.ts.map +1 -1
  141. package/dist/core/model-capability.js +0 -19
  142. package/dist/core/model-capability.js.map +1 -1
  143. package/dist/core/model-registry.d.ts +6 -1
  144. package/dist/core/model-registry.d.ts.map +1 -1
  145. package/dist/core/model-registry.js +13 -5
  146. package/dist/core/model-registry.js.map +1 -1
  147. package/dist/core/model-resolver.d.ts +16 -1
  148. package/dist/core/model-resolver.d.ts.map +1 -1
  149. package/dist/core/model-resolver.js +32 -16
  150. package/dist/core/model-resolver.js.map +1 -1
  151. package/dist/core/model-router-controller.d.ts +1 -1
  152. package/dist/core/model-router-controller.d.ts.map +1 -1
  153. package/dist/core/model-router-controller.js.map +1 -1
  154. package/dist/core/model-selection-controller.d.ts +1 -1
  155. package/dist/core/model-selection-controller.d.ts.map +1 -1
  156. package/dist/core/model-selection-controller.js.map +1 -1
  157. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
  158. package/dist/core/orchestration/delegation-ledger.js +3 -0
  159. package/dist/core/orchestration/delegation-ledger.js.map +1 -1
  160. package/dist/core/orchestration/work-state-projection.d.ts.map +1 -1
  161. package/dist/core/orchestration/work-state-projection.js +1 -1
  162. package/dist/core/orchestration/work-state-projection.js.map +1 -1
  163. package/dist/core/package-manager.d.ts.map +1 -1
  164. package/dist/core/package-manager.js +20 -3
  165. package/dist/core/package-manager.js.map +1 -1
  166. package/dist/core/profile-filter-controller.d.ts +8 -1
  167. package/dist/core/profile-filter-controller.d.ts.map +1 -1
  168. package/dist/core/profile-filter-controller.js +23 -5
  169. package/dist/core/profile-filter-controller.js.map +1 -1
  170. package/dist/core/prompt-templates.d.ts +1 -0
  171. package/dist/core/prompt-templates.d.ts.map +1 -1
  172. package/dist/core/prompt-templates.js +18 -29
  173. package/dist/core/prompt-templates.js.map +1 -1
  174. package/dist/core/reflection-controller.d.ts +1 -1
  175. package/dist/core/reflection-controller.d.ts.map +1 -1
  176. package/dist/core/reflection-controller.js +3 -1
  177. package/dist/core/reflection-controller.js.map +1 -1
  178. package/dist/core/request-auth.d.ts +7 -0
  179. package/dist/core/request-auth.d.ts.map +1 -0
  180. package/dist/core/request-auth.js +8 -0
  181. package/dist/core/request-auth.js.map +1 -0
  182. package/dist/core/resource-loader.d.ts.map +1 -1
  183. package/dist/core/resource-loader.js +16 -6
  184. package/dist/core/resource-loader.js.map +1 -1
  185. package/dist/core/risk-classifier.d.ts.map +1 -1
  186. package/dist/core/risk-classifier.js +8 -0
  187. package/dist/core/risk-classifier.js.map +1 -1
  188. package/dist/core/runtime-builder.d.ts +15 -3
  189. package/dist/core/runtime-builder.d.ts.map +1 -1
  190. package/dist/core/runtime-builder.js +132 -79
  191. package/dist/core/runtime-builder.js.map +1 -1
  192. package/dist/core/sdk.d.ts.map +1 -1
  193. package/dist/core/sdk.js +7 -1
  194. package/dist/core/sdk.js.map +1 -1
  195. package/dist/core/secrets/credential-exposure-guard.d.ts +9 -0
  196. package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -0
  197. package/dist/core/secrets/credential-exposure-guard.js +241 -0
  198. package/dist/core/secrets/credential-exposure-guard.js.map +1 -0
  199. package/dist/core/secrets/secret-dotenv.d.ts +27 -0
  200. package/dist/core/secrets/secret-dotenv.d.ts.map +1 -0
  201. package/dist/core/secrets/secret-dotenv.js +183 -0
  202. package/dist/core/secrets/secret-dotenv.js.map +1 -0
  203. package/dist/core/secrets/secret-vault-format.d.ts +112 -0
  204. package/dist/core/secrets/secret-vault-format.d.ts.map +1 -0
  205. package/dist/core/secrets/secret-vault-format.js +397 -0
  206. package/dist/core/secrets/secret-vault-format.js.map +1 -0
  207. package/dist/core/secrets/secret-vault.d.ts +72 -0
  208. package/dist/core/secrets/secret-vault.d.ts.map +1 -0
  209. package/dist/core/secrets/secret-vault.js +671 -0
  210. package/dist/core/secrets/secret-vault.js.map +1 -0
  211. package/dist/core/session-analytics.d.ts +4 -23
  212. package/dist/core/session-analytics.d.ts.map +1 -1
  213. package/dist/core/session-analytics.js +39 -69
  214. package/dist/core/session-analytics.js.map +1 -1
  215. package/dist/core/session-role.d.ts +5 -0
  216. package/dist/core/session-role.d.ts.map +1 -1
  217. package/dist/core/session-role.js +14 -1
  218. package/dist/core/session-role.js.map +1 -1
  219. package/dist/core/session-tree-navigator.d.ts +4 -6
  220. package/dist/core/session-tree-navigator.d.ts.map +1 -1
  221. package/dist/core/session-tree-navigator.js +4 -1
  222. package/dist/core/session-tree-navigator.js.map +1 -1
  223. package/dist/core/settings-manager.d.ts +1 -1
  224. package/dist/core/settings-manager.d.ts.map +1 -1
  225. package/dist/core/settings-manager.js +1 -1
  226. package/dist/core/settings-manager.js.map +1 -1
  227. package/dist/core/slash-commands.d.ts.map +1 -1
  228. package/dist/core/slash-commands.js +2 -2
  229. package/dist/core/slash-commands.js.map +1 -1
  230. package/dist/core/tool-capability-policy.d.ts.map +1 -1
  231. package/dist/core/tool-capability-policy.js +1 -0
  232. package/dist/core/tool-capability-policy.js.map +1 -1
  233. package/dist/core/tool-gate-controller.d.ts.map +1 -1
  234. package/dist/core/tool-gate-controller.js +8 -2
  235. package/dist/core/tool-gate-controller.js.map +1 -1
  236. package/dist/core/tool-protocol-controller.d.ts +2 -4
  237. package/dist/core/tool-protocol-controller.d.ts.map +1 -1
  238. package/dist/core/tool-protocol-controller.js.map +1 -1
  239. package/dist/core/tool-recovery-stats.d.ts +21 -1
  240. package/dist/core/tool-recovery-stats.d.ts.map +1 -1
  241. package/dist/core/tool-recovery-stats.js.map +1 -1
  242. package/dist/core/tools/bash.d.ts +5 -0
  243. package/dist/core/tools/bash.d.ts.map +1 -1
  244. package/dist/core/tools/bash.js +59 -5
  245. package/dist/core/tools/bash.js.map +1 -1
  246. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  247. package/dist/core/tools/delegate-status.js +6 -7
  248. package/dist/core/tools/delegate-status.js.map +1 -1
  249. package/dist/core/tools/delegate.d.ts.map +1 -1
  250. package/dist/core/tools/delegate.js +6 -8
  251. package/dist/core/tools/delegate.js.map +1 -1
  252. package/dist/core/tools/git-filter.d.ts +1 -8
  253. package/dist/core/tools/git-filter.d.ts.map +1 -1
  254. package/dist/core/tools/git-filter.js +2 -63
  255. package/dist/core/tools/git-filter.js.map +1 -1
  256. package/dist/core/tools/goal.d.ts +5 -3
  257. package/dist/core/tools/goal.d.ts.map +1 -1
  258. package/dist/core/tools/goal.js +97 -19
  259. package/dist/core/tools/goal.js.map +1 -1
  260. package/dist/core/tools/index.d.ts +1 -0
  261. package/dist/core/tools/index.d.ts.map +1 -1
  262. package/dist/core/tools/index.js +1 -0
  263. package/dist/core/tools/index.js.map +1 -1
  264. package/dist/core/tools/orchestration-panel.d.ts +1 -4
  265. package/dist/core/tools/orchestration-panel.d.ts.map +1 -1
  266. package/dist/core/tools/orchestration-panel.js +0 -44
  267. package/dist/core/tools/orchestration-panel.js.map +1 -1
  268. package/dist/core/tools/output-accumulator.d.ts +11 -0
  269. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  270. package/dist/core/tools/output-accumulator.js +36 -3
  271. package/dist/core/tools/output-accumulator.js.map +1 -1
  272. package/dist/core/tools/python.d.ts +2 -0
  273. package/dist/core/tools/python.d.ts.map +1 -1
  274. package/dist/core/tools/python.js +3 -1
  275. package/dist/core/tools/python.js.map +1 -1
  276. package/dist/core/tools/read.d.ts.map +1 -1
  277. package/dist/core/tools/read.js +1 -1
  278. package/dist/core/tools/read.js.map +1 -1
  279. package/dist/core/tools/search-command-guard.d.ts +14 -0
  280. package/dist/core/tools/search-command-guard.d.ts.map +1 -0
  281. package/dist/core/tools/search-command-guard.js +333 -0
  282. package/dist/core/tools/search-command-guard.js.map +1 -0
  283. package/dist/core/tools/secret-store.d.ts +38 -0
  284. package/dist/core/tools/secret-store.d.ts.map +1 -0
  285. package/dist/core/tools/secret-store.js +412 -0
  286. package/dist/core/tools/secret-store.js.map +1 -0
  287. package/dist/core/tools/shell-command-parser.d.ts +16 -0
  288. package/dist/core/tools/shell-command-parser.d.ts.map +1 -0
  289. package/dist/core/tools/shell-command-parser.js +113 -0
  290. package/dist/core/tools/shell-command-parser.js.map +1 -0
  291. package/dist/core/tools/task-steps.d.ts.map +1 -1
  292. package/dist/core/tools/task-steps.js +4 -7
  293. package/dist/core/tools/task-steps.js.map +1 -1
  294. package/dist/core/util/atomic-file.d.ts +6 -2
  295. package/dist/core/util/atomic-file.d.ts.map +1 -1
  296. package/dist/core/util/atomic-file.js +4 -4
  297. package/dist/core/util/atomic-file.js.map +1 -1
  298. package/dist/index.d.ts +3 -2
  299. package/dist/index.d.ts.map +1 -1
  300. package/dist/index.js +2 -1
  301. package/dist/index.js.map +1 -1
  302. package/dist/main.d.ts.map +1 -1
  303. package/dist/main.js +25 -11
  304. package/dist/main.js.map +1 -1
  305. package/dist/modes/interactive/auth-dialogs-controller.d.ts +4 -0
  306. package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
  307. package/dist/modes/interactive/auth-dialogs-controller.js +60 -1
  308. package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
  309. package/dist/modes/interactive/components/activity-lane.d.ts +55 -0
  310. package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -0
  311. package/dist/modes/interactive/components/activity-lane.js +304 -0
  312. package/dist/modes/interactive/components/activity-lane.js.map +1 -0
  313. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  314. package/dist/modes/interactive/components/assistant-message.js +19 -10
  315. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  316. package/dist/modes/interactive/components/expandable-text.d.ts +12 -0
  317. package/dist/modes/interactive/components/expandable-text.d.ts.map +1 -0
  318. package/dist/modes/interactive/components/expandable-text.js +17 -0
  319. package/dist/modes/interactive/components/expandable-text.js.map +1 -0
  320. package/dist/modes/interactive/components/extension-editor.d.ts +15 -1
  321. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  322. package/dist/modes/interactive/components/extension-editor.js +30 -21
  323. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  324. package/dist/modes/interactive/components/extension-input.d.ts +1 -0
  325. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/extension-input.js +6 -1
  327. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  328. package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -2
  329. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  330. package/dist/modes/interactive/components/scoped-models-selector.js +23 -14
  331. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  332. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  333. package/dist/modes/interactive/components/settings-selector.js +4 -4
  334. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  335. package/dist/modes/interactive/components/tool-execution.d.ts +19 -11
  336. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  337. package/dist/modes/interactive/components/tool-execution.js +53 -20
  338. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  339. package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
  340. package/dist/modes/interactive/components/tool-group.js +3 -0
  341. package/dist/modes/interactive/components/tool-group.js.map +1 -1
  342. package/dist/modes/interactive/components/usage-action-selector.d.ts +16 -0
  343. package/dist/modes/interactive/components/usage-action-selector.d.ts.map +1 -0
  344. package/dist/modes/interactive/components/usage-action-selector.js +46 -0
  345. package/dist/modes/interactive/components/usage-action-selector.js.map +1 -0
  346. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
  347. package/dist/modes/interactive/extension-ui-host.js +1 -0
  348. package/dist/modes/interactive/extension-ui-host.js.map +1 -1
  349. package/dist/modes/interactive/external-editor.d.ts +15 -0
  350. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  351. package/dist/modes/interactive/external-editor.js +27 -19
  352. package/dist/modes/interactive/external-editor.js.map +1 -1
  353. package/dist/modes/interactive/history-reload-math.d.ts +6 -2
  354. package/dist/modes/interactive/history-reload-math.d.ts.map +1 -1
  355. package/dist/modes/interactive/history-reload-math.js +10 -5
  356. package/dist/modes/interactive/history-reload-math.js.map +1 -1
  357. package/dist/modes/interactive/interactive-event-controller.d.ts +74 -0
  358. package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -0
  359. package/dist/modes/interactive/interactive-event-controller.js +328 -0
  360. package/dist/modes/interactive/interactive-event-controller.js.map +1 -0
  361. package/dist/modes/interactive/interactive-mode.d.ts +20 -25
  362. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  363. package/dist/modes/interactive/interactive-mode.js +196 -608
  364. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  365. package/dist/modes/interactive/loaded-resources-view.d.ts +20 -0
  366. package/dist/modes/interactive/loaded-resources-view.d.ts.map +1 -0
  367. package/dist/modes/interactive/loaded-resources-view.js +147 -0
  368. package/dist/modes/interactive/loaded-resources-view.js.map +1 -0
  369. package/dist/modes/interactive/resource-display.d.ts.map +1 -1
  370. package/dist/modes/interactive/resource-display.js +8 -2
  371. package/dist/modes/interactive/resource-display.js.map +1 -1
  372. package/dist/modes/interactive/resource-shell-commands.d.ts +1 -5
  373. package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -1
  374. package/dist/modes/interactive/resource-shell-commands.js +0 -5
  375. package/dist/modes/interactive/resource-shell-commands.js.map +1 -1
  376. package/dist/modes/interactive/session-flow-commands.d.ts +10 -6
  377. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  378. package/dist/modes/interactive/session-flow-commands.js +123 -70
  379. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  380. package/dist/modes/interactive/usage-commands.d.ts +34 -0
  381. package/dist/modes/interactive/usage-commands.d.ts.map +1 -0
  382. package/dist/modes/interactive/usage-commands.js +225 -0
  383. package/dist/modes/interactive/usage-commands.js.map +1 -0
  384. package/dist/utils/shell.d.ts.map +1 -1
  385. package/dist/utils/shell.js +5 -3
  386. package/dist/utils/shell.js.map +1 -1
  387. package/dist/utils/version-check.d.ts.map +1 -1
  388. package/dist/utils/version-check.js +3 -1
  389. package/dist/utils/version-check.js.map +1 -1
  390. package/docs/UI_POLISH_ORCHESTRATION.md +25 -31
  391. package/docs/UI_QUALITY_ORCHESTRATION.md +22 -24
  392. package/docs/providers.md +9 -1
  393. package/docs/ui-reference/README.md +6 -6
  394. package/docs/ui-reference/orchestration-after.txt +14 -7
  395. package/docs/ui-reference/orchestration-before.txt +12 -6
  396. package/docs/ui-reference/orchestration-reference.txt +15 -5
  397. package/docs/usage.md +9 -1
  398. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  399. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  400. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  401. package/examples/extensions/sandbox/package-lock.json +2 -2
  402. package/examples/extensions/sandbox/package.json +1 -1
  403. package/examples/extensions/with-deps/package-lock.json +2 -2
  404. package/examples/extensions/with-deps/package.json +1 -1
  405. package/npm-shrinkwrap.json +13 -13
  406. package/package.json +4 -4
@@ -0,0 +1,112 @@
1
+ export declare const VAULT_MARKER = "pi-secret-vault-v1";
2
+ export declare const DEFAULT_SCRYPT_N = 32768;
3
+ export declare const MAX_VAULT_FILE_BYTES: number;
4
+ export declare const MAX_PROFILES = 64;
5
+ export declare const MAX_VARIABLES_PER_PROFILE = 64;
6
+ export declare const MAX_BINDINGS_PER_PROFILE = 16;
7
+ export declare const SECRET_PROFILE_ID_MAX_CHARS = 64;
8
+ export declare const SECRET_DESCRIPTION_MAX_CHARS = 240;
9
+ export declare const SECRET_PROFILE_ID_PATTERN = "^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,62}[A-Za-z0-9])?$";
10
+ export { SECRET_VARIABLE_NAME_MAX_CHARS, SECRET_VARIABLE_NAME_PATTERN } from "./secret-dotenv.ts";
11
+ export declare const SECRET_PRINTABLE_METADATA_PATTERN = "^[^\\u0000-\\u001f\\u007f-\\u009f]+$";
12
+ export declare const MANAGED_ENV_HEADER_PREFIX = "# pi-secret-store:v1 profile=";
13
+ export type SecretVaultErrorCode = "already_initialized" | "ambiguous_binding" | "binding_missing" | "destination_conflict" | "destination_invalid" | "invalid_description" | "invalid_dotenv" | "invalid_passphrase" | "invalid_profile" | "invalid_variable" | "not_initialized" | "not_unlocked" | "profile_limit" | "profile_missing" | "symlink_refused" | "unlock_failed" | "value_too_large" | "variable_limit" | "vault_corrupt" | "vault_too_large";
14
+ export declare class SecretVaultError extends Error {
15
+ readonly code: SecretVaultErrorCode;
16
+ constructor(code: SecretVaultErrorCode, message: string);
17
+ }
18
+ export interface SecretVariableValue {
19
+ name: string;
20
+ value: string;
21
+ }
22
+ export interface SecretProfileSummary {
23
+ profile: string;
24
+ description?: string;
25
+ variableNames: string[];
26
+ bindings: SecretBindingSummary[];
27
+ createdAt: string;
28
+ updatedAt: string;
29
+ }
30
+ export interface SecretBindingSummary {
31
+ workspace: string;
32
+ envFile: string;
33
+ updatedAt: string;
34
+ }
35
+ export interface SecretBindingResolution extends SecretBindingSummary {
36
+ profile: string;
37
+ destination: string;
38
+ variableNames: string[];
39
+ }
40
+ export type SecretEnvDestinationState = "missing" | "managed-profile" | "managed-other" | "unmanaged";
41
+ export interface SecretMaterializationResult {
42
+ profile: string;
43
+ variableNames: string[];
44
+ previousState: SecretEnvDestinationState;
45
+ }
46
+ export interface SecretRemovalResult {
47
+ profile: string;
48
+ removedProfile: boolean;
49
+ removedVariableNames: string[];
50
+ managedMaterializationRemoved: boolean;
51
+ boundMaterializationsRemoved: number;
52
+ }
53
+ export interface SecretVaultOptions {
54
+ agentDir: string;
55
+ /** Test-only cost override. Production callers should retain the default. */
56
+ scryptN?: number;
57
+ now?: () => Date;
58
+ /** Reset credential-bearing child process state after activation, mutation, or lock. */
59
+ onEnvironmentChanged?: () => void;
60
+ }
61
+ export interface VaultKdf {
62
+ algorithm: "scrypt";
63
+ salt: string;
64
+ N: number;
65
+ r: number;
66
+ p: number;
67
+ keyLength: number;
68
+ }
69
+ export interface VaultCiphertext {
70
+ iv: string;
71
+ tag: string;
72
+ ciphertext: string;
73
+ }
74
+ export interface VaultEnvelope {
75
+ version: 1;
76
+ kdf: VaultKdf;
77
+ payload: VaultCiphertext;
78
+ }
79
+ export interface SecretProfileRecord {
80
+ profile: string;
81
+ description?: string;
82
+ createdAt: string;
83
+ updatedAt: string;
84
+ dotenv: string;
85
+ bindings: SecretBindingSummary[];
86
+ }
87
+ export interface VaultPayload {
88
+ marker: typeof VAULT_MARKER;
89
+ profiles: SecretProfileRecord[];
90
+ }
91
+ export declare function validateScryptN(value: number): number;
92
+ export declare function createVaultKdf(scryptN: number): VaultKdf;
93
+ export declare function parseEnvelope(text: string): VaultEnvelope;
94
+ export declare function validateProfileId(profile: string): string;
95
+ export declare function validateDescription(description: string | undefined): string | undefined;
96
+ export declare function validateBindingWorkspace(workspace: string): string;
97
+ export declare function validateBindingEnvFile(envFile: string): string;
98
+ export declare function validateVariableName(name: string): string;
99
+ export declare function validateSecretValue(value: string): string;
100
+ export declare function validateDotenvProfileDocument(document: string): {
101
+ document: string;
102
+ variables: SecretVariableValue[];
103
+ };
104
+ export declare function scrubPayload(payload: VaultPayload): void;
105
+ export declare function assertPassphrase(passphrase: string, creating: boolean): void;
106
+ export declare function sameKdf(left: VaultKdf, right: VaultKdf): boolean;
107
+ export declare function deriveKey(passphrase: string, kdf: VaultKdf): Promise<Buffer>;
108
+ export declare function decryptPayload(ciphertext: VaultCiphertext, key: Buffer): VaultPayload;
109
+ export declare function serializeEnvelope(kdf: VaultKdf, payload: VaultPayload, key: Buffer): string;
110
+ export declare function profileSummary(profile: SecretProfileRecord): SecretProfileSummary;
111
+ export declare function serializeVariableValues(values: readonly SecretVariableValue[]): string;
112
+ //# sourceMappingURL=secret-vault-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-vault-format.d.ts","sourceRoot":"","sources":["../../../src/core/secrets/secret-vault-format.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCipheriv, createDecipheriv, randomBytes, scrypt } from \"node:crypto\";\nimport { isAbsolute, normalize, sep } from \"node:path\";\nimport {\n\tformatDotenvVariables,\n\tMAX_DOTENV_VARIABLES,\n\tparseDotenvDocument,\n\tSecretDotenvError,\n\tvalidateDotenvValue,\n\tvalidateDotenvVariableName,\n} from \"./secret-dotenv.ts\";\n\nconst VAULT_VERSION = 1;\nexport const VAULT_MARKER = \"pi-secret-vault-v1\";\nconst VAULT_AAD = Buffer.from(\"pi-secret-vault:v1\", \"utf8\");\nconst AES_ALGORITHM = \"aes-256-gcm\";\nconst KEY_LENGTH = 32;\nconst IV_LENGTH = 12;\nconst AUTH_TAG_LENGTH = 16;\nconst SALT_LENGTH = 16;\nexport const DEFAULT_SCRYPT_N = 32_768;\nconst SCRYPT_R = 8;\nconst SCRYPT_P = 1;\nconst MIN_SCRYPT_N = 1_024;\nconst MAX_SCRYPT_N = 65_536;\nexport const MAX_VAULT_FILE_BYTES = 4 * 1024 * 1024;\nconst MAX_VAULT_PAYLOAD_BYTES = 2 * 1024 * 1024;\nexport const MAX_PROFILES = 64;\nexport const MAX_VARIABLES_PER_PROFILE = MAX_DOTENV_VARIABLES;\nexport const MAX_BINDINGS_PER_PROFILE = 16;\nconst MAX_PASSPHRASE_CHARS = 4_096;\nconst MIN_NEW_PASSPHRASE_CHARS = 12;\nexport const SECRET_PROFILE_ID_MAX_CHARS = 64;\nexport const SECRET_DESCRIPTION_MAX_CHARS = 240;\nexport const SECRET_PROFILE_ID_PATTERN = `^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,${SECRET_PROFILE_ID_MAX_CHARS - 2}}[A-Za-z0-9])?$`;\nexport { SECRET_VARIABLE_NAME_MAX_CHARS, SECRET_VARIABLE_NAME_PATTERN } from \"./secret-dotenv.ts\";\nexport const SECRET_PRINTABLE_METADATA_PATTERN = \"^[^\\\\u0000-\\\\u001f\\\\u007f-\\\\u009f]+$\";\nexport const MANAGED_ENV_HEADER_PREFIX = \"# pi-secret-store:v1 profile=\";\nconst PROFILE_ID_RE = new RegExp(SECRET_PROFILE_ID_PATTERN);\nconst PRINTABLE_METADATA_RE = new RegExp(SECRET_PRINTABLE_METADATA_PATTERN);\nconst WINDOWS_RESERVED_NAME_RE = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\.|$)/i;\n\nexport type SecretVaultErrorCode =\n\t| \"already_initialized\"\n\t| \"ambiguous_binding\"\n\t| \"binding_missing\"\n\t| \"destination_conflict\"\n\t| \"destination_invalid\"\n\t| \"invalid_description\"\n\t| \"invalid_dotenv\"\n\t| \"invalid_passphrase\"\n\t| \"invalid_profile\"\n\t| \"invalid_variable\"\n\t| \"not_initialized\"\n\t| \"not_unlocked\"\n\t| \"profile_limit\"\n\t| \"profile_missing\"\n\t| \"symlink_refused\"\n\t| \"unlock_failed\"\n\t| \"value_too_large\"\n\t| \"variable_limit\"\n\t| \"vault_corrupt\"\n\t| \"vault_too_large\";\n\nexport class SecretVaultError extends Error {\n\treadonly code: SecretVaultErrorCode;\n\n\tconstructor(code: SecretVaultErrorCode, message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"SecretVaultError\";\n\t\tthis.code = code;\n\t}\n}\n\nexport interface SecretVariableValue {\n\tname: string;\n\tvalue: string;\n}\n\nexport interface SecretProfileSummary {\n\tprofile: string;\n\tdescription?: string;\n\tvariableNames: string[];\n\tbindings: SecretBindingSummary[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface SecretBindingSummary {\n\tworkspace: string;\n\tenvFile: string;\n\tupdatedAt: string;\n}\n\nexport interface SecretBindingResolution extends SecretBindingSummary {\n\tprofile: string;\n\tdestination: string;\n\tvariableNames: string[];\n}\n\nexport type SecretEnvDestinationState = \"missing\" | \"managed-profile\" | \"managed-other\" | \"unmanaged\";\n\nexport interface SecretMaterializationResult {\n\tprofile: string;\n\tvariableNames: string[];\n\tpreviousState: SecretEnvDestinationState;\n}\n\nexport interface SecretRemovalResult {\n\tprofile: string;\n\tremovedProfile: boolean;\n\tremovedVariableNames: string[];\n\tmanagedMaterializationRemoved: boolean;\n\tboundMaterializationsRemoved: number;\n}\n\nexport interface SecretVaultOptions {\n\tagentDir: string;\n\t/** Test-only cost override. Production callers should retain the default. */\n\tscryptN?: number;\n\tnow?: () => Date;\n\t/** Reset credential-bearing child process state after activation, mutation, or lock. */\n\tonEnvironmentChanged?: () => void;\n}\n\nexport interface VaultKdf {\n\talgorithm: \"scrypt\";\n\tsalt: string;\n\tN: number;\n\tr: number;\n\tp: number;\n\tkeyLength: number;\n}\n\nexport interface VaultCiphertext {\n\tiv: string;\n\ttag: string;\n\tciphertext: string;\n}\n\nexport interface VaultEnvelope {\n\tversion: 1;\n\tkdf: VaultKdf;\n\tpayload: VaultCiphertext;\n}\n\nexport interface SecretProfileRecord {\n\tprofile: string;\n\tdescription?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tdotenv: string;\n\tbindings: SecretBindingSummary[];\n}\n\nexport interface VaultPayload {\n\tmarker: typeof VAULT_MARKER;\n\tprofiles: SecretProfileRecord[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction decodeCanonicalBase64(value: unknown, field: string, expectedBytes?: number): Buffer {\n\tif (typeof value !== \"string\" || value.length === 0 || value.length > MAX_VAULT_FILE_BYTES) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", `Secret vault ${field} is invalid.`);\n\t}\n\tconst decoded = Buffer.from(value, \"base64\");\n\tif (decoded.toString(\"base64\") !== value || (expectedBytes !== undefined && decoded.byteLength !== expectedBytes)) {\n\t\tdecoded.fill(0);\n\t\tthrow new SecretVaultError(\"vault_corrupt\", `Secret vault ${field} is invalid.`);\n\t}\n\treturn decoded;\n}\n\nexport function validateScryptN(value: number): number {\n\tif (!Number.isInteger(value) || value < MIN_SCRYPT_N || value > MAX_SCRYPT_N || (value & (value - 1)) !== 0) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault KDF settings are invalid.\");\n\t}\n\treturn value;\n}\n\nexport function createVaultKdf(scryptN: number): VaultKdf {\n\tconst salt = randomBytes(SALT_LENGTH);\n\ttry {\n\t\treturn {\n\t\t\talgorithm: \"scrypt\",\n\t\t\tsalt: salt.toString(\"base64\"),\n\t\t\tN: validateScryptN(scryptN),\n\t\t\tr: SCRYPT_R,\n\t\t\tp: SCRYPT_P,\n\t\t\tkeyLength: KEY_LENGTH,\n\t\t};\n\t} finally {\n\t\tsalt.fill(0);\n\t}\n}\n\nfunction parseKdf(value: unknown): VaultKdf {\n\tif (!isRecord(value)) throw new SecretVaultError(\"vault_corrupt\", \"Secret vault KDF is missing.\");\n\tif (value.algorithm !== \"scrypt\" || value.r !== SCRYPT_R || value.p !== SCRYPT_P || value.keyLength !== KEY_LENGTH) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault KDF settings are unsupported.\");\n\t}\n\tconst salt = decodeCanonicalBase64(value.salt, \"salt\", SALT_LENGTH);\n\tsalt.fill(0);\n\treturn {\n\t\talgorithm: \"scrypt\",\n\t\tsalt: value.salt as string,\n\t\tN: validateScryptN(value.N as number),\n\t\tr: SCRYPT_R,\n\t\tp: SCRYPT_P,\n\t\tkeyLength: KEY_LENGTH,\n\t};\n}\n\nfunction parseCiphertext(value: unknown): VaultCiphertext {\n\tif (!isRecord(value)) throw new SecretVaultError(\"vault_corrupt\", \"Secret vault payload is missing.\");\n\tconst iv = decodeCanonicalBase64(value.iv, \"IV\", IV_LENGTH);\n\tconst tag = decodeCanonicalBase64(value.tag, \"authentication tag\", AUTH_TAG_LENGTH);\n\tconst ciphertext = decodeCanonicalBase64(value.ciphertext, \"ciphertext\");\n\tiv.fill(0);\n\ttag.fill(0);\n\tciphertext.fill(0);\n\treturn {\n\t\tiv: value.iv as string,\n\t\ttag: value.tag as string,\n\t\tciphertext: value.ciphertext as string,\n\t};\n}\n\nexport function parseEnvelope(text: string): VaultEnvelope {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(text);\n\t} catch {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault data is not valid JSON.\");\n\t}\n\tif (!isRecord(parsed) || parsed.version !== VAULT_VERSION) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault version is unsupported.\");\n\t}\n\treturn { version: VAULT_VERSION, kdf: parseKdf(parsed.kdf), payload: parseCiphertext(parsed.payload) };\n}\n\nexport function validateProfileId(profile: string): string {\n\tif (!PROFILE_ID_RE.test(profile) || WINDOWS_RESERVED_NAME_RE.test(profile)) {\n\t\tthrow new SecretVaultError(\n\t\t\t\"invalid_profile\",\n\t\t\t\"Profile names must be portable 1-64 character identifiers using letters, numbers, dot, dash, or underscore.\",\n\t\t);\n\t}\n\treturn profile;\n}\n\nexport function validateDescription(description: string | undefined): string | undefined {\n\tif (description === undefined) return undefined;\n\tconst normalized = description.trim();\n\tif (!normalized || normalized.length > SECRET_DESCRIPTION_MAX_CHARS || !PRINTABLE_METADATA_RE.test(normalized)) {\n\t\tthrow new SecretVaultError(\"invalid_description\", \"Secret profile descriptions must be short printable text.\");\n\t}\n\treturn normalized;\n}\n\nexport function validateBindingWorkspace(workspace: string): string {\n\tif (\n\t\t!isAbsolute(workspace) ||\n\t\tworkspace.length > 4_096 ||\n\t\tworkspace.includes(\"\\0\") ||\n\t\t/[\\u0000-\\u001f\\u007f-\\u009f]/.test(workspace)\n\t) {\n\t\tthrow new SecretVaultError(\"destination_invalid\", \"Credential workspace must be an absolute local path.\");\n\t}\n\treturn normalize(workspace);\n}\n\nexport function validateBindingEnvFile(envFile: string): string {\n\tconst trimmed = envFile.trim();\n\tconst normalized = normalize(trimmed);\n\tconst segments = normalized.split(/[\\\\/]+/);\n\tconst fileName = segments.at(-1) ?? \"\";\n\tif (\n\t\t!trimmed ||\n\t\ttrimmed.length > 512 ||\n\t\tisAbsolute(trimmed) ||\n\t\tnormalized === \"..\" ||\n\t\tnormalized.startsWith(`..${sep}`) ||\n\t\tsegments.includes(\"..\") ||\n\t\ttrimmed.includes(\"\\0\") ||\n\t\t/[\\u0000-\\u001f\\u007f-\\u009f]/.test(trimmed) ||\n\t\t!(fileName === \".env\" || fileName.startsWith(\".env.\") || fileName.endsWith(\".env\"))\n\t) {\n\t\tthrow new SecretVaultError(\n\t\t\t\"destination_invalid\",\n\t\t\t\"Credential target must be a relative dotenv path inside the workspace (for example .env or config/dev.env).\",\n\t\t);\n\t}\n\treturn normalized;\n}\n\nfunction parseBinding(value: unknown): SecretBindingSummary {\n\tif (!isRecord(value) || typeof value.workspace !== \"string\" || typeof value.envFile !== \"string\") {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault binding data is invalid.\");\n\t}\n\ttry {\n\t\treturn {\n\t\t\tworkspace: validateBindingWorkspace(value.workspace),\n\t\t\tenvFile: validateBindingEnvFile(value.envFile),\n\t\t\tupdatedAt: validateTimestamp(value.updatedAt),\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SecretVaultError) {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault binding data is invalid.\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function validateVariableName(name: string): string {\n\ttry {\n\t\treturn validateDotenvVariableName(name);\n\t} catch (error) {\n\t\tif (error instanceof SecretDotenvError) {\n\t\t\tthrow new SecretVaultError(\"invalid_variable\", \"Environment variable names must use portable dotenv syntax.\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function validateSecretValue(value: string): string {\n\ttry {\n\t\treturn validateDotenvValue(value);\n\t} catch (error) {\n\t\tif (error instanceof SecretDotenvError) {\n\t\t\tthrow new SecretVaultError(\n\t\t\t\terror.message.includes(\"64 KiB\") ? \"value_too_large\" : \"invalid_variable\",\n\t\t\t\terror.message.includes(\"64 KiB\")\n\t\t\t\t\t? \"A secret value exceeds the 64 KiB limit.\"\n\t\t\t\t\t: \"Secret values cannot contain null bytes.\",\n\t\t\t);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function validateDotenvProfileDocument(document: string): {\n\tdocument: string;\n\tvariables: SecretVariableValue[];\n} {\n\ttry {\n\t\treturn parseDotenvDocument(document);\n\t} catch (error) {\n\t\tif (error instanceof SecretDotenvError) throw new SecretVaultError(\"invalid_dotenv\", error.message);\n\t\tthrow error;\n\t}\n}\n\nfunction validateTimestamp(value: unknown): string {\n\tif (typeof value !== \"string\" || value.length > 64 || Number.isNaN(Date.parse(value))) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault timestamps are invalid.\");\n\t}\n\treturn value;\n}\n\nfunction parsePayload(value: unknown): VaultPayload {\n\tif (!isRecord(value) || value.marker !== VAULT_MARKER || !Array.isArray(value.profiles)) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault payload is invalid.\");\n\t}\n\tif (value.profiles.length > MAX_PROFILES) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault profile count exceeds its bound.\");\n\t}\n\tconst profileNames = new Set<string>();\n\tconst profiles: SecretProfileRecord[] = value.profiles.map((candidate) => {\n\t\tif (!isRecord(candidate) || typeof candidate.dotenv !== \"string\" || !Array.isArray(candidate.bindings)) {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault profile data is invalid.\");\n\t\t}\n\t\tconst profile = validateProfileId(typeof candidate.profile === \"string\" ? candidate.profile : \"\");\n\t\tif (profileNames.has(profile))\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault profiles are duplicated.\");\n\t\tprofileNames.add(profile);\n\t\tlet dotenv: string;\n\t\ttry {\n\t\t\tdotenv = validateDotenvProfileDocument(candidate.dotenv).document;\n\t\t} catch {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault dotenv data is invalid.\");\n\t\t}\n\t\tif (candidate.bindings.length > MAX_BINDINGS_PER_PROFILE) {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault binding count exceeds its bound.\");\n\t\t}\n\t\tconst bindingIds = new Set<string>();\n\t\tconst bindings = candidate.bindings.map((binding) => {\n\t\t\tconst parsed = parseBinding(binding);\n\t\t\tconst id = `${parsed.workspace}\\0${parsed.envFile}`;\n\t\t\tif (bindingIds.has(id)) throw new SecretVaultError(\"vault_corrupt\", \"Secret vault bindings are duplicated.\");\n\t\t\tbindingIds.add(id);\n\t\t\treturn parsed;\n\t\t});\n\t\treturn {\n\t\t\tprofile,\n\t\t\t...(candidate.description !== undefined\n\t\t\t\t? {\n\t\t\t\t\t\tdescription: validateDescription(\n\t\t\t\t\t\t\ttypeof candidate.description === \"string\" ? candidate.description : \"\",\n\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\tcreatedAt: validateTimestamp(candidate.createdAt),\n\t\t\tupdatedAt: validateTimestamp(candidate.updatedAt),\n\t\t\tdotenv,\n\t\t\tbindings: bindings.sort(\n\t\t\t\t(left, right) => left.workspace.localeCompare(right.workspace) || left.envFile.localeCompare(right.envFile),\n\t\t\t),\n\t\t};\n\t});\n\treturn { marker: VAULT_MARKER, profiles: profiles.sort((left, right) => left.profile.localeCompare(right.profile)) };\n}\n\nexport function scrubPayload(payload: VaultPayload): void {\n\tfor (const profile of payload.profiles) profile.dotenv = \"\";\n}\n\nexport function assertPassphrase(passphrase: string, creating: boolean): void {\n\tif (\n\t\tpassphrase.length > MAX_PASSPHRASE_CHARS ||\n\t\tpassphrase.includes(\"\\0\") ||\n\t\t(creating ? passphrase.length < MIN_NEW_PASSPHRASE_CHARS : passphrase.length === 0)\n\t) {\n\t\tthrow new SecretVaultError(\n\t\t\t\"invalid_passphrase\",\n\t\t\tcreating\n\t\t\t\t? `The vault passphrase must contain ${MIN_NEW_PASSPHRASE_CHARS}-${MAX_PASSPHRASE_CHARS} characters.`\n\t\t\t\t: \"The vault passphrase is invalid.\",\n\t\t);\n\t}\n}\n\nexport function sameKdf(left: VaultKdf, right: VaultKdf): boolean {\n\treturn (\n\t\tleft.algorithm === right.algorithm &&\n\t\tleft.salt === right.salt &&\n\t\tleft.N === right.N &&\n\t\tleft.r === right.r &&\n\t\tleft.p === right.p &&\n\t\tleft.keyLength === right.keyLength\n\t);\n}\n\nexport async function deriveKey(passphrase: string, kdf: VaultKdf): Promise<Buffer> {\n\tconst salt = Buffer.from(kdf.salt, \"base64\");\n\tconst maxmem = Math.max(64 * 1024 * 1024, 128 * kdf.N * kdf.r + 16 * 1024 * 1024);\n\ttry {\n\t\treturn await new Promise<Buffer>((resolveKey, reject) => {\n\t\t\tscrypt(passphrase, salt, kdf.keyLength, { N: kdf.N, r: kdf.r, p: kdf.p, maxmem }, (error, key) => {\n\t\t\t\tif (error) reject(error);\n\t\t\t\telse resolveKey(key);\n\t\t\t});\n\t\t});\n\t} finally {\n\t\tsalt.fill(0);\n\t}\n}\n\nfunction encryptPayload(payload: VaultPayload, key: Buffer): VaultCiphertext {\n\tlet serialized = JSON.stringify(payload);\n\tif (Buffer.byteLength(serialized, \"utf8\") > MAX_VAULT_PAYLOAD_BYTES) {\n\t\tserialized = \"\";\n\t\tthrow new SecretVaultError(\"vault_too_large\", \"Secret vault payload exceeds its 2 MiB limit.\");\n\t}\n\tconst plaintext = Buffer.from(serialized, \"utf8\");\n\tserialized = \"\";\n\tconst iv = randomBytes(IV_LENGTH);\n\ttry {\n\t\tconst cipher = createCipheriv(AES_ALGORITHM, key, iv);\n\t\tcipher.setAAD(VAULT_AAD);\n\t\tconst ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);\n\t\tconst tag = cipher.getAuthTag();\n\t\ttry {\n\t\t\treturn {\n\t\t\t\tiv: iv.toString(\"base64\"),\n\t\t\t\ttag: tag.toString(\"base64\"),\n\t\t\t\tciphertext: ciphertext.toString(\"base64\"),\n\t\t\t};\n\t\t} finally {\n\t\t\ttag.fill(0);\n\t\t\tciphertext.fill(0);\n\t\t}\n\t} finally {\n\t\tplaintext.fill(0);\n\t\tiv.fill(0);\n\t}\n}\n\nexport function decryptPayload(ciphertext: VaultCiphertext, key: Buffer): VaultPayload {\n\tconst iv = Buffer.from(ciphertext.iv, \"base64\");\n\tconst tag = Buffer.from(ciphertext.tag, \"base64\");\n\tconst encrypted = Buffer.from(ciphertext.ciphertext, \"base64\");\n\tlet plaintext: Buffer | undefined;\n\ttry {\n\t\tconst decipher = createDecipheriv(AES_ALGORITHM, key, iv);\n\t\tdecipher.setAAD(VAULT_AAD);\n\t\tdecipher.setAuthTag(tag);\n\t\tplaintext = Buffer.concat([decipher.update(encrypted), decipher.final()]);\n\t\tif (plaintext.byteLength > MAX_VAULT_PAYLOAD_BYTES) {\n\t\t\tthrow new SecretVaultError(\"vault_too_large\", \"Secret vault payload exceeds its 2 MiB limit.\");\n\t\t}\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(plaintext.toString(\"utf8\"));\n\t\t} catch {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault payload is invalid.\");\n\t\t}\n\t\treturn parsePayload(parsed);\n\t} catch (error) {\n\t\tif (error instanceof SecretVaultError) throw error;\n\t\tthrow new SecretVaultError(\"unlock_failed\", \"The vault passphrase is incorrect or the vault is damaged.\");\n\t} finally {\n\t\tiv.fill(0);\n\t\ttag.fill(0);\n\t\tencrypted.fill(0);\n\t\tplaintext?.fill(0);\n\t}\n}\n\nexport function serializeEnvelope(kdf: VaultKdf, payload: VaultPayload, key: Buffer): string {\n\tconst envelope: VaultEnvelope = { version: VAULT_VERSION, kdf, payload: encryptPayload(payload, key) };\n\tconst serialized = `${JSON.stringify(envelope, null, 2)}\\n`;\n\tif (Buffer.byteLength(serialized, \"utf8\") > MAX_VAULT_FILE_BYTES) {\n\t\tthrow new SecretVaultError(\"vault_too_large\", \"Secret vault file exceeds its 4 MiB limit.\");\n\t}\n\treturn serialized;\n}\n\nexport function profileSummary(profile: SecretProfileRecord): SecretProfileSummary {\n\tconst parsed = validateDotenvProfileDocument(profile.dotenv);\n\treturn {\n\t\tprofile: profile.profile,\n\t\t...(profile.description ? { description: profile.description } : {}),\n\t\tvariableNames: parsed.variables.map((variable) => variable.name),\n\t\tbindings: profile.bindings.map((binding) => ({ ...binding })),\n\t\tcreatedAt: profile.createdAt,\n\t\tupdatedAt: profile.updatedAt,\n\t};\n}\n\nexport function serializeVariableValues(values: readonly SecretVariableValue[]): string {\n\treturn formatDotenvVariables(values);\n}\n"]}
@@ -0,0 +1,397 @@
1
+ import { createCipheriv, createDecipheriv, randomBytes, scrypt } from "node:crypto";
2
+ import { isAbsolute, normalize, sep } from "node:path";
3
+ import { formatDotenvVariables, MAX_DOTENV_VARIABLES, parseDotenvDocument, SecretDotenvError, validateDotenvValue, validateDotenvVariableName, } from "./secret-dotenv.js";
4
+ const VAULT_VERSION = 1;
5
+ export const VAULT_MARKER = "pi-secret-vault-v1";
6
+ const VAULT_AAD = Buffer.from("pi-secret-vault:v1", "utf8");
7
+ const AES_ALGORITHM = "aes-256-gcm";
8
+ const KEY_LENGTH = 32;
9
+ const IV_LENGTH = 12;
10
+ const AUTH_TAG_LENGTH = 16;
11
+ const SALT_LENGTH = 16;
12
+ export const DEFAULT_SCRYPT_N = 32_768;
13
+ const SCRYPT_R = 8;
14
+ const SCRYPT_P = 1;
15
+ const MIN_SCRYPT_N = 1_024;
16
+ const MAX_SCRYPT_N = 65_536;
17
+ export const MAX_VAULT_FILE_BYTES = 4 * 1024 * 1024;
18
+ const MAX_VAULT_PAYLOAD_BYTES = 2 * 1024 * 1024;
19
+ export const MAX_PROFILES = 64;
20
+ export const MAX_VARIABLES_PER_PROFILE = MAX_DOTENV_VARIABLES;
21
+ export const MAX_BINDINGS_PER_PROFILE = 16;
22
+ const MAX_PASSPHRASE_CHARS = 4_096;
23
+ const MIN_NEW_PASSPHRASE_CHARS = 12;
24
+ export const SECRET_PROFILE_ID_MAX_CHARS = 64;
25
+ export const SECRET_DESCRIPTION_MAX_CHARS = 240;
26
+ export const SECRET_PROFILE_ID_PATTERN = `^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,${SECRET_PROFILE_ID_MAX_CHARS - 2}}[A-Za-z0-9])?$`;
27
+ export { SECRET_VARIABLE_NAME_MAX_CHARS, SECRET_VARIABLE_NAME_PATTERN } from "./secret-dotenv.js";
28
+ export const SECRET_PRINTABLE_METADATA_PATTERN = "^[^\\u0000-\\u001f\\u007f-\\u009f]+$";
29
+ export const MANAGED_ENV_HEADER_PREFIX = "# pi-secret-store:v1 profile=";
30
+ const PROFILE_ID_RE = new RegExp(SECRET_PROFILE_ID_PATTERN);
31
+ const PRINTABLE_METADATA_RE = new RegExp(SECRET_PRINTABLE_METADATA_PATTERN);
32
+ const WINDOWS_RESERVED_NAME_RE = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i;
33
+ export class SecretVaultError extends Error {
34
+ code;
35
+ constructor(code, message) {
36
+ super(message);
37
+ this.name = "SecretVaultError";
38
+ this.code = code;
39
+ }
40
+ }
41
+ function isRecord(value) {
42
+ return typeof value === "object" && value !== null && !Array.isArray(value);
43
+ }
44
+ function decodeCanonicalBase64(value, field, expectedBytes) {
45
+ if (typeof value !== "string" || value.length === 0 || value.length > MAX_VAULT_FILE_BYTES) {
46
+ throw new SecretVaultError("vault_corrupt", `Secret vault ${field} is invalid.`);
47
+ }
48
+ const decoded = Buffer.from(value, "base64");
49
+ if (decoded.toString("base64") !== value || (expectedBytes !== undefined && decoded.byteLength !== expectedBytes)) {
50
+ decoded.fill(0);
51
+ throw new SecretVaultError("vault_corrupt", `Secret vault ${field} is invalid.`);
52
+ }
53
+ return decoded;
54
+ }
55
+ export function validateScryptN(value) {
56
+ if (!Number.isInteger(value) || value < MIN_SCRYPT_N || value > MAX_SCRYPT_N || (value & (value - 1)) !== 0) {
57
+ throw new SecretVaultError("vault_corrupt", "Secret vault KDF settings are invalid.");
58
+ }
59
+ return value;
60
+ }
61
+ export function createVaultKdf(scryptN) {
62
+ const salt = randomBytes(SALT_LENGTH);
63
+ try {
64
+ return {
65
+ algorithm: "scrypt",
66
+ salt: salt.toString("base64"),
67
+ N: validateScryptN(scryptN),
68
+ r: SCRYPT_R,
69
+ p: SCRYPT_P,
70
+ keyLength: KEY_LENGTH,
71
+ };
72
+ }
73
+ finally {
74
+ salt.fill(0);
75
+ }
76
+ }
77
+ function parseKdf(value) {
78
+ if (!isRecord(value))
79
+ throw new SecretVaultError("vault_corrupt", "Secret vault KDF is missing.");
80
+ if (value.algorithm !== "scrypt" || value.r !== SCRYPT_R || value.p !== SCRYPT_P || value.keyLength !== KEY_LENGTH) {
81
+ throw new SecretVaultError("vault_corrupt", "Secret vault KDF settings are unsupported.");
82
+ }
83
+ const salt = decodeCanonicalBase64(value.salt, "salt", SALT_LENGTH);
84
+ salt.fill(0);
85
+ return {
86
+ algorithm: "scrypt",
87
+ salt: value.salt,
88
+ N: validateScryptN(value.N),
89
+ r: SCRYPT_R,
90
+ p: SCRYPT_P,
91
+ keyLength: KEY_LENGTH,
92
+ };
93
+ }
94
+ function parseCiphertext(value) {
95
+ if (!isRecord(value))
96
+ throw new SecretVaultError("vault_corrupt", "Secret vault payload is missing.");
97
+ const iv = decodeCanonicalBase64(value.iv, "IV", IV_LENGTH);
98
+ const tag = decodeCanonicalBase64(value.tag, "authentication tag", AUTH_TAG_LENGTH);
99
+ const ciphertext = decodeCanonicalBase64(value.ciphertext, "ciphertext");
100
+ iv.fill(0);
101
+ tag.fill(0);
102
+ ciphertext.fill(0);
103
+ return {
104
+ iv: value.iv,
105
+ tag: value.tag,
106
+ ciphertext: value.ciphertext,
107
+ };
108
+ }
109
+ export function parseEnvelope(text) {
110
+ let parsed;
111
+ try {
112
+ parsed = JSON.parse(text);
113
+ }
114
+ catch {
115
+ throw new SecretVaultError("vault_corrupt", "Secret vault data is not valid JSON.");
116
+ }
117
+ if (!isRecord(parsed) || parsed.version !== VAULT_VERSION) {
118
+ throw new SecretVaultError("vault_corrupt", "Secret vault version is unsupported.");
119
+ }
120
+ return { version: VAULT_VERSION, kdf: parseKdf(parsed.kdf), payload: parseCiphertext(parsed.payload) };
121
+ }
122
+ export function validateProfileId(profile) {
123
+ if (!PROFILE_ID_RE.test(profile) || WINDOWS_RESERVED_NAME_RE.test(profile)) {
124
+ throw new SecretVaultError("invalid_profile", "Profile names must be portable 1-64 character identifiers using letters, numbers, dot, dash, or underscore.");
125
+ }
126
+ return profile;
127
+ }
128
+ export function validateDescription(description) {
129
+ if (description === undefined)
130
+ return undefined;
131
+ const normalized = description.trim();
132
+ if (!normalized || normalized.length > SECRET_DESCRIPTION_MAX_CHARS || !PRINTABLE_METADATA_RE.test(normalized)) {
133
+ throw new SecretVaultError("invalid_description", "Secret profile descriptions must be short printable text.");
134
+ }
135
+ return normalized;
136
+ }
137
+ export function validateBindingWorkspace(workspace) {
138
+ if (!isAbsolute(workspace) ||
139
+ workspace.length > 4_096 ||
140
+ workspace.includes("\0") ||
141
+ /[\u0000-\u001f\u007f-\u009f]/.test(workspace)) {
142
+ throw new SecretVaultError("destination_invalid", "Credential workspace must be an absolute local path.");
143
+ }
144
+ return normalize(workspace);
145
+ }
146
+ export function validateBindingEnvFile(envFile) {
147
+ const trimmed = envFile.trim();
148
+ const normalized = normalize(trimmed);
149
+ const segments = normalized.split(/[\\/]+/);
150
+ const fileName = segments.at(-1) ?? "";
151
+ if (!trimmed ||
152
+ trimmed.length > 512 ||
153
+ isAbsolute(trimmed) ||
154
+ normalized === ".." ||
155
+ normalized.startsWith(`..${sep}`) ||
156
+ segments.includes("..") ||
157
+ trimmed.includes("\0") ||
158
+ /[\u0000-\u001f\u007f-\u009f]/.test(trimmed) ||
159
+ !(fileName === ".env" || fileName.startsWith(".env.") || fileName.endsWith(".env"))) {
160
+ throw new SecretVaultError("destination_invalid", "Credential target must be a relative dotenv path inside the workspace (for example .env or config/dev.env).");
161
+ }
162
+ return normalized;
163
+ }
164
+ function parseBinding(value) {
165
+ if (!isRecord(value) || typeof value.workspace !== "string" || typeof value.envFile !== "string") {
166
+ throw new SecretVaultError("vault_corrupt", "Secret vault binding data is invalid.");
167
+ }
168
+ try {
169
+ return {
170
+ workspace: validateBindingWorkspace(value.workspace),
171
+ envFile: validateBindingEnvFile(value.envFile),
172
+ updatedAt: validateTimestamp(value.updatedAt),
173
+ };
174
+ }
175
+ catch (error) {
176
+ if (error instanceof SecretVaultError) {
177
+ throw new SecretVaultError("vault_corrupt", "Secret vault binding data is invalid.");
178
+ }
179
+ throw error;
180
+ }
181
+ }
182
+ export function validateVariableName(name) {
183
+ try {
184
+ return validateDotenvVariableName(name);
185
+ }
186
+ catch (error) {
187
+ if (error instanceof SecretDotenvError) {
188
+ throw new SecretVaultError("invalid_variable", "Environment variable names must use portable dotenv syntax.");
189
+ }
190
+ throw error;
191
+ }
192
+ }
193
+ export function validateSecretValue(value) {
194
+ try {
195
+ return validateDotenvValue(value);
196
+ }
197
+ catch (error) {
198
+ if (error instanceof SecretDotenvError) {
199
+ throw new SecretVaultError(error.message.includes("64 KiB") ? "value_too_large" : "invalid_variable", error.message.includes("64 KiB")
200
+ ? "A secret value exceeds the 64 KiB limit."
201
+ : "Secret values cannot contain null bytes.");
202
+ }
203
+ throw error;
204
+ }
205
+ }
206
+ export function validateDotenvProfileDocument(document) {
207
+ try {
208
+ return parseDotenvDocument(document);
209
+ }
210
+ catch (error) {
211
+ if (error instanceof SecretDotenvError)
212
+ throw new SecretVaultError("invalid_dotenv", error.message);
213
+ throw error;
214
+ }
215
+ }
216
+ function validateTimestamp(value) {
217
+ if (typeof value !== "string" || value.length > 64 || Number.isNaN(Date.parse(value))) {
218
+ throw new SecretVaultError("vault_corrupt", "Secret vault timestamps are invalid.");
219
+ }
220
+ return value;
221
+ }
222
+ function parsePayload(value) {
223
+ if (!isRecord(value) || value.marker !== VAULT_MARKER || !Array.isArray(value.profiles)) {
224
+ throw new SecretVaultError("vault_corrupt", "Secret vault payload is invalid.");
225
+ }
226
+ if (value.profiles.length > MAX_PROFILES) {
227
+ throw new SecretVaultError("vault_corrupt", "Secret vault profile count exceeds its bound.");
228
+ }
229
+ const profileNames = new Set();
230
+ const profiles = value.profiles.map((candidate) => {
231
+ if (!isRecord(candidate) || typeof candidate.dotenv !== "string" || !Array.isArray(candidate.bindings)) {
232
+ throw new SecretVaultError("vault_corrupt", "Secret vault profile data is invalid.");
233
+ }
234
+ const profile = validateProfileId(typeof candidate.profile === "string" ? candidate.profile : "");
235
+ if (profileNames.has(profile))
236
+ throw new SecretVaultError("vault_corrupt", "Secret vault profiles are duplicated.");
237
+ profileNames.add(profile);
238
+ let dotenv;
239
+ try {
240
+ dotenv = validateDotenvProfileDocument(candidate.dotenv).document;
241
+ }
242
+ catch {
243
+ throw new SecretVaultError("vault_corrupt", "Secret vault dotenv data is invalid.");
244
+ }
245
+ if (candidate.bindings.length > MAX_BINDINGS_PER_PROFILE) {
246
+ throw new SecretVaultError("vault_corrupt", "Secret vault binding count exceeds its bound.");
247
+ }
248
+ const bindingIds = new Set();
249
+ const bindings = candidate.bindings.map((binding) => {
250
+ const parsed = parseBinding(binding);
251
+ const id = `${parsed.workspace}\0${parsed.envFile}`;
252
+ if (bindingIds.has(id))
253
+ throw new SecretVaultError("vault_corrupt", "Secret vault bindings are duplicated.");
254
+ bindingIds.add(id);
255
+ return parsed;
256
+ });
257
+ return {
258
+ profile,
259
+ ...(candidate.description !== undefined
260
+ ? {
261
+ description: validateDescription(typeof candidate.description === "string" ? candidate.description : ""),
262
+ }
263
+ : {}),
264
+ createdAt: validateTimestamp(candidate.createdAt),
265
+ updatedAt: validateTimestamp(candidate.updatedAt),
266
+ dotenv,
267
+ bindings: bindings.sort((left, right) => left.workspace.localeCompare(right.workspace) || left.envFile.localeCompare(right.envFile)),
268
+ };
269
+ });
270
+ return { marker: VAULT_MARKER, profiles: profiles.sort((left, right) => left.profile.localeCompare(right.profile)) };
271
+ }
272
+ export function scrubPayload(payload) {
273
+ for (const profile of payload.profiles)
274
+ profile.dotenv = "";
275
+ }
276
+ export function assertPassphrase(passphrase, creating) {
277
+ if (passphrase.length > MAX_PASSPHRASE_CHARS ||
278
+ passphrase.includes("\0") ||
279
+ (creating ? passphrase.length < MIN_NEW_PASSPHRASE_CHARS : passphrase.length === 0)) {
280
+ throw new SecretVaultError("invalid_passphrase", creating
281
+ ? `The vault passphrase must contain ${MIN_NEW_PASSPHRASE_CHARS}-${MAX_PASSPHRASE_CHARS} characters.`
282
+ : "The vault passphrase is invalid.");
283
+ }
284
+ }
285
+ export function sameKdf(left, right) {
286
+ return (left.algorithm === right.algorithm &&
287
+ left.salt === right.salt &&
288
+ left.N === right.N &&
289
+ left.r === right.r &&
290
+ left.p === right.p &&
291
+ left.keyLength === right.keyLength);
292
+ }
293
+ export async function deriveKey(passphrase, kdf) {
294
+ const salt = Buffer.from(kdf.salt, "base64");
295
+ const maxmem = Math.max(64 * 1024 * 1024, 128 * kdf.N * kdf.r + 16 * 1024 * 1024);
296
+ try {
297
+ return await new Promise((resolveKey, reject) => {
298
+ scrypt(passphrase, salt, kdf.keyLength, { N: kdf.N, r: kdf.r, p: kdf.p, maxmem }, (error, key) => {
299
+ if (error)
300
+ reject(error);
301
+ else
302
+ resolveKey(key);
303
+ });
304
+ });
305
+ }
306
+ finally {
307
+ salt.fill(0);
308
+ }
309
+ }
310
+ function encryptPayload(payload, key) {
311
+ let serialized = JSON.stringify(payload);
312
+ if (Buffer.byteLength(serialized, "utf8") > MAX_VAULT_PAYLOAD_BYTES) {
313
+ serialized = "";
314
+ throw new SecretVaultError("vault_too_large", "Secret vault payload exceeds its 2 MiB limit.");
315
+ }
316
+ const plaintext = Buffer.from(serialized, "utf8");
317
+ serialized = "";
318
+ const iv = randomBytes(IV_LENGTH);
319
+ try {
320
+ const cipher = createCipheriv(AES_ALGORITHM, key, iv);
321
+ cipher.setAAD(VAULT_AAD);
322
+ const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
323
+ const tag = cipher.getAuthTag();
324
+ try {
325
+ return {
326
+ iv: iv.toString("base64"),
327
+ tag: tag.toString("base64"),
328
+ ciphertext: ciphertext.toString("base64"),
329
+ };
330
+ }
331
+ finally {
332
+ tag.fill(0);
333
+ ciphertext.fill(0);
334
+ }
335
+ }
336
+ finally {
337
+ plaintext.fill(0);
338
+ iv.fill(0);
339
+ }
340
+ }
341
+ export function decryptPayload(ciphertext, key) {
342
+ const iv = Buffer.from(ciphertext.iv, "base64");
343
+ const tag = Buffer.from(ciphertext.tag, "base64");
344
+ const encrypted = Buffer.from(ciphertext.ciphertext, "base64");
345
+ let plaintext;
346
+ try {
347
+ const decipher = createDecipheriv(AES_ALGORITHM, key, iv);
348
+ decipher.setAAD(VAULT_AAD);
349
+ decipher.setAuthTag(tag);
350
+ plaintext = Buffer.concat([decipher.update(encrypted), decipher.final()]);
351
+ if (plaintext.byteLength > MAX_VAULT_PAYLOAD_BYTES) {
352
+ throw new SecretVaultError("vault_too_large", "Secret vault payload exceeds its 2 MiB limit.");
353
+ }
354
+ let parsed;
355
+ try {
356
+ parsed = JSON.parse(plaintext.toString("utf8"));
357
+ }
358
+ catch {
359
+ throw new SecretVaultError("vault_corrupt", "Secret vault payload is invalid.");
360
+ }
361
+ return parsePayload(parsed);
362
+ }
363
+ catch (error) {
364
+ if (error instanceof SecretVaultError)
365
+ throw error;
366
+ throw new SecretVaultError("unlock_failed", "The vault passphrase is incorrect or the vault is damaged.");
367
+ }
368
+ finally {
369
+ iv.fill(0);
370
+ tag.fill(0);
371
+ encrypted.fill(0);
372
+ plaintext?.fill(0);
373
+ }
374
+ }
375
+ export function serializeEnvelope(kdf, payload, key) {
376
+ const envelope = { version: VAULT_VERSION, kdf, payload: encryptPayload(payload, key) };
377
+ const serialized = `${JSON.stringify(envelope, null, 2)}\n`;
378
+ if (Buffer.byteLength(serialized, "utf8") > MAX_VAULT_FILE_BYTES) {
379
+ throw new SecretVaultError("vault_too_large", "Secret vault file exceeds its 4 MiB limit.");
380
+ }
381
+ return serialized;
382
+ }
383
+ export function profileSummary(profile) {
384
+ const parsed = validateDotenvProfileDocument(profile.dotenv);
385
+ return {
386
+ profile: profile.profile,
387
+ ...(profile.description ? { description: profile.description } : {}),
388
+ variableNames: parsed.variables.map((variable) => variable.name),
389
+ bindings: profile.bindings.map((binding) => ({ ...binding })),
390
+ createdAt: profile.createdAt,
391
+ updatedAt: profile.updatedAt,
392
+ };
393
+ }
394
+ export function serializeVariableValues(values) {
395
+ return formatDotenvVariables(values);
396
+ }
397
+ //# sourceMappingURL=secret-vault-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-vault-format.js","sourceRoot":"","sources":["../../../src/core/secrets/secret-vault-format.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCipheriv, createDecipheriv, randomBytes, scrypt } from \"node:crypto\";\nimport { isAbsolute, normalize, sep } from \"node:path\";\nimport {\n\tformatDotenvVariables,\n\tMAX_DOTENV_VARIABLES,\n\tparseDotenvDocument,\n\tSecretDotenvError,\n\tvalidateDotenvValue,\n\tvalidateDotenvVariableName,\n} from \"./secret-dotenv.ts\";\n\nconst VAULT_VERSION = 1;\nexport const VAULT_MARKER = \"pi-secret-vault-v1\";\nconst VAULT_AAD = Buffer.from(\"pi-secret-vault:v1\", \"utf8\");\nconst AES_ALGORITHM = \"aes-256-gcm\";\nconst KEY_LENGTH = 32;\nconst IV_LENGTH = 12;\nconst AUTH_TAG_LENGTH = 16;\nconst SALT_LENGTH = 16;\nexport const DEFAULT_SCRYPT_N = 32_768;\nconst SCRYPT_R = 8;\nconst SCRYPT_P = 1;\nconst MIN_SCRYPT_N = 1_024;\nconst MAX_SCRYPT_N = 65_536;\nexport const MAX_VAULT_FILE_BYTES = 4 * 1024 * 1024;\nconst MAX_VAULT_PAYLOAD_BYTES = 2 * 1024 * 1024;\nexport const MAX_PROFILES = 64;\nexport const MAX_VARIABLES_PER_PROFILE = MAX_DOTENV_VARIABLES;\nexport const MAX_BINDINGS_PER_PROFILE = 16;\nconst MAX_PASSPHRASE_CHARS = 4_096;\nconst MIN_NEW_PASSPHRASE_CHARS = 12;\nexport const SECRET_PROFILE_ID_MAX_CHARS = 64;\nexport const SECRET_DESCRIPTION_MAX_CHARS = 240;\nexport const SECRET_PROFILE_ID_PATTERN = `^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,${SECRET_PROFILE_ID_MAX_CHARS - 2}}[A-Za-z0-9])?$`;\nexport { SECRET_VARIABLE_NAME_MAX_CHARS, SECRET_VARIABLE_NAME_PATTERN } from \"./secret-dotenv.ts\";\nexport const SECRET_PRINTABLE_METADATA_PATTERN = \"^[^\\\\u0000-\\\\u001f\\\\u007f-\\\\u009f]+$\";\nexport const MANAGED_ENV_HEADER_PREFIX = \"# pi-secret-store:v1 profile=\";\nconst PROFILE_ID_RE = new RegExp(SECRET_PROFILE_ID_PATTERN);\nconst PRINTABLE_METADATA_RE = new RegExp(SECRET_PRINTABLE_METADATA_PATTERN);\nconst WINDOWS_RESERVED_NAME_RE = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\.|$)/i;\n\nexport type SecretVaultErrorCode =\n\t| \"already_initialized\"\n\t| \"ambiguous_binding\"\n\t| \"binding_missing\"\n\t| \"destination_conflict\"\n\t| \"destination_invalid\"\n\t| \"invalid_description\"\n\t| \"invalid_dotenv\"\n\t| \"invalid_passphrase\"\n\t| \"invalid_profile\"\n\t| \"invalid_variable\"\n\t| \"not_initialized\"\n\t| \"not_unlocked\"\n\t| \"profile_limit\"\n\t| \"profile_missing\"\n\t| \"symlink_refused\"\n\t| \"unlock_failed\"\n\t| \"value_too_large\"\n\t| \"variable_limit\"\n\t| \"vault_corrupt\"\n\t| \"vault_too_large\";\n\nexport class SecretVaultError extends Error {\n\treadonly code: SecretVaultErrorCode;\n\n\tconstructor(code: SecretVaultErrorCode, message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"SecretVaultError\";\n\t\tthis.code = code;\n\t}\n}\n\nexport interface SecretVariableValue {\n\tname: string;\n\tvalue: string;\n}\n\nexport interface SecretProfileSummary {\n\tprofile: string;\n\tdescription?: string;\n\tvariableNames: string[];\n\tbindings: SecretBindingSummary[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface SecretBindingSummary {\n\tworkspace: string;\n\tenvFile: string;\n\tupdatedAt: string;\n}\n\nexport interface SecretBindingResolution extends SecretBindingSummary {\n\tprofile: string;\n\tdestination: string;\n\tvariableNames: string[];\n}\n\nexport type SecretEnvDestinationState = \"missing\" | \"managed-profile\" | \"managed-other\" | \"unmanaged\";\n\nexport interface SecretMaterializationResult {\n\tprofile: string;\n\tvariableNames: string[];\n\tpreviousState: SecretEnvDestinationState;\n}\n\nexport interface SecretRemovalResult {\n\tprofile: string;\n\tremovedProfile: boolean;\n\tremovedVariableNames: string[];\n\tmanagedMaterializationRemoved: boolean;\n\tboundMaterializationsRemoved: number;\n}\n\nexport interface SecretVaultOptions {\n\tagentDir: string;\n\t/** Test-only cost override. Production callers should retain the default. */\n\tscryptN?: number;\n\tnow?: () => Date;\n\t/** Reset credential-bearing child process state after activation, mutation, or lock. */\n\tonEnvironmentChanged?: () => void;\n}\n\nexport interface VaultKdf {\n\talgorithm: \"scrypt\";\n\tsalt: string;\n\tN: number;\n\tr: number;\n\tp: number;\n\tkeyLength: number;\n}\n\nexport interface VaultCiphertext {\n\tiv: string;\n\ttag: string;\n\tciphertext: string;\n}\n\nexport interface VaultEnvelope {\n\tversion: 1;\n\tkdf: VaultKdf;\n\tpayload: VaultCiphertext;\n}\n\nexport interface SecretProfileRecord {\n\tprofile: string;\n\tdescription?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tdotenv: string;\n\tbindings: SecretBindingSummary[];\n}\n\nexport interface VaultPayload {\n\tmarker: typeof VAULT_MARKER;\n\tprofiles: SecretProfileRecord[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction decodeCanonicalBase64(value: unknown, field: string, expectedBytes?: number): Buffer {\n\tif (typeof value !== \"string\" || value.length === 0 || value.length > MAX_VAULT_FILE_BYTES) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", `Secret vault ${field} is invalid.`);\n\t}\n\tconst decoded = Buffer.from(value, \"base64\");\n\tif (decoded.toString(\"base64\") !== value || (expectedBytes !== undefined && decoded.byteLength !== expectedBytes)) {\n\t\tdecoded.fill(0);\n\t\tthrow new SecretVaultError(\"vault_corrupt\", `Secret vault ${field} is invalid.`);\n\t}\n\treturn decoded;\n}\n\nexport function validateScryptN(value: number): number {\n\tif (!Number.isInteger(value) || value < MIN_SCRYPT_N || value > MAX_SCRYPT_N || (value & (value - 1)) !== 0) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault KDF settings are invalid.\");\n\t}\n\treturn value;\n}\n\nexport function createVaultKdf(scryptN: number): VaultKdf {\n\tconst salt = randomBytes(SALT_LENGTH);\n\ttry {\n\t\treturn {\n\t\t\talgorithm: \"scrypt\",\n\t\t\tsalt: salt.toString(\"base64\"),\n\t\t\tN: validateScryptN(scryptN),\n\t\t\tr: SCRYPT_R,\n\t\t\tp: SCRYPT_P,\n\t\t\tkeyLength: KEY_LENGTH,\n\t\t};\n\t} finally {\n\t\tsalt.fill(0);\n\t}\n}\n\nfunction parseKdf(value: unknown): VaultKdf {\n\tif (!isRecord(value)) throw new SecretVaultError(\"vault_corrupt\", \"Secret vault KDF is missing.\");\n\tif (value.algorithm !== \"scrypt\" || value.r !== SCRYPT_R || value.p !== SCRYPT_P || value.keyLength !== KEY_LENGTH) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault KDF settings are unsupported.\");\n\t}\n\tconst salt = decodeCanonicalBase64(value.salt, \"salt\", SALT_LENGTH);\n\tsalt.fill(0);\n\treturn {\n\t\talgorithm: \"scrypt\",\n\t\tsalt: value.salt as string,\n\t\tN: validateScryptN(value.N as number),\n\t\tr: SCRYPT_R,\n\t\tp: SCRYPT_P,\n\t\tkeyLength: KEY_LENGTH,\n\t};\n}\n\nfunction parseCiphertext(value: unknown): VaultCiphertext {\n\tif (!isRecord(value)) throw new SecretVaultError(\"vault_corrupt\", \"Secret vault payload is missing.\");\n\tconst iv = decodeCanonicalBase64(value.iv, \"IV\", IV_LENGTH);\n\tconst tag = decodeCanonicalBase64(value.tag, \"authentication tag\", AUTH_TAG_LENGTH);\n\tconst ciphertext = decodeCanonicalBase64(value.ciphertext, \"ciphertext\");\n\tiv.fill(0);\n\ttag.fill(0);\n\tciphertext.fill(0);\n\treturn {\n\t\tiv: value.iv as string,\n\t\ttag: value.tag as string,\n\t\tciphertext: value.ciphertext as string,\n\t};\n}\n\nexport function parseEnvelope(text: string): VaultEnvelope {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(text);\n\t} catch {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault data is not valid JSON.\");\n\t}\n\tif (!isRecord(parsed) || parsed.version !== VAULT_VERSION) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault version is unsupported.\");\n\t}\n\treturn { version: VAULT_VERSION, kdf: parseKdf(parsed.kdf), payload: parseCiphertext(parsed.payload) };\n}\n\nexport function validateProfileId(profile: string): string {\n\tif (!PROFILE_ID_RE.test(profile) || WINDOWS_RESERVED_NAME_RE.test(profile)) {\n\t\tthrow new SecretVaultError(\n\t\t\t\"invalid_profile\",\n\t\t\t\"Profile names must be portable 1-64 character identifiers using letters, numbers, dot, dash, or underscore.\",\n\t\t);\n\t}\n\treturn profile;\n}\n\nexport function validateDescription(description: string | undefined): string | undefined {\n\tif (description === undefined) return undefined;\n\tconst normalized = description.trim();\n\tif (!normalized || normalized.length > SECRET_DESCRIPTION_MAX_CHARS || !PRINTABLE_METADATA_RE.test(normalized)) {\n\t\tthrow new SecretVaultError(\"invalid_description\", \"Secret profile descriptions must be short printable text.\");\n\t}\n\treturn normalized;\n}\n\nexport function validateBindingWorkspace(workspace: string): string {\n\tif (\n\t\t!isAbsolute(workspace) ||\n\t\tworkspace.length > 4_096 ||\n\t\tworkspace.includes(\"\\0\") ||\n\t\t/[\\u0000-\\u001f\\u007f-\\u009f]/.test(workspace)\n\t) {\n\t\tthrow new SecretVaultError(\"destination_invalid\", \"Credential workspace must be an absolute local path.\");\n\t}\n\treturn normalize(workspace);\n}\n\nexport function validateBindingEnvFile(envFile: string): string {\n\tconst trimmed = envFile.trim();\n\tconst normalized = normalize(trimmed);\n\tconst segments = normalized.split(/[\\\\/]+/);\n\tconst fileName = segments.at(-1) ?? \"\";\n\tif (\n\t\t!trimmed ||\n\t\ttrimmed.length > 512 ||\n\t\tisAbsolute(trimmed) ||\n\t\tnormalized === \"..\" ||\n\t\tnormalized.startsWith(`..${sep}`) ||\n\t\tsegments.includes(\"..\") ||\n\t\ttrimmed.includes(\"\\0\") ||\n\t\t/[\\u0000-\\u001f\\u007f-\\u009f]/.test(trimmed) ||\n\t\t!(fileName === \".env\" || fileName.startsWith(\".env.\") || fileName.endsWith(\".env\"))\n\t) {\n\t\tthrow new SecretVaultError(\n\t\t\t\"destination_invalid\",\n\t\t\t\"Credential target must be a relative dotenv path inside the workspace (for example .env or config/dev.env).\",\n\t\t);\n\t}\n\treturn normalized;\n}\n\nfunction parseBinding(value: unknown): SecretBindingSummary {\n\tif (!isRecord(value) || typeof value.workspace !== \"string\" || typeof value.envFile !== \"string\") {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault binding data is invalid.\");\n\t}\n\ttry {\n\t\treturn {\n\t\t\tworkspace: validateBindingWorkspace(value.workspace),\n\t\t\tenvFile: validateBindingEnvFile(value.envFile),\n\t\t\tupdatedAt: validateTimestamp(value.updatedAt),\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof SecretVaultError) {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault binding data is invalid.\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function validateVariableName(name: string): string {\n\ttry {\n\t\treturn validateDotenvVariableName(name);\n\t} catch (error) {\n\t\tif (error instanceof SecretDotenvError) {\n\t\t\tthrow new SecretVaultError(\"invalid_variable\", \"Environment variable names must use portable dotenv syntax.\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function validateSecretValue(value: string): string {\n\ttry {\n\t\treturn validateDotenvValue(value);\n\t} catch (error) {\n\t\tif (error instanceof SecretDotenvError) {\n\t\t\tthrow new SecretVaultError(\n\t\t\t\terror.message.includes(\"64 KiB\") ? \"value_too_large\" : \"invalid_variable\",\n\t\t\t\terror.message.includes(\"64 KiB\")\n\t\t\t\t\t? \"A secret value exceeds the 64 KiB limit.\"\n\t\t\t\t\t: \"Secret values cannot contain null bytes.\",\n\t\t\t);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function validateDotenvProfileDocument(document: string): {\n\tdocument: string;\n\tvariables: SecretVariableValue[];\n} {\n\ttry {\n\t\treturn parseDotenvDocument(document);\n\t} catch (error) {\n\t\tif (error instanceof SecretDotenvError) throw new SecretVaultError(\"invalid_dotenv\", error.message);\n\t\tthrow error;\n\t}\n}\n\nfunction validateTimestamp(value: unknown): string {\n\tif (typeof value !== \"string\" || value.length > 64 || Number.isNaN(Date.parse(value))) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault timestamps are invalid.\");\n\t}\n\treturn value;\n}\n\nfunction parsePayload(value: unknown): VaultPayload {\n\tif (!isRecord(value) || value.marker !== VAULT_MARKER || !Array.isArray(value.profiles)) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault payload is invalid.\");\n\t}\n\tif (value.profiles.length > MAX_PROFILES) {\n\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault profile count exceeds its bound.\");\n\t}\n\tconst profileNames = new Set<string>();\n\tconst profiles: SecretProfileRecord[] = value.profiles.map((candidate) => {\n\t\tif (!isRecord(candidate) || typeof candidate.dotenv !== \"string\" || !Array.isArray(candidate.bindings)) {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault profile data is invalid.\");\n\t\t}\n\t\tconst profile = validateProfileId(typeof candidate.profile === \"string\" ? candidate.profile : \"\");\n\t\tif (profileNames.has(profile))\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault profiles are duplicated.\");\n\t\tprofileNames.add(profile);\n\t\tlet dotenv: string;\n\t\ttry {\n\t\t\tdotenv = validateDotenvProfileDocument(candidate.dotenv).document;\n\t\t} catch {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault dotenv data is invalid.\");\n\t\t}\n\t\tif (candidate.bindings.length > MAX_BINDINGS_PER_PROFILE) {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault binding count exceeds its bound.\");\n\t\t}\n\t\tconst bindingIds = new Set<string>();\n\t\tconst bindings = candidate.bindings.map((binding) => {\n\t\t\tconst parsed = parseBinding(binding);\n\t\t\tconst id = `${parsed.workspace}\\0${parsed.envFile}`;\n\t\t\tif (bindingIds.has(id)) throw new SecretVaultError(\"vault_corrupt\", \"Secret vault bindings are duplicated.\");\n\t\t\tbindingIds.add(id);\n\t\t\treturn parsed;\n\t\t});\n\t\treturn {\n\t\t\tprofile,\n\t\t\t...(candidate.description !== undefined\n\t\t\t\t? {\n\t\t\t\t\t\tdescription: validateDescription(\n\t\t\t\t\t\t\ttypeof candidate.description === \"string\" ? candidate.description : \"\",\n\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\tcreatedAt: validateTimestamp(candidate.createdAt),\n\t\t\tupdatedAt: validateTimestamp(candidate.updatedAt),\n\t\t\tdotenv,\n\t\t\tbindings: bindings.sort(\n\t\t\t\t(left, right) => left.workspace.localeCompare(right.workspace) || left.envFile.localeCompare(right.envFile),\n\t\t\t),\n\t\t};\n\t});\n\treturn { marker: VAULT_MARKER, profiles: profiles.sort((left, right) => left.profile.localeCompare(right.profile)) };\n}\n\nexport function scrubPayload(payload: VaultPayload): void {\n\tfor (const profile of payload.profiles) profile.dotenv = \"\";\n}\n\nexport function assertPassphrase(passphrase: string, creating: boolean): void {\n\tif (\n\t\tpassphrase.length > MAX_PASSPHRASE_CHARS ||\n\t\tpassphrase.includes(\"\\0\") ||\n\t\t(creating ? passphrase.length < MIN_NEW_PASSPHRASE_CHARS : passphrase.length === 0)\n\t) {\n\t\tthrow new SecretVaultError(\n\t\t\t\"invalid_passphrase\",\n\t\t\tcreating\n\t\t\t\t? `The vault passphrase must contain ${MIN_NEW_PASSPHRASE_CHARS}-${MAX_PASSPHRASE_CHARS} characters.`\n\t\t\t\t: \"The vault passphrase is invalid.\",\n\t\t);\n\t}\n}\n\nexport function sameKdf(left: VaultKdf, right: VaultKdf): boolean {\n\treturn (\n\t\tleft.algorithm === right.algorithm &&\n\t\tleft.salt === right.salt &&\n\t\tleft.N === right.N &&\n\t\tleft.r === right.r &&\n\t\tleft.p === right.p &&\n\t\tleft.keyLength === right.keyLength\n\t);\n}\n\nexport async function deriveKey(passphrase: string, kdf: VaultKdf): Promise<Buffer> {\n\tconst salt = Buffer.from(kdf.salt, \"base64\");\n\tconst maxmem = Math.max(64 * 1024 * 1024, 128 * kdf.N * kdf.r + 16 * 1024 * 1024);\n\ttry {\n\t\treturn await new Promise<Buffer>((resolveKey, reject) => {\n\t\t\tscrypt(passphrase, salt, kdf.keyLength, { N: kdf.N, r: kdf.r, p: kdf.p, maxmem }, (error, key) => {\n\t\t\t\tif (error) reject(error);\n\t\t\t\telse resolveKey(key);\n\t\t\t});\n\t\t});\n\t} finally {\n\t\tsalt.fill(0);\n\t}\n}\n\nfunction encryptPayload(payload: VaultPayload, key: Buffer): VaultCiphertext {\n\tlet serialized = JSON.stringify(payload);\n\tif (Buffer.byteLength(serialized, \"utf8\") > MAX_VAULT_PAYLOAD_BYTES) {\n\t\tserialized = \"\";\n\t\tthrow new SecretVaultError(\"vault_too_large\", \"Secret vault payload exceeds its 2 MiB limit.\");\n\t}\n\tconst plaintext = Buffer.from(serialized, \"utf8\");\n\tserialized = \"\";\n\tconst iv = randomBytes(IV_LENGTH);\n\ttry {\n\t\tconst cipher = createCipheriv(AES_ALGORITHM, key, iv);\n\t\tcipher.setAAD(VAULT_AAD);\n\t\tconst ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);\n\t\tconst tag = cipher.getAuthTag();\n\t\ttry {\n\t\t\treturn {\n\t\t\t\tiv: iv.toString(\"base64\"),\n\t\t\t\ttag: tag.toString(\"base64\"),\n\t\t\t\tciphertext: ciphertext.toString(\"base64\"),\n\t\t\t};\n\t\t} finally {\n\t\t\ttag.fill(0);\n\t\t\tciphertext.fill(0);\n\t\t}\n\t} finally {\n\t\tplaintext.fill(0);\n\t\tiv.fill(0);\n\t}\n}\n\nexport function decryptPayload(ciphertext: VaultCiphertext, key: Buffer): VaultPayload {\n\tconst iv = Buffer.from(ciphertext.iv, \"base64\");\n\tconst tag = Buffer.from(ciphertext.tag, \"base64\");\n\tconst encrypted = Buffer.from(ciphertext.ciphertext, \"base64\");\n\tlet plaintext: Buffer | undefined;\n\ttry {\n\t\tconst decipher = createDecipheriv(AES_ALGORITHM, key, iv);\n\t\tdecipher.setAAD(VAULT_AAD);\n\t\tdecipher.setAuthTag(tag);\n\t\tplaintext = Buffer.concat([decipher.update(encrypted), decipher.final()]);\n\t\tif (plaintext.byteLength > MAX_VAULT_PAYLOAD_BYTES) {\n\t\t\tthrow new SecretVaultError(\"vault_too_large\", \"Secret vault payload exceeds its 2 MiB limit.\");\n\t\t}\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(plaintext.toString(\"utf8\"));\n\t\t} catch {\n\t\t\tthrow new SecretVaultError(\"vault_corrupt\", \"Secret vault payload is invalid.\");\n\t\t}\n\t\treturn parsePayload(parsed);\n\t} catch (error) {\n\t\tif (error instanceof SecretVaultError) throw error;\n\t\tthrow new SecretVaultError(\"unlock_failed\", \"The vault passphrase is incorrect or the vault is damaged.\");\n\t} finally {\n\t\tiv.fill(0);\n\t\ttag.fill(0);\n\t\tencrypted.fill(0);\n\t\tplaintext?.fill(0);\n\t}\n}\n\nexport function serializeEnvelope(kdf: VaultKdf, payload: VaultPayload, key: Buffer): string {\n\tconst envelope: VaultEnvelope = { version: VAULT_VERSION, kdf, payload: encryptPayload(payload, key) };\n\tconst serialized = `${JSON.stringify(envelope, null, 2)}\\n`;\n\tif (Buffer.byteLength(serialized, \"utf8\") > MAX_VAULT_FILE_BYTES) {\n\t\tthrow new SecretVaultError(\"vault_too_large\", \"Secret vault file exceeds its 4 MiB limit.\");\n\t}\n\treturn serialized;\n}\n\nexport function profileSummary(profile: SecretProfileRecord): SecretProfileSummary {\n\tconst parsed = validateDotenvProfileDocument(profile.dotenv);\n\treturn {\n\t\tprofile: profile.profile,\n\t\t...(profile.description ? { description: profile.description } : {}),\n\t\tvariableNames: parsed.variables.map((variable) => variable.name),\n\t\tbindings: profile.bindings.map((binding) => ({ ...binding })),\n\t\tcreatedAt: profile.createdAt,\n\t\tupdatedAt: profile.updatedAt,\n\t};\n}\n\nexport function serializeVariableValues(values: readonly SecretVariableValue[]): string {\n\treturn formatDotenvVariables(values);\n}\n"]}