tailii-host 0.1.0 → 0.3.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 (348) hide show
  1. package/README.md +35 -14
  2. package/dist/{broker.d.ts → approval/broker.d.ts} +9 -5
  3. package/dist/{broker.js → approval/broker.js} +42 -6
  4. package/dist/approval/broker.js.map +1 -0
  5. package/dist/{hook.d.ts → approval/hook.d.ts} +48 -7
  6. package/dist/{hook.js → approval/hook.js} +359 -50
  7. package/dist/approval/hook.js.map +1 -0
  8. package/dist/backend/herdr.d.ts +226 -0
  9. package/dist/backend/herdr.js +749 -0
  10. package/dist/backend/herdr.js.map +1 -0
  11. package/dist/backend/sessionBackend.d.ts +81 -0
  12. package/dist/backend/sessionBackend.js +114 -0
  13. package/dist/backend/sessionBackend.js.map +1 -0
  14. package/dist/backend/tmux.d.ts +125 -0
  15. package/dist/backend/tmux.js +392 -0
  16. package/dist/backend/tmux.js.map +1 -0
  17. package/dist/{chatTailController.d.ts → chat/chatTailController.d.ts} +29 -6
  18. package/dist/{chatTailController.js → chat/chatTailController.js} +94 -18
  19. package/dist/chat/chatTailController.js.map +1 -0
  20. package/dist/{imageService.d.ts → chat/imageService.d.ts} +12 -1
  21. package/dist/{imageService.js → chat/imageService.js} +39 -11
  22. package/dist/chat/imageService.js.map +1 -0
  23. package/dist/chat/remoteQuestionMonitor.d.ts +27 -0
  24. package/dist/chat/remoteQuestionMonitor.js +128 -0
  25. package/dist/chat/remoteQuestionMonitor.js.map +1 -0
  26. package/dist/chat/subagentTailer.d.ts +30 -0
  27. package/dist/chat/subagentTailer.js +704 -0
  28. package/dist/chat/subagentTailer.js.map +1 -0
  29. package/dist/chat/subagentTranscript.d.ts +20 -0
  30. package/dist/chat/subagentTranscript.js +273 -0
  31. package/dist/chat/subagentTranscript.js.map +1 -0
  32. package/dist/{transcriptTailer.d.ts → chat/transcriptTailer.d.ts} +12 -1
  33. package/dist/{transcriptTailer.js → chat/transcriptTailer.js} +183 -10
  34. package/dist/chat/transcriptTailer.js.map +1 -0
  35. package/dist/cli.js +15 -10
  36. package/dist/cli.js.map +1 -1
  37. package/dist/codex/codexAccountUsage.d.ts +22 -0
  38. package/dist/codex/codexAccountUsage.js +128 -0
  39. package/dist/codex/codexAccountUsage.js.map +1 -0
  40. package/dist/codex/codexAppServer.d.ts +166 -0
  41. package/dist/codex/codexAppServer.js +1297 -0
  42. package/dist/codex/codexAppServer.js.map +1 -0
  43. package/dist/codex/codexNativeTurnController.d.ts +153 -0
  44. package/dist/codex/codexNativeTurnController.js +673 -0
  45. package/dist/codex/codexNativeTurnController.js.map +1 -0
  46. package/dist/codex/codexRolloutTailer.d.ts +100 -0
  47. package/dist/codex/codexRolloutTailer.js +568 -0
  48. package/dist/codex/codexRolloutTailer.js.map +1 -0
  49. package/dist/{codexSessionStore.d.ts → codex/codexSessionStore.d.ts} +10 -2
  50. package/dist/{codexSessionStore.js → codex/codexSessionStore.js} +184 -15
  51. package/dist/codex/codexSessionStore.js.map +1 -0
  52. package/dist/codex/codexSubagentTracker.d.ts +21 -0
  53. package/dist/codex/codexSubagentTracker.js +281 -0
  54. package/dist/codex/codexSubagentTracker.js.map +1 -0
  55. package/dist/codex/codexToolActivity.d.ts +69 -0
  56. package/dist/codex/codexToolActivity.js +425 -0
  57. package/dist/codex/codexToolActivity.js.map +1 -0
  58. package/dist/{codexUsage.d.ts → codex/codexUsage.d.ts} +1 -1
  59. package/dist/{codexUsage.js → codex/codexUsage.js} +19 -26
  60. package/dist/codex/codexUsage.js.map +1 -0
  61. package/dist/commands/doctor.d.ts +65 -0
  62. package/dist/commands/doctor.js +425 -0
  63. package/dist/commands/doctor.js.map +1 -0
  64. package/dist/{hookSettings.d.ts → commands/hookSettings.d.ts} +14 -1
  65. package/dist/{hookSettings.js → commands/hookSettings.js} +96 -12
  66. package/dist/commands/hookSettings.js.map +1 -0
  67. package/dist/{kick.js → commands/kick.js} +16 -1
  68. package/dist/commands/kick.js.map +1 -0
  69. package/dist/{launch.d.ts → commands/launch.d.ts} +67 -5
  70. package/dist/commands/launch.js +716 -0
  71. package/dist/commands/launch.js.map +1 -0
  72. package/dist/commands/legacyHomeMigration.js.map +1 -0
  73. package/dist/{pairingCode.d.ts → commands/pairingCode.d.ts} +29 -2
  74. package/dist/{pairingCode.js → commands/pairingCode.js} +120 -11
  75. package/dist/commands/pairingCode.js.map +1 -0
  76. package/dist/{pushTokenCommand.d.ts → commands/pushTokenCommand.d.ts} +1 -1
  77. package/dist/{pushTokenCommand.js → commands/pushTokenCommand.js} +2 -2
  78. package/dist/commands/pushTokenCommand.js.map +1 -0
  79. package/dist/{setup.d.ts → commands/setup.d.ts} +17 -6
  80. package/dist/{setup.js → commands/setup.js} +133 -75
  81. package/dist/commands/setup.js.map +1 -0
  82. package/dist/engine/context.d.ts +145 -0
  83. package/dist/engine/context.js +184 -0
  84. package/dist/engine/context.js.map +1 -0
  85. package/dist/engine/engine.d.ts +121 -0
  86. package/dist/engine/engine.js +799 -0
  87. package/dist/engine/engine.js.map +1 -0
  88. package/dist/engine/handlers/accountUsage.d.ts +53 -0
  89. package/dist/engine/handlers/accountUsage.js +203 -0
  90. package/dist/engine/handlers/accountUsage.js.map +1 -0
  91. package/dist/engine/handlers/claudeModels.d.ts +2 -0
  92. package/dist/engine/handlers/claudeModels.js +23 -0
  93. package/dist/engine/handlers/claudeModels.js.map +1 -0
  94. package/dist/engine/handlers/codex.d.ts +2 -0
  95. package/dist/engine/handlers/codex.js +97 -0
  96. package/dist/engine/handlers/codex.js.map +1 -0
  97. package/dist/engine/handlers/conversation.d.ts +2 -0
  98. package/dist/engine/handlers/conversation.js +259 -0
  99. package/dist/engine/handlers/conversation.js.map +1 -0
  100. package/dist/engine/handlers/core.d.ts +2 -0
  101. package/dist/engine/handlers/core.js +66 -0
  102. package/dist/engine/handlers/core.js.map +1 -0
  103. package/dist/engine/handlers/git.d.ts +2 -0
  104. package/dist/engine/handlers/git.js +127 -0
  105. package/dist/engine/handlers/git.js.map +1 -0
  106. package/dist/engine/handlers/index.d.ts +2 -0
  107. package/dist/engine/handlers/index.js +32 -0
  108. package/dist/engine/handlers/index.js.map +1 -0
  109. package/dist/engine/handlers/mode.d.ts +2 -0
  110. package/dist/engine/handlers/mode.js +194 -0
  111. package/dist/engine/handlers/mode.js.map +1 -0
  112. package/dist/engine/handlers/officialApps.d.ts +2 -0
  113. package/dist/engine/handlers/officialApps.js +79 -0
  114. package/dist/engine/handlers/officialApps.js.map +1 -0
  115. package/dist/engine/handlers/preview.d.ts +2 -0
  116. package/dist/engine/handlers/preview.js +59 -0
  117. package/dist/engine/handlers/preview.js.map +1 -0
  118. package/dist/engine/handlers/session.d.ts +2 -0
  119. package/dist/engine/handlers/session.js +385 -0
  120. package/dist/engine/handlers/session.js.map +1 -0
  121. package/dist/engine/handlers/usage.d.ts +2 -0
  122. package/dist/engine/handlers/usage.js +96 -0
  123. package/dist/engine/handlers/usage.js.map +1 -0
  124. package/dist/engine/handlers/workspace.d.ts +2 -0
  125. package/dist/engine/handlers/workspace.js +110 -0
  126. package/dist/engine/handlers/workspace.js.map +1 -0
  127. package/dist/engine/slashCommands.d.ts +3 -0
  128. package/dist/engine/slashCommands.js +211 -0
  129. package/dist/engine/slashCommands.js.map +1 -0
  130. package/dist/hub/engineRelaySocket.d.ts +58 -0
  131. package/dist/hub/engineRelaySocket.js +161 -0
  132. package/dist/hub/engineRelaySocket.js.map +1 -0
  133. package/dist/hub/hubClient.d.ts +28 -0
  134. package/dist/hub/hubClient.js +187 -0
  135. package/dist/hub/hubClient.js.map +1 -0
  136. package/dist/hub/hubDaemon.d.ts +69 -0
  137. package/dist/hub/hubDaemon.js +466 -0
  138. package/dist/hub/hubDaemon.js.map +1 -0
  139. package/dist/hub/hubProtocol.d.ts +161 -0
  140. package/dist/hub/hubProtocol.js +379 -0
  141. package/dist/hub/hubProtocol.js.map +1 -0
  142. package/dist/hub/panePreviewPump.d.ts +65 -0
  143. package/dist/hub/panePreviewPump.js +187 -0
  144. package/dist/hub/panePreviewPump.js.map +1 -0
  145. package/dist/hub/questionInjection.d.ts +19 -0
  146. package/dist/hub/questionInjection.js +126 -0
  147. package/dist/hub/questionInjection.js.map +1 -0
  148. package/dist/hub/reaper.d.ts +74 -0
  149. package/dist/hub/reaper.js +333 -0
  150. package/dist/hub/reaper.js.map +1 -0
  151. package/dist/hub/sessionHub.d.ts +203 -0
  152. package/dist/hub/sessionHub.js +1862 -0
  153. package/dist/hub/sessionHub.js.map +1 -0
  154. package/dist/protocol/common.d.ts +18 -0
  155. package/dist/protocol/common.js +78 -0
  156. package/dist/protocol/common.js.map +1 -0
  157. package/dist/protocol/decode.d.ts +3 -0
  158. package/dist/protocol/decode.js +1036 -0
  159. package/dist/protocol/decode.js.map +1 -0
  160. package/dist/protocol/encode.d.ts +3 -0
  161. package/dist/protocol/encode.js +84 -0
  162. package/dist/protocol/encode.js.map +1 -0
  163. package/dist/protocol/messages.d.ts +1002 -0
  164. package/dist/protocol/messages.js +8 -0
  165. package/dist/protocol/messages.js.map +1 -0
  166. package/dist/protocol.d.ts +4 -329
  167. package/dist/protocol.js +13 -531
  168. package/dist/protocol.js.map +1 -1
  169. package/dist/push/apnsConfigStore.js.map +1 -0
  170. package/dist/push/apnsJwtProvider.js.map +1 -0
  171. package/dist/{apnsSender.js.map → push/apnsSender.js.map} +1 -1
  172. package/dist/{approvalPushNotifier.js → push/approvalPushNotifier.js} +1 -1
  173. package/dist/push/approvalPushNotifier.js.map +1 -0
  174. package/dist/push/deviceTokenStore.js.map +1 -0
  175. package/dist/{pushTypes.js → push/pushTypes.js} +1 -1
  176. package/dist/push/pushTypes.js.map +1 -0
  177. package/dist/push/sendLog.js.map +1 -0
  178. package/dist/services/accountIdentity.d.ts +44 -0
  179. package/dist/services/accountIdentity.js +184 -0
  180. package/dist/services/accountIdentity.js.map +1 -0
  181. package/dist/services/claudeCredentialRefresh.d.ts +30 -0
  182. package/dist/services/claudeCredentialRefresh.js +345 -0
  183. package/dist/services/claudeCredentialRefresh.js.map +1 -0
  184. package/dist/services/claudeModelCatalog.d.ts +21 -0
  185. package/dist/services/claudeModelCatalog.js +181 -0
  186. package/dist/services/claudeModelCatalog.js.map +1 -0
  187. package/dist/{dirLister.d.ts → services/dirLister.d.ts} +9 -4
  188. package/dist/services/dirLister.js +169 -0
  189. package/dist/services/dirLister.js.map +1 -0
  190. package/dist/services/fileService.d.ts +10 -0
  191. package/dist/services/fileService.js +123 -0
  192. package/dist/services/fileService.js.map +1 -0
  193. package/dist/services/gitService.d.ts +79 -0
  194. package/dist/services/gitService.js +648 -0
  195. package/dist/services/gitService.js.map +1 -0
  196. package/dist/services/hostVersions.d.ts +38 -0
  197. package/dist/services/hostVersions.js +120 -0
  198. package/dist/services/hostVersions.js.map +1 -0
  199. package/dist/services/officialApps.d.ts +148 -0
  200. package/dist/services/officialApps.js +1079 -0
  201. package/dist/services/officialApps.js.map +1 -0
  202. package/dist/services/planUsageFetcher.d.ts +119 -0
  203. package/dist/services/planUsageFetcher.js +357 -0
  204. package/dist/services/planUsageFetcher.js.map +1 -0
  205. package/dist/services/previewServer.d.ts +31 -0
  206. package/dist/services/previewServer.js +233 -0
  207. package/dist/services/previewServer.js.map +1 -0
  208. package/dist/services/quicGateway.d.ts +143 -0
  209. package/dist/services/quicGateway.js +292 -0
  210. package/dist/services/quicGateway.js.map +1 -0
  211. package/dist/services/serveService.d.ts +50 -0
  212. package/dist/services/serveService.js +302 -0
  213. package/dist/services/serveService.js.map +1 -0
  214. package/dist/services/usageAggregator.js.map +1 -0
  215. package/dist/sessions/claudeSessionStore.d.ts +80 -0
  216. package/dist/sessions/claudeSessionStore.js +477 -0
  217. package/dist/sessions/claudeSessionStore.js.map +1 -0
  218. package/dist/sessions/heartbeat.d.ts +24 -0
  219. package/dist/sessions/heartbeat.js +86 -0
  220. package/dist/sessions/heartbeat.js.map +1 -0
  221. package/dist/sessions/liveSessionJoin.d.ts +20 -0
  222. package/dist/sessions/liveSessionJoin.js +80 -0
  223. package/dist/sessions/liveSessionJoin.js.map +1 -0
  224. package/dist/sessions/sessionActivityProvider.d.ts +14 -0
  225. package/dist/sessions/sessionActivityProvider.js +57 -0
  226. package/dist/sessions/sessionActivityProvider.js.map +1 -0
  227. package/dist/{sessionListService.d.ts → sessions/sessionListService.d.ts} +3 -3
  228. package/dist/{sessionListService.js → sessions/sessionListService.js} +23 -6
  229. package/dist/sessions/sessionListService.js.map +1 -0
  230. package/dist/{sessionMetadataStore.d.ts → sessions/sessionMetadataStore.d.ts} +18 -0
  231. package/dist/{sessionMetadataStore.js → sessions/sessionMetadataStore.js} +36 -1
  232. package/dist/sessions/sessionMetadataStore.js.map +1 -0
  233. package/dist/{sessionSearch.d.ts → sessions/sessionSearch.d.ts} +1 -1
  234. package/dist/sessions/sessionSearch.js.map +1 -0
  235. package/dist/shared/hostDisplayName.d.ts +11 -0
  236. package/dist/shared/hostDisplayName.js +50 -0
  237. package/dist/shared/hostDisplayName.js.map +1 -0
  238. package/dist/{lineWriter.d.ts → shared/lineWriter.d.ts} +1 -1
  239. package/dist/{lineWriter.js → shared/lineWriter.js} +1 -1
  240. package/dist/shared/lineWriter.js.map +1 -0
  241. package/dist/{observationLog.js.map → shared/observationLog.js.map} +1 -1
  242. package/dist/{paths.d.ts → shared/paths.d.ts} +7 -0
  243. package/dist/{paths.js → shared/paths.js} +9 -0
  244. package/dist/shared/paths.js.map +1 -0
  245. package/dist/shared/permissionMode.d.ts +10 -0
  246. package/dist/shared/permissionMode.js +51 -0
  247. package/dist/shared/permissionMode.js.map +1 -0
  248. package/dist/shared/skillInjection.d.ts +9 -0
  249. package/dist/shared/skillInjection.js +16 -0
  250. package/dist/shared/skillInjection.js.map +1 -0
  251. package/dist/shared/sleep.js.map +1 -0
  252. package/dist/{socketPath.d.ts → shared/socketPath.d.ts} +4 -0
  253. package/dist/{socketPath.js → shared/socketPath.js} +22 -0
  254. package/dist/shared/socketPath.js.map +1 -0
  255. package/dist/shared/version.js.map +1 -0
  256. package/package.json +13 -7
  257. package/dist/apnsConfigStore.js.map +0 -1
  258. package/dist/apnsJwtProvider.js.map +0 -1
  259. package/dist/approvalPushNotifier.js.map +0 -1
  260. package/dist/broker.js.map +0 -1
  261. package/dist/chatTailController.js.map +0 -1
  262. package/dist/claudeSessionStore.d.ts +0 -15
  263. package/dist/claudeSessionStore.js +0 -201
  264. package/dist/claudeSessionStore.js.map +0 -1
  265. package/dist/codexRolloutTailer.d.ts +0 -56
  266. package/dist/codexRolloutTailer.js +0 -303
  267. package/dist/codexRolloutTailer.js.map +0 -1
  268. package/dist/codexSessionStore.js.map +0 -1
  269. package/dist/codexUsage.js.map +0 -1
  270. package/dist/deviceTokenStore.js.map +0 -1
  271. package/dist/dirLister.js +0 -98
  272. package/dist/dirLister.js.map +0 -1
  273. package/dist/doctor.d.ts +0 -36
  274. package/dist/doctor.js +0 -162
  275. package/dist/doctor.js.map +0 -1
  276. package/dist/engine.d.ts +0 -85
  277. package/dist/engine.js +0 -962
  278. package/dist/engine.js.map +0 -1
  279. package/dist/hook.js.map +0 -1
  280. package/dist/hookSettings.js.map +0 -1
  281. package/dist/idleReaper.d.ts +0 -13
  282. package/dist/idleReaper.js +0 -30
  283. package/dist/idleReaper.js.map +0 -1
  284. package/dist/imageService.js.map +0 -1
  285. package/dist/kick.js.map +0 -1
  286. package/dist/launch.js +0 -396
  287. package/dist/launch.js.map +0 -1
  288. package/dist/legacyHomeMigration.js.map +0 -1
  289. package/dist/lineWriter.js.map +0 -1
  290. package/dist/mdnsAdvertiser.d.ts +0 -46
  291. package/dist/mdnsAdvertiser.js +0 -268
  292. package/dist/mdnsAdvertiser.js.map +0 -1
  293. package/dist/pairingCode.js.map +0 -1
  294. package/dist/paths.js.map +0 -1
  295. package/dist/permissionMode.d.ts +0 -8
  296. package/dist/permissionMode.js +0 -32
  297. package/dist/permissionMode.js.map +0 -1
  298. package/dist/planUsageFetcher.d.ts +0 -35
  299. package/dist/planUsageFetcher.js +0 -172
  300. package/dist/planUsageFetcher.js.map +0 -1
  301. package/dist/pushTokenCommand.js.map +0 -1
  302. package/dist/pushTypes.js.map +0 -1
  303. package/dist/sendLog.js.map +0 -1
  304. package/dist/sessionActivityProvider.d.ts +0 -7
  305. package/dist/sessionActivityProvider.js +0 -44
  306. package/dist/sessionActivityProvider.js.map +0 -1
  307. package/dist/sessionIdleTracker.d.ts +0 -19
  308. package/dist/sessionIdleTracker.js +0 -42
  309. package/dist/sessionIdleTracker.js.map +0 -1
  310. package/dist/sessionListService.js.map +0 -1
  311. package/dist/sessionMetadataStore.js.map +0 -1
  312. package/dist/sessionSearch.js.map +0 -1
  313. package/dist/setup.js.map +0 -1
  314. package/dist/sleep.js.map +0 -1
  315. package/dist/socketPath.js.map +0 -1
  316. package/dist/subagentTailer.d.ts +0 -15
  317. package/dist/subagentTailer.js +0 -399
  318. package/dist/subagentTailer.js.map +0 -1
  319. package/dist/tmux.d.ts +0 -62
  320. package/dist/tmux.js +0 -163
  321. package/dist/tmux.js.map +0 -1
  322. package/dist/transcriptTailer.js.map +0 -1
  323. package/dist/usageAggregator.js.map +0 -1
  324. package/dist/version.js.map +0 -1
  325. /package/dist/{kick.d.ts → commands/kick.d.ts} +0 -0
  326. /package/dist/{legacyHomeMigration.d.ts → commands/legacyHomeMigration.d.ts} +0 -0
  327. /package/dist/{legacyHomeMigration.js → commands/legacyHomeMigration.js} +0 -0
  328. /package/dist/{apnsConfigStore.d.ts → push/apnsConfigStore.d.ts} +0 -0
  329. /package/dist/{apnsConfigStore.js → push/apnsConfigStore.js} +0 -0
  330. /package/dist/{apnsJwtProvider.d.ts → push/apnsJwtProvider.d.ts} +0 -0
  331. /package/dist/{apnsJwtProvider.js → push/apnsJwtProvider.js} +0 -0
  332. /package/dist/{apnsSender.d.ts → push/apnsSender.d.ts} +0 -0
  333. /package/dist/{apnsSender.js → push/apnsSender.js} +0 -0
  334. /package/dist/{approvalPushNotifier.d.ts → push/approvalPushNotifier.d.ts} +0 -0
  335. /package/dist/{deviceTokenStore.d.ts → push/deviceTokenStore.d.ts} +0 -0
  336. /package/dist/{deviceTokenStore.js → push/deviceTokenStore.js} +0 -0
  337. /package/dist/{pushTypes.d.ts → push/pushTypes.d.ts} +0 -0
  338. /package/dist/{sendLog.d.ts → push/sendLog.d.ts} +0 -0
  339. /package/dist/{sendLog.js → push/sendLog.js} +0 -0
  340. /package/dist/{usageAggregator.d.ts → services/usageAggregator.d.ts} +0 -0
  341. /package/dist/{usageAggregator.js → services/usageAggregator.js} +0 -0
  342. /package/dist/{sessionSearch.js → sessions/sessionSearch.js} +0 -0
  343. /package/dist/{observationLog.d.ts → shared/observationLog.d.ts} +0 -0
  344. /package/dist/{observationLog.js → shared/observationLog.js} +0 -0
  345. /package/dist/{sleep.d.ts → shared/sleep.d.ts} +0 -0
  346. /package/dist/{sleep.js → shared/sleep.js} +0 -0
  347. /package/dist/{version.d.ts → shared/version.d.ts} +0 -0
  348. /package/dist/{version.js → shared/version.js} +0 -0
