@codyswann/lisa 4.84.11 → 4.86.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/dist/cli/doctor-session-manager-pending.d.ts +17 -0
  2. package/dist/cli/doctor-session-manager-pending.d.ts.map +1 -0
  3. package/dist/cli/doctor-session-manager-pending.js +130 -0
  4. package/dist/cli/doctor-session-manager-pending.js.map +1 -0
  5. package/dist/cli/doctor-session-manager-token.d.ts +69 -0
  6. package/dist/cli/doctor-session-manager-token.d.ts.map +1 -0
  7. package/dist/cli/doctor-session-manager-token.js +264 -0
  8. package/dist/cli/doctor-session-manager-token.js.map +1 -0
  9. package/dist/cli/doctor-session-manager.d.ts +3 -1
  10. package/dist/cli/doctor-session-manager.d.ts.map +1 -1
  11. package/dist/cli/doctor-session-manager.js +168 -146
  12. package/dist/cli/doctor-session-manager.js.map +1 -1
  13. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  14. package/dist/core/lisa-owned-hash-ledger.js +34 -0
  15. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  16. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  17. package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
  18. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  19. package/dist/core/upstream-evidence-manifest.js +172 -23
  20. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  21. package/package.json +4 -4
  22. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  24. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/SKILL.md +5 -3
  25. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  26. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
  27. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/SKILL.md +197 -54
  28. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/references/runbook-template.md +23 -10
  29. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  30. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  31. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  32. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  33. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  34. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  35. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  36. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  37. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  38. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/config.mjs +39 -11
  39. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  40. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  41. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  42. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  43. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  44. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  45. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  46. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  47. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  48. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  49. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  50. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  51. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  52. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token.mjs +39 -120
  53. package/plugins/lisa/.codex-plugin/skills/lisa-setup-session-manager/SKILL.md +82 -19
  54. package/plugins/lisa/commands/session-manager.md +1 -1
  55. package/plugins/lisa/commands/setup/session-manager.md +1 -1
  56. package/plugins/lisa/rules/reference/config-resolution.md +39 -7
  57. package/plugins/lisa/skills/lisa-secrets-access/SKILL.md +5 -3
  58. package/plugins/lisa/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  59. package/plugins/lisa/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
  60. package/plugins/lisa/skills/lisa-session-manager/SKILL.md +197 -54
  61. package/plugins/lisa/skills/lisa-session-manager/references/runbook-template.md +23 -10
  62. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  63. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  64. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  65. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  66. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  67. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  68. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  69. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  70. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  71. package/plugins/lisa/skills/lisa-session-manager/scripts/config.mjs +39 -11
  72. package/plugins/lisa/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  73. package/plugins/lisa/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  74. package/plugins/lisa/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  75. package/plugins/lisa/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  76. package/plugins/lisa/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  77. package/plugins/lisa/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  78. package/plugins/lisa/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  79. package/plugins/lisa/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  80. package/plugins/lisa/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  81. package/plugins/lisa/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  82. package/plugins/lisa/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  83. package/plugins/lisa/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  84. package/plugins/lisa/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  85. package/plugins/lisa/skills/lisa-session-manager/scripts/token.mjs +39 -120
  86. package/plugins/lisa/skills/lisa-setup-session-manager/SKILL.md +82 -19
  87. package/plugins/lisa-agy/commands/lisa/session-manager.md +1 -1
  88. package/plugins/lisa-agy/commands/lisa/setup/session-manager.md +1 -1
  89. package/plugins/lisa-agy/plugin.json +1 -1
  90. package/plugins/lisa-agy/skills/lisa-secrets-access/SKILL.md +5 -3
  91. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  92. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
  93. package/plugins/lisa-agy/skills/lisa-session-manager/SKILL.md +197 -54
  94. package/plugins/lisa-agy/skills/lisa-session-manager/references/runbook-template.md +23 -10
  95. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  96. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  97. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  98. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  99. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  100. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  101. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  102. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  103. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  104. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/config.mjs +39 -11
  105. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  106. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  107. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  108. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  109. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  110. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  111. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  112. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  113. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  114. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  115. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  116. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  117. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  118. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token.mjs +39 -120
  119. package/plugins/lisa-agy/skills/lisa-setup-session-manager/SKILL.md +82 -19
  120. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  121. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  122. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  123. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  124. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  125. package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
  126. package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
  127. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  128. package/plugins/lisa-copilot/commands/lisa/session-manager.md +1 -1
  129. package/plugins/lisa-copilot/commands/lisa/setup/session-manager.md +1 -1
  130. package/plugins/lisa-copilot/rules/reference/config-resolution.md +39 -7
  131. package/plugins/lisa-copilot/skills/lisa-secrets-access/SKILL.md +5 -3
  132. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  133. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
  134. package/plugins/lisa-copilot/skills/lisa-session-manager/SKILL.md +197 -54
  135. package/plugins/lisa-copilot/skills/lisa-session-manager/references/runbook-template.md +23 -10
  136. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  137. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  138. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  139. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  140. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  141. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  142. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  143. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  144. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  145. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/config.mjs +39 -11
  146. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  147. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  148. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  149. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  150. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  151. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  152. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  153. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  154. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  155. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  156. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  157. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  158. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  159. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token.mjs +39 -120
  160. package/plugins/lisa-copilot/skills/lisa-setup-session-manager/SKILL.md +82 -19
  161. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  162. package/plugins/lisa-cursor/commands/lisa/session-manager.md +1 -1
  163. package/plugins/lisa-cursor/commands/lisa/setup/session-manager.md +1 -1
  164. package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +39 -7
  165. package/plugins/lisa-cursor/skills/lisa-secrets-access/SKILL.md +5 -3
  166. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  167. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
  168. package/plugins/lisa-cursor/skills/lisa-session-manager/SKILL.md +197 -54
  169. package/plugins/lisa-cursor/skills/lisa-session-manager/references/runbook-template.md +23 -10
  170. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  171. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  172. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  173. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  174. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  175. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  176. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  177. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  178. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  179. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/config.mjs +39 -11
  180. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  181. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  182. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  183. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  184. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  185. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  186. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  187. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  188. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  189. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  190. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  191. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  192. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  193. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token.mjs +39 -120
  194. package/plugins/lisa-cursor/skills/lisa-setup-session-manager/SKILL.md +82 -19
  195. package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
  196. package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
  197. package/plugins/lisa-devin/rules/reference/config-resolution.md +39 -7
  198. package/plugins/lisa-devin/skills/lisa-secrets-access/SKILL.md +5 -3
  199. package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  200. package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
  201. package/plugins/lisa-devin/skills/lisa-session-manager/SKILL.md +197 -54
  202. package/plugins/lisa-devin/skills/lisa-session-manager/references/runbook-template.md +23 -10
  203. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  204. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  205. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  206. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  207. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  208. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  209. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  210. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  211. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  212. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/config.mjs +39 -11
  213. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  214. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  215. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  216. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  217. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  218. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  219. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  220. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  221. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  222. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  223. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  224. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  225. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  226. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token.mjs +39 -120
  227. package/plugins/lisa-devin/skills/lisa-setup-session-manager/SKILL.md +82 -19
  228. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  229. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  230. package/plugins/lisa-expo-agy/plugin.json +1 -1
  231. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  232. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  233. package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
  234. package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
  235. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  236. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  237. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  238. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  239. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  240. package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
  241. package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
  242. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  243. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  244. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  245. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  246. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  247. package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
  248. package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
  249. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  250. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  251. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  252. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  253. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  254. package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
  255. package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
  256. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  257. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  258. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  259. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  260. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  261. package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
  262. package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
  263. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  264. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  265. package/plugins/lisa-rails-agy/plugin.json +1 -1
  266. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  267. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  268. package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
  269. package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
  270. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  271. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  272. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  273. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  274. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  275. package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
  276. package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
  277. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  278. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  279. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  280. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  281. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  282. package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
  283. package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
  284. package/plugins/src/base/commands/session-manager.md +1 -1
  285. package/plugins/src/base/commands/setup/session-manager.md +1 -1
  286. package/plugins/src/base/rules/reference/config-resolution.md +39 -7
  287. package/plugins/src/base/skills/lisa-secrets-access/SKILL.md +5 -3
  288. package/plugins/src/base/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
  289. package/plugins/src/base/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
  290. package/plugins/src/base/skills/lisa-session-manager/SKILL.md +197 -54
  291. package/plugins/src/base/skills/lisa-session-manager/references/runbook-template.md +23 -10
  292. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
  293. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
  294. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
  295. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
  296. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
  297. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
  298. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
  299. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
  300. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
  301. package/plugins/src/base/skills/lisa-session-manager/scripts/config.mjs +39 -11
  302. package/plugins/src/base/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
  303. package/plugins/src/base/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
  304. package/plugins/src/base/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
  305. package/plugins/src/base/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
  306. package/plugins/src/base/skills/lisa-session-manager/scripts/launch.mjs +69 -60
  307. package/plugins/src/base/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
  308. package/plugins/src/base/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
  309. package/plugins/src/base/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
  310. package/plugins/src/base/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
  311. package/plugins/src/base/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
  312. package/plugins/src/base/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
  313. package/plugins/src/base/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
  314. package/plugins/src/base/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
  315. package/plugins/src/base/skills/lisa-session-manager/scripts/token.mjs +39 -120
  316. package/plugins/src/base/skills/lisa-setup-session-manager/SKILL.md +82 -19
  317. package/rails/copy-overwrite/scripts/lisa-rspec-shards.mjs +747 -0
  318. package/rails/copy-overwrite/scripts/lisa_rspec_shard_recorder.rb +143 -0
  319. package/rails/copy-overwrite/scripts/lisa_simplecov_collate.rb +51 -0
  320. package/rails/create-only/.github/workflows/ci.yml +4 -0
  321. package/scripts/two-channel-couplings.json +89 -7
  322. package/typescript/copy-overwrite/.prettierignore +1 -0
