@caupulican/pi-adaptative 0.85.8 → 0.86.2

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 (239) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/core/agent-paths.d.ts +6 -3
  3. package/dist/core/agent-paths.d.ts.map +1 -1
  4. package/dist/core/agent-paths.js +10 -3
  5. package/dist/core/agent-paths.js.map +1 -1
  6. package/dist/core/agent-session.d.ts +5 -2
  7. package/dist/core/agent-session.d.ts.map +1 -1
  8. package/dist/core/agent-session.js +7 -1
  9. package/dist/core/agent-session.js.map +1 -1
  10. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  11. package/dist/core/autonomy/bounded-completion.js +19 -8
  12. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  13. package/dist/core/autonomy/lane-tool-surface.d.ts +11 -5
  14. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  15. package/dist/core/autonomy/lane-tool-surface.js +34 -8
  16. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  17. package/dist/core/autonomy/subagent-prompt.d.ts +3 -3
  18. package/dist/core/autonomy/subagent-prompt.js +9 -9
  19. package/dist/core/autonomy/subagent-prompt.js.map +1 -1
  20. package/dist/core/background-lane-controller.d.ts +10 -8
  21. package/dist/core/background-lane-controller.d.ts.map +1 -1
  22. package/dist/core/background-lane-controller.js +23 -13
  23. package/dist/core/background-lane-controller.js.map +1 -1
  24. package/dist/core/bash-execution-controller.d.ts +4 -0
  25. package/dist/core/bash-execution-controller.d.ts.map +1 -1
  26. package/dist/core/bash-execution-controller.js +11 -4
  27. package/dist/core/bash-execution-controller.js.map +1 -1
  28. package/dist/core/bash-executor.d.ts +2 -0
  29. package/dist/core/bash-executor.d.ts.map +1 -1
  30. package/dist/core/bash-executor.js +2 -1
  31. package/dist/core/bash-executor.js.map +1 -1
  32. package/dist/core/capability-contract.d.ts +1 -1
  33. package/dist/core/capability-contract.d.ts.map +1 -1
  34. package/dist/core/capability-contract.js +0 -1
  35. package/dist/core/capability-contract.js.map +1 -1
  36. package/dist/core/default-tool-surface.d.ts +1 -0
  37. package/dist/core/default-tool-surface.d.ts.map +1 -1
  38. package/dist/core/default-tool-surface.js +3 -2
  39. package/dist/core/default-tool-surface.js.map +1 -1
  40. package/dist/core/delegation/worker-agent-control-coordinator.d.ts +27 -8
  41. package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
  42. package/dist/core/delegation/worker-agent-control-coordinator.js +191 -33
  43. package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
  44. package/dist/core/delegation/worker-agent-control.d.ts +45 -6
  45. package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
  46. package/dist/core/delegation/worker-agent-control.js +110 -13
  47. package/dist/core/delegation/worker-agent-control.js.map +1 -1
  48. package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
  49. package/dist/core/delegation/worker-attempt-executor.js +177 -158
  50. package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
  51. package/dist/core/delegation/worker-authority-resolver.d.ts +23 -0
  52. package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -0
  53. package/dist/core/delegation/worker-authority-resolver.js +128 -0
  54. package/dist/core/delegation/worker-authority-resolver.js.map +1 -0
  55. package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -1
  56. package/dist/core/delegation/worker-conversation-store.js +1 -1
  57. package/dist/core/delegation/worker-conversation-store.js.map +1 -1
  58. package/dist/core/delegation/worker-delegation-controller.d.ts +7 -1
  59. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  60. package/dist/core/delegation/worker-delegation-controller.js +260 -87
  61. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  62. package/dist/core/delegation/worker-delegation-request.d.ts +25 -4
  63. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
  64. package/dist/core/delegation/worker-delegation-request.js +90 -1
  65. package/dist/core/delegation/worker-delegation-request.js.map +1 -1
  66. package/dist/core/delegation/worker-execution-policy.d.ts +2 -0
  67. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
  68. package/dist/core/delegation/worker-execution-policy.js +22 -12
  69. package/dist/core/delegation/worker-execution-policy.js.map +1 -1
  70. package/dist/core/delegation/worker-lifecycle.d.ts +1 -0
  71. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
  72. package/dist/core/delegation/worker-lifecycle.js +4 -2
  73. package/dist/core/delegation/worker-lifecycle.js.map +1 -1
  74. package/dist/core/delegation/worker-profile-resolver.d.ts +0 -2
  75. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
  76. package/dist/core/delegation/worker-profile-resolver.js +8 -35
  77. package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
  78. package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
  79. package/dist/core/delegation/worker-recovery-coordinator.js +1 -0
  80. package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
  81. package/dist/core/delegation/worker-runner.d.ts +6 -1
  82. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  83. package/dist/core/delegation/worker-runner.js +20 -6
  84. package/dist/core/delegation/worker-runner.js.map +1 -1
  85. package/dist/core/delegation/worker-tree-budget-coordinator.d.ts +47 -0
  86. package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -0
  87. package/dist/core/delegation/worker-tree-budget-coordinator.js +210 -0
  88. package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -0
  89. package/dist/core/memory/providers/file-store.d.ts +2 -0
  90. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  91. package/dist/core/memory/providers/file-store.js +22 -20
  92. package/dist/core/memory/providers/file-store.js.map +1 -1
  93. package/dist/core/models/runtime-process.d.ts.map +1 -1
  94. package/dist/core/models/runtime-process.js +5 -18
  95. package/dist/core/models/runtime-process.js.map +1 -1
  96. package/dist/core/orchestration/bounded-string-array.d.ts +11 -0
  97. package/dist/core/orchestration/bounded-string-array.d.ts.map +1 -0
  98. package/dist/core/orchestration/bounded-string-array.js +17 -0
  99. package/dist/core/orchestration/bounded-string-array.js.map +1 -0
  100. package/dist/core/orchestration/capability-gateway.d.ts +16 -0
  101. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
  102. package/dist/core/orchestration/capability-gateway.js +38 -0
  103. package/dist/core/orchestration/capability-gateway.js.map +1 -1
  104. package/dist/core/orchestration/contracts.d.ts +11 -3
  105. package/dist/core/orchestration/contracts.d.ts.map +1 -1
  106. package/dist/core/orchestration/contracts.js +0 -1
  107. package/dist/core/orchestration/contracts.js.map +1 -1
  108. package/dist/core/orchestration/delegation-ledger.d.ts +1 -0
  109. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
  110. package/dist/core/orchestration/delegation-ledger.js +3 -0
  111. package/dist/core/orchestration/delegation-ledger.js.map +1 -1
  112. package/dist/core/orchestration/event-store.d.ts +12 -10
  113. package/dist/core/orchestration/event-store.d.ts.map +1 -1
  114. package/dist/core/orchestration/event-store.js +94 -104
  115. package/dist/core/orchestration/event-store.js.map +1 -1
  116. package/dist/core/orchestration/lane-tool-manifests.d.ts +2 -2
  117. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
  118. package/dist/core/orchestration/lane-tool-manifests.js +4 -1
  119. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
  120. package/dist/core/orchestration/policy-compiler.d.ts.map +1 -1
  121. package/dist/core/orchestration/policy-compiler.js +8 -9
  122. package/dist/core/orchestration/policy-compiler.js.map +1 -1
  123. package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
  124. package/dist/core/orchestration/profile-registry.js +4 -10
  125. package/dist/core/orchestration/profile-registry.js.map +1 -1
  126. package/dist/core/orchestration/task-runtime.d.ts +1 -0
  127. package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
  128. package/dist/core/orchestration/task-runtime.js +58 -3
  129. package/dist/core/orchestration/task-runtime.js.map +1 -1
  130. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
  131. package/dist/core/orchestration/worker-execution-contract.js +10 -17
  132. package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
  133. package/dist/core/risk-classifier.js +3 -3
  134. package/dist/core/risk-classifier.js.map +1 -1
  135. package/dist/core/runtime-builder.d.ts +4 -1
  136. package/dist/core/runtime-builder.d.ts.map +1 -1
  137. package/dist/core/runtime-builder.js +34 -15
  138. package/dist/core/runtime-builder.js.map +1 -1
  139. package/dist/core/secrets/bitwarden-credential-storage.d.ts +51 -0
  140. package/dist/core/secrets/bitwarden-credential-storage.d.ts.map +1 -0
  141. package/dist/core/secrets/bitwarden-credential-storage.js +345 -0
  142. package/dist/core/secrets/bitwarden-credential-storage.js.map +1 -0
  143. package/dist/core/secrets/credential-exposure-guard.d.ts +8 -4
  144. package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -1
  145. package/dist/core/secrets/credential-exposure-guard.js +30 -31
  146. package/dist/core/secrets/credential-exposure-guard.js.map +1 -1
  147. package/dist/core/secrets/credential-manager.d.ts +109 -0
  148. package/dist/core/secrets/credential-manager.d.ts.map +1 -0
  149. package/dist/core/secrets/credential-manager.js +384 -0
  150. package/dist/core/secrets/credential-manager.js.map +1 -0
  151. package/dist/core/secrets/credential-project.d.ts +4 -0
  152. package/dist/core/secrets/credential-project.d.ts.map +1 -0
  153. package/dist/core/secrets/credential-project.js +145 -0
  154. package/dist/core/secrets/credential-project.js.map +1 -0
  155. package/dist/core/secrets/secret-dotenv.d.ts +1 -1
  156. package/dist/core/secrets/secret-dotenv.js +1 -1
  157. package/dist/core/secrets/secret-dotenv.js.map +1 -1
  158. package/dist/core/settings-manager.d.ts +4 -2
  159. package/dist/core/settings-manager.d.ts.map +1 -1
  160. package/dist/core/settings-manager.js +9 -5
  161. package/dist/core/settings-manager.js.map +1 -1
  162. package/dist/core/slash-commands.d.ts.map +1 -1
  163. package/dist/core/slash-commands.js +1 -0
  164. package/dist/core/slash-commands.js.map +1 -1
  165. package/dist/core/system-prompt.js +1 -1
  166. package/dist/core/system-prompt.js.map +1 -1
  167. package/dist/core/tool-capability-policy.js +2 -2
  168. package/dist/core/tool-capability-policy.js.map +1 -1
  169. package/dist/core/tools/delegate.d.ts +29 -1
  170. package/dist/core/tools/delegate.d.ts.map +1 -1
  171. package/dist/core/tools/delegate.js +179 -28
  172. package/dist/core/tools/delegate.js.map +1 -1
  173. package/dist/core/tools/git-filter.d.ts +1 -0
  174. package/dist/core/tools/git-filter.d.ts.map +1 -1
  175. package/dist/core/tools/git-filter.js +1 -1
  176. package/dist/core/tools/git-filter.js.map +1 -1
  177. package/dist/core/tools/profile-writer.js +3 -3
  178. package/dist/core/tools/profile-writer.js.map +1 -1
  179. package/dist/core/tools/python.d.ts +2 -0
  180. package/dist/core/tools/python.d.ts.map +1 -1
  181. package/dist/core/tools/python.js +17 -12
  182. package/dist/core/tools/python.js.map +1 -1
  183. package/dist/core/tools/run-process.d.ts +2 -0
  184. package/dist/core/tools/run-process.d.ts.map +1 -1
  185. package/dist/core/tools/run-process.js +7 -3
  186. package/dist/core/tools/run-process.js.map +1 -1
  187. package/dist/core/tools/secret-store.d.ts +8 -18
  188. package/dist/core/tools/secret-store.d.ts.map +1 -1
  189. package/dist/core/tools/secret-store.js +83 -348
  190. package/dist/core/tools/secret-store.js.map +1 -1
  191. package/dist/index.d.ts +3 -1
  192. package/dist/index.d.ts.map +1 -1
  193. package/dist/index.js +3 -1
  194. package/dist/index.js.map +1 -1
  195. package/dist/migrations.d.ts.map +1 -1
  196. package/dist/migrations.js +38 -1
  197. package/dist/migrations.js.map +1 -1
  198. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  199. package/dist/modes/interactive/components/settings-selector.js +35 -14
  200. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  201. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  202. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  203. package/dist/modes/interactive/interactive-mode.js +26 -3
  204. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  205. package/dist/modes/interactive/secret-menu-controller.d.ts +21 -0
  206. package/dist/modes/interactive/secret-menu-controller.d.ts.map +1 -0
  207. package/dist/modes/interactive/secret-menu-controller.js +276 -0
  208. package/dist/modes/interactive/secret-menu-controller.js.map +1 -0
  209. package/dist/utils/tools-manager.d.ts +2 -1
  210. package/dist/utils/tools-manager.d.ts.map +1 -1
  211. package/dist/utils/tools-manager.js +43 -48
  212. package/dist/utils/tools-manager.js.map +1 -1
  213. package/dist/utils/zip-extractor.d.ts +8 -0
  214. package/dist/utils/zip-extractor.d.ts.map +1 -0
  215. package/dist/utils/zip-extractor.js +275 -0
  216. package/dist/utils/zip-extractor.js.map +1 -0
  217. package/docs/harness-architecture.md +34 -22
  218. package/docs/index.md +1 -1
  219. package/docs/resources.md +1 -1
  220. package/docs/settings.md +39 -103
  221. package/docs/usage.md +7 -5
  222. package/docs/worker-profiles.md +9 -7
  223. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  224. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  225. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  226. package/examples/extensions/sandbox/package-lock.json +2 -2
  227. package/examples/extensions/sandbox/package.json +1 -1
  228. package/examples/extensions/with-deps/package-lock.json +2 -2
  229. package/examples/extensions/with-deps/package.json +1 -1
  230. package/npm-shrinkwrap.json +12 -12
  231. package/package.json +4 -4
  232. package/dist/core/secrets/secret-vault-format.d.ts +0 -112
  233. package/dist/core/secrets/secret-vault-format.d.ts.map +0 -1
  234. package/dist/core/secrets/secret-vault-format.js +0 -396
  235. package/dist/core/secrets/secret-vault-format.js.map +0 -1
  236. package/dist/core/secrets/secret-vault.d.ts +0 -72
  237. package/dist/core/secrets/secret-vault.d.ts.map +0 -1
  238. package/dist/core/secrets/secret-vault.js +0 -663
  239. package/dist/core/secrets/secret-vault.js.map +0 -1
