@jsonstudio/rcc 0.89.1803 → 0.89.1959

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 (283) hide show
  1. package/configsamples/config.json +19 -0
  2. package/configsamples/provider/deepseek/config.v1.json +59 -0
  3. package/dist/build-info.js +2 -2
  4. package/dist/cli/commands/claude.d.ts +4 -0
  5. package/dist/cli/commands/claude.js +56 -0
  6. package/dist/cli/commands/claude.js.map +1 -0
  7. package/dist/cli/commands/clock-admin.d.ts +20 -0
  8. package/dist/cli/commands/clock-admin.js +234 -0
  9. package/dist/cli/commands/clock-admin.js.map +1 -0
  10. package/dist/cli/commands/code.d.ts +0 -42
  11. package/dist/cli/commands/code.js +4 -414
  12. package/dist/cli/commands/code.js.map +1 -1
  13. package/dist/cli/commands/codex.d.ts +4 -0
  14. package/dist/cli/commands/codex.js +43 -0
  15. package/dist/cli/commands/codex.js.map +1 -0
  16. package/dist/cli/commands/examples.js +13 -16
  17. package/dist/cli/commands/examples.js.map +1 -1
  18. package/dist/cli/commands/init/basic.d.ts +40 -0
  19. package/dist/cli/commands/init/basic.js +482 -0
  20. package/dist/cli/commands/init/basic.js.map +1 -0
  21. package/dist/cli/commands/init/camoufox.d.ts +7 -0
  22. package/dist/cli/commands/init/camoufox.js +59 -0
  23. package/dist/cli/commands/init/camoufox.js.map +1 -0
  24. package/dist/cli/commands/init/interactive.d.ts +18 -0
  25. package/dist/cli/commands/init/interactive.js +223 -0
  26. package/dist/cli/commands/init/interactive.js.map +1 -0
  27. package/dist/cli/commands/init/shared.d.ts +66 -0
  28. package/dist/cli/commands/init/shared.js +9 -0
  29. package/dist/cli/commands/init/shared.js.map +1 -0
  30. package/dist/cli/commands/init/workflows.d.ts +29 -0
  31. package/dist/cli/commands/init/workflows.js +341 -0
  32. package/dist/cli/commands/init/workflows.js.map +1 -0
  33. package/dist/cli/commands/init.d.ts +2 -26
  34. package/dist/cli/commands/init.js +220 -53
  35. package/dist/cli/commands/init.js.map +1 -1
  36. package/dist/cli/commands/launcher-kernel.d.ts +78 -0
  37. package/dist/cli/commands/launcher-kernel.js +1194 -0
  38. package/dist/cli/commands/launcher-kernel.js.map +1 -0
  39. package/dist/cli/commands/start.js +27 -1
  40. package/dist/cli/commands/start.js.map +1 -1
  41. package/dist/cli/commands/status.d.ts +2 -0
  42. package/dist/cli/commands/status.js +24 -1
  43. package/dist/cli/commands/status.js.map +1 -1
  44. package/dist/cli/commands/stop.d.ts +1 -0
  45. package/dist/cli/commands/stop.js +201 -4
  46. package/dist/cli/commands/stop.js.map +1 -1
  47. package/dist/cli/commands/tmux-inject.d.ts +20 -0
  48. package/dist/cli/commands/tmux-inject.js +212 -0
  49. package/dist/cli/commands/tmux-inject.js.map +1 -0
  50. package/dist/cli/config/init-provider-catalog.js +34 -0
  51. package/dist/cli/config/init-provider-catalog.js.map +1 -1
  52. package/dist/cli/register/claude-command.d.ts +3 -0
  53. package/dist/cli/register/claude-command.js +5 -0
  54. package/dist/cli/register/claude-command.js.map +1 -0
  55. package/dist/cli/register/clock-admin-command.d.ts +3 -0
  56. package/dist/cli/register/clock-admin-command.js +5 -0
  57. package/dist/cli/register/clock-admin-command.js.map +1 -0
  58. package/dist/cli/register/codex-command.d.ts +3 -0
  59. package/dist/cli/register/codex-command.js +5 -0
  60. package/dist/cli/register/codex-command.js.map +1 -0
  61. package/dist/cli/register/status-config-commands.d.ts +2 -0
  62. package/dist/cli/register/status-config-commands.js.map +1 -1
  63. package/dist/cli/register/tmux-inject-command.d.ts +3 -0
  64. package/dist/cli/register/tmux-inject-command.js +5 -0
  65. package/dist/cli/register/tmux-inject-command.js.map +1 -0
  66. package/dist/cli/server/port-utils.d.ts +3 -2
  67. package/dist/cli/server/port-utils.js +171 -32
  68. package/dist/cli/server/port-utils.js.map +1 -1
  69. package/dist/cli.js +45 -6
  70. package/dist/cli.js.map +1 -1
  71. package/dist/client/gemini/gemini-protocol-client.js +56 -5
  72. package/dist/client/gemini/gemini-protocol-client.js.map +1 -1
  73. package/dist/commands/token-daemon.js +59 -7
  74. package/dist/commands/token-daemon.js.map +1 -1
  75. package/dist/commands/validate.js +87 -15
  76. package/dist/commands/validate.js.map +1 -1
  77. package/dist/config/routecodex-config-loader.js +31 -2
  78. package/dist/config/routecodex-config-loader.js.map +1 -1
  79. package/dist/docs/daemon-admin-ui.html +948 -74
  80. package/dist/index.d.ts +1 -0
  81. package/dist/index.js +325 -37
  82. package/dist/index.js.map +1 -1
  83. package/dist/manager/quota/provider-quota-center.js +8 -14
  84. package/dist/manager/quota/provider-quota-center.js.map +1 -1
  85. package/dist/modules/llmswitch/bridge.d.ts +39 -0
  86. package/dist/modules/llmswitch/bridge.js +169 -0
  87. package/dist/modules/llmswitch/bridge.js.map +1 -1
  88. package/dist/modules/pipeline/utils/colored-logger.js +1 -1
  89. package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
  90. package/dist/providers/auth/deepseek-account-auth.d.ts +39 -0
  91. package/dist/providers/auth/deepseek-account-auth.js +329 -0
  92. package/dist/providers/auth/deepseek-account-auth.js.map +1 -0
  93. package/dist/providers/auth/deepseek-account-token-acquirer.d.ts +15 -0
  94. package/dist/providers/auth/deepseek-account-token-acquirer.js +644 -0
  95. package/dist/providers/auth/deepseek-account-token-acquirer.js.map +1 -0
  96. package/dist/providers/auth/oauth-lifecycle.js +26 -4
  97. package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
  98. package/dist/providers/auth/oauth-repair-cooldown.d.ts +5 -0
  99. package/dist/providers/auth/oauth-repair-cooldown.js +39 -0
  100. package/dist/providers/auth/oauth-repair-cooldown.js.map +1 -1
  101. package/dist/providers/auth/token-scanner/index.d.ts +6 -0
  102. package/dist/providers/auth/token-scanner/index.js +53 -0
  103. package/dist/providers/auth/token-scanner/index.js.map +1 -1
  104. package/dist/providers/core/api/provider-config.d.ts +17 -2
  105. package/dist/providers/core/api/provider-types.d.ts +6 -0
  106. package/dist/providers/core/api/provider-types.js.map +1 -1
  107. package/dist/providers/core/config/camoufox-launcher.d.ts +7 -0
  108. package/dist/providers/core/config/camoufox-launcher.js +68 -21
  109. package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
  110. package/dist/providers/core/config/service-profiles.js +19 -0
  111. package/dist/providers/core/config/service-profiles.js.map +1 -1
  112. package/dist/providers/core/contracts/deepseek-provider-contract.d.ts +34 -0
  113. package/dist/providers/core/contracts/deepseek-provider-contract.js +100 -0
  114. package/dist/providers/core/contracts/deepseek-provider-contract.js.map +1 -0
  115. package/dist/providers/core/runtime/anthropic-http-provider.d.ts +0 -5
  116. package/dist/providers/core/runtime/anthropic-http-provider.js +0 -26
  117. package/dist/providers/core/runtime/anthropic-http-provider.js.map +1 -1
  118. package/dist/providers/core/runtime/deepseek-http-provider.d.ts +35 -0
  119. package/dist/providers/core/runtime/deepseek-http-provider.js +373 -0
  120. package/dist/providers/core/runtime/deepseek-http-provider.js.map +1 -0
  121. package/dist/providers/core/runtime/deepseek-session-pow.d.ts +55 -0
  122. package/dist/providers/core/runtime/deepseek-session-pow.js +422 -0
  123. package/dist/providers/core/runtime/deepseek-session-pow.js.map +1 -0
  124. package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +0 -3
  125. package/dist/providers/core/runtime/gemini-cli-http-provider.js +0 -72
  126. package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
  127. package/dist/providers/core/runtime/gemini-http-provider.d.ts +1 -7
  128. package/dist/providers/core/runtime/gemini-http-provider.js +3 -110
  129. package/dist/providers/core/runtime/gemini-http-provider.js.map +1 -1
  130. package/dist/providers/core/runtime/http-request-executor.d.ts +1 -0
  131. package/dist/providers/core/runtime/http-request-executor.js +4 -0
  132. package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
  133. package/dist/providers/core/runtime/http-transport-provider.d.ts +10 -4
  134. package/dist/providers/core/runtime/http-transport-provider.js +308 -82
  135. package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
  136. package/dist/providers/core/runtime/iflow-http-provider.d.ts +0 -4
  137. package/dist/providers/core/runtime/iflow-http-provider.js +0 -28
  138. package/dist/providers/core/runtime/iflow-http-provider.js.map +1 -1
  139. package/dist/providers/core/runtime/provider-factory.d.ts +5 -0
  140. package/dist/providers/core/runtime/provider-factory.js +59 -6
  141. package/dist/providers/core/runtime/provider-factory.js.map +1 -1
  142. package/dist/providers/core/runtime/responses-provider.d.ts +0 -2
  143. package/dist/providers/core/runtime/responses-provider.js +0 -11
  144. package/dist/providers/core/runtime/responses-provider.js.map +1 -1
  145. package/dist/providers/core/strategies/oauth-device-flow.js +16 -1
  146. package/dist/providers/core/strategies/oauth-device-flow.js.map +1 -1
  147. package/dist/providers/core/utils/provider-type-utils.js +2 -1
  148. package/dist/providers/core/utils/provider-type-utils.js.map +1 -1
  149. package/dist/providers/profile/families/anthropic-profile.d.ts +2 -0
  150. package/dist/providers/profile/families/anthropic-profile.js +32 -0
  151. package/dist/providers/profile/families/anthropic-profile.js.map +1 -0
  152. package/dist/providers/profile/families/antigravity-profile.d.ts +2 -0
  153. package/dist/providers/profile/families/antigravity-profile.js +109 -0
  154. package/dist/providers/profile/families/antigravity-profile.js.map +1 -0
  155. package/dist/providers/profile/families/glm-profile.d.ts +2 -0
  156. package/dist/providers/profile/families/glm-profile.js +48 -0
  157. package/dist/providers/profile/families/glm-profile.js.map +1 -0
  158. package/dist/providers/profile/families/iflow-profile.d.ts +2 -0
  159. package/dist/providers/profile/families/iflow-profile.js +232 -0
  160. package/dist/providers/profile/families/iflow-profile.js.map +1 -0
  161. package/dist/providers/profile/families/qwen-profile.d.ts +2 -0
  162. package/dist/providers/profile/families/qwen-profile.js +14 -0
  163. package/dist/providers/profile/families/qwen-profile.js.map +1 -0
  164. package/dist/providers/profile/families/responses-profile.d.ts +2 -0
  165. package/dist/providers/profile/families/responses-profile.js +28 -0
  166. package/dist/providers/profile/families/responses-profile.js.map +1 -0
  167. package/dist/providers/profile/profile-contracts.d.ts +74 -0
  168. package/dist/providers/profile/profile-contracts.js +2 -0
  169. package/dist/providers/profile/profile-contracts.js.map +1 -0
  170. package/dist/providers/profile/profile-registry.d.ts +3 -0
  171. package/dist/providers/profile/profile-registry.js +40 -0
  172. package/dist/providers/profile/profile-registry.js.map +1 -0
  173. package/dist/providers/profile/provider-directory.d.ts +2 -0
  174. package/dist/providers/profile/provider-directory.js +55 -0
  175. package/dist/providers/profile/provider-directory.js.map +1 -0
  176. package/dist/providers/profile/provider-profile-loader.js +43 -3
  177. package/dist/providers/profile/provider-profile-loader.js.map +1 -1
  178. package/dist/providers/profile/provider-profile.d.ts +8 -0
  179. package/dist/scripts/deepseek/pow-solver.mjs +146 -0
  180. package/dist/scripts/deepseek/sha3_wasm_bg.7b9ca65ddd.wasm +0 -0
  181. package/dist/server/handlers/config-admin-handler.js +27 -0
  182. package/dist/server/handlers/config-admin-handler.js.map +1 -1
  183. package/dist/server/runtime/http-server/clock-client-registry.d.ts +113 -0
  184. package/dist/server/runtime/http-server/clock-client-registry.js +592 -0
  185. package/dist/server/runtime/http-server/clock-client-registry.js.map +1 -0
  186. package/dist/server/runtime/http-server/clock-client-routes.d.ts +2 -0
  187. package/dist/server/runtime/http-server/clock-client-routes.js +481 -0
  188. package/dist/server/runtime/http-server/clock-client-routes.js.map +1 -0
  189. package/dist/server/runtime/http-server/clock-daemon-inject-config.d.ts +1 -0
  190. package/dist/server/runtime/http-server/clock-daemon-inject-config.js +11 -0
  191. package/dist/server/runtime/http-server/clock-daemon-inject-config.js.map +1 -0
  192. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +3 -3
  193. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -1
  194. package/dist/server/runtime/http-server/daemon-admin/auth-session.d.ts +1 -0
  195. package/dist/server/runtime/http-server/daemon-admin/auth-session.js +18 -2
  196. package/dist/server/runtime/http-server/daemon-admin/auth-session.js.map +1 -1
  197. package/dist/server/runtime/http-server/daemon-admin/control-handler.js +2 -15
  198. package/dist/server/runtime/http-server/daemon-admin/control-handler.js.map +1 -1
  199. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +65 -7
  200. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
  201. package/dist/server/runtime/http-server/executor-metadata.js +37 -1
  202. package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
  203. package/dist/server/runtime/http-server/executor-provider.js +55 -0
  204. package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
  205. package/dist/server/runtime/http-server/executor-response.js +49 -1
  206. package/dist/server/runtime/http-server/executor-response.js.map +1 -1
  207. package/dist/server/runtime/http-server/index.d.ts +10 -0
  208. package/dist/server/runtime/http-server/index.js +534 -9
  209. package/dist/server/runtime/http-server/index.js.map +1 -1
  210. package/dist/server/runtime/http-server/managed-process-probe.d.ts +6 -0
  211. package/dist/server/runtime/http-server/managed-process-probe.js +294 -0
  212. package/dist/server/runtime/http-server/managed-process-probe.js.map +1 -0
  213. package/dist/server/runtime/http-server/middleware.js +16 -1
  214. package/dist/server/runtime/http-server/middleware.js.map +1 -1
  215. package/dist/server/runtime/http-server/provider-utils.js +6 -2
  216. package/dist/server/runtime/http-server/provider-utils.js.map +1 -1
  217. package/dist/server/runtime/http-server/request-executor.d.ts +1 -0
  218. package/dist/server/runtime/http-server/request-executor.js +360 -35
  219. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  220. package/dist/server/runtime/http-server/routes.js +95 -3
  221. package/dist/server/runtime/http-server/routes.js.map +1 -1
  222. package/dist/server/runtime/http-server/stats-manager.d.ts +10 -0
  223. package/dist/server/runtime/http-server/stats-manager.js +119 -16
  224. package/dist/server/runtime/http-server/stats-manager.js.map +1 -1
  225. package/dist/server/runtime/http-server/tmux-session-probe.d.ts +3 -0
  226. package/dist/server/runtime/http-server/tmux-session-probe.js +101 -0
  227. package/dist/server/runtime/http-server/tmux-session-probe.js.map +1 -0
  228. package/dist/server/utils/stage-logger.js +21 -5
  229. package/dist/server/utils/stage-logger.js.map +1 -1
  230. package/dist/token-daemon/index.js +59 -10
  231. package/dist/token-daemon/index.js.map +1 -1
  232. package/dist/token-daemon/server-utils.d.ts +1 -0
  233. package/dist/token-daemon/server-utils.js +4 -1
  234. package/dist/token-daemon/server-utils.js.map +1 -1
  235. package/dist/token-daemon/token-daemon.js +38 -4
  236. package/dist/token-daemon/token-daemon.js.map +1 -1
  237. package/dist/token-daemon/token-types.d.ts +1 -1
  238. package/dist/token-daemon/token-types.js +2 -1
  239. package/dist/token-daemon/token-types.js.map +1 -1
  240. package/dist/token-daemon/token-utils.js +5 -2
  241. package/dist/token-daemon/token-utils.js.map +1 -1
  242. package/dist/utils/clock-client-token.d.ts +3 -0
  243. package/dist/utils/clock-client-token.js +54 -0
  244. package/dist/utils/clock-client-token.js.map +1 -0
  245. package/dist/utils/managed-server-pids.d.ts +25 -0
  246. package/dist/utils/managed-server-pids.js +176 -0
  247. package/dist/utils/managed-server-pids.js.map +1 -0
  248. package/dist/utils/process-lifecycle-logger.d.ts +8 -0
  249. package/dist/utils/process-lifecycle-logger.js +151 -0
  250. package/dist/utils/process-lifecycle-logger.js.map +1 -0
  251. package/dist/utils/runtime-exit-forensics.d.ts +30 -0
  252. package/dist/utils/runtime-exit-forensics.js +101 -0
  253. package/dist/utils/runtime-exit-forensics.js.map +1 -0
  254. package/dist/utils/shutdown-caller-context.d.ts +22 -0
  255. package/dist/utils/shutdown-caller-context.js +25 -0
  256. package/dist/utils/shutdown-caller-context.js.map +1 -0
  257. package/docs/PROVIDERS_BUILTIN.md +8 -0
  258. package/docs/PROVIDER_TYPES.md +3 -1
  259. package/docs/SERVERTOOL_PRE_COMMAND_HOOKS.md +85 -0
  260. package/docs/clock-client-daemon-design.md +343 -0
  261. package/docs/daemon-admin-ui.html +948 -74
  262. package/docs/providers/deepseek-web-provider-design.md +192 -0
  263. package/docs/routing-instructions.md +4 -1
  264. package/docs/stop-message-auto.md +4 -3
  265. package/docs/v2-architecture/PROVIDER-V2-CHANGESET-RELEASE-CHECKLIST.md +80 -0
  266. package/docs/v2-architecture/PROVIDER-V2-LAYERING-ADR-DRAFT.md +225 -0
  267. package/docs/v2-architecture/PROVIDER-V2-MIGRATION-MATRIX-DRAFT.md +88 -0
  268. package/docs/v2-architecture/PROVIDER-V2-PHASED-MIGRATION-ROLLBACK-DRAFT.md +164 -0
  269. package/docs/v2-architecture/PROVIDER-V2-PROFILE-API-REGISTRY-DRAFT.md +201 -0
  270. package/docs/v2-architecture/PROVIDER-V2-PROFILE-GEMINI-DRAFT.md +56 -0
  271. package/docs/v2-architecture/PROVIDER-V2-REFACTOR-OVERVIEW-DRAFT.md +102 -0
  272. package/docs/v2-architecture/PROVIDER-V2-VERIFICATION-MATRIX-DRAFT.md +163 -0
  273. package/package.json +10 -9
  274. package/scripts/copy-compat-assets.mjs +18 -0
  275. package/scripts/copy-modules-config.mjs +1 -0
  276. package/scripts/deepseek/pow-solver.mjs +146 -0
  277. package/scripts/deepseek/sha3_wasm_bg.7b9ca65ddd.wasm +0 -0
  278. package/scripts/ensure-cli-executable.mjs +64 -0
  279. package/scripts/install-global.sh +5 -2
  280. package/scripts/install.sh +1 -1
  281. package/scripts/monitor/daemon-kill-watch.mjs +184 -0
  282. package/scripts/monitor/port-kill-watch.sh +74 -0
  283. package/scripts/quick-install.sh +1 -1