@@ -13,159 +13,33 @@
13
13
  * With `sessionManager.backlogPickup` on, `queue` also ranks the backlog tier
14
14
  * (open leaves in no lifecycle role) as `backlogOrdered`, under the same
15
15
  * paging rule. The manager walks it only after the whole Ready queue.
16
+ *
17
+ * The GitHub fetches live in queue-github.mjs and JSON input in
18
+ * json-input.mjs (re-exported here), to keep each module under the line
19
+ * budget.
16
20
  * @module session-manager/cli-queue
17
21
  */
18
- import { readFileSync } from "node:fs";
19
-
20
22
  import {
21
23
  assertPagedToCompletion,
22
- normalizeGithubIssue,
23
24
  normalizeJiraIssue,
24
25
  normalizeLinearIssue,
25
26
  orderBacklogQueue,
26
27
  orderReadyQueue,
27
28
  } from "../../../scripts/ready-queue-order.mjs";
28
- import { resolveRole } from "../../../scripts/resolve-lifecycle-role.mjs";
29
29
  import {
30
30
  CliError,
31
31
  asSetupError,
32
32
  humanNeededLabel,
33
33
  loadProject,
34
- mustRun,
35
34
  validOrAbsent,
36
35
  } from "./cli-runtime.mjs";
36
+ import { readJsonFile } from "./json-input.mjs";
37
37
  import { readLedger } from "./ledger.mjs";
