wave-code 1.0.9 → 1.1.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 (244) hide show
  1. package/bin/wave-code.js +8 -2
  2. package/dist/bundle/wave.mjs +3207 -0
  3. package/package.json +24 -25
  4. package/src/commands/update.ts +2 -7
  5. package/src/components/App.tsx +3 -7
  6. package/src/components/BtwDisplay.tsx +10 -1
  7. package/src/components/ChatInterface.tsx +21 -52
  8. package/src/components/ConfirmationDetails.tsx +144 -37
  9. package/src/components/DiffDisplay.tsx +335 -301
  10. package/src/components/InputBox.tsx +3 -1
  11. package/src/components/LoadingIndicator.tsx +16 -2
  12. package/src/components/MessageBlockItem.tsx +2 -4
  13. package/src/components/MessageList.tsx +75 -14
  14. package/src/components/ReasoningDisplay.tsx +2 -4
  15. package/src/components/SessionSelector.tsx +82 -11
  16. package/src/components/StatusCommand.tsx +2 -9
  17. package/src/components/ToolDisplay.tsx +2 -4
  18. package/src/contexts/useChat.tsx +172 -350
  19. package/src/daemon/commands.ts +57 -27
  20. package/src/daemon/jsonRpcClient.ts +1 -1
  21. package/src/daemon/socketClient.ts +2 -2
  22. package/src/hooks/useInputManager.ts +1 -1
  23. package/src/index.ts +57 -10
  24. package/src/managers/inputReducer.ts +186 -104
  25. package/src/print-cli.ts +21 -17
  26. package/src/reducers/selectorReducer.ts +10 -0
  27. package/src/session-selector-cli.tsx +269 -28
  28. package/src/stdio/agentBridge.ts +22 -21
  29. package/src/stdio/daemonServer.ts +3 -1
  30. package/src/stdio/jsonRpcConnection.ts +19 -1
  31. package/src/stdio/stdioServer.ts +17 -0
  32. package/src/utils/clipboard.ts +21 -0
  33. package/src/utils/highlightUtils.ts +46 -1
  34. package/src/utils/readPackageJson.ts +29 -0
  35. package/src/utils/streamingText.ts +11 -0
  36. package/src/utils/worktree.ts +191 -43
  37. package/dist/cli.d.ts +0 -6
  38. package/dist/cli.js +0 -53
  39. package/dist/commands/plugin/disable.d.ts +0 -5
  40. package/dist/commands/plugin/disable.js +0 -15
  41. package/dist/commands/plugin/enable.d.ts +0 -5
  42. package/dist/commands/plugin/enable.js +0 -15
  43. package/dist/commands/plugin/install.d.ts +0 -5
  44. package/dist/commands/plugin/install.js +0 -21
  45. package/dist/commands/plugin/list.d.ts +0 -1
  46. package/dist/commands/plugin/list.js +0 -31
  47. package/dist/commands/plugin/marketplace.d.ts +0 -10
  48. package/dist/commands/plugin/marketplace.js +0 -90
  49. package/dist/commands/plugin/uninstall.d.ts +0 -3
  50. package/dist/commands/plugin/uninstall.js +0 -16
  51. package/dist/commands/plugin/update.d.ts +0 -3
  52. package/dist/commands/plugin/update.js +0 -15
  53. package/dist/commands/update.d.ts +0 -1
  54. package/dist/commands/update.js +0 -97
  55. package/dist/components/AgentsManager.d.ts +0 -7
  56. package/dist/components/AgentsManager.js +0 -109
  57. package/dist/components/App.d.ts +0 -9
  58. package/dist/components/App.js +0 -76
  59. package/dist/components/BackgroundTaskManager.d.ts +0 -5
  60. package/dist/components/BackgroundTaskManager.js +0 -99
  61. package/dist/components/BangDisplay.d.ts +0 -8
  62. package/dist/components/BangDisplay.js +0 -17
  63. package/dist/components/BtwDisplay.d.ts +0 -7
  64. package/dist/components/BtwDisplay.js +0 -19
  65. package/dist/components/ChatInterface.d.ts +0 -2
  66. package/dist/components/ChatInterface.js +0 -61
  67. package/dist/components/CommandSelector.d.ts +0 -10
  68. package/dist/components/CommandSelector.js +0 -66
  69. package/dist/components/CompactDisplay.d.ts +0 -8
  70. package/dist/components/CompactDisplay.js +0 -13
  71. package/dist/components/ConfirmationDetails.d.ts +0 -9
  72. package/dist/components/ConfirmationDetails.js +0 -45
  73. package/dist/components/ConfirmationSelector.d.ts +0 -13
  74. package/dist/components/ConfirmationSelector.js +0 -127
  75. package/dist/components/DiffDisplay.d.ts +0 -8
  76. package/dist/components/DiffDisplay.js +0 -201
  77. package/dist/components/DiscoverView.d.ts +0 -2
  78. package/dist/components/DiscoverView.js +0 -37
  79. package/dist/components/FileSelector.d.ts +0 -11
  80. package/dist/components/FileSelector.js +0 -50
  81. package/dist/components/HelpView.d.ts +0 -7
  82. package/dist/components/HelpView.js +0 -74
  83. package/dist/components/HistorySearch.d.ts +0 -8
  84. package/dist/components/HistorySearch.js +0 -66
  85. package/dist/components/InputBox.d.ts +0 -24
  86. package/dist/components/InputBox.js +0 -149
  87. package/dist/components/InstalledView.d.ts +0 -2
  88. package/dist/components/InstalledView.js +0 -45
  89. package/dist/components/LoadingIndicator.d.ts +0 -10
  90. package/dist/components/LoadingIndicator.js +0 -6
  91. package/dist/components/LoginCommand.d.ts +0 -5
  92. package/dist/components/LoginCommand.js +0 -153
  93. package/dist/components/Markdown.d.ts +0 -5
  94. package/dist/components/Markdown.js +0 -127
  95. package/dist/components/MarketplaceAddForm.d.ts +0 -2
  96. package/dist/components/MarketplaceAddForm.js +0 -55
  97. package/dist/components/MarketplaceDetail.d.ts +0 -2
  98. package/dist/components/MarketplaceDetail.js +0 -74
  99. package/dist/components/MarketplaceList.d.ts +0 -8
  100. package/dist/components/MarketplaceList.js +0 -17
  101. package/dist/components/MarketplaceView.d.ts +0 -2
  102. package/dist/components/MarketplaceView.js +0 -41
  103. package/dist/components/McpManager.d.ts +0 -9
  104. package/dist/components/McpManager.js +0 -88
  105. package/dist/components/MessageBlockItem.d.ts +0 -8
  106. package/dist/components/MessageBlockItem.js +0 -15
  107. package/dist/components/MessageList.d.ts +0 -10
  108. package/dist/components/MessageList.js +0 -80
  109. package/dist/components/ModelSelector.d.ts +0 -8
  110. package/dist/components/ModelSelector.js +0 -45
  111. package/dist/components/Notifications.d.ts +0 -7
  112. package/dist/components/Notifications.js +0 -9
  113. package/dist/components/PlanDisplay.d.ts +0 -7
  114. package/dist/components/PlanDisplay.js +0 -6
  115. package/dist/components/PluginDetail.d.ts +0 -2
  116. package/dist/components/PluginDetail.js +0 -87
  117. package/dist/components/PluginList.d.ts +0 -13
  118. package/dist/components/PluginList.js +0 -15
  119. package/dist/components/PluginManagerShell.d.ts +0 -6
  120. package/dist/components/PluginManagerShell.js +0 -92
  121. package/dist/components/PluginManagerTypes.d.ts +0 -35
  122. package/dist/components/PluginManagerTypes.js +0 -1
  123. package/dist/components/QueuedMessageList.d.ts +0 -2
  124. package/dist/components/QueuedMessageList.js +0 -18
  125. package/dist/components/ReasoningDisplay.d.ts +0 -8
  126. package/dist/components/ReasoningDisplay.js +0 -13
  127. package/dist/components/RewindCommand.d.ts +0 -12
  128. package/dist/components/RewindCommand.js +0 -78
  129. package/dist/components/SessionSelector.d.ts +0 -12
  130. package/dist/components/SessionSelector.js +0 -47
  131. package/dist/components/StatusCommand.d.ts +0 -5
  132. package/dist/components/StatusCommand.js +0 -28
  133. package/dist/components/StatusLine.d.ts +0 -6
  134. package/dist/components/StatusLine.js +0 -9
  135. package/dist/components/TaskList.d.ts +0 -5
  136. package/dist/components/TaskList.js +0 -197
  137. package/dist/components/TaskNotificationMessage.d.ts +0 -5
  138. package/dist/components/TaskNotificationMessage.js +0 -12
  139. package/dist/components/ToolDisplay.d.ts +0 -9
  140. package/dist/components/ToolDisplay.js +0 -55
  141. package/dist/components/WorkflowManager.d.ts +0 -5
  142. package/dist/components/WorkflowManager.js +0 -102
  143. package/dist/components/WorktreeExitPrompt.d.ts +0 -12
  144. package/dist/components/WorktreeExitPrompt.js +0 -35
  145. package/dist/constants/commands.d.ts +0 -2
  146. package/dist/constants/commands.js +0 -92
  147. package/dist/contexts/PluginManagerContext.d.ts +0 -3
  148. package/dist/contexts/PluginManagerContext.js +0 -9
  149. package/dist/contexts/useAppConfig.d.ts +0 -10
  150. package/dist/contexts/useAppConfig.js +0 -13
  151. package/dist/contexts/useChat.d.ts +0 -101
  152. package/dist/contexts/useChat.js +0 -992
  153. package/dist/contracts/status.d.ts +0 -7
  154. package/dist/contracts/status.js +0 -1
  155. package/dist/daemon/commands.d.ts +0 -49
  156. package/dist/daemon/commands.js +0 -341
  157. package/dist/daemon/jsonRpcClient.d.ts +0 -38
  158. package/dist/daemon/jsonRpcClient.js +0 -129
  159. package/dist/daemon/socketClient.d.ts +0 -13
  160. package/dist/daemon/socketClient.js +0 -26
  161. package/dist/daemon-cli.d.ts +0 -10
  162. package/dist/daemon-cli.js +0 -15
  163. package/dist/hooks/useInputManager.d.ts +0 -75
  164. package/dist/hooks/useInputManager.js +0 -583
  165. package/dist/hooks/usePluginManager.d.ts +0 -4
  166. package/dist/hooks/usePluginManager.js +0 -265
  167. package/dist/hooks/useTasks.d.ts +0 -1
  168. package/dist/hooks/useTasks.js +0 -5
  169. package/dist/index.d.ts +0 -4
  170. package/dist/index.js +0 -447
  171. package/dist/managers/inputHandlers.d.ts +0 -30
  172. package/dist/managers/inputHandlers.js +0 -625
  173. package/dist/managers/inputReducer.d.ts +0 -271
  174. package/dist/managers/inputReducer.js +0 -1121
  175. package/dist/plugin-manager-cli.d.ts +0 -5
  176. package/dist/plugin-manager-cli.js +0 -12
  177. package/dist/print-cli.d.ts +0 -10
  178. package/dist/print-cli.js +0 -209
  179. package/dist/reducers/agentsManagerReducer.d.ts +0 -26
  180. package/dist/reducers/agentsManagerReducer.js +0 -54
  181. package/dist/reducers/backgroundTaskManagerReducer.d.ts +0 -62
  182. package/dist/reducers/backgroundTaskManagerReducer.js +0 -106
  183. package/dist/reducers/confirmationReducer.d.ts +0 -37
  184. package/dist/reducers/confirmationReducer.js +0 -193
  185. package/dist/reducers/helpSelectorReducer.d.ts +0 -25
  186. package/dist/reducers/helpSelectorReducer.js +0 -52
  187. package/dist/reducers/marketplaceAddFormReducer.d.ts +0 -24
  188. package/dist/reducers/marketplaceAddFormReducer.js +0 -58
  189. package/dist/reducers/mcpManagerReducer.d.ts +0 -37
  190. package/dist/reducers/mcpManagerReducer.js +0 -74
  191. package/dist/reducers/pluginDetailReducer.d.ts +0 -32
  192. package/dist/reducers/pluginDetailReducer.js +0 -70
  193. package/dist/reducers/questionReducer.d.ts +0 -82
  194. package/dist/reducers/questionReducer.js +0 -375
  195. package/dist/reducers/rewindSelectorReducer.d.ts +0 -21
  196. package/dist/reducers/rewindSelectorReducer.js +0 -37
  197. package/dist/reducers/selectorReducer.d.ts +0 -23
  198. package/dist/reducers/selectorReducer.js +0 -42
  199. package/dist/reducers/workflowManagerReducer.d.ts +0 -40
  200. package/dist/reducers/workflowManagerReducer.js +0 -100
  201. package/dist/session-selector-cli.d.ts +0 -3
  202. package/dist/session-selector-cli.js +0 -25
  203. package/dist/stdio/agentBridge.d.ts +0 -139
  204. package/dist/stdio/agentBridge.js +0 -999
  205. package/dist/stdio/daemonServer.d.ts +0 -67
  206. package/dist/stdio/daemonServer.js +0 -191
  207. package/dist/stdio/index.d.ts +0 -5
  208. package/dist/stdio/index.js +0 -5
  209. package/dist/stdio/jsonRpcConnection.d.ts +0 -30
  210. package/dist/stdio/jsonRpcConnection.js +0 -127
  211. package/dist/stdio/protocol.d.ts +0 -41
  212. package/dist/stdio/protocol.js +0 -26
  213. package/dist/stdio/stdioServer.d.ts +0 -28
  214. package/dist/stdio/stdioServer.js +0 -36
  215. package/dist/stdio-cli.d.ts +0 -8
  216. package/dist/stdio-cli.js +0 -15
  217. package/dist/types.d.ts +0 -20
  218. package/dist/types.js +0 -1
  219. package/dist/utils/bracketedPaste.d.ts +0 -39
  220. package/dist/utils/bracketedPaste.js +0 -122
  221. package/dist/utils/clipboard.d.ts +0 -21
  222. package/dist/utils/clipboard.js +0 -347
  223. package/dist/utils/constants.d.ts +0 -16
  224. package/dist/utils/constants.js +0 -18
  225. package/dist/utils/highlightUtils.d.ts +0 -1
  226. package/dist/utils/highlightUtils.js +0 -93
  227. package/dist/utils/inputUtils.d.ts +0 -17
  228. package/dist/utils/inputUtils.js +0 -67
  229. package/dist/utils/logger.d.ts +0 -71
  230. package/dist/utils/logger.js +0 -259
  231. package/dist/utils/markdownTable.d.ts +0 -34
  232. package/dist/utils/markdownTable.js +0 -302
  233. package/dist/utils/rewindCheckpoints.d.ts +0 -8
  234. package/dist/utils/rewindCheckpoints.js +0 -17
  235. package/dist/utils/throttle.d.ts +0 -14
  236. package/dist/utils/throttle.js +0 -55
  237. package/dist/utils/toolParameterTransforms.d.ts +0 -18
  238. package/dist/utils/toolParameterTransforms.js +0 -73
  239. package/dist/utils/usageSummary.d.ts +0 -28
  240. package/dist/utils/usageSummary.js +0 -121
  241. package/dist/utils/version.d.ts +0 -1
  242. package/dist/utils/version.js +0 -4
  243. package/dist/utils/worktree.d.ts +0 -35
  244. package/dist/utils/worktree.js +0 -219
