seatmesh 1.1.4 → 1.2.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 (320) hide show
  1. package/bin/seatmesh +20 -0
  2. package/bin/sm +3 -0
  3. package/dist/commands/ack-cli.d.ts.map +1 -1
  4. package/dist/commands/ack-cli.js +32 -14
  5. package/dist/commands/ack-cli.js.map +1 -1
  6. package/dist/commands/ack-reply.d.ts +29 -0
  7. package/dist/commands/ack-reply.d.ts.map +1 -0
  8. package/dist/commands/ack-reply.js +110 -0
  9. package/dist/commands/ack-reply.js.map +1 -0
  10. package/dist/commands/ack-reply.test.d.ts +2 -0
  11. package/dist/commands/ack-reply.test.d.ts.map +1 -0
  12. package/dist/commands/ack-reply.test.js +37 -0
  13. package/dist/commands/ack-reply.test.js.map +1 -0
  14. package/dist/commands/agent-shorthand.d.ts +27 -0
  15. package/dist/commands/agent-shorthand.d.ts.map +1 -0
  16. package/dist/commands/agent-shorthand.js +57 -0
  17. package/dist/commands/agent-shorthand.js.map +1 -0
  18. package/dist/commands/agent-shorthand.test.d.ts +2 -0
  19. package/dist/commands/agent-shorthand.test.d.ts.map +1 -0
  20. package/dist/commands/agent-shorthand.test.js +36 -0
  21. package/dist/commands/agent-shorthand.test.js.map +1 -0
  22. package/dist/commands/checkback-cli.d.ts.map +1 -1
  23. package/dist/commands/checkback-cli.js +18 -3
  24. package/dist/commands/checkback-cli.js.map +1 -1
  25. package/dist/commands/completion.d.ts +20 -0
  26. package/dist/commands/completion.d.ts.map +1 -0
  27. package/dist/commands/completion.js +416 -0
  28. package/dist/commands/completion.js.map +1 -0
  29. package/dist/commands/completion.test.d.ts +2 -0
  30. package/dist/commands/completion.test.d.ts.map +1 -0
  31. package/dist/commands/completion.test.js +40 -0
  32. package/dist/commands/completion.test.js.map +1 -0
  33. package/dist/commands/config-cli.d.ts +9 -0
  34. package/dist/commands/config-cli.d.ts.map +1 -0
  35. package/dist/commands/config-cli.js +74 -0
  36. package/dist/commands/config-cli.js.map +1 -0
  37. package/dist/commands/gen-commands-md.d.ts +3 -0
  38. package/dist/commands/gen-commands-md.d.ts.map +1 -0
  39. package/dist/commands/gen-commands-md.js +50 -0
  40. package/dist/commands/gen-commands-md.js.map +1 -0
  41. package/dist/commands/help-human-surface.test.d.ts +2 -0
  42. package/dist/commands/help-human-surface.test.d.ts.map +1 -0
  43. package/dist/commands/help-human-surface.test.js +32 -0
  44. package/dist/commands/help-human-surface.test.js.map +1 -0
  45. package/dist/commands/help-text.d.ts +25 -0
  46. package/dist/commands/help-text.d.ts.map +1 -0
  47. package/dist/commands/help-text.js +466 -0
  48. package/dist/commands/help-text.js.map +1 -0
  49. package/dist/commands/help-text.test.d.ts +2 -0
  50. package/dist/commands/help-text.test.d.ts.map +1 -0
  51. package/dist/commands/help-text.test.js +62 -0
  52. package/dist/commands/help-text.test.js.map +1 -0
  53. package/dist/commands/notify-cli.d.ts.map +1 -1
  54. package/dist/commands/notify-cli.js +16 -7
  55. package/dist/commands/notify-cli.js.map +1 -1
  56. package/dist/commands/notify-cli.test.d.ts +2 -0
  57. package/dist/commands/notify-cli.test.d.ts.map +1 -0
  58. package/dist/commands/notify-cli.test.js +33 -0
  59. package/dist/commands/notify-cli.test.js.map +1 -0
  60. package/dist/commands/room-cli.d.ts.map +1 -1
  61. package/dist/commands/room-cli.js +2 -1
  62. package/dist/commands/room-cli.js.map +1 -1
  63. package/dist/commands/seat-cli.d.ts.map +1 -1
  64. package/dist/commands/seat-cli.js +115 -7
  65. package/dist/commands/seat-cli.js.map +1 -1
  66. package/dist/commands/sessions-cli.d.ts +15 -1
  67. package/dist/commands/sessions-cli.d.ts.map +1 -1
  68. package/dist/commands/sessions-cli.js +90 -5
  69. package/dist/commands/sessions-cli.js.map +1 -1
  70. package/dist/commands/sessions-cli.test.d.ts +2 -0
  71. package/dist/commands/sessions-cli.test.d.ts.map +1 -0
  72. package/dist/commands/sessions-cli.test.js +21 -0
  73. package/dist/commands/sessions-cli.test.js.map +1 -0
  74. package/dist/commands/target-cli.js +1 -1
  75. package/dist/commands/todo-give.test.d.ts +2 -0
  76. package/dist/commands/todo-give.test.d.ts.map +1 -0
  77. package/dist/commands/todo-give.test.js +20 -0
  78. package/dist/commands/todo-give.test.js.map +1 -0
  79. package/dist/commands/tp-cli.d.ts +3 -0
  80. package/dist/commands/tp-cli.d.ts.map +1 -0
  81. package/dist/commands/tp-cli.js +95 -0
  82. package/dist/commands/tp-cli.js.map +1 -0
  83. package/dist/commands/web-cli.d.ts +11 -0
  84. package/dist/commands/web-cli.d.ts.map +1 -0
  85. package/dist/commands/web-cli.js +187 -0
  86. package/dist/commands/web-cli.js.map +1 -0
  87. package/dist/main.js +450 -34
  88. package/dist/main.js.map +1 -1
  89. package/dist/setup/install.d.ts +17 -0
  90. package/dist/setup/install.d.ts.map +1 -0
  91. package/dist/setup/install.js +69 -0
  92. package/dist/setup/install.js.map +1 -0
  93. package/dist/setup/install.test.d.ts +2 -0
  94. package/dist/setup/install.test.d.ts.map +1 -0
  95. package/dist/setup/install.test.js +32 -0
  96. package/dist/setup/install.test.js.map +1 -0
  97. package/dist/setup/merge-mesh-config.d.ts +13 -0
  98. package/dist/setup/merge-mesh-config.d.ts.map +1 -0
  99. package/dist/setup/merge-mesh-config.js +112 -0
  100. package/dist/setup/merge-mesh-config.js.map +1 -0
  101. package/dist/setup/merge-mesh-config.test.d.ts +2 -0
  102. package/dist/setup/merge-mesh-config.test.d.ts.map +1 -0
  103. package/dist/setup/merge-mesh-config.test.js +96 -0
  104. package/dist/setup/merge-mesh-config.test.js.map +1 -0
  105. package/dist/setup/session-health.d.ts +33 -0
  106. package/dist/setup/session-health.d.ts.map +1 -0
  107. package/dist/setup/session-health.js +418 -0
  108. package/dist/setup/session-health.js.map +1 -0
  109. package/dist/setup/session-health.test.d.ts +2 -0
  110. package/dist/setup/session-health.test.d.ts.map +1 -0
  111. package/dist/setup/session-health.test.js +46 -0
  112. package/dist/setup/session-health.test.js.map +1 -0
  113. package/dist/setup/update.d.ts +2 -0
  114. package/dist/setup/update.d.ts.map +1 -1
  115. package/dist/setup/update.js +27 -2
  116. package/dist/setup/update.js.map +1 -1
  117. package/dist/setup/update.test.js +45 -0
  118. package/dist/setup/update.test.js.map +1 -1
  119. package/package.json +7 -6
  120. package/templates/docs/COMMANDS.md +1078 -0
  121. package/templates/docs/ONE-PATH.md +136 -0
  122. package/templates/docs/RELEASE.md +32 -0
  123. package/templates/docs/cli/README.md +96 -0
  124. package/templates/docs/cli/ack.md +12 -0
  125. package/templates/docs/cli/ackmsg.md +12 -0
  126. package/templates/docs/cli/agent.md +13 -0
  127. package/templates/docs/cli/apply.md +11 -0
  128. package/templates/docs/cli/ask.md +12 -0
  129. package/templates/docs/cli/assign.md +11 -0
  130. package/templates/docs/cli/auto.md +10 -0
  131. package/templates/docs/cli/balance.md +10 -0
  132. package/templates/docs/cli/base.md +10 -0
  133. package/templates/docs/cli/cb.md +12 -0
  134. package/templates/docs/cli/chat.md +12 -0
  135. package/templates/docs/cli/cold-start.md +11 -0
  136. package/templates/docs/cli/completion.md +11 -0
  137. package/templates/docs/cli/config.md +15 -0
  138. package/templates/docs/cli/contexts.md +12 -0
  139. package/templates/docs/cli/continue.md +10 -0
  140. package/templates/docs/cli/contract.md +25 -0
  141. package/templates/docs/cli/flush.md +10 -0
  142. package/templates/docs/cli/forum.md +12 -0
  143. package/templates/docs/cli/func.md +10 -0
  144. package/templates/docs/cli/golf.md +10 -0
  145. package/templates/docs/cli/help.md +13 -0
  146. package/templates/docs/cli/hub.md +14 -0
  147. package/templates/docs/cli/human.md +35 -0
  148. package/templates/docs/cli/inbox.md +11 -0
  149. package/templates/docs/cli/index.md +10 -0
  150. package/templates/docs/cli/init.md +10 -0
  151. package/templates/docs/cli/kind.md +11 -0
  152. package/templates/docs/cli/labels.md +10 -0
  153. package/templates/docs/cli/launch.md +12 -0
  154. package/templates/docs/cli/layout.md +11 -0
  155. package/templates/docs/cli/limit.md +11 -0
  156. package/templates/docs/cli/migrate-runtime.md +10 -0
  157. package/templates/docs/cli/mini.md +11 -0
  158. package/templates/docs/cli/night.md +10 -0
  159. package/templates/docs/cli/notify.md +28 -0
  160. package/templates/docs/cli/oc-proxy.md +47 -0
  161. package/templates/docs/cli/ops.md +10 -0
  162. package/templates/docs/cli/pane-meta.md +10 -0
  163. package/templates/docs/cli/peek.md +10 -0
  164. package/templates/docs/cli/peer.md +14 -0
  165. package/templates/docs/cli/ppa.md +12 -0
  166. package/templates/docs/cli/preview.md +16 -0
  167. package/templates/docs/cli/profile.md +10 -0
  168. package/templates/docs/cli/prompt.md +14 -0
  169. package/templates/docs/cli/providers.md +10 -0
  170. package/templates/docs/cli/proxy.md +10 -0
  171. package/templates/docs/cli/read-history.md +12 -0
  172. package/templates/docs/cli/realign.md +10 -0
  173. package/templates/docs/cli/reload.md +10 -0
  174. package/templates/docs/cli/remind.md +10 -0
  175. package/templates/docs/cli/remote.md +19 -0
  176. package/templates/docs/cli/reply.md +11 -0
  177. package/templates/docs/cli/report.md +10 -0
  178. package/templates/docs/cli/roles.md +10 -0
  179. package/templates/docs/cli/room.md +15 -0
  180. package/templates/docs/cli/run.md +12 -0
  181. package/templates/docs/cli/save.md +10 -0
  182. package/templates/docs/cli/seat.md +11 -0
  183. package/templates/docs/cli/secretary.md +12 -0
  184. package/templates/docs/cli/session.md +10 -0
  185. package/templates/docs/cli/sessions.md +12 -0
  186. package/templates/docs/cli/set.md +10 -0
  187. package/templates/docs/cli/slot-advice.md +10 -0
  188. package/templates/docs/cli/stack.md +11 -0
  189. package/templates/docs/cli/start.md +10 -0
  190. package/templates/docs/cli/status.md +10 -0
  191. package/templates/docs/cli/swap.md +10 -0
  192. package/templates/docs/cli/switch.md +14 -0
  193. package/templates/docs/cli/tag.md +10 -0
  194. package/templates/docs/cli/target.md +12 -0
  195. package/templates/docs/cli/test.md +10 -0
  196. package/templates/docs/cli/title.md +10 -0
  197. package/templates/docs/cli/to-master.md +10 -0
  198. package/templates/docs/cli/to-mini.md +10 -0
  199. package/templates/docs/cli/to-slot.md +10 -0
  200. package/templates/docs/cli/todo.md +16 -0
  201. package/templates/docs/cli/update.md +23 -0
  202. package/templates/docs/cli/verify.md +10 -0
  203. package/templates/docs/cli/version.md +10 -0
  204. package/templates/docs/cli/whoami.md +12 -0
  205. package/templates/init/AGENTS.md +88 -26
  206. package/templates/init/contracts/_vendor/balance.yaml +11 -0
  207. package/templates/init/contracts/_vendor/supervise.yaml +14 -0
  208. package/templates/init/mesh.config.yaml +40 -0
  209. package/templates/init/roles/common.yaml +6 -2
  210. package/templates/init/roles/docs/common.md +3 -1
  211. package/templates/init/roles/docs/manager.md +4 -0
  212. package/templates/init/roles/docs/secretary.md +2 -0
  213. package/templates/init/roles/docs/worker.md +3 -0
  214. package/templates/init/roles/manager.yaml +2 -0
  215. package/templates/init/roles/secretary.yaml +3 -0
  216. package/templates/init/roles/worker.yaml +3 -1
  217. package/dist/agent-context-init.d.ts +0 -5
  218. package/dist/agent-context-init.d.ts.map +0 -1
  219. package/dist/agent-context-init.js +0 -41
  220. package/dist/agent-context-init.js.map +0 -1
  221. package/dist/banner.d.ts +0 -9
  222. package/dist/banner.d.ts.map +0 -1
  223. package/dist/banner.js +0 -113
  224. package/dist/banner.js.map +0 -1
  225. package/dist/chat-cli.d.ts +0 -4
  226. package/dist/chat-cli.d.ts.map +0 -1
  227. package/dist/chat-cli.js +0 -162
  228. package/dist/chat-cli.js.map +0 -1
  229. package/dist/checkback-cli.d.ts +0 -4
  230. package/dist/checkback-cli.d.ts.map +0 -1
  231. package/dist/checkback-cli.js +0 -203
  232. package/dist/checkback-cli.js.map +0 -1
  233. package/dist/contract-lock-cli.d.ts +0 -4
  234. package/dist/contract-lock-cli.d.ts.map +0 -1
  235. package/dist/contract-lock-cli.js +0 -180
  236. package/dist/contract-lock-cli.js.map +0 -1
  237. package/dist/coord-cli.d.ts +0 -3
  238. package/dist/coord-cli.d.ts.map +0 -1
  239. package/dist/coord-cli.js +0 -15
  240. package/dist/coord-cli.js.map +0 -1
  241. package/dist/discovery-report.d.ts +0 -15
  242. package/dist/discovery-report.d.ts.map +0 -1
  243. package/dist/discovery-report.js +0 -42
  244. package/dist/discovery-report.js.map +0 -1
  245. package/dist/init.d.ts +0 -23
  246. package/dist/init.d.ts.map +0 -1
  247. package/dist/init.js +0 -74
  248. package/dist/init.js.map +0 -1
  249. package/dist/init.test.d.ts +0 -2
  250. package/dist/init.test.d.ts.map +0 -1
  251. package/dist/init.test.js +0 -37
  252. package/dist/init.test.js.map +0 -1
  253. package/dist/logo-art.d.ts +0 -4
  254. package/dist/logo-art.d.ts.map +0 -1
  255. package/dist/logo-art.js +0 -134
  256. package/dist/logo-art.js.map +0 -1
  257. package/dist/logo-cli.d.ts +0 -3
  258. package/dist/logo-cli.d.ts.map +0 -1
  259. package/dist/logo-cli.js +0 -30
  260. package/dist/logo-cli.js.map +0 -1
  261. package/dist/logo-color.d.ts +0 -16
  262. package/dist/logo-color.d.ts.map +0 -1
  263. package/dist/logo-color.js +0 -65
  264. package/dist/logo-color.js.map +0 -1
  265. package/dist/migrate-runtime.d.ts +0 -15
  266. package/dist/migrate-runtime.d.ts.map +0 -1
  267. package/dist/migrate-runtime.js +0 -67
  268. package/dist/migrate-runtime.js.map +0 -1
  269. package/dist/notify-cli.d.ts +0 -4
  270. package/dist/notify-cli.d.ts.map +0 -1
  271. package/dist/notify-cli.js +0 -45
  272. package/dist/notify-cli.js.map +0 -1
  273. package/dist/preview-cli.d.ts +0 -4
  274. package/dist/preview-cli.d.ts.map +0 -1
  275. package/dist/preview-cli.js +0 -39
  276. package/dist/preview-cli.js.map +0 -1
  277. package/dist/program-help.d.ts +0 -3
  278. package/dist/program-help.d.ts.map +0 -1
  279. package/dist/program-help.js +0 -23
  280. package/dist/program-help.js.map +0 -1
  281. package/dist/room-cli.d.ts +0 -5
  282. package/dist/room-cli.d.ts.map +0 -1
  283. package/dist/room-cli.js +0 -316
  284. package/dist/room-cli.js.map +0 -1
  285. package/dist/room.d.ts +0 -4
  286. package/dist/room.d.ts.map +0 -1
  287. package/dist/room.js +0 -149
  288. package/dist/room.js.map +0 -1
  289. package/dist/seat-cli.d.ts +0 -3
  290. package/dist/seat-cli.d.ts.map +0 -1
  291. package/dist/seat-cli.js +0 -73
  292. package/dist/seat-cli.js.map +0 -1
  293. package/dist/sessions-cli.d.ts +0 -11
  294. package/dist/sessions-cli.d.ts.map +0 -1
  295. package/dist/sessions-cli.js +0 -178
  296. package/dist/sessions-cli.js.map +0 -1
  297. package/dist/status-report.d.ts +0 -22
  298. package/dist/status-report.d.ts.map +0 -1
  299. package/dist/status-report.js +0 -231
  300. package/dist/status-report.js.map +0 -1
  301. package/dist/update.d.ts +0 -15
  302. package/dist/update.d.ts.map +0 -1
  303. package/dist/update.js +0 -89
  304. package/dist/update.js.map +0 -1
  305. package/dist/version-nudge.d.ts +0 -20
  306. package/dist/version-nudge.d.ts.map +0 -1
  307. package/dist/version-nudge.js +0 -107
  308. package/dist/version-nudge.js.map +0 -1
  309. package/dist/version-nudge.test.d.ts +0 -2
  310. package/dist/version-nudge.test.d.ts.map +0 -1
  311. package/dist/version-nudge.test.js +0 -16
  312. package/dist/version-nudge.test.js.map +0 -1
  313. package/dist/watch-daemon.d.ts +0 -2
  314. package/dist/watch-daemon.d.ts.map +0 -1
  315. package/dist/watch-daemon.js +0 -41
  316. package/dist/watch-daemon.js.map +0 -1
  317. package/dist/work-daemon.d.ts +0 -2
  318. package/dist/work-daemon.d.ts.map +0 -1
  319. package/dist/work-daemon.js +0 -42
  320. package/dist/work-daemon.js.map +0 -1