@@ -0,0 +1,343 @@
1
+ # Clock Client Daemon + Private Clock Marker Design (routecodex-119)
2
+
3
+ ## 1. Background
4
+
5
+ Current clock scheduling relies on server-side followup/hold behavior. This works for long-lived connections, but cannot actively inject new user input into `codex` / `claude` terminals when the client side is uncontrollable.
6
+
7
+ We need a controlled path where:
8
+
9
+ 1. `rcc codex` / `rcc claude` can optionally attach an input-capable client daemon.
10
+ 2. Server-side clock expiration can notify that daemon.
11
+ 3. The daemon injects a new message into client input and presses Enter.
12
+ 4. Private clock syntax can be accepted and transformed into standard clock tool semantics.
13
+
14
+ ## 2. Scope & Non-goals
15
+
16
+ ### Scope
17
+
18
+ - Add a tmux-backed client daemon integration for launcher flows.
19
+ - Add local daemon registration/heartbeat/injection endpoints on RouteCodex server.
20
+ - Add private syntax parsing for `<**clock:{time,message}**>` in llmswitch-core request inbound process.
21
+ - Keep existing servertool clock behavior compatible.
22
+
23
+ ### Non-goals (this phase)
24
+
25
+ - No cross-host daemon control.
26
+ - No new auth/session protocol beyond localhost guard.
27
+ - No natural-language/relative time parsing (`in 10m`) yet.
28
+
29
+ ## 3. Key Decisions
30
+
31
+ 1. **tmux transport first (transparent)**
32
+ - If tmux is available, launcher auto-reuses current tmux pane or auto-creates a managed tmux session when user is outside tmux.
33
+ - In non-tmux launches, launcher first tries to reuse unattached orphan `rcc_*` managed sessions whose panes are not currently running `codex`/`claude`; otherwise it creates a fresh managed session.
34
+ - Users do not need to manually start tmux for advanced mode.
35
+ - If tmux is not available, advanced service is disabled but normal server/client launching continues.
36
+
37
+ 2. **Private marker format**
38
+ - Support: `<**clock:{time,message}**>`
39
+ - `time` must be ISO8601 absolute datetime in this phase.
40
+
41
+ 3. **Parsing location**
42
+ - Parse markers in llmswitch-core Hub inbound processing path.
43
+ - Do not parse in provider layer or host transport layer.
44
+
45
+ 4. **tool_call_id behavior**
46
+ - If missing in clock tool path, generate one deterministically from request context and sequence.
47
+ - Keep generated id consistently reused in tool outputs/messages.
48
+
49
+ 5. **Daemon auth model**
50
+ - Localhost-only access guard for daemon control endpoints.
51
+
52
+ 6. **Clock inject session binding**
53
+ - Daemon routing key is `tmuxSessionId` (tmux session domain), not conversation `sessionId`.
54
+ - Conversation `sessionId` is bound separately to a tmux session in server registry (mapping domain separation).
55
+ - Launcher appends daemon identity suffix to proxied api key (`::rcc-clockd:<daemonId>`).
56
+ - HTTP auth middleware extracts daemon suffix and attaches `x-routecodex-clock-daemon-id` request hint.
57
+ - Executor metadata binds `conversationSessionId -> daemonId/tmuxSessionId` deterministically before due injection tick.
58
+ - `/daemon/clock-client/inject` remains strict and never falls back to unrelated alive daemons.
59
+
60
+ ## 4. Architecture
61
+
62
+ ### 4.1 Components
63
+
64
+ - **Launcher (`rcc codex/claude`)**
65
+ - Detects tmux capability.
66
+ - Starts/attaches client daemon if available.
67
+ - **Clock Client Daemon**
68
+ - Maintains registration + heartbeat with server.
69
+ - Executes `tmux send-keys` for injection + Enter.
70
+ - Self-terminates when parent/client exits.
71
+ - **HTTP Server daemon routes**
72
+ - Local control plane for register/heartbeat/inject/unregister.
73
+ - **llmswitch-core Hub parser**
74
+ - Scans latest user content for private clock marker.
75
+ - Converts marker into equivalent clock schedule semantics.
76
+
77
+ ### 4.2 Sequence (happy path)
78
+
79
+ 1. User runs `rcc codex`.
80
+ 2. Launcher resolves tmux target (reuse current tmux when possible, else auto-create managed tmux session).
81
+ 3. Daemon registers session metadata to server.
82
+ 4. User/model creates clock schedule or marker-based schedule.
83
+ 5. On due window, server triggers daemon injection.
84
+ 6. Daemon injects message + Enter into tmux pane.
85
+ 7. Client emits a normal request back; clock flow continues with tool semantics.
86
+
87
+ ### 4.3 Degraded path
88
+
89
+ - tmux missing/unavailable:
90
+ - Daemon path disabled.
91
+ - Server/client remain functional.
92
+ - Existing servertool followup behavior remains available.
93
+
94
+ ## 5. Private Syntax Contract
95
+
96
+ ### 5.1 Supported syntax
97
+
98
+ - `<**clock:{time,message}**>`
99
+
100
+ Example:
101
+
102
+ ```text
103
+ please remind me
104
+ <**clock:{"time":"2026-02-11T09:30:00+08:00","message":"standup"}**>
105
+ ```
106
+
107
+ ### 5.2 Parse behavior
108
+
109
+ - Parse from user content during inbound process.
110
+ - On success:
111
+ - Remove marker from user-visible content before upstream model processing.
112
+ - Convert to standard clock schedule input shape.
113
+ - On parse failure:
114
+ - Keep request safe and non-crashing.
115
+ - Skip conversion for invalid markers.
116
+
117
+ ## 6. Server Daemon Control Endpoints (localhost only)
118
+
119
+ - `POST /daemon/clock-client/register`
120
+ - `POST /daemon/clock-client/heartbeat`
121
+ - `POST /daemon/clock-client/inject`
122
+ - `POST /daemon/clock-client/unregister`
123
+
124
+ Payload fields include session/client type/tmux target/request id/injection text as needed.
125
+
126
+ ### 6.1 External injection CLI
127
+
128
+ - Command: `routecodex tmux-inject` / `rcc tmux-inject`
129
+ - Common usage:
130
+ - `rcc tmux-inject --port 5520 --list`
131
+ - `rcc tmux-inject --port 5520 --text "hello" --tmux-session-id <tmuxSessionId>`
132
+ - Target resolution rules:
133
+ - Prefer explicit `--tmux-session-id` (or legacy `--session-id` alias);
134
+ - else resolve via `--daemon-id`;
135
+ - else auto-select only when exactly one daemon session exists;
136
+ - otherwise fail-fast and require explicit target.
137
+
138
+ ## 7. Compatibility & Constraints
139
+
140
+ - Keep Provider V2 transport-only role unchanged.
141
+ - Keep host semantics minimal: no tool semantic repair in provider layer.
142
+ - Maintain existing servertool clock tests and behavior.
143
+
144
+ ## 8. Testing Strategy
145
+
146
+ 1. Baseline tests before implementation (done):
147
+ - `tests/servertool/servertool-clock.spec.ts`
148
+ - `tests/cli/smoke.spec.ts`
149
+ 2. Add tests for:
150
+ - marker parsing success/failure paths
151
+ - tool_call_id fallback generation
152
+ - launcher tmux available/unavailable branch
153
+ - daemon route localhost guard and injection handling
154
+ 3. Replay checks:
155
+ - one affected provider replay
156
+ - one unaffected control provider replay
157
+
158
+ ## 9. Rollout
159
+
160
+ 1. Introduce feature with default-safe degradation.
161
+ 2. Monitor logs for registration/injection failures.
162
+ 3. Keep fallback path active to avoid regression in non-tmux environments.
163
+
164
+
165
+ ## 10. Runtime delivery loop (routecodex-125)
166
+
167
+ To ensure due tasks are actually delivered to the client input surface (not only stored in task files), host server adds a background inject loop:
168
+
169
+ - Source of truth: `clock/*.json` under server-scoped `ROUTECODEX_SESSION_DIR`.
170
+ - Runtime config parsing: delegated to llmswitch-core `resolveClockConfig` bridge API.
171
+ - Due reservation: delegated to llmswitch-core `reserveDueTasksForRequest` bridge API.
172
+ - Delivery path: host `ClockClientRegistry.inject({ sessionId, ... })`, where `sessionId` can be conversation ID and is resolved to mapped `tmuxSessionId`.
173
+ - Commit rule: call `commitClockReservation` only after successful daemon injection.
174
+
175
+ ### 10.1 Lifecycle
176
+
177
+ - Start/restart loop on runtime setup (`setupRuntime`) to pick latest config and avoid stale timers.
178
+ - Stop loop on server shutdown (`stop`) to avoid orphan timer handles.
179
+ - Loop is best-effort and throttles repeated error logs.
180
+
181
+ ## 11. clock_hold_flow followup provider pinning
182
+
183
+ Clock auto-hold followup is stateful and must stay on the same provider alias as the triggering request.
184
+
185
+ Fix:
186
+
187
+ - In llmswitch-core `servertool/engine.ts`, `clock_hold_flow` now shares the same forced-provider behavior as `stop_message_flow`.
188
+ - Followup metadata includes `__shadowCompareForcedProviderKey=<current providerKey>`.
189
+ - This prevents alias drift on `:clock_hold_followup` request-id suffix hops and avoids compatibility mismatch (e.g., Responses provider requiring `instructions`).
190
+
191
+ ## 12. Verification evidence (this change set)
192
+
193
+ ### 12.1 Automated
194
+
195
+ - `sharedmodule/llmswitch-core`: `npm run build` ✅
196
+ - RouteCodex targeted suite (via `npm run jest:run -- --runTestsByPath ...`) ✅
197
+ - `tests/servertool/servertool-clock.spec.ts` (includes new provider pin regression)
198
+ - `tests/server/http-server/clock-client-routes.spec.ts`
199
+ - `tests/server/http-server/hub-policy-injection.spec.ts`
200
+ - `tests/server/http-server/quota-view-injection.spec.ts`
201
+ - `tests/cli/tmux-inject-command.spec.ts`
202
+ - `tests/cli/codex-command.spec.ts`
203
+ - `tests/cli/claude-command.spec.ts`
204
+ - `npm run build:dev` ✅
205
+ - `npm run install:global` ✅
206
+
207
+ ### 12.2 Live local proof (daemon auto-inject)
208
+
209
+ Using a temporary server on port `5630` + mock callback daemon:
210
+
211
+ 1. Register daemon with mapping `conversationSessionId=conv_clock_live -> tmuxSessionId=rcc_test_tmux`.
212
+ 2. Schedule one due task for `conv_clock_live` in task-store.
213
+ 3. Observe callback payload auto-arrival from server loop:
214
+
215
+ - `source: "clock.daemon.inject"`
216
+ - `tmuxSessionId: "rcc_test_tmux"`
217
+ - text includes `[Clock Reminder]` and scheduled task details.
218
+
219
+ 4. `/daemon/clock-client/list` shows `lastInjectAtMs` updated.
220
+
221
+ ## 13. Submit-key reliability hardening (routecodex-128)
222
+
223
+ Observed in live Codex tmux session (`rcc_codex_1770782906272_ac260d:0.0`):
224
+
225
+ - daemon text injection succeeded, but message stayed in compose box without being sent;
226
+ - manual `tmux send-keys Enter` immediately moved UI into `Working`, confirming target/session mapping was correct and failure was submit timing-related.
227
+
228
+ Fix applied in launcher daemon path:
229
+
230
+ - keep text injection and submit key as **two independent tmux commands**;
231
+ - after text injection, wait a short delay (`80ms`) before submit key dispatch;
232
+ - in daemon path, select submit key sequence with client-aware preference (`codex`/`claude`: `Enter` primary, fallback `C-m`/`KPEnter`);
233
+ - in launcher command bootstrap path, remove accidental `clientType` free variable and keep generic submit dispatch for shell command launch.
234
+
235
+ Validation:
236
+
237
+ - `npm run jest:run -- --runInBand --runTestsByPath tests/cli/codex-command.spec.ts tests/cli/claude-command.spec.ts tests/cli/tmux-inject-command.spec.ts` ✅
238
+ - `npm run jest:run -- --runInBand --runTestsByPath tests/server/http-server/clock-client-routes.spec.ts tests/server/http-server/executor-metadata.spec.ts tests/server/http-server/httpserver-apikey-env-resolution.spec.ts tests/utils/clock-client-token.spec.ts` ✅
239
+ - `npx tsc --noEmit` ✅
240
+
241
+ ## 14. Precise trigger mode (routecodex-129)
242
+
243
+ Clock daemon delivery now runs in exact due-time mode by default:
244
+
245
+ - host daemon inject loop rewrites effective clock config to `dueWindowMs=0` before reservation;
246
+ - this prevents early-fire behavior from legacy wide due windows in request-driven paths;
247
+ - task is triggered only when `now >= dueAt` (subject to polling interval, i.e. may be slightly late but never early).
248
+
249
+ Reminder payload and manual injection CLI now both include explicit waiting guidance:
250
+
251
+ - `MANDATORY: if waiting is needed, use the clock tool to schedule wake-up (clock.schedule) now; do not only promise to wait.`
252
+
253
+ ## 15. Recurrence + persistence + CRUD management (routecodex-130)
254
+
255
+ ### 15.1 Standard recurrence contract
256
+
257
+ `clock` now supports recurring schedules with mandatory run caps:
258
+
259
+ - `daily` + `maxRuns`
260
+ - `weekly` + `maxRuns`
261
+ - `interval` + `everyMinutes` + `maxRuns`
262
+
263
+ All recurrence tasks are persisted in clock session files and tracked by `deliveryCount`.
264
+ Task lifecycle is driven by reserve/commit in llmswitch-core:
265
+
266
+ - on each successful delivery commit, `deliveryCount += 1`
267
+ - if `deliveryCount >= maxRuns`, task is removed
268
+ - otherwise, task is re-scheduled to the next due time
269
+
270
+ Current weekly behavior uses fixed `+7d` stepping.
271
+
272
+ ### 15.2 Private marker syntax extensions
273
+
274
+ Private marker remains `<**clock:{...}**>`, now supporting recurrence fields in JSON form.
275
+
276
+ Examples:
277
+
278
+ ```text
279
+ <**clock:{"time":"2026-02-12T09:00:00+08:00","message":"daily standup","recurrence":{"kind":"daily","maxRuns":5}}**>
280
+ ```
281
+
282
+ ```text
283
+ <**clock:{"time":"2026-02-12T09:00:00+08:00","message":"weekly report","recurrence":{"kind":"weekly","maxRuns":4}}**>
284
+ ```
285
+
286
+ ```text
287
+ <**clock:{"time":"2026-02-12T09:00:00+08:00","message":"poll status","recurrence":{"kind":"interval","everyMinutes":30,"maxRuns":8}}**>
288
+ ```
289
+
290
+ Validation rule: if recurrence is present but invalid/missing required fields, marker scheduling is skipped (marker text remains unchanged).
291
+
292
+ ### 15.3 Cleanup policy (tmux vs conversation session)
293
+
294
+ Two session domains are intentionally separated:
295
+
296
+ - **tmuxSessionId**: daemon/runtime delivery domain
297
+ - **conversation sessionId**: clock task persistence domain
298
+
299
+ Cleanup behavior:
300
+
301
+ - tmux session gone → auto cleanup daemon record + mapping + clear mapped conversation clock tasks
302
+ - conversation session gone but tmux still alive → do not auto-clean; use explicit admin cleanup command
303
+
304
+ ### 15.4 Management APIs / CLI / WebUI
305
+
306
+ Added management endpoints:
307
+
308
+ - `GET /daemon/clock/tasks` (list)
309
+ - `POST /daemon/clock/tasks` (create)
310
+ - `PATCH /daemon/clock/tasks` (update)
311
+ - `DELETE /daemon/clock/tasks` (delete one / clear session)
312
+ - `POST /daemon/clock/cleanup` (`mode=dead_tmux|unbind`)
313
+
314
+ CLI management command:
315
+
316
+ - `rcc clock-admin --list`
317
+ - `rcc clock-admin --create --session-id <sid> --due-at <iso> --task <text> --recurrence interval --every-minutes 5 --max-runs 10`
318
+ - `rcc clock-admin --update --session-id <sid> --task-id <tid> --due-at <iso> --task "..."`
319
+ - `rcc clock-admin --delete --session-id <sid> --task-id <tid>`
320
+ - `rcc clock-admin --clear --session-id <sid>`
321
+ - `rcc clock-admin --cleanup-dead-tmux`
322
+ - `rcc clock-admin --unbind-session <conversationSessionId> [--clear-tasks]`
323
+
324
+ WebUI management entry:
325
+
326
+ - `GET /daemon/admin`
327
+ - use integrated `Clock` tab in `docs/daemon-admin-ui.html`
328
+
329
+ ### 15.5 Tool update support
330
+
331
+ Clock tool now supports `action=update` (with `taskId` + `items[0]`) so models can modify existing reminders instead of creating duplicates.
332
+
333
+ ### 15.6 Trigger precision and reminder guidance
334
+
335
+ Clock daemon inject loop uses exact due matching (`dueWindowMs=0`) to avoid early delivery.
336
+ Reminder payload includes guidance text:
337
+
338
+ - `MANDATORY: if waiting is needed, use the clock tool to schedule wake-up (clock.schedule) now; do not only promise to wait.`
339
+
340
+
341
+ ### 15.7 Overdue auto cleanup
342
+
343
+ One-shot tasks are auto-removed after overdue grace window (default 60s, capped by retentionMs) to avoid stale backlog.