38
- import { scrubWorkerEnv } from "./workers.mjs";
39
-
40
- const NORMALIZERS = { jira: normalizeJiraIssue, linear: normalizeLinearIssue };
38
+ import { fetchGithubBacklog, fetchGithubQueue } from "./queue-github.mjs";
41
39
 
42
- const OWNER_REPO = /^[\w.-]+\/[\w.-]+$/;
40
+ export { parseJson, readJsonFile } from "./json-input.mjs";
43
41
 
44
- /**
45
- * Parse JSON, or exit 2 naming the source.
46
- * @param {string} text - JSON text
47
- * @param {string} source - Where it came from
48
- * @returns {any} Parsed value
49
- */
50
- export function parseJson(text, source) {
51
- try {
52
- return JSON.parse(text);
53
- } catch (error) {
54
- throw new CliError(`${source} is not valid JSON: ${error.message}`, 2);
55
- }
56
- }
57
-
58
- /**
59
- * Read a JSON file named by a flag, or exit 2.
60
- * @param {string} file - Path
61
- * @returns {any} Parsed value
62
- */
63
- export function readJsonFile(file) {
64
- const text = asSetupError(() => readFileSync(file, "utf8"));
65
- return parseJson(text, file);
66
- }
67
-
68
- /**
69
- * The GitHub repo to read: `--github-repo`, else github.org/github.repo.
70
- * @param {object} ctx - CLI context
71
- * @param {ReturnType<typeof loadProject>} project - Loaded project
72
- * @returns {string} `owner/repo`
73
- */
74
- function githubRepo(ctx, project) {
75
- const merged = { ...project.global?.github, ...project.local?.github };
76
- const repo =
77
- ctx.values["github-repo"] ??
78
- (merged.org && merged.repo ? `${merged.org}/${merged.repo}` : "");
79
- if (!OWNER_REPO.test(repo)) {
80
- throw new CliError(
81
- "No GitHub repo: set github.org and github.repo, or pass --github-repo <owner/repo>.",
82
- 2
83
- );
84
- }
85
- return repo;
86
- }
87
-
88
- /**
89
- * Every string leaf of an object (label names, including env-keyed `done`).
90
- * @param {unknown} value - Config subtree
91
- * @returns {string[]} Leaves
92
- */
93
- function stringLeaves(value) {
94
- if (typeof value === "string") return value ? [value] : [];
95
- if (!value || typeof value !== "object") return [];
96
- return Object.values(value).flatMap(stringLeaves);
97
- }
98
-
99
- /**
100
- * Fetch every open GitHub issue carrying no lifecycle label (build or PRD),
101
- * all pages: the GitHub backlog tier.
102
- * @param {object} ctx - CLI context
103
- * @param {ReturnType<typeof loadProject>} project - Loaded project
104
- * @returns {{ items: object[], pages: number }} Normalized items
105
- */
106
- function fetchGithubBacklog(ctx, project) {
107
- const repo = githubRepo(ctx, project);
108
- const lifecycle = new Set(
109
- [project.global?.github?.labels, project.local?.github?.labels]
110
- .flatMap(labels => [
111
- ...stringLeaves(labels?.build),
112
- ...stringLeaves(labels?.prd),
113
- ])
114
- .map(label => label.toLowerCase())
115
- );
116
- const stdout = mustRun(
117
- "gh",
118
- [
119
- "api",
120
- "--paginate",
121
- "--slurp",
122
- `repos/${repo}/issues?state=open&per_page=100`,
123
- ],
124
- { env: scrubWorkerEnv(ctx.env) }
125
- );
126
- const pages = parseJson(stdout, "gh api output");
127
- const rows = Array.isArray(pages) ? pages.flat() : [];
128
- return {
129
- items: rows
130
- .map(row => normalizeGithubIssue(row, { repo }))
131
- .filter(Boolean)
132
- .filter(
133
- item => !item.labels.some(label => lifecycle.has(label.toLowerCase()))
134
- ),
135
- pages: Array.isArray(pages) ? pages.length : 0,
136
- };
137
- }
138
-
139
- /**
140
- * Fetch every open GitHub issue carrying the ready label, all pages.
141
- * @param {object} ctx - CLI context
142
- * @param {ReturnType<typeof loadProject>} project - Loaded project
143
- * @returns {{ items: object[], pages: number }} Normalized items
144
- */
145
- function fetchGithubQueue(ctx, project) {
146
- const repo = githubRepo(ctx, project);
147
- const role = resolveRole({
148
- role: "ready",
149
- vendor: "github",
150
- intent: "read",
151
- local: project.local,
152
- global: project.global,
153
- });
154
- const label = ctx.values.label ?? role.value;
155
- if (!label) throw new CliError(role.message, 2);
156
- const endpoint =
157
- `repos/${repo}/issues?state=open&labels=${encodeURIComponent(label)}` +
158
- `&per_page=100`;
159
- const stdout = mustRun("gh", ["api", "--paginate", "--slurp", endpoint], {
160
- env: scrubWorkerEnv(ctx.env),
161
- });
162
- const pages = parseJson(stdout, "gh api output");
163
- const rows = Array.isArray(pages) ? pages.flat() : [];
164
- return {
165
- items: rows.map(row => normalizeGithubIssue(row, { repo })).filter(Boolean),
166
- pages: Array.isArray(pages) ? pages.length : 0,
167
- };
168
- }
42
+ const NORMALIZERS = { jira: normalizeJiraIssue, linear: normalizeLinearIssue };
169
43
 