package/dist/main.js CHANGED
@@ -1,15 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawnSync } from "node:child_process";
3
3
  import { findDotSmConfig } from "@seat-mesh/core";
4
- import { loadProfile, profilePaths, loadRoleIndex, renderRoleIndex, validateRoleIndex, runStackPassthrough, roleAllows, isCoordKind, isManagerKind, managerColumnIds, addBaseColumn, removeBaseColumn, listBaseColumns, chatRoomConfigForLoaded, clearAckEndedSync, } from "@seat-mesh/core";
4
+ import { loadProfile, profilePaths, loadRoleIndex, renderRoleIndex, validateRoleIndex, runStackPassthrough, roleAllows, isCoordKind, isManagerKind, managerColumnIds, addBaseColumn, removeBaseColumn, listBaseColumns, chatRoomConfigForLoaded, clearAckEndedSync, resolveAckRedirectDefaults, } from "@seat-mesh/core";
5
5
  import { snapshotConnectivity, formatStatus } from "@seat-mesh/connectivity";
6
6
  import { createRegistryForProfile } from "@seat-mesh/providers";
7
- import { printWhoami, whoamiJson, whoamiJsonWithValidate, validateWhoamiRoleIndex, printAgentCard, printAgentContext, printAgentContextAllRoles, runWhoami, roleKindFromWhoami, requireCoordRole, requireInboxLifecycleRole, assertAgentDispatch, printAgentUnauthorized, stripAgentFromArgv, AGENT_META, capturePaneSnapshot, listSessionPanes, sessionAttach, sessionUp, sessionDown, sessionStatus, sessionSync, tmuxHasSession, relayoutMeshSession, realignAllLayouts, reloadMesh, ensureMeshInbox, startMeshInbox, stopMeshInbox, restartMeshInbox, meshInboxEverConfigured, meshInboxPort, printMeshInboxStatus, waitForMeshInbox, printInboxMeta, tailInboxLog, listInboxInstances, parseInboxStatusFlags, inboxStatusArgv, listInbox, resolveInbox, secretaryLaunch, secretaryRestart, secretaryDispatch, secretaryCollect, secretaryMeshWatch, secretarySupervise, secretaryStatus, printMiniList, miniSpawn, miniPrompt, miniDone, miniSpawnAll, runMeshSmoke, printSmokeResults, launchSession, printLaunchResults, enqueuePrompt, injectPromptDirect, printPeerVerify, runPeerVerify, runRemind, printRemindResults, runNight, runContinue, printContinueResults, runSlotAdvice, verifyMeshSession, printVerify, labelMeshSession, liveMeshSession, ensureBaseLayout, realignBaseLayout, applyMeshSessionBorders, runFlush, printFlushResults, runSwitch, runSet, runTag, setPaneTitle, setPaneStatus, printSeatContexts, runPeek, runPaneKind, runPaneMeta, runPpa, runToSlot, runToMini, runPeer, parseRemotePeerTarget, runRemotePeer, applyMeshState, saveMeshSession, saveMeshSessionDetailed, assertSaveAllowed, formatSaveSummary, submitPaneOp, clearPaneOpsQueue, printPaneOpsList, printRelayoutPlan, assertRelayoutSafe, buildFullColdStartBrief, enqueueColdStart, runSeatInit, applyAgentContractBundle, balanceLeadCommand, } from "@seat-mesh/tmux";
7
+ import { printWhoami, whoamiJson, whoamiJsonWithValidate, validateWhoamiRoleIndex, printAgentCard, printAgentContext, printAgentContextAllRoles, runWhoami, roleKindFromWhoami, requireCoordRole, requireInboxLifecycleRole, assertAgentDispatch, printAgentUnauthorized, stripAgentFromArgv, AGENT_META, capturePaneSnapshot, listSessionPanes, sessionAttach, sessionUp, sessionDown, sessionStatus, sessionSync, tmuxHasSession, relayoutMeshSession, realignAllLayouts, reloadMesh, ensureMeshInbox, startMeshInbox, stopMeshInbox, restartMeshInbox, meshInboxEverConfigured, meshInboxPort, printMeshInboxStatus, waitForMeshInbox, printInboxMeta, tailInboxLog, listInboxInstances, parseInboxStatusFlags, inboxStatusArgv, listInbox, resolveInbox, secretaryLaunch, secretaryDispatch, secretaryCollect, secretaryMeshWatch, secretarySupervise, secretaryStatus, printMiniList, miniSpawn, miniPrompt, miniDone, miniSpawnAll, runMeshSmoke, printSmokeResults, launchSession, printLaunchResults, defaultHarnessTypeForSeat, enqueuePrompt, injectPromptDirect, printPeerVerify, runPeerVerify, runRemind, printRemindResults, runNight, runContinue, printContinueResults, runSlotAdvice, verifyMeshSession, printVerify, labelMeshSession, liveMeshSession, ensureBaseLayout, realignBaseLayout, applyMeshSessionBorders, runFlush, printFlushResults, runSwitch, runPaneResume, runSeatSwap, runSet, runTag, setPaneTitle, setPaneStatus, printSeatContexts, runAgentHub, runPeek, runPaneKind, runPaneMeta, runPpa, runToSlot, runToMini, runPeer, parseRemotePeerTarget, runRemotePeer, applyMeshState, saveMeshSession, saveMeshSessionDetailed, assertSaveAllowed, formatSaveSummary, submitPaneOp, clearPaneOpsQueue, printPaneOpsList, printRelayoutPlan, assertRelayoutSafe, buildFullColdStartBrief, enqueueColdStart, runSeatInit, applyAgentContractBundle, balanceLeadCommand, } from "@seat-mesh/tmux";
8
8
  import { parseAgentApplyArgs } from "@seat-mesh/core";