@@ -0,0 +1,51 @@
1
+ import { type ManagedToolResolver } from "../../utils/tools-manager.ts";
2
+ import { type CredentialProfileRecord, type CredentialProfileStorage, CredentialStorageError, type StoredCredentialProfileSummary } from "./credential-manager.ts";
3
+ export type BitwardenCredentialStorageErrorCode = "provider_command_failed" | "provider_unavailable" | "malformed_provider_data" | "not_connected" | "profile_not_found";
4
+ export declare class BitwardenCredentialStorageError extends CredentialStorageError {
5
+ readonly code: BitwardenCredentialStorageErrorCode;
6
+ constructor(code: BitwardenCredentialStorageErrorCode, message: string);
7
+ }
8
+ export interface BitwardenCommandRequest {
9
+ executable: string;
10
+ args: string[];
11
+ input?: string;
12
+ sessionKey: string;
13
+ signal?: AbortSignal;
14
+ }
15
+ export interface BitwardenCommandResult {
16
+ exitCode: number;
17
+ stdout: string;
18
+ stderr: string;
19
+ aborted?: boolean;
20
+ timedOut?: boolean;
21
+ outputLimitExceeded?: boolean;
22
+ }
23
+ export type BitwardenCommandRunner = (request: BitwardenCommandRequest) => Promise<BitwardenCommandResult>;
24
+ export interface BitwardenCredentialStorageOptions {
25
+ resolveTool?: ManagedToolResolver;
26
+ runCommand?: BitwardenCommandRunner;
27
+ }
28
+ export declare function runBitwardenCommand(request: BitwardenCommandRequest): Promise<BitwardenCommandResult>;
29
+ export declare class BitwardenCredentialStorage implements CredentialProfileStorage {
30
+ private readonly resolveTool;
31
+ private readonly runCommand;
32
+ private readonly profiles;
33
+ private executable;
34
+ private sessionKey;
35
+ private loaded;
36
+ private lastSyncAt;
37
+ constructor(options?: BitwardenCredentialStorageOptions);
38
+ connect(sessionKey: string, signal?: AbortSignal): Promise<void>;
39
+ refresh(signal?: AbortSignal): Promise<void>;
40
+ listProfiles(signal?: AbortSignal): Promise<StoredCredentialProfileSummary[]>;
41
+ readProfile(profile: string, signal?: AbortSignal): Promise<CredentialProfileRecord>;
42
+ writeProfile(record: CredentialProfileRecord, signal?: AbortSignal): Promise<void>;
43
+ deleteProfile(profile: string, signal?: AbortSignal): Promise<void>;
44
+ lock(): void;
45
+ private assertConnected;
46
+ private ensureLoaded;
47
+ private reload;
48
+ private lockProfileCache;
49
+ private runChecked;
50
+ }
51
+ //# sourceMappingURL=bitwarden-credential-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitwarden-credential-storage.d.ts","sourceRoot":"","sources":["../../../src/core/secrets/bitwarden-credential-storage.ts"],"names":[],"mappings":"AAEA,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnG,OAAO,EACN,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,sBAAsB,EACtB,KAAK,8BAA8B,EAGnC,MAAM,yBAAyB,CAAC;AAYjC,MAAM,MAAM,mCAAmC,GAC5C,yBAAyB,GACzB,sBAAsB,GACtB,yBAAyB,GACzB,eAAe,GACf,mBAAmB,CAAC;AAEvB,qBAAa,+BAAgC,SAAQ,sBAAsB;IAC1E,SAAiB,IAAI,EAAE,mCAAmC,CAAC;IAE3D,YAAY,IAAI,EAAE,mCAAmC,EAAE,OAAO,EAAE,MAAM,EAGrE;CACD;AAED,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAE3G,MAAM,WAAW,iCAAiC;IACjD,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACpC;AAiCD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAkD3G;AA6GD,qBAAa,0BAA2B,YAAW,wBAAwB;IAC1E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6C;IACtE,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAK;IAEvB,YAAY,OAAO,GAAE,iCAAsC,EAG1D;IAEK,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBrE;IAEK,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjD;IAEK,YAAY,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC,CAKlF;IAEK,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAOzF;IAEK,YAAY,CAAC,MAAM,EAAE,uBAAuB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA4CvF;IAEK,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CASxE;IAED,IAAI,IAAI,IAAI,CAUX;IAED,OAAO,CAAC,eAAe;YAOT,YAAY;YAKZ,MAAM;IAsCpB,OAAO,CAAC,gBAAgB;YAQV,UAAU;CA0BxB"}
@@ -0,0 +1,345 @@
1
+ import { spawnProcess, waitForChildProcessWithTermination } from "../../utils/child-process.js";
2
+ import { ensureToolWithDiagnostics } from "../../utils/tools-manager.js";
3
+ import { CredentialStorageError, validateCredentialProfileName, validateCredentialProfileRecord, } from "./credential-manager.js";
4
+ const ITEM_NAME_PREFIX = "Pi credential profile · ";
5
+ const ENVELOPE_KIND = "pi.credential-profile";
6
+ const ENVELOPE_SCHEMA = 1;
7
+ const MAX_COMMAND_OUTPUT_BYTES = 4 * 1024 * 1024;
8
+ const MAX_PROFILE_ITEMS = 256;
9
+ const MAX_NOTE_BYTES = 1024 * 1024;
10
+ const COMMAND_TIMEOUT_MS = 30_000;
11
+ const SYNC_FRESHNESS_MS = 30_000;
12
+ const ITEM_ID_PATTERN = /^[A-Za-z0-9-]{1,128}$/;
13
+ export class BitwardenCredentialStorageError extends CredentialStorageError {
14
+ constructor(code, message) {
15
+ super(code, message);
16
+ this.name = "BitwardenCredentialStorageError";
17
+ }
18
+ }
19
+ function appendBounded(current, chunk, limit) {
20
+ const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
21
+ if (Buffer.byteLength(current, "utf8") + Buffer.byteLength(text, "utf8") <= limit) {
22
+ return { value: current + text, exceeded: false };
23
+ }
24
+ return { value: current, exceeded: true };
25
+ }
26
+ function combineAbortSignal(source, controller) {
27
+ if (!source)
28
+ return () => { };
29
+ const abort = () => controller.abort();
30
+ if (source.aborted)
31
+ abort();
32
+ else
33
+ source.addEventListener("abort", abort, { once: true });
34
+ return () => source.removeEventListener("abort", abort);
35
+ }
36
+ export async function runBitwardenCommand(request) {
37
+ const controller = new AbortController();
38
+ const detachAbort = combineAbortSignal(request.signal, controller);
39
+ let stdout = "";
40
+ let stderr = "";
41
+ let outputLimitExceeded = false;
42
+ let child;
43
+ try {
44
+ child = spawnProcess(request.executable, request.args, {
45
+ env: { ...process.env, BW_SESSION: request.sessionKey, NO_COLOR: "1" },
46
+ stdio: ["pipe", "pipe", "pipe"],
47
+ windowsHide: true,
48
+ });
49
+ child.stdout?.on("data", (chunk) => {
50
+ const appended = appendBounded(stdout, chunk, MAX_COMMAND_OUTPUT_BYTES);
51
+ stdout = appended.value;
52
+ if (appended.exceeded) {
53
+ outputLimitExceeded = true;
54
+ controller.abort();
55
+ }
56
+ });
57
+ child.stderr?.on("data", (chunk) => {
58
+ const appended = appendBounded(stderr, chunk, MAX_COMMAND_OUTPUT_BYTES);
59
+ stderr = appended.value;
60
+ if (appended.exceeded) {
61
+ outputLimitExceeded = true;
62
+ controller.abort();
63
+ }
64
+ });
65
+ child.stdin?.end(request.input);
66
+ const terminal = await waitForChildProcessWithTermination(child, {
67
+ signal: controller.signal,
68
+ timeoutMs: COMMAND_TIMEOUT_MS,
69
+ killGraceMs: 2_000,
70
+ });
71
+ return {
72
+ exitCode: terminal.code ?? 1,
73
+ stdout,
74
+ stderr,
75
+ ...(terminal.reason === "aborted" ? { aborted: true } : {}),
76
+ ...(terminal.reason === "timeout" ? { timedOut: true } : {}),
77
+ ...(outputLimitExceeded ? { outputLimitExceeded: true } : {}),
78
+ };
79
+ }
80
+ catch {
81
+ return { exitCode: 1, stdout: "", stderr: "" };
82
+ }
83
+ finally {
84
+ detachAbort();
85
+ stdout = "";
86
+ stderr = "";
87
+ }
88
+ }
89
+ function isObject(value) {
90
+ return typeof value === "object" && value !== null && !Array.isArray(value);
91
+ }
92
+ function parseJson(value) {
93
+ try {
94
+ return JSON.parse(value);
95
+ }
96
+ catch {
97
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden returned malformed profile data.");
98
+ }
99
+ }
100
+ function parseEnvelope(note, expectedProfile) {
101
+ if (Buffer.byteLength(note, "utf8") > MAX_NOTE_BYTES) {
102
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden returned an oversized profile record.");
103
+ }
104
+ const value = parseJson(note);
105
+ if (!isObject(value) ||
106
+ value.kind !== ENVELOPE_KIND ||
107
+ value.schema !== ENVELOPE_SCHEMA ||
108
+ value.profile !== expectedProfile ||
109
+ (value.description !== undefined && typeof value.description !== "string") ||
110
+ !Array.isArray(value.variables) ||
111
+ !Array.isArray(value.projectKeys) ||
112
+ !value.variables.every((variable) => isObject(variable) && typeof variable.name === "string" && typeof variable.value === "string") ||
113
+ !value.projectKeys.every((key) => typeof key === "string")) {
114
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden returned malformed profile data.");
115
+ }
116
+ const record = {
117
+ profile: expectedProfile,
118
+ ...(typeof value.description === "string" ? { description: value.description } : {}),
119
+ variables: value.variables.map((variable) => ({
120
+ name: variable.name,
121
+ value: variable.value,
122
+ })),
123
+ projectKeys: value.projectKeys,
124
+ };
125
+ try {
126
+ return validateCredentialProfileRecord(record);
127
+ }
128
+ catch {
129
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden returned malformed profile data.");
130
+ }
131
+ }
132
+ function parseProfileItem(value) {
133
+ if (!isObject(value) || typeof value.name !== "string" || !value.name.startsWith(ITEM_NAME_PREFIX))
134
+ return undefined;
135
+ const profile = value.name.slice(ITEM_NAME_PREFIX.length);
136
+ if (value.type !== 2 ||
137
+ typeof value.id !== "string" ||
138
+ !ITEM_ID_PATTERN.test(value.id) ||
139
+ typeof value.notes !== "string" ||
140
+ !isObject(value.secureNote) ||
141
+ value.secureNote.type !== 0) {
142
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden returned malformed profile data.");
143
+ }
144
+ try {
145
+ validateCredentialProfileName(profile);
146
+ }
147
+ catch {
148
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden returned malformed profile data.");
149
+ }
150
+ return { id: value.id, item: value, record: parseEnvelope(value.notes, profile) };
151
+ }
152
+ function profileSummary(record) {
153
+ return {
154
+ profile: record.profile,
155
+ ...(record.description ? { description: record.description } : {}),
156
+ variableNames: record.variables.map((variable) => variable.name),
157
+ projectKeys: [...record.projectKeys],
158
+ };
159
+ }
160
+ function createEnvelope(record) {
161
+ return {
162
+ kind: ENVELOPE_KIND,
163
+ schema: ENVELOPE_SCHEMA,
164
+ profile: record.profile,
165
+ ...(record.description ? { description: record.description } : {}),
166
+ variables: record.variables.map((variable) => ({ ...variable })),
167
+ projectKeys: [...record.projectKeys],
168
+ };
169
+ }
170
+ export class BitwardenCredentialStorage {
171
+ constructor(options = {}) {
172
+ this.profiles = new Map();
173
+ this.loaded = false;
174
+ this.lastSyncAt = 0;
175
+ this.resolveTool = options.resolveTool ?? ensureToolWithDiagnostics;
176
+ this.runCommand = options.runCommand ?? runBitwardenCommand;
177
+ }
178
+ async connect(sessionKey, signal) {
179
+ this.lock();
180
+ const resolution = await this.resolveTool("bw", true);
181
+ if (resolution.status === "unavailable") {
182
+ throw new BitwardenCredentialStorageError("provider_unavailable", `Bitwarden CLI could not be provisioned (${resolution.failureCode}).`);
183
+ }
184
+ this.executable = resolution.path;
185
+ this.sessionKey = sessionKey;
186
+ try {
187
+ await this.reload(signal, true);
188
+ }
189
+ catch (error) {
190
+ this.lock();
191
+ throw error;
192
+ }
193
+ }
194
+ async refresh(signal) {
195
+ this.assertConnected();
196
+ if (this.loaded && Date.now() - this.lastSyncAt < SYNC_FRESHNESS_MS)
197
+ return;
198
+ await this.reload(signal, true);
199
+ }
200
+ async listProfiles(signal) {
201
+ await this.ensureLoaded(signal);
202
+ return [...this.profiles.values()]
203
+ .map((profile) => profileSummary(profile.record))
204
+ .sort((left, right) => left.profile.localeCompare(right.profile));
205
+ }
206
+ async readProfile(profile, signal) {
207
+ await this.ensureLoaded(signal);
208
+ const cached = this.profiles.get(profile);
209
+ if (!cached) {
210
+ throw new BitwardenCredentialStorageError("profile_not_found", "Credential profile was not found.");
211
+ }
212
+ return structuredClone(cached.record);
213
+ }
214
+ async writeProfile(record, signal) {
215
+ validateCredentialProfileRecord(record);
216
+ await this.ensureLoaded(signal);
217
+ const existing = this.profiles.get(record.profile);
218
+ let item;
219
+ if (existing) {
220
+ item = structuredClone(existing.item);
221
+ }
222
+ else {
223
+ const template = parseJson(await this.runChecked(["get", "template", "item"], undefined, signal));
224
+ if (!isObject(template)) {
225
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden returned a malformed item template.");
226
+ }
227
+ item = template;
228
+ }
229
+ item.type = 2;
230
+ item.name = `${ITEM_NAME_PREFIX}${record.profile}`;
231
+ item.notes = JSON.stringify(createEnvelope(record));
232
+ item.secureNote = { type: 0 };
233
+ let serialized = "";
234
+ let encoded = "";
235
+ try {
236
+ serialized = JSON.stringify(item);
237
+ encoded = Buffer.from(serialized, "utf8").toString("base64");
238
+ const output = existing
239
+ ? await this.runChecked(["edit", "item", existing.id], encoded, signal)
240
+ : await this.runChecked(["create", "item"], encoded, signal);
241
+ const updated = parseProfileItem(parseJson(output));
242
+ if (!updated || updated.record.profile !== record.profile) {
243
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden returned malformed profile data.");
244
+ }
245
+ this.profiles.set(record.profile, updated);
246
+ this.lastSyncAt = Date.now();
247
+ }
248
+ finally {
249
+ serialized = "";
250
+ encoded = "";
251
+ item.notes = "";
252
+ }
253
+ }
254
+ async deleteProfile(profile, signal) {
255
+ await this.ensureLoaded(signal);
256
+ const cached = this.profiles.get(profile);
257
+ if (!cached) {
258
+ throw new BitwardenCredentialStorageError("profile_not_found", "Credential profile was not found.");
259
+ }
260
+ await this.runChecked(["delete", "item", cached.id], undefined, signal);
261
+ this.profiles.delete(profile);
262
+ this.lastSyncAt = Date.now();
263
+ }
264
+ lock() {
265
+ this.executable = undefined;
266
+ this.sessionKey = undefined;
267
+ for (const cached of this.profiles.values()) {
268
+ for (const variable of cached.record.variables)
269
+ variable.value = "";
270
+ cached.item.notes = "";
271
+ }
272
+ this.profiles.clear();
273
+ this.loaded = false;
274
+ this.lastSyncAt = 0;
275
+ }
276
+ assertConnected() {
277
+ if (!this.executable || !this.sessionKey) {
278
+ throw new BitwardenCredentialStorageError("not_connected", "Bitwarden is not connected.");
279
+ }
280
+ return { executable: this.executable, sessionKey: this.sessionKey };
281
+ }
282
+ async ensureLoaded(signal) {
283
+ this.assertConnected();
284
+ if (!this.loaded)
285
+ await this.reload(signal, false);
286
+ }
287
+ async reload(signal, attemptSync) {
288
+ if (attemptSync) {
289
+ try {
290
+ await this.runChecked(["sync"], undefined, signal);
291
+ }
292
+ catch (error) {
293
+ if (!(error instanceof BitwardenCredentialStorageError) || error.code !== "provider_command_failed") {
294
+ throw error;
295
+ }
296
+ // A network sync failure must not discard a locally available encrypted vault.
297
+ }
298
+ }
299
+ const rawItems = parseJson(await this.runChecked(["list", "items", "--search", ITEM_NAME_PREFIX], undefined, signal));
300
+ if (!Array.isArray(rawItems) || rawItems.length > MAX_PROFILE_ITEMS) {
301
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden returned an invalid number of profile items.");
302
+ }
303
+ const next = new Map();
304
+ for (const rawItem of rawItems) {
305
+ const parsed = parseProfileItem(rawItem);
306
+ if (!parsed)
307
+ continue;
308
+ if (next.has(parsed.record.profile)) {
309
+ throw new BitwardenCredentialStorageError("malformed_provider_data", "Bitwarden contains duplicate Pi credential profiles.");
310
+ }
311
+ next.set(parsed.record.profile, parsed);
312
+ }
313
+ this.lockProfileCache();
314
+ for (const [profile, cached] of next)
315
+ this.profiles.set(profile, cached);
316
+ this.loaded = true;
317
+ this.lastSyncAt = Date.now();
318
+ }
319
+ lockProfileCache() {
320
+ for (const cached of this.profiles.values()) {
321
+ for (const variable of cached.record.variables)
322
+ variable.value = "";
323
+ cached.item.notes = "";
324
+ }
325
+ this.profiles.clear();
326
+ }
327
+ async runChecked(args, input, signal) {
328
+ const { executable, sessionKey } = this.assertConnected();
329
+ const result = await this.runCommand({
330
+ executable,
331
+ args,
332
+ ...(input !== undefined ? { input } : {}),
333
+ sessionKey,
334
+ ...(signal ? { signal } : {}),
335
+ });
336
+ if (result.exitCode !== 0 ||
337
+ result.aborted === true ||
338
+ result.timedOut === true ||
339
+ result.outputLimitExceeded === true) {
340
+ throw new BitwardenCredentialStorageError("provider_command_failed", "Bitwarden command failed safely without exposing provider output.");
341
+ }
342
+ return result.stdout;
343
+ }
344
+ }
345
+ //# sourceMappingURL=bitwarden-credential-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitwarden-credential-storage.js","sourceRoot":"","sources":["../../../src/core/secrets/bitwarden-credential-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChildProcess } from \"node:child_process\";\nimport { spawnProcess, waitForChildProcessWithTermination } from \"../../utils/child-process.ts\";\nimport { ensureToolWithDiagnostics, type ManagedToolResolver } from \"../../utils/tools-manager.ts\";\nimport {\n\ttype CredentialProfileRecord,\n\ttype CredentialProfileStorage,\n\tCredentialStorageError,\n\ttype StoredCredentialProfileSummary,\n\tvalidateCredentialProfileName,\n\tvalidateCredentialProfileRecord,\n} from \"./credential-manager.ts\";\n\nconst ITEM_NAME_PREFIX = \"Pi credential profile · \";\nconst ENVELOPE_KIND = \"pi.credential-profile\";\nconst ENVELOPE_SCHEMA = 1;\nconst MAX_COMMAND_OUTPUT_BYTES = 4 * 1024 * 1024;\nconst MAX_PROFILE_ITEMS = 256;\nconst MAX_NOTE_BYTES = 1024 * 1024;\nconst COMMAND_TIMEOUT_MS = 30_000;\nconst SYNC_FRESHNESS_MS = 30_000;\nconst ITEM_ID_PATTERN = /^[A-Za-z0-9-]{1,128}$/;\n\nexport type BitwardenCredentialStorageErrorCode =\n\t| \"provider_command_failed\"\n\t| \"provider_unavailable\"\n\t| \"malformed_provider_data\"\n\t| \"not_connected\"\n\t| \"profile_not_found\";\n\nexport class BitwardenCredentialStorageError extends CredentialStorageError {\n\tdeclare readonly code: BitwardenCredentialStorageErrorCode;\n\n\tconstructor(code: BitwardenCredentialStorageErrorCode, message: string) {\n\t\tsuper(code, message);\n\t\tthis.name = \"BitwardenCredentialStorageError\";\n\t}\n}\n\nexport interface BitwardenCommandRequest {\n\texecutable: string;\n\targs: string[];\n\tinput?: string;\n\tsessionKey: string;\n\tsignal?: AbortSignal;\n}\n\nexport interface BitwardenCommandResult {\n\texitCode: number;\n\tstdout: string;\n\tstderr: string;\n\taborted?: boolean;\n\ttimedOut?: boolean;\n\toutputLimitExceeded?: boolean;\n}\n\nexport type BitwardenCommandRunner = (request: BitwardenCommandRequest) => Promise<BitwardenCommandResult>;\n\nexport interface BitwardenCredentialStorageOptions {\n\tresolveTool?: ManagedToolResolver;\n\trunCommand?: BitwardenCommandRunner;\n}\n\ninterface BitwardenProfileEnvelope {\n\tkind: typeof ENVELOPE_KIND;\n\tschema: typeof ENVELOPE_SCHEMA;\n\tprofile: string;\n\tdescription?: string;\n\tvariables: Array<{ name: string; value: string }>;\n\tprojectKeys: string[];\n}\n\ninterface CachedBitwardenProfile {\n\tid: string;\n\titem: Record<string, unknown>;\n\trecord: CredentialProfileRecord;\n}\n\nfunction appendBounded(current: string, chunk: Buffer | string, limit: number): { value: string; exceeded: boolean } {\n\tconst text = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\tif (Buffer.byteLength(current, \"utf8\") + Buffer.byteLength(text, \"utf8\") <= limit) {\n\t\treturn { value: current + text, exceeded: false };\n\t}\n\treturn { value: current, exceeded: true };\n}\n\nfunction combineAbortSignal(source: AbortSignal | undefined, controller: AbortController): () => void {\n\tif (!source) return () => {};\n\tconst abort = () => controller.abort();\n\tif (source.aborted) abort();\n\telse source.addEventListener(\"abort\", abort, { once: true });\n\treturn () => source.removeEventListener(\"abort\", abort);\n}\n\nexport async function runBitwardenCommand(request: BitwardenCommandRequest): Promise<BitwardenCommandResult> {\n\tconst controller = new AbortController();\n\tconst detachAbort = combineAbortSignal(request.signal, controller);\n\tlet stdout = \"\";\n\tlet stderr = \"\";\n\tlet outputLimitExceeded = false;\n\tlet child: ChildProcess;\n\ttry {\n\t\tchild = spawnProcess(request.executable, request.args, {\n\t\t\tenv: { ...process.env, BW_SESSION: request.sessionKey, NO_COLOR: \"1\" },\n\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t\twindowsHide: true,\n\t\t});\n\t\tchild.stdout?.on(\"data\", (chunk: Buffer | string) => {\n\t\t\tconst appended = appendBounded(stdout, chunk, MAX_COMMAND_OUTPUT_BYTES);\n\t\t\tstdout = appended.value;\n\t\t\tif (appended.exceeded) {\n\t\t\t\toutputLimitExceeded = true;\n\t\t\t\tcontroller.abort();\n\t\t\t}\n\t\t});\n\t\tchild.stderr?.on(\"data\", (chunk: Buffer | string) => {\n\t\t\tconst appended = appendBounded(stderr, chunk, MAX_COMMAND_OUTPUT_BYTES);\n\t\t\tstderr = appended.value;\n\t\t\tif (appended.exceeded) {\n\t\t\t\toutputLimitExceeded = true;\n\t\t\t\tcontroller.abort();\n\t\t\t}\n\t\t});\n\t\tchild.stdin?.end(request.input);\n\t\tconst terminal = await waitForChildProcessWithTermination(child, {\n\t\t\tsignal: controller.signal,\n\t\t\ttimeoutMs: COMMAND_TIMEOUT_MS,\n\t\t\tkillGraceMs: 2_000,\n\t\t});\n\t\treturn {\n\t\t\texitCode: terminal.code ?? 1,\n\t\t\tstdout,\n\t\t\tstderr,\n\t\t\t...(terminal.reason === \"aborted\" ? { aborted: true } : {}),\n\t\t\t...(terminal.reason === \"timeout\" ? { timedOut: true } : {}),\n\t\t\t...(outputLimitExceeded ? { outputLimitExceeded: true } : {}),\n\t\t};\n\t} catch {\n\t\treturn { exitCode: 1, stdout: \"\", stderr: \"\" };\n\t} finally {\n\t\tdetachAbort();\n\t\tstdout = \"\";\n\t\tstderr = \"\";\n\t}\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parseJson(value: string): unknown {\n\ttry {\n\t\treturn JSON.parse(value) as unknown;\n\t} catch {\n\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\"malformed_provider_data\",\n\t\t\t\"Bitwarden returned malformed profile data.\",\n\t\t);\n\t}\n}\n\nfunction parseEnvelope(note: string, expectedProfile: string): CredentialProfileRecord {\n\tif (Buffer.byteLength(note, \"utf8\") > MAX_NOTE_BYTES) {\n\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\"malformed_provider_data\",\n\t\t\t\"Bitwarden returned an oversized profile record.\",\n\t\t);\n\t}\n\tconst value = parseJson(note);\n\tif (\n\t\t!isObject(value) ||\n\t\tvalue.kind !== ENVELOPE_KIND ||\n\t\tvalue.schema !== ENVELOPE_SCHEMA ||\n\t\tvalue.profile !== expectedProfile ||\n\t\t(value.description !== undefined && typeof value.description !== \"string\") ||\n\t\t!Array.isArray(value.variables) ||\n\t\t!Array.isArray(value.projectKeys) ||\n\t\t!value.variables.every(\n\t\t\t(variable) => isObject(variable) && typeof variable.name === \"string\" && typeof variable.value === \"string\",\n\t\t) ||\n\t\t!value.projectKeys.every((key) => typeof key === \"string\")\n\t) {\n\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\"malformed_provider_data\",\n\t\t\t\"Bitwarden returned malformed profile data.\",\n\t\t);\n\t}\n\tconst record: CredentialProfileRecord = {\n\t\tprofile: expectedProfile,\n\t\t...(typeof value.description === \"string\" ? { description: value.description } : {}),\n\t\tvariables: value.variables.map((variable) => ({\n\t\t\tname: (variable as Record<string, unknown>).name as string,\n\t\t\tvalue: (variable as Record<string, unknown>).value as string,\n\t\t})),\n\t\tprojectKeys: value.projectKeys as string[],\n\t};\n\ttry {\n\t\treturn validateCredentialProfileRecord(record);\n\t} catch {\n\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\"malformed_provider_data\",\n\t\t\t\"Bitwarden returned malformed profile data.\",\n\t\t);\n\t}\n}\n\nfunction parseProfileItem(value: unknown): CachedBitwardenProfile | undefined {\n\tif (!isObject(value) || typeof value.name !== \"string\" || !value.name.startsWith(ITEM_NAME_PREFIX)) return undefined;\n\tconst profile = value.name.slice(ITEM_NAME_PREFIX.length);\n\tif (\n\t\tvalue.type !== 2 ||\n\t\ttypeof value.id !== \"string\" ||\n\t\t!ITEM_ID_PATTERN.test(value.id) ||\n\t\ttypeof value.notes !== \"string\" ||\n\t\t!isObject(value.secureNote) ||\n\t\tvalue.secureNote.type !== 0\n\t) {\n\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\"malformed_provider_data\",\n\t\t\t\"Bitwarden returned malformed profile data.\",\n\t\t);\n\t}\n\ttry {\n\t\tvalidateCredentialProfileName(profile);\n\t} catch {\n\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\"malformed_provider_data\",\n\t\t\t\"Bitwarden returned malformed profile data.\",\n\t\t);\n\t}\n\treturn { id: value.id, item: value, record: parseEnvelope(value.notes, profile) };\n}\n\nfunction profileSummary(record: CredentialProfileRecord): StoredCredentialProfileSummary {\n\treturn {\n\t\tprofile: record.profile,\n\t\t...(record.description ? { description: record.description } : {}),\n\t\tvariableNames: record.variables.map((variable) => variable.name),\n\t\tprojectKeys: [...record.projectKeys],\n\t};\n}\n\nfunction createEnvelope(record: CredentialProfileRecord): BitwardenProfileEnvelope {\n\treturn {\n\t\tkind: ENVELOPE_KIND,\n\t\tschema: ENVELOPE_SCHEMA,\n\t\tprofile: record.profile,\n\t\t...(record.description ? { description: record.description } : {}),\n\t\tvariables: record.variables.map((variable) => ({ ...variable })),\n\t\tprojectKeys: [...record.projectKeys],\n\t};\n}\n\nexport class BitwardenCredentialStorage implements CredentialProfileStorage {\n\tprivate readonly resolveTool: ManagedToolResolver;\n\tprivate readonly runCommand: BitwardenCommandRunner;\n\tprivate readonly profiles = new Map<string, CachedBitwardenProfile>();\n\tprivate executable: string | undefined;\n\tprivate sessionKey: string | undefined;\n\tprivate loaded = false;\n\tprivate lastSyncAt = 0;\n\n\tconstructor(options: BitwardenCredentialStorageOptions = {}) {\n\t\tthis.resolveTool = options.resolveTool ?? ensureToolWithDiagnostics;\n\t\tthis.runCommand = options.runCommand ?? runBitwardenCommand;\n\t}\n\n\tasync connect(sessionKey: string, signal?: AbortSignal): Promise<void> {\n\t\tthis.lock();\n\t\tconst resolution = await this.resolveTool(\"bw\", true);\n\t\tif (resolution.status === \"unavailable\") {\n\t\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\t\"provider_unavailable\",\n\t\t\t\t`Bitwarden CLI could not be provisioned (${resolution.failureCode}).`,\n\t\t\t);\n\t\t}\n\t\tthis.executable = resolution.path;\n\t\tthis.sessionKey = sessionKey;\n\t\ttry {\n\t\t\tawait this.reload(signal, true);\n\t\t} catch (error) {\n\t\t\tthis.lock();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync refresh(signal?: AbortSignal): Promise<void> {\n\t\tthis.assertConnected();\n\t\tif (this.loaded && Date.now() - this.lastSyncAt < SYNC_FRESHNESS_MS) return;\n\t\tawait this.reload(signal, true);\n\t}\n\n\tasync listProfiles(signal?: AbortSignal): Promise<StoredCredentialProfileSummary[]> {\n\t\tawait this.ensureLoaded(signal);\n\t\treturn [...this.profiles.values()]\n\t\t\t.map((profile) => profileSummary(profile.record))\n\t\t\t.sort((left, right) => left.profile.localeCompare(right.profile));\n\t}\n\n\tasync readProfile(profile: string, signal?: AbortSignal): Promise<CredentialProfileRecord> {\n\t\tawait this.ensureLoaded(signal);\n\t\tconst cached = this.profiles.get(profile);\n\t\tif (!cached) {\n\t\t\tthrow new BitwardenCredentialStorageError(\"profile_not_found\", \"Credential profile was not found.\");\n\t\t}\n\t\treturn structuredClone(cached.record);\n\t}\n\n\tasync writeProfile(record: CredentialProfileRecord, signal?: AbortSignal): Promise<void> {\n\t\tvalidateCredentialProfileRecord(record);\n\t\tawait this.ensureLoaded(signal);\n\t\tconst existing = this.profiles.get(record.profile);\n\t\tlet item: Record<string, unknown>;\n\t\tif (existing) {\n\t\t\titem = structuredClone(existing.item);\n\t\t} else {\n\t\t\tconst template = parseJson(await this.runChecked([\"get\", \"template\", \"item\"], undefined, signal));\n\t\t\tif (!isObject(template)) {\n\t\t\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\t\t\"malformed_provider_data\",\n\t\t\t\t\t\"Bitwarden returned a malformed item template.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\titem = template;\n\t\t}\n\t\titem.type = 2;\n\t\titem.name = `${ITEM_NAME_PREFIX}${record.profile}`;\n\t\titem.notes = JSON.stringify(createEnvelope(record));\n\t\titem.secureNote = { type: 0 };\n\n\t\tlet serialized = \"\";\n\t\tlet encoded = \"\";\n\t\ttry {\n\t\t\tserialized = JSON.stringify(item);\n\t\t\tencoded = Buffer.from(serialized, \"utf8\").toString(\"base64\");\n\t\t\tconst output = existing\n\t\t\t\t? await this.runChecked([\"edit\", \"item\", existing.id], encoded, signal)\n\t\t\t\t: await this.runChecked([\"create\", \"item\"], encoded, signal);\n\t\t\tconst updated = parseProfileItem(parseJson(output));\n\t\t\tif (!updated || updated.record.profile !== record.profile) {\n\t\t\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\t\t\"malformed_provider_data\",\n\t\t\t\t\t\"Bitwarden returned malformed profile data.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.profiles.set(record.profile, updated);\n\t\t\tthis.lastSyncAt = Date.now();\n\t\t} finally {\n\t\t\tserialized = \"\";\n\t\t\tencoded = \"\";\n\t\t\titem.notes = \"\";\n\t\t}\n\t}\n\n\tasync deleteProfile(profile: string, signal?: AbortSignal): Promise<void> {\n\t\tawait this.ensureLoaded(signal);\n\t\tconst cached = this.profiles.get(profile);\n\t\tif (!cached) {\n\t\t\tthrow new BitwardenCredentialStorageError(\"profile_not_found\", \"Credential profile was not found.\");\n\t\t}\n\t\tawait this.runChecked([\"delete\", \"item\", cached.id], undefined, signal);\n\t\tthis.profiles.delete(profile);\n\t\tthis.lastSyncAt = Date.now();\n\t}\n\n\tlock(): void {\n\t\tthis.executable = undefined;\n\t\tthis.sessionKey = undefined;\n\t\tfor (const cached of this.profiles.values()) {\n\t\t\tfor (const variable of cached.record.variables) variable.value = \"\";\n\t\t\tcached.item.notes = \"\";\n\t\t}\n\t\tthis.profiles.clear();\n\t\tthis.loaded = false;\n\t\tthis.lastSyncAt = 0;\n\t}\n\n\tprivate assertConnected(): { executable: string; sessionKey: string } {\n\t\tif (!this.executable || !this.sessionKey) {\n\t\t\tthrow new BitwardenCredentialStorageError(\"not_connected\", \"Bitwarden is not connected.\");\n\t\t}\n\t\treturn { executable: this.executable, sessionKey: this.sessionKey };\n\t}\n\n\tprivate async ensureLoaded(signal?: AbortSignal): Promise<void> {\n\t\tthis.assertConnected();\n\t\tif (!this.loaded) await this.reload(signal, false);\n\t}\n\n\tprivate async reload(signal: AbortSignal | undefined, attemptSync: boolean): Promise<void> {\n\t\tif (attemptSync) {\n\t\t\ttry {\n\t\t\t\tawait this.runChecked([\"sync\"], undefined, signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof BitwardenCredentialStorageError) || error.code !== \"provider_command_failed\") {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\t// A network sync failure must not discard a locally available encrypted vault.\n\t\t\t}\n\t\t}\n\t\tconst rawItems = parseJson(\n\t\t\tawait this.runChecked([\"list\", \"items\", \"--search\", ITEM_NAME_PREFIX], undefined, signal),\n\t\t);\n\t\tif (!Array.isArray(rawItems) || rawItems.length > MAX_PROFILE_ITEMS) {\n\t\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\t\"malformed_provider_data\",\n\t\t\t\t\"Bitwarden returned an invalid number of profile items.\",\n\t\t\t);\n\t\t}\n\t\tconst next = new Map<string, CachedBitwardenProfile>();\n\t\tfor (const rawItem of rawItems) {\n\t\t\tconst parsed = parseProfileItem(rawItem);\n\t\t\tif (!parsed) continue;\n\t\t\tif (next.has(parsed.record.profile)) {\n\t\t\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\t\t\"malformed_provider_data\",\n\t\t\t\t\t\"Bitwarden contains duplicate Pi credential profiles.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tnext.set(parsed.record.profile, parsed);\n\t\t}\n\t\tthis.lockProfileCache();\n\t\tfor (const [profile, cached] of next) this.profiles.set(profile, cached);\n\t\tthis.loaded = true;\n\t\tthis.lastSyncAt = Date.now();\n\t}\n\n\tprivate lockProfileCache(): void {\n\t\tfor (const cached of this.profiles.values()) {\n\t\t\tfor (const variable of cached.record.variables) variable.value = \"\";\n\t\t\tcached.item.notes = \"\";\n\t\t}\n\t\tthis.profiles.clear();\n\t}\n\n\tprivate async runChecked(\n\t\targs: string[],\n\t\tinput: string | undefined,\n\t\tsignal: AbortSignal | undefined,\n\t): Promise<string> {\n\t\tconst { executable, sessionKey } = this.assertConnected();\n\t\tconst result = await this.runCommand({\n\t\t\texecutable,\n\t\t\targs,\n\t\t\t...(input !== undefined ? { input } : {}),\n\t\t\tsessionKey,\n\t\t\t...(signal ? { signal } : {}),\n\t\t});\n\t\tif (\n\t\t\tresult.exitCode !== 0 ||\n\t\t\tresult.aborted === true ||\n\t\t\tresult.timedOut === true ||\n\t\t\tresult.outputLimitExceeded === true\n\t\t) {\n\t\t\tthrow new BitwardenCredentialStorageError(\n\t\t\t\t\"provider_command_failed\",\n\t\t\t\t\"Bitwarden command failed safely without exposing provider output.\",\n\t\t\t);\n\t\t}\n\t\treturn result.stdout;\n\t}\n}\n"]}
@@ -1,9 +1,13 @@
1
1
  import type { AgentTool } from "@caupulican/pi-agent-core";
