@codyswann/lisa 4.85.0 → 4.86.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/all/copy-overwrite/scripts/lib/completion-proof-content.mjs +63 -22
  2. package/all/copy-overwrite/scripts/lib/npm-update-hosted-hook.mjs +6 -1
  3. package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +19 -3
  4. package/all/copy-overwrite/scripts/npm-updater-helper-graph.json +2 -2
  5. package/dist/cli/doctor-session-manager-pending.d.ts +17 -0
  6. package/dist/cli/doctor-session-manager-pending.d.ts.map +1 -0
  7. package/dist/cli/doctor-session-manager-pending.js +130 -0
  8. package/dist/cli/doctor-session-manager-pending.js.map +1 -0
  9. package/dist/cli/doctor-session-manager-token.d.ts +69 -0
  10. package/dist/cli/doctor-session-manager-token.d.ts.map +1 -0
  11. package/dist/cli/doctor-session-manager-token.js +264 -0
  12. package/dist/cli/doctor-session-manager-token.js.map +1 -0
  13. package/dist/cli/doctor-session-manager.d.ts +3 -1
  14. package/dist/cli/doctor-session-manager.d.ts.map +1 -1
  15. package/dist/cli/doctor-session-manager.js +168 -146
  16. package/dist/cli/doctor-session-manager.js.map +1 -1
  17. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  18. package/dist/core/lisa-owned-hash-ledger.js +16 -0
  19. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  20. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  21. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  22. package/dist/core/upstream-evidence-manifest.js +168 -26
  23. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  24. package/dist/opencode/plugin-templates/parity-safety-net.sh +19 -3
  25. package/package.json +4 -4
  26. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  28. package/plugins/lisa/.codex-plugin/skills/lisa-parity-sentry-sdk-setup/SKILL.md +24 -17
  29. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/SKILL.md +5 -3
  30. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  31. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/validate-config.mjs +86 -31
  32. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/SKILL.md +197 -54
  33. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/references/runbook-template.md +23 -10
  34. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  35. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  36. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  37. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  38. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  39. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  40. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  41. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  42. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  43. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/config.mjs +39 -11
  44. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  45. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  46. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  47. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  48. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  49. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  50. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  51. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  52. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  53. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  54. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  55. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  56. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  57. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token.mjs +39 -120
  58. package/plugins/lisa/.codex-plugin/skills/lisa-setup-session-manager/SKILL.md +82 -19
  59. package/plugins/lisa/commands/session-manager.md +1 -1
  60. package/plugins/lisa/commands/setup/session-manager.md +1 -1
  61. package/plugins/lisa/hooks/parity-safety-net.sh +19 -3
  62. package/plugins/lisa/rules/reference/config-resolution.md +39 -7
  63. package/plugins/lisa/skills/lisa-parity-sentry-sdk-setup/SKILL.md +24 -17
  64. package/plugins/lisa/skills/lisa-secrets-access/SKILL.md +5 -3
  65. package/plugins/lisa/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  66. package/plugins/lisa/skills/lisa-secrets-access/scripts/validate-config.mjs +86 -31
  67. package/plugins/lisa/skills/lisa-session-manager/SKILL.md +197 -54
  68. package/plugins/lisa/skills/lisa-session-manager/references/runbook-template.md +23 -10
  69. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  70. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  71. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  72. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  73. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  74. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  75. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  76. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  77. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  78. package/plugins/lisa/skills/lisa-session-manager/scripts/config.mjs +39 -11
  79. package/plugins/lisa/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  80. package/plugins/lisa/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  81. package/plugins/lisa/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  82. package/plugins/lisa/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  83. package/plugins/lisa/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  84. package/plugins/lisa/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  85. package/plugins/lisa/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  86. package/plugins/lisa/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  87. package/plugins/lisa/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  88. package/plugins/lisa/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  89. package/plugins/lisa/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  90. package/plugins/lisa/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  91. package/plugins/lisa/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  92. package/plugins/lisa/skills/lisa-session-manager/scripts/token.mjs +39 -120
  93. package/plugins/lisa/skills/lisa-setup-session-manager/SKILL.md +82 -19
  94. package/plugins/lisa-agy/commands/lisa/session-manager.md +1 -1
  95. package/plugins/lisa-agy/commands/lisa/setup/session-manager.md +1 -1
  96. package/plugins/lisa-agy/hooks/parity-safety-net.sh +19 -3
  97. package/plugins/lisa-agy/plugin.json +1 -1
  98. package/plugins/lisa-agy/skills/lisa-parity-sentry-sdk-setup/SKILL.md +24 -17
  99. package/plugins/lisa-agy/skills/lisa-secrets-access/SKILL.md +5 -3
  100. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  101. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/validate-config.mjs +86 -31
  102. package/plugins/lisa-agy/skills/lisa-session-manager/SKILL.md +197 -54
  103. package/plugins/lisa-agy/skills/lisa-session-manager/references/runbook-template.md +23 -10
  104. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  105. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  106. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  107. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  108. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  109. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  110. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  111. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  112. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  113. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/config.mjs +39 -11
  114. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  115. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  116. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  117. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  118. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  119. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  120. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  121. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  122. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  123. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  124. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  125. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  126. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  127. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token.mjs +39 -120
  128. package/plugins/lisa-agy/skills/lisa-setup-session-manager/SKILL.md +82 -19
  129. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  130. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  131. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  132. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  133. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  134. package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
  135. package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
  136. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  137. package/plugins/lisa-copilot/commands/lisa/session-manager.md +1 -1
  138. package/plugins/lisa-copilot/commands/lisa/setup/session-manager.md +1 -1
  139. package/plugins/lisa-copilot/hooks/parity-safety-net.sh +19 -3
  140. package/plugins/lisa-copilot/rules/reference/config-resolution.md +39 -7
  141. package/plugins/lisa-copilot/skills/lisa-parity-sentry-sdk-setup/SKILL.md +24 -17
  142. package/plugins/lisa-copilot/skills/lisa-secrets-access/SKILL.md +5 -3
  143. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  144. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/validate-config.mjs +86 -31
  145. package/plugins/lisa-copilot/skills/lisa-session-manager/SKILL.md +197 -54
  146. package/plugins/lisa-copilot/skills/lisa-session-manager/references/runbook-template.md +23 -10
  147. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  148. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  149. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  150. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  151. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  152. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  153. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  154. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  155. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  156. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/config.mjs +39 -11
  157. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  158. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  159. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  160. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  161. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  162. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  163. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  164. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  165. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  166. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  167. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  168. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  169. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  170. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token.mjs +39 -120
  171. package/plugins/lisa-copilot/skills/lisa-setup-session-manager/SKILL.md +82 -19
  172. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  173. package/plugins/lisa-cursor/commands/lisa/session-manager.md +1 -1
  174. package/plugins/lisa-cursor/commands/lisa/setup/session-manager.md +1 -1
  175. package/plugins/lisa-cursor/hooks/parity-safety-net.sh +19 -3
  176. package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +39 -7
  177. package/plugins/lisa-cursor/skills/lisa-parity-sentry-sdk-setup/SKILL.md +24 -17
  178. package/plugins/lisa-cursor/skills/lisa-secrets-access/SKILL.md +5 -3
  179. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  180. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/validate-config.mjs +86 -31
  181. package/plugins/lisa-cursor/skills/lisa-session-manager/SKILL.md +197 -54
  182. package/plugins/lisa-cursor/skills/lisa-session-manager/references/runbook-template.md +23 -10
  183. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  184. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  185. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  186. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  187. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  188. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  189. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  190. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  191. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  192. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/config.mjs +39 -11
  193. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  194. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  195. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  196. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  197. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  198. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  199. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  200. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  201. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  202. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  203. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  204. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  205. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  206. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token.mjs +39 -120
  207. package/plugins/lisa-cursor/skills/lisa-setup-session-manager/SKILL.md +82 -19
  208. package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
  209. package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
  210. package/plugins/lisa-devin/hooks/parity-safety-net.sh +19 -3
  211. package/plugins/lisa-devin/rules/reference/config-resolution.md +39 -7
  212. package/plugins/lisa-devin/skills/lisa-parity-sentry-sdk-setup/SKILL.md +24 -17
  213. package/plugins/lisa-devin/skills/lisa-secrets-access/SKILL.md +5 -3
  214. package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  215. package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/validate-config.mjs +86 -31
  216. package/plugins/lisa-devin/skills/lisa-session-manager/SKILL.md +197 -54
  217. package/plugins/lisa-devin/skills/lisa-session-manager/references/runbook-template.md +23 -10
  218. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  219. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  220. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  221. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  222. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  223. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  224. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  225. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  226. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  227. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/config.mjs +39 -11
  228. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  229. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  230. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  231. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  232. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  233. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  234. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  235. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  236. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  237. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  238. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  239. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  240. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  241. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token.mjs +39 -120
  242. package/plugins/lisa-devin/skills/lisa-setup-session-manager/SKILL.md +82 -19
  243. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  244. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  245. package/plugins/lisa-expo-agy/plugin.json +1 -1
  246. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  247. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  248. package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
  249. package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
  250. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  251. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  252. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  253. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  254. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  255. package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
  256. package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
  257. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  258. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  259. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  260. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  261. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  262. package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
  263. package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
  264. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  265. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  266. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  267. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  268. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  269. package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
  270. package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
  271. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  272. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  273. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  274. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  275. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  276. package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
  277. package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
  278. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  279. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  280. package/plugins/lisa-rails-agy/plugin.json +1 -1
  281. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  282. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  283. package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
  284. package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
  285. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  286. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  287. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  288. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  289. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  290. package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
  291. package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
  292. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  293. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  294. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  295. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  296. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  297. package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
  298. package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
  299. package/plugins/src/base/commands/session-manager.md +1 -1
  300. package/plugins/src/base/commands/setup/session-manager.md +1 -1
  301. package/plugins/src/base/hooks/parity-safety-net.sh +19 -3
  302. package/plugins/src/base/rules/reference/config-resolution.md +39 -7
  303. package/plugins/src/base/skills/lisa-parity-sentry-sdk-setup/SKILL.md +24 -17
  304. package/plugins/src/base/skills/lisa-secrets-access/SKILL.md +5 -3
  305. package/plugins/src/base/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  306. package/plugins/src/base/skills/lisa-secrets-access/scripts/validate-config.mjs +86 -31
  307. package/plugins/src/base/skills/lisa-session-manager/SKILL.md +197 -54
  308. package/plugins/src/base/skills/lisa-session-manager/references/runbook-template.md +23 -10
  309. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  310. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  311. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  312. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  313. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  314. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  315. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  316. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  317. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  318. package/plugins/src/base/skills/lisa-session-manager/scripts/config.mjs +39 -11
  319. package/plugins/src/base/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  320. package/plugins/src/base/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  321. package/plugins/src/base/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  322. package/plugins/src/base/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  323. package/plugins/src/base/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  324. package/plugins/src/base/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  325. package/plugins/src/base/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  326. package/plugins/src/base/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  327. package/plugins/src/base/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  328. package/plugins/src/base/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  329. package/plugins/src/base/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  330. package/plugins/src/base/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  331. package/plugins/src/base/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  332. package/plugins/src/base/skills/lisa-session-manager/scripts/token.mjs +39 -120
  333. package/plugins/src/base/skills/lisa-setup-session-manager/SKILL.md +82 -19
