very-happy-cli 0.2.158 → 0.2.160

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 (258) hide show
  1. package/dist/{AcpBackend-DIDRig5G.cjs → AcpBackend-Bm2rdke8.cjs} +78 -76
  2. package/dist/{AcpBackend-vDVLHuYJ.mjs → AcpBackend-mzv8Dhba.mjs} +4 -2
  3. package/dist/{AcpSessionManager-C44U99CC.cjs → AcpSessionManager-BAY1Pggx.cjs} +9 -9
  4. package/dist/{AcpSessionManager-CmRjfhn3.mjs → AcpSessionManager-CoMWFVw3.mjs} +1 -1
  5. package/dist/BasePermissionHandler-CFHAxumV.cjs +157 -0
  6. package/dist/BasePermissionHandler-m3WVholL.mjs +155 -0
  7. package/dist/BaseReasoningProcessor-BFa9_rZA.cjs +200 -0
  8. package/dist/BaseReasoningProcessor-CYrKBXGm.mjs +198 -0
  9. package/dist/RemoteModeDisplay-D-HewyXg.mjs +150 -0
  10. package/dist/RemoteModeDisplay-NC1gPHtj.cjs +153 -0
  11. package/dist/agentAttachments-Dbw8iMCZ.cjs +20 -0
  12. package/dist/agentAttachments-M_B5qEF2.mjs +18 -0
  13. package/dist/agentGuidance-B5NATuFa.cjs +28 -0
  14. package/dist/agentGuidance-CQuNlNx8.mjs +20 -0
  15. package/dist/{agentHome-Dw8Jx_CJ.cjs → agentHome-CboCeKWq.cjs} +14 -28
  16. package/dist/{agentHome-CyLmGH5L.mjs → agentHome-Dj1C43aJ.mjs} +8 -22
  17. package/dist/api-CLMUr-SX.mjs +3339 -0
  18. package/dist/api-CgundNNX.cjs +3346 -0
  19. package/dist/{types-DIBF4U0Y.mjs → apiMachine-B9dLW_p5.mjs} +9116 -16015
  20. package/dist/{types-DnrPeN80.cjs → apiMachine-Bn8482VM.cjs} +9104 -16057
  21. package/dist/assistantTools-BTqPnlFl.cjs +380 -0
  22. package/dist/assistantTools-D6tuc6o4.mjs +376 -0
  23. package/dist/attachmentContent-DpiTJZb4.cjs +88 -0
  24. package/dist/attachmentContent-_kxRznNf.mjs +82 -0
  25. package/dist/attachmentLimits-CzVrqgLR.cjs +354 -0
  26. package/dist/attachmentLimits-yba1uHFO.mjs +348 -0
  27. package/dist/auth-BDOVh5h5.cjs +220 -0
  28. package/dist/auth-Cwutmdsa.mjs +225 -0
  29. package/dist/auth-PYHZQNPp.mjs +218 -0
  30. package/dist/auth-ba4WMYrN.cjs +227 -0
  31. package/dist/authRelay-BdYkC1Po.cjs +156 -0
  32. package/dist/authRelay-DSAvg1uv.mjs +143 -0
  33. package/dist/{auto-DZbNcTXx.cjs → auto-BOX_fgmR.cjs} +70 -79
  34. package/dist/{auto-BlMZPwOk.mjs → auto-BXu14yP_.mjs} +27 -36
  35. package/dist/backgroundTaskActivity-8PdPxrvy.mjs +149 -0
  36. package/dist/backgroundTaskActivity-CBvUdj39.cjs +157 -0
  37. package/dist/bootstrap-B5G1TijC.cjs +116 -0
  38. package/dist/bootstrap-hxXPCFMx.mjs +112 -0
  39. package/dist/browser-Y6Bl8L_O.cjs +22 -0
  40. package/dist/browser-jh2P0UVZ.mjs +20 -0
  41. package/dist/claudeCliPath-BqkaH2oR.mjs +8 -0
  42. package/dist/claudeCliPath-U4HHmV4r.cjs +10 -0
  43. package/dist/claudeLocal-BaY4fZKi.mjs +339 -0
  44. package/dist/claudeLocal-CRGG4Pea.cjs +343 -0
  45. package/dist/claudeLocalLauncher-D4T7MTqd.mjs +152 -0
  46. package/dist/claudeLocalLauncher-DyEbVzUN.cjs +154 -0
  47. package/dist/cliUpdate-DsKXPFYp.cjs +120 -0
  48. package/dist/cliUpdate-Y34VGe9Y.mjs +112 -0
  49. package/dist/client-3Ac-O4pw.cjs +104 -0
  50. package/dist/client-BPNbmtvO.cjs +119 -0
  51. package/dist/client-CeGKqqcJ.mjs +100 -0
  52. package/dist/client-ClR0K8zX.mjs +112 -0
  53. package/dist/codex/happyMcpStdioBridge.cjs +33 -14
  54. package/dist/codex/happyMcpStdioBridge.mjs +26 -7
  55. package/dist/codexAppServerClient-I3teiV-N.mjs +1088 -0
  56. package/dist/codexAppServerClient-q2FjnRcK.cjs +1090 -0
  57. package/dist/codexCommand-4zcccIoq.cjs +2088 -0
  58. package/dist/codexCommand-Cc9gcbdX.mjs +2086 -0
  59. package/dist/codexThreadFork-BH9IZPqD.cjs +350 -0
  60. package/dist/codexThreadFork-slzAseLx.mjs +338 -0
  61. package/dist/{config-BtPArqRH.mjs → config-CTx_jb-C.mjs} +7 -40
  62. package/dist/{config-DG84bjwF.cjs → config-Ci9Kpgwa.cjs} +26 -59
  63. package/dist/configuration-BSYpcPwE.cjs +181 -0
  64. package/dist/configuration-RfeNjFmd.mjs +170 -0
  65. package/dist/connect-BpOdzNbE.mjs +682 -0
  66. package/dist/connect-C2CiOUFs.cjs +684 -0
  67. package/dist/constants-BC4St0xd.mjs +11 -0
  68. package/dist/constants-VJ0N6WuG.cjs +17 -0
  69. package/dist/contentLogMetadata-BlWI0egu.mjs +51 -0
  70. package/dist/contentLogMetadata-ZSFk_NjQ.cjs +54 -0
  71. package/dist/context-DsDr6E2t.cjs +69 -0
  72. package/dist/context-H0Bcb9S_.mjs +65 -0
  73. package/dist/controlClient-BGbDcgWS.mjs +260 -0
  74. package/dist/controlClient-Bcwv3D21.cjs +279 -0
  75. package/dist/createSessionMetadata-BJxEnM-o.cjs +58 -0
  76. package/dist/createSessionMetadata-CVVkGjxV.mjs +54 -0
  77. package/dist/defaultPermissionMode-BnxJPVHT.mjs +4 -0
  78. package/dist/defaultPermissionMode-CxmTXUQR.cjs +7 -0
  79. package/dist/detectCLI-CSGMlV51.mjs +58 -0
  80. package/dist/detectCLI-DR9ZaN6B.cjs +61 -0
  81. package/dist/deterministicJson-C5CYTVpm.cjs +507 -0
  82. package/dist/deterministicJson-CzkFJWw1.mjs +502 -0
  83. package/dist/doctor-BPkYWSuq.mjs +75 -0
  84. package/dist/doctor-D2YJ-Yn2.cjs +395 -0
  85. package/dist/doctor-DOvByjbk.mjs +391 -0
  86. package/dist/doctor-u46qYYKX.cjs +79 -0
  87. package/dist/doctorReadiness-BCZGcN0a.cjs +151 -0
  88. package/dist/doctorReadiness-C208SMN9.mjs +142 -0
  89. package/dist/editPaths-BVfS_FFL.mjs +68 -0
  90. package/dist/editPaths-Bqp4OFPw.cjs +73 -0
  91. package/dist/ensureDaemonRunning-BCwNrMyv.cjs +64 -0
  92. package/dist/ensureDaemonRunning-Dqa2pOjY.mjs +61 -0
  93. package/dist/handleResumeCommand-BvXYf5El.mjs +240 -0
  94. package/dist/handleResumeCommand-C2cKchpX.cjs +245 -0
  95. package/dist/ids-B6ZC0HGt.cjs +13 -0
  96. package/dist/ids-DU6sLx4C.mjs +10 -0
  97. package/dist/index-B6UGRQ7h.mjs +102 -0
  98. package/dist/{index-DPCsWlWK.cjs → index-B6pAdvJx.cjs} +131 -91
  99. package/dist/index-Bu5Zi_a9.cjs +182 -0
  100. package/dist/index-D3kI0hDR.cjs +107 -0
  101. package/dist/index-DA7yINuk.cjs +994 -0
  102. package/dist/index-DDeHXrIX.cjs +71 -0
  103. package/dist/index-DKLU_fD0.mjs +158 -0
  104. package/dist/{index-ZChGsuB7.mjs → index-DMZqWwsP.mjs} +79 -39
  105. package/dist/index-DVkMGPyS.mjs +68 -0
  106. package/dist/index-qdS1friN.mjs +949 -0
  107. package/dist/index.cjs +5 -46
  108. package/dist/index.mjs +5 -46
  109. package/dist/{install-DarS_Wco.mjs → install-BO_W7VhL.mjs} +37 -37
  110. package/dist/install-BgoC2e_2.cjs +88 -0
  111. package/dist/install-CFY3tYtJ.mjs +86 -0
  112. package/dist/{install-wKQGgXvN.cjs → install-Cs5qAPrB.cjs} +38 -38
  113. package/dist/{installPiTools-DuZ6jZvX.cjs → installPiTools-BKnXjrVu.cjs} +2 -3
  114. package/dist/{installPiTools-Cj7yU9Fc.mjs → installPiTools-B_CdM5_2.mjs} +1 -2
  115. package/dist/{installTerminalHooks-DcQfee_O.cjs → installTerminalHooks-BQZbvxsZ.cjs} +5 -40
  116. package/dist/{installTerminalHooks-CpNbRFPz.mjs → installTerminalHooks-By7gBMEF.mjs} +3 -38
  117. package/dist/lib.cjs +28 -19
  118. package/dist/lib.d.cts +126 -2
  119. package/dist/lib.d.mts +126 -2
  120. package/dist/lib.mjs +23 -14
  121. package/dist/lidState-BeDfxxEX.cjs +305 -0
  122. package/dist/lidState-CeEt442o.mjs +297 -0
  123. package/dist/limits-C-a7gr04.cjs +43 -0
  124. package/dist/limits-DIo7rEBR.mjs +36 -0
  125. package/dist/localHappyAgentAuth-C-HQyiv6.mjs +82 -0
  126. package/dist/localHappyAgentAuth-D6rFhaoc.cjs +86 -0
  127. package/dist/logger-6HYUEXNk.mjs +271 -0
  128. package/dist/logger-CS0mw3fa.cjs +275 -0
  129. package/dist/loginShellEnv-BkuYtExZ.cjs +182 -0
  130. package/dist/loginShellEnv-Dw8M7tkI.mjs +167 -0
  131. package/dist/machineMetadata-DyDbODYd.cjs +41 -0
  132. package/dist/machineMetadata-oOzBfDfs.mjs +38 -0
  133. package/dist/main-BkxJP6JQ.cjs +941 -0
  134. package/dist/main-BwNIAI1A.mjs +939 -0
  135. package/dist/manager-BQ4flvQZ.mjs +101 -0
  136. package/dist/manager-Cly8xVIR.cjs +105 -0
  137. package/dist/{mcp-BN6bKIGb.mjs → mcp-B1A4I3TK.mjs} +27 -33
  138. package/dist/{mcp-DGdeUUDJ.cjs → mcp-Hszd7qpS.cjs} +42 -48
  139. package/dist/messageBuffer-BWlGgR3A.mjs +71 -0
  140. package/dist/messageBuffer-fJMH6uY8.cjs +73 -0
  141. package/dist/mirrorProtocol-BNLtoWjO.mjs +170 -0
  142. package/dist/mirrorProtocol-BUtmg1ws.cjs +186 -0
  143. package/dist/oneShotPrompts-CL0dip9C.cjs +16 -0
  144. package/dist/oneShotPrompts-DT4p6RNd.mjs +12 -0
  145. package/dist/package-BhaKlnxz.mjs +171 -0
  146. package/dist/package-BwMrPwqH.cjs +173 -0
  147. package/dist/path-B7zW-WwE.cjs +18 -0
  148. package/dist/path-D2wdaNSk.mjs +15 -0
  149. package/dist/peerTools-BTqw97Gb.mjs +272 -0
  150. package/dist/peerTools-BvKtHXj8.cjs +283 -0
  151. package/dist/permissionMode-Cr5JCbB7.mjs +80 -0
  152. package/dist/permissionMode-CrV-XuMs.cjs +87 -0
  153. package/dist/persistence-HGW_ZVs9.mjs +372 -0
  154. package/dist/persistence-yKTH3-5X.cjs +414 -0
  155. package/dist/piExtension.mjs +2 -1
  156. package/dist/piRunnerArgs-BNloJCCg.cjs +66 -0
  157. package/dist/piRunnerArgs-BuX1UFWy.mjs +59 -0
  158. package/dist/{piRuntime-bkw2NAZU.mjs → piRuntime-CSGkwCKQ.mjs} +2 -2
  159. package/dist/{piRuntime-3qtbKujX.cjs → piRuntime-C_H7MJCM.cjs} +4 -4
  160. package/dist/{piTerminal-DilKwM7B.mjs → piTerminal-C8a1OrNQ.mjs} +32 -35
  161. package/dist/{piTerminal-BYxp3LMr.cjs → piTerminal-DNCZ6yTM.cjs} +32 -35
  162. package/dist/previewPath-B0rBdhy1.cjs +83 -0
  163. package/dist/previewPath-CXN4Vag0.mjs +81 -0
  164. package/dist/projectPath-BTBIMB57.mjs +10 -0
  165. package/dist/projectPath-ChLhdOyt.cjs +13 -0
  166. package/dist/registerCommonHandlers-Ccvsz7Ou.mjs +536 -0
  167. package/dist/registerCommonHandlers-DskirN-_.cjs +538 -0
  168. package/dist/registerKillSessionHandler-DZeLXWcB.cjs +361 -0
  169. package/dist/registerKillSessionHandler-GYvHdipX.mjs +358 -0
  170. package/dist/remoteSessionClient-B0LraSB9.cjs +634 -0
  171. package/dist/remoteSessionClient-CYnXRynE.mjs +612 -0
  172. package/dist/resources-BdFBQi8r.mjs +117 -0
  173. package/dist/resources-JDPugcDq.cjs +120 -0
  174. package/dist/run-CJzxoHVh.cjs +5762 -0
  175. package/dist/run-D3ifupU3.mjs +5739 -0
  176. package/dist/runClaude-Ba01qT-u.mjs +848 -0
  177. package/dist/runClaude-Da3RirzE.cjs +850 -0
  178. package/dist/runClaudeDeps-DOt79DjU.mjs +3624 -0
  179. package/dist/runClaudeDeps-DOzEBMls.cjs +3649 -0
  180. package/dist/{runGemini-Cjii069p.mjs → runGemini-BGeTz57m.mjs} +58 -31
  181. package/dist/{runGemini-28O2sqyI.cjs → runGemini-DSr9LIxL.cjs} +202 -175
  182. package/dist/{runOpenClaw-CiMZad-H.cjs → runOpenClaw-B1mTxN35.cjs} +64 -65
  183. package/dist/{runOpenClaw-jaLr7KF1.mjs → runOpenClaw-CogSedIc.mjs} +31 -32
  184. package/dist/sandbox-CG7IyDTU.cjs +187 -0
  185. package/dist/sandbox-DTe6d54R.mjs +180 -0
  186. package/dist/selfCheck-C9mVrQwf.mjs +84 -0
  187. package/dist/selfCheck-Dc-mNSLb.cjs +87 -0
  188. package/dist/{send-D5ejHPXG.cjs → send-B7J_eaG3.cjs} +16 -9
  189. package/dist/{send-C9mOtChi.mjs → send-CBXJKc6O.mjs} +12 -5
  190. package/dist/server-CZTP_iOn.cjs +407 -0
  191. package/dist/server-DcVBv04l.mjs +404 -0
  192. package/dist/sessionLock-Bys1PNSo.cjs +205 -0
  193. package/dist/sessionLock-D-EG2CfG.mjs +197 -0
  194. package/dist/sessionModeFile-DMl3dw3r.mjs +32 -0
  195. package/dist/sessionModeFile-RSm0NQkH.cjs +36 -0
  196. package/dist/sessionOps-Dn8z85h_.cjs +783 -0
  197. package/dist/sessionOps-SuHW8Dfe.mjs +760 -0
  198. package/dist/sessionScanner-BOrGjMXL.cjs +209 -0
  199. package/dist/sessionScanner-CX3onqXh.mjs +206 -0
  200. package/dist/{sessions-W6771g3X.mjs → sessions-BEG_HTSi.mjs} +17 -8
  201. package/dist/{sessions-BNMPQoLE.cjs → sessions-D74aJbhL.cjs} +37 -28
  202. package/dist/setupOfflineReconnection-ByElY60m.cjs +74 -0
  203. package/dist/setupOfflineReconnection-DpvWTt69.mjs +72 -0
  204. package/dist/smallFastModel-BLNgMrwR.mjs +18 -0
  205. package/dist/smallFastModel-D_uxGMo3.cjs +21 -0
  206. package/dist/{spawn-D0QVhzRb.mjs → spawn-B7yro0b2.mjs} +26 -38
  207. package/dist/{spawn-Ddtom1cb.cjs → spawn-DgR0RKRs.cjs} +52 -64
  208. package/dist/spawnAgents-BGQiEF-w.cjs +52 -0
  209. package/dist/spawnAgents-DZzZ9jMI.mjs +45 -0
  210. package/dist/spawnHappyCLI-B2H5s4B_.mjs +64 -0
  211. package/dist/spawnHappyCLI-DBhwZT7O.cjs +66 -0
  212. package/dist/specialCommands-BSqhYg5X.mjs +52 -0
  213. package/dist/specialCommands-DSsTeRej.cjs +54 -0
  214. package/dist/startFileWatcher-B4VsLgjD.cjs +71 -0
  215. package/dist/startFileWatcher-DErVWZE4.mjs +69 -0
  216. package/dist/startupPlan-BLMbfQIH.cjs +12 -0
  217. package/dist/startupPlan-DFMyNgAs.mjs +10 -0
  218. package/dist/streamRelay-BiKw59Cc.cjs +233 -0
  219. package/dist/streamRelay-FPVbHpbM.mjs +231 -0
  220. package/dist/sync-C8gyQFMc.mjs +69 -0
  221. package/dist/sync-DccIKZ5_.cjs +71 -0
  222. package/dist/systemPrompt-BwTPWfMu.cjs +97 -0
  223. package/dist/systemPrompt-DX521JJz.mjs +94 -0
  224. package/dist/{teams-CqSwtw2O.mjs → teams-C32F1hqd.mjs} +9 -40
  225. package/dist/{teams-BZ1tayg_.cjs → teams-Dl8g8kTI.cjs} +14 -45
  226. package/dist/template-BaHAmH2K.cjs +129 -0
  227. package/dist/template-CiOPa2rd.mjs +121 -0
  228. package/dist/{terminalTitleSuggest-DKgX3osW.mjs → terminalTitleSuggest-CeKsX_V6.mjs} +1 -9
  229. package/dist/{terminalTitleSuggest-Dji8I0Jy.cjs → terminalTitleSuggest-DhvRFX3H.cjs} +0 -10
  230. package/dist/terminals-B_bfC9c2.cjs +250 -0
  231. package/dist/terminals-Dlg0x3nY.mjs +235 -0
  232. package/dist/time-D0XyHOid.mjs +38 -0
  233. package/dist/time-DCuTyook.cjs +42 -0
  234. package/dist/titleGenerator-CQ8CoGhg.mjs +166 -0
  235. package/dist/titleGenerator-ChzMJsyg.cjs +172 -0
  236. package/dist/tmuxSocket-B8Yx20sT.mjs +19 -0
  237. package/dist/tmuxSocket-D-Xt6Vn-.cjs +24 -0
  238. package/dist/{todo-BYMg0fR0.cjs → todo-BvUOTa8G.cjs} +15 -12
  239. package/dist/{todo-BbusB1zM.mjs → todo-CZ6cFrrn.mjs} +11 -8
  240. package/dist/tools-BZtHF_qQ.mjs +177 -0
  241. package/dist/tools-Be3AoAwu.cjs +63 -0
  242. package/dist/tools-DQj0AeLk.cjs +180 -0
  243. package/dist/tools-DkluDcG4.mjs +60 -0
  244. package/dist/trimIdent-4gvk9Wk6.cjs +22 -0
  245. package/dist/trimIdent-BAjmv_TG.mjs +20 -0
  246. package/dist/types-CRS-srZK.cjs +66 -0
  247. package/dist/types-CkqAACXx.mjs +64 -0
  248. package/dist/uninstall-BkLzaJ6I.mjs +47 -0
  249. package/dist/uninstall-x-TUtf5H.cjs +49 -0
  250. package/package.json +7 -7
  251. package/dist/agentGuidance-CrR9l62U.mjs +0 -2145
  252. package/dist/agentGuidance-DwOWbX55.cjs +0 -2217
  253. package/dist/index-BG932eCh.cjs +0 -19655
  254. package/dist/index-CVCt3kSt.mjs +0 -19591
  255. package/dist/index-D5ScEErM.cjs +0 -58
  256. package/dist/index-DgO0FHOx.mjs +0 -52
  257. package/dist/limits-D2uN090G.mjs +0 -2528
  258. package/dist/limits-kqFqhfsh.cjs +0 -2652