170
44
  /**
171
45
  * Check one paged envelope and normalize its raw issues.
@@ -216,6 +90,40 @@ function readEnvelopeQueue(ctx, tracker, withBacklog) {
216
90
  };
217
91
  }
218
92
 
93
+ /**
94
+ * Refs waiting on a human: every ledger item with a pending question.
95
+ * @param {{items: Record<string, {pendingQuestion?: unknown}>}} ledger - Ledger
96
+ * @returns {Set<string>} Refs
97
+ */
98
+ function pendingRefs(ledger) {
99
+ return new Set(
100
+ Object.entries(ledger.items)
101
+ .filter(([, item]) => item.pendingQuestion)
102
+ .map(([ref]) => ref)
103
+ );
104
+ }
105
+
106
+ /**
107
+ * Move items waiting on a human out of `ordered` into `excluded` with reason
108
+ * `pending-question` (#4555). The item stays marked for its human; every
109
+ * other item is still dispatched, so one question never stalls the queue.
110
+ * @param {{ordered: {ref: string}[], excluded: {ref: string, reason: string}[]}} order - Ordered tier
111
+ * @param {Set<string>} waiting - Refs with a pending question
112
+ * @returns {{ordered: {ref: string}[], excluded: {ref: string, reason: string}[]}} Filtered tier
113
+ */
114
+ function withoutPending(order, waiting) {
115
+ return {
116
+ ...order,
117
+ ordered: order.ordered.filter(item => !waiting.has(item.ref)),
118
+ excluded: [
119
+ ...order.excluded,
120
+ ...order.ordered
121
+ .filter(item => waiting.has(item.ref))
122
+ .map(item => ({ ref: item.ref, reason: "pending-question" })),
123
+ ],
124
+ };
125
+ }
126
+
219
127
  /**
220
128
  * `queue --tracker <github|jira|linear>`: the Ready queue, the operator's
221
129
  * items first (`sessionManager.operatorIds`), then mine, then unassigned.
@@ -251,7 +159,8 @@ export async function queue(ctx) {
251
159
  trustedAuthorIds: config?.trustedAuthorIds ?? undefined,
252
160
  humanNeededLabel: humanNeededLabel(project, tracker),
253
161
  };
254
- const order = orderReadyQueue(items, policy);
162
+ const waiting = pendingRefs(ledger);
163
+ const order = withoutPending(orderReadyQueue(items, policy), waiting);
255
164
  const json = {
256
165
  tracker,
257
166
  me,
@@ -265,10 +174,13 @@ export async function queue(ctx) {
265
174
  // An item both Ready and in the backlog fetch is Ready work; never twice.
266
175
  const readyRefs = new Set(items.map(item => item.ref));
267
176
  const backlogItems = backlog.items.filter(item => !readyRefs.has(item.ref));
268
- const tier = orderBacklogQueue(backlogItems, {
269
- ...policy,
270
- validationFailures: ledger.validationFailures,
271
- });
177
+ const tier = withoutPending(
178
+ orderBacklogQueue(backlogItems, {
179
+ ...policy,
180
+ validationFailures: ledger.validationFailures,
181
+ }),
182
+ waiting
183
+ );
272
184
  return {
273
185
  json: {
274
186
  ...json,
@@ -227,15 +227,17 @@ export function requireLisaRepo(dir) {
227
227
  * Run a command with an argv array and no shell.
228
228
  * @param {string} command - Executable, looked up on PATH
229
229
  * @param {readonly string[]} args - argv
230
- * @param {{ env: Record<string, string | undefined>, cwd?: string }} options
231
- * - Environment and working directory
230
+ * @param {{ env: Record<string, string | undefined>, cwd?: string,
231
+ * input?: string }} options - Environment, working directory and stdin
232
+ * (for text that must stay out of argv)
232
233
  * @returns {{ status: number | null, stdout: string, stderr: string,
233
234
  * missing: boolean }} Outcome; `missing` when the command is not on PATH
234
235
  */