@@ -3475,12 +3475,28 @@ if [ -f "$rules_file" ]; then
3475
3475
  # here — before the remaining rules ran, and with an exit status that is
3476
3476
  # not a refusal. The `||` puts the pipeline in a condition context, where
3477
3477
  # a non-zero status is expected rather than fatal.
3478
- # Consume the whole input: grep -q can close an early match while printf
3479
- # is still writing, making pipefail report SIGPIPE instead of the match.
3478
+ # A here-string, never a pipe. With `printf | grep` under pipefail, a grep
3479
+ # that stops at its first match (`-q`, and GNU grep whose stdout is
3480
+ # /dev/null, which it treats as `-q`) closes the pipe while printf is still
3481
+ # writing; printf takes SIGPIPE and the pipeline reports 141 instead of
3482
+ # grep's 0. 141 lands in the `*)` arm below and a rule that MATCHED was
3483
+ # reported as an invalid regex and not enforced (CodySwannGT/lisa#4564).
3484
+ # A here-string has no writer process, so the status is grep's alone.
3485
+ #
3486
+ # The here-string is staged by the shell (a pipe, or a temp file for a
3487
+ # large body or on Bash 3.2), and that staging can fail: no temp space,
3488
+ # a file-size limit. A failed redirection on a bare `grep … <<<` returns
3489
+ # 1, the same status as "no match", so the rule would silently pass. The
3490
+ # brace group separates the two: grep's own status is captured INSIDE it,
3491
+ # so the group itself only fails when the redirection could not be set up.
3480
3492
  rule_status=0