package/README.md CHANGED
@@ -1,28 +1,40 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/namasugi/tailii-host/main/assets/tailii-logo.png" alt="Tailii" width="480">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/tailii-host"><img src="https://img.shields.io/npm/v/tailii-host" alt="npm version"></a>
7
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="license MIT"></a>
8
+ </p>
9
+
1
10
  # tailii-host
2
11
 
3
- Tailii is an iPhone app for controlling Claude Code and Codex sessions running on your own Mac.
12
+ Tailii is an iPhone app for controlling Claude Code and Codex sessions running on your own machine.
4
13
 
5
- `tailii-host` は、Tailii iPhone アプリと Mac 上の Claude Code / Codex セッションをつなぐホスト側ヘルパーです。Mac 側で `npx tailii-host setup` を実行してペアリングします。
14
+ `tailii-host` は、Tailii iPhone アプリとホストマシン上の Claude Code / Codex セッションをつなぐホスト側ヘルパーです。ホスト側で `npx tailii-host setup` を実行してペアリングします。
6
15
 
7
16
  ## Requirements
8
17
 
9
18
  - Node.js 20 以上
10
- - macOS
11
- - tmux
12
- - `claude` CLI (Claude Code) がインストール済みでログイン済みであること
19
+ - macOS または Linux(QUIC ゲートウェイは macOS のみ)
20
+ - tmux(任意で herdr — セッション収容先をアプリ設定から herdr に切り替えられます)
21
+ - SSH サーバーが有効であること(macOS では「リモートログイン」を ON)
22
+ - `claude` CLI (Claude Code) がインストール済みでログイン済みであること(Codex を使う場合は `codex` CLI)
13
23
  - Tailii iPhone アプリ
