openryoko 2026.5.28 → 2026.6.3

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 (235) hide show
  1. package/dist/assets/hook-relay.mjs +53 -0
  2. package/dist/bin/jimmy.js +2 -0
  3. package/dist/bin/jimmy.js.map +1 -1
  4. package/dist/package.json +3 -2
  5. package/dist/src/cli/update.d.ts +2 -0
  6. package/dist/src/cli/update.d.ts.map +1 -1
  7. package/dist/src/cli/update.js +39 -1
  8. package/dist/src/cli/update.js.map +1 -1
  9. package/dist/src/connectors/slack/__tests__/agents-canvas.test.js +1 -0
  10. package/dist/src/connectors/slack/__tests__/agents-canvas.test.js.map +1 -1
  11. package/dist/src/connectors/slack/index.d.ts.map +1 -1
  12. package/dist/src/connectors/slack/index.js +13 -3
  13. package/dist/src/connectors/slack/index.js.map +1 -1
  14. package/dist/src/engines/__tests__/claude-interactive-race.test.d.ts +2 -0
  15. package/dist/src/engines/__tests__/claude-interactive-race.test.d.ts.map +1 -0
  16. package/dist/src/engines/__tests__/claude-interactive-race.test.js +89 -0
  17. package/dist/src/engines/__tests__/claude-interactive-race.test.js.map +1 -0
  18. package/dist/src/engines/__tests__/claude-interactive-ssh-fallback.test.d.ts +2 -0
  19. package/dist/src/engines/__tests__/claude-interactive-ssh-fallback.test.d.ts.map +1 -0
  20. package/dist/src/engines/__tests__/claude-interactive-ssh-fallback.test.js +78 -0
  21. package/dist/src/engines/__tests__/claude-interactive-ssh-fallback.test.js.map +1 -0
  22. package/dist/src/engines/__tests__/claude-interactive.test.d.ts +2 -0
  23. package/dist/src/engines/__tests__/claude-interactive.test.d.ts.map +1 -0
  24. package/dist/src/engines/__tests__/claude-interactive.test.js +54 -0
  25. package/dist/src/engines/__tests__/claude-interactive.test.js.map +1 -0
  26. package/dist/src/engines/__tests__/claude.ssh.test.d.ts +2 -0
  27. package/dist/src/engines/__tests__/claude.ssh.test.d.ts.map +1 -0
  28. package/dist/src/engines/__tests__/claude.ssh.test.js +156 -0
  29. package/dist/src/engines/__tests__/claude.ssh.test.js.map +1 -0
  30. package/dist/src/engines/__tests__/pty-lifecycle.test.d.ts +2 -0
  31. package/dist/src/engines/__tests__/pty-lifecycle.test.d.ts.map +1 -0
  32. package/dist/src/engines/__tests__/pty-lifecycle.test.js +69 -0
  33. package/dist/src/engines/__tests__/pty-lifecycle.test.js.map +1 -0
  34. package/dist/src/engines/__tests__/sse-event-to-deltas.test.d.ts +2 -0
  35. package/dist/src/engines/__tests__/sse-event-to-deltas.test.d.ts.map +1 -0
  36. package/dist/src/engines/__tests__/sse-event-to-deltas.test.js +46 -0
  37. package/dist/src/engines/__tests__/sse-event-to-deltas.test.js.map +1 -0
  38. package/dist/src/engines/__tests__/sse-pty-proxy-classify.test.d.ts +2 -0
  39. package/dist/src/engines/__tests__/sse-pty-proxy-classify.test.d.ts.map +1 -0
  40. package/dist/src/engines/__tests__/sse-pty-proxy-classify.test.js +52 -0
  41. package/dist/src/engines/__tests__/sse-pty-proxy-classify.test.js.map +1 -0
  42. package/dist/src/engines/__tests__/sse-pty-proxy-retry.test.d.ts +2 -0
  43. package/dist/src/engines/__tests__/sse-pty-proxy-retry.test.d.ts.map +1 -0
  44. package/dist/src/engines/__tests__/sse-pty-proxy-retry.test.js +99 -0
  45. package/dist/src/engines/__tests__/sse-pty-proxy-retry.test.js.map +1 -0
  46. package/dist/src/engines/claude-interactive.d.ts +161 -0
  47. package/dist/src/engines/claude-interactive.d.ts.map +1 -0
  48. package/dist/src/engines/claude-interactive.js +796 -0
  49. package/dist/src/engines/claude-interactive.js.map +1 -0
  50. package/dist/src/engines/claude.d.ts +6 -0
  51. package/dist/src/engines/claude.d.ts.map +1 -1
  52. package/dist/src/engines/claude.js +264 -30
  53. package/dist/src/engines/claude.js.map +1 -1
  54. package/dist/src/engines/codex.d.ts.map +1 -1
  55. package/dist/src/engines/codex.js +21 -1
  56. package/dist/src/engines/codex.js.map +1 -1
  57. package/dist/src/engines/pty-lifecycle.d.ts +47 -0
  58. package/dist/src/engines/pty-lifecycle.d.ts.map +1 -0
  59. package/dist/src/engines/pty-lifecycle.js +130 -0
  60. package/dist/src/engines/pty-lifecycle.js.map +1 -0
  61. package/dist/src/engines/pty-view-engine.d.ts +29 -0
  62. package/dist/src/engines/pty-view-engine.d.ts.map +1 -0
  63. package/dist/src/engines/pty-view-engine.js +8 -0
  64. package/dist/src/engines/pty-view-engine.js.map +1 -0
  65. package/dist/src/engines/sse-pty-proxy.d.ts +95 -0
  66. package/dist/src/engines/sse-pty-proxy.d.ts.map +1 -0
  67. package/dist/src/engines/sse-pty-proxy.js +331 -0
  68. package/dist/src/engines/sse-pty-proxy.js.map +1 -0
  69. package/dist/src/gateway/__tests__/hook-endpoint.test.d.ts +2 -0
  70. package/dist/src/gateway/__tests__/hook-endpoint.test.d.ts.map +1 -0
  71. package/dist/src/gateway/__tests__/hook-endpoint.test.js +46 -0
  72. package/dist/src/gateway/__tests__/hook-endpoint.test.js.map +1 -0
  73. package/dist/src/gateway/__tests__/hook-registry.test.d.ts +2 -0
  74. package/dist/src/gateway/__tests__/hook-registry.test.d.ts.map +1 -0
  75. package/dist/src/gateway/__tests__/hook-registry.test.js +68 -0
  76. package/dist/src/gateway/__tests__/hook-registry.test.js.map +1 -0
  77. package/dist/src/gateway/__tests__/org.test.js +56 -1
  78. package/dist/src/gateway/__tests__/org.test.js.map +1 -1
  79. package/dist/src/gateway/__tests__/restart.test.d.ts +2 -0
  80. package/dist/src/gateway/__tests__/restart.test.d.ts.map +1 -0
  81. package/dist/src/gateway/__tests__/restart.test.js +154 -0
  82. package/dist/src/gateway/__tests__/restart.test.js.map +1 -0
  83. package/dist/src/gateway/api.d.ts +8 -0
  84. package/dist/src/gateway/api.d.ts.map +1 -1
  85. package/dist/src/gateway/api.js +98 -1
  86. package/dist/src/gateway/api.js.map +1 -1
  87. package/dist/src/gateway/gateway-info.d.ts +14 -0
  88. package/dist/src/gateway/gateway-info.d.ts.map +1 -0
  89. package/dist/src/gateway/gateway-info.js +36 -0
  90. package/dist/src/gateway/gateway-info.js.map +1 -0
  91. package/dist/src/gateway/hook-endpoint.d.ts +15 -0
  92. package/dist/src/gateway/hook-endpoint.d.ts.map +1 -0
  93. package/dist/src/gateway/hook-endpoint.js +25 -0
  94. package/dist/src/gateway/hook-endpoint.js.map +1 -0
  95. package/dist/src/gateway/hook-registry.d.ts +29 -0
  96. package/dist/src/gateway/hook-registry.d.ts.map +1 -0
  97. package/dist/src/gateway/hook-registry.js +63 -0
  98. package/dist/src/gateway/hook-registry.js.map +1 -0
  99. package/dist/src/gateway/lifecycle.d.ts +20 -0
  100. package/dist/src/gateway/lifecycle.d.ts.map +1 -1
  101. package/dist/src/gateway/lifecycle.js +78 -1
  102. package/dist/src/gateway/lifecycle.js.map +1 -1
  103. package/dist/src/gateway/org.d.ts +6 -0
  104. package/dist/src/gateway/org.d.ts.map +1 -1
  105. package/dist/src/gateway/org.js +27 -1
  106. package/dist/src/gateway/org.js.map +1 -1
  107. package/dist/src/gateway/pty-ws.d.ts +20 -0
  108. package/dist/src/gateway/pty-ws.d.ts.map +1 -0
  109. package/dist/src/gateway/pty-ws.js +109 -0
  110. package/dist/src/gateway/pty-ws.js.map +1 -0
  111. package/dist/src/gateway/server.d.ts.map +1 -1
  112. package/dist/src/gateway/server.js +191 -11
  113. package/dist/src/gateway/server.js.map +1 -1
  114. package/dist/src/sessions/__tests__/callbacks.test.js +1 -0
  115. package/dist/src/sessions/__tests__/callbacks.test.js.map +1 -1
  116. package/dist/src/sessions/manager.d.ts.map +1 -1
  117. package/dist/src/sessions/manager.js +46 -4
  118. package/dist/src/sessions/manager.js.map +1 -1
  119. package/dist/src/sessions/registry.d.ts +1 -0
  120. package/dist/src/sessions/registry.d.ts.map +1 -1
  121. package/dist/src/sessions/registry.js +7 -0
  122. package/dist/src/sessions/registry.js.map +1 -1
  123. package/dist/src/shared/__tests__/claude-settings.test.d.ts +2 -0
  124. package/dist/src/shared/__tests__/claude-settings.test.d.ts.map +1 -0
  125. package/dist/src/shared/__tests__/claude-settings.test.js +59 -0
  126. package/dist/src/shared/__tests__/claude-settings.test.js.map +1 -0
  127. package/dist/src/shared/__tests__/rateLimit.test.js +34 -1
  128. package/dist/src/shared/__tests__/rateLimit.test.js.map +1 -1
  129. package/dist/src/shared/claude-settings.d.ts +24 -0
  130. package/dist/src/shared/claude-settings.d.ts.map +1 -0
  131. package/dist/src/shared/claude-settings.js +69 -0
  132. package/dist/src/shared/claude-settings.js.map +1 -0
  133. package/dist/src/shared/paths.d.ts +7 -0
  134. package/dist/src/shared/paths.d.ts.map +1 -1
  135. package/dist/src/shared/paths.js +8 -0
  136. package/dist/src/shared/paths.js.map +1 -1
  137. package/dist/src/shared/rateLimit.d.ts +6 -0
  138. package/dist/src/shared/rateLimit.d.ts.map +1 -1
  139. package/dist/src/shared/rateLimit.js +28 -0
  140. package/dist/src/shared/rateLimit.js.map +1 -1
  141. package/dist/src/shared/skill-commands.d.ts +11 -0
  142. package/dist/src/shared/skill-commands.d.ts.map +1 -0
  143. package/dist/src/shared/skill-commands.js +34 -0
  144. package/dist/src/shared/skill-commands.js.map +1 -0
  145. package/dist/src/shared/types.d.ts +34 -1
  146. package/dist/src/shared/types.d.ts.map +1 -1
  147. package/dist/src/shared/types.js.map +1 -1
  148. package/dist/web/404.html +1 -1
  149. package/dist/web/__next.__PAGE__.txt +1 -1
  150. package/dist/web/__next._full.txt +1 -1
  151. package/dist/web/__next._head.txt +1 -1
  152. package/dist/web/__next._index.txt +1 -1
  153. package/dist/web/__next._tree.txt +1 -1
  154. package/dist/web/_next/static/chunks/0jm3e~uc~qd~p.js +79 -0
  155. package/dist/web/_next/static/chunks/17oc2l.ekcs8b.css +1 -0
  156. package/dist/web/_not-found/__next._full.txt +1 -1
  157. package/dist/web/_not-found/__next._head.txt +1 -1
  158. package/dist/web/_not-found/__next._index.txt +1 -1
  159. package/dist/web/_not-found/__next._not-found.__PAGE__.txt +1 -1
  160. package/dist/web/_not-found/__next._not-found.txt +1 -1
  161. package/dist/web/_not-found/__next._tree.txt +1 -1
  162. package/dist/web/_not-found.html +1 -1
  163. package/dist/web/_not-found.txt +1 -1
  164. package/dist/web/chat/__next._full.txt +3 -2
  165. package/dist/web/chat/__next._head.txt +1 -1
  166. package/dist/web/chat/__next._index.txt +1 -1
  167. package/dist/web/chat/__next._tree.txt +2 -1
  168. package/dist/web/chat/__next.chat.__PAGE__.txt +3 -2
  169. package/dist/web/chat/__next.chat.txt +1 -1
  170. package/dist/web/chat.html +1 -1
  171. package/dist/web/chat.txt +3 -2
  172. package/dist/web/cron/__next._full.txt +1 -1
  173. package/dist/web/cron/__next._head.txt +1 -1
  174. package/dist/web/cron/__next._index.txt +1 -1
  175. package/dist/web/cron/__next._tree.txt +1 -1
  176. package/dist/web/cron/__next.cron.__PAGE__.txt +1 -1
  177. package/dist/web/cron/__next.cron.txt +1 -1
  178. package/dist/web/cron.html +1 -1
  179. package/dist/web/cron.txt +1 -1
  180. package/dist/web/index.html +1 -1
  181. package/dist/web/index.txt +1 -1
  182. package/dist/web/kanban/__next._full.txt +1 -1
  183. package/dist/web/kanban/__next._head.txt +1 -1
  184. package/dist/web/kanban/__next._index.txt +1 -1
  185. package/dist/web/kanban/__next._tree.txt +1 -1
  186. package/dist/web/kanban/__next.kanban.__PAGE__.txt +1 -1
  187. package/dist/web/kanban/__next.kanban.txt +1 -1
  188. package/dist/web/kanban.html +1 -1
  189. package/dist/web/kanban.txt +1 -1
  190. package/dist/web/logs/__next._full.txt +1 -1
  191. package/dist/web/logs/__next._head.txt +1 -1
  192. package/dist/web/logs/__next._index.txt +1 -1
  193. package/dist/web/logs/__next._tree.txt +1 -1
  194. package/dist/web/logs/__next.logs.__PAGE__.txt +1 -1
  195. package/dist/web/logs/__next.logs.txt +1 -1
  196. package/dist/web/logs.html +1 -1
  197. package/dist/web/logs.txt +1 -1
  198. package/dist/web/org/__next._full.txt +1 -1
  199. package/dist/web/org/__next._head.txt +1 -1
  200. package/dist/web/org/__next._index.txt +1 -1
  201. package/dist/web/org/__next._tree.txt +1 -1
  202. package/dist/web/org/__next.org.__PAGE__.txt +1 -1
  203. package/dist/web/org/__next.org.txt +1 -1
  204. package/dist/web/org.html +1 -1
  205. package/dist/web/org.txt +1 -1
  206. package/dist/web/sessions/__next._full.txt +1 -1
  207. package/dist/web/sessions/__next._head.txt +1 -1
  208. package/dist/web/sessions/__next._index.txt +1 -1
  209. package/dist/web/sessions/__next._tree.txt +1 -1
  210. package/dist/web/sessions/__next.sessions.__PAGE__.txt +1 -1
  211. package/dist/web/sessions/__next.sessions.txt +1 -1
  212. package/dist/web/sessions.html +1 -1
  213. package/dist/web/sessions.txt +1 -1
  214. package/dist/web/settings/__next._full.txt +1 -1
  215. package/dist/web/settings/__next._head.txt +1 -1
  216. package/dist/web/settings/__next._index.txt +1 -1
  217. package/dist/web/settings/__next._tree.txt +1 -1
  218. package/dist/web/settings/__next.settings.__PAGE__.txt +1 -1
  219. package/dist/web/settings/__next.settings.txt +1 -1
  220. package/dist/web/settings.html +1 -1
  221. package/dist/web/settings.txt +1 -1
  222. package/dist/web/skills/__next._full.txt +1 -1
  223. package/dist/web/skills/__next._head.txt +1 -1
  224. package/dist/web/skills/__next._index.txt +1 -1
  225. package/dist/web/skills/__next._tree.txt +1 -1
  226. package/dist/web/skills/__next.skills.__PAGE__.txt +1 -1
  227. package/dist/web/skills/__next.skills.txt +1 -1
  228. package/dist/web/skills.html +1 -1
  229. package/dist/web/skills.txt +1 -1
  230. package/package.json +3 -2
  231. package/template/config.default.yaml +6 -0
  232. package/dist/web/_next/static/chunks/0z5lzlvft9.4o.js +0 -62
  233. /package/dist/web/_next/static/{bNLmW65Gsur_aLrJJh98i → oKaQ0ixfT8Uk-O0Ag7UXk}/_buildManifest.js +0 -0
  234. /package/dist/web/_next/static/{bNLmW65Gsur_aLrJJh98i → oKaQ0ixfT8Uk-O0Ag7UXk}/_clientMiddlewareManifest.js +0 -0
  235. /package/dist/web/_next/static/{bNLmW65Gsur_aLrJJh98i → oKaQ0ixfT8Uk-O0Ag7UXk}/_ssgManifest.js +0 -0