3481
- printf '%s' "$custom_command_str" | grep -Ei -- "$rule" >/dev/null || rule_status=$?
3493
+ { grep -qEi -- "$rule" || rule_status=$?; } <<<"$custom_command_str" \
3494
+ || rule_status=unstaged
3482
3495
  case "$rule_status" in
3483
3496
  0) block "matched a project custom safety rule (${rules_file##*/}): $rule" ;;
3497
+ # Fail closed: the rule could not be evaluated at all, which is not the
3498
+ # same thing as the rule not matching.
3499
+ unstaged) block "could not stage the command to check project custom safety rule (${rules_file##*/}): $rule" ;;
3484
3500
  1) ;; # no match
3485
3501
  # grep exits 2 on a malformed ERE. Treated as no-match before, so a typo
3486
3502
  # in a project's rules file silently disabled that rule — a guard the
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.85.0",
3
+ "version": "4.86.1",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -177,8 +177,11 @@ once at module startup with the DSN from the environment. Await a finite positiv
177
177
  flush budget on both success and original-error paths. A false flush result or
178
178
  rejection must not turn successful queue work into a retry or replace its real
179
179
  error. Keep diagnostics local and non-throwing, and preserve the client for warm
180
- invocations: `close()` disables it. The following helper wraps the host's existing
181
- business operation; it neither mutates context nor adds a Lambda callback.
180
+ invocations: `close()` disables it. A warm container reuses the same process, so
181
+ run each invocation inside `Sentry.withIsolationScope()`: tags, user and
182
+ breadcrumbs that one invocation sets then stay with that invocation instead of
183
+ leaking into the next one's events. The following helper wraps the host's existing
184
+ business operation; it neither mutates the Lambda context nor adds a Lambda callback.
182
185
 