14
24
 
15
25
  ## Quick start
16
26
 
17
- Mac で次のコマンドを実行します。
27
+ ホストマシンで次のコマンドを実行します。
18
28
 
19
29
  ```sh
20
30
  npx tailii-host setup
21
31
  ```
22
32
 
23
- 表示された QR コードを Tailii アプリで読み取るか、表示されたコードをアプリに入力してペアリングします。
33
+ 表示された QR コードを Tailii アプリで読み取るか、表示された `host:port` と 6 桁コードをアプリに入力してペアリングします。
34
+
35
+ SSH 鍵は **iPhone 側で生成され、その公開鍵だけがホストの `~/.ssh/authorized_keys` に登録されます**(秘密鍵はネットワークにも QR にも載りません)。QR には接続先とワンタイムの共有鍵だけが入っており、**`setup` の実行中のみ有効**で 1 回のペアリングで失効します。うまくいかなかったときは `setup` をやり直してください。
24
36
 
25
- `setup` は、アプリが SSH 経由で実行するランチャー(`~/.local/bin/tailii-host`)を自動生成し、あわせて環境診断(tmux / claude CLI / リモートログイン)を表示します。診断だけを再実行するには:
37
+ `setup` は、アプリが SSH 経由で実行するランチャー(`~/.local/bin/tailii-host`)を自動生成し、あわせて環境診断を表示します。Node.js / Claude / Codex / herdr の対応最低版、tmux、SSH サーバー、ランチャーを検査し、OS と検出できたパッケージマネージャーに合わせた導入/更新コマンドを案内します。macOS では任意の QUIC 環境も検査し、Linux では macOS 専用項目を表示しません。診断だけを再実行するには:
26
38
 