235
- export function run(command, args, { env, cwd }) {
236
+ export function run(command, args, { env, cwd, input }) {
236
237
  const result = spawnSync(command, args, {
237
238
  cwd,
238
239
  env,
240
+ ...(input === undefined ? {} : { input }),
239
241
  encoding: "utf8",
240
242
  maxBuffer: MAX_BUFFER,
241
243
  });
@@ -21,25 +21,36 @@ import {
21
21
  buildDefaultBlock,
22
22
  detectRepoLayout,
23
23
  draftHints,
24
+ notifyProvider,
24
25
  resolveRepoDir,
25
26
  } from "./config.mjs";
26
27
  import { defaultProjectSlug } from "./isolation.mjs";
27
28
  import {
29
+ readTokenFromClipboard,
30
+ readTokenFromPrompt,
31
+ resolveStateDir,
28
32
  storeToken as storeTokenFile,
29
33
  storeTokenFromClipboard,
30
34
  } from "./launch.mjs";
35
+ import {
36
+ loadTokenSecrets,
37
+ storeTokenInProvider,
38
+ telegramSecretName,
39
+ } from "./token-store.mjs";
31
40
  import {
32
41
  coexistence as readCoexistence,
33
42
  trustStatus as readTrust,
34
43
  } from "./setup-checks.mjs";
35
44
 
36
45
  /**
37
- * `init-config [--slug <slug>] [--write]`: the default block for this
38
- * project, written to `.lisa.config.json` only with `--write` and only when
39
- * no block exists. Non-secret fields only; the token never goes here. Repos
40
- * are the routable children `detectRepoLayout` finds under `projects/`, else
41
- * directly under the root (linked worktrees and second clones of one remote
42
- * left out), each with drafted hints.
46
+ * `init-config [--slug <slug>] [--notify none|telegram] [--write]`: the
47
+ * default block for this project, written to `.lisa.config.json` only with
48
+ * `--write` and only when no block exists. Non-secret fields only; the token
49
+ * never goes here. Repos are the routable children `detectRepoLayout` finds
50
+ * under `projects/`, else directly under the root (linked worktrees and second
51
+ * clones of one remote left out), each with drafted hints. `--notify` defaults
52
+ * to `none` (no notification channel, so no state dir); `telegram` adds the
53
+ * per-project state dir. Anything else exits 2.
43
54
  * @param {object} ctx - CLI context
44
55
  * @returns {{ json: object }} `{written,block,...}`
45
56
  */
@@ -60,7 +71,13 @@ export function initConfig(ctx) {
60
71
  ])
61
72
  );
62
73
  const block = asSetupError(() =>
63
- buildDefaultBlock({ projectSlug: slug, detectedRepos, hints, reposRoot })
74
+ buildDefaultBlock({
75
+ projectSlug: slug,
76
+ detectedRepos,
77
+ hints,
78
+ reposRoot,
79
+ notify: ctx.values.notify ?? "none",
80
+ })
64
81
  );
65
82
  if (!ctx.values.write) return { json: { written: false, block } };
66
83
 
@@ -80,16 +97,33 @@ export function initConfig(ctx) {
80
97
  }
81
98
 
82
99
  /**
83
- * `store-token [--replace] [--from-clipboard]`: store the bot token in the
84
- * project's state dir. By default it prompts on the operator's terminal (echo
85
- * off); with no TTY it prints the two commands that work instead and exits 0
86
- * with `stored:false`. `--from-clipboard` reads the system clipboard and needs
87
- * no TTY. An existing token is kept (exit 2) unless `--replace` is given.
100
+ * `store-token [--replace] [--from-clipboard] [--vault-project <id>]`: store
101
+ * the bot token. With a secrets provider configured (`secrets.provider` set
102
+ * and not `env`) it goes into the provider as `TELEGRAM_BOT_TOKEN_<NAME>`
103
+ * and nothing is written to disk: a plaintext `<stateDir>/.env` left by an
104
+ * older setup is migrated (stored, read back and compared, then deleted), and
105
+ * an already-stored token is kept (exit 0) unless `--replace` is given
106
+ * (#4555). With no provider it is written to `<stateDir>/.env` as before,
107
+ * and an existing file is kept (exit 2) unless `--replace`.
108
+ *
109
+ * Either way the token is read from the operator's terminal (echo off) or,
110
+ * with `--from-clipboard`, from the system clipboard; with no TTY it prints
111
+ * the two commands that work instead and exits 0 with `stored:false`. The
112
+ * token is never printed.
88
113
  * @param {object} ctx - CLI context
89
114
  * @returns {Promise<{ json: object, exitCode: number }>} Outcome
90
115
  */