183
186
  <!-- lisa-node24-unwrapped-example:start -->
184
187
  ```ts
@@ -200,24 +203,28 @@ export async function withSentryFlush<T>(
200
203
  if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
201
204
  throw new RangeError("Choose a finite positive Sentry flush budget");
202
205
  }
203
- try {
204
- return await work();
205
- } catch (originalError) {
206
- try {
207
- Sentry.captureException(originalError);
208
- } catch {
209
- // Preserve the original handler error even if capture fails.
210
- }
211
- throw originalError;
212
- } finally {
206
+ // A fresh isolation scope per invocation: scope data set by one warm
207
+ // invocation must not be attached to the next invocation's events.
208
+ return Sentry.withIsolationScope(async () => {
213
209
  try {
214
- if (!(await Sentry.flush(timeoutMs))) {
215
- reportFlushProblem("Sentry flush did not finish in time");
210
+ return await work();
211
+ } catch (originalError) {
212
+ try {
213
+ Sentry.captureException(originalError);
214
+ } catch {
215
+ // Preserve the original handler error even if capture fails.
216
+ }
217
+ throw originalError;
218
+ } finally {
219
+ try {
220
+ if (!(await Sentry.flush(timeoutMs))) {
221
+ reportFlushProblem("Sentry flush did not finish in time");
222
+ }
223
+ } catch {
224
+ reportFlushProblem("Sentry flush rejected");
216
225
  }
217
- } catch {
218
- reportFlushProblem("Sentry flush rejected");
219
226
  }
220
- }
227
+ });
221
228
  }
222
229
  ```
223
230
  <!-- lisa-node24-unwrapped-example:end -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lisa-secrets-access
3
- description: "Vendor-neutral access layer for secrets. Every skill and script that needs an API key MUST resolve it through this skill rather than reading a keychain, an .env file, or a provider CLI directly. Models two independent axes — the provider a secret lives in (Bitwarden, 1Password, AWS Secrets Manager, Doppler, Vault) and the surface the code runs on (local, GitHub Actions, Codex Cloud) — resolving environment first, then a materialized file where the surface has one, then the provider by exact key name. Enforces one store per secret, fails closed on duplicate names, reads usage metadata from the provider's own note field, and never writes. Rotating credentials route through the separate rotate-secret writer, and copying one into a second store (Bitwarden → GitHub Actions) routes through the separate sync-secret-to-ci propagator."
3
+ description: "Vendor-neutral access layer for secrets. Every skill and script that needs an API key MUST resolve it through this skill rather than reading a keychain, an .env file, or a provider CLI directly. Models two independent axes — the provider a secret lives in (Bitwarden, 1Password, AWS Secrets Manager, Doppler, Vault) and the surface the code runs on (local, GitHub Actions, Codex Cloud) — resolving environment first, then a materialized file where the surface has one, then the provider by exact key name. Enforces one store per secret, fails closed on duplicate names, reads usage metadata from the provider's own note field, and never writes. Rotating credentials route through the separate rotate-secret writer, and copying one into a second store (Bitwarden → GitHub Actions) routes through the separate sync-secret-to-ci propagator; the session manager's Telegram bot token is stored through its own store-token, which uses this skill's provider write path."
4
4
  allowed-tools: ["Bash", "Read", "Skill"]