@@ -0,0 +1,117 @@
1
+ const TEAM_SKILL = `---
2
+ name: very-happy-teams
3
+ description: Coordinate coding agents through Very Happy teams: delegate tasks, exchange messages, review results, and recover interrupted work. Use when asked to organize or participate in an agent team.
4
+ ---
5
+
6
+ # Very Happy Agent Teams
7
+
8
+ Use the team_* tools in a managed Very Happy session. If absent, explain that this host needs Very Happy Teams setup; reading this skill alone does not establish a connection.
9
+
10
+ Start with team_inspect if already assigned. Otherwise team_create or team_join connects the current session. A scoped worker cannot create another root identity or use account-wide tools to bypass its scope.
11
+
12
+ Work yourself when delegation would add needless overhead. Delegate independent work with a clear goal and acceptance criteria. When delegating within your assignment, pass its parentTaskId. Members may delegate further within their existing authority. After delegating child work, wait for those results instead of continuing parallel edits yourself. Waiting parents yield their execution slot to their children; the team limit counts progressing leaf assignments, not OS processes.
13
+
14
+ Name exactly one integrator for each team. Workers edit only their assigned worktrees; they must not merge main, publish releases, change global daemon or npm installations, or allocate shared backlog IDs. The integrator serializes these operations. Across teams, the owner coordinates shared resources: a worktree is not a global lock.
15
+
16
+ Use a unique requestId for each action and reuse it with identical arguments when the outcome is unknown. Inspect state before retrying; a timeout does not prove no action occurred. A delivered message is not proof its recipient processed it.
17
+
18
+ Inspect the current attemptId and goalVersion before team_submit. Include artifact locations and verification evidence. The owner reviews and accepts or returns the result. All children completing does not automatically satisfy the parent goal.
19
+
20
+ Acceptance and cleanup are separate. Never delete dirty worktrees, stop user-owned sessions, or bypass permissions to finish cleanup. Use team_cancel or team_handoff and inspect the resulting status. Keep summaries concise; do not repeatedly forward full descendant transcripts.
21
+
22
+ A root member may create a persistent schedule for itself with the schedule tools; team_inspect shows schedules. Timely delivery requires an online daemon. A scheduled delivery does not prove the model completed the work. Pause or cancel schedules explicitly when they are no longer needed.
23
+
24
+ On restart inspect authoritative state and messages before taking new actions. Do not invent completed work from a previous context. Scope credentials are runtime-owned; never read, print, or copy them into prompts.
25
+ `;
26
+ const PI_TEAMS_EXTENSION = `// Managed by Very Happy Agent Teams.
27
+ export default async function(pi) {
28
+ const managed = !!process.env.HAPPY_MCP_URL;
29
+ const endpoint = process.env.HAPPY_MCP_URL || process.env.HAPPY_TERMINAL_MCP_URL;
30
+ if (!endpoint) return;
31
+ const url = new URL(endpoint);
32
+ if (!['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname) || url.protocol !== 'http:') throw new Error('Very Happy MCP must be local');
33
+ const {readFile} = await import('node:fs/promises');
34
+ const {join} = await import('node:path');
35
+ const {homedir} = await import('node:os');
36
+ const contextEndpoint = managed && process.env.HAPPY_CONTEXT_USAGE_URL;
37
+ if (contextEndpoint) {
38
+ const target = new URL(contextEndpoint);
39
+ if (target.origin !== url.origin || !target.pathname.startsWith('/runtime-context/')) throw new Error('Very Happy context must be local');
40
+ let reporting = Promise.resolve();
41
+ for (const name of ['session_start', 'session_switch', 'session_compact', 'model_select', 'turn_end', 'agent_end']) {
42
+ pi.on(name, async (_event, ctx) => {
43
+ const usage = ctx.getContextUsage?.();
44
+ const contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow;
45
+ if (!(contextWindow > 0)) return;
46
+ const snapshot = {source:'pi', tokens:usage?.tokens ?? null, contextWindow};
47
+ reporting = reporting.catch(() => {}).then(async () => {
48
+ try { await fetch(contextEndpoint, {method:'POST', redirect:'error', headers:{'content-type':'application/json'}, body:JSON.stringify(snapshot), signal:AbortSignal.timeout(2000)}); } catch {}
49
+ });
50
+ await reporting;
51
+ });
52
+ }
53
+ }
54
+ if (managed) pi.on('tool_call', async (event, ctx) => {
55
+ let mode = process.env.HAPPY_PERMISSION_MODE || 'default';
56
+ const sid = process.env.HAPPY_SESSION_ID;
57
+ if (sid && /^[a-zA-Z0-9_-]+$/.test(sid)) {
58
+ try { mode = JSON.parse(await readFile(join(process.env.HAPPY_HOME_DIR || join(homedir(), '.happy'), 'session-modes', sid + '.json'), 'utf8')).permissionMode; }
59
+ catch (error) { if (error.code !== 'ENOENT') mode = 'default'; }
60
+ }
61
+ if (mode === 'yolo') mode = 'bypassPermissions';
62
+ if (!['default','plan','acceptEdits','bypassPermissions'].includes(mode)) mode = 'default';
63
+ if (mode === 'bypassPermissions') return;
64
+ if (['read','ls','find','grep','team_inspect','change_title','report_progress'].includes(event.toolName)) return;
65
+ if (mode === 'plan') return {block:true,reason:'Plan mode allows read-only tools'};
66
+ if (mode === 'acceptEdits' && ['write','edit'].includes(event.toolName)) return;
67
+ try {
68
+ const allowed = await ctx.ui.confirm('Allow ' + event.toolName + '?', JSON.stringify(event.input || {}).slice(0,4000));
69
+ if (allowed === true) return;
70
+ } catch {}
71
+ return {block:true,reason:'Tool requires explicit approval'};
72
+ });
73
+ let nextId = 0;
74
+ async function rpc(method, params) {
75
+ const requestId = ++nextId;
76
+ const response = await fetch(endpoint, { method: 'POST', redirect: 'error', headers: {'content-type':'application/json', accept:'application/json, text/event-stream'}, body: JSON.stringify({jsonrpc:'2.0',id:requestId,method,params}), signal: AbortSignal.timeout(30000) });
77
+ if (!response.ok) throw new Error('Very Happy tools unavailable (HTTP ' + response.status + ')');
78
+ const body = await response.text();
79
+ let data;
80
+ if ((response.headers.get('content-type') || '').includes('text/event-stream')) {
81
+ for (const event of body.split(/\\r?\\n\\r?\\n/)) {
82
+ const payload = event.split(/\\r?\\n/).filter(line => line.startsWith('data:')).map(line => line.slice(5).trimStart()).join('\\n');
83
+ if (payload) { const candidate = JSON.parse(payload); if (candidate.id === requestId) data = candidate; }
84
+ }
85
+ } else data = JSON.parse(body);
86
+ if (!data || data.error) throw new Error('Very Happy tool request failed');
87
+ return data.result;
88
+ }
89
+ await rpc('initialize', {protocolVersion:'2024-11-05',capabilities:{},clientInfo:{name:'very-happy-pi-teams',version:'1'}});
90
+ if (!managed && pi.setSessionName) {
91
+ // B-500: name the pi session from its first prompt (managed sessions are titled by TitleGenerator).
92
+ let titleArmed = false, generation = 0;
93
+ pi.on('session_start', async () => { generation += 1; titleArmed = !pi.getSessionName?.(); });
94
+ pi.on('before_agent_start', async (event) => {
95
+ const prompt = event && typeof event.prompt === 'string' ? event.prompt : '';
96
+ if (!titleArmed || !prompt.trim()) return;
97
+ titleArmed = false;
98
+ const expected = generation;
99
+ rpc('very-happy/terminal-title-suggest', {prompt}).then(result => {
100
+ if (result && result.title && expected === generation && !pi.getSessionName?.()) pi.setSessionName(result.title);
101
+ }).catch(() => {});
102
+ });
103
+ }
104
+ const available = await rpc('tools/list', {});
105
+ for (const tool of available.tools || []) {
106
+ pi.registerTool({name:tool.name,label:tool.name,description:tool.description || tool.name,parameters:tool.inputSchema,
107
+ async execute(_id, args) {
108
+ const result = await rpc('tools/call', {name:tool.name,arguments:args});
109
+ if (result.isError) throw new Error((result.content || []).filter(block => block.type === 'text').map(block => block.text).join('\\n') || 'Very Happy tool failed');
110
+ return {content:result.content,details:{isError:false}};
111
+ }
112
+ });
113
+ }
114
+ }
115
+ `;
116
+
117
+ export { PI_TEAMS_EXTENSION as P, TEAM_SKILL as T };
@@ -0,0 +1,120 @@
1
+ 'use strict';
2
+
3
+ const TEAM_SKILL = `---
4
+ name: very-happy-teams
5
+ description: Coordinate coding agents through Very Happy teams: delegate tasks, exchange messages, review results, and recover interrupted work. Use when asked to organize or participate in an agent team.
6
+ ---
7
+
8
+ # Very Happy Agent Teams
9
+
10
+ Use the team_* tools in a managed Very Happy session. If absent, explain that this host needs Very Happy Teams setup; reading this skill alone does not establish a connection.
11
+
12
+ Start with team_inspect if already assigned. Otherwise team_create or team_join connects the current session. A scoped worker cannot create another root identity or use account-wide tools to bypass its scope.
13
+
14
+ Work yourself when delegation would add needless overhead. Delegate independent work with a clear goal and acceptance criteria. When delegating within your assignment, pass its parentTaskId. Members may delegate further within their existing authority. After delegating child work, wait for those results instead of continuing parallel edits yourself. Waiting parents yield their execution slot to their children; the team limit counts progressing leaf assignments, not OS processes.
15
+
16
+ Name exactly one integrator for each team. Workers edit only their assigned worktrees; they must not merge main, publish releases, change global daemon or npm installations, or allocate shared backlog IDs. The integrator serializes these operations. Across teams, the owner coordinates shared resources: a worktree is not a global lock.
17
+
18
+ Use a unique requestId for each action and reuse it with identical arguments when the outcome is unknown. Inspect state before retrying; a timeout does not prove no action occurred. A delivered message is not proof its recipient processed it.
19
+
20
+ Inspect the current attemptId and goalVersion before team_submit. Include artifact locations and verification evidence. The owner reviews and accepts or returns the result. All children completing does not automatically satisfy the parent goal.
21
+
22
+ Acceptance and cleanup are separate. Never delete dirty worktrees, stop user-owned sessions, or bypass permissions to finish cleanup. Use team_cancel or team_handoff and inspect the resulting status. Keep summaries concise; do not repeatedly forward full descendant transcripts.
23
+
24
+ A root member may create a persistent schedule for itself with the schedule tools; team_inspect shows schedules. Timely delivery requires an online daemon. A scheduled delivery does not prove the model completed the work. Pause or cancel schedules explicitly when they are no longer needed.
25
+
26
+ On restart inspect authoritative state and messages before taking new actions. Do not invent completed work from a previous context. Scope credentials are runtime-owned; never read, print, or copy them into prompts.
27
+ `;
28
+ const PI_TEAMS_EXTENSION = `// Managed by Very Happy Agent Teams.
29
+ export default async function(pi) {
30
+ const managed = !!process.env.HAPPY_MCP_URL;
31
+ const endpoint = process.env.HAPPY_MCP_URL || process.env.HAPPY_TERMINAL_MCP_URL;
32
+ if (!endpoint) return;
33
+ const url = new URL(endpoint);
34
+ if (!['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname) || url.protocol !== 'http:') throw new Error('Very Happy MCP must be local');
35
+ const {readFile} = await import('node:fs/promises');
36
+ const {join} = await import('node:path');
37
+ const {homedir} = await import('node:os');
38
+ const contextEndpoint = managed && process.env.HAPPY_CONTEXT_USAGE_URL;
39
+ if (contextEndpoint) {
40
+ const target = new URL(contextEndpoint);
41
+ if (target.origin !== url.origin || !target.pathname.startsWith('/runtime-context/')) throw new Error('Very Happy context must be local');
42
+ let reporting = Promise.resolve();
43
+ for (const name of ['session_start', 'session_switch', 'session_compact', 'model_select', 'turn_end', 'agent_end']) {
44
+ pi.on(name, async (_event, ctx) => {
45
+ const usage = ctx.getContextUsage?.();
46
+ const contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow;
47
+ if (!(contextWindow > 0)) return;
48
+ const snapshot = {source:'pi', tokens:usage?.tokens ?? null, contextWindow};
49
+ reporting = reporting.catch(() => {}).then(async () => {
50
+ try { await fetch(contextEndpoint, {method:'POST', redirect:'error', headers:{'content-type':'application/json'}, body:JSON.stringify(snapshot), signal:AbortSignal.timeout(2000)}); } catch {}
51
+ });
52
+ await reporting;
53
+ });
54
+ }
55
+ }
56
+ if (managed) pi.on('tool_call', async (event, ctx) => {
57
+ let mode = process.env.HAPPY_PERMISSION_MODE || 'default';
58
+ const sid = process.env.HAPPY_SESSION_ID;
59
+ if (sid && /^[a-zA-Z0-9_-]+$/.test(sid)) {
60
+ try { mode = JSON.parse(await readFile(join(process.env.HAPPY_HOME_DIR || join(homedir(), '.happy'), 'session-modes', sid + '.json'), 'utf8')).permissionMode; }
61
+ catch (error) { if (error.code !== 'ENOENT') mode = 'default'; }
62
+ }
63
+ if (mode === 'yolo') mode = 'bypassPermissions';
64
+ if (!['default','plan','acceptEdits','bypassPermissions'].includes(mode)) mode = 'default';
65
+ if (mode === 'bypassPermissions') return;
66
+ if (['read','ls','find','grep','team_inspect','change_title','report_progress'].includes(event.toolName)) return;
67
+ if (mode === 'plan') return {block:true,reason:'Plan mode allows read-only tools'};
68
+ if (mode === 'acceptEdits' && ['write','edit'].includes(event.toolName)) return;
69
+ try {
70
+ const allowed = await ctx.ui.confirm('Allow ' + event.toolName + '?', JSON.stringify(event.input || {}).slice(0,4000));
71
+ if (allowed === true) return;
72
+ } catch {}
73
+ return {block:true,reason:'Tool requires explicit approval'};
74
+ });
75
+ let nextId = 0;
76
+ async function rpc(method, params) {
77
+ const requestId = ++nextId;
78
+ const response = await fetch(endpoint, { method: 'POST', redirect: 'error', headers: {'content-type':'application/json', accept:'application/json, text/event-stream'}, body: JSON.stringify({jsonrpc:'2.0',id:requestId,method,params}), signal: AbortSignal.timeout(30000) });
79
+ if (!response.ok) throw new Error('Very Happy tools unavailable (HTTP ' + response.status + ')');
80
+ const body = await response.text();
81
+ let data;
82
+ if ((response.headers.get('content-type') || '').includes('text/event-stream')) {
83
+ for (const event of body.split(/\\r?\\n\\r?\\n/)) {
84
+ const payload = event.split(/\\r?\\n/).filter(line => line.startsWith('data:')).map(line => line.slice(5).trimStart()).join('\\n');
85
+ if (payload) { const candidate = JSON.parse(payload); if (candidate.id === requestId) data = candidate; }
86
+ }
87
+ } else data = JSON.parse(body);
88
+ if (!data || data.error) throw new Error('Very Happy tool request failed');
89
+ return data.result;
90
+ }
91
+ await rpc('initialize', {protocolVersion:'2024-11-05',capabilities:{},clientInfo:{name:'very-happy-pi-teams',version:'1'}});
92
+ if (!managed && pi.setSessionName) {
93
+ // B-500: name the pi session from its first prompt (managed sessions are titled by TitleGenerator).
94
+ let titleArmed = false, generation = 0;
95
+ pi.on('session_start', async () => { generation += 1; titleArmed = !pi.getSessionName?.(); });
96
+ pi.on('before_agent_start', async (event) => {
97
+ const prompt = event && typeof event.prompt === 'string' ? event.prompt : '';
98
+ if (!titleArmed || !prompt.trim()) return;
99
+ titleArmed = false;
100
+ const expected = generation;
101
+ rpc('very-happy/terminal-title-suggest', {prompt}).then(result => {
102
+ if (result && result.title && expected === generation && !pi.getSessionName?.()) pi.setSessionName(result.title);
103
+ }).catch(() => {});
104
+ });
105
+ }
106
+ const available = await rpc('tools/list', {});
107
+ for (const tool of available.tools || []) {
108
+ pi.registerTool({name:tool.name,label:tool.name,description:tool.description || tool.name,parameters:tool.inputSchema,
109
+ async execute(_id, args) {
110
+ const result = await rpc('tools/call', {name:tool.name,arguments:args});
111
+ if (result.isError) throw new Error((result.content || []).filter(block => block.type === 'text').map(block => block.text).join('\\n') || 'Very Happy tool failed');
112
+ return {content:result.content,details:{isError:false}};
113
+ }
114
+ });
115
+ }
116
+ }
117
+ `;
118
+
119
+ exports.PI_TEAMS_EXTENSION = PI_TEAMS_EXTENSION;
120
+ exports.TEAM_SKILL = TEAM_SKILL;