91
116
  export async function storeToken(ctx) {
92
117
  const config = requireConfig(ctx);
118
+ if (notifyProvider(config) !== "telegram") {
119
+ throw new CliError(
120
+ `sessionManager.notify.provider is "none", so there is no bot token ` +
121
+ `to store. To use Telegram, set notify to {"provider":"telegram",` +
122
+ `"stateDir":"~/.claude/channels/telegram-<project>"} and run ` +
123
+ `store-token again.`,
124
+ EXIT.SETUP
125
+ );
126
+ }
93
127
  const input = {
94
128
  stateDir: config.notify?.stateDir,
95
129
  scriptsDir: ctx.scriptsDir,
@@ -98,11 +132,57 @@ export async function storeToken(ctx) {
98
132
  env: ctx.env,
99
133
  homedir: ctx.homedir,
100
134
  };
135
+ const secrets = await asSetupErrorAsync(() =>
136
+ loadTokenSecrets(ctx.root, ctx.env)
137
+ );
138
+ const result =
139
+ secrets === null
140
+ ? await storeInFile(ctx, input)
141
+ : await asSetupErrorAsync(() =>
142
+ storeInProvider(ctx, input, { ...secrets, name: config.name })
143
+ );
144
+ const refused = result.stored === false && result.reason !== "no-tty";
145
+ return { json: result, exitCode: refused ? EXIT.SETUP : EXIT.OK };
146
+ }
147
+
148
+ /**
149
+ * The no-provider path: `<stateDir>/.env`, as before #4555.
150
+ * @param {object} ctx - CLI context
151
+ * @param {object} input - Store input
152
+ * @returns {Promise<object>} Outcome, with `storage:"file"` once stored
153
+ */
154
+ async function storeInFile(ctx, input) {
101
155
  const result = ctx.values["from-clipboard"]
102
156
  ? asSetupError(() => storeTokenFromClipboard(input))
103
157
  : await asSetupErrorAsync(() => storeTokenFile(input));
104
- const refused = result.stored === false && result.reason !== "no-tty";
105
- return { json: result, exitCode: refused ? EXIT.SETUP : EXIT.OK };
158
+ return result.stored ? { ...result, storage: "file" } : result;
159
+ }
160
+
161
+ /**
162
+ * The provider path: see {@link storeTokenInProvider}. The token reader
163
+ * (prompt or clipboard) runs only when there is no plaintext file to migrate
164
+ * and no stored token to keep.
165
+ * @param {object} ctx - CLI context
166
+ * @param {object} input - Store input
167
+ * @param {{ cfg: object, adapter: object, name: string }} secrets - Provider
168
+ * config, adapter and the manager name
169
+ * @returns {Promise<object>} Outcome
170
+ */
171
+ function storeInProvider(ctx, input, { cfg, adapter, name }) {
172
+ const secret = telegramSecretName(name);
173
+ const vaultProject = ctx.values["vault-project"];
174
+ return storeTokenInProvider({
175
+ cfg,
176
+ adapter,
177
+ name: secret,
178
+ stateDir: resolveStateDir(input.stateDir, input),
179
+ replace: input.replace,
180
+ vaultProject,
181
+ readToken: () =>
182
+ ctx.values["from-clipboard"]
183
+ ? readTokenFromClipboard()
184
+ : readTokenFromPrompt({ ...input, label: secret, vaultProject }),
185
+ });
106
186
  }
107
187
 
108
188
  /**
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The `status` subcommand of the session-manager CLI, split out of
3
+ * cli-manager.mjs to keep it under the line budget (#4555): is the manager's
4
+ * tmux session up, which notification provider is configured, what the
5
+ * ledger says about each worker, and which items wait on a human.
6
+ * cli-manager.mjs re-exports {@link status}, so callers keep one import.
7
+ * @module session-manager/cli-status
8
+ */
9
+ import path from "node:path";
10
+
11
+ import { listAgents, requireConfig, run } from "./cli-runtime.mjs";
12
+ import { notifyProvider } from "./config.mjs";
13
+ import { buildHasSession } from "./launch.mjs";
14
+ import { listPendingQuestions } from "./ledger-questions.mjs";
15
+ import { readLedger } from "./ledger.mjs";
16
+ import { shellQuote } from "./token.mjs";
17
+ import { parseWorkerName } from "./workers.mjs";
18
+
19
+ /**
20
+ * The line an operator at this machine runs to answer a pending question:
21
+ * the answer goes on stdin, never in argv. Every word is single-quoted for
22
+ * the shell, so a path or ref holding `$(…)` or a backtick runs nothing.
23
+ * @param {{scriptsDir: string, root: string}} ctx - CLI context
24
+ * @param {string} ref - Item ref
25
+ * @returns {string} Command line
26
+ */
27
+ function answerCommandFor(ctx, ref) {
28
+ const script = path.join(ctx.scriptsDir, "session-manager.mjs");
29
+ return `node ${shellQuote(script)} answer ${shellQuote(ref)} --project-root ${shellQuote(ctx.root)} < answer.txt`;
30
+ }
31
+
32
+ /**
33
+ * `status`: is the manager's tmux session up, and what does the ledger say
34
+ * about each worker it dispatched.
35
+ * @param {object} ctx - CLI context
36
+ * `notify` is the configured notification provider (`telegram` or `none`),
37
+ * so the manager knows each cycle whether a channel exists.
38
+ * @returns {Promise<{ json: object }>}
39
+ * `{manager,notify,control,workers,untracked,pendingQuestions}`
40
+ */
41
+ export async function status(ctx) {
42
+ const config = requireConfig(ctx);
43
+ const tmux = run("tmux", buildHasSession(config.name), { env: ctx.env });
44
+ const agents = listAgents(ctx, { all: true });
45
+ const ledger = await readLedger(ctx.root);
46
+ const liveNames = new Set(
47
+ agents.filter(agent => agent.active).map(agent => agent.name)
48
+ );
49
+ const tracked = new Set(Object.values(ledger.items).map(i => i.worker));
50
+ return {
51
+ json: {
52
+ manager: { name: config.name, running: tmux.status === 0 },
53
+ notify: notifyProvider(config),
54
+ control: ledger.control,
55
+ workers: Object.entries(ledger.items).map(([ref, item]) => ({
56
+ ref,
57
+ worker: item.worker ?? null,
58
+ sessionId: item.sessionId ?? null,
59
+ repo: item.repo ?? null,
60
+ status: item.status ?? null,
61
+ attempts: item.attempts ?? 0,
62
+ pendingQuestion: Boolean(item.pendingQuestion),
63
+ live: liveNames.has(item.worker),
64
+ })),
65
+ untracked: [...liveNames]
66
+ .filter(name => parseWorkerName(name) !== null && !tracked.has(name))
67
+ .sort(),
68
+ pendingQuestions: listPendingQuestions(ledger, ref =>
69
+ answerCommandFor(ctx, ref)
70
+ ),
71
+ },
72
+ };
73
+ }
@@ -44,12 +44,29 @@ Workers and capacity
44
44
  pendingQuestion}], classification one of finished|waiting|requestion|
45
45
  working|stalled|dead|exhausted.
46
46
  status
47
- stdout {manager:{name,running},control,workers:[{ref,worker,sessionId,
48
- repo,status,attempts,pendingQuestion,live}],untracked:[wk- names]}.
47
+ stdout {manager:{name,running},notify,control,workers:[{ref,worker,
48
+ sessionId,repo,status,attempts,pendingQuestion,live}],untracked:[wk-
49
+ names],pendingQuestions:[{ref,kind,text,askedAt,marked,answerQueued,
50
+ answerCommand}]}. notify is the configured channel: "telegram" or
51
+ "none". pendingQuestions lists every item waiting on a human, oldest
52
+ first; answerCommand is the answer line to run at this machine.
49
53
 