5
5
  ---
6
6
 
@@ -273,6 +273,8 @@ No create, no update, no rotate. Writing secrets or their notes requires an auth
273
273
 
274
274
  The two writers are siblings, not modes: `rotate-secret.mjs` replaces a value **at its source**, and `sync-secret-to-ci.mjs` copies one **into a second store** without touching the source. Each needs an authority the resolver must not hold, so each is its own program with its own declaration list.
275
275
 
276
+ A third, narrow writer lives outside this skill: the session manager's `store-token` (`lisa-session-manager/scripts/token-store.mjs`) stores the Telegram bot token as `TELEGRAM_BOT_TOKEN_<NAME>` through `providers.mjs` `createSecret` (a new record) or `writeSecret` (`--replace`), then reads it back through the ordinary provider view and compares hashes before deleting the plaintext file it replaces. It writes that one name only, and only when an operator runs it. `createSecret` is Bitwarden-only; on any other provider the operator creates the secret and `store-token` verifies it. Like `bws secret edit`, `bws secret create` (2.1.0) takes the value as a positional argument and its help offers no stdin or file option, so the value is in argv for the life of that one call: the same documented exception, confined the same way (no shell, `--output none`, and a failure message that never repeats the command line).
277
+
276
278
  ## Rotating credentials
277
279
 
278
280
  A **consumable** credential is one where using it can invalidate the stored copy: an OAuth refresh token the issuer replaces on every exchange, a short-lived session, a single-use enrollment token. The defining property is not "OAuth" — it is that a successful use makes the value on record wrong.
@@ -366,9 +368,9 @@ Values never enter that process, so its output cannot leak one even if logged.
366
368
 
367
369
  ## Provider dispatch
368
370
 