@@ -0,0 +1,78 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { InteractiveClaudeEngine } from "../claude-interactive.js";
3
+ import { PtyLifecycleManager } from "../pty-lifecycle.js";
4
+ import { HookRegistry } from "../../gateway/hook-registry.js";
5
+ /**
6
+ * OpenRyoko-specific: the interactive PTY engine runs Claude LOCALLY (for the Max
7
+ * subsidy), so it cannot drive a remote engine over SSH. When opts.sshHost is set
8
+ * it must delegate to the headless `claude -p` fallback, and route kill/isAlive/
9
+ * killAll there too. These cover that adaptation (not present upstream).
10
+ */
11
+ function makeFakeFallback() {
12
+ const calls = {
13
+ run: [], kill: [], killAll: 0, isAlive: [],
14
+ };
15
+ const engine = {
16
+ name: "claude",
17
+ run: async (opts) => {
18
+ calls.run.push(opts);
19
+ return { sessionId: "remote-sess", result: "from remote" };
20
+ },
21
+ kill: (sessionId) => { calls.kill.push(sessionId); },
22
+ isAlive: (sessionId) => { calls.isAlive.push(sessionId); return true; },
23
+ killAll: () => { calls.killAll += 1; },
24
+ };
25
+ return { engine, calls };
26
+ }
27
+ function makeEngine(fallback) {
28
+ const lifecycle = new PtyLifecycleManager({ maxLivePtys: 4 });
29
+ const registry = new HookRegistry();
30
+ const engine = new InteractiveClaudeEngine(lifecycle, registry, fallback);
31
+ return { engine, lifecycle, registry };
32
+ }
33
+ describe("InteractiveClaudeEngine SSH remote fallback", () => {
34
+ it("delegates run() to the fallback when sshHost is set", async () => {
35
+ const { engine: fallback, calls } = makeFakeFallback();
36
+ const { engine, registry } = makeEngine(fallback);
37
+ const result = await engine.run({
38
+ prompt: "hi",
39
+ cwd: "/tmp",
40
+ sshHost: "my-host",
41
+ sessionId: "s1",
42
+ });
43
+ expect(result.result).toBe("from remote");
44
+ expect(calls.run).toHaveLength(1);
45
+ expect(calls.run[0].sshHost).toBe("my-host");
46
+ registry.dispose();
47
+ });
48
+ it("does NOT delegate run() when sshHost is absent (would use local PTY)", async () => {
49
+ const { engine: fallback, calls } = makeFakeFallback();
50
+ const { engine, registry } = makeEngine(fallback);
51
+ // No sshHost → must NOT hit the fallback. We don't actually spawn a PTY here;
52
+ // just assert the fallback's run was never called for a local turn. Guard the
53
+ // local path by giving it a session already "active" so run() returns early.
54
+ engine.active.set("s2", {});
55
+ await engine.run({ prompt: "hi", cwd: "/tmp", sessionId: "s2" });
56
+ expect(calls.run).toHaveLength(0);
57
+ registry.dispose();
58
+ });
59
+ it("routes kill/isAlive/killAll to the fallback too", () => {
60
+ const { engine: fallback, calls } = makeFakeFallback();
61
+ const { engine, registry } = makeEngine(fallback);
62
+ engine.kill("s3", "Interrupted: test");
63
+ expect(calls.kill).toContain("s3");
64
+ expect(engine.isAlive("s4")).toBe(true);
65
+ expect(calls.isAlive).toContain("s4");
66
+ engine.killAll();
67
+ expect(calls.killAll).toBe(1);
68
+ registry.dispose();
69
+ });
70
+ it("works without a fallback (local-only) — kill/isAlive/killAll are safe no-ops", () => {
71
+ const { engine, registry } = makeEngine(undefined);
72
+ expect(() => engine.kill("x")).not.toThrow();
73
+ expect(engine.isAlive("x")).toBe(false);
74
+ expect(() => engine.killAll()).not.toThrow();
75
+ registry.dispose();
76
+ });
77
+ });
78
+ //# sourceMappingURL=claude-interactive-ssh-fallback.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-interactive-ssh-fallback.test.js","sourceRoot":"","sources":["../../../../src/engines/__tests__/claude-interactive-ssh-fallback.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=claude-interactive.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-interactive.test.d.ts","sourceRoot":"","sources":["../../../../src/engines/__tests__/claude-interactive.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ // claude-interactive.ts imports node-pty at the top level. node-pty loads its
3
+ // native module at import time and that fails on Linux CI runners (looks for
4
+ // prebuilds/linux-x64/pty.node under a wrong relative path). TurnResolver is a
5
+ // pure-JS class with zero PTY dependency, so mocking the module keeps the test
6
+ // focused and CI-portable.
7
+ vi.mock("node-pty", () => ({ spawn: vi.fn() }));
8
+ import { TurnResolver } from "../claude-interactive.js";
9
+ describe("TurnResolver", () => {
10
+ it("resolves only after BOTH SessionStart and Stop", async () => {
11
+ const r = new TurnResolver({ fallbackSessionId: "old" });
12
+ let resolved;
13
+ r.promise.then((v) => { resolved = v; });
14
+ r.onHook({ hook_event_name: "Stop", last_assistant_message: "done" });
15
+ await new Promise((res) => setTimeout(res, 5));
16
+ expect(resolved).toBeUndefined(); // Stop alone is not enough
17
+ r.onHook({ hook_event_name: "SessionStart", session_id: "claude-123" });
18
+ await new Promise((res) => setTimeout(res, 5));
19
+ expect(resolved.result).toBe("done");
20
+ expect(resolved.sessionId).toBe("claude-123");
21
+ expect(resolved.numTurns).toBe(1);
22
+ });
23
+ it("settles with an Interrupted error when killed", async () => {
24
+ const r = new TurnResolver({ fallbackSessionId: "old" });
25
+ r.onHook({ hook_event_name: "SessionStart", session_id: "c1" });
26
+ r.interrupt("Interrupted: user");
27
+ const v = await r.promise;
28
+ expect(v.error).toMatch(/^Interrupted/);
29
+ });
30
+ it("treats a missing session id as a hard error", async () => {
31
+ const r = new TurnResolver({ fallbackSessionId: undefined });
32
+ r.onHook({ hook_event_name: "SessionStart" }); // no session_id
33
+ r.onHook({ hook_event_name: "Stop", last_assistant_message: "x" });
34
+ const v = await r.promise;
35
+ expect(v.error).toMatch(/session id/i);
36
+ });
37
+ it("with assumeStarted, resolves on Stop alone using fallbackSessionId", async () => {
38
+ const r = new TurnResolver({ fallbackSessionId: "warm-sid", assumeStarted: true });
39
+ r.onHook({ hook_event_name: "Stop", last_assistant_message: "ok" });
40
+ const v = await r.promise;
41
+ expect(v.result).toBe("ok");
42
+ expect(v.sessionId).toBe("warm-sid");
43
+ expect(v.numTurns).toBe(1);
44
+ });
45
+ it("settles immediately on StopFailure (does not wait for SessionStart) and exposes it", async () => {
46
+ const r = new TurnResolver({ fallbackSessionId: "old" });
47
+ r.onHook({ hook_event_name: "StopFailure", error: "rate_limit", error_details: "resets 3pm" });
48
+ const v = await r.promise;
49
+ expect(v.error).toMatch(/rate_limit/);
50
+ expect(v.numTurns).toBe(1);
51
+ expect(r.stopFailure?.error).toBe("rate_limit");
52
+ });
53
+ });
54
+ //# sourceMappingURL=claude-interactive.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-interactive.test.js","sourceRoot":"","sources":["../../../../src/engines/__tests__/claude-interactive.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=claude.ssh.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.ssh.test.d.ts","sourceRoot":"","sources":["../../../../src/engines/__tests__/claude.ssh.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,156 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { EventEmitter } from "node:events";
3
+ vi.mock("node:child_process", () => ({
4
+ spawn: vi.fn(),
5
+ }));
6
+ vi.mock("../../shared/logger.js", () => ({
7
+ logger: { warn: vi.fn(), debug: vi.fn(), info: vi.fn(), error: vi.fn() },
8
+ }));
9
+ // resolveBin is only used on the local (non-SSH) path; keep it deterministic.
10
+ vi.mock("../../shared/resolveBin.js", () => ({
11
+ resolveBin: (bin) => `/usr/local/bin/${bin}`,
12
+ formatSpawnError: (label, bin, err) => `Failed to spawn ${label} (${bin}): ${err.message}`,
13
+ }));
14
+ import { spawn } from "node:child_process";
15
+ import { ClaudeEngine } from "../claude.js";
16
+ const mockSpawn = vi.mocked(spawn);
17
+ function createMockProcess() {
18
+ const proc = new EventEmitter();
19
+ proc.stdout = new EventEmitter();
20
+ proc.stderr = new EventEmitter();
21
+ proc.stdin = { write: vi.fn(), end: vi.fn(), on: vi.fn() };
22
+ proc.pid = 12345;
23
+ proc.exitCode = null;
24
+ proc.killed = false;
25
+ proc.kill = vi.fn(() => { proc.killed = true; });
26
+ return proc;
27
+ }
28
+ /** Emit a successful stream-json result and close the process. */
29
+ function finishOk(proc, result = "done") {
30
+ proc.stdout.emit("data", Buffer.from(JSON.stringify({ type: "result", subtype: "success", result, session_id: "sess-1" }) + "\n"));
31
+ proc.exitCode = 0;
32
+ proc.emit("close", 0);
33
+ }
34
+ describe("ClaudeEngine — SSH remote execution", () => {
35
+ let engine;
36
+ beforeEach(() => {
37
+ engine = new ClaudeEngine();
38
+ });
39
+ afterEach(() => {
40
+ vi.restoreAllMocks();
41
+ mockSpawn.mockReset();
42
+ });
43
+ it("runs claude over ssh and sends the prompt via stdin, never on the command line", async () => {
44
+ const proc = createMockProcess();
45
+ mockSpawn.mockReturnValue(proc);
46
+ // A prompt full of shell metacharacters and a flag-shaped token.
47
+ const nastyPrompt = "--help; rm -rf / $(curl evil) `id`";
48
+ const p = engine.run({ prompt: nastyPrompt, cwd: "/tmp", sshHost: "myhost", sessionId: "s1" });
49
+ const [bin, args] = mockSpawn.mock.calls[0];
50
+ expect(bin).toBe("ssh");
51
+ expect(args).toContain("-T");
52
+ expect(args).toContain("BatchMode=yes");
53
+ // host is passed after a `--` end-of-options guard
54
+ expect(args[args.indexOf("--") + 1]).toBe("myhost");
55
+ const remoteCmd = args[args.length - 1];
56
+ expect(remoteCmd).toContain("setsid sh -c");
57
+ expect(remoteCmd).toContain("__JINN_REMOTE_PGID__=$$");
58
+ // The untrusted prompt must NOT appear in the remote command line at all.
59
+ expect(remoteCmd).not.toContain("rm -rf");
60
+ expect(remoteCmd).not.toContain("curl evil");
61
+ // Prompt is delivered over stdin instead.
62
+ expect(proc.stdin.write).toHaveBeenCalledWith(nastyPrompt);
63
+ expect(proc.stdin.end).toHaveBeenCalled();
64
+ finishOk(proc);
65
+ await p;
66
+ });
67
+ it("drops local-only flags (--chrome, --mcp-config) on the remote command", async () => {
68
+ const proc = createMockProcess();
69
+ mockSpawn.mockReturnValue(proc);
70
+ const p = engine.run({ prompt: "hi", cwd: "/tmp", sshHost: "h", sessionId: "s2", mcpConfigPath: "/local/mcp.json" });
71
+ const args = mockSpawn.mock.calls[0][1];
72
+ const remoteCmd = args[args.length - 1];
73
+ expect(remoteCmd).not.toContain("--chrome");
74
+ expect(remoteCmd).not.toContain("--mcp-config");
75
+ expect(remoteCmd).not.toContain("/local/mcp.json");
76
+ finishOk(proc);
77
+ await p;
78
+ });
79
+ it("prepends a cd to remoteCwd when provided", async () => {
80
+ const proc = createMockProcess();
81
+ mockSpawn.mockReturnValue(proc);
82
+ const p = engine.run({ prompt: "hi", cwd: "/tmp", sshHost: "h", sessionId: "s3", remoteCwd: "/srv/work" });
83
+ const args = mockSpawn.mock.calls[0][1];
84
+ const remoteCmd = args[args.length - 1];
85
+ expect(remoteCmd).toMatch(/^cd '\/srv\/work' && setsid sh -c/);
86
+ finishOk(proc);
87
+ await p;
88
+ });
89
+ it("kill() terminates the remote process group over a second ssh connection", async () => {
90
+ const runProc = createMockProcess();
91
+ const killProc = createMockProcess();
92
+ mockSpawn.mockReturnValueOnce(runProc).mockReturnValueOnce(killProc);
93
+ const p = engine.run({ prompt: "long task", cwd: "/tmp", sshHost: "remote1", sessionId: "k1" });
94
+ // Remote supervisor reports its process-group id on stderr.
95
+ runProc.stderr.emit("data", Buffer.from("__JINN_REMOTE_PGID__=4242\n"));
96
+ engine.kill("k1", "User cancelled");
97
+ // Second spawn must be an ssh kill targeting the negative pgid.
98
+ expect(mockSpawn.mock.calls.length).toBeGreaterThanOrEqual(2);
99
+ const [killBin, killArgs] = mockSpawn.mock.calls[1];
100
+ expect(killBin).toBe("ssh");
101
+ expect(killArgs).toContain("remote1");
102
+ expect(killArgs.join(" ")).toContain("kill -s TERM -- -4242");
103
+ // Let the run settle as interrupted.
104
+ runProc.exitCode = 0;
105
+ runProc.emit("close", 0);
106
+ const result = await p;
107
+ expect(result.error).toBe("User cancelled");
108
+ });
109
+ it("defers the remote kill until the pgid marker arrives when kill() races startup", async () => {
110
+ const runProc = createMockProcess();
111
+ const killProc = createMockProcess();
112
+ mockSpawn.mockReturnValueOnce(runProc).mockReturnValueOnce(killProc);
113
+ const p = engine.run({ prompt: "task", cwd: "/tmp", sshHost: "remote2", sessionId: "race1" });
114
+ // Kill BEFORE the supervisor reported its pgid — no remote kill is possible yet.
115
+ engine.kill("race1", "User cancelled");
116
+ expect(mockSpawn.mock.calls.length).toBe(1);
117
+ // Marker arrives, split across two chunks (chunk-boundary robustness).
118
+ runProc.stderr.emit("data", Buffer.from("__JINN_REMOTE_PGID__=77"));
119
+ runProc.stderr.emit("data", Buffer.from("7\n"));
120
+ // The deferred remote kill must now have fired with the captured pgid.
121
+ expect(mockSpawn.mock.calls.length).toBe(2);
122
+ expect(mockSpawn.mock.calls[1][1].join(" ")).toContain("kill -s TERM -- -777");
123
+ runProc.exitCode = 0;
124
+ runProc.emit("close", 0);
125
+ const result = await p;
126
+ expect(result.error).toBe("User cancelled");
127
+ });
128
+ it("strips the pgid marker so it never leaks into reported stderr", async () => {
129
+ const proc = createMockProcess();
130
+ mockSpawn.mockReturnValue(proc);
131
+ const p = engine.run({ prompt: "hi", cwd: "/tmp", sshHost: "h", sessionId: "s4" });
132
+ proc.stderr.emit("data", Buffer.from("__JINN_REMOTE_PGID__=99\nreal warning\n"));
133
+ // Non-zero exit surfaces stderr; the marker line must be gone.
134
+ proc.exitCode = 2;
135
+ proc.emit("close", 2);
136
+ const result = await p;
137
+ expect(result.error ?? "").not.toContain("__JINN_REMOTE_PGID__");
138
+ });
139
+ });
140
+ describe("ClaudeEngine — local execution unchanged", () => {
141
+ let engine;
142
+ beforeEach(() => { engine = new ClaudeEngine(); });
143
+ afterEach(() => { vi.restoreAllMocks(); mockSpawn.mockReset(); });
144
+ it("passes the prompt as an argv element and does not write to stdin", async () => {
145
+ const proc = createMockProcess();
146
+ mockSpawn.mockReturnValue(proc);
147
+ const p = engine.run({ prompt: "hello world", cwd: "/tmp", sessionId: "l1" });
148
+ const [bin, args] = mockSpawn.mock.calls[0];
149
+ expect(bin).toBe("/usr/local/bin/claude");
150
+ expect(args).toContain("hello world");
151
+ expect(proc.stdin.write).not.toHaveBeenCalled();
152
+ finishOk(proc);
153
+ await p;
154
+ });
155
+ });
156
+ //# sourceMappingURL=claude.ssh.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.ssh.test.js","sourceRoot":"","sources":["../../../../src/engines/__tests__/claude.ssh.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pty-lifecycle.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty-lifecycle.test.d.ts","sourceRoot":"","sources":["../../../../src/engines/__tests__/pty-lifecycle.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { PtyLifecycleManager } from "../pty-lifecycle.js";
3
+ function fakeHandle() {
4
+ const h = { killed: false, pid: Math.floor(Math.random() * 9999) };
5
+ h.kill = () => { h.killed = true; };
6
+ return h;
7
+ }
8
+ describe("PtyLifecycleManager", () => {
9
+ it("registers a PTY and reports it as warm", () => {
10
+ const m = new PtyLifecycleManager({ maxLivePtys: 8 });
11
+ const h = fakeHandle();
12
+ m.adopt("sess-1", h);
13
+ expect(m.getWarm("sess-1")).toBe(h);
14
+ });
15
+ it("releaseSession kills the PTY, cleans the handle, and fires onCleanup", () => {
16
+ let cleaned = "";
17
+ const m = new PtyLifecycleManager({ maxLivePtys: 8, onCleanup: (id) => { cleaned = id; } });
18
+ const h = fakeHandle();
19
+ m.adopt("sess-2", h);
20
+ m.releaseSession("sess-2");
21
+ expect(h.killed).toBe(true);
22
+ expect(m.getWarm("sess-2")).toBeUndefined();
23
+ expect(cleaned).toBe("sess-2");
24
+ });
25
+ it("a PTY with no viewer dies within the grace window after turnEnded", () => {
26
+ // No viewer, no turn → grace window starts → reevaluate kills since lastTurnEndedAt is 0… actually
27
+ // lastTurnEndedAt is set on turnEnded, so within the 10-min cap it stays alive.
28
+ const m = new PtyLifecycleManager({ maxLivePtys: 8 });
29
+ const h = fakeHandle();
30
+ m.adopt("sess-3", h);
31
+ m.turnStarted("sess-3");
32
+ m.turnEnded("sess-3");
33
+ expect(h.killed).toBe(false); // still inside CLI_KEEPALIVE_AFTER_LEAVE_MS
34
+ });
35
+ it("a PTY with an active viewer survives turnEnded indefinitely (within the keep-alive cap)", () => {
36
+ const m = new PtyLifecycleManager({ maxLivePtys: 8 });
37
+ const h = fakeHandle();
38
+ m.adopt("sess-4", h);
39
+ m.viewerEnter("sess-4");
40
+ m.turnStarted("sess-4");
41
+ m.turnEnded("sess-4");
42
+ expect(h.killed).toBe(false);
43
+ });
44
+ it("releases the PTY when the last viewer leaves and no turn has ever run", () => {
45
+ const m = new PtyLifecycleManager({ maxLivePtys: 8 });
46
+ const h = fakeHandle();
47
+ m.adopt("sess-5", h);
48
+ m.viewerEnter("sess-5");
49
+ m.viewerLeave("sess-5");
50
+ // viewingEndedAt was just set to now → still inside 10-min grace → alive
51
+ expect(h.killed).toBe(false);
52
+ });
53
+ it("isAtCapacity is true once maxLivePtys is reached", () => {
54
+ const m = new PtyLifecycleManager({ maxLivePtys: 2 });
55
+ m.adopt("a", fakeHandle());
56
+ m.adopt("b", fakeHandle());
57
+ expect(m.isAtCapacity()).toBe(true);
58
+ });
59
+ it("killAll kills every live PTY", () => {
60
+ const m = new PtyLifecycleManager({ maxLivePtys: 8 });
61
+ const a = fakeHandle(), b = fakeHandle();
62
+ m.adopt("a", a);
63
+ m.adopt("b", b);
64
+ m.killAll();
65
+ expect(a.killed).toBe(true);
66
+ expect(b.killed).toBe(true);
67
+ });
68
+ });
69
+ //# sourceMappingURL=pty-lifecycle.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty-lifecycle.test.js","sourceRoot":"","sources":["../../../../src/engines/__tests__/pty-lifecycle.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sse-event-to-deltas.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-event-to-deltas.test.d.ts","sourceRoot":"","sources":["../../../../src/engines/__tests__/sse-event-to-deltas.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ // claude-interactive.ts imports node-pty at module load; mock it so this pure
3
+ // unit test stays CI-portable (no native binding needed).
4
+ vi.mock("node-pty", () => ({ spawn: vi.fn() }));
5
+ import { sseEventToDeltas } from "../claude-interactive.js";
6
+ describe("sseEventToDeltas (Item D — SSE → StreamDelta mapping)", () => {
7
+ it("maps message_start.usage to a context delta (input + cache_read + cache_creation)", () => {
8
+ const out = sseEventToDeltas({
9
+ type: "message_start",
10
+ message: { usage: { input_tokens: 600, cache_read_input_tokens: 10, cache_creation_input_tokens: 6 } },
11
+ });
12
+ expect(out).toEqual([{ type: "context", content: "616" }]);
13
+ });
14
+ it("emits no context delta when usage is absent or zero", () => {
15
+ expect(sseEventToDeltas({ type: "message_start", message: {} })).toEqual([]);
16
+ expect(sseEventToDeltas({ type: "message_start", message: { usage: { input_tokens: 0 } } })).toEqual([]);
17
+ });
18
+ it("maps a content_block_start tool_use to a tool_use marker (name + id)", () => {
19
+ const out = sseEventToDeltas({
20
+ type: "content_block_start",
21
+ content_block: { type: "tool_use", name: "Bash", id: "toolu_123" },
22
+ });
23
+ expect(out).toEqual([{ type: "tool_use", content: "Bash", toolName: "Bash", toolId: "toolu_123" }]);
24
+ });
25
+ it("ignores text/thinking content_block_start (their content arrives via deltas)", () => {
26
+ expect(sseEventToDeltas({ type: "content_block_start", content_block: { type: "text" } })).toEqual([]);
27
+ expect(sseEventToDeltas({ type: "content_block_start", content_block: { type: "thinking" } })).toEqual([]);
28
+ });
29
+ it("maps content_block_delta text_delta to an incremental text delta (word-by-word)", () => {
30
+ expect(sseEventToDeltas({ type: "content_block_delta", delta: { type: "text_delta", text: "PO" } }))
31
+ .toEqual([{ type: "text", content: "PO" }]);
32
+ expect(sseEventToDeltas({ type: "content_block_delta", delta: { type: "text_delta", text: "NG" } }))
33
+ .toEqual([{ type: "text", content: "NG" }]);
34
+ });
35
+ it("ignores empty text_delta, input_json_delta and thinking_delta", () => {
36
+ expect(sseEventToDeltas({ type: "content_block_delta", delta: { type: "text_delta", text: "" } })).toEqual([]);
37
+ expect(sseEventToDeltas({ type: "content_block_delta", delta: { type: "input_json_delta", partial_json: "{" } })).toEqual([]);
38
+ expect(sseEventToDeltas({ type: "content_block_delta", delta: { type: "thinking_delta", thinking: "hmm" } })).toEqual([]);
39
+ });
40
+ it("ignores lifecycle-only events (ping, content_block_stop, message_delta, message_stop)", () => {
41
+ for (const type of ["ping", "content_block_stop", "message_delta", "message_stop"]) {
42
+ expect(sseEventToDeltas({ type })).toEqual([]);
43
+ }
44
+ });
45
+ });
46
+ //# sourceMappingURL=sse-event-to-deltas.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-event-to-deltas.test.js","sourceRoot":"","sources":["../../../../src/engines/__tests__/sse-event-to-deltas.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sse-pty-proxy-classify.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-pty-proxy-classify.test.d.ts","sourceRoot":"","sources":["../../../../src/engines/__tests__/sse-pty-proxy-classify.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { SsePtyProxy } from "../sse-pty-proxy.js";
3
+ // Locks the main-vs-sub-agent classifier. The live bug: Claude Code fires
4
+ // AUXILIARY requests (haiku topic/title detection, quota checks) through the same
5
+ // per-PTY proxy. Those have no `tools`. If one set the main fingerprint (or simply
6
+ // differed from it), every real turn's request was tagged as a "sub-agent" → a
7
+ // card spawned per message/tool call. The fix gates classification on a non-empty
8
+ // `tools` array.
9
+ /** classifyRequest is private; reach it directly for a focused unit test. */
10
+ function classify(proxy, body) {
11
+ return proxy
12
+ .classifyRequest(Buffer.from(JSON.stringify(body)));
13
+ }
14
+ const TOOLS = [{ name: "Bash", description: "run", input_schema: { type: "object" } }];
15
+ function newProxy() {
16
+ return new SsePtyProxy("test", () => { });
17
+ }
18
+ describe("SsePtyProxy.classifyRequest", () => {
19
+ it("never tags an auxiliary (no-tools) request, even with a novel system", () => {
20
+ const proxy = newProxy();
21
+ const aux = { system: "Detect if this is a new topic.", messages: [{ role: "user", content: "hi" }] };
22
+ expect(classify(proxy, aux)).toEqual({});
23
+ });
24
+ it("an auxiliary request does NOT poison the main fingerprint", () => {
25
+ const proxy = newProxy();
26
+ // Aux lands first (the poisoning scenario) — must be ignored...
27
+ classify(proxy, { system: "topic-detector", messages: [], tools: [] });
28
+ // ...so the first TOOL-BEARING request becomes main (untagged), and the next
29
+ // identical main turn stays main (no spurious card).
30
+ const main = { system: "MAIN", messages: [{ role: "user", content: "do x" }], tools: TOOLS };
31
+ expect(classify(proxy, main)).toEqual({});
32
+ expect(classify(proxy, main)).toEqual({});
33
+ });
34
+ it("tags a tool-bearing request whose system differs from main as a sub-agent", () => {
35
+ const proxy = newProxy();
36
+ classify(proxy, { system: "MAIN", messages: [{ role: "user", content: "main task" }], tools: TOOLS });
37
+ const sub = { system: "SUBAGENT", messages: [{ role: "user", content: "find all bugs" }], tools: TOOLS };
38
+ const ctx = classify(proxy, sub);
39
+ expect(ctx.subAgent).toBeTruthy();
40
+ expect(ctx.subAgent?.label).toBe("find all bugs");
41
+ // Stable id across the sub-agent's turns.
42
+ expect(classify(proxy, sub).subAgent?.id).toBe(ctx.subAgent?.id);
43
+ });
44
+ it("does not tag main-agent tool rounds (stable system) as sub-agents", () => {
45
+ const proxy = newProxy();
46
+ const main = { system: "MAIN", messages: [{ role: "user", content: "x" }], tools: TOOLS };
47
+ classify(proxy, main); // sets main fp
48
+ for (let i = 0; i < 5; i++)
49
+ expect(classify(proxy, main)).toEqual({});
50
+ });
51
+ });
52
+ //# sourceMappingURL=sse-pty-proxy-classify.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-pty-proxy-classify.test.js","sourceRoot":"","sources":["../../../../src/engines/__tests__/sse-pty-proxy-classify.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sse-pty-proxy-retry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-pty-proxy-retry.test.d.ts","sourceRoot":"","sources":["../../../../src/engines/__tests__/sse-pty-proxy-retry.test.ts"],"names":[],"mappings":""}