50
54
  Manager
51
55
  start [--settle-ms <n>]
52
- Refuses (exit 2) without <notify.stateDir>/.env (mode 0600) or for
56
+ With notify.provider "none" (or no notify block): no token, state
57
+ dir or Telegram plugin is needed; launches with no --channels, no
58
+ TELEGRAM_STATE_DIR and no plugin in --settings. With "telegram"
59
+ and a secrets provider (secrets.provider set, not "env"): reads
60
+ TELEGRAM_BOT_TOKEN_<NAME> from the provider once, before any tmux
61
+ call, and passes it to tmux on stdin (tmux start-server ;
62
+ source-file -), never in argv; tmux's stderr is never shown.
63
+ Exit 2 when a plaintext <notify.stateDir>/.env is left over (the
64
+ message names the store-token command that migrates it), when
65
+ the secret is missing, or when secrets.require does not list it.
66
+ Exit 1, "Nothing was started", when the provider cannot be
67
+ reached, is rate-limited or times out: wait a minute and run
68
+ start again. With "telegram" and no provider: refuses (exit 2)
69
+ without <notify.stateDir>/.env (mode 0600). Either way exit 2 for
53
70
  the shared default state dir. "already-running" when the tmux
54
71
  session =<name> exists and was started in this project root;
55
72
  exit 2 naming the conflict when it was started anywhere else.
@@ -57,21 +74,38 @@ Manager
57
74
  has-session -t =<name> every 250 ms for --settle-ms (default
58
75
  3000, at most 60000): exit 2, with the foreground command to run
59
76
  to see claude's error, when the session is gone.
60
- stdout {status:"started"|"already-running",name,...}.
77
+ stdout {status:"started"|"already-running",name,notify,
78
+ [stateDir,tokenSource:"provider"|"file",secret,]attach}.
61
79
  stop tmux kill-session -t =<name> only, and only for a session started
62
80
  in this root (exit 2 otherwise); workers keep running.
63
81
  stdout {status:"stopped"|"not-running",name}.