369
- | Provider | Read | Write (rotation only) |
371
+ | Provider | Read | Write (rotation, and the session manager's `store-token`) |
370
372
  | --- | --- | --- |
371
- | `bitwarden` | `bws secret list --output json` → index by `key` | `bws secret edit`; temporary `create`/`delete` for AWS publication coordination |
373
+ | `bitwarden` | `bws secret list --output json` → index by `key` | `bws secret edit`; `bws secret create <KEY> <VALUE> <PROJECT_ID> --output none` for `store-token` (`createSecret`); temporary `create`/`delete` for AWS publication coordination |
372
374
  | `doppler` | `doppler secrets download --no-file --format json` | not implemented |
373
375
  | `env` | environment only; the provider is the environment | n/a |
374
376
  | `1password` | `op read "op://<vault>/<name>/credential"` | not implemented |
@@ -701,6 +701,72 @@ export function rawByKey(cfg, key) {
701
701
  return matches[0] ?? null;
702
702
  }
703
703
 
704
+ /** A provider error that names a rate limit (HTTP 429). */
705
+ const RATE_LIMITED = /\b429\b|too many requests|rate.?limit/i;
706
+
707
+ /**
708
+ * Run a provider CLI whose argv carries a secret value, and never let that
709
+ * argv reach an error message.
710
+ *
711
+ * `execFileSync` puts the whole command line in its error (`Command failed:
712
+ * bws secret create KEY <value> ...`), so a failed write would print the very
713
+ * value it was writing. The rethrown error keeps only what a caller needs to
714
+ * act on: the operation, the exit status and whether the provider
715
+ * rate-limited the call. Every other error (a missing binary's
716
+ * `spawnSync bws ENOENT`, a deadline {@link run} already reworded) is
717
+ * rebuilt too, keeping only its message (with the value redacted) and its
718
+ * `code`/`errno`/`syscall`/`status`/`signal`: Node's spawn errors also carry
719
+ * `spawnargs`, the full argv, value included, which a caller that logs or
720
+ * serializes the error would publish.
721
+ * @param {string} bin Executable name.
722
+ * @param {string[]} args Arguments, one of them a secret value.
723
+ * @param {NodeJS.ProcessEnv} env Environment for the child.
724
+ * @param {string} operation What the call was doing, in operator words.
725
+ * @param {string} value The secret value in `args`, redacted from any error.
726
+ * @returns {string} Captured stdout.
727
+ */
728
+ function runWithValue(bin, args, env, operation, value) {
729
+ try {
730
+ return run(bin, args, env, operation);
731
+ } catch (error) {
732
+ // Node's "Command failed: <command line>" error carries argv in its text.
733
+ if (!String(error?.message ?? "").startsWith("Command failed")) {
734
+ throw withoutArgv(error, value);
735
+ }
736
+ const why = RATE_LIMITED.test(String(error.stderr ?? ""))
737
+ ? "the provider rate-limited the request (429 Too Many Requests)"
738
+ : "the provider refused the request or could not be reached";
739
+ throw new Error(
740
+ `${operation} failed (exit ${error.status ?? error.signal}): ${why}. ` +
741
+ `The command's own output is withheld because its arguments carry ` +
742
+ `the secret value.`
743
+ );
744
+ }
745
+ }
746
+
747
+ /** The fields of a spawn error that carry no argv, output or value. */
748
+ const SAFE_ERROR_FIELDS = ["code", "errno", "syscall", "status", "signal"];
749
+
750
+ /**
751
+ * A copy of a child-process error with no argv on it: a fresh Error whose
752
+ * message has `value` redacted, and only {@link SAFE_ERROR_FIELDS}. Drops
753
+ * `spawnargs`, `cmd`, `path`, `stdout`, `stderr` and `output`.
754
+ * @param {unknown} error What the call threw.
755
+ * @param {string} value The secret value to redact.
756
+ * @returns {Error} The rebuilt error.
757
+ */
758
+ function withoutArgv(error, value) {
759
+ const text = String(error?.message ?? error);
760
+ const message = value ? text.split(String(value)).join("<redacted>") : text;
761
+ const safe = Object.fromEntries(
762
+ SAFE_ERROR_FIELDS.filter(key => error?.[key] !== undefined).map(key => [
763
+ key,
764
+ error[key],
765
+ ])
766
+ );
767
+ return Object.assign(new Error(message), safe);
768
+ }
769
+
704
770
  /**
705
771
  * Write a replacement value back to the provider.
706
772
  *
@@ -709,7 +775,8 @@ export function rawByKey(cfg, key) {
709
775
  * Bitwarden CLI exposes no stdin path for an edit, so this is a documented
710
776
  * exception rather than an oversight: it is confined to the one operation that
711
777
  * cannot be expressed otherwise, and `execFileSync` at least keeps the value
712
- * out of a shell and therefore out of shell history.
778
+ * out of a shell and therefore out of shell history. A failure is reported
779
+ * through {@link runWithValue}, so the value never reaches the error either.
713
780
  * @param {object} cfg Resolved configuration.
714
781
  * @param {string} id Provider-side identifier for the secret.
715
782
  * @param {string} value Replacement value.
@@ -718,11 +785,12 @@ export function writeSecret(cfg, id, value) {
718
785
  const env = providerEnv(cfg);
719
786
 
720
787
  if (cfg.provider === "bitwarden") {
721
- run(
788
+ runWithValue(
722
789
  "bws",
723
790
  ["secret", "edit", id, "--value", value],
724
791
  env,
725
- "updating a secret in Bitwarden"
792
+ "updating a secret in Bitwarden",
793
+ value
726
794
  );
727
795
  return;
728
796
  }
@@ -732,6 +800,56 @@ export function writeSecret(cfg, id, value) {
732
800
  );
733
801
  }
734
802
 
803
+ /**
804
+ * Create one new secret in the provider.
805
+ *
806
+ * The one caller is the session manager's `store-token` (#4555), which moves
807
+ * the Telegram bot token out of a plaintext file and into the vault, then
808
+ * reads it back to prove the write before deleting the file. It never
809
+ * replaces an existing record: that is {@link writeSecret}'s job.
810
+ *
811
+ * The value is a positional argument, the same documented exception as
812
+ * {@link writeSecret}: `bws secret create` (2.1.0) takes `<KEY> <VALUE>
813
+ * <PROJECT_ID>` and its help lists no stdin or file option for the value, so
814
+ * there is no way to keep it out of argv. `execFileSync` keeps it out of a
815
+ * shell, `--output none` keeps the created record (value included) off
816
+ * stdout, and {@link runWithValue} keeps it out of any error.
817
+ *
818
+ * Bitwarden only. Other providers fail with a message naming where to add
819
+ * one; until then the operator creates the secret in the vault themselves.
820
+ * @param {object} cfg Resolved configuration.
821
+ * @param {{name: string, value: string, projectId: string, note?: string}}
822
+ * secret Exact key, value, target provider project and usage note.
823
+ */
824
+ export function createSecret(cfg, { name, value, projectId, note }) {
825
+ if (!ENV_KEY.test(name)) {
826
+ throw new Error(`secret name is not an environment variable name: ${name}`);
827
+ }
828
+ if (cfg.provider === "bitwarden") {
829
+ runWithValue(
830
+ "bws",
831
+ [
832
+ "secret",
833
+ "create",
834
+ name,
835
+ value,
836
+ projectId,
837
+ ...(note ? ["--note", note] : []),
838
+ "--output",
839
+ "none",
840
+ ],
841
+ providerEnv(cfg),
842
+ "creating a secret in Bitwarden",
843
+ value
844
+ );
845
+ return;
846
+ }
847
+ throw new Error(
848
+ `provider "${cfg.provider}" has no create implemented.\n` +
849
+ `Create the secret in the provider yourself, or add one in providers.mjs.`
850
+ );
851
+ }
852
+
735
853
  /**
736
854
  * Create one provider-issued publication contender in the target project.
737
855
  *
@@ -664,12 +664,19 @@ const STALL_RULES = {
664
664
  requestionHours: [n => n >= 0, "zero or a positive number"],
665
665
  };
666
666
 
667
+ /** Notification providers `sessionManager.notify.provider` accepts. */
668
+ const NOTIFY_PROVIDERS = ["none", "telegram"];
669
+
667
670
  /**
668
671
  * Validate `sessionManager.notify`.
669
672
  *
670
- * `stateDir` is required rather than defaulted here: the default dir is shared
671
- * by every project, and a shared dir is exactly how one project's bot gets
672
- * taken over by another's session.
673
+ * A notification channel is optional (#4555): an absent block, an absent
674
+ * provider and `"none"` all mean the manager runs with no channel, and then
675
+ * there is no state dir to name. A `stateDir` without the telegram provider is
676
+ * refused rather than ignored, because it means the operator believes a bot is
677
+ * attached when none will be. For telegram, `stateDir` is required rather than
678
+ * defaulted here: the default dir is shared by every project, and a shared dir
679
+ * is exactly how one project's bot gets taken over by another's session.
673
680
  * @param {unknown} notify The declared value.
674
681
  * @returns {string[]} Problems found.
675
682
  */
@@ -677,56 +684,104 @@ function validateNotify(notify) {
677
684
  if (notify !== undefined && !isPlainObject(notify)) {
678
685
  return ["sessionManager.notify must be an object"];
679
686
  }
680
- const provider = notify?.provider;
681
- const stateDir = notify?.stateDir;
682
- return [
683
- ...(provider === undefined || provider === "telegram"
684
- ? []
685
- : [
686
- `sessionManager.notify.provider ${JSON.stringify(provider)} is not ` +
687
- `supported. Only "telegram" is implemented.`,
688
- ]),
689
- ...(typeof stateDir === "string" && stateDir.trim() !== ""
690
- ? []
691
- : [
692
- `sessionManager.notify.stateDir is missing. Each project needs its ` +
693
- `own Telegram state dir, such as ` +
694
- `"~/.claude/channels/telegram-<project>".`,
695
- ]),
696
- ];
687
+ const provider = notify?.provider ?? "none";
688
+ if (!NOTIFY_PROVIDERS.includes(provider)) {
689
+ return [
690
+ `sessionManager.notify.provider ${JSON.stringify(provider)} is not ` +
691
+ `supported. Use "none" (no notification channel) or "telegram".`,
692
+ ];
693
+ }
694
+ const hasStateDir = notify?.stateDir !== undefined;
695
+ const stateDirOk =
696
+ typeof notify?.stateDir === "string" && notify.stateDir.trim() !== "";
697
+ if (provider === "none") {
698
+ return hasStateDir
699
+ ? [
700
+ `sessionManager.notify.stateDir is set, but notify.provider is not ` +
701
+ `"telegram", so no bot would use it. Set notify.provider to ` +
702
+ `"telegram", or remove notify.stateDir.`,
703
+ ]
704
+ : [];
705
+ }
706
+ return stateDirOk
707
+ ? []
708
+ : [
709
+ `sessionManager.notify.stateDir is missing. Each project needs its ` +
710
+ `own Telegram state dir, such as ` +
711
+ `"~/.claude/channels/telegram-<project>".`,
712
+ ];
713
+ }
714
+
715
+ /**
716
+ * Maps under `sessionManager` whose KEYS are names chosen by the project, not
717
+ * config field names. `repos.entries` is keyed by child repository directory,
718
+ * so a repo called `token-service` or `secrets-manager` is a name, not a
719
+ * credential field; testing it against CREDENTIAL_KEY made `init-config
720
+ * --write` emit a block that `validate` then refused (CodySwannGT/lisa#4564).
721
+ * Their VALUES are still walked, so a token placed inside an entry is caught.
722
+ */
723
+ const NAME_KEYED_MAPS = [["repos", "entries"]];
724
+
725
+ /**
726
+ * Whether a key trail below `sessionManager` is exactly a name-keyed map.
727
+ * Compared segment by segment, never as a dotted string: a literal key
728
+ * `"repos.entries"` would otherwise borrow the exemption.
729
+ * @param {readonly string[]} segments Object keys from the block root.
730
+ * @returns {boolean} True for a map whose keys are names.
731
+ */
732
+ function isNameKeyedMap(segments) {
733
+ return NAME_KEYED_MAPS.some(
734
+ map =>
735
+ map.length === segments.length &&
736
+ map.every((segment, i) => segment === segments[i])
737
+ );
697
738
  }
698
739
 
699
740
  /**
700
741
  * Walk the block for anything that looks like a credential.
701
742
  *
702
743
  * Config is committed, and this block configures a bot that grants shell
703
- * access over chat. The token belongs in the state dir's dotenv file (mode
704
- * 0600), so a token here is both leaked and unused. The value is never echoed.
744
+ * access over chat. The token belongs in the project's secrets provider
745
+ * (#4555; the state dir's 0600 dotenv file only when no provider is
746
+ * configured), so a token here is both leaked and unused. The value is never
747
+ * echoed.
705
748
  * @param {unknown} value Subtree.
706
- * @param {string} path Dotted path so far.
749
+ * @param {string} path Dotted path so far, for messages.
750
+ * @param {readonly string[] | null} [segments] Object keys from the block root;
751
+ * `null` once an array is crossed, since no name-keyed map lives there.
707
752
  * @returns {string[]} Problems found.
708
753
  */
709
- function findCredentials(value, path) {
754
+ function findCredentials(value, path, segments = []) {
710
755
  if (typeof value === "string") {
711
756
  return TOKEN_VALUE.test(value.trim())
712
757
  ? [
713
- `${path} looks like a bot token. Tokens never go in config; ` +
714
- `/lisa:setup:session-manager stores it in the state dir.`,
758
+ `${path} looks like a bot token. Tokens never go in config: ` +
759
+ `remove it, and store the token in the project's secrets ` +
760
+ `provider with session-manager.mjs store-token ` +
761
+ `(/lisa:setup:session-manager runs it).`,
715
762
  ]
716
763
  : [];
717
764
  }
718
765
  if (Array.isArray(value)) {
719
- return value.flatMap((item, i) => findCredentials(item, `${path}[${i}]`));
766
+ return value.flatMap((item, i) =>
767
+ findCredentials(item, `${path}[${i}]`, null)
768
+ );
720
769
  }
721
770
  if (!isPlainObject(value)) return [];
771
+ const keysAreNames = segments !== null && isNameKeyedMap(segments);
722
772
  return Object.entries(value).flatMap(([key, child]) =>
723
- CREDENTIAL_KEY.test(key)
773
+ !keysAreNames && CREDENTIAL_KEY.test(key)
724
774
  ? [
725
775
  `${path}.${key} names a credential. Tokens and secrets never go in ` +
726
- `config; /lisa:setup:session-manager stores the bot token in the ` +
727
- `state dir.`,
776
+ `config: remove it, and keep the bot token in the project's ` +
777
+ `secrets provider (session-manager.mjs store-token, run by ` +
778
+ `/lisa:setup:session-manager).`,
728
779
  ]
729
- : findCredentials(child, `${path}.${key}`)
780
+ : findCredentials(
781
+ child,
782
+ `${path}.${key}`,
783
+ segments === null ? null : [...segments, key]
784
+ )
730
785
  );
731
786
  }
732
787