27
39
  ```sh
28
40
  npx tailii-host doctor
@@ -30,21 +42,30 @@ npx tailii-host doctor
30
42
 
31
43
  ## How it works
32
44
 
33
- Tailii はサーバーレス構成で動作し、リレーサーバーは使いません。Mac への到達性は自宅 LAN や Tailscale など、ユーザー自身のネットワーク環境で確保します。
45
+ Tailii はサーバーレス構成で動作し、リレーサーバーは使いません。ホストへの到達性は自宅 LAN や Tailscale など、ユーザー自身のネットワーク環境で確保します。
46
+
47
+ 接続は SSH が基本です。macOS ホストでは、これに加えて QUIC ゲートウェイ(Rust / quinn)を launchd に常駐させ、Wi-Fi ↔ モバイル回線の切り替えやスリープ復帰をまたいでも会話が切れない、mosh 的なトランスポートとして利用できます。QUIC が使えない環境では自動的に SSH へフォールバックします。ゲートウェイの prebuilt バイナリは optionalDependencies(`@tailii/quic-gw-darwin-arm64` / `@tailii/quic-gw-darwin-x64`)として配布され、`setup` が設置から常駐化まで行います。
48
+
49
+ 承認フローでは Claude Code の PreToolUse hook を使い、ツール実行を一時停止して構造化イベントを iPhone に転送します。ユーザーは iPhone アプリ上でネイティブに承認または拒否できます。セッションは tmux(または herdr)により維持されるため、接続が切れても継続できます。
50
+
51
+ 接続中の出来事は iPhone 側のローカル通知で知らせます。バックグラウンド push 通知は現在準備中の実験的機能で、既定では無効です(ホスト側に APNs 設定が無い場合、送信は行われません)。
34
52
 
35
- 承認フローでは Claude Code の PreToolUse hook を使い、ツール実行を一時停止して構造化イベントを iPhone に転送します。ユーザーは iPhone アプリ上でネイティブに承認または拒否できます。セッションは tmux により維持されるため、接続が切れても継続できます。バックグラウンド通知は Mac から APNs に直接送信されます。
53
+ 実行エンジンは、サブスクリプション認証済みの対話型 `claude` CLI(および `codex` CLI)です。Agent SDK やヘッドレス実行は使いません。
36
54
 
37
- 実行エンジンは、サブスクリプション認証済みの対話型 `claude` CLI です。Agent SDK やヘッドレス実行は使いません。
55
+ Tailii アプリの「使用量・情報」は、Claude / Codex のアカウント使用量とともに、ホストのバージョン・必須/任意診断・修復コマンドを表示します。診断は同シートの更新ごとに再実行されます。
38
56
 
39
57
  ## Commands
40
58
 
41
- - `setup`: メインのユーザー向けコマンドです。Mac と Tailii iPhone アプリをペアリングします。
59
+ - `setup`: メインのユーザー向けコマンドです。ホストと Tailii iPhone アプリをペアリングし、アプリが生成した公開鍵を `authorized_keys` に登録します。
60
+ - `doctor`: バージョン互換性、必須/任意のホスト環境、OS 別の導入/更新手順を診断します。
42
61
  - `engine`: Tailii が利用する実行エンジン関連の処理を行います。
43
- - `serve`: Mac 側ホストのローカルサーバーを起動します。
62
+ - `serve`: ホスト側のローカルサーバーを起動します。
44
63
  - `hook`: Claude Code の hook から呼び出され、承認イベントを処理します。
45
- - `launch`: tmux-backed セッションを起動します。
64
+ - `launch`: 端末バックエンド(tmux 既定 / herdr 任意)上にセッションを起動します。
46
65
  - `kick`: セッションやホスト側処理を再開・通知するために使われます。
47
66
  - `push-token`: iPhone アプリのプッシュ通知トークンを登録します。
67
+ - `hub`: 会話状態・出力配信・入力調停とアイドルなセッション(tmux / herdr)の自動掃除を担う常駐デーモンです。engine 起動時や hook から自動起動されるため、通常は手動実行不要です。
68
+ - `quic-info`: QUIC ゲートウェイの接続情報(ポート・証明書ピン・トークン)を出力します。アプリが SSH 経由で取得するために使う内部コマンドです。
48
69
 
49
70
  ## License
50
71
 
@@ -1,5 +1,5 @@
1
1
  import type { Readable, Writable } from "node:stream";
2
- import { type StaleDistGuard } from "./version.js";
2
+ import { type StaleDistGuard } from "../shared/version.js";
3
3
  export interface RunBrokerOptions {
4
4
  socketPath: string;
5
5
  /** "stdin" 側(iOS→hook 方向の決定が流れてくる)。 */
@@ -14,11 +14,15 @@ export interface RunBrokerOptions {
14
14
  onStaleDist?: () => void;
15
15
  /** 起動直後に SSH 側へ channel_hello を送る(CLI の serve 経路で有効)。 */
16
16
  sendHello?: boolean;
17
+ /**
18
+ * 先発 listener の解放待ち猶予(ms)。iOS が chat 離脱で旧 serve チャネルを閉じた直後に
19
+ * 同一会話を開き直すと、旧 serve の終了(socket 解放)と新 serve の起動が競走する。
20
+ * 即失敗にせず短時間だけ解放を待って引き継ぐ(猶予内に解放されなければ従来どおり失敗)。
21
+ */
22
+ socketWaitGraceMs?: number;
23
+ /** 解放待ちの再確認間隔(ms)。 */
24
+ socketWaitIntervalMs?: number;
17
25
  }
18
- /**
19
- * unix socket と input/output の間を双方向中継する非解釈リレーの本体。
20
- * input EOF(SSH 断)で全クライアントを閉じ、socket ファイルを削除して resolve する。
21
- */
22
26
  export declare function runBroker(options: RunBrokerOptions): Promise<void>;
23
27
  /** serve サブコマンドのエントリポイント(`--session <name>` | `--socket <path>`)。 */
24
28
  export declare function runServeCommand(args: string[]): Promise<number>;
@@ -10,14 +10,16 @@
10
10
  // - SSH→hook 方向は input の完全行を登録中の全クライアントへブロードキャスト
11
11
  // (宛先選別なし=各 hook が自 id を照合)。購読者ゼロ時は行を保持しない(非永続)。
12
12
  // - channel_hello を含むあらゆる行を非解釈で透過する。
13
- // - SSH 断(input EOF)→ 全クライアント socket を閉じ(各 hook EOF→deny, 5.6)、
13
+ // - SSH 断(input EOF)→ 全クライアント socket を閉じ(各 hook は EOF を切断と検知して
14
+ // retry-connect フォールバックへ, hook.ts 参照)、
14
15
  // listen を止めて socket ファイルを削除して終了する。
15
16
  // - EOF 時の残余バッファ(改行なしの部分行)は Swift 版同様そのまま転送する。
16
17
  import * as fs from "node:fs";
17
18
  import * as net from "node:net";
18
- import { resolveSocketPath } from "./socketPath.js";
19
- import { encodeControlMessage, PROTOCOL_MAX_SUPPORTED, PROTOCOL_V1 } from "./protocol.js";
20
- import { createStaleDistGuard, isStaleDist, readPackageVersion } from "./version.js";
19
+ import { resolveSocketPath } from "../shared/socketPath.js";
20
+ import { sleep } from "../shared/sleep.js";
21
+ import { encodeControlMessage, PROTOCOL_MAX_SUPPORTED, PROTOCOL_V1 } from "../protocol.js";
22
+ import { createStaleDistGuard, isStaleDist, readPackageVersion } from "../shared/version.js";
21
23
  /** 行分割器: チャンクを積み、完全行(末尾 \n 込み)ごとに onLine を呼ぶ。 */
22
24
  function makeLineFeeder(onLine) {
23
25
  let buf = Buffer.alloc(0);
@@ -42,11 +44,43 @@ function makeLineFeeder(onLine) {
42
44
  * unix socket と input/output の間を双方向中継する非解釈リレーの本体。
43
45
  * input EOF(SSH 断)で全クライアントを閉じ、socket ファイルを削除して resolve する。
44
46
  */
47
+ /**
48
+ * `socketPath` に既に生きた listener がいるかを probe する(reject せず bool で返す)。
49
+ * 同一 session 名の serve が重複起動されうる(iOS 側の enterChat レース、または同一
50
+ * session を複数デバイスから同時に開いた場合)。無条件に unlink→listen すると生きている
51
+ * 側の listen 中ソケットを奪ってしまい、しかも Node の `net.Server.close()` は bind した
52
+ * パスを close 時に自動 unlink するため、奪われた側が閉じた瞬間に「今生きている方」の
53
+ * ソケットファイルまで消える(以後の hook connect が全て ECONNREFUSED になり、承認が
54
+ * 「考え中」のまま永久にハングする不具合の実根因)。奪う前に生存確認する。
55
+ */
56
+ function isSocketAlive(socketPath) {
57
+ return new Promise((resolve) => {
58
+ const probe = net.connect(socketPath);
59
+ probe.once("connect", () => {
60
+ probe.destroy();
61
+ resolve(true);
62
+ });
63
+ probe.once("error", () => resolve(false));
64
+ });
65
+ }
45
66
  export async function runBroker(options) {
46
67
  const { socketPath, input, output } = options;
47
68
  const log = options.log ?? (() => { });
48
69
  const staleDistGuard = options.staleDistGuard ?? createStaleDistGuard();
49
- // 既存 socket ファイルを削除してから listen(Swift 版 unlink→bind と同一)。
70
+ // 既存 socket ファイルが生きていれば奪わず、まず解放を短時間待つ(chat 離脱→開き直しで
71
+ // 旧 serve の終了と競走するケースの吸収)。猶予内に解放されなければ従来どおり諦める
72
+ // (生きている正当な所有者からは決して奪わない, 上記コメント参照)。
73
+ // 生きていなければ(前回異常終了のスタール残骸)安全に削除して bind し直す
74
+ // (Swift 版 unlink→bind と同一の後始末)。
75
+ const graceMs = options.socketWaitGraceMs ?? 4000;
76
+ const intervalMs = options.socketWaitIntervalMs ?? 200;
77
+ const waitDeadline = Date.now() + graceMs;
78
+ while (await isSocketAlive(socketPath)) {
79
+ if (Date.now() >= waitDeadline) {
80
+ throw new Error(`socket already in use by a live listener: ${socketPath}`);
81
+ }
82
+ await sleep(intervalMs);
83
+ }
50
84
  fs.rmSync(socketPath, { force: true });
51
85
  const clients = new Set();
52
86
  let registryClosed = false;
@@ -59,8 +93,10 @@ export async function runBroker(options) {
59
93
  registryClosed = true;
60
94
  for (const client of clients)
61
95
  client.end();
96
+ // `net.Server.close()` は bind したパスの socket ファイルを自前で unlink するため
97
+ // (Node 内部仕様)、ここで追加の fs.rmSync は不要(かつ、上の isSocketAlive ガードにより
98
+ // このプロセスは常にこのパスの正当な唯一の所有者として起動しているため安全)。
62
99
  server.close(() => { });
63
- fs.rmSync(socketPath, { force: true });
64
100
  resolveBroker?.();
65
101
  };
66
102
  /** 1 完全行を SSH (output) へ書き込む(失敗は無視 — Swift 版 try? と同一)。 */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker.js","sourceRoot":"","sources":["../../src/approval/broker.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import { type PushObserving } from "../push/approvalPushNotifier.js";
2
+ import { type TmuxCommandRunner } from "../backend/tmux.js";
1
3
  /**
2
4
  * hook 内部デッドラインの既定値(秒)。settings の外部タイムアウト
3
5
  * (hookSettings.HOOK_EXTERNAL_TIMEOUT_SECONDS = 600)より**厳密に小さく**保つこと。
@@ -22,6 +24,12 @@ export interface ApprovalPushRequest {
22
24
  * 送信可否は deny 判断に影響しない(結果は捨てる)。本番実装は push-token 移植時に配線する。
23
25
  */
24
26
  export type ApprovalPushNotifier = (request: ApprovalPushRequest, timeLimitMs: number) => Promise<void>;
27
+ export type PresenceReason = "mac-attached" | "client-live";
28
+ export type PresenceProbe = (session: string) => Promise<PresenceReason | null>;
29
+ /** presence 判定全体の上限。失敗・超過は push 送信へ倒す。 */
30
+ export declare const PRESENCE_PROBE_TIME_LIMIT_MS = 500;
31
+ /** Hub への使い捨て presence RPC の上限。 */
32
+ export declare const HUB_PRESENCE_RPC_TIMEOUT_MS = 300;
25
33
  export interface RunHookOptions {
26
34
  stdinData: Buffer;
27
35
  /** 接続する unix socket パス。null は接続不能と同義(PreToolUse は即 deny)。 */
@@ -38,8 +46,27 @@ export interface RunHookOptions {
38
46
  notifier?: ApprovalPushNotifier;
39
47
  /** push 送信部の時間上限(ms)。gate 非阻害のためこの時間で打ち切る。既定 5000。 */
40
48
  notifierTimeLimitMs?: number;
49
+ /** 背景 push 前の presence 判定。例外・超過は不在扱いにせず fail-open で push する。 */
50
+ presenceProbe?: PresenceProbe;
51
+ /** presence により push を抑制した場合の観測先。 */
52
+ pushObserver?: Pick<PushObserving, "recordSkipped">;
53
+ /** connect 不能時に engine relay へ通知する socket path。省略時は既定パス。null なら送らない。 */
54
+ engineRelaySocketPath?: string | null;
41
55
  /** connect 不能ブランチでの retry-connect ポーリング間隔(秒)。既定 1.0。 */
42
56
  retryConnectIntervalSeconds?: number;
57
+ /**
58
+ * 現在の permission mode("default" | "acceptEdits" | "plan" | "auto" | null)を返す
59
+ * provider(注入)。auto/acceptEdits の自動許可判定に使う。省略・null・例外は
60
+ * 「判定不能」として従来どおり iPhone ゲートへフォールバックする(安全側)。
61
+ */
62
+ permissionModeProvider?: () => Promise<string | null>;
63
+ /**
64
+ * reaper daemon の判定権威となる heartbeat ファイルの置き場(注入)。
65
+ * 省略時は書かない(テスト密閉)。runHookCommand が既定パスを渡す。
66
+ */
67
+ heartbeatDir?: string;
68
+ /** Session Hub daemon の常駐保証(注入)。省略時は何もしない。UserPromptSubmit でのみ呼ぶ。 */
69
+ ensureHub?: () => void;
43
70
  }
44
71
  export interface HookRunResult {
45
72
  exitCode: number;
@@ -47,6 +74,27 @@ export interface HookRunResult {
47
74
  }
48
75
  /** hook の本体(テスタブル・完全版)。stdin JSON の `hook_event_name` で分岐する。 */
49
76
  export declare function runHookCore(options: RunHookOptions): Promise<HookRunResult>;
77
+ /**
78
+ * permission mode によって iPhone 承認をスキップできる場合、その理由文字列を返す(純ロジック)。
79
+ * - auto: 全ツールを自動許可。
80
+ * - acceptEdits: 編集系ツール(Write/Edit/MultiEdit/NotebookEdit)のみ自動許可。
81
+ * - それ以外(default / plan / null = 判定不能): null(従来どおり iPhone ゲート)。
82
+ */
83
+ export declare function autoAllowReasonForMode(mode: string | null, toolName: string): string | null;
84
+ /**
85
+ * pane 表示から permission mode を判定する本番 provider を作る(claude 専用)。
86
+ * capture が timeLimitMs 内に返らない・失敗する場合は null(判定不能 → 従来ゲート)。
87
+ * 本番の hook CLI は Claude 専用なので、この provider も Claude にだけ配線する。
88
+ * セッションの属するバックエンド(tmux / herdr)はメタデータで解決する。
89
+ */
90
+ export declare function makeTmuxPermissionModeProvider(session: string, timeLimitMs?: number): () => Promise<string | null>;
91
+ /**
92
+ * Hub socket へ短命接続し、1回だけ presence RPC を行う。
93
+ * false は正常応答で購読者なし、null は接続・応答失敗を表す。
94
+ */
95
+ export declare function requestHubPresence(session: string, socketPath: string, timeoutMs?: number): Promise<boolean | null>;
96
+ /** tmux attach と Hub subscriber を順に調べる本番 presence probe。 */
97
+ export declare function makePresenceProbe(runner?: TmuxCommandRunner, hubSocketPath?: string): PresenceProbe;
50
98
  /**
51
99
  * hook サブコマンドのエントリポイント。
52
100
  * 引数: `--socket <path>` | `--session <name>` | `--deadline <seconds>` |
@@ -58,10 +106,3 @@ export declare function runHookCore(options: RunHookOptions): Promise<HookRunRes
58
106
  * 判断する(未設定なら送らず観測記録, 3.5/6.4)。送信可否は deny 判断に影響しない。
59
107
  */
60
108
  export declare function runHookCommand(args: string[]): Promise<number>;
61
- /**
62
- * エージェント別にフックが実際に stdout へ書く文字列を決める(TESTABLE)。
63
- * claude: 生成した decision JSON をそのまま出す。
64
- * codex : allow/ask を「unsupported」として拒否するため、承認(allow 決定)時は無出力(null)で
65
- * exit 0 続行にする。拒否(deny)や監査出力はそのまま出す(deny JSON は codex も解釈する)。
66
- */
67
- export declare function hookStdoutForAgent(agent: "claude" | "codex", stdout: string): string | null;