64
- store-token [--replace] [--from-clipboard]
65
- Prompts for the bot token on the terminal (echo off) and writes
66
- <stateDir>/.env. Exit 2 when a token is already there, unless
67
- --replace. With no TTY (an agent's Bash, and Claude Code's !
82
+ store-token [--replace] [--from-clipboard] [--vault-project <id>]
83
+ Telegram only: exit 2 when notify.provider is "none".
84
+ With a secrets provider: stores the token in it as
85
+ TELEGRAM_BOT_TOKEN_<NAME> and writes nothing to disk. A
86
+ plaintext <stateDir>/.env is migrated: stored, read back and
87
+ compared, then deleted (refused, exit 2, when the file holds
88
+ other keys or a different token than the stored one). An
89
+ already-stored token is kept (exit 0, alreadyStored:true) unless
90
+ --replace. --vault-project picks the provider project for a new
91
+ secret (default: the one in secrets.narrow.projectIds, else the
92
+ one every visible secret is in). stdout {stored:true,
93
+ storage:"provider",provider,secret,verified,[migratedFrom,
94
+ deleted]}. Provider unreachable or rate-limited: exit 1, nothing
95
+ stored, the file kept.
96
+ With no provider: prompts for the bot token on the terminal (echo
97
+ off) and writes <stateDir>/.env. Exit 2 when a token is already
98
+ there, unless --replace.
99
+ Either way, with no TTY (an agent's Bash, and Claude Code's !
68
100
  prefix too): exit 0, stdout {stored:false,reason:"no-tty",
69
101
  message,command,clipboardCommand}; command is the line the
70
102
  operator runs in a separate terminal app.
71
103
  --from-clipboard reads the token from the clipboard instead
72
104
  (pbpaste; wl-paste, xclip or xsel on Linux), needs no TTY, and
73
105
  clears the clipboard after a successful store. stdout
74
- {stored:true,path,clipboardCleared}. The token is never printed.
106
+ {stored:true,storage:"file",path,clipboardCleared} (with a
107
+ provider, the provider shape plus clipboardCleared). The token
108
+ is never printed.
75
109
  Bad input, empty clipboard or no clipboard tool: exit 2,
76
110
  {stored:false,reason,message}.
77
111
 
@@ -80,8 +114,12 @@ Config and routing
80
114
  stdout {repo,dir}; --raw prints the bare dir. Exit 2 for an
81
115
  unknown key or a dir without .lisa.config.json.
82
116
  validate stdout {valid,errors}; exit 2 when invalid or absent.
83
- init-config [--slug <slug>] [--write]
84
- stdout {written,block[,reason:"exists"][,path]}. Detects
117
+ init-config [--slug <slug>] [--notify none|telegram] [--write]
118
+ stdout {written,block[,reason:"exists"][,path]}. --notify picks
119
+ the notification channel (default none): none writes
120
+ notify {provider:"none"} and no state dir; telegram writes
121
+ {provider:"telegram",stateDir:"~/.claude/channels/telegram-<slug>"}.
122
+ Any other value: exit 2. Detects
85
123
  projects/*/.lisa.config.json, else root children with their own
86
124
  .lisa.config.json and .git (repos.root "."), skipping linked
87
125
  worktrees (.git is a file) and keeping one child per origin
@@ -113,7 +151,9 @@ Per cycle
113
151
  <file> = {complete:true,pages,items:[raw vendor issues]}; exit 2 unless
114
152
  complete is exactly true.
115
153
  Both print {tracker,me,operators,total,pages,ordered,excluded:[{ref,
116
- reason}]}. ordered: items assigned to sessionManager.operatorIds
154
+ reason}]}. An item with a pending question in the ledger is excluded
155
+ (pending-question) from both tiers, and every other item still comes
156
+ back, so one item waiting on a human never stops dispatch. ordered: items assigned to sessionManager.operatorIds
117
157
  first, then to --me, then unassigned; each group by priority, then age.
118
158
  Items assigned to anyone else are excluded (assigned-to-other).
119
159
  --me defaults to the ledger's control.me.
@@ -126,9 +166,23 @@ Per cycle
126
166
  {complete:true,pages,items}, else exit 2.
127
167
  ledger get [<ref>]
128
168
  ledger record-spawn <ref> --worker <name> [--session-id <id>] [--repo <key>]
129
- ledger set-question <ref> [--telegram-message-id <n>] [--sender <name>]
130
- STDIN: question
131
- ledger clear-question <ref>
169
+ ledger set-question <ref> [--kind <kind>] [--telegram-message-id <n>]
170
+ [--sender <name>] STDIN: question
171
+ --kind: worker-question (default) | repo-route | exhausted | decision.
172
+ No message id with no channel. A re-ask keeps the item's marker
173
+ fields (markerType, marker, markedAt); a queued answer survives only a
174
+ re-ping of the same text.
175
+ ledger marked <ref> --marker-type label|role --marker <value>
176
+ --comment-id <id>
177
+ Records that the human-needed marker was applied on the tracker and
178
+ read back (markedAt). --comment-id (required): the id of the question
179
+ comment the manager posted; item-answer anchors on it to find the
180
+ answer after it, and never reads it as an answer. Exit 2 when it is
181
+ missing or not a tracker comment id, or <ref> has no pending
182
+ question.
183
+ ledger clear-question <ref> [--reset-attempts]
184
+ After the answer is delivered and the marker removed. --reset-attempts
185
+ zeroes the attempt count (an exhausted item a human has answered).
132
186
  ledger finish <ref> --status DONE|FAILED [--sender <name>] STDIN: reason
133
187
  --sender: exit 2 unless the ledger's worker for <ref> is exactly <name>.
134
188
  ledger validation-failed <ref> --updated-at <ts> STDIN: failing gates
@@ -148,6 +202,42 @@ Per cycle
148
202
  unset); trustedHumanActorIds in the input is ignored. stdout
149
203
  {action:release|keep|escalate|skip-human-gate,reason,edges,gate}.
150
204
  --ref fills pendingQuestion from the ledger.
205
+ mark-plan <ref> --kind <kind> STDIN: question or reason
206
+ Plans marking an item that needs a human; writes nothing. kind:
207
+ worker-question | repo-route | exhausted | decision. stdout {ref,kind,
208
+ marker:{type:"label"|"role",value},[move:{role:"blocked",value},]
209
+ comment,answerWith:{item,cli,channel}}. marker is the tracker's
210
+ configured human-needed label, else the configured blocked role;
211
+ exhausted also moves to the blocked role. comment starts with
212
+ [lisa-session-manager-question] and says, in plain words, how to
213
+ answer: on the item (only when operatorIds or trustedAuthorIds is set;
214
+ answerWith.item is null otherwise), with the answerCommand that status
215
+ lists, or on Telegram when it is the channel. Exit 2 for an unknown
216
+ kind, empty or credential-shaped text, no marker configured, or
217
+ exhausted with no blocked role.
218
+ answer <ref> STDIN: the answer
219
+ Queues an operator's answer (source "cli") for the next cycle to
220
+ deliver. stdout {queued:true,ref,source}. Exit 2 when <ref> has no
221
+ pending question, or the text looks like a credential.
222
+ item-answer <ref> STDIN: {"comments":[{user|author,body,createdAt}]}
223
+ Queues the human's answer from the item's comments (source "item"):
224
+ the first comment after the latest [lisa-session-manager-question]
225
+ comment whose author's STABLE id (GitHub login or numeric id, Jira
226
+ accountId, Linear user id; never a name, displayName or email) is in
227
+ sessionManager.operatorIds or trustedAuthorIds, and that is not a
228
+ machine comment, checked first (body starting with a bracketed tag
229
+ such as [lisa-...] or [claude-sync]; [lisa- or <!-- lisa: anywhere;
230
+ "Written by Claude"; the agent "Generated with Claude Code" footer;
231
+ or an id in the ledger's managerCommentIds, so keep each comment's
232
+ id). For GitHub, pipe the rows of
233
+ gh api --paginate repos/<o>/<r>/issues/<n>/comments (user.login,
234
+ user.id). stdout {queued:true,ref,source,author} or {queued:false,ref,
235
+ reason:no-question-comment|no-answer-yet|already-queued|
236
+ no-answerers-configured[,explanation]}. no-answerers-configured (exit
237
+ 0): neither list is set, so nothing on the item is read, because the
238
+ tracker identity is the one workers post as; answer with answer.
239
+ Exit 2 when <ref> has no pending question, or the answer looks like a
240
+ credential.
151
241
  record-cycle --outcome <outcome> [--ref <url>]... [--run-id <id>]
152
242
  STDIN: one-line summary. Records loop session-manager with runbook
153
243
  .lisa/automations/session-manager.runbook.md. stdout {path,appended,