@@ -1,67 +0,0 @@
1
- /**
2
- * DaemonServer — JSON-RPC server over a unix socket for remote background
3
- * sessions (spec: docs/specs/ui/desktop-app.md 「SSH 远程后台会话」).
4
- *
5
- * The desktop app launches `wave --daemon <socket>` on the remote host via
6
- * nohup/setsid, then tunnels the socket back with `ssh -L`. All connections
7
- * share one AgentBridge, so sessions and pending tool permissions survive
8
- * client detach/attach — the daemon keeps running (and generating) while no
9
- * desktop is connected. The daemon never exits on a client disconnect; it
10
- * only exits when killed (app quit / 删除会话 / remote reboot).
11
- *
12
- * Idle auto-exit (spec: 「远程 daemon 空闲自动退出」): once every session has
13
- * settled and no client is connected, the daemon mirrors `wave -p`'s exit
14
- * semantics — after a grace period it destroys the sessions (saving their
15
- * transcripts), closes the socket, and exits, so the remote process doesn't
16
- * linger forever after background work completes.
17
- */
18
- import { AgentBridge, type AgentBridgeOptions } from "./agentBridge.js";
19
- export interface DaemonServerOptions {
20
- socketPath: string;
21
- bridgeOptions?: AgentBridgeOptions;
22
- /** Idle grace period before the daemon auto-exits (default 60s). */
23
- graceMs?: number;
24
- }
25
- export declare class DaemonServer {
26
- static readonly DEFAULT_IDLE_GRACE_MS = 60000;
27
- private socketPath;
28
- private server;
29
- private bridge;
30
- private connections;
31
- private sockets;
32
- private graceMs;
33
- private idleTimer;
34
- private shuttingDown;
35
- private stopped;
36
- constructor(options: DaemonServerOptions);
37
- get agentBridge(): AgentBridge;
38
- /**
39
- * Listen on the socket path. Rejects when a live daemon already holds it. A
40
- * stale socket file left by a crashed daemon would otherwise block the
41
- * restart with EADDRINUSE, so it is cleaned up first: non-socket files are
42
- * unlinked outright; socket files are probe-connected — ECONNREFUSED means
43
- * no listener (stale → unlink and listen), anything else means a live
44
- * daemon owns the path (reject).
45
- */
46
- start(): Promise<void>;
47
- private listen;
48
- stop(): Promise<void>;
49
- private clearIdleTimer;
50
- /**
51
- * Re-evaluate the idle condition after any state transition: sessions busy
52
- * (loading / pending messages / background work) or any client attached →
53
- * cancel the timer. Fully idle + detached → arm the grace timer once; when
54
- * it fires, shut the daemon down. Evaluation is event-driven (every
55
- * busy→idle transition emits a notification, every attach/detach fires a
56
- * connection event), so nothing is polled. The failure mode is
57
- * conservative: a missed transition just leaves the daemon running.
58
- */
59
- private evaluateIdle;
60
- /**
61
- * Destroy the sessions (each agent saves its transcript and drains
62
- * auto-memory), close the listener, unlink the socket file, then exit.
63
- * `shuttingDown` guards against re-entry: new connections are refused and
64
- * further idle evaluations become no-ops.
65
- */
66
- private shutdown;
67
- }
@@ -1,191 +0,0 @@
1
- /**
2
- * DaemonServer — JSON-RPC server over a unix socket for remote background
3
- * sessions (spec: docs/specs/ui/desktop-app.md 「SSH 远程后台会话」).
4
- *
5
- * The desktop app launches `wave --daemon <socket>` on the remote host via
6
- * nohup/setsid, then tunnels the socket back with `ssh -L`. All connections
7
- * share one AgentBridge, so sessions and pending tool permissions survive
8
- * client detach/attach — the daemon keeps running (and generating) while no
9
- * desktop is connected. The daemon never exits on a client disconnect; it
10
- * only exits when killed (app quit / 删除会话 / remote reboot).
11
- *
12
- * Idle auto-exit (spec: 「远程 daemon 空闲自动退出」): once every session has
13
- * settled and no client is connected, the daemon mirrors `wave -p`'s exit
14
- * semantics — after a grace period it destroys the sessions (saving their
15
- * transcripts), closes the socket, and exits, so the remote process doesn't
16
- * linger forever after background work completes.
17
- */
18
- import net from "net";
19
- import * as fs from "fs";
20
- import { AgentBridge } from "./agentBridge.js";
21
- import { JsonRpcConnection } from "./jsonRpcConnection.js";
22
- export class DaemonServer {
23
- constructor(options) {
24
- this.connections = new Set();
25
- this.sockets = new Set();
26
- this.shuttingDown = false;
27
- this.stopped = false;
28
- this.socketPath = options.socketPath;
29
- this.graceMs = options.graceMs ?? DaemonServer.DEFAULT_IDLE_GRACE_MS;
30
- this.bridge = new AgentBridge({
31
- ...options.bridgeOptions,
32
- // Notifications go to every attached client; a fully detached daemon
33
- // has none, and the write is dropped silently (the attach snapshot
34
- // re-syncs state on reconnect).
35
- emit: (method, params, sessionId) => {
36
- for (const conn of this.connections) {
37
- conn.sendNotification(method, params, sessionId);
38
- }
39
- // Any session activity can change the idle state — re-evaluate.
40
- this.evaluateIdle();
41
- },
42
- });
43
- this.server = net.createServer((socket) => {
44
- if (this.shuttingDown) {
45
- socket.destroy();
46
- return;
47
- }
48
- const conn = new JsonRpcConnection(socket, socket, this.bridge);
49
- this.connections.add(conn);
50
- this.sockets.add(socket);
51
- // A (re)attached client cancels a pending idle exit.
52
- this.evaluateIdle();
53
- socket.on("error", () => {
54
- // The client (ssh tunnel) can reset the socket mid-detach; the daemon
55
- // must keep running — 'close' below cleans up the connection.
56
- });
57
- socket.on("close", () => {
58
- this.connections.delete(conn);
59
- this.sockets.delete(socket);
60
- // A client detach may leave the daemon idle — re-evaluate.
61
- this.evaluateIdle();
62
- });
63
- conn.start();
64
- });
65
- }
66
- get agentBridge() {
67
- return this.bridge;
68
- }
69
- /**
70
- * Listen on the socket path. Rejects when a live daemon already holds it. A
71
- * stale socket file left by a crashed daemon would otherwise block the
72
- * restart with EADDRINUSE, so it is cleaned up first: non-socket files are
73
- * unlinked outright; socket files are probe-connected — ECONNREFUSED means
74
- * no listener (stale → unlink and listen), anything else means a live
75
- * daemon owns the path (reject).
76
- */
77
- start() {
78
- return new Promise((resolve, reject) => {
79
- const server = this.server;
80
- if (!server)
81
- return resolve();
82
- try {
83
- const st = fs.statSync(this.socketPath);
84
- if (st.isSocket()) {
85
- const probe = net.connect(this.socketPath);
86
- probe.once("connect", () => {
87
- probe.destroy();
88
- reject(new Error(`另一个 wave daemon 已在 ${this.socketPath} 监听`));
89
- });
90
- probe.once("error", (err) => {
91
- probe.destroy();
92
- if (err.code === "ECONNREFUSED") {
93
- fs.unlinkSync(this.socketPath);
94
- this.listen(server, resolve, reject);
95
- }
96
- else {
97
- reject(err);
98
- }
99
- });
100
- return;
101
- }
102
- fs.unlinkSync(this.socketPath);
103
- }
104
- catch {
105
- // ENOENT — no stale socket, listen directly.
106
- }
107
- this.listen(server, resolve, reject);
108
- });
109
- }
110
- listen(server, resolve, reject) {
111
- server.once("error", reject);
112
- server.listen(this.socketPath, () => {
113
- server.removeListener("error", reject);
114
- resolve();
115
- // A freshly started daemon may already be idle (no sessions) — start the
116
- // idle watch so a zero-session daemon also auto-exits.
117
- this.evaluateIdle();
118
- });
119
- }
120
- stop() {
121
- this.stopped = true;
122
- this.clearIdleTimer();
123
- return new Promise((resolve) => {
124
- const server = this.server;
125
- if (!server)
126
- return resolve();
127
- this.server = undefined;
128
- server.close(() => resolve());
129
- });
130
- }
131
- // ── Idle auto-exit ────────────────────────────────────────────
132
- clearIdleTimer() {
133
- if (this.idleTimer) {
134
- clearTimeout(this.idleTimer);
135
- this.idleTimer = undefined;
136
- }
137
- }
138
- /**
139
- * Re-evaluate the idle condition after any state transition: sessions busy
140
- * (loading / pending messages / background work) or any client attached →
141
- * cancel the timer. Fully idle + detached → arm the grace timer once; when
142
- * it fires, shut the daemon down. Evaluation is event-driven (every
143
- * busy→idle transition emits a notification, every attach/detach fires a
144
- * connection event), so nothing is polled. The failure mode is
145
- * conservative: a missed transition just leaves the daemon running.
146
- */
147
- evaluateIdle() {
148
- // A stopped/shutting-down daemon never (re)arms the idle timer — late
149
- // socket 'close' events (which fire after server.close resolves) must not
150
- // resurrect a timer after stop().
151
- if (this.shuttingDown || this.stopped)
152
- return;
153
- if (this.connections.size > 0 || !this.bridge.isIdle()) {
154
- this.clearIdleTimer();
155
- return;
156
- }
157
- if (this.idleTimer)
158
- return;
159
- this.idleTimer = setTimeout(() => {
160
- this.idleTimer = undefined;
161
- void this.shutdown();
162
- }, this.graceMs);
163
- }
164
- /**
165
- * Destroy the sessions (each agent saves its transcript and drains
166
- * auto-memory), close the listener, unlink the socket file, then exit.
167
- * `shuttingDown` guards against re-entry: new connections are refused and
168
- * further idle evaluations become no-ops.
169
- */
170
- async shutdown() {
171
- if (this.shuttingDown)
172
- return;
173
- this.shuttingDown = true;
174
- this.clearIdleTimer();
175
- // Destroy client sockets first so server.close() can complete (an open
176
- // socket keeps the close callback pending).
177
- for (const socket of this.sockets)
178
- socket.destroy();
179
- this.sockets.clear();
180
- await this.bridge.destroyAll();
181
- await this.stop();
182
- try {
183
- fs.unlinkSync(this.socketPath);
184
- }
185
- catch {
186
- // Already gone — a stale file would be probed/unlinked on next start.
187
- }
188
- process.exit(0);
189
- }
190
- }
191
- DaemonServer.DEFAULT_IDLE_GRACE_MS = 60000;
@@ -1,5 +0,0 @@
1
- export { StdioServer, type StdioServerOptions } from "./stdioServer.js";
2
- export { JsonRpcConnection } from "./jsonRpcConnection.js";
3
- export { DaemonServer, type DaemonServerOptions } from "./daemonServer.js";
4
- export { AgentBridge, type AgentBridgeOptions, RpcError, } from "./agentBridge.js";
5
- export * from "./protocol.js";
@@ -1,5 +0,0 @@
1
- export { StdioServer } from "./stdioServer.js";
2
- export { JsonRpcConnection } from "./jsonRpcConnection.js";
3
- export { DaemonServer } from "./daemonServer.js";
4
- export { AgentBridge, RpcError, } from "./agentBridge.js";
5
- export * from "./protocol.js";
@@ -1,30 +0,0 @@
1
- /**
2
- * JsonRpcConnection — one JSON-RPC connection over a Readable/Writable pair,
3
- * dispatching to a shared AgentBridge.
4
- *
5
- * Shared by StdioServer (process stdin/stdout) and DaemonServer (each unix
6
- * socket connection). The AgentBridge owns all session/agent state, so any
7
- * number of connections can share it — a detached client loses nothing and
8
- * every session keeps running on the daemon side.
9
- */
10
- import type { Readable, Writable } from "stream";
11
- import { AgentBridge } from "./agentBridge.js";
12
- export declare class JsonRpcConnection {
13
- private input;
14
- private output;
15
- private bridge;
16
- private rl;
17
- private started;
18
- constructor(input: Readable, output: Writable, bridge: AgentBridge);
19
- start(): void;
20
- stop(): void;
21
- handleLine(line: string): Promise<void>;
22
- private handleRequest;
23
- private handleNotification;
24
- sendResponse(id: number | string | null, result?: unknown, error?: {
25
- code: number;
26
- message: string;
27
- }): void;
28
- sendNotification(method: string, params?: unknown, sessionId?: string): void;
29
- private write;
30
- }
@@ -1,127 +0,0 @@
1
- /**
2
- * JsonRpcConnection — one JSON-RPC connection over a Readable/Writable pair,
3
- * dispatching to a shared AgentBridge.
4
- *
5
- * Shared by StdioServer (process stdin/stdout) and DaemonServer (each unix
6
- * socket connection). The AgentBridge owns all session/agent state, so any
7
- * number of connections can share it — a detached client loses nothing and
8
- * every session keeps running on the daemon side.
9
- */
10
- import readline from "readline";
11
- import { PARSE_ERROR, INVALID_REQUEST, INTERNAL_ERROR, isRequest, isNotification, } from "./protocol.js";
12
- export class JsonRpcConnection {
13
- constructor(input, output, bridge) {
14
- this.input = input;
15
- this.output = output;
16
- this.bridge = bridge;
17
- this.started = false;
18
- }
19
- start() {
20
- if (this.started)
21
- return;
22
- this.started = true;
23
- this.rl = readline.createInterface({
24
- input: this.input,
25
- crlfDelay: Infinity,
26
- });
27
- // readline re-emits input errors on the Interface; error handling on the
28
- // underlying stream is the owner's job (the daemon keeps running on a
29
- // client reset), so swallow them here.
30
- this.rl.on("error", () => { });
31
- this.rl.on("line", (line) => {
32
- this.handleLine(line).catch((err) => {
33
- // Should never reach here — handleLine catches internally
34
- this.sendResponse(null, undefined, {
35
- code: INTERNAL_ERROR,
36
- message: `Unhandled error: ${err.message}`,
37
- });
38
- });
39
- });
40
- this.rl.on("close", () => {
41
- this.started = false;
42
- });
43
- }
44
- stop() {
45
- this.rl?.close();
46
- this.rl = undefined;
47
- this.started = false;
48
- }
49
- async handleLine(line) {
50
- const trimmed = line.trim();
51
- if (!trimmed)
52
- return;
53
- let msg;
54
- try {
55
- msg = JSON.parse(trimmed);
56
- }
57
- catch {
58
- this.sendResponse(null, undefined, {
59
- code: PARSE_ERROR,
60
- message: "Parse error: invalid JSON",
61
- });
62
- return;
63
- }
64
- if (isRequest(msg)) {
65
- await this.handleRequest(msg);
66
- }
67
- else if (isNotification(msg)) {
68
- this.handleNotification(msg);
69
- }
70
- else {
71
- // Echo back the id if the message has one, otherwise null
72
- const id = typeof msg === "object" &&
73
- msg !== null &&
74
- "id" in msg &&
75
- (typeof msg.id === "number" ||
76
- typeof msg.id === "string")
77
- ? msg.id
78
- : null;
79
- this.sendResponse(id, undefined, {
80
- code: INVALID_REQUEST,
81
- message: "Invalid request: must have 'method' field",
82
- });
83
- }
84
- }
85
- async handleRequest(msg) {
86
- try {
87
- const result = await this.bridge.handleRequest(msg.method, msg.params, msg.sessionId);
88
- this.sendResponse(msg.id, result);
89
- }
90
- catch (err) {
91
- const code = err && typeof err === "object" && "code" in err
92
- ? err.code
93
- : INTERNAL_ERROR;
94
- const message = err instanceof Error ? err.message : String(err);
95
- this.sendResponse(msg.id, undefined, { code, message });
96
- }
97
- }
98
- handleNotification(msg) {
99
- try {
100
- this.bridge.handleNotification(msg.method, msg.params);
101
- }
102
- catch (err) {
103
- // Notifications don't get responses, but we log to stderr
104
- process.stderr.write(`Error handling notification ${msg.method}: ${err.message}\n`);
105
- }
106
- }
107
- // ── Output helpers ────────────────────────────────────────────
108
- sendResponse(id, result, error) {
109
- const response = { id };
110
- if (error) {
111
- response.error = error;
112
- }
113
- else {
114
- response.result = result ?? null;
115
- }
116
- this.write(response);
117
- }
118
- sendNotification(method, params, sessionId) {
119
- const notification = { method, params };
120
- if (sessionId)
121
- notification.sessionId = sessionId;
122
- this.write(notification);
123
- }
124
- write(obj) {
125
- this.output.write(JSON.stringify(obj) + "\n");
126
- }
127
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * JSON-RPC 2.0-compatible protocol types for stdio communication.
3
- *
4
- * Each line on stdin/stdout is one JSON object.
5
- * - Requests have `id` (number|string) and expect a response.
6
- * - Responses match the request `id` with either `result` or `error`.
7
- * - Notifications have no `id` and expect no response.
8
- */
9
- export interface JsonRpcRequest {
10
- id: number | string;
11
- method: string;
12
- params?: unknown;
13
- /** Session-scoped requests carry sessionId for routing to the right Agent. */
14
- sessionId?: string;
15
- }
16
- export interface JsonRpcResponse {
17
- id: number | string | null;
18
- result?: unknown;
19
- error?: JsonRpcError;
20
- }
21
- export interface JsonRpcError {
22
- code: number;
23
- message: string;
24
- data?: unknown;
25
- }
26
- export interface JsonRpcNotification {
27
- method: string;
28
- params?: unknown;
29
- /** Session-scoped notifications carry sessionId for demultiplexing on the client. */
30
- sessionId?: string;
31
- }
32
- export declare const PARSE_ERROR = -32700;
33
- export declare const INVALID_REQUEST = -32600;
34
- export declare const METHOD_NOT_FOUND = -32601;
35
- export declare const INVALID_PARAMS = -32602;
36
- export declare const INTERNAL_ERROR = -32603;
37
- export type RequestMethod = "initialize" | "destroy" | "restoreSession" | "listSessions" | "getSessionInfo" | "sendMessage" | "bang" | "askBtw" | "abortMessage" | "clearMessages" | "rewindToMessage" | "listRewindCheckpoints" | "deleteQueuedMessage" | "updateQueuedMessage" | "deleteQueuedMessageById" | "getMessages" | "getFullMessageThread" | "setPermissionMode" | "getPermissionMode" | "getMcpServers" | "connectMcpServer" | "disconnectMcpServer" | "getSlashCommands" | "searchFiles" | "writeArtifactFile" | "getPromptHistory" | "searchPromptHistory" | "updateConfig" | "getConfiguredModels" | "setModel" | "listPendingPermissions" | "listDaemonSessions" | "getAuthStatus" | "login" | "logout" | "listPlugins" | "installPlugin" | "uninstallPlugin" | "enablePlugin" | "disablePlugin" | "updatePlugin" | "listMarketplaces" | "addMarketplace" | "removeMarketplace" | "updateMarketplace" | "compact" | "getBackgroundTaskOutput" | "stopBackgroundTask" | "getWorkflowRuns" | "stopWorkflowRun" | "listGitBranches" | "createWorktree" | "removeWorktree";
38
- export type ClientNotificationMethod = "permissionResponse";
39
- export type ServerNotificationMethod = "userMessageAdded" | "assistantMessageAdded" | "assistantContentUpdated" | "assistantReasoningUpdated" | "toolBlockUpdated" | "errorBlockAdded" | "loadingChange" | "commandRunningChange" | "queuedMessagesChange" | "tasksChange" | "sessionIdChange" | "permissionModeChange" | "mcpServersChange" | "workdirChange" | "bangMessageAdded" | "bangMessageUpdated" | "bangMessageCompleted" | "notificationMessageAdded" | "permissionRequest" | "authUrl" | "compactBlockAdded" | "compactionStateChange" | "backgroundTasksChange" | "btwContent";
40
- export declare function isRequest(msg: unknown): msg is JsonRpcRequest;
41
- export declare function isNotification(msg: unknown): msg is JsonRpcNotification;
@@ -1,26 +0,0 @@
1
- /**
2
- * JSON-RPC 2.0-compatible protocol types for stdio communication.
3
- *
4
- * Each line on stdin/stdout is one JSON object.
5
- * - Requests have `id` (number|string) and expect a response.
6
- * - Responses match the request `id` with either `result` or `error`.
7
- * - Notifications have no `id` and expect no response.
8
- */
9
- // ── Error codes (JSON-RPC 2.0 standard) ────────────────────────
10
- export const PARSE_ERROR = -32700;
11
- export const INVALID_REQUEST = -32600;
12
- export const METHOD_NOT_FOUND = -32601;
13
- export const INVALID_PARAMS = -32602;
14
- export const INTERNAL_ERROR = -32603;
15
- // ── Helper: is this a request (has id)? ─────────────────────────
16
- export function isRequest(msg) {
17
- return (typeof msg === "object" &&
18
- msg !== null &&
19
- "method" in msg &&
20
- "id" in msg &&
21
- (typeof msg.id === "number" ||
22
- typeof msg.id === "string"));
23
- }
24
- export function isNotification(msg) {
25
- return (typeof msg === "object" && msg !== null && "method" in msg && !("id" in msg));
26
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * StdioServer — reads JSON-RPC messages from stdin, dispatches to AgentBridge,
3
- * and writes responses / notifications to stdout.
4
- *
5
- * One JSON object per line. stderr is reserved for logger output.
6
- * Line handling lives in JsonRpcConnection (shared with DaemonServer).
7
- */
8
- import type { Readable, Writable } from "stream";
9
- import { AgentBridge, type AgentBridgeOptions } from "./agentBridge.js";
10
- export interface StdioServerOptions {
11
- input?: Readable;
12
- output?: Writable;
13
- bridgeOptions?: AgentBridgeOptions;
14
- }
15
- export declare class StdioServer {
16
- private bridge;
17
- private conn;
18
- constructor(options?: StdioServerOptions);
19
- get agentBridge(): AgentBridge;
20
- start(): void;
21
- stop(): void;
22
- handleLine(line: string): Promise<void>;
23
- sendResponse(id: number | string | null, result?: unknown, error?: {
24
- code: number;
25
- message: string;
26
- }): void;
27
- sendNotification(method: string, params?: unknown, sessionId?: string): void;
28
- }
@@ -1,36 +0,0 @@
1
- /**
2
- * StdioServer — reads JSON-RPC messages from stdin, dispatches to AgentBridge,
3
- * and writes responses / notifications to stdout.
4
- *
5
- * One JSON object per line. stderr is reserved for logger output.
6
- * Line handling lives in JsonRpcConnection (shared with DaemonServer).
7
- */
8
- import { AgentBridge } from "./agentBridge.js";
9
- import { JsonRpcConnection } from "./jsonRpcConnection.js";
10
- export class StdioServer {
11
- constructor(options = {}) {
12
- this.bridge = new AgentBridge({
13
- ...options.bridgeOptions,
14
- emit: (method, params, sessionId) => this.sendNotification(method, params, sessionId),
15
- });
16
- this.conn = new JsonRpcConnection(options.input ?? process.stdin, options.output ?? process.stdout, this.bridge);
17
- }
18
- get agentBridge() {
19
- return this.bridge;
20
- }
21
- start() {
22
- this.conn.start();
23
- }
24
- stop() {
25
- this.conn.stop();
26
- }
27
- handleLine(line) {
28
- return this.conn.handleLine(line);
29
- }
30
- sendResponse(id, result, error) {
31
- this.conn.sendResponse(id, result, error);
32
- }
33
- sendNotification(method, params, sessionId) {
34
- this.conn.sendNotification(method, params, sessionId);
35
- }
36
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * stdio-cli.ts — Entry point for `wave --stdio` mode.
3
- *
4
- * Starts a StdioServer that reads JSON-RPC messages from stdin and writes
5
- * responses/notifications to stdout. The server creates an Agent lazily when
6
- * the client sends an "initialize" request.
7
- */
8
- export declare function startStdioCli(): Promise<void>;
package/dist/stdio-cli.js DELETED
@@ -1,15 +0,0 @@
1
- /**
2
- * stdio-cli.ts — Entry point for `wave --stdio` mode.
3
- *
4
- * Starts a StdioServer that reads JSON-RPC messages from stdin and writes
5
- * responses/notifications to stdout. The server creates an Agent lazily when
6
- * the client sends an "initialize" request.
7
- */
8
- import { StdioServer } from "./stdio/stdioServer.js";
9
- export async function startStdioCli() {
10
- const server = new StdioServer();
11
- server.start();
12
- // Keep the process alive — readline on stdin handles the event loop.
13
- // When stdin closes (EOF), the readline interface emits 'close' and
14
- // the process will exit naturally.
15
- }
package/dist/types.d.ts DELETED
@@ -1,20 +0,0 @@
1
- import { WorktreeSession } from "./utils/worktree.js";
2
- import { PermissionMode, McpServerConfig } from "wave-agent-sdk";
3
- export interface BaseAppProps {
4
- bypassPermissions?: boolean;
5
- permissionMode?: PermissionMode;
6
- pluginDirs?: string[];
7
- /** Additional directories to add to the session Safe Zone (from --add-dir). */
8
- additionalDirectories?: string[];
9
- tools?: string[];
10
- allowedTools?: string[];
11
- disallowedTools?: string[];
12
- worktreeSession?: WorktreeSession;
13
- workdir?: string;
14
- /** The working directory before entering a worktree (CLI -w); injected into the agent's container. */
15
- originalCwd?: string;
16
- version?: string;
17
- model?: string;
18
- /** Optional MCP server configs to pass to Agent.create() */
19
- mcpServers?: Record<string, McpServerConfig>;
20
- }
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,39 +0,0 @@
1
- /**
2
- * Bracketed paste (DECSET 2004) detector.
3
- *
4
- * When bracketed paste is enabled, terminals wrap pasted text in
5
- * `\x1b[200~` (start) and `\x1b[201~` (end) markers, which lets the input
6
- * pipeline distinguish "text was pasted" from "user typed keys" — most
7
- * importantly, a pasted trailing `\r` must NOT be treated as an Enter key.
8
- *
9
- * ink delivers each stdin chunk through useInput after stripping ONE leading
10
- * ESC from the parsed sequence (see use-input.js), so markers may arrive in
11
- * either the raw form (`\x1b[200~`) or the stripped form (`[200~`), and may
12
- * be split across chunks. The detector normalizes both forms and buffers
13
- * partial markers until they complete (deferral is safe: a deferred partial
14
- * is flushed unchanged if the next chunk does not complete a marker).
15
- */
16
- export type PasteProcessResult = {
17
- kind: "input";
18
- input: string;
19
- } | {
20
- kind: "paste";
21
- text: string;
22
- leadingInput?: string;
23
- } | {
24
- kind: "consume";
25
- };
26
- export interface BracketedPasteDetector {
27
- /**
28
- * Feed one input chunk (as delivered by ink's useInput callback).
29
- * - `input`: regular keystrokes, pass through to normal handling.
30
- * - `paste`: completed bracketed paste; insert `text` without submitting.
31
- * `leadingInput` (rare) is content that preceded the start marker in the
32
- * same chunk and should be handled as regular input first.
33
- * - `consume`: content of an in-flight paste (or an empty paste); do
34
- * nothing with this chunk.
35
- */
36
- process(chunk: string): PasteProcessResult;
37
- reset(): void;
38
- }
39
- export declare function createBracketedPasteDetector(): BracketedPasteDetector;