2
2
  import type { TSchema } from "typebox";
3
- import type { SecretVault } from "./secret-vault.ts";
4
- export declare function isProtectedCredentialPath(rawPath: string, cwd: string, vault?: SecretVault): boolean;
3
+ export interface CredentialExposureBoundary {
4
+ redactSensitiveText(text: string): string;
5
+ protectedFiles?: readonly string[];
6
+ protectedDirectories?: readonly string[];
7
+ }
8
+ export declare function isProtectedCredentialPath(rawPath: string, cwd: string, boundary?: CredentialExposureBoundary): boolean;
5
9
  /** Stable model-facing refusal for direct inspection/mutation of credential material. */
6
- export declare function credentialToolBlockReason(toolName: string, args: unknown, cwd: string, vault?: SecretVault): string | undefined;
10
+ export declare function credentialToolBlockReason(toolName: string, args: unknown, cwd: string, boundary?: CredentialExposureBoundary): string | undefined;
7
11
  /** Apply the same path refusal and output redaction to foreground, extension, scout, and lane tools. */
8
- export declare function wrapToolWithCredentialExposureGuard<TParameters extends TSchema, TDetails>(tool: AgentTool<TParameters, TDetails>, cwd: string, vault?: SecretVault): AgentTool<TParameters, TDetails>;
12
+ export declare function wrapToolWithCredentialExposureGuard<TParameters extends TSchema, TDetails>(tool: AgentTool<TParameters, TDetails>, _cwd: string, boundary?: CredentialExposureBoundary): AgentTool<TParameters, TDetails>;
9
13
  //# sourceMappingURL=credential-exposure-guard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credential-exposure-guard.d.ts","sourceRoot":"","sources":["../../../src/core/secrets/credential-exposure-guard.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAsCrD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CA8BpG;AAyHD,yFAAyF;AACzF,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,WAAW,GACjB,MAAM,GAAG,SAAS,CAwDpB;AAuCD,wGAAwG;AACxG,wBAAgB,mCAAmC,CAAC,WAAW,SAAS,OAAO,EAAE,QAAQ,EACxF,IAAI,EAAE,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,EACtC,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,WAAW,GACjB,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAqBlC"}
1
+ {"version":3,"file":"credential-exposure-guard.d.ts","sourceRoot":"","sources":["../../../src/core/secrets/credential-exposure-guard.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAgCvC,MAAM,WAAW,0BAA0B;IAC1C,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAWD,wBAAgB,yBAAyB,CACxC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAgCT;AAyHD,yFAAyF;AACzF,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,0BAA0B,GACnC,MAAM,GAAG,SAAS,CAwDpB;AAuCD,wGAAwG;AACxG,wBAAgB,mCAAmC,CAAC,WAAW,SAAS,OAAO,EAAE,QAAQ,EACxF,IAAI,EAAE,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,EACtC,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,0BAA0B,GACnC,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAqBlC"}