9
9
  import { buildChatCommands } from "./commands/chat-cli.js";
10
10
  import { buildCheckbackCommands } from "./commands/checkback-cli.js";
11
11
  import { buildTargetCommands } from "./commands/target-cli.js";
12
12
  import { buildAckCommands } from "./commands/ack-cli.js";
13
+ import { resolvePeerEndedAckId, shouldAutoAckReply, } from "./commands/ack-reply.js";
13
14
  import { buildLimitCommands } from "./commands/limit-cli.js";
14
15
  import { buildRolesCommands } from "./commands/roles-cli.js";
15
16
  import { buildNotifyCommand } from "./commands/notify-cli.js";
@@ -18,11 +19,13 @@ import { buildContractLockCommands } from "./commands/contract-lock-cli.js";
18
19
  import { buildRoomCommands } from "./commands/room-cli.js";
19
20
  import { runInit } from "./setup/init.js";
20
21
  import { runAgentContextInit } from "./setup/agent-context-init.js";
22
+ import { printSessionCheck, printSessionRepair, runSessionCheck, runSessionRepair, } from "./setup/session-health.js";
21
23
  import { runSeatCommand } from "./commands/seat-cli.js";
22
24
  import { coordCommand } from "./commands/coord-cli.js";
23
25
  function parseArgs(argv) {
24
26
  const profileFlag = [];
25
27
  const rest = [];
28
+ let agentsHelp = false;
26
29
  for (let i = 0; i < argv.length; i++) {
27
30
  const a = argv[i];
28
31
  if (a === "--profile" || a === "-p") {
@@ -32,31 +35,91 @@ function parseArgs(argv) {
32
35
  profileFlag.push(v);
33
36
  continue;
34
37
  }
38
+ if (a === "--agents" || a === "--agent-help") {
39
+ agentsHelp = true;
40
+ continue;
41
+ }
35
42
  rest.push(a);
36
43
  }
37
- return { profile: profileFlag[0], rest };
44
+ return { profile: profileFlag[0], rest, agentsHelp };
38
45
  }
39
46
  /** Profile yaml + mesh-agents.json layout overrides (yaml is fallback only). */
40
47
  function meshLoaded(profileArg) {
41
48
  return applyMeshState(loadProfile(profileArg));
42
49
  }
50
+ /** Operator-facing help — human/session verbs only (default `seatmesh help`). */
51
+ function usageHuman(loaded) {
52
+ const prof = loaded ? `profile=${loaded.profile.name}` : "";
53
+ console.log(`seatmesh${prof ? ` (${prof})` : ""} — operator CLI (human surface)
54
+
55
+ Docs: README.md + docs/QUICKSTART.md · full agent+human list: seatmesh --agents help
56
+
57
+ Setup
58
+ start | run | init | install | update | version
59
+ session attach|up|down|status|sync|init <sm-name>
60
+ sessions [list|attach|forget|register]
61
+
62
+ Put an agent on a pane
63
+ help human ← cheat sheet (aliases: put-agent | panes)
64
+ switch <target> <opencode|oc-proxy|claude|agent|kiro|empty>
65
+ launch <target|all>
66
+ kind <target>
67
+
68
+ Work / status
69
+ todo give <target> "…" | todo <target> "…" | assign <target> "…"
70
+ todo list [target] | todo check <target> "…"
71
+ target add|list|done|triage
72
+ report | verify | test | save|auto | inbox […] | labels
73
+
74
+ Session shape
75
+ reload [--layout] | layout […] | realign | ops list|clear
76
+
77
+ Agent panes use the gateway (not listed here by default):
78
+ seatmesh agent … · seatmesh agent help
79
+ seatmesh --agents help · show human + agent + shared verbs
80
+
81
+ --profile <dir|yaml> optional; default walk-up .sm/
82
+ `);
83
+ }
84
+ /** Full help — human + agent + shared (`seatmesh --agents help`). */
43
85
  function usage(loaded) {
44
86
  const prof = loaded ? `profile=${loaded.profile.name}` : "";
45
87
  console.log(`seatmesh${prof ? ` (${prof})` : ""} — profile-driven tmux multi-agent CLI
46
88
 
47
89
  Docs: README.md + docs/ONE-PATH.md + docs/QUICKSTART.md
48
90
  Cold start: bin/seatmesh auto-runs npm install + build when dist is stale
91
+ Default operator help (human-only): seatmesh help · this list: seatmesh --agents help
49
92
 
50
93
  Setup (run once per project, by a human)
51
94
  start ONE command: init if needed + create-or-attach session (fresh or existing)
95
+ run logs-window left pane: status line → interactive $SHELL (npx seatmesh run)
52
96
  init [--force] [--seats-root PATH] [--name NAME] create .sm/ dotdir only
53
97
  session init <sm-name> [--force] [--name NAME] create .sm-<name>/ (multi-config)
54
98
  sessions [list|attach|forget|register] [--json] global registry + TUI picker (all meshes)
99
+ install [--bin DIR] [--force] symlink tracked bin/sm + seatmesh → ~/.local/bin
55
100
  update [--dry-run] [--migrate] [--no-restart-inbox]
56
- refresh _vendor (file-by-file) + role-pack migrate + paths.json
101
+ 1) npm i -g seatmesh@latest 2) refresh .sm/_vendor
102
+ config check | config upgrade validate yaml · how to bump CLI (npm i -g)
103
+ web status|open|url | open-web operator hub :3190 (parity with packages/web)
57
104
  roles status|migrate [--to VER]|steps locked role-pack up/down (1.1.x)
58
105
  version [--json] [--check-registry] CLI vs npm latest vs profile .seatmesh-version
59
106
 
107
+ Put an agent on a pane (human — most common)
108
+ help human ← full cheat sheet (aliases: put-agent | panes)
109
+ switch <target> <opencode|oc-proxy|claude|agent|kiro> empty shell → agent CLI
110
+ switch <target> empty agent → plain shell
111
+ launch <target|all> resume configured CLI (no type pick)
112
+ pane resume [target] autodetect session id → resume/relaunch
113
+ kind <target> agent vs terminal?
114
+ Examples: switch slot-1 opencode · switch secretary oc-proxy · pane resume here
115
+
116
+ Give a seat a todo (human or base agent — contracts optional)
117
+ todo give <target> "…" ← FOCUS+TASK+inject+CB≥20m (preferred)
118
+ todo <target> "…" ← same shorthand
119
+ assign <target> "…" ← same engine
120
+ todo list [target] | todo check <target> "…"
121
+ Examples: todo give slot-1 "fix login" · agent todo mini-2 "draft README"
122
+
60
123
  Status / diagnostics
61
124
  report [--json] [--verbose] stack status (one line default; --verbose = full section dump)
62
125
  verify layout + labels health
@@ -78,35 +141,48 @@ Agent runtime (pane — always via gateway)
78
141
  agent scoped can/cannot for this pane
79
142
  agent <cmd> … run <cmd> if allowed; else UNAUTHORIZED
80
143
  agent context [roles|init] registered read_first/files; init scaffolds .sm
81
- agent apply|preflight … contract apply
144
+ agent contract [status|on|off|open] simple locks (prefer over apply)
145
+ agent apply|preflight … legacy multi-clause DSL
82
146
 
83
147
  Shared/operator (outside agent — humans + session ops)
84
- session | update | init | report | test | layout | save | inbox restart | target …
148
+ run | session | update | init | report | test | layout | save | inbox restart | target …
85
149
 
86
- Examples: agent whoami | agent kind slot-1 | agent peer <t> "<msg>" | agent ack <id> "<note>" | agent cb list
150
+ Examples: switch slot-1 opencode | agent whoami | agent help peer | agent hub | agent kind slot-1
151
+ Discover: help human # put agent on pane · help <cmd> · agent help <cmd> · <cmd> --help
152
+ Tab complete: eval "$(seatmesh completion zsh)" # or bash|fish; see: completion install
87
153
  Operator EOD: target add "finish s13 tickets" [--deadline eod|6h] · target list · target done <id> · target triage <id>
88
154
 
89
155
  --profile <dir|yaml> optional; default walk-up .sm/; multi-config: --profile .sm-<name>
156
+ --agents with help: show this full human+agent surface (default help is human-only)
90
157
  `);
91
158
  }
92
- function printPlainUsage(profileArg) {
159
+ function printPlainUsage(profileArg, agentsHelp = false) {
160
+ const print = agentsHelp ? usage : usageHuman;
93
161
  if (profileArg) {
94
162
  try {
95
- usage(meshLoaded(profileArg));
163
+ print(meshLoaded(profileArg));
96
164
  return;
97
165
  }
98
166
  catch {
99
167
  /* fall through — plain help without profile load */
100
168
  }
101
169
  }
102
- usage();
170
+ print();
103
171
  }
104
172
  async function main() {
105
- const { profile: profileArg, rest } = parseArgs(process.argv.slice(2));
173
+ const { profile: profileArg, rest, agentsHelp } = parseArgs(process.argv.slice(2));
106
174
  const [cmd, sub, ...tail] = rest;
107
175
  // Bare `npx seatmesh` / help: logo+version once per terminal; later invocations plain usage.
176
+ // `help <cmd>` → per-command usage (agents: `agent help <cmd>`).
177
+ // Default help = human-only; `--agents help` = full human+agent surface.
108
178
  const helpCmd = cmd === "-h" || cmd === "--help" || cmd === "help";
109
179
  const blankCmd = !cmd || (cmd.startsWith("-") && !helpCmd);
180
+ if (helpCmd && cmd === "help" && sub && sub !== "--agents") {
181
+ const { printCmdHelp } = await import("./commands/help-text.js");
182
+ if (!printCmdHelp(sub))
183
+ process.exit(2);
184
+ return;
185
+ }
110
186
  if (blankCmd || helpCmd) {
111
187
  const { printSeatmeshBanner } = await import("./ui/banner.js");
112
188
  const { formatHelpVersionBlock, installKindLabel, readInstalledCliVersion, resolveLatestRegistryVersion, } = await import("./ui/version-nudge.js");
@@ -119,17 +195,63 @@ async function main() {
119
195
  }
120
196
  console.log("");
121
197
  }
122
- printPlainUsage(profileArg);
198
+ printPlainUsage(profileArg, agentsHelp);
199
+ const { printGlobalHelpHint } = await import("./commands/help-text.js");
200
+ printGlobalHelpHint(agentsHelp);
123
201
  return;
124
202
  }
203
+ // Per-command --help / `cmd help` — never execute the verb (no launch/reload/whoami side effects).
204
+ if (cmd !== "agent") {
205
+ const { wantsCmdHelp, printCmdHelp } = await import("./commands/help-text.js");
206
+ if (wantsCmdHelp(rest)) {
207
+ if (!printCmdHelp(cmd))
208
+ process.exit(2);
209
+ return;
210
+ }
211
+ }
212
+ // Universal shorthands (all agents): ask/msg/tell → peer; ackmsg → peer --ack; reply → ack reply
213
+ if (cmd === "ask" ||
214
+ cmd === "msg" ||
215
+ cmd === "tell" ||
216
+ cmd === "ackmsg" ||
217
+ cmd === "answered" ||
218
+ cmd === "reply") {
219
+ const { expandAgentShorthand } = await import("./commands/agent-shorthand.js");
220
+ const args = [sub, ...tail].filter((a) => a != null && a !== "");
221
+ try {
222
+ const { argvRest, label } = expandAgentShorthand(cmd, args);
223
+ console.error(`shorthand: ${label}`);
224
+ const bin = process.argv[0];
225
+ const script = process.argv[1];
226
+ // Preserve --profile if present in original argv
227
+ const profileIdx = process.argv.indexOf("--profile");
228
+ const profileArgs = profileIdx >= 0 && process.argv[profileIdx + 1]
229
+ ? ["--profile", process.argv[profileIdx + 1]]
230
+ : process.argv.some((a) => a.startsWith("--profile="))
231
+ ? [process.argv.find((a) => a.startsWith("--profile="))]
232
+ : [];
233
+ process.argv = [bin, script, ...profileArgs, ...argvRest];
234
+ return main();
235
+ }
236
+ catch (e) {
237
+ console.error(e.message);
238
+ process.exit(2);
239
+ }
240
+ }
125
241
  const { maybePrintVersionNudge } = await import("./ui/version-nudge.js");
126
242
  // Attach/session picker must not wait on npm view — operator is trying to get into tmux.
127
243
  const skipNudge = process.env.SEATMESH_SKIP_VERSION_CHECK === "1" ||
128
244
  cmd === "session" ||
129
245
  cmd === "sessions" ||
130
- cmd === "start";
246
+ cmd === "start" ||
247
+ cmd === "completion";
131
248
  if (!skipNudge)
132
249
  maybePrintVersionNudge();
250
+ if (cmd === "completion") {
251
+ const { runCompletionCommand } = await import("./commands/completion.js");
252
+ runCompletionCommand([sub, ...tail].filter((a) => a != null));
253
+ return;
254
+ }
133
255
  if (cmd === "version") {
134
256
  const { printVersionInfo } = await import("./ui/version-nudge.js");
135
257
  let profileDir;
@@ -146,6 +268,20 @@ async function main() {
146
268
  });
147
269
  return;
148
270
  }
271
+ if (cmd === "install") {
272
+ const { runInstall, defaultInstallBinDir } = await import("./setup/install.js");
273
+ let binDir = defaultInstallBinDir();
274
+ const force = rest.includes("--force");
275
+ for (let i = 0; i < rest.length; i++) {
276
+ if (rest[i] === "--bin" && rest[i + 1]) {
277
+ binDir = rest[++i];
278
+ }
279
+ }
280
+ const r = runInstall({ binDir, force });
281
+ console.log(`OK: install ${r.created ? "linked" : "already linked"} ${r.link} -> ${r.target}`);
282
+ console.log(` bin dir: ${r.binDir} (ensure it is on PATH)`);
283
+ return;
284
+ }
149
285
  if (cmd === "update") {
150
286
  const { runUpdate } = await import("./setup/update.js");
151
287
  const { formatInstallStatusLine, isNpxEphemeralInstall, readInstalledCliVersion, resolveLatestRegistryVersion, semverLess, } = await import("./ui/version-nudge.js");
@@ -154,9 +290,20 @@ async function main() {
154
290
  const noRestartInbox = rest.includes("--no-restart-inbox");
155
291
  const installed = readInstalledCliVersion();
156
292
  const npmLatest = resolveLatestRegistryVersion(true);
293
+ // Lead with CLI upgrade — most users think "update" means bump the package.
294
+ console.log("seatmesh update — two steps");
295
+ console.log(" 1) CLI package (do this first if you want npm latest):");
296
+ console.log(" npm install -g seatmesh@latest");
297
+ console.log(" # or: npx seatmesh@latest update");
298
+ console.log(" 2) This command: refresh .sm/_vendor + config merge from the CLI you ran");
299
+ console.log(" (see also: seatmesh config upgrade)");
300
+ console.log("");
157
301
  console.log(formatInstallStatusLine(installed, npmLatest));
302
+ if (npmLatest && semverLess(installed, npmLatest)) {
303
+ console.error(` WARN: CLI ${installed} < npm ${npmLatest} — step 1 first, then re-run update`);
304
+ }
158
305
  const r = runUpdate({ profileArg, dryRun, migrate });
159
- console.log(`OK: update dryRun=${dryRun} migrate=${migrate}`);
306
+ console.log(`OK: profile update dryRun=${dryRun} migrate=${migrate}`);
160
307
  console.log(` CLI running: ${r.packageVersion}`);
161
308
  if (r.previousVersion != null) {
162
309
  console.log(` profile .seatmesh-version: ${r.previousVersion} (last profile update — not npm "installed")`);
@@ -166,9 +313,6 @@ async function main() {
166
313
  }
167
314
  if (npmLatest)
168
315
  console.log(` npm latest: ${npmLatest}`);
169
- if (npmLatest && semverLess(installed, npmLatest)) {
170
- console.error(` WARN: CLI ${installed} < npm ${npmLatest} — upgrade: npm install -g seatmesh@latest or npx seatmesh@latest update`);
171
- }
172
316
  console.log(` paths: ${r.pathsManifest}`);
173
317
  for (const line of r.refreshed)
174
318
  console.log(` refreshed: ${line}`);
@@ -184,8 +328,12 @@ async function main() {
184
328
  console.log(` role-pack: ${r.rolePack.direction} ${r.rolePack.from ?? "none"} → ${r.rolePack.to}` +
185
329
  (r.rolePack.steps.length ? ` [${r.rolePack.steps.join(",")}]` : ""));
186
330
  }
331
+ if (r.configMerge?.added.length) {
332
+ console.log(` config-merge: ${r.configMerge.added.join(", ")}` +
333
+ (dryRun ? " (dry-run)" : ""));
334
+ }
187
335
  if (isNpxEphemeralInstall()) {
188
- console.log(" note: npx cache CLI — profile vendor updated only; npm package is re-fetched each npx run");
336
+ console.log(" note: npx cache CLI — profile vendor updated only; use npm i -g seatmesh@latest to pin a global bin");
189
337
  }
190
338
  if (!dryRun && !noRestartInbox) {
191
339
  const loaded = meshLoaded(profileArg);
@@ -261,6 +409,20 @@ async function main() {
261
409
  sessionAttach(loaded);
262
410
  return;
263
411
  }
412
+ if (cmd === "run") {
413
+ // Logs window left pane: one-liner status, then plain interactive shell.
414
+ const loaded = meshLoaded(profileArg);
415
+ const port = meshInboxPort(loaded);
416
+ console.log(`seatmesh run · session=${loaded.sessionName} · workspace=${loaded.workspace} · inbox=:${port}`);
417
+ console.log(`tips: seatmesh agent · seatmesh report · seatmesh inbox · seatmesh help`);
418
+ const shell = process.env.SHELL || "/bin/bash";
419
+ const r = spawnSync(shell, ["-l"], {
420
+ cwd: loaded.workspace,
421
+ stdio: "inherit",
422
+ env: process.env,
423
+ });
424
+ process.exit(typeof r.status === "number" ? r.status : 1);
425
+ }
264
426
  if (cmd === "init") {
265
427
  const force = rest.includes("--force");
266
428
  const seatsIdx = rest.indexOf("--seats-root");
@@ -284,9 +446,65 @@ async function main() {
284
446
  return;
285
447
  }
286
448
  if (cmd === "sessions") {
287
- const { runSessionsCommand } = await import("./commands/sessions-cli.js");
449
+ const { runSessionsCommand, printAgentSessionsList } = await import("./commands/sessions-cli.js");
450
+ // After `agent sessions` strip: only list/json — never attach/pick/forget/register.
451
+ const fromAgent = process.env.SEATMESH_AGENT_GATEWAY === "1";
452
+ if (fromAgent) {
453
+ const action = (sub ?? "list").toLowerCase();
454
+ if (["attach", "forget", "register", "pick", "add"].includes(action)) {
455
+ console.error(`UNAUTHORIZED: sessions ${action} is operator-only — run without agent: seatmesh sessions ${action} …`);
456
+ console.error("hint: seatmesh agent sessions # list other meshes");
457
+ console.error('hint: seatmesh agent peer @pia:secretary "…" # cross-mesh');
458
+ process.exit(2);
459
+ }
460
+ const loaded = meshLoaded(profileArg);
461
+ await printAgentSessionsList(loaded, { json: rest.includes("--json") || tail.includes("--json") });
462
+ return;
463
+ }
288
464
  process.exit(await runSessionsCommand(sub, tail, profileArg));
289
465
  }
466
+ if (cmd === "remote" || cmd === "meshes") {
467
+ const loaded = meshLoaded(profileArg);
468
+ const { printAgentSessionsList } = await import("./commands/sessions-cli.js");
469
+ const json = rest.includes("--json") || sub === "--json";
470
+ // bare / list / --json → discover
471
+ if (!sub || sub === "list" || sub === "--json" || sub === "-h" || sub === "--help") {
472
+ if (sub === "-h" || sub === "--help") {
473
+ const { printCmdHelp } = await import("./commands/help-text.js");
474
+ printCmdHelp("remote");
475
+ return;
476
+ }
477
+ await printAgentSessionsList(loaded, { json });
478
+ return;
479
+ }
480
+ // remote @alias:seat <msg...>
481
+ const atTarget = parseRemotePeerTarget(sub);
482
+ if (atTarget) {
483
+ const rawMsg = [...tail].join(" ").trim();
484
+ if (!rawMsg) {
485
+ console.error('usage: remote @alias:seat "<msg>"');
486
+ process.exit(2);
487
+ }
488
+ runRemotePeer(loaded, atTarget.alias, atTarget.seat, rawMsg);
489
+ return;
490
+ }
491
+ // remote <alias> <seat> <msg...>
492
+ const alias = sub.replace(/^@/, "");
493
+ const seat = tail[0];
494
+ const rawMsg = tail.slice(1).join(" ").trim();
495
+ if (!seat || !rawMsg) {
496
+ console.error('usage: remote <alias> <seat> "<msg>"');
497
+ console.error(' or: remote @alias:seat "<msg>"');
498
+ console.error(" or: remote [--json] # list meshes");
499
+ process.exit(2);
500
+ }
501
+ if (!/^[a-z][a-z0-9-]{0,31}$/i.test(alias) || !/^[a-z][a-z0-9-]{0,31}$/i.test(seat)) {
502
+ console.error(`bad remote target: ${alias} ${seat} (want alias seat, e.g. pia secretary)`);
503
+ process.exit(2);
504
+ }
505
+ runRemotePeer(loaded, alias.toLowerCase(), seat.toLowerCase(), rawMsg);
506
+ return;
507
+ }
290
508
  if (cmd === "profile" && sub === "show") {
291
509
  const loaded = meshLoaded(profileArg);
292
510
  const paths = profilePaths(loaded);
@@ -372,9 +590,52 @@ async function main() {
372
590
  sessionStatus(loaded);
373
591
  return;
374
592
  }
375
- console.error("usage: session attach|up|down|status|sync|init <sm-name>");
593
+ if (sub === "check") {
594
+ const r = runSessionCheck(loaded);
595
+ printSessionCheck(r);
596
+ process.exit(r.ok ? 0 : 1);
597
+ }
598
+ if (sub === "repair") {
599
+ const noSync = tail.includes("--no-sync");
600
+ const skipInbox = tail.includes("--no-inbox");
601
+ const r = runSessionRepair(loaded, { sync: !noSync, skipInbox });
602
+ printSessionRepair(r);
603
+ process.exit(r.check.ok ? 0 : 1);
604
+ }
605
+ console.error("usage: session attach|up|down|status|sync|check|repair|init <sm-name>");
376
606
  process.exit(2);
377
607
  }
608
+ if (cmd === "config") {
609
+ const { runConfigCheck, printConfigHelp, printConfigUpgradeGuide } = await import("./commands/config-cli.js");
610
+ const json = rest.includes("--json") || sub === "--json" || tail.includes("--json");
611
+ if (!sub || sub === "help" || sub === "-h" || sub === "--help") {
612
+ printConfigHelp();
613
+ return;
614
+ }
615
+ if (sub === "check") {
616
+ process.exit(runConfigCheck(profileArg, { json }));
617
+ }
618
+ if (sub === "upgrade" || sub === "up") {
619
+ printConfigUpgradeGuide();
620
+ return;
621
+ }
622
+ console.error("usage: config check [--json] | config upgrade");
623
+ process.exit(2);
624
+ }
625
+ if (cmd === "tp") {
626
+ const loaded = meshLoaded(profileArg);
627
+ const { runTpCommand } = await import("./commands/tp-cli.js");
628
+ await runTpCommand(loaded, sub, tail);
629
+ return;
630
+ }
631
+ if (cmd === "web" || cmd === "open-web") {
632
+ const loaded = meshLoaded(profileArg);
633
+ const { runWebCommand, runWebOpen } = await import("./commands/web-cli.js");
634
+ if (cmd === "open-web") {
635
+ process.exit(runWebOpen(sub));
636
+ }
637
+ process.exit(await runWebCommand(loaded, sub, tail));
638
+ }
378
639
  if (cmd === "verify") {
379
640
  const loaded = meshLoaded(profileArg);
380
641
  ensureMeshInbox(loaded, { quiet: true });
@@ -620,12 +881,13 @@ async function main() {
620
881
  }
621
882
  if (cmd === "peer") {
622
883
  const loaded = meshLoaded(profileArg);
884
+ const redirDefaults = resolveAckRedirectDefaults(loaded);
623
885
  let direct = false;
624
886
  let endedId;
625
887
  let redirectFrom;
626
- let redirectBlock = "*managers";
627
- let redirectTo = "secretary";
628
- let redirectTtlMin = 45;
888
+ let redirectBlock = redirDefaults.block;
889
+ let redirectTo = redirDefaults.rewriteTo;
890
+ let redirectTtlMin = redirDefaults.ttlMin;
629
891
  const args = [];
630
892
  const rawArgs = [sub, ...tail].filter((x) => x != null && x !== "");
631
893
  for (let i = 0; i < rawArgs.length; i++) {
@@ -637,8 +899,9 @@ async function main() {
637
899
  if (a === "--ended" || a === "--ack") {
638
900
  const id = rawArgs[i + 1];
639
901
  if (!id || id.startsWith("-")) {
640
- console.error("usage: peer … --ended <ack-id>");
641
- process.exit(2);
902
+ // Bare --ack / --ended: auto-pick open ACK for this peer target.
903
+ endedId = "__auto__";
904
+ continue;
642
905
  }
643
906
  endedId = id;
644
907
  i++;
@@ -682,7 +945,7 @@ async function main() {
682
945
  console.error("usage: peer … --redirect-ttl <minutes>");
683
946
  process.exit(2);
684
947
  }
685
- redirectTtlMin = Number(v) || 45;
948
+ redirectTtlMin = Number(v) || redirDefaults.ttlMin;
686
949
  i++;
687
950
  continue;
688
951
  }
@@ -700,9 +963,32 @@ async function main() {
700
963
  const [target, ...textParts] = args;
701
964
  const rawMsg = textParts.join(" ").trim();
702
965
  if (!target || !rawMsg) {
703
- console.error("usage: peer verify [target] | peer [--direct] [--ended <ack-id>] [--redirect-from <seat>] <manager|secretary|slot-N|mini-N|@alias:seat|pane> <msg...>");
966
+ console.error("usage: peer verify [target] | peer [--direct] [--ended|--ack [ack-id]] [--redirect-from <seat>] <target> <msg...>\n" +
967
+ " --ack / --ended [id] close open ask (id optional = auto-match from target)\n" +
968
+ " ack-class msg (ACK/FYI/PASS) auto-closes matching open ask\n" +
969
+ " or: agent ack reply <id> [msg] (peer back + close in one shot)");
704
970
  process.exit(2);
705
971
  }
972
+ if (shouldAutoAckReply(rawMsg, endedId)) {
973
+ endedId = "__auto__";
974
+ }
975
+ try {
976
+ const resolvedEnded = await resolvePeerEndedAckId(loaded, target, endedId);
977
+ endedId = resolvedEnded;
978
+ }
979
+ catch (e) {
980
+ if (endedId === "__auto__") {
981
+ console.error(`WARN: --ack auto: ${e.message}`);
982
+ endedId = undefined;
983
+ }
984
+ else {
985
+ throw e;
986
+ }
987
+ }
988
+ if (endedId === "__auto__") {
989
+ console.error(`WARN: --ack auto: no open ask matching ${target} — peer sent without close`);
990
+ endedId = undefined;
991
+ }
706
992
  const armRedirect = async (fromSeat, reason) => {
707
993
  const cfg = chatRoomConfigForLoaded(loaded);
708
994
  try {
@@ -905,6 +1191,7 @@ async function main() {
905
1191
  "claude",
906
1192
  "kiro",
907
1193
  "opencode",
1194
+ "oc-proxy",
908
1195
  "cursor-agent",
909
1196
  "oc",
910
1197
  "cursor",
@@ -936,7 +1223,10 @@ async function main() {
936
1223
  saveMeshSession(loaded, reg);
937
1224
  return;
938
1225
  }
939
- secretaryRestart(loaded, reg, typeArg, fresh);
1226
+ runSwitch(loaded, reg, "secretary", typeArg ?? defaultHarnessTypeForSeat(loaded, "secretary"), {
1227
+ fresh,
1228
+ reason: fresh ? "restart-fresh" : "restart",
1229
+ });
940
1230
  saveMeshSession(loaded, reg);
941
1231
  return;
942
1232
  }
@@ -1035,16 +1325,59 @@ async function main() {
1035
1325
  }
1036
1326
  return;
1037
1327
  }
1328
+ if (cmd === "pane") {
1329
+ const loaded = meshLoaded(profileArg);
1330
+ const reg = createRegistryForProfile(loaded.profile);
1331
+ const action = sub ?? "help";
1332
+ if (action === "help" || action === "-h" || action === "--help") {
1333
+ console.log(`pane — pane helpers (operator)
1334
+
1335
+ pane resume [target] autodetect session id on pane → resume / relaunch
1336
+ Targets: here (default) | secretary | manager | slot-N | mini-N
1337
+
1338
+ Live OpenCode: pastes resume [ses_…]
1339
+ Shell / dead OC: relaunches oc-proxy|opencode|claude with that session`);
1340
+ return;
1341
+ }
1342
+ if (action === "resume") {
1343
+ requireCoordRole(loaded, "pane resume");
1344
+ const target = tail.find((t) => !t.startsWith("-")) ?? "here";
1345
+ try {
1346
+ const r = runPaneResume(loaded, reg, target);
1347
+ if (!r.ok) {
1348
+ console.error(`FAIL: pane resume ${r.target} pane=${r.paneId}: ${r.detail}`);
1349
+ process.exit(1);
1350
+ }
1351
+ console.log(`OK: pane resume ${r.mode} ${r.target} pane=${r.paneId} session=${r.sessionId} ${r.harnessType} — ${r.detail}`);
1352
+ if (r.mode === "relaunch")
1353
+ saveMeshSession(loaded, reg);
1354
+ }
1355
+ catch (e) {
1356
+ console.error(e.message);
1357
+ process.exit(1);
1358
+ }
1359
+ return;
1360
+ }
1361
+ console.error(`usage: pane resume [target]\n unknown: pane ${action}`);
1362
+ process.exit(2);
1363
+ }
1038
1364
  if (cmd === "ppa") {
1039
1365
  const loaded = meshLoaded(profileArg);
1040
1366
  const reg = createRegistryForProfile(loaded.profile);
1041
- const ppaSub = sub ?? "perf-index";
1042
- if (ppaSub !== "perf-index" && ppaSub !== "index") {
1043
- console.error("usage: ppa [perf-index]");
1044
- process.exit(2);
1367
+ const args = [sub, ...tail].filter((a) => Boolean(a));
1368
+ const raw = args.includes("--raw") || args.includes("perf-index") || args.includes("index");
1369
+ const idleIdx = args.findIndex((a) => a === "--idle" || a === "--idle-sec");
1370
+ const idleSec = idleIdx >= 0 && args[idleIdx + 1] ? Number.parseInt(args[idleIdx + 1], 10) : undefined;
1371
+ if (args.some((a) => a === "-h" || a === "--help" || a === "help")) {
1372
+ const { printCmdHelp } = await import("./commands/help-text.js");
1373
+ printCmdHelp("ppa");
1374
+ return;
1045
1375
  }
1046
1376
  try {
1047
- runPpa(loaded, reg);
1377
+ runPpa(loaded, reg, {
1378
+ raw,
1379
+ idleSec: idleSec != null && Number.isFinite(idleSec) ? idleSec : undefined,
1380
+ });
1048
1381
  }
1049
1382
  catch (e) {
1050
1383
  console.error(e.message);
@@ -1057,6 +1390,19 @@ async function main() {
1057
1390
  printSeatContexts(loaded, rest.includes("--json"));
1058
1391
  return;
1059
1392
  }
1393
+ if (cmd === "hub" || cmd === "get") {
1394
+ const loaded = meshLoaded(profileArg);
1395
+ await runAgentHub(loaded, [sub, ...tail].filter((x) => x != null && x !== ""));
1396
+ return;
1397
+ }
1398
+ // Discoverable aliases — no literal "read-history" existed; map to chat + room tip.
1399
+ if (cmd === "read-history" || cmd === "history" || cmd === "readhistory") {
1400
+ const loaded = meshLoaded(profileArg);
1401
+ const extra = [sub, ...tail].filter((x) => x != null && x !== "");
1402
+ await runAgentHub(loaded, ["chat", ...extra]);
1403
+ console.log("also: seatmesh agent room tail [-r slug] [-n N] · hub room");
1404
+ return;
1405
+ }
1060
1406
  if (cmd === "cold-start" || cmd === "coldstart") {
1061
1407
  const loaded = meshLoaded(profileArg);
1062
1408
  const inject = rest.includes("--inject");
@@ -1093,6 +1439,11 @@ async function main() {
1093
1439
  runSeatCommand(loaded, [sub, ...tail]);
1094
1440
  return;
1095
1441
  }
1442
+ if (cmd === "todo" || cmd === "todos") {
1443
+ const loaded = meshLoaded(profileArg);
1444
+ runSeatCommand(loaded, ["task", ...(sub ? [sub, ...tail] : tail)]);
1445
+ return;
1446
+ }
1096
1447
  if (cmd === "test") {
1097
1448
  const loaded = meshLoaded(profileArg);
1098
1449
  ensureMeshInbox(loaded, { quiet: true });
@@ -1161,6 +1512,7 @@ async function main() {
1161
1512
  manager,
1162
1513
  });
1163
1514
  console.log(`SENT: prompt -> ${targetLabel} pane=${paneId} token=${token ?? "-"} via=${via ?? "pane-row"}`);
1515
+ console.log('hint: prefer `todo give` (work) or `ask`/`msg`/`peer` (comms) over bare `prompt`');
1164
1516
  return;
1165
1517
  }
1166
1518
  if (cmd === "remind") {
@@ -1306,6 +1658,28 @@ async function main() {
1306
1658
  }
1307
1659
  return;
1308
1660
  }
1661
+ if (cmd === "swap") {
1662
+ const loaded = meshLoaded(profileArg);
1663
+ requireCoordRole(loaded, "swap");
1664
+ const a = sub;
1665
+ const b = tail.find((t) => !t.startsWith("-"));
1666
+ if (!a || !b) {
1667
+ console.error("usage: swap <slot-A|mini-A> <slot-B|mini-B> [--identity]\n" +
1668
+ " default: visual tmux swap-pane (session data stays with each agent)\n" +
1669
+ " --identity: exchange numbers + seat dirs + mesh-agents (peer addresses swap)");
1670
+ process.exit(2);
1671
+ }
1672
+ const identity = tail.includes("--identity");
1673
+ try {
1674
+ const result = runSeatSwap(loaded, a, b, { identity });
1675
+ console.log(`OK: swap ${result.mode} ${result.a} ↔ ${result.b} (${result.paneA} ↔ ${result.paneB})`);
1676
+ }
1677
+ catch (e) {
1678
+ console.error(e.message);
1679
+ process.exit(1);
1680
+ }
1681
+ return;
1682
+ }
1309
1683
  if (cmd === "report") {
1310
1684
  const loaded = meshLoaded(profileArg);
1311
1685
  const { printStatusReport } = await import("./report/status-report.js");
@@ -1374,7 +1748,35 @@ async function main() {
1374
1748
  if (cmd === "agent") {
1375
1749
  const loaded = meshLoaded(profileArg);
1376
1750
  const reg = createRegistryForProfile(loaded.profile);
1751
+ // agent help / agent --help — never UNAUTHORIZED; teach the card + per-cmd usage.
1752
+ if (!sub ||
1753
+ sub === "help" ||
1754
+ sub === "-h" ||
1755
+ sub === "--help") {
1756
+ if (sub === "help" && tail[0] && !tail[0].startsWith("-")) {
1757
+ const { printCmdHelp } = await import("./commands/help-text.js");
1758
+ if (!printCmdHelp(tail[0]))
1759
+ process.exit(2);
1760
+ return;
1761
+ }
1762
+ if (sub === "help" || sub === "-h" || sub === "--help") {
1763
+ const { printAgentHelpIndex } = await import("./commands/help-text.js");
1764
+ printAgentHelpIndex();
1765
+ const w = runWhoami(loaded, "here");
1766
+ printAgentCard(w);
1767
+ return;
1768
+ }
1769
+ // bare `agent` — card only (+ one help hint)
1770
+ const w = runWhoami(loaded, "here");
1771
+ printAgentCard(w);
1772
+ console.log("help=seatmesh agent help <cmd> # usage for one verb");
1773
+ return;
1774
+ }
1377
1775
  if (sub && AGENT_META.has(sub)) {
1776
+ if (sub === "forum" || sub === "golf") {
1777
+ console.log("agent forum/golf — see docs/cli/forum.md (not bundled in this build)");
1778
+ return;
1779
+ }
1378
1780
  if (sub === "apply") {
1379
1781
  const { bundle, opts } = parseAgentApplyArgs(tail);
1380
1782
  applyAgentContractBundle(loaded, reg, bundle, opts);
@@ -1409,6 +1811,7 @@ async function main() {
1409
1811
  printAgentUnauthorized(decision);
1410
1812
  process.exit(2);
1411
1813
  }
1814
+ process.env.SEATMESH_AGENT_GATEWAY = "1";
1412
1815
  process.argv = stripAgentFromArgv(process.argv);
1413
1816
  return main();
1414
1817
  }
@@ -1645,6 +2048,19 @@ async function main() {
1645
2048
  : cmd === "contract"
1646
2049
  ? buildContractLockCommands(getLoaded)
1647
2050
  : buildChatCommands(getLoaded);
2051
+ // contract with no sub → status (simple agent path)
2052
+ if (!sub && cmd === "contract") {
2053
+ try {
2054
+ await branch.parseAsync(["status"], { from: "user" });
2055
+ }
2056
+ catch (e) {
2057
+ const err = e;
2058
+ if (err.code === "commander.helpDisplayed" || err.code === "commander.version")
2059
+ return;
2060
+ throw e;
2061
+ }
2062
+ return;
2063
+ }
1648
2064
  if (!sub) {
1649
2065
  branch.outputHelp();
1650
2066
  return;
@@ -1783,7 +2199,7 @@ async function main() {
1783
2199
  return;
1784
2200
  }
1785
2201
  console.error(`unknown command: ${cmd}`);
1786
- usage();
2202
+ console.error("hint: seatmesh help · seatmesh help human · seatmesh --agents help");
1787
2203
  process.exit(2);
1788
2204
  }
1789
2205
  main